hyperframes 0.8.113 → 0.8.115
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/{add-ILIGSLV4.js → add-ZSLFODRZ.js} +15 -14
- package/dist/{animatedGifPrep-U7FMC7DB.js → animatedGifPrep-72A45YER.js} +5 -5
- package/dist/{asset-OFDEIAGM.js → asset-SGDOHBBN.js} +2 -2
- package/dist/{assetCataloger-5LCGR5XU.js → assetCataloger-Q7BCDARF.js} +2 -2
- package/dist/{auth-5JDDEX2M.js → auth-5JGFN7SV.js} +2 -2
- package/dist/{autoUpdate-JXVZVJCV.js → autoUpdate-ZVTMYO7Z.js} +2 -2
- package/dist/{backgroundChecks-BBWGY3V6.js → backgroundChecks-IY3G5G2D.js} +3 -3
- package/dist/backgroundChecksWorker.js +3 -3
- package/dist/{batchRender-QVJ7NEUH.js → batchRender-QVLLL5DN.js} +3 -3
- package/dist/{beats-YEYVQMX6.js → beats-66KZIB5V.js} +14 -10
- package/dist/{benchmark-J2V46VWI.js → benchmark-AWFKSWQH.js} +11 -11
- package/dist/{browser-XBWASLD2.js → browser-J54EXMCE.js} +8 -8
- package/dist/{bundleWithLocalizedFonts-4CVITCYK.js → bundleWithLocalizedFonts-BLLHP2TO.js} +2 -2
- package/dist/{capture-GLHK4ST7.js → capture-D4HRSVSK.js} +2 -2
- package/dist/{capture-F2Y7TIHU.js → capture-SLI2I5BS.js} +16 -11
- package/dist/{catalog-3QDMTDK2.js → catalog-BUMLQU7L.js} +15 -14
- package/dist/{check-O3RR4NWI.js → check-HEZUK62C.js} +31 -29
- package/dist/{checkBrowser-K36DAG4S.js → checkBrowser-RVJM6IUO.js} +30 -28
- package/dist/{chunk-EMZF2TPA.js → chunk-2DX6JYL2.js} +2 -2
- package/dist/{chunk-BOUDTDBQ.js → chunk-2GWVY66H.js} +1 -1
- package/dist/{chunk-P3FGUSFK.js → chunk-2H37RGJ2.js} +7 -7
- package/dist/{chunk-7543YIMQ.js → chunk-3J4EBX5M.js} +1 -1
- package/dist/{chunk-3XPZJUKM.js → chunk-3R6P5BIG.js} +2 -2
- package/dist/{chunk-ZZIXIOK2.js → chunk-3YTWSGBV.js} +4 -4
- package/dist/{chunk-HYXL3VJA.js → chunk-4HIF3LI3.js} +5 -5
- package/dist/{chunk-HTQR7SUZ.js → chunk-4P2TOD7N.js} +1 -1
- package/dist/{chunk-G2T2X6FZ.js → chunk-5MXN7WM4.js} +2 -2
- package/dist/{chunk-2DBYGR4N.js → chunk-5YSA3YXO.js} +14 -18
- package/dist/{chunk-7CGIICLA.js → chunk-6SEUZGID.js} +3 -3
- package/dist/{chunk-VLC7JS4K.js → chunk-74RAXWDF.js} +1 -1
- package/dist/{chunk-ZYSS3JED.js → chunk-AXXK3LWL.js} +1 -1
- package/dist/chunk-BDNCUMZM.js +2961 -0
- package/dist/{chunk-E52XEEAA.js → chunk-BQG33YTI.js} +1 -1
- package/dist/{chunk-QPR4N2D4.js → chunk-CVBWF2MD.js} +1 -1
- package/dist/{chunk-R4NWAW35.js → chunk-HOBR4IHC.js} +7 -7
- package/dist/{chunk-XZM2I47O.js → chunk-HPWPLV5J.js} +2 -2
- package/dist/{chunk-FCEFKWPM.js → chunk-IEE7GIVX.js} +1 -1
- package/dist/{chunk-L5QASNBN.js → chunk-IOJAVV6J.js} +1 -1
- package/dist/{chunk-DDK22K3I.js → chunk-KLZ7OCHR.js} +3 -3
- package/dist/{chunk-OCNCK5FQ.js → chunk-M7XTMZF5.js} +1 -1
- package/dist/{chunk-GDJ74GHW.js → chunk-MPB7BQT7.js} +1 -1
- package/dist/{chunk-VIJ35BJ6.js → chunk-ORAISNGN.js} +14 -17
- package/dist/{chunk-IP3XINRB.js → chunk-P6LJ4Y32.js} +23 -2944
- package/dist/chunk-P73WQPSB.js +93 -0
- package/dist/{chunk-VTP4VSRP.js → chunk-PLP4K6WZ.js} +194 -52
- package/dist/{chunk-LMC46FK5.js → chunk-QMFCL2ZN.js} +1 -1
- package/dist/{chunk-DR7QW6C5.js → chunk-QXNRRMBQ.js} +2 -2
- package/dist/{chunk-C6AIZOQN.js → chunk-RRPJEHHW.js} +1 -1
- package/dist/{chunk-FXHVADV6.js → chunk-SAO3NQPF.js} +1 -1
- package/dist/{chunk-3IUSKIZW.js → chunk-SC7ICSIU.js} +1 -1
- package/dist/{chunk-FW7K32YT.js → chunk-SK53U3PF.js} +1 -1
- package/dist/{chunk-XXKBPGPJ.js → chunk-SOEQWMNS.js} +2 -2
- package/dist/{chunk-L5SYYW2P.js → chunk-SSZYJCAL.js} +2 -2
- package/dist/{chunk-U4VSY56O.js → chunk-T5HXGUM3.js} +1 -1
- package/dist/{chunk-ENHAGQEP.js → chunk-TMCJPHPP.js} +1 -1
- package/dist/{chunk-XFJXFNJF.js → chunk-TWJT2RGZ.js} +27 -12
- package/dist/{chunk-ZMMSMDCA.js → chunk-VDASTWUM.js} +1 -1
- package/dist/{chunk-T3NMEYGM.js → chunk-WZYHTXZY.js} +1 -1
- package/dist/{chunk-IRJBTYJF.js → chunk-XJQ7TRLG.js} +1 -1
- package/dist/{chunk-OEA2J2TF.js → chunk-Y2Y4LBJD.js} +3 -3
- package/dist/{chunk-SIN32SJB.js → chunk-YNHP6OFJ.js} +2 -2
- package/dist/{chunk-4KGMIOMY.js → chunk-ZBQP54CD.js} +10 -7
- package/dist/{clean-RPB34TT6.js → clean-X6Y252ZC.js} +14 -14
- package/dist/cli.js +53 -52
- package/dist/{cloud-QECFFPKC.js → cloud-EE4GALWR.js} +4 -4
- package/dist/{cloudrun-BML6ZG7K.js → cloudrun-Y6A42KHE.js} +3 -3
- package/dist/{compare-PF6WHQ4T.js → compare-K6XJZ3OC.js} +25 -23
- package/dist/{compiler-ZHVIEP26.js → compiler-DYACPLUW.js} +2 -2
- package/dist/{component-4ENCNLED.js → component-T6IYSCFP.js} +3 -3
- package/dist/{compositions-5UA33RSG.js → compositions-4KUTNS5L.js} +10 -10
- package/dist/{delete-SARS5LIK.js → delete-C64TWAPE.js} +2 -2
- package/dist/{dist-OKRUIHYU.js → dist-KNGSQALD.js} +2 -2
- package/dist/{doctor-TSAQGYP4.js → doctor-WJXZK5QN.js} +9 -9
- package/dist/{events-3HUO73ZE.js → events-FVG3Y6Q4.js} +8 -8
- package/dist/{events-SZ5NWYWD.js → events-QRWJBSV4.js} +7 -7
- package/dist/{feedback-42OTOFC6.js → feedback-NQHRUOZP.js} +9 -9
- package/dist/{figma-RYNFCYXB.js → figma-MEX4CSIM.js} +3 -3
- package/dist/fontLocalizeCli.js +7 -7
- package/dist/{get-IRHLG5OQ.js → get-CMJIHGSA.js} +2 -2
- package/dist/{gpuPolicy-LRMOZXFU.js → gpuPolicy-5S4OZDME.js} +5 -5
- package/dist/{grade-compare-KGJP5HV7.js → grade-compare-NIDMIUGZ.js} +25 -23
- package/dist/{help-C5HS56RZ.js → help-G6AWAWJW.js} +1 -1
- package/dist/{history-DFJNDM2T.js → history-ZBOK2JQF.js} +20 -18
- package/dist/hyperframe-runtime.js +36 -36
- package/dist/hyperframe.manifest.json +1 -1
- package/dist/hyperframe.runtime.iife.js +36 -36
- package/dist/hyperframes-player.global.js +1 -1
- package/dist/{info-26GTDTKN.js → info-2ORQZ6I2.js} +10 -10
- package/dist/{init-RXA6NI73.js → init-3PSKH6UR.js} +22 -21
- package/dist/{inspect-2S5GAZYC.js → inspect-NR54RMEE.js} +26 -24
- package/dist/{installer-DGYYDGWJ.js → installer-YQUWHYBZ.js} +5 -4
- package/dist/{keyframes-WBMAX7XZ.js → keyframes-KT7T4AEV.js} +11 -11
- package/dist/{lambda-OQBFCEFA.js → lambda-3FF4V3X3.js} +4 -4
- package/dist/{layout-ZRU7PXBG.js → layout-RB3M37ER.js} +26 -24
- package/dist/{lint-ATVNZ6FG.js → lint-HR57M5YP.js} +11 -11
- package/dist/{list-E2GHYPCQ.js → list-YDXYHXHF.js} +2 -2
- package/dist/{login-LOC4KA7H.js → login-N6UNRVYW.js} +4 -4
- package/dist/{media-treatment-L43MVH2V.js → media-treatment-UXJOTNRO.js} +11 -11
- package/dist/{models-JF5OOZ5A.js → models-Z3XFMGXB.js} +6 -6
- package/dist/{motionShot-BJ5CLYMN.js → motionShot-KQMCXJ77.js} +15 -12
- package/dist/{normalize-audio-K33FKGAF.js → normalize-audio-XJQMDWRV.js} +10 -10
- package/dist/{pipeline-IWPF5ZMK.js → pipeline-U3OISHWV.js} +5 -5
- package/dist/{play-PHHXYCQI.js → play-XP77PML5.js} +20 -19
- package/dist/{preflight-2GH2Z4GZ.js → preflight-CANFVC4Y.js} +6 -6
- package/dist/{present-KBFK2YVB.js → present-MWGA3O4S.js} +15 -15
- package/dist/{preview-T3E5TFDC.js → preview-X5GWZ3Q6.js} +31 -24
- package/dist/{producer-SL66UNEP.js → producer-B2IHU7MA.js} +1 -1
- package/dist/{projectConfig-7AKXZNNR.js → projectConfig-2A64YU5H.js} +7 -6
- package/dist/{publication-B2OERUY7.js → publication-CFYBPLRS.js} +2 -2
- package/dist/{publish-ZGKT7KED.js → publish-WE6AS77D.js} +8 -7
- package/dist/{remove-background-4LRTT6YL.js → remove-background-XSDOCVN5.js} +6 -6
- package/dist/{render-H6RSJF2V.js → render-5TMRIC73.js} +11 -11
- package/dist/{render-OKNPNMFS.js → render-HVZUCLYW.js} +21 -20
- package/dist/{render-TGCDBKMP.js → render-QX6AKB6Y.js} +3 -3
- package/dist/{render-batch-WRQFW4UC.js → render-batch-QJXFVTDE.js} +3 -3
- package/dist/{renderCancellation-BFCQYGVV.js → renderCancellation-WSSSHRFR.js} +5 -5
- package/dist/{resolver-37UOGAMT.js → resolver-WTXO6WXA.js} +5 -4
- package/dist/{sherpa-SDVKYXCX.js → sherpa-S6ZBBEFO.js} +6 -6
- package/dist/skills/hyperframes/SKILL.md +4 -0
- package/dist/skills/hyperframes-cli/SKILL.md +8 -0
- package/dist/skills/hyperframes-cli/references/upgrade-info-misc.md +8 -0
- package/dist/skills/media-use/audio/scripts/audio.mjs +4 -1
- package/dist/skills/media-use/audio/scripts/audio.test.mjs +33 -0
- package/dist/skills/media-use/audio/scripts/lib/tts.mjs +1 -0
- package/dist/skills/media-use/audio/scripts/lib/tts.test.mjs +44 -1
- package/dist/{skills-O25ZTFTO.js → skills-CDRSTETB.js} +10 -10
- package/dist/{skillsUpdateCheck-Y2V4OMMT.js → skillsUpdateCheck-FKREJXSF.js} +3 -3
- package/dist/{snapshot-KGM2HZIC.js → snapshot-T4PFSXTH.js} +142 -51
- package/dist/{src-PLWCT745.js → src-5BZDQAVN.js} +6 -6
- package/dist/{src-PJJ6NISA.js → src-IZMCUYK7.js} +4 -4
- package/dist/{staticProjectServer-OCE7GU5S.js → staticProjectServer-VN4ARAH4.js} +14 -13
- package/dist/{status-LENRPQS5.js → status-OJZWJB53.js} +5 -5
- package/dist/studio/assets/{hyperframes-player-DzJbtQVO.js → hyperframes-player-C-9N8nk0.js} +1 -1
- package/dist/studio/assets/{index-n5FUn1xv.js → index-BoUM6Xqb.js} +1 -1
- package/dist/studio/assets/{index-DRhF3v4Z.js → index-CAvZ0AA-.js} +204 -204
- package/dist/studio/assets/{index-DgwDQK5G.js → index-CVuorIMv.js} +1 -1
- package/dist/studio/assets/index-t1LH6H5H.css +1 -0
- package/dist/studio/{chunk-K47E2ZJA.js → chunk-5EKWJZLM.js} +504 -17
- package/dist/studio/chunk-5EKWJZLM.js.map +1 -0
- package/dist/studio/{chunk-VWT7STY3.js → chunk-J6Q572FA.js} +2 -2
- package/dist/studio/{chunk-BIUXP3PG.js → chunk-TXZMMOMA.js} +43 -276
- package/dist/studio/chunk-TXZMMOMA.js.map +1 -0
- package/dist/studio/{domEditingLayers-V67MS4WP.js → domEditingLayers-D7VYFJJD.js} +3 -5
- package/dist/studio/index.d.ts +46 -22
- package/dist/studio/index.html +2 -2
- package/dist/studio/index.js +3899 -3487
- package/dist/studio/index.js.map +1 -1
- package/dist/studio/player.js +2 -2
- package/dist/studio/styles.css +1 -1
- package/dist/{studio-api-IEQ5BIHT.js → studio-api-CIO2NKK5.js} +9 -7
- package/dist/{studioServer-LXJ34MGN.js → studioServer-G5GNYWDI.js} +45 -45
- package/dist/{system-4KRSV2B7.js → system-PPNNGVIM.js} +5 -5
- package/dist/{telemetry-R3BPD6VK.js → telemetry-GMDMISOX.js} +8 -8
- package/dist/{timeline-N5UKVS2S.js → timeline-5LSQX4OS.js} +14 -14
- package/dist/{tokens-774UBF2R.js → tokens-VBXAT7CK.js} +2 -2
- package/dist/{transcribe-IP74EZLM.js → transcribe-GYCAIIEQ.js} +11 -11
- package/dist/{transcribe-3UXXEDXX.js → transcribe-VGYAWRXS.js} +6 -6
- package/dist/{updateCheck-EXHNAPKI.js → updateCheck-AZEREUQV.js} +2 -2
- package/dist/{upgrade-A4M3O2F2.js → upgrade-S63QN2LA.js} +2 -2
- package/dist/{urlDownloader-4KNER64L.js → urlDownloader-SM6ODN5O.js} +4 -4
- package/dist/usage-EC3KFUIJ.js +2139 -0
- package/dist/{validate-DV75GM6J.js → validate-7MNUK5MH.js} +15 -14
- package/dist/{video-GINAMW5I.js → video-JEOHARTC.js} +5 -5
- package/package.json +1 -1
- package/dist/studio/assets/index-DbfKVTId.css +0 -1
- package/dist/studio/chunk-BIUXP3PG.js.map +0 -1
- package/dist/studio/chunk-K47E2ZJA.js.map +0 -1
- /package/dist/studio/{chunk-VWT7STY3.js.map → chunk-J6Q572FA.js.map} +0 -0
- /package/dist/studio/{domEditingLayers-V67MS4WP.js.map → domEditingLayers-D7VYFJJD.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/editor/probeSourceElement.ts","../src/components/editor/domEditingLayers.ts","../src/components/editor/domEditingGroups.ts","../src/components/editor/domEditingElement.ts","../src/components/editor/domEditingRootLayer.ts","../src/components/editor/domEditLayerWalkCache.ts"],"sourcesContent":["import { buildProjectApiPath } from \"../../utils/projectRouting\";\n\ntype ProbeTarget = { id?: string; hfId?: string; selector?: string; selectorIndex?: number };\n\ninterface PendingProbe {\n target: ProbeTarget;\n resolve: (exists: boolean) => void;\n}\n\nconst pending = new Map<string, PendingProbe[]>();\n\nasync function sendBatch(projectId: string, sourceFile: string, probes: PendingProbe[]) {\n let exists: boolean[] = [];\n try {\n const response = await fetch(\n buildProjectApiPath(\n projectId,\n `/file-mutations/probe-elements/${encodeURIComponent(sourceFile)}`,\n ),\n {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ targets: probes.map((probe) => probe.target) }),\n },\n );\n if (response.ok) {\n const data = await response.json();\n if (Array.isArray(data?.exists)) exists = data.exists;\n }\n } catch {}\n probes.forEach((probe, index) => probe.resolve(exists[index] !== false));\n}\n\nexport function probeSourceElement(\n projectId: string,\n sourceFile: string,\n target: ProbeTarget,\n): Promise<boolean> {\n return new Promise((resolve) => {\n const key = `${projectId}\\0${sourceFile}`;\n let probes = pending.get(key);\n if (!probes) {\n const batch: PendingProbe[] = [];\n probes = batch;\n pending.set(key, batch);\n setTimeout(() => {\n pending.delete(key);\n void sendBatch(projectId, sourceFile, batch);\n }, 0);\n }\n probes.push({ target, resolve });\n });\n}\n","import { probeSourceElement } from \"./probeSourceElement\";\nimport { isAudibleVideoNode } from \"../../player/lib/timelineElementHelpers\";\nimport type { PatchOperation } from \"../../utils/sourcePatcher\";\nimport {\n resolveEditingAffordances,\n resolveEditingSections,\n type EditableElementFacts,\n} from \"@hyperframes/core/editing\";\nimport { groupScopedLayerRoots, resolveGroupCapture } from \"./domEditingGroups\";\nimport type {\n DomEditCapabilities,\n DomEditContextOptions,\n DomEditLayerItem,\n DomEditSelection,\n DomEditTextField,\n} from \"./domEditingTypes\";\nimport {\n buildElementLabel,\n buildStableSelector,\n findClosestByAttribute,\n getCuratedComputedStyles,\n getDataAttributes,\n getInlineStyles,\n getSelectorIndex,\n getSourceFileForElement,\n isEditableTextLeaf,\n isHtmlElement,\n} from \"./domEditingDom\";\nimport {\n findElementForSelection,\n getSelectionCandidate,\n isDomLayerElement,\n} from \"./domEditingElement\";\nimport { isCompositionRootLayer } from \"./domEditingRootLayer\";\nimport { withSelectorIndexPass } from \"../../utils/sourceScopedSelectorIndex\";\nimport { type DomEditLayerWalkCache, readDomEditLayerWalkEntry } from \"./domEditLayerWalkCache\";\n\nfunction sameTagChildIndex(el: HTMLElement): number {\n let index = 0;\n let sibling = el.previousElementSibling;\n while (sibling) {\n if (sibling.tagName === el.tagName) index += 1;\n sibling = sibling.previousElementSibling;\n }\n return index;\n}\n\nfunction getTextFieldLabel(\n _tagName: string,\n index: number,\n total: number,\n source: \"self\" | \"child\",\n): string {\n if (source === \"self\" || total === 1) return \"Content\";\n return `Text ${index + 1}`;\n}\n\nfunction buildTextField(\n el: HTMLElement,\n index: number,\n total: number,\n source: \"self\" | \"child\",\n sourceChildIndex?: number,\n): DomEditTextField {\n const tagName = el.tagName.toLowerCase();\n const key = el.getAttribute(\"data-hf-text-key\") ?? `${source}:${index}:${tagName}`;\n return {\n key,\n label: getTextFieldLabel(tagName, index, total, source),\n value: el.textContent ?? \"\",\n tagName,\n attributes: Array.from(el.attributes)\n .filter((attribute) => attribute.name !== \"style\")\n .map((attribute) => ({\n name: attribute.name,\n value: attribute.value,\n })),\n inlineStyles: getInlineStyles(el),\n computedStyles: getCuratedComputedStyles(el),\n source,\n ...(sourceChildIndex == null ? {} : { sourceChildIndex }),\n };\n}\n\n// fallow-ignore-next-line complexity\nexport function collectDomEditTextFields(el: HTMLElement): DomEditTextField[] {\n const childElements = Array.from(el.children).filter(isHtmlElement).filter(isEditableTextLeaf);\n\n if (childElements.length > 0) {\n const hasMixedContent = Array.from(el.childNodes).some(\n (node) => node.nodeType === 3 && node.textContent?.trim(),\n );\n\n if (hasMixedContent) {\n const fields: DomEditTextField[] = [];\n let childIdx = 0;\n for (const node of el.childNodes) {\n if (node.nodeType === 3) {\n const text = node.textContent ?? \"\";\n if (!text.trim()) continue;\n fields.push({\n key: `text-node:${childIdx}`,\n label: `Text ${childIdx + 1}`,\n value: text,\n tagName: \"#text\",\n attributes: [],\n inlineStyles: {},\n computedStyles: {},\n source: \"text-node\",\n });\n childIdx++;\n } else if (isHtmlElement(node) && isEditableTextLeaf(node)) {\n fields.push(\n buildTextField(node, childIdx, childElements.length, \"child\", sameTagChildIndex(node)),\n );\n childIdx++;\n }\n }\n return fields;\n }\n\n return childElements.map((child, index) =>\n buildTextField(child, index, childElements.length, \"child\", sameTagChildIndex(child)),\n );\n }\n\n if (isEditableTextLeaf(el)) {\n return [buildTextField(el, 0, 1, \"self\")];\n }\n\n return [];\n}\n\nfunction escapeHtmlText(value: string): string {\n return value.replace(/&/g, \"&\").replace(/</g, \"<\").replace(/>/g, \">\");\n}\n\nfunction serializeTextFieldStyle(field: DomEditTextField): string {\n const entries = Object.entries(field.inlineStyles).filter(([, value]) => Boolean(value));\n if (entries.length === 0) return \"\";\n return entries.map(([key, value]) => `${key}: ${value}`).join(\"; \");\n}\n\nexport function serializeDomEditTextFields(fields: DomEditTextField[]): string {\n return fields\n .filter((field) => field.source === \"child\" || field.source === \"text-node\")\n .map((field) => {\n if (field.source === \"text-node\") {\n return escapeHtmlText(field.value);\n }\n const attrs = [\n ...field.attributes.filter((attribute) => attribute.name !== \"data-hf-text-key\"),\n { name: \"data-hf-text-key\", value: field.key },\n ]\n .map((attribute) => ` ${attribute.name}=\"${attribute.value.replace(/\"/g, \""\")}\"`)\n .join(\"\");\n const style = serializeTextFieldStyle(field);\n const styleAttr = style ? ` style=\"${style.replace(/\"/g, \""\")}\"` : \"\";\n return `<${field.tagName}${attrs}${styleAttr}>${escapeHtmlText(field.value)}</${field.tagName}>`;\n })\n .join(\"\");\n}\n\nexport function buildDefaultDomEditTextField(base?: Partial<DomEditTextField>): DomEditTextField {\n return {\n key: `child:new:${Date.now()}`,\n label: \"Text\",\n value: \"New text\",\n tagName: \"span\",\n attributes: [],\n inlineStyles: {\n \"font-family\": base?.computedStyles?.[\"font-family\"] ?? \"inherit\",\n \"font-size\": base?.computedStyles?.[\"font-size\"] ?? \"16px\",\n \"font-weight\": base?.computedStyles?.[\"font-weight\"] ?? \"400\",\n color: base?.computedStyles?.color ?? \"inherit\",\n },\n computedStyles: {},\n source: \"child\",\n };\n}\n\nexport interface DomEditChildLocator {\n childSelector: string;\n childIndex: number;\n}\n\nexport function buildTextFieldChildLocator(\n fields: DomEditTextField[],\n fieldKey: string,\n): DomEditChildLocator | null {\n const field = fields.find((candidate) => candidate.key === fieldKey);\n if (!field || field.source !== \"child\") return null;\n // sourceChildIndex is only absent for a synthetic field that was never read\n // back from the live DOM (e.g. one built by buildDefaultDomEditTextField).\n // Guessing its position by counting same-tag \"child\" fields elsewhere in\n // the array is unreliable and can silently locate the wrong element — fail\n // closed instead so the caller falls back to the unsupported-structure path.\n if (field.sourceChildIndex == null) return null;\n\n return {\n childSelector: `:scope > ${field.tagName}`,\n childIndex: field.sourceChildIndex,\n };\n}\n\nfunction capabilityFacts(geometry: {\n hasStableTarget: boolean;\n tag: string;\n inlineStyles: Record<string, string>;\n computedStyles: Record<string, string>;\n isCompositionHost: boolean;\n isCompositionRoot: boolean;\n isInsideLockedComposition: boolean;\n isMasterView: boolean;\n existsInSource: boolean;\n}): EditableElementFacts {\n return {\n ...geometry,\n hasEditableText: false,\n hasTimingStart: false,\n animationCount: 0,\n };\n}\n\n/**\n * Build core EditableElementFacts from a fully-resolved DomEditSelection.\n * `animationCount` is supplied by the caller because live GSAP tweens arrive on\n * a separate channel (the PropertyPanel `gsapAnimations` prop), not on the\n * selection — `selection.gsapAnimations` is never populated.\n */\nexport function domEditSelectionToFacts(\n selection: DomEditSelection,\n animationCount = selection.gsapAnimations?.length ?? 0,\n): EditableElementFacts {\n return {\n hasStableTarget: Boolean(selection.selector || selection.hfId),\n tag: selection.tagName,\n inlineStyles: selection.inlineStyles,\n computedStyles: selection.computedStyles,\n isCompositionHost: selection.isCompositionHost,\n isCompositionRoot: false,\n isInsideLockedComposition: selection.isInsideLockedComposition,\n isMasterView: false,\n existsInSource: true,\n hasEditableText: selection.textFields.length > 0,\n hasTimingStart: selection.dataAttributes.start != null,\n animationCount,\n hasAudio: isAudibleVideoNode(selection.element),\n };\n}\n\n/**\n * Resolve DOM edit capabilities for a given element.\n * Thin wrapper over core resolveEditingAffordances — kept for backward\n * compatibility (tests and the barrel import this signature directly).\n */\nexport function resolveDomEditCapabilities(args: {\n selector?: string;\n hfId?: string;\n tagName?: string;\n inlineStyles: Record<string, string>;\n computedStyles: Record<string, string>;\n isCompositionHost: boolean;\n isCompositionRoot?: boolean;\n isInsideLockedComposition: boolean;\n isMasterView: boolean;\n existsInSource?: boolean;\n}): DomEditCapabilities {\n return resolveEditingAffordances(\n capabilityFacts({\n hasStableTarget: Boolean(args.selector || args.hfId),\n tag: (args.tagName ?? \"div\").toLowerCase(),\n inlineStyles: args.inlineStyles,\n computedStyles: args.computedStyles,\n isCompositionHost: args.isCompositionHost,\n isCompositionRoot: args.isCompositionRoot ?? false,\n isInsideLockedComposition: args.isInsideLockedComposition ?? false,\n isMasterView: args.isMasterView,\n existsInSource: args.existsInSource ?? true,\n }),\n ).capabilities;\n}\n\n// fallow-ignore-next-line complexity\nexport async function resolveDomEditSelection(\n startEl: HTMLElement | null,\n options: DomEditContextOptions & {\n projectId?: string | null;\n skipSourceProbe?: boolean;\n exactTarget?: boolean;\n },\n): Promise<DomEditSelection | null> {\n if (!startEl) return null;\n const doc = startEl.ownerDocument;\n\n let capture = options.exactTarget\n ? ({ kind: \"unit\", element: startEl } as const)\n : resolveGroupCapture(startEl, options.activeGroupElement ?? null);\n if (capture.kind === \"out-of-scope\") {\n // Drill-in is non-sticky: clicking/hovering OUTSIDE the drilled-into group\n // exits it and resolves the target normally, rather than selecting nothing\n // (which felt like \"can't select anything\" once you'd drilled in).\n capture = resolveGroupCapture(startEl, null);\n }\n let current: HTMLElement | null =\n capture.kind === \"unit\" ? capture.element : getSelectionCandidate(startEl, options);\n while (current && current !== doc.body && current !== doc.documentElement) {\n const selector = buildStableSelector(current);\n const hfId = readHfId(current);\n if (!selector && !hfId) {\n current = current.parentElement;\n continue;\n }\n\n const { sourceFile, compositionPath } = getSourceFileForElement(\n current,\n options.activeCompositionPath,\n );\n const selectorIndex = selector\n ? getSelectorIndex(doc, current, selector, sourceFile, options.activeCompositionPath)\n : undefined;\n const compositionSrc =\n current.getAttribute(\"data-composition-src\") ??\n current.getAttribute(\"data-composition-file\") ??\n undefined;\n const inlineStyles = getInlineStyles(current);\n const computedStyles = getCuratedComputedStyles(current);\n const isCompositionRoot =\n (current.hasAttribute(\"data-composition-id\") && !compositionSrc) ||\n isCompositionRootLayer(current, doc, computedStyles);\n const textFields = collectDomEditTextFields(current);\n const isInsideLocked = Boolean(findClosestByAttribute(current, [\"data-timeline-locked\"]));\n let existsInSource: boolean | undefined;\n if (!options.skipSourceProbe && options.projectId && (current.id || selector || hfId)) {\n const probeTarget: { id?: string; hfId?: string; selector?: string; selectorIndex?: number } =\n {};\n if (current.id) probeTarget.id = current.id;\n if (hfId) probeTarget.hfId = hfId;\n if (selector) probeTarget.selector = selector;\n if (selectorIndex != null) probeTarget.selectorIndex = selectorIndex;\n existsInSource = await probeSourceElement(options.projectId, sourceFile, probeTarget);\n }\n const capabilities = resolveEditingAffordances(\n capabilityFacts({\n hasStableTarget: Boolean(selector || hfId),\n tag: current.tagName.toLowerCase(),\n inlineStyles,\n computedStyles,\n isCompositionHost: Boolean(compositionSrc),\n isCompositionRoot,\n isInsideLockedComposition: isInsideLocked,\n isMasterView: options.isMasterView,\n existsInSource: existsInSource ?? true,\n }),\n ).capabilities;\n const rect = current.getBoundingClientRect();\n\n return {\n element: current,\n id: current.id || undefined,\n hfId,\n selector,\n selectorIndex,\n sourceFile,\n compositionPath,\n compositionSrc,\n isCompositionHost: Boolean(compositionSrc),\n isInsideLockedComposition: isInsideLocked,\n label: buildElementLabel(current),\n tagName: current.tagName.toLowerCase(),\n boundingBox: {\n x: rect.left,\n y: rect.top,\n width: rect.width,\n height: rect.height,\n },\n textContent: current.textContent?.trim() || null,\n dataAttributes: getDataAttributes(current),\n inlineStyles,\n computedStyles,\n textFields,\n capabilities,\n };\n }\n\n return null;\n}\n\nexport async function refreshDomEditSelection(\n selection: DomEditSelection,\n activeCompositionPath: string | null,\n): Promise<DomEditSelection | null> {\n const doc = selection.element.ownerDocument;\n const nextElement = findElementForSelection(doc, selection, activeCompositionPath);\n return nextElement\n ? resolveDomEditSelection(nextElement, {\n activeCompositionPath,\n isMasterView: !activeCompositionPath || activeCompositionPath === \"index.html\",\n })\n : null;\n}\n\n// ─── Layer items ─────────────────────────────────────────────────────────────\n\nexport function getDomEditLayerKey(\n target: Pick<DomEditSelection, \"id\" | \"selector\" | \"selectorIndex\" | \"sourceFile\">,\n): string {\n const selectorIndex = target.selectorIndex ?? 0;\n return `${target.sourceFile}:${target.id ?? target.selector ?? \"layer\"}:${selectorIndex}`;\n}\n\nexport function countDomEditChildLayers(\n root: HTMLElement | null | undefined,\n options: DomEditContextOptions,\n maxCount = 99,\n): number {\n if (!root) return 0;\n\n let count = 0;\n const visit = (el: HTMLElement) => {\n for (const child of Array.from(el.children)) {\n if (!isHtmlElement(child)) continue;\n if (isDomLayerElement(child)) {\n count += 1;\n if (count >= maxCount) return;\n }\n visit(child);\n if (count >= maxCount) return;\n }\n };\n\n visit(root);\n return count;\n}\n\n// Every editable element under `root`, in document order. `maxItems` is a\n// caller's rendering budget, not a property of the document: hit-testing\n// callers (marquee, off-canvas indicators) must see all of it, and sharing a\n// truncated list left everything past the cut unselectable however far you drag.\nexport function collectDomEditLayerItems(\n root: HTMLElement | null | undefined,\n options: DomEditContextOptions,\n maxItems = Number.POSITIVE_INFINITY,\n cache?: DomEditLayerWalkCache,\n): DomEditLayerItem[] {\n if (!root) return [];\n cache?.beginWalk(options.activeCompositionPath);\n\n const items: DomEditLayerItem[] = [];\n // fallow-ignore-next-line complexity\n const visit = (el: HTMLElement, depth: number) => {\n if (items.length >= maxItems) return;\n\n const entry = readDomEditLayerWalkEntry(el, options.activeCompositionPath, cache);\n if (entry) {\n const { target } = entry;\n items.push({\n key: getDomEditLayerKey(target),\n element: el,\n label: entry.label,\n tagName: el.tagName.toLowerCase(),\n depth,\n childCount: entry.childCount,\n id: target.id ?? undefined,\n hfId: target.hfId ?? undefined,\n selector: target.selector ?? undefined,\n selectorIndex: target.selectorIndex,\n sourceFile: target.sourceFile,\n });\n }\n\n const nextDepth = entry ? depth + 1 : depth;\n for (const child of Array.from(el.children)) {\n if (!isHtmlElement(child)) continue;\n visit(child, nextDepth);\n if (items.length >= maxItems) return;\n }\n };\n\n // Every item resolves its selector's occurrence index, and unshared that is a\n // whole-document query per element — quadratic once a composition repeats a\n // card or tile class. The walk is one synchronous read of a document it does\n // not mutate, so one index per selector serves the whole of it. The pass lives\n // here rather than in each caller because this function owns the loop.\n withSelectorIndexPass(root.ownerDocument, () => {\n // Drilled into a group → show only its members; otherwise the whole tree.\n for (const el of groupScopedLayerRoots(root, options.activeGroupElement ?? null)) visit(el, 0);\n });\n return items;\n}\n\nexport function liveLayerElement(\n layer: DomEditLayerItem,\n doc: Document | null | undefined,\n activeCompositionPath: string | null,\n): HTMLElement {\n if (layer.element.isConnected || !doc) return layer.element;\n return findElementForSelection(doc, layer, activeCompositionPath) ?? layer.element;\n}\n\n// ─── Patch operations ────────────────────────────────────────────────────────\n\nexport function buildDomEditStylePatchOperation(\n property: string,\n value: string | null,\n childLocator?: DomEditChildLocator,\n): PatchOperation {\n return {\n type: \"inline-style\",\n property,\n value,\n ...childLocator,\n };\n}\n\nexport function buildDomEditTextPatchOperation(\n value: string,\n childLocator?: DomEditChildLocator,\n): PatchOperation {\n return { type: \"text-content\", property: \"text\", value, ...childLocator };\n}\n\n/** Replace an element's contents with markup, for a change no per-child operation\n * can express (a text layer added, removed or reordered). Sanitized at both ends. */\nexport function buildDomEditRichTextPatchOperation(value: string): PatchOperation {\n return { type: \"rich-text\", property: \"\", value };\n}\n\n// ─── Non-editable reason ─────────────────────────────────────────────────────\n\nfunction hasSupportedDirectEdit(capabilities: DomEditCapabilities): boolean {\n return (\n capabilities.canEditStyles ||\n capabilities.canMove ||\n capabilities.canResize ||\n capabilities.canApplyManualOffset ||\n capabilities.canApplyManualSize ||\n capabilities.canApplyManualRotation\n );\n}\n\nexport function getDomEditNonEditableReason(\n element: HTMLElement,\n selection: DomEditSelection | null,\n): string | null {\n if (!selection) {\n return \"No stable source target\";\n }\n\n if (selection.element !== element) {\n return selection.isCompositionHost\n ? \"Nested composition boundary\"\n : `Selection resolves to ${selection.label}`;\n }\n\n if (!hasSupportedDirectEdit(selection.capabilities)) {\n return selection.capabilities.reasonIfDisabled ?? \"No supported direct edits\";\n }\n\n return null;\n}\n\nexport function getDomEditTargetKey(\n selection: Pick<DomEditSelection, \"id\" | \"hfId\" | \"selector\" | \"selectorIndex\" | \"sourceFile\">,\n): string {\n return [\n selection.sourceFile || \"index.html\",\n selection.hfId ?? \"\",\n selection.id ?? \"\",\n selection.selector ?? \"\",\n selection.selectorIndex ?? \"\",\n ].join(\"|\");\n}\n\nexport function isTextEditableSelection(selection: DomEditSelection): boolean {\n return resolveEditingSections(domEditSelectionToFacts(selection)).text;\n}\n\n// buildElementAgentPrompt is in domEditingAgentPrompt.ts\n\nexport function readHfId(element: Element): string | undefined {\n return element.getAttribute(\"data-hf-id\")?.trim() || undefined;\n}\n\nexport function buildDomEditPatchTarget(\n selection: Pick<DomEditSelection, \"id\" | \"hfId\" | \"selector\" | \"selectorIndex\">,\n): { id?: string | null; hfId?: string; selector?: string; selectorIndex?: number } {\n return {\n id: selection.id,\n hfId: selection.hfId,\n selector: selection.selector,\n selectorIndex: selection.selectorIndex,\n };\n}\n","import { isHtmlElement } from \"./domEditingDom\";\n\n// `data-hf-group` selection semantics: a group wrapper is selected as one unit\n// until the user drills into it; once drilled in, clicks resolve to its children\n// (or to the next nested group inside it). One level of drill-in at a time keeps\n// nested groups navigable.\n\nexport type GroupCapture =\n | { kind: \"unit\"; element: HTMLElement } // select this group wrapper as one unit\n | { kind: \"child\" } // resolve the clicked element normally\n | { kind: \"out-of-scope\" }; // clicked outside the drilled-into group → select nothing\n\n// Layer-tree roots: the drilled-into group's element children, else the doc root.\nexport function groupScopedLayerRoots(\n root: HTMLElement,\n activeGroupElement: HTMLElement | null,\n): HTMLElement[] {\n const els = activeGroupElement?.isConnected ? Array.from(activeGroupElement.children) : [root];\n return els.filter(isHtmlElement);\n}\n\nexport function resolveGroupCapture(\n startEl: HTMLElement,\n activeGroupElement: HTMLElement | null,\n): GroupCapture {\n const groups: HTMLElement[] = [];\n for (let n: HTMLElement | null = startEl; n; n = n.parentElement) {\n if (n.hasAttribute(\"data-hf-group\")) groups.push(n);\n }\n const result = ((): GroupCapture => {\n if (!activeGroupElement) {\n const outermost = groups[groups.length - 1];\n return outermost ? { kind: \"unit\", element: outermost } : { kind: \"child\" };\n }\n const idx = groups.indexOf(activeGroupElement);\n if (idx === -1) return { kind: \"out-of-scope\" };\n const nestedInside = groups[idx - 1];\n return nestedInside ? { kind: \"unit\", element: nestedInside } : { kind: \"child\" };\n })();\n return result;\n}\n","/**\n * Element visibility, visual scoring, layer patch targets, element finders,\n * and the `findElementForSelection` / `findElementForTimelineElement` lookups.\n */\nimport type {\n DomEditContextOptions,\n DomEditSelection,\n DomEditViewport,\n TimelineElementDomTarget,\n TimelineElementDomTargetOptions,\n} from \"./domEditingTypes\";\nimport {\n buildStableSelector,\n escapeCssString,\n getSelectorIndex,\n getSourceFileForElement,\n isHtmlElement,\n isElementVisibleThroughAncestors,\n normalizeTimelineCompositionSource,\n querySelectorAllSafely,\n} from \"./domEditingDom\";\n\n// ─── Visibility ──────────────────────────────────────────────────────────────\n\nexport function isElementComputedVisible(\n el: HTMLElement,\n memo?: Map<HTMLElement, boolean>,\n): boolean {\n return isElementVisibleThroughAncestors(el, memo);\n}\n\nconst VISUAL_LEAF_TAGS = new Set([\"img\", \"video\", \"canvas\", \"svg\", \"audio\"]);\n\n// fallow-ignore-next-line complexity\nfunction hasVisualPresence(el: HTMLElement): boolean {\n const win = el.ownerDocument.defaultView;\n if (!win) return false;\n const cs = win.getComputedStyle(el);\n if (cs.backgroundImage !== \"none\") return true;\n if (\n cs.backgroundColor &&\n cs.backgroundColor !== \"transparent\" &&\n cs.backgroundColor !== \"rgba(0, 0, 0, 0)\"\n )\n return true;\n if (cs.borderWidth && parseFloat(cs.borderWidth) > 0 && cs.borderStyle !== \"none\") return true;\n if (cs.boxShadow && cs.boxShadow !== \"none\") return true;\n return false;\n}\n\nfunction isEmptyVisualContainer(el: HTMLElement): boolean {\n const tag = el.tagName.toLowerCase();\n if (VISUAL_LEAF_TAGS.has(tag)) return false;\n if (hasVisualPresence(el)) return false;\n\n const { children } = el;\n if (children.length === 0) {\n return (el.textContent ?? \"\").trim().length === 0;\n }\n\n for (let i = 0; i < children.length; i += 1) {\n const child = children[i];\n if (!isHtmlElement(child)) continue;\n if (VISUAL_LEAF_TAGS.has(child.tagName.toLowerCase())) return false;\n if (isElementComputedVisible(child)) return false;\n }\n\n return true;\n}\n\nfunction hasRenderedBox(el: HTMLElement): boolean {\n const rect = el.getBoundingClientRect();\n if (rect.width <= 1 || rect.height <= 1) return false;\n if (!isElementComputedVisible(el)) return false;\n if (isEmptyVisualContainer(el)) return false;\n return true;\n}\n\n// ─── Visual scoring ──────────────────────────────────────────────────────────\n\n// ─── Layer patch target ──────────────────────────────────────────────────────\n\nconst DOM_LAYER_IGNORED_TAGS = new Set([\n \"base\",\n \"br\",\n \"canvas\",\n \"link\",\n \"meta\",\n \"script\",\n \"source\",\n \"style\",\n \"template\",\n \"track\",\n \"wbr\",\n]);\n\n/**\n * Is the element rendered at all? The half of `getDomLayerPatchTarget` that a\n * plain style write can flip, and the only half that reads computed style.\n * Exported so a caller memoizing a layer walk can give it its own (short)\n * cache lifetime — see `domEditLayerWalkCache`.\n */\nexport function isInspectableLayerElement(el: HTMLElement): boolean {\n const tagName = el.tagName.toLowerCase();\n if (DOM_LAYER_IGNORED_TAGS.has(tagName)) return false;\n\n const computed = el.ownerDocument.defaultView?.getComputedStyle(el);\n if (computed?.display === \"none\" || computed?.visibility === \"hidden\") return false;\n\n return true;\n}\n\n/**\n * How the element is ADDRESSED — its selector, that selector's occurrence index\n * within the source file, and the file itself. Independent of whether the\n * element currently renders, so it survives every style write and moves only\n * when an identity attribute changes or the document's population of elements\n * sharing the selector does.\n */\n/**\n * The selector an element is addressed by, or undefined when it cannot be a\n * layer at all. Sole owner of that rule: `isDomLayerElement` answers the same\n * question without paying for the occurrence index, and a second copy of the\n * conditions would go stale the first time one of them changed.\n */\nfunction resolveLayerSelector(el: HTMLElement): string | undefined {\n if (el.hasAttribute(\"data-composition-id\")) return undefined;\n return buildStableSelector(el);\n}\n\nexport function resolveDomLayerIdentity(\n el: HTMLElement,\n activeCompositionPath: string | null,\n): Pick<DomEditSelection, \"id\" | \"hfId\" | \"selector\" | \"selectorIndex\" | \"sourceFile\"> | null {\n const selector = resolveLayerSelector(el);\n if (!selector) return null;\n\n const { sourceFile } = getSourceFileForElement(el, activeCompositionPath);\n return {\n id: el.id || undefined,\n hfId: el.getAttribute(\"data-hf-id\") || undefined,\n selector,\n selectorIndex: getSelectorIndex(\n el.ownerDocument,\n el,\n selector,\n sourceFile,\n activeCompositionPath,\n ),\n sourceFile,\n };\n}\n\nexport function getDomLayerPatchTarget(\n el: HTMLElement,\n activeCompositionPath: string | null,\n): Pick<DomEditSelection, \"id\" | \"hfId\" | \"selector\" | \"selectorIndex\" | \"sourceFile\"> | null {\n return isInspectableLayerElement(el) ? resolveDomLayerIdentity(el, activeCompositionPath) : null;\n}\n\n/**\n * Is `el` a layer at all? Exactly the condition under which\n * `getDomLayerPatchTarget` returns non-null, for callers that want the yes/no\n * and throw the target away.\n *\n * Worth its own function because the target carries the selector's OCCURRENCE\n * INDEX, and resolving that is a whole-document query — which the yes/no does\n * not depend on. Counting an element's layer children asked for one per child.\n */\nexport function isDomLayerElement(el: HTMLElement): boolean {\n return isInspectableLayerElement(el) && resolveLayerSelector(el) !== undefined;\n}\n\n// ─── Clip ancestor / selection candidate ─────────────────────────────────────\n\nfunction getPreferredClipAncestor(startEl: HTMLElement): HTMLElement | null {\n let current: HTMLElement | null = startEl;\n while (current) {\n if (current.classList.contains(\"clip\")) {\n const isCompositionHost =\n current.hasAttribute(\"data-composition-src\") ||\n current.hasAttribute(\"data-composition-file\");\n if (!isCompositionHost || current === startEl) return current;\n }\n current = current.parentElement;\n }\n return null;\n}\n\nexport function getSelectionCandidate(\n startEl: HTMLElement,\n options: DomEditContextOptions,\n): HTMLElement {\n if (options.preferClipAncestor) {\n const clipAncestor = getPreferredClipAncestor(startEl);\n if (clipAncestor) {\n return clipAncestor;\n }\n }\n\n return startEl;\n}\n\n// ─── Visual target resolution ─────────────────────────────────────────────────\n\nexport function resolveVisualDomEditSelectionTarget(\n elementsFromPoint: Iterable<Element | null | undefined>,\n options: Pick<DomEditContextOptions, \"activeCompositionPath\">,\n): HTMLElement | null {\n const candidates = resolveAllVisualDomEditTargets(elementsFromPoint, options);\n return candidates[0] ?? null;\n}\n\n/**\n * Returns all independently-selectable elements at the given point, in paint\n * order (topmost first). Used for click-cycling through stacked layers.\n *\n * Each entry in the returned array is an independent \"layer\" — an element\n * that is not an ancestor of an earlier entry. This gives one result per\n * z-stacked element rather than one per DOM node.\n */\nexport function resolveAllVisualDomEditTargets(\n elementsFromPoint: Iterable<Element | null | undefined>,\n options: Pick<DomEditContextOptions, \"activeCompositionPath\">,\n): HTMLElement[] {\n const raw: HTMLElement[] = [];\n\n for (const entry of elementsFromPoint) {\n if (!isHtmlElement(entry)) continue;\n if (hasRenderedBox(entry) && getDomLayerPatchTarget(entry, options.activeCompositionPath)) {\n raw.push(entry);\n }\n }\n\n if (raw.length === 0) return [];\n\n // First pass: for each contiguous ancestor-descendant run, keep only the\n // deepest (most specific) element, matching the original single-pick logic.\n const layers: HTMLElement[] = [];\n let best = raw[0];\n for (let i = 1; i < raw.length; i++) {\n const el = raw[i];\n if (best.contains(el)) {\n best = el; // go deeper in this subtree\n } else {\n layers.push(best);\n best = el;\n }\n }\n layers.push(best);\n\n return layers;\n}\n\n// ─── Raster detection ────────────────────────────────────────────────────────\n\nfunction hasRasterBackground(selection: Pick<DomEditSelection, \"computedStyles\">): boolean {\n const backgroundImage = selection.computedStyles[\"background-image\"]?.trim();\n return Boolean(backgroundImage && backgroundImage !== \"none\");\n}\n\nexport function isLargeRasterDomEditSelection(\n selection: Pick<DomEditSelection, \"boundingBox\" | \"computedStyles\" | \"tagName\">,\n viewport?: DomEditViewport | null,\n): boolean {\n const tagName = selection.tagName.toLowerCase();\n const isRasterLike = tagName === \"img\" || hasRasterBackground(selection);\n if (!isRasterLike) return false;\n\n const { width, height } = selection.boundingBox;\n if (width <= 1 || height <= 1) return false;\n if (!viewport || viewport.width <= 1 || viewport.height <= 1) {\n return width >= 960 && height >= 540;\n }\n\n const areaRatio = (width * height) / (viewport.width * viewport.height);\n const widthRatio = width / viewport.width;\n const heightRatio = height / viewport.height;\n return areaRatio >= 0.4 || (widthRatio >= 0.7 && heightRatio >= 0.5);\n}\n\n// ─── Element finders ──────────────────────────────────────────────────────────\n\ntype FindElementSelection = Pick<DomEditSelection, \"id\" | \"hfId\" | \"selector\" | \"selectorIndex\"> & {\n sourceFile?: string;\n};\n\nexport function findElementForSelection(\n doc: Document,\n selection: FindElementSelection,\n activeCompositionPath: string | null = null,\n): HTMLElement | null {\n const sourceMatches = (candidate: Element): candidate is HTMLElement =>\n isHtmlElement(candidate) &&\n (!selection.sourceFile ||\n getSourceFileForElement(candidate, activeCompositionPath).sourceFile ===\n selection.sourceFile);\n const findAll = (selector: string): HTMLElement[] =>\n querySelectorAllSafely(doc, selector).filter(sourceMatches);\n\n if (selection.hfId) {\n const byHfId = findAll(`[data-hf-id=\"${escapeCssString(selection.hfId)}\"]`)[0];\n if (byHfId) return byHfId;\n }\n\n if (selection.id) {\n // Flattened sub-compositions can repeat authored ids. getElementById returns\n // only the first document match, so filter every id match by source first.\n const byId = findAll(`[id=\"${escapeCssString(selection.id)}\"]`)[0];\n if (byId) return byId;\n }\n\n if (!selection.selector) return null;\n return findAll(selection.selector)[selection.selectorIndex ?? 0] ?? null;\n}\n\n// The selected node while mounted, else its copy in the selection's own file (ids repeat across files), else any copy.\nexport function findPreviewNode(\n doc: Document | null | undefined,\n el: DomEditSelection,\n): Element | null {\n if (!doc) return null;\n if (el.element?.isConnected && el.element.ownerDocument === doc) return el.element;\n return (\n findElementForSelection(doc, el) ??\n findElementForSelection(doc, { ...el, sourceFile: undefined })\n );\n}\n\n// fallow-ignore-next-line complexity\nexport function findElementForTimelineElement(\n doc: Document,\n element: TimelineElementDomTarget,\n options: TimelineElementDomTargetOptions,\n): HTMLElement | null {\n const elementId = typeof element.id === \"string\" ? element.id : \"\";\n const compositionSource =\n normalizeTimelineCompositionSource(element.compositionSrc) ??\n options.compIdToSrc?.get(elementId);\n const sourceFile =\n compositionSource ??\n normalizeTimelineCompositionSource(element.sourceFile) ??\n options.activeCompositionPath ??\n \"index.html\";\n const escapedElementId = escapeCssString(elementId);\n const escapedCompositionSource = compositionSource ? escapeCssString(compositionSource) : null;\n const selector =\n element.selector ??\n (compositionSource\n ? `[data-composition-src=\"${escapedCompositionSource}\"],[data-composition-file=\"${escapedCompositionSource}\"],[data-composition-id=\"${escapedElementId}\"]`\n : escapedElementId\n ? `[data-composition-id=\"${escapedElementId}\"]`\n : undefined);\n\n if (selector || element.domId) {\n const targetElement = findElementForSelection(\n doc,\n {\n id: element.domId ?? undefined,\n selector,\n selectorIndex: element.selectorIndex,\n sourceFile,\n },\n options.activeCompositionPath,\n );\n if (targetElement) return targetElement;\n }\n\n const hasExplicitDomTarget = Boolean(element.domId || element.selector || compositionSource);\n if (options.isMasterView || hasExplicitDomTarget || !options.activeCompositionPath) {\n return null;\n }\n\n const root = doc.querySelector(\"[data-composition-id]\");\n if (!isHtmlElement(root)) return null;\n return getSourceFileForElement(root, options.activeCompositionPath).sourceFile === sourceFile\n ? root\n : null;\n}\n\n// ─── Layer children ───────────────────────────────────────────────────────────\n\n/** `el`'s direct children that are layers. No longer takes the context options:\n * layer-ness does not depend on the active composition path. */\nexport function getDirectLayerChildren(el: HTMLElement): HTMLElement[] {\n return Array.from(el.children).filter(\n (child): child is HTMLElement => isHtmlElement(child) && isDomLayerElement(child),\n );\n}\n","import { parsePx } from \"./domEditingDom\";\n\nconst COMPOSITION_ROOT_LAYER_EPSILON_PX = 1;\n\nfunction readPositiveDimension(value: string | null): number | null {\n if (!value) return null;\n const parsed = Number.parseFloat(value);\n return Number.isFinite(parsed) && parsed > 0 ? parsed : null;\n}\n\nfunction approximatelyEqual(a: number, b: number) {\n return Math.abs(a - b) <= COMPOSITION_ROOT_LAYER_EPSILON_PX;\n}\n\nfunction getCompositionRootBounds(doc: Document) {\n const root =\n doc.querySelector<HTMLElement>(\"[data-composition-id]\") ?? doc.documentElement ?? null;\n const rootWidth = readPositiveDimension(root?.getAttribute(\"data-width\") ?? null);\n const rootHeight = readPositiveDimension(root?.getAttribute(\"data-height\") ?? null);\n if (!root || !rootWidth || !rootHeight) return null;\n return { rect: root.getBoundingClientRect(), width: rootWidth, height: rootHeight };\n}\n\nfunction getRenderedLayerSize(element: HTMLElement, computedStyles: Record<string, string>) {\n const rect = element.getBoundingClientRect();\n const width = rect.width || parsePx(computedStyles.width);\n const height = rect.height || parsePx(computedStyles.height);\n return width && height ? { width, height } : null;\n}\n\nfunction matchesCompositionRootBounds(\n elementRect: DOMRect,\n elementSize: { width: number; height: number },\n rootBounds: { rect: DOMRect; width: number; height: number },\n) {\n return (\n approximatelyEqual(elementRect.left, rootBounds.rect.left) &&\n approximatelyEqual(elementRect.top, rootBounds.rect.top) &&\n approximatelyEqual(elementSize.width, rootBounds.width) &&\n approximatelyEqual(elementSize.height, rootBounds.height)\n );\n}\n\nfunction isExplicitFullBleedLayer(computedStyles: Record<string, string>) {\n return computedStyles.position === \"absolute\" || computedStyles.position === \"fixed\";\n}\n\nexport function isCompositionRootLayer(\n element: HTMLElement,\n doc: Document,\n computedStyles: Record<string, string>,\n) {\n if (element.parentElement !== doc.body) return false;\n if (element.hasAttribute(\"data-hf-allow-root-edit\")) return false;\n if (isExplicitFullBleedLayer(computedStyles)) return false;\n\n const rootBounds = getCompositionRootBounds(doc);\n const elementSize = getRenderedLayerSize(element, computedStyles);\n return Boolean(\n rootBounds &&\n elementSize &&\n matchesCompositionRootBounds(element.getBoundingClientRect(), elementSize, rootBounds),\n );\n}\n","/**\n * Incremental memory for `collectDomEditLayerItems`.\n *\n * The layer walk is re-run from scratch every time a MutationObserver says the\n * preview changed, and the observer's loudest source is inline `style` — which\n * is exactly what animation writes. So a paused-looking editor re-derived every\n * element's patch target, label and child count several times a second, and each\n * derivation costs two `getComputedStyle` reads (its own plus one per direct\n * child), two ancestor walks for the source file, and a `textContent` read whose\n * cost is the element's whole subtree.\n *\n * None of that depends on the traversal — only on the element. So the traversal\n * stays live (it is pointer-chasing, and `depth` genuinely is positional) and the\n * per-element half is memoized, with the mutation records deciding what to drop.\n *\n * WHAT MAKES A CACHED ENTRY WRONG, and how each is caught:\n *\n * - the element's own attributes (`style` -> computed display, `class`/`id`/\n * `data-hf-group` -> selector and label) -> attribute record on it\n * - an ancestor's `visibility`, the ONLY inherited input to the\n * display/visibility gate (`display:none` on an ancestor does not change a\n * descendant's own computed `display`) -> attribute record on the\n * ancestor, whose subtree is\n * dropped only when the\n * style declares visibility\n * - a direct child appearing or disappearing from the layer list, which moves\n * the parent's `childCount` -> the parent is dropped\n * alongside every element\n * - descendant text, which moves an ancestor's label -> characterData record,\n * ancestors dropped\n * - selector occurrence indices, which shift for EVERY element sharing a\n * selector when one element's identity changes -> whole cache dropped\n * - nodes added or removed, which shift indices, order, labels and counts at\n * once and cannot be attributed to one element -> whole cache dropped\n * - a different active composition path, or a new composition-id -> source-file\n * map, both of which re-scope every source file -> checked per walk\n *\n * The bias is deliberate and matches the duration cache in the runtime: a\n * redundant recomputation is a missed optimisation, a missed one is a wrong\n * layer tree.\n */\n\nimport { buildElementLabel, getCompositionSourceMapRevision, isHtmlElement } from \"./domEditingDom\";\nimport {\n getDirectLayerChildren,\n isInspectableLayerElement,\n resolveDomLayerIdentity,\n} from \"./domEditingElement\";\nimport type { DomEditSelection } from \"./domEditingTypes\";\n\n/** How an element is addressed. Survives style writes; see `readIdentity`. */\nexport type DomEditLayerIdentity = Pick<\n DomEditSelection,\n \"id\" | \"hfId\" | \"selector\" | \"selectorIndex\" | \"sourceFile\"\n>;\n\n/** Whether the element renders, and how many of its direct children are layers.\n * Both are computed style reads, and both a style write can flip. Filled\n * lazily: `childCount` is only asked for once an element is known to be one. */\ninterface PresenceMemo {\n inspectable?: boolean;\n childCount?: number;\n}\n\ninterface IdentityMemo {\n identity?: DomEditLayerIdentity | null;\n label?: string;\n}\n\n/**\n * Attributes that decide an element's SELECTOR, and therefore the occurrence\n * index of every other element sharing that selector. One of these changing\n * renumbers elements the record does not mention, so the only sound response is\n * to drop everything. `class` is here because `buildStableSelector` falls back\n * to the preferred class.\n */\nconst SELECTOR_IDENTITY_ATTRIBUTES = new Set([\n \"id\",\n \"class\",\n \"data-hf-group\",\n \"data-composition-id\",\n \"data-composition-file\",\n \"data-composition-src\",\n \"data-hf-original-composition-id\",\n]);\n\n/**\n * The observer configuration the cache's invalidation is written against.\n * Exported so the refresh loop and the tests cannot drift from it.\n *\n * No `attributeFilter`: an unlisted attribute is one the cache would never learn\n * about, and serving a stale entry is worse than the extra records.\n */\nexport const DOM_EDIT_LAYER_OBSERVER_INIT: MutationObserverInit = {\n attributes: true,\n characterData: true,\n childList: true,\n subtree: true,\n};\n\n/**\n * The inline `visibility` each element last presented. Deliberately NOT cleared\n * by `invalidateAll`: it records what the DOM said, not a value derived from it.\n */\nconst lastInlineVisibility = new WeakMap<HTMLElement, string>();\n\n/**\n * Did this style write move the element's inline `visibility`?\n *\n * `visibility` is inherited, so changing it changes the layer-list membership of\n * the element's whole subtree, and only then is the subtree worth dropping.\n *\n * The comparison is on the PARSED value, remembered per element. Testing the\n * attribute TEXT for \"visibility\" looks equivalent and is not: the standard\n * GSAP fade (`autoAlpha`) writes `visibility: visible` once and leaves it in the\n * attribute for the rest of the clip, so a text test stays true for every\n * transform tick afterwards. That is a whole-subtree walk per animation frame,\n * in the observer callback rather than behind the rebuild throttle, on exactly\n * the elements a composition animates most.\n *\n * An element seen for the first time reports changed, which costs one drop and\n * is the safe answer: its entries were derived before this write.\n */\nfunction inlineVisibilityChanged(el: HTMLElement): boolean {\n const next = el.style.visibility;\n if (lastInlineVisibility.get(el) === next) return false;\n lastInlineVisibility.set(el, next);\n return true;\n}\n\nexport interface DomEditLayerWalkCache {\n /**\n * Start a walk. Drops everything when the scoping inputs the entries were\n * built under no longer hold. Call once per `collectDomEditLayerItems`.\n */\n beginWalk(activeCompositionPath: string | null): void;\n /**\n * Does `el` render? Cheap to invalidate and invalidated often: any attribute\n * write on the element, on its parent, or a `visibility` write on an ancestor\n * drops it, because all three can flip the answer.\n */\n readInspectable(el: HTMLElement, compute: () => boolean): boolean;\n /** How many of `el`'s direct children are layers. Same lifetime as\n * `readInspectable`: it is a sum over their answers. */\n readChildCount(el: HTMLElement, compute: () => number): number;\n /**\n * `el`'s selector, occurrence index and source file. A SEPARATE, much longer\n * lifetime than presence: a style write cannot renumber a selector, so this\n * survives one, and it is the only part of the walk that queries the\n * document. That split is what makes an ordinary animation frame cost no\n * document queries at all.\n */\n readIdentity(\n el: HTMLElement,\n compute: () => DomEditLayerIdentity | null,\n ): DomEditLayerIdentity | null;\n /** `el`'s display label. Shares the identity lifetime, plus descendant text. */\n readLabel(el: HTMLElement, compute: () => string): string;\n /** Apply mutation records. Safe to call with an empty array. */\n ingest(records: MutationRecord[]): void;\n /** Forget every entry — the fallback for anything not attributable. */\n invalidateAll(): void;\n}\n\nexport function createDomEditLayerWalkCache(): DomEditLayerWalkCache {\n let presence = new WeakMap<HTMLElement, PresenceMemo>();\n let identities = new WeakMap<HTMLElement, IdentityMemo>();\n let scope: string | null = null;\n\n const invalidateAll = () => {\n presence = new WeakMap();\n identities = new WeakMap();\n };\n\n const drop = (el: HTMLElement | null) => {\n if (el) presence.delete(el);\n };\n\n const dropSubtree = (el: HTMLElement) => {\n for (const descendant of el.querySelectorAll(\"*\")) {\n if (isHtmlElement(descendant)) presence.delete(descendant);\n }\n };\n\n const ingestOne = (record: MutationRecord): boolean => {\n // Structural change: order, occurrence indices, labels and child counts all\n // move at once, and the record names the parent rather than everything\n // affected. This is the documented full-rebuild fallback.\n if (record.type === \"childList\") return false;\n\n if (record.type === \"characterData\") {\n // `buildElementLabel` falls back to `textContent`, so edited text changes\n // the label of every ancestor that contains it.\n for (\n let ancestor = record.target.parentElement;\n ancestor;\n ancestor = ancestor.parentElement\n ) {\n identities.delete(ancestor);\n }\n return true;\n }\n\n const target = record.target;\n if (!isHtmlElement(target)) return true;\n if (record.attributeName && SELECTOR_IDENTITY_ATTRIBUTES.has(record.attributeName))\n return false;\n\n drop(target);\n // The parent counts its layer children, and this element may have just\n // joined or left that count.\n drop(target.parentElement);\n if (record.attributeName === \"style\" && inlineVisibilityChanged(target)) dropSubtree(target);\n return true;\n };\n\n return {\n beginWalk(activeCompositionPath) {\n const nextScope = `${activeCompositionPath ?? \"\"}|${getCompositionSourceMapRevision()}`;\n if (nextScope === scope) return;\n scope = nextScope;\n invalidateAll();\n },\n readInspectable(el, compute) {\n const memo = presence.get(el) ?? {};\n if (memo.inspectable === undefined) {\n memo.inspectable = compute();\n presence.set(el, memo);\n }\n return memo.inspectable;\n },\n readChildCount(el, compute) {\n const memo = presence.get(el) ?? {};\n if (memo.childCount === undefined) {\n memo.childCount = compute();\n presence.set(el, memo);\n }\n return memo.childCount;\n },\n readIdentity(el, compute) {\n const memo = identities.get(el) ?? {};\n if (memo.identity === undefined) {\n memo.identity = compute();\n identities.set(el, memo);\n }\n return memo.identity;\n },\n readLabel(el, compute) {\n const memo = identities.get(el) ?? {};\n if (memo.label === undefined) {\n memo.label = compute();\n identities.set(el, memo);\n }\n return memo.label;\n },\n ingest(records) {\n for (const record of records) {\n if (!ingestOne(record)) {\n invalidateAll();\n return;\n }\n }\n },\n invalidateAll,\n };\n}\n\n/** One element's contribution to a layer walk. `depth` is absent on purpose: it\n * belongs to the traversal, not to the element. */\nexport interface DomEditLayerWalkEntry {\n target: DomEditLayerIdentity;\n label: string;\n childCount: number;\n}\n\n/**\n * Everything `collectDomEditLayerItems` needs about ONE element, served from\n * `cache` where it is still valid. Null when the element is not a layer.\n *\n * The four reads go through the cache separately rather than as one record\n * because they do not go stale together: a style write flips whether an element\n * renders without touching how it is addressed. Without a cache this is exactly\n * the original per-element derivation, which is what every other caller of the\n * walk still gets.\n *\n * Lives here rather than in the walk so the two halves of the memoization —\n * what is stored and what is read — sit in one file.\n */\nexport function readDomEditLayerWalkEntry(\n el: HTMLElement,\n activeCompositionPath: string | null,\n cache?: DomEditLayerWalkCache,\n): DomEditLayerWalkEntry | null {\n const inspectable = cache\n ? cache.readInspectable(el, () => isInspectableLayerElement(el))\n : isInspectableLayerElement(el);\n if (!inspectable) return null;\n\n const identity = () => resolveDomLayerIdentity(el, activeCompositionPath);\n const target = cache ? cache.readIdentity(el, identity) : identity();\n if (!target) return null;\n\n const label = () => buildElementLabel(el);\n const childCount = () => getDirectLayerChildren(el).length;\n return {\n target,\n label: cache ? cache.readLabel(el, label) : label(),\n childCount: cache ? cache.readChildCount(el, childCount) : childCount(),\n };\n}\n\n/**\n * Apply the records the observer has taken in but not yet delivered.\n *\n * Records arrive in a microtask, so an edit made earlier in THIS task would\n * otherwise be read back against entries that predate it. Taking them suppresses\n * the observer's own callback for them, which is equivalent here: that callback\n * only ingests and marks a rebuild owed, and a caller draining is rebuilding\n * regardless. A caller with no observer yet has nothing pending.\n */\nexport function drainPendingLayerMutations(\n observer: MutationObserver | null,\n cache: DomEditLayerWalkCache,\n): void {\n if (!observer) return;\n cache.ingest(observer.takeRecords());\n}\n"],"mappings":"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","names":[]}
|
|
@@ -12,7 +12,6 @@ import {
|
|
|
12
12
|
getDomEditLayerKey,
|
|
13
13
|
getDomEditNonEditableReason,
|
|
14
14
|
getDomEditTargetKey,
|
|
15
|
-
isEditableTextLeaf,
|
|
16
15
|
isTextEditableSelection,
|
|
17
16
|
liveLayerElement,
|
|
18
17
|
readHfId,
|
|
@@ -20,8 +19,8 @@ import {
|
|
|
20
19
|
resolveDomEditCapabilities,
|
|
21
20
|
resolveDomEditSelection,
|
|
22
21
|
serializeDomEditTextFields
|
|
23
|
-
} from "./chunk-
|
|
24
|
-
import "./chunk-
|
|
22
|
+
} from "./chunk-TXZMMOMA.js";
|
|
23
|
+
import "./chunk-5EKWJZLM.js";
|
|
25
24
|
import "./chunk-PZ5AY32C.js";
|
|
26
25
|
export {
|
|
27
26
|
buildDefaultDomEditTextField,
|
|
@@ -37,7 +36,6 @@ export {
|
|
|
37
36
|
getDomEditLayerKey,
|
|
38
37
|
getDomEditNonEditableReason,
|
|
39
38
|
getDomEditTargetKey,
|
|
40
|
-
isEditableTextLeaf,
|
|
41
39
|
isTextEditableSelection,
|
|
42
40
|
liveLayerElement,
|
|
43
41
|
readHfId,
|
|
@@ -46,4 +44,4 @@ export {
|
|
|
46
44
|
resolveDomEditSelection,
|
|
47
45
|
serializeDomEditTextFields
|
|
48
46
|
};
|
|
49
|
-
//# sourceMappingURL=domEditingLayers-
|
|
47
|
+
//# sourceMappingURL=domEditingLayers-D7VYFJJD.js.map
|
package/dist/studio/index.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
export { Button, ButtonSize, ButtonVariant, ContextMenu, HyperframesLoader, HyperframesLoaderProps, HyperframesLogo, IconButton, Input, InputProps, Menu, MenuItem, MenuItemTone, MenuRadioGroup, MenuRadioItem, MenuSeparator, MenuShortcut, NumberField, NumberFieldProps, Popover, PopupPreviewState, PreviewState, Select, SelectOption, SelectProps, Slider, SliderProps, Tab, TabPanel, Tabs, TabsList, Toggle, ToggleProps, Tooltip, buttonBase, buttonSizes, buttonVariants, cn, fieldBase, fieldText, popupSurface } from './ui.js';
|
|
2
|
-
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
3
2
|
import * as react from 'react';
|
|
4
3
|
import { RefObject, MutableRefObject, ReactNode, DragEventHandler, ComponentProps, RefCallback, MouseEvent, CSSProperties, UIEvent, PointerEvent } from 'react';
|
|
5
4
|
import { RuntimeTimelineClipIdentity, HyperframePickerElementInfo } from '@hyperframes/core';
|
|
6
5
|
import { GsapAnimation, ParsedGsap, PropertyGroupName } from '@hyperframes/core/gsap-parser';
|
|
7
6
|
import { GsapAnimation as GsapAnimation$1, ArcPathSegment } from '@hyperframes/parsers/gsap-parser';
|
|
8
7
|
import { Composition } from '@hyperframes/sdk';
|
|
8
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
9
9
|
import * as zustand from 'zustand';
|
|
10
10
|
import { StoreApi } from 'zustand';
|
|
11
11
|
export { Player } from './player.js';
|
|
@@ -386,6 +386,16 @@ interface TimelineElement {
|
|
|
386
386
|
authoredStartIsMasterTime?: boolean;
|
|
387
387
|
/** Legacy marker for an inline sub-composition child; current rows never set it. */
|
|
388
388
|
expandedHostKey?: string;
|
|
389
|
+
/** A text layer's words and look, which its row draws live instead of a captured picture. */
|
|
390
|
+
text?: TimelineText;
|
|
391
|
+
}
|
|
392
|
+
interface TimelineText {
|
|
393
|
+
value: string;
|
|
394
|
+
fontFamily?: string;
|
|
395
|
+
fontWeight?: string;
|
|
396
|
+
color?: string;
|
|
397
|
+
/** The layer's own opaque background colour, when it paints one. */
|
|
398
|
+
background?: string;
|
|
389
399
|
}
|
|
390
400
|
/**
|
|
391
401
|
* The fields `updateElement` may write.
|
|
@@ -399,7 +409,7 @@ interface TimelineElement {
|
|
|
399
409
|
* write has to be able to land here or the header goes on rendering whatever it
|
|
400
410
|
* parsed at load.
|
|
401
411
|
*/
|
|
402
|
-
type TimelineElementPatch = Partial<Pick<TimelineElement, "start" | "duration" | "track" | "zIndex" | "hasExplicitZIndex" | "playbackStart" | "hidden" | "audioGroup" | "audioGroupLabel" | "audioGroupVolume" | "audioGroupHidden" | "audioGroupFxChain" | "audioGroupAutomation">>;
|
|
412
|
+
type TimelineElementPatch = Partial<Pick<TimelineElement, "start" | "duration" | "track" | "zIndex" | "hasExplicitZIndex" | "playbackStart" | "hidden" | "audioGroup" | "audioGroupLabel" | "audioGroupVolume" | "audioGroupHidden" | "audioGroupFxChain" | "audioGroupAutomation" | "text">>;
|
|
403
413
|
/**
|
|
404
414
|
* The `data-*` state an expanded sub-composition child needs but cannot reach.
|
|
405
415
|
*
|
|
@@ -805,7 +815,7 @@ interface TimelineStackingReorderIntent {
|
|
|
805
815
|
zIndexChanges: TimelineStackingZIndexChange[];
|
|
806
816
|
}
|
|
807
817
|
|
|
808
|
-
type BlockedTimelineEditIntent = "move" | "resize-start" | "resize-end";
|
|
818
|
+
type BlockedTimelineEditIntent = "move" | "edit-many" | "resize-start" | "resize-end";
|
|
809
819
|
interface TimelineRangeSelection {
|
|
810
820
|
start: number;
|
|
811
821
|
end: number;
|
|
@@ -926,9 +936,12 @@ type RuntimeTweenChange = {
|
|
|
926
936
|
props: SetPatchProps;
|
|
927
937
|
};
|
|
928
938
|
|
|
939
|
+
type KeyframeUsageAction = "add" | "convert" | "remove_all" | "reset";
|
|
940
|
+
|
|
929
941
|
interface MutationResult {
|
|
930
942
|
ok: boolean;
|
|
931
943
|
changed?: boolean;
|
|
944
|
+
mutationChanges?: boolean[];
|
|
932
945
|
parsed?: ParsedGsap;
|
|
933
946
|
before?: string;
|
|
934
947
|
after?: string;
|
|
@@ -936,6 +949,9 @@ interface MutationResult {
|
|
|
936
949
|
}
|
|
937
950
|
interface CommitMutationOptions {
|
|
938
951
|
label: string;
|
|
952
|
+
keyframeTelemetry?: boolean;
|
|
953
|
+
keyframeAction?: KeyframeUsageAction;
|
|
954
|
+
keyframeProperty?: string;
|
|
939
955
|
/** Observe the durable writer result without duplicating the request path. */
|
|
940
956
|
onResult?: (result: MutationResult) => void;
|
|
941
957
|
coalesceKey?: string;
|
|
@@ -1143,6 +1159,7 @@ interface TimelineEditCallbacks {
|
|
|
1143
1159
|
onRazorSplit?: (element: TimelineElement, splitTime: number) => Promise<void> | void;
|
|
1144
1160
|
onRazorSplitAll?: (splitTime: number) => Promise<void> | void;
|
|
1145
1161
|
onFreezeFrame?: (element: TimelineElement, time: number) => Promise<void> | void;
|
|
1162
|
+
clipMenuTools?: boolean;
|
|
1146
1163
|
onNotice?: (message: string, tone?: "error" | "info") => void;
|
|
1147
1164
|
onDeleteKeyframe?: (elementId: string, keyframe: TimelineKeyframeTarget) => void;
|
|
1148
1165
|
onDeleteAllKeyframes?: (element: TimelineElement, animationId?: string) => void;
|
|
@@ -2008,7 +2025,7 @@ interface EditorShellProps extends TimelineEditCallbackDeps {
|
|
|
2008
2025
|
/** Short text shown on disabled hand-edit controls while `readOnlyPreview` is set. */
|
|
2009
2026
|
readOnlyPreviewReason?: string;
|
|
2010
2027
|
}
|
|
2011
|
-
declare
|
|
2028
|
+
declare const EditorShell: react.NamedExoticComponent<EditorShellProps>;
|
|
2012
2029
|
|
|
2013
2030
|
interface PreviewCompositionSize {
|
|
2014
2031
|
width: number;
|
|
@@ -2293,6 +2310,11 @@ interface SourceEditorProps {
|
|
|
2293
2310
|
}
|
|
2294
2311
|
declare const SourceEditor: react.NamedExoticComponent<SourceEditorProps>;
|
|
2295
2312
|
|
|
2313
|
+
interface GeometryCommitResult {
|
|
2314
|
+
ok: true;
|
|
2315
|
+
changed: boolean;
|
|
2316
|
+
}
|
|
2317
|
+
|
|
2296
2318
|
/**
|
|
2297
2319
|
* Edit callbacks shared by GsapAnimationSection and each AnimationCard it
|
|
2298
2320
|
* renders. Extracted so the two prop interfaces don't duplicate the (large)
|
|
@@ -2391,14 +2413,14 @@ interface PropertyPanelProps {
|
|
|
2391
2413
|
y: number;
|
|
2392
2414
|
}, route?: {
|
|
2393
2415
|
plainTranslate: boolean;
|
|
2394
|
-
}) => void | Promise<void>;
|
|
2416
|
+
}) => void | Promise<void | GeometryCommitResult>;
|
|
2395
2417
|
onSetManualSize: (element: DomEditSelection, next: {
|
|
2396
2418
|
width: number;
|
|
2397
2419
|
height: number;
|
|
2398
|
-
}) => void | Promise<void>;
|
|
2420
|
+
}) => void | Promise<void | GeometryCommitResult>;
|
|
2399
2421
|
onSetManualRotation: (element: DomEditSelection, next: {
|
|
2400
2422
|
angle: number;
|
|
2401
|
-
}) => void | Promise<void>;
|
|
2423
|
+
}) => void | Promise<void | GeometryCommitResult>;
|
|
2402
2424
|
onSetText: (value: string, fieldKey?: string) => void;
|
|
2403
2425
|
onSetTextFieldStyle: (fieldKey: string, property: string, value: string) => void;
|
|
2404
2426
|
onPreviewTextFieldStyle?: (fieldKey: string, property: string, value: string) => void;
|
|
@@ -2793,7 +2815,7 @@ declare function useTimelineEditing({ projectId, activeCompPath, timelineElement
|
|
|
2793
2815
|
handleTimelineAssetDrop: (assetPath: string, placement: TimelineDropPlacement, durationOverride?: number | undefined) => Promise<void>;
|
|
2794
2816
|
handleTimelineFileDrop: (files: File[], placement?: TimelineDropPlacement | undefined) => Promise<void>;
|
|
2795
2817
|
handleTimelineCompositionDrop: (sourcePath: string, placement: Pick<TimelineElement, "track" | "start">) => Promise<void>;
|
|
2796
|
-
handleBlockedTimelineEdit: (element: TimelineElement) => void;
|
|
2818
|
+
handleBlockedTimelineEdit: (element: TimelineElement, intent: BlockedTimelineEditIntent) => void;
|
|
2797
2819
|
handleTimelineGroupMove: (changes: TimelineGroupMoveChange[], options?: TimelineGroupCommitOptions | undefined) => Promise<void>;
|
|
2798
2820
|
handleTimelineGroupResize: (changes: TimelineGroupResizeChange[], options?: TimelineGroupCommitOptions | undefined) => Promise<void>;
|
|
2799
2821
|
restoreLiveLanes: (restore: Parameters<(restore: LiveLaneRestore) => void>[0]) => void;
|
|
@@ -2991,7 +3013,7 @@ interface TimelineToolbarProps {
|
|
|
2991
3013
|
/** Hides Add keyframe and auto-record, and turns off auto-record and the K shortcut with them. */
|
|
2992
3014
|
showKeyframes?: boolean;
|
|
2993
3015
|
}
|
|
2994
|
-
declare
|
|
3016
|
+
declare const TimelineToolbar: react.NamedExoticComponent<TimelineToolbarProps>;
|
|
2995
3017
|
|
|
2996
3018
|
interface AudioMeterStripProps {
|
|
2997
3019
|
/** Pass a stable ref (useRef): a new object each render restarts the meter loop. */
|
|
@@ -3190,6 +3212,10 @@ interface SnapGuideOverlayProps {
|
|
|
3190
3212
|
}
|
|
3191
3213
|
declare const SnapGuideOverlay: react.NamedExoticComponent<SnapGuideOverlayProps>;
|
|
3192
3214
|
|
|
3215
|
+
interface DomSelectionResult {
|
|
3216
|
+
changed: boolean;
|
|
3217
|
+
count: number;
|
|
3218
|
+
}
|
|
3193
3219
|
interface ApplyDomSelectionOptions {
|
|
3194
3220
|
revealPanel?: boolean;
|
|
3195
3221
|
additive?: boolean;
|
|
@@ -3250,6 +3276,7 @@ type DomEditCommitDeclineReason = "no-project" | "no-selection" | "geometry-prop
|
|
|
3250
3276
|
type DomEditCommitOutcome = {
|
|
3251
3277
|
ok: true;
|
|
3252
3278
|
persistence?: DomEditPersistOutcome;
|
|
3279
|
+
changed?: boolean;
|
|
3253
3280
|
} | {
|
|
3254
3281
|
ok: false;
|
|
3255
3282
|
reason: DomEditCommitDeclineReason;
|
|
@@ -3338,8 +3365,8 @@ declare function useDomEditSession({ projectId, activeCompPath, compIdToSrc, cap
|
|
|
3338
3365
|
handleDomPathOffsetCommit: (selection: DomEditSelection, next: {
|
|
3339
3366
|
x: number;
|
|
3340
3367
|
y: number;
|
|
3341
|
-
}, modifiers?: MoveCommitOptions) => Promise<
|
|
3342
|
-
handleDomGroupPathOffsetCommit: (updates: DomEditGroupPathOffsetCommit[]) => Promise<
|
|
3368
|
+
}, modifiers?: MoveCommitOptions) => Promise<GeometryCommitResult | undefined>;
|
|
3369
|
+
handleDomGroupPathOffsetCommit: (updates: DomEditGroupPathOffsetCommit[]) => Promise<GeometryCommitResult>;
|
|
3343
3370
|
handleDomZIndexReorderCommit: (entries: Array<{
|
|
3344
3371
|
element: HTMLElement;
|
|
3345
3372
|
zIndex: number;
|
|
@@ -3355,9 +3382,9 @@ declare function useDomEditSession({ projectId, activeCompPath, compIdToSrc, cap
|
|
|
3355
3382
|
}, offset?: {
|
|
3356
3383
|
x: number;
|
|
3357
3384
|
y: number;
|
|
3358
|
-
}, restore?: () => void) => Promise<
|
|
3359
|
-
handleDomRotationCommit: (selection: DomEditSelection, next: RotationCommit) => Promise<
|
|
3360
|
-
handleDomManualEditsReset: (selection: DomEditSelection) => Promise<
|
|
3385
|
+
}, restore?: () => void) => Promise<GeometryCommitResult>;
|
|
3386
|
+
handleDomRotationCommit: (selection: DomEditSelection, next: RotationCommit) => Promise<GeometryCommitResult | undefined>;
|
|
3387
|
+
handleDomManualEditsReset: (selection: DomEditSelection) => Promise<DomEditPersistOutcome | undefined>;
|
|
3361
3388
|
handleDomTextCommit: (value: string, fieldKey?: string) => Promise<DomEditCommitOutcome>;
|
|
3362
3389
|
handleDomTextCommitForSelection: (selection: DomEditSelection, value: string, fieldKey?: string) => Promise<DomEditCommitOutcome>;
|
|
3363
3390
|
handleDomRichTextCommit: ({ element, html, previousHtml }: InlineTextEditCommit) => Promise<void>;
|
|
@@ -3378,7 +3405,7 @@ declare function useDomEditSession({ projectId, activeCompPath, compIdToSrc, cap
|
|
|
3378
3405
|
buildDomSelectionFromTarget: (target: HTMLElement, options?: ResolveDomSelectionOptions) => Promise<DomEditSelection | null>;
|
|
3379
3406
|
buildDomSelectionForTimelineElement: (element: TimelineElement) => Promise<DomEditSelection | null>;
|
|
3380
3407
|
updateDomEditHoverSelection: (selection: DomEditSelection | null) => void;
|
|
3381
|
-
applyMarqueeSelection: (selections: DomEditSelection[], additive: boolean) =>
|
|
3408
|
+
applyMarqueeSelection: (selections: DomEditSelection[], additive: boolean) => DomSelectionResult;
|
|
3382
3409
|
resolveImportedFontAsset: (fontFamilyValue: string) => ImportedFontAsset | null;
|
|
3383
3410
|
setAgentModalOpen: react.Dispatch<react.SetStateAction<boolean>>;
|
|
3384
3411
|
setAgentPromptSelectionContext: react.Dispatch<react.SetStateAction<string | undefined>>;
|
|
@@ -3410,7 +3437,7 @@ declare function useDomEditSession({ projectId, activeCompPath, compIdToSrc, cap
|
|
|
3410
3437
|
to: number;
|
|
3411
3438
|
}>, selectionOverride?: DomEditSelection | null) => Promise<boolean>;
|
|
3412
3439
|
handleGsapConvertToKeyframes: (animId: string, resolvedFromValues?: Record<string, number | string>, duration?: number, commitOverrides?: Partial<CommitMutationOptions>, selectionOverride?: DomEditSelection | null) => Promise<void>;
|
|
3413
|
-
handleGsapRemoveAllKeyframes: (animId: string, selectionOverride?: DomEditSelection | null) => Promise<boolean>;
|
|
3440
|
+
handleGsapRemoveAllKeyframes: (animId: string, selectionOverride?: DomEditSelection | null, telemetry?: boolean) => Promise<boolean>;
|
|
3414
3441
|
handleResetSelectedElementKeyframes: () => boolean;
|
|
3415
3442
|
handleUpdateKeyframeEase: (animationId: string, percentage: number, ease: string) => void;
|
|
3416
3443
|
handleUpdateSegmentEase: (targets: AnimationKeyframeTarget[], ease: string) => void;
|
|
@@ -3446,10 +3473,7 @@ declare function useDomEditSession({ projectId, activeCompPath, compIdToSrc, cap
|
|
|
3446
3473
|
handleUnroll: () => void;
|
|
3447
3474
|
invalidateGsapCache: () => void;
|
|
3448
3475
|
previewIframeRef: react.MutableRefObject<HTMLIFrameElement | null>;
|
|
3449
|
-
commitMutation: (mutation: Record<string, unknown>, options:
|
|
3450
|
-
label: string;
|
|
3451
|
-
softReload?: boolean;
|
|
3452
|
-
}) => Promise<void>;
|
|
3476
|
+
commitMutation: (mutation: Record<string, unknown>, options: CommitMutationOptions, selection?: DomEditSelection | null) => Promise<void>;
|
|
3453
3477
|
};
|
|
3454
3478
|
|
|
3455
3479
|
/** The one source for which preview is on screen: the host's iframe, then each reload promoted in its place. */
|
|
@@ -3620,7 +3644,7 @@ interface DomEditOverlayProps {
|
|
|
3620
3644
|
onStyleCommit?: (property: string, value: string) => Promise<unknown> | void;
|
|
3621
3645
|
recordingState?: GestureRecordingState;
|
|
3622
3646
|
onToggleRecording?: () => void;
|
|
3623
|
-
onMarqueeSelect?: (selections: DomEditSelection[], additive: boolean) => void;
|
|
3647
|
+
onMarqueeSelect?: (selections: DomEditSelection[], additive: boolean) => DomSelectionResult | void;
|
|
3624
3648
|
/**
|
|
3625
3649
|
* Delete the selected canvas element.
|
|
3626
3650
|
* Wire to handleDomEditElementDelete from useDomEditActionsContext —
|
|
@@ -3722,7 +3746,7 @@ interface MarqueeGesturesDeps<T = DomEditSelection> {
|
|
|
3722
3746
|
iframeRef: React.RefObject<HTMLIFrameElement | null>;
|
|
3723
3747
|
overlayRef: React.RefObject<HTMLDivElement | null>;
|
|
3724
3748
|
activeCompositionPathRef: React.RefObject<string | null>;
|
|
3725
|
-
onMarqueeSelectRef: React.RefObject<((selections: T[], additive: boolean) => void) | undefined>;
|
|
3749
|
+
onMarqueeSelectRef: React.RefObject<((selections: T[], additive: boolean) => DomSelectionResult | void) | undefined>;
|
|
3726
3750
|
/** Turns the elements a drag touched into picks; without it, Studio's edit selections. */
|
|
3727
3751
|
resolveHits?: (elements: HTMLElement[]) => T[] | Promise<T[]>;
|
|
3728
3752
|
selectionRef?: React.RefObject<DomEditSelection | null>;
|
package/dist/studio/index.html
CHANGED
|
@@ -14,8 +14,8 @@
|
|
|
14
14
|
document.documentElement.dataset.theme = "paper";
|
|
15
15
|
}
|
|
16
16
|
</script>
|
|
17
|
-
<script type="module" crossorigin src="/assets/index-
|
|
18
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
17
|
+
<script type="module" crossorigin src="/assets/index-CAvZ0AA-.js"></script>
|
|
18
|
+
<link rel="stylesheet" crossorigin href="/assets/index-t1LH6H5H.css">
|
|
19
19
|
</head>
|
|
20
20
|
<body>
|
|
21
21
|
<div data-hf-id="hf-aph5" id="root"></div>
|