stx-router 0.2.287 → 0.2.288
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.
- package/dist/client.js +30 -5
- package/package.json +1 -1
package/dist/client.js
CHANGED
|
@@ -322,6 +322,23 @@ export function getRouterScript() {
|
|
|
322
322
|
var head=code.trimStart();
|
|
323
323
|
return head.charAt(0)==='('||head.charAt(0)===';';
|
|
324
324
|
}
|
|
325
|
+
// A component scope script names the root it binds in data-stx-owner (#1958).
|
|
326
|
+
// On navigation it runs only for a root that just ARRIVED: one swapped in
|
|
327
|
+
// with the new content, which is not bound yet. A layout component that
|
|
328
|
+
// stayed on screen is skipped, in both shapes that reach here:
|
|
329
|
+
// - its root is gone: it keeps its first render's id while the fragment
|
|
330
|
+
// carries the next page's id for it (ids are page-keyed on purpose), so
|
|
331
|
+
// the script has no markup of its own;
|
|
332
|
+
// - its root is present and already bound: the same page file on both
|
|
333
|
+
// sides of the navigation gives the same id.
|
|
334
|
+
// Either way running it built a second instance of a component whose markup
|
|
335
|
+
// stays bound to the first -- setup and its side effects repeated on every
|
|
336
|
+
// navigation. Scripts without an owner are unaffected.
|
|
337
|
+
function ownerStays(owner){
|
|
338
|
+
if(!owner)return false;
|
|
339
|
+
var root=document.querySelector('[data-stx-scope="'+owner+'"]');
|
|
340
|
+
return !root||typeof root.__stx_disposers==='function';
|
|
341
|
+
}
|
|
325
342
|
function hashScript(code){
|
|
326
343
|
var h=0;for(var i=0;i<code.length;i++){h=((h<<5)-h)+code.charCodeAt(i);h|=0}
|
|
327
344
|
return h;
|
|
@@ -819,7 +836,8 @@ else {
|
|
|
819
836
|
var slot='fragment-'+(++fragScriptId);
|
|
820
837
|
var scoped=/(?:^|\\s)data-stx-scoped(?:\\s|=|$)/i.test(attrs);
|
|
821
838
|
var runDecl=(attrs.match(/data-stx-run\\s*=\\s*["']?(always|once)["']?/i)||[])[1];
|
|
822
|
-
|
|
839
|
+
var ownerDecl=(attrs.match(/data-stx-owner\\s*=\\s*["']([^"']+)["']/i)||[])[1]||'';
|
|
840
|
+
fragScripts.push({text:code,slot:slot,setupName:generatedSetupName(code),scoped:scoped,run:runDecl?runDecl.toLowerCase():'',owner:ownerDecl});
|
|
823
841
|
// Retain scoped setup code in its inert placeholder. A placeholder
|
|
824
842
|
// inside template.content is unreachable through document, so the
|
|
825
843
|
// repeated component runtime must execute it for each clone.
|
|
@@ -934,6 +952,10 @@ else {
|
|
|
934
952
|
// declarations would throw "Identifier has already been declared"
|
|
935
953
|
// on re-execution. Setup functions (__stx_setup_) must always
|
|
936
954
|
// re-execute because each page has its own setup.
|
|
955
|
+
if(ownerStays(entry.owner)){
|
|
956
|
+
log('[router] skipping component that stayed on the page:', entry.owner);
|
|
957
|
+
return;
|
|
958
|
+
}
|
|
937
959
|
var h=hashScript(code);
|
|
938
960
|
var isSetup=code.indexOf('__stx_setup_')!==-1;
|
|
939
961
|
// Self-contained scope scripts must re-execute on every navigation:
|
|
@@ -1157,7 +1179,7 @@ else {
|
|
|
1157
1179
|
var slot='document-'+(++routedBodyScriptId);
|
|
1158
1180
|
var setupName=generatedSetupName(text);
|
|
1159
1181
|
if(setupName)incomingSetupName=setupName;
|
|
1160
|
-
routedBodyScripts.push({text:text,runAlways:true,slot:slot,setupName:setupName,run:s.getAttribute('data-stx-run')||''});
|
|
1182
|
+
routedBodyScripts.push({text:text,runAlways:true,slot:slot,setupName:setupName,run:s.getAttribute('data-stx-run')||'',owner:s.getAttribute('data-stx-owner')||''});
|
|
1161
1183
|
s.textContent='';
|
|
1162
1184
|
s.setAttribute('type','application/stx-pending');
|
|
1163
1185
|
s.setAttribute('data-stx-route-script',slot);
|
|
@@ -1226,8 +1248,8 @@ else {
|
|
|
1226
1248
|
document.querySelectorAll('script[data-stx-page]').forEach(function(s){s.remove()});
|
|
1227
1249
|
|
|
1228
1250
|
var scripts=routedBodyScripts.slice();
|
|
1229
|
-
function addScript(text, runAlways, slot){
|
|
1230
|
-
scripts.push({text:text,runAlways:!!runAlways,slot:slot||''});
|
|
1251
|
+
function addScript(text, runAlways, slot, owner){
|
|
1252
|
+
scripts.push({text:text,runAlways:!!runAlways,slot:slot||'',owner:owner||''});
|
|
1231
1253
|
}
|
|
1232
1254
|
if(isLayoutChange){
|
|
1233
1255
|
// Also collect setup functions from <head>
|
|
@@ -1257,7 +1279,9 @@ else {
|
|
|
1257
1279
|
var key=text.substring(0,80);
|
|
1258
1280
|
if(seenSetups[key])return;
|
|
1259
1281
|
seenSetups[key]=1;
|
|
1260
|
-
|
|
1282
|
+
// A layout component outside the container carries its owner, so
|
|
1283
|
+
// execScripts skips it when it stayed on the page (#1958).
|
|
1284
|
+
addScript(text,true,'',s.getAttribute('data-stx-owner')||'');
|
|
1261
1285
|
});
|
|
1262
1286
|
}
|
|
1263
1287
|
// Component setup scripts also assign window.stx._latestSetup. Run the
|
|
@@ -1328,6 +1352,7 @@ else {
|
|
|
1328
1352
|
scripts.forEach(function(entry){
|
|
1329
1353
|
var text=typeof entry==='string'?entry:entry.text;
|
|
1330
1354
|
var runAlways=typeof entry==='string'?false:entry.runAlways;
|
|
1355
|
+
if(typeof entry!=='string'&&ownerStays(entry.owner))return;
|
|
1331
1356
|
// Skip scripts that were already executed (layout-level partials
|
|
1332
1357
|
// like theme.stx). Their top-level const/function declarations
|
|
1333
1358
|
// would throw "Identifier has already been declared" on re-execution.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "stx-router",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.288",
|
|
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",
|