@useinsider/guido 3.12.0 → 3.13.0-beta.ef18f66

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.
Files changed (54) hide show
  1. package/README.md +16 -1
  2. package/dist/@types/config/schemas.js +27 -25
  3. package/dist/components/Guido.vue.js +1 -1
  4. package/dist/components/Guido.vue2.js +110 -101
  5. package/dist/components/organisms/email-preview/desktop-preview/DesktopPreview.vue.js +1 -1
  6. package/dist/components/organisms/email-preview/desktop-preview/DesktopPreview.vue2.js +8 -8
  7. package/dist/components/organisms/email-preview/mobile-preview/ContentView.vue.js +5 -5
  8. package/dist/components/organisms/email-preview/mobile-preview/ContentView.vue2.js +10 -10
  9. package/dist/components/organisms/header/ViewOptions.vue.js +3 -3
  10. package/dist/components/organisms/header/version-history/ViewOptions.vue.js +1 -1
  11. package/dist/composables/useAllowlist.js +50 -0
  12. package/dist/composables/usePreviewInteractionGuard.js +36 -11
  13. package/dist/composables/useRecommendationPreview.js +61 -60
  14. package/dist/composables/useSave.js +42 -23
  15. package/dist/composables/useStripo.js +72 -69
  16. package/dist/composables/useUserRole.js +12 -0
  17. package/dist/enums/roles.js +4 -0
  18. package/dist/extensions/Blocks/Recommendation/constants/controlIds.js +1 -1
  19. package/dist/extensions/Blocks/Recommendation/controls/blockBackground/index.js +10 -0
  20. package/dist/extensions/Blocks/Recommendation/controls/omnibusDiscount/textAfter.js +12 -12
  21. package/dist/extensions/Blocks/Recommendation/controls/omnibusDiscount/textBefore.js +12 -12
  22. package/dist/extensions/Blocks/Recommendation/controls/omnibusPrice/textAfter.js +12 -12
  23. package/dist/extensions/Blocks/Recommendation/controls/omnibusPrice/textBefore.js +12 -12
  24. package/dist/extensions/Blocks/Recommendation/extension.js +23 -21
  25. package/dist/extensions/Blocks/Recommendation/settingsPanel.js +41 -40
  26. package/dist/extensions/Blocks/Recommendation/utils/captureStyleTemplates.js +7 -7
  27. package/dist/extensions/Blocks/Unsubscribe/utils/constants.js +3 -2
  28. package/dist/extensions/Blocks/controlFactories.js +125 -75
  29. package/dist/guido.css +1 -1
  30. package/dist/services/allowlistApi.js +15 -0
  31. package/dist/services/stripoApi.js +18 -18
  32. package/dist/src/@types/config/schemas.d.ts +10 -0
  33. package/dist/src/components/Guido.vue.d.ts +18 -2
  34. package/dist/src/composables/useAllowlist.d.ts +6 -0
  35. package/dist/src/composables/useConfig.d.ts +2 -0
  36. package/dist/src/composables/usePreviewInteractionGuard.d.ts +1 -1
  37. package/dist/src/composables/useStripo.d.ts +3 -2
  38. package/dist/src/composables/useUserRole.d.ts +3 -0
  39. package/dist/src/enums/roles.d.ts +9 -0
  40. package/dist/src/extensions/Blocks/Recommendation/constants/controlIds.d.ts +1 -0
  41. package/dist/src/extensions/Blocks/Recommendation/controls/blockBackground/index.d.ts +14 -0
  42. package/dist/src/extensions/Blocks/Recommendation/controls/index.d.ts +1 -0
  43. package/dist/src/extensions/Blocks/Unsubscribe/utils/constants.d.ts +1 -0
  44. package/dist/src/extensions/Blocks/controlFactories.d.ts +36 -0
  45. package/dist/src/services/allowlistApi.d.ts +4 -0
  46. package/dist/src/stores/config.d.ts +21 -1
  47. package/dist/src/utils/urlSchemes.d.ts +6 -0
  48. package/dist/static/styles/components/base-input.css.js +6 -7
  49. package/dist/stores/config.js +21 -19
  50. package/dist/utils/pairProductVariables.js +44 -43
  51. package/dist/{extensions/Blocks/Recommendation/utils → utils}/preserveTextStyles.js +1 -1
  52. package/dist/utils/urlSchemes.js +4 -0
  53. package/package.json +2 -2
  54. /package/dist/src/{extensions/Blocks/Recommendation/utils → utils}/preserveTextStyles.d.ts +0 -0
