-
Notifications
You must be signed in to change notification settings - Fork 26
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
272 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,268 @@ | ||
(function () { | ||
/* eslint-disable no-unused-vars */ | ||
|
||
function escapeHtml(string) { | ||
var entityMap = { | ||
"&": "&", | ||
"<": "<", | ||
">": ">", | ||
'"': """, | ||
"'": "'", | ||
}; | ||
|
||
return String(string).replace(/[&<>"']/g, function (s) { | ||
return entityMap[s]; | ||
}); | ||
} | ||
|
||
var abortController; | ||
|
||
/** | ||
* @param {String} query Search query | ||
* @returns {Array} Array of results | ||
*/ | ||
async function search(query) { | ||
if (abortController) abortController.abort(); | ||
|
||
abortController = new AbortController(); | ||
|
||
const response = await fetch(`https://api.trieve.ai/api/chunk/search`, { | ||
method: "POST", | ||
headers: { | ||
Authorization: `${CONFIG.api_key}`, | ||
"TR-Dataset": `${CONFIG.dataset}`, | ||
"Content-Type": "application/json", | ||
}, | ||
body: JSON.stringify({ | ||
query: query, | ||
search_type: "semantic", | ||
highlight_delimiters: [" "], | ||
highlight_max_length: 100, | ||
highlight_max_num: 2, | ||
highlight_window: 20, | ||
score_threshold: 0.05, | ||
}), | ||
signal: abortController.signal, | ||
}); | ||
|
||
if (!response.ok) { | ||
throw new Error("Failed to fetch search results"); | ||
} | ||
|
||
results = await response.json(); | ||
|
||
let matches = []; | ||
|
||
results.score_chunks.forEach((chunk) => { | ||
if (chunk.highlights.length === 0) return; | ||
|
||
title = | ||
chunk.metadata[0].metadata?.title ?? chunk.metadata[0].tracking_id; | ||
content = "..." + chunk.highlights.join("<br/>") + "..."; | ||
url = chunk.metadata[0].link.replace( | ||
/^https?:\/\/[^\/]+\//, | ||
window.DOCSIFY_ROUTER_MODE == "hash" ? "#/" : "/" | ||
); | ||
|
||
matches.push({ | ||
title, | ||
content, | ||
url, | ||
}); | ||
}); | ||
|
||
return matches; | ||
} | ||
|
||
/* eslint-disable no-unused-vars */ | ||
|
||
var NO_DATA_TEXT = ""; | ||
var options; | ||
|
||
function style() { | ||
var code = | ||
"\n.sidebar {\n padding-top: 0;\n}\n\n.search {\n margin-bottom: 20px;\n padding: 6px;\n border-bottom: 1px solid #eee;\n}\n\n.search .input-wrap {\n display: flex;\n align-items: center;\n}\n\n.search .results-panel {\n display: none;\n}\n\n.search .results-panel.show {\n display: block;\n}\n\n.search input {\n outline: none;\n border: none;\n width: 100%;\n padding: 0 7px;\n line-height: 36px;\n font-size: 14px;\n border: 1px solid transparent;\n}\n\n.search input:focus {\n box-shadow: 0 0 5px var(--theme-color, #42b983);\n border: 1px solid var(--theme-color, #42b983);\n}\n\n.search input::-webkit-search-decoration,\n.search input::-webkit-search-cancel-button,\n.search input {\n -webkit-appearance: none;\n -moz-appearance: none;\n appearance: none;\n}\n.search .clear-button {\n cursor: pointer;\n width: 36px;\n text-align: right;\n display: none;\n}\n\n.search .clear-button.show {\n display: block;\n}\n\n.search .clear-button svg {\n transform: scale(.5);\n}\n\n.search h2 {\n font-size: 17px;\n margin: 10px 0;\n}\n\n.search a {\n text-decoration: none;\n color: inherit;\n}\n\n.search .matching-post {\n border-bottom: 1px solid #eee;\n}\n\n.search .matching-post:last-child {\n border-bottom: 0;\n}\n\n.search p {\n font-size: 14px;\n overflow: hidden;\n text-overflow: ellipsis;\n display: -webkit-box;\n -webkit-line-clamp: 4;\n -webkit-box-orient: vertical;\n}\n\n.search p.empty {\n text-align: center;\n}\n\n.app-name.hide, .sidebar-nav.hide {\n display: none;\n}"; | ||
|
||
Docsify.dom.style(code); | ||
} | ||
|
||
function tpl(defaultValue) { | ||
if (defaultValue === void 0) defaultValue = ""; | ||
|
||
var html = | ||
'<div class="input-wrap">\n <input type="search" value="' + | ||
defaultValue + | ||
'" aria-label="Search text" />\n <div class="clear-button">\n <svg width="26" height="24">\n <circle cx="12" cy="12" r="11" fill="#ccc" />\n <path stroke="white" stroke-width="2" d="M8.25,8.25,15.75,15.75" />\n <path stroke="white" stroke-width="2"d="M8.25,15.75,15.75,8.25" />\n </svg>\n </div>\n </div>\n <div class="results-panel"></div>\n </div>'; | ||
var el = Docsify.dom.create("div", html); | ||
var aside = Docsify.dom.find("aside"); | ||
|
||
Docsify.dom.toggleClass(el, "search"); | ||
Docsify.dom.before(aside, el); | ||
} | ||
|
||
async function doSearch(value) { | ||
var $search = Docsify.dom.find("div.search"); | ||
var $panel = Docsify.dom.find($search, ".results-panel"); | ||
var $clearBtn = Docsify.dom.find($search, ".clear-button"); | ||
var $sidebarNav = Docsify.dom.find(".sidebar-nav"); | ||
var $appName = Docsify.dom.find(".app-name"); | ||
|
||
if (!value) { | ||
$panel.classList.remove("show"); | ||
$clearBtn.classList.remove("show"); | ||
$panel.innerHTML = ""; | ||
|
||
if (options.hideOtherSidebarContent) { | ||
$sidebarNav.classList.remove("hide"); | ||
$appName.classList.remove("hide"); | ||
} | ||
|
||
return; | ||
} | ||
|
||
var matchs; | ||
|
||
try { | ||
matchs = await search(value); | ||
} catch (e) { | ||
if (e.name !== "AbortError") { | ||
console.error(e); | ||
} | ||
return; | ||
} | ||
|
||
var html = ""; | ||
matchs.forEach(function (post) { | ||
html += | ||
'<div class="matching-post">\n<a href="' + | ||
post.url + | ||
'">\n<h2>' + | ||
post.title + | ||
"</h2>\n<p>" + | ||
post.content + | ||
"</p>\n</a>\n</div>"; | ||
}); | ||
|
||
$panel.classList.add("show"); | ||
$clearBtn.classList.add("show"); | ||
$panel.innerHTML = html || '<p class="empty">' + NO_DATA_TEXT + "</p>"; | ||
if (options.hideOtherSidebarContent) { | ||
$sidebarNav.classList.add("hide"); | ||
$appName.classList.add("hide"); | ||
} | ||
} | ||
|
||
function bindEvents() { | ||
var $search = Docsify.dom.find("div.search"); | ||
var $input = Docsify.dom.find($search, "input"); | ||
var $inputWrap = Docsify.dom.find($search, ".input-wrap"); | ||
|
||
var timeId; | ||
|
||
/** | ||
Prevent to Fold sidebar. | ||
When searching on the mobile end, | ||
the sidebar is collapsed when you click the INPUT box, | ||
making it impossible to search. | ||
*/ | ||
Docsify.dom.on($search, "click", function (e) { | ||
return ( | ||
["A", "H2", "P", "EM"].indexOf(e.target.tagName) === -1 && | ||
e.stopPropagation() | ||
); | ||
}); | ||
Docsify.dom.on($input, "input", function (e) { | ||
clearTimeout(timeId); | ||
timeId = setTimeout(function (_) { | ||
return doSearch(e.target.value.trim()); | ||
}, 100); | ||
}); | ||
Docsify.dom.on($inputWrap, "click", function (e) { | ||
// Click input outside | ||
if (e.target.tagName !== "INPUT") { | ||
$input.value = ""; | ||
doSearch(); | ||
} | ||
}); | ||
} | ||
|
||
function updatePlaceholder(text, path) { | ||
var $input = Docsify.dom.getNode('.search input[type="search"]'); | ||
|
||
if (!$input) { | ||
return; | ||
} | ||
|
||
if (typeof text === "string") { | ||
$input.placeholder = text; | ||
} else { | ||
var match = Object.keys(text).filter(function (key) { | ||
return path.indexOf(key) > -1; | ||
})[0]; | ||
$input.placeholder = text[match]; | ||
} | ||
} | ||
|
||
function updateNoData(text, path) { | ||
if (typeof text === "string") { | ||
NO_DATA_TEXT = text; | ||
} else { | ||
var match = Object.keys(text).filter(function (key) { | ||
return path.indexOf(key) > -1; | ||
})[0]; | ||
NO_DATA_TEXT = text[match]; | ||
} | ||
} | ||
|
||
function updateOptions(opts) { | ||
options = opts; | ||
} | ||
|
||
function init(opts, vm) { | ||
var keywords = vm.router.parse().query.s; | ||
|
||
updateOptions(opts); | ||
style(); | ||
tpl(keywords); | ||
bindEvents(); | ||
keywords && | ||
setTimeout(function (_) { | ||
return doSearch(keywords); | ||
}, 500); | ||
} | ||
|
||
function update(opts, vm) { | ||
updateOptions(opts); | ||
updatePlaceholder(opts.placeholder, vm.route.path); | ||
updateNoData(opts.noData, vm.route.path); | ||
} | ||
|
||
/* eslint-disable no-unused-vars */ | ||
|
||
var CONFIG = { | ||
placeholder: "Type to search", | ||
noData: "No Results!", | ||
hideOtherSidebarContent: false, | ||
api_key: window.TRIEVE_API_KEY, | ||
dataset: window.TRIEVE_DATASET, | ||
}; | ||
|
||
var install = function (hook, vm) { | ||
var opts = vm.config.search || CONFIG; | ||
|
||
CONFIG.placeholder = opts.placeholder || CONFIG.placeholder; | ||
CONFIG.noData = opts.noData || CONFIG.noData; | ||
CONFIG.hideOtherSidebarContent = | ||
opts.hideOtherSidebarContent || CONFIG.hideOtherSidebarContent; | ||
|
||
hook.mounted(function (_) { | ||
init(CONFIG, vm); | ||
}); | ||
hook.doneEach(function (_) { | ||
update(CONFIG, vm); | ||
}); | ||
}; | ||
|
||
$docsify.plugins = [].concat(install, $docsify.plugins); | ||
})(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -33,6 +33,9 @@ | |
<script> !function(t,e){var o,n,p,r;e.__SV||(window.posthog=e,e._i=[],e.init=function(i,s,a){function g(t,e){var o=e.split(".");2==o.length&&(t=t[o[0]],e=o[1]),t[e]=function(){t.push([e].concat(Array.prototype.slice.call(arguments,0)))}}(p=t.createElement("script")).type="text/javascript",p.async=!0,p.src=s.api_host+"/static/array.js",(r=t.getElementsByTagName("script")[0]).parentNode.insertBefore(p,r);var u=e;for(void 0!==a?u=e[a]=[]:a="posthog",u.people=u.people||[],u.toString=function(t){var e="posthog";return"posthog"!==a&&(e+="."+a),t||(e+=" (stub)"),e},u.people.toString=function(){return u.toString(1)+".people (stub)"},o="capture identify alias people.set people.set_once set_config register register_once unregister opt_out_capturing has_opted_out_capturing opt_in_capturing reset isFeatureEnabled onFeatureFlags getFeatureFlag getFeatureFlagPayload reloadFeatureFlags group updateEarlyAccessFeatureEnrollment getEarlyAccessFeatures getActiveMatchingSurveys getSurveys".split(" "),n=0;n<o.length;n++)g(u,o[n]);e._i.push([i,s,a])},e.__SV=1)}(document,window.posthog||[]); | ||
posthog.init('phc_fc9VFWdFAAm5gSlCodHq93iaxxnTTKbjOwsWgAS1FMP',{api_host:'https://app.posthog.com'})</script> | ||
<!-- End Posthog --> | ||
<!-- Trieve --> | ||
<script>window.TRIEVE_DATASET = "38d0ad51-82d5-45dc-b8b6-817bcf49da35"; window.TRIEVE_API_KEY = "tr-JtPZuXATfHbKLyKxsHFa66tVqXZ0wUvM"</script> | ||
<!-- End Trieve --> | ||
</head> | ||
<body> | ||
<div id="app"></div> | ||
|
@@ -215,7 +218,7 @@ | |
} | ||
</script> | ||
<script src="//cdn.jsdelivr.net/npm/docsify@4"></script> | ||
<script src="/assets/docsify-search.js"></script> | ||
<script src="/assets/docsify-trieve-search.js"></script> | ||
<script src="//unpkg.com/[email protected]/dist/docsify-namespaced.min.js"></script> | ||
<script src="//cdn.jsdelivr.net/npm/katex@latest/dist/katex.min.js"></script> | ||
<script src="//cdn.jsdelivr.net/npm/marked@4"></script> | ||
|