polyfill-service
Version:
A polyfill combinator
98 lines (93 loc) • 3.01 kB
JavaScript
// ES6-shim 0.16.0 (c) 2013-2014 Paul Miller (http://paulmillr.com)
// ES6-shim may be freely distributed under the MIT license.
// For more details and documentation:
// https://github.com/paulmillr/es6-shim/
// NOTE: This versions needs object ownership
// because every promoted object needs to be reassigned
// otherwise uncompatible browsers cannot work as expected
//
// NOTE: This might need es5-shim or polyfills upfront
// because it's based on ES5 API.
// (probably just an IE <= 8 problem)
//
// NOTE: nodejs is fine in version 0.8, 0.10, and future versions.
(function () {
if (Object.setPrototypeOf) { return; }
/*jshint proto: true */
// @author Andrea Giammarchi - @WebReflection
var getOwnPropertyNames = Object.getOwnPropertyNames;
var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
var create = Object.create;
var defineProperty = Object.defineProperty;
var getPrototypeOf = Object.getPrototypeOf;
var objProto = Object.prototype;
var copyDescriptors = function (target, source) {
// define into target descriptors from source
getOwnPropertyNames(source).forEach(function (key) {
defineProperty(
target,
key,
getOwnPropertyDescriptor(source, key)
);
});
return target;
};
// used as fallback when no promotion is possible
var createAndCopy = function (origin, proto) {
return copyDescriptors(create(proto), origin);
};
var set, setPrototypeOf;
try {
// this might fail for various reasons
// ignore if Chrome cought it at runtime
set = getOwnPropertyDescriptor(objProto, '__proto__').set;
set.call({}, null);
// setter not poisoned, it can promote
// Firefox, Chrome
setPrototypeOf = function (origin, proto) {
set.call(origin, proto);
return origin;
};
} catch (e) {
// do one or more feature detections
set = { __proto__: null };
// if proto does not work, needs to fallback
// some Opera, Rhino, ducktape
if (set instanceof Object) {
setPrototypeOf = createAndCopy;
} else {
// verify if null objects are buggy
/* eslint-disable no-proto */
set.__proto__ = objProto;
/* eslint-enable no-proto */
// if null objects are buggy
// nodejs 0.8 to 0.10
if (set instanceof Object) {
setPrototypeOf = function (origin, proto) {
// use such bug to promote
/* eslint-disable no-proto */
origin.__proto__ = proto;
/* eslint-enable no-proto */
return origin;
};
} else {
// try to use proto or fallback
// Safari, old Firefox, many others
setPrototypeOf = function (origin, proto) {
// if proto is not null
if (getPrototypeOf(origin)) {
// use __proto__ to promote
/* eslint-disable no-proto */
origin.__proto__ = proto;
/* eslint-enable no-proto */
return origin;
} else {
// otherwise unable to promote: fallback
return createAndCopy(origin, proto);
}
};
}
}
}
Object.setPrototypeOf = setPrototypeOf;
}());