From f850a6fafc6cae76b57601cef891460fb3598064 Mon Sep 17 00:00:00 2001
From: Alexander Kryvomaz <akryvomaz@gmail.com>
Date: Sun, 1 Jul 2018 15:44:36 +0300
Subject: [PATCH 1/3] bindings for Function.prototype.bind()

---
 src/js.rs                        |  7 ++++++
 tests/all/js_globals/Function.rs | 40 ++++++++++++++++++++++++++++++++
 2 files changed, 47 insertions(+)

diff --git a/src/js.rs b/src/js.rs
index ced94305..e10d8d88 100644
--- a/src/js.rs
+++ b/src/js.rs
@@ -325,6 +325,13 @@ extern "C" {
     #[wasm_bindgen(method)]
     pub fn apply(this: &Function, context: &JsValue, args: &Array) -> Function;
 
+    /// The bind() method creates a new function that, when called, has its this keyword set to the provided value,
+    /// with a given sequence of arguments preceding any provided when the new function is called.
+    /// 
+    /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
+    #[wasm_bindgen(method)]
+    pub fn bind(this: &Function, context: &JsValue) -> Function;
+
     /// The length property indicates the number of arguments expected by the function.
     ///
     /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/length
diff --git a/tests/all/js_globals/Function.rs b/tests/all/js_globals/Function.rs
index b54a2629..b5f32d5b 100644
--- a/tests/all/js_globals/Function.rs
+++ b/tests/all/js_globals/Function.rs
@@ -38,6 +38,46 @@ fn apply() {
         .test()
 }
 
+#[test]
+fn bind() {
+    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 bind(this: &js::Function, context: &JsValue) -> js::Function {
+                this.bind(context)
+            }
+        "#,
+        )
+        .file(
+            "test.ts",
+            r#"
+            import * as assert from "assert";
+            import * as wasm from "./out";
+
+            export function test() {
+                const obj = {
+                    a: 0,
+                    fn: function () {
+                        return this.a + 1;
+                    }
+                }
+
+                const boundFn = wasm.bind(obj.fn, { a: 41 });
+                assert.equal(boundFn(), 42);
+            }
+        "#,
+        )
+        .test()
+}
+
 #[test]
 fn length() {
     project()

From 0f07dd9048625365acd236e1be75088c73efc7a4 Mon Sep 17 00:00:00 2001
From: Alexander Kryvomaz <akryvomaz@gmail.com>
Date: Sun, 1 Jul 2018 15:53:44 +0300
Subject: [PATCH 2/3] bindings for decodeURIComponent

---
 src/js.rs                   |  7 +++++++
 tests/all/js_globals/mod.rs | 28 +++++++++++++++++++++++++++-
 2 files changed, 34 insertions(+), 1 deletion(-)

diff --git a/src/js.rs b/src/js.rs
index e10d8d88..465edac3 100644
--- a/src/js.rs
+++ b/src/js.rs
@@ -49,6 +49,13 @@ extern "C" {
     #[wasm_bindgen(catch, js_name = decodeURI)]
     pub fn decode_uri(encoded: &str) -> Result<JsString, JsValue>;
 
+    /// The decodeURIComponent() function decodes a Uniform Resource Identifier (URI)
+    /// component previously created by encodeURIComponent or by a similar routine.
+    /// 
+    /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent
+    #[wasm_bindgen(catch, js_name = decodeURIComponent)]
+    pub fn decode_uri_component(encoded: &str) -> Result<JsString, JsValue>;
+
     /// The `encodeURI()` function encodes a Uniform Resource Identifier (URI)
     /// by replacing each instance of certain characters by one, two, three, or
     /// four escape sequences representing the UTF-8 encoding of the character
diff --git a/tests/all/js_globals/mod.rs b/tests/all/js_globals/mod.rs
index e33d9d6d..b365c6ce 100644
--- a/tests/all/js_globals/mod.rs
+++ b/tests/all/js_globals/mod.rs
@@ -6,8 +6,8 @@ mod Array;
 mod ArrayIterator;
 mod Boolean;
 mod Date;
-mod Function;
 mod Error;
+mod Function;
 mod JsString;
 mod Map;
 mod MapIterator;
@@ -47,6 +47,32 @@ fn decode_uri() {
         .test();
 }
 
+#[test]
+fn decode_uri_component() {
+    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 test() {
+                let x = js::decode_uri_component("%3Fx%3Dtest")
+                    .ok()
+                    .expect("should decode URI OK");
+                assert_eq!(String::from(x), "?x=test");
+
+                assert!(js::decode_uri_component("%E0%A4%A").is_err());
+            }
+        "#,
+        )
+        .test();
+}
+
 #[test]
 #[cfg(feature = "std")]
 fn encode_uri() {

From 609bf34d602a4b9b2c7cb942ef242cb36abb10bd Mon Sep 17 00:00:00 2001
From: Alexander Kryvomaz <akryvomaz@gmail.com>
Date: Sun, 1 Jul 2018 15:59:12 +0300
Subject: [PATCH 3/3] bindings for encodeURIComponent

---
 src/js.rs                   | 13 +++++++++++--
 tests/all/js_globals/mod.rs | 22 ++++++++++++++++++++++
 2 files changed, 33 insertions(+), 2 deletions(-)

diff --git a/src/js.rs b/src/js.rs
index 465edac3..7d957f74 100644
--- a/src/js.rs
+++ b/src/js.rs
@@ -49,8 +49,8 @@ extern "C" {
     #[wasm_bindgen(catch, js_name = decodeURI)]
     pub fn decode_uri(encoded: &str) -> Result<JsString, JsValue>;
 
-    /// The decodeURIComponent() function decodes a Uniform Resource Identifier (URI)
-    /// component previously created by encodeURIComponent or by a similar routine.
+    /// The decodeURIComponent() function decodes a Uniform Resource Identifier (URI) component
+    /// previously created by encodeURIComponent or by a similar routine.
     /// 
     /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent
     #[wasm_bindgen(catch, js_name = decodeURIComponent)]
@@ -66,6 +66,15 @@ extern "C" {
     #[wasm_bindgen(js_name = encodeURI)]
     pub fn encode_uri(decoded: &str) -> JsString;
 
+    /// The encodeURIComponent() function encodes a Uniform Resource Identifier (URI) component
+    /// by replacing each instance of certain characters by one, two, three, or four escape sequences
+    /// representing the UTF-8 encoding of the character
+    /// (will only be four escape sequences for characters composed of two "surrogate" characters).
+    /// 
+    /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent
+    #[wasm_bindgen(js_name = encodeURIComponent)]
+    pub fn encode_uri_component(decoded: &str) -> JsString;
+
     /// The `eval()` function evaluates JavaScript code represented as a string.
     ///
     /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval
diff --git a/tests/all/js_globals/mod.rs b/tests/all/js_globals/mod.rs
index b365c6ce..632898e0 100644
--- a/tests/all/js_globals/mod.rs
+++ b/tests/all/js_globals/mod.rs
@@ -96,6 +96,28 @@ fn encode_uri() {
         .test();
 }
 
+#[test]
+fn encode_uri_component() {
+    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 test() {
+                let x = js::encode_uri_component("?x=шеллы");
+                assert_eq!(String::from(x), "%3Fx%3D%D1%88%D0%B5%D0%BB%D0%BB%D1%8B");
+            }
+        "#,
+        )
+        .test();
+}
+
 #[test]
 fn eval() {
     project()