Skip to content

Commit

Permalink
Load AMD modules with the same crossorigin attribute as document.curr…
Browse files Browse the repository at this point in the history
…entScript (#801)

* Load AMD modules with the same crossorigin attribute as document.currentScript

* Update tests and changelog

* Initialize readonly ModuleG.crossorigin

* Regenerate test baselines

* Update polyserve test goldens

* Default to crossorigin=anonymous
  • Loading branch information
keanulee authored Dec 6, 2018
1 parent ffed1e3 commit 5aebb66
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 12 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<html><head>
<script>(function(a){var b=a.babelHelpers={};b.interopRequireDefault=function(a){return a&&a.__esModule?a:{default:a}},b.interopRequireWildcard=function(a){if(a&&a.__esModule)return a;var b={};if(null!=a)for(var c in a)if(Object.prototype.hasOwnProperty.call(a,c)){var d=Object.defineProperty&&Object.getOwnPropertyDescriptor?Object.getOwnPropertyDescriptor(a,c):{};d.get||d.set?Object.defineProperty(b,c,d):b[c]=a[c]}return b.default=a,b}})("undefined"===typeof global?self:global);</script>
<script>"use strict";(function(){function a(a,b,c){var d=a;if(d.state=b,d.stateData=c,0<d.onNextStateChange.length){var e=d.onNextStateChange.slice();d.onNextStateChange.length=0;for(var f,g=0,h=e;g<h.length;g++)f=h[g],f()}return d}function b(b){function d(){try{document.head.removeChild(f)}catch(a){}}var e=a(b,"Loading",void 0),f=document.createElement("script");return f.src=b.url,f.onload=function(){var a,b,f;void 0===r?(b=[],f=void 0):(a=r(),b=a[0],f=a[1]),c(e,b,f),d()},f.onerror=function(){g(b,new TypeError("Failed to fetch "+b.url)),d()},document.head.appendChild(f),e}function c(b,c,e){var f=d(b,c),g=f[0],h=f[1];return a(b,"WaitingForTurn",{args:g,deps:h,moduleBody:e})}function d(a,c){for(var e,f=[],g=[],i=0,j=c;i<j.length;i++){if(e=j[i],"exports"===e){f.push(a.exports);continue}if("require"===e){f.push(function(b,c,e){var f=d(a,b),g=f[0],i=f[1];h(i,function(){c&&c.apply(null,g)},e)});continue}if("meta"===e){f.push({url:!0===a.isTopLevel?a.url.substring(0,a.url.lastIndexOf("#")):a.url});continue}var l=k(n(a.urlBase,e));f.push(l.exports),g.push(l),"Initialized"===l.state&&b(l)}return[f,g]}function e(b){var c=a(b,"WaitingOnDeps",b.stateData);return h(b.stateData.deps,function(){return f(c)},function(a){return g(c,a)}),c}function f(b){var c=b.stateData;if(null!=c.moduleBody)try{c.moduleBody.apply(null,c.args)}catch(a){return g(b,a)}return a(b,"Executed",void 0)}function g(b,c){return!0===b.isTopLevel&&setTimeout(function(){throw c}),a(b,"Failed",c)}function h(a,b,c){var d=a.shift();return void 0===d?void(b&&b()):"WaitingOnDeps"===d.state?(!1,void h(a,b,c)):void i(d,function(){h(a,b,c)},c)}function i(a,b,c){switch(a.state){case"WaitingForTurn":return e(a),void i(a,b,c);case"Failed":return void(c&&c(a.stateData));case"Executed":return void b();case"Loading":case"WaitingOnDeps":return void a.onNextStateChange.push(function(){return i(a,b,c)});case"Initialized":throw new Error("All dependencies should be loading already before pressureDependencyToExecute is called.");default:throw new Error("Impossible module state: "+a.state);}}function j(a,b){switch(a.state){case"Executed":case"Failed":return void b();default:a.onNextStateChange.push(function(){return j(a,b)});}}function k(a){var b=q[a];return void 0===b&&(b=q[a]={url:a,urlBase:m(a),exports:Object.create(null),state:"Initialized",stateData:void 0,isTopLevel:!1,onNextStateChange:[]}),b}function l(a){return v.href=a,v.href}function m(a){return a=a.split("?")[0],a=a.split("#")[0],a.substring(0,a.lastIndexOf("/")+1)}function n(a,b){return-1===b.indexOf("://")?l("/"===b[0]?b:a+b):b}function o(){return document.baseURI||(document.querySelector("base")||window.location).href}function p(){var b=document.currentScript;if(!b)return u;if(window.HTMLImports){var c=window.HTMLImports.importForElement(b);return c?c.href:u}var d=b.ownerDocument.createElement("a");return d.href="",d.href}if(!window.define){var q=Object.create(null),r=void 0,s=0,t=void 0,u=o();window.define=function(a,b){var d=!1;r=function(){return d=!0,r=void 0,[a,b]};var f=p();setTimeout(function(){if(!1==d){r=void 0;var g=f+"#"+s++,h=k(g);h.isTopLevel=!0;var i=c(h,a,b);void 0===t?e(i):j(k(t),function(){e(i)}),t=g}},0)},window.define._reset=function(){for(var a in q)delete q[a];r=void 0,s=0,t=void 0,u=o()};var v=document.createElement("a")}})();</script>
<script>"use strict";(function(){function a(a,b,c){var d=a;if(d.state=b,d.stateData=c,0<d.onNextStateChange.length){var e=d.onNextStateChange.slice();d.onNextStateChange.length=0;for(var f,g=0,h=e;g<h.length;g++)f=h[g],f()}return d}function b(b){function d(){try{document.head.removeChild(f)}catch(a){}}var e=a(b,"Loading",void 0),f=document.createElement("script");return f.src=b.url,null!==b.crossorigin&&f.setAttribute("crossorigin",b.crossorigin),f.onload=function(){var a,b,f;void 0===r?(b=[],f=void 0):(a=r(),b=a[0],f=a[1]),c(e,b,f),d()},f.onerror=function(){g(b,new TypeError("Failed to fetch "+b.url)),d()},document.head.appendChild(f),e}function c(b,c,e){var f=d(b,c),g=f[0],h=f[1];return a(b,"WaitingForTurn",{args:g,deps:h,moduleBody:e})}function d(a,c){for(var e,f=[],g=[],i=0,j=c;i<j.length;i++){if(e=j[i],"exports"===e){f.push(a.exports);continue}if("require"===e){f.push(function(b,c,e){var f=d(a,b),g=f[0],i=f[1];h(i,function(){c&&c.apply(null,g)},e)});continue}if("meta"===e){f.push({url:!0===a.isTopLevel?a.url.substring(0,a.url.lastIndexOf("#")):a.url});continue}var l=k(n(a.urlBase,e),a.crossorigin);f.push(l.exports),g.push(l),"Initialized"===l.state&&b(l)}return[f,g]}function e(b){var c=a(b,"WaitingOnDeps",b.stateData);return h(b.stateData.deps,function(){return f(c)},function(a){return g(c,a)}),c}function f(b){var c=b.stateData;if(null!=c.moduleBody)try{c.moduleBody.apply(null,c.args)}catch(a){return g(b,a)}return a(b,"Executed",void 0)}function g(b,c){return!0===b.isTopLevel&&setTimeout(function(){throw c}),a(b,"Failed",c)}function h(a,b,c){var d=a.shift();return void 0===d?void(b&&b()):"WaitingOnDeps"===d.state?(!1,void h(a,b,c)):void i(d,function(){h(a,b,c)},c)}function i(a,b,c){switch(a.state){case"WaitingForTurn":return e(a),void i(a,b,c);case"Failed":return void(c&&c(a.stateData));case"Executed":return void b();case"Loading":case"WaitingOnDeps":return void a.onNextStateChange.push(function(){return i(a,b,c)});case"Initialized":throw new Error("All dependencies should be loading already before pressureDependencyToExecute is called.");default:throw new Error("Impossible module state: "+a.state);}}function j(a,b){switch(a.state){case"Executed":case"Failed":return void b();default:a.onNextStateChange.push(function(){return j(a,b)});}}function k(a,b){void 0===b&&(b="anonymous");var c=q[a];return void 0===c&&(c=q[a]={url:a,urlBase:m(a),exports:Object.create(null),state:"Initialized",stateData:void 0,isTopLevel:!1,crossorigin:b,onNextStateChange:[]}),c}function l(a){return v.href=a,v.href}function m(a){return a=a.split("?")[0],a=a.split("#")[0],a.substring(0,a.lastIndexOf("/")+1)}function n(a,b){return-1===b.indexOf("://")?l("/"===b[0]?b:a+b):b}function o(){return document.baseURI||(document.querySelector("base")||window.location).href}function p(){var b=document.currentScript;if(!b)return u;if(window.HTMLImports){var c=window.HTMLImports.importForElement(b);return c?c.href:u}var d=b.ownerDocument.createElement("a");return d.href="",d.href}if(!window.define){var q=Object.create(null),r=void 0,s=0,t=void 0,u=o();window.define=function(a,b){var d=!1;r=function(){return d=!0,r=void 0,[a,b]};var f=p(),g=document.currentScript&&document.currentScript.getAttribute("crossorigin")||"anonymous";setTimeout(function(){if(!1==d){r=void 0;var h=f+"#"+s++,i=k(h,g);i.isTopLevel=!0;var l=c(i,a,b);void 0===t?e(l):j(k(t),function(){e(l)}),t=h}},0)},window.define._reset=function(){for(var a in q)delete q[a];r=void 0,s=0,t=void 0,u=o()};var v=document.createElement("a")}})();</script>
<script>define(['shared_bundle_1.js']);</script>
</head>
<body>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<html><head>
<script>(function(a){var b=a.babelHelpers={};b.interopRequireDefault=function(a){return a&&a.__esModule?a:{default:a}},b.interopRequireWildcard=function(a){if(a&&a.__esModule)return a;var b={};if(null!=a)for(var c in a)if(Object.prototype.hasOwnProperty.call(a,c)){var d=Object.defineProperty&&Object.getOwnPropertyDescriptor?Object.getOwnPropertyDescriptor(a,c):{};d.get||d.set?Object.defineProperty(b,c,d):b[c]=a[c]}return b.default=a,b}})("undefined"===typeof global?self:global);</script>
<script>"use strict";(function(){function a(a,b,c){var d=a;if(d.state=b,d.stateData=c,0<d.onNextStateChange.length){var e=d.onNextStateChange.slice();d.onNextStateChange.length=0;for(var f,g=0,h=e;g<h.length;g++)f=h[g],f()}return d}function b(b){function d(){try{document.head.removeChild(f)}catch(a){}}var e=a(b,"Loading",void 0),f=document.createElement("script");return f.src=b.url,f.onload=function(){var a,b,f;void 0===r?(b=[],f=void 0):(a=r(),b=a[0],f=a[1]),c(e,b,f),d()},f.onerror=function(){g(b,new TypeError("Failed to fetch "+b.url)),d()},document.head.appendChild(f),e}function c(b,c,e){var f=d(b,c),g=f[0],h=f[1];return a(b,"WaitingForTurn",{args:g,deps:h,moduleBody:e})}function d(a,c){for(var e,f=[],g=[],i=0,j=c;i<j.length;i++){if(e=j[i],"exports"===e){f.push(a.exports);continue}if("require"===e){f.push(function(b,c,e){var f=d(a,b),g=f[0],i=f[1];h(i,function(){c&&c.apply(null,g)},e)});continue}if("meta"===e){f.push({url:!0===a.isTopLevel?a.url.substring(0,a.url.lastIndexOf("#")):a.url});continue}var l=k(n(a.urlBase,e));f.push(l.exports),g.push(l),"Initialized"===l.state&&b(l)}return[f,g]}function e(b){var c=a(b,"WaitingOnDeps",b.stateData);return h(b.stateData.deps,function(){return f(c)},function(a){return g(c,a)}),c}function f(b){var c=b.stateData;if(null!=c.moduleBody)try{c.moduleBody.apply(null,c.args)}catch(a){return g(b,a)}return a(b,"Executed",void 0)}function g(b,c){return!0===b.isTopLevel&&setTimeout(function(){throw c}),a(b,"Failed",c)}function h(a,b,c){var d=a.shift();return void 0===d?void(b&&b()):"WaitingOnDeps"===d.state?(!1,void h(a,b,c)):void i(d,function(){h(a,b,c)},c)}function i(a,b,c){switch(a.state){case"WaitingForTurn":return e(a),void i(a,b,c);case"Failed":return void(c&&c(a.stateData));case"Executed":return void b();case"Loading":case"WaitingOnDeps":return void a.onNextStateChange.push(function(){return i(a,b,c)});case"Initialized":throw new Error("All dependencies should be loading already before pressureDependencyToExecute is called.");default:throw new Error("Impossible module state: "+a.state);}}function j(a,b){switch(a.state){case"Executed":case"Failed":return void b();default:a.onNextStateChange.push(function(){return j(a,b)});}}function k(a){var b=q[a];return void 0===b&&(b=q[a]={url:a,urlBase:m(a),exports:Object.create(null),state:"Initialized",stateData:void 0,isTopLevel:!1,onNextStateChange:[]}),b}function l(a){return v.href=a,v.href}function m(a){return a=a.split("?")[0],a=a.split("#")[0],a.substring(0,a.lastIndexOf("/")+1)}function n(a,b){return-1===b.indexOf("://")?l("/"===b[0]?b:a+b):b}function o(){return document.baseURI||(document.querySelector("base")||window.location).href}function p(){var b=document.currentScript;if(!b)return u;if(window.HTMLImports){var c=window.HTMLImports.importForElement(b);return c?c.href:u}var d=b.ownerDocument.createElement("a");return d.href="",d.href}if(!window.define){var q=Object.create(null),r=void 0,s=0,t=void 0,u=o();window.define=function(a,b){var d=!1;r=function(){return d=!0,r=void 0,[a,b]};var f=p();setTimeout(function(){if(!1==d){r=void 0;var g=f+"#"+s++,h=k(g);h.isTopLevel=!0;var i=c(h,a,b);void 0===t?e(i):j(k(t),function(){e(i)}),t=g}},0)},window.define._reset=function(){for(var a in q)delete q[a];r=void 0,s=0,t=void 0,u=o()};var v=document.createElement("a")}})();</script>
<script>"use strict";(function(){function a(a,b,c){var d=a;if(d.state=b,d.stateData=c,0<d.onNextStateChange.length){var e=d.onNextStateChange.slice();d.onNextStateChange.length=0;for(var f,g=0,h=e;g<h.length;g++)f=h[g],f()}return d}function b(b){function d(){try{document.head.removeChild(f)}catch(a){}}var e=a(b,"Loading",void 0),f=document.createElement("script");return f.src=b.url,null!==b.crossorigin&&f.setAttribute("crossorigin",b.crossorigin),f.onload=function(){var a,b,f;void 0===r?(b=[],f=void 0):(a=r(),b=a[0],f=a[1]),c(e,b,f),d()},f.onerror=function(){g(b,new TypeError("Failed to fetch "+b.url)),d()},document.head.appendChild(f),e}function c(b,c,e){var f=d(b,c),g=f[0],h=f[1];return a(b,"WaitingForTurn",{args:g,deps:h,moduleBody:e})}function d(a,c){for(var e,f=[],g=[],i=0,j=c;i<j.length;i++){if(e=j[i],"exports"===e){f.push(a.exports);continue}if("require"===e){f.push(function(b,c,e){var f=d(a,b),g=f[0],i=f[1];h(i,function(){c&&c.apply(null,g)},e)});continue}if("meta"===e){f.push({url:!0===a.isTopLevel?a.url.substring(0,a.url.lastIndexOf("#")):a.url});continue}var l=k(n(a.urlBase,e),a.crossorigin);f.push(l.exports),g.push(l),"Initialized"===l.state&&b(l)}return[f,g]}function e(b){var c=a(b,"WaitingOnDeps",b.stateData);return h(b.stateData.deps,function(){return f(c)},function(a){return g(c,a)}),c}function f(b){var c=b.stateData;if(null!=c.moduleBody)try{c.moduleBody.apply(null,c.args)}catch(a){return g(b,a)}return a(b,"Executed",void 0)}function g(b,c){return!0===b.isTopLevel&&setTimeout(function(){throw c}),a(b,"Failed",c)}function h(a,b,c){var d=a.shift();return void 0===d?void(b&&b()):"WaitingOnDeps"===d.state?(!1,void h(a,b,c)):void i(d,function(){h(a,b,c)},c)}function i(a,b,c){switch(a.state){case"WaitingForTurn":return e(a),void i(a,b,c);case"Failed":return void(c&&c(a.stateData));case"Executed":return void b();case"Loading":case"WaitingOnDeps":return void a.onNextStateChange.push(function(){return i(a,b,c)});case"Initialized":throw new Error("All dependencies should be loading already before pressureDependencyToExecute is called.");default:throw new Error("Impossible module state: "+a.state);}}function j(a,b){switch(a.state){case"Executed":case"Failed":return void b();default:a.onNextStateChange.push(function(){return j(a,b)});}}function k(a,b){void 0===b&&(b="anonymous");var c=q[a];return void 0===c&&(c=q[a]={url:a,urlBase:m(a),exports:Object.create(null),state:"Initialized",stateData:void 0,isTopLevel:!1,crossorigin:b,onNextStateChange:[]}),c}function l(a){return v.href=a,v.href}function m(a){return a=a.split("?")[0],a=a.split("#")[0],a.substring(0,a.lastIndexOf("/")+1)}function n(a,b){return-1===b.indexOf("://")?l("/"===b[0]?b:a+b):b}function o(){return document.baseURI||(document.querySelector("base")||window.location).href}function p(){var b=document.currentScript;if(!b)return u;if(window.HTMLImports){var c=window.HTMLImports.importForElement(b);return c?c.href:u}var d=b.ownerDocument.createElement("a");return d.href="",d.href}if(!window.define){var q=Object.create(null),r=void 0,s=0,t=void 0,u=o();window.define=function(a,b){var d=!1;r=function(){return d=!0,r=void 0,[a,b]};var f=p(),g=document.currentScript&&document.currentScript.getAttribute("crossorigin")||"anonymous";setTimeout(function(){if(!1==d){r=void 0;var h=f+"#"+s++,i=k(h,g);i.isTopLevel=!0;var l=c(i,a,b);void 0===t?e(l):j(k(t),function(){e(l)}),t=h}},0)},window.define._reset=function(){for(var a in q)delete q[a];r=void 0,s=0,t=void 0,u=o()};var v=document.createElement("a")}})();</script>
<script>define(['./mod1.js']);</script>
</head>
<body>
Expand Down
4 changes: 3 additions & 1 deletion packages/esm-amd-loader/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).

