@intlayer/editor 8.7.6 → 8.7.7
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/cjs/components/ContentSelector.cjs +85 -75
- package/dist/cjs/components/ContentSelector.cjs.map +1 -1
- package/dist/cjs/components/ContentSelectorWrapper.cjs +131 -95
- package/dist/cjs/components/ContentSelectorWrapper.cjs.map +1 -1
- package/dist/cjs/components/EditedContent.cjs +74 -49
- package/dist/cjs/components/EditedContent.cjs.map +1 -1
- package/dist/cjs/components/IntlayerEditor.cjs +34 -27
- package/dist/cjs/components/IntlayerEditor.cjs.map +1 -1
- package/dist/cjs/core/CrossFrameMessenger.cjs +6 -3
- package/dist/cjs/core/CrossFrameMessenger.cjs.map +1 -1
- package/dist/cjs/core/CrossFrameStateManager.cjs +5 -1
- package/dist/cjs/core/CrossFrameStateManager.cjs.map +1 -1
- package/dist/cjs/core/EditorStateManager.cjs +14 -3
- package/dist/cjs/core/EditorStateManager.cjs.map +1 -1
- package/dist/cjs/core/IframeClickInterceptor.cjs +3 -2
- package/dist/cjs/core/IframeClickInterceptor.cjs.map +1 -1
- package/dist/cjs/core/UrlStateManager.cjs +4 -3
- package/dist/cjs/core/UrlStateManager.cjs.map +1 -1
- package/dist/cjs/core/globalManager.cjs.map +1 -1
- package/dist/cjs/core/initEditorClient.cjs.map +1 -1
- package/dist/esm/components/ContentSelector.mjs +85 -74
- package/dist/esm/components/ContentSelector.mjs.map +1 -1
- package/dist/esm/components/ContentSelectorWrapper.mjs +131 -95
- package/dist/esm/components/ContentSelectorWrapper.mjs.map +1 -1
- package/dist/esm/components/EditedContent.mjs +74 -49
- package/dist/esm/components/EditedContent.mjs.map +1 -1
- package/dist/esm/components/IntlayerEditor.mjs +34 -26
- package/dist/esm/components/IntlayerEditor.mjs.map +1 -1
- package/dist/esm/core/CrossFrameMessenger.mjs +6 -3
- package/dist/esm/core/CrossFrameMessenger.mjs.map +1 -1
- package/dist/esm/core/CrossFrameStateManager.mjs +5 -1
- package/dist/esm/core/CrossFrameStateManager.mjs.map +1 -1
- package/dist/esm/core/EditorStateManager.mjs +14 -3
- package/dist/esm/core/EditorStateManager.mjs.map +1 -1
- package/dist/esm/core/IframeClickInterceptor.mjs +3 -2
- package/dist/esm/core/IframeClickInterceptor.mjs.map +1 -1
- package/dist/esm/core/UrlStateManager.mjs +4 -3
- package/dist/esm/core/UrlStateManager.mjs.map +1 -1
- package/dist/esm/core/globalManager.mjs.map +1 -1
- package/dist/esm/core/initEditorClient.mjs.map +1 -1
- package/dist/types/components/ContentSelector.d.ts +15 -10
- package/dist/types/components/ContentSelector.d.ts.map +1 -1
- package/dist/types/components/ContentSelectorWrapper.d.ts +22 -12
- package/dist/types/components/ContentSelectorWrapper.d.ts.map +1 -1
- package/dist/types/components/EditedContent.d.ts +21 -10
- package/dist/types/components/EditedContent.d.ts.map +1 -1
- package/dist/types/components/IntlayerEditor.d.ts +16 -10
- package/dist/types/components/IntlayerEditor.d.ts.map +1 -1
- package/package.json +7 -8
- package/dist/cjs/_virtual/_@oxc-project_runtime@0.126.0/helpers/decorate.cjs +0 -11
- package/dist/esm/_virtual/_@oxc-project_runtime@0.126.0/helpers/decorate.mjs +0 -10
|
@@ -9,10 +9,11 @@ const require_messageKey = require('../messageKey.cjs');
|
|
|
9
9
|
* Replaces useCrossURLPathSetter / useCrossURLPathState across all frameworks.
|
|
10
10
|
*/
|
|
11
11
|
var UrlStateManager = class {
|
|
12
|
+
_messenger;
|
|
13
|
+
_originalPushState = null;
|
|
14
|
+
_originalReplaceState = null;
|
|
15
|
+
_listeners = [];
|
|
12
16
|
constructor(messenger) {
|
|
13
|
-
this._originalPushState = null;
|
|
14
|
-
this._originalReplaceState = null;
|
|
15
|
-
this._listeners = [];
|
|
16
17
|
this._messenger = messenger;
|
|
17
18
|
}
|
|
18
19
|
start() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UrlStateManager.cjs","names":[],"sources":["../../../src/core/UrlStateManager.ts"],"sourcesContent":["import { MessageKey } from '../messageKey';\nimport type { CrossFrameMessenger } from './CrossFrameMessenger';\n\n/**\n * UrlStateManager patches window.history and broadcasts URL path changes\n * across frames via postMessage.\n *\n * Replaces useCrossURLPathSetter / useCrossURLPathState across all frameworks.\n */\nexport class UrlStateManager {\n private readonly _messenger: CrossFrameMessenger;\n private _originalPushState: typeof history.pushState | null = null;\n private _originalReplaceState: typeof history.replaceState | null = null;\n private _listeners: Array<[string, EventListener]> = [];\n\n constructor(messenger: CrossFrameMessenger) {\n this._messenger = messenger;\n }\n\n start(): void {\n if (typeof window === 'undefined') return;\n\n const updateURLState = () => {\n this._messenger.send(\n `${MessageKey.INTLAYER_URL_CHANGE}/post`,\n window.location.pathname\n );\n };\n\n this._originalPushState = history.pushState;\n this._originalReplaceState = history.replaceState;\n\n const injectLocationChange = (method: typeof history.pushState) =>\n function (\n this: typeof history,\n ...args: Parameters<typeof history.pushState>\n ) {\n method.apply(this, args);\n window.dispatchEvent(new Event('locationchange'));\n };\n\n history.pushState = injectLocationChange(\n this._originalPushState\n ) as typeof history.pushState;\n history.replaceState = injectLocationChange(\n this._originalReplaceState\n ) as typeof history.replaceState;\n\n for (const eventName of [\n 'locationchange',\n 'popstate',\n 'hashchange',\n 'load',\n ] as const) {\n const listener = updateURLState as EventListener;\n window.addEventListener(eventName, listener);\n this._listeners.push([eventName, listener]);\n }\n\n updateURLState();\n }\n\n stop(): void {\n if (typeof window === 'undefined') return;\n\n for (const [eventName, listener] of this._listeners) {\n window.removeEventListener(eventName, listener);\n }\n this._listeners = [];\n\n if (this._originalPushState) {\n history.pushState = this._originalPushState;\n this._originalPushState = null;\n }\n if (this._originalReplaceState) {\n history.replaceState = this._originalReplaceState;\n this._originalReplaceState = null;\n }\n }\n}\n"],"mappings":";;;;;;;;;;AASA,IAAa,kBAAb,MAA6B;
|
|
1
|
+
{"version":3,"file":"UrlStateManager.cjs","names":[],"sources":["../../../src/core/UrlStateManager.ts"],"sourcesContent":["import { MessageKey } from '../messageKey';\nimport type { CrossFrameMessenger } from './CrossFrameMessenger';\n\n/**\n * UrlStateManager patches window.history and broadcasts URL path changes\n * across frames via postMessage.\n *\n * Replaces useCrossURLPathSetter / useCrossURLPathState across all frameworks.\n */\nexport class UrlStateManager {\n private readonly _messenger: CrossFrameMessenger;\n private _originalPushState: typeof history.pushState | null = null;\n private _originalReplaceState: typeof history.replaceState | null = null;\n private _listeners: Array<[string, EventListener]> = [];\n\n constructor(messenger: CrossFrameMessenger) {\n this._messenger = messenger;\n }\n\n start(): void {\n if (typeof window === 'undefined') return;\n\n const updateURLState = () => {\n this._messenger.send(\n `${MessageKey.INTLAYER_URL_CHANGE}/post`,\n window.location.pathname\n );\n };\n\n this._originalPushState = history.pushState;\n this._originalReplaceState = history.replaceState;\n\n const injectLocationChange = (method: typeof history.pushState) =>\n function (\n this: typeof history,\n ...args: Parameters<typeof history.pushState>\n ) {\n method.apply(this, args);\n window.dispatchEvent(new Event('locationchange'));\n };\n\n history.pushState = injectLocationChange(\n this._originalPushState\n ) as typeof history.pushState;\n history.replaceState = injectLocationChange(\n this._originalReplaceState\n ) as typeof history.replaceState;\n\n for (const eventName of [\n 'locationchange',\n 'popstate',\n 'hashchange',\n 'load',\n ] as const) {\n const listener = updateURLState as EventListener;\n window.addEventListener(eventName, listener);\n this._listeners.push([eventName, listener]);\n }\n\n updateURLState();\n }\n\n stop(): void {\n if (typeof window === 'undefined') return;\n\n for (const [eventName, listener] of this._listeners) {\n window.removeEventListener(eventName, listener);\n }\n this._listeners = [];\n\n if (this._originalPushState) {\n history.pushState = this._originalPushState;\n this._originalPushState = null;\n }\n if (this._originalReplaceState) {\n history.replaceState = this._originalReplaceState;\n this._originalReplaceState = null;\n }\n }\n}\n"],"mappings":";;;;;;;;;;AASA,IAAa,kBAAb,MAA6B;CAC3B,AAAiB;CACjB,AAAQ,qBAAsD;CAC9D,AAAQ,wBAA4D;CACpE,AAAQ,aAA6C,EAAE;CAEvD,YAAY,WAAgC;AAC1C,OAAK,aAAa;;CAGpB,QAAc;AACZ,MAAI,OAAO,WAAW,YAAa;EAEnC,MAAM,uBAAuB;AAC3B,QAAK,WAAW,KACd,yBAAkC,QAClC,OAAO,SAAS,SACjB;;AAGH,OAAK,qBAAqB,QAAQ;AAClC,OAAK,wBAAwB,QAAQ;EAErC,MAAM,wBAAwB,WAC5B,SAEE,GAAG,MACH;AACA,UAAO,MAAM,MAAM,KAAK;AACxB,UAAO,cAAc,IAAI,MAAM,iBAAiB,CAAC;;AAGrD,UAAQ,YAAY,qBAClB,KAAK,mBACN;AACD,UAAQ,eAAe,qBACrB,KAAK,sBACN;AAED,OAAK,MAAM,aAAa;GACtB;GACA;GACA;GACA;GACD,EAAW;GACV,MAAM,WAAW;AACjB,UAAO,iBAAiB,WAAW,SAAS;AAC5C,QAAK,WAAW,KAAK,CAAC,WAAW,SAAS,CAAC;;AAG7C,kBAAgB;;CAGlB,OAAa;AACX,MAAI,OAAO,WAAW,YAAa;AAEnC,OAAK,MAAM,CAAC,WAAW,aAAa,KAAK,WACvC,QAAO,oBAAoB,WAAW,SAAS;AAEjD,OAAK,aAAa,EAAE;AAEpB,MAAI,KAAK,oBAAoB;AAC3B,WAAQ,YAAY,KAAK;AACzB,QAAK,qBAAqB;;AAE5B,MAAI,KAAK,uBAAuB;AAC9B,WAAQ,eAAe,KAAK;AAC5B,QAAK,wBAAwB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"globalManager.cjs","names":[],"sources":["../../../src/core/globalManager.ts"],"sourcesContent":["import type { EditorStateManager } from './EditorStateManager';\n\n/**\n * Type for storing custom properties on the global window object.\n * Used to safely attach singleton instances across multiple module instances.\n */\ntype WindowWithEditorGlobals = typeof window & {\n [MANAGER_KEY]?: EditorStateManager | null;\n [EVENTS_KEY]?: EventTarget;\n [key: string]: unknown;\n};\n\n/**\n * Keys on window used to share the singleton across multiple module instances.\n * When bundlers include @intlayer/editor more than once (e.g. framework package +\n * app), each copy has its own module-level variables. Using window ensures they\n * all read/write the same manager and event-target.\n */\nconst MANAGER_KEY = '__intlayer_editor_manager__';\nconst EVENTS_KEY = '__intlayer_editor_manager_events__';\n\n/**\n * Retrieves or creates a shared EventTarget for global editor manager events.\n * In browser environments, stores the EventTarget on window to ensure sharing\n * across multiple module instances. In SSR environments, creates a fresh\n * EventTarget (no sharing needed on server-side).\n *\n * @returns The shared EventTarget instance for dispatching manager change events\n * @private\n */\nconst getEventTarget = (): EventTarget => {\n if (typeof window === 'undefined') {\n // SSR fallback — create a fresh one (no sharing needed server-side)\n return new EventTarget();\n }\n\n const windowGlobals = window as WindowWithEditorGlobals;\n if (!windowGlobals[EVENTS_KEY]) {\n windowGlobals[EVENTS_KEY] = new EventTarget();\n }\n\n return windowGlobals[EVENTS_KEY] as EventTarget;\n};\n\n/**\n * Retrieves the global editor state manager instance.\n * Returns null if no manager has been set or in SSR environments where\n * window is undefined.\n *\n * @returns The global EditorStateManager instance or null if not set\n */\nexport const getGlobalEditorManager = (): EditorStateManager | null => {\n if (typeof window === 'undefined') {\n return null;\n }\n\n const windowGlobals = window as WindowWithEditorGlobals;\n const manager = windowGlobals[MANAGER_KEY];\n\n return manager ?? null;\n};\n\n/**\n * Sets the global editor state manager instance and notifies all listeners\n * of the change through a CustomEvent.\n *\n * @param manager - The EditorStateManager instance to set globally, or null to clear it\n */\nexport const setGlobalEditorManager = (\n manager: EditorStateManager | null\n): void => {\n if (typeof window !== 'undefined') {\n const windowGlobals = window as WindowWithEditorGlobals;\n windowGlobals[MANAGER_KEY] = manager;\n }\n\n const eventTarget = getEventTarget();\n\n eventTarget.dispatchEvent(\n new CustomEvent<EditorStateManager | null>('change', { detail: manager })\n );\n};\n\n/**\n * Registers a callback function to be invoked whenever the global editor\n * manager changes. Useful for reactive updates across the application.\n *\n * @param changeCallback - Function to invoke with the new manager state whenever it changes\n * @returns An unsubscribe function that removes the listener when called\n *\n * @example\n * ```typescript\n * const unsubscribe = onGlobalEditorManagerChange((manager) => {\n * console.log('Manager updated:', manager);\n * });\n *\n * // Later, clean up the listener\n * unsubscribe();\n * ```\n */\nexport const onGlobalEditorManagerChange = (\n changeCallback: (manager: EditorStateManager | null) => void\n): (() => void) => {\n const eventTarget = getEventTarget();\n\n const eventHandler = (event: Event) => {\n const customEvent = event as CustomEvent<EditorStateManager | null>;\n changeCallback(customEvent.detail);\n };\n\n eventTarget.addEventListener('change', eventHandler);\n\n return () => {\n eventTarget.removeEventListener('change', eventHandler);\n };\n};\n"],"mappings":";;;;;;;;;AAkBA,MAAM,cAAc;AACpB,MAAM,aAAa;;;;;;;;;;AAWnB,MAAM,uBAAoC;AACxC,KAAI,OAAO,WAAW,YAEpB,QAAO,IAAI,aAAa;CAG1B,MAAM,gBAAgB;AACtB,KAAI,CAAC,cAAc,YACjB,eAAc,cAAc,IAAI,aAAa;AAG/C,QAAO,cAAc;;;;;;;;;AAUvB,MAAa,+BAA0D;AACrE,KAAI,OAAO,WAAW,YACpB,QAAO;AAMT,
|
|
1
|
+
{"version":3,"file":"globalManager.cjs","names":["windowGlobals","customEvent"],"sources":["../../../src/core/globalManager.ts"],"sourcesContent":["import type { EditorStateManager } from './EditorStateManager';\n\n/**\n * Type for storing custom properties on the global window object.\n * Used to safely attach singleton instances across multiple module instances.\n */\ntype WindowWithEditorGlobals = typeof window & {\n [MANAGER_KEY]?: EditorStateManager | null;\n [EVENTS_KEY]?: EventTarget;\n [key: string]: unknown;\n};\n\n/**\n * Keys on window used to share the singleton across multiple module instances.\n * When bundlers include @intlayer/editor more than once (e.g. framework package +\n * app), each copy has its own module-level variables. Using window ensures they\n * all read/write the same manager and event-target.\n */\nconst MANAGER_KEY = '__intlayer_editor_manager__';\nconst EVENTS_KEY = '__intlayer_editor_manager_events__';\n\n/**\n * Retrieves or creates a shared EventTarget for global editor manager events.\n * In browser environments, stores the EventTarget on window to ensure sharing\n * across multiple module instances. In SSR environments, creates a fresh\n * EventTarget (no sharing needed on server-side).\n *\n * @returns The shared EventTarget instance for dispatching manager change events\n * @private\n */\nconst getEventTarget = (): EventTarget => {\n if (typeof window === 'undefined') {\n // SSR fallback — create a fresh one (no sharing needed server-side)\n return new EventTarget();\n }\n\n const windowGlobals = window as WindowWithEditorGlobals;\n if (!windowGlobals[EVENTS_KEY]) {\n windowGlobals[EVENTS_KEY] = new EventTarget();\n }\n\n return windowGlobals[EVENTS_KEY] as EventTarget;\n};\n\n/**\n * Retrieves the global editor state manager instance.\n * Returns null if no manager has been set or in SSR environments where\n * window is undefined.\n *\n * @returns The global EditorStateManager instance or null if not set\n */\nexport const getGlobalEditorManager = (): EditorStateManager | null => {\n if (typeof window === 'undefined') {\n return null;\n }\n\n const windowGlobals = window as WindowWithEditorGlobals;\n const manager = windowGlobals[MANAGER_KEY];\n\n return manager ?? null;\n};\n\n/**\n * Sets the global editor state manager instance and notifies all listeners\n * of the change through a CustomEvent.\n *\n * @param manager - The EditorStateManager instance to set globally, or null to clear it\n */\nexport const setGlobalEditorManager = (\n manager: EditorStateManager | null\n): void => {\n if (typeof window !== 'undefined') {\n const windowGlobals = window as WindowWithEditorGlobals;\n windowGlobals[MANAGER_KEY] = manager;\n }\n\n const eventTarget = getEventTarget();\n\n eventTarget.dispatchEvent(\n new CustomEvent<EditorStateManager | null>('change', { detail: manager })\n );\n};\n\n/**\n * Registers a callback function to be invoked whenever the global editor\n * manager changes. Useful for reactive updates across the application.\n *\n * @param changeCallback - Function to invoke with the new manager state whenever it changes\n * @returns An unsubscribe function that removes the listener when called\n *\n * @example\n * ```typescript\n * const unsubscribe = onGlobalEditorManagerChange((manager) => {\n * console.log('Manager updated:', manager);\n * });\n *\n * // Later, clean up the listener\n * unsubscribe();\n * ```\n */\nexport const onGlobalEditorManagerChange = (\n changeCallback: (manager: EditorStateManager | null) => void\n): (() => void) => {\n const eventTarget = getEventTarget();\n\n const eventHandler = (event: Event) => {\n const customEvent = event as CustomEvent<EditorStateManager | null>;\n changeCallback(customEvent.detail);\n };\n\n eventTarget.addEventListener('change', eventHandler);\n\n return () => {\n eventTarget.removeEventListener('change', eventHandler);\n };\n};\n"],"mappings":";;;;;;;;;AAkBA,MAAM,cAAc;AACpB,MAAM,aAAa;;;;;;;;;;AAWnB,MAAM,uBAAoC;AACxC,KAAI,OAAO,WAAW,YAEpB,QAAO,IAAI,aAAa;CAG1B,MAAM,gBAAgB;AACtB,KAAI,CAAC,cAAc,YACjB,eAAc,cAAc,IAAI,aAAa;AAG/C,QAAO,cAAc;;;;;;;;;AAUvB,MAAa,+BAA0D;AACrE,KAAI,OAAO,WAAW,YACpB,QAAO;AAMT,QAFgBA,OAAc,gBAEZ;;;;;;;;AASpB,MAAa,0BACX,YACS;AACT,KAAI,OAAO,WAAW,aAAa;EACjC,MAAM,gBAAgB;AACtB,gBAAc,eAAe;;AAK/B,CAFoB,gBAET,CAAC,cACV,IAAI,YAAuC,UAAU,EAAE,QAAQ,SAAS,CAAC,CAC1E;;;;;;;;;;;;;;;;;;;AAoBH,MAAa,+BACX,mBACiB;CACjB,MAAM,cAAc,gBAAgB;CAEpC,MAAM,gBAAgB,UAAiB;AAErC,iBAAeC,MAAY,OAAO;;AAGpC,aAAY,iBAAiB,UAAU,aAAa;AAEpD,cAAa;AACX,cAAY,oBAAoB,UAAU,aAAa"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"initEditorClient.cjs","names":["editor","getGlobalEditorManager","EditorStateManager"],"sources":["../../../src/core/initEditorClient.ts"],"sourcesContent":["import { default as configuration, editor } from '@intlayer/config/built';\nimport { defineIntlayerElements } from '../components';\nimport type { MessengerConfig } from './CrossFrameMessenger';\nimport { EditorStateManager } from './EditorStateManager';\nimport {\n getGlobalEditorManager,\n setGlobalEditorManager,\n} from './globalManager';\n\nexport const buildClientMessengerConfig = (): MessengerConfig => {\n return {\n allowedOrigins: [editor?.editorURL, editor?.cmsURL].filter(\n Boolean\n ) as string[],\n postMessageFn: (payload: unknown, origin: string) => {\n if (typeof window === 'undefined') return;\n\n const isInIframe = window.self !== window.top;\n\n if (!isInIframe) return;\n window.parent?.postMessage(payload, origin);\n },\n };\n};\n\n/** Reference count — tracks how many providers have called initEditorClient. */\nlet _clientRefCount = 0;\n\n/**\n * Initialize the Intlayer editor client singleton.\n * Safe to call multiple times — returns the existing manager if already initialized.\n * Increments a reference counter so nested providers don't destroy the manager\n * prematurely when the inner provider unmounts.\n */\nexport const initEditorClient = (): EditorStateManager => {\n _clientRefCount++;\n\n const existing = getGlobalEditorManager();\n if (existing) return existing;\n\n const manager = new EditorStateManager({\n mode: 'client',\n messenger: buildClientMessengerConfig(),\n configuration,\n });\n\n setGlobalEditorManager(manager);\n defineIntlayerElements();\n manager.start();\n\n return manager;\n};\n\n/**\n * Decrement the reference count and stop the global editor client singleton\n * only when the last provider unmounts.\n */\nexport const stopEditorClient = (): void => {\n _clientRefCount = Math.max(0, _clientRefCount - 1);\n\n if (_clientRefCount > 0) return;\n\n const manager = getGlobalEditorManager();\n manager?.stop();\n setGlobalEditorManager(null);\n};\n"],"mappings":";;;;;;;;;AASA,MAAa,mCAAoD;AAC/D,QAAO;EACL,gBAAgB,CAACA,+BAAQ,WAAWA,+BAAQ,OAAO,CAAC,OAClD,QACD;EACD,gBAAgB,SAAkB,WAAmB;AACnD,OAAI,OAAO,WAAW,YAAa;AAInC,OAAI,EAFe,OAAO,SAAS,OAAO,KAEzB;AACjB,UAAO,QAAQ,YAAY,SAAS,OAAO;;EAE9C;;;AAIH,IAAI,kBAAkB;;;;;;;AAQtB,MAAa,yBAA6C;AACxD;CAEA,MAAM,WAAWC,mDAAwB;AACzC,KAAI,SAAU,QAAO;CAErB,MAAM,UAAU,IAAIC,mDAAmB;EACrC,MAAM;EACN,WAAW,4BAA4B;EACvC;EACD,CAAC;AAEF,mDAAuB,QAAQ;AAC/B,4DAAwB;AACxB,SAAQ,OAAO;AAEf,QAAO;;;;;;AAOT,MAAa,yBAA+B;AAC1C,mBAAkB,KAAK,IAAI,GAAG,kBAAkB,EAAE;AAElD,KAAI,kBAAkB,EAAG;AAGzB,CADgBD,
|
|
1
|
+
{"version":3,"file":"initEditorClient.cjs","names":["editor","getGlobalEditorManager","EditorStateManager"],"sources":["../../../src/core/initEditorClient.ts"],"sourcesContent":["import { default as configuration, editor } from '@intlayer/config/built';\nimport { defineIntlayerElements } from '../components';\nimport type { MessengerConfig } from './CrossFrameMessenger';\nimport { EditorStateManager } from './EditorStateManager';\nimport {\n getGlobalEditorManager,\n setGlobalEditorManager,\n} from './globalManager';\n\nexport const buildClientMessengerConfig = (): MessengerConfig => {\n return {\n allowedOrigins: [editor?.editorURL, editor?.cmsURL].filter(\n Boolean\n ) as string[],\n postMessageFn: (payload: unknown, origin: string) => {\n if (typeof window === 'undefined') return;\n\n const isInIframe = window.self !== window.top;\n\n if (!isInIframe) return;\n window.parent?.postMessage(payload, origin);\n },\n };\n};\n\n/** Reference count — tracks how many providers have called initEditorClient. */\nlet _clientRefCount = 0;\n\n/**\n * Initialize the Intlayer editor client singleton.\n * Safe to call multiple times — returns the existing manager if already initialized.\n * Increments a reference counter so nested providers don't destroy the manager\n * prematurely when the inner provider unmounts.\n */\nexport const initEditorClient = (): EditorStateManager => {\n _clientRefCount++;\n\n const existing = getGlobalEditorManager();\n if (existing) return existing;\n\n const manager = new EditorStateManager({\n mode: 'client',\n messenger: buildClientMessengerConfig(),\n configuration,\n });\n\n setGlobalEditorManager(manager);\n defineIntlayerElements();\n manager.start();\n\n return manager;\n};\n\n/**\n * Decrement the reference count and stop the global editor client singleton\n * only when the last provider unmounts.\n */\nexport const stopEditorClient = (): void => {\n _clientRefCount = Math.max(0, _clientRefCount - 1);\n\n if (_clientRefCount > 0) return;\n\n const manager = getGlobalEditorManager();\n manager?.stop();\n setGlobalEditorManager(null);\n};\n"],"mappings":";;;;;;;;;AASA,MAAa,mCAAoD;AAC/D,QAAO;EACL,gBAAgB,CAACA,+BAAQ,WAAWA,+BAAQ,OAAO,CAAC,OAClD,QACD;EACD,gBAAgB,SAAkB,WAAmB;AACnD,OAAI,OAAO,WAAW,YAAa;AAInC,OAAI,EAFe,OAAO,SAAS,OAAO,KAEzB;AACjB,UAAO,QAAQ,YAAY,SAAS,OAAO;;EAE9C;;;AAIH,IAAI,kBAAkB;;;;;;;AAQtB,MAAa,yBAA6C;AACxD;CAEA,MAAM,WAAWC,mDAAwB;AACzC,KAAI,SAAU,QAAO;CAErB,MAAM,UAAU,IAAIC,mDAAmB;EACrC,MAAM;EACN,WAAW,4BAA4B;EACvC;EACD,CAAC;AAEF,mDAAuB,QAAQ;AAC/B,4DAAwB;AACxB,SAAQ,OAAO;AAEf,QAAO;;;;;;AAOT,MAAa,yBAA+B;AAC1C,mBAAkB,KAAK,IAAI,GAAG,kBAAkB,EAAE;AAElD,KAAI,kBAAkB,EAAG;AAGzB,CADgBD,mDACT,EAAE,MAAM;AACf,mDAAuB,KAAK"}
|
|
@@ -1,20 +1,37 @@
|
|
|
1
|
-
import { __decorate } from "../_virtual/_@oxc-project_runtime@0.126.0/helpers/decorate.mjs";
|
|
2
1
|
import { defineIntlayerContentSelectorWrapper } from "./ContentSelectorWrapper.mjs";
|
|
3
2
|
import { defineIntlayerEditedContent } from "./EditedContent.mjs";
|
|
4
3
|
import { defineIntlayerEditorElement } from "./IntlayerEditor.mjs";
|
|
5
|
-
import { LitElement, css, html } from "lit";
|
|
6
|
-
import { property, query, state } from "lit/decorators.js";
|
|
7
4
|
|
|
8
5
|
//#region src/components/ContentSelector.ts
|
|
9
6
|
const DEFAULT_PRESS_DURATION = 250;
|
|
7
|
+
const STYLES = `
|
|
8
|
+
:host {
|
|
9
|
+
display: contents;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.wrapper {
|
|
13
|
+
display: inline-block;
|
|
14
|
+
cursor: pointer;
|
|
15
|
+
user-select: none;
|
|
16
|
+
border-radius: 0.375rem;
|
|
17
|
+
outline-width: 2px;
|
|
18
|
+
outline-offset: 4px;
|
|
19
|
+
outline-style: solid;
|
|
20
|
+
outline-color: transparent;
|
|
21
|
+
transition: all 100ms 50ms ease-in-out;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.wrapper[data-active] {
|
|
25
|
+
outline-color: inherit;
|
|
26
|
+
}
|
|
27
|
+
`;
|
|
28
|
+
const _HTMLElement = typeof HTMLElement !== "undefined" ? HTMLElement : class {};
|
|
10
29
|
/**
|
|
11
30
|
* <intlayer-content-selector>
|
|
12
31
|
*
|
|
13
32
|
* A framework-agnostic web component that wraps content with Intlayer editor
|
|
14
33
|
* selection UI (hover outline, long-press to select, click-outside to deselect).
|
|
15
34
|
*
|
|
16
|
-
* Replaces the per-framework ContentSelector components (React, Svelte, Vue, Solid).
|
|
17
|
-
*
|
|
18
35
|
* @fires intlayer:press - Fired after a long press (pressDuration ms). Bubbles.
|
|
19
36
|
* @fires intlayer:hover - Fired on mouseenter. Bubbles.
|
|
20
37
|
* @fires intlayer:unhover - Fired on mouseleave / mouseup. Bubbles.
|
|
@@ -23,57 +40,80 @@ const DEFAULT_PRESS_DURATION = 250;
|
|
|
23
40
|
* @prop {boolean} isSelecting - Whether this element is currently selected (external state)
|
|
24
41
|
* @prop {number} pressDuration - Long-press threshold in ms. Default: 250
|
|
25
42
|
*/
|
|
26
|
-
var IntlayerContentSelectorElement = class extends
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
43
|
+
var IntlayerContentSelectorElement = class extends _HTMLElement {
|
|
44
|
+
_isSelecting = false;
|
|
45
|
+
_pressDuration = DEFAULT_PRESS_DURATION;
|
|
46
|
+
_isHovered = false;
|
|
47
|
+
_isSelectingState = false;
|
|
48
|
+
_wrapper;
|
|
49
|
+
_pressTimer = null;
|
|
50
|
+
_clickOutsideHandler = null;
|
|
51
|
+
static get observedAttributes() {
|
|
52
|
+
return ["is-selecting", "press-duration"];
|
|
53
|
+
}
|
|
54
|
+
get isSelecting() {
|
|
55
|
+
return this._isSelecting;
|
|
56
|
+
}
|
|
57
|
+
set isSelecting(v) {
|
|
58
|
+
this._isSelecting = v;
|
|
59
|
+
this._updateActiveState();
|
|
60
|
+
}
|
|
61
|
+
get pressDuration() {
|
|
62
|
+
return this._pressDuration;
|
|
63
|
+
}
|
|
64
|
+
set pressDuration(v) {
|
|
65
|
+
this._pressDuration = v;
|
|
66
|
+
}
|
|
67
|
+
constructor() {
|
|
68
|
+
super();
|
|
69
|
+
const shadow = this.attachShadow({ mode: "open" });
|
|
70
|
+
const style = document.createElement("style");
|
|
71
|
+
style.textContent = STYLES;
|
|
72
|
+
shadow.appendChild(style);
|
|
73
|
+
const wrapper = document.createElement("span");
|
|
74
|
+
wrapper.className = "wrapper";
|
|
75
|
+
wrapper.setAttribute("role", "button");
|
|
76
|
+
wrapper.setAttribute("tabindex", "0");
|
|
77
|
+
wrapper.appendChild(document.createElement("slot"));
|
|
78
|
+
shadow.appendChild(wrapper);
|
|
79
|
+
this._wrapper = wrapper;
|
|
80
|
+
wrapper.addEventListener("mousedown", () => this._handleMouseDown());
|
|
81
|
+
wrapper.addEventListener("mouseup", () => this._handleMouseUpOrLeave());
|
|
82
|
+
wrapper.addEventListener("mouseleave", () => this._handleMouseUpOrLeave());
|
|
83
|
+
wrapper.addEventListener("mouseenter", () => this._handleMouseEnter());
|
|
84
|
+
wrapper.addEventListener("click", (e) => this._handleClick(e));
|
|
85
|
+
wrapper.addEventListener("touchstart", () => this._handleMouseDown());
|
|
86
|
+
wrapper.addEventListener("touchend", () => this._handleMouseUpOrLeave());
|
|
87
|
+
wrapper.addEventListener("touchcancel", () => this._handleMouseUpOrLeave());
|
|
88
|
+
wrapper.addEventListener("blur", () => this._handleBlur());
|
|
89
|
+
}
|
|
90
|
+
attributeChangedCallback(name, _oldVal, newVal) {
|
|
91
|
+
if (name === "is-selecting") {
|
|
92
|
+
this._isSelecting = newVal !== null;
|
|
93
|
+
this._updateActiveState();
|
|
94
|
+
} else if (name === "press-duration") this._pressDuration = newVal !== null ? parseInt(newVal, 10) : DEFAULT_PRESS_DURATION;
|
|
58
95
|
}
|
|
59
96
|
connectedCallback() {
|
|
60
|
-
super.connectedCallback();
|
|
61
97
|
this._clickOutsideHandler = (e) => {
|
|
62
98
|
if (!e.composedPath().includes(this)) {
|
|
63
99
|
this._isSelectingState = false;
|
|
64
100
|
this._dispatch("intlayer:click-outside");
|
|
101
|
+
this._updateActiveState();
|
|
65
102
|
}
|
|
66
103
|
};
|
|
67
104
|
document.addEventListener("mousedown", this._clickOutsideHandler);
|
|
68
105
|
}
|
|
69
106
|
disconnectedCallback() {
|
|
70
|
-
super.disconnectedCallback();
|
|
71
107
|
if (this._clickOutsideHandler) {
|
|
72
108
|
document.removeEventListener("mousedown", this._clickOutsideHandler);
|
|
73
109
|
this._clickOutsideHandler = null;
|
|
74
110
|
}
|
|
75
111
|
this._clearPressTimer();
|
|
76
112
|
}
|
|
113
|
+
_updateActiveState() {
|
|
114
|
+
if (this._isSelecting || this._isSelectingState || this._isHovered) this._wrapper.setAttribute("data-active", "");
|
|
115
|
+
else this._wrapper.removeAttribute("data-active");
|
|
116
|
+
}
|
|
77
117
|
_clearPressTimer() {
|
|
78
118
|
if (this._pressTimer !== null) {
|
|
79
119
|
clearTimeout(this._pressTimer);
|
|
@@ -90,11 +130,13 @@ var IntlayerContentSelectorElement = class extends LitElement {
|
|
|
90
130
|
this._clearPressTimer();
|
|
91
131
|
this._pressTimer = setTimeout(() => {
|
|
92
132
|
this._isSelectingState = true;
|
|
133
|
+
this._updateActiveState();
|
|
93
134
|
this._dispatch("intlayer:press");
|
|
94
|
-
}, this.
|
|
135
|
+
}, this._pressDuration);
|
|
95
136
|
}
|
|
96
137
|
_handleMouseEnter() {
|
|
97
138
|
this._isHovered = true;
|
|
139
|
+
this._updateActiveState();
|
|
98
140
|
this._dispatch("intlayer:hover");
|
|
99
141
|
}
|
|
100
142
|
_handleMouseUpOrLeave() {
|
|
@@ -103,50 +145,19 @@ var IntlayerContentSelectorElement = class extends LitElement {
|
|
|
103
145
|
this._dispatch("intlayer:unhover");
|
|
104
146
|
}
|
|
105
147
|
this._clearPressTimer();
|
|
148
|
+
this._updateActiveState();
|
|
106
149
|
}
|
|
107
150
|
_handleClick(e) {
|
|
108
|
-
if (this.
|
|
151
|
+
if (this._isSelecting || this._isSelectingState) {
|
|
109
152
|
e.preventDefault();
|
|
110
153
|
e.stopPropagation();
|
|
111
154
|
}
|
|
112
155
|
}
|
|
113
156
|
_handleBlur() {
|
|
114
157
|
this._isSelectingState = false;
|
|
115
|
-
|
|
116
|
-
render() {
|
|
117
|
-
return html`
|
|
118
|
-
<span
|
|
119
|
-
class="wrapper"
|
|
120
|
-
?data-active=${this.isSelecting || this._isSelectingState || this._isHovered}
|
|
121
|
-
role="button"
|
|
122
|
-
tabindex="0"
|
|
123
|
-
@mousedown=${this._handleMouseDown}
|
|
124
|
-
@mouseup=${this._handleMouseUpOrLeave}
|
|
125
|
-
@mouseleave=${this._handleMouseUpOrLeave}
|
|
126
|
-
@mouseenter=${this._handleMouseEnter}
|
|
127
|
-
@click=${this._handleClick}
|
|
128
|
-
@touchstart=${this._handleMouseDown}
|
|
129
|
-
@touchend=${this._handleMouseUpOrLeave}
|
|
130
|
-
@touchcancel=${this._handleMouseUpOrLeave}
|
|
131
|
-
@blur=${this._handleBlur}
|
|
132
|
-
@keyup=${() => {}}
|
|
133
|
-
>
|
|
134
|
-
<slot></slot>
|
|
135
|
-
</span>
|
|
136
|
-
`;
|
|
158
|
+
this._updateActiveState();
|
|
137
159
|
}
|
|
138
160
|
};
|
|
139
|
-
__decorate([property({
|
|
140
|
-
type: Boolean,
|
|
141
|
-
attribute: "is-selecting"
|
|
142
|
-
})], IntlayerContentSelectorElement.prototype, "isSelecting", void 0);
|
|
143
|
-
__decorate([property({
|
|
144
|
-
type: Number,
|
|
145
|
-
attribute: "press-duration"
|
|
146
|
-
})], IntlayerContentSelectorElement.prototype, "pressDuration", void 0);
|
|
147
|
-
__decorate([state()], IntlayerContentSelectorElement.prototype, "_isHovered", void 0);
|
|
148
|
-
__decorate([state()], IntlayerContentSelectorElement.prototype, "_isSelectingState", void 0);
|
|
149
|
-
__decorate([query(".wrapper")], IntlayerContentSelectorElement.prototype, "_wrapper", void 0);
|
|
150
161
|
/**
|
|
151
162
|
* Register all Intlayer custom elements.
|
|
152
163
|
* Call this once at application startup (inside IntlayerEditorProvider or similar).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContentSelector.mjs","names":[],"sources":["../../../src/components/ContentSelector.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"ContentSelector.mjs","names":[],"sources":["../../../src/components/ContentSelector.ts"],"sourcesContent":["import { defineIntlayerContentSelectorWrapper } from './ContentSelectorWrapper';\nimport { defineIntlayerEditedContent } from './EditedContent';\nimport { defineIntlayerEditorElement } from './IntlayerEditor';\n\nconst DEFAULT_PRESS_DURATION = 250;\n\nconst STYLES = `\n :host {\n display: contents;\n }\n\n .wrapper {\n display: inline-block;\n cursor: pointer;\n user-select: none;\n border-radius: 0.375rem;\n outline-width: 2px;\n outline-offset: 4px;\n outline-style: solid;\n outline-color: transparent;\n transition: all 100ms 50ms ease-in-out;\n }\n\n .wrapper[data-active] {\n outline-color: inherit;\n }\n`;\n\nconst _HTMLElement =\n typeof HTMLElement !== 'undefined'\n ? HTMLElement\n : (class {} as unknown as typeof HTMLElement);\n\n/**\n * <intlayer-content-selector>\n *\n * A framework-agnostic web component that wraps content with Intlayer editor\n * selection UI (hover outline, long-press to select, click-outside to deselect).\n *\n * @fires intlayer:press - Fired after a long press (pressDuration ms). Bubbles.\n * @fires intlayer:hover - Fired on mouseenter. Bubbles.\n * @fires intlayer:unhover - Fired on mouseleave / mouseup. Bubbles.\n * @fires intlayer:click-outside - Fired when a click occurs outside the element. Bubbles.\n *\n * @prop {boolean} isSelecting - Whether this element is currently selected (external state)\n * @prop {number} pressDuration - Long-press threshold in ms. Default: 250\n */\nexport class IntlayerContentSelectorElement extends _HTMLElement {\n private _isSelecting = false;\n private _pressDuration = DEFAULT_PRESS_DURATION;\n private _isHovered = false;\n private _isSelectingState = false;\n private _wrapper: HTMLSpanElement;\n private _pressTimer: ReturnType<typeof setTimeout> | null = null;\n private _clickOutsideHandler: ((e: MouseEvent) => void) | null = null;\n\n static get observedAttributes(): string[] {\n return ['is-selecting', 'press-duration'];\n }\n\n get isSelecting(): boolean {\n return this._isSelecting;\n }\n set isSelecting(v: boolean) {\n this._isSelecting = v;\n this._updateActiveState();\n }\n\n get pressDuration(): number {\n return this._pressDuration;\n }\n set pressDuration(v: number) {\n this._pressDuration = v;\n }\n\n constructor() {\n super();\n const shadow = this.attachShadow({ mode: 'open' });\n\n const style = document.createElement('style');\n style.textContent = STYLES;\n shadow.appendChild(style);\n\n const wrapper = document.createElement('span');\n wrapper.className = 'wrapper';\n wrapper.setAttribute('role', 'button');\n wrapper.setAttribute('tabindex', '0');\n wrapper.appendChild(document.createElement('slot'));\n shadow.appendChild(wrapper);\n this._wrapper = wrapper;\n\n wrapper.addEventListener('mousedown', () => this._handleMouseDown());\n wrapper.addEventListener('mouseup', () => this._handleMouseUpOrLeave());\n wrapper.addEventListener('mouseleave', () => this._handleMouseUpOrLeave());\n wrapper.addEventListener('mouseenter', () => this._handleMouseEnter());\n wrapper.addEventListener('click', (e) => this._handleClick(e));\n wrapper.addEventListener('touchstart', () => this._handleMouseDown());\n wrapper.addEventListener('touchend', () => this._handleMouseUpOrLeave());\n wrapper.addEventListener('touchcancel', () => this._handleMouseUpOrLeave());\n wrapper.addEventListener('blur', () => this._handleBlur());\n }\n\n attributeChangedCallback(\n name: string,\n _oldVal: string | null,\n newVal: string | null\n ): void {\n if (name === 'is-selecting') {\n this._isSelecting = newVal !== null;\n this._updateActiveState();\n } else if (name === 'press-duration') {\n this._pressDuration =\n newVal !== null ? parseInt(newVal, 10) : DEFAULT_PRESS_DURATION;\n }\n }\n\n connectedCallback(): void {\n this._clickOutsideHandler = (e: MouseEvent) => {\n // composedPath() pierces shadow boundaries\n if (!e.composedPath().includes(this)) {\n this._isSelectingState = false;\n this._dispatch('intlayer:click-outside');\n this._updateActiveState();\n }\n };\n document.addEventListener('mousedown', this._clickOutsideHandler);\n }\n\n disconnectedCallback(): void {\n if (this._clickOutsideHandler) {\n document.removeEventListener('mousedown', this._clickOutsideHandler);\n this._clickOutsideHandler = null;\n }\n this._clearPressTimer();\n }\n\n private _updateActiveState(): void {\n const isActive =\n this._isSelecting || this._isSelectingState || this._isHovered;\n if (isActive) {\n this._wrapper.setAttribute('data-active', '');\n } else {\n this._wrapper.removeAttribute('data-active');\n }\n }\n\n private _clearPressTimer(): void {\n if (this._pressTimer !== null) {\n clearTimeout(this._pressTimer);\n this._pressTimer = null;\n }\n }\n\n private _dispatch(eventName: string): void {\n this.dispatchEvent(\n new CustomEvent(eventName, { bubbles: true, composed: true })\n );\n }\n\n private _handleMouseDown(): void {\n this._clearPressTimer();\n this._pressTimer = setTimeout(() => {\n this._isSelectingState = true;\n this._updateActiveState();\n this._dispatch('intlayer:press');\n }, this._pressDuration);\n }\n\n private _handleMouseEnter(): void {\n this._isHovered = true;\n this._updateActiveState();\n this._dispatch('intlayer:hover');\n }\n\n private _handleMouseUpOrLeave(): void {\n if (this._isHovered) {\n this._isHovered = false;\n this._dispatch('intlayer:unhover');\n }\n this._clearPressTimer();\n this._updateActiveState();\n }\n\n private _handleClick(e: MouseEvent): void {\n if (this._isSelecting || this._isSelectingState) {\n e.preventDefault();\n e.stopPropagation();\n }\n }\n\n private _handleBlur(): void {\n this._isSelectingState = false;\n this._updateActiveState();\n }\n}\n\n/**\n * Register all Intlayer custom elements.\n * Call this once at application startup (inside IntlayerEditorProvider or similar).\n * Safe to call multiple times — only registers elements that are not yet defined.\n */\nexport const defineIntlayerElements = (): void => {\n if (typeof customElements === 'undefined') return;\n if (!customElements.get('intlayer-content-selector')) {\n customElements.define(\n 'intlayer-content-selector',\n IntlayerContentSelectorElement\n );\n }\n defineIntlayerContentSelectorWrapper();\n defineIntlayerEditedContent();\n defineIntlayerEditorElement();\n};\n"],"mappings":"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"}
|
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
import { MessageKey } from "../messageKey.mjs";
|
|
2
2
|
import { getGlobalEditorManager, onGlobalEditorManagerChange } from "../core/globalManager.mjs";
|
|
3
|
-
import { __decorate } from "../_virtual/_@oxc-project_runtime@0.126.0/helpers/decorate.mjs";
|
|
4
|
-
import { LitElement, css, html } from "lit";
|
|
5
|
-
import { property, state } from "lit/decorators.js";
|
|
6
3
|
import { isSameKeyPath } from "@intlayer/core/utils";
|
|
7
4
|
import * as NodeTypes from "@intlayer/types/nodeType";
|
|
8
5
|
|
|
9
6
|
//#region src/components/ContentSelectorWrapper.ts
|
|
7
|
+
const _HTMLElement = typeof HTMLElement !== "undefined" ? HTMLElement : class {};
|
|
10
8
|
/**
|
|
11
9
|
* <intlayer-content-selector-wrapper>
|
|
12
10
|
*
|
|
13
|
-
* Framework-agnostic
|
|
11
|
+
* Framework-agnostic web component that wraps content with the Intlayer editor
|
|
14
12
|
* selection UI. It replaces the per-framework ContentSelectorWrapper components
|
|
15
13
|
* (Vue, Svelte, Solid, Preact).
|
|
16
14
|
*
|
|
@@ -21,42 +19,64 @@ import * as NodeTypes from "@intlayer/types/nodeType";
|
|
|
21
19
|
* @attr {string} key-path - JSON-serialized KeyPath[] for this content node
|
|
22
20
|
* @attr {string} dictionary-key - The dictionary key owning this content node
|
|
23
21
|
*/
|
|
24
|
-
var IntlayerContentSelectorWrapperElement = class extends
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
22
|
+
var IntlayerContentSelectorWrapperElement = class extends _HTMLElement {
|
|
23
|
+
_keyPathJson = "[]";
|
|
24
|
+
_dictionaryKey = "";
|
|
25
|
+
_editorEnabled = false;
|
|
26
|
+
_isInIframe = false;
|
|
27
|
+
_isSelected = false;
|
|
28
|
+
_editedValue = void 0;
|
|
29
|
+
_renderState = null;
|
|
30
|
+
_selector = null;
|
|
31
|
+
_unsubManager = null;
|
|
32
|
+
_unsubEnabled = null;
|
|
33
|
+
_unsubFocused = null;
|
|
34
|
+
_unsubEditedContent = null;
|
|
35
|
+
static get observedAttributes() {
|
|
36
|
+
return ["key-path", "dictionary-key"];
|
|
37
|
+
}
|
|
38
|
+
get keyPathJson() {
|
|
39
|
+
return this._keyPathJson;
|
|
40
|
+
}
|
|
41
|
+
set keyPathJson(v) {
|
|
42
|
+
this._keyPathJson = v;
|
|
43
|
+
const manager = getGlobalEditorManager();
|
|
44
|
+
if (manager) this._updateEditedValue(manager);
|
|
45
|
+
}
|
|
46
|
+
get dictionaryKey() {
|
|
47
|
+
return this._dictionaryKey;
|
|
37
48
|
}
|
|
38
|
-
|
|
39
|
-
this.
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
49
|
+
set dictionaryKey(v) {
|
|
50
|
+
this._dictionaryKey = v;
|
|
51
|
+
const manager = getGlobalEditorManager();
|
|
52
|
+
if (manager) this._updateEditedValue(manager);
|
|
53
|
+
}
|
|
54
|
+
constructor() {
|
|
55
|
+
super();
|
|
56
|
+
const shadow = this.attachShadow({ mode: "open" });
|
|
57
|
+
const style = document.createElement("style");
|
|
58
|
+
style.textContent = ":host { display: contents; }";
|
|
59
|
+
shadow.appendChild(style);
|
|
60
|
+
}
|
|
61
|
+
attributeChangedCallback(name, _oldVal, newVal) {
|
|
62
|
+
if (name === "key-path") {
|
|
63
|
+
this._keyPathJson = newVal ?? "[]";
|
|
64
|
+
const manager = getGlobalEditorManager();
|
|
65
|
+
if (manager) this._updateEditedValue(manager);
|
|
66
|
+
} else if (name === "dictionary-key") {
|
|
67
|
+
this._dictionaryKey = newVal ?? "";
|
|
68
|
+
const manager = getGlobalEditorManager();
|
|
69
|
+
if (manager) this._updateEditedValue(manager);
|
|
70
|
+
}
|
|
44
71
|
}
|
|
45
72
|
connectedCallback() {
|
|
46
|
-
super.connectedCallback();
|
|
47
73
|
if (typeof window !== "undefined") this._isInIframe = window.self !== window.top;
|
|
48
74
|
this._subscribeToManager();
|
|
75
|
+
this._render();
|
|
49
76
|
}
|
|
50
77
|
disconnectedCallback() {
|
|
51
|
-
super.disconnectedCallback();
|
|
52
78
|
this._teardown();
|
|
53
79
|
}
|
|
54
|
-
updated(changedProperties) {
|
|
55
|
-
if (changedProperties.has("keyPathJson") || changedProperties.has("dictionaryKey")) {
|
|
56
|
-
const manager = getGlobalEditorManager();
|
|
57
|
-
if (manager) this._updateEditedValue(manager);
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
80
|
_teardown() {
|
|
61
81
|
this._unsubManager?.();
|
|
62
82
|
this._unsubEnabled?.();
|
|
@@ -67,6 +87,53 @@ var IntlayerContentSelectorWrapperElement = class extends LitElement {
|
|
|
67
87
|
this._unsubFocused = null;
|
|
68
88
|
this._unsubEditedContent = null;
|
|
69
89
|
}
|
|
90
|
+
_getRawKeyPath() {
|
|
91
|
+
try {
|
|
92
|
+
return JSON.parse(this._keyPathJson);
|
|
93
|
+
} catch {
|
|
94
|
+
return [];
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
_getFilteredKeyPath() {
|
|
98
|
+
return this._getRawKeyPath().filter((k) => k.type !== NodeTypes.TRANSLATION);
|
|
99
|
+
}
|
|
100
|
+
_updateEditedValue(manager) {
|
|
101
|
+
const filteredKeyPath = this._getFilteredKeyPath();
|
|
102
|
+
if (!this._dictionaryKey || filteredKeyPath.length === 0) {
|
|
103
|
+
this._editedValue = void 0;
|
|
104
|
+
this._render();
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
const rawKeyPath = this._getRawKeyPath();
|
|
108
|
+
const lastStepType = rawKeyPath[rawKeyPath.length - 1]?.type;
|
|
109
|
+
if (lastStepType === NodeTypes.MARKDOWN || lastStepType === NodeTypes.HTML || lastStepType === NodeTypes.INSERTION || lastStepType === NodeTypes.FILE) {
|
|
110
|
+
this._editedValue = void 0;
|
|
111
|
+
this._render();
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
let value = manager.getContentValue(this._dictionaryKey, filteredKeyPath);
|
|
115
|
+
if (value !== null && value !== void 0 && typeof value === "object" && value.nodeType === NodeTypes.TRANSLATION) {
|
|
116
|
+
const locale = manager.currentLocale.value;
|
|
117
|
+
value = locale ? value[NodeTypes.TRANSLATION][locale] : void 0;
|
|
118
|
+
}
|
|
119
|
+
this._editedValue = value;
|
|
120
|
+
this._render();
|
|
121
|
+
}
|
|
122
|
+
_updateIsSelected(focusedContent) {
|
|
123
|
+
if (!focusedContent) {
|
|
124
|
+
this._isSelected = false;
|
|
125
|
+
this._updateSelectorAttr();
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
const keyPath = this._getFilteredKeyPath();
|
|
129
|
+
this._isSelected = focusedContent.dictionaryKey === this._dictionaryKey && (focusedContent.keyPath?.length ?? 0) > 0 && isSameKeyPath(focusedContent.keyPath ?? [], keyPath);
|
|
130
|
+
this._updateSelectorAttr();
|
|
131
|
+
}
|
|
132
|
+
_updateSelectorAttr() {
|
|
133
|
+
if (!this._selector) return;
|
|
134
|
+
if (this._isSelected) this._selector.setAttribute("is-selecting", "");
|
|
135
|
+
else this._selector.removeAttribute("is-selecting");
|
|
136
|
+
}
|
|
70
137
|
_subscribeToManager() {
|
|
71
138
|
const manager = getGlobalEditorManager();
|
|
72
139
|
if (manager) this._setupManagerSubscriptions(manager);
|
|
@@ -82,6 +149,7 @@ var IntlayerContentSelectorWrapperElement = class extends LitElement {
|
|
|
82
149
|
this._editorEnabled = false;
|
|
83
150
|
this._isSelected = false;
|
|
84
151
|
this._editedValue = void 0;
|
|
152
|
+
this._render();
|
|
85
153
|
}
|
|
86
154
|
});
|
|
87
155
|
}
|
|
@@ -91,6 +159,7 @@ var IntlayerContentSelectorWrapperElement = class extends LitElement {
|
|
|
91
159
|
this._updateEditedValue(manager);
|
|
92
160
|
const handleEnabledChange = (e) => {
|
|
93
161
|
this._editorEnabled = e.detail;
|
|
162
|
+
this._render();
|
|
94
163
|
};
|
|
95
164
|
const handleFocusedChange = (e) => {
|
|
96
165
|
this._updateIsSelected(e.detail);
|
|
@@ -105,56 +174,19 @@ var IntlayerContentSelectorWrapperElement = class extends LitElement {
|
|
|
105
174
|
this._unsubFocused = () => manager.focusedContent.removeEventListener("change", handleFocusedChange);
|
|
106
175
|
this._unsubEditedContent = () => manager.editedContent.removeEventListener("change", handleEditedContentChange);
|
|
107
176
|
}
|
|
108
|
-
_getRawKeyPath() {
|
|
109
|
-
try {
|
|
110
|
-
return JSON.parse(this.keyPathJson);
|
|
111
|
-
} catch {
|
|
112
|
-
return [];
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
_getFilteredKeyPath() {
|
|
116
|
-
return this._getRawKeyPath().filter((k) => k.type !== NodeTypes.TRANSLATION);
|
|
117
|
-
}
|
|
118
|
-
_updateEditedValue(manager) {
|
|
119
|
-
const filteredKeyPath = this._getFilteredKeyPath();
|
|
120
|
-
if (!this.dictionaryKey || filteredKeyPath.length === 0) {
|
|
121
|
-
this._editedValue = void 0;
|
|
122
|
-
return;
|
|
123
|
-
}
|
|
124
|
-
const rawKeyPath = this._getRawKeyPath();
|
|
125
|
-
const lastStepType = rawKeyPath[rawKeyPath.length - 1]?.type;
|
|
126
|
-
if (lastStepType === NodeTypes.MARKDOWN || lastStepType === NodeTypes.HTML || lastStepType === NodeTypes.INSERTION || lastStepType === NodeTypes.FILE) {
|
|
127
|
-
this._editedValue = void 0;
|
|
128
|
-
return;
|
|
129
|
-
}
|
|
130
|
-
let value = manager.getContentValue(this.dictionaryKey, filteredKeyPath);
|
|
131
|
-
if (value !== null && value !== void 0 && typeof value === "object" && value.nodeType === NodeTypes.TRANSLATION) {
|
|
132
|
-
const locale = manager.currentLocale.value;
|
|
133
|
-
value = locale ? value[NodeTypes.TRANSLATION][locale] : void 0;
|
|
134
|
-
}
|
|
135
|
-
this._editedValue = value;
|
|
136
|
-
}
|
|
137
|
-
_updateIsSelected(focusedContent) {
|
|
138
|
-
if (!focusedContent) {
|
|
139
|
-
this._isSelected = false;
|
|
140
|
-
return;
|
|
141
|
-
}
|
|
142
|
-
const keyPath = this._getFilteredKeyPath();
|
|
143
|
-
this._isSelected = focusedContent.dictionaryKey === this.dictionaryKey && (focusedContent.keyPath?.length ?? 0) > 0 && isSameKeyPath(focusedContent.keyPath ?? [], keyPath);
|
|
144
|
-
}
|
|
145
177
|
_handlePress(e) {
|
|
146
178
|
e.stopPropagation();
|
|
147
179
|
const manager = getGlobalEditorManager();
|
|
148
180
|
if (!manager) return;
|
|
149
181
|
manager.focusedContent.set({
|
|
150
|
-
dictionaryKey: this.
|
|
182
|
+
dictionaryKey: this._dictionaryKey,
|
|
151
183
|
keyPath: this._getFilteredKeyPath()
|
|
152
184
|
});
|
|
153
185
|
}
|
|
154
186
|
_handleHover(e) {
|
|
155
187
|
e.stopPropagation();
|
|
156
188
|
getGlobalEditorManager()?.messenger.send(`${"INTLAYER_HOVERED_CONTENT_CHANGED"}/post`, {
|
|
157
|
-
dictionaryKey: this.
|
|
189
|
+
dictionaryKey: this._dictionaryKey,
|
|
158
190
|
keyPath: this._getFilteredKeyPath()
|
|
159
191
|
});
|
|
160
192
|
}
|
|
@@ -162,34 +194,38 @@ var IntlayerContentSelectorWrapperElement = class extends LitElement {
|
|
|
162
194
|
e.stopPropagation();
|
|
163
195
|
getGlobalEditorManager()?.messenger.send(`${"INTLAYER_HOVERED_CONTENT_CHANGED"}/post`, null);
|
|
164
196
|
}
|
|
165
|
-
|
|
166
|
-
|
|
197
|
+
_render() {
|
|
198
|
+
const useWrapper = this._isInIframe && this._editorEnabled;
|
|
167
199
|
const editedValue = this._editedValue;
|
|
168
|
-
const
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
200
|
+
const newState = !useWrapper ? "simple" : typeof editedValue === "string" || typeof editedValue === "number" || typeof editedValue === "boolean" ? "wrapped-text" : "wrapped-slot";
|
|
201
|
+
if (this._renderState !== newState) {
|
|
202
|
+
this._rebuildContent(newState);
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
if (newState !== "simple" && this._selector) {
|
|
206
|
+
this._updateSelectorAttr();
|
|
207
|
+
if (newState === "wrapped-text" && this._selector.firstChild?.nodeType === Node.TEXT_NODE) this._selector.firstChild.data = String(editedValue);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
_rebuildContent(state) {
|
|
211
|
+
const shadow = this.shadowRoot;
|
|
212
|
+
while (shadow.childNodes.length > 1) shadow.removeChild(shadow.lastChild);
|
|
213
|
+
this._selector = null;
|
|
214
|
+
if (state === "simple") shadow.appendChild(document.createElement("slot"));
|
|
215
|
+
else {
|
|
216
|
+
const selector = document.createElement("intlayer-content-selector");
|
|
217
|
+
this._selector = selector;
|
|
218
|
+
if (this._isSelected) selector.setAttribute("is-selecting", "");
|
|
219
|
+
selector.addEventListener("intlayer:press", (e) => this._handlePress(e));
|
|
220
|
+
selector.addEventListener("intlayer:hover", (e) => this._handleHover(e));
|
|
221
|
+
selector.addEventListener("intlayer:unhover", (e) => this._handleUnhover(e));
|
|
222
|
+
if (state === "wrapped-text") selector.appendChild(document.createTextNode(String(this._editedValue)));
|
|
223
|
+
else selector.appendChild(document.createElement("slot"));
|
|
224
|
+
shadow.appendChild(selector);
|
|
225
|
+
}
|
|
226
|
+
this._renderState = state;
|
|
179
227
|
}
|
|
180
228
|
};
|
|
181
|
-
__decorate([property({
|
|
182
|
-
type: String,
|
|
183
|
-
attribute: "key-path"
|
|
184
|
-
})], IntlayerContentSelectorWrapperElement.prototype, "keyPathJson", void 0);
|
|
185
|
-
__decorate([property({
|
|
186
|
-
type: String,
|
|
187
|
-
attribute: "dictionary-key"
|
|
188
|
-
})], IntlayerContentSelectorWrapperElement.prototype, "dictionaryKey", void 0);
|
|
189
|
-
__decorate([state()], IntlayerContentSelectorWrapperElement.prototype, "_editorEnabled", void 0);
|
|
190
|
-
__decorate([state()], IntlayerContentSelectorWrapperElement.prototype, "_isInIframe", void 0);
|
|
191
|
-
__decorate([state()], IntlayerContentSelectorWrapperElement.prototype, "_isSelected", void 0);
|
|
192
|
-
__decorate([state()], IntlayerContentSelectorWrapperElement.prototype, "_editedValue", void 0);
|
|
193
229
|
const defineIntlayerContentSelectorWrapper = () => {
|
|
194
230
|
if (typeof customElements === "undefined") return;
|
|
195
231
|
if (!customElements.get("intlayer-content-selector-wrapper")) customElements.define("intlayer-content-selector-wrapper", IntlayerContentSelectorWrapperElement);
|