/// /// /// import { caret, insertText } from "../scrapbox-userscript-std/dom.ts"; import type { Scrapbox } from "https://raw.githubusercontent.com/scrapbox-jp/types/0.0.8/mod.ts"; declare const scrapbox: Scrapbox; const userscriptId = "mobile-decorate-page-menu"; const dummyImage = "/assets/img/favicon/apple-touch-icon.png"; export interface Init { id?: string; decorates?: Decorate[]; } export interface Decorate { title: string; titleStyle?: string; icon?: string; onClick: ( text: string, ) => (Promise | string | undefined); } export function mount(init?: Init) { const id = (init?.id ?? userscriptId).replaceAll(" ", "_"); const decorates = init?.decorates ?? defaultDecorates; const selector = `head style[data-userscript-name="${id}"]`; document.querySelector(selector)?.remove?.(); const style = document.createElement("style"); style.dataset.userscriptName = id; style.textContent = `a#${id}.tool-btn:hover { text-decoration: none; } a#${id}.tool-btn::before { position: absolute; content: "\\f591"; font: 900 20px/46px "Font Awesome 5 Free"; } a#${id}.tool-btn img { opacity: 0; } a#${id}.tool-btn ~ ul a::before { position: absolute; font-family: "Font Awesome 5 Free"; font-weight: 900; } a#${id}.tool-btn ~ ul img { opacity: 0; margin-right: 0; }`; document.head.append(style); if (!document.getElementById(id)) { scrapbox.PageMenu.addMenu({ title: id, image: dummyImage, }); } scrapbox.PageMenu(id).removeAllItems(); let counter = 0; for (const { title, titleStyle, icon, onClick } of decorates) { counter++; scrapbox.PageMenu(id).addItem({ title, ...(icon ? { image: dummyImage } : {}), onClick: async () => { const { selectedText } = caret(); if (selectedText === "") return; const result = onClick(selectedText); const text = result instanceof Promise ? await result : result; if (text === undefined) return; if (text === selectedText) return; await insertText(text); }, }); if (titleStyle) { style.textContent += `a#${id}.tool-btn ~ ul li:nth-of-type(${counter}) a { ${titleStyle} }\n`; } if (!icon) continue; style.textContent += `a#${id}.tool-btn ~ ul li:nth-of-type(${counter}) a::before { content:"${icon}"; }\n`; } } export const defaultDecorates: Decorate[] = [ { title: "Strong", titleStyle: "font-weight: bold;", icon: "\\f032", onClick: (text) => `[* ${text}]`, }, { title: "Italic", titleStyle: "font-style: italic;", icon: "\\f033", onClick: (text) => `[/ ${text}]`, }, { title: "Strike", titleStyle: "text-decoration-line: line-through;", icon: "\\f0cc", onClick: (text) => `[- ${text}]`, }, { title: "Underline", titleStyle: "text-decoration-line: underline;", icon: "\\f0cd", onClick: (text) => `[_ ${text}]`, }, { title: "Marker", titleStyle: "font-weight: bold;", icon: "\\f5a1", onClick: (text) => `[[${text}]]`, }, ];