From 5925871a05c7ee31f3c8d3409200c0c8329501c6 Mon Sep 17 00:00:00 2001 From: Tim Ryan Date: Tue, 26 Jun 2018 00:34:17 -0400 Subject: [PATCH 1/5] Adds support for the UInt8Array constructor and its fill method. --- src/js.rs | 19 +++++++ tests/all/js_globals/TypedArray.rs | 85 ++++++++++++++++++++++++++++++ tests/all/js_globals/mod.rs | 1 + 3 files changed, 105 insertions(+) create mode 100644 tests/all/js_globals/TypedArray.rs diff --git a/src/js.rs b/src/js.rs index cef43b16..87d250e1 100644 --- a/src/js.rs +++ b/src/js.rs @@ -65,6 +65,25 @@ extern { pub fn eval(js_source_text: &str) -> Result; } +// UInt8Array +#[wasm_bindgen] +extern { + pub type Uint8Array; + + /// The `Uint8Array()` constructor creates an array of unsigned 8-bit integers. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array + #[wasm_bindgen(constructor)] + pub fn new(constructor_arg: JsValue) -> Uint8Array; + + /// The fill() method fills all the elements of an array from a start index + /// to an end index with a static value. The end index is not included. + /// + /// http://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/fill + #[wasm_bindgen(method)] + pub fn fill(this: &Uint8Array, value: JsValue, start: u32, end: u32) -> Uint8Array; +} + // Array #[wasm_bindgen] extern { diff --git a/tests/all/js_globals/TypedArray.rs b/tests/all/js_globals/TypedArray.rs new file mode 100644 index 00000000..139c4371 --- /dev/null +++ b/tests/all/js_globals/TypedArray.rs @@ -0,0 +1,85 @@ +#![allow(non_snake_case)] + +use project; + +#[test] +fn new_undefined() { + project() + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + + #[wasm_bindgen] + pub fn new_array() -> js::Uint8Array { + js::Uint8Array::new(JsValue::undefined()) + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + assert.equal(wasm.new_array().length, 0); + } + "#) + .test() +} + +#[test] +fn new_length() { + project() + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + + #[wasm_bindgen] + pub fn new_array() -> js::Uint8Array { + js::Uint8Array::new(JsValue::from_f64(4.0)) + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + assert.equal(wasm.new_array().length, 4); + } + "#) + .test() +} + +#[test] +fn fill() { + project() + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + + #[wasm_bindgen] + pub fn fill_with(this: &js::Uint8Array, value: JsValue, start: u32, end: u32) -> js::Uint8Array { + this.fill(value, start, end) + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + let characters = new Uint8Array([0, 0, 0, 0, 0, 0]); + let subset = wasm.fill_with(characters, 1, 0, 3); + + assert.equal(subset[0], 1); + assert.equal(subset[4], 0); + } + "#) + .test() +} diff --git a/tests/all/js_globals/mod.rs b/tests/all/js_globals/mod.rs index 3fd54d80..0ade163d 100644 --- a/tests/all/js_globals/mod.rs +++ b/tests/all/js_globals/mod.rs @@ -9,6 +9,7 @@ mod JsFunction; mod JsString; mod Number; mod Math; +mod TypedArray; #[test] #[cfg(feature = "std")] From a30509d142877e208b5bb9736a2a3e6ed79ab210 Mon Sep 17 00:00:00 2001 From: belfz Date: Tue, 26 Jun 2018 14:02:42 +0200 Subject: [PATCH 2/5] implements Object.seal binding --- src/js.rs | 8 ++++++ tests/all/js_globals/Object.rs | 51 ++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/src/js.rs b/src/js.rs index cef43b16..c42b6f4d 100644 --- a/src/js.rs +++ b/src/js.rs @@ -412,6 +412,14 @@ extern { #[wasm_bindgen(method, js_name = propertyIsEnumerable)] pub fn property_is_enumerable(this: &Object, property: &JsValue) -> bool; + /// The Object.seal() method seals an object, preventing new properties + /// from being added to it and marking all existing properties as non-configurable. + /// Values of present properties can still be changed as long as they are writable. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/seal + #[wasm_bindgen(static_method_of = Object)] + pub fn seal(value: &JsValue) -> JsValue; + /// The toLocaleString() method returns a string representing the object. /// This method is meant to be overridden by derived objects for /// locale-specific purposes. diff --git a/tests/all/js_globals/Object.rs b/tests/all/js_globals/Object.rs index 2ca6a093..48526636 100755 --- a/tests/all/js_globals/Object.rs +++ b/tests/all/js_globals/Object.rs @@ -185,6 +185,57 @@ fn property_is_enumerable() { .test() } +#[test] +fn seal() { + project() + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + + #[wasm_bindgen] + pub fn seal(value: &JsValue) -> JsValue { + js::Object::seal(&value) + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + const object: any = { foo: 'bar' }; + const sealedObject = wasm.seal(object); + assert.strictEqual(object, sealedObject); + assert.throws(() => { + 'use strict'; + sealedObject.bar = 'foo'; + }, TypeError); + assert.throws(() => { + 'use strict'; + delete sealedObject.foo; + }, TypeError); + + const primitive = 42; + assert.doesNotThrow(() => { + 'use strict'; + // according to ES2015, this should not throw anymore + // see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/seal#Notes + wasm.seal(primitive); + }); + + const array = [1, 2, 3]; + const sealedArray = wasm.seal(array); + assert.throws(() => { + 'use strict'; + sealedArray.push(42); + }, TypeError); + } + "#) + .test() +} + #[test] fn to_locale_string() { project() From ae847861e7a0f9fa1e8403d77b6a0aab964f3c9f Mon Sep 17 00:00:00 2001 From: Satoshi Amemiya Date: Tue, 26 Jun 2018 20:29:07 +0900 Subject: [PATCH 3/5] String - includes() support --- src/js.rs | 6 ++++++ tests/all/js_globals/JsString.rs | 35 ++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/src/js.rs b/src/js.rs index cef43b16..0bdba97a 100644 --- a/src/js.rs +++ b/src/js.rs @@ -455,6 +455,12 @@ extern { #[wasm_bindgen(method, js_class = "String", js_name = indexOf)] pub fn index_of(this: &JsString, search_value: &JsString, from_index: i32) -> i32; + /// The includes() method determines whether one string may be found within another string, returning true or false as appropriate. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/includes + #[wasm_bindgen(method, js_class = "String")] + pub fn includes(this: &JsString, search_string: &JsString, position: i32) -> bool; + /// The slice() method extracts a section of a string and returns it as a /// new string, without modifying the original string. /// diff --git a/tests/all/js_globals/JsString.rs b/tests/all/js_globals/JsString.rs index 9bfe0ba4..be63c137 100644 --- a/tests/all/js_globals/JsString.rs +++ b/tests/all/js_globals/JsString.rs @@ -204,3 +204,38 @@ fn substr() { "#) .test() } + +#[test] +fn includes() { + project() + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + + #[wasm_bindgen] + pub fn string_includes(this: &js::JsString, search_value: &js::JsString, position: i32) -> bool { + this.includes(search_value, position) + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + let str = "Blue Whale"; + + // TODO: remove second parameter once we have optional parameters + assert.equal(wasm.string_includes(str, 'Blue', 0), true); + assert.equal(wasm.string_includes(str, 'Blute', 0), false); + assert.equal(wasm.string_includes(str, 'Whale', 0), true); + assert.equal(wasm.string_includes(str, 'Whale', 5), true); + assert.equal(wasm.string_includes(str, 'Whale', 7), false); + assert.equal(wasm.string_includes(str, '', 0), true); + assert.equal(wasm.string_includes(str, '', 16), true); + } + "#) + .test() +} From 22fdcf02b23d571f6a508f6ba934ab1b93c3404d Mon Sep 17 00:00:00 2001 From: Satoshi Amemiya Date: Tue, 26 Jun 2018 21:25:44 +0900 Subject: [PATCH 4/5] Support String.prototype.charCodeAt --- src/js.rs | 10 ++++++++++ tests/all/js_globals/JsString.rs | 29 +++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/src/js.rs b/src/js.rs index cef43b16..d10ba5ab 100644 --- a/src/js.rs +++ b/src/js.rs @@ -447,6 +447,16 @@ extern { #[wasm_bindgen(method, js_class = "String", js_name = charAt)] pub fn char_at(this: &JsString, index: u32) -> JsString; + /// The charCodeAt() method returns an integer between 0 and 65535 representing the UTF-16 code unit at + /// the given index (the UTF-16 code unit matches the Unicode code point for code points representable in + /// a single UTF-16 code unit, but might also be the first code unit of a surrogate pair for + /// code points not representable in a single UTF-16 code unit, e.g. Unicode code points > 0x10000). + /// If you want the entire code point value, use codePointAt(). + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/charCodeAt + #[wasm_bindgen(method, js_class = "String", js_name = charCodeAt)] + pub fn char_code_at(this: &JsString, index: u32) -> Number; + /// The indexOf() method returns the index within the calling String object of /// the first occurrence of the specified value, starting the search at fromIndex. /// Returns -1 if the value is not found. diff --git a/tests/all/js_globals/JsString.rs b/tests/all/js_globals/JsString.rs index 9bfe0ba4..5658727d 100644 --- a/tests/all/js_globals/JsString.rs +++ b/tests/all/js_globals/JsString.rs @@ -31,6 +31,35 @@ fn char_at() { .test() } +#[test] +fn char_code_at() { + project() + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + + #[wasm_bindgen] + pub fn string_char_code_at(this: &js::JsString, index: u32) -> js::Number { + this.char_code_at(index) + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + var anyString = 'Brave new world'; + + export function test() { + assert.equal(wasm.string_char_code_at(anyString, 0), 66); + assert.ok(isNaN(wasm.string_char_code_at(anyString, 999))); + } + "#) + .test() +} + #[test] fn starts_with() { project() From 0f7db31888400be86c0255f84c1341beaa393882 Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Tue, 26 Jun 2018 10:18:31 -0700 Subject: [PATCH 5/5] js: Sort Array bindings alphabetically --- src/js.rs | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/js.rs b/src/js.rs index 126c9479..66afb54b 100644 --- a/src/js.rs +++ b/src/js.rs @@ -117,14 +117,12 @@ extern { #[wasm_bindgen(method)] pub fn filter(this: &Array, predicate: &mut FnMut(JsValue, u32, Array) -> bool) -> Array; - /// The length property of an object which is an instance of type Array - /// sets or returns the number of elements in that array. The value is an - /// unsigned, 32-bit integer that is always numerically greater than the - /// highest index in the array. + /// The includes() method determines whether an array includes a certain + /// element, returning true or false as appropriate. /// - /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/length - #[wasm_bindgen(method, getter, structural)] - pub fn length(this: &Array) -> u32; + /// http://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes + #[wasm_bindgen(method)] + pub fn includes(this: &Array, value: JsValue, from_index: i32) -> bool; /// The indexOf() method returns the first index at which a given element /// can be found in the array, or -1 if it is not present. @@ -133,13 +131,6 @@ extern { #[wasm_bindgen(method, js_name = indexOf)] pub fn index_of(this: &Array, value: JsValue, from_index: i32) -> i32; - /// The includes() method determines whether an array includes a certain - /// element, returning true or false as appropriate. - /// - /// http://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes - #[wasm_bindgen(method)] - pub fn includes(this: &Array, value: JsValue, from_index: i32) -> bool; - /// The join() method joins all elements of an array (or an array-like object) /// into a string and returns this string. /// @@ -155,6 +146,15 @@ extern { #[wasm_bindgen(method, js_name = lastIndexOf)] pub fn last_index_of(this: &Array, value: JsValue, from_index: i32) -> i32; + /// The length property of an object which is an instance of type Array + /// sets or returns the number of elements in that array. The value is an + /// unsigned, 32-bit integer that is always numerically greater than the + /// highest index in the array. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/length + #[wasm_bindgen(method, getter, structural)] + pub fn length(this: &Array) -> u32; + /// The pop() method removes the last element from an array and returns that /// element. This method changes the length of the array. /// @@ -176,6 +176,13 @@ extern { #[wasm_bindgen(method)] pub fn reverse(this: &Array) -> Array; + /// The shift() method removes the first element from an array and returns + /// that removed element. This method changes the length of the array. + /// + /// http://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/shift + #[wasm_bindgen(method)] + pub fn shift(this: &Array) -> JsValue; + /// The slice() method returns a shallow copy of a portion of an array into /// a new array object selected from begin to end (end not included). /// The original array will not be modified. @@ -184,13 +191,6 @@ extern { #[wasm_bindgen(method)] pub fn slice(this: &Array, start: u32, end: u32) -> Array; - /// The shift() method removes the first element from an array and returns - /// that removed element. This method changes the length of the array. - /// - /// http://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/shift - #[wasm_bindgen(method)] - pub fn shift(this: &Array) -> JsValue; - /// The sort() method sorts the elements of an array in place and returns /// the array. The sort is not necessarily stable. The default sort /// order is according to string Unicode code points.