es5-sham.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. // Copyright 2009-2012 by contributors, MIT License
  2. // vim: ts=4 sts=4 sw=4 expandtab
  3. // Module systems magic dance
  4. (function (definition) {
  5. // RequireJS
  6. if (typeof define == "function") {
  7. define(definition);
  8. // YUI3
  9. } else if (typeof YUI == "function") {
  10. YUI.add("es5-sham", definition);
  11. // CommonJS and <script>
  12. } else {
  13. definition();
  14. }
  15. })(function () {
  16. // ES5 15.2.3.2
  17. // http://es5.github.com/#x15.2.3.2
  18. if (!Object.getPrototypeOf) {
  19. // https://github.com/kriskowal/es5-shim/issues#issue/2
  20. // http://ejohn.org/blog/objectgetprototypeof/
  21. // recommended by fschaefer on github
  22. Object.getPrototypeOf = function getPrototypeOf(object) {
  23. return object.__proto__ || (
  24. object.constructor
  25. ? object.constructor.prototype
  26. : prototypeOfObject
  27. );
  28. };
  29. }
  30. var call = Function.prototype.call;
  31. var prototypeOfObject = Object.prototype;
  32. var owns = call.bind(prototypeOfObject.hasOwnProperty);
  33. var supportsAccessors;
  34. if ((supportsAccessors = owns(prototypeOfObject, "__defineGetter__"))) {
  35. defineGetter = call.bind(prototypeOfObject.__defineGetter__);
  36. defineSetter = call.bind(prototypeOfObject.__defineSetter__);
  37. lookupGetter = call.bind(prototypeOfObject.__lookupGetter__);
  38. lookupSetter = call.bind(prototypeOfObject.__lookupSetter__);
  39. }
  40. // ES5 15.2.3.3
  41. // http://es5.github.com/#x15.2.3.3
  42. if (!Object.getOwnPropertyDescriptor) {
  43. var ERR_NON_OBJECT = "Object.getOwnPropertyDescriptor called on a non-object: ";
  44. Object.getOwnPropertyDescriptor = function getOwnPropertyDescriptor(object, property) {
  45. if ((typeof object != "object" && typeof object != "function") || object === null) {
  46. throw new TypeError(ERR_NON_OBJECT + object);
  47. }
  48. // If object does not owns property return undefined immediately.
  49. if (!owns(object, property)) {
  50. return;
  51. }
  52. // If object has a property then it's for sure both `enumerable` and
  53. // `configurable`.
  54. var descriptor = { enumerable: true, configurable: true };
  55. // If JS engine supports accessor properties then property may be a
  56. // getter or setter.
  57. if (supportsAccessors) {
  58. // Unfortunately `__lookupGetter__` will return a getter even
  59. // if object has own non getter property along with a same named
  60. // inherited getter. To avoid misbehavior we temporary remove
  61. // `__proto__` so that `__lookupGetter__` will return getter only
  62. // if it's owned by an object.
  63. var prototype = object.__proto__;
  64. object.__proto__ = prototypeOfObject;
  65. var getter = lookupGetter(object, property);
  66. var setter = lookupSetter(object, property);
  67. // Once we have getter and setter we can put values back.
  68. object.__proto__ = prototype;
  69. if (getter || setter) {
  70. if (getter) {
  71. descriptor.get = getter;
  72. }
  73. if (setter) {
  74. descriptor.set = setter;
  75. }
  76. // If it was accessor property we're done and return here
  77. // in order to avoid adding `value` to the descriptor.
  78. return descriptor;
  79. }
  80. }
  81. // If we got this far we know that object has an own property that is
  82. // not an accessor so we set it as a value and return descriptor.
  83. descriptor.value = object[property];
  84. return descriptor;
  85. };
  86. }
  87. // ES5 15.2.3.4
  88. // http://es5.github.com/#x15.2.3.4
  89. if (!Object.getOwnPropertyNames) {
  90. Object.getOwnPropertyNames = function getOwnPropertyNames(object) {
  91. return Object.keys(object);
  92. };
  93. }
  94. // ES5 15.2.3.5
  95. // http://es5.github.com/#x15.2.3.5
  96. if (!Object.create) {
  97. Object.create = function create(prototype, properties) {
  98. var object;
  99. function Type() {} // An empty constructor.
  100. if (prototype === null) {
  101. object = { "__proto__": null };
  102. } else {
  103. if (typeof prototype !== "object" && typeof prototype !== "function") {
  104. // In the native implementation `parent` can be `null`
  105. // OR *any* `instanceof Object` (Object|Function|Array|RegExp|etc)
  106. // Use `typeof` tho, b/c in old IE, DOM elements are not `instanceof Object`
  107. // like they are in modern browsers. Using `Object.create` on DOM elements
  108. // is...err...probably inappropriate, but the native version allows for it.
  109. throw new TypeError("Object prototype may only be an Object or null"); // same msg as Chrome
  110. }
  111. Type.prototype = prototype;
  112. object = new Type();
  113. // IE has no built-in implementation of `Object.getPrototypeOf`
  114. // neither `__proto__`, but this manually setting `__proto__` will
  115. // guarantee that `Object.getPrototypeOf` will work as expected with
  116. // objects created using `Object.create`
  117. object.__proto__ = prototype;
  118. }
  119. if (properties !== void 0) {
  120. Object.defineProperties(object, properties);
  121. }
  122. return object;
  123. };
  124. }
  125. // ES5 15.2.3.6
  126. // http://es5.github.com/#x15.2.3.6
  127. // Patch for WebKit and IE8 standard mode
  128. // Designed by hax <hax.github.com>
  129. // related issue: https://github.com/kriskowal/es5-shim/issues#issue/5
  130. // IE8 Reference:
  131. // http://msdn.microsoft.com/en-us/library/dd282900.aspx
  132. // http://msdn.microsoft.com/en-us/library/dd229916.aspx
  133. // WebKit Bugs:
  134. // https://bugs.webkit.org/show_bug.cgi?id=36423
  135. function doesDefinePropertyWork(object) {
  136. try {
  137. Object.defineProperty(object, "sentinel", {});
  138. return "sentinel" in object;
  139. } catch (exception) {
  140. // returns falsy
  141. }
  142. }
  143. // check whether defineProperty works if it's given. Otherwise,
  144. // shim partially.
  145. if (Object.defineProperty) {
  146. var definePropertyWorksOnObject = doesDefinePropertyWork({});
  147. var definePropertyWorksOnDom = typeof document == "undefined" ||
  148. doesDefinePropertyWork(document.createElement("div"));
  149. if (!definePropertyWorksOnObject || !definePropertyWorksOnDom) {
  150. var definePropertyFallback = Object.defineProperty;
  151. }
  152. }
  153. if (!Object.defineProperty || definePropertyFallback) {
  154. var ERR_NON_OBJECT_DESCRIPTOR = "Property description must be an object: ";
  155. var ERR_NON_OBJECT_TARGET = "Object.defineProperty called on non-object: "
  156. var ERR_ACCESSORS_NOT_SUPPORTED = "getters & setters can not be defined " +
  157. "on this javascript engine";
  158. Object.defineProperty = function defineProperty(object, property, descriptor) {
  159. if ((typeof object != "object" && typeof object != "function") || object === null) {
  160. throw new TypeError(ERR_NON_OBJECT_TARGET + object);
  161. }
  162. if ((typeof descriptor != "object" && typeof descriptor != "function") || descriptor === null) {
  163. throw new TypeError(ERR_NON_OBJECT_DESCRIPTOR + descriptor);
  164. }
  165. // make a valiant attempt to use the real defineProperty
  166. // for I8's DOM elements.
  167. if (definePropertyFallback) {
  168. try {
  169. return definePropertyFallback.call(Object, object, property, descriptor);
  170. } catch (exception) {
  171. // try the shim if the real one doesn't work
  172. }
  173. }
  174. // If it's a data property.
  175. if (owns(descriptor, "value")) {
  176. // fail silently if "writable", "enumerable", or "configurable"
  177. // are requested but not supported
  178. /*
  179. // alternate approach:
  180. if ( // can't implement these features; allow false but not true
  181. !(owns(descriptor, "writable") ? descriptor.writable : true) ||
  182. !(owns(descriptor, "enumerable") ? descriptor.enumerable : true) ||
  183. !(owns(descriptor, "configurable") ? descriptor.configurable : true)
  184. )
  185. throw new RangeError(
  186. "This implementation of Object.defineProperty does not " +
  187. "support configurable, enumerable, or writable."
  188. );
  189. */
  190. if (supportsAccessors && (lookupGetter(object, property) ||
  191. lookupSetter(object, property)))
  192. {
  193. // As accessors are supported only on engines implementing
  194. // `__proto__` we can safely override `__proto__` while defining
  195. // a property to make sure that we don't hit an inherited
  196. // accessor.
  197. var prototype = object.__proto__;
  198. object.__proto__ = prototypeOfObject;
  199. // Deleting a property anyway since getter / setter may be
  200. // defined on object itself.
  201. delete object[property];
  202. object[property] = descriptor.value;
  203. // Setting original `__proto__` back now.
  204. object.__proto__ = prototype;
  205. } else {
  206. object[property] = descriptor.value;
  207. }
  208. } else {
  209. if (!supportsAccessors) {
  210. throw new TypeError(ERR_ACCESSORS_NOT_SUPPORTED);
  211. }
  212. // If we got that far then getters and setters can be defined !!
  213. if (owns(descriptor, "get")) {
  214. defineGetter(object, property, descriptor.get);
  215. }
  216. if (owns(descriptor, "set")) {
  217. defineSetter(object, property, descriptor.set);
  218. }
  219. }
  220. return object;
  221. };
  222. }
  223. // ES5 15.2.3.7
  224. // http://es5.github.com/#x15.2.3.7
  225. if (!Object.defineProperties) {
  226. Object.defineProperties = function defineProperties(object, properties) {
  227. for (var property in properties) {
  228. if (owns(properties, property) && property != "__proto__") {
  229. Object.defineProperty(object, property, properties[property]);
  230. }
  231. }
  232. return object;
  233. };
  234. }
  235. // ES5 15.2.3.8
  236. // http://es5.github.com/#x15.2.3.8
  237. if (!Object.seal) {
  238. Object.seal = function seal(object) {
  239. // this is misleading and breaks feature-detection, but
  240. // allows "securable" code to "gracefully" degrade to working
  241. // but insecure code.
  242. return object;
  243. };
  244. }
  245. // ES5 15.2.3.9
  246. // http://es5.github.com/#x15.2.3.9
  247. if (!Object.freeze) {
  248. Object.freeze = function freeze(object) {
  249. // this is misleading and breaks feature-detection, but
  250. // allows "securable" code to "gracefully" degrade to working
  251. // but insecure code.
  252. return object;
  253. };
  254. }
  255. // detect a Rhino bug and patch it
  256. try {
  257. Object.freeze(function () {});
  258. } catch (exception) {
  259. Object.freeze = (function freeze(freezeObject) {
  260. return function freeze(object) {
  261. if (typeof object == "function") {
  262. return object;
  263. } else {
  264. return freezeObject(object);
  265. }
  266. };
  267. })(Object.freeze);
  268. }
  269. // ES5 15.2.3.10
  270. // http://es5.github.com/#x15.2.3.10
  271. if (!Object.preventExtensions) {
  272. Object.preventExtensions = function preventExtensions(object) {
  273. // this is misleading and breaks feature-detection, but
  274. // allows "securable" code to "gracefully" degrade to working
  275. // but insecure code.
  276. return object;
  277. };
  278. }
  279. // ES5 15.2.3.11
  280. // http://es5.github.com/#x15.2.3.11
  281. if (!Object.isSealed) {
  282. Object.isSealed = function isSealed(object) {
  283. return false;
  284. };
  285. }
  286. // ES5 15.2.3.12
  287. // http://es5.github.com/#x15.2.3.12
  288. if (!Object.isFrozen) {
  289. Object.isFrozen = function isFrozen(object) {
  290. return false;
  291. };
  292. }
  293. // ES5 15.2.3.13
  294. // http://es5.github.com/#x15.2.3.13
  295. if (!Object.isExtensible) {
  296. Object.isExtensible = function isExtensible(object) {
  297. // 1. If Type(O) is not Object throw a TypeError exception.
  298. if (Object(object) !== object) {
  299. throw new TypeError(); // TODO message
  300. }
  301. // 2. Return the Boolean value of the [[Extensible]] internal property of O.
  302. var name = '';
  303. while (owns(object, name)) {
  304. name += '?';
  305. }
  306. object[name] = true;
  307. var returnValue = owns(object, name);
  308. delete object[name];
  309. return returnValue;
  310. };
  311. }
  312. });