@useinsider/guido 3.20.0-beta.11a0bde → 3.20.0-beta.30c96fc
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 +14 -5
- package/dist/config/compiler/utils/itemsCompilerUtils.js +48 -21
- package/dist/config/migrator/itemsBlockMigrator.js +112 -108
- package/dist/extensions/Blocks/Items/block.js +78 -67
- package/dist/extensions/Blocks/Items/constants/cardWidth.js +20 -0
- package/dist/extensions/Blocks/Items/layouts/vertical.html.js +1 -1
- package/dist/extensions/Blocks/Recommendation/utils/legacyStrategyMigration.js +9 -9
- package/dist/extensions/Blocks/Recommendation/utils/productIds.js +3 -5
- package/dist/src/config/compiler/utils/itemsCompilerUtils.d.ts +5 -0
- package/dist/src/extensions/Blocks/Items/block.d.ts +5 -0
- package/dist/src/extensions/Blocks/Items/constants/cardWidth.d.ts +12 -0
- package/dist/src/extensions/Blocks/Recommendation/utils/productIds.d.ts +0 -2
- package/dist/src/utils/liquidProtection.d.ts +3 -0
- package/dist/utils/liquidProtection.js +5 -0
- package/package.json +1 -1
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
import { pairProductVariables as o } from "../../utils/pairProductVariables.js";
|
|
2
|
-
import {
|
|
3
|
-
const
|
|
2
|
+
import { normalizeItemsBlockWidths as r, wrapHiddenPriceTdsForOutlook as e, MSO_ITEMS_HIDE_START as t, MSO_ITEMS_HIDE_END as s } from "./utils/itemsCompilerUtils.js";
|
|
3
|
+
const d = [
|
|
4
|
+
{
|
|
5
|
+
id: "normalize-items-block-widths",
|
|
6
|
+
// Runs before the other items rules so they see non-zero widths; not AMP-safe.
|
|
7
|
+
description: "Normalize zero Items card widths in the compiled email",
|
|
8
|
+
type: "custom",
|
|
9
|
+
processor: r,
|
|
10
|
+
priority: 55
|
|
11
|
+
// Before pair-product-variables (60)
|
|
12
|
+
},
|
|
4
13
|
{
|
|
5
14
|
id: "pair-product-variables",
|
|
6
15
|
description: "Replace product default values with template variables",
|
|
@@ -16,7 +25,7 @@ const a = [
|
|
|
16
25
|
// with safe placeholder comments and collapse them inline for web-engine Outlook.
|
|
17
26
|
description: "Mark hidden Items price tds for Outlook conditional hiding",
|
|
18
27
|
type: "custom",
|
|
19
|
-
processor:
|
|
28
|
+
processor: e,
|
|
20
29
|
priority: 65
|
|
21
30
|
// After pair-product-variables (60), before outlook rules (70+)
|
|
22
31
|
},
|
|
@@ -26,10 +35,10 @@ const a = [
|
|
|
26
35
|
// and reco swap P100) keeps it out of every whitespace/comment-mangling pass.
|
|
27
36
|
description: "Swap Items MSO markers into [if !mso] conditional comments",
|
|
28
37
|
type: "custom",
|
|
29
|
-
processor: (i) => i.replaceAll(`<!--${
|
|
38
|
+
processor: (i) => i.replaceAll(`<!--${t}-->`, "<!--[if !mso]><!-- -->").replaceAll(`<!--${s}-->`, "<!--<![endif]-->"),
|
|
30
39
|
priority: 101
|
|
31
40
|
}
|
|
32
41
|
];
|
|
33
42
|
export {
|
|
34
|
-
|
|
43
|
+
d as itemsCompilerRules
|
|
35
44
|
};
|
|
@@ -1,28 +1,55 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
1
|
+
import { PRODUCT_WRAPPER_SELECTOR as A, hasZeroWidthDeclaration as E, isZeroWidthValue as u, withWidthPin as h, PRODUCT_TD_SELECTOR as S, withoutZeroWidth as _ } from "../../../extensions/Blocks/Items/constants/cardWidth.js";
|
|
2
|
+
import { protectLiquid as m, restoreLiquid as y } from "../../../utils/liquidProtection.js";
|
|
3
|
+
const f = "MSO_ITEMS_HIDE_START", D = "MSO_ITEMS_HIDE_END", T = "mso-hide:all; max-height:0; overflow:hidden; font-size:0; line-height:0;", M = ".ins-product-cart td.horizontal-price, .ins-product-cart td.vertical-price";
|
|
4
|
+
function g(e) {
|
|
5
|
+
if (!e.includes("vertical-price") || !e.includes("ins-product-cart"))
|
|
6
|
+
return e;
|
|
7
|
+
const n = e.replaceAll("{%", "<!--{%").replaceAll("%}", "%}-->"), r = new DOMParser().parseFromString(n, "text/html");
|
|
8
|
+
let s = !1;
|
|
9
|
+
if (r.querySelectorAll(M).forEach((t) => {
|
|
10
|
+
var d, a;
|
|
11
|
+
const o = t.getAttribute("style") || "";
|
|
10
12
|
if (!/display\s*:\s*none/i.test(o))
|
|
11
13
|
return;
|
|
12
|
-
const
|
|
13
|
-
if (((
|
|
14
|
-
const
|
|
15
|
-
|
|
14
|
+
const l = t.previousSibling;
|
|
15
|
+
if (((l == null ? void 0 : l.nodeType) !== Node.COMMENT_NODE || l.data !== f) && ((d = t.parentNode) == null || d.insertBefore(r.createComment(f), t), (a = t.parentNode) == null || a.insertBefore(r.createComment(D), t.nextSibling)), !/mso-hide/i.test(o)) {
|
|
16
|
+
const p = o.trim().endsWith(";") ? " " : "; ";
|
|
17
|
+
t.setAttribute("style", `${o}${p}${T}`);
|
|
16
18
|
}
|
|
17
|
-
|
|
18
|
-
}), !
|
|
19
|
-
return
|
|
20
|
-
const
|
|
21
|
-
return ((
|
|
19
|
+
s = !0;
|
|
20
|
+
}), !s)
|
|
21
|
+
return e;
|
|
22
|
+
const c = n.match(/<!DOCTYPE[^>]*>/i);
|
|
23
|
+
return ((c ? `${c[0]}
|
|
22
24
|
` : "") + r.documentElement.outerHTML).replaceAll("<!--{%", "{%").replaceAll("%}-->", "%}").replaceAll("<!--{%", "{%").replaceAll("%}-->", "%}");
|
|
23
25
|
}
|
|
26
|
+
function I(e) {
|
|
27
|
+
if (!e.includes("ins-product-wrapper") && !e.includes("ins-product-td"))
|
|
28
|
+
return e;
|
|
29
|
+
const n = new DOMParser().parseFromString(m(e), "text/html");
|
|
30
|
+
let r = !1;
|
|
31
|
+
if (n.querySelectorAll(A).forEach((i) => {
|
|
32
|
+
const t = i.getAttribute("style") || "";
|
|
33
|
+
if (!E(t) && !u(i.getAttribute("width")))
|
|
34
|
+
return;
|
|
35
|
+
const o = h(t);
|
|
36
|
+
o !== t && (i.setAttribute("style", o), r = !0), u(i.getAttribute("width")) && (i.setAttribute("width", "100%"), r = !0);
|
|
37
|
+
}), n.querySelectorAll(S).forEach((i) => {
|
|
38
|
+
const t = i.getAttribute("style") || "";
|
|
39
|
+
if (E(t)) {
|
|
40
|
+
const o = _(t);
|
|
41
|
+
o ? i.setAttribute("style", o) : i.removeAttribute("style"), r = !0;
|
|
42
|
+
}
|
|
43
|
+
u(i.getAttribute("width")) && (i.removeAttribute("width"), r = !0);
|
|
44
|
+
}), !r)
|
|
45
|
+
return e;
|
|
46
|
+
const s = e.match(/<!DOCTYPE[^>]*>/i), c = s ? `${s[0]}
|
|
47
|
+
` : "";
|
|
48
|
+
return y(c + n.documentElement.outerHTML);
|
|
49
|
+
}
|
|
24
50
|
export {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
51
|
+
D as MSO_ITEMS_HIDE_END,
|
|
52
|
+
f as MSO_ITEMS_HIDE_START,
|
|
53
|
+
I as normalizeItemsBlockWidths,
|
|
54
|
+
g as wrapHiddenPriceTdsForOutlook
|
|
28
55
|
};
|
|
@@ -1,84 +1,86 @@
|
|
|
1
|
-
var
|
|
2
|
-
var v = (
|
|
3
|
-
var M = (
|
|
1
|
+
var B = Object.defineProperty;
|
|
2
|
+
var v = (n, t, e) => t in n ? B(n, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : n[t] = e;
|
|
3
|
+
var M = (n, t, e) => v(n, typeof t != "symbol" ? t + "" : t, e);
|
|
4
4
|
import { BLOCK_ID as R } from "../../extensions/Blocks/Items/block.js";
|
|
5
|
+
import { hasZeroWidthDeclaration as L, withoutZeroWidth as x } from "../../extensions/Blocks/Items/constants/cardWidth.js";
|
|
5
6
|
import { ItemInCartOptions as h, DefaultConfigValues as b, SETTINGS_ENUMS as _ } from "../../extensions/Blocks/Items/enums/settingsEnums.js";
|
|
6
|
-
import { getDefaultTemplate as
|
|
7
|
-
import { useTemplateStore as
|
|
8
|
-
|
|
7
|
+
import { getDefaultTemplate as V } from "../../extensions/Blocks/Items/template.js";
|
|
8
|
+
import { useTemplateStore as O } from "../../stores/template.js";
|
|
9
|
+
import { protectLiquid as H, restoreLiquid as $ } from "../../utils/liquidProtection.js";
|
|
10
|
+
function F() {
|
|
9
11
|
return String(Date.now() + Math.floor(Math.random() * 1e3));
|
|
10
12
|
}
|
|
11
|
-
function
|
|
12
|
-
return
|
|
13
|
+
function D(n) {
|
|
14
|
+
return n ? {
|
|
13
15
|
CartItems: _.ITEMS_TYPE.CART_ITEMS,
|
|
14
16
|
BrowsedItems: _.ITEMS_TYPE.BROWSED_ITEMS,
|
|
15
17
|
PurchasedItems: _.ITEMS_TYPE.PURCHASED_ITEMS,
|
|
16
18
|
CART_ITEMS: _.ITEMS_TYPE.CART_ITEMS,
|
|
17
19
|
BROWSED_ITEMS: _.ITEMS_TYPE.BROWSED_ITEMS,
|
|
18
20
|
PURCHASED_ITEMS: _.ITEMS_TYPE.PURCHASED_ITEMS
|
|
19
|
-
}[
|
|
21
|
+
}[n] || _.ITEMS_TYPE.CART_ITEMS : _.ITEMS_TYPE.CART_ITEMS;
|
|
20
22
|
}
|
|
21
|
-
function
|
|
22
|
-
return
|
|
23
|
+
function U(n) {
|
|
24
|
+
return n.classList.contains("esd-browsed-items-block") ? _.ITEMS_TYPE.BROWSED_ITEMS : n.classList.contains("esd-purchased-items-block") ? _.ITEMS_TYPE.PURCHASED_ITEMS : _.ITEMS_TYPE.CART_ITEMS;
|
|
23
25
|
}
|
|
24
|
-
function
|
|
26
|
+
function P(n) {
|
|
25
27
|
var o;
|
|
26
|
-
const t = (i,
|
|
27
|
-
let
|
|
28
|
-
if (
|
|
29
|
-
const i = parseInt(
|
|
30
|
-
|
|
28
|
+
const t = (i, d) => i == null ? d : i === "1" || i === "true", e = (i, d) => i || d, a = n["data-type"] || n["data-source"], r = D(a), u = h[r];
|
|
29
|
+
let c = n["data-cart_items_select_control_value"] || ((o = u == null ? void 0 : u[0]) == null ? void 0 : o.value) || b.cartItemsSelectControlValue;
|
|
30
|
+
if (c && !c.includes("{{") && /^\d+$/.test(c)) {
|
|
31
|
+
const i = parseInt(c) - 1, d = h[r];
|
|
32
|
+
d && d[i] && (c = d[i].value);
|
|
31
33
|
}
|
|
32
34
|
return {
|
|
33
35
|
initialized: !0,
|
|
34
|
-
blockInstanceId: e(
|
|
36
|
+
blockInstanceId: e(n["data-block-instance-id"], F()),
|
|
35
37
|
source: r,
|
|
36
38
|
type: r,
|
|
37
|
-
itemsSelectValue:
|
|
38
|
-
orientation:
|
|
39
|
-
nameTrimming: t(
|
|
40
|
-
priceHideDiscount: t(
|
|
41
|
-
priceFormatted: t(
|
|
42
|
-
priceSinglePrice: t(
|
|
39
|
+
itemsSelectValue: c,
|
|
40
|
+
orientation: n["data-card_orientation_control_value"] || _.ORIENTATION.VERTICAL,
|
|
41
|
+
nameTrimming: t(n["data-product_name_control_trim"], !0),
|
|
42
|
+
priceHideDiscount: t(n["data-product_price_control_nodup"], !0),
|
|
43
|
+
priceFormatted: t(n["data-product_price_control_formated"], !0),
|
|
44
|
+
priceSinglePrice: t(n["data-product_price_control_single_price"], !1),
|
|
43
45
|
priceCurrencySymbol: e(
|
|
44
|
-
|
|
46
|
+
n["data-product_price_control_currency_symbol"],
|
|
45
47
|
b.productPriceCurrencySymbolControlValue
|
|
46
48
|
),
|
|
47
49
|
priceCurrencyLocation: e(
|
|
48
|
-
|
|
50
|
+
n["data-product_price_currency_location"],
|
|
49
51
|
b.productPriceCurrencyLocationControlValue
|
|
50
52
|
),
|
|
51
|
-
priceOrientation:
|
|
52
|
-
quantityControlEnabled: t(
|
|
53
|
-
buttonLink: e(
|
|
54
|
-
imageLink: e(
|
|
55
|
-
buttonLabel: e(
|
|
56
|
-
buttonFullWidth: t(
|
|
57
|
-
imageVisible: t(
|
|
58
|
-
nameVisible: t(
|
|
59
|
-
quantityVisible: t(
|
|
60
|
-
priceVisible: t(
|
|
61
|
-
originalPriceVisible: t(
|
|
62
|
-
buttonVisible: t(
|
|
53
|
+
priceOrientation: n["data-product_original_price_control_orientation"] || "horizontal",
|
|
54
|
+
quantityControlEnabled: t(n["data-product_quantity_control_enabled"], !0),
|
|
55
|
+
buttonLink: e(n["data-product_button_link"], b.productButtonLinkControlValue),
|
|
56
|
+
imageLink: e(n["data-product_image_link"], b.productImageLinkControlValue),
|
|
57
|
+
buttonLabel: e(n["data-product_button_control_label"], "Buy"),
|
|
58
|
+
buttonFullWidth: t(n["data-product_button_control_atw"], !0),
|
|
59
|
+
imageVisible: t(n["data-product_image_control_enabled"], !0),
|
|
60
|
+
nameVisible: t(n["data-product_name_control_enabled"], !0),
|
|
61
|
+
quantityVisible: t(n["data-product_quantity_control_enabled"], !0),
|
|
62
|
+
priceVisible: t(n["data-product_price_control_enabled"], !0),
|
|
63
|
+
originalPriceVisible: t(n["data-product_original_price_control_enabled"], !0),
|
|
64
|
+
buttonVisible: t(n["data-product_button_control_enabled"], !0)
|
|
63
65
|
};
|
|
64
66
|
}
|
|
65
|
-
function
|
|
67
|
+
function Y(n, t) {
|
|
66
68
|
const e = {
|
|
67
69
|
CART_ITEMS: `{{Abandoned Cart Item (${t}) Image}}`,
|
|
68
70
|
BROWSED_ITEMS: `{{Browsed Item (${t}) Image}}`,
|
|
69
71
|
PURCHASED_ITEMS: `{{Purchased Item (${t}) Image}}`
|
|
70
72
|
};
|
|
71
|
-
return e[
|
|
73
|
+
return e[n] || e.CART_ITEMS;
|
|
72
74
|
}
|
|
73
|
-
function
|
|
75
|
+
function W(n, t) {
|
|
74
76
|
const e = {
|
|
75
77
|
CART_ITEMS: `{{Abandoned Cart Item (${t}) Url}}`,
|
|
76
78
|
BROWSED_ITEMS: `{{Browsed Item (${t}) Url}}`,
|
|
77
79
|
PURCHASED_ITEMS: `{{Purchased Item (${t}) Url}}`
|
|
78
80
|
};
|
|
79
|
-
return e[
|
|
81
|
+
return e[n] || e.CART_ITEMS;
|
|
80
82
|
}
|
|
81
|
-
class
|
|
83
|
+
class z {
|
|
82
84
|
constructor() {
|
|
83
85
|
M(this, "parser");
|
|
84
86
|
this.parser = new DOMParser();
|
|
@@ -90,10 +92,10 @@ class F {
|
|
|
90
92
|
const e = this.removeJinjaConditionals(t), a = this.parser.parseFromString(e, "text/html"), r = a.querySelectorAll(
|
|
91
93
|
"td.esd-cart-items-block, td.esd-browsed-items-block, td.esd-purchased-items-block"
|
|
92
94
|
);
|
|
93
|
-
return
|
|
94
|
-
|
|
95
|
-
}), r.length === 0 ? (console.warn("ItemsBlockMigrator: No blocks found with items block selectors"), e) : (r.forEach((
|
|
96
|
-
const o = this.extractConfiguration(
|
|
95
|
+
return O().$patch((c) => {
|
|
96
|
+
c.migrations = { ...c.migrations, [R]: r.length };
|
|
97
|
+
}), r.length === 0 ? (console.warn("ItemsBlockMigrator: No blocks found with items block selectors"), this.backfillV2ProductTdAttributes(e)) : (r.forEach((c) => {
|
|
98
|
+
const o = this.extractConfiguration(c), i = V({
|
|
97
99
|
orientation: o.orientation,
|
|
98
100
|
itemsType: o.itemsType,
|
|
99
101
|
itemId: o.itemId,
|
|
@@ -107,18 +109,18 @@ class F {
|
|
|
107
109
|
priceStyles: o.priceStyles,
|
|
108
110
|
originalPriceStyles: o.originalPriceStyles,
|
|
109
111
|
quantityStyles: o.quantityStyles,
|
|
110
|
-
nodeConfig:
|
|
112
|
+
nodeConfig: P(o.configBlockAttributes)
|
|
111
113
|
}), l = this.parser.parseFromString(
|
|
112
114
|
`<table><tbody><tr>${i}</tr></tbody></table>`,
|
|
113
115
|
"text/html"
|
|
114
116
|
).querySelector("td");
|
|
115
|
-
if (l &&
|
|
116
|
-
const s =
|
|
117
|
+
if (l && c.parentNode) {
|
|
118
|
+
const s = P(o.configBlockAttributes);
|
|
117
119
|
l.setAttribute("esd-ext-config", JSON.stringify(s)), l.setAttribute("data-type", s.type);
|
|
118
120
|
const p = l.querySelector("esd-config-block");
|
|
119
|
-
p && p.remove(),
|
|
121
|
+
p && p.remove(), c.parentNode.replaceChild(l, c);
|
|
120
122
|
}
|
|
121
|
-
}), a.documentElement.outerHTML);
|
|
123
|
+
}), this.backfillV2ProductTdAttributes(a.documentElement.outerHTML));
|
|
122
124
|
} catch (e) {
|
|
123
125
|
return console.error("ItemsBlockMigrator failed:", e), t;
|
|
124
126
|
}
|
|
@@ -131,24 +133,24 @@ class F {
|
|
|
131
133
|
*/
|
|
132
134
|
extractConfiguration(t) {
|
|
133
135
|
var C;
|
|
134
|
-
const e =
|
|
135
|
-
this.readSelfOrDescendantAttribute(t, "data-type") ||
|
|
136
|
-
), a = this.readSelfOrDescendantAttribute(t, "data-number") || "1", r = parseInt(a) - 1,
|
|
136
|
+
const e = D(
|
|
137
|
+
this.readSelfOrDescendantAttribute(t, "data-type") || U(t)
|
|
138
|
+
), a = this.readSelfOrDescendantAttribute(t, "data-number") || "1", r = parseInt(a) - 1, u = h[e], c = ((C = u == null ? void 0 : u[r]) == null ? void 0 : C.value) || u[0].value, o = this.extractConfigBlockAttributes(t, e, a);
|
|
137
139
|
this.applyDomFallbacks(t, o);
|
|
138
|
-
const i = t.querySelector('[product-attr="price"]'),
|
|
140
|
+
const i = t.querySelector('[product-attr="price"]'), d = o["data-product_price_control_currency_symbol"], l = o["data-product_price_currency_location"] || "0", s = o["data-product_price_control_formated"], p = s !== "false" && s !== "0", S = o["data-card_orientation_control_value"] === "horizontal" ? "horizontal" : "vertical", f = t.querySelector('a[product-attr="name"]'), y = (f == null ? void 0 : f.getAttribute("style")) || void 0, g = t.querySelector('a[product-attr="button"]') ?? t.querySelector('[product-attr="button"]'), I = (g == null ? void 0 : g.getAttribute("style")) || void 0, k = (i == null ? void 0 : i.getAttribute("style")) || void 0, m = t.querySelector("p.original-price") ?? t.querySelector('[product-attr="originalPrice"]'), A = m != null && m.getAttribute("style") ? m : (m == null ? void 0 : m.closest("p")) ?? m, q = (A == null ? void 0 : A.getAttribute("style")) || void 0, E = t.querySelector('[product-attr="quantity"]'), w = (E == null ? void 0 : E.getAttribute("style")) || void 0;
|
|
139
141
|
return {
|
|
140
142
|
orientation: S,
|
|
141
143
|
itemsType: e,
|
|
142
|
-
itemId:
|
|
143
|
-
currencySymbol:
|
|
144
|
+
itemId: c,
|
|
145
|
+
currencySymbol: d,
|
|
144
146
|
currencyLocation: l,
|
|
145
147
|
formattedPrice: p,
|
|
146
148
|
configBlockAttributes: o,
|
|
147
|
-
nameStyles:
|
|
149
|
+
nameStyles: y,
|
|
148
150
|
buttonStyles: I,
|
|
149
|
-
priceStyles:
|
|
150
|
-
originalPriceStyles:
|
|
151
|
-
quantityStyles:
|
|
151
|
+
priceStyles: k,
|
|
152
|
+
originalPriceStyles: q,
|
|
153
|
+
quantityStyles: w
|
|
152
154
|
};
|
|
153
155
|
}
|
|
154
156
|
/**
|
|
@@ -159,8 +161,8 @@ class F {
|
|
|
159
161
|
* card migrates with the boilerplate defaults: caption "Buy", USD, full-width button.
|
|
160
162
|
*/
|
|
161
163
|
applyDomFallbacks(t, e) {
|
|
162
|
-
var S,
|
|
163
|
-
const a = t.querySelector("esd-config-block"), r = (...
|
|
164
|
+
var S, f;
|
|
165
|
+
const a = t.querySelector("esd-config-block"), r = (...y) => !a || y.every((g) => !(a.getAttribute(g) ?? "").trim());
|
|
164
166
|
Object.entries({
|
|
165
167
|
image: '[product-attr="imageSrc"]',
|
|
166
168
|
name: '[product-attr="name"]',
|
|
@@ -168,17 +170,17 @@ class F {
|
|
|
168
170
|
original_price: '[product-attr="originalPrice"], p.original-price',
|
|
169
171
|
quantity: '[product-attr="quantity"]',
|
|
170
172
|
button: '[product-attr="button"]'
|
|
171
|
-
}).forEach(([
|
|
172
|
-
const I = `data-product_${
|
|
173
|
+
}).forEach(([y, g]) => {
|
|
174
|
+
const I = `data-product_${y}_control_enabled`;
|
|
173
175
|
r(I) && (e[I] = t.querySelector(g) ? "true" : "false");
|
|
174
176
|
}), r("data-card_orientation_control_value") && (e["data-card_orientation_control_value"] = t.querySelector('[colspan="2"]') ? "vertical" : "horizontal");
|
|
175
|
-
const
|
|
177
|
+
const c = t.querySelector('a[product-attr="button"]') ?? t.querySelector('[product-attr="button"]'), o = (S = c == null ? void 0 : c.textContent) == null ? void 0 : S.replace(/\s+/g, " ").trim();
|
|
176
178
|
o && r("data-product_button_control_label") && (e["data-product_button_control_label"] = o);
|
|
177
|
-
const i = (
|
|
179
|
+
const i = (c == null ? void 0 : c.getAttribute("style")) || "";
|
|
178
180
|
r("data-product_button_control_atw") && /display:\s*inline/.test(i) && !/(?:^|;)\s*width\s*:\s*100%/.test(i) && (e["data-product_button_control_atw"] = "false");
|
|
179
|
-
const
|
|
181
|
+
const d = t.querySelector('[product-attr="imageSrc"]'), l = d ? this.readImageSize(d) : null, s = (l == null ? void 0 : l.height) ?? (l == null ? void 0 : l.width), p = (l == null ? void 0 : l.width) ?? (l == null ? void 0 : l.height);
|
|
180
182
|
s && r("data-product_image_control_image-height") && (e["data-product_image_control_image-height"] = s), p && r("data-product_image_control_image-width") && (e["data-product_image_control_image-width"] = p), this.applyPriceDomFallbacks(t, e, r);
|
|
181
|
-
const T = ((
|
|
183
|
+
const T = ((f = t.querySelector('[product-attr="name"]')) == null ? void 0 : f.getAttribute("style")) || "";
|
|
182
184
|
r("data-product_name_control_trim") && /white-space:\s*normal/.test(T) && (e["data-product_name_control_trim"] = "0");
|
|
183
185
|
}
|
|
184
186
|
/**
|
|
@@ -189,15 +191,15 @@ class F {
|
|
|
189
191
|
* the default back over the real value.
|
|
190
192
|
*/
|
|
191
193
|
applyPriceDomFallbacks(t, e, a) {
|
|
192
|
-
var
|
|
194
|
+
var d;
|
|
193
195
|
const r = t.querySelector('[product-attr="price"]') ?? t.querySelector('[product-attr="originalPrice"]');
|
|
194
196
|
if (!r)
|
|
195
197
|
return;
|
|
196
|
-
const
|
|
197
|
-
|
|
198
|
-
const
|
|
199
|
-
if (
|
|
200
|
-
const l =
|
|
198
|
+
const u = (d = r.getAttribute("data-currency_symbol")) == null ? void 0 : d.trim();
|
|
199
|
+
u && a("data-product_price_control_currency_symbol") && (e["data-product_price_control_currency_symbol"] = u);
|
|
200
|
+
const c = r.getAttribute("data-curency");
|
|
201
|
+
if (c && a("data-product_price_currency_location", "data-product_price_control_curency")) {
|
|
202
|
+
const l = c === "after" ? "1" : "0";
|
|
201
203
|
e["data-product_price_currency_location"] = l, e["data-product_price_control_curency"] = l;
|
|
202
204
|
}
|
|
203
205
|
const o = r.getAttribute("data-formated");
|
|
@@ -232,14 +234,14 @@ class F {
|
|
|
232
234
|
* to nothing, so only a positive integer counts as an answer.
|
|
233
235
|
*/
|
|
234
236
|
readImageDimension(t, e) {
|
|
235
|
-
var
|
|
237
|
+
var d;
|
|
236
238
|
const a = (l) => {
|
|
237
239
|
const s = (l ?? "").trim().match(/^(\d+(?:\.\d+)?)(?:px)?$/i), p = s ? Math.floor(parseFloat(s[1])) : 0;
|
|
238
240
|
return p > 0 ? String(p) : null;
|
|
239
|
-
}, r = a((
|
|
241
|
+
}, r = a((d = t.getAttribute(e)) == null ? void 0 : d.trim());
|
|
240
242
|
if (r)
|
|
241
243
|
return r;
|
|
242
|
-
const
|
|
244
|
+
const u = t.getAttribute("style") || "", c = new RegExp(`(?:^|;)\\s*${e}:\\s*(\\d+(?:\\.\\d+)?)px`), o = new RegExp(`max-${e}:\\s*(\\d+(?:\\.\\d+)?)px`), i = u.match(c) || u.match(o);
|
|
243
245
|
return a(i == null ? void 0 : i[1]);
|
|
244
246
|
}
|
|
245
247
|
/**
|
|
@@ -250,26 +252,26 @@ class F {
|
|
|
250
252
|
* @param itemNumber - The item number (1-based index)
|
|
251
253
|
*/
|
|
252
254
|
extractConfigBlockAttributes(t, e, a) {
|
|
253
|
-
const r = t.querySelector("esd-config-block"),
|
|
255
|
+
const r = t.querySelector("esd-config-block"), u = {};
|
|
254
256
|
if (r) {
|
|
255
257
|
if (Array.from(r.attributes).forEach((o) => {
|
|
256
|
-
o.name.startsWith("data-") && (
|
|
257
|
-
}),
|
|
258
|
-
const o =
|
|
258
|
+
o.name.startsWith("data-") && (u[o.name] = o.value);
|
|
259
|
+
}), u["data-cart_items_select_control_value"]) {
|
|
260
|
+
const o = u["data-cart_items_select_control_value"];
|
|
259
261
|
if (/^\d+$/.test(o)) {
|
|
260
|
-
const i = parseInt(o) - 1,
|
|
261
|
-
|
|
262
|
+
const i = parseInt(o) - 1, d = h[e];
|
|
263
|
+
d && d[i] && (u["data-cart_items_select_control_value"] = d[i].value);
|
|
262
264
|
}
|
|
263
265
|
}
|
|
264
|
-
if (
|
|
265
|
-
const o =
|
|
266
|
+
if (u["data-product_price_control_curency"]) {
|
|
267
|
+
const o = u["data-product_price_control_curency"];
|
|
266
268
|
let i = o;
|
|
267
|
-
o === "before" ? i = "0" : o === "after" && (i = "1"),
|
|
269
|
+
o === "before" ? i = "0" : o === "after" && (i = "1"), u["data-product_price_control_curency"] = i, u["data-product_price_currency_location"] = i;
|
|
268
270
|
}
|
|
269
|
-
(!
|
|
271
|
+
(!u["data-product_price_control_currency_symbol"] || u["data-product_price_control_currency_symbol"].trim() === "") && (u["data-product_price_control_currency_symbol"] = "USD");
|
|
270
272
|
}
|
|
271
|
-
const
|
|
272
|
-
return
|
|
273
|
+
const c = { ...this.getDefaultConfigBlockAttributes(), ...u };
|
|
274
|
+
return c["data-type"] = e, c["data-source"] = e, c["data-product_image_link"] = Y(e, a), c["data-product_button_link"] = W(e, a), c;
|
|
273
275
|
}
|
|
274
276
|
/**
|
|
275
277
|
* Returns default esd-config-block attributes based on the old template structure
|
|
@@ -343,27 +345,29 @@ class F {
|
|
|
343
345
|
backfillV2ProductTdAttributes(t) {
|
|
344
346
|
if (!t.includes("ins-product-td") || !t.includes("esd-ext-config"))
|
|
345
347
|
return t;
|
|
346
|
-
const e = this.parser.parseFromString(t, "text/html");
|
|
348
|
+
const e = this.parser.parseFromString(H(t), "text/html");
|
|
347
349
|
let a = !1;
|
|
348
350
|
return e.querySelectorAll(".ins-product-td").forEach((r) => {
|
|
349
|
-
r.hasAttribute("width") && (r.removeAttribute("width"), a = !0), r.classList.contains("esd-container-frame") && (r.classList.remove("esd-container-frame"), a = !0)
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
351
|
+
r.hasAttribute("width") && (r.removeAttribute("width"), a = !0), r.classList.contains("esd-container-frame") && (r.classList.remove("esd-container-frame"), a = !0), r.querySelectorAll("table.ins-product-wrapper").forEach((d) => {
|
|
352
|
+
d.hasAttribute("width") && d.getAttribute("width") !== "100%" && (d.setAttribute("width", "100%"), a = !0);
|
|
353
|
+
const l = d.getAttribute("style");
|
|
354
|
+
l && L(l) && (d.setAttribute("style", x(l)), d.setAttribute("width", "100%"), a = !0);
|
|
355
|
+
});
|
|
356
|
+
const u = r.getAttribute("esd-ext-config");
|
|
357
|
+
let c = null;
|
|
354
358
|
try {
|
|
355
|
-
|
|
359
|
+
c = u ? JSON.parse(u) : null;
|
|
356
360
|
} catch {
|
|
357
361
|
}
|
|
358
|
-
if (!
|
|
362
|
+
if (!c || (!r.getAttribute("data-nodup") && typeof c.priceHideDiscount == "boolean" && (r.setAttribute("data-nodup", String(c.priceHideDiscount)), a = !0), r.getAttribute("data-type")))
|
|
359
363
|
return;
|
|
360
|
-
const
|
|
361
|
-
if (!
|
|
364
|
+
const o = c.type || c.source;
|
|
365
|
+
if (!o)
|
|
362
366
|
return;
|
|
363
|
-
r.setAttribute("data-type",
|
|
364
|
-
const
|
|
365
|
-
|
|
366
|
-
}), a ? e.documentElement.outerHTML : t;
|
|
367
|
+
r.setAttribute("data-type", o), a = !0;
|
|
368
|
+
const i = typeof c.itemsSelectValue == "string" ? c.itemsSelectValue.match(/\((\d+)\)/) : null;
|
|
369
|
+
i && r.getAttribute("data-number") !== i[1] && r.setAttribute("data-number", i[1]);
|
|
370
|
+
}), a ? $(e.documentElement.outerHTML) : t;
|
|
367
371
|
}
|
|
368
372
|
/**
|
|
369
373
|
* Fast check for the presence of any items block (cart / browsed / purchased)
|
|
@@ -397,9 +401,9 @@ class F {
|
|
|
397
401
|
`), r;
|
|
398
402
|
}
|
|
399
403
|
}
|
|
400
|
-
function
|
|
401
|
-
return new
|
|
404
|
+
function X(n) {
|
|
405
|
+
return new z().migrate(n);
|
|
402
406
|
}
|
|
403
407
|
export {
|
|
404
|
-
|
|
408
|
+
X as migrateItemsBlock
|
|
405
409
|
};
|
|
@@ -1,32 +1,33 @@
|
|
|
1
1
|
var k = Object.defineProperty;
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
import { BlockId as
|
|
2
|
+
var S = (d, l, e) => l in d ? k(d, l, { enumerable: !0, configurable: !0, writable: !0, value: e }) : d[l] = e;
|
|
3
|
+
var g = (d, l, e) => S(d, typeof l != "symbol" ? l + "" : l, e);
|
|
4
|
+
import { BlockId as D } from "../../../enums/block.js";
|
|
5
5
|
import { useOnboardingStore as T } from "../../../stores/onboarding.js";
|
|
6
|
-
import { getMigrationBannerHtml as
|
|
7
|
-
import { Block as
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
6
|
+
import { getMigrationBannerHtml as N } from "../../../utils/migrationBannerHtml.js";
|
|
7
|
+
import { Block as H, BlockCompositionType as R, ModificationDescription as u } from "../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
|
|
8
|
+
import { PRODUCT_WRAPPER_SELECTOR as M, isZeroWidthValue as m } from "./constants/cardWidth.js";
|
|
9
|
+
import { currencyAttrTargets as w, ITEMS_CURRENCY_ATTR as y } from "./constants/currency.js";
|
|
10
|
+
import { ItemsBlockId as E } from "./enums/controlEnums.js";
|
|
11
|
+
import { SETTINGS_ENUMS as b, DefaultConfigValues as p } from "./enums/settingsEnums.js";
|
|
11
12
|
import { getDefaultTemplate as O } from "./template.js";
|
|
12
|
-
import { getItemsBlockContainer as
|
|
13
|
-
const
|
|
14
|
-
class
|
|
13
|
+
import { getItemsBlockContainer as _, getItemsBlockConfig as C, deriveItemNumber as B, generateBlockInstanceId as P, getDefaultItemsBlockConfig as v } from "./utils/nodeConfigUtils.js";
|
|
14
|
+
const A = D.Items, V = "Reconcile Items currency DOM attributes";
|
|
15
|
+
class $ extends H {
|
|
15
16
|
constructor() {
|
|
16
17
|
super(...arguments);
|
|
17
18
|
/** Block instances whose currency attrs were already self-healed this session (SD-147588 — undo-safe). */
|
|
18
|
-
|
|
19
|
+
g(this, "_currencyHealed", /* @__PURE__ */ new Set());
|
|
19
20
|
/** blockInstanceIds already claimed by a live block this session (SD-147588 collision detection). */
|
|
20
|
-
|
|
21
|
+
g(this, "_seenInstanceIds", /* @__PURE__ */ new Set());
|
|
21
22
|
}
|
|
22
23
|
getId() {
|
|
23
|
-
return
|
|
24
|
+
return A;
|
|
24
25
|
}
|
|
25
26
|
getIcon() {
|
|
26
27
|
return "items-icon";
|
|
27
28
|
}
|
|
28
29
|
getBlockCompositionType() {
|
|
29
|
-
return
|
|
30
|
+
return R.CONTAINER;
|
|
30
31
|
}
|
|
31
32
|
getName() {
|
|
32
33
|
return this.api.translate("Items");
|
|
@@ -35,20 +36,20 @@ class K extends A {
|
|
|
35
36
|
return this.api.translate("Items lets you display personalized products based on user behavior.");
|
|
36
37
|
}
|
|
37
38
|
getSettingsPanelTitleHtml() {
|
|
38
|
-
return
|
|
39
|
-
|
|
39
|
+
return N(
|
|
40
|
+
A,
|
|
40
41
|
this.api.translate("Items"),
|
|
41
42
|
this.api.translate("This block is switched from the Old Version to the New Version. We recommend you check the Items block and test your message to ensure it works properly.")
|
|
42
43
|
);
|
|
43
44
|
}
|
|
44
45
|
getTemplate() {
|
|
45
46
|
return O({
|
|
46
|
-
orientation:
|
|
47
|
-
itemsType:
|
|
47
|
+
orientation: b.ORIENTATION.VERTICAL,
|
|
48
|
+
itemsType: b.ITEMS_TYPE.CART_ITEMS,
|
|
48
49
|
itemId: "{{Abandoned Cart Item (1) Url}}",
|
|
49
|
-
currencySymbol:
|
|
50
|
-
currencyLocation:
|
|
51
|
-
formattedPrice:
|
|
50
|
+
currencySymbol: p.productPriceCurrencySymbolControlValue,
|
|
51
|
+
currencyLocation: p.productPriceCurrencyLocationControlValue,
|
|
52
|
+
formattedPrice: p.productPriceFormattedControlValue === "1"
|
|
52
53
|
});
|
|
53
54
|
}
|
|
54
55
|
allowInnerBlocksDND() {
|
|
@@ -57,27 +58,27 @@ class K extends A {
|
|
|
57
58
|
canBeSavedAsModule() {
|
|
58
59
|
return !0;
|
|
59
60
|
}
|
|
60
|
-
onCreated(
|
|
61
|
-
const
|
|
62
|
-
c.querySelector('[product-attr="imageSrc"] img') ||
|
|
63
|
-
const
|
|
64
|
-
if (!
|
|
61
|
+
onCreated(e) {
|
|
62
|
+
const t = this.api.getDocumentModifier(), c = this.api.getDocumentRootCssNode();
|
|
63
|
+
c.querySelector('[product-attr="imageSrc"] img') || t.modifyCss(c).appendRule('[product-attr="imageSrc"] img {object-fit: contain;}');
|
|
64
|
+
const r = _(e);
|
|
65
|
+
if (!r)
|
|
65
66
|
return;
|
|
66
|
-
const
|
|
67
|
-
if (
|
|
67
|
+
const o = r.getNodeConfig(), s = o && Object.keys(o).length > 0, i = C(e);
|
|
68
|
+
if (i != null && i.initialized) {
|
|
68
69
|
if (!s) {
|
|
69
|
-
const
|
|
70
|
-
|
|
70
|
+
const a = this.api.getDocumentModifier();
|
|
71
|
+
a.modifyHtml(r).setNodeConfig(i), this._stampProductTdDomAttributes(r, i, a), this._healCollapsedWidths(r, a), this._shouldReconcileCurrency(i) && this._reconcileCurrencyDomAttributes(r, i, a), a.apply(new u("Migrate legacy config to nodeConfig")), this._markCurrencyHealed(i.blockInstanceId);
|
|
71
72
|
return;
|
|
72
73
|
}
|
|
73
74
|
} else {
|
|
74
|
-
const
|
|
75
|
-
|
|
75
|
+
const a = v(), I = this.api.getDocumentModifier();
|
|
76
|
+
I.modifyHtml(r).setNodeConfig(a), this._stampProductTdDomAttributes(r, a, I, !0), I.apply(new u("Initialize Items block with default configuration")), T().startOnboarding("itemsOnboarding");
|
|
76
77
|
return;
|
|
77
78
|
}
|
|
78
|
-
const n = this._resolveInstanceId(
|
|
79
|
-
let
|
|
80
|
-
n !==
|
|
79
|
+
const n = this._resolveInstanceId(i.blockInstanceId), f = this.api.getDocumentModifier();
|
|
80
|
+
let h = !1;
|
|
81
|
+
n !== i.blockInstanceId && (f.modifyHtml(r).setNodeConfig({ ...i, blockInstanceId: n }), h = !0), !this._currencyHealed.has(n) && this._reconcileCurrencyDomAttributes(r, i, f) && (h = !0), this._healCollapsedWidths(r, f) && (h = !0), h && f.apply(new u("Assign Items block instance ID and reconcile currency")), this._markCurrencyHealed(n);
|
|
81
82
|
}
|
|
82
83
|
/**
|
|
83
84
|
* Re-seeds nodeConfig from the persisted esd-ext-config when a saved module
|
|
@@ -85,24 +86,24 @@ class K extends A {
|
|
|
85
86
|
* into nodeConfig, so without this a reused module would reset to defaults.
|
|
86
87
|
* Guarded to the nodeConfig-empty case so it runs once and never loops.
|
|
87
88
|
*/
|
|
88
|
-
onDocumentChanged(
|
|
89
|
-
const
|
|
90
|
-
if (!
|
|
89
|
+
onDocumentChanged(e) {
|
|
90
|
+
const t = _(e);
|
|
91
|
+
if (!t)
|
|
91
92
|
return;
|
|
92
|
-
const c =
|
|
93
|
+
const c = t.getNodeConfig();
|
|
93
94
|
if (c && Object.keys(c).length > 0) {
|
|
94
|
-
const
|
|
95
|
-
if (
|
|
95
|
+
const i = C(e);
|
|
96
|
+
if (i != null && i.initialized && this._shouldReconcileCurrency(i)) {
|
|
96
97
|
const n = this.api.getDocumentModifier();
|
|
97
|
-
this._reconcileCurrencyDomAttributes(
|
|
98
|
+
this._reconcileCurrencyDomAttributes(t, i, n) && n.apply(new u(V)), this._markCurrencyHealed(i.blockInstanceId);
|
|
98
99
|
}
|
|
99
100
|
return;
|
|
100
101
|
}
|
|
101
|
-
const
|
|
102
|
-
if (!(
|
|
102
|
+
const o = C(e);
|
|
103
|
+
if (!(o != null && o.initialized))
|
|
103
104
|
return;
|
|
104
105
|
const s = this.api.getDocumentModifier();
|
|
105
|
-
s.modifyHtml(
|
|
106
|
+
s.modifyHtml(t).setNodeConfig(o), this._stampProductTdDomAttributes(t, o, s), this._healCollapsedWidths(t, s), this._shouldReconcileCurrency(o) && this._reconcileCurrencyDomAttributes(t, o, s), s.apply(new u("Recover Items block config from saved module")), this._markCurrencyHealed(o.blockInstanceId);
|
|
106
107
|
}
|
|
107
108
|
/**
|
|
108
109
|
* Bakes the compiler-read DOM attributes (`data-type`, `data-number`, `data-nodup`) onto the
|
|
@@ -112,11 +113,21 @@ class K extends A {
|
|
|
112
113
|
* restored before export. The name `<a>` carries no data-type/data-number of its own and
|
|
113
114
|
* relies on this td-level fallback in pairProductVariables.
|
|
114
115
|
*/
|
|
115
|
-
_stampProductTdDomAttributes(
|
|
116
|
-
const
|
|
117
|
-
|
|
116
|
+
_stampProductTdDomAttributes(e, t, c, r = !1) {
|
|
117
|
+
const o = B(t.itemsSelectValue, t.type), s = (i, n) => {
|
|
118
|
+
r && e.getAttribute(i) || c.modifyHtml(e).setAttribute(i, n);
|
|
118
119
|
};
|
|
119
|
-
s("data-type",
|
|
120
|
+
s("data-type", t.type), s("data-number", o), s("data-nodup", String(t.priceHideDiscount));
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Repairs a saved module's collapsed card into the state the load migrator produces. Acts only
|
|
124
|
+
* on a zero width, so Stripo's non-zero drop-time width never triggers it and a healed block no-ops.
|
|
125
|
+
*/
|
|
126
|
+
_healCollapsedWidths(e, t) {
|
|
127
|
+
const r = e.querySelectorAll(M).filter((o) => m(o.getAttribute("width")) || m(o.getStyle("width")));
|
|
128
|
+
return !m(e.getAttribute("width")) && !r.length ? !1 : (e.hasClass("esd-container-frame") && t.modifyHtml(e).removeClass("esd-container-frame"), e.getAttribute("width") !== null && t.modifyHtml(e).removeAttribute("width"), r.forEach((o) => {
|
|
129
|
+
m(o.getAttribute("width")) && t.modifyHtml(o).setAttribute("width", "100%"), m(o.getStyle("width")) && t.modifyHtml(o).setStyle("width", "100%");
|
|
130
|
+
}), !0);
|
|
120
131
|
}
|
|
121
132
|
/**
|
|
122
133
|
* Whether a currency self-heal pass should run for this block (SD-147588). The only gate here is
|
|
@@ -126,12 +137,12 @@ class K extends A {
|
|
|
126
137
|
* the symbol write alone is skipped for the 'USD' sentinel — so we must NOT gate the whole pass
|
|
127
138
|
* on symbol customization here, or a default-symbol block with a toggled location never heals.
|
|
128
139
|
*/
|
|
129
|
-
_shouldReconcileCurrency(
|
|
130
|
-
return !
|
|
140
|
+
_shouldReconcileCurrency(e) {
|
|
141
|
+
return !e.blockInstanceId || !this._currencyHealed.has(e.blockInstanceId);
|
|
131
142
|
}
|
|
132
143
|
/** Marks a block instance's currency as reconciled so it is not healed again (undo-safe). */
|
|
133
|
-
_markCurrencyHealed(
|
|
134
|
-
|
|
144
|
+
_markCurrencyHealed(e) {
|
|
145
|
+
e && this._currencyHealed.add(e);
|
|
135
146
|
}
|
|
136
147
|
/**
|
|
137
148
|
* Resolves the id for a just-created block to one that is unique per live instance.
|
|
@@ -140,13 +151,13 @@ class K extends A {
|
|
|
140
151
|
* currency heal guard and settings-panel switch detection. Mint a fresh id on absence
|
|
141
152
|
* or collision, otherwise keep the existing one. Registers the result as claimed.
|
|
142
153
|
*/
|
|
143
|
-
_resolveInstanceId(
|
|
144
|
-
let
|
|
145
|
-
if (!
|
|
154
|
+
_resolveInstanceId(e) {
|
|
155
|
+
let t = e;
|
|
156
|
+
if (!t || this._seenInstanceIds.has(t))
|
|
146
157
|
do
|
|
147
|
-
|
|
148
|
-
while (this._seenInstanceIds.has(
|
|
149
|
-
return this._seenInstanceIds.add(
|
|
158
|
+
t = P();
|
|
159
|
+
while (this._seenInstanceIds.has(t));
|
|
160
|
+
return this._seenInstanceIds.add(t), t;
|
|
150
161
|
}
|
|
151
162
|
/**
|
|
152
163
|
* Stamps the export-read currency attrs onto every price `<p>` from config, so a template whose
|
|
@@ -159,15 +170,15 @@ class K extends A {
|
|
|
159
170
|
* Returns true only when an attr actually changed, so the caller can skip an empty apply that
|
|
160
171
|
* would otherwise re-trigger onDocumentChanged and loop.
|
|
161
172
|
*/
|
|
162
|
-
_reconcileCurrencyDomAttributes(
|
|
163
|
-
const { position:
|
|
164
|
-
let
|
|
173
|
+
_reconcileCurrencyDomAttributes(e, t, c) {
|
|
174
|
+
const { position: r, symbol: o } = w(t), s = e.querySelectorAll(`.${E.PRICE} p`);
|
|
175
|
+
let i = !1;
|
|
165
176
|
return s.forEach((n) => {
|
|
166
|
-
|
|
167
|
-
}),
|
|
177
|
+
r !== void 0 && n.getAttribute(y.POSITION) !== r && (c.modifyHtml(n).setAttribute(y.POSITION, r), i = !0), o !== void 0 && n.getAttribute(y.SYMBOL) !== o && (c.modifyHtml(n).setAttribute(y.SYMBOL, o), i = !0);
|
|
178
|
+
}), i;
|
|
168
179
|
}
|
|
169
180
|
}
|
|
170
181
|
export {
|
|
171
|
-
|
|
172
|
-
|
|
182
|
+
A as BLOCK_ID,
|
|
183
|
+
$ as ItemsBlock
|
|
173
184
|
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
const R = ".ins-product-td", T = ".ins-product-wrapper", s = "width: 100%", c = /(^|;)\s*width\s*:\s*0(?:px|%)?\s*(?:!important)?\s*(?=;|$)/i, n = new RegExp(c.source, "gi"), o = /(^|;)\s*width\s*:/i, _ = /^0(?:px|%)?$/i, a = (t) => _.test((t ?? "").trim()), E = (t) => c.test(t), h = (t) => {
|
|
2
|
+
if (E(t))
|
|
3
|
+
return t.replace(
|
|
4
|
+
n,
|
|
5
|
+
(i, e) => `${e}${e ? " " : ""}${s}`
|
|
6
|
+
);
|
|
7
|
+
if (o.test(t))
|
|
8
|
+
return t;
|
|
9
|
+
const r = t.trim();
|
|
10
|
+
return r ? r.endsWith(";") ? `${r} ${s};` : `${r}; ${s};` : `${s};`;
|
|
11
|
+
}, p = (t) => t.replace(n, (r, i) => i).replace(/;{2,}/g, ";").replace(/^\s*;\s*/, "").replace(/;\s*$/, "").trim();
|
|
12
|
+
export {
|
|
13
|
+
R as PRODUCT_TD_SELECTOR,
|
|
14
|
+
T as PRODUCT_WRAPPER_SELECTOR,
|
|
15
|
+
s as WIDTH_PIN_DECLARATION,
|
|
16
|
+
E as hasZeroWidthDeclaration,
|
|
17
|
+
a as isZeroWidthValue,
|
|
18
|
+
h as withWidthPin,
|
|
19
|
+
p as withoutZeroWidth
|
|
20
|
+
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const t = `{-{-TEMPLATE_FIRST_LINE-}-}
|
|
2
|
-
<table class="es-left ins-product-wrapper" cellspacing="0" cellpadding="0" align="left" width="100%">
|
|
2
|
+
<table class="es-left ins-product-wrapper" cellspacing="0" cellpadding="0" align="left" width="100%" style="width: 100%;">
|
|
3
3
|
<tbody>
|
|
4
4
|
<tr>
|
|
5
5
|
<td class="es-p20b es-p10r es-p10l es-m-p20b es-p10t" width="100%" align="center">
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
import "../constants/selectors.js";
|
|
2
2
|
import { RRS_CONFIG_VERSION as m } from "../constants/defaultConfig.js";
|
|
3
|
-
import { sanitizeProductIds as p
|
|
4
|
-
const
|
|
5
|
-
function
|
|
3
|
+
import { sanitizeProductIds as p } from "./productIds.js";
|
|
4
|
+
const d = "manualMerchandising";
|
|
5
|
+
function N({ strategyId: e, nodeConfigVersion: t }) {
|
|
6
6
|
return !e && t < m;
|
|
7
7
|
}
|
|
8
8
|
const o = (e) => {
|
|
9
9
|
const t = String(e ?? "").trim();
|
|
10
10
|
return /^[1-9]\d*$/.test(t) ? t : null;
|
|
11
11
|
};
|
|
12
|
-
function
|
|
12
|
+
function f({ campaignId: e, templateLibraryId: t }) {
|
|
13
13
|
if (o(e))
|
|
14
14
|
return { scope: "campaign" };
|
|
15
15
|
const n = o(t);
|
|
16
16
|
return n ? { scope: "template", templateId: n } : { scope: "campaign" };
|
|
17
17
|
}
|
|
18
|
-
function
|
|
18
|
+
function y({
|
|
19
19
|
blockId: e,
|
|
20
20
|
url: t,
|
|
21
21
|
campaignId: n,
|
|
@@ -24,7 +24,7 @@ function S({
|
|
|
24
24
|
productIds: s,
|
|
25
25
|
target: r
|
|
26
26
|
}) {
|
|
27
|
-
const i = c ===
|
|
27
|
+
const i = c === d ? p(s).split(",").filter(Boolean) : [];
|
|
28
28
|
return {
|
|
29
29
|
...r.scope === "template" ? { templateId: Number.parseInt(r.templateId) } : {
|
|
30
30
|
campaignId: Number.parseInt(n) || 0,
|
|
@@ -36,7 +36,7 @@ function S({
|
|
|
36
36
|
};
|
|
37
37
|
}
|
|
38
38
|
export {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
y as buildLegacyMigrationPayload,
|
|
40
|
+
N as isLegacyStrategyConfig,
|
|
41
|
+
f as resolveMigrationTarget
|
|
42
42
|
};
|
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
return t.map((n) => String(n ?? "").trim()).filter(Boolean).join(",");
|
|
1
|
+
function n(t) {
|
|
2
|
+
return t.map((i) => String(i ?? "").trim()).filter(Boolean).join(",");
|
|
4
3
|
}
|
|
5
4
|
export {
|
|
6
|
-
|
|
7
|
-
o as sanitizeProductIds
|
|
5
|
+
n as sanitizeProductIds
|
|
8
6
|
};
|
|
@@ -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
|
+
* Export safety net for a zero Items width: the wrapper gets the 100% pin, the cell's zero is
|
|
15
|
+
* dropped so it keeps its column width (a pin there overflows 33%/50% columns).
|
|
16
|
+
*/
|
|
17
|
+
export declare function normalizeItemsBlockWidths(html: string): string;
|
|
@@ -46,6 +46,11 @@ export declare class ItemsBlock extends Block {
|
|
|
46
46
|
* relies on this td-level fallback in pairProductVariables.
|
|
47
47
|
*/
|
|
48
48
|
private _stampProductTdDomAttributes;
|
|
49
|
+
/**
|
|
50
|
+
* Repairs a saved module's collapsed card into the state the load migrator produces. Acts only
|
|
51
|
+
* on a zero width, so Stripo's non-zero drop-time width never triggers it and a healed block no-ops.
|
|
52
|
+
*/
|
|
53
|
+
private _healCollapsedWidths;
|
|
49
54
|
/**
|
|
50
55
|
* Whether a currency self-heal pass should run for this block (SD-147588). The only gate here is
|
|
51
56
|
* once-per-session: heal each instance at most once, so the auto-fix can't fight undo (undo
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare const PRODUCT_TD_SELECTOR = ".ins-product-td";
|
|
2
|
+
export declare const PRODUCT_WRAPPER_SELECTOR = ".ins-product-wrapper";
|
|
3
|
+
/** The declaration `layouts/vertical.html` and `layouts/horizontal.html` ship inline. */
|
|
4
|
+
export declare const WIDTH_PIN_DECLARATION = "width: 100%";
|
|
5
|
+
/** True for a `width` attribute value that renders the card zero-wide (`0`, `0px`, `0%`). */
|
|
6
|
+
export declare const isZeroWidthValue: (value?: string | null) => boolean;
|
|
7
|
+
/** True when an inline style declares a zero `width` (ignores `max-width` / `min-width`). */
|
|
8
|
+
export declare const hasZeroWidthDeclaration: (style: string) => boolean;
|
|
9
|
+
/** Rewrites a zero width to the pin or appends it; a non-zero width is kept. Idempotent. */
|
|
10
|
+
export declare const withWidthPin: (style: string) => string;
|
|
11
|
+
/** Drops a zero `width` declaration; the product cell must inherit its column width, not be pinned. */
|
|
12
|
+
export declare const withoutZeroWidth: (style: string) => string;
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
/** Separator between product ids in the `sanitizeProductIds` output */
|
|
2
|
-
export declare const PRODUCT_ID_SEPARATOR = ",";
|
|
3
1
|
/**
|
|
4
2
|
* Builds the request/URL `productId` value from raw product ID segments.
|
|
5
3
|
* Trimming happens here — NOT on input change — so the user's in-progress
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
const p = (l) => l.split(/(<!--[\s\S]*?-->)/).map((e, c) => c % 2 ? e : e.replaceAll("{%", "<!--lq{%").replaceAll("%}", "%}lq-->")).join(""), r = (l) => l.replaceAll("<!--lq{%", "{%").replaceAll("%}lq-->", "%}").replaceAll("<!--lq{%", "{%").replaceAll("%}lq-->", "%}");
|
|
2
|
+
export {
|
|
3
|
+
p as protectLiquid,
|
|
4
|
+
r as restoreLiquid
|
|
5
|
+
};
|
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.30c96fc",
|
|
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",
|