@useinsider/guido 3.20.2-beta.87fb8ae → 3.21.0
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/Guido.vue.js +1 -1
- package/dist/components/Guido.vue2.js +65 -64
- package/dist/components/organisms/AutoSaveController.vue2.js +10 -9
- package/dist/components/organisms/header/EditorActions.vue.js +4 -4
- package/dist/components/organisms/header/EditorActions.vue2.js +53 -51
- package/dist/components/organisms/validation/ValidationErrorDrawer.vue.js +3 -3
- package/dist/components/organisms/validation/ValidationErrorDrawer.vue2.js +23 -22
- package/dist/composables/useAutoSave.js +46 -44
- package/dist/composables/useSave.js +26 -23
- package/dist/composables/useSaveValidation.js +113 -114
- package/dist/composables/useSaveValidationRollout.js +17 -6
- package/dist/composables/useStripo.js +4 -3
- package/dist/extensions/Blocks/Items/block.js +43 -42
- package/dist/extensions/Blocks/Recommendation/store/recommendation.js +9 -5
- package/dist/extensions/Blocks/Unsubscribe/block.js +70 -75
- package/dist/guido.css +1 -1
- package/dist/node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js +271 -192
- package/dist/package.json.js +1 -1
- package/dist/services/settingsApi.js +11 -0
- package/dist/src/components/Guido.vue.d.ts +1 -1
- package/dist/src/components/organisms/header/EditorActions.vue.d.ts +1 -1
- package/dist/src/components/organisms/header/HeaderWrapper.vue.d.ts +1 -1
- package/dist/src/components/organisms/header/RightSlot.vue.d.ts +1 -1
- package/dist/src/composables/useAutoSave.d.ts +4 -1
- package/dist/src/composables/useSaveValidationRollout.d.ts +1 -0
- package/dist/src/extensions/Blocks/Checkbox/controls/blockBackground/index.d.ts +1 -0
- package/dist/src/extensions/Blocks/CouponBlock/controls/index.d.ts +8 -0
- package/dist/src/extensions/Blocks/Items/controls/index.d.ts +40 -0
- package/dist/src/extensions/Blocks/RadioButton/controls/blockBackground/index.d.ts +1 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/blockBackground/index.d.ts +1 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/button/index.d.ts +11 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/customAttribute/index.d.ts +7 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/image/index.d.ts +2 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/name/index.d.ts +7 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/oldPrice/index.d.ts +7 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/omnibusDiscount/index.d.ts +7 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/omnibusPrice/index.d.ts +7 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/price/index.d.ts +7 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/title/index.d.ts +7 -0
- package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +1 -0
- package/dist/src/extensions/Blocks/Unsubscribe/block.d.ts +1 -6
- package/dist/src/extensions/Blocks/_Boilerplate/controls/blockBackground/index.d.ts +1 -0
- package/dist/src/extensions/Blocks/controlFactories.d.ts +22 -0
- package/dist/src/services/settingsApi.d.ts +6 -0
- package/dist/src/stores/setup-settings.d.ts +4 -0
- package/dist/static/styles/components/button.css.js +5 -0
- package/dist/stores/setup-settings.js +10 -0
- package/package.json +4 -4
|
@@ -1,9 +1,20 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import { useSettingsApi as l } from "../services/settingsApi.js";
|
|
2
|
+
import { useSetupSettingsStore as s } from "../stores/setup-settings.js";
|
|
3
|
+
import { computed as a } from "vue";
|
|
4
|
+
let o = null;
|
|
5
|
+
const m = () => {
|
|
6
|
+
const t = s();
|
|
7
|
+
return { isEnabled: a(() => t.isEmailAutoSaveEnabled), loadRollout: () => t.isLoaded ? Promise.resolve() : (o ?? (o = l().getSetupSettings().then(({ isEmailAutoSaveEnabled: e }) => {
|
|
8
|
+
t.$patch({
|
|
9
|
+
isEmailAutoSaveEnabled: !!Number(e ?? 0),
|
|
10
|
+
isLoaded: !0
|
|
11
|
+
});
|
|
12
|
+
}).catch((e) => {
|
|
13
|
+
console.warn("Failed to load setup settings; soft-save stays off.", e);
|
|
14
|
+
}).finally(() => {
|
|
15
|
+
o = null;
|
|
16
|
+
})), o) };
|
|
6
17
|
};
|
|
7
18
|
export {
|
|
8
|
-
|
|
19
|
+
m as useSaveValidationRollout
|
|
9
20
|
};
|
|
@@ -31,13 +31,13 @@ const he = () => {
|
|
|
31
31
|
n = null;
|
|
32
32
|
}), n), D = async (r, s, o, a = [], i = !1) => {
|
|
33
33
|
var y, E, h, C;
|
|
34
|
-
const e = k(), { html: d, css:
|
|
34
|
+
const e = k(), { html: d, css: P } = r, { baseBlocks: g, extensions: R } = await V(), S = ((y = c.value) == null ? void 0 : y.displayConditions) ?? !0, U = ((E = c.value) == null ? void 0 : E.modulesDisabled) ?? !1, I = !!d || (((h = u.value) == null ? void 0 : h.forceRecreate) ?? !1), q = "https://email-static.useinsider.com https://edge.fullstory.com https://rs.fullstory.com";
|
|
35
35
|
w().importCss(), await window.UIEditor.initEditor(
|
|
36
36
|
document.querySelector("#guido-editor"),
|
|
37
37
|
{
|
|
38
38
|
metadata: s,
|
|
39
39
|
html: d,
|
|
40
|
-
css:
|
|
40
|
+
css: P,
|
|
41
41
|
forceRecreate: I,
|
|
42
42
|
locale: "en",
|
|
43
43
|
undoButtonSelector: "#guido__undo-button",
|
|
@@ -60,6 +60,7 @@ const he = () => {
|
|
|
60
60
|
keepModuleStylesEnabled: !0,
|
|
61
61
|
displayTitle: !1,
|
|
62
62
|
displayUTM: !1,
|
|
63
|
+
copyPasteEnabled: !1,
|
|
63
64
|
selectElementAfterDrop: !0,
|
|
64
65
|
sameFontSizeForOutlook: !0,
|
|
65
66
|
allowedScriptSourceDomains: q,
|
|
@@ -120,7 +121,7 @@ const he = () => {
|
|
|
120
121
|
".in-modal-v2-wrapper",
|
|
121
122
|
".in-toasts-wrapper"
|
|
122
123
|
],
|
|
123
|
-
extensions:
|
|
124
|
+
extensions: R,
|
|
124
125
|
localePatch: J
|
|
125
126
|
}
|
|
126
127
|
);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
var k = Object.defineProperty;
|
|
2
|
-
var S = (d, l,
|
|
3
|
-
var g = (d, l,
|
|
2
|
+
var S = (d, l, t) => l in d ? k(d, l, { enumerable: !0, configurable: !0, writable: !0, value: t }) : d[l] = t;
|
|
3
|
+
var g = (d, l, t) => S(d, typeof l != "symbol" ? l + "" : l, t);
|
|
4
4
|
import { BlockId as D } from "../../../enums/block.js";
|
|
5
5
|
import { useOnboardingStore as T } from "../../../stores/onboarding.js";
|
|
6
6
|
import { getMigrationBannerHtml as N } from "../../../utils/migrationBannerHtml.js";
|
|
@@ -58,15 +58,15 @@ class $ extends H {
|
|
|
58
58
|
canBeSavedAsModule() {
|
|
59
59
|
return !0;
|
|
60
60
|
}
|
|
61
|
-
onCreated(
|
|
62
|
-
const
|
|
63
|
-
c.querySelector('[product-attr="imageSrc"] img') ||
|
|
64
|
-
const r = _(
|
|
61
|
+
onCreated(t) {
|
|
62
|
+
const e = this.api.getDocumentModifier(), c = this.api.getDocumentRootCssNode();
|
|
63
|
+
c.querySelector('[product-attr="imageSrc"] img') || e.modifyCss(c).appendRule('[product-attr="imageSrc"] img {object-fit: contain;}');
|
|
64
|
+
const r = _(t);
|
|
65
65
|
if (!r)
|
|
66
66
|
return;
|
|
67
|
-
const o = r.getNodeConfig(),
|
|
67
|
+
const o = r.getNodeConfig(), n = o && Object.keys(o).length > 0, i = C(t);
|
|
68
68
|
if (i != null && i.initialized) {
|
|
69
|
-
if (!
|
|
69
|
+
if (!n) {
|
|
70
70
|
const a = this.api.getDocumentModifier();
|
|
71
71
|
a.modifyHtml(r).setNodeConfig(i), this._stampProductTdDomAttributes(r, i, a), this._healCollapsedWidths(r, a), this._shouldReconcileCurrency(i) && this._reconcileCurrencyDomAttributes(r, i, a), a.apply(new u("Migrate legacy config to nodeConfig")), this._markCurrencyHealed(i.blockInstanceId);
|
|
72
72
|
return;
|
|
@@ -76,9 +76,9 @@ class $ extends H {
|
|
|
76
76
|
I.modifyHtml(r).setNodeConfig(a), this._stampProductTdDomAttributes(r, a, I, !0), I.apply(new u("Initialize Items block with default configuration")), T().startOnboarding("itemsOnboarding");
|
|
77
77
|
return;
|
|
78
78
|
}
|
|
79
|
-
const
|
|
79
|
+
const s = this._resolveInstanceId(i.blockInstanceId), f = this.api.getDocumentModifier();
|
|
80
80
|
let h = !1;
|
|
81
|
-
|
|
81
|
+
s !== i.blockInstanceId && (f.modifyHtml(r).setNodeConfig({ ...i, blockInstanceId: s }), h = !0), !this._currencyHealed.has(s) && this._reconcileCurrencyDomAttributes(r, i, f) && (h = !0), this._healCollapsedWidths(r, f) && (h = !0), h && f.apply(new u("Assign Items block instance ID and reconcile currency")), this._markCurrencyHealed(s);
|
|
82
82
|
}
|
|
83
83
|
/**
|
|
84
84
|
* Re-seeds nodeConfig from the persisted esd-ext-config when a saved module
|
|
@@ -86,24 +86,24 @@ class $ extends H {
|
|
|
86
86
|
* into nodeConfig, so without this a reused module would reset to defaults.
|
|
87
87
|
* Guarded to the nodeConfig-empty case so it runs once and never loops.
|
|
88
88
|
*/
|
|
89
|
-
onDocumentChanged(
|
|
90
|
-
const
|
|
91
|
-
if (!
|
|
89
|
+
onDocumentChanged(t) {
|
|
90
|
+
const e = _(t);
|
|
91
|
+
if (!e)
|
|
92
92
|
return;
|
|
93
|
-
const c =
|
|
93
|
+
const c = e.getNodeConfig();
|
|
94
94
|
if (c && Object.keys(c).length > 0) {
|
|
95
|
-
const i = C(
|
|
95
|
+
const i = C(t);
|
|
96
96
|
if (i != null && i.initialized && this._shouldReconcileCurrency(i)) {
|
|
97
|
-
const
|
|
98
|
-
this._reconcileCurrencyDomAttributes(
|
|
97
|
+
const s = this.api.getDocumentModifier();
|
|
98
|
+
this._reconcileCurrencyDomAttributes(e, i, s) && s.apply(new u(V)), this._markCurrencyHealed(i.blockInstanceId);
|
|
99
99
|
}
|
|
100
100
|
return;
|
|
101
101
|
}
|
|
102
|
-
const o = C(
|
|
102
|
+
const o = C(t);
|
|
103
103
|
if (!(o != null && o.initialized))
|
|
104
104
|
return;
|
|
105
|
-
const
|
|
106
|
-
|
|
105
|
+
const n = this.api.getDocumentModifier();
|
|
106
|
+
n.modifyHtml(e).setNodeConfig(o), this._stampProductTdDomAttributes(e, o, n), this._healCollapsedWidths(e, n), this._shouldReconcileCurrency(o) && this._reconcileCurrencyDomAttributes(e, o, n), n.apply(new u("Recover Items block config from saved module")), this._markCurrencyHealed(o.blockInstanceId);
|
|
107
107
|
}
|
|
108
108
|
/**
|
|
109
109
|
* Bakes the compiler-read DOM attributes (`data-type`, `data-number`, `data-nodup`) onto the
|
|
@@ -113,20 +113,21 @@ class $ extends H {
|
|
|
113
113
|
* restored before export. The name `<a>` carries no data-type/data-number of its own and
|
|
114
114
|
* relies on this td-level fallback in pairProductVariables.
|
|
115
115
|
*/
|
|
116
|
-
_stampProductTdDomAttributes(
|
|
117
|
-
const o = B(
|
|
118
|
-
r &&
|
|
116
|
+
_stampProductTdDomAttributes(t, e, c, r = !1) {
|
|
117
|
+
const o = B(e.itemsSelectValue, e.type), n = (i, s) => {
|
|
118
|
+
r && t.getAttribute(i) || c.modifyHtml(t).setAttribute(i, s);
|
|
119
119
|
};
|
|
120
|
-
|
|
120
|
+
n("data-type", e.type), n("data-number", o), n("data-nodup", String(e.priceHideDiscount));
|
|
121
121
|
}
|
|
122
122
|
/**
|
|
123
123
|
* Repairs a saved module's collapsed card into the state the load migrator produces. Acts only
|
|
124
124
|
* on a zero width, so Stripo's non-zero drop-time width never triggers it and a healed block no-ops.
|
|
125
125
|
*/
|
|
126
|
-
_healCollapsedWidths(
|
|
127
|
-
const r =
|
|
128
|
-
return !m(
|
|
129
|
-
|
|
126
|
+
_healCollapsedWidths(t, e) {
|
|
127
|
+
const r = t.querySelectorAll(M).filter((o) => m(o.getAttribute("width")) || m(o.getStyle("width")));
|
|
128
|
+
return !m(t.getAttribute("width")) && !r.length ? !1 : (t.hasClass("esd-container-frame") && e.modifyHtml(t).removeClass("esd-container-frame"), t.getAttribute("width") !== null && e.modifyHtml(t).removeAttribute("width"), r.forEach((o) => {
|
|
129
|
+
const n = o.getAttribute("width");
|
|
130
|
+
(n === null || m(n)) && e.modifyHtml(o).setAttribute("width", "100%"), m(o.getStyle("width")) && e.modifyHtml(o).setStyle("width", "100%");
|
|
130
131
|
}), !0);
|
|
131
132
|
}
|
|
132
133
|
/**
|
|
@@ -137,12 +138,12 @@ class $ extends H {
|
|
|
137
138
|
* the symbol write alone is skipped for the 'USD' sentinel — so we must NOT gate the whole pass
|
|
138
139
|
* on symbol customization here, or a default-symbol block with a toggled location never heals.
|
|
139
140
|
*/
|
|
140
|
-
_shouldReconcileCurrency(
|
|
141
|
-
return !
|
|
141
|
+
_shouldReconcileCurrency(t) {
|
|
142
|
+
return !t.blockInstanceId || !this._currencyHealed.has(t.blockInstanceId);
|
|
142
143
|
}
|
|
143
144
|
/** Marks a block instance's currency as reconciled so it is not healed again (undo-safe). */
|
|
144
|
-
_markCurrencyHealed(
|
|
145
|
-
|
|
145
|
+
_markCurrencyHealed(t) {
|
|
146
|
+
t && this._currencyHealed.add(t);
|
|
146
147
|
}
|
|
147
148
|
/**
|
|
148
149
|
* Resolves the id for a just-created block to one that is unique per live instance.
|
|
@@ -151,13 +152,13 @@ class $ extends H {
|
|
|
151
152
|
* currency heal guard and settings-panel switch detection. Mint a fresh id on absence
|
|
152
153
|
* or collision, otherwise keep the existing one. Registers the result as claimed.
|
|
153
154
|
*/
|
|
154
|
-
_resolveInstanceId(
|
|
155
|
-
let
|
|
156
|
-
if (!
|
|
155
|
+
_resolveInstanceId(t) {
|
|
156
|
+
let e = t;
|
|
157
|
+
if (!e || this._seenInstanceIds.has(e))
|
|
157
158
|
do
|
|
158
|
-
|
|
159
|
-
while (this._seenInstanceIds.has(
|
|
160
|
-
return this._seenInstanceIds.add(
|
|
159
|
+
e = P();
|
|
160
|
+
while (this._seenInstanceIds.has(e));
|
|
161
|
+
return this._seenInstanceIds.add(e), e;
|
|
161
162
|
}
|
|
162
163
|
/**
|
|
163
164
|
* Stamps the export-read currency attrs onto every price `<p>` from config, so a template whose
|
|
@@ -170,11 +171,11 @@ class $ extends H {
|
|
|
170
171
|
* Returns true only when an attr actually changed, so the caller can skip an empty apply that
|
|
171
172
|
* would otherwise re-trigger onDocumentChanged and loop.
|
|
172
173
|
*/
|
|
173
|
-
_reconcileCurrencyDomAttributes(
|
|
174
|
-
const { position: r, symbol: o } = w(
|
|
174
|
+
_reconcileCurrencyDomAttributes(t, e, c) {
|
|
175
|
+
const { position: r, symbol: o } = w(e), n = t.querySelectorAll(`.${E.PRICE} p`);
|
|
175
176
|
let i = !1;
|
|
176
|
-
return
|
|
177
|
-
r !== void 0 &&
|
|
177
|
+
return n.forEach((s) => {
|
|
178
|
+
r !== void 0 && s.getAttribute(y.POSITION) !== r && (c.modifyHtml(s).setAttribute(y.POSITION, r), i = !0), o !== void 0 && s.getAttribute(y.SYMBOL) !== o && (c.modifyHtml(s).setAttribute(y.SYMBOL, o), i = !0);
|
|
178
179
|
}), i;
|
|
179
180
|
}
|
|
180
181
|
}
|
|
@@ -25,6 +25,9 @@ function W(t) {
|
|
|
25
25
|
return e && e.token === u.get(t) ? e.outcome : !1;
|
|
26
26
|
}
|
|
27
27
|
let l = null;
|
|
28
|
+
const X = () => {
|
|
29
|
+
l == null || l();
|
|
30
|
+
};
|
|
28
31
|
function D() {
|
|
29
32
|
return {
|
|
30
33
|
cardsInRow: x,
|
|
@@ -80,7 +83,7 @@ function G() {
|
|
|
80
83
|
adoptedSizeVersion: 0
|
|
81
84
|
};
|
|
82
85
|
}
|
|
83
|
-
const
|
|
86
|
+
const Y = () => ({
|
|
84
87
|
recommendationCampaignUrls: {},
|
|
85
88
|
activePredictiveAlgorithms: [],
|
|
86
89
|
languages: {},
|
|
@@ -95,8 +98,8 @@ const X = () => ({
|
|
|
95
98
|
currentRecommendationId: null,
|
|
96
99
|
strategyPanelOpen: !1,
|
|
97
100
|
configVersion: 0
|
|
98
|
-
}),
|
|
99
|
-
state: () =>
|
|
101
|
+
}), St = V("guidoRecommendationExtension", {
|
|
102
|
+
state: () => Y(),
|
|
100
103
|
getters: {
|
|
101
104
|
// ====================================================================
|
|
102
105
|
// Proxy Getters — Backward Compatible Access to Current Block State
|
|
@@ -472,7 +475,7 @@ const X = () => ({
|
|
|
472
475
|
},
|
|
473
476
|
/** Lets the editor tear the return listeners down when it unmounts. */
|
|
474
477
|
disposeStrategyPageReturn() {
|
|
475
|
-
|
|
478
|
+
X();
|
|
476
479
|
},
|
|
477
480
|
/**
|
|
478
481
|
* Opens Smart Recommender's strategy creation page. Every return refreshes the list so the
|
|
@@ -805,5 +808,6 @@ const X = () => ({
|
|
|
805
808
|
}
|
|
806
809
|
});
|
|
807
810
|
export {
|
|
808
|
-
|
|
811
|
+
X as disposeStrategyPageReturnListeners,
|
|
812
|
+
St as useRecommendationExtensionStore
|
|
809
813
|
};
|
|
@@ -1,42 +1,48 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
1
|
+
var y = Object.defineProperty;
|
|
2
|
+
var I = (c, o, e) => o in c ? y(c, o, { enumerable: !0, configurable: !0, writable: !0, value: e }) : c[o] = e;
|
|
3
|
+
var g = (c, o, e) => I(c, typeof o != "symbol" ? o + "" : o, e);
|
|
4
4
|
import { useToaster as L } from "../../../composables/useToaster.js";
|
|
5
|
-
import { ToasterTypeOptions as
|
|
6
|
-
import { PAGE_TYPES as
|
|
7
|
-
import { useEditorStore as
|
|
8
|
-
import { useUnsubscribeStore as
|
|
9
|
-
import { Block as
|
|
10
|
-
import { getDefaultTemplate as
|
|
11
|
-
import { UNSUBSCRIBE_BLOCK_SELECTOR as
|
|
12
|
-
import { parsePageList as
|
|
13
|
-
const
|
|
14
|
-
[
|
|
15
|
-
[
|
|
16
|
-
},
|
|
17
|
-
|
|
5
|
+
import { ToasterTypeOptions as C } from "../../../enums/toaster.js";
|
|
6
|
+
import { PAGE_TYPES as m } from "../../../enums/unsubscribe.js";
|
|
7
|
+
import { useEditorStore as N } from "../../../stores/editor.js";
|
|
8
|
+
import { useUnsubscribeStore as a } from "../../../stores/unsubscribe.js";
|
|
9
|
+
import { Block as U, BlockCompositionType as R, ContextActionType as f, ModificationDescription as u, BlockType as v } from "../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
|
|
10
|
+
import { getDefaultTemplate as D } from "./template.js";
|
|
11
|
+
import { UNSUBSCRIBE_BLOCK_SELECTOR as B, DATA_ATTRIBUTES as n, UNSUBSCRIBE_EVENTS as h } from "./utils/constants.js";
|
|
12
|
+
import { parsePageList as S } from "./utils/utils.js";
|
|
13
|
+
const w = "unsubscribe-block", E = 'a[data-unsubscribe-link="true"]', P = "{{ins-unsubscribe-link}}", x = "https://academy.insiderone.com/docs/adding-unsubscribe-pages-into-emails", G = "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.", M = {
|
|
14
|
+
[m.GLOBAL_UNSUBSCRIBE]: "{{ins-global-unsubscribe-link}}",
|
|
15
|
+
[m.SUBSCRIPTION_PREFERENCE_CENTER]: "{{ins-preferences-unsubscribe-link}}"
|
|
16
|
+
}, O = 3;
|
|
17
|
+
let d = null, p = null;
|
|
18
|
+
const A = () => {
|
|
19
|
+
d && (document.removeEventListener(h.SELECT, d), d = null);
|
|
20
|
+
}, T = () => {
|
|
21
|
+
p && (document.removeEventListener(h.CANCEL, p), p = null);
|
|
22
|
+
}, q = () => {
|
|
23
|
+
A(), T();
|
|
24
|
+
};
|
|
25
|
+
class J extends U {
|
|
18
26
|
constructor() {
|
|
19
27
|
super();
|
|
20
|
-
|
|
21
|
-
a(this, "cancelEventListener", null);
|
|
22
|
-
a(this, "currentNode");
|
|
28
|
+
g(this, "currentNode");
|
|
23
29
|
// Per-block "did this instance have a link last time we saw it?" tracking.
|
|
24
30
|
// Keyed by the stable `data-unsubscribe-block-id` we assign, because
|
|
25
31
|
// ImmutableHtmlNode instances are recreated on every document mutation and
|
|
26
32
|
// can't be used as Map keys directly. A singleton boolean here would be
|
|
27
33
|
// polluted across blocks since Stripo fires onDocumentChanged per-instance.
|
|
28
|
-
|
|
34
|
+
g(this, "linkStateByBlockId", /* @__PURE__ */ new Map());
|
|
29
35
|
// Per-block prepend retry counter for the leading text guard (SD-143097).
|
|
30
|
-
|
|
36
|
+
g(this, "guardAttemptsByBlockId", /* @__PURE__ */ new Map());
|
|
31
37
|
}
|
|
32
38
|
getId() {
|
|
33
|
-
return
|
|
39
|
+
return w;
|
|
34
40
|
}
|
|
35
41
|
getIcon() {
|
|
36
42
|
return "unsubscribe-icon";
|
|
37
43
|
}
|
|
38
44
|
getBlockCompositionType() {
|
|
39
|
-
return
|
|
45
|
+
return R.BLOCK;
|
|
40
46
|
}
|
|
41
47
|
getName() {
|
|
42
48
|
return this.api.translate("Unsubscribe Block");
|
|
@@ -45,16 +51,16 @@ class W extends T {
|
|
|
45
51
|
return this.api.translate("Unsubscribe Block Description");
|
|
46
52
|
}
|
|
47
53
|
getTemplate() {
|
|
48
|
-
return
|
|
54
|
+
return D();
|
|
49
55
|
}
|
|
50
56
|
getContextActionsIds() {
|
|
51
|
-
return [
|
|
57
|
+
return [f.MOVE, f.REMOVE];
|
|
52
58
|
}
|
|
53
59
|
onSelect(e) {
|
|
54
|
-
if (this.currentNode = e,
|
|
60
|
+
if (this.currentNode = e, N().isPreviewModeOpen)
|
|
55
61
|
return;
|
|
56
62
|
const t = this._getOrAssignBlockId(e);
|
|
57
|
-
t && this.linkStateByBlockId.set(t, this._hasUnsubscribeLink(e)), this._setupSelectEventListener(), this._setupCancelEventListener(t), !("getAttribute" in e && e.getAttribute("data-migration")) && (this._resetStoreState(), t && (
|
|
63
|
+
t && this.linkStateByBlockId.set(t, this._hasUnsubscribeLink(e)), this._setupSelectEventListener(), this._setupCancelEventListener(t), !("getAttribute" in e && e.getAttribute("data-migration")) && (this._resetStoreState(), t && (a().pendingBlockId = t), this._loadBlockState(e), this._checkExistingBlocks(), this._openDrawer());
|
|
58
64
|
}
|
|
59
65
|
onCreated(e) {
|
|
60
66
|
this._ensureLeadingTextGuard(e);
|
|
@@ -62,7 +68,7 @@ class W extends T {
|
|
|
62
68
|
onDocumentInit() {
|
|
63
69
|
try {
|
|
64
70
|
const e = this.api.getDocumentRoot();
|
|
65
|
-
e && "querySelectorAll" in e && e.querySelectorAll(
|
|
71
|
+
e && "querySelectorAll" in e && e.querySelectorAll(B).forEach((t) => {
|
|
66
72
|
this._ensureLeadingTextGuard(t);
|
|
67
73
|
});
|
|
68
74
|
} catch {
|
|
@@ -77,13 +83,10 @@ class W extends T {
|
|
|
77
83
|
this.linkStateByBlockId.get(t) === !0 && !s && this._warnLinkRemoved(), this.linkStateByBlockId.set(t, s);
|
|
78
84
|
}
|
|
79
85
|
onDelete(e) {
|
|
80
|
-
|
|
86
|
+
q(), this._removeBlockTemplatesFromStore(e), this._resetStoreState();
|
|
81
87
|
const t = this._readBlockId(e);
|
|
82
88
|
t && (this.linkStateByBlockId.delete(t), this.guardAttemptsByBlockId.delete(t));
|
|
83
89
|
}
|
|
84
|
-
onDestroy() {
|
|
85
|
-
this._removeEventListeners(), this.currentNode = void 0, this.linkStateByBlockId.clear(), this.guardAttemptsByBlockId.clear();
|
|
86
|
-
}
|
|
87
90
|
/**
|
|
88
91
|
* Guarantees a plain-text node before the link's wrapper inside the <p>.
|
|
89
92
|
* Without it the only caret position left of the link is inside the anchor,
|
|
@@ -102,20 +105,20 @@ class W extends T {
|
|
|
102
105
|
return;
|
|
103
106
|
const i = s.previousSibling();
|
|
104
107
|
if (!!(i && i.getType() === "text" && i.getTextContent())) {
|
|
105
|
-
const
|
|
106
|
-
|
|
108
|
+
const b = this._readBlockId(e);
|
|
109
|
+
b && this.guardAttemptsByBlockId.delete(b);
|
|
107
110
|
return;
|
|
108
111
|
}
|
|
109
|
-
const
|
|
110
|
-
if (!
|
|
112
|
+
const k = this._getOrAssignBlockId(e);
|
|
113
|
+
if (!k)
|
|
111
114
|
return;
|
|
112
|
-
const
|
|
113
|
-
if (!(
|
|
114
|
-
this.guardAttemptsByBlockId.set(
|
|
115
|
+
const _ = this.guardAttemptsByBlockId.get(k) ?? 0;
|
|
116
|
+
if (!(_ >= O)) {
|
|
117
|
+
this.guardAttemptsByBlockId.set(k, _ + 1);
|
|
115
118
|
try {
|
|
116
|
-
this.api.getDocumentModifier().modifyHtml(r).prepend(" ").apply(new
|
|
117
|
-
} catch (
|
|
118
|
-
console.warn("[UnsubscribeBlock] Failed to ensure link text guard:",
|
|
119
|
+
this.api.getDocumentModifier().modifyHtml(r).prepend(" ").apply(new u("Ensure unsubscribe link text guard"));
|
|
120
|
+
} catch (b) {
|
|
121
|
+
console.warn("[UnsubscribeBlock] Failed to ensure link text guard:", b);
|
|
119
122
|
}
|
|
120
123
|
}
|
|
121
124
|
}
|
|
@@ -139,7 +142,7 @@ class W extends T {
|
|
|
139
142
|
return null;
|
|
140
143
|
const s = this._generateNextBlockId();
|
|
141
144
|
try {
|
|
142
|
-
this.api.getDocumentModifier().modifyHtml(e).setAttribute(n.BLOCK_ID, s).apply(new
|
|
145
|
+
this.api.getDocumentModifier().modifyHtml(e).setAttribute(n.BLOCK_ID, s).apply(new u(`Assign unsubscribe block id ${s}`));
|
|
143
146
|
} catch (r) {
|
|
144
147
|
return console.warn("[UnsubscribeBlock] Failed to assign block id:", r), null;
|
|
145
148
|
}
|
|
@@ -154,10 +157,10 @@ class W extends T {
|
|
|
154
157
|
let e = 0;
|
|
155
158
|
try {
|
|
156
159
|
const t = this.api.getDocumentRoot();
|
|
157
|
-
t && "querySelectorAll" in t && t.querySelectorAll(
|
|
160
|
+
t && "querySelectorAll" in t && t.querySelectorAll(B).forEach((r) => {
|
|
158
161
|
if ("getAttribute" in r) {
|
|
159
|
-
const i = r.getAttribute(n.BLOCK_ID),
|
|
160
|
-
|
|
162
|
+
const i = r.getAttribute(n.BLOCK_ID), l = i ? parseInt(i) : 0;
|
|
163
|
+
l > e && (e = l);
|
|
161
164
|
}
|
|
162
165
|
});
|
|
163
166
|
} catch {
|
|
@@ -168,12 +171,12 @@ class W extends T {
|
|
|
168
171
|
try {
|
|
169
172
|
const { showToaster: e } = L();
|
|
170
173
|
e({
|
|
171
|
-
type:
|
|
172
|
-
message: this.api.translate(
|
|
174
|
+
type: C.Warning,
|
|
175
|
+
message: this.api.translate(G),
|
|
173
176
|
actionButton: {
|
|
174
177
|
text: this.api.translate("Visit Academy"),
|
|
175
178
|
onClick: () => {
|
|
176
|
-
window.open(
|
|
179
|
+
window.open(x, "_blank", "noopener,noreferrer");
|
|
177
180
|
}
|
|
178
181
|
}
|
|
179
182
|
});
|
|
@@ -182,35 +185,26 @@ class W extends T {
|
|
|
182
185
|
}
|
|
183
186
|
}
|
|
184
187
|
_setupSelectEventListener() {
|
|
185
|
-
|
|
188
|
+
A(), d = (e) => {
|
|
186
189
|
const t = e, { collectionType: s, selectedPages: r } = t.detail;
|
|
187
190
|
this._updateBlock(s, r.join(","));
|
|
188
|
-
}, document.addEventListener(
|
|
189
|
-
}
|
|
190
|
-
_removeSelectEventListener() {
|
|
191
|
-
this.selectEventListener && (document.removeEventListener(b.SELECT, this.selectEventListener), this.selectEventListener = null);
|
|
191
|
+
}, document.addEventListener(h.SELECT, d);
|
|
192
192
|
}
|
|
193
193
|
_setupCancelEventListener(e) {
|
|
194
|
-
|
|
194
|
+
T(), p = (t) => {
|
|
195
195
|
const { detail: s } = t;
|
|
196
196
|
((s == null ? void 0 : s.blockId) ?? null) === e && this._handleCancel();
|
|
197
|
-
}, document.addEventListener(
|
|
198
|
-
}
|
|
199
|
-
_removeCancelEventListener() {
|
|
200
|
-
this.cancelEventListener && (document.removeEventListener(b.CANCEL, this.cancelEventListener), this.cancelEventListener = null);
|
|
197
|
+
}, document.addEventListener(h.CANCEL, p);
|
|
201
198
|
}
|
|
202
199
|
_handleCancel() {
|
|
203
200
|
try {
|
|
204
201
|
if (!this.currentNode)
|
|
205
202
|
return;
|
|
206
|
-
this.api.getDocumentModifier().modifyHtml(this.currentNode).replaceWith(`<${v.EMPTY_CONTAINER}/>`).apply(new
|
|
203
|
+
this.api.getDocumentModifier().modifyHtml(this.currentNode).replaceWith(`<${v.EMPTY_CONTAINER}/>`).apply(new u("Removed unsubscribe block due to cancel"));
|
|
207
204
|
} catch (e) {
|
|
208
205
|
console.warn("[UnsubscribeBlock] Failed to remove unsubscribe block:", e);
|
|
209
206
|
}
|
|
210
207
|
}
|
|
211
|
-
_removeEventListeners() {
|
|
212
|
-
this._removeSelectEventListener(), this._removeCancelEventListener();
|
|
213
|
-
}
|
|
214
208
|
_updateBlock(e, t) {
|
|
215
209
|
if (!this.currentNode || !("querySelector" in this.currentNode))
|
|
216
210
|
return;
|
|
@@ -218,28 +212,28 @@ class W extends T {
|
|
|
218
212
|
if (!s)
|
|
219
213
|
return;
|
|
220
214
|
const r = this._getMergeTag(e);
|
|
221
|
-
this.api.getDocumentModifier().modifyHtml(s).setAttribute("href", r).apply(new
|
|
215
|
+
this.api.getDocumentModifier().modifyHtml(s).setAttribute("href", r).apply(new u(`Updated unsubscribe link to ${r}`)), this.api.getDocumentModifier().modifyHtml(this.currentNode).setAttribute(n.PAGE_TYPE, e.toString()).setAttribute(n.PAGE_LIST, t).apply(new u("Updated unsubscribe block metadata"));
|
|
222
216
|
}
|
|
223
217
|
_getMergeTag(e) {
|
|
224
|
-
return
|
|
218
|
+
return M[e] ?? P;
|
|
225
219
|
}
|
|
226
220
|
_openDrawer() {
|
|
227
221
|
if (!(this.currentNode && this.currentNode.getAttribute("data-unsubscribe-page-type")))
|
|
228
222
|
try {
|
|
229
|
-
const e =
|
|
223
|
+
const e = a();
|
|
230
224
|
e.typeSelectionDrawerStatus = !0;
|
|
231
225
|
} catch (e) {
|
|
232
226
|
console.error("[UnsubscribeBlock] Failed to open drawer:", e);
|
|
233
227
|
}
|
|
234
228
|
}
|
|
235
229
|
_checkExistingBlocks() {
|
|
236
|
-
const e =
|
|
237
|
-
e.isGlobalUnsubscribeDisabled = !1, e.isSubscriptionPreferencesCenterDisabled = !1, this.api.getDocumentRoot().querySelectorAll(
|
|
230
|
+
const e = a();
|
|
231
|
+
e.isGlobalUnsubscribeDisabled = !1, e.isSubscriptionPreferencesCenterDisabled = !1, this.api.getDocumentRoot().querySelectorAll(B).forEach((s) => {
|
|
238
232
|
if ("getAttribute" in s) {
|
|
239
233
|
const r = s.getAttribute(n.PAGE_TYPE);
|
|
240
234
|
if (r) {
|
|
241
235
|
const i = Number(r);
|
|
242
|
-
i ===
|
|
236
|
+
i === m.GLOBAL_UNSUBSCRIBE ? e.isGlobalUnsubscribeDisabled = !0 : i === m.SUBSCRIPTION_PREFERENCE_CENTER && (e.isSubscriptionPreferencesCenterDisabled = !0);
|
|
243
237
|
}
|
|
244
238
|
}
|
|
245
239
|
});
|
|
@@ -250,11 +244,11 @@ class W extends T {
|
|
|
250
244
|
const t = e.getAttribute(n.PAGE_TYPE), s = e.getAttribute(n.PAGE_LIST);
|
|
251
245
|
if (!t || !s)
|
|
252
246
|
return;
|
|
253
|
-
const r =
|
|
254
|
-
await r.fetchTemplates(), r.setCollectionWithoutAutoSelection(i), r.loadSelectedTemplates(
|
|
247
|
+
const r = a(), i = Number(t), l = S(s);
|
|
248
|
+
await r.fetchTemplates(), r.setCollectionWithoutAutoSelection(i), r.loadSelectedTemplates(l);
|
|
255
249
|
}
|
|
256
250
|
_resetStoreState() {
|
|
257
|
-
|
|
251
|
+
a().$reset();
|
|
258
252
|
}
|
|
259
253
|
_removeBlockTemplatesFromStore(e) {
|
|
260
254
|
if (!("getAttribute" in e))
|
|
@@ -262,11 +256,12 @@ class W extends T {
|
|
|
262
256
|
const t = e.getAttribute(n.PAGE_LIST);
|
|
263
257
|
if (!t)
|
|
264
258
|
return;
|
|
265
|
-
const s =
|
|
259
|
+
const s = a(), r = S(t);
|
|
266
260
|
s.removeUnsubscribePages(r);
|
|
267
261
|
}
|
|
268
262
|
}
|
|
269
263
|
export {
|
|
270
|
-
|
|
271
|
-
|
|
264
|
+
w as UNSUBSCRIBE_BLOCK_ID,
|
|
265
|
+
J as UnsubscribeBlock,
|
|
266
|
+
q as disposeUnsubscribeListeners
|
|
272
267
|
};
|
package/dist/guido.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
@charset "UTF-8";.auth-error-modal[data-v-b4d7ae51]{position:relative;z-index:145}.gap-16[data-v-5553d071],.gap-16[data-v-0e1b0c54]{gap:16px}[data-v-b8f24f34] .in-button-v2__wrapper{line-height:0}[data-v-22226124] .in-segments-wrapper__button_selected,[data-v-22226124] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb;color:#0010ac;border-color:#0010ac}[data-v-2cb418af] .in-progress-wrapper__progress p span:last-child{display:none!important}[data-v-2cb418af] .in-progress-description-status{display:none!important}.view-options-wrapper[data-v-87033101]{position:relative;display:inline-block}.new-tag[data-v-87033101]{position:absolute;top:-8px;right:-16px;z-index:10}[data-v-87033101] .guido__view-option-selection-desktop svg,[data-v-87033101] .guido__view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-87033101] .in-segments-wrapper__button_selected,[data-v-87033101] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}[data-v-87033101] .in-tooltip-wrapper-v2__icon{cursor:pointer}.editor-toolbar[data-v-173c3a40]{gap:4px}.version-history-item[data-v-ee4b9c3f]{flex-basis:200px}.version-history[data-v-fad98586]{gap:8px}.version-history__toolbar[data-v-fad98586]{gap:4px}.view-options-wrapper[data-v-6ebabfe4]{position:relative;display:inline-block}.new-tag[data-v-6ebabfe4]{position:absolute;top:-8px;right:-16px;z-index:10}[data-v-6ebabfe4] .guido__verion-history-view-option-selection-desktop svg,[data-v-6ebabfe4] .guido__verion-history-view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-6ebabfe4] .in-segments-wrapper__button_selected,[data-v-6ebabfe4] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}[data-v-6ebabfe4] .in-tooltip-wrapper-v2__icon{cursor:pointer}.auto-save-toggle[data-v-2c964af4]{position:relative}.auto-save-toggle__info-box[data-v-2c964af4]{position:absolute;top:100%;left:0;z-index:10;width:280px}.editor-actions[data-v-
|
|
1
|
+
@charset "UTF-8";.auth-error-modal[data-v-b4d7ae51]{position:relative;z-index:145}.gap-16[data-v-5553d071],.gap-16[data-v-0e1b0c54]{gap:16px}[data-v-b8f24f34] .in-button-v2__wrapper{line-height:0}[data-v-22226124] .in-segments-wrapper__button_selected,[data-v-22226124] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb;color:#0010ac;border-color:#0010ac}[data-v-2cb418af] .in-progress-wrapper__progress p span:last-child{display:none!important}[data-v-2cb418af] .in-progress-description-status{display:none!important}.view-options-wrapper[data-v-87033101]{position:relative;display:inline-block}.new-tag[data-v-87033101]{position:absolute;top:-8px;right:-16px;z-index:10}[data-v-87033101] .guido__view-option-selection-desktop svg,[data-v-87033101] .guido__view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-87033101] .in-segments-wrapper__button_selected,[data-v-87033101] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}[data-v-87033101] .in-tooltip-wrapper-v2__icon{cursor:pointer}.editor-toolbar[data-v-173c3a40]{gap:4px}.version-history-item[data-v-ee4b9c3f]{flex-basis:200px}.version-history[data-v-fad98586]{gap:8px}.version-history__toolbar[data-v-fad98586]{gap:4px}.view-options-wrapper[data-v-6ebabfe4]{position:relative;display:inline-block}.new-tag[data-v-6ebabfe4]{position:absolute;top:-8px;right:-16px;z-index:10}[data-v-6ebabfe4] .guido__verion-history-view-option-selection-desktop svg,[data-v-6ebabfe4] .guido__verion-history-view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-6ebabfe4] .in-segments-wrapper__button_selected,[data-v-6ebabfe4] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}[data-v-6ebabfe4] .in-tooltip-wrapper-v2__icon{cursor:pointer}.auto-save-toggle[data-v-2c964af4]{position:relative}.auto-save-toggle__info-box[data-v-2c964af4]{position:absolute;top:100%;left:0;z-index:10;width:280px}.editor-actions[data-v-baf7a5dd]{gap:4px}.header-wrapper[data-v-d11dd577]{min-width:1000px}.guido-loading__wrapper[data-v-07c4b2d8]{height:100%;top:75px!important;bottom:0!important}.validation-error-list[data-v-e48cebe9]{gap:16px}.validation-error-row[data-v-e48cebe9]{gap:8px;padding:24px;border:1px solid #E1E1E1;border-radius:8px}.validation-error-row__icon[data-v-e48cebe9]{flex-shrink:0;font-size:24px;line-height:0}.validation-error-row__text[data-v-e48cebe9]{font-size:13px;line-height:16px;color:#292929;word-break:break-word}.guido-editor__wrapper[data-v-c5146fc5]{--ribbon-offset: 0px;position:relative;width:100%;height:calc(100vh - 128px - var(--ribbon-offset))}.guido-editor__container[data-v-c5146fc5]{width:100%;height:calc(100vh - 128px - var(--ribbon-offset))}.guido-editor__no-header[data-v-c5146fc5]{height:calc(100vh - 75px - var(--ribbon-offset))}[data-v-293f1c47] .in-breadcrumb-wrapper__links{cursor:pointer}.templates-wrapper[data-v-91a26acd]{gap:16px;grid-template-columns:repeat(3,1fr)}.templates-wrapper .template-wrapper[data-v-91a26acd]{cursor:pointer}.templates-wrapper .template-wrapper .template-container[data-v-91a26acd]{height:274px;padding:2px;transition:none}.templates-wrapper .template-wrapper .template-container.selected[data-v-91a26acd]{padding:1px}.templates-wrapper .template-wrapper .template-container .thumbnail[data-v-91a26acd]{object-fit:cover;transform:scale(1)}[data-v-b9a93c6e] .guido__verion-history-view-option-selection-desktop svg,[data-v-b9a93c6e] .guido__verion-history-view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-b9a93c6e] .in-segments-wrapper__button_selected,[data-v-b9a93c6e] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}.error-list[data-v-c3fd5d4b]{gap:16px}.desktop-browser-header[data-v-d86c5af5]{height:79px;min-height:79px}.desktop-browser-header__left[data-v-d86c5af5]{-webkit-user-drag:none;height:79px;width:378px}.desktop-browser-header__center[data-v-d86c5af5]{height:79px;background-repeat:repeat-x;background-size:auto 100%;background-position:left top}.desktop-browser-header__right[data-v-d86c5af5]{-webkit-user-drag:none;height:79px;width:112px}.desktop-preview[data-v-cf946232]{min-width:602px;height:70vh;min-height:583px;border-radius:10px}.desktop-preview iframe[data-v-cf946232]{min-height:504px}.iframe-wrapper[data-v-f255b2bb]{width:258px}.iframe-scaled[data-v-f255b2bb]{width:320px;height:124.0310077519%;transform:scale(.80625);transform-origin:top left}.cropped-text[data-v-eb3d05d7]{width:220px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.mobile-preview-wrapper__phone[data-v-3f472f96]{width:282px}.mobile-preview-wrapper__phone img[data-v-3f472f96]{object-fit:cover;border-radius:44px}.mobile-preview-wrapper__content[data-v-3f472f96]{width:258px;height:450px;left:12px}[data-v-6bcaca8a] .vueperslides__parallax-wrapper{padding-bottom:110px!important}[data-v-f16f20f8] .vueperslides__bullets{pointer-events:none!important}[data-v-f16f20f8] .vueperslides__parallax-wrapper{padding-bottom:110px!important}[data-v-bb3cca55] .vueperslides__bullets{pointer-events:none!important}[data-v-bb3cca55] .vueperslides__parallax-wrapper{height:110px!important;padding-bottom:110px!important}[data-v-19d8cb42] .vueperslides__bullets,[data-v-ec2027ff] .vueperslides__bullets,[data-v-b09e80c4] .vueperslides__bullets{pointer-events:none!important}[data-v-b09e80c4] .vueperslides__parallax-wrapper{height:110px!important;padding-bottom:110px!important}[data-v-9bdef600] .vueperslides__parallax-wrapper{padding-bottom:110px!important}.assign-strategy-drawer-content .assign-strategy-select[data-v-6ce48dfd]{width:100%;max-width:none}.assign-strategy-drawer-content .assign-strategy-select[data-v-6ce48dfd] .in-skeleton{width:100%!important}.assign-strategy-drawer-content .assign-strategy-select[data-v-6ce48dfd] .in-dropdown-box__container{width:413px}.assign-strategy-drawer .spaced-dot-sep{background-image:linear-gradient(90deg,#91949f 20%,#fff0 0);background-position:center bottom;background-repeat:repeat-x;background-size:5px 1px}.assign-strategy-drawer .spaced-dot-sep--top{background-position:center top}.assign-strategy-drawer .spaced-dot-sep--fc-n:first-child{background:none}.legacy-strategy-updated-modal[data-v-da2225a1]{position:relative;z-index:145}
|