Skip to content

Commit

Permalink
Fix search on Safari and handle errors and :: queries
Browse files Browse the repository at this point in the history
`::` needs to be escaped to a space, since `:` is handled specially
by lunrjs.

Errors during search get displayed on the page.

Avoid import for json files as Safari doens't support it. Instead write
a JS file which sets a variable, and load it through a script tag.

Generate search index items for things without pages of their own:
- fields
- methods
- aliases
  • Loading branch information
danakj committed Dec 24, 2023
1 parent 3abc3a7 commit 08281be
Show file tree
Hide file tree
Showing 57 changed files with 3,049 additions and 1,441 deletions.
89 changes: 60 additions & 29 deletions subdoc/gen_tests/function-overloads/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
<meta name="description" content=""></meta>
<meta property="og:description" content=""></meta>
<script src="https://unpkg.com/lunr/lunr.js"></script>
<script src="./search_db.js"></script>
<script>

// Delayed loading of whatever was in the search box.
Expand All @@ -31,7 +32,7 @@
searchDelayLoad = null;

let without_search =
window.location.href.replace(window.location.search, '');
window.location.origin + window.location.pathname;
if (query) {
window.history.replaceState(null, "",
without_search + "?" + `search=${query}`);
Expand All @@ -53,9 +54,16 @@
e.preventDefault();
}
};
var searchPlaceholder;
document.querySelector(".search-input").onfocus = (e) => {
searchPlaceholder = e.target.placeholder;
e.target.placeholder = "Type your search here.";
navigateToSearch(e.target.value);
};
document.querySelector(".search-input").onblur = (e) => {
e.target.placeholder = searchPlaceholder;
searchPlaceholder = null;
};
});

// Show or hide any DOM element.
Expand All @@ -80,24 +88,32 @@
const search_db = loaded.search_db;
const idx = loaded.idx;

