@useinsider/guido 3.7.1-beta.4622f87 → 3.7.1-beta.794b3fc
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/unsubscribe/UnsubscribePageSelection.vue.js +2 -2
- package/dist/components/organisms/unsubscribe/UnsubscribePageSelection.vue2.js +24 -22
- package/dist/composables/useHtmlValidator.js +79 -73
- package/dist/enums/extensions/recommendationBlock.js +3 -1
- package/dist/enums/html-validator.js +13 -5
- package/dist/enums/toaster.js +1 -1
- package/dist/extensions/Blocks/Recommendation/block.js +35 -16
- package/dist/extensions/Blocks/Recommendation/controls/main/index.js +35 -30
- package/dist/extensions/Blocks/Recommendation/controls/main/productLayout.js +62 -50
- package/dist/extensions/Blocks/Recommendation/controls/main/utils.js +208 -193
- package/dist/extensions/Blocks/Recommendation/store/recommendation.js +21 -20
- package/dist/extensions/Blocks/Recommendation/useRecommendationBlockWarning.js +16 -0
- package/dist/extensions/Blocks/Recommendation/utils/recommendationBlockCount.js +9 -0
- package/dist/extensions/Blocks/Unsubscribe/block.js +122 -72
- package/dist/extensions/Blocks/Unsubscribe/control.js +33 -26
- package/dist/extensions/Blocks/Unsubscribe/template.js +4 -4
- package/dist/guido.css +1 -1
- package/dist/services/recommendationApi.js +31 -19
- package/dist/src/enums/extensions/recommendationBlock.d.ts +1 -0
- package/dist/src/enums/html-validator.d.ts +4 -0
- package/dist/src/enums/toaster.d.ts +2 -1
- package/dist/src/extensions/Blocks/Recommendation/block.d.ts +13 -0
- package/dist/src/extensions/Blocks/Recommendation/block.test.d.ts +1 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +1 -0
- package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +1 -0
- package/dist/src/extensions/Blocks/Recommendation/useRecommendationBlockWarning.d.ts +12 -0
- package/dist/src/extensions/Blocks/Recommendation/utils/recommendationBlockCount.d.ts +28 -0
- package/dist/src/extensions/Blocks/Recommendation/utils/recommendationBlockCount.test.d.ts +1 -0
- package/dist/src/extensions/Blocks/Unsubscribe/block.d.ts +9 -0
- package/dist/src/extensions/Blocks/Unsubscribe/control.d.ts +1 -0
- package/dist/static/styles/components/base-input.css.js +5 -0
- package/dist/stores/autosave.js +6 -6
- package/package.json +1 -1
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import { getRecommendationFeedSourceMaps as g, getOperatorOptions as R, PriceAttributes as C } from "../../../../enums/extensions/recommendationBlock.js";
|
|
2
2
|
import { useRecommendationApi as y } from "../../../../services/recommendationApi.js";
|
|
3
3
|
import { useConfigStore as G } from "../../../../stores/config.js";
|
|
4
|
-
import { defineStore as
|
|
5
|
-
import { DEFAULT_CARDS_IN_ROW as
|
|
6
|
-
import { EXCLUDED_ALGORITHM_IDS as
|
|
4
|
+
import { defineStore as F } from "pinia";
|
|
5
|
+
import { DEFAULT_MOBILE_CARDS_IN_ROW as P, DEFAULT_CARDS_IN_ROW as D } from "../constants/layout.js";
|
|
6
|
+
import { EXCLUDED_ALGORITHM_IDS as w } from "../constants/defaultConfig.js";
|
|
7
7
|
import { getDefaultProducts as S } from "../templates/utils.js";
|
|
8
8
|
import { generateCompleteFilterQuery as b } from "../utils/filterUtil.js";
|
|
9
9
|
import { getPartnerRecommendationParams as v } from "../utils/partnerCustomizations.js";
|
|
10
|
-
import { isFilterValid as
|
|
11
|
-
import { isConfigValid as
|
|
10
|
+
import { isFilterValid as N } from "../validation/filterSchema.js";
|
|
11
|
+
import { isConfigValid as x } from "../validation/requiredFields.js";
|
|
12
12
|
const h = y();
|
|
13
13
|
let m = null, u = null, d = null;
|
|
14
|
-
function
|
|
14
|
+
function k() {
|
|
15
15
|
return {
|
|
16
|
-
cardsInRow:
|
|
16
|
+
cardsInRow: D,
|
|
17
17
|
currencySettings: {
|
|
18
18
|
name: "USD",
|
|
19
19
|
value: "USD",
|
|
@@ -27,6 +27,7 @@ function I() {
|
|
|
27
27
|
productIds: [],
|
|
28
28
|
id: 1,
|
|
29
29
|
language: "en_US",
|
|
30
|
+
mobileCardsInRow: P,
|
|
30
31
|
mobileLayoutEnabled: !1,
|
|
31
32
|
orientation: "grid",
|
|
32
33
|
recommendedProducts: [],
|
|
@@ -39,9 +40,9 @@ function I() {
|
|
|
39
40
|
customAttributes: []
|
|
40
41
|
};
|
|
41
42
|
}
|
|
42
|
-
function
|
|
43
|
+
function I() {
|
|
43
44
|
return {
|
|
44
|
-
recommendationConfigs:
|
|
45
|
+
recommendationConfigs: k(),
|
|
45
46
|
recommendationProducts: [],
|
|
46
47
|
filterStatus: !1,
|
|
47
48
|
filterSelectionDrawerStatus: !1,
|
|
@@ -50,7 +51,7 @@ function k() {
|
|
|
50
51
|
filterSnapshot: null
|
|
51
52
|
};
|
|
52
53
|
}
|
|
53
|
-
const
|
|
54
|
+
const L = () => ({
|
|
54
55
|
recommendationCampaignUrls: {},
|
|
55
56
|
activePredictiveAlgorithms: [],
|
|
56
57
|
languages: {},
|
|
@@ -59,8 +60,8 @@ const x = () => ({
|
|
|
59
60
|
blockStates: {},
|
|
60
61
|
currentRecommendationId: null,
|
|
61
62
|
configVersion: 0
|
|
62
|
-
}),
|
|
63
|
-
state: () =>
|
|
63
|
+
}), K = F("guidoRecommendationExtension", {
|
|
64
|
+
state: () => L(),
|
|
64
65
|
getters: {
|
|
65
66
|
// ====================================================================
|
|
66
67
|
// Proxy Getters — Backward Compatible Access to Current Block State
|
|
@@ -70,7 +71,7 @@ const x = () => ({
|
|
|
70
71
|
* This allows all existing code that reads `store.recommendationConfigs` to work unchanged.
|
|
71
72
|
*/
|
|
72
73
|
recommendationConfigs(t) {
|
|
73
|
-
return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].recommendationConfigs :
|
|
74
|
+
return t.currentRecommendationId !== null && t.blockStates[t.currentRecommendationId] ? t.blockStates[t.currentRecommendationId].recommendationConfigs : k();
|
|
74
75
|
},
|
|
75
76
|
/**
|
|
76
77
|
* Proxy getter: delegates to blockStates[currentRecommendationId].recommendationProducts
|
|
@@ -116,7 +117,7 @@ const x = () => ({
|
|
|
116
117
|
},
|
|
117
118
|
getActivePredictiveAlgorithms: (t) => {
|
|
118
119
|
const e = g(), r = [];
|
|
119
|
-
return t.activePredictiveAlgorithms.filter((n) => !
|
|
120
|
+
return t.activePredictiveAlgorithms.filter((n) => !w.includes(n)).forEach((n) => {
|
|
120
121
|
r.push(...e.filter((c) => c.id === n));
|
|
121
122
|
}), r.map((n) => ({
|
|
122
123
|
text: n.name,
|
|
@@ -132,7 +133,7 @@ const x = () => ({
|
|
|
132
133
|
value: e.text
|
|
133
134
|
})),
|
|
134
135
|
getFilterList() {
|
|
135
|
-
return Object.values(this.filterList).map((t) => {
|
|
136
|
+
return Object.values(this.filterList).filter((t) => t.isFilterable !== 0 && t.isFilterable !== !1).map((t) => {
|
|
136
137
|
let e;
|
|
137
138
|
return t.type === "productAttribute" ? e = `product_attributes.${t.attributeName}` : C.includes(t.attributeName) ? e = `${t.attributeName}.${this.recommendationConfigs.currencySettings.value}` : e = t.attributeName, {
|
|
138
139
|
text: t.displayName,
|
|
@@ -156,7 +157,7 @@ const x = () => ({
|
|
|
156
157
|
setCurrentBlock(t) {
|
|
157
158
|
this.blockStates[t] || (this.blockStates = {
|
|
158
159
|
...this.blockStates,
|
|
159
|
-
[t]:
|
|
160
|
+
[t]: I()
|
|
160
161
|
}), this.currentRecommendationId = t;
|
|
161
162
|
},
|
|
162
163
|
/**
|
|
@@ -224,7 +225,7 @@ const x = () => ({
|
|
|
224
225
|
decimalCount: String(e.currencyDecimalCount),
|
|
225
226
|
decimalSeparator: r(e.currencyDecimalSeparator, ","),
|
|
226
227
|
thousandSeparator: r(e.currencyThousandSeparator, ".")
|
|
227
|
-
}, c = !this.blockStates[t], i = c ?
|
|
228
|
+
}, c = !this.blockStates[t], i = c ? I() : this.blockStates[t];
|
|
228
229
|
i.recommendationConfigs = {
|
|
229
230
|
...i.recommendationConfigs,
|
|
230
231
|
strategy: e.strategy,
|
|
@@ -379,7 +380,7 @@ const x = () => ({
|
|
|
379
380
|
const n = [...e.recommendationConfigs.filters];
|
|
380
381
|
n[r] = {
|
|
381
382
|
...t,
|
|
382
|
-
isValid:
|
|
383
|
+
isValid: N(t)
|
|
383
384
|
}, e.recommendationConfigs.filters = n;
|
|
384
385
|
}
|
|
385
386
|
},
|
|
@@ -425,7 +426,7 @@ const x = () => ({
|
|
|
425
426
|
* every block's recommendationConfigs across user edits.
|
|
426
427
|
*/
|
|
427
428
|
hasInvalidBlock() {
|
|
428
|
-
return Object.values(this.blockStates).some((t) => !
|
|
429
|
+
return Object.values(this.blockStates).some((t) => !x(t.recommendationConfigs, this));
|
|
429
430
|
},
|
|
430
431
|
// ====================================================================
|
|
431
432
|
// Per-Block Product Fetching
|
|
@@ -475,5 +476,5 @@ const x = () => ({
|
|
|
475
476
|
}
|
|
476
477
|
});
|
|
477
478
|
export {
|
|
478
|
-
|
|
479
|
+
K as useRecommendationExtensionStore
|
|
479
480
|
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { useToaster as r } from "../../../composables/useToaster.js";
|
|
2
|
+
import { useTranslations as s } from "../../../composables/useTranslations.js";
|
|
3
|
+
import { ToasterTypeOptions as n } from "../../../enums/toaster.js";
|
|
4
|
+
import { countLiveRecommendationBlocks as i } from "./utils/recommendationBlockCount.js";
|
|
5
|
+
const a = "newsletter.multiple-reco-blocks-warning", f = () => {
|
|
6
|
+
const { showToaster: o } = r(), t = s();
|
|
7
|
+
return { warnIfMultipleBlocks: (e) => {
|
|
8
|
+
i(e) > 1 && o({
|
|
9
|
+
type: n.Dark,
|
|
10
|
+
message: t(a)
|
|
11
|
+
});
|
|
12
|
+
} };
|
|
13
|
+
};
|
|
14
|
+
export {
|
|
15
|
+
f as useRecommendationBlockWarning
|
|
16
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
const r = ".recommendation-block-v2", t = ".recommendation-product-row";
|
|
2
|
+
function n(o) {
|
|
3
|
+
return Array.from(o.querySelectorAll(r)).filter((e) => e.querySelector(t)).length;
|
|
4
|
+
}
|
|
5
|
+
export {
|
|
6
|
+
r as RECOMMENDATION_BLOCK_SELECTOR,
|
|
7
|
+
t as RECOMMENDATION_PRODUCT_ROW_SELECTOR,
|
|
8
|
+
n as countLiveRecommendationBlocks
|
|
9
|
+
};
|
|
@@ -1,39 +1,41 @@
|
|
|
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 S = Object.defineProperty;
|
|
2
|
+
var L = (c, o, e) => o in c ? S(c, o, { enumerable: !0, configurable: !0, writable: !0, value: e }) : c[o] = e;
|
|
3
|
+
var a = (c, o, e) => L(c, typeof o != "symbol" ? o + "" : o, e);
|
|
4
|
+
import { useToaster as f } from "../../../composables/useToaster.js";
|
|
5
|
+
import { ToasterTypeOptions as A } from "../../../enums/toaster.js";
|
|
6
|
+
import { PAGE_TYPES as h } from "../../../enums/unsubscribe.js";
|
|
7
|
+
import { useUnsubscribeStore as u } from "../../../stores/unsubscribe.js";
|
|
8
|
+
import { Block as y, BlockCompositionType as T, ContextActionType as k, ModificationDescription as d, BlockType as I } from "../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
|
|
9
|
+
import { getDefaultTemplate as v } from "./template.js";
|
|
10
|
+
import { DATA_ATTRIBUTES as n, UNSUBSCRIBE_EVENTS as p } from "./utils/constants.js";
|
|
11
|
+
import { parsePageList as B } from "./utils/utils.js";
|
|
12
|
+
const C = "unsubscribe-block", m = 'a[data-unsubscribe-link="true"]', E = ".unsubscribe-block-v2", N = "{{ins-unsubscribe-link}}", U = "https://academy.insiderone.com/docs/adding-unsubscribe-pages-into-emails", R = "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.", D = {
|
|
13
|
+
[h.GLOBAL_UNSUBSCRIBE]: "{{ins-global-unsubscribe-link}}",
|
|
14
|
+
[h.SUBSCRIPTION_PREFERENCE_CENTER]: "{{ins-preferences-unsubscribe-link}}"
|
|
15
|
+
}, w = 3;
|
|
16
|
+
class H extends y {
|
|
17
17
|
constructor() {
|
|
18
18
|
super();
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
a(this, "selectEventListener", null);
|
|
20
|
+
a(this, "cancelEventListener", null);
|
|
21
|
+
a(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
|
-
|
|
27
|
+
a(this, "linkStateByBlockId", /* @__PURE__ */ new Map());
|
|
28
|
+
// Per-block prepend retry counter for the leading text guard (SD-143097).
|
|
29
|
+
a(this, "guardAttemptsByBlockId", /* @__PURE__ */ new Map());
|
|
28
30
|
}
|
|
29
31
|
getId() {
|
|
30
|
-
return
|
|
32
|
+
return C;
|
|
31
33
|
}
|
|
32
34
|
getIcon() {
|
|
33
35
|
return "unsubscribe-icon";
|
|
34
36
|
}
|
|
35
37
|
getBlockCompositionType() {
|
|
36
|
-
return
|
|
38
|
+
return T.BLOCK;
|
|
37
39
|
}
|
|
38
40
|
getName() {
|
|
39
41
|
return this.api.translate("Unsubscribe Block");
|
|
@@ -42,36 +44,84 @@ class F extends L {
|
|
|
42
44
|
return this.api.translate("Unsubscribe Block Description");
|
|
43
45
|
}
|
|
44
46
|
getTemplate() {
|
|
45
|
-
return
|
|
47
|
+
return v();
|
|
46
48
|
}
|
|
47
49
|
getContextActionsIds() {
|
|
48
|
-
return [
|
|
50
|
+
return [k.MOVE, k.REMOVE];
|
|
49
51
|
}
|
|
50
52
|
onSelect(e) {
|
|
51
53
|
this.currentNode = e;
|
|
52
54
|
const t = this._getOrAssignBlockId(e);
|
|
53
55
|
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());
|
|
54
56
|
}
|
|
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
|
+
}
|
|
55
69
|
onDocumentChanged(e) {
|
|
70
|
+
this._ensureLeadingTextGuard(e);
|
|
56
71
|
const t = this._getOrAssignBlockId(e);
|
|
57
72
|
if (!t)
|
|
58
73
|
return;
|
|
59
|
-
const
|
|
60
|
-
this.linkStateByBlockId.get(t) === !0 && !
|
|
74
|
+
const s = this._hasUnsubscribeLink(e);
|
|
75
|
+
this.linkStateByBlockId.get(t) === !0 && !s && this._warnLinkRemoved(), this.linkStateByBlockId.set(t, s);
|
|
61
76
|
}
|
|
62
77
|
onDelete(e) {
|
|
63
78
|
this._removeEventListeners(), this._removeBlockTemplatesFromStore(e), this._resetStoreState();
|
|
64
79
|
const t = this._readBlockId(e);
|
|
65
|
-
t && this.linkStateByBlockId.delete(t);
|
|
80
|
+
t && (this.linkStateByBlockId.delete(t), this.guardAttemptsByBlockId.delete(t));
|
|
66
81
|
}
|
|
67
82
|
onDestroy() {
|
|
68
|
-
this._removeEventListeners(), this.currentNode = void 0, this.linkStateByBlockId.clear();
|
|
83
|
+
this._removeEventListeners(), this.currentNode = void 0, this.linkStateByBlockId.clear(), this.guardAttemptsByBlockId.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
|
+
}
|
|
69
119
|
}
|
|
70
120
|
_hasUnsubscribeLink(e) {
|
|
71
121
|
return "querySelector" in e ? !!e.querySelector(m) : !1;
|
|
72
122
|
}
|
|
73
123
|
_readBlockId(e) {
|
|
74
|
-
return "getAttribute" in e ? e.getAttribute(
|
|
124
|
+
return "getAttribute" in e ? e.getAttribute(n.BLOCK_ID) : null;
|
|
75
125
|
}
|
|
76
126
|
/**
|
|
77
127
|
* Returns the block's stable id, assigning one via the document modifier if
|
|
@@ -85,13 +135,13 @@ class F extends L {
|
|
|
85
135
|
return t;
|
|
86
136
|
if (!("getAttribute" in e))
|
|
87
137
|
return null;
|
|
88
|
-
const
|
|
138
|
+
const s = this._generateNextBlockId();
|
|
89
139
|
try {
|
|
90
|
-
this.api.getDocumentModifier().modifyHtml(e).setAttribute(
|
|
91
|
-
} catch (
|
|
92
|
-
return console.warn("[UnsubscribeBlock] Failed to assign block id:",
|
|
140
|
+
this.api.getDocumentModifier().modifyHtml(e).setAttribute(n.BLOCK_ID, s).apply(new d(`Assign unsubscribe block id ${s}`));
|
|
141
|
+
} catch (r) {
|
|
142
|
+
return console.warn("[UnsubscribeBlock] Failed to assign block id:", r), null;
|
|
93
143
|
}
|
|
94
|
-
return
|
|
144
|
+
return s;
|
|
95
145
|
}
|
|
96
146
|
/**
|
|
97
147
|
* Generates a unique id by scanning the document for the highest existing
|
|
@@ -102,10 +152,10 @@ class F extends L {
|
|
|
102
152
|
let e = 0;
|
|
103
153
|
try {
|
|
104
154
|
const t = this.api.getDocumentRoot();
|
|
105
|
-
t && "querySelectorAll" in t && t.querySelectorAll(
|
|
106
|
-
if ("getAttribute" in
|
|
107
|
-
const
|
|
108
|
-
|
|
155
|
+
t && "querySelectorAll" in t && t.querySelectorAll(E).forEach((r) => {
|
|
156
|
+
if ("getAttribute" in r) {
|
|
157
|
+
const i = r.getAttribute(n.BLOCK_ID), l = i ? parseInt(i) : 0;
|
|
158
|
+
l > e && (e = l);
|
|
109
159
|
}
|
|
110
160
|
});
|
|
111
161
|
} catch {
|
|
@@ -114,14 +164,14 @@ class F extends L {
|
|
|
114
164
|
}
|
|
115
165
|
_warnLinkRemoved() {
|
|
116
166
|
try {
|
|
117
|
-
const { showToaster: e } =
|
|
167
|
+
const { showToaster: e } = f();
|
|
118
168
|
e({
|
|
119
|
-
type:
|
|
120
|
-
message: this.api.translate(
|
|
169
|
+
type: A.Warning,
|
|
170
|
+
message: this.api.translate(R),
|
|
121
171
|
actionButton: {
|
|
122
172
|
text: this.api.translate("Visit Academy"),
|
|
123
173
|
onClick: () => {
|
|
124
|
-
window.open(
|
|
174
|
+
window.open(U, "_blank", "noopener,noreferrer");
|
|
125
175
|
}
|
|
126
176
|
}
|
|
127
177
|
});
|
|
@@ -131,26 +181,26 @@ class F extends L {
|
|
|
131
181
|
}
|
|
132
182
|
_setupSelectEventListener() {
|
|
133
183
|
this._removeSelectEventListener(), this.selectEventListener = (e) => {
|
|
134
|
-
const t = e, { collectionType:
|
|
135
|
-
this._updateBlock(
|
|
136
|
-
}, document.addEventListener(
|
|
184
|
+
const t = e, { collectionType: s, selectedPages: r } = t.detail;
|
|
185
|
+
this._updateBlock(s, r.join(","));
|
|
186
|
+
}, document.addEventListener(p.SELECT, this.selectEventListener);
|
|
137
187
|
}
|
|
138
188
|
_removeSelectEventListener() {
|
|
139
|
-
this.selectEventListener && (document.removeEventListener(
|
|
189
|
+
this.selectEventListener && (document.removeEventListener(p.SELECT, this.selectEventListener), this.selectEventListener = null);
|
|
140
190
|
}
|
|
141
191
|
_setupCancelEventListener() {
|
|
142
192
|
this._removeCancelEventListener(), this.cancelEventListener = () => {
|
|
143
193
|
this._handleCancel();
|
|
144
|
-
}, document.addEventListener(
|
|
194
|
+
}, document.addEventListener(p.CANCEL, this.cancelEventListener);
|
|
145
195
|
}
|
|
146
196
|
_removeCancelEventListener() {
|
|
147
|
-
this.cancelEventListener && (document.removeEventListener(
|
|
197
|
+
this.cancelEventListener && (document.removeEventListener(p.CANCEL, this.cancelEventListener), this.cancelEventListener = null);
|
|
148
198
|
}
|
|
149
199
|
_handleCancel() {
|
|
150
200
|
try {
|
|
151
201
|
if (!this.currentNode)
|
|
152
202
|
return;
|
|
153
|
-
this.api.getDocumentModifier().modifyHtml(this.currentNode).replaceWith(`<${
|
|
203
|
+
this.api.getDocumentModifier().modifyHtml(this.currentNode).replaceWith(`<${I.EMPTY_CONTAINER}/>`).apply(new d("Removed unsubscribe block due to cancel"));
|
|
154
204
|
} catch (e) {
|
|
155
205
|
console.warn("[UnsubscribeBlock] Failed to remove unsubscribe block:", e);
|
|
156
206
|
}
|
|
@@ -161,32 +211,32 @@ class F extends L {
|
|
|
161
211
|
_updateBlock(e, t) {
|
|
162
212
|
if (!this.currentNode || !("querySelector" in this.currentNode))
|
|
163
213
|
return;
|
|
164
|
-
const
|
|
165
|
-
if (!
|
|
214
|
+
const s = this.currentNode.querySelector(m);
|
|
215
|
+
if (!s)
|
|
166
216
|
return;
|
|
167
|
-
const
|
|
168
|
-
this.api.getDocumentModifier().modifyHtml(
|
|
217
|
+
const r = this._getMergeTag(e);
|
|
218
|
+
this.api.getDocumentModifier().modifyHtml(s).setAttribute("href", r).apply(new d(`Updated unsubscribe link to ${r}`)), this.api.getDocumentModifier().modifyHtml(this.currentNode).setAttribute(n.PAGE_TYPE, e.toString()).setAttribute(n.PAGE_LIST, t).apply(new d("Updated unsubscribe block metadata"));
|
|
169
219
|
}
|
|
170
220
|
_getMergeTag(e) {
|
|
171
|
-
return
|
|
221
|
+
return D[e] ?? N;
|
|
172
222
|
}
|
|
173
223
|
_openDrawer() {
|
|
174
224
|
if (!(this.currentNode && this.currentNode.getAttribute("data-unsubscribe-page-type")))
|
|
175
225
|
try {
|
|
176
|
-
const e =
|
|
226
|
+
const e = u();
|
|
177
227
|
e.typeSelectionDrawerStatus = !0;
|
|
178
228
|
} catch (e) {
|
|
179
229
|
console.error("[UnsubscribeBlock] Failed to open drawer:", e);
|
|
180
230
|
}
|
|
181
231
|
}
|
|
182
232
|
_checkExistingBlocks() {
|
|
183
|
-
const e =
|
|
184
|
-
e.isGlobalUnsubscribeDisabled = !1, e.isSubscriptionPreferencesCenterDisabled = !1, this.api.getDocumentRoot().querySelectorAll(
|
|
185
|
-
if ("getAttribute" in
|
|
186
|
-
const
|
|
187
|
-
if (
|
|
188
|
-
const
|
|
189
|
-
|
|
233
|
+
const e = u();
|
|
234
|
+
e.isGlobalUnsubscribeDisabled = !1, e.isSubscriptionPreferencesCenterDisabled = !1, this.api.getDocumentRoot().querySelectorAll(E).forEach((s) => {
|
|
235
|
+
if ("getAttribute" in s) {
|
|
236
|
+
const r = s.getAttribute(n.PAGE_TYPE);
|
|
237
|
+
if (r) {
|
|
238
|
+
const i = Number(r);
|
|
239
|
+
i === h.GLOBAL_UNSUBSCRIBE ? e.isGlobalUnsubscribeDisabled = !0 : i === h.SUBSCRIPTION_PREFERENCE_CENTER && (e.isSubscriptionPreferencesCenterDisabled = !0);
|
|
190
240
|
}
|
|
191
241
|
}
|
|
192
242
|
});
|
|
@@ -194,26 +244,26 @@ class F extends L {
|
|
|
194
244
|
async _loadBlockState(e) {
|
|
195
245
|
if (!("getAttribute" in e))
|
|
196
246
|
return;
|
|
197
|
-
const t = e.getAttribute(
|
|
198
|
-
if (!t || !
|
|
247
|
+
const t = e.getAttribute(n.PAGE_TYPE), s = e.getAttribute(n.PAGE_LIST);
|
|
248
|
+
if (!t || !s)
|
|
199
249
|
return;
|
|
200
|
-
const
|
|
201
|
-
await
|
|
250
|
+
const r = u(), i = Number(t), l = B(s);
|
|
251
|
+
await r.fetchTemplates(), r.setCollectionWithoutAutoSelection(i), r.loadSelectedTemplates(l);
|
|
202
252
|
}
|
|
203
253
|
_resetStoreState() {
|
|
204
|
-
|
|
254
|
+
u().$reset();
|
|
205
255
|
}
|
|
206
256
|
_removeBlockTemplatesFromStore(e) {
|
|
207
257
|
if (!("getAttribute" in e))
|
|
208
258
|
return;
|
|
209
|
-
const t = e.getAttribute(
|
|
259
|
+
const t = e.getAttribute(n.PAGE_LIST);
|
|
210
260
|
if (!t)
|
|
211
261
|
return;
|
|
212
|
-
const
|
|
213
|
-
|
|
262
|
+
const s = u(), r = B(t);
|
|
263
|
+
s.removeUnsubscribePages(r);
|
|
214
264
|
}
|
|
215
265
|
}
|
|
216
266
|
export {
|
|
217
|
-
|
|
218
|
-
|
|
267
|
+
C as UNSUBSCRIBE_BLOCK_ID,
|
|
268
|
+
H as UnsubscribeBlock
|
|
219
269
|
};
|
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
1
|
+
var T = Object.defineProperty;
|
|
2
|
+
var p = (o, s, e) => s in o ? T(o, s, { enumerable: !0, configurable: !0, writable: !0, value: e }) : o[s] = e;
|
|
3
|
+
var c = (o, s, e) => p(o, typeof s != "symbol" ? s + "" : s, e);
|
|
4
4
|
import { useUnsubscribeStore as l } from "../../../stores/unsubscribe.js";
|
|
5
|
-
import { Control as
|
|
6
|
-
import { DATA_ATTRIBUTES as
|
|
7
|
-
import { parsePageList as
|
|
8
|
-
const
|
|
5
|
+
import { Control as _, UEAttr as i, UIElementType as n } from "../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
|
|
6
|
+
import { DATA_ATTRIBUTES as d } from "./utils/constants.js";
|
|
7
|
+
import { parsePageList as h } from "./utils/utils.js";
|
|
8
|
+
const g = "ui-elements-unsubscribe", r = {
|
|
9
9
|
SELECT_BUTTON: "selectTemplateButton",
|
|
10
10
|
PREV_BUTTON: "prevButton",
|
|
11
11
|
NEXT_BUTTON: "nextButton",
|
|
12
12
|
COUNTER_TEXT: "counterText",
|
|
13
13
|
PREVIEW_IMAGE: "previewImage"
|
|
14
14
|
};
|
|
15
|
-
class B extends
|
|
15
|
+
class B extends _ {
|
|
16
16
|
constructor() {
|
|
17
17
|
super(...arguments);
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
18
|
+
c(this, "currentPreviewIndex", 0);
|
|
19
|
+
c(this, "currentNode");
|
|
20
|
+
c(this, "currentPages");
|
|
21
|
+
c(this, "valueChangeHandlers", []);
|
|
22
|
+
c(this, "lastParsedAttribute");
|
|
23
23
|
}
|
|
24
24
|
getId() {
|
|
25
|
-
return
|
|
25
|
+
return g;
|
|
26
26
|
}
|
|
27
27
|
getTemplate() {
|
|
28
28
|
return `
|
|
@@ -34,8 +34,8 @@ class B extends T {
|
|
|
34
34
|
}
|
|
35
35
|
onTemplateNodeUpdated(e) {
|
|
36
36
|
if (this.currentNode = e, "getAttribute" in this.currentNode) {
|
|
37
|
-
const t = this.currentNode.getAttribute(
|
|
38
|
-
t && (t !== this.lastParsedAttribute && (this.currentPages =
|
|
37
|
+
const t = this.currentNode.getAttribute(d.PAGE_LIST);
|
|
38
|
+
t && (t !== this.lastParsedAttribute && (this.currentPages = h(t), this.lastParsedAttribute = t, this.currentPreviewIndex = 0), this._updateCounter(), this._loadAndUpdatePreview());
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
41
|
onRender() {
|
|
@@ -62,11 +62,18 @@ class B extends T {
|
|
|
62
62
|
_onButtonClick() {
|
|
63
63
|
try {
|
|
64
64
|
const e = l();
|
|
65
|
-
e.activeType = e.getSelectedCollection[this.currentPreviewIndex], e.pageSelectionUpdateStatus = !0, e.pageSelectionDrawerStatus = !0;
|
|
65
|
+
this._reseedSelectionFromBlock(), e.activeType = e.getSelectedCollection[this.currentPreviewIndex], e.pageSelectionUpdateStatus = !0, e.pageSelectionDrawerStatus = !0;
|
|
66
66
|
} catch (e) {
|
|
67
67
|
console.error("[UnsubscribeControl] Failed to open drawer:", e);
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
|
+
_reseedSelectionFromBlock() {
|
|
71
|
+
const e = l();
|
|
72
|
+
if (e.$reset(), !this.currentNode || !("getAttribute" in this.currentNode))
|
|
73
|
+
return;
|
|
74
|
+
const t = this.currentNode.getAttribute(d.PAGE_TYPE), a = this.currentNode.getAttribute(d.PAGE_LIST);
|
|
75
|
+
!t || !a || (e.setCollectionWithoutAutoSelection(Number(t)), e.loadSelectedTemplates(h(a)));
|
|
76
|
+
}
|
|
70
77
|
_onPrevClick() {
|
|
71
78
|
this.currentPreviewIndex > 0 && (this.currentPreviewIndex--, this._updatePreview(), this._updateCounter());
|
|
72
79
|
}
|
|
@@ -80,21 +87,21 @@ class B extends T {
|
|
|
80
87
|
var e;
|
|
81
88
|
if ((e = this.currentPages) != null && e.length)
|
|
82
89
|
try {
|
|
83
|
-
const t = this.currentPages[this.currentPreviewIndex],
|
|
84
|
-
if (!
|
|
90
|
+
const t = this.currentPages[this.currentPreviewIndex], u = l().getThumbnailByTemplateId(t);
|
|
91
|
+
if (!u) {
|
|
85
92
|
console.warn("[UnsubscribeControl] No thumbnail found for page:", t);
|
|
86
93
|
return;
|
|
87
94
|
}
|
|
88
95
|
this.api.updateValues({
|
|
89
|
-
[r.PREVIEW_IMAGE]:
|
|
96
|
+
[r.PREVIEW_IMAGE]: u
|
|
90
97
|
});
|
|
91
98
|
} catch (t) {
|
|
92
99
|
console.error("[UnsubscribeControl] Failed to update preview:", t);
|
|
93
100
|
}
|
|
94
101
|
}
|
|
95
102
|
_updateCounter() {
|
|
96
|
-
const e = this.currentPreviewIndex + 1, t = this.totalTemplates,
|
|
97
|
-
this.api.setUIEAttribute(r.PREV_BUTTON, i.BUTTON.disabled,
|
|
103
|
+
const e = this.currentPreviewIndex + 1, t = this.totalTemplates, a = this.currentPreviewIndex === 0, u = this.currentPreviewIndex >= t - 1;
|
|
104
|
+
this.api.setUIEAttribute(r.PREV_BUTTON, i.BUTTON.disabled, a), this.api.setUIEAttribute(r.NEXT_BUTTON, i.BUTTON.disabled, u), this.api.setUIEAttribute(
|
|
98
105
|
r.COUNTER_TEXT,
|
|
99
106
|
i.LABEL.text,
|
|
100
107
|
`${this.api.translate("Showing")} ${e} ${this.api.translate("of")} ${t}`
|
|
@@ -135,14 +142,14 @@ class B extends T {
|
|
|
135
142
|
</${n.LABEL}>
|
|
136
143
|
`;
|
|
137
144
|
}
|
|
138
|
-
_getIconButton(e, t,
|
|
139
|
-
const
|
|
145
|
+
_getIconButton(e, t, a) {
|
|
146
|
+
const u = a ? `${i.BUTTON.disabled}="true"` : "";
|
|
140
147
|
return `
|
|
141
148
|
<${n.BUTTON}
|
|
142
149
|
id="${e}"
|
|
143
150
|
class="flat-inline flat-white"
|
|
144
151
|
${i.BUTTON.name}="${e}"
|
|
145
|
-
${
|
|
152
|
+
${u}
|
|
146
153
|
>
|
|
147
154
|
<${n.ICON}
|
|
148
155
|
src="${t}"
|
|
@@ -165,6 +172,6 @@ class B extends T {
|
|
|
165
172
|
}
|
|
166
173
|
}
|
|
167
174
|
export {
|
|
168
|
-
|
|
175
|
+
g as UNSUBSCRIBE_CONTROL_ID,
|
|
169
176
|
B as UnsubscribeControl
|
|
170
177
|
};
|
|
@@ -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}}", b = `
|
|
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> <
|
|
9
|
+
<p> <a
|
|
10
10
|
href="${n}"
|
|
11
11
|
class="unsubscribe-link"
|
|
12
12
|
target="_blank"
|
|
13
13
|
data-unsubscribe-link="true"
|
|
14
|
-
>${e}</a></
|
|
14
|
+
>${e}</a></p>
|
|
15
15
|
</${s.BLOCK_TEXT}>
|
|
16
16
|
`;
|
|
17
17
|
function u() {
|
|
18
|
-
return
|
|
18
|
+
return b;
|
|
19
19
|
}
|
|
20
20
|
export {
|
|
21
21
|
u as getDefaultTemplate
|