@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.
Files changed (56) hide show
  1. package/dist/components/organisms/email-preview/desktop-preview/DesktopPreview.vue.js +8 -8
  2. package/dist/components/organisms/email-preview/desktop-preview/DesktopPreview.vue2.js +15 -12
  3. package/dist/components/organisms/email-preview/mobile-preview/ContentView.vue.js +5 -5
  4. package/dist/components/organisms/email-preview/mobile-preview/ContentView.vue2.js +16 -15
  5. package/dist/components/organisms/unsubscribe/UnsubscribePageSelection.vue.js +5 -5
  6. package/dist/components/organisms/unsubscribe/UnsubscribePageSelection.vue2.js +42 -37
  7. package/dist/components/organisms/unsubscribe/UnsubscribeTypeSelection.vue.js +3 -3
  8. package/dist/components/organisms/unsubscribe/UnsubscribeTypeSelection.vue2.js +40 -37
  9. package/dist/composables/useHtmlCompiler.js +13 -10
  10. package/dist/composables/useHtmlValidator.js +180 -133
  11. package/dist/composables/usePreviewInteractionGuard.js +17 -0
  12. package/dist/composables/useSave.js +14 -14
  13. package/dist/composables/validators/useUnsubscribeBlockValidator.js +26 -17
  14. package/dist/config/compiler/htmlCompilerRules.js +38 -10
  15. package/dist/config/compiler/recommendationCompilerRules.js +83 -108
  16. package/dist/config/compiler/utils/recommendationCompilerUtils.js +110 -89
  17. package/dist/config/compiler/utils/recommendationIgnoreUtils.js +15 -0
  18. package/dist/config/migrator/recommendation/extractors.js +44 -22
  19. package/dist/config/migrator/recommendation/htmlBuilder.js +175 -169
  20. package/dist/config/migrator/recommendationMigrator.js +30 -31
  21. package/dist/extensions/Blocks/Recommendation/constants/selectors.js +26 -20
  22. package/dist/extensions/Blocks/Recommendation/controls/cardComposition/index.js +55 -41
  23. package/dist/extensions/Blocks/Recommendation/controls/main/index.js +58 -57
  24. package/dist/extensions/Blocks/Recommendation/controls/main/layoutOrientation.js +43 -31
  25. package/dist/extensions/Blocks/Recommendation/controls/main/productCount.js +3 -2
  26. package/dist/extensions/Blocks/Recommendation/controls/main/productLayout.js +55 -45
  27. package/dist/extensions/Blocks/Recommendation/controls/main/utils.js +60 -53
  28. package/dist/extensions/Blocks/Recommendation/controls/syncInfoMessage.js +7 -6
  29. package/dist/extensions/Blocks/Recommendation/extension.js +3 -2
  30. package/dist/extensions/Blocks/Recommendation/settingsPanel.js +3 -2
  31. package/dist/extensions/Blocks/Recommendation/store/recommendation.js +3 -2
  32. package/dist/extensions/Blocks/Recommendation/templates/grid/template.js +13 -12
  33. package/dist/extensions/Blocks/Recommendation/templates/index.js +7 -6
  34. package/dist/extensions/Blocks/Recommendation/templates/utils.js +1 -1
  35. package/dist/extensions/Blocks/Unsubscribe/block.js +40 -37
  36. package/dist/extensions/Blocks/Unsubscribe/control.js +19 -16
  37. package/dist/guido.css +1 -1
  38. package/dist/src/composables/useHtmlValidator.d.ts +27 -0
  39. package/dist/src/composables/useHtmlValidator.test.d.ts +1 -0
  40. package/dist/src/composables/usePreviewInteractionGuard.d.ts +3 -0
  41. package/dist/src/composables/validators/useUnsubscribeBlockValidator.d.ts +1 -0
  42. package/dist/src/config/compiler/utils/recommendationIgnoreUtils.d.ts +17 -0
  43. package/dist/src/config/compiler/utils/recommendationIgnoreUtils.test.d.ts +1 -0
  44. package/dist/src/config/migrator/recommendation/extractors.d.ts +15 -0
  45. package/dist/src/config/migrator/recommendation/htmlBuilder.d.ts +8 -0
  46. package/dist/src/extensions/Blocks/Recommendation/constants/index.d.ts +1 -1
  47. package/dist/src/extensions/Blocks/Recommendation/constants/selectors.d.ts +21 -0
  48. package/dist/src/extensions/Blocks/Recommendation/controls/cardComposition/index.d.ts +7 -0
  49. package/dist/src/extensions/Blocks/Recommendation/controls/main/layoutOrientation.d.ts +5 -0
  50. package/dist/src/extensions/Blocks/Recommendation/controls/main/productLayout.d.ts +6 -0
  51. package/dist/src/extensions/Blocks/Recommendation/controls/main/utils.d.ts +9 -0
  52. package/dist/src/stores/unsubscribe.d.ts +11 -1
  53. package/dist/src/utils/ampErrorFilter.d.ts +1 -0
  54. package/dist/stores/unsubscribe.js +8 -7
  55. package/dist/utils/ampErrorFilter.js +6 -5
  56. package/package.json +1 -1
