// Source: https://github.com/inspect-js/is-callable // The MIT License (MIT) // // Copyright (c) 2015 Jordan Harband // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. var fnToStr = Function.prototype.toString; var reflectApply = typeof Reflect === 'object' && Reflect !== null && Reflect.apply; var badArrayLike; var isCallableMarker; if (typeof reflectApply === 'function' && typeof Object.defineProperty === 'function') { try { badArrayLike = Object.defineProperty({}, 'length', { get: function () { throw isCallableMarker; } }); isCallableMarker = {}; // eslint-disable-next-line no-throw-literal reflectApply(function () { throw 42; }, null, badArrayLike); } catch (_) { if (_ !== isCallableMarker) { reflectApply = null; } } } else { reflectApply = null; } var constructorRegex = /^\s*class\b/; var isES6ClassFn = function isES6ClassFunction(value) { try { var fnStr = fnToStr.call(value); return constructorRegex.test(fnStr); } catch (e) { return false; // not a function } }; var tryFunctionObject = function tryFunctionToStr(value) { try { if (isES6ClassFn(value)) { return false; } fnToStr.call(value); return true; } catch (e) { return false; } }; var toStr = Object.prototype.toString; var objectClass = '[object Object]'; var fnClass = '[object Function]'; var genClass = '[object GeneratorFunction]'; var ddaClass = '[object HTMLAllCollection]'; // IE 11 var ddaClass2 = '[object HTML document.all class]'; var ddaClass3 = '[object HTMLCollection]'; // IE 9-10 var hasToStringTag = typeof Symbol === 'function' && !!Symbol.toStringTag; // better: use `has-tostringtag` var isIE68 = !(0 in [,]); // eslint-disable-line no-sparse-arrays, comma-spacing var isDDA = function isDocumentDotAll() { return false; }; if (typeof document === 'object') { // Firefox 3 canonicalizes 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); return (str === ddaClass || str === ddaClass2 || str === ddaClass3 // opera 12.16 || str === objectClass // IE 6-8 ) && value('') == null; // eslint-disable-line eqeqeq } catch (e) { /**/ } } return false; }; } } function isCallableRefApply(value) { if (isDDA(value)) { return true; } if (!value) { return false; } if (typeof value !== 'function' && typeof value !== 'object') { return false; } try { reflectApply(value, null, badArrayLike); } catch (e) { if (e !== isCallableMarker) { return false; } } return !isES6ClassFn(value) && tryFunctionObject(value); } function isCallableNoRefApply(value) { if (isDDA(value)) { return true; } if (!value) { return false; } if (typeof value !== 'function' && typeof value !== 'object') { return false; } if (hasToStringTag) { return tryFunctionObject(value); } if (isES6ClassFn(value)) { return false; } var strClass = toStr.call(value); if (strClass !== fnClass && strClass !== genClass && !(/^\[object HTML/).test(strClass)) { return false; } return tryFunctionObject(value); } ; export default reflectApply ? isCallableRefApply : isCallableNoRefApply;