1 | 'use strict';
|
---|
2 |
|
---|
3 | var keysShim;
|
---|
4 | if (!Object.keys) {
|
---|
5 | // modified from https://github.com/es-shims/es5-shim
|
---|
6 | var has = Object.prototype.hasOwnProperty;
|
---|
7 | var toStr = Object.prototype.toString;
|
---|
8 | var isArgs = require('./isArguments'); // eslint-disable-line global-require
|
---|
9 | var isEnumerable = Object.prototype.propertyIsEnumerable;
|
---|
10 | var hasDontEnumBug = !isEnumerable.call({ toString: null }, 'toString');
|
---|
11 | var hasProtoEnumBug = isEnumerable.call(function () {}, 'prototype');
|
---|
12 | var dontEnums = [
|
---|
13 | 'toString',
|
---|
14 | 'toLocaleString',
|
---|
15 | 'valueOf',
|
---|
16 | 'hasOwnProperty',
|
---|
17 | 'isPrototypeOf',
|
---|
18 | 'propertyIsEnumerable',
|
---|
19 | 'constructor'
|
---|
20 | ];
|
---|
21 | var equalsConstructorPrototype = function (o) {
|
---|
22 | var ctor = o.constructor;
|
---|
23 | return ctor && ctor.prototype === o;
|
---|
24 | };
|
---|
25 | var excludedKeys = {
|
---|
26 | $applicationCache: true,
|
---|
27 | $console: true,
|
---|
28 | $external: true,
|
---|
29 | $frame: true,
|
---|
30 | $frameElement: true,
|
---|
31 | $frames: true,
|
---|
32 | $innerHeight: true,
|
---|
33 | $innerWidth: true,
|
---|
34 | $onmozfullscreenchange: true,
|
---|
35 | $onmozfullscreenerror: true,
|
---|
36 | $outerHeight: true,
|
---|
37 | $outerWidth: true,
|
---|
38 | $pageXOffset: true,
|
---|
39 | $pageYOffset: true,
|
---|
40 | $parent: true,
|
---|
41 | $scrollLeft: true,
|
---|
42 | $scrollTop: true,
|
---|
43 | $scrollX: true,
|
---|
44 | $scrollY: true,
|
---|
45 | $self: true,
|
---|
46 | $webkitIndexedDB: true,
|
---|
47 | $webkitStorageInfo: true,
|
---|
48 | $window: true
|
---|
49 | };
|
---|
50 | var hasAutomationEqualityBug = (function () {
|
---|
51 | /* global window */
|
---|
52 | if (typeof window === 'undefined') { return false; }
|
---|
53 | for (var k in window) {
|
---|
54 | try {
|
---|
55 | if (!excludedKeys['$' + k] && has.call(window, k) && window[k] !== null && typeof window[k] === 'object') {
|
---|
56 | try {
|
---|
57 | equalsConstructorPrototype(window[k]);
|
---|
58 | } catch (e) {
|
---|
59 | return true;
|
---|
60 | }
|
---|
61 | }
|
---|
62 | } catch (e) {
|
---|
63 | return true;
|
---|
64 | }
|
---|
65 | }
|
---|
66 | return false;
|
---|
67 | }());
|
---|
68 | var equalsConstructorPrototypeIfNotBuggy = function (o) {
|
---|
69 | /* global window */
|
---|
70 | if (typeof window === 'undefined' || !hasAutomationEqualityBug) {
|
---|
71 | return equalsConstructorPrototype(o);
|
---|
72 | }
|
---|
73 | try {
|
---|
74 | return equalsConstructorPrototype(o);
|
---|
75 | } catch (e) {
|
---|
76 | return false;
|
---|
77 | }
|
---|
78 | };
|
---|
79 |
|
---|
80 | keysShim = function keys(object) {
|
---|
81 | var isObject = object !== null && typeof object === 'object';
|
---|
82 | var isFunction = toStr.call(object) === '[object Function]';
|
---|
83 | var isArguments = isArgs(object);
|
---|
84 | var isString = isObject && toStr.call(object) === '[object String]';
|
---|
85 | var theKeys = [];
|
---|
86 |
|
---|
87 | if (!isObject && !isFunction && !isArguments) {
|
---|
88 | throw new TypeError('Object.keys called on a non-object');
|
---|
89 | }
|
---|
90 |
|
---|
91 | var skipProto = hasProtoEnumBug && isFunction;
|
---|
92 | if (isString && object.length > 0 && !has.call(object, 0)) {
|
---|
93 | for (var i = 0; i < object.length; ++i) {
|
---|
94 | theKeys.push(String(i));
|
---|
95 | }
|
---|
96 | }
|
---|
97 |
|
---|
98 | if (isArguments && object.length > 0) {
|
---|
99 | for (var j = 0; j < object.length; ++j) {
|
---|
100 | theKeys.push(String(j));
|
---|
101 | }
|
---|
102 | } else {
|
---|
103 | for (var name in object) {
|
---|
104 | if (!(skipProto && name === 'prototype') && has.call(object, name)) {
|
---|
105 | theKeys.push(String(name));
|
---|
106 | }
|
---|
107 | }
|
---|
108 | }
|
---|
109 |
|
---|
110 | if (hasDontEnumBug) {
|
---|
111 | var skipConstructor = equalsConstructorPrototypeIfNotBuggy(object);
|
---|
112 |
|
---|
113 | for (var k = 0; k < dontEnums.length; ++k) {
|
---|
114 | if (!(skipConstructor && dontEnums[k] === 'constructor') && has.call(object, dontEnums[k])) {
|
---|
115 | theKeys.push(dontEnums[k]);
|
---|
116 | }
|
---|
117 | }
|
---|
118 | }
|
---|
119 | return theKeys;
|
---|
120 | };
|
---|
121 | }
|
---|
122 | module.exports = keysShim;
|
---|