@useinsider/guido 3.20.0 → 3.20.1-beta.5e7765e
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/config/compiler/itemsCompilerRules.js +21 -5
- package/dist/config/compiler/utils/itemsCompilerUtils.js +64 -17
- package/dist/config/migrator/itemsBlockMigrator.js +112 -108
- package/dist/extensions/Blocks/Items/block.js +78 -67
- package/dist/extensions/Blocks/Items/constants/cardWidth.js +20 -0
- package/dist/extensions/Blocks/Items/layouts/vertical.html.js +1 -1
- package/dist/extensions/Blocks/Recommendation/block.js +51 -44
- package/dist/extensions/Blocks/Recommendation/controls/cardComposition/index.js +103 -91
- package/dist/extensions/Blocks/Recommendation/controls/main/index.js +90 -73
- package/dist/extensions/Blocks/Recommendation/controls/main/utils.js +209 -203
- package/dist/extensions/Blocks/Recommendation/store/recommendation.js +122 -90
- package/dist/extensions/Blocks/Recommendation/utils/blockUrlConfig.js +25 -0
- package/dist/extensions/Blocks/Recommendation/utils/captureStyleTemplates.js +72 -70
- package/dist/extensions/Blocks/Recommendation/utils/compositionKeys.js +69 -60
- package/dist/extensions/Blocks/Recommendation/utils/nodeConfigWriter.js +46 -25
- package/dist/extensions/Blocks/Recommendation/utils/strategyCommit.js +40 -17
- package/dist/extensions/Blocks/Unsubscribe/block.js +82 -83
- package/dist/src/config/compiler/utils/itemsCompilerUtils.d.ts +10 -0
- package/dist/src/extensions/Blocks/Items/block.d.ts +5 -0
- package/dist/src/extensions/Blocks/Items/constants/cardWidth.d.ts +12 -0
- package/dist/src/extensions/Blocks/Recommendation/block.d.ts +2 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/cardComposition/index.d.ts +3 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/main/index.d.ts +2 -0
- package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +18 -5
- package/dist/src/extensions/Blocks/Recommendation/utils/blockUrlConfig.d.ts +4 -0
- package/dist/src/extensions/Blocks/Recommendation/utils/compositionKeys.d.ts +4 -0
- package/dist/src/extensions/Blocks/Recommendation/utils/nodeConfigWriter.d.ts +3 -1
- package/dist/src/extensions/Blocks/Recommendation/utils/strategyCommit.d.ts +7 -0
- package/dist/src/extensions/Blocks/Unsubscribe/block.d.ts +0 -2
- package/dist/src/utils/liquidProtection.d.ts +3 -0
- package/dist/utils/liquidProtection.js +5 -0
- package/dist/utils/templatePreparation.js +61 -85
- package/package.json +1 -1
|
@@ -1,42 +1,41 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
import { useToaster as
|
|
5
|
-
import { ToasterTypeOptions as
|
|
1
|
+
var A = Object.defineProperty;
|
|
2
|
+
var y = (c, o, e) => o in c ? A(c, o, { enumerable: !0, configurable: !0, writable: !0, value: e }) : c[o] = e;
|
|
3
|
+
var g = (c, o, e) => y(c, typeof o != "symbol" ? o + "" : o, e);
|
|
4
|
+
import { useToaster as T } from "../../../composables/useToaster.js";
|
|
5
|
+
import { ToasterTypeOptions as I } from "../../../enums/toaster.js";
|
|
6
6
|
import { PAGE_TYPES as h } from "../../../enums/unsubscribe.js";
|
|
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
|
|
7
|
+
import { useEditorStore as L } from "../../../stores/editor.js";
|
|
8
|
+
import { useUnsubscribeStore as a } from "../../../stores/unsubscribe.js";
|
|
9
|
+
import { Block as C, BlockCompositionType as v, ContextActionType as S, ModificationDescription as u, BlockType as N } from "../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
|
|
10
|
+
import { getDefaultTemplate as U } from "./template.js";
|
|
11
|
+
import { UNSUBSCRIBE_BLOCK_SELECTOR as B, DATA_ATTRIBUTES as n, UNSUBSCRIBE_EVENTS as m } from "./utils/constants.js";
|
|
12
|
+
import { parsePageList as f } from "./utils/utils.js";
|
|
13
|
+
const R = "unsubscribe-block", E = 'a[data-unsubscribe-link="true"]', D = "{{ins-unsubscribe-link}}", w = "https://academy.insiderone.com/docs/adding-unsubscribe-pages-into-emails", P = "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.", x = {
|
|
14
14
|
[h.GLOBAL_UNSUBSCRIBE]: "{{ins-global-unsubscribe-link}}",
|
|
15
15
|
[h.SUBSCRIPTION_PREFERENCE_CENTER]: "{{ins-preferences-unsubscribe-link}}"
|
|
16
|
-
},
|
|
17
|
-
|
|
16
|
+
}, G = 3;
|
|
17
|
+
let d = null, p = null;
|
|
18
|
+
class j extends C {
|
|
18
19
|
constructor() {
|
|
19
20
|
super();
|
|
20
|
-
|
|
21
|
-
a(this, "cancelEventListener", null);
|
|
22
|
-
a(this, "currentNode");
|
|
21
|
+
g(this, "currentNode");
|
|
23
22
|
// Per-block "did this instance have a link last time we saw it?" tracking.
|
|
24
23
|
// Keyed by the stable `data-unsubscribe-block-id` we assign, because
|
|
25
24
|
// ImmutableHtmlNode instances are recreated on every document mutation and
|
|
26
25
|
// can't be used as Map keys directly. A singleton boolean here would be
|
|
27
26
|
// polluted across blocks since Stripo fires onDocumentChanged per-instance.
|
|
28
|
-
|
|
27
|
+
g(this, "linkStateByBlockId", /* @__PURE__ */ new Map());
|
|
29
28
|
// Per-block prepend retry counter for the leading text guard (SD-143097).
|
|
30
|
-
|
|
29
|
+
g(this, "guardAttemptsByBlockId", /* @__PURE__ */ new Map());
|
|
31
30
|
}
|
|
32
31
|
getId() {
|
|
33
|
-
return
|
|
32
|
+
return R;
|
|
34
33
|
}
|
|
35
34
|
getIcon() {
|
|
36
35
|
return "unsubscribe-icon";
|
|
37
36
|
}
|
|
38
37
|
getBlockCompositionType() {
|
|
39
|
-
return
|
|
38
|
+
return v.BLOCK;
|
|
40
39
|
}
|
|
41
40
|
getName() {
|
|
42
41
|
return this.api.translate("Unsubscribe Block");
|
|
@@ -45,16 +44,16 @@ class W extends T {
|
|
|
45
44
|
return this.api.translate("Unsubscribe Block Description");
|
|
46
45
|
}
|
|
47
46
|
getTemplate() {
|
|
48
|
-
return
|
|
47
|
+
return U();
|
|
49
48
|
}
|
|
50
49
|
getContextActionsIds() {
|
|
51
|
-
return [
|
|
50
|
+
return [S.MOVE, S.REMOVE];
|
|
52
51
|
}
|
|
53
52
|
onSelect(e) {
|
|
54
|
-
if (this.currentNode = e,
|
|
53
|
+
if (this.currentNode = e, L().isPreviewModeOpen)
|
|
55
54
|
return;
|
|
56
55
|
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 && (
|
|
56
|
+
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
57
|
}
|
|
59
58
|
onCreated(e) {
|
|
60
59
|
this._ensureLeadingTextGuard(e);
|
|
@@ -62,7 +61,7 @@ class W extends T {
|
|
|
62
61
|
onDocumentInit() {
|
|
63
62
|
try {
|
|
64
63
|
const e = this.api.getDocumentRoot();
|
|
65
|
-
e && "querySelectorAll" in e && e.querySelectorAll(
|
|
64
|
+
e && "querySelectorAll" in e && e.querySelectorAll(B).forEach((t) => {
|
|
66
65
|
this._ensureLeadingTextGuard(t);
|
|
67
66
|
});
|
|
68
67
|
} catch {
|
|
@@ -73,8 +72,8 @@ class W extends T {
|
|
|
73
72
|
const t = this._getOrAssignBlockId(e);
|
|
74
73
|
if (!t)
|
|
75
74
|
return;
|
|
76
|
-
const
|
|
77
|
-
this.linkStateByBlockId.get(t) === !0 && !
|
|
75
|
+
const i = this._hasUnsubscribeLink(e);
|
|
76
|
+
this.linkStateByBlockId.get(t) === !0 && !i && this._warnLinkRemoved(), this.linkStateByBlockId.set(t, i);
|
|
78
77
|
}
|
|
79
78
|
onDelete(e) {
|
|
80
79
|
this._removeEventListeners(), this._removeBlockTemplatesFromStore(e), this._resetStoreState();
|
|
@@ -95,27 +94,27 @@ class W extends T {
|
|
|
95
94
|
const t = e.querySelector(E);
|
|
96
95
|
if (!t)
|
|
97
96
|
return;
|
|
98
|
-
let
|
|
97
|
+
let i = t, r = i.parent();
|
|
99
98
|
for (; r && "getTagName" in r && r.getTagName().toLowerCase() !== "p"; )
|
|
100
|
-
|
|
99
|
+
i = r, r = r.parent();
|
|
101
100
|
if (!r || !("getTagName" in r) || r.getTagName().toLowerCase() !== "p")
|
|
102
101
|
return;
|
|
103
|
-
const
|
|
104
|
-
if (!!(
|
|
105
|
-
const
|
|
106
|
-
|
|
102
|
+
const s = i.previousSibling();
|
|
103
|
+
if (!!(s && s.getType() === "text" && s.getTextContent())) {
|
|
104
|
+
const b = this._readBlockId(e);
|
|
105
|
+
b && this.guardAttemptsByBlockId.delete(b);
|
|
107
106
|
return;
|
|
108
107
|
}
|
|
109
|
-
const
|
|
110
|
-
if (!
|
|
108
|
+
const k = this._getOrAssignBlockId(e);
|
|
109
|
+
if (!k)
|
|
111
110
|
return;
|
|
112
|
-
const
|
|
113
|
-
if (!(
|
|
114
|
-
this.guardAttemptsByBlockId.set(
|
|
111
|
+
const _ = this.guardAttemptsByBlockId.get(k) ?? 0;
|
|
112
|
+
if (!(_ >= G)) {
|
|
113
|
+
this.guardAttemptsByBlockId.set(k, _ + 1);
|
|
115
114
|
try {
|
|
116
|
-
this.api.getDocumentModifier().modifyHtml(r).prepend(" ").apply(new
|
|
117
|
-
} catch (
|
|
118
|
-
console.warn("[UnsubscribeBlock] Failed to ensure link text guard:",
|
|
115
|
+
this.api.getDocumentModifier().modifyHtml(r).prepend(" ").apply(new u("Ensure unsubscribe link text guard"));
|
|
116
|
+
} catch (b) {
|
|
117
|
+
console.warn("[UnsubscribeBlock] Failed to ensure link text guard:", b);
|
|
119
118
|
}
|
|
120
119
|
}
|
|
121
120
|
}
|
|
@@ -137,13 +136,13 @@ class W extends T {
|
|
|
137
136
|
return t;
|
|
138
137
|
if (!("getAttribute" in e))
|
|
139
138
|
return null;
|
|
140
|
-
const
|
|
139
|
+
const i = this._generateNextBlockId();
|
|
141
140
|
try {
|
|
142
|
-
this.api.getDocumentModifier().modifyHtml(e).setAttribute(n.BLOCK_ID,
|
|
141
|
+
this.api.getDocumentModifier().modifyHtml(e).setAttribute(n.BLOCK_ID, i).apply(new u(`Assign unsubscribe block id ${i}`));
|
|
143
142
|
} catch (r) {
|
|
144
143
|
return console.warn("[UnsubscribeBlock] Failed to assign block id:", r), null;
|
|
145
144
|
}
|
|
146
|
-
return
|
|
145
|
+
return i;
|
|
147
146
|
}
|
|
148
147
|
/**
|
|
149
148
|
* Generates a unique id by scanning the document for the highest existing
|
|
@@ -154,10 +153,10 @@ class W extends T {
|
|
|
154
153
|
let e = 0;
|
|
155
154
|
try {
|
|
156
155
|
const t = this.api.getDocumentRoot();
|
|
157
|
-
t && "querySelectorAll" in t && t.querySelectorAll(
|
|
156
|
+
t && "querySelectorAll" in t && t.querySelectorAll(B).forEach((r) => {
|
|
158
157
|
if ("getAttribute" in r) {
|
|
159
|
-
const
|
|
160
|
-
|
|
158
|
+
const s = r.getAttribute(n.BLOCK_ID), l = s ? parseInt(s) : 0;
|
|
159
|
+
l > e && (e = l);
|
|
161
160
|
}
|
|
162
161
|
});
|
|
163
162
|
} catch {
|
|
@@ -166,14 +165,14 @@ class W extends T {
|
|
|
166
165
|
}
|
|
167
166
|
_warnLinkRemoved() {
|
|
168
167
|
try {
|
|
169
|
-
const { showToaster: e } =
|
|
168
|
+
const { showToaster: e } = T();
|
|
170
169
|
e({
|
|
171
|
-
type:
|
|
172
|
-
message: this.api.translate(
|
|
170
|
+
type: I.Warning,
|
|
171
|
+
message: this.api.translate(P),
|
|
173
172
|
actionButton: {
|
|
174
173
|
text: this.api.translate("Visit Academy"),
|
|
175
174
|
onClick: () => {
|
|
176
|
-
window.open(
|
|
175
|
+
window.open(w, "_blank", "noopener,noreferrer");
|
|
177
176
|
}
|
|
178
177
|
}
|
|
179
178
|
});
|
|
@@ -182,28 +181,28 @@ class W extends T {
|
|
|
182
181
|
}
|
|
183
182
|
}
|
|
184
183
|
_setupSelectEventListener() {
|
|
185
|
-
this._removeSelectEventListener(),
|
|
186
|
-
const t = e, { collectionType:
|
|
187
|
-
this._updateBlock(
|
|
188
|
-
}, document.addEventListener(
|
|
184
|
+
this._removeSelectEventListener(), d = (e) => {
|
|
185
|
+
const t = e, { collectionType: i, selectedPages: r } = t.detail;
|
|
186
|
+
this._updateBlock(i, r.join(","));
|
|
187
|
+
}, document.addEventListener(m.SELECT, d);
|
|
189
188
|
}
|
|
190
189
|
_removeSelectEventListener() {
|
|
191
|
-
|
|
190
|
+
d && (document.removeEventListener(m.SELECT, d), d = null);
|
|
192
191
|
}
|
|
193
192
|
_setupCancelEventListener(e) {
|
|
194
|
-
this._removeCancelEventListener(),
|
|
195
|
-
const { detail:
|
|
196
|
-
((
|
|
197
|
-
}, document.addEventListener(
|
|
193
|
+
this._removeCancelEventListener(), p = (t) => {
|
|
194
|
+
const { detail: i } = t;
|
|
195
|
+
((i == null ? void 0 : i.blockId) ?? null) === e && this._handleCancel();
|
|
196
|
+
}, document.addEventListener(m.CANCEL, p);
|
|
198
197
|
}
|
|
199
198
|
_removeCancelEventListener() {
|
|
200
|
-
|
|
199
|
+
p && (document.removeEventListener(m.CANCEL, p), p = null);
|
|
201
200
|
}
|
|
202
201
|
_handleCancel() {
|
|
203
202
|
try {
|
|
204
203
|
if (!this.currentNode)
|
|
205
204
|
return;
|
|
206
|
-
this.api.getDocumentModifier().modifyHtml(this.currentNode).replaceWith(`<${
|
|
205
|
+
this.api.getDocumentModifier().modifyHtml(this.currentNode).replaceWith(`<${N.EMPTY_CONTAINER}/>`).apply(new u("Removed unsubscribe block due to cancel"));
|
|
207
206
|
} catch (e) {
|
|
208
207
|
console.warn("[UnsubscribeBlock] Failed to remove unsubscribe block:", e);
|
|
209
208
|
}
|
|
@@ -214,32 +213,32 @@ class W extends T {
|
|
|
214
213
|
_updateBlock(e, t) {
|
|
215
214
|
if (!this.currentNode || !("querySelector" in this.currentNode))
|
|
216
215
|
return;
|
|
217
|
-
const
|
|
218
|
-
if (!
|
|
216
|
+
const i = this.currentNode.querySelector(E);
|
|
217
|
+
if (!i)
|
|
219
218
|
return;
|
|
220
219
|
const r = this._getMergeTag(e);
|
|
221
|
-
this.api.getDocumentModifier().modifyHtml(
|
|
220
|
+
this.api.getDocumentModifier().modifyHtml(i).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
221
|
}
|
|
223
222
|
_getMergeTag(e) {
|
|
224
|
-
return
|
|
223
|
+
return x[e] ?? D;
|
|
225
224
|
}
|
|
226
225
|
_openDrawer() {
|
|
227
226
|
if (!(this.currentNode && this.currentNode.getAttribute("data-unsubscribe-page-type")))
|
|
228
227
|
try {
|
|
229
|
-
const e =
|
|
228
|
+
const e = a();
|
|
230
229
|
e.typeSelectionDrawerStatus = !0;
|
|
231
230
|
} catch (e) {
|
|
232
231
|
console.error("[UnsubscribeBlock] Failed to open drawer:", e);
|
|
233
232
|
}
|
|
234
233
|
}
|
|
235
234
|
_checkExistingBlocks() {
|
|
236
|
-
const e =
|
|
237
|
-
e.isGlobalUnsubscribeDisabled = !1, e.isSubscriptionPreferencesCenterDisabled = !1, this.api.getDocumentRoot().querySelectorAll(
|
|
238
|
-
if ("getAttribute" in
|
|
239
|
-
const r =
|
|
235
|
+
const e = a();
|
|
236
|
+
e.isGlobalUnsubscribeDisabled = !1, e.isSubscriptionPreferencesCenterDisabled = !1, this.api.getDocumentRoot().querySelectorAll(B).forEach((i) => {
|
|
237
|
+
if ("getAttribute" in i) {
|
|
238
|
+
const r = i.getAttribute(n.PAGE_TYPE);
|
|
240
239
|
if (r) {
|
|
241
|
-
const
|
|
242
|
-
|
|
240
|
+
const s = Number(r);
|
|
241
|
+
s === h.GLOBAL_UNSUBSCRIBE ? e.isGlobalUnsubscribeDisabled = !0 : s === h.SUBSCRIPTION_PREFERENCE_CENTER && (e.isSubscriptionPreferencesCenterDisabled = !0);
|
|
243
242
|
}
|
|
244
243
|
}
|
|
245
244
|
});
|
|
@@ -247,14 +246,14 @@ class W extends T {
|
|
|
247
246
|
async _loadBlockState(e) {
|
|
248
247
|
if (!("getAttribute" in e))
|
|
249
248
|
return;
|
|
250
|
-
const t = e.getAttribute(n.PAGE_TYPE),
|
|
251
|
-
if (!t || !
|
|
249
|
+
const t = e.getAttribute(n.PAGE_TYPE), i = e.getAttribute(n.PAGE_LIST);
|
|
250
|
+
if (!t || !i)
|
|
252
251
|
return;
|
|
253
|
-
const r =
|
|
254
|
-
await r.fetchTemplates(), r.setCollectionWithoutAutoSelection(
|
|
252
|
+
const r = a(), s = Number(t), l = f(i);
|
|
253
|
+
await r.fetchTemplates(), r.setCollectionWithoutAutoSelection(s), r.loadSelectedTemplates(l);
|
|
255
254
|
}
|
|
256
255
|
_resetStoreState() {
|
|
257
|
-
|
|
256
|
+
a().$reset();
|
|
258
257
|
}
|
|
259
258
|
_removeBlockTemplatesFromStore(e) {
|
|
260
259
|
if (!("getAttribute" in e))
|
|
@@ -262,11 +261,11 @@ class W extends T {
|
|
|
262
261
|
const t = e.getAttribute(n.PAGE_LIST);
|
|
263
262
|
if (!t)
|
|
264
263
|
return;
|
|
265
|
-
const
|
|
266
|
-
|
|
264
|
+
const i = a(), r = f(t);
|
|
265
|
+
i.removeUnsubscribePages(r);
|
|
267
266
|
}
|
|
268
267
|
}
|
|
269
268
|
export {
|
|
270
|
-
|
|
271
|
-
|
|
269
|
+
R as UNSUBSCRIBE_BLOCK_ID,
|
|
270
|
+
j as UnsubscribeBlock
|
|
272
271
|
};
|
|
@@ -10,3 +10,13 @@ export declare const MSO_ITEMS_HIDE_END = "MSO_ITEMS_HIDE_END";
|
|
|
10
10
|
* and collapse them inline for web-engine Outlook.
|
|
11
11
|
*/
|
|
12
12
|
export declare function wrapHiddenPriceTdsForOutlook(html: string): string;
|
|
13
|
+
/**
|
|
14
|
+
* Export safety net for a zero Items width: the wrapper gets the 100% pin, the cell's zero is
|
|
15
|
+
* dropped so it keeps its column width (a pin there overflows 33%/50% columns).
|
|
16
|
+
*/
|
|
17
|
+
export declare function normalizeItemsBlockWidths(html: string): string;
|
|
18
|
+
/**
|
|
19
|
+
* The mobile `.adapt-img { width: 100% }` rule sizes the horizontal thumbnail by its auto-width column,
|
|
20
|
+
* so it grows in a roomy row and collapses to nothing in a crowded one — bound it to [default, width].
|
|
21
|
+
*/
|
|
22
|
+
export declare function lockHorizontalItemImageWidths(html: string): string;
|
|
@@ -46,6 +46,11 @@ export declare class ItemsBlock extends Block {
|
|
|
46
46
|
* relies on this td-level fallback in pairProductVariables.
|
|
47
47
|
*/
|
|
48
48
|
private _stampProductTdDomAttributes;
|
|
49
|
+
/**
|
|
50
|
+
* Repairs a saved module's collapsed card into the state the load migrator produces. Acts only
|
|
51
|
+
* on a zero width, so Stripo's non-zero drop-time width never triggers it and a healed block no-ops.
|
|
52
|
+
*/
|
|
53
|
+
private _healCollapsedWidths;
|
|
49
54
|
/**
|
|
50
55
|
* Whether a currency self-heal pass should run for this block (SD-147588). The only gate here is
|
|
51
56
|
* once-per-session: heal each instance at most once, so the auto-fix can't fight undo (undo
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare const PRODUCT_TD_SELECTOR = ".ins-product-td";
|
|
2
|
+
export declare const PRODUCT_WRAPPER_SELECTOR = ".ins-product-wrapper";
|
|
3
|
+
/** The declaration `layouts/vertical.html` and `layouts/horizontal.html` ship inline. */
|
|
4
|
+
export declare const WIDTH_PIN_DECLARATION = "width: 100%";
|
|
5
|
+
/** True for a `width` attribute value that renders the card zero-wide (`0`, `0px`, `0%`). */
|
|
6
|
+
export declare const isZeroWidthValue: (value?: string | null) => boolean;
|
|
7
|
+
/** True when an inline style declares a zero `width` (ignores `max-width` / `min-width`). */
|
|
8
|
+
export declare const hasZeroWidthDeclaration: (style: string) => boolean;
|
|
9
|
+
/** Rewrites a zero width to the pin or appends it; a non-zero width is kept. Idempotent. */
|
|
10
|
+
export declare const withWidthPin: (style: string) => string;
|
|
11
|
+
/** Drops a zero `width` declaration; the product cell must inherit its column width, not be pinned. */
|
|
12
|
+
export declare const withoutZeroWidth: (style: string) => string;
|
|
@@ -17,6 +17,8 @@ export declare class RecommendationBlock extends Block {
|
|
|
17
17
|
private _pendingBlockId;
|
|
18
18
|
/** Ids already reset under their new name, so the deferred pass skips their stale snapshot. */
|
|
19
19
|
private _resetSourceIds;
|
|
20
|
+
/** Ids handed to duplicates the document root does not show yet: a copied module renames all its blocks at once. */
|
|
21
|
+
private _unsettledDuplicateIds;
|
|
20
22
|
constructor();
|
|
21
23
|
getId(): string;
|
|
22
24
|
getIcon(): string;
|
|
@@ -189,6 +189,9 @@ export declare class RecommendationCardCompositionControl extends CommonControl
|
|
|
189
189
|
*/
|
|
190
190
|
private _buildCompositionHtml;
|
|
191
191
|
private _applyVisibilityToBlock;
|
|
192
|
+
/** Inline "Product Prices" group row is tagged with whichever price comes first, so it drives both keys. */
|
|
193
|
+
private _resolveVisibilityKeys;
|
|
194
|
+
private _isInlinePrices;
|
|
192
195
|
private _applyTitleVisibilityToBlock;
|
|
193
196
|
private _resolveTitleInjection;
|
|
194
197
|
private _readTitleHtml;
|
|
@@ -139,6 +139,8 @@ export declare class RecommendationBlockControl extends CommonControl {
|
|
|
139
139
|
* fails when the size actually changed.
|
|
140
140
|
*/
|
|
141
141
|
private _debouncedRegenerateWithProducts;
|
|
142
|
+
/** Draws the current block's products into this panel's node. */
|
|
143
|
+
private _regenerateWithProducts;
|
|
142
144
|
/**
|
|
143
145
|
* Listen to store changes that require product refresh or regeneration.
|
|
144
146
|
*
|
|
@@ -620,12 +620,25 @@ export declare const useRecommendationExtensionStore: import("pinia").StoreDefin
|
|
|
620
620
|
fetchRecommendationProducts(): Promise<void>;
|
|
621
621
|
_doFetchProducts(): Promise<void>;
|
|
622
622
|
/**
|
|
623
|
-
* Block-scoped counterpart of `fetchRecommendationProducts`, which only
|
|
624
|
-
*
|
|
625
|
-
*
|
|
623
|
+
* Block-scoped counterpart of `fetchRecommendationProducts`, which only serves the selected block:
|
|
624
|
+
* the legacy conversion and the duplicate refresh must reach a block that may no longer be selected.
|
|
625
|
+
* @returns whether real products arrived
|
|
626
626
|
*/
|
|
627
|
-
fetchStrategyProductsForBlock(blockId: number
|
|
628
|
-
|
|
627
|
+
fetchStrategyProductsForBlock(blockId: number, options?: {
|
|
628
|
+
keepOnFailure?: boolean;
|
|
629
|
+
}): Promise<boolean>;
|
|
630
|
+
/**
|
|
631
|
+
* Reloads a block's products and adopts its strategy's current size, which may have
|
|
632
|
+
* moved since the block was assigned.
|
|
633
|
+
* @returns whether a fresh listing holds the strategy and its products arrived
|
|
634
|
+
*/
|
|
635
|
+
refreshStrategyBlock(blockId: number): Promise<boolean>;
|
|
636
|
+
_doFetchStrategyProducts(blockId: number, options?: {
|
|
637
|
+
keepOnFailure?: boolean;
|
|
638
|
+
}): Promise<boolean>;
|
|
639
|
+
_loadStrategyProducts(blockId: number, token: number, { keepOnFailure }: {
|
|
640
|
+
keepOnFailure?: boolean;
|
|
641
|
+
}): Promise<boolean>;
|
|
629
642
|
_setBlockProducts(blockId: number, products: RecommendationProduct[], size: number): void;
|
|
630
643
|
}>;
|
|
631
644
|
export {};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { PerBlockUrlConfig } from '../store/recommendation';
|
|
2
|
+
import type { RecommendationNodeConfig } from '../types/nodeConfig';
|
|
3
|
+
/** Maps a persisted node config onto the store's per-block seed, defaulting what an older config lacks. */
|
|
4
|
+
export declare function toBlockUrlConfig(config: Partial<RecommendationNodeConfig>): PerBlockUrlConfig;
|
|
@@ -33,6 +33,10 @@ export declare function normalizeCustomAttrValues(values: string[], blockNode?:
|
|
|
33
33
|
* value, which stays correct on rows still tagged with a legacy bare name.
|
|
34
34
|
*/
|
|
35
35
|
export declare function resolveRowCompositionKey(row: ImmutableHtmlNode): string | null;
|
|
36
|
+
/** Inline price mode renders sale + original price in ONE row, tagged with whichever comes first. */
|
|
37
|
+
export declare function isMergedInlinePriceRow(row: ImmutableHtmlNode | null | undefined): boolean;
|
|
38
|
+
/** Keys whose visibility a row carries: the merged inline price row stands for both prices. */
|
|
39
|
+
export declare function resolveRowVisibilityKeys(row: ImmutableHtmlNode): string[];
|
|
36
40
|
/**
|
|
37
41
|
* Finds an attribute row by composition key, tolerating rows still tagged with the
|
|
38
42
|
* legacy bare-name key. Custom candidates are validated against their `product-attr`,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { DocumentModifier } from '../services/configService';
|
|
2
|
-
import type { PartialNodeConfig } from '../types/nodeConfig';
|
|
2
|
+
import type { PartialNodeConfig, RecommendationNodeConfig } from '../types/nodeConfig';
|
|
3
3
|
import type { RecommendationProduct } from '@@/Types/recommendation';
|
|
4
4
|
import { ImmutableHtmlNode } from '@stripoinc/ui-editor-extensions';
|
|
5
5
|
interface ConfigWriterApi {
|
|
@@ -13,6 +13,8 @@ interface ConfigWriterApi {
|
|
|
13
13
|
* itself is torn down.
|
|
14
14
|
*/
|
|
15
15
|
export declare function registerNodeConfigWriter(api: ConfigWriterApi): void;
|
|
16
|
+
/** Reads the persisted config of every node carrying a block id (two while a duplicate still shares it). */
|
|
17
|
+
export declare function readBlockNodeConfigs(blockId: number): RecommendationNodeConfig[];
|
|
16
18
|
/**
|
|
17
19
|
* Commits a config change and its product re-render straight to the document,
|
|
18
20
|
* bypassing the settings panel.
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
import type { RecommendationNodeConfig } from '../types/nodeConfig';
|
|
2
|
+
/**
|
|
3
|
+
* Re-reads the strategy of a duplicated block and its source and redraws both: the clone copies the
|
|
4
|
+
* cards the source last drew, so a strategy edited since then only reached a block once selected (SD-153266).
|
|
5
|
+
* @param config - the arriving block's persisted config; seeds either block its store entry does not match
|
|
6
|
+
*/
|
|
7
|
+
export declare function refreshDuplicatedStrategyBlocks(sourceId: number, duplicateId: number, config: RecommendationNodeConfig): Promise<void>;
|
|
1
8
|
/**
|
|
2
9
|
* Writes a strategy change and its products straight to the document, without the settings panel.
|
|
3
10
|
*
|
|
@@ -2,8 +2,6 @@ import type { ImmutableHtmlElementNode, ImmutableHtmlNode } from '@stripoinc/ui-
|
|
|
2
2
|
import { Block, BlockCompositionType } from '@stripoinc/ui-editor-extensions';
|
|
3
3
|
export declare const UNSUBSCRIBE_BLOCK_ID = "unsubscribe-block";
|
|
4
4
|
export declare class UnsubscribeBlock extends Block {
|
|
5
|
-
private selectEventListener;
|
|
6
|
-
private cancelEventListener;
|
|
7
5
|
private currentNode?;
|
|
8
6
|
private linkStateByBlockId;
|
|
9
7
|
private guardAttemptsByBlockId;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
const p = (l) => l.split(/(<!--[\s\S]*?-->)/).map((e, c) => c % 2 ? e : e.replaceAll("{%", "<!--lq{%").replaceAll("%}", "%}lq-->")).join(""), r = (l) => l.replaceAll("<!--lq{%", "{%").replaceAll("%}lq-->", "%}").replaceAll("<!--lq{%", "{%").replaceAll("%}lq-->", "%}");
|
|
2
|
+
export {
|
|
3
|
+
p as protectLiquid,
|
|
4
|
+
r as restoreLiquid
|
|
5
|
+
};
|