1 |
3a515b92
|
cagy
|
'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;
|