stx-router 0.2.119 → 0.2.120

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 +30 -3
  2. package/package.json +1 -1
package/dist/client.js CHANGED
@@ -419,8 +419,13 @@ else {
419
419
  var cleanFrag=html.replace(new RegExp('<scr'+'ipt\\\\b([^>]*)>([\\\\s\\\\S]*?)<\\\\/scr'+'ipt>','gi'),function(m,attrs,code){
420
420
  if(code&&code.trim()&&!isSignalsRuntimeScript({hasAttribute:function(name){return name==='data-stx-runtime'&&attrs.indexOf('data-stx-runtime')!==-1}},code)){
421
421
  var slot='fragment-'+(++fragScriptId);
422
- fragScripts.push({text:code,slot:slot,setupName:generatedSetupName(code)});
423
- return '<scr'+'ipt type="application/stx-pending" data-stx-route-script="'+slot+'"></scr'+'ipt>';
422
+ var scoped=/(?:^|\\s)data-stx-scoped(?:\\s|=|$)/i.test(attrs);
423
+ fragScripts.push({text:code,slot:slot,setupName:generatedSetupName(code),scoped:scoped});
424
+ // Retain scoped setup code in its inert placeholder. A placeholder
425
+ // inside template.content is unreachable through document, so the
426
+ // repeated component runtime must execute it for each clone.
427
+ return '<scr'+'ipt type="application/stx-pending" data-stx-route-script="'+slot+'"'
428
+ +(scoped?' data-stx-scoped':'')+'>'+code+'<\\/scr'+'ipt>';
424
429
  }
425
430
  return '';
426
431
  });
@@ -474,6 +479,29 @@ else {
474
479
  fragScripts.forEach(function(entry){
475
480
  var code=entry.text;
476
481
  log('[router] exec script len:', code.length, 'has __stx_setup:', code.indexOf('__stx_setup')>-1);
482
+ var placeholder=document.querySelector('script[data-stx-route-script="'+entry.slot+'"]');
483
+ var nestedScopedTemplate=false;
484
+ var scopedLoopSetup=false;
485
+ if(entry.scoped&&placeholder){
486
+ document.querySelectorAll('template').forEach(function(template){
487
+ if(template.contains(placeholder)||(template.content&&template.content.contains(placeholder)))
488
+ nestedScopedTemplate=true;
489
+ });
490
+ var loopRoot=placeholder.previousSibling;
491
+ while(loopRoot&&(
492
+ (loopRoot.nodeType===Node.TEXT_NODE&&!(loopRoot.textContent||'').trim())
493
+ ||loopRoot.nodeType===Node.COMMENT_NODE
494
+ ))loopRoot=loopRoot.previousSibling;
495
+ if(loopRoot&&loopRoot.nodeType===Node.ELEMENT_NODE&&loopRoot.hasAttribute('data-stx-scope')
496
+ &&(loopRoot.hasAttribute(':for')||loopRoot.hasAttribute('@for')||loopRoot.hasAttribute('x-for'))){
497
+ var loopScopeId=loopRoot.getAttribute('data-stx-scope');
498
+ scopedLoopSetup=!!loopScopeId&&code.indexOf(loopScopeId)!==-1;
499
+ }
500
+ }
501
+ if(entry.scoped&&(!placeholder||!placeholder.parentNode||nestedScopedTemplate||scopedLoopSetup)){
502
+ log('[router] leaving loop-scoped script for component hydration');
503
+ return;
504
+ }
477
505
  // Skip scripts that were already executed (layout-level partials
478
506
  // like theme.stx, stores.stx, nav.stx). Their top-level const/let
479
507
  // declarations would throw "Identifier has already been declared"
@@ -504,7 +532,6 @@ else {
504
532
  }
505
533
  ns.textContent=(hasImport||isAlreadyScoped)?code:'{'+code+'}';
506
534
  ns.setAttribute('data-stx-page','');
507
- var placeholder=document.querySelector('script[data-stx-route-script="'+entry.slot+'"]');
508
535
  if(placeholder&&placeholder.parentNode){
509
536
  ns.setAttribute('data-stx-positioned','');
510
537
  placeholder.parentNode.replaceChild(ns,placeholder);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "stx-router",
3
3
  "type": "module",
4
- "version": "0.2.119",
4
+ "version": "0.2.120",
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",