<!-- # Unreleased -->
## Unreleased
* Load AMD modules with the same crossorigin attribute as
document.currentScript.
<!-- Add new, unreleased changes here. -->

## [1.0.3] - 2018-09-18
Expand Down
31 changes: 27 additions & 4 deletions packages/esm-amd-loader/src/esm-amd-loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,15 @@ interface ModuleG<State extends keyof StateDataMap> {
readonly url: NormalizedUrl;
readonly urlBase: NormalizedUrl;
readonly exports: {[id: string]: {}};
/** True if this is a top-level module. */
/**
* True if this is a top-level module.
*/
isTopLevel: boolean;
/**
* Value of the `crossorigin` attribute that will be used to load this
* module.
*/
readonly crossorigin: string;
/**
* Callbacks that are called exactly once, for the next time the module
* progresses to a new state.
Expand Down Expand Up @@ -188,6 +195,11 @@ function load(module: ModuleG<StateEnum.Initialized>):
const script = document.createElement('script');
script.src = module.url;

// Crossorigin attribute could be the empty string - preserve this.
if (module.crossorigin !== null) {
script.setAttribute('crossorigin', module.crossorigin);
}

/**
* Remove our script tags from the document after they have loaded/errored, to
* reduce the number of nodes. Since the file load order is arbitrary and not
Expand Down Expand Up @@ -277,7 +289,8 @@ function loadDeps(
}

// We have a dependency on a real module.
const dependency = getModule(resolveUrl(module.urlBase, depSpec));
const dependency =
getModule(resolveUrl(module.urlBase, depSpec), module.crossorigin);
args.push(dependency.exports);
depModules.push(dependency);

Expand Down Expand Up @@ -434,13 +447,22 @@ window.define = function(deps: string[], moduleBody?: OnExecutedCallback) {
// by waiting a tick, and if we haven't already been defined by the "onload"
// handler from case #1, then this must be case #2.
const documentUrl = getDocumentUrl();

// Save the value of the crossorigin attribute before setTimeout while we
// can still get document.currentScript. If not set, default to 'anonymous'
// to match native <script type="module"> behavior. Note: IE11 doesn't
// support the crossorigin attribute nor currentScript, so it will use the
// default.
const crossorigin = document.currentScript &&
document.currentScript.getAttribute('crossorigin') || 'anonymous';

setTimeout(() => {
if (defined === false) {
pendingDefine = undefined;
const url = documentUrl + '#' + topLevelScriptIdx++ as NormalizedUrl;
// It's actually Initialized, but we're skipping over the Loading
// state, because this is a top level document and it's already loaded.
const mod = getModule(url) as ModuleG<StateEnum.Loading>;
const mod = getModule(url, crossorigin) as ModuleG<StateEnum.Loading>;
mod.isTopLevel = true;
const waitingModule = beginWaitingForTurn(mod, deps, moduleBody);
if (previousTopLevelUrl !== undefined) {
Expand Down Expand Up @@ -489,7 +511,7 @@ window.define._reset = () => {
* Return a module object from the registry for the given URL, creating one if
* it doesn't exist yet.
*/
function getModule(url: NormalizedUrl): Module {
function getModule(url: NormalizedUrl, crossorigin: string = 'anonymous') {
let mod = registry[url];
if (mod === undefined) {
mod = registry[url] = {
Expand All @@ -499,6 +521,7 @@ function getModule(url: NormalizedUrl): Module {
state: StateEnum.Initialized,
stateData: undefined,
isTopLevel: false,
crossorigin,
onNextStateChange: []
};
}
Expand Down
Loading

0 comments on commit 5aebb66

Please sign in to comment.