From 473586d5224f951398490cfbbf209a406ebe007a Mon Sep 17 00:00:00 2001 From: David Jackson Date: Wed, 15 Sep 2021 19:42:59 -0700 Subject: [PATCH] Port set-prototype-of to ext --- .DS_Store | Bin 0 -> 6148 bytes object/create.js | 43 ++++++++++++ object/is-object.js | 7 ++ object/set-prototype-of/implement.js | 10 +++ object/set-prototype-of/implementation.js | 81 ++++++++++++++++++++++ object/set-prototype-of/index.js | 3 + object/set-prototype-of/is-implemented.js | 9 +++ object/valid-value.js | 8 +++ 8 files changed, 161 insertions(+) create mode 100644 .DS_Store create mode 100644 object/create.js create mode 100644 object/is-object.js create mode 100644 object/set-prototype-of/implement.js create mode 100644 object/set-prototype-of/implementation.js create mode 100644 object/set-prototype-of/index.js create mode 100644 object/set-prototype-of/is-implemented.js create mode 100644 object/valid-value.js diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..22c89a4595fd9e77dd2ef8588ed12633659ecb86 GIT binary patch literal 6148 zcmeHKOKQU~5S>X)F?8c)mbyZ2AWU)sU!b%pfe;)hZPs4pTs>Ofd^WDzUAhTxVDzNX zJPEyp$0H)zf9^LTortt>L%G_pG}|{{*eW9mgyW1?`M3=4M z{ovakjS5f!DnJFO02R2c0$E?%r`sOO)2ILyxB~_3`%vJ9HE{~`PX`8X0e}s{ZkT&7 z0W1~(*2F0g5ts%Q7*x#`LxYZZ$-J641qNL-n-9&KH9Hjb+i`yJbkQ2fkqS_OxdIQd z?5zIp;D7Z0a}rlnfC}7|0@`ecZI35qZCyOhYHfi(!!73vZicy2FnBozdO60z%JJHh bBCpsS`!#V2bUNZr2l8jYbfHm!|5o4|v)2`s literal 0 HcmV?d00001 diff --git a/object/create.js b/object/create.js new file mode 100644 index 00000000..80eff64e --- /dev/null +++ b/object/create.js @@ -0,0 +1,43 @@ +// Workaround for http://code.google.com/p/v8/issues/detail?id=2804 + +"use strict"; + +var create = Object.create, shim; + +if (!require("./set-prototype-of/is-implemented")()) { + shim = require("./set-prototype-of/implementation"); +} + +module.exports = (function () { + var nullObject, polyProps, desc; + if (!shim) return create; + if (shim.level !== 1) return create; + + nullObject = {}; + polyProps = {}; + desc = { configurable: false, enumerable: false, writable: true, value: undefined }; + Object.getOwnPropertyNames(Object.prototype).forEach(function (name) { + if (name === "__proto__") { + polyProps[name] = { + configurable: true, + enumerable: false, + writable: true, + value: undefined + }; + return; + } + polyProps[name] = desc; + }); + Object.defineProperties(nullObject, polyProps); + + Object.defineProperty(shim, "nullPolyfill", { + configurable: false, + enumerable: false, + writable: false, + value: nullObject + }); + + return function (prototype, props) { + return create(prototype === null ? nullObject : prototype, props); + }; +})(); diff --git a/object/is-object.js b/object/is-object.js new file mode 100644 index 00000000..0e576d76 --- /dev/null +++ b/object/is-object.js @@ -0,0 +1,7 @@ +"use strict"; + +var isValue = require("./is-value"); + +var map = { function: true, object: true }; + +module.exports = function (value) { return (isValue(value) && map[typeof value]) || false; }; diff --git a/object/set-prototype-of/implement.js b/object/set-prototype-of/implement.js new file mode 100644 index 00000000..57cc93df --- /dev/null +++ b/object/set-prototype-of/implement.js @@ -0,0 +1,10 @@ +"use strict"; + +if (!require("./is-implemented")()) { + Object.defineProperty(Object, "setPrototypeOf", { + value: require("./implementation"), + configurable: true, + enumerable: false, + writable: true + }); +} diff --git a/object/set-prototype-of/implementation.js b/object/set-prototype-of/implementation.js new file mode 100644 index 00000000..97b0b504 --- /dev/null +++ b/object/set-prototype-of/implementation.js @@ -0,0 +1,81 @@ +/* eslint no-proto: "off" */ + +// Big thanks to @WebReflection for sorting this out +// https://gist.github.com/WebReflection/5593554 + +"use strict"; + +var isObject = require("../is-object") + , value = require("../valid-value") + , objIsPrototypeOf = Object.prototype.isPrototypeOf + , defineProperty = Object.defineProperty + , nullDesc = { configurable: true, enumerable: false, writable: true, value: undefined } + , validate; + +validate = function (obj, prototype) { + value(obj); + if (prototype === null || isObject(prototype)) return obj; + throw new TypeError("Prototype must be null or an object"); +}; + +module.exports = (function (status) { + var fn, set; + if (!status) return null; + if (status.level === 2) { + if (status.set) { + set = status.set; + fn = function (obj, prototype) { + set.call(validate(obj, prototype), prototype); + return obj; + }; + } else { + fn = function (obj, prototype) { + validate(obj, prototype).__proto__ = prototype; + return obj; + }; + } + } else { + fn = function self(obj, prototype) { + var isNullBase; + validate(obj, prototype); + isNullBase = objIsPrototypeOf.call(self.nullPolyfill, obj); + if (isNullBase) delete self.nullPolyfill.__proto__; + if (prototype === null) prototype = self.nullPolyfill; + obj.__proto__ = prototype; + if (isNullBase) defineProperty(self.nullPolyfill, "__proto__", nullDesc); + return obj; + }; + } + return Object.defineProperty(fn, "level", { + configurable: false, + enumerable: false, + writable: false, + value: status.level + }); +})( + (function () { + var tmpObj1 = Object.create(null) + , tmpObj2 = {} + , set + , desc = Object.getOwnPropertyDescriptor(Object.prototype, "__proto__"); + + if (desc) { + try { + set = desc.set; // Opera crashes at this point + set.call(tmpObj1, tmpObj2); + } catch (ignore) {} + if (Object.getPrototypeOf(tmpObj1) === tmpObj2) return { set: set, level: 2 }; + } + + tmpObj1.__proto__ = tmpObj2; + if (Object.getPrototypeOf(tmpObj1) === tmpObj2) return { level: 2 }; + + tmpObj1 = {}; + tmpObj1.__proto__ = tmpObj2; + if (Object.getPrototypeOf(tmpObj1) === tmpObj2) return { level: 1 }; + + return false; + })() +); + +require("../create"); diff --git a/object/set-prototype-of/index.js b/object/set-prototype-of/index.js new file mode 100644 index 00000000..d2ddf0a0 --- /dev/null +++ b/object/set-prototype-of/index.js @@ -0,0 +1,3 @@ +"use strict"; + +module.exports = require("./is-implemented")() ? Object.setPrototypeOf : require("./implementation"); diff --git a/object/set-prototype-of/is-implemented.js b/object/set-prototype-of/is-implemented.js new file mode 100644 index 00000000..1a00627b --- /dev/null +++ b/object/set-prototype-of/is-implemented.js @@ -0,0 +1,9 @@ +"use strict"; + +var create = Object.create, getPrototypeOf = Object.getPrototypeOf, plainObject = {}; + +module.exports = function (/* CustomCreate*/) { + var setPrototypeOf = Object.setPrototypeOf, customCreate = arguments[0] || create; + if (typeof setPrototypeOf !== "function") return false; + return getPrototypeOf(setPrototypeOf(customCreate(null), plainObject)) === plainObject; +}; diff --git a/object/valid-value.js b/object/valid-value.js new file mode 100644 index 00000000..d0ced8a4 --- /dev/null +++ b/object/valid-value.js @@ -0,0 +1,8 @@ +"use strict"; + +var isValue = require("./is-value"); + +module.exports = function (value) { + if (!isValue(value)) throw new TypeError("Cannot use null or undefined"); + return value; +};