問合せ対応中のトグルボタンUserScript
#問合せ対応中というリンクを#問合せ対応完了に置き換える
https://gyazo.com/3d38fabbae2d42c125fa1c63d2bbc15f
動作確認用テキスト
確認したら、ctrl(command) + zでundoしてくださいshokai.icon
インデントされた文字装飾記法の中のhashtag
グローバル汚染しないようにスコープを作る
code:script.js
(() => {
Page menuにボタン追加
code:script.js
cosense.PageMenu.addMenu({
title: '問合せ対応中・対応完了',
icon: 'fas fa-question',
onClick: updateContactState
});
Page menuに追加したボタンを押したら呼び出される関数
code:script.js
async function updateContactState () {
if (updateAllLinksInPage({ from: '問合せ対応中', to: '問合せ対応完了' })) return;
if (updateAllLinksInPage({ from: '問合せ対応完了', to: '問合せ対応中' })) return;
}
それもなかった場合、どちらでもないページだ、と表示する
ページ内の全てのリンク記法とハッシュタグを置換する関数
返り値
1つでも置換したらtrue、置換しなければfalseを返す
code:script.js
function updateAllLinksInPage({ from, to }) {
let updated = false;
for (const index, line of cosense.Page.lines.entries()) { if (!line.nodes) continue;
const result = updateLink({ node: line.nodes, from, to });
if (result !== line.text) {
cosense.Page.updateLine(result, index);
updated = true;
}
}
return updated;
}
1行を処理する関数
code:script.js
function updateLink({ node, from, to }) {
const args = { from, to };
if (typeof node === 'string') return node;
if (Array.isArray(node)) return node.map(i => updateLink({ node: i, ...args })).join('');
switch (node.type) {
case 'link':
case 'hashTag': {
if (!node.unit.project && node.unit.page === from) {
node.unit.page = to;
}
return node.unit.whole;
}
case 'indent':
case 'quote': {
return node.unit.tag + updateLink({ node: node.children, ...args });
}
case 'deco': {
return '+ node.unit.deco + ' ' + updateLink({ node: node.children, ...args }) + '';
}
case 'strong': {
return '[+ updateLink({ node: node.children, ...args }) + ']';
}
}
return node.unit.whole;
}
node treeを再帰でたどる
リンク記法もしくはhashTagを対象に
fromをtoに置換する
node treeを文字列に戻して返す
グローバル汚染しないように作ったスコープを閉じる
code:script.js
})();