/// /// import { Style } from "./deps.ts"; interface ChildStyle { [K: string]: string | number | ChildStyle; } export type AttributeSelectorOperator = "^=" | "=" | "$=" | "*=" | "~=" | "|="; export interface URLInit { url: string; /** * 属性セレクタに使用する演算子 * 指定しない場合は`^=`が用いられる */ selectorSyntax: AttributeSelectorOperator; } export interface LinkInit { url: string | URLInit | (string | URLInit)[]; style: ChildStyle; } /** * 外部リンクを区別するUserCSSを生成する関数 */ export function generateExternalLinkStyle(links: LinkInit[]): Style { const urls = getURLFromLinkInit(links); const selector = ".line span:not(.modal-image):not(.pointing-device-map) > a.link:not(.icon):not(:is(" + urls.reduce( (pre, crt) => `${pre}[href${crt.selectorSyntax}"${crt.url}"],`, "", ) + "))::after"; const style: Style = { [selector]: { "font-family": "'Font Awesome 5 Free', 'Font Awesome 5 Brands'", "font-weight": "900", "font-size": "0.8rem", "content": "'\\f35d'", "display": "inline-block", "cursor": "text", }, }; return style; } /** * 特定のリンクにアイコンをつけるUserCSSを生成する関数 */ export function generateLinkIconStyle(links: LinkInit[]): Style { const allURLs = getURLFromLinkInit(links); const baseSelector = ".line span:not(.deco-\\.) > span > a.link:is(" + allURLs.reduce( (pre, crt) => `${pre}[href${crt.selectorSyntax}"${crt.url}"],`, "", ) + ")::before"; /** 先頭にアイコンを付けるための共通のスタイル */ const baseStyle: Style = { [baseSelector]: { "display": "inline-block", "width": "1em", "height": "1em", "vertical-align": "-1px", "text-align": "center", "background-size": "contain", "background-repeat": "no-repeat", "cursor": "text", }, }; const individualStyle: Style = {}; for (const link of links) { const urls = getURLFromLinkInit([link]); const selector = ":is(.line, .line .deco) a.link:is(" + urls.reduce( (pre, crt) => `${pre}[href${crt.selectorSyntax}"${crt.url}"],`, "", ) + ")::before"; individualStyle[selector] = link.style; } return { ...baseStyle, ...individualStyle }; } /** * LinkInitの配列からURLを取り出す * @param {LinkInit[]} links 取り出し元のオブジェクト * @param {AttributeSelectorOperator} [defaultOperator="^="] selectorSyntaxが指定されていなかった際に使用するデフォルト値 * @return {URLInit[]} */ function getURLFromLinkInit( links: LinkInit[], defaultOperator: AttributeSelectorOperator = "^=", ): URLInit[] { const resultURLs: URLInit[] = []; for (const link of links) { if (Array.isArray(link.url)) { for (const url of link.url) { if (typeof url === "string") { resultURLs.push({ url: url, selectorSyntax: defaultOperator }); } else { resultURLs.push(url); } } } else { const url = link.url; if (typeof url === "string") { resultURLs.push({ url: url, selectorSyntax: defaultOperator }); } else { resultURLs.push(url); } } } return resultURLs; }