@useinsider/guido 3.8.1 → 3.8.2-beta.06011ff
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/components/organisms/email-preview/desktop-preview/DesktopPreview.vue.js +8 -8
- package/dist/components/organisms/email-preview/desktop-preview/DesktopPreview.vue2.js +15 -12
- package/dist/components/organisms/email-preview/mobile-preview/ContentView.vue.js +5 -5
- package/dist/components/organisms/email-preview/mobile-preview/ContentView.vue2.js +16 -15
- package/dist/components/organisms/unsubscribe/UnsubscribePageSelection.vue.js +5 -5
- package/dist/components/organisms/unsubscribe/UnsubscribePageSelection.vue2.js +42 -37
- package/dist/components/organisms/unsubscribe/UnsubscribeTypeSelection.vue.js +3 -3
- package/dist/components/organisms/unsubscribe/UnsubscribeTypeSelection.vue2.js +40 -37
- package/dist/composables/useHtmlCompiler.js +13 -10
- package/dist/composables/useHtmlValidator.js +180 -133
- package/dist/composables/usePreviewInteractionGuard.js +17 -0
- package/dist/composables/useSave.js +14 -14
- package/dist/composables/validators/useUnsubscribeBlockValidator.js +26 -17
- package/dist/config/compiler/htmlCompilerRules.js +38 -10
- package/dist/config/compiler/recommendationCompilerRules.js +83 -108
- package/dist/config/compiler/utils/recommendationCompilerUtils.js +58 -57
- 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/constants/selectors.js +26 -20
- package/dist/extensions/Blocks/Recommendation/controls/cardComposition/index.js +55 -41
- package/dist/extensions/Blocks/Recommendation/controls/main/algorithm.js +22 -21
- package/dist/extensions/Blocks/Recommendation/controls/main/index.js +58 -57
- package/dist/extensions/Blocks/Recommendation/controls/main/layoutOrientation.js +43 -31
- package/dist/extensions/Blocks/Recommendation/controls/main/productCount.js +3 -2
- package/dist/extensions/Blocks/Recommendation/controls/main/productLayout.js +55 -45
- package/dist/extensions/Blocks/Recommendation/controls/main/utils.js +60 -53
- package/dist/extensions/Blocks/Recommendation/controls/syncInfoMessage.js +7 -6
- package/dist/extensions/Blocks/Recommendation/extension.js +3 -2
- package/dist/extensions/Blocks/Recommendation/recommendation.css.js +62 -4
- 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 +7 -6
- package/dist/extensions/Blocks/Recommendation/templates/utils.js +1 -1
- package/dist/extensions/Blocks/Unsubscribe/block.js +40 -37
- package/dist/extensions/Blocks/Unsubscribe/control.js +19 -16
- package/dist/extensions/Blocks/common-control.js +58 -45
- package/dist/guido.css +1 -1
- package/dist/src/composables/useHtmlValidator.d.ts +27 -0
- package/dist/src/composables/useHtmlValidator.test.d.ts +1 -0
- package/dist/src/composables/usePreviewInteractionGuard.d.ts +3 -0
- package/dist/src/composables/validators/useUnsubscribeBlockValidator.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/algorithm.d.ts +1 -1
- 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/dist/src/extensions/Blocks/common-control.d.ts +7 -0
- package/dist/src/stores/unsubscribe.d.ts +11 -1
- package/dist/src/utils/ampErrorFilter.d.ts +1 -0
- package/dist/stores/unsubscribe.js +8 -7
- package/dist/utils/ampErrorFilter.js +6 -5
- package/package.json +1 -1
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import { useRecommendation as
|
|
2
|
-
import { DUMMY_IMAGE_MAPPINGS as
|
|
3
|
-
import { prepareRecommendationBlocks as
|
|
4
|
-
const
|
|
1
|
+
import { useRecommendation as N } from "../../composables/useRecommendation.js";
|
|
2
|
+
import { DUMMY_IMAGE_MAPPINGS as M, REGEX as d, VerticalOrientation as $, CSS as n, ATTRIBUTES as p, CONDITIONS as T, HTML as g } from "../../enums/recommendation.js";
|
|
3
|
+
import { prepareRecommendationBlocks as O } from "./utils/recommendationCompilerUtils.js";
|
|
4
|
+
const U = [
|
|
5
5
|
{
|
|
6
6
|
id: "replace-images-with-variable-names",
|
|
7
7
|
description: "Replacing dummy images with variable names in recommendation module",
|
|
8
8
|
type: "custom",
|
|
9
|
-
processor: (
|
|
10
|
-
let e =
|
|
11
|
-
return Object.entries(
|
|
12
|
-
Object.entries(
|
|
13
|
-
e = e.replaceAll(
|
|
9
|
+
processor: (o) => {
|
|
10
|
+
let e = o;
|
|
11
|
+
return Object.entries(M).forEach(([, r]) => {
|
|
12
|
+
Object.entries(r).forEach(([t, i]) => {
|
|
13
|
+
e = e.replaceAll(i, `{{${t}}}`);
|
|
14
14
|
});
|
|
15
15
|
}), e;
|
|
16
16
|
},
|
|
@@ -41,21 +41,21 @@ const w = [
|
|
|
41
41
|
id: "add-recommendation-unresponsive-css",
|
|
42
42
|
description: "Adding recommendation unresponsive css",
|
|
43
43
|
type: "custom",
|
|
44
|
-
processor: (
|
|
45
|
-
const { calculateCardWidth: e, getRecommendationCampaignData:
|
|
46
|
-
let
|
|
47
|
-
const
|
|
48
|
-
if (
|
|
49
|
-
const
|
|
50
|
-
if (
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
}),
|
|
54
|
-
const
|
|
55
|
-
|
|
44
|
+
processor: (o) => {
|
|
45
|
+
const { calculateCardWidth: e, getRecommendationCampaignData: r } = N();
|
|
46
|
+
let t = o;
|
|
47
|
+
const i = t.match(d.ID);
|
|
48
|
+
if (i) {
|
|
49
|
+
const s = [];
|
|
50
|
+
if (i.forEach((c) => {
|
|
51
|
+
const m = /recommendation-id="(.*?)"/i.exec(c), E = m ? m[1].trim() : "", u = r(E);
|
|
52
|
+
u.textTrimming && u.orientation === $ && s.push(e(u));
|
|
53
|
+
}), s.length) {
|
|
54
|
+
const c = `width:${Math.min(...s)}px!important;`;
|
|
55
|
+
t = t.replace(n.REGULAR_NAME_HEIGHT, `${n.TRIMMED_NAME_HEIGHT} ${c} ${n.ELLIPSIS}`).replace(n.REGULAR_NAME_CONTAINER_HEIGHT, n.TRIMMED_NAME_CONTAINER_CSS).replace(n.RESPONSIVE_NAME_SIZE, `${n.RESPONSIVE_NAME_HEIGHT} ${c} ${n.ELLIPSIS}`).replace(n.RESPONSIVE_NAME_CONTAINER_HEIGHT, n.TRIMMED_RESPONSIVE_NAME_CONTAINER_CSS);
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
|
-
return
|
|
58
|
+
return t;
|
|
59
59
|
},
|
|
60
60
|
priority: 52
|
|
61
61
|
},
|
|
@@ -63,34 +63,34 @@ const w = [
|
|
|
63
63
|
id: "prepare-recommendations",
|
|
64
64
|
description: "Replacing product data with template variables in recommendation blocks",
|
|
65
65
|
type: "custom",
|
|
66
|
-
processor: (
|
|
66
|
+
processor: (o) => O(o),
|
|
67
67
|
priority: 48
|
|
68
68
|
},
|
|
69
69
|
{
|
|
70
70
|
id: "add-discount-conditions",
|
|
71
71
|
description: "Adding discount conditions to the recommendation block",
|
|
72
72
|
type: "custom",
|
|
73
|
-
processor: (
|
|
74
|
-
let e =
|
|
75
|
-
const
|
|
76
|
-
return
|
|
77
|
-
const
|
|
78
|
-
if (!
|
|
73
|
+
processor: (o) => {
|
|
74
|
+
let e = o;
|
|
75
|
+
const r = e.match(d.ATTRIBUTE_PARAGRAPH), { getRecommendationCampaignData: t } = N();
|
|
76
|
+
return r !== null && r.forEach((i) => {
|
|
77
|
+
const s = i.match(d.CUSTOM_FIELD);
|
|
78
|
+
if (!s)
|
|
79
79
|
return;
|
|
80
|
-
const [
|
|
81
|
-
if (!
|
|
80
|
+
const [c] = s, m = c.match(d.CUSTOM_FIELD_INDEXES_PART), E = c.match(d.CUSTOM_FIELD_NAME_PART), u = i.match(d.ATTRIBUTE_PARAGRAPH_START_TAG);
|
|
81
|
+
if (!m || !E || !u)
|
|
82
82
|
return;
|
|
83
|
-
const [
|
|
84
|
-
let
|
|
85
|
-
if (
|
|
86
|
-
const
|
|
87
|
-
|
|
83
|
+
const [A] = m, [I] = E, [R] = u, b = I.substring(1, I.length - 2), S = R.match(d.COMPOSITION) !== null;
|
|
84
|
+
let a = c;
|
|
85
|
+
if (S) {
|
|
86
|
+
const f = A.substring(2, A.length - 3), l = t(f);
|
|
87
|
+
b === p.OMNIBUS_PRICE && (l.priceBeforeTextValue && (a = `${l.priceBeforeTextValue}${a}`), l.priceAfterTextValue && (a = `${a}${l.priceAfterTextValue}`)), b === p.OMNIBUS_DISCOUNT && (l.discountBeforeTextValue && (a = `${l.discountBeforeTextValue}${a}`), l.discountAfterTextValue && (a = `${a}${l.discountAfterTextValue}`));
|
|
88
88
|
}
|
|
89
|
-
const
|
|
90
|
-
let
|
|
91
|
-
|
|
92
|
-
const
|
|
93
|
-
e = e.replace(
|
|
89
|
+
const _ = A.substring(2);
|
|
90
|
+
let y = "";
|
|
91
|
+
b in T.IF && (y = T.IF[b].replaceAll(`{${p.DISCOUNT}}`, `${_}${p.DISCOUNT}`).replaceAll(`{${p.OMNIBUS_DISCOUNT}}`, `${_}${p.OMNIBUS_DISCOUNT}`).replaceAll(`{${p.OMNIBUS_PRICE}}`, `${_}${p.OMNIBUS_PRICE}`));
|
|
92
|
+
const C = `${R}${a}${g.PARAGRAPH_END_TAG}`, h = `${y}${S ? C : i}${T.ELSE}${R}${g.PARAGRAPH_END_TAG}${T.END_IF}`;
|
|
93
|
+
e = e.replace(i, h);
|
|
94
94
|
}), e;
|
|
95
95
|
},
|
|
96
96
|
priority: 53
|
|
@@ -110,11 +110,11 @@ const w = [
|
|
|
110
110
|
type: "custom",
|
|
111
111
|
// Scoped to REC_START/REC_END markers so it cannot strip `product-attr`
|
|
112
112
|
// from Items block elements, which the items compiler rule depends on.
|
|
113
|
-
processor: (
|
|
113
|
+
processor: (o) => {
|
|
114
114
|
const e = /\s+(?:esd-extension-block-id|data-attribute-type|data-visibility|data-text-before|data-text-after|product-attr|composition)="[^"]*"/g;
|
|
115
|
-
return
|
|
115
|
+
return o.replace(
|
|
116
116
|
/<!--REC_START-->([\s\S]*?)<!--REC_END-->/g,
|
|
117
|
-
(
|
|
117
|
+
(r, t) => `<!--REC_START-->${t.replace(e, "")}<!--REC_END-->`
|
|
118
118
|
);
|
|
119
119
|
},
|
|
120
120
|
priority: 55
|
|
@@ -123,8 +123,8 @@ const w = [
|
|
|
123
123
|
id: "strip-unused-recommendation-classes",
|
|
124
124
|
description: "Remove CSS classes not referenced by any style rule from recommendation elements",
|
|
125
125
|
type: "custom",
|
|
126
|
-
processor: (
|
|
127
|
-
let e =
|
|
126
|
+
processor: (o) => {
|
|
127
|
+
let e = o.replace(
|
|
128
128
|
/ class="(?:product-card-segment|attribute-cell|recommendation-attribute-row|product-image|product-name|product-price|product-old-price|product-omnibus-price|product-omnibus-discount|product-button|recommendation-product-row|product-card-wrapper)"/g,
|
|
129
129
|
""
|
|
130
130
|
);
|
|
@@ -136,8 +136,8 @@ const w = [
|
|
|
136
136
|
id: "remove-empty-mobile-layout-artifacts",
|
|
137
137
|
description: "Remove empty mobile container rows and unused mobile layout CSS",
|
|
138
138
|
type: "custom",
|
|
139
|
-
processor: (
|
|
140
|
-
let e =
|
|
139
|
+
processor: (o) => {
|
|
140
|
+
let e = o;
|
|
141
141
|
return e = e.replace(
|
|
142
142
|
/<tr[^>]*class="ins-recommendation-mobile-row"[^>]*><\/tr>/g,
|
|
143
143
|
""
|
|
@@ -146,75 +146,50 @@ const w = [
|
|
|
146
146
|
""
|
|
147
147
|
), e = e.replace(
|
|
148
148
|
/@media[^{]*max-width\s*:\s*480px[^{]*\{((?:[^{}]*\{[^{}]*\})*[^{}]*)\}/g,
|
|
149
|
-
(
|
|
150
|
-
const
|
|
151
|
-
return
|
|
149
|
+
(r, t) => {
|
|
150
|
+
const i = t.match(/[^{}]+\{[^{}]*\}/g) || [], s = /ins-recommendation|product-image-cell|button-cell|product-info-cell/;
|
|
151
|
+
return i.every((m) => s.test(m)) ? "" : r;
|
|
152
152
|
}
|
|
153
153
|
)), e;
|
|
154
154
|
},
|
|
155
155
|
priority: 57
|
|
156
156
|
},
|
|
157
157
|
{
|
|
158
|
-
id: "
|
|
159
|
-
|
|
158
|
+
id: "protect-gmail-button-link-color",
|
|
159
|
+
// Gmail overrides link colors with `.ii a[href] { color: #15c }`. Force
|
|
160
|
+
// `!important` on es-button anchor colors so the intended button text color
|
|
161
|
+
// wins. Kept INLINE (never moved into a <style> class) so it survives Gmail's
|
|
162
|
+
// clipping — "view entire message" strips <style> blocks but keeps inline styles.
|
|
163
|
+
// (SD-142395: split out of the removed deduplicate-inline-styles rule.)
|
|
164
|
+
description: "Force !important on es-button link color to defeat Gmail link-color override",
|
|
160
165
|
type: "custom",
|
|
161
|
-
processor: (
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
(
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
), l = /<!--REC_START-->([\s\S]*?)<!--REC_END-->/g, n = / style="([^"]*)"/g, s = /* @__PURE__ */ new Map();
|
|
169
|
-
let a = l.exec(e);
|
|
170
|
-
for (; a !== null; ) {
|
|
171
|
-
let o = n.exec(a[1]);
|
|
172
|
-
for (; o !== null; ) {
|
|
173
|
-
const [, r] = o;
|
|
174
|
-
s.set(r, (s.get(r) || 0) + 1), o = n.exec(a[1]);
|
|
175
|
-
}
|
|
176
|
-
n.lastIndex = 0, a = l.exec(e);
|
|
177
|
-
}
|
|
178
|
-
const i = /* @__PURE__ */ new Map(), u = [];
|
|
179
|
-
let _ = 0;
|
|
180
|
-
if (s.forEach((o, r) => {
|
|
181
|
-
if (!r.includes("v-text-anchor") && o >= 6) {
|
|
182
|
-
const t = `rc${_++}`, p = r.endsWith(";") ? r : `${r};`;
|
|
183
|
-
i.set(r, t), u.push(`.${t}{${p}}`);
|
|
184
|
-
}
|
|
185
|
-
}), i.size === 0) {
|
|
186
|
-
let o = e;
|
|
187
|
-
return o = o.replaceAll("<!--REC_START-->", ""), o = o.replaceAll("<!--REC_END-->", ""), o;
|
|
188
|
-
}
|
|
189
|
-
const R = (o) => o.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), b = (o, r) => `${o.slice(0, -1)} ${r}"`, I = /* @__PURE__ */ new Map();
|
|
190
|
-
i.forEach((o, r) => {
|
|
191
|
-
const t = R(r);
|
|
192
|
-
I.set(r, {
|
|
193
|
-
caseA: new RegExp(`(class="[^"]*")((?:[^>]*?)) style="${t}"`, "g"),
|
|
194
|
-
caseB: new RegExp(` style="${t}"((?:[^>]*?))(class="[^"]*")`, "g")
|
|
195
|
-
});
|
|
196
|
-
});
|
|
197
|
-
let d = e.replace("</style>", `${u.join("")}</style>`);
|
|
198
|
-
return d = d.replace(
|
|
199
|
-
/<!--REC_START-->([\s\S]*?)<!--REC_END-->/g,
|
|
200
|
-
(o, r) => {
|
|
201
|
-
let t = r;
|
|
202
|
-
return i.forEach((p, f) => {
|
|
203
|
-
const g = I.get(f);
|
|
204
|
-
t = t.replace(
|
|
205
|
-
g.caseA,
|
|
206
|
-
($, S, m) => b(S, p) + m
|
|
207
|
-
), t = t.replace(
|
|
208
|
-
g.caseB,
|
|
209
|
-
($, S, m) => S + b(m, p)
|
|
210
|
-
), t = t.replaceAll(` style="${f}"`, ` class="${p}"`);
|
|
211
|
-
}), t;
|
|
212
|
-
}
|
|
213
|
-
), d = d.replaceAll("<!--REC_START-->", ""), d = d.replaceAll("<!--REC_END-->", ""), d;
|
|
214
|
-
},
|
|
166
|
+
processor: (o) => o.replace(
|
|
167
|
+
/<a\b[^>]*\bes-button\b[^>]*>/g,
|
|
168
|
+
(e) => e.replace(
|
|
169
|
+
/([;"]color:)([^;"]+)/g,
|
|
170
|
+
(r, t, i) => i.includes("!important") ? r : `${t}${i} !important`
|
|
171
|
+
)
|
|
172
|
+
),
|
|
215
173
|
priority: 58
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
id: "minify-recommendation-whitespace",
|
|
177
|
+
// SD-142395: shrink the compiled recommendation block to keep emails under
|
|
178
|
+
// Gmail's ~102KB clip threshold. The editor templates emit deeply-indented
|
|
179
|
+
// markup that the P48 DOMParser round-trip preserves, and nothing else in the
|
|
180
|
+
// pipeline minifies it. Scoped to REC_START/REC_END so it only touches
|
|
181
|
+
// recommendation markup, and strips those markers last (relocated here from the
|
|
182
|
+
// removed deduplicate-inline-styles rule). Render-critical styles are left inline
|
|
183
|
+
// rather than classed, so they survive Gmail clipping.
|
|
184
|
+
description: "Collapse whitespace inside recommendation blocks and strip boundary markers",
|
|
185
|
+
type: "custom",
|
|
186
|
+
processor: (o) => {
|
|
187
|
+
const e = (r) => r.replace(/>\s+</g, "><").replace(/<[^>]+>/g, (t) => t.replace(/\s+/g, " "));
|
|
188
|
+
return o.replace(/<!--REC_START-->([\s\S]*?)<!--REC_END-->/g, (r, t) => e(t)).replaceAll("<!--REC_START-->", "").replaceAll("<!--REC_END-->", "");
|
|
189
|
+
},
|
|
190
|
+
priority: 99
|
|
216
191
|
}
|
|
217
192
|
];
|
|
218
193
|
export {
|
|
219
|
-
|
|
194
|
+
U as recommendationCompilerRules
|
|
220
195
|
};
|
|
@@ -2,61 +2,62 @@ import { useConfig as _ } from "../../../composables/useConfig.js";
|
|
|
2
2
|
import { useRecommendation as g } from "../../../composables/useRecommendation.js";
|
|
3
3
|
import { CSS_CLASS_RECO_BUTTON as q } from "../../../extensions/Blocks/Recommendation/constants/selectors.js";
|
|
4
4
|
import { useRecommendationExtensionStore as C } from "../../../extensions/Blocks/Recommendation/store/recommendation.js";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
import { isIgnoredRecommendationBlock as w } from "./recommendationIgnoreUtils.js";
|
|
6
|
+
function h(r, n, e, o, c = "") {
|
|
7
|
+
const i = `{{${c}${r}_${n}_${e}}}`, t = `{{${c}${r}_${n}_currency}}`;
|
|
8
|
+
return o === "before" ? `${t} ${i}` : `${i} ${t}`;
|
|
8
9
|
}
|
|
9
|
-
function
|
|
10
|
+
function f(r) {
|
|
10
11
|
let n = r;
|
|
11
12
|
for (; n.children.length === 1; )
|
|
12
13
|
[n] = n.children;
|
|
13
14
|
return n;
|
|
14
15
|
}
|
|
15
|
-
function A(r, n, e, o,
|
|
16
|
+
function A(r, n, e, o, c, i) {
|
|
16
17
|
switch (n) {
|
|
17
18
|
case "productImage": {
|
|
18
19
|
const t = r.querySelector("img");
|
|
19
|
-
t && (t.setAttribute("src", `{{${
|
|
20
|
+
t && (t.setAttribute("src", `{{${i}${e}_${o}_image_url}}`), t.setAttribute("alt", `{{${i}${e}_${o}_name}}`));
|
|
20
21
|
const s = r.querySelector("a");
|
|
21
|
-
s && (s.setAttribute("href", `{{${
|
|
22
|
+
s && (s.setAttribute("href", `{{${i}${e}_${o}_url}}`), s.classList.add(q));
|
|
22
23
|
break;
|
|
23
24
|
}
|
|
24
25
|
case "productName": {
|
|
25
26
|
const t = r.querySelector("p");
|
|
26
|
-
t && (
|
|
27
|
+
t && (f(t).textContent = `{{${i}${e}_${o}_name}}`);
|
|
27
28
|
break;
|
|
28
29
|
}
|
|
29
30
|
case "productPrice": {
|
|
30
31
|
const t = r.querySelector("p");
|
|
31
|
-
t && (
|
|
32
|
+
t && (f(t).textContent = h(
|
|
32
33
|
e,
|
|
33
34
|
o,
|
|
34
35
|
"price",
|
|
35
|
-
|
|
36
|
-
|
|
36
|
+
c,
|
|
37
|
+
i
|
|
37
38
|
));
|
|
38
39
|
break;
|
|
39
40
|
}
|
|
40
41
|
case "productOldPrice": {
|
|
41
42
|
const t = r.querySelector("p");
|
|
42
|
-
t && (
|
|
43
|
+
t && (f(t).textContent = h(
|
|
43
44
|
e,
|
|
44
45
|
o,
|
|
45
46
|
"original_price",
|
|
46
|
-
|
|
47
|
-
|
|
47
|
+
c,
|
|
48
|
+
i
|
|
48
49
|
), t.setAttribute("product-attr", "discount"));
|
|
49
50
|
break;
|
|
50
51
|
}
|
|
51
52
|
case "productButton": {
|
|
52
53
|
const t = r.querySelector("a");
|
|
53
|
-
t && t.setAttribute("href", `{{${
|
|
54
|
+
t && t.setAttribute("href", `{{${i}${e}_${o}_url}}`);
|
|
54
55
|
break;
|
|
55
56
|
}
|
|
56
57
|
case "productOmnibusPrice": {
|
|
57
58
|
const t = r.querySelector(".omnibus-price-value");
|
|
58
59
|
if (t) {
|
|
59
|
-
t.textContent = `{{${
|
|
60
|
+
t.textContent = `{{${i}${e}_${o}_omnibus_price}}`;
|
|
60
61
|
const s = t.closest("p");
|
|
61
62
|
s && (s.setAttribute("product-attr", "omnibus_price"), s.setAttribute("composition", "true"));
|
|
62
63
|
}
|
|
@@ -65,7 +66,7 @@ function A(r, n, e, o, i, c) {
|
|
|
65
66
|
case "productOmnibusDiscount": {
|
|
66
67
|
const t = r.querySelector(".omnibus-discount-value");
|
|
67
68
|
if (t) {
|
|
68
|
-
t.textContent = `{{${
|
|
69
|
+
t.textContent = `{{${i}${e}_${o}_omnibus_discount}}`;
|
|
69
70
|
const s = t.closest("p");
|
|
70
71
|
s && (s.setAttribute("product-attr", "omnibus_discount"), s.setAttribute("composition", "true"));
|
|
71
72
|
}
|
|
@@ -75,15 +76,15 @@ function A(r, n, e, o, i, c) {
|
|
|
75
76
|
const t = r.getAttribute("product-attr") ? r : r.querySelector("[product-attr]");
|
|
76
77
|
if (t) {
|
|
77
78
|
const s = t.getAttribute("product-attr"), a = t.querySelector("p");
|
|
78
|
-
a && (
|
|
79
|
+
a && (f(a).textContent = `{{${i}${e}_${o}_${s}}}`);
|
|
79
80
|
}
|
|
80
81
|
break;
|
|
81
82
|
}
|
|
82
83
|
}
|
|
83
84
|
}
|
|
84
|
-
function
|
|
85
|
-
r.querySelectorAll(".recommendation-product-row").forEach((
|
|
86
|
-
|
|
85
|
+
function E(r, n, e, o) {
|
|
86
|
+
r.querySelectorAll(".recommendation-product-row").forEach((i, t) => {
|
|
87
|
+
i.querySelectorAll("[data-attribute-type]").forEach((a) => {
|
|
87
88
|
const u = a.getAttribute("data-attribute-type") || "", p = a.querySelectorAll(".attribute-cell");
|
|
88
89
|
p.length > 0 ? p.forEach((l) => {
|
|
89
90
|
A(l, u, n, t, e, o);
|
|
@@ -91,35 +92,35 @@ function w(r, n, e, o) {
|
|
|
91
92
|
});
|
|
92
93
|
});
|
|
93
94
|
}
|
|
94
|
-
function
|
|
95
|
-
const
|
|
96
|
-
if (!
|
|
95
|
+
function R(r, n, e, o) {
|
|
96
|
+
const c = r.querySelectorAll(".recommendation-product-row");
|
|
97
|
+
if (!c.length)
|
|
97
98
|
return;
|
|
98
|
-
const [
|
|
99
|
-
|
|
99
|
+
const [i] = c, t = i.querySelector("[data-attribute-type]"), s = t ? t.querySelectorAll(".attribute-cell").length : 1;
|
|
100
|
+
c.forEach((a, u) => {
|
|
100
101
|
a.querySelectorAll("[data-attribute-type]").forEach((l) => {
|
|
101
|
-
const
|
|
102
|
+
const m = l.getAttribute("data-attribute-type") || "";
|
|
102
103
|
l.querySelectorAll(".attribute-cell").forEach((y, $) => {
|
|
103
104
|
const S = u * s + $;
|
|
104
|
-
A(y,
|
|
105
|
+
A(y, m, n, S, e, o);
|
|
105
106
|
});
|
|
106
107
|
});
|
|
107
108
|
});
|
|
108
109
|
}
|
|
109
|
-
function
|
|
110
|
-
r.querySelectorAll(".ins-recommendation-product-container").forEach((
|
|
111
|
-
|
|
110
|
+
function P(r, n, e, o) {
|
|
111
|
+
r.querySelectorAll(".ins-recommendation-product-container").forEach((i) => {
|
|
112
|
+
R(i, n, e, o);
|
|
112
113
|
});
|
|
113
114
|
}
|
|
114
|
-
function
|
|
115
|
-
const o = r.getAttribute("data-layout") || "grid",
|
|
116
|
-
o === "list" ?
|
|
115
|
+
function T(r, n, e) {
|
|
116
|
+
const o = r.getAttribute("data-layout") || "grid", c = r.getAttribute("currency-alignment") || "after";
|
|
117
|
+
o === "list" ? E(r, n, c, e) : P(r, n, c, e);
|
|
117
118
|
}
|
|
118
|
-
function
|
|
119
|
-
const o = new RegExp(`${n}\\s*:\\s*(\\d+)\\s*px`, "i"),
|
|
120
|
-
return
|
|
119
|
+
function b(r, n, e) {
|
|
120
|
+
const o = new RegExp(`${n}\\s*:\\s*(\\d+)\\s*px`, "i"), c = r.match(o);
|
|
121
|
+
return c ? parseInt(c[1]) : e;
|
|
121
122
|
}
|
|
122
|
-
function
|
|
123
|
+
function v(r, n) {
|
|
123
124
|
let e = r.parentElement;
|
|
124
125
|
for (; e && e !== n; ) {
|
|
125
126
|
if (e.tagName === "TD") {
|
|
@@ -131,42 +132,42 @@ function T(r, n) {
|
|
|
131
132
|
}
|
|
132
133
|
return null;
|
|
133
134
|
}
|
|
134
|
-
function
|
|
135
|
-
const n = r.getAttribute("style") || "", e =
|
|
136
|
-
|
|
137
|
-
if (
|
|
135
|
+
function O(r) {
|
|
136
|
+
const n = r.getAttribute("style") || "", e = b(n, "width", 600), o = b(n, "padding", 0) * 2, c = Math.max(0, e - o);
|
|
137
|
+
c !== 0 && r.querySelectorAll("img.adapt-img").forEach((i) => {
|
|
138
|
+
if (i.hasAttribute("width"))
|
|
138
139
|
return;
|
|
139
|
-
const t =
|
|
140
|
+
const t = v(i, r);
|
|
140
141
|
if (!t)
|
|
141
142
|
return;
|
|
142
|
-
const s = t.getAttribute("width"), a = parseFloat(s), u =
|
|
143
|
-
|
|
144
|
-
const
|
|
145
|
-
if (!/\bwidth\s*:\s*\d/i.test(
|
|
146
|
-
const
|
|
147
|
-
|
|
143
|
+
const s = t.getAttribute("width"), a = parseFloat(s), u = b(t.getAttribute("style") || "", "padding", 0) * 2, p = Math.floor(c * a / 100), l = Math.max(1, p - u);
|
|
144
|
+
i.setAttribute("width", String(l));
|
|
145
|
+
const m = i.getAttribute("style") || "";
|
|
146
|
+
if (!/\bwidth\s*:\s*\d/i.test(m)) {
|
|
147
|
+
const d = m && !m.trim().endsWith(";") ? "; " : "";
|
|
148
|
+
i.setAttribute("style", `${m}${d}width: ${l}px`);
|
|
148
149
|
}
|
|
149
150
|
});
|
|
150
151
|
}
|
|
151
|
-
function
|
|
152
|
+
function W(r, n) {
|
|
152
153
|
const e = r.match(/<!DOCTYPE[^>]*>/i);
|
|
153
154
|
return (e ? `${e[0]}
|
|
154
155
|
` : "") + n.documentElement.outerHTML;
|
|
155
156
|
}
|
|
156
|
-
function
|
|
157
|
+
function F(r) {
|
|
157
158
|
const n = r.replaceAll("{%", "<!--{%").replaceAll("%}", "%}-->"), e = new DOMParser().parseFromString(n, "text/html"), o = e.querySelectorAll(".recommendation-block-v2");
|
|
158
159
|
if (!o.length)
|
|
159
160
|
return r;
|
|
160
|
-
const { buildCampaignUrl:
|
|
161
|
-
|
|
161
|
+
const { buildCampaignUrl: c } = g(), i = C();
|
|
162
|
+
i.recommendationCampaignUrls = {};
|
|
162
163
|
const { isFeatureEnabled: t } = _(), s = t("liquidSyntax") ? "reco_" : "";
|
|
163
164
|
return o.forEach((u) => {
|
|
164
|
-
var l,
|
|
165
|
+
var l, m;
|
|
165
166
|
const p = u.getAttribute("recommendation-id");
|
|
166
|
-
p && ((l = u.parentNode) == null || l.insertBefore(e.createComment("REC_START"), u), (
|
|
167
|
-
}),
|
|
167
|
+
p && ((l = u.parentNode) == null || l.insertBefore(e.createComment("REC_START"), u), (m = u.parentNode) == null || m.insertBefore(e.createComment("REC_END"), u.nextSibling), u.querySelectorAll('[data-visibility="0"]').forEach((d) => d.remove()), c(p), w(u) || T(u, p, s), O(u));
|
|
168
|
+
}), W(n, e).replaceAll("<!--{%", "{%").replaceAll("%}-->", "%}").replaceAll("<!--{%", "{%").replaceAll("%}-->", "%}");
|
|
168
169
|
}
|
|
169
170
|
export {
|
|
170
171
|
h as formatPriceVariable,
|
|
171
|
-
|
|
172
|
+
F as prepareRecommendationBlocks
|
|
172
173
|
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { CSS_CLASS_SKIP_COMPILE as n, BLOCK_ROOT_SELECTOR as i } from "../../../extensions/Blocks/Recommendation/constants/selectors.js";
|
|
2
|
+
function m(o) {
|
|
3
|
+
return o.classList.contains(n);
|
|
4
|
+
}
|
|
5
|
+
function a(o) {
|
|
6
|
+
const r = new DOMParser().parseFromString(o, "text/html").querySelectorAll(`${i}.${n}`), t = /* @__PURE__ */ new Set();
|
|
7
|
+
return r.forEach((c) => {
|
|
8
|
+
const e = c.getAttribute("recommendation-id");
|
|
9
|
+
e && t.add(e);
|
|
10
|
+
}), t;
|
|
11
|
+
}
|
|
12
|
+
export {
|
|
13
|
+
a as getIgnoredRecommendationBlockIds,
|
|
14
|
+
m as isIgnoredRecommendationBlock
|
|
15
|
+
};
|
|
@@ -1,27 +1,49 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
import { CURRENCY_ATTR as n, CSS_CLASS_SKIP_COMPILE as c } from "../../../extensions/Blocks/Recommendation/constants/selectors.js";
|
|
2
|
+
const a = "You May Also Like!";
|
|
3
|
+
function l(t) {
|
|
4
|
+
var o;
|
|
5
|
+
const r = t.querySelector(".ext-recommendation-title");
|
|
6
|
+
if (!r)
|
|
7
|
+
return a;
|
|
8
|
+
const e = (o = r.textContent) == null ? void 0 : o.trim();
|
|
9
|
+
return e && e.length > 0 ? e : a;
|
|
9
10
|
}
|
|
10
|
-
function
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
...Array.from(
|
|
11
|
+
function m(t) {
|
|
12
|
+
const r = [
|
|
13
|
+
t,
|
|
14
|
+
...Array.from(t.querySelectorAll(".product-card, .ext-recommendation-card"))
|
|
14
15
|
];
|
|
15
|
-
let
|
|
16
|
-
return
|
|
17
|
-
const
|
|
18
|
-
if (
|
|
19
|
-
return
|
|
20
|
-
const
|
|
21
|
-
return
|
|
22
|
-
}),
|
|
16
|
+
let e = "";
|
|
17
|
+
return r.some((o) => {
|
|
18
|
+
const i = o.getAttribute("bgcolor");
|
|
19
|
+
if (i && i.trim())
|
|
20
|
+
return e = i.trim(), !0;
|
|
21
|
+
const u = (o.getAttribute("style") ?? "").match(/background-color\s*:\s*([^;]+)/i);
|
|
22
|
+
return u && u[1] ? (e = u[1].trim(), !0) : !1;
|
|
23
|
+
}), e;
|
|
24
|
+
}
|
|
25
|
+
function C(t) {
|
|
26
|
+
const r = t.getAttribute(n.CURRENCY);
|
|
27
|
+
if (!r)
|
|
28
|
+
return;
|
|
29
|
+
const e = t.getAttribute(n.SYMBOL);
|
|
30
|
+
return {
|
|
31
|
+
value: r,
|
|
32
|
+
// An empty `currency-symbol` is omitted so `mapCurrency` falls back to
|
|
33
|
+
// the currency code as the symbol.
|
|
34
|
+
...e ? { symbol: e } : {},
|
|
35
|
+
alignment: t.getAttribute(n.ALIGNMENT) ?? "",
|
|
36
|
+
decimalCount: t.getAttribute(n.DECIMAL_COUNT) ?? "",
|
|
37
|
+
decimalSeparator: t.getAttribute(n.DECIMAL_SEPARATOR) ?? "",
|
|
38
|
+
thousandSeparator: t.getAttribute(n.THOUSAND_SEPARATOR) ?? ""
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
function d(t) {
|
|
42
|
+
return t.classList.contains(c);
|
|
23
43
|
}
|
|
24
44
|
export {
|
|
25
|
-
|
|
26
|
-
|
|
45
|
+
m as extractCardBgColor,
|
|
46
|
+
C as extractCurrencyFromBlock,
|
|
47
|
+
l as extractTitleText,
|
|
48
|
+
d as isPartnerManagedBlock
|
|
27
49
|
};
|