const results = idx.search(searchQuery());
// lunrjs treats `:` specially and `::` breaks the query syntax, so
// just split into two words.
const query = searchQuery().split("::").join(" ");
let content = '';
for (r of results) {
const item = search_db[r.ref];

const type = item.type;
const url = item.url;
const name = item.name;
const full_name = item.full_name;
const summmary = item.summary ? item.summary : "";

content += `\
<a class="search-results-link" href="${url}">
<span class="search-results-type">${type}</span>\
<span class="search-results-name">${full_name}</span>\
<span class="search-results-summary">${summmary}</span>\
</a>\
`
try {
const results = idx.search(query);
for (r of results) {
const item = search_db[r.ref];

const type = item.type;
const url = item.url;
const name = item.name;
const full_name = item.full_name;
const summmary = item.summary ? item.summary : "";

content += `\
<a class="search-results-link" href="${url}">
<span class="search-results-type">${type}</span>\
<span class="search-results-name">${full_name}</span>\
<span class="search-results-summary">${summmary}</span>\
</a>\
`
}
} catch (err) {
content +=
`<div class="search-error">Search error: ${err.message}</div>`;
}

let content_elem = document.querySelector(".search-results-content");
Expand All @@ -117,12 +133,14 @@
// - idx: the lunr search index.
// Documented at https://lunrjs.com/docs/lunr.Index.html.
async function loadSearchIndex() {
async function load_search_db() {
let x = await import('./search.json', {
assert: {type: 'json'}
});
return x.default;
}
// This is not widely supported yet (not on Safari), so instead we
// turned the json file into a js file that sets a global variable. :|
//async function load_search_db() {
// let x = await import('./search.json', {
// with: {type: 'json'}
// });
// return x.default;
//}

async function load_idx(search_db) {
let idx = lunr(function () {
Expand All @@ -146,6 +164,16 @@
// No stemming?
// this.pipeline = new lunr.Pipeline();

this.use(builder => {
function splitColons(token) {
return token.toString().split("::").map(str => {
return token.clone().update(() => { return str })
})
}
lunr.Pipeline.registerFunction(splitColons, 'splitColons')
builder.searchPipeline.before(lunr.stemmer, splitColons)
});

search_db.forEach(item => {
this.add(item, {
'boost': item.weight
Expand All @@ -159,7 +187,7 @@
};

if (!cache_idx) {
cache_idx = await load_search_db().then(load_idx);
cache_idx = await load_idx(g_search_db);
}
return cache_idx;
}
Expand All @@ -178,15 +206,18 @@
let header_elem = document.querySelector(".search-results-header");
header_elem.innerText = "Loading search results...";

let content_ele = document.querySelector(".search-results-content");
content_ele.innerText = "";

loadSearchIndex().then(populateSearchResults)
} else {
showHide(".main-content", true);

let header_elem = document.querySelector(".search-results-header");
header_elem.innerText = "";

let content_elem = document.querySelector(".search-results-content");
content_elem.innerText = "";
let content_ele = document.querySelector(".search-results-content");
content_ele.innerText = "";
}
}

Expand Down Expand Up @@ -238,7 +269,7 @@
<main>
<nav class="search-nav">
<form class="search-form">
<input class="search-input" name="search" autocomplete="off" spellcheck="false" placeholder="Click or press 'S' to search..." onblur="this.placeholder = 'Click or press \'S\' to search...'" onfocus="this.placeholder = 'Type your search here.'">
<input class="search-input" name="search" autocomplete="off" spellcheck="false" placeholder="Click or press 'S' to search...">
</input>
</form>
</nav>
Expand All @@ -254,7 +285,7 @@ <h1 class="search-results-header">
<div class="section overview">
<h1 class="section-header">
<div>
<a class="project-name" data-pagefind-weight="0" href="#">PROJECT NAME</a>
<a class="project-name" href="#">PROJECT NAME</a>
</div>
</h1>
<div class="description long">
Expand Down
93 changes: 62 additions & 31 deletions subdoc/gen_tests/function-overloads/n-fn.multiple.0.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
<meta name="description" content="Function with overloads"></meta>
<meta property="og:description" content="Function with overloads"></meta>
<script src="https://unpkg.com/lunr/lunr.js"></script>
<script src="./search_db.js"></script>
<script>

// Delayed loading of whatever was in the search box.
Expand All @@ -31,7 +32,7 @@
searchDelayLoad = null;

let without_search =
window.location.href.replace(window.location.search, '');
window.location.origin + window.location.pathname;
if (query) {
window.history.replaceState(null, "",
without_search + "?" + `search=${query}`);
Expand All @@ -53,9 +54,16 @@
e.preventDefault();
}
};
var searchPlaceholder;
document.querySelector(".search-input").onfocus = (e) => {
searchPlaceholder = e.target.placeholder;
e.target.placeholder = "Type your search here.";
navigateToSearch(e.target.value);
};
document.querySelector(".search-input").onblur = (e) => {
e.target.placeholder = searchPlaceholder;
searchPlaceholder = null;
};
});

// Show or hide any DOM element.
Expand All @@ -80,24 +88,32 @@
const search_db = loaded.search_db;
const idx = loaded.idx;

const results = idx.search(searchQuery());
// lunrjs treats `:` specially and `::` breaks the query syntax, so
// just split into two words.
const query = searchQuery().split("::").join(" ");
let content = '';
for (r of results) {
const item = search_db[r.ref];

const type = item.type;
const url = item.url;
const name = item.name;
const full_name = item.full_name;
const summmary = item.summary ? item.summary : "";

content += `\
<a class="search-results-link" href="${url}">
<span class="search-results-type">${type}</span>\
<span class="search-results-name">${full_name}</span>\
<span class="search-results-summary">${summmary}</span>\
</a>\
`
try {
const results = idx.search(query);
for (r of results) {
const item = search_db[r.ref];

const type = item.type;
const url = item.url;
const name = item.name;
const full_name = item.full_name;
const summmary = item.summary ? item.summary : "";

content += `\
<a class="search-results-link" href="${url}">
<span class="search-results-type">${type}</span>\
<span class="search-results-name">${full_name}</span>\
<span class="search-results-summary">${summmary}</span>\
</a>\
`
}
} catch (err) {
content +=
`<div class="search-error">Search error: ${err.message}</div>`;
}

let content_elem = document.querySelector(".search-results-content");
Expand All @@ -117,12 +133,14 @@
// - idx: the lunr search index.
// Documented at https://lunrjs.com/docs/lunr.Index.html.
async function loadSearchIndex() {
async function load_search_db() {
let x = await import('./search.json', {
assert: {type: 'json'}
});
return x.default;
}
// This is not widely supported yet (not on Safari), so instead we
// turned the json file into a js file that sets a global variable. :|
//async function load_search_db() {
// let x = await import('./search.json', {
// with: {type: 'json'}
// });
// return x.default;
//}

async function load_idx(search_db) {
let idx = lunr(function () {
Expand All @@ -146,6 +164,16 @@
// No stemming?
// this.pipeline = new lunr.Pipeline();

this.use(builder => {
function splitColons(token) {
return token.toString().split("::").map(str => {
return token.clone().update(() => { return str })
})
}
lunr.Pipeline.registerFunction(splitColons, 'splitColons')
builder.searchPipeline.before(lunr.stemmer, splitColons)
});

search_db.forEach(item => {
this.add(item, {
'boost': item.weight
Expand All @@ -159,7 +187,7 @@
};

if (!cache_idx) {
cache_idx = await load_search_db().then(load_idx);
cache_idx = await load_idx(g_search_db);
}
return cache_idx;
}
Expand All @@ -178,15 +206,18 @@
let header_elem = document.querySelector(".search-results-header");
header_elem.innerText = "Loading search results...";

let content_ele = document.querySelector(".search-results-content");
content_ele.innerText = "";

loadSearchIndex().then(populateSearchResults)
} else {
showHide(".main-content", true);

let header_elem = document.querySelector(".search-results-header");
header_elem.innerText = "";

let content_elem = document.querySelector(".search-results-content");
content_elem.innerText = "";
let content_ele = document.querySelector(".search-results-content");
content_ele.innerText = "";
}
}

Expand Down Expand Up @@ -232,7 +263,7 @@
<main>
<nav class="search-nav">
<form class="search-form">
<input class="search-input" name="search" autocomplete="off" spellcheck="false" placeholder="Click or press 'S' to search..." onblur="this.placeholder = 'Click or press \'S\' to search...'" onfocus="this.placeholder = 'Type your search here.'">
<input class="search-input" name="search" autocomplete="off" spellcheck="false" placeholder="Click or press 'S' to search...">
</input>
</form>
</nav>
Expand All @@ -250,11 +281,11 @@ <h1 class="section-header">
<span>
Function
</span>
<a class="project-name" data-pagefind-weight="1" href="index.html">PROJECT NAME</a>
<a class="project-name" href="index.html">PROJECT NAME</a>
<span class="namespace-dots">::</span>
<a class="namespace-name" data-pagefind-weight="1" href="namespace.n.html">n</a>
<a class="namespace-name" href="namespace.n.html">n</a>
<span class="namespace-dots">::</span>
<a class="function-name" data-pagefind-weight="20" href="#">multiple</a>
<a class="function-name" href="#">multiple</a>
</h1>
<div class="overload-set">
<div class="overload">
Expand Down
Loading

0 comments on commit 08281be

Please sign in to comment.