@returningai/widget-sdk 1.7.1 → 1.7.2
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/CHANGELOG.md +16 -0
- package/README.md +6 -2
- package/dist/rai-banner.iife.js +1 -1
- package/dist/rai-banner.js +40 -30
- package/dist/rai-widget.iife.js +2 -2
- package/dist/rai-widget.js +85 -36
- package/dist/types/BaseWidget.d.ts +1 -0
- package/dist/types/banner/color.d.ts +3 -0
- package/dist/types/banner/render.d.ts +3 -1
- package/dist/types/core/auto-theme-lease.d.ts +5 -0
- package/package.json +1 -1
package/dist/rai-widget.js
CHANGED
|
@@ -11741,9 +11741,10 @@ function sanitizeBannerHtml(html2) {
|
|
|
11741
11741
|
ALLOW_DATA_ATTR: false
|
|
11742
11742
|
});
|
|
11743
11743
|
}
|
|
11744
|
-
function resolveCssToken(token) {
|
|
11744
|
+
function resolveCssToken(token, preferredScope) {
|
|
11745
11745
|
const normalizedToken = token.startsWith("--") ? token : `--${token}`;
|
|
11746
11746
|
const candidates = [
|
|
11747
|
+
preferredScope,
|
|
11747
11748
|
document.documentElement,
|
|
11748
11749
|
document.body,
|
|
11749
11750
|
...Array.from(
|
|
@@ -11763,32 +11764,33 @@ function resolveCssToken(token) {
|
|
|
11763
11764
|
)
|
|
11764
11765
|
)
|
|
11765
11766
|
].filter(Boolean);
|
|
11767
|
+
const checked = /* @__PURE__ */ new Set();
|
|
11766
11768
|
for (const node of candidates) {
|
|
11769
|
+
if (checked.has(node)) continue;
|
|
11770
|
+
checked.add(node);
|
|
11767
11771
|
const value = getComputedStyle(node).getPropertyValue(normalizedToken).trim();
|
|
11768
11772
|
if (value) return value;
|
|
11769
11773
|
}
|
|
11770
11774
|
for (const node of Array.from(document.querySelectorAll("*"))) {
|
|
11775
|
+
if (checked.has(node)) continue;
|
|
11771
11776
|
const value = getComputedStyle(node).getPropertyValue(normalizedToken).trim();
|
|
11772
11777
|
if (value) return value;
|
|
11773
11778
|
}
|
|
11774
11779
|
return void 0;
|
|
11775
11780
|
}
|
|
11776
|
-
|
|
11781
|
+
function safeColor(v, preferredScope) {
|
|
11777
11782
|
if (!v) return void 0;
|
|
11778
11783
|
const value = v.trim();
|
|
11779
11784
|
if (/^(#|rgb|hsl)/i.test(value)) return value;
|
|
11780
11785
|
if (/^(--)?[a-z0-9-]+$/i.test(value)) {
|
|
11781
|
-
|
|
11782
|
-
return resolved;
|
|
11786
|
+
return resolveCssToken(value, preferredScope);
|
|
11783
11787
|
}
|
|
11784
11788
|
const varMatch = value.match(/^var\((--[a-z0-9-]+)\)$/i);
|
|
11785
11789
|
if (varMatch) {
|
|
11786
|
-
|
|
11787
|
-
const resolved = resolveCssToken(token);
|
|
11788
|
-
return resolved;
|
|
11790
|
+
return resolveCssToken(varMatch[1], preferredScope);
|
|
11789
11791
|
}
|
|
11790
11792
|
return void 0;
|
|
11791
|
-
}
|
|
11793
|
+
}
|
|
11792
11794
|
function el(tag, styles, attrs) {
|
|
11793
11795
|
const node = document.createElement(tag);
|
|
11794
11796
|
Object.assign(node.style, styles);
|
|
@@ -11872,15 +11874,15 @@ function justifyFromTextAlign(align) {
|
|
|
11872
11874
|
if (align === "right") return "flex-end";
|
|
11873
11875
|
return "flex-start";
|
|
11874
11876
|
}
|
|
11875
|
-
function renderBanner(banner, handlers) {
|
|
11877
|
+
function renderBanner(banner, handlers, colorScope) {
|
|
11876
11878
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
|
|
11877
11879
|
const placement = banner.placement || {};
|
|
11878
11880
|
const mode = placement.mode || "overlay";
|
|
11879
11881
|
const position = placement.position || "top";
|
|
11880
11882
|
const zIndex = String(placement.zIndex || 2147483e3);
|
|
11881
11883
|
const imageBanner = isImageBanner(banner);
|
|
11882
|
-
const bg = imageBanner ? "transparent" : safeColor((_a = banner.style) == null ? void 0 : _a.backgroundColor) || "#1f2024";
|
|
11883
|
-
const color = safeColor((_b = banner.style) == null ? void 0 : _b.color) || "#ffffff";
|
|
11884
|
+
const bg = imageBanner ? "transparent" : safeColor((_a = banner.style) == null ? void 0 : _a.backgroundColor, colorScope) || "#1f2024";
|
|
11885
|
+
const color = safeColor((_b = banner.style) == null ? void 0 : _b.color, colorScope) || "#ffffff";
|
|
11884
11886
|
const isCard = mode === "overlay" || mode === "popup";
|
|
11885
11887
|
const ctaPosition = getCtaStyleValue(banner, ["position"]) || "center";
|
|
11886
11888
|
const imageHorizontal = imageAlign((_c = banner.image) == null ? void 0 : _c.horizontalAlignment);
|
|
@@ -12021,9 +12023,13 @@ function renderBanner(banner, handlers) {
|
|
|
12021
12023
|
}
|
|
12022
12024
|
if (!imageBanner && ((_n = banner.cta) == null ? void 0 : _n.enabled)) {
|
|
12023
12025
|
const ctaBg = safeColor(
|
|
12024
|
-
getCtaStyleValue(banner, ["backgroundColor", "buttonColor", "aColor"])
|
|
12026
|
+
getCtaStyleValue(banner, ["backgroundColor", "buttonColor", "aColor"]),
|
|
12027
|
+
colorScope
|
|
12025
12028
|
) || "#2f6df6";
|
|
12026
|
-
const ctaColor = safeColor(
|
|
12029
|
+
const ctaColor = safeColor(
|
|
12030
|
+
getCtaStyleValue(banner, ["textColor", "color"]),
|
|
12031
|
+
colorScope
|
|
12032
|
+
) || "#ffffff";
|
|
12027
12033
|
const btn = el("button", {
|
|
12028
12034
|
cursor: "pointer",
|
|
12029
12035
|
border: "none",
|
|
@@ -12498,6 +12504,33 @@ function clearState(state) {
|
|
|
12498
12504
|
state.syncTimer = null;
|
|
12499
12505
|
}
|
|
12500
12506
|
}
|
|
12507
|
+
const AUTO_THEME_LEASE_STATE = "__RAI_AUTO_THEME_LEASE_STATE__";
|
|
12508
|
+
const DISABLE_AUTO_THEME = "__DISABLE_AUTO_THEME__";
|
|
12509
|
+
function acquireAutoThemeDisableLease(target = window) {
|
|
12510
|
+
let state = target[AUTO_THEME_LEASE_STATE];
|
|
12511
|
+
if (!state) {
|
|
12512
|
+
state = {
|
|
12513
|
+
count: 0,
|
|
12514
|
+
previousValue: target[DISABLE_AUTO_THEME]
|
|
12515
|
+
};
|
|
12516
|
+
target[AUTO_THEME_LEASE_STATE] = state;
|
|
12517
|
+
}
|
|
12518
|
+
state.count += 1;
|
|
12519
|
+
target[DISABLE_AUTO_THEME] = true;
|
|
12520
|
+
let released = false;
|
|
12521
|
+
return () => {
|
|
12522
|
+
if (released) return;
|
|
12523
|
+
released = true;
|
|
12524
|
+
state.count = Math.max(0, state.count - 1);
|
|
12525
|
+
if (state.count > 0) return;
|
|
12526
|
+
if (state.previousValue === void 0) {
|
|
12527
|
+
delete target[DISABLE_AUTO_THEME];
|
|
12528
|
+
} else {
|
|
12529
|
+
target[DISABLE_AUTO_THEME] = state.previousValue;
|
|
12530
|
+
}
|
|
12531
|
+
delete target[AUTO_THEME_LEASE_STATE];
|
|
12532
|
+
};
|
|
12533
|
+
}
|
|
12501
12534
|
const BUNDLE_READY_TIMEOUT_MS = 3e4;
|
|
12502
12535
|
function isPromiseLike(value) {
|
|
12503
12536
|
return (typeof value === "object" || typeof value === "function") && value !== null && typeof value.then === "function";
|
|
@@ -13133,6 +13166,7 @@ class BaseWidget extends HTMLElement {
|
|
|
13133
13166
|
__publicField(this, "lottieInstances", []);
|
|
13134
13167
|
__publicField(this, "callbackRegistry", new WidgetCallbackRegistry());
|
|
13135
13168
|
__publicField(this, "bannerNode", null);
|
|
13169
|
+
__publicField(this, "releaseAutoThemeDisableLease");
|
|
13136
13170
|
this.shadow = this.attachShadow({ mode: "closed" });
|
|
13137
13171
|
}
|
|
13138
13172
|
static get observedAttributes() {
|
|
@@ -13605,24 +13639,28 @@ class BaseWidget extends HTMLElement {
|
|
|
13605
13639
|
if (!banner) return;
|
|
13606
13640
|
if (((_a = banner.placement) == null ? void 0 : _a.mobileBehavior) === "hide" && device === "mobile")
|
|
13607
13641
|
return;
|
|
13608
|
-
const node = renderBanner(
|
|
13609
|
-
|
|
13610
|
-
|
|
13611
|
-
|
|
13612
|
-
|
|
13613
|
-
|
|
13614
|
-
|
|
13615
|
-
|
|
13616
|
-
|
|
13617
|
-
|
|
13642
|
+
const node = renderBanner(
|
|
13643
|
+
banner,
|
|
13644
|
+
{
|
|
13645
|
+
onCtaClick: () => {
|
|
13646
|
+
var _a2, _b2, _c;
|
|
13647
|
+
fireTracking((_a2 = banner.tracking) == null ? void 0 : _a2.clickUrl);
|
|
13648
|
+
this.emit("rai-banner-click", { bannerId: banner.id });
|
|
13649
|
+
const url = (_b2 = banner.cta) == null ? void 0 : _b2.url;
|
|
13650
|
+
if (!url) return;
|
|
13651
|
+
if ((_c = banner.cta) == null ? void 0 : _c.openInNewTab)
|
|
13652
|
+
window.open(url, "_blank", "noopener,noreferrer");
|
|
13653
|
+
else window.location.href = url;
|
|
13654
|
+
},
|
|
13655
|
+
onDismiss: () => {
|
|
13656
|
+
var _a2;
|
|
13657
|
+
fireTracking((_a2 = banner.tracking) == null ? void 0 : _a2.dismissUrl);
|
|
13658
|
+
this.emit("rai-banner-dismiss", { bannerId: banner.id });
|
|
13659
|
+
this.removeBanner();
|
|
13660
|
+
}
|
|
13618
13661
|
},
|
|
13619
|
-
|
|
13620
|
-
|
|
13621
|
-
fireTracking((_a2 = banner.tracking) == null ? void 0 : _a2.dismissUrl);
|
|
13622
|
-
this.emit("rai-banner-dismiss", { bannerId: banner.id });
|
|
13623
|
-
this.removeBanner();
|
|
13624
|
-
}
|
|
13625
|
-
});
|
|
13662
|
+
this
|
|
13663
|
+
);
|
|
13626
13664
|
this.bannerNode = node;
|
|
13627
13665
|
document.body.appendChild(node);
|
|
13628
13666
|
fireTracking((_b = banner.tracking) == null ? void 0 : _b.impressionUrl);
|
|
@@ -13730,6 +13768,9 @@ class BaseWidget extends HTMLElement {
|
|
|
13730
13768
|
return this.isConnected && initId === this.initGeneration;
|
|
13731
13769
|
}
|
|
13732
13770
|
teardownMountedWidget() {
|
|
13771
|
+
var _a;
|
|
13772
|
+
(_a = this.releaseAutoThemeDisableLease) == null ? void 0 : _a.call(this);
|
|
13773
|
+
this.releaseAutoThemeDisableLease = void 0;
|
|
13733
13774
|
if (this.cleanupListener) {
|
|
13734
13775
|
this.cleanupListener();
|
|
13735
13776
|
this.cleanupListener = void 0;
|
|
@@ -13783,9 +13824,13 @@ class BaseWidget extends HTMLElement {
|
|
|
13783
13824
|
}
|
|
13784
13825
|
// ── Bundle mode (no-iframe) ──────────────────────────────────────────
|
|
13785
13826
|
async mountWidget(initId) {
|
|
13827
|
+
var _a;
|
|
13786
13828
|
let container = null;
|
|
13787
13829
|
try {
|
|
13788
13830
|
this.teardownMountedWidget();
|
|
13831
|
+
if (this.config.widgetType === "custom") {
|
|
13832
|
+
this.releaseAutoThemeDisableLease = acquireAutoThemeDisableLease();
|
|
13833
|
+
}
|
|
13789
13834
|
const bundleApiUrl = this.config.v2ApiUrl || resolveV2ApiUrl(this.config.domainKey);
|
|
13790
13835
|
const w = window;
|
|
13791
13836
|
if (!w.DomainKey) {
|
|
@@ -13853,7 +13898,7 @@ class BaseWidget extends HTMLElement {
|
|
|
13853
13898
|
// post. Mirrors the iframe behavior, where `isOpenWidget` is only
|
|
13854
13899
|
// injected by SSR for the explicit `/open-widget` route.
|
|
13855
13900
|
isOpenWidget: !this.state.accessToken,
|
|
13856
|
-
defaultColorSchema: this.config.
|
|
13901
|
+
defaultColorSchema: this.config.widgetType === "custom" && !this.config.themeExplicit ? null : colorMode,
|
|
13857
13902
|
requestHostCallback: async (callbackName, payload) => {
|
|
13858
13903
|
if (this.config.widgetType !== "store" && this.config.widgetType !== "custom") {
|
|
13859
13904
|
throw new Error(
|
|
@@ -13881,6 +13926,8 @@ class BaseWidget extends HTMLElement {
|
|
|
13881
13926
|
return;
|
|
13882
13927
|
}
|
|
13883
13928
|
console.error("[rai-widget] Bundle mount failed:", err);
|
|
13929
|
+
(_a = this.releaseAutoThemeDisableLease) == null ? void 0 : _a.call(this);
|
|
13930
|
+
this.releaseAutoThemeDisableLease = void 0;
|
|
13884
13931
|
this.showError();
|
|
13885
13932
|
}
|
|
13886
13933
|
}
|
|
@@ -14056,17 +14103,19 @@ class CustomWidget extends BaseWidget {
|
|
|
14056
14103
|
const base = config.widgetUrl.endsWith("custom-widget") ? `${config.widgetUrl}/${config.widgetId}` : config.widgetUrl;
|
|
14057
14104
|
try {
|
|
14058
14105
|
const u = new URL(base);
|
|
14059
|
-
u.searchParams.set("
|
|
14106
|
+
u.searchParams.set("auth", "postmessage");
|
|
14107
|
+
if (config.themeExplicit) u.searchParams.set("color", config.theme);
|
|
14060
14108
|
if (config.locale) u.searchParams.set("locale", config.locale);
|
|
14061
14109
|
return u.toString();
|
|
14062
14110
|
} catch {
|
|
14063
|
-
const params = [
|
|
14111
|
+
const params = ["auth=postmessage"];
|
|
14112
|
+
if (config.themeExplicit) params.push(`color=${config.theme}`);
|
|
14064
14113
|
if (config.locale) params.push(`locale=${encodeURIComponent(config.locale)}`);
|
|
14065
|
-
return `${base}?${params.join("&")}
|
|
14114
|
+
return params.length > 0 ? `${base}?${params.join("&")}` : base;
|
|
14066
14115
|
}
|
|
14067
14116
|
}
|
|
14068
14117
|
}
|
|
14069
|
-
console.log(`[rai-widget] v${"1.7.
|
|
14118
|
+
console.log(`[rai-widget] v${"1.7.2"}`);
|
|
14070
14119
|
class StoreWidgetCompat extends StoreWidget {
|
|
14071
14120
|
}
|
|
14072
14121
|
const WIDGET_REGISTRY = [
|
|
@@ -14130,7 +14179,7 @@ function exposePublicApi() {
|
|
|
14130
14179
|
})();
|
|
14131
14180
|
const widget = container == null ? void 0 : container.querySelector(ALL_WIDGET_SELECTOR);
|
|
14132
14181
|
window.ReturningAIWidget = {
|
|
14133
|
-
version: "1.7.
|
|
14182
|
+
version: "1.7.2",
|
|
14134
14183
|
reload: () => (widget == null ? void 0 : widget.reload()) ?? Promise.resolve(),
|
|
14135
14184
|
logout: () => (widget == null ? void 0 : widget.logoutPublic()) ?? Promise.resolve(),
|
|
14136
14185
|
isAuthenticated: () => (widget == null ? void 0 : widget.isAuthenticated()) ?? false,
|
|
@@ -19,6 +19,7 @@ export declare abstract class BaseWidget extends HTMLElement {
|
|
|
19
19
|
private lottieInstances;
|
|
20
20
|
private callbackRegistry;
|
|
21
21
|
private bannerNode;
|
|
22
|
+
private releaseAutoThemeDisableLease?;
|
|
22
23
|
constructor();
|
|
23
24
|
registerCallback(callbackName: typeof STORE_CALLBACK_FIELD_OPTIONS_CALLBACK_NAME, callback: ReturningAIStoreCallbackFieldOptionsCallback): void;
|
|
24
25
|
registerCallback(callbackName: typeof STORE_PURCHASE_SUCCESS_CALLBACK_NAME, callback: ReturningAIStorePurchaseSuccessCallback): void;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
/** Resolve a CSS token from the owning widget before consulting the host page. */
|
|
2
|
+
export declare function resolveCssToken(token: string, preferredScope?: Element): string | undefined;
|
|
3
|
+
export declare function safeColor(v?: string, preferredScope?: Element): string | undefined;
|
|
@@ -7,6 +7,8 @@ export interface BannerHandlers {
|
|
|
7
7
|
* Builds the banner DOM (plain elements + inline styles, so it renders correctly
|
|
8
8
|
* on any host site without external CSS). Honors `placement.mode`:
|
|
9
9
|
* overlay/popup → fixed centered card; inline → in-flow full-width bar.
|
|
10
|
+
* Color tokens resolve from `colorScope` first so a banner uses its owning
|
|
11
|
+
* widget's palette instead of an unrelated host-page or sibling-widget theme.
|
|
10
12
|
* The caller decides where to attach it (body for overlay, target for inline).
|
|
11
13
|
*/
|
|
12
|
-
export declare function renderBanner(banner: EligibleBanner, handlers: BannerHandlers): HTMLElement;
|
|
14
|
+
export declare function renderBanner(banner: EligibleBanner, handlers: BannerHandlers, colorScope?: Element): HTMLElement;
|