incremental全文検索のテスト
でないとmax-heightを無視して<ul>が縦に伸びてしまう
2021-05-21
21:34:50 こんな感じ
https://gyazo.com/a3209ad24fda22871c80810eb1279848
21:02:43 projectを変えられるようにした
https://gyazo.com/31bb620a15fe2ad592c8bd231d75bfbd
1文字目からいきなり検索を初めちゃうのはきついな
21:09:56 入れた
21:11:44 試した
21:22:00 高速でタイプした時、最後に入力した文字列が実行されていないようだ
21:32:11 直した
20:55:12 project名を変えられるように試行錯誤中
属性からは外した
内部のuseState()で値を変えても、属性が変わらない限り変化しないみたいだったので
useMemo()でprojectを依存配列に入れてなかったのが原因だ
函数を返す函数だったので、useCallback()じゃなくてよかった
ついでに検索中の語句を出せるようにした
20:34:30 中身を表示できるようにした
https://gyazo.com/72e7f1a93d2e568e13914d874beb3a09
あと要素の属性を変更すれば、検索先projectを切り替えられる事もわかった
20:19:31 リンク表示までできた
検索中はSearching...と表示される
https://gyazo.com/0ade14e0841a9c10b8c1c58d7c3b4896
References
code:js
import('/api/code/programming-notes/incremental全文検索のテスト/script.js');
code:script.js
import {html} from '../htm@3.0.4%2Fpreact/script.js';
import {throttle} from '../custom-throttle/script.js';
import {useState, useMemo} from '../preact@10.5.13/hooks.js';
import register from '../preact-custom-element@4.2.1/script.js';
const titleLc = title => title.toLowerCase().replaceAll(' ', '_').replace('/', '%2F');
const App = () => {
const search = useMemo(() => throttle(async (query) => {
setQuery(query);
if (query === '') {
setItems([]);
return;
}
try {
const res = await fetch(/api/pages/${project}/search/query?q=${encodeURIComponent(query)});
const {pages} = await res.json();
setItems(pages.map(({title, words, lines}) => ({project, title, words, lines})));
} catch(e) {
console.error(e);
setItems([]);
} finally {
setQuery('');
}
return html`
<style>
:host {
display: block;
}
ul {
max-height: 50vh;
overflow-y: auto;
}
a {
background-color: transparent;
text-decoration: none;
cursor: pointer;
}
a:hover {color: var(--page-link-hover-color, #2d67f5);} span {
margin-right: .5em;
}
</style>
${query !== '' && html<div>Searching for ${query}...</div>}
${items.length > 0 && html<div>${items.length} results</div>}
<ul>
${items.map(item => html`<li key="${item}">
<a href="/${item.project}/${titleLc(item.title)}" target="_blank">
/${item.project}/${item.title}
</a>
<br />
${item.lines.map(line => html<span>${line}</span>)}
</li>`)}
</ul>
<input type="text" onInput="${({target}) => search(target.value)}" />
<input type="text" value="${project}" onChange="${({target}) => setProject(target.value)}" />
`;
};
register(App, 'userscript-search-test', [], {shadow: true});
document.getElementById('editor')
.insertAdjacentHTML('beforebegin', '<userscript-search-test></userscript-search-test>');