/** * Editor Bridge — injected into customer site iframes by the DCS visual editor. * * Responsibilities: * 1. Report available sections and text keys to the parent portal * 2. Enable inline contenteditable editing on data-text-key/data-dcs-text elements (double-click) * 3. Render section overlay highlights on hover/select from parent * 4. Communicate all interactions back to the parent via postMessage * 5. Monitor navigation within the iframe and notify the parent * 6. Show floating edit icon on hover for text-key elements * 7. Show floating image icon on hover for images within sections * * Supports both legacy `data-text-key` and modern `data-dcs-text` attributes * for backward compatibility during the migration period. * * NOTE: AI ✨ buttons are rendered by the portal-side SectionOverlayLayer, * NOT by this bridge. The bridge only reports section/text key data and * handles inline text editing. * * This script runs inside the iframe (customer site). The parent portal * communicates via postMessage using the `dcs:*` message protocol. */ interface SectionInfo { id: string; label: string | null; bounds: { x: number; y: number; width: number; height: number; }; textKeyCount: number; } interface EditorReadyPayload { sections: SectionInfo[]; textKeys: string[]; contentHeight: number; /** Whether the page has a [data-blog-content] element (blog post page) */ hasBlogContent: boolean; /** Current innerHTML of the blog content element, if present */ blogContentHtml: string | null; /** Whether the page has a [data-event-content] or [data-rich-content="event"] element */ hasEventContent: boolean; /** Current innerHTML of the event content element, if present */ eventContentHtml: string | null; /** Current blog post title text from [data-blog-title], if present */ blogTitle: string | null; /** Current blog post summary/description text from [data-blog-summary], if present */ blogSummary: string | null; /** Whether the page has any managed form roots */ hasManagedForms: boolean; /** Form IDs for all detected managed-form roots */ managedFormIds: string[]; /** Whether the page has any [data-dcs-reviews] elements */ hasReviews: boolean; /** Keys of all [data-dcs-reviews] elements found on the page */ reviewKeys: string[]; } /** * Swap the live ``(s) carrying a managed image key to a new source. * * Mirrors the self-heal invariant: a `` does NOT re-resolve after its * `` set changes, so the stale `` siblings are removed and the * `srcset` on the `` cleared — otherwise the browser keeps serving the old * variant. `data-dcs-image-url`/`-alt` are updated too so a subsequent * right-click reports the new image, not the replaced one. * * @returns the number of elements updated (0 when the key isn't on the page). */ declare function applyImageOverride(key: string, src: string, alt?: string | null): number; /** * Re-apply all pending image overrides. Called after a re-render (HMR / SPA nav) * so a hot reload doesn't revert a not-yet-saved swap. */ declare function applyPendingImageOverrides(): void; /** * Record a pending image override (test/utility seam for the replay path). */ declare function recordPendingImageOverride(key: string, src: string, alt?: string | null): void; /** * Handle a `dcs:update-text` that actually targets a MANAGED IMAGE key. * * The portal's discard/undo paths (discardTextChanges / discardSingleTextChange * in visualEditor.ts) revert EVERY staged key — including image keys — via the * text revert callback, which sends `dcs:update-text`. `updateTextInPlace` only * touches `data-text-key` elements, a no-op for image keys (which live on * `data-dcs-image-key`), while `pendingImageOverrides` would keep re-applying * the discarded src on every re-render — the discarded swap stayed sticky until * a manual refresh. So: if the key has a pending image override (or a managed * image element on the page), drop the sticky override and swap the live * `` back to the reverted URL. Covers discard-all, discard-single, undo, * and reload-drops-staged-swap in one place. * * @returns true when the key was handled as an image revert (skip text handling). */ declare function revertImageOverrideIfImageKey(key: string, value: string): boolean; /** * Handle a `dcs:update-text` that targets a MANAGED IMAGE **ALT** key * (`data-dcs-image-alt-key`). The portal stages an alt change alongside the * src change on "Replace without AI"; on discard/undo it reverts each staged * key via `dcs:update-text`. Alt keys are attributes, not text nodes, so * `updateTextInPlace` would be a silent no-op — instead restore the `` * alt and refresh any pending image override (keyed by the SRC key) so a * re-render replay does not resurrect the discarded alt. * * @returns true when the key was handled as an image-alt revert. */ declare function revertImageAltOverrideIfAltKey(key: string, value: string): boolean; /** Clear all pending image overrides (test isolation). */ declare function clearPendingImageOverrides(): void; declare function initEditorBridge(): void; export { type EditorReadyPayload, type SectionInfo, applyImageOverride, applyPendingImageOverrides, clearPendingImageOverrides, initEditorBridge, recordPendingImageOverride, revertImageAltOverrideIfAltKey, revertImageOverrideIfImageKey };