Skip to content

Commit cf65048

Browse files
committed
fix: correct all spec inconsistencies
1 parent 5ec4759 commit cf65048

File tree

3 files changed

+175
-15
lines changed

3 files changed

+175
-15
lines changed

index.js

Lines changed: 166 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,26 @@
11
'use strict';
2-
/* globals Promise: false */
32
/* !
43
* type-detect
54
* Copyright(c) 2013 jake luer <jake@alogicalparadox.com>
65
* MIT Licensed
76
*/
8-
var isPrototypeOfExists = typeof Object.getPrototypeOf === 'function';
9-
var promiseExists = typeof Promise === 'function';
7+
var getPrototypeOfExists = typeof Object.getPrototypeOf === 'function';
8+
var globalObject = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : self; // eslint-disable-line
9+
var isDom = 'location' in globalObject && 'document' in globalObject;
10+
var htmlElementExists = typeof HTMLElement !== 'undefined';
11+
var symbolExists = typeof Symbol !== 'undefined';
12+
var mapExists = typeof Map !== 'undefined';
13+
var setExists = typeof Set !== 'undefined';
14+
var dataViewExists = typeof DataView !== 'undefined';
15+
var symbolIteratorExists = symbolExists && Symbol.iterator;
16+
var setEntriesExists = setExists && typeof Set.prototype.entries === 'function';
17+
var mapEntriesExists = mapExists && typeof Map.prototype.entries === 'function';
18+
var setIteratorPrototype = getPrototypeOfExists && setEntriesExists && Object.getPrototypeOf(new Set().entries());
19+
var mapIteratorPrototype = getPrototypeOfExists && mapEntriesExists && Object.getPrototypeOf(new Map().entries());
20+
var arrayIteratorExists = symbolIteratorExists && typeof Array.prototype[Symbol.iterator] === 'function';
21+
var arrayIteratorPrototype = arrayIteratorExists && Object.getPrototypeOf([][Symbol.iterator]());
22+
var stringIteratorExists = symbolIteratorExists && typeof Array.prototype[Symbol.iterator] === 'function';
23+
var stringIteratorPrototype = stringIteratorExists && Object.getPrototypeOf(''[Symbol.iterator]());
1024
var toStringLeftSliceLength = 8;
1125
var toStringRightSliceLength = -1;
1226
/**
@@ -40,16 +54,155 @@ module.exports = function typeDetect(obj) {
4054
return 'undefined';
4155
}
4256

43-
/* ! Spec Conformance
44-
* ES6$25.4.5.4 - Promise.prototype[@@toStringTag] should be "Promise":
45-
* Test: `Object.prototype.toString.call(Promise.resolve())``
46-
* - Chrome <=47 === "[object Object]"
47-
* - Edge <=20 === "[object Object]"
48-
* - Firefox 29-Latest === "[object Promise]"
49-
* - Safari 7.1-Latest === "[object Promise]"
50-
*/
51-
if (promiseExists && isPrototypeOfExists && Object.getPrototypeOf(obj) === Promise.prototype) {
52-
return 'promise';
57+
if (isDom) {
58+
/* ! Spec Conformance
59+
* (https://html.spec.whatwg.org/multipage/browsers.html#location)
60+
* WhatWG HTML$7.7.3 - The `Location` interface
61+
* Test: `Object.prototype.toString.call(window.location)``
62+
* - IE <=11 === "[object Object]"
63+
* - IE Edge <=13 === "[object Object]"
64+
*/
65+
if (obj === globalObject.location) {
66+
return 'location';
67+
}
68+
69+
/* ! Spec Conformance
70+
* (https://html.spec.whatwg.org/#document)
71+
* WhatWG HTML$3.1.1 - The `Document` object
72+
* Note: Most browsers currently adher to the W3C DOM Level 2 spec
73+
* (https://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-26809268)
74+
* which suggests that browsers should use HTMLTableCellElement for
75+
* both TD and TH elements. WhatWG separates these.
76+
* WhatWG HTML states:
77+
* > For historical reasons, Window objects must also have a
78+
* > writable, configurable, non-enumerable property named
79+
* > HTMLDocument whose value is the Document interface object.
80+
* Test: `Object.prototype.toString.call(document)``
81+
* - Chrome === "[object HTMLDocument]"
82+
* - Firefox === "[object HTMLDocument]"
83+
* - Safari === "[object HTMLDocument]"
84+
* - IE <=10 === "[object Document]"
85+
* - IE 11 === "[object HTMLDocument]"
86+
* - IE Edge <=13 === "[object HTMLDocument]"
87+
*/
88+
if (obj === globalObject.document) {
89+
return 'document';
90+
}
91+
92+
/* ! Spec Conformance
93+
* (https://html.spec.whatwg.org/multipage/webappapis.html#mimetypearray)
94+
* WhatWG HTML$8.6.1.5 - Plugins - Interface MimeTypeArray
95+
* Test: `Object.prototype.toString.call(navigator.mimeTypes)``
96+
* - IE <=10 === "[object MSMimeTypesCollection]"
97+
*/
98+
if (obj === (globalObject.navigator || {}).mimeTypes) {
99+
return 'mimetypearray';
100+
}
101+
102+
/* ! Spec Conformance
103+
* (https://html.spec.whatwg.org/multipage/webappapis.html#pluginarray)
104+
* WhatWG HTML$8.6.1.5 - Plugins - Interface PluginArray
105+
* Test: `Object.prototype.toString.call(navigator.plugins)``
106+
* - IE <=10 === "[object MSPluginsCollection]"
107+
*/
108+
if (obj === (globalObject.navigator || {}).plugins) {
109+
return 'pluginarray';
110+
}
111+
112+
/* ! Spec Conformance
113+
* (https://html.spec.whatwg.org/multipage/webappapis.html#pluginarray)
114+
* WhatWG HTML$4.4.4 - The `blockquote` element - Interface `HTMLQuoteElement`
115+
* Test: `Object.prototype.toString.call(document.createElement('blockquote'))``
116+
* - IE <=10 === "[object HTMLBlockElement]"
117+
*/
118+
if (htmlElementExists && obj instanceof HTMLElement && obj.tagName === 'BLOCKQUOTE') {
119+
return 'htmlquoteelement';
120+
}
121+
122+
/* ! Spec Conformance
123+
* (https://html.spec.whatwg.org/#htmltabledatacellelement)
124+
* WhatWG HTML$4.9.9 - The `td` element - Interface `HTMLTableDataCellElement`
125+
* Note: Most browsers currently adher to the W3C DOM Level 2 spec
126+
* (https://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-82915075)
127+
* which suggests that browsers should use HTMLTableCellElement for
128+
* both TD and TH elements. WhatWG separates these.
129+
* Test: Object.prototype.toString.call(document.createElement('td'))
130+
* - Chrome === "[object HTMLTableCellElement]"
131+
* - Firefox === "[object HTMLTableCellElement]"
132+
* - Safari === "[object HTMLTableCellElement]"
133+
*/
134+
if (htmlElementExists && obj instanceof HTMLElement && obj.tagName === 'TD') {
135+
return 'htmltabledatacellelement';
136+
}
137+
138+
/* ! Spec Conformance
139+
* (https://html.spec.whatwg.org/#htmltableheadercellelement)
140+
* WhatWG HTML$4.9.9 - The `td` element - Interface `HTMLTableHeaderCellElement`
141+
* Note: Most browsers currently adher to the W3C DOM Level 2 spec
142+
* (https://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-82915075)
143+
* which suggests that browsers should use HTMLTableCellElement for
144+
* both TD and TH elements. WhatWG separates these.
145+
* Test: Object.prototype.toString.call(document.createElement('th'))
146+
* - Chrome === "[object HTMLTableCellElement]"
147+
* - Firefox === "[object HTMLTableCellElement]"
148+
* - Safari === "[object HTMLTableCellElement]"
149+
*/
150+
if (htmlElementExists && obj instanceof HTMLElement && obj.tagName === 'TH') {
151+
return 'htmltableheadercellelement';
152+
}
153+
}
154+
155+
if (getPrototypeOfExists && (symbolExists === false || typeof obj[Symbol.toStringTag] === 'undefined')) {
156+
var objPrototype = Object.getPrototypeOf(obj);
157+
/* ! Spec Conformance
158+
* (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-dataview.prototype-@@tostringtag)
159+
* ES6$24.2.4.21 - DataView.prototype[@@toStringTag] should be "DataView":
160+
* Test: `Object.prototype.toString.call(new DataView(new ArrayBuffer(1)))``
161+
* - Edge <=13 === "[object Object]"
162+
*/
163+
if (dataViewExists && objPrototype === DataView.prototype) {
164+
return 'dataview';
165+
}
166+
167+
/* ! Spec Conformance
168+
* (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%mapiteratorprototype%-@@tostringtag)
169+
* ES6$23.1.5.2.2 - %MapIteratorPrototype%[@@toStringTag] should be "Map Iterator":
170+
* Test: `Object.prototype.toString.call(new Map().entries())``
171+
* - Edge <=13 === "[object Object]"
172+
*/
173+
if (mapExists && objPrototype === mapIteratorPrototype) {
174+
return 'map iterator';
175+
}
176+
177+
/* ! Spec Conformance
178+
* (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%setiteratorprototype%-@@tostringtag)
179+
* ES6$23.2.5.2.2 - %SetIteratorPrototype%[@@toStringTag] should be "Set Iterator":
180+
* Test: `Object.prototype.toString.call(new Set().entries())``
181+
* - Edge <=13 === "[object Object]"
182+
*/
183+
if (setExists && objPrototype === setIteratorPrototype) {
184+
return 'set iterator';
185+
}
186+
187+
/* ! Spec Conformance
188+
* (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%arrayiteratorprototype%-@@tostringtag)
189+
* ES6$22.1.5.2.2 - %ArrayIteratorPrototype%[@@toStringTag] should be "Array Iterator":
190+
* Test: `Object.prototype.toString.call([][Symbol.iterator]())``
191+
* - Edge <=13 === "[object Object]"
192+
*/
193+
if (arrayIteratorExists && objPrototype === arrayIteratorPrototype) {
194+
return 'array iterator';
195+
}
196+
197+
/* ! Spec Conformance
198+
* (http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%stringiteratorprototype%-@@tostringtag)
199+
* ES6$21.1.5.2.2 - %StringIteratorPrototype%[@@toStringTag] should be "String Iterator":
200+
* Test: `Object.prototype.toString.call(''[Symbol.iterator]())``
201+
* - Edge <=13 === "[object Object]"
202+
*/
203+
if (stringIteratorExists && objPrototype === stringIteratorPrototype) {
204+
return 'string iterator';
205+
}
53206
}
54207

55208
return Object

package.json

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,15 @@
3838
"extends": [
3939
"strict/es5"
4040
],
41+
"env": {
42+
"es6": true
43+
},
44+
"globals": {
45+
"HTMLElement": false
46+
},
4147
"rules": {
42-
"complexity": 0
48+
"complexity": 0,
49+
"max-statements": 0
4350
}
4451
},
4552
"dependencies": {},

test/dom.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ describeIf(typeof window !== 'undefined' && typeof window.document !== 'undefine
1414
});
1515

1616
it('document', function () {
17-
assert(type(document) === 'htmldocument');
17+
assert(type(document) === 'document');
1818
});
1919

2020
it('domparser', function () {

0 commit comments

Comments
 (0)