@useinsider/guido 3.17.0-beta.dc7f4d2 → 3.17.0-beta.ddd4dde
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/README.md +5 -5
- package/dist/components/Guido.vue.js +8 -8
- package/dist/components/Guido.vue2.js +76 -78
- package/dist/components/organisms/AutoSaveController.vue2.js +8 -9
- package/dist/components/organisms/header/EditorActions.vue.js +2 -2
- package/dist/components/organisms/header/EditorActions.vue2.js +43 -74
- package/dist/components/organisms/header/LeftSlot.vue.js +5 -5
- package/dist/components/organisms/header/LeftSlot.vue2.js +23 -46
- package/dist/components/wrappers/WpDrawer.vue.js +7 -9
- package/dist/components/wrappers/WpDrawer.vue2.js +1 -1
- package/dist/composables/useHtmlCompiler.js +26 -37
- package/dist/composables/useHtmlValidator.js +0 -2
- package/dist/composables/useSave.js +41 -84
- package/dist/composables/validators/useCouponBlockValidator.js +21 -24
- package/dist/composables/validators/useUnsubscribeBlockValidator.js +27 -34
- package/dist/extensions/Blocks/Items/block.js +98 -49
- package/dist/extensions/Blocks/Items/constants/currency.js +11 -0
- package/dist/extensions/Blocks/Items/controls/price/currencyLocation.js +25 -24
- package/dist/extensions/Blocks/Items/controls/price/currencySymbol.js +12 -11
- package/dist/extensions/Blocks/Items/template.js +153 -152
- package/dist/extensions/Blocks/Recommendation/store/recommendation.js +26 -33
- package/dist/guido.css +1 -1
- package/dist/src/components/Guido.vue.d.ts +1 -17
- package/dist/src/components/organisms/header/EditorActions.vue.d.ts +1 -17
- package/dist/src/components/organisms/header/HeaderWrapper.vue.d.ts +1 -17
- package/dist/src/components/organisms/header/RightSlot.vue.d.ts +1 -17
- package/dist/src/components/wrappers/WpDrawer.vue.d.ts +3 -4
- package/dist/src/composables/useHtmlValidator.d.ts +0 -21
- package/dist/src/composables/useSave.d.ts +1 -6
- package/dist/src/composables/validators/useCouponBlockValidator.d.ts +0 -3
- package/dist/src/composables/validators/useUnsubscribeBlockValidator.d.ts +0 -10
- package/dist/src/extensions/Blocks/Items/block.d.ts +21 -0
- package/dist/src/extensions/Blocks/Items/constants/currency.d.ts +19 -0
- package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +0 -5
- package/dist/src/stores/config.d.ts +0 -5
- package/dist/src/utils/templatePreparation.d.ts +0 -30
- package/dist/stores/config.js +6 -13
- package/dist/utils/pairProductVariables.js +60 -59
- package/dist/utils/templatePreparation.js +25 -28
- package/package.json +2 -2
- package/dist/components/organisms/validation/ValidationErrorDrawer.vue.js +0 -20
- package/dist/components/organisms/validation/ValidationErrorDrawer.vue2.js +0 -48
- package/dist/composables/useSaveValidation.js +0 -279
- package/dist/composables/useSaveValidationRollout.js +0 -9
- package/dist/enums/save-validation.js +0 -4
- package/dist/src/@types/save-validation.d.ts +0 -19
- package/dist/src/components/organisms/validation/ValidationErrorDrawer.vue.d.ts +0 -2
- package/dist/src/composables/useSaveValidation.d.ts +0 -6
- package/dist/src/composables/useSaveValidationRollout.d.ts +0 -3
- package/dist/src/enums/save-validation.d.ts +0 -27
- package/dist/src/stores/save-validation.d.ts +0 -22
- package/dist/stores/save-validation.js +0 -30
|
@@ -1,19 +1,17 @@
|
|
|
1
1
|
import r from "./WpDrawer.vue2.js";
|
|
2
2
|
import s from "../../_virtual/_plugin-vue2_normalizer.js";
|
|
3
3
|
var u = function() {
|
|
4
|
-
var t = this,
|
|
5
|
-
return
|
|
4
|
+
var t = this, n = t._self._c, e = t._self._setupProxy;
|
|
5
|
+
return n(e.InDrawer, { class: t.className, attrs: { id: t.id, "footer-status": "", "close-on-outside-click": t.closeOnOutsideClick, "description-status": t.descriptionStatus, "description-text": t.descriptionText, "footer-button-group-options": t.footerButtonGroupOptions, size: t.size, status: t.status, "title-text": t.titleText }, on: { cancelOrBackButtonEvent: function(o) {
|
|
6
6
|
return e.emit("cancelOrBackButtonEvent");
|
|
7
|
-
}, onCloseEvent: function(
|
|
7
|
+
}, onCloseEvent: function(o) {
|
|
8
8
|
return e.emit("onCloseEvent");
|
|
9
|
-
}, primaryButtonEvent: function(
|
|
9
|
+
}, primaryButtonEvent: function(o) {
|
|
10
10
|
return e.emit("primaryButtonEvent");
|
|
11
|
-
}, secondaryButtonEvent: function(n) {
|
|
12
|
-
return e.emit("secondaryButtonEvent");
|
|
13
11
|
} }, scopedSlots: t._u([t.$slots.headerBottomSlot ? { key: "headerBottomSlot", fn: function() {
|
|
14
12
|
return [t._t("headerBottomSlot")];
|
|
15
13
|
}, proxy: !0 } : null, { key: "contentSlot", fn: function() {
|
|
16
|
-
return [
|
|
14
|
+
return [n("div", [t._t("default")], 2)];
|
|
17
15
|
}, proxy: !0 }], null, !0) });
|
|
18
16
|
}, i = [], c = /* @__PURE__ */ s(
|
|
19
17
|
r,
|
|
@@ -23,7 +21,7 @@ var u = function() {
|
|
|
23
21
|
null,
|
|
24
22
|
null
|
|
25
23
|
);
|
|
26
|
-
const
|
|
24
|
+
const f = c.exports;
|
|
27
25
|
export {
|
|
28
|
-
|
|
26
|
+
f as default
|
|
29
27
|
};
|
|
@@ -13,7 +13,7 @@ const r = /* @__PURE__ */ e({
|
|
|
13
13
|
status: { type: Boolean },
|
|
14
14
|
titleText: null
|
|
15
15
|
},
|
|
16
|
-
emits: ["cancelOrBackButtonEvent", "onCloseEvent", "primaryButtonEvent"
|
|
16
|
+
emits: ["cancelOrBackButtonEvent", "onCloseEvent", "primaryButtonEvent"],
|
|
17
17
|
setup(n, { emit: t }) {
|
|
18
18
|
return { __sfc: !0, emit: t, InDrawer: o };
|
|
19
19
|
}
|
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
import { defaultHtmlCompilerRules as
|
|
2
|
-
import { itemsCompilerRules as
|
|
3
|
-
import { liquidCompilerRules as
|
|
4
|
-
import { outlookCompilerRules as
|
|
1
|
+
import { defaultHtmlCompilerRules as R } from "../config/compiler/htmlCompilerRules.js";
|
|
2
|
+
import { itemsCompilerRules as g } from "../config/compiler/itemsCompilerRules.js";
|
|
3
|
+
import { liquidCompilerRules as C } from "../config/compiler/liquidCompilerRules.js";
|
|
4
|
+
import { outlookCompilerRules as b } from "../config/compiler/outlookCompilerRules.js";
|
|
5
5
|
import { recommendationCompilerRules as v } from "../config/compiler/recommendationCompilerRules.js";
|
|
6
6
|
import { socialCompilerRules as H } from "../config/compiler/socialCompilerRules.js";
|
|
7
|
-
import { unsubscribeCompilerRules as
|
|
8
|
-
import { createHtmlCompiler as
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
const x = /* @__PURE__ */ new Set([
|
|
7
|
+
import { unsubscribeCompilerRules as x } from "../config/compiler/unsubscribeCompilerRules.js";
|
|
8
|
+
import { createHtmlCompiler as s } from "../utils/htmlCompiler.js";
|
|
9
|
+
import { useConfig as k } from "./useConfig.js";
|
|
10
|
+
const y = /* @__PURE__ */ new Set([
|
|
12
11
|
// URL/tag encoding fixes — keep merge-tag and placeholder integrity intact.
|
|
13
12
|
"fix-url-encoding-start",
|
|
14
13
|
"fix-url-encoding-end",
|
|
@@ -31,34 +30,24 @@ const x = /* @__PURE__ */ new Set([
|
|
|
31
30
|
// Editor-only attribute strip — AMP4EMAIL has no `contenteditable`, so leaving
|
|
32
31
|
// it in narrows/breaks rendering. Pure attribute removal, emits nothing.
|
|
33
32
|
"remove-contenteditable"
|
|
34
|
-
]),
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
...
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
];
|
|
52
|
-
}), r = p(() => {
|
|
53
|
-
var t;
|
|
54
|
-
const e = c.value, s = n(e), m = n(e.filter((o) => x.has(o.id))), l = (t = a.value) == null ? void 0 : t.fallbackFont;
|
|
55
|
-
return {
|
|
56
|
-
compileHtml: (o) => s.compile(o, void 0, l),
|
|
57
|
-
compileAmpHtml: (o) => m.compile(o, void 0, l)
|
|
58
|
-
};
|
|
59
|
-
});
|
|
60
|
-
return { compileHtml: (e) => r.value.compileHtml(e), compileAmpHtml: (e) => r.value.compileAmpHtml(e) };
|
|
33
|
+
]), M = () => {
|
|
34
|
+
var i, m, r;
|
|
35
|
+
const { compiler: o, isFeatureEnabled: n, partner: a } = k(), p = ((i = o.value) == null ? void 0 : i.customRules) || [], l = [
|
|
36
|
+
...!!((m = o.value) != null && m.ignoreDefaultRules) ? [] : R,
|
|
37
|
+
...v,
|
|
38
|
+
...x,
|
|
39
|
+
...g,
|
|
40
|
+
...b,
|
|
41
|
+
...H,
|
|
42
|
+
...n("liquidSyntax") ? C : [],
|
|
43
|
+
...p.map((e, f) => ({
|
|
44
|
+
...e,
|
|
45
|
+
priority: e.priority + 1e3 + f
|
|
46
|
+
// Ensure additional rules run after default rules
|
|
47
|
+
}))
|
|
48
|
+
], u = s(l), c = l.filter((e) => y.has(e.id)), d = s(c), t = (r = a.value) == null ? void 0 : r.fallbackFont;
|
|
49
|
+
return { compileHtml: (e) => u.compile(e, void 0, t), compileAmpHtml: (e) => d.compile(e, void 0, t) };
|
|
61
50
|
};
|
|
62
51
|
export {
|
|
63
|
-
|
|
52
|
+
M as useHtmlCompiler
|
|
64
53
|
};
|
|
@@ -221,8 +221,6 @@ const De = () => {
|
|
|
221
221
|
export {
|
|
222
222
|
de as buildPartnerAttributeNameSet,
|
|
223
223
|
fe as findInvalidCustomFields,
|
|
224
|
-
pe as getInvalidDynamicContentTags,
|
|
225
|
-
ce as getRecommendationBlockIds,
|
|
226
224
|
ue as parseRecommendationVariable,
|
|
227
225
|
De as useHtmlValidator
|
|
228
226
|
};
|
|
@@ -1,94 +1,51 @@
|
|
|
1
|
-
import { useActionsApi as
|
|
2
|
-
import { useConfig as
|
|
3
|
-
import { useSaveStart as
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { useSyncModuleExtractor as O } from "./useSyncModuleExtractor.js";
|
|
7
|
-
import { ToasterTypeOptions as W } from "../enums/toaster.js";
|
|
1
|
+
import { useActionsApi as T } from "./useActionsApi.js";
|
|
2
|
+
import { useConfig as k } from "./useConfig.js";
|
|
3
|
+
import { useSaveStart as B, useSaveComplete as E } from "./useGuidoActions.js";
|
|
4
|
+
import { useSyncModuleExtractor as q } from "./useSyncModuleExtractor.js";
|
|
5
|
+
import { ToasterTypeOptions as C } from "../enums/toaster.js";
|
|
8
6
|
import { useStripoApi as D } from "../services/stripoApi.js";
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
const n = A(), d = q(), { validateHtml: u } = K(), { validateLiquidSyntax: f } = X(), { validateCouponBlockTags: p } = Q(), { validateUnsubscribeBlockUniqueness: v, validateUnsubscribeBlockHasTemplate: y } = Y(), { callbacks: a, isFeatureEnabled: c } = L(), { extractSyncModuleData: S } = O(), { setSyncModuleUnsubscriptionPages: b } = D(), { editorSave: g, getTemplateData: w } = h(), { showToaster: H } = N(), { getBlockedDomains: V, resolveToast: C } = J(), { prepareTemplateDetails: m } = G(), { collectSaveValidationErrors: E } = M(), { isEnabled: x } = R(), k = z(), T = j(), B = F(), r = async (t, e, o) => {
|
|
21
|
-
if (!c("allowlistEnabled"))
|
|
22
|
-
return !1;
|
|
23
|
-
const i = await V(t, e);
|
|
24
|
-
if (!i.length)
|
|
25
|
-
return !1;
|
|
26
|
-
if (!o) {
|
|
27
|
-
const s = await C(i);
|
|
28
|
-
s != null && s.message && H({
|
|
29
|
-
type: W.Warning,
|
|
30
|
-
message: s.message,
|
|
31
|
-
actionButton: s.actionButton
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
|
-
return !0;
|
|
35
|
-
}, P = async (t) => !p(t.compiledHtml) || !v(t.compiledHtml) || !y(t.compiledHtml) ? !1 : c("liquidSyntax") ? f(t.compiledHtml) : u(t.compiledHtml, t.dynamicContentList, !0), l = async (t, e) => {
|
|
36
|
-
if (!await g())
|
|
37
|
-
return;
|
|
38
|
-
const { unsubscribePayload: i, stripoModules: s } = S(t.rawHtml);
|
|
39
|
-
if (await b(i), t.modules = s, !e.suppress) {
|
|
40
|
-
const U = e.blankCompiled ? { compiledHtml: "", ampHtml: "" } : {};
|
|
41
|
-
d({ ...t, ...U, silent: e.silent });
|
|
42
|
-
}
|
|
43
|
-
return t;
|
|
44
|
-
};
|
|
45
|
-
return { save: async (t = !1, e = !1) => {
|
|
46
|
-
var i;
|
|
7
|
+
import { useTemplatePreparation as L } from "../utils/templatePreparation.js";
|
|
8
|
+
import { useAllowlist as P } from "./useAllowlist.js";
|
|
9
|
+
import { useHtmlValidator as U } from "./useHtmlValidator.js";
|
|
10
|
+
import { useToaster as A } from "./useToaster.js";
|
|
11
|
+
import { useCouponBlockValidator as M } from "./validators/useCouponBlockValidator.js";
|
|
12
|
+
import { useLiquidValidator as h } from "./validators/useLiquidValidator.js";
|
|
13
|
+
import { useUnsubscribeBlockValidator as F } from "./validators/useUnsubscribeBlockValidator.js";
|
|
14
|
+
const $ = () => {
|
|
15
|
+
const n = B(), l = E(), { validateHtml: c } = U(), { validateLiquidSyntax: d } = h(), { validateCouponBlockTags: m } = M(), { validateUnsubscribeBlockUniqueness: u, validateUnsubscribeBlockHasTemplate: p } = F(), { callbacks: e, isFeatureEnabled: a } = k(), { extractSyncModuleData: f } = q(), { setSyncModuleUnsubscriptionPages: v } = D(), { editorSave: S } = T(), { showToaster: b } = A(), { getBlockedDomains: w, resolveToast: V } = P();
|
|
16
|
+
return { save: async (y = !1, s = !1) => {
|
|
17
|
+
var r;
|
|
47
18
|
n();
|
|
48
|
-
const
|
|
49
|
-
if (
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
);
|
|
54
|
-
if (s.length) {
|
|
55
|
-
k.open(s, "save");
|
|
19
|
+
const { prepareTemplateDetails: H } = L(), t = await H();
|
|
20
|
+
if (!m(t.compiledHtml) || !u(t.compiledHtml) || !p(t.compiledHtml))
|
|
21
|
+
return;
|
|
22
|
+
if (a("liquidSyntax")) {
|
|
23
|
+
if (!await d(t.compiledHtml))
|
|
56
24
|
return;
|
|
57
|
-
|
|
58
|
-
} else if (!await P(o))
|
|
25
|
+
} else if (!await c(t.compiledHtml, t.dynamicContentList, !0))
|
|
59
26
|
return;
|
|
60
|
-
if (
|
|
61
|
-
return l(o, { silent: e, suppress: t });
|
|
62
|
-
}, saveWithErrors: async () => {
|
|
63
|
-
var e;
|
|
64
|
-
if (B.isTransactional)
|
|
27
|
+
if ((r = e.value) != null && r.externalValidation && !await e.value.externalValidation(t))
|
|
65
28
|
return;
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
rawHtml: t,
|
|
79
|
-
css: e,
|
|
80
|
-
ampHtml: "",
|
|
81
|
-
ampErrors: [],
|
|
82
|
-
modules: [],
|
|
83
|
-
recommendation: { campaignUrls: {}, configs: {} },
|
|
84
|
-
unsubscribe: {
|
|
85
|
-
status: o.length > 0,
|
|
86
|
-
config: o
|
|
29
|
+
if (a("allowlistEnabled")) {
|
|
30
|
+
const i = await w(t.compiledHtml, t.css);
|
|
31
|
+
if (i.length) {
|
|
32
|
+
if (!s) {
|
|
33
|
+
const o = await V(i);
|
|
34
|
+
o != null && o.message && b({
|
|
35
|
+
type: C.Warning,
|
|
36
|
+
message: o.message,
|
|
37
|
+
actionButton: o.actionButton
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
return;
|
|
87
41
|
}
|
|
88
|
-
}
|
|
89
|
-
|
|
42
|
+
}
|
|
43
|
+
if (!await S())
|
|
44
|
+
return;
|
|
45
|
+
const { unsubscribePayload: g, stripoModules: x } = f(t.rawHtml);
|
|
46
|
+
return await v(g), t.modules = x, y || l({ ...t, silent: s }), t;
|
|
90
47
|
} };
|
|
91
48
|
};
|
|
92
49
|
export {
|
|
93
|
-
|
|
50
|
+
$ as useSave
|
|
94
51
|
};
|
|
@@ -1,27 +1,24 @@
|
|
|
1
|
-
import { ToasterTypeOptions as
|
|
2
|
-
import { COUPON_PLACEHOLDER_DEFAULT as
|
|
3
|
-
import { useToaster as
|
|
4
|
-
import { useTranslations as
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
]),
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
}), !1) : !0 };
|
|
1
|
+
import { ToasterTypeOptions as c } from "../../enums/toaster.js";
|
|
2
|
+
import { COUPON_PLACEHOLDER_DEFAULT as i, COUPON_PLACEHOLDER_LIQUID as l } from "../../extensions/Blocks/CouponBlock/template.js";
|
|
3
|
+
import { useToaster as m } from "../useToaster.js";
|
|
4
|
+
import { useTranslations as p } from "../useTranslations.js";
|
|
5
|
+
const u = /* @__PURE__ */ new Set([
|
|
6
|
+
i,
|
|
7
|
+
l
|
|
8
|
+
]), A = () => {
|
|
9
|
+
const { showToaster: t } = m(), r = p();
|
|
10
|
+
return { validateCouponBlockTags: (e) => {
|
|
11
|
+
const n = new DOMParser().parseFromString(e, "text/html");
|
|
12
|
+
return Array.from(n.querySelectorAll(".coupon-block")).find((s) => {
|
|
13
|
+
var o;
|
|
14
|
+
const a = ((o = s.textContent) == null ? void 0 : o.trim()) ?? "";
|
|
15
|
+
return !u.has(a);
|
|
16
|
+
}) ? (t({
|
|
17
|
+
type: c.Warning,
|
|
18
|
+
message: r("newsletter.coupon-tag-modified")
|
|
19
|
+
}), !1) : !0;
|
|
20
|
+
} };
|
|
22
21
|
};
|
|
23
22
|
export {
|
|
24
|
-
|
|
25
|
-
u as findInvalidCouponBlocks,
|
|
26
|
-
T as useCouponBlockValidator
|
|
23
|
+
A as useCouponBlockValidator
|
|
27
24
|
};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { ToasterTypeOptions as
|
|
1
|
+
import { ToasterTypeOptions as i } from "../../enums/toaster.js";
|
|
2
2
|
import { PAGE_TYPES as u } from "../../enums/unsubscribe.js";
|
|
3
|
-
import { UNSUBSCRIBE_BLOCK_SELECTOR as
|
|
4
|
-
import { useToaster as
|
|
5
|
-
import { useTranslations as
|
|
3
|
+
import { UNSUBSCRIBE_BLOCK_SELECTOR as l, DATA_ATTRIBUTES as a } from "../../extensions/Blocks/Unsubscribe/utils/constants.js";
|
|
4
|
+
import { useToaster as E } from "../useToaster.js";
|
|
5
|
+
import { useTranslations as m } from "../useTranslations.js";
|
|
6
6
|
const T = [
|
|
7
7
|
{
|
|
8
8
|
pageType: u.GLOBAL_UNSUBSCRIBE,
|
|
@@ -12,37 +12,30 @@ const T = [
|
|
|
12
12
|
pageType: u.SUBSCRIPTION_PREFERENCE_CENTER,
|
|
13
13
|
messageKey: "unsubscription-preference.duplicate-pref-center"
|
|
14
14
|
}
|
|
15
|
-
], g = "unsubscription-preference.duplicate-both",
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
return !n || !e;
|
|
28
|
-
}).length;
|
|
29
|
-
}
|
|
30
|
-
const y = () => {
|
|
31
|
-
const { showToaster: r } = p(), s = l();
|
|
32
|
-
return { validateUnsubscribeBlockUniqueness: (e) => {
|
|
33
|
-
const o = m(e);
|
|
34
|
-
return o.length ? (r({
|
|
35
|
-
type: c.Error,
|
|
36
|
-
message: s(o.length > 1 ? g : o[0].messageKey)
|
|
15
|
+
], g = "unsubscription-preference.duplicate-both", b = "unsubscription-preference.select-page-to-continue", P = () => {
|
|
16
|
+
const { showToaster: c } = E(), p = m();
|
|
17
|
+
return { validateUnsubscribeBlockUniqueness: (n) => {
|
|
18
|
+
const o = new DOMParser().parseFromString(n, "text/html"), r = /* @__PURE__ */ new Map();
|
|
19
|
+
o.querySelectorAll(l).forEach((e) => {
|
|
20
|
+
const s = Number(e.getAttribute(a.PAGE_TYPE));
|
|
21
|
+
r.set(s, (r.get(s) ?? 0) + 1);
|
|
22
|
+
});
|
|
23
|
+
const t = T.filter((e) => (r.get(e.pageType) ?? 0) > 1).map((e) => e.messageKey);
|
|
24
|
+
return t.length ? (c({
|
|
25
|
+
type: i.Error,
|
|
26
|
+
message: p(t.length > 1 ? g : t[0])
|
|
37
27
|
}), !1) : !0;
|
|
38
|
-
}, validateUnsubscribeBlockHasTemplate: (
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
28
|
+
}, validateUnsubscribeBlockHasTemplate: (n) => {
|
|
29
|
+
const o = new DOMParser().parseFromString(n, "text/html");
|
|
30
|
+
return Array.from(o.querySelectorAll(l)).some((t) => {
|
|
31
|
+
const e = t.getAttribute(a.PAGE_TYPE), s = t.getAttribute(a.PAGE_LIST);
|
|
32
|
+
return !e || !s;
|
|
33
|
+
}) ? (c({
|
|
34
|
+
type: i.Warning,
|
|
35
|
+
message: p(b)
|
|
36
|
+
}), !1) : !0;
|
|
37
|
+
} };
|
|
42
38
|
};
|
|
43
39
|
export {
|
|
44
|
-
|
|
45
|
-
b as countUnsubBlocksWithoutPage,
|
|
46
|
-
m as findDuplicateUnsubPageTypes,
|
|
47
|
-
y as useUnsubscribeBlockValidator
|
|
40
|
+
P as useUnsubscribeBlockValidator
|
|
48
41
|
};
|
|
@@ -1,20 +1,30 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
|
|
1
|
+
var D = Object.defineProperty;
|
|
2
|
+
var k = (l, a, t) => a in l ? D(l, a, { enumerable: !0, configurable: !0, writable: !0, value: t }) : l[a] = t;
|
|
3
|
+
var I = (l, a, t) => k(l, typeof a != "symbol" ? a + "" : a, t);
|
|
4
|
+
import { BlockId as N } from "../../../enums/block.js";
|
|
5
|
+
import { useOnboardingStore as T } from "../../../stores/onboarding.js";
|
|
6
|
+
import { getMigrationBannerHtml as _ } from "../../../utils/migrationBannerHtml.js";
|
|
7
|
+
import { Block as A, BlockCompositionType as M, ModificationDescription as m } from "../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
|
|
8
|
+
import { currencyPositionFromLocation as O, ITEMS_CURRENCY_ATTR as d } from "./constants/currency.js";
|
|
9
|
+
import { ItemsBlockId as R } from "./enums/controlEnums.js";
|
|
10
|
+
import { SETTINGS_ENUMS as b, DefaultConfigValues as f } from "./enums/settingsEnums.js";
|
|
11
|
+
import { getDefaultTemplate as E } from "./template.js";
|
|
12
|
+
import { getItemsBlockContainer as h, getItemsBlockConfig as C, deriveItemNumber as H, getDefaultItemsBlockConfig as B } from "./utils/nodeConfigUtils.js";
|
|
13
|
+
const S = N.Items, P = "Reconcile Items currency DOM attributes";
|
|
14
|
+
class G extends A {
|
|
15
|
+
constructor() {
|
|
16
|
+
super(...arguments);
|
|
17
|
+
/** Block instances whose currency attrs were already self-healed this session (SD-147588 — undo-safe). */
|
|
18
|
+
I(this, "_currencyHealed", /* @__PURE__ */ new Set());
|
|
19
|
+
}
|
|
10
20
|
getId() {
|
|
11
|
-
return
|
|
21
|
+
return S;
|
|
12
22
|
}
|
|
13
23
|
getIcon() {
|
|
14
24
|
return "items-icon";
|
|
15
25
|
}
|
|
16
26
|
getBlockCompositionType() {
|
|
17
|
-
return
|
|
27
|
+
return M.CONTAINER;
|
|
18
28
|
}
|
|
19
29
|
getName() {
|
|
20
30
|
return this.api.translate("Items");
|
|
@@ -23,20 +33,20 @@ class E extends C {
|
|
|
23
33
|
return this.api.translate("Items lets you display personalized products based on user behavior.");
|
|
24
34
|
}
|
|
25
35
|
getSettingsPanelTitleHtml() {
|
|
26
|
-
return
|
|
27
|
-
|
|
36
|
+
return _(
|
|
37
|
+
S,
|
|
28
38
|
this.api.translate("Items"),
|
|
29
39
|
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.")
|
|
30
40
|
);
|
|
31
41
|
}
|
|
32
42
|
getTemplate() {
|
|
33
|
-
return
|
|
34
|
-
orientation:
|
|
35
|
-
itemsType:
|
|
43
|
+
return E({
|
|
44
|
+
orientation: b.ORIENTATION.VERTICAL,
|
|
45
|
+
itemsType: b.ITEMS_TYPE.CART_ITEMS,
|
|
36
46
|
itemId: "{{Abandoned Cart Item (1) Url}}",
|
|
37
|
-
currencySymbol:
|
|
38
|
-
currencyLocation:
|
|
39
|
-
formattedPrice:
|
|
47
|
+
currencySymbol: f.productPriceCurrencySymbolControlValue,
|
|
48
|
+
currencyLocation: f.productPriceCurrencyLocationControlValue,
|
|
49
|
+
formattedPrice: f.productPriceFormattedControlValue === "1"
|
|
40
50
|
});
|
|
41
51
|
}
|
|
42
52
|
allowInnerBlocksDND() {
|
|
@@ -45,24 +55,27 @@ class E extends C {
|
|
|
45
55
|
canBeSavedAsModule() {
|
|
46
56
|
return !0;
|
|
47
57
|
}
|
|
48
|
-
onCreated(
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
const
|
|
52
|
-
if (!
|
|
58
|
+
onCreated(t) {
|
|
59
|
+
const o = this.api.getDocumentModifier(), s = this.api.getDocumentRootCssNode();
|
|
60
|
+
s.querySelector('[product-attr="imageSrc"] img') || o.modifyCss(s).appendRule('[product-attr="imageSrc"] img {object-fit: contain;}');
|
|
61
|
+
const r = h(t);
|
|
62
|
+
if (!r)
|
|
53
63
|
return;
|
|
54
|
-
const
|
|
55
|
-
if (
|
|
56
|
-
if (
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
s.modifyHtml(e).setNodeConfig(i), this._stampProductTdDomAttributes(e, i, s), s.apply(new c("Migrate legacy config to nodeConfig"));
|
|
64
|
+
const i = r.getNodeConfig(), c = i && Object.keys(i).length > 0, e = C(t);
|
|
65
|
+
if (e != null && e.initialized) {
|
|
66
|
+
if (!c) {
|
|
67
|
+
const u = this.api.getDocumentModifier();
|
|
68
|
+
u.modifyHtml(r).setNodeConfig(e), this._stampProductTdDomAttributes(r, e, u), u.apply(new m("Migrate legacy config to nodeConfig"));
|
|
69
|
+
return;
|
|
61
70
|
}
|
|
62
|
-
else {
|
|
63
|
-
const
|
|
64
|
-
|
|
71
|
+
} else {
|
|
72
|
+
const u = B(), g = this.api.getDocumentModifier();
|
|
73
|
+
g.modifyHtml(r).setNodeConfig(u), this._stampProductTdDomAttributes(r, u, g, !0), g.apply(new m("Initialize Items block with default configuration")), T().startOnboarding("itemsOnboarding");
|
|
74
|
+
return;
|
|
65
75
|
}
|
|
76
|
+
const n = e.blockInstanceId || String(Date.now()), p = this.api.getDocumentModifier();
|
|
77
|
+
let y = !1;
|
|
78
|
+
e.blockInstanceId || (p.modifyHtml(r).setNodeConfig({ ...e, blockInstanceId: n }), y = !0), this._shouldReconcileCurrency(e) && this._reconcileCurrencyDomAttributes(r, e, p) && (y = !0), y && p.apply(new m("Assign Items block instance ID and reconcile currency")), this._markCurrencyHealed(n);
|
|
66
79
|
}
|
|
67
80
|
/**
|
|
68
81
|
* Re-seeds nodeConfig from the persisted esd-ext-config when a saved module
|
|
@@ -70,18 +83,24 @@ class E extends C {
|
|
|
70
83
|
* into nodeConfig, so without this a reused module would reset to defaults.
|
|
71
84
|
* Guarded to the nodeConfig-empty case so it runs once and never loops.
|
|
72
85
|
*/
|
|
73
|
-
onDocumentChanged(
|
|
74
|
-
const
|
|
75
|
-
if (!
|
|
86
|
+
onDocumentChanged(t) {
|
|
87
|
+
const o = h(t);
|
|
88
|
+
if (!o)
|
|
76
89
|
return;
|
|
77
|
-
const
|
|
78
|
-
if (
|
|
90
|
+
const s = o.getNodeConfig();
|
|
91
|
+
if (s && Object.keys(s).length > 0) {
|
|
92
|
+
const e = C(t);
|
|
93
|
+
if (e != null && e.initialized && this._shouldReconcileCurrency(e)) {
|
|
94
|
+
const n = this.api.getDocumentModifier();
|
|
95
|
+
this._reconcileCurrencyDomAttributes(o, e, n) && n.apply(new m(P)), this._markCurrencyHealed(e.blockInstanceId);
|
|
96
|
+
}
|
|
79
97
|
return;
|
|
80
|
-
|
|
81
|
-
|
|
98
|
+
}
|
|
99
|
+
const i = C(t);
|
|
100
|
+
if (!(i != null && i.initialized))
|
|
82
101
|
return;
|
|
83
|
-
const
|
|
84
|
-
|
|
102
|
+
const c = this.api.getDocumentModifier();
|
|
103
|
+
c.modifyHtml(o).setNodeConfig(i), this._stampProductTdDomAttributes(o, i, c), c.apply(new m("Recover Items block config from saved module"));
|
|
85
104
|
}
|
|
86
105
|
/**
|
|
87
106
|
* Bakes the compiler-read DOM attributes (`data-type`, `data-number`, `data-nodup`) onto the
|
|
@@ -91,14 +110,44 @@ class E extends C {
|
|
|
91
110
|
* restored before export. The name `<a>` carries no data-type/data-number of its own and
|
|
92
111
|
* relies on this td-level fallback in pairProductVariables.
|
|
93
112
|
*/
|
|
94
|
-
_stampProductTdDomAttributes(
|
|
95
|
-
const
|
|
96
|
-
|
|
113
|
+
_stampProductTdDomAttributes(t, o, s, r = !1) {
|
|
114
|
+
const i = H(o.itemsSelectValue, o.type), c = (e, n) => {
|
|
115
|
+
r && t.getAttribute(e) || s.modifyHtml(t).setAttribute(e, n);
|
|
97
116
|
};
|
|
98
|
-
|
|
117
|
+
c("data-type", o.type), c("data-number", i), c("data-nodup", String(o.priceHideDiscount));
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Whether the currency self-heal should run for this block. Two guards (SD-147588):
|
|
121
|
+
* 1. Config is only authoritative when the symbol was actually customized — a symbol still at
|
|
122
|
+
* the 'USD' sentinel may be a migrator default, so we trust the DOM's real value over a
|
|
123
|
+
* defaulted config and never overwrite it.
|
|
124
|
+
* 2. Heal each instance at most once per session, so the auto-fix can't fight undo (undo
|
|
125
|
+
* re-drifts the attr, which would otherwise re-trigger the heal forever).
|
|
126
|
+
*/
|
|
127
|
+
_shouldReconcileCurrency(t) {
|
|
128
|
+
const o = (t.priceCurrencySymbol ?? "").trim();
|
|
129
|
+
return !o || o === f.productPriceCurrencySymbolControlValue ? !1 : !t.blockInstanceId || !this._currencyHealed.has(t.blockInstanceId);
|
|
130
|
+
}
|
|
131
|
+
/** Marks a block instance's currency as reconciled so it is not healed again (undo-safe). */
|
|
132
|
+
_markCurrencyHealed(t) {
|
|
133
|
+
t && this._currencyHealed.add(t);
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Stamps the export-read currency attrs onto every price `<p>` from config, so a template whose
|
|
137
|
+
* attrs drifted (e.g. a location toggle before the sync fix) self-heals to match the editor.
|
|
138
|
+
* Config is the source of truth — never derive from visible text. Callers gate this with
|
|
139
|
+
* `_shouldReconcileCurrency`. Returns true only when an attr actually changed, so the caller can
|
|
140
|
+
* skip an empty apply that would otherwise re-trigger onDocumentChanged and loop (SD-147588).
|
|
141
|
+
*/
|
|
142
|
+
_reconcileCurrencyDomAttributes(t, o, s) {
|
|
143
|
+
const r = O(o.priceCurrencyLocation), i = (o.priceCurrencySymbol ?? "").trim(), c = t.querySelectorAll(`.${R.PRICE} p`);
|
|
144
|
+
let e = !1;
|
|
145
|
+
return c.forEach((n) => {
|
|
146
|
+
n.getAttribute(d.POSITION) !== r && (s.modifyHtml(n).setAttribute(d.POSITION, r), e = !0), i && n.getAttribute(d.SYMBOL) !== i && (s.modifyHtml(n).setAttribute(d.SYMBOL, i), e = !0);
|
|
147
|
+
}), e;
|
|
99
148
|
}
|
|
100
149
|
}
|
|
101
150
|
export {
|
|
102
|
-
|
|
103
|
-
|
|
151
|
+
S as BLOCK_ID,
|
|
152
|
+
G as ItemsBlock
|
|
104
153
|
};
|