fix: twind style generation in islands (#830)

Fixes #778
This commit is contained in:
Luca Casonato 2022-10-11 11:15:12 +02:00 committed by GitHub
parent 0cb05d1dac
commit 9ee03e09bb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 23 additions and 9 deletions

View File

@ -18,11 +18,15 @@ export default function(state) { hydrate(options, state); }`;
render(ctx) {
sheet.reset(undefined);
const res = ctx.render();
const cssText = [...sheet.target].join("\n");
const cssTexts = [...sheet.target];
const snapshot = sheet.reset();
const scripts = [];
let cssText: string;
if (res.requiresHydration) {
const precedences = snapshot[1];
const precedences = snapshot[1] as number[];
cssText = cssTexts.map((cssText, i) =>
`${cssText}/*${precedences[i].toString(36)}*/`
).join("\n");
const mappings: (string | [string, string])[] = [];
for (
const [key, value] of (snapshot[3] as Map<string, string>).entries()
@ -33,8 +37,9 @@ export default function(state) { hydrate(options, state); }`;
mappings.push([key, value]);
}
}
const state = [precedences, mappings];
scripts.push({ entrypoint: "main", state });
scripts.push({ entrypoint: "main", state: mappings });
} else {
cssText = cssTexts.join("\n");
}
return {
scripts,

View File

@ -1,17 +1,26 @@
import { Sheet } from "twind";
import { Options, setup, STYLE_ELEMENT_ID } from "./shared.ts";
type State = [string[], [string, string][]];
type State = [string, string][];
export default function hydrate(options: Options, state: State) {
const el = document.getElementById(STYLE_ELEMENT_ID) as HTMLStyleElement;
const rules = new Set(el.innerText.split("\n"));
const precedences = state[0];
const mappings = new Map(state[1]
.map((v) => typeof v === "string" ? [v, v] : v));
const rules = new Set<string>();
const precedences: number[] = [];
const mappings = new Map(
state.map((v) => typeof v === "string" ? [v, v] : v),
);
// deno-lint-ignore no-explicit-any
const sheetState: any[] = [precedences, rules, mappings, true];
const target = el.sheet!;
const ruleText = Array.from(target.cssRules).map((r) => r.cssText);
for (const r of ruleText) {
const m = r.lastIndexOf("/*");
const precedence = parseInt(r.slice(m + 2, -2), 36);
const rule = r.slice(0, m);
rules.add(rule);
precedences.push(precedence);
}
const sheet: Sheet = {
target,
insert: (rule, index) => target.insertRule(rule, index),