他のプロジェクトにページを送るUserScript

script.jsexport const sendPage = ({image, ...rest}) => scrapbox.PageMenu.addMenu({
title: `send to ${rest.project}`,
image: image,
onClick: () => _sendPage({...rest}),
});
async function _sendPage({project, privateTag, useSendingMark, useReferenceMark}) {
const pageTitle = scrapbox.Page.title;
const ePageTitle = encodeURIComponent(scrapbox.Page.title);
const response = await fetch(`/api/pages/${scrapbox.Project.name}/${ePageTitle}`);
let json = await response.json();
// ページにprivateTagがついている場合はエラー
if (privateTag && json.links.includes(privateTag)) {
const msg = `This page contains #${privateTag}!\nAborted.`;
alert(msg);
throw new Error(msg);
}
// 送り先ページへのリンクを含む行があれば消してから送る
const len = json.lines.length; // 送り先ページへのリンクの有無の判定に使う
//json.lines = json.lines.filter(line => !line.text.includes(`[/${project}/${pageTitle}]`));
const regExp = new RegExp(`(?:sent\\sto|from)\\s\\[\\/${project}\\/${pageTitle.replace(/[.*+?^=!:${}()|[\]\/\\]/g, '\\$&')}\\]`);
json.lines = json.lines.filter(line => !regExp.test(line.text.trim()));
const jsonExport = { pages: [json] };
let formdata = new FormData();
formdata.append(
'import-file',
new Blob([JSON.stringify(jsonExport)], { type: 'application/json' })
);
await fetch(`/api/page-data/import/${project}.json`, {
method: 'POST',
headers: { 'X-CSRF-TOKEN': window._csrf },
body: formdata,
});
// 送り先ページを開く
// 送り元ページへのリンクが必要ならつける
if (useReferenceMark) {
window.open(`https://scrapbox.io/${project}/${ePageTitle}?body=${encodeURIComponent(`from [/${scrapbox.Project.name}/${pageTitle}]\n`)}`);
} else {
window.open(`https://scrapbox.io/${project}/${ePageTitle}`);
}
// 送り先ページへのリンクが必要ならつける
if (useSendingMark && len == json.lines.length) { // リンクの行を消す前と行数が同じならリンクが無いとする
window.open(`https://scrapbox.io/${scrapbox.Project.name}/${ePageTitle}?body=${encodeURIComponent(`sent to [/${project}/${pageTitle}]\n`)}`, "_self");
}
}