Add cross-domain SX navigation with OOB swap
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 1m38s
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 1m38s
Enable instant cross-subdomain navigation (blog → market, etc.) via sx-get instead of full page reloads. The server prepends missing component definitions to OOB responses so the client can render components from other domains. - sexp.js: send SX-Components header, add credentials for cross-origin fetches to .rose-ash.com/.localhost, process sexp scripts in response before OOB swap - helpers.py: add components_for_request() to diff client/server component sets, update sexp_response() to prepend missing defs - factory.py: add SX-Components to CORS allowed headers, add Access-Control-Allow-Methods - fragments/routes.py: switch nav items from ~blog-nav-item-plain to ~blog-nav-item-link (sx-get enabled) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1452,6 +1452,12 @@
|
||||
var targetSel = el.getAttribute("sx-target");
|
||||
if (targetSel) headers["SX-Target"] = targetSel;
|
||||
|
||||
// Send loaded component names so cross-domain responses can prepend missing defs
|
||||
var loadedNames = Object.keys(_componentEnv).filter(function (k) {
|
||||
return k.charAt(0) === "~";
|
||||
});
|
||||
if (loadedNames.length) headers["SX-Components"] = loadedNames.join(",");
|
||||
|
||||
// Extra headers from sx-headers
|
||||
var extraH = el.getAttribute("sx-headers");
|
||||
if (extraH) {
|
||||
@@ -1545,6 +1551,14 @@
|
||||
el.setAttribute("aria-busy", "true");
|
||||
|
||||
var fetchOpts = { method: method, headers: headers, signal: ctrl.signal };
|
||||
// Cross-origin credentials for known subdomains
|
||||
try {
|
||||
var urlHost = new URL(url, location.href).hostname;
|
||||
if (urlHost !== location.hostname &&
|
||||
(urlHost.endsWith(".rose-ash.com") || urlHost.endsWith(".localhost"))) {
|
||||
fetchOpts.credentials = "include";
|
||||
}
|
||||
} catch (e) {}
|
||||
if (body && method !== "GET") fetchOpts.body = body;
|
||||
|
||||
return fetch(url, fetchOpts).then(function (resp) {
|
||||
@@ -1580,6 +1594,9 @@
|
||||
var parser = new DOMParser();
|
||||
var doc = parser.parseFromString(text, "text/html");
|
||||
|
||||
// Process any sexp script blocks in the response (e.g. cross-domain component defs)
|
||||
Sexp.processScripts(doc);
|
||||
|
||||
// OOB processing: extract elements with sx-swap-oob
|
||||
var oobs = doc.querySelectorAll("[sx-swap-oob]");
|
||||
oobs.forEach(function (oob) {
|
||||
@@ -1854,9 +1871,17 @@
|
||||
}
|
||||
}
|
||||
// Fetch fresh
|
||||
fetch(url, {
|
||||
var histOpts = {
|
||||
headers: { "SX-Request": "true", "SX-History-Restore": "true" }
|
||||
}).then(function (resp) {
|
||||
};
|
||||
try {
|
||||
var hHost = new URL(url, location.href).hostname;
|
||||
if (hHost !== location.hostname &&
|
||||
(hHost.endsWith(".rose-ash.com") || hHost.endsWith(".localhost"))) {
|
||||
histOpts.credentials = "include";
|
||||
}
|
||||
} catch (e) {}
|
||||
fetch(url, histOpts).then(function (resp) {
|
||||
return resp.text();
|
||||
}).then(function (text) {
|
||||
var ct = "";
|
||||
|
||||
Reference in New Issue
Block a user