@useinsider/guido 3.8.1 → 3.8.2-beta.151aeb6
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 +110 -89
- 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/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/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/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/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/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,172 +1,219 @@
|
|
|
1
|
-
import { useConfig as
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { useConfig as W } from "./useConfig.js";
|
|
2
|
+
import { getIgnoredRecommendationBlockIds as G } from "../config/compiler/utils/recommendationIgnoreUtils.js";
|
|
3
|
+
import { TemplateTypes as H } from "../enums/defaults.js";
|
|
4
|
+
import { DISPLAY_CONDITIONS_REGEX as P, DISPLAY_CONDITIONS_EXCEPTIONS_REGEX as X, CampaignCouldNotBeSavedKey as $, CanNotMakeAnyChangesForRunningKey as Y, DATA_ATTRIBUTE_REGEX as U, DYNAMIC_CONTENT_TAG_REGEX as j, ALLOWED_DYNAMIC_SYSTEM_TOKENS as q, VALID_DYNAMIC_VARIABLE_REGEX as K } from "../enums/html-validator.js";
|
|
4
5
|
import { ToasterTypeOptions as c } from "../enums/toaster.js";
|
|
5
|
-
import { itemsBlockDynamicVariables as
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
6
|
+
import { itemsBlockDynamicVariables as z } from "../extensions/Blocks/Items/enums/productEnums.js";
|
|
7
|
+
import { RECOMMENDATION_VARIABLE_BUILTIN_ATTRIBUTES as Z } from "../extensions/Blocks/Recommendation/constants/selectors.js";
|
|
8
|
+
import { useRecommendationExtensionStore as J } from "../extensions/Blocks/Recommendation/store/recommendation.js";
|
|
9
|
+
import { resolveProductAttrValue as Q } from "../extensions/Blocks/Recommendation/templates/utils.js";
|
|
10
|
+
import { RecommendationRequiredFieldsKey as ee } from "../extensions/Blocks/Recommendation/validation/requiredFields.js";
|
|
11
|
+
import { useRecommendationStore as te } from "../stores/recommendation.js";
|
|
12
|
+
import { base64EncodeWithSpecialChars as ne } from "../utils/base64.js";
|
|
13
|
+
import { useHttp as se } from "./useHttp.js";
|
|
14
|
+
import { useToaster as oe } from "./useToaster.js";
|
|
15
|
+
import { useTranslations as ie } from "./useTranslations.js";
|
|
16
|
+
const re = /recommendation-id="(\d+)"/g;
|
|
17
|
+
function ae(t) {
|
|
18
|
+
return [...t.matchAll(re)].map((m) => m[1]);
|
|
16
19
|
}
|
|
17
|
-
function
|
|
18
|
-
return
|
|
20
|
+
function ce(t, m) {
|
|
21
|
+
return m.some((f) => t.startsWith(`${f}_`));
|
|
19
22
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
23
|
+
const le = /^(\d+)_\d+_(.+)$/;
|
|
24
|
+
function me(t) {
|
|
25
|
+
const m = t.match(le);
|
|
26
|
+
return m ? { recoId: m[1], attribute: m[2] } : null;
|
|
27
|
+
}
|
|
28
|
+
function ue(t) {
|
|
29
|
+
const m = new Set(Z);
|
|
30
|
+
return Object.values(t).forEach((f) => {
|
|
31
|
+
m.add(Q(f.attributeName, t).toLowerCase());
|
|
32
|
+
}), m;
|
|
33
|
+
}
|
|
34
|
+
function de(t, m, f, i, d) {
|
|
35
|
+
const u = t.match(/{{([a-zA-Z0-9_.\s]*)}}/gm);
|
|
36
|
+
if (!u)
|
|
37
|
+
return [];
|
|
38
|
+
const p = new Set(m.map((y) => y.toLowerCase())), h = [];
|
|
39
|
+
return u.forEach((y) => {
|
|
40
|
+
const g = y.slice(2, -2).trim().toLowerCase();
|
|
41
|
+
if (g !== "" && p.has(g))
|
|
42
|
+
return;
|
|
43
|
+
const E = me(g);
|
|
44
|
+
if (E && i.has(E.recoId)) {
|
|
45
|
+
if (!d || d.has(E.attribute))
|
|
46
|
+
return;
|
|
47
|
+
h.push(g);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
ce(g, f) || g.includes(".") || h.push(g);
|
|
51
|
+
}), h;
|
|
52
|
+
}
|
|
53
|
+
function fe(t) {
|
|
54
|
+
return (t.replace(U, "$1").match(j) ?? []).filter((i) => {
|
|
55
|
+
const d = i.slice(2, -2), u = d.indexOf("|"), p = (u === -1 ? d : d.slice(0, u)).trim();
|
|
56
|
+
return q.includes(p) ? !1 : K.test(p) ? u !== -1 && d.slice(u + 1).trim() === "" : !0;
|
|
24
57
|
});
|
|
25
58
|
}
|
|
26
|
-
const
|
|
27
|
-
var
|
|
28
|
-
const { showToaster:
|
|
29
|
-
|
|
59
|
+
const xe = () => {
|
|
60
|
+
var I, b;
|
|
61
|
+
const { showToaster: t } = oe(), { post: m } = se(), { config: f } = W(), i = ie(), d = te(), u = J(), p = ((b = (I = f.value) == null ? void 0 : I.partner) == null ? void 0 : b.messageType) === H.transactional, h = async (e) => {
|
|
62
|
+
if (e.size === 0)
|
|
63
|
+
return /* @__PURE__ */ new Set();
|
|
64
|
+
try {
|
|
65
|
+
await u.fetchRecommendationFilters();
|
|
66
|
+
} catch {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
return ue(u.filterList);
|
|
70
|
+
}, y = async (e) => {
|
|
71
|
+
const n = await m(
|
|
30
72
|
"/newsletter/template-library/check-template-html-body",
|
|
31
|
-
{ html:
|
|
32
|
-
), { status:
|
|
33
|
-
return
|
|
73
|
+
{ html: ne(e) }
|
|
74
|
+
), { status: o, message: a } = n.data;
|
|
75
|
+
return o || t({
|
|
34
76
|
type: c.Alert,
|
|
35
|
-
message:
|
|
36
|
-
}),
|
|
77
|
+
message: o === void 0 ? a : i("newsletter.invalid-url-link-for-toaster")
|
|
78
|
+
}), i($), a === i(Y) && t({
|
|
37
79
|
type: c.Alert,
|
|
38
|
-
message:
|
|
39
|
-
}),
|
|
40
|
-
},
|
|
41
|
-
const
|
|
42
|
-
let
|
|
43
|
-
return
|
|
44
|
-
const
|
|
45
|
-
if (
|
|
46
|
-
const [
|
|
47
|
-
|
|
80
|
+
message: i("newsletter.already-in-progress")
|
|
81
|
+
}), o;
|
|
82
|
+
}, g = (e) => !["if", "endif", "else", "elif", "now"].includes(e.toLowerCase()), E = (e) => ["if", "endif"].includes(e.toLowerCase()), T = (e, s) => {
|
|
83
|
+
const n = e.match(/({%(.*?)%})/g);
|
|
84
|
+
let o = !0;
|
|
85
|
+
return n !== null && !p && n.forEach((a) => {
|
|
86
|
+
const r = a.slice(2, -2).trim().match(/(".*?"|[^"\s]+)(?=\s*|\s*$)/g);
|
|
87
|
+
if (r && r.length > 0) {
|
|
88
|
+
const [l] = r;
|
|
89
|
+
g(l) && !s.includes(l) && (t({
|
|
48
90
|
type: c.Warning,
|
|
49
|
-
message:
|
|
50
|
-
}),
|
|
91
|
+
message: i("custom-fields.invalid-custom-fields")
|
|
92
|
+
}), o = !1);
|
|
51
93
|
}
|
|
52
|
-
}),
|
|
53
|
-
},
|
|
54
|
-
const
|
|
55
|
-
return
|
|
56
|
-
},
|
|
94
|
+
}), o;
|
|
95
|
+
}, w = async (e, s, n) => {
|
|
96
|
+
const o = n ? await y(e) : !0;
|
|
97
|
+
return T(e, s) && o;
|
|
98
|
+
}, R = (e) => e.length > 0 ? !0 : (t({
|
|
57
99
|
type: c.Warning,
|
|
58
|
-
message:
|
|
59
|
-
}), !1),
|
|
60
|
-
const s = (e.match(/{/gm) || []).length,
|
|
61
|
-
return s >
|
|
100
|
+
message: i("newsletter.html-content-is-empty")
|
|
101
|
+
}), !1), _ = (e) => {
|
|
102
|
+
const s = (e.match(/{/gm) || []).length, n = (e.match(/}/gm) || []).length;
|
|
103
|
+
return s > n && t({
|
|
62
104
|
type: c.Warning,
|
|
63
|
-
message:
|
|
64
|
-
}), s <
|
|
105
|
+
message: i("custom-fields.missing-closing-braces")
|
|
106
|
+
}), s < n && t({
|
|
65
107
|
type: c.Warning,
|
|
66
|
-
message:
|
|
67
|
-
}), s ===
|
|
68
|
-
},
|
|
69
|
-
const s =
|
|
70
|
-
return s ||
|
|
108
|
+
message: i("custom-fields.missing-opening-braces")
|
|
109
|
+
}), s === n;
|
|
110
|
+
}, N = (e) => {
|
|
111
|
+
const s = fe(e).length === 0;
|
|
112
|
+
return s || t({
|
|
71
113
|
type: c.Warning,
|
|
72
|
-
message:
|
|
114
|
+
message: i("custom-fields.invalid-custom-fields")
|
|
73
115
|
}), s;
|
|
74
|
-
},
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
116
|
+
}, x = (e, s, n, o) => {
|
|
117
|
+
if (p)
|
|
118
|
+
return !0;
|
|
119
|
+
const a = de(
|
|
120
|
+
e,
|
|
121
|
+
s,
|
|
122
|
+
ae(e),
|
|
123
|
+
n,
|
|
124
|
+
o
|
|
125
|
+
);
|
|
126
|
+
if (a.length > 0) {
|
|
127
|
+
const r = `
|
|
128
|
+
<ul>
|
|
129
|
+
${a.map((l) => `<li>${l}</li>`).join("")}
|
|
130
|
+
</ul>
|
|
131
|
+
`;
|
|
132
|
+
return t({
|
|
133
|
+
type: c.Alert,
|
|
134
|
+
message: i("custom-fields.invalid-custom-fields") + r
|
|
135
|
+
}), !1;
|
|
92
136
|
}
|
|
93
137
|
return !0;
|
|
94
|
-
},
|
|
95
|
-
const s = e.match(/{%(.*?)%}/g),
|
|
96
|
-
let
|
|
97
|
-
if (s && s.forEach((
|
|
98
|
-
const
|
|
99
|
-
(!
|
|
138
|
+
}, O = (e) => {
|
|
139
|
+
const s = e.match(/{%(.*?)%}/g), n = [];
|
|
140
|
+
let o = !0;
|
|
141
|
+
if (s && s.forEach((a) => {
|
|
142
|
+
const r = a.match(P), l = a.match(X), v = (r == null ? void 0 : r.join("")) || "";
|
|
143
|
+
(!r || a !== v) && !l && (t({
|
|
100
144
|
type: c.Alert,
|
|
101
|
-
message:
|
|
102
|
-
}),
|
|
103
|
-
|
|
145
|
+
message: i("newsletter.display-conditions-invalid-syntax")
|
|
146
|
+
}), o = !1), r && r.forEach((C) => {
|
|
147
|
+
C.trim() === "=" && (t({
|
|
104
148
|
type: c.Alert,
|
|
105
|
-
message:
|
|
106
|
-
}),
|
|
107
|
-
const
|
|
108
|
-
|
|
109
|
-
|
|
149
|
+
message: i("custom-conditions.wrong-equality-operators")
|
|
150
|
+
}), o = !1);
|
|
151
|
+
const A = C.match(/^[a-zA-Z]*$/g);
|
|
152
|
+
A && A.forEach((S) => {
|
|
153
|
+
E(S) && n.push(S);
|
|
110
154
|
});
|
|
111
155
|
});
|
|
112
|
-
}),
|
|
113
|
-
const
|
|
114
|
-
|
|
156
|
+
}), n.length) {
|
|
157
|
+
const a = n.filter((l) => l === "if"), r = n.filter((l) => l === "endif");
|
|
158
|
+
a.length !== r.length && (t({
|
|
115
159
|
type: c.Alert,
|
|
116
|
-
message:
|
|
117
|
-
}),
|
|
160
|
+
message: i("custom-conditions.missing-if-endif-tag")
|
|
161
|
+
}), o = !1);
|
|
118
162
|
}
|
|
119
|
-
return
|
|
120
|
-
},
|
|
121
|
-
const s = (e.match(/{% /gm) || []).length,
|
|
122
|
-
return
|
|
163
|
+
return o;
|
|
164
|
+
}, k = (e) => {
|
|
165
|
+
const s = (e.match(/{% /gm) || []).length, n = (e.match(/ %}/gm) || []).length, o = s === n;
|
|
166
|
+
return o || t({
|
|
123
167
|
type: c.Warning,
|
|
124
|
-
message:
|
|
125
|
-
}),
|
|
126
|
-
},
|
|
168
|
+
message: i("custom-conditions.no-space-after-braces")
|
|
169
|
+
}), o;
|
|
170
|
+
}, B = (e) => (e.match(/({%(.*?)%})/g) || []).filter((n) => n.includes("if")).map((n) => (n.match(/{{.*}}/gm) || []).length).reduce((n, o) => n + o, 0) > 0 ? (t({
|
|
127
171
|
type: c.Warning,
|
|
128
|
-
message:
|
|
129
|
-
}), !1) : !0,
|
|
172
|
+
message: i("custom-conditions.no-braces-inside-if-tag")
|
|
173
|
+
}), !1) : !0, D = () => u.hasInvalidBlock() ? (t({
|
|
130
174
|
type: c.Alert,
|
|
131
|
-
message:
|
|
132
|
-
}), !1) : !0,
|
|
175
|
+
message: i(ee)
|
|
176
|
+
}), !1) : !0, F = () => d.recommendationConfigs && Object.values(d.recommendationConfigs).find((s) => s.filters.find((n) => n.value === "")) !== void 0 ? (t({
|
|
133
177
|
type: c.Alert,
|
|
134
|
-
message:
|
|
135
|
-
}), !1) : !0,
|
|
178
|
+
message: i("newsletter.fill-all-necessary-fields")
|
|
179
|
+
}), !1) : !0, L = (e) => {
|
|
136
180
|
const s = /src="[^"]*\.(svg|pst)"/gm;
|
|
137
|
-
return e.match(s) === null ? !0 : (
|
|
181
|
+
return e.match(s) === null ? !0 : (t({
|
|
138
182
|
type: c.Alert,
|
|
139
|
-
message:
|
|
183
|
+
message: i("newsletter.invalid-image-type")
|
|
140
184
|
}), !1);
|
|
141
|
-
},
|
|
142
|
-
const
|
|
143
|
-
return Array.from(
|
|
144
|
-
var
|
|
145
|
-
return !((
|
|
146
|
-
}) ? (
|
|
185
|
+
}, V = (e) => {
|
|
186
|
+
const o = new DOMParser().parseFromString(e, "text/html").querySelectorAll(".checkbox-block-v2");
|
|
187
|
+
return Array.from(o).find((r) => {
|
|
188
|
+
var l;
|
|
189
|
+
return !((l = r.id) != null && l.trim());
|
|
190
|
+
}) ? (t({
|
|
147
191
|
type: c.Alert,
|
|
148
|
-
message:
|
|
192
|
+
message: i("unsubscribe-templates.select-checkbox-groups")
|
|
149
193
|
}), !1) : !0;
|
|
150
|
-
},
|
|
151
|
-
const
|
|
152
|
-
return Array.from(
|
|
153
|
-
var
|
|
154
|
-
return !((
|
|
155
|
-
}) ? (
|
|
194
|
+
}, M = (e) => {
|
|
195
|
+
const o = new DOMParser().parseFromString(e, "text/html").querySelectorAll(".radio-button-v2");
|
|
196
|
+
return Array.from(o).find((r) => {
|
|
197
|
+
var l;
|
|
198
|
+
return !((l = r.id) != null && l.trim());
|
|
199
|
+
}) ? (t({
|
|
156
200
|
type: c.Alert,
|
|
157
|
-
message:
|
|
201
|
+
message: i("unsubscribe-templates.select-radio-button-groups")
|
|
158
202
|
}), !1) : !0;
|
|
159
203
|
};
|
|
160
|
-
return { validateHtml: async (e, s,
|
|
161
|
-
var
|
|
162
|
-
const
|
|
163
|
-
...s.map((
|
|
164
|
-
...
|
|
165
|
-
...((
|
|
166
|
-
];
|
|
167
|
-
return await
|
|
204
|
+
return { validateHtml: async (e, s, n = !1) => {
|
|
205
|
+
var v, C;
|
|
206
|
+
const o = [
|
|
207
|
+
...s.map((A) => A.value),
|
|
208
|
+
...z,
|
|
209
|
+
...((C = (v = f.value) == null ? void 0 : v.template) == null ? void 0 : C.customFieldAttributes) ?? []
|
|
210
|
+
], a = G(e), r = await h(a);
|
|
211
|
+
return await w(e, o, n) && R(e) && _(e) && N(e) && x(e, o, a, r) && O(e) && k(e) && B(e) && D() && F() && L(e) && V(e) && M(e);
|
|
168
212
|
} };
|
|
169
213
|
};
|
|
170
214
|
export {
|
|
171
|
-
|
|
215
|
+
ue as buildPartnerAttributeNameSet,
|
|
216
|
+
de as findInvalidCustomFields,
|
|
217
|
+
me as parseRecommendationVariable,
|
|
218
|
+
xe as useHtmlValidator
|
|
172
219
|
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
const o = ["click", "auxclick", "submit"], c = (t) => {
|
|
2
|
+
t.preventDefault(), t.stopPropagation();
|
|
3
|
+
}, a = () => ({ blockPreviewInteractions: (r) => {
|
|
4
|
+
try {
|
|
5
|
+
const e = r.contentDocument;
|
|
6
|
+
if (!e)
|
|
7
|
+
return;
|
|
8
|
+
o.forEach((n) => {
|
|
9
|
+
e.addEventListener(n, c, !0);
|
|
10
|
+
});
|
|
11
|
+
} catch (e) {
|
|
12
|
+
console.warn("[usePreviewInteractionGuard] Could not guard preview iframe:", e);
|
|
13
|
+
}
|
|
14
|
+
} });
|
|
15
|
+
export {
|
|
16
|
+
a as usePreviewInteractionGuard
|
|
17
|
+
};
|
|
@@ -1,32 +1,32 @@
|
|
|
1
|
-
import { useActionsApi as
|
|
1
|
+
import { useActionsApi as H } from "./useActionsApi.js";
|
|
2
2
|
import { useConfig as y } from "./useConfig.js";
|
|
3
|
-
import { useSaveStart as w, useSaveComplete as
|
|
3
|
+
import { useSaveStart as w, useSaveComplete as k } from "./useGuidoActions.js";
|
|
4
4
|
import { useSyncModuleExtractor as q } from "./useSyncModuleExtractor.js";
|
|
5
5
|
import { useStripoApi as C } from "../services/stripoApi.js";
|
|
6
6
|
import { useTemplatePreparation as E } from "../utils/templatePreparation.js";
|
|
7
|
-
import { useHtmlValidator as
|
|
7
|
+
import { useHtmlValidator as B } from "./useHtmlValidator.js";
|
|
8
8
|
import { useCouponBlockValidator as L } from "./validators/useCouponBlockValidator.js";
|
|
9
9
|
import { useLiquidValidator as P } from "./validators/useLiquidValidator.js";
|
|
10
|
-
import { useUnsubscribeBlockValidator as
|
|
11
|
-
const
|
|
12
|
-
const o = w(), s =
|
|
13
|
-
return { save: async (f = !1,
|
|
10
|
+
import { useUnsubscribeBlockValidator as U } from "./validators/useUnsubscribeBlockValidator.js";
|
|
11
|
+
const K = () => {
|
|
12
|
+
const o = w(), s = k(), { validateHtml: r } = B(), { validateLiquidSyntax: l } = P(), { validateCouponBlockTags: n } = L(), { validateUnsubscribeBlockUniqueness: d, validateUnsubscribeBlockHasTemplate: c } = U(), { callbacks: i, isFeatureEnabled: u } = y(), { extractSyncModuleData: m } = q(), { setSyncModuleUnsubscriptionPages: p } = C(), { editorSave: v } = H();
|
|
13
|
+
return { save: async (f = !1, S = !1) => {
|
|
14
14
|
var a;
|
|
15
15
|
o();
|
|
16
|
-
const { prepareTemplateDetails:
|
|
17
|
-
if (!
|
|
16
|
+
const { prepareTemplateDetails: V } = E(), t = await V();
|
|
17
|
+
if (!n(t.compiledHtml) || !d(t.compiledHtml) || !c(t.compiledHtml))
|
|
18
18
|
return;
|
|
19
19
|
if (u("liquidSyntax")) {
|
|
20
|
-
if (!await
|
|
20
|
+
if (!await l(t.compiledHtml))
|
|
21
21
|
return;
|
|
22
22
|
} else if (!await r(t.compiledHtml, t.dynamicContentList, !0))
|
|
23
23
|
return;
|
|
24
|
-
if ((a = i.value) != null && a.externalValidation && !await i.value.externalValidation(t) || !await
|
|
24
|
+
if ((a = i.value) != null && a.externalValidation && !await i.value.externalValidation(t) || !await v())
|
|
25
25
|
return;
|
|
26
|
-
const { unsubscribePayload:
|
|
27
|
-
return await
|
|
26
|
+
const { unsubscribePayload: b, stripoModules: x } = m(t.rawHtml);
|
|
27
|
+
return await p(b), t.modules = x, f || s({ ...t, silent: S }), t;
|
|
28
28
|
} };
|
|
29
29
|
};
|
|
30
30
|
export {
|
|
31
|
-
|
|
31
|
+
K as useSave
|
|
32
32
|
};
|
|
@@ -1,32 +1,41 @@
|
|
|
1
1
|
import { ToasterTypeOptions as i } from "../../enums/toaster.js";
|
|
2
|
-
import { PAGE_TYPES as
|
|
3
|
-
import { UNSUBSCRIBE_BLOCK_SELECTOR as
|
|
4
|
-
import { useToaster as
|
|
2
|
+
import { PAGE_TYPES as u } from "../../enums/unsubscribe.js";
|
|
3
|
+
import { UNSUBSCRIBE_BLOCK_SELECTOR as l, DATA_ATTRIBUTES as a } from "../../extensions/Blocks/Unsubscribe/utils/constants.js";
|
|
4
|
+
import { useToaster as m } from "../useToaster.js";
|
|
5
5
|
import { useTranslations as E } from "../useTranslations.js";
|
|
6
|
-
const
|
|
6
|
+
const T = [
|
|
7
7
|
{
|
|
8
|
-
pageType:
|
|
8
|
+
pageType: u.GLOBAL_UNSUBSCRIBE,
|
|
9
9
|
messageKey: "unsubscription-preference.duplicate-global-unsub"
|
|
10
10
|
},
|
|
11
11
|
{
|
|
12
|
-
pageType:
|
|
12
|
+
pageType: u.SUBSCRIPTION_PREFERENCE_CENTER,
|
|
13
13
|
messageKey: "unsubscription-preference.duplicate-pref-center"
|
|
14
14
|
}
|
|
15
|
-
], g = "unsubscription-preference.duplicate-both",
|
|
16
|
-
const { showToaster:
|
|
17
|
-
return { validateUnsubscribeBlockUniqueness: (
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
const r = Number(e.getAttribute(
|
|
21
|
-
|
|
15
|
+
], g = "unsubscription-preference.duplicate-both", b = "unsubscription-preference.select-page-to-continue", P = () => {
|
|
16
|
+
const { showToaster: c } = m(), p = E();
|
|
17
|
+
return { validateUnsubscribeBlockUniqueness: (n) => {
|
|
18
|
+
const o = new DOMParser().parseFromString(n, "text/html"), s = /* @__PURE__ */ new Map();
|
|
19
|
+
o.querySelectorAll(l).forEach((e) => {
|
|
20
|
+
const r = Number(e.getAttribute(a.PAGE_TYPE));
|
|
21
|
+
s.set(r, (s.get(r) ?? 0) + 1);
|
|
22
22
|
});
|
|
23
|
-
const
|
|
24
|
-
return
|
|
23
|
+
const t = T.filter((e) => (s.get(e.pageType) ?? 0) > 1).map((e) => e.messageKey);
|
|
24
|
+
return t.length ? (c({
|
|
25
25
|
type: i.Alert,
|
|
26
|
-
message:
|
|
26
|
+
message: p(t.length > 1 ? g : t[0])
|
|
27
|
+
}), !1) : !0;
|
|
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), r = t.getAttribute(a.PAGE_LIST);
|
|
32
|
+
return !e || !r;
|
|
33
|
+
}) ? (c({
|
|
34
|
+
type: i.Warning,
|
|
35
|
+
message: p(b)
|
|
27
36
|
}), !1) : !0;
|
|
28
37
|
} };
|
|
29
38
|
};
|
|
30
39
|
export {
|
|
31
|
-
|
|
40
|
+
P as useUnsubscribeBlockValidator
|
|
32
41
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { stripFontTags as
|
|
2
|
-
const
|
|
1
|
+
import { stripFontTags as p } from "../../utils/stripFontTags.js";
|
|
2
|
+
const d = [
|
|
3
3
|
{
|
|
4
4
|
id: "fix-url-encoding-start",
|
|
5
5
|
description: "Replace {%22 with %7B%22 to fix URL encoding",
|
|
@@ -58,7 +58,7 @@ const l = [
|
|
|
58
58
|
id: "strip-font-tags",
|
|
59
59
|
description: 'Unwrap browser-translate-injected <font dir="auto"> tags, keeping inner content; other <font> elements are left intact.',
|
|
60
60
|
type: "custom",
|
|
61
|
-
processor: (e) =>
|
|
61
|
+
processor: (e) => p(e),
|
|
62
62
|
priority: 15
|
|
63
63
|
},
|
|
64
64
|
{
|
|
@@ -99,7 +99,7 @@ const l = [
|
|
|
99
99
|
description: "Adding MSO Conditions",
|
|
100
100
|
type: "custom",
|
|
101
101
|
processor: (e) => {
|
|
102
|
-
const
|
|
102
|
+
const t = [
|
|
103
103
|
`<!--[if gte mso 9]>
|
|
104
104
|
<style>sup {
|
|
105
105
|
font-size: 100% !important;
|
|
@@ -119,13 +119,13 @@ const l = [
|
|
|
119
119
|
<w:DontUseAdvancedTypographyReadingMail></w:DontUseAdvancedTypographyReadingMail>
|
|
120
120
|
</w:WordDocument>
|
|
121
121
|
</xml><![endif]-->`
|
|
122
|
-
],
|
|
122
|
+
], i = /<head>([\S\s]*)<\/head>/, o = new RegExp(i);
|
|
123
123
|
if (!e.match(o))
|
|
124
124
|
return e;
|
|
125
|
-
let
|
|
126
|
-
return
|
|
127
|
-
|
|
128
|
-
}),
|
|
125
|
+
let s = e;
|
|
126
|
+
return t.forEach((r) => {
|
|
127
|
+
s = s.replace("</head>", `${r}</head>`);
|
|
128
|
+
}), s;
|
|
129
129
|
},
|
|
130
130
|
priority: 30
|
|
131
131
|
},
|
|
@@ -146,8 +146,36 @@ const l = [
|
|
|
146
146
|
replacement: "email-static.useinsider.com",
|
|
147
147
|
replaceAll: !0,
|
|
148
148
|
priority: 41
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
id: "convert-rgb-to-hex",
|
|
152
|
+
// SD-142395: rgb()/6-digit hex are verbose; hex/3-digit shorthand is byte-identical
|
|
153
|
+
// to render. Shrinks the whole email to stay under Gmail's ~102KB clip threshold.
|
|
154
|
+
// Leaves rgba()/8-digit hex (alpha) untouched.
|
|
155
|
+
description: "Convert rgb() colors to hex and collapse 6-digit hex to shorthand",
|
|
156
|
+
type: "custom",
|
|
157
|
+
processor: (e) => {
|
|
158
|
+
const t = (i) => i.toString(16).padStart(2, "0");
|
|
159
|
+
return e.replace(/rgb\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)/gi, (i, o, n, s) => {
|
|
160
|
+
const [r, a, c] = [Number(o), Number(n), Number(s)];
|
|
161
|
+
return r > 255 || a > 255 || c > 255 ? i : `#${t(r)}${t(a)}${t(c)}`;
|
|
162
|
+
}).replace(/#([0-9a-f])\1([0-9a-f])\2([0-9a-f])\3\b/gi, "#$1$2$3");
|
|
163
|
+
},
|
|
164
|
+
priority: 44
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
id: "remove-contenteditable",
|
|
168
|
+
// SD-142395: contenteditable is a Stripo editor flag with zero effect in a
|
|
169
|
+
// delivered email. Stripping it globally shaves bytes off every text block,
|
|
170
|
+
// helping the whole email stay under Gmail's ~102KB clip threshold.
|
|
171
|
+
description: "Strip editor-only contenteditable attributes from compiled output",
|
|
172
|
+
type: "regex",
|
|
173
|
+
pattern: '\\s+contenteditable="[^"]*"',
|
|
174
|
+
replacement: "",
|
|
175
|
+
flags: "g",
|
|
176
|
+
priority: 45
|
|
149
177
|
}
|
|
150
178
|
];
|
|
151
179
|
export {
|
|
152
|
-
|
|
180
|
+
d as defaultHtmlCompilerRules
|
|
153
181
|
};
|