@craftile/preview-client 0.8.0 → 0.9.0
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/index.cjs +11 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +11 -4
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.cjs
CHANGED
|
@@ -165,7 +165,9 @@ class Inspector {
|
|
|
165
165
|
}
|
|
166
166
|
if (this.currentSelectedBlock?.dataset.block === blockId) {
|
|
167
167
|
this.currentSelectedBlock = newElement;
|
|
168
|
-
|
|
168
|
+
requestAnimationFrame(() => {
|
|
169
|
+
this.sendSelectedBlockPosition(true);
|
|
170
|
+
});
|
|
169
171
|
this.trackSelectedBlock();
|
|
170
172
|
}
|
|
171
173
|
}
|
|
@@ -233,7 +235,7 @@ class Inspector {
|
|
|
233
235
|
setupGlobalEventListeners() {
|
|
234
236
|
document.addEventListener("mouseover", this.handleGlobalHover.bind(this));
|
|
235
237
|
document.addEventListener("mouseout", this.handleGlobalLeave.bind(this));
|
|
236
|
-
document.addEventListener("click", this.handleGlobalClick.bind(this));
|
|
238
|
+
document.addEventListener("click", this.handleGlobalClick.bind(this), { capture: true });
|
|
237
239
|
}
|
|
238
240
|
handleGlobalHover(e) {
|
|
239
241
|
if (!this.active) {
|
|
@@ -269,9 +271,14 @@ class Inspector {
|
|
|
269
271
|
if (!blockElement) {
|
|
270
272
|
return;
|
|
271
273
|
}
|
|
272
|
-
e.stopPropagation();
|
|
273
274
|
const blockId = blockElement.getAttribute("data-block");
|
|
274
|
-
if (blockId) {
|
|
275
|
+
if (!blockId) {
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
const isAlreadySelected = this.currentSelectedBlock === blockElement;
|
|
279
|
+
if (!isAlreadySelected) {
|
|
280
|
+
e.preventDefault();
|
|
281
|
+
e.stopImmediatePropagation();
|
|
275
282
|
this.currentSelectedBlock = blockElement;
|
|
276
283
|
this.sendSelectedBlockPosition();
|
|
277
284
|
this.trackSelectedBlock();
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../../messenger/src/index.ts","../../event-bus/src/index.ts","../src/inspector.ts","../src/client.ts"],"sourcesContent":["export interface TypedMessage<T = any> {\n type: string;\n payload: T | undefined;\n}\n\nexport class WindowMessenger<Messages extends Record<string, any>> {\n private handlers = new Map<keyof Messages, Function[]>();\n private targetWindow: Window;\n private targetOrigin: string;\n private fallbackHandler?: (data: any, event: MessageEvent) => void;\n\n constructor(targetWindow: Window, targetOrigin: string = '*') {\n this.targetWindow = targetWindow;\n this.targetOrigin = targetOrigin;\n\n window.addEventListener('message', this.handleMessage.bind(this));\n }\n\n private handleMessage(event: MessageEvent) {\n const message = event.data as TypedMessage;\n\n if (!message.type) {\n return;\n }\n\n const handlers = this.handlers.get(message.type);\n\n if (handlers) {\n handlers.forEach((handler) => handler(message.payload, event));\n } else if (this.fallbackHandler) {\n this.fallbackHandler(event.data, event);\n }\n }\n\n send<K extends keyof Messages>(type: K, payload?: Messages[K]): void {\n const message: TypedMessage<Messages[K]> = { type: type as string, payload };\n this.targetWindow.postMessage(message, this.targetOrigin);\n }\n\n listen<K extends keyof Messages>(type: K, handler: (data: Messages[K], event: MessageEvent) => void): () => void {\n if (!this.handlers.has(type)) {\n this.handlers.set(type, []);\n }\n\n this.handlers.get(type)!.push(handler);\n\n return () => {\n const handlers = this.handlers.get(type);\n if (handlers) {\n const index = handlers.indexOf(handler);\n if (index > -1) {\n handlers.splice(index, 1);\n }\n }\n };\n }\n\n registerFallbackHandler(handler: (data: any, event: MessageEvent) => void) {\n this.fallbackHandler = handler;\n }\n}\n\nexport function createIframeMessenger<T extends Record<string, any>>(iframe: HTMLIFrameElement, targetOrigin = '*') {\n return new WindowMessenger<T>(iframe.contentWindow!, targetOrigin);\n}\n\nexport function createParentMessenger<T extends Record<string, any>>(targetOrigin = '*') {\n if (window.parent === window) {\n throw new Error('Not inside an iframe');\n }\n return new WindowMessenger<T>(window.parent, targetOrigin);\n}\n","export type EventListener<T = any> = (data: T) => void;\nexport type EventMap = {\n [event: string]: any;\n};\n\n/**\n * Type-safe EventBus with generic event map support\n *\n * @template T Event map interface that defines the events and their data types\n */\nexport class EventBus<T extends EventMap = EventMap> {\n private listeners: Map<keyof T, Set<EventListener<any>>> = new Map();\n\n /**\n * Add an event listener\n *\n * @param event Event name\n * @param listener Event listener function\n *\n * @returns Cleanup function to remove the listener\n */\n on<K extends keyof T>(event: K, listener: EventListener<T[K]>): () => void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n\n this.listeners.get(event)!.add(listener);\n\n return () => {\n this.off(event, listener);\n };\n }\n\n /**\n * Remove an event listener\n *\n * @param event Event name\n * @param listener Event listener function to remove\n */\n off<K extends keyof T>(event: K, listener: EventListener<T[K]>): void {\n const eventListeners = this.listeners.get(event);\n\n if (eventListeners) {\n eventListeners.delete(listener);\n\n if (eventListeners.size === 0) {\n this.listeners.delete(event);\n }\n }\n }\n\n /**\n * Add a one-time event listener\n *\n * @param event Event name\n * @param listener Event listener function\n */\n once<K extends keyof T>(event: K, listener: EventListener<T[K]>): void {\n const onceWrapper = (data: T[K]) => {\n listener(data);\n this.off(event, onceWrapper);\n };\n\n this.on(event, onceWrapper);\n }\n\n /**\n * Emit an event\n *\n * @param event Event name\n * @param args Event data (optional, depending on event type)\n */\n emit<K extends keyof T>(event: K, ...args: T[K] extends void ? [] : [T[K]]): void {\n const eventListeners = this.listeners.get(event);\n\n if (eventListeners) {\n const data = args[0];\n eventListeners.forEach((listener) => {\n try {\n listener(data);\n } catch (error) {\n console.error(`Error in event listener for '${String(event)}':`, error);\n }\n });\n }\n }\n\n /**\n * Remove all listeners for an event, or all listeners if no event specified\n *\n * @param event Optional event name. If not provided, removes all listeners\n */\n removeAllListeners<K extends keyof T>(event?: K): void {\n if (event) {\n this.listeners.delete(event);\n } else {\n this.listeners.clear();\n }\n }\n}\n","import type { WindowMessenger } from '@craftile/messenger';\nimport type { WindowMessages } from '@craftile/types';\n\nexport class Inspector {\n private active = true;\n private messenger: WindowMessenger<WindowMessages>;\n private currentHoveredBlock: HTMLElement | null = null;\n private currentSelectedBlock: HTMLElement | null = null;\n private overlayButtonHovered = false;\n\n private resizeObserver: ResizeObserver | null = null;\n private mutationObserver: MutationObserver | null = null;\n\n constructor(messenger: WindowMessenger<WindowMessages>) {\n this.messenger = messenger;\n\n this.messenger.listen('craftile.inspector.enable', () => this.enable());\n this.messenger.listen('craftile.inspector.disable', () => this.disable());\n this.messenger.listen('craftile.inspector.overlay-button-enter', this.handleOverlayButtonEnter.bind(this));\n this.messenger.listen('craftile.inspector.overlay-button-leave', this.handleOverlayButtonLeave.bind(this));\n this.messenger.listen('craftile.editor.select-block', this.handleEditorSelectBlock.bind(this));\n this.messenger.listen('craftile.editor.deselect-block', this.handleEditorDeselectBlock.bind(this));\n\n window.addEventListener('scroll', this.handleScroll.bind(this), { passive: true });\n this.setupGlobalEventListeners();\n }\n\n /**\n * Update the tracked element reference when a block's DOM element changes.\n * This is needed when the root tag of a block changes during an update.\n */\n updateTrackedElement(blockId: string, newElement: HTMLElement): void {\n // Update hovered block if it matches\n if (this.currentHoveredBlock?.dataset.block === blockId) {\n this.currentHoveredBlock = newElement;\n this.sendHoveredBlockPosition();\n }\n\n // Update selected block if it matches and re-track it\n if (this.currentSelectedBlock?.dataset.block === blockId) {\n this.currentSelectedBlock = newElement;\n this.sendSelectedBlockPosition(true);\n this.trackSelectedBlock();\n }\n }\n\n enable() {\n this.active = true;\n document.body.classList.add('craftile-inspector-active');\n\n // Re-track selected block if it exists\n if (this.currentSelectedBlock) {\n this.trackSelectedBlock();\n }\n }\n\n disable() {\n this.active = false;\n document.body.classList.remove('craftile-inspector-active');\n this.currentHoveredBlock = null;\n this.overlayButtonHovered = false;\n\n if (this.resizeObserver) {\n this.resizeObserver.disconnect();\n this.resizeObserver = null;\n }\n\n if (this.mutationObserver) {\n this.mutationObserver.disconnect();\n this.mutationObserver = null;\n }\n }\n\n private handleOverlayButtonEnter() {\n this.overlayButtonHovered = true;\n }\n\n private handleOverlayButtonLeave(_data: { blockId: string }) {\n this.overlayButtonHovered = false;\n\n if (!this.currentHoveredBlock) {\n this.messenger.send('craftile.preview.block-leave');\n }\n }\n\n private handleEditorSelectBlock(data: { blockId: string }) {\n const element = document.querySelector(`[data-block=\"${data.blockId}\"]`) as HTMLElement;\n\n if (element) {\n this.currentSelectedBlock = element;\n this.sendSelectedBlockPosition();\n this.trackSelectedBlock();\n element.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'nearest' });\n }\n }\n\n private handleEditorDeselectBlock() {\n this.currentSelectedBlock = null;\n\n if (this.resizeObserver) {\n this.resizeObserver.disconnect();\n this.resizeObserver = null;\n }\n\n if (this.mutationObserver) {\n this.mutationObserver.disconnect();\n this.mutationObserver = null;\n }\n }\n\n private handleScroll() {\n if (!this.active) {\n return;\n }\n\n if (this.currentSelectedBlock) {\n this.sendSelectedBlockPosition();\n }\n\n if (this.currentHoveredBlock) {\n this.sendHoveredBlockPosition();\n }\n }\n\n private setupGlobalEventListeners() {\n document.addEventListener('mouseover', this.handleGlobalHover.bind(this));\n document.addEventListener('mouseout', this.handleGlobalLeave.bind(this));\n document.addEventListener('click', this.handleGlobalClick.bind(this));\n }\n\n private handleGlobalHover(e: Event) {\n if (!this.active) {\n return;\n }\n\n const blockElement = (e.target as Element).closest('[data-block]') as HTMLElement;\n\n if (!blockElement) {\n return;\n }\n\n e.stopPropagation();\n this.currentHoveredBlock = blockElement;\n this.sendHoveredBlockPosition();\n }\n\n private handleGlobalLeave(e: Event) {\n if (!this.active) {\n return;\n }\n\n const blockElement = (e.target as Element).closest('[data-block]') as HTMLElement;\n if (!blockElement) {\n return;\n }\n\n // Only clear overlay if button is not being hovered\n if (!this.overlayButtonHovered) {\n this.currentHoveredBlock = null;\n this.messenger.send('craftile.preview.block-leave');\n }\n }\n\n private handleGlobalClick(e: Event) {\n this.messenger.send('craftile.preview.click');\n\n if (!this.active) {\n return;\n }\n\n const blockElement = (e.target as Element).closest('[data-block]') as HTMLElement;\n if (!blockElement) {\n return;\n }\n\n e.stopPropagation();\n\n const blockId = blockElement.getAttribute('data-block');\n\n if (blockId) {\n this.currentSelectedBlock = blockElement;\n this.sendSelectedBlockPosition();\n this.trackSelectedBlock();\n }\n }\n\n private sendHoveredBlockPosition() {\n const position = this.computeElementPositioning(this.currentHoveredBlock!);\n\n this.messenger.send('craftile.preview.block-hover', {\n blockRect: position.rect,\n parentRect: position.parentRect,\n scrollTop: position.scrollTop,\n scrollLeft: position.scrollLeft,\n blockId: this.currentHoveredBlock!.dataset.block as string,\n parentFlexDirection: position.parentFlexDirection,\n });\n }\n\n private sendSelectedBlockPosition(updates: boolean = false) {\n if (!this.currentSelectedBlock) {\n return;\n }\n\n const position = this.computeElementPositioning(this.currentSelectedBlock!);\n this.messenger.send(updates ? 'craftile.preview.update-selected-block' : 'craftile.preview.block-select', {\n blockRect: position.rect,\n scrollTop: position.scrollTop,\n scrollLeft: position.scrollLeft,\n blockId: this.currentSelectedBlock!.dataset.block as string,\n });\n }\n\n private trackSelectedBlock() {\n if (!this.currentSelectedBlock) {\n return;\n }\n\n if (this.resizeObserver) {\n this.resizeObserver.disconnect();\n this.resizeObserver = null;\n }\n\n if (this.mutationObserver) {\n this.mutationObserver.disconnect();\n this.mutationObserver = null;\n }\n\n this.resizeObserver = new ResizeObserver(() => {\n if (this.active && this.currentSelectedBlock) {\n this.sendSelectedBlockPosition(true);\n }\n });\n this.resizeObserver.observe(this.currentSelectedBlock);\n\n this.mutationObserver = new MutationObserver(() => {\n if (this.active && this.currentSelectedBlock) {\n this.sendSelectedBlockPosition(true);\n }\n });\n\n this.mutationObserver.observe(this.currentSelectedBlock, {\n attributes: true,\n subtree: false,\n });\n\n // Also observe parent elements that might affect positioning\n let parent = this.currentSelectedBlock.parentElement;\n while (parent) {\n this.mutationObserver.observe(parent, {\n childList: true,\n subtree: false,\n });\n\n if (parent === document.body) {\n break;\n }\n\n parent = parent.parentElement;\n }\n }\n\n private computeElementPositioning(element: HTMLElement) {\n const rect = element.getBoundingClientRect();\n const scrollTop = window.pageYOffset || document.documentElement.scrollTop;\n const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;\n\n const eldestParent = this.findEldestParentBlock(element);\n const parentRect = eldestParent && eldestParent !== element ? eldestParent.getBoundingClientRect() : undefined;\n const parentFlexDirection = this.getElementFlexDirection(element.parentElement);\n\n return {\n rect,\n parentRect,\n scrollTop,\n scrollLeft,\n parentFlexDirection,\n };\n }\n\n private findEldestParentBlock(element: HTMLElement): HTMLElement | null {\n let eldestParent: HTMLElement | null = null;\n let parentElement = element.parentElement;\n\n while (parentElement && parentElement !== document.body) {\n if (parentElement.hasAttribute('data-block')) {\n eldestParent = parentElement;\n }\n parentElement = parentElement.parentElement;\n }\n\n return eldestParent;\n }\n\n private getElementFlexDirection(element: HTMLElement | null): 'row' | 'column' {\n if (!element) {\n return 'column';\n }\n\n const style = window.getComputedStyle(element);\n const flexDirection = style.display.includes('flex') ? style.flexDirection : 'column';\n\n return flexDirection === 'row' || flexDirection === 'row-reverse' ? 'row' : 'column';\n }\n}\n","import type { WindowMessages } from '@craftile/types';\nimport { createParentMessenger, WindowMessenger } from '@craftile/messenger';\nimport { EventBus } from '@craftile/event-bus';\nimport { Inspector } from './inspector';\n\nexport class PreviewClient extends EventBus {\n private messenger: WindowMessenger<WindowMessages>;\n public inspector: Inspector;\n\n constructor() {\n super();\n\n this.messenger = createParentMessenger(window.origin);\n this.inspector = new Inspector(this.messenger);\n\n this.initialize();\n }\n\n private initialize() {\n window.addEventListener('load', () => {\n this.messenger.send('craftile.preview.ready', {});\n setTimeout(() => {\n this.sendPageData();\n }, 0);\n });\n\n this.messenger.registerFallbackHandler((data: any) => {\n const { type, payload } = data;\n this.emit(type, payload);\n });\n }\n\n private sendPageData() {\n const pageDataElement = document.getElementById('page-data');\n\n if (!pageDataElement) {\n return;\n }\n\n try {\n const pageData = JSON.parse(pageDataElement.textContent || '{}');\n this.messenger.send('craftile.preview.page-data', { pageData });\n } catch (error) {\n console.error('Failed to parse page data:', error);\n }\n }\n}\n"],"names":[],"mappings":";;;;;AAKO,MAAM,gBAAsD;AAAA,EAMjE,YAAY,cAAsB,eAAuB,KAAK;AALtD,wDAAe,IAAA;AACf;AACA;AACA;AAGN,SAAK,eAAe;AACpB,SAAK,eAAe;AAEpB,WAAO,iBAAiB,WAAW,KAAK,cAAc,KAAK,IAAI,CAAC;AAAA,EAClE;AAAA,EAEQ,cAAc,OAAqB;AACzC,UAAM,UAAU,MAAM;AAEtB,QAAI,CAAC,QAAQ,MAAM;AACjB;AAAA,IACF;AAEA,UAAM,WAAW,KAAK,SAAS,IAAI,QAAQ,IAAI;AAE/C,QAAI,UAAU;AACZ,eAAS,QAAQ,CAAC,YAAY,QAAQ,QAAQ,SAAS,KAAK,CAAC;AAAA,IAC/D,WAAW,KAAK,iBAAiB;AAC/B,WAAK,gBAAgB,MAAM,MAAM,KAAK;AAAA,IACxC;AAAA,EACF;AAAA,EAEA,KAA+B,MAAS,SAA6B;AACnE,UAAM,UAAqC,EAAE,MAAsB,QAAA;AACnE,SAAK,aAAa,YAAY,SAAS,KAAK,YAAY;AAAA,EAC1D;AAAA,EAEA,OAAiC,MAAS,SAAuE;AAC/G,QAAI,CAAC,KAAK,SAAS,IAAI,IAAI,GAAG;AAC5B,WAAK,SAAS,IAAI,MAAM,CAAA,CAAE;AAAA,IAC5B;AAEA,SAAK,SAAS,IAAI,IAAI,EAAG,KAAK,OAAO;AAErC,WAAO,MAAM;AACX,YAAM,WAAW,KAAK,SAAS,IAAI,IAAI;AACvC,UAAI,UAAU;AACZ,cAAM,QAAQ,SAAS,QAAQ,OAAO;AACtC,YAAI,QAAQ,IAAI;AACd,mBAAS,OAAO,OAAO,CAAC;AAAA,QAC1B;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,wBAAwB,SAAmD;AACzE,SAAK,kBAAkB;AAAA,EACzB;AACF;AAMO,SAAS,sBAAqD,eAAe,KAAK;AACvF,MAAI,OAAO,WAAW,QAAQ;AAC5B,UAAM,IAAI,MAAM,sBAAsB;AAAA,EACxC;AACA,SAAO,IAAI,gBAAmB,OAAO,QAAQ,YAAY;AAC3D;AC7DO,MAAM,SAAwC;AAAA,EAA9C;AACG,yDAAuD,IAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAU/D,GAAsB,OAAU,UAA2C;AACzE,QAAI,CAAC,KAAK,UAAU,IAAI,KAAK,GAAG;AAC9B,WAAK,UAAU,IAAI,OAAO,oBAAI,KAAK;AAAA,IACrC;AAEA,SAAK,UAAU,IAAI,KAAK,EAAG,IAAI,QAAQ;AAEvC,WAAO,MAAM;AACX,WAAK,IAAI,OAAO,QAAQ;AAAA,IAC1B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,IAAuB,OAAU,UAAqC;AACpE,UAAM,iBAAiB,KAAK,UAAU,IAAI,KAAK;AAE/C,QAAI,gBAAgB;AAClB,qBAAe,OAAO,QAAQ;AAE9B,UAAI,eAAe,SAAS,GAAG;AAC7B,aAAK,UAAU,OAAO,KAAK;AAAA,MAC7B;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,KAAwB,OAAU,UAAqC;AACrE,UAAM,cAAc,CAAC,SAAe;AAClC,eAAS,IAAI;AACb,WAAK,IAAI,OAAO,WAAW;AAAA,IAC7B;AAEA,SAAK,GAAG,OAAO,WAAW;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,KAAwB,UAAa,MAA6C;AAChF,UAAM,iBAAiB,KAAK,UAAU,IAAI,KAAK;AAE/C,QAAI,gBAAgB;AAClB,YAAM,OAAO,KAAK,CAAC;AACnB,qBAAe,QAAQ,CAAC,aAAa;AACnC,YAAI;AACF,mBAAS,IAAI;AAAA,QACf,SAAS,OAAO;AACd,kBAAQ,MAAM,gCAAgC,OAAO,KAAK,CAAC,MAAM,KAAK;AAAA,QACxE;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,mBAAsC,OAAiB;AACrD,QAAI,OAAO;AACT,WAAK,UAAU,OAAO,KAAK;AAAA,IAC7B,OAAO;AACL,WAAK,UAAU,MAAA;AAAA,IACjB;AAAA,EACF;AACF;AChGO,MAAM,UAAU;AAAA,EAUrB,YAAY,WAA4C;AAThD,kCAAS;AACT;AACA,+CAA0C;AAC1C,gDAA2C;AAC3C,gDAAuB;AAEvB,0CAAwC;AACxC,4CAA4C;AAGlD,SAAK,YAAY;AAEjB,SAAK,UAAU,OAAO,6BAA6B,MAAM,KAAK,QAAQ;AACtE,SAAK,UAAU,OAAO,8BAA8B,MAAM,KAAK,SAAS;AACxE,SAAK,UAAU,OAAO,2CAA2C,KAAK,yBAAyB,KAAK,IAAI,CAAC;AACzG,SAAK,UAAU,OAAO,2CAA2C,KAAK,yBAAyB,KAAK,IAAI,CAAC;AACzG,SAAK,UAAU,OAAO,gCAAgC,KAAK,wBAAwB,KAAK,IAAI,CAAC;AAC7F,SAAK,UAAU,OAAO,kCAAkC,KAAK,0BAA0B,KAAK,IAAI,CAAC;AAEjG,WAAO,iBAAiB,UAAU,KAAK,aAAa,KAAK,IAAI,GAAG,EAAE,SAAS,MAAM;AACjF,SAAK,0BAAA;AAAA,EACP;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,qBAAqB,SAAiB,YAA+B;AAEnE,QAAI,KAAK,qBAAqB,QAAQ,UAAU,SAAS;AACvD,WAAK,sBAAsB;AAC3B,WAAK,yBAAA;AAAA,IACP;AAGA,QAAI,KAAK,sBAAsB,QAAQ,UAAU,SAAS;AACxD,WAAK,uBAAuB;AAC5B,WAAK,0BAA0B,IAAI;AACnC,WAAK,mBAAA;AAAA,IACP;AAAA,EACF;AAAA,EAEA,SAAS;AACP,SAAK,SAAS;AACd,aAAS,KAAK,UAAU,IAAI,2BAA2B;AAGvD,QAAI,KAAK,sBAAsB;AAC7B,WAAK,mBAAA;AAAA,IACP;AAAA,EACF;AAAA,EAEA,UAAU;AACR,SAAK,SAAS;AACd,aAAS,KAAK,UAAU,OAAO,2BAA2B;AAC1D,SAAK,sBAAsB;AAC3B,SAAK,uBAAuB;AAE5B,QAAI,KAAK,gBAAgB;AACvB,WAAK,eAAe,WAAA;AACpB,WAAK,iBAAiB;AAAA,IACxB;AAEA,QAAI,KAAK,kBAAkB;AACzB,WAAK,iBAAiB,WAAA;AACtB,WAAK,mBAAmB;AAAA,IAC1B;AAAA,EACF;AAAA,EAEQ,2BAA2B;AACjC,SAAK,uBAAuB;AAAA,EAC9B;AAAA,EAEQ,yBAAyB,OAA4B;AAC3D,SAAK,uBAAuB;AAE5B,QAAI,CAAC,KAAK,qBAAqB;AAC7B,WAAK,UAAU,KAAK,8BAA8B;AAAA,IACpD;AAAA,EACF;AAAA,EAEQ,wBAAwB,MAA2B;AACzD,UAAM,UAAU,SAAS,cAAc,gBAAgB,KAAK,OAAO,IAAI;AAEvE,QAAI,SAAS;AACX,WAAK,uBAAuB;AAC5B,WAAK,0BAAA;AACL,WAAK,mBAAA;AACL,cAAQ,eAAe,EAAE,UAAU,UAAU,OAAO,WAAW,QAAQ,WAAW;AAAA,IACpF;AAAA,EACF;AAAA,EAEQ,4BAA4B;AAClC,SAAK,uBAAuB;AAE5B,QAAI,KAAK,gBAAgB;AACvB,WAAK,eAAe,WAAA;AACpB,WAAK,iBAAiB;AAAA,IACxB;AAEA,QAAI,KAAK,kBAAkB;AACzB,WAAK,iBAAiB,WAAA;AACtB,WAAK,mBAAmB;AAAA,IAC1B;AAAA,EACF;AAAA,EAEQ,eAAe;AACrB,QAAI,CAAC,KAAK,QAAQ;AAChB;AAAA,IACF;AAEA,QAAI,KAAK,sBAAsB;AAC7B,WAAK,0BAAA;AAAA,IACP;AAEA,QAAI,KAAK,qBAAqB;AAC5B,WAAK,yBAAA;AAAA,IACP;AAAA,EACF;AAAA,EAEQ,4BAA4B;AAClC,aAAS,iBAAiB,aAAa,KAAK,kBAAkB,KAAK,IAAI,CAAC;AACxE,aAAS,iBAAiB,YAAY,KAAK,kBAAkB,KAAK,IAAI,CAAC;AACvE,aAAS,iBAAiB,SAAS,KAAK,kBAAkB,KAAK,IAAI,CAAC;AAAA,EACtE;AAAA,EAEQ,kBAAkB,GAAU;AAClC,QAAI,CAAC,KAAK,QAAQ;AAChB;AAAA,IACF;AAEA,UAAM,eAAgB,EAAE,OAAmB,QAAQ,cAAc;AAEjE,QAAI,CAAC,cAAc;AACjB;AAAA,IACF;AAEA,MAAE,gBAAA;AACF,SAAK,sBAAsB;AAC3B,SAAK,yBAAA;AAAA,EACP;AAAA,EAEQ,kBAAkB,GAAU;AAClC,QAAI,CAAC,KAAK,QAAQ;AAChB;AAAA,IACF;AAEA,UAAM,eAAgB,EAAE,OAAmB,QAAQ,cAAc;AACjE,QAAI,CAAC,cAAc;AACjB;AAAA,IACF;AAGA,QAAI,CAAC,KAAK,sBAAsB;AAC9B,WAAK,sBAAsB;AAC3B,WAAK,UAAU,KAAK,8BAA8B;AAAA,IACpD;AAAA,EACF;AAAA,EAEQ,kBAAkB,GAAU;AAClC,SAAK,UAAU,KAAK,wBAAwB;AAE5C,QAAI,CAAC,KAAK,QAAQ;AAChB;AAAA,IACF;AAEA,UAAM,eAAgB,EAAE,OAAmB,QAAQ,cAAc;AACjE,QAAI,CAAC,cAAc;AACjB;AAAA,IACF;AAEA,MAAE,gBAAA;AAEF,UAAM,UAAU,aAAa,aAAa,YAAY;AAEtD,QAAI,SAAS;AACX,WAAK,uBAAuB;AAC5B,WAAK,0BAAA;AACL,WAAK,mBAAA;AAAA,IACP;AAAA,EACF;AAAA,EAEQ,2BAA2B;AACjC,UAAM,WAAW,KAAK,0BAA0B,KAAK,mBAAoB;AAEzE,SAAK,UAAU,KAAK,gCAAgC;AAAA,MAClD,WAAW,SAAS;AAAA,MACpB,YAAY,SAAS;AAAA,MACrB,WAAW,SAAS;AAAA,MACpB,YAAY,SAAS;AAAA,MACrB,SAAS,KAAK,oBAAqB,QAAQ;AAAA,MAC3C,qBAAqB,SAAS;AAAA,IAAA,CAC/B;AAAA,EACH;AAAA,EAEQ,0BAA0B,UAAmB,OAAO;AAC1D,QAAI,CAAC,KAAK,sBAAsB;AAC9B;AAAA,IACF;AAEA,UAAM,WAAW,KAAK,0BAA0B,KAAK,oBAAqB;AAC1E,SAAK,UAAU,KAAK,UAAU,2CAA2C,iCAAiC;AAAA,MACxG,WAAW,SAAS;AAAA,MACpB,WAAW,SAAS;AAAA,MACpB,YAAY,SAAS;AAAA,MACrB,SAAS,KAAK,qBAAsB,QAAQ;AAAA,IAAA,CAC7C;AAAA,EACH;AAAA,EAEQ,qBAAqB;AAC3B,QAAI,CAAC,KAAK,sBAAsB;AAC9B;AAAA,IACF;AAEA,QAAI,KAAK,gBAAgB;AACvB,WAAK,eAAe,WAAA;AACpB,WAAK,iBAAiB;AAAA,IACxB;AAEA,QAAI,KAAK,kBAAkB;AACzB,WAAK,iBAAiB,WAAA;AACtB,WAAK,mBAAmB;AAAA,IAC1B;AAEA,SAAK,iBAAiB,IAAI,eAAe,MAAM;AAC7C,UAAI,KAAK,UAAU,KAAK,sBAAsB;AAC5C,aAAK,0BAA0B,IAAI;AAAA,MACrC;AAAA,IACF,CAAC;AACD,SAAK,eAAe,QAAQ,KAAK,oBAAoB;AAErD,SAAK,mBAAmB,IAAI,iBAAiB,MAAM;AACjD,UAAI,KAAK,UAAU,KAAK,sBAAsB;AAC5C,aAAK,0BAA0B,IAAI;AAAA,MACrC;AAAA,IACF,CAAC;AAED,SAAK,iBAAiB,QAAQ,KAAK,sBAAsB;AAAA,MACvD,YAAY;AAAA,MACZ,SAAS;AAAA,IAAA,CACV;AAGD,QAAI,SAAS,KAAK,qBAAqB;AACvC,WAAO,QAAQ;AACb,WAAK,iBAAiB,QAAQ,QAAQ;AAAA,QACpC,WAAW;AAAA,QACX,SAAS;AAAA,MAAA,CACV;AAED,UAAI,WAAW,SAAS,MAAM;AAC5B;AAAA,MACF;AAEA,eAAS,OAAO;AAAA,IAClB;AAAA,EACF;AAAA,EAEQ,0BAA0B,SAAsB;AACtD,UAAM,OAAO,QAAQ,sBAAA;AACrB,UAAM,YAAY,OAAO,eAAe,SAAS,gBAAgB;AACjE,UAAM,aAAa,OAAO,eAAe,SAAS,gBAAgB;AAElE,UAAM,eAAe,KAAK,sBAAsB,OAAO;AACvD,UAAM,aAAa,gBAAgB,iBAAiB,UAAU,aAAa,0BAA0B;AACrG,UAAM,sBAAsB,KAAK,wBAAwB,QAAQ,aAAa;AAE9E,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAAA,EAEJ;AAAA,EAEQ,sBAAsB,SAA0C;AACtE,QAAI,eAAmC;AACvC,QAAI,gBAAgB,QAAQ;AAE5B,WAAO,iBAAiB,kBAAkB,SAAS,MAAM;AACvD,UAAI,cAAc,aAAa,YAAY,GAAG;AAC5C,uBAAe;AAAA,MACjB;AACA,sBAAgB,cAAc;AAAA,IAChC;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,wBAAwB,SAA+C;AAC7E,QAAI,CAAC,SAAS;AACZ,aAAO;AAAA,IACT;AAEA,UAAM,QAAQ,OAAO,iBAAiB,OAAO;AAC7C,UAAM,gBAAgB,MAAM,QAAQ,SAAS,MAAM,IAAI,MAAM,gBAAgB;AAE7E,WAAO,kBAAkB,SAAS,kBAAkB,gBAAgB,QAAQ;AAAA,EAC9E;AACF;AC3SO,MAAM,sBAAsB,SAAS;AAAA,EAI1C,cAAc;AACZ,UAAA;AAJM;AACD;AAKL,SAAK,YAAY,sBAAsB,OAAO,MAAM;AACpD,SAAK,YAAY,IAAI,UAAU,KAAK,SAAS;AAE7C,SAAK,WAAA;AAAA,EACP;AAAA,EAEQ,aAAa;AACnB,WAAO,iBAAiB,QAAQ,MAAM;AACpC,WAAK,UAAU,KAAK,0BAA0B,CAAA,CAAE;AAChD,iBAAW,MAAM;AACf,aAAK,aAAA;AAAA,MACP,GAAG,CAAC;AAAA,IACN,CAAC;AAED,SAAK,UAAU,wBAAwB,CAAC,SAAc;AACpD,YAAM,EAAE,MAAM,QAAA,IAAY;AAC1B,WAAK,KAAK,MAAM,OAAO;AAAA,IACzB,CAAC;AAAA,EACH;AAAA,EAEQ,eAAe;AACrB,UAAM,kBAAkB,SAAS,eAAe,WAAW;AAE3D,QAAI,CAAC,iBAAiB;AACpB;AAAA,IACF;AAEA,QAAI;AACF,YAAM,WAAW,KAAK,MAAM,gBAAgB,eAAe,IAAI;AAC/D,WAAK,UAAU,KAAK,8BAA8B,EAAE,UAAU;AAAA,IAChE,SAAS,OAAO;AACd,cAAQ,MAAM,8BAA8B,KAAK;AAAA,IACnD;AAAA,EACF;AACF;;;"}
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../messenger/src/index.ts","../../event-bus/src/index.ts","../src/inspector.ts","../src/client.ts"],"sourcesContent":["export interface TypedMessage<T = any> {\n type: string;\n payload: T | undefined;\n}\n\nexport class WindowMessenger<Messages extends Record<string, any>> {\n private handlers = new Map<keyof Messages, Function[]>();\n private targetWindow: Window;\n private targetOrigin: string;\n private fallbackHandler?: (data: any, event: MessageEvent) => void;\n\n constructor(targetWindow: Window, targetOrigin: string = '*') {\n this.targetWindow = targetWindow;\n this.targetOrigin = targetOrigin;\n\n window.addEventListener('message', this.handleMessage.bind(this));\n }\n\n private handleMessage(event: MessageEvent) {\n const message = event.data as TypedMessage;\n\n if (!message.type) {\n return;\n }\n\n const handlers = this.handlers.get(message.type);\n\n if (handlers) {\n handlers.forEach((handler) => handler(message.payload, event));\n } else if (this.fallbackHandler) {\n this.fallbackHandler(event.data, event);\n }\n }\n\n send<K extends keyof Messages>(type: K, payload?: Messages[K]): void {\n const message: TypedMessage<Messages[K]> = { type: type as string, payload };\n this.targetWindow.postMessage(message, this.targetOrigin);\n }\n\n listen<K extends keyof Messages>(type: K, handler: (data: Messages[K], event: MessageEvent) => void): () => void {\n if (!this.handlers.has(type)) {\n this.handlers.set(type, []);\n }\n\n this.handlers.get(type)!.push(handler);\n\n return () => {\n const handlers = this.handlers.get(type);\n if (handlers) {\n const index = handlers.indexOf(handler);\n if (index > -1) {\n handlers.splice(index, 1);\n }\n }\n };\n }\n\n registerFallbackHandler(handler: (data: any, event: MessageEvent) => void) {\n this.fallbackHandler = handler;\n }\n}\n\nexport function createIframeMessenger<T extends Record<string, any>>(iframe: HTMLIFrameElement, targetOrigin = '*') {\n return new WindowMessenger<T>(iframe.contentWindow!, targetOrigin);\n}\n\nexport function createParentMessenger<T extends Record<string, any>>(targetOrigin = '*') {\n if (window.parent === window) {\n throw new Error('Not inside an iframe');\n }\n return new WindowMessenger<T>(window.parent, targetOrigin);\n}\n","export type EventListener<T = any> = (data: T) => void;\nexport type EventMap = {\n [event: string]: any;\n};\n\n/**\n * Type-safe EventBus with generic event map support\n *\n * @template T Event map interface that defines the events and their data types\n */\nexport class EventBus<T extends EventMap = EventMap> {\n private listeners: Map<keyof T, Set<EventListener<any>>> = new Map();\n\n /**\n * Add an event listener\n *\n * @param event Event name\n * @param listener Event listener function\n *\n * @returns Cleanup function to remove the listener\n */\n on<K extends keyof T>(event: K, listener: EventListener<T[K]>): () => void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n\n this.listeners.get(event)!.add(listener);\n\n return () => {\n this.off(event, listener);\n };\n }\n\n /**\n * Remove an event listener\n *\n * @param event Event name\n * @param listener Event listener function to remove\n */\n off<K extends keyof T>(event: K, listener: EventListener<T[K]>): void {\n const eventListeners = this.listeners.get(event);\n\n if (eventListeners) {\n eventListeners.delete(listener);\n\n if (eventListeners.size === 0) {\n this.listeners.delete(event);\n }\n }\n }\n\n /**\n * Add a one-time event listener\n *\n * @param event Event name\n * @param listener Event listener function\n */\n once<K extends keyof T>(event: K, listener: EventListener<T[K]>): void {\n const onceWrapper = (data: T[K]) => {\n listener(data);\n this.off(event, onceWrapper);\n };\n\n this.on(event, onceWrapper);\n }\n\n /**\n * Emit an event\n *\n * @param event Event name\n * @param args Event data (optional, depending on event type)\n */\n emit<K extends keyof T>(event: K, ...args: T[K] extends void ? [] : [T[K]]): void {\n const eventListeners = this.listeners.get(event);\n\n if (eventListeners) {\n const data = args[0];\n eventListeners.forEach((listener) => {\n try {\n listener(data);\n } catch (error) {\n console.error(`Error in event listener for '${String(event)}':`, error);\n }\n });\n }\n }\n\n /**\n * Remove all listeners for an event, or all listeners if no event specified\n *\n * @param event Optional event name. If not provided, removes all listeners\n */\n removeAllListeners<K extends keyof T>(event?: K): void {\n if (event) {\n this.listeners.delete(event);\n } else {\n this.listeners.clear();\n }\n }\n}\n","import type { WindowMessenger } from '@craftile/messenger';\nimport type { WindowMessages } from '@craftile/types';\n\nexport class Inspector {\n private active = true;\n private messenger: WindowMessenger<WindowMessages>;\n private currentHoveredBlock: HTMLElement | null = null;\n private currentSelectedBlock: HTMLElement | null = null;\n private overlayButtonHovered = false;\n\n private resizeObserver: ResizeObserver | null = null;\n private mutationObserver: MutationObserver | null = null;\n\n constructor(messenger: WindowMessenger<WindowMessages>) {\n this.messenger = messenger;\n\n this.messenger.listen('craftile.inspector.enable', () => this.enable());\n this.messenger.listen('craftile.inspector.disable', () => this.disable());\n this.messenger.listen('craftile.inspector.overlay-button-enter', this.handleOverlayButtonEnter.bind(this));\n this.messenger.listen('craftile.inspector.overlay-button-leave', this.handleOverlayButtonLeave.bind(this));\n this.messenger.listen('craftile.editor.select-block', this.handleEditorSelectBlock.bind(this));\n this.messenger.listen('craftile.editor.deselect-block', this.handleEditorDeselectBlock.bind(this));\n\n window.addEventListener('scroll', this.handleScroll.bind(this), { passive: true });\n this.setupGlobalEventListeners();\n }\n\n /**\n * Update the tracked element reference when a block's DOM element changes.\n * This is needed when the root tag of a block changes during an update.\n */\n updateTrackedElement(blockId: string, newElement: HTMLElement): void {\n // Update hovered block if it matches\n if (this.currentHoveredBlock?.dataset.block === blockId) {\n this.currentHoveredBlock = newElement;\n this.sendHoveredBlockPosition();\n }\n\n // Update selected block if it matches and re-track it\n if (this.currentSelectedBlock?.dataset.block === blockId) {\n this.currentSelectedBlock = newElement;\n requestAnimationFrame(() => {\n this.sendSelectedBlockPosition(true);\n });\n this.trackSelectedBlock();\n }\n }\n\n enable() {\n this.active = true;\n document.body.classList.add('craftile-inspector-active');\n\n // Re-track selected block if it exists\n if (this.currentSelectedBlock) {\n this.trackSelectedBlock();\n }\n }\n\n disable() {\n this.active = false;\n document.body.classList.remove('craftile-inspector-active');\n this.currentHoveredBlock = null;\n this.overlayButtonHovered = false;\n\n if (this.resizeObserver) {\n this.resizeObserver.disconnect();\n this.resizeObserver = null;\n }\n\n if (this.mutationObserver) {\n this.mutationObserver.disconnect();\n this.mutationObserver = null;\n }\n }\n\n private handleOverlayButtonEnter() {\n this.overlayButtonHovered = true;\n }\n\n private handleOverlayButtonLeave(_data: { blockId: string }) {\n this.overlayButtonHovered = false;\n\n if (!this.currentHoveredBlock) {\n this.messenger.send('craftile.preview.block-leave');\n }\n }\n\n private handleEditorSelectBlock(data: { blockId: string }) {\n const element = document.querySelector(`[data-block=\"${data.blockId}\"]`) as HTMLElement;\n\n if (element) {\n this.currentSelectedBlock = element;\n this.sendSelectedBlockPosition();\n this.trackSelectedBlock();\n element.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'nearest' });\n }\n }\n\n private handleEditorDeselectBlock() {\n this.currentSelectedBlock = null;\n\n if (this.resizeObserver) {\n this.resizeObserver.disconnect();\n this.resizeObserver = null;\n }\n\n if (this.mutationObserver) {\n this.mutationObserver.disconnect();\n this.mutationObserver = null;\n }\n }\n\n private handleScroll() {\n if (!this.active) {\n return;\n }\n\n if (this.currentSelectedBlock) {\n this.sendSelectedBlockPosition();\n }\n\n if (this.currentHoveredBlock) {\n this.sendHoveredBlockPosition();\n }\n }\n\n private setupGlobalEventListeners() {\n document.addEventListener('mouseover', this.handleGlobalHover.bind(this));\n document.addEventListener('mouseout', this.handleGlobalLeave.bind(this));\n document.addEventListener('click', this.handleGlobalClick.bind(this), { capture: true });\n }\n\n private handleGlobalHover(e: Event) {\n if (!this.active) {\n return;\n }\n\n const blockElement = (e.target as Element).closest('[data-block]') as HTMLElement;\n\n if (!blockElement) {\n return;\n }\n\n e.stopPropagation();\n this.currentHoveredBlock = blockElement;\n this.sendHoveredBlockPosition();\n }\n\n private handleGlobalLeave(e: Event) {\n if (!this.active) {\n return;\n }\n\n const blockElement = (e.target as Element).closest('[data-block]') as HTMLElement;\n if (!blockElement) {\n return;\n }\n\n // Only clear overlay if button is not being hovered\n if (!this.overlayButtonHovered) {\n this.currentHoveredBlock = null;\n this.messenger.send('craftile.preview.block-leave');\n }\n }\n\n private handleGlobalClick(e: Event) {\n this.messenger.send('craftile.preview.click');\n\n if (!this.active) {\n return;\n }\n\n const blockElement = (e.target as Element).closest('[data-block]') as HTMLElement;\n if (!blockElement) {\n return;\n }\n\n const blockId = blockElement.getAttribute('data-block');\n if (!blockId) {\n return;\n }\n\n const isAlreadySelected = this.currentSelectedBlock === blockElement;\n\n if (!isAlreadySelected) {\n e.preventDefault();\n e.stopImmediatePropagation();\n\n this.currentSelectedBlock = blockElement;\n this.sendSelectedBlockPosition();\n this.trackSelectedBlock();\n }\n }\n\n private sendHoveredBlockPosition() {\n const position = this.computeElementPositioning(this.currentHoveredBlock!);\n\n this.messenger.send('craftile.preview.block-hover', {\n blockRect: position.rect,\n parentRect: position.parentRect,\n scrollTop: position.scrollTop,\n scrollLeft: position.scrollLeft,\n blockId: this.currentHoveredBlock!.dataset.block as string,\n parentFlexDirection: position.parentFlexDirection,\n });\n }\n\n private sendSelectedBlockPosition(updates: boolean = false) {\n if (!this.currentSelectedBlock) {\n return;\n }\n\n const position = this.computeElementPositioning(this.currentSelectedBlock!);\n this.messenger.send(updates ? 'craftile.preview.update-selected-block' : 'craftile.preview.block-select', {\n blockRect: position.rect,\n scrollTop: position.scrollTop,\n scrollLeft: position.scrollLeft,\n blockId: this.currentSelectedBlock!.dataset.block as string,\n });\n }\n\n private trackSelectedBlock() {\n if (!this.currentSelectedBlock) {\n return;\n }\n\n if (this.resizeObserver) {\n this.resizeObserver.disconnect();\n this.resizeObserver = null;\n }\n\n if (this.mutationObserver) {\n this.mutationObserver.disconnect();\n this.mutationObserver = null;\n }\n\n this.resizeObserver = new ResizeObserver(() => {\n if (this.active && this.currentSelectedBlock) {\n this.sendSelectedBlockPosition(true);\n }\n });\n this.resizeObserver.observe(this.currentSelectedBlock);\n\n this.mutationObserver = new MutationObserver(() => {\n if (this.active && this.currentSelectedBlock) {\n this.sendSelectedBlockPosition(true);\n }\n });\n\n this.mutationObserver.observe(this.currentSelectedBlock, {\n attributes: true,\n subtree: false,\n });\n\n // Also observe parent elements that might affect positioning\n let parent = this.currentSelectedBlock.parentElement;\n while (parent) {\n this.mutationObserver.observe(parent, {\n childList: true,\n subtree: false,\n });\n\n if (parent === document.body) {\n break;\n }\n\n parent = parent.parentElement;\n }\n }\n\n private computeElementPositioning(element: HTMLElement) {\n const rect = element.getBoundingClientRect();\n const scrollTop = window.pageYOffset || document.documentElement.scrollTop;\n const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;\n\n const eldestParent = this.findEldestParentBlock(element);\n const parentRect = eldestParent && eldestParent !== element ? eldestParent.getBoundingClientRect() : undefined;\n const parentFlexDirection = this.getElementFlexDirection(element.parentElement);\n\n return {\n rect,\n parentRect,\n scrollTop,\n scrollLeft,\n parentFlexDirection,\n };\n }\n\n private findEldestParentBlock(element: HTMLElement): HTMLElement | null {\n let eldestParent: HTMLElement | null = null;\n let parentElement = element.parentElement;\n\n while (parentElement && parentElement !== document.body) {\n if (parentElement.hasAttribute('data-block')) {\n eldestParent = parentElement;\n }\n parentElement = parentElement.parentElement;\n }\n\n return eldestParent;\n }\n\n private getElementFlexDirection(element: HTMLElement | null): 'row' | 'column' {\n if (!element) {\n return 'column';\n }\n\n const style = window.getComputedStyle(element);\n const flexDirection = style.display.includes('flex') ? style.flexDirection : 'column';\n\n return flexDirection === 'row' || flexDirection === 'row-reverse' ? 'row' : 'column';\n }\n}\n","import type { WindowMessages } from '@craftile/types';\nimport { createParentMessenger, WindowMessenger } from '@craftile/messenger';\nimport { EventBus } from '@craftile/event-bus';\nimport { Inspector } from './inspector';\n\nexport class PreviewClient extends EventBus {\n private messenger: WindowMessenger<WindowMessages>;\n public inspector: Inspector;\n\n constructor() {\n super();\n\n this.messenger = createParentMessenger(window.origin);\n this.inspector = new Inspector(this.messenger);\n\n this.initialize();\n }\n\n private initialize() {\n window.addEventListener('load', () => {\n this.messenger.send('craftile.preview.ready', {});\n setTimeout(() => {\n this.sendPageData();\n }, 0);\n });\n\n this.messenger.registerFallbackHandler((data: any) => {\n const { type, payload } = data;\n this.emit(type, payload);\n });\n }\n\n private sendPageData() {\n const pageDataElement = document.getElementById('page-data');\n\n if (!pageDataElement) {\n return;\n }\n\n try {\n const pageData = JSON.parse(pageDataElement.textContent || '{}');\n this.messenger.send('craftile.preview.page-data', { pageData });\n } catch (error) {\n console.error('Failed to parse page data:', error);\n }\n }\n}\n"],"names":[],"mappings":";;;;;AAKO,MAAM,gBAAsD;AAAA,EAMjE,YAAY,cAAsB,eAAuB,KAAK;AALtD,wDAAe,IAAA;AACf;AACA;AACA;AAGN,SAAK,eAAe;AACpB,SAAK,eAAe;AAEpB,WAAO,iBAAiB,WAAW,KAAK,cAAc,KAAK,IAAI,CAAC;AAAA,EAClE;AAAA,EAEQ,cAAc,OAAqB;AACzC,UAAM,UAAU,MAAM;AAEtB,QAAI,CAAC,QAAQ,MAAM;AACjB;AAAA,IACF;AAEA,UAAM,WAAW,KAAK,SAAS,IAAI,QAAQ,IAAI;AAE/C,QAAI,UAAU;AACZ,eAAS,QAAQ,CAAC,YAAY,QAAQ,QAAQ,SAAS,KAAK,CAAC;AAAA,IAC/D,WAAW,KAAK,iBAAiB;AAC/B,WAAK,gBAAgB,MAAM,MAAM,KAAK;AAAA,IACxC;AAAA,EACF;AAAA,EAEA,KAA+B,MAAS,SAA6B;AACnE,UAAM,UAAqC,EAAE,MAAsB,QAAA;AACnE,SAAK,aAAa,YAAY,SAAS,KAAK,YAAY;AAAA,EAC1D;AAAA,EAEA,OAAiC,MAAS,SAAuE;AAC/G,QAAI,CAAC,KAAK,SAAS,IAAI,IAAI,GAAG;AAC5B,WAAK,SAAS,IAAI,MAAM,CAAA,CAAE;AAAA,IAC5B;AAEA,SAAK,SAAS,IAAI,IAAI,EAAG,KAAK,OAAO;AAErC,WAAO,MAAM;AACX,YAAM,WAAW,KAAK,SAAS,IAAI,IAAI;AACvC,UAAI,UAAU;AACZ,cAAM,QAAQ,SAAS,QAAQ,OAAO;AACtC,YAAI,QAAQ,IAAI;AACd,mBAAS,OAAO,OAAO,CAAC;AAAA,QAC1B;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,wBAAwB,SAAmD;AACzE,SAAK,kBAAkB;AAAA,EACzB;AACF;AAMO,SAAS,sBAAqD,eAAe,KAAK;AACvF,MAAI,OAAO,WAAW,QAAQ;AAC5B,UAAM,IAAI,MAAM,sBAAsB;AAAA,EACxC;AACA,SAAO,IAAI,gBAAmB,OAAO,QAAQ,YAAY;AAC3D;AC7DO,MAAM,SAAwC;AAAA,EAA9C;AACG,yDAAuD,IAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAU/D,GAAsB,OAAU,UAA2C;AACzE,QAAI,CAAC,KAAK,UAAU,IAAI,KAAK,GAAG;AAC9B,WAAK,UAAU,IAAI,OAAO,oBAAI,KAAK;AAAA,IACrC;AAEA,SAAK,UAAU,IAAI,KAAK,EAAG,IAAI,QAAQ;AAEvC,WAAO,MAAM;AACX,WAAK,IAAI,OAAO,QAAQ;AAAA,IAC1B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,IAAuB,OAAU,UAAqC;AACpE,UAAM,iBAAiB,KAAK,UAAU,IAAI,KAAK;AAE/C,QAAI,gBAAgB;AAClB,qBAAe,OAAO,QAAQ;AAE9B,UAAI,eAAe,SAAS,GAAG;AAC7B,aAAK,UAAU,OAAO,KAAK;AAAA,MAC7B;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,KAAwB,OAAU,UAAqC;AACrE,UAAM,cAAc,CAAC,SAAe;AAClC,eAAS,IAAI;AACb,WAAK,IAAI,OAAO,WAAW;AAAA,IAC7B;AAEA,SAAK,GAAG,OAAO,WAAW;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,KAAwB,UAAa,MAA6C;AAChF,UAAM,iBAAiB,KAAK,UAAU,IAAI,KAAK;AAE/C,QAAI,gBAAgB;AAClB,YAAM,OAAO,KAAK,CAAC;AACnB,qBAAe,QAAQ,CAAC,aAAa;AACnC,YAAI;AACF,mBAAS,IAAI;AAAA,QACf,SAAS,OAAO;AACd,kBAAQ,MAAM,gCAAgC,OAAO,KAAK,CAAC,MAAM,KAAK;AAAA,QACxE;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,mBAAsC,OAAiB;AACrD,QAAI,OAAO;AACT,WAAK,UAAU,OAAO,KAAK;AAAA,IAC7B,OAAO;AACL,WAAK,UAAU,MAAA;AAAA,IACjB;AAAA,EACF;AACF;AChGO,MAAM,UAAU;AAAA,EAUrB,YAAY,WAA4C;AAThD,kCAAS;AACT;AACA,+CAA0C;AAC1C,gDAA2C;AAC3C,gDAAuB;AAEvB,0CAAwC;AACxC,4CAA4C;AAGlD,SAAK,YAAY;AAEjB,SAAK,UAAU,OAAO,6BAA6B,MAAM,KAAK,QAAQ;AACtE,SAAK,UAAU,OAAO,8BAA8B,MAAM,KAAK,SAAS;AACxE,SAAK,UAAU,OAAO,2CAA2C,KAAK,yBAAyB,KAAK,IAAI,CAAC;AACzG,SAAK,UAAU,OAAO,2CAA2C,KAAK,yBAAyB,KAAK,IAAI,CAAC;AACzG,SAAK,UAAU,OAAO,gCAAgC,KAAK,wBAAwB,KAAK,IAAI,CAAC;AAC7F,SAAK,UAAU,OAAO,kCAAkC,KAAK,0BAA0B,KAAK,IAAI,CAAC;AAEjG,WAAO,iBAAiB,UAAU,KAAK,aAAa,KAAK,IAAI,GAAG,EAAE,SAAS,MAAM;AACjF,SAAK,0BAAA;AAAA,EACP;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,qBAAqB,SAAiB,YAA+B;AAEnE,QAAI,KAAK,qBAAqB,QAAQ,UAAU,SAAS;AACvD,WAAK,sBAAsB;AAC3B,WAAK,yBAAA;AAAA,IACP;AAGA,QAAI,KAAK,sBAAsB,QAAQ,UAAU,SAAS;AACxD,WAAK,uBAAuB;AAC5B,4BAAsB,MAAM;AAC1B,aAAK,0BAA0B,IAAI;AAAA,MACrC,CAAC;AACD,WAAK,mBAAA;AAAA,IACP;AAAA,EACF;AAAA,EAEA,SAAS;AACP,SAAK,SAAS;AACd,aAAS,KAAK,UAAU,IAAI,2BAA2B;AAGvD,QAAI,KAAK,sBAAsB;AAC7B,WAAK,mBAAA;AAAA,IACP;AAAA,EACF;AAAA,EAEA,UAAU;AACR,SAAK,SAAS;AACd,aAAS,KAAK,UAAU,OAAO,2BAA2B;AAC1D,SAAK,sBAAsB;AAC3B,SAAK,uBAAuB;AAE5B,QAAI,KAAK,gBAAgB;AACvB,WAAK,eAAe,WAAA;AACpB,WAAK,iBAAiB;AAAA,IACxB;AAEA,QAAI,KAAK,kBAAkB;AACzB,WAAK,iBAAiB,WAAA;AACtB,WAAK,mBAAmB;AAAA,IAC1B;AAAA,EACF;AAAA,EAEQ,2BAA2B;AACjC,SAAK,uBAAuB;AAAA,EAC9B;AAAA,EAEQ,yBAAyB,OAA4B;AAC3D,SAAK,uBAAuB;AAE5B,QAAI,CAAC,KAAK,qBAAqB;AAC7B,WAAK,UAAU,KAAK,8BAA8B;AAAA,IACpD;AAAA,EACF;AAAA,EAEQ,wBAAwB,MAA2B;AACzD,UAAM,UAAU,SAAS,cAAc,gBAAgB,KAAK,OAAO,IAAI;AAEvE,QAAI,SAAS;AACX,WAAK,uBAAuB;AAC5B,WAAK,0BAAA;AACL,WAAK,mBAAA;AACL,cAAQ,eAAe,EAAE,UAAU,UAAU,OAAO,WAAW,QAAQ,WAAW;AAAA,IACpF;AAAA,EACF;AAAA,EAEQ,4BAA4B;AAClC,SAAK,uBAAuB;AAE5B,QAAI,KAAK,gBAAgB;AACvB,WAAK,eAAe,WAAA;AACpB,WAAK,iBAAiB;AAAA,IACxB;AAEA,QAAI,KAAK,kBAAkB;AACzB,WAAK,iBAAiB,WAAA;AACtB,WAAK,mBAAmB;AAAA,IAC1B;AAAA,EACF;AAAA,EAEQ,eAAe;AACrB,QAAI,CAAC,KAAK,QAAQ;AAChB;AAAA,IACF;AAEA,QAAI,KAAK,sBAAsB;AAC7B,WAAK,0BAAA;AAAA,IACP;AAEA,QAAI,KAAK,qBAAqB;AAC5B,WAAK,yBAAA;AAAA,IACP;AAAA,EACF;AAAA,EAEQ,4BAA4B;AAClC,aAAS,iBAAiB,aAAa,KAAK,kBAAkB,KAAK,IAAI,CAAC;AACxE,aAAS,iBAAiB,YAAY,KAAK,kBAAkB,KAAK,IAAI,CAAC;AACvE,aAAS,iBAAiB,SAAS,KAAK,kBAAkB,KAAK,IAAI,GAAG,EAAE,SAAS,MAAM;AAAA,EACzF;AAAA,EAEQ,kBAAkB,GAAU;AAClC,QAAI,CAAC,KAAK,QAAQ;AAChB;AAAA,IACF;AAEA,UAAM,eAAgB,EAAE,OAAmB,QAAQ,cAAc;AAEjE,QAAI,CAAC,cAAc;AACjB;AAAA,IACF;AAEA,MAAE,gBAAA;AACF,SAAK,sBAAsB;AAC3B,SAAK,yBAAA;AAAA,EACP;AAAA,EAEQ,kBAAkB,GAAU;AAClC,QAAI,CAAC,KAAK,QAAQ;AAChB;AAAA,IACF;AAEA,UAAM,eAAgB,EAAE,OAAmB,QAAQ,cAAc;AACjE,QAAI,CAAC,cAAc;AACjB;AAAA,IACF;AAGA,QAAI,CAAC,KAAK,sBAAsB;AAC9B,WAAK,sBAAsB;AAC3B,WAAK,UAAU,KAAK,8BAA8B;AAAA,IACpD;AAAA,EACF;AAAA,EAEQ,kBAAkB,GAAU;AAClC,SAAK,UAAU,KAAK,wBAAwB;AAE5C,QAAI,CAAC,KAAK,QAAQ;AAChB;AAAA,IACF;AAEA,UAAM,eAAgB,EAAE,OAAmB,QAAQ,cAAc;AACjE,QAAI,CAAC,cAAc;AACjB;AAAA,IACF;AAEA,UAAM,UAAU,aAAa,aAAa,YAAY;AACtD,QAAI,CAAC,SAAS;AACZ;AAAA,IACF;AAEA,UAAM,oBAAoB,KAAK,yBAAyB;AAExD,QAAI,CAAC,mBAAmB;AACtB,QAAE,eAAA;AACF,QAAE,yBAAA;AAEF,WAAK,uBAAuB;AAC5B,WAAK,0BAAA;AACL,WAAK,mBAAA;AAAA,IACP;AAAA,EACF;AAAA,EAEQ,2BAA2B;AACjC,UAAM,WAAW,KAAK,0BAA0B,KAAK,mBAAoB;AAEzE,SAAK,UAAU,KAAK,gCAAgC;AAAA,MAClD,WAAW,SAAS;AAAA,MACpB,YAAY,SAAS;AAAA,MACrB,WAAW,SAAS;AAAA,MACpB,YAAY,SAAS;AAAA,MACrB,SAAS,KAAK,oBAAqB,QAAQ;AAAA,MAC3C,qBAAqB,SAAS;AAAA,IAAA,CAC/B;AAAA,EACH;AAAA,EAEQ,0BAA0B,UAAmB,OAAO;AAC1D,QAAI,CAAC,KAAK,sBAAsB;AAC9B;AAAA,IACF;AAEA,UAAM,WAAW,KAAK,0BAA0B,KAAK,oBAAqB;AAC1E,SAAK,UAAU,KAAK,UAAU,2CAA2C,iCAAiC;AAAA,MACxG,WAAW,SAAS;AAAA,MACpB,WAAW,SAAS;AAAA,MACpB,YAAY,SAAS;AAAA,MACrB,SAAS,KAAK,qBAAsB,QAAQ;AAAA,IAAA,CAC7C;AAAA,EACH;AAAA,EAEQ,qBAAqB;AAC3B,QAAI,CAAC,KAAK,sBAAsB;AAC9B;AAAA,IACF;AAEA,QAAI,KAAK,gBAAgB;AACvB,WAAK,eAAe,WAAA;AACpB,WAAK,iBAAiB;AAAA,IACxB;AAEA,QAAI,KAAK,kBAAkB;AACzB,WAAK,iBAAiB,WAAA;AACtB,WAAK,mBAAmB;AAAA,IAC1B;AAEA,SAAK,iBAAiB,IAAI,eAAe,MAAM;AAC7C,UAAI,KAAK,UAAU,KAAK,sBAAsB;AAC5C,aAAK,0BAA0B,IAAI;AAAA,MACrC;AAAA,IACF,CAAC;AACD,SAAK,eAAe,QAAQ,KAAK,oBAAoB;AAErD,SAAK,mBAAmB,IAAI,iBAAiB,MAAM;AACjD,UAAI,KAAK,UAAU,KAAK,sBAAsB;AAC5C,aAAK,0BAA0B,IAAI;AAAA,MACrC;AAAA,IACF,CAAC;AAED,SAAK,iBAAiB,QAAQ,KAAK,sBAAsB;AAAA,MACvD,YAAY;AAAA,MACZ,SAAS;AAAA,IAAA,CACV;AAGD,QAAI,SAAS,KAAK,qBAAqB;AACvC,WAAO,QAAQ;AACb,WAAK,iBAAiB,QAAQ,QAAQ;AAAA,QACpC,WAAW;AAAA,QACX,SAAS;AAAA,MAAA,CACV;AAED,UAAI,WAAW,SAAS,MAAM;AAC5B;AAAA,MACF;AAEA,eAAS,OAAO;AAAA,IAClB;AAAA,EACF;AAAA,EAEQ,0BAA0B,SAAsB;AACtD,UAAM,OAAO,QAAQ,sBAAA;AACrB,UAAM,YAAY,OAAO,eAAe,SAAS,gBAAgB;AACjE,UAAM,aAAa,OAAO,eAAe,SAAS,gBAAgB;AAElE,UAAM,eAAe,KAAK,sBAAsB,OAAO;AACvD,UAAM,aAAa,gBAAgB,iBAAiB,UAAU,aAAa,0BAA0B;AACrG,UAAM,sBAAsB,KAAK,wBAAwB,QAAQ,aAAa;AAE9E,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAAA,EAEJ;AAAA,EAEQ,sBAAsB,SAA0C;AACtE,QAAI,eAAmC;AACvC,QAAI,gBAAgB,QAAQ;AAE5B,WAAO,iBAAiB,kBAAkB,SAAS,MAAM;AACvD,UAAI,cAAc,aAAa,YAAY,GAAG;AAC5C,uBAAe;AAAA,MACjB;AACA,sBAAgB,cAAc;AAAA,IAChC;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,wBAAwB,SAA+C;AAC7E,QAAI,CAAC,SAAS;AACZ,aAAO;AAAA,IACT;AAEA,UAAM,QAAQ,OAAO,iBAAiB,OAAO;AAC7C,UAAM,gBAAgB,MAAM,QAAQ,SAAS,MAAM,IAAI,MAAM,gBAAgB;AAE7E,WAAO,kBAAkB,SAAS,kBAAkB,gBAAgB,QAAQ;AAAA,EAC9E;AACF;ACnTO,MAAM,sBAAsB,SAAS;AAAA,EAI1C,cAAc;AACZ,UAAA;AAJM;AACD;AAKL,SAAK,YAAY,sBAAsB,OAAO,MAAM;AACpD,SAAK,YAAY,IAAI,UAAU,KAAK,SAAS;AAE7C,SAAK,WAAA;AAAA,EACP;AAAA,EAEQ,aAAa;AACnB,WAAO,iBAAiB,QAAQ,MAAM;AACpC,WAAK,UAAU,KAAK,0BAA0B,CAAA,CAAE;AAChD,iBAAW,MAAM;AACf,aAAK,aAAA;AAAA,MACP,GAAG,CAAC;AAAA,IACN,CAAC;AAED,SAAK,UAAU,wBAAwB,CAAC,SAAc;AACpD,YAAM,EAAE,MAAM,QAAA,IAAY;AAC1B,WAAK,KAAK,MAAM,OAAO;AAAA,IACzB,CAAC;AAAA,EACH;AAAA,EAEQ,eAAe;AACrB,UAAM,kBAAkB,SAAS,eAAe,WAAW;AAE3D,QAAI,CAAC,iBAAiB;AACpB;AAAA,IACF;AAEA,QAAI;AACF,YAAM,WAAW,KAAK,MAAM,gBAAgB,eAAe,IAAI;AAC/D,WAAK,UAAU,KAAK,8BAA8B,EAAE,UAAU;AAAA,IAChE,SAAS,OAAO;AACd,cAAQ,MAAM,8BAA8B,KAAK;AAAA,IACnD;AAAA,EACF;AACF;;;"}
|
package/dist/index.js
CHANGED
|
@@ -163,7 +163,9 @@ class Inspector {
|
|
|
163
163
|
}
|
|
164
164
|
if (this.currentSelectedBlock?.dataset.block === blockId) {
|
|
165
165
|
this.currentSelectedBlock = newElement;
|
|
166
|
-
|
|
166
|
+
requestAnimationFrame(() => {
|
|
167
|
+
this.sendSelectedBlockPosition(true);
|
|
168
|
+
});
|
|
167
169
|
this.trackSelectedBlock();
|
|
168
170
|
}
|
|
169
171
|
}
|
|
@@ -231,7 +233,7 @@ class Inspector {
|
|
|
231
233
|
setupGlobalEventListeners() {
|
|
232
234
|
document.addEventListener("mouseover", this.handleGlobalHover.bind(this));
|
|
233
235
|
document.addEventListener("mouseout", this.handleGlobalLeave.bind(this));
|
|
234
|
-
document.addEventListener("click", this.handleGlobalClick.bind(this));
|
|
236
|
+
document.addEventListener("click", this.handleGlobalClick.bind(this), { capture: true });
|
|
235
237
|
}
|
|
236
238
|
handleGlobalHover(e) {
|
|
237
239
|
if (!this.active) {
|
|
@@ -267,9 +269,14 @@ class Inspector {
|
|
|
267
269
|
if (!blockElement) {
|
|
268
270
|
return;
|
|
269
271
|
}
|
|
270
|
-
e.stopPropagation();
|
|
271
272
|
const blockId = blockElement.getAttribute("data-block");
|
|
272
|
-
if (blockId) {
|
|
273
|
+
if (!blockId) {
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
const isAlreadySelected = this.currentSelectedBlock === blockElement;
|
|
277
|
+
if (!isAlreadySelected) {
|
|
278
|
+
e.preventDefault();
|
|
279
|
+
e.stopImmediatePropagation();
|
|
273
280
|
this.currentSelectedBlock = blockElement;
|
|
274
281
|
this.sendSelectedBlockPosition();
|
|
275
282
|
this.trackSelectedBlock();
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../messenger/src/index.ts","../../event-bus/src/index.ts","../src/inspector.ts","../src/client.ts"],"sourcesContent":["export interface TypedMessage<T = any> {\n type: string;\n payload: T | undefined;\n}\n\nexport class WindowMessenger<Messages extends Record<string, any>> {\n private handlers = new Map<keyof Messages, Function[]>();\n private targetWindow: Window;\n private targetOrigin: string;\n private fallbackHandler?: (data: any, event: MessageEvent) => void;\n\n constructor(targetWindow: Window, targetOrigin: string = '*') {\n this.targetWindow = targetWindow;\n this.targetOrigin = targetOrigin;\n\n window.addEventListener('message', this.handleMessage.bind(this));\n }\n\n private handleMessage(event: MessageEvent) {\n const message = event.data as TypedMessage;\n\n if (!message.type) {\n return;\n }\n\n const handlers = this.handlers.get(message.type);\n\n if (handlers) {\n handlers.forEach((handler) => handler(message.payload, event));\n } else if (this.fallbackHandler) {\n this.fallbackHandler(event.data, event);\n }\n }\n\n send<K extends keyof Messages>(type: K, payload?: Messages[K]): void {\n const message: TypedMessage<Messages[K]> = { type: type as string, payload };\n this.targetWindow.postMessage(message, this.targetOrigin);\n }\n\n listen<K extends keyof Messages>(type: K, handler: (data: Messages[K], event: MessageEvent) => void): () => void {\n if (!this.handlers.has(type)) {\n this.handlers.set(type, []);\n }\n\n this.handlers.get(type)!.push(handler);\n\n return () => {\n const handlers = this.handlers.get(type);\n if (handlers) {\n const index = handlers.indexOf(handler);\n if (index > -1) {\n handlers.splice(index, 1);\n }\n }\n };\n }\n\n registerFallbackHandler(handler: (data: any, event: MessageEvent) => void) {\n this.fallbackHandler = handler;\n }\n}\n\nexport function createIframeMessenger<T extends Record<string, any>>(iframe: HTMLIFrameElement, targetOrigin = '*') {\n return new WindowMessenger<T>(iframe.contentWindow!, targetOrigin);\n}\n\nexport function createParentMessenger<T extends Record<string, any>>(targetOrigin = '*') {\n if (window.parent === window) {\n throw new Error('Not inside an iframe');\n }\n return new WindowMessenger<T>(window.parent, targetOrigin);\n}\n","export type EventListener<T = any> = (data: T) => void;\nexport type EventMap = {\n [event: string]: any;\n};\n\n/**\n * Type-safe EventBus with generic event map support\n *\n * @template T Event map interface that defines the events and their data types\n */\nexport class EventBus<T extends EventMap = EventMap> {\n private listeners: Map<keyof T, Set<EventListener<any>>> = new Map();\n\n /**\n * Add an event listener\n *\n * @param event Event name\n * @param listener Event listener function\n *\n * @returns Cleanup function to remove the listener\n */\n on<K extends keyof T>(event: K, listener: EventListener<T[K]>): () => void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n\n this.listeners.get(event)!.add(listener);\n\n return () => {\n this.off(event, listener);\n };\n }\n\n /**\n * Remove an event listener\n *\n * @param event Event name\n * @param listener Event listener function to remove\n */\n off<K extends keyof T>(event: K, listener: EventListener<T[K]>): void {\n const eventListeners = this.listeners.get(event);\n\n if (eventListeners) {\n eventListeners.delete(listener);\n\n if (eventListeners.size === 0) {\n this.listeners.delete(event);\n }\n }\n }\n\n /**\n * Add a one-time event listener\n *\n * @param event Event name\n * @param listener Event listener function\n */\n once<K extends keyof T>(event: K, listener: EventListener<T[K]>): void {\n const onceWrapper = (data: T[K]) => {\n listener(data);\n this.off(event, onceWrapper);\n };\n\n this.on(event, onceWrapper);\n }\n\n /**\n * Emit an event\n *\n * @param event Event name\n * @param args Event data (optional, depending on event type)\n */\n emit<K extends keyof T>(event: K, ...args: T[K] extends void ? [] : [T[K]]): void {\n const eventListeners = this.listeners.get(event);\n\n if (eventListeners) {\n const data = args[0];\n eventListeners.forEach((listener) => {\n try {\n listener(data);\n } catch (error) {\n console.error(`Error in event listener for '${String(event)}':`, error);\n }\n });\n }\n }\n\n /**\n * Remove all listeners for an event, or all listeners if no event specified\n *\n * @param event Optional event name. If not provided, removes all listeners\n */\n removeAllListeners<K extends keyof T>(event?: K): void {\n if (event) {\n this.listeners.delete(event);\n } else {\n this.listeners.clear();\n }\n }\n}\n","import type { WindowMessenger } from '@craftile/messenger';\nimport type { WindowMessages } from '@craftile/types';\n\nexport class Inspector {\n private active = true;\n private messenger: WindowMessenger<WindowMessages>;\n private currentHoveredBlock: HTMLElement | null = null;\n private currentSelectedBlock: HTMLElement | null = null;\n private overlayButtonHovered = false;\n\n private resizeObserver: ResizeObserver | null = null;\n private mutationObserver: MutationObserver | null = null;\n\n constructor(messenger: WindowMessenger<WindowMessages>) {\n this.messenger = messenger;\n\n this.messenger.listen('craftile.inspector.enable', () => this.enable());\n this.messenger.listen('craftile.inspector.disable', () => this.disable());\n this.messenger.listen('craftile.inspector.overlay-button-enter', this.handleOverlayButtonEnter.bind(this));\n this.messenger.listen('craftile.inspector.overlay-button-leave', this.handleOverlayButtonLeave.bind(this));\n this.messenger.listen('craftile.editor.select-block', this.handleEditorSelectBlock.bind(this));\n this.messenger.listen('craftile.editor.deselect-block', this.handleEditorDeselectBlock.bind(this));\n\n window.addEventListener('scroll', this.handleScroll.bind(this), { passive: true });\n this.setupGlobalEventListeners();\n }\n\n /**\n * Update the tracked element reference when a block's DOM element changes.\n * This is needed when the root tag of a block changes during an update.\n */\n updateTrackedElement(blockId: string, newElement: HTMLElement): void {\n // Update hovered block if it matches\n if (this.currentHoveredBlock?.dataset.block === blockId) {\n this.currentHoveredBlock = newElement;\n this.sendHoveredBlockPosition();\n }\n\n // Update selected block if it matches and re-track it\n if (this.currentSelectedBlock?.dataset.block === blockId) {\n this.currentSelectedBlock = newElement;\n this.sendSelectedBlockPosition(true);\n this.trackSelectedBlock();\n }\n }\n\n enable() {\n this.active = true;\n document.body.classList.add('craftile-inspector-active');\n\n // Re-track selected block if it exists\n if (this.currentSelectedBlock) {\n this.trackSelectedBlock();\n }\n }\n\n disable() {\n this.active = false;\n document.body.classList.remove('craftile-inspector-active');\n this.currentHoveredBlock = null;\n this.overlayButtonHovered = false;\n\n if (this.resizeObserver) {\n this.resizeObserver.disconnect();\n this.resizeObserver = null;\n }\n\n if (this.mutationObserver) {\n this.mutationObserver.disconnect();\n this.mutationObserver = null;\n }\n }\n\n private handleOverlayButtonEnter() {\n this.overlayButtonHovered = true;\n }\n\n private handleOverlayButtonLeave(_data: { blockId: string }) {\n this.overlayButtonHovered = false;\n\n if (!this.currentHoveredBlock) {\n this.messenger.send('craftile.preview.block-leave');\n }\n }\n\n private handleEditorSelectBlock(data: { blockId: string }) {\n const element = document.querySelector(`[data-block=\"${data.blockId}\"]`) as HTMLElement;\n\n if (element) {\n this.currentSelectedBlock = element;\n this.sendSelectedBlockPosition();\n this.trackSelectedBlock();\n element.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'nearest' });\n }\n }\n\n private handleEditorDeselectBlock() {\n this.currentSelectedBlock = null;\n\n if (this.resizeObserver) {\n this.resizeObserver.disconnect();\n this.resizeObserver = null;\n }\n\n if (this.mutationObserver) {\n this.mutationObserver.disconnect();\n this.mutationObserver = null;\n }\n }\n\n private handleScroll() {\n if (!this.active) {\n return;\n }\n\n if (this.currentSelectedBlock) {\n this.sendSelectedBlockPosition();\n }\n\n if (this.currentHoveredBlock) {\n this.sendHoveredBlockPosition();\n }\n }\n\n private setupGlobalEventListeners() {\n document.addEventListener('mouseover', this.handleGlobalHover.bind(this));\n document.addEventListener('mouseout', this.handleGlobalLeave.bind(this));\n document.addEventListener('click', this.handleGlobalClick.bind(this));\n }\n\n private handleGlobalHover(e: Event) {\n if (!this.active) {\n return;\n }\n\n const blockElement = (e.target as Element).closest('[data-block]') as HTMLElement;\n\n if (!blockElement) {\n return;\n }\n\n e.stopPropagation();\n this.currentHoveredBlock = blockElement;\n this.sendHoveredBlockPosition();\n }\n\n private handleGlobalLeave(e: Event) {\n if (!this.active) {\n return;\n }\n\n const blockElement = (e.target as Element).closest('[data-block]') as HTMLElement;\n if (!blockElement) {\n return;\n }\n\n // Only clear overlay if button is not being hovered\n if (!this.overlayButtonHovered) {\n this.currentHoveredBlock = null;\n this.messenger.send('craftile.preview.block-leave');\n }\n }\n\n private handleGlobalClick(e: Event) {\n this.messenger.send('craftile.preview.click');\n\n if (!this.active) {\n return;\n }\n\n const blockElement = (e.target as Element).closest('[data-block]') as HTMLElement;\n if (!blockElement) {\n return;\n }\n\n e.stopPropagation();\n\n const blockId = blockElement.getAttribute('data-block');\n\n if (blockId) {\n this.currentSelectedBlock = blockElement;\n this.sendSelectedBlockPosition();\n this.trackSelectedBlock();\n }\n }\n\n private sendHoveredBlockPosition() {\n const position = this.computeElementPositioning(this.currentHoveredBlock!);\n\n this.messenger.send('craftile.preview.block-hover', {\n blockRect: position.rect,\n parentRect: position.parentRect,\n scrollTop: position.scrollTop,\n scrollLeft: position.scrollLeft,\n blockId: this.currentHoveredBlock!.dataset.block as string,\n parentFlexDirection: position.parentFlexDirection,\n });\n }\n\n private sendSelectedBlockPosition(updates: boolean = false) {\n if (!this.currentSelectedBlock) {\n return;\n }\n\n const position = this.computeElementPositioning(this.currentSelectedBlock!);\n this.messenger.send(updates ? 'craftile.preview.update-selected-block' : 'craftile.preview.block-select', {\n blockRect: position.rect,\n scrollTop: position.scrollTop,\n scrollLeft: position.scrollLeft,\n blockId: this.currentSelectedBlock!.dataset.block as string,\n });\n }\n\n private trackSelectedBlock() {\n if (!this.currentSelectedBlock) {\n return;\n }\n\n if (this.resizeObserver) {\n this.resizeObserver.disconnect();\n this.resizeObserver = null;\n }\n\n if (this.mutationObserver) {\n this.mutationObserver.disconnect();\n this.mutationObserver = null;\n }\n\n this.resizeObserver = new ResizeObserver(() => {\n if (this.active && this.currentSelectedBlock) {\n this.sendSelectedBlockPosition(true);\n }\n });\n this.resizeObserver.observe(this.currentSelectedBlock);\n\n this.mutationObserver = new MutationObserver(() => {\n if (this.active && this.currentSelectedBlock) {\n this.sendSelectedBlockPosition(true);\n }\n });\n\n this.mutationObserver.observe(this.currentSelectedBlock, {\n attributes: true,\n subtree: false,\n });\n\n // Also observe parent elements that might affect positioning\n let parent = this.currentSelectedBlock.parentElement;\n while (parent) {\n this.mutationObserver.observe(parent, {\n childList: true,\n subtree: false,\n });\n\n if (parent === document.body) {\n break;\n }\n\n parent = parent.parentElement;\n }\n }\n\n private computeElementPositioning(element: HTMLElement) {\n const rect = element.getBoundingClientRect();\n const scrollTop = window.pageYOffset || document.documentElement.scrollTop;\n const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;\n\n const eldestParent = this.findEldestParentBlock(element);\n const parentRect = eldestParent && eldestParent !== element ? eldestParent.getBoundingClientRect() : undefined;\n const parentFlexDirection = this.getElementFlexDirection(element.parentElement);\n\n return {\n rect,\n parentRect,\n scrollTop,\n scrollLeft,\n parentFlexDirection,\n };\n }\n\n private findEldestParentBlock(element: HTMLElement): HTMLElement | null {\n let eldestParent: HTMLElement | null = null;\n let parentElement = element.parentElement;\n\n while (parentElement && parentElement !== document.body) {\n if (parentElement.hasAttribute('data-block')) {\n eldestParent = parentElement;\n }\n parentElement = parentElement.parentElement;\n }\n\n return eldestParent;\n }\n\n private getElementFlexDirection(element: HTMLElement | null): 'row' | 'column' {\n if (!element) {\n return 'column';\n }\n\n const style = window.getComputedStyle(element);\n const flexDirection = style.display.includes('flex') ? style.flexDirection : 'column';\n\n return flexDirection === 'row' || flexDirection === 'row-reverse' ? 'row' : 'column';\n }\n}\n","import type { WindowMessages } from '@craftile/types';\nimport { createParentMessenger, WindowMessenger } from '@craftile/messenger';\nimport { EventBus } from '@craftile/event-bus';\nimport { Inspector } from './inspector';\n\nexport class PreviewClient extends EventBus {\n private messenger: WindowMessenger<WindowMessages>;\n public inspector: Inspector;\n\n constructor() {\n super();\n\n this.messenger = createParentMessenger(window.origin);\n this.inspector = new Inspector(this.messenger);\n\n this.initialize();\n }\n\n private initialize() {\n window.addEventListener('load', () => {\n this.messenger.send('craftile.preview.ready', {});\n setTimeout(() => {\n this.sendPageData();\n }, 0);\n });\n\n this.messenger.registerFallbackHandler((data: any) => {\n const { type, payload } = data;\n this.emit(type, payload);\n });\n }\n\n private sendPageData() {\n const pageDataElement = document.getElementById('page-data');\n\n if (!pageDataElement) {\n return;\n }\n\n try {\n const pageData = JSON.parse(pageDataElement.textContent || '{}');\n this.messenger.send('craftile.preview.page-data', { pageData });\n } catch (error) {\n console.error('Failed to parse page data:', error);\n }\n }\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../messenger/src/index.ts","../../event-bus/src/index.ts","../src/inspector.ts","../src/client.ts"],"sourcesContent":["export interface TypedMessage<T = any> {\n type: string;\n payload: T | undefined;\n}\n\nexport class WindowMessenger<Messages extends Record<string, any>> {\n private handlers = new Map<keyof Messages, Function[]>();\n private targetWindow: Window;\n private targetOrigin: string;\n private fallbackHandler?: (data: any, event: MessageEvent) => void;\n\n constructor(targetWindow: Window, targetOrigin: string = '*') {\n this.targetWindow = targetWindow;\n this.targetOrigin = targetOrigin;\n\n window.addEventListener('message', this.handleMessage.bind(this));\n }\n\n private handleMessage(event: MessageEvent) {\n const message = event.data as TypedMessage;\n\n if (!message.type) {\n return;\n }\n\n const handlers = this.handlers.get(message.type);\n\n if (handlers) {\n handlers.forEach((handler) => handler(message.payload, event));\n } else if (this.fallbackHandler) {\n this.fallbackHandler(event.data, event);\n }\n }\n\n send<K extends keyof Messages>(type: K, payload?: Messages[K]): void {\n const message: TypedMessage<Messages[K]> = { type: type as string, payload };\n this.targetWindow.postMessage(message, this.targetOrigin);\n }\n\n listen<K extends keyof Messages>(type: K, handler: (data: Messages[K], event: MessageEvent) => void): () => void {\n if (!this.handlers.has(type)) {\n this.handlers.set(type, []);\n }\n\n this.handlers.get(type)!.push(handler);\n\n return () => {\n const handlers = this.handlers.get(type);\n if (handlers) {\n const index = handlers.indexOf(handler);\n if (index > -1) {\n handlers.splice(index, 1);\n }\n }\n };\n }\n\n registerFallbackHandler(handler: (data: any, event: MessageEvent) => void) {\n this.fallbackHandler = handler;\n }\n}\n\nexport function createIframeMessenger<T extends Record<string, any>>(iframe: HTMLIFrameElement, targetOrigin = '*') {\n return new WindowMessenger<T>(iframe.contentWindow!, targetOrigin);\n}\n\nexport function createParentMessenger<T extends Record<string, any>>(targetOrigin = '*') {\n if (window.parent === window) {\n throw new Error('Not inside an iframe');\n }\n return new WindowMessenger<T>(window.parent, targetOrigin);\n}\n","export type EventListener<T = any> = (data: T) => void;\nexport type EventMap = {\n [event: string]: any;\n};\n\n/**\n * Type-safe EventBus with generic event map support\n *\n * @template T Event map interface that defines the events and their data types\n */\nexport class EventBus<T extends EventMap = EventMap> {\n private listeners: Map<keyof T, Set<EventListener<any>>> = new Map();\n\n /**\n * Add an event listener\n *\n * @param event Event name\n * @param listener Event listener function\n *\n * @returns Cleanup function to remove the listener\n */\n on<K extends keyof T>(event: K, listener: EventListener<T[K]>): () => void {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, new Set());\n }\n\n this.listeners.get(event)!.add(listener);\n\n return () => {\n this.off(event, listener);\n };\n }\n\n /**\n * Remove an event listener\n *\n * @param event Event name\n * @param listener Event listener function to remove\n */\n off<K extends keyof T>(event: K, listener: EventListener<T[K]>): void {\n const eventListeners = this.listeners.get(event);\n\n if (eventListeners) {\n eventListeners.delete(listener);\n\n if (eventListeners.size === 0) {\n this.listeners.delete(event);\n }\n }\n }\n\n /**\n * Add a one-time event listener\n *\n * @param event Event name\n * @param listener Event listener function\n */\n once<K extends keyof T>(event: K, listener: EventListener<T[K]>): void {\n const onceWrapper = (data: T[K]) => {\n listener(data);\n this.off(event, onceWrapper);\n };\n\n this.on(event, onceWrapper);\n }\n\n /**\n * Emit an event\n *\n * @param event Event name\n * @param args Event data (optional, depending on event type)\n */\n emit<K extends keyof T>(event: K, ...args: T[K] extends void ? [] : [T[K]]): void {\n const eventListeners = this.listeners.get(event);\n\n if (eventListeners) {\n const data = args[0];\n eventListeners.forEach((listener) => {\n try {\n listener(data);\n } catch (error) {\n console.error(`Error in event listener for '${String(event)}':`, error);\n }\n });\n }\n }\n\n /**\n * Remove all listeners for an event, or all listeners if no event specified\n *\n * @param event Optional event name. If not provided, removes all listeners\n */\n removeAllListeners<K extends keyof T>(event?: K): void {\n if (event) {\n this.listeners.delete(event);\n } else {\n this.listeners.clear();\n }\n }\n}\n","import type { WindowMessenger } from '@craftile/messenger';\nimport type { WindowMessages } from '@craftile/types';\n\nexport class Inspector {\n private active = true;\n private messenger: WindowMessenger<WindowMessages>;\n private currentHoveredBlock: HTMLElement | null = null;\n private currentSelectedBlock: HTMLElement | null = null;\n private overlayButtonHovered = false;\n\n private resizeObserver: ResizeObserver | null = null;\n private mutationObserver: MutationObserver | null = null;\n\n constructor(messenger: WindowMessenger<WindowMessages>) {\n this.messenger = messenger;\n\n this.messenger.listen('craftile.inspector.enable', () => this.enable());\n this.messenger.listen('craftile.inspector.disable', () => this.disable());\n this.messenger.listen('craftile.inspector.overlay-button-enter', this.handleOverlayButtonEnter.bind(this));\n this.messenger.listen('craftile.inspector.overlay-button-leave', this.handleOverlayButtonLeave.bind(this));\n this.messenger.listen('craftile.editor.select-block', this.handleEditorSelectBlock.bind(this));\n this.messenger.listen('craftile.editor.deselect-block', this.handleEditorDeselectBlock.bind(this));\n\n window.addEventListener('scroll', this.handleScroll.bind(this), { passive: true });\n this.setupGlobalEventListeners();\n }\n\n /**\n * Update the tracked element reference when a block's DOM element changes.\n * This is needed when the root tag of a block changes during an update.\n */\n updateTrackedElement(blockId: string, newElement: HTMLElement): void {\n // Update hovered block if it matches\n if (this.currentHoveredBlock?.dataset.block === blockId) {\n this.currentHoveredBlock = newElement;\n this.sendHoveredBlockPosition();\n }\n\n // Update selected block if it matches and re-track it\n if (this.currentSelectedBlock?.dataset.block === blockId) {\n this.currentSelectedBlock = newElement;\n requestAnimationFrame(() => {\n this.sendSelectedBlockPosition(true);\n });\n this.trackSelectedBlock();\n }\n }\n\n enable() {\n this.active = true;\n document.body.classList.add('craftile-inspector-active');\n\n // Re-track selected block if it exists\n if (this.currentSelectedBlock) {\n this.trackSelectedBlock();\n }\n }\n\n disable() {\n this.active = false;\n document.body.classList.remove('craftile-inspector-active');\n this.currentHoveredBlock = null;\n this.overlayButtonHovered = false;\n\n if (this.resizeObserver) {\n this.resizeObserver.disconnect();\n this.resizeObserver = null;\n }\n\n if (this.mutationObserver) {\n this.mutationObserver.disconnect();\n this.mutationObserver = null;\n }\n }\n\n private handleOverlayButtonEnter() {\n this.overlayButtonHovered = true;\n }\n\n private handleOverlayButtonLeave(_data: { blockId: string }) {\n this.overlayButtonHovered = false;\n\n if (!this.currentHoveredBlock) {\n this.messenger.send('craftile.preview.block-leave');\n }\n }\n\n private handleEditorSelectBlock(data: { blockId: string }) {\n const element = document.querySelector(`[data-block=\"${data.blockId}\"]`) as HTMLElement;\n\n if (element) {\n this.currentSelectedBlock = element;\n this.sendSelectedBlockPosition();\n this.trackSelectedBlock();\n element.scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'nearest' });\n }\n }\n\n private handleEditorDeselectBlock() {\n this.currentSelectedBlock = null;\n\n if (this.resizeObserver) {\n this.resizeObserver.disconnect();\n this.resizeObserver = null;\n }\n\n if (this.mutationObserver) {\n this.mutationObserver.disconnect();\n this.mutationObserver = null;\n }\n }\n\n private handleScroll() {\n if (!this.active) {\n return;\n }\n\n if (this.currentSelectedBlock) {\n this.sendSelectedBlockPosition();\n }\n\n if (this.currentHoveredBlock) {\n this.sendHoveredBlockPosition();\n }\n }\n\n private setupGlobalEventListeners() {\n document.addEventListener('mouseover', this.handleGlobalHover.bind(this));\n document.addEventListener('mouseout', this.handleGlobalLeave.bind(this));\n document.addEventListener('click', this.handleGlobalClick.bind(this), { capture: true });\n }\n\n private handleGlobalHover(e: Event) {\n if (!this.active) {\n return;\n }\n\n const blockElement = (e.target as Element).closest('[data-block]') as HTMLElement;\n\n if (!blockElement) {\n return;\n }\n\n e.stopPropagation();\n this.currentHoveredBlock = blockElement;\n this.sendHoveredBlockPosition();\n }\n\n private handleGlobalLeave(e: Event) {\n if (!this.active) {\n return;\n }\n\n const blockElement = (e.target as Element).closest('[data-block]') as HTMLElement;\n if (!blockElement) {\n return;\n }\n\n // Only clear overlay if button is not being hovered\n if (!this.overlayButtonHovered) {\n this.currentHoveredBlock = null;\n this.messenger.send('craftile.preview.block-leave');\n }\n }\n\n private handleGlobalClick(e: Event) {\n this.messenger.send('craftile.preview.click');\n\n if (!this.active) {\n return;\n }\n\n const blockElement = (e.target as Element).closest('[data-block]') as HTMLElement;\n if (!blockElement) {\n return;\n }\n\n const blockId = blockElement.getAttribute('data-block');\n if (!blockId) {\n return;\n }\n\n const isAlreadySelected = this.currentSelectedBlock === blockElement;\n\n if (!isAlreadySelected) {\n e.preventDefault();\n e.stopImmediatePropagation();\n\n this.currentSelectedBlock = blockElement;\n this.sendSelectedBlockPosition();\n this.trackSelectedBlock();\n }\n }\n\n private sendHoveredBlockPosition() {\n const position = this.computeElementPositioning(this.currentHoveredBlock!);\n\n this.messenger.send('craftile.preview.block-hover', {\n blockRect: position.rect,\n parentRect: position.parentRect,\n scrollTop: position.scrollTop,\n scrollLeft: position.scrollLeft,\n blockId: this.currentHoveredBlock!.dataset.block as string,\n parentFlexDirection: position.parentFlexDirection,\n });\n }\n\n private sendSelectedBlockPosition(updates: boolean = false) {\n if (!this.currentSelectedBlock) {\n return;\n }\n\n const position = this.computeElementPositioning(this.currentSelectedBlock!);\n this.messenger.send(updates ? 'craftile.preview.update-selected-block' : 'craftile.preview.block-select', {\n blockRect: position.rect,\n scrollTop: position.scrollTop,\n scrollLeft: position.scrollLeft,\n blockId: this.currentSelectedBlock!.dataset.block as string,\n });\n }\n\n private trackSelectedBlock() {\n if (!this.currentSelectedBlock) {\n return;\n }\n\n if (this.resizeObserver) {\n this.resizeObserver.disconnect();\n this.resizeObserver = null;\n }\n\n if (this.mutationObserver) {\n this.mutationObserver.disconnect();\n this.mutationObserver = null;\n }\n\n this.resizeObserver = new ResizeObserver(() => {\n if (this.active && this.currentSelectedBlock) {\n this.sendSelectedBlockPosition(true);\n }\n });\n this.resizeObserver.observe(this.currentSelectedBlock);\n\n this.mutationObserver = new MutationObserver(() => {\n if (this.active && this.currentSelectedBlock) {\n this.sendSelectedBlockPosition(true);\n }\n });\n\n this.mutationObserver.observe(this.currentSelectedBlock, {\n attributes: true,\n subtree: false,\n });\n\n // Also observe parent elements that might affect positioning\n let parent = this.currentSelectedBlock.parentElement;\n while (parent) {\n this.mutationObserver.observe(parent, {\n childList: true,\n subtree: false,\n });\n\n if (parent === document.body) {\n break;\n }\n\n parent = parent.parentElement;\n }\n }\n\n private computeElementPositioning(element: HTMLElement) {\n const rect = element.getBoundingClientRect();\n const scrollTop = window.pageYOffset || document.documentElement.scrollTop;\n const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;\n\n const eldestParent = this.findEldestParentBlock(element);\n const parentRect = eldestParent && eldestParent !== element ? eldestParent.getBoundingClientRect() : undefined;\n const parentFlexDirection = this.getElementFlexDirection(element.parentElement);\n\n return {\n rect,\n parentRect,\n scrollTop,\n scrollLeft,\n parentFlexDirection,\n };\n }\n\n private findEldestParentBlock(element: HTMLElement): HTMLElement | null {\n let eldestParent: HTMLElement | null = null;\n let parentElement = element.parentElement;\n\n while (parentElement && parentElement !== document.body) {\n if (parentElement.hasAttribute('data-block')) {\n eldestParent = parentElement;\n }\n parentElement = parentElement.parentElement;\n }\n\n return eldestParent;\n }\n\n private getElementFlexDirection(element: HTMLElement | null): 'row' | 'column' {\n if (!element) {\n return 'column';\n }\n\n const style = window.getComputedStyle(element);\n const flexDirection = style.display.includes('flex') ? style.flexDirection : 'column';\n\n return flexDirection === 'row' || flexDirection === 'row-reverse' ? 'row' : 'column';\n }\n}\n","import type { WindowMessages } from '@craftile/types';\nimport { createParentMessenger, WindowMessenger } from '@craftile/messenger';\nimport { EventBus } from '@craftile/event-bus';\nimport { Inspector } from './inspector';\n\nexport class PreviewClient extends EventBus {\n private messenger: WindowMessenger<WindowMessages>;\n public inspector: Inspector;\n\n constructor() {\n super();\n\n this.messenger = createParentMessenger(window.origin);\n this.inspector = new Inspector(this.messenger);\n\n this.initialize();\n }\n\n private initialize() {\n window.addEventListener('load', () => {\n this.messenger.send('craftile.preview.ready', {});\n setTimeout(() => {\n this.sendPageData();\n }, 0);\n });\n\n this.messenger.registerFallbackHandler((data: any) => {\n const { type, payload } = data;\n this.emit(type, payload);\n });\n }\n\n private sendPageData() {\n const pageDataElement = document.getElementById('page-data');\n\n if (!pageDataElement) {\n return;\n }\n\n try {\n const pageData = JSON.parse(pageDataElement.textContent || '{}');\n this.messenger.send('craftile.preview.page-data', { pageData });\n } catch (error) {\n console.error('Failed to parse page data:', error);\n }\n }\n}\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@craftile/preview-client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "Browser client for Craftile editor preview iframe functionality",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"craftile",
|
|
@@ -35,9 +35,9 @@
|
|
|
35
35
|
"typescript": "^5.8.4",
|
|
36
36
|
"vite": "^7.0.0",
|
|
37
37
|
"vite-plugin-dts": "^4.3.0",
|
|
38
|
-
"@craftile/event-bus": "0.
|
|
39
|
-
"@craftile/messenger": "0.
|
|
40
|
-
"@craftile/types": "0.
|
|
38
|
+
"@craftile/event-bus": "0.9.0",
|
|
39
|
+
"@craftile/messenger": "0.9.0",
|
|
40
|
+
"@craftile/types": "0.9.0"
|
|
41
41
|
},
|
|
42
42
|
"repository": {
|
|
43
43
|
"type": "git",
|