nudge-ui 0.2.4 → 0.2.5
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/cli/agentCommand.js +4 -28
- package/dist/client.mjs +863 -213
- package/dist/hosts/next/wrapper.js +1 -7
- package/dist/hosts/projectBridge.js +3 -17
- package/dist/inspector/agent/McpConnectionDialog.js +7 -3
- package/dist/inspector/agent/activity.d.ts +1 -1
- package/dist/inspector/agent/activity.js +3 -2
- package/dist/inspector/agent/client.d.ts +2 -2
- package/dist/inspector/agent/client.js +28 -29
- package/dist/inspector/agent/connectionStatus.d.ts +3 -1
- package/dist/inspector/agent/connectionStatus.js +25 -0
- package/dist/inspector/agent/httpTransport.js +31 -147
- package/dist/inspector/agent/protocol.d.ts +1 -1
- package/dist/inspector/agent/protocol.js +1 -1
- package/dist/inspector/agent/verification.d.ts +1 -1
- package/dist/inspector/agent/verification.js +7 -4
- package/dist/inspector/boot.d.ts +3 -0
- package/dist/inspector/boot.js +297 -0
- package/dist/inspector/canvas/AgentActivityOverlay.d.ts +2 -1
- package/dist/inspector/canvas/AgentActivityOverlay.js +6 -3
- package/dist/inspector/canvas/CanvasCard.js +21 -12
- package/dist/inspector/canvas/CanvasElementOverlay.js +82 -127
- package/dist/inspector/canvas/CanvasToolbar.js +2 -1
- package/dist/inspector/canvas/CanvasWorkspace.js +74 -97
- package/dist/inspector/canvas/LockedWorkspaceNotice.d.ts +3 -2
- package/dist/inspector/canvas/LockedWorkspaceNotice.js +10 -6
- package/dist/inspector/canvas/PageCard.d.ts +10 -0
- package/dist/inspector/canvas/PageCard.js +51 -0
- package/dist/inspector/canvas/SketchToolOptions.d.ts +5 -0
- package/dist/inspector/canvas/SketchToolOptions.js +86 -0
- package/dist/inspector/canvas/StaleChangeIndicator.d.ts +1 -1
- package/dist/inspector/canvas/StaleChangeIndicator.js +1 -1
- package/dist/inspector/canvas/ToolOptionsDrawer.d.ts +21 -0
- package/dist/inspector/canvas/ToolOptionsDrawer.js +77 -0
- package/dist/inspector/canvas/activeCanvasDocument.d.ts +3 -2
- package/dist/inspector/canvas/assets/eraser.svg +28 -0
- package/dist/inspector/canvas/assets/pen.svg +25 -0
- package/dist/inspector/canvas/canvasFrame.d.ts +16 -0
- package/dist/inspector/canvas/canvasFrame.js +10 -0
- package/dist/inspector/canvas/canvasGestures.d.ts +0 -1
- package/dist/inspector/canvas/canvasGestures.js +0 -6
- package/dist/inspector/canvas/canvasStore.d.ts +6 -0
- package/dist/inspector/canvas/canvasStore.js +36 -1
- package/dist/inspector/canvas/frameConnection.d.ts +48 -0
- package/dist/inspector/canvas/frameConnection.js +73 -0
- package/dist/inspector/canvas/frameProtocol.d.ts +18 -1
- package/dist/inspector/canvas/frameProtocol.js +36 -0
- package/dist/inspector/canvas/pageSurface.d.ts +11 -0
- package/dist/inspector/canvas/pageSurface.js +34 -0
- package/dist/inspector/canvas/projection.d.ts +19 -9
- package/dist/inspector/canvas/projection.js +58 -31
- package/dist/inspector/canvas/rendererBootstrap.js +4 -1
- package/dist/inspector/canvas/rendererElementSelector.js +9 -1
- package/dist/inspector/canvas/rendererMessageRouter.d.ts +4 -5
- package/dist/inspector/canvas/rendererMessageRouter.js +12 -16
- package/dist/inspector/canvas/rendererSelectionProxy.d.ts +7 -1
- package/dist/inspector/canvas/rendererSelectionProxy.js +8 -36
- package/dist/inspector/canvas/rendererStylesheet.js +15 -0
- package/dist/inspector/canvas/sessionStore.d.ts +2 -2
- package/dist/inspector/canvas/sessionStore.js +12 -9
- package/dist/inspector/canvas/staleChangeDetector.d.ts +1 -1
- package/dist/inspector/canvas/staleChangeDetector.js +10 -22
- package/dist/inspector/changes/codecs.d.ts +1 -0
- package/dist/inspector/changes/codecs.js +20 -5
- package/dist/inspector/changes/draftPreview.d.ts +12 -0
- package/dist/inspector/changes/draftPreview.js +133 -0
- package/dist/inspector/changes/editModel.d.ts +8 -0
- package/dist/inspector/changes/editModel.js +8 -2
- package/dist/inspector/changes/managedStyleProjection.js +2 -1
- package/dist/inspector/changes/previewDiagnostics.js +1 -1
- package/dist/inspector/changes/types.d.ts +11 -1
- package/dist/inspector/comments/CommentsOverlay.js +18 -16
- package/dist/inspector/comments/store.js +3 -2
- package/dist/inspector/comments/verification.js +1 -1
- package/dist/inspector/componentSemantics/ComponentPropsSection.js +2 -1
- package/dist/inspector/componentSemantics/changeAction.js +1 -1
- package/dist/inspector/componentSemantics/textBinding.d.ts +1 -2
- package/dist/inspector/componentSemantics/textBinding.js +4 -45
- package/dist/inspector/drafts/draftStore.d.ts +109 -0
- package/dist/inspector/drafts/draftStore.js +451 -0
- package/dist/inspector/drafts/model.d.ts +9 -1
- package/dist/inspector/drafts/model.js +5 -1
- package/dist/inspector/drafts/store.d.ts +53 -15
- package/dist/inspector/drafts/store.js +143 -169
- package/dist/inspector/index.d.ts +2 -4
- package/dist/inspector/index.js +2 -264
- package/dist/inspector/inline-text/inlineTextEditor.d.ts +1 -1
- package/dist/inspector/inline-text/inlineTextEditor.js +1 -2
- package/dist/inspector/inline-text/textEditChange.d.ts +1 -1
- package/dist/inspector/inspection/bridge.d.ts +1 -1
- package/dist/inspector/inspection/bridge.js +2 -1
- package/dist/inspector/inspection/browserCssInspection.d.ts +8 -0
- package/dist/inspector/inspection/browserCssInspection.js +28 -6
- package/dist/inspector/inspection/inspectionSnapshot.d.ts +6 -0
- package/dist/inspector/inspection/inspectionSnapshot.js +10 -0
- package/dist/inspector/inspection/performanceDiagnostics.d.ts +18 -0
- package/dist/inspector/inspection/performanceDiagnostics.js +31 -0
- package/dist/inspector/inspection/useBrowserCssInspection.js +17 -38
- package/dist/inspector/iterations/capture.d.ts +2 -1
- package/dist/inspector/iterations/client.d.ts +2 -1
- package/dist/inspector/iterations/coordinator.d.ts +4 -3
- package/dist/inspector/iterations/coordinator.js +5 -3
- package/dist/inspector/iterations/prompt.js +9 -8
- package/dist/inspector/overlay/interactionStyles.js +17 -0
- package/dist/inspector/pageInspector.d.ts +42 -0
- package/dist/inspector/pageInspector.js +342 -0
- package/dist/inspector/projection/draftProjection.d.ts +10 -2
- package/dist/inspector/projection/draftProjection.js +9 -1
- package/dist/inspector/projection/managedStylesheet.js +24 -4
- package/dist/inspector/projection/renderedInstance.js +7 -1
- package/dist/inspector/projection/structuralProjection.d.ts +0 -9
- package/dist/inspector/projection/structuralProjection.js +14 -44
- package/dist/inspector/projection/textProjection.d.ts +8 -2
- package/dist/inspector/projection/textProjection.js +21 -13
- package/dist/inspector/prompt/clipboardHandoff.d.ts +9 -0
- package/dist/inspector/prompt/clipboardHandoff.js +42 -16
- package/dist/inspector/prompt/generatePrompt.d.ts +1 -1
- package/dist/inspector/prompt/generatePrompt.js +243 -147
- package/dist/inspector/prompt/promptDocument.d.ts +3 -0
- package/dist/inspector/prompt/promptDocument.js +8 -0
- package/dist/inspector/prompt/promptSettings.js +7 -5
- package/dist/inspector/runtime/inspectorStorage.d.ts +17 -0
- package/dist/inspector/runtime/inspectorStorage.js +42 -0
- package/dist/inspector/runtime/ownedStylesheets.d.ts +20 -0
- package/dist/inspector/runtime/ownedStylesheets.js +72 -0
- package/dist/inspector/runtime/runtimeConfig.d.ts +4 -0
- package/dist/inspector/runtime/runtimeConfig.js +10 -1
- package/dist/inspector/runtime/runtimeIdentityClaims.d.ts +29 -0
- package/dist/inspector/runtime/runtimeIdentityClaims.js +188 -0
- package/dist/inspector/runtime/staticHtmlRuntimeIdentity.d.ts +15 -0
- package/dist/inspector/runtime/staticHtmlRuntimeIdentity.js +113 -29
- package/dist/inspector/selection/editScope.d.ts +1 -0
- package/dist/inspector/selection/editScope.js +13 -2
- package/dist/inspector/shell/AgentStatusButton.js +2 -2
- package/dist/inspector/shell/AppShell.js +6 -2
- package/dist/inspector/shell/ChangesLog.js +27 -9
- package/dist/inspector/shell/CopyPromptButton.js +60 -54
- package/dist/inspector/shell/EmptyState.js +3 -3
- package/dist/inspector/shell/InspectorShell.d.ts +0 -3
- package/dist/inspector/shell/InspectorShell.js +21 -13
- package/dist/inspector/shell/PeekOriginalButton.js +3 -3
- package/dist/inspector/shell/interactionStatePreview.d.ts +9 -0
- package/dist/inspector/shell/interactionStatePreview.js +112 -0
- package/dist/inspector/shell/originalPreview.d.ts +3 -2
- package/dist/inspector/shell/originalPreview.js +10 -37
- package/dist/inspector/shell/stateValue.js +2 -3
- package/dist/inspector/sketch/SketchEditor.js +5 -4
- package/dist/inspector/sketch/SketchFrameOverlay.d.ts +2 -1
- package/dist/inspector/sketch/SketchFrameOverlay.js +5 -4
- package/dist/inspector/sketch/SketchOverlay.d.ts +3 -5
- package/dist/inspector/sketch/SketchOverlay.js +139 -263
- package/dist/inspector/sketch/SketchPromptPanel.d.ts +1 -1
- package/dist/inspector/sketch/SketchPromptPanel.js +8 -1
- package/dist/inspector/sketch/SketchThumbnail.d.ts +5 -0
- package/dist/inspector/sketch/SketchThumbnail.js +18 -0
- package/dist/inspector/sketch/SketchWorkspace.d.ts +1 -2
- package/dist/inspector/sketch/SketchWorkspace.js +69 -34
- package/dist/inspector/sketch/capture.js +19 -3
- package/dist/inspector/sketch/copySketch.d.ts +10 -0
- package/dist/inspector/sketch/copySketch.js +52 -0
- package/dist/inspector/sketch/drawingTools.d.ts +17 -0
- package/dist/inspector/sketch/drawingTools.js +47 -0
- package/dist/inspector/sketch/frameHeading.d.ts +9 -0
- package/dist/inspector/sketch/frameHeading.js +30 -0
- package/dist/inspector/sketch/freehand.js +3 -3
- package/dist/inspector/sketch/geometry.d.ts +6 -0
- package/dist/inspector/sketch/geometry.js +19 -0
- package/dist/inspector/sketch/history.d.ts +30 -0
- package/dist/inspector/sketch/history.js +58 -0
- package/dist/inspector/sketch/interaction.d.ts +1 -3
- package/dist/inspector/sketch/interaction.js +6 -9
- package/dist/inspector/sketch/model.d.ts +35 -1
- package/dist/inspector/sketch/model.js +116 -61
- package/dist/inspector/sketch/persistence.d.ts +14 -0
- package/dist/inspector/sketch/persistence.js +63 -7
- package/dist/inspector/sketch/raster.d.ts +6 -2
- package/dist/inspector/sketch/raster.js +43 -17
- package/dist/inspector/sketch/store.d.ts +1 -1
- package/dist/inspector/sketch/store.js +1 -1
- package/dist/inspector/sketch/videoFrames.d.ts +6 -0
- package/dist/inspector/sketch/videoFrames.js +81 -0
- package/dist/inspector/styleEditors/BackgroundEditor.js +2 -1
- package/dist/inspector/styleEditors/BorderEditor.js +30 -130
- package/dist/inspector/styleEditors/BorderRadiusEditor.js +8 -3
- package/dist/inspector/styleEditors/ImageBackgroundEditor.js +1 -1
- package/dist/inspector/styleEditors/LayoutSection.js +2 -2
- package/dist/inspector/styleEditors/borderModel.d.ts +42 -0
- package/dist/inspector/styleEditors/borderModel.js +114 -0
- package/dist/inspector/styleEditors/layoutValue.js +2 -3
- package/dist/inspector/tokens/TokenField.js +34 -3
- package/dist/inspector/tokens/TokensPanel.js +2 -1
- package/dist/inspector/tokens/editActions.d.ts +3 -3
- package/dist/inspector/tokens/editActions.js +9 -3
- package/dist/inspector/tokens/resolution/containerQueryEvaluator.d.ts +15 -0
- package/dist/inspector/tokens/resolution/containerQueryEvaluator.js +86 -0
- package/dist/inspector/tokens/resolution/cssomCollector.js +44 -9
- package/dist/inspector/tokens/resolution/nestedSelectors.d.ts +6 -0
- package/dist/inspector/tokens/resolution/nestedSelectors.js +67 -0
- package/dist/inspector/tokens/resolution/ruleMatching.js +23 -4
- package/dist/inspector/tokens/resolution.d.ts +6 -3
- package/dist/inspector/tokens/resolution.js +91 -112
- package/dist/inspector/tokens/tokenEdits.d.ts +1 -1
- package/dist/inspector/tokens/tokenEdits.js +1 -1
- package/dist/inspector/ui/InlineStyleWarning.js +2 -2
- package/dist/inspector/ui/InspectorStyle.d.ts +8 -0
- package/dist/inspector/ui/InspectorStyle.js +26 -0
- package/dist/inspector/ui/PopoverListbox.d.ts +2 -1
- package/dist/inspector/ui/PopoverListbox.js +3 -3
- package/dist/inspector/ui/Toast.d.ts +14 -0
- package/dist/inspector/ui/Toast.js +30 -0
- package/dist/inspector/ui/assets/canvasIllustration.d.ts +2 -0
- package/dist/inspector/ui/assets/canvasIllustration.js +21 -0
- package/dist/inspector/ui/assets/gridIllustration.d.ts +2 -0
- package/dist/inspector/ui/assets/{grid.svg → gridIllustration.js} +3 -2
- package/dist/inspector/ui/customCursors.d.ts +5 -0
- package/dist/inspector/ui/customCursors.js +32 -6
- package/dist/inspector/ui/styles.js +12 -10
- package/dist/inspector/workspace/commands.js +1 -2
- package/dist/inspector/workspace/controller.js +1 -2
- package/dist/inspector/workspace/handoff.js +3 -2
- package/dist/inspector/workspace/sentItems.d.ts +3 -6
- package/dist/inspector/workspace/sentItems.js +6 -24
- package/dist/inspector/workspace/timeline.d.ts +24 -10
- package/dist/inspector/workspace/timeline.js +118 -96
- package/dist/internal/agent-protocol.d.ts +50 -13
- package/dist/internal/agent-protocol.js +145 -19
- package/dist/nudge-ui.mjs +81 -65
- package/dist/project/mcpPackage.d.ts +8 -0
- package/dist/project/mcpPackage.js +60 -0
- package/package.json +12 -2
- package/dist/inspector/canvas/measurementProjection.d.ts +0 -8
- package/dist/inspector/canvas/measurementProjection.js +0 -16
- package/dist/inspector/changes/changesLog.d.ts +0 -49
- package/dist/inspector/changes/changesLog.js +0 -255
- package/dist/inspector/changes/draftChanges.d.ts +0 -58
- package/dist/inspector/changes/draftChanges.js +0 -304
- package/dist/inspector/conformance/projection.d.ts +0 -2
- package/dist/inspector/conformance/projection.js +0 -3
- package/dist/inspector/inline-text/textChangeBoundary.d.ts +0 -6
- package/dist/inspector/inline-text/textChangeBoundary.js +0 -1
- package/dist/inspector/overlay/InspectorOverlay.d.ts +0 -5
- package/dist/inspector/overlay/InspectorOverlay.js +0 -332
- package/dist/inspector/overlay/elementSelector.d.ts +0 -1
- package/dist/inspector/overlay/elementSelector.js +0 -111
- package/dist/inspector/sketch/SketchChanges.d.ts +0 -2
- package/dist/inspector/sketch/SketchChanges.js +0 -72
- package/dist/inspector/sketch/SketchEntryButton.d.ts +0 -4
- package/dist/inspector/sketch/SketchEntryButton.js +0 -11
- package/dist/inspector/sketch/SketchLayersPanel.d.ts +0 -2
- package/dist/inspector/sketch/SketchLayersPanel.js +0 -71
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { canvasFrameElement } from "./canvasFrame.js";
|
|
2
3
|
const activityStyles = ".canvas-agent-activity {\n position: absolute;\n inset: 0;\n pointer-events: none;\n z-index: 12;\n overflow: hidden;\n border-radius: 4px;\n}\n\n.canvas-agent-activity__label {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n position: absolute;\n top: 12px;\n right: 12px;\n max-width: 80%;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n padding: 4px 10px 4px 4px;\n border-radius: 20px;\n background: #242424e8;\n color: #fff;\n font: 12px system-ui;\n box-shadow: 0 2px 12px #0003;\n}\n\n.canvas-agent-activity__label canvas {\n flex: 0 0 auto;\n}\n\n.canvas-agent-activity__label > span {\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.canvas-agent-activity__shimmer {\n position: absolute;\n border-radius: 5px;\n background: linear-gradient(110deg, transparent 20%, rgb(212 212 212 / 0.18) 35%, rgb(212 212 212 / 0.35) 50%, rgb(212 212 212 / 0.18) 65%, transparent 80%);\n background-size: 250% 100%;\n animation: nudge-component-shimmer 2.4s ease-in-out infinite;\n}\n\n@keyframes nudge-component-shimmer {\n from { background-position: 150% 0; }\n to { background-position: -150% 0; }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .canvas-agent-activity__shimmer {\n animation: none;\n }\n}\n";
|
|
3
4
|
import { useEffect, useState } from "react";
|
|
4
5
|
import { ThinkingOrb } from "thinking-orbs";
|
|
@@ -7,6 +8,7 @@ import { getNudgeUiRuntimeConfig } from "../runtime/runtimeConfig.js";
|
|
|
7
8
|
import { parseDataSrc } from "../selection/resolveSelection.js";
|
|
8
9
|
import { targetKey } from "../drafts/model.js";
|
|
9
10
|
import { contentEditTarget } from "./frameContent.js";
|
|
11
|
+
import { InspectorStyle } from "../ui/InspectorStyle.js";
|
|
10
12
|
/** Reuses rendered source identities. Iteration provenance cannot target application source. */
|
|
11
13
|
export function attributeActivity(content, document, files) {
|
|
12
14
|
const target = contentEditTarget(content);
|
|
@@ -99,13 +101,14 @@ export function AgentActivityOverlay({ cardId, content, iframe }) {
|
|
|
99
101
|
};
|
|
100
102
|
};
|
|
101
103
|
attachDocument();
|
|
102
|
-
iframe
|
|
103
|
-
|
|
104
|
+
const element = canvasFrameElement(iframe);
|
|
105
|
+
element?.addEventListener("load", attachDocument);
|
|
106
|
+
return () => { element?.removeEventListener("load", attachDocument); detachDocument(); };
|
|
104
107
|
}, [activity, content, iframe]);
|
|
105
108
|
const submitted = activity.requestId !== null && activity.targets.includes(cardId)
|
|
106
109
|
&& (!activity.target || targetKey(activity.target) === targetKey(contentEditTarget(content)));
|
|
107
110
|
const working = activity.requestId !== null && (submitted || visual.files.length > 0);
|
|
108
111
|
if (!working)
|
|
109
112
|
return null;
|
|
110
|
-
return _jsxs("div", { className: "canvas-agent-activity", "data-test": `canvas-agent-activity-${cardId}`, children: [visual.highlights.map((rect, index) => _jsx("div", { className: "canvas-agent-activity__shimmer", "data-test": "canvas-agent-component-shimmer", style: { left: rect.x, top: rect.y, width: rect.width, height: rect.height } }, index)), _jsxs("span", { className: "canvas-agent-activity__label", role: "status", children: [_jsx(ThinkingOrb, { state: "solving", size: 20, theme: "dark", "aria-hidden": "true" }), _jsx("span", { children: "Agent working\u2026" })] }), _jsx(
|
|
113
|
+
return _jsxs("div", { className: "canvas-agent-activity", "data-test": `canvas-agent-activity-${cardId}`, children: [visual.highlights.map((rect, index) => _jsx("div", { className: "canvas-agent-activity__shimmer", "data-test": "canvas-agent-component-shimmer", style: { left: rect.x, top: rect.y, width: rect.width, height: rect.height } }, index)), _jsxs("span", { className: "canvas-agent-activity__label", role: "status", children: [_jsx(ThinkingOrb, { state: "solving", size: 20, theme: "dark", "aria-hidden": "true" }), _jsx("span", { children: "Agent working\u2026" })] }), _jsx(InspectorStyle, { css: activityStyles })] });
|
|
111
114
|
}
|
|
@@ -4,11 +4,11 @@ import { contentDocumentUrl, contentNavigationUrl, contentSourceUrl, iterationId
|
|
|
4
4
|
import { refreshHtmlIteration } from "../iterations/coordinator.js";
|
|
5
5
|
import { useCallback, useEffect, useLayoutEffect, useRef, useState } from "react";
|
|
6
6
|
import { CANVAS_RENDERER_ATTR } from "./roleDetection.js";
|
|
7
|
-
import { useCanvasCards, getCanvasCardLabel, updateCardUrl, resizeCard, setCardPosition, selectCard, getSelectedCardId, useSelectedCardId, useFocusedCardId, } from "./canvasStore.js";
|
|
7
|
+
import { useCanvasCards, getCanvasCardLabel, updateCardUrl, resizeCard, setCardPosition, beginCardGeometryChange, selectCard, getSelectedCardId, useSelectedCardId, useFocusedCardId, } from "./canvasStore.js";
|
|
8
8
|
import { useBoardCamera } from "./viewStore.js";
|
|
9
9
|
import { IconArrowsDiagonal, IconCopy, IconCornerLeftDown, IconBoltFilled, IconArtboard, IconTrash } from "@tabler/icons-react";
|
|
10
|
-
import {
|
|
11
|
-
import { registerCardFrame, registerCardFrameSource, unregisterCardFrame, sendProjectionToCard, invalidateCanvasPreviewDocument
|
|
10
|
+
import { connectFrame } from "./frameConnection.js";
|
|
11
|
+
import { registerCardFrame, registerCardFrameSource, unregisterCardFrame, sendProjectionToCard, invalidateCanvasPreviewDocument } from "./projection.js";
|
|
12
12
|
import { Button } from "../ui/Button.js";
|
|
13
13
|
import { IconButton } from "../ui/IconButton.js";
|
|
14
14
|
import { Tooltip } from "../ui/Tooltip.js";
|
|
@@ -20,6 +20,7 @@ import { getCanvasToolbarScale } from "./toolbarScale.js";
|
|
|
20
20
|
import { getCanvasResizeHandleScale } from "./resizeHandleScale.js";
|
|
21
21
|
import { disposeBrowserCssInspection } from "../inspection/browserCssInspectionRegistry.js";
|
|
22
22
|
import { releaseDocumentProjection } from "../projection/structuralProjection.js";
|
|
23
|
+
import { disposeRuntimeIdentityClaims } from "../runtime/runtimeIdentityClaims.js";
|
|
23
24
|
import { startClipboardHandoffController } from "../prompt/clipboardHandoff.js";
|
|
24
25
|
import { disposeInlineTextEdit, isInlineTextEditingActive } from "../inline-text/inlineTextEditor.js";
|
|
25
26
|
import { configureNudgeUiRuntime, getNudgeUiRuntimeConfig } from "../runtime/runtimeConfig.js";
|
|
@@ -93,12 +94,17 @@ export function CanvasCard({ card, presentation = "canvas", presentationCard = t
|
|
|
93
94
|
const frameDocument = iframeRef.current?.contentDocument;
|
|
94
95
|
if (!documentOwner || !frameDocument)
|
|
95
96
|
return;
|
|
97
|
+
// The initial blank document is discarded by navigation. A blocked frame
|
|
98
|
+
// can make its Window inaccessible before cleanup runs.
|
|
99
|
+
if (frameDocument.URL === "about:blank")
|
|
100
|
+
return;
|
|
96
101
|
if (documentSessionRef.current?.document === frameDocument)
|
|
97
102
|
return;
|
|
98
103
|
disposeDocumentSession();
|
|
99
104
|
const session = documentOwner.createDocumentSession(frameDocument);
|
|
100
105
|
session.registerCleanup(() => disposeBrowserCssInspection(frameDocument));
|
|
101
106
|
session.registerCleanup(() => releaseDocumentProjection(frameDocument));
|
|
107
|
+
session.registerCleanup(() => disposeRuntimeIdentityClaims(frameDocument));
|
|
102
108
|
session.registerCleanup(() => disposeInlineTextEdit("frame-disposed", frameDocument));
|
|
103
109
|
session.registerCleanup(startClipboardHandoffController(frameDocument));
|
|
104
110
|
session.registerCleanup(installFrameScrollbarStyles(frameDocument));
|
|
@@ -170,13 +176,8 @@ export function CanvasCard({ card, presentation = "canvas", presentationCard = t
|
|
|
170
176
|
}
|
|
171
177
|
/** The controller half of the handshake: announce workspace identity. */
|
|
172
178
|
function sendParentReady() {
|
|
173
|
-
iframeRef.current
|
|
174
|
-
type: "parent-ready"
|
|
175
|
-
protocolVersion: PROTOCOL_VERSION,
|
|
176
|
-
projectId: PROJECT_ID,
|
|
177
|
-
workspaceId: WORKSPACE_ID,
|
|
178
|
-
cardId: card.id,
|
|
179
|
-
}, window.location.origin);
|
|
179
|
+
if (iframeRef.current)
|
|
180
|
+
connectFrame(card.id, iframeRef.current).post({ type: "parent-ready" });
|
|
180
181
|
}
|
|
181
182
|
function adoptFrameRuntime(runtime) {
|
|
182
183
|
frameRuntimeRef.current = runtime;
|
|
@@ -202,8 +203,8 @@ export function CanvasCard({ card, presentation = "canvas", presentationCard = t
|
|
|
202
203
|
adoptFrameRuntime(frameRuntimeRef.current);
|
|
203
204
|
}, [isSelected]);
|
|
204
205
|
useEffect(() => {
|
|
205
|
-
return subscribeCanvasRendererMessages(({
|
|
206
|
-
if (cardId !== card.id)
|
|
206
|
+
return subscribeCanvasRendererMessages(({ frame, message: data }) => {
|
|
207
|
+
if (frame.cardId !== card.id)
|
|
207
208
|
return;
|
|
208
209
|
// A renderer whose runtime finished booting after the iframe load event
|
|
209
210
|
// asks for the identity announcement it may have missed.
|
|
@@ -294,6 +295,8 @@ export function CanvasCard({ card, presentation = "canvas", presentationCard = t
|
|
|
294
295
|
e.stopPropagation();
|
|
295
296
|
e.preventDefault();
|
|
296
297
|
const iterationDrag = e.altKey && !!onCreateIteration && loadState === "ready" && !creatingIteration;
|
|
298
|
+
// Iteration creation history already records where the new frame was dropped.
|
|
299
|
+
const commitMove = iterationDrag ? null : beginCardGeometryChange(card.id);
|
|
297
300
|
let moved = false;
|
|
298
301
|
let iterationId;
|
|
299
302
|
let creationStarted = false;
|
|
@@ -344,6 +347,7 @@ export function CanvasCard({ card, presentation = "canvas", presentationCard = t
|
|
|
344
347
|
cleanup();
|
|
345
348
|
setIsDragging(false);
|
|
346
349
|
cancelled = true;
|
|
350
|
+
commitMove?.();
|
|
347
351
|
if (iterationId) {
|
|
348
352
|
removeFrame(iterationId, { undoable: false });
|
|
349
353
|
selectCard(card.id);
|
|
@@ -352,6 +356,7 @@ export function CanvasCard({ card, presentation = "canvas", presentationCard = t
|
|
|
352
356
|
function onUp() {
|
|
353
357
|
cleanup();
|
|
354
358
|
setIsDragging(false);
|
|
359
|
+
commitMove?.();
|
|
355
360
|
if (iterationId)
|
|
356
361
|
setCardPosition(iterationId, position.x, position.y);
|
|
357
362
|
}
|
|
@@ -380,6 +385,7 @@ export function CanvasCard({ card, presentation = "canvas", presentationCard = t
|
|
|
380
385
|
width: card.width,
|
|
381
386
|
height: card.height,
|
|
382
387
|
};
|
|
388
|
+
const commitResize = beginCardGeometryChange(card.id);
|
|
383
389
|
function onMove(ev) {
|
|
384
390
|
if (ev.pointerId !== pointerId)
|
|
385
391
|
return;
|
|
@@ -399,6 +405,7 @@ export function CanvasCard({ card, presentation = "canvas", presentationCard = t
|
|
|
399
405
|
target.releasePointerCapture(pointerId);
|
|
400
406
|
if (resizeCleanupRef.current === cleanup)
|
|
401
407
|
resizeCleanupRef.current = null;
|
|
408
|
+
commitResize();
|
|
402
409
|
}
|
|
403
410
|
function onUp(ev) {
|
|
404
411
|
if (ev.pointerId !== pointerId)
|
|
@@ -441,7 +448,9 @@ export function CanvasCard({ card, presentation = "canvas", presentationCard = t
|
|
|
441
448
|
if ((delta.x !== 0 && edges.horizontal === null) || (delta.y !== 0 && edges.vertical === null))
|
|
442
449
|
return;
|
|
443
450
|
const next = resizeCanvasRect(card, direction, delta);
|
|
451
|
+
const commitResize = beginCardGeometryChange(card.id);
|
|
444
452
|
resizeCard(card.id, next.width, next.height, { x: next.x, y: next.y });
|
|
453
|
+
commitResize();
|
|
445
454
|
}
|
|
446
455
|
return (_jsxs("div", { className: `canvas-card${linkedToActive ? " is-linked" : ""}${isDragging ? " is-dragging" : ""}${isSelected ? " is-selected" : ""}${isFocused ? " is-focused" : ""}${isFocusPresentationCard ? " is-focus-presentation" : ""}${presentationCard ? " is-presentation-card" : ""}`, "data-card-id": card.id, tabIndex: presentation === "canvas" ? 0 : undefined, role: "group", "aria-label": `Frame: ${frameLabel}`, style: {
|
|
447
456
|
"--canvas-toolbar-scale": toolbarScale,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useEffect, useLayoutEffect, useMemo, useReducer, useRef, useState } from "react";
|
|
3
|
-
import {
|
|
3
|
+
import { isElementClickMessage, isInlineTextIntentMessage } from "./frameProtocol.js";
|
|
4
4
|
import { useCanvasCards } from "./canvasStore.js";
|
|
5
5
|
import { useBoardCamera, useCanvasPresentation, useCanvasPresentationTransitioning, useCanvasLayoutTransitioning, getCanvasLayoutTransitioning, useTemporaryAppInteraction, } from "./viewStore.js";
|
|
6
6
|
import { handleElementClick } from "./rendererSelectionProxy.js";
|
|
@@ -9,7 +9,7 @@ import { readBorderWidths, toRect, } from "../overlay/overlayGeometry.js";
|
|
|
9
9
|
const overlayStyles = ".canvas-element-overlay {\n position: fixed;\n pointer-events: none;\n z-index: 1;\n background: transparent;\n outline: 1px solid var(--accent);\n outline-offset: -1px;\n}\n\n.canvas-spacing-guide {\n position: fixed;\n z-index: 1;\n border-radius: 999px;\n background: var(--accent);\n outline: none;\n box-shadow: none;\n pointer-events: none;\n}\n\n.canvas-spacing-fill {\n position: fixed;\n z-index: 1;\n pointer-events: none;\n background: rgb(59 130 246 / 14%);\n}\n\n.canvas-spacing-fill[data-kind=\"gap\"] {\n background: rgb(236 72 153 / 14%);\n}\n\n.canvas-spacing-guide[data-kind=\"gap\"] {\n background: #ec4899;\n}\n\n.canvas-spacing-value-badge {\n position: fixed;\n z-index: 2;\n transform: translate(-50%, calc(-100% - var(--space-8)));\n padding: var(--space-4) var(--space-8);\n border-radius: var(--radius-8);\n background: var(--surface-raised-2x);\n box-shadow: var(--shadow-popup);\n color: var(--text-primary);\n font-family: var(--font-family);\n font-size: var(--font-size-base);\n font-weight: 400;\n line-height: 1.4;\n font-variant-numeric: tabular-nums;\n white-space: nowrap;\n pointer-events: none;\n}\n\n.canvas-selected-outline {\n position: fixed;\n pointer-events: none;\n z-index: 1;\n outline: 1px solid var(--accent);\n outline-offset: -1px;\n}\n\n.canvas-dom-drop-line {\n z-index: 2147483647;\n border-radius: 999px;\n background: #3b82f6;\n box-shadow: 0 0 0 1px rgb(255 255 255 / 95%), 0 1px 5px rgb(37 99 235 / 72%);\n}\n\n.canvas-dom-drop-line::before,\n.canvas-dom-drop-line::after {\n position: absolute;\n top: 50%;\n width: 8px;\n height: 8px;\n border: 2px solid #ffffff;\n border-radius: 50%;\n background: #2563eb;\n content: \"\";\n transform: translateY(-50%);\n}\n\n.canvas-dom-drop-line::before { left: -3px; }\n.canvas-dom-drop-line::after { right: -3px; }\n\n.canvas-dom-drop-line[data-orientation=\"vertical\"]::before,\n.canvas-dom-drop-line[data-orientation=\"vertical\"]::after {\n left: 50%;\n right: auto;\n transform: translateX(-50%);\n}\n\n.canvas-dom-drop-line[data-orientation=\"vertical\"]::before { top: -3px; }\n.canvas-dom-drop-line[data-orientation=\"vertical\"]::after { top: auto; bottom: -3px; }\n\n.canvas-dom-drop-target {\n z-index: 2147483646;\n box-sizing: border-box;\n border: 1px solid rgb(59 130 246 / 72%);\n border-radius: 4px;\n background: rgb(59 130 246 / 5%);\n}\n";
|
|
10
10
|
import { deleteElement, getDropLocationAtPoint, moveElement, nudgeElement } from "../overlay/structuralGestures.js";
|
|
11
11
|
import { changeKey } from "../changes/model.js";
|
|
12
|
-
import {
|
|
12
|
+
import { getActiveDraftChanges, redo, subscribeActiveDraftChanges, undo } from "../drafts/store.js";
|
|
13
13
|
import { resolveSelectionFromElement } from "../selection/resolveSelection.js";
|
|
14
14
|
import { setSelectedElement } from "../selection/selectionStore.js";
|
|
15
15
|
import { clearDropGuide, showDropGuide, useDropGuide } from "../overlay/dropGuide.js";
|
|
@@ -17,8 +17,8 @@ import { DropGuideOverlay } from "../overlay/DropGuideOverlay.js";
|
|
|
17
17
|
import { getMeasurementGeometry } from "../overlay/measurementGeometry.js";
|
|
18
18
|
import { getElementComputedStyle } from "../runtime/domRealm.js";
|
|
19
19
|
import { MeasurementGuideOverlay } from "../overlay/MeasurementGuideOverlay.js";
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
20
|
+
import { findCanvasFrameByDocument, getRegisteredFrames } from "./projection.js";
|
|
21
|
+
import { connectFrame, measureFrameViewport, toViewportPoint, toViewportRect } from "./frameConnection.js";
|
|
22
22
|
import { RENDERER_ELEMENT_ID_ATTR } from "./rendererCidIndex.js";
|
|
23
23
|
import { observeSelectedGeometry } from "../overlay/selectedGeometry.js";
|
|
24
24
|
import { handleInlineTextEditIntent, useInlineTextSession } from "../inline-text/inlineTextEditor.js";
|
|
@@ -30,22 +30,7 @@ import { getSpacingAffordanceAtPoint, getSpacingAffordanceForDescriptor, getSpac
|
|
|
30
30
|
import { beginLayoutPreview, endLayoutPreview } from "../styleEditors/layoutPreviewState.js";
|
|
31
31
|
import { useNudgeUiRuntimeConfig } from "../runtime/useRuntimeConfig.js";
|
|
32
32
|
import { DomNavigator } from "../overlay/DomNavigator.js";
|
|
33
|
-
|
|
34
|
-
const frameRect = iframe.getBoundingClientRect();
|
|
35
|
-
return {
|
|
36
|
-
left: frameRect.left + rect.left * zoom,
|
|
37
|
-
top: frameRect.top + rect.top * zoom,
|
|
38
|
-
width: rect.width * zoom,
|
|
39
|
-
height: rect.height * zoom,
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
function projectPoint(iframe, x, y, zoom) {
|
|
43
|
-
const frameRect = iframe.getBoundingClientRect();
|
|
44
|
-
return {
|
|
45
|
-
x: frameRect.left + x * zoom,
|
|
46
|
-
y: frameRect.top + y * zoom,
|
|
47
|
-
};
|
|
48
|
-
}
|
|
33
|
+
import { InspectorStyle } from "../ui/InspectorStyle.js";
|
|
49
34
|
function spacingBadgeForDrag(drag, point) {
|
|
50
35
|
return {
|
|
51
36
|
iframe: drag.iframe,
|
|
@@ -74,40 +59,18 @@ function spacingGuideStyle(rect) {
|
|
|
74
59
|
height,
|
|
75
60
|
});
|
|
76
61
|
}
|
|
77
|
-
function
|
|
78
|
-
const
|
|
79
|
-
if (!
|
|
80
|
-
return null;
|
|
81
|
-
if (!/^r\d+$/.test(elementId))
|
|
82
|
-
return null;
|
|
83
|
-
const candidates = doc.querySelectorAll(`[${RENDERER_ELEMENT_ID_ATTR}="${elementId}"]`);
|
|
84
|
-
if (candidates.length !== 1)
|
|
85
|
-
return null;
|
|
86
|
-
const candidate = candidates[0] ?? null;
|
|
87
|
-
if (!candidate
|
|
88
|
-
|| candidate.getAttribute("data-cid") !== cid
|
|
89
|
-
|| (candidate.getAttribute("data-src") ?? "") !== src)
|
|
90
|
-
return null;
|
|
91
|
-
const frameWindow = doc.defaultView;
|
|
92
|
-
return frameWindow && candidate instanceof frameWindow.HTMLElement ? candidate : null;
|
|
93
|
-
}
|
|
94
|
-
function projectGuideToCanvas(guide, zoom) {
|
|
95
|
-
if (!guide)
|
|
96
|
-
return null;
|
|
97
|
-
const iframe = guide.document.defaultView?.frameElement;
|
|
98
|
-
if (!(iframe instanceof HTMLIFrameElement))
|
|
62
|
+
function projectGuideToCanvas(guide) {
|
|
63
|
+
const iframe = findCanvasFrameByDocument(guide?.document);
|
|
64
|
+
if (!guide || !iframe)
|
|
99
65
|
return null;
|
|
100
|
-
const
|
|
101
|
-
const project = (rect, scaleWidth, scaleHeight) => ({
|
|
102
|
-
left: iframeRect.left + rect.left * zoom,
|
|
103
|
-
top: iframeRect.top + rect.top * zoom,
|
|
104
|
-
width: scaleWidth ? rect.width * zoom : rect.width,
|
|
105
|
-
height: scaleHeight ? rect.height * zoom : rect.height,
|
|
106
|
-
});
|
|
66
|
+
const viewport = measureFrameViewport(iframe);
|
|
107
67
|
return {
|
|
108
68
|
orientation: guide.orientation,
|
|
109
|
-
line:
|
|
110
|
-
|
|
69
|
+
line: toViewportRect(viewport, guide.line, {
|
|
70
|
+
width: guide.orientation === "horizontal",
|
|
71
|
+
height: guide.orientation === "vertical",
|
|
72
|
+
}),
|
|
73
|
+
target: toViewportRect(viewport, guide.target),
|
|
111
74
|
};
|
|
112
75
|
}
|
|
113
76
|
function spacingDescriptorMatches(affordance, descriptor) {
|
|
@@ -191,7 +154,7 @@ function releasePendingSpacingCommits(pending, iframe) {
|
|
|
191
154
|
function reconcilePendingSpacingCommits(pending) {
|
|
192
155
|
if (pending.length === 0)
|
|
193
156
|
return;
|
|
194
|
-
const survivingKeys = new Set(
|
|
157
|
+
const survivingKeys = new Set(getActiveDraftChanges().changes.map(changeKey));
|
|
195
158
|
let write = 0;
|
|
196
159
|
for (const commit of pending) {
|
|
197
160
|
if (commit.keys.some((key) => survivingKeys.has(key))) {
|
|
@@ -227,16 +190,6 @@ function pushPendingSpacingCommit(pending, next) {
|
|
|
227
190
|
originalInlinePriority: pending[existing].originalInlinePriority,
|
|
228
191
|
};
|
|
229
192
|
}
|
|
230
|
-
function sendMeasureModifier(iframe, cardId, altKey) {
|
|
231
|
-
iframe.contentWindow?.postMessage({
|
|
232
|
-
type: "measure-modifier",
|
|
233
|
-
protocolVersion: PROTOCOL_VERSION,
|
|
234
|
-
projectId: PROJECT_ID,
|
|
235
|
-
workspaceId: WORKSPACE_ID,
|
|
236
|
-
cardId,
|
|
237
|
-
altKey,
|
|
238
|
-
}, window.location.origin);
|
|
239
|
-
}
|
|
240
193
|
export function CanvasElementOverlay() {
|
|
241
194
|
const [hover, setHover] = useState(null);
|
|
242
195
|
const [measureState, setMeasureState] = useState(null);
|
|
@@ -257,10 +210,9 @@ export function CanvasElementOverlay() {
|
|
|
257
210
|
setHover(null);
|
|
258
211
|
setMeasureState(null);
|
|
259
212
|
}, [layoutTransitioning]);
|
|
260
|
-
const projectionZoom = presentation === "focus" ? 1 : camera.zoom;
|
|
261
213
|
const cards = useCanvasCards(); // Projected geometry must follow card drag and resize updates.
|
|
262
214
|
const cardGeometryKey = cards.map((card) => `${card.id}:${card.x}:${card.y}:${card.width}:${card.height}`).join("|");
|
|
263
|
-
const projectionGeometryKey = `${presentation}:${camera.x}:${camera.y}:${
|
|
215
|
+
const projectionGeometryKey = `${presentation}:${camera.x}:${camera.y}:${camera.zoom}:${cardGeometryKey}`;
|
|
264
216
|
const previousProjectionGeometryKey = useRef(projectionGeometryKey);
|
|
265
217
|
const dragRef = useRef(null);
|
|
266
218
|
const spacingDragRef = useRef(null);
|
|
@@ -268,29 +220,26 @@ export function CanvasElementOverlay() {
|
|
|
268
220
|
const [spacingDragBadge, setSpacingDragBadge] = useState(null);
|
|
269
221
|
const measureAltKeyRef = useRef(false);
|
|
270
222
|
const dropGuide = useDropGuide("canvas");
|
|
271
|
-
const projectedDropGuide = projectGuideToCanvas(dropGuide
|
|
272
|
-
const selectedFrame = selected?.domElement.ownerDocument
|
|
273
|
-
const selectedInCanvas = selectedFrame
|
|
274
|
-
&& selectedFrame.hasAttribute("data-nudge-ui-canvas-renderer");
|
|
223
|
+
const projectedDropGuide = projectGuideToCanvas(dropGuide);
|
|
224
|
+
const selectedFrame = findCanvasFrameByDocument(selected?.domElement.ownerDocument);
|
|
225
|
+
const selectedInCanvas = selectedFrame !== null;
|
|
275
226
|
const selectedRects = selectedInCanvas
|
|
276
227
|
? selectedElements.map((candidate) => {
|
|
277
|
-
const frame = candidate.domElement.ownerDocument
|
|
228
|
+
const frame = findCanvasFrameByDocument(candidate.domElement.ownerDocument);
|
|
278
229
|
return frame === selectedFrame ? toRect(candidate.domElement.getBoundingClientRect()) : null;
|
|
279
230
|
})
|
|
280
231
|
: [];
|
|
281
232
|
const selectedPrimaryIndex = selectedElements.findIndex((candidate) => candidate.domElement === selected?.domElement);
|
|
282
233
|
const selectedLocalRect = selectedRects[selectedPrimaryIndex >= 0 ? selectedPrimaryIndex : 0] ?? null;
|
|
283
|
-
const
|
|
284
|
-
|
|
234
|
+
const selectedFrameViewport = selectedInCanvas ? measureFrameViewport(selectedFrame) : null;
|
|
235
|
+
const selectedRect = selectedFrameViewport && selectedLocalRect
|
|
236
|
+
? toViewportRect(selectedFrameViewport, selectedLocalRect)
|
|
285
237
|
: null;
|
|
286
|
-
const
|
|
287
|
-
? projectRect(selectedFrame, selectedLocalRect, projectionZoom)
|
|
288
|
-
: null;
|
|
289
|
-
const projectedSelectedGeometry = selectedInCanvas
|
|
238
|
+
const projectedSelectedGeometry = selectedFrameViewport
|
|
290
239
|
? selectedRects.flatMap((rect, index) => {
|
|
291
240
|
const element = selectedElements[index];
|
|
292
241
|
return rect && element
|
|
293
|
-
? [{ element, rect:
|
|
242
|
+
? [{ element, rect: toViewportRect(selectedFrameViewport, rect) }]
|
|
294
243
|
: [];
|
|
295
244
|
})
|
|
296
245
|
: [];
|
|
@@ -316,7 +265,7 @@ export function CanvasElementOverlay() {
|
|
|
316
265
|
const broadcastMeasureModifier = (altKey) => {
|
|
317
266
|
measureAltKeyRef.current = altKey;
|
|
318
267
|
for (const [cardId, iframe] of getRegisteredFrames()) {
|
|
319
|
-
|
|
268
|
+
connectFrame(cardId, iframe).post({ type: "measure-modifier", altKey });
|
|
320
269
|
}
|
|
321
270
|
};
|
|
322
271
|
const onKeyDown = (event) => {
|
|
@@ -352,7 +301,7 @@ export function CanvasElementOverlay() {
|
|
|
352
301
|
// it: undo/redo/revert/clear remove the record synchronously, so restore the
|
|
353
302
|
// authored declaration before the renderer's next replace-styles lands.
|
|
354
303
|
useEffect(() => {
|
|
355
|
-
return
|
|
304
|
+
return subscribeActiveDraftChanges(() => {
|
|
356
305
|
reconcilePendingSpacingCommits(pendingSpacingCommitsRef.current);
|
|
357
306
|
});
|
|
358
307
|
}, []);
|
|
@@ -389,14 +338,14 @@ export function CanvasElementOverlay() {
|
|
|
389
338
|
};
|
|
390
339
|
});
|
|
391
340
|
};
|
|
392
|
-
const unsubscribe = subscribeCanvasRendererMessages(({
|
|
341
|
+
const unsubscribe = subscribeCanvasRendererMessages(({ frame, message: data }) => {
|
|
393
342
|
if (data.type === "renderer-hello" || data.type === "frame-ready") {
|
|
394
|
-
|
|
343
|
+
frame.post({ type: "measure-modifier", altKey: measureAltKeyRef.current });
|
|
395
344
|
}
|
|
396
345
|
if (data.type === "renderer-hello")
|
|
397
346
|
return;
|
|
398
347
|
if (data.type === "projection-applied") {
|
|
399
|
-
releasePendingSpacingCommits(pendingSpacingCommitsRef.current,
|
|
348
|
+
releasePendingSpacingCommits(pendingSpacingCommitsRef.current, frame.iframe);
|
|
400
349
|
return;
|
|
401
350
|
}
|
|
402
351
|
if (getCanvasLayoutTransitioning())
|
|
@@ -406,18 +355,17 @@ export function CanvasElementOverlay() {
|
|
|
406
355
|
if (!msg.cid)
|
|
407
356
|
return;
|
|
408
357
|
if (msg.rect === null) {
|
|
409
|
-
setHover((current) => current?.cardId ===
|
|
358
|
+
setHover((current) => current?.cardId === frame.cardId ? null : current);
|
|
410
359
|
return;
|
|
411
360
|
}
|
|
412
361
|
const spacingDescriptor = msg.hoverSpacing ?? msg.spacing ?? null;
|
|
413
362
|
const hoverPoint = msg.point ?? null;
|
|
414
|
-
const hoverElement = spacingDescriptor
|
|
415
|
-
|
|
416
|
-
: null;
|
|
363
|
+
const hoverElement = spacingDescriptor ? frame.element(msg) : null;
|
|
364
|
+
const frameDocument = frame.document();
|
|
417
365
|
const hoverAffordance = spacingDescriptor && hoverElement
|
|
418
366
|
? getSpacingAffordanceForDescriptor(hoverElement, spacingDescriptor)
|
|
419
|
-
: spacingDescriptor && hoverPoint &&
|
|
420
|
-
? getSpacingHoverAtPoint(
|
|
367
|
+
: spacingDescriptor && hoverPoint && frameDocument
|
|
368
|
+
? getSpacingHoverAtPoint(frameDocument, hoverPoint.x, hoverPoint.y)
|
|
421
369
|
: null;
|
|
422
370
|
const matchingAffordance = spacingDescriptorMatches(hoverAffordance, spacingDescriptor)
|
|
423
371
|
? hoverAffordance
|
|
@@ -433,11 +381,11 @@ export function CanvasElementOverlay() {
|
|
|
433
381
|
? { point: hoverPoint, value: handleAffordance.value }
|
|
434
382
|
: null;
|
|
435
383
|
setHover({
|
|
436
|
-
iframe:
|
|
384
|
+
iframe: frame.iframe,
|
|
437
385
|
identity: { elementId: msg.elementId },
|
|
438
386
|
rect: msg.rect,
|
|
439
387
|
borders: msg.borders ?? { top: 0, right: 0, bottom: 0, left: 0 },
|
|
440
|
-
cardId:
|
|
388
|
+
cardId: frame.cardId,
|
|
441
389
|
spacing: spacingGuides.length > 0 ? spacingDescriptor : null,
|
|
442
390
|
spacingGuides,
|
|
443
391
|
spacingAreas,
|
|
@@ -447,29 +395,29 @@ export function CanvasElementOverlay() {
|
|
|
447
395
|
else if (data.type === "element-measure-state") {
|
|
448
396
|
const msg = data;
|
|
449
397
|
setMeasureState({
|
|
450
|
-
iframe:
|
|
398
|
+
iframe: frame.iframe,
|
|
451
399
|
altKey: msg.altKey,
|
|
452
400
|
pointerOverPage: msg.pointerOverPage,
|
|
453
401
|
});
|
|
454
402
|
}
|
|
455
403
|
else if (data.type === "element-click") {
|
|
456
|
-
if (!isElementClickMessage(data,
|
|
404
|
+
if (!isElementClickMessage(data, frame.identity))
|
|
457
405
|
return;
|
|
458
406
|
const msg = data;
|
|
459
407
|
if (!msg.cid)
|
|
460
408
|
return;
|
|
461
|
-
handleElementClick(msg,
|
|
409
|
+
handleElementClick(msg, frame);
|
|
462
410
|
}
|
|
463
411
|
else if (data.type === "inline-text-intent") {
|
|
464
|
-
if (!isInlineTextIntentMessage(data,
|
|
412
|
+
if (!isInlineTextIntentMessage(data, frame.identity))
|
|
465
413
|
return;
|
|
466
414
|
if (getSelectedElements().length > 1)
|
|
467
415
|
return;
|
|
468
416
|
const emptyProjection = data.emptyProjectionId
|
|
469
|
-
? Array.from(
|
|
417
|
+
? Array.from(frame.document()?.querySelectorAll(`[${EMPTY_TEXT_PROJECTION_ATTR}]`) ?? [])
|
|
470
418
|
.find((candidate) => candidate.getAttribute(EMPTY_TEXT_PROJECTION_ATTR) === data.emptyProjectionId)
|
|
471
419
|
: null;
|
|
472
|
-
const element = emptyProjection ??
|
|
420
|
+
const element = emptyProjection ?? frame.element(data);
|
|
473
421
|
if (!element)
|
|
474
422
|
return;
|
|
475
423
|
handleInlineTextEditIntent(data.intent === "double-click"
|
|
@@ -492,23 +440,24 @@ export function CanvasElementOverlay() {
|
|
|
492
440
|
if (getSelectedElements().length > 1)
|
|
493
441
|
return;
|
|
494
442
|
const msg = data;
|
|
495
|
-
const element =
|
|
443
|
+
const element = frame.element(msg);
|
|
496
444
|
if (!element)
|
|
497
445
|
return;
|
|
498
446
|
clearSpacingDrag(spacingDragRef);
|
|
499
447
|
dragRef.current = null;
|
|
500
448
|
const startPoint = msg.startPoint ?? msg.point;
|
|
449
|
+
const frameDocument = frame.document();
|
|
501
450
|
const spacing = msg.spacing
|
|
502
451
|
? getSpacingAffordanceForDescriptor(element, msg.spacing)
|
|
503
|
-
:
|
|
504
|
-
? getSpacingAffordanceAtPoint(
|
|
452
|
+
: frameDocument
|
|
453
|
+
? getSpacingAffordanceAtPoint(frameDocument, startPoint.x, startPoint.y)
|
|
505
454
|
: null;
|
|
506
455
|
const isSpacingDrag = spacing
|
|
507
456
|
&& spacing.element === element
|
|
508
457
|
&& (!msg.spacing || spacingDescriptorMatches(spacing, msg.spacing));
|
|
509
458
|
if (isSpacingDrag) {
|
|
510
459
|
spacingDragRef.current = {
|
|
511
|
-
iframe:
|
|
460
|
+
iframe: frame.iframe,
|
|
512
461
|
element,
|
|
513
462
|
affordance: spacing,
|
|
514
463
|
start: startPoint,
|
|
@@ -525,26 +474,26 @@ export function CanvasElementOverlay() {
|
|
|
525
474
|
refreshSpacingPreviewOverlay(spacingDragRef.current);
|
|
526
475
|
return;
|
|
527
476
|
}
|
|
528
|
-
dragRef.current = { iframe:
|
|
477
|
+
dragRef.current = { iframe: frame.iframe, element };
|
|
529
478
|
const selectedElement = resolveSelectionFromElement(element);
|
|
530
479
|
if (selectedElement)
|
|
531
480
|
setSelectedElement(selectedElement);
|
|
532
|
-
updateDropGuide(msg.point
|
|
481
|
+
updateDropGuide(msg.point);
|
|
533
482
|
}
|
|
534
483
|
else if (data.type === "element-drag-move") {
|
|
535
484
|
const spacing = spacingDragRef.current;
|
|
536
|
-
if (spacing && spacing.iframe ===
|
|
485
|
+
if (spacing && spacing.iframe === frame.iframe) {
|
|
537
486
|
applySpacingPreview(spacing, data.point, data.shiftKey === true);
|
|
538
487
|
setSpacingDragBadge(spacingBadgeForDrag(spacing, data.point));
|
|
539
488
|
refreshSpacingPreviewOverlay(spacing);
|
|
540
489
|
return;
|
|
541
490
|
}
|
|
542
|
-
updateDropGuide(data.point
|
|
491
|
+
updateDropGuide(data.point);
|
|
543
492
|
}
|
|
544
493
|
else if (data.type === "element-drag-end") {
|
|
545
494
|
const msg = data;
|
|
546
495
|
const spacing = spacingDragRef.current;
|
|
547
|
-
if (spacing && spacing.iframe ===
|
|
496
|
+
if (spacing && spacing.iframe === frame.iframe) {
|
|
548
497
|
spacingDragRef.current = null;
|
|
549
498
|
setSpacingDragBadge(null);
|
|
550
499
|
if (msg.cancelled) {
|
|
@@ -556,7 +505,7 @@ export function CanvasElementOverlay() {
|
|
|
556
505
|
const records = commitSpacingDrag(spacing);
|
|
557
506
|
if (records.length > 0) {
|
|
558
507
|
pushPendingSpacingCommit(pendingSpacingCommitsRef.current, {
|
|
559
|
-
iframe:
|
|
508
|
+
iframe: frame.iframe,
|
|
560
509
|
element: spacing.element,
|
|
561
510
|
property: spacing.affordance.property,
|
|
562
511
|
committedValue: spacingValueCss(spacing.currentValue),
|
|
@@ -576,8 +525,9 @@ export function CanvasElementOverlay() {
|
|
|
576
525
|
return;
|
|
577
526
|
}
|
|
578
527
|
const current = dragRef.current;
|
|
579
|
-
|
|
580
|
-
|
|
528
|
+
const frameDocument = frame.document();
|
|
529
|
+
if (!msg.cancelled && current && current.iframe === frame.iframe && frameDocument) {
|
|
530
|
+
const drop = getDropLocationAtPoint(frameDocument, current.element, msg.point.x, msg.point.y);
|
|
581
531
|
if (drop)
|
|
582
532
|
moveElement(current.element, drop);
|
|
583
533
|
const selectedElement = resolveSelectionFromElement(current.element);
|
|
@@ -590,8 +540,7 @@ export function CanvasElementOverlay() {
|
|
|
590
540
|
else if (data.type === "element-delete") {
|
|
591
541
|
if (getSelectedElements().length !== 1)
|
|
592
542
|
return;
|
|
593
|
-
const
|
|
594
|
-
const element = findFrameElement(sourceIframe, msg.elementId, msg.cid, msg.src);
|
|
543
|
+
const element = frame.element(data);
|
|
595
544
|
const selectedElement = element ? resolveSelectionFromElement(element) : null;
|
|
596
545
|
if (selectedElement && deleteElement(selectedElement))
|
|
597
546
|
setSelectedElement(null);
|
|
@@ -599,9 +548,8 @@ export function CanvasElementOverlay() {
|
|
|
599
548
|
else if (data.type === "element-nudge") {
|
|
600
549
|
if (getSelectedElements().length !== 1)
|
|
601
550
|
return;
|
|
602
|
-
const
|
|
603
|
-
const
|
|
604
|
-
const record = element ? nudgeElement(element, msg.key) : null;
|
|
551
|
+
const element = frame.element(data);
|
|
552
|
+
const record = element ? nudgeElement(element, data.key) : null;
|
|
605
553
|
if (element && record) {
|
|
606
554
|
const selectedElement = resolveSelectionFromElement(element);
|
|
607
555
|
if (selectedElement)
|
|
@@ -623,16 +571,17 @@ export function CanvasElementOverlay() {
|
|
|
623
571
|
else if (data.type === "inspector-open-request") {
|
|
624
572
|
setInspectorOpen(true);
|
|
625
573
|
}
|
|
626
|
-
function updateDropGuide(point
|
|
574
|
+
function updateDropGuide(point) {
|
|
627
575
|
const current = dragRef.current;
|
|
628
|
-
|
|
576
|
+
const frameDocument = frame.document();
|
|
577
|
+
if (!current || current.iframe !== frame.iframe || !frameDocument)
|
|
629
578
|
return;
|
|
630
|
-
const drop = getDropLocationAtPoint(
|
|
579
|
+
const drop = getDropLocationAtPoint(frameDocument, current.element, point.x, point.y);
|
|
631
580
|
if (!drop) {
|
|
632
581
|
clearDropGuide("canvas");
|
|
633
582
|
return;
|
|
634
583
|
}
|
|
635
|
-
showDropGuide("canvas",
|
|
584
|
+
showDropGuide("canvas", frameDocument, drop);
|
|
636
585
|
}
|
|
637
586
|
});
|
|
638
587
|
return () => {
|
|
@@ -647,20 +596,21 @@ export function CanvasElementOverlay() {
|
|
|
647
596
|
return null;
|
|
648
597
|
if (!hover && projectedSelectedGeometry.length === 0 && !projectedDropGuide)
|
|
649
598
|
return null;
|
|
650
|
-
const
|
|
651
|
-
const
|
|
652
|
-
const
|
|
599
|
+
const hoverViewport = hover ? measureFrameViewport(hover.iframe) : null;
|
|
600
|
+
const projectedHoverRect = hover && hoverViewport ? toViewportRect(hoverViewport, hover.rect) : null;
|
|
601
|
+
const projectedSpacingGuides = hover && hoverViewport ? hover.spacingGuides.map((guide) => toViewportRect(hoverViewport, guide)) : [];
|
|
602
|
+
const projectedSpacingAreas = hover && hoverViewport ? hover.spacingAreas.map((area) => toViewportRect(hoverViewport, area)) : [];
|
|
653
603
|
const spacingBadge = spacingDragBadge
|
|
654
604
|
?? (hover?.spacingHandleBadge ? { iframe: hover.iframe, ...hover.spacingHandleBadge } : null);
|
|
655
605
|
const projectedSpacingBadge = spacingBadge
|
|
656
|
-
?
|
|
606
|
+
? toViewportPoint(measureFrameViewport(spacingBadge.iframe), spacingBadge.point)
|
|
657
607
|
: null;
|
|
658
608
|
const hoverSpacing = hover?.spacing ?? null;
|
|
659
609
|
const measureStateForSelectedFrame = measureState?.iframe === selectedFrame ? measureState : null;
|
|
660
610
|
const hoverInSelectedFrame = hover?.iframe === selectedFrame ? hover : null;
|
|
661
611
|
const showGuideOverlay = Boolean(selectedElements.length === 1
|
|
662
612
|
&& selectedRect
|
|
663
|
-
&&
|
|
613
|
+
&& selectedFrameViewport
|
|
664
614
|
&& measureStateForSelectedFrame?.altKey
|
|
665
615
|
&& measureStateForSelectedFrame.pointerOverPage);
|
|
666
616
|
const isSelfHover = Boolean(hoverInSelectedFrame
|
|
@@ -673,15 +623,20 @@ export function CanvasElementOverlay() {
|
|
|
673
623
|
&& selectedLocalRect
|
|
674
624
|
&& hoverInSelectedFrame
|
|
675
625
|
&& !isSelfHover);
|
|
676
|
-
|
|
677
|
-
|
|
626
|
+
// Segment distances stay in frame CSS pixels so labels read the same at any board zoom.
|
|
627
|
+
const measurementSegments = showMeasurement && selectedFrameViewport && selectedLocalRect && hoverInSelectedFrame
|
|
628
|
+
? getMeasurementGeometry(selectedLocalRect, hoverInSelectedFrame.rect, {
|
|
678
629
|
selectedBorders: selectedBorders ?? undefined,
|
|
679
630
|
hoveredBorders: hoverInSelectedFrame.borders,
|
|
680
|
-
}).segments
|
|
631
|
+
}).segments.map((segment) => ({
|
|
632
|
+
...segment,
|
|
633
|
+
from: toViewportPoint(selectedFrameViewport, segment.from),
|
|
634
|
+
to: toViewportPoint(selectedFrameViewport, segment.to),
|
|
635
|
+
}))
|
|
681
636
|
: [];
|
|
682
637
|
if (presentationTransitioning || layoutTransitioning || temporaryAppInteraction)
|
|
683
|
-
return _jsx(
|
|
684
|
-
return (_jsxs(_Fragment, { children: [_jsx(
|
|
685
|
-
?
|
|
638
|
+
return _jsx(InspectorStyle, { testId: "canvas-element-overlay-styles", css: overlayStyles });
|
|
639
|
+
return (_jsxs(_Fragment, { children: [_jsx(InspectorStyle, { testId: "canvas-element-overlay-styles", css: overlayStyles }), showGuideOverlay && selectedRect && selectedFrameViewport ? (_jsx(MeasurementGuideOverlay, { testId: "canvas-measurement-overlay", selectedRect: selectedRect, guideViewport: selectedFrameViewport, segments: measurementSegments })) : null, projectedHoverRect ? (_jsxs(_Fragment, { children: [hoverSpacing ? projectedSpacingAreas.map((area, index) => (_jsx("div", { className: "canvas-spacing-fill", "data-test": "canvas-spacing-fill", "data-kind": hoverSpacing.kind, "data-property": hoverSpacing.property, "data-side": hoverSpacing.side ?? undefined, "data-area-index": index, style: overlayStyle(area), "aria-hidden": "true" }, `${hoverSpacing.property}-area-${index}`))) : null, showHoverOutline ? (_jsx("div", { className: "canvas-element-overlay", "data-test": "canvas-hover-outline", style: overlayStyle(projectedHoverRect), "aria-hidden": "true" })) : null, hoverSpacing ? projectedSpacingGuides.map((guide, index) => (_jsx("div", { className: "canvas-spacing-guide", "data-test": "canvas-spacing-guide", "data-kind": hoverSpacing.kind, "data-property": hoverSpacing.property, "data-side": hoverSpacing.side ?? undefined, "data-guide-index": index, style: spacingGuideStyle(guide), "aria-hidden": "true" }, `${hoverSpacing.property}-${index}`))) : null] })) : null, projectedSelectedGeometry.map(({ element, rect }, index) => (_jsx("div", { className: "canvas-selected-outline", "data-test": "canvas-selected-outline", "data-selected-cid": element.cid, "data-selected-index": index, "data-selected-src": element.src, style: overlayStyle(rect), "aria-hidden": "true" }, `${element.cid}-${index}`))), projectedSpacingBadge && spacingBadge ? (_jsx("div", { className: "canvas-spacing-value-badge", "data-test": "canvas-spacing-value-badge", style: { left: projectedSpacingBadge.x, top: projectedSpacingBadge.y }, "aria-hidden": "true", children: spacingValueCss(spacingBadge.value) })) : null, domNavigationEnabled && !inlineTextSession && selectedElements.length === 1 && selected && selectedRect && selectedFrameViewport ? (_jsx(DomNavigator, { selected: selected, hierarchy: hierarchy, anchor: selectedRect, project: (element) => element.ownerDocument === selected.domElement.ownerDocument
|
|
640
|
+
? toViewportRect(selectedFrameViewport, toRect(element.getBoundingClientRect()))
|
|
686
641
|
: null })) : null, _jsx(DropGuideOverlay, { guide: projectedDropGuide, lineClassName: "canvas-dom-drop-line", lineTestId: "canvas-dom-drop-line", targetClassName: "canvas-dom-drop-target", targetTestId: "canvas-dom-drop-target" })] }));
|
|
687
642
|
}
|