@useinsider/guido 3.7.2-beta.3cec1a4 → 3.7.2-beta.a114aa7
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 +180 -133
- 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/extensions/Blocks/Recommendation/block.js +1 -4
- package/dist/extensions/Blocks/Recommendation/constants/selectors.js +21 -15
- package/dist/extensions/Blocks/Recommendation/controls/cardComposition/index.js +166 -169
- package/dist/extensions/Blocks/Recommendation/controls/main/index.js +43 -42
- package/dist/extensions/Blocks/Recommendation/controls/main/layoutOrientation.js +44 -33
- package/dist/extensions/Blocks/Recommendation/controls/main/productCount.js +3 -2
- package/dist/extensions/Blocks/Recommendation/controls/main/productLayout.js +59 -49
- package/dist/extensions/Blocks/Recommendation/controls/main/utils.js +89 -82
- 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 +13 -12
- package/dist/extensions/Blocks/Recommendation/templates/index.js +5 -4
- package/dist/src/composables/useHtmlValidator.d.ts +27 -0
- package/dist/src/composables/useHtmlValidator.test.d.ts +1 -0
- package/dist/src/config/compiler/utils/recommendationIgnoreUtils.d.ts +17 -0
- package/dist/src/config/compiler/utils/recommendationIgnoreUtils.test.d.ts +1 -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/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
|
@@ -1,42 +1,42 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
import { UIElementType as f, UEAttr as
|
|
5
|
-
import { CommonControl as
|
|
6
|
-
import { ATTR_PRODUCT_IMAGE as
|
|
7
|
-
import { DEFAULT_COMPOSITION as P, DEFAULT_VISIBILITY as
|
|
8
|
-
import { RecommendationConfigService as
|
|
1
|
+
var J = Object.defineProperty;
|
|
2
|
+
var Q = (p, _, t) => _ in p ? J(p, _, { enumerable: !0, configurable: !0, writable: !0, value: t }) : p[_] = t;
|
|
3
|
+
var T = (p, _, t) => Q(p, typeof _ != "symbol" ? _ + "" : _, t);
|
|
4
|
+
import { UIElementType as f, UEAttr as I, ModificationDescription as A } from "../../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
|
|
5
|
+
import { CommonControl as Z } from "../../../common-control.js";
|
|
6
|
+
import { ATTR_PRODUCT_IMAGE as L, ATTR_PRODUCT_NAME as tt, ATTR_PRODUCT_PRICE as et, ATTR_PRODUCT_OLD_PRICE as rt, ATTR_PRODUCT_OMNIBUS_PRICE as ot, ATTR_PRODUCT_OMNIBUS_DISCOUNT as st, ATTR_PRODUCT_BUTTON as B, ATTR_DATA_CUSTOM_ATTRIBUTES as q, ATTR_CUSTOM_PREFIX as m, BUILT_IN_DEFAULT_ATTRIBUTES as it } from "../../constants/selectors.js";
|
|
7
|
+
import { DEFAULT_COMPOSITION as P, DEFAULT_VISIBILITY as F } from "../../constants/defaultConfig.js";
|
|
8
|
+
import { RecommendationConfigService as nt } from "../../services/configService.js";
|
|
9
9
|
import { useRecommendationExtensionStore as lt } from "../../store/recommendation.js";
|
|
10
10
|
import { ATTRIBUTE_CELL_CLASS as at, gridElementRenderer as ct, DEFAULT_CELL_PADDING as ut, buildFillerCell as dt } from "../../templates/grid/elementRenderer.js";
|
|
11
11
|
import { listElementRenderer as mt } from "../../templates/list/elementRenderer.js";
|
|
12
|
-
import { toDisplayName as ht, isDefaultAttribute as pt, toDisplayableAttributeValue as
|
|
12
|
+
import { toDisplayName as ht, isDefaultAttribute as pt, toDisplayableAttributeValue as _t, buildElementRenderer as w } from "../../templates/utils.js";
|
|
13
13
|
import { getTableDisplayValue as ft } from "../../utils/tagName.js";
|
|
14
|
-
import { getCurrentLayout as
|
|
15
|
-
const
|
|
14
|
+
import { isPartnerManagedBlock as gt, getCurrentLayout as bt } from "../main/utils.js";
|
|
15
|
+
const yt = "ui-elements-recommendation-card-composition", S = ".recommendation-attribute-row", N = ".product-card-wrapper > tbody", M = ".product-info-cell > table > tbody", V = "data-card-composition", y = "data-attribute-type", v = "data-visibility", x = {
|
|
16
16
|
ADD_ATTRIBUTE: "addAttribute"
|
|
17
|
-
},
|
|
18
|
-
{ key:
|
|
19
|
-
{ key:
|
|
20
|
-
{ key:
|
|
21
|
-
{ key:
|
|
22
|
-
{ key:
|
|
23
|
-
{ key:
|
|
24
|
-
{ key:
|
|
25
|
-
],
|
|
26
|
-
class
|
|
17
|
+
}, g = 5, E = "reorderIcon_", h = [
|
|
18
|
+
{ key: L, label: "Product Image" },
|
|
19
|
+
{ key: tt, label: "Product Name" },
|
|
20
|
+
{ key: et, label: "Product Price" },
|
|
21
|
+
{ key: rt, label: "Product Original Price" },
|
|
22
|
+
{ key: ot, label: "Omnibus Price" },
|
|
23
|
+
{ key: st, label: "Omnibus Discount" },
|
|
24
|
+
{ key: B, label: "Product Button" }
|
|
25
|
+
], At = new Set(h.map((p) => p.key)), C = "customAttr_", R = "deleteAttr_";
|
|
26
|
+
class Ut extends Z {
|
|
27
27
|
constructor() {
|
|
28
28
|
super(...arguments);
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
T(this, "store", lt());
|
|
30
|
+
T(this, "unsubscribeStore", null);
|
|
31
|
+
T(this, "eventController", null);
|
|
32
32
|
/**
|
|
33
33
|
* Guard flag: when true, onTemplateNodeUpdated skips _initializeComposition.
|
|
34
34
|
* Used during _onReorder to prevent multiple intermediate rebuilds.
|
|
35
35
|
*/
|
|
36
|
-
|
|
36
|
+
T(this, "reorderInProgress", !1);
|
|
37
37
|
}
|
|
38
38
|
getId() {
|
|
39
|
-
return
|
|
39
|
+
return yt;
|
|
40
40
|
}
|
|
41
41
|
// ========================================================================
|
|
42
42
|
// Lifecycle
|
|
@@ -47,23 +47,23 @@ class Ht extends tt {
|
|
|
47
47
|
${this._GuToggle(`visibility_${l.key}`)}
|
|
48
48
|
</div>
|
|
49
49
|
`).join(""), r = Array.from(
|
|
50
|
-
{ length:
|
|
50
|
+
{ length: g },
|
|
51
51
|
(l, u) => `
|
|
52
|
-
<div data-custom-select-key="${
|
|
52
|
+
<div data-custom-select-key="${C}${u}" style="display: none;">
|
|
53
53
|
${this._GuSelect({
|
|
54
|
-
name: `${
|
|
54
|
+
name: `${C}${u}`,
|
|
55
55
|
placeholder: this.api.translate("Select Attribute"),
|
|
56
56
|
options: []
|
|
57
57
|
})}
|
|
58
58
|
</div>
|
|
59
59
|
`
|
|
60
|
-
).join(""), e = h.length +
|
|
60
|
+
).join(""), e = h.length + g, o = Array.from(
|
|
61
61
|
{ length: e },
|
|
62
62
|
(l, u) => `
|
|
63
|
-
<div data-reorder-icon-key="${
|
|
63
|
+
<div data-reorder-icon-key="${E}${u}" style="display: none;">
|
|
64
64
|
<${f.BUTTON}
|
|
65
65
|
class="drag-handle-btn flat-inline flat-white"
|
|
66
|
-
${
|
|
66
|
+
${I.BUTTON.name}="${E}${u}"
|
|
67
67
|
>
|
|
68
68
|
<${f.ICON}
|
|
69
69
|
src="reorder"
|
|
@@ -73,12 +73,12 @@ class Ht extends tt {
|
|
|
73
73
|
</div>
|
|
74
74
|
`
|
|
75
75
|
).join(""), s = Array.from(
|
|
76
|
-
{ length:
|
|
76
|
+
{ length: g },
|
|
77
77
|
(l, u) => `
|
|
78
|
-
<div data-custom-delete-key="${
|
|
78
|
+
<div data-custom-delete-key="${R}${u}" style="display: none;">
|
|
79
79
|
<${f.BUTTON}
|
|
80
80
|
class="custom-attr-delete flat-inline flat-white"
|
|
81
|
-
${
|
|
81
|
+
${I.BUTTON.name}="${R}${u}"
|
|
82
82
|
>
|
|
83
83
|
<${f.ICON}
|
|
84
84
|
src="delete"
|
|
@@ -89,15 +89,15 @@ class Ht extends tt {
|
|
|
89
89
|
`
|
|
90
90
|
).join(""), i = "https://academy.insiderone.com/docs/new-editor-email-recommendation-block", n = this.api.translate(
|
|
91
91
|
"Drag and drop the card elements to reorder them, adjust their visibility or add new attributes up to 5."
|
|
92
|
-
),
|
|
92
|
+
), a = this.api.translate("For more information, you can"), c = this.api.translate("visit Academy");
|
|
93
93
|
return `
|
|
94
94
|
<div class="recommendation-controls-container" data-card-composition-control>
|
|
95
95
|
<div class="container">
|
|
96
96
|
<p class="card-composition-description">
|
|
97
97
|
${n}
|
|
98
|
-
${
|
|
98
|
+
${a}
|
|
99
99
|
<!-- cspell:disable-next-line -->
|
|
100
|
-
<a href="${i}" target="_blank" rel="noopener noreferrer">${
|
|
100
|
+
<a href="${i}" target="_blank" rel="noopener noreferrer">${c}</a>.
|
|
101
101
|
</p>
|
|
102
102
|
</div>
|
|
103
103
|
|
|
@@ -120,7 +120,7 @@ class Ht extends tt {
|
|
|
120
120
|
<div class="orderable-list" data-composition-list></div>
|
|
121
121
|
|
|
122
122
|
${this._GuButton({
|
|
123
|
-
name:
|
|
123
|
+
name: x.ADD_ATTRIBUTE,
|
|
124
124
|
label: this.api.translate("Add Attribute"),
|
|
125
125
|
id: "guido__btn-add-attribute"
|
|
126
126
|
})}
|
|
@@ -128,10 +128,24 @@ class Ht extends tt {
|
|
|
128
128
|
`;
|
|
129
129
|
}
|
|
130
130
|
onRender() {
|
|
131
|
-
this._initializeComposition(), this._registerValueChangeListeners(), this._setupEventListeners(), this._updateOrderableState(), this._subscribeToStoreChanges();
|
|
131
|
+
this._initializeComposition(), this._registerValueChangeListeners(), this._setupEventListeners(), this._updateOrderableState(), this._subscribeToStoreChanges(), this._syncDisabledState();
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Card composition restructures the block (toggles/reorders/adds attribute
|
|
135
|
+
* cells), which would corrupt a partner-managed (`ins-skip-compile`) block's
|
|
136
|
+
* preserved markup. There is no native tab-disable API, so the whole control
|
|
137
|
+
* container is rendered inert (greyed + non-interactive) instead.
|
|
138
|
+
*/
|
|
139
|
+
_syncDisabledState() {
|
|
140
|
+
var e;
|
|
141
|
+
const t = (e = this.getContainer()) == null ? void 0 : e.querySelector("[data-card-composition-control]");
|
|
142
|
+
if (!t)
|
|
143
|
+
return;
|
|
144
|
+
const r = gt(this.currentNode);
|
|
145
|
+
t.style.pointerEvents = r ? "none" : "", t.style.opacity = r ? "0.5" : "";
|
|
132
146
|
}
|
|
133
147
|
onTemplateNodeUpdated(t) {
|
|
134
|
-
super.onTemplateNodeUpdated(t), !this.reorderInProgress && (this._initializeComposition(), this._updateOrderableState());
|
|
148
|
+
super.onTemplateNodeUpdated(t), !this.reorderInProgress && (this._initializeComposition(), this._updateOrderableState(), this._syncDisabledState());
|
|
135
149
|
}
|
|
136
150
|
onDestroy() {
|
|
137
151
|
super.onDestroy(), this.eventController && (this.eventController.abort(), this.eventController = null), this.unsubscribeStore && (this.unsubscribeStore(), this.unsubscribeStore = null);
|
|
@@ -149,8 +163,8 @@ class Ht extends tt {
|
|
|
149
163
|
this._applyVisibilityToBlock(t.key, r);
|
|
150
164
|
});
|
|
151
165
|
});
|
|
152
|
-
for (let t = 0; t <
|
|
153
|
-
const r = `${
|
|
166
|
+
for (let t = 0; t < g; t++) {
|
|
167
|
+
const r = `${C}${t}`, e = t;
|
|
154
168
|
this.api.onValueChanged(r, (o) => {
|
|
155
169
|
this._onCustomAttributeChanged(e, o);
|
|
156
170
|
});
|
|
@@ -162,42 +176,36 @@ class Ht extends tt {
|
|
|
162
176
|
_readCompositionFromNode() {
|
|
163
177
|
if (!this.currentNode || !("getAttribute" in this.currentNode))
|
|
164
178
|
return [...P];
|
|
165
|
-
const t = this.currentNode.getAttribute(
|
|
166
|
-
|
|
167
|
-
return t.split(",").filter(Boolean);
|
|
168
|
-
const { composition: r } = $.getConfig(this.currentNode);
|
|
169
|
-
return r != null && r.length ? [...r] : [...P];
|
|
179
|
+
const t = this.currentNode.getAttribute(V);
|
|
180
|
+
return t ? t.split(",").filter(Boolean) : [...P];
|
|
170
181
|
}
|
|
171
182
|
_readCustomAttributesFromNode() {
|
|
172
183
|
if (!this.currentNode || !("getAttribute" in this.currentNode))
|
|
173
184
|
return [];
|
|
174
|
-
const t = this.currentNode.getAttribute(
|
|
175
|
-
if (t)
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
185
|
+
const t = this.currentNode.getAttribute(q);
|
|
186
|
+
if (!t)
|
|
187
|
+
return [];
|
|
188
|
+
try {
|
|
189
|
+
return JSON.parse(t);
|
|
190
|
+
} catch {
|
|
191
|
+
return [];
|
|
192
|
+
}
|
|
182
193
|
}
|
|
183
194
|
_readVisibilityFromRows() {
|
|
184
195
|
if (!this.currentNode)
|
|
185
196
|
return this._getDefaultVisibilities();
|
|
186
|
-
const t = Array.from(this.currentNode.querySelectorAll(
|
|
187
|
-
|
|
188
|
-
return this._mergeWithDefaults(r);
|
|
189
|
-
const e = $.getConfig(this.currentNode).visibility;
|
|
190
|
-
return this._mergeWithDefaults({ ...e });
|
|
197
|
+
const t = Array.from(this.currentNode.querySelectorAll(S)), r = this._extractVisibilityFromRows(t);
|
|
198
|
+
return this._mergeWithDefaults(r);
|
|
191
199
|
}
|
|
192
200
|
_getDefaultVisibilities() {
|
|
193
|
-
return { ...
|
|
201
|
+
return { ...F };
|
|
194
202
|
}
|
|
195
203
|
_extractVisibilityFromRows(t) {
|
|
196
204
|
const r = {};
|
|
197
205
|
return t.forEach((e) => {
|
|
198
206
|
if (!("getAttribute" in e))
|
|
199
207
|
return;
|
|
200
|
-
const o = e.getAttribute(y), s = e.getAttribute(
|
|
208
|
+
const o = e.getAttribute(y), s = e.getAttribute(v);
|
|
201
209
|
o && s !== null && (r[o] = this._parseVisibilityValue(s));
|
|
202
210
|
}), r;
|
|
203
211
|
}
|
|
@@ -205,7 +213,7 @@ class Ht extends tt {
|
|
|
205
213
|
return t === "1" || t === "true";
|
|
206
214
|
}
|
|
207
215
|
_mergeWithDefaults(t) {
|
|
208
|
-
return Object.entries(
|
|
216
|
+
return Object.entries(F).forEach(([r, e]) => {
|
|
209
217
|
r in t || (t[r] = e);
|
|
210
218
|
}), t;
|
|
211
219
|
}
|
|
@@ -229,19 +237,19 @@ class Ht extends tt {
|
|
|
229
237
|
return !1;
|
|
230
238
|
const s = new Set(r);
|
|
231
239
|
let i = 0, n = 0;
|
|
232
|
-
const
|
|
233
|
-
if (
|
|
234
|
-
const l = h.find((u) => u.key ===
|
|
240
|
+
const a = t.map((c) => {
|
|
241
|
+
if (At.has(c)) {
|
|
242
|
+
const l = h.find((u) => u.key === c);
|
|
235
243
|
return this._createBuiltInItemHtml(l, n++);
|
|
236
244
|
}
|
|
237
|
-
if (
|
|
238
|
-
const l =
|
|
245
|
+
if (c.startsWith(m)) {
|
|
246
|
+
const l = c.substring(m.length);
|
|
239
247
|
if (s.has(l))
|
|
240
|
-
return this._createCustomItemHtml(
|
|
248
|
+
return this._createCustomItemHtml(c, i++, n++);
|
|
241
249
|
}
|
|
242
250
|
return "";
|
|
243
251
|
}).join("");
|
|
244
|
-
return this._rescueTogglesToStore(e), this._rescueSelectsToStore(e), this._rescueDeleteButtonsToStore(e), this._rescueReorderIconsToStore(e), o.innerHTML =
|
|
252
|
+
return this._rescueTogglesToStore(e), this._rescueSelectsToStore(e), this._rescueDeleteButtonsToStore(e), this._rescueReorderIconsToStore(e), o.innerHTML = a, this._moveTogglesIntoItems(e), this._moveSelectsIntoItems(e, r.length), this._moveDeleteButtonsIntoItems(e, r.length), this._moveReorderIconsIntoItems(e, n), !0;
|
|
245
253
|
}
|
|
246
254
|
/**
|
|
247
255
|
* Attempts to reorder existing orderable-item elements to match the composition order.
|
|
@@ -253,27 +261,27 @@ class Ht extends tt {
|
|
|
253
261
|
const e = Array.from(t.querySelectorAll(".orderable-item"));
|
|
254
262
|
if (e.length !== r.length)
|
|
255
263
|
return !1;
|
|
256
|
-
const o = e.map((
|
|
264
|
+
const o = e.map((c) => c.dataset.key).filter(Boolean);
|
|
257
265
|
if (o.length !== r.length)
|
|
258
266
|
return !1;
|
|
259
267
|
const s = [...o].sort().join(","), i = [...r].sort().join(",");
|
|
260
|
-
if (s !== i || r.some((
|
|
268
|
+
if (s !== i || r.some((c) => c.startsWith(m)))
|
|
261
269
|
return !1;
|
|
262
270
|
const n = /* @__PURE__ */ new Map();
|
|
263
|
-
e.forEach((
|
|
264
|
-
const { key: l } =
|
|
271
|
+
e.forEach((c) => {
|
|
272
|
+
const { key: l } = c.dataset;
|
|
265
273
|
if (l) {
|
|
266
274
|
const u = n.get(l) || [];
|
|
267
|
-
u.push(
|
|
275
|
+
u.push(c), n.set(l, u);
|
|
268
276
|
}
|
|
269
277
|
});
|
|
270
|
-
const
|
|
271
|
-
return r.forEach((
|
|
272
|
-
const l = n.get(
|
|
278
|
+
const a = /* @__PURE__ */ new Map();
|
|
279
|
+
return r.forEach((c) => {
|
|
280
|
+
const l = n.get(c);
|
|
273
281
|
if (!l)
|
|
274
282
|
return;
|
|
275
|
-
const u =
|
|
276
|
-
|
|
283
|
+
const u = a.get(c) || 0;
|
|
284
|
+
a.set(c, u + 1), l[u] && t.appendChild(l[u]);
|
|
277
285
|
}), !0;
|
|
278
286
|
}
|
|
279
287
|
_createBuiltInItemHtml(t, r) {
|
|
@@ -321,8 +329,8 @@ class Ht extends tt {
|
|
|
321
329
|
_initializeCustomSelects(t) {
|
|
322
330
|
t.length !== 0 && setTimeout(() => {
|
|
323
331
|
t.forEach((r, e) => {
|
|
324
|
-
const o = `${
|
|
325
|
-
this.api.setUIEAttribute(o,
|
|
332
|
+
const o = `${C}${e}`, s = this._getSelectOptions(r, t);
|
|
333
|
+
this.api.setUIEAttribute(o, I.SELECTPICKER.items, s), this.api.updateValues({ [o]: r });
|
|
326
334
|
});
|
|
327
335
|
}, 0);
|
|
328
336
|
}
|
|
@@ -345,7 +353,7 @@ class Ht extends tt {
|
|
|
345
353
|
*/
|
|
346
354
|
_moveSelectsIntoItems(t, r) {
|
|
347
355
|
for (let e = 0; e < r; e++) {
|
|
348
|
-
const o = `${
|
|
356
|
+
const o = `${C}${e}`, s = t.querySelector(`[data-custom-select-key="${o}"]`), i = t.querySelector(`[data-custom-select-slot="${e}"]`);
|
|
349
357
|
if (s && i) {
|
|
350
358
|
const n = s.querySelector("ue-select");
|
|
351
359
|
n && i.appendChild(n);
|
|
@@ -372,8 +380,8 @@ class Ht extends tt {
|
|
|
372
380
|
* Same rescue pattern as _rescueTogglesToStore — prevents innerHTML from destroying them.
|
|
373
381
|
*/
|
|
374
382
|
_rescueSelectsToStore(t) {
|
|
375
|
-
for (let r = 0; r <
|
|
376
|
-
const e = `${
|
|
383
|
+
for (let r = 0; r < g; r++) {
|
|
384
|
+
const e = `${C}${r}`, o = t.querySelector(`[data-custom-select-key="${e}"]`), s = t.querySelector(`[data-custom-select-slot="${r}"]`);
|
|
377
385
|
if (s) {
|
|
378
386
|
const i = s.querySelector("ue-select");
|
|
379
387
|
i && o && o.appendChild(i);
|
|
@@ -386,7 +394,7 @@ class Ht extends tt {
|
|
|
386
394
|
*/
|
|
387
395
|
_moveDeleteButtonsIntoItems(t, r) {
|
|
388
396
|
for (let e = 0; e < r; e++) {
|
|
389
|
-
const o = `${
|
|
397
|
+
const o = `${R}${e}`, s = t.querySelector(`[data-custom-delete-key="${o}"]`), i = t.querySelector(`[data-custom-delete-slot="${e}"]`);
|
|
390
398
|
if (s && i) {
|
|
391
399
|
const n = s.querySelector("ue-button");
|
|
392
400
|
n && i.appendChild(n);
|
|
@@ -398,8 +406,8 @@ class Ht extends tt {
|
|
|
398
406
|
* Same rescue pattern as _rescueSelectsToStore — prevents innerHTML from destroying them.
|
|
399
407
|
*/
|
|
400
408
|
_rescueDeleteButtonsToStore(t) {
|
|
401
|
-
for (let r = 0; r <
|
|
402
|
-
const e = `${
|
|
409
|
+
for (let r = 0; r < g; r++) {
|
|
410
|
+
const e = `${R}${r}`, o = t.querySelector(`[data-custom-delete-key="${e}"]`), s = t.querySelector(`[data-custom-delete-slot="${r}"]`);
|
|
403
411
|
if (s) {
|
|
404
412
|
const i = s.querySelector("ue-button");
|
|
405
413
|
i && o && o.appendChild(i);
|
|
@@ -412,7 +420,7 @@ class Ht extends tt {
|
|
|
412
420
|
*/
|
|
413
421
|
_moveReorderIconsIntoItems(t, r) {
|
|
414
422
|
for (let e = 0; e < r; e++) {
|
|
415
|
-
const o = `${
|
|
423
|
+
const o = `${E}${e}`, s = t.querySelector(`[data-reorder-icon-key="${o}"]`), i = t.querySelector(`[data-reorder-icon-slot="${e}"]`);
|
|
416
424
|
if (s && i) {
|
|
417
425
|
const n = s.querySelector("ue-button");
|
|
418
426
|
n && i.appendChild(n);
|
|
@@ -424,9 +432,9 @@ class Ht extends tt {
|
|
|
424
432
|
* Same rescue pattern as _rescueDeleteButtonsToStore — prevents innerHTML from destroying them.
|
|
425
433
|
*/
|
|
426
434
|
_rescueReorderIconsToStore(t) {
|
|
427
|
-
const r = h.length +
|
|
435
|
+
const r = h.length + g;
|
|
428
436
|
for (let e = 0; e < r; e++) {
|
|
429
|
-
const o = `${
|
|
437
|
+
const o = `${E}${e}`, s = t.querySelector(`[data-reorder-icon-key="${o}"]`), i = t.querySelector(`[data-reorder-icon-slot="${e}"]`);
|
|
430
438
|
if (i) {
|
|
431
439
|
const n = i.querySelector("ue-button");
|
|
432
440
|
n && s && s.appendChild(n);
|
|
@@ -450,24 +458,24 @@ class Ht extends tt {
|
|
|
450
458
|
_setupDragAndDrop(t, r) {
|
|
451
459
|
let e = null, o = null;
|
|
452
460
|
t.addEventListener("dragstart", (s) => {
|
|
453
|
-
var
|
|
461
|
+
var a;
|
|
454
462
|
const n = s.target.closest(".orderable-item");
|
|
455
|
-
n && (e = n, n.classList.add("dragging"), (
|
|
463
|
+
n && (e = n, n.classList.add("dragging"), (a = s.dataTransfer) == null || a.setData("text/plain", n.dataset.key || ""));
|
|
456
464
|
}, { signal: r }), t.addEventListener("dragend", () => {
|
|
457
465
|
e && e.classList.remove("dragging"), e = null, o == null || o.classList.remove("drag-over"), o = null;
|
|
458
466
|
}, { signal: r }), t.addEventListener("dragover", (s) => {
|
|
459
467
|
s.preventDefault();
|
|
460
|
-
const n = s.target.closest(".orderable-item"),
|
|
461
|
-
|
|
468
|
+
const n = s.target.closest(".orderable-item"), a = n && n !== e ? n : null;
|
|
469
|
+
a !== o && (o == null || o.classList.remove("drag-over"), o = a, o == null || o.classList.add("drag-over"));
|
|
462
470
|
}, { signal: r }), t.addEventListener("drop", (s) => {
|
|
463
471
|
s.preventDefault();
|
|
464
472
|
const n = s.target.closest(".orderable-item");
|
|
465
473
|
if (!n || !e || n === e)
|
|
466
474
|
return;
|
|
467
|
-
const
|
|
468
|
-
s.clientY <
|
|
469
|
-
const u = t.querySelectorAll(".orderable-item"),
|
|
470
|
-
this._onReorder(
|
|
475
|
+
const a = n.getBoundingClientRect(), c = a.top + a.height / 2;
|
|
476
|
+
s.clientY < c ? t.insertBefore(e, n) : t.insertBefore(e, n.nextSibling), o == null || o.classList.remove("drag-over"), o = null, e.classList.remove("dragging");
|
|
477
|
+
const u = t.querySelectorAll(".orderable-item"), d = Array.from(u).map((b) => b.dataset.key).filter(Boolean);
|
|
478
|
+
this._onReorder(d), e = null;
|
|
471
479
|
}, { signal: r });
|
|
472
480
|
}
|
|
473
481
|
_setupDeleteHandler(t, r) {
|
|
@@ -483,7 +491,7 @@ class Ht extends tt {
|
|
|
483
491
|
// Actions (Add, Delete, Reorder)
|
|
484
492
|
// ========================================================================
|
|
485
493
|
_onAddAttribute(t, r) {
|
|
486
|
-
const e = `${
|
|
494
|
+
const e = `${m}${t}`, o = this._readCompositionFromNode();
|
|
487
495
|
o.push(e);
|
|
488
496
|
const s = [...this._readCustomAttributesFromNode(), t];
|
|
489
497
|
this._updateBothAttributes(o, s), this._injectCustomAttributeHtml(t, r, e, o), this._renderOrderableItems(o, s), this._initializeCustomSelects(s), this._updateAddButtonState();
|
|
@@ -496,7 +504,7 @@ class Ht extends tt {
|
|
|
496
504
|
const r = this._readCustomAttributesFromNode();
|
|
497
505
|
if (r[t] === void 0)
|
|
498
506
|
return;
|
|
499
|
-
const o = this._readCompositionFromNode(), s = this._findNthCustomKeyIndex(o, t), i = o.filter((
|
|
507
|
+
const o = this._readCompositionFromNode(), s = this._findNthCustomKeyIndex(o, t), i = o.filter((a, c) => c !== s), n = r.filter((a, c) => c !== t);
|
|
500
508
|
this._updateBothAttributes(i, n), this._removeCustomAttributeHtml(i), this._renderOrderableItems(i, n), this._initializeCustomSelects(n), this._updateAddButtonState();
|
|
501
509
|
}
|
|
502
510
|
/**
|
|
@@ -507,13 +515,13 @@ class Ht extends tt {
|
|
|
507
515
|
const e = this._readCustomAttributesFromNode(), o = e[t];
|
|
508
516
|
if (o === void 0 || o === r)
|
|
509
517
|
return;
|
|
510
|
-
const s = `${
|
|
518
|
+
const s = `${m}${r}`, i = this._readCompositionFromNode(), n = this._findNthCustomKeyIndex(i, t);
|
|
511
519
|
n !== -1 && (i[n] = s), e[t] = r;
|
|
512
|
-
const
|
|
513
|
-
this._updateBothAttributes(i, e), this._injectCustomAttributeHtml(r,
|
|
520
|
+
const a = this._getDisplayNameForAttribute(r);
|
|
521
|
+
this._updateBothAttributes(i, e), this._injectCustomAttributeHtml(r, a, s, i), this._renderOrderableItems(i, e), this._initializeCustomSelects(e);
|
|
514
522
|
}
|
|
515
523
|
_onReorder(t) {
|
|
516
|
-
const r = t.filter((e) => e.startsWith(
|
|
524
|
+
const r = t.filter((e) => e.startsWith(m)).map((e) => e.substring(m.length));
|
|
517
525
|
this.reorderInProgress = !0;
|
|
518
526
|
try {
|
|
519
527
|
this._updateBothAttributes(t, r), this._getCurrentLayout() === "grid" && this._reorderProductAttributes(t);
|
|
@@ -531,61 +539,61 @@ class Ht extends tt {
|
|
|
531
539
|
this._getCurrentLayout() === "grid" ? this._injectGridAttributeRow(t, r, e, o) : this._injectListAttributeRow(t, r, e, o);
|
|
532
540
|
}
|
|
533
541
|
_injectGridAttributeRow(t, r, e, o) {
|
|
534
|
-
const s = this.currentNode.querySelectorAll(
|
|
542
|
+
const s = this.currentNode.querySelectorAll(N);
|
|
535
543
|
if (!(s != null && s.length))
|
|
536
544
|
return;
|
|
537
|
-
const i =
|
|
545
|
+
const i = nt.getConfig(this.currentNode), a = `0 ${Math.floor(i.columnSpacing / 2)}px`, c = this.api.getDocumentModifier(), l = this.store.recommendationProducts.length;
|
|
538
546
|
let u = 0;
|
|
539
|
-
s.forEach((
|
|
547
|
+
s.forEach((d) => {
|
|
540
548
|
var k;
|
|
541
|
-
const b =
|
|
542
|
-
if (
|
|
543
|
-
const
|
|
549
|
+
const b = d.querySelector(S), $ = ((k = b == null ? void 0 : b.querySelectorAll(`.${at}`)) == null ? void 0 : k.length) || 1, U = (100 / $).toFixed(2), { bgStyle: j, bgAttr: W } = this._extractSegmentBgFromCard(d), O = l > 0 ? Math.min($, l - u) : $, K = o.map((H) => {
|
|
550
|
+
if (H === e) {
|
|
551
|
+
const z = Array.from(
|
|
544
552
|
{ length: O },
|
|
545
|
-
(
|
|
546
|
-
const
|
|
553
|
+
(St, Y) => {
|
|
554
|
+
const X = this._resolveAttributeContent(
|
|
547
555
|
t,
|
|
548
556
|
r,
|
|
549
|
-
u +
|
|
557
|
+
u + Y
|
|
550
558
|
);
|
|
551
559
|
return this._getGridCellHtml(
|
|
552
560
|
t,
|
|
553
|
-
|
|
554
|
-
|
|
561
|
+
X,
|
|
562
|
+
U,
|
|
563
|
+
j,
|
|
555
564
|
W,
|
|
556
|
-
|
|
557
|
-
c
|
|
565
|
+
a
|
|
558
566
|
);
|
|
559
567
|
}
|
|
560
|
-
).join(""),
|
|
561
|
-
return `<tr class="recommendation-attribute-row" ${y}="${e}" ${
|
|
568
|
+
).join(""), G = dt(U, a).repeat($ - O);
|
|
569
|
+
return `<tr class="recommendation-attribute-row" ${y}="${e}" ${v}="1">${z}${G}</tr>`;
|
|
562
570
|
}
|
|
563
|
-
const D =
|
|
564
|
-
`${
|
|
571
|
+
const D = d.querySelector(
|
|
572
|
+
`${S}[${y}="${H}"]`
|
|
565
573
|
);
|
|
566
574
|
return D && "getOuterHTML" in D ? D.getOuterHTML() : "";
|
|
567
575
|
}).join("");
|
|
568
|
-
u += O, l > 0 && u >= l && (u = 0),
|
|
569
|
-
}),
|
|
576
|
+
u += O, l > 0 && u >= l && (u = 0), c.modifyHtml(d).setInnerHtml(K);
|
|
577
|
+
}), c.apply(new A(`${this.api.translate("Add custom attribute")}: ${r}`));
|
|
570
578
|
}
|
|
571
579
|
_injectListAttributeRow(t, r, e, o) {
|
|
572
|
-
const s = this.currentNode.querySelectorAll(
|
|
580
|
+
const s = this.currentNode.querySelectorAll(M);
|
|
573
581
|
if (!(s != null && s.length))
|
|
574
582
|
return;
|
|
575
|
-
const i = o.filter((
|
|
576
|
-
s.forEach((
|
|
583
|
+
const i = o.filter((a) => a !== L && a !== B), n = this.api.getDocumentModifier();
|
|
584
|
+
s.forEach((a, c) => {
|
|
577
585
|
const l = i.map((u) => {
|
|
578
586
|
if (u === e) {
|
|
579
|
-
const b = this._resolveAttributeContent(t, r,
|
|
587
|
+
const b = this._resolveAttributeContent(t, r, c);
|
|
580
588
|
return this._getListRowHtml(t, b, e);
|
|
581
589
|
}
|
|
582
|
-
const
|
|
583
|
-
`${
|
|
590
|
+
const d = a.querySelector(
|
|
591
|
+
`${S}[${y}="${u}"]`
|
|
584
592
|
);
|
|
585
|
-
return
|
|
593
|
+
return d && "getOuterHTML" in d ? d.getOuterHTML() : "";
|
|
586
594
|
}).join("");
|
|
587
|
-
n.modifyHtml(
|
|
588
|
-
}), n.apply(new
|
|
595
|
+
n.modifyHtml(a).setInnerHtml(l);
|
|
596
|
+
}), n.apply(new A(`${this.api.translate("Add custom attribute")}: ${r}`));
|
|
589
597
|
}
|
|
590
598
|
/**
|
|
591
599
|
* Removes a custom attribute by rebuilding product card content without it.
|
|
@@ -596,19 +604,19 @@ class Ht extends tt {
|
|
|
596
604
|
return;
|
|
597
605
|
const r = this._getCurrentLayout(), e = this.api.getDocumentModifier();
|
|
598
606
|
if (r === "grid") {
|
|
599
|
-
const o = this.currentNode.querySelectorAll(
|
|
607
|
+
const o = this.currentNode.querySelectorAll(N);
|
|
600
608
|
o == null || o.forEach((s) => {
|
|
601
609
|
const i = this._buildCompositionHtml(s, t);
|
|
602
610
|
e.modifyHtml(s).setInnerHtml(i);
|
|
603
611
|
});
|
|
604
612
|
} else {
|
|
605
|
-
const o = t.filter((i) => i !==
|
|
613
|
+
const o = t.filter((i) => i !== L && i !== B), s = this.currentNode.querySelectorAll(M);
|
|
606
614
|
s == null || s.forEach((i) => {
|
|
607
615
|
const n = this._buildCompositionHtml(i, o);
|
|
608
616
|
e.modifyHtml(i).setInnerHtml(n);
|
|
609
617
|
});
|
|
610
618
|
}
|
|
611
|
-
e.apply(new
|
|
619
|
+
e.apply(new A(this.api.translate("Remove custom attribute")));
|
|
612
620
|
}
|
|
613
621
|
// ========================================================================
|
|
614
622
|
// DOM Mutation (Block Root Attributes, Reorder)
|
|
@@ -621,13 +629,7 @@ class Ht extends tt {
|
|
|
621
629
|
* producing a flicker on the custom attribute dropdowns.
|
|
622
630
|
*/
|
|
623
631
|
_updateBothAttributes(t, r) {
|
|
624
|
-
|
|
625
|
-
return;
|
|
626
|
-
const e = {
|
|
627
|
-
...$.getConfig(this.currentNode),
|
|
628
|
-
composition: t
|
|
629
|
-
};
|
|
630
|
-
this.api.getDocumentModifier().modifyHtml(this.currentNode).setAttribute(x, t.join(",")).setAttribute(F, JSON.stringify(r)).setNodeConfig(e).apply(new C(this.api.translate("Update card composition")));
|
|
632
|
+
this.currentNode && this.api.getDocumentModifier().modifyHtml(this.currentNode).setAttribute(V, t.join(",")).setAttribute(q, JSON.stringify(r)).apply(new A(this.api.translate("Update card composition")));
|
|
631
633
|
}
|
|
632
634
|
/**
|
|
633
635
|
* Reorders attribute rows within each product card based on composition order.
|
|
@@ -636,14 +638,14 @@ class Ht extends tt {
|
|
|
636
638
|
_reorderProductAttributes(t) {
|
|
637
639
|
if (!this.currentNode)
|
|
638
640
|
return;
|
|
639
|
-
const r = this.currentNode.querySelectorAll(
|
|
641
|
+
const r = this.currentNode.querySelectorAll(N);
|
|
640
642
|
if (!(r != null && r.length))
|
|
641
643
|
return;
|
|
642
644
|
const e = this.api.getDocumentModifier();
|
|
643
645
|
r.forEach((o) => {
|
|
644
646
|
const s = this._buildCompositionHtml(o, t);
|
|
645
647
|
e.modifyHtml(o).setInnerHtml(s);
|
|
646
|
-
}), e.apply(new
|
|
648
|
+
}), e.apply(new A(this.api.translate("Reorder product attributes")));
|
|
647
649
|
}
|
|
648
650
|
/**
|
|
649
651
|
* Builds HTML string with attributes ordered according to composition.
|
|
@@ -651,7 +653,7 @@ class Ht extends tt {
|
|
|
651
653
|
*/
|
|
652
654
|
_buildCompositionHtml(t, r) {
|
|
653
655
|
return r.reduce((e, o) => {
|
|
654
|
-
const s = t.querySelector(`${
|
|
656
|
+
const s = t.querySelector(`${S}[${y}="${o}"]`);
|
|
655
657
|
return s && "getOuterHTML" in s ? e + s.getOuterHTML() : e;
|
|
656
658
|
}, "");
|
|
657
659
|
}
|
|
@@ -661,19 +663,14 @@ class Ht extends tt {
|
|
|
661
663
|
_applyVisibilityToBlock(t, r) {
|
|
662
664
|
if (!this.currentNode)
|
|
663
665
|
return;
|
|
664
|
-
const e = this.currentNode.querySelectorAll(`${
|
|
666
|
+
const e = this.currentNode.querySelectorAll(`${S}[${y}="${t}"]`);
|
|
665
667
|
if (!(e != null && e.length))
|
|
666
668
|
return;
|
|
667
669
|
const o = r ? "1" : "0", s = r ? this.api.translate("visible") : this.api.translate("hidden"), i = `${this.api.translate("Set visibility")}: ${t} → ${s}`, n = this.api.getDocumentModifier();
|
|
668
670
|
e.forEach((a) => {
|
|
669
|
-
const
|
|
670
|
-
n.modifyHtml(a).setStyle("display",
|
|
671
|
-
});
|
|
672
|
-
const c = {
|
|
673
|
-
...$.getConfig(this.currentNode),
|
|
674
|
-
visibility: { ...this._readVisibilityFromRows(), [t]: r }
|
|
675
|
-
};
|
|
676
|
-
n.modifyHtml(this.currentNode).setNodeConfig(c), n.apply(new C(i));
|
|
671
|
+
const c = ft(a), l = r ? c : "none";
|
|
672
|
+
n.modifyHtml(a).setStyle("display", l).setAttribute(v, o);
|
|
673
|
+
}), n.apply(new A(i));
|
|
677
674
|
}
|
|
678
675
|
// ========================================================================
|
|
679
676
|
// Utilities
|
|
@@ -686,7 +683,7 @@ class Ht extends tt {
|
|
|
686
683
|
_findNthCustomKeyIndex(t, r) {
|
|
687
684
|
let e = 0;
|
|
688
685
|
for (let o = 0; o < t.length; o++)
|
|
689
|
-
if (t[o].startsWith(
|
|
686
|
+
if (t[o].startsWith(m)) {
|
|
690
687
|
if (e === r)
|
|
691
688
|
return o;
|
|
692
689
|
e++;
|
|
@@ -694,7 +691,7 @@ class Ht extends tt {
|
|
|
694
691
|
return -1;
|
|
695
692
|
}
|
|
696
693
|
_getCurrentLayout() {
|
|
697
|
-
return this.store.recommendationConfigs.orientation ||
|
|
694
|
+
return this.store.recommendationConfigs.orientation || bt(this.currentNode);
|
|
698
695
|
}
|
|
699
696
|
/**
|
|
700
697
|
* Extracts background color properties from existing card elements.
|
|
@@ -745,10 +742,10 @@ class Ht extends tt {
|
|
|
745
742
|
* or when all available filters have already been added (no unused attributes left).
|
|
746
743
|
*/
|
|
747
744
|
_updateAddButtonState() {
|
|
748
|
-
const t = this._readCustomAttributesFromNode(), r = t.length >=
|
|
745
|
+
const t = this._readCustomAttributesFromNode(), r = t.length >= g, e = new Set(t), o = this._getAddableFilters(), s = o.length > 0 && o.every((i) => e.has(i.attributeName));
|
|
749
746
|
this.api.setUIEAttribute(
|
|
750
|
-
|
|
751
|
-
|
|
747
|
+
x.ADD_ATTRIBUTE,
|
|
748
|
+
I.BUTTON.disabled,
|
|
752
749
|
r || s ? "true" : "false"
|
|
753
750
|
);
|
|
754
751
|
}
|
|
@@ -771,7 +768,7 @@ class Ht extends tt {
|
|
|
771
768
|
* excluding default attributes already covered by built-in toggle items.
|
|
772
769
|
*/
|
|
773
770
|
_getAddableFilters() {
|
|
774
|
-
return Object.values(this.store.filterList).filter((t) => !(t.type === "defaultAttribute" &&
|
|
771
|
+
return Object.values(this.store.filterList).filter((t) => !(t.type === "defaultAttribute" && it.has(t.attributeName)));
|
|
775
772
|
}
|
|
776
773
|
/**
|
|
777
774
|
* Looks up the display name for an attribute from the store's filterList.
|
|
@@ -788,28 +785,28 @@ class Ht extends tt {
|
|
|
788
785
|
_resolveAttributeContent(t, r, e) {
|
|
789
786
|
var n;
|
|
790
787
|
const s = this.store.recommendationProducts[e], i = pt(t, this.store.filterList) ? s == null ? void 0 : s[t] : (n = s == null ? void 0 : s.product_attributes) == null ? void 0 : n[t];
|
|
791
|
-
return
|
|
788
|
+
return _t(i) ?? r;
|
|
792
789
|
}
|
|
793
790
|
_getGridCellHtml(t, r, e, o = "", s = "", i = "") {
|
|
794
|
-
const n = `${
|
|
791
|
+
const n = `${m}${t}`, a = w(ct, [n], this.store.filterList), c = {
|
|
795
792
|
[t]: r,
|
|
796
793
|
product_attributes: { [t]: r }
|
|
797
794
|
};
|
|
798
|
-
let l =
|
|
795
|
+
let l = a[n](c);
|
|
799
796
|
return l = l.replace("<td", `<td width="${e}%"`), i && (l = l.replace(
|
|
800
797
|
`padding: ${ut}`,
|
|
801
798
|
`padding: ${i}`
|
|
802
799
|
)), o && (l = l.replace(/style="table-layout: fixed;"/, `style="table-layout: fixed; ${o}"`)), s && (l = l.replace(/border="0"/, `border="0" bgcolor="${s}"`)), l;
|
|
803
800
|
}
|
|
804
801
|
_getListRowHtml(t, r, e) {
|
|
805
|
-
const o =
|
|
802
|
+
const o = w(mt, [e], this.store.filterList), s = {
|
|
806
803
|
[t]: r,
|
|
807
804
|
product_attributes: { [t]: r }
|
|
808
805
|
}, n = o[e](s).replace(/<tr>/, "").replace(/<\/tr>/, "");
|
|
809
|
-
return `<tr class="recommendation-attribute-row" ${y}="${e}" ${
|
|
806
|
+
return `<tr class="recommendation-attribute-row" ${y}="${e}" ${v}="1">${n}</tr>`;
|
|
810
807
|
}
|
|
811
808
|
}
|
|
812
809
|
export {
|
|
813
|
-
|
|
814
|
-
|
|
810
|
+
yt as COMPOSITION_CONTROL_BLOCK_ID,
|
|
811
|
+
Ut as RecommendationCardCompositionControl
|
|
815
812
|
};
|