step8 fix: wildcard gate data-expect-any="1" (end-a) + deep search index path ../../data/ (query.html) + forbidden-table path derived from data-index (components.js); both browser-verified, NOTE empty

This commit is contained in:
2026-09-30 15:07:45 +08:00
parent 2ad5604b51
commit bdb2fe093c
3 changed files with 10 additions and 4 deletions
+8 -2
View File
@@ -149,7 +149,13 @@ Alpine.data('search', () => ({
if (!this.q) return;
const enc = hash(this.q);
const forbiddenTable = await (await fetch('data/forbidden.json')).json();
// Resolve both tables relative to the mounting page: data-index is kept relative to the mounting
// page (search.html template contract), so a deep search carries "../../data/keywords.secret.json"
// and its forbidden table lives beside it. Deriving forbidden from the index directory keeps the
// root hub ("data/…") and a deep page ("../../data/…") both correct.
const idx = this.$el.dataset.index;
const forbiddenUrl = new URL('forbidden.json', new URL(idx, location.href)).href;
const forbiddenTable = await (await fetch(forbiddenUrl)).json();
const hit = Object.values(forbiddenTable).find(f => f.keywords.includes(enc));
if (hit) { // State 3: forbidden — full-page reskin (background/title/logo/footer)
this.forbidden = hit;
@@ -159,7 +165,7 @@ Alpine.data('search', () => ({
return;
}
const map = await (await fetch(this.$el.dataset.index)).json();
const map = await (await fetch(idx)).json();
this.results = map[enc] ?? [];
this.state = this.results.length ? 'hit' : 'miss';
},