@useinsider/guido 3.20.0-beta.12889e0 → 3.20.0-beta.13006ea

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,11 +1,11 @@
1
- import { pairProductVariables as o } from "../../utils/pairProductVariables.js";
2
- import { wrapHiddenPriceTdsForOutlook as r, MSO_ITEMS_HIDE_START as e, MSO_ITEMS_HIDE_END as t } from "./utils/itemsCompilerUtils.js";
3
- const a = [
1
+ import { pairProductVariables as i } from "../../utils/pairProductVariables.js";
2
+ import { wrapHiddenPriceTdsForOutlook as r, lockHorizontalItemImageWidths as t, MSO_ITEMS_HIDE_START as e, MSO_ITEMS_HIDE_END as s } from "./utils/itemsCompilerUtils.js";
3
+ const c = [
4
4
  {
5
5
  id: "pair-product-variables",
6
6
  description: "Replace product default values with template variables",
7
7
  type: "custom",
8
- processor: o,
8
+ processor: i,
9
9
  priority: 60
10
10
  // After recommendation rules (priority 50-53)
11
11
  },
@@ -20,16 +20,23 @@ const a = [
20
20
  priority: 65
21
21
  // After pair-product-variables (60), before outlook rules (70+)
22
22
  },
23
+ {
24
+ id: "lock-horizontal-item-image-widths",
25
+ description: "Pin horizontal Items thumbnails to their width so narrow rows cannot collapse them",
26
+ type: "custom",
27
+ processor: t,
28
+ priority: 66
29
+ },
23
30
  {
24
31
  id: "swap-items-mso-markers",
25
32
  // Injecting the delicate `<!-- -->` ghost token LAST (after reco minify P99
26
33
  // and reco swap P100) keeps it out of every whitespace/comment-mangling pass.
27
34
  description: "Swap Items MSO markers into [if !mso] conditional comments",
28
35
  type: "custom",
29
- processor: (i) => i.replaceAll(`<!--${e}-->`, "<!--[if !mso]><!-- -->").replaceAll(`<!--${t}-->`, "<!--<![endif]-->"),
36
+ processor: (o) => o.replaceAll(`<!--${e}-->`, "<!--[if !mso]><!-- -->").replaceAll(`<!--${s}-->`, "<!--<![endif]-->"),
30
37
  priority: 101
31
38
  }
32
39
  ];
33
40
  export {
34
- a as itemsCompilerRules
41
+ c as itemsCompilerRules
35
42
  };
@@ -1,28 +1,45 @@
1
- const p = "MSO_ITEMS_HIDE_START", E = "MSO_ITEMS_HIDE_END", u = "mso-hide:all; max-height:0; overflow:hidden; font-size:0; line-height:0;", _ = ".ins-product-cart td.horizontal-price, .ins-product-cart td.vertical-price";
2
- function T(t) {
1
+ import { DefaultConfigValues as m } from "../../../extensions/Blocks/Items/enums/settingsEnums.js";
2
+ const u = "MSO_ITEMS_HIDE_START", f = "MSO_ITEMS_HIDE_END", _ = "mso-hide:all; max-height:0; overflow:hidden; font-size:0; line-height:0;", T = ".ins-product-cart td.horizontal-price, .ins-product-cart td.vertical-price", A = ".ins-product-td td.product-image-class img[width]", I = Number(m.productImageWidth), p = (t) => t.replaceAll("{%", "<!--{%").replaceAll("%}", "%}-->");
3
+ function E(t, n) {
4
+ const r = t.match(/<!DOCTYPE[^>]*>/i);
5
+ return ((r ? `${r[0]}
6
+ ` : "") + n.documentElement.outerHTML).replaceAll("<!--{%", "{%").replaceAll("%}-->", "%}").replaceAll("&lt;!--{%", "{%").replaceAll("%}--&gt;", "%}");
7
+ }
8
+ function h(t) {
3
9
  if (!t.includes("vertical-price") || !t.includes("ins-product-cart"))
4
10
  return t;
5
- const i = t.replaceAll("{%", "<!--{%").replaceAll("%}", "%}-->"), r = new DOMParser().parseFromString(i, "text/html");
6
- let n = !1;
7
- if (r.querySelectorAll(_).forEach((e) => {
8
- var s, a;
11
+ const n = p(t), r = new DOMParser().parseFromString(n, "text/html");
12
+ let c = !1;
13
+ return r.querySelectorAll(T).forEach((e) => {
14
+ var s, l;
9
15
  const o = e.getAttribute("style") || "";
10
16
  if (!/display\s*:\s*none/i.test(o))
11
17
  return;
12
- const c = e.previousSibling;
13
- if (((c == null ? void 0 : c.nodeType) !== Node.COMMENT_NODE || c.data !== p) && ((s = e.parentNode) == null || s.insertBefore(r.createComment(p), e), (a = e.parentNode) == null || a.insertBefore(r.createComment(E), e.nextSibling)), !/mso-hide/i.test(o)) {
18
+ const i = e.previousSibling;
19
+ if (((i == null ? void 0 : i.nodeType) !== Node.COMMENT_NODE || i.data !== u) && ((s = e.parentNode) == null || s.insertBefore(r.createComment(u), e), (l = e.parentNode) == null || l.insertBefore(r.createComment(f), e.nextSibling)), !/mso-hide/i.test(o)) {
14
20
  const d = o.trim().endsWith(";") ? " " : "; ";
15
- e.setAttribute("style", `${o}${d}${u}`);
21
+ e.setAttribute("style", `${o}${d}${_}`);
16
22
  }
17
- n = !0;
18
- }), !n)
23
+ c = !0;
24
+ }), c ? E(n, r) : t;
25
+ }
26
+ function D(t) {
27
+ if (!t.includes("product-image-class"))
19
28
  return t;
20
- const l = i.match(/<!DOCTYPE[^>]*>/i);
21
- return ((l ? `${l[0]}
22
- ` : "") + r.documentElement.outerHTML).replaceAll("<!--{%", "{%").replaceAll("%}-->", "%}").replaceAll("&lt;!--{%", "{%").replaceAll("%}--&gt;", "%}");
29
+ const n = p(t), r = new DOMParser().parseFromString(n, "text/html");
30
+ let c = !1;
31
+ return r.querySelectorAll(A).forEach((e) => {
32
+ var d, a;
33
+ const o = ((d = e.getAttribute("width")) == null ? void 0 : d.trim()) ?? "", i = ((a = e.getAttribute("style")) == null ? void 0 : a.trim()) ?? "";
34
+ if (!/^\d+$/.test(o) || /(^|;)\s*min-width\s*:/i.test(i))
35
+ return;
36
+ const s = i && !i.endsWith(";") ? ";" : "", l = Math.min(Number(o), I);
37
+ e.setAttribute("style", `${i}${s}min-width:${l}px;max-width:${o}px`), c = !0;
38
+ }), c ? E(n, r) : t;
23
39
  }
24
40
  export {
25
- E as MSO_ITEMS_HIDE_END,
26
- p as MSO_ITEMS_HIDE_START,
27
- T as wrapHiddenPriceTdsForOutlook
41
+ f as MSO_ITEMS_HIDE_END,
42
+ u as MSO_ITEMS_HIDE_START,
43
+ D as lockHorizontalItemImageWidths,
44
+ h as wrapHiddenPriceTdsForOutlook
28
45
  };
@@ -1,10 +1,9 @@
1
- import { useConfig as O } from "../../../composables/useConfig.js";
2
- import { useRecommendation as q } from "../../../composables/useRecommendation.js";
3
- import { MOBILE_ROW_SELECTOR as L, MOBILE_CONTAINER_SELECTOR as M, CSS_CLASS_RECO_BUTTON as P } from "../../../extensions/Blocks/Recommendation/constants/selectors.js";
4
- import { useRecommendationExtensionStore as R } from "../../../extensions/Blocks/Recommendation/store/recommendation.js";
5
- import { FLUID_IMAGE_MOBILE_RULE as T, getFluidImageStyleChanges as B } from "../../../utils/fluidImageStyle.js";
6
- import { isIgnoredRecommendationBlock as N } from "./recommendationIgnoreUtils.js";
7
- function D(t, r, e, o, c = "") {
1
+ import { useConfig as g } from "../../../composables/useConfig.js";
2
+ import { useRecommendation as O } from "../../../composables/useRecommendation.js";
3
+ import { MOBILE_ROW_SELECTOR as q, MOBILE_CONTAINER_SELECTOR as M, CSS_CLASS_RECO_BUTTON as B } from "../../../extensions/Blocks/Recommendation/constants/selectors.js";
4
+ import { useRecommendationExtensionStore as N } from "../../../extensions/Blocks/Recommendation/store/recommendation.js";
5
+ import { isIgnoredRecommendationBlock as T } from "./recommendationIgnoreUtils.js";
6
+ function L(t, r, e, o, c = "") {
8
7
  const i = `{{${c}${t}_${r}_${e}}}`, n = `{{${c}${t}_${r}_currency}}`;
9
8
  return o === "before" ? `${n} ${i}` : `${i} ${n}`;
10
9
  }
@@ -14,13 +13,13 @@ function _(t) {
14
13
  [r] = r.children;
15
14
  return r;
16
15
  }
17
- function E(t, r, e, o, c, i) {
16
+ function A(t, r, e, o, c, i) {
18
17
  switch (r) {
19
18
  case "productImage": {
20
19
  const n = t.querySelector("img");
21
20
  n && (n.setAttribute("src", `{{${i}${e}_${o}_image_url}}`), n.setAttribute("alt", `{{${i}${e}_${o}_name}}`));
22
21
  const s = t.querySelector("a");
23
- s && (s.setAttribute("href", `{{${i}${e}_${o}_url}}`), s.classList.add(P));
22
+ s && (s.setAttribute("href", `{{${i}${e}_${o}_url}}`), s.classList.add(B));
24
23
  break;
25
24
  }
26
25
  case "productName": {
@@ -34,7 +33,7 @@ function E(t, r, e, o, c, i) {
34
33
  case "productPrice":
35
34
  case "productOldPrice": {
36
35
  const n = (l, d) => {
37
- l && (_(l).textContent = D(
36
+ l && (_(l).textContent = L(
38
37
  e,
39
38
  o,
40
39
  d,
@@ -78,24 +77,24 @@ function E(t, r, e, o, c, i) {
78
77
  }
79
78
  }
80
79
  }
81
- const w = "name";
80
+ const P = "name";
82
81
  function b(t, r, e, o) {
83
- const c = `${o}${r}_${e}_${w}`;
82
+ const c = `${o}${r}_${e}_${P}`;
84
83
  return {
85
84
  open: t.createComment(`{% if ${c} and ${c} != "" %}`),
86
85
  close: t.createComment("{% endif %}")
87
86
  };
88
87
  }
89
- function F(t, r, e) {
88
+ function R(t, r, e) {
90
89
  return b(t, r, 0, e);
91
90
  }
92
- function v(t, r, e, o) {
91
+ function D(t, r, e, o) {
93
92
  if (!t.innerHTML.includes("{{"))
94
93
  return;
95
94
  const { open: c, close: i } = b(t.ownerDocument, r, e, o);
96
95
  t.insertBefore(c, t.firstChild), t.appendChild(i);
97
96
  }
98
- function H(t, r, e, o) {
97
+ function w(t, r, e, o) {
99
98
  var n, s;
100
99
  if (!t.innerHTML.includes("{{"))
101
100
  return;
@@ -107,36 +106,36 @@ function W(t, r, e, o) {
107
106
  i.querySelectorAll("[data-attribute-type]").forEach((a) => {
108
107
  const u = a.getAttribute("data-attribute-type") || "", l = a.querySelectorAll(".attribute-cell");
109
108
  l.length > 0 ? l.forEach((d) => {
110
- E(d, u, r, n, e, o);
111
- }) : E(a, u, r, n, e, o);
112
- }), H(i, r, n, o);
109
+ A(d, u, r, n, e, o);
110
+ }) : A(a, u, r, n, e, o);
111
+ }), w(i, r, n, o);
113
112
  });
114
113
  }
115
- function G(t, r, e, o) {
114
+ function v(t, r, e, o) {
116
115
  const c = t.querySelectorAll(".recommendation-product-row");
117
116
  if (!c.length)
118
117
  return;
119
118
  const [i] = c, n = i.querySelector("[data-attribute-type]"), s = n ? n.querySelectorAll(".attribute-cell").length : 1;
120
119
  c.forEach((a, u) => {
121
120
  a.querySelectorAll("[data-attribute-type]").forEach((d) => {
122
- const f = d.getAttribute("data-attribute-type") || "";
123
- d.querySelectorAll(".attribute-cell").forEach((p, m) => {
124
- const y = u * s + m;
125
- E(p, f, r, y, e, o), v(p, r, y, o);
121
+ const p = d.getAttribute("data-attribute-type") || "";
122
+ d.querySelectorAll(".attribute-cell").forEach((f, m) => {
123
+ const h = u * s + m;
124
+ A(f, p, r, h, e, o), D(f, r, h, o);
126
125
  });
127
126
  });
128
127
  });
129
128
  }
130
- function U(t, r, e, o) {
129
+ function H(t, r, e, o) {
131
130
  t.querySelectorAll(".ins-recommendation-product-container").forEach((i) => {
132
- G(i, r, e, o);
131
+ v(i, r, e, o);
133
132
  });
134
133
  }
135
- function I(t, r, e) {
134
+ function F(t, r, e) {
136
135
  const o = t.getAttribute("data-layout") || "grid", c = t.getAttribute("currency-alignment") || "after";
137
- o === "list" ? W(t, r, c, e) : U(t, r, c, e);
136
+ o === "list" ? W(t, r, c, e) : H(t, r, c, e);
138
137
  }
139
- function S(t, r, e) {
138
+ function y(t, r, e) {
140
139
  const o = new RegExp(`${r}\\s*:\\s*(\\d+)\\s*px`, "i"), c = t.match(o);
141
140
  return c ? parseInt(c[1]) : e;
142
141
  }
@@ -151,7 +150,7 @@ function C(t) {
151
150
  const e = (t.getAttribute("style") || "").match(/(?:^|[;\s])width\s*:\s*(\d+(?:\.\d+)?(?:px|%))/i);
152
151
  return e && $(e[1]) ? e[1] : null;
153
152
  }
154
- function V(t, r) {
153
+ function G(t, r) {
155
154
  let e = t.parentElement;
156
155
  for (; e && e !== r; ) {
157
156
  if (e.tagName === "TD" && C(e))
@@ -160,74 +159,60 @@ function V(t, r) {
160
159
  }
161
160
  return null;
162
161
  }
163
- function A(t) {
164
- const r = B(
165
- (e) => t.style.getPropertyValue(e),
166
- t.getAttribute("width")
167
- );
168
- Object.entries(r).forEach(([e, o]) => t.style.setProperty(e, o));
169
- }
170
- function X(t) {
171
- const r = t.getAttribute("style") || "", e = S(r, "width", 600), o = S(r, "padding", 0) * 2, c = Math.max(0, e - o);
172
- t.querySelectorAll("img.adapt-img").forEach((i) => {
173
- if (i.hasAttribute("width") || c === 0) {
174
- A(i);
162
+ function V(t) {
163
+ const r = t.getAttribute("style") || "", e = y(r, "width", 600), o = y(r, "padding", 0) * 2, c = Math.max(0, e - o);
164
+ c !== 0 && t.querySelectorAll("img.adapt-img").forEach((i) => {
165
+ if (i.hasAttribute("width"))
175
166
  return;
176
- }
177
- const n = V(i, t);
178
- if (!n) {
179
- A(i);
167
+ const n = G(i, t);
168
+ if (!n)
180
169
  return;
170
+ const s = C(n), a = y(n.getAttribute("style") || "", "padding", 0) * 2, u = s.endsWith("%") ? Math.floor(c * parseFloat(s) / 100) : parseInt(s), l = Math.max(1, u - a);
171
+ i.setAttribute("width", String(l));
172
+ const d = i.getAttribute("style") || "";
173
+ if (!/\bwidth\s*:\s*\d/i.test(d)) {
174
+ const p = d && !d.trim().endsWith(";") ? "; " : "";
175
+ i.setAttribute("style", `${d}${p}width: ${l}px`);
181
176
  }
182
- const s = C(n), a = S(n.getAttribute("style") || "", "padding", 0) * 2, u = s.endsWith("%") ? Math.floor(c * parseFloat(s) / 100) : parseInt(s), l = Math.max(1, u - a);
183
- i.setAttribute("width", String(l)), A(i);
184
177
  });
185
178
  }
186
- const j = /\.recommendation-block-v2\s+\.adapt-img/;
187
- function x(t, r) {
188
- const e = r.some((i) => i.querySelector("img.adapt-img")), o = Array.from(t.querySelectorAll("style")).some((i) => j.test(i.textContent ?? ""));
189
- if (!e || o || !t.head)
190
- return;
191
- const c = t.createElement("style");
192
- c.setAttribute("type", "text/css"), c.textContent = T, t.head.appendChild(c);
193
- }
194
- const g = "MSO_MOBILE_HIDE_START", Y = "MSO_MOBILE_HIDE_END";
195
- function k(t, r) {
196
- t.querySelectorAll(L).forEach((e) => {
179
+ const E = "MSO_MOBILE_HIDE_START", U = "MSO_MOBILE_HIDE_END";
180
+ function X(t, r) {
181
+ t.querySelectorAll(q).forEach((e) => {
197
182
  var i, n;
198
183
  const o = e.querySelector(M);
199
184
  if (!o || o.children.length === 0)
200
185
  return;
201
186
  const c = e.previousSibling;
202
- (c == null ? void 0 : c.nodeType) === Node.COMMENT_NODE && c.data === g || ((i = e.parentNode) == null || i.insertBefore(r.createComment(g), e), (n = e.parentNode) == null || n.insertBefore(r.createComment(Y), e.nextSibling));
187
+ (c == null ? void 0 : c.nodeType) === Node.COMMENT_NODE && c.data === E || ((i = e.parentNode) == null || i.insertBefore(r.createComment(E), e), (n = e.parentNode) == null || n.insertBefore(r.createComment(U), e.nextSibling));
203
188
  });
204
189
  }
205
- function z(t, r) {
190
+ function j(t, r) {
206
191
  const e = t.match(/<!DOCTYPE[^>]*>/i);
207
192
  return (e ? `${e[0]}
208
193
  ` : "") + r.documentElement.outerHTML;
209
194
  }
210
- function rt(t) {
195
+ function Q(t) {
211
196
  const r = t.replaceAll("{%", "<!--{%").replaceAll("%}", "%}-->"), e = new DOMParser().parseFromString(r, "text/html"), o = e.querySelectorAll(".recommendation-block-v2");
212
197
  if (!o.length)
213
198
  return t;
214
- const { buildCampaignUrl: c } = q(), i = R();
199
+ const { buildCampaignUrl: c } = O(), i = N();
215
200
  i.recommendationCampaignUrls = {};
216
- const { isFeatureEnabled: n } = O(), s = n("liquidSyntax") ? "reco_" : "";
201
+ const { isFeatureEnabled: n } = g(), s = n("liquidSyntax") ? "reco_" : "";
217
202
  return o.forEach((u) => {
218
- var d, f, h, p;
203
+ var d, p, S, f;
219
204
  const l = u.getAttribute("recommendation-id");
220
205
  if (l) {
221
- if ((d = u.parentNode) == null || d.insertBefore(e.createComment("REC_START"), u), (f = u.parentNode) == null || f.insertBefore(e.createComment("REC_END"), u.nextSibling), u.querySelectorAll('[data-visibility="0"]').forEach((m) => m.remove()), c(l), k(u, e), !N(u)) {
222
- I(u, l, s);
223
- const { open: m, close: y } = F(e, l, s);
224
- (h = u.parentNode) == null || h.insertBefore(m, u), (p = u.parentNode) == null || p.insertBefore(y, u.nextSibling);
206
+ if ((d = u.parentNode) == null || d.insertBefore(e.createComment("REC_START"), u), (p = u.parentNode) == null || p.insertBefore(e.createComment("REC_END"), u.nextSibling), u.querySelectorAll('[data-visibility="0"]').forEach((m) => m.remove()), c(l), X(u, e), !T(u)) {
207
+ F(u, l, s);
208
+ const { open: m, close: h } = R(e, l, s);
209
+ (S = u.parentNode) == null || S.insertBefore(m, u), (f = u.parentNode) == null || f.insertBefore(h, u.nextSibling);
225
210
  }
226
- X(u);
211
+ V(u);
227
212
  }
228
- }), x(e, Array.from(o)), z(r, e).replaceAll("<!--{%", "{%").replaceAll("%}-->", "%}").replaceAll("&lt;!--{%", "{%").replaceAll("%}--&gt;", "%}");
213
+ }), j(r, e).replaceAll("<!--{%", "{%").replaceAll("%}-->", "%}").replaceAll("&lt;!--{%", "{%").replaceAll("%}--&gt;", "%}");
229
214
  }
230
215
  export {
231
- D as formatPriceVariable,
232
- rt as prepareRecommendationBlocks
216
+ L as formatPriceVariable,
217
+ Q as prepareRecommendationBlocks
233
218
  };
@@ -1,40 +1,39 @@
1
- var A = Object.defineProperty;
2
- var B = (a, c, t) => c in a ? A(a, c, { enumerable: !0, configurable: !0, writable: !0, value: t }) : a[c] = t;
3
- var p = (a, c, t) => B(a, typeof c != "symbol" ? c + "" : c, t);
1
+ var y = Object.defineProperty;
2
+ var A = (l, c, t) => c in l ? y(l, c, { enumerable: !0, configurable: !0, writable: !0, value: t }) : l[c] = t;
3
+ var h = (l, c, t) => A(l, typeof c != "symbol" ? c + "" : c, t);
4
4
  import { useConfig as d } from "../../../composables/useConfig.js";
5
5
  import { BlockId as D } from "../../../enums/block.js";
6
- import { getFluidImageStyleChanges as E } from "../../../utils/fluidImageStyle.js";
7
6
  import { getMigrationBannerHtml as C } from "../../../utils/migrationBannerHtml.js";
8
- import { Block as S, BlockCompositionType as N, ModificationDescription as h } from "../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
9
- import { CURRENT_CONFIG_VERSION as M, PRE_RRS_CONFIG_VERSION as O } from "./constants/defaultConfig.js";
7
+ import { Block as E, BlockCompositionType as S, ModificationDescription as p } from "../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
8
+ import { CURRENT_CONFIG_VERSION as N, PRE_RRS_CONFIG_VERSION as O } from "./constants/defaultConfig.js";
10
9
  import { RECOMMENDATION_ID_ATTR as m } from "./constants/selectors.js";
11
- import { regenerateMobileProductRows as w } from "./controls/main/utils.js";
12
- import { ensureMobileCssRulesExist as I, setMobileLayoutOptOut as k, hasMobileLayoutOptOut as H } from "./controls/mobileLayout/cssRules.js";
13
- import { RecommendationConfigService as l } from "./services/configService.js";
14
- import { useRecommendationExtensionStore as f } from "./store/recommendation.js";
10
+ import { regenerateMobileProductRows as M } from "./controls/main/utils.js";
11
+ import { ensureMobileCssRulesExist as I, setMobileLayoutOptOut as R, hasMobileLayoutOptOut as w } from "./controls/mobileLayout/cssRules.js";
12
+ import { RecommendationConfigService as s } from "./services/configService.js";
13
+ import { useRecommendationExtensionStore as g } from "./store/recommendation.js";
15
14
  import { getDefaultTemplate as T } from "./templates/grid/template.js";
16
15
  import { useRecommendationBlockWarning as v } from "./useRecommendationBlockWarning.js";
17
- const R = D.Recommendation, u = "recommendation-block-v2", y = "hide-price";
16
+ const k = D.Recommendation, u = "recommendation-block-v2", B = "hide-price";
18
17
  let b = !1;
19
- class Q extends S {
18
+ class j extends E {
20
19
  constructor() {
21
20
  super();
22
21
  /**
23
22
  * Stores the ID generated in getTemplate() so onCreated() can reuse it.
24
23
  * This avoids generating a new (different) ID in onCreated().
25
24
  */
26
- p(this, "_pendingBlockId", null);
25
+ h(this, "_pendingBlockId", null);
27
26
  /** Ids already reset under their new name, so the deferred pass skips their stale snapshot. */
28
- p(this, "_resetSourceIds", /* @__PURE__ */ new Set());
27
+ h(this, "_resetSourceIds", /* @__PURE__ */ new Set());
29
28
  }
30
29
  getId() {
31
- return R;
30
+ return k;
32
31
  }
33
32
  getIcon() {
34
33
  return "recommendation-icon";
35
34
  }
36
35
  getBlockCompositionType() {
37
- return N.CONTAINER;
36
+ return S.CONTAINER;
38
37
  }
39
38
  getName() {
40
39
  return this.api.translate("Recommendation Block");
@@ -46,7 +45,7 @@ class Q extends S {
46
45
  }
47
46
  getSettingsPanelTitleHtml() {
48
47
  return C(
49
- R,
48
+ k,
50
49
  this.api.translate("Recommendation Block"),
51
50
  this.api.translate("This block is switched from the Old Version to the New Version. We recommend you check the Recommendation block and test your message to ensure it works properly.")
52
51
  );
@@ -92,28 +91,28 @@ class Q extends S {
92
91
  }
93
92
  const i = this._pendingBlockId ?? this._generateNextId();
94
93
  this._pendingBlockId = null, this._assignRecommendationId(t, i);
95
- const n = d().isFeatureEnabled("reusableRecommendationStrategy"), o = n && !l.hasConfig(t), { config: r, wasFreshDrop: s } = l.initializeConfig(
94
+ const n = d().isFeatureEnabled("reusableRecommendationStrategy"), o = n && !s.hasConfig(t), { config: r, wasFreshDrop: a } = s.initializeConfig(
96
95
  this.api,
97
96
  t,
98
97
  {
99
98
  recommendationId: i,
100
- configVersion: n ? M : O,
99
+ configVersion: n ? N : O,
101
100
  ...o ? { partnerName: d().partnerName.value } : {},
102
101
  // An RRS block picks a strategy, not an algorithm, and its algorithm control is
103
102
  // hidden. Keeping the `mostPopular` default would bake a most-popular feed URL
104
103
  // at save for a block the user never configured.
105
104
  ...o ? { strategy: "" } : {}
106
105
  }
107
- ), g = f();
108
- if (g.setCurrentBlock(i), this._stampHidePrice(t, r.priceHideIfSameAsDiscounted), s) {
106
+ ), f = g();
107
+ if (f.setCurrentBlock(i), this._stampHidePrice(t, r.priceHideIfSameAsDiscounted), a) {
109
108
  I(this.api);
110
109
  const _ = this._getBlockElement(t);
111
- _ && (k(this.api, _, !0), w({
110
+ _ && (R(this.api, _, !0), M({
112
111
  currentNode: t,
113
112
  documentModifier: this.api.getDocumentModifier()
114
113
  }));
115
114
  }
116
- g.patchCurrentBlockConfig({ language: r.language }, { triggerRefetch: !1 }), this._warnIfMultipleBlocks();
115
+ f.patchCurrentBlockConfig({ language: r.language }, { triggerRefetch: !1 }), this._warnIfMultipleBlocks();
117
116
  }
118
117
  /**
119
118
  * Called when the document changes or template is loaded
@@ -126,24 +125,20 @@ class Q extends S {
126
125
  if (!(!t || !("getNodeConfig" in t))) {
127
126
  if (!this._getRecommendationId(t)) {
128
127
  const e = this._generateNextId();
129
- this._assignRecommendationId(t, e), l.hasConfig(t) && l.updateConfig(
128
+ this._assignRecommendationId(t, e), s.hasConfig(t) && s.updateConfig(
130
129
  this.api,
131
130
  t,
132
131
  { recommendationId: e },
133
132
  "Assign recommendation ID to legacy block"
134
133
  );
135
134
  }
136
- this._healLingeringDuplicate(t), l.needsMigration(t) && this._migrateFromLegacy(t), this._healHidePriceAttr(t);
137
- try {
138
- this._healFluidImages(t);
139
- } catch {
140
- }
135
+ this._healLingeringDuplicate(t), s.needsMigration(t) && this._migrateFromLegacy(t), this._healHidePriceAttr(t);
141
136
  try {
142
137
  b || (I(this.api), b = !0);
143
- const e = l.getConfig(t), i = this._getBlockElement(t);
138
+ const e = s.getConfig(t), i = this._getBlockElement(t);
144
139
  if (i) {
145
140
  const n = !e.mobileLayoutEnabled;
146
- H(i) !== n && k(this.api, i, n);
141
+ w(i) !== n && R(this.api, i, n);
147
142
  }
148
143
  } catch {
149
144
  }
@@ -157,7 +152,7 @@ class Q extends S {
157
152
  */
158
153
  onDelete(t) {
159
154
  const e = this._getRecommendationId(t);
160
- e && f().removeBlockState(e);
155
+ e && g().removeBlockState(e);
161
156
  }
162
157
  /**
163
158
  * Warns (dark advisory toaster) when the design holds more than one live
@@ -205,7 +200,7 @@ class Q extends S {
205
200
  _scheduleArrivalReset(t) {
206
201
  d().isFeatureEnabled("reusableRecommendationStrategy") && setTimeout(() => {
207
202
  const e = this._getRecommendationId(t);
208
- e !== null && e > 0 && !this._resetSourceIds.delete(e) && f().resetArrivedBlock(e);
203
+ e !== null && e > 0 && !this._resetSourceIds.delete(e) && g().resetArrivedBlock(e);
209
204
  }, 0);
210
205
  }
211
206
  /**
@@ -236,9 +231,9 @@ class Q extends S {
236
231
  if (!o)
237
232
  return;
238
233
  let r = -1;
239
- for (let s = 0; s < n.length; s++)
240
- if (n[s] === o) {
241
- r = s;
234
+ for (let a = 0; a < n.length; a++)
235
+ if (n[a] === o) {
236
+ r = a;
242
237
  break;
243
238
  }
244
239
  if (r <= 0)
@@ -261,7 +256,7 @@ class Q extends S {
261
256
  }
262
257
  /** Assigns a fresh id to a duplicated block and syncs DOM, node config and store. */
263
258
  _handleDuplicate(t, e) {
264
- const i = this._reassignDuplicateId(t, e), n = f();
259
+ const i = this._reassignDuplicateId(t, e), n = g();
265
260
  n.cloneBlockState(e, i), n.setCurrentBlock(i), d().isFeatureEnabled("reusableRecommendationStrategy") && (this._resetSourceIds.add(e), n.resetArrivedBlock(i)), this._warnIfMultipleBlocks();
266
261
  }
267
262
  /**
@@ -277,7 +272,7 @@ class Q extends S {
277
272
  */
278
273
  _reassignDuplicateId(t, e) {
279
274
  const i = this._generateNextId(), n = this._getBlockElement(t);
280
- return this._assignRecommendationId(t, i), n && this._reassignInstanceClass(n, e, i), l.hasConfig(t) && l.updateConfig(
275
+ return this._assignRecommendationId(t, i), n && this._reassignInstanceClass(n, e, i), s.hasConfig(t) && s.updateConfig(
281
276
  this.api,
282
277
  t,
283
278
  { recommendationId: i },
@@ -295,7 +290,7 @@ class Q extends S {
295
290
  if (!("getAttribute" in t))
296
291
  return;
297
292
  const n = `ins-recommendation-v3-block-${e}`, o = `ins-recommendation-v3-block-${i}`, r = this.api.getDocumentModifier();
298
- r.modifyHtml(t).removeClass(n).setClass(o), r.apply(new h(
293
+ r.modifyHtml(t).removeClass(n).setClass(o), r.apply(new p(
299
294
  `Reassign recommendation instance class ${n} -> ${o}`
300
295
  ));
301
296
  }
@@ -310,7 +305,7 @@ class Q extends S {
310
305
  if (!i)
311
306
  return;
312
307
  const n = this.api.getDocumentModifier();
313
- n.modifyHtml(i).setAttribute(m, e.toString()), n.apply(new h(`Assign recommendation ID ${e}`));
308
+ n.modifyHtml(i).setAttribute(m, e.toString()), n.apply(new p(`Assign recommendation ID ${e}`));
314
309
  }
315
310
  /**
316
311
  * Stamps the `hide-price` attribute (read by email-service at send time) on
@@ -318,7 +313,7 @@ class Q extends S {
318
313
  */
319
314
  _stampHidePrice(t, e) {
320
315
  const i = this._getBlockElement(t);
321
- i && this.api.getDocumentModifier().modifyHtml(i).setAttribute(y, String(e)).apply(new h("Stamp hide-price"));
316
+ i && this.api.getDocumentModifier().modifyHtml(i).setAttribute(B, String(e)).apply(new p("Stamp hide-price"));
322
317
  }
323
318
  /**
324
319
  * Stamps `hide-price` from config only when the block lacks the attribute —
@@ -326,28 +321,11 @@ class Q extends S {
326
321
  */
327
322
  _healHidePriceAttr(t) {
328
323
  const e = this._getBlockElement(t);
329
- if (!e || !("getAttribute" in e) || e.getAttribute(y) !== null)
324
+ if (!e || !("getAttribute" in e) || e.getAttribute(B) !== null)
330
325
  return;
331
- const { priceHideIfSameAsDiscounted: i } = l.getConfig(t);
326
+ const { priceHideIfSameAsDiscounted: i } = s.getConfig(t);
332
327
  this._stampHidePrice(t, i);
333
328
  }
334
- // Writes into the stored template too, which email-service compiles again.
335
- // Applies only on a real change: an empty apply re-fires onDocumentChanged.
336
- _healFluidImages(t) {
337
- const e = this._getBlockElement(t);
338
- if (!e || !("querySelectorAll" in e))
339
- return;
340
- const i = this.api.getDocumentModifier();
341
- let n = !1;
342
- e.querySelectorAll("img.adapt-img").forEach((o) => {
343
- if (!("getStyle" in o) || !("getAttribute" in o))
344
- return;
345
- const r = E((s) => o.getStyle(s), o.getAttribute("width"));
346
- Object.entries(r).forEach(([s, g]) => {
347
- i.modifyHtml(o).setStyle(s, g), n = !0;
348
- });
349
- }), n && i.apply(new h("Make product images fluid"));
350
- }
351
329
  /**
352
330
  * Gets the recommendation-id from a block node
353
331
  */
@@ -376,10 +354,10 @@ class Q extends S {
376
354
  * Migrate configuration from legacy format
377
355
  */
378
356
  _migrateFromLegacy(t) {
379
- l.migrateFromDataAttributes(this.api, t);
357
+ s.migrateFromDataAttributes(this.api, t);
380
358
  }
381
359
  }
382
360
  export {
383
- R as BLOCK_ID,
384
- Q as RecommendationBlock
361
+ k as BLOCK_ID,
362
+ j as RecommendationBlock
385
363
  };
@@ -1,30 +1,26 @@
1
- import { FLUID_IMAGE_MOBILE_RULE as u, FLUID_IMAGE_CLASS as m, FLUID_IMAGE_SELECTOR as p } from "../../../../../utils/fluidImageStyle.js";
2
1
  import { ModificationDescription as a } from "../../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
3
- const r = "ins-recommendation-desktop-container", l = "ins-recommendation-mobile-container", i = "ins-recommendation-list-layout", s = "ins-recommendation-no-mobile-layout", d = `.${l} { display: none; }`, c = `@media only screen and (max-width: 480px) { .${r} { display: none !important; } .${l} { display: table !important; } .${i} .${r} { display: table !important; } .${i} .${l}, .${i} .ins-recommendation-mobile-row { display: none !important; } .${i} .product-image-cell { width: 80px !important; } .${i} .product-image-cell img { max-width: 80px !important; } .${i} .button-cell { width: 80px !important; } .${i} .product-info-cell { padding: 5px 8px !important; } }`, f = `@media only screen and (max-width: 480px) { .${s} .${r} { display: table !important; } .${s} .${l}, .${s} .ins-recommendation-mobile-row { display: none !important; } }`, _ = `.${l}`;
4
- function S(t, e) {
2
+ const r = "ins-recommendation-desktop-container", l = "ins-recommendation-mobile-container", i = "ins-recommendation-list-layout", s = "ins-recommendation-no-mobile-layout", u = `.${l} { display: none; }`, m = `@media only screen and (max-width: 480px) { .${r} { display: none !important; } .${l} { display: table !important; } .${i} .${r} { display: table !important; } .${i} .${l}, .${i} .ins-recommendation-mobile-row { display: none !important; } .${i} .product-image-cell { width: 80px !important; } .${i} .product-image-cell img { max-width: 80px !important; } .${i} .button-cell { width: 80px !important; } .${i} .product-info-cell { padding: 5px 8px !important; } }`, d = `@media only screen and (max-width: 480px) { .${s} .${r} { display: table !important; } .${s} .${l}, .${s} .ins-recommendation-mobile-row { display: none !important; } }`, p = `.${l}`;
3
+ function c(t, e) {
5
4
  return !!t.querySelector(e);
6
5
  }
7
- function y(t) {
6
+ function f(t) {
8
7
  return t.querySelectorAll(`*${r}`).length > 0;
9
8
  }
10
- function C(t) {
9
+ function y(t) {
11
10
  return t.querySelectorAll(`*${s}`).length > 0;
12
11
  }
13
- function E(t) {
14
- return t.querySelectorAll(`*${m}`).some((e) => "getSelector" in e && typeof e.getSelector == "function" && e.getSelector() === p);
15
- }
16
- function I(t) {
12
+ function S(t) {
17
13
  const e = t.getDocumentRootCssNode();
18
14
  if (!e)
19
15
  return;
20
16
  const o = t.getDocumentModifier();
21
17
  let n = !1;
22
- S(e, _) || (o.modifyCss(e).appendRule(d), n = !0), y(e) || (o.modifyCss(e).appendRule(c), n = !0), C(e) || (o.modifyCss(e).appendRule(f), n = !0), E(e) || (o.modifyCss(e).appendRule(u), n = !0), n && o.apply(new a("Add mobile layout CSS rules"));
18
+ c(e, p) || (o.modifyCss(e).appendRule(u), n = !0), f(e) || (o.modifyCss(e).appendRule(m), n = !0), y(e) || (o.modifyCss(e).appendRule(d), n = !0), n && o.apply(new a("Add mobile layout CSS rules"));
23
19
  }
24
- function R(t) {
20
+ function C(t) {
25
21
  return "hasClass" in t ? t.hasClass(s) : !1;
26
22
  }
27
- function $(t, e, o) {
23
+ function O(t, e, o) {
28
24
  const n = t.getDocumentModifier();
29
25
  o ? n.modifyHtml(e).setClass(s) : n.modifyHtml(e).removeClass(s), n.apply(
30
26
  new a(
@@ -36,7 +32,7 @@ export {
36
32
  r as CSS_CLASS_DESKTOP_CONTAINER,
37
33
  l as CSS_CLASS_MOBILE_CONTAINER,
38
34
  s as CSS_CLASS_NO_MOBILE_LAYOUT,
39
- I as ensureMobileCssRulesExist,
40
- R as hasMobileLayoutOptOut,
41
- $ as setMobileLayoutOptOut
35
+ S as ensureMobileCssRulesExist,
36
+ C as hasMobileLayoutOptOut,
37
+ O as setMobileLayoutOptOut
42
38
  };
@@ -1,6 +1,6 @@
1
1
  import { ATTR_PRODUCT_PRICE as l, ATTR_PRODUCT_OLD_PRICE as a, ATTR_CUSTOM_PREFIX as T, ATTR_PRODUCT_IMAGE as b, ATTR_PRODUCT_NAME as _, ATTR_PRODUCT_OMNIBUS_PRICE as C, ATTR_PRODUCT_OMNIBUS_DISCOUNT as A, ATTR_PRODUCT_BUTTON as p, PRODUCT_ATTRIBUTE_PREFIX as I } from "../constants/selectors.js";
2
2
  import { useRecommendationExtensionStore as L } from "../store/recommendation.js";
3
- import { compositionKeyToProductAttr as y, isDefaultProductAttr as f, bareAttributeName as S, findFilterByBareName as $, productAttrToCompositionKey as h } from "../utils/compositionKeys.js";
3
+ import { compositionKeyToProductAttr as y, isDefaultProductAttr as f, bareAttributeName as S, findFilterByBareName as $, productAttrToCompositionKey as P } from "../utils/compositionKeys.js";
4
4
  import { formatPrice as B } from "../utils/priceFormatter.js";
5
5
  import { buildTitleRows as k } from "./titleRows.js";
6
6
  function x() {
@@ -35,22 +35,22 @@ function J(t) {
35
35
  skip: n ? l : a
36
36
  };
37
37
  }
38
- function w(t) {
38
+ function F(t) {
39
39
  const e = Array.isArray(t) ? t[t.length - 1] : t;
40
40
  if (typeof e == "string")
41
41
  return e;
42
42
  if (typeof e == "number")
43
43
  return String(e);
44
44
  }
45
- function F(t, e) {
45
+ function v(t, e) {
46
46
  var o;
47
47
  return ((o = $(t, e)) == null ? void 0 : o.type) === "defaultAttribute";
48
48
  }
49
- function v(t, e) {
50
- return F(t, e) ? t : `${I}${t}`;
49
+ function w(t, e) {
50
+ return v(t, e) ? t : `${I}${t}`;
51
51
  }
52
52
  function Q(t) {
53
- return h(t);
53
+ return P(t);
54
54
  }
55
55
  const M = Symbol("customCellHtml");
56
56
  function Z(t, e, o = {}) {
@@ -59,16 +59,16 @@ function Z(t, e, o = {}) {
59
59
  return { ...t };
60
60
  const c = { ...t };
61
61
  return e.filter((i) => i.startsWith(T) && !c[i]).forEach((i) => {
62
- const s = y(i), r = f(s) ? v(s, o) : s, u = S(r), R = N(u), D = f(r);
62
+ const s = y(i), r = f(s) ? w(s, o) : s, u = S(r), h = N(u), D = f(r);
63
63
  c[i] = (d, U) => {
64
64
  var g;
65
- const O = D ? d[u] : (g = d.product_attributes) == null ? void 0 : g[u], E = w(O) ?? R;
65
+ const O = D ? d[u] : (g = d.product_attributes) == null ? void 0 : g[u], E = F(O) ?? h;
66
66
  return n(r, E, U);
67
67
  };
68
68
  }), c;
69
69
  }
70
70
  function tt(t, e, o = []) {
71
- const n = t.startsWith(T) ? h(S(y(t))) : t, i = n !== t && !o.includes(n) ? n : t, s = (r) => (r == null ? void 0 : r[t]) ?? (r == null ? void 0 : r[i]);
71
+ const n = t.startsWith(T) ? P(S(y(t))) : t, i = n !== t && !o.includes(n) ? n : t, s = (r) => (r == null ? void 0 : r[t]) ?? (r == null ? void 0 : r[i]);
72
72
  return {
73
73
  cellPadding: e.cellPadding,
74
74
  cardBackgroundColor: e.cardBackgroundColor,
@@ -135,14 +135,14 @@ function at(t, e) {
135
135
  function ut(t) {
136
136
  return t != null && t.buttonFitToContainer ? "es-button-border es-fw" : "es-button-border";
137
137
  }
138
- const dt = "display: block; width: 100%; max-width: 100%; height: auto;", gt = "border-width: 1px; background: rgb(217, 234, 211); border-color: rgb(106, 168, 79);", ft = "color: rgb(56, 118, 29); background: rgb(217, 234, 211); font-family: arial, 'helvetica neue', helvetica, sans-serif; font-size: 16px; font-weight: normal; line-height: 120%; mso-border-alt: 10px solid rgb(217, 234, 211); mso-padding-alt: 0;", P = "https://email-static.useinsider.com/stripo/modules/email-recommendation-v3/assets/images/image-placeholder.png";
138
+ const dt = "display: block; max-width: 100%; height: auto;", gt = "border-width: 1px; background: rgb(217, 234, 211); border-color: rgb(106, 168, 79);", ft = "color: rgb(56, 118, 29); background: rgb(217, 234, 211); font-family: arial, 'helvetica neue', helvetica, sans-serif; font-size: 16px; font-weight: normal; line-height: 120%; mso-border-alt: 10px solid rgb(217, 234, 211); mso-padding-alt: 0;", R = "https://email-static.useinsider.com/stripo/modules/email-recommendation-v3/assets/images/image-placeholder.png";
139
139
  function mt(t) {
140
- return !t || typeof t != "string" || t.trim() === "" ? P : t.startsWith("http://") ? t.replace("http://", "https://") : t;
140
+ return !t || typeof t != "string" || t.trim() === "" ? R : t.startsWith("http://") ? t.replace("http://", "https://") : t;
141
141
  }
142
142
  function Y(t) {
143
143
  return {
144
144
  name: "Product Name",
145
- image_url: P,
145
+ image_url: R,
146
146
  price: { USD: 18 },
147
147
  original_price: { USD: 20 },
148
148
  discount: { USD: 2 },
@@ -224,7 +224,7 @@ export {
224
224
  nt as DEFAULT_CARD_VISIBILITY,
225
225
  dt as DEFAULT_IMG_STYLE,
226
226
  W as DEFAULT_ROW_SPACING_PX,
227
- P as PLACEHOLDER_IMAGE,
227
+ R as PLACEHOLDER_IMAGE,
228
228
  V as bgColorFragment,
229
229
  tt as buildCellOptions,
230
230
  Z as buildElementRenderer,
@@ -234,7 +234,7 @@ export {
234
234
  m as formatProductPrice,
235
235
  x as getCurrentCurrencyConfig,
236
236
  Tt as getDefaultProducts,
237
- F as isDefaultAttribute,
237
+ v as isDefaultAttribute,
238
238
  q as isSamePrice,
239
239
  at as renderButtonLabel,
240
240
  it as renderStyledParagraph,
@@ -242,10 +242,10 @@ export {
242
242
  J as resolveInlinePriceOrder,
243
243
  lt as resolveOmnibusText,
244
244
  H as resolvePStyle,
245
- v as resolveProductAttrValue,
245
+ w as resolveProductAttrValue,
246
246
  st as resolveSegmentBgStyle,
247
247
  mt as sanitizeImageUrl,
248
248
  Q as toCustomCompositionKey,
249
249
  N as toDisplayName,
250
- w as toDisplayableAttributeValue
250
+ F as toDisplayableAttributeValue
251
251
  };
@@ -1,12 +1,11 @@
1
- import { getFluidImageStyleChanges as E } from "../../../../utils/fluidImageStyle.js";
2
- import { extractWrapperTags as A } from "../../../../utils/preserveTextStyles.js";
1
+ import { extractWrapperTags as C } from "../../../../utils/preserveTextStyles.js";
3
2
  import { RecommendationBlockId as c } from "../constants/blockIds.js";
4
- import { DESKTOP_CONTAINER_SELECTOR as g, ATTR_PRODUCT_NAME as P, ATTR_PRODUCT_PRICE as b, ATTR_PRODUCT_OLD_PRICE as p, ATTR_PRODUCT_OMNIBUS_PRICE as R, ATTR_PRODUCT_OMNIBUS_DISCOUNT as _, ATTR_PRODUCT_BUTTON as q, ATTR_PRODUCT_IMAGE as x, ATTR_PRODUCT_ATTR as v } from "../constants/selectors.js";
5
- import { CSS_CLASS_TEXT_TRIM as B } from "../controls/shared/textTrimCssRules.js";
6
- import { toCustomCompositionKey as U } from "../templates/utils.js";
7
- import { resolveRowCompositionKey as M } from "./compositionKeys.js";
8
- import { hasQuerySelectorAll as I, hasGetAttribute as a, hasGetStyle as O, hasGetComputedStyle as N } from "./tagName.js";
9
- const l = [
3
+ import { DESKTOP_CONTAINER_SELECTOR as S, ATTR_PRODUCT_NAME as E, ATTR_PRODUCT_PRICE as p, ATTR_PRODUCT_OLD_PRICE as y, ATTR_PRODUCT_OMNIBUS_PRICE as A, ATTR_PRODUCT_OMNIBUS_DISCOUNT as R, ATTR_PRODUCT_BUTTON as P, ATTR_PRODUCT_IMAGE as q, ATTR_PRODUCT_ATTR as x } from "../constants/selectors.js";
4
+ import { CSS_CLASS_TEXT_TRIM as v } from "../controls/shared/textTrimCssRules.js";
5
+ import { toCustomCompositionKey as B } from "../templates/utils.js";
6
+ import { resolveRowCompositionKey as U } from "./compositionKeys.js";
7
+ import { hasQuerySelectorAll as _, hasGetAttribute as l, hasGetStyle as I, hasGetComputedStyle as N } from "./tagName.js";
8
+ const s = [
10
9
  "font-size",
11
10
  "font-family",
12
11
  "font-weight",
@@ -15,15 +14,15 @@ const l = [
15
14
  "text-align",
16
15
  "line-height",
17
16
  "text-decoration"
18
- ], D = [
17
+ ], M = [
19
18
  "background",
20
19
  "background-color",
21
20
  "border-width",
22
21
  "border-color",
23
22
  "border-style",
24
23
  "border-radius"
25
- ], w = [
26
- ...l,
24
+ ], D = [
25
+ ...s,
27
26
  "background",
28
27
  "background-color",
29
28
  // Stripo's Border Radius control writes the radius to the anchor too, not just the
@@ -40,48 +39,48 @@ const l = [
40
39
  "max-width",
41
40
  "border-radius",
42
41
  "margin"
43
- ], S = /* @__PURE__ */ new Set(["transparent", "rgba(0, 0, 0, 0)"]), L = [
44
- { attrKey: P, blockId: c.NAME, kind: "text" },
45
- { attrKey: b, blockId: c.PRICE, kind: "text" },
46
- { attrKey: p, blockId: c.OLD_PRICE, kind: "text" },
47
- { attrKey: R, blockId: c.OMNIBUS_PRICE, kind: "text" },
48
- { attrKey: _, blockId: c.OMNIBUS_DISCOUNT, kind: "text" },
49
- { attrKey: q, blockId: c.BUTTON, kind: "button" },
50
- { attrKey: x, blockId: c.IMAGE, kind: "image" }
42
+ ], g = /* @__PURE__ */ new Set(["transparent", "rgba(0, 0, 0, 0)"]), L = [
43
+ { attrKey: E, blockId: c.NAME, kind: "text" },
44
+ { attrKey: p, blockId: c.PRICE, kind: "text" },
45
+ { attrKey: y, blockId: c.OLD_PRICE, kind: "text" },
46
+ { attrKey: A, blockId: c.OMNIBUS_PRICE, kind: "text" },
47
+ { attrKey: R, blockId: c.OMNIBUS_DISCOUNT, kind: "text" },
48
+ { attrKey: P, blockId: c.BUTTON, kind: "button" },
49
+ { attrKey: q, blockId: c.IMAGE, kind: "image" }
51
50
  ];
52
- function h(t) {
51
+ function O(t) {
53
52
  return t && "getInnerHTML" in t && typeof t.getInnerHTML == "function" ? t.getInnerHTML().trim() : "";
54
53
  }
55
- function K(t) {
54
+ function w(t) {
56
55
  return t && "getInnerText" in t && typeof t.getInnerText == "function" ? t.getInnerText().trim() : "";
57
56
  }
58
- function s(t, e, r) {
59
- !e || !O(e) || r.forEach((n) => {
57
+ function a(t, e, r) {
58
+ !e || !I(e) || r.forEach((n) => {
60
59
  const o = e.getStyle(n);
61
60
  o && o !== "inherit" && o !== "initial" && (t[n] = o);
62
61
  });
63
62
  }
64
- function y(t) {
63
+ function h(t) {
65
64
  return Object.entries(t).map(([e, r]) => `${e}: ${r};`).join(" ");
66
65
  }
67
66
  function k(t) {
68
- if (!t || !O(t))
67
+ if (!t || !I(t))
69
68
  return;
70
69
  const e = t.getStyle("background-color") || t.getStyle("background");
71
- return e && !S.has(e) ? e : void 0;
70
+ return e && !g.has(e) ? e : void 0;
72
71
  }
73
- function C(t, e) {
72
+ function b(t, e) {
74
73
  const r = {};
75
- return s(r, t, e), y(r);
74
+ return a(r, t, e), h(r);
76
75
  }
77
- function $(t) {
76
+ function K(t) {
78
77
  const e = t.querySelector("p"), r = {};
79
- s(r, t, l), s(r, e, l), s(r, t.querySelector("strong"), l), s(r, t.querySelector("em"), l), s(r, t.querySelector("s"), l);
80
- const n = y(r), { openTags: o, closeTags: i } = A(h(e));
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);
79
+ const n = h(r), { openTags: o, closeTags: i } = C(O(e));
81
80
  return !n && !o ? null : { pStyle: n || void 0, openTags: o, closeTags: i };
82
81
  }
83
- function j(t) {
84
- const e = t.querySelector(".es-button-border"), r = t.querySelector("a.es-button") ?? t.querySelector("a"), n = C(e, D), o = C(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);
82
+ function $(t) {
83
+ const e = t.querySelector(".es-button-border"), r = t.querySelector("a.es-button") ?? t.querySelector("a"), n = b(e, M), o = b(r, D), i = e && "getAttribute" in e ? e.getAttribute("class") ?? "" : "", u = /\bes-fw\b/.test(i), { openTags: T, closeTags: d } = C(O(r)), m = w(r);
85
84
  return !n && !o && !u && !T && !m ? null : {
86
85
  buttonBorderStyle: n || void 0,
87
86
  buttonAnchorStyle: o || void 0,
@@ -91,140 +90,137 @@ function j(t) {
91
90
  closeTags: d
92
91
  };
93
92
  }
94
- function F(t) {
95
- const e = t.querySelector("img"), r = {};
96
- if (s(r, e, G), !Object.keys(r).length)
97
- return null;
98
- const n = a(e) ? e.getAttribute("width") : null;
99
- return Object.assign(r, E((o) => r[o], n)), { imgStyle: y(r) };
93
+ function H(t) {
94
+ const e = b(t.querySelector("img"), G);
95
+ return e ? { imgStyle: e } : null;
100
96
  }
101
- function H(t, e) {
102
- return e === "button" ? j(t) : e === "image" ? F(t) : $(t);
97
+ function F(t, e) {
98
+ return e === "button" ? $(t) : e === "image" ? H(t) : K(t);
103
99
  }
104
100
  function f(t, e) {
105
101
  if (!t || !("querySelector" in t))
106
102
  return;
107
- const r = t.querySelector(g) ?? t;
103
+ const r = t.querySelector(S) ?? t;
108
104
  if (L.forEach(({ attrKey: i, blockId: u, kind: T }) => {
109
105
  const d = r.querySelector(`[esd-extension-block-id="${u}"]`);
110
106
  d && e(d, i, T);
111
- }), !I(r))
107
+ }), !_(r))
112
108
  return;
113
109
  const n = /* @__PURE__ */ new Set();
114
110
  r.querySelectorAll(
115
111
  `[esd-extension-block-id="${c.CUSTOM_ATTRIBUTE}"]`
116
112
  ).forEach((i) => {
117
- const u = a(i) ? i.getAttribute(v) : null;
118
- !u || n.has(u) || (n.add(u), e(i, U(u), "text"));
113
+ const u = l(i) ? i.getAttribute(x) : null;
114
+ !u || n.has(u) || (n.add(u), e(i, B(u), "text"));
119
115
  });
120
116
  }
121
- function X(t) {
117
+ function j(t) {
122
118
  const e = {};
123
119
  return f(t, (r, n, o) => {
124
120
  if (!("querySelector" in r))
125
121
  return;
126
- const i = H(r, o);
122
+ const i = F(r, o);
127
123
  i && (e[n] = i);
128
124
  }), e;
129
125
  }
130
- function z(t) {
126
+ function X(t) {
131
127
  if (!t || !("querySelector" in t))
132
128
  return;
133
- const e = t.querySelector(g) ?? t, r = e.querySelector(".product-card-segment") ?? e.querySelector(".product-card-wrapper");
129
+ const e = t.querySelector(S) ?? t, r = e.querySelector(".product-card-segment") ?? e.querySelector(".product-card-wrapper");
134
130
  return k(r);
135
131
  }
136
- function Q(t) {
132
+ function z(t) {
137
133
  if (!t)
138
134
  return;
139
- const e = a(t) ? t.getAttribute("bgcolor") : null;
140
- if (e && !S.has(e))
135
+ const e = l(t) ? t.getAttribute("bgcolor") : null;
136
+ if (e && !g.has(e))
141
137
  return e;
142
138
  const r = k(t);
143
139
  if (r)
144
140
  return r;
145
141
  const n = N(t) ? t.getComputedStyle("background-color") : void 0;
146
- return n && !S.has(n) ? n : void 0;
142
+ return n && !g.has(n) ? n : void 0;
147
143
  }
148
- function V(t) {
144
+ function Q(t) {
149
145
  const e = {};
150
146
  return f(t, (r, n, o) => {
151
147
  if (o !== "text")
152
148
  return;
153
- const i = Q(r);
149
+ const i = z(r);
154
150
  i && (e[n] = i);
155
151
  }), e;
156
152
  }
157
- function W(t) {
153
+ function V(t) {
158
154
  const e = {};
159
155
  return f(t, (r, n, o) => {
160
156
  if (o === "image")
161
157
  return;
162
- const i = a(r) ? r.getAttribute("align") : null;
158
+ const i = l(r) ? r.getAttribute("align") : null;
163
159
  i && (e[n] = i);
164
160
  }), e;
165
161
  }
166
- const Y = /^es-[pm]\d+[trbl]?$/;
167
- function J(t) {
168
- const e = a(t) ? t.getAttribute("class") : null;
162
+ const W = /^es-[pm]\d+[trbl]?$/;
163
+ function Y(t) {
164
+ const e = l(t) ? t.getAttribute("class") : null;
169
165
  if (!e)
170
166
  return;
171
- const r = e.split(/\s+/).filter((n) => Y.test(n) || n === B);
167
+ const r = e.split(/\s+/).filter((n) => W.test(n) || n === v);
172
168
  return r.length ? r.join(" ") : void 0;
173
169
  }
174
- function Z(t) {
170
+ function J(t) {
175
171
  if (!t || !("querySelector" in t))
176
172
  return !1;
177
- const e = t.querySelector(g) ?? t, r = (n) => !!(n && "querySelector" in n && n.querySelector(".product-price") && n.querySelector(".product-old-price"));
178
- return r(e.querySelector(`[data-attribute-type="${b}"]`)) || r(e.querySelector(`[data-attribute-type="${p}"]`));
173
+ const e = t.querySelector(S) ?? t, r = (n) => !!(n && "querySelector" in n && n.querySelector(".product-price") && n.querySelector(".product-old-price"));
174
+ return r(e.querySelector(`[data-attribute-type="${p}"]`)) || r(e.querySelector(`[data-attribute-type="${y}"]`));
179
175
  }
180
- function tt(t) {
181
- const e = {}, r = Z(t);
176
+ function Z(t) {
177
+ const e = {}, r = J(t);
182
178
  return f(t, (n, o, i) => {
183
- if (i === "image" || r && (o === b || o === p))
179
+ if (i === "image" || r && (o === p || o === y))
184
180
  return;
185
- const u = J(n);
181
+ const u = Y(n);
186
182
  u && (e[o] = u);
187
183
  }), e;
188
184
  }
189
- function et(t) {
185
+ function tt(t) {
190
186
  const e = {};
191
187
  return f(t, (r, n) => {
192
- if (n !== R && n !== _ || !a(r))
188
+ if (n !== A && n !== R || !l(r))
193
189
  return;
194
190
  const o = r.getAttribute("data-text-before"), i = r.getAttribute("data-text-after");
195
191
  (o != null || i != null) && (e[n] = { before: o ?? void 0, after: i ?? void 0 });
196
192
  }), e;
197
193
  }
198
- function rt(t) {
194
+ function et(t) {
199
195
  const e = {};
200
196
  if (!t || !("querySelector" in t))
201
197
  return e;
202
- const r = t.querySelector(g) ?? t;
203
- return I(r) && r.querySelectorAll(".recommendation-attribute-row").forEach((n) => {
204
- if (!a(n))
198
+ const r = t.querySelector(S) ?? t;
199
+ return _(r) && r.querySelectorAll(".recommendation-attribute-row").forEach((n) => {
200
+ if (!l(n))
205
201
  return;
206
- const o = M(n), i = n.getAttribute("data-visibility");
202
+ const o = U(n), i = n.getAttribute("data-visibility");
207
203
  o && i != null && (e[o] = i !== "0");
208
204
  }), e;
209
205
  }
210
- function ft(t) {
206
+ function at(t) {
211
207
  return {
212
- styleTemplates: X(t),
213
- cardBackgroundColor: z(t),
214
- cellBackgroundColors: V(t),
215
- cellAlignments: W(t),
216
- cellClasses: tt(t),
217
- omnibusTexts: et(t),
218
- visibility: rt(t)
208
+ styleTemplates: j(t),
209
+ cardBackgroundColor: X(t),
210
+ cellBackgroundColors: Q(t),
211
+ cellAlignments: V(t),
212
+ cellClasses: Z(t),
213
+ omnibusTexts: tt(t),
214
+ visibility: et(t)
219
215
  };
220
216
  }
221
217
  export {
222
- X as captureAttributeStyleTemplates,
223
- z as captureCardBackgroundColor,
224
- W as captureCellAlignments,
225
- V as captureCellBackgroundColors,
226
- tt as captureCellClasses,
227
- et as captureOmnibusTexts,
228
- ft as captureStyles,
229
- rt as captureVisibility
218
+ j as captureAttributeStyleTemplates,
219
+ X as captureCardBackgroundColor,
220
+ V as captureCellAlignments,
221
+ Q as captureCellBackgroundColors,
222
+ Z as captureCellClasses,
223
+ tt as captureOmnibusTexts,
224
+ at as captureStyles,
225
+ et as captureVisibility
230
226
  };
@@ -10,3 +10,8 @@ export declare const MSO_ITEMS_HIDE_END = "MSO_ITEMS_HIDE_END";
10
10
  * and collapse them inline for web-engine Outlook.
11
11
  */
12
12
  export declare function wrapHiddenPriceTdsForOutlook(html: string): string;
13
+ /**
14
+ * The mobile `.adapt-img { width: 100% }` rule sizes the horizontal thumbnail by its auto-width column,
15
+ * so it grows in a roomy row and collapses to nothing in a crowded one — bound it to [default, width].
16
+ */
17
+ export declare function lockHorizontalItemImageWidths(html: string): string;
@@ -137,7 +137,6 @@ export declare class RecommendationBlock extends Block {
137
137
  * heals templates saved before this feature without dirtying current ones.
138
138
  */
139
139
  private _healHidePriceAttr;
140
- private _healFluidImages;
141
140
  /**
142
141
  * Gets the recommendation-id from a block node
143
142
  */
@@ -292,11 +292,8 @@ export declare function renderButtonLabel(label: string, template?: AttributeSty
292
292
  * class, not inline width, so we preserve the class across regeneration.
293
293
  */
294
294
  export declare function resolveButtonBorderClass(template?: AttributeStyleTemplate): string;
295
- /**
296
- * Default inline style for the product image `<img>` (used when nothing is captured).
297
- * `width: 100%` is inline so the image shrinks even where the `.adapt-img` media rule is dropped.
298
- */
299
- export declare const DEFAULT_IMG_STYLE = "display: block; width: 100%; max-width: 100%; height: auto;";
295
+ /** Default inline style for the product image `<img>` (used when nothing is captured). */
296
+ export declare const DEFAULT_IMG_STYLE = "display: block; max-width: 100%; height: auto;";
300
297
  /** Default inline style for the button `<span class="es-button-border">`. */
301
298
  export declare const DEFAULT_BUTTON_BORDER_STYLE: string;
302
299
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@useinsider/guido",
3
- "version": "3.20.0-beta.12889e0",
3
+ "version": "3.20.0-beta.13006ea",
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",
@@ -1,7 +0,0 @@
1
- /** Reads one inline style property (Stripo `getStyle` or CSSOM `getPropertyValue`). */
2
- export type StyleReader = (property: string) => string | null | undefined;
3
- export type FluidImageStyleChanges = Partial<Record<'width' | 'max-width' | 'height', string>>;
4
- export declare function getFluidImageStyleChanges(readStyle: StyleReader, widthAttr?: string | null): FluidImageStyleChanges;
5
- export declare const FLUID_IMAGE_CLASS = "recommendation-block-v2";
6
- export declare const FLUID_IMAGE_SELECTOR = ".recommendation-block-v2 .adapt-img";
7
- export declare const FLUID_IMAGE_MOBILE_RULE: string;
@@ -1,26 +0,0 @@
1
- const c = /^(\d+(?:\.\d+)?)px$/i;
2
- function o(t) {
3
- return (t ?? "").trim().toLowerCase();
4
- }
5
- function e(t) {
6
- const n = o(t).match(c);
7
- return n && parseFloat(n[1]) > 0 ? `${n[1]}px` : null;
8
- }
9
- function h(t) {
10
- const n = (t ?? "").trim();
11
- return /^\d+$/.test(n) && parseInt(n) > 0 ? `${parseInt(n)}px` : null;
12
- }
13
- function r(t, n) {
14
- return e(t("width")) ?? e(t("max-width")) ?? h(n) ?? "100%";
15
- }
16
- function d(t, n) {
17
- const i = {}, a = r(t, n);
18
- return o(t("width")) !== "100%" && (i.width = "100%"), o(t("max-width")) !== a && (i["max-width"] = a), o(t("height")) || (i.height = "auto"), i;
19
- }
20
- const s = "recommendation-block-v2", m = `.${s} .adapt-img`, u = `@media only screen and (max-width: 600px) { ${m} { max-width: 100% !important; } }`;
21
- export {
22
- s as FLUID_IMAGE_CLASS,
23
- u as FLUID_IMAGE_MOBILE_RULE,
24
- m as FLUID_IMAGE_SELECTOR,
25
- d as getFluidImageStyleChanges
26
- };