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