Files

1 line
40 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{"version":3,"file":"index.cjs","names":[],"sources":["../src/lib/overlay-manager.ts","../src/lib/overlay-element.ts","../src/lib/editable-element.ts","../src/lib/editable-store.ts","../src/lib/directus-frame.ts","../src/lib/page-manager.ts","../src/index.ts"],"sourcesContent":["export class OverlayManager {\n\tprivate static readonly CSS_VAR_Z_INDEX = '--directus-visual-editing--overlay--z-index';\n\tprivate static readonly CSS_VAR_BORDER_SPACING = '--directus-visual-editing--rect--border-spacing';\n\tprivate static readonly CSS_VAR_BORDER_WIDTH = '--directus-visual-editing--rect--border-width';\n\tprivate static readonly CSS_VAR_BORDER_COLOR = '--directus-visual-editing--rect--border-color';\n\tprivate static readonly CSS_VAR_BORDER_RADIUS = '--directus-visual-editing--rect--border-radius';\n\tprivate static readonly CSS_VAR_HOVER_OPACITY = '--directus-visual-editing--rect-hover--opacity';\n\tprivate static readonly CSS_VAR_HIGHLIGHT_OPACITY = '--directus-visual-editing--rect-highlight--opacity';\n\tprivate static readonly CSS_VAR_ACTIONS_GAP = '--directus-visual-editing--actions--gap';\n\tprivate static readonly CSS_VAR_BUTTON_WIDTH = '--directus-visual-editing--edit-btn--width';\n\tprivate static readonly CSS_VAR_BUTTON_HEIGHT = '--directus-visual-editing--edit-btn--height';\n\tprivate static readonly CSS_VAR_BUTTON_RADIUS = '--directus-visual-editing--edit-btn--radius';\n\tprivate static readonly CSS_VAR_EDIT_BUTTON_BG_COLOR = '--directus-visual-editing--edit-btn--bg-color';\n\tprivate static readonly CSS_VAR_EDIT_BUTTON_ICON_BG_IMAGE = '--directus-visual-editing--edit-btn--icon-bg-image';\n\tprivate static readonly CSS_VAR_EDIT_BUTTON_ICON_BG_SIZE = '--directus-visual-editing--edit-btn--icon-bg-size';\n\tprivate static readonly CSS_VAR_AI_BUTTON_BG_COLOR = '--directus-visual-editing--ai-btn--bg-color';\n\tprivate static readonly CSS_VAR_AI_BUTTON_ICON_BG_IMAGE = '--directus-visual-editing--ai-btn--icon-bg-image';\n\tprivate static readonly CSS_VAR_AI_BUTTON_ICON_BG_SIZE = '--directus-visual-editing--ai-btn--icon-bg-size';\n\n\t// For icons use https://fonts.google.com/icons?icon.set=Material+Icons&icon.color=%23ffffff\n\tprivate static readonly ICON_EDIT = `url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 0 24 24\" width=\"24px\" fill=\"%23ffffff\"><path d=\"M0 0h24v24H0V0z\" fill=\"none\"/><path d=\"M14.06 9.02l.92.92L5.92 19H5v-.92l9.06-9.06M17.66 3c-.25 0-.51.1-.7.29l-1.83 1.83 3.75 3.75 1.83-1.83c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.2-.2-.45-.29-.71-.29zm-3.6 3.19L3 17.25V21h3.75L17.81 9.94l-3.75-3.75z\"/></svg>')`;\n\tprivate static readonly ICON_AI = `url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 0 24 24\" width=\"24px\"><path fill=\"%23ffffff\" d=\"M10 14.175L11 12l2.175-1L11 10l-1-2.175L9 10l-2.175 1L9 12l1 2.175ZM10 19l-2.5-5.5L2 11l5.5-2.5L10 3l2.5 5.5L18 11l-5.5 2.5L10 19Zm8 2l-1.25-2.75L14 17l2.75-1.25L18 13l1.25 2.75L22 17l-2.75 1.25L18 21Zm-8-10Z\"/></svg>')`;\n\n\tprivate static readonly OVERLAY_ID = 'directus-visual-editing';\n\tprivate static readonly STYLE_ID = 'directus-visual-editing-style';\n\n\tstatic readonly CONTAINER_RECT_CLASS_NAME = 'directus-visual-editing-overlay';\n\tstatic readonly RECT_CLASS_NAME = 'directus-visual-editing-rect';\n\tstatic readonly RECT_HIGHLIGHT_CLASS_NAME = 'directus-visual-editing-rect-highlight';\n\tstatic readonly RECT_HIGHLIGHT_ACTIVE_CLASS_NAME = 'directus-visual-editing-rect-highlight-active';\n\tstatic readonly RECT_PARENT_HOVER_CLASS_NAME = 'directus-visual-editing-rect-parent-hover';\n\tstatic readonly RECT_HOVER_CLASS_NAME = 'directus-visual-editing-rect-hover';\n\tstatic readonly RECT_INNER_CLASS_NAME = 'directus-visual-editing-rect-inner';\n\tstatic readonly RECT_BUTTON_CLASS_NAME = 'directus-visual-editing-button';\n\tstatic readonly RECT_EDIT_BUTTON_CLASS_NAME = 'directus-visual-editing-edit-button';\n\tstatic readonly RECT_AI_BUTTON_CLASS_NAME = 'directus-visual-editing-ai-button';\n\n\tstatic getGlobalOverlay(): HTMLElement {\n\t\tconst existingOverlay = document.getElementById(OverlayManager.OVERLAY_ID);\n\t\tif (existingOverlay) return existingOverlay;\n\n\t\tconst globalOverlay = document.createElement('div');\n\t\tglobalOverlay.id = OverlayManager.OVERLAY_ID;\n\t\tdocument.body.insertAdjacentElement('afterend', globalOverlay);\n\n\t\treturn globalOverlay;\n\t}\n\n\tstatic addStyles(): void {\n\t\tconst existingStyle = document.getElementById(OverlayManager.STYLE_ID);\n\t\tif (existingStyle) return;\n\n\t\tconst style = document.createElement('style');\n\t\tstyle.id = OverlayManager.STYLE_ID;\n\n\t\tconst buttonSize = 28;\n\t\tconst buttonWidth = `var(${OverlayManager.CSS_VAR_BUTTON_WIDTH}, ${buttonSize}px)`;\n\t\tconst buttonGap = 4;\n\t\tconst editButtonBgColor = `var(${OverlayManager.CSS_VAR_EDIT_BUTTON_BG_COLOR}, #6644ff)`;\n\t\tconst aiButtonBgColor = `var(${OverlayManager.CSS_VAR_AI_BUTTON_BG_COLOR}, ${editButtonBgColor})`;\n\t\tconst buttonBgColorMix = '#2e3C43 25%';\n\t\tconst borderSpacing = `var(${OverlayManager.CSS_VAR_BORDER_SPACING}, ${Math.round(buttonSize * 0.333)}px)`;\n\t\tconst borderWidth = `var(${OverlayManager.CSS_VAR_BORDER_WIDTH}, 2px)`;\n\n\t\tstyle.appendChild(\n\t\t\tdocument.createTextNode(`\n\t\t\t\t#${OverlayManager.OVERLAY_ID} {\n\t\t\t\t\tdisplay: contents;\n\t\t\t\t}\n\t\t\t\t.${OverlayManager.CONTAINER_RECT_CLASS_NAME} {\n\t\t\t\t\tpointer-events: none;\n\t\t\t\t\tposition: fixed;\n\t\t\t\t\ttop: 0;\n\t\t\t\t\tleft: 0;\n\t\t\t\t\tright: 0;\n\t\t\t\t\tbottom: 0;\n\t\t\t\t\tz-index: var(${OverlayManager.CSS_VAR_Z_INDEX}, 999999999);\n\t\t\t\t}\n\t\t\t\t.${OverlayManager.RECT_CLASS_NAME} {\n\t\t\t\t\tposition: absolute;\n\t\t\t\t}\n\t\t\t\t.${OverlayManager.RECT_INNER_CLASS_NAME} {\n\t\t\t\t\tposition: absolute;\n\t\t\t\t\tbox-sizing: border-box;\n\t\t\t\t\ttop: calc(-1 * ${borderSpacing});\n\t\t\t\t\tleft: calc(-1 * ${borderSpacing});\n\t\t\t\t\tright: calc(-1 * ${borderSpacing});\n\t\t\t\t\tbottom: calc(-1 * ${borderSpacing});\n\t\t\t\t\tborder: ${borderWidth} solid var(${OverlayManager.CSS_VAR_BORDER_COLOR}, #6644ff);\n\t\t\t\t\tborder-radius: var(${OverlayManager.CSS_VAR_BORDER_RADIUS}, 6px);\n\t\t\t\t\topacity: 0;\n\t\t\t\t}\n\t\t\t\t.${OverlayManager.RECT_CLASS_NAME}.${OverlayManager.RECT_HOVER_CLASS_NAME} .${OverlayManager.RECT_INNER_CLASS_NAME} {\n\t\t\t\t\t--hover-opacity: var(${OverlayManager.CSS_VAR_HOVER_OPACITY}, 0.333);\n\t\t\t\t\topacity: var(--hover-opacity);\n\t\t\t\t}\n\t\t\t\t.${OverlayManager.RECT_CLASS_NAME}.${OverlayManager.RECT_PARENT_HOVER_CLASS_NAME} .${OverlayManager.RECT_INNER_CLASS_NAME} {\n\t\t\t\t\topacity: calc(var(--hover-opacity) / 3);\n\t\t\t\t}\n\t\t\t\t.${OverlayManager.RECT_HIGHLIGHT_CLASS_NAME} {\n\t\t\t\t\tpointer-events: all;\n\t\t\t\t\tcursor: pointer;\n\t\t\t\t}\n\t\t\t\t.${OverlayManager.RECT_HIGHLIGHT_CLASS_NAME} .${OverlayManager.RECT_INNER_CLASS_NAME} {\n\t\t\t\t\topacity: var(${OverlayManager.CSS_VAR_HIGHLIGHT_OPACITY}, 0.333);\n\t\t\t\t}\n\t\t\t\t.${OverlayManager.RECT_BUTTON_CLASS_NAME}:visited,\n\t\t\t\t.${OverlayManager.RECT_BUTTON_CLASS_NAME}:active,\n\t\t\t\t.${OverlayManager.RECT_BUTTON_CLASS_NAME}:hover,\n\t\t\t\t.${OverlayManager.RECT_BUTTON_CLASS_NAME}:focus,\n\t\t\t\t.${OverlayManager.RECT_BUTTON_CLASS_NAME} {\n\t\t\t\t\tall: initial;\n\t\t\t\t\tpointer-events: all;\n\t\t\t\t\tcursor: pointer;\n\t\t\t\t\tposition: absolute;\n\t\t\t\t\tz-index: 1;\n\t\t\t\t\ttop: calc(-1 * ${borderSpacing} + ${borderWidth} / 2);\n\t\t\t\t\ttransform: translate(-50%, -50%);\n\t\t\t\t\twidth: ${buttonWidth};\n\t\t\t\t\theight: var(${OverlayManager.CSS_VAR_BUTTON_HEIGHT}, ${buttonSize}px);\n\t\t\t\t\tborder-radius: var(${OverlayManager.CSS_VAR_BUTTON_RADIUS}, 50%);\n\t\t\t\t\tbackground-position: center;\n\t\t\t\t\tbackground-repeat: no-repeat;\n\t\t\t\t\topacity: 0;\n\t\t\t\t}\n\t\t\t\t.${OverlayManager.RECT_BUTTON_CLASS_NAME}.${OverlayManager.RECT_EDIT_BUTTON_CLASS_NAME} {\n\t\t\t\t\tleft: calc(-1 * ${borderSpacing} + ${borderWidth} / 2);\n\t\t\t\t\tbackground-color: ${editButtonBgColor};\n\t\t\t\t\tbackground-image: var(${OverlayManager.CSS_VAR_EDIT_BUTTON_ICON_BG_IMAGE}, ${OverlayManager.ICON_EDIT});\n\t\t\t\t\tbackground-size: var(${OverlayManager.CSS_VAR_EDIT_BUTTON_ICON_BG_SIZE}, 66.6%);\n\t\t\t\t}\n\t\t\t\t.${OverlayManager.RECT_BUTTON_CLASS_NAME}.${OverlayManager.RECT_AI_BUTTON_CLASS_NAME} {\n\t\t\t\t\tleft: calc(-1 * ${borderSpacing} + ${borderWidth} / 2 + ${buttonWidth} + var(${OverlayManager.CSS_VAR_ACTIONS_GAP}, ${buttonGap}px));\n\t\t\t\t\tbackground-color: ${aiButtonBgColor};\n\t\t\t\t\tbackground-image: var(${OverlayManager.CSS_VAR_AI_BUTTON_ICON_BG_IMAGE}, ${OverlayManager.ICON_AI});\n\t\t\t\t\tbackground-size: var(${OverlayManager.CSS_VAR_AI_BUTTON_ICON_BG_SIZE}, 66.6%);\n\t\t\t\t}\n\t\t\t\t.${OverlayManager.RECT_CLASS_NAME}.${OverlayManager.RECT_HOVER_CLASS_NAME}:not(.${OverlayManager.RECT_PARENT_HOVER_CLASS_NAME}) .${OverlayManager.RECT_BUTTON_CLASS_NAME},\n\t\t\t\t.${OverlayManager.RECT_HIGHLIGHT_ACTIVE_CLASS_NAME} .${OverlayManager.RECT_INNER_CLASS_NAME},\n\t\t\t\t.${OverlayManager.RECT_HIGHLIGHT_CLASS_NAME}:hover .${OverlayManager.RECT_BUTTON_CLASS_NAME},\n\t\t\t\t.${OverlayManager.RECT_BUTTON_CLASS_NAME}:hover,\n\t\t\t\t.${OverlayManager.RECT_BUTTON_CLASS_NAME}:hover ~ .${OverlayManager.RECT_INNER_CLASS_NAME},\n\t\t\t\t.${OverlayManager.RECT_HIGHLIGHT_CLASS_NAME}:hover .${OverlayManager.RECT_INNER_CLASS_NAME},\n\t\t\t\t.${OverlayManager.RECT_CLASS_NAME}:has(.${OverlayManager.RECT_BUTTON_CLASS_NAME}:hover) .${OverlayManager.RECT_BUTTON_CLASS_NAME} {\n\t\t\t\t\topacity: 1;\n\t\t\t\t}\n\t\t\t\t.${OverlayManager.RECT_BUTTON_CLASS_NAME}.${OverlayManager.RECT_EDIT_BUTTON_CLASS_NAME}:hover {\n\t\t\t\t\tbackground-color: color-mix(in srgb, ${editButtonBgColor}, ${buttonBgColorMix});\n\t\t\t\t}\n\t\t\t\t.${OverlayManager.RECT_BUTTON_CLASS_NAME}.${OverlayManager.RECT_AI_BUTTON_CLASS_NAME}:hover {\n\t\t\t\t\tbackground-color: color-mix(in srgb, ${aiButtonBgColor}, ${buttonBgColorMix});\n\t\t\t\t}\n\t\t\t`),\n\t\t);\n\n\t\tdocument.head.appendChild(style);\n\t}\n}\n","import { EditableStore } from './editable-store.ts';\nimport { OverlayManager } from './overlay-manager.ts';\nimport { DirectusFrame } from './directus-frame.ts';\n\nexport class OverlayElement {\n\tprivate hasNoDimensions: boolean = false;\n\tprivate element: HTMLElement;\n\tprivate container: HTMLElement;\n\n\treadonly editButton: HTMLButtonElement;\n\treadonly aiButton: HTMLButtonElement | null;\n\n\tconstructor() {\n\t\tthis.container = this.createContainer();\n\t\tthis.element = this.createElement();\n\t\tthis.editButton = this.createEditButton();\n\t\tthis.aiButton = new DirectusFrame().isAiEnabled() ? this.createAiButton() : null;\n\t\tthis.createRectElement();\n\n\t\tOverlayManager.getGlobalOverlay().appendChild(this.container);\n\n\t\tif (EditableStore.highlightOverlayElements) this.toggleHighlight(true);\n\n\t\tthis.element.addEventListener('click', () => this.editButton.click());\n\t}\n\n\tprivate createContainer() {\n\t\tconst container = document.createElement('div');\n\t\tcontainer.classList.add(OverlayManager.CONTAINER_RECT_CLASS_NAME);\n\t\treturn container;\n\t}\n\n\tprivate createElement() {\n\t\tconst element = document.createElement('div');\n\t\telement.classList.add(OverlayManager.RECT_CLASS_NAME);\n\t\tthis.container.appendChild(element);\n\t\treturn element;\n\t}\n\n\tprivate createRectElement() {\n\t\tconst rectInnerElement = document.createElement('div');\n\t\trectInnerElement.classList.add(OverlayManager.RECT_INNER_CLASS_NAME);\n\t\tthis.element.appendChild(rectInnerElement);\n\t}\n\n\tprivate createEditButton() {\n\t\tconst editButton = document.createElement('button');\n\t\teditButton.type = 'button';\n\t\teditButton.classList.add(OverlayManager.RECT_BUTTON_CLASS_NAME);\n\t\teditButton.classList.add(OverlayManager.RECT_EDIT_BUTTON_CLASS_NAME);\n\t\tthis.element.appendChild(editButton);\n\t\treturn editButton;\n\t}\n\n\tprivate createAiButton() {\n\t\tconst aiButton = document.createElement('button');\n\t\taiButton.type = 'button';\n\t\taiButton.classList.add(OverlayManager.RECT_BUTTON_CLASS_NAME);\n\t\taiButton.classList.add(OverlayManager.RECT_AI_BUTTON_CLASS_NAME);\n\t\tthis.element.appendChild(aiButton);\n\t\treturn aiButton;\n\t}\n\n\tupdateRect(rect: DOMRect) {\n\t\tconst hasDimensions = rect.width !== 0 && rect.height !== 0;\n\n\t\tif (!this.hasNoDimensions && !hasDimensions) {\n\t\t\tthis.hasNoDimensions = true;\n\t\t\tthis.disable();\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.hasNoDimensions && hasDimensions) {\n\t\t\tthis.hasNoDimensions = false;\n\t\t\tthis.enable();\n\t\t}\n\n\t\tthis.element.style.width = `${rect.width}px`;\n\t\tthis.element.style.height = `${rect.height}px`;\n\t\tthis.element.style.transform = `translate(${rect.left}px,${rect.top}px)`;\n\t}\n\n\tsetCustomClass(customClass: string | undefined) {\n\t\tif (customClass === undefined) return;\n\n\t\tconst isValidClassName = /^[a-zA-Z_][\\w-]*$/.test(customClass);\n\t\tif (isValidClassName) this.container.classList.add(customClass);\n\t}\n\n\ttoggleHover(hover: boolean) {\n\t\tthis.element.classList.toggle(OverlayManager.RECT_HOVER_CLASS_NAME, hover);\n\t}\n\n\ttoggleParentHover(hover: boolean) {\n\t\tthis.element.classList.toggle(OverlayManager.RECT_PARENT_HOVER_CLASS_NAME, hover);\n\t}\n\n\ttoggleHighlight(show: boolean) {\n\t\tthis.element.classList.toggle(OverlayManager.RECT_HIGHLIGHT_CLASS_NAME, show);\n\t}\n\n\ttoggleHighlightActive(show: boolean) {\n\t\tthis.element.classList.toggle(OverlayManager.RECT_HIGHLIGHT_ACTIVE_CLASS_NAME, show);\n\t}\n\n\tdisable() {\n\t\tthis.element.style.display = 'none';\n\t}\n\n\tenable() {\n\t\tthis.element.style.removeProperty('display');\n\t}\n\n\tremove() {\n\t\tthis.container.remove();\n\t}\n}\n","import observeRect from '@reach/observe-rect';\nimport { DirectusFrame } from './directus-frame.ts';\nimport { EditableStore } from './editable-store.ts';\nimport { OverlayElement } from './overlay-element.ts';\nimport type { EditConfig, EditConfigStrict, EditableElementOptions } from './types/index.ts';\n\nexport class EditableElement {\n\tprivate static readonly DATASET = 'directus';\n\tprivate static readonly DATA_ATTRIBUTE_VALID_KEYS: Array<keyof EditConfig> = ['collection', 'item', 'fields', 'mode'];\n\n\tprivate optionsWritable = true;\n\n\treadonly element: HTMLElement;\n\treadonly key: string; // A unique key to identify editable elements not to be confused with the primary key\n\treadonly editConfig: EditConfigStrict;\n\treadonly rectObserver: { observe(): void; unobserve(): void };\n\treadonly overlayElement: OverlayElement;\n\n\trect: DOMRect;\n\thover = false;\n\tdisabled = false;\n\tonSaved: EditableElementOptions['onSaved'] = undefined;\n\n\tprivate boundMouseenter: (e: MouseEvent) => void;\n\tprivate boundMouseleave: (e: MouseEvent) => void;\n\n\tconstructor(element: HTMLElement) {\n\t\tthis.element = element;\n\t\tthis.boundMouseenter = this.onMouseenter.bind(this);\n\t\tthis.boundMouseleave = this.onMouseleave.bind(this);\n\t\tthis.element.addEventListener('mouseenter', this.boundMouseenter);\n\t\tthis.element.addEventListener('mouseleave', this.boundMouseleave);\n\n\t\tthis.key = crypto.randomUUID();\n\t\tthis.editConfig = EditableElement.editAttrToObject(this.element.dataset[EditableElement.DATASET]!);\n\n\t\tthis.rect = this.element.getBoundingClientRect();\n\t\tthis.overlayElement = new OverlayElement();\n\t\tthis.overlayElement.updateRect(this.rect);\n\t\tthis.overlayElement.editButton.addEventListener('click', this.onClickEdit.bind(this));\n\t\tthis.overlayElement.aiButton?.addEventListener('click', this.onClickAddToContext.bind(this));\n\n\t\t// @ts-expect-error\n\t\tthis.rectObserver = observeRect(this.element, this.onObserveRect.bind(this));\n\t\tthis.rectObserver.observe();\n\t}\n\n\tstatic query(elements: HTMLElement | HTMLElement[] | undefined | null) {\n\t\tif (!elements) return Array.from(document.querySelectorAll(`[data-${EditableElement.DATASET}]`)) as HTMLElement[];\n\n\t\tconst elementsArray = Array.isArray(elements) ? elements : [elements];\n\t\treturn elementsArray\n\t\t\t.filter((element) => element instanceof HTMLElement)\n\t\t\t.flatMap((element) => {\n\t\t\t\tif (element.dataset[EditableElement.DATASET] !== undefined) return element;\n\t\t\t\tconst childrenElements = Array.from(element.querySelectorAll(`[data-${EditableElement.DATASET}]`));\n\t\t\t\treturn childrenElements as HTMLElement[];\n\t\t\t})\n\t\t\t.filter((element) => element !== null);\n\t}\n\n\tstatic objectToEditAttr(editConfig: EditConfig): string {\n\t\tconst dataAttr: string[] = [];\n\n\t\tfor (const [key, value] of Object.entries(editConfig)) {\n\t\t\tif (!EditableElement.validEditConfigKey(key as keyof EditConfig)) continue;\n\n\t\t\tif (key === 'fields' && Array.isArray(value)) {\n\t\t\t\tdataAttr.push(`${key}:${value.join(',')}`);\n\t\t\t} else {\n\t\t\t\tdataAttr.push(`${key}:${value}`);\n\t\t\t}\n\t\t}\n\n\t\treturn dataAttr.join(';');\n\t}\n\n\tprivate static editAttrToObject(str: string) {\n\t\tconst pairs = str.split(';');\n\t\tconst result: Record<string, any> = {};\n\n\t\tpairs.forEach((pair) => {\n\t\t\tconst keyValue = pair.split(':');\n\t\t\tif (keyValue[0] === undefined || keyValue?.[1] === undefined) return;\n\n\t\t\tconst key = keyValue[0].trim() as keyof EditConfig;\n\t\t\tif (!EditableElement.validEditConfigKey(key)) return;\n\n\t\t\tconst value = keyValue[1];\n\n\t\t\tif (key === 'fields') {\n\t\t\t\tresult['fields'] = value.split(',').map((field) => field.trim());\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tresult[key] = value.trim();\n\t\t});\n\n\t\treturn result as EditConfigStrict;\n\t}\n\n\tprivate static validEditConfigKey(key: keyof EditConfig) {\n\t\treturn EditableElement.DATA_ATTRIBUTE_VALID_KEYS.includes(key);\n\t}\n\n\tapplyOptions({ customClass, onSaved }: EditableElementOptions, elementsSpecified = false) {\n\t\tif (!this.optionsWritable) return;\n\t\tif (elementsSpecified) this.optionsWritable = false;\n\t\tthis.overlayElement.setCustomClass(customClass);\n\t\tif (onSaved !== undefined) this.onSaved = onSaved;\n\t}\n\n\tremoveHoverListener() {\n\t\tthis.element.removeEventListener('mouseenter', this.boundMouseenter);\n\t\tthis.element.removeEventListener('mouseleave', this.boundMouseleave);\n\t}\n\n\tprivate onClickEdit() {\n\t\tnew DirectusFrame().send('edit', { key: this.key, editConfig: this.editConfig, rect: this.rect });\n\t}\n\n\tprivate onClickAddToContext(event: MouseEvent) {\n\t\tevent.stopPropagation();\n\t\tnew DirectusFrame().send('addToContext', { key: this.key, editConfig: this.editConfig, rect: this.rect });\n\t}\n\n\tprivate onMouseenter(event: MouseEvent) {\n\t\tthis.toggleItemHover(true, event);\n\t}\n\n\tprivate onMouseleave(event: MouseEvent) {\n\t\tthis.toggleItemHover(false, event);\n\t}\n\n\tprivate toggleItemHover(hover: boolean, event: MouseEvent) {\n\t\tif (this.element !== event.currentTarget || this.hover === hover) return;\n\n\t\tthis.hover = hover;\n\t\tthis.setParentsHover();\n\t\tthis.overlayElement.toggleHover(hover);\n\t}\n\n\tprivate setParentsHover() {\n\t\tconst hoveredItems = EditableStore.getHoveredItems();\n\n\t\thoveredItems.forEach((hoveredItem) => {\n\t\t\tconst otherElements = hoveredItems.filter((item) => item.element !== hoveredItem.element);\n\t\t\tconst isParentElement = otherElements.some((el) => hoveredItem.element.contains(el.element));\n\n\t\t\thoveredItem.overlayElement.toggleParentHover(isParentElement);\n\t\t});\n\t}\n\n\tprivate onObserveRect(rect: DOMRect) {\n\t\tif (this.disabled) return;\n\t\tthis.rect = rect;\n\t\tthis.overlayElement.updateRect(rect);\n\t}\n}\n","import { EditableElement } from './editable-element.ts';\n\nexport class EditableStore {\n\tprivate static items: EditableElement[] = [];\n\tstatic highlightOverlayElements = false;\n\tprivate static highlightedKey: string | null = null;\n\n\tstatic getItem(element: Element) {\n\t\treturn EditableStore.items.find((item) => item.element === element);\n\t}\n\n\tstatic getItemByKey(key: EditableElement['key']) {\n\t\treturn EditableStore.items.find((item) => item.key === key);\n\t}\n\n\tstatic getItemByEditConfig(collection: string, item: string | number, fields?: string[]) {\n\t\treturn EditableStore.items.find((i) => {\n\t\t\tif (i.editConfig.collection !== collection) return false;\n\t\t\tif (String(i.editConfig.item) !== String(item)) return false;\n\n\t\t\tconst itemFields = i.editConfig.fields ?? [];\n\t\t\tconst targetFields = fields ?? [];\n\n\t\t\tif (itemFields.length !== targetFields.length) return false;\n\n\t\t\treturn itemFields.every((f) => targetFields.includes(f));\n\t\t});\n\t}\n\n\tstatic getHoveredItems() {\n\t\treturn EditableStore.items.filter((item) => item.hover);\n\t}\n\n\tstatic addItem(item: EditableElement) {\n\t\tEditableStore.items.push(item);\n\t}\n\n\tstatic enableItems(selectedItems?: EditableElement[]) {\n\t\tconst items = selectedItems ?? EditableStore.items;\n\n\t\titems.forEach((item) => {\n\t\t\titem.disabled = false;\n\t\t\titem.rectObserver.observe();\n\t\t\titem.overlayElement.enable();\n\t\t});\n\t}\n\n\tstatic disableItems(selectedItems?: EditableElement[]) {\n\t\tconst items = selectedItems ?? EditableStore.items.filter((item) => !item.disabled);\n\n\t\titems.forEach((item) => {\n\t\t\titem.disabled = true;\n\t\t\titem.hover = false;\n\t\t\titem.rectObserver.unobserve();\n\t\t\titem.overlayElement.disable();\n\t\t});\n\n\t\treturn [...items];\n\t}\n\n\tstatic removeItems(selectedItems?: EditableElement[]) {\n\t\tconst items = selectedItems ?? EditableStore.items;\n\n\t\titems.forEach((item) => {\n\t\t\titem.rectObserver.unobserve();\n\t\t\titem.overlayElement.remove();\n\t\t\titem.removeHoverListener();\n\t\t});\n\n\t\tEditableStore.items = EditableStore.items.filter((item) => !items.includes(item));\n\t}\n\n\tstatic highlightItems(show: boolean) {\n\t\tif (this.highlightOverlayElements === show) return;\n\n\t\tthis.highlightOverlayElements = show;\n\n\t\tEditableStore.items.forEach((item) => {\n\t\t\titem.overlayElement.toggleHighlight(show);\n\t\t});\n\t}\n\n\tstatic highlightElement(\n\t\tidentifier: { key: string } | { collection: string; item: string | number; fields?: string[] } | null,\n\t) {\n\t\tif (this.highlightedKey !== null) {\n\t\t\tEditableStore.getItemByKey(this.highlightedKey)?.overlayElement.toggleHighlightActive(false);\n\t\t}\n\n\t\tif (identifier === null) {\n\t\t\tthis.highlightedKey = null;\n\t\t\treturn;\n\t\t}\n\n\t\tlet element: EditableElement | undefined;\n\n\t\tif ('key' in identifier) {\n\t\t\telement = EditableStore.getItemByKey(identifier.key);\n\t\t} else {\n\t\t\telement = EditableStore.getItemByEditConfig(identifier.collection, identifier.item, identifier.fields);\n\t\t}\n\n\t\tif (element) {\n\t\t\tthis.highlightedKey = element.key;\n\t\t\telement.overlayElement.toggleHighlightActive(true);\n\t\t} else {\n\t\t\tthis.highlightedKey = null;\n\t\t}\n\t}\n}\n","import { EditableStore } from './editable-store.ts';\nimport type { HighlightElementData, ConfirmData, SendAction, ReceiveData, SavedData } from './types/index.ts';\n\n/**\n * *Singleton* class to handle communication with Directus in parent frame.\n */\nexport class DirectusFrame {\n\tprivate static SINGLETON?: DirectusFrame;\n\tprivate static readonly ERROR_PARENT_NOT_FOUND = 'Error sending message to Directus in parent frame:';\n\n\tprivate origin: string | null = null;\n\tprivate confirmed = false;\n\tprivate aiEnabled = false;\n\n\tconstructor() {\n\t\tif (DirectusFrame.SINGLETON) return DirectusFrame.SINGLETON;\n\t\tDirectusFrame.SINGLETON = this;\n\n\t\twindow?.addEventListener('message', this.receive.bind(this));\n\t}\n\n\tconnect(origin: string) {\n\t\tthis.origin = origin;\n\t\treturn this.send('connect');\n\t}\n\n\tsend(action: SendAction, data?: unknown) {\n\t\ttry {\n\t\t\tif (!this.origin) throw new Error();\n\t\t\twindow.parent.postMessage({ action, data }, this.origin);\n\t\t\treturn true;\n\t\t} catch (error) {\n\t\t\t// eslint-disable-next-line\n\t\t\tconsole.error(DirectusFrame.ERROR_PARENT_NOT_FOUND, error);\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tprivate sameOrigin(origin: string, url: string) {\n\t\ttry {\n\t\t\treturn origin === new URL(url).origin;\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\treceive(event: MessageEvent) {\n\t\tif (!this.origin || !this.sameOrigin(event.origin, this.origin)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst { action, data }: ReceiveData = event.data;\n\n\t\tif (action === 'confirm') this.receiveConfirmAction(data);\n\t\tif (action === 'showEditableElements') this.receiveShowEditableElements(data);\n\t\tif (action === 'saved') this.receiveSaved(data);\n\t\tif (action === 'highlightElement') this.receiveHighlightElement(data);\n\t}\n\n\tprivate receiveConfirmAction(data: unknown) {\n\t\tthis.confirmed = true;\n\t\tthis.aiEnabled = !!(data as ConfirmData)?.aiEnabled;\n\t}\n\n\tisAiEnabled() {\n\t\treturn this.aiEnabled;\n\t}\n\n\treceiveConfirm() {\n\t\tlet attempts = 0;\n\t\tconst maxAttempts = 10;\n\t\tconst timeout = 100;\n\n\t\treturn new Promise<boolean>((resolve) => {\n\t\t\tconst checkConfirmed = () => {\n\t\t\t\tif (attempts >= maxAttempts) return resolve(false);\n\t\t\t\tattempts++;\n\n\t\t\t\tif (this.confirmed) resolve(true);\n\t\t\t\telse setTimeout(checkConfirmed, timeout);\n\t\t\t};\n\n\t\t\tcheckConfirmed();\n\t\t});\n\t}\n\n\tprivate receiveShowEditableElements(data: unknown) {\n\t\tconst show = !!data;\n\t\tEditableStore.highlightItems(show);\n\t}\n\n\tprivate receiveSaved(data: unknown) {\n\t\tconst { key = '', collection = '', item = null, payload = {} } = data as SavedData;\n\n\t\tconst storeItem = EditableStore.getItemByKey(key);\n\n\t\tif (storeItem && collection && typeof storeItem.onSaved === 'function') {\n\t\t\tstoreItem.onSaved({ collection, item, payload });\n\t\t\treturn;\n\t\t}\n\n\t\twindow.location.reload();\n\t}\n\n\tprivate receiveHighlightElement(data: unknown) {\n\t\tif (!data || typeof data !== 'object') {\n\t\t\tEditableStore.highlightElement(null);\n\t\t\treturn;\n\t\t}\n\n\t\tconst { key, collection, item, fields } = data as HighlightElementData;\n\n\t\tif (key === null) {\n\t\t\t// Clear highlight (edit overlay closed or AI store emits null)\n\t\t\tEditableStore.highlightElement(null);\n\t\t} else if (collection && item !== undefined) {\n\t\t\t// Key absent, collection+item present: AI context panel hover\n\t\t\t// Looks up via getItemByEditConfig(). fields included for relational/multi-field items\n\t\t\tEditableStore.highlightElement(fields ? { collection, item, fields } : { collection, item });\n\t\t} else if (typeof key === 'string') {\n\t\t\t// Key of type string = UUID from editable-element.ts, looks up via getItemByKey()\n\t\t\tEditableStore.highlightElement({ key });\n\t\t}\n\t}\n}\n","export class PageManager {\n\tprivate static navigationInitialized = false;\n\n\tstatic onNavigation(callback: (data: { url: string; title: string }) => void) {\n\t\tif (PageManager.navigationInitialized) return;\n\n\t\tlet lastUrl = '';\n\t\tlet lastTitle = '';\n\t\tlet debounceId: number;\n\n\t\tconst debounce = (debounceFunction: () => void) => {\n\t\t\tclearTimeout(debounceId);\n\t\t\tdebounceId = setTimeout(debounceFunction, 100);\n\t\t};\n\n\t\tconst observeNavigation = () => {\n\t\t\tconst url = window.location.href;\n\t\t\tconst title = document.title;\n\t\t\tconst changesDetected = lastUrl !== url || lastTitle !== title;\n\n\t\t\tif (changesDetected) {\n\t\t\t\tdebounce(() => callback({ url, title }));\n\t\t\t\tlastUrl = url;\n\t\t\t\tlastTitle = title;\n\t\t\t}\n\n\t\t\tsetTimeout(observeNavigation, changesDetected ? 50 : 200);\n\t\t};\n\n\t\tobserveNavigation();\n\n\t\tPageManager.navigationInitialized = true;\n\t}\n}\n","import { DirectusFrame } from './lib/directus-frame.ts';\nimport { EditableElement } from './lib/editable-element.ts';\nimport { EditableStore } from './lib/editable-store.ts';\nimport { OverlayManager } from './lib/overlay-manager.ts';\nimport { PageManager } from './lib/page-manager.ts';\nimport type { EditConfig, EditableElementOptions } from './lib/types/index.ts';\n\nexport async function apply({\n\tdirectusUrl,\n\telements = undefined,\n\tcustomClass = undefined,\n\tonSaved = undefined,\n}: {\n\tdirectusUrl: string;\n\telements?: HTMLElement | HTMLElement[] | null;\n} & EditableElementOptions) {\n\tconst directusFrame = new DirectusFrame();\n\tconst connected = directusFrame.connect(directusUrl);\n\tif (!connected) return;\n\n\tconst confirmed = await directusFrame.receiveConfirm();\n\tif (!confirmed) return;\n\n\tPageManager.onNavigation((data) => directusFrame.send('navigation', data));\n\tOverlayManager.addStyles();\n\n\tconst editableElements = EditableElement.query(elements);\n\tconst scopedItems: EditableElement[] = [];\n\n\teditableElements.forEach((element) => {\n\t\tconst existingItem = EditableStore.getItem(element);\n\t\tconst item = existingItem ?? new EditableElement(element);\n\n\t\titem.applyOptions({ customClass, onSaved }, !!elements);\n\n\t\tscopedItems.push(item);\n\t\tif (!existingItem) EditableStore.addItem(item);\n\t});\n\n\treturn {\n\t\tremove() {\n\t\t\tEditableStore.removeItems(scopedItems);\n\t\t},\n\t\tenable() {\n\t\t\tEditableStore.enableItems(scopedItems);\n\t\t},\n\t\tdisable() {\n\t\t\tEditableStore.disableItems(scopedItems);\n\t\t},\n\t};\n}\n\nexport function remove() {\n\tEditableStore.removeItems();\n}\n\nexport function disable() {\n\tconst items = EditableStore.disableItems();\n\treturn {\n\t\tenable() {\n\t\t\tEditableStore.enableItems(items);\n\t\t},\n\t};\n}\n\nexport function setAttr(editConfig: EditConfig) {\n\treturn EditableElement.objectToEditAttr(editConfig);\n}\n"],"mappings":"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"}