Skip to content

Commit

Permalink
extract es5-sham Object.create(null) shim
Browse files Browse the repository at this point in the history
  • Loading branch information
stefanpenner committed Jul 24, 2014
1 parent 7a9dd16 commit 2fde5b7
Showing 1 changed file with 104 additions and 38 deletions.
142 changes: 104 additions & 38 deletions packages/ember-metal/lib/platform.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,44 +16,6 @@ import Ember from "ember-metal/core";
// TODO remove this
var platform = {};

/**
Identical to `Object.create()`. Implements if not available natively.
@method create
@for Ember
*/
var create = Object.create;

// IE8 has Object.create but it couldn't treat property descriptors.
if (create) {
if (create({a: 1}, {a: {value: 2}}).a !== 2) {
create = null;
}
}

// STUB_OBJECT_CREATE allows us to override other libraries that stub
// Object.create different than we would prefer
if (!create || Ember.ENV.STUB_OBJECT_CREATE) {
var K = function() {};

create = function(obj, props) {
K.prototype = obj;
obj = new K();
if (props) {
K.prototype = obj;
for (var prop in props) {
K.prototype[prop] = props[prop].value;
}
obj = new K();
}
K.prototype = null;

return obj;
};

create.isSimulated = true;
}

var defineProperty = Object.defineProperty;
var canRedefineProperties, canDefinePropertyOnDOM;

Expand Down Expand Up @@ -122,6 +84,110 @@ if (defineProperty) {
}
}

// ES5 15.2.3.7
// http://es5.github.com/#x15.2.3.7
if (!Object.defineProperties) {
Object.defineProperties = function defineProperties(object, properties) {
for (var property in properties) {
if (properties.hasOwnProperty(property) && property !== "__proto__") {
defineProperty(object, property, properties[property]);
}
}
return object;
};
}

/**
Identical to `Object.create()`. Implements if not available natively.
@method create
@for Ember
*/
var create;
// ES5 15.2.3.5
// http://es5.github.com/#x15.2.3.5
if (!(Object.create && !Object.create(null).hasOwnProperty)) {
/* jshint scripturl:true, proto:true */
// Contributed by Brandon Benvie, October, 2012
var createEmpty;
var supportsProto = !({'__proto__':null} instanceof Object);
// the following produces false positives
// in Opera Mini => not a reliable check
// Object.prototype.__proto__ === null
if (supportsProto || typeof document === 'undefined') {
createEmpty = function () {
return { "__proto__": null };
};
} else {
// In old IE __proto__ can't be used to manually set `null`, nor does
// any other method exist to make an object that inherits from nothing,
// aside from Object.prototype itself. Instead, create a new global
// object and *steal* its Object.prototype and strip it bare. This is
// used as the prototype to create nullary objects.
createEmpty = function () {
var iframe = document.createElement('iframe');
var parent = document.body || document.documentElement;
iframe.style.display = 'none';
parent.appendChild(iframe);
iframe.src = 'javascript:';
var empty = iframe.contentWindow.Object.prototype;
parent.removeChild(iframe);
iframe = null;
delete empty.constructor;
delete empty.hasOwnProperty;
delete empty.propertyIsEnumerable;
delete empty.isPrototypeOf;
delete empty.toLocaleString;
delete empty.toString;
delete empty.valueOf;
empty.__proto__ = null;

function Empty() {}
Empty.prototype = empty;
// short-circuit future calls
createEmpty = function () {
return new Empty();
};
return new Empty();
};
}

create = Object.create = function create(prototype, properties) {

var object;
function Type() {} // An empty constructor.

if (prototype === null) {
object = createEmpty();
} else {
if (typeof prototype !== "object" && typeof prototype !== "function") {
// In the native implementation `parent` can be `null`
// OR *any* `instanceof Object` (Object|Function|Array|RegExp|etc)
// Use `typeof` tho, b/c in old IE, DOM elements are not `instanceof Object`
// like they are in modern browsers. Using `Object.create` on DOM elements
// is...err...probably inappropriate, but the native version allows for it.
throw new TypeError("Object prototype may only be an Object or null"); // same msg as Chrome
}
Type.prototype = prototype;
object = new Type();
// IE has no built-in implementation of `Object.getPrototypeOf`
// neither `__proto__`, but this manually setting `__proto__` will
// guarantee that `Object.getPrototypeOf` will work as expected with
// objects created using `Object.create`
object.__proto__ = prototype;
}

if (properties !== void 0) {
Object.defineProperties(object, properties);
}

return object;
};
} else {
create = Object.create;
}


/**
@class platform
@namespace Ember
Expand Down

0 comments on commit 2fde5b7

Please sign in to comment.