@ptengine/inline-editor 0.0.0-stage → 0.1.1

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.
Files changed (169) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/README.md +286 -2
  3. package/dist/InlineEditor.d.ts +349 -0
  4. package/dist/InlineEditor.js +886 -0
  5. package/dist/PagePreview.d.ts +83 -0
  6. package/dist/PagePreview.js +111 -0
  7. package/dist/assets/AssetsPanel.d.ts +19 -0
  8. package/dist/assets/AssetsPanel.js +23 -0
  9. package/dist/assets/componentLibrary.d.ts +23 -0
  10. package/dist/assets/componentLibrary.js +12 -0
  11. package/dist/canvas-ui/index.d.ts +17 -0
  12. package/dist/canvas-ui/index.js +7 -0
  13. package/dist/canvas-ui/scope.d.ts +13 -0
  14. package/dist/canvas-ui/scope.js +1 -0
  15. package/dist/canvas-ui/selection/classNames.d.ts +30 -0
  16. package/dist/canvas-ui/selection/classNames.js +15 -0
  17. package/dist/canvas-ui/selection/tokens.css +204 -0
  18. package/dist/canvas-ui/tree/TreePanel.d.ts +47 -0
  19. package/dist/canvas-ui/tree/TreePanel.js +132 -0
  20. package/dist/canvas-ui/tree/classNames.d.ts +21 -0
  21. package/dist/canvas-ui/tree/classNames.js +8 -0
  22. package/dist/canvas-ui/tree/order.d.ts +38 -0
  23. package/dist/canvas-ui/tree/order.js +38 -0
  24. package/dist/canvas-ui/tree/tree.css +131 -0
  25. package/dist/chrome/EditorChrome.d.ts +83 -0
  26. package/dist/chrome/EditorChrome.js +10 -0
  27. package/dist/chrome/VersionMenu.d.ts +26 -0
  28. package/dist/chrome/VersionMenu.js +86 -0
  29. package/dist/chrome/topbarPrimitives.d.ts +69 -0
  30. package/dist/chrome/topbarPrimitives.js +39 -0
  31. package/dist/chrome/useDismissOnOutside.d.ts +23 -0
  32. package/dist/chrome/useDismissOnOutside.js +27 -0
  33. package/dist/dialogs/ClickActionDialog.d.ts +24 -0
  34. package/dist/dialogs/ClickActionDialog.js +35 -0
  35. package/dist/dialogs/HtmlEditDialog.d.ts +23 -0
  36. package/dist/dialogs/HtmlEditDialog.js +23 -0
  37. package/dist/dialogs/ImageEditDialog.d.ts +30 -0
  38. package/dist/dialogs/ImageEditDialog.js +57 -0
  39. package/dist/dialogs/ImageSettingDialog.d.ts +16 -0
  40. package/dist/dialogs/ImageSettingDialog.js +17 -0
  41. package/dist/dialogs/InsertElementDialog.d.ts +23 -0
  42. package/dist/dialogs/InsertElementDialog.js +28 -0
  43. package/dist/dialogs/ReplaceVideoDialog.d.ts +18 -0
  44. package/dist/dialogs/ReplaceVideoDialog.js +16 -0
  45. package/dist/dialogs/actionTypes.d.ts +53 -0
  46. package/dist/dialogs/actionTypes.js +74 -0
  47. package/dist/dialogs/htmlValidation.d.ts +24 -0
  48. package/dist/dialogs/htmlValidation.js +37 -0
  49. package/dist/dialogs/imageEdit.d.ts +49 -0
  50. package/dist/dialogs/imageEdit.js +30 -0
  51. package/dist/index.d.ts +101 -0
  52. package/dist/index.js +53 -0
  53. package/dist/kernel/CanvasContextBar.d.ts +23 -0
  54. package/dist/kernel/CanvasContextBar.js +12 -0
  55. package/dist/kernel/CanvasFrame.d.ts +56 -0
  56. package/dist/kernel/CanvasFrame.js +53 -0
  57. package/dist/kernel/ai/aiInlineApply.d.ts +330 -0
  58. package/dist/kernel/ai/aiInlineApply.js +477 -0
  59. package/dist/kernel/ai/imageSource.d.ts +24 -0
  60. package/dist/kernel/ai/imageSource.js +19 -0
  61. package/dist/kernel/ai/insertHtmlGate.d.ts +71 -0
  62. package/dist/kernel/ai/insertHtmlGate.js +123 -0
  63. package/dist/kernel/ai/postApplyCheck.d.ts +56 -0
  64. package/dist/kernel/ai/postApplyCheck.js +74 -0
  65. package/dist/kernel/ai/replaceHtmlGate.d.ts +71 -0
  66. package/dist/kernel/ai/replaceHtmlGate.js +147 -0
  67. package/dist/kernel/blocks/BlockOverlay.d.ts +16 -0
  68. package/dist/kernel/blocks/BlockOverlay.js +66 -0
  69. package/dist/kernel/blocks/annotateAndTile.d.ts +106 -0
  70. package/dist/kernel/blocks/annotateAndTile.js +122 -0
  71. package/dist/kernel/blocks/resolveBlocks.d.ts +153 -0
  72. package/dist/kernel/blocks/resolveBlocks.js +233 -0
  73. package/dist/kernel/canvasCapabilities.d.ts +31 -0
  74. package/dist/kernel/canvasCapabilities.js +39 -0
  75. package/dist/kernel/canvasCommands.d.ts +126 -0
  76. package/dist/kernel/canvasCommands.js +146 -0
  77. package/dist/kernel/canvasErrors.d.ts +1 -0
  78. package/dist/kernel/canvasErrors.js +14 -0
  79. package/dist/kernel/captureGeometry.d.ts +35 -0
  80. package/dist/kernel/captureGeometry.js +25 -0
  81. package/dist/kernel/captureOrchestration.d.ts +48 -0
  82. package/dist/kernel/captureOrchestration.js +43 -0
  83. package/dist/kernel/captureSlices.d.ts +36 -0
  84. package/dist/kernel/captureSlices.js +20 -0
  85. package/dist/kernel/changelist/ChangeListPanel.d.ts +13 -0
  86. package/dist/kernel/changelist/ChangeListPanel.js +47 -0
  87. package/dist/kernel/changelist/ChangeListPopover.d.ts +20 -0
  88. package/dist/kernel/changelist/ChangeListPopover.js +10 -0
  89. package/dist/kernel/changelist/builders.d.ts +89 -0
  90. package/dist/kernel/changelist/builders.js +81 -0
  91. package/dist/kernel/changelist/changeSummary.d.ts +19 -0
  92. package/dist/kernel/changelist/changeSummary.js +85 -0
  93. package/dist/kernel/changelist/clipboard.d.ts +16 -0
  94. package/dist/kernel/changelist/clipboard.js +4 -0
  95. package/dist/kernel/changelist/exportForSave.d.ts +30 -0
  96. package/dist/kernel/changelist/exportForSave.js +11 -0
  97. package/dist/kernel/changelist/mergeForSave.d.ts +79 -0
  98. package/dist/kernel/changelist/mergeForSave.js +40 -0
  99. package/dist/kernel/changelist/moveObserverSafety.d.ts +70 -0
  100. package/dist/kernel/changelist/moveObserverSafety.js +39 -0
  101. package/dist/kernel/changelist/overrides.d.ts +22 -0
  102. package/dist/kernel/changelist/overrides.js +63 -0
  103. package/dist/kernel/changelist/useChangeList.d.ts +200 -0
  104. package/dist/kernel/changelist/useChangeList.js +282 -0
  105. package/dist/kernel/config.d.ts +29 -0
  106. package/dist/kernel/config.js +10 -0
  107. package/dist/kernel/dataUrlToBlob.d.ts +8 -0
  108. package/dist/kernel/dataUrlToBlob.js +17 -0
  109. package/dist/kernel/linkHref.d.ts +25 -0
  110. package/dist/kernel/linkHref.js +16 -0
  111. package/dist/kernel/mobileFit.d.ts +46 -0
  112. package/dist/kernel/mobileFit.js +44 -0
  113. package/dist/kernel/moveState.d.ts +35 -0
  114. package/dist/kernel/moveState.js +14 -0
  115. package/dist/kernel/selection/SelectionOverlay.d.ts +10 -0
  116. package/dist/kernel/selection/SelectionOverlay.js +25 -0
  117. package/dist/kernel/selection/SelectionToolbar.d.ts +30 -0
  118. package/dist/kernel/selection/SelectionToolbar.js +82 -0
  119. package/dist/kernel/selection/SelectorPathBar.d.ts +27 -0
  120. package/dist/kernel/selection/SelectorPathBar.js +55 -0
  121. package/dist/kernel/selection/buildDescendantShelf.d.ts +40 -0
  122. package/dist/kernel/selection/buildDescendantShelf.js +50 -0
  123. package/dist/kernel/selection/buildRootShelf.d.ts +26 -0
  124. package/dist/kernel/selection/buildRootShelf.js +149 -0
  125. package/dist/kernel/selection/elementAiContext.d.ts +324 -0
  126. package/dist/kernel/selection/elementAiContext.js +122 -0
  127. package/dist/kernel/selection/elementGeometryForAi.d.ts +9 -0
  128. package/dist/kernel/selection/elementGeometryForAi.js +15 -0
  129. package/dist/kernel/selection/geometry.d.ts +55 -0
  130. package/dist/kernel/selection/geometry.js +18 -0
  131. package/dist/kernel/selection/resolveAnchors.d.ts +116 -0
  132. package/dist/kernel/selection/resolveAnchors.js +173 -0
  133. package/dist/kernel/selection/shelfRow.d.ts +33 -0
  134. package/dist/kernel/selection/shelfRow.js +21 -0
  135. package/dist/kernel/selection/tagLabels.d.ts +9 -0
  136. package/dist/kernel/selection/tagLabels.js +46 -0
  137. package/dist/kernel/selection/toolbarButtons.d.ts +60 -0
  138. package/dist/kernel/selection/toolbarButtons.js +105 -0
  139. package/dist/kernel/selection/useAiSelectionContext.d.ts +26 -0
  140. package/dist/kernel/selection/useAiSelectionContext.js +26 -0
  141. package/dist/kernel/selection/useCanvasGeometry.d.ts +32 -0
  142. package/dist/kernel/selection/useCanvasGeometry.js +47 -0
  143. package/dist/kernel/selection/useSelectionRestore.d.ts +18 -0
  144. package/dist/kernel/selection/useSelectionRestore.js +25 -0
  145. package/dist/kernel/shrinkImageForUpload.d.ts +45 -0
  146. package/dist/kernel/shrinkImageForUpload.js +61 -0
  147. package/dist/kernel/useCanvasBridge.d.ts +36 -0
  148. package/dist/kernel/useCanvasBridge.js +41 -0
  149. package/dist/kernel/useCanvasGate.d.ts +22 -0
  150. package/dist/kernel/useCanvasGate.js +35 -0
  151. package/dist/kernel/useCanvasSession.d.ts +44 -0
  152. package/dist/kernel/useCanvasSession.js +182 -0
  153. package/dist/kernel/useCanvasStream.d.ts +39 -0
  154. package/dist/kernel/useCanvasStream.js +45 -0
  155. package/dist/kernel/useMobileFit.d.ts +40 -0
  156. package/dist/kernel/useMobileFit.js +139 -0
  157. package/dist/locales.d.ts +1094 -0
  158. package/dist/locales.js +545 -0
  159. package/dist/panels/StylePanel.d.ts +24 -0
  160. package/dist/panels/StylePanel.js +40 -0
  161. package/dist/panels/styleFields.d.ts +39 -0
  162. package/dist/panels/styleFields.js +91 -0
  163. package/dist/tree/LayersPanel.d.ts +30 -0
  164. package/dist/tree/LayersPanel.js +15 -0
  165. package/dist/tree/domTreeAdapter.d.ts +63 -0
  166. package/dist/tree/domTreeAdapter.js +90 -0
  167. package/dist/useInlineEditor.d.ts +161 -0
  168. package/dist/useInlineEditor.js +346 -0
  169. package/package.json +58 -3
