hono
Version:
Web framework built on Web Standards
118 lines (117 loc) • 3.87 kB
JavaScript
// src/helper/css/index.ts
import { raw } from "../../helper/html/index.js";
import { DOM_RENDERER } from "../../jsx/constants.js";
import { createCssJsxDomObjects } from "../../jsx/dom/css.js";
import {
CLASS_NAME,
DEFAULT_STYLE_ID,
PSEUDO_GLOBAL_SELECTOR,
SELECTOR,
SELECTORS,
STYLE_STRING,
cssCommon,
cxCommon,
keyframesCommon,
viewTransitionCommon
} from "./common.js";
import { rawCssString } from "./common.js";
var createCssContext = ({ id }) => {
const [cssJsxDomObject, StyleRenderToDom] = createCssJsxDomObjects({ id });
const contextMap = /* @__PURE__ */ new WeakMap();
const replaceStyleRe = new RegExp(`(<style id="${id}">.*?)(</style>)`);
const newCssClassNameObject = (cssClassName) => {
const appendStyle = ({ buffer, context }) => {
const [toAdd, added] = contextMap.get(context);
const names = Object.keys(toAdd);
if (!names.length) {
return;
}
let stylesStr = "";
names.forEach((className2) => {
added[className2] = true;
stylesStr += className2.startsWith(PSEUDO_GLOBAL_SELECTOR) ? toAdd[className2] : `${className2[0] === "@" ? "" : "."}${className2}{${toAdd[className2]}}`;
});
contextMap.set(context, [{}, added]);
if (buffer && replaceStyleRe.test(buffer[0])) {
buffer[0] = buffer[0].replace(replaceStyleRe, (_, pre, post) => `${pre}${stylesStr}${post}`);
return;
}
const appendStyleScript = `<script>document.querySelector('#${id}').textContent+=${JSON.stringify(
stylesStr
)}<\/script>`;
if (buffer) {
buffer[0] = `${appendStyleScript}${buffer[0]}`;
return;
}
return Promise.resolve(appendStyleScript);
};
const addClassNameToContext = ({ context }) => {
if (!contextMap.get(context)) {
contextMap.set(context, [{}, {}]);
}
const [toAdd, added] = contextMap.get(context);
let allAdded = true;
if (!added[cssClassName[SELECTOR]]) {
allAdded = false;
toAdd[cssClassName[SELECTOR]] = cssClassName[STYLE_STRING];
}
cssClassName[SELECTORS].forEach(
({ [CLASS_NAME]: className2, [STYLE_STRING]: styleString }) => {
if (!added[className2]) {
allAdded = false;
toAdd[className2] = styleString;
}
}
);
if (allAdded) {
return;
}
return Promise.resolve(raw("", [appendStyle]));
};
const className = new String(cssClassName[CLASS_NAME]);
Object.assign(className, cssClassName);
className.isEscaped = true;
className.callbacks = [addClassNameToContext];
const promise = Promise.resolve(className);
Object.assign(promise, cssClassName);
promise.toString = cssJsxDomObject.toString;
return promise;
};
const css2 = (strings, ...values) => {
return newCssClassNameObject(cssCommon(strings, values));
};
const cx2 = (...args) => {
args = cxCommon(args);
return css2(Array(args.length).fill(""), ...args);
};
const keyframes2 = keyframesCommon;
const viewTransition2 = (strings, ...values) => {
return newCssClassNameObject(viewTransitionCommon(strings, values));
};
const Style2 = ({ children } = {}) => children ? raw(`<style id="${id}">${children[STYLE_STRING]}</style>`) : raw(`<style id="${id}"></style>`);
Style2[DOM_RENDERER] = StyleRenderToDom;
return {
css: css2,
cx: cx2,
keyframes: keyframes2,
viewTransition: viewTransition2,
Style: Style2
};
};
var defaultContext = createCssContext({
id: DEFAULT_STYLE_ID
});
var css = defaultContext.css;
var cx = defaultContext.cx;
var keyframes = defaultContext.keyframes;
var viewTransition = defaultContext.viewTransition;
var Style = defaultContext.Style;
export {
Style,
createCssContext,
css,
cx,
keyframes,
rawCssString,
viewTransition
};