@useinsider/guido 3.21.0-beta.78e343a → 3.21.0-beta.8a9421f

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.
@@ -1,10 +1,10 @@
1
1
  import { extractWrapperTags as A } from "../../../../utils/preserveTextStyles.js";
2
2
  import { RecommendationBlockId as c } from "../constants/blockIds.js";
3
- import { DESKTOP_CONTAINER_SELECTOR as g, ATTR_PRODUCT_NAME as k, ATTR_PRODUCT_PRICE as y, ATTR_PRODUCT_OLD_PRICE as p, ATTR_PRODUCT_OMNIBUS_PRICE as R, ATTR_PRODUCT_OMNIBUS_DISCOUNT as _, ATTR_PRODUCT_BUTTON as x, ATTR_PRODUCT_IMAGE as q, ATTR_PRODUCT_ATTR as v } from "../constants/selectors.js";
3
+ import { DESKTOP_CONTAINER_SELECTOR as b, ATTR_PRODUCT_NAME as k, ATTR_PRODUCT_PRICE as y, ATTR_PRODUCT_OLD_PRICE as p, ATTR_PRODUCT_OMNIBUS_PRICE as R, ATTR_PRODUCT_OMNIBUS_DISCOUNT as _, ATTR_PRODUCT_BUTTON as x, ATTR_PRODUCT_IMAGE as q, ATTR_PRODUCT_ATTR as v } from "../constants/selectors.js";
4
4
  import { CSS_CLASS_TEXT_TRIM as B } from "../controls/shared/textTrimCssRules.js";
5
5
  import { toCustomCompositionKey as U } from "../templates/utils.js";
6
6
  import { resolveRowVisibilityKeys as N, isMergedInlinePriceRow as C } from "./compositionKeys.js";
