@useinsider/guido 3.14.0 → 3.15.0-beta.244c73c
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/composables/useEmailTemplateApplier.js +46 -32
- package/dist/composables/useHtmlValidator.js +111 -106
- package/dist/composables/useRecommendation.js +20 -19
- package/dist/config/compiler/itemsCompilerRules.js +25 -4
- package/dist/config/compiler/utils/itemsCompilerUtils.js +28 -0
- package/dist/config/migrator/index.js +9 -8
- package/dist/config/migrator/itemsBlockMigrator.js +47 -45
- package/dist/config/migrator/productNameLinkMigrator.js +27 -0
- package/dist/extensions/Blocks/Items/block.js +30 -30
- package/dist/extensions/Blocks/Items/controls/name/trimming.js +16 -16
- package/dist/extensions/Blocks/Items/controls/price/hideDiscount.js +26 -22
- package/dist/extensions/Blocks/Items/controls/settingsControl.js +36 -35
- package/dist/extensions/Blocks/Items/template.js +228 -263
- package/dist/extensions/Blocks/Items/utils/nameNode.js +4 -0
- package/dist/extensions/Blocks/Recommendation/controls/main/algorithm.js +33 -34
- package/dist/extensions/Blocks/Recommendation/store/recommendation.js +13 -12
- package/dist/extensions/Blocks/Recommendation/utils/productIds.js +6 -0
- package/dist/src/config/compiler/utils/itemsCompilerUtils.d.ts +12 -0
- package/dist/src/config/migrator/productNameLinkMigrator.d.ts +1 -0
- package/dist/src/extensions/Blocks/Items/block.d.ts +1 -1
- package/dist/src/extensions/Blocks/Items/utils/nameNode.d.ts +9 -0
- package/dist/src/extensions/Blocks/Recommendation/utils/productIds.d.ts +6 -0
- package/dist/src/stores/dynamic-content.d.ts +8 -0
- package/dist/src/utils/registerUsedDynamicContent.d.ts +8 -0
- package/dist/src/utils/unwrapProductNameLink.d.ts +15 -0
- package/dist/stores/dynamic-content.js +12 -2
- package/dist/utils/pairProductVariables.js +75 -72
- package/dist/utils/registerUsedDynamicContent.js +23 -0
- package/dist/utils/unwrapProductNameLink.js +37 -0
- package/package.json +1 -1
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
import { UEAttr as
|
|
5
|
-
import { CommonControl as
|
|
1
|
+
var d = Object.defineProperty;
|
|
2
|
+
var h = (r, o, t) => o in r ? d(r, o, { enumerable: !0, configurable: !0, writable: !0, value: t }) : r[o] = t;
|
|
3
|
+
var c = (r, o, t) => h(r, typeof o != "symbol" ? o + "" : o, t);
|
|
4
|
+
import { UEAttr as l } from "../../../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
|
|
5
|
+
import { CommonControl as g } from "../../../common-control.js";
|
|
6
6
|
import { RecommendationConfigService as n } from "../../services/configService.js";
|
|
7
7
|
import { useRecommendationExtensionStore as m } from "../../store/recommendation.js";
|
|
8
|
-
import { mapLegacyStrategy as
|
|
9
|
-
const
|
|
8
|
+
import { mapLegacyStrategy as u } from "../../utils/legacyStrategyMap.js";
|
|
9
|
+
const p = "recommendation-algorithm-control", e = {
|
|
10
10
|
ALGORITHM: "strategy",
|
|
11
11
|
PRODUCT_IDS: "productIds"
|
|
12
12
|
};
|
|
13
|
-
class
|
|
13
|
+
class S extends g {
|
|
14
14
|
constructor() {
|
|
15
15
|
super(...arguments);
|
|
16
16
|
// Store is used ONLY for API-fetched data (algorithms list), not for config
|
|
17
|
-
|
|
17
|
+
c(this, "store", m());
|
|
18
18
|
}
|
|
19
19
|
getId() {
|
|
20
|
-
return
|
|
20
|
+
return p;
|
|
21
21
|
}
|
|
22
22
|
getTemplate() {
|
|
23
23
|
return `
|
|
@@ -25,13 +25,13 @@ class R extends d {
|
|
|
25
25
|
${this._GuTwoColumns([
|
|
26
26
|
this._GuLabel({ text: this.api.translate("Recommendation Algorithm") }),
|
|
27
27
|
this._GuSelect({
|
|
28
|
-
name:
|
|
28
|
+
name: e.ALGORITHM,
|
|
29
29
|
placeholder: this.api.translate("Select Recommendation Algorithm"),
|
|
30
30
|
options: this.store.getActivePredictiveAlgorithms
|
|
31
31
|
}),
|
|
32
|
-
this._GuLabel({ text: this.api.translate("Product Ids"), name: `${
|
|
32
|
+
this._GuLabel({ text: this.api.translate("Product Ids"), name: `${e.PRODUCT_IDS}_label` }),
|
|
33
33
|
this._GuTextInput({
|
|
34
|
-
name:
|
|
34
|
+
name: e.PRODUCT_IDS,
|
|
35
35
|
placeholder: this.api.translate("Enter Product Ids"),
|
|
36
36
|
className: "es-180w"
|
|
37
37
|
})
|
|
@@ -46,29 +46,28 @@ class R extends d {
|
|
|
46
46
|
super.onTemplateNodeUpdated(t), this._initializeSelectItems(), this._setFormValues();
|
|
47
47
|
}
|
|
48
48
|
_setFormValues() {
|
|
49
|
-
const t = n.getConfig(this.currentNode),
|
|
50
|
-
this._setProductIdsVisibility(
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
});
|
|
49
|
+
const t = n.getConfig(this.currentNode), s = u(t.strategy) ?? t.strategy;
|
|
50
|
+
this._setProductIdsVisibility(s);
|
|
51
|
+
const i = { [e.ALGORITHM]: s }, a = t.productIds.join(",");
|
|
52
|
+
this.api.getValues()[e.PRODUCT_IDS] !== a && (i[e.PRODUCT_IDS] = a), this.api.updateValues(i);
|
|
54
53
|
}
|
|
55
54
|
_initializeSelectItems() {
|
|
56
|
-
var
|
|
57
|
-
const t = (
|
|
55
|
+
var s;
|
|
56
|
+
const t = (s = this.store) == null ? void 0 : s.getActivePredictiveAlgorithms;
|
|
58
57
|
if (t != null && t.length)
|
|
59
58
|
try {
|
|
60
59
|
this.api.setUIEAttribute(
|
|
61
|
-
|
|
62
|
-
|
|
60
|
+
e.ALGORITHM,
|
|
61
|
+
l.SELECTPICKER.items,
|
|
63
62
|
t
|
|
64
63
|
);
|
|
65
|
-
} catch (
|
|
66
|
-
console.warn("[AlgorithmControl] Failed to set algorithm options:",
|
|
64
|
+
} catch (i) {
|
|
65
|
+
console.warn("[AlgorithmControl] Failed to set algorithm options:", i);
|
|
67
66
|
}
|
|
68
67
|
}
|
|
69
68
|
_setProductIdsVisibility(t) {
|
|
70
|
-
const
|
|
71
|
-
this.api.setVisibility(
|
|
69
|
+
const i = (t ?? n.getConfig(this.currentNode).strategy) === "manualMerchandising";
|
|
70
|
+
this.api.setVisibility(e.PRODUCT_IDS, i), this.api.setVisibility(`${e.PRODUCT_IDS}_label`, i);
|
|
72
71
|
}
|
|
73
72
|
_onAlgorithmChange(t) {
|
|
74
73
|
!this.currentNode || n.getConfig(this.currentNode).strategy === t || (n.updateConfig(
|
|
@@ -79,25 +78,25 @@ class R extends d {
|
|
|
79
78
|
), this.store.patchCurrentBlockConfig({ strategy: t }), this._setProductIdsVisibility(t));
|
|
80
79
|
}
|
|
81
80
|
_onProductIdsChange(t) {
|
|
82
|
-
if (!this.currentNode)
|
|
81
|
+
if (!this.currentNode || n.getConfig(this.currentNode).productIds.join(",") === t)
|
|
83
82
|
return;
|
|
84
|
-
const
|
|
83
|
+
const i = t.split(",");
|
|
85
84
|
n.updateConfig(
|
|
86
85
|
this.api,
|
|
87
86
|
this.currentNode,
|
|
88
|
-
{ productIds:
|
|
87
|
+
{ productIds: i },
|
|
89
88
|
"Updated product IDs"
|
|
90
|
-
), this.store.patchCurrentBlockConfig({ productIds:
|
|
89
|
+
), this.store.patchCurrentBlockConfig({ productIds: i });
|
|
91
90
|
}
|
|
92
91
|
_listenToFormUpdates() {
|
|
93
|
-
this.api.onValueChanged(
|
|
92
|
+
this.api.onValueChanged(e.ALGORITHM, (t) => {
|
|
94
93
|
this._onAlgorithmChange(t);
|
|
95
|
-
}), this.api.onValueChanged(
|
|
94
|
+
}), this.api.onValueChanged(e.PRODUCT_IDS, (t) => {
|
|
96
95
|
this._onProductIdsChange(t);
|
|
97
96
|
});
|
|
98
97
|
}
|
|
99
98
|
}
|
|
100
99
|
export {
|
|
101
|
-
|
|
102
|
-
|
|
100
|
+
p as ALGORITHM_CONTROL_ID,
|
|
101
|
+
S as AlgorithmControl
|
|
103
102
|
};
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import { getRecommendationFeedSourceMaps as g, getOperatorOptions as R, PriceAttributes as C } from "../../../../enums/extensions/recommendationBlock.js";
|
|
2
2
|
import { useRecommendationApi as y } from "../../../../services/recommendationApi.js";
|
|
3
3
|
import { useConfigStore as G } from "../../../../stores/config.js";
|
|
4
|
-
import { defineStore as
|
|
4
|
+
import { defineStore as P } from "pinia";
|
|
5
5
|
import "../constants/selectors.js";
|
|
6
|
-
import { DEFAULT_MOBILE_CARDS_IN_ROW as
|
|
6
|
+
import { DEFAULT_MOBILE_CARDS_IN_ROW as F, DEFAULT_CARDS_IN_ROW as D } from "../constants/layout.js";
|
|
7
7
|
import { EXCLUDED_ALGORITHM_IDS as w } from "../constants/defaultConfig.js";
|
|
8
8
|
import { getDefaultProducts as S } from "../templates/utils.js";
|
|
9
9
|
import { generateCompleteFilterQuery as b } from "../utils/filterUtil.js";
|
|
10
10
|
import { getPartnerRecommendationParams as v } from "../utils/partnerCustomizations.js";
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
11
|
+
import { sanitizeProductIds as N } from "../utils/productIds.js";
|
|
12
|
+
import { isFilterValid as x } from "../validation/filterSchema.js";
|
|
13
|
+
import { isConfigValid as L } from "../validation/requiredFields.js";
|
|
13
14
|
const h = y();
|
|
14
15
|
let m = null, u = null, d = null;
|
|
15
16
|
function k() {
|
|
@@ -28,7 +29,7 @@ function k() {
|
|
|
28
29
|
productIds: [],
|
|
29
30
|
id: 1,
|
|
30
31
|
language: "en_US",
|
|
31
|
-
mobileCardsInRow:
|
|
32
|
+
mobileCardsInRow: F,
|
|
32
33
|
mobileLayoutEnabled: !1,
|
|
33
34
|
orientation: "grid",
|
|
34
35
|
recommendedProducts: [],
|
|
@@ -54,7 +55,7 @@ function I() {
|
|
|
54
55
|
filterSnapshot: null
|
|
55
56
|
};
|
|
56
57
|
}
|
|
57
|
-
const
|
|
58
|
+
const U = () => ({
|
|
58
59
|
recommendationCampaignUrls: {},
|
|
59
60
|
activePredictiveAlgorithms: [],
|
|
60
61
|
languages: {},
|
|
@@ -63,8 +64,8 @@ const L = () => ({
|
|
|
63
64
|
blockStates: {},
|
|
64
65
|
currentRecommendationId: null,
|
|
65
66
|
configVersion: 0
|
|
66
|
-
}),
|
|
67
|
-
state: () =>
|
|
67
|
+
}), H = P("guidoRecommendationExtension", {
|
|
68
|
+
state: () => U(),
|
|
68
69
|
getters: {
|
|
69
70
|
// ====================================================================
|
|
70
71
|
// Proxy Getters — Backward Compatible Access to Current Block State
|
|
@@ -383,7 +384,7 @@ const L = () => ({
|
|
|
383
384
|
const n = [...e.recommendationConfigs.filters];
|
|
384
385
|
n[r] = {
|
|
385
386
|
...t,
|
|
386
|
-
isValid:
|
|
387
|
+
isValid: x(t)
|
|
387
388
|
}, e.recommendationConfigs.filters = n;
|
|
388
389
|
}
|
|
389
390
|
},
|
|
@@ -429,7 +430,7 @@ const L = () => ({
|
|
|
429
430
|
* every block's recommendationConfigs across user edits.
|
|
430
431
|
*/
|
|
431
432
|
hasInvalidBlock() {
|
|
432
|
-
return Object.values(this.blockStates).some((t) => !
|
|
433
|
+
return Object.values(this.blockStates).some((t) => !L(t.recommendationConfigs, this));
|
|
433
434
|
},
|
|
434
435
|
// ====================================================================
|
|
435
436
|
// Per-Block Product Fetching
|
|
@@ -458,7 +459,7 @@ const L = () => ({
|
|
|
458
459
|
details: !0,
|
|
459
460
|
campaignId: o.variationId
|
|
460
461
|
};
|
|
461
|
-
r.strategy === "manualMerchandising" ? a.productId = r.productIds
|
|
462
|
+
r.strategy === "manualMerchandising" ? a.productId = N(r.productIds) : r.strategy === "similarViewed" && (a.productId = "{itemId}"), r.strategy === "userBased" && (a.userId = "{user_id}"), c && (a.filter = c), r.shuffleProducts && (a.shuffle = !0), Object.assign(
|
|
462
463
|
a,
|
|
463
464
|
v(o.partnerName, r.strategy)
|
|
464
465
|
);
|
|
@@ -479,5 +480,5 @@ const L = () => ({
|
|
|
479
480
|
}
|
|
480
481
|
});
|
|
481
482
|
export {
|
|
482
|
-
|
|
483
|
+
H as useRecommendationExtensionStore
|
|
483
484
|
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare const MSO_ITEMS_HIDE_START = "MSO_ITEMS_HIDE_START";
|
|
2
|
+
export declare const MSO_ITEMS_HIDE_END = "MSO_ITEMS_HIDE_END";
|
|
3
|
+
/**
|
|
4
|
+
* SD-147597: the horizontal Items layout ships a second copy of price +
|
|
5
|
+
* original price in a `td.vertical-price` fallback hidden only by inline
|
|
6
|
+
* `display:none` (and vice versa for the vertical price orientation). Outlook's
|
|
7
|
+
* Word engine ignores `display:none` on `<td>`, so it paints BOTH copies —
|
|
8
|
+
* duplicate price. Wrap whichever price td(s) are hidden at export time in safe
|
|
9
|
+
* placeholder comments (swapped into `<!--[if !mso]>` by the priority-101 rule)
|
|
10
|
+
* and collapse them inline for web-engine Outlook.
|
|
11
|
+
*/
|
|
12
|
+
export declare function wrapHiddenPriceTdsForOutlook(html: string): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function migrateProductNameLink(html: string): string;
|
|
@@ -34,7 +34,7 @@ export declare class ItemsBlock extends Block {
|
|
|
34
34
|
*/
|
|
35
35
|
onDocumentChanged(node: ImmutableHtmlNode): void;
|
|
36
36
|
/**
|
|
37
|
-
* Bakes the compiler-read DOM attributes (`data-type`, `data-number`) onto the
|
|
37
|
+
* Bakes the compiler-read DOM attributes (`data-type`, `data-number`, `data-nodup`) onto the
|
|
38
38
|
* `.ins-product-td` container from the recovered config. Required for saved modules:
|
|
39
39
|
* `migrate()` (which backfills these) only runs at template load — never when a module
|
|
40
40
|
* is dropped into a live editor — so this is the one place the namespace + index get
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ImmutableHtmlElementNode, ImmutableHtmlNode } from '@stripoinc/ui-editor-extensions';
|
|
2
|
+
/**
|
|
3
|
+
* Resolves the element carrying the product name text.
|
|
4
|
+
*
|
|
5
|
+
* New blocks put `product-attr="name"` on the `<p>`; blocks saved before SD-147616 still
|
|
6
|
+
* carry it on the inner `<a>`, and the oldest ones have no attribute at all — hence the
|
|
7
|
+
* `p > a` fallback. Without it, trimming silently no-ops on legacy blocks.
|
|
8
|
+
*/
|
|
9
|
+
export declare const findNameTextNode: (container?: ImmutableHtmlNode) => ImmutableHtmlElementNode | undefined;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Builds the request/URL `productId` value from raw product ID segments.
|
|
3
|
+
* Trimming happens here — NOT on input change — so the user's in-progress
|
|
4
|
+
* text (trailing commas, spaces) is never rewritten under the caret (SD-147111).
|
|
5
|
+
*/
|
|
6
|
+
export declare function sanitizeProductIds(ids: string[]): string;
|
|
@@ -36,4 +36,12 @@ export declare const useDynamicContentStore: import("pinia").StoreDefinition<"gu
|
|
|
36
36
|
}[];
|
|
37
37
|
}, {
|
|
38
38
|
setSelectedDynamicContent(dynamicContent: DynamicContent): void;
|
|
39
|
+
/**
|
|
40
|
+
* Append-only bulk registration for dynamic content used by an
|
|
41
|
+
* AI-applied template. Unlike `setSelectedDynamicContent` it doesn't
|
|
42
|
+
* touch `selectedDynamicContent`; the getter removes duplicates, so
|
|
43
|
+
* re-registering the same entries is harmless. Items are shallow-copied so Pinia
|
|
44
|
+
* reactivity can't write a later mutation back into the host's catalog.
|
|
45
|
+
*/
|
|
46
|
+
registerDynamicContent(items: DynamicContent[]): void;
|
|
39
47
|
}>;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { DynamicContent } from '@@/Types/generic';
|
|
2
|
+
export declare const extractUsedDynamicContent: (html: string, flattenedCatalog: DynamicContent[] | undefined | null) => DynamicContent[];
|
|
3
|
+
/**
|
|
4
|
+
* Dev-diagnostic sibling of `extractUsedDynamicContent`: the used token names
|
|
5
|
+
* with NO catalog match (so intentionally not registered). Surfaced via a
|
|
6
|
+
* dev-gated `console.debug` to spot a neo↔guido vocabulary mismatch. Never throws.
|
|
7
|
+
*/
|
|
8
|
+
export declare const getUnmatchedDynamicContentTokens: (html: string, flattenedCatalog: DynamicContent[] | undefined | null) => string[];
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unwraps the `<a>` around an Items-block product name so the name compiles as plain text.
|
|
3
|
+
*
|
|
4
|
+
* Outlook's Word engine ignores `color: inherit` on an `<a>` and paints its own blue link
|
|
5
|
+
* color (SD-147616). New blocks no longer emit the anchor, but templates saved before the
|
|
6
|
+
* fix still carry it in their stored HTML — this heals them at compile time.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Removes the product-name link from every `.ins-product-td` in the document, in place.
|
|
10
|
+
*
|
|
11
|
+
* Scoped like `pairProductVariables` so partner or legacy recommendation markup outside a
|
|
12
|
+
* product cell is never touched. Idempotent.
|
|
13
|
+
* @param doc - Parsed template document, mutated in place
|
|
14
|
+
*/
|
|
15
|
+
export declare function unwrapProductNameLinks(doc: Document): void;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { removeDuplicatesFromArray as n } from "../utils/arrayUtil.js";
|
|
2
2
|
import { defineStore as a } from "pinia";
|
|
3
|
-
const
|
|
3
|
+
const c = a("guidoDynamicContent", {
|
|
4
4
|
state: () => ({
|
|
5
5
|
selectedDynamicContent: { text: "", value: "" },
|
|
6
6
|
selectedDynamicContentList: []
|
|
@@ -8,6 +8,16 @@ const s = a("guidoDynamicContent", {
|
|
|
8
8
|
actions: {
|
|
9
9
|
setSelectedDynamicContent(t) {
|
|
10
10
|
this.selectedDynamicContent = t, this.selectedDynamicContentList.push(t);
|
|
11
|
+
},
|
|
12
|
+
/**
|
|
13
|
+
* Append-only bulk registration for dynamic content used by an
|
|
14
|
+
* AI-applied template. Unlike `setSelectedDynamicContent` it doesn't
|
|
15
|
+
* touch `selectedDynamicContent`; the getter removes duplicates, so
|
|
16
|
+
* re-registering the same entries is harmless. Items are shallow-copied so Pinia
|
|
17
|
+
* reactivity can't write a later mutation back into the host's catalog.
|
|
18
|
+
*/
|
|
19
|
+
registerDynamicContent(t) {
|
|
20
|
+
this.selectedDynamicContentList.push(...t.map((e) => ({ ...e })));
|
|
11
21
|
}
|
|
12
22
|
},
|
|
13
23
|
getters: {
|
|
@@ -20,5 +30,5 @@ const s = a("guidoDynamicContent", {
|
|
|
20
30
|
}
|
|
21
31
|
});
|
|
22
32
|
export {
|
|
23
|
-
|
|
33
|
+
c as useDynamicContentStore
|
|
24
34
|
};
|
|
@@ -1,85 +1,88 @@
|
|
|
1
|
-
import { productPairs as
|
|
1
|
+
import { productPairs as q } from "../extensions/Blocks/Items/enums/productEnums.js";
|
|
2
2
|
import { DefaultConfigValues as O } from "../extensions/Blocks/Items/enums/settingsEnums.js";
|
|
3
3
|
import { preserveTextStyles as C } from "./preserveTextStyles.js";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
4
|
+
import { unwrapProductNameLinks as U } from "./unwrapProductNameLink.js";
|
|
5
|
+
function Y(L) {
|
|
6
|
+
const H = L.replaceAll("{%", "<!--{%").replaceAll("%}", "%}-->"), b = new DOMParser().parseFromString(H, "text/html");
|
|
7
|
+
U(b);
|
|
8
|
+
const R = q.PAIRS_FOR_EXTENSION;
|
|
9
|
+
Object.entries(R).forEach(([r, u]) => {
|
|
10
|
+
b.querySelectorAll(".ins-product-td").forEach((l) => {
|
|
11
|
+
const h = l.getAttribute("data-number") || "1", $ = l.getAttribute("data-type") || "CART_ITEMS";
|
|
12
|
+
l.querySelectorAll(`[product-attr="${r}"]`).forEach((t) => {
|
|
10
13
|
var F, I, w;
|
|
11
|
-
const T = t.getAttribute("data-type") ||
|
|
14
|
+
const T = t.getAttribute("data-type") || $, f = t.getAttribute("data-number") || h, d = u[T];
|
|
12
15
|
if (d)
|
|
13
16
|
switch (r) {
|
|
14
17
|
case "imageSrc": {
|
|
15
|
-
let e = null,
|
|
16
|
-
if (t.tagName === "IMG" ? (e = t,
|
|
18
|
+
let e = null, c = null;
|
|
19
|
+
if (t.tagName === "IMG" ? (e = t, c = e.closest("a")) : (e = t.querySelector("img"), c = t.querySelector("a") || t.closest("a")), !e)
|
|
17
20
|
break;
|
|
18
|
-
const
|
|
19
|
-
if (
|
|
21
|
+
const i = d.DEFAULT, a = d.ATTR;
|
|
22
|
+
if (i && e.src) {
|
|
20
23
|
const o = e.src;
|
|
21
|
-
|
|
22
|
-
const
|
|
23
|
-
return o.includes(
|
|
24
|
-
}) && (e.src = `{{${
|
|
24
|
+
i.some((E) => {
|
|
25
|
+
const s = E.split("/").pop() || "", g = o.split("/").pop() || "";
|
|
26
|
+
return o.includes(E) || o.includes(s) || g === s;
|
|
27
|
+
}) && (e.src = `{{${a}_${f}}}`);
|
|
25
28
|
}
|
|
26
|
-
const n = (I = (F =
|
|
27
|
-
if (n && e.setAttribute("alt", `{{${n}_${
|
|
28
|
-
const o = (w =
|
|
29
|
+
const n = (I = (F = R.name) == null ? void 0 : F[T]) == null ? void 0 : I.ATTR;
|
|
30
|
+
if (n && e.setAttribute("alt", `{{${n}_${f}}}`), c) {
|
|
31
|
+
const o = (w = R.itemLink) == null ? void 0 : w[T];
|
|
29
32
|
if (o) {
|
|
30
|
-
const
|
|
31
|
-
(
|
|
33
|
+
const A = o.HREF, E = o.DEFAULT_HREF || "#!", s = c.href;
|
|
34
|
+
(s === "#" || s === "" || s.endsWith("#!") || s.endsWith(E) || s === `${window.location.href}${E}` || !s || s === window.location.href) && (c.href = `{{${A}_${f}}}`);
|
|
32
35
|
}
|
|
33
36
|
}
|
|
34
37
|
break;
|
|
35
38
|
}
|
|
36
39
|
case "name": {
|
|
37
|
-
const e = d,
|
|
38
|
-
t.textContent && (t.innerHTML = C(t, `{{${
|
|
40
|
+
const e = d, c = e.ATTR, i = e.DEFAULT_HREF || "#!", a = e.HREF;
|
|
41
|
+
t.textContent && (t.innerHTML = C(t, `{{${c}_${f}}}`));
|
|
39
42
|
const n = t.closest("a") || (t.tagName === "A" ? t : null);
|
|
40
|
-
if (n &&
|
|
41
|
-
const o = n.href,
|
|
42
|
-
(o ===
|
|
43
|
+
if (n && a) {
|
|
44
|
+
const o = n.href, A = `${window.location.href}${i}`;
|
|
45
|
+
(o === A || o.endsWith(i)) && (n.href = `{{${a}_${f}}}`);
|
|
43
46
|
}
|
|
44
47
|
break;
|
|
45
48
|
}
|
|
46
49
|
case "price":
|
|
47
50
|
case "originalPrice": {
|
|
48
|
-
const e = d,
|
|
49
|
-
let
|
|
50
|
-
n ?
|
|
51
|
-
const
|
|
52
|
-
let
|
|
53
|
-
const
|
|
54
|
-
let
|
|
55
|
-
|
|
51
|
+
const e = d, c = t.getAttribute("data-formated"), i = t.getAttribute("data-single_price"), a = c === "true", n = i === "true", o = t.getAttribute("data-curency") || "before";
|
|
52
|
+
let A;
|
|
53
|
+
n ? A = a ? e.SINGLE_PRICE_FORMATTED : e.SINGLE_PRICE : A = a ? e.PRICE_FORMATTED : e.PRICE;
|
|
54
|
+
const E = e.CURRENCY;
|
|
55
|
+
let s = `{{${A}_${f}}}`;
|
|
56
|
+
const g = (t.getAttribute("data-currency_symbol") || "").trim(), N = g !== "" && g !== O.productPriceCurrencySymbolControlValue;
|
|
57
|
+
let m = "";
|
|
58
|
+
N ? m = g : E && (m = `{{${E}_${f}}}`), m && (s = o === "after" ? `${s} ${m}` : `${m} ${s}`), t.innerHTML = C(t, s);
|
|
56
59
|
break;
|
|
57
60
|
}
|
|
58
61
|
case "quantity": {
|
|
59
|
-
const e = d,
|
|
60
|
-
t.textContent && t.textContent.trim() ===
|
|
62
|
+
const e = d, c = e.ATTR, i = e.DEFAULT;
|
|
63
|
+
t.textContent && t.textContent.trim() === i && (t.innerHTML = C(t, `{{${c}_${f}}}`));
|
|
61
64
|
break;
|
|
62
65
|
}
|
|
63
66
|
case "button": {
|
|
64
|
-
const e = d,
|
|
65
|
-
if (
|
|
66
|
-
const n =
|
|
67
|
-
(n === "" || n === "#" || n === o || n.endsWith(
|
|
67
|
+
const e = d, c = e.HREF, i = e.DEFAULT_HREF || "#!", a = t.tagName === "A" ? t : t.querySelector("a");
|
|
68
|
+
if (a) {
|
|
69
|
+
const n = a.href || "", o = `${window.location.href}${i}`;
|
|
70
|
+
(n === "" || n === "#" || n === o || n.endsWith(i) || n.endsWith("#!") || n === window.location.href) && (a.href = `{{${c}_${f}}}`);
|
|
68
71
|
}
|
|
69
72
|
break;
|
|
70
73
|
}
|
|
71
74
|
case "itemLink": {
|
|
72
|
-
const e = d,
|
|
73
|
-
if (
|
|
74
|
-
const n =
|
|
75
|
-
(n === o || n.endsWith(
|
|
75
|
+
const e = d, c = e.HREF, i = e.DEFAULT_HREF || "#!", a = t;
|
|
76
|
+
if (a.href) {
|
|
77
|
+
const n = a.href, o = `${window.location.href}${i}`;
|
|
78
|
+
(n === o || n.endsWith(i)) && (a.href = `{{${c}_${f}}}`);
|
|
76
79
|
}
|
|
77
80
|
break;
|
|
78
81
|
}
|
|
79
82
|
default: {
|
|
80
83
|
if ("ATTR" in d) {
|
|
81
84
|
const e = d.ATTR;
|
|
82
|
-
t.textContent && (t.innerHTML = C(t, `{{${e}_${
|
|
85
|
+
t.textContent && (t.innerHTML = C(t, `{{${e}_${f}}}`));
|
|
83
86
|
}
|
|
84
87
|
break;
|
|
85
88
|
}
|
|
@@ -88,54 +91,54 @@ function V(L) {
|
|
|
88
91
|
});
|
|
89
92
|
});
|
|
90
93
|
const k = H.match(/<!DOCTYPE[^>]*>/i), P = k ? `${k[0]}
|
|
91
|
-
` : "", D =
|
|
94
|
+
` : "", D = b.querySelectorAll(".ins-product-td"), M = [];
|
|
92
95
|
D.forEach((r) => {
|
|
93
|
-
const
|
|
96
|
+
const u = r.getAttribute("data-type") || "CART_ITEMS", p = r.getAttribute("data-number") || "1", l = r.outerHTML;
|
|
94
97
|
M.push({
|
|
95
98
|
element: r,
|
|
96
|
-
outerHtml:
|
|
97
|
-
type:
|
|
98
|
-
number: p
|
|
99
|
-
nodup: c || void 0
|
|
99
|
+
outerHtml: l,
|
|
100
|
+
type: u,
|
|
101
|
+
number: p
|
|
100
102
|
});
|
|
101
103
|
});
|
|
102
|
-
let _ = P +
|
|
103
|
-
M.reverse().forEach(({ outerHtml: r, type:
|
|
104
|
-
let
|
|
105
|
-
switch (
|
|
104
|
+
let _ = P + b.documentElement.outerHTML;
|
|
105
|
+
M.reverse().forEach(({ outerHtml: r, type: u, number: p }) => {
|
|
106
|
+
let l = "";
|
|
107
|
+
switch (u) {
|
|
106
108
|
case "CART_ITEMS":
|
|
107
|
-
|
|
109
|
+
l = "ins_apr_total_product_kind";
|
|
108
110
|
break;
|
|
109
111
|
case "BROWSED_ITEMS":
|
|
110
|
-
|
|
112
|
+
l = "browsed_item_total_product_kind";
|
|
111
113
|
break;
|
|
112
114
|
case "PURCHASED_ITEMS":
|
|
113
|
-
|
|
115
|
+
l = "purchased_item_total_product_kind";
|
|
114
116
|
break;
|
|
115
117
|
}
|
|
116
|
-
if (
|
|
117
|
-
const
|
|
118
|
+
if (l) {
|
|
119
|
+
const $ = parseInt(p) - 1, T = `${`{% if ${l} > ${$} %}`}${r}{% endif %}`;
|
|
118
120
|
_ = _.replace(r, T);
|
|
119
121
|
}
|
|
120
122
|
});
|
|
121
|
-
const x =
|
|
123
|
+
const x = b.querySelectorAll('[product-attr="originalPrice"][data-type="CART_ITEMS"]'), S = [];
|
|
122
124
|
return x.forEach((r) => {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
+
var $;
|
|
126
|
+
const u = r.getAttribute("data-number"), p = r.getAttribute("data-type");
|
|
127
|
+
if (!u || p !== "CART_ITEMS" || (($ = r.closest(".ins-product-td")) == null ? void 0 : $.getAttribute("data-nodup")) === "false")
|
|
125
128
|
return;
|
|
126
|
-
const
|
|
127
|
-
if (
|
|
128
|
-
const
|
|
129
|
-
|
|
129
|
+
const h = r.closest(".product-original-price-class");
|
|
130
|
+
if (h) {
|
|
131
|
+
const y = h.outerHTML;
|
|
132
|
+
S.some((T) => T.tdOuterHtml === y) || S.push({ tdOuterHtml: y, number: u });
|
|
130
133
|
}
|
|
131
|
-
}),
|
|
132
|
-
const p = `{% if ins_apr_price_${
|
|
134
|
+
}), S.reverse().forEach(({ tdOuterHtml: r, number: u }) => {
|
|
135
|
+
const p = `{% if ins_apr_price_${u} != ins_apr_originalprice_${u} %}`;
|
|
133
136
|
if (!_.includes(p) && !r.includes("{% if")) {
|
|
134
|
-
const
|
|
135
|
-
_ = _.replace(r,
|
|
137
|
+
const h = `${p}${r}{% endif %}`;
|
|
138
|
+
_ = _.replace(r, h);
|
|
136
139
|
}
|
|
137
140
|
}), _.replaceAll("<!--{%", "{%").replaceAll("%}-->", "%}").replaceAll("<!--{%", "{%").replaceAll("%}-->", "%}");
|
|
138
141
|
}
|
|
139
142
|
export {
|
|
140
|
-
|
|
143
|
+
Y as pairProductVariables
|
|
141
144
|
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { DATA_ATTRIBUTE_REGEX as T } from "../enums/html-validator.js";
|
|
2
|
+
const d = /{{([a-zA-Z0-9_.\s]*)}}/gm, h = (n, e) => {
|
|
3
|
+
if (!e || e.length === 0)
|
|
4
|
+
return { matched: [], unmatchedTokens: [] };
|
|
5
|
+
const s = n.replace(T, "$1").match(d);
|
|
6
|
+
if (!s)
|
|
7
|
+
return { matched: [], unmatchedTokens: [] };
|
|
8
|
+
const u = new Map(
|
|
9
|
+
e.map((c) => [c.value.trim().toLowerCase(), c])
|
|
10
|
+
), a = /* @__PURE__ */ new Set(), o = [], m = [];
|
|
11
|
+
return s.forEach((c) => {
|
|
12
|
+
const t = c.slice(2, -2).trim().toLowerCase();
|
|
13
|
+
if (t === "" || a.has(t))
|
|
14
|
+
return;
|
|
15
|
+
a.add(t);
|
|
16
|
+
const r = u.get(t);
|
|
17
|
+
r ? o.push(r) : m.push(t);
|
|
18
|
+
}), { matched: o, unmatchedTokens: m };
|
|
19
|
+
}, E = (n, e) => h(n, e).matched, k = (n, e) => h(n, e).unmatchedTokens;
|
|
20
|
+
export {
|
|
21
|
+
E as extractUsedDynamicContent,
|
|
22
|
+
k as getUnmatchedDynamicContentTokens
|
|
23
|
+
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
const f = "text-decoration", A = /(?:[^;"'()]|"[^"]*"|'[^']*'|\([^)]*\))+/g, c = (e) => (e.match(A) || []).map((r) => r.trim()).filter(Boolean), l = (e) => e.slice(0, e.indexOf(":")).trim().toLowerCase(), m = (e) => e.slice(e.indexOf(":") + 1).trim().toLowerCase(), u = (e, r) => {
|
|
2
|
+
const s = e.getAttribute("style");
|
|
3
|
+
if (!s)
|
|
4
|
+
return;
|
|
5
|
+
const t = c(r.getAttribute("style") || ""), i = new Set(t.map(l)), o = c(s).filter((n) => {
|
|
6
|
+
const a = l(n);
|
|
7
|
+
return !a || i.has(a) ? !1 : !a.startsWith(f) && m(n) !== "inherit";
|
|
8
|
+
});
|
|
9
|
+
o.length && r.setAttribute("style", [...t, ...o].join("; "));
|
|
10
|
+
}, y = ["product-attr", "data-type", "data-number", "data-slot-2"], p = (e, r) => {
|
|
11
|
+
y.forEach((s) => {
|
|
12
|
+
const t = e.getAttribute(s);
|
|
13
|
+
t !== null && !r.hasAttribute(s) && r.setAttribute(s, t);
|
|
14
|
+
});
|
|
15
|
+
};
|
|
16
|
+
function E(e) {
|
|
17
|
+
e.querySelectorAll(".ins-product-td").forEach((r) => {
|
|
18
|
+
const s = /* @__PURE__ */ new Set();
|
|
19
|
+
r.querySelectorAll('[product-attr="name"]').forEach((t) => {
|
|
20
|
+
const i = t.closest("a");
|
|
21
|
+
i && r.contains(i) && s.add(i);
|
|
22
|
+
}), s.forEach((t) => {
|
|
23
|
+
if (t.querySelector("img") || Array.from(t.querySelectorAll("[product-attr]")).some((a) => a.getAttribute("product-attr") !== "name"))
|
|
24
|
+
return;
|
|
25
|
+
const o = t.closest("p");
|
|
26
|
+
if (o && r.contains(o)) {
|
|
27
|
+
p(t, o), u(t, o), t.replaceWith(...Array.from(t.childNodes));
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
const n = e.createElement("span");
|
|
31
|
+
p(t, n), u(t, n), n.append(...Array.from(t.childNodes)), t.replaceWith(n);
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
export {
|
|
36
|
+
E as unwrapProductNameLinks
|
|
37
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@useinsider/guido",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.15.0-beta.244c73c",
|
|
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",
|