@intlayer/editor 8.4.0-canary.0 → 8.4.1
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/{_virtual/_rolldown/runtime.cjs → chunk-Bmb41Sf3.cjs} +1 -1
- package/dist/cjs/components/ContentSelector.cjs +1 -41
- package/dist/cjs/components/ContentSelectorWrapper.cjs +2 -2
- package/dist/cjs/components/ContentSelectorWrapper.cjs.map +1 -1
- package/dist/cjs/components/EditedContent.cjs +2 -2
- package/dist/cjs/components/EditedContent.cjs.map +1 -1
- package/dist/cjs/components/IntlayerEditor.cjs +1 -2
- package/dist/cjs/components/index.cjs +1 -1
- package/dist/cjs/components-DWu35JEb.cjs +41 -0
- package/dist/cjs/components-DWu35JEb.cjs.map +1 -0
- package/dist/cjs/core/EditorStateManager.cjs +1 -1
- package/dist/cjs/core/EditorStateManager.cjs.map +1 -1
- package/dist/cjs/core/index.cjs +1 -1
- package/dist/cjs/core/initEditorClient.cjs +1 -2
- package/dist/{esm/_virtual/_@oxc-project_runtime@0.115.0/helpers/decorate.mjs → cjs/decorate-Bg73f0d3.cjs} +1 -1
- package/dist/cjs/index.cjs +1 -1
- package/dist/cjs/isEnabled.cjs +1 -1
- package/dist/cjs/isEnabled.cjs.map +1 -1
- package/dist/esm/components/ContentSelector.mjs +1 -41
- package/dist/esm/components/ContentSelectorWrapper.mjs +1 -1
- package/dist/esm/components/ContentSelectorWrapper.mjs.map +1 -1
- package/dist/esm/components/EditedContent.mjs +1 -1
- package/dist/esm/components/EditedContent.mjs.map +1 -1
- package/dist/esm/components/IntlayerEditor.mjs +1 -2
- package/dist/esm/components/index.mjs +1 -1
- package/dist/esm/components-RtOXxg9h.mjs +41 -0
- package/dist/esm/components-RtOXxg9h.mjs.map +1 -0
- package/dist/esm/core/index.mjs +1 -1
- package/dist/esm/core/initEditorClient.mjs +1 -2
- package/dist/{cjs/_virtual/_@oxc-project_runtime@0.115.0/helpers/decorate.cjs → esm/decorate-BWURH4oJ.mjs} +1 -1
- package/dist/esm/index.mjs +1 -1
- package/dist/types/ContentSelector-sIfZu4Dd.d.ts +49 -0
- package/dist/types/ContentSelector-sIfZu4Dd.d.ts.map +1 -0
- package/dist/types/ContentSelectorWrapper-CID6anMf.d.ts +49 -0
- package/dist/types/ContentSelectorWrapper-CID6anMf.d.ts.map +1 -0
- package/dist/types/CrossFrameMessenger-CPt3Bu8S.d.ts +51 -0
- package/dist/types/CrossFrameMessenger-CPt3Bu8S.d.ts.map +1 -0
- package/dist/types/CrossFrameStateManager-CW1DPY_Z.d.ts +44 -0
- package/dist/types/CrossFrameStateManager-CW1DPY_Z.d.ts.map +1 -0
- package/dist/types/EditedContent-2kq4wk4R.d.ts +39 -0
- package/dist/types/EditedContent-2kq4wk4R.d.ts.map +1 -0
- package/dist/types/EditorStateManager-Y9j0SYCd.d.ts +73 -0
- package/dist/types/EditorStateManager-Y9j0SYCd.d.ts.map +1 -0
- package/dist/types/IframeClickInterceptor-Cm89LRcI.d.ts +26 -0
- package/dist/types/IframeClickInterceptor-Cm89LRcI.d.ts.map +1 -0
- package/dist/types/IntlayerEditor-ePRSIuBI.d.ts +40 -0
- package/dist/types/IntlayerEditor-ePRSIuBI.d.ts.map +1 -0
- package/dist/types/UrlStateManager-CIOVEeTq.d.ts +21 -0
- package/dist/types/UrlStateManager-CIOVEeTq.d.ts.map +1 -0
- package/dist/types/components/ContentSelector.d.ts +2 -49
- package/dist/types/components/ContentSelectorWrapper.d.ts +2 -49
- package/dist/types/components/EditedContent.d.ts +2 -39
- package/dist/types/components/IntlayerEditor.d.ts +2 -40
- package/dist/types/components/index.d.ts +4 -4
- package/dist/types/core/CrossFrameMessenger.d.ts +2 -51
- package/dist/types/core/CrossFrameStateManager.d.ts +2 -44
- package/dist/types/core/EditorStateManager.d.ts +2 -73
- package/dist/types/core/IframeClickInterceptor.d.ts +2 -26
- package/dist/types/core/UrlStateManager.d.ts +2 -21
- package/dist/types/core/globalManager.d.ts +2 -39
- package/dist/types/core/index.d.ts +7 -7
- package/dist/types/core/initEditorClient.d.ts +2 -20
- package/dist/types/globalManager-BD6UaK_1.d.ts +39 -0
- package/dist/types/globalManager-BD6UaK_1.d.ts.map +1 -0
- package/dist/types/index.d.ts +11 -11
- package/dist/types/initEditorClient-ovRVUf_n.d.ts +20 -0
- package/dist/types/initEditorClient-ovRVUf_n.d.ts.map +1 -0
- package/package.json +6 -9
- package/dist/cjs/components/ContentSelector.cjs.map +0 -1
- package/dist/cjs/components/IntlayerEditor.cjs.map +0 -1
- package/dist/cjs/core/initEditorClient.cjs.map +0 -1
- package/dist/esm/components/ContentSelector.mjs.map +0 -1
- package/dist/esm/components/IntlayerEditor.mjs.map +0 -1
- package/dist/esm/core/initEditorClient.mjs.map +0 -1
- package/dist/types/components/ContentSelector.d.ts.map +0 -1
- package/dist/types/components/ContentSelectorWrapper.d.ts.map +0 -1
- package/dist/types/components/EditedContent.d.ts.map +0 -1
- package/dist/types/components/IntlayerEditor.d.ts.map +0 -1
- package/dist/types/core/CrossFrameMessenger.d.ts.map +0 -1
- package/dist/types/core/CrossFrameStateManager.d.ts.map +0 -1
- package/dist/types/core/EditorStateManager.d.ts.map +0 -1
- package/dist/types/core/IframeClickInterceptor.d.ts.map +0 -1
- package/dist/types/core/UrlStateManager.d.ts.map +0 -1
- package/dist/types/core/globalManager.d.ts.map +0 -1
- package/dist/types/core/initEditorClient.d.ts.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,a)=>(a=n==null?{}:e(i(n)),o(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));exports
|
|
1
|
+
var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,a)=>(a=n==null?{}:e(i(n)),o(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return s}});
|
|
@@ -1,41 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`})
|
|
2
|
-
:host {
|
|
3
|
-
display: contents;
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
.wrapper {
|
|
7
|
-
display: inline-block;
|
|
8
|
-
cursor: pointer;
|
|
9
|
-
user-select: none;
|
|
10
|
-
border-radius: 0.375rem;
|
|
11
|
-
outline-width: 2px;
|
|
12
|
-
outline-offset: 4px;
|
|
13
|
-
outline-style: solid;
|
|
14
|
-
outline-color: transparent;
|
|
15
|
-
transition: all 100ms 50ms ease-in-out;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
.wrapper[data-active] {
|
|
19
|
-
outline-color: inherit;
|
|
20
|
-
}
|
|
21
|
-
`}connectedCallback(){super.connectedCallback(),this._clickOutsideHandler=e=>{e.composedPath().includes(this)||(this._isSelectingState=!1,this._dispatch(`intlayer:click-outside`))},document.addEventListener(`mousedown`,this._clickOutsideHandler)}disconnectedCallback(){super.disconnectedCallback(),this._clickOutsideHandler&&=(document.removeEventListener(`mousedown`,this._clickOutsideHandler),null),this._clearPressTimer()}_clearPressTimer(){this._pressTimer!==null&&(clearTimeout(this._pressTimer),this._pressTimer=null)}_dispatch(e){this.dispatchEvent(new CustomEvent(e,{bubbles:!0,composed:!0}))}_handleMouseDown(){this._clearPressTimer(),this._pressTimer=setTimeout(()=>{this._isSelectingState=!0,this._dispatch(`intlayer:press`)},this.pressDuration)}_handleMouseEnter(){this._isHovered=!0,this._dispatch(`intlayer:hover`)}_handleMouseUpOrLeave(){this._isHovered&&(this._isHovered=!1,this._dispatch(`intlayer:unhover`)),this._clearPressTimer()}_handleClick(e){(this.isSelecting||this._isSelectingState)&&(e.preventDefault(),e.stopPropagation())}_handleBlur(){this._isSelectingState=!1}render(){return i.html`
|
|
22
|
-
<span
|
|
23
|
-
class="wrapper"
|
|
24
|
-
?data-active=${this.isSelecting||this._isSelectingState||this._isHovered}
|
|
25
|
-
role="button"
|
|
26
|
-
tabindex="0"
|
|
27
|
-
@mousedown=${this._handleMouseDown}
|
|
28
|
-
@mouseup=${this._handleMouseUpOrLeave}
|
|
29
|
-
@mouseleave=${this._handleMouseUpOrLeave}
|
|
30
|
-
@mouseenter=${this._handleMouseEnter}
|
|
31
|
-
@click=${this._handleClick}
|
|
32
|
-
@touchstart=${this._handleMouseDown}
|
|
33
|
-
@touchend=${this._handleMouseUpOrLeave}
|
|
34
|
-
@touchcancel=${this._handleMouseUpOrLeave}
|
|
35
|
-
@blur=${this._handleBlur}
|
|
36
|
-
@keyup=${()=>{}}
|
|
37
|
-
>
|
|
38
|
-
<slot></slot>
|
|
39
|
-
</span>
|
|
40
|
-
`}};e.__decorate([(0,a.property)({type:Boolean,attribute:`is-selecting`})],o.prototype,`isSelecting`,void 0),e.__decorate([(0,a.property)({type:Number,attribute:`press-duration`})],o.prototype,`pressDuration`,void 0),e.__decorate([(0,a.state)()],o.prototype,`_isHovered`,void 0),e.__decorate([(0,a.state)()],o.prototype,`_isSelectingState`,void 0),e.__decorate([(0,a.query)(`.wrapper`)],o.prototype,`_wrapper`,void 0);const s=()=>{typeof customElements>`u`||(customElements.get(`intlayer-content-selector`)||customElements.define(`intlayer-content-selector`,o),t.defineIntlayerContentSelectorWrapper(),n.defineIntlayerEditedContent(),r.defineIntlayerEditorElement())};exports.IntlayerContentSelectorElement=o,exports.defineIntlayerElements=s;
|
|
41
|
-
//# sourceMappingURL=ContentSelector.cjs.map
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../components-DWu35JEb.cjs`);exports.IntlayerContentSelectorElement=e.t,exports.defineIntlayerElements=e.n;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../chunk-Bmb41Sf3.cjs`);const e=require(`../messageKey.cjs`),t=require(`../core/globalManager.cjs`),n=require(`../decorate-Bg73f0d3.cjs`);let r=require(`lit`),i=require(`lit/decorators.js`),a=require(`@intlayer/core/utils`),o=require(`@intlayer/types/nodeType`);var s=class extends r.LitElement{constructor(...e){super(...e),this.keyPathJson=`[]`,this.dictionaryKey=``,this._editorEnabled=!1,this._isInIframe=!1,this._isSelected=!1,this._editedValue=void 0,this._unsubManager=null,this._unsubEnabled=null,this._unsubFocused=null,this._unsubEditedContent=null}static{this.styles=r.css`
|
|
2
2
|
:host {
|
|
3
3
|
display: contents;
|
|
4
4
|
}
|
|
@@ -11,5 +11,5 @@ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../_
|
|
|
11
11
|
>
|
|
12
12
|
${t}
|
|
13
13
|
</intlayer-content-selector>
|
|
14
|
-
`}};n.
|
|
14
|
+
`}};n.t([(0,i.property)({type:String,attribute:`key-path`})],s.prototype,`keyPathJson`,void 0),n.t([(0,i.property)({type:String,attribute:`dictionary-key`})],s.prototype,`dictionaryKey`,void 0),n.t([(0,i.state)()],s.prototype,`_editorEnabled`,void 0),n.t([(0,i.state)()],s.prototype,`_isInIframe`,void 0),n.t([(0,i.state)()],s.prototype,`_isSelected`,void 0),n.t([(0,i.state)()],s.prototype,`_editedValue`,void 0);const c=()=>{typeof customElements>`u`||customElements.get(`intlayer-content-selector-wrapper`)||customElements.define(`intlayer-content-selector-wrapper`,s)};exports.IntlayerContentSelectorWrapperElement=s,exports.defineIntlayerContentSelectorWrapper=c;
|
|
15
15
|
//# sourceMappingURL=ContentSelectorWrapper.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContentSelectorWrapper.cjs","names":["LitElement","getGlobalEditorManager","onGlobalEditorManagerChange","NodeType","MessageKey"],"sources":["../../../src/components/ContentSelectorWrapper.ts"],"sourcesContent":["import { isSameKeyPath } from '@intlayer/core/utils';\nimport type { ContentNode } from '@intlayer/types/dictionary';\nimport type { KeyPath } from '@intlayer/types/keyPath';\nimport { NodeType, type TypedNodeModel } from '@intlayer/types/nodeType';\nimport { css, html, LitElement } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport type {\n EditorStateManager,\n FileContent,\n} from '../core/EditorStateManager';\nimport {\n getGlobalEditorManager,\n onGlobalEditorManagerChange,\n} from '../core/globalManager';\nimport { MessageKey } from '../messageKey';\n\n/**\n * <intlayer-content-selector-wrapper>\n *\n * Framework-agnostic Lit element that wraps content with the Intlayer editor\n * selection UI. It replaces the per-framework ContentSelectorWrapper components\n * (Vue, Svelte, Solid, Preact).\n *\n * It reads from the global EditorStateManager singleton (set by initEditorClient)\n * and conditionally renders <intlayer-content-selector> around its slot content\n * when the editor is active and the app is running inside an iframe.\n *\n * @attr {string} key-path - JSON-serialized KeyPath[] for this content node\n * @attr {string} dictionary-key - The dictionary key owning this content node\n */\nexport class IntlayerContentSelectorWrapperElement extends LitElement {\n static styles = css`\n :host {\n display: contents;\n }\n `;\n\n @property({ type: String, attribute: 'key-path' }) keyPathJson = '[]';\n @property({ type: String, attribute: 'dictionary-key' }) dictionaryKey = '';\n\n @state() private _editorEnabled = false;\n @state() private _isInIframe = false;\n @state() private _isSelected = false;\n @state() private _editedValue: ContentNode | undefined = undefined;\n\n private _unsubManager: (() => void) | null = null;\n private _unsubEnabled: (() => void) | null = null;\n private _unsubFocused: (() => void) | null = null;\n private _unsubEditedContent: (() => void) | null = null;\n\n connectedCallback(): void {\n super.connectedCallback();\n if (typeof window !== 'undefined') {\n this._isInIframe = window.self !== window.top;\n }\n this._subscribeToManager();\n }\n\n disconnectedCallback(): void {\n super.disconnectedCallback();\n this._teardown();\n }\n\n updated(changedProperties: Map<string, unknown>): void {\n if (\n changedProperties.has('keyPathJson') ||\n changedProperties.has('dictionaryKey')\n ) {\n const manager = getGlobalEditorManager();\n if (manager) this._updateEditedValue(manager);\n }\n }\n\n private _teardown(): void {\n this._unsubManager?.();\n this._unsubEnabled?.();\n this._unsubFocused?.();\n this._unsubEditedContent?.();\n this._unsubManager = null;\n this._unsubEnabled = null;\n this._unsubFocused = null;\n this._unsubEditedContent = null;\n }\n\n private _subscribeToManager(): void {\n const manager = getGlobalEditorManager();\n if (manager) {\n this._setupManagerSubscriptions(manager);\n }\n // Keep listening for manager changes (handles stop + re-init cycles)\n this._unsubManager = onGlobalEditorManagerChange((m) => {\n this._unsubEnabled?.();\n this._unsubFocused?.();\n this._unsubEditedContent?.();\n this._unsubEnabled = null;\n this._unsubFocused = null;\n this._unsubEditedContent = null;\n if (m) {\n this._setupManagerSubscriptions(m);\n } else {\n this._editorEnabled = false;\n this._isSelected = false;\n this._editedValue = undefined;\n }\n });\n }\n\n private _setupManagerSubscriptions(manager: EditorStateManager): void {\n this._editorEnabled = manager.editorEnabled.value ?? false;\n this._updateIsSelected(manager.focusedContent.value);\n this._updateEditedValue(manager);\n\n const handleEnabledChange = (e: Event) => {\n this._editorEnabled = (e as CustomEvent<boolean>).detail;\n };\n const handleFocusedChange = (e: Event) => {\n this._updateIsSelected((e as CustomEvent<FileContent | null>).detail);\n };\n const handleEditedContentChange = () => {\n this._updateEditedValue(manager);\n };\n\n manager.editorEnabled.addEventListener('change', handleEnabledChange);\n manager.focusedContent.addEventListener('change', handleFocusedChange);\n manager.editedContent.addEventListener('change', handleEditedContentChange);\n\n this._unsubEnabled = () =>\n manager.editorEnabled.removeEventListener('change', handleEnabledChange);\n this._unsubFocused = () =>\n manager.focusedContent.removeEventListener('change', handleFocusedChange);\n this._unsubEditedContent = () =>\n manager.editedContent.removeEventListener(\n 'change',\n handleEditedContentChange\n );\n }\n\n private _getRawKeyPath(): KeyPath[] {\n try {\n return JSON.parse(this.keyPathJson) as KeyPath[];\n } catch {\n return [];\n }\n }\n\n private _getFilteredKeyPath(): KeyPath[] {\n return this._getRawKeyPath().filter((k) => k.type !== NodeType.Translation);\n }\n\n private _updateEditedValue(manager: EditorStateManager): void {\n const filteredKeyPath = this._getFilteredKeyPath();\n if (!this.dictionaryKey || filteredKeyPath.length === 0) {\n this._editedValue = undefined;\n return;\n }\n\n // Node types whose display requires framework-level rendering (markdown,\n // HTML, insertion, file): do not override the slot — the framework handles\n // those. Only plain / translated strings can be substituted here.\n const rawKeyPath = this._getRawKeyPath();\n const lastStepType = rawKeyPath[rawKeyPath.length - 1]?.type;\n if (\n lastStepType === NodeType.Markdown ||\n lastStepType === NodeType.HTML ||\n lastStepType === NodeType.Insertion ||\n lastStepType === NodeType.File\n ) {\n this._editedValue = undefined;\n return;\n }\n\n let value = manager.getContentValue(this.dictionaryKey, filteredKeyPath);\n\n // getContentNodeByKeyPath resolves translation nodes only at intermediate\n // steps, not the final leaf. Resolve manually when the returned value is\n // still a translation object (happens when Translation steps are filtered\n // out and the leaf IS the translation object).\n if (\n value !== null &&\n value !== undefined &&\n typeof value === 'object' &&\n value.nodeType === NodeType.Translation\n ) {\n const locale = manager.currentLocale.value as string | undefined;\n // TypedNodeModel<Translation, …> structurally satisfies TypedNode<BaseNode>\n // (both have nodeType), so this narrowing cast is sound.\n const node = value as TypedNodeModel<\n typeof NodeType.Translation,\n Record<string, ContentNode>\n >;\n value = locale ? node[NodeType.Translation][locale] : undefined;\n }\n\n this._editedValue = value;\n }\n\n private _updateIsSelected(\n focusedContent: FileContent | null | undefined\n ): void {\n if (!focusedContent) {\n this._isSelected = false;\n return;\n }\n const keyPath = this._getFilteredKeyPath();\n this._isSelected =\n focusedContent.dictionaryKey === this.dictionaryKey &&\n (focusedContent.keyPath?.length ?? 0) > 0 &&\n isSameKeyPath(focusedContent.keyPath ?? [], keyPath);\n }\n\n private _handlePress(e: Event): void {\n // Stop propagation so nested wrappers don't also fire (composed + bubbles)\n e.stopPropagation();\n const manager = getGlobalEditorManager();\n if (!manager) return;\n manager.focusedContent.set({\n dictionaryKey: this.dictionaryKey,\n keyPath: this._getFilteredKeyPath(),\n });\n }\n\n private _handleHover(e: Event): void {\n e.stopPropagation();\n getGlobalEditorManager()?.messenger.send(\n `${MessageKey.INTLAYER_HOVERED_CONTENT_CHANGED}/post`,\n { dictionaryKey: this.dictionaryKey, keyPath: this._getFilteredKeyPath() }\n );\n }\n\n private _handleUnhover(e: Event): void {\n e.stopPropagation();\n getGlobalEditorManager()?.messenger.send(\n `${MessageKey.INTLAYER_HOVERED_CONTENT_CHANGED}/post`,\n null\n );\n }\n\n render() {\n if (!this._isInIframe || !this._editorEnabled) {\n return html`<slot></slot>`;\n }\n\n const editedValue = this._editedValue;\n const displayedContent =\n typeof editedValue === 'string' ||\n typeof editedValue === 'number' ||\n typeof editedValue === 'boolean'\n ? editedValue\n : html`<slot></slot>`;\n\n return html`\n <intlayer-content-selector\n ?is-selecting=${this._isSelected}\n @intlayer:press=${this._handlePress}\n @intlayer:hover=${this._handleHover}\n @intlayer:unhover=${this._handleUnhover}\n >\n ${displayedContent}\n </intlayer-content-selector>\n `;\n }\n}\n\nexport const defineIntlayerContentSelectorWrapper = (): void => {\n if (typeof customElements === 'undefined') return;\n\n if (!customElements.get('intlayer-content-selector-wrapper')) {\n customElements.define(\n 'intlayer-content-selector-wrapper',\n IntlayerContentSelectorWrapperElement\n );\n }\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ContentSelectorWrapper.cjs","names":["LitElement","getGlobalEditorManager","onGlobalEditorManagerChange","NodeType","MessageKey"],"sources":["../../../src/components/ContentSelectorWrapper.ts"],"sourcesContent":["import { isSameKeyPath } from '@intlayer/core/utils';\nimport type { ContentNode } from '@intlayer/types/dictionary';\nimport type { KeyPath } from '@intlayer/types/keyPath';\nimport { NodeType, type TypedNodeModel } from '@intlayer/types/nodeType';\nimport { css, html, LitElement } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport type {\n EditorStateManager,\n FileContent,\n} from '../core/EditorStateManager';\nimport {\n getGlobalEditorManager,\n onGlobalEditorManagerChange,\n} from '../core/globalManager';\nimport { MessageKey } from '../messageKey';\n\n/**\n * <intlayer-content-selector-wrapper>\n *\n * Framework-agnostic Lit element that wraps content with the Intlayer editor\n * selection UI. It replaces the per-framework ContentSelectorWrapper components\n * (Vue, Svelte, Solid, Preact).\n *\n * It reads from the global EditorStateManager singleton (set by initEditorClient)\n * and conditionally renders <intlayer-content-selector> around its slot content\n * when the editor is active and the app is running inside an iframe.\n *\n * @attr {string} key-path - JSON-serialized KeyPath[] for this content node\n * @attr {string} dictionary-key - The dictionary key owning this content node\n */\nexport class IntlayerContentSelectorWrapperElement extends LitElement {\n static styles = css`\n :host {\n display: contents;\n }\n `;\n\n @property({ type: String, attribute: 'key-path' }) keyPathJson = '[]';\n @property({ type: String, attribute: 'dictionary-key' }) dictionaryKey = '';\n\n @state() private _editorEnabled = false;\n @state() private _isInIframe = false;\n @state() private _isSelected = false;\n @state() private _editedValue: ContentNode | undefined = undefined;\n\n private _unsubManager: (() => void) | null = null;\n private _unsubEnabled: (() => void) | null = null;\n private _unsubFocused: (() => void) | null = null;\n private _unsubEditedContent: (() => void) | null = null;\n\n connectedCallback(): void {\n super.connectedCallback();\n if (typeof window !== 'undefined') {\n this._isInIframe = window.self !== window.top;\n }\n this._subscribeToManager();\n }\n\n disconnectedCallback(): void {\n super.disconnectedCallback();\n this._teardown();\n }\n\n updated(changedProperties: Map<string, unknown>): void {\n if (\n changedProperties.has('keyPathJson') ||\n changedProperties.has('dictionaryKey')\n ) {\n const manager = getGlobalEditorManager();\n if (manager) this._updateEditedValue(manager);\n }\n }\n\n private _teardown(): void {\n this._unsubManager?.();\n this._unsubEnabled?.();\n this._unsubFocused?.();\n this._unsubEditedContent?.();\n this._unsubManager = null;\n this._unsubEnabled = null;\n this._unsubFocused = null;\n this._unsubEditedContent = null;\n }\n\n private _subscribeToManager(): void {\n const manager = getGlobalEditorManager();\n if (manager) {\n this._setupManagerSubscriptions(manager);\n }\n // Keep listening for manager changes (handles stop + re-init cycles)\n this._unsubManager = onGlobalEditorManagerChange((m) => {\n this._unsubEnabled?.();\n this._unsubFocused?.();\n this._unsubEditedContent?.();\n this._unsubEnabled = null;\n this._unsubFocused = null;\n this._unsubEditedContent = null;\n if (m) {\n this._setupManagerSubscriptions(m);\n } else {\n this._editorEnabled = false;\n this._isSelected = false;\n this._editedValue = undefined;\n }\n });\n }\n\n private _setupManagerSubscriptions(manager: EditorStateManager): void {\n this._editorEnabled = manager.editorEnabled.value ?? false;\n this._updateIsSelected(manager.focusedContent.value);\n this._updateEditedValue(manager);\n\n const handleEnabledChange = (e: Event) => {\n this._editorEnabled = (e as CustomEvent<boolean>).detail;\n };\n const handleFocusedChange = (e: Event) => {\n this._updateIsSelected((e as CustomEvent<FileContent | null>).detail);\n };\n const handleEditedContentChange = () => {\n this._updateEditedValue(manager);\n };\n\n manager.editorEnabled.addEventListener('change', handleEnabledChange);\n manager.focusedContent.addEventListener('change', handleFocusedChange);\n manager.editedContent.addEventListener('change', handleEditedContentChange);\n\n this._unsubEnabled = () =>\n manager.editorEnabled.removeEventListener('change', handleEnabledChange);\n this._unsubFocused = () =>\n manager.focusedContent.removeEventListener('change', handleFocusedChange);\n this._unsubEditedContent = () =>\n manager.editedContent.removeEventListener(\n 'change',\n handleEditedContentChange\n );\n }\n\n private _getRawKeyPath(): KeyPath[] {\n try {\n return JSON.parse(this.keyPathJson) as KeyPath[];\n } catch {\n return [];\n }\n }\n\n private _getFilteredKeyPath(): KeyPath[] {\n return this._getRawKeyPath().filter((k) => k.type !== NodeType.Translation);\n }\n\n private _updateEditedValue(manager: EditorStateManager): void {\n const filteredKeyPath = this._getFilteredKeyPath();\n if (!this.dictionaryKey || filteredKeyPath.length === 0) {\n this._editedValue = undefined;\n return;\n }\n\n // Node types whose display requires framework-level rendering (markdown,\n // HTML, insertion, file): do not override the slot — the framework handles\n // those. Only plain / translated strings can be substituted here.\n const rawKeyPath = this._getRawKeyPath();\n const lastStepType = rawKeyPath[rawKeyPath.length - 1]?.type;\n if (\n lastStepType === NodeType.Markdown ||\n lastStepType === NodeType.HTML ||\n lastStepType === NodeType.Insertion ||\n lastStepType === NodeType.File\n ) {\n this._editedValue = undefined;\n return;\n }\n\n let value = manager.getContentValue(this.dictionaryKey, filteredKeyPath);\n\n // getContentNodeByKeyPath resolves translation nodes only at intermediate\n // steps, not the final leaf. Resolve manually when the returned value is\n // still a translation object (happens when Translation steps are filtered\n // out and the leaf IS the translation object).\n if (\n value !== null &&\n value !== undefined &&\n typeof value === 'object' &&\n value.nodeType === NodeType.Translation\n ) {\n const locale = manager.currentLocale.value as string | undefined;\n // TypedNodeModel<Translation, …> structurally satisfies TypedNode<BaseNode>\n // (both have nodeType), so this narrowing cast is sound.\n const node = value as TypedNodeModel<\n typeof NodeType.Translation,\n Record<string, ContentNode>\n >;\n value = locale ? node[NodeType.Translation][locale] : undefined;\n }\n\n this._editedValue = value;\n }\n\n private _updateIsSelected(\n focusedContent: FileContent | null | undefined\n ): void {\n if (!focusedContent) {\n this._isSelected = false;\n return;\n }\n const keyPath = this._getFilteredKeyPath();\n this._isSelected =\n focusedContent.dictionaryKey === this.dictionaryKey &&\n (focusedContent.keyPath?.length ?? 0) > 0 &&\n isSameKeyPath(focusedContent.keyPath ?? [], keyPath);\n }\n\n private _handlePress(e: Event): void {\n // Stop propagation so nested wrappers don't also fire (composed + bubbles)\n e.stopPropagation();\n const manager = getGlobalEditorManager();\n if (!manager) return;\n manager.focusedContent.set({\n dictionaryKey: this.dictionaryKey,\n keyPath: this._getFilteredKeyPath(),\n });\n }\n\n private _handleHover(e: Event): void {\n e.stopPropagation();\n getGlobalEditorManager()?.messenger.send(\n `${MessageKey.INTLAYER_HOVERED_CONTENT_CHANGED}/post`,\n { dictionaryKey: this.dictionaryKey, keyPath: this._getFilteredKeyPath() }\n );\n }\n\n private _handleUnhover(e: Event): void {\n e.stopPropagation();\n getGlobalEditorManager()?.messenger.send(\n `${MessageKey.INTLAYER_HOVERED_CONTENT_CHANGED}/post`,\n null\n );\n }\n\n render() {\n if (!this._isInIframe || !this._editorEnabled) {\n return html`<slot></slot>`;\n }\n\n const editedValue = this._editedValue;\n const displayedContent =\n typeof editedValue === 'string' ||\n typeof editedValue === 'number' ||\n typeof editedValue === 'boolean'\n ? editedValue\n : html`<slot></slot>`;\n\n return html`\n <intlayer-content-selector\n ?is-selecting=${this._isSelected}\n @intlayer:press=${this._handlePress}\n @intlayer:hover=${this._handleHover}\n @intlayer:unhover=${this._handleUnhover}\n >\n ${displayedContent}\n </intlayer-content-selector>\n `;\n }\n}\n\nexport const defineIntlayerContentSelectorWrapper = (): void => {\n if (typeof customElements === 'undefined') return;\n\n if (!customElements.get('intlayer-content-selector-wrapper')) {\n customElements.define(\n 'intlayer-content-selector-wrapper',\n IntlayerContentSelectorWrapperElement\n );\n }\n};\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../chunk-Bmb41Sf3.cjs`);const e=require(`../core/globalManager.cjs`),t=require(`../decorate-Bg73f0d3.cjs`);let n=require(`lit`),r=require(`lit/decorators.js`),i=require(`@intlayer/core/interpreter`);var a=class extends n.LitElement{constructor(...e){super(...e),this.dictionaryKey=``,this.keyPathJson=`[]`,this.locale=``,this._editedText=null,this._unsubManager=null,this._unsubEditedContent=null}static{this.styles=n.css`
|
|
2
2
|
:host {
|
|
3
3
|
display: contents;
|
|
4
4
|
}
|
|
@@ -9,5 +9,5 @@ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../_
|
|
|
9
9
|
>
|
|
10
10
|
${this._editedText===null?n.html`<slot></slot>`:this._editedText}
|
|
11
11
|
</intlayer-content-selector-wrapper>
|
|
12
|
-
`}};t.
|
|
12
|
+
`}};t.t([(0,r.property)({type:String,attribute:`dictionary-key`})],a.prototype,`dictionaryKey`,void 0),t.t([(0,r.property)({type:String,attribute:`key-path`})],a.prototype,`keyPathJson`,void 0),t.t([(0,r.property)({type:String,attribute:`locale`})],a.prototype,`locale`,void 0),t.t([(0,r.state)()],a.prototype,`_editedText`,void 0);const o=()=>{typeof customElements>`u`||customElements.get(`intlayer-edited-content`)||customElements.define(`intlayer-edited-content`,a)};exports.IntlayerEditedContentElement=a,exports.defineIntlayerEditedContent=o;
|
|
13
13
|
//# sourceMappingURL=EditedContent.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EditedContent.cjs","names":["LitElement","getGlobalEditorManager","onGlobalEditorManagerChange"],"sources":["../../../src/components/EditedContent.ts"],"sourcesContent":["import { getBasePlugins, getContent } from '@intlayer/core/interpreter';\nimport type { KeyPath } from '@intlayer/types/keyPath';\nimport { css, html, LitElement } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport type { EditorStateManager } from '../core/EditorStateManager';\nimport {\n getGlobalEditorManager,\n onGlobalEditorManagerChange,\n} from '../core/globalManager';\n\n/**\n * <intlayer-edited-content>\n *\n * Framework-agnostic Lit element that displays edited content from the Intlayer\n * editor. When the editor has an edited value for the given dictionary key and\n * key path, it renders the edited value; otherwise it renders the original\n * content via a slot.\n *\n * Always wraps content in <intlayer-content-selector-wrapper> for selection UI.\n *\n * @attr {string} dictionary-key - The dictionary key owning this content node\n * @attr {string} key-path - JSON-serialized KeyPath[] for this content node\n * @attr {string} locale - The current locale string\n */\nexport class IntlayerEditedContentElement extends LitElement {\n static styles = css`\n :host {\n display: contents;\n }\n `;\n\n @property({ type: String, attribute: 'dictionary-key' }) dictionaryKey = '';\n @property({ type: String, attribute: 'key-path' }) keyPathJson = '[]';\n @property({ type: String, attribute: 'locale' }) locale = '';\n\n @state() private _editedText: string | null = null;\n\n private _unsubManager: (() => void) | null = null;\n private _unsubEditedContent: (() => void) | null = null;\n\n connectedCallback(): void {\n super.connectedCallback();\n this._subscribeToManager();\n }\n\n disconnectedCallback(): void {\n super.disconnectedCallback();\n this._teardown();\n }\n\n private _teardown(): void {\n this._unsubManager?.();\n this._unsubEditedContent?.();\n this._unsubManager = null;\n this._unsubEditedContent = null;\n }\n\n private _getKeyPath(): KeyPath[] {\n try {\n return JSON.parse(this.keyPathJson);\n } catch {\n return [];\n }\n }\n\n private _resolveEditedText(manager: EditorStateManager): void {\n const keyPath = this._getKeyPath();\n const editedValue = manager.getContentValue(this.dictionaryKey, keyPath);\n\n if (editedValue === undefined || editedValue === null) {\n this._editedText = null;\n return;\n }\n\n if (typeof editedValue === 'string' || typeof editedValue === 'number') {\n this._editedText = String(editedValue);\n return;\n }\n\n if (typeof editedValue === 'object') {\n const locale = this.locale || undefined;\n const transformed = getContent(\n editedValue,\n {\n locale: locale as any,\n dictionaryKey: this.dictionaryKey,\n keyPath,\n },\n getBasePlugins(locale as any)\n );\n if (typeof transformed === 'string' || typeof transformed === 'number') {\n this._editedText = String(transformed);\n } else {\n console.error(\n `[intlayer-edited-content] Incorrect edited content format. Expected string. Value: ${JSON.stringify(transformed)}`\n );\n this._editedText = null;\n }\n return;\n }\n\n this._editedText = null;\n }\n\n private _setupManagerSubscriptions(manager: EditorStateManager): void {\n this._resolveEditedText(manager);\n\n const handleChange = () => this._resolveEditedText(manager);\n manager.editedContent.addEventListener('change', handleChange);\n\n this._unsubEditedContent = () =>\n manager.editedContent.removeEventListener('change', handleChange);\n }\n\n private _subscribeToManager(): void {\n const manager = getGlobalEditorManager();\n if (manager) {\n this._setupManagerSubscriptions(manager);\n }\n\n this._unsubManager = onGlobalEditorManagerChange((m) => {\n this._unsubEditedContent?.();\n this._unsubEditedContent = null;\n if (m) {\n this._setupManagerSubscriptions(m);\n } else {\n this._editedText = null;\n }\n });\n }\n\n render() {\n return html`\n <intlayer-content-selector-wrapper\n key-path=${this.keyPathJson}\n dictionary-key=${this.dictionaryKey}\n >\n ${this._editedText !== null ? this._editedText : html`<slot></slot>`}\n </intlayer-content-selector-wrapper>\n `;\n }\n}\n\nexport const defineIntlayerEditedContent = (): void => {\n if (typeof customElements === 'undefined') return;\n\n if (!customElements.get('intlayer-edited-content')) {\n customElements.define(\n 'intlayer-edited-content',\n IntlayerEditedContentElement\n );\n }\n};\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"EditedContent.cjs","names":["LitElement","getGlobalEditorManager","onGlobalEditorManagerChange"],"sources":["../../../src/components/EditedContent.ts"],"sourcesContent":["import { getBasePlugins, getContent } from '@intlayer/core/interpreter';\nimport type { KeyPath } from '@intlayer/types/keyPath';\nimport { css, html, LitElement } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport type { EditorStateManager } from '../core/EditorStateManager';\nimport {\n getGlobalEditorManager,\n onGlobalEditorManagerChange,\n} from '../core/globalManager';\n\n/**\n * <intlayer-edited-content>\n *\n * Framework-agnostic Lit element that displays edited content from the Intlayer\n * editor. When the editor has an edited value for the given dictionary key and\n * key path, it renders the edited value; otherwise it renders the original\n * content via a slot.\n *\n * Always wraps content in <intlayer-content-selector-wrapper> for selection UI.\n *\n * @attr {string} dictionary-key - The dictionary key owning this content node\n * @attr {string} key-path - JSON-serialized KeyPath[] for this content node\n * @attr {string} locale - The current locale string\n */\nexport class IntlayerEditedContentElement extends LitElement {\n static styles = css`\n :host {\n display: contents;\n }\n `;\n\n @property({ type: String, attribute: 'dictionary-key' }) dictionaryKey = '';\n @property({ type: String, attribute: 'key-path' }) keyPathJson = '[]';\n @property({ type: String, attribute: 'locale' }) locale = '';\n\n @state() private _editedText: string | null = null;\n\n private _unsubManager: (() => void) | null = null;\n private _unsubEditedContent: (() => void) | null = null;\n\n connectedCallback(): void {\n super.connectedCallback();\n this._subscribeToManager();\n }\n\n disconnectedCallback(): void {\n super.disconnectedCallback();\n this._teardown();\n }\n\n private _teardown(): void {\n this._unsubManager?.();\n this._unsubEditedContent?.();\n this._unsubManager = null;\n this._unsubEditedContent = null;\n }\n\n private _getKeyPath(): KeyPath[] {\n try {\n return JSON.parse(this.keyPathJson);\n } catch {\n return [];\n }\n }\n\n private _resolveEditedText(manager: EditorStateManager): void {\n const keyPath = this._getKeyPath();\n const editedValue = manager.getContentValue(this.dictionaryKey, keyPath);\n\n if (editedValue === undefined || editedValue === null) {\n this._editedText = null;\n return;\n }\n\n if (typeof editedValue === 'string' || typeof editedValue === 'number') {\n this._editedText = String(editedValue);\n return;\n }\n\n if (typeof editedValue === 'object') {\n const locale = this.locale || undefined;\n const transformed = getContent(\n editedValue,\n {\n locale: locale as any,\n dictionaryKey: this.dictionaryKey,\n keyPath,\n },\n getBasePlugins(locale as any)\n );\n if (typeof transformed === 'string' || typeof transformed === 'number') {\n this._editedText = String(transformed);\n } else {\n console.error(\n `[intlayer-edited-content] Incorrect edited content format. Expected string. Value: ${JSON.stringify(transformed)}`\n );\n this._editedText = null;\n }\n return;\n }\n\n this._editedText = null;\n }\n\n private _setupManagerSubscriptions(manager: EditorStateManager): void {\n this._resolveEditedText(manager);\n\n const handleChange = () => this._resolveEditedText(manager);\n manager.editedContent.addEventListener('change', handleChange);\n\n this._unsubEditedContent = () =>\n manager.editedContent.removeEventListener('change', handleChange);\n }\n\n private _subscribeToManager(): void {\n const manager = getGlobalEditorManager();\n if (manager) {\n this._setupManagerSubscriptions(manager);\n }\n\n this._unsubManager = onGlobalEditorManagerChange((m) => {\n this._unsubEditedContent?.();\n this._unsubEditedContent = null;\n if (m) {\n this._setupManagerSubscriptions(m);\n } else {\n this._editedText = null;\n }\n });\n }\n\n render() {\n return html`\n <intlayer-content-selector-wrapper\n key-path=${this.keyPathJson}\n dictionary-key=${this.dictionaryKey}\n >\n ${this._editedText !== null ? this._editedText : html`<slot></slot>`}\n </intlayer-content-selector-wrapper>\n `;\n }\n}\n\nexport const defineIntlayerEditedContent = (): void => {\n if (typeof customElements === 'undefined') return;\n\n if (!customElements.get('intlayer-edited-content')) {\n customElements.define(\n 'intlayer-edited-content',\n IntlayerEditedContentElement\n );\n }\n};\n"],"mappings":"mRAwBA,IAAa,EAAb,cAAkDA,EAAAA,UAAW,kDAOc,oBACR,iBACP,oBAEZ,wBAED,8BACM,wBAbnC,EAAA,GAAG;;;;IAenB,mBAA0B,CACxB,MAAM,mBAAmB,CACzB,KAAK,qBAAqB,CAG5B,sBAA6B,CAC3B,MAAM,sBAAsB,CAC5B,KAAK,WAAW,CAGlB,WAA0B,CACxB,KAAK,iBAAiB,CACtB,KAAK,uBAAuB,CAC5B,KAAK,cAAgB,KACrB,KAAK,oBAAsB,KAG7B,aAAiC,CAC/B,GAAI,CACF,OAAO,KAAK,MAAM,KAAK,YAAY,MAC7B,CACN,MAAO,EAAE,EAIb,mBAA2B,EAAmC,CAC5D,IAAM,EAAU,KAAK,aAAa,CAC5B,EAAc,EAAQ,gBAAgB,KAAK,cAAe,EAAQ,CAExE,GAAI,GAA6C,KAAM,CACrD,KAAK,YAAc,KACnB,OAGF,GAAI,OAAO,GAAgB,UAAY,OAAO,GAAgB,SAAU,CACtE,KAAK,YAAc,OAAO,EAAY,CACtC,OAGF,GAAI,OAAO,GAAgB,SAAU,CACnC,IAAM,EAAS,KAAK,QAAU,IAAA,GACxB,GAAA,EAAA,EAAA,YACJ,EACA,CACU,SACR,cAAe,KAAK,cACpB,UACD,EAAA,EAAA,EAAA,gBACc,EAAc,CAC9B,CACG,OAAO,GAAgB,UAAY,OAAO,GAAgB,SAC5D,KAAK,YAAc,OAAO,EAAY,EAEtC,QAAQ,MACN,sFAAsF,KAAK,UAAU,EAAY,GAClH,CACD,KAAK,YAAc,MAErB,OAGF,KAAK,YAAc,KAGrB,2BAAmC,EAAmC,CACpE,KAAK,mBAAmB,EAAQ,CAEhC,IAAM,MAAqB,KAAK,mBAAmB,EAAQ,CAC3D,EAAQ,cAAc,iBAAiB,SAAU,EAAa,CAE9D,KAAK,wBACH,EAAQ,cAAc,oBAAoB,SAAU,EAAa,CAGrE,qBAAoC,CAClC,IAAM,EAAUC,EAAAA,wBAAwB,CACpC,GACF,KAAK,2BAA2B,EAAQ,CAG1C,KAAK,cAAgBC,EAAAA,4BAA6B,GAAM,CACtD,KAAK,uBAAuB,CAC5B,KAAK,oBAAsB,KACvB,EACF,KAAK,2BAA2B,EAAE,CAElC,KAAK,YAAc,MAErB,CAGJ,QAAS,CACP,MAAO,GAAA,IAAI;;mBAEI,KAAK,YAAY;yBACX,KAAK,cAAc;;UAElC,KAAK,cAAgB,KAA0B,EAAA,IAAI,gBAAvB,KAAK,YAAkC;;4BA1GjE,CAAE,KAAM,OAAQ,UAAW,iBAAkB,CAAC,CAAA,CAAA,EAAA,UAAA,gBAAA,IAAA,GAAA,qBAC9C,CAAE,KAAM,OAAQ,UAAW,WAAY,CAAC,CAAA,CAAA,EAAA,UAAA,cAAA,IAAA,GAAA,qBACxC,CAAE,KAAM,OAAQ,UAAW,SAAU,CAAC,CAAA,CAAA,EAAA,UAAA,SAAA,IAAA,GAAA,mBAExC,CAAA,CAAA,EAAA,UAAA,cAAA,IAAA,GAAA,CA4GV,MAAa,MAA0C,CACjD,OAAO,eAAmB,KAEzB,eAAe,IAAI,0BAA0B,EAChD,eAAe,OACb,0BACA,EACD"}
|
|
@@ -1,2 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`})
|
|
2
|
-
//# sourceMappingURL=IntlayerEditor.cjs.map
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../components-DWu35JEb.cjs`);exports.IntlayerEditorElement=e.r,exports.defineIntlayerEditorElement=e.i;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./ContentSelectorWrapper.cjs`),t=require(`./EditedContent.cjs`),n=require(
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./ContentSelectorWrapper.cjs`),t=require(`./EditedContent.cjs`),n=require(`../components-DWu35JEb.cjs`);exports.IntlayerContentSelectorElement=n.t,exports.IntlayerContentSelectorWrapperElement=e.IntlayerContentSelectorWrapperElement,exports.IntlayerEditedContentElement=t.IntlayerEditedContentElement,exports.IntlayerEditorElement=n.r,exports.defineIntlayerContentSelectorWrapper=e.defineIntlayerContentSelectorWrapper,exports.defineIntlayerEditedContent=t.defineIntlayerEditedContent,exports.defineIntlayerEditorElement=n.i,exports.defineIntlayerElements=n.n;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
const e=require(`./chunk-Bmb41Sf3.cjs`),t=require(`./core/globalManager.cjs`),n=require(`./decorate-Bg73f0d3.cjs`),r=require(`./components/ContentSelectorWrapper.cjs`),i=require(`./components/EditedContent.cjs`),a=require(`./core/EditorStateManager.cjs`);let o=require(`@intlayer/config/built`);o=e.t(o);let s=require(`lit`),c=require(`lit/decorators.js`);const l=()=>{let{editor:e}=o.default??{};return{allowedOrigins:[e?.editorURL,e?.cmsURL].filter(Boolean),postMessageFn:(e,t)=>{typeof window>`u`||window.self!==window.top&&window.parent?.postMessage(e,t)}}};let u=0;const d=()=>{u++;let e=t.getGlobalEditorManager();if(e)return e;let n=new a.EditorStateManager({mode:`client`,messenger:l(),configuration:o.default});return t.setGlobalEditorManager(n),g(),n.start(),n},f=()=>{u=Math.max(0,u-1),!(u>0)&&(t.getGlobalEditorManager()?.stop(),t.setGlobalEditorManager(null))};var p=class extends s.LitElement{constructor(...e){super(...e),this._initialized=!1,this._unsubManager=null}createRenderRoot(){return this}connectedCallback(){super.connectedCallback(),this._init()}disconnectedCallback(){super.disconnectedCallback(),this._unsubManager?.(),this._unsubManager=null,this._initialized&&=(f(),!1)}updated(e){e.has(`configuration`)&&!this._initialized&&this._init(),e.has(`locale`)&&this.locale&&this._syncLocale(this.locale)}_init(){this._initialized||(d(),this._initialized=!0,this.locale&&this._syncLocale(this.locale))}_syncLocale(e){let n=t.getGlobalEditorManager();n?n.currentLocale.set(e):(this._unsubManager?.(),this._unsubManager=t.onGlobalEditorManagerChange(t=>{t&&(this._unsubManager?.(),this._unsubManager=null,t.currentLocale.set(e))}))}};n.t([(0,c.property)({attribute:!1})],p.prototype,`configuration`,void 0),n.t([(0,c.property)({type:String})],p.prototype,`locale`,void 0);const m=()=>{typeof customElements>`u`||customElements.get(`intlayer-editor`)||customElements.define(`intlayer-editor`,p)};var h=class extends s.LitElement{constructor(...e){super(...e),this.isSelecting=!1,this.pressDuration=250,this._isHovered=!1,this._isSelectingState=!1,this._pressTimer=null,this._clickOutsideHandler=null}static{this.styles=s.css`
|
|
2
|
+
:host {
|
|
3
|
+
display: contents;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
.wrapper {
|
|
7
|
+
display: inline-block;
|
|
8
|
+
cursor: pointer;
|
|
9
|
+
user-select: none;
|
|
10
|
+
border-radius: 0.375rem;
|
|
11
|
+
outline-width: 2px;
|
|
12
|
+
outline-offset: 4px;
|
|
13
|
+
outline-style: solid;
|
|
14
|
+
outline-color: transparent;
|
|
15
|
+
transition: all 100ms 50ms ease-in-out;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.wrapper[data-active] {
|
|
19
|
+
outline-color: inherit;
|
|
20
|
+
}
|
|
21
|
+
`}connectedCallback(){super.connectedCallback(),this._clickOutsideHandler=e=>{e.composedPath().includes(this)||(this._isSelectingState=!1,this._dispatch(`intlayer:click-outside`))},document.addEventListener(`mousedown`,this._clickOutsideHandler)}disconnectedCallback(){super.disconnectedCallback(),this._clickOutsideHandler&&=(document.removeEventListener(`mousedown`,this._clickOutsideHandler),null),this._clearPressTimer()}_clearPressTimer(){this._pressTimer!==null&&(clearTimeout(this._pressTimer),this._pressTimer=null)}_dispatch(e){this.dispatchEvent(new CustomEvent(e,{bubbles:!0,composed:!0}))}_handleMouseDown(){this._clearPressTimer(),this._pressTimer=setTimeout(()=>{this._isSelectingState=!0,this._dispatch(`intlayer:press`)},this.pressDuration)}_handleMouseEnter(){this._isHovered=!0,this._dispatch(`intlayer:hover`)}_handleMouseUpOrLeave(){this._isHovered&&(this._isHovered=!1,this._dispatch(`intlayer:unhover`)),this._clearPressTimer()}_handleClick(e){(this.isSelecting||this._isSelectingState)&&(e.preventDefault(),e.stopPropagation())}_handleBlur(){this._isSelectingState=!1}render(){return s.html`
|
|
22
|
+
<span
|
|
23
|
+
class="wrapper"
|
|
24
|
+
?data-active=${this.isSelecting||this._isSelectingState||this._isHovered}
|
|
25
|
+
role="button"
|
|
26
|
+
tabindex="0"
|
|
27
|
+
@mousedown=${this._handleMouseDown}
|
|
28
|
+
@mouseup=${this._handleMouseUpOrLeave}
|
|
29
|
+
@mouseleave=${this._handleMouseUpOrLeave}
|
|
30
|
+
@mouseenter=${this._handleMouseEnter}
|
|
31
|
+
@click=${this._handleClick}
|
|
32
|
+
@touchstart=${this._handleMouseDown}
|
|
33
|
+
@touchend=${this._handleMouseUpOrLeave}
|
|
34
|
+
@touchcancel=${this._handleMouseUpOrLeave}
|
|
35
|
+
@blur=${this._handleBlur}
|
|
36
|
+
@keyup=${()=>{}}
|
|
37
|
+
>
|
|
38
|
+
<slot></slot>
|
|
39
|
+
</span>
|
|
40
|
+
`}};n.t([(0,c.property)({type:Boolean,attribute:`is-selecting`})],h.prototype,`isSelecting`,void 0),n.t([(0,c.property)({type:Number,attribute:`press-duration`})],h.prototype,`pressDuration`,void 0),n.t([(0,c.state)()],h.prototype,`_isHovered`,void 0),n.t([(0,c.state)()],h.prototype,`_isSelectingState`,void 0),n.t([(0,c.query)(`.wrapper`)],h.prototype,`_wrapper`,void 0);const g=()=>{typeof customElements>`u`||(customElements.get(`intlayer-content-selector`)||customElements.define(`intlayer-content-selector`,h),r.defineIntlayerContentSelectorWrapper(),i.defineIntlayerEditedContent(),m())};Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return l}}),Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return m}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return g}}),Object.defineProperty(exports,`o`,{enumerable:!0,get:function(){return d}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return p}}),Object.defineProperty(exports,`s`,{enumerable:!0,get:function(){return f}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return h}});
|
|
41
|
+
//# sourceMappingURL=components-DWu35JEb.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"components-DWu35JEb.cjs","names":["configuration","getGlobalEditorManager","EditorStateManager","LitElement","getGlobalEditorManager","onGlobalEditorManagerChange","LitElement"],"sources":["../../src/core/initEditorClient.ts","../../src/components/IntlayerEditor.ts","../../src/components/ContentSelector.ts"],"sourcesContent":["import configuration 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 const { editor } = configuration ?? {};\n\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","import type { Locale } from '@intlayer/types/allLocales';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport { LitElement } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport {\n getGlobalEditorManager,\n onGlobalEditorManagerChange,\n} from '../core/globalManager';\nimport { initEditorClient, stopEditorClient } from '../core/initEditorClient';\n\n/**\n * <intlayer-editor>\n *\n * A framework-agnostic Lit element that manages the Intlayer editor singleton\n * lifecycle and keeps the current locale in sync with the EditorStateManager.\n *\n * Drop this element once at the root of your application to activate the editor.\n * It renders no UI (display: contents, empty shadow root).\n *\n * @prop {IntlayerConfig} configuration - The Intlayer config (required; set as property, not attribute)\n * @prop {string} locale - The active application locale (attribute/property)\n *\n * @example\n * // Svelte\n * <intlayer-editor .configuration={config} locale={$locale} />\n *\n * // Vue\n * <intlayer-editor :configuration=\"config\" :locale=\"currentLocale\" />\n */\nexport class IntlayerEditorElement extends LitElement {\n /** No visible UI — render nothing into the shadow root */\n createRenderRoot(): this {\n return this;\n }\n\n @property({ attribute: false }) configuration?: IntlayerConfig;\n\n @property({ type: String }) locale?: string;\n\n private _initialized = false;\n private _unsubManager: (() => void) | null = null;\n\n connectedCallback(): void {\n super.connectedCallback();\n this._init();\n }\n\n disconnectedCallback(): void {\n super.disconnectedCallback();\n this._unsubManager?.();\n this._unsubManager = null;\n\n if (this._initialized) {\n stopEditorClient();\n this._initialized = false;\n }\n }\n\n updated(changedProperties: Map<string | symbol, unknown>): void {\n if (changedProperties.has('configuration') && !this._initialized) {\n this._init();\n }\n\n if (changedProperties.has('locale') && this.locale) {\n this._syncLocale(this.locale);\n }\n }\n\n private _init(): void {\n if (this._initialized) return;\n\n initEditorClient();\n\n this._initialized = true;\n\n // Sync locale immediately after init if it is already set\n if (this.locale) {\n this._syncLocale(this.locale);\n }\n }\n\n private _syncLocale(locale: string): void {\n const manager = getGlobalEditorManager();\n\n if (manager) {\n manager.currentLocale.set(locale as Locale);\n } else {\n // Manager may not be ready yet — wait for it\n this._unsubManager?.();\n this._unsubManager = onGlobalEditorManagerChange((manager) => {\n if (manager) {\n this._unsubManager?.();\n this._unsubManager = null;\n\n manager.currentLocale.set(locale as Locale);\n }\n });\n }\n }\n}\n\nexport const defineIntlayerEditorElement = (): void => {\n if (typeof customElements === 'undefined') return;\n\n if (!customElements.get('intlayer-editor')) {\n customElements.define('intlayer-editor', IntlayerEditorElement);\n }\n};\n","import { css, html, LitElement } from 'lit';\nimport { property, query, state } from 'lit/decorators.js';\nimport { defineIntlayerContentSelectorWrapper } from './ContentSelectorWrapper';\nimport { defineIntlayerEditedContent } from './EditedContent';\nimport { defineIntlayerEditorElement } from './IntlayerEditor';\n\nconst DEFAULT_PRESS_DURATION = 250;\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 * Replaces the per-framework ContentSelector components (React, Svelte, Vue, Solid).\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 LitElement {\n static styles = css`\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\n @property({ type: Boolean, attribute: 'is-selecting' })\n isSelecting = false;\n\n @property({ type: Number, attribute: 'press-duration' })\n pressDuration = DEFAULT_PRESS_DURATION;\n\n @state() private _isHovered = false;\n @state() private _isSelectingState = false;\n\n @query('.wrapper') private _wrapper!: HTMLSpanElement;\n\n private _pressTimer: ReturnType<typeof setTimeout> | null = null;\n private _clickOutsideHandler: ((e: MouseEvent) => void) | null = null;\n\n connectedCallback(): void {\n super.connectedCallback();\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 }\n };\n document.addEventListener('mousedown', this._clickOutsideHandler);\n }\n\n disconnectedCallback(): void {\n super.disconnectedCallback();\n if (this._clickOutsideHandler) {\n document.removeEventListener('mousedown', this._clickOutsideHandler);\n this._clickOutsideHandler = null;\n }\n this._clearPressTimer();\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._dispatch('intlayer:press');\n }, this.pressDuration);\n }\n\n private _handleMouseEnter(): void {\n this._isHovered = true;\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 }\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 }\n\n render() {\n const isActive =\n this.isSelecting || this._isSelectingState || this._isHovered;\n return html`\n <span\n class=\"wrapper\"\n ?data-active=${isActive}\n role=\"button\"\n tabindex=\"0\"\n @mousedown=${this._handleMouseDown}\n @mouseup=${this._handleMouseUpOrLeave}\n @mouseleave=${this._handleMouseUpOrLeave}\n @mouseenter=${this._handleMouseEnter}\n @click=${this._handleClick}\n @touchstart=${this._handleMouseDown}\n @touchend=${this._handleMouseUpOrLeave}\n @touchcancel=${this._handleMouseUpOrLeave}\n @blur=${this._handleBlur}\n @keyup=${() => {}}\n >\n <slot></slot>\n </span>\n `;\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,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../chunk-Bmb41Sf3.cjs`);const e=require(`../messageKey.cjs`),t=require(`./CrossFrameMessenger.cjs`),n=require(`./CrossFrameStateManager.cjs`),r=require(`./IframeClickInterceptor.cjs`),i=require(`./UrlStateManager.cjs`);let a=require(`@intlayer/types/nodeType`),o=require(`@intlayer/core/dictionaryManipulator`);var s=class{constructor(a){this._unsubAreYouThere=null,this._unsubActivate=null,this._unsubClientReady=null,this._mode=a.mode,this._configuration=a.configuration,this.messenger=new t.CrossFrameMessenger(a.messenger),this.editorEnabled=new n.CrossFrameStateManager(e.MessageKey.INTLAYER_EDITOR_ENABLED,this.messenger,{emit:!1,receive:!0,initialValue:!1}),this.focusedContent=new n.CrossFrameStateManager(e.MessageKey.INTLAYER_FOCUSED_CONTENT_CHANGED,this.messenger,{emit:!0,receive:!0,initialValue:null}),this.localeDictionaries=new n.CrossFrameStateManager(e.MessageKey.INTLAYER_LOCALE_DICTIONARIES_CHANGED,this.messenger),this.editedContent=new n.CrossFrameStateManager(e.MessageKey.INTLAYER_EDITED_CONTENT_CHANGED,this.messenger),this.configuration=new n.CrossFrameStateManager(e.MessageKey.INTLAYER_CONFIGURATION,this.messenger,{emit:!0,receive:!1,...a.configuration?{initialValue:a.configuration}:{}}),this.currentLocale=new n.CrossFrameStateManager(e.MessageKey.INTLAYER_CURRENT_LOCALE,this.messenger,{emit:a.mode===`client`,receive:a.mode===`editor`}),this._urlManager=new i.UrlStateManager(this.messenger),this._iframeInterceptor=new r.IframeClickInterceptor(this.messenger)}start(){this.messenger.start(),this.editorEnabled.start(),this.focusedContent.start(),this.localeDictionaries.start(),this.editedContent.start(),this.configuration.start(),this.currentLocale.start(),this._mode===`client`?(this._urlManager.start(),this._iframeInterceptor.startInterceptor(),this._loadDictionaries(),this.messenger.send(`${e.MessageKey.INTLAYER_EDITED_CONTENT_CHANGED}/get`),this._configuration?.editor?.enabled!==!1&&this._setupActivationHandshake()):(this._iframeInterceptor.startMerger(),this._setupEditorHandshake())}stop(){this._unsubAreYouThere?.(),this._unsubActivate?.(),this._unsubClientReady?.(),this._unsubAreYouThere=null,this._unsubActivate=null,this._unsubClientReady=null,this.messenger.stop(),this.editorEnabled.stop(),this.focusedContent.stop(),this.localeDictionaries.stop(),this.editedContent.stop(),this.configuration.stop(),this.currentLocale.stop(),this._urlManager.stop(),this._iframeInterceptor.stopInterceptor(),this._iframeInterceptor.stopMerger()}pingClient(){this._mode===`editor`&&this.messenger.send(e.MessageKey.INTLAYER_ARE_YOU_THERE)}setFocusedContentKeyPath(e){let t=e.filter(e=>e.type!==a.NodeType.Translation),n=this.focusedContent.value;n&&this.focusedContent.set({...n,keyPath:t})}setLocaleDictionary(e){if(!e.localId)return;let t=this.localeDictionaries.value??{};this.localeDictionaries.set({...t,[e.localId]:e})}setEditedDictionary(e){if(!e.localId){console.error(`setEditedDictionary: missing localId`,e);return}let t=this.editedContent.value??{};this.editedContent.set({...t,[e.localId]:e})}setEditedContent(e,t){let n=this.editedContent.value??{};this.editedContent.set({...n,[e]:{...n[e],content:t}})}addContent(e,t,n=[],r=!0){let i=this.editedContent.value??{},a=(this.localeDictionaries.value??{})[e]?.content,s=structuredClone(i[e]?.content??a),c=n;if(!r){let e=0,t=n.slice(0,-1),r=n[n.length-1],i=r.key;for(;(0,o.getContentNodeByKeyPath)(s,c)!==void 0;)e++,i=e===0?r.key:`${r.key} (${e})`,c=[...t,{...r,key:i}]}let l=(0,o.editDictionaryByKeyPath)(s,c,t);this.editedContent.set({...i,[e]:{...i[e],content:l}})}renameContent(e,t,n=[]){let r=this.editedContent.value??{},i=(this.localeDictionaries.value??{})[e]?.content,a=(0,o.renameContentNodeByKeyPath)(structuredClone(r[e]?.content??i),t,n);this.editedContent.set({...r,[e]:{...r[e],content:a}})}removeContent(e,t){let n=this.editedContent.value??{},r=(this.localeDictionaries.value??{})[e]?.content,i=(0,o.editDictionaryByKeyPath)(structuredClone(n[e]?.content??r),t,(0,o.getContentNodeByKeyPath)(r,t));this.editedContent.set({...n,[e]:{...n[e],content:i}})}restoreContent(e){let t={...this.editedContent.value??{}};delete t[e],this.editedContent.set(t)}clearContent(e){let t={...this.editedContent.value??{}};delete t[e],this.editedContent.set(t)}clearAllContent(){this.editedContent.set({})}getContentValue(e,t){let n=this.editedContent.value;if(!n)return;let r=t.filter(e=>e.type!==a.NodeType.Translation),i=this.localeDictionaries.value;if(e.includes(`:local:`)||e.includes(`:remote:`))return i&&!(e in i)?void 0:(0,o.getContentNodeByKeyPath)(n[e]?.content??{},r,this.currentLocale.value);let s=Object.keys(n).filter(t=>t.startsWith(`${e}:`)&&(!i||t in i));for(let e of s){let t=(0,o.getContentNodeByKeyPath)(n[e]?.content??{},r,this.currentLocale.value);if(t)return t}}_setupEditorHandshake(){this._unsubClientReady=this.messenger.subscribe(e.MessageKey.INTLAYER_CLIENT_READY,()=>{this.editorEnabled.set(!0),this.messenger.send(e.MessageKey.INTLAYER_EDITOR_ACTIVATE)}),this.messenger.send(e.MessageKey.INTLAYER_ARE_YOU_THERE)}_setupActivationHandshake(){this.messenger.send(e.MessageKey.INTLAYER_CLIENT_READY),this._unsubAreYouThere=this.messenger.subscribe(e.MessageKey.INTLAYER_ARE_YOU_THERE,()=>{this.messenger.send(e.MessageKey.INTLAYER_CLIENT_READY)}),this._unsubActivate=this.messenger.subscribe(e.MessageKey.INTLAYER_EDITOR_ACTIVATE,()=>{this.editorEnabled.set(!0),this._broadcastData()})}_broadcastData(){let t=this.configuration.value;t&&this.messenger.send(`${e.MessageKey.INTLAYER_CONFIGURATION}/post`,t);let n=this.currentLocale.value;n&&this.messenger.send(`${e.MessageKey.INTLAYER_CURRENT_LOCALE}/post`,n);let r=this.localeDictionaries.value;r&&this.messenger.send(`${e.MessageKey.INTLAYER_LOCALE_DICTIONARIES_CHANGED}/post`,r)}async _loadDictionaries(){try{let e=(await import(`@intlayer/unmerged-dictionaries-entry`)).getUnmergedDictionaries(),t=Object.fromEntries(Object.values(e).flat().map(e=>[e.localId,e]));this.localeDictionaries.set(t),this.editorEnabled.value&&this._broadcastData()}catch(e){console.warn(`[intlayer] Failed to load unmerged dictionaries:`,e)}}};exports.EditorStateManager=s;
|
|
2
2
|
//# sourceMappingURL=EditorStateManager.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EditorStateManager.cjs","names":["CrossFrameMessenger","CrossFrameStateManager","MessageKey","UrlStateManager","IframeClickInterceptor","NodeType"],"sources":["../../../src/core/EditorStateManager.ts"],"sourcesContent":["import {\n editDictionaryByKeyPath,\n getContentNodeByKeyPath,\n renameContentNodeByKeyPath,\n} from '@intlayer/core/dictionaryManipulator';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type {\n ContentNode,\n Dictionary,\n LocalDictionaryId,\n} from '@intlayer/types/dictionary';\nimport type { KeyPath } from '@intlayer/types/keyPath';\nimport { NodeType } from '@intlayer/types/nodeType';\nimport { MessageKey } from '../messageKey';\nimport {\n CrossFrameMessenger,\n type MessengerConfig,\n} from './CrossFrameMessenger';\nimport { CrossFrameStateManager } from './CrossFrameStateManager';\nimport { IframeClickInterceptor } from './IframeClickInterceptor';\nimport { UrlStateManager } from './UrlStateManager';\n\nexport type DictionaryContent = Record<LocalDictionaryId, Dictionary>;\n\nexport type FileContent = {\n dictionaryKey: string;\n dictionaryLocalId?: LocalDictionaryId;\n keyPath?: KeyPath[];\n};\n\nexport type EditorStateManagerConfig = {\n /** 'client' = the app running inside the iframe; 'editor' = the editor wrapping the app */\n mode: 'editor' | 'client';\n /** Cross-frame messaging configuration */\n messenger: MessengerConfig;\n /** Optional initial Intlayer configuration to broadcast */\n configuration?: IntlayerConfig;\n};\n\n/**\n * EditorStateManager is the single entry point for all Intlayer editor state.\n * It is framework-agnostic: instantiate one instance at the root of the application\n * and subscribe to its EventTarget-based events from any framework adapter.\n *\n * Replaces all context providers, hooks and store files across React, Preact,\n * Solid, Svelte, and Vue integrations.\n */\nexport class EditorStateManager {\n readonly messenger: CrossFrameMessenger;\n readonly editorEnabled: CrossFrameStateManager<boolean>;\n readonly focusedContent: CrossFrameStateManager<FileContent | null>;\n readonly localeDictionaries: CrossFrameStateManager<DictionaryContent>;\n readonly editedContent: CrossFrameStateManager<DictionaryContent>;\n readonly configuration: CrossFrameStateManager<IntlayerConfig>;\n readonly currentLocale: CrossFrameStateManager<Locale | undefined>;\n\n private readonly _urlManager: UrlStateManager;\n private readonly _iframeInterceptor: IframeClickInterceptor;\n private readonly _mode: 'editor' | 'client';\n private readonly _configuration: IntlayerConfig | undefined;\n\n // Client-mode handshake subscribers\n private _unsubAreYouThere: (() => void) | null = null;\n private _unsubActivate: (() => void) | null = null;\n // Editor-mode handshake subscriber\n private _unsubClientReady: (() => void) | null = null;\n\n constructor(config: EditorStateManagerConfig) {\n this._mode = config.mode;\n this._configuration = config.configuration;\n\n this.messenger = new CrossFrameMessenger(config.messenger);\n\n this.editorEnabled = new CrossFrameStateManager<boolean>(\n MessageKey.INTLAYER_EDITOR_ENABLED,\n this.messenger,\n { emit: false, receive: true, initialValue: false }\n );\n\n this.focusedContent = new CrossFrameStateManager<FileContent | null>(\n MessageKey.INTLAYER_FOCUSED_CONTENT_CHANGED,\n this.messenger,\n { emit: true, receive: true, initialValue: null }\n );\n\n this.localeDictionaries = new CrossFrameStateManager<DictionaryContent>(\n MessageKey.INTLAYER_LOCALE_DICTIONARIES_CHANGED,\n this.messenger\n );\n\n this.editedContent = new CrossFrameStateManager<DictionaryContent>(\n MessageKey.INTLAYER_EDITED_CONTENT_CHANGED,\n this.messenger\n );\n\n this.configuration = new CrossFrameStateManager<IntlayerConfig>(\n MessageKey.INTLAYER_CONFIGURATION,\n this.messenger,\n {\n emit: true,\n receive: false,\n ...(config.configuration ? { initialValue: config.configuration } : {}),\n }\n );\n\n // Client emits its locale to the editor; editor receives it.\n this.currentLocale = new CrossFrameStateManager<Locale>(\n MessageKey.INTLAYER_CURRENT_LOCALE,\n this.messenger,\n {\n emit: config.mode === 'client',\n receive: config.mode === 'editor',\n }\n );\n\n this._urlManager = new UrlStateManager(this.messenger);\n this._iframeInterceptor = new IframeClickInterceptor(this.messenger);\n }\n\n start(): void {\n this.messenger.start();\n this.editorEnabled.start();\n this.focusedContent.start();\n this.localeDictionaries.start();\n this.editedContent.start();\n this.configuration.start();\n this.currentLocale.start();\n\n if (this._mode === 'client') {\n this._urlManager.start();\n this._iframeInterceptor.startInterceptor();\n this._loadDictionaries();\n // Request current edited content from the editor\n this.messenger.send(`${MessageKey.INTLAYER_EDITED_CONTENT_CHANGED}/get`);\n // Activation handshake: only participate if editor.enabled !== false\n if (this._configuration?.editor?.enabled !== false) {\n this._setupActivationHandshake();\n }\n } else {\n this._iframeInterceptor.startMerger();\n this._setupEditorHandshake();\n }\n }\n\n stop(): void {\n this._unsubAreYouThere?.();\n this._unsubActivate?.();\n this._unsubClientReady?.();\n this._unsubAreYouThere = null;\n this._unsubActivate = null;\n this._unsubClientReady = null;\n this.messenger.stop();\n this.editorEnabled.stop();\n this.focusedContent.stop();\n this.localeDictionaries.stop();\n this.editedContent.stop();\n this.configuration.stop();\n this.currentLocale.stop();\n this._urlManager.stop();\n this._iframeInterceptor.stopInterceptor();\n this._iframeInterceptor.stopMerger();\n }\n\n // ─── Handshake helpers ───────────────────────────────────────────────────────\n\n /**\n * EDITOR mode: re-send ARE_YOU_THERE to attempt re-connection with the client.\n * Call this when the user clicks \"Enable Editor\" or when the iframe reloads.\n */\n pingClient(): void {\n if (this._mode !== 'editor') return;\n\n this.messenger.send(MessageKey.INTLAYER_ARE_YOU_THERE);\n }\n\n // ─── Focus helpers ──────────────────────────────────────────────────────────\n\n setFocusedContentKeyPath(keyPath: KeyPath[]): void {\n const filtered = keyPath.filter((key) => key.type !== NodeType.Translation);\n const prev = this.focusedContent.value;\n\n if (!prev) return;\n\n this.focusedContent.set({ ...prev, keyPath: filtered });\n }\n\n // ─── Dictionary record helpers ───────────────────────────────────────────\n\n setLocaleDictionary(dictionary: Dictionary): void {\n if (!dictionary.localId) return;\n const current = this.localeDictionaries.value ?? {};\n\n this.localeDictionaries.set({\n ...current,\n [dictionary.localId as LocalDictionaryId]: dictionary,\n });\n }\n\n // ─── Edited content helpers ───────────────────────────────────────────────\n\n setEditedDictionary(newDict: Dictionary): void {\n if (!newDict.localId) {\n console.error('setEditedDictionary: missing localId', newDict);\n return;\n }\n const current = this.editedContent.value ?? {};\n\n this.editedContent.set({\n ...current,\n [newDict.localId as LocalDictionaryId]: newDict,\n });\n }\n\n setEditedContent(\n localDictionaryId: LocalDictionaryId,\n newValue: Dictionary['content']\n ): void {\n const current = this.editedContent.value ?? {};\n\n this.editedContent.set({\n ...current,\n [localDictionaryId]: {\n ...current[localDictionaryId],\n content: newValue,\n },\n });\n }\n\n addContent(\n localDictionaryId: LocalDictionaryId,\n newValue: ContentNode,\n keyPath: KeyPath[] = [],\n overwrite = true\n ): void {\n const current = this.editedContent.value ?? {};\n const localeDicts = this.localeDictionaries.value ?? {};\n\n const originalContent = localeDicts[localDictionaryId]?.content;\n const currentContent = structuredClone(\n current[localDictionaryId]?.content ?? originalContent\n );\n\n let newKeyPath = keyPath;\n if (!overwrite) {\n let index = 0;\n\n const otherKeyPath = keyPath.slice(0, -1);\n const lastKeyPath = keyPath[keyPath.length - 1];\n\n let finalKey = lastKeyPath.key;\n\n while (\n typeof getContentNodeByKeyPath(currentContent, newKeyPath) !==\n 'undefined'\n ) {\n index++;\n finalKey =\n index === 0 ? lastKeyPath.key : `${lastKeyPath.key} (${index})`;\n newKeyPath = [\n ...otherKeyPath,\n { ...lastKeyPath, key: finalKey } as KeyPath,\n ];\n }\n }\n\n const updatedContent = editDictionaryByKeyPath(\n currentContent,\n newKeyPath,\n newValue\n );\n\n this.editedContent.set({\n ...current,\n [localDictionaryId]: {\n ...current[localDictionaryId],\n content: updatedContent as Dictionary['content'],\n },\n });\n }\n\n renameContent(\n localDictionaryId: LocalDictionaryId,\n newKey: KeyPath['key'],\n keyPath: KeyPath[] = []\n ): void {\n const current = this.editedContent.value ?? {};\n const localeDicts = this.localeDictionaries.value ?? {};\n const originalContent = localeDicts[localDictionaryId]?.content;\n const currentContent = structuredClone(\n current[localDictionaryId]?.content ?? originalContent\n );\n const updated = renameContentNodeByKeyPath(currentContent, newKey, keyPath);\n\n this.editedContent.set({\n ...current,\n [localDictionaryId]: {\n ...current[localDictionaryId],\n content: updated as Dictionary['content'],\n },\n });\n }\n\n removeContent(\n localDictionaryId: LocalDictionaryId,\n keyPath: KeyPath[]\n ): void {\n const current = this.editedContent.value ?? {};\n const localeDicts = this.localeDictionaries.value ?? {};\n const originalContent = localeDicts[localDictionaryId]?.content;\n const currentContent = structuredClone(\n current[localDictionaryId]?.content ?? originalContent\n );\n const initialContent = getContentNodeByKeyPath(originalContent, keyPath);\n const restored = editDictionaryByKeyPath(\n currentContent,\n keyPath,\n initialContent\n );\n\n this.editedContent.set({\n ...current,\n [localDictionaryId]: {\n ...current[localDictionaryId],\n content: restored as Dictionary['content'],\n },\n });\n }\n\n restoreContent(localDictionaryId: LocalDictionaryId): void {\n const current = this.editedContent.value ?? {};\n const updated = { ...current };\n\n delete updated[localDictionaryId];\n\n this.editedContent.set(updated);\n }\n\n clearContent(localDictionaryId: LocalDictionaryId): void {\n const current = this.editedContent.value ?? {};\n const filtered = { ...current };\n\n delete filtered[localDictionaryId];\n\n this.editedContent.set(filtered);\n }\n\n clearAllContent(): void {\n this.editedContent.set({});\n }\n\n getContentValue(\n localDictionaryIdOrKey: LocalDictionaryId | string,\n keyPath: KeyPath[]\n ): ContentNode | undefined {\n const edited = this.editedContent.value;\n if (!edited) return undefined;\n\n const filteredKeyPath = keyPath.filter(\n (key) => key.type !== NodeType.Translation\n );\n\n // Only use edited content entries whose localId is known to this client.\n // This prevents stale edits from other apps (different framework demos) from\n // being applied when the editor sends back its stored editedContent.\n const localeDicts = this.localeDictionaries.value;\n\n const isDictionaryId =\n localDictionaryIdOrKey.includes(':local:') ||\n localDictionaryIdOrKey.includes(':remote:');\n\n if (isDictionaryId) {\n // If localeDictionaries is loaded, verify this localId belongs to us\n if (localeDicts && !(localDictionaryIdOrKey in localeDicts)) {\n return undefined;\n }\n const content =\n edited[localDictionaryIdOrKey as LocalDictionaryId]?.content ?? {};\n\n return getContentNodeByKeyPath(\n content,\n filteredKeyPath,\n this.currentLocale.value\n );\n }\n\n const matchingIds = Object.keys(edited).filter(\n (key) =>\n key.startsWith(`${localDictionaryIdOrKey}:`) &&\n // If localeDictionaries is loaded, only include known localIds\n (!localeDicts || key in localeDicts)\n );\n\n for (const localId of matchingIds) {\n const content = edited[localId as LocalDictionaryId]?.content ?? {};\n const node = getContentNodeByKeyPath(\n content,\n filteredKeyPath,\n this.currentLocale.value\n );\n if (node) return node;\n }\n\n return undefined;\n }\n\n /**\n * EDITOR mode: listen for CLIENT_READY and respond with EDITOR_ACTIVATE.\n * Also pings the client immediately in case it loaded before the editor.\n */\n private _setupEditorHandshake(): void {\n // When the client announces it is ready, activate it\n this._unsubClientReady = this.messenger.subscribe(\n MessageKey.INTLAYER_CLIENT_READY,\n () => {\n this.editorEnabled.set(true);\n this.messenger.send(MessageKey.INTLAYER_EDITOR_ACTIVATE);\n }\n );\n\n // Ping any already-running client (covers editor-opens-after-client scenario)\n this.messenger.send(MessageKey.INTLAYER_ARE_YOU_THERE);\n }\n\n private _setupActivationHandshake(): void {\n // Announce to the editor that the client is ready\n this.messenger.send(MessageKey.INTLAYER_CLIENT_READY);\n\n // Respond to \"are you there?\" pings from the editor\n this._unsubAreYouThere = this.messenger.subscribe(\n MessageKey.INTLAYER_ARE_YOU_THERE,\n () => {\n this.messenger.send(MessageKey.INTLAYER_CLIENT_READY);\n }\n );\n\n // When the editor activates us, enable the selector and broadcast state\n this._unsubActivate = this.messenger.subscribe(\n MessageKey.INTLAYER_EDITOR_ACTIVATE,\n () => {\n this.editorEnabled.set(true);\n this._broadcastData();\n }\n );\n }\n\n private _broadcastData(): void {\n const configVal = this.configuration.value;\n\n if (configVal) {\n this.messenger.send(\n `${MessageKey.INTLAYER_CONFIGURATION}/post`,\n configVal\n );\n }\n const localeVal = this.currentLocale.value;\n\n if (localeVal) {\n this.messenger.send(\n `${MessageKey.INTLAYER_CURRENT_LOCALE}/post`,\n localeVal\n );\n }\n const dicts = this.localeDictionaries.value;\n\n if (dicts) {\n this.messenger.send(\n `${MessageKey.INTLAYER_LOCALE_DICTIONARIES_CHANGED}/post`,\n dicts\n );\n }\n }\n\n private async _loadDictionaries(): Promise<void> {\n try {\n const mod = await import('@intlayer/unmerged-dictionaries-entry');\n const unmergedDictionaries = mod.getUnmergedDictionaries();\n const dictionariesList = Object.fromEntries(\n Object.values(unmergedDictionaries)\n .flat()\n .map((dictionary) => [dictionary.localId, dictionary])\n ) as DictionaryContent;\n\n this.localeDictionaries.set(dictionariesList);\n\n // If the editor already activated us before dictionaries finished loading,\n // re-broadcast now so the editor receives the dictionaries.\n if (this.editorEnabled.value) {\n this._broadcastData();\n }\n } catch (e) {\n // Dynamic entry not available (expected in editor mode or when not configured)\n console.warn('[intlayer] Failed to load unmerged dictionaries:', e);\n }\n }\n}\n"],"mappings":"+YAgDA,IAAa,EAAb,KAAgC,CAoB9B,YAAY,EAAkC,wBALG,yBACH,4BAEG,KAG/C,KAAK,MAAQ,EAAO,KACpB,KAAK,eAAiB,EAAO,cAE7B,KAAK,UAAY,IAAIA,EAAAA,oBAAoB,EAAO,UAAU,CAE1D,KAAK,cAAgB,IAAIC,EAAAA,uBACvBC,EAAAA,WAAW,wBACX,KAAK,UACL,CAAE,KAAM,GAAO,QAAS,GAAM,aAAc,GAAO,CACpD,CAED,KAAK,eAAiB,IAAID,EAAAA,uBACxBC,EAAAA,WAAW,iCACX,KAAK,UACL,CAAE,KAAM,GAAM,QAAS,GAAM,aAAc,KAAM,CAClD,CAED,KAAK,mBAAqB,IAAID,EAAAA,uBAC5BC,EAAAA,WAAW,qCACX,KAAK,UACN,CAED,KAAK,cAAgB,IAAID,EAAAA,uBACvBC,EAAAA,WAAW,gCACX,KAAK,UACN,CAED,KAAK,cAAgB,IAAID,EAAAA,uBACvBC,EAAAA,WAAW,uBACX,KAAK,UACL,CACE,KAAM,GACN,QAAS,GACT,GAAI,EAAO,cAAgB,CAAE,aAAc,EAAO,cAAe,CAAG,EAAE,CACvE,CACF,CAGD,KAAK,cAAgB,IAAID,EAAAA,uBACvBC,EAAAA,WAAW,wBACX,KAAK,UACL,CACE,KAAM,EAAO,OAAS,SACtB,QAAS,EAAO,OAAS,SAC1B,CACF,CAED,KAAK,YAAc,IAAIC,EAAAA,gBAAgB,KAAK,UAAU,CACtD,KAAK,mBAAqB,IAAIC,EAAAA,uBAAuB,KAAK,UAAU,CAGtE,OAAc,CACZ,KAAK,UAAU,OAAO,CACtB,KAAK,cAAc,OAAO,CAC1B,KAAK,eAAe,OAAO,CAC3B,KAAK,mBAAmB,OAAO,CAC/B,KAAK,cAAc,OAAO,CAC1B,KAAK,cAAc,OAAO,CAC1B,KAAK,cAAc,OAAO,CAEtB,KAAK,QAAU,UACjB,KAAK,YAAY,OAAO,CACxB,KAAK,mBAAmB,kBAAkB,CAC1C,KAAK,mBAAmB,CAExB,KAAK,UAAU,KAAK,GAAGF,EAAAA,WAAW,gCAAgC,MAAM,CAEpE,KAAK,gBAAgB,QAAQ,UAAY,IAC3C,KAAK,2BAA2B,GAGlC,KAAK,mBAAmB,aAAa,CACrC,KAAK,uBAAuB,EAIhC,MAAa,CACX,KAAK,qBAAqB,CAC1B,KAAK,kBAAkB,CACvB,KAAK,qBAAqB,CAC1B,KAAK,kBAAoB,KACzB,KAAK,eAAiB,KACtB,KAAK,kBAAoB,KACzB,KAAK,UAAU,MAAM,CACrB,KAAK,cAAc,MAAM,CACzB,KAAK,eAAe,MAAM,CAC1B,KAAK,mBAAmB,MAAM,CAC9B,KAAK,cAAc,MAAM,CACzB,KAAK,cAAc,MAAM,CACzB,KAAK,cAAc,MAAM,CACzB,KAAK,YAAY,MAAM,CACvB,KAAK,mBAAmB,iBAAiB,CACzC,KAAK,mBAAmB,YAAY,CAStC,YAAmB,CACb,KAAK,QAAU,UAEnB,KAAK,UAAU,KAAKA,EAAAA,WAAW,uBAAuB,CAKxD,yBAAyB,EAA0B,CACjD,IAAM,EAAW,EAAQ,OAAQ,GAAQ,EAAI,OAASG,EAAAA,SAAS,YAAY,CACrE,EAAO,KAAK,eAAe,MAE5B,GAEL,KAAK,eAAe,IAAI,CAAE,GAAG,EAAM,QAAS,EAAU,CAAC,CAKzD,oBAAoB,EAA8B,CAChD,GAAI,CAAC,EAAW,QAAS,OACzB,IAAM,EAAU,KAAK,mBAAmB,OAAS,EAAE,CAEnD,KAAK,mBAAmB,IAAI,CAC1B,GAAG,GACF,EAAW,SAA+B,EAC5C,CAAC,CAKJ,oBAAoB,EAA2B,CAC7C,GAAI,CAAC,EAAQ,QAAS,CACpB,QAAQ,MAAM,uCAAwC,EAAQ,CAC9D,OAEF,IAAM,EAAU,KAAK,cAAc,OAAS,EAAE,CAE9C,KAAK,cAAc,IAAI,CACrB,GAAG,GACF,EAAQ,SAA+B,EACzC,CAAC,CAGJ,iBACE,EACA,EACM,CACN,IAAM,EAAU,KAAK,cAAc,OAAS,EAAE,CAE9C,KAAK,cAAc,IAAI,CACrB,GAAG,GACF,GAAoB,CACnB,GAAG,EAAQ,GACX,QAAS,EACV,CACF,CAAC,CAGJ,WACE,EACA,EACA,EAAqB,EAAE,CACvB,EAAY,GACN,CACN,IAAM,EAAU,KAAK,cAAc,OAAS,EAAE,CAGxC,GAFc,KAAK,mBAAmB,OAAS,EAAE,EAEnB,IAAoB,QAClD,EAAiB,gBACrB,EAAQ,IAAoB,SAAW,EACxC,CAEG,EAAa,EACjB,GAAI,CAAC,EAAW,CACd,IAAI,EAAQ,EAEN,EAAe,EAAQ,MAAM,EAAG,GAAG,CACnC,EAAc,EAAQ,EAAQ,OAAS,GAEzC,EAAW,EAAY,IAE3B,MACE,EAAA,EAAA,yBAA+B,EAAgB,EAAW,GAC1D,QAEA,IACA,EACE,IAAU,EAAI,EAAY,IAAM,GAAG,EAAY,IAAI,IAAI,EAAM,GAC/D,EAAa,CACX,GAAG,EACH,CAAE,GAAG,EAAa,IAAK,EAAU,CAClC,CAIL,IAAM,GAAA,EAAA,EAAA,yBACJ,EACA,EACA,EACD,CAED,KAAK,cAAc,IAAI,CACrB,GAAG,GACF,GAAoB,CACnB,GAAG,EAAQ,GACX,QAAS,EACV,CACF,CAAC,CAGJ,cACE,EACA,EACA,EAAqB,EAAE,CACjB,CACN,IAAM,EAAU,KAAK,cAAc,OAAS,EAAE,CAExC,GADc,KAAK,mBAAmB,OAAS,EAAE,EACnB,IAAoB,QAIlD,GAAA,EAAA,EAAA,4BAHiB,gBACrB,EAAQ,IAAoB,SAAW,EACxC,CAC0D,EAAQ,EAAQ,CAE3E,KAAK,cAAc,IAAI,CACrB,GAAG,GACF,GAAoB,CACnB,GAAG,EAAQ,GACX,QAAS,EACV,CACF,CAAC,CAGJ,cACE,EACA,EACM,CACN,IAAM,EAAU,KAAK,cAAc,OAAS,EAAE,CAExC,GADc,KAAK,mBAAmB,OAAS,EAAE,EACnB,IAAoB,QAKlD,GAAA,EAAA,EAAA,yBAJiB,gBACrB,EAAQ,IAAoB,SAAW,EACxC,CAIC,GAAA,EAAA,EAAA,yBAH6C,EAAiB,EAAQ,CAKvE,CAED,KAAK,cAAc,IAAI,CACrB,GAAG,GACF,GAAoB,CACnB,GAAG,EAAQ,GACX,QAAS,EACV,CACF,CAAC,CAGJ,eAAe,EAA4C,CAEzD,IAAM,EAAU,CAAE,GADF,KAAK,cAAc,OAAS,EAAE,CAChB,CAE9B,OAAO,EAAQ,GAEf,KAAK,cAAc,IAAI,EAAQ,CAGjC,aAAa,EAA4C,CAEvD,IAAM,EAAW,CAAE,GADH,KAAK,cAAc,OAAS,EAAE,CACf,CAE/B,OAAO,EAAS,GAEhB,KAAK,cAAc,IAAI,EAAS,CAGlC,iBAAwB,CACtB,KAAK,cAAc,IAAI,EAAE,CAAC,CAG5B,gBACE,EACA,EACyB,CACzB,IAAM,EAAS,KAAK,cAAc,MAClC,GAAI,CAAC,EAAQ,OAEb,IAAM,EAAkB,EAAQ,OAC7B,GAAQ,EAAI,OAASA,EAAAA,SAAS,YAChC,CAKK,EAAc,KAAK,mBAAmB,MAM5C,GAHE,EAAuB,SAAS,UAAU,EAC1C,EAAuB,SAAS,WAAW,CAU3C,OANI,GAAe,EAAE,KAA0B,GAC7C,QAKF,EAAA,EAAA,yBAFE,EAAO,IAA8C,SAAW,EAAE,CAIlE,EACA,KAAK,cAAc,MACpB,CAGH,IAAM,EAAc,OAAO,KAAK,EAAO,CAAC,OACrC,GACC,EAAI,WAAW,GAAG,EAAuB,GAAG,GAE3C,CAAC,GAAe,KAAO,GAC3B,CAED,IAAK,IAAM,KAAW,EAAa,CAEjC,IAAM,GAAA,EAAA,EAAA,yBADU,EAAO,IAA+B,SAAW,EAAE,CAGjE,EACA,KAAK,cAAc,MACpB,CACD,GAAI,EAAM,OAAO,GAUrB,uBAAsC,CAEpC,KAAK,kBAAoB,KAAK,UAAU,UACtCH,EAAAA,WAAW,0BACL,CACJ,KAAK,cAAc,IAAI,GAAK,CAC5B,KAAK,UAAU,KAAKA,EAAAA,WAAW,yBAAyB,EAE3D,CAGD,KAAK,UAAU,KAAKA,EAAAA,WAAW,uBAAuB,CAGxD,2BAA0C,CAExC,KAAK,UAAU,KAAKA,EAAAA,WAAW,sBAAsB,CAGrD,KAAK,kBAAoB,KAAK,UAAU,UACtCA,EAAAA,WAAW,2BACL,CACJ,KAAK,UAAU,KAAKA,EAAAA,WAAW,sBAAsB,EAExD,CAGD,KAAK,eAAiB,KAAK,UAAU,UACnCA,EAAAA,WAAW,6BACL,CACJ,KAAK,cAAc,IAAI,GAAK,CAC5B,KAAK,gBAAgB,EAExB,CAGH,gBAA+B,CAC7B,IAAM,EAAY,KAAK,cAAc,MAEjC,GACF,KAAK,UAAU,KACb,GAAGA,EAAAA,WAAW,uBAAuB,OACrC,EACD,CAEH,IAAM,EAAY,KAAK,cAAc,MAEjC,GACF,KAAK,UAAU,KACb,GAAGA,EAAAA,WAAW,wBAAwB,OACtC,EACD,CAEH,IAAM,EAAQ,KAAK,mBAAmB,MAElC,GACF,KAAK,UAAU,KACb,GAAGA,EAAAA,WAAW,qCAAqC,OACnD,EACD,CAIL,MAAc,mBAAmC,CAC/C,GAAI,CAEF,IAAM,GADM,MAAM,OAAO,0CACQ,yBAAyB,CACpD,EAAmB,OAAO,YAC9B,OAAO,OAAO,EAAqB,CAChC,MAAM,CACN,IAAK,GAAe,CAAC,EAAW,QAAS,EAAW,CAAC,CACzD,CAED,KAAK,mBAAmB,IAAI,EAAiB,CAIzC,KAAK,cAAc,OACrB,KAAK,gBAAgB,OAEhB,EAAG,CAEV,QAAQ,KAAK,mDAAoD,EAAE"}
|
|
1
|
+
{"version":3,"file":"EditorStateManager.cjs","names":["CrossFrameMessenger","CrossFrameStateManager","MessageKey","UrlStateManager","IframeClickInterceptor","NodeType"],"sources":["../../../src/core/EditorStateManager.ts"],"sourcesContent":["import {\n editDictionaryByKeyPath,\n getContentNodeByKeyPath,\n renameContentNodeByKeyPath,\n} from '@intlayer/core/dictionaryManipulator';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type {\n ContentNode,\n Dictionary,\n LocalDictionaryId,\n} from '@intlayer/types/dictionary';\nimport type { KeyPath } from '@intlayer/types/keyPath';\nimport { NodeType } from '@intlayer/types/nodeType';\nimport { MessageKey } from '../messageKey';\nimport {\n CrossFrameMessenger,\n type MessengerConfig,\n} from './CrossFrameMessenger';\nimport { CrossFrameStateManager } from './CrossFrameStateManager';\nimport { IframeClickInterceptor } from './IframeClickInterceptor';\nimport { UrlStateManager } from './UrlStateManager';\n\nexport type DictionaryContent = Record<LocalDictionaryId, Dictionary>;\n\nexport type FileContent = {\n dictionaryKey: string;\n dictionaryLocalId?: LocalDictionaryId;\n keyPath?: KeyPath[];\n};\n\nexport type EditorStateManagerConfig = {\n /** 'client' = the app running inside the iframe; 'editor' = the editor wrapping the app */\n mode: 'editor' | 'client';\n /** Cross-frame messaging configuration */\n messenger: MessengerConfig;\n /** Optional initial Intlayer configuration to broadcast */\n configuration?: IntlayerConfig;\n};\n\n/**\n * EditorStateManager is the single entry point for all Intlayer editor state.\n * It is framework-agnostic: instantiate one instance at the root of the application\n * and subscribe to its EventTarget-based events from any framework adapter.\n *\n * Replaces all context providers, hooks and store files across React, Preact,\n * Solid, Svelte, and Vue integrations.\n */\nexport class EditorStateManager {\n readonly messenger: CrossFrameMessenger;\n readonly editorEnabled: CrossFrameStateManager<boolean>;\n readonly focusedContent: CrossFrameStateManager<FileContent | null>;\n readonly localeDictionaries: CrossFrameStateManager<DictionaryContent>;\n readonly editedContent: CrossFrameStateManager<DictionaryContent>;\n readonly configuration: CrossFrameStateManager<IntlayerConfig>;\n readonly currentLocale: CrossFrameStateManager<Locale | undefined>;\n\n private readonly _urlManager: UrlStateManager;\n private readonly _iframeInterceptor: IframeClickInterceptor;\n private readonly _mode: 'editor' | 'client';\n private readonly _configuration: IntlayerConfig | undefined;\n\n // Client-mode handshake subscribers\n private _unsubAreYouThere: (() => void) | null = null;\n private _unsubActivate: (() => void) | null = null;\n // Editor-mode handshake subscriber\n private _unsubClientReady: (() => void) | null = null;\n\n constructor(config: EditorStateManagerConfig) {\n this._mode = config.mode;\n this._configuration = config.configuration;\n\n this.messenger = new CrossFrameMessenger(config.messenger);\n\n this.editorEnabled = new CrossFrameStateManager<boolean>(\n MessageKey.INTLAYER_EDITOR_ENABLED,\n this.messenger,\n { emit: false, receive: true, initialValue: false }\n );\n\n this.focusedContent = new CrossFrameStateManager<FileContent | null>(\n MessageKey.INTLAYER_FOCUSED_CONTENT_CHANGED,\n this.messenger,\n { emit: true, receive: true, initialValue: null }\n );\n\n this.localeDictionaries = new CrossFrameStateManager<DictionaryContent>(\n MessageKey.INTLAYER_LOCALE_DICTIONARIES_CHANGED,\n this.messenger\n );\n\n this.editedContent = new CrossFrameStateManager<DictionaryContent>(\n MessageKey.INTLAYER_EDITED_CONTENT_CHANGED,\n this.messenger\n );\n\n this.configuration = new CrossFrameStateManager<IntlayerConfig>(\n MessageKey.INTLAYER_CONFIGURATION,\n this.messenger,\n {\n emit: true,\n receive: false,\n ...(config.configuration ? { initialValue: config.configuration } : {}),\n }\n );\n\n // Client emits its locale to the editor; editor receives it.\n this.currentLocale = new CrossFrameStateManager<Locale>(\n MessageKey.INTLAYER_CURRENT_LOCALE,\n this.messenger,\n {\n emit: config.mode === 'client',\n receive: config.mode === 'editor',\n }\n );\n\n this._urlManager = new UrlStateManager(this.messenger);\n this._iframeInterceptor = new IframeClickInterceptor(this.messenger);\n }\n\n start(): void {\n this.messenger.start();\n this.editorEnabled.start();\n this.focusedContent.start();\n this.localeDictionaries.start();\n this.editedContent.start();\n this.configuration.start();\n this.currentLocale.start();\n\n if (this._mode === 'client') {\n this._urlManager.start();\n this._iframeInterceptor.startInterceptor();\n this._loadDictionaries();\n // Request current edited content from the editor\n this.messenger.send(`${MessageKey.INTLAYER_EDITED_CONTENT_CHANGED}/get`);\n // Activation handshake: only participate if editor.enabled !== false\n if (this._configuration?.editor?.enabled !== false) {\n this._setupActivationHandshake();\n }\n } else {\n this._iframeInterceptor.startMerger();\n this._setupEditorHandshake();\n }\n }\n\n stop(): void {\n this._unsubAreYouThere?.();\n this._unsubActivate?.();\n this._unsubClientReady?.();\n this._unsubAreYouThere = null;\n this._unsubActivate = null;\n this._unsubClientReady = null;\n this.messenger.stop();\n this.editorEnabled.stop();\n this.focusedContent.stop();\n this.localeDictionaries.stop();\n this.editedContent.stop();\n this.configuration.stop();\n this.currentLocale.stop();\n this._urlManager.stop();\n this._iframeInterceptor.stopInterceptor();\n this._iframeInterceptor.stopMerger();\n }\n\n // ─── Handshake helpers ───────────────────────────────────────────────────────\n\n /**\n * EDITOR mode: re-send ARE_YOU_THERE to attempt re-connection with the client.\n * Call this when the user clicks \"Enable Editor\" or when the iframe reloads.\n */\n pingClient(): void {\n if (this._mode !== 'editor') return;\n\n this.messenger.send(MessageKey.INTLAYER_ARE_YOU_THERE);\n }\n\n // ─── Focus helpers ──────────────────────────────────────────────────────────\n\n setFocusedContentKeyPath(keyPath: KeyPath[]): void {\n const filtered = keyPath.filter((key) => key.type !== NodeType.Translation);\n const prev = this.focusedContent.value;\n\n if (!prev) return;\n\n this.focusedContent.set({ ...prev, keyPath: filtered });\n }\n\n // ─── Dictionary record helpers ───────────────────────────────────────────\n\n setLocaleDictionary(dictionary: Dictionary): void {\n if (!dictionary.localId) return;\n const current = this.localeDictionaries.value ?? {};\n\n this.localeDictionaries.set({\n ...current,\n [dictionary.localId as LocalDictionaryId]: dictionary,\n });\n }\n\n // ─── Edited content helpers ───────────────────────────────────────────────\n\n setEditedDictionary(newDict: Dictionary): void {\n if (!newDict.localId) {\n console.error('setEditedDictionary: missing localId', newDict);\n return;\n }\n const current = this.editedContent.value ?? {};\n\n this.editedContent.set({\n ...current,\n [newDict.localId as LocalDictionaryId]: newDict,\n });\n }\n\n setEditedContent(\n localDictionaryId: LocalDictionaryId,\n newValue: Dictionary['content']\n ): void {\n const current = this.editedContent.value ?? {};\n\n this.editedContent.set({\n ...current,\n [localDictionaryId]: {\n ...current[localDictionaryId],\n content: newValue,\n },\n });\n }\n\n addContent(\n localDictionaryId: LocalDictionaryId,\n newValue: ContentNode,\n keyPath: KeyPath[] = [],\n overwrite = true\n ): void {\n const current = this.editedContent.value ?? {};\n const localeDicts = this.localeDictionaries.value ?? {};\n\n const originalContent = localeDicts[localDictionaryId]?.content;\n const currentContent = structuredClone(\n current[localDictionaryId]?.content ?? originalContent\n );\n\n let newKeyPath = keyPath;\n if (!overwrite) {\n let index = 0;\n\n const otherKeyPath = keyPath.slice(0, -1);\n const lastKeyPath = keyPath[keyPath.length - 1];\n\n let finalKey = lastKeyPath.key;\n\n while (\n typeof getContentNodeByKeyPath(currentContent, newKeyPath) !==\n 'undefined'\n ) {\n index++;\n finalKey =\n index === 0 ? lastKeyPath.key : `${lastKeyPath.key} (${index})`;\n newKeyPath = [\n ...otherKeyPath,\n { ...lastKeyPath, key: finalKey } as KeyPath,\n ];\n }\n }\n\n const updatedContent = editDictionaryByKeyPath(\n currentContent,\n newKeyPath,\n newValue\n );\n\n this.editedContent.set({\n ...current,\n [localDictionaryId]: {\n ...current[localDictionaryId],\n content: updatedContent as Dictionary['content'],\n },\n });\n }\n\n renameContent(\n localDictionaryId: LocalDictionaryId,\n newKey: KeyPath['key'],\n keyPath: KeyPath[] = []\n ): void {\n const current = this.editedContent.value ?? {};\n const localeDicts = this.localeDictionaries.value ?? {};\n const originalContent = localeDicts[localDictionaryId]?.content;\n const currentContent = structuredClone(\n current[localDictionaryId]?.content ?? originalContent\n );\n const updated = renameContentNodeByKeyPath(currentContent, newKey, keyPath);\n\n this.editedContent.set({\n ...current,\n [localDictionaryId]: {\n ...current[localDictionaryId],\n content: updated as Dictionary['content'],\n },\n });\n }\n\n removeContent(\n localDictionaryId: LocalDictionaryId,\n keyPath: KeyPath[]\n ): void {\n const current = this.editedContent.value ?? {};\n const localeDicts = this.localeDictionaries.value ?? {};\n const originalContent = localeDicts[localDictionaryId]?.content;\n const currentContent = structuredClone(\n current[localDictionaryId]?.content ?? originalContent\n );\n const initialContent = getContentNodeByKeyPath(originalContent, keyPath);\n const restored = editDictionaryByKeyPath(\n currentContent,\n keyPath,\n initialContent\n );\n\n this.editedContent.set({\n ...current,\n [localDictionaryId]: {\n ...current[localDictionaryId],\n content: restored as Dictionary['content'],\n },\n });\n }\n\n restoreContent(localDictionaryId: LocalDictionaryId): void {\n const current = this.editedContent.value ?? {};\n const updated = { ...current };\n\n delete updated[localDictionaryId];\n\n this.editedContent.set(updated);\n }\n\n clearContent(localDictionaryId: LocalDictionaryId): void {\n const current = this.editedContent.value ?? {};\n const filtered = { ...current };\n\n delete filtered[localDictionaryId];\n\n this.editedContent.set(filtered);\n }\n\n clearAllContent(): void {\n this.editedContent.set({});\n }\n\n getContentValue(\n localDictionaryIdOrKey: LocalDictionaryId | string,\n keyPath: KeyPath[]\n ): ContentNode | undefined {\n const edited = this.editedContent.value;\n if (!edited) return undefined;\n\n const filteredKeyPath = keyPath.filter(\n (key) => key.type !== NodeType.Translation\n );\n\n // Only use edited content entries whose localId is known to this client.\n // This prevents stale edits from other apps (different framework demos) from\n // being applied when the editor sends back its stored editedContent.\n const localeDicts = this.localeDictionaries.value;\n\n const isDictionaryId =\n localDictionaryIdOrKey.includes(':local:') ||\n localDictionaryIdOrKey.includes(':remote:');\n\n if (isDictionaryId) {\n // If localeDictionaries is loaded, verify this localId belongs to us\n if (localeDicts && !(localDictionaryIdOrKey in localeDicts)) {\n return undefined;\n }\n const content =\n edited[localDictionaryIdOrKey as LocalDictionaryId]?.content ?? {};\n\n return getContentNodeByKeyPath(\n content,\n filteredKeyPath,\n this.currentLocale.value\n );\n }\n\n const matchingIds = Object.keys(edited).filter(\n (key) =>\n key.startsWith(`${localDictionaryIdOrKey}:`) &&\n // If localeDictionaries is loaded, only include known localIds\n (!localeDicts || key in localeDicts)\n );\n\n for (const localId of matchingIds) {\n const content = edited[localId as LocalDictionaryId]?.content ?? {};\n const node = getContentNodeByKeyPath(\n content,\n filteredKeyPath,\n this.currentLocale.value\n );\n if (node) return node;\n }\n\n return undefined;\n }\n\n /**\n * EDITOR mode: listen for CLIENT_READY and respond with EDITOR_ACTIVATE.\n * Also pings the client immediately in case it loaded before the editor.\n */\n private _setupEditorHandshake(): void {\n // When the client announces it is ready, activate it\n this._unsubClientReady = this.messenger.subscribe(\n MessageKey.INTLAYER_CLIENT_READY,\n () => {\n this.editorEnabled.set(true);\n this.messenger.send(MessageKey.INTLAYER_EDITOR_ACTIVATE);\n }\n );\n\n // Ping any already-running client (covers editor-opens-after-client scenario)\n this.messenger.send(MessageKey.INTLAYER_ARE_YOU_THERE);\n }\n\n private _setupActivationHandshake(): void {\n // Announce to the editor that the client is ready\n this.messenger.send(MessageKey.INTLAYER_CLIENT_READY);\n\n // Respond to \"are you there?\" pings from the editor\n this._unsubAreYouThere = this.messenger.subscribe(\n MessageKey.INTLAYER_ARE_YOU_THERE,\n () => {\n this.messenger.send(MessageKey.INTLAYER_CLIENT_READY);\n }\n );\n\n // When the editor activates us, enable the selector and broadcast state\n this._unsubActivate = this.messenger.subscribe(\n MessageKey.INTLAYER_EDITOR_ACTIVATE,\n () => {\n this.editorEnabled.set(true);\n this._broadcastData();\n }\n );\n }\n\n private _broadcastData(): void {\n const configVal = this.configuration.value;\n\n if (configVal) {\n this.messenger.send(\n `${MessageKey.INTLAYER_CONFIGURATION}/post`,\n configVal\n );\n }\n const localeVal = this.currentLocale.value;\n\n if (localeVal) {\n this.messenger.send(\n `${MessageKey.INTLAYER_CURRENT_LOCALE}/post`,\n localeVal\n );\n }\n const dicts = this.localeDictionaries.value;\n\n if (dicts) {\n this.messenger.send(\n `${MessageKey.INTLAYER_LOCALE_DICTIONARIES_CHANGED}/post`,\n dicts\n );\n }\n }\n\n private async _loadDictionaries(): Promise<void> {\n try {\n const mod = await import('@intlayer/unmerged-dictionaries-entry');\n const unmergedDictionaries = mod.getUnmergedDictionaries();\n const dictionariesList = Object.fromEntries(\n Object.values(unmergedDictionaries)\n .flat()\n .map((dictionary) => [dictionary.localId, dictionary])\n ) as DictionaryContent;\n\n this.localeDictionaries.set(dictionariesList);\n\n // If the editor already activated us before dictionaries finished loading,\n // re-broadcast now so the editor receives the dictionaries.\n if (this.editorEnabled.value) {\n this._broadcastData();\n }\n } catch (e) {\n // Dynamic entry not available (expected in editor mode or when not configured)\n console.warn('[intlayer] Failed to load unmerged dictionaries:', e);\n }\n }\n}\n"],"mappings":"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"}
|
package/dist/cjs/core/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./globalManager.cjs`),t=require(`./CrossFrameMessenger.cjs`),n=require(`./CrossFrameStateManager.cjs`),r=require(`./IframeClickInterceptor.cjs`),i=require(`./UrlStateManager.cjs`),a=require(`./EditorStateManager.cjs`),o=require(
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./globalManager.cjs`),t=require(`./CrossFrameMessenger.cjs`),n=require(`./CrossFrameStateManager.cjs`),r=require(`./IframeClickInterceptor.cjs`),i=require(`./UrlStateManager.cjs`),a=require(`./EditorStateManager.cjs`),o=require(`../components-DWu35JEb.cjs`);exports.CrossFrameMessenger=t.CrossFrameMessenger,exports.CrossFrameStateManager=n.CrossFrameStateManager,exports.EditorStateManager=a.EditorStateManager,exports.IframeClickInterceptor=r.IframeClickInterceptor,exports.UrlStateManager=i.UrlStateManager,exports.buildClientMessengerConfig=o.a,exports.getGlobalEditorManager=e.getGlobalEditorManager,exports.initEditorClient=o.o,exports.onGlobalEditorManagerChange=e.onGlobalEditorManagerChange,exports.setGlobalEditorManager=e.setGlobalEditorManager,exports.stopEditorClient=o.s;
|
|
@@ -1,2 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../
|
|
2
|
-
//# sourceMappingURL=initEditorClient.cjs.map
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../components-DWu35JEb.cjs`);exports.buildClientMessengerConfig=e.a,exports.initEditorClient=e.o,exports.stopEditorClient=e.s;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
function e(e,t,n,r){var i=arguments.length,a=i<3?t:r===null?r=Object.getOwnPropertyDescriptor(t,n):r,o;if(typeof Reflect==`object`&&typeof Reflect.decorate==`function`)a=Reflect.decorate(e,t,n,r);else for(var s=e.length-1;s>=0;s--)(o=e[s])&&(a=(i<3?o(a):i>3?o(t,n,a):o(t,n))||a);return i>3&&a&&Object.defineProperty(t,n,a),a}
|
|
1
|
+
function e(e,t,n,r){var i=arguments.length,a=i<3?t:r===null?r=Object.getOwnPropertyDescriptor(t,n):r,o;if(typeof Reflect==`object`&&typeof Reflect.decorate==`function`)a=Reflect.decorate(e,t,n,r);else for(var s=e.length-1;s>=0;s--)(o=e[s])&&(a=(i<3?o(a):i>3?o(t,n,a):o(t,n))||a);return i>3&&a&&Object.defineProperty(t,n,a),a}Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return e}});
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./compareUrls.cjs`),t=require(`./messageKey.cjs`),n=require(`./mergeIframeClick.cjs`),r=require(`./core/globalManager.cjs`),i=require(`./components/ContentSelectorWrapper.cjs`),a=require(`./components/EditedContent.cjs`),o=require(`./core/CrossFrameMessenger.cjs`),s=require(`./core/CrossFrameStateManager.cjs`),c=require(`./core/IframeClickInterceptor.cjs`),l=require(`./core/UrlStateManager.cjs`),u=require(`./core/EditorStateManager.cjs`),d=require(`./
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./compareUrls.cjs`),t=require(`./messageKey.cjs`),n=require(`./mergeIframeClick.cjs`),r=require(`./core/globalManager.cjs`),i=require(`./components/ContentSelectorWrapper.cjs`),a=require(`./components/EditedContent.cjs`),o=require(`./core/CrossFrameMessenger.cjs`),s=require(`./core/CrossFrameStateManager.cjs`),c=require(`./core/IframeClickInterceptor.cjs`),l=require(`./core/UrlStateManager.cjs`),u=require(`./core/EditorStateManager.cjs`),d=require(`./components-DWu35JEb.cjs`);require(`./core/index.cjs`),exports.CrossFrameMessenger=o.CrossFrameMessenger,exports.CrossFrameStateManager=s.CrossFrameStateManager,exports.EditorStateManager=u.EditorStateManager,exports.IframeClickInterceptor=c.IframeClickInterceptor,exports.IntlayerContentSelectorElement=d.t,exports.IntlayerContentSelectorWrapperElement=i.IntlayerContentSelectorWrapperElement,exports.IntlayerEditedContentElement=a.IntlayerEditedContentElement,exports.IntlayerEditorElement=d.r,exports.MessageKey=t.MessageKey,exports.UrlStateManager=l.UrlStateManager,exports.buildClientMessengerConfig=d.a,exports.compareUrls=e.compareUrls,exports.defineIntlayerContentSelectorWrapper=i.defineIntlayerContentSelectorWrapper,exports.defineIntlayerEditedContent=a.defineIntlayerEditedContent,exports.defineIntlayerEditorElement=d.i,exports.defineIntlayerElements=d.n,exports.getGlobalEditorManager=r.getGlobalEditorManager,exports.initEditorClient=d.o,exports.mergeIframeClick=n.mergeIframeClick,exports.onGlobalEditorManagerChange=r.onGlobalEditorManagerChange,exports.setGlobalEditorManager=r.setGlobalEditorManager,exports.stopEditorClient=d.s;
|
package/dist/cjs/isEnabled.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./chunk-Bmb41Sf3.cjs`);let t=require(`@intlayer/config/built`);t=e.t(t);const n=t.default.editor?.enabled&&typeof window<`u`&&window.self!==window.top;exports.isEnabled=n;
|
|
2
2
|
//# sourceMappingURL=isEnabled.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"isEnabled.cjs","names":["configuration"],"sources":["../../src/isEnabled.ts"],"sourcesContent":["import configuration from '@intlayer/config/built';\n\nexport const isEnabled =\n configuration.editor?.enabled && // Editor enabled in config\n typeof window !== 'undefined' && // Client side\n window.self !== window.top; // Is in iframe\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"isEnabled.cjs","names":["configuration"],"sources":["../../src/isEnabled.ts"],"sourcesContent":["import configuration from '@intlayer/config/built';\n\nexport const isEnabled =\n configuration.editor?.enabled && // Editor enabled in config\n typeof window !== 'undefined' && // Client side\n window.self !== window.top; // Is in iframe\n"],"mappings":"4JAEA,MAAa,EACXA,EAAAA,QAAc,QAAQ,SACtB,OAAO,OAAW,KAClB,OAAO,OAAS,OAAO"}
|
|
@@ -1,41 +1 @@
|
|
|
1
|
-
import{
|
|
2
|
-
:host {
|
|
3
|
-
display: contents;
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
.wrapper {
|
|
7
|
-
display: inline-block;
|
|
8
|
-
cursor: pointer;
|
|
9
|
-
user-select: none;
|
|
10
|
-
border-radius: 0.375rem;
|
|
11
|
-
outline-width: 2px;
|
|
12
|
-
outline-offset: 4px;
|
|
13
|
-
outline-style: solid;
|
|
14
|
-
outline-color: transparent;
|
|
15
|
-
transition: all 100ms 50ms ease-in-out;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
.wrapper[data-active] {
|
|
19
|
-
outline-color: inherit;
|
|
20
|
-
}
|
|
21
|
-
`}connectedCallback(){super.connectedCallback(),this._clickOutsideHandler=e=>{e.composedPath().includes(this)||(this._isSelectingState=!1,this._dispatch(`intlayer:click-outside`))},document.addEventListener(`mousedown`,this._clickOutsideHandler)}disconnectedCallback(){super.disconnectedCallback(),this._clickOutsideHandler&&=(document.removeEventListener(`mousedown`,this._clickOutsideHandler),null),this._clearPressTimer()}_clearPressTimer(){this._pressTimer!==null&&(clearTimeout(this._pressTimer),this._pressTimer=null)}_dispatch(e){this.dispatchEvent(new CustomEvent(e,{bubbles:!0,composed:!0}))}_handleMouseDown(){this._clearPressTimer(),this._pressTimer=setTimeout(()=>{this._isSelectingState=!0,this._dispatch(`intlayer:press`)},this.pressDuration)}_handleMouseEnter(){this._isHovered=!0,this._dispatch(`intlayer:hover`)}_handleMouseUpOrLeave(){this._isHovered&&(this._isHovered=!1,this._dispatch(`intlayer:unhover`)),this._clearPressTimer()}_handleClick(e){(this.isSelecting||this._isSelectingState)&&(e.preventDefault(),e.stopPropagation())}_handleBlur(){this._isSelectingState=!1}render(){return o`
|
|
22
|
-
<span
|
|
23
|
-
class="wrapper"
|
|
24
|
-
?data-active=${this.isSelecting||this._isSelectingState||this._isHovered}
|
|
25
|
-
role="button"
|
|
26
|
-
tabindex="0"
|
|
27
|
-
@mousedown=${this._handleMouseDown}
|
|
28
|
-
@mouseup=${this._handleMouseUpOrLeave}
|
|
29
|
-
@mouseleave=${this._handleMouseUpOrLeave}
|
|
30
|
-
@mouseenter=${this._handleMouseEnter}
|
|
31
|
-
@click=${this._handleClick}
|
|
32
|
-
@touchstart=${this._handleMouseDown}
|
|
33
|
-
@touchend=${this._handleMouseUpOrLeave}
|
|
34
|
-
@touchcancel=${this._handleMouseUpOrLeave}
|
|
35
|
-
@blur=${this._handleBlur}
|
|
36
|
-
@keyup=${()=>{}}
|
|
37
|
-
>
|
|
38
|
-
<slot></slot>
|
|
39
|
-
</span>
|
|
40
|
-
`}};e([s({type:Boolean,attribute:`is-selecting`})],u.prototype,`isSelecting`,void 0),e([s({type:Number,attribute:`press-duration`})],u.prototype,`pressDuration`,void 0),e([l()],u.prototype,`_isHovered`,void 0),e([l()],u.prototype,`_isSelectingState`,void 0),e([c(`.wrapper`)],u.prototype,`_wrapper`,void 0);const d=()=>{typeof customElements>`u`||(customElements.get(`intlayer-content-selector`)||customElements.define(`intlayer-content-selector`,u),t(),n(),r())};export{u as IntlayerContentSelectorElement,d as defineIntlayerElements};
|
|
41
|
-
//# sourceMappingURL=ContentSelector.mjs.map
|
|
1
|
+
import{n as e,t}from"../components-RtOXxg9h.mjs";export{t as IntlayerContentSelectorElement,e as defineIntlayerElements};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{MessageKey as e}from"../messageKey.mjs";import{getGlobalEditorManager as t,onGlobalEditorManagerChange as n}from"../core/globalManager.mjs";import{
|
|
1
|
+
import{MessageKey as e}from"../messageKey.mjs";import{getGlobalEditorManager as t,onGlobalEditorManagerChange as n}from"../core/globalManager.mjs";import{t as r}from"../decorate-BWURH4oJ.mjs";import{LitElement as i,css as a,html as o}from"lit";import{property as s,state as c}from"lit/decorators.js";import{isSameKeyPath as l}from"@intlayer/core/utils";import{NodeType as u}from"@intlayer/types/nodeType";var d=class extends i{constructor(...e){super(...e),this.keyPathJson=`[]`,this.dictionaryKey=``,this._editorEnabled=!1,this._isInIframe=!1,this._isSelected=!1,this._editedValue=void 0,this._unsubManager=null,this._unsubEnabled=null,this._unsubFocused=null,this._unsubEditedContent=null}static{this.styles=a`
|
|
2
2
|
:host {
|
|
3
3
|
display: contents;
|
|
4
4
|
}
|