@@ -115,6 +115,42 @@ export declare function createTextBackgroundColorControl(controlId: string, targ
115
115
  isVisible(_node: ImmutableHtmlNode): boolean;
116
116
  };
117
117
  };
118
+ /**
119
+ * Factory for a background-color control that paints a whole extension block (SD-145082).
120
+ *
121
+ * Base is `ButtonBackgroundColorBuiltInControl` because its `GENERAL.BACKGROUND_COLOR` form key
122
+ * round-trips through `getValues()`; the block-text base (`TextBlockBackgroundBuiltInControl`, the
123
+ * built-in this replaces) reports `textBlockBackgroundColor`, which our read path never sees. That
124
+ * borrowed base targets the block's Buy buttons, so `getTargetNodes` here is a GUARD that keeps it
125
+ * off the buttons — not the write path.
126
+ *
127
+ * The write is entirely ours (`getAdditionalModifications`): Stripo's built-in emits a stylesheet
128
+ * rule that inline styles from regeneration outrank (SD-143023), so it would silently no-op on the
129
+ * next edit. We write inline `background-color` + `bgcolor` on the block `<td>` instead — surviving
130
+ * regeneration and reaching Outlook, matching the migrator's convention.
131
+ */
132
+ export declare function createBlockBackgroundColorControl(controlId: string, blockRootSelector?: string): {
133
+ new (): {
134
+ getId(): string;
135
+ /** The parent control renders its own generic title; restore the block-level wording. */
136
+ getLabels(): {
137
+ title: string;
138
+ };
139
+ /** Guard: redirect the borrowed button parent onto the block `<td>` so it never paints the Buy buttons. */
140
+ getTargetNodes(root: ImmutableHtmlNode): ImmutableHtmlNode[];
141
+ /**
142
+ * Writes the picked background onto the block as an inline style plus a `bgcolor`
143
+ * attribute. This is the whole mechanism, not a mirror: the parent control's own
144
+ * write never reaches the block element (verified at runtime). `bgcolor` is the
145
+ * channel Outlook honours on a `<td>`, and matches what the migrator emits.
146
+ */
147
+ getAdditionalModifications(root: ImmutableHtmlNode): import("@stripoinc/ui-editor-extensions").TemplateModifier<import("@stripoinc/ui-editor-extensions").HtmlNodeModifier, import("@stripoinc/ui-editor-extensions").CssNodeModifier> | undefined;
148
+ getParentControlId(): string;
149
+ api: import("@stripoinc/ui-editor-extensions").ControlApi;
150
+ getModificationDescription(): import("@stripoinc/ui-editor-extensions").ModificationDescription | undefined;
151
+ isVisible(_node: ImmutableHtmlNode): boolean;
152
+ };
153
+ };
118
154
  /**
119
155
  * Factory function to create paddings controls for different block elements
120
156
  * When targetBlockId and containerSelector are not provided, applies directly to root
@@ -0,0 +1,4 @@
1
+ export declare const useAllowlistApi: () => {
2
+ checkDomain: (domain: string) => Promise<boolean>;
3
+ getUserRole: () => Promise<string | undefined>;
4
+ };
@@ -101,6 +101,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
101
101
  modulesDisabled: boolean;
102
102
  liquidSyntax: boolean;
103
103
  autosave: boolean;
104
+ allowlistEnabled: boolean;
104
105
  };
105
106
  blocks: {
106
107
  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")[];
@@ -238,6 +239,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
238
239
  modulesDisabled: boolean;
239
240
  liquidSyntax: boolean;
240
241
  autosave: boolean;
242
+ allowlistEnabled: boolean;
241
243
  };
242
244
  blocks: {
243
245
  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")[];
@@ -375,6 +377,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
375
377
  modulesDisabled: boolean;
376
378
  liquidSyntax: boolean;
377
379
  autosave: boolean;
380
+ allowlistEnabled: boolean;
378
381
  };
379
382
  blocks: {
380
383
  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")[];
@@ -512,6 +515,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
512
515
  modulesDisabled: boolean;
513
516
  liquidSyntax: boolean;
514
517
  autosave: boolean;
518
+ allowlistEnabled: boolean;
515
519
  };
516
520
  blocks: {
517
521
  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")[];
@@ -649,6 +653,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
649
653
  modulesDisabled: boolean;
650
654
  liquidSyntax: boolean;
651
655
  autosave: boolean;
656
+ allowlistEnabled: boolean;
652
657
  };
653
658
  blocks: {
654
659
  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")[];
@@ -786,6 +791,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
786
791
  modulesDisabled: boolean;
787
792
  liquidSyntax: boolean;
788
793
  autosave: boolean;
794
+ allowlistEnabled: boolean;
789
795
  };
790
796
  blocks: {
791
797
  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")[];
@@ -923,6 +929,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
923
929
  modulesDisabled: boolean;
924
930
  liquidSyntax: boolean;
925
931
  autosave: boolean;
932
+ allowlistEnabled: boolean;
926
933
  };
927
934
  blocks: {
928
935
  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")[];
@@ -1060,6 +1067,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
1060
1067
  modulesDisabled: boolean;
1061
1068
  liquidSyntax: boolean;
1062
1069
  autosave: boolean;
1070
+ allowlistEnabled: boolean;
1063
1071
  };
1064
1072
  blocks: {
1065
1073
  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")[];
@@ -1197,6 +1205,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
1197
1205
  modulesDisabled: boolean;
1198
1206
  liquidSyntax: boolean;
1199
1207
  autosave: boolean;
1208
+ allowlistEnabled: boolean;
1200
1209
  };
1201
1210
  blocks: {
1202
1211
  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")[];
@@ -1334,6 +1343,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
1334
1343
  modulesDisabled: boolean;
1335
1344
  liquidSyntax: boolean;
1336
1345
  autosave: boolean;
1346
+ allowlistEnabled: boolean;
1337
1347
  };
1338
1348
  blocks: {
1339
1349
  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")[];
@@ -1471,6 +1481,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
1471
1481
  modulesDisabled: boolean;
1472
1482
  liquidSyntax: boolean;
1473
1483
  autosave: boolean;
1484
+ allowlistEnabled: boolean;
1474
1485
  };
1475
1486
  blocks: {
1476
1487
  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")[];
@@ -1608,6 +1619,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
1608
1619
  modulesDisabled: boolean;
1609
1620
  liquidSyntax: boolean;
1610
1621
  autosave: boolean;
1622
+ allowlistEnabled: boolean;
1611
1623
  };
1612
1624
  blocks: {
1613
1625
  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")[];
@@ -1745,6 +1757,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
1745
1757
  modulesDisabled: boolean;
1746
1758
  liquidSyntax: boolean;
1747
1759
  autosave: boolean;
1760
+ allowlistEnabled: boolean;
1748
1761
  };
1749
1762
  blocks: {
1750
1763
  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")[];
@@ -1882,6 +1895,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
1882
1895
  modulesDisabled: boolean;
1883
1896
  liquidSyntax: boolean;
1884
1897
  autosave: boolean;
1898
+ allowlistEnabled: boolean;
1885
1899
  };
1886
1900
  blocks: {
1887
1901
  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")[];
@@ -2019,6 +2033,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
2019
2033
  modulesDisabled: boolean;
2020
2034
  liquidSyntax: boolean;
2021
2035
  autosave: boolean;
2036
+ allowlistEnabled: boolean;
2022
2037
  };
2023
2038
  blocks: {
2024
2039
  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")[];
@@ -2156,6 +2171,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
2156
2171
  modulesDisabled: boolean;
2157
2172
  liquidSyntax: boolean;
2158
2173
  autosave: boolean;
2174
+ allowlistEnabled: boolean;
2159
2175
  };
2160
2176
  blocks: {
2161
2177
  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")[];
@@ -2293,6 +2309,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
2293
2309
  modulesDisabled: boolean;
2294
2310
  liquidSyntax: boolean;
2295
2311
  autosave: boolean;
2312
+ allowlistEnabled: boolean;
2296
2313
  };
2297
2314
  blocks: {
2298
2315
  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")[];
@@ -2336,7 +2353,9 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
2336
2353
  } | null;
2337
2354
  } & import("pinia").PiniaCustomStateProperties<ConfigStoreState>) => boolean;
2338
2355
  /**
2339
- * Check if a specific feature is enabled
2356
+ * Check if a specific feature is enabled.
2357
+ * Returns false before init (config null) so header controls don't
2358
+ * flash on during loading, then disappear once config resolves.
2340
2359
  */
