Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix issue 29 #31

Merged
merged 5 commits into from
Apr 21, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 55 additions & 10 deletions object.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,16 +120,22 @@ define(function (require) {
'object-isextensible': 'isExtensible',
'object-preventextensions': 'preventExtensions',
'object-defineproperty-obj': function () {
return hasDefineProperty({});
return hasDefineProperty({}, 'sentinel1', { value: true });
},
'object-defineproperty-dom': function () {
return doc && hasDefineProperty(testEl);
return doc && hasDefineProperty(testEl, 'sentinel1', { value: true });
},
'object-defineproperty-function': function () {
return hasDefineProperty(function () {}, 'prototype', { value: { test: true } });
},
'object-defineproperties-obj': function () {
return hasDefineProperties({});
return hasDefineProperties({}, { 'sentinel2': { value: true } });
},
'object-defineproperties-dom': function () {
return doc && hasDefineProperties(testEl);
return doc && hasDefineProperties(testEl, { 'sentinel2': { value: true } });
},
'object-defineproperties-function': function () {
return hasDefineProperties(function () {}, { 'prototype': { value: { test: true } } });
},
'object-getownpropertydescriptor-obj': function () {
return hasGetOwnPropertyDescriptor({});
Expand Down Expand Up @@ -196,6 +202,13 @@ define(function (require) {
? useNativeForDom(Object.defineProperties, defineProperties)
: defineProperties;
}
else {
// check if it can assign a value to a function's prototype
if (!has('object-defineproperties-function')) {
Object.defineProperties = shims.defineProperties
= definePropertiesFunctionPrototype(Object.defineProperties, defineProperties);
}
}

if (!has('object-defineproperty-obj')) {
// check if dom has it (IE8)
Expand All @@ -204,6 +217,13 @@ define(function (require) {
? useNativeForDom(Object.defineProperty, defineProperty)
: defineProperty;
}
else {
// check if it can assign a value to a function's prototype
if (!has('object-defineproperty-function')) {
Object.defineProperty = shims.defineProperty
= definePropertyFunctionPrototype(Object.defineProperty, defineProperty);
}
}

if (!has('object-isextensible')) {
Object.isExtensible = shims.isExtensible = isExtensible;
Expand All @@ -221,25 +241,34 @@ define(function (require) {
: getOwnPropertyDescriptor;
}

function hasDefineProperty (object) {
function hasDefineProperty (object, prop, descriptor) {
if (('defineProperty' in Object)) {
try {
// test it
Object.defineProperty(object, 'sentinel1', { value: true })
return object['sentinel1'] === true;
Object.defineProperty(object, prop, descriptor);
return object[prop] === descriptor.value;
}
catch (ex) { /* squelch */ }
}
}

// Note: MSDN docs say that IE8 has this function, but tests show
// that it does not! JMH
function hasDefineProperties (object) {
function hasDefineProperties (object, props) {
var keys, property;

if (('defineProperties' in Object)) {
try {
// test it
Object.defineProperties(object, { 'sentinel2': { value: true } })
return object['sentinel2'] === true;
Object.defineProperties(object, props);
keys = _keys(props);

while (property = keys.pop()) {
if (object[property] !== props[property].value) {
return false;
}
}
return true;
}
catch (ex) { /* squelch */ }
}
Expand Down Expand Up @@ -308,11 +337,27 @@ define(function (require) {
return object;
}

function definePropertiesFunctionPrototype (orig, shim) {
return function (object, descriptors) {
return (!!descriptors['prototype'] && typeof object === 'function')
? shim.apply(this, arguments) // use shim
: orig.apply(this, arguments); // use native
};
}

function defineProperty (object, name, descriptor) {
object[name] = descriptor && descriptor.value;
return object;
}

function definePropertyFunctionPrototype (orig, shim) {
return function (object, name, descriptor) {
return (name === 'prototype' && typeof object === 'function')
? shim.apply(this, arguments) // use shim
: orig.apply(this, arguments); // use native
};
}

function getOwnPropertyDescriptor (object, name) {
return hasProp(object, name)
? {
Expand Down
19 changes: 19 additions & 0 deletions test/object.html
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,13 @@
Object.defineProperty(test, 'foo', { value: 5 });
return test.foo == 5;
});
tester.assertTrue("Object.defineProperty should define the prototype property correctly", function () {
function fn() {};

Object.defineProperty(fn, 'prototype', { value: { test: true } });

return fn.prototype.test === true && (new fn).test === true;
});
tester.assertTrue('Object.defineProperties should add several properties', function () {
var test = {};
// writable and get don't actually work, just putting them in here
Expand All @@ -267,6 +274,18 @@
});
return test.foo == 5 && test.bar == 27;
});
tester.assertTrue("Object.defineProperties should define the prototype property correctly", function () {
function fn() {};

Object.defineProperties(fn, {
prototype: {
value: {
test: true
}
}
});
return fn.prototype.test === true && (new fn).test === true;
});

// test getOwnPropertyDescriptor
tester.assertTrue('Object.getOwnPropertyDescriptor should return a factual descriptor object', function () {
Expand Down