@useinsider/guido 3.7.0-beta.830822b → 3.7.0-beta.960d9c8

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.
@@ -13,6 +13,8 @@ const y = /* @__PURE__ */ new Set([
13
13
  "fix-url-encoding-end",
14
14
  "fix-tags-start",
15
15
  "fix-tags-end",
16
+ // Remove translate-injected <font> tags — pure removal, never emits AMP-forbidden output.
17
+ "strip-font-tags",
16
18
  // Image domain corrections — plain string replacement.
17
19
  "replace-old-image-domain",
18
20
  "replace-old-v2-image-domain",
@@ -26,22 +28,22 @@ const y = /* @__PURE__ */ new Set([
26
28
  // Coupon placeholder replacement (only present when liquidSyntax is enabled).
27
29
  "liquid-coupon-code"
28
30
  ]), M = () => {
29
- var m, t, r;
30
- const { compiler: e, isFeatureEnabled: a, partner: n } = k(), u = ((m = e.value) == null ? void 0 : m.customRules) || [], l = [
31
- ...!!((t = e.value) != null && t.ignoreDefaultRules) ? [] : R,
31
+ var t, m, r;
32
+ const { compiler: e, isFeatureEnabled: a, partner: n } = k(), p = ((t = e.value) == null ? void 0 : t.customRules) || [], l = [
33
+ ...!!((m = e.value) != null && m.ignoreDefaultRules) ? [] : R,
32
34
  ...v,
33
35
  ...x,
34
36
  ...g,
35
37
  ...b,
36
38
  ...H,
37
39
  ...a("liquidSyntax") ? C : [],
38
- ...u.map((o, f) => ({
40
+ ...p.map((o, f) => ({
39
41
  ...o,
40
42
  priority: o.priority + 1e3 + f
41
43
  // Ensure additional rules run after default rules
42
44
  }))
43
- ], p = s(l), c = l.filter((o) => y.has(o.id)), d = s(c), i = (r = n.value) == null ? void 0 : r.fallbackFont;
44
- return { compileHtml: (o) => p.compile(o, void 0, i), compileAmpHtml: (o) => d.compile(o, void 0, i) };
45
+ ], u = s(l), c = l.filter((o) => y.has(o.id)), d = s(c), i = (r = n.value) == null ? void 0 : r.fallbackFont;
46
+ return { compileHtml: (o) => u.compile(o, void 0, i), compileAmpHtml: (o) => d.compile(o, void 0, i) };
45
47
  };
46
48
  export {
47
49
  M as useHtmlCompiler
@@ -1,4 +1,5 @@
1
- const a = [
1
+ import { stripFontTags as n } from "../../utils/stripFontTags.js";
2
+ const l = [
2
3
  {
3
4
  id: "fix-url-encoding-start",
4
5
  description: "Replace {%22 with %7B%22 to fix URL encoding",
@@ -53,6 +54,13 @@ const a = [
53
54
  replaceAll: !0,
54
55
  priority: 14
55
56
  },
57
+ {
58
+ id: "strip-font-tags",
59
+ description: 'Unwrap <font> tags injected by browser translate extensions (e.g. Google Translate), keeping inner content — prevents Chrome DOM-depth overflow ("512 nodes")',
60
+ type: "custom",
61
+ processor: (e) => n(e),
62
+ priority: 15
63
+ },
56
64
  {
57
65
  id: "remove-apty-iframe",
58
66
  description: "Cleanup Apty Iframe Code",
@@ -91,7 +99,7 @@ const a = [
91
99
  description: "Adding MSO Conditions",
92
100
  type: "custom",
93
101
  processor: (e) => {
94
- const t = [
102
+ const i = [
95
103
  `<!--[if gte mso 9]>
96
104
  <style>sup {
97
105
  font-size: 100% !important;
@@ -114,10 +122,10 @@ const a = [
114
122
  ], s = /<head>([\S\s]*)<\/head>/, o = new RegExp(s);
115
123
  if (!e.match(o))
116
124
  return e;
117
- let i = e;
118
- return t.forEach((r) => {
119
- i = i.replace("</head>", `${r}</head>`);
120
- }), i;
125
+ let t = e;
126
+ return i.forEach((r) => {
127
+ t = t.replace("</head>", `${r}</head>`);
128
+ }), t;
121
129
  },
122
130
  priority: 30
123
131
  },
@@ -141,5 +149,5 @@ const a = [
141
149
  }
142
150
  ];
143
151
  export {
144
- a as defaultHtmlCompilerRules
152
+ l as defaultHtmlCompilerRules
145
153
  };
@@ -0,0 +1,7 @@
1
+ import { stripFontTags as r } from "../../utils/stripFontTags.js";
2
+ function n(t) {
3
+ return r(t);
4
+ }
5
+ export {
6
+ n as migrateFontTags
7
+ };
@@ -1,13 +1,14 @@
1
1
  import { migrateCheckbox as o } from "./checkboxMigrator.js";
2
2
  import { migrateCouponBlock as i } from "./couponBlockMigrator.js";
3
- import { migrateItemsBlock as e } from "./itemsBlockMigrator.js";
4
- import { migrateRadioButton as a } from "./radioButtonMigrator.js";
5
- import { migrateRecommendation as g } from "./recommendationMigrator.js";
6
- import { migrateUnsubscribe as n } from "./unsubscribeMigrator.js";
7
- const b = async (r, t = {}) => {
3
+ import { migrateFontTags as e } from "./fontTagMigrator.js";
4
+ import { migrateItemsBlock as a } from "./itemsBlockMigrator.js";
5
+ import { migrateRadioButton as g } from "./radioButtonMigrator.js";
6
+ import { migrateRecommendation as n } from "./recommendationMigrator.js";
7
+ import { migrateUnsubscribe as p } from "./unsubscribeMigrator.js";
8
+ const k = async (r, t = {}) => {
8
9
  let m = r;
9
- return m = o(m), m = a(m), m = await n(m), m = i(m), m = g(m, t), m = e(m), m;
10
+ return m = e(m), m = o(m), m = g(m), m = await p(m), m = i(m), m = n(m, t), m = a(m), m;
10
11
  };
11
12
  export {
12
- b as migrate
13
+ k as migrate
13
14
  };
@@ -1,8 +1,6 @@
1
1
  import { useTranslations as r } from "../../composables/useTranslations.js";
2
2
  const l = {
3
- RECOMMENDATION_API_URL: "https://recommendationv2.api.useinsider.com",
4
- // Relative path → same-origin as the embedding inone dashboard (Dataforce).
5
- PRODUCT_ATTRIBUTES_PATH: "/product-attributes/get-attributes"
3
+ RECOMMENDATION_API_URL: "https://recommendationv2.api.useinsider.com"
6
4
  }, c = {
7
5
  CLIENT_ID: "clientId"
8
6
  }, d = () => {
@@ -6,8 +6,8 @@ import { DEFAULT_CARDS_IN_ROW as F } from "../constants/layout.js";
6
6
  import { EXCLUDED_ALGORITHM_IDS as D } from "../constants/defaultConfig.js";
7
7
  import { getDefaultProducts as S } from "../templates/utils.js";
8
8
  import { generateCompleteFilterQuery as b } from "../utils/filterUtil.js";
9
- import { getPartnerRecommendationParams as w } from "../utils/partnerCustomizations.js";
10
- import { isFilterValid as v } from "../validation/filterSchema.js";
9
+ import { getPartnerRecommendationParams as v } from "../utils/partnerCustomizations.js";
10
+ import { isFilterValid as w } from "../validation/filterSchema.js";
11
11
  import { isConfigValid as N } from "../validation/requiredFields.js";
12
12
  const h = y();
13
13
  let m = null, u = null, d = null;
@@ -132,7 +132,7 @@ const x = () => ({
132
132
  value: e.text
133
133
  })),
134
134
  getFilterList() {
135
- return Object.values(this.filterList).filter((t) => t.isFilterable !== 0 && t.isFilterable !== !1).map((t) => {
135
+ return Object.values(this.filterList).map((t) => {
136
136
  let e;
137
137
  return t.type === "productAttribute" ? e = `product_attributes.${t.attributeName}` : C.includes(t.attributeName) ? e = `${t.attributeName}.${this.recommendationConfigs.currencySettings.value}` : e = t.attributeName, {
138
138
  text: t.displayName,
@@ -379,7 +379,7 @@ const x = () => ({
379
379
  const n = [...e.recommendationConfigs.filters];
380
380
  n[r] = {
381
381
  ...t,
382
- isValid: v(t)
382
+ isValid: w(t)
383
383
  }, e.recommendationConfigs.filters = n;
384
384
  }
385
385
  },
@@ -456,7 +456,7 @@ const x = () => ({
456
456
  };
457
457
  r.strategy === "manualMerchandising" ? a.productId = r.productIds.join(",") : r.strategy === "similarViewed" && (a.productId = "{itemId}"), r.strategy === "userBased" && (a.userId = "{user_id}"), c && (a.filter = c), r.shuffleProducts && (a.shuffle = !0), Object.assign(
458
458
  a,
459
- w(o.partnerName, r.strategy)
459
+ v(o.partnerName, r.strategy)
460
460
  );
461
461
  let f;
462
462
  try {
@@ -1,52 +1,40 @@
1
- import { useHttp as d } from "../composables/useHttp.js";
2
- import { QUERY_PARAMS as l, URLS as u } from "../enums/extensions/recommendationBlock.js";
3
- const R = (o) => o.reduce(
4
- (a, t, s) => (a[s] = {
5
- attributeName: t.attributeName,
6
- attributeJs: t.attributeJs,
7
- attributeType: t.attributeType,
8
- type: t.type,
9
- displayName: t.displayName,
10
- isFilterable: t.isFilterable
11
- }, a),
12
- {}
13
- ), f = () => {
14
- const { get: o } = d(), { get: a } = d({ headers: {} }), t = "6KcLM9TwheVB1mgK";
1
+ import { useHttp as a } from "../composables/useHttp.js";
2
+ import { QUERY_PARAMS as d, URLS as h } from "../enums/extensions/recommendationBlock.js";
3
+ const y = () => {
4
+ const { get: r } = a(), { get: s } = a({ headers: {} }), m = "6KcLM9TwheVB1mgK";
15
5
  return {
16
6
  fetchRecommendationCreateData: async () => {
17
7
  try {
18
- return (await o("/newsletter/recommendations/create-data")).data;
8
+ return (await r("/newsletter/recommendations/create-data")).data;
19
9
  } catch (e) {
20
10
  throw console.error("fetchUserModalState error:", e), e;
21
11
  }
22
12
  },
23
13
  fetchRecommendationFilters: async () => {
24
14
  try {
25
- const { data: e } = await o(
26
- u.PRODUCT_ATTRIBUTES_PATH
27
- ), n = Array.isArray(e) ? e : (e == null ? void 0 : e.data) ?? [];
28
- return R(n);
15
+ const { data: e } = await r("/stripo/email-recommendation-attributes");
16
+ return e;
29
17
  } catch (e) {
30
18
  throw console.error("fetchRecommendationFilters error:", e), e;
31
19
  }
32
20
  },
33
- fetchRecommendationProducts: async (e, n) => {
34
- var i;
21
+ fetchRecommendationProducts: async (e, i) => {
22
+ var n;
35
23
  try {
36
- const r = new URLSearchParams(Object.entries(n));
37
- r.set(l.CLIENT_ID, t);
38
- const m = decodeURIComponent(r.toString());
39
- console.debug("🏁 Recommendation API Query:", m);
40
- const c = await a(
41
- `${u.RECOMMENDATION_API_URL}/v2/${e}?${m}`
24
+ const t = new URLSearchParams(Object.entries(i));
25
+ t.set(d.CLIENT_ID, m);
26
+ const c = decodeURIComponent(t.toString());
27
+ console.debug("🏁 Recommendation API Query:", c);
28
+ const o = await s(
29
+ `${h.RECOMMENDATION_API_URL}/v2/${e}?${c}`
42
30
  );
43
- return ((i = c == null ? void 0 : c.data) == null ? void 0 : i.data) ?? [];
44
- } catch (r) {
45
- throw console.error("fetchRecommendationProducts error:", r), r;
31
+ return ((n = o == null ? void 0 : o.data) == null ? void 0 : n.data) ?? [];
32
+ } catch (t) {
33
+ throw console.error("fetchRecommendationProducts error:", t), t;
46
34
  }
47
35
  }
48
36
  };
49
37
  };
50
38
  export {
51
- f as useRecommendationApi
39
+ y as useRecommendationApi
52
40
  };
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Heals templates already saved with browser-translate-injected `<font>` tags
3
+ * (see {@link stripFontTags}). Runs on load before the block migrators so they
4
+ * operate on clean HTML, and stops the accumulated nesting from re-triggering
5
+ * Chrome's DOM-depth limit when the template is reopened in the editor.
6
+ */
7
+ export declare function migrateFontTags(html: string): string;
@@ -2,7 +2,6 @@ import type { TextValueObject } from '@@/Types/generic';
2
2
  import type { RecommendationFeedItem } from '@@/Types/recommendation';
3
3
  export declare const URLS: {
4
4
  RECOMMENDATION_API_URL: string;
5
- PRODUCT_ATTRIBUTES_PATH: string;
6
5
  };
7
6
  export declare const QUERY_PARAMS: {
8
7
  CLIENT_ID: string;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Browser translation extensions (e.g. Google Translate) wrap translated text in
3
+ * nested `<font style="vertical-align:inherit">` tags. These get persisted into
4
+ * the template and accumulate over edit/translate cycles until Chrome exceeds its
5
+ * DOM-depth limit (the "512 nodes" error). Stripo never emits `<font>` tags, so
6
+ * any present are foreign — unwrap them (drop the tag, keep the inner content).
7
+ *
8
+ * Removing each open/close tag independently handles any nesting depth without a
9
+ * DOMParser round-trip, so surrounding markup (incl. `esd-*` attributes) is left
10
+ * byte-for-byte intact.
11
+ */
12
+ export declare function stripFontTags(html: string): string;
@@ -0,0 +1,7 @@
1
+ const r = /<\s*\/?\s*font(?=[\s/>])[^>]*>/gi;
2
+ function s(n) {
3
+ return n && n.replace(r, "");
4
+ }
5
+ export {
6
+ s as stripFontTags
7
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@useinsider/guido",
3
- "version": "3.7.0-beta.830822b",
3
+ "version": "3.7.0-beta.960d9c8",
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",