2341
2360
  isFeatureEnabled: (state: {
2342
2361
  initialized: boolean;
@@ -2430,6 +2449,7 @@ export declare const useConfigStore: import("pinia").StoreDefinition<"guido-conf
2430
2449
  modulesDisabled: boolean;
2431
2450
  liquidSyntax: boolean;
2432
2451
  autosave: boolean;
2452
+ allowlistEnabled: boolean;
2433
2453
  };
2434
2454
  blocks: {
2435
2455
  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")[];
@@ -0,0 +1,6 @@
1
+ /**
2
+ * URL schemes that are safe to follow from partner-authored email HTML. Shared so a
3
+ * future bypass fix lands in one place — the preview guard and the recommendation
4
+ * sanitizer both gate on it. Stored with the trailing colon to match `anchor.protocol`.
5
+ */
6
+ export declare const BASE_SAFE_URL_SCHEMES: readonly string[];
@@ -3,8 +3,12 @@ const n = `.base-input {
3
3
  border-radius: 4px;
4
4
  background-color: var(--guido-color-gray-0);
5
5
  align-items: center;
6
- height: 40px;
7
- max-height: 40px;
6
+ /* 40px is a floor, never a cap: \`.base-input\` is shared by every settings field,
7
+ including Stripo's own auto-height inputs (e.g. the link field) that expand on
8
+ focus. A fixed max-height clamped their inner box; keep 40px only as the floor. */
9
+ min-height: 40px;
10
+ height: auto;
11
+ max-height: none;
8
12
  box-sizing: content-box;
9
13
  outline: none;
10
14
  resize: vertical;
@@ -36,11 +40,6 @@ ue-contenteditable .base-input {
36
40
  line-height: 24px;
37
41
  }
38
42
 
39
- /* Image link input is auto-height; lift the fixed 40px cap so it can grow. */
40
- ue-contenteditable.link-autoheight-contenteditable .base-input {
41
- max-height: none;
42
- }
43
-
44
43
  ue-icon-component.icon-button.icon-clear-input {
45
44
  right: 2px;
46
45
  top: 2px;
@@ -75,65 +75,67 @@ const f = r("guido-config", {
75
75
  * Get the template ID
76
76
  */
77
77
  templateId: (i) => {
78
- var e, t;
79
- return ((t = (e = i.config) == null ? void 0 : e.identity) == null ? void 0 : t.templateId) ?? "";
78
+ var e, n;
79
+ return ((n = (e = i.config) == null ? void 0 : e.identity) == null ? void 0 : n.templateId) ?? "";
80
80
  },
81
81
  /**
82
82
  * Get the user ID
83
83
  */
84
84
  userId: (i) => {
85
- var e, t;
86
- return ((t = (e = i.config) == null ? void 0 : e.identity) == null ? void 0 : t.userId) ?? "";
85
+ var e, n;
86
+ return ((n = (e = i.config) == null ? void 0 : e.identity) == null ? void 0 : n.userId) ?? "";
87
87
  },
88
88
  /**
89
89
  * Get the variation ID
90
90
  */
91
91
  variationId: (i) => {
92
- var e, t;
93
- return ((t = (e = i.config) == null ? void 0 : e.identity) == null ? void 0 : t.variationId) ?? "";
92
+ var e, n;
93
+ return ((n = (e = i.config) == null ? void 0 : e.identity) == null ? void 0 : n.variationId) ?? "";
94
94
  },
95
95
  /**
96
96
  * Get the partner name
97
97
  */
98
98
  partnerName: (i) => {
99
- var e, t;
100
- return ((t = (e = i.config) == null ? void 0 : e.partner) == null ? void 0 : t.name) ?? "";
99
+ var e, n;
100
+ return ((n = (e = i.config) == null ? void 0 : e.partner) == null ? void 0 : n.name) ?? "";
101
101
  },
102
102
  /**
103
103
  * Get the product type
104
104
  */
105
105
  productType: (i) => {
106
- var e, t;
107
- return ((t = (e = i.config) == null ? void 0 : e.partner) == null ? void 0 : t.productType) ?? 60;
106
+ var e, n;
107
+ return ((n = (e = i.config) == null ? void 0 : e.partner) == null ? void 0 : n.productType) ?? 60;
108
108
  },
109
109
  /**
110
110
  * Get the message type
111
111
  */
112
112
  messageType: (i) => {
113
- var e, t;
114
- return ((t = (e = i.config) == null ? void 0 : e.partner) == null ? void 0 : t.messageType) ?? 1;
113
+ var e, n;
114
+ return ((n = (e = i.config) == null ? void 0 : e.partner) == null ? void 0 : n.messageType) ?? 1;
115
115
  },
116
116
  /**
117
117
  * Get the username
118
118
  */
119
119
  username: (i) => {
120
- var e, t;
121
- return ((t = (e = i.config) == null ? void 0 : e.partner) == null ? void 0 : t.username) ?? "Guido User";
120
+ var e, n;
121
+ return ((n = (e = i.config) == null ? void 0 : e.partner) == null ? void 0 : n.username) ?? "Guido User";
122
122
  },
123
123
  /**
124
124
  * Check if header should be shown
125
125
  */
126
126
  showHeader: (i) => {
127
- var e, t;
128
- return ((t = (e = i.config) == null ? void 0 : e.ui) == null ? void 0 : t.showHeader) ?? !0;
127
+ var e, n;
128
+ return ((n = (e = i.config) == null ? void 0 : e.ui) == null ? void 0 : n.showHeader) ?? !0;
129
129
  },
130
130
  /**
131
- * Check if a specific feature is enabled
131
+ * Check if a specific feature is enabled.
132
+ * Returns false before init (config null) so header controls don't
133
+ * flash on during loading, then disappear once config resolves.
132
134
  */
133
135
  // eslint-disable-next-line @stylistic/max-len
134
136
  isFeatureEnabled: (i) => (e) => {
135
- var t, n;
136
- return ((n = (t = i.config) == null ? void 0 : t.features) == null ? void 0 : n[e]) ?? !0;
137
+ var n, t;
138
+ return ((t = (n = i.config) == null ? void 0 : n.features) == null ? void 0 : t[e]) ?? !1;
137
139
  }
138
140
  },
139
141
  actions: {
@@ -1,30 +1,31 @@
1
- import { productPairs as q } from "../extensions/Blocks/Items/enums/productEnums.js";
2
- import { DefaultConfigValues as N } from "../extensions/Blocks/Items/enums/settingsEnums.js";
3
- function W(M) {
4
- const S = M.replaceAll("{%", "<!--{%").replaceAll("%}", "%}-->"), g = new DOMParser().parseFromString(S, "text/html"), m = q.PAIRS_FOR_EXTENSION;
1
+ import { productPairs as N } from "../extensions/Blocks/Items/enums/productEnums.js";
2
+ import { DefaultConfigValues as O } from "../extensions/Blocks/Items/enums/settingsEnums.js";
3
+ import { preserveTextStyles as C } from "./preserveTextStyles.js";
4
+ function V(L) {
5
+ const H = L.replaceAll("{%", "<!--{%").replaceAll("%}", "%}-->"), g = new DOMParser().parseFromString(H, "text/html"), m = N.PAIRS_FOR_EXTENSION;
5
6
  Object.entries(m).forEach(([r, f]) => {
6
7
  g.querySelectorAll(".ins-product-td").forEach((c) => {
7
- const A = c.getAttribute("data-number") || "1", C = c.getAttribute("data-type") || "CART_ITEMS";
8
- c.querySelectorAll(`[product-attr="${r}"]`).forEach((e) => {
8
+ const A = c.getAttribute("data-number") || "1", y = c.getAttribute("data-type") || "CART_ITEMS";
9
+ c.querySelectorAll(`[product-attr="${r}"]`).forEach((t) => {
9
10
  var F, I, w;
10
- const $ = e.getAttribute("data-type") || C, u = e.getAttribute("data-number") || A, d = f[$];
11
+ const T = t.getAttribute("data-type") || y, u = t.getAttribute("data-number") || A, d = f[T];
11
12
  if (d)
12
13
  switch (r) {
13
14
  case "imageSrc": {
14
- let t = null, i = null;
15
- if (e.tagName === "IMG" ? (t = e, i = t.closest("a")) : (t = e.querySelector("img"), i = e.querySelector("a") || e.closest("a")), !t)
15
+ let e = null, i = null;
16
+ if (t.tagName === "IMG" ? (e = t, i = e.closest("a")) : (e = t.querySelector("img"), i = t.querySelector("a") || t.closest("a")), !e)
16
17
  break;
17
18
  const a = d.DEFAULT, s = d.ATTR;
18
- if (a && t.src) {
19
- const o = t.src;
19
+ if (a && e.src) {
20
+ const o = e.src;
20
21
  a.some((h) => {
21
- const l = h.split("/").pop() || "", b = o.split("/").pop() || "";
22
- return o.includes(h) || o.includes(l) || b === l;
23
- }) && (t.src = `{{${s}_${u}}}`);
22
+ const l = h.split("/").pop() || "", $ = o.split("/").pop() || "";
23
+ return o.includes(h) || o.includes(l) || $ === l;
24
+ }) && (e.src = `{{${s}_${u}}}`);
24
25
  }
25
- const n = (I = (F = m.name) == null ? void 0 : F[$]) == null ? void 0 : I.ATTR;
26
- if (n && t.setAttribute("alt", `{{${n}_${u}}}`), i) {
27
- const o = (w = m.itemLink) == null ? void 0 : w[$];
26
+ const n = (I = (F = m.name) == null ? void 0 : F[T]) == null ? void 0 : I.ATTR;
27
+ if (n && e.setAttribute("alt", `{{${n}_${u}}}`), i) {
28
+ const o = (w = m.itemLink) == null ? void 0 : w[T];
28
29
  if (o) {
29
30
  const E = o.HREF, h = o.DEFAULT_HREF || "#!", l = i.href;
30
31
  (l === "#" || l === "" || l.endsWith("#!") || l.endsWith(h) || l === `${window.location.href}${h}` || !l || l === window.location.href) && (i.href = `{{${E}_${u}}}`);
@@ -33,9 +34,9 @@ function W(M) {
33
34
  break;
34
35
  }
35
36
  case "name": {
36
- const t = d, i = t.ATTR, a = t.DEFAULT_HREF || "#!", s = t.HREF;
37
- e.textContent && (e.textContent = `{{${i}_${u}}}`);
38
- const n = e.closest("a") || (e.tagName === "A" ? e : null);
37
+ const e = d, i = e.ATTR, a = e.DEFAULT_HREF || "#!", s = e.HREF;
38
+ t.textContent && (t.innerHTML = C(t, `{{${i}_${u}}}`));
39
+ const n = t.closest("a") || (t.tagName === "A" ? t : null);
39
40
  if (n && s) {
40
41
  const o = n.href, E = `${window.location.href}${a}`;
41
42
  (o === E || o.endsWith(a)) && (n.href = `{{${s}_${u}}}`);
@@ -44,23 +45,23 @@ function W(M) {
44
45
  }
45
46
  case "price":
46
47
  case "originalPrice": {
47
- const t = d, i = e.getAttribute("data-formated"), a = e.getAttribute("data-single_price"), s = i === "true", n = a === "true", o = e.getAttribute("data-curency") || "before";
48
+ const e = d, i = t.getAttribute("data-formated"), a = t.getAttribute("data-single_price"), s = i === "true", n = a === "true", o = t.getAttribute("data-curency") || "before";
48
49
  let E;
49
- n ? E = s ? t.SINGLE_PRICE_FORMATTED : t.SINGLE_PRICE : E = s ? t.PRICE_FORMATTED : t.PRICE;
50
- const h = t.CURRENCY;
50
+ n ? E = s ? e.SINGLE_PRICE_FORMATTED : e.SINGLE_PRICE : E = s ? e.PRICE_FORMATTED : e.PRICE;
51
+ const h = e.CURRENCY;
51
52
  let l = `{{${E}_${u}}}`;
52
- const b = (e.getAttribute("data-currency_symbol") || "").trim(), x = b !== "" && b !== N.productPriceCurrencySymbolControlValue;
53
- let T = "";
54
- x ? T = b : h && (T = `{{${h}_${u}}}`), T && (l = o === "after" ? `${l} ${T}` : `${T} ${l}`), e.textContent = l;
53
+ const $ = (t.getAttribute("data-currency_symbol") || "").trim(), q = $ !== "" && $ !== O.productPriceCurrencySymbolControlValue;
54
+ let b = "";
55
+ q ? b = $ : h && (b = `{{${h}_${u}}}`), b && (l = o === "after" ? `${l} ${b}` : `${b} ${l}`), t.innerHTML = C(t, l);
55
56
  break;
56
57
  }
57
58
  case "quantity": {
58
- const t = d, i = t.ATTR, a = t.DEFAULT;
59
- e.textContent && e.textContent.trim() === a && (e.textContent = `{{${i}_${u}}}`);
59
+ const e = d, i = e.ATTR, a = e.DEFAULT;
60
+ t.textContent && t.textContent.trim() === a && (t.innerHTML = C(t, `{{${i}_${u}}}`));
60
61
  break;
61
62
  }
62
63
  case "button": {
63
- const t = d, i = t.HREF, a = t.DEFAULT_HREF || "#!", s = e.tagName === "A" ? e : e.querySelector("a");
64
+ const e = d, i = e.HREF, a = e.DEFAULT_HREF || "#!", s = t.tagName === "A" ? t : t.querySelector("a");
64
65
  if (s) {
65
66
  const n = s.href || "", o = `${window.location.href}${a}`;
66
67
  (n === "" || n === "#" || n === o || n.endsWith(a) || n.endsWith("#!") || n === window.location.href) && (s.href = `{{${i}_${u}}}`);
@@ -68,7 +69,7 @@ function W(M) {
68
69
  break;
69
70
  }
70
71
  case "itemLink": {
71
- const t = d, i = t.HREF, a = t.DEFAULT_HREF || "#!", s = e;
72
+ const e = d, i = e.HREF, a = e.DEFAULT_HREF || "#!", s = t;
72
73
  if (s.href) {
73
74
  const n = s.href, o = `${window.location.href}${a}`;
74
75
  (n === o || n.endsWith(a)) && (s.href = `{{${i}_${u}}}`);
@@ -77,8 +78,8 @@ function W(M) {
77
78
  }
78
79
  default: {
79
80
  if ("ATTR" in d) {
80
- const t = d.ATTR;
81
- e.textContent && (e.textContent = `{{${t}_${u}}}`);
81
+ const e = d.ATTR;
82
+ t.textContent && (t.innerHTML = C(t, `{{${e}_${u}}}`));
82
83
  }
83
84
  break;
84
85
  }
@@ -86,11 +87,11 @@ function W(M) {
86
87
  });
87
88
  });
88
89
  });
89
- const H = S.match(/<!DOCTYPE[^>]*>/i), P = H ? `${H[0]}
90
- ` : "", D = g.querySelectorAll(".ins-product-td"), k = [];
90
+ const k = H.match(/<!DOCTYPE[^>]*>/i), P = k ? `${k[0]}
91
+ ` : "", D = g.querySelectorAll(".ins-product-td"), M = [];
91
92
  D.forEach((r) => {
92
93
  const f = r.getAttribute("data-type") || "CART_ITEMS", p = r.getAttribute("data-number") || "1", c = r.getAttribute("data-nodup"), A = r.outerHTML;
93
- k.push({
94
+ M.push({
94
95
  element: r,
95
96
  outerHtml: A,
96
97
  type: f,
@@ -99,7 +100,7 @@ function W(M) {
99
100
  });
100
101
  });
101
102
  let _ = P + g.documentElement.outerHTML;
102
- k.reverse().forEach(({ outerHtml: r, type: f, number: p }) => {
103
+ M.reverse().forEach(({ outerHtml: r, type: f, number: p }) => {
103
104
  let c = "";
104
105
  switch (f) {
105
106
  case "CART_ITEMS":
@@ -113,21 +114,21 @@ function W(M) {
113
114
  break;
114
115
  }
115
116
  if (c) {
116
- const C = parseInt(p) - 1, $ = `${`{% if ${c} > ${C} %}`}${r}{% endif %}`;
117
- _ = _.replace(r, $);
117
+ const y = parseInt(p) - 1, T = `${`{% if ${c} > ${y} %}`}${r}{% endif %}`;
118
+ _ = _.replace(r, T);
118
119
  }
119
120
  });
120
- const L = g.querySelectorAll('[product-attr="originalPrice"][data-type="CART_ITEMS"]'), y = [];
121
- return L.forEach((r) => {
121
+ const x = g.querySelectorAll('[product-attr="originalPrice"][data-type="CART_ITEMS"]'), R = [];
122
+ return x.forEach((r) => {
122
123
  const f = r.getAttribute("data-number"), p = r.getAttribute("data-type");
123
124
  if (!f || p !== "CART_ITEMS")
124
125
  return;
125
126
  const c = r.closest(".product-original-price-class");
126
127
  if (c) {
127
128
  const A = c.outerHTML;
128
- y.some((R) => R.tdOuterHtml === A) || y.push({ tdOuterHtml: A, number: f });
129
+ R.some((S) => S.tdOuterHtml === A) || R.push({ tdOuterHtml: A, number: f });
129
130
  }
130
- }), y.reverse().forEach(({ tdOuterHtml: r, number: f }) => {
131
+ }), R.reverse().forEach(({ tdOuterHtml: r, number: f }) => {
131
132
  const p = `{% if ins_apr_price_${f} != ins_apr_originalprice_${f} %}`;
132
133
  if (!_.includes(p) && !r.includes("{% if")) {
133
134
  const A = `${p}${r}{% endif %}`;
@@ -136,5 +137,5 @@ function W(M) {
136
137
  }), _.replaceAll("<!--{%", "{%").replaceAll("%}-->", "%}").replaceAll("&lt;!--{%", "{%").replaceAll("%}--&gt;", "%}");
137
138
  }
138
139
  export {
139
- W as pairProductVariables
140
+ V as pairProductVariables
140
141
  };
@@ -1,4 +1,4 @@
1
- import { escapeHtml as g } from "../../../../utils/htmlEscape.js";
1
+ import { escapeHtml as g } from "./htmlEscape.js";
2
2
  function u(n) {
3
3
  return "getInnerHTML" in n && typeof n.getInnerHTML == "function" ? n.getInnerHTML().trim() : "innerHTML" in n ? n.innerHTML : "";
4
4
  }
@@ -0,0 +1,4 @@
1
+ const t = ["http:", "https:", "mailto:"];
2
+ export {
3
+ t as BASE_SAFE_URL_SCHEMES
4
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@useinsider/guido",
3
- "version": "3.12.0",
3
+ "version": "3.13.0-beta.ef18f66",
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",
@@ -44,7 +44,7 @@
44
44
  "license": "ISC",
45
45
  "dependencies": {
46
46
  "@stripoinc/ui-editor-extensions": "3.8.0",
47
- "@useinsider/design-system-vue": "1.3.0",
47
+ "@useinsider/design-system-vue": "2.0.0",
48
48
  "@vueuse/core": "11.3.0",
49
49
  "lodash-es": "4.17.21",
50
50
  "pinia": "2.3.1",