@codepress/design-kit 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -1
- package/package.json +1 -1
- package/src/kit.mjs +54 -7
package/README.md
CHANGED
|
@@ -463,7 +463,11 @@ by id, title, component and source file only.
|
|
|
463
463
|
`compose` writes one self-contained page: the frame's markup with slots
|
|
464
464
|
filled and every `<kit-snippet id="…">` expanded, its CSS inlined, every
|
|
465
465
|
relative `url()` that names a file in the kit (fonts included) as a data URI,
|
|
466
|
-
and `data-kit-sha`/`data-kit-id` on `<html>`.
|
|
466
|
+
and `data-kit-sha`/`data-kit-id` on `<html>`. Each expanded snippet's
|
|
467
|
+
top-level elements carry `data-kit-snippet="<id>"`, and a
|
|
468
|
+
`<meta name="design-kit-usage">` in the head holds a JSON record of the kit sha,
|
|
469
|
+
the frame, the snippet ids and how many `data-kit-new` elements the page has.
|
|
470
|
+
The record stays in the page: `kit.mjs` makes no network call. Scripts, event handlers,
|
|
467
471
|
`<link>`s and SVG animation are removed, and URLs pass an allowlist: only
|
|
468
472
|
relative references, fragments and `data:` survive, read the way the browser
|
|
469
473
|
reads them. `--theme dark` applies the manifest's theme. Elements marked
|
package/package.json
CHANGED
package/src/kit.mjs
CHANGED
|
@@ -711,7 +711,30 @@ export function inlineAssets(kit, css, cssDir = join(kit.dir, "css")) {
|
|
|
711
711
|
|
|
712
712
|
// ── compose ─────────────────────────────────────────────────────────────────
|
|
713
713
|
|
|
714
|
-
|
|
714
|
+
/**
|
|
715
|
+
* `data-kit-snippet="<id>"` on each top-level element of a snippet's markup,
|
|
716
|
+
* so the composed page records which real piece every part came from. A
|
|
717
|
+
* nested `<kit-snippet>` at the top is left alone: its own expansion stamps
|
|
718
|
+
* the elements that replace it.
|
|
719
|
+
*/
|
|
720
|
+
function stampSnippetRoots(html, id) {
|
|
721
|
+
const roots = elements(html).filter(
|
|
722
|
+
(e) =>
|
|
723
|
+
e.depth === 0 &&
|
|
724
|
+
e.name !== "kit-snippet" &&
|
|
725
|
+
!("data-kit-snippet" in e.attrs),
|
|
726
|
+
);
|
|
727
|
+
let out = "";
|
|
728
|
+
let i = 0;
|
|
729
|
+
for (const root of roots) {
|
|
730
|
+
const at = root.start + 1 + root.name.length;
|
|
731
|
+
out += `${html.slice(i, at)} data-kit-snippet="${escapeAttr(id)}"`;
|
|
732
|
+
i = at;
|
|
733
|
+
}
|
|
734
|
+
return out + html.slice(i);
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
function expandSnippets(kit, html, used, budget, depth = 0, ids = []) {
|
|
715
738
|
const found = elements(html).filter((e) => e.name === "kit-snippet");
|
|
716
739
|
if (!found.length) return html;
|
|
717
740
|
if (depth >= SNIPPET_DEPTH) {
|
|
@@ -735,9 +758,17 @@ function expandSnippets(kit, html, used, budget, depth = 0) {
|
|
|
735
758
|
);
|
|
736
759
|
}
|
|
737
760
|
if (rowSource(row) === "stories") markup = unwrapStoryRoot(markup);
|
|
761
|
+
if (!ids.includes(row.id)) ids.push(row.id);
|
|
738
762
|
out +=
|
|
739
763
|
html.slice(i, element.start) +
|
|
740
|
-
expandSnippets(
|
|
764
|
+
expandSnippets(
|
|
765
|
+
kit,
|
|
766
|
+
stampSnippetRoots(markup, row.id),
|
|
767
|
+
used,
|
|
768
|
+
budget,
|
|
769
|
+
depth + 1,
|
|
770
|
+
ids,
|
|
771
|
+
);
|
|
741
772
|
i = element.end;
|
|
742
773
|
}
|
|
743
774
|
return out + html.slice(i);
|
|
@@ -874,10 +905,17 @@ export function compose(
|
|
|
874
905
|
}
|
|
875
906
|
const used = new Set([rowCssFile(kit, row)]);
|
|
876
907
|
const filled = fillSlots(kit, row, readSnippet(kit, row), slots);
|
|
877
|
-
const
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
908
|
+
const snippetIds = [];
|
|
909
|
+
const body = sanitizeMarkup(
|
|
910
|
+
expandSnippets(
|
|
911
|
+
kit,
|
|
912
|
+
filled,
|
|
913
|
+
used,
|
|
914
|
+
{ left: maxBytes - filled.length, max: maxBytes },
|
|
915
|
+
0,
|
|
916
|
+
snippetIds,
|
|
917
|
+
),
|
|
918
|
+
);
|
|
881
919
|
|
|
882
920
|
// Stories' sheet first, then the route sheets, as before page sources.
|
|
883
921
|
const storiesCss = cssFile(kit, "stories");
|
|
@@ -912,18 +950,27 @@ export function compose(
|
|
|
912
950
|
"body",
|
|
913
951
|
{},
|
|
914
952
|
);
|
|
953
|
+
// What this page used, for whoever wants to count it later. Recorded in
|
|
954
|
+
// the page only; kit.mjs never sends it anywhere.
|
|
955
|
+
const usage = {
|
|
956
|
+
kit_sha: sha,
|
|
957
|
+
frame,
|
|
958
|
+
snippets: snippetIds,
|
|
959
|
+
new_parts: elements(body).filter((e) => "data-kit-new" in e.attrs).length,
|
|
960
|
+
};
|
|
915
961
|
const page = `<!doctype html>
|
|
916
962
|
<html${htmlAttrs}>
|
|
917
963
|
<head>
|
|
918
964
|
<meta charset="utf-8">
|
|
919
965
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
966
|
+
<meta name="design-kit-usage" content="${escapeAttr(JSON.stringify(usage))}">
|
|
920
967
|
<title>${escapeAttr(row.title ?? frame)}</title>
|
|
921
968
|
<style>
|
|
922
969
|
${sanitizeCss(css)}${showNewCss}
|
|
923
970
|
</style>
|
|
924
971
|
</head>
|
|
925
972
|
<body${bodyAttrs}>
|
|
926
|
-
${
|
|
973
|
+
${body}
|
|
927
974
|
</body>
|
|
928
975
|
</html>
|
|
929
976
|
`;
|