261029.4 · 00011b6688dc6372821c09b0a62727dbb8effcb3
A search's recent pages come only from the page's own tree
Recent pages crossed trees, so on the web address a search in one repo listed pages from repos read before. Each page's search box now names its tree, and each stored entry keeps the tree it was opened in. A version counts as its tree. Entries stored before this have no tree and are dropped.
reading declarations
Changes to assets/. All files
@@ -13,7 +13,7 @@ <nav>{{range $i, $c := .Crumbs}}{{if $i}} / {{end}}{{if $c.Href}}<a href="{{$c.Href}}"{{with $c.Title}} title="{{.}}"{{end}}>{{$c.Label}}</a>{{else if $c.Title}}<span title="{{$c.Title}}">{{$c.Label}}</span>{{else}}<span>{{$c.Label}}</span>{{end}}{{end}}</nav> {{if not .Stopped}}<span>{{with .Status}}<span class="age">{{.}}</span>{{end}}{{if .Raw}}<a href="?raw">raw</a>{{end}}{{if not (or .Shared .NoStop)}}<form method="post" action="{{ownPath}}stop">{{if .Tree}}<input type="hidden" name="tree" value="{{.Tree}}"><button>Delete lock</button>{{else}}<button class="kill">Kill server</button>{{end}}</form>{{end}}</span>{{end}} </header>-{{if not .Stopped}}{{with .Search}}<div class="search"><input type="search" class="search" data-search="{{.}}" placeholder="search" aria-label="Search this directory" autocomplete="off"><span class="tools"><button class="copy" title="copy the page's text" aria-label="copy the page's text">⧉</button>{{if $.Forge}}<button class="share" data-forge="{{$.Forge}}" data-lines="{{$.ForgeLines}}" title="copy the forge's link to what is selected, or to the page" aria-label="copy the forge's link to what is selected, or to the page">⤴</button>{{else}}<button class="share" title="copy a link to what is selected, or to the page" aria-label="copy a link to what is selected, or to the page">⤴</button>{{end}}</span></div>+{{if not .Stopped}}{{with .Search}}<div class="search"><input type="search" class="search" data-search="{{.}}" data-recents="{{$.Recents}}" placeholder="search" aria-label="Search this directory" autocomplete="off"><span class="tools"><button class="copy" title="copy the page's text" aria-label="copy the page's text">⧉</button>{{if $.Forge}}<button class="share" data-forge="{{$.Forge}}" data-lines="{{$.ForgeLines}}" title="copy the forge's link to what is selected, or to the page" aria-label="copy the forge's link to what is selected, or to the page">⤴</button>{{else}}<button class="share" title="copy a link to what is selected, or to the page" aria-label="copy a link to what is selected, or to the page">⤴</button>{{end}}</span></div> {{end}}{{end}}<main> {{.Body}} </main>
@@ -578,12 +578,19 @@ // origin, never on the server, so each viewer of a share sees only // what that viewer opened. Each entry counts its visits and keeps the // last; the score weighs both, as zoxide does. A reload is no visit.+ // Each entry names its tree, and a search lists only the page's own+ // tree, so one repo's reading never shows in another's. An entry+ // without a tree predates that and is dropped. const recentKey = "recent"; const maxRecent = 300;+ const recentTree = () => {+ const b = box();+ return b ? b.dataset.recents : undefined;+ }; const readRecent = () => { try { const list = JSON.parse(localStorage.getItem(recentKey));- return Array.isArray(list) ? list : [];+ return Array.isArray(list) ? list.filter((e) => typeof e.r === "string") : []; } catch { return []; }@@ -594,7 +601,9 @@ }; const recentPaths = () => { const now = Date.now();+ const tree = recentTree(); return readRecent()+ .filter((e) => e.r === tree) .sort((a, b) => score(b, now) - score(a, now)) .map((e) => e.p); };@@ -617,13 +626,16 @@ if (!["doc", "code", "dir"].includes(document.body.className)) return; const nav = performance.getEntriesByType("navigation")[0]; if (nav && nav.type === "reload") return;+ const tree = recentTree();+ if (tree === undefined) return; const now = Date.now(); const list = readRecent(); const e = list.find((e) => e.p === location.pathname); if (e) { e.n++; e.t = now;- } else list.push({ p: location.pathname, n: 1, t: now });+ e.r = tree;+ } else list.push({ p: location.pathname, r: tree, n: 1, t: now }); list.sort((a, b) => score(b, now) - score(a, now)); try { localStorage.setItem(recentKey, JSON.stringify(list.slice(0, maxRecent)));