@useinsider/guido 3.7.0-beta.b2980d8 → 3.7.0-beta.d579d2a
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/extensions/Blocks/Recommendation/controls/main/index.js +10 -12
- package/dist/extensions/Blocks/Recommendation/controls/main/layoutOrientation.js +24 -33
- package/dist/extensions/Blocks/Recommendation/controls/main/productLayout.js +34 -40
- package/dist/extensions/Blocks/Recommendation/controls/main/utils.js +287 -330
- package/dist/extensions/Blocks/Recommendation/extension.js +6 -5
- package/dist/extensions/Blocks/Recommendation/settingsPanel.js +3 -2
- package/dist/extensions/Blocks/Recommendation/templates/grid/elementRenderer.js +142 -173
- package/dist/extensions/Blocks/Recommendation/templates/grid/template.js +56 -30
- package/dist/extensions/Blocks/Recommendation/templates/index.js +29 -8
- package/dist/extensions/Blocks/Recommendation/templates/list/elementRenderer.js +132 -105
- package/dist/extensions/Blocks/Recommendation/templates/list/template.js +44 -23
- package/dist/extensions/Blocks/Recommendation/templates/utils.js +96 -53
- package/dist/extensions/Blocks/Recommendation/utils/captureStyleTemplates.js +207 -0
- package/dist/extensions/Blocks/Recommendation/utils/preserveTextStyles.js +24 -19
- package/dist/extensions/Blocks/Recommendation/utils/tagName.js +20 -16
- package/dist/extensions/Blocks/Unsubscribe/block.js +72 -122
- package/dist/extensions/Blocks/Unsubscribe/template.js +4 -4
- package/dist/extensions/Blocks/controlFactories.js +159 -133
- package/dist/src/extensions/Blocks/Items/controls/index.d.ts +1 -1
- package/dist/src/extensions/Blocks/Recommendation/controls/button/index.d.ts +1 -1
- package/dist/src/extensions/Blocks/Recommendation/controls/main/utils.d.ts +20 -47
- package/dist/src/extensions/Blocks/Recommendation/templates/grid/template.d.ts +4 -4
- package/dist/src/extensions/Blocks/Recommendation/templates/index.d.ts +1 -1
- package/dist/src/extensions/Blocks/Recommendation/templates/list/template.d.ts +3 -2
- package/dist/src/extensions/Blocks/Recommendation/templates/utils.d.ts +158 -11
- package/dist/src/extensions/Blocks/Recommendation/utils/captureStyleTemplates.d.ts +85 -0
- package/dist/src/extensions/Blocks/Recommendation/utils/preserveTextStyles.d.ts +15 -0
- package/dist/src/extensions/Blocks/Recommendation/utils/tagName.d.ts +20 -9
- package/dist/src/extensions/Blocks/Unsubscribe/block.d.ts +0 -9
- package/dist/src/extensions/Blocks/controlFactories.d.ts +11 -1
- package/package.json +1 -1
- package/dist/src/extensions/Blocks/Recommendation/utils/stylePreserver.d.ts +0 -113
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import { RecommendationBlockId as u } from "../constants/blockIds.js";
|
|
2
|
+
import { DESKTOP_CONTAINER_SELECTOR as b, ATTR_PRODUCT_NAME as O, ATTR_PRODUCT_PRICE as k, ATTR_PRODUCT_OLD_PRICE as E, ATTR_PRODUCT_OMNIBUS_PRICE as y, ATTR_PRODUCT_OMNIBUS_DISCOUNT as p, ATTR_PRODUCT_BUTTON as P, ATTR_PRODUCT_IMAGE as h } from "../constants/selectors.js";
|
|
3
|
+
import { CSS_CLASS_TEXT_TRIM as x } from "../controls/shared/textTrimCssRules.js";
|
|
4
|
+
import { extractWrapperTags as m } from "./preserveTextStyles.js";
|
|
5
|
+
import { hasGetAttribute as l, hasGetStyle as C, hasGetComputedStyle as v } from "./tagName.js";
|
|
6
|
+
const c = [
|
|
7
|
+
"font-size",
|
|
8
|
+
"font-family",
|
|
9
|
+
"font-weight",
|
|
10
|
+
"font-style",
|
|
11
|
+
"color",
|
|
12
|
+
"text-align",
|
|
13
|
+
"line-height",
|
|
14
|
+
"text-decoration"
|
|
15
|
+
], q = [
|
|
16
|
+
"background",
|
|
17
|
+
"background-color",
|
|
18
|
+
"border-width",
|
|
19
|
+
"border-color",
|
|
20
|
+
"border-style",
|
|
21
|
+
"border-radius"
|
|
22
|
+
], B = [
|
|
23
|
+
...c,
|
|
24
|
+
"background",
|
|
25
|
+
"background-color",
|
|
26
|
+
"padding",
|
|
27
|
+
"width",
|
|
28
|
+
"mso-border-alt",
|
|
29
|
+
"mso-padding-alt"
|
|
30
|
+
], N = [
|
|
31
|
+
"display",
|
|
32
|
+
"width",
|
|
33
|
+
"height",
|
|
34
|
+
"max-width",
|
|
35
|
+
"border-radius",
|
|
36
|
+
"margin"
|
|
37
|
+
], T = /* @__PURE__ */ new Set(["transparent", "rgba(0, 0, 0, 0)"]), U = [
|
|
38
|
+
{ attrKey: O, blockId: u.NAME, kind: "text" },
|
|
39
|
+
{ attrKey: k, blockId: u.PRICE, kind: "text" },
|
|
40
|
+
{ attrKey: E, blockId: u.OLD_PRICE, kind: "text" },
|
|
41
|
+
{ attrKey: y, blockId: u.OMNIBUS_PRICE, kind: "text" },
|
|
42
|
+
{ attrKey: p, blockId: u.OMNIBUS_DISCOUNT, kind: "text" },
|
|
43
|
+
{ attrKey: P, blockId: u.BUTTON, kind: "button" },
|
|
44
|
+
{ attrKey: h, blockId: u.IMAGE, kind: "image" }
|
|
45
|
+
];
|
|
46
|
+
function A(t) {
|
|
47
|
+
return t && "getInnerHTML" in t && typeof t.getInnerHTML == "function" ? t.getInnerHTML().trim() : "";
|
|
48
|
+
}
|
|
49
|
+
function M(t) {
|
|
50
|
+
return t && "getInnerText" in t && typeof t.getInnerText == "function" ? t.getInnerText().trim() : "";
|
|
51
|
+
}
|
|
52
|
+
function s(t, e, r) {
|
|
53
|
+
!e || !C(e) || r.forEach((n) => {
|
|
54
|
+
const o = e.getStyle(n);
|
|
55
|
+
o && o !== "inherit" && o !== "initial" && (t[n] = o);
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
function R(t) {
|
|
59
|
+
return Object.entries(t).map(([e, r]) => `${e}: ${r};`).join(" ");
|
|
60
|
+
}
|
|
61
|
+
function _(t) {
|
|
62
|
+
if (!t || !C(t))
|
|
63
|
+
return;
|
|
64
|
+
const e = t.getStyle("background-color") || t.getStyle("background");
|
|
65
|
+
return e && !T.has(e) ? e : void 0;
|
|
66
|
+
}
|
|
67
|
+
function g(t, e) {
|
|
68
|
+
const r = {};
|
|
69
|
+
return s(r, t, e), R(r);
|
|
70
|
+
}
|
|
71
|
+
function D(t) {
|
|
72
|
+
const e = t.querySelector("p"), r = {};
|
|
73
|
+
s(r, t, c), s(r, e, c), s(r, t.querySelector("strong"), c), s(r, t.querySelector("em"), c), s(r, t.querySelector("s"), c);
|
|
74
|
+
const n = R(r), { openTags: o, closeTags: i } = m(A(e));
|
|
75
|
+
return !n && !o ? null : { pStyle: n || void 0, openTags: o, closeTags: i };
|
|
76
|
+
}
|
|
77
|
+
function G(t) {
|
|
78
|
+
const e = t.querySelector(".es-button-border"), r = t.querySelector("a.es-button") ?? t.querySelector("a"), n = g(e, q), o = g(r, B), i = e && "getAttribute" in e ? e.getAttribute("class") ?? "" : "", a = /\bes-fw\b/.test(i), { openTags: d, closeTags: I } = m(A(r)), S = M(r);
|
|
79
|
+
return !n && !o && !a && !d && !S ? null : {
|
|
80
|
+
buttonBorderStyle: n || void 0,
|
|
81
|
+
buttonAnchorStyle: o || void 0,
|
|
82
|
+
buttonFitToContainer: a || void 0,
|
|
83
|
+
buttonText: S || void 0,
|
|
84
|
+
openTags: d,
|
|
85
|
+
closeTags: I
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
function L(t) {
|
|
89
|
+
const e = g(t.querySelector("img"), N);
|
|
90
|
+
return e ? { imgStyle: e } : null;
|
|
91
|
+
}
|
|
92
|
+
function w(t, e) {
|
|
93
|
+
return e === "button" ? G(t) : e === "image" ? L(t) : D(t);
|
|
94
|
+
}
|
|
95
|
+
function f(t, e) {
|
|
96
|
+
if (!t || !("querySelector" in t))
|
|
97
|
+
return;
|
|
98
|
+
const r = t.querySelector(b) ?? t;
|
|
99
|
+
U.forEach(({ attrKey: n, blockId: o, kind: i }) => {
|
|
100
|
+
const a = r.querySelector(`[esd-extension-block-id="${o}"]`);
|
|
101
|
+
a && e(a, n, i);
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
function K(t) {
|
|
105
|
+
const e = {};
|
|
106
|
+
return f(t, (r, n, o) => {
|
|
107
|
+
if (!("querySelector" in r))
|
|
108
|
+
return;
|
|
109
|
+
const i = w(r, o);
|
|
110
|
+
i && (e[n] = i);
|
|
111
|
+
}), e;
|
|
112
|
+
}
|
|
113
|
+
function H(t) {
|
|
114
|
+
if (!t || !("querySelector" in t))
|
|
115
|
+
return;
|
|
116
|
+
const e = t.querySelector(b) ?? t, r = e.querySelector(".product-card-segment") ?? e.querySelector(".product-card-wrapper");
|
|
117
|
+
return _(r);
|
|
118
|
+
}
|
|
119
|
+
function F(t) {
|
|
120
|
+
if (!t)
|
|
121
|
+
return;
|
|
122
|
+
const e = l(t) ? t.getAttribute("bgcolor") : null;
|
|
123
|
+
if (e && !T.has(e))
|
|
124
|
+
return e;
|
|
125
|
+
const r = _(t);
|
|
126
|
+
if (r)
|
|
127
|
+
return r;
|
|
128
|
+
const n = v(t) ? t.getComputedStyle("background-color") : void 0;
|
|
129
|
+
return n && !T.has(n) ? n : void 0;
|
|
130
|
+
}
|
|
131
|
+
function $(t) {
|
|
132
|
+
const e = {};
|
|
133
|
+
return f(t, (r, n, o) => {
|
|
134
|
+
if (o !== "text")
|
|
135
|
+
return;
|
|
136
|
+
const i = F(r);
|
|
137
|
+
i && (e[n] = i);
|
|
138
|
+
}), e;
|
|
139
|
+
}
|
|
140
|
+
function j(t) {
|
|
141
|
+
const e = {};
|
|
142
|
+
return f(t, (r, n, o) => {
|
|
143
|
+
if (o === "image")
|
|
144
|
+
return;
|
|
145
|
+
const i = l(r) ? r.getAttribute("align") : null;
|
|
146
|
+
i && (e[n] = i);
|
|
147
|
+
}), e;
|
|
148
|
+
}
|
|
149
|
+
const X = /^es-[pm]\d+[trbl]?$/;
|
|
150
|
+
function z(t) {
|
|
151
|
+
const e = l(t) ? t.getAttribute("class") : null;
|
|
152
|
+
if (!e)
|
|
153
|
+
return;
|
|
154
|
+
const r = e.split(/\s+/).filter((n) => X.test(n) || n === x);
|
|
155
|
+
return r.length ? r.join(" ") : void 0;
|
|
156
|
+
}
|
|
157
|
+
function V(t) {
|
|
158
|
+
const e = {};
|
|
159
|
+
return f(t, (r, n, o) => {
|
|
160
|
+
if (o === "image")
|
|
161
|
+
return;
|
|
162
|
+
const i = z(r);
|
|
163
|
+
i && (e[n] = i);
|
|
164
|
+
}), e;
|
|
165
|
+
}
|
|
166
|
+
function W(t) {
|
|
167
|
+
const e = {};
|
|
168
|
+
return f(t, (r, n) => {
|
|
169
|
+
if (n !== y && n !== p || !l(r))
|
|
170
|
+
return;
|
|
171
|
+
const o = r.getAttribute("data-text-before"), i = r.getAttribute("data-text-after");
|
|
172
|
+
(o != null || i != null) && (e[n] = { before: o ?? void 0, after: i ?? void 0 });
|
|
173
|
+
}), e;
|
|
174
|
+
}
|
|
175
|
+
function Y(t) {
|
|
176
|
+
const e = {};
|
|
177
|
+
if (!t || !("querySelector" in t))
|
|
178
|
+
return e;
|
|
179
|
+
const r = t.querySelector(b) ?? t;
|
|
180
|
+
return !("querySelectorAll" in r) || typeof r.querySelectorAll != "function" || r.querySelectorAll(".recommendation-attribute-row").forEach((n) => {
|
|
181
|
+
if (!l(n))
|
|
182
|
+
return;
|
|
183
|
+
const o = n.getAttribute("data-attribute-type"), i = n.getAttribute("data-visibility");
|
|
184
|
+
o && i != null && (e[o] = i !== "0");
|
|
185
|
+
}), e;
|
|
186
|
+
}
|
|
187
|
+
function rt(t) {
|
|
188
|
+
return {
|
|
189
|
+
styleTemplates: K(t),
|
|
190
|
+
cardBackgroundColor: H(t),
|
|
191
|
+
cellBackgroundColors: $(t),
|
|
192
|
+
cellAlignments: j(t),
|
|
193
|
+
cellClasses: V(t),
|
|
194
|
+
omnibusTexts: W(t),
|
|
195
|
+
visibility: Y(t)
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
export {
|
|
199
|
+
K as captureAttributeStyleTemplates,
|
|
200
|
+
H as captureCardBackgroundColor,
|
|
201
|
+
j as captureCellAlignments,
|
|
202
|
+
$ as captureCellBackgroundColors,
|
|
203
|
+
V as captureCellClasses,
|
|
204
|
+
W as captureOmnibusTexts,
|
|
205
|
+
rt as captureStyles,
|
|
206
|
+
Y as captureVisibility
|
|
207
|
+
};
|
|
@@ -1,27 +1,32 @@
|
|
|
1
|
-
import { escapeHtml as
|
|
2
|
-
function
|
|
3
|
-
return "getInnerHTML" in
|
|
1
|
+
import { escapeHtml as g } from "../../../../utils/htmlEscape.js";
|
|
2
|
+
function u(n) {
|
|
3
|
+
return "getInnerHTML" in n && typeof n.getInnerHTML == "function" ? n.getInnerHTML().trim() : "innerHTML" in n ? n.innerHTML : "";
|
|
4
4
|
}
|
|
5
|
-
function
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
return n;
|
|
9
|
-
const r = T(t);
|
|
10
|
-
if (!r || r.trim() === "" || !/<(strong|em|u|s|b|i)\b/i.test(r))
|
|
11
|
-
return n;
|
|
12
|
-
const e = [], s = [];
|
|
13
|
-
let o = r.trim();
|
|
5
|
+
function T(n) {
|
|
6
|
+
const s = [], t = [];
|
|
7
|
+
let r = n.trim();
|
|
14
8
|
for (; ; ) {
|
|
15
|
-
const
|
|
16
|
-
if (!
|
|
9
|
+
const e = r.match(/^<(strong|em|u|s|b|i)(\s[^>]*)?>(.*)$/is);
|
|
10
|
+
if (!e)
|
|
17
11
|
break;
|
|
18
|
-
const [, i, a = "",
|
|
19
|
-
if (!
|
|
12
|
+
const [, i, a = "", o] = e, c = new RegExp(`</${i}>$`, "i");
|
|
13
|
+
if (!c.test(o))
|
|
20
14
|
break;
|
|
21
|
-
|
|
15
|
+
s.push(`<${i}${a}>`), t.unshift(`</${i}>`), r = o.replace(c, "").trim();
|
|
22
16
|
}
|
|
23
|
-
return
|
|
17
|
+
return { openTags: s.join(""), closeTags: t.join("") };
|
|
18
|
+
}
|
|
19
|
+
function p(n, s) {
|
|
20
|
+
const t = g(s);
|
|
21
|
+
if (!n)
|
|
22
|
+
return t;
|
|
23
|
+
const r = u(n);
|
|
24
|
+
if (!r || r.trim() === "")
|
|
25
|
+
return t;
|
|
26
|
+
const { openTags: e, closeTags: i } = T(r);
|
|
27
|
+
return e ? e + t + i : t;
|
|
24
28
|
}
|
|
25
29
|
export {
|
|
26
|
-
|
|
30
|
+
T as extractWrapperTags,
|
|
31
|
+
p as preserveTextStyles
|
|
27
32
|
};
|
|
@@ -1,26 +1,29 @@
|
|
|
1
|
-
function
|
|
1
|
+
function n(t) {
|
|
2
2
|
return typeof t == "object" && t !== null && "tagName" in t && typeof t.tagName == "string";
|
|
3
3
|
}
|
|
4
|
-
function
|
|
4
|
+
function r(t) {
|
|
5
5
|
return typeof t == "object" && t !== null && "getTagName" in t && typeof t.getTagName == "function";
|
|
6
6
|
}
|
|
7
|
-
function
|
|
7
|
+
function u(t) {
|
|
8
8
|
return typeof t == "object" && t !== null && "getStyle" in t && typeof t.getStyle == "function";
|
|
9
9
|
}
|
|
10
|
-
function
|
|
11
|
-
return typeof t == "object" && t !== null && "
|
|
10
|
+
function p(t) {
|
|
11
|
+
return typeof t == "object" && t !== null && "getComputedStyle" in t && typeof t.getComputedStyle == "function";
|
|
12
12
|
}
|
|
13
13
|
function g(t) {
|
|
14
|
-
return typeof t == "object" && t !== null && "
|
|
14
|
+
return typeof t == "object" && t !== null && "getAttribute" in t && typeof t.getAttribute == "function";
|
|
15
|
+
}
|
|
16
|
+
function a(t) {
|
|
17
|
+
return typeof t == "object" && t !== null && "parent" in t && typeof t.parent == "function";
|
|
15
18
|
}
|
|
16
|
-
function
|
|
17
|
-
return !t || !
|
|
19
|
+
function y(t, e) {
|
|
20
|
+
return !t || !u(t) ? null : t.getStyle(e);
|
|
18
21
|
}
|
|
19
|
-
function
|
|
20
|
-
return !t || !
|
|
22
|
+
function o(t) {
|
|
23
|
+
return !t || !a(t) ? null : t.parent() ?? null;
|
|
21
24
|
}
|
|
22
25
|
function l(t, e = "UNKNOWN") {
|
|
23
|
-
return t ?
|
|
26
|
+
return t ? n(t) ? t.tagName.toUpperCase() : r(t) ? t.getTagName().toUpperCase() : e : e;
|
|
24
27
|
}
|
|
25
28
|
const f = /* @__PURE__ */ new Set(["TD", "BLOCK_IMAGE", "BLOCK_BUTTON"]);
|
|
26
29
|
function i(t) {
|
|
@@ -36,11 +39,12 @@ function s(t) {
|
|
|
36
39
|
export {
|
|
37
40
|
s as getTableDisplayValue,
|
|
38
41
|
l as getTagName,
|
|
39
|
-
|
|
40
|
-
|
|
42
|
+
g as hasGetAttribute,
|
|
43
|
+
p as hasGetComputedStyle,
|
|
44
|
+
u as hasGetStyle,
|
|
45
|
+
a as hasParent,
|
|
41
46
|
c as isTableCellNode,
|
|
42
47
|
i as isTableCellTag,
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
p as safeGetStyle
|
|
48
|
+
o as safeGetParent,
|
|
49
|
+
y as safeGetStyle
|
|
46
50
|
};
|
|
@@ -1,41 +1,39 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
import { useToaster as
|
|
5
|
-
import { ToasterTypeOptions as
|
|
6
|
-
import { PAGE_TYPES as
|
|
7
|
-
import { useUnsubscribeStore as
|
|
8
|
-
import { Block as
|
|
9
|
-
import { getDefaultTemplate as
|
|
10
|
-
import { DATA_ATTRIBUTES as
|
|
11
|
-
import { parsePageList as
|
|
12
|
-
const
|
|
13
|
-
[
|
|
14
|
-
[
|
|
15
|
-
}
|
|
16
|
-
class
|
|
1
|
+
var g = Object.defineProperty;
|
|
2
|
+
var k = (c, n, e) => n in c ? g(c, n, { enumerable: !0, configurable: !0, writable: !0, value: e }) : c[n] = e;
|
|
3
|
+
var l = (c, n, e) => k(c, typeof n != "symbol" ? n + "" : n, e);
|
|
4
|
+
import { useToaster as B } from "../../../composables/useToaster.js";
|
|
5
|
+
import { ToasterTypeOptions as S } from "../../../enums/toaster.js";
|
|
6
|
+
import { PAGE_TYPES as E } from "../../../enums/unsubscribe.js";
|
|
7
|
+
import { useUnsubscribeStore as a } from "../../../stores/unsubscribe.js";
|
|
8
|
+
import { Block as L, BlockCompositionType as f, ContextActionType as h, ModificationDescription as b, BlockType as v } from "../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
|
|
9
|
+
import { getDefaultTemplate as A } from "./template.js";
|
|
10
|
+
import { DATA_ATTRIBUTES as i, UNSUBSCRIBE_EVENTS as d } from "./utils/constants.js";
|
|
11
|
+
import { parsePageList as p } from "./utils/utils.js";
|
|
12
|
+
const y = "unsubscribe-block", m = 'a[data-unsubscribe-link="true"]', _ = ".unsubscribe-block-v2", I = "{{ins-unsubscribe-link}}", T = "https://academy.insiderone.com/docs/adding-unsubscribe-pages-into-emails", C = "Removing the unsubscribe text leaves an empty block, but an active unsubscribe link is required. Undo your last action to restore the text, or delete the unsubscribe block entirely.", N = {
|
|
13
|
+
[E.GLOBAL_UNSUBSCRIBE]: "{{ins-global-unsubscribe-link}}",
|
|
14
|
+
[E.SUBSCRIPTION_PREFERENCE_CENTER]: "{{ins-preferences-unsubscribe-link}}"
|
|
15
|
+
};
|
|
16
|
+
class F extends L {
|
|
17
17
|
constructor() {
|
|
18
18
|
super();
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
l(this, "selectEventListener", null);
|
|
20
|
+
l(this, "cancelEventListener", null);
|
|
21
|
+
l(this, "currentNode");
|
|
22
22
|
// Per-block "did this instance have a link last time we saw it?" tracking.
|
|
23
23
|
// Keyed by the stable `data-unsubscribe-block-id` we assign, because
|
|
24
24
|
// ImmutableHtmlNode instances are recreated on every document mutation and
|
|
25
25
|
// can't be used as Map keys directly. A singleton boolean here would be
|
|
26
26
|
// polluted across blocks since Stripo fires onDocumentChanged per-instance.
|
|
27
|
-
|
|
28
|
-
// Per-block prepend retry counter for the leading text guard (SD-143097).
|
|
29
|
-
a(this, "guardAttemptsByBlockId", /* @__PURE__ */ new Map());
|
|
27
|
+
l(this, "linkStateByBlockId", /* @__PURE__ */ new Map());
|
|
30
28
|
}
|
|
31
29
|
getId() {
|
|
32
|
-
return
|
|
30
|
+
return y;
|
|
33
31
|
}
|
|
34
32
|
getIcon() {
|
|
35
33
|
return "unsubscribe-icon";
|
|
36
34
|
}
|
|
37
35
|
getBlockCompositionType() {
|
|
38
|
-
return
|
|
36
|
+
return f.BLOCK;
|
|
39
37
|
}
|
|
40
38
|
getName() {
|
|
41
39
|
return this.api.translate("Unsubscribe Block");
|
|
@@ -44,84 +42,36 @@ class H extends y {
|
|
|
44
42
|
return this.api.translate("Unsubscribe Block Description");
|
|
45
43
|
}
|
|
46
44
|
getTemplate() {
|
|
47
|
-
return
|
|
45
|
+
return A();
|
|
48
46
|
}
|
|
49
47
|
getContextActionsIds() {
|
|
50
|
-
return [
|
|
48
|
+
return [h.MOVE, h.REMOVE];
|
|
51
49
|
}
|
|
52
50
|
onSelect(e) {
|
|
53
51
|
this.currentNode = e;
|
|
54
52
|
const t = this._getOrAssignBlockId(e);
|
|
55
53
|
t && this.linkStateByBlockId.set(t, this._hasUnsubscribeLink(e)), !("getAttribute" in e && e.getAttribute("data-migration")) && (this._resetStoreState(), this._loadBlockState(e), this._setupSelectEventListener(), this._setupCancelEventListener(), this._checkExistingBlocks(), this._openDrawer());
|
|
56
54
|
}
|
|
57
|
-
onCreated(e) {
|
|
58
|
-
this._ensureLeadingTextGuard(e);
|
|
59
|
-
}
|
|
60
|
-
onDocumentInit() {
|
|
61
|
-
try {
|
|
62
|
-
const e = this.api.getDocumentRoot();
|
|
63
|
-
e && "querySelectorAll" in e && e.querySelectorAll(E).forEach((t) => {
|
|
64
|
-
this._ensureLeadingTextGuard(t);
|
|
65
|
-
});
|
|
66
|
-
} catch {
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
55
|
onDocumentChanged(e) {
|
|
70
|
-
this._ensureLeadingTextGuard(e);
|
|
71
56
|
const t = this._getOrAssignBlockId(e);
|
|
72
57
|
if (!t)
|
|
73
58
|
return;
|
|
74
|
-
const
|
|
75
|
-
this.linkStateByBlockId.get(t) === !0 && !
|
|
59
|
+
const r = this._hasUnsubscribeLink(e);
|
|
60
|
+
this.linkStateByBlockId.get(t) === !0 && !r && this._warnLinkRemoved(), this.linkStateByBlockId.set(t, r);
|
|
76
61
|
}
|
|
77
62
|
onDelete(e) {
|
|
78
63
|
this._removeEventListeners(), this._removeBlockTemplatesFromStore(e), this._resetStoreState();
|
|
79
64
|
const t = this._readBlockId(e);
|
|
80
|
-
t &&
|
|
65
|
+
t && this.linkStateByBlockId.delete(t);
|
|
81
66
|
}
|
|
82
67
|
onDestroy() {
|
|
83
|
-
this._removeEventListeners(), this.currentNode = void 0, this.linkStateByBlockId.clear()
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* Guarantees a plain-text node before the link's wrapper inside the <p>.
|
|
87
|
-
* Without it the only caret position left of the link is inside the anchor,
|
|
88
|
-
* so anything typed there becomes part of the link (SD-143097).
|
|
89
|
-
*/
|
|
90
|
-
_ensureLeadingTextGuard(e) {
|
|
91
|
-
if (!("querySelector" in e))
|
|
92
|
-
return;
|
|
93
|
-
const t = e.querySelector(m);
|
|
94
|
-
if (!t)
|
|
95
|
-
return;
|
|
96
|
-
let s = t, r = s.parent();
|
|
97
|
-
for (; r && "getTagName" in r && r.getTagName().toLowerCase() !== "p"; )
|
|
98
|
-
s = r, r = r.parent();
|
|
99
|
-
if (!r || !("getTagName" in r) || r.getTagName().toLowerCase() !== "p")
|
|
100
|
-
return;
|
|
101
|
-
const i = s.previousSibling();
|
|
102
|
-
if (!!(i && i.getType() === "text" && i.getTextContent())) {
|
|
103
|
-
const b = this._readBlockId(e);
|
|
104
|
-
b && this.guardAttemptsByBlockId.delete(b);
|
|
105
|
-
return;
|
|
106
|
-
}
|
|
107
|
-
const g = this._getOrAssignBlockId(e);
|
|
108
|
-
if (!g)
|
|
109
|
-
return;
|
|
110
|
-
const _ = this.guardAttemptsByBlockId.get(g) ?? 0;
|
|
111
|
-
if (!(_ >= w)) {
|
|
112
|
-
this.guardAttemptsByBlockId.set(g, _ + 1);
|
|
113
|
-
try {
|
|
114
|
-
this.api.getDocumentModifier().modifyHtml(r).prepend(" ").apply(new d("Ensure unsubscribe link text guard"));
|
|
115
|
-
} catch (b) {
|
|
116
|
-
console.warn("[UnsubscribeBlock] Failed to ensure link text guard:", b);
|
|
117
|
-
}
|
|
118
|
-
}
|
|
68
|
+
this._removeEventListeners(), this.currentNode = void 0, this.linkStateByBlockId.clear();
|
|
119
69
|
}
|
|
120
70
|
_hasUnsubscribeLink(e) {
|
|
121
71
|
return "querySelector" in e ? !!e.querySelector(m) : !1;
|
|
122
72
|
}
|
|
123
73
|
_readBlockId(e) {
|
|
124
|
-
return "getAttribute" in e ? e.getAttribute(
|
|
74
|
+
return "getAttribute" in e ? e.getAttribute(i.BLOCK_ID) : null;
|
|
125
75
|
}
|
|
126
76
|
/**
|
|
127
77
|
* Returns the block's stable id, assigning one via the document modifier if
|
|
@@ -135,13 +85,13 @@ class H extends y {
|
|
|
135
85
|
return t;
|
|
136
86
|
if (!("getAttribute" in e))
|
|
137
87
|
return null;
|
|
138
|
-
const
|
|
88
|
+
const r = this._generateNextBlockId();
|
|
139
89
|
try {
|
|
140
|
-
this.api.getDocumentModifier().modifyHtml(e).setAttribute(
|
|
141
|
-
} catch (
|
|
142
|
-
return console.warn("[UnsubscribeBlock] Failed to assign block id:",
|
|
90
|
+
this.api.getDocumentModifier().modifyHtml(e).setAttribute(i.BLOCK_ID, r).apply(new b(`Assign unsubscribe block id ${r}`));
|
|
91
|
+
} catch (s) {
|
|
92
|
+
return console.warn("[UnsubscribeBlock] Failed to assign block id:", s), null;
|
|
143
93
|
}
|
|
144
|
-
return
|
|
94
|
+
return r;
|
|
145
95
|
}
|
|
146
96
|
/**
|
|
147
97
|
* Generates a unique id by scanning the document for the highest existing
|
|
@@ -152,10 +102,10 @@ class H extends y {
|
|
|
152
102
|
let e = 0;
|
|
153
103
|
try {
|
|
154
104
|
const t = this.api.getDocumentRoot();
|
|
155
|
-
t && "querySelectorAll" in t && t.querySelectorAll(
|
|
156
|
-
if ("getAttribute" in
|
|
157
|
-
const
|
|
158
|
-
|
|
105
|
+
t && "querySelectorAll" in t && t.querySelectorAll(_).forEach((s) => {
|
|
106
|
+
if ("getAttribute" in s) {
|
|
107
|
+
const o = s.getAttribute(i.BLOCK_ID), u = o ? parseInt(o) : 0;
|
|
108
|
+
u > e && (e = u);
|
|
159
109
|
}
|
|
160
110
|
});
|
|
161
111
|
} catch {
|
|
@@ -164,14 +114,14 @@ class H extends y {
|
|
|
164
114
|
}
|
|
165
115
|
_warnLinkRemoved() {
|
|
166
116
|
try {
|
|
167
|
-
const { showToaster: e } =
|
|
117
|
+
const { showToaster: e } = B();
|
|
168
118
|
e({
|
|
169
|
-
type:
|
|
170
|
-
message: this.api.translate(
|
|
119
|
+
type: S.Warning,
|
|
120
|
+
message: this.api.translate(C),
|
|
171
121
|
actionButton: {
|
|
172
122
|
text: this.api.translate("Visit Academy"),
|
|
173
123
|
onClick: () => {
|
|
174
|
-
window.open(
|
|
124
|
+
window.open(T, "_blank", "noopener,noreferrer");
|
|
175
125
|
}
|
|
176
126
|
}
|
|
177
127
|
});
|
|
@@ -181,26 +131,26 @@ class H extends y {
|
|
|
181
131
|
}
|
|
182
132
|
_setupSelectEventListener() {
|
|
183
133
|
this._removeSelectEventListener(), this.selectEventListener = (e) => {
|
|
184
|
-
const t = e, { collectionType:
|
|
185
|
-
this._updateBlock(
|
|
186
|
-
}, document.addEventListener(
|
|
134
|
+
const t = e, { collectionType: r, selectedPages: s } = t.detail;
|
|
135
|
+
this._updateBlock(r, s.join(","));
|
|
136
|
+
}, document.addEventListener(d.SELECT, this.selectEventListener);
|
|
187
137
|
}
|
|
188
138
|
_removeSelectEventListener() {
|
|
189
|
-
this.selectEventListener && (document.removeEventListener(
|
|
139
|
+
this.selectEventListener && (document.removeEventListener(d.SELECT, this.selectEventListener), this.selectEventListener = null);
|
|
190
140
|
}
|
|
191
141
|
_setupCancelEventListener() {
|
|
192
142
|
this._removeCancelEventListener(), this.cancelEventListener = () => {
|
|
193
143
|
this._handleCancel();
|
|
194
|
-
}, document.addEventListener(
|
|
144
|
+
}, document.addEventListener(d.CANCEL, this.cancelEventListener);
|
|
195
145
|
}
|
|
196
146
|
_removeCancelEventListener() {
|
|
197
|
-
this.cancelEventListener && (document.removeEventListener(
|
|
147
|
+
this.cancelEventListener && (document.removeEventListener(d.CANCEL, this.cancelEventListener), this.cancelEventListener = null);
|
|
198
148
|
}
|
|
199
149
|
_handleCancel() {
|
|
200
150
|
try {
|
|
201
151
|
if (!this.currentNode)
|
|
202
152
|
return;
|
|
203
|
-
this.api.getDocumentModifier().modifyHtml(this.currentNode).replaceWith(`<${
|
|
153
|
+
this.api.getDocumentModifier().modifyHtml(this.currentNode).replaceWith(`<${v.EMPTY_CONTAINER}/>`).apply(new b("Removed unsubscribe block due to cancel"));
|
|
204
154
|
} catch (e) {
|
|
205
155
|
console.warn("[UnsubscribeBlock] Failed to remove unsubscribe block:", e);
|
|
206
156
|
}
|
|
@@ -211,32 +161,32 @@ class H extends y {
|
|
|
211
161
|
_updateBlock(e, t) {
|
|
212
162
|
if (!this.currentNode || !("querySelector" in this.currentNode))
|
|
213
163
|
return;
|
|
214
|
-
const
|
|
215
|
-
if (!
|
|
164
|
+
const r = this.currentNode.querySelector(m);
|
|
165
|
+
if (!r)
|
|
216
166
|
return;
|
|
217
|
-
const
|
|
218
|
-
this.api.getDocumentModifier().modifyHtml(
|
|
167
|
+
const s = this._getMergeTag(e);
|
|
168
|
+
this.api.getDocumentModifier().modifyHtml(r).setAttribute("href", s).apply(new b(`Updated unsubscribe link to ${s}`)), this.api.getDocumentModifier().modifyHtml(this.currentNode).setAttribute(i.PAGE_TYPE, e.toString()).setAttribute(i.PAGE_LIST, t).apply(new b("Updated unsubscribe block metadata"));
|
|
219
169
|
}
|
|
220
170
|
_getMergeTag(e) {
|
|
221
|
-
return
|
|
171
|
+
return N[e] ?? I;
|
|
222
172
|
}
|
|
223
173
|
_openDrawer() {
|
|
224
174
|
if (!(this.currentNode && this.currentNode.getAttribute("data-unsubscribe-page-type")))
|
|
225
175
|
try {
|
|
226
|
-
const e =
|
|
176
|
+
const e = a();
|
|
227
177
|
e.typeSelectionDrawerStatus = !0;
|
|
228
178
|
} catch (e) {
|
|
229
179
|
console.error("[UnsubscribeBlock] Failed to open drawer:", e);
|
|
230
180
|
}
|
|
231
181
|
}
|
|
232
182
|
_checkExistingBlocks() {
|
|
233
|
-
const e =
|
|
234
|
-
e.isGlobalUnsubscribeDisabled = !1, e.isSubscriptionPreferencesCenterDisabled = !1, this.api.getDocumentRoot().querySelectorAll(
|
|
235
|
-
if ("getAttribute" in
|
|
236
|
-
const
|
|
237
|
-
if (
|
|
238
|
-
const
|
|
239
|
-
|
|
183
|
+
const e = a();
|
|
184
|
+
e.isGlobalUnsubscribeDisabled = !1, e.isSubscriptionPreferencesCenterDisabled = !1, this.api.getDocumentRoot().querySelectorAll(_).forEach((r) => {
|
|
185
|
+
if ("getAttribute" in r) {
|
|
186
|
+
const s = r.getAttribute(i.PAGE_TYPE);
|
|
187
|
+
if (s) {
|
|
188
|
+
const o = Number(s);
|
|
189
|
+
o === E.GLOBAL_UNSUBSCRIBE ? e.isGlobalUnsubscribeDisabled = !0 : o === E.SUBSCRIPTION_PREFERENCE_CENTER && (e.isSubscriptionPreferencesCenterDisabled = !0);
|
|
240
190
|
}
|
|
241
191
|
}
|
|
242
192
|
});
|
|
@@ -244,26 +194,26 @@ class H extends y {
|
|
|
244
194
|
async _loadBlockState(e) {
|
|
245
195
|
if (!("getAttribute" in e))
|
|
246
196
|
return;
|
|
247
|
-
const t = e.getAttribute(
|
|
248
|
-
if (!t || !
|
|
197
|
+
const t = e.getAttribute(i.PAGE_TYPE), r = e.getAttribute(i.PAGE_LIST);
|
|
198
|
+
if (!t || !r)
|
|
249
199
|
return;
|
|
250
|
-
const
|
|
251
|
-
await
|
|
200
|
+
const s = a(), o = Number(t), u = p(r);
|
|
201
|
+
await s.fetchTemplates(), s.setCollectionWithoutAutoSelection(o), s.loadSelectedTemplates(u);
|
|
252
202
|
}
|
|
253
203
|
_resetStoreState() {
|
|
254
|
-
|
|
204
|
+
a().$reset();
|
|
255
205
|
}
|
|
256
206
|
_removeBlockTemplatesFromStore(e) {
|
|
257
207
|
if (!("getAttribute" in e))
|
|
258
208
|
return;
|
|
259
|
-
const t = e.getAttribute(
|
|
209
|
+
const t = e.getAttribute(i.PAGE_LIST);
|
|
260
210
|
if (!t)
|
|
261
211
|
return;
|
|
262
|
-
const
|
|
263
|
-
|
|
212
|
+
const r = a(), s = p(t);
|
|
213
|
+
r.removeUnsubscribePages(s);
|
|
264
214
|
}
|
|
265
215
|
}
|
|
266
216
|
export {
|
|
267
|
-
|
|
268
|
-
|
|
217
|
+
y as UNSUBSCRIBE_BLOCK_ID,
|
|
218
|
+
F as UnsubscribeBlock
|
|
269
219
|
};
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
import { BlockType as s } from "../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
|
|
2
|
-
const e = "unsubscribe", n = "{{ins-unsubscribe-link}}",
|
|
2
|
+
const e = "unsubscribe", n = "{{ins-unsubscribe-link}}", t = `
|
|
3
3
|
<${s.BLOCK_TEXT}
|
|
4
4
|
class="unsubscribe-block-v2 esd-block-unsubscribe es-p0"
|
|
5
5
|
align="center"
|
|
6
6
|
data-unsubscribe-page-type=""
|
|
7
7
|
data-unsubscribe-page-list=""
|
|
8
8
|
>
|
|
9
|
-
<p> <a
|
|
9
|
+
<p> <strong><a
|
|
10
10
|
href="${n}"
|
|
11
11
|
class="unsubscribe-link"
|
|
12
12
|
target="_blank"
|
|
13
13
|
data-unsubscribe-link="true"
|
|
14
|
-
>${e}</a></p>
|
|
14
|
+
>${e}</a></strong></p>
|
|
15
15
|
</${s.BLOCK_TEXT}>
|
|
16
16
|
`;
|
|
17
17
|
function u() {
|
|
18
|
-
return
|
|
18
|
+
return t;
|
|
19
19
|
}
|
|
20
20
|
export {
|
|
21
21
|
u as getDefaultTemplate
|