@useinsider/guido 3.21.0-beta.6e25977 → 3.21.0-beta.78e343a

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.
@@ -7,13 +7,13 @@ function L(t, r, e, o, c = "") {
7
7
  const i = `{{${c}${t}_${r}_${e}}}`, n = `{{${c}${t}_${r}_currency}}`;
8
8
  return o === "before" ? `${n} ${i}` : `${i} ${n}`;
9
9
  }
10
- function _(t) {
10
+ function A(t) {
11
11
  let r = t;
12
12
  for (; r.children.length === 1; )
13
13
  [r] = r.children;
14
14
  return r;
15
15
  }
16
- function A(t, r, e, o, c, i) {
16
+ function y(t, r, e, o, c, i) {
17
17
  switch (r) {
18
18
  case "productImage": {
19
19
  const n = t.querySelector("img");
@@ -24,7 +24,7 @@ function A(t, r, e, o, c, i) {
24
24
  }
25
25
  case "productName": {
26
26
  const n = t.querySelector("p");
27
- n && (_(n).textContent = `{{${i}${e}_${o}_name}}`);
27
+ n && (A(n).textContent = `{{${i}${e}_${o}_name}}`);
28
28
  break;
29
29
  }
30
30
  // Inline mode ("Move to next line" OFF) merges BOTH prices into one row
@@ -32,16 +32,16 @@ function A(t, r, e, o, c, i) {
32
32
  // substitute by cell content, not by the row's anchor (SD-145161).
33
33
  case "productPrice":
34
34
  case "productOldPrice": {
35
- const n = (l, d) => {
36
- l && (_(l).textContent = L(
35
+ const n = (a, l) => {
36
+ a && (A(a).textContent = L(
37
37
  e,
38
38
  o,
39
- d,
39
+ l,
40
40
  c,
41
41
  i
42
42
  ));
43
- }, s = t.querySelector(".product-price p"), a = t.querySelector(".product-old-price p"), u = !s && !a ? t.querySelector("p") : null;
44
- n(s ?? (r === "productPrice" ? u : null), "price"), n(a ?? (r === "productOldPrice" ? u : null), "original_price");
43
+ }, s = t.querySelector(".product-price p"), d = t.querySelector(".product-old-price p"), u = !s && !d ? t.querySelector("p") : null;
44
+ n(s ?? (r === "productPrice" ? u : null), "price"), n(d ?? (r === "productOldPrice" ? u : null), "original_price");
45
45
  break;
46
46
  }
47
47
  case "productButton": {
@@ -70,8 +70,8 @@ function A(t, r, e, o, c, i) {
70
70
  default: {
71
71
  const n = t.getAttribute("product-attr") ? t : t.querySelector("[product-attr]");
72
72
  if (n) {
73
- const s = n.getAttribute("product-attr"), a = n.querySelector("p");
74
- a && (_(a).textContent = `{{${i}${e}_${o}_${s}}}`);
73
+ const s = n.getAttribute("product-attr"), d = n.querySelector("p");
74
+ d && (A(d).textContent = `{{${i}${e}_${o}_${s}}}`);
75
75
  }
76
76
  break;
77
77
  }
@@ -88,54 +88,54 @@ function b(t, r, e, o) {
88
88
  function R(t, r, e) {
89
89
  return b(t, r, 0, e);
90
90
  }
91
- function D(t, r, e, o) {
91
+ function w(t, r, e, o) {
92
92
  if (!t.innerHTML.includes("{{"))
93
93
  return;
94
94
  const { open: c, close: i } = b(t.ownerDocument, r, e, o);
95
95
  t.insertBefore(c, t.firstChild), t.appendChild(i);
96
96
  }
97
- function w(t, r, e, o) {
97
+ function D(t, r, e, o) {
98
98
  var n, s;
99
99
  if (!t.innerHTML.includes("{{"))
100
100
  return;
101
101
  const { open: c, close: i } = b(t.ownerDocument, r, e, o);
102
102
  (n = t.parentNode) == null || n.insertBefore(c, t), (s = t.parentNode) == null || s.insertBefore(i, t.nextSibling);
103
103
  }
104
- function W(t, r, e, o) {
104
+ function v(t, r, e, o) {
105
105
  t.querySelectorAll(".recommendation-product-row").forEach((i, n) => {
106
- i.querySelectorAll("[data-attribute-type]").forEach((a) => {
107
- const u = a.getAttribute("data-attribute-type") || "", l = a.querySelectorAll(".attribute-cell");
108
- l.length > 0 ? l.forEach((d) => {
109
- A(d, u, r, n, e, o);
110
- }) : A(a, u, r, n, e, o);
111
- }), w(i, r, n, o);
106
+ i.querySelectorAll("[data-attribute-type]").forEach((d) => {
107
+ const u = d.getAttribute("data-attribute-type") || "", a = d.querySelectorAll(".attribute-cell");
108
+ a.length > 0 ? a.forEach((l) => {
109
+ y(l, u, r, n, e, o);
110
+ }) : y(d, u, r, n, e, o);
111
+ }), D(i, r, n, o);
112
112
  });
113
113
  }
114
- function v(t, r, e, o) {
114
+ function H(t, r, e, o) {
115
115
  const c = t.querySelectorAll(".recommendation-product-row");
116
116
  if (!c.length)
117
117
  return;
118
118
  const [i] = c, n = i.querySelector("[data-attribute-type]"), s = n ? n.querySelectorAll(".attribute-cell").length : 1;
119
- c.forEach((a, u) => {
120
- a.querySelectorAll("[data-attribute-type]").forEach((d) => {
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);
119
+ c.forEach((d, u) => {
120
+ d.querySelectorAll("[data-attribute-type]").forEach((l) => {
121
+ const p = l.getAttribute("data-attribute-type") || "";
122
+ l.querySelectorAll(".attribute-cell").forEach((f, h) => {
123
+ const S = u * s + h;
124
+ y(f, p, r, S, e, o), w(f, r, S, o);
125
125
  });
126
126
  });
127
127
  });
128
128
  }
129
- function H(t, r, e, o) {
129
+ function W(t, r, e, o) {
130
130
  t.querySelectorAll(".ins-recommendation-product-container").forEach((i) => {
131
- v(i, r, e, o);
131
+ H(i, r, e, o);
132
132
  });
133
133
  }
134
134
  function F(t, r, e) {
135
135
  const o = t.getAttribute("data-layout") || "grid", c = t.getAttribute("currency-alignment") || "after";
136
- o === "list" ? W(t, r, c, e) : H(t, r, c, e);
136
+ o === "list" ? v(t, r, c, e) : W(t, r, c, e);
137
137
  }
138
- function y(t, r, e) {
138
+ function _(t, r, e) {
139
139
  const o = new RegExp(`${r}\\s*:\\s*(\\d+)\\s*px`, "i"), c = t.match(o);
140
140
  return c ? parseInt(c[1]) : e;
141
141
  }
@@ -150,7 +150,7 @@ function C(t) {
150
150
  const e = (t.getAttribute("style") || "").match(/(?:^|[;\s])width\s*:\s*(\d+(?:\.\d+)?(?:px|%))/i);
151
151
  return e && $(e[1]) ? e[1] : null;
152
152
  }
153
- function G(t, r) {
153
+ function x(t, r) {
154
154
  let e = t.parentElement;
155
155
  for (; e && e !== r; ) {
156
156
  if (e.tagName === "TD" && C(e))
@@ -159,35 +159,37 @@ function G(t, r) {
159
159
  }
160
160
  return null;
161
161
  }
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);
162
+ function G(t) {
163
+ const r = t.getAttribute("style") || "", e = _(r, "width", 600), o = _(r, "padding", 0) * 2, c = Math.max(0, e - o);
164
164
  c !== 0 && t.querySelectorAll("img.adapt-img").forEach((i) => {
165
165
  if (i.hasAttribute("width"))
166
166
  return;
167
- const n = G(i, t);
167
+ const n = x(i, t);
168
168
  if (!n)
169
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`);
170
+ const s = C(n), d = _(n.getAttribute("style") || "", "padding", 0) * 2, u = s.endsWith("%") ? Math.floor(c * parseFloat(s) / 100) : parseInt(s), a = Math.max(1, u - d), l = i.getAttribute("style") || "", p = /(?:^|[;\s])max-height\s*:\s*(\d+(?:\.\d+)?)px/i.exec(l);
171
+ if (p) {
172
+ i.setAttribute("width", String(Math.max(1, Math.min(a, Math.floor(parseFloat(p[1])))))), i.removeAttribute("height");
173
+ return;
174
+ }
175
+ if (i.setAttribute("width", String(a)), !/\bwidth\s*:\s*\d/i.test(l)) {
176
+ const m = l && !l.trim().endsWith(";") ? "; " : "";
177
+ i.setAttribute("style", `${l}${m}width: ${a}px`);
176
178
  }
177
179
  });
178
180
  }
179
- const E = "MSO_MOBILE_HIDE_START", U = "MSO_MOBILE_HIDE_END";
180
- function X(t, r) {
181
+ const E = "MSO_MOBILE_HIDE_START", V = "MSO_MOBILE_HIDE_END";
182
+ function U(t, r) {
181
183
  t.querySelectorAll(q).forEach((e) => {
182
184
  var i, n;
183
185
  const o = e.querySelector(M);
184
186
  if (!o || o.children.length === 0)
185
187
  return;
186
188
  const c = e.previousSibling;
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));
189
+ (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(V), e.nextSibling));
188
190
  });
189
191
  }
190
- function j(t, r) {
192
+ function X(t, r) {
191
193
  const e = t.match(/<!DOCTYPE[^>]*>/i);
192
194
  return (e ? `${e[0]}
193
195
  ` : "") + r.documentElement.outerHTML;
@@ -200,17 +202,17 @@ function Q(t) {
200
202
  i.recommendationCampaignUrls = {};
201
203
  const { isFeatureEnabled: n } = g(), s = n("liquidSyntax") ? "reco_" : "";
202
204
  return o.forEach((u) => {
203
- var d, p, S, f;
204
- const l = u.getAttribute("recommendation-id");
205
- if (l) {
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);
205
+ var l, p, m, f;
206
+ const a = u.getAttribute("recommendation-id");
207
+ if (a) {
208
+ if ((l = u.parentNode) == null || l.insertBefore(e.createComment("REC_START"), u), (p = u.parentNode) == null || p.insertBefore(e.createComment("REC_END"), u.nextSibling), u.querySelectorAll('[data-visibility="0"]').forEach((h) => h.remove()), c(a), U(u, e), !T(u)) {
209
+ F(u, a, s);
210
+ const { open: h, close: S } = R(e, a, s);
211
+ (m = u.parentNode) == null || m.insertBefore(h, u), (f = u.parentNode) == null || f.insertBefore(S, u.nextSibling);
210
212
  }
211
- V(u);
213
+ G(u);
212
214
  }
213
- }), j(r, e).replaceAll("<!--{%", "{%").replaceAll("%}-->", "%}").replaceAll("&lt;!--{%", "{%").replaceAll("%}--&gt;", "%}");
215
+ }), X(r, e).replaceAll("<!--{%", "{%").replaceAll("%}-->", "%}").replaceAll("&lt;!--{%", "{%").replaceAll("%}--&gt;", "%}");
214
216
  }
215
217
  export {
216
218
  L as formatPriceVariable,
@@ -1,23 +1,24 @@
1
- var B = Object.defineProperty;
2
- var b = (a, l, t) => l in a ? B(a, l, { enumerable: !0, configurable: !0, writable: !0, value: t }) : a[l] = t;
3
- var d = (a, l, t) => b(a, typeof l != "symbol" ? l + "" : l, t);
1
+ var y = Object.defineProperty;
2
+ var B = (a, c, t) => c in a ? y(a, c, { enumerable: !0, configurable: !0, writable: !0, value: t }) : a[c] = t;
3
+ var d = (a, c, t) => B(a, typeof c != "symbol" ? c + "" : c, t);
4
4
  import { useConfig as g } from "../../../composables/useConfig.js";
5
5
  import { BlockId as C } from "../../../enums/block.js";
6
6
  import { getMigrationBannerHtml as A } from "../../../utils/migrationBannerHtml.js";
7
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 w } from "./constants/defaultConfig.js";
8
+ import { CURRENT_CONFIG_VERSION as N, PRE_RRS_CONFIG_VERSION as M } from "./constants/defaultConfig.js";
9
9
  import { RECOMMENDATION_ID_ATTR as m } from "./constants/selectors.js";
10
- import { regenerateMobileProductRows as M } from "./controls/main/utils.js";
11
- import { ensureMobileCssRulesExist as I, setMobileLayoutOptOut as R, hasMobileLayoutOptOut as O } from "./controls/mobileLayout/cssRules.js";
10
+ import { ensureMobileFitRule as w } from "./controls/image/index.js";
11
+ import { regenerateMobileProductRows as O } from "./controls/main/utils.js";
12
+ import { ensureMobileCssRulesExist as I, setMobileLayoutOptOut as R, hasMobileLayoutOptOut as x } from "./controls/mobileLayout/cssRules.js";
12
13
  import { RecommendationConfigService as s } from "./services/configService.js";
13
14
  import { useRecommendationExtensionStore as h } from "./store/recommendation.js";
14
- import { getDefaultTemplate as x } from "./templates/grid/template.js";
15
- import { useRecommendationBlockWarning as T } from "./useRecommendationBlockWarning.js";
15
+ import { getDefaultTemplate as T } from "./templates/grid/template.js";
16
+ import { useRecommendationBlockWarning as F } from "./useRecommendationBlockWarning.js";
16
17
  import { registerNodeConfigWriter as H } from "./utils/nodeConfigWriter.js";
17
18
  import { refreshDuplicatedStrategyBlocks as $ } from "./utils/strategyCommit.js";
18
- const k = C.Recommendation, u = "recommendation-block-v2", D = "hide-price";
19
- let y = !1;
20
- class Y extends E {
19
+ const k = C.Recommendation, u = "recommendation-block-v2", b = "hide-price";
20
+ let D = !1;
21
+ class tt extends E {
21
22
  constructor() {
22
23
  super();
23
24
  /**
@@ -72,7 +73,7 @@ class Y extends E {
72
73
  */
73
74
  getTemplate() {
74
75
  const t = this._generateNextId();
75
- return this._pendingBlockId = t, x(t);
76
+ return this._pendingBlockId = t, T(t);
76
77
  }
77
78
  /**
78
79
  * Called when a new block is dropped into the template
@@ -84,7 +85,7 @@ class Y extends E {
84
85
  onCreated(t) {
85
86
  const e = this._getRecommendationId(t);
86
87
  if (e !== null && e > 0) {
87
- if (this._detectDuplicate(e)) {
88
+ if (this._ensureMobileFitRule(t), this._detectDuplicate(e)) {
88
89
  this._handleDuplicate(t, e), this._scheduleArrivalReset(t);
89
90
  return;
90
91
  }
@@ -95,12 +96,12 @@ class Y extends E {
95
96
  }
96
97
  const i = this._pendingBlockId ?? this._generateNextId();
97
98
  this._pendingBlockId = null, this._assignRecommendationId(t, i);
98
- const n = g().isFeatureEnabled("reusableRecommendationStrategy"), o = n && !s.hasConfig(t), { config: r, wasFreshDrop: c } = s.initializeConfig(
99
+ const n = g().isFeatureEnabled("reusableRecommendationStrategy"), o = n && !s.hasConfig(t), { config: r, wasFreshDrop: l } = s.initializeConfig(
99
100
  this.api,
100
101
  t,
101
102
  {
102
103
  recommendationId: i,
103
- configVersion: n ? N : w,
104
+ configVersion: n ? N : M,
104
105
  ...o ? { partnerName: g().partnerName.value } : {},
105
106
  // An RRS block picks a strategy, not an algorithm, and its algorithm control is
106
107
  // hidden. Keeping the `mostPopular` default would bake a most-popular feed URL
@@ -108,10 +109,10 @@ class Y extends E {
108
109
  ...o ? { strategy: "" } : {}
109
110
  }
110
111
  ), f = h();
111
- if (f.setCurrentBlock(i), this._stampHidePrice(t, r.priceHideIfSameAsDiscounted), c) {
112
+ if (f.setCurrentBlock(i), this._stampHidePrice(t, r.priceHideIfSameAsDiscounted), l) {
112
113
  I(this.api);
113
114
  const _ = this._getBlockElement(t);
114
- _ && (R(this.api, _, !0), M({
115
+ _ && (R(this.api, _, !0), O({
115
116
  currentNode: t,
116
117
  documentModifier: this.api.getDocumentModifier()
117
118
  }));
@@ -136,13 +137,13 @@ class Y extends E {
136
137
  "Assign recommendation ID to legacy block"
137
138
  );
138
139
  }
139
- this._healLingeringDuplicate(t), s.needsMigration(t) && this._migrateFromLegacy(t), this._healHidePriceAttr(t);
140
+ this._healLingeringDuplicate(t), s.needsMigration(t) && this._migrateFromLegacy(t), this._healHidePriceAttr(t), this._ensureMobileFitRule(t);
140
141
  try {
141
- y || (I(this.api), y = !0);
142
+ D || (I(this.api), D = !0);
142
143
  const e = s.getConfig(t), i = this._getBlockElement(t);
143
144
  if (i) {
144
145
  const n = !e.mobileLayoutEnabled;
145
- O(i) !== n && R(this.api, i, n);
146
+ x(i) !== n && R(this.api, i, n);
146
147
  }
147
148
  } catch {
148
149
  }
@@ -158,6 +159,12 @@ class Y extends E {
158
159
  const e = this._getRecommendationId(t);
159
160
  e && h().removeBlockState(e);
160
161
  }
162
+ _ensureMobileFitRule(t) {
163
+ try {
164
+ w(this.api, t);
165
+ } catch {
166
+ }
167
+ }
161
168
  /**
162
169
  * Warns (dark advisory toaster) when the design holds more than one live
163
170
  * recommendation block. Triggered from the user-add paths only (fresh drop
@@ -172,7 +179,7 @@ class Y extends E {
172
179
  */
173
180
  _warnIfMultipleBlocks() {
174
181
  try {
175
- T().warnIfMultipleBlocks(this.api.getDocumentRootHtmlNode());
182
+ F().warnIfMultipleBlocks(this.api.getDocumentRootHtmlNode());
176
183
  } catch {
177
184
  }
178
185
  }
@@ -187,8 +194,8 @@ class Y extends E {
187
194
  const i = this.api.getDocumentRoot();
188
195
  i && "querySelectorAll" in i && i.querySelectorAll(`.${u}`).forEach((o) => {
189
196
  if ("getAttribute" in o) {
190
- const r = o.getAttribute(m), c = r ? parseInt(r) : 0;
191
- e.add(c), c > t && (t = c);
197
+ const r = o.getAttribute(m), l = r ? parseInt(r) : 0;
198
+ e.add(l), l > t && (t = l);
192
199
  }
193
200
  });
194
201
  } catch {
@@ -238,9 +245,9 @@ class Y extends E {
238
245
  if (!o)
239
246
  return;
240
247
  let r = -1;
241
- for (let c = 0; c < n.length; c++)
242
- if (n[c] === o) {
243
- r = c;
248
+ for (let l = 0; l < n.length; l++)
249
+ if (n[l] === o) {
250
+ r = l;
244
251
  break;
245
252
  }
246
253
  if (r <= 0)
@@ -320,7 +327,7 @@ class Y extends E {
320
327
  */
321
328
  _stampHidePrice(t, e) {
322
329
  const i = this._getBlockElement(t);
323
- i && this.api.getDocumentModifier().modifyHtml(i).setAttribute(D, String(e)).apply(new p("Stamp hide-price"));
330
+ i && this.api.getDocumentModifier().modifyHtml(i).setAttribute(b, String(e)).apply(new p("Stamp hide-price"));
324
331
  }
325
332
  /**
326
333
  * Stamps `hide-price` from config only when the block lacks the attribute —
@@ -328,7 +335,7 @@ class Y extends E {
328
335
  */
329
336
  _healHidePriceAttr(t) {
330
337
  const e = this._getBlockElement(t);
331
- if (!e || !("getAttribute" in e) || e.getAttribute(D) !== null)
338
+ if (!e || !("getAttribute" in e) || e.getAttribute(b) !== null)
332
339
  return;
333
340
  const { priceHideIfSameAsDiscounted: i } = s.getConfig(t);
334
341
  this._stampHidePrice(t, i);
@@ -366,5 +373,5 @@ class Y extends E {
366
373
  }
367
374
  export {
368
375
  k as BLOCK_ID,
369
- Y as RecommendationBlock
376
+ tt as RecommendationBlock
370
377
  };
@@ -1,19 +1,63 @@
1
- import { createImageMarginsControl as m, createImageSizeControl as n } from "../../../controlFactories.js";
2
- import { RecommendationBlockId as o } from "../../constants/blockIds.js";
3
- import { RecommendationControlId as r } from "../../constants/controlIds.js";
4
- import { BLOCK_ROOT_SELECTOR as t } from "../../constants/selectors.js";
5
- const e = n(
6
- r.IMAGE_SIZE,
7
- o.IMAGE,
8
- t
9
- ), i = m(
10
- r.IMAGE_MARGINS,
11
- o.IMAGE,
12
- t
13
- ), C = {
14
- size: e,
15
- margins: i
1
+ import { EditorStatePropertyType as S, PreviewDeviceMode as E, ModificationDescription as y } from "../../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
2
+ import { createImageMarginsControl as I, createImageSizeControl as M } from "../../../controlFactories.js";
3
+ import { RecommendationBlockId as d } from "../../constants/blockIds.js";
4
+ import { RecommendationControlId as u } from "../../constants/controlIds.js";
5
+ import { BLOCK_ROOT_SELECTOR as l } from "../../constants/selectors.js";
6
+ import { hasGetStyle as g } from "../../utils/tagName.js";
7
+ const C = { width: "", height: "auto", "max-height": "" }, h = `${l} img.adapt-img`, R = `*${l.slice(1)}`, f = `@media only screen and (max-width: 600px) { ${h} { max-height: none !important; } }`;
8
+ function O(t) {
9
+ return { width: "auto", height: "auto", "max-height": `${t}px` };
10
+ }
11
+ function T(t) {
12
+ return t.querySelectorAll(R).some((e) => "getSelector" in e && e.getSelector() === h);
13
+ }
14
+ function _(t, e) {
15
+ return g(t) && Object.entries(e).some(([i, o]) => (t.getStyle(i) ?? "") !== o);
16
+ }
17
+ function p(t) {
18
+ const e = t.getDocumentRootCssNode();
19
+ return e && !T(e) ? e : null;
20
+ }
21
+ function G(t, e) {
22
+ const o = e.querySelectorAll("img").some((r) => g(r) && !!r.getStyle("max-height")) ? p(t) : null;
23
+ if (!o)
24
+ return;
25
+ const n = t.getDocumentModifier();
26
+ n.modifyCss(o).appendRule(f), n.apply(new y("Add the reco image mobile fit rule"));
27
+ }
28
+ class x extends M(
29
+ u.IMAGE_SIZE,
30
+ d.IMAGE,
31
+ l
32
+ ) {
33
+ getAdditionalModifications(e) {
34
+ if (this.api.getEditorState()[S.previewDeviceMode] === E.MOBILE)
35
+ return;
36
+ const i = this.getFitStyles(), o = this.getTargetNodes(e).map((s) => s.querySelector("img")).filter((s) => _(s, i)), n = i["max-height"] ? p(this.api) : null;
37
+ if (!o.length && !n)
38
+ return;
39
+ const r = this.api.getDocumentModifier();
40
+ return n && r.modifyCss(n).appendRule(f), o.forEach((s) => {
41
+ const a = r.modifyHtml(s);
42
+ Object.entries(i).forEach(([c, m]) => {
43
+ m ? a.setStyle(c, m) : a.removeStyle(c);
44
+ });
45
+ }), r;
46
+ }
47
+ getFitStyles() {
48
+ const { size: e } = this.api.getValues();
49
+ return (e == null ? void 0 : e.type) === "height" && e.value ? O(e.value) : C;
50
+ }
51
+ }
52
+ const A = I(
53
+ u.IMAGE_MARGINS,
54
+ d.IMAGE,
55
+ l
56
+ ), b = {
57
+ size: x,
58
+ margins: A
16
59
  };
17
60
  export {
18
- C as ImageControls
61
+ b as ImageControls,
62
+ G as ensureMobileFitRule
19
63
  };
@@ -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 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";
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";
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 O, hasGetComputedStyle as M } from "./tagName.js";
7
+ import { hasQuerySelectorAll as I, hasGetAttribute as l, hasGetStyle as h, hasGetComputedStyle as M } from "./tagName.js";
8
8
  const s = [
9
9
  "font-size",
10
10
  "font-family",
@@ -37,9 +37,10 @@ const s = [
37
37
  "width",
38
38
  "height",
39
39
  "max-width",
40
+ "max-height",
40
41
  "border-radius",
41
42
  "margin"
42
- ], g = /* @__PURE__ */ new Set(["transparent", "rgba(0, 0, 0, 0)"]), L = [
43
+ ], b = /* @__PURE__ */ new Set(["transparent", "rgba(0, 0, 0, 0)"]), L = [
43
44
  { attrKey: k, blockId: c.NAME, kind: "text" },
44
45
  { attrKey: y, blockId: c.PRICE, kind: "text" },
45
46
  { attrKey: p, blockId: c.OLD_PRICE, kind: "text" },
@@ -48,14 +49,14 @@ const s = [
48
49
  { attrKey: x, blockId: c.BUTTON, kind: "button" },
49
50
  { attrKey: q, blockId: c.IMAGE, kind: "image" }
50
51
  ];
51
- function h(t) {
52
+ function O(t) {
52
53
  return t && "getInnerHTML" in t && typeof t.getInnerHTML == "function" ? t.getInnerHTML().trim() : "";
53
54
  }
54
55
  function K(t) {
55
56
  return t && "getInnerText" in t && typeof t.getInnerText == "function" ? t.getInnerText().trim() : "";
56
57
  }
57
58
  function a(t, e, r) {
58
- !e || !O(e) || r.forEach((n) => {
59
+ !e || !h(e) || r.forEach((n) => {
59
60
  const o = e.getStyle(n);
60
61
  o && o !== "inherit" && o !== "initial" && (t[n] = o);
61
62
  });
@@ -64,10 +65,10 @@ function E(t) {
64
65
  return Object.entries(t).map(([e, r]) => `${e}: ${r};`).join(" ");
65
66
  }
66
67
  function P(t) {
67
- if (!t || !O(t))
68
+ if (!t || !h(t))
68
69
  return;
69
70
  const e = t.getStyle("background-color") || t.getStyle("background");
70
- return e && !g.has(e) ? e : void 0;
71
+ return e && !b.has(e) ? e : void 0;
71
72
  }
72
73
  function S(t, e) {
73
74
  const r = {};
@@ -76,11 +77,11 @@ function S(t, e) {
76
77
  function $(t) {
77
78
  const e = t.querySelector("p"), r = {};
78
79
  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 = E(r), { openTags: o, closeTags: i } = A(h(e));
80
+ const n = E(r), { openTags: o, closeTags: i } = A(O(e));
80
81
  return !n && !o ? null : { pStyle: n || void 0, openTags: o, closeTags: i };
81
82
  }
82
83
  function H(t) {
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);
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);
84
85
  return !n && !o && !u && !T && !m ? null : {
85
86
  buttonBorderStyle: n || void 0,
86
87
  buttonAnchorStyle: o || void 0,
@@ -100,7 +101,7 @@ function j(t, e) {
100
101
  function f(t, e) {
101
102
  if (!t || !("querySelector" in t))
102
103
  return;
103
- const r = t.querySelector(b) ?? t;
104
+ const r = t.querySelector(g) ?? t;
104
105
  if (L.forEach(({ attrKey: i, blockId: u, kind: T }) => {
105
106
  const d = r.querySelector(`[esd-extension-block-id="${u}"]`);
106
107
  d && e(d, i, T);
@@ -126,20 +127,20 @@ function V(t) {
126
127
  function X(t) {
127
128
  if (!t || !("querySelector" in t))
128
129
  return;
129
- const e = t.querySelector(b) ?? t, r = e.querySelector(".product-card-segment") ?? e.querySelector(".product-card-wrapper");
130
+ const e = t.querySelector(g) ?? t, r = e.querySelector(".product-card-segment") ?? e.querySelector(".product-card-wrapper");
130
131
  return P(r);
131
132
  }
132
133
  function z(t) {
133
134
  if (!t)
134
135
  return;
135
136
  const e = l(t) ? t.getAttribute("bgcolor") : null;
136
- if (e && !g.has(e))
137
+ if (e && !b.has(e))
137
138
  return e;
138
139
  const r = P(t);
139
140
  if (r)
140
141
  return r;
141
142
  const n = M(t) ? t.getComputedStyle("background-color") : void 0;
142
- return n && !g.has(n) ? n : void 0;
143
+ return n && !b.has(n) ? n : void 0;
143
144
  }
144
145
  function Q(t) {
145
146
  const e = {};
@@ -170,7 +171,7 @@ function J(t) {
170
171
  function Z(t) {
171
172
  if (!t || !("querySelector" in t))
172
173
  return !1;
173
- const e = t.querySelector(b) ?? t;
174
+ const e = t.querySelector(g) ?? t;
174
175
  return C(e.querySelector(`[data-attribute-type="${y}"]`)) || C(e.querySelector(`[data-attribute-type="${p}"]`));
175
176
  }
176
177
  function tt(t) {
@@ -195,7 +196,7 @@ function rt(t) {
195
196
  const e = {};
196
197
  if (!t || !("querySelector" in t))
197
198
  return e;
198
- const r = t.querySelector(b) ?? t;
199
+ const r = t.querySelector(g) ?? t;
199
200
  return I(r) && r.querySelectorAll(".recommendation-attribute-row").forEach((n) => {
200
201
  if (!l(n))
201
202
  return;
@@ -59,6 +59,7 @@ export declare class RecommendationBlock extends Block {
59
59
  * @param node - The block node being deleted
60
60
  */
61
61
  onDelete(node: ImmutableHtmlNode): void;
62
+ private _ensureMobileFitRule;
62
63
  /**
63
64
  * Warns (dark advisory toaster) when the design holds more than one live
64
65
  * recommendation block. Triggered from the user-add paths only (fresh drop
@@ -3,35 +3,48 @@
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
+ }
6
30
  /**
7
31
  * Grouped Image Controls
8
32
  * Use this object for cleaner imports in extension.ts
9
33
  */
10
34
  export declare const ImageControls: {
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
- };
35
+ readonly size: typeof SizeControl;
24
36
  readonly margins: {
25
37
  new (): {
26
38
  getId(): string;
27
- getTargetNodes(root: import("@stripoinc/ui-editor-extensions").ImmutableHtmlNode): import("@stripoinc/ui-editor-extensions").ImmutableHtmlNode[];
39
+ getTargetNodes(root: ImmutableHtmlNode): ImmutableHtmlNode[];
28
40
  getParentControlId(): string;
29
41
  api: import("@stripoinc/ui-editor-extensions").ControlApi;
30
42
  getLabels(): import("@stripoinc/ui-editor-extensions").ControlLabels | undefined;
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;
43
+ getModificationDescription(): ModificationDescription | undefined;
44
+ getAdditionalModifications(_root: ImmutableHtmlNode): TemplateModifier<HtmlNodeModifier, CssNodeModifier> | undefined;
45
+ isVisible(_node: ImmutableHtmlNode): boolean;
34
46
  getElementLockCategory(): import("@stripoinc/ui-editor-extensions").ElementLockCategory | undefined;
35
47
  };
36
48
  };
37
49
  };
50
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@useinsider/guido",
3
- "version": "3.21.0-beta.6e25977",
3
+ "version": "3.21.0-beta.78e343a",
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",