tomiokario
https://scrapbox.io/files/66407c8e26d826001d275643.png
ユーザースクリプト
code:script.js
(async function() {
// プロジェクト名を設定してください
const projectName = "TOMIOKARIO";
const baseUrl = https://scrapbox.io/api/pages/${projectName}/search/titles;
// 索引ページのタイトルを設定してください(ここからリンクをたどります)
const indexPageTitle = "索引";
// 全ページ情報を格納する配列
let allPages = [];
// 次ページの取得用 URL(最初はベースURL)
let nextUrl = baseUrl;
// API の応答がなくなるまで全件取得(1000件ずつ)
while (nextUrl) {
try {
const response = await fetch(nextUrl);
if (!response.ok) {
console.error(HTTPエラー: ${response.status});
break;
}
const pages = await response.json();
allPages.push(...pages);
// 応答ヘッダ「X-Following-Id」から次回用のIDを取得
const followingId = response.headers.get('X-Following-Id');
if (followingId) {
nextUrl = ${baseUrl}?followingId=${followingId};
} else {
nextUrl = null;
}
} catch (error) {
console.error("データ取得中にエラーが発生しました:", error);
break;
}
}
// 全ページ情報を元に、タイトルをキーとしたマップ(辞書型)を作成
const pagesMap = {};
allPages.forEach(page => {
});
// 索引ページからリンクをたどって到達可能なページを集合で収集
const reachable = new Set();
const queue = [];
// 初期状態として索引ページが存在する場合はキューに追加
queue.push(indexPageTitle);
} else {
console.error(索引ページ "${indexPageTitle}" が存在しません。);
}
// 幅優先探索(BFS)で到達可能なページ群を求める
while (queue.length > 0) {
const currentTitle = queue.shift();
if (reachable.has(currentTitle)) continue;
reachable.add(currentTitle);
if (currentPage && Array.isArray(currentPage.links)) {
currentPage.links.forEach(linkTitle => {
if (pagesMaplinkTitle && !reachable.has(linkTitle)) { queue.push(linkTitle);
}
});
}
}
// プロジェクト内のすべてのページの中から、索引経由でたどり着けなかったページを抽出
const unreachablePages = allPages.filter(page => !reachable.has(page.title));
// 到達できないページがある場合のみポップアップを表示
if (unreachablePages.length > 0) {
let resultHtml = `
<html>
<head>
<meta charset="utf-8">
<title>到達できないページ一覧</title>
</head>
<body>
<h1>索引からたどって到達できないページ一覧</h1>
<ul>
`;
unreachablePages.forEach(page => {
resultHtml += <li>${page.title}</li>;
});
resultHtml += `
</ul>
</body>
</html>
`;
const popup = window.open("", "UnreachablePages", "width=400,height=600,scrollbars=yes");
if (popup) {
popup.document.open();
popup.document.write(resultHtml);
popup.document.close();
} else {
alert("ポップアップウィンドウの表示がブロックされました。ブラウザのポップアップブロック設定を確認してください。");
}
} else {
console.log("すべてのページは索引から到達可能です。");
}
})();