@parhelia/core 0.1.12880 → 0.1.12881
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/components/ui/card.d.ts +3 -1
- package/dist/components/ui/card.js +2 -2
- package/dist/components/ui/card.js.map +1 -1
- package/dist/components/ui/context-menu.js +2 -2
- package/dist/config/config.js +6 -5
- package/dist/config/config.js.map +1 -1
- package/dist/config/types.d.ts +0 -7
- package/dist/config/types.js.map +1 -1
- package/dist/editor/FieldActionsOverlay.d.ts +0 -1
- package/dist/editor/FieldActionsOverlay.js +1 -45
- package/dist/editor/FieldActionsOverlay.js.map +1 -1
- package/dist/editor/FieldListField.d.ts +1 -1
- package/dist/editor/FieldListField.js +20 -18
- package/dist/editor/FieldListField.js.map +1 -1
- package/dist/editor/ImageEditor.d.ts +6 -1
- package/dist/editor/ImageEditor.js +19 -3
- package/dist/editor/ImageEditor.js.map +1 -1
- package/dist/editor/PictureEditor.d.ts +2 -1
- package/dist/editor/PictureEditor.js +5 -14
- package/dist/editor/PictureEditor.js.map +1 -1
- package/dist/editor/ai/Agents.js +2 -2
- package/dist/editor/ai/Agents.js.map +1 -1
- package/dist/editor/ai/GuidanceOverlay.js +1 -11
- package/dist/editor/ai/GuidanceOverlay.js.map +1 -1
- package/dist/editor/ai/InlineAiDialog.js +22 -11
- package/dist/editor/ai/InlineAiDialog.js.map +1 -1
- package/dist/editor/ai/InlineAiTrigger.js +17 -57
- package/dist/editor/ai/InlineAiTrigger.js.map +1 -1
- package/dist/editor/ai/dialogs/capturePageDom.js +66 -36
- package/dist/editor/ai/dialogs/capturePageDom.js.map +1 -1
- package/dist/editor/ai/dialogs/capturePageScreenshot.js +281 -162
- package/dist/editor/ai/dialogs/capturePageScreenshot.js.map +1 -1
- package/dist/editor/ai/terminal/agentSessionState.d.ts +3 -0
- package/dist/editor/ai/terminal/agentSessionState.js +3 -1
- package/dist/editor/ai/terminal/agentSessionState.js.map +1 -1
- package/dist/editor/ai/terminal/agentStartRequest.d.ts +2 -1
- package/dist/editor/ai/terminal/agentStartRequest.js +2 -1
- package/dist/editor/ai/terminal/agentStartRequest.js.map +1 -1
- package/dist/editor/ai/terminal/components/AgentCostDisplay.js +1 -1
- package/dist/editor/ai/terminal/components/AgentCostDisplay.js.map +1 -1
- package/dist/editor/ai/terminal/components/AgentDocumentList.d.ts +7 -0
- package/dist/editor/ai/terminal/components/AgentDocumentList.js +55 -13
- package/dist/editor/ai/terminal/components/AgentDocumentList.js.map +1 -1
- package/dist/editor/ai/terminal/components/AgentEditHistoryButton.d.ts +5 -0
- package/dist/editor/ai/terminal/components/AgentEditHistoryButton.js +12 -0
- package/dist/editor/ai/terminal/components/AgentEditHistoryButton.js.map +1 -0
- package/dist/editor/ai/terminal/components/AgentFullPromptControls.d.ts +3 -1
- package/dist/editor/ai/terminal/components/AgentFullPromptControls.js +22 -14
- package/dist/editor/ai/terminal/components/AgentFullPromptControls.js.map +1 -1
- package/dist/editor/ai/terminal/components/AgentModeSelector.js +4 -4
- package/dist/editor/ai/terminal/components/AgentModeSelector.js.map +1 -1
- package/dist/editor/ai/terminal/components/AgentPromptActionButtons.js +4 -4
- package/dist/editor/ai/terminal/components/AgentPromptActionButtons.js.map +1 -1
- package/dist/editor/ai/terminal/components/AgentPromptComposer.js +1 -1
- package/dist/editor/ai/terminal/components/AgentPromptComposer.js.map +1 -1
- package/dist/editor/ai/terminal/components/AgentPromptInputArea.d.ts +2 -1
- package/dist/editor/ai/terminal/components/AgentPromptInputArea.js +8 -11
- package/dist/editor/ai/terminal/components/AgentPromptInputArea.js.map +1 -1
- package/dist/editor/ai/terminal/components/AgentPromptTrayPopovers.d.ts +1 -4
- package/dist/editor/ai/terminal/components/AgentPromptTrayPopovers.js +31 -14
- package/dist/editor/ai/terminal/components/AgentPromptTrayPopovers.js.map +1 -1
- package/dist/editor/ai/terminal/components/AgentSettingsPopover.js +1 -1
- package/dist/editor/ai/terminal/components/AgentSettingsPopover.js.map +1 -1
- package/dist/editor/ai/terminal/components/AgentTerminalFullLayout.d.ts +2 -1
- package/dist/editor/ai/terminal/components/AgentTerminalFullLayout.js +2 -4
- package/dist/editor/ai/terminal/components/AgentTerminalFullLayout.js.map +1 -1
- package/dist/editor/ai/terminal/components/AgentTerminalMessageGroups.js +1 -1
- package/dist/editor/ai/terminal/components/AgentTerminalMessageGroups.js.map +1 -1
- package/dist/editor/ai/terminal/components/AgentTerminalView.js +13 -2
- package/dist/editor/ai/terminal/components/AgentTerminalView.js.map +1 -1
- package/dist/editor/ai/terminal/components/AiResponseMessage.js +16 -14
- package/dist/editor/ai/terminal/components/AiResponseMessage.js.map +1 -1
- package/dist/editor/ai/terminal/components/ContextInfoBar.js +22 -2
- package/dist/editor/ai/terminal/components/ContextInfoBar.js.map +1 -1
- package/dist/editor/ai/terminal/components/QueuedPromptsPanel.js +37 -26
- package/dist/editor/ai/terminal/components/QueuedPromptsPanel.js.map +1 -1
- package/dist/editor/ai/terminal/components/UserMessage.d.ts +2 -1
- package/dist/editor/ai/terminal/components/UserMessage.js +144 -8
- package/dist/editor/ai/terminal/components/UserMessage.js.map +1 -1
- package/dist/editor/ai/terminal/useAgentPromptComposerHandlers.js +1 -1
- package/dist/editor/ai/terminal/useAgentPromptComposerHandlers.js.map +1 -1
- package/dist/editor/ai/terminal/useAgentSessionSync.d.ts +1 -0
- package/dist/editor/ai/terminal/useAgentSubmitHandlers.d.ts +3 -1
- package/dist/editor/ai/terminal/useAgentSubmitHandlers.js +9 -3
- package/dist/editor/ai/terminal/useAgentSubmitHandlers.js.map +1 -1
- package/dist/editor/ai/terminal/useAgentTerminalController.js +7 -0
- package/dist/editor/ai/terminal/useAgentTerminalController.js.map +1 -1
- package/dist/editor/ai/terminal/useAgentTerminalUiState.js +1 -1
- package/dist/editor/ai/terminal/useAgentTerminalUiState.js.map +1 -1
- package/dist/editor/ai/terminal/useAgentUserMessageSocketHandler.js +3 -1
- package/dist/editor/ai/terminal/useAgentUserMessageSocketHandler.js.map +1 -1
- package/dist/editor/ai/useInlineAiPosition.d.ts +1 -1
- package/dist/editor/ai/useInlineAiPosition.js +22 -52
- package/dist/editor/ai/useInlineAiPosition.js.map +1 -1
- package/dist/editor/ai-image-editor/AiImageResultOverlay.js +30 -62
- package/dist/editor/ai-image-editor/AiImageResultOverlay.js.map +1 -1
- package/dist/editor/bridge/BridgeClient.d.ts +80 -0
- package/dist/editor/bridge/BridgeClient.js +417 -0
- package/dist/editor/bridge/BridgeClient.js.map +1 -0
- package/dist/editor/client/EditorShell.d.ts +5 -1
- package/dist/editor/client/EditorShell.js +282 -126
- package/dist/editor/client/EditorShell.js.map +1 -1
- package/dist/editor/client/editContext.d.ts +33 -5
- package/dist/editor/client/editContext.js.map +1 -1
- package/dist/editor/client/hooks/useSocketMessageHandler.js +14 -17
- package/dist/editor/client/hooks/useSocketMessageHandler.js.map +1 -1
- package/dist/editor/client/itemsRepository.d.ts +2 -0
- package/dist/editor/client/itemsRepository.js +15 -8
- package/dist/editor/client/itemsRepository.js.map +1 -1
- package/dist/editor/client/operations.d.ts +1 -1
- package/dist/editor/client/operations.js +41 -17
- package/dist/editor/client/operations.js.map +1 -1
- package/dist/editor/client/pageModelBuilder.js +24 -7
- package/dist/editor/client/pageModelBuilder.js.map +1 -1
- package/dist/editor/field-types/MultiLineText.js +10 -3
- package/dist/editor/field-types/MultiLineText.js.map +1 -1
- package/dist/editor/field-types/RawEditor.js +8 -1
- package/dist/editor/field-types/RawEditor.js.map +1 -1
- package/dist/editor/field-types/RichTextEditorComponent.js +156 -45
- package/dist/editor/field-types/RichTextEditorComponent.js.map +1 -1
- package/dist/editor/field-types/SingleLineText.js +10 -3
- package/dist/editor/field-types/SingleLineText.js.map +1 -1
- package/dist/editor/field-types/richtext/components/ReactSlate.js +8 -2
- package/dist/editor/field-types/richtext/components/ReactSlate.js.map +1 -1
- package/dist/editor/field-types/richtext/contextMenuFactory.d.ts +1 -2
- package/dist/editor/field-types/richtext/contextMenuFactory.js +100 -303
- package/dist/editor/field-types/richtext/contextMenuFactory.js.map +1 -1
- package/dist/editor/field-types/richtext/types.d.ts +2 -0
- package/dist/editor/field-types/richtext/types.js.map +1 -1
- package/dist/editor/field-types/useFormFieldCaretPresence.d.ts +13 -0
- package/dist/editor/field-types/useFormFieldCaretPresence.js +92 -0
- package/dist/editor/field-types/useFormFieldCaretPresence.js.map +1 -0
- package/dist/editor/media-selector/TreeSelector.js +15 -15
- package/dist/editor/media-selector/TreeSelector.js.map +1 -1
- package/dist/editor/menubar/PageSelector.js +8 -2
- package/dist/editor/menubar/PageSelector.js.map +1 -1
- package/dist/editor/menubar/VersionPreviewCard.js +4 -249
- package/dist/editor/menubar/VersionPreviewCard.js.map +1 -1
- package/dist/editor/menubar/toolbar-sections/EditControls.js +2 -2
- package/dist/editor/menubar/toolbar-sections/EditControls.js.map +1 -1
- package/dist/editor/menubar/toolbar-sections/ManualBrowser.d.ts +0 -10
- package/dist/editor/menubar/toolbar-sections/ManualBrowser.js +63 -462
- package/dist/editor/menubar/toolbar-sections/ManualBrowser.js.map +1 -1
- package/dist/editor/menubar/toolbar-sections/ViewportControls.js +1 -1
- package/dist/editor/page-editor-chrome/BridgeInlineFormatOverlay.d.ts +6 -0
- package/dist/editor/page-editor-chrome/BridgeInlineFormatOverlay.js +123 -0
- package/dist/editor/page-editor-chrome/BridgeInlineFormatOverlay.js.map +1 -0
- package/dist/editor/page-editor-chrome/CommentHighlightings.d.ts +5 -2
- package/dist/editor/page-editor-chrome/CommentHighlightings.js +340 -215
- package/dist/editor/page-editor-chrome/CommentHighlightings.js.map +1 -1
- package/dist/editor/page-editor-chrome/FeedbackHighlightBadge.d.ts +5 -1
- package/dist/editor/page-editor-chrome/FeedbackHighlightBadge.js +11 -4
- package/dist/editor/page-editor-chrome/FeedbackHighlightBadge.js.map +1 -1
- package/dist/editor/page-editor-chrome/FieldActionIndicator.js +21 -13
- package/dist/editor/page-editor-chrome/FieldActionIndicator.js.map +1 -1
- package/dist/editor/page-editor-chrome/FieldEditedIndicator.js +23 -29
- package/dist/editor/page-editor-chrome/FieldEditedIndicator.js.map +1 -1
- package/dist/editor/page-editor-chrome/FrameMenu.js +110 -19
- package/dist/editor/page-editor-chrome/FrameMenu.js.map +1 -1
- package/dist/editor/page-editor-chrome/LockedFieldIndicator.d.ts +3 -2
- package/dist/editor/page-editor-chrome/LockedFieldIndicator.js +148 -45
- package/dist/editor/page-editor-chrome/LockedFieldIndicator.js.map +1 -1
- package/dist/editor/page-editor-chrome/PageEditorChrome.d.ts +2 -0
- package/dist/editor/page-editor-chrome/PageEditorChrome.js +25 -21
- package/dist/editor/page-editor-chrome/PageEditorChrome.js.map +1 -1
- package/dist/editor/page-editor-chrome/PictureEditorOverlay.js +163 -128
- package/dist/editor/page-editor-chrome/PictureEditorOverlay.js.map +1 -1
- package/dist/editor/page-editor-chrome/PlaceholderDropZone.d.ts +1 -1
- package/dist/editor/page-editor-chrome/PlaceholderDropZone.js +6 -3
- package/dist/editor/page-editor-chrome/PlaceholderDropZone.js.map +1 -1
- package/dist/editor/page-editor-chrome/PlaceholderDropZones.d.ts +1 -2
- package/dist/editor/page-editor-chrome/PlaceholderDropZones.js +83 -146
- package/dist/editor/page-editor-chrome/PlaceholderDropZones.js.map +1 -1
- package/dist/editor/page-editor-chrome/SuggestionHighlightings.d.ts +5 -2
- package/dist/editor/page-editor-chrome/SuggestionHighlightings.js +144 -63
- package/dist/editor/page-editor-chrome/SuggestionHighlightings.js.map +1 -1
- package/dist/editor/page-editor-chrome/VersionDiffHighlightings.d.ts +1 -2
- package/dist/editor/page-editor-chrome/VersionDiffHighlightings.js +101 -30
- package/dist/editor/page-editor-chrome/VersionDiffHighlightings.js.map +1 -1
- package/dist/editor/page-editor-chrome/overlay/IframeOverlayProvider.d.ts +10 -1
- package/dist/editor/page-editor-chrome/overlay/IframeOverlayProvider.js +105 -122
- package/dist/editor/page-editor-chrome/overlay/IframeOverlayProvider.js.map +1 -1
- package/dist/editor/page-editor-chrome/overlay/geometry.d.ts +11 -4
- package/dist/editor/page-editor-chrome/overlay/geometry.js +139 -36
- package/dist/editor/page-editor-chrome/overlay/geometry.js.map +1 -1
- package/dist/editor/page-editor-chrome/useBridgeInlineEditing.d.ts +26 -0
- package/dist/editor/page-editor-chrome/useBridgeInlineEditing.js +222 -0
- package/dist/editor/page-editor-chrome/useBridgeInlineEditing.js.map +1 -0
- package/dist/editor/page-viewer/EditorForm.js +17 -1
- package/dist/editor/page-viewer/EditorForm.js.map +1 -1
- package/dist/editor/page-viewer/MiniMap.d.ts +2 -2
- package/dist/editor/page-viewer/MiniMap.js +176 -364
- package/dist/editor/page-viewer/MiniMap.js.map +1 -1
- package/dist/editor/page-viewer/PageViewer.js +40 -13
- package/dist/editor/page-viewer/PageViewer.js.map +1 -1
- package/dist/editor/page-viewer/PageViewerFrame.d.ts +0 -5
- package/dist/editor/page-viewer/PageViewerFrame.js +1529 -1511
- package/dist/editor/page-viewer/PageViewerFrame.js.map +1 -1
- package/dist/editor/page-viewer/bridgeFieldPatch.d.ts +20 -0
- package/dist/editor/page-viewer/bridgeFieldPatch.js +33 -0
- package/dist/editor/page-viewer/bridgeFieldPatch.js.map +1 -0
- package/dist/editor/page-viewer/pageViewContext.d.ts +32 -0
- package/dist/editor/page-viewer/pageViewContext.js +37 -6
- package/dist/editor/page-viewer/pageViewContext.js.map +1 -1
- package/dist/editor/reviews/Comment.d.ts +2 -1
- package/dist/editor/reviews/Comment.js +9 -4
- package/dist/editor/reviews/Comment.js.map +1 -1
- package/dist/editor/reviews/CommentEditor.js +1 -1
- package/dist/editor/reviews/CommentEditor.js.map +1 -1
- package/dist/editor/reviews/CommentPopover.js +68 -9
- package/dist/editor/reviews/CommentPopover.js.map +1 -1
- package/dist/editor/reviews/CommentView.js +24 -4
- package/dist/editor/reviews/CommentView.js.map +1 -1
- package/dist/editor/reviews/Comments.d.ts +0 -2
- package/dist/editor/reviews/Comments.js +29 -30
- package/dist/editor/reviews/Comments.js.map +1 -1
- package/dist/editor/reviews/FeedbackCard.d.ts +4 -2
- package/dist/editor/reviews/FeedbackCard.js +5 -5
- package/dist/editor/reviews/FeedbackCard.js.map +1 -1
- package/dist/editor/reviews/SuggestedEdit.js +4 -6
- package/dist/editor/reviews/SuggestedEdit.js.map +1 -1
- package/dist/editor/reviews/SuggestionDisplayPopover.js +3 -2
- package/dist/editor/reviews/SuggestionDisplayPopover.js.map +1 -1
- package/dist/editor/reviews/commentAi.js +96 -27
- package/dist/editor/reviews/commentAi.js.map +1 -1
- package/dist/editor/reviews/commentTransientSelection.d.ts +23 -0
- package/dist/editor/reviews/commentTransientSelection.js +7 -0
- package/dist/editor/reviews/commentTransientSelection.js.map +1 -0
- package/dist/editor/reviews/feedbackOrdering.d.ts +5 -0
- package/dist/editor/reviews/feedbackOrdering.js +27 -0
- package/dist/editor/reviews/feedbackOrdering.js.map +1 -0
- package/dist/editor/reviews/feedbackSelection.js +32 -4
- package/dist/editor/reviews/feedbackSelection.js.map +1 -1
- package/dist/editor/reviews/suggestedEditState.d.ts +12 -0
- package/dist/editor/reviews/suggestedEditState.js +90 -0
- package/dist/editor/reviews/suggestedEditState.js.map +1 -0
- package/dist/editor/reviews/suggestionDisplayValue.d.ts +43 -0
- package/dist/editor/reviews/suggestionDisplayValue.js +93 -0
- package/dist/editor/reviews/suggestionDisplayValue.js.map +1 -0
- package/dist/editor/services/agentService.d.ts +15 -0
- package/dist/editor/services/agentService.js +11 -1
- package/dist/editor/services/agentService.js.map +1 -1
- package/dist/editor/services/reviewsService.d.ts +2 -2
- package/dist/editor/services/reviewsService.js.map +1 -1
- package/dist/editor/settings/SettingsView.js +2 -2
- package/dist/editor/settings/SettingsView.js.map +1 -1
- package/dist/editor/settings/panels/ProjectTemplatesPanel.js +1 -1
- package/dist/editor/settings/panels/ProjectTemplatesPanel.js.map +1 -1
- package/dist/editor/settings/panels/ProvidersPanel.js +2 -3
- package/dist/editor/settings/panels/ProvidersPanel.js.map +1 -1
- package/dist/editor/sidebar/MorePanelsButton.js +1 -1
- package/dist/editor/sidebar/MorePanelsButton.js.map +1 -1
- package/dist/editor/sidebar/Workbox.js +1 -1
- package/dist/editor/sidebar/Workbox.js.map +1 -1
- package/dist/editor/ui/IconSelectorDialog.js +1 -1
- package/dist/editor/ui/IconSelectorDialog.js.map +1 -1
- package/dist/editor/ui/SimpleIconButton.d.ts +2 -2
- package/dist/editor/ui/SimpleIconButton.js +1 -1
- package/dist/editor/ui/SimpleIconButton.js.map +1 -1
- package/dist/editor/utils.d.ts +1 -17
- package/dist/editor/utils.js +0 -143
- package/dist/editor/utils.js.map +1 -1
- package/dist/editor/version-diff/versionDiffTargets.d.ts +3 -8
- package/dist/editor/version-diff/versionDiffTargets.js +37 -94
- package/dist/editor/version-diff/versionDiffTargets.js.map +1 -1
- package/dist/revision.d.ts +2 -2
- package/dist/revision.js +2 -2
- package/dist/splash-screen/DialogWrappers.js +2 -2
- package/dist/splash-screen/DialogWrappers.js.map +1 -1
- package/dist/splash-screen/ModernSplashScreen.js +11 -3
- package/dist/splash-screen/ModernSplashScreen.js.map +1 -1
- package/dist/splash-screen/NewPage.js +7 -5
- package/dist/splash-screen/NewPage.js.map +1 -1
- package/dist/splash-screen/OpenPage.js +5 -3
- package/dist/splash-screen/OpenPage.js.map +1 -1
- package/dist/splash-screen/RecentPages.js +3 -3
- package/dist/splash-screen/RecentPages.js.map +1 -1
- package/package.json +2 -1
- package/styles.css +49 -0
- package/dist/editor/page-editor-chrome/InlineEditor.d.ts +0 -7
- package/dist/editor/page-editor-chrome/InlineEditor.js +0 -1719
- package/dist/editor/page-editor-chrome/InlineEditor.js.map +0 -1
- package/dist/editor/page-editor-chrome/overlay/iframeAccess.d.ts +0 -2
- package/dist/editor/page-editor-chrome/overlay/iframeAccess.js +0 -21
- package/dist/editor/page-editor-chrome/overlay/iframeAccess.js.map +0 -1
- package/dist/editor/page-editor-chrome/useInlineAICompletion.d.ts +0 -7
- package/dist/editor/page-editor-chrome/useInlineAICompletion.js +0 -758
- package/dist/editor/page-editor-chrome/useInlineAICompletion.js.map +0 -1
- package/dist/editor/page-viewer/pageModelSkeletonBuilder.d.ts +0 -3
- package/dist/editor/page-viewer/pageModelSkeletonBuilder.js +0 -796
- package/dist/editor/page-viewer/pageModelSkeletonBuilder.js.map +0 -1
|
@@ -17,60 +17,6 @@ function SvgIcon({ svg, size, className, }) {
|
|
|
17
17
|
return (_jsx("span", { className: cn("inline-flex items-center justify-center [&>svg]:block [&>svg]:h-full [&>svg]:w-full", className), style: { width: size, height: size }, dangerouslySetInnerHTML: { __html: sanitizedSvg } }));
|
|
18
18
|
}
|
|
19
19
|
const HIGHLIGHT_DURATION_MS = 2000;
|
|
20
|
-
const EDITOR_FORM_SLIDER_SELECTOR = '[data-testid="editor-form-slider"]';
|
|
21
|
-
const EDITOR_FORM_HIDDEN_ATTRIBUTE = "aria-hidden";
|
|
22
|
-
const CLOSE_PANE_LABEL = "Close pane";
|
|
23
|
-
function waitForDelay(delayMs) {
|
|
24
|
-
return new Promise((resolve) => {
|
|
25
|
-
window.setTimeout(resolve, delayMs);
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
function getEditorFormSlider(elements = []) {
|
|
29
|
-
for (const element of elements) {
|
|
30
|
-
const slider = element.closest(EDITOR_FORM_SLIDER_SELECTOR);
|
|
31
|
-
if (slider) {
|
|
32
|
-
return slider;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
return document.querySelector(EDITOR_FORM_SLIDER_SELECTOR);
|
|
36
|
-
}
|
|
37
|
-
function isEditorFormSliderHidden(slider) {
|
|
38
|
-
return slider?.getAttribute(EDITOR_FORM_HIDDEN_ATTRIBUTE) === "true";
|
|
39
|
-
}
|
|
40
|
-
async function waitForEditorFormSliderOpen(slider, timeoutMs = 1000) {
|
|
41
|
-
const startedAt = Date.now();
|
|
42
|
-
while (Date.now() - startedAt < timeoutMs) {
|
|
43
|
-
if (!isEditorFormSliderHidden(slider ?? getEditorFormSlider())) {
|
|
44
|
-
return;
|
|
45
|
-
}
|
|
46
|
-
await waitForDelay(50);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
async function waitForResolvedElements(resolveElements, selector, timeoutMs = 1000) {
|
|
50
|
-
const startedAt = Date.now();
|
|
51
|
-
while (Date.now() - startedAt < timeoutMs) {
|
|
52
|
-
const elements = resolveElements(selector);
|
|
53
|
-
if (elements.length > 0) {
|
|
54
|
-
return elements;
|
|
55
|
-
}
|
|
56
|
-
await waitForDelay(50);
|
|
57
|
-
}
|
|
58
|
-
return resolveElements(selector);
|
|
59
|
-
}
|
|
60
|
-
// Wait until at least one element for the selector is actually VISIBLE (not just
|
|
61
|
-
// present). After a reveal/animation a target can be in the DOM but not yet laid
|
|
62
|
-
// out, which would otherwise cause highlightElement to skip it.
|
|
63
|
-
async function waitForVisibleElements(selector, timeoutMs = 1000) {
|
|
64
|
-
const startedAt = Date.now();
|
|
65
|
-
while (Date.now() - startedAt < timeoutMs) {
|
|
66
|
-
const elements = getVisibleElementsForSelector(selector);
|
|
67
|
-
if (elements.length > 0) {
|
|
68
|
-
return elements;
|
|
69
|
-
}
|
|
70
|
-
await waitForDelay(50);
|
|
71
|
-
}
|
|
72
|
-
return getVisibleElementsForSelector(selector);
|
|
73
|
-
}
|
|
74
20
|
const manualMarkdownComponents = {
|
|
75
21
|
h1: ({ children }) => (_jsx("h1", { className: "text-neutral-grey-100 mt-4 mb-0 text-xl font-bold", children: children })),
|
|
76
22
|
h2: ({ children }) => (_jsx("h2", { className: "text-neutral-grey-100 mt-3 mb-0 text-lg font-semibold", children: children })),
|
|
@@ -106,15 +52,7 @@ export function parseUiSelectors(uiSelectors) {
|
|
|
106
52
|
let beforeAction;
|
|
107
53
|
let afterAction;
|
|
108
54
|
let availabilitySelector;
|
|
109
|
-
let selectorOverride;
|
|
110
|
-
let tab;
|
|
111
|
-
let closeMode;
|
|
112
55
|
for (const segment of segments) {
|
|
113
|
-
if (segment.startsWith("close=")) {
|
|
114
|
-
const value = segment.substring("close=".length).trim();
|
|
115
|
-
closeMode = value === "auto" ? "auto" : "click";
|
|
116
|
-
continue;
|
|
117
|
-
}
|
|
118
56
|
if (segment.startsWith("beforeAction=")) {
|
|
119
57
|
beforeAction = segment.substring("beforeAction=".length).trim();
|
|
120
58
|
continue;
|
|
@@ -129,14 +67,6 @@ export function parseUiSelectors(uiSelectors) {
|
|
|
129
67
|
.trim();
|
|
130
68
|
continue;
|
|
131
69
|
}
|
|
132
|
-
if (segment.startsWith("selector=")) {
|
|
133
|
-
selectorOverride = segment.substring("selector=".length).trim();
|
|
134
|
-
continue;
|
|
135
|
-
}
|
|
136
|
-
if (segment.startsWith("tab=")) {
|
|
137
|
-
tab = segment.substring("tab=".length).trim();
|
|
138
|
-
continue;
|
|
139
|
-
}
|
|
140
70
|
if (!notFoundMessage) {
|
|
141
71
|
notFoundMessage = segment;
|
|
142
72
|
}
|
|
@@ -150,16 +80,14 @@ export function parseUiSelectors(uiSelectors) {
|
|
|
150
80
|
: undefined;
|
|
151
81
|
const parsed = {
|
|
152
82
|
name,
|
|
153
|
-
selector: isSidebarOnly ? "" :
|
|
83
|
+
selector: isSidebarOnly ? "" : `@${name}`, // Empty selector for sidebar-only
|
|
154
84
|
availabilitySelector,
|
|
155
|
-
tab,
|
|
156
85
|
description,
|
|
157
86
|
notFoundMessage: notFoundMessage || undefined,
|
|
158
87
|
location: isSidebarOnly ? sidebarId : undefined, // Use actual sidebar ID (without -sidebar suffix) for sidebar-only
|
|
159
88
|
isSidebarOnly,
|
|
160
89
|
beforeAction,
|
|
161
90
|
afterAction,
|
|
162
|
-
closeMode,
|
|
163
91
|
};
|
|
164
92
|
// Primary key remains the selector name
|
|
165
93
|
map.set(name, parsed);
|
|
@@ -171,7 +99,8 @@ function parseSelectorToken(selectorToken) {
|
|
|
171
99
|
if (!selectorToken.startsWith("@"))
|
|
172
100
|
return { selector: selectorToken };
|
|
173
101
|
const raw = selectorToken.slice(1);
|
|
174
|
-
// Preserve iframe: selectors
|
|
102
|
+
// Preserve iframe: selectors as unavailable selectors. Page DOM inspection now
|
|
103
|
+
// goes through the editing bridge instead of same-origin iframe probing.
|
|
175
104
|
if (raw.startsWith("iframe:"))
|
|
176
105
|
return { selector: selectorToken };
|
|
177
106
|
// Check for sidebar-only syntax: @sidebar-id-sidebar (e.g., @reviews-sidebar)
|
|
@@ -207,7 +136,6 @@ export function expandSelector(selectorShorthand) {
|
|
|
207
136
|
return selector;
|
|
208
137
|
}
|
|
209
138
|
if (selector.startsWith("iframe:")) {
|
|
210
|
-
// Iframe selector: @iframe:selector → iframe:selector (handled by GuidanceOverlay)
|
|
211
139
|
return selector;
|
|
212
140
|
}
|
|
213
141
|
// Default: data-testid selector: @name → [data-testid="name"]
|
|
@@ -216,55 +144,10 @@ export function expandSelector(selectorShorthand) {
|
|
|
216
144
|
function getElementsForSelector(selector) {
|
|
217
145
|
const cssSelector = expandSelector(selector);
|
|
218
146
|
if (cssSelector.startsWith("iframe:")) {
|
|
219
|
-
|
|
220
|
-
const iframe = document.querySelector("iframe.page-iframe");
|
|
221
|
-
if (!iframe?.contentDocument) {
|
|
222
|
-
return [];
|
|
223
|
-
}
|
|
224
|
-
return Array.from(iframe.contentDocument.querySelectorAll(iframeSelector));
|
|
147
|
+
return [];
|
|
225
148
|
}
|
|
226
149
|
return Array.from(document.querySelectorAll(cssSelector));
|
|
227
150
|
}
|
|
228
|
-
// Determine whether an element is genuinely visible to the user, not merely
|
|
229
|
-
// present in the DOM. A target sitting inside a collapsed panel, a hidden
|
|
230
|
-
// sidebar (aria-hidden), or with `display:none` / `visibility:hidden` / zero
|
|
231
|
-
// size counts as NOT visible.
|
|
232
|
-
function isElementVisible(element) {
|
|
233
|
-
// Treat anything inside an explicitly aria-hidden container (e.g. a collapsed
|
|
234
|
-
// editor form slider) as not visible.
|
|
235
|
-
if (element.closest('[aria-hidden="true"]')) {
|
|
236
|
-
return false;
|
|
237
|
-
}
|
|
238
|
-
const candidate = element;
|
|
239
|
-
if (typeof candidate.checkVisibility === "function") {
|
|
240
|
-
if (!candidate.checkVisibility({
|
|
241
|
-
checkOpacity: true,
|
|
242
|
-
checkVisibilityCSS: true,
|
|
243
|
-
})) {
|
|
244
|
-
return false;
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
else {
|
|
248
|
-
// Fallback for environments without Element.checkVisibility (e.g. jsdom).
|
|
249
|
-
const style = window.getComputedStyle(element);
|
|
250
|
-
if (style.display === "none" ||
|
|
251
|
-
style.visibility === "hidden" ||
|
|
252
|
-
style.visibility === "collapse") {
|
|
253
|
-
return false;
|
|
254
|
-
}
|
|
255
|
-
// position:fixed elements have a null offsetParent but can still be visible.
|
|
256
|
-
if (element.offsetParent === null && style.position !== "fixed") {
|
|
257
|
-
return false;
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
// Reject zero-area elements (e.g. a width:0 collapsed panel).
|
|
261
|
-
const rect = element.getBoundingClientRect();
|
|
262
|
-
return rect.width > 0 && rect.height > 0;
|
|
263
|
-
}
|
|
264
|
-
// Return only the elements matching a selector that are currently visible.
|
|
265
|
-
function getVisibleElementsForSelector(selector) {
|
|
266
|
-
return getElementsForSelector(selector).filter(isElementVisible);
|
|
267
|
-
}
|
|
268
151
|
function shouldSkipHighlightScroll(element) {
|
|
269
152
|
const rect = element.getBoundingClientRect();
|
|
270
153
|
const computedStyle = window.getComputedStyle(element);
|
|
@@ -302,32 +185,6 @@ async function waitForScrollToFinish(element) {
|
|
|
302
185
|
previousRect = currentRect;
|
|
303
186
|
}
|
|
304
187
|
}
|
|
305
|
-
// Wait until an element's box (position and size) stops changing. This avoids
|
|
306
|
-
// drawing the highlight overlay mid-animation (e.g. while a sidebar panel is
|
|
307
|
-
// still expanding from its collapsed width).
|
|
308
|
-
async function waitForStableRect(element, timeoutMs = 1000) {
|
|
309
|
-
let previousRect = element.getBoundingClientRect();
|
|
310
|
-
let stableFrames = 0;
|
|
311
|
-
const startedAt = Date.now();
|
|
312
|
-
while (Date.now() - startedAt < timeoutMs) {
|
|
313
|
-
await waitForNextFrame();
|
|
314
|
-
const currentRect = element.getBoundingClientRect();
|
|
315
|
-
const changed = Math.abs(currentRect.width - previousRect.width) > 0.5 ||
|
|
316
|
-
Math.abs(currentRect.height - previousRect.height) > 0.5 ||
|
|
317
|
-
Math.abs(currentRect.top - previousRect.top) > 0.5 ||
|
|
318
|
-
Math.abs(currentRect.left - previousRect.left) > 0.5;
|
|
319
|
-
if (changed) {
|
|
320
|
-
stableFrames = 0;
|
|
321
|
-
}
|
|
322
|
-
else {
|
|
323
|
-
stableFrames += 1;
|
|
324
|
-
if (stableFrames >= 2) {
|
|
325
|
-
return;
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
previousRect = currentRect;
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
188
|
async function scrollElementForHighlight(element) {
|
|
332
189
|
if (shouldSkipHighlightScroll(element)) {
|
|
333
190
|
return;
|
|
@@ -342,57 +199,21 @@ async function scrollElementForHighlight(element) {
|
|
|
342
199
|
// Highlight an element temporarily
|
|
343
200
|
export async function highlightElement(selector, duration = HIGHLIGHT_DURATION_MS) {
|
|
344
201
|
const cssSelector = expandSelector(selector);
|
|
345
|
-
|
|
346
|
-
// collapsed panel or hidden sidebar must not receive a stray overlay.
|
|
347
|
-
const elements = getElementsForSelector(selector).filter(isElementVisible);
|
|
202
|
+
const elements = getElementsForSelector(selector);
|
|
348
203
|
if (elements.length === 0)
|
|
349
204
|
return;
|
|
350
|
-
if (cssSelector.startsWith("iframe:")) {
|
|
351
|
-
const iframe = document.querySelector("iframe.page-iframe");
|
|
352
|
-
const iframeRect = iframe?.getBoundingClientRect();
|
|
353
|
-
if (elements[0]) {
|
|
354
|
-
await scrollElementForHighlight(elements[0]);
|
|
355
|
-
await waitForStableRect(elements[0]);
|
|
356
|
-
}
|
|
357
|
-
elements.forEach((element) => {
|
|
358
|
-
const elementRect = element.getBoundingClientRect();
|
|
359
|
-
showHighlightOverlay(elementRect.left + (iframeRect?.left ?? 0), elementRect.top + (iframeRect?.top ?? 0), elementRect.width, elementRect.height, duration);
|
|
360
|
-
});
|
|
361
|
-
return;
|
|
362
|
-
}
|
|
363
205
|
if (elements[0]) {
|
|
364
206
|
await scrollElementForHighlight(elements[0]);
|
|
365
|
-
await waitForStableRect(elements[0]);
|
|
366
207
|
}
|
|
367
208
|
elements.forEach((element) => {
|
|
368
209
|
const rect = element.getBoundingClientRect();
|
|
369
210
|
showHighlightOverlay(rect.left, rect.top, rect.width, rect.height, duration);
|
|
370
211
|
});
|
|
371
212
|
}
|
|
372
|
-
// Check if an element is currently
|
|
373
|
-
function
|
|
213
|
+
// Check if an element is currently available in the DOM
|
|
214
|
+
function isElementAvailable(selector) {
|
|
374
215
|
return getElementsForSelector(selector).length > 0;
|
|
375
216
|
}
|
|
376
|
-
// Check if an element matching the selector is currently visible to the user
|
|
377
|
-
function isElementVisibleBySelector(selector) {
|
|
378
|
-
return getVisibleElementsForSelector(selector).length > 0;
|
|
379
|
-
}
|
|
380
|
-
export function deriveSelectorState(params) {
|
|
381
|
-
if (!params.isAnchorReachable) {
|
|
382
|
-
return "disabled";
|
|
383
|
-
}
|
|
384
|
-
// Sidebar-only selectors have no element to "see"; opening the sidebar is the action.
|
|
385
|
-
if (params.isSidebarOnly) {
|
|
386
|
-
return "show-action";
|
|
387
|
-
}
|
|
388
|
-
if (params.isTargetVisible) {
|
|
389
|
-
return "show";
|
|
390
|
-
}
|
|
391
|
-
if (params.hasRevealPath) {
|
|
392
|
-
return "show-action";
|
|
393
|
-
}
|
|
394
|
-
return "disabled";
|
|
395
|
-
}
|
|
396
217
|
// Create a temporary highlight overlay
|
|
397
218
|
function showHighlightOverlay(x, y, width, height, duration) {
|
|
398
219
|
const padding = 4;
|
|
@@ -444,187 +265,59 @@ function showHighlightOverlay(x, y, width, height, duration) {
|
|
|
444
265
|
overlay.remove();
|
|
445
266
|
}, duration);
|
|
446
267
|
}
|
|
447
|
-
let activeRevealController = null;
|
|
448
|
-
let revealControllerSeq = 0;
|
|
449
|
-
function registerActiveReveal(controller) {
|
|
450
|
-
const previous = activeRevealController;
|
|
451
|
-
activeRevealController = controller;
|
|
452
|
-
if (previous && previous.id !== controller.id) {
|
|
453
|
-
previous.close();
|
|
454
|
-
}
|
|
455
|
-
}
|
|
456
|
-
function clearActiveReveal(id) {
|
|
457
|
-
if (activeRevealController?.id === id) {
|
|
458
|
-
activeRevealController = null;
|
|
459
|
-
}
|
|
460
|
-
}
|
|
461
|
-
// Close the More-panels flyout if it is currently open (inverse of open-more-sidebars).
|
|
462
|
-
function closeMorePanelsIfOpen() {
|
|
463
|
-
if (!isElementPresent("@more-sidebars-panel"))
|
|
464
|
-
return;
|
|
465
|
-
const trigger = document.querySelector('[data-testid="more-sidebars-button"]');
|
|
466
|
-
trigger?.click();
|
|
467
|
-
}
|
|
468
268
|
// Button component for "Show me" functionality with availability detection
|
|
469
269
|
function SelectorButton({ selectorDef, keyProp, }) {
|
|
470
270
|
const editContext = useEditContext();
|
|
471
271
|
const manualActions = editContext?.configuration.editor.manualActions;
|
|
472
|
-
const
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
const
|
|
478
|
-
//
|
|
479
|
-
const
|
|
480
|
-
editContextRef.current = editContext;
|
|
272
|
+
const availabilitySelector = selectorDef.availabilitySelector || selectorDef.selector;
|
|
273
|
+
// For sidebar-only selectors, we don't need to check for an element
|
|
274
|
+
const isSidebarOnly = selectorDef.isSidebarOnly;
|
|
275
|
+
// Initialize to true for sidebar-only, false otherwise to avoid hydration mismatch
|
|
276
|
+
// (document.querySelector doesn't exist during SSR)
|
|
277
|
+
const [isAvailable, setIsAvailable] = useState(isSidebarOnly ? true : false);
|
|
278
|
+
// Can open sidebar if: sidebar-only selector
|
|
279
|
+
const canAutoOpenSidebar = Boolean(isSidebarOnly && editContext?.openSidebar && selectorDef.location);
|
|
481
280
|
const hasBeforeAction = Boolean(selectorDef.beforeAction &&
|
|
482
281
|
manualActions?.[selectorDef.beforeAction] &&
|
|
483
282
|
editContext);
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
editContext?.openSidebar &&
|
|
489
|
-
editContext.workspace?.supportsSidebars &&
|
|
490
|
-
editContext.availableSidebars?.some((s) => s.id === selectorDef.location));
|
|
491
|
-
// Presence/visibility probes, kept up to date by the effect below.
|
|
492
|
-
// The anchor gates "is this relevant in the current context", so it checks
|
|
493
|
-
// presence (it may itself be a currently-collapsed container). The target
|
|
494
|
-
// checks visibility to distinguish "show" from "show-action".
|
|
495
|
-
const [isTargetPresent, setIsTargetPresent] = useState(false);
|
|
496
|
-
const [isTargetVisible, setIsTargetVisible] = useState(false);
|
|
497
|
-
const [isAnchorPresent, setIsAnchorPresent] = useState(false);
|
|
498
|
-
// True while THIS button has revealed a container (State 3 active -> green).
|
|
499
|
-
const [isActiveReveal, setIsActiveReveal] = useState(false);
|
|
500
|
-
const controllerIdRef = useRef(0);
|
|
501
|
-
const revealRef = useRef(null);
|
|
502
|
-
const isAnchorReachable = hasAvailabilitySelector
|
|
503
|
-
? isAnchorPresent
|
|
504
|
-
: isSidebarOnly
|
|
505
|
-
? canAutoOpenSidebar
|
|
506
|
-
: isTargetPresent || hasBeforeAction;
|
|
507
|
-
const hasRevealPath = isSidebarOnly || hasBeforeAction || canAutoOpenSidebar || isTargetPresent;
|
|
508
|
-
const state = deriveSelectorState({
|
|
509
|
-
isSidebarOnly,
|
|
510
|
-
isAnchorReachable,
|
|
511
|
-
isTargetVisible,
|
|
512
|
-
hasRevealPath,
|
|
513
|
-
});
|
|
514
|
-
const isDisabled = state === "disabled";
|
|
515
|
-
// Reset active (green) state WITHOUT running the undo steps. Used when the
|
|
516
|
-
// revealed container was closed by some other means.
|
|
517
|
-
const resetActiveState = useCallback(() => {
|
|
518
|
-
clearActiveReveal(controllerIdRef.current);
|
|
519
|
-
revealRef.current = null;
|
|
520
|
-
setIsActiveReveal(false);
|
|
521
|
-
}, []);
|
|
522
|
-
// Run the undo steps and reset. Used for explicit close (2nd click, auto
|
|
523
|
-
// timer, or being superseded by another reveal via mutual exclusion).
|
|
524
|
-
const runRestore = useCallback(() => {
|
|
525
|
-
const reveal = revealRef.current;
|
|
526
|
-
if (reveal) {
|
|
527
|
-
try {
|
|
528
|
-
reveal.restore();
|
|
529
|
-
}
|
|
530
|
-
catch {
|
|
531
|
-
// ignore restore failures
|
|
532
|
-
}
|
|
533
|
-
}
|
|
534
|
-
clearActiveReveal(reveal?.id ?? controllerIdRef.current);
|
|
535
|
-
revealRef.current = null;
|
|
536
|
-
setIsActiveReveal(false);
|
|
537
|
-
}, []);
|
|
538
|
-
const runRestoreRef = useRef(runRestore);
|
|
539
|
-
runRestoreRef.current = runRestore;
|
|
540
|
-
// Keep the presence/visibility probes fresh.
|
|
283
|
+
const isActionable = isSidebarOnly
|
|
284
|
+
? canAutoOpenSidebar || hasBeforeAction
|
|
285
|
+
: isAvailable || canAutoOpenSidebar || hasBeforeAction;
|
|
286
|
+
// Monitor for element availability changes (skip for sidebar-only selectors)
|
|
541
287
|
useEffect(() => {
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
setIsAnchorPresent(anchorSelector ? isElementPresent(anchorSelector) : false);
|
|
546
|
-
};
|
|
547
|
-
check();
|
|
548
|
-
const attributeFilter = [
|
|
549
|
-
"data-testid",
|
|
550
|
-
"class",
|
|
551
|
-
"id",
|
|
552
|
-
"style",
|
|
553
|
-
"hidden",
|
|
554
|
-
"aria-hidden",
|
|
555
|
-
];
|
|
556
|
-
const observer = new MutationObserver(check);
|
|
557
|
-
observer.observe(document.body, {
|
|
558
|
-
childList: true,
|
|
559
|
-
subtree: true,
|
|
560
|
-
attributes: true,
|
|
561
|
-
attributeFilter,
|
|
562
|
-
});
|
|
563
|
-
let iframeObserver = null;
|
|
564
|
-
const iframe = document.querySelector("iframe.page-iframe");
|
|
565
|
-
if (iframe?.contentDocument?.body) {
|
|
566
|
-
iframeObserver = new MutationObserver(check);
|
|
567
|
-
iframeObserver.observe(iframe.contentDocument.body, {
|
|
568
|
-
childList: true,
|
|
569
|
-
subtree: true,
|
|
570
|
-
attributes: true,
|
|
571
|
-
attributeFilter,
|
|
572
|
-
});
|
|
573
|
-
}
|
|
574
|
-
const intervalId = setInterval(check, 1000);
|
|
575
|
-
return () => {
|
|
576
|
-
observer.disconnect();
|
|
577
|
-
iframeObserver?.disconnect();
|
|
578
|
-
clearInterval(intervalId);
|
|
579
|
-
};
|
|
580
|
-
}, [targetSelector, anchorSelector]);
|
|
581
|
-
// While active, detect if the revealed container was closed externally and
|
|
582
|
-
// reset the button's active (green) state accordingly.
|
|
583
|
-
useEffect(() => {
|
|
584
|
-
if (!isActiveReveal)
|
|
288
|
+
// Sidebar-only selectors are always "available" if openSidebar exists
|
|
289
|
+
if (isSidebarOnly) {
|
|
290
|
+
setIsAvailable(true);
|
|
585
291
|
return;
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
292
|
+
}
|
|
293
|
+
// Initial check
|
|
294
|
+
const initialAvailable = isElementAvailable(availabilitySelector);
|
|
295
|
+
setIsAvailable(initialAvailable);
|
|
296
|
+
// Set up MutationObserver to watch for DOM changes
|
|
297
|
+
const checkAvailability = () => {
|
|
298
|
+
const available = isElementAvailable(availabilitySelector);
|
|
299
|
+
setIsAvailable(available);
|
|
591
300
|
};
|
|
592
|
-
|
|
301
|
+
// Watch the main document for changes
|
|
302
|
+
const observer = new MutationObserver(checkAvailability);
|
|
593
303
|
observer.observe(document.body, {
|
|
594
304
|
childList: true,
|
|
595
305
|
subtree: true,
|
|
596
306
|
attributes: true,
|
|
597
|
-
attributeFilter: [
|
|
598
|
-
EDITOR_FORM_HIDDEN_ATTRIBUTE,
|
|
599
|
-
"class",
|
|
600
|
-
"style",
|
|
601
|
-
"data-testid",
|
|
602
|
-
],
|
|
307
|
+
attributeFilter: ["data-testid", "class", "id"],
|
|
603
308
|
});
|
|
604
|
-
|
|
309
|
+
// Also poll periodically as a fallback for async UI updates.
|
|
310
|
+
const intervalId = setInterval(checkAvailability, 1000);
|
|
605
311
|
return () => {
|
|
606
312
|
observer.disconnect();
|
|
607
313
|
clearInterval(intervalId);
|
|
608
314
|
};
|
|
609
|
-
}, [
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
}, []);
|
|
616
|
-
const tooltipText = isActiveReveal
|
|
617
|
-
? CLOSE_PANE_LABEL
|
|
618
|
-
: isDisabled
|
|
619
|
-
? selectorDef.notFoundMessage || selectorDef.description
|
|
620
|
-
: selectorDef.description;
|
|
621
|
-
return (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsxs("button", { "aria-label": isActiveReveal ? CLOSE_PANE_LABEL : "Show me", onClick: async () => {
|
|
622
|
-
// Second click while active -> restore (close=click behaviour).
|
|
623
|
-
if (isActiveReveal) {
|
|
624
|
-
runRestore();
|
|
625
|
-
return;
|
|
626
|
-
}
|
|
627
|
-
if (isDisabled)
|
|
315
|
+
}, [availabilitySelector, isSidebarOnly]);
|
|
316
|
+
const tooltipText = isActionable
|
|
317
|
+
? selectorDef.description
|
|
318
|
+
: selectorDef.notFoundMessage || selectorDef.description;
|
|
319
|
+
return (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsxs("button", { "aria-label": "Show me", onClick: async () => {
|
|
320
|
+
if (!isActionable)
|
|
628
321
|
return;
|
|
629
322
|
const runId = globalThis.crypto?.randomUUID?.() ??
|
|
630
323
|
`manual-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
@@ -644,126 +337,34 @@ function SelectorButton({ selectorDef, keyProp, }) {
|
|
|
644
337
|
};
|
|
645
338
|
await action(actionProps);
|
|
646
339
|
};
|
|
647
|
-
//
|
|
648
|
-
//
|
|
649
|
-
|
|
650
|
-
const openPredicates = [];
|
|
651
|
-
// 1. Sidebar-only: open the sidebar.
|
|
652
|
-
if (isSidebarOnly &&
|
|
340
|
+
// If this selector is sidebar-only, open the sidebar before highlighting.
|
|
341
|
+
// For sidebar-only selectors, location is the sidebar ID (without -sidebar suffix)
|
|
342
|
+
if (selectorDef.isSidebarOnly &&
|
|
653
343
|
editContext?.openSidebar &&
|
|
654
344
|
selectorDef.location) {
|
|
655
345
|
const sidebarId = selectorDef.location;
|
|
656
|
-
const
|
|
657
|
-
if (!
|
|
346
|
+
const isSidebarAlreadyOpen = !!editContext.openSidebars?.includes(sidebarId);
|
|
347
|
+
if (!isSidebarAlreadyOpen) {
|
|
658
348
|
editContext.openSidebar(sidebarId);
|
|
659
|
-
|
|
660
|
-
forceClose: true,
|
|
661
|
-
}));
|
|
662
|
-
// Give the sidebar a moment to render before querying.
|
|
349
|
+
// Give the sidebar a moment to render before querying/highlighting.
|
|
663
350
|
await new Promise((resolve) => setTimeout(resolve, 150));
|
|
664
351
|
}
|
|
665
|
-
openPredicates.push(() => !!editContextRef.current?.openSidebars?.includes(sidebarId));
|
|
666
|
-
}
|
|
667
|
-
const availabilityElements = anchorSelector
|
|
668
|
-
? resolveElements(anchorSelector)
|
|
669
|
-
: [];
|
|
670
|
-
const relevantElements = !isSidebarOnly
|
|
671
|
-
? [...resolveElements(), ...availabilityElements]
|
|
672
|
-
: availabilityElements;
|
|
673
|
-
const formSlider = getEditorFormSlider(relevantElements);
|
|
674
|
-
const shouldOpenEditorForm = !isSidebarOnly &&
|
|
675
|
-
!!formSlider &&
|
|
676
|
-
isEditorFormSliderHidden(formSlider);
|
|
677
|
-
if (selectorDef.tab) {
|
|
678
|
-
editContext?.setActiveEditorTab(selectorDef.tab);
|
|
679
|
-
}
|
|
680
|
-
// 2. Editor form slider.
|
|
681
|
-
if (shouldOpenEditorForm && editContext) {
|
|
682
|
-
const slotId = editContext.getActiveSlotId();
|
|
683
|
-
editContext.setEditorFormHiddenForSlot(slotId, false);
|
|
684
|
-
undoSteps.push(() => editContextRef.current?.setEditorFormHiddenForSlot(slotId, true));
|
|
685
|
-
openPredicates.push(() => !isEditorFormSliderHidden(getEditorFormSlider()));
|
|
686
|
-
await waitForEditorFormSliderOpen(formSlider);
|
|
687
|
-
}
|
|
688
|
-
else if (selectorDef.tab) {
|
|
689
|
-
await waitForNextFrame();
|
|
690
352
|
}
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
: availabilityElements;
|
|
698
|
-
const morePanelsWasOpen = isElementPresent("@more-sidebars-panel");
|
|
699
|
-
await runManualAction(selectorDef.beforeAction, actionElements);
|
|
700
|
-
if (selectorDef.beforeAction === "open-more-sidebars") {
|
|
701
|
-
const morePanelsNowOpen = isElementPresent("@more-sidebars-panel");
|
|
702
|
-
if (!morePanelsWasOpen && morePanelsNowOpen) {
|
|
703
|
-
undoSteps.push(() => closeMorePanelsIfOpen());
|
|
704
|
-
openPredicates.push(() => isElementPresent("@more-sidebars-panel"));
|
|
705
|
-
}
|
|
353
|
+
const resolvedElements = !isSidebarOnly ? resolveElements() : [];
|
|
354
|
+
await runManualAction(selectorDef.beforeAction, resolvedElements);
|
|
355
|
+
// For sidebar-only selectors, we just open the sidebar (done above)
|
|
356
|
+
// For regular selectors, also highlight the element
|
|
357
|
+
if (!isSidebarOnly && selectorDef.selector) {
|
|
358
|
+
await highlightElement(selectorDef.selector, HIGHLIGHT_DURATION_MS);
|
|
706
359
|
}
|
|
707
|
-
// afterAction is the declared inverse for custom reveals (e.g. field actions).
|
|
708
360
|
if (selectorDef.afterAction) {
|
|
709
|
-
|
|
710
|
-
void runManualAction(selectorDef.afterAction, !isSidebarOnly ? resolveElements() :
|
|
711
|
-
});
|
|
712
|
-
}
|
|
713
|
-
// Highlight the target. For sidebar-only selectors there is no inner
|
|
714
|
-
// target, so we highlight the opened sidebar panel itself. Wait for
|
|
715
|
-
// it to become visible first, since a just-revealed element may be
|
|
716
|
-
// present but not yet laid out (highlightElement skips invisible ones).
|
|
717
|
-
const highlightSelector = isSidebarOnly
|
|
718
|
-
? selectorDef.location
|
|
719
|
-
? `@sidebar-panel-${selectorDef.location}`
|
|
720
|
-
: ""
|
|
721
|
-
: selectorDef.selector;
|
|
722
|
-
if (highlightSelector) {
|
|
723
|
-
const highlightTargets = await waitForVisibleElements(highlightSelector, 1500);
|
|
724
|
-
if (highlightTargets.length > 0) {
|
|
725
|
-
await highlightElement(highlightSelector, HIGHLIGHT_DURATION_MS);
|
|
726
|
-
}
|
|
727
|
-
}
|
|
728
|
-
// If we opened/undid anything, this was a State-3 reveal: keep the
|
|
729
|
-
// button active (green) and register it for mutual exclusion.
|
|
730
|
-
if (undoSteps.length > 0) {
|
|
731
|
-
const id = ++revealControllerSeq;
|
|
732
|
-
controllerIdRef.current = id;
|
|
733
|
-
revealRef.current = {
|
|
734
|
-
id,
|
|
735
|
-
restore: () => {
|
|
736
|
-
for (let i = undoSteps.length - 1; i >= 0; i -= 1) {
|
|
737
|
-
try {
|
|
738
|
-
undoSteps[i]?.();
|
|
739
|
-
}
|
|
740
|
-
catch {
|
|
741
|
-
// ignore individual undo failures
|
|
742
|
-
}
|
|
743
|
-
}
|
|
744
|
-
},
|
|
745
|
-
isStillOpen: () => openPredicates.length === 0
|
|
746
|
-
? true
|
|
747
|
-
: openPredicates.some((predicate) => predicate()),
|
|
748
|
-
};
|
|
749
|
-
registerActiveReveal({
|
|
750
|
-
id,
|
|
751
|
-
close: () => runRestoreRef.current(),
|
|
752
|
-
});
|
|
753
|
-
setIsActiveReveal(true);
|
|
754
|
-
if (closeMode === "auto") {
|
|
755
|
-
window.setTimeout(() => {
|
|
756
|
-
if (controllerIdRef.current === id) {
|
|
757
|
-
runRestoreRef.current();
|
|
758
|
-
}
|
|
759
|
-
}, HIGHLIGHT_DURATION_MS);
|
|
760
|
-
}
|
|
361
|
+
window.setTimeout(() => {
|
|
362
|
+
void runManualAction(selectorDef.afterAction, !isSidebarOnly ? resolveElements() : []);
|
|
363
|
+
}, HIGHLIGHT_DURATION_MS);
|
|
761
364
|
}
|
|
762
|
-
}, disabled:
|
|
763
|
-
? "border-feedback-
|
|
764
|
-
:
|
|
765
|
-
? "border-feedback-blue bg-feedback-blue-light text-feedback-blue hover:bg-feedback-blue-light cursor-pointer"
|
|
766
|
-
: "border-border-default bg-neutral-grey-5 text-neutral-grey-50 cursor-not-allowed"), children: [_jsx(LocateFixed, { className: "h-3.5 w-3.5", strokeWidth: 1.5 }), _jsx("span", { className: "sr-only", children: "Show me" })] }, keyProp) }), _jsx(TooltipContent, { children: tooltipText })] }));
|
|
365
|
+
}, disabled: !isActionable, className: cn("inline-flex h-5 w-5 items-center justify-center rounded border transition-colors", isActionable
|
|
366
|
+
? "border-feedback-blue bg-feedback-blue-light text-feedback-blue hover:bg-feedback-blue-light cursor-pointer"
|
|
367
|
+
: "border-border-default bg-neutral-grey-5 text-neutral-grey-50 cursor-not-allowed"), children: [_jsx(LocateFixed, { className: "h-3.5 w-3.5", strokeWidth: 1.5 }), _jsx("span", { className: "sr-only", children: "Show me" })] }, keyProp) }), _jsx(TooltipContent, { children: tooltipText })] }));
|
|
767
368
|
}
|
|
768
369
|
// Render markdown content with clickable selectors
|
|
769
370
|
// Supports both {{selectorName}} syntax (looks up in uiSelectors) and legacy @selector syntax
|
|
@@ -806,10 +407,10 @@ function renderLineWithSelectors(text, uiSelectors, manualLinkTargets, onManualL
|
|
|
806
407
|
function renderInlineSelectorsAndFormatting(text, uiSelectors) {
|
|
807
408
|
const parts = [];
|
|
808
409
|
let lastIndex = 0;
|
|
809
|
-
// Combined regex for {{namedSelector}}, @selector, and **bold
|
|
810
|
-
//
|
|
811
|
-
//
|
|
812
|
-
//
|
|
410
|
+
// Combined regex for {{namedSelector}}, @selector, and **bold**.
|
|
411
|
+
// @selector can include -sidebar suffix for sidebar-only selectors.
|
|
412
|
+
// The matcher keeps legacy @iframe: tokens parseable, but they are unavailable.
|
|
413
|
+
// Also matches optional parentheses around selectors: ({{name}}) or (@selector).
|
|
813
414
|
const regex = /(\()?(\{\{([\w\-]+)\}\})|(\()?(@(?:iframe:[\w\-\.#\[\]=]*[\w\-#\[\]=]|[\w\-\.#\[\]=]*[\w\-#\[\]=]))|(\*\*(.+?)\*\*)/g;
|
|
814
415
|
let match;
|
|
815
416
|
while ((match = regex.exec(text)) !== null) {
|