/** * notion-enhancer * (c) 2022 dragonwocky (https://dragonwocky.me/) * (https://notion-enhancer.github.io/) under the MIT license */ import "../vendor/twind.min.js"; import "../vendor/lucide.min.js"; import htm from "../vendor/htm.min.js"; const { readFile } = globalThis.__enhancerApi, enhancerIconColour = await readFile("/assets/colour.svg"), enhancerIconMonochrome = await readFile("/assets/monochrome.svg"); const kebabToPascalCase = (string) => string[0].toUpperCase() + string.replace(/-[a-z]/g, (match) => match.slice(1).toUpperCase()).slice(1), hToString = (type, props, ...children) => `<${type}${Object.entries(props) .map(([attr, value]) => ` ${attr}="${value}"`) .join("")}>${children .flat(Infinity) .map(([tag, attrs, children]) => hToString(tag, attrs, children)) .join("")}`; // https://gist.github.com/jennyknuth/222825e315d45a738ed9d6e04c7a88d0 const encodeSvg = (svg) => svg .replace( "/g, "%3E") .replace(/\s+/g, " "); // https://antfu.me/posts/icons-in-pure-css const presetIcons = () => ({ rules: [ [ /^i-((?:\w|-)+)(?:\?(mask|bg|auto))?$/, ([, icon, mode]) => { let svg; // manually register i-notion-enhancer: renders the colour // version by default, renders the monochrome version when // mask mode is requested via i-notion-enhancer?mask if (icon === "notion-enhancer") { svg = mode === "mask" ? enhancerIconMonochrome : enhancerIconColour; } else { icon = kebabToPascalCase(icon); if (!globalThis.lucide[icon]) return; svg = hToString(...globalThis.lucide[icon]); } const dataUri = `url("data:image/svg+xml;utf8,${encodeSvg(svg)}")`; if (mode === "auto") mode = undefined; mode ??= svg.includes("currentColor") ? "mask" : "bg"; return mode === "mask" ? { mask: `${dataUri} no-repeat`, "mask-size": "100% 100%", "background-color": "currentColor", color: "inherit", height: "1em", width: "1em", } : { background: `${dataUri} no-repeat`, "background-size": "100% 100%", "background-color": "transparent", height: "1em", width: "1em", }; }, ], ], }); const { twind } = globalThis; twind.install({ presets: [presetIcons()] }); // constructs elements via html`tagged templates` const h = (type, props, ...children) => { const elem = document.createElement(type); for (const prop in props) { if (["string", "number", "boolean"].includes(typeof props[prop])) { elem.setAttribute(prop, props[prop]); } else elem[prop] = props[prop]; } for (const child of children) elem.append(child); return elem; }, html = htm.bind(h); export { html, twind };