Skip to content

Commit

Permalink
[Fix] work for document.all in Firefox 3 and IE 6-8
Browse files Browse the repository at this point in the history
  • Loading branch information
ljharb committed Sep 13, 2022
1 parent 4b732ff commit 015132a
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 15 deletions.
32 changes: 23 additions & 9 deletions index.js
Expand Up @@ -43,19 +43,33 @@ var tryFunctionObject = function tryFunctionToStr(value) {
}
};
var toStr = Object.prototype.toString;
var objectClass = '[object Object]';
var fnClass = '[object Function]';
var genClass = '[object GeneratorFunction]';
var ddaClass = '[object HTMLAllCollection]';
var hasToStringTag = typeof Symbol === 'function' && !!Symbol.toStringTag; // better: use `has-tostringtag`
var isDDA = typeof document === 'object' ? function isDocumentDotAll(value) {
/* globals document: false */
// in IE 8, typeof document.all is "object"
if (typeof value === 'undefined' || typeof value === 'object') {
try {
return value('') == null; // eslint-disable-line eqeqeq
} catch (e) { /**/ }

var isIE68 = !(0 in [,]); // eslint-disable-line no-sparse-arrays, comma-spacing

var isDDA = function isDocumentDotAll() { return false; };
if (typeof document === 'object') {
// Firefox 3 canonicalized DDA to undefined when it's not accessed directly
var all = document.all;
if (toStr.call(all) === toStr.call(document.all)) {
isDDA = function isDocumentDotAll(value) {
/* globals document: false */
// in IE 6-8, typeof document.all is "object" and it's truthy
if ((isIE68 || !value) && (typeof value === 'undefined' || typeof value === 'object')) {
try {
var str = toStr.call(value);
// IE 6-8 uses `objectClass`
return (str === ddaClass || str === objectClass) && value('') == null; // eslint-disable-line eqeqeq
} catch (e) { /**/ }
}
return false;
};
}
return false;
} : function () { return false; };
}

module.exports = reflectApply
? function isCallable(value) {
Expand Down
24 changes: 18 additions & 6 deletions test/index.js
Expand Up @@ -20,6 +20,7 @@ try {
} catch (e) { /**/ }

var isIE68 = !(0 in [undefined]);
var isFirefox = typeof window !== 'undefined' && ('netscape' in window) && (/ rv:/).test(navigator.userAgent);

var noop = function () {};
var classFake = function classFake() { }; // eslint-disable-line func-name-matching
Expand Down Expand Up @@ -78,11 +79,19 @@ test('not callables', function (t) {
new RegExp('a', 'g'),
new Date()
]), function (nonFunction) {
t['throws'](
function () { Function.prototype.toString.call(nonFunction); },
TypeError,
inspect(nonFunction) + ' can not be used with Function toString'
);
if (isFirefox && nonFunction == null) { // eslint-disable-line eqeqeq
// Firefox 3 throws some kind of *object* here instead of a proper error
t['throws'](
function () { Function.prototype.toString.call(nonFunction); },
inspect(nonFunction) + ' can not be used with Function toString'
);
} else {
t['throws'](
function () { Function.prototype.toString.call(nonFunction); },
TypeError,
inspect(nonFunction) + ' can not be used with Function toString'
);
}
t.equal(isCallable(nonFunction), false, inspect(nonFunction) + ' is not callable');
});

Expand Down Expand Up @@ -172,7 +181,10 @@ test('DOM', function (t) {

t.test('document.all', { skip: typeof document !== 'object' }, function (st) {
st.notOk(isCallable(document), 'document is not callable');
st.ok(isCallable(document.all), 'document.all is callable');

var all = document.all;
var isFF3 = Object.prototype.toString(all) === Object.prototype.toString.call(document.all);
st.equal(isCallable(document.all), isFF3, 'document.all is ' + (isFF3 ? 'not ' : '') + 'callable');

st.end();
});
Expand Down

0 comments on commit 015132a

Please sign in to comment.