| /* 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"); |