@hyperframes/core 0.7.14 → 0.7.16
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/compiler/staticGuard.js +1 -1
- package/dist/compiler/staticGuard.js.map +1 -1
- package/dist/core.types.d.ts +2 -369
- package/dist/core.types.d.ts.map +1 -1
- package/dist/core.types.js +1 -84
- package/dist/core.types.js.map +1 -1
- package/dist/generated/runtime-inline.js.map +1 -1
- package/dist/generators/hyperframes.d.ts +1 -1
- package/dist/generators/hyperframes.d.ts.map +1 -1
- package/dist/generators/hyperframes.js +1 -1
- package/dist/generators/hyperframes.js.map +1 -1
- package/dist/hyperframe.runtime.iife.js +20 -20
- package/dist/index.d.ts +5 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -4
- package/dist/index.js.map +1 -1
- package/dist/lint/index.d.ts +2 -2
- package/dist/lint/index.d.ts.map +1 -1
- package/dist/lint/index.js +2 -1
- package/dist/lint/index.js.map +1 -1
- package/dist/parsers/gsapConstants.d.ts +2 -12
- package/dist/parsers/gsapConstants.d.ts.map +1 -1
- package/dist/parsers/gsapConstants.js +2 -110
- package/dist/parsers/gsapConstants.js.map +1 -1
- package/dist/parsers/gsapParserAcorn.d.ts +2 -48
- package/dist/parsers/gsapParserAcorn.d.ts.map +1 -1
- package/dist/parsers/gsapParserAcorn.js +2 -1057
- package/dist/parsers/gsapParserAcorn.js.map +1 -1
- package/dist/parsers/gsapParserExports.d.ts +2 -20
- package/dist/parsers/gsapParserExports.d.ts.map +1 -1
- package/dist/parsers/gsapParserExports.js +2 -8
- package/dist/parsers/gsapParserExports.js.map +1 -1
- package/dist/parsers/gsapWriterAcorn.d.ts +2 -90
- package/dist/parsers/gsapWriterAcorn.d.ts.map +1 -1
- package/dist/parsers/gsapWriterAcorn.js +2 -2016
- package/dist/parsers/gsapWriterAcorn.js.map +1 -1
- package/dist/parsers/hfIds.d.ts +2 -16
- package/dist/parsers/hfIds.d.ts.map +1 -1
- package/dist/parsers/hfIds.js +2 -127
- package/dist/parsers/hfIds.js.map +1 -1
- package/dist/parsers/springEase.d.ts +2 -28
- package/dist/parsers/springEase.d.ts.map +1 -1
- package/dist/parsers/springEase.js +2 -69
- package/dist/parsers/springEase.js.map +1 -1
- package/dist/slideshow/index.d.ts +1 -0
- package/dist/slideshow/index.d.ts.map +1 -1
- package/dist/slideshow/index.js +1 -0
- package/dist/slideshow/index.js.map +1 -1
- package/dist/studio-api/helpers/draftMarkers.d.ts +2 -10
- package/dist/studio-api/helpers/draftMarkers.d.ts.map +1 -1
- package/dist/studio-api/helpers/draftMarkers.js +2 -10
- package/dist/studio-api/helpers/draftMarkers.js.map +1 -1
- package/dist/studio-api/helpers/finiteMutation.d.ts +2 -10
- package/dist/studio-api/helpers/finiteMutation.d.ts.map +1 -1
- package/dist/studio-api/helpers/finiteMutation.js +2 -20
- package/dist/studio-api/helpers/finiteMutation.js.map +1 -1
- package/dist/studio-api/helpers/manualEditsRenderScript.d.ts +2 -12
- package/dist/studio-api/helpers/manualEditsRenderScript.d.ts.map +1 -1
- package/dist/studio-api/helpers/manualEditsRenderScript.js +2 -632
- package/dist/studio-api/helpers/manualEditsRenderScript.js.map +1 -1
- package/dist/studio-api/helpers/screenshotClip.d.ts +2 -7
- package/dist/studio-api/helpers/screenshotClip.d.ts.map +1 -1
- package/dist/studio-api/helpers/screenshotClip.js +2 -21
- package/dist/studio-api/helpers/screenshotClip.js.map +1 -1
- package/dist/studio-api/helpers/studioMotionRenderScript.d.ts +2 -8
- package/dist/studio-api/helpers/studioMotionRenderScript.d.ts.map +1 -1
- package/dist/studio-api/helpers/studioMotionRenderScript.js +2 -207
- package/dist/studio-api/helpers/studioMotionRenderScript.js.map +1 -1
- package/dist/studio-api/index.d.ts +2 -9
- package/dist/studio-api/index.d.ts.map +1 -1
- package/dist/studio-api/index.js +2 -8
- package/dist/studio-api/index.js.map +1 -1
- package/package.json +16 -18
- package/dist/generated/runtime-inline.js +0 -11
- package/dist/hyperframe.manifest.json +0 -22
- package/dist/hyperframe.runtime.mjs +0 -325
- package/dist/lint/context.d.ts +0 -17
- package/dist/lint/context.d.ts.map +0 -1
- package/dist/lint/context.js +0 -37
- package/dist/lint/context.js.map +0 -1
- package/dist/lint/hyperframeLinter.d.ts +0 -14
- package/dist/lint/hyperframeLinter.d.ts.map +0 -1
- package/dist/lint/hyperframeLinter.js +0 -132
- package/dist/lint/hyperframeLinter.js.map +0 -1
- package/dist/lint/rules/adapters.d.ts +0 -3
- package/dist/lint/rules/adapters.d.ts.map +0 -1
- package/dist/lint/rules/adapters.js +0 -40
- package/dist/lint/rules/adapters.js.map +0 -1
- package/dist/lint/rules/captions.d.ts +0 -3
- package/dist/lint/rules/captions.d.ts.map +0 -1
- package/dist/lint/rules/captions.js +0 -242
- package/dist/lint/rules/captions.js.map +0 -1
- package/dist/lint/rules/composition.d.ts +0 -5
- package/dist/lint/rules/composition.d.ts.map +0 -1
- package/dist/lint/rules/composition.js +0 -694
- package/dist/lint/rules/composition.js.map +0 -1
- package/dist/lint/rules/core.d.ts +0 -3
- package/dist/lint/rules/core.d.ts.map +0 -1
- package/dist/lint/rules/core.js +0 -432
- package/dist/lint/rules/core.js.map +0 -1
- package/dist/lint/rules/fonts.d.ts +0 -3
- package/dist/lint/rules/fonts.d.ts.map +0 -1
- package/dist/lint/rules/fonts.js +0 -205
- package/dist/lint/rules/fonts.js.map +0 -1
- package/dist/lint/rules/gsap.d.ts +0 -4
- package/dist/lint/rules/gsap.d.ts.map +0 -1
- package/dist/lint/rules/gsap.js +0 -1039
- package/dist/lint/rules/gsap.js.map +0 -1
- package/dist/lint/rules/media.d.ts +0 -3
- package/dist/lint/rules/media.d.ts.map +0 -1
- package/dist/lint/rules/media.js +0 -491
- package/dist/lint/rules/media.js.map +0 -1
- package/dist/lint/rules/slideshow.d.ts +0 -4
- package/dist/lint/rules/slideshow.d.ts.map +0 -1
- package/dist/lint/rules/slideshow.js +0 -74
- package/dist/lint/rules/slideshow.js.map +0 -1
- package/dist/lint/rules/textures.d.ts +0 -3
- package/dist/lint/rules/textures.d.ts.map +0 -1
- package/dist/lint/rules/textures.js +0 -192
- package/dist/lint/rules/textures.js.map +0 -1
- package/dist/lint/types.d.ts +0 -36
- package/dist/lint/types.d.ts.map +0 -1
- package/dist/lint/types.js +0 -2
- package/dist/lint/types.js.map +0 -1
- package/dist/lint/utils.d.ts +0 -55
- package/dist/lint/utils.d.ts.map +0 -1
- package/dist/lint/utils.js +0 -264
- package/dist/lint/utils.js.map +0 -1
- package/dist/parsers/gsapInline.d.ts +0 -47
- package/dist/parsers/gsapInline.d.ts.map +0 -1
- package/dist/parsers/gsapInline.js +0 -513
- package/dist/parsers/gsapInline.js.map +0 -1
- package/dist/parsers/gsapParser.d.ts +0 -158
- package/dist/parsers/gsapParser.d.ts.map +0 -1
- package/dist/parsers/gsapParser.js +0 -2634
- package/dist/parsers/gsapParser.js.map +0 -1
- package/dist/parsers/gsapParser.test-helpers.d.ts +0 -49
- package/dist/parsers/gsapParser.test-helpers.d.ts.map +0 -1
- package/dist/parsers/gsapParser.test-helpers.js +0 -97
- package/dist/parsers/gsapParser.test-helpers.js.map +0 -1
- package/dist/parsers/gsapSerialize.d.ts +0 -191
- package/dist/parsers/gsapSerialize.d.ts.map +0 -1
- package/dist/parsers/gsapSerialize.js +0 -410
- package/dist/parsers/gsapSerialize.js.map +0 -1
- package/dist/parsers/gsapUnroll.d.ts +0 -7
- package/dist/parsers/gsapUnroll.d.ts.map +0 -1
- package/dist/parsers/gsapUnroll.js +0 -137
- package/dist/parsers/gsapUnroll.js.map +0 -1
- package/dist/parsers/htmlParser.d.ts +0 -27
- package/dist/parsers/htmlParser.d.ts.map +0 -1
- package/dist/parsers/htmlParser.js +0 -731
- package/dist/parsers/htmlParser.js.map +0 -1
- package/dist/studio-api/createStudioApi.d.ts +0 -10
- package/dist/studio-api/createStudioApi.d.ts.map +0 -1
- package/dist/studio-api/createStudioApi.js +0 -32
- package/dist/studio-api/createStudioApi.js.map +0 -1
- package/dist/studio-api/helpers/backupJournal.d.ts +0 -9
- package/dist/studio-api/helpers/backupJournal.d.ts.map +0 -1
- package/dist/studio-api/helpers/backupJournal.js +0 -81
- package/dist/studio-api/helpers/backupJournal.js.map +0 -1
- package/dist/studio-api/helpers/hfIdPersist.d.ts +0 -11
- package/dist/studio-api/helpers/hfIdPersist.d.ts.map +0 -1
- package/dist/studio-api/helpers/hfIdPersist.js +0 -39
- package/dist/studio-api/helpers/hfIdPersist.js.map +0 -1
- package/dist/studio-api/helpers/mediaValidation.d.ts +0 -20
- package/dist/studio-api/helpers/mediaValidation.d.ts.map +0 -1
- package/dist/studio-api/helpers/mediaValidation.js +0 -56
- package/dist/studio-api/helpers/mediaValidation.js.map +0 -1
- package/dist/studio-api/helpers/mime.d.ts +0 -4
- package/dist/studio-api/helpers/mime.d.ts.map +0 -1
- package/dist/studio-api/helpers/mime.js +0 -39
- package/dist/studio-api/helpers/mime.js.map +0 -1
- package/dist/studio-api/helpers/previewAdapter.d.ts +0 -43
- package/dist/studio-api/helpers/previewAdapter.d.ts.map +0 -1
- package/dist/studio-api/helpers/previewAdapter.js +0 -118
- package/dist/studio-api/helpers/previewAdapter.js.map +0 -1
- package/dist/studio-api/helpers/projectSignature.d.ts +0 -5
- package/dist/studio-api/helpers/projectSignature.d.ts.map +0 -1
- package/dist/studio-api/helpers/projectSignature.js +0 -154
- package/dist/studio-api/helpers/projectSignature.js.map +0 -1
- package/dist/studio-api/helpers/safePath.d.ts +0 -12
- package/dist/studio-api/helpers/safePath.d.ts.map +0 -1
- package/dist/studio-api/helpers/safePath.js +0 -38
- package/dist/studio-api/helpers/safePath.js.map +0 -1
- package/dist/studio-api/helpers/sourceMutation.d.ts +0 -28
- package/dist/studio-api/helpers/sourceMutation.d.ts.map +0 -1
- package/dist/studio-api/helpers/sourceMutation.js +0 -339
- package/dist/studio-api/helpers/sourceMutation.js.map +0 -1
- package/dist/studio-api/helpers/subComposition.d.ts +0 -20
- package/dist/studio-api/helpers/subComposition.d.ts.map +0 -1
- package/dist/studio-api/helpers/subComposition.js +0 -289
- package/dist/studio-api/helpers/subComposition.js.map +0 -1
- package/dist/studio-api/helpers/waveform.d.ts +0 -4
- package/dist/studio-api/helpers/waveform.d.ts.map +0 -1
- package/dist/studio-api/helpers/waveform.js +0 -80
- package/dist/studio-api/helpers/waveform.js.map +0 -1
- package/dist/studio-api/routes/files.d.ts +0 -4
- package/dist/studio-api/routes/files.d.ts.map +0 -1
- package/dist/studio-api/routes/files.js +0 -1200
- package/dist/studio-api/routes/files.js.map +0 -1
- package/dist/studio-api/routes/fonts.d.ts +0 -3
- package/dist/studio-api/routes/fonts.d.ts.map +0 -1
- package/dist/studio-api/routes/fonts.js +0 -157
- package/dist/studio-api/routes/fonts.js.map +0 -1
- package/dist/studio-api/routes/lint.d.ts +0 -4
- package/dist/studio-api/routes/lint.d.ts.map +0 -1
- package/dist/studio-api/routes/lint.js +0 -29
- package/dist/studio-api/routes/lint.js.map +0 -1
- package/dist/studio-api/routes/preview.d.ts +0 -4
- package/dist/studio-api/routes/preview.d.ts.map +0 -1
- package/dist/studio-api/routes/preview.js +0 -331
- package/dist/studio-api/routes/preview.js.map +0 -1
- package/dist/studio-api/routes/projects.d.ts +0 -4
- package/dist/studio-api/routes/projects.d.ts.map +0 -1
- package/dist/studio-api/routes/projects.js +0 -45
- package/dist/studio-api/routes/projects.js.map +0 -1
- package/dist/studio-api/routes/registry.d.ts +0 -4
- package/dist/studio-api/routes/registry.d.ts.map +0 -1
- package/dist/studio-api/routes/registry.js +0 -31
- package/dist/studio-api/routes/registry.js.map +0 -1
- package/dist/studio-api/routes/render.d.ts +0 -4
- package/dist/studio-api/routes/render.d.ts.map +0 -1
- package/dist/studio-api/routes/render.js +0 -269
- package/dist/studio-api/routes/render.js.map +0 -1
- package/dist/studio-api/routes/storyboard.d.ts +0 -4
- package/dist/studio-api/routes/storyboard.d.ts.map +0 -1
- package/dist/studio-api/routes/storyboard.js +0 -65
- package/dist/studio-api/routes/storyboard.js.map +0 -1
- package/dist/studio-api/routes/thumbnail.d.ts +0 -4
- package/dist/studio-api/routes/thumbnail.d.ts.map +0 -1
- package/dist/studio-api/routes/thumbnail.js +0 -107
- package/dist/studio-api/routes/thumbnail.js.map +0 -1
- package/dist/studio-api/routes/waveform.d.ts +0 -4
- package/dist/studio-api/routes/waveform.d.ts.map +0 -1
- package/dist/studio-api/routes/waveform.js +0 -41
- package/dist/studio-api/routes/waveform.js.map +0 -1
- package/dist/studio-api/types.d.ts +0 -120
- package/dist/studio-api/types.d.ts.map +0 -1
- package/dist/studio-api/types.js +0 -2
- package/dist/studio-api/types.js.map +0 -1
|
@@ -1,289 +0,0 @@
|
|
|
1
|
-
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
-
import { join } from "node:path";
|
|
3
|
-
import { parseHTML } from "linkedom";
|
|
4
|
-
import { rewriteAssetPaths, rewriteCssAssetUrls, rewriteInlineStyleAssetUrls, } from "../../compiler/rewriteSubCompPaths.js";
|
|
5
|
-
import { stripEmbeddedRuntimeScripts } from "../../compiler/htmlDocument.js";
|
|
6
|
-
/**
|
|
7
|
-
* Detect whether `html` is a full document (has `<html>`, `<head>`, or
|
|
8
|
-
* `<!doctype`), as opposed to a `<template>`-wrapped fragment.
|
|
9
|
-
* Anchored to start-of-string (ignoring leading whitespace) so stray
|
|
10
|
-
* occurrences inside script/template content don't false-positive.
|
|
11
|
-
*/
|
|
12
|
-
function isFullHtmlDocument(html) {
|
|
13
|
-
return /^\s*(?:<!doctype\s|<html[\s>])/i.test(html);
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* Rewrite relative asset paths in a parsed DOM tree. Shared across all
|
|
17
|
-
* three dispatch branches (template, full-doc, fragment) to avoid drift.
|
|
18
|
-
*/
|
|
19
|
-
function rewriteRelativePaths(root, compPath) {
|
|
20
|
-
rewriteAssetPaths(root.querySelectorAll("[src], [href]"), compPath, (el, attr) => el.getAttribute(attr), (el, attr, value) => el.setAttribute(attr, value));
|
|
21
|
-
rewriteInlineStyleAssetUrls(root.querySelectorAll("[style]"), compPath, (el) => el.getAttribute("style"), (el, value) => el.setAttribute("style", value));
|
|
22
|
-
for (const styleEl of root.querySelectorAll("style")) {
|
|
23
|
-
styleEl.textContent = rewriteCssAssetUrls(styleEl.textContent || "", compPath);
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* Escape a CSS identifier whose first character is a digit so it is a valid
|
|
28
|
-
* selector. A CSS ident cannot start with a digit, so it must be written as an
|
|
29
|
-
* escaped code point: `01-foo` → `\30 1-foo` (leading `0` → `\30 `, rest kept).
|
|
30
|
-
*
|
|
31
|
-
* Only the leading digit needs escaping (per CSS Syntax Level 3 §4.3.11): once
|
|
32
|
-
* the parser consumes the `\<hex> ` escape, the rest of the ident continues
|
|
33
|
-
* normally, so `123-scene` → `\31 23-scene` is valid (the `23-scene` tail is
|
|
34
|
-
* consumed as identifier continuation). The trailing space terminates the hex
|
|
35
|
-
* escape so a following hex digit isn't folded into the code point.
|
|
36
|
-
*/
|
|
37
|
-
function escapeLeadingDigitIdent(id) {
|
|
38
|
-
return `\\${id.charCodeAt(0).toString(16)} ${id.slice(1)}`;
|
|
39
|
-
}
|
|
40
|
-
const REGEXP_SPECIALS = /[.*+?^${}()|[\]\\]/g;
|
|
41
|
-
/**
|
|
42
|
-
* Fix `#<digit-leading-id>` selectors in the tree's `<style>` blocks.
|
|
43
|
-
*
|
|
44
|
-
* CSS identifiers cannot start with a digit, so an authored rule like
|
|
45
|
-
* `#01-wall-pushes-back { width: 1920px; height: 1080px; background: #F0EBDE }`
|
|
46
|
-
* is an invalid selector and the browser silently drops the WHOLE rule — taking
|
|
47
|
-
* the root's size and background with it. In a full composition the frame is
|
|
48
|
-
* stretched/painted by its `data-composition-src` host so the collapse is
|
|
49
|
-
* masked, but a standalone preview has no host: the root falls back to
|
|
50
|
-
* `height: 0` + transparent and the frame renders blank (black).
|
|
51
|
-
*
|
|
52
|
-
* Rewrite each such selector to its escaped, valid form (`#\30 1-wall-pushes-back`,
|
|
53
|
-
* which still matches `id="01-wall-pushes-back"`) so the rule applies and the
|
|
54
|
-
* whole declaration block — size, background, position, container-type — comes
|
|
55
|
-
* back. Scoped to ids that are actually present on elements in the content and
|
|
56
|
-
* matched only as `#id` not followed by another ident char, so hex colors
|
|
57
|
-
* (`#1F2BE0`) and other values are never touched (they are not element ids).
|
|
58
|
-
*/
|
|
59
|
-
function fixDigitLeadingIdSelectors(root) {
|
|
60
|
-
const digitIds = new Set();
|
|
61
|
-
for (const el of root.querySelectorAll("[id]")) {
|
|
62
|
-
const id = el.getAttribute("id");
|
|
63
|
-
if (id && /^\d/.test(id))
|
|
64
|
-
digitIds.add(id);
|
|
65
|
-
}
|
|
66
|
-
if (digitIds.size === 0)
|
|
67
|
-
return;
|
|
68
|
-
for (const styleEl of root.querySelectorAll("style")) {
|
|
69
|
-
let css = styleEl.textContent || "";
|
|
70
|
-
for (const id of digitIds) {
|
|
71
|
-
const pattern = new RegExp(`#${id.replace(REGEXP_SPECIALS, "\\$&")}(?![\\w-])`, "g");
|
|
72
|
-
css = css.replace(pattern, `#${escapeLeadingDigitIdent(id)}`);
|
|
73
|
-
}
|
|
74
|
-
styleEl.textContent = css;
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* Parse a full HTML document and extract its head elements and body
|
|
79
|
-
* content separately, so they can be reassembled into a clean standalone
|
|
80
|
-
* page without nesting `<html>` inside `<body>`.
|
|
81
|
-
*
|
|
82
|
-
* Extracts the full innerHTML of `<head>` — this preserves `<style>`,
|
|
83
|
-
* `<script>`, `<link>`, `<meta>`, and any other head-level tags the
|
|
84
|
-
* composition declares. Dropping `<link rel="stylesheet">` or `<meta>`
|
|
85
|
-
* would cause silent rendering failures for compositions that ship with
|
|
86
|
-
* external CSS or viewport-dependent meta.
|
|
87
|
-
*
|
|
88
|
-
* `<html>` and `<body>` attributes (lang, class, data-*) are extracted
|
|
89
|
-
* so callers can forward them to the assembled page.
|
|
90
|
-
*/
|
|
91
|
-
function extractFullDocumentParts(rawHtml, compPath) {
|
|
92
|
-
const { document: doc } = parseHTML(rawHtml);
|
|
93
|
-
const rewriteTargets = [doc.head, doc.body].filter(Boolean);
|
|
94
|
-
for (const target of rewriteTargets) {
|
|
95
|
-
rewriteRelativePaths(target, compPath);
|
|
96
|
-
}
|
|
97
|
-
// Run on the whole document: ids live in <body> but their rules may live in
|
|
98
|
-
// a <head> <style>, so the scope must span both.
|
|
99
|
-
fixDigitLeadingIdSelectors(doc);
|
|
100
|
-
const headContent = doc.head?.innerHTML ?? "";
|
|
101
|
-
const bodyContent = doc.body?.innerHTML ?? "";
|
|
102
|
-
const htmlEl = doc.documentElement;
|
|
103
|
-
const htmlAttrs = extractElementAttrs(htmlEl);
|
|
104
|
-
const bodyAttrs = doc.body ? extractElementAttrs(doc.body) : "";
|
|
105
|
-
return { headContent, bodyContent, htmlAttrs, bodyAttrs };
|
|
106
|
-
}
|
|
107
|
-
/**
|
|
108
|
-
* Extract the inner HTML of the composition's wrapping `<template>` element, or
|
|
109
|
-
* `null` if the source has no `<template>`.
|
|
110
|
-
*
|
|
111
|
-
* Located via the DOM rather than a regex. A greedy
|
|
112
|
-
* `/<template[^>]*>([\s\S]*)<\/template>/` can latch onto a literal
|
|
113
|
-
* `"<template>"` that appears inside an HTML comment — e.g. a head note such as
|
|
114
|
-
* "the HF runtime clones ONLY <template> contents" — and mis-slice the capture,
|
|
115
|
-
* leaving the real composition content re-wrapped in an inert `<template>` in
|
|
116
|
-
* the output. That template is never rendered by the browser, so the standalone
|
|
117
|
-
* preview has no `[data-composition-id]` element and no registered timeline, and
|
|
118
|
-
* renders blank. `querySelector("template")` only ever matches a real element
|
|
119
|
-
* node, so comment text can't fool it.
|
|
120
|
-
*/
|
|
121
|
-
function extractTemplateInnerHtml(rawComp) {
|
|
122
|
-
const { document: doc } = parseHTML(rawComp);
|
|
123
|
-
const template = doc.querySelector("template");
|
|
124
|
-
return template ? template.innerHTML : null;
|
|
125
|
-
}
|
|
126
|
-
function extractElementAttrs(el) {
|
|
127
|
-
const parts = [];
|
|
128
|
-
for (let i = 0; i < el.attributes.length; i++) {
|
|
129
|
-
const attr = el.attributes[i];
|
|
130
|
-
if (attr.value === "") {
|
|
131
|
-
parts.push(attr.name);
|
|
132
|
-
}
|
|
133
|
-
else {
|
|
134
|
-
parts.push(`${attr.name}="${attr.value}"`);
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
return parts.join(" ");
|
|
138
|
-
}
|
|
139
|
-
const NON_RENDERED_TAGS = new Set(["SCRIPT", "STYLE", "LINK", "META", "TEMPLATE", "NOSCRIPT"]);
|
|
140
|
-
/**
|
|
141
|
-
* Carry the `<template>`'s `data-composition-id` onto the content's root
|
|
142
|
-
* rendered element when the author declared it only on the `<template>` tag.
|
|
143
|
-
*
|
|
144
|
-
* In a full composition, each sub-composition is mounted under a wrapper
|
|
145
|
-
* element (the `data-composition-src` host) that carries the composition id,
|
|
146
|
-
* which is how the runtime binds `window.__timelines[id]` into the player's
|
|
147
|
-
* master timeline. A standalone preview has no such wrapper, so it relies on
|
|
148
|
-
* the frame's own root element carrying `data-composition-id`. If the id lives
|
|
149
|
-
* only on the inert `<template>` tag (a common authoring pattern), the rendered
|
|
150
|
-
* body has no `[data-composition-id]` element — the runtime then never selects
|
|
151
|
-
* a root composition, the registered GSAP timeline stays unbound, and seeking
|
|
152
|
-
* does nothing. The frame renders at its pre-animation state (GSAP `fromTo`
|
|
153
|
-
* pins `opacity:0`), producing a blank preview/thumbnail.
|
|
154
|
-
*
|
|
155
|
-
* This is a no-op when the content already exposes a `[data-composition-id]`
|
|
156
|
-
* element (e.g. the id is authored on the root div), so compositions that
|
|
157
|
-
* already render correctly are untouched.
|
|
158
|
-
*/
|
|
159
|
-
function promoteTemplateCompositionId(rawComp, body) {
|
|
160
|
-
const templateCompositionId = rawComp.match(/<template[^>]*\sdata-composition-id\s*=\s*["']([^"']+)["']/i)?.[1];
|
|
161
|
-
if (!templateCompositionId)
|
|
162
|
-
return;
|
|
163
|
-
if (body.querySelector("[data-composition-id]"))
|
|
164
|
-
return;
|
|
165
|
-
const root = Array.from(body.children).find((el) => !NON_RENDERED_TAGS.has(el.tagName));
|
|
166
|
-
root?.setAttribute("data-composition-id", templateCompositionId);
|
|
167
|
-
}
|
|
168
|
-
/**
|
|
169
|
-
* Add `data-composition-file="<compPath>"` to the comp's root composition
|
|
170
|
-
* element (the first `[data-composition-id]` that lacks the attribute), so the
|
|
171
|
-
* studio resolves its top-level elements to the right source file. Idempotent;
|
|
172
|
-
* a no-op when no composition element is present.
|
|
173
|
-
*/
|
|
174
|
-
function tagRootCompositionFile(bodyHtml, compPath) {
|
|
175
|
-
const match = bodyHtml.match(/<[a-zA-Z][^>]*\bdata-composition-id=/);
|
|
176
|
-
if (match?.index == null)
|
|
177
|
-
return bodyHtml;
|
|
178
|
-
const tagEnd = bodyHtml.indexOf(">", match.index);
|
|
179
|
-
if (tagEnd === -1)
|
|
180
|
-
return bodyHtml;
|
|
181
|
-
if (bodyHtml.slice(match.index, tagEnd).includes("data-composition-file"))
|
|
182
|
-
return bodyHtml;
|
|
183
|
-
return (bodyHtml.slice(0, tagEnd) + ` data-composition-file="${compPath}"` + bodyHtml.slice(tagEnd));
|
|
184
|
-
}
|
|
185
|
-
/**
|
|
186
|
-
* Build a standalone HTML page for a sub-composition.
|
|
187
|
-
*
|
|
188
|
-
* Uses the project's own index.html `<head>` so all dependencies (GSAP, fonts,
|
|
189
|
-
* Lottie, reset styles, runtime) are preserved — instead of building a minimal
|
|
190
|
-
* page from scratch that would miss important scripts/styles.
|
|
191
|
-
*
|
|
192
|
-
* Three dispatch modes, tried in order:
|
|
193
|
-
* 1. `<template>` wrapper → extract template content (existing compositions)
|
|
194
|
-
* 2. Full HTML document → parse and extract head/body separately (registry blocks)
|
|
195
|
-
* 3. Raw fragment → wrap in a minimal document
|
|
196
|
-
*
|
|
197
|
-
* For full-doc mode, the composition's own `<head>` content (styles, scripts,
|
|
198
|
-
* links, meta) is appended AFTER the project's index.html head. When both
|
|
199
|
-
* declare the same dependency (e.g. GSAP CDN), the composition's copy wins
|
|
200
|
-
* by last-write-wins script execution order — this is intentional so the
|
|
201
|
-
* composition can pin a specific version.
|
|
202
|
-
*/
|
|
203
|
-
export function buildSubCompositionHtml(projectDir, compPath, runtimeUrl, baseHref) {
|
|
204
|
-
const compFile = join(projectDir, compPath);
|
|
205
|
-
if (!existsSync(compFile))
|
|
206
|
-
return null;
|
|
207
|
-
const rawComp = readFileSync(compFile, "utf-8");
|
|
208
|
-
let compHeadContent = "";
|
|
209
|
-
let rewrittenContent;
|
|
210
|
-
let htmlAttrs = "";
|
|
211
|
-
let bodyAttrs = "";
|
|
212
|
-
const templateInner = extractTemplateInnerHtml(rawComp);
|
|
213
|
-
if (templateInner != null) {
|
|
214
|
-
const { document: contentDoc } = parseHTML(`<!DOCTYPE html><html><head></head><body>${templateInner}</body></html>`);
|
|
215
|
-
rewriteRelativePaths(contentDoc, compPath);
|
|
216
|
-
fixDigitLeadingIdSelectors(contentDoc);
|
|
217
|
-
promoteTemplateCompositionId(rawComp, contentDoc.body);
|
|
218
|
-
rewrittenContent = contentDoc.body.innerHTML || templateInner;
|
|
219
|
-
}
|
|
220
|
-
else if (isFullHtmlDocument(rawComp)) {
|
|
221
|
-
const parts = extractFullDocumentParts(rawComp, compPath);
|
|
222
|
-
compHeadContent = parts.headContent;
|
|
223
|
-
rewrittenContent = parts.bodyContent;
|
|
224
|
-
htmlAttrs = parts.htmlAttrs;
|
|
225
|
-
bodyAttrs = parts.bodyAttrs;
|
|
226
|
-
}
|
|
227
|
-
else {
|
|
228
|
-
const { document: contentDoc } = parseHTML(`<!DOCTYPE html><html><head></head><body>${rawComp}</body></html>`);
|
|
229
|
-
rewriteRelativePaths(contentDoc, compPath);
|
|
230
|
-
fixDigitLeadingIdSelectors(contentDoc);
|
|
231
|
-
rewrittenContent = contentDoc.body.innerHTML || rawComp;
|
|
232
|
-
}
|
|
233
|
-
// A composition file may ship a baked inline runtime (from a prior export:
|
|
234
|
-
// data-hyperframes-runtime / __hyperframeRuntime…). The studio injects its own
|
|
235
|
-
// preview runtime below, so strip the baked one from the body — otherwise it's
|
|
236
|
-
// double-loaded AND the baked inline copy can fail to parse inline (the
|
|
237
|
-
// "Unexpected token '<'" SyntaxError seen on comps with a baked runtime).
|
|
238
|
-
rewrittenContent = stripEmbeddedRuntimeScripts(rewrittenContent);
|
|
239
|
-
// The comp's root carries data-composition-id but (unlike inlined sub-comps,
|
|
240
|
-
// which inlineSubCompositions tags) no data-composition-file. Without it the
|
|
241
|
-
// studio can't resolve which file this comp's top-level elements live in and
|
|
242
|
-
// falls back to "index.html" — so the GSAP panel parses the project root (which
|
|
243
|
-
// may be a multi-timeline master) and wrongly reports "multiple timelines",
|
|
244
|
-
// disabling editing for a single-timeline comp. Tag the root with its own path.
|
|
245
|
-
rewrittenContent = tagRootCompositionFile(rewrittenContent, compPath);
|
|
246
|
-
// Use the project's index.html <head> to preserve all dependencies
|
|
247
|
-
const indexPath = join(projectDir, "index.html");
|
|
248
|
-
let headContent = "";
|
|
249
|
-
if (existsSync(indexPath)) {
|
|
250
|
-
const indexHtml = readFileSync(indexPath, "utf-8");
|
|
251
|
-
const headMatch = indexHtml.match(/<head[^>]*>([\s\S]*?)<\/head>/i);
|
|
252
|
-
headContent = headMatch?.[1] ?? "";
|
|
253
|
-
}
|
|
254
|
-
// Inject <base> for relative asset resolution (before other tags)
|
|
255
|
-
if (baseHref && !headContent.includes("<base")) {
|
|
256
|
-
headContent = `<base href="${baseHref}">\n${headContent}`;
|
|
257
|
-
}
|
|
258
|
-
// Append the sub-composition's own <head> content so its CSS, scripts,
|
|
259
|
-
// links, and meta tags are preserved. Placed after the project head so
|
|
260
|
-
// the composition's deps take precedence (last-write-wins for scripts).
|
|
261
|
-
if (compHeadContent)
|
|
262
|
-
headContent += `\n${compHeadContent}`;
|
|
263
|
-
// Strip any baked runtime the borrowed index/comp <head> carried, for the same
|
|
264
|
-
// reason as the body above — done before injecting the preview runtime so the
|
|
265
|
-
// injected tag (added next) is never removed.
|
|
266
|
-
headContent = stripEmbeddedRuntimeScripts(headContent);
|
|
267
|
-
// Ensure runtime is present (might differ from the one in index.html)
|
|
268
|
-
if (!headContent.includes("hyperframe.runtime") &&
|
|
269
|
-
!headContent.includes("hyperframes-preview-runtime")) {
|
|
270
|
-
headContent += `\n<script data-hyperframes-preview-runtime="1" src="${runtimeUrl}"></script>`;
|
|
271
|
-
}
|
|
272
|
-
// Fallback: if no index.html head was found, add minimal deps
|
|
273
|
-
if (!headContent.includes("gsap")) {
|
|
274
|
-
headContent += `\n<script src="https://cdn.jsdelivr.net/npm/gsap@3/dist/gsap.min.js"></script>`;
|
|
275
|
-
}
|
|
276
|
-
const htmlOpen = htmlAttrs ? `<html ${htmlAttrs}>` : "<html>";
|
|
277
|
-
const bodyOpen = bodyAttrs ? `<body ${bodyAttrs}>` : "<body>";
|
|
278
|
-
return `<!DOCTYPE html>
|
|
279
|
-
${htmlOpen}
|
|
280
|
-
<head>
|
|
281
|
-
${headContent}
|
|
282
|
-
</head>
|
|
283
|
-
${bodyOpen}
|
|
284
|
-
<script>window.__timelines=window.__timelines||{};</script>
|
|
285
|
-
${rewrittenContent}
|
|
286
|
-
</body>
|
|
287
|
-
</html>`;
|
|
288
|
-
}
|
|
289
|
-
//# sourceMappingURL=subComposition.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"subComposition.js","sourceRoot":"","sources":["../../../src/studio-api/helpers/subComposition.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
export declare function buildWaveformCacheKey(assetPath: string): string;
|
|
2
|
-
export declare function decodeAudioPeaks(audioPath: string): Promise<number[]>;
|
|
3
|
-
export declare function generateWaveformCache(projectDir: string, assetPath: string): Promise<void>;
|
|
4
|
-
//# sourceMappingURL=waveform.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"waveform.d.ts","sourceRoot":"","sources":["../../../src/studio-api/helpers/waveform.ts"],"names":[],"mappings":"AAQA,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAE/D;AAyBD,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAuCrE;AAED,wBAAsB,qBAAqB,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAWhG"}
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import { spawn } from "node:child_process";
|
|
2
|
-
import { existsSync, writeFileSync, mkdirSync } from "node:fs";
|
|
3
|
-
import { join, resolve } from "node:path";
|
|
4
|
-
const SAMPLE_RATE = 4000;
|
|
5
|
-
const PEAK_COUNT = 4000;
|
|
6
|
-
const WAVEFORM_CACHE_VERSION = "v2";
|
|
7
|
-
export function buildWaveformCacheKey(assetPath) {
|
|
8
|
-
return `${WAVEFORM_CACHE_VERSION}_${assetPath.replace(/[/\\]/g, "_")}.json`;
|
|
9
|
-
}
|
|
10
|
-
function computePeaks(floats, count) {
|
|
11
|
-
const step = floats.length / count;
|
|
12
|
-
const peaks = [];
|
|
13
|
-
for (let i = 0; i < count; i++) {
|
|
14
|
-
const start = Math.floor(i * step);
|
|
15
|
-
const end = Math.min(Math.floor((i + 1) * step), floats.length);
|
|
16
|
-
let max = 0;
|
|
17
|
-
for (let j = start; j < end; j++) {
|
|
18
|
-
const abs = Math.abs(floats[j] ?? 0);
|
|
19
|
-
if (abs > max)
|
|
20
|
-
max = abs;
|
|
21
|
-
}
|
|
22
|
-
peaks.push(max);
|
|
23
|
-
}
|
|
24
|
-
const maxPeak = Math.max(...peaks, 0.001);
|
|
25
|
-
return peaks.map((p) => p / maxPeak);
|
|
26
|
-
}
|
|
27
|
-
function ffmpegBinary() {
|
|
28
|
-
const configured = process.env.HYPERFRAMES_FFMPEG_PATH?.trim();
|
|
29
|
-
if (configured)
|
|
30
|
-
return resolve(configured);
|
|
31
|
-
return "ffmpeg";
|
|
32
|
-
}
|
|
33
|
-
export function decodeAudioPeaks(audioPath) {
|
|
34
|
-
return new Promise((resolvePromise, reject) => {
|
|
35
|
-
const proc = spawn(ffmpegBinary(), [
|
|
36
|
-
"-i",
|
|
37
|
-
audioPath,
|
|
38
|
-
"-af",
|
|
39
|
-
"atrim=start_sample=1152",
|
|
40
|
-
"-f",
|
|
41
|
-
"f32le",
|
|
42
|
-
"-ac",
|
|
43
|
-
"1",
|
|
44
|
-
"-ar",
|
|
45
|
-
String(SAMPLE_RATE),
|
|
46
|
-
"-vn",
|
|
47
|
-
"pipe:1",
|
|
48
|
-
], { stdio: ["ignore", "pipe", "ignore"] });
|
|
49
|
-
const chunks = [];
|
|
50
|
-
proc.stdout?.on("data", (chunk) => chunks.push(chunk));
|
|
51
|
-
proc.on("close", (code) => {
|
|
52
|
-
if (code !== 0 && chunks.length === 0) {
|
|
53
|
-
reject(new Error(`ffmpeg exited with code ${code}`));
|
|
54
|
-
return;
|
|
55
|
-
}
|
|
56
|
-
const buf = Buffer.concat(chunks);
|
|
57
|
-
const numSamples = Math.floor(buf.length / 4);
|
|
58
|
-
if (numSamples === 0) {
|
|
59
|
-
reject(new Error("ffmpeg produced no audio samples"));
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
const ab = buf.buffer.slice(buf.byteOffset, buf.byteOffset + numSamples * 4);
|
|
63
|
-
resolvePromise(computePeaks(new Float32Array(ab), PEAK_COUNT));
|
|
64
|
-
});
|
|
65
|
-
proc.on("error", reject);
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
export async function generateWaveformCache(projectDir, assetPath) {
|
|
69
|
-
const audioPath = join(projectDir, assetPath);
|
|
70
|
-
if (!existsSync(audioPath))
|
|
71
|
-
return;
|
|
72
|
-
const cacheDir = join(projectDir, ".waveform-cache");
|
|
73
|
-
const cachePath = join(cacheDir, buildWaveformCacheKey(assetPath));
|
|
74
|
-
if (existsSync(cachePath))
|
|
75
|
-
return;
|
|
76
|
-
const peaks = await decodeAudioPeaks(audioPath);
|
|
77
|
-
mkdirSync(cacheDir, { recursive: true });
|
|
78
|
-
writeFileSync(cachePath, JSON.stringify(peaks));
|
|
79
|
-
}
|
|
80
|
-
//# sourceMappingURL=waveform.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"waveform.js","sourceRoot":"","sources":["../../../src/studio-api/helpers/waveform.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"files.d.ts","sourceRoot":"","sources":["../../../src/studio-api/routes/files.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAcjC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAm0CpD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAyZ7E"}
|