stx-router 0.2.562 → 0.2.564

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/client.js +27 -27
  2. package/package.json +1 -1
package/dist/client.js CHANGED
@@ -1026,12 +1026,23 @@ function routerSource() {
1026
1026
  // links it again (recoverUnbound) asks for it again rather than finding it
1027
1027
  // "loaded" and running without it until the next reload.
1028
1028
  var pendingExternalScripts={};
1029
- function loadExternalScript(src,base){
1029
+ function externalScriptAttributes(source){
1030
+ var el=source;
1031
+ if(typeof source==='string')el=new DOMParser().parseFromString('<scr'+'ipt '+source+'></scr'+'ipt>','text/html').querySelector('script');
1032
+ var attrs={};
1033
+ if(el)['src','type','integrity','crossorigin','referrerpolicy','nonce','nomodule','defer','fetchpriority','blocking'].forEach(function(name){
1034
+ if(el.hasAttribute(name))attrs[name]=name==='nonce'?(el.nonce||el.getAttribute(name)||''):(el.getAttribute(name)||'');
1035
+ });
1036
+ return attrs;
1037
+ }
1038
+ function loadExternalScript(src,base,attrs){
1030
1039
  var key=externalScriptKey(src,base);
1031
1040
  if(!key||loadedExternalScripts[key])return null;
1041
+ if(attrs&&Object.prototype.hasOwnProperty.call(attrs,'nomodule')&&'noModule' in ce('script'))return null;
1032
1042
  if(pendingExternalScripts[key])return pendingExternalScripts[key];
1033
1043
  return pendingExternalScripts[key]=new Promise(function(resolve){
1034
1044
  var el=ce('script');
1045
+ Object.keys(attrs||{}).forEach(function(name){if(name!=='src')el.setAttribute(name,attrs[name])});
1035
1046
  el.src=key;
1036
1047
  // Deliberately NOT data-stx-page: both swap paths clear those on every
1037
1048
  // navigation, which would sweep this away and \u2014 since it is never loaded
@@ -1730,15 +1741,14 @@ else {
1730
1741
  // structured data wherever it sits, and the browser will not execute
1731
1742
  // a non-JS type anyway. Mirrors prepareRoutedBodyScripts' notion of
1732
1743
  // executable, which this path never had.
1733
- var typeMatch=attrs.match(/\\btype\\s*=\\s*(?:"([^"]*)"|'([^']*)'|([^\\s>]+))/i);
1734
- var scriptType=((typeMatch&&(typeMatch[1]||typeMatch[2]||typeMatch[3]))||'').trim().toLowerCase();
1744
+ var externalAttrs=externalScriptAttributes(attrs);
1745
+ var scriptType=(externalAttrs.type||'').trim().toLowerCase();
1735
1746
  if(scriptType&&scriptType!=='text/javascript'&&scriptType!=='application/javascript'&&scriptType!=='module')return m;
1736
1747
  // An external script has no body, so every check below reads it as
1737
1748
  // nothing to run and the fragment loses it. Queue it instead; the
1738
1749
  // file is where the page's factory usually lives.
1739
- var srcMatch=attrs.match(/\\bsrc\\s*=\\s*(?:"([^"]*)"|'([^']*)'|([^\\s>]+))/i);
1740
- var fragSrc=srcMatch&&(srcMatch[1]||srcMatch[2]||srcMatch[3]);
1741
- if(fragSrc){if(!isSharedClientScriptAttrs(attrs))fragExternalScripts.push(fragSrc);return ''}
1750
+ var fragSrc=externalAttrs.src;
1751
+ if(fragSrc){if(!isSharedClientScriptAttrs(attrs))fragExternalScripts.push({src:fragSrc,attrs:externalAttrs});return ''}
1742
1752
  if(code&&code.trim()&&!isSignalsRuntimeScript({hasAttribute:function(name){return name==='data-stx-runtime'&&attrs.indexOf('data-stx-runtime')!==-1}},code)){
1743
1753
  var slot='fragment-'+(++fragScriptId);
1744
1754
  var scoped=/(?:^|\\s)data-stx-scoped(?:\\s|=|$)/i.test(attrs);
@@ -1913,9 +1923,9 @@ else {
1913
1923
  // scripts in the same synchronous turn and nothing about its timing
1914
1924
  // moves.
1915
1925
  var fragPending=[];
1916
- fragExternalScripts.forEach(function(src){
1917
- var pending=loadExternalScript(src,url);
1918
- if(pending)fragPending.push({src:src,promise:pending});
1926
+ fragExternalScripts.forEach(function(script){
1927
+ var pending=loadExternalScript(script.src,url,script.attrs);
1928
+ if(pending)fragPending.push({src:script.src,promise:pending});
1919
1929
  });
1920
1930
  afterExternalScripts(fragPending,runFragScripts,url+(hash||''),ctx);
1921
1931
  }
@@ -2116,7 +2126,7 @@ else {
2116
2126
  // Not discarded: queued against docBase, so a relative src resolves
2117
2127
  // against the page being navigated to rather than the current URL.
2118
2128
  // The runtime and router are dropped, not queued: see isSharedClientScript.
2119
- if(s.hasAttribute('src')){if(!isSharedClientScript(s))routedExternalScripts.push(s.getAttribute('src'));s.remove();return}
2129
+ if(s.hasAttribute('src')){if(!isSharedClientScript(s))routedExternalScripts.push({src:s.getAttribute('src'),attrs:externalScriptAttributes(s)});s.remove();return}
2120
2130
  var type=(s.getAttribute('type')||'').trim().toLowerCase();
2121
2131
  var executable=!type||type==='text/javascript'||type==='application/javascript'||type==='module';
2122
2132
  if(!executable||!text.trim())return;
@@ -2180,33 +2190,22 @@ else {
2180
2190
  hydrateServerData(html);
2181
2191
 
2182
2192
  // \u2500\u2500 Load new external <head> scripts \u2500\u2500
2183
- var loadedSrcs={};
2184
- qsa('head script[src]').forEach(function(s){loadedSrcs[s.src]=1});
2185
2193
  var extPromises=[];
2186
2194
  doc.querySelectorAll('head script[src]').forEach(function(s){
2187
2195
  if(isSharedClientScript(s))return;
2188
2196
  // Fetched-document script: resolve against the page being navigated to
2189
2197
  // (docBase), not the origin root \u2014 same rationale as the <link> reconcile (#1777).
2190
2198
  var src=new URL(s.getAttribute('src'),docBase).href;
2191
- if(loadedSrcs[src])return;
2192
- loadedSrcs[src]=1;
2193
- extPromises.push({src:src,promise:new Promise(function(resolve){
2194
- var ns=ce('script');
2195
- ns.src=src;
2196
- ns.onload=function(){resolve(true)};
2197
- // Settled either way, as before (a rejection ran the scripts at
2198
- // once); afterExternalScripts tells a failed module bundle apart.
2199
- ns.onerror=function(){if(ns.parentNode)ns.parentNode.removeChild(ns);resolve(false)};
2200
- dhead().appendChild(ns);
2201
- })});
2199
+ var pending=loadExternalScript(src,docBase,externalScriptAttributes(s));
2200
+ if(pending)extPromises.push({src:src,promise:pending});
2202
2201
  });
2203
2202
 
2204
2203
  // Before the inline scripts, and through the same barrier: an inline
2205
2204
  // script's whole reason for existing is often to call into one of these,
2206
2205
  // so running it first would fail exactly the way this bug did.
2207
- routedExternalScripts.forEach(function(src){
2208
- var pending=loadExternalScript(src,docBase);
2209
- if(pending)extPromises.push({src:src,promise:pending});
2206
+ routedExternalScripts.forEach(function(script){
2207
+ var pending=loadExternalScript(script.src,docBase,script.attrs);
2208
+ if(pending)extPromises.push({src:script.src,promise:pending});
2210
2209
  });
2211
2210
 
2212
2211
  // \u2500\u2500 Script re-execution \u2500\u2500
@@ -3572,7 +3571,8 @@ else {
3572
3571
  var src=srcMatch&&(srcMatch[1]||srcMatch[2]||srcMatch[3]);
3573
3572
  if(!src)return m;
3574
3573
  if(!/(?:^|\\s)data-stx-modules(?:[\\s=]|$)/i.test(attrs)&&!isModuleBundle(src))return m;
3575
- var pending=loadExternalScript(src,base);
3574
+ var assetAttrs=externalScriptAttributes(attrs);
3575
+ var pending=loadExternalScript(assetAttrs.src||src,base,assetAttrs);
3576
3576
  if(pending)waits.push(pending);
3577
3577
  return m;
3578
3578
  });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "stx-router",
3
3
  "type": "module",
4
- "version": "0.2.562",
4
+ "version": "0.2.564",
5
5
  "description": "File-based router for STX — .stx template discovery, nested layouts, typed route params, middleware, and client-side SPA navigation.",
6
6
  "author": "Chris Breuer <chris@stacksjs.org>",
7
7
  "license": "MIT",