@useinsider/guido 3.20.1 → 3.21.0-beta.27e5667
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/useLegacyStrategyConversion.js +16 -16
- 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/block.js +166 -136
- package/dist/extensions/Blocks/Recommendation/controls/main/index.js +296 -223
- package/dist/extensions/Blocks/Recommendation/store/recommendation.js +221 -203
- package/dist/extensions/Blocks/Recommendation/utils/blockRefresh.js +19 -0
- package/dist/extensions/Blocks/Recommendation/utils/nodeConfigWriter.js +51 -36
- package/dist/extensions/Blocks/Recommendation/utils/strategyCommit.js +49 -36
- 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/block.d.ts +7 -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/main/index.d.ts +18 -3
- 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 +9 -1
- package/dist/src/extensions/Blocks/Recommendation/utils/blockRefresh.d.ts +17 -0
- package/dist/src/extensions/Blocks/Recommendation/utils/nodeConfigWriter.d.ts +7 -0
- package/dist/src/extensions/Blocks/Recommendation/utils/strategyCommit.d.ts +9 -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,43 +1,44 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
import { useConfig as
|
|
1
|
+
var D = Object.defineProperty;
|
|
2
|
+
var A = (l, c, e) => c in l ? D(l, c, { enumerable: !0, configurable: !0, writable: !0, value: e }) : l[c] = e;
|
|
3
|
+
var m = (l, c, e) => A(l, typeof c != "symbol" ? c + "" : c, e);
|
|
4
|
+
import { useConfig as u } from "../../../composables/useConfig.js";
|
|
5
5
|
import { BlockId as C } from "../../../enums/block.js";
|
|
6
|
-
import { getMigrationBannerHtml as
|
|
7
|
-
import { Block as
|
|
8
|
-
import { CURRENT_CONFIG_VERSION as
|
|
9
|
-
import { RECOMMENDATION_ID_ATTR as
|
|
10
|
-
import { regenerateMobileProductRows as
|
|
11
|
-
import { ensureMobileCssRulesExist as I, setMobileLayoutOptOut as
|
|
12
|
-
import { RecommendationConfigService as
|
|
13
|
-
import { useRecommendationExtensionStore as
|
|
14
|
-
import { getDefaultTemplate as
|
|
15
|
-
import { useRecommendationBlockWarning as
|
|
16
|
-
import { registerNodeConfigWriter as
|
|
17
|
-
import { refreshDuplicatedStrategyBlocks as $ } from "./utils/strategyCommit.js";
|
|
18
|
-
const
|
|
19
|
-
let
|
|
20
|
-
class
|
|
6
|
+
import { getMigrationBannerHtml as E } from "../../../utils/migrationBannerHtml.js";
|
|
7
|
+
import { Block as S, BlockCompositionType as N, ModificationDescription as p } from "../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
|
|
8
|
+
import { CURRENT_CONFIG_VERSION as v, PRE_RRS_CONFIG_VERSION as M } from "./constants/defaultConfig.js";
|
|
9
|
+
import { RECOMMENDATION_ID_ATTR as d } from "./constants/selectors.js";
|
|
10
|
+
import { regenerateMobileProductRows as w } from "./controls/main/utils.js";
|
|
11
|
+
import { ensureMobileCssRulesExist as I, setMobileLayoutOptOut as k, hasMobileLayoutOptOut as O } from "./controls/mobileLayout/cssRules.js";
|
|
12
|
+
import { RecommendationConfigService as o } from "./services/configService.js";
|
|
13
|
+
import { useRecommendationExtensionStore as f } from "./store/recommendation.js";
|
|
14
|
+
import { getDefaultTemplate as T } from "./templates/grid/template.js";
|
|
15
|
+
import { useRecommendationBlockWarning as x } from "./useRecommendationBlockWarning.js";
|
|
16
|
+
import { registerNodeConfigWriter as R } from "./utils/nodeConfigWriter.js";
|
|
17
|
+
import { refreshArrivedStrategyBlocks as H, refreshDuplicatedStrategyBlocks as $ } from "./utils/strategyCommit.js";
|
|
18
|
+
const y = C.Recommendation, g = "recommendation-block-v2", B = "hide-price";
|
|
19
|
+
let b = !1;
|
|
20
|
+
class Z extends S {
|
|
21
21
|
constructor() {
|
|
22
22
|
super();
|
|
23
23
|
/**
|
|
24
24
|
* Stores the ID generated in getTemplate() so onCreated() can reuse it.
|
|
25
25
|
* This avoids generating a new (different) ID in onCreated().
|
|
26
26
|
*/
|
|
27
|
-
|
|
27
|
+
m(this, "_pendingBlockId", null);
|
|
28
28
|
/** Ids already reset under their new name, so the deferred pass skips their stale snapshot. */
|
|
29
|
-
|
|
29
|
+
m(this, "_resetSourceIds", /* @__PURE__ */ new Set());
|
|
30
30
|
/** Ids handed to duplicates the document root does not show yet: a copied module renames all its blocks at once. */
|
|
31
|
-
|
|
31
|
+
m(this, "_unsettledDuplicateIds", /* @__PURE__ */ new Set());
|
|
32
|
+
m(this, "_arrivedNodes", []);
|
|
32
33
|
}
|
|
33
34
|
getId() {
|
|
34
|
-
return
|
|
35
|
+
return y;
|
|
35
36
|
}
|
|
36
37
|
getIcon() {
|
|
37
38
|
return "recommendation-icon";
|
|
38
39
|
}
|
|
39
40
|
getBlockCompositionType() {
|
|
40
|
-
return
|
|
41
|
+
return N.CONTAINER;
|
|
41
42
|
}
|
|
42
43
|
getName() {
|
|
43
44
|
return this.api.translate("Recommendation Block");
|
|
@@ -48,8 +49,8 @@ class Y extends E {
|
|
|
48
49
|
);
|
|
49
50
|
}
|
|
50
51
|
getSettingsPanelTitleHtml() {
|
|
51
|
-
return
|
|
52
|
-
|
|
52
|
+
return E(
|
|
53
|
+
y,
|
|
53
54
|
this.api.translate("Recommendation Block"),
|
|
54
55
|
this.api.translate("This block is switched from the Old Version to the New Version. We recommend you check the Recommendation block and test your message to ensure it works properly.")
|
|
55
56
|
);
|
|
@@ -71,8 +72,8 @@ class Y extends E {
|
|
|
71
72
|
* attribute and overwrites dynamically added classes via setAttribute.
|
|
72
73
|
*/
|
|
73
74
|
getTemplate() {
|
|
74
|
-
const
|
|
75
|
-
return this._pendingBlockId =
|
|
75
|
+
const e = this._generateNextId();
|
|
76
|
+
return this._pendingBlockId = e, T(e);
|
|
76
77
|
}
|
|
77
78
|
/**
|
|
78
79
|
* Called when a new block is dropped into the template
|
|
@@ -81,42 +82,49 @@ class Y extends E {
|
|
|
81
82
|
* and assigns the recommendation-id attribute + initializes configuration.
|
|
82
83
|
* @param node - The newly created block node
|
|
83
84
|
*/
|
|
84
|
-
onCreated(
|
|
85
|
-
const
|
|
86
|
-
if (
|
|
87
|
-
if (this._detectDuplicate(
|
|
88
|
-
this._handleDuplicate(
|
|
85
|
+
onCreated(e) {
|
|
86
|
+
const t = this._getRecommendationId(e);
|
|
87
|
+
if (t !== null && t > 0) {
|
|
88
|
+
if (this._detectDuplicate(t)) {
|
|
89
|
+
this._handleDuplicate(e, t), this._scheduleArrivalReset(e);
|
|
89
90
|
return;
|
|
90
91
|
}
|
|
91
|
-
this._pendingBlockId === null
|
|
92
|
-
|
|
93
|
-
|
|
92
|
+
const h = this._pendingBlockId === null;
|
|
93
|
+
setTimeout(() => {
|
|
94
|
+
if (this._getBlockElement(e)) {
|
|
95
|
+
if (h && this._detectDuplicate(t)) {
|
|
96
|
+
this._handleDuplicate(e, t);
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
this._queueArrivalRefresh(e);
|
|
100
|
+
}
|
|
101
|
+
}, 0), this._scheduleArrivalReset(e);
|
|
94
102
|
return;
|
|
95
103
|
}
|
|
96
104
|
const i = this._pendingBlockId ?? this._generateNextId();
|
|
97
|
-
this._pendingBlockId = null, this._assignRecommendationId(
|
|
98
|
-
const
|
|
105
|
+
this._pendingBlockId = null, this._assignRecommendationId(e, i);
|
|
106
|
+
const r = u().isFeatureEnabled("reusableRecommendationStrategy"), n = r && !o.hasConfig(e), { config: s, wasFreshDrop: a } = o.initializeConfig(
|
|
99
107
|
this.api,
|
|
100
|
-
|
|
108
|
+
e,
|
|
101
109
|
{
|
|
102
110
|
recommendationId: i,
|
|
103
|
-
configVersion:
|
|
104
|
-
...
|
|
111
|
+
configVersion: r ? v : M,
|
|
112
|
+
...n ? { partnerName: u().partnerName.value } : {},
|
|
105
113
|
// An RRS block picks a strategy, not an algorithm, and its algorithm control is
|
|
106
114
|
// hidden. Keeping the `mostPopular` default would bake a most-popular feed URL
|
|
107
115
|
// at save for a block the user never configured.
|
|
108
|
-
...
|
|
116
|
+
...n ? { strategy: "" } : {}
|
|
109
117
|
}
|
|
110
|
-
),
|
|
111
|
-
if (
|
|
118
|
+
), _ = f();
|
|
119
|
+
if (_.setCurrentBlock(i), this._stampHidePrice(e, s.priceHideIfSameAsDiscounted), a) {
|
|
112
120
|
I(this.api);
|
|
113
|
-
const
|
|
114
|
-
|
|
115
|
-
currentNode:
|
|
121
|
+
const h = this._getBlockElement(e);
|
|
122
|
+
h && (k(this.api, h, !0), w({
|
|
123
|
+
currentNode: e,
|
|
116
124
|
documentModifier: this.api.getDocumentModifier()
|
|
117
125
|
}));
|
|
118
126
|
}
|
|
119
|
-
|
|
127
|
+
_.patchCurrentBlockConfig({ language: s.language }, { triggerRefetch: !1 }), this._warnIfMultipleBlocks();
|
|
120
128
|
}
|
|
121
129
|
/**
|
|
122
130
|
* Called when the document changes or template is loaded
|
|
@@ -125,24 +133,24 @@ class Y extends E {
|
|
|
125
133
|
* and assigns recommendation-id to legacy blocks that lack one.
|
|
126
134
|
* @param node - The block node that may need migration
|
|
127
135
|
*/
|
|
128
|
-
onDocumentChanged(
|
|
129
|
-
if (!(!
|
|
130
|
-
if (!this._getRecommendationId(
|
|
131
|
-
const
|
|
132
|
-
this._assignRecommendationId(
|
|
136
|
+
onDocumentChanged(e) {
|
|
137
|
+
if (!(!e || !("getNodeConfig" in e))) {
|
|
138
|
+
if (!this._getRecommendationId(e)) {
|
|
139
|
+
const t = this._generateNextId();
|
|
140
|
+
this._assignRecommendationId(e, t), o.hasConfig(e) && o.updateConfig(
|
|
133
141
|
this.api,
|
|
134
|
-
|
|
135
|
-
{ recommendationId:
|
|
142
|
+
e,
|
|
143
|
+
{ recommendationId: t },
|
|
136
144
|
"Assign recommendation ID to legacy block"
|
|
137
145
|
);
|
|
138
146
|
}
|
|
139
|
-
this._healLingeringDuplicate(
|
|
147
|
+
this._healLingeringDuplicate(e), o.needsMigration(e) && this._migrateFromLegacy(e), this._healHidePriceAttr(e);
|
|
140
148
|
try {
|
|
141
|
-
|
|
142
|
-
const
|
|
149
|
+
b || (I(this.api), b = !0);
|
|
150
|
+
const t = o.getConfig(e), i = this._getBlockElement(e);
|
|
143
151
|
if (i) {
|
|
144
|
-
const
|
|
145
|
-
O(i) !==
|
|
152
|
+
const r = !t.mobileLayoutEnabled;
|
|
153
|
+
O(i) !== r && k(this.api, i, r);
|
|
146
154
|
}
|
|
147
155
|
} catch {
|
|
148
156
|
}
|
|
@@ -154,9 +162,9 @@ class Y extends E {
|
|
|
154
162
|
* Cleans up the per-block state from the Pinia store.
|
|
155
163
|
* @param node - The block node being deleted
|
|
156
164
|
*/
|
|
157
|
-
onDelete(
|
|
158
|
-
const
|
|
159
|
-
|
|
165
|
+
onDelete(e) {
|
|
166
|
+
const t = this._getRecommendationId(e);
|
|
167
|
+
t && f().removeBlockState(t);
|
|
160
168
|
}
|
|
161
169
|
/**
|
|
162
170
|
* Warns (dark advisory toaster) when the design holds more than one live
|
|
@@ -172,7 +180,7 @@ class Y extends E {
|
|
|
172
180
|
*/
|
|
173
181
|
_warnIfMultipleBlocks() {
|
|
174
182
|
try {
|
|
175
|
-
|
|
183
|
+
x().warnIfMultipleBlocks(this.api.getDocumentRootHtmlNode());
|
|
176
184
|
} catch {
|
|
177
185
|
}
|
|
178
186
|
}
|
|
@@ -181,21 +189,21 @@ class Y extends E {
|
|
|
181
189
|
* in the document and finding the maximum existing ID + 1.
|
|
182
190
|
*/
|
|
183
191
|
_generateNextId() {
|
|
184
|
-
let
|
|
185
|
-
const
|
|
192
|
+
let e = 0;
|
|
193
|
+
const t = /* @__PURE__ */ new Set();
|
|
186
194
|
try {
|
|
187
195
|
const i = this.api.getDocumentRoot();
|
|
188
|
-
i && "querySelectorAll" in i && i.querySelectorAll(`.${
|
|
189
|
-
if ("getAttribute" in
|
|
190
|
-
const
|
|
191
|
-
|
|
196
|
+
i && "querySelectorAll" in i && i.querySelectorAll(`.${g}`).forEach((n) => {
|
|
197
|
+
if ("getAttribute" in n) {
|
|
198
|
+
const s = n.getAttribute(d), a = s ? parseInt(s) : 0;
|
|
199
|
+
t.add(a), a > e && (e = a);
|
|
192
200
|
}
|
|
193
201
|
});
|
|
194
202
|
} catch {
|
|
195
203
|
}
|
|
196
204
|
return this._unsettledDuplicateIds.forEach((i) => {
|
|
197
|
-
|
|
198
|
-
}), Math.max(
|
|
205
|
+
t.has(i) && this._unsettledDuplicateIds.delete(i);
|
|
206
|
+
}), Math.max(e, ...this._unsettledDuplicateIds) + 1;
|
|
199
207
|
}
|
|
200
208
|
/**
|
|
201
209
|
* Drops the "already fetched" claims of a block that arrived holding a baked id
|
|
@@ -204,12 +212,34 @@ class Y extends E {
|
|
|
204
212
|
* Deferred a tick: the collision handlers rename a sibling first, and either sibling can be
|
|
205
213
|
* the renamed one depending on where the module was dropped (SD-149916).
|
|
206
214
|
*/
|
|
207
|
-
_scheduleArrivalReset(
|
|
208
|
-
|
|
209
|
-
const
|
|
210
|
-
|
|
215
|
+
_scheduleArrivalReset(e) {
|
|
216
|
+
u().isFeatureEnabled("reusableRecommendationStrategy") && setTimeout(() => {
|
|
217
|
+
const t = this._getRecommendationId(e);
|
|
218
|
+
t !== null && t > 0 && !this._resetSourceIds.delete(t) && f().resetArrivedBlock(t);
|
|
211
219
|
}, 0);
|
|
212
220
|
}
|
|
221
|
+
/**
|
|
222
|
+
* Re-reads the strategy of a block that arrived with saved cards, without waiting for a click. Stripo
|
|
223
|
+
* creates every block of an opened template or dropped module, so arrivals of one tick refresh together.
|
|
224
|
+
*/
|
|
225
|
+
_queueArrivalRefresh(e) {
|
|
226
|
+
u().isFeatureEnabled("reusableRecommendationStrategy") && (this._arrivedNodes.push(e) > 1 || setTimeout(() => {
|
|
227
|
+
const t = this._arrivedNodes;
|
|
228
|
+
this._arrivedNodes = [];
|
|
229
|
+
try {
|
|
230
|
+
this._refreshArrivedBlocks(t);
|
|
231
|
+
} catch (i) {
|
|
232
|
+
console.error("[recommendation] refreshing an arrived strategy failed", i);
|
|
233
|
+
}
|
|
234
|
+
}, 0));
|
|
235
|
+
}
|
|
236
|
+
_refreshArrivedBlocks(e) {
|
|
237
|
+
const t = e.flatMap((i) => {
|
|
238
|
+
const r = this._getRecommendationId(i), n = this._getBlockElement(i);
|
|
239
|
+
return r && n ? [{ id: r, config: o.getConfig(n) }] : [];
|
|
240
|
+
});
|
|
241
|
+
R(this.api), H(t).catch((i) => console.error("[recommendation] refreshing an arrived strategy failed", i));
|
|
242
|
+
}
|
|
213
243
|
/**
|
|
214
244
|
* Heals a duplicate that slipped past the create-time `_detectDuplicate`
|
|
215
245
|
* scan (or that was persisted by an older template before SD-142352).
|
|
@@ -222,49 +252,49 @@ class Y extends E {
|
|
|
222
252
|
* yanking the user's current selection mid-edit when the heal fires from
|
|
223
253
|
* `onDocumentChanged`.
|
|
224
254
|
*/
|
|
225
|
-
_healLingeringDuplicate(
|
|
226
|
-
const
|
|
227
|
-
if (!(
|
|
255
|
+
_healLingeringDuplicate(e) {
|
|
256
|
+
const t = this._getRecommendationId(e);
|
|
257
|
+
if (!(t === null || t <= 0))
|
|
228
258
|
try {
|
|
229
259
|
const i = this.api.getDocumentRoot();
|
|
230
260
|
if (!i || !("querySelectorAll" in i))
|
|
231
261
|
return;
|
|
232
|
-
const
|
|
233
|
-
`.${
|
|
262
|
+
const r = i.querySelectorAll(
|
|
263
|
+
`.${g}[${d}="${t}"]`
|
|
234
264
|
);
|
|
235
|
-
if (
|
|
265
|
+
if (r.length <= 1)
|
|
236
266
|
return;
|
|
237
|
-
const
|
|
238
|
-
if (!
|
|
267
|
+
const n = this._getBlockElement(e);
|
|
268
|
+
if (!n)
|
|
239
269
|
return;
|
|
240
|
-
let
|
|
241
|
-
for (let
|
|
242
|
-
if (
|
|
243
|
-
|
|
270
|
+
let s = -1;
|
|
271
|
+
for (let a = 0; a < r.length; a++)
|
|
272
|
+
if (r[a] === n) {
|
|
273
|
+
s = a;
|
|
244
274
|
break;
|
|
245
275
|
}
|
|
246
|
-
if (
|
|
276
|
+
if (s <= 0)
|
|
247
277
|
return;
|
|
248
|
-
this._reassignDuplicateId(
|
|
278
|
+
this._reassignDuplicateId(e, t);
|
|
249
279
|
} catch {
|
|
250
280
|
}
|
|
251
281
|
}
|
|
252
282
|
/** True when another block already holds the same id — Stripo's duplication signal. */
|
|
253
|
-
_detectDuplicate(
|
|
283
|
+
_detectDuplicate(e) {
|
|
254
284
|
try {
|
|
255
|
-
const
|
|
256
|
-
if (
|
|
257
|
-
return
|
|
258
|
-
`.${
|
|
285
|
+
const t = this.api.getDocumentRoot();
|
|
286
|
+
if (t && "querySelectorAll" in t)
|
|
287
|
+
return t.querySelectorAll(
|
|
288
|
+
`.${g}[${d}="${e}"]`
|
|
259
289
|
).length > 1;
|
|
260
290
|
} catch {
|
|
261
291
|
}
|
|
262
292
|
return !1;
|
|
263
293
|
}
|
|
264
294
|
/** Assigns a fresh id to a duplicated block and syncs DOM, node config and store. */
|
|
265
|
-
_handleDuplicate(
|
|
266
|
-
const i = this._reassignDuplicateId(
|
|
267
|
-
|
|
295
|
+
_handleDuplicate(e, t) {
|
|
296
|
+
const i = this._reassignDuplicateId(e, t), r = f();
|
|
297
|
+
r.cloneBlockState(t, i), r.setCurrentBlock(i), u().isFeatureEnabled("reusableRecommendationStrategy") && (this._resetSourceIds.add(t), R(this.api), $(t, i, o.getConfig(e)).catch((n) => console.error("[recommendation] refreshing a duplicated strategy failed", n))), this._warnIfMultipleBlocks();
|
|
268
298
|
}
|
|
269
299
|
/**
|
|
270
300
|
* Core id-reassignment for a duplicated block: rewrites the DOM
|
|
@@ -277,13 +307,13 @@ class Y extends E {
|
|
|
277
307
|
* effects so older bug-affected templates can self-repair without
|
|
278
308
|
* disturbing the user's current selection).
|
|
279
309
|
*/
|
|
280
|
-
_reassignDuplicateId(
|
|
281
|
-
const i = this._generateNextId(),
|
|
282
|
-
return this._unsettledDuplicateIds.add(i), this._assignRecommendationId(
|
|
310
|
+
_reassignDuplicateId(e, t) {
|
|
311
|
+
const i = this._generateNextId(), r = this._getBlockElement(e);
|
|
312
|
+
return this._unsettledDuplicateIds.add(i), this._assignRecommendationId(e, i), r && this._reassignInstanceClass(r, t, i), o.hasConfig(e) && o.updateConfig(
|
|
283
313
|
this.api,
|
|
284
|
-
|
|
314
|
+
e,
|
|
285
315
|
{ recommendationId: i },
|
|
286
|
-
`Reassign recommendation ID on duplicate (was ${
|
|
316
|
+
`Reassign recommendation ID on duplicate (was ${t})`
|
|
287
317
|
), i;
|
|
288
318
|
}
|
|
289
319
|
/**
|
|
@@ -293,12 +323,12 @@ class Y extends E {
|
|
|
293
323
|
* the source's class would both leak stylistic edits across blocks and
|
|
294
324
|
* cause the mail render to apply the source block's config to the clone.
|
|
295
325
|
*/
|
|
296
|
-
_reassignInstanceClass(
|
|
297
|
-
if (!("getAttribute" in
|
|
326
|
+
_reassignInstanceClass(e, t, i) {
|
|
327
|
+
if (!("getAttribute" in e))
|
|
298
328
|
return;
|
|
299
|
-
const
|
|
300
|
-
|
|
301
|
-
`Reassign recommendation instance class ${
|
|
329
|
+
const r = `ins-recommendation-v3-block-${t}`, n = `ins-recommendation-v3-block-${i}`, s = this.api.getDocumentModifier();
|
|
330
|
+
s.modifyHtml(e).removeClass(r).setClass(n), s.apply(new p(
|
|
331
|
+
`Reassign recommendation instance class ${r} -> ${n}`
|
|
302
332
|
));
|
|
303
333
|
}
|
|
304
334
|
/**
|
|
@@ -307,64 +337,64 @@ class Y extends E {
|
|
|
307
337
|
* HTML by getTemplate(), since Stripo's Angular rendering overwrites dynamically
|
|
308
338
|
* added classes via setAttribute.
|
|
309
339
|
*/
|
|
310
|
-
_assignRecommendationId(
|
|
311
|
-
const i = this._getBlockElement(
|
|
340
|
+
_assignRecommendationId(e, t) {
|
|
341
|
+
const i = this._getBlockElement(e);
|
|
312
342
|
if (!i)
|
|
313
343
|
return;
|
|
314
|
-
const
|
|
315
|
-
|
|
344
|
+
const r = this.api.getDocumentModifier();
|
|
345
|
+
r.modifyHtml(i).setAttribute(d, t.toString()), r.apply(new p(`Assign recommendation ID ${t}`));
|
|
316
346
|
}
|
|
317
347
|
/**
|
|
318
348
|
* Stamps the `hide-price` attribute (read by email-service at send time) on
|
|
319
349
|
* the block element from the config flag.
|
|
320
350
|
*/
|
|
321
|
-
_stampHidePrice(
|
|
322
|
-
const i = this._getBlockElement(
|
|
323
|
-
i && this.api.getDocumentModifier().modifyHtml(i).setAttribute(
|
|
351
|
+
_stampHidePrice(e, t) {
|
|
352
|
+
const i = this._getBlockElement(e);
|
|
353
|
+
i && this.api.getDocumentModifier().modifyHtml(i).setAttribute(B, String(t)).apply(new p("Stamp hide-price"));
|
|
324
354
|
}
|
|
325
355
|
/**
|
|
326
356
|
* Stamps `hide-price` from config only when the block lacks the attribute —
|
|
327
357
|
* heals templates saved before this feature without dirtying current ones.
|
|
328
358
|
*/
|
|
329
|
-
_healHidePriceAttr(
|
|
330
|
-
const
|
|
331
|
-
if (!
|
|
359
|
+
_healHidePriceAttr(e) {
|
|
360
|
+
const t = this._getBlockElement(e);
|
|
361
|
+
if (!t || !("getAttribute" in t) || t.getAttribute(B) !== null)
|
|
332
362
|
return;
|
|
333
|
-
const { priceHideIfSameAsDiscounted: i } =
|
|
334
|
-
this._stampHidePrice(
|
|
363
|
+
const { priceHideIfSameAsDiscounted: i } = o.getConfig(e);
|
|
364
|
+
this._stampHidePrice(e, i);
|
|
335
365
|
}
|
|
336
366
|
/**
|
|
337
367
|
* Gets the recommendation-id from a block node
|
|
338
368
|
*/
|
|
339
|
-
_getRecommendationId(
|
|
340
|
-
const
|
|
341
|
-
if (!
|
|
369
|
+
_getRecommendationId(e) {
|
|
370
|
+
const t = this._getBlockElement(e);
|
|
371
|
+
if (!t || !("getAttribute" in t))
|
|
342
372
|
return null;
|
|
343
|
-
const i =
|
|
373
|
+
const i = t.getAttribute(d);
|
|
344
374
|
if (!i)
|
|
345
375
|
return null;
|
|
346
|
-
const
|
|
347
|
-
return Number.isNaN(
|
|
376
|
+
const r = parseInt(i);
|
|
377
|
+
return Number.isNaN(r) ? null : r;
|
|
348
378
|
}
|
|
349
379
|
/**
|
|
350
380
|
* Gets the block element (the element with BLOCK_CLASS)
|
|
351
381
|
*/
|
|
352
|
-
_getBlockElement(
|
|
353
|
-
if ("getAttribute" in
|
|
354
|
-
const
|
|
355
|
-
if (
|
|
356
|
-
return
|
|
382
|
+
_getBlockElement(e) {
|
|
383
|
+
if ("getAttribute" in e) {
|
|
384
|
+
const t = e.getAttribute("class");
|
|
385
|
+
if (t && t.includes(g))
|
|
386
|
+
return e;
|
|
357
387
|
}
|
|
358
|
-
return "querySelector" in
|
|
388
|
+
return "querySelector" in e ? e.querySelector(`.${g}`) ?? null : null;
|
|
359
389
|
}
|
|
360
390
|
/**
|
|
361
391
|
* Migrate configuration from legacy format
|
|
362
392
|
*/
|
|
363
|
-
_migrateFromLegacy(
|
|
364
|
-
|
|
393
|
+
_migrateFromLegacy(e) {
|
|
394
|
+
o.migrateFromDataAttributes(this.api, e);
|
|
365
395
|
}
|
|
366
396
|
}
|
|
367
397
|
export {
|
|
368
|
-
|
|
369
|
-
|
|
398
|
+
y as BLOCK_ID,
|
|
399
|
+
Z as RecommendationBlock
|
|
370
400
|
};
|