stx-router 0.2.265 → 0.2.267
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 +50 -16
- package/package.json +1 -1
package/dist/client.js
CHANGED
|
@@ -125,6 +125,45 @@ export function getRouterScript() {
|
|
|
125
125
|
delete attrsCache[oldest];
|
|
126
126
|
}
|
|
127
127
|
}
|
|
128
|
+
// Read a prefetch response into the shape setCache stores, or null when this
|
|
129
|
+
// answer must not be cached at all.
|
|
130
|
+
//
|
|
131
|
+
// Both prefetch paths used to assemble this by hand, and both left out
|
|
132
|
+
// X-STX-Container-Attrs (#1947): setCache takes six arguments and they
|
|
133
|
+
// passed five, which JavaScript accepts without a word. The entry was
|
|
134
|
+
// cached with no container attributes, so a link that had been hovered
|
|
135
|
+
// before it was clicked applied '' on the cache hit, and setContainerAttrs
|
|
136
|
+
// stripped the class the previous navigation had put on the routed
|
|
137
|
+
// container. A dashboard lost its max-width, but only on links that
|
|
138
|
+
// happened to be hovered first, and a hard reload always fixed it \u2014 which
|
|
139
|
+
// made it read as a CSS problem.
|
|
140
|
+
//
|
|
141
|
+
// Hand-assembling it twice is what let them drift, so the two guards below
|
|
142
|
+
// live here rather than at the call sites \u2014 the hover path had one of them
|
|
143
|
+
// and the public router.prefetch() had neither:
|
|
144
|
+
//
|
|
145
|
+
// - a redirected body belongs to the URL it came FROM. A guarded route
|
|
146
|
+
// prefetched while logged out answers with /login's markup, and storing
|
|
147
|
+
// that under the guarded key poisons the cache: the later real
|
|
148
|
+
// navigation is a hit, so it swaps the login page in without ever
|
|
149
|
+
// reaching the network, where navigate's own redirect check would have
|
|
150
|
+
// caught it (#1849).
|
|
151
|
+
// - a fragment from a DIFFERENT build must not be handed to this page's
|
|
152
|
+
// runtime (#1772). navigate answers skew by reloading; a prefetch must
|
|
153
|
+
// not, because the user only hovered a link. Declining to cache is the
|
|
154
|
+
// whole fix \u2014 the click then goes to the network, where navigate does
|
|
155
|
+
// the reload properly.
|
|
156
|
+
function readPrefetchResponse(r,wantsFragment){
|
|
157
|
+
if(r.redirected)return Promise.resolve(null);
|
|
158
|
+
if(isBuildSkew(r.headers.get('X-STX-Build')||''))return Promise.resolve(null);
|
|
159
|
+
var isFrag=wantsFragment&&r.headers.get('X-STX-Fragment')==='true';
|
|
160
|
+
var layout=r.headers.get('X-STX-Layout')||'';
|
|
161
|
+
var group=r.headers.get('X-STX-Layout-Group')||'';
|
|
162
|
+
var title=r.headers.get('X-STX-Title')||'';
|
|
163
|
+
var cattrs=r.headers.get('X-STX-Container-Attrs')||'';
|
|
164
|
+
var runtime=r.headers.get('X-STX-Runtime')||'';
|
|
165
|
+
return r.text().then(function(html){return{html:isFrag?fragmentMarker(runtime)+html:html,layout:layout,layoutGroup:group,title:title,containerAttrs:cattrs}});
|
|
166
|
+
}
|
|
128
167
|
// Apply a page title captured from the fragment response's X-STX-Title
|
|
129
168
|
// header (URI-encoded) so SPA swaps keep document.title in sync with the
|
|
130
169
|
// page \u2014 full-document swaps set the title from the <title> tag directly.
|
|
@@ -145,7 +184,14 @@ export function getRouterScript() {
|
|
|
145
184
|
var probe=document.createElement('div');
|
|
146
185
|
probe.innerHTML='<i '+attrStr+'></i>';
|
|
147
186
|
var src=probe.firstChild;
|
|
148
|
-
|
|
187
|
+
// getAttributeNames first: it is the same standard DOM answer and it is
|
|
188
|
+
// what the test DOM implements. Reading .attributes alone made this
|
|
189
|
+
// silently return {} there \u2014 so the whole container-attrs path, header to
|
|
190
|
+
// element, had no test coverage at all while #1947 sat in it.
|
|
191
|
+
if(src&&src.getAttributeNames){
|
|
192
|
+
src.getAttributeNames().forEach(function(n){map[n]=src.getAttribute(n)});
|
|
193
|
+
}
|
|
194
|
+
else if(src&&src.attributes){
|
|
149
195
|
Array.prototype.forEach.call(src.attributes,function(a){map[a.name]=a.value});
|
|
150
196
|
}
|
|
151
197
|
return map;
|
|
@@ -1609,21 +1655,9 @@ else {
|
|
|
1609
1655
|
prefetching[key]=true;
|
|
1610
1656
|
var wantsFragment=shouldUseFragmentResponse();
|
|
1611
1657
|
fetch(href,{headers:wantsFragment?{'X-STX-Router':'true','Accept':'text/html'}:{'Accept':'text/html'}}).then(function(r){
|
|
1612
|
-
|
|
1613
|
-
// prefetched while logged out answers with /login's markup, and
|
|
1614
|
-
// storing it under the guarded key poisons the cache: the later real
|
|
1615
|
-
// navigation is a cache hit, so it swaps the login page in without
|
|
1616
|
-
// ever hitting the network, where the redirect check above would
|
|
1617
|
-
// have caught it (#1849).
|
|
1618
|
-
if(r.redirected)return null;
|
|
1619
|
-
var isFrag=wantsFragment&&r.headers.get('X-STX-Fragment')==='true';
|
|
1620
|
-
var pLayout=r.headers.get('X-STX-Layout')||'';
|
|
1621
|
-
var pGroup=r.headers.get('X-STX-Layout-Group')||'';
|
|
1622
|
-
var pTitle=r.headers.get('X-STX-Title')||'';
|
|
1623
|
-
var pRuntime=r.headers.get('X-STX-Runtime')||'';
|
|
1624
|
-
return r.text().then(function(html){return{html:isFrag?fragmentMarker(pRuntime)+html:html,layout:pLayout,layoutGroup:pGroup,title:pTitle}});
|
|
1658
|
+
return readPrefetchResponse(r,wantsFragment);
|
|
1625
1659
|
}).then(function(result){
|
|
1626
|
-
if(result&&o.cache)setCache(key,result.html,result.layout,result.layoutGroup,result.title);
|
|
1660
|
+
if(result&&o.cache)setCache(key,result.html,result.layout,result.layoutGroup,result.title,result.containerAttrs);
|
|
1627
1661
|
}).catch(function(){}).finally(function(){delete prefetching[key]});
|
|
1628
1662
|
},true);
|
|
1629
1663
|
}
|
|
@@ -1739,7 +1773,7 @@ else {
|
|
|
1739
1773
|
var key=cacheKey(url);
|
|
1740
1774
|
if(!cache[key]){
|
|
1741
1775
|
var wantsFragment=shouldUseFragmentResponse();
|
|
1742
|
-
fetch(url,{headers:wantsFragment?{'X-STX-Router':'true'}:{'Accept':'text/html'}}).then(function(r){
|
|
1776
|
+
fetch(url,{headers:wantsFragment?{'X-STX-Router':'true'}:{'Accept':'text/html'}}).then(function(r){return readPrefetchResponse(r,wantsFragment)}).then(function(result){if(result)setCache(key,result.html,result.layout,result.layoutGroup,result.title,result.containerAttrs)}).catch(function(){});
|
|
1743
1777
|
}
|
|
1744
1778
|
},
|
|
1745
1779
|
// Re-run the CURRENT route against the server and swap the result.
|
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.267",
|
|
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",
|