@intlayer/next-i18next 8.12.5-canary.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +330 -0
- package/dist/cjs/_virtual/_rolldown/runtime.cjs +29 -0
- package/dist/cjs/appWithTranslation.cjs +31 -0
- package/dist/cjs/appWithTranslation.cjs.map +1 -0
- package/dist/cjs/index.cjs +69 -0
- package/dist/cjs/index.cjs.map +1 -0
- package/dist/cjs/packages/@intlayer/editor/dist/esm/compareUrls.cjs +39 -0
- package/dist/cjs/packages/@intlayer/editor/dist/esm/compareUrls.cjs.map +1 -0
- package/dist/cjs/packages/@intlayer/editor/dist/esm/components/ContentSelector.cjs +161 -0
- package/dist/cjs/packages/@intlayer/editor/dist/esm/components/ContentSelector.cjs.map +1 -0
- package/dist/cjs/packages/@intlayer/editor/dist/esm/components/ContentSelectorWrapper.cjs +269 -0
- package/dist/cjs/packages/@intlayer/editor/dist/esm/components/ContentSelectorWrapper.cjs.map +1 -0
- package/dist/cjs/packages/@intlayer/editor/dist/esm/components/EditedContent.cjs +161 -0
- package/dist/cjs/packages/@intlayer/editor/dist/esm/components/EditedContent.cjs.map +1 -0
- package/dist/cjs/packages/@intlayer/editor/dist/esm/components/IntlayerEditorElement.cjs +88 -0
- package/dist/cjs/packages/@intlayer/editor/dist/esm/components/IntlayerEditorElement.cjs.map +1 -0
- package/dist/cjs/packages/@intlayer/editor/dist/esm/components/defineIntlayerElements.cjs +27 -0
- package/dist/cjs/packages/@intlayer/editor/dist/esm/components/defineIntlayerElements.cjs.map +1 -0
- package/dist/cjs/packages/@intlayer/editor/dist/esm/core/CrossFrameMessenger.cjs +80 -0
- package/dist/cjs/packages/@intlayer/editor/dist/esm/core/CrossFrameMessenger.cjs.map +1 -0
- package/dist/cjs/packages/@intlayer/editor/dist/esm/core/CrossFrameStateManager.cjs +75 -0
- package/dist/cjs/packages/@intlayer/editor/dist/esm/core/CrossFrameStateManager.cjs.map +1 -0
- package/dist/cjs/packages/@intlayer/editor/dist/esm/core/EditorStateManager.cjs +383 -0
- package/dist/cjs/packages/@intlayer/editor/dist/esm/core/EditorStateManager.cjs.map +1 -0
- package/dist/cjs/packages/@intlayer/editor/dist/esm/core/IframeClickInterceptor.cjs +45 -0
- package/dist/cjs/packages/@intlayer/editor/dist/esm/core/IframeClickInterceptor.cjs.map +1 -0
- package/dist/cjs/packages/@intlayer/editor/dist/esm/core/UrlStateManager.cjs +59 -0
- package/dist/cjs/packages/@intlayer/editor/dist/esm/core/UrlStateManager.cjs.map +1 -0
- package/dist/cjs/packages/@intlayer/editor/dist/esm/core/editedContentBus.cjs +36 -0
- package/dist/cjs/packages/@intlayer/editor/dist/esm/core/editedContentBus.cjs.map +1 -0
- package/dist/cjs/packages/@intlayer/editor/dist/esm/core/focusedContentBus.cjs +42 -0
- package/dist/cjs/packages/@intlayer/editor/dist/esm/core/focusedContentBus.cjs.map +1 -0
- package/dist/cjs/packages/@intlayer/editor/dist/esm/core/globalManager.cjs +82 -0
- package/dist/cjs/packages/@intlayer/editor/dist/esm/core/globalManager.cjs.map +1 -0
- package/dist/cjs/packages/@intlayer/editor/dist/esm/core/initEditorClient.cjs +55 -0
- package/dist/cjs/packages/@intlayer/editor/dist/esm/core/initEditorClient.cjs.map +1 -0
- package/dist/cjs/packages/@intlayer/editor/dist/esm/index.cjs +19 -0
- package/dist/cjs/packages/@intlayer/editor/dist/esm/isEnabled.cjs +9 -0
- package/dist/cjs/packages/@intlayer/editor/dist/esm/isEnabled.cjs.map +1 -0
- package/dist/cjs/packages/@intlayer/editor/dist/esm/mergeIframeClick.cjs +22 -0
- package/dist/cjs/packages/@intlayer/editor/dist/esm/mergeIframeClick.cjs.map +1 -0
- package/dist/cjs/packages/@intlayer/unmerged-dictionaries-entry/dist/esm/index.cjs +32 -0
- package/dist/cjs/packages/@intlayer/unmerged-dictionaries-entry/dist/esm/index.cjs.map +1 -0
- package/dist/cjs/packages/react-intlayer/dist/esm/client/IntlayerContext.cjs +25 -0
- package/dist/cjs/packages/react-intlayer/dist/esm/client/IntlayerContext.cjs.map +1 -0
- package/dist/cjs/packages/react-intlayer/dist/esm/client/IntlayerProvider.cjs +78 -0
- package/dist/cjs/packages/react-intlayer/dist/esm/client/IntlayerProvider.cjs.map +1 -0
- package/dist/cjs/packages/react-intlayer/dist/esm/client/useLocaleStorage.cjs +24 -0
- package/dist/cjs/packages/react-intlayer/dist/esm/client/useLocaleStorage.cjs.map +1 -0
- package/dist/cjs/packages/react-intlayer/dist/esm/editor/EditorProvider.cjs +11 -0
- package/dist/cjs/packages/react-intlayer/dist/esm/editor/EditorProvider.cjs.map +1 -0
- package/dist/cjs/packages/react-intlayer/dist/esm/editor/useEditor.cjs +39 -0
- package/dist/cjs/packages/react-intlayer/dist/esm/editor/useEditor.cjs.map +1 -0
- package/dist/cjs/plugin/index.cjs +170 -0
- package/dist/cjs/plugin/index.cjs.map +1 -0
- package/dist/cjs/serverSideTranslations.cjs +46 -0
- package/dist/cjs/serverSideTranslations.cjs.map +1 -0
- package/dist/esm/_virtual/_rolldown/runtime.mjs +8 -0
- package/dist/esm/appWithTranslation.mjs +29 -0
- package/dist/esm/appWithTranslation.mjs.map +1 -0
- package/dist/esm/index.mjs +11 -0
- package/dist/esm/index.mjs.map +1 -0
- package/dist/esm/packages/@intlayer/editor/dist/esm/compareUrls.mjs +38 -0
- package/dist/esm/packages/@intlayer/editor/dist/esm/compareUrls.mjs.map +1 -0
- package/dist/esm/packages/@intlayer/editor/dist/esm/components/ContentSelector.mjs +160 -0
- package/dist/esm/packages/@intlayer/editor/dist/esm/components/ContentSelector.mjs.map +1 -0
- package/dist/esm/packages/@intlayer/editor/dist/esm/components/ContentSelectorWrapper.mjs +266 -0
- package/dist/esm/packages/@intlayer/editor/dist/esm/components/ContentSelectorWrapper.mjs.map +1 -0
- package/dist/esm/packages/@intlayer/editor/dist/esm/components/EditedContent.mjs +159 -0
- package/dist/esm/packages/@intlayer/editor/dist/esm/components/EditedContent.mjs.map +1 -0
- package/dist/esm/packages/@intlayer/editor/dist/esm/components/IntlayerEditorElement.mjs +88 -0
- package/dist/esm/packages/@intlayer/editor/dist/esm/components/IntlayerEditorElement.mjs.map +1 -0
- package/dist/esm/packages/@intlayer/editor/dist/esm/components/defineIntlayerElements.mjs +26 -0
- package/dist/esm/packages/@intlayer/editor/dist/esm/components/defineIntlayerElements.mjs.map +1 -0
- package/dist/esm/packages/@intlayer/editor/dist/esm/core/CrossFrameMessenger.mjs +80 -0
- package/dist/esm/packages/@intlayer/editor/dist/esm/core/CrossFrameMessenger.mjs.map +1 -0
- package/dist/esm/packages/@intlayer/editor/dist/esm/core/CrossFrameStateManager.mjs +74 -0
- package/dist/esm/packages/@intlayer/editor/dist/esm/core/CrossFrameStateManager.mjs.map +1 -0
- package/dist/esm/packages/@intlayer/editor/dist/esm/core/EditorStateManager.mjs +381 -0
- package/dist/esm/packages/@intlayer/editor/dist/esm/core/EditorStateManager.mjs.map +1 -0
- package/dist/esm/packages/@intlayer/editor/dist/esm/core/IframeClickInterceptor.mjs +45 -0
- package/dist/esm/packages/@intlayer/editor/dist/esm/core/IframeClickInterceptor.mjs.map +1 -0
- package/dist/esm/packages/@intlayer/editor/dist/esm/core/UrlStateManager.mjs +58 -0
- package/dist/esm/packages/@intlayer/editor/dist/esm/core/UrlStateManager.mjs.map +1 -0
- package/dist/esm/packages/@intlayer/editor/dist/esm/core/editedContentBus.mjs +33 -0
- package/dist/esm/packages/@intlayer/editor/dist/esm/core/editedContentBus.mjs.map +1 -0
- package/dist/esm/packages/@intlayer/editor/dist/esm/core/focusedContentBus.mjs +39 -0
- package/dist/esm/packages/@intlayer/editor/dist/esm/core/focusedContentBus.mjs.map +1 -0
- package/dist/esm/packages/@intlayer/editor/dist/esm/core/globalManager.mjs +79 -0
- package/dist/esm/packages/@intlayer/editor/dist/esm/core/globalManager.mjs.map +1 -0
- package/dist/esm/packages/@intlayer/editor/dist/esm/core/initEditorClient.mjs +52 -0
- package/dist/esm/packages/@intlayer/editor/dist/esm/core/initEditorClient.mjs.map +1 -0
- package/dist/esm/packages/@intlayer/editor/dist/esm/index.mjs +18 -0
- package/dist/esm/packages/@intlayer/editor/dist/esm/isEnabled.mjs +8 -0
- package/dist/esm/packages/@intlayer/editor/dist/esm/isEnabled.mjs.map +1 -0
- package/dist/esm/packages/@intlayer/editor/dist/esm/mergeIframeClick.mjs +21 -0
- package/dist/esm/packages/@intlayer/editor/dist/esm/mergeIframeClick.mjs.map +1 -0
- package/dist/esm/packages/@intlayer/unmerged-dictionaries-entry/dist/esm/index.browser.mjs +6 -0
- package/dist/esm/packages/@intlayer/unmerged-dictionaries-entry/dist/esm/index.browser.mjs.map +1 -0
- package/dist/esm/packages/react-intlayer/dist/esm/client/IntlayerContext.mjs +23 -0
- package/dist/esm/packages/react-intlayer/dist/esm/client/IntlayerContext.mjs.map +1 -0
- package/dist/esm/packages/react-intlayer/dist/esm/client/IntlayerProvider.mjs +77 -0
- package/dist/esm/packages/react-intlayer/dist/esm/client/IntlayerProvider.mjs.map +1 -0
- package/dist/esm/packages/react-intlayer/dist/esm/client/useLocaleStorage.mjs +22 -0
- package/dist/esm/packages/react-intlayer/dist/esm/client/useLocaleStorage.mjs.map +1 -0
- package/dist/esm/packages/react-intlayer/dist/esm/editor/EditorProvider.mjs +11 -0
- package/dist/esm/packages/react-intlayer/dist/esm/editor/EditorProvider.mjs.map +1 -0
- package/dist/esm/packages/react-intlayer/dist/esm/editor/useEditor.mjs +38 -0
- package/dist/esm/packages/react-intlayer/dist/esm/editor/useEditor.mjs.map +1 -0
- package/dist/esm/plugin/index.mjs +165 -0
- package/dist/esm/plugin/index.mjs.map +1 -0
- package/dist/esm/serverSideTranslations.mjs +44 -0
- package/dist/esm/serverSideTranslations.mjs.map +1 -0
- package/dist/types/appWithTranslation.d.ts +18 -0
- package/dist/types/appWithTranslation.d.ts.map +1 -0
- package/dist/types/index.d.ts +10 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/plugin/index.d.ts +23 -0
- package/dist/types/plugin/index.d.ts.map +1 -0
- package/dist/types/serverSideTranslations.d.ts +33 -0
- package/dist/types/serverSideTranslations.d.ts.map +1 -0
- package/package.json +116 -0
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { compareUrls } from "../compareUrls.mjs";
|
|
2
|
+
|
|
3
|
+
//#region ../../packages/@intlayer/editor/dist/esm/core/CrossFrameMessenger.mjs
|
|
4
|
+
const randomUUID = () => Math.random().toString(36).slice(2);
|
|
5
|
+
/**
|
|
6
|
+
* CrossFrameMessenger manages all cross-frame postMessage communication.
|
|
7
|
+
* It owns a single window message listener and routes incoming messages to
|
|
8
|
+
* type-specific subscribers.
|
|
9
|
+
*
|
|
10
|
+
* Replaces CommunicatorContext + useCrossFrameMessageListener across all frameworks.
|
|
11
|
+
*/
|
|
12
|
+
var CrossFrameMessenger = class {
|
|
13
|
+
senderId;
|
|
14
|
+
_config;
|
|
15
|
+
_subscribers = /* @__PURE__ */ new Map();
|
|
16
|
+
_windowHandler = null;
|
|
17
|
+
/** Tracks recently processed messageIds to discard duplicates (same payload sent to multiple origins) */
|
|
18
|
+
_seenMessageIds = /* @__PURE__ */ new Set();
|
|
19
|
+
constructor(config) {
|
|
20
|
+
this._config = config;
|
|
21
|
+
this.senderId = randomUUID();
|
|
22
|
+
}
|
|
23
|
+
/** Start listening for incoming messages on window. */
|
|
24
|
+
start() {
|
|
25
|
+
if (typeof window === "undefined") return;
|
|
26
|
+
if (this._windowHandler) return;
|
|
27
|
+
this._windowHandler = (event) => {
|
|
28
|
+
this._handleMessage(event);
|
|
29
|
+
};
|
|
30
|
+
window.addEventListener("message", this._windowHandler);
|
|
31
|
+
}
|
|
32
|
+
/** Stop listening and clean up. */
|
|
33
|
+
stop() {
|
|
34
|
+
if (this._windowHandler) {
|
|
35
|
+
window.removeEventListener("message", this._windowHandler);
|
|
36
|
+
this._windowHandler = null;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/** Send a message payload to all configured target origins. */
|
|
40
|
+
send(type, data) {
|
|
41
|
+
const payload = {
|
|
42
|
+
type,
|
|
43
|
+
data,
|
|
44
|
+
senderId: this.senderId,
|
|
45
|
+
messageId: randomUUID()
|
|
46
|
+
};
|
|
47
|
+
for (const origin of this._config.allowedOrigins) if (origin) this._config.postMessageFn(payload, origin);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Subscribe to messages of a given type.
|
|
51
|
+
* Returns an unsubscribe function.
|
|
52
|
+
*/
|
|
53
|
+
subscribe(type, handler) {
|
|
54
|
+
if (!this._subscribers.has(type)) this._subscribers.set(type, /* @__PURE__ */ new Set());
|
|
55
|
+
this._subscribers.get(type).add(handler);
|
|
56
|
+
return () => {
|
|
57
|
+
this._subscribers.get(type)?.delete(handler);
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
_handleMessage(event) {
|
|
61
|
+
const payload = event.data;
|
|
62
|
+
if (!payload || typeof payload !== "object") return;
|
|
63
|
+
const { type, data, senderId: msgSenderId, messageId } = payload;
|
|
64
|
+
if (!type || typeof type !== "string") return;
|
|
65
|
+
if (msgSenderId === this.senderId) return;
|
|
66
|
+
if (messageId) {
|
|
67
|
+
if (this._seenMessageIds.has(messageId)) return;
|
|
68
|
+
this._seenMessageIds.add(messageId);
|
|
69
|
+
if (this._seenMessageIds.size > 200) this._seenMessageIds.clear();
|
|
70
|
+
}
|
|
71
|
+
const { allowedOrigins } = this._config;
|
|
72
|
+
if (!(!allowedOrigins || allowedOrigins.length === 0 || allowedOrigins.includes("*") || allowedOrigins.filter((url) => Boolean(url) && url !== "").some((url) => compareUrls(url, event.origin)))) return;
|
|
73
|
+
const handlers = this._subscribers.get(type);
|
|
74
|
+
if (handlers) for (const handler of handlers) handler(data, msgSenderId);
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
//#endregion
|
|
79
|
+
export { CrossFrameMessenger };
|
|
80
|
+
//# sourceMappingURL=CrossFrameMessenger.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CrossFrameMessenger.mjs","names":[],"sources":["../../../../../../../../../../packages/@intlayer/editor/dist/esm/core/CrossFrameMessenger.mjs"],"sourcesContent":["import { compareUrls } from \"../compareUrls.mjs\";\n\n//#region src/core/CrossFrameMessenger.ts\nconst randomUUID = () => Math.random().toString(36).slice(2);\n/**\n* CrossFrameMessenger manages all cross-frame postMessage communication.\n* It owns a single window message listener and routes incoming messages to\n* type-specific subscribers.\n*\n* Replaces CommunicatorContext + useCrossFrameMessageListener across all frameworks.\n*/\nvar CrossFrameMessenger = class {\n\tsenderId;\n\t_config;\n\t_subscribers = /* @__PURE__ */ new Map();\n\t_windowHandler = null;\n\t/** Tracks recently processed messageIds to discard duplicates (same payload sent to multiple origins) */\n\t_seenMessageIds = /* @__PURE__ */ new Set();\n\tconstructor(config) {\n\t\tthis._config = config;\n\t\tthis.senderId = randomUUID();\n\t}\n\t/** Start listening for incoming messages on window. */\n\tstart() {\n\t\tif (typeof window === \"undefined\") return;\n\t\tif (this._windowHandler) return;\n\t\tthis._windowHandler = (event) => {\n\t\t\tthis._handleMessage(event);\n\t\t};\n\t\twindow.addEventListener(\"message\", this._windowHandler);\n\t}\n\t/** Stop listening and clean up. */\n\tstop() {\n\t\tif (this._windowHandler) {\n\t\t\twindow.removeEventListener(\"message\", this._windowHandler);\n\t\t\tthis._windowHandler = null;\n\t\t}\n\t}\n\t/** Send a message payload to all configured target origins. */\n\tsend(type, data) {\n\t\tconst payload = {\n\t\t\ttype,\n\t\t\tdata,\n\t\t\tsenderId: this.senderId,\n\t\t\tmessageId: randomUUID()\n\t\t};\n\t\tfor (const origin of this._config.allowedOrigins) if (origin) this._config.postMessageFn(payload, origin);\n\t}\n\t/**\n\t* Subscribe to messages of a given type.\n\t* Returns an unsubscribe function.\n\t*/\n\tsubscribe(type, handler) {\n\t\tif (!this._subscribers.has(type)) this._subscribers.set(type, /* @__PURE__ */ new Set());\n\t\tthis._subscribers.get(type).add(handler);\n\t\treturn () => {\n\t\t\tthis._subscribers.get(type)?.delete(handler);\n\t\t};\n\t}\n\t_handleMessage(event) {\n\t\tconst payload = event.data;\n\t\tif (!payload || typeof payload !== \"object\") return;\n\t\tconst { type, data, senderId: msgSenderId, messageId } = payload;\n\t\tif (!type || typeof type !== \"string\") return;\n\t\tif (msgSenderId === this.senderId) return;\n\t\tif (messageId) {\n\t\t\tif (this._seenMessageIds.has(messageId)) return;\n\t\t\tthis._seenMessageIds.add(messageId);\n\t\t\tif (this._seenMessageIds.size > 200) this._seenMessageIds.clear();\n\t\t}\n\t\tconst { allowedOrigins } = this._config;\n\t\tif (!(!allowedOrigins || allowedOrigins.length === 0 || allowedOrigins.includes(\"*\") || allowedOrigins.filter((url) => Boolean(url) && url !== \"\").some((url) => compareUrls(url, event.origin)))) return;\n\t\tconst handlers = this._subscribers.get(type);\n\t\tif (handlers) for (const handler of handlers) handler(data, msgSenderId);\n\t}\n};\n\n//#endregion\nexport { CrossFrameMessenger };\n//# sourceMappingURL=CrossFrameMessenger.mjs.map"],"mappings":";;;AAGA,MAAM,mBAAmB,KAAK,QAAQ,CAAC,SAAS,GAAG,CAAC,MAAM,EAAE;;;;;;;;AAQ5D,IAAI,sBAAsB,MAAM;CAC/B;CACA;CACA,+BAA+B,IAAI,KAAK;CACxC,iBAAiB;;CAEjB,kCAAkC,IAAI,KAAK;CAC3C,YAAY,QAAQ;AACnB,OAAK,UAAU;AACf,OAAK,WAAW,YAAY;;;CAG7B,QAAQ;AACP,MAAI,OAAO,WAAW,YAAa;AACnC,MAAI,KAAK,eAAgB;AACzB,OAAK,kBAAkB,UAAU;AAChC,QAAK,eAAe,MAAM;;AAE3B,SAAO,iBAAiB,WAAW,KAAK,eAAe;;;CAGxD,OAAO;AACN,MAAI,KAAK,gBAAgB;AACxB,UAAO,oBAAoB,WAAW,KAAK,eAAe;AAC1D,QAAK,iBAAiB;;;;CAIxB,KAAK,MAAM,MAAM;EAChB,MAAM,UAAU;GACf;GACA;GACA,UAAU,KAAK;GACf,WAAW,YAAY;GACvB;AACD,OAAK,MAAM,UAAU,KAAK,QAAQ,eAAgB,KAAI,OAAQ,MAAK,QAAQ,cAAc,SAAS,OAAO;;;;;;CAM1G,UAAU,MAAM,SAAS;AACxB,MAAI,CAAC,KAAK,aAAa,IAAI,KAAK,CAAE,MAAK,aAAa,IAAI,sBAAsB,IAAI,KAAK,CAAC;AACxF,OAAK,aAAa,IAAI,KAAK,CAAC,IAAI,QAAQ;AACxC,eAAa;AACZ,QAAK,aAAa,IAAI,KAAK,EAAE,OAAO,QAAQ;;;CAG9C,eAAe,OAAO;EACrB,MAAM,UAAU,MAAM;AACtB,MAAI,CAAC,WAAW,OAAO,YAAY,SAAU;EAC7C,MAAM,EAAE,MAAM,MAAM,UAAU,aAAa,cAAc;AACzD,MAAI,CAAC,QAAQ,OAAO,SAAS,SAAU;AACvC,MAAI,gBAAgB,KAAK,SAAU;AACnC,MAAI,WAAW;AACd,OAAI,KAAK,gBAAgB,IAAI,UAAU,CAAE;AACzC,QAAK,gBAAgB,IAAI,UAAU;AACnC,OAAI,KAAK,gBAAgB,OAAO,IAAK,MAAK,gBAAgB,OAAO;;EAElE,MAAM,EAAE,mBAAmB,KAAK;AAChC,MAAI,EAAE,CAAC,kBAAkB,eAAe,WAAW,KAAK,eAAe,SAAS,IAAI,IAAI,eAAe,QAAQ,QAAQ,QAAQ,IAAI,IAAI,QAAQ,GAAG,CAAC,MAAM,QAAQ,YAAY,KAAK,MAAM,OAAO,CAAC,EAAG;EACnM,MAAM,WAAW,KAAK,aAAa,IAAI,KAAK;AAC5C,MAAI,SAAU,MAAK,MAAM,WAAW,SAAU,SAAQ,MAAM,YAAY"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
//#region ../../packages/@intlayer/editor/dist/esm/core/CrossFrameStateManager.mjs
|
|
2
|
+
/**
|
|
3
|
+
* CrossFrameStateManager synchronizes a single named value across frames using
|
|
4
|
+
* the postMessage API via CrossFrameMessenger.
|
|
5
|
+
*
|
|
6
|
+
* Protocol:
|
|
7
|
+
* `{key}/post` — broadcast a new value
|
|
8
|
+
* `{key}/get` — request the current value from other frames
|
|
9
|
+
*
|
|
10
|
+
* Replaces useCrossFrameState across all frameworks.
|
|
11
|
+
*
|
|
12
|
+
* @fires change — CustomEvent<T> dispatched whenever the value changes (local set or received)
|
|
13
|
+
*/
|
|
14
|
+
var CrossFrameStateManager = class extends EventTarget {
|
|
15
|
+
_value;
|
|
16
|
+
_key;
|
|
17
|
+
_messenger;
|
|
18
|
+
_options;
|
|
19
|
+
_unsubscribers = [];
|
|
20
|
+
constructor(key, messenger, options = {}) {
|
|
21
|
+
super();
|
|
22
|
+
this._key = key;
|
|
23
|
+
this._messenger = messenger;
|
|
24
|
+
this._options = {
|
|
25
|
+
emit: options.emit ?? true,
|
|
26
|
+
receive: options.receive ?? true
|
|
27
|
+
};
|
|
28
|
+
if (options.initialValue !== void 0) this._value = options.initialValue;
|
|
29
|
+
}
|
|
30
|
+
get value() {
|
|
31
|
+
return this._value;
|
|
32
|
+
}
|
|
33
|
+
/** Update the value locally and broadcast it to other frames if emit is enabled. */
|
|
34
|
+
set(newValue) {
|
|
35
|
+
this._value = newValue;
|
|
36
|
+
this.dispatchEvent(new CustomEvent("change", { detail: newValue }));
|
|
37
|
+
if (this._options.emit) this._messenger.send(`${this._key}/post`, newValue);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Start listening for incoming state updates and responding to /get requests.
|
|
41
|
+
* If receive=true and no initial value is set, sends a /get to request the current value.
|
|
42
|
+
*/
|
|
43
|
+
start() {
|
|
44
|
+
if (this._options.receive) {
|
|
45
|
+
const unsub = this._messenger.subscribe(`${this._key}/post`, (data) => {
|
|
46
|
+
this._value = data;
|
|
47
|
+
this.dispatchEvent(new CustomEvent("change", { detail: data }));
|
|
48
|
+
});
|
|
49
|
+
this._unsubscribers.push(unsub);
|
|
50
|
+
}
|
|
51
|
+
if (this._options.emit) {
|
|
52
|
+
const unsub = this._messenger.subscribe(`${this._key}/get`, (_, originSenderId) => {
|
|
53
|
+
if (originSenderId === this._messenger.senderId) return;
|
|
54
|
+
if (this._value === void 0) return;
|
|
55
|
+
this._messenger.send(`${this._key}/post`, this._value);
|
|
56
|
+
});
|
|
57
|
+
this._unsubscribers.push(unsub);
|
|
58
|
+
}
|
|
59
|
+
if (this._options.receive && this._value === void 0) this._messenger.send(`${this._key}/get`);
|
|
60
|
+
}
|
|
61
|
+
/** Stop all listeners. */
|
|
62
|
+
stop() {
|
|
63
|
+
for (const unsub of this._unsubscribers) unsub();
|
|
64
|
+
this._unsubscribers.length = 0;
|
|
65
|
+
}
|
|
66
|
+
/** Broadcast the current value to all frames (useful after reconnect). */
|
|
67
|
+
postCurrentValue() {
|
|
68
|
+
if (this._value !== void 0) this._messenger.send(`${this._key}/post`, this._value);
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
//#endregion
|
|
73
|
+
export { CrossFrameStateManager };
|
|
74
|
+
//# sourceMappingURL=CrossFrameStateManager.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CrossFrameStateManager.mjs","names":[],"sources":["../../../../../../../../../../packages/@intlayer/editor/dist/esm/core/CrossFrameStateManager.mjs"],"sourcesContent":["//#region src/core/CrossFrameStateManager.ts\n/**\n* CrossFrameStateManager synchronizes a single named value across frames using\n* the postMessage API via CrossFrameMessenger.\n*\n* Protocol:\n* `{key}/post` — broadcast a new value\n* `{key}/get` — request the current value from other frames\n*\n* Replaces useCrossFrameState across all frameworks.\n*\n* @fires change — CustomEvent<T> dispatched whenever the value changes (local set or received)\n*/\nvar CrossFrameStateManager = class extends EventTarget {\n\t_value;\n\t_key;\n\t_messenger;\n\t_options;\n\t_unsubscribers = [];\n\tconstructor(key, messenger, options = {}) {\n\t\tsuper();\n\t\tthis._key = key;\n\t\tthis._messenger = messenger;\n\t\tthis._options = {\n\t\t\temit: options.emit ?? true,\n\t\t\treceive: options.receive ?? true\n\t\t};\n\t\tif (options.initialValue !== void 0) this._value = options.initialValue;\n\t}\n\tget value() {\n\t\treturn this._value;\n\t}\n\t/** Update the value locally and broadcast it to other frames if emit is enabled. */\n\tset(newValue) {\n\t\tthis._value = newValue;\n\t\tthis.dispatchEvent(new CustomEvent(\"change\", { detail: newValue }));\n\t\tif (this._options.emit) this._messenger.send(`${this._key}/post`, newValue);\n\t}\n\t/**\n\t* Start listening for incoming state updates and responding to /get requests.\n\t* If receive=true and no initial value is set, sends a /get to request the current value.\n\t*/\n\tstart() {\n\t\tif (this._options.receive) {\n\t\t\tconst unsub = this._messenger.subscribe(`${this._key}/post`, (data) => {\n\t\t\t\tthis._value = data;\n\t\t\t\tthis.dispatchEvent(new CustomEvent(\"change\", { detail: data }));\n\t\t\t});\n\t\t\tthis._unsubscribers.push(unsub);\n\t\t}\n\t\tif (this._options.emit) {\n\t\t\tconst unsub = this._messenger.subscribe(`${this._key}/get`, (_, originSenderId) => {\n\t\t\t\tif (originSenderId === this._messenger.senderId) return;\n\t\t\t\tif (this._value === void 0) return;\n\t\t\t\tthis._messenger.send(`${this._key}/post`, this._value);\n\t\t\t});\n\t\t\tthis._unsubscribers.push(unsub);\n\t\t}\n\t\tif (this._options.receive && this._value === void 0) this._messenger.send(`${this._key}/get`);\n\t}\n\t/** Stop all listeners. */\n\tstop() {\n\t\tfor (const unsub of this._unsubscribers) unsub();\n\t\tthis._unsubscribers.length = 0;\n\t}\n\t/** Broadcast the current value to all frames (useful after reconnect). */\n\tpostCurrentValue() {\n\t\tif (this._value !== void 0) this._messenger.send(`${this._key}/post`, this._value);\n\t}\n};\n\n//#endregion\nexport { CrossFrameStateManager };\n//# sourceMappingURL=CrossFrameStateManager.mjs.map"],"mappings":";;;;;;;;;;;;;AAaA,IAAI,yBAAyB,cAAc,YAAY;CACtD;CACA;CACA;CACA;CACA,iBAAiB,EAAE;CACnB,YAAY,KAAK,WAAW,UAAU,EAAE,EAAE;AACzC,SAAO;AACP,OAAK,OAAO;AACZ,OAAK,aAAa;AAClB,OAAK,WAAW;GACf,MAAM,QAAQ,QAAQ;GACtB,SAAS,QAAQ,WAAW;GAC5B;AACD,MAAI,QAAQ,iBAAiB,KAAK,EAAG,MAAK,SAAS,QAAQ;;CAE5D,IAAI,QAAQ;AACX,SAAO,KAAK;;;CAGb,IAAI,UAAU;AACb,OAAK,SAAS;AACd,OAAK,cAAc,IAAI,YAAY,UAAU,EAAE,QAAQ,UAAU,CAAC,CAAC;AACnE,MAAI,KAAK,SAAS,KAAM,MAAK,WAAW,KAAK,GAAG,KAAK,KAAK,QAAQ,SAAS;;;;;;CAM5E,QAAQ;AACP,MAAI,KAAK,SAAS,SAAS;GAC1B,MAAM,QAAQ,KAAK,WAAW,UAAU,GAAG,KAAK,KAAK,SAAS,SAAS;AACtE,SAAK,SAAS;AACd,SAAK,cAAc,IAAI,YAAY,UAAU,EAAE,QAAQ,MAAM,CAAC,CAAC;KAC9D;AACF,QAAK,eAAe,KAAK,MAAM;;AAEhC,MAAI,KAAK,SAAS,MAAM;GACvB,MAAM,QAAQ,KAAK,WAAW,UAAU,GAAG,KAAK,KAAK,QAAQ,GAAG,mBAAmB;AAClF,QAAI,mBAAmB,KAAK,WAAW,SAAU;AACjD,QAAI,KAAK,WAAW,KAAK,EAAG;AAC5B,SAAK,WAAW,KAAK,GAAG,KAAK,KAAK,QAAQ,KAAK,OAAO;KACrD;AACF,QAAK,eAAe,KAAK,MAAM;;AAEhC,MAAI,KAAK,SAAS,WAAW,KAAK,WAAW,KAAK,EAAG,MAAK,WAAW,KAAK,GAAG,KAAK,KAAK,MAAM;;;CAG9F,OAAO;AACN,OAAK,MAAM,SAAS,KAAK,eAAgB,QAAO;AAChD,OAAK,eAAe,SAAS;;;CAG9B,mBAAmB;AAClB,MAAI,KAAK,WAAW,KAAK,EAAG,MAAK,WAAW,KAAK,GAAG,KAAK,KAAK,QAAQ,KAAK,OAAO"}
|
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
import { CrossFrameMessenger } from "./CrossFrameMessenger.mjs";
|
|
2
|
+
import { CrossFrameStateManager } from "./CrossFrameStateManager.mjs";
|
|
3
|
+
import { getGlobalEditedContent, setGlobalEditedContent, subscribeToGlobalEditedContent } from "./editedContentBus.mjs";
|
|
4
|
+
import { getGlobalFocusedContent, setGlobalFocusedContent, subscribeToGlobalFocusedContent } from "./focusedContentBus.mjs";
|
|
5
|
+
import { IframeClickInterceptor } from "./IframeClickInterceptor.mjs";
|
|
6
|
+
import { UrlStateManager } from "./UrlStateManager.mjs";
|
|
7
|
+
import * as NodeTypes from "@intlayer/types/nodeType";
|
|
8
|
+
import { editDictionaryByKeyPath, getContentNodeByKeyPath, renameContentNodeByKeyPath } from "@intlayer/core/dictionaryManipulator";
|
|
9
|
+
|
|
10
|
+
//#region ../../packages/@intlayer/editor/dist/esm/core/EditorStateManager.mjs
|
|
11
|
+
/**
|
|
12
|
+
* EditorStateManager is the single entry point for all Intlayer editor state.
|
|
13
|
+
* It is framework-agnostic: instantiate one instance at the root of the application
|
|
14
|
+
* and subscribe to its EventTarget-based events from any framework adapter.
|
|
15
|
+
*
|
|
16
|
+
* Replaces all context providers, hooks and store files across React, Preact,
|
|
17
|
+
* Solid, Svelte, and Vue integrations.
|
|
18
|
+
*/
|
|
19
|
+
var EditorStateManager = class {
|
|
20
|
+
messenger;
|
|
21
|
+
editorEnabled;
|
|
22
|
+
focusedContent;
|
|
23
|
+
localeDictionaries;
|
|
24
|
+
editedContent;
|
|
25
|
+
configuration;
|
|
26
|
+
currentLocale;
|
|
27
|
+
displayedDictionaryKeys;
|
|
28
|
+
_urlManager;
|
|
29
|
+
_iframeInterceptor;
|
|
30
|
+
_mode;
|
|
31
|
+
_configuration;
|
|
32
|
+
_unsubAreYouThere = null;
|
|
33
|
+
_unsubActivate = null;
|
|
34
|
+
_unsubClientReady = null;
|
|
35
|
+
_displayedKeysObserver = null;
|
|
36
|
+
_displayedKeysTimer = null;
|
|
37
|
+
_displayedKeysListeners = [];
|
|
38
|
+
_editedContentFromBus = false;
|
|
39
|
+
_unsubGlobalEditedContent = null;
|
|
40
|
+
_editedContentBusHandler = null;
|
|
41
|
+
_focusedContentFromBus = false;
|
|
42
|
+
_unsubGlobalFocusedContent = null;
|
|
43
|
+
_focusedContentBusHandler = null;
|
|
44
|
+
constructor(config) {
|
|
45
|
+
this._mode = config.mode;
|
|
46
|
+
this._configuration = config.configuration;
|
|
47
|
+
this.messenger = new CrossFrameMessenger(config.messenger);
|
|
48
|
+
this.editorEnabled = new CrossFrameStateManager("INTLAYER_EDITOR_ENABLED", this.messenger, {
|
|
49
|
+
emit: false,
|
|
50
|
+
receive: true,
|
|
51
|
+
initialValue: false
|
|
52
|
+
});
|
|
53
|
+
this.focusedContent = new CrossFrameStateManager("INTLAYER_FOCUSED_CONTENT_CHANGED", this.messenger, {
|
|
54
|
+
emit: true,
|
|
55
|
+
receive: true,
|
|
56
|
+
initialValue: null
|
|
57
|
+
});
|
|
58
|
+
this.localeDictionaries = new CrossFrameStateManager("INTLAYER_LOCALE_DICTIONARIES_CHANGED", this.messenger);
|
|
59
|
+
this.editedContent = new CrossFrameStateManager("INTLAYER_EDITED_CONTENT_CHANGED", this.messenger);
|
|
60
|
+
this.configuration = new CrossFrameStateManager("INTLAYER_CONFIGURATION", this.messenger, {
|
|
61
|
+
emit: true,
|
|
62
|
+
receive: false,
|
|
63
|
+
...config.configuration ? { initialValue: config.configuration } : {}
|
|
64
|
+
});
|
|
65
|
+
this.currentLocale = new CrossFrameStateManager("INTLAYER_CURRENT_LOCALE", this.messenger, {
|
|
66
|
+
emit: config.mode === "client",
|
|
67
|
+
receive: config.mode === "editor"
|
|
68
|
+
});
|
|
69
|
+
this.displayedDictionaryKeys = new CrossFrameStateManager("INTLAYER_DISPLAYED_DICTIONARY_KEYS", this.messenger, {
|
|
70
|
+
emit: config.mode === "client",
|
|
71
|
+
receive: config.mode === "editor",
|
|
72
|
+
initialValue: []
|
|
73
|
+
});
|
|
74
|
+
this._urlManager = new UrlStateManager(this.messenger);
|
|
75
|
+
this._iframeInterceptor = new IframeClickInterceptor(this.messenger);
|
|
76
|
+
}
|
|
77
|
+
start() {
|
|
78
|
+
this.messenger.start();
|
|
79
|
+
this.editorEnabled.start();
|
|
80
|
+
this.focusedContent.start();
|
|
81
|
+
this.localeDictionaries.start();
|
|
82
|
+
this.editedContent.start();
|
|
83
|
+
this.configuration.start();
|
|
84
|
+
this.currentLocale.start();
|
|
85
|
+
this.displayedDictionaryKeys.start();
|
|
86
|
+
this._startEditedContentBusSync();
|
|
87
|
+
this._startFocusedContentBusSync();
|
|
88
|
+
if (this._mode === "client") {
|
|
89
|
+
this._urlManager.start();
|
|
90
|
+
this._iframeInterceptor.startInterceptor();
|
|
91
|
+
this._loadDictionaries();
|
|
92
|
+
this._startDisplayedDictionariesTracking();
|
|
93
|
+
this.messenger.send(`INTLAYER_EDITED_CONTENT_CHANGED/get`);
|
|
94
|
+
if (this._configuration?.editor?.enabled !== false) this._setupActivationHandshake();
|
|
95
|
+
} else {
|
|
96
|
+
this._iframeInterceptor.startMerger();
|
|
97
|
+
this._setupEditorHandshake();
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
stop() {
|
|
101
|
+
this._unsubAreYouThere?.();
|
|
102
|
+
this._unsubActivate?.();
|
|
103
|
+
this._unsubClientReady?.();
|
|
104
|
+
this._unsubAreYouThere = null;
|
|
105
|
+
this._unsubActivate = null;
|
|
106
|
+
this._unsubClientReady = null;
|
|
107
|
+
this.messenger.stop();
|
|
108
|
+
this.editorEnabled.stop();
|
|
109
|
+
this.focusedContent.stop();
|
|
110
|
+
this.localeDictionaries.stop();
|
|
111
|
+
this.editedContent.stop();
|
|
112
|
+
this.configuration.stop();
|
|
113
|
+
this.currentLocale.stop();
|
|
114
|
+
this.displayedDictionaryKeys.stop();
|
|
115
|
+
this._stopDisplayedDictionariesTracking();
|
|
116
|
+
this._stopEditedContentBusSync();
|
|
117
|
+
this._stopFocusedContentBusSync();
|
|
118
|
+
this._urlManager.stop();
|
|
119
|
+
this._iframeInterceptor.stopInterceptor();
|
|
120
|
+
this._iframeInterceptor.stopMerger();
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* EDITOR mode: re-send ARE_YOU_THERE to attempt re-connection with the client.
|
|
124
|
+
* Call this when the user clicks "Enable Editor" or when the iframe reloads.
|
|
125
|
+
*/
|
|
126
|
+
pingClient() {
|
|
127
|
+
if (this._mode !== "editor") return;
|
|
128
|
+
this.messenger.send("INTLAYER_ARE_YOU_THERE");
|
|
129
|
+
}
|
|
130
|
+
setFocusedContentKeyPath(keyPath) {
|
|
131
|
+
const filtered = keyPath.filter((key) => key.type !== NodeTypes.TRANSLATION);
|
|
132
|
+
const prev = this.focusedContent.value;
|
|
133
|
+
if (!prev) return;
|
|
134
|
+
this.focusedContent.set({
|
|
135
|
+
...prev,
|
|
136
|
+
keyPath: filtered
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
setLocaleDictionary(dictionary) {
|
|
140
|
+
if (!dictionary.localId) return;
|
|
141
|
+
const current = this.localeDictionaries.value ?? {};
|
|
142
|
+
this.localeDictionaries.set({
|
|
143
|
+
...current,
|
|
144
|
+
[dictionary.localId]: dictionary
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
setEditedDictionary(newDict) {
|
|
148
|
+
if (!newDict.localId) {
|
|
149
|
+
console.error("setEditedDictionary: missing localId", newDict);
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
const current = this.editedContent.value ?? {};
|
|
153
|
+
this.editedContent.set({
|
|
154
|
+
...current,
|
|
155
|
+
[newDict.localId]: newDict
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
setEditedContent(localDictionaryId, newValue) {
|
|
159
|
+
const current = this.editedContent.value ?? {};
|
|
160
|
+
this.editedContent.set({
|
|
161
|
+
...current,
|
|
162
|
+
[localDictionaryId]: {
|
|
163
|
+
...current[localDictionaryId],
|
|
164
|
+
content: newValue
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
addContent(localDictionaryId, newValue, keyPath = [], overwrite = true) {
|
|
169
|
+
const current = this.editedContent.value ?? {};
|
|
170
|
+
const originalContent = (this.localeDictionaries.value ?? {})[localDictionaryId]?.content;
|
|
171
|
+
const currentContent = structuredClone(current[localDictionaryId]?.content ?? originalContent);
|
|
172
|
+
let newKeyPath = keyPath;
|
|
173
|
+
if (!overwrite) {
|
|
174
|
+
let index = 0;
|
|
175
|
+
const otherKeyPath = keyPath.slice(0, -1);
|
|
176
|
+
const lastKeyPath = keyPath[keyPath.length - 1];
|
|
177
|
+
let finalKey = lastKeyPath.key;
|
|
178
|
+
while (typeof getContentNodeByKeyPath(currentContent, newKeyPath) !== "undefined") {
|
|
179
|
+
index++;
|
|
180
|
+
finalKey = index === 0 ? lastKeyPath.key : `${lastKeyPath.key} (${index})`;
|
|
181
|
+
newKeyPath = [...otherKeyPath, {
|
|
182
|
+
...lastKeyPath,
|
|
183
|
+
key: finalKey
|
|
184
|
+
}];
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
const updatedContent = editDictionaryByKeyPath(currentContent, newKeyPath, newValue);
|
|
188
|
+
this.editedContent.set({
|
|
189
|
+
...current,
|
|
190
|
+
[localDictionaryId]: {
|
|
191
|
+
...current[localDictionaryId],
|
|
192
|
+
content: updatedContent
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
renameContent(localDictionaryId, newKey, keyPath = []) {
|
|
197
|
+
const current = this.editedContent.value ?? {};
|
|
198
|
+
const originalContent = (this.localeDictionaries.value ?? {})[localDictionaryId]?.content;
|
|
199
|
+
const updated = renameContentNodeByKeyPath(structuredClone(current[localDictionaryId]?.content ?? originalContent), newKey, keyPath);
|
|
200
|
+
this.editedContent.set({
|
|
201
|
+
...current,
|
|
202
|
+
[localDictionaryId]: {
|
|
203
|
+
...current[localDictionaryId],
|
|
204
|
+
content: updated
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
removeContent(localDictionaryId, keyPath) {
|
|
209
|
+
const current = this.editedContent.value ?? {};
|
|
210
|
+
const originalContent = (this.localeDictionaries.value ?? {})[localDictionaryId]?.content;
|
|
211
|
+
const restored = editDictionaryByKeyPath(structuredClone(current[localDictionaryId]?.content ?? originalContent), keyPath, getContentNodeByKeyPath(originalContent, keyPath));
|
|
212
|
+
this.editedContent.set({
|
|
213
|
+
...current,
|
|
214
|
+
[localDictionaryId]: {
|
|
215
|
+
...current[localDictionaryId],
|
|
216
|
+
content: restored
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
restoreContent(localDictionaryId) {
|
|
221
|
+
const updated = { ...this.editedContent.value ?? {} };
|
|
222
|
+
delete updated[localDictionaryId];
|
|
223
|
+
this.editedContent.set(updated);
|
|
224
|
+
}
|
|
225
|
+
clearContent(localDictionaryId) {
|
|
226
|
+
const filtered = { ...this.editedContent.value ?? {} };
|
|
227
|
+
delete filtered[localDictionaryId];
|
|
228
|
+
this.editedContent.set(filtered);
|
|
229
|
+
}
|
|
230
|
+
clearAllContent() {
|
|
231
|
+
this.editedContent.set({});
|
|
232
|
+
}
|
|
233
|
+
getContentValue(localDictionaryIdOrKey, keyPath) {
|
|
234
|
+
const edited = this.editedContent.value;
|
|
235
|
+
if (!edited) return void 0;
|
|
236
|
+
const filteredKeyPath = keyPath.filter((key) => key.type !== NodeTypes.TRANSLATION);
|
|
237
|
+
const localeDicts = this.localeDictionaries.value;
|
|
238
|
+
if (localDictionaryIdOrKey.includes(":local:") || localDictionaryIdOrKey.includes(":remote:")) {
|
|
239
|
+
if (localeDicts && !(localDictionaryIdOrKey in localeDicts)) return;
|
|
240
|
+
return getContentNodeByKeyPath(edited[localDictionaryIdOrKey]?.content ?? {}, filteredKeyPath, this.currentLocale.value);
|
|
241
|
+
}
|
|
242
|
+
const matchingIds = Object.keys(edited).filter((key) => key.startsWith(`${localDictionaryIdOrKey}:`) && (!localeDicts || key in localeDicts));
|
|
243
|
+
for (const localId of matchingIds) {
|
|
244
|
+
const node = getContentNodeByKeyPath(edited[localId]?.content ?? {}, filteredKeyPath, this.currentLocale.value);
|
|
245
|
+
if (node) return node;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
_startEditedContentBusSync() {
|
|
249
|
+
this._editedContentBusHandler = (e) => {
|
|
250
|
+
if (this._editedContentFromBus) return;
|
|
251
|
+
const content = e.detail;
|
|
252
|
+
setGlobalEditedContent(content, this.messenger.senderId);
|
|
253
|
+
};
|
|
254
|
+
this.editedContent.addEventListener("change", this._editedContentBusHandler);
|
|
255
|
+
this._unsubGlobalEditedContent = subscribeToGlobalEditedContent((content, sourceId) => {
|
|
256
|
+
if (sourceId === this.messenger.senderId) return;
|
|
257
|
+
this._editedContentFromBus = true;
|
|
258
|
+
this.editedContent.set(content);
|
|
259
|
+
this._editedContentFromBus = false;
|
|
260
|
+
});
|
|
261
|
+
const existing = getGlobalEditedContent();
|
|
262
|
+
if (Object.keys(existing).length > 0) {
|
|
263
|
+
this._editedContentFromBus = true;
|
|
264
|
+
this.editedContent.set(existing);
|
|
265
|
+
this._editedContentFromBus = false;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
_stopEditedContentBusSync() {
|
|
269
|
+
if (this._editedContentBusHandler) {
|
|
270
|
+
this.editedContent.removeEventListener("change", this._editedContentBusHandler);
|
|
271
|
+
this._editedContentBusHandler = null;
|
|
272
|
+
}
|
|
273
|
+
this._unsubGlobalEditedContent?.();
|
|
274
|
+
this._unsubGlobalEditedContent = null;
|
|
275
|
+
}
|
|
276
|
+
_startFocusedContentBusSync() {
|
|
277
|
+
this._focusedContentBusHandler = (e) => {
|
|
278
|
+
if (this._focusedContentFromBus) return;
|
|
279
|
+
const content = e.detail;
|
|
280
|
+
setGlobalFocusedContent(content, this.messenger.senderId);
|
|
281
|
+
};
|
|
282
|
+
this.focusedContent.addEventListener("change", this._focusedContentBusHandler);
|
|
283
|
+
this._unsubGlobalFocusedContent = subscribeToGlobalFocusedContent((content, sourceId) => {
|
|
284
|
+
if (sourceId === this.messenger.senderId) return;
|
|
285
|
+
this._focusedContentFromBus = true;
|
|
286
|
+
this.focusedContent.set(content);
|
|
287
|
+
this._focusedContentFromBus = false;
|
|
288
|
+
});
|
|
289
|
+
const existing = getGlobalFocusedContent();
|
|
290
|
+
if (existing !== void 0) {
|
|
291
|
+
this._focusedContentFromBus = true;
|
|
292
|
+
this.focusedContent.set(existing);
|
|
293
|
+
this._focusedContentFromBus = false;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
_stopFocusedContentBusSync() {
|
|
297
|
+
if (this._focusedContentBusHandler) {
|
|
298
|
+
this.focusedContent.removeEventListener("change", this._focusedContentBusHandler);
|
|
299
|
+
this._focusedContentBusHandler = null;
|
|
300
|
+
}
|
|
301
|
+
this._unsubGlobalFocusedContent?.();
|
|
302
|
+
this._unsubGlobalFocusedContent = null;
|
|
303
|
+
}
|
|
304
|
+
_scanDisplayedDictionaryKeys() {
|
|
305
|
+
if (typeof document === "undefined") return;
|
|
306
|
+
const elements = document.querySelectorAll("intlayer-content-selector-wrapper[dictionary-key]");
|
|
307
|
+
const keys = Array.from(new Set(Array.from(elements).map((el) => el.getAttribute("dictionary-key") ?? "").filter(Boolean)));
|
|
308
|
+
this.displayedDictionaryKeys.set(keys);
|
|
309
|
+
}
|
|
310
|
+
_startDisplayedDictionariesTracking() {
|
|
311
|
+
if (typeof document === "undefined" || typeof MutationObserver === "undefined") return;
|
|
312
|
+
const schedule = () => {
|
|
313
|
+
if (this._displayedKeysTimer) clearTimeout(this._displayedKeysTimer);
|
|
314
|
+
this._displayedKeysTimer = setTimeout(() => this._scanDisplayedDictionaryKeys(), 100);
|
|
315
|
+
};
|
|
316
|
+
this._displayedKeysObserver = new MutationObserver(schedule);
|
|
317
|
+
this._displayedKeysObserver.observe(document.body, {
|
|
318
|
+
childList: true,
|
|
319
|
+
subtree: true
|
|
320
|
+
});
|
|
321
|
+
for (const evt of ["locationchange", "popstate"]) {
|
|
322
|
+
const listener = schedule;
|
|
323
|
+
window.addEventListener(evt, listener);
|
|
324
|
+
this._displayedKeysListeners.push([evt, listener]);
|
|
325
|
+
}
|
|
326
|
+
this._scanDisplayedDictionaryKeys();
|
|
327
|
+
}
|
|
328
|
+
_stopDisplayedDictionariesTracking() {
|
|
329
|
+
this._displayedKeysObserver?.disconnect();
|
|
330
|
+
this._displayedKeysObserver = null;
|
|
331
|
+
if (this._displayedKeysTimer) {
|
|
332
|
+
clearTimeout(this._displayedKeysTimer);
|
|
333
|
+
this._displayedKeysTimer = null;
|
|
334
|
+
}
|
|
335
|
+
for (const [evt, listener] of this._displayedKeysListeners) window.removeEventListener(evt, listener);
|
|
336
|
+
this._displayedKeysListeners = [];
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* EDITOR mode: listen for CLIENT_READY and respond with EDITOR_ACTIVATE.
|
|
340
|
+
* Also pings the client immediately in case it loaded before the editor.
|
|
341
|
+
*/
|
|
342
|
+
_setupEditorHandshake() {
|
|
343
|
+
this._unsubClientReady = this.messenger.subscribe("INTLAYER_CLIENT_READY", () => {
|
|
344
|
+
this.editorEnabled.set(true);
|
|
345
|
+
this.messenger.send("INTLAYER_EDITOR_ACTIVATE");
|
|
346
|
+
});
|
|
347
|
+
this.messenger.send("INTLAYER_ARE_YOU_THERE");
|
|
348
|
+
}
|
|
349
|
+
_setupActivationHandshake() {
|
|
350
|
+
this.messenger.send("INTLAYER_CLIENT_READY");
|
|
351
|
+
this._unsubAreYouThere = this.messenger.subscribe("INTLAYER_ARE_YOU_THERE", () => {
|
|
352
|
+
this.messenger.send("INTLAYER_CLIENT_READY");
|
|
353
|
+
});
|
|
354
|
+
this._unsubActivate = this.messenger.subscribe("INTLAYER_EDITOR_ACTIVATE", () => {
|
|
355
|
+
this.editorEnabled.set(true);
|
|
356
|
+
this._broadcastData();
|
|
357
|
+
});
|
|
358
|
+
}
|
|
359
|
+
_broadcastData() {
|
|
360
|
+
const configVal = this.configuration.value;
|
|
361
|
+
if (configVal) this.messenger.send(`INTLAYER_CONFIGURATION/post`, configVal);
|
|
362
|
+
const localeVal = this.currentLocale.value;
|
|
363
|
+
if (localeVal) this.messenger.send(`INTLAYER_CURRENT_LOCALE/post`, localeVal);
|
|
364
|
+
const dicts = this.localeDictionaries.value;
|
|
365
|
+
if (dicts) this.messenger.send(`INTLAYER_LOCALE_DICTIONARIES_CHANGED/post`, dicts);
|
|
366
|
+
}
|
|
367
|
+
async _loadDictionaries() {
|
|
368
|
+
try {
|
|
369
|
+
const unmergedDictionaries = (await import("../../../../unmerged-dictionaries-entry/dist/esm/index.browser.mjs")).getUnmergedDictionaries();
|
|
370
|
+
const dictionariesList = Object.fromEntries(Object.values(unmergedDictionaries).flat().map((dictionary) => [dictionary.localId, dictionary]));
|
|
371
|
+
this.localeDictionaries.set(dictionariesList);
|
|
372
|
+
if (this.editorEnabled.value) this._broadcastData();
|
|
373
|
+
} catch (e) {
|
|
374
|
+
console.warn("[intlayer] Failed to load unmerged dictionaries:", e);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
};
|
|
378
|
+
|
|
379
|
+
//#endregion
|
|
380
|
+
export { EditorStateManager };
|
|
381
|
+
//# sourceMappingURL=EditorStateManager.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EditorStateManager.mjs","names":[],"sources":["../../../../../../../../../../packages/@intlayer/editor/dist/esm/core/EditorStateManager.mjs"],"sourcesContent":["import { MessageKey } from \"../messageKey.mjs\";\nimport { CrossFrameMessenger } from \"./CrossFrameMessenger.mjs\";\nimport { CrossFrameStateManager } from \"./CrossFrameStateManager.mjs\";\nimport { getGlobalEditedContent, setGlobalEditedContent, subscribeToGlobalEditedContent } from \"./editedContentBus.mjs\";\nimport { getGlobalFocusedContent, setGlobalFocusedContent, subscribeToGlobalFocusedContent } from \"./focusedContentBus.mjs\";\nimport { IframeClickInterceptor } from \"./IframeClickInterceptor.mjs\";\nimport { UrlStateManager } from \"./UrlStateManager.mjs\";\nimport * as NodeTypes from \"@intlayer/types/nodeType\";\nimport { editDictionaryByKeyPath, getContentNodeByKeyPath, renameContentNodeByKeyPath } from \"@intlayer/core/dictionaryManipulator\";\n\n//#region src/core/EditorStateManager.ts\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*/\nvar EditorStateManager = class {\n\tmessenger;\n\teditorEnabled;\n\tfocusedContent;\n\tlocaleDictionaries;\n\teditedContent;\n\tconfiguration;\n\tcurrentLocale;\n\tdisplayedDictionaryKeys;\n\t_urlManager;\n\t_iframeInterceptor;\n\t_mode;\n\t_configuration;\n\t_unsubAreYouThere = null;\n\t_unsubActivate = null;\n\t_unsubClientReady = null;\n\t_displayedKeysObserver = null;\n\t_displayedKeysTimer = null;\n\t_displayedKeysListeners = [];\n\t_editedContentFromBus = false;\n\t_unsubGlobalEditedContent = null;\n\t_editedContentBusHandler = null;\n\t_focusedContentFromBus = false;\n\t_unsubGlobalFocusedContent = null;\n\t_focusedContentBusHandler = null;\n\tconstructor(config) {\n\t\tthis._mode = config.mode;\n\t\tthis._configuration = config.configuration;\n\t\tthis.messenger = new CrossFrameMessenger(config.messenger);\n\t\tthis.editorEnabled = new CrossFrameStateManager(\"INTLAYER_EDITOR_ENABLED\", this.messenger, {\n\t\t\temit: false,\n\t\t\treceive: true,\n\t\t\tinitialValue: false\n\t\t});\n\t\tthis.focusedContent = new CrossFrameStateManager(\"INTLAYER_FOCUSED_CONTENT_CHANGED\", this.messenger, {\n\t\t\temit: true,\n\t\t\treceive: true,\n\t\t\tinitialValue: null\n\t\t});\n\t\tthis.localeDictionaries = new CrossFrameStateManager(\"INTLAYER_LOCALE_DICTIONARIES_CHANGED\", this.messenger);\n\t\tthis.editedContent = new CrossFrameStateManager(\"INTLAYER_EDITED_CONTENT_CHANGED\", this.messenger);\n\t\tthis.configuration = new CrossFrameStateManager(\"INTLAYER_CONFIGURATION\", this.messenger, {\n\t\t\temit: true,\n\t\t\treceive: false,\n\t\t\t...config.configuration ? { initialValue: config.configuration } : {}\n\t\t});\n\t\tthis.currentLocale = new CrossFrameStateManager(\"INTLAYER_CURRENT_LOCALE\", this.messenger, {\n\t\t\temit: config.mode === \"client\",\n\t\t\treceive: config.mode === \"editor\"\n\t\t});\n\t\tthis.displayedDictionaryKeys = new CrossFrameStateManager(\"INTLAYER_DISPLAYED_DICTIONARY_KEYS\", this.messenger, {\n\t\t\temit: config.mode === \"client\",\n\t\t\treceive: config.mode === \"editor\",\n\t\t\tinitialValue: []\n\t\t});\n\t\tthis._urlManager = new UrlStateManager(this.messenger);\n\t\tthis._iframeInterceptor = new IframeClickInterceptor(this.messenger);\n\t}\n\tstart() {\n\t\tthis.messenger.start();\n\t\tthis.editorEnabled.start();\n\t\tthis.focusedContent.start();\n\t\tthis.localeDictionaries.start();\n\t\tthis.editedContent.start();\n\t\tthis.configuration.start();\n\t\tthis.currentLocale.start();\n\t\tthis.displayedDictionaryKeys.start();\n\t\tthis._startEditedContentBusSync();\n\t\tthis._startFocusedContentBusSync();\n\t\tif (this._mode === \"client\") {\n\t\t\tthis._urlManager.start();\n\t\t\tthis._iframeInterceptor.startInterceptor();\n\t\t\tthis._loadDictionaries();\n\t\t\tthis._startDisplayedDictionariesTracking();\n\t\t\tthis.messenger.send(`${\"INTLAYER_EDITED_CONTENT_CHANGED\"}/get`);\n\t\t\tif (this._configuration?.editor?.enabled !== false) this._setupActivationHandshake();\n\t\t} else {\n\t\t\tthis._iframeInterceptor.startMerger();\n\t\t\tthis._setupEditorHandshake();\n\t\t}\n\t}\n\tstop() {\n\t\tthis._unsubAreYouThere?.();\n\t\tthis._unsubActivate?.();\n\t\tthis._unsubClientReady?.();\n\t\tthis._unsubAreYouThere = null;\n\t\tthis._unsubActivate = null;\n\t\tthis._unsubClientReady = null;\n\t\tthis.messenger.stop();\n\t\tthis.editorEnabled.stop();\n\t\tthis.focusedContent.stop();\n\t\tthis.localeDictionaries.stop();\n\t\tthis.editedContent.stop();\n\t\tthis.configuration.stop();\n\t\tthis.currentLocale.stop();\n\t\tthis.displayedDictionaryKeys.stop();\n\t\tthis._stopDisplayedDictionariesTracking();\n\t\tthis._stopEditedContentBusSync();\n\t\tthis._stopFocusedContentBusSync();\n\t\tthis._urlManager.stop();\n\t\tthis._iframeInterceptor.stopInterceptor();\n\t\tthis._iframeInterceptor.stopMerger();\n\t}\n\t/**\n\t* EDITOR mode: re-send ARE_YOU_THERE to attempt re-connection with the client.\n\t* Call this when the user clicks \"Enable Editor\" or when the iframe reloads.\n\t*/\n\tpingClient() {\n\t\tif (this._mode !== \"editor\") return;\n\t\tthis.messenger.send(\"INTLAYER_ARE_YOU_THERE\");\n\t}\n\tsetFocusedContentKeyPath(keyPath) {\n\t\tconst filtered = keyPath.filter((key) => key.type !== NodeTypes.TRANSLATION);\n\t\tconst prev = this.focusedContent.value;\n\t\tif (!prev) return;\n\t\tthis.focusedContent.set({\n\t\t\t...prev,\n\t\t\tkeyPath: filtered\n\t\t});\n\t}\n\tsetLocaleDictionary(dictionary) {\n\t\tif (!dictionary.localId) return;\n\t\tconst current = this.localeDictionaries.value ?? {};\n\t\tthis.localeDictionaries.set({\n\t\t\t...current,\n\t\t\t[dictionary.localId]: dictionary\n\t\t});\n\t}\n\tsetEditedDictionary(newDict) {\n\t\tif (!newDict.localId) {\n\t\t\tconsole.error(\"setEditedDictionary: missing localId\", newDict);\n\t\t\treturn;\n\t\t}\n\t\tconst current = this.editedContent.value ?? {};\n\t\tthis.editedContent.set({\n\t\t\t...current,\n\t\t\t[newDict.localId]: newDict\n\t\t});\n\t}\n\tsetEditedContent(localDictionaryId, newValue) {\n\t\tconst current = this.editedContent.value ?? {};\n\t\tthis.editedContent.set({\n\t\t\t...current,\n\t\t\t[localDictionaryId]: {\n\t\t\t\t...current[localDictionaryId],\n\t\t\t\tcontent: newValue\n\t\t\t}\n\t\t});\n\t}\n\taddContent(localDictionaryId, newValue, keyPath = [], overwrite = true) {\n\t\tconst current = this.editedContent.value ?? {};\n\t\tconst originalContent = (this.localeDictionaries.value ?? {})[localDictionaryId]?.content;\n\t\tconst currentContent = structuredClone(current[localDictionaryId]?.content ?? originalContent);\n\t\tlet newKeyPath = keyPath;\n\t\tif (!overwrite) {\n\t\t\tlet index = 0;\n\t\t\tconst otherKeyPath = keyPath.slice(0, -1);\n\t\t\tconst lastKeyPath = keyPath[keyPath.length - 1];\n\t\t\tlet finalKey = lastKeyPath.key;\n\t\t\twhile (typeof getContentNodeByKeyPath(currentContent, newKeyPath) !== \"undefined\") {\n\t\t\t\tindex++;\n\t\t\t\tfinalKey = index === 0 ? lastKeyPath.key : `${lastKeyPath.key} (${index})`;\n\t\t\t\tnewKeyPath = [...otherKeyPath, {\n\t\t\t\t\t...lastKeyPath,\n\t\t\t\t\tkey: finalKey\n\t\t\t\t}];\n\t\t\t}\n\t\t}\n\t\tconst updatedContent = editDictionaryByKeyPath(currentContent, newKeyPath, newValue);\n\t\tthis.editedContent.set({\n\t\t\t...current,\n\t\t\t[localDictionaryId]: {\n\t\t\t\t...current[localDictionaryId],\n\t\t\t\tcontent: updatedContent\n\t\t\t}\n\t\t});\n\t}\n\trenameContent(localDictionaryId, newKey, keyPath = []) {\n\t\tconst current = this.editedContent.value ?? {};\n\t\tconst originalContent = (this.localeDictionaries.value ?? {})[localDictionaryId]?.content;\n\t\tconst updated = renameContentNodeByKeyPath(structuredClone(current[localDictionaryId]?.content ?? originalContent), newKey, keyPath);\n\t\tthis.editedContent.set({\n\t\t\t...current,\n\t\t\t[localDictionaryId]: {\n\t\t\t\t...current[localDictionaryId],\n\t\t\t\tcontent: updated\n\t\t\t}\n\t\t});\n\t}\n\tremoveContent(localDictionaryId, keyPath) {\n\t\tconst current = this.editedContent.value ?? {};\n\t\tconst originalContent = (this.localeDictionaries.value ?? {})[localDictionaryId]?.content;\n\t\tconst restored = editDictionaryByKeyPath(structuredClone(current[localDictionaryId]?.content ?? originalContent), keyPath, getContentNodeByKeyPath(originalContent, keyPath));\n\t\tthis.editedContent.set({\n\t\t\t...current,\n\t\t\t[localDictionaryId]: {\n\t\t\t\t...current[localDictionaryId],\n\t\t\t\tcontent: restored\n\t\t\t}\n\t\t});\n\t}\n\trestoreContent(localDictionaryId) {\n\t\tconst updated = { ...this.editedContent.value ?? {} };\n\t\tdelete updated[localDictionaryId];\n\t\tthis.editedContent.set(updated);\n\t}\n\tclearContent(localDictionaryId) {\n\t\tconst filtered = { ...this.editedContent.value ?? {} };\n\t\tdelete filtered[localDictionaryId];\n\t\tthis.editedContent.set(filtered);\n\t}\n\tclearAllContent() {\n\t\tthis.editedContent.set({});\n\t}\n\tgetContentValue(localDictionaryIdOrKey, keyPath) {\n\t\tconst edited = this.editedContent.value;\n\t\tif (!edited) return void 0;\n\t\tconst filteredKeyPath = keyPath.filter((key) => key.type !== NodeTypes.TRANSLATION);\n\t\tconst localeDicts = this.localeDictionaries.value;\n\t\tif (localDictionaryIdOrKey.includes(\":local:\") || localDictionaryIdOrKey.includes(\":remote:\")) {\n\t\t\tif (localeDicts && !(localDictionaryIdOrKey in localeDicts)) return;\n\t\t\treturn getContentNodeByKeyPath(edited[localDictionaryIdOrKey]?.content ?? {}, filteredKeyPath, this.currentLocale.value);\n\t\t}\n\t\tconst matchingIds = Object.keys(edited).filter((key) => key.startsWith(`${localDictionaryIdOrKey}:`) && (!localeDicts || key in localeDicts));\n\t\tfor (const localId of matchingIds) {\n\t\t\tconst node = getContentNodeByKeyPath(edited[localId]?.content ?? {}, filteredKeyPath, this.currentLocale.value);\n\t\t\tif (node) return node;\n\t\t}\n\t}\n\t_startEditedContentBusSync() {\n\t\tthis._editedContentBusHandler = (e) => {\n\t\t\tif (this._editedContentFromBus) return;\n\t\t\tconst content = e.detail;\n\t\t\tsetGlobalEditedContent(content, this.messenger.senderId);\n\t\t};\n\t\tthis.editedContent.addEventListener(\"change\", this._editedContentBusHandler);\n\t\tthis._unsubGlobalEditedContent = subscribeToGlobalEditedContent((content, sourceId) => {\n\t\t\tif (sourceId === this.messenger.senderId) return;\n\t\t\tthis._editedContentFromBus = true;\n\t\t\tthis.editedContent.set(content);\n\t\t\tthis._editedContentFromBus = false;\n\t\t});\n\t\tconst existing = getGlobalEditedContent();\n\t\tif (Object.keys(existing).length > 0) {\n\t\t\tthis._editedContentFromBus = true;\n\t\t\tthis.editedContent.set(existing);\n\t\t\tthis._editedContentFromBus = false;\n\t\t}\n\t}\n\t_stopEditedContentBusSync() {\n\t\tif (this._editedContentBusHandler) {\n\t\t\tthis.editedContent.removeEventListener(\"change\", this._editedContentBusHandler);\n\t\t\tthis._editedContentBusHandler = null;\n\t\t}\n\t\tthis._unsubGlobalEditedContent?.();\n\t\tthis._unsubGlobalEditedContent = null;\n\t}\n\t_startFocusedContentBusSync() {\n\t\tthis._focusedContentBusHandler = (e) => {\n\t\t\tif (this._focusedContentFromBus) return;\n\t\t\tconst content = e.detail;\n\t\t\tsetGlobalFocusedContent(content, this.messenger.senderId);\n\t\t};\n\t\tthis.focusedContent.addEventListener(\"change\", this._focusedContentBusHandler);\n\t\tthis._unsubGlobalFocusedContent = subscribeToGlobalFocusedContent((content, sourceId) => {\n\t\t\tif (sourceId === this.messenger.senderId) return;\n\t\t\tthis._focusedContentFromBus = true;\n\t\t\tthis.focusedContent.set(content);\n\t\t\tthis._focusedContentFromBus = false;\n\t\t});\n\t\tconst existing = getGlobalFocusedContent();\n\t\tif (existing !== void 0) {\n\t\t\tthis._focusedContentFromBus = true;\n\t\t\tthis.focusedContent.set(existing);\n\t\t\tthis._focusedContentFromBus = false;\n\t\t}\n\t}\n\t_stopFocusedContentBusSync() {\n\t\tif (this._focusedContentBusHandler) {\n\t\t\tthis.focusedContent.removeEventListener(\"change\", this._focusedContentBusHandler);\n\t\t\tthis._focusedContentBusHandler = null;\n\t\t}\n\t\tthis._unsubGlobalFocusedContent?.();\n\t\tthis._unsubGlobalFocusedContent = null;\n\t}\n\t_scanDisplayedDictionaryKeys() {\n\t\tif (typeof document === \"undefined\") return;\n\t\tconst elements = document.querySelectorAll(\"intlayer-content-selector-wrapper[dictionary-key]\");\n\t\tconst keys = Array.from(new Set(Array.from(elements).map((el) => el.getAttribute(\"dictionary-key\") ?? \"\").filter(Boolean)));\n\t\tthis.displayedDictionaryKeys.set(keys);\n\t}\n\t_startDisplayedDictionariesTracking() {\n\t\tif (typeof document === \"undefined\" || typeof MutationObserver === \"undefined\") return;\n\t\tconst schedule = () => {\n\t\t\tif (this._displayedKeysTimer) clearTimeout(this._displayedKeysTimer);\n\t\t\tthis._displayedKeysTimer = setTimeout(() => this._scanDisplayedDictionaryKeys(), 100);\n\t\t};\n\t\tthis._displayedKeysObserver = new MutationObserver(schedule);\n\t\tthis._displayedKeysObserver.observe(document.body, {\n\t\t\tchildList: true,\n\t\t\tsubtree: true\n\t\t});\n\t\tfor (const evt of [\"locationchange\", \"popstate\"]) {\n\t\t\tconst listener = schedule;\n\t\t\twindow.addEventListener(evt, listener);\n\t\t\tthis._displayedKeysListeners.push([evt, listener]);\n\t\t}\n\t\tthis._scanDisplayedDictionaryKeys();\n\t}\n\t_stopDisplayedDictionariesTracking() {\n\t\tthis._displayedKeysObserver?.disconnect();\n\t\tthis._displayedKeysObserver = null;\n\t\tif (this._displayedKeysTimer) {\n\t\t\tclearTimeout(this._displayedKeysTimer);\n\t\t\tthis._displayedKeysTimer = null;\n\t\t}\n\t\tfor (const [evt, listener] of this._displayedKeysListeners) window.removeEventListener(evt, listener);\n\t\tthis._displayedKeysListeners = [];\n\t}\n\t/**\n\t* EDITOR mode: listen for CLIENT_READY and respond with EDITOR_ACTIVATE.\n\t* Also pings the client immediately in case it loaded before the editor.\n\t*/\n\t_setupEditorHandshake() {\n\t\tthis._unsubClientReady = this.messenger.subscribe(\"INTLAYER_CLIENT_READY\", () => {\n\t\t\tthis.editorEnabled.set(true);\n\t\t\tthis.messenger.send(\"INTLAYER_EDITOR_ACTIVATE\");\n\t\t});\n\t\tthis.messenger.send(\"INTLAYER_ARE_YOU_THERE\");\n\t}\n\t_setupActivationHandshake() {\n\t\tthis.messenger.send(\"INTLAYER_CLIENT_READY\");\n\t\tthis._unsubAreYouThere = this.messenger.subscribe(\"INTLAYER_ARE_YOU_THERE\", () => {\n\t\t\tthis.messenger.send(\"INTLAYER_CLIENT_READY\");\n\t\t});\n\t\tthis._unsubActivate = this.messenger.subscribe(\"INTLAYER_EDITOR_ACTIVATE\", () => {\n\t\t\tthis.editorEnabled.set(true);\n\t\t\tthis._broadcastData();\n\t\t});\n\t}\n\t_broadcastData() {\n\t\tconst configVal = this.configuration.value;\n\t\tif (configVal) this.messenger.send(`${\"INTLAYER_CONFIGURATION\"}/post`, configVal);\n\t\tconst localeVal = this.currentLocale.value;\n\t\tif (localeVal) this.messenger.send(`${\"INTLAYER_CURRENT_LOCALE\"}/post`, localeVal);\n\t\tconst dicts = this.localeDictionaries.value;\n\t\tif (dicts) this.messenger.send(`${\"INTLAYER_LOCALE_DICTIONARIES_CHANGED\"}/post`, dicts);\n\t}\n\tasync _loadDictionaries() {\n\t\ttry {\n\t\t\tconst unmergedDictionaries = (await import(\"@intlayer/unmerged-dictionaries-entry\")).getUnmergedDictionaries();\n\t\t\tconst dictionariesList = Object.fromEntries(Object.values(unmergedDictionaries).flat().map((dictionary) => [dictionary.localId, dictionary]));\n\t\t\tthis.localeDictionaries.set(dictionariesList);\n\t\t\tif (this.editorEnabled.value) this._broadcastData();\n\t\t} catch (e) {\n\t\t\tconsole.warn(\"[intlayer] Failed to load unmerged dictionaries:\", e);\n\t\t}\n\t}\n};\n\n//#endregion\nexport { EditorStateManager };\n//# sourceMappingURL=EditorStateManager.mjs.map"],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { mergeIframeClick } from "../mergeIframeClick.mjs";
|
|
2
|
+
|
|
3
|
+
//#region ../../packages/@intlayer/editor/dist/esm/core/IframeClickInterceptor.mjs
|
|
4
|
+
/**
|
|
5
|
+
* IframeClickInterceptor handles click events across iframe boundaries.
|
|
6
|
+
*
|
|
7
|
+
* - startInterceptor(): called in the client (iframe) — broadcasts mousedown to parent
|
|
8
|
+
* - startMerger(): called in the editor (parent) — merges received clicks into DOM events
|
|
9
|
+
*
|
|
10
|
+
* Replaces useIframeClickInterceptor / useIframeClickMerger across all frameworks.
|
|
11
|
+
*/
|
|
12
|
+
var IframeClickInterceptor = class {
|
|
13
|
+
_messenger;
|
|
14
|
+
_mousedownHandler = null;
|
|
15
|
+
_unsubscribeMerge = null;
|
|
16
|
+
constructor(messenger) {
|
|
17
|
+
this._messenger = messenger;
|
|
18
|
+
}
|
|
19
|
+
/** Called on the client side (inside iframe). Broadcasts click events to parent. */
|
|
20
|
+
startInterceptor() {
|
|
21
|
+
if (typeof window === "undefined") return;
|
|
22
|
+
this._mousedownHandler = () => {
|
|
23
|
+
this._messenger.send("INTLAYER_IFRAME_CLICKED");
|
|
24
|
+
};
|
|
25
|
+
window.addEventListener("mousedown", this._mousedownHandler);
|
|
26
|
+
}
|
|
27
|
+
/** Called on the editor side (parent frame). Merges incoming iframe clicks into DOM. */
|
|
28
|
+
startMerger() {
|
|
29
|
+
this._unsubscribeMerge = this._messenger.subscribe("INTLAYER_IFRAME_CLICKED", mergeIframeClick);
|
|
30
|
+
}
|
|
31
|
+
stopInterceptor() {
|
|
32
|
+
if (this._mousedownHandler) {
|
|
33
|
+
window.removeEventListener("mousedown", this._mousedownHandler);
|
|
34
|
+
this._mousedownHandler = null;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
stopMerger() {
|
|
38
|
+
this._unsubscribeMerge?.();
|
|
39
|
+
this._unsubscribeMerge = null;
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
//#endregion
|
|
44
|
+
export { IframeClickInterceptor };
|
|
45
|
+
//# sourceMappingURL=IframeClickInterceptor.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IframeClickInterceptor.mjs","names":[],"sources":["../../../../../../../../../../packages/@intlayer/editor/dist/esm/core/IframeClickInterceptor.mjs"],"sourcesContent":["import { MessageKey } from \"../messageKey.mjs\";\nimport { mergeIframeClick } from \"../mergeIframeClick.mjs\";\n\n//#region src/core/IframeClickInterceptor.ts\n/**\n* IframeClickInterceptor handles click events across iframe boundaries.\n*\n* - startInterceptor(): called in the client (iframe) — broadcasts mousedown to parent\n* - startMerger(): called in the editor (parent) — merges received clicks into DOM events\n*\n* Replaces useIframeClickInterceptor / useIframeClickMerger across all frameworks.\n*/\nvar IframeClickInterceptor = class {\n\t_messenger;\n\t_mousedownHandler = null;\n\t_unsubscribeMerge = null;\n\tconstructor(messenger) {\n\t\tthis._messenger = messenger;\n\t}\n\t/** Called on the client side (inside iframe). Broadcasts click events to parent. */\n\tstartInterceptor() {\n\t\tif (typeof window === \"undefined\") return;\n\t\tthis._mousedownHandler = () => {\n\t\t\tthis._messenger.send(\"INTLAYER_IFRAME_CLICKED\");\n\t\t};\n\t\twindow.addEventListener(\"mousedown\", this._mousedownHandler);\n\t}\n\t/** Called on the editor side (parent frame). Merges incoming iframe clicks into DOM. */\n\tstartMerger() {\n\t\tthis._unsubscribeMerge = this._messenger.subscribe(\"INTLAYER_IFRAME_CLICKED\", mergeIframeClick);\n\t}\n\tstopInterceptor() {\n\t\tif (this._mousedownHandler) {\n\t\t\twindow.removeEventListener(\"mousedown\", this._mousedownHandler);\n\t\t\tthis._mousedownHandler = null;\n\t\t}\n\t}\n\tstopMerger() {\n\t\tthis._unsubscribeMerge?.();\n\t\tthis._unsubscribeMerge = null;\n\t}\n};\n\n//#endregion\nexport { IframeClickInterceptor };\n//# sourceMappingURL=IframeClickInterceptor.mjs.map"],"mappings":";;;;;;;;;;;AAYA,IAAI,yBAAyB,MAAM;CAClC;CACA,oBAAoB;CACpB,oBAAoB;CACpB,YAAY,WAAW;AACtB,OAAK,aAAa;;;CAGnB,mBAAmB;AAClB,MAAI,OAAO,WAAW,YAAa;AACnC,OAAK,0BAA0B;AAC9B,QAAK,WAAW,KAAK,0BAA0B;;AAEhD,SAAO,iBAAiB,aAAa,KAAK,kBAAkB;;;CAG7D,cAAc;AACb,OAAK,oBAAoB,KAAK,WAAW,UAAU,2BAA2B,iBAAiB;;CAEhG,kBAAkB;AACjB,MAAI,KAAK,mBAAmB;AAC3B,UAAO,oBAAoB,aAAa,KAAK,kBAAkB;AAC/D,QAAK,oBAAoB;;;CAG3B,aAAa;AACZ,OAAK,qBAAqB;AAC1B,OAAK,oBAAoB"}
|