@bootdesk/chat-widget-bridge 0.3.4 → 0.3.6
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/embed-chat.cjs +10 -3
- package/dist/embed-chat.cjs.map +1 -1
- package/dist/embed-chat.js +10 -3
- package/dist/embed-chat.js.map +1 -1
- package/dist/index.cjs +128 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +14 -3
- package/dist/index.d.ts +14 -3
- package/dist/index.js +126 -2
- package/dist/index.js.map +1 -1
- package/dist/shim.cjs +101 -0
- package/dist/shim.cjs.map +1 -0
- package/dist/shim.js +75 -0
- package/dist/shim.js.map +1 -0
- package/package.json +5 -1
package/dist/embed-chat.cjs
CHANGED
|
@@ -121,7 +121,12 @@
|
|
|
121
121
|
} catch {
|
|
122
122
|
}
|
|
123
123
|
state.iframe.contentWindow.postMessage(
|
|
124
|
-
{
|
|
124
|
+
{
|
|
125
|
+
type: "chat-config",
|
|
126
|
+
title: opts.title,
|
|
127
|
+
placeholder: opts.placeholder,
|
|
128
|
+
theme: { mode: savedTheme }
|
|
129
|
+
},
|
|
125
130
|
"*"
|
|
126
131
|
);
|
|
127
132
|
});
|
|
@@ -169,8 +174,10 @@
|
|
|
169
174
|
if (!state.initialized) return;
|
|
170
175
|
if (state.button && state.button.parentNode) state.button.parentNode.removeChild(state.button);
|
|
171
176
|
if (state.iframe && state.iframe.parentNode) state.iframe.parentNode.removeChild(state.iframe);
|
|
172
|
-
if (state.overlay && state.overlay.parentNode)
|
|
173
|
-
|
|
177
|
+
if (state.overlay && state.overlay.parentNode)
|
|
178
|
+
state.overlay.parentNode.removeChild(state.overlay);
|
|
179
|
+
if (state.styleEl && state.styleEl.parentNode)
|
|
180
|
+
state.styleEl.parentNode.removeChild(state.styleEl);
|
|
174
181
|
window.removeEventListener("message", handleMessage);
|
|
175
182
|
state.initialized = false;
|
|
176
183
|
}
|
package/dist/embed-chat.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/embed-chat.js"],"sourcesContent":["(function () {\n \"use strict\";\n\n var DEFAULTS = {\n iframeSrc: \"/chat-iframe\",\n title: \"Chat\",\n placeholder: \"Type a message...\",\n buttonInnerHtml:\n '<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\"/></svg>',\n buttonStyle: {\n position: \"fixed\",\n bottom: \"24px\",\n right: \"24px\",\n width: \"56px\",\n height: \"56px\",\n borderRadius: \"50%\",\n border: \"none\",\n background: \"var(--chat-primary, #6366f1)\",\n color: \"#fff\",\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n boxShadow: \"0 4px 16px rgba(0,0,0,0.2)\",\n zIndex: \"2147483646\",\n transition: \"transform 0.2s, opacity 0.2s\",\n },\n overlayStyle: {\n position: \"fixed\",\n inset: \"0\",\n background: \"rgba(0,0,0,0.3)\",\n zIndex: \"2147483646\",\n opacity: \"0\",\n transition: \"opacity 0.2s\",\n pointerEvents: \"none\",\n },\n };\n\n var state = {\n opts: null,\n button: null,\n iframe: null,\n overlay: null,\n styleEl: null,\n isOpen: false,\n originalViewport: undefined,\n initialized: false,\n };\n\n function mergeStyles(base, overrides) {\n var result = {};\n for (var key in base) result[key] = base[key];\n if (overrides) {\n for (var k in overrides) result[k] = overrides[k];\n }\n return result;\n }\n\n function createButton() {\n var opts = state.opts;\n state.button = document.createElement(\"button\");\n state.button.setAttribute(\"data-embed-chat-btn\", \"\");\n state.button.setAttribute(\"aria-label\", \"Open chat\");\n state.button.setAttribute(\"aria-expanded\", \"false\");\n state.button.innerHTML = opts.buttonInnerHtml;\n Object.assign(state.button.style, mergeStyles(DEFAULTS.buttonStyle, opts.buttonStyle));\n state.button.addEventListener(\"mouseenter\", function () {\n state.button.style.transform = \"scale(1.05)\";\n });\n state.button.addEventListener(\"mouseleave\", function () {\n state.button.style.transform = \"\";\n });\n state.button.addEventListener(\"click\", toggle);\n state.button.addEventListener(\"keydown\", function (e) {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n toggle();\n }\n });\n document.body.appendChild(state.button);\n }\n\n function createOverlay() {\n var opts = state.opts;\n state.overlay = document.createElement(\"div\");\n state.overlay.setAttribute(\"data-embed-chat-overlay\", \"\");\n Object.assign(state.overlay.style, mergeStyles(DEFAULTS.overlayStyle, opts.overlayStyle));\n state.overlay.addEventListener(\"click\", toggle);\n document.body.appendChild(state.overlay);\n }\n\n function createIframe() {\n var opts = state.opts;\n state.iframe = document.createElement(\"iframe\");\n state.iframe.setAttribute(\"data-embed-chat-iframe\", \"\");\n state.iframe.setAttribute(\"title\", \"Chat Widget\");\n state.iframe.setAttribute(\"role\", \"dialog\");\n state.iframe.setAttribute(\"aria-modal\", \"true\");\n state.iframe.setAttribute(\"allow\", \"clipboard-write; microphone\");\n state.iframe.src = opts.iframeSrc;\n Object.assign(state.iframe.style, {\n position: \"fixed\",\n bottom: \"96px\",\n right: \"24px\",\n width: \"420px\",\n height: \"600px\",\n maxWidth: \"calc(100dvw - 48px)\",\n maxHeight: \"calc(100dvh - 120px)\",\n border: \"none\",\n borderRadius: \"16px\",\n boxShadow: \"0 8px 32px rgba(0,0,0,0.15)\",\n zIndex: \"2147483647\",\n opacity: \"0\",\n transform: \"translateY(16px) scale(0.96)\",\n transition: \"opacity 0.2s, transform 0.25s\",\n pointerEvents: \"none\",\n background: \"#fff\",\n });\n document.body.appendChild(state.iframe);\n\n state.iframe.addEventListener(\"load\", function () {\n var savedTheme = \"auto\";\n try {\n var stored = localStorage.getItem(\"chat-theme\");\n if (stored === \"light\" || stored === \"dark\" || stored === \"auto\") savedTheme = stored;\n } catch { /* unavailable */ }\n state.iframe.contentWindow.postMessage(\n { type: \"chat-config\", title: opts.title, placeholder: opts.placeholder, theme: { mode: savedTheme } },\n \"*\",\n );\n });\n }\n\n function toggle() {\n state.isOpen = !state.isOpen;\n var open = state.isOpen;\n\n state.button.setAttribute(\"aria-expanded\", String(open));\n state.iframe.style.opacity = open ? \"1\" : \"0\";\n state.iframe.style.transform = open ? \"translateY(0) scale(1)\" : \"translateY(16px) scale(0.96)\";\n state.iframe.style.pointerEvents = open ? \"auto\" : \"none\";\n\n state.overlay.style.opacity = open ? \"1\" : \"0\";\n state.overlay.style.pointerEvents = open ? \"auto\" : \"none\";\n\n state.button.style.transform = open ? \"scale(0)\" : \"\";\n state.button.style.opacity = open ? \"0\" : \"1\";\n state.button.style.pointerEvents = open ? \"none\" : \"auto\";\n\n document.body.style.overflow = open ? \"hidden\" : \"\";\n\n if (open) state.iframe.focus();\n }\n\n function handleMessage(event) {\n if (!state.iframe || event.source !== state.iframe.contentWindow) return;\n var data = event.data || {};\n if (data.type === \"chat-message\") {\n console.log(\"[Embed Chat] Message:\", data.text);\n }\n if (data.type === \"chat-close\") {\n toggle();\n }\n if (data.type === \"chat-viewport-config\") {\n var meta = document.querySelector('meta[name=\"viewport\"]');\n if (!meta) return;\n var current = meta.getAttribute(\"content\") || \"\";\n if (data.content) {\n if (state.originalViewport === undefined) state.originalViewport = current;\n if (!current.includes(data.content)) {\n meta.setAttribute(\"content\", current + (current ? \", \" : \"\") + data.content);\n }\n } else {\n meta.setAttribute(\"content\", state.originalViewport ?? current);\n state.originalViewport = undefined;\n }\n }\n }\n\n function destroy() {\n if (!state.initialized) return;\n if (state.button && state.button.parentNode) state.button.parentNode.removeChild(state.button);\n if (state.iframe && state.iframe.parentNode) state.iframe.parentNode.removeChild(state.iframe);\n if (state.overlay && state.overlay.parentNode) state.overlay.parentNode.removeChild(state.overlay);\n if (state.styleEl && state.styleEl.parentNode) state.styleEl.parentNode.removeChild(state.styleEl);\n window.removeEventListener(\"message\", handleMessage);\n state.initialized = false;\n }\n\n function _initialize(opts) {\n if (document.querySelector(\"[data-embed-chat-btn]\")) return;\n\n state.opts = {};\n for (var key in DEFAULTS) {\n state.opts[key] = DEFAULTS[key];\n }\n if (opts) {\n for (var k in opts) {\n if (k === \"buttonStyle\" || k === \"overlayStyle\") {\n state.opts[k] = mergeStyles(state.opts[k] || {}, opts[k]);\n } else if (opts[k] !== undefined) {\n state.opts[k] = opts[k];\n }\n }\n }\n\n var style = document.createElement(\"style\");\n style.textContent =\n '@media (max-width: 799px) { [data-embed-chat-iframe] { width: 100dvw !important; height: 100dvh !important; bottom: 0 !important; right: 0 !important; max-width: none !important; max-height: none !important; border-radius: 0 !important; } [data-embed-chat-overlay] { display: none !important; } }';\n document.head.appendChild(style);\n state.styleEl = style;\n\n createOverlay();\n createIframe();\n createButton();\n window.addEventListener(\"message\", handleMessage);\n state.initialized = true;\n }\n\n function initialize(opts) {\n if (document.readyState === \"loading\") {\n document.addEventListener(\"DOMContentLoaded\", function () { _initialize(opts); });\n } else {\n _initialize(opts);\n }\n }\n\n window.ChatSDK = { initialize: initialize, destroy: destroy };\n})();\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/embed-chat.js"],"sourcesContent":["(function () {\n \"use strict\";\n\n var DEFAULTS = {\n iframeSrc: \"/chat-iframe\",\n title: \"Chat\",\n placeholder: \"Type a message...\",\n buttonInnerHtml:\n '<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\"/></svg>',\n buttonStyle: {\n position: \"fixed\",\n bottom: \"24px\",\n right: \"24px\",\n width: \"56px\",\n height: \"56px\",\n borderRadius: \"50%\",\n border: \"none\",\n background: \"var(--chat-primary, #6366f1)\",\n color: \"#fff\",\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n boxShadow: \"0 4px 16px rgba(0,0,0,0.2)\",\n zIndex: \"2147483646\",\n transition: \"transform 0.2s, opacity 0.2s\",\n },\n overlayStyle: {\n position: \"fixed\",\n inset: \"0\",\n background: \"rgba(0,0,0,0.3)\",\n zIndex: \"2147483646\",\n opacity: \"0\",\n transition: \"opacity 0.2s\",\n pointerEvents: \"none\",\n },\n };\n\n var state = {\n opts: null,\n button: null,\n iframe: null,\n overlay: null,\n styleEl: null,\n isOpen: false,\n originalViewport: undefined,\n initialized: false,\n };\n\n function mergeStyles(base, overrides) {\n var result = {};\n for (var key in base) result[key] = base[key];\n if (overrides) {\n for (var k in overrides) result[k] = overrides[k];\n }\n return result;\n }\n\n function createButton() {\n var opts = state.opts;\n state.button = document.createElement(\"button\");\n state.button.setAttribute(\"data-embed-chat-btn\", \"\");\n state.button.setAttribute(\"aria-label\", \"Open chat\");\n state.button.setAttribute(\"aria-expanded\", \"false\");\n state.button.innerHTML = opts.buttonInnerHtml;\n Object.assign(state.button.style, mergeStyles(DEFAULTS.buttonStyle, opts.buttonStyle));\n state.button.addEventListener(\"mouseenter\", function () {\n state.button.style.transform = \"scale(1.05)\";\n });\n state.button.addEventListener(\"mouseleave\", function () {\n state.button.style.transform = \"\";\n });\n state.button.addEventListener(\"click\", toggle);\n state.button.addEventListener(\"keydown\", function (e) {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n toggle();\n }\n });\n document.body.appendChild(state.button);\n }\n\n function createOverlay() {\n var opts = state.opts;\n state.overlay = document.createElement(\"div\");\n state.overlay.setAttribute(\"data-embed-chat-overlay\", \"\");\n Object.assign(state.overlay.style, mergeStyles(DEFAULTS.overlayStyle, opts.overlayStyle));\n state.overlay.addEventListener(\"click\", toggle);\n document.body.appendChild(state.overlay);\n }\n\n function createIframe() {\n var opts = state.opts;\n state.iframe = document.createElement(\"iframe\");\n state.iframe.setAttribute(\"data-embed-chat-iframe\", \"\");\n state.iframe.setAttribute(\"title\", \"Chat Widget\");\n state.iframe.setAttribute(\"role\", \"dialog\");\n state.iframe.setAttribute(\"aria-modal\", \"true\");\n state.iframe.setAttribute(\"allow\", \"clipboard-write; microphone\");\n state.iframe.src = opts.iframeSrc;\n Object.assign(state.iframe.style, {\n position: \"fixed\",\n bottom: \"96px\",\n right: \"24px\",\n width: \"420px\",\n height: \"600px\",\n maxWidth: \"calc(100dvw - 48px)\",\n maxHeight: \"calc(100dvh - 120px)\",\n border: \"none\",\n borderRadius: \"16px\",\n boxShadow: \"0 8px 32px rgba(0,0,0,0.15)\",\n zIndex: \"2147483647\",\n opacity: \"0\",\n transform: \"translateY(16px) scale(0.96)\",\n transition: \"opacity 0.2s, transform 0.25s\",\n pointerEvents: \"none\",\n background: \"#fff\",\n });\n document.body.appendChild(state.iframe);\n\n state.iframe.addEventListener(\"load\", function () {\n var savedTheme = \"auto\";\n try {\n var stored = localStorage.getItem(\"chat-theme\");\n if (stored === \"light\" || stored === \"dark\" || stored === \"auto\") savedTheme = stored;\n } catch {\n /* unavailable */\n }\n state.iframe.contentWindow.postMessage(\n {\n type: \"chat-config\",\n title: opts.title,\n placeholder: opts.placeholder,\n theme: { mode: savedTheme },\n },\n \"*\",\n );\n });\n }\n\n function toggle() {\n state.isOpen = !state.isOpen;\n var open = state.isOpen;\n\n state.button.setAttribute(\"aria-expanded\", String(open));\n state.iframe.style.opacity = open ? \"1\" : \"0\";\n state.iframe.style.transform = open ? \"translateY(0) scale(1)\" : \"translateY(16px) scale(0.96)\";\n state.iframe.style.pointerEvents = open ? \"auto\" : \"none\";\n\n state.overlay.style.opacity = open ? \"1\" : \"0\";\n state.overlay.style.pointerEvents = open ? \"auto\" : \"none\";\n\n state.button.style.transform = open ? \"scale(0)\" : \"\";\n state.button.style.opacity = open ? \"0\" : \"1\";\n state.button.style.pointerEvents = open ? \"none\" : \"auto\";\n\n document.body.style.overflow = open ? \"hidden\" : \"\";\n\n if (open) state.iframe.focus();\n }\n\n function handleMessage(event) {\n if (!state.iframe || event.source !== state.iframe.contentWindow) return;\n var data = event.data || {};\n if (data.type === \"chat-message\") {\n console.log(\"[Embed Chat] Message:\", data.text);\n }\n if (data.type === \"chat-close\") {\n toggle();\n }\n if (data.type === \"chat-viewport-config\") {\n var meta = document.querySelector('meta[name=\"viewport\"]');\n if (!meta) return;\n var current = meta.getAttribute(\"content\") || \"\";\n if (data.content) {\n if (state.originalViewport === undefined) state.originalViewport = current;\n if (!current.includes(data.content)) {\n meta.setAttribute(\"content\", current + (current ? \", \" : \"\") + data.content);\n }\n } else {\n meta.setAttribute(\"content\", state.originalViewport ?? current);\n state.originalViewport = undefined;\n }\n }\n }\n\n function destroy() {\n if (!state.initialized) return;\n if (state.button && state.button.parentNode) state.button.parentNode.removeChild(state.button);\n if (state.iframe && state.iframe.parentNode) state.iframe.parentNode.removeChild(state.iframe);\n if (state.overlay && state.overlay.parentNode)\n state.overlay.parentNode.removeChild(state.overlay);\n if (state.styleEl && state.styleEl.parentNode)\n state.styleEl.parentNode.removeChild(state.styleEl);\n window.removeEventListener(\"message\", handleMessage);\n state.initialized = false;\n }\n\n function _initialize(opts) {\n if (document.querySelector(\"[data-embed-chat-btn]\")) return;\n\n state.opts = {};\n for (var key in DEFAULTS) {\n state.opts[key] = DEFAULTS[key];\n }\n if (opts) {\n for (var k in opts) {\n if (k === \"buttonStyle\" || k === \"overlayStyle\") {\n state.opts[k] = mergeStyles(state.opts[k] || {}, opts[k]);\n } else if (opts[k] !== undefined) {\n state.opts[k] = opts[k];\n }\n }\n }\n\n var style = document.createElement(\"style\");\n style.textContent =\n \"@media (max-width: 799px) { [data-embed-chat-iframe] { width: 100dvw !important; height: 100dvh !important; bottom: 0 !important; right: 0 !important; max-width: none !important; max-height: none !important; border-radius: 0 !important; } [data-embed-chat-overlay] { display: none !important; } }\";\n document.head.appendChild(style);\n state.styleEl = style;\n\n createOverlay();\n createIframe();\n createButton();\n window.addEventListener(\"message\", handleMessage);\n state.initialized = true;\n }\n\n function initialize(opts) {\n if (document.readyState === \"loading\") {\n document.addEventListener(\"DOMContentLoaded\", function () {\n _initialize(opts);\n });\n } else {\n _initialize(opts);\n }\n }\n\n window.ChatSDK = { initialize: initialize, destroy: destroy };\n})();\n"],"mappings":"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","names":[]}
|
package/dist/embed-chat.js
CHANGED
|
@@ -119,7 +119,12 @@
|
|
|
119
119
|
} catch {
|
|
120
120
|
}
|
|
121
121
|
state.iframe.contentWindow.postMessage(
|
|
122
|
-
{
|
|
122
|
+
{
|
|
123
|
+
type: "chat-config",
|
|
124
|
+
title: opts.title,
|
|
125
|
+
placeholder: opts.placeholder,
|
|
126
|
+
theme: { mode: savedTheme }
|
|
127
|
+
},
|
|
123
128
|
"*"
|
|
124
129
|
);
|
|
125
130
|
});
|
|
@@ -167,8 +172,10 @@
|
|
|
167
172
|
if (!state.initialized) return;
|
|
168
173
|
if (state.button && state.button.parentNode) state.button.parentNode.removeChild(state.button);
|
|
169
174
|
if (state.iframe && state.iframe.parentNode) state.iframe.parentNode.removeChild(state.iframe);
|
|
170
|
-
if (state.overlay && state.overlay.parentNode)
|
|
171
|
-
|
|
175
|
+
if (state.overlay && state.overlay.parentNode)
|
|
176
|
+
state.overlay.parentNode.removeChild(state.overlay);
|
|
177
|
+
if (state.styleEl && state.styleEl.parentNode)
|
|
178
|
+
state.styleEl.parentNode.removeChild(state.styleEl);
|
|
172
179
|
window.removeEventListener("message", handleMessage);
|
|
173
180
|
state.initialized = false;
|
|
174
181
|
}
|
package/dist/embed-chat.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/embed-chat.js"],"sourcesContent":["(function () {\n \"use strict\";\n\n var DEFAULTS = {\n iframeSrc: \"/chat-iframe\",\n title: \"Chat\",\n placeholder: \"Type a message...\",\n buttonInnerHtml:\n '<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\"/></svg>',\n buttonStyle: {\n position: \"fixed\",\n bottom: \"24px\",\n right: \"24px\",\n width: \"56px\",\n height: \"56px\",\n borderRadius: \"50%\",\n border: \"none\",\n background: \"var(--chat-primary, #6366f1)\",\n color: \"#fff\",\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n boxShadow: \"0 4px 16px rgba(0,0,0,0.2)\",\n zIndex: \"2147483646\",\n transition: \"transform 0.2s, opacity 0.2s\",\n },\n overlayStyle: {\n position: \"fixed\",\n inset: \"0\",\n background: \"rgba(0,0,0,0.3)\",\n zIndex: \"2147483646\",\n opacity: \"0\",\n transition: \"opacity 0.2s\",\n pointerEvents: \"none\",\n },\n };\n\n var state = {\n opts: null,\n button: null,\n iframe: null,\n overlay: null,\n styleEl: null,\n isOpen: false,\n originalViewport: undefined,\n initialized: false,\n };\n\n function mergeStyles(base, overrides) {\n var result = {};\n for (var key in base) result[key] = base[key];\n if (overrides) {\n for (var k in overrides) result[k] = overrides[k];\n }\n return result;\n }\n\n function createButton() {\n var opts = state.opts;\n state.button = document.createElement(\"button\");\n state.button.setAttribute(\"data-embed-chat-btn\", \"\");\n state.button.setAttribute(\"aria-label\", \"Open chat\");\n state.button.setAttribute(\"aria-expanded\", \"false\");\n state.button.innerHTML = opts.buttonInnerHtml;\n Object.assign(state.button.style, mergeStyles(DEFAULTS.buttonStyle, opts.buttonStyle));\n state.button.addEventListener(\"mouseenter\", function () {\n state.button.style.transform = \"scale(1.05)\";\n });\n state.button.addEventListener(\"mouseleave\", function () {\n state.button.style.transform = \"\";\n });\n state.button.addEventListener(\"click\", toggle);\n state.button.addEventListener(\"keydown\", function (e) {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n toggle();\n }\n });\n document.body.appendChild(state.button);\n }\n\n function createOverlay() {\n var opts = state.opts;\n state.overlay = document.createElement(\"div\");\n state.overlay.setAttribute(\"data-embed-chat-overlay\", \"\");\n Object.assign(state.overlay.style, mergeStyles(DEFAULTS.overlayStyle, opts.overlayStyle));\n state.overlay.addEventListener(\"click\", toggle);\n document.body.appendChild(state.overlay);\n }\n\n function createIframe() {\n var opts = state.opts;\n state.iframe = document.createElement(\"iframe\");\n state.iframe.setAttribute(\"data-embed-chat-iframe\", \"\");\n state.iframe.setAttribute(\"title\", \"Chat Widget\");\n state.iframe.setAttribute(\"role\", \"dialog\");\n state.iframe.setAttribute(\"aria-modal\", \"true\");\n state.iframe.setAttribute(\"allow\", \"clipboard-write; microphone\");\n state.iframe.src = opts.iframeSrc;\n Object.assign(state.iframe.style, {\n position: \"fixed\",\n bottom: \"96px\",\n right: \"24px\",\n width: \"420px\",\n height: \"600px\",\n maxWidth: \"calc(100dvw - 48px)\",\n maxHeight: \"calc(100dvh - 120px)\",\n border: \"none\",\n borderRadius: \"16px\",\n boxShadow: \"0 8px 32px rgba(0,0,0,0.15)\",\n zIndex: \"2147483647\",\n opacity: \"0\",\n transform: \"translateY(16px) scale(0.96)\",\n transition: \"opacity 0.2s, transform 0.25s\",\n pointerEvents: \"none\",\n background: \"#fff\",\n });\n document.body.appendChild(state.iframe);\n\n state.iframe.addEventListener(\"load\", function () {\n var savedTheme = \"auto\";\n try {\n var stored = localStorage.getItem(\"chat-theme\");\n if (stored === \"light\" || stored === \"dark\" || stored === \"auto\") savedTheme = stored;\n } catch { /* unavailable */ }\n state.iframe.contentWindow.postMessage(\n { type: \"chat-config\", title: opts.title, placeholder: opts.placeholder, theme: { mode: savedTheme } },\n \"*\",\n );\n });\n }\n\n function toggle() {\n state.isOpen = !state.isOpen;\n var open = state.isOpen;\n\n state.button.setAttribute(\"aria-expanded\", String(open));\n state.iframe.style.opacity = open ? \"1\" : \"0\";\n state.iframe.style.transform = open ? \"translateY(0) scale(1)\" : \"translateY(16px) scale(0.96)\";\n state.iframe.style.pointerEvents = open ? \"auto\" : \"none\";\n\n state.overlay.style.opacity = open ? \"1\" : \"0\";\n state.overlay.style.pointerEvents = open ? \"auto\" : \"none\";\n\n state.button.style.transform = open ? \"scale(0)\" : \"\";\n state.button.style.opacity = open ? \"0\" : \"1\";\n state.button.style.pointerEvents = open ? \"none\" : \"auto\";\n\n document.body.style.overflow = open ? \"hidden\" : \"\";\n\n if (open) state.iframe.focus();\n }\n\n function handleMessage(event) {\n if (!state.iframe || event.source !== state.iframe.contentWindow) return;\n var data = event.data || {};\n if (data.type === \"chat-message\") {\n console.log(\"[Embed Chat] Message:\", data.text);\n }\n if (data.type === \"chat-close\") {\n toggle();\n }\n if (data.type === \"chat-viewport-config\") {\n var meta = document.querySelector('meta[name=\"viewport\"]');\n if (!meta) return;\n var current = meta.getAttribute(\"content\") || \"\";\n if (data.content) {\n if (state.originalViewport === undefined) state.originalViewport = current;\n if (!current.includes(data.content)) {\n meta.setAttribute(\"content\", current + (current ? \", \" : \"\") + data.content);\n }\n } else {\n meta.setAttribute(\"content\", state.originalViewport ?? current);\n state.originalViewport = undefined;\n }\n }\n }\n\n function destroy() {\n if (!state.initialized) return;\n if (state.button && state.button.parentNode) state.button.parentNode.removeChild(state.button);\n if (state.iframe && state.iframe.parentNode) state.iframe.parentNode.removeChild(state.iframe);\n if (state.overlay && state.overlay.parentNode) state.overlay.parentNode.removeChild(state.overlay);\n if (state.styleEl && state.styleEl.parentNode) state.styleEl.parentNode.removeChild(state.styleEl);\n window.removeEventListener(\"message\", handleMessage);\n state.initialized = false;\n }\n\n function _initialize(opts) {\n if (document.querySelector(\"[data-embed-chat-btn]\")) return;\n\n state.opts = {};\n for (var key in DEFAULTS) {\n state.opts[key] = DEFAULTS[key];\n }\n if (opts) {\n for (var k in opts) {\n if (k === \"buttonStyle\" || k === \"overlayStyle\") {\n state.opts[k] = mergeStyles(state.opts[k] || {}, opts[k]);\n } else if (opts[k] !== undefined) {\n state.opts[k] = opts[k];\n }\n }\n }\n\n var style = document.createElement(\"style\");\n style.textContent =\n '@media (max-width: 799px) { [data-embed-chat-iframe] { width: 100dvw !important; height: 100dvh !important; bottom: 0 !important; right: 0 !important; max-width: none !important; max-height: none !important; border-radius: 0 !important; } [data-embed-chat-overlay] { display: none !important; } }';\n document.head.appendChild(style);\n state.styleEl = style;\n\n createOverlay();\n createIframe();\n createButton();\n window.addEventListener(\"message\", handleMessage);\n state.initialized = true;\n }\n\n function initialize(opts) {\n if (document.readyState === \"loading\") {\n document.addEventListener(\"DOMContentLoaded\", function () { _initialize(opts); });\n } else {\n _initialize(opts);\n }\n }\n\n window.ChatSDK = { initialize: initialize, destroy: destroy };\n})();\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/embed-chat.js"],"sourcesContent":["(function () {\n \"use strict\";\n\n var DEFAULTS = {\n iframeSrc: \"/chat-iframe\",\n title: \"Chat\",\n placeholder: \"Type a message...\",\n buttonInnerHtml:\n '<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\"/></svg>',\n buttonStyle: {\n position: \"fixed\",\n bottom: \"24px\",\n right: \"24px\",\n width: \"56px\",\n height: \"56px\",\n borderRadius: \"50%\",\n border: \"none\",\n background: \"var(--chat-primary, #6366f1)\",\n color: \"#fff\",\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n boxShadow: \"0 4px 16px rgba(0,0,0,0.2)\",\n zIndex: \"2147483646\",\n transition: \"transform 0.2s, opacity 0.2s\",\n },\n overlayStyle: {\n position: \"fixed\",\n inset: \"0\",\n background: \"rgba(0,0,0,0.3)\",\n zIndex: \"2147483646\",\n opacity: \"0\",\n transition: \"opacity 0.2s\",\n pointerEvents: \"none\",\n },\n };\n\n var state = {\n opts: null,\n button: null,\n iframe: null,\n overlay: null,\n styleEl: null,\n isOpen: false,\n originalViewport: undefined,\n initialized: false,\n };\n\n function mergeStyles(base, overrides) {\n var result = {};\n for (var key in base) result[key] = base[key];\n if (overrides) {\n for (var k in overrides) result[k] = overrides[k];\n }\n return result;\n }\n\n function createButton() {\n var opts = state.opts;\n state.button = document.createElement(\"button\");\n state.button.setAttribute(\"data-embed-chat-btn\", \"\");\n state.button.setAttribute(\"aria-label\", \"Open chat\");\n state.button.setAttribute(\"aria-expanded\", \"false\");\n state.button.innerHTML = opts.buttonInnerHtml;\n Object.assign(state.button.style, mergeStyles(DEFAULTS.buttonStyle, opts.buttonStyle));\n state.button.addEventListener(\"mouseenter\", function () {\n state.button.style.transform = \"scale(1.05)\";\n });\n state.button.addEventListener(\"mouseleave\", function () {\n state.button.style.transform = \"\";\n });\n state.button.addEventListener(\"click\", toggle);\n state.button.addEventListener(\"keydown\", function (e) {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n toggle();\n }\n });\n document.body.appendChild(state.button);\n }\n\n function createOverlay() {\n var opts = state.opts;\n state.overlay = document.createElement(\"div\");\n state.overlay.setAttribute(\"data-embed-chat-overlay\", \"\");\n Object.assign(state.overlay.style, mergeStyles(DEFAULTS.overlayStyle, opts.overlayStyle));\n state.overlay.addEventListener(\"click\", toggle);\n document.body.appendChild(state.overlay);\n }\n\n function createIframe() {\n var opts = state.opts;\n state.iframe = document.createElement(\"iframe\");\n state.iframe.setAttribute(\"data-embed-chat-iframe\", \"\");\n state.iframe.setAttribute(\"title\", \"Chat Widget\");\n state.iframe.setAttribute(\"role\", \"dialog\");\n state.iframe.setAttribute(\"aria-modal\", \"true\");\n state.iframe.setAttribute(\"allow\", \"clipboard-write; microphone\");\n state.iframe.src = opts.iframeSrc;\n Object.assign(state.iframe.style, {\n position: \"fixed\",\n bottom: \"96px\",\n right: \"24px\",\n width: \"420px\",\n height: \"600px\",\n maxWidth: \"calc(100dvw - 48px)\",\n maxHeight: \"calc(100dvh - 120px)\",\n border: \"none\",\n borderRadius: \"16px\",\n boxShadow: \"0 8px 32px rgba(0,0,0,0.15)\",\n zIndex: \"2147483647\",\n opacity: \"0\",\n transform: \"translateY(16px) scale(0.96)\",\n transition: \"opacity 0.2s, transform 0.25s\",\n pointerEvents: \"none\",\n background: \"#fff\",\n });\n document.body.appendChild(state.iframe);\n\n state.iframe.addEventListener(\"load\", function () {\n var savedTheme = \"auto\";\n try {\n var stored = localStorage.getItem(\"chat-theme\");\n if (stored === \"light\" || stored === \"dark\" || stored === \"auto\") savedTheme = stored;\n } catch {\n /* unavailable */\n }\n state.iframe.contentWindow.postMessage(\n {\n type: \"chat-config\",\n title: opts.title,\n placeholder: opts.placeholder,\n theme: { mode: savedTheme },\n },\n \"*\",\n );\n });\n }\n\n function toggle() {\n state.isOpen = !state.isOpen;\n var open = state.isOpen;\n\n state.button.setAttribute(\"aria-expanded\", String(open));\n state.iframe.style.opacity = open ? \"1\" : \"0\";\n state.iframe.style.transform = open ? \"translateY(0) scale(1)\" : \"translateY(16px) scale(0.96)\";\n state.iframe.style.pointerEvents = open ? \"auto\" : \"none\";\n\n state.overlay.style.opacity = open ? \"1\" : \"0\";\n state.overlay.style.pointerEvents = open ? \"auto\" : \"none\";\n\n state.button.style.transform = open ? \"scale(0)\" : \"\";\n state.button.style.opacity = open ? \"0\" : \"1\";\n state.button.style.pointerEvents = open ? \"none\" : \"auto\";\n\n document.body.style.overflow = open ? \"hidden\" : \"\";\n\n if (open) state.iframe.focus();\n }\n\n function handleMessage(event) {\n if (!state.iframe || event.source !== state.iframe.contentWindow) return;\n var data = event.data || {};\n if (data.type === \"chat-message\") {\n console.log(\"[Embed Chat] Message:\", data.text);\n }\n if (data.type === \"chat-close\") {\n toggle();\n }\n if (data.type === \"chat-viewport-config\") {\n var meta = document.querySelector('meta[name=\"viewport\"]');\n if (!meta) return;\n var current = meta.getAttribute(\"content\") || \"\";\n if (data.content) {\n if (state.originalViewport === undefined) state.originalViewport = current;\n if (!current.includes(data.content)) {\n meta.setAttribute(\"content\", current + (current ? \", \" : \"\") + data.content);\n }\n } else {\n meta.setAttribute(\"content\", state.originalViewport ?? current);\n state.originalViewport = undefined;\n }\n }\n }\n\n function destroy() {\n if (!state.initialized) return;\n if (state.button && state.button.parentNode) state.button.parentNode.removeChild(state.button);\n if (state.iframe && state.iframe.parentNode) state.iframe.parentNode.removeChild(state.iframe);\n if (state.overlay && state.overlay.parentNode)\n state.overlay.parentNode.removeChild(state.overlay);\n if (state.styleEl && state.styleEl.parentNode)\n state.styleEl.parentNode.removeChild(state.styleEl);\n window.removeEventListener(\"message\", handleMessage);\n state.initialized = false;\n }\n\n function _initialize(opts) {\n if (document.querySelector(\"[data-embed-chat-btn]\")) return;\n\n state.opts = {};\n for (var key in DEFAULTS) {\n state.opts[key] = DEFAULTS[key];\n }\n if (opts) {\n for (var k in opts) {\n if (k === \"buttonStyle\" || k === \"overlayStyle\") {\n state.opts[k] = mergeStyles(state.opts[k] || {}, opts[k]);\n } else if (opts[k] !== undefined) {\n state.opts[k] = opts[k];\n }\n }\n }\n\n var style = document.createElement(\"style\");\n style.textContent =\n \"@media (max-width: 799px) { [data-embed-chat-iframe] { width: 100dvw !important; height: 100dvh !important; bottom: 0 !important; right: 0 !important; max-width: none !important; max-height: none !important; border-radius: 0 !important; } [data-embed-chat-overlay] { display: none !important; } }\";\n document.head.appendChild(style);\n state.styleEl = style;\n\n createOverlay();\n createIframe();\n createButton();\n window.addEventListener(\"message\", handleMessage);\n state.initialized = true;\n }\n\n function initialize(opts) {\n if (document.readyState === \"loading\") {\n document.addEventListener(\"DOMContentLoaded\", function () {\n _initialize(opts);\n });\n } else {\n _initialize(opts);\n }\n }\n\n window.ChatSDK = { initialize: initialize, destroy: destroy };\n})();\n"],"mappings":"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","names":[]}
|
package/dist/index.cjs
CHANGED
|
@@ -20,6 +20,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
|
+
WEBVIEW_SHIM: () => WEBVIEW_SHIM,
|
|
24
|
+
buildShimUrl: () => buildShimUrl,
|
|
23
25
|
useIframeBridge: () => useIframeBridge
|
|
24
26
|
});
|
|
25
27
|
module.exports = __toCommonJS(index_exports);
|
|
@@ -28,8 +30,15 @@ module.exports = __toCommonJS(index_exports);
|
|
|
28
30
|
var import_react = require("react");
|
|
29
31
|
function useIframeBridge() {
|
|
30
32
|
const [config, setConfig] = (0, import_react.useState)(null);
|
|
33
|
+
const [pushState, setPushState] = (0, import_react.useState)(null);
|
|
31
34
|
const notificationCbRef = (0, import_react.useRef)(null);
|
|
35
|
+
const readyRef = (0, import_react.useRef)(false);
|
|
32
36
|
const isInIframe = typeof window !== "undefined" && window !== window.parent;
|
|
37
|
+
(0, import_react.useEffect)(() => {
|
|
38
|
+
if (typeof window !== "undefined" && window.__chatBridge?._pushState) {
|
|
39
|
+
setPushState(window.__chatBridge._pushState);
|
|
40
|
+
}
|
|
41
|
+
}, []);
|
|
33
42
|
const notifyMessage = (0, import_react.useCallback)(
|
|
34
43
|
(text) => {
|
|
35
44
|
if (!isInIframe) return;
|
|
@@ -49,6 +58,25 @@ function useIframeBridge() {
|
|
|
49
58
|
const onNotificationClicked = (0, import_react.useCallback)((cb) => {
|
|
50
59
|
notificationCbRef.current = cb;
|
|
51
60
|
}, []);
|
|
61
|
+
const requestPushSubscribe = (0, import_react.useCallback)(() => {
|
|
62
|
+
if (!isInIframe) return;
|
|
63
|
+
const msg = { type: "chat-push-subscribe" };
|
|
64
|
+
window.parent.postMessage(msg, "*");
|
|
65
|
+
}, [isInIframe]);
|
|
66
|
+
const requestPushUnsubscribe = (0, import_react.useCallback)(() => {
|
|
67
|
+
if (!isInIframe) return;
|
|
68
|
+
const msg = { type: "chat-push-unsubscribe" };
|
|
69
|
+
window.parent.postMessage(msg, "*");
|
|
70
|
+
}, [isInIframe]);
|
|
71
|
+
(0, import_react.useEffect)(() => {
|
|
72
|
+
if (!isInIframe) return;
|
|
73
|
+
if (readyRef.current) return;
|
|
74
|
+
readyRef.current = true;
|
|
75
|
+
const msg = { type: "chat-ready" };
|
|
76
|
+
if (typeof window.parent.postMessage === "function") {
|
|
77
|
+
window.parent.postMessage(msg, "*");
|
|
78
|
+
}
|
|
79
|
+
}, [isInIframe]);
|
|
52
80
|
(0, import_react.useEffect)(() => {
|
|
53
81
|
if (!isInIframe) return;
|
|
54
82
|
function handleMessage(event) {
|
|
@@ -64,15 +92,113 @@ function useIframeBridge() {
|
|
|
64
92
|
case "chat-notification-clicked":
|
|
65
93
|
notificationCbRef.current?.();
|
|
66
94
|
break;
|
|
95
|
+
case "chat-push-state":
|
|
96
|
+
if (typeof data.status === "string") {
|
|
97
|
+
setPushState(data.status);
|
|
98
|
+
}
|
|
99
|
+
break;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
function handleCustomEvent(event) {
|
|
103
|
+
const detail = event.detail;
|
|
104
|
+
if (!detail || typeof detail !== "object") return;
|
|
105
|
+
if (detail.type === "chat-push-state" && typeof detail.status === "string") {
|
|
106
|
+
setPushState(detail.status);
|
|
67
107
|
}
|
|
68
108
|
}
|
|
69
109
|
window.addEventListener("message", handleMessage);
|
|
70
|
-
|
|
110
|
+
window.addEventListener("chat-bridge", handleCustomEvent);
|
|
111
|
+
return () => {
|
|
112
|
+
window.removeEventListener("message", handleMessage);
|
|
113
|
+
window.removeEventListener("chat-bridge", handleCustomEvent);
|
|
114
|
+
};
|
|
71
115
|
}, [isInIframe]);
|
|
72
|
-
return {
|
|
116
|
+
return {
|
|
117
|
+
config,
|
|
118
|
+
isInIframe,
|
|
119
|
+
notifyMessage,
|
|
120
|
+
notifyViewportConfig,
|
|
121
|
+
onNotificationClicked,
|
|
122
|
+
pushState,
|
|
123
|
+
requestPushSubscribe,
|
|
124
|
+
requestPushUnsubscribe
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// src/shim.ts
|
|
129
|
+
var WEBVIEW_SHIM = `
|
|
130
|
+
(function () {
|
|
131
|
+
'use strict';
|
|
132
|
+
var _cached = [];
|
|
133
|
+
var _originalPostMessage = window.parent && window.parent.postMessage;
|
|
134
|
+
|
|
135
|
+
function _send(msg) {
|
|
136
|
+
try {
|
|
137
|
+
var json = JSON.stringify(msg);
|
|
138
|
+
} catch (e) {
|
|
139
|
+
var errJson = JSON.stringify({ type: 'chat-error', code: 'SERIALIZE_ERROR', message: 'Failed to serialize message' + e.message });
|
|
140
|
+
try { if (window.parent) window.parent.postMessage(errJson, '*'); } catch (_) {}
|
|
141
|
+
console.error('[ChatBridge] JSON.stringify failed:', e);
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
try {
|
|
145
|
+
if (window.ReactNativeWebView && window.ReactNativeWebView.postMessage) {
|
|
146
|
+
window.ReactNativeWebView.postMessage(json);
|
|
147
|
+
} else if (window.AndroidBridge && window.AndroidBridge.postMessage) {
|
|
148
|
+
window.AndroidBridge.postMessage(json);
|
|
149
|
+
} else if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.chatBridge) {
|
|
150
|
+
window.webkit.messageHandlers.chatBridge.postMessage(msg);
|
|
151
|
+
} else if (_originalPostMessage) {
|
|
152
|
+
_originalPostMessage.call(window.parent, msg, '*');
|
|
153
|
+
} else {
|
|
154
|
+
console.warn('[ChatBridge] No bridge API detected');
|
|
155
|
+
}
|
|
156
|
+
} catch (e) {
|
|
157
|
+
var fallback = JSON.stringify({ type: 'chat-error', code: 'BRIDGE_ERROR', message: 'Bridge postMessage failed: ' + e.message });
|
|
158
|
+
try { if (window.parent) window.parent.postMessage(fallback, '*'); } catch (_) {}
|
|
159
|
+
console.error('[ChatBridge] postMessage failed:', e);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
window.__chatBridge = {
|
|
164
|
+
_pushState: null,
|
|
165
|
+
send: function (msg) { _send(msg); },
|
|
166
|
+
setPushState: function (status) { window.__chatBridge._pushState = status; },
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
var _batches = 0;
|
|
170
|
+
window.addEventListener('chat-bridge', function (e) {
|
|
171
|
+
if (_batches++ > 0) return;
|
|
172
|
+
requestAnimationFrame(function () {
|
|
173
|
+
_batches = 0;
|
|
174
|
+
});
|
|
175
|
+
var payload = e.detail;
|
|
176
|
+
if (!payload || typeof payload !== 'object') return;
|
|
177
|
+
var type = payload.type;
|
|
178
|
+
if (type === 'chat-config') {
|
|
179
|
+
window.__chatBridge._config = payload;
|
|
180
|
+
} else if (type === 'chat-push-state') {
|
|
181
|
+
window.__chatBridge._pushState = payload.status || null;
|
|
182
|
+
}
|
|
183
|
+
_cached.push(payload);
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
window.addEventListener('message', function (e) {
|
|
187
|
+
var data = e.data;
|
|
188
|
+
if (!data || typeof data !== 'object' || !data.type) return;
|
|
189
|
+
if (data.type === 'chat-push-state') {
|
|
190
|
+
window.__chatBridge._pushState = data.status || null;
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
})();
|
|
194
|
+
`;
|
|
195
|
+
function buildShimUrl() {
|
|
196
|
+
return "data:text/javascript;base64," + btoa(WEBVIEW_SHIM);
|
|
73
197
|
}
|
|
74
198
|
// Annotate the CommonJS export names for ESM import in node:
|
|
75
199
|
0 && (module.exports = {
|
|
200
|
+
WEBVIEW_SHIM,
|
|
201
|
+
buildShimUrl,
|
|
76
202
|
useIframeBridge
|
|
77
203
|
});
|
|
78
204
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/useIframeBridge.ts"],"sourcesContent":["export { useIframeBridge } from \"./useIframeBridge\";\nexport type {
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/useIframeBridge.ts","../src/shim.ts"],"sourcesContent":["export { useIframeBridge } from \"./useIframeBridge\";\nexport { WEBVIEW_SHIM, buildShimUrl } from \"./shim\";\nexport type {\n BridgeConfig,\n IframeBridgeHook,\n BridgeMessage,\n BridgePushStatus,\n BridgeMessageType,\n ThemeMode,\n} from \"./types\";\n","import { useCallback, useEffect, useRef, useState } from \"react\";\nimport type { BridgeConfig, BridgeMessage, BridgePushStatus, IframeBridgeHook } from \"./types\";\n\nexport function useIframeBridge(): IframeBridgeHook {\n const [config, setConfig] = useState<BridgeConfig | null>(null);\n const [pushState, setPushState] = useState<BridgePushStatus | null>(null);\n const notificationCbRef = useRef<(() => void) | null>(null);\n const readyRef = useRef(false);\n\n const isInIframe = typeof window !== \"undefined\" && window !== window.parent;\n\n useEffect(() => {\n if (typeof window !== \"undefined\" && (window as any).__chatBridge?._pushState) {\n setPushState((window as any).__chatBridge._pushState);\n }\n }, []);\n\n const notifyMessage = useCallback(\n (text: string) => {\n if (!isInIframe) return;\n const msg: BridgeMessage = { type: \"chat-message\", text };\n window.parent.postMessage(msg, \"*\");\n },\n [isInIframe],\n );\n\n const notifyViewportConfig = useCallback(\n (content: string) => {\n if (!isInIframe) return;\n const msg: BridgeMessage = { type: \"chat-viewport-config\", content };\n window.parent.postMessage(msg, \"*\");\n },\n [isInIframe],\n );\n\n const onNotificationClicked = useCallback((cb: () => void) => {\n notificationCbRef.current = cb;\n }, []);\n\n const requestPushSubscribe = useCallback(() => {\n if (!isInIframe) return;\n const msg: BridgeMessage = { type: \"chat-push-subscribe\" };\n window.parent.postMessage(msg, \"*\");\n }, [isInIframe]);\n\n const requestPushUnsubscribe = useCallback(() => {\n if (!isInIframe) return;\n const msg: BridgeMessage = { type: \"chat-push-unsubscribe\" };\n window.parent.postMessage(msg, \"*\");\n }, [isInIframe]);\n\n useEffect(() => {\n if (!isInIframe) return;\n if (readyRef.current) return;\n readyRef.current = true;\n\n const msg: BridgeMessage = { type: \"chat-ready\" };\n if (typeof window.parent.postMessage === \"function\") {\n window.parent.postMessage(msg, \"*\");\n }\n }, [isInIframe]);\n\n useEffect(() => {\n if (!isInIframe) return;\n\n function handleMessage(event: MessageEvent) {\n const data = event.data as Record<string, unknown>;\n if (!data || typeof data !== \"object\" || !data.type) return;\n\n switch (data.type) {\n case \"chat-config\": {\n const configData = { ...data };\n delete configData.type;\n setConfig(configData as BridgeConfig);\n break;\n }\n case \"chat-notification-clicked\":\n notificationCbRef.current?.();\n break;\n case \"chat-push-state\":\n if (typeof data.status === \"string\") {\n setPushState(data.status as BridgePushStatus);\n }\n break;\n }\n }\n\n function handleCustomEvent(event: Event) {\n const detail = (event as CustomEvent).detail;\n if (!detail || typeof detail !== \"object\") return;\n if (detail.type === \"chat-push-state\" && typeof detail.status === \"string\") {\n setPushState(detail.status as BridgePushStatus);\n }\n }\n\n window.addEventListener(\"message\", handleMessage);\n window.addEventListener(\"chat-bridge\", handleCustomEvent);\n return () => {\n window.removeEventListener(\"message\", handleMessage);\n window.removeEventListener(\"chat-bridge\", handleCustomEvent);\n };\n }, [isInIframe]);\n\n return {\n config,\n isInIframe,\n notifyMessage,\n notifyViewportConfig,\n onNotificationClicked,\n pushState,\n requestPushSubscribe,\n requestPushUnsubscribe,\n };\n}\n","export const WEBVIEW_SHIM: string = `\n(function () {\n 'use strict';\n var _cached = [];\n var _originalPostMessage = window.parent && window.parent.postMessage;\n\n function _send(msg) {\n try {\n var json = JSON.stringify(msg);\n } catch (e) {\n var errJson = JSON.stringify({ type: 'chat-error', code: 'SERIALIZE_ERROR', message: 'Failed to serialize message' + e.message });\n try { if (window.parent) window.parent.postMessage(errJson, '*'); } catch (_) {}\n console.error('[ChatBridge] JSON.stringify failed:', e);\n return;\n }\n try {\n if (window.ReactNativeWebView && window.ReactNativeWebView.postMessage) {\n window.ReactNativeWebView.postMessage(json);\n } else if (window.AndroidBridge && window.AndroidBridge.postMessage) {\n window.AndroidBridge.postMessage(json);\n } else if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.chatBridge) {\n window.webkit.messageHandlers.chatBridge.postMessage(msg);\n } else if (_originalPostMessage) {\n _originalPostMessage.call(window.parent, msg, '*');\n } else {\n console.warn('[ChatBridge] No bridge API detected');\n }\n } catch (e) {\n var fallback = JSON.stringify({ type: 'chat-error', code: 'BRIDGE_ERROR', message: 'Bridge postMessage failed: ' + e.message });\n try { if (window.parent) window.parent.postMessage(fallback, '*'); } catch (_) {}\n console.error('[ChatBridge] postMessage failed:', e);\n }\n }\n\n window.__chatBridge = {\n _pushState: null,\n send: function (msg) { _send(msg); },\n setPushState: function (status) { window.__chatBridge._pushState = status; },\n };\n\n var _batches = 0;\n window.addEventListener('chat-bridge', function (e) {\n if (_batches++ > 0) return;\n requestAnimationFrame(function () {\n _batches = 0;\n });\n var payload = e.detail;\n if (!payload || typeof payload !== 'object') return;\n var type = payload.type;\n if (type === 'chat-config') {\n window.__chatBridge._config = payload;\n } else if (type === 'chat-push-state') {\n window.__chatBridge._pushState = payload.status || null;\n }\n _cached.push(payload);\n });\n\n window.addEventListener('message', function (e) {\n var data = e.data;\n if (!data || typeof data !== 'object' || !data.type) return;\n if (data.type === 'chat-push-state') {\n window.__chatBridge._pushState = data.status || null;\n }\n });\n})();\n`;\n\nexport function buildShimUrl(): string {\n return \"data:text/javascript;base64,\" + btoa(WEBVIEW_SHIM);\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
|
+
type BridgePushStatus = "unsupported" | "default" | "subscribed" | "denied" | "subscribing" | "error";
|
|
2
|
+
type BridgeMessageType = "chat-ready" | "chat-config" | "chat-message" | "chat-notification-clicked" | "chat-close" | "chat-viewport-config" | "chat-viewport-insets" | "chat-push-state" | "chat-push-subscribe" | "chat-push-unsubscribe" | "chat-error";
|
|
3
|
+
type ThemeMode = "auto" | "light" | "dark";
|
|
1
4
|
interface BridgeConfig {
|
|
2
5
|
locale?: string;
|
|
3
6
|
title?: string;
|
|
4
7
|
placeholder?: string;
|
|
5
8
|
theme?: {
|
|
6
|
-
mode?:
|
|
9
|
+
mode?: ThemeMode;
|
|
10
|
+
cssVariables?: Record<string, string>;
|
|
7
11
|
};
|
|
8
12
|
}
|
|
9
13
|
interface IframeBridgeHook {
|
|
@@ -12,12 +16,19 @@ interface IframeBridgeHook {
|
|
|
12
16
|
notifyMessage: (text: string) => void;
|
|
13
17
|
notifyViewportConfig: (content: string) => void;
|
|
14
18
|
onNotificationClicked: (cb: () => void) => void;
|
|
19
|
+
pushState: BridgePushStatus | null;
|
|
20
|
+
requestPushSubscribe: () => void;
|
|
21
|
+
requestPushUnsubscribe: () => void;
|
|
15
22
|
}
|
|
16
23
|
interface BridgeMessage {
|
|
17
|
-
type:
|
|
24
|
+
type: BridgeMessageType;
|
|
25
|
+
id?: string;
|
|
18
26
|
[key: string]: unknown;
|
|
19
27
|
}
|
|
20
28
|
|
|
21
29
|
declare function useIframeBridge(): IframeBridgeHook;
|
|
22
30
|
|
|
23
|
-
|
|
31
|
+
declare const WEBVIEW_SHIM: string;
|
|
32
|
+
declare function buildShimUrl(): string;
|
|
33
|
+
|
|
34
|
+
export { type BridgeConfig, type BridgeMessage, type BridgeMessageType, type BridgePushStatus, type IframeBridgeHook, type ThemeMode, WEBVIEW_SHIM, buildShimUrl, useIframeBridge };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
|
+
type BridgePushStatus = "unsupported" | "default" | "subscribed" | "denied" | "subscribing" | "error";
|
|
2
|
+
type BridgeMessageType = "chat-ready" | "chat-config" | "chat-message" | "chat-notification-clicked" | "chat-close" | "chat-viewport-config" | "chat-viewport-insets" | "chat-push-state" | "chat-push-subscribe" | "chat-push-unsubscribe" | "chat-error";
|
|
3
|
+
type ThemeMode = "auto" | "light" | "dark";
|
|
1
4
|
interface BridgeConfig {
|
|
2
5
|
locale?: string;
|
|
3
6
|
title?: string;
|
|
4
7
|
placeholder?: string;
|
|
5
8
|
theme?: {
|
|
6
|
-
mode?:
|
|
9
|
+
mode?: ThemeMode;
|
|
10
|
+
cssVariables?: Record<string, string>;
|
|
7
11
|
};
|
|
8
12
|
}
|
|
9
13
|
interface IframeBridgeHook {
|
|
@@ -12,12 +16,19 @@ interface IframeBridgeHook {
|
|
|
12
16
|
notifyMessage: (text: string) => void;
|
|
13
17
|
notifyViewportConfig: (content: string) => void;
|
|
14
18
|
onNotificationClicked: (cb: () => void) => void;
|
|
19
|
+
pushState: BridgePushStatus | null;
|
|
20
|
+
requestPushSubscribe: () => void;
|
|
21
|
+
requestPushUnsubscribe: () => void;
|
|
15
22
|
}
|
|
16
23
|
interface BridgeMessage {
|
|
17
|
-
type:
|
|
24
|
+
type: BridgeMessageType;
|
|
25
|
+
id?: string;
|
|
18
26
|
[key: string]: unknown;
|
|
19
27
|
}
|
|
20
28
|
|
|
21
29
|
declare function useIframeBridge(): IframeBridgeHook;
|
|
22
30
|
|
|
23
|
-
|
|
31
|
+
declare const WEBVIEW_SHIM: string;
|
|
32
|
+
declare function buildShimUrl(): string;
|
|
33
|
+
|
|
34
|
+
export { type BridgeConfig, type BridgeMessage, type BridgeMessageType, type BridgePushStatus, type IframeBridgeHook, type ThemeMode, WEBVIEW_SHIM, buildShimUrl, useIframeBridge };
|
package/dist/index.js
CHANGED
|
@@ -2,8 +2,15 @@
|
|
|
2
2
|
import { useCallback, useEffect, useRef, useState } from "react";
|
|
3
3
|
function useIframeBridge() {
|
|
4
4
|
const [config, setConfig] = useState(null);
|
|
5
|
+
const [pushState, setPushState] = useState(null);
|
|
5
6
|
const notificationCbRef = useRef(null);
|
|
7
|
+
const readyRef = useRef(false);
|
|
6
8
|
const isInIframe = typeof window !== "undefined" && window !== window.parent;
|
|
9
|
+
useEffect(() => {
|
|
10
|
+
if (typeof window !== "undefined" && window.__chatBridge?._pushState) {
|
|
11
|
+
setPushState(window.__chatBridge._pushState);
|
|
12
|
+
}
|
|
13
|
+
}, []);
|
|
7
14
|
const notifyMessage = useCallback(
|
|
8
15
|
(text) => {
|
|
9
16
|
if (!isInIframe) return;
|
|
@@ -23,6 +30,25 @@ function useIframeBridge() {
|
|
|
23
30
|
const onNotificationClicked = useCallback((cb) => {
|
|
24
31
|
notificationCbRef.current = cb;
|
|
25
32
|
}, []);
|
|
33
|
+
const requestPushSubscribe = useCallback(() => {
|
|
34
|
+
if (!isInIframe) return;
|
|
35
|
+
const msg = { type: "chat-push-subscribe" };
|
|
36
|
+
window.parent.postMessage(msg, "*");
|
|
37
|
+
}, [isInIframe]);
|
|
38
|
+
const requestPushUnsubscribe = useCallback(() => {
|
|
39
|
+
if (!isInIframe) return;
|
|
40
|
+
const msg = { type: "chat-push-unsubscribe" };
|
|
41
|
+
window.parent.postMessage(msg, "*");
|
|
42
|
+
}, [isInIframe]);
|
|
43
|
+
useEffect(() => {
|
|
44
|
+
if (!isInIframe) return;
|
|
45
|
+
if (readyRef.current) return;
|
|
46
|
+
readyRef.current = true;
|
|
47
|
+
const msg = { type: "chat-ready" };
|
|
48
|
+
if (typeof window.parent.postMessage === "function") {
|
|
49
|
+
window.parent.postMessage(msg, "*");
|
|
50
|
+
}
|
|
51
|
+
}, [isInIframe]);
|
|
26
52
|
useEffect(() => {
|
|
27
53
|
if (!isInIframe) return;
|
|
28
54
|
function handleMessage(event) {
|
|
@@ -38,14 +64,112 @@ function useIframeBridge() {
|
|
|
38
64
|
case "chat-notification-clicked":
|
|
39
65
|
notificationCbRef.current?.();
|
|
40
66
|
break;
|
|
67
|
+
case "chat-push-state":
|
|
68
|
+
if (typeof data.status === "string") {
|
|
69
|
+
setPushState(data.status);
|
|
70
|
+
}
|
|
71
|
+
break;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
function handleCustomEvent(event) {
|
|
75
|
+
const detail = event.detail;
|
|
76
|
+
if (!detail || typeof detail !== "object") return;
|
|
77
|
+
if (detail.type === "chat-push-state" && typeof detail.status === "string") {
|
|
78
|
+
setPushState(detail.status);
|
|
41
79
|
}
|
|
42
80
|
}
|
|
43
81
|
window.addEventListener("message", handleMessage);
|
|
44
|
-
|
|
82
|
+
window.addEventListener("chat-bridge", handleCustomEvent);
|
|
83
|
+
return () => {
|
|
84
|
+
window.removeEventListener("message", handleMessage);
|
|
85
|
+
window.removeEventListener("chat-bridge", handleCustomEvent);
|
|
86
|
+
};
|
|
45
87
|
}, [isInIframe]);
|
|
46
|
-
return {
|
|
88
|
+
return {
|
|
89
|
+
config,
|
|
90
|
+
isInIframe,
|
|
91
|
+
notifyMessage,
|
|
92
|
+
notifyViewportConfig,
|
|
93
|
+
onNotificationClicked,
|
|
94
|
+
pushState,
|
|
95
|
+
requestPushSubscribe,
|
|
96
|
+
requestPushUnsubscribe
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// src/shim.ts
|
|
101
|
+
var WEBVIEW_SHIM = `
|
|
102
|
+
(function () {
|
|
103
|
+
'use strict';
|
|
104
|
+
var _cached = [];
|
|
105
|
+
var _originalPostMessage = window.parent && window.parent.postMessage;
|
|
106
|
+
|
|
107
|
+
function _send(msg) {
|
|
108
|
+
try {
|
|
109
|
+
var json = JSON.stringify(msg);
|
|
110
|
+
} catch (e) {
|
|
111
|
+
var errJson = JSON.stringify({ type: 'chat-error', code: 'SERIALIZE_ERROR', message: 'Failed to serialize message' + e.message });
|
|
112
|
+
try { if (window.parent) window.parent.postMessage(errJson, '*'); } catch (_) {}
|
|
113
|
+
console.error('[ChatBridge] JSON.stringify failed:', e);
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
try {
|
|
117
|
+
if (window.ReactNativeWebView && window.ReactNativeWebView.postMessage) {
|
|
118
|
+
window.ReactNativeWebView.postMessage(json);
|
|
119
|
+
} else if (window.AndroidBridge && window.AndroidBridge.postMessage) {
|
|
120
|
+
window.AndroidBridge.postMessage(json);
|
|
121
|
+
} else if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.chatBridge) {
|
|
122
|
+
window.webkit.messageHandlers.chatBridge.postMessage(msg);
|
|
123
|
+
} else if (_originalPostMessage) {
|
|
124
|
+
_originalPostMessage.call(window.parent, msg, '*');
|
|
125
|
+
} else {
|
|
126
|
+
console.warn('[ChatBridge] No bridge API detected');
|
|
127
|
+
}
|
|
128
|
+
} catch (e) {
|
|
129
|
+
var fallback = JSON.stringify({ type: 'chat-error', code: 'BRIDGE_ERROR', message: 'Bridge postMessage failed: ' + e.message });
|
|
130
|
+
try { if (window.parent) window.parent.postMessage(fallback, '*'); } catch (_) {}
|
|
131
|
+
console.error('[ChatBridge] postMessage failed:', e);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
window.__chatBridge = {
|
|
136
|
+
_pushState: null,
|
|
137
|
+
send: function (msg) { _send(msg); },
|
|
138
|
+
setPushState: function (status) { window.__chatBridge._pushState = status; },
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
var _batches = 0;
|
|
142
|
+
window.addEventListener('chat-bridge', function (e) {
|
|
143
|
+
if (_batches++ > 0) return;
|
|
144
|
+
requestAnimationFrame(function () {
|
|
145
|
+
_batches = 0;
|
|
146
|
+
});
|
|
147
|
+
var payload = e.detail;
|
|
148
|
+
if (!payload || typeof payload !== 'object') return;
|
|
149
|
+
var type = payload.type;
|
|
150
|
+
if (type === 'chat-config') {
|
|
151
|
+
window.__chatBridge._config = payload;
|
|
152
|
+
} else if (type === 'chat-push-state') {
|
|
153
|
+
window.__chatBridge._pushState = payload.status || null;
|
|
154
|
+
}
|
|
155
|
+
_cached.push(payload);
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
window.addEventListener('message', function (e) {
|
|
159
|
+
var data = e.data;
|
|
160
|
+
if (!data || typeof data !== 'object' || !data.type) return;
|
|
161
|
+
if (data.type === 'chat-push-state') {
|
|
162
|
+
window.__chatBridge._pushState = data.status || null;
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
})();
|
|
166
|
+
`;
|
|
167
|
+
function buildShimUrl() {
|
|
168
|
+
return "data:text/javascript;base64," + btoa(WEBVIEW_SHIM);
|
|
47
169
|
}
|
|
48
170
|
export {
|
|
171
|
+
WEBVIEW_SHIM,
|
|
172
|
+
buildShimUrl,
|
|
49
173
|
useIframeBridge
|
|
50
174
|
};
|
|
51
175
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/useIframeBridge.ts"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from \"react\";\nimport type { BridgeConfig, BridgeMessage, IframeBridgeHook } from \"./types\";\n\nexport function useIframeBridge(): IframeBridgeHook {\n const [config, setConfig] = useState<BridgeConfig | null>(null);\n const notificationCbRef = useRef<(() => void) | null>(null);\n\n const isInIframe = typeof window !== \"undefined\" && window !== window.parent;\n\n const notifyMessage = useCallback(\n (text: string) => {\n if (!isInIframe) return;\n const msg: BridgeMessage = { type: \"chat-message\", text };\n window.parent.postMessage(msg, \"*\");\n },\n [isInIframe],\n );\n\n const notifyViewportConfig = useCallback(\n (content: string) => {\n if (!isInIframe) return;\n const msg: BridgeMessage = { type: \"chat-viewport-config\", content };\n window.parent.postMessage(msg, \"*\");\n },\n [isInIframe],\n );\n\n const onNotificationClicked = useCallback((cb: () => void) => {\n notificationCbRef.current = cb;\n }, []);\n\n useEffect(() => {\n if (!isInIframe) return;\n\n function handleMessage(event: MessageEvent) {\n const data = event.data as Record<string, unknown>;\n if (!data || typeof data !== \"object\" || !data.type) return;\n\n switch (data.type) {\n case \"chat-config\": {\n const configData = { ...data };\n delete configData.type;\n setConfig(configData as BridgeConfig);\n break;\n }\n case \"chat-notification-clicked\":\n notificationCbRef.current?.();\n break;\n }\n }\n\n window.addEventListener(\"message\", handleMessage);\n return () => window.removeEventListener(\"message\", handleMessage);\n }, [isInIframe]);\n\n return {
|
|
1
|
+
{"version":3,"sources":["../src/useIframeBridge.ts","../src/shim.ts"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from \"react\";\nimport type { BridgeConfig, BridgeMessage, BridgePushStatus, IframeBridgeHook } from \"./types\";\n\nexport function useIframeBridge(): IframeBridgeHook {\n const [config, setConfig] = useState<BridgeConfig | null>(null);\n const [pushState, setPushState] = useState<BridgePushStatus | null>(null);\n const notificationCbRef = useRef<(() => void) | null>(null);\n const readyRef = useRef(false);\n\n const isInIframe = typeof window !== \"undefined\" && window !== window.parent;\n\n useEffect(() => {\n if (typeof window !== \"undefined\" && (window as any).__chatBridge?._pushState) {\n setPushState((window as any).__chatBridge._pushState);\n }\n }, []);\n\n const notifyMessage = useCallback(\n (text: string) => {\n if (!isInIframe) return;\n const msg: BridgeMessage = { type: \"chat-message\", text };\n window.parent.postMessage(msg, \"*\");\n },\n [isInIframe],\n );\n\n const notifyViewportConfig = useCallback(\n (content: string) => {\n if (!isInIframe) return;\n const msg: BridgeMessage = { type: \"chat-viewport-config\", content };\n window.parent.postMessage(msg, \"*\");\n },\n [isInIframe],\n );\n\n const onNotificationClicked = useCallback((cb: () => void) => {\n notificationCbRef.current = cb;\n }, []);\n\n const requestPushSubscribe = useCallback(() => {\n if (!isInIframe) return;\n const msg: BridgeMessage = { type: \"chat-push-subscribe\" };\n window.parent.postMessage(msg, \"*\");\n }, [isInIframe]);\n\n const requestPushUnsubscribe = useCallback(() => {\n if (!isInIframe) return;\n const msg: BridgeMessage = { type: \"chat-push-unsubscribe\" };\n window.parent.postMessage(msg, \"*\");\n }, [isInIframe]);\n\n useEffect(() => {\n if (!isInIframe) return;\n if (readyRef.current) return;\n readyRef.current = true;\n\n const msg: BridgeMessage = { type: \"chat-ready\" };\n if (typeof window.parent.postMessage === \"function\") {\n window.parent.postMessage(msg, \"*\");\n }\n }, [isInIframe]);\n\n useEffect(() => {\n if (!isInIframe) return;\n\n function handleMessage(event: MessageEvent) {\n const data = event.data as Record<string, unknown>;\n if (!data || typeof data !== \"object\" || !data.type) return;\n\n switch (data.type) {\n case \"chat-config\": {\n const configData = { ...data };\n delete configData.type;\n setConfig(configData as BridgeConfig);\n break;\n }\n case \"chat-notification-clicked\":\n notificationCbRef.current?.();\n break;\n case \"chat-push-state\":\n if (typeof data.status === \"string\") {\n setPushState(data.status as BridgePushStatus);\n }\n break;\n }\n }\n\n function handleCustomEvent(event: Event) {\n const detail = (event as CustomEvent).detail;\n if (!detail || typeof detail !== \"object\") return;\n if (detail.type === \"chat-push-state\" && typeof detail.status === \"string\") {\n setPushState(detail.status as BridgePushStatus);\n }\n }\n\n window.addEventListener(\"message\", handleMessage);\n window.addEventListener(\"chat-bridge\", handleCustomEvent);\n return () => {\n window.removeEventListener(\"message\", handleMessage);\n window.removeEventListener(\"chat-bridge\", handleCustomEvent);\n };\n }, [isInIframe]);\n\n return {\n config,\n isInIframe,\n notifyMessage,\n notifyViewportConfig,\n onNotificationClicked,\n pushState,\n requestPushSubscribe,\n requestPushUnsubscribe,\n };\n}\n","export const WEBVIEW_SHIM: string = `\n(function () {\n 'use strict';\n var _cached = [];\n var _originalPostMessage = window.parent && window.parent.postMessage;\n\n function _send(msg) {\n try {\n var json = JSON.stringify(msg);\n } catch (e) {\n var errJson = JSON.stringify({ type: 'chat-error', code: 'SERIALIZE_ERROR', message: 'Failed to serialize message' + e.message });\n try { if (window.parent) window.parent.postMessage(errJson, '*'); } catch (_) {}\n console.error('[ChatBridge] JSON.stringify failed:', e);\n return;\n }\n try {\n if (window.ReactNativeWebView && window.ReactNativeWebView.postMessage) {\n window.ReactNativeWebView.postMessage(json);\n } else if (window.AndroidBridge && window.AndroidBridge.postMessage) {\n window.AndroidBridge.postMessage(json);\n } else if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.chatBridge) {\n window.webkit.messageHandlers.chatBridge.postMessage(msg);\n } else if (_originalPostMessage) {\n _originalPostMessage.call(window.parent, msg, '*');\n } else {\n console.warn('[ChatBridge] No bridge API detected');\n }\n } catch (e) {\n var fallback = JSON.stringify({ type: 'chat-error', code: 'BRIDGE_ERROR', message: 'Bridge postMessage failed: ' + e.message });\n try { if (window.parent) window.parent.postMessage(fallback, '*'); } catch (_) {}\n console.error('[ChatBridge] postMessage failed:', e);\n }\n }\n\n window.__chatBridge = {\n _pushState: null,\n send: function (msg) { _send(msg); },\n setPushState: function (status) { window.__chatBridge._pushState = status; },\n };\n\n var _batches = 0;\n window.addEventListener('chat-bridge', function (e) {\n if (_batches++ > 0) return;\n requestAnimationFrame(function () {\n _batches = 0;\n });\n var payload = e.detail;\n if (!payload || typeof payload !== 'object') return;\n var type = payload.type;\n if (type === 'chat-config') {\n window.__chatBridge._config = payload;\n } else if (type === 'chat-push-state') {\n window.__chatBridge._pushState = payload.status || null;\n }\n _cached.push(payload);\n });\n\n window.addEventListener('message', function (e) {\n var data = e.data;\n if (!data || typeof data !== 'object' || !data.type) return;\n if (data.type === 'chat-push-state') {\n window.__chatBridge._pushState = data.status || null;\n }\n });\n})();\n`;\n\nexport function buildShimUrl(): string {\n return \"data:text/javascript;base64,\" + btoa(WEBVIEW_SHIM);\n}\n"],"mappings":"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","names":[]}
|
package/dist/shim.cjs
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/shim.ts
|
|
21
|
+
var shim_exports = {};
|
|
22
|
+
__export(shim_exports, {
|
|
23
|
+
WEBVIEW_SHIM: () => WEBVIEW_SHIM,
|
|
24
|
+
buildShimUrl: () => buildShimUrl
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(shim_exports);
|
|
27
|
+
var WEBVIEW_SHIM = `
|
|
28
|
+
(function () {
|
|
29
|
+
'use strict';
|
|
30
|
+
var _cached = [];
|
|
31
|
+
var _originalPostMessage = window.parent && window.parent.postMessage;
|
|
32
|
+
|
|
33
|
+
function _send(msg) {
|
|
34
|
+
try {
|
|
35
|
+
var json = JSON.stringify(msg);
|
|
36
|
+
} catch (e) {
|
|
37
|
+
var errJson = JSON.stringify({ type: 'chat-error', code: 'SERIALIZE_ERROR', message: 'Failed to serialize message' + e.message });
|
|
38
|
+
try { if (window.parent) window.parent.postMessage(errJson, '*'); } catch (_) {}
|
|
39
|
+
console.error('[ChatBridge] JSON.stringify failed:', e);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
try {
|
|
43
|
+
if (window.ReactNativeWebView && window.ReactNativeWebView.postMessage) {
|
|
44
|
+
window.ReactNativeWebView.postMessage(json);
|
|
45
|
+
} else if (window.AndroidBridge && window.AndroidBridge.postMessage) {
|
|
46
|
+
window.AndroidBridge.postMessage(json);
|
|
47
|
+
} else if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.chatBridge) {
|
|
48
|
+
window.webkit.messageHandlers.chatBridge.postMessage(msg);
|
|
49
|
+
} else if (_originalPostMessage) {
|
|
50
|
+
_originalPostMessage.call(window.parent, msg, '*');
|
|
51
|
+
} else {
|
|
52
|
+
console.warn('[ChatBridge] No bridge API detected');
|
|
53
|
+
}
|
|
54
|
+
} catch (e) {
|
|
55
|
+
var fallback = JSON.stringify({ type: 'chat-error', code: 'BRIDGE_ERROR', message: 'Bridge postMessage failed: ' + e.message });
|
|
56
|
+
try { if (window.parent) window.parent.postMessage(fallback, '*'); } catch (_) {}
|
|
57
|
+
console.error('[ChatBridge] postMessage failed:', e);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
window.__chatBridge = {
|
|
62
|
+
_pushState: null,
|
|
63
|
+
send: function (msg) { _send(msg); },
|
|
64
|
+
setPushState: function (status) { window.__chatBridge._pushState = status; },
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
var _batches = 0;
|
|
68
|
+
window.addEventListener('chat-bridge', function (e) {
|
|
69
|
+
if (_batches++ > 0) return;
|
|
70
|
+
requestAnimationFrame(function () {
|
|
71
|
+
_batches = 0;
|
|
72
|
+
});
|
|
73
|
+
var payload = e.detail;
|
|
74
|
+
if (!payload || typeof payload !== 'object') return;
|
|
75
|
+
var type = payload.type;
|
|
76
|
+
if (type === 'chat-config') {
|
|
77
|
+
window.__chatBridge._config = payload;
|
|
78
|
+
} else if (type === 'chat-push-state') {
|
|
79
|
+
window.__chatBridge._pushState = payload.status || null;
|
|
80
|
+
}
|
|
81
|
+
_cached.push(payload);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
window.addEventListener('message', function (e) {
|
|
85
|
+
var data = e.data;
|
|
86
|
+
if (!data || typeof data !== 'object' || !data.type) return;
|
|
87
|
+
if (data.type === 'chat-push-state') {
|
|
88
|
+
window.__chatBridge._pushState = data.status || null;
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
})();
|
|
92
|
+
`;
|
|
93
|
+
function buildShimUrl() {
|
|
94
|
+
return "data:text/javascript;base64," + btoa(WEBVIEW_SHIM);
|
|
95
|
+
}
|
|
96
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
97
|
+
0 && (module.exports = {
|
|
98
|
+
WEBVIEW_SHIM,
|
|
99
|
+
buildShimUrl
|
|
100
|
+
});
|
|
101
|
+
//# sourceMappingURL=shim.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/shim.ts"],"sourcesContent":["export const WEBVIEW_SHIM: string = `\n(function () {\n 'use strict';\n var _cached = [];\n var _originalPostMessage = window.parent && window.parent.postMessage;\n\n function _send(msg) {\n try {\n var json = JSON.stringify(msg);\n } catch (e) {\n var errJson = JSON.stringify({ type: 'chat-error', code: 'SERIALIZE_ERROR', message: 'Failed to serialize message' + e.message });\n try { if (window.parent) window.parent.postMessage(errJson, '*'); } catch (_) {}\n console.error('[ChatBridge] JSON.stringify failed:', e);\n return;\n }\n try {\n if (window.ReactNativeWebView && window.ReactNativeWebView.postMessage) {\n window.ReactNativeWebView.postMessage(json);\n } else if (window.AndroidBridge && window.AndroidBridge.postMessage) {\n window.AndroidBridge.postMessage(json);\n } else if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.chatBridge) {\n window.webkit.messageHandlers.chatBridge.postMessage(msg);\n } else if (_originalPostMessage) {\n _originalPostMessage.call(window.parent, msg, '*');\n } else {\n console.warn('[ChatBridge] No bridge API detected');\n }\n } catch (e) {\n var fallback = JSON.stringify({ type: 'chat-error', code: 'BRIDGE_ERROR', message: 'Bridge postMessage failed: ' + e.message });\n try { if (window.parent) window.parent.postMessage(fallback, '*'); } catch (_) {}\n console.error('[ChatBridge] postMessage failed:', e);\n }\n }\n\n window.__chatBridge = {\n _pushState: null,\n send: function (msg) { _send(msg); },\n setPushState: function (status) { window.__chatBridge._pushState = status; },\n };\n\n var _batches = 0;\n window.addEventListener('chat-bridge', function (e) {\n if (_batches++ > 0) return;\n requestAnimationFrame(function () {\n _batches = 0;\n });\n var payload = e.detail;\n if (!payload || typeof payload !== 'object') return;\n var type = payload.type;\n if (type === 'chat-config') {\n window.__chatBridge._config = payload;\n } else if (type === 'chat-push-state') {\n window.__chatBridge._pushState = payload.status || null;\n }\n _cached.push(payload);\n });\n\n window.addEventListener('message', function (e) {\n var data = e.data;\n if (!data || typeof data !== 'object' || !data.type) return;\n if (data.type === 'chat-push-state') {\n window.__chatBridge._pushState = data.status || null;\n }\n });\n})();\n`;\n\nexport function buildShimUrl(): string {\n return \"data:text/javascript;base64,\" + btoa(WEBVIEW_SHIM);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAO,IAAM,eAAuB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAmE7B,SAAS,eAAuB;AACrC,SAAO,iCAAiC,KAAK,YAAY;AAC3D;","names":[]}
|
package/dist/shim.js
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
// src/shim.ts
|
|
2
|
+
var WEBVIEW_SHIM = `
|
|
3
|
+
(function () {
|
|
4
|
+
'use strict';
|
|
5
|
+
var _cached = [];
|
|
6
|
+
var _originalPostMessage = window.parent && window.parent.postMessage;
|
|
7
|
+
|
|
8
|
+
function _send(msg) {
|
|
9
|
+
try {
|
|
10
|
+
var json = JSON.stringify(msg);
|
|
11
|
+
} catch (e) {
|
|
12
|
+
var errJson = JSON.stringify({ type: 'chat-error', code: 'SERIALIZE_ERROR', message: 'Failed to serialize message' + e.message });
|
|
13
|
+
try { if (window.parent) window.parent.postMessage(errJson, '*'); } catch (_) {}
|
|
14
|
+
console.error('[ChatBridge] JSON.stringify failed:', e);
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
try {
|
|
18
|
+
if (window.ReactNativeWebView && window.ReactNativeWebView.postMessage) {
|
|
19
|
+
window.ReactNativeWebView.postMessage(json);
|
|
20
|
+
} else if (window.AndroidBridge && window.AndroidBridge.postMessage) {
|
|
21
|
+
window.AndroidBridge.postMessage(json);
|
|
22
|
+
} else if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.chatBridge) {
|
|
23
|
+
window.webkit.messageHandlers.chatBridge.postMessage(msg);
|
|
24
|
+
} else if (_originalPostMessage) {
|
|
25
|
+
_originalPostMessage.call(window.parent, msg, '*');
|
|
26
|
+
} else {
|
|
27
|
+
console.warn('[ChatBridge] No bridge API detected');
|
|
28
|
+
}
|
|
29
|
+
} catch (e) {
|
|
30
|
+
var fallback = JSON.stringify({ type: 'chat-error', code: 'BRIDGE_ERROR', message: 'Bridge postMessage failed: ' + e.message });
|
|
31
|
+
try { if (window.parent) window.parent.postMessage(fallback, '*'); } catch (_) {}
|
|
32
|
+
console.error('[ChatBridge] postMessage failed:', e);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
window.__chatBridge = {
|
|
37
|
+
_pushState: null,
|
|
38
|
+
send: function (msg) { _send(msg); },
|
|
39
|
+
setPushState: function (status) { window.__chatBridge._pushState = status; },
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
var _batches = 0;
|
|
43
|
+
window.addEventListener('chat-bridge', function (e) {
|
|
44
|
+
if (_batches++ > 0) return;
|
|
45
|
+
requestAnimationFrame(function () {
|
|
46
|
+
_batches = 0;
|
|
47
|
+
});
|
|
48
|
+
var payload = e.detail;
|
|
49
|
+
if (!payload || typeof payload !== 'object') return;
|
|
50
|
+
var type = payload.type;
|
|
51
|
+
if (type === 'chat-config') {
|
|
52
|
+
window.__chatBridge._config = payload;
|
|
53
|
+
} else if (type === 'chat-push-state') {
|
|
54
|
+
window.__chatBridge._pushState = payload.status || null;
|
|
55
|
+
}
|
|
56
|
+
_cached.push(payload);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
window.addEventListener('message', function (e) {
|
|
60
|
+
var data = e.data;
|
|
61
|
+
if (!data || typeof data !== 'object' || !data.type) return;
|
|
62
|
+
if (data.type === 'chat-push-state') {
|
|
63
|
+
window.__chatBridge._pushState = data.status || null;
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
})();
|
|
67
|
+
`;
|
|
68
|
+
function buildShimUrl() {
|
|
69
|
+
return "data:text/javascript;base64," + btoa(WEBVIEW_SHIM);
|
|
70
|
+
}
|
|
71
|
+
export {
|
|
72
|
+
WEBVIEW_SHIM,
|
|
73
|
+
buildShimUrl
|
|
74
|
+
};
|
|
75
|
+
//# sourceMappingURL=shim.js.map
|
package/dist/shim.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/shim.ts"],"sourcesContent":["export const WEBVIEW_SHIM: string = `\n(function () {\n 'use strict';\n var _cached = [];\n var _originalPostMessage = window.parent && window.parent.postMessage;\n\n function _send(msg) {\n try {\n var json = JSON.stringify(msg);\n } catch (e) {\n var errJson = JSON.stringify({ type: 'chat-error', code: 'SERIALIZE_ERROR', message: 'Failed to serialize message' + e.message });\n try { if (window.parent) window.parent.postMessage(errJson, '*'); } catch (_) {}\n console.error('[ChatBridge] JSON.stringify failed:', e);\n return;\n }\n try {\n if (window.ReactNativeWebView && window.ReactNativeWebView.postMessage) {\n window.ReactNativeWebView.postMessage(json);\n } else if (window.AndroidBridge && window.AndroidBridge.postMessage) {\n window.AndroidBridge.postMessage(json);\n } else if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.chatBridge) {\n window.webkit.messageHandlers.chatBridge.postMessage(msg);\n } else if (_originalPostMessage) {\n _originalPostMessage.call(window.parent, msg, '*');\n } else {\n console.warn('[ChatBridge] No bridge API detected');\n }\n } catch (e) {\n var fallback = JSON.stringify({ type: 'chat-error', code: 'BRIDGE_ERROR', message: 'Bridge postMessage failed: ' + e.message });\n try { if (window.parent) window.parent.postMessage(fallback, '*'); } catch (_) {}\n console.error('[ChatBridge] postMessage failed:', e);\n }\n }\n\n window.__chatBridge = {\n _pushState: null,\n send: function (msg) { _send(msg); },\n setPushState: function (status) { window.__chatBridge._pushState = status; },\n };\n\n var _batches = 0;\n window.addEventListener('chat-bridge', function (e) {\n if (_batches++ > 0) return;\n requestAnimationFrame(function () {\n _batches = 0;\n });\n var payload = e.detail;\n if (!payload || typeof payload !== 'object') return;\n var type = payload.type;\n if (type === 'chat-config') {\n window.__chatBridge._config = payload;\n } else if (type === 'chat-push-state') {\n window.__chatBridge._pushState = payload.status || null;\n }\n _cached.push(payload);\n });\n\n window.addEventListener('message', function (e) {\n var data = e.data;\n if (!data || typeof data !== 'object' || !data.type) return;\n if (data.type === 'chat-push-state') {\n window.__chatBridge._pushState = data.status || null;\n }\n });\n})();\n`;\n\nexport function buildShimUrl(): string {\n return \"data:text/javascript;base64,\" + btoa(WEBVIEW_SHIM);\n}\n"],"mappings":";AAAO,IAAM,eAAuB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAmE7B,SAAS,eAAuB;AACrC,SAAO,iCAAiC,KAAK,YAAY;AAC3D;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bootdesk/chat-widget-bridge",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.6",
|
|
4
4
|
"description": "Iframe bridge for BootDesk Chat SDK - enables embedding the chat widget in an iframe with cross-frame communication via postMessage",
|
|
5
5
|
"repository": "https://github.com/bootdesk/chat-sdk",
|
|
6
6
|
"type": "module",
|
|
@@ -16,6 +16,10 @@
|
|
|
16
16
|
"./embed-chat": {
|
|
17
17
|
"import": "./dist/embed-chat.js",
|
|
18
18
|
"require": "./dist/embed-chat.cjs"
|
|
19
|
+
},
|
|
20
|
+
"./shim": {
|
|
21
|
+
"import": "./dist/shim.js",
|
|
22
|
+
"require": "./dist/shim.cjs"
|
|
19
23
|
}
|
|
20
24
|
},
|
|
21
25
|
"files": [
|