@useinsider/guido 3.6.0-beta.6c3407e → 3.6.0-beta.70bbf9f
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/composables/useHtmlValidator.js +165 -118
- package/dist/config/compiler/utils/recommendationCompilerUtils.js +28 -27
- package/dist/config/compiler/utils/recommendationIgnoreUtils.js +15 -0
- package/dist/config/migrator/recommendation/extractors.js +44 -22
- package/dist/config/migrator/recommendation/htmlBuilder.js +175 -169
- package/dist/config/migrator/recommendationMigrator.js +30 -31
- package/dist/enums/toaster.js +1 -1
- package/dist/extensions/Blocks/Recommendation/block.js +16 -35
- package/dist/extensions/Blocks/Recommendation/constants/selectors.js +21 -15
- package/dist/extensions/Blocks/Recommendation/controls/cardComposition/index.js +38 -24
- package/dist/extensions/Blocks/Recommendation/controls/main/index.js +39 -38
- package/dist/extensions/Blocks/Recommendation/controls/main/layoutOrientation.js +45 -34
- package/dist/extensions/Blocks/Recommendation/controls/main/productCount.js +3 -2
- package/dist/extensions/Blocks/Recommendation/controls/main/productLayout.js +62 -52
- package/dist/extensions/Blocks/Recommendation/controls/main/utils.js +74 -67
- package/dist/extensions/Blocks/Recommendation/controls/syncInfoMessage.js +7 -6
- package/dist/extensions/Blocks/Recommendation/extension.js +6 -5
- package/dist/extensions/Blocks/Recommendation/settingsPanel.js +3 -2
- package/dist/extensions/Blocks/Recommendation/store/recommendation.js +3 -2
- package/dist/extensions/Blocks/Recommendation/templates/grid/template.js +3 -2
- package/dist/extensions/Blocks/Recommendation/templates/index.js +5 -4
- package/dist/src/composables/useHtmlValidator.d.ts +27 -0
- package/dist/src/config/compiler/utils/recommendationIgnoreUtils.d.ts +17 -0
- package/dist/src/config/migrator/recommendation/extractors.d.ts +15 -0
- package/dist/src/config/migrator/recommendation/htmlBuilder.d.ts +8 -0
- package/dist/src/enums/toaster.d.ts +1 -2
- package/dist/src/extensions/Blocks/Recommendation/block.d.ts +0 -13
- package/dist/src/extensions/Blocks/Recommendation/constants/index.d.ts +1 -1
- package/dist/src/extensions/Blocks/Recommendation/constants/selectors.d.ts +21 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/cardComposition/index.d.ts +7 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/main/layoutOrientation.d.ts +5 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/main/productLayout.d.ts +6 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/main/utils.d.ts +9 -0
- package/package.json +1 -1
- package/dist/extensions/Blocks/Recommendation/useRecommendationBlockWarning.js +0 -16
- package/dist/extensions/Blocks/Recommendation/utils/recommendationBlockCount.js +0 -9
- package/dist/src/extensions/Blocks/Recommendation/useRecommendationBlockWarning.d.ts +0 -12
- package/dist/src/extensions/Blocks/Recommendation/utils/recommendationBlockCount.d.ts +0 -28
- /package/dist/src/{extensions/Blocks/Recommendation/block.test.d.ts → composables/useHtmlValidator.test.d.ts} +0 -0
- /package/dist/src/{extensions/Blocks/Recommendation/utils/recommendationBlockCount.test.d.ts → config/compiler/utils/recommendationIgnoreUtils.test.d.ts} +0 -0
|
@@ -1,36 +1,40 @@
|
|
|
1
1
|
import { ModificationDescription as p } from "../../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
|
|
2
2
|
import { RecommendationBlockId as m } from "../../constants/blockIds.js";
|
|
3
|
-
import { CURRENCY_ATTR as y, MOBILE_CONTAINER_SELECTOR as q, MOBILE_ROW_SELECTOR as
|
|
3
|
+
import { CURRENCY_ATTR as y, CSS_CLASS_SKIP_COMPILE as v, MOBILE_CONTAINER_SELECTOR as q, MOBILE_ROW_SELECTOR as w, DESKTOP_CONTAINER_SELECTOR as h, CONTAINER_SELECTOR as W, ATTR_PRODUCT_ATTR as j } from "../../constants/selectors.js";
|
|
4
4
|
import { RecommendationConfigService as E } from "../../services/configService.js";
|
|
5
5
|
import { useRecommendationExtensionStore as C } from "../../store/recommendation.js";
|
|
6
|
-
import { prepareProductRows as
|
|
7
|
-
import { formatPrice as
|
|
8
|
-
import { isTdNode as
|
|
9
|
-
import { getDefaultProducts as L, DEFAULT_CARD_COMPOSITION as
|
|
10
|
-
const
|
|
11
|
-
function
|
|
6
|
+
import { prepareProductRows as N } from "../../templates/index.js";
|
|
7
|
+
import { formatPrice as F } from "../../utils/priceFormatter.js";
|
|
8
|
+
import { isTdNode as V } from "../../utils/tagName.js";
|
|
9
|
+
import { getDefaultProducts as L, DEFAULT_CARD_COMPOSITION as M, sanitizeImageUrl as G } from "../../templates/utils.js";
|
|
10
|
+
const R = "recommendation-block-v2";
|
|
11
|
+
function A(t) {
|
|
12
12
|
if (!t)
|
|
13
13
|
return null;
|
|
14
14
|
if ("getAttribute" in t) {
|
|
15
15
|
const e = t.getAttribute("class");
|
|
16
|
-
if (e && e.includes(
|
|
16
|
+
if (e && e.includes(R))
|
|
17
17
|
return t;
|
|
18
18
|
}
|
|
19
|
-
return "querySelector" in t ? t.querySelector(`.${
|
|
19
|
+
return "querySelector" in t ? t.querySelector(`.${R}`) ?? null : null;
|
|
20
|
+
}
|
|
21
|
+
function K(t) {
|
|
22
|
+
const e = A(t);
|
|
23
|
+
return !e || !("getAttribute" in e) ? !1 : (e.getAttribute("class") ?? "").split(/\s+/).includes(v);
|
|
20
24
|
}
|
|
21
25
|
function b(t) {
|
|
22
|
-
const e =
|
|
26
|
+
const e = A(t);
|
|
23
27
|
if (!e || !("getAttribute" in e))
|
|
24
28
|
return "grid";
|
|
25
29
|
const o = e.getAttribute("data-layout");
|
|
26
30
|
return o === "list" || o === "horizontal" ? "list" : "grid";
|
|
27
31
|
}
|
|
28
32
|
function x(t) {
|
|
29
|
-
const e =
|
|
33
|
+
const e = A(t);
|
|
30
34
|
if (!e || !("getAttribute" in e))
|
|
31
|
-
return
|
|
35
|
+
return M;
|
|
32
36
|
const o = e.getAttribute("data-card-composition");
|
|
33
|
-
return o ? o.split(",").filter(Boolean) :
|
|
37
|
+
return o ? o.split(",").filter(Boolean) : M;
|
|
34
38
|
}
|
|
35
39
|
function D(t) {
|
|
36
40
|
if (!t || !("childNodes" in t))
|
|
@@ -47,14 +51,14 @@ function S(t, e, o) {
|
|
|
47
51
|
function U(t, e) {
|
|
48
52
|
return t && t.length > 0 ? t : e.length > 0 ? e : L();
|
|
49
53
|
}
|
|
50
|
-
function
|
|
54
|
+
function Y(t) {
|
|
51
55
|
const { currentNode: e, documentModifier: o } = t;
|
|
52
56
|
if (!e || !("querySelector" in e))
|
|
53
57
|
return;
|
|
54
|
-
const n = e.querySelector(
|
|
58
|
+
const n = e.querySelector(w);
|
|
55
59
|
n && (o.modifyHtml(n).setInnerHtml(""), o.apply(new p("Cleared mobile row content")));
|
|
56
60
|
}
|
|
57
|
-
function
|
|
61
|
+
function X(t) {
|
|
58
62
|
const {
|
|
59
63
|
currentNode: e,
|
|
60
64
|
documentModifier: o,
|
|
@@ -66,20 +70,20 @@ function Y(t) {
|
|
|
66
70
|
return;
|
|
67
71
|
const r = i ?? b(e), s = E.getConfig(e);
|
|
68
72
|
if (r === "list" || !s.mobileLayoutEnabled) {
|
|
69
|
-
|
|
73
|
+
Y({ currentNode: e, documentModifier: o });
|
|
70
74
|
return;
|
|
71
75
|
}
|
|
72
|
-
const u = e.querySelector(
|
|
76
|
+
const u = e.querySelector(w);
|
|
73
77
|
if (!u)
|
|
74
78
|
return;
|
|
75
|
-
const l = C(), d = U(n, l.recommendationProducts), a = c ?? x(e), g = `<td><table class="ins-recommendation-product-container ins-recommendation-mobile-container" width="100%" cellpadding="0" cellspacing="0" border="0">${
|
|
79
|
+
const l = C(), d = U(n, l.recommendationProducts), a = c ?? x(e), g = `<td><table class="ins-recommendation-product-container ins-recommendation-mobile-container" width="100%" cellpadding="0" cellspacing="0" border="0">${N(d, r, {
|
|
76
80
|
productsPerRow: s.mobileCardsInRow,
|
|
77
81
|
composition: a,
|
|
78
82
|
filterList: l.filterList
|
|
79
83
|
})}</table></td>`;
|
|
80
84
|
o.modifyHtml(u).setInnerHtml(g), o.apply(new p("Updated mobile product rows"));
|
|
81
85
|
}
|
|
82
|
-
function
|
|
86
|
+
function z(t) {
|
|
83
87
|
const {
|
|
84
88
|
currentNode: e,
|
|
85
89
|
documentModifier: o,
|
|
@@ -90,15 +94,15 @@ function K(t) {
|
|
|
90
94
|
} = t;
|
|
91
95
|
if (!e || !("querySelector" in e))
|
|
92
96
|
return;
|
|
93
|
-
const s = e.querySelector(
|
|
97
|
+
const s = e.querySelector(h) ?? e.querySelector(W);
|
|
94
98
|
if (!s)
|
|
95
99
|
return;
|
|
96
|
-
const u = C(), l = U(i, u.recommendationProducts), { cardsInRow: d } = u.recommendationConfigs, a = r ?? x(e), f = c ?? b(e), g =
|
|
100
|
+
const u = C(), l = U(i, u.recommendationProducts), { cardsInRow: d } = u.recommendationConfigs, a = r ?? x(e), f = c ?? b(e), g = N(l, f, {
|
|
97
101
|
productsPerRow: d,
|
|
98
102
|
composition: a,
|
|
99
103
|
filterList: u.filterList
|
|
100
104
|
});
|
|
101
|
-
o.modifyHtml(s).setInnerHtml(g).apply(new p("Updated product")),
|
|
105
|
+
o.modifyHtml(s).setInnerHtml(g).apply(new p("Updated product")), X(t), n == null || n();
|
|
102
106
|
}
|
|
103
107
|
function T(t, e, o, n) {
|
|
104
108
|
const c = `0 ${Math.floor(o / 2)}px`;
|
|
@@ -111,7 +115,7 @@ function T(t, e, o, n) {
|
|
|
111
115
|
t.querySelectorAll(".product-card-wrapper")
|
|
112
116
|
).forEach((u) => {
|
|
113
117
|
const l = "parentNode" in u ? u.parentNode : null;
|
|
114
|
-
l &&
|
|
118
|
+
l && V(l) && (e.modifyHtml(l).setStyle("padding", c), r = !0);
|
|
115
119
|
}), r;
|
|
116
120
|
}
|
|
117
121
|
function I(t, e, o) {
|
|
@@ -121,13 +125,13 @@ function I(t, e, o) {
|
|
|
121
125
|
e.modifyHtml(r).setStyle("height", n), c = !0;
|
|
122
126
|
}), c;
|
|
123
127
|
}
|
|
124
|
-
function
|
|
128
|
+
function J(t) {
|
|
125
129
|
const { currentNode: e, documentModifier: o } = t;
|
|
126
130
|
if (!e)
|
|
127
131
|
return;
|
|
128
132
|
const n = E.getConfig(e), i = b(e);
|
|
129
133
|
let c = !1;
|
|
130
|
-
const r = e.querySelector(
|
|
134
|
+
const r = e.querySelector(h);
|
|
131
135
|
if (r) {
|
|
132
136
|
c = T(
|
|
133
137
|
r,
|
|
@@ -160,9 +164,9 @@ function X(t) {
|
|
|
160
164
|
}
|
|
161
165
|
c && o.apply(new p("Reapply spacing after regeneration"));
|
|
162
166
|
}
|
|
163
|
-
function
|
|
167
|
+
function de(t) {
|
|
164
168
|
const { currentNode: e, documentModifier: o, afterRegenerate: n, products: i, layout: c, composition: r } = t;
|
|
165
|
-
e &&
|
|
169
|
+
e && z({
|
|
166
170
|
currentNode: e,
|
|
167
171
|
documentModifier: o,
|
|
168
172
|
products: i,
|
|
@@ -170,12 +174,12 @@ function se(t) {
|
|
|
170
174
|
composition: r,
|
|
171
175
|
afterRegenerate: () => {
|
|
172
176
|
setTimeout(() => {
|
|
173
|
-
|
|
177
|
+
J({ currentNode: e, documentModifier: o });
|
|
174
178
|
}, 0), n == null || n();
|
|
175
179
|
}
|
|
176
180
|
});
|
|
177
181
|
}
|
|
178
|
-
function
|
|
182
|
+
function fe(t, e) {
|
|
179
183
|
return t.length === e ? t : t.length > e ? t.slice(0, e) : [...t, ...L(e - t.length)];
|
|
180
184
|
}
|
|
181
185
|
function H() {
|
|
@@ -189,14 +193,14 @@ function H() {
|
|
|
189
193
|
thousandSeparator: e.thousandSeparator
|
|
190
194
|
};
|
|
191
195
|
}
|
|
192
|
-
function
|
|
196
|
+
function P(t, e = "price") {
|
|
193
197
|
const o = H(), n = t[e], i = (n == null ? void 0 : n[o.code]) ?? Object.values(n ?? {})[0] ?? 0;
|
|
194
|
-
return
|
|
198
|
+
return F({
|
|
195
199
|
price: i,
|
|
196
200
|
currency: o
|
|
197
201
|
});
|
|
198
202
|
}
|
|
199
|
-
function
|
|
203
|
+
function Q(t) {
|
|
200
204
|
var c, r;
|
|
201
205
|
const e = H(), o = ((c = t.original_price) == null ? void 0 : c[e.code]) ?? Object.values(t.original_price ?? {})[0] ?? 0, n = ((r = t.price) == null ? void 0 : r[e.code]) ?? Object.values(t.price ?? {})[0] ?? 0, i = o > 0 ? Math.round((o - n) / o * 100) : 0;
|
|
202
206
|
return i > 0 ? `-${i}%` : "0%";
|
|
@@ -205,24 +209,24 @@ function $(t) {
|
|
|
205
209
|
const { documentModifier: e, product: o, priceEl: n, oldPriceEl: i, omnibusPriceEl: c, omnibusDiscountEl: r } = t;
|
|
206
210
|
let s = !1;
|
|
207
211
|
if (n && "querySelector" in n) {
|
|
208
|
-
const u = n.querySelector("strong") ?? n.querySelector("p"), l =
|
|
212
|
+
const u = n.querySelector("strong") ?? n.querySelector("p"), l = P(o, "price");
|
|
209
213
|
S(e, u ?? null, l) && (s = !0);
|
|
210
214
|
}
|
|
211
215
|
if (i && "querySelector" in i) {
|
|
212
|
-
const u = i.querySelector("strong") ?? i.querySelector("p"), l =
|
|
216
|
+
const u = i.querySelector("strong") ?? i.querySelector("p"), l = P(o, "original_price");
|
|
213
217
|
S(e, u ?? null, l) && (s = !0);
|
|
214
218
|
}
|
|
215
219
|
if (c && "querySelector" in c) {
|
|
216
|
-
const u = c.querySelector(".omnibus-price-value") ?? null, l =
|
|
220
|
+
const u = c.querySelector(".omnibus-price-value") ?? null, l = P(o, "original_price");
|
|
217
221
|
S(e, u, l) && (s = !0);
|
|
218
222
|
}
|
|
219
223
|
if (r && "querySelector" in r) {
|
|
220
|
-
const u = r.querySelector(".omnibus-discount-value") ?? null, l =
|
|
224
|
+
const u = r.querySelector(".omnibus-discount-value") ?? null, l = Q(o);
|
|
221
225
|
S(e, u, l) && (s = !0);
|
|
222
226
|
}
|
|
223
227
|
return s;
|
|
224
228
|
}
|
|
225
|
-
function
|
|
229
|
+
function Z(t) {
|
|
226
230
|
const {
|
|
227
231
|
documentModifier: e,
|
|
228
232
|
product: o,
|
|
@@ -237,7 +241,7 @@ function J(t) {
|
|
|
237
241
|
let d = !1;
|
|
238
242
|
if (n && "querySelector" in n) {
|
|
239
243
|
const a = n.querySelector("img");
|
|
240
|
-
a && (e.modifyHtml(a).setAttribute("src",
|
|
244
|
+
a && (e.modifyHtml(a).setAttribute("src", G(o.image_url)).setAttribute("alt", o.name), d = !0);
|
|
241
245
|
const f = n.querySelector("a");
|
|
242
246
|
f && (e.modifyHtml(f).setAttribute("href", o.url), d = !0);
|
|
243
247
|
}
|
|
@@ -259,10 +263,10 @@ function J(t) {
|
|
|
259
263
|
return d;
|
|
260
264
|
}
|
|
261
265
|
function B(t) {
|
|
262
|
-
return "querySelector" in t ? t.querySelector(
|
|
266
|
+
return "querySelector" in t ? t.querySelector(h) ?? t : t;
|
|
263
267
|
}
|
|
264
268
|
const O = "product_attribute.";
|
|
265
|
-
function
|
|
269
|
+
function ee(t, e) {
|
|
266
270
|
var n;
|
|
267
271
|
let o;
|
|
268
272
|
if (t.startsWith(O)) {
|
|
@@ -272,7 +276,7 @@ function Q(t, e) {
|
|
|
272
276
|
o = e[t];
|
|
273
277
|
return typeof o == "string" && o.length > 0 ? o : typeof o == "number" ? String(o) : null;
|
|
274
278
|
}
|
|
275
|
-
function
|
|
279
|
+
function te(t, e, o) {
|
|
276
280
|
if (!("querySelectorAll" in t))
|
|
277
281
|
return !1;
|
|
278
282
|
const n = t.querySelectorAll(
|
|
@@ -284,7 +288,7 @@ function Z(t, e, o) {
|
|
|
284
288
|
n.forEach((r) => {
|
|
285
289
|
if (!("getAttribute" in r))
|
|
286
290
|
return;
|
|
287
|
-
const s = r.getAttribute(
|
|
291
|
+
const s = r.getAttribute(j);
|
|
288
292
|
if (!s)
|
|
289
293
|
return;
|
|
290
294
|
const u = i.get(s) ?? [];
|
|
@@ -296,7 +300,7 @@ function Z(t, e, o) {
|
|
|
296
300
|
r.slice(0, u).forEach((l, d) => {
|
|
297
301
|
if (!("querySelector" in l))
|
|
298
302
|
return;
|
|
299
|
-
const a =
|
|
303
|
+
const a = ee(s, o[d]);
|
|
300
304
|
if (a === null)
|
|
301
305
|
return;
|
|
302
306
|
const f = l.querySelector("p") ?? null;
|
|
@@ -304,7 +308,7 @@ function Z(t, e, o) {
|
|
|
304
308
|
});
|
|
305
309
|
}), c;
|
|
306
310
|
}
|
|
307
|
-
function
|
|
311
|
+
function _(t, e, o) {
|
|
308
312
|
if (!("querySelectorAll" in t))
|
|
309
313
|
return !1;
|
|
310
314
|
const n = t.querySelectorAll(
|
|
@@ -324,7 +328,7 @@ function w(t, e, o) {
|
|
|
324
328
|
), d = Math.min(n.length, o.length);
|
|
325
329
|
let a = !1;
|
|
326
330
|
for (let f = 0; f < d; f++) {
|
|
327
|
-
const g =
|
|
331
|
+
const g = Z({
|
|
328
332
|
documentModifier: e,
|
|
329
333
|
product: o[f],
|
|
330
334
|
imageEl: n[f] ?? null,
|
|
@@ -337,9 +341,9 @@ function w(t, e, o) {
|
|
|
337
341
|
});
|
|
338
342
|
a = a || g;
|
|
339
343
|
}
|
|
340
|
-
return
|
|
344
|
+
return te(t, e, o) && (a = !0), a;
|
|
341
345
|
}
|
|
342
|
-
function
|
|
346
|
+
function me(t) {
|
|
343
347
|
const { currentNode: e, documentModifier: o, products: n } = t;
|
|
344
348
|
if (!e || !("querySelectorAll" in e))
|
|
345
349
|
return !1;
|
|
@@ -348,12 +352,12 @@ function de(t) {
|
|
|
348
352
|
`[esd-extension-block-id="${m.IMAGE}"]`
|
|
349
353
|
).length !== n.length)
|
|
350
354
|
return !1;
|
|
351
|
-
let r =
|
|
355
|
+
let r = _(i, o, n);
|
|
352
356
|
const s = b(e), u = E.getConfig(e);
|
|
353
357
|
if (s !== "list" && u.mobileLayoutEnabled && "querySelector" in e) {
|
|
354
358
|
const l = e.querySelector(q);
|
|
355
359
|
if (l) {
|
|
356
|
-
const d =
|
|
360
|
+
const d = _(
|
|
357
361
|
l,
|
|
358
362
|
o,
|
|
359
363
|
n
|
|
@@ -363,7 +367,7 @@ function de(t) {
|
|
|
363
367
|
}
|
|
364
368
|
return r && o.apply(new p("Updated product content in-place")), !0;
|
|
365
369
|
}
|
|
366
|
-
function
|
|
370
|
+
function k(t, e, o) {
|
|
367
371
|
if (!("querySelectorAll" in t))
|
|
368
372
|
return !1;
|
|
369
373
|
const n = t.querySelectorAll(
|
|
@@ -387,27 +391,29 @@ function N(t, e, o) {
|
|
|
387
391
|
}) && (u = !0);
|
|
388
392
|
return u;
|
|
389
393
|
}
|
|
390
|
-
function
|
|
394
|
+
function pe(t) {
|
|
391
395
|
const { currentNode: e, documentModifier: o } = t;
|
|
392
396
|
if (!e || !("querySelectorAll" in e))
|
|
393
397
|
return !1;
|
|
398
|
+
if (K(e))
|
|
399
|
+
return !0;
|
|
394
400
|
const i = C().recommendationProducts;
|
|
395
401
|
if (i.length === 0)
|
|
396
402
|
return !1;
|
|
397
403
|
const c = B(e);
|
|
398
|
-
let r =
|
|
404
|
+
let r = k(c, o, i);
|
|
399
405
|
const s = b(e), u = E.getConfig(e);
|
|
400
406
|
if (s !== "list" && u.mobileLayoutEnabled && "querySelector" in e) {
|
|
401
407
|
const l = e.querySelector(q);
|
|
402
408
|
if (l) {
|
|
403
|
-
const d =
|
|
409
|
+
const d = k(l, o, i);
|
|
404
410
|
r = r || d;
|
|
405
411
|
}
|
|
406
412
|
}
|
|
407
413
|
return r && o.apply(new p("Updated price formatting in-place")), r;
|
|
408
414
|
}
|
|
409
|
-
function
|
|
410
|
-
const { currentNode: e, documentModifier: o, currency: n } = t, i =
|
|
415
|
+
function ye(t) {
|
|
416
|
+
const { currentNode: e, documentModifier: o, currency: n } = t, i = A(e);
|
|
411
417
|
if (!i)
|
|
412
418
|
return;
|
|
413
419
|
const c = n.alignment === "before" ? "0" : "1", r = (s, u) => {
|
|
@@ -416,17 +422,18 @@ function me(t) {
|
|
|
416
422
|
r(y.CURRENCY, n.code), r(y.SYMBOL, n.symbol), r(y.ALIGNMENT, c), r(y.THOUSAND_SEPARATOR, n.thousandSeparator), r(y.DECIMAL_SEPARATOR, n.decimalSeparator), r(y.DECIMAL_COUNT, n.decimalCount.toString()), o.apply(new p("Update currency attributes"));
|
|
417
423
|
}
|
|
418
424
|
export {
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
425
|
+
fe as adjustProductsToSize,
|
|
426
|
+
P as formatProductPrice,
|
|
427
|
+
A as getBlockElement,
|
|
422
428
|
x as getCardComposition,
|
|
423
429
|
b as getCurrentLayout,
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
430
|
+
K as isPartnerManagedBlock,
|
|
431
|
+
J as reapplySpacing,
|
|
432
|
+
X as regenerateMobileProductRows,
|
|
433
|
+
z as regenerateProductRows,
|
|
434
|
+
de as regenerateProductRowsWithStyles,
|
|
435
|
+
ye as setCurrencyAttributes,
|
|
436
|
+
pe as updatePricesInPlace,
|
|
437
|
+
me as updateProductContentInPlace,
|
|
438
|
+
Z as updateSingleProductContent
|
|
432
439
|
};
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
var m = Object.defineProperty;
|
|
2
|
-
var
|
|
3
|
-
var a = (o, e, t) =>
|
|
4
|
-
import { UIElementType as c, UEAttr as
|
|
2
|
+
var p = (o, e, t) => e in o ? m(o, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : o[e] = t;
|
|
3
|
+
var a = (o, e, t) => p(o, typeof e != "symbol" ? e + "" : e, t);
|
|
4
|
+
import { UIElementType as c, UEAttr as _ } from "../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
|
|
5
5
|
import { CommonControl as d } from "../../common-control.js";
|
|
6
6
|
import { RecommendationControlId as C } from "../constants/controlIds.js";
|
|
7
|
+
import "../constants/selectors.js";
|
|
7
8
|
const S = C.SYNC_INFO_MESSAGE, r = "sync-info-message", u = "Note that changes will be applied to all product cards in your recommendation block.";
|
|
8
|
-
class
|
|
9
|
+
class O extends d {
|
|
9
10
|
constructor() {
|
|
10
11
|
super(...arguments);
|
|
11
12
|
a(this, "_repositionedElement", null);
|
|
@@ -17,7 +18,7 @@ class h extends d {
|
|
|
17
18
|
return `
|
|
18
19
|
<div class="${r}">
|
|
19
20
|
<${c.ICON}
|
|
20
|
-
${
|
|
21
|
+
${_.ICON.src}="migration-info-icon"
|
|
21
22
|
class="${r}__icon">
|
|
22
23
|
</${c.ICON}>
|
|
23
24
|
<p class="${r}__text">
|
|
@@ -61,5 +62,5 @@ class h extends d {
|
|
|
61
62
|
}
|
|
62
63
|
export {
|
|
63
64
|
S as SYNC_INFO_MESSAGE_CONTROL_ID,
|
|
64
|
-
|
|
65
|
+
O as SyncInfoMessageControl
|
|
65
66
|
};
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { ExtensionBuilder as r } from "../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
|
|
2
2
|
import { RecommendationBlock as m } from "./block.js";
|
|
3
3
|
import { RecommendationBlockControl as n } from "./controls/main/index.js";
|
|
4
|
+
import "./constants/selectors.js";
|
|
4
5
|
import "./store/recommendation.js";
|
|
5
6
|
import { NameControls as i } from "./controls/name/index.js";
|
|
6
7
|
import { PriceControls as e } from "./controls/price/index.js";
|
|
7
8
|
import { OldPriceControls as s } from "./controls/oldPrice/index.js";
|
|
8
9
|
import { OmnibusPriceControls as l } from "./controls/omnibusPrice/index.js";
|
|
9
|
-
import { OmnibusDiscountControls as
|
|
10
|
-
import { ButtonControls as
|
|
10
|
+
import { OmnibusDiscountControls as p } from "./controls/omnibusDiscount/index.js";
|
|
11
|
+
import { ButtonControls as a } from "./controls/button/index.js";
|
|
11
12
|
import { ImageControls as c } from "./controls/image/index.js";
|
|
12
13
|
import { CustomAttributeControls as C } from "./controls/customAttribute/index.js";
|
|
13
14
|
import { SpacingControl as f } from "./controls/spacing/index.js";
|
|
@@ -22,8 +23,8 @@ const b = [
|
|
|
22
23
|
e,
|
|
23
24
|
s,
|
|
24
25
|
l,
|
|
25
|
-
a,
|
|
26
26
|
p,
|
|
27
|
+
a,
|
|
27
28
|
c,
|
|
28
29
|
C
|
|
29
30
|
], P = [
|
|
@@ -35,10 +36,10 @@ const b = [
|
|
|
35
36
|
], S = [
|
|
36
37
|
...P,
|
|
37
38
|
...b.flatMap((o) => Object.values(o))
|
|
38
|
-
],
|
|
39
|
+
], L = S.reduce(
|
|
39
40
|
(o, t) => o.addControl(t),
|
|
40
41
|
new r().addBlock(m).withSettingsPanelRegistry(B)
|
|
41
42
|
).addStyles(y).withIconsRegistry(R).build();
|
|
42
43
|
export {
|
|
43
|
-
|
|
44
|
+
L as default
|
|
44
45
|
};
|
|
@@ -2,6 +2,7 @@ import { SettingsPanelRegistry as E, SettingsPanelTab as _, SettingsTab as O, Co
|
|
|
2
2
|
import { BLOCK_ID as U } from "./block.js";
|
|
3
3
|
import { RecommendationBlockId as S } from "./constants/blockIds.js";
|
|
4
4
|
import { RecommendationControlId as T } from "./constants/controlIds.js";
|
|
5
|
+
import "./constants/selectors.js";
|
|
5
6
|
import { CONTROL_BLOCK_ID as A } from "./controls/main/index.js";
|
|
6
7
|
import "./store/recommendation.js";
|
|
7
8
|
import "./controls/name/index.js";
|
|
@@ -15,7 +16,7 @@ import { SPACING_CONTROL_ID as L } from "./controls/spacing/index.js";
|
|
|
15
16
|
import { CARD_BACKGROUND_COLOR_CONTROL_ID as D } from "./controls/cardBackground/index.js";
|
|
16
17
|
import { COMPOSITION_CONTROL_BLOCK_ID as B } from "./controls/cardComposition/index.js";
|
|
17
18
|
import { SYNC_INFO_MESSAGE_CONTROL_ID as N } from "./controls/syncInfoMessage.js";
|
|
18
|
-
class
|
|
19
|
+
class a extends E {
|
|
19
20
|
registerBlockControls(I) {
|
|
20
21
|
I[U] = [
|
|
21
22
|
new _(
|
|
@@ -194,5 +195,5 @@ class Z extends E {
|
|
|
194
195
|
}
|
|
195
196
|
}
|
|
196
197
|
export {
|
|
197
|
-
|
|
198
|
+
a as SettingsPanel
|
|
198
199
|
};
|
|
@@ -2,6 +2,7 @@ import { getRecommendationFeedSourceMaps as g, getOperatorOptions as R, PriceAtt
|
|
|
2
2
|
import { useRecommendationApi as y } from "../../../../services/recommendationApi.js";
|
|
3
3
|
import { useConfigStore as G } from "../../../../stores/config.js";
|
|
4
4
|
import { defineStore as P } from "pinia";
|
|
5
|
+
import "../constants/selectors.js";
|
|
5
6
|
import { DEFAULT_CARDS_IN_ROW as F } from "../constants/layout.js";
|
|
6
7
|
import { EXCLUDED_ALGORITHM_IDS as D } from "../constants/defaultConfig.js";
|
|
7
8
|
import { getDefaultProducts as S } from "../templates/utils.js";
|
|
@@ -59,7 +60,7 @@ const x = () => ({
|
|
|
59
60
|
blockStates: {},
|
|
60
61
|
currentRecommendationId: null,
|
|
61
62
|
configVersion: 0
|
|
62
|
-
}),
|
|
63
|
+
}), K = P("guidoRecommendationExtension", {
|
|
63
64
|
state: () => x(),
|
|
64
65
|
getters: {
|
|
65
66
|
// ====================================================================
|
|
@@ -475,5 +476,5 @@ const x = () => ({
|
|
|
475
476
|
}
|
|
476
477
|
});
|
|
477
478
|
export {
|
|
478
|
-
|
|
479
|
+
K as useRecommendationExtensionStore
|
|
479
480
|
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import "../../constants/selectors.js";
|
|
1
2
|
import { DEFAULT_PRODUCTS_PER_ROW as L } from "../../constants/layout.js";
|
|
2
3
|
import { getDefaultProducts as E, DEFAULTS as I, createBlockTemplate as _, DEFAULT_CARD_COMPOSITION as S, spacer as b, buildElementRenderer as A, DEFAULT_CARD_VISIBILITY as f } from "../utils.js";
|
|
3
4
|
import { ATTRIBUTE_CELL_CLASS as w, DEFAULT_CELL_PADDING as D, gridElementRenderer as C } from "./elementRenderer.js";
|
|
@@ -52,12 +53,12 @@ function U(t, e, o, r, n = {}) {
|
|
|
52
53
|
function h(t, e, o, r = {}) {
|
|
53
54
|
return U(t, e, C, o, r);
|
|
54
55
|
}
|
|
55
|
-
function
|
|
56
|
+
function H(t) {
|
|
56
57
|
const e = t ? `ins-recommendation-v3-block-${t}` : void 0, o = _("grid", e), r = E(), n = h(r, L);
|
|
57
58
|
return o.replace("{-{-TITLE-}-}", I.TITLE).replace("{-{-PRODUCT_ROWS-}-}", n).replace("{-{-MOBILE_PRODUCT_ROWS-}-}", "");
|
|
58
59
|
}
|
|
59
60
|
export {
|
|
60
|
-
|
|
61
|
+
H as getDefaultTemplate,
|
|
61
62
|
P as prepareGridAttributeRows,
|
|
62
63
|
U as prepareGridProductRows,
|
|
63
64
|
h as prepareProductRows
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
+
import "../constants/selectors.js";
|
|
1
2
|
import { DEFAULT_PRODUCTS_PER_ROW as s } from "../constants/layout.js";
|
|
2
3
|
import { prepareProductRows as c } from "./grid/template.js";
|
|
3
|
-
import { prepareProductRows as
|
|
4
|
-
function
|
|
4
|
+
import { prepareProductRows as m } from "./list/template.js";
|
|
5
|
+
function f(o, t, r = {}) {
|
|
5
6
|
if (t === "list")
|
|
6
|
-
return
|
|
7
|
+
return m(o, r.composition, r.filterList);
|
|
7
8
|
const { productsPerRow: e = s, composition: p, filterList: i } = r;
|
|
8
9
|
return c(o, e, p, i);
|
|
9
10
|
}
|
|
10
11
|
export {
|
|
11
|
-
|
|
12
|
+
f as prepareProductRows
|
|
12
13
|
};
|
|
@@ -1,4 +1,31 @@
|
|
|
1
1
|
import type { DynamicContent } from '@@/Types/generic';
|
|
2
|
+
import type { FiltersResponse } from '@@/Types/recommendation';
|
|
3
|
+
/**
|
|
4
|
+
* Parses a `{{recoId_index_attributeName}}` variable (already stripped of the
|
|
5
|
+
* braces/whitespace) into its recommendation id and attribute name. Returns
|
|
6
|
+
* null for anything that isn't a well-formed recommendation variable.
|
|
7
|
+
*/
|
|
8
|
+
export declare function parseRecommendationVariable(field: string): {
|
|
9
|
+
recoId: string;
|
|
10
|
+
attribute: string;
|
|
11
|
+
} | null;
|
|
12
|
+
/**
|
|
13
|
+
* Builds the set of attribute forms valid inside partner-authored
|
|
14
|
+
* `{{recoId_index_attribute}}` variables: the built-in compiler attributes plus
|
|
15
|
+
* each account attribute in its canonical token form — bare for
|
|
16
|
+
* `defaultAttribute`, `product_attribute.<name>` for `productAttribute`. Using
|
|
17
|
+
* `resolveProductAttrValue` (the same producer the block builder uses) keeps the
|
|
18
|
+
* validator's notion of "valid form" identical to what is actually emitted.
|
|
19
|
+
*/
|
|
20
|
+
export declare function buildPartnerAttributeNameSet(filterList: FiltersResponse): Set<string>;
|
|
21
|
+
/**
|
|
22
|
+
* Returns the `{{...}}` custom fields in the HTML that are invalid. Partner
|
|
23
|
+
* attributes in `ins-skip-compile` blocks (recoId ∈ ignoredIds) are checked
|
|
24
|
+
* against `ignoredAttributeNames`; Guido-generated reco variables and known merge
|
|
25
|
+
* tags pass. An unrecognized dotted token is ignored: it was never captured
|
|
26
|
+
* before, so flagging it would false-positive on merge tags like `{{user.name}}`.
|
|
27
|
+
*/
|
|
28
|
+
export declare function findInvalidCustomFields(html: string, validCustomFields: string[], recommendationBlockIds: string[], ignoredIds: Set<string>, ignoredAttributeNames: Set<string> | null): string[];
|
|
2
29
|
export declare const useHtmlValidator: () => {
|
|
3
30
|
validateHtml: (html: string, customFields: DynamicContent[], isOnSaveValidation?: boolean) => Promise<boolean>;
|
|
4
31
|
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns true when a recommendation block has opted out of Guido's
|
|
3
|
+
* product-data → template-variable substitution. Partners signal opt-out by
|
|
4
|
+
* adding the `ins-skip-compile` class on the `.recommendation-block-v2`
|
|
5
|
+
* element. Only the variable substitution is skipped — campaign URL building,
|
|
6
|
+
* hidden-row removal, Outlook image widths, discount conditions, text-trim CSS
|
|
7
|
+
* and general HTML optimizations still apply. See `CSS_CLASS_SKIP_COMPILE` for
|
|
8
|
+
* the full scope.
|
|
9
|
+
*/
|
|
10
|
+
export declare function isIgnoredRecommendationBlock(block: Element): boolean;
|
|
11
|
+
/**
|
|
12
|
+
* DOM-parses the HTML once and returns the set of `recommendation-id`
|
|
13
|
+
* values that belong to ignored blocks. Use this in regex/string-based
|
|
14
|
+
* compiler rules where the rule processes flat matches and only has the
|
|
15
|
+
* extracted block ID rather than a DOM Element reference.
|
|
16
|
+
*/
|
|
17
|
+
export declare function getIgnoredRecommendationBlockIds(html: string): Set<string>;
|
|
@@ -5,3 +5,18 @@ export declare function extractTitleText(block: Element): string;
|
|
|
5
5
|
* the caller treats that as "no segment background".
|
|
6
6
|
*/
|
|
7
7
|
export declare function extractCardBgColor(block: Element): string;
|
|
8
|
+
/**
|
|
9
|
+
* Reads the legacy block's own `currency-*` attributes into a
|
|
10
|
+
* `currencySettings`-shaped object that `mapCurrency` understands. Used as a
|
|
11
|
+
* fallback when the external recommendationConfigs map has no entry for this
|
|
12
|
+
* block, so the migrated block keeps its real currency instead of defaulting.
|
|
13
|
+
* Returns undefined when the block carries no `currency` attribute.
|
|
14
|
+
*/
|
|
15
|
+
export declare function extractCurrencyFromBlock(block: Element): Record<string, string> | undefined;
|
|
16
|
+
/**
|
|
17
|
+
* True when a PM has manually opted the legacy block out of content
|
|
18
|
+
* regeneration by adding the `ins-skip-compile` class. Detected before rebuild
|
|
19
|
+
* so the migrator preserves the partner's markup verbatim (keeping their
|
|
20
|
+
* hand-authored variables) instead of regenerating the block.
|
|
21
|
+
*/
|
|
22
|
+
export declare function isPartnerManagedBlock(block: Element): boolean;
|
|
@@ -8,4 +8,12 @@ export declare function buildBlockHtml(params: {
|
|
|
8
8
|
extraClasses?: string;
|
|
9
9
|
legacyId?: string;
|
|
10
10
|
legacyBgColor?: string;
|
|
11
|
+
/**
|
|
12
|
+
* When set, the block's existing inner HTML is preserved verbatim instead
|
|
13
|
+
* of regenerating product rows — used for partner-customized blocks so
|
|
14
|
+
* their hand-authored `{{...}}` variables survive migration.
|
|
15
|
+
*/
|
|
16
|
+
preserveInnerHtml?: string;
|
|
17
|
+
/** Adds the `ins-skip-compile` opt-out class to the migrated block. */
|
|
18
|
+
skipCompile?: boolean;
|
|
11
19
|
}): string;
|
|
@@ -55,19 +55,6 @@ export declare class RecommendationBlock extends Block {
|
|
|
55
55
|
* @param node - The block node being deleted
|
|
56
56
|
*/
|
|
57
57
|
onDelete(node: ImmutableHtmlNode): void;
|
|
58
|
-
/**
|
|
59
|
-
* Warns (dark advisory toaster) when the design holds more than one live
|
|
60
|
-
* recommendation block. Triggered from the user-add paths only (fresh drop
|
|
61
|
-
* and duplicate) — never from document-load/migration, so opening a template
|
|
62
|
-
* that already has multiple blocks does not fire it. `onCreated` also runs
|
|
63
|
-
* for a reco block that arrives inside a saved structure (SD-143028), so this
|
|
64
|
-
* covers that case too — no separate `module_dropped` handling is needed.
|
|
65
|
-
*
|
|
66
|
-
* Counting lives in `useRecommendationBlockWarning`, whose DOM-based logic
|
|
67
|
-
* ignores the empty shells deletions leave behind (SD-143028). Wrapped in
|
|
68
|
-
* try/catch because the document root may be unavailable during initial load.
|
|
69
|
-
*/
|
|
70
|
-
private _warnIfMultipleBlocks;
|
|
71
58
|
/**
|
|
72
59
|
* Generates the next unique recommendation ID by scanning all existing blocks
|
|
73
60
|
* in the document and finding the maximum existing ID + 1.
|
|
@@ -8,6 +8,6 @@
|
|
|
8
8
|
*/
|
|
9
9
|
export { RecommendationBlockId } from './blockIds';
|
|
10
10
|
export { RecommendationControlId } from './controlIds';
|
|
11
|
-
export { BLOCK_ROOT_SELECTOR, CONTAINER_SELECTOR, DESKTOP_CONTAINER_SELECTOR, MOBILE_CONTAINER_SELECTOR, MOBILE_ROW_SELECTOR, CSS_CLASS_RECO_BUTTON, CURRENCY_ATTR, ATTR_PRODUCT_IMAGE, ATTR_PRODUCT_NAME, ATTR_PRODUCT_PRICE, ATTR_PRODUCT_OLD_PRICE, ATTR_PRODUCT_OMNIBUS_PRICE, ATTR_PRODUCT_OMNIBUS_DISCOUNT, ATTR_PRODUCT_BUTTON, ATTR_CUSTOM_PREFIX, ATTR_DATA_CUSTOM_ATTRIBUTES, ATTR_PRODUCT_ATTR, BUILT_IN_DEFAULT_ATTRIBUTES, } from './selectors';
|
|
11
|
+
export { BLOCK_ROOT_SELECTOR, CONTAINER_SELECTOR, DESKTOP_CONTAINER_SELECTOR, MOBILE_CONTAINER_SELECTOR, MOBILE_ROW_SELECTOR, CSS_CLASS_RECO_BUTTON, CSS_CLASS_SKIP_COMPILE, RECOMMENDATION_VARIABLE_BUILTIN_ATTRIBUTES, CURRENCY_ATTR, ATTR_PRODUCT_IMAGE, ATTR_PRODUCT_NAME, ATTR_PRODUCT_PRICE, ATTR_PRODUCT_OLD_PRICE, ATTR_PRODUCT_OMNIBUS_PRICE, ATTR_PRODUCT_OMNIBUS_DISCOUNT, ATTR_PRODUCT_BUTTON, ATTR_CUSTOM_PREFIX, ATTR_DATA_CUSTOM_ATTRIBUTES, ATTR_PRODUCT_ATTR, BUILT_IN_DEFAULT_ATTRIBUTES, } from './selectors';
|
|
12
12
|
export { LAYOUT_VALUES, LAYOUT_OPTIONS, DEFAULT_PRODUCTS_PER_ROW, DEFAULT_CARDS_IN_ROW, DEFAULT_MOBILE_CARDS_IN_ROW, MAX_PRODUCT_COUNT, MIN_PRODUCT_COUNT, MAX_PRODUCTS_PER_ROW, MIN_PRODUCTS_PER_ROW, MAX_MOBILE_PRODUCTS_PER_ROW, MIN_MOBILE_PRODUCTS_PER_ROW, DEFAULT_COLUMN_SPACING, DEFAULT_ROW_SPACING, DEFAULT_MOBILE_COLUMN_SPACING, DEFAULT_MOBILE_ROW_SPACING, MIN_SPACING, MAX_SPACING, SPACING_STEP, } from './layout';
|
|
13
13
|
export { DEFAULT_NODE_CONFIG, DEFAULT_CURRENCY, DEFAULT_COMPOSITION, DEFAULT_VISIBILITY, CURRENT_CONFIG_VERSION, EXCLUDED_ALGORITHM_IDS, } from './defaultConfig';
|