Skip to content

Commit

Permalink
use a document.currentScript polyfill which works in all Internet Exp…
Browse files Browse the repository at this point in the history
…lorer versions :-D (#480)

* use a document.currentScript polyfill which works in all Internet Explorer versions :-D

* simplify tests

* modify currentScript polyfill to work in IE8
  • Loading branch information
Jake Champion committed Feb 24, 2020
1 parent 7aa29b1 commit 653e432
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 78 deletions.
2 changes: 1 addition & 1 deletion .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,4 @@ tasks/**/node_modules
polyfills/HTMLTemplateElement/polyfill.js
polyfills/ResizeObserver/polyfill.js
polyfills/AbortController/polyfill.js
polyfills/smoothscroll/polyfill.js
polyfills/smoothscroll/polyfill.js
5 changes: 5 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
"Base64": "^1.0.0",
"abort-controller": "^3.0.0",
"audio-context-polyfill": "^1.0.0",
"current-script-polyfill": "^1.0.0",
"diff": "4.0.2",
"event-source-polyfill": "^1.0.12",
"from2-string": "^1.1.0",
Expand Down
8 changes: 2 additions & 6 deletions polyfills/document/currentScript/config.toml
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
repo = "https://github.com/JamesMGreene/document.currentScript"
repo = "https://github.com/amiller-gh/currentScript-polyfill"
license = "MIT"
docs = "https://developer.mozilla.org/en-US/docs/Web/API/Document/currentScript"
spec = "https://html.spec.whatwg.org/multipage/dom.html#dom-document-currentscript"
notes = [
"This polyfill will not work in IE11 because of a critical design choice made Microsoft (\"Don't Call Me IE!\") [\\[1\\]](https://msdn.microsoft.com/en-us/library/ie/bg182625.aspx)[\\[2\\]](https://msdn.microsoft.com/en-us/library/ie/dn384059.aspx)[\\[3\\]](http://www.nczonline.net/blog/2013/07/02/internet-explorer-11-dont-call-me-ie/)[\\[4\\]](http://blog.getify.com/ie11-please-bring-real-script-preloading-back/) in order to avoid consumers receiving an unnecessarily downgraded experience on websites that were making logic branch and feature decisions based on browser detection rather than feature detection."
]

[browsers]
ie = "8 - 10"

ie = "*"
94 changes: 37 additions & 57 deletions polyfills/document/currentScript/polyfill.js
Original file line number Diff line number Diff line change
@@ -1,57 +1,37 @@
if ((typeof WorkerGlobalScope === "undefined") && (typeof importScripts !== "function")) {
(function () {

var

// Check if the browser supports the `readyState` property on `script` elements.
// Guaranteed accurate in IE 6-10.
// Not correctly supported in any other browsers. =(
supportsScriptReadyState = 'readyState' in document.createElement('script'),

// Unfortunately necessary browser detection for Opera.
isOpera = self.opera && self.opera.toString() === '[object Opera]',

// Has support for `Object.defineProperty`.
// Even IE8's incomplete implementation is sufficient here since it works on
// native DOM interfaces like `document`.
canDefineProp = typeof Object.defineProperty === 'function',

// Get the currently "executing" (i.e. EVALUATING) `script` DOM element per the
// spec requirements for `document.currentScript`.
_currentEvaluatingScript = function () {
var

// Live NodeList collection
scripts = document.getElementsByTagName('script');

// Guaranteed accurate for IE 6-10 (but NOT IE11!).
for (var i = scripts.length; scripts[--i];) {
if (scripts[i].readyState === 'interactive') {
return scripts[i];
}
}

return null;
};


if (!supportsScriptReadyState) {
throw new Error('Cannot polyfill `document.currentScript` as your browser does not support the "readyState" DOM property of script elements. Please see https://github.com/Financial-Times/polyfill-service/issues/952 for more information.');
}
if (isOpera) {
throw new Error('Cannot polyfill `document.currentScript` as your Opera browser does not correctly support the "readyState" DOM property of script elements. Please see https://github.com/Financial-Times/polyfill-service/issues/952 for more information.');
}
if (!canDefineProp) {
throw new Error('Cannot polyfill `document.currentScript` as your browser does not support `Object.defineProperty`. Please see https://github.com/Financial-Times/polyfill-service/issues/952 for more information.');
}


Object.defineProperty(document, 'currentScript', {
get: function Document$currentScript() {
return _currentEvaluatingScript();
},
configurable: true
});

}());
}
// document.currentScript polyfill by Adam Miller -- modifed by Jake Champion

// MIT license

(function(document){
var currentScript = "currentScript",
scripts = document.getElementsByTagName('script'); // Live NodeList collection

// If browser needs currentScript polyfill, add get currentScript() to the document object
if (!(currentScript in document)) {
Object.defineProperty(document, currentScript, {
get: function(){

// IE 6-10 supports script readyState
// IE 10+ support stack trace
try { throw new Error(); }
catch (err) {

// Find the second match for the "at" string to get file src url from stack.
// Specifically works with the format of stack traces in IE.
var i = 0;
var res = ((/.*at [^(]*\((.*):.+:.+\)$/ig).exec(err.stack) || [false])[1];

// For all scripts on the page, if src matches or if ready state is interactive, return the script tag
for(i = 0; i < scripts.length; i++){
if(scripts[i].src == res || scripts[i].readyState == "interactive"){
return scripts[i];
}
}

// If no match, return null
return null;
}
}
});
}
})(document);
14 changes: 0 additions & 14 deletions polyfills/document/currentScript/tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,3 @@ it('returns the current script element when invoked during synchronous evaluatio
proclaim.include(cs.src, 'http://bs-local.com:9876/tests.js');
proclaim.equal(cs.innerHTML, '');
});

it('returns null when not invoked during synchronous evaluation', function () {
proclaim.isNull(document.currentScript);
});

// TODO: Investigate why this fails when run under Karma iframe mode
it.skip('returns the current script element when invoked during dynamic evaluation', function () {
var script = document.createElement('script');
script.id = 'rnd' + (Math.random() * 1e9 | 0);
script.innerHTML = 'if (document.currentScript === document.getElementById("' + script.id + '")) document.currentScript.className = "' + script.id + '";';
document.body.appendChild(script);
proclaim.equal(script.id, script.className);
document.body.removeChild(script);
});

0 comments on commit 653e432

Please sign in to comment.