Skip to content

Commit

Permalink
Fix Map/Set polyfill detection
Browse files Browse the repository at this point in the history
Safari does not support ES6 Map/Set correctly which leads to trouble.
Be more strict in detecting whether the native Map/Set is good enough.

Fixes google#1650, google#1810
  • Loading branch information
arv committed May 17, 2015
1 parent 76ab4ca commit c4f2fe1
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 21 deletions.
28 changes: 15 additions & 13 deletions src/runtime/polyfills/Map.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@

import {
isObject,
maybeAddIterator,
registerPolyfill
} from './utils.js'

var getOwnHashObject = $traceurRuntime.getOwnHashObject;
var {getOwnHashObject, hasNativeSymbol} = $traceurRuntime;
var $hasOwnProperty = Object.prototype.hasOwnProperty;

var deletedSentinel = {};

function lookupIndex(map, key) {
Expand Down Expand Up @@ -192,19 +192,21 @@ Object.defineProperty(Map.prototype, Symbol.iterator, {
value: Map.prototype.entries
});

export function polyfillMap(global) {
var {Object, Symbol} = global;
if (!global.Map)
global.Map = Map;
function needsPolyfill(global) {
var {Map, Symbol} = global;
if (!Map || !$traceurRuntime.hasNativeSymbol() ||
!Map.prototype[Symbol.iterator] || !Map.prototype.entries) {
return true;
}
try {
return new Map([[]]).size !== 1;
} catch (e) {}
return false;
}

var mapPrototype = global.Map.prototype;
if (mapPrototype.entries === undefined)
export function polyfillMap(global) {
if (needsPolyfill(global)) {
global.Map = Map;

if (mapPrototype.entries) {
maybeAddIterator(mapPrototype, mapPrototype.entries, Symbol);
maybeAddIterator(Object.getPrototypeOf(new global.Map().entries()),
function() { return this; }, Symbol);
}
}

Expand Down
21 changes: 13 additions & 8 deletions src/runtime/polyfills/Set.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@

import {
isObject,
maybeAddIterator,
registerPolyfill
} from './utils.js';
import {Map} from './Map.js'
Expand Down Expand Up @@ -93,15 +92,21 @@ Object.defineProperty(Set.prototype, 'keys', {
value: Set.prototype.values
});

function needsPolyfill(global) {
var {Set, Symbol} = global;
if (!Set || !$traceurRuntime.hasNativeSymbol() ||
!Set.prototype[Symbol.iterator] || !Set.prototype.values) {
return true;
}
try {
return new Set([1]).size !== 1;
} catch (e) {}
return false;
}

export function polyfillSet(global) {
var {Object, Symbol} = global;
if (!global.Set)
if (needsPolyfill(global)) {
global.Set = Set;
var setPrototype = global.Set.prototype;
if (setPrototype.values) {
maybeAddIterator(setPrototype, setPrototype.values, Symbol);
maybeAddIterator(Object.getPrototypeOf(new global.Set().values()),
function() { return this; }, Symbol);
}
}

Expand Down
10 changes: 10 additions & 0 deletions src/runtime/runtime.js
Original file line number Diff line number Diff line change
Expand Up @@ -459,10 +459,15 @@
return argument;
}

var hasNativeSymbol = false;

function polyfillSymbol(global, Symbol) {
if (!global.Symbol) {
global.Symbol = Symbol;
Object.getOwnPropertySymbols = getOwnPropertySymbols;
hasNativeSymbol = false;
} else {
hasNativeSymbol = true;
}
if (!global.Symbol.iterator) {
global.Symbol.iterator = Symbol('Symbol.iterator');
Expand All @@ -472,6 +477,10 @@
}
}

function hasNativeSymbolFunc() {
return hasNativeSymbol;
}

function setupGlobals(global) {
polyfillSymbol(global, Symbol)
global.Reflect = global.Reflect || {};
Expand All @@ -494,6 +503,7 @@
getOwnHashObject: getOwnHashObject,
getOwnPropertyDescriptor: $getOwnPropertyDescriptor,
getOwnPropertyNames: $getOwnPropertyNames,
hasNativeSymbol: hasNativeSymbolFunc,
initTailRecursiveFunction: initTailRecursiveFunction,
isObject: isObject,
isPrivateName: isPrivateName,
Expand Down

0 comments on commit c4f2fe1

Please sign in to comment.