@useinsider/guido 3.13.0 → 3.13.1-beta.a1e3c5f
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 +1 -1
- package/dist/@types/config/defaults.js +6 -2
- package/dist/@types/config/schemas.js +15 -13
- package/dist/components/Guido.vue.js +1 -1
- package/dist/components/Guido.vue2.js +67 -66
- package/dist/composables/useTranslations.js +7 -5
- package/dist/config/compiler/outlookCompilerRules.js +21 -8
- package/dist/config/migrator/index.js +11 -10
- package/dist/config/migrator/trackIdMigrator.js +11 -0
- package/dist/guido.css +1 -1
- package/dist/library.js +14 -9
- package/dist/src/@types/config/schemas.d.ts +4 -0
- package/dist/src/composables/useConfig.d.ts +2 -0
- package/dist/src/composables/useModuleDynamicContentRepair.d.ts +0 -5
- package/dist/src/config/migrator/index.d.ts +4 -1
- package/dist/src/config/migrator/trackIdMigrator.d.ts +6 -0
- package/dist/src/library.d.ts +2 -0
- package/dist/src/stores/config.d.ts +18 -0
- package/dist/src/stores/editor.d.ts +25 -0
- package/dist/src/utils/linkTrackingIds.d.ts +25 -0
- package/dist/stores/editor.js +4 -1
- package/dist/utils/linkTrackingIds.js +44 -0
- package/dist/utils/templatePreparation.js +70 -59
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -134,7 +134,7 @@ const config: GuidoConfigInput = {
|
|
|
134
134
|
// Optional: Editor settings
|
|
135
135
|
editor?: {
|
|
136
136
|
locale?: string, // Default: 'en'
|
|
137
|
-
translationsPath?: string, // Default:
|
|
137
|
+
translationsPath?: string, // Default: first locale registered on window.trans
|
|
138
138
|
migrationDate?: number, // Stripo migration timestamp
|
|
139
139
|
emailHeader?: {
|
|
140
140
|
senderName?: string,
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { ProductType as a, MessageType as o } from "./schemas.js";
|
|
2
|
+
const i = {
|
|
3
|
+
translationsPath: "window.trans[Object.keys(window.trans)[0]]"
|
|
4
|
+
};
|
|
2
5
|
a.EMAIL;
|
|
3
6
|
o.PROMOTIONAL;
|
|
4
7
|
const e = [
|
|
@@ -33,12 +36,13 @@ const e = [
|
|
|
33
36
|
"vikingsankara",
|
|
34
37
|
"stripoeditorlivetest"
|
|
35
38
|
];
|
|
36
|
-
function
|
|
39
|
+
function s(t) {
|
|
37
40
|
return e.includes(t);
|
|
38
41
|
}
|
|
39
42
|
export {
|
|
43
|
+
i as DEFAULT_EDITOR,
|
|
40
44
|
o as MessageType,
|
|
41
45
|
a as ProductType,
|
|
42
46
|
e as TEST_PARTNERS,
|
|
43
|
-
|
|
47
|
+
s as isTestPartner
|
|
44
48
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ModuleFolderDefaults as
|
|
2
|
-
import { object as a, number as n, optional as e, string as t, picklist as r, pipe as p, minLength as b, custom as h, boolean as o, array as c, record as k, fallback as C, literal as i, looseObject as g, variant as R, union as
|
|
1
|
+
import { ModuleFolderDefaults as f } from "../../enums/defaults.js";
|
|
2
|
+
import { object as a, number as n, optional as e, string as t, picklist as r, pipe as p, minLength as b, custom as h, boolean as o, array as c, record as k, fallback as C, literal as i, looseObject as g, variant as R, union as y, 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,
|
|
@@ -12,7 +12,7 @@ const d = {
|
|
|
12
12
|
ARCHITECT: 49,
|
|
13
13
|
/** Unsubscribe page builder */
|
|
14
14
|
UNSUBSCRIBE_PAGES: 97
|
|
15
|
-
},
|
|
15
|
+
}, I = a({
|
|
16
16
|
/** Unique identifier for the template being edited */
|
|
17
17
|
templateId: p(
|
|
18
18
|
t(),
|
|
@@ -25,7 +25,7 @@ const d = {
|
|
|
25
25
|
),
|
|
26
26
|
/** Optional variation ID for A/B testing */
|
|
27
27
|
variationId: e(t())
|
|
28
|
-
}),
|
|
28
|
+
}), A = a({
|
|
29
29
|
/** Fallback font name (e.g., "Georgia") */
|
|
30
30
|
name: t(),
|
|
31
31
|
/** Fallback font family (e.g., "serif" or "sans-serif") */
|
|
@@ -53,7 +53,7 @@ const d = {
|
|
|
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
|
-
fallbackFont: e(
|
|
56
|
+
fallbackFont: e(A)
|
|
57
57
|
}), v = a({
|
|
58
58
|
/** Display text for the dynamic content */
|
|
59
59
|
text: t(),
|
|
@@ -83,7 +83,7 @@ const d = {
|
|
|
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
|
-
decimalCount: e(
|
|
86
|
+
decimalCount: e(y([t(), n()])),
|
|
87
87
|
/** Pinned product IDs (empty array when filter-driven) */
|
|
88
88
|
productIds: e(c(s())),
|
|
89
89
|
/** Whether the block requested live products at send time */
|
|
@@ -117,7 +117,7 @@ const d = {
|
|
|
117
117
|
/** Block type marker used by some legacy variants */
|
|
118
118
|
blockType: e(t()),
|
|
119
119
|
/** Size variant marker (legacy data may use string or number) */
|
|
120
|
-
size: e(
|
|
120
|
+
size: e(y([t(), n()])),
|
|
121
121
|
/** Vertical responsiveness flag (legacy size=1 variants) */
|
|
122
122
|
verticalResponsiveness: e(o()),
|
|
123
123
|
/** Legacy "Move to next line" price placement toggle (cardPricePlacement.js) */
|
|
@@ -175,9 +175,9 @@ const d = {
|
|
|
175
175
|
/** Email header settings */
|
|
176
176
|
emailHeader: e(N, { senderName: "", subject: "" }),
|
|
177
177
|
/** Folder name for user-saved modules (used by Stripo plugin panel for path construction) */
|
|
178
|
-
savedModulesFolderName: e(t(),
|
|
178
|
+
savedModulesFolderName: e(t(), f.SAVED_MODULES),
|
|
179
179
|
/** Folder name for default/prebuilt modules (used by Stripo plugin panel for path construction) */
|
|
180
|
-
defaultModulesFolderName: e(t(),
|
|
180
|
+
defaultModulesFolderName: e(t(), f.DEFAULT_MODULES)
|
|
181
181
|
}), x = a({
|
|
182
182
|
/** Whether to show the header bar */
|
|
183
183
|
showHeader: e(o(), !0),
|
|
@@ -203,7 +203,9 @@ const d = {
|
|
|
203
203
|
/** Enable autosave (3-min interval + tab-hide). User toggles on/off from the header. */
|
|
204
204
|
autosave: e(o(), !1),
|
|
205
205
|
/** Enable pre-save domain-allowlist validation (opt-in; Guido self-serves the block toaster) */
|
|
206
|
-
allowlistEnabled: e(o(), !1)
|
|
206
|
+
allowlistEnabled: e(o(), !1),
|
|
207
|
+
/** Enable persistent link tracking-id assignment for the click heatmap (opt-in) */
|
|
208
|
+
linkTrackingIds: e(o(), !1)
|
|
207
209
|
}), U = r([
|
|
208
210
|
"amp-accordion",
|
|
209
211
|
"amp-carousel",
|
|
@@ -299,7 +301,7 @@ const d = {
|
|
|
299
301
|
}), K = a({
|
|
300
302
|
// Required sections
|
|
301
303
|
/** Identity configuration (required) */
|
|
302
|
-
identity:
|
|
304
|
+
identity: I,
|
|
303
305
|
/** Partner configuration (required) */
|
|
304
306
|
partner: L,
|
|
305
307
|
// Optional sections (with defaults)
|
|
@@ -331,10 +333,10 @@ export {
|
|
|
331
333
|
v as DynamicContentSchema,
|
|
332
334
|
O as EditorSchema,
|
|
333
335
|
N as EmailHeaderSchema,
|
|
334
|
-
|
|
336
|
+
A as FallbackFontSchema,
|
|
335
337
|
F as FeaturesSchema,
|
|
336
338
|
K as GuidoConfigSchema,
|
|
337
|
-
|
|
339
|
+
I as IdentitySchema,
|
|
338
340
|
P as LegacyRecommendationConfigSchema,
|
|
339
341
|
d as MessageType,
|
|
340
342
|
L as PartnerSchema,
|
|
@@ -1,49 +1,50 @@
|
|
|
1
|
-
import { defineComponent as
|
|
2
|
-
import { useCortexBlueprintBridge as
|
|
3
|
-
import { provideGuidoActions as
|
|
4
|
-
import { useGuidoStateBridge as
|
|
5
|
-
import { usePartner as
|
|
6
|
-
import { useStripo as
|
|
7
|
-
import { useTimerClone as
|
|
8
|
-
import { migrate as
|
|
1
|
+
import { defineComponent as K, defineAsyncComponent as M, ref as O, computed as U, watch as _, onMounted as V, onUnmounted as j } from "vue";
|
|
2
|
+
import { useCortexBlueprintBridge as J } from "../composables/useCortexBlueprintBridge.js";
|
|
3
|
+
import { provideGuidoActions as Q } from "../composables/useGuidoActions.js";
|
|
4
|
+
import { useGuidoStateBridge as X } from "../composables/useGuidoStateBridge.js";
|
|
5
|
+
import { usePartner as Y } from "../composables/usePartner.js";
|
|
6
|
+
import { useStripo as Z } from "../composables/useStripo.js";
|
|
7
|
+
import { useTimerClone as ee } from "../composables/useTimerClone.js";
|
|
8
|
+
import { migrate as B } from "../config/migrator/index.js";
|
|
9
9
|
import { ModuleFolderDefaults as N } from "../enums/defaults.js";
|
|
10
|
-
import { RIBBON_SELECTOR as
|
|
11
|
-
import { useRecommendationExtensionStore as
|
|
12
|
-
import
|
|
13
|
-
import
|
|
14
|
-
import
|
|
15
|
-
import
|
|
16
|
-
import
|
|
17
|
-
import
|
|
18
|
-
import
|
|
19
|
-
import { useStripoApi as
|
|
20
|
-
import { useConfigStore as
|
|
21
|
-
import { useDynamicContentStore as
|
|
22
|
-
import { useEditorStore as
|
|
23
|
-
import { usePreviewStore as
|
|
24
|
-
import { useTemplateStore as
|
|
25
|
-
import { useUnsubscribeStore as
|
|
26
|
-
|
|
10
|
+
import { RIBBON_SELECTOR as te } from "../enums/onboarding.js";
|
|
11
|
+
import { useRecommendationExtensionStore as oe } from "../extensions/Blocks/Recommendation/store/recommendation.js";
|
|
12
|
+
import ne from "./organisms/AutoSaveController.vue.js";
|
|
13
|
+
import re from "./organisms/base/Toaster.vue.js";
|
|
14
|
+
import se from "./organisms/extensions/recommendation/FilterSelectionDrawer.vue.js";
|
|
15
|
+
import ie from "./organisms/header/HeaderWrapper.vue.js";
|
|
16
|
+
import ae from "./organisms/LoadingWrapper.vue.js";
|
|
17
|
+
import ce from "./organisms/save-as-template/SaveAsTemplateDrawer.vue.js";
|
|
18
|
+
import de from "./organisms/unsubscribe/UnsubscribeWrapper.vue.js";
|
|
19
|
+
import { useStripoApi as me } from "../services/stripoApi.js";
|
|
20
|
+
import { useConfigStore as le } from "../stores/config.js";
|
|
21
|
+
import { useDynamicContentStore as ue } from "../stores/dynamic-content.js";
|
|
22
|
+
import { useEditorStore as P } from "../stores/editor.js";
|
|
23
|
+
import { usePreviewStore as pe } from "../stores/preview.js";
|
|
24
|
+
import { useTemplateStore as fe } from "../stores/template.js";
|
|
25
|
+
import { useUnsubscribeStore as ye } from "../stores/unsubscribe.js";
|
|
26
|
+
import { readTrackSeq as ve } from "../utils/linkTrackingIds.js";
|
|
27
|
+
const $e = /* @__PURE__ */ K({
|
|
27
28
|
__name: "Guido",
|
|
28
29
|
props: {
|
|
29
30
|
config: null,
|
|
30
31
|
ready: { type: Boolean, default: !0 }
|
|
31
32
|
},
|
|
32
33
|
emits: ["dynamic-content:open", "back", "save:start", "save:complete", "on-change", "ready", "onboarding:finished", "test-email:click"],
|
|
33
|
-
setup(
|
|
34
|
-
const i =
|
|
34
|
+
setup(A, { expose: W, emit: r }) {
|
|
35
|
+
const i = A, x = M(
|
|
35
36
|
() => import("./organisms/email-preview/PreviewContainer.vue.js")
|
|
36
|
-
),
|
|
37
|
+
), G = M(
|
|
37
38
|
() => import("./organisms/onboarding/OnboardingWrapper.vue.js")
|
|
38
|
-
), g =
|
|
39
|
+
), g = O(), l = O(), u = ue(), S = ye(), o = le();
|
|
39
40
|
i.ready && o.init(i.config);
|
|
40
|
-
const
|
|
41
|
+
const c = P(), H = pe(), m = U(() => c.hasChanges), { isTestPartner: $ } = Y(), h = () => {
|
|
41
42
|
var t;
|
|
42
43
|
return (t = g.value) == null ? void 0 : t.handleSave(!0);
|
|
43
44
|
}, b = (t) => {
|
|
44
|
-
|
|
45
|
+
c.loadingStatus = t;
|
|
45
46
|
};
|
|
46
|
-
|
|
47
|
+
J(), X();
|
|
47
48
|
const p = () => {
|
|
48
49
|
var t, e;
|
|
49
50
|
return {
|
|
@@ -54,78 +55,78 @@ const xe = /* @__PURE__ */ q({
|
|
|
54
55
|
savedModulesFolderName: ((t = o.editor) == null ? void 0 : t.savedModulesFolderName) || N.SAVED_MODULES,
|
|
55
56
|
defaultModulesFolderName: ((e = o.editor) == null ? void 0 : e.defaultModulesFolderName) || N.DEFAULT_MODULES
|
|
56
57
|
};
|
|
57
|
-
}, { initPlugin: E, preloadRuntime: w } =
|
|
58
|
+
}, { initPlugin: E, preloadRuntime: w } = Z(), { getDefaultTemplate: C } = me(), { cloneTimersOnSave: D, hasTimerBlocks: k } = ee(), z = U(() => {
|
|
58
59
|
var t;
|
|
59
60
|
return !((t = o.ui) != null && t.showHeader);
|
|
60
61
|
});
|
|
61
|
-
|
|
62
|
+
Q({
|
|
62
63
|
onBack: () => {
|
|
63
|
-
console.debug("guido:back"),
|
|
64
|
+
console.debug("guido:back"), r("back");
|
|
64
65
|
},
|
|
65
66
|
onSaveStart: () => {
|
|
66
|
-
console.debug("guido:save:start"),
|
|
67
|
+
console.debug("guido:save:start"), r("save:start");
|
|
67
68
|
},
|
|
68
69
|
onSaveComplete: (t) => {
|
|
69
70
|
const e = { ...t, metadata: p() };
|
|
70
|
-
console.debug("guido:save:complete", e),
|
|
71
|
+
console.debug("guido:save:complete", e), r("save:complete", e);
|
|
71
72
|
},
|
|
72
73
|
onTestEmailClick: () => {
|
|
73
|
-
console.debug("guido:test-email:click"),
|
|
74
|
+
console.debug("guido:test-email:click"), r("test-email:click");
|
|
74
75
|
}
|
|
75
76
|
});
|
|
76
|
-
const
|
|
77
|
+
const T = (t) => {
|
|
77
78
|
console.debug("dynamic-content:close", t), u.setSelectedDynamicContent(t), document.dispatchEvent(new CustomEvent("dynamic-content:close", { detail: t }));
|
|
78
|
-
},
|
|
79
|
+
}, F = () => {
|
|
79
80
|
console.debug("dynamic-content:close", "Without Data"), document.dispatchEvent(new CustomEvent("dynamic-content:close", { detail: { text: "", value: "" } }));
|
|
80
81
|
};
|
|
81
|
-
|
|
82
|
-
|
|
82
|
+
_(() => m.value, () => {
|
|
83
|
+
r("on-change", m.value);
|
|
83
84
|
});
|
|
84
85
|
const f = (t) => {
|
|
85
|
-
const e = t, { attribute: s, position:
|
|
86
|
-
console.debug("dynamic-content:open", e.detail),
|
|
86
|
+
const e = t, { attribute: s, position: d } = e.detail;
|
|
87
|
+
console.debug("dynamic-content:open", e.detail), r("dynamic-content:open", s, d);
|
|
87
88
|
};
|
|
88
89
|
let a = null;
|
|
89
90
|
const y = () => {
|
|
90
91
|
var e;
|
|
91
|
-
const t = document.querySelector(
|
|
92
|
+
const t = document.querySelector(te);
|
|
92
93
|
(e = l.value) == null || e.style.setProperty("--ribbon-offset", `${(t == null ? void 0 : t.offsetHeight) ?? 0}px`);
|
|
93
94
|
}, v = async () => {
|
|
94
95
|
var t;
|
|
95
96
|
try {
|
|
96
|
-
o.initialized || o.init(i.config),
|
|
97
|
-
const e = o.template, s = (e == null ? void 0 : e.html) || "",
|
|
97
|
+
o.initialized || o.init(i.config), c.templateId = o.templateId;
|
|
98
|
+
const e = o.template, s = (e == null ? void 0 : e.html) || "", d = (e == null ? void 0 : e.css) || "", I = (e == null ? void 0 : e.preselectedDynamicContent) || [];
|
|
98
99
|
S.selectedUnsubscribePages = (e == null ? void 0 : e.selectedUnsubscribePages) || [];
|
|
99
|
-
const
|
|
100
|
-
let
|
|
101
|
-
html: s && await
|
|
102
|
-
css:
|
|
100
|
+
const L = ((t = e == null ? void 0 : e.migration) == null ? void 0 : t.recommendationConfigs) ?? {}, R = { linkTrackingIds: o.isFeatureEnabled("linkTrackingIds") };
|
|
101
|
+
let n = {
|
|
102
|
+
html: s && await B(s, L, R),
|
|
103
|
+
css: d
|
|
103
104
|
};
|
|
104
|
-
|
|
105
|
-
const
|
|
106
|
-
preselectedDynamicContentList:
|
|
105
|
+
n.html || (n = await C(), n.html = await B(n.html, L, R)), k(n.html) && (n.html = await D(n.html)), c.trackIdSessionFloor = ve(n.html);
|
|
106
|
+
const q = {
|
|
107
|
+
preselectedDynamicContentList: I,
|
|
107
108
|
onReady: () => {
|
|
108
|
-
console.debug("guido:ready"),
|
|
109
|
+
console.debug("guido:ready"), r("ready");
|
|
109
110
|
}
|
|
110
111
|
};
|
|
111
|
-
await E(
|
|
112
|
+
await E(n, p(), q), u.selectedDynamicContentList = I;
|
|
112
113
|
} catch (e) {
|
|
113
114
|
console.error("Failed to initialize Stripo editor:", e);
|
|
114
115
|
}
|
|
115
116
|
};
|
|
116
|
-
return
|
|
117
|
+
return V(async () => {
|
|
117
118
|
var e;
|
|
118
|
-
console.debug("Guido says happy coding 🎉"), console.debug("🚗 Ka-Chow"),
|
|
119
|
+
console.debug("Guido says happy coding 🎉"), console.debug("🚗 Ka-Chow"), oe().$reset(), P().$reset(), fe().$reset(), y();
|
|
119
120
|
const t = (e = l.value) == null ? void 0 : e.parentElement;
|
|
120
121
|
if (t && (a = new ResizeObserver(y), a.observe(t)), w(), i.ready)
|
|
121
122
|
await v();
|
|
122
123
|
else {
|
|
123
|
-
const s =
|
|
124
|
-
|
|
124
|
+
const s = _(() => i.ready, (d) => {
|
|
125
|
+
d && (s(), v());
|
|
125
126
|
});
|
|
126
127
|
}
|
|
127
128
|
document.addEventListener("dynamic-content:open", f);
|
|
128
|
-
}),
|
|
129
|
+
}), j(() => {
|
|
129
130
|
a == null || a.disconnect(), document.removeEventListener("dynamic-content:open", f);
|
|
130
131
|
try {
|
|
131
132
|
window.UIEditor.removeEditor();
|
|
@@ -133,17 +134,17 @@ const xe = /* @__PURE__ */ q({
|
|
|
133
134
|
console.debug("Failed to remove Stripo editor: No editor found");
|
|
134
135
|
}
|
|
135
136
|
o.reset();
|
|
136
|
-
}),
|
|
137
|
+
}), W({
|
|
137
138
|
dynamicContent: {
|
|
138
|
-
insert:
|
|
139
|
-
close:
|
|
139
|
+
insert: T,
|
|
140
|
+
close: F
|
|
140
141
|
},
|
|
141
142
|
hasChanges: m,
|
|
142
143
|
saveSilent: h,
|
|
143
144
|
setLoading: b
|
|
144
|
-
}), { __sfc: !0, PreviewContainer:
|
|
145
|
+
}), { __sfc: !0, PreviewContainer: x, OnboardingWrapper: G, headerWrapperRef: g, wrapperRef: l, dynamicContentStore: u, unsubscribeStore: S, props: i, configStore: o, editorStore: c, previewStore: H, hasChanges: m, isTestPartner: $, saveSilent: h, setLoading: b, emit: r, buildMetadata: p, initPlugin: E, preloadRuntime: w, getDefaultTemplate: C, cloneTimersOnSave: D, hasTimerBlocks: k, noHeader: z, insertDynamicContent: T, closeDynamicContent: F, handleDynamicContentOpen: f, ribbonObserver: a, updateRibbonOffset: y, startEditor: v, AutoSaveController: ne, Toaster: re, FilterSelectionDrawer: se, HeaderWrapper: ie, LoadingWrapper: ae, SaveAsTemplateDrawer: ce, UnsubscribeWrapper: de };
|
|
145
146
|
}
|
|
146
147
|
});
|
|
147
148
|
export {
|
|
148
|
-
|
|
149
|
+
$e as default
|
|
149
150
|
};
|
|
@@ -1,18 +1,20 @@
|
|
|
1
|
+
import "../@types/config/schemas.js";
|
|
2
|
+
import { DEFAULT_EDITOR } from "../@types/config/defaults.js";
|
|
1
3
|
import memoize from "../node_modules/lodash-es/memoize.js";
|
|
2
4
|
import { ref } from "vue";
|
|
3
5
|
import { useConfig } from "./useConfig.js";
|
|
4
6
|
const useTranslations = () => {
|
|
5
7
|
var o, e;
|
|
6
|
-
const { config } = useConfig(), translationsPath = ((e = (o = config.value) == null ? void 0 : o.editor) == null ? void 0 : e.translationsPath) ||
|
|
7
|
-
const r = translations.value[
|
|
8
|
-
return r ?
|
|
8
|
+
const { config } = useConfig(), translationsPath = ((e = (o = config.value) == null ? void 0 : o.editor) == null ? void 0 : e.translationsPath) || DEFAULT_EDITOR.translationsPath, translations = ref(eval(translationsPath)), trans = (t, n) => {
|
|
9
|
+
const r = translations.value[t];
|
|
10
|
+
return r ? n ? Object.entries(n).reduce(
|
|
9
11
|
(s, [i, a]) => s.replace(new RegExp(`{${i}}`, "g"), String(a)),
|
|
10
12
|
r
|
|
11
|
-
) : r : (console.warn(`Translation key not found: ${
|
|
13
|
+
) : r : (console.warn(`Translation key not found: ${t}`), t);
|
|
12
14
|
};
|
|
13
15
|
return memoize(
|
|
14
16
|
trans,
|
|
15
|
-
(
|
|
17
|
+
(t, n) => !n || Object.keys(n).length === 0 ? t : JSON.stringify({ key: t, params: n })
|
|
16
18
|
);
|
|
17
19
|
};
|
|
18
20
|
export {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
1
|
+
const r = `
|
|
2
2
|
<!--[if gte mso 9]>
|
|
3
3
|
<xml>
|
|
4
4
|
<o:OfficeDocumentSettings>
|
|
@@ -6,15 +6,21 @@ const c = `
|
|
|
6
6
|
<o:PixelsPerInch>96</o:PixelsPerInch>
|
|
7
7
|
</o:OfficeDocumentSettings>
|
|
8
8
|
</xml>
|
|
9
|
-
<![endif]-->`,
|
|
9
|
+
<![endif]-->`, n = {
|
|
10
10
|
xmlns: "http://www.w3.org/1999/xhtml",
|
|
11
11
|
"xmlns:o": "urn:schemas-microsoft-com:office:office"
|
|
12
|
-
},
|
|
12
|
+
}, p = `
|
|
13
|
+
<style type="text/css">
|
|
14
|
+
ul, ol { padding: 0px 0px 0px 40px; }
|
|
15
|
+
li p { mso-margin-bottom-alt: 15px; }
|
|
16
|
+
.es-text-ltr ul, .es-text-ltr ol { padding: 0px 0px 0px 40px; }
|
|
17
|
+
.es-text-rtl ol, .es-text-rtl ul { padding: 0px 40px 0px 0px; }
|
|
18
|
+
</style>`, l = [
|
|
13
19
|
{
|
|
14
20
|
id: "append-office-xml",
|
|
15
21
|
description: "Appending office XML into the head if it does not exist.",
|
|
16
22
|
type: "custom",
|
|
17
|
-
processor: (e) => e.includes("<o:OfficeDocumentSettings>") ? e : e.replace("</head>", `${
|
|
23
|
+
processor: (e) => e.includes("<o:OfficeDocumentSettings>") ? e : e.replace("</head>", `${r}</head>`),
|
|
18
24
|
priority: 70
|
|
19
25
|
},
|
|
20
26
|
{
|
|
@@ -23,14 +29,21 @@ const c = `
|
|
|
23
29
|
type: "custom",
|
|
24
30
|
processor: (e) => {
|
|
25
31
|
let t = e;
|
|
26
|
-
return Object.entries(
|
|
27
|
-
const
|
|
28
|
-
t.search(
|
|
32
|
+
return Object.entries(n).forEach(([o, i]) => {
|
|
33
|
+
const s = new RegExp(`${o}="[^"]*"`);
|
|
34
|
+
t.search(s) === -1 && (t = t.replace("<html", `<html ${o}="${i}"`));
|
|
29
35
|
}), t;
|
|
30
36
|
},
|
|
31
37
|
priority: 71
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
id: "append-outlook-list-css",
|
|
41
|
+
description: "Appending Outlook list rules into the head if the base CSS does not already carry them.",
|
|
42
|
+
type: "custom",
|
|
43
|
+
processor: (e) => e.includes("mso-margin-bottom-alt") ? e : e.replace("</head>", `${p}</head>`),
|
|
44
|
+
priority: 73
|
|
32
45
|
}
|
|
33
46
|
];
|
|
34
47
|
export {
|
|
35
|
-
|
|
48
|
+
l as outlookCompilerRules
|
|
36
49
|
};
|
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
import { migrateCheckbox as
|
|
2
|
-
import { migrateCouponBlock as
|
|
1
|
+
import { migrateCheckbox as i } from "./checkboxMigrator.js";
|
|
2
|
+
import { migrateCouponBlock as a } from "./couponBlockMigrator.js";
|
|
3
3
|
import { migrateItemsBlock as e } from "./itemsBlockMigrator.js";
|
|
4
|
-
import { migrateRadioButton as
|
|
5
|
-
import { migrateRecommendation as
|
|
6
|
-
import { migrateSocialIcons as
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
4
|
+
import { migrateRadioButton as c } from "./radioButtonMigrator.js";
|
|
5
|
+
import { migrateRecommendation as g } from "./recommendationMigrator.js";
|
|
6
|
+
import { migrateSocialIcons as n } from "./socialIconMigrator.js";
|
|
7
|
+
import { migrateTrackIds as p } from "./trackIdMigrator.js";
|
|
8
|
+
import { migrateUnsubscribe as f } from "./unsubscribeMigrator.js";
|
|
9
|
+
const x = async (m, o = {}, t = {}) => {
|
|
10
|
+
let r = m;
|
|
11
|
+
return r = i(r), r = c(r), r = await f(r), r = a(r), r = g(r, o), r = e(r), r = n(r), t.linkTrackingIds && (r = p(r)), r;
|
|
11
12
|
};
|
|
12
13
|
export {
|
|
13
|
-
|
|
14
|
+
x as migrate
|
|
14
15
|
};
|
package/dist/guido.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
.gap-16[data-v-5553d071],.gap-16[data-v-0e1b0c54]{gap:16px}[data-v-73199fa4] .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-195ab6d4]{position:relative;display:inline-block}.new-tag[data-v-195ab6d4]{position:absolute;top:-8px;right:-16px;z-index:10}[data-v-195ab6d4] .guido__view-option-selection-desktop svg,[data-v-195ab6d4] .guido__view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-195ab6d4] .in-segments-wrapper__button_selected,[data-v-195ab6d4] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}[data-v-195ab6d4] .in-tooltip-wrapper__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-d405ca59]{position:relative;display:inline-block}.new-tag[data-v-d405ca59]{position:absolute;top:-8px;right:-16px;z-index:10}[data-v-d405ca59] .guido__verion-history-view-option-selection-desktop svg,[data-v-d405ca59] .guido__verion-history-view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-d405ca59] .in-segments-wrapper__button_selected,[data-v-d405ca59] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}[data-v-d405ca59] .in-tooltip-wrapper__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-6e711fd7]{gap:4px}.header-wrapper[data-v-d11dd577]{min-width:1000px}.guido-loading__wrapper[data-v-07c4b2d8]{height:100%;top:75px!important;bottom:0!important}.guido-editor__wrapper[data-v-
|
|
1
|
+
.gap-16[data-v-5553d071],.gap-16[data-v-0e1b0c54]{gap:16px}[data-v-73199fa4] .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-195ab6d4]{position:relative;display:inline-block}.new-tag[data-v-195ab6d4]{position:absolute;top:-8px;right:-16px;z-index:10}[data-v-195ab6d4] .guido__view-option-selection-desktop svg,[data-v-195ab6d4] .guido__view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-195ab6d4] .in-segments-wrapper__button_selected,[data-v-195ab6d4] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}[data-v-195ab6d4] .in-tooltip-wrapper__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-d405ca59]{position:relative;display:inline-block}.new-tag[data-v-d405ca59]{position:absolute;top:-8px;right:-16px;z-index:10}[data-v-d405ca59] .guido__verion-history-view-option-selection-desktop svg,[data-v-d405ca59] .guido__verion-history-view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-d405ca59] .in-segments-wrapper__button_selected,[data-v-d405ca59] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}[data-v-d405ca59] .in-tooltip-wrapper__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-6e711fd7]{gap:4px}.header-wrapper[data-v-d11dd577]{min-width:1000px}.guido-loading__wrapper[data-v-07c4b2d8]{height:100%;top:75px!important;bottom:0!important}.guido-editor__wrapper[data-v-81958b3d]{--ribbon-offset: 0px;position:relative;width:100%;height:calc(100vh - 128px - var(--ribbon-offset))}.guido-editor__container[data-v-81958b3d]{width:100%;height:calc(100vh - 128px - var(--ribbon-offset))}.guido-editor__no-header[data-v-81958b3d]{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-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}
|
package/dist/library.js
CHANGED
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
import { default as a } from "./components/Guido.vue.js";
|
|
2
|
-
import { MessageType as
|
|
2
|
+
import { MessageType as T, ProductType as f } from "./@types/config/schemas.js";
|
|
3
3
|
import "./@types/config/defaults.js";
|
|
4
|
-
import { getValidationErrors as
|
|
4
|
+
import { getValidationErrors as t, isValidConfig as p, parseConfig as d, parseConfigSafe as g, validateConfig as n } from "./@types/config/validator.js";
|
|
5
|
+
import { TRACK_ID_ATTRIBUTE as m, TRACK_SEQ_ATTRIBUTE as l, assignTrackingIds as x, readTrackSeq as A } from "./utils/linkTrackingIds.js";
|
|
5
6
|
export {
|
|
6
7
|
a as Guido,
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
8
|
+
T as MessageType,
|
|
9
|
+
f as ProductType,
|
|
10
|
+
m as TRACK_ID_ATTRIBUTE,
|
|
11
|
+
l as TRACK_SEQ_ATTRIBUTE,
|
|
12
|
+
x as assignTrackingIds,
|
|
13
|
+
t as getValidationErrors,
|
|
14
|
+
p as isValidConfig,
|
|
15
|
+
d as parseConfig,
|
|
16
|
+
g as parseConfigSafe,
|
|
17
|
+
A as readTrackSeq,
|
|
18
|
+
n as validateConfig
|
|
14
19
|
};
|
|
@@ -385,6 +385,8 @@ export declare const FeaturesSchema: v.ObjectSchema<{
|
|
|
385
385
|
readonly autosave: v.OptionalSchema<v.BooleanSchema<undefined>, false>;
|
|
386
386
|
/** Enable pre-save domain-allowlist validation (opt-in; Guido self-serves the block toaster) */
|
|
387
387
|
readonly allowlistEnabled: v.OptionalSchema<v.BooleanSchema<undefined>, false>;
|
|
388
|
+
/** Enable persistent link tracking-id assignment for the click heatmap (opt-in) */
|
|
389
|
+
readonly linkTrackingIds: v.OptionalSchema<v.BooleanSchema<undefined>, false>;
|
|
388
390
|
}, undefined>;
|
|
389
391
|
/**
|
|
390
392
|
* Default block types available in Stripo
|
|
@@ -774,6 +776,8 @@ export declare const GuidoConfigSchema: v.ObjectSchema<{
|
|
|
774
776
|
readonly autosave: v.OptionalSchema<v.BooleanSchema<undefined>, false>;
|
|
775
777
|
/** Enable pre-save domain-allowlist validation (opt-in; Guido self-serves the block toaster) */
|
|
776
778
|
readonly allowlistEnabled: v.OptionalSchema<v.BooleanSchema<undefined>, false>;
|
|
779
|
+
/** Enable persistent link tracking-id assignment for the click heatmap (opt-in) */
|
|
780
|
+
readonly linkTrackingIds: v.OptionalSchema<v.BooleanSchema<undefined>, false>;
|
|
777
781
|
}, undefined>, {}>;
|
|
778
782
|
/** Block configuration */
|
|
779
783
|
readonly blocks: v.OptionalSchema<v.ObjectSchema<{
|
|
@@ -97,6 +97,7 @@ export declare const useConfig: () => {
|
|
|
97
97
|
liquidSyntax: boolean;
|
|
98
98
|
autosave: boolean;
|
|
99
99
|
allowlistEnabled: boolean;
|
|
100
|
+
linkTrackingIds: boolean;
|
|
100
101
|
};
|
|
101
102
|
blocks: {
|
|
102
103
|
excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
|
|
@@ -229,6 +230,7 @@ export declare const useConfig: () => {
|
|
|
229
230
|
liquidSyntax: boolean;
|
|
230
231
|
autosave: boolean;
|
|
231
232
|
allowlistEnabled: boolean;
|
|
233
|
+
linkTrackingIds: boolean;
|
|
232
234
|
} | null>;
|
|
233
235
|
blocks: import("vue").ComputedRef<{
|
|
234
236
|
excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
|
|
@@ -1,9 +1,4 @@
|
|
|
1
1
|
import type { ModuleAddData, ModuleModifier } from '@@/Types/stripo';
|
|
2
|
-
/**
|
|
3
|
-
* Host-registered translation key for the "some attributes could not be
|
|
4
|
-
* converted" toaster. Guido resolves it against the host's `window.trans.en`;
|
|
5
|
-
* the copy is registered host-side.
|
|
6
|
-
*/
|
|
7
2
|
export declare const UNRESOLVED_DYNAMIC_CONTENT_ON_DROP_KEY = "dynamic-content.unresolved-attributes-on-drop";
|
|
8
3
|
/**
|
|
9
4
|
* Repairs label-form dynamic-content tokens in saved modules as they are dropped
|
|
@@ -1,2 +1,5 @@
|
|
|
1
1
|
import type { LegacyRecommendationConfig } from '@@/Types/config';
|
|
2
|
-
export
|
|
2
|
+
export interface MigrateOptions {
|
|
3
|
+
linkTrackingIds?: boolean;
|
|
4
|
+
}
|
|
5
|
+
export declare const migrate: (html: string, recommendationConfigs?: Record<string, LegacyRecommendationConfig>, options?: MigrateOptions) => Promise<string>;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Backfills persistent link tracking ids (SD-141414) at load so legacy
|
|
3
|
+
* templates, library imports and externally edited HTML enter the editor
|
|
4
|
+
* already tagged — before Stripo sees the document (no dirty flag, no undo).
|
|
5
|
+
*/
|
|
6
|
+
export declare function migrateTrackIds(html: string): string;
|
package/dist/src/library.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export { default as Guido } from './components/Guido.vue';
|
|
2
2
|
export type { GuidoConfig, GuidoConfigInput, IdentityConfig, PartnerConfig, TemplateConfig, TemplateMigrationConfig, LegacyRecommendationConfig, EditorConfig, UIConfig, FeaturesConfig, BlocksConfig, CompilerConfig, DynamicContent, EmailHeader, DefaultBlockType, CustomBlockType, ValidationResult, ValidationError, } from './@types/config';
|
|
3
3
|
export { validateConfig, parseConfig, parseConfigSafe, isValidConfig, getValidationErrors, MessageType, ProductType, } from './@types/config';
|
|
4
|
+
export { assignTrackingIds, readTrackSeq, TRACK_ID_ATTRIBUTE, TRACK_SEQ_ATTRIBUTE, } from './utils/linkTrackingIds';
|
|
5
|
+
export type { TrackingIdResult } from './utils/linkTrackingIds';
|
|
4
6
|
export type { StripoEventType } from './@types/events';
|
|
5
7
|
export type { PositionData, DynamicContentEvent, MergeTagClickEvent, MergeTag, BaseDynamicContent, DynamicContentNode, DynamicContentList, TooltipOptions, TextValueObject, L10n, } from './@types/generic';
|
|
@@ -102,6 +102,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
|
|
|
102
102
|
liquidSyntax: boolean;
|
|
103
103
|
autosave: boolean;
|
|
104
104
|
allowlistEnabled: boolean;
|
|
105
|
+
linkTrackingIds: boolean;
|
|
105
106
|
};
|
|
106
107
|
blocks: {
|
|
107
108
|
excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
|
|
@@ -240,6 +241,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
|
|
|
240
241
|
liquidSyntax: boolean;
|
|
241
242
|
autosave: boolean;
|
|
242
243
|
allowlistEnabled: boolean;
|
|
244
|
+
linkTrackingIds: boolean;
|
|
243
245
|
};
|
|
244
246
|
blocks: {
|
|
245
247
|
excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
|
|
@@ -378,6 +380,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
|
|
|
378
380
|
liquidSyntax: boolean;
|
|
379
381
|
autosave: boolean;
|
|
380
382
|
allowlistEnabled: boolean;
|
|
383
|
+
linkTrackingIds: boolean;
|
|
381
384
|
};
|
|
382
385
|
blocks: {
|
|
383
386
|
excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
|
|
@@ -516,6 +519,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
|
|
|
516
519
|
liquidSyntax: boolean;
|
|
517
520
|
autosave: boolean;
|
|
518
521
|
allowlistEnabled: boolean;
|
|
522
|
+
linkTrackingIds: boolean;
|
|
519
523
|
};
|
|
520
524
|
blocks: {
|
|
521
525
|
excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
|
|
@@ -654,6 +658,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
|
|
|
654
658
|
liquidSyntax: boolean;
|
|
655
659
|
autosave: boolean;
|
|
656
660
|
allowlistEnabled: boolean;
|
|
661
|
+
linkTrackingIds: boolean;
|
|
657
662
|
};
|
|
658
663
|
blocks: {
|
|
659
664
|
excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
|
|
@@ -792,6 +797,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
|
|
|
792
797
|
liquidSyntax: boolean;
|
|
793
798
|
autosave: boolean;
|
|
794
799
|
allowlistEnabled: boolean;
|
|
800
|
+
linkTrackingIds: boolean;
|
|
795
801
|
};
|
|
796
802
|
blocks: {
|
|
797
803
|
excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
|
|
@@ -930,6 +936,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
|
|
|
930
936
|
liquidSyntax: boolean;
|
|
931
937
|
autosave: boolean;
|
|
932
938
|
allowlistEnabled: boolean;
|
|
939
|
+
linkTrackingIds: boolean;
|
|
933
940
|
};
|
|
934
941
|
blocks: {
|
|
935
942
|
excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
|
|
@@ -1068,6 +1075,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
|
|
|
1068
1075
|
liquidSyntax: boolean;
|
|
1069
1076
|
autosave: boolean;
|
|
1070
1077
|
allowlistEnabled: boolean;
|
|
1078
|
+
linkTrackingIds: boolean;
|
|
1071
1079
|
};
|
|
1072
1080
|
blocks: {
|
|
1073
1081
|
excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
|
|
@@ -1206,6 +1214,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
|
|
|
1206
1214
|
liquidSyntax: boolean;
|
|
1207
1215
|
autosave: boolean;
|
|
1208
1216
|
allowlistEnabled: boolean;
|
|
1217
|
+
linkTrackingIds: boolean;
|
|
1209
1218
|
};
|
|
1210
1219
|
blocks: {
|
|
1211
1220
|
excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
|
|
@@ -1344,6 +1353,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
|
|
|
1344
1353
|
liquidSyntax: boolean;
|
|
1345
1354
|
autosave: boolean;
|
|
1346
1355
|
allowlistEnabled: boolean;
|
|
1356
|
+
linkTrackingIds: boolean;
|
|
1347
1357
|
};
|
|
1348
1358
|
blocks: {
|
|
1349
1359
|
excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
|
|
@@ -1482,6 +1492,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
|
|
|
1482
1492
|
liquidSyntax: boolean;
|
|
1483
1493
|
autosave: boolean;
|
|
1484
1494
|
allowlistEnabled: boolean;
|
|
1495
|
+
linkTrackingIds: boolean;
|
|
1485
1496
|
};
|
|
1486
1497
|
blocks: {
|
|
1487
1498
|
excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
|
|
@@ -1620,6 +1631,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
|
|
|
1620
1631
|
liquidSyntax: boolean;
|
|
1621
1632
|
autosave: boolean;
|
|
1622
1633
|
allowlistEnabled: boolean;
|
|
1634
|
+
linkTrackingIds: boolean;
|
|
1623
1635
|
};
|
|
1624
1636
|
blocks: {
|
|
1625
1637
|
excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
|
|
@@ -1758,6 +1770,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
|
|
|
1758
1770
|
liquidSyntax: boolean;
|
|
1759
1771
|
autosave: boolean;
|
|
1760
1772
|
allowlistEnabled: boolean;
|
|
1773
|
+
linkTrackingIds: boolean;
|
|
1761
1774
|
};
|
|
1762
1775
|
blocks: {
|
|
1763
1776
|
excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
|
|
@@ -1896,6 +1909,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
|
|
|
1896
1909
|
liquidSyntax: boolean;
|
|
1897
1910
|
autosave: boolean;
|
|
1898
1911
|
allowlistEnabled: boolean;
|
|
1912
|
+
linkTrackingIds: boolean;
|
|
1899
1913
|
};
|
|
1900
1914
|
blocks: {
|
|
1901
1915
|
excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
|
|
@@ -2034,6 +2048,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
|
|
|
2034
2048
|
liquidSyntax: boolean;
|
|
2035
2049
|
autosave: boolean;
|
|
2036
2050
|
allowlistEnabled: boolean;
|
|
2051
|
+
linkTrackingIds: boolean;
|
|
2037
2052
|
};
|
|
2038
2053
|
blocks: {
|
|
2039
2054
|
excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
|
|
@@ -2172,6 +2187,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
|
|
|
2172
2187
|
liquidSyntax: boolean;
|
|
2173
2188
|
autosave: boolean;
|
|
2174
2189
|
allowlistEnabled: boolean;
|
|
2190
|
+
linkTrackingIds: boolean;
|
|
2175
2191
|
};
|
|
2176
2192
|
blocks: {
|
|
2177
2193
|
excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
|
|
@@ -2310,6 +2326,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
|
|
|
2310
2326
|
liquidSyntax: boolean;
|
|
2311
2327
|
autosave: boolean;
|
|
2312
2328
|
allowlistEnabled: boolean;
|
|
2329
|
+
linkTrackingIds: boolean;
|
|
2313
2330
|
};
|
|
2314
2331
|
blocks: {
|
|
2315
2332
|
excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
|
|
@@ -2450,6 +2467,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
|
|
|
2450
2467
|
liquidSyntax: boolean;
|
|
2451
2468
|
autosave: boolean;
|
|
2452
2469
|
allowlistEnabled: boolean;
|
|
2470
|
+
linkTrackingIds: boolean;
|
|
2453
2471
|
};
|
|
2454
2472
|
blocks: {
|
|
2455
2473
|
excludeDefaults: ("amp-accordion" | "amp-carousel" | "amp-form-controls" | "banner-block" | "button-block" | "html-block" | "image-block" | "menu-block" | "social-block" | "spacer-block" | "text-block" | "timer-block" | "video-block")[];
|
|
@@ -9,6 +9,7 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
|
|
|
9
9
|
isStripoInitialized: boolean;
|
|
10
10
|
templateId: string;
|
|
11
11
|
syncModulesEnabled: boolean;
|
|
12
|
+
trackIdSessionFloor: number;
|
|
12
13
|
}, {
|
|
13
14
|
isEditorToolbarVisible: (state: {
|
|
14
15
|
loadingStatus: boolean;
|
|
@@ -21,6 +22,7 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
|
|
|
21
22
|
isStripoInitialized: boolean;
|
|
22
23
|
templateId: string;
|
|
23
24
|
syncModulesEnabled: boolean;
|
|
25
|
+
trackIdSessionFloor: number;
|
|
24
26
|
} & import("pinia").PiniaCustomStateProperties<{
|
|
25
27
|
loadingStatus: boolean;
|
|
26
28
|
isCodeEditorOpen: boolean;
|
|
@@ -32,6 +34,7 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
|
|
|
32
34
|
isStripoInitialized: boolean;
|
|
33
35
|
templateId: string;
|
|
34
36
|
syncModulesEnabled: boolean;
|
|
37
|
+
trackIdSessionFloor: number;
|
|
35
38
|
}>) => boolean;
|
|
36
39
|
isUndoButtonDisabled: (state: {
|
|
37
40
|
loadingStatus: boolean;
|
|
@@ -44,6 +47,7 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
|
|
|
44
47
|
isStripoInitialized: boolean;
|
|
45
48
|
templateId: string;
|
|
46
49
|
syncModulesEnabled: boolean;
|
|
50
|
+
trackIdSessionFloor: number;
|
|
47
51
|
} & import("pinia").PiniaCustomStateProperties<{
|
|
48
52
|
loadingStatus: boolean;
|
|
49
53
|
isCodeEditorOpen: boolean;
|
|
@@ -55,6 +59,7 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
|
|
|
55
59
|
isStripoInitialized: boolean;
|
|
56
60
|
templateId: string;
|
|
57
61
|
syncModulesEnabled: boolean;
|
|
62
|
+
trackIdSessionFloor: number;
|
|
58
63
|
}>) => boolean;
|
|
59
64
|
isRedoButtonDisabled: (state: {
|
|
60
65
|
loadingStatus: boolean;
|
|
@@ -67,6 +72,7 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
|
|
|
67
72
|
isStripoInitialized: boolean;
|
|
68
73
|
templateId: string;
|
|
69
74
|
syncModulesEnabled: boolean;
|
|
75
|
+
trackIdSessionFloor: number;
|
|
70
76
|
} & import("pinia").PiniaCustomStateProperties<{
|
|
71
77
|
loadingStatus: boolean;
|
|
72
78
|
isCodeEditorOpen: boolean;
|
|
@@ -78,6 +84,7 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
|
|
|
78
84
|
isStripoInitialized: boolean;
|
|
79
85
|
templateId: string;
|
|
80
86
|
syncModulesEnabled: boolean;
|
|
87
|
+
trackIdSessionFloor: number;
|
|
81
88
|
}>) => boolean;
|
|
82
89
|
isCodeEditorButtonDisabled: (state: {
|
|
83
90
|
loadingStatus: boolean;
|
|
@@ -90,6 +97,7 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
|
|
|
90
97
|
isStripoInitialized: boolean;
|
|
91
98
|
templateId: string;
|
|
92
99
|
syncModulesEnabled: boolean;
|
|
100
|
+
trackIdSessionFloor: number;
|
|
93
101
|
} & import("pinia").PiniaCustomStateProperties<{
|
|
94
102
|
loadingStatus: boolean;
|
|
95
103
|
isCodeEditorOpen: boolean;
|
|
@@ -101,6 +109,7 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
|
|
|
101
109
|
isStripoInitialized: boolean;
|
|
102
110
|
templateId: string;
|
|
103
111
|
syncModulesEnabled: boolean;
|
|
112
|
+
trackIdSessionFloor: number;
|
|
104
113
|
}>) => boolean;
|
|
105
114
|
isPreviewButtonDisabled: (state: {
|
|
106
115
|
loadingStatus: boolean;
|
|
@@ -113,6 +122,7 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
|
|
|
113
122
|
isStripoInitialized: boolean;
|
|
114
123
|
templateId: string;
|
|
115
124
|
syncModulesEnabled: boolean;
|
|
125
|
+
trackIdSessionFloor: number;
|
|
116
126
|
} & import("pinia").PiniaCustomStateProperties<{
|
|
117
127
|
loadingStatus: boolean;
|
|
118
128
|
isCodeEditorOpen: boolean;
|
|
@@ -124,6 +134,7 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
|
|
|
124
134
|
isStripoInitialized: boolean;
|
|
125
135
|
templateId: string;
|
|
126
136
|
syncModulesEnabled: boolean;
|
|
137
|
+
trackIdSessionFloor: number;
|
|
127
138
|
}>) => boolean;
|
|
128
139
|
isViewOptionsDisabled: (state: {
|
|
129
140
|
loadingStatus: boolean;
|
|
@@ -136,6 +147,7 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
|
|
|
136
147
|
isStripoInitialized: boolean;
|
|
137
148
|
templateId: string;
|
|
138
149
|
syncModulesEnabled: boolean;
|
|
150
|
+
trackIdSessionFloor: number;
|
|
139
151
|
} & import("pinia").PiniaCustomStateProperties<{
|
|
140
152
|
loadingStatus: boolean;
|
|
141
153
|
isCodeEditorOpen: boolean;
|
|
@@ -147,6 +159,7 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
|
|
|
147
159
|
isStripoInitialized: boolean;
|
|
148
160
|
templateId: string;
|
|
149
161
|
syncModulesEnabled: boolean;
|
|
162
|
+
trackIdSessionFloor: number;
|
|
150
163
|
}>) => boolean;
|
|
151
164
|
isVersionHistoryButtonDisabled: (state: {
|
|
152
165
|
loadingStatus: boolean;
|
|
@@ -159,6 +172,7 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
|
|
|
159
172
|
isStripoInitialized: boolean;
|
|
160
173
|
templateId: string;
|
|
161
174
|
syncModulesEnabled: boolean;
|
|
175
|
+
trackIdSessionFloor: number;
|
|
162
176
|
} & import("pinia").PiniaCustomStateProperties<{
|
|
163
177
|
loadingStatus: boolean;
|
|
164
178
|
isCodeEditorOpen: boolean;
|
|
@@ -170,6 +184,7 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
|
|
|
170
184
|
isStripoInitialized: boolean;
|
|
171
185
|
templateId: string;
|
|
172
186
|
syncModulesEnabled: boolean;
|
|
187
|
+
trackIdSessionFloor: number;
|
|
173
188
|
}>) => boolean;
|
|
174
189
|
isExportButtonDisabled: (state: {
|
|
175
190
|
loadingStatus: boolean;
|
|
@@ -182,6 +197,7 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
|
|
|
182
197
|
isStripoInitialized: boolean;
|
|
183
198
|
templateId: string;
|
|
184
199
|
syncModulesEnabled: boolean;
|
|
200
|
+
trackIdSessionFloor: number;
|
|
185
201
|
} & import("pinia").PiniaCustomStateProperties<{
|
|
186
202
|
loadingStatus: boolean;
|
|
187
203
|
isCodeEditorOpen: boolean;
|
|
@@ -193,6 +209,7 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
|
|
|
193
209
|
isStripoInitialized: boolean;
|
|
194
210
|
templateId: string;
|
|
195
211
|
syncModulesEnabled: boolean;
|
|
212
|
+
trackIdSessionFloor: number;
|
|
196
213
|
}>) => boolean;
|
|
197
214
|
isSaveAsButtonDisabled: (state: {
|
|
198
215
|
loadingStatus: boolean;
|
|
@@ -205,6 +222,7 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
|
|
|
205
222
|
isStripoInitialized: boolean;
|
|
206
223
|
templateId: string;
|
|
207
224
|
syncModulesEnabled: boolean;
|
|
225
|
+
trackIdSessionFloor: number;
|
|
208
226
|
} & import("pinia").PiniaCustomStateProperties<{
|
|
209
227
|
loadingStatus: boolean;
|
|
210
228
|
isCodeEditorOpen: boolean;
|
|
@@ -216,6 +234,7 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
|
|
|
216
234
|
isStripoInitialized: boolean;
|
|
217
235
|
templateId: string;
|
|
218
236
|
syncModulesEnabled: boolean;
|
|
237
|
+
trackIdSessionFloor: number;
|
|
219
238
|
}>) => boolean;
|
|
220
239
|
isTestButtonDisabled: (state: {
|
|
221
240
|
loadingStatus: boolean;
|
|
@@ -228,6 +247,7 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
|
|
|
228
247
|
isStripoInitialized: boolean;
|
|
229
248
|
templateId: string;
|
|
230
249
|
syncModulesEnabled: boolean;
|
|
250
|
+
trackIdSessionFloor: number;
|
|
231
251
|
} & import("pinia").PiniaCustomStateProperties<{
|
|
232
252
|
loadingStatus: boolean;
|
|
233
253
|
isCodeEditorOpen: boolean;
|
|
@@ -239,6 +259,7 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
|
|
|
239
259
|
isStripoInitialized: boolean;
|
|
240
260
|
templateId: string;
|
|
241
261
|
syncModulesEnabled: boolean;
|
|
262
|
+
trackIdSessionFloor: number;
|
|
242
263
|
}>) => boolean;
|
|
243
264
|
isSaveButtonDisabled: (state: {
|
|
244
265
|
loadingStatus: boolean;
|
|
@@ -251,6 +272,7 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
|
|
|
251
272
|
isStripoInitialized: boolean;
|
|
252
273
|
templateId: string;
|
|
253
274
|
syncModulesEnabled: boolean;
|
|
275
|
+
trackIdSessionFloor: number;
|
|
254
276
|
} & import("pinia").PiniaCustomStateProperties<{
|
|
255
277
|
loadingStatus: boolean;
|
|
256
278
|
isCodeEditorOpen: boolean;
|
|
@@ -262,6 +284,7 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
|
|
|
262
284
|
isStripoInitialized: boolean;
|
|
263
285
|
templateId: string;
|
|
264
286
|
syncModulesEnabled: boolean;
|
|
287
|
+
trackIdSessionFloor: number;
|
|
265
288
|
}>) => boolean;
|
|
266
289
|
isInSaveableState: (state: {
|
|
267
290
|
loadingStatus: boolean;
|
|
@@ -274,6 +297,7 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
|
|
|
274
297
|
isStripoInitialized: boolean;
|
|
275
298
|
templateId: string;
|
|
276
299
|
syncModulesEnabled: boolean;
|
|
300
|
+
trackIdSessionFloor: number;
|
|
277
301
|
} & import("pinia").PiniaCustomStateProperties<{
|
|
278
302
|
loadingStatus: boolean;
|
|
279
303
|
isCodeEditorOpen: boolean;
|
|
@@ -285,5 +309,6 @@ export declare const useEditorStore: import("pinia").StoreDefinition<"guidoEdito
|
|
|
285
309
|
isStripoInitialized: boolean;
|
|
286
310
|
templateId: string;
|
|
287
311
|
syncModulesEnabled: boolean;
|
|
312
|
+
trackIdSessionFloor: number;
|
|
288
313
|
}>) => boolean;
|
|
289
314
|
}, {}>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Persistent link tracking ids for the click heatmap (SD-141414).
|
|
3
|
+
* Pure string transforms — no DOM parse/serialize round-trip, safe for both
|
|
4
|
+
* Stripo raw HTML and hand-authored HTML-editor documents. Shared with email-fe.
|
|
5
|
+
*/
|
|
6
|
+
export declare const TRACK_ID_ATTRIBUTE = "data-ins-track-id";
|
|
7
|
+
export declare const TRACK_SEQ_ATTRIBUTE = "data-ins-track-seq";
|
|
8
|
+
export interface TrackingIdResult {
|
|
9
|
+
html: string;
|
|
10
|
+
changed: boolean;
|
|
11
|
+
nextSeq: number;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Reads the persisted id high-water mark: <body> attr, then <html> attr,
|
|
15
|
+
* then the leading comment fallback. Returns 0 when absent.
|
|
16
|
+
*/
|
|
17
|
+
export declare function readTrackSeq(html: string): number;
|
|
18
|
+
/**
|
|
19
|
+
* Ensures every <a> opening tag carries a unique positive-integer id and the
|
|
20
|
+
* document records the id high-water mark. Ids are minted above
|
|
21
|
+
* max(persisted seq, max id in document, floor) so deleted ids are never
|
|
22
|
+
* reused — even after a version restore or paste-over (floor = session floor).
|
|
23
|
+
* Idempotent: a document already normalized returns changed=false.
|
|
24
|
+
*/
|
|
25
|
+
export declare function assignTrackingIds(html: string, floor?: number): TrackingIdResult;
|
package/dist/stores/editor.js
CHANGED
|
@@ -10,7 +10,10 @@ const o = e("guidoEditor", {
|
|
|
10
10
|
hasChanges: !1,
|
|
11
11
|
isStripoInitialized: !1,
|
|
12
12
|
templateId: "",
|
|
13
|
-
syncModulesEnabled: !1
|
|
13
|
+
syncModulesEnabled: !1,
|
|
14
|
+
// In-session id high-water mark; floors tracking-id minting so ids
|
|
15
|
+
// deleted by a version restore / paste-over are never reused.
|
|
16
|
+
trackIdSessionFloor: 0
|
|
14
17
|
}),
|
|
15
18
|
getters: {
|
|
16
19
|
// Middle Slot
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
const E = "data-ins-track-id", g = "data-ins-track-seq", N = /<a\b[^>]*>/gi, $ = /\bdata-ins-track-id\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s>]+))/i, R = /\bdata-ins-track-seq\s*=\s*(?:"(\d+)"|'(\d+)'|(\d+))/i, f = /<body\b[^>]*>/i, b = /<html\b[^>]*>/i, A = /<!--\s*ins-track-seq:(\d+)\s*-->/i, k = /^[1-9][0-9]{0,14}$/;
|
|
2
|
+
function S(e) {
|
|
3
|
+
const s = Number(e);
|
|
4
|
+
return Number.isSafeInteger(s) && s > 0 ? s : 0;
|
|
5
|
+
}
|
|
6
|
+
function x(e) {
|
|
7
|
+
var i, a, c;
|
|
8
|
+
const n = [(i = f.exec(e)) == null ? void 0 : i[0], (a = b.exec(e)) == null ? void 0 : a[0]].reduce(
|
|
9
|
+
(T, o) => T ?? (o ? R.exec(o) : null),
|
|
10
|
+
null
|
|
11
|
+
), t = (n == null ? void 0 : n[1]) ?? (n == null ? void 0 : n[2]) ?? (n == null ? void 0 : n[3]) ?? ((c = A.exec(e)) == null ? void 0 : c[1]) ?? "";
|
|
12
|
+
return S(t);
|
|
13
|
+
}
|
|
14
|
+
function I(e, s) {
|
|
15
|
+
const n = `${g}="${s}"`, t = f.exec(e) ?? b.exec(e);
|
|
16
|
+
if (t) {
|
|
17
|
+
const [i] = t, a = R.exec(i), c = a ? i.replace(a[0], n) : i.replace(/\/?>$/, (T) => ` ${n}${T}`);
|
|
18
|
+
return e.slice(0, t.index) + c + e.slice(t.index + i.length);
|
|
19
|
+
}
|
|
20
|
+
return A.test(e) ? e.replace(A, `<!--ins-track-seq:${s}-->`) : `<!--ins-track-seq:${s}-->${e}`;
|
|
21
|
+
}
|
|
22
|
+
function p(e, s, n) {
|
|
23
|
+
const t = `${E}="${n}"`;
|
|
24
|
+
return s ? e.replace(s[0], t) : e.replace(/^<a\b/i, (i) => `${i} ${t}`);
|
|
25
|
+
}
|
|
26
|
+
function q(e, s = 0) {
|
|
27
|
+
const n = /* @__PURE__ */ new Set();
|
|
28
|
+
let t = 0;
|
|
29
|
+
const i = [...e.matchAll(N)].map((r) => {
|
|
30
|
+
const [_] = r, u = $.exec(_), l = u ? u[1] ?? u[2] ?? u[3] ?? "" : "";
|
|
31
|
+
let d = null;
|
|
32
|
+
return k.test(l) && !n.has(Number(l)) && (d = Number(l), n.add(d), t = Math.max(t, d)), { index: r.index, tag: _, attrMatch: u, id: d };
|
|
33
|
+
});
|
|
34
|
+
let a = Math.max(x(e), t, s), c = "", T = 0, o = !1;
|
|
35
|
+
return i.forEach((r) => {
|
|
36
|
+
c += e.slice(T, r.index), r.id === null ? (a += 1, c += p(r.tag, r.attrMatch, a), o = !0) : c += r.tag, T = r.index + r.tag.length;
|
|
37
|
+
}), c += e.slice(T), a > 0 && x(c) !== a && (c = I(c, a), o = !0), { html: c, changed: o, nextSeq: a };
|
|
38
|
+
}
|
|
39
|
+
export {
|
|
40
|
+
E as TRACK_ID_ATTRIBUTE,
|
|
41
|
+
g as TRACK_SEQ_ATTRIBUTE,
|
|
42
|
+
q as assignTrackingIds,
|
|
43
|
+
x as readTrackSeq
|
|
44
|
+
};
|
|
@@ -1,62 +1,65 @@
|
|
|
1
|
-
import { useActionsApi as
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
1
|
+
import { useActionsApi as k } from "../composables/useActionsApi.js";
|
|
2
|
+
import { useConfig as U } from "../composables/useConfig.js";
|
|
3
|
+
import { useHtmlCompiler as x } from "../composables/useHtmlCompiler.js";
|
|
4
|
+
import { DEFAULT_CURRENCY as d, DEFAULT_NODE_CONFIG as s } from "../extensions/Blocks/Recommendation/constants/defaultConfig.js";
|
|
5
|
+
import { useRecommendationExtensionStore as T } from "../extensions/Blocks/Recommendation/store/recommendation.js";
|
|
6
|
+
import { mapLegacyStrategy as L } from "../extensions/Blocks/Recommendation/utils/legacyStrategyMap.js";
|
|
7
|
+
import { DATA_ATTRIBUTES as C } from "../extensions/Blocks/Unsubscribe/utils/constants.js";
|
|
8
|
+
import { parsePageList as R } from "../extensions/Blocks/Unsubscribe/utils/utils.js";
|
|
9
|
+
import { useDynamicContentStore as N } from "../stores/dynamic-content.js";
|
|
10
|
+
import { useEditorStore as z } from "../stores/editor.js";
|
|
11
|
+
import { useUnsubscribeStore as _ } from "../stores/unsubscribe.js";
|
|
12
|
+
import { assignTrackingIds as v } from "./linkTrackingIds.js";
|
|
13
|
+
function O(c) {
|
|
14
|
+
const n = new DOMParser().parseFromString(c, "text/html").querySelectorAll(`[${C.PAGE_LIST}]`), t = [];
|
|
15
|
+
return n.forEach((a) => {
|
|
16
|
+
const r = a.getAttribute(C.PAGE_LIST);
|
|
17
|
+
r && t.push(...R(r));
|
|
15
18
|
}), [...new Set(t)];
|
|
16
19
|
}
|
|
17
|
-
async function
|
|
18
|
-
const m = new DOMParser().parseFromString(
|
|
20
|
+
async function M(c) {
|
|
21
|
+
const m = new DOMParser().parseFromString(c, "text/html").querySelectorAll(".recommendation-block-v2");
|
|
19
22
|
if (m.length === 0)
|
|
20
23
|
return;
|
|
21
|
-
const
|
|
24
|
+
const n = T();
|
|
22
25
|
m.forEach((t) => {
|
|
23
|
-
var
|
|
24
|
-
const a = t.getAttribute("recommendation-id"),
|
|
25
|
-
if (!Number.isFinite(
|
|
26
|
+
var l, g, f, i, S;
|
|
27
|
+
const a = t.getAttribute("recommendation-id"), r = a ? Number(a) : NaN;
|
|
28
|
+
if (!Number.isFinite(r))
|
|
26
29
|
return;
|
|
27
|
-
const
|
|
28
|
-
if (!
|
|
30
|
+
const p = t.getAttribute("esd-ext-config");
|
|
31
|
+
if (!p)
|
|
29
32
|
return;
|
|
30
33
|
let e;
|
|
31
34
|
try {
|
|
32
|
-
e = JSON.parse(
|
|
35
|
+
e = JSON.parse(p);
|
|
33
36
|
} catch {
|
|
34
37
|
return;
|
|
35
38
|
}
|
|
36
39
|
if (!e || typeof e != "object" || Array.isArray(e))
|
|
37
40
|
return;
|
|
38
|
-
const
|
|
41
|
+
const o = {
|
|
39
42
|
// Normalize legacy strategy keys (e.g. `mostViewed` → `mostPopular`) so
|
|
40
43
|
// already-saved blocks that never re-run the migrator don't emit a
|
|
41
44
|
// strategy-less campaign URL. `||` also catches '' / undefined (SD-144882).
|
|
42
|
-
strategy:
|
|
43
|
-
language: e.language ??
|
|
44
|
-
size: e.size ??
|
|
45
|
+
strategy: L(e.strategy) || s.strategy,
|
|
46
|
+
language: e.language ?? s.language,
|
|
47
|
+
size: e.size ?? s.size,
|
|
45
48
|
// Spread the default arrays so each block gets a fresh reference
|
|
46
49
|
// instead of sharing the singleton in DEFAULT_NODE_CONFIG.
|
|
47
|
-
productIds: e.productIds ?? [...
|
|
48
|
-
filters: e.filters ?? [...
|
|
49
|
-
shuffleProducts: e.shuffleProducts ??
|
|
50
|
-
currencyCode: ((
|
|
51
|
-
currencyAlignment: ((
|
|
52
|
-
currencyDecimalCount: ((
|
|
53
|
-
currencyDecimalSeparator: ((
|
|
54
|
-
currencyThousandSeparator: ((
|
|
50
|
+
productIds: e.productIds ?? [...s.productIds],
|
|
51
|
+
filters: e.filters ?? [...s.filters],
|
|
52
|
+
shuffleProducts: e.shuffleProducts ?? s.shuffleProducts,
|
|
53
|
+
currencyCode: ((l = e.currency) == null ? void 0 : l.code) ?? d.code,
|
|
54
|
+
currencyAlignment: ((g = e.currency) == null ? void 0 : g.alignment) ?? d.alignment,
|
|
55
|
+
currencyDecimalCount: ((f = e.currency) == null ? void 0 : f.decimalCount) ?? d.decimalCount,
|
|
56
|
+
currencyDecimalSeparator: ((i = e.currency) == null ? void 0 : i.decimalSeparator) ?? d.decimalSeparator,
|
|
57
|
+
currencyThousandSeparator: ((S = e.currency) == null ? void 0 : S.thousandSeparator) ?? d.thousandSeparator
|
|
55
58
|
};
|
|
56
|
-
|
|
59
|
+
n.seedBlockUrlConfig(r, o);
|
|
57
60
|
});
|
|
58
61
|
try {
|
|
59
|
-
await
|
|
62
|
+
await n.fetchRecommendationCreateData();
|
|
60
63
|
} catch (t) {
|
|
61
64
|
console.warn(
|
|
62
65
|
"Recommendation reference data pre-load failed; validator will skip the availability check.",
|
|
@@ -64,43 +67,51 @@ async function R(s) {
|
|
|
64
67
|
);
|
|
65
68
|
}
|
|
66
69
|
}
|
|
67
|
-
const
|
|
68
|
-
const
|
|
70
|
+
const Z = () => {
|
|
71
|
+
const c = N(), u = _(), { getCompiledEmail: m, getTemplateData: n, updateHtmlAndCss: t } = k(), { compileHtml: a, compileAmpHtml: r } = x(), { isFeatureEnabled: p } = U();
|
|
69
72
|
return {
|
|
70
73
|
prepareTemplateDetails: async () => {
|
|
71
|
-
|
|
74
|
+
let { html: o, css: l, syncModulesIds: g = [] } = await n();
|
|
75
|
+
if (p("linkTrackingIds"))
|
|
76
|
+
try {
|
|
77
|
+
const h = z(), { html: A, changed: H, nextSeq: I } = v(o, h.trackIdSessionFloor);
|
|
78
|
+
H && (t(A, l), o = A), h.trackIdSessionFloor = I;
|
|
79
|
+
} catch (h) {
|
|
80
|
+
console.error("Tracking-id assignment failed, saving without new ids:", h);
|
|
81
|
+
}
|
|
82
|
+
const { html: f, ampHtml: i = "", ampErrors: S = [] } = await m({
|
|
72
83
|
minimize: !0,
|
|
73
84
|
resetDataSavedFlag: !1
|
|
74
|
-
})
|
|
75
|
-
u.selectedUnsubscribePages.length && await u.fetchTemplates(), await
|
|
76
|
-
const { compiledHtml:
|
|
85
|
+
});
|
|
86
|
+
u.selectedUnsubscribePages.length && await u.fetchTemplates(), await M(o);
|
|
87
|
+
const { compiledHtml: w, stats: y, appliedRules: D } = a(f), E = i && r(i).compiledHtml, P = c.getSelectedDynamicContentList, F = T(), b = O(o);
|
|
77
88
|
return console.debug("HTML Compilation Stats:", {
|
|
78
|
-
originalSize:
|
|
79
|
-
compiledSize:
|
|
80
|
-
reduction: `${
|
|
81
|
-
appliedRules:
|
|
82
|
-
executionTime: `${
|
|
89
|
+
originalSize: y.originalSize,
|
|
90
|
+
compiledSize: y.compiledSize,
|
|
91
|
+
reduction: `${y.reductionPercentage.toFixed(2)}%`,
|
|
92
|
+
appliedRules: D,
|
|
93
|
+
executionTime: `${y.executionTime.toFixed(2)}ms`
|
|
83
94
|
}), {
|
|
84
|
-
dynamicContentList:
|
|
85
|
-
compiledHtml:
|
|
86
|
-
rawHtml:
|
|
87
|
-
css:
|
|
88
|
-
ampHtml:
|
|
89
|
-
ampErrors:
|
|
95
|
+
dynamicContentList: P,
|
|
96
|
+
compiledHtml: w,
|
|
97
|
+
rawHtml: o,
|
|
98
|
+
css: l,
|
|
99
|
+
ampHtml: E,
|
|
100
|
+
ampErrors: S,
|
|
90
101
|
modules: g.map(Number),
|
|
91
102
|
recommendation: {
|
|
92
|
-
campaignUrls:
|
|
103
|
+
campaignUrls: F.recommendationCampaignUrls,
|
|
93
104
|
configs: {}
|
|
94
105
|
},
|
|
95
106
|
unsubscribe: {
|
|
96
|
-
status:
|
|
97
|
-
config:
|
|
107
|
+
status: b.length > 0,
|
|
108
|
+
config: b
|
|
98
109
|
}
|
|
99
110
|
};
|
|
100
111
|
}
|
|
101
112
|
};
|
|
102
113
|
};
|
|
103
114
|
export {
|
|
104
|
-
|
|
105
|
-
|
|
115
|
+
O as getHtmlReferencedUnsubscribePages,
|
|
116
|
+
Z as useTemplatePreparation
|
|
106
117
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@useinsider/guido",
|
|
3
|
-
"version": "3.13.
|
|
3
|
+
"version": "3.13.1-beta.a1e3c5f",
|
|
4
4
|
"description": "Guido is a Vue + TypeScript wrapper for Email Plugin. Easily embed the email editor in your Vue applications.",
|
|
5
5
|
"main": "./dist/guido.umd.cjs",
|
|
6
6
|
"module": "./dist/library.js",
|