@useinsider/guido 3.12.0 → 3.13.0
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 +16 -1
- package/dist/@types/config/schemas.js +27 -25
- package/dist/components/Guido.vue.js +1 -1
- package/dist/components/Guido.vue2.js +110 -101
- package/dist/components/organisms/email-preview/desktop-preview/DesktopPreview.vue.js +1 -1
- package/dist/components/organisms/email-preview/desktop-preview/DesktopPreview.vue2.js +8 -8
- package/dist/components/organisms/email-preview/mobile-preview/ContentView.vue.js +5 -5
- package/dist/components/organisms/email-preview/mobile-preview/ContentView.vue2.js +10 -10
- package/dist/composables/useAllowlist.js +50 -0
- package/dist/composables/usePreviewInteractionGuard.js +36 -11
- package/dist/composables/useRecommendationPreview.js +61 -60
- package/dist/composables/useSave.js +42 -23
- package/dist/composables/useStripo.js +72 -69
- package/dist/composables/useUserRole.js +12 -0
- package/dist/enums/roles.js +4 -0
- package/dist/extensions/Blocks/Recommendation/constants/controlIds.js +1 -1
- package/dist/extensions/Blocks/Recommendation/controls/blockBackground/index.js +10 -0
- package/dist/extensions/Blocks/Recommendation/controls/omnibusDiscount/textAfter.js +12 -12
- package/dist/extensions/Blocks/Recommendation/controls/omnibusDiscount/textBefore.js +12 -12
- package/dist/extensions/Blocks/Recommendation/controls/omnibusPrice/textAfter.js +12 -12
- package/dist/extensions/Blocks/Recommendation/controls/omnibusPrice/textBefore.js +12 -12
- package/dist/extensions/Blocks/Recommendation/extension.js +23 -21
- package/dist/extensions/Blocks/Recommendation/settingsPanel.js +41 -40
- package/dist/extensions/Blocks/Recommendation/utils/captureStyleTemplates.js +7 -7
- package/dist/extensions/Blocks/Unsubscribe/utils/constants.js +3 -2
- package/dist/extensions/Blocks/controlFactories.js +125 -75
- package/dist/guido.css +1 -1
- package/dist/services/allowlistApi.js +15 -0
- package/dist/services/stripoApi.js +18 -18
- package/dist/src/@types/config/schemas.d.ts +10 -0
- package/dist/src/components/Guido.vue.d.ts +18 -2
- package/dist/src/composables/useAllowlist.d.ts +6 -0
- package/dist/src/composables/useConfig.d.ts +2 -0
- package/dist/src/composables/usePreviewInteractionGuard.d.ts +1 -1
- package/dist/src/composables/useStripo.d.ts +3 -2
- package/dist/src/composables/useUserRole.d.ts +3 -0
- package/dist/src/enums/roles.d.ts +9 -0
- package/dist/src/extensions/Blocks/Recommendation/constants/controlIds.d.ts +1 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/blockBackground/index.d.ts +14 -0
- package/dist/src/extensions/Blocks/Recommendation/controls/index.d.ts +1 -0
- package/dist/src/extensions/Blocks/Unsubscribe/utils/constants.d.ts +1 -0
- package/dist/src/extensions/Blocks/controlFactories.d.ts +36 -0
- package/dist/src/services/allowlistApi.d.ts +4 -0
- package/dist/src/stores/config.d.ts +21 -1
- package/dist/src/utils/urlSchemes.d.ts +6 -0
- package/dist/static/styles/components/base-input.css.js +6 -7
- package/dist/stores/config.js +21 -19
- package/dist/utils/pairProductVariables.js +44 -43
- package/dist/{extensions/Blocks/Recommendation/utils → utils}/preserveTextStyles.js +1 -1
- package/dist/utils/urlSchemes.js +4 -0
- package/package.json +1 -1
- /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
|
|
@@ -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
|
-
|
|
7
|
-
|
|
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;
|
package/dist/stores/config.js
CHANGED
|
@@ -75,65 +75,67 @@ const f = r("guido-config", {
|
|
|
75
75
|
* Get the template ID
|
|
76
76
|
*/
|
|
77
77
|
templateId: (i) => {
|
|
78
|
-
var e,
|
|
79
|
-
return ((
|
|
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,
|
|
86
|
-
return ((
|
|
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,
|
|
93
|
-
return ((
|
|
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,
|
|
100
|
-
return ((
|
|
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,
|
|
107
|
-
return ((
|
|
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,
|
|
114
|
-
return ((
|
|
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,
|
|
121
|
-
return ((
|
|
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,
|
|
128
|
-
return ((
|
|
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
|
|
136
|
-
return ((
|
|
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
|
|
2
|
-
import { DefaultConfigValues as
|
|
3
|
-
|
|
4
|
-
|
|
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",
|
|
8
|
-
c.querySelectorAll(`[product-attr="${r}"]`).forEach((
|
|
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
|
|
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
|
|
15
|
-
if (
|
|
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 &&
|
|
19
|
-
const o =
|
|
19
|
+
if (a && e.src) {
|
|
20
|
+
const o = e.src;
|
|
20
21
|
a.some((h) => {
|
|
21
|
-
const l = h.split("/").pop() || "",
|
|
22
|
-
return o.includes(h) || o.includes(l) ||
|
|
23
|
-
}) && (
|
|
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[
|
|
26
|
-
if (n &&
|
|
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
|
|
37
|
-
|
|
38
|
-
const n =
|
|
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
|
|
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 ?
|
|
50
|
-
const h =
|
|
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
|
|
53
|
-
let
|
|
54
|
-
|
|
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
|
|
59
|
-
|
|
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
|
|
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
|
|
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
|
|
81
|
-
|
|
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
|
|
90
|
-
` : "", D = g.querySelectorAll(".ins-product-td"),
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
121
|
-
return
|
|
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
|
-
|
|
129
|
+
R.some((S) => S.tdOuterHtml === A) || R.push({ tdOuterHtml: A, number: f });
|
|
129
130
|
}
|
|
130
|
-
}),
|
|
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("<!--{%", "{%").replaceAll("%}-->", "%}");
|
|
137
138
|
}
|
|
138
139
|
export {
|
|
139
|
-
|
|
140
|
+
V as pairProductVariables
|
|
140
141
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { escapeHtml as g } from "
|
|
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
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@useinsider/guido",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.13.0",
|
|
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",
|
|
File without changes
|