@@ -0,0 +1,49 @@
1
+ import type { ElementCapabilities } from '@ptengine/inline-core/protocol';
2
+ /**
3
+ * 「替换图片」的分支判定 —— 移植现役 `ImageEditDialog.vue:93-130`。
4
+ *
5
+ * ⚠️ **同一个按钮,按元素类型产出三种完全不同的 change**:
6
+ *
7
+ * | 元素 | change | 说明 |
8
+ * |---|---|---|
9
+ * | `<img>` | `changeElementAttribute`(55) `src` | 顺带清 `srcset`(应用侧已自动做,见 applyChange) |
10
+ * | 有 computed 背景图 | `elementStyle`(53) `background-image` | 现役先 `undoStyle` 再 `changeStyle` |
11
+ * | 其它(可插入位置) | `elementContent`(54) 插一个新 `<img>` | 包一层带防撞号的 div |
12
+ *
13
+ * 判错的后果不是报错,是「点了替换图片、图没变」:比如对一个背景图 div 产出
14
+ * `changeElementAttribute src`,属性确实被设上了,但 div 根本不吃 src。
15
+ */
16
+ export type ImageEditBranch = 'img-src' | 'background' | 'insert';
17
+ /**
18
+ * ⚠️ 优先级:**先判 `<img>`,再判背景图**。
19
+ * 一个 `<img>` 完全可能同时带背景图(CSS 给它加了占位背景),这时用户要换的是 src,
20
+ * 不是背景。反过来判会让换图作用在看不见的背景层上。
21
+ */
22
+ export declare function resolveImageBranch(caps: ElementCapabilities): ImageEditBranch;
23
+ /** `background-image` 的值。现役是把旧 url 替换掉,这里直接产出完整值。 */
24
+ export declare function backgroundImageValue(url: string): string;
25
+ /**
26
+ * 插入新 `<img>` 时的 HTML —— 移植 `common.util.js:326-333` 的 `createPtElementDom`。
27
+ *
28
+ * ⚠️ 三件必须照做的事:
29
+ * 1. 外面包一层 `div`,`id` 是 `pt-element-` + **8 位**随机十六进制。
30
+ * 这个 id 会被选择器生成优先当锚点用(`#id`),复制粘贴时必须重新生成防撞号,
31
+ * 否则页面上出现两个同 id 元素 → identifier 不再唯一 → 第二份的所有后续 change
32
+ * 全部错打到第一份上。
33
+ * 2. `pt-element-name` 打大写 tagName —— `metadata.service.js:530` 靠它判定元素能力。
34
+ * 3. `mode` 为 insert/append(内部开头/结尾)时加 `display:inline-block`,
35
+ * 否则块级 div 会把行内布局撑坏。
36
+ */
37
+ export declare function buildInsertImageHtml(url: string, mode: 'insert' | 'append' | 'before' | 'after', randomId: () => string): string;
38
+ /** 8 位十六进制(与 `uuid_8bit()` 同形态)。 */
39
+ export declare function randomPtElementId(): string;
40
+ /**
41
+ * 复制粘贴时重写 HTML 里的防撞号 —— 移植 `common.util.js:340-349`
42
+ * 的 `updatePtCopyElementId`。
43
+ *
44
+ * ⚠️ 现役有一个**副作用**:它用无 `g` 标志的正则逐个替换,同一个 id 在 HTML 里出现
45
+ * N 次时会被换成 N 个**互不相同**的新 id,原有引用关系会断。
46
+ * **未确证**那是有意还是 bug。这里改成「同一个旧 id 映射到同一个新 id」——
47
+ * 保持引用关系,且不影响防撞这个目的本身。
48
+ */
49
+ export declare function rewritePtElementIds(html: string, randomId?: () => string): string;
@@ -0,0 +1,30 @@
1
+ export function resolveImageBranch(caps) {
2
+ if (caps.isImg)
3
+ return 'img-src';
4
+ if (caps.hasBackgroundImage)
5
+ return 'background';
6
+ return 'insert';
7
+ }
8
+ export function backgroundImageValue(url) {
9
+ return `url("${url}")`;
10
+ }
11
+ export function buildInsertImageHtml(url, mode, randomId) {
12
+ const inlineBlock = mode === 'insert' || mode === 'append' ? ' style="display:inline-block"' : '';
13
+ const img = `<img src="${url}" data-user-url="${url}">`;
14
+ return `<div id="pt-element-${randomId()}" pt-element-name="IMG"${inlineBlock}>${img}</div>`;
15
+ }
16
+ export function randomPtElementId() {
17
+ let out = '';
18
+ for (let i = 0; i < 8; i++) {
19
+ out += Math.floor(Math.random() * 16).toString(16);
20
+ }
21
+ return out;
22
+ }
23
+ export function rewritePtElementIds(html, randomId = randomPtElementId) {
24
+ const seen = new Map();
25
+ return html.replace(/pt-element-([A-Za-z0-9_]{8})/g, (_m, old) => {
26
+ if (!seen.has(old))
27
+ seen.set(old, randomId());
28
+ return `pt-element-${seen.get(old)}`;
29
+ });
30
+ }
@@ -0,0 +1,101 @@
1
+ /**
2
+ * 内联编辑器 —— 公开出口。
3
+ *
4
+ * **两层 API,按宿主的外壳需求选**:
5
+ * - `useInlineEditor()` —— headless。宿主完全自定义 UI(AI 对话那种极简壳走这条)。
6
+ * - `<EditorChrome>` + 各面板/弹框 —— 默认外壳与成品部件,按需拼装。
7
+ *
8
+ * ⚠️ 画布内核(会话/几何/选中/change list)目前物理位置仍在
9
+ * `./kernel/*`,这里统一再导出一次,
10
+ * 让消费方**只认这一个入口**。物理搬迁是后续单独一步,搬完这里的路径变、
11
+ * 对外的 API 不变 —— 这正是留这层再导出的目的。
12
+ */
13
+ export { InlineEditor } from './InlineEditor.js';
14
+ export type { InlineEditorProps } from './InlineEditor.js';
15
+ /**
16
+ * 分析阶段的被动预览板(顶栏 + 画布 + 区块框,别的一概不渲染)。
17
+ * 它就是上面那条主张的样板:**用 headless 层拼一个极简外壳**,而不是给
18
+ * `<InlineEditor>` 加 `showXxx` 开关。
19
+ */
20
+ export { PagePreview } from './PagePreview.js';
21
+ export type { PagePreviewProps, PagePreviewHandle } from './PagePreview.js';
22
+ export { useInlineEditor } from './useInlineEditor.js';
23
+ export type { UseInlineEditorInput, UseInlineEditorResult, InlineEditorSelection } from './useInlineEditor.js';
24
+ export { EditorChrome } from './chrome/EditorChrome.js';
25
+ export type { EditorChromeProps, ChromeVariant } from './chrome/EditorChrome.js';
26
+ export { StylePanel } from './panels/StylePanel.js';
27
+ export type { StylePanelProps } from './panels/StylePanel.js';
28
+ export { STYLE_SECTIONS, visibleSections, composeStyleValue } from './panels/styleFields.js';
29
+ export type { StyleSection, StyleField } from './panels/styleFields.js';
30
+ export { HtmlEditDialog } from './dialogs/HtmlEditDialog.js';
31
+ export { validateHtml } from './dialogs/htmlValidation.js';
32
+ export type { HtmlValidationResult } from './dialogs/htmlValidation.js';
33
+ export { inlineEditorLocales, zhCN, enUS, jaJP } from './locales.js';
34
+ export type { InlineEditorLocale } from './locales.js';
35
+ export { useCanvasSession } from './kernel/useCanvasSession.js';
36
+ export { useCanvasStream } from './kernel/useCanvasStream.js';
37
+ export { checkCanvasGate } from './kernel/useCanvasGate.js';
38
+ export type { GateResult } from './kernel/useCanvasGate.js';
39
+ export { useCanvasGeometry } from './kernel/selection/useCanvasGeometry.js';
40
+ export { useSelectionRestore } from './kernel/selection/useSelectionRestore.js';
41
+ export { useChangeList } from './kernel/changelist/useChangeList.js';
42
+ export { deleteElement, editStyle, editHtml, editText, replaceImage, setImageAlt, setClickAction } from './kernel/changelist/useChangeList.js';
43
+ export * as canvasCommands from './kernel/canvasCommands.js';
44
+ export { setPickMode, getDomTree, setCode, getElementCapabilities, getAncestorChain, resolveCanvasSelector, setSelection, setHoverTarget, applyChange, revertChange, getOuterHtml, resolveHeatmapSelector, elementsInBand, measureDocument, setStyleLayer, observeDocumentSize, queryElements, elementsAtPoints, configureCanvas } from './kernel/canvasCommands.js';
45
+ export { capabilitiesFromHandshake, disabledCapabilities, hasCanvasCapability, missingCoreCapabilities, narrowByReady } from './kernel/canvasCapabilities.js';
46
+ export { useMobileFit } from './kernel/useMobileFit.js';
47
+ export type { MobileFitState, UseMobileFitInput, UseMobileFitResult } from './kernel/useMobileFit.js';
48
+ export { MOBILE_FIT_LAYER, RENDER_FIXES_LAYER, planMobileFit, buildRenderFixesCss } from './kernel/mobileFit.js';
49
+ export type { MobileFitPlan, NaturalSize } from './kernel/mobileFit.js';
50
+ export { configureInlineEditor, getInlineEditorConfig, resetInlineEditorConfig } from './kernel/config.js';
51
+ export type { InlineEditorConfig } from './kernel/config.js';
52
+ export { EXTENSION_ID_ATTR, getExtensionId, isExtensionIdConfigured, hasExtensionChannel, sendCanvasCommand, probeExtension } from './kernel/useCanvasBridge.js';
53
+ export type { UseChangeListResult, ChangeRecord, HydrateOutcome } from './kernel/changelist/useChangeList.js';
54
+ export type { ToolbarButtonSpec } from './kernel/selection/toolbarButtons.js';
55
+ export { tagLabelKey, hasTagLabel, tagsWithLabel } from './kernel/selection/tagLabels.js';
56
+ export { buildStyleChange, buildContentChange, buildAttributeChange, buildActionChange, buildMoveChange, buildTextChange, buildScriptChange } from './kernel/changelist/builders.js';
57
+ export { applyOverride, findOverrideIndex } from './kernel/changelist/overrides.js';
58
+ export { CanvasFrame, TARGET_VIEWPORT_WIDTH, computeZoom } from './kernel/CanvasFrame.js';
59
+ export { SelectionOverlay } from './kernel/selection/SelectionOverlay.js';
60
+ export { SelectionToolbar } from './kernel/selection/SelectionToolbar.js';
61
+ export { SelectorPathBar } from './kernel/selection/SelectorPathBar.js';
62
+ export { ChangeListPanel } from './kernel/changelist/ChangeListPanel.js';
63
+ export { TOOLBAR_BUTTONS, visibleButtons, pasteModes } from './kernel/selection/toolbarButtons.js';
64
+ export { frameRectToProductRect } from './kernel/selection/geometry.js';
65
+ export { describeCanvasError } from './kernel/canvasErrors.js';
66
+ /** 落盘:明文 change list → 数值形态。**存库前必经这一步**(见该函数注释)。 */
67
+ export { exportChangesForSave } from './kernel/changelist/exportForSave.js';
68
+ export { buildElementAiContext, truncateHtml, AI_HTML_BUDGET_BYTES, AI_DESCENDANT_LIMIT, SHELF_TREE_MAX_DEPTH, SHELF_TREE_MAX_NODES, ROOT_SHELF_LIMIT, composeAnchorHtml, extractPageLinks, linksFragment } from './kernel/selection/elementAiContext.js';
69
+ export type { ElementAiContext, AiDescendant, AiHtmlFragment, AiPageImage, AnchorShot } from './kernel/selection/elementAiContext.js';
70
+ /**
71
+ * 方案锚点:宿主存下来的「这一版要改哪个区块」,包在活页面上重新解析并预授权它的子树。
72
+ * 形状与 backend `contracts.ts` 的 `InlinePlanAnchor` 逐字同形。
73
+ */
74
+ export { resolveInlinePlanAnchors } from './kernel/selection/resolveAnchors.js';
75
+ export type { InlinePlanAnchor, ResolvedAnchor, AnchorShelfResult } from './kernel/selection/resolveAnchors.js';
76
+ export { buildDescendantShelf } from './kernel/selection/buildDescendantShelf.js';
77
+ export { formatShelfRow, imageTag, linkTag, SHELF_TEXT_MAX } from './kernel/selection/shelfRow.js';
78
+ export { linkPath } from './kernel/linkHref.js';
79
+ export { buildRootShelf } from './kernel/selection/buildRootShelf.js';
80
+ export { LayersPanel } from './tree/LayersPanel.js';
81
+ export { adaptDomTree, moveModeFromDropPos } from './tree/domTreeAdapter.js';
82
+ export type { AdaptDomTreeOptions, TreeNodeIconInput } from './tree/domTreeAdapter.js';
83
+ export { exportRecordsForSave } from './kernel/changelist/exportForSave.js';
84
+ export { mergeForSave } from './kernel/changelist/mergeForSave.js';
85
+ export type { MergeOutcome } from './kernel/changelist/mergeForSave.js';
86
+ export { applyAiChanges, AI_SAFE_OPS, AI_INSERT_MODES, AI_MOVE_MODES } from './kernel/ai/aiInlineApply.js';
87
+ export type { AiApplyApi, InlineEditorHandle } from './InlineEditor.js';
88
+ export type { AiApplyOutcome, AiAppliedChange, AiApplyReject, AiRejectReason, AiApplyDeps, AiScopeGrant, AiWireChange } from './kernel/ai/aiInlineApply.js';
89
+ export { evaluateApplyCheck, APPLY_CHECK_SETTLE_MS } from './kernel/ai/postApplyCheck.js';
90
+ export type { ApplyCheck, ApplyCheckFlag, ApplyCheckInserted } from './kernel/ai/postApplyCheck.js';
91
+ export type { AdaptedTree, AdaptedTreeNode } from './tree/domTreeAdapter.js';
92
+ export { AssetsPanel } from './assets/AssetsPanel.js';
93
+ export { componentInsertPayload } from './assets/componentLibrary.js';
94
+ export type { LibraryComponent } from './assets/componentLibrary.js';
95
+ export { resolveBlocks, summarizeTree } from './kernel/blocks/resolveBlocks.js';
96
+ export type { BlockLinks, HeatmapBlockConfig, PageModelBlock, PageModelBlockMember, ResolveBlocksDeps, ResolveBlocksOptions } from './kernel/blocks/resolveBlocks.js';
97
+ export { annotateAndTile, planAnnotateAndTile } from './kernel/blocks/annotateAndTile.js';
98
+ export type { AnnotateBlock, AnnotateOptions, AnnotatePlan, AnnotateResult, AnnotateDeps } from './kernel/blocks/annotateAndTile.js';
99
+ export { BlockOverlay } from './kernel/blocks/BlockOverlay.js';
100
+ export type { BlockOverlayProps } from './kernel/blocks/BlockOverlay.js';
101
+ export { dataUrlToBlob } from './kernel/dataUrlToBlob.js';
package/dist/index.js ADDED
@@ -0,0 +1,53 @@
1
+ export { InlineEditor } from './InlineEditor.js';
2
+ export { PagePreview } from './PagePreview.js';
3
+ export { useInlineEditor } from './useInlineEditor.js';
4
+ export { EditorChrome } from './chrome/EditorChrome.js';
5
+ export { StylePanel } from './panels/StylePanel.js';
6
+ export { STYLE_SECTIONS, visibleSections, composeStyleValue } from './panels/styleFields.js';
7
+ export { HtmlEditDialog } from './dialogs/HtmlEditDialog.js';
8
+ export { validateHtml } from './dialogs/htmlValidation.js';
9
+ export { inlineEditorLocales, zhCN, enUS, jaJP } from './locales.js';
10
+ export { useCanvasSession } from './kernel/useCanvasSession.js';
11
+ export { useCanvasStream } from './kernel/useCanvasStream.js';
12
+ export { checkCanvasGate } from './kernel/useCanvasGate.js';
13
+ export { useCanvasGeometry } from './kernel/selection/useCanvasGeometry.js';
14
+ export { useSelectionRestore } from './kernel/selection/useSelectionRestore.js';
15
+ export { useChangeList } from './kernel/changelist/useChangeList.js';
16
+ export { deleteElement, editStyle, editHtml, editText, replaceImage, setImageAlt, setClickAction } from './kernel/changelist/useChangeList.js';
17
+ export * as canvasCommands from './kernel/canvasCommands.js';
18
+ export { setPickMode, getDomTree, setCode, getElementCapabilities, getAncestorChain, resolveCanvasSelector, setSelection, setHoverTarget, applyChange, revertChange, getOuterHtml, resolveHeatmapSelector, elementsInBand, measureDocument, setStyleLayer, observeDocumentSize, queryElements, elementsAtPoints, configureCanvas } from './kernel/canvasCommands.js';
19
+ export { capabilitiesFromHandshake, disabledCapabilities, hasCanvasCapability, missingCoreCapabilities, narrowByReady } from './kernel/canvasCapabilities.js';
20
+ export { useMobileFit } from './kernel/useMobileFit.js';
21
+ export { MOBILE_FIT_LAYER, RENDER_FIXES_LAYER, planMobileFit, buildRenderFixesCss } from './kernel/mobileFit.js';
22
+ export { configureInlineEditor, getInlineEditorConfig, resetInlineEditorConfig } from './kernel/config.js';
23
+ export { EXTENSION_ID_ATTR, getExtensionId, isExtensionIdConfigured, hasExtensionChannel, sendCanvasCommand, probeExtension } from './kernel/useCanvasBridge.js';
24
+ export { tagLabelKey, hasTagLabel, tagsWithLabel } from './kernel/selection/tagLabels.js';
25
+ export { buildStyleChange, buildContentChange, buildAttributeChange, buildActionChange, buildMoveChange, buildTextChange, buildScriptChange } from './kernel/changelist/builders.js';
26
+ export { applyOverride, findOverrideIndex } from './kernel/changelist/overrides.js';
27
+ export { CanvasFrame, TARGET_VIEWPORT_WIDTH, computeZoom } from './kernel/CanvasFrame.js';
28
+ export { SelectionOverlay } from './kernel/selection/SelectionOverlay.js';
29
+ export { SelectionToolbar } from './kernel/selection/SelectionToolbar.js';
30
+ export { SelectorPathBar } from './kernel/selection/SelectorPathBar.js';
31
+ export { ChangeListPanel } from './kernel/changelist/ChangeListPanel.js';
32
+ export { TOOLBAR_BUTTONS, visibleButtons, pasteModes } from './kernel/selection/toolbarButtons.js';
33
+ export { frameRectToProductRect } from './kernel/selection/geometry.js';
34
+ export { describeCanvasError } from './kernel/canvasErrors.js';
35
+ export { exportChangesForSave } from './kernel/changelist/exportForSave.js';
36
+ export { buildElementAiContext, truncateHtml, AI_HTML_BUDGET_BYTES, AI_DESCENDANT_LIMIT, SHELF_TREE_MAX_DEPTH, SHELF_TREE_MAX_NODES, ROOT_SHELF_LIMIT, composeAnchorHtml, extractPageLinks, linksFragment } from './kernel/selection/elementAiContext.js';
37
+ export { resolveInlinePlanAnchors } from './kernel/selection/resolveAnchors.js';
38
+ export { buildDescendantShelf } from './kernel/selection/buildDescendantShelf.js';
39
+ export { formatShelfRow, imageTag, linkTag, SHELF_TEXT_MAX } from './kernel/selection/shelfRow.js';
40
+ export { linkPath } from './kernel/linkHref.js';
41
+ export { buildRootShelf } from './kernel/selection/buildRootShelf.js';
42
+ export { LayersPanel } from './tree/LayersPanel.js';
43
+ export { adaptDomTree, moveModeFromDropPos } from './tree/domTreeAdapter.js';
44
+ export { exportRecordsForSave } from './kernel/changelist/exportForSave.js';
45
+ export { mergeForSave } from './kernel/changelist/mergeForSave.js';
46
+ export { applyAiChanges, AI_SAFE_OPS, AI_INSERT_MODES, AI_MOVE_MODES } from './kernel/ai/aiInlineApply.js';
47
+ export { evaluateApplyCheck, APPLY_CHECK_SETTLE_MS } from './kernel/ai/postApplyCheck.js';
48
+ export { AssetsPanel } from './assets/AssetsPanel.js';
49
+ export { componentInsertPayload } from './assets/componentLibrary.js';
50
+ export { resolveBlocks, summarizeTree } from './kernel/blocks/resolveBlocks.js';
51
+ export { annotateAndTile, planAnnotateAndTile } from './kernel/blocks/annotateAndTile.js';
52
+ export { BlockOverlay } from './kernel/blocks/BlockOverlay.js';
53
+ export { dataUrlToBlob } from './kernel/dataUrlToBlob.js';
@@ -0,0 +1,23 @@
1
+ import type { CanvasDevice } from '@ptengine/inline-core/protocol';
2
+ /**
3
+ * 画布列顶部的上下文条 —— **「我在看哪台设备上的哪一页」**。
4
+ *
5
+ * 顶栏收敛成一行时这两样从顶栏搬了下来:它们说的是画布的状态,不是 experience 的动作,
6
+ * 混在退出/保存/改动清单那一排里读不出归属。放在画布正上方,它们指向的东西就在眼皮底下。
7
+ *
8
+ * ## 设备切换是**绝对居中**的
9
+ *
10
+ * 与三代落地页编辑器同一条口径(`.editor-toolbar-center`):脱离 flex 流,永远落在
11
+ * 这一列的几何正中 —— 也就是画布的中轴。不居中的话它会随 URL 长度左右漂。
12
+ *
13
+ * ⚠️ 代价是它**不会把 URL 推开**(绝对定位的东西不参与流)。所以 URL 必须自己设上限:
14
+ * `max-width: calc(50% - 60px)`,60 ≈ 分段控件半宽 + 一点余量。不设的话长 URL 会从
15
+ * 设备切换底下穿过去,两段文字叠在一起。
16
+ */
17
+ export interface CanvasContextBarProps {
18
+ /** 目标页地址。空串时整条仍然渲染(设备切换要在),只是不显示地址。 */
19
+ url: string;
20
+ device: CanvasDevice;
21
+ onDeviceChange: (device: CanvasDevice) => void;
22
+ }
23
+ export declare function CanvasContextBar({ url, device, onDeviceChange }: CanvasContextBarProps): import("react").JSX.Element;
@@ -0,0 +1,12 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useTranslation } from 'react-i18next';
3
+ import { Link2, Monitor, Smartphone } from 'lucide-react';
4
+ import { ChromeSegment, ChromeSegmented } from '../chrome/topbarPrimitives.js';
5
+ export function CanvasContextBar({ url, device, onDeviceChange }) {
6
+ const { t } = useTranslation();
7
+ const items = [
8
+ ['pc', Monitor, t('inlineCanvas.chrome.pc', 'PC')],
9
+ ['mobile', Smartphone, t('inlineCanvas.chrome.mobile', '移动')]
10
+ ];
11
+ return (_jsxs("div", { "data-testid": "canvas-context-bar", className: "relative flex h-9 shrink-0 items-center border-b border-[#EBECF0]\n bg-white px-3", children: [url && (_jsxs("a", { "data-testid": "canvas-context-url", href: url, target: "_blank", rel: "noopener noreferrer", title: url, className: "flex max-w-[calc(50%-60px)] items-center gap-1.5 truncate text-xs\n text-[#8a8f98] hover:text-[#52525b] hover:underline", children: [_jsx(Link2, { className: "size-3.5 shrink-0" }), _jsx("span", { className: "truncate", children: url })] })), _jsx(ChromeSegmented, { "data-testid": "device-switch", className: "absolute left-1/2 -translate-x-1/2", children: items.map(([value, Icon, label]) => (_jsxs(ChromeSegment, { "data-testid": `device-${value}`, active: device === value, onClick: () => onDeviceChange(value), children: [_jsx(Icon, { className: "size-3.5" }), label] }, value))) })] }));
12
+ }
@@ -0,0 +1,56 @@
1
+ import { type CanvasDevice } from '@ptengine/inline-core/protocol';
2
+ /**
3
+ * 目标逻辑视口宽的默认表(宿主可按实例覆盖)。
4
+ *
5
+ * 客户页按 1440 设计,画布用 `zoom` 缩放去适应面板宽度,而不是把 iframe 做窄 ——
6
+ * 做窄会触发客户页的响应式断点,看到的就不是 PC 版了。
7
+ *
8
+ * ⚠️ **放在这里是为了让所有外壳共用同一份**:`<InlineEditor>` 与 `<PagePreview>`
9
+ * 都要用它算 `zoom`,而 `zoom` 同时决定「画面怎么缩」与「区块框/选中框怎么换算」。
10
+ * 各写一份的结果是框与画面错位,且错位量随设备与面板宽变化 —— 看起来像高亮框在飘。
11
+ */
12
+ export declare const TARGET_VIEWPORT_WIDTH: Record<CanvasDevice, number>;
13
+ /**
14
+ * zoom = 面板宽 ÷ 目标逻辑视口宽;只缩不放,避免小面板把页面放大。
15
+ *
16
+ * 截断(而非四舍五入)到 4 位小数:`toFixed(4)` 会四舍五入,对
17
+ * 685.08/1063 = 0.64447789... 舍入成 0.6445,与规格值 0.6444 不符。
18
+ */
19
+ export declare function computeZoom(panelWidth: number, targetViewportWidth: number): number;
20
+ interface Props {
21
+ url: string;
22
+ /** 画布会话 id(不是本仓惯用的 `sid`/profile id)—— 与契约 canvasFrameName 的第 2 段一致。 */
23
+ sessionId: string;
24
+ device: CanvasDevice;
25
+ panelWidth: number;
26
+ targetViewportWidth: number;
27
+ /**
28
+ * 把真实 iframe 元素交出去。目前只有一个用途:**页面内改文字前要先让焦点进入
29
+ * 画布 frame**。agent 在客户页里调 `el.focus()` 只是在那个文档内部选中元素,
30
+ * 浏览器的活动 frame 仍停在产品页 —— 用户敲的字会打到产品页上,表现是
31
+ * 「点了编辑文字,什么都没发生」。必须由产品侧 `iframe.focus()` 把焦点送进去。
32
+ */
33
+ iframeRef?: React.MutableRefObject<HTMLIFrameElement | null>;
34
+ /**
35
+ * 只表示 iframe 的 `load` 事件发生了——**不等于**画布真的加载成功。Chrome 的
36
+ * XFO/CSP 拦截页本身也会正常触发 `load`(它是一个真实渲染出来的内建错误页),
37
+ * 所以这里绝不能把它当成「成功」上报给业务。真正的成功信号要等扩展侧的
38
+ * `ready` 事件打通(下一个任务),本次只用它来解除 visibility:hidden 避免白屏。
39
+ */
40
+ onFrameLoad: () => void;
41
+ /**
42
+ * agent 的 `domReady`(DOMContentLoaded)是否已到。用来**提前**解除
43
+ * `visibility: hidden`。
44
+ *
45
+ * 为什么需要它:iframe 的原生 `load` 要等**全部子资源**(图片、字体、嵌套
46
+ * iframe、广告位)都加载完,真实落地页往往好几秒;在那之前画布区是空白的,
47
+ * 而 DOM 其实早就解析完、可以看也可以编辑了。有了扩展侧的生命周期上报之后
48
+ * 就不必再等 `load`。
49
+ *
50
+ * 取「两者谁先到」而不是只看 `domReady`:没装插件 / 通道不通时不会有任何
51
+ * 生命周期事件,此时仍要靠原生 `load` 兜底,否则画布永远不可见。
52
+ */
53
+ domReady?: boolean;
54
+ }
55
+ export declare function CanvasFrame({ url, sessionId, device, panelWidth, targetViewportWidth, onFrameLoad, domReady, iframeRef }: Props): import("react").JSX.Element;
56
+ export {};
@@ -0,0 +1,53 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useLayoutEffect, useRef, useState } from 'react';
3
+ import { canvasFrameName } from '@ptengine/inline-core/protocol';
4
+ export const TARGET_VIEWPORT_WIDTH = { pc: 1440, mobile: 390 };
5
+ const SANDBOX = [
6
+ 'allow-scripts',
7
+ 'allow-same-origin',
8
+ 'allow-forms',
9
+ 'allow-popups',
10
+ 'allow-popups-to-escape-sandbox'
11
+ ].join(' ');
12
+ export function computeZoom(panelWidth, targetViewportWidth) {
13
+ if (!panelWidth || !targetViewportWidth)
14
+ return 1;
15
+ const raw = panelWidth / targetViewportWidth;
16
+ const truncated = Math.trunc(raw * 10000) / 10000;
17
+ return Math.min(1, truncated);
18
+ }
19
+ export function CanvasFrame({ url, sessionId, device, panelWidth, targetViewportWidth, onFrameLoad, domReady = false, iframeRef }) {
20
+ const ref = useRef(null);
21
+ const [loaded, setLoaded] = useState(false);
22
+ const zoom = computeZoom(panelWidth, targetViewportWidth);
23
+ const revealed = loaded || domReady;
24
+ useLayoutEffect(() => {
25
+ const el = ref.current;
26
+ if (!el)
27
+ return;
28
+ el.setAttribute('style', [
29
+ `width: ${targetViewportWidth}px`,
30
+ 'max-width: none',
31
+ 'height: 100%',
32
+ 'margin: 0',
33
+ 'border: none',
34
+ `zoom: ${zoom}`,
35
+ `visibility: ${revealed ? 'visible' : 'hidden'}`
36
+ ].join('; '));
37
+ }, [zoom, revealed, targetViewportWidth]);
38
+ return (_jsx("div", { style: { width: '100%', height: '100%', display: 'flex', justifyContent: 'center' }, children: _jsx("div", { "data-testid": "canvas-frame-shell", style: {
39
+ display: 'flex',
40
+ height: '100%',
41
+ border: '1px solid #DFE1E6',
42
+ borderRadius: 6,
43
+ background: '#fff',
44
+ overflow: 'hidden'
45
+ }, children: _jsx("iframe", { ref: node => {
46
+ ref.current = node;
47
+ if (iframeRef)
48
+ iframeRef.current = node;
49
+ }, title: "Canvas", name: canvasFrameName(sessionId, device, zoom), src: url, sandbox: SANDBOX, onLoad: () => {
50
+ setLoaded(true);
51
+ onFrameLoad();
52
+ } }) }) }));
53
+ }