@useinsider/guido 3.2.0-beta.22a0c4c → 3.2.0-beta.250b0a1

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.
Files changed (19) hide show
  1. package/dist/config/compiler/utils/recommendationCompilerUtils.js +30 -33
  2. package/dist/config/migrator/radioButtonMigrator.js +56 -48
  3. package/dist/config/migrator/recommendationMigrator.js +1 -1
  4. package/dist/extensions/Blocks/Recommendation/constants/controlIds.js +1 -1
  5. package/dist/extensions/Blocks/Recommendation/controls/customAttribute/index.js +18 -21
  6. package/dist/extensions/Blocks/Recommendation/controls/main/algorithm.js +6 -6
  7. package/dist/extensions/Blocks/Recommendation/controls/main/index.js +1 -3
  8. package/dist/extensions/Blocks/Recommendation/controls/name/textTrim.js +57 -27
  9. package/dist/extensions/Blocks/Recommendation/settingsPanel.js +17 -18
  10. package/dist/extensions/Blocks/Recommendation/store/recommendation.js +25 -29
  11. package/dist/extensions/Blocks/Recommendation/templates/list/template.js +11 -11
  12. package/dist/src/extensions/Blocks/Recommendation/constants/controlIds.d.ts +0 -1
  13. package/dist/src/extensions/Blocks/Recommendation/controls/customAttribute/index.d.ts +0 -3
  14. package/dist/src/extensions/Blocks/Recommendation/controls/name/textTrim.d.ts +20 -3
  15. package/package.json +1 -1
  16. package/dist/extensions/Blocks/Recommendation/controls/customAttribute/textTrim.js +0 -99
  17. package/dist/extensions/Blocks/Recommendation/controls/shared/textTrimCssRules.js +0 -14
  18. package/dist/src/extensions/Blocks/Recommendation/controls/customAttribute/textTrim.d.ts +0 -35
  19. package/dist/src/extensions/Blocks/Recommendation/controls/shared/textTrimCssRules.d.ts +0 -29
@@ -1,11 +1,10 @@
1
1
  import { useConfig as S } from "../../../composables/useConfig.js";
2
2
  import { useRecommendation as _ } from "../../../composables/useRecommendation.js";
3
- import { useRecommendationExtensionStore as d } from "../../../extensions/Blocks/Recommendation/store/recommendation.js";
4
3
  function y(e, u, r, o, s = "") {
5
4
  const n = `{{${s}${e}_${u}_${r}}}`, t = `{{${s}${e}_${u}_currency}}`;
6
5
  return o === "before" ? `${t} ${n}` : `${n} ${t}`;
7
6
  }