7
- import { hasQuerySelectorAll as I, hasGetAttribute as l, hasGetStyle as h, hasGetComputedStyle as M } from "./tagName.js";
7
+ import { hasQuerySelectorAll as I, hasGetAttribute as l, hasGetStyle as O, hasGetComputedStyle as M } from "./tagName.js";
8
8
  const s = [
9
9
  "font-size",
10
10
  "font-family",
@@ -37,10 +37,9 @@ const s = [
37
37
  "width",
38
38
  "height",
39
39
  "max-width",
40
- "max-height",
41
40
  "border-radius",
42
41
  "margin"
43
- ], b = /* @__PURE__ */ new Set(["transparent", "rgba(0, 0, 0, 0)"]), L = [
42
+ ], g = /* @__PURE__ */ new Set(["transparent", "rgba(0, 0, 0, 0)"]), L = [
44
43
  { attrKey: k, blockId: c.NAME, kind: "text" },
45
44
  { attrKey: y, blockId: c.PRICE, kind: "text" },
46
45
  { attrKey: p, blockId: c.OLD_PRICE, kind: "text" },
@@ -49,14 +48,14 @@ const s = [
49
48
  { attrKey: x, blockId: c.BUTTON, kind: "button" },
50
49
  { attrKey: q, blockId: c.IMAGE, kind: "image" }
51
50
  ];
52
- function O(t) {
51
+ function h(t) {
53
52
  return t && "getInnerHTML" in t && typeof t.getInnerHTML == "function" ? t.getInnerHTML().trim() : "";
54
53
  }
55
54
  function K(t) {
56
55
  return t && "getInnerText" in t && typeof t.getInnerText == "function" ? t.getInnerText().trim() : "";
57
56
  }
58
57
  function a(t, e, r) {
59
- !e || !h(e) || r.forEach((n) => {
58
+ !e || !O(e) || r.forEach((n) => {
60
59
  const o = e.getStyle(n);
61
60
  o && o !== "inherit" && o !== "initial" && (t[n] = o);
62
61
  });
@@ -65,10 +64,10 @@ function E(t) {
65
64
  return Object.entries(t).map(([e, r]) => `${e}: ${r};`).join(" ");
66
65
  }
67
66
  function P(t) {
68
- if (!t || !h(t))
67
+ if (!t || !O(t))
69
68
  return;
70
69
  const e = t.getStyle("background-color") || t.getStyle("background");
71
- return e && !b.has(e) ? e : void 0;
70
+ return e && !g.has(e) ? e : void 0;
72
71
  }
73
72
  function S(t, e) {
74
73
  const r = {};
@@ -77,11 +76,11 @@ function S(t, e) {
77
76
  function $(t) {
78
77
  const e = t.querySelector("p"), r = {};
79
78
  a(r, t, s), a(r, e, s), a(r, t.querySelector("strong"), s), a(r, t.querySelector("em"), s), a(r, t.querySelector("s"), s);
80
- const n = E(r), { openTags: o, closeTags: i } = A(O(e));
79
+ const n = E(r), { openTags: o, closeTags: i } = A(h(e));
81
80
  return !n && !o ? null : { pStyle: n || void 0, openTags: o, closeTags: i };
82
81
  }
83
82
  function H(t) {
84
- const e = t.querySelector(".es-button-border"), r = t.querySelector("a.es-button") ?? t.querySelector("a"), n = S(e, D), o = S(r, w), i = e && "getAttribute" in e ? e.getAttribute("class") ?? "" : "", u = /\bes-fw\b/.test(i), { openTags: T, closeTags: d } = A(O(r)), m = K(r);
83
+ const e = t.querySelector(".es-button-border"), r = t.querySelector("a.es-button") ?? t.querySelector("a"), n = S(e, D), o = S(r, w), i = e && "getAttribute" in e ? e.getAttribute("class") ?? "" : "", u = /\bes-fw\b/.test(i), { openTags: T, closeTags: d } = A(h(r)), m = K(r);
85
84
  return !n && !o && !u && !T && !m ? null : {
86
85
  buttonBorderStyle: n || void 0,
87
86
  buttonAnchorStyle: o || void 0,
@@ -101,7 +100,7 @@ function j(t, e) {
101
100
  function f(t, e) {
102
101
  if (!t || !("querySelector" in t))
103
102
  return;
104
- const r = t.querySelector(g) ?? t;
103
+ const r = t.querySelector(b) ?? t;
105
104
  if (L.forEach(({ attrKey: i, blockId: u, kind: T }) => {
106
105
  const d = r.querySelector(`[esd-extension-block-id="${u}"]`);
107
106
  d && e(d, i, T);
@@ -127,20 +126,20 @@ function V(t) {
127
126
  function X(t) {
128
127
  if (!t || !("querySelector" in t))
129
128
  return;
130
- const e = t.querySelector(g) ?? t, r = e.querySelector(".product-card-segment") ?? e.querySelector(".product-card-wrapper");
129
+ const e = t.querySelector(b) ?? t, r = e.querySelector(".product-card-segment") ?? e.querySelector(".product-card-wrapper");
131
130
  return P(r);
132
131
  }
133
132
  function z(t) {
134
133
  if (!t)
135
134
  return;
136
135
  const e = l(t) ? t.getAttribute("bgcolor") : null;
137
- if (e && !b.has(e))
136
+ if (e && !g.has(e))
138
137
  return e;
139
138
  const r = P(t);
140
139
  if (r)
141
140
  return r;
142
141
  const n = M(t) ? t.getComputedStyle("background-color") : void 0;
143
- return n && !b.has(n) ? n : void 0;
142
+ return n && !g.has(n) ? n : void 0;
144
143
  }
145
144
  function Q(t) {
146
145
  const e = {};
@@ -171,7 +170,7 @@ function J(t) {
171
170
  function Z(t) {
172
171
  if (!t || !("querySelector" in t))
173
172
  return !1;
174
- const e = t.querySelector(g) ?? t;
173
+ const e = t.querySelector(b) ?? t;
175
174
  return C(e.querySelector(`[data-attribute-type="${y}"]`)) || C(e.querySelector(`[data-attribute-type="${p}"]`));
176
175
  }
177
176
  function tt(t) {
@@ -196,7 +195,7 @@ function rt(t) {
196
195
  const e = {};
197
196
  if (!t || !("querySelector" in t))
198
197
  return e;
199
- const r = t.querySelector(g) ?? t;
198
+ const r = t.querySelector(b) ?? t;
200
199
  return I(r) && r.querySelectorAll(".recommendation-attribute-row").forEach((n) => {
201
200
  if (!l(n))
202
201
  return;
@@ -1,43 +1,64 @@
1
- import { useRecommendationExtensionStore as g } from "../store/recommendation.js";
2
- import { refreshBlockOutsidePanel as y } from "./blockRefresh.js";
3
- import { toBlockUrlConfig as a } from "./blockUrlConfig.js";
4
- import { commitBlockChangeOutsidePanel as l, readBlockNodeConfigs as S } from "./nodeConfigWriter.js";
5
- function d(e, t) {
6
- const r = JSON.stringify(a(t));
7
- return S(e).find((o) => JSON.stringify(a(o)) !== r) ?? t;
1
+ import { useRecommendationExtensionStore as f } from "../store/recommendation.js";
2
+ import { refreshBlockOutsidePanel as l } from "./blockRefresh.js";
3
+ import { toBlockUrlConfig as c } from "./blockUrlConfig.js";
4
+ import { readBlockNodeConfigs as m, commitBlockChangeOutsidePanel as d } from "./nodeConfigWriter.js";
5
+ function u(n, t) {
6
+ const r = JSON.stringify(c(t));
7
+ return m(n).find((s) => JSON.stringify(c(s)) !== r) ?? t;
8
8
  }
9
- async function p(e, t, r) {
10
- const o = g(), s = [e, t];
11
- (/* @__PURE__ */ new Map([[e, d(e, r)], [t, r]])).forEach((n, i) => {
12
- var m;
13
- (!!n.strategyId || i === t) && ((m = o.blockStates[i]) == null ? void 0 : m.recommendationConfigs.strategyId) !== n.strategyId && o.seedBlockUrlConfig(i, a(n));
14
- }), o.resetArrivedBlock(t), await Promise.all(s.map(async (n) => {
15
- if (!await o.refreshStrategyBlock(n))
9
+ async function y(n, t, r = () => !0) {
10
+ const s = f();
11
+ await Promise.all(n.map(async (e) => {
12
+ if (!await s.refreshStrategyBlock(e))
16
13
  return;
17
- const { recommendationConfigs: i, recommendationProducts: f } = o.blockStates[n];
18
- l(
19
- n,
20
- { size: i.size },
21
- f,
22
- "Refresh duplicated recommendation strategy"
14
+ const { recommendationConfigs: a, recommendationProducts: o } = s.blockStates[e];
15
+ r(e, a.size) && d(
16
+ e,
17
+ { size: a.size },
18
+ o,
19
+ t
23
20
  );
24
21
  }));
25
22
  }
26
- async function k(e, t) {
27
- if (!g().blockStates[e])
23
+ async function w(n, t, r) {
24
+ const s = f(), e = [n, t];
25
+ (/* @__PURE__ */ new Map([[n, u(n, r)], [t, r]])).forEach((o, i) => {
26
+ var g;
27
+ (!!o.strategyId || i === t) && ((g = s.blockStates[i]) == null ? void 0 : g.recommendationConfigs.strategyId) !== o.strategyId && s.seedBlockUrlConfig(i, c(o));
28
+ }), s.resetArrivedBlock(t), await y(e, "Refresh duplicated recommendation strategy");
29
+ }
30
+ async function k(n) {
31
+ const t = f(), r = n.filter(({ config: e }) => !!e.strategyId);
32
+ if (!r.length)
33
+ return;
34
+ r.forEach(({ id: e, config: a }) => t.seedBlockUrlConfig(e, c(a))), t.invalidateStrategies();
35
+ const s = new Map(r.map(({ id: e, config: a }) => [e, a]));
36
+ await y(
37
+ r.map(({ id: e }) => e),
38
+ "Refresh recommendation strategy",
39
+ (e, a) => {
40
+ const o = s.get(e);
41
+ return a !== (o == null ? void 0 : o.size) && m(e).some((i) => i.strategyId === (o == null ? void 0 : o.strategyId));
42
+ }
43
+ );
44
+ }
45
+ async function O(n, t) {
46
+ if (!f().blockStates[n])
28
47
  return !1;
29
- const r = await y(e, {
30
- pickUpdates: ({ strategyId: o, strategy: s, size: c, nodeConfigVersion: n }) => ({
31
- strategyId: o,
32
- strategy: s,
33
- size: c,
34
- configVersion: n
48
+ const r = await l(n, {
49
+ pickUpdates: ({ strategyId: s, strategy: e, size: a, nodeConfigVersion: o }) => ({
50
+ strategyId: s,
51
+ strategy: e,
52
+ size: a,
53
+ configVersion: o
35
54
  }),
36
55
  description: t
37
56
  });
38
- return r || console.error("[recommendation] strategy change did not reach a node", { blockId: e }), r;
57
+ return r || console.error("[recommendation] strategy change did not reach a node", { blockId: n }), r;
39
58
  }
40
59
  export {
41
- k as commitStrategyChange,
42
- p as refreshDuplicatedStrategyBlocks
60
+ O as commitStrategyChange,
61
+ k as refreshArrivedStrategyBlocks,
62
+ w as refreshDuplicatedStrategyBlocks,
63
+ u as resolveSourceConfig
43
64
  };
package/dist/guido.css CHANGED
@@ -1 +1 @@
1
- @charset "UTF-8";.auth-error-modal[data-v-b4d7ae51]{position:relative;z-index:145}.gap-16[data-v-5553d071],.gap-16[data-v-0e1b0c54]{gap:16px}[data-v-b8f24f34] .in-button-v2__wrapper{line-height:0}[data-v-22226124] .in-segments-wrapper__button_selected,[data-v-22226124] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb;color:#0010ac;border-color:#0010ac}[data-v-2cb418af] .in-progress-wrapper__progress p span:last-child{display:none!important}[data-v-2cb418af] .in-progress-description-status{display:none!important}.view-options-wrapper[data-v-87033101]{position:relative;display:inline-block}.new-tag[data-v-87033101]{position:absolute;top:-8px;right:-16px;z-index:10}[data-v-87033101] .guido__view-option-selection-desktop svg,[data-v-87033101] .guido__view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-87033101] .in-segments-wrapper__button_selected,[data-v-87033101] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}[data-v-87033101] .in-tooltip-wrapper-v2__icon{cursor:pointer}.editor-toolbar[data-v-173c3a40]{gap:4px}.version-history-item[data-v-ee4b9c3f]{flex-basis:200px}.version-history[data-v-fad98586]{gap:8px}.version-history__toolbar[data-v-fad98586]{gap:4px}.view-options-wrapper[data-v-6ebabfe4]{position:relative;display:inline-block}.new-tag[data-v-6ebabfe4]{position:absolute;top:-8px;right:-16px;z-index:10}[data-v-6ebabfe4] .guido__verion-history-view-option-selection-desktop svg,[data-v-6ebabfe4] .guido__verion-history-view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-6ebabfe4] .in-segments-wrapper__button_selected,[data-v-6ebabfe4] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}[data-v-6ebabfe4] .in-tooltip-wrapper-v2__icon{cursor:pointer}.auto-save-toggle[data-v-2c964af4]{position:relative}.auto-save-toggle__info-box[data-v-2c964af4]{position:absolute;top:100%;left:0;z-index:10;width:280px}.editor-actions[data-v-baf7a5dd]{gap:4px}.header-wrapper[data-v-d11dd577]{min-width:1000px}.guido-loading__wrapper[data-v-07c4b2d8]{height:100%;top:75px!important;bottom:0!important}.validation-error-list[data-v-e48cebe9]{gap:16px}.validation-error-row[data-v-e48cebe9]{gap:8px;padding:24px;border:1px solid #E1E1E1;border-radius:8px}.validation-error-row__icon[data-v-e48cebe9]{flex-shrink:0;font-size:24px;line-height:0}.validation-error-row__text[data-v-e48cebe9]{font-size:13px;line-height:16px;color:#292929;word-break:break-word}.guido-editor__wrapper[data-v-c5146fc5]{--ribbon-offset: 0px;position:relative;width:100%;height:calc(100vh - 128px - var(--ribbon-offset))}.guido-editor__container[data-v-c5146fc5]{width:100%;height:calc(100vh - 128px - var(--ribbon-offset))}.guido-editor__no-header[data-v-c5146fc5]{height:calc(100vh - 75px - var(--ribbon-offset))}[data-v-293f1c47] .in-breadcrumb-wrapper__links{cursor:pointer}.templates-wrapper[data-v-91a26acd]{gap:16px;grid-template-columns:repeat(3,1fr)}.templates-wrapper .template-wrapper[data-v-91a26acd]{cursor:pointer}.templates-wrapper .template-wrapper .template-container[data-v-91a26acd]{height:274px;padding:2px;transition:none}.templates-wrapper .template-wrapper .template-container.selected[data-v-91a26acd]{padding:1px}.templates-wrapper .template-wrapper .template-container .thumbnail[data-v-91a26acd]{object-fit:cover;transform:scale(1)}[data-v-b9a93c6e] .guido__verion-history-view-option-selection-desktop svg,[data-v-b9a93c6e] .guido__verion-history-view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-b9a93c6e] .in-segments-wrapper__button_selected,[data-v-b9a93c6e] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}.error-list[data-v-c3fd5d4b]{gap:16px}.desktop-browser-header[data-v-d86c5af5]{height:79px;min-height:79px}.desktop-browser-header__left[data-v-d86c5af5]{-webkit-user-drag:none;height:79px;width:378px}.desktop-browser-header__center[data-v-d86c5af5]{height:79px;background-repeat:repeat-x;background-size:auto 100%;background-position:left top}.desktop-browser-header__right[data-v-d86c5af5]{-webkit-user-drag:none;height:79px;width:112px}.desktop-preview[data-v-cf946232]{min-width:602px;height:70vh;min-height:583px;border-radius:10px}.desktop-preview iframe[data-v-cf946232]{min-height:504px}.iframe-wrapper[data-v-f255b2bb]{width:258px}.iframe-scaled[data-v-f255b2bb]{width:320px;height:124.0310077519%;transform:scale(.80625);transform-origin:top left}.cropped-text[data-v-eb3d05d7]{width:220px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.mobile-preview-wrapper__phone[data-v-3f472f96]{width:282px}.mobile-preview-wrapper__phone img[data-v-3f472f96]{object-fit:cover;border-radius:44px}.mobile-preview-wrapper__content[data-v-3f472f96]{width:258px;height:450px;left:12px}[data-v-6bcaca8a] .vueperslides__parallax-wrapper{padding-bottom:110px!important}[data-v-f16f20f8] .vueperslides__bullets{pointer-events:none!important}[data-v-f16f20f8] .vueperslides__parallax-wrapper{padding-bottom:110px!important}[data-v-bb3cca55] .vueperslides__bullets{pointer-events:none!important}[data-v-bb3cca55] .vueperslides__parallax-wrapper{height:110px!important;padding-bottom:110px!important}[data-v-19d8cb42] .vueperslides__bullets,[data-v-ec2027ff] .vueperslides__bullets,[data-v-b09e80c4] .vueperslides__bullets{pointer-events:none!important}[data-v-b09e80c4] .vueperslides__parallax-wrapper{height:110px!important;padding-bottom:110px!important}[data-v-9bdef600] .vueperslides__parallax-wrapper{padding-bottom:110px!important}.assign-strategy-drawer-content .assign-strategy-select[data-v-6ce48dfd]{width:100%;max-width:none}.assign-strategy-drawer-content .assign-strategy-select[data-v-6ce48dfd] .in-skeleton{width:100%!important}.assign-strategy-drawer-content .assign-strategy-select[data-v-6ce48dfd] .in-dropdown-box__container{width:413px}.assign-strategy-drawer .spaced-dot-sep{background-image:linear-gradient(90deg,#91949f 20%,#fff0 0);background-position:center bottom;background-repeat:repeat-x;background-size:5px 1px}.assign-strategy-drawer .spaced-dot-sep--top{background-position:center top}.assign-strategy-drawer .spaced-dot-sep--fc-n:first-child{background:none}.legacy-strategy-updated-modal[data-v-da2225a1]{position:relative;z-index:145}
1
+ @charset "UTF-8";.auth-error-modal[data-v-b4d7ae51]{position:relative;z-index:145}.gap-16[data-v-5553d071],.gap-16[data-v-0e1b0c54]{gap:16px}[data-v-b8f24f34] .in-button-v2__wrapper{line-height:0}[data-v-22226124] .in-segments-wrapper__button_selected,[data-v-22226124] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb;color:#0010ac;border-color:#0010ac}[data-v-2cb418af] .in-progress-wrapper__progress p span:last-child{display:none!important}[data-v-2cb418af] .in-progress-description-status{display:none!important}.view-options-wrapper[data-v-87033101]{position:relative;display:inline-block}.new-tag[data-v-87033101]{position:absolute;top:-8px;right:-16px;z-index:10}[data-v-87033101] .guido__view-option-selection-desktop svg,[data-v-87033101] .guido__view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-87033101] .in-segments-wrapper__button_selected,[data-v-87033101] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}[data-v-87033101] .in-tooltip-wrapper-v2__icon{cursor:pointer}.editor-toolbar[data-v-173c3a40]{gap:4px}.version-history-item[data-v-ee4b9c3f]{flex-basis:200px}.version-history[data-v-fad98586]{gap:8px}.version-history__toolbar[data-v-fad98586]{gap:4px}.view-options-wrapper[data-v-6ebabfe4]{position:relative;display:inline-block}.new-tag[data-v-6ebabfe4]{position:absolute;top:-8px;right:-16px;z-index:10}[data-v-6ebabfe4] .guido__verion-history-view-option-selection-desktop svg,[data-v-6ebabfe4] .guido__verion-history-view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-6ebabfe4] .in-segments-wrapper__button_selected,[data-v-6ebabfe4] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}[data-v-6ebabfe4] .in-tooltip-wrapper-v2__icon{cursor:pointer}.auto-save-toggle[data-v-2c964af4]{position:relative}.auto-save-toggle__info-box[data-v-2c964af4]{position:absolute;top:100%;left:0;z-index:10;width:280px}.editor-actions[data-v-baf7a5dd]{gap:4px}.header-wrapper[data-v-d11dd577]{min-width:1000px}.guido-loading__wrapper[data-v-07c4b2d8]{height:100%;top:75px!important;bottom:0!important}.validation-error-list[data-v-e48cebe9]{gap:16px}.validation-error-row[data-v-e48cebe9]{gap:8px;padding:24px;border:1px solid #E1E1E1;border-radius:8px}.validation-error-row__icon[data-v-e48cebe9]{flex-shrink:0;font-size:24px;line-height:0}.validation-error-row__text[data-v-e48cebe9]{font-size:13px;line-height:16px;color:#292929;word-break:break-word}.guido-editor__wrapper[data-v-1a3ddd48]{--ribbon-offset: 0px;position:relative;width:100%;height:calc(100vh - 128px - var(--ribbon-offset))}.guido-editor__container[data-v-1a3ddd48]{width:100%;height:calc(100vh - 128px - var(--ribbon-offset))}.guido-editor__no-header[data-v-1a3ddd48]{height:calc(100vh - 75px - var(--ribbon-offset))}[data-v-293f1c47] .in-breadcrumb-wrapper__links{cursor:pointer}.templates-wrapper[data-v-91a26acd]{gap:16px;grid-template-columns:repeat(3,1fr)}.templates-wrapper .template-wrapper[data-v-91a26acd]{cursor:pointer}.templates-wrapper .template-wrapper .template-container[data-v-91a26acd]{height:274px;padding:2px;transition:none}.templates-wrapper .template-wrapper .template-container.selected[data-v-91a26acd]{padding:1px}.templates-wrapper .template-wrapper .template-container .thumbnail[data-v-91a26acd]{object-fit:cover;transform:scale(1)}[data-v-b9a93c6e] .guido__verion-history-view-option-selection-desktop svg,[data-v-b9a93c6e] .guido__verion-history-view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-b9a93c6e] .in-segments-wrapper__button_selected,[data-v-b9a93c6e] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}.error-list[data-v-c3fd5d4b]{gap:16px}.desktop-browser-header[data-v-d86c5af5]{height:79px;min-height:79px}.desktop-browser-header__left[data-v-d86c5af5]{-webkit-user-drag:none;height:79px;width:378px}.desktop-browser-header__center[data-v-d86c5af5]{height:79px;background-repeat:repeat-x;background-size:auto 100%;background-position:left top}.desktop-browser-header__right[data-v-d86c5af5]{-webkit-user-drag:none;height:79px;width:112px}.desktop-preview[data-v-cf946232]{min-width:602px;height:70vh;min-height:583px;border-radius:10px}.desktop-preview iframe[data-v-cf946232]{min-height:504px}.iframe-wrapper[data-v-f255b2bb]{width:258px}.iframe-scaled[data-v-f255b2bb]{width:320px;height:124.0310077519%;transform:scale(.80625);transform-origin:top left}.cropped-text[data-v-eb3d05d7]{width:220px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.mobile-preview-wrapper__phone[data-v-3f472f96]{width:282px}.mobile-preview-wrapper__phone img[data-v-3f472f96]{object-fit:cover;border-radius:44px}.mobile-preview-wrapper__content[data-v-3f472f96]{width:258px;height:450px;left:12px}[data-v-6bcaca8a] .vueperslides__parallax-wrapper{padding-bottom:110px!important}[data-v-f16f20f8] .vueperslides__bullets{pointer-events:none!important}[data-v-f16f20f8] .vueperslides__parallax-wrapper{padding-bottom:110px!important}[data-v-bb3cca55] .vueperslides__bullets{pointer-events:none!important}[data-v-bb3cca55] .vueperslides__parallax-wrapper{height:110px!important;padding-bottom:110px!important}[data-v-19d8cb42] .vueperslides__bullets,[data-v-ec2027ff] .vueperslides__bullets,[data-v-b09e80c4] .vueperslides__bullets{pointer-events:none!important}[data-v-b09e80c4] .vueperslides__parallax-wrapper{height:110px!important;padding-bottom:110px!important}[data-v-9bdef600] .vueperslides__parallax-wrapper{padding-bottom:110px!important}.assign-strategy-drawer-content .assign-strategy-select[data-v-6ce48dfd]{width:100%;max-width:none}.assign-strategy-drawer-content .assign-strategy-select[data-v-6ce48dfd] .in-skeleton{width:100%!important}.assign-strategy-drawer-content .assign-strategy-select[data-v-6ce48dfd] .in-dropdown-box__container{width:413px}.assign-strategy-drawer .spaced-dot-sep{background-image:linear-gradient(90deg,#91949f 20%,#fff0 0);background-position:center bottom;background-repeat:repeat-x;background-size:5px 1px}.assign-strategy-drawer .spaced-dot-sep--top{background-position:center top}.assign-strategy-drawer .spaced-dot-sep--fc-n:first-child{background:none}.legacy-strategy-updated-modal[data-v-da2225a1]{position:relative;z-index:145}
package/dist/library.js CHANGED
@@ -1,20 +1,22 @@
1
1
  import { default as a } from "./components/Guido.vue.js";
2
- import { MessageType as t, ProductType as d } from "./@types/config/schemas.js";
2
+ import { MessageType as t, ProductType as f } from "./@types/config/schemas.js";
3
3
  import "./@types/config/defaults.js";
4
- import { getValidationErrors as s, isValidConfig as p, parseConfig as g, parseConfigSafe as m, validateConfig as n } from "./@types/config/validator.js";
5
- import { assignTrackingIds as u, readTrackFloor as x, readTrackSeq as T } from "./utils/linkTrackingIds.js";
4
+ import { getValidationErrors as p, isValidConfig as s, parseConfig as m, parseConfigSafe as g, validateConfig as n } from "./@types/config/validator.js";
5
+ import { assignTrackingIds as l, readTrackFloor as x, readTrackSeq as c } from "./utils/linkTrackingIds.js";
6
6
  import { useGuidoEmailEditorStore as C } from "./stores/guido-email-editor.js";
7
+ import { prefetchGuidoRuntime as E } from "./utils/runtimePrefetch.js";
7
8
  export {
8
9
  a as Guido,
9
10
  t as MessageType,
10
- d as ProductType,
11
- u as assignTrackingIds,
12
- s as getValidationErrors,
13
- p as isValidConfig,
14
- g as parseConfig,
15
- m as parseConfigSafe,
11
+ f as ProductType,
12
+ l as assignTrackingIds,
13
+ p as getValidationErrors,
14
+ s as isValidConfig,
15
+ m as parseConfig,
16
+ g as parseConfigSafe,
17
+ E as prefetchGuidoRuntime,
16
18
  x as readTrackFloor,
17
- T as readTrackSeq,
19
+ c as readTrackSeq,
18
20
  C as useGuidoEmailEditorStore,
19
21
  n as validateConfig
20
22
  };
@@ -1,7 +1,9 @@
1
- const o = { stripo: { version: "2.79.0" } }, s = {
2
- guido: o
1
+ const o = "3.21.0-beta.8a9421f", s = { stripo: { version: "2.79.0" } }, t = {
2
+ version: o,
3
+ guido: s
3
4
  };
4
5
  export {
5
- s as default,
6
- o as guido
6
+ t as default,
7
+ s as guido,
8
+ o as version
7
9
  };
@@ -0,0 +1,4 @@
1
+ import { prefetchGuidoRuntime as r } from "../utils/runtimePrefetch.js";
2
+ export {
3
+ r as prefetchGuidoRuntime
4
+ };
@@ -0,0 +1,27 @@
1
+ export type TimedOpenPhase = 'migration' | 'default_template' | 'timer_clone';
2
+ export type OpenPhase = 'setup' | 'host_ready' | `${TimedOpenPhase}_start` | `${TimedOpenPhase}_end` | 'plugin_start' | 'script_ready' | 'fonts_sync_ready' | 'blocks_config_ready' | 'init_editor' | 'token_start' | 'token_end' | 'ready';
3
+ export type OpenOutcome = 'ready' | 'error' | 'abandoned';
4
+ export interface OpenContext {
5
+ partnerName: string;
6
+ productType: number;
7
+ templateId: string;
8
+ variationId: string;
9
+ }
10
+ export interface OpenTemplate {
11
+ html: string;
12
+ css: string;
13
+ forceRecreate: boolean;
14
+ }
15
+ export interface EditorOpenMetrics {
16
+ mark: (phase: OpenPhase) => void;
17
+ timed: <T>(phase: TimedOpenPhase, task: () => Promise<T>) => Promise<T>;
18
+ setContext: (context: OpenContext) => void;
19
+ setTemplate: (template: OpenTemplate) => void;
20
+ setScriptPreloaded: (preloaded: boolean) => void;
21
+ markReady: () => void;
22
+ markFailed: () => void;
23
+ dispose: () => void;
24
+ }
25
+ export declare const startEditorOpenMetrics: () => EditorOpenMetrics;
26
+ /** Binds to the session open at call time, so a remounted editor never writes into its replacement's session. */
27
+ export declare const useEditorOpenMetrics: () => EditorOpenMetrics;
@@ -19,6 +19,9 @@ export declare class RecommendationBlock extends Block {
19
19
  private _resetSourceIds;
20
20
  /** Ids handed to duplicates the document root does not show yet: a copied module renames all its blocks at once. */
21
21
  private _unsettledDuplicateIds;
22
+ private _arrivedBlocks;
23
+ /** Strategy each in-flight arrival or duplicate refresh is fetching, by block id, so a second one does not race it. */
24
+ private _refreshClaims;
22
25
  constructor();
23
26
  getId(): string;
24
27
  getIcon(): string;
@@ -44,6 +47,8 @@ export declare class RecommendationBlock extends Block {
44
47
  * @param node - The newly created block node
45
48
  */
46
49
  onCreated(node: ImmutableHtmlNode): void;
50
+ /** Refreshes every block of an opened template: Stripo restores a stored document without `onCreated`. */
51
+ onDocumentInit(): void;
47
52
  /**
48
53
  * Called when the document changes or template is loaded
49
54
  *
@@ -59,7 +64,6 @@ export declare class RecommendationBlock extends Block {
59
64
  * @param node - The block node being deleted
60
65
  */
61
66
  onDelete(node: ImmutableHtmlNode): void;
62
- private _ensureMobileFitRule;
63
67
  /**
64
68
  * Warns (dark advisory toaster) when the design holds more than one live
65
69
  * recommendation block. Triggered from the user-add paths only (fresh drop
@@ -86,15 +90,26 @@ export declare class RecommendationBlock extends Block {
86
90
  * the renamed one depending on where the module was dropped (SD-149916).
87
91
  */
88
92
  private _scheduleArrivalReset;
93
+ /**
94
+ * Re-reads the strategy of a block that arrived with saved cards, without waiting for a click.
95
+ * Blocks of one opened template or dropped module arrive in one tick and refresh together.
96
+ */
97
+ private _queueArrivalRefresh;
98
+ private _refreshArrivedBlocks;
99
+ /**
100
+ * A new document reports each block to onCreated and onDocumentInit, not always in one batch, so a
101
+ * claimed block refreshes again only once the document shows it under another strategy (a restored version).
102
+ */
103
+ private _canClaimRefresh;
104
+ private _releaseRefreshClaim;
89
105
  /**
90
106
  * Heals a duplicate that slipped past the create-time `_detectDuplicate`
91
107
  * scan (or that was persisted by an older template before SD-142352).
92
108
  * When two blocks share a `recommendation-id`, the first occurrence in DOM
93
109
  * order is treated as the source and any later sibling is reassigned a
94
- * fresh id. The store entry and active-block focus are intentionally not
95
- * touched here: each block's persisted `esd-ext-config` carries its own
96
- * truth and the regular save-time hydration (`hydrateRecommendationStore`)
97
- * will seed the new id from that. Skipping `setCurrentBlock` avoids
110
+ * fresh id and queued for the arrival refresh, which seeds the new id's
111
+ * store entry from its persisted `esd-ext-config`. The source's store
112
+ * entry is not cloned and focus is not moved. Skipping `setCurrentBlock` avoids
98
113
  * yanking the user's current selection mid-edit when the heal fires from
99
114
  * `onDocumentChanged`.
100
115
  */
@@ -110,9 +125,9 @@ export declare class RecommendationBlock extends Block {
110
125
  *
111
126
  * Used by `_handleDuplicate` at create-time (which additionally clones the
112
127
  * store entry and focuses the new block) and by `_healLingeringDuplicate`
113
- * at document-change time (which intentionally skips store/focus side
114
- * effects so older bug-affected templates can self-repair without
115
- * disturbing the user's current selection).
128
+ * at document-change time (which skips the clone and focus change so older
129
+ * bug-affected templates can self-repair without disturbing the user's
130
+ * current selection, and queues the arrival refresh for the new id).
116
131
  */
117
132
  private _reassignDuplicateId;
118
133
  /**
@@ -3,48 +3,35 @@
3
3
  *
4
4
  * Controls for styling the product image element in recommendation cards.
5
5
  */
6
- import type { CssNodeModifier, HtmlNodeModifier, ImmutableCssNode, ImmutableHtmlNode, TemplateModifier } from '@stripoinc/ui-editor-extensions';
7
- import { ModificationDescription } from '@stripoinc/ui-editor-extensions';
8
- interface FitRuleApi {
9
- getDocumentRootCssNode: () => ImmutableCssNode | null;
10
- getDocumentModifier: () => TemplateModifier<HtmlNodeModifier, CssNodeModifier>;
11
- }
12
- export declare function ensureMobileFitRule(api: FitRuleApi, block: ImmutableHtmlNode): void;
13
- declare const SizeControl_base: {
14
- new (): {
15
- getId(): string;
16
- getTargetNodes(root: ImmutableHtmlNode): ImmutableHtmlNode[];
17
- getParentControlId(): string;
18
- api: import("@stripoinc/ui-editor-extensions").ControlApi;
19
- getLabels(): import("@stripoinc/ui-editor-extensions").ControlLabels | undefined;
20
- getModificationDescription(): ModificationDescription | undefined;
21
- getAdditionalModifications(_root: ImmutableHtmlNode): TemplateModifier<HtmlNodeModifier, CssNodeModifier> | undefined;
22
- isVisible(_node: ImmutableHtmlNode): boolean;
23
- getElementLockCategory(): import("@stripoinc/ui-editor-extensions").ElementLockCategory | undefined;
24
- };
25
- };
26
- declare class SizeControl extends SizeControl_base {
27
- getAdditionalModifications(root: ImmutableHtmlNode): TemplateModifier<HtmlNodeModifier, CssNodeModifier> | undefined;
28
- private getFitStyles;
29
- }
30
6
  /**
31
7
  * Grouped Image Controls
32
8
  * Use this object for cleaner imports in extension.ts
33
9
  */
34
10
  export declare const ImageControls: {
35
- readonly size: typeof SizeControl;
11
+ readonly size: {
12
+ new (): {
13
+ getId(): string;
14
+ getTargetNodes(root: import("@stripoinc/ui-editor-extensions").ImmutableHtmlNode): import("@stripoinc/ui-editor-extensions").ImmutableHtmlNode[];
15
+ getParentControlId(): string;
16
+ api: import("@stripoinc/ui-editor-extensions").ControlApi;
17
+ getLabels(): import("@stripoinc/ui-editor-extensions").ControlLabels | undefined;
18
+ getModificationDescription(): import("@stripoinc/ui-editor-extensions").ModificationDescription | undefined;
19
+ getAdditionalModifications(_root: import("@stripoinc/ui-editor-extensions").ImmutableHtmlNode): import("@stripoinc/ui-editor-extensions").TemplateModifier<import("@stripoinc/ui-editor-extensions").HtmlNodeModifier, import("@stripoinc/ui-editor-extensions").CssNodeModifier> | undefined;
20
+ isVisible(_node: import("@stripoinc/ui-editor-extensions").ImmutableHtmlNode): boolean;
21
+ getElementLockCategory(): import("@stripoinc/ui-editor-extensions").ElementLockCategory | undefined;
22
+ };
23
+ };
36
24
  readonly margins: {
37
25
  new (): {
38
26
  getId(): string;
39
- getTargetNodes(root: ImmutableHtmlNode): ImmutableHtmlNode[];
27
+ getTargetNodes(root: import("@stripoinc/ui-editor-extensions").ImmutableHtmlNode): import("@stripoinc/ui-editor-extensions").ImmutableHtmlNode[];
40
28
  getParentControlId(): string;
41
29
  api: import("@stripoinc/ui-editor-extensions").ControlApi;
42
30
  getLabels(): import("@stripoinc/ui-editor-extensions").ControlLabels | undefined;
43
- getModificationDescription(): ModificationDescription | undefined;
44
- getAdditionalModifications(_root: ImmutableHtmlNode): TemplateModifier<HtmlNodeModifier, CssNodeModifier> | undefined;
45
- isVisible(_node: ImmutableHtmlNode): boolean;
31
+ getModificationDescription(): import("@stripoinc/ui-editor-extensions").ModificationDescription | undefined;
32
+ getAdditionalModifications(_root: import("@stripoinc/ui-editor-extensions").ImmutableHtmlNode): import("@stripoinc/ui-editor-extensions").TemplateModifier<import("@stripoinc/ui-editor-extensions").HtmlNodeModifier, import("@stripoinc/ui-editor-extensions").CssNodeModifier> | undefined;
33
+ isVisible(_node: import("@stripoinc/ui-editor-extensions").ImmutableHtmlNode): boolean;
46
34
  getElementLockCategory(): import("@stripoinc/ui-editor-extensions").ElementLockCategory | undefined;
47
35
  };
48
36
  };
49
37
  };
50
- export {};
@@ -1,10 +1,21 @@
1
1
  import type { RecommendationNodeConfig } from '../types/nodeConfig';
2
+ /** A saved module keeps the id it was saved with, so it can arrive sharing the id of an unrelated block. */
3
+ export declare function resolveSourceConfig(sourceId: number, arrived: RecommendationNodeConfig): RecommendationNodeConfig;
2
4
  /**
3
5
  * Re-reads the strategy of a duplicated block and its source and redraws both: the clone copies the
4
6
  * cards the source last drew, so a strategy edited since then only reached a block once selected (SD-153266).
5
7
  * @param config - the arriving block's persisted config; seeds either block its store entry does not match
6
8
  */
7
9
  export declare function refreshDuplicatedStrategyBlocks(sourceId: number, duplicateId: number, config: RecommendationNodeConfig): Promise<void>;
10
+ /**
11
+ * Re-reads the strategy of blocks that arrived from a saved template or module, so the panel and
12
+ * preview show a strategy edited since the design was saved without selecting the block.
13
+ * @param blocks - each block's id with its persisted config, the truth its store entry is seeded from
14
+ */
15
+ export declare function refreshArrivedStrategyBlocks(blocks: {
16
+ id: number;
17
+ config: RecommendationNodeConfig;
18
+ }[]): Promise<void>;
8
19
  /**
9
20
  * Writes a strategy change and its products straight to the document, without the settings panel.
10
21
  *
@@ -4,5 +4,6 @@ export { validateConfig, parseConfig, parseConfigSafe, isValidConfig, getValidat
4
4
  export { assignTrackingIds, readTrackFloor, readTrackSeq } from './public/trackingIds';
5
5
  export { useGuidoEmailEditorStore } from './public/editorState';
6
6
  export type { GuidoEmailEditorState } from './public/editorState';
7
+ export { prefetchGuidoRuntime } from './public/prefetchRuntime';
7
8
  export type { StripoEventType } from './@types/events';
8
9
  export type { PositionData, DynamicContentEvent, MergeTagClickEvent, MergeTag, BaseDynamicContent, DynamicContentNode, DynamicContentList, TooltipOptions, TextValueObject, L10n, } from './@types/generic';
@@ -0,0 +1 @@
1
+ export { prefetchGuidoRuntime } from '../utils/runtimePrefetch';
@@ -0,0 +1,4 @@
1
+ export type RuntimePrefetchState = 'none' | 'pending' | 'done';
2
+ export declare const RUNTIME_PREFETCH_ATTRIBUTE = "data-guido-prefetch";
3
+ export declare const prefetchGuidoRuntime: () => void;
4
+ export declare const readRuntimePrefetchState: () => RuntimePrefetchState;
@@ -0,0 +1,2 @@
1
+ /** Null when package.json does not pin `guido.stripo.version`. */
2
+ export declare const getStripoRuntimeBaseUrl: () => string | null;
@@ -0,0 +1,9 @@
1
+ const s = "2.79.0", n = ["UIEditor.js", "zone.js", "styles-BWH3PMR4.css", "polyfills-FF3RLU5F.js", "main-MFU2R4FE.js", "chunk-2PIEA5YN.js", "chunk-5FVAINMG.js", "chunk-67OKDPNA.js", "chunk-BEE4NTMB.js", "chunk-FXMA33WF.js", "chunk-HEM7M3GC.js", "chunk-IP346EOD.js", "chunk-J3Q2HMUE.js", "chunk-JER72PP5.js", "chunk-LXRTAID3.js", "chunk-MV5VZJ34.js", "chunk-RTXKBDZV.js", "chunk-UQMM7Q74.js", "chunk-WCDYHSTN.js", "assets/css/uiEditor.css", "assets/i18n/en.json", "assets/icons/ui-editor-icons.sprite.svg", "assets/icons/ui-editor-icons.map.json", "assets/imageeditor/scripts.min.js", "assets/imageeditor/assets/icons/merged.svg"], c = {
2
+ version: s,
3
+ files: n
4
+ };
5
+ export {
6
+ c as default,
7
+ n as files,
8
+ s as version
9
+ };
@@ -0,0 +1,26 @@
1
+ import s from "../static/stripo-runtime-manifest.json.js";
2
+ import { getStripoRuntimeBaseUrl as c } from "./stripoRuntime.js";
3
+ const r = "data-guido-prefetch", d = "pending", o = "settled", i = `link[${r}]`, u = ["slow-2g", "2g"], l = /\.(?:js|json)$/, a = () => document.getElementById("UiEditorScript") !== null || window.UIEditor !== void 0, E = () => {
4
+ const { connection: e } = navigator;
5
+ return (e == null ? void 0 : e.saveData) === !0 || u.includes((e == null ? void 0 : e.effectiveType) ?? "");
6
+ }, m = (e) => {
7
+ const t = document.createElement("link"), n = () => t.setAttribute(r, o);
8
+ t.rel = "prefetch", t.href = e, l.test(e) && t.setAttribute("crossorigin", "anonymous"), t.setAttribute(r, d), t.addEventListener("load", n, { once: !0 }), t.addEventListener("error", n, { once: !0 }), document.head.appendChild(t);
9
+ }, T = () => {
10
+ try {
11
+ const e = c(), t = document.querySelector(i) !== null;
12
+ if (!e || t || a() || E())
13
+ return;
14
+ s.files.forEach((n) => m(`${e}${n}`));
15
+ } catch (e) {
16
+ console.debug("guido: runtime prefetch skipped", e);
17
+ }
18
+ }, g = () => {
19
+ const e = Array.from(document.querySelectorAll(i));
20
+ return e.length ? e.every((t) => t.getAttribute(r) === o) ? "done" : "pending" : "none";
21
+ };
22
+ export {
23
+ r as RUNTIME_PREFETCH_ATTRIBUTE,
24
+ T as prefetchGuidoRuntime,
25
+ g as readRuntimePrefetchState
26
+ };
@@ -0,0 +1,9 @@
1
+ import r from "../package.json.js";
2
+ const e = "https://email-static.useinsider.com/guido/", n = () => {
3
+ var s;
4
+ const t = r.guido, o = (s = t == null ? void 0 : t.stripo) == null ? void 0 : s.version;
5
+ return o ? `${e}${o}/` : null;
6
+ };
7
+ export {
8
+ n as getStripoRuntimeBaseUrl
9
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@useinsider/guido",
3
- "version": "3.21.0-beta.78e343a",
3
+ "version": "3.21.0-beta.8a9421f",
4
4
  "description": "Guido is a Vue + TypeScript wrapper for Email Plugin. Easily embed the email editor in your Vue applications.",
5
5
  "main": "./dist/guido.umd.cjs",
6
6
  "module": "./dist/library.js",
@@ -22,6 +22,10 @@
22
22
  "types": "./dist/src/public/editorState.d.ts",
23
23
  "import": "./dist/public/editorState.js"
24
24
  },
25
+ "./prefetch": {
26
+ "types": "./dist/src/public/prefetchRuntime.d.ts",
27
+ "import": "./dist/public/prefetchRuntime.js"
28
+ },
25
29
  "./style": "./dist/guido.css"
26
30
  },
27
31
  "scripts": {
@@ -45,6 +49,7 @@
45
49
  "coverage:e2e:report": "nyc report --reporter=lcov --reporter=text-summary --report-dir=coverage/e2e",
46
50
  "test:mutation": "stryker run",
47
51
  "test:mutation:since": "CHANGED=$(git diff --name-only --diff-filter=AMR origin/develop...HEAD -- 'src/**/*.ts' ':(glob)src/components/organisms/onboarding/**/*.vue' ':(glob)src/components/organisms/header/**/*.vue' ':(glob)src/components/organisms/unsubscribe/**/*.vue' ':(glob)src/components/organisms/save-as-template/**/*.vue' ':(glob)src/components/organisms/email-preview/**/*.vue' ':(glob)src/components/wrappers/**/*.vue' 'src/components/Guido.vue' ':(exclude)src/**/*.test.ts' ':(exclude)src/**/index.ts' ':(exclude)src/@types/**' ':(exclude)src/enums/**' ':(exclude)src/mock/**' ':(exclude)src/**/_Boilerplate/**' | paste -sd, -); if [ -n \"$CHANGED\" ]; then stryker run --incremental --mutate \"$CHANGED\"; else echo \"No changed mutatable src files vs origin/develop\"; fi",
52
+ "stripo:manifest": "node scripts/stripo-runtime-manifest.mjs",
48
53
  "prepare": "husky",
49
54
  "preinstall": "rm -rf ./node_modules/.vite"
50
55
  },