@@ -1,172 +1,219 @@
1
- import { useConfig as V } from "./useConfig.js";
2
- import { TemplateTypes as G } from "../enums/defaults.js";
3
- import { DISPLAY_CONDITIONS_REGEX as H, DISPLAY_CONDITIONS_EXCEPTIONS_REGEX as M, CampaignCouldNotBeSavedKey as X, CanNotMakeAnyChangesForRunningKey as P, DATA_ATTRIBUTE_REGEX as Y, DYNAMIC_CONTENT_TAG_REGEX as $, ALLOWED_DYNAMIC_SYSTEM_TOKENS as q, VALID_DYNAMIC_VARIABLE_REGEX as K } from "../enums/html-validator.js";
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 j } from "../extensions/Blocks/Items/enums/productEnums.js";
6
- import { useRecommendationExtensionStore as U } from "../extensions/Blocks/Recommendation/store/recommendation.js";
7
- import { RecommendationRequiredFieldsKey as z } from "../extensions/Blocks/Recommendation/validation/requiredFields.js";
8
- import { useRecommendationStore as Z } from "../stores/recommendation.js";
9
- import { base64EncodeWithSpecialChars as J } from "../utils/base64.js";
10
- import { useHttp as Q } from "./useHttp.js";
11
- import { useToaster as ee } from "./useToaster.js";
12
- import { useTranslations as te } from "./useTranslations.js";
13
- const se = /recommendation-id="(\d+)"/g;
14
- function ne(i) {
15
- return [...i.matchAll(se)].map((d) => d[1]);
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 ie(i, d) {
18
- return d.some((g) => i.startsWith(`${g}_`));
20
+ function ce(t, m) {
21
+ return m.some((f) => t.startsWith(`${f}_`));
19
22
  }
20
- function oe(i) {
21
- return (i.replace(Y, "$1").match($) ?? []).filter((r) => {
22
- const u = r.slice(2, -2), f = u.indexOf("|"), p = (f === -1 ? u : u.slice(0, f)).trim();
23
- return q.includes(p) ? !1 : K.test(p) ? f !== -1 && u.slice(f + 1).trim() === "" : !0;
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 Ce = () => {
27
- var h, v;
28
- const { showToaster: i } = ee(), { post: d } = Q(), { config: g } = V(), r = te(), u = Z(), f = U(), p = ((v = (h = g.value) == null ? void 0 : h.partner) == null ? void 0 : v.messageType) === G.transactional, A = async (e) => {
29
- const t = await d(
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: J(e) }
32
- ), { status: n, message: l } = t.data;
33
- return n || i({
73
+ { html: ne(e) }
74
+ ), { status: o, message: a } = n.data;
75
+ return o || t({
34
76
  type: c.Alert,
35
- message: n === void 0 ? l : r("newsletter.invalid-url-link-for-toaster")
36
- }), r(X), l === r(P) && i({
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: r("newsletter.already-in-progress")
39
- }), n;
40
- }, S = (e) => !["if", "endif", "else", "elif", "now"].includes(e.toLowerCase()), b = (e) => ["if", "endif"].includes(e.toLowerCase()), I = (e, s) => {
41
- const t = e.match(/({%(.*?)%})/g);
42
- let n = !0;
43
- return t !== null && !p && t.forEach((l) => {
44
- const o = l.slice(2, -2).trim().match(/(".*?"|[^"\s]+)(?=\s*|\s*$)/g);
45
- if (o && o.length > 0) {
46
- const [a] = o;
47
- S(a) && !s.includes(a) && (i({
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: r("custom-fields.invalid-custom-fields")
50
- }), n = !1);
91
+ message: i("custom-fields.invalid-custom-fields")
92
+ }), o = !1);
51
93
  }
52
- }), n;
53
- }, T = async (e, s, t) => {
54
- const n = t ? await A(e) : !0;
55
- return I(e, s) && n;
56
- }, w = (e) => e.length > 0 ? !0 : (i({
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: r("newsletter.html-content-is-empty")
59
- }), !1), x = (e) => {
60
- const s = (e.match(/{/gm) || []).length, t = (e.match(/}/gm) || []).length;
61
- return s > t && i({
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: r("custom-fields.missing-closing-braces")
64
- }), s < t && i({
105
+ message: i("custom-fields.missing-closing-braces")
106
+ }), s < n && t({
65
107
  type: c.Warning,
66
- message: r("custom-fields.missing-opening-braces")
67
- }), s === t;
68
- }, _ = (e) => {
69
- const s = oe(e).length === 0;
70
- return s || i({
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: r("custom-fields.invalid-custom-fields")
114
+ message: i("custom-fields.invalid-custom-fields")
73
115
  }), s;
74
- }, k = (e, s) => {
75
- const t = e.match(/{{([a-zA-Z0-9_\s]*)}}/gm);
76
- if (t && !p) {
77
- const n = new Set(s.map((a) => a.toLowerCase())), l = ne(e), o = [];
78
- if (t.forEach((a) => {
79
- const m = a.slice(2, -2).trim().toLowerCase();
80
- (!n.has(m) || m === "") && !ie(m, l) && o.push(m);
81
- }), o.length > 0) {
82
- const a = `
83
- <ul>
84
- ${o.map((m) => `<li>${m}</li>`).join("")}
85
- </ul>
86
- `;
87
- return i({
88
- type: c.Alert,
89
- message: r("custom-fields.invalid-custom-fields") + a
90
- }), !1;
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
- }, R = (e) => {
95
- const s = e.match(/{%(.*?)%}/g), t = [];
96
- let n = !0;
97
- if (s && s.forEach((l) => {
98
- const o = l.match(H), a = l.match(M), m = (o == null ? void 0 : o.join("")) || "";
99
- (!o || l !== m) && !a && (i({
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: r("newsletter.display-conditions-invalid-syntax")
102
- }), n = !1), o && o.forEach((y) => {
103
- y.trim() === "=" && (i({
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: r("custom-conditions.wrong-equality-operators")
106
- }), n = !1);
107
- const C = y.match(/^[a-zA-Z]*$/g);
108
- C && C.forEach((E) => {
109
- b(E) && t.push(E);
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
- }), t.length) {
113
- const l = t.filter((a) => a === "if"), o = t.filter((a) => a === "endif");
114
- l.length !== o.length && (i({
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: r("custom-conditions.missing-if-endif-tag")
117
- }), n = !1);
160
+ message: i("custom-conditions.missing-if-endif-tag")
161
+ }), o = !1);
118
162
  }
119
- return n;
120
- }, N = (e) => {
121
- const s = (e.match(/{% /gm) || []).length, t = (e.match(/ %}/gm) || []).length, n = s === t;
122
- return n || i({
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: r("custom-conditions.no-space-after-braces")
125
- }), n;
126
- }, D = (e) => (e.match(/({%(.*?)%})/g) || []).filter((t) => t.includes("if")).map((t) => (t.match(/{{.*}}/gm) || []).length).reduce((t, n) => t + n, 0) > 0 ? (i({
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: r("custom-conditions.no-braces-inside-if-tag")
129
- }), !1) : !0, F = () => f.hasInvalidBlock() ? (i({
172
+ message: i("custom-conditions.no-braces-inside-if-tag")
173
+ }), !1) : !0, D = () => u.hasInvalidBlock() ? (t({
130
174
  type: c.Alert,
131
- message: r(z)
132
- }), !1) : !0, O = () => u.recommendationConfigs && Object.values(u.recommendationConfigs).find((s) => s.filters.find((t) => t.value === "")) !== void 0 ? (i({
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: r("newsletter.fill-all-necessary-fields")
135
- }), !1) : !0, B = (e) => {
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 : (i({
181
+ return e.match(s) === null ? !0 : (t({
138
182
  type: c.Alert,
139
- message: r("newsletter.invalid-image-type")
183
+ message: i("newsletter.invalid-image-type")
140
184
  }), !1);
141
- }, L = (e) => {
142
- const n = new DOMParser().parseFromString(e, "text/html").querySelectorAll(".checkbox-block-v2");
143
- return Array.from(n).find((o) => {
144
- var a;
145
- return !((a = o.id) != null && a.trim());
146
- }) ? (i({
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: r("unsubscribe-templates.select-checkbox-groups")
192
+ message: i("unsubscribe-templates.select-checkbox-groups")
149
193
  }), !1) : !0;
150
- }, W = (e) => {
151
- const n = new DOMParser().parseFromString(e, "text/html").querySelectorAll(".radio-button-v2");
152
- return Array.from(n).find((o) => {
153
- var a;
154
- return !((a = o.id) != null && a.trim());
155
- }) ? (i({
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: r("unsubscribe-templates.select-radio-button-groups")
201
+ message: i("unsubscribe-templates.select-radio-button-groups")
158
202
  }), !1) : !0;
159
203
  };
160
- return { validateHtml: async (e, s, t = !1) => {
161
- var o, a;
162
- const n = [
163
- ...s.map((m) => m.value),
164
- ...j,
165
- ...((a = (o = g.value) == null ? void 0 : o.template) == null ? void 0 : a.customFieldAttributes) ?? []
166
- ];
167
- return await T(e, n, t) && w(e) && x(e) && _(e) && k(e, n) && R(e) && N(e) && D(e) && F() && O() && B(e) && L(e) && W(e);
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
- Ce as useHtmlValidator
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 x } from "./useActionsApi.js";
1
+ import { useActionsApi as H } from "./useActionsApi.js";
2
2
  import { useConfig as y } from "./useConfig.js";
3
- import { useSaveStart as w, useSaveComplete as H } from "./useGuidoActions.js";
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 k } from "./useHtmlValidator.js";
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 B } from "./validators/useUnsubscribeBlockValidator.js";
11
- const J = () => {
12
- const o = w(), s = H(), { validateHtml: r } = k(), { validateLiquidSyntax: n } = P(), { validateCouponBlockTags: l } = L(), { validateUnsubscribeBlockUniqueness: d } = B(), { callbacks: i, isFeatureEnabled: u } = y(), { extractSyncModuleData: c } = q(), { setSyncModuleUnsubscriptionPages: m } = C(), { editorSave: p } = x();
13
- return { save: async (f = !1, v = !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: S } = E(), t = await S();
17
- if (!l(t.compiledHtml) || !d(t.compiledHtml))
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 n(t.compiledHtml))
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 p())
24
+ if ((a = i.value) != null && a.externalValidation && !await i.value.externalValidation(t) || !await v())
25
25
  return;
26
- const { unsubscribePayload: V, stripoModules: b } = c(t.rawHtml);
27
- return await m(V), t.modules = b, f || s({ ...t, silent: v }), t;
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
- J as useSave
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 n } from "../../enums/unsubscribe.js";
3
- import { UNSUBSCRIBE_BLOCK_SELECTOR as u, DATA_ATTRIBUTES as l } from "../../extensions/Blocks/Unsubscribe/utils/constants.js";
4
- import { useToaster as T } from "../useToaster.js";
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 m = [
6
+ const T = [
7
7
  {
8
- pageType: n.GLOBAL_UNSUBSCRIBE,
8
+ pageType: u.GLOBAL_UNSUBSCRIBE,
9
9
  messageKey: "unsubscription-preference.duplicate-global-unsub"
10
10
  },
11
11
  {
12
- pageType: n.SUBSCRIPTION_PREFERENCE_CENTER,
12
+ pageType: u.SUBSCRIPTION_PREFERENCE_CENTER,
13
13
  messageKey: "unsubscription-preference.duplicate-pref-center"
14
14
  }
15
- ], g = "unsubscription-preference.duplicate-both", y = () => {
16
- const { showToaster: o } = T(), a = E();
17
- return { validateUnsubscribeBlockUniqueness: (c) => {
18
- const p = new DOMParser().parseFromString(c, "text/html"), t = /* @__PURE__ */ new Map();
19
- p.querySelectorAll(u).forEach((e) => {
20
- const r = Number(e.getAttribute(l.PAGE_TYPE));
21
- t.set(r, (t.get(r) ?? 0) + 1);
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 s = m.filter((e) => (t.get(e.pageType) ?? 0) > 1).map((e) => e.messageKey);
24
- return s.length ? (o({
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: a(s.length > 1 ? g : s[0])
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
- y as useUnsubscribeBlockValidator
40
+ P as useUnsubscribeBlockValidator
32
41
  };
@@ -1,5 +1,5 @@
1
- import { stripFontTags as n } from "../../utils/stripFontTags.js";
2
- const l = [
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) => n(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 i = [
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
- ], s = /<head>([\S\s]*)<\/head>/, o = new RegExp(s);
122
+ ], i = /<head>([\S\s]*)<\/head>/, o = new RegExp(i);
123
123
  if (!e.match(o))
124
124
  return e;
125
- let t = e;
126
- return i.forEach((r) => {
127
- t = t.replace("</head>", `${r}</head>`);
128
- }), t;
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
- l as defaultHtmlCompilerRules
180
+ d as defaultHtmlCompilerRules
153
181
  };