8
- function m(e, u, r, o, s, n) {
7
+ function p(e, u, r, o, s, n) {
9
8
  switch (u) {
10
9
  case "productImage": {
11
10
  const t = e.querySelector("img");
@@ -70,69 +69,67 @@ function m(e, u, r, o, s, n) {
70
69
  default: {
71
70
  const t = e.getAttribute("product-attr") ? e : e.querySelector("[product-attr]");
72
71
  if (t) {
73
- const c = t.getAttribute("product-attr"), a = t.querySelector("p");
74
- if (a) {
75
- const i = a.querySelector("strong") || a;
76
- i.textContent = `{{${n}${r}_${o}_${c}}}`;
72
+ const c = t.getAttribute("product-attr"), i = t.querySelector("p");
73
+ if (i) {
74
+ const a = i.querySelector("strong") || i;
75
+ a.textContent = `{{${n}${r}_${o}_${c}}}`;
77
76
  }
78
77
  }
79
78
  break;
80
79
  }
81
80
  }
82
81
  }
83
- function q(e, u, r, o) {
82
+ function d(e, u, r, o) {
84
83
  e.querySelectorAll(".recommendation-product-row").forEach((n, t) => {
85
- n.querySelectorAll("[data-attribute-type]").forEach((a) => {
86
- const i = a.getAttribute("data-attribute-type") || "", l = a.querySelectorAll(".attribute-cell");
87
- l.length > 0 ? l.forEach((p) => {
88
- m(p, i, u, t, r, o);
89
- }) : m(a, i, u, t, r, o);
84
+ n.querySelectorAll("[data-attribute-type]").forEach((i) => {
85
+ const a = i.getAttribute("data-attribute-type") || "", b = i.querySelectorAll(".attribute-cell");
86
+ b.length > 0 ? b.forEach((l) => {
87
+ p(l, a, u, t, r, o);
88
+ }) : p(i, a, u, t, r, o);
90
89
  });
91
90
  });
92
91
  }
93
- function g(e, u, r, o) {
92
+ function q(e, u, r, o) {
94
93
  const s = e.querySelectorAll(".recommendation-product-row");
95
94
  if (!s.length)
96
95
  return;
97
96
  const [n] = s, t = n.querySelector("[data-attribute-type]"), c = t ? t.querySelectorAll(".attribute-cell").length : 1;
98
- s.forEach((a, i) => {
99
- a.querySelectorAll("[data-attribute-type]").forEach((p) => {
100
- const b = p.getAttribute("data-attribute-type") || "";
101
- p.querySelectorAll(".attribute-cell").forEach((f, $) => {
102
- const A = i * c + $;
103
- m(f, b, u, A, r, o);
97
+ s.forEach((i, a) => {
98
+ i.querySelectorAll("[data-attribute-type]").forEach((l) => {
99
+ const m = l.getAttribute("data-attribute-type") || "";
100
+ l.querySelectorAll(".attribute-cell").forEach(($, f) => {
101
+ const A = a * c + f;
102
+ p($, m, u, A, r, o);
104
103
  });
105
104
  });
106
105
  });
107
106
  }
108
- function h(e, u, r, o) {
107
+ function g(e, u, r, o) {
109
108
  e.querySelectorAll(".ins-recommendation-product-container").forEach((n) => {
110
- g(n, u, r, o);
109
+ q(n, u, r, o);
111
110
  });
112
111
  }
113
- function C(e, u, r) {
112
+ function h(e, u, r) {
114
113
  const o = e.getAttribute("data-layout") || "grid", s = e.getAttribute("currency-alignment") || "after";
115
- o === "list" ? q(e, u, s, r) : h(e, u, s, r);
114
+ o === "list" ? d(e, u, s, r) : g(e, u, s, r);
116
115
  }
117
- function E(e, u) {
116
+ function C(e, u) {
118
117
  const r = e.match(/<!DOCTYPE[^>]*>/i);
119
118
  return (r ? `${r[0]}
120
119
  ` : "") + u.documentElement.outerHTML;
121
120
  }
122
- function T(e) {
121
+ function P(e) {
123
122
  const u = e.replaceAll("{%", "<!--{%").replaceAll("%}", "%}-->"), r = new DOMParser().parseFromString(u, "text/html"), o = r.querySelectorAll(".recommendation-block-v2");
124
123
  if (!o.length)
125
124
  return e;
126
- const { buildCampaignUrl: s } = _(), n = d();
127
- n.recommendationCampaignUrls = {};
128
- const { isFeatureEnabled: t } = S(), c = t("liquidSyntax") ? "reco_" : "";
125
+ const { buildCampaignUrl: s } = _(), { isFeatureEnabled: n } = S(), t = n("liquidSyntax") ? "reco_" : "";
129
126
  return o.forEach((i) => {
130
- var p, b;
131
- const l = i.getAttribute("recommendation-id");
132
- l && ((p = i.parentNode) == null || p.insertBefore(r.createComment("REC_START"), i), (b = i.parentNode) == null || b.insertBefore(r.createComment("REC_END"), i.nextSibling), s(l), C(i, l, c));
133
- }), E(u, r).replaceAll("<!--{%", "{%").replaceAll("%}-->", "%}").replaceAll("&lt;!--{%", "{%").replaceAll("%}--&gt;", "%}");
127
+ var b, l;
128
+ const a = i.getAttribute("recommendation-id");
129
+ a && ((b = i.parentNode) == null || b.insertBefore(r.createComment("REC_START"), i), (l = i.parentNode) == null || l.insertBefore(r.createComment("REC_END"), i.nextSibling), s(a), h(i, a, t));
130
+ }), C(u, r).replaceAll("<!--{%", "{%").replaceAll("%}-->", "%}").replaceAll("&lt;!--{%", "{%").replaceAll("%}--&gt;", "%}");
134
131
  }
135
132
  export {
136
133
  y as formatPriceVariable,
137
- T as prepareRecommendationBlocks
134
+ P as prepareRecommendationBlocks
138
135
  };
@@ -1,87 +1,95 @@
1
- var x = Object.defineProperty;
2
- var f = (r, t, e) => t in r ? x(r, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : r[t] = e;
3
- var b = (r, t, e) => f(r, typeof t != "symbol" ? t + "" : t, e);
4
- import h from "../../extensions/Blocks/RadioButton/template.js";
5
- class T {
1
+ var f = Object.defineProperty;
2
+ var h = (o, e, t) => e in o ? f(o, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : o[e] = t;
3
+ var y = (o, e, t) => h(o, typeof e != "symbol" ? e + "" : e, t);
4
+ import T from "../../extensions/Blocks/RadioButton/template.js";
5
+ class S {
6
6
  constructor() {
7
- b(this, "parser");
7
+ y(this, "parser");
8
8
  this.parser = new DOMParser();
9
9
  }
10
- migrate(t) {
10
+ migrate(e) {
11
11
  try {
12
- const e = this.parser.parseFromString(t, "text/html"), i = e.querySelectorAll("td.radio-button-block");
13
- return i.length === 0 ? t : (i.forEach((s) => {
14
- if (s.classList.contains("radio-button-v2"))
12
+ const t = this.parser.parseFromString(e, "text/html"), s = t.querySelectorAll("td.radio-button-block"), i = t.querySelectorAll("td.radio-button-v2");
13
+ return s.length === 0 && i.length === 0 ? e : (s.forEach((r) => {
14
+ if (r.classList.contains("radio-button-v2"))
15
15
  return;
16
- const n = s.getAttribute("id"), l = this.extractTextFromElement(s, "ins-title"), a = this.extractTextFromElement(s, "ins-description"), p = this.extractTextFromElement(s, "ins-subscribe"), u = this.extractTextFromElement(s, "ins-unsubscribe"), d = this.buildTextBlock(l), g = this.buildTextBlock(a), m = this.buildTextBlock({ ...p, classList: "" }), o = this.buildTextBlock({ ...u, classList: "" }), c = h.replace("{-{-TITLE-}-}", d).replace("{-{-DESCRIPTION-}-}", g).replace("{-{-YES-}-}", m).replace("{-{-NO-}-}", o), y = this.parser.parseFromString(
17
- `<table id="tempDoc"><tbody><tr>${c}</tr></tbody></table>`,
16
+ const l = r.getAttribute("id"), n = this.extractTextFromElement(r, "ins-title"), c = this.extractTextFromElement(r, "ins-description"), a = this.extractTextFromElement(r, "ins-subscribe"), p = this.extractTextFromElement(r, "ins-unsubscribe"), g = this.buildTextBlock(n), m = this.buildTextBlock(c), d = this.buildTextBlock({ ...a, classList: "" }), u = this.buildTextBlock({ ...p, classList: "" }), x = T.replace("{-{-TITLE-}-}", g).replace("{-{-DESCRIPTION-}-}", m).replace("{-{-YES-}-}", d).replace("{-{-NO-}-}", u), b = this.parser.parseFromString(
17
+ `<table id="tempDoc"><tbody><tr>${x}</tr></tbody></table>`,
18
18
  "text/html"
19
19
  ).querySelector(".radio-button-v2");
20
- y && s.parentNode && (y.setAttribute("id", n || ""), s.parentNode.replaceChild(y, s));
21
- }), e.documentElement.outerHTML);
22
- } catch (e) {
23
- return console.error("RadioButtonMigrator failed:", e), t;
20
+ b && r.parentNode && (b.setAttribute("id", l || ""), r.parentNode.replaceChild(b, r));
21
+ }), t.querySelectorAll("td.radio-button-v2 input#radioYes").forEach((r) => {
22
+ var a, p;
23
+ const l = (a = r.parentElement) == null ? void 0 : a.querySelector(":scope > p"), n = (p = r.parentElement) == null ? void 0 : p.parentElement;
24
+ if (!l || (n == null ? void 0 : n.tagName) !== "TR")
25
+ return;
26
+ r.removeAttribute("esd-block-text");
27
+ const c = t.createElement("td");
28
+ c.className = "esd-block-text", c.appendChild(l), n.appendChild(c);
29
+ }), t.documentElement.outerHTML);
30
+ } catch (t) {
31
+ return console.error("RadioButtonMigrator failed:", t), e;
24
32
  }
25
33
  }
26
- extractTextFromElement(t, e) {
27
- var o, c;
28
- const i = t.querySelector(`.${e}`);
29
- if (!i)
34
+ extractTextFromElement(e, t) {
35
+ var d, u;
36
+ const s = e.querySelector(`.${t}`);
37
+ if (!s)
30
38
  return {
31
- text: e === "ins-title" ? "Title" : "Description",
39
+ text: t === "ins-title" ? "Title" : "Description",
32
40
  isBold: !1,
33
41
  isItalic: !1,
34
42
  align: "left",
35
43
  styles: "",
36
44
  classList: ""
37
45
  };
38
- const s = i.querySelector("p");
39
- if (!s)
46
+ const i = s.querySelector("p");
47
+ if (!i)
40
48
  return {
41
- text: ((o = i.textContent) == null ? void 0 : o.trim()) || (e === "ins-title" ? "Title" : "Description"),
49
+ text: ((d = s.textContent) == null ? void 0 : d.trim()) || (t === "ins-title" ? "Title" : "Description"),
42
50
  isBold: !1,
43
51
  isItalic: !1,
44
- align: i.getAttribute("align") || "left",
52
+ align: s.getAttribute("align") || "left",
45
53
  styles: "",
46
54
  classList: ""
47
55
  };
48
- const n = ((c = s.textContent) == null ? void 0 : c.trim()) || (e === "ins-title" ? "Title" : "Description"), l = s.getAttribute("style") || "", a = i.getAttribute("align") || s.getAttribute("align") || "left", p = /font-weight\s*:\s*bold/i.test(l) || !!s.querySelector("b, strong"), u = /font-style\s*:\s*italic/i.test(l) || !!s.querySelector("i, em"), d = this.removeStyleProperties(l, ["font-weight", "font-style"]), g = this.convertInlineToBlock(d), m = i.getAttribute("class") || "";
56
+ const r = ((u = i.textContent) == null ? void 0 : u.trim()) || (t === "ins-title" ? "Title" : "Description"), l = i.getAttribute("style") || "", n = s.getAttribute("align") || i.getAttribute("align") || "left", c = /font-weight\s*:\s*bold/i.test(l) || !!i.querySelector("b, strong"), a = /font-style\s*:\s*italic/i.test(l) || !!i.querySelector("i, em"), p = this.removeStyleProperties(l, ["font-weight", "font-style"]), g = this.convertInlineToBlock(p), m = s.getAttribute("class") || "";
49
57
  return {
50
- text: n,
51
- isBold: p,
52
- isItalic: u,
53
- align: a,
58
+ text: r,
59
+ isBold: c,
60
+ isItalic: a,
61
+ align: n,
54
62
  styles: g,
55
63
  classList: m
56
64
  };
57
65
  }
58
- buildTextBlock(t) {
59
- let e = t.text;
60
- t.isBold && t.isItalic ? e = `<strong path="1,0"><em path="1,0,0">${e}</em></strong>` : t.isBold ? e = `<strong path="1,0">${e}</strong>` : t.isItalic && (e = `<em path="1,0">${e}</em>`);
61
- const i = t.align ? ` align="${t.align}"` : "", s = t.styles ? ` style="${t.styles.replaceAll('"', "'")}"` : "";
66
+ buildTextBlock(e) {
67
+ let t = e.text;
68
+ e.isBold && e.isItalic ? t = `<strong path="1,0"><em path="1,0,0">${t}</em></strong>` : e.isBold ? t = `<strong path="1,0">${t}</strong>` : e.isItalic && (t = `<em path="1,0">${t}</em>`);
69
+ const s = e.align ? ` align="${e.align}"` : "", i = e.styles ? ` style="${e.styles.replaceAll('"', "'")}"` : "";
62
70
  return `
63
- <td class="esd-block-text ${t.classList}" ${i}>
64
- <p path="1" ${s}>
65
- ${e}
71
+ <td class="esd-block-text ${e.classList}" ${s}>
72
+ <p path="1" ${i}>
73
+ ${t}
66
74
  </p>
67
75
  </td>
68
76
  `;
69
77
  }
70
- removeStyleProperties(t, e) {
71
- return t ? e.reduce((s, n) => {
72
- const l = new RegExp(`${n}\\s*:\\s*[^;]*;?`, "gi");
73
- return s.replace(l, "");
74
- }, t).replace(/;\s*;/g, ";").replace(/^;|;$/g, "").trim() : "";
78
+ removeStyleProperties(e, t) {
79
+ return e ? t.reduce((i, r) => {
80
+ const l = new RegExp(`${r}\\s*:\\s*[^;]*;?`, "gi");
81
+ return i.replace(l, "");
82
+ }, e).replace(/;\s*;/g, ";").replace(/^;|;$/g, "").trim() : "";
75
83
  }
76
- convertInlineToBlock(t) {
77
- if (!t)
84
+ convertInlineToBlock(e) {
85
+ if (!e)
78
86
  return "";
79
- let e = t.replace(/display\s*:\s*inline/gi, "display: block");
80
- return /display\s*:/i.test(e) || (e = e ? `${e}; display: block` : "display: block"), e.replace(/;\s*;/g, ";").replace(/^;|;$/g, "").trim();
87
+ let t = e.replace(/display\s*:\s*inline/gi, "display: block");
88
+ return /display\s*:/i.test(t) || (t = t ? `${t}; display: block` : "display: block"), t.replace(/;\s*;/g, ";").replace(/^;|;$/g, "").trim();
81
89
  }
82
90
  }
83
- function A(r) {
84
- return new T().migrate(r);
91
+ function A(o) {
92
+ return new S().migrate(o);
85
93
  }
86
94
  export {
87
95
  A as migrateRadioButton
@@ -13,7 +13,7 @@ class B {
13
13
  migrate(e) {
14
14
  try {
15
15
  const t = this.parser.parseFromString(e, "text/html"), s = t.querySelectorAll(
16
- 'td.ins-recommendation-v3-block-1:not(.recommendation-block-v2), td.product-block[esd-handler-name*="EmailRecommendationV3"]:not(.recommendation-block-v2)'
16
+ 'td.ins-recommendation-v3-block-1, td.product-block[esd-handler-name*="EmailRecommendationV3"]'
17
17
  );
18
18
  return w().$patch((i) => {
19
19
  i.migrations = { ...i.migrations, [S]: s.length };
@@ -1,4 +1,4 @@
1
- var o = /* @__PURE__ */ ((c) => (c.BUTTON_ALIGN = "recommendation-block-button-align-control", c.BUTTON_BORDER = "recommendation-block-button-border-control", c.BUTTON_BORDER_RADIUS = "recommendation-block-button-border-radius-control", c.BUTTON_COLOR = "recommendation-block-button-color-control", c.BUTTON_FIT_TO_CONTENT = "recommendation-block-button-fit-to-content-control", c.BUTTON_FONT_FAMILY = "recommendation-block-button-font-family-control", c.BUTTON_MARGINS = "recommendation-block-button-margins-control", c.BUTTON_PADDINGS = "recommendation-block-button-paddings-control", c.BUTTON_TEXT = "recommendation-block-button-text-control", c.BUTTON_TEXT_SIZE = "recommendation-block-button-text-size-control", c.BUTTON_TEXT_STYLE_AND_FONT_COLOR = "recommendation-block-button-text-style-and-font-color-control", c.NAME_ALIGN = "recommendation-block-name-align-control", c.NAME_BACKGROUND = "recommendation-block-name-background-control", c.NAME_COLOR = "recommendation-block-name-color-control", c.NAME_FONT_FAMILY = "recommendation-block-name-font-family-control", c.NAME_PADDINGS = "recommendation-block-name-paddings-control", c.NAME_SIZE = "recommendation-block-name-size-control", c.NAME_STYLE = "recommendation-block-name-style-control", c.NAME_TEXT_TRIM = "recommendation-block-name-text-trim-control", c.PRICE_ALIGN = "recommendation-block-price-align-control", c.PRICE_BACKGROUND = "recommendation-block-price-background-control", c.PRICE_COLOR = "recommendation-block-price-color-control", c.PRICE_FONT_FAMILY = "recommendation-block-price-font-family-control", c.PRICE_PADDINGS = "recommendation-block-price-paddings-control", c.PRICE_SIZE = "recommendation-block-price-size-control", c.PRICE_STYLE = "recommendation-block-price-style-control", c.OLD_PRICE_ALIGN = "recommendation-block-old-price-align-control", c.OLD_PRICE_BACKGROUND = "recommendation-block-old-price-background-control", c.OLD_PRICE_COLOR = "recommendation-block-old-price-color-control", c.OLD_PRICE_FONT_FAMILY = "recommendation-block-old-price-font-family-control", c.OLD_PRICE_PADDINGS = "recommendation-block-old-price-paddings-control", c.OLD_PRICE_SIZE = "recommendation-block-old-price-size-control", c.OLD_PRICE_STYLE = "recommendation-block-old-price-style-control", c.OMNIBUS_PRICE_ALIGN = "recommendation-block-omnibus-price-align-control", c.OMNIBUS_PRICE_BACKGROUND = "recommendation-block-omnibus-price-background-control", c.OMNIBUS_PRICE_COLOR = "recommendation-block-omnibus-price-color-control", c.OMNIBUS_PRICE_FONT_FAMILY = "recommendation-block-omnibus-price-font-family-control", c.OMNIBUS_PRICE_PADDINGS = "recommendation-block-omnibus-price-paddings-control", c.OMNIBUS_PRICE_SIZE = "recommendation-block-omnibus-price-size-control", c.OMNIBUS_PRICE_STYLE = "recommendation-block-omnibus-price-style-control", c.OMNIBUS_PRICE_TEXT_BEFORE = "recommendation-block-omnibus-price-text-before-control", c.OMNIBUS_PRICE_TEXT_AFTER = "recommendation-block-omnibus-price-text-after-control", c.OMNIBUS_DISCOUNT_ALIGN = "recommendation-block-omnibus-discount-align-control", c.OMNIBUS_DISCOUNT_BACKGROUND = "recommendation-block-omnibus-discount-background-control", c.OMNIBUS_DISCOUNT_COLOR = "recommendation-block-omnibus-discount-color-control", c.OMNIBUS_DISCOUNT_FONT_FAMILY = "recommendation-block-omnibus-discount-font-family-control", c.OMNIBUS_DISCOUNT_PADDINGS = "recommendation-block-omnibus-discount-paddings-control", c.OMNIBUS_DISCOUNT_SIZE = "recommendation-block-omnibus-discount-size-control", c.OMNIBUS_DISCOUNT_STYLE = "recommendation-block-omnibus-discount-style-control", c.OMNIBUS_DISCOUNT_TEXT_BEFORE = "recommendation-block-omnibus-discount-text-before-control", c.OMNIBUS_DISCOUNT_TEXT_AFTER = "recommendation-block-omnibus-discount-text-after-control", c.IMAGE_SIZE = "recommendation-block-image-size-control", c.IMAGE_MARGINS = "recommendation-block-image-margins-control", c.CUSTOM_ATTR_ALIGN = "recommendation-block-custom-attr-align-control", c.CUSTOM_ATTR_BACKGROUND = "recommendation-block-custom-attr-background-control", c.CUSTOM_ATTR_COLOR = "recommendation-block-custom-attr-color-control", c.CUSTOM_ATTR_FONT_FAMILY = "recommendation-block-custom-attr-font-family-control", c.CUSTOM_ATTR_PADDINGS = "recommendation-block-custom-attr-paddings-control", c.CUSTOM_ATTR_SIZE = "recommendation-block-custom-attr-size-control", c.CUSTOM_ATTR_STYLE = "recommendation-block-custom-attr-style-control", c.CUSTOM_ATTR_TEXT_TRIM = "recommendation-block-custom-attr-text-trim-control", c.SYNC_INFO_MESSAGE = "recommendation-block-sync-info-message", c))(o || {});
1
+ var o = /* @__PURE__ */ ((c) => (c.BUTTON_ALIGN = "recommendation-block-button-align-control", c.BUTTON_BORDER = "recommendation-block-button-border-control", c.BUTTON_BORDER_RADIUS = "recommendation-block-button-border-radius-control", c.BUTTON_COLOR = "recommendation-block-button-color-control", c.BUTTON_FIT_TO_CONTENT = "recommendation-block-button-fit-to-content-control", c.BUTTON_FONT_FAMILY = "recommendation-block-button-font-family-control", c.BUTTON_MARGINS = "recommendation-block-button-margins-control", c.BUTTON_PADDINGS = "recommendation-block-button-paddings-control", c.BUTTON_TEXT = "recommendation-block-button-text-control", c.BUTTON_TEXT_SIZE = "recommendation-block-button-text-size-control", c.BUTTON_TEXT_STYLE_AND_FONT_COLOR = "recommendation-block-button-text-style-and-font-color-control", c.NAME_ALIGN = "recommendation-block-name-align-control", c.NAME_BACKGROUND = "recommendation-block-name-background-control", c.NAME_COLOR = "recommendation-block-name-color-control", c.NAME_FONT_FAMILY = "recommendation-block-name-font-family-control", c.NAME_PADDINGS = "recommendation-block-name-paddings-control", c.NAME_SIZE = "recommendation-block-name-size-control", c.NAME_STYLE = "recommendation-block-name-style-control", c.NAME_TEXT_TRIM = "recommendation-block-name-text-trim-control", c.PRICE_ALIGN = "recommendation-block-price-align-control", c.PRICE_BACKGROUND = "recommendation-block-price-background-control", c.PRICE_COLOR = "recommendation-block-price-color-control", c.PRICE_FONT_FAMILY = "recommendation-block-price-font-family-control", c.PRICE_PADDINGS = "recommendation-block-price-paddings-control", c.PRICE_SIZE = "recommendation-block-price-size-control", c.PRICE_STYLE = "recommendation-block-price-style-control", c.OLD_PRICE_ALIGN = "recommendation-block-old-price-align-control", c.OLD_PRICE_BACKGROUND = "recommendation-block-old-price-background-control", c.OLD_PRICE_COLOR = "recommendation-block-old-price-color-control", c.OLD_PRICE_FONT_FAMILY = "recommendation-block-old-price-font-family-control", c.OLD_PRICE_PADDINGS = "recommendation-block-old-price-paddings-control", c.OLD_PRICE_SIZE = "recommendation-block-old-price-size-control", c.OLD_PRICE_STYLE = "recommendation-block-old-price-style-control", c.OMNIBUS_PRICE_ALIGN = "recommendation-block-omnibus-price-align-control", c.OMNIBUS_PRICE_BACKGROUND = "recommendation-block-omnibus-price-background-control", c.OMNIBUS_PRICE_COLOR = "recommendation-block-omnibus-price-color-control", c.OMNIBUS_PRICE_FONT_FAMILY = "recommendation-block-omnibus-price-font-family-control", c.OMNIBUS_PRICE_PADDINGS = "recommendation-block-omnibus-price-paddings-control", c.OMNIBUS_PRICE_SIZE = "recommendation-block-omnibus-price-size-control", c.OMNIBUS_PRICE_STYLE = "recommendation-block-omnibus-price-style-control", c.OMNIBUS_PRICE_TEXT_BEFORE = "recommendation-block-omnibus-price-text-before-control", c.OMNIBUS_PRICE_TEXT_AFTER = "recommendation-block-omnibus-price-text-after-control", c.OMNIBUS_DISCOUNT_ALIGN = "recommendation-block-omnibus-discount-align-control", c.OMNIBUS_DISCOUNT_BACKGROUND = "recommendation-block-omnibus-discount-background-control", c.OMNIBUS_DISCOUNT_COLOR = "recommendation-block-omnibus-discount-color-control", c.OMNIBUS_DISCOUNT_FONT_FAMILY = "recommendation-block-omnibus-discount-font-family-control", c.OMNIBUS_DISCOUNT_PADDINGS = "recommendation-block-omnibus-discount-paddings-control", c.OMNIBUS_DISCOUNT_SIZE = "recommendation-block-omnibus-discount-size-control", c.OMNIBUS_DISCOUNT_STYLE = "recommendation-block-omnibus-discount-style-control", c.OMNIBUS_DISCOUNT_TEXT_BEFORE = "recommendation-block-omnibus-discount-text-before-control", c.OMNIBUS_DISCOUNT_TEXT_AFTER = "recommendation-block-omnibus-discount-text-after-control", c.IMAGE_SIZE = "recommendation-block-image-size-control", c.IMAGE_MARGINS = "recommendation-block-image-margins-control", c.CUSTOM_ATTR_ALIGN = "recommendation-block-custom-attr-align-control", c.CUSTOM_ATTR_BACKGROUND = "recommendation-block-custom-attr-background-control", c.CUSTOM_ATTR_COLOR = "recommendation-block-custom-attr-color-control", c.CUSTOM_ATTR_FONT_FAMILY = "recommendation-block-custom-attr-font-family-control", c.CUSTOM_ATTR_PADDINGS = "recommendation-block-custom-attr-paddings-control", c.CUSTOM_ATTR_SIZE = "recommendation-block-custom-attr-size-control", c.CUSTOM_ATTR_STYLE = "recommendation-block-custom-attr-style-control", c.SYNC_INFO_MESSAGE = "recommendation-block-sync-info-message", c))(o || {});
2
2
  export {
3
3
  o as RecommendationControlId
4
4
  };
@@ -1,22 +1,21 @@
1
- import { TextPaddingsBuiltInControl as d, ButtonBackgroundColorBuiltInControl as i, TextFontFamilyBuiltInControl as u, TextStyleBuiltInControl as c, TextSizeBuiltInControl as C, TextColorBuiltInControl as g, TextAlignBuiltInControl as a } from "../../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
1
+ import { TextPaddingsBuiltInControl as d, ButtonBackgroundColorBuiltInControl as c, TextFontFamilyBuiltInControl as u, TextStyleBuiltInControl as i, TextSizeBuiltInControl as C, TextColorBuiltInControl as g, TextAlignBuiltInControl as a } from "../../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
2
2
  import { RecommendationBlockId as l } from "../../constants/blockIds.js";
3
3
  import { RecommendationControlId as e } from "../../constants/controlIds.js";
4
- import { BLOCK_ROOT_SELECTOR as A, ATTR_PRODUCT_ATTR as s } from "../../constants/selectors.js";
5
- import { CustomAttributeTextTrimControl as I } from "./textTrim.js";
4
+ import { BLOCK_ROOT_SELECTOR as I, ATTR_PRODUCT_ATTR as s } from "../../constants/selectors.js";
6
5
  function o(t) {
7
- const r = t.closest(A);
8
- if (!r)
6
+ const n = t.closest(I);
7
+ if (!n)
9
8
  return [];
10
- const n = t.asElement().getAttribute(s);
11
- if (n) {
12
- const T = `[esd-extension-block-id="${l.CUSTOM_ATTRIBUTE}"][${s}="${n}"]`;
13
- return r.querySelectorAll(T);
9
+ const r = t.asElement().getAttribute(s);
10
+ if (r) {
11
+ const T = `[esd-extension-block-id="${l.CUSTOM_ATTRIBUTE}"][${s}="${r}"]`;
12
+ return n.querySelectorAll(T);
14
13
  }
15
- return r.querySelectorAll(
14
+ return n.querySelectorAll(
16
15
  `[esd-extension-block-id="${l.CUSTOM_ATTRIBUTE}"]`
17
16
  );
18
17
  }
19
- const m = class extends a {
18
+ const A = class extends a {
20
19
  getId() {
21
20
  return e.CUSTOM_ATTR_ALIGN;
22
21
  }
@@ -37,7 +36,7 @@ const m = class extends a {
37
36
  getTargetNodes(t) {
38
37
  return o(t);
39
38
  }
40
- }, x = class extends c {
39
+ }, m = class extends i {
41
40
  getId() {
42
41
  return e.CUSTOM_ATTR_STYLE;
43
42
  }
@@ -51,31 +50,29 @@ const m = class extends a {
51
50
  getTargetNodes(t) {
52
51
  return o(t);
53
52
  }
54
- }, R = class extends i {
53
+ }, R = class extends c {
55
54
  getId() {
56
55
  return e.CUSTOM_ATTR_BACKGROUND;
57
56
  }
58
57
  getTargetNodes(t) {
59
58
  return o(t);
60
59
  }
61
- }, B = class extends d {
60
+ }, x = class extends d {
62
61
  getId() {
63
62
  return e.CUSTOM_ATTR_PADDINGS;
64
63
  }
65
64
  getTargetNodes(t) {
66
65
  return o(t);
67
66
  }
68
- }, p = {
69
- align: m,
67
+ }, k = {
68
+ align: A,
70
69
  color: _,
71
70
  size: S,
72
- style: x,
71
+ style: m,
73
72
  fontFamily: O,
74
73
  background: R,
75
- paddings: B,
76
- textTrim: I
74
+ paddings: x
77
75
  };
78
76
  export {
79
- p as CustomAttributeControls,
80
- I as CustomAttributeTextTrimControl
77
+ k as CustomAttributeControls
81
78
  };
@@ -1,7 +1,7 @@
1
- var l = Object.defineProperty;
2
- var c = (s, i, t) => i in s ? l(s, i, { enumerable: !0, configurable: !0, writable: !0, value: t }) : s[i] = t;
3
- var a = (s, i, t) => c(s, typeof i != "symbol" ? i + "" : i, t);
4
- import { UEAttr as h } from "../../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
1
+ var c = Object.defineProperty;
2
+ var h = (s, i, t) => i in s ? c(s, i, { enumerable: !0, configurable: !0, writable: !0, value: t }) : s[i] = t;
3
+ var a = (s, i, t) => h(s, typeof i != "symbol" ? i + "" : i, t);
4
+ import { UEAttr as l } from "../../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
5
5
  import { CommonControl as d } from "../../../common-control.js";
6
6
  import { RecommendationConfigService as n } from "../../services/configService.js";
7
7
  import { useRecommendationExtensionStore as m } from "../../store/recommendation.js";
@@ -42,7 +42,7 @@ class T extends d {
42
42
  this._initializeSelectItems(), this._setFormValues(), this._listenToFormUpdates();
43
43
  }
44
44
  onTemplateNodeUpdated(t) {
45
- super.onTemplateNodeUpdated(t), this._initializeSelectItems(), this._setFormValues();
45
+ super.onTemplateNodeUpdated(t), this._setFormValues();
46
46
  }
47
47
  _setFormValues() {
48
48
  const t = n.getConfig(this.currentNode);
@@ -58,7 +58,7 @@ class T extends d {
58
58
  try {
59
59
  this.api.setUIEAttribute(
60
60
  e.ALGORITHM,
61
- h.SELECTPICKER.items,
61
+ l.SELECTPICKER.items,
62
62
  t
63
63
  );
64
64
  } catch (r) {
@@ -114,9 +114,7 @@ class H extends g {
114
114
  var r;
115
115
  super.onTemplateNodeUpdated(t);
116
116
  const e = this._getRecommendationIdFromNode(t);
117
- e !== null && e !== this.store.currentRecommendationId && this.store.setCurrentBlock(e), e !== null && this._syncNodeConfigToStore(), e !== null && !((r = this.store.blockStates[e]) != null && r.isInitialized) && this._fetchBlockData(e).then(() => {
118
- this._initializeSubControls();
119
- }), [
117
+ e !== null && e !== this.store.currentRecommendationId && this.store.setCurrentBlock(e), this._syncNodeConfigToStore(), e !== null && !((r = this.store.blockStates[e]) != null && r.isInitialized) && this._fetchBlockData(e), [
120
118
  this.layoutOrientationControl,
121
119
  this.productCountControl,
122
120
  this.algorithmControl,
@@ -1,15 +1,14 @@
1
- import { ModificationDescription as l } from "../../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
2
- import { CommonControl as u } from "../../../common-control.js";
3
- import { RecommendationBlockId as a } from "../../constants/blockIds.js";
4
- import { RecommendationControlId as d } from "../../constants/controlIds.js";
5
- import { BLOCK_ROOT_SELECTOR as m } from "../../constants/selectors.js";
6
- import { CSS_CLASS_TEXT_TRIM as r, ensureTextTrimCssRulesExist as T } from "../shared/textTrimCssRules.js";
7
- const s = {
1
+ import { ModificationDescription as a } from "../../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
2
+ import { CommonControl as d } from "../../../common-control.js";
3
+ import { RecommendationBlockId as l } from "../../constants/blockIds.js";
4
+ import { RecommendationControlId as m } from "../../constants/controlIds.js";
5
+ import { BLOCK_ROOT_SELECTOR as u } from "../../constants/selectors.js";
6
+ const i = {
8
7
  TEXT_TRIM_ENABLED: "textTrimEnabled"
9
- };
10
- class N extends u {
8
+ }, o = "text-trim-enabled", c = `.${o}`, T = `.${o} p`, p = `.${o} { max-width: 0; }`, _ = `.${o} p { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; margin: 0; display: block; }`;
9
+ class N extends d {
11
10
  getId() {
12
- return d.NAME_TEXT_TRIM;
11
+ return m.NAME_TEXT_TRIM;
13
12
  }
14
13
  getTemplate() {
15
14
  return `
@@ -17,7 +16,7 @@ class N extends u {
17
16
  <div class="name-text-trim-control-container">
18
17
  ${this._GuTwoColumns([
19
18
  this._GuLabel({ text: this.api.translate("Trim Long Text") }),
20
- this._GuToggle(s.TEXT_TRIM_ENABLED)
19
+ this._GuToggle(i.TEXT_TRIM_ENABLED)
21
20
  ])}
22
21
  </div>
23
22
  `;
@@ -31,45 +30,76 @@ class N extends u {
31
30
  _setFormValues() {
32
31
  const e = this._getCurrentTrimState();
33
32
  this.api.updateValues({
34
- [s.TEXT_TRIM_ENABLED]: e
33
+ [i.TEXT_TRIM_ENABLED]: e
35
34
  });
36
35
  }
37
36
  _getCurrentTrimState() {
38
37
  if (!this.currentNode || !("hasClass" in this.currentNode))
39
38
  return !1;
40
- if (this.currentNode.hasClass(r))
39
+ if (this.currentNode.hasClass(o))
41
40
  return !0;
42
- const e = this.currentNode.closest(m);
41
+ const e = this.currentNode.closest(u);
43
42
  if (!e)
44
43
  return !1;
45
44
  const t = e.querySelector(
46
- `[esd-extension-block-id="${a.NAME}"]`
45
+ `[esd-extension-block-id="${l.NAME}"]`
47
46
  );
48
- return t && "hasClass" in t ? t.hasClass(r) : !1;
47
+ return t && "hasClass" in t ? t.hasClass(o) : !1;
48
+ }
49
+ /**
50
+ * Finds an existing CSS rule in the document stylesheet by exact query
51
+ * @param query - The CSS query to search for (uses Stripo's CSS query syntax)
52
+ * @returns The CSS rule node if found, undefined otherwise
53
+ */
54
+ _findCssRule(e) {
55
+ const t = this.api.getDocumentRootCssNode();
56
+ if (t)
57
+ return t.querySelector(e);
58
+ }
59
+ /**
60
+ * Finds the .text-trim-enabled p rule by searching all text-trim rules and comparing selectors
61
+ * This is needed because Stripo's CSS query syntax interprets spaces as path separators
62
+ * @returns true if the rule exists
63
+ */
64
+ _hasParagraphRule() {
65
+ const e = this.api.getDocumentRootCssNode();
66
+ return e ? e.querySelectorAll(`*${o}`).some((s) => "getSelector" in s && typeof s.getSelector == "function" ? s.getSelector() === T : !1) : !1;
67
+ }
68
+ /**
69
+ * Ensures the text-trim CSS rules exist in the document stylesheet
70
+ * Only adds rules if they don't already exist (prevents duplicates across multiple blocks)
71
+ */
72
+ _ensureCssRulesExist() {
73
+ const e = this.api.getDocumentRootCssNode();
74
+ if (!e)
75
+ return;
76
+ const t = this.api.getDocumentModifier();
77
+ let s = !1;
78
+ this._findCssRule(c) || (t.modifyCss(e).appendRule(p), s = !0), this._hasParagraphRule() || (t.modifyCss(e).appendRule(_), s = !0), s && t.apply(new a("Add text trim CSS rules"));
49
79
  }
50
80
  _onTextTrimChange(e) {
51
81
  if (!this.currentNode || !("closest" in this.currentNode))
52
82
  return;
53
- const t = this.currentNode.closest(m);
83
+ const t = this.currentNode.closest(u);
54
84
  if (!t || !("querySelectorAll" in t))
55
85
  return;
56
- const i = Array.from(
57
- t.querySelectorAll(`[esd-extension-block-id="${a.NAME}"]`)
86
+ const s = Array.from(
87
+ t.querySelectorAll(`[esd-extension-block-id="${l.NAME}"]`)
58
88
  );
59
- if (!i.length)
89
+ if (!s.length)
60
90
  return;
61
- e && T(this.api);
62
- const o = this.api.getDocumentModifier();
63
- i.forEach((n) => {
64
- e ? o.modifyHtml(n).setClass(r) : o.modifyHtml(n).removeClass(r);
65
- }), o.apply(
66
- new l(
91
+ e && this._ensureCssRulesExist();
92
+ const r = this.api.getDocumentModifier();
93
+ s.forEach((n) => {
94
+ e ? r.modifyHtml(n).setClass(o) : r.modifyHtml(n).removeClass(o);
95
+ }), r.apply(
96
+ new a(
67
97
  e ? "Enable product name text trimming" : "Disable product name text trimming"
68
98
  )
69
99
  );
70
100
  }
71
101
  _listenToFormUpdates() {
72
- this.api.onValueChanged(s.TEXT_TRIM_ENABLED, (e) => {
102
+ this.api.onValueChanged(i.TEXT_TRIM_ENABLED, (e) => {
73
103
  this._onTextTrimChange(e);
74
104
  });
75
105
  }
@@ -1,6 +1,6 @@
1
1
  import { SettingsPanelRegistry as E, SettingsPanelTab as _, SettingsTab as O, ContainerControls as C, TextControls as R } from "../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
2
2
  import { BLOCK_ID as U } from "./block.js";
3
- import { RecommendationBlockId as S } from "./constants/blockIds.js";
3
+ import { RecommendationBlockId as N } from "./constants/blockIds.js";
4
4
  import { RecommendationControlId as T } from "./constants/controlIds.js";
5
5
  import { CONTROL_BLOCK_ID as A } from "./controls/main/index.js";
6
6
  import "./store/recommendation.js";
@@ -14,7 +14,7 @@ import "./controls/image/index.js";
14
14
  import { SPACING_CONTROL_ID as L } from "./controls/spacing/index.js";
15
15
  import { CARD_BACKGROUND_COLOR_CONTROL_ID as D } from "./controls/cardBackground/index.js";
16
16
  import { COMPOSITION_CONTROL_BLOCK_ID as B } from "./controls/cardComposition/index.js";
17
- import { SYNC_INFO_MESSAGE_CONTROL_ID as N } from "./controls/syncInfoMessage.js";
17
+ import { SYNC_INFO_MESSAGE_CONTROL_ID as S } from "./controls/syncInfoMessage.js";
18
18
  class Z extends E {
19
19
  registerBlockControls(I) {
20
20
  I[U] = [
@@ -39,11 +39,11 @@ class Z extends E {
39
39
  B
40
40
  ]
41
41
  ).withLabel(this.api.translate("Card Composition"))
42
- ], I[S.NAME] = [
42
+ ], I[N.NAME] = [
43
43
  new _(
44
44
  O.SETTINGS,
45
45
  [
46
- N,
46
+ S,
47
47
  T.NAME_STYLE,
48
48
  T.NAME_ALIGN,
49
49
  T.NAME_TEXT_TRIM,
@@ -59,11 +59,11 @@ class Z extends E {
59
59
  T.NAME_COLOR
60
60
  ]
61
61
  )
62
- ], I[S.PRICE] = [
62
+ ], I[N.PRICE] = [
63
63
  new _(
64
64
  O.SETTINGS,
65
65
  [
66
- N,
66
+ S,
67
67
  T.PRICE_STYLE,
68
68
  T.PRICE_ALIGN,
69
69
  T.PRICE_PADDINGS
@@ -78,11 +78,11 @@ class Z extends E {
78
78
  T.PRICE_COLOR
79
79
  ]
80
80
  )
81
- ], I[S.OLD_PRICE] = [
81
+ ], I[N.OLD_PRICE] = [
82
82
  new _(
83
83
  O.SETTINGS,
84
84
  [
85
- N,
85
+ S,
86
86
  T.OLD_PRICE_STYLE,
87
87
  T.OLD_PRICE_ALIGN,
88
88
  T.OLD_PRICE_PADDINGS
@@ -97,11 +97,11 @@ class Z extends E {
97
97
  T.OLD_PRICE_COLOR
98
98
  ]
99
99
  )
100
- ], I[S.OMNIBUS_PRICE] = [
100
+ ], I[N.OMNIBUS_PRICE] = [
101
101
  new _(
102
102
  O.SETTINGS,
103
103
  [
104
- N,
104
+ S,
105
105
  T.OMNIBUS_PRICE_TEXT_BEFORE,
106
106
  T.OMNIBUS_PRICE_TEXT_AFTER,
107
107
  T.OMNIBUS_PRICE_STYLE,
@@ -118,11 +118,11 @@ class Z extends E {
118
118
  T.OMNIBUS_PRICE_COLOR
119
119
  ]
120
120
  )
121
- ], I[S.OMNIBUS_DISCOUNT] = [
121
+ ], I[N.OMNIBUS_DISCOUNT] = [
122
122
  new _(
123
123
  O.SETTINGS,
124
124
  [
125
- N,
125
+ S,
126
126
  T.OMNIBUS_DISCOUNT_TEXT_BEFORE,
127
127
  T.OMNIBUS_DISCOUNT_TEXT_AFTER,
128
128
  T.OMNIBUS_DISCOUNT_STYLE,
@@ -139,11 +139,11 @@ class Z extends E {
139
139
  T.OMNIBUS_DISCOUNT_COLOR
140
140
  ]
141
141
  )
142
- ], I[S.BUTTON] = [
142
+ ], I[N.BUTTON] = [
143
143
  new _(
144
144
  O.SETTINGS,
145
145
  [
146
- N,
146
+ S,
147
147
  T.BUTTON_TEXT,
148
148
  T.BUTTON_ALIGN,
149
149
  T.BUTTON_PADDINGS,
@@ -162,13 +162,12 @@ class Z extends E {
162
162
  T.BUTTON_BORDER
163
163
  ]
164
164
  )
165
- ], I[S.CUSTOM_ATTRIBUTE] = [
165
+ ], I[N.CUSTOM_ATTRIBUTE] = [
166
166
  new _(
167
167
  O.SETTINGS,
168
168
  [
169
169
  T.CUSTOM_ATTR_STYLE,
170
170
  T.CUSTOM_ATTR_ALIGN,
171
- T.CUSTOM_ATTR_TEXT_TRIM,
172
171
  T.CUSTOM_ATTR_PADDINGS
173
172
  ]
174
173
  ),
@@ -181,11 +180,11 @@ class Z extends E {
181
180
  T.CUSTOM_ATTR_COLOR
182
181
  ]
183
182
  )
184
- ], I[S.IMAGE] = [
183
+ ], I[N.IMAGE] = [
185
184
  new _(
186
185
  O.SETTINGS,
187
186
  [
188
- N,
187
+ S,
189
188
  T.IMAGE_SIZE,
190
189
  T.IMAGE_MARGINS
191
190
  ]
@@ -1,14 +1,14 @@
1
1
  import { RecommendationFeedSourceMaps as g, getOperatorOptions as R, PriceAttributes as k } from "../../../../enums/extensions/recommendationBlock.js";
2
- import { useRecommendationApi as C } from "../../../../services/recommendationApi.js";
3
- import { useConfigStore as y } from "../../../../stores/config.js";
2
+ import { useRecommendationApi as y } from "../../../../services/recommendationApi.js";
3
+ import { useConfigStore as C } from "../../../../stores/config.js";
4
4
  import { defineStore as G } from "pinia";
5
5
  import { DEFAULT_CARDS_IN_ROW as F } from "../constants/layout.js";
6
6
  import { EXCLUDED_ALGORITHM_IDS as w } from "../constants/defaultConfig.js";
7
7
  import { getDefaultProducts as S } from "../templates/utils.js";
8
8
  import { generateCompleteFilterQuery as b } from "../utils/filterUtil.js";
9
9
  import { isFilterValid as D } from "../validation/filterSchema.js";
10
- const h = C();
11
- let m = null, u = null, d = null;
10
+ const h = y();
11
+ let u = null, m = null, d = null;
12
12
  function I() {
13
13
  return {
14
14
  cardsInRow: F,
@@ -57,7 +57,7 @@ const v = () => ({
57
57
  blockStates: {},
58
58
  currentRecommendationId: null,
59
59
  configVersion: 0
60
- }), z = G("guidoRecommendationExtension", {
60
+ }), E = G("guidoRecommendationExtension", {
61
61
  state: () => v(),
62
62
  getters: {
63
63
  // ====================================================================
@@ -131,10 +131,11 @@ const v = () => ({
131
131
  })),
132
132
  getFilterList() {
133
133
  return Object.values(this.filterList).map((t) => {
134
- let r;
135
- return t.type === "productAttribute" ? r = `product_attributes.${t.attributeName}` : k.includes(t.attributeName) ? r = `${t.attributeName}.${this.recommendationConfigs.currencySettings.value}` : r = t.attributeName, {
134
+ const r = t.type === "defaultAttribute", e = k.includes(t.attributeName);
135
+ let n = r ? t.attributeName : `product_attributes.${t.attributeName}`;
136
+ return n = e ? `${n}.${this.recommendationConfigs.currencySettings.value}` : n, {
136
137
  text: t.displayName,
137
- value: r,
138
+ value: n,
138
139
  type: t.attributeType
139
140
  };
140
141
  });
@@ -162,15 +163,10 @@ const v = () => ({
162
163
  * Resets currentRecommendationId if it was the deleted block.
163
164
  */
164
165
  removeBlockState(t) {
165
- const r = t.toString();
166
- if (this.recommendationCampaignUrls[r]) {
167
- const n = { ...this.recommendationCampaignUrls };
168
- delete n[r], this.recommendationCampaignUrls = n;
169
- }
170
- const e = { ...this.blockStates };
171
- if (delete e[t], this.blockStates = e, this.currentRecommendationId === t) {
172
- const n = Object.keys(this.blockStates).map(Number);
173
- this.currentRecommendationId = n.length > 0 ? n[0] : null;
166
+ const r = { ...this.blockStates };
167
+ if (delete r[t], this.blockStates = r, this.currentRecommendationId === t) {
168
+ const e = Object.keys(this.blockStates).map(Number);
169
+ this.currentRecommendationId = e.length > 0 ? e[0] : null;
174
170
  }
175
171
  },
176
172
  /**
@@ -255,11 +251,11 @@ const v = () => ({
255
251
  // ====================================================================
256
252
  async fetchRecommendationCreateData() {
257
253
  if (!this.activePredictiveAlgorithms.length) {
258
- if (m) {
259
- await m;
254
+ if (u) {
255
+ await u;
260
256
  return;
261
257
  }
262
- m = (async () => {
258
+ u = (async () => {
263
259
  const {
264
260
  activePredictiveAlgorithms: t,
265
261
  languages: r,
@@ -272,26 +268,26 @@ const v = () => ({
272
268
  this.currencyList = e;
273
269
  })();
274
270
  try {
275
- await m;
271
+ await u;
276
272
  } finally {
277
- m = null;
273
+ u = null;
278
274
  }
279
275
  }
280
276
  },
281
277
  async fetchRecommendationFilters() {
282
278
  if (!Object.keys(this.filterList).length) {
283
- if (u) {
284
- await u;
279
+ if (m) {
280
+ await m;
285
281
  return;
286
282
  }
287
- u = (async () => {
283
+ m = (async () => {
288
284
  const t = await h.fetchRecommendationFilters();
289
285
  this.filterList = t;
290
286
  })();
291
287
  try {
292
- await u;
288
+ await m;
293
289
  } finally {
294
- u = null;
290
+ m = null;
295
291
  }
296
292
  }
297
293
  },
@@ -379,7 +375,7 @@ const v = () => ({
379
375
  },
380
376
  async _doFetchProducts() {
381
377
  var p;
382
- const t = this.currentRecommendationId, r = this.blockStates[t], { recommendationConfigs: e } = r, n = e.filters.filter((a) => a.isValid), c = b(n), i = ((p = g.find((a) => a.key === e.strategy)) == null ? void 0 : p.path) || "", o = y(), s = {
378
+ const t = this.currentRecommendationId, r = this.blockStates[t], { recommendationConfigs: e } = r, n = e.filters.filter((a) => a.isValid), c = b(n), i = ((p = g.find((a) => a.key === e.strategy)) == null ? void 0 : p.path) || "", o = C(), s = {
383
379
  locale: e.language,
384
380
  currency: e.currencySettings.value,
385
381
  partnerName: o.partnerName,
@@ -403,5 +399,5 @@ const v = () => ({
403
399
  }
404
400
  });
405
401
  export {
406
- z as useRecommendationExtensionStore
402
+ E as useRecommendationExtensionStore
407
403
  };
@@ -1,7 +1,7 @@
1
- import { ATTR_PRODUCT_IMAGE as a, ATTR_PRODUCT_BUTTON as d } from "../../constants/selectors.js";
2
- import { DEFAULT_CARD_COMPOSITION as b, spacer as m, buildElementRenderer as C, DEFAULT_CARD_VISIBILITY as T } from "../utils.js";
3
- import { listElementRenderer as f } from "./elementRenderer.js";
4
- function R(r, n, l) {
1
+ import { ATTR_PRODUCT_IMAGE as d, ATTR_PRODUCT_BUTTON as a } from "../../constants/selectors.js";
2
+ import { DEFAULT_CARD_COMPOSITION as m, spacer as C, buildElementRenderer as b, DEFAULT_CARD_VISIBILITY as T } from "../utils.js";
3
+ import { listElementRenderer as R } from "./elementRenderer.js";
4
+ function f(r, n, l) {
5
5
  const t = l ? "" : ' style="display: none;"', o = r.replace(/<tr>/, "").replace(/<\/tr>/, "");
6
6
  return `<tr
7
7
  class="recommendation-attribute-row"
@@ -26,26 +26,26 @@ const y = `
26
26
  </td>
27
27
  </tr>
28
28
  `;
29
- function O(r, n = b, l = {}) {
30
- const t = C(f, n, l), o = t[a](r), c = `
29
+ function O(r, n = m, l = {}) {
30
+ const t = b(R, n, l), o = t[d](r), c = `
31
31
  <td class="product-info-cell" valign="middle" style="padding: 15px;">
32
- <table cellpadding="0" cellspacing="0" role="presentation" width="100%" style="table-layout: fixed;">
32
+ <table cellpadding="0" cellspacing="0" role="presentation" width="100%">
33
33
  <tbody>
34
- ${n.filter((e) => e !== a && e !== d).filter((e) => t[e]).map((e) => {
34
+ ${n.filter((e) => e !== d && e !== a).filter((e) => t[e]).map((e) => {
35
35
  const u = T[e] ?? !0;
36
- return R(t[e](r), e, u);
36
+ return f(t[e](r), e, u);
37
37
  }).join(`
38
38
  `)}
39
39
  </tbody>
40
40
  </table>
41
41
  </td>
42
- `, s = t[d](r), p = o + c + s;
42
+ `, s = t[a](r), p = o + c + s;
43
43
  return y.replace("{-{-PRODUCT_CONTENT-}-}", p);
44
44
  }
45
45
  function D(r, n, l = {}) {
46
46
  return r.map((t, o) => {
47
47
  const i = O(t, n, l);
48
- return o > 0 ? m + i : i;
48
+ return o > 0 ? C + i : i;
49
49
  }).join("");
50
50
  }
51
51
  export {
@@ -63,6 +63,5 @@ export declare enum RecommendationControlId {
63
63
  CUSTOM_ATTR_PADDINGS = "recommendation-block-custom-attr-paddings-control",
64
64
  CUSTOM_ATTR_SIZE = "recommendation-block-custom-attr-size-control",
65
65
  CUSTOM_ATTR_STYLE = "recommendation-block-custom-attr-style-control",
66
- CUSTOM_ATTR_TEXT_TRIM = "recommendation-block-custom-attr-text-trim-control",
67
66
  SYNC_INFO_MESSAGE = "recommendation-block-sync-info-message"
68
67
  }
@@ -13,12 +13,10 @@
13
13
  * product cards — changing "brand" color won't affect "rating_star" color.
14
14
  */
15
15
  import { ImmutableHtmlNode } from '@stripoinc/ui-editor-extensions';
16
- import { CustomAttributeTextTrimControl } from './textTrim';
17
16
  /**
18
17
  * Grouped Custom Attribute Controls
19
18
  * Use this object for cleaner imports in extension.ts
20
19
  */
21
- export { CustomAttributeTextTrimControl } from './textTrim';
22
20
  export declare const CustomAttributeControls: {
23
21
  readonly align: {
24
22
  new (): {
@@ -104,5 +102,4 @@ export declare const CustomAttributeControls: {
104
102
  isVisible(_node: ImmutableHtmlNode): boolean;
105
103
  };
106
104
  };
107
- readonly textTrim: typeof CustomAttributeTextTrimControl;
108
105
  };
@@ -1,9 +1,9 @@
1
- import { ImmutableHtmlNode } from '@stripoinc/ui-editor-extensions';
1
+ import { ImmutableCssNode, ImmutableHtmlNode } from '@stripoinc/ui-editor-extensions';
2
2
  import { CommonControl } from '../../../common-control';
3
3
  /**
4
- * Control for enabling/disabling text trimming on product names.
4
+ * Control for enabling/disabling text trimming on product names
5
5
  * When enabled, adds a CSS class that applies text-overflow: ellipsis
6
- * and injects the required CSS rules into the document stylesheet.
6
+ * and injects the required CSS rules into the document stylesheet
7
7
  */
8
8
  export declare class NameTextTrimControl extends CommonControl {
9
9
  getId(): string;
@@ -12,6 +12,23 @@ export declare class NameTextTrimControl extends CommonControl {
12
12
  onTemplateNodeUpdated(node: ImmutableHtmlNode): void;
13
13
  _setFormValues(): void;
14
14
  _getCurrentTrimState(): boolean;
15
+ /**
16
+ * Finds an existing CSS rule in the document stylesheet by exact query
17
+ * @param query - The CSS query to search for (uses Stripo's CSS query syntax)
18
+ * @returns The CSS rule node if found, undefined otherwise
19
+ */
20
+ _findCssRule(query: string): ImmutableCssNode | undefined;
21
+ /**
22
+ * Finds the .text-trim-enabled p rule by searching all text-trim rules and comparing selectors
23
+ * This is needed because Stripo's CSS query syntax interprets spaces as path separators
24
+ * @returns true if the rule exists
25
+ */
26
+ _hasParagraphRule(): boolean;
27
+ /**
28
+ * Ensures the text-trim CSS rules exist in the document stylesheet
29
+ * Only adds rules if they don't already exist (prevents duplicates across multiple blocks)
30
+ */
31
+ _ensureCssRulesExist(): void;
15
32
  _onTextTrimChange(enabled: boolean): void;
16
33
  _listenToFormUpdates(): void;
17
34
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@useinsider/guido",
3
- "version": "3.2.0-beta.22a0c4c",
3
+ "version": "3.2.0-beta.250b0a1",
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,99 +0,0 @@
1
- import { ModificationDescription as T } from "../../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
2
- import { CommonControl as m } from "../../../common-control.js";
3
- import { RecommendationBlockId as n } from "../../constants/blockIds.js";
4
- import { RecommendationControlId as l } from "../../constants/controlIds.js";
5
- import { BLOCK_ROOT_SELECTOR as u, ATTR_PRODUCT_ATTR as a } from "../../constants/selectors.js";
6
- import { CSS_CLASS_TEXT_TRIM as o, ensureTextTrimCssRulesExist as c } from "../shared/textTrimCssRules.js";
7
- const i = {
8
- TEXT_TRIM_ENABLED: "customAttrTextTrimEnabled"
9
- };
10
- class g extends m {
11
- getId() {
12
- return l.CUSTOM_ATTR_TEXT_TRIM;
13
- }
14
- getTemplate() {
15
- return `
16
- <hr style="margin: 0; border: none; border-top: 1px solid #e0e0e0;" />
17
- <div class="custom-attr-text-trim-control-container">
18
- ${this._GuTwoColumns([
19
- this._GuLabel({ text: this.api.translate("Trim Long Text") }),
20
- this._GuToggle(i.TEXT_TRIM_ENABLED)
21
- ])}
22
- </div>
23
- `;
24
- }
25
- onRender() {
26
- this._setFormValues(), this._listenToFormUpdates();
27
- }
28
- onTemplateNodeUpdated(t) {
29
- super.onTemplateNodeUpdated(t), this._setFormValues();
30
- }
31
- // ========================================================================
32
- // State Reading
33
- // ========================================================================
34
- _setFormValues() {
35
- this.api.updateValues({
36
- [i.TEXT_TRIM_ENABLED]: this._getCurrentTrimState()
37
- });
38
- }
39
- _getCurrentTrimState() {
40
- if (!this.currentNode || !("hasClass" in this.currentNode))
41
- return !1;
42
- if (this.currentNode.hasClass(o))
43
- return !0;
44
- const t = this._getTargetElements();
45
- return t.length > 0 && "hasClass" in t[0] ? t[0].hasClass(o) : !1;
46
- }
47
- // ========================================================================
48
- // Target Element Discovery (per-attribute scoping)
49
- // ========================================================================
50
- /**
51
- * Finds all custom attribute elements of the same type as the current node.
52
- *
53
- * Similar to getCustomAttrTargetNodes in customAttribute/index.ts, but adapted
54
- * for CommonControl lifecycle where currentNode is a class property (not a
55
- * parameter from Stripo's getTargetNodes override).
56
- */
57
- _getTargetElements() {
58
- if (!this.currentNode || !("closest" in this.currentNode))
59
- return [];
60
- const t = this.currentNode.closest(u);
61
- if (!t)
62
- return [];
63
- const e = "asElement" in this.currentNode ? this.currentNode.asElement().getAttribute(a) : null;
64
- if (e) {
65
- const s = `[esd-extension-block-id="${n.CUSTOM_ATTRIBUTE}"][${a}="${e}"]`;
66
- return Array.from(t.querySelectorAll(s));
67
- }
68
- return Array.from(
69
- t.querySelectorAll(
70
- `[esd-extension-block-id="${n.CUSTOM_ATTRIBUTE}"]`
71
- )
72
- );
73
- }
74
- // ========================================================================
75
- // Toggle Handler
76
- // ========================================================================
77
- _onTextTrimChange(t) {
78
- const e = this._getTargetElements();
79
- if (!e.length)
80
- return;
81
- t && c(this.api);
82
- const r = this.api.getDocumentModifier();
83
- e.forEach((s) => {
84
- t ? r.modifyHtml(s).setClass(o) : r.modifyHtml(s).removeClass(o);
85
- }), r.apply(
86
- new T(
87
- t ? "Enable custom attribute text trimming" : "Disable custom attribute text trimming"
88
- )
89
- );
90
- }
91
- _listenToFormUpdates() {
92
- this.api.onValueChanged(i.TEXT_TRIM_ENABLED, (t) => {
93
- this._onTextTrimChange(t);
94
- });
95
- }
96
- }
97
- export {
98
- g as CustomAttributeTextTrimControl
99
- };
@@ -1,14 +0,0 @@
1
- import { ModificationDescription as r } from "../../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
2
- const t = "text-trim-enabled", l = `.${t}`, c = `.${t} p`, S = `.${t} { max-width: 0; }`, T = `.${t} p { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; margin: 0; display: block; }`;
3
- function f(n) {
4
- const e = n.getDocumentRootCssNode();
5
- if (!e)
6
- return;
7
- const o = n.getDocumentModifier();
8
- let i = !1;
9
- e.querySelector(l) || (o.modifyCss(e).appendRule(S), i = !0), e.querySelectorAll(`*${t}`).some((s) => "getSelector" in s && typeof s.getSelector == "function" && s.getSelector() === c) || (o.modifyCss(e).appendRule(T), i = !0), i && o.apply(new r("Add text trim CSS rules"));
10
- }
11
- export {
12
- t as CSS_CLASS_TEXT_TRIM,
13
- f as ensureTextTrimCssRulesExist
14
- };
@@ -1,35 +0,0 @@
1
- /**
2
- * Custom Attribute Text Trim Control
3
- *
4
- * Per-attribute text trimming for custom product attributes.
5
- * Unlike NameTextTrimControl which applies to ALL product names globally,
6
- * this control is scoped to a specific custom attribute type via the
7
- * `product-attr` HTML attribute — changing text-trim on "brand" won't
8
- * affect "rating_star".
9
- *
10
- * CSS rules are shared with NameTextTrimControl via shared/textTrimCssRules.ts.
11
- */
12
- import { ImmutableHtmlNode } from '@stripoinc/ui-editor-extensions';
13
- import { CommonControl } from '../../../common-control';
14
- /**
15
- * Control for enabling/disabling text trimming on individual custom attributes.
16
- * Scoped per attribute type using the `product-attr` HTML attribute.
17
- */
18
- export declare class CustomAttributeTextTrimControl extends CommonControl {
19
- getId(): string;
20
- getTemplate(): string;
21
- onRender(): void;
22
- onTemplateNodeUpdated(node: ImmutableHtmlNode): void;
23
- _setFormValues(): void;
24
- _getCurrentTrimState(): boolean;
25
- /**
26
- * Finds all custom attribute elements of the same type as the current node.
27
- *
28
- * Similar to getCustomAttrTargetNodes in customAttribute/index.ts, but adapted
29
- * for CommonControl lifecycle where currentNode is a class property (not a
30
- * parameter from Stripo's getTargetNodes override).
31
- */
32
- _getTargetElements(): ImmutableHtmlNode[];
33
- _onTextTrimChange(enabled: boolean): void;
34
- _listenToFormUpdates(): void;
35
- }
@@ -1,29 +0,0 @@
1
- /**
2
- * Shared Text Trim CSS Rule Management
3
- *
4
- * Extracted from NameTextTrimControl to be reused by CustomAttributeTextTrimControl.
5
- * Follows the same pattern as controls/mobileLayout/cssRules.ts — standalone
6
- * functions that accept an API parameter, importable by any control class.
7
- *
8
- * The CSS rules are document-scoped (shared across all recommendation blocks).
9
- * Once injected, they persist until the template is closed.
10
- */
11
- import type { ImmutableCssNode } from '@stripoinc/ui-editor-extensions';
12
- import { ModificationDescription } from '@stripoinc/ui-editor-extensions';
13
- export declare const CSS_CLASS_TEXT_TRIM = "text-trim-enabled";
14
- interface CssCapableApi {
15
- getDocumentRootCssNode: () => ImmutableCssNode | null;
16
- getDocumentModifier: () => {
17
- modifyCss: (node: ImmutableCssNode) => {
18
- appendRule: (rule: string) => void;
19
- };
20
- apply: (desc: ModificationDescription) => void;
21
- };
22
- }
23
- /**
24
- * Ensures the text-trim CSS rules exist in the document stylesheet.
25
- * Only adds rules if they don't already exist (prevents duplicates across blocks).
26
- * Calls getDocumentRootCssNode once and passes it to both checks.
27
- */
28
- export declare function ensureTextTrimCssRulesExist(api: CssCapableApi): void;
29
- export {};