類似したタイトルのページを関連ページとして表示する
改造してみる
改造ポイント
タイトルの監視だけなら、linesの先頭要素を監視すれば良い
NativeのDOM操作APIを使う
code:script.js
import {fizzSearch} from '/api/takker/fizzSearch/import.js';
(() => {
if (document.getElementById('asearch-list-grid').length !== 0) {
return;
}
$('.page-wrapper .related-page-list.clearfix').append(
'<ul class="grid" id="asearch-list-grid">' +
'<li class="splitter" style="height: 30px !important" />' +
'<li class="relation-label"><a><span class="title">Similar Pages</span>' +
'<span class="kamon kamon-search icon-lg"/></a><span class="arrow"/></li></ul>'
);
const grid = document.getElementById('#asearch-list-grid');
let prevTitle;
let titleLcMap;
function regenTitleLcMap() {
titleLcMap = {};
for (let p of scrapbox.Project.pages) {
}
}
regenTitleLcMap();
function resetList() {
grid.children().slice(2).remove();
}
function pathToTitle(path) {
const a = path.replace(/#.*$/, '').split('/');
if (a.length === 3 && a2.length > 0) { const title = decodeURIComponent(a2); // Project.pagesを元にタイトル取得
// (_が実際は空白なのか_なのか分からないため)
const titleLc = title.toLowerCase();
}
return null;
}
function updateList(title, replace) {
// 既に関連リンクに入っているページのタイトルを取得する
let links = new Set();
$('.page-wrapper .related-page-list.clearfix ul.grid:nth(0) li a').each(
(i, e) => {
links.add(pathToTitle(e.pathname));
}
);
const search = new Asearch(title);
const titleLc = title.toLowerCase();
const matchedTitles = fizzSearch(title, scrapbox.Project.pages.map(p => p.title));
scrapbox.Project.pages
.filter(page =>
page.title !== title
&& !links.has(page.title)
&& !(replace && page.title === prevTitle))
.map(page => fizzSearch )
.filter(matchedTitle => !(replace && matchedTitle === prevTitle))
.forEach(matchedTitle)
for (let p of scrapbox.Project.pages) {
if (p.title === title || links.has(p.title)) continue;
if (replace && p.title === prevTitle) continue;
if (
search.match(p.title, Math.min(title.length - 1, 2)) ||
p.titleLc.indexOf(titleLc) != -1 ||
titleLc.indexOf(p.titleLc) != -1
) {
const item = $(`<li class="page-list-item grid-style-item${
p.exists ? '' : ' empty'
}">
<a href="/${scrapbox.Project.name}/${encodeURIComponent(p.title.replace(' ', '_'))}" rel="route">
<div class="hover"></div>
<div class="content">
<div class="header"><div class="title"></div></div>
<div class="description"><div class="line-img">
<div></div><div></div><div></div><div></div><div></div>
</div></div>
</div>
</a>`);
$('.title', item).text(p.title);
grid.append(item);
}
grid.show();
}
}
// scrapbox.Page.title が書き換わるのを監視
//(その時点でページ書き換えが完了していることを期待)
function waitForUpdate(title, n, replace) {
if (scrapbox.Page.title === title) {
resetList();
regenTitleLcMap();
updateList(title, replace);
prevTitle = replace ? title : null;
return;
}
if (n == 0) {
resetList();
return;
}
setTimeout(() => waitForUpdate(title, n - 1, replace), 100);
}
function hook(func) {
const history = window.history;
const orig = historyfunc; historyfunc = (state) => { let title = pathToTitle(state.path);
if (title === 'new') {
resetList();
} else if (title) {
waitForUpdate(title, 50, func === 'replaceState');
}
return orig.apply(history, arguments);
};
}
hook('pushState');
hook('replaceState');
let observer = new MutationObserver(mutationRecords => {
updateList(mutationRecords); // console.log(the changes)
});
observer.observe(document.getElementsByClassName('line-titile')0, { // 属性以外のすべてを監視する
childList: true,
subtree: true,
characterData: true
});
})();