@useinsider/guido 3.12.0-beta.1b68f97 → 3.12.0-beta.29b526b
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/README.md +0 -4
- package/dist/@types/config/schemas.js +50 -63
- package/dist/components/organisms/email-preview/desktop-preview/DesktopPreview.vue.js +1 -1
- package/dist/components/organisms/email-preview/desktop-preview/DesktopPreview.vue2.js +8 -8
- package/dist/components/organisms/email-preview/mobile-preview/ContentView.vue.js +5 -5
- package/dist/components/organisms/email-preview/mobile-preview/ContentView.vue2.js +10 -10
- package/dist/composables/useEmailTemplateApplier.js +49 -30
- package/dist/composables/usePreviewInteractionGuard.js +11 -36
- package/dist/composables/useRecommendationPreview.js +60 -61
- package/dist/composables/useSave.js +24 -43
- package/dist/extensions/Blocks/Recommendation/constants/controlIds.js +1 -1
- package/dist/extensions/Blocks/Recommendation/extension.js +21 -23
- package/dist/extensions/Blocks/Recommendation/settingsPanel.js +40 -41
- package/dist/extensions/Blocks/Unsubscribe/utils/constants.js +2 -3
- package/dist/extensions/Blocks/controlFactories.js +75 -125
- package/dist/guido.css +1 -1
- package/dist/src/@types/config/schemas.d.ts +0 -29
- package/dist/src/composables/useConfig.d.ts +0 -4
- package/dist/src/composables/useEmailTemplateApplier.d.ts +5 -0
- package/dist/src/composables/usePreviewInteractionGuard.d.ts +1 -1
- package/dist/src/extensions/Blocks/Recommendation/constants/controlIds.d.ts +0 -1
- package/dist/src/extensions/Blocks/Recommendation/controls/index.d.ts +0 -1
- package/dist/src/extensions/Blocks/Unsubscribe/utils/constants.d.ts +0 -1
- package/dist/src/extensions/Blocks/controlFactories.d.ts +0 -36
- package/dist/src/stores/config.d.ts +0 -36
- package/package.json +1 -1
- package/dist/composables/validators/useAllowlistValidator.js +0 -31
- package/dist/extensions/Blocks/Recommendation/controls/blockBackground/index.js +0 -10
- package/dist/src/composables/validators/useAllowlistValidator.d.ts +0 -9
- package/dist/src/extensions/Blocks/Recommendation/controls/blockBackground/index.d.ts +0 -14
- package/dist/src/utils/urlSchemes.d.ts +0 -6
- package/dist/utils/urlSchemes.js +0 -4
package/README.md
CHANGED
|
@@ -161,15 +161,11 @@ const config: GuidoConfigInput = {
|
|
|
161
161
|
modulesDisabled?: boolean, // Default: false - Disable modules panel
|
|
162
162
|
liquidSyntax?: boolean, // Default: false - Enable Liquid template syntax
|
|
163
163
|
autosave?: boolean, // Default: false - Show the Auto Save toggle in the header. See wiki/AUTOSAVE.md.
|
|
164
|
-
allowlistEnabled?: boolean, // Default: false - Pre-save domain-allowlist check (opt-in). Pair with callbacks.resolveAllowlistToast.
|
|
165
164
|
},
|
|
166
165
|
|
|
167
166
|
// Optional: Callbacks
|
|
168
167
|
callbacks?: {
|
|
169
168
|
externalValidation?: (data: SavedTemplateDetails) => Promise<boolean>, // Return false to cancel save
|
|
170
|
-
// Supplies the block toaster when features.allowlistEnabled blocks a save on a non-allowlisted domain.
|
|
171
|
-
// The host owns role-gating, the settings deep-link, and copy; Guido renders the result. Return null/void to block silently.
|
|
172
|
-
resolveAllowlistToast?: (blockedDomains: string[]) => { message: string, actionButton?: { text: string, onClick: () => void } } | null | void,
|
|
173
169
|
},
|
|
174
170
|
|
|
175
171
|
// Optional: Block configuration
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ModuleFolderDefaults as y } from "../../enums/defaults.js";
|
|
2
|
-
import { object as a, number as n, optional as e, string as t, picklist as
|
|
2
|
+
import { object as a, number as n, optional as e, string as t, picklist as l, pipe as p, minLength as b, custom as f, boolean as o, array as c, record as k, fallback as C, literal as i, looseObject as g, variant as R, union as h, unknown as s, lazy as T } from "../../node_modules/valibot/dist/index.js";
|
|
3
3
|
const d = {
|
|
4
4
|
/** Promotional/marketing emails */
|
|
5
5
|
PROMOTIONAL: 1,
|
|
@@ -30,7 +30,7 @@ const d = {
|
|
|
30
30
|
name: t(),
|
|
31
31
|
/** Fallback font family (e.g., "serif" or "sans-serif") */
|
|
32
32
|
family: t()
|
|
33
|
-
}),
|
|
33
|
+
}), L = a({
|
|
34
34
|
/** Partner/organization name (required) */
|
|
35
35
|
name: p(
|
|
36
36
|
t(),
|
|
@@ -38,7 +38,7 @@ const d = {
|
|
|
38
38
|
),
|
|
39
39
|
/** Product type identifier */
|
|
40
40
|
productType: e(
|
|
41
|
-
|
|
41
|
+
l([
|
|
42
42
|
r.EMAIL,
|
|
43
43
|
r.ARCHITECT,
|
|
44
44
|
r.UNSUBSCRIBE_PAGES
|
|
@@ -47,14 +47,14 @@ const d = {
|
|
|
47
47
|
),
|
|
48
48
|
/** Message type (promotional or transactional) */
|
|
49
49
|
messageType: e(
|
|
50
|
-
|
|
50
|
+
l([d.PROMOTIONAL, d.TRANSACTIONAL]),
|
|
51
51
|
d.PROMOTIONAL
|
|
52
52
|
),
|
|
53
53
|
/** Display name for the current user */
|
|
54
54
|
username: e(t(), "Guido User"),
|
|
55
55
|
/** Fallback font settings from partner settings — used to match backend size calculation */
|
|
56
56
|
fallbackFont: e(I)
|
|
57
|
-
}),
|
|
57
|
+
}), v = a({
|
|
58
58
|
/** Display text for the dynamic content */
|
|
59
59
|
text: t(),
|
|
60
60
|
/** Template variable value (e.g., {{username}}) */
|
|
@@ -68,40 +68,40 @@ const d = {
|
|
|
68
68
|
value: t()
|
|
69
69
|
})
|
|
70
70
|
)
|
|
71
|
-
}),
|
|
71
|
+
}), S = T(() => g({
|
|
72
72
|
text: e(t()),
|
|
73
73
|
// eslint-disable-next-line camelcase -- backend field name
|
|
74
74
|
tag_text: e(t()),
|
|
75
75
|
value: e(t()),
|
|
76
|
-
children: e(c(
|
|
76
|
+
children: e(c(S)),
|
|
77
77
|
// eslint-disable-next-line camelcase -- backend field name
|
|
78
|
-
select_items: e(c(
|
|
79
|
-
})),
|
|
78
|
+
select_items: e(c(S))
|
|
79
|
+
})), P = k(
|
|
80
80
|
t(),
|
|
81
|
-
C(c(
|
|
82
|
-
),
|
|
81
|
+
C(c(S), [])
|
|
82
|
+
), D = g({
|
|
83
83
|
/** Block ID (matches the dictionary key and the legacy HTML element id) */
|
|
84
84
|
id: e(n()),
|
|
85
85
|
/** Decimal places for price display (legacy data may use string or number) */
|
|
86
86
|
decimalCount: e(h([t(), n()])),
|
|
87
87
|
/** Pinned product IDs (empty array when filter-driven) */
|
|
88
|
-
productIds: e(c(
|
|
88
|
+
productIds: e(c(s())),
|
|
89
89
|
/** Whether the block requested live products at send time */
|
|
90
90
|
sendProductRequestFlag: e(o()),
|
|
91
91
|
/** Whether to randomize product order */
|
|
92
92
|
shuffleProducts: e(o()),
|
|
93
93
|
/** Filter rules driving product selection */
|
|
94
|
-
filters: e(c(
|
|
94
|
+
filters: e(c(s())),
|
|
95
95
|
/** Currency code (e.g. 'EUR') — sometimes absent in legacy data */
|
|
96
96
|
currency: e(t()),
|
|
97
97
|
/** Currency display settings (separators, alignment, decimals) */
|
|
98
|
-
currencySettings: e(
|
|
98
|
+
currencySettings: e(s()),
|
|
99
99
|
/** Locale (e.g. 'nl_NL') */
|
|
100
100
|
language: e(t()),
|
|
101
101
|
/** Recommendation strategy key (e.g. 'newArrivals') */
|
|
102
102
|
strategy: e(t()),
|
|
103
103
|
/** Snapshot of products as rendered by the legacy block */
|
|
104
|
-
recommendedProducts: e(c(
|
|
104
|
+
recommendedProducts: e(c(s())),
|
|
105
105
|
/** Number of product cards per row */
|
|
106
106
|
cardsInRow: e(n()),
|
|
107
107
|
/** Mobile-only padding (right) */
|
|
@@ -124,7 +124,7 @@ const d = {
|
|
|
124
124
|
isPriceMovedToNextLine: e(o()),
|
|
125
125
|
/** Legacy "Hide if same as discounted" / delete-price-for-zero-sale toggle */
|
|
126
126
|
isPriceDeletedForZeroSale: e(o())
|
|
127
|
-
}),
|
|
127
|
+
}), E = a({
|
|
128
128
|
/**
|
|
129
129
|
* Legacy recommendation block configs keyed by block ID.
|
|
130
130
|
* Pass this when loading a template authored with the v1
|
|
@@ -132,7 +132,7 @@ const d = {
|
|
|
132
132
|
* strategy, currency, locale, and layout data.
|
|
133
133
|
*/
|
|
134
134
|
recommendationConfigs: e(
|
|
135
|
-
k(t(),
|
|
135
|
+
k(t(), D),
|
|
136
136
|
{}
|
|
137
137
|
)
|
|
138
138
|
}), M = a({
|
|
@@ -142,7 +142,7 @@ const d = {
|
|
|
142
142
|
css: e(t(), ""),
|
|
143
143
|
/** Preselected dynamic content items */
|
|
144
144
|
preselectedDynamicContent: e(
|
|
145
|
-
c(
|
|
145
|
+
c(v),
|
|
146
146
|
[]
|
|
147
147
|
),
|
|
148
148
|
/**
|
|
@@ -151,7 +151,7 @@ const d = {
|
|
|
151
151
|
* (first) partner's leaf attributes into the label→token map that repairs
|
|
152
152
|
* label-form placeholders (`{{ Phone Number }}`) in dropped saved modules.
|
|
153
153
|
*/
|
|
154
|
-
dynamicContentList: e(
|
|
154
|
+
dynamicContentList: e(P, {}),
|
|
155
155
|
/** Valid custom field attribute names from the partner's categorized fields */
|
|
156
156
|
customFieldAttributes: e(c(t()), []),
|
|
157
157
|
/** Selected unsubscribe page IDs */
|
|
@@ -159,7 +159,7 @@ const d = {
|
|
|
159
159
|
/** Force recreate template in Stripo storage (use true when updating externally modified templates) */
|
|
160
160
|
forceRecreate: e(o(), !1),
|
|
161
161
|
/** Migration-only inputs (legacy block configs) */
|
|
162
|
-
migration: e(
|
|
162
|
+
migration: e(E, {})
|
|
163
163
|
}), N = a({
|
|
164
164
|
/** Sender display name */
|
|
165
165
|
senderName: e(t(), ""),
|
|
@@ -201,10 +201,8 @@ const d = {
|
|
|
201
201
|
/** Enable Liquid template syntax */
|
|
202
202
|
liquidSyntax: e(o(), !1),
|
|
203
203
|
/** Enable autosave (3-min interval + tab-hide). User toggles on/off from the header. */
|
|
204
|
-
autosave: e(o(), !1)
|
|
205
|
-
|
|
206
|
-
allowlistEnabled: e(o(), !1)
|
|
207
|
-
}), w = i([
|
|
204
|
+
autosave: e(o(), !1)
|
|
205
|
+
}), U = l([
|
|
208
206
|
"amp-accordion",
|
|
209
207
|
"amp-carousel",
|
|
210
208
|
"amp-form-controls",
|
|
@@ -218,7 +216,7 @@ const d = {
|
|
|
218
216
|
"text-block",
|
|
219
217
|
"timer-block",
|
|
220
218
|
"video-block"
|
|
221
|
-
]),
|
|
219
|
+
]), B = l([
|
|
222
220
|
"dynamic-content",
|
|
223
221
|
"checkbox-block",
|
|
224
222
|
"radio-button-block",
|
|
@@ -226,18 +224,18 @@ const d = {
|
|
|
226
224
|
"unsubscribe-block",
|
|
227
225
|
"coupon-block",
|
|
228
226
|
"items-block"
|
|
229
|
-
]),
|
|
227
|
+
]), w = a({
|
|
230
228
|
/** Default blocks to exclude from the editor */
|
|
231
229
|
excludeDefaults: e(
|
|
232
|
-
c(
|
|
230
|
+
c(U),
|
|
233
231
|
[]
|
|
234
232
|
),
|
|
235
233
|
/** Custom blocks to include in the editor */
|
|
236
234
|
includeCustoms: e(
|
|
237
|
-
c(
|
|
235
|
+
c(B),
|
|
238
236
|
[]
|
|
239
237
|
)
|
|
240
|
-
}),
|
|
238
|
+
}), m = a({
|
|
241
239
|
/** Unique identifier for the rule */
|
|
242
240
|
id: t(),
|
|
243
241
|
/** Human-readable description */
|
|
@@ -245,8 +243,8 @@ const d = {
|
|
|
245
243
|
/** Priority for rule ordering (lower = earlier) */
|
|
246
244
|
priority: n()
|
|
247
245
|
}), H = a({
|
|
248
|
-
...
|
|
249
|
-
type:
|
|
246
|
+
...m.entries,
|
|
247
|
+
type: i("replace"),
|
|
250
248
|
/** String to search for */
|
|
251
249
|
search: t(),
|
|
252
250
|
/** Replacement string */
|
|
@@ -254,8 +252,8 @@ const d = {
|
|
|
254
252
|
/** Replace all occurrences (default: false) */
|
|
255
253
|
replaceAll: e(o())
|
|
256
254
|
}), _ = a({
|
|
257
|
-
...
|
|
258
|
-
type:
|
|
255
|
+
...m.entries,
|
|
256
|
+
type: i("regex"),
|
|
259
257
|
/** Regex pattern string */
|
|
260
258
|
pattern: t(),
|
|
261
259
|
/** Replacement string (supports $1, $2, etc.) */
|
|
@@ -263,16 +261,16 @@ const d = {
|
|
|
263
261
|
/** Regex flags (e.g., 'gi') */
|
|
264
262
|
flags: e(t())
|
|
265
263
|
}), j = a({
|
|
266
|
-
...
|
|
267
|
-
type:
|
|
264
|
+
...m.entries,
|
|
265
|
+
type: i("remove"),
|
|
268
266
|
/** Strings or patterns to remove */
|
|
269
267
|
targets: c(t())
|
|
270
268
|
}), q = a({
|
|
271
|
-
...
|
|
272
|
-
type:
|
|
269
|
+
...m.entries,
|
|
270
|
+
type: i("custom"),
|
|
273
271
|
/** Custom processor function */
|
|
274
|
-
processor:
|
|
275
|
-
(
|
|
272
|
+
processor: f(
|
|
273
|
+
(u) => typeof u == "function",
|
|
276
274
|
"processor must be a function"
|
|
277
275
|
)
|
|
278
276
|
}), G = R("type", [
|
|
@@ -291,28 +289,17 @@ const d = {
|
|
|
291
289
|
* Return false to cancel the save operation.
|
|
292
290
|
*/
|
|
293
291
|
externalValidation: e(
|
|
294
|
-
|
|
295
|
-
(
|
|
292
|
+
f(
|
|
293
|
+
(u) => typeof u == "function",
|
|
296
294
|
"externalValidation must be a function"
|
|
297
295
|
)
|
|
298
|
-
),
|
|
299
|
-
/**
|
|
300
|
-
* Resolves the block toaster's content when the domain-allowlist check (features.allowlistEnabled)
|
|
301
|
-
* blocks a save. Host-supplied so role-gating, the settings deep-link, and copy stay host-side.
|
|
302
|
-
* Returning null/void blocks the save with no toaster.
|
|
303
|
-
*/
|
|
304
|
-
resolveAllowlistToast: e(
|
|
305
|
-
S(
|
|
306
|
-
(s) => typeof s == "function",
|
|
307
|
-
"resolveAllowlistToast must be a function"
|
|
308
|
-
)
|
|
309
296
|
)
|
|
310
297
|
}), K = a({
|
|
311
298
|
// Required sections
|
|
312
299
|
/** Identity configuration (required) */
|
|
313
300
|
identity: A,
|
|
314
301
|
/** Partner configuration (required) */
|
|
315
|
-
partner:
|
|
302
|
+
partner: L,
|
|
316
303
|
// Optional sections (with defaults)
|
|
317
304
|
/** Template content and presets */
|
|
318
305
|
template: e(M, {}),
|
|
@@ -323,37 +310,37 @@ const d = {
|
|
|
323
310
|
/** Feature toggles */
|
|
324
311
|
features: e(F, {}),
|
|
325
312
|
/** Block configuration */
|
|
326
|
-
blocks: e(
|
|
313
|
+
blocks: e(w, {}),
|
|
327
314
|
/** Compiler configuration */
|
|
328
315
|
compiler: e(V, {}),
|
|
329
316
|
/** Callbacks and event handlers */
|
|
330
317
|
callbacks: e(z, {})
|
|
331
318
|
});
|
|
332
319
|
export {
|
|
333
|
-
|
|
320
|
+
w as BlocksSchema,
|
|
334
321
|
z as CallbacksSchema,
|
|
335
322
|
G as CompilerRuleSchema,
|
|
336
323
|
V as CompilerSchema,
|
|
337
|
-
|
|
324
|
+
B as CustomBlockTypeSchema,
|
|
338
325
|
q as CustomRuleSchema,
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
326
|
+
U as DefaultBlockTypeSchema,
|
|
327
|
+
P as DynamicContentListSchema,
|
|
328
|
+
S as DynamicContentNodeSchema,
|
|
329
|
+
v as DynamicContentSchema,
|
|
343
330
|
O as EditorSchema,
|
|
344
331
|
N as EmailHeaderSchema,
|
|
345
332
|
I as FallbackFontSchema,
|
|
346
333
|
F as FeaturesSchema,
|
|
347
334
|
K as GuidoConfigSchema,
|
|
348
335
|
A as IdentitySchema,
|
|
349
|
-
|
|
336
|
+
D as LegacyRecommendationConfigSchema,
|
|
350
337
|
d as MessageType,
|
|
351
|
-
|
|
338
|
+
L as PartnerSchema,
|
|
352
339
|
r as ProductType,
|
|
353
340
|
_ as RegexRuleSchema,
|
|
354
341
|
j as RemoveRuleSchema,
|
|
355
342
|
H as ReplaceRuleSchema,
|
|
356
|
-
|
|
343
|
+
E as TemplateMigrationSchema,
|
|
357
344
|
M as TemplateSchema,
|
|
358
345
|
x as UISchema
|
|
359
346
|
};
|
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
import { defineComponent as u, ref as a, onMounted as p, onBeforeUnmount as l, nextTick as
|
|
2
|
-
import { usePreviewInteractionGuard as
|
|
1
|
+
import { defineComponent as u, ref as a, onMounted as p, onBeforeUnmount as l, nextTick as v } from "vue";
|
|
2
|
+
import { usePreviewInteractionGuard as d } from "../../../../composables/usePreviewInteractionGuard.js";
|
|
3
3
|
import { useTranslations as _ } from "../../../../composables/useTranslations.js";
|
|
4
4
|
import { usePreviewStore as w } from "../../../../stores/preview.js";
|
|
5
5
|
import I from "./DesktopBrowserHeader.vue.js";
|
|
6
6
|
const C = /* @__PURE__ */ u({
|
|
7
7
|
__name: "DesktopPreview",
|
|
8
|
-
setup(
|
|
9
|
-
const i = _(), {
|
|
8
|
+
setup(k) {
|
|
9
|
+
const i = _(), { blockPreviewInteractions: t } = d(), o = a(), n = a(!1), c = w();
|
|
10
10
|
let e = null;
|
|
11
11
|
const f = (m) => {
|
|
12
12
|
t(m.target);
|
|
13
|
-
},
|
|
13
|
+
}, r = () => {
|
|
14
14
|
o.value && (e = new ResizeObserver(() => {
|
|
15
|
-
}), e.observe(o.value),
|
|
16
|
-
|
|
15
|
+
}), e.observe(o.value), v(() => {
|
|
16
|
+
n.value = !0;
|
|
17
17
|
}));
|
|
18
18
|
}, s = () => {
|
|
19
19
|
e == null || e.disconnect();
|
|
20
20
|
};
|
|
21
|
-
return p(
|
|
21
|
+
return p(r), l(s), { __sfc: !0, trans: i, blockPreviewInteractions: t, containerRef: o, isContainerReady: n, previewStore: c, resizeObserver: e, onIframeLoad: f, initIframe: r, cleanIframe: s, DesktopBrowserHeader: I };
|
|
22
22
|
}
|
|
23
23
|
});
|
|
24
24
|
export {
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import e from "./ContentView.vue2.js";
|
|
2
2
|
/* empty css */
|
|
3
3
|
import n from "../../../../_virtual/_plugin-vue2_normalizer.js";
|
|
4
|
-
var
|
|
4
|
+
var c = function() {
|
|
5
5
|
var t = this, s = t._self._c, a = t._self._setupProxy;
|
|
6
6
|
return s("div", { staticClass: "w-1 h-1 b-c-4 d-f f-d-c" }, [s("div", { staticClass: "d-f j-c-s-b a-i-c p-2 h-6-s" }, [s("div", { staticClass: "d-f a-i-c cur-p", on: { click: function(l) {
|
|
7
7
|
return t.$emit("back-to-inbox");
|
|
8
8
|
} } }, [s(a.InIcons, { staticClass: "f-s-3 i-c-7", attrs: { name: "line-chevron-left" } }), s("span", { staticClass: "ml-2 f-s-1 f-w-400 l-h-1 t-c-7" }, [t._v(t._s(a.trans("newsletter.inbox")))])], 1), s("div", { staticClass: "d-f a-i-c" }, [s(a.InIcons, { staticClass: "i-c-52", attrs: { name: "line-chevron-down" } }), s(a.InIcons, { staticClass: "ml-1 i-c-52", attrs: { name: "line-chevron-up" } })], 1)]), s("div", { staticClass: "iframe-wrapper f-g-1 o-h" }, [s("iframe", { ref: "iframeRef", staticClass: "iframe-scaled d-b b-c-4 bor-s-n", attrs: { sandbox: "allow-same-origin allow-popups allow-forms allow-scripts allow-popups-to-escape-sandbox", srcdoc: a.previewStore.previewHtml }, on: { load: a.onLoad } })])]);
|
|
9
|
-
},
|
|
9
|
+
}, o = [], i = /* @__PURE__ */ n(
|
|
10
10
|
e,
|
|
11
|
+
c,
|
|
11
12
|
o,
|
|
12
|
-
i,
|
|
13
13
|
!1,
|
|
14
14
|
null,
|
|
15
|
-
"
|
|
15
|
+
"cbafc185"
|
|
16
16
|
);
|
|
17
|
-
const d =
|
|
17
|
+
const d = i.exports;
|
|
18
18
|
export {
|
|
19
19
|
d as default
|
|
20
20
|
};
|
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
import { defineComponent as
|
|
1
|
+
import { defineComponent as m, ref as a } from "vue";
|
|
2
2
|
import { usePreviewInteractionGuard as f } from "../../../../composables/usePreviewInteractionGuard.js";
|
|
3
3
|
import { useResponsivePreview as p } from "../../../../composables/useResponsivePreview.js";
|
|
4
4
|
import { useTranslations as u } from "../../../../composables/useTranslations.js";
|
|
5
5
|
import { usePreviewStore as v } from "../../../../stores/preview.js";
|
|
6
|
-
import { InIcons as
|
|
7
|
-
const
|
|
6
|
+
import { InIcons as P } from "@useinsider/design-system-vue";
|
|
7
|
+
const g = /* @__PURE__ */ m({
|
|
8
8
|
__name: "ContentView",
|
|
9
9
|
emits: ["back-to-inbox"],
|
|
10
|
-
setup(
|
|
11
|
-
const
|
|
10
|
+
setup(_) {
|
|
11
|
+
const c = u(), t = v(), r = a(), { setupResponsivePreview: n } = p(), { blockPreviewInteractions: s } = f(), i = (e) => {
|
|
12
12
|
["transform", "transform-origin", "height"].forEach((o) => {
|
|
13
13
|
e.documentElement.style.removeProperty(o);
|
|
14
14
|
});
|
|
15
15
|
};
|
|
16
|
-
return { __sfc: !0, trans:
|
|
17
|
-
const e =
|
|
18
|
-
o && (n(e), s(e),
|
|
19
|
-
}, InIcons:
|
|
16
|
+
return { __sfc: !0, trans: c, previewStore: t, iframeRef: r, setupResponsivePreview: n, blockPreviewInteractions: s, clearAMPTransforms: i, onLoad: () => {
|
|
17
|
+
const e = r.value, o = e == null ? void 0 : e.contentDocument;
|
|
18
|
+
o && (n(e), s(e), t.isAMPResponsive && i(o));
|
|
19
|
+
}, InIcons: P };
|
|
20
20
|
}
|
|
21
21
|
});
|
|
22
22
|
export {
|
|
23
|
-
|
|
23
|
+
g as default
|
|
24
24
|
};
|
|
@@ -1,43 +1,62 @@
|
|
|
1
|
-
import { useActionsApi as
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
import { useActionsApi as O } from "./useActionsApi.js";
|
|
2
|
+
import { useConfig as w } from "./useConfig.js";
|
|
3
|
+
import { useToaster as M } from "./useToaster.js";
|
|
4
|
+
import { useTranslations as _ } from "./useTranslations.js";
|
|
5
|
+
import { DYNAMIC_CONTENT_TAG_REGEX as L } from "../enums/html-validator.js";
|
|
6
|
+
import { ToasterTypeOptions as v } from "../enums/toaster.js";
|
|
7
|
+
import { useDynamicContentStore as N } from "../stores/dynamic-content.js";
|
|
8
|
+
import { flattenDynamicContentList as x } from "../utils/genericUtil.js";
|
|
9
|
+
import { ref as B } from "vue";
|
|
10
|
+
const U = 250, s = B({}), a = {}, E = /* @__PURE__ */ new Map(), z = () => {
|
|
11
|
+
const { updateHtmlAndCss: r } = O(), { showToaster: i } = M(), { config: C } = w(), p = N(), h = _(), D = (e) => {
|
|
8
12
|
s.value[e] === void 0 && (s.value = { ...s.value, [e]: "pending" });
|
|
9
|
-
},
|
|
13
|
+
}, A = () => {
|
|
14
|
+
const e = "newsletter.ai-template-applied", t = h(e);
|
|
15
|
+
return t === e ? "Template applied to the editor" : t;
|
|
16
|
+
}, S = (e) => {
|
|
17
|
+
var y, T;
|
|
18
|
+
const t = x((T = (y = C.value) == null ? void 0 : y.template) == null ? void 0 : T.dynamicContentList);
|
|
19
|
+
if (t.length === 0)
|
|
20
|
+
return;
|
|
21
|
+
const c = new Map(t.map((n) => [n.value, n])), o = new Set(
|
|
22
|
+
p.selectedDynamicContentList.map((n) => n.value)
|
|
23
|
+
);
|
|
24
|
+
(e.match(L) ?? []).forEach((n) => {
|
|
25
|
+
const m = n.slice(2, -2), g = m.indexOf("|"), l = (g === -1 ? m : m.slice(0, g)).trim(), d = c.get(l);
|
|
26
|
+
d && !o.has(l) && (o.add(l), p.selectedDynamicContentList.push(d));
|
|
27
|
+
});
|
|
28
|
+
}, u = (e, t, c) => {
|
|
10
29
|
s.value = { ...s.value, [e]: "applying" };
|
|
11
30
|
try {
|
|
12
|
-
|
|
13
|
-
type:
|
|
14
|
-
message:
|
|
15
|
-
});
|
|
16
|
-
} catch (
|
|
17
|
-
s.value = { ...s.value, [e]: "failed" },
|
|
18
|
-
type:
|
|
19
|
-
message:
|
|
31
|
+
r(t, c), s.value = { ...s.value, [e]: "applied" }, S(t), E.get(e) !== t && (E.set(e, t), i({
|
|
32
|
+
type: v.Success,
|
|
33
|
+
message: A()
|
|
34
|
+
}));
|
|
35
|
+
} catch (o) {
|
|
36
|
+
s.value = { ...s.value, [e]: "failed" }, i({
|
|
37
|
+
type: v.Error,
|
|
38
|
+
message: o instanceof Error ? o.message : "Failed to apply template"
|
|
20
39
|
});
|
|
21
40
|
}
|
|
22
|
-
},
|
|
23
|
-
const t =
|
|
24
|
-
t && (clearTimeout(t), delete
|
|
41
|
+
}, f = (e) => {
|
|
42
|
+
const t = a[e];
|
|
43
|
+
t && (clearTimeout(t), delete a[e]);
|
|
25
44
|
};
|
|
26
|
-
return { applyStatus: s, markPending:
|
|
27
|
-
t.html && (
|
|
45
|
+
return { applyStatus: s, markPending: D, applyTemplate: (e, t) => {
|
|
46
|
+
t.html && (f(e), u(e, t.html, t.css ?? ""));
|
|
28
47
|
}, applyTemplateDebounced: (e, t) => {
|
|
29
48
|
if (!t.html)
|
|
30
49
|
return;
|
|
31
|
-
|
|
32
|
-
const { html:
|
|
33
|
-
|
|
34
|
-
delete
|
|
35
|
-
},
|
|
50
|
+
f(e);
|
|
51
|
+
const { html: c } = t, o = t.css ?? "";
|
|
52
|
+
a[e] = setTimeout(() => {
|
|
53
|
+
delete a[e], u(e, c, o);
|
|
54
|
+
}, U);
|
|
36
55
|
} };
|
|
37
|
-
},
|
|
38
|
-
Object.values(
|
|
56
|
+
}, J = () => {
|
|
57
|
+
Object.values(a).forEach(clearTimeout), Object.keys(a).forEach((r) => delete a[r]), s.value = {};
|
|
39
58
|
};
|
|
40
59
|
export {
|
|
41
|
-
|
|
42
|
-
|
|
60
|
+
J as resetEmailTemplateApplier,
|
|
61
|
+
z as useEmailTemplateApplier
|
|
43
62
|
};
|
|
@@ -1,42 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const E = ["click", "auxclick"], d = [
|
|
5
|
-
...Object.values(a),
|
|
6
|
-
o.UNSUBSCRIBE_URL,
|
|
7
|
-
o.PREFERENCES_URL
|
|
8
|
-
], l = (e) => {
|
|
9
|
-
if (e.matches(i))
|
|
10
|
-
return !0;
|
|
11
|
-
const r = e.getAttribute("href") ?? "";
|
|
12
|
-
return d.some((t) => r.includes(t));
|
|
13
|
-
}, S = [...u, "tel:", "sms:"], f = (e) => {
|
|
14
|
-
const r = (e.getAttribute("href") ?? "").trim();
|
|
15
|
-
return r === "" || r.startsWith("#") || r.startsWith("{{") ? !1 : S.includes(e.protocol);
|
|
16
|
-
}, m = (e) => {
|
|
17
|
-
var t, n;
|
|
18
|
-
const r = (n = (t = e.target) == null ? void 0 : t.closest) == null ? void 0 : n.call(t, "a");
|
|
19
|
-
if (r) {
|
|
20
|
-
if (l(r) || !f(r)) {
|
|
21
|
-
e.preventDefault(), e.stopPropagation();
|
|
22
|
-
return;
|
|
23
|
-
}
|
|
24
|
-
r.setAttribute("target", "_blank"), r.setAttribute("rel", "noopener noreferrer");
|
|
25
|
-
}
|
|
26
|
-
}, R = (e) => {
|
|
27
|
-
e.preventDefault(), e.stopPropagation();
|
|
28
|
-
}, s = /* @__PURE__ */ new WeakSet(), c = "guidoPreviewGuarded", g = () => ({ guardPreviewInteractions: (r) => {
|
|
1
|
+
const o = ["click", "auxclick", "submit"], c = (t) => {
|
|
2
|
+
t.preventDefault(), t.stopPropagation();
|
|
3
|
+
}, a = () => ({ blockPreviewInteractions: (r) => {
|
|
29
4
|
try {
|
|
30
|
-
const
|
|
31
|
-
if (!
|
|
5
|
+
const e = r.contentDocument;
|
|
6
|
+
if (!e)
|
|
32
7
|
return;
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
})
|
|
36
|
-
} catch (
|
|
37
|
-
console.warn("[usePreviewInteractionGuard] Could not guard preview iframe:",
|
|
8
|
+
o.forEach((n) => {
|
|
9
|
+
e.addEventListener(n, c, !0);
|
|
10
|
+
});
|
|
11
|
+
} catch (e) {
|
|
12
|
+
console.warn("[usePreviewInteractionGuard] Could not guard preview iframe:", e);
|
|
38
13
|
}
|
|
39
14
|
} });
|
|
40
15
|
export {
|
|
41
|
-
|
|
16
|
+
a as usePreviewInteractionGuard
|
|
42
17
|
};
|