From 03e61ebc615c98be3506dd2ece76ccb3d2062264 Mon Sep 17 00:00:00 2001 From: Sami Vaarala Date: Mon, 8 Sep 2014 11:40:15 +0300 Subject: [PATCH 1/6] Add Object.assign polyfill More or less untested. --- polyfills/object-assign.js | 45 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 polyfills/object-assign.js diff --git a/polyfills/object-assign.js b/polyfills/object-assign.js new file mode 100644 index 00000000..3fcef846 --- /dev/null +++ b/polyfills/object-assign.js @@ -0,0 +1,45 @@ +/* + * Object.assign(), described in E6 Section 19.1.2.1 + * + * https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.assign + */ + +if (typeof Object.assign === 'undefined') { + Object.defineProperty(Object, 'assign', { + value: function (target) { + var i, n, j, m, k; + var source, keys; + var gotError; + var pendingError; + + if (target == null) { + throw new Exception('target null or undefined'); + } + + for (i = 1, n = arguments.length; i < n; i++) { + source = arguments[i]; + if (source == null) { + continue; // null or undefined + } + source = Object(source); + keys = Object.keys(source); // enumerable own keys + + for (j = 0, m = keys.length; j < m; j++) { + k = keys[j]; + try { + target[k] = source[k]; + } catch (e) { + if (!gotError) { + gotError = true; + pendingError = e; + } + } + } + } + + if (gotError) { + throw pendingError; + } + }, writable: true, enumerable: false, configurable: true + }); +} From 430ccc89947c8a73a19625a8c4a3d799091f5762 Mon Sep 17 00:00:00 2001 From: Sami Vaarala Date: Mon, 8 Sep 2014 11:40:31 +0300 Subject: [PATCH 2/6] Add Performance.now() polyfill More or less untested. --- polyfills/performance-now.js | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 polyfills/performance-now.js diff --git a/polyfills/performance-now.js b/polyfills/performance-now.js new file mode 100644 index 00000000..8671d180 --- /dev/null +++ b/polyfills/performance-now.js @@ -0,0 +1,25 @@ +/* + * Performance.now() + * + * http://www.w3.org/TR/hr-time/#sec-high-resolution-time + * + * Dummy implementation which uses the Date built-in and has no higher + * resolution. If/when Duktape has a built-in high resolution timer + * interface, reimplement this. + */ + +var _perfNowZeroTime = Date.now(); + +if (typeof Performance === 'undefined') { + Object.defineProperty(this, 'Performance', { + value: {}, + writable: true, enumerable: false, configurable: true + }); +} +if (typeof Performance.now === 'undefined') { + Object.defineProperty(Performance, 'now', { + value: function () { + return Date.now() - _perfNowZeroTime; + }, writable: true, enumerable: false, configurable: true + }); +} From 9d5ac371b8928d649fe80a39d3f1b8a2c27c930c Mon Sep 17 00:00:00 2001 From: Sami Vaarala Date: Mon, 8 Sep 2014 12:16:01 +0300 Subject: [PATCH 3/6] Add RegExp.prototype.compile() polyfill --- polyfills/regexp-prototype-compile.js | 65 +++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 polyfills/regexp-prototype-compile.js diff --git a/polyfills/regexp-prototype-compile.js b/polyfills/regexp-prototype-compile.js new file mode 100644 index 00000000..39168c23 --- /dev/null +++ b/polyfills/regexp-prototype-compile.js @@ -0,0 +1,65 @@ +/* + * RegExp.prototype.compile(), described in E6 Annex B: + * + * https://people.mozilla.org/~jorendorff/es6-draft.html#sec-regexp.prototype.compile + * + * See also: + * + * http://mozilla.6506.n7.nabble.com/RegExp-prototype-compile-and-RegExp-instance-properties-td270408.html + * + * This polyfill cannot be implemented in terms of standard E5 because it + * needs to reinitialize the internal state of a RegExp instance. To do + * that, we access the Duktape internal properties directly, which is + * quite fragile. + * + * Avoid storing a public copy of Duktape or some internal property name in + * the global object. This could subvert user sandboxing. + */ + +(function () { + var propBytecode = Duktape.dec('hex', 'ff62797465636f6465'); // \xFFbytecode + + if (typeof RegExp.prototype.compile !== 'undefined') { + return; + } + + Object.defineProperty(RegExp.prototype, 'compile', { + value: function (pattern, flags) { + var newBytecode, tmpRegexp; + if (typeof this !== 'object' || !(propBytecode in this)) { + throw new TypeError('invalid this binding'); + } + + // FIXME: property attributes prevent this approach from working + // right now. The properties we'd need to modify are non-writable + // and non-configurable: + // + // \xffbytecode + // source + // global + // ignoreCase + // multiline + // + // The property attributes can be relaxed, or the properties can + // be made accessors backing to the regexp bytecode, see Ditz + // issues: 0f2c246cadbb3b3913b75dc7e890ee4e7d336a1a and + // f8396fbcc36db4610fec5ad5a7d7a8f471d084a4. + + if (typeof pattern === 'object' && (propBytecode in pattern)) { + this[propBytecode] = pattern[propBytecode]; + } else { + tmpRegexp = new RegExp(pattern, flags); + this[propBytecode] = tmpRegexp[propBytecode]; + } + + //this.source + //this.global + //this.ignoreCase + //this.multiline + this.lastIndex = 0; + return this; + }, writable: true, enumerable: false, configurable: true + }); + + throw new Error('RegExp.prototype.compile() polyfill incomplete'); +})(); From 5702351e036d0ae75df88a69fe8d29745e5e2302 Mon Sep 17 00:00:00 2001 From: Sami Vaarala Date: Mon, 8 Sep 2014 12:19:50 +0300 Subject: [PATCH 4/6] Polyfill comment updates --- polyfills/console-minimal.js | 4 ++++ polyfills/object-prototype-definegetter.js | 4 ++++ polyfills/object-prototype-definesetter.js | 4 ++++ polyfills/performance-now.js | 2 +- polyfills/regexp-prototype-compile.js | 2 +- 5 files changed, 14 insertions(+), 2 deletions(-) diff --git a/polyfills/console-minimal.js b/polyfills/console-minimal.js index f5183163..e9e854c9 100644 --- a/polyfills/console-minimal.js +++ b/polyfills/console-minimal.js @@ -1,3 +1,7 @@ +/* + * Minimal console.log() polyfill + */ + if (typeof console === 'undefined') { Object.defineProperty(this, 'console', { value: {}, writable: true, enumerable: false, configurable: true diff --git a/polyfills/object-prototype-definegetter.js b/polyfills/object-prototype-definegetter.js index f0530c76..8d8cabb3 100644 --- a/polyfills/object-prototype-definegetter.js +++ b/polyfills/object-prototype-definegetter.js @@ -1,3 +1,7 @@ +/* + * Object.prototype.__defineGetter__ polyfill + */ + if (typeof Object.prototype.__defineGetter__ === 'undefined') { Object.defineProperty(Object.prototype, '__defineGetter__', { value: function (n, f) { diff --git a/polyfills/object-prototype-definesetter.js b/polyfills/object-prototype-definesetter.js index 1818885c..6bd1722f 100644 --- a/polyfills/object-prototype-definesetter.js +++ b/polyfills/object-prototype-definesetter.js @@ -1,3 +1,7 @@ +/* + * Object.prototype.__defineSetter__ polyfill + */ + if (typeof Object.prototype.__defineSetter__ === 'undefined') { Object.defineProperty(Object.prototype, '__defineSetter__', { value: function (n, f) { diff --git a/polyfills/performance-now.js b/polyfills/performance-now.js index 8671d180..dfb0a1d6 100644 --- a/polyfills/performance-now.js +++ b/polyfills/performance-now.js @@ -1,5 +1,5 @@ /* - * Performance.now() + * Performance.now() polyfill * * http://www.w3.org/TR/hr-time/#sec-high-resolution-time * diff --git a/polyfills/regexp-prototype-compile.js b/polyfills/regexp-prototype-compile.js index 39168c23..ab2d31aa 100644 --- a/polyfills/regexp-prototype-compile.js +++ b/polyfills/regexp-prototype-compile.js @@ -1,5 +1,5 @@ /* - * RegExp.prototype.compile(), described in E6 Annex B: + * RegExp.prototype.compile() polyfill, described in E6 Annex B: * * https://people.mozilla.org/~jorendorff/es6-draft.html#sec-regexp.prototype.compile * From d81d5df532196544db867fc5452e6ec08a6124f4 Mon Sep 17 00:00:00 2001 From: Sami Vaarala Date: Mon, 8 Sep 2014 12:20:00 +0300 Subject: [PATCH 5/6] Add polyfills to dist Leave RegExp.prototype.compile() out as non-working. --- util/make_dist.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/util/make_dist.sh b/util/make_dist.sh index 5a752511..e5cb775f 100644 --- a/util/make_dist.sh +++ b/util/make_dist.sh @@ -188,6 +188,8 @@ for i in \ console-minimal.js \ object-prototype-definegetter.js \ object-prototype-definesetter.js \ + object-assign.js \ + performance-now.js \ ; do cp polyfills/$i $DIST/polyfills/ done From 024d57c85fbdc5e8b3b6cd4d5538138022bfdb75 Mon Sep 17 00:00:00 2001 From: Sami Vaarala Date: Mon, 8 Sep 2014 12:20:29 +0300 Subject: [PATCH 6/6] Release note: more polyfills --- RELEASES.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/RELEASES.txt b/RELEASES.txt index 2def2ab9..b5f1a33d 100644 --- a/RELEASES.txt +++ b/RELEASES.txt @@ -515,6 +515,8 @@ Planned * Make objects and functions defined by included polyfills non-enumerable so that they don't enumerate e.g. in a for-in loop +* A few more polyfills. + 1.0.0 (2014-08-XX) ------------------