/*! * https://github.com/es-shims/es5-shim * @license es5-shim copyright 2009-2015 by contributors, mit license * see https://github.com/es-shims/es5-shim/blob/master/license */ // vim: ts=4 sts=4 sw=4 expandtab // add semicolon to prevent iife from being passed as argument to concatenated code. ; // umd (universal module definition) // see https://github.com/umdjs/umd/blob/master/templates/returnexports.js (function (root, factory) { 'use strict'; /* global define, exports, module */ if (typeof define === 'function' && define.amd) { // amd. register as an anonymous module. define(factory); } else if (typeof exports === 'object') { // node. does not work with strict commonjs, but // only commonjs-like enviroments that support module.exports, // like node. module.exports = factory(); } else { // browser globals (root is window) root.returnexports = factory(); } }(this, function () { var call = function.call; var prototypeofobject = object.prototype; var owns = call.bind(prototypeofobject.hasownproperty); var isenumerable = call.bind(prototypeofobject.propertyisenumerable); var tostr = call.bind(prototypeofobject.tostring); // if js engine supports accessors creating shortcuts. var definegetter; var definesetter; var lookupgetter; var lookupsetter; var supportsaccessors = owns(prototypeofobject, '__definegetter__'); if (supportsaccessors) { /* eslint-disable no-underscore-dangle */ definegetter = call.bind(prototypeofobject.__definegetter__); definesetter = call.bind(prototypeofobject.__definesetter__); lookupgetter = call.bind(prototypeofobject.__lookupgetter__); lookupsetter = call.bind(prototypeofobject.__lookupsetter__); /* eslint-enable no-underscore-dangle */ } var isprimitive = function isprimitive(o) { return o == null || (typeof o !== 'object' && typeof o !== 'function'); }; // es5 15.2.3.2 // http://es5.github.com/#x15.2.3.2 if (!object.getprototypeof) { // https://github.com/es-shims/es5-shim/issues#issue/2 // http://ejohn.org/blog/objectgetprototypeof/ // recommended by fschaefer on github // // sure, and webreflection says ^_^ // ... this will nerever possibly return null // ... opera mini breaks here with infinite loops object.getprototypeof = function getprototypeof(object) { /* eslint-disable no-proto */ var proto = object.__proto__; /* eslint-enable no-proto */ if (proto || proto === null) { return proto; } else if (tostr(object.constructor) === '[object function]') { return object.constructor.prototype; } else if (object instanceof object) { return prototypeofobject; } else { // correctly return null for objects created with `object.create(null)` // (shammed or native) or `{ __proto__: null}`. also returns null for // cross-realm objects on browsers that lack `__proto__` support (like // ie <11), but that's the best we can do. return null; } }; } // es5 15.2.3.3 // http://es5.github.com/#x15.2.3.3 var doesgetownpropertydescriptorwork = function doesgetownpropertydescriptorwork(object) { try { object.sentinel = 0; return object.getownpropertydescriptor(object, 'sentinel').value === 0; } catch (exception) { return false; } }; // check whether getownpropertydescriptor works if it's given. otherwise, shim partially. if (object.defineproperty) { var getownpropertydescriptorworksonobject = doesgetownpropertydescriptorwork({}); var getownpropertydescriptorworksondom = typeof document === 'undefined' || doesgetownpropertydescriptorwork(document.createelement('div')); if (!getownpropertydescriptorworksondom || !getownpropertydescriptorworksonobject) { var getownpropertydescriptorfallback = object.getownpropertydescriptor; } } if (!object.getownpropertydescriptor || getownpropertydescriptorfallback) { var err_non_object = 'object.getownpropertydescriptor called on a non-object: '; /* eslint-disable no-proto */ object.getownpropertydescriptor = function getownpropertydescriptor(object, property) { if (isprimitive(object)) { throw new typeerror(err_non_object + object); } // make a valiant attempt to use the real getownpropertydescriptor // for i8's dom elements. if (getownpropertydescriptorfallback) { try { return getownpropertydescriptorfallback.call(object, object, property); } catch (exception) { // try the shim if the real one doesn't work } } var descriptor; // if object does not owns property return undefined immediately. if (!owns(object, property)) { return descriptor; } // if object has a property then it's for sure `configurable`, and // probably `enumerable`. detect enumerability though. descriptor = { enumerable: isenumerable(object, property), configurable: true }; // if js engine supports accessor properties then property may be a // getter or setter. if (supportsaccessors) { // unfortunately `__lookupgetter__` will return a getter even // if object has own non getter property along with a same named // inherited getter. to avoid misbehavior we temporary remove // `__proto__` so that `__lookupgetter__` will return getter only // if it's owned by an object. var prototype = object.__proto__; var notprototypeofobject = object !== prototypeofobject; // avoid recursion problem, breaking in opera mini when // object.getownpropertydescriptor(object.prototype, 'tostring') // or any other object.prototype accessor if (notprototypeofobject) { object.__proto__ = prototypeofobject; } var getter = lookupgetter(object, property); var setter = lookupsetter(object, property); if (notprototypeofobject) { // once we have getter and setter we can put values back. object.__proto__ = prototype; } if (getter || setter) { if (getter) { descriptor.get = getter; } if (setter) { descriptor.set = setter; } // if it was accessor property we're done and return here // in order to avoid adding `value` to the descriptor. return descriptor; } } // if we got this far we know that object has an own property that is // not an accessor so we set it as a value and return descriptor. descriptor.value = object[property]; descriptor.writable = true; return descriptor; }; /* eslint-enable no-proto */ } // es5 15.2.3.4 // http://es5.github.com/#x15.2.3.4 if (!object.getownpropertynames) { object.getownpropertynames = function getownpropertynames(object) { return object.keys(object); }; } // es5 15.2.3.5 // http://es5.github.com/#x15.2.3.5 if (!object.create) { // 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 // check for document.domain and active x support // no need to use active x approach when document.domain is not set // see https://github.com/es-shims/es5-shim/issues/150 // variation of https://github.com/kitcambridge/es5-shim/commit/4f738ac066346 /* global activexobject */ var shoulduseactivex = function shoulduseactivex() { // return early if document.domain not set if (!document.domain) { return false; } try { return !!new activexobject('htmlfile'); } catch (exception) { return false; } }; // this supports ie8 when document.domain is used // see https://github.com/es-shims/es5-shim/issues/150 // variation of https://github.com/kitcambridge/es5-shim/commit/4f738ac066346 var getemptyviaactivex = function getemptyviaactivex() { var empty; var xdoc; xdoc = new activexobject('htmlfile'); var script = 'script'; xdoc.write('<' + script + '>'); xdoc.close(); empty = xdoc.parentwindow.object.prototype; xdoc = null; return empty; }; // the original implementation using an iframe // before the activex approach was added // see https://github.com/es-shims/es5-shim/issues/150 var getemptyviaiframe = function getemptyviaiframe() { var iframe = document.createelement('iframe'); var parent = document.body || document.documentelement; var empty; iframe.style.display = 'none'; parent.appendchild(iframe); /* eslint-disable no-script-url */ iframe.src = 'javascript:'; /* eslint-enable no-script-url */ empty = iframe.contentwindow.object.prototype; parent.removechild(iframe); iframe = null; return empty; }; /* global document */ 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 () { // determine which approach to use // see https://github.com/es-shims/es5-shim/issues/150 var empty = shoulduseactivex() ? getemptyviaactivex() : getemptyviaiframe(); delete empty.constructor; delete empty.hasownproperty; delete empty.propertyisenumerable; delete empty.isprototypeof; delete empty.tolocalestring; delete empty.tostring; delete empty.valueof; var empty = function empty() {}; empty.prototype = empty; // short-circuit future calls createempty = function () { return new empty(); }; return new empty(); }; } object.create = function create(prototype, properties) { var object; var type = function type() {}; // an empty constructor. if (prototype === null) { object = createempty(); } else { if (prototype !== null && isprimitive(prototype)) { // 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` /* eslint-disable no-proto */ object.__proto__ = prototype; /* eslint-enable no-proto */ } if (properties !== void 0) { object.defineproperties(object, properties); } return object; }; } // es5 15.2.3.6 // http://es5.github.com/#x15.2.3.6 // patch for webkit and ie8 standard mode // designed by hax // related issue: https://github.com/es-shims/es5-shim/issues#issue/5 // ie8 reference: // http://msdn.microsoft.com/en-us/library/dd282900.aspx // http://msdn.microsoft.com/en-us/library/dd229916.aspx // webkit bugs: // https://bugs.webkit.org/show_bug.cgi?id=36423 var doesdefinepropertywork = function doesdefinepropertywork(object) { try { object.defineproperty(object, 'sentinel', {}); return 'sentinel' in object; } catch (exception) { return false; } }; // check whether defineproperty works if it's given. otherwise, // shim partially. if (object.defineproperty) { var definepropertyworksonobject = doesdefinepropertywork({}); var definepropertyworksondom = typeof document === 'undefined' || doesdefinepropertywork(document.createelement('div')); if (!definepropertyworksonobject || !definepropertyworksondom) { var definepropertyfallback = object.defineproperty, definepropertiesfallback = object.defineproperties; } } if (!object.defineproperty || definepropertyfallback) { var err_non_object_descriptor = 'property description must be an object: '; var err_non_object_target = 'object.defineproperty called on non-object: '; var err_accessors_not_supported = 'getters & setters can not be defined on this javascript engine'; object.defineproperty = function defineproperty(object, property, descriptor) { if (isprimitive(object)) { throw new typeerror(err_non_object_target + object); } if (isprimitive(descriptor)) { throw new typeerror(err_non_object_descriptor + descriptor); } // make a valiant attempt to use the real defineproperty // for i8's dom elements. if (definepropertyfallback) { try { return definepropertyfallback.call(object, object, property, descriptor); } catch (exception) { // try the shim if the real one doesn't work } } // if it's a data property. if ('value' in descriptor) { // fail silently if 'writable', 'enumerable', or 'configurable' // are requested but not supported /* // alternate approach: if ( // can't implement these features; allow false but not true ('writable' in descriptor && !descriptor.writable) || ('enumerable' in descriptor && !descriptor.enumerable) || ('configurable' in descriptor && !descriptor.configurable) )) throw new rangeerror( 'this implementation of object.defineproperty does not support configurable, enumerable, or writable.' ); */ if (supportsaccessors && (lookupgetter(object, property) || lookupsetter(object, property))) { // as accessors are supported only on engines implementing // `__proto__` we can safely override `__proto__` while defining // a property to make sure that we don't hit an inherited // accessor. /* eslint-disable no-proto */ var prototype = object.__proto__; object.__proto__ = prototypeofobject; // deleting a property anyway since getter / setter may be // defined on object itself. delete object[property]; object[property] = descriptor.value; // setting original `__proto__` back now. object.__proto__ = prototype; /* eslint-enable no-proto */ } else { object[property] = descriptor.value; } } else { var hasgetter = 'get' in descriptor; var hassetter = 'set' in descriptor; if (!supportsaccessors && (hasgetter || hassetter)) { throw new typeerror(err_accessors_not_supported); } // if we got that far then getters and setters can be defined !! if (hasgetter) { definegetter(object, property, descriptor.get); } if (hassetter) { definesetter(object, property, descriptor.set); } } return object; }; } // es5 15.2.3.7 // http://es5.github.com/#x15.2.3.7 if (!object.defineproperties || definepropertiesfallback) { object.defineproperties = function defineproperties(object, properties) { // make a valiant attempt to use the real defineproperties if (definepropertiesfallback) { try { return definepropertiesfallback.call(object, object, properties); } catch (exception) { // try the shim if the real one doesn't work } } object.keys(properties).foreach(function (property) { if (property !== '__proto__') { object.defineproperty(object, property, properties[property]); } }); return object; }; } // es5 15.2.3.8 // http://es5.github.com/#x15.2.3.8 if (!object.seal) { object.seal = function seal(object) { if (object(object) !== object) { throw new typeerror('object.seal can only be called on objects.'); } // this is misleading and breaks feature-detection, but // allows "securable" code to "gracefully" degrade to working // but insecure code. return object; }; } // es5 15.2.3.9 // http://es5.github.com/#x15.2.3.9 if (!object.freeze) { object.freeze = function freeze(object) { if (object(object) !== object) { throw new typeerror('object.freeze can only be called on objects.'); } // this is misleading and breaks feature-detection, but // allows "securable" code to "gracefully" degrade to working // but insecure code. return object; }; } // detect a rhino bug and patch it try { object.freeze(function () {}); } catch (exception) { object.freeze = (function (freezeobject) { return function freeze(object) { if (typeof object === 'function') { return object; } else { return freezeobject(object); } }; }(object.freeze)); } // es5 15.2.3.10 // http://es5.github.com/#x15.2.3.10 if (!object.preventextensions) { object.preventextensions = function preventextensions(object) { if (object(object) !== object) { throw new typeerror('object.preventextensions can only be called on objects.'); } // this is misleading and breaks feature-detection, but // allows "securable" code to "gracefully" degrade to working // but insecure code. return object; }; } // es5 15.2.3.11 // http://es5.github.com/#x15.2.3.11 if (!object.issealed) { object.issealed = function issealed(object) { if (object(object) !== object) { throw new typeerror('object.issealed can only be called on objects.'); } return false; }; } // es5 15.2.3.12 // http://es5.github.com/#x15.2.3.12 if (!object.isfrozen) { object.isfrozen = function isfrozen(object) { if (object(object) !== object) { throw new typeerror('object.isfrozen can only be called on objects.'); } return false; }; } // es5 15.2.3.13 // http://es5.github.com/#x15.2.3.13 if (!object.isextensible) { object.isextensible = function isextensible(object) { // 1. if type(o) is not object throw a typeerror exception. if (object(object) !== object) { throw new typeerror('object.isextensible can only be called on objects.'); } // 2. return the boolean value of the [[extensible]] internal property of o. var name = ''; while (owns(object, name)) { name += '?'; } object[name] = true; var returnvalue = owns(object, name); delete object[name]; return returnvalue; }; } }));