///
///
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;
}