Skip to content

Commit

Permalink
Fix compatibility bugs with Firefox 25, 30, 31.
Browse files Browse the repository at this point in the history
Shim `Array#find` and `Array#findIndex` if they don't match ES6 spec's
treatment of holes.  (Be sure to do this test after `Number` has been
shimmed, and we've already eliminated a premature use of `Math.sign`.)

Broaden the permissible values of `Math.cosh` (Firefox 31 on Linux/x86
shows a difference here.)

Fix an overly-specific test for `Symbol.iterator` (for compatibility,
we use `'@@iterator'` as the name of our iterator on Firefox, in the
absence of `Symbol.iterator`).

The `defineProperties` method doesn't work if we are using
`Symbol.iterator` as the name for the iterator method.  Only newer
browsers define enough of `Symbol` to encounter this problem.  Be
careful when shimming iterators.
  • Loading branch information
cscott committed Sep 4, 2014
1 parent d0e4bbf commit 355a46c
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 36 deletions.
36 changes: 18 additions & 18 deletions es6-shim.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,11 @@
var o = {};
o[$iterator$] = impl;
defineProperties(prototype, o);
/* jshint notypeof: true */
if (!prototype[$iterator$] && typeof($iterator$)==='symbol') {
// implementations are buggy when $iterator$ is a Symbol
prototype[$iterator$] = impl;
}
};

// taken directly from https://github.com/ljharb/is-arguments/blob/master/index.js
Expand Down Expand Up @@ -667,7 +672,7 @@
});
addIterator(ArrayIterator.prototype);

var arrayPrototypeShims = {
var ArrayPrototypeShims = {
copyWithin: function(target, start) {
var end = arguments[2]; // copyWithin.length must be 2
var o = ES.ToObject(this);
Expand Down Expand Up @@ -754,23 +759,7 @@
return new ArrayIterator(this, "entry");
}
};
defineProperties(Array.prototype, arrayPrototypeShims);

var handlesSparseArrays = function (method) {
var count = 0;
method.call([1, ,], function (item) { count += 1; });
return count === 2;
};

// Firefox >= 25 (up to 31 at least) does not handle sparse arrays properly
// for Array#find and Array#findIndex
if (!handlesSparseArrays(Array.prototype.find)) {
defineProperty(Array.prototype, 'find', arrayPrototypeShims.find, true);
}
if (!handlesSparseArrays(Array.prototype.findIndex)) {
defineProperty(Array.prototype, 'findIndex', arrayPrototypeShims.findIndex, true);
}

defineProperties(Array.prototype, ArrayPrototypeShims);
addIterator(Array.prototype, function() { return this.values(); });
// Chrome defines keys/values/entries on Array, but doesn't give us
// any way to identify its iterator. So add our own shimmed field.
Expand Down Expand Up @@ -811,6 +800,17 @@

});

// Work around bugs in Array#find and Array#findIndex -- early
// implementations skipped holes in sparse arrays. (Note that the
// implementations of find/findIndex indirectly use shimmed
// methods of Number, so this test has to happen down here.)
if (![,1].find(function(item,idx) { return idx===0; })) {
defineProperty(Array.prototype, 'find', ArrayPrototypeShims.find, true);
}
if ([,1].findIndex(function(item,idx) { return idx===0; }) !== 0) {
defineProperty(Array.prototype, 'findIndex', ArrayPrototypeShims.findIndex, true);
}

if (supportsDescriptors) {
defineProperties(Object, {
getPropertyDescriptor: function(subject, name) {
Expand Down
23 changes: 6 additions & 17 deletions test/array.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,16 @@
var runArrayTests = function() {
var getIteratorPropertyName = function() {
var iterator;
if (typeof Symbol === 'function' && Symbol.iterator) {
iterator = Symbol.iterator;
} else {
iterator = '_es6shim_iterator_';
}
// Firefox ships a partial implementation using the name @@iterator.
// https://bugzilla.mozilla.org/show_bug.cgi?id=907077#c14
// So use that name if we detect it.
if (Set && typeof new Set()['@@iterator'] === 'function') {
iterator = '@@iterator';
}
return iterator;
};

describe('Array', function() {
var list = [5, 10, 15, 20];

describe('@@iterator', function() {
it('uses Symbol.iterator if available', function() {
var a = [];
var iterator = getIteratorPropertyName();
var iterator;
if (typeof Symbol === 'function' && Symbol.iterator) {
iterator = Symbol.iterator;
} else {
return;
}
expect(a[iterator]()).to.eql(a.values());
});
});
Expand Down
3 changes: 2 additions & 1 deletion test/math.js
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,8 @@ describe('Math', function() {

it('should be correct', function() {
// Overridden precision values here are for Chrome, as of v25.0.1364.172
expect(Math.cosh(12)).to.almostEqual(81377.39571257407, 3e-11);
// Broadened slightly for Firefox 31
expect(Math.cosh(12)).to.almostEqual(81377.39571257407, 9e-11);
expect(Math.cosh(22)).to.almostEqual(1792456423.065795780980053377, 1e-5);
expect(Math.cosh(-10)).to.almostEqual(11013.23292010332313972137);
expect(Math.cosh(-23)).to.almostEqual(4872401723.1244513000, 1e-5);
Expand Down

0 comments on commit 355a46c

Please sign in to comment.