nudge-ui 0.2.3 → 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 +870 -212
- 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 +5 -7
- package/dist/inspector/agent/verification.js +67 -20
- 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 +23 -12
- package/dist/inspector/canvas/CanvasElementOverlay.js +97 -128
- package/dist/inspector/canvas/CanvasToolbar.js +2 -1
- package/dist/inspector/canvas/CanvasWorkspace.js +119 -162
- 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/frameScrollbarStyles.d.ts +3 -0
- package/dist/inspector/canvas/frameScrollbarStyles.js +21 -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 +2 -0
- package/dist/inspector/changes/codecs.js +27 -3
- package/dist/inspector/changes/draftPreview.d.ts +12 -0
- package/dist/inspector/changes/draftPreview.js +133 -0
- package/dist/inspector/changes/editModel.d.ts +18 -0
- package/dist/inspector/changes/editModel.js +16 -3
- package/dist/inspector/changes/managedStyleProjection.js +2 -1
- package/dist/inspector/changes/previewDiagnostics.js +1 -1
- package/dist/inspector/changes/types.d.ts +18 -1
- package/dist/inspector/comments/CommentsOverlay.js +18 -16
- package/dist/inspector/comments/element.js +10 -3
- 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/adapterRegistry.d.ts +6 -1
- package/dist/inspector/componentSemantics/adapterRegistry.js +23 -1
- package/dist/inspector/componentSemantics/changeAction.js +1 -1
- package/dist/inspector/componentSemantics/reactRuntime.d.ts +2 -1
- package/dist/inspector/componentSemantics/reactRuntime.js +38 -0
- package/dist/inspector/componentSemantics/runtimeBridge.d.ts +4 -2
- package/dist/inspector/componentSemantics/runtimeBridge.js +17 -0
- package/dist/inspector/componentSemantics/textBinding.d.ts +1 -2
- package/dist/inspector/componentSemantics/textBinding.js +4 -45
- package/dist/inspector/componentSemantics/types.d.ts +11 -0
- 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/capture.js +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.d.ts +15 -2
- package/dist/inspector/projection/renderedInstance.js +60 -7
- package/dist/inspector/projection/structuralProjection.d.ts +0 -9
- package/dist/inspector/projection/structuralProjection.js +16 -46
- package/dist/inspector/projection/textProjection.d.ts +8 -2
- package/dist/inspector/projection/textProjection.js +77 -24
- package/dist/inspector/prompt/clipboardHandoff.d.ts +14 -0
- package/dist/inspector/prompt/clipboardHandoff.js +47 -16
- package/dist/inspector/prompt/generatePrompt.d.ts +1 -1
- package/dist/inspector/prompt/generatePrompt.js +248 -148
- 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/selection/sourceSite.d.ts +12 -0
- package/dist/inspector/selection/sourceSite.js +28 -0
- 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 +74 -26
- 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 +3 -2
- 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 +40 -7
- package/dist/inspector/tokens/TokensPanel.js +2 -1
- package/dist/inspector/tokens/editActions.d.ts +3 -3
- package/dist/inspector/tokens/editActions.js +15 -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 +16 -0
- package/dist/inspector/workspace/sentItems.js +33 -0
- 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 +13 -3
- 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 -47
- package/dist/inspector/changes/changesLog.js +0 -247
- package/dist/inspector/changes/draftChanges.d.ts +0 -56
- package/dist/inspector/changes/draftChanges.js +0 -300
- 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
|
@@ -19,6 +19,42 @@ import { isStructuralProjectionReport } from "../projection/structuralProjection
|
|
|
19
19
|
// added the renderer-hello handshake solicitation for runtimes whose boot
|
|
20
20
|
// completes after the controller's load-time parent-ready.
|
|
21
21
|
export const PROTOCOL_VERSION = 21;
|
|
22
|
+
const RENDERER_MESSAGE_TYPES = {
|
|
23
|
+
"renderer-hello": true,
|
|
24
|
+
"frame-ready": true,
|
|
25
|
+
"frame-runtime": true,
|
|
26
|
+
"frame-metadata": true,
|
|
27
|
+
"frame-error": true,
|
|
28
|
+
"projection-applied": true,
|
|
29
|
+
"structural-projection-report": true,
|
|
30
|
+
"rendered-instance-projection-report": true,
|
|
31
|
+
"text-projection-report": true,
|
|
32
|
+
"navigation-intent": true,
|
|
33
|
+
"element-hover": true,
|
|
34
|
+
"element-measure-state": true,
|
|
35
|
+
"element-click": true,
|
|
36
|
+
"inline-text-intent": true,
|
|
37
|
+
"element-deselect": true,
|
|
38
|
+
"element-drag-start": true,
|
|
39
|
+
"element-drag-move": true,
|
|
40
|
+
"element-drag-end": true,
|
|
41
|
+
"element-delete": true,
|
|
42
|
+
"element-nudge": true,
|
|
43
|
+
"history-request": true,
|
|
44
|
+
"inspector-toggle-request": true,
|
|
45
|
+
"inspector-open-request": true,
|
|
46
|
+
"keyboard-shortcut": true,
|
|
47
|
+
"pan-start": true,
|
|
48
|
+
"pan-move": true,
|
|
49
|
+
"pan-end": true,
|
|
50
|
+
"pan-modifier": true,
|
|
51
|
+
"zoom": true,
|
|
52
|
+
"wheel-pan": true,
|
|
53
|
+
"app-interaction-modifier": true,
|
|
54
|
+
};
|
|
55
|
+
export function isRendererMessageType(type) {
|
|
56
|
+
return typeof type === "string" && Object.hasOwn(RENDERER_MESSAGE_TYPES, type);
|
|
57
|
+
}
|
|
22
58
|
let rendererIdentity = null;
|
|
23
59
|
export function setRendererIdentity(identity) {
|
|
24
60
|
rendererIdentity = identity;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export const FRAME_SCROLLBAR_STYLE_ID = "nudge-ui-frame-scrollbar-styles";
|
|
2
|
+
// `:where()` keeps specificity at zero so any application scrollbar rule wins.
|
|
3
|
+
const FRAME_SCROLLBAR_CSS = `
|
|
4
|
+
:where(html) {
|
|
5
|
+
scrollbar-color: rgba(128, 128, 128, 0.5) transparent;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
:where(*) {
|
|
9
|
+
scrollbar-width: thin;
|
|
10
|
+
}
|
|
11
|
+
`;
|
|
12
|
+
/** Gives frame documents thin scrollbars over a transparent track by default. */
|
|
13
|
+
export function installFrameScrollbarStyles(doc) {
|
|
14
|
+
if (!doc.head || doc.getElementById(FRAME_SCROLLBAR_STYLE_ID))
|
|
15
|
+
return () => undefined;
|
|
16
|
+
const style = doc.createElement("style");
|
|
17
|
+
style.id = FRAME_SCROLLBAR_STYLE_ID;
|
|
18
|
+
style.textContent = FRAME_SCROLLBAR_CSS;
|
|
19
|
+
doc.head.append(style);
|
|
20
|
+
return () => style.remove();
|
|
21
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { CanvasFrame } from "./canvasFrame.js";
|
|
2
|
+
/**
|
|
3
|
+
* Runs the renderer and controller in the inspected window. The single Canvas
|
|
4
|
+
* card is the page itself, so no iframe or framing permission is needed.
|
|
5
|
+
*/
|
|
6
|
+
export declare function enablePageSurface(): void;
|
|
7
|
+
export declare function isPageSurface(): boolean;
|
|
8
|
+
/** The page-surface card's frame: the inspected window, filling the viewport. */
|
|
9
|
+
export declare function getPageFrame(win?: Window): CanvasFrame;
|
|
10
|
+
/** True for events that start inside the inspector's own shadow root. */
|
|
11
|
+
export declare function isInspectorUiEvent(event: Event): boolean;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { NUDGE_UI_MOUNT_ID } from "../../transport/routes.js";
|
|
2
|
+
let pageSurface = false;
|
|
3
|
+
/**
|
|
4
|
+
* Runs the renderer and controller in the inspected window. The single Canvas
|
|
5
|
+
* card is the page itself, so no iframe or framing permission is needed.
|
|
6
|
+
*/
|
|
7
|
+
export function enablePageSurface() {
|
|
8
|
+
pageSurface = true;
|
|
9
|
+
}
|
|
10
|
+
export function isPageSurface() {
|
|
11
|
+
return pageSurface;
|
|
12
|
+
}
|
|
13
|
+
const pageFrames = new WeakMap();
|
|
14
|
+
/** The page-surface card's frame: the inspected window, filling the viewport. */
|
|
15
|
+
export function getPageFrame(win = window) {
|
|
16
|
+
const existing = pageFrames.get(win);
|
|
17
|
+
if (existing)
|
|
18
|
+
return existing;
|
|
19
|
+
const root = win.document.documentElement;
|
|
20
|
+
const frame = {
|
|
21
|
+
contentWindow: win,
|
|
22
|
+
contentDocument: win.document,
|
|
23
|
+
isConnected: true,
|
|
24
|
+
get clientWidth() { return root.clientWidth; },
|
|
25
|
+
get clientHeight() { return root.clientHeight; },
|
|
26
|
+
getBoundingClientRect: () => new DOMRect(0, 0, root.clientWidth, root.clientHeight),
|
|
27
|
+
};
|
|
28
|
+
pageFrames.set(win, frame);
|
|
29
|
+
return frame;
|
|
30
|
+
}
|
|
31
|
+
/** True for events that start inside the inspector's own shadow root. */
|
|
32
|
+
export function isInspectorUiEvent(event) {
|
|
33
|
+
return pageSurface && event.composedPath().some((node) => node instanceof Element && node.id === NUDGE_UI_MOUNT_ID);
|
|
34
|
+
}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { CanvasFrame } from "./canvasFrame.js";
|
|
2
|
+
import type { DraftContents } from "../drafts/model.js";
|
|
2
3
|
import type { CanvasCard } from "./canvasStore.js";
|
|
3
4
|
import { type PreviewDocument } from "../changes/previewDiagnostics.js";
|
|
4
5
|
import { type CompiledManagedStyles, type DraftProjectionPlan } from "../projection/draftProjection.js";
|
|
5
|
-
export declare const PROJECT_ID: string;
|
|
6
|
-
export declare const WORKSPACE_ID: string;
|
|
7
6
|
export interface FrameProjection extends DraftProjectionPlan<CompiledManagedStyles> {
|
|
8
7
|
readonly draftId: string;
|
|
9
8
|
readonly draftRevision: number;
|
|
@@ -27,27 +26,36 @@ export declare function computeProjection(): {
|
|
|
27
26
|
structuralChanges: readonly import("../changes/structuralTypes.js").StructuralChange[];
|
|
28
27
|
textContentChanges: readonly import("../changes/editModel.js").TextContentChangeRecord[];
|
|
29
28
|
componentOverrides: readonly import("../componentSemantics/types.js").ComponentOverride[];
|
|
29
|
+
runtimeIdentities?: readonly import("../runtime/runtimeIdentityClaims.js").RuntimeIdentityClaim[];
|
|
30
30
|
};
|
|
31
31
|
export declare function computeProjectionForCard(cardId: string): FrameProjection;
|
|
32
32
|
export declare function getCanonicalFrameProjection(cardId: string, expectedRevision: number): FrameProjection | null;
|
|
33
|
-
|
|
33
|
+
/**
|
|
34
|
+
* Re-sends the canonical projection after a temporary verification projection
|
|
35
|
+
* and settles once the renderer acknowledges it, so callers can treat the
|
|
36
|
+
* acknowledgement's stylesheet invalidation as part of their own work.
|
|
37
|
+
*/
|
|
38
|
+
export declare function restoreCanonicalFrameProjection(doc: Document): Promise<void>;
|
|
34
39
|
export declare function getCanvasCardIdForDocument(doc: Document): string | null;
|
|
35
40
|
export declare function resetProjectionRevision(): void;
|
|
36
|
-
|
|
41
|
+
/** Sends the canonical projection and returns its revision, or null when the frame has no window. */
|
|
42
|
+
export declare function sendProjectionToCard(card: Pick<CanvasCard, "id">, iframe: CanvasFrame): number | null;
|
|
37
43
|
/** Temporarily projects a snapshot through the renderer that owns the document. */
|
|
38
44
|
export declare function projectDraftToDocument(doc: Document, snapshot: DraftContents): Promise<number | null>;
|
|
39
45
|
/** Returns whether an acknowledged temporary projection is still authoritative. */
|
|
40
46
|
export declare function isCanvasProjectionRevisionCurrent(doc: Document, expectedRevision: number): boolean;
|
|
41
47
|
/** Returns whether the live frame acknowledged its latest canonical workspace projection. */
|
|
42
48
|
export declare function isCanvasCanonicalProjectionRevisionCurrent(doc: Document, expectedRevision: number): boolean;
|
|
43
|
-
export declare function registerCardFrameSource(cardId: string, iframe:
|
|
44
|
-
export declare function registerCardFrame(cardId: string, iframe:
|
|
49
|
+
export declare function registerCardFrameSource(cardId: string, iframe: CanvasFrame): void;
|
|
50
|
+
export declare function registerCardFrame(cardId: string, iframe: CanvasFrame): void;
|
|
45
51
|
export declare function unregisterCardFrame(cardId: string): void;
|
|
46
|
-
export declare function getRegisteredFrames(): ReadonlyMap<string,
|
|
52
|
+
export declare function getRegisteredFrames(): ReadonlyMap<string, CanvasFrame>;
|
|
47
53
|
export declare function findCanvasFrameBySource(source: MessageEventSource | null): {
|
|
48
54
|
cardId: string;
|
|
49
|
-
iframe:
|
|
55
|
+
iframe: CanvasFrame;
|
|
50
56
|
} | null;
|
|
57
|
+
/** The registered frame rendering `doc`, which may be the controller document on the page surface. */
|
|
58
|
+
export declare function findCanvasFrameByDocument(doc: Document | null | undefined): CanvasFrame | null;
|
|
51
59
|
export declare function subscribeFrameRegistry(listener: () => void): () => void;
|
|
52
60
|
/** Records the highest complete projection revision accepted by one frame. */
|
|
53
61
|
export declare function recordCanvasProjectionApplied(cardId: string, appliedRevision: number): void;
|
|
@@ -55,4 +63,6 @@ export declare function recordCanvasProjectionApplied(cardId: string, appliedRev
|
|
|
55
63
|
export declare function getCanvasProjectionStatus(doc: Document): CanvasProjectionStatus | null;
|
|
56
64
|
export declare function subscribeCanvasProjectionAcknowledgements(listener: () => void): () => void;
|
|
57
65
|
export declare function getCanvasProjectionAcknowledgementVersion(): number;
|
|
66
|
+
/** Changes whenever a frame registers or unregisters, for `useSyncExternalStore`. */
|
|
67
|
+
export declare function getFrameRegistryVersion(): number;
|
|
58
68
|
export declare function projectToAllReadyCards(): void;
|
|
@@ -1,21 +1,14 @@
|
|
|
1
|
-
import { draftIdForCard } from "../drafts/store.js";
|
|
2
|
-
import { getDraftChanges, getActiveDraftChanges } from "../changes/draftChanges.js";
|
|
1
|
+
import { draftIdForCard, getDraftChanges, getActiveDraftChanges } from "../drafts/store.js";
|
|
3
2
|
import { getCanvasCards } from "./canvasStore.js";
|
|
4
3
|
import { getCanvasMode } from "./viewStore.js";
|
|
5
|
-
import {
|
|
4
|
+
import { connectFrame } from "./frameConnection.js";
|
|
6
5
|
import { clearCanvasRenderedInstanceProjectionReports, setCanonicalRenderedInstanceOverrides, } from "../projection/renderedInstance.js";
|
|
7
6
|
import { clearCanvasTextProjectionReports, setCanonicalTextContentChanges, } from "../projection/textProjection.js";
|
|
8
7
|
import { clearCanvasStructuralProjectionReports } from "../projection/structuralProjection.js";
|
|
9
8
|
import { invalidatePreviewDocumentSession, startPreviewDocumentSession, } from "../changes/previewDiagnostics.js";
|
|
10
9
|
import { compileDraftProjection, } from "../projection/draftProjection.js";
|
|
11
10
|
import { isOriginalPreviewActive } from "../shell/originalPreview.js";
|
|
12
|
-
import { disposeBrowserCssInspection } from "../inspection/browserCssInspectionRegistry.js";
|
|
13
|
-
export const PROJECT_ID = typeof window !== "undefined" && window.location?.origin
|
|
14
|
-
? window.location.origin
|
|
15
|
-
: "";
|
|
16
|
-
export const WORKSPACE_ID = typeof crypto !== "undefined" && typeof crypto.randomUUID === "function"
|
|
17
|
-
? crypto.randomUUID()
|
|
18
|
-
: `ws-${Date.now()}`;
|
|
11
|
+
import { disposeBrowserCssInspection, notifyBrowserStylesheetChange } from "../inspection/browserCssInspectionRegistry.js";
|
|
19
12
|
let revision = 0;
|
|
20
13
|
let lastRulesKey = null;
|
|
21
14
|
let lastPeekActive = false;
|
|
@@ -116,12 +109,20 @@ export function getCanonicalFrameProjection(cardId, expectedRevision) {
|
|
|
116
109
|
return null;
|
|
117
110
|
return plan;
|
|
118
111
|
}
|
|
119
|
-
|
|
112
|
+
/**
|
|
113
|
+
* Re-sends the canonical projection after a temporary verification projection
|
|
114
|
+
* and settles once the renderer acknowledges it, so callers can treat the
|
|
115
|
+
* acknowledgement's stylesheet invalidation as part of their own work.
|
|
116
|
+
*/
|
|
117
|
+
export async function restoreCanonicalFrameProjection(doc) {
|
|
120
118
|
const id = getCanvasCardIdForDocument(doc);
|
|
121
119
|
const card = getCanvasCards().find((card) => card.id === id);
|
|
122
120
|
const frame = id ? frameRegistry.get(id) : undefined;
|
|
123
|
-
if (card
|
|
124
|
-
|
|
121
|
+
if (!card || !frame)
|
|
122
|
+
return;
|
|
123
|
+
const sent = sendProjectionToCard(card, frame);
|
|
124
|
+
if (sent !== null)
|
|
125
|
+
await waitForProjectionApplied(card.id, doc, sent);
|
|
125
126
|
}
|
|
126
127
|
export function getCanvasCardIdForDocument(doc) {
|
|
127
128
|
for (const [id, state] of frameProjectionStates)
|
|
@@ -143,10 +144,11 @@ export function resetProjectionRevision() {
|
|
|
143
144
|
projectionAcknowledgementVersion += 1;
|
|
144
145
|
notifyProjectionAcknowledgementListeners();
|
|
145
146
|
}
|
|
147
|
+
/** Sends the canonical projection and returns its revision, or null when the frame has no window. */
|
|
146
148
|
export function sendProjectionToCard(card, iframe) {
|
|
147
149
|
const win = iframe.contentWindow;
|
|
148
150
|
if (!win)
|
|
149
|
-
return;
|
|
151
|
+
return null;
|
|
150
152
|
let plan = computeProjectionForCard(card.id);
|
|
151
153
|
const state = frameProjectionStates.get(card.id);
|
|
152
154
|
if (state && plan.revision < state.sentRevision) {
|
|
@@ -155,28 +157,24 @@ export function sendProjectionToCard(card, iframe) {
|
|
|
155
157
|
}
|
|
156
158
|
if (state)
|
|
157
159
|
state.canonicalProjection = plan;
|
|
158
|
-
const { css, revision: rev, instanceOverrides, structuralChanges, textContentChanges, componentOverrides } = plan;
|
|
159
|
-
sendProjectionMessage(card.id, iframe, rev, css, instanceOverrides, structuralChanges, textContentChanges, componentOverrides, true);
|
|
160
|
+
const { css, revision: rev, instanceOverrides, structuralChanges, textContentChanges, componentOverrides, runtimeIdentities } = plan;
|
|
161
|
+
sendProjectionMessage(card.id, iframe, rev, css, instanceOverrides, structuralChanges, textContentChanges, componentOverrides, runtimeIdentities, true);
|
|
162
|
+
return rev;
|
|
160
163
|
}
|
|
161
|
-
function sendProjectionMessage(cardId, iframe, rev, css, instanceOverrides, structuralChanges, textContentChanges, componentOverrides, canonical = false) {
|
|
162
|
-
|
|
163
|
-
if (!win)
|
|
164
|
+
function sendProjectionMessage(cardId, iframe, rev, css, instanceOverrides, structuralChanges, textContentChanges, componentOverrides, runtimeIdentities, canonical = false) {
|
|
165
|
+
if (!iframe.contentWindow)
|
|
164
166
|
return;
|
|
165
|
-
|
|
167
|
+
markProjectionSent(cardId, iframe, rev, canonical);
|
|
168
|
+
connectFrame(cardId, iframe).post({
|
|
166
169
|
type: "replace-styles",
|
|
167
|
-
protocolVersion: PROTOCOL_VERSION,
|
|
168
|
-
projectId: PROJECT_ID,
|
|
169
|
-
workspaceId: WORKSPACE_ID,
|
|
170
|
-
cardId,
|
|
171
170
|
css,
|
|
172
171
|
revision: rev,
|
|
173
172
|
instanceOverrides: [...instanceOverrides],
|
|
174
173
|
structuralChanges: [...structuralChanges],
|
|
175
174
|
textContentChanges: [...textContentChanges],
|
|
176
175
|
componentOverrides: [...componentOverrides],
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
win.postMessage(msg, window.location.origin);
|
|
176
|
+
...(runtimeIdentities ? { runtimeIdentities: [...runtimeIdentities] } : {}),
|
|
177
|
+
});
|
|
180
178
|
}
|
|
181
179
|
/** Temporarily projects a snapshot through the renderer that owns the document. */
|
|
182
180
|
export async function projectDraftToDocument(doc, snapshot) {
|
|
@@ -186,10 +184,18 @@ export async function projectDraftToDocument(doc, snapshot) {
|
|
|
186
184
|
const [cardId, state] = entry;
|
|
187
185
|
const plan = compileDraftProjection({ ...snapshot, revision: 0 });
|
|
188
186
|
revision += 1;
|
|
189
|
-
sendProjectionMessage(cardId, state.iframe, revision, plan.managedStyles.css, plan.instanceOverrides, plan.structuralChanges, plan.textContentChanges, plan.componentOverrides);
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
187
|
+
sendProjectionMessage(cardId, state.iframe, revision, plan.managedStyles.css, plan.instanceOverrides, plan.structuralChanges, plan.textContentChanges, plan.componentOverrides, plan.runtimeIdentities);
|
|
188
|
+
return waitForProjectionApplied(cardId, doc, revision);
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Resolves with `requestedRevision` once the frame acknowledges it, or null
|
|
192
|
+
* when a newer projection supersedes it, the frame is replaced, or 2s pass.
|
|
193
|
+
*/
|
|
194
|
+
function waitForProjectionApplied(cardId, doc, requestedRevision) {
|
|
195
|
+
const initial = frameProjectionStates.get(cardId);
|
|
196
|
+
if (initial?.appliedRevision === requestedRevision && initial.sentRevision === requestedRevision) {
|
|
197
|
+
return Promise.resolve(requestedRevision);
|
|
198
|
+
}
|
|
193
199
|
return new Promise((resolve) => {
|
|
194
200
|
let settled = false;
|
|
195
201
|
let timer;
|
|
@@ -304,6 +310,16 @@ export function findCanvasFrameBySource(source) {
|
|
|
304
310
|
}
|
|
305
311
|
return null;
|
|
306
312
|
}
|
|
313
|
+
/** The registered frame rendering `doc`, which may be the controller document on the page surface. */
|
|
314
|
+
export function findCanvasFrameByDocument(doc) {
|
|
315
|
+
if (!doc)
|
|
316
|
+
return null;
|
|
317
|
+
for (const iframe of frameRegistry.values()) {
|
|
318
|
+
if (getFrameDocument(iframe) === doc)
|
|
319
|
+
return iframe;
|
|
320
|
+
}
|
|
321
|
+
return null;
|
|
322
|
+
}
|
|
307
323
|
const frameRegistryListeners = new Set();
|
|
308
324
|
export function subscribeFrameRegistry(listener) {
|
|
309
325
|
frameRegistryListeners.add(listener);
|
|
@@ -333,6 +349,11 @@ export function recordCanvasProjectionApplied(cardId, appliedRevision) {
|
|
|
333
349
|
if (!state || appliedRevision > state.sentRevision || appliedRevision <= state.appliedRevision)
|
|
334
350
|
return;
|
|
335
351
|
state.appliedRevision = appliedRevision;
|
|
352
|
+
// Adopted stylesheet writes in the renderer do not emit DOM mutations or
|
|
353
|
+
// invalidate the controller's separate CSSOM cache.
|
|
354
|
+
if (state.document && state.iframe.contentDocument === state.document) {
|
|
355
|
+
notifyBrowserStylesheetChange(state.document);
|
|
356
|
+
}
|
|
336
357
|
projectionAcknowledgementVersion += 1;
|
|
337
358
|
notifyProjectionAcknowledgementListeners();
|
|
338
359
|
}
|
|
@@ -365,7 +386,13 @@ function notifyProjectionAcknowledgementListeners() {
|
|
|
365
386
|
catch { /* ignore */ }
|
|
366
387
|
}
|
|
367
388
|
}
|
|
389
|
+
let frameRegistryVersion = 0;
|
|
390
|
+
/** Changes whenever a frame registers or unregisters, for `useSyncExternalStore`. */
|
|
391
|
+
export function getFrameRegistryVersion() {
|
|
392
|
+
return frameRegistryVersion;
|
|
393
|
+
}
|
|
368
394
|
function notifyFrameRegistryListeners() {
|
|
395
|
+
frameRegistryVersion += 1;
|
|
369
396
|
for (const listener of frameRegistryListeners) {
|
|
370
397
|
try {
|
|
371
398
|
listener();
|
|
@@ -7,6 +7,8 @@ import { createFrameThrottle } from "../overlay/frameThrottle.js";
|
|
|
7
7
|
import { isNudgeUiDev } from "../runtime/devFlag.js";
|
|
8
8
|
import { getNudgeUiRuntimeConfig, subscribeNudgeUiRuntime } from "../runtime/runtimeConfig.js";
|
|
9
9
|
import { APP_INTERACTION_KEY } from "./keyboardShortcuts.js";
|
|
10
|
+
import { isInspectorUiEvent } from "./pageSurface.js";
|
|
11
|
+
import { disposeRuntimeIdentityClaims } from "../runtime/runtimeIdentityClaims.js";
|
|
10
12
|
let activeRendererBootstrap = null;
|
|
11
13
|
function ownsRendererBootstrap(owner) {
|
|
12
14
|
return owner.active && activeRendererBootstrap?.owner === owner;
|
|
@@ -149,6 +151,7 @@ export function bootstrapRenderer() {
|
|
|
149
151
|
activeRendererBootstrap = { owner, handle };
|
|
150
152
|
try {
|
|
151
153
|
observeFrameMetadata(owner);
|
|
154
|
+
owner.resourceDisposers.push(() => disposeRuntimeIdentityClaims(document));
|
|
152
155
|
owner.resourceDisposers.push(subscribeNudgeUiRuntime(() => sendFrameRuntime(owner)));
|
|
153
156
|
const disposeDiagnostics = startRendererProjectionDiagnostics();
|
|
154
157
|
if (disposeDiagnostics)
|
|
@@ -319,7 +322,7 @@ function installRendererPanProxy(owner) {
|
|
|
319
322
|
sendToParent({ type: "app-interaction-modifier", protocolVersion: PROTOCOL_VERSION, held, ...identity });
|
|
320
323
|
}
|
|
321
324
|
const onKeyDown = (event) => {
|
|
322
|
-
if (!ownsRendererBootstrap(owner))
|
|
325
|
+
if (!ownsRendererBootstrap(owner) || isInspectorUiEvent(event))
|
|
323
326
|
return;
|
|
324
327
|
if (event.code === APP_INTERACTION_KEY && !event.repeat && !isEditableTarget(event.target))
|
|
325
328
|
sendAppInteractionModifier(true);
|
|
@@ -11,6 +11,7 @@ import { APPLICATION_GESTURE_EVENTS, blockApplicationClick, blockApplicationGest
|
|
|
11
11
|
import { EMPTY_TEXT_PROJECTION_ATTR } from "../projection/textProjection.js";
|
|
12
12
|
import { getSpacingAffordanceAtPoint, getSpacingHoverAtPoint, toSpacingDescriptor, } from "../overlay/spacingGestures.js";
|
|
13
13
|
import { COMMENT_CURSOR, INTERACTION_CURSOR_PROPERTY, rendererCursorValue } from "../ui/customCursors.js";
|
|
14
|
+
import { isInspectorUiEvent, isPageSurface } from "./pageSurface.js";
|
|
14
15
|
const REACT_FIBER_KEY = /^__reactFiber\$/;
|
|
15
16
|
const REACT_INTERNAL_KEY = /^__reactInternalInstance\$/;
|
|
16
17
|
const HOVER_SCROLL_SETTLE_DELAY = 150;
|
|
@@ -94,7 +95,11 @@ export function installRendererElementSelector(acceptsClick = isUserClick) {
|
|
|
94
95
|
let suppressHoverDuringSpacingDrag = false;
|
|
95
96
|
let lastHoverPoint = null;
|
|
96
97
|
function trackListener(target, type, listener, options) {
|
|
97
|
-
const eventListener = (event) =>
|
|
98
|
+
const eventListener = (event) => {
|
|
99
|
+
if (isInspectorUiEvent(event))
|
|
100
|
+
return;
|
|
101
|
+
listener(event);
|
|
102
|
+
};
|
|
98
103
|
target.addEventListener(type, eventListener, options);
|
|
99
104
|
listenerCleanup.push(() => target.removeEventListener(type, eventListener, options));
|
|
100
105
|
}
|
|
@@ -507,6 +512,9 @@ export function installRendererElementSelector(acceptsClick = isUserClick) {
|
|
|
507
512
|
}
|
|
508
513
|
trackListener(document, "mouseup", finishDrag, true);
|
|
509
514
|
function forwardKeyboardShortcut(event, phase) {
|
|
515
|
+
// The controller's own window listeners already see page-surface keys.
|
|
516
|
+
if (isPageSurface())
|
|
517
|
+
return false;
|
|
510
518
|
const code = isKeyboardShortcutCode(event.code) ? event.code : null;
|
|
511
519
|
if (!code)
|
|
512
520
|
return false;
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type RendererToControllerMessage } from "./frameProtocol.js";
|
|
2
|
+
import { type FrameConnection } from "./frameConnection.js";
|
|
2
3
|
export interface CanvasRendererMessage {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
identity: FrameIdentity;
|
|
6
|
-
message: FrameProtocolMessage;
|
|
4
|
+
frame: FrameConnection;
|
|
5
|
+
message: RendererToControllerMessage;
|
|
7
6
|
}
|
|
8
7
|
type CanvasRendererMessageListener = (event: CanvasRendererMessage) => void;
|
|
9
8
|
/** Subscribes to same-origin messages from registered Canvas renderer frames. */
|
|
@@ -1,32 +1,28 @@
|
|
|
1
|
-
import { isRendererMessageFor, PROTOCOL_VERSION, } from "./frameProtocol.js";
|
|
2
|
-
import {
|
|
1
|
+
import { isRendererMessageFor, isRendererMessageType, PROTOCOL_VERSION, } from "./frameProtocol.js";
|
|
2
|
+
import { connectFrame } from "./frameConnection.js";
|
|
3
|
+
import { findCanvasFrameBySource } from "./projection.js";
|
|
3
4
|
const listeners = new Set();
|
|
4
5
|
function routeRendererMessage(event) {
|
|
5
6
|
if (event.origin !== window.location.origin || !event.data || typeof event.data !== "object")
|
|
6
7
|
return;
|
|
7
|
-
const
|
|
8
|
-
if (!
|
|
8
|
+
const source = findCanvasFrameBySource(event.source);
|
|
9
|
+
if (!source)
|
|
9
10
|
return;
|
|
10
|
-
const
|
|
11
|
-
projectId: PROJECT_ID,
|
|
12
|
-
workspaceId: WORKSPACE_ID,
|
|
13
|
-
cardId: frame.cardId,
|
|
14
|
-
};
|
|
11
|
+
const frame = connectFrame(source.cardId, source.iframe);
|
|
15
12
|
// SAFETY: The object guard above makes the optional discriminator fields safe to inspect.
|
|
16
13
|
const candidate = event.data;
|
|
14
|
+
if (!isRendererMessageType(candidate.type))
|
|
15
|
+
return;
|
|
17
16
|
if (candidate.type === "renderer-hello") {
|
|
18
17
|
if (candidate.protocolVersion !== PROTOCOL_VERSION)
|
|
19
18
|
return;
|
|
20
19
|
}
|
|
21
|
-
else if (!isRendererMessageFor(event.data, identity)) {
|
|
20
|
+
else if (!isRendererMessageFor(event.data, frame.identity)) {
|
|
22
21
|
return;
|
|
23
22
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
// SAFETY: Subscribers narrow the discriminated protocol union before reading message-specific fields.
|
|
28
|
-
message: event.data,
|
|
29
|
-
};
|
|
23
|
+
// SAFETY: The type is a known renderer message; subscribers narrow it and
|
|
24
|
+
// apply the strict per-message schema before trusting message-specific fields.
|
|
25
|
+
const routed = { frame, message: event.data };
|
|
30
26
|
for (const listener of listeners)
|
|
31
27
|
listener(routed);
|
|
32
28
|
}
|
|
@@ -1,2 +1,8 @@
|
|
|
1
1
|
import type { ElementClickMessage } from "./frameProtocol.js";
|
|
2
|
-
|
|
2
|
+
import type { FrameConnection } from "./frameConnection.js";
|
|
3
|
+
/**
|
|
4
|
+
* Selects the exact DOM node the user clicked inside a card's frame, so the
|
|
5
|
+
* controller mutates that physical node. If it no longer exists, the card is
|
|
6
|
+
* selected instead of binding the click to an unrelated node.
|
|
7
|
+
*/
|
|
8
|
+
export declare function handleElementClick(msg: ElementClickMessage, frame: FrameConnection): void;
|
|
@@ -1,44 +1,16 @@
|
|
|
1
1
|
import { getSelectedElements, setSelectedElement, toggleSelectedElement } from "../selection/selectionStore.js";
|
|
2
2
|
import { selectCard } from "./canvasStore.js";
|
|
3
|
-
import { RENDERER_ELEMENT_ID_ATTR } from "./rendererCidIndex.js";
|
|
4
3
|
import { inspectComponentTargets } from "../componentSemantics/index.js";
|
|
5
|
-
function isHtmlElementInDocument(node, doc) {
|
|
6
|
-
const frameWindow = doc.defaultView;
|
|
7
|
-
return frameWindow !== null && node instanceof frameWindow.HTMLElement;
|
|
8
|
-
}
|
|
9
4
|
/**
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* that stable data attribute so that the parent app can mutate the same
|
|
14
|
-
* physical DOM node the user clicked.
|
|
15
|
-
*
|
|
16
|
-
* The resolution uses a scoped ID query and never depends on document order.
|
|
17
|
-
*
|
|
18
|
-
* If the exact renderer-owned node no longer exists, fail closed instead of
|
|
19
|
-
* binding the copied component metadata to an unrelated DOM node.
|
|
5
|
+
* Selects the exact DOM node the user clicked inside a card's frame, so the
|
|
6
|
+
* controller mutates that physical node. If it no longer exists, the card is
|
|
7
|
+
* selected instead of binding the click to an unrelated node.
|
|
20
8
|
*/
|
|
21
|
-
function
|
|
22
|
-
|
|
23
|
-
return null;
|
|
24
|
-
if (!/^r\d+$/.test(elementId))
|
|
25
|
-
return null;
|
|
26
|
-
const candidates = doc.querySelectorAll(`[${RENDERER_ELEMENT_ID_ATTR}="${elementId}"]`);
|
|
27
|
-
if (candidates.length !== 1)
|
|
28
|
-
return null;
|
|
29
|
-
const candidate = candidates[0] ?? null;
|
|
30
|
-
if (!candidate
|
|
31
|
-
|| candidate.getAttribute("data-cid") !== cid
|
|
32
|
-
|| (candidate.getAttribute("data-src") ?? "") !== src)
|
|
33
|
-
return null;
|
|
34
|
-
return isHtmlElementInDocument(candidate, doc) ? candidate : null;
|
|
35
|
-
}
|
|
36
|
-
export function handleElementClick(msg, iframe, cardId) {
|
|
37
|
-
const doc = iframe.contentDocument;
|
|
38
|
-
const el = findClickedElement(doc, msg.elementId, msg.cid, msg.src);
|
|
9
|
+
export function handleElementClick(msg, frame) {
|
|
10
|
+
const el = frame.element(msg);
|
|
39
11
|
if (!el) {
|
|
40
12
|
setSelectedElement(null);
|
|
41
|
-
selectCard(cardId);
|
|
13
|
+
selectCard(frame.cardId);
|
|
42
14
|
return;
|
|
43
15
|
}
|
|
44
16
|
const componentTargets = inspectComponentTargets(el);
|
|
@@ -55,11 +27,11 @@ export function handleElementClick(msg, iframe, cardId) {
|
|
|
55
27
|
// setSelectedElement must run before any side effect that could reload the
|
|
56
28
|
// host page, otherwise the selection would be discarded by the unload.
|
|
57
29
|
const current = getSelectedElements();
|
|
58
|
-
if (msg.additive && current.length > 0 && current.every((candidate) => candidate.domElement.ownerDocument ===
|
|
30
|
+
if (msg.additive && current.length > 0 && current.every((candidate) => candidate.domElement.ownerDocument === el.ownerDocument)) {
|
|
59
31
|
toggleSelectedElement(selected);
|
|
60
32
|
}
|
|
61
33
|
else {
|
|
62
34
|
setSelectedElement(selected);
|
|
63
35
|
}
|
|
64
|
-
selectCard(cardId);
|
|
36
|
+
selectCard(frame.cardId);
|
|
65
37
|
}
|
|
@@ -9,8 +9,15 @@ import { applyStructuralProjection, getStructuralProjectionReports, isStructural
|
|
|
9
9
|
import { applyTextContentProjection, getTextProjectionReports, subscribeTextProjectionDiagnostics, } from "../projection/textProjection.js";
|
|
10
10
|
import { isTextContentChangeListValue } from "../changes/types.js";
|
|
11
11
|
import { applyDraftProjection, } from "../projection/draftProjection.js";
|
|
12
|
+
import { adoptStylesheet, allowsStyleElements } from "../runtime/ownedStylesheets.js";
|
|
13
|
+
import { applyRuntimeIdentityClaims, isRuntimeIdentityClaim } from "../runtime/runtimeIdentityClaims.js";
|
|
12
14
|
const SHEET_ID = "nudge-ui-styles";
|
|
13
15
|
function replaceRendererCss(css) {
|
|
16
|
+
if (!allowsStyleElements(document)) {
|
|
17
|
+
adoptStylesheet(document, SHEET_ID, css);
|
|
18
|
+
notifyBrowserStylesheetChange(document);
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
14
21
|
let sheet = document.getElementById(SHEET_ID);
|
|
15
22
|
if (!sheet) {
|
|
16
23
|
sheet = document.createElement("style");
|
|
@@ -22,6 +29,9 @@ function replaceRendererCss(css) {
|
|
|
22
29
|
notifyBrowserStylesheetChange(document);
|
|
23
30
|
}
|
|
24
31
|
const rendererDocumentProjectionAdapter = {
|
|
32
|
+
applyRuntimeIdentities: (claims) => {
|
|
33
|
+
applyRuntimeIdentityClaims(document, claims);
|
|
34
|
+
},
|
|
25
35
|
applyStructural: (changes) => {
|
|
26
36
|
applyStructuralProjection(document, changes);
|
|
27
37
|
},
|
|
@@ -44,6 +54,7 @@ function projectionFromReplaceStylesMessage(msg) {
|
|
|
44
54
|
structuralChanges: msg.structuralChanges,
|
|
45
55
|
textContentChanges: msg.textContentChanges,
|
|
46
56
|
componentOverrides: msg.componentOverrides,
|
|
57
|
+
runtimeIdentities: msg.runtimeIdentities,
|
|
47
58
|
};
|
|
48
59
|
}
|
|
49
60
|
let lastAppliedRevision = -1;
|
|
@@ -195,6 +206,10 @@ export function validateReplaceStyles(msg, projectId, workspaceId, cardId) {
|
|
|
195
206
|
if (!isTextContentChangeListValue(m.textContentChanges)) {
|
|
196
207
|
return { valid: false, reason: "text content changes are invalid" };
|
|
197
208
|
}
|
|
209
|
+
if (m.runtimeIdentities !== undefined
|
|
210
|
+
&& (!Array.isArray(m.runtimeIdentities) || !m.runtimeIdentities.every(isRuntimeIdentityClaim))) {
|
|
211
|
+
return { valid: false, reason: "runtime identities are invalid" };
|
|
212
|
+
}
|
|
198
213
|
if (!isComponentOverrideList(m.componentOverrides)) {
|
|
199
214
|
return { valid: false, reason: "component overrides are invalid" };
|
|
200
215
|
}
|
|
@@ -38,8 +38,8 @@ export interface HydrationResult {
|
|
|
38
38
|
export declare function serializeSession(): DurableSession;
|
|
39
39
|
export declare function persistSession(): boolean;
|
|
40
40
|
export declare function hydrateSession(): HydrationResult;
|
|
41
|
-
/** Clears the active
|
|
42
|
-
export declare function clearSelectedFrameChanges(): void
|
|
41
|
+
/** Clears the active draft, its comments, and project sketches while preserving canvas geometry and other drafts. */
|
|
42
|
+
export declare function clearSelectedFrameChanges(): Promise<void>;
|
|
43
43
|
export declare function clearSession(): void;
|
|
44
44
|
export declare function enableAutoSave(): void;
|
|
45
45
|
/**
|