@hyperframes/core 0.8.142 → 0.8.144
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/dist/beats/beatFile.d.ts +1 -1
- package/dist/beats/beatFile.d.ts.map +1 -1
- package/dist/beats/beatFile.js +11 -10
- package/dist/beats/beatFile.js.map +1 -1
- package/dist/compiler/compositionAssembly.d.ts +7 -2
- package/dist/compiler/compositionAssembly.d.ts.map +1 -1
- package/dist/compiler/compositionAssembly.js +53 -5
- package/dist/compiler/compositionAssembly.js.map +1 -1
- package/dist/compiler/htmlBundler.d.ts +1 -0
- package/dist/compiler/htmlBundler.d.ts.map +1 -1
- package/dist/compiler/htmlBundler.js +85 -39
- package/dist/compiler/htmlBundler.js.map +1 -1
- package/dist/compiler/htmlCompiler.d.ts.map +1 -1
- package/dist/compiler/htmlCompiler.js +7 -1
- package/dist/compiler/htmlCompiler.js.map +1 -1
- package/dist/compiler/index.d.ts +3 -2
- package/dist/compiler/index.d.ts.map +1 -1
- package/dist/compiler/index.js +3 -2
- package/dist/compiler/index.js.map +1 -1
- package/dist/compiler/inlineSubCompositions.js +5 -3
- package/dist/compiler/inlineSubCompositions.js.map +1 -1
- package/dist/compiler/scriptRuns.d.ts +0 -1
- package/dist/compiler/scriptRuns.d.ts.map +1 -1
- package/dist/compiler/scriptRuns.js +1 -23
- package/dist/compiler/scriptRuns.js.map +1 -1
- package/dist/compiler/timingCompiler.d.ts +1 -1
- package/dist/compiler/timingCompiler.d.ts.map +1 -1
- package/dist/compiler/timingCompiler.js +57 -128
- package/dist/compiler/timingCompiler.js.map +1 -1
- package/dist/generated/runtime-inline.js +1 -1
- package/dist/generated/runtime-inline.js.map +1 -1
- package/dist/hyperframe.runtime.iife.js +56 -56
- package/dist/media/gif.d.ts.map +1 -1
- package/dist/media/gif.js +7 -2
- package/dist/media/gif.js.map +1 -1
- package/dist/runtime/compositionLength.d.ts +3 -2
- package/dist/runtime/compositionLength.d.ts.map +1 -1
- package/dist/runtime/compositionLength.js +11 -5
- package/dist/runtime/compositionLength.js.map +1 -1
- package/dist/runtime/stackingContext.d.ts.map +1 -1
- package/dist/runtime/stackingContext.js +3 -0
- package/dist/runtime/stackingContext.js.map +1 -1
- package/dist/runtime/timeline.d.ts +0 -4
- package/dist/runtime/timeline.d.ts.map +1 -1
- package/dist/runtime/timeline.js +1 -4
- package/dist/runtime/timeline.js.map +1 -1
- package/dist/studioPreviewMark.d.ts +2 -0
- package/dist/studioPreviewMark.d.ts.map +1 -1
- package/dist/studioPreviewMark.js +6 -0
- package/dist/studioPreviewMark.js.map +1 -1
- package/dist/text/fitTextFontSize.d.ts.map +1 -1
- package/dist/text/fitTextFontSize.js +3 -1
- package/dist/text/fitTextFontSize.js.map +1 -1
- package/dist/timelineAssetId.d.ts.map +1 -1
- package/dist/timelineAssetId.js +3 -2
- package/dist/timelineAssetId.js.map +1 -1
- package/package.json +5 -4
package/dist/beats/beatFile.d.ts
CHANGED
|
@@ -13,7 +13,7 @@ export declare function parseBeats(content: string): {
|
|
|
13
13
|
* the FIRST `<audio>`, or `<video data-has-audio="true">` without `muted` (in
|
|
14
14
|
* document order) where data-timeline-role="music", or —
|
|
15
15
|
* when no role is set — whose id matches the music regex. An explicit non-music
|
|
16
|
-
* role excludes the element. Returns the
|
|
16
|
+
* role excludes the element. Returns the decoded src attribute, or null.
|
|
17
17
|
*/
|
|
18
18
|
export declare function findMusicAudioSrc(html: string): string | null;
|
|
19
19
|
//# sourceMappingURL=beatFile.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"beatFile.d.ts","sourceRoot":"","sources":["../../src/beats/beatFile.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"beatFile.d.ts","sourceRoot":"","sources":["../../src/beats/beatFile.ts"],"names":[],"mappings":"AAgBA,oFAAoF;AACpF,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CA8BhF;AAED,mFAAmF;AACnF,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAGhF;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAO1F;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAAC,SAAS,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG,IAAI,CAsB3F;AAoBD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAc7D"}
|
package/dist/beats/beatFile.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// Persistence for beat data: one JSON file per audio file, matched by the
|
|
2
2
|
// audio's project-relative path. Lives under `beats/` in the project so it
|
|
3
3
|
// survives the audio being removed and re-added.
|
|
4
|
+
import { decodeAuthoredAttribute, scanHtmlOpeningTags, } from "@hyperframes/parsers";
|
|
4
5
|
/** Project-relative path of the audio file behind a (possibly absolute) src URL. */
|
|
5
6
|
export function audioRelPathForSrc(src) {
|
|
6
7
|
if (!src)
|
|
@@ -79,12 +80,15 @@ export function parseBeats(content) {
|
|
|
79
80
|
}
|
|
80
81
|
const MUSIC_ID_RE = /\b(music|bgm|soundtrack|background[-_]?music)\b/i;
|
|
81
82
|
function attr(tag, name) {
|
|
82
|
-
const
|
|
83
|
-
return
|
|
83
|
+
const attribute = tag.attributes.find((value) => value.name === name);
|
|
84
|
+
return attribute?.kind === "value" ? decodeAuthoredAttribute(attribute.value) : null;
|
|
84
85
|
}
|
|
85
86
|
function isSoundingVideoTag(tag) {
|
|
86
|
-
|
|
87
|
-
|
|
87
|
+
return (attr(tag, "data-has-audio") === "true" &&
|
|
88
|
+
!tag.attributes.some((attribute) => attribute.name === "muted"));
|
|
89
|
+
}
|
|
90
|
+
function isMusicSourceTag(tag) {
|
|
91
|
+
return tag.closed && (tag.name === "audio" || (tag.name === "video" && isSoundingVideoTag(tag)));
|
|
88
92
|
}
|
|
89
93
|
/**
|
|
90
94
|
* Find the music track's src in composition HTML, applying the SAME rules as the
|
|
@@ -92,14 +96,11 @@ function isSoundingVideoTag(tag) {
|
|
|
92
96
|
* the FIRST `<audio>`, or `<video data-has-audio="true">` without `muted` (in
|
|
93
97
|
* document order) where data-timeline-role="music", or —
|
|
94
98
|
* when no role is set — whose id matches the music regex. An explicit non-music
|
|
95
|
-
* role excludes the element. Returns the
|
|
99
|
+
* role excludes the element. Returns the decoded src attribute, or null.
|
|
96
100
|
*/
|
|
97
101
|
export function findMusicAudioSrc(html) {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
const tags = html.match(/<(?:audio|video)\b[^>]*>/gi) ?? [];
|
|
101
|
-
for (const tag of tags) {
|
|
102
|
-
if (/^<video/i.test(tag) && !isSoundingVideoTag(tag))
|
|
102
|
+
for (const tag of scanHtmlOpeningTags(html)) {
|
|
103
|
+
if (!isMusicSourceTag(tag))
|
|
103
104
|
continue;
|
|
104
105
|
const src = attr(tag, "src");
|
|
105
106
|
if (!src)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"beatFile.js","sourceRoot":"","sources":["../../src/beats/beatFile.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,2EAA2E;AAC3E,iDAAiD;
|
|
1
|
+
{"version":3,"file":"beatFile.js","sourceRoot":"","sources":["../../src/beats/beatFile.ts"],"names":[],"mappings":"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"}
|
|
@@ -20,7 +20,10 @@
|
|
|
20
20
|
* takes strings — so both a linkedom document and a live browser document
|
|
21
21
|
* satisfy it without an `as T` cast at either call site.
|
|
22
22
|
*/
|
|
23
|
-
export declare
|
|
23
|
+
export declare function isJavaScriptType(el: AssemblyAttributed): boolean;
|
|
24
|
+
export declare function executableScripts<TElement extends AssemblyAttributed>(node: AssemblyQueryable<TElement> | null | undefined): TElement[];
|
|
25
|
+
/** The styles, scripts and links both paths extract, so the mounted copy must drop them. */
|
|
26
|
+
export declare function extractedCompositionAssets<TElement extends AssemblyAttributed>(node: AssemblyQueryable<TElement>): TElement[];
|
|
24
27
|
/**
|
|
25
28
|
* The compiler's nesting cap, enforced against the ancestry chain rather than a
|
|
26
29
|
* counter so a wide tree is not penalised for a deep sibling.
|
|
@@ -102,6 +105,8 @@ export interface CompositionAssemblyPlan<TElement extends AssemblyAttributed> {
|
|
|
102
105
|
scriptSources: TElement[];
|
|
103
106
|
/** Head and content links to hoist into the host document. */
|
|
104
107
|
linkSources: TElement[];
|
|
108
|
+
/** Inert scripts the mounted root would leave behind; both paths mount them next to it. */
|
|
109
|
+
inertScriptsOutsideRoot: TElement[];
|
|
105
110
|
/**
|
|
106
111
|
* Nodes that may declare the composition's variable defaults, in precedence
|
|
107
112
|
* order — later wins. Full-document compositions declare on `<html>`;
|
|
@@ -116,7 +121,7 @@ export interface CompositionAssemblyPlan<TElement extends AssemblyAttributed> {
|
|
|
116
121
|
* how it is identified. Pure: it reads attributes and runs selectors, and does
|
|
117
122
|
* not mutate, fetch, or touch a filesystem.
|
|
118
123
|
*/
|
|
119
|
-
export declare function planCompositionAssembly<TElement extends AssemblyAttributed
|
|
124
|
+
export declare function planCompositionAssembly<TElement extends AssemblyAttributed & AssemblyQueryable<TElement>>(input: CompositionAssemblyInput<TElement>): CompositionAssemblyPlan<TElement>;
|
|
120
125
|
export type NestedHostSkipReason = "circular composition reference" | "nesting depth exceeded";
|
|
121
126
|
export interface NestedCompositionHost<TElement> {
|
|
122
127
|
host: TElement;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compositionAssembly.d.ts","sourceRoot":"","sources":["../../src/compiler/compositionAssembly.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;
|
|
1
|
+
{"version":3,"file":"compositionAssembly.d.ts","sourceRoot":"","sources":["../../src/compiler/compositionAssembly.ts"],"names":[],"mappings":"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"}
|
|
@@ -31,7 +31,53 @@ const SCRIPT_SELECTOR = "script";
|
|
|
31
31
|
* webfonts a composition's CSS depends on; preconnects are their latency hint.
|
|
32
32
|
*/
|
|
33
33
|
const HOISTED_LINK_SELECTOR = 'link[rel="stylesheet"], link[rel="preconnect"]';
|
|
34
|
-
|
|
34
|
+
// The HTML spec's JavaScript MIME type essence matches: a script with any of these types runs as classic.
|
|
35
|
+
const JAVASCRIPT_TYPES = new Set([
|
|
36
|
+
"",
|
|
37
|
+
"application/ecmascript",
|
|
38
|
+
"application/javascript",
|
|
39
|
+
"application/x-ecmascript",
|
|
40
|
+
"application/x-javascript",
|
|
41
|
+
"text/ecmascript",
|
|
42
|
+
"text/javascript",
|
|
43
|
+
"text/javascript1.0",
|
|
44
|
+
"text/javascript1.1",
|
|
45
|
+
"text/javascript1.2",
|
|
46
|
+
"text/javascript1.3",
|
|
47
|
+
"text/javascript1.4",
|
|
48
|
+
"text/javascript1.5",
|
|
49
|
+
"text/jscript",
|
|
50
|
+
"text/livescript",
|
|
51
|
+
"text/x-ecmascript",
|
|
52
|
+
"text/x-javascript",
|
|
53
|
+
]);
|
|
54
|
+
const scriptType = (el) => (el.getAttribute("type") || "").trim().toLowerCase();
|
|
55
|
+
export function isJavaScriptType(el) {
|
|
56
|
+
return JAVASCRIPT_TYPES.has(scriptType(el));
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* A data block (application/json, text/template, ...) or a classic nomodule script never runs,
|
|
60
|
+
* so it is mounted as authored.
|
|
61
|
+
*/
|
|
62
|
+
function isExecutableScript(el) {
|
|
63
|
+
const type = scriptType(el);
|
|
64
|
+
if (type === "module" || type === "importmap")
|
|
65
|
+
return true;
|
|
66
|
+
return JAVASCRIPT_TYPES.has(type) && el.getAttribute("nomodule") === null;
|
|
67
|
+
}
|
|
68
|
+
function inertScripts(node) {
|
|
69
|
+
return toArray(node?.querySelectorAll(SCRIPT_SELECTOR)).filter((el) => !isExecutableScript(el));
|
|
70
|
+
}
|
|
71
|
+
export function executableScripts(node) {
|
|
72
|
+
return toArray(node?.querySelectorAll(SCRIPT_SELECTOR)).filter(isExecutableScript);
|
|
73
|
+
}
|
|
74
|
+
/** The styles, scripts and links both paths extract, so the mounted copy must drop them. */
|
|
75
|
+
export function extractedCompositionAssets(node) {
|
|
76
|
+
return [
|
|
77
|
+
...toArray(node.querySelectorAll(`${STYLE_SELECTOR}, ${HOISTED_LINK_SELECTOR}`)),
|
|
78
|
+
...executableScripts(node),
|
|
79
|
+
];
|
|
80
|
+
}
|
|
35
81
|
/**
|
|
36
82
|
* The compiler's nesting cap, enforced against the ancestry chain rather than a
|
|
37
83
|
* counter so a wide tree is not penalised for a deep sibling.
|
|
@@ -60,6 +106,7 @@ export function planCompositionAssembly(input) {
|
|
|
60
106
|
const declaredCompositionId = (innerRoot ?? compositionRoots[0])?.getAttribute(COMPOSITION_ID_ATTR)?.trim() || "";
|
|
61
107
|
// A templated composition's <head> belongs to its host page, not to it.
|
|
62
108
|
const assetHead = hasTemplate ? null : (head ?? null);
|
|
109
|
+
const mountedInert = innerRoot ? inertScripts(innerRoot) : [];
|
|
63
110
|
return {
|
|
64
111
|
innerRoot,
|
|
65
112
|
authoredCompositionId: compositionId || declaredCompositionId || null,
|
|
@@ -69,14 +116,15 @@ export function planCompositionAssembly(input) {
|
|
|
69
116
|
...toArray(assetHead?.querySelectorAll(STYLE_SELECTOR)),
|
|
70
117
|
...toArray(contentNode.querySelectorAll(STYLE_SELECTOR)),
|
|
71
118
|
],
|
|
72
|
-
scriptSources: [
|
|
73
|
-
...toArray(assetHead?.querySelectorAll(SCRIPT_SELECTOR)),
|
|
74
|
-
...toArray(contentNode.querySelectorAll(SCRIPT_SELECTOR)),
|
|
75
|
-
],
|
|
119
|
+
scriptSources: [...executableScripts(assetHead), ...executableScripts(contentNode)],
|
|
76
120
|
linkSources: [
|
|
77
121
|
...toArray(head?.querySelectorAll(HOISTED_LINK_SELECTOR)),
|
|
78
122
|
...toArray(contentNode.querySelectorAll(HOISTED_LINK_SELECTOR)),
|
|
79
123
|
],
|
|
124
|
+
inertScriptsOutsideRoot: [
|
|
125
|
+
...inertScripts(assetHead),
|
|
126
|
+
...(innerRoot ? inertScripts(contentNode).filter((el) => !mountedInert.includes(el)) : []),
|
|
127
|
+
],
|
|
80
128
|
variableDefaultCarriers: [documentElement, innerRoot].filter((carrier) => carrier != null),
|
|
81
129
|
};
|
|
82
130
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compositionAssembly.js","sourceRoot":"","sources":["../../src/compiler/compositionAssembly.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,MAAM,mBAAmB,GAAG,qBAAqB,CAAC;AAClD,MAAM,oBAAoB,GAAG,sBAAsB,CAAC;AACpD,MAAM,yBAAyB,GAAG,IAAI,mBAAmB,GAAG,CAAC;AAC7D,MAAM,yBAAyB,GAAG,IAAI,oBAAoB,GAAG,CAAC;AAC9D,MAAM,cAAc,GAAG,OAAO,CAAC;AAC/B,MAAM,eAAe,GAAG,QAAQ,CAAC;AAEjC;;;GAGG;AACH,MAAM,qBAAqB,GAAG,gDAAgD,CAAC;AAE/E,MAAM,CAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"compositionAssembly.js","sourceRoot":"","sources":["../../src/compiler/compositionAssembly.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,6 +6,7 @@ export type BundledHostCompositionIdentity = {
|
|
|
6
6
|
};
|
|
7
7
|
export declare function assignBundledRuntimeCompositionIds(hosts: Element[], counts?: Map<string, number>): Map<Element, BundledHostCompositionIdentity>;
|
|
8
8
|
export declare function prepareFlattenedInnerRoot(innerRoot: Element): Element;
|
|
9
|
+
export declare function parsesAsScript(source: string): boolean;
|
|
9
10
|
export interface BundleOptions {
|
|
10
11
|
/** Project-relative HTML entry to bundle. Defaults to `index.html`. */
|
|
11
12
|
entryFile?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"htmlBundler.d.ts","sourceRoot":"","sources":["../../src/compiler/htmlBundler.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"htmlBundler.d.ts","sourceRoot":"","sources":["../../src/compiler/htmlBundler.ts"],"names":[],"mappings":"AAwBA,OAAO,EAAE,gCAAgC,EAAE,MAAM,0BAA0B,CAAC;AAiB5E,OAAO,EAAe,KAAK,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAqdvE,MAAM,MAAM,8BAA8B,GAAG;IAC3C,qBAAqB,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;CACrC,CAAC;AA4CF,wBAAgB,kCAAkC,CAChD,KAAK,EAAE,OAAO,EAAE,EAChB,MAAM,GAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAA6C,GACtE,GAAG,CAAC,OAAO,EAAE,8BAA8B,CAAC,CAyC9C;AAED,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,OAAO,GAAG,OAAO,CAWrE;AAsMD,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAOtD;AAgBD,MAAM,WAAW,aAAa;IAC5B,uEAAuE;IACvE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,oGAAoG;IACpG,kBAAkB,CAAC,EAAE,mBAAmB,CAAC;IACzC;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,EAAE,QAAQ,GAAG,aAAa,CAAC;IACnC;;;;OAIG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,uGAAuG;IACvG,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,kFAAkF;IAClF,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC;AA6HD,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAG/F;AAkbD;;;;;;;;;;;;GAYG;AACH,wBAAgB,iCAAiC,CAC/C,QAAQ,EAAE,QAAQ,EAClB,eAAe,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAM,EAC7D,SAAS,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACtC,OAAO,CAcT"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { compositionStyle, cssStyleMergeKey, deferScriptsUntilFonts, UNCONDITIONAL_CSS_KEY, headStyleRuns, INLINED_FILE_ATTR, inlineScriptRuns,
|
|
1
|
+
import { compositionStyle, cssStyleMergeKey, deferScriptsUntilFonts, UNCONDITIONAL_CSS_KEY, headStyleRuns, INLINED_FILE_ATTR, inlineScriptRuns, styleElementsFor, } from "./scriptRuns.js";
|
|
2
|
+
import { executableScripts, isJavaScriptType, planCompositionAssembly, } from "./compositionAssembly.js";
|
|
2
3
|
import { SCENE_PART_ATTR } from "../sceneParts.js";
|
|
3
4
|
import { ensureExternalScriptTag, readExternalScriptAttributes, } from "./externalScripts.js";
|
|
4
|
-
import { emitMountedModuleScripts } from "./importMaps.js";
|
|
5
|
+
import { emitMountedModuleScripts, parseImportMap } from "./importMaps.js";
|
|
5
6
|
import { markFlattenedInnerRoot } from "../runtime/flattenedRoot.js";
|
|
6
7
|
export { FLATTENED_INNER_ROOT_STRIP_ATTRS } from "../runtime/flattenedRoot.js";
|
|
7
8
|
import { parseHostVariableValues, warnUnknownEnumValues } from "../runtime/getVariables.js";
|
|
@@ -9,18 +10,19 @@ import { sanitizeCssValue } from "../runtime/applyVariableBindings.js";
|
|
|
9
10
|
import { cssVariableName } from "../tokenSlug.js";
|
|
10
11
|
import { AsyncLocalStorage } from "async_hooks";
|
|
11
12
|
import { readFileSync, existsSync, statSync } from "fs";
|
|
13
|
+
import { parse as parseJs } from "acorn";
|
|
12
14
|
import { resolve, relative, dirname, isAbsolute, sep } from "path";
|
|
15
|
+
import { decodeCssEscapes, decodeWellFormedEscapes, encodeUrlPath, decodedUrlPath, splitUrlSuffix, } from "@hyperframes/parsers/asset-paths";
|
|
13
16
|
import { CSS_URL_RE, isNonRelativeUrl } from "./assetPaths.js";
|
|
14
17
|
import { transformSync } from "esbuild";
|
|
15
18
|
import { compileHtml } from "./htmlCompiler.js";
|
|
16
19
|
import { RUNTIME_BOOTSTRAP_ATTR, escapeInlineScriptSource, insertRuntimeTag, parseHTMLContent, stripEmbeddedRuntimeScripts, } from "./htmlDocument.js";
|
|
17
20
|
// rewriteSubCompPaths functions are used by inlineSubCompositions (shared module)
|
|
18
|
-
import { buildVariablesByCompScript, dedupeFontFaceRules, scopeCssToComposition, wrapInlineScriptWithErrorBoundary, wrapScopedCompositionScript, } from "./compositionScoping.js";
|
|
21
|
+
import { buildVariablesByCompScript, dedupeFontFaceRules, scopeCssToComposition, wrapInlineScriptWithErrorBoundary, scopedModulePrelude, wrapScopedCompositionScript, } from "./compositionScoping.js";
|
|
19
22
|
import { validateHyperframeHtmlContract } from "./staticGuard.js";
|
|
20
23
|
import { getHyperframeRuntimeScript } from "../generated/runtime-inline.js";
|
|
21
24
|
import { readDeclaredDefaults } from "../runtime/getVariables.js";
|
|
22
25
|
import { ensureExternalLinkTag, inlineSubCompositions, refuseSwapsReachedByRootScripts, } from "./inlineSubCompositions.js";
|
|
23
|
-
import { queryByAttr } from "../utils/cssSelector.js";
|
|
24
26
|
import { isSafePath, resolveWithinProject } from "../safePath.js";
|
|
25
27
|
import { ensureHfIds } from "@hyperframes/parsers/hf-ids";
|
|
26
28
|
import { HF_COLOR_GRADING_ATTR } from "../colorGrading.js";
|
|
@@ -90,30 +92,35 @@ function withCommentsStripped(css, fn) {
|
|
|
90
92
|
};
|
|
91
93
|
return { result, restore };
|
|
92
94
|
}
|
|
95
|
+
function resolveRelativeUrlPath(fromDir, basePath) {
|
|
96
|
+
return resolve(fromDir, decodeWellFormedEscapes(basePath.replaceAll("\\", "/")));
|
|
97
|
+
}
|
|
93
98
|
function rebaseCssUrls(css, cssFileDir, projectDir) {
|
|
94
99
|
const resolvedRoot = resolve(projectDir);
|
|
95
100
|
const resolvedDir = resolve(cssFileDir);
|
|
96
101
|
if (resolvedDir === resolvedRoot)
|
|
97
102
|
return css;
|
|
98
103
|
return css.replace(CSS_URL_RE, (full, quote, urlValue) => {
|
|
99
|
-
|
|
104
|
+
const decoded = decodeCssEscapes(urlValue);
|
|
105
|
+
if (!decoded || !isRelativeUrl(decoded))
|
|
100
106
|
return full;
|
|
101
|
-
const { basePath, suffix } = splitUrlSuffix(
|
|
107
|
+
const { basePath, suffix } = splitUrlSuffix(decoded);
|
|
102
108
|
if (!basePath)
|
|
103
109
|
return full;
|
|
104
|
-
const absolutePath =
|
|
105
|
-
const rebased = relative(resolvedRoot, absolutePath).split(sep).join("/");
|
|
110
|
+
const absolutePath = resolveRelativeUrlPath(resolvedDir, basePath);
|
|
111
|
+
const rebased = encodeUrlPath(relative(resolvedRoot, absolutePath).split(sep).join("/"));
|
|
106
112
|
if (rebased === basePath)
|
|
107
113
|
return full;
|
|
108
|
-
|
|
114
|
+
const escapedSuffix = suffix.replace(/[\s\p{Cc}"'()\\<>]/gu, (char) => `\\${char.codePointAt(0).toString(16).padStart(6, "0")}`);
|
|
115
|
+
return `url(${quote || ""}${rebased}${escapedSuffix}${quote || ""})`;
|
|
109
116
|
});
|
|
110
117
|
}
|
|
111
118
|
function rebaseRelativePath(urlValue, fromDir, toDir) {
|
|
112
119
|
const { basePath, suffix } = splitUrlSuffix(urlValue.trim());
|
|
113
120
|
if (!basePath)
|
|
114
121
|
return urlValue;
|
|
115
|
-
const absolutePath =
|
|
116
|
-
const rebased = relative(resolve(toDir), absolutePath).split(sep).join("/");
|
|
122
|
+
const absolutePath = resolveRelativeUrlPath(fromDir, basePath);
|
|
123
|
+
const rebased = encodeUrlPath(relative(resolve(toDir), absolutePath).split(sep).join("/"));
|
|
117
124
|
return appendSuffixToUrl(rebased, suffix);
|
|
118
125
|
}
|
|
119
126
|
function rebaseSrcsetPaths(srcsetValue, fromDir, toDir) {
|
|
@@ -200,7 +207,7 @@ function inlineCssFile(css, cssFileDir, projectDir, visited = new Set()) {
|
|
|
200
207
|
const importPath = urlPath ?? barePath;
|
|
201
208
|
if (!importPath || !isRelativeUrl(importPath))
|
|
202
209
|
return full;
|
|
203
|
-
const resolved = resolve(cssFileDir, importPath);
|
|
210
|
+
const resolved = resolve(cssFileDir, decodedUrlPath(importPath));
|
|
204
211
|
// @import is resolved relative to the CSS file, but must stay within the
|
|
205
212
|
// project root; isSafePath also blocks symlink escapes (content is inlined).
|
|
206
213
|
if (!isSafePath(projectDir, resolved))
|
|
@@ -236,14 +243,6 @@ function safeReadFileBuffer(filePath) {
|
|
|
236
243
|
return null;
|
|
237
244
|
}
|
|
238
245
|
}
|
|
239
|
-
function splitUrlSuffix(urlValue) {
|
|
240
|
-
const queryIdx = urlValue.indexOf("?");
|
|
241
|
-
const hashIdx = urlValue.indexOf("#");
|
|
242
|
-
if (queryIdx < 0 && hashIdx < 0)
|
|
243
|
-
return { basePath: urlValue, suffix: "" };
|
|
244
|
-
const cutIdx = queryIdx < 0 ? hashIdx : hashIdx < 0 ? queryIdx : Math.min(queryIdx, hashIdx);
|
|
245
|
-
return { basePath: urlValue.slice(0, cutIdx), suffix: urlValue.slice(cutIdx) };
|
|
246
|
-
}
|
|
247
246
|
function appendSuffixToUrl(baseUrl, suffix) {
|
|
248
247
|
if (!suffix)
|
|
249
248
|
return baseUrl;
|
|
@@ -320,7 +319,7 @@ function maybeInlineRelativeAssetUrl(urlValue, projectDir, inlineAssets) {
|
|
|
320
319
|
const { basePath, suffix } = splitUrlSuffix(urlValue.trim());
|
|
321
320
|
if (!basePath)
|
|
322
321
|
return null;
|
|
323
|
-
const filePath = resolveWithinProject(projectDir, basePath);
|
|
322
|
+
const filePath = resolveWithinProject(projectDir, decodeWellFormedEscapes(basePath));
|
|
324
323
|
if (!filePath)
|
|
325
324
|
return null;
|
|
326
325
|
const ext = filePath.toLowerCase().match(/\.[^.]+$/)?.[0] ?? "";
|
|
@@ -666,12 +665,17 @@ function coalesceHeadStylesAndBodyScripts(document) {
|
|
|
666
665
|
const isPinned = (el) => el.hasAttribute(RUNTIME_BOOTSTRAP_ATTR) || el.hasAttribute(SCENE_PART_ATTR);
|
|
667
666
|
for (const { members, anchor } of inlineScriptRuns([...document.querySelectorAll("body script")], isPinned)) {
|
|
668
667
|
const mergedJs = joinJsChunks(members.map((el) => el.textContent || ""));
|
|
668
|
+
if (mergedJs && !parsesAsScript(mergedJs)) {
|
|
669
|
+
for (const el of members)
|
|
670
|
+
el.textContent = inlineScriptSource(el.textContent || "");
|
|
671
|
+
continue;
|
|
672
|
+
}
|
|
669
673
|
for (const el of members)
|
|
670
674
|
el.remove();
|
|
671
675
|
if (!mergedJs)
|
|
672
676
|
continue;
|
|
673
677
|
const inlineScript = document.createElement("script");
|
|
674
|
-
inlineScript.textContent =
|
|
678
|
+
inlineScript.textContent = inlineScriptSource(mergedJs);
|
|
675
679
|
if (anchor)
|
|
676
680
|
anchor.before(inlineScript);
|
|
677
681
|
else
|
|
@@ -723,6 +727,17 @@ function joinJsChunks(chunks) {
|
|
|
723
727
|
.map((chunk) => (chunk.endsWith(";") ? chunk : chunk + "\n;"))
|
|
724
728
|
.join("\n");
|
|
725
729
|
}
|
|
730
|
+
// acorn in script mode, not the host engine: Bun 1.3's vm.Script compiles lazily and accepts anything.
|
|
731
|
+
// esbuild accepts export, top-level await and return, which a <script> rejects; acorn does not.
|
|
732
|
+
export function parsesAsScript(source) {
|
|
733
|
+
try {
|
|
734
|
+
parseJs(source, { ecmaVersion: "latest", sourceType: "script" });
|
|
735
|
+
return true;
|
|
736
|
+
}
|
|
737
|
+
catch {
|
|
738
|
+
return false;
|
|
739
|
+
}
|
|
740
|
+
}
|
|
726
741
|
function stripJsCommentsParserSafe(source) {
|
|
727
742
|
if (!source)
|
|
728
743
|
return source;
|
|
@@ -734,6 +749,9 @@ function stripJsCommentsParserSafe(source) {
|
|
|
734
749
|
return source;
|
|
735
750
|
}
|
|
736
751
|
}
|
|
752
|
+
function inlineScriptSource(js) {
|
|
753
|
+
return escapeInlineScriptSource(stripJsCommentsParserSafe(js));
|
|
754
|
+
}
|
|
737
755
|
function preserveLocalScriptIntegrity(doc, src, resolvePath) {
|
|
738
756
|
const path = resolvePath(src);
|
|
739
757
|
if (!path)
|
|
@@ -758,10 +776,10 @@ function hoistExternalScript(src, projectDir, doc, seenSrcs, chunks, attributes)
|
|
|
758
776
|
return;
|
|
759
777
|
seenSrcs.add(src);
|
|
760
778
|
if (!isNonRelativeUrl(src) && !isAbsolute(src) && attributes.type !== "module") {
|
|
761
|
-
const jsPath = resolveWithinProject(projectDir, src);
|
|
779
|
+
const jsPath = resolveWithinProject(projectDir, decodedUrlPath(src));
|
|
762
780
|
const js = jsPath ? safeReadFile(jsPath) : null;
|
|
763
781
|
if (js != null) {
|
|
764
|
-
chunks.push(() => preserveLocalScriptIntegrity(doc, src, (value) => resolveWithinProject(projectDir, value))
|
|
782
|
+
chunks.push(() => preserveLocalScriptIntegrity(doc, src, (value) => resolveWithinProject(projectDir, decodedUrlPath(value)))
|
|
765
783
|
? ""
|
|
766
784
|
: js);
|
|
767
785
|
return;
|
|
@@ -770,9 +788,21 @@ function hoistExternalScript(src, projectDir, doc, seenSrcs, chunks, attributes)
|
|
|
770
788
|
ensureExternalScriptTag(doc, src, attributes);
|
|
771
789
|
}
|
|
772
790
|
function hoistCompositionScripts(container, opts) {
|
|
773
|
-
for (const scriptEl of
|
|
791
|
+
for (const scriptEl of executableScripts(container)) {
|
|
774
792
|
const externalSrc = (scriptEl.getAttribute("src") || "").trim();
|
|
775
|
-
|
|
793
|
+
const type = (scriptEl.getAttribute("type") || "").trim().toLowerCase();
|
|
794
|
+
if (!externalSrc && type === "importmap") {
|
|
795
|
+
const map = parseImportMap(scriptEl.textContent || "", (url) => url);
|
|
796
|
+
if (map)
|
|
797
|
+
opts.importMaps.push(map);
|
|
798
|
+
else
|
|
799
|
+
console.warn(`[HyperFrames] ${opts.compId}: import map is not valid JSON, so it is skipped.`);
|
|
800
|
+
}
|
|
801
|
+
else if (!externalSrc && type === "module") {
|
|
802
|
+
const prelude = opts.compId ? scopedModulePrelude(opts.runtimeCompId || opts.compId) : "";
|
|
803
|
+
opts.moduleScripts.push(prelude + (scriptEl.textContent || ""));
|
|
804
|
+
}
|
|
805
|
+
else if (externalSrc) {
|
|
776
806
|
hoistExternalScript(externalSrc, opts.projectDir, opts.document, opts.seenCompScriptSrcs, opts.compScriptChunks, readExternalScriptAttributes(scriptEl));
|
|
777
807
|
}
|
|
778
808
|
else {
|
|
@@ -798,6 +828,7 @@ async function bundleProject(projectDir, options) {
|
|
|
798
828
|
const resolved = resolve(sourceDir, relativePath);
|
|
799
829
|
return isSafePath(projectDir, resolved) ? resolved : null;
|
|
800
830
|
};
|
|
831
|
+
const resolveEntryUrl = (url) => resolveEntryPath(decodedUrlPath(url));
|
|
801
832
|
const readSource = options?.stampHfIds ? ensureHfIds : (html) => html;
|
|
802
833
|
noteRead(indexPath);
|
|
803
834
|
const rawHtml = readSource(readFileSync(indexPath, "utf-8"));
|
|
@@ -819,7 +850,7 @@ async function bundleProject(projectDir, options) {
|
|
|
819
850
|
continue;
|
|
820
851
|
if (el.hasAttribute("disabled"))
|
|
821
852
|
continue;
|
|
822
|
-
const cssPath =
|
|
853
|
+
const cssPath = resolveEntryUrl(href);
|
|
823
854
|
if (!cssPath)
|
|
824
855
|
continue;
|
|
825
856
|
const css = safeReadFile(cssPath);
|
|
@@ -843,7 +874,7 @@ async function bundleProject(projectDir, options) {
|
|
|
843
874
|
]),
|
|
844
875
|
].map((el) => {
|
|
845
876
|
const src = el.getAttribute("src");
|
|
846
|
-
const path = src && isRelativeUrl(src) ?
|
|
877
|
+
const path = src && isRelativeUrl(src) ? resolveEntryUrl(src) : null;
|
|
847
878
|
return src ? (path && safeReadFile(path)) || "" : el.textContent || "";
|
|
848
879
|
})
|
|
849
880
|
: [];
|
|
@@ -907,10 +938,10 @@ async function bundleProject(projectDir, options) {
|
|
|
907
938
|
continue;
|
|
908
939
|
seenCompScriptSrcs.add(extSrc);
|
|
909
940
|
if (isRelativeUrl(extSrc) && scriptItem.type !== "module") {
|
|
910
|
-
const jsPath =
|
|
941
|
+
const jsPath = resolveEntryUrl(extSrc);
|
|
911
942
|
const js = jsPath ? safeReadFile(jsPath) : null;
|
|
912
943
|
if (js != null) {
|
|
913
|
-
const chunk = () => preserveLocalScriptIntegrity(document, extSrc,
|
|
944
|
+
const chunk = () => preserveLocalScriptIntegrity(document, extSrc, resolveEntryUrl) ? "" : js;
|
|
914
945
|
pushRun(scriptRuns, scriptItem.scene, chunk);
|
|
915
946
|
continue;
|
|
916
947
|
}
|
|
@@ -937,8 +968,12 @@ async function bundleProject(projectDir, options) {
|
|
|
937
968
|
const hostIdentity = hostIdentityByElement.get(host);
|
|
938
969
|
const runtimeCompId = hostIdentity?.runtimeCompositionId || compId;
|
|
939
970
|
const innerDoc = parseHTMLContent(templateHtml);
|
|
940
|
-
const
|
|
941
|
-
|
|
971
|
+
const plan = planCompositionAssembly({
|
|
972
|
+
contentNode: innerDoc,
|
|
973
|
+
hasTemplate: true,
|
|
974
|
+
compositionId: compId,
|
|
975
|
+
});
|
|
976
|
+
const { innerRoot, authoredRootId } = plan;
|
|
942
977
|
const runtimeScope = runtimeCompId
|
|
943
978
|
? cssAttributeSelector("data-composition-id", runtimeCompId)
|
|
944
979
|
: "";
|
|
@@ -976,6 +1011,8 @@ async function bundleProject(projectDir, options) {
|
|
|
976
1011
|
authoredRootId: authoredRootId ?? undefined,
|
|
977
1012
|
seenCompScriptSrcs,
|
|
978
1013
|
compScriptChunks,
|
|
1014
|
+
importMaps: subCompResult.importMaps,
|
|
1015
|
+
moduleScripts: subCompResult.moduleScripts,
|
|
979
1016
|
});
|
|
980
1017
|
// Copy dimension attributes from inner root to host if not already set
|
|
981
1018
|
const innerW = innerRoot.getAttribute("data-width");
|
|
@@ -1009,9 +1046,13 @@ async function bundleProject(projectDir, options) {
|
|
|
1009
1046
|
authoredRootId: undefined,
|
|
1010
1047
|
seenCompScriptSrcs,
|
|
1011
1048
|
compScriptChunks,
|
|
1049
|
+
importMaps: subCompResult.importMaps,
|
|
1050
|
+
moduleScripts: subCompResult.moduleScripts,
|
|
1012
1051
|
});
|
|
1013
1052
|
host.innerHTML = innerDoc.body.innerHTML || "";
|
|
1014
1053
|
}
|
|
1054
|
+
for (const el of plan.inertScriptsOutsideRoot)
|
|
1055
|
+
host.insertAdjacentHTML("beforeend", el.outerHTML);
|
|
1015
1056
|
}
|
|
1016
1057
|
// Remove the template element from the document
|
|
1017
1058
|
templateEl.remove();
|
|
@@ -1020,14 +1061,14 @@ async function bundleProject(projectDir, options) {
|
|
|
1020
1061
|
const src = el.getAttribute("src");
|
|
1021
1062
|
if (!src || !isRelativeUrl(src))
|
|
1022
1063
|
continue;
|
|
1023
|
-
if (preserveLocalScriptIntegrity(document, src,
|
|
1064
|
+
if (preserveLocalScriptIntegrity(document, src, resolveEntryUrl))
|
|
1024
1065
|
continue;
|
|
1025
1066
|
// Module scripts can contain static imports whose resolution is relative
|
|
1026
1067
|
// to the script URL. Folding their source into a classic inline script
|
|
1027
1068
|
// both drops module semantics and changes the import base URL.
|
|
1028
1069
|
if ((el.getAttribute("type") || "").trim().toLowerCase() === "module")
|
|
1029
1070
|
continue;
|
|
1030
|
-
const jsPath =
|
|
1071
|
+
const jsPath = resolveEntryUrl(src);
|
|
1031
1072
|
const js = jsPath ? safeReadFile(jsPath) : null;
|
|
1032
1073
|
if (js == null)
|
|
1033
1074
|
continue;
|
|
@@ -1057,11 +1098,16 @@ async function bundleProject(projectDir, options) {
|
|
|
1057
1098
|
}
|
|
1058
1099
|
}
|
|
1059
1100
|
for (const { scene, chunks } of scriptRuns) {
|
|
1060
|
-
const
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1101
|
+
const texts = chunks.map((chunk) => (typeof chunk === "string" ? chunk : chunk()));
|
|
1102
|
+
const joined = joinJsChunks(texts);
|
|
1103
|
+
const skipsRunMerge = Boolean(scene);
|
|
1104
|
+
for (const text of parsesAsScript(joined) ? [joined] : texts.filter(Boolean)) {
|
|
1105
|
+
const script = document.createElement("script");
|
|
1106
|
+
if (scene)
|
|
1107
|
+
script.setAttribute(SCENE_PART_ATTR, scene);
|
|
1108
|
+
script.textContent = skipsRunMerge ? inlineScriptSource(text) : text;
|
|
1109
|
+
document.body.appendChild(script);
|
|
1110
|
+
}
|
|
1065
1111
|
}
|
|
1066
1112
|
emitMountedModuleScripts(document, subCompResult.importMaps, subCompResult.moduleScripts);
|
|
1067
1113
|
emitRootCompositionVariableStyles(document, compVariablesByComp);
|