@useinsider/guido 3.12.0-beta.b9402d1 → 3.12.0-beta.bec0e55

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.
@@ -15,7 +15,7 @@ var a = function() {
15
15
  i,
16
16
  !1,
17
17
  null,
18
- "06afaecb"
18
+ "cf946232"
19
19
  );
20
20
  const f = n.exports;
21
21
  export {
@@ -1,24 +1,24 @@
1
- import { defineComponent as u, ref as a, onMounted as p, onBeforeUnmount as l, nextTick as v } from "vue";
2
- import { usePreviewInteractionGuard as d } from "../../../../composables/usePreviewInteractionGuard.js";
1
+ import { defineComponent as u, ref as a, onMounted as p, onBeforeUnmount as l, nextTick as d } from "vue";
2
+ import { usePreviewInteractionGuard as v } from "../../../../composables/usePreviewInteractionGuard.js";
3
3
  import { useTranslations as _ } from "../../../../composables/useTranslations.js";
4
4
  import { usePreviewStore as w } from "../../../../stores/preview.js";
5
5
  import I from "./DesktopBrowserHeader.vue.js";
6
6
  const C = /* @__PURE__ */ u({
7
7
  __name: "DesktopPreview",
8
- setup(k) {
9
- const i = _(), { blockPreviewInteractions: t } = d(), o = a(), n = a(!1), c = w();
8
+ setup(P) {
9
+ const i = _(), { guardPreviewInteractions: t } = v(), o = a(), r = a(!1), c = w();
10
10
  let e = null;
11
11
  const f = (m) => {
12
12
  t(m.target);
13
- }, r = () => {
13
+ }, n = () => {
14
14
  o.value && (e = new ResizeObserver(() => {
15
- }), e.observe(o.value), v(() => {
16
- n.value = !0;
15
+ }), e.observe(o.value), d(() => {
16
+ r.value = !0;
17
17
  }));
18
18
  }, s = () => {
19
19
  e == null || e.disconnect();
20
20
  };
21
- return p(r), l(s), { __sfc: !0, trans: i, blockPreviewInteractions: t, containerRef: o, isContainerReady: n, previewStore: c, resizeObserver: e, onIframeLoad: f, initIframe: r, cleanIframe: s, DesktopBrowserHeader: I };
21
+ return p(n), l(s), { __sfc: !0, trans: i, guardPreviewInteractions: t, containerRef: o, isContainerReady: r, previewStore: c, resizeObserver: e, onIframeLoad: f, initIframe: n, cleanIframe: s, DesktopBrowserHeader: I };
22
22
  }
23
23
  });
24
24
  export {
@@ -1,20 +1,20 @@
1
1
  import e from "./ContentView.vue2.js";
2
2
  /* empty css */
3
3
  import n from "../../../../_virtual/_plugin-vue2_normalizer.js";
4
- var c = function() {
4
+ var o = function() {
5
5
  var t = this, s = t._self._c, a = t._self._setupProxy;
6
6
  return s("div", { staticClass: "w-1 h-1 b-c-4 d-f f-d-c" }, [s("div", { staticClass: "d-f j-c-s-b a-i-c p-2 h-6-s" }, [s("div", { staticClass: "d-f a-i-c cur-p", on: { click: function(l) {
7
7
  return t.$emit("back-to-inbox");
8
8
  } } }, [s(a.InIcons, { staticClass: "f-s-3 i-c-7", attrs: { name: "line-chevron-left" } }), s("span", { staticClass: "ml-2 f-s-1 f-w-400 l-h-1 t-c-7" }, [t._v(t._s(a.trans("newsletter.inbox")))])], 1), s("div", { staticClass: "d-f a-i-c" }, [s(a.InIcons, { staticClass: "i-c-52", attrs: { name: "line-chevron-down" } }), s(a.InIcons, { staticClass: "ml-1 i-c-52", attrs: { name: "line-chevron-up" } })], 1)]), s("div", { staticClass: "iframe-wrapper f-g-1 o-h" }, [s("iframe", { ref: "iframeRef", staticClass: "iframe-scaled d-b b-c-4 bor-s-n", attrs: { sandbox: "allow-same-origin allow-popups allow-forms allow-scripts allow-popups-to-escape-sandbox", srcdoc: a.previewStore.previewHtml }, on: { load: a.onLoad } })])]);
9
- }, o = [], i = /* @__PURE__ */ n(
9
+ }, i = [], r = /* @__PURE__ */ n(
10
10
  e,
11
- c,
12
11
  o,
12
+ i,
13
13
  !1,
14
14
  null,
15
- "cbafc185"
15
+ "f255b2bb"
16
16
  );
17
- const d = i.exports;
17
+ const d = r.exports;
18
18
  export {
19
19
  d as default
20
20
  };
@@ -1,24 +1,24 @@
1
- import { defineComponent as m, ref as a } from "vue";
1
+ import { defineComponent as c, ref as a } from "vue";
2
2
  import { usePreviewInteractionGuard as f } from "../../../../composables/usePreviewInteractionGuard.js";
3
3
  import { useResponsivePreview as p } from "../../../../composables/useResponsivePreview.js";
4
4
  import { useTranslations as u } from "../../../../composables/useTranslations.js";
5
5
  import { usePreviewStore as v } from "../../../../stores/preview.js";
6
- import { InIcons as P } from "@useinsider/design-system-vue";
7
- const g = /* @__PURE__ */ m({
6
+ import { InIcons as d } from "@useinsider/design-system-vue";
7
+ const b = /* @__PURE__ */ c({
8
8
  __name: "ContentView",
9
9
  emits: ["back-to-inbox"],
10
- setup(_) {
11
- const c = u(), t = v(), r = a(), { setupResponsivePreview: n } = p(), { blockPreviewInteractions: s } = f(), i = (e) => {
10
+ setup(P) {
11
+ const m = u(), r = v(), t = a(), { setupResponsivePreview: n } = p(), { guardPreviewInteractions: s } = f(), i = (e) => {
12
12
  ["transform", "transform-origin", "height"].forEach((o) => {
13
13
  e.documentElement.style.removeProperty(o);
14
14
  });
15
15
  };
16
- return { __sfc: !0, trans: c, previewStore: t, iframeRef: r, setupResponsivePreview: n, blockPreviewInteractions: s, clearAMPTransforms: i, onLoad: () => {
17
- const e = r.value, o = e == null ? void 0 : e.contentDocument;
18
- o && (n(e), s(e), t.isAMPResponsive && i(o));
19
- }, InIcons: P };
16
+ return { __sfc: !0, trans: m, previewStore: r, iframeRef: t, setupResponsivePreview: n, guardPreviewInteractions: s, clearAMPTransforms: i, onLoad: () => {
17
+ const e = t.value, o = e == null ? void 0 : e.contentDocument;
18
+ o && (n(e), s(e), r.isAMPResponsive && i(o));
19
+ }, InIcons: d };
20
20
  }
21
21
  });
22
22
  export {
23
- g as default
23
+ b as default
24
24
  };
@@ -1,17 +1,42 @@
1
- const o = ["click", "auxclick", "submit"], c = (t) => {
2
- t.preventDefault(), t.stopPropagation();
3
- }, a = () => ({ blockPreviewInteractions: (r) => {
1
+ import { URLS as o, MERGE_TAGS as a } from "../enums/unsubscribe.js";
2
+ import { UNSUBSCRIBE_LINK_SELECTOR as i } from "../extensions/Blocks/Unsubscribe/utils/constants.js";
3
+ import { BASE_SAFE_URL_SCHEMES as u } from "../utils/urlSchemes.js";
4
+ const E = ["click", "auxclick"], d = [
5
+ ...Object.values(a),
6
+ o.UNSUBSCRIBE_URL,
7
+ o.PREFERENCES_URL
8
+ ], l = (e) => {
9
+ if (e.matches(i))
10
+ return !0;
11
+ const r = e.getAttribute("href") ?? "";
12
+ return d.some((t) => r.includes(t));
13
+ }, S = [...u, "tel:", "sms:"], f = (e) => {
14
+ const r = (e.getAttribute("href") ?? "").trim();
15
+ return r === "" || r.startsWith("#") || r.startsWith("{{") ? !1 : S.includes(e.protocol);
16
+ }, m = (e) => {
17
+ var t, n;
18
+ const r = (n = (t = e.target) == null ? void 0 : t.closest) == null ? void 0 : n.call(t, "a");
19
+ if (r) {
20
+ if (l(r) || !f(r)) {
21
+ e.preventDefault(), e.stopPropagation();
22
+ return;
23
+ }
24
+ r.setAttribute("target", "_blank"), r.setAttribute("rel", "noopener noreferrer");
25
+ }
26
+ }, R = (e) => {
27
+ e.preventDefault(), e.stopPropagation();
28
+ }, s = /* @__PURE__ */ new WeakSet(), c = "guidoPreviewGuarded", g = () => ({ guardPreviewInteractions: (r) => {
4
29
  try {
5
- const e = r.contentDocument;
6
- if (!e)
30
+ const t = r.contentDocument;
31
+ if (!t || s.has(t))
7
32
  return;
8
- o.forEach((n) => {
9
- e.addEventListener(n, c, !0);
10
- });
11
- } catch (e) {
12
- console.warn("[usePreviewInteractionGuard] Could not guard preview iframe:", e);
33
+ delete t.documentElement.dataset[c], E.forEach((n) => {
34
+ t.addEventListener(n, m, !0);
35
+ }), t.addEventListener("submit", R, !0), s.add(t), t.documentElement.dataset[c] = "true";
36
+ } catch (t) {
37
+ console.warn("[usePreviewInteractionGuard] Could not guard preview iframe:", t);
13
38
  }
14
39
  } });
15
40
  export {
16
- a as usePreviewInteractionGuard
41
+ g as usePreviewInteractionGuard
17
42
  };
@@ -1,111 +1,112 @@
1
- import { BLOCK_ROOT_SELECTOR as S, CURRENCY_ATTR as p, CONTAINER_SELECTOR as O } from "../extensions/Blocks/Recommendation/constants/selectors.js";
2
- import { useRecommendationExtensionStore as h } from "../extensions/Blocks/Recommendation/store/recommendation.js";
3
- import { formatPrice as E } from "../extensions/Blocks/Recommendation/utils/priceFormatter.js";
4
- const f = `${S}[recommendation-id]`, C = ".product-old-price", R = /\{\{(?:reco_)?(\d+_\d+_[a-zA-Z0-9_.]+)\}\}/g, T = new RegExp(
1
+ import { BLOCK_ROOT_SELECTOR as f, CURRENCY_ATTR as A, CONTAINER_SELECTOR as O } from "../extensions/Blocks/Recommendation/constants/selectors.js";
2
+ import { useRecommendationExtensionStore as C } from "../extensions/Blocks/Recommendation/store/recommendation.js";
3
+ import { formatPrice as _ } from "../extensions/Blocks/Recommendation/utils/priceFormatter.js";
4
+ import { BASE_SAFE_URL_SCHEMES as R } from "../utils/urlSchemes.js";
5
+ const S = `${f}[recommendation-id]`, h = ".product-old-price", T = /\{\{(?:reco_)?(\d+_\d+_[a-zA-Z0-9_.]+)\}\}/g, b = new RegExp(
5
6
  "\\{%\\s*if\\s+([\\s\\S]+?)\\s*%\\}([\\s\\S]*?)(?:\\{%\\s*else\\s*%\\}([\\s\\S]*?))?\\{%\\s*endif\\s*%\\}",
6
7
  "g"
7
8
  );
8
- function b(e) {
9
+ function L(e) {
9
10
  return e.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
10
11
  }
11
- function _(e) {
12
- var s;
13
- const n = (s = e.replace(/[\u0000-\u0020]+/g, "").toLowerCase().match(/^([a-z][a-z0-9+.-]*):/)) == null ? void 0 : s[1];
14
- return n && n !== "http" && n !== "https" && n !== "mailto" ? "" : e;
12
+ function g(e) {
13
+ var c;
14
+ const i = (c = e.replace(/[\u0000-\u0020]+/g, "").toLowerCase().match(/^([a-z][a-z0-9+.-]*):/)) == null ? void 0 : c[1];
15
+ return i && !R.includes(`${i}:`) ? "" : e;
15
16
  }
16
17
  function N(e) {
17
- const t = e.getAttribute(p.CURRENCY) || "USD", n = e.getAttribute(p.DECIMAL_SEPARATOR) || ".", s = e.getAttribute(p.THOUSAND_SEPARATOR) || ",";
18
+ const t = e.getAttribute(A.CURRENCY) || "USD", i = e.getAttribute(A.DECIMAL_SEPARATOR) || ".", c = e.getAttribute(A.THOUSAND_SEPARATOR) || ",";
18
19
  return {
19
20
  code: t,
20
- symbol: e.getAttribute(p.SYMBOL) || t,
21
- alignment: e.getAttribute(p.ALIGNMENT) === "0" ? "before" : "after",
22
- decimalCount: parseInt(e.getAttribute(p.DECIMAL_COUNT) || "2") || 2,
23
- decimalSeparator: n,
24
- thousandSeparator: s
21
+ symbol: e.getAttribute(A.SYMBOL) || t,
22
+ alignment: e.getAttribute(A.ALIGNMENT) === "0" ? "before" : "after",
23
+ decimalCount: parseInt(e.getAttribute(A.DECIMAL_COUNT) || "2") || 2,
24
+ decimalSeparator: i,
25
+ thousandSeparator: c
25
26
  };
26
27
  }
27
- function g(e, t) {
28
+ function E(e, t) {
28
29
  return (e == null ? void 0 : e[t]) ?? Object.values(e ?? {})[0] ?? 0;
29
30
  }
30
- function L(e, t) {
31
- const n = g(e.original_price, t), s = g(e.price, t), o = n > 0 ? Math.round((n - s) / n * 100) : 0;
32
- return o > 0 ? `${o}%` : "0%";
31
+ function $(e, t) {
32
+ const i = E(e.original_price, t), c = E(e.price, t), n = i > 0 ? Math.round((i - c) / i * 100) : 0;
33
+ return n > 0 ? `${n}%` : "0%";
33
34
  }
34
- function P(e, t, n, s, o, a) {
35
- s.forEach((i, c) => {
36
- const r = (m) => `${n}_${c}_${m}`, u = E({ price: g(i.price, o.code), currency: o }), l = E({ price: g(i.original_price, o.code), currency: o }), d = L(i, o.code);
37
- e.set(r("name"), i.name ?? ""), e.set(r("image_url"), _(i.image_url ?? "")), e.set(r("url"), _(i.url ?? "")), e.set(r("item_id"), i.item_id ?? ""), e.set(r("currency"), ""), e.set(r("price"), u), e.set(r("original_price"), l), e.set(r("discount"), d), e.set(r("omnibus_price"), l), e.set(r("omnibus_discount"), d), a && u === l && t.add(`${n}_${c}`), Object.entries(i.product_attributes ?? {}).forEach(([m, A]) => {
38
- e.set(r(`product_attribute.${m}`), String(A)), e.set(r(m), String(A));
35
+ function P(e, t, i, c, n, a) {
36
+ c.forEach((o, s) => {
37
+ const r = (m) => `${i}_${s}_${m}`, u = _({ price: E(o.price, n.code), currency: n }), l = _({ price: E(o.original_price, n.code), currency: n }), d = $(o, n.code);
38
+ e.set(r("name"), o.name ?? ""), e.set(r("image_url"), g(o.image_url ?? "")), e.set(r("url"), g(o.url ?? "")), e.set(r("item_id"), o.item_id ?? ""), e.set(r("currency"), ""), e.set(r("price"), u), e.set(r("original_price"), l), e.set(r("discount"), d), e.set(r("omnibus_price"), l), e.set(r("omnibus_discount"), d), a && u === l && t.add(`${i}_${s}`), Object.entries(o.product_attributes ?? {}).forEach(([m, p]) => {
39
+ e.set(r(`product_attribute.${m}`), String(p)), e.set(r(m), String(p));
39
40
  });
40
41
  });
41
42
  }
42
- function $(e, t) {
43
- const n = e.match(/^(.+?)\s*(!=|==)\s*"([^"]*)"$/);
44
- if (!n)
43
+ function z(e, t) {
44
+ const i = e.match(/^(.+?)\s*(!=|==)\s*"([^"]*)"$/);
45
+ if (!i)
45
46
  return !0;
46
- const [, s, o, a] = n, i = t.get(s.trim()) ?? "";
47
- return o === "!=" ? i !== a : i === a;
47
+ const [, c, n, a] = i, o = t.get(c.trim()) ?? "";
48
+ return n === "!=" ? o !== a : o === a;
48
49
  }
49
- function z(e, t) {
50
+ function w(e, t) {
50
51
  return e.replace(
51
- T,
52
- (n, s, o, a) => s.split(/\s+and\s+/).every((c) => $(c.trim(), t)) ? o : a ?? ""
52
+ b,
53
+ (i, c, n, a) => c.split(/\s+and\s+/).every((s) => z(s.trim(), t)) ? n : a ?? ""
53
54
  );
54
55
  }
55
- function w(e) {
56
+ function D(e) {
56
57
  let t = e;
57
58
  for (; t.children.length === 1; )
58
59
  [t] = t.children;
59
60
  return t;
60
61
  }
61
- function D(e, t) {
62
- var i;
62
+ function I(e, t) {
63
+ var o;
63
64
  if (!t.size)
64
65
  return e;
65
- const n = e.replaceAll("{%", "<!--{%").replaceAll("%}", "%}-->"), s = new DOMParser().parseFromString(n, "text/html");
66
- s.querySelectorAll(f).forEach((c) => {
67
- const r = Number(c.getAttribute("recommendation-id"));
66
+ const i = e.replaceAll("{%", "<!--{%").replaceAll("%}", "%}-->"), c = new DOMParser().parseFromString(i, "text/html");
67
+ c.querySelectorAll(S).forEach((s) => {
68
+ const r = Number(s.getAttribute("recommendation-id"));
68
69
  if (!Number.isFinite(r))
69
70
  return;
70
- const u = c.querySelectorAll(O);
71
- (u.length ? Array.from(u) : [c]).forEach((d) => {
72
- d.querySelectorAll(C).forEach((m, A) => {
73
- t.has(`${r}_${A}`) && (w(m).textContent = "");
71
+ const u = s.querySelectorAll(O);
72
+ (u.length ? Array.from(u) : [s]).forEach((d) => {
73
+ d.querySelectorAll(h).forEach((m, p) => {
74
+ t.has(`${r}_${p}`) && (D(m).textContent = "");
74
75
  });
75
76
  });
76
77
  });
77
- const o = (i = e.match(/<!DOCTYPE[^>]*>/i)) == null ? void 0 : i[0];
78
- return ((o ? `${o}
79
- ` : "") + s.documentElement.outerHTML).replaceAll("<!--{%", "{%").replaceAll("%}-->", "%}").replaceAll("&lt;!--{%", "{%").replaceAll("%}--&gt;", "%}");
78
+ const n = (o = e.match(/<!DOCTYPE[^>]*>/i)) == null ? void 0 : o[0];
79
+ return ((n ? `${n}
80
+ ` : "") + c.documentElement.outerHTML).replaceAll("<!--{%", "{%").replaceAll("%}-->", "%}").replaceAll("&lt;!--{%", "{%").replaceAll("%}--&gt;", "%}");
80
81
  }
81
- function I(e) {
82
+ function y(e) {
82
83
  if (!e || !e.includes("recommendation-block-v2"))
83
84
  return e;
84
- const t = h(), n = new DOMParser().parseFromString(e, "text/html"), s = Array.from(n.querySelectorAll(f)), o = /* @__PURE__ */ new Map(), a = /* @__PURE__ */ new Set();
85
- if (s.forEach((c) => {
85
+ const t = C(), i = new DOMParser().parseFromString(e, "text/html"), c = Array.from(i.querySelectorAll(S)), n = /* @__PURE__ */ new Map(), a = /* @__PURE__ */ new Set();
86
+ if (c.forEach((s) => {
86
87
  var l;
87
- const r = Number(c.getAttribute("recommendation-id"));
88
+ const r = Number(s.getAttribute("recommendation-id"));
88
89
  if (!Number.isFinite(r))
89
90
  return;
90
91
  const u = ((l = t.blockStates[r]) == null ? void 0 : l.recommendationProducts) ?? [];
91
92
  u.length && P(
92
- o,
93
+ n,
93
94
  a,
94
95
  r,
95
96
  u,
96
- N(c),
97
- c.getAttribute("hide-price") === "true"
97
+ N(s),
98
+ s.getAttribute("hide-price") === "true"
98
99
  );
99
- }), !o.size)
100
+ }), !n.size)
100
101
  return e;
101
- let i = D(e, a);
102
- return i = i.replace(
103
- R,
104
- (c, r) => o.has(r) ? b(o.get(r)) : c
105
- ), i = z(i, o), i;
102
+ let o = I(e, a);
103
+ return o = o.replace(
104
+ T,
105
+ (s, r) => n.has(r) ? L(n.get(r)) : s
106
+ ), o = w(o, n), o;
106
107
  }
107
- const q = () => ({ substituteRecommendationPreview: I });
108
+ const q = () => ({ substituteRecommendationPreview: y });
108
109
  export {
109
- I as substituteRecommendationPreview,
110
+ y as substituteRecommendationPreview,
110
111
  q as useRecommendationPreview
111
112
  };
@@ -5,9 +5,10 @@ const s = {
5
5
  PAGE_TYPE: "data-unsubscribe-page-type",
6
6
  PAGE_LIST: "data-unsubscribe-page-list",
7
7
  BLOCK_ID: "data-unsubscribe-block-id"
8
- }, c = ".unsubscribe-block-v2";
8
+ }, c = ".unsubscribe-block-v2", u = 'a[data-unsubscribe-link="true"], a.unsubscribe-link';
9
9
  export {
10
10
  b as DATA_ATTRIBUTES,
11
11
  c as UNSUBSCRIBE_BLOCK_SELECTOR,
12
- s as UNSUBSCRIBE_EVENTS
12
+ s as UNSUBSCRIBE_EVENTS,
13
+ u as UNSUBSCRIBE_LINK_SELECTOR
13
14
  };
@@ -1,80 +1,80 @@
1
- import { TextAlignBuiltInControl as C, TextColorBuiltInControl as B, TextSizeBuiltInControl as T, TextStyleBuiltInControl as m, TextFontFamilyBuiltInControl as y, ButtonBackgroundColorBuiltInControl as a, TextPaddingsBuiltInControl as I, ImageSizeBuiltInControl as S, ImageMarginsBuiltInControl as b, ButtonAlignBuiltInControl as A, ButtonBorderBuiltInControl as k, ButtonBorderRadiusBuiltInControl as N, ButtonColorBuiltInControl as h, ButtonFontFamilyBuiltInControl as p, ButtonMarginsBuiltInControl as q, ButtonPaddingsBuiltInControl as $, ButtonTextBuiltInControl as F, ButtonTextSizeBuiltInControl as v, ButtonTextStyleAndFontColorBuiltInControl as M, ButtonFitToContainerBuiltInControl as R, TextLineSpacingBuiltInControl as _ } from "../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
2
- const O = "buttonTextStyleForm", g = "backgroundColor", f = /* @__PURE__ */ new Set(["", "transparent", "rgba(0, 0, 0, 0)"]), E = ["elementColor", g];
3
- function L(o, e, r) {
1
+ import { TextAlignBuiltInControl as C, TextColorBuiltInControl as x, TextSizeBuiltInControl as T, TextStyleBuiltInControl as B, TextFontFamilyBuiltInControl as m, ButtonBackgroundColorBuiltInControl as d, TextPaddingsBuiltInControl as y, ImageSizeBuiltInControl as b, ImageMarginsBuiltInControl as I, ButtonAlignBuiltInControl as S, ButtonBorderBuiltInControl as A, ButtonBorderRadiusBuiltInControl as k, ButtonColorBuiltInControl as N, ButtonFontFamilyBuiltInControl as h, ButtonMarginsBuiltInControl as p, ButtonPaddingsBuiltInControl as $, ButtonTextBuiltInControl as q, ButtonTextSizeBuiltInControl as F, ButtonTextStyleAndFontColorBuiltInControl as v, ButtonFitToContainerBuiltInControl as R, TextLineSpacingBuiltInControl as M } from "../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
2
+ const O = "buttonTextStyleForm", a = "backgroundColor", g = /* @__PURE__ */ new Set(["", "transparent", "rgba(0, 0, 0, 0)"]), _ = ["elementColor", a], E = /^#([0-9a-f]{3}|[0-9a-f]{6})$/i;
3
+ function P(o, n, r) {
4
4
  return class extends C {
5
5
  getId() {
6
6
  return o;
7
7
  }
8
- getTargetNodes(n) {
9
- if (!e || !r)
10
- return [n];
11
- const t = n.closest(r);
12
- return t ? t.querySelectorAll(`[esd-extension-block-id="${e}"]`) : [];
8
+ getTargetNodes(e) {
9
+ if (!n || !r)
10
+ return [e];
11
+ const t = e.closest(r);
12
+ return t ? t.querySelectorAll(`[esd-extension-block-id="${n}"]`) : [];
13
13
  }
14
14
  };
15
15
  }
16
- function P(o, e, r) {
17
- return class extends B {
16
+ function H(o, n, r) {
17
+ return class extends x {
18
18
  getId() {
19
19
  return o;
20
20
  }
21
- getTargetNodes(n) {
22
- if (!e || !r)
23
- return [n];
24
- const t = n.closest(r);
25
- return t ? t.querySelectorAll(`[esd-extension-block-id="${e}"]`) : [];
21
+ getTargetNodes(e) {
22
+ if (!n || !r)
23
+ return [e];
24
+ const t = e.closest(r);
25
+ return t ? t.querySelectorAll(`[esd-extension-block-id="${n}"]`) : [];
26
26
  }
27
27
  };
28
28
  }
29
- function U(o, e, r) {
29
+ function U(o, n, r) {
30
30
  return class extends T {
31
31
  getId() {
32
32
  return o;
33
33
  }
34
- getTargetNodes(n) {
35
- if (!e || !r)
36
- return [n];
37
- const t = n.closest(r);
38
- return t ? t.querySelectorAll(`[esd-extension-block-id="${e}"]`) : [];
34
+ getTargetNodes(e) {
35
+ if (!n || !r)
36
+ return [e];
37
+ const t = e.closest(r);
38
+ return t ? t.querySelectorAll(`[esd-extension-block-id="${n}"]`) : [];
39
39
  }
40
40
  };
41
41
  }
42
- function Y(o, e, r) {
43
- return class extends m {
42
+ function Y(o, n, r) {
43
+ return class extends B {
44
44
  getId() {
45
45
  return o;
46
46
  }
47
- getTargetNodes(n) {
48
- if (!e || !r)
49
- return [n];
50
- const t = n.closest(r);
51
- return t ? t.querySelectorAll(`[esd-extension-block-id="${e}"]`) : [];
47
+ getTargetNodes(e) {
48
+ if (!n || !r)
49
+ return [e];
50
+ const t = e.closest(r);
51
+ return t ? t.querySelectorAll(`[esd-extension-block-id="${n}"]`) : [];
52
52
  }
53
53
  };
54
54
  }
55
- function G(o, e, r) {
56
- return class extends y {
55
+ function G(o, n, r) {
56
+ return class extends m {
57
57
  getId() {
58
58
  return o;
59
59
  }
60
- getTargetNodes(n) {
61
- if (!e || !r)
62
- return [n];
63
- const t = n.closest(r);
64
- return t ? t.querySelectorAll(`[esd-extension-block-id="${e}"]`) : [];
60
+ getTargetNodes(e) {
61
+ if (!n || !r)
62
+ return [e];
63
+ const t = e.closest(r);
64
+ return t ? t.querySelectorAll(`[esd-extension-block-id="${n}"]`) : [];
65
65
  }
66
66
  };
67
67
  }
68
- function H(o, e, r) {
69
- return class extends a {
68
+ function V(o, n, r) {
69
+ return class extends d {
70
70
  getId() {
71
71
  return o;
72
72
  }
73
- getTargetNodes(n) {
74
- if (!e || !r)
75
- return [n];
76
- const t = n.closest(r);
77
- return t ? t.querySelectorAll(`[esd-extension-block-id="${e}"]`) : [];
73
+ getTargetNodes(e) {
74
+ if (!n || !r)
75
+ return [e];
76
+ const t = e.closest(r);
77
+ return t ? t.querySelectorAll(`[esd-extension-block-id="${n}"]`) : [];
78
78
  }
79
79
  /**
80
80
  * Mirrors the picked background onto each target cell as an INLINE style.
@@ -85,37 +85,37 @@ function H(o, e, r) {
85
85
  * (SD-143023). Writing the inline here keeps it the single source of truth and in
86
86
  * sync on every edit. Merged into the parent control's single patch (no extra apply).
87
87
  */
88
- getAdditionalModifications(n) {
89
- const t = this.getTargetNodes(n);
88
+ getAdditionalModifications(e) {
89
+ const t = this.getTargetNodes(e);
90
90
  if (!t.length)
91
91
  return;
92
- const s = this.api.getValues()[g], i = !s || f.has(s), l = this.api.getDocumentModifier();
92
+ const i = this.api.getValues()[a], l = !i || g.has(i), s = this.api.getDocumentModifier();
93
93
  return t.forEach((u) => {
94
- const c = l.modifyHtml(u);
95
- i ? c.removeStyle("background-color") : c.setStyle("background-color", s);
96
- }), l;
94
+ const c = s.modifyHtml(u);
95
+ l ? c.removeStyle("background-color") : c.setStyle("background-color", i);
96
+ }), s;
97
97
  }
98
98
  };
99
99
  }
100
100
  function K(o) {
101
- const e = E.find((n) => n in o);
102
- if (!e)
101
+ const n = _.find((e) => e in o);
102
+ if (!n)
103
103
  return;
104
- const r = o[e];
104
+ const r = o[n];
105
105
  return typeof r == "string" ? r : "";
106
106
  }
107
- function z(o, e) {
108
- return e.startsWith(".") && "hasClass" in o && o.hasClass(e.slice(1));
107
+ function L(o, n) {
108
+ return n.startsWith(".") && "hasClass" in o && o.hasClass(n.slice(1));
109
109
  }
110
- function d(o, e) {
110
+ function z(o, n) {
111
111
  try {
112
- return z(o, e) ? o : o.closest(e) ?? void 0;
112
+ return L(o, n) ? o : o.closest(n) ?? void 0;
113
113
  } catch {
114
114
  return;
115
115
  }
116
116
  }
117
- function V(o, e) {
118
- return class extends a {
117
+ function w(o, n) {
118
+ return class extends d {
119
119
  getId() {
120
120
  return o;
121
121
  }
@@ -123,9 +123,10 @@ function V(o, e) {
123
123
  getLabels() {
124
124
  return { title: this.api.translate("Block Background Color") };
125
125
  }
126
+ /** Guard: redirect the borrowed button parent onto the block `<td>` so it never paints the Buy buttons. */
126
127
  getTargetNodes(r) {
127
- const n = d(r, e);
128
- return n ? [n] : [];
128
+ const e = z(r, n);
129
+ return e ? [e] : [];
129
130
  }
130
131
  /**
131
132
  * Writes the picked background onto the block as an inline style plus a `bgcolor`
@@ -134,147 +135,147 @@ function V(o, e) {
134
135
  * channel Outlook honours on a `<td>`, and matches what the migrator emits.
135
136
  */
136
137
  getAdditionalModifications(r) {
137
- const n = d(r, e);
138
- if (!n)
138
+ const [e] = this.getTargetNodes(r);
139
+ if (!e)
139
140
  return;
140
141
  const t = K(this.api.getValues());
141
142
  if (t === void 0)
142
143
  return;
143
- const s = !t || f.has(t), i = this.api.getDocumentModifier(), l = i.modifyHtml(n);
144
- return s ? l.removeStyle("background-color").removeAttribute("bgcolor") : l.setStyle("background-color", t).setAttribute("bgcolor", t), i;
144
+ const i = !t || g.has(t), l = this.api.getDocumentModifier(), s = l.modifyHtml(e);
145
+ return i ? s.removeStyle("background-color").removeAttribute("bgcolor") : (s.setStyle("background-color", t), E.test(t) ? s.setAttribute("bgcolor", t) : s.removeAttribute("bgcolor")), l;
145
146
  }
146
147
  };
147
148
  }
148
- function w(o, e, r) {
149
- return class extends I {
149
+ function W(o, n, r) {
150
+ return class extends y {
150
151
  getId() {
151
152
  return o;
152
153
  }
153
- getTargetNodes(n) {
154
- if (!e || !r)
155
- return [n];
156
- const t = n.closest(r);
157
- return t ? t.querySelectorAll(`[esd-extension-block-id="${e}"]`) : [];
154
+ getTargetNodes(e) {
155
+ if (!n || !r)
156
+ return [e];
157
+ const t = e.closest(r);
158
+ return t ? t.querySelectorAll(`[esd-extension-block-id="${n}"]`) : [];
158
159
  }
159
160
  };
160
161
  }
161
- function W(o, e, r) {
162
- return class extends _ {
162
+ function X(o, n, r) {
163
+ return class extends M {
163
164
  getId() {
164
165
  return o;
165
166
  }
166
- getTargetNodes(n) {
167
- return [n];
167
+ getTargetNodes(e) {
168
+ return [e];
168
169
  }
169
170
  };
170
171
  }
171
- function X(o, e, r = ".ins-recommendation-product-container") {
172
- return class extends A {
172
+ function j(o, n, r = ".ins-recommendation-product-container") {
173
+ return class extends S {
173
174
  getId() {
174
175
  return o;
175
176
  }
176
- getTargetNodes(n) {
177
- const t = n.closest(r);
178
- return t ? t.querySelectorAll(`[esd-extension-block-id="${e}"]`) : [];
177
+ getTargetNodes(e) {
178
+ const t = e.closest(r);
179
+ return t ? t.querySelectorAll(`[esd-extension-block-id="${n}"]`) : [];
179
180
  }
180
181
  };
181
182
  }
182
- function j(o, e, r = ".ins-recommendation-product-container") {
183
- return class extends h {
183
+ function J(o, n, r = ".ins-recommendation-product-container") {
184
+ return class extends N {
184
185
  getId() {
185
186
  return o;
186
187
  }
187
- getTargetNodes(n) {
188
- const t = n.closest(r);
189
- return t ? t.querySelectorAll(`[esd-extension-block-id="${e}"]`) : [];
188
+ getTargetNodes(e) {
189
+ const t = e.closest(r);
190
+ return t ? t.querySelectorAll(`[esd-extension-block-id="${n}"]`) : [];
190
191
  }
191
192
  };
192
193
  }
193
- function J(o, e, r = ".ins-recommendation-product-container") {
194
- return class extends k {
194
+ function Q(o, n, r = ".ins-recommendation-product-container") {
195
+ return class extends A {
195
196
  getId() {
196
197
  return o;
197
198
  }
198
- getTargetNodes(n) {
199
- const t = n.closest(r);
200
- return t ? t.querySelectorAll(`[esd-extension-block-id="${e}"]`) : [];
199
+ getTargetNodes(e) {
200
+ const t = e.closest(r);
201
+ return t ? t.querySelectorAll(`[esd-extension-block-id="${n}"]`) : [];
201
202
  }
202
203
  };
203
204
  }
204
- function Q(o, e, r = ".ins-recommendation-product-container") {
205
- return class extends N {
205
+ function Z(o, n, r = ".ins-recommendation-product-container") {
206
+ return class extends k {
206
207
  getId() {
207
208
  return o;
208
209
  }
209
- getTargetNodes(n) {
210
- const t = n.closest(r);
211
- return t ? t.querySelectorAll(`[esd-extension-block-id="${e}"]`) : [];
210
+ getTargetNodes(e) {
211
+ const t = e.closest(r);
212
+ return t ? t.querySelectorAll(`[esd-extension-block-id="${n}"]`) : [];
212
213
  }
213
214
  };
214
215
  }
215
- function Z(o, e, r = ".ins-recommendation-product-container") {
216
- return class extends p {
216
+ function tt(o, n, r = ".ins-recommendation-product-container") {
217
+ return class extends h {
217
218
  getId() {
218
219
  return o;
219
220
  }
220
- getTargetNodes(n) {
221
- const t = n.closest(r);
222
- return t ? t.querySelectorAll(`[esd-extension-block-id="${e}"]`) : [];
221
+ getTargetNodes(e) {
222
+ const t = e.closest(r);
223
+ return t ? t.querySelectorAll(`[esd-extension-block-id="${n}"]`) : [];
223
224
  }
224
225
  };
225
226
  }
226
- function tt(o, e, r = ".ins-recommendation-product-container") {
227
- return class extends q {
227
+ function et(o, n, r = ".ins-recommendation-product-container") {
228
+ return class extends p {
228
229
  getId() {
229
230
  return o;
230
231
  }
231
- getTargetNodes(n) {
232
- const t = n.closest(r);
233
- return t ? t.querySelectorAll(`[esd-extension-block-id="${e}"]`) : [];
232
+ getTargetNodes(e) {
233
+ const t = e.closest(r);
234
+ return t ? t.querySelectorAll(`[esd-extension-block-id="${n}"]`) : [];
234
235
  }
235
236
  };
236
237
  }
237
- function et(o, e, r = ".ins-recommendation-product-container") {
238
+ function nt(o, n, r = ".ins-recommendation-product-container") {
238
239
  return class extends $ {
239
240
  getId() {
240
241
  return o;
241
242
  }
242
- getTargetNodes(n) {
243
- const t = n.closest(r);
244
- return t ? t.querySelectorAll(`[esd-extension-block-id="${e}"]`) : [];
243
+ getTargetNodes(e) {
244
+ const t = e.closest(r);
245
+ return t ? t.querySelectorAll(`[esd-extension-block-id="${n}"]`) : [];
245
246
  }
246
247
  };
247
248
  }
248
- function nt(o, e, r = ".ins-recommendation-product-container") {
249
- return class extends F {
249
+ function rt(o, n, r = ".ins-recommendation-product-container") {
250
+ return class extends q {
250
251
  getId() {
251
252
  return o;
252
253
  }
253
- getTargetNodes(n) {
254
- const t = n.closest(r);
255
- return t ? t.querySelectorAll(`[esd-extension-block-id="${e}"]`) : [];
254
+ getTargetNodes(e) {
255
+ const t = e.closest(r);
256
+ return t ? t.querySelectorAll(`[esd-extension-block-id="${n}"]`) : [];
256
257
  }
257
258
  };
258
259
  }
259
- function rt(o, e, r = ".ins-recommendation-product-container") {
260
- return class extends v {
260
+ function ot(o, n, r = ".ins-recommendation-product-container") {
261
+ return class extends F {
261
262
  getId() {
262
263
  return o;
263
264
  }
264
- getTargetNodes(n) {
265
- const t = n.closest(r);
266
- return t ? t.querySelectorAll(`[esd-extension-block-id="${e}"]`) : [];
265
+ getTargetNodes(e) {
266
+ const t = e.closest(r);
267
+ return t ? t.querySelectorAll(`[esd-extension-block-id="${n}"]`) : [];
267
268
  }
268
269
  };
269
270
  }
270
- function ot(o, e, r) {
271
- return class extends M {
271
+ function st(o, n, r) {
272
+ return class extends v {
272
273
  getId() {
273
274
  return o;
274
275
  }
275
- getTargetNodes(n) {
276
- const t = n.closest(r);
277
- return t ? t.querySelectorAll(`[esd-extension-block-id="${e}"]`) : [];
276
+ getTargetNodes(e) {
277
+ const t = e.closest(r);
278
+ return t ? t.querySelectorAll(`[esd-extension-block-id="${n}"]`) : [];
278
279
  }
279
280
  /**
280
281
  * Propagates Bold/Italic to ALL product buttons, not just the focused one.
@@ -286,58 +287,58 @@ function ot(o, e, r) {
286
287
  * (`buttonTextStyleForm.{bold,italic}`) because the patched node isn't updated yet
287
288
  * when this runs. Returned modifications are merged into the parent control's patch.
288
289
  */
289
- getAdditionalModifications(n) {
290
- const t = n.closest(r);
290
+ getAdditionalModifications(e) {
291
+ const t = e.closest(r);
291
292
  if (!t)
292
293
  return;
293
- const s = t.querySelectorAll(`[esd-extension-block-id="${e}"] a.es-button`);
294
- if (!s.length)
294
+ const i = t.querySelectorAll(`[esd-extension-block-id="${n}"] a.es-button`);
295
+ if (!i.length)
295
296
  return;
296
- const i = this.api.getValues()[O];
297
- if (!i)
297
+ const l = this.api.getValues()[O];
298
+ if (!l)
298
299
  return;
299
- const l = i.bold ? "bold" : "normal", u = i.italic ? "italic" : "normal", c = this.api.getDocumentModifier();
300
- return s.forEach((x) => {
301
- c.modifyHtml(x).setStyle("font-weight", l).setStyle("font-style", u);
300
+ const s = l.bold ? "bold" : "normal", u = l.italic ? "italic" : "normal", c = this.api.getDocumentModifier();
301
+ return i.forEach((f) => {
302
+ c.modifyHtml(f).setStyle("font-weight", s).setStyle("font-style", u);
302
303
  }), c;
303
304
  }
304
305
  };
305
306
  }
306
- function st(o, e, r) {
307
+ function it(o, n, r) {
307
308
  return class extends R {
308
309
  getId() {
309
310
  return o;
310
311
  }
311
- getTargetNodes(n) {
312
- const t = n.closest(r);
313
- return t ? t.querySelectorAll(`[esd-extension-block-id="${e}"]`) : [];
312
+ getTargetNodes(e) {
313
+ const t = e.closest(r);
314
+ return t ? t.querySelectorAll(`[esd-extension-block-id="${n}"]`) : [];
314
315
  }
315
316
  };
316
317
  }
317
- function it(o, e, r) {
318
- return class extends S {
318
+ function lt(o, n, r) {
319
+ return class extends b {
319
320
  getId() {
320
321
  return o;
321
322
  }
322
- getTargetNodes(n) {
323
+ getTargetNodes(e) {
323
324
  try {
324
- const t = n.closest(r);
325
- return t ? t.querySelectorAll(`[esd-extension-block-id="${e}"]`) : [];
325
+ const t = e.closest(r);
326
+ return t ? t.querySelectorAll(`[esd-extension-block-id="${n}"]`) : [];
326
327
  } catch {
327
328
  return [];
328
329
  }
329
330
  }
330
331
  };
331
332
  }
332
- function lt(o, e, r) {
333
- return class extends b {
333
+ function ct(o, n, r) {
334
+ return class extends I {
334
335
  getId() {
335
336
  return o;
336
337
  }
337
- getTargetNodes(n) {
338
+ getTargetNodes(e) {
338
339
  try {
339
- const t = n.closest(r);
340
- return t ? t.querySelectorAll(`[esd-extension-block-id="${e}"]`) : [];
340
+ const t = e.closest(r);
341
+ return t ? t.querySelectorAll(`[esd-extension-block-id="${n}"]`) : [];
341
342
  } catch {
342
343
  return [];
343
344
  }
@@ -345,26 +346,26 @@ function lt(o, e, r) {
345
346
  };
346
347
  }
347
348
  export {
348
- V as createBlockBackgroundColorControl,
349
- X as createButtonAlignControl,
350
- J as createButtonBorderControl,
351
- Q as createButtonBorderRadiusControl,
352
- j as createButtonColorControl,
353
- st as createButtonFitToContainerControl,
354
- Z as createButtonFontFamilyControl,
355
- tt as createButtonMarginsControl,
356
- et as createButtonPaddingsControl,
357
- nt as createButtonTextControl,
358
- rt as createButtonTextSizeControl,
359
- ot as createButtonTextStyleAndFontColorControl,
360
- lt as createImageMarginsControl,
361
- it as createImageSizeControl,
362
- w as createPaddingsControl,
363
- L as createTextAlignControl,
364
- H as createTextBackgroundColorControl,
365
- P as createTextColorControl,
349
+ w as createBlockBackgroundColorControl,
350
+ j as createButtonAlignControl,
351
+ Q as createButtonBorderControl,
352
+ Z as createButtonBorderRadiusControl,
353
+ J as createButtonColorControl,
354
+ it as createButtonFitToContainerControl,
355
+ tt as createButtonFontFamilyControl,
356
+ et as createButtonMarginsControl,
357
+ nt as createButtonPaddingsControl,
358
+ rt as createButtonTextControl,
359
+ ot as createButtonTextSizeControl,
360
+ st as createButtonTextStyleAndFontColorControl,
361
+ ct as createImageMarginsControl,
362
+ lt as createImageSizeControl,
363
+ W as createPaddingsControl,
364
+ P as createTextAlignControl,
365
+ V as createTextBackgroundColorControl,
366
+ H as createTextColorControl,
366
367
  G as createTextFontFamilyControl,
367
- W as createTextLineSpacingControl,
368
+ X as createTextLineSpacingControl,
368
369
  U as createTextSizeControl,
369
370
  Y as createTextStyleControl
370
371
  };
package/dist/guido.css CHANGED
@@ -1 +1 @@
1
- .gap-16[data-v-5553d071],.gap-16[data-v-0e1b0c54]{gap:16px}[data-v-73199fa4] .in-button-v2__wrapper{line-height:0}[data-v-22226124] .in-segments-wrapper__button_selected,[data-v-22226124] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb;color:#0010ac;border-color:#0010ac}[data-v-2cb418af] .in-progress-wrapper__progress p span:last-child{display:none!important}[data-v-2cb418af] .in-progress-description-status{display:none!important}.view-options-wrapper[data-v-195ab6d4]{position:relative;display:inline-block}.new-tag[data-v-195ab6d4]{position:absolute;top:-8px;right:-16px;z-index:10}[data-v-195ab6d4] .guido__view-option-selection-desktop svg,[data-v-195ab6d4] .guido__view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-195ab6d4] .in-segments-wrapper__button_selected,[data-v-195ab6d4] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}[data-v-195ab6d4] .in-tooltip-wrapper__icon{cursor:pointer}.editor-toolbar[data-v-173c3a40]{gap:4px}.version-history-item[data-v-ee4b9c3f]{flex-basis:200px}.version-history[data-v-fad98586]{gap:8px}.version-history__toolbar[data-v-fad98586]{gap:4px}.view-options-wrapper[data-v-d405ca59]{position:relative;display:inline-block}.new-tag[data-v-d405ca59]{position:absolute;top:-8px;right:-16px;z-index:10}[data-v-d405ca59] .guido__verion-history-view-option-selection-desktop svg,[data-v-d405ca59] .guido__verion-history-view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-d405ca59] .in-segments-wrapper__button_selected,[data-v-d405ca59] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}[data-v-d405ca59] .in-tooltip-wrapper__icon{cursor:pointer}.auto-save-toggle[data-v-2c964af4]{position:relative}.auto-save-toggle__info-box[data-v-2c964af4]{position:absolute;top:100%;left:0;z-index:10;width:280px}.editor-actions[data-v-6e711fd7]{gap:4px}.header-wrapper[data-v-d11dd577]{min-width:1000px}.guido-loading__wrapper[data-v-07c4b2d8]{height:100%;top:75px!important;bottom:0!important}.guido-editor__wrapper[data-v-50dac6de]{--ribbon-offset: 0px;position:relative;width:100%;height:calc(100vh - 128px - var(--ribbon-offset))}.guido-editor__container[data-v-50dac6de]{width:100%;height:calc(100vh - 128px - var(--ribbon-offset))}.guido-editor__no-header[data-v-50dac6de]{height:calc(100vh - 75px - var(--ribbon-offset))}[data-v-293f1c47] .in-breadcrumb-wrapper__links{cursor:pointer}.templates-wrapper[data-v-91a26acd]{gap:16px;grid-template-columns:repeat(3,1fr)}.templates-wrapper .template-wrapper[data-v-91a26acd]{cursor:pointer}.templates-wrapper .template-wrapper .template-container[data-v-91a26acd]{height:274px;padding:2px;transition:none}.templates-wrapper .template-wrapper .template-container.selected[data-v-91a26acd]{padding:1px}.templates-wrapper .template-wrapper .template-container .thumbnail[data-v-91a26acd]{object-fit:cover;transform:scale(1)}[data-v-b9a93c6e] .guido__verion-history-view-option-selection-desktop svg,[data-v-b9a93c6e] .guido__verion-history-view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-b9a93c6e] .in-segments-wrapper__button_selected,[data-v-b9a93c6e] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}.error-list[data-v-c3fd5d4b]{gap:16px}.desktop-browser-header[data-v-d86c5af5]{height:79px;min-height:79px}.desktop-browser-header__left[data-v-d86c5af5]{-webkit-user-drag:none;height:79px;width:378px}.desktop-browser-header__center[data-v-d86c5af5]{height:79px;background-repeat:repeat-x;background-size:auto 100%;background-position:left top}.desktop-browser-header__right[data-v-d86c5af5]{-webkit-user-drag:none;height:79px;width:112px}.desktop-preview[data-v-06afaecb]{min-width:602px;height:70vh;min-height:583px;border-radius:10px}.desktop-preview iframe[data-v-06afaecb]{min-height:504px}.iframe-wrapper[data-v-cbafc185]{width:258px}.iframe-scaled[data-v-cbafc185]{width:320px;height:124.0310077519%;transform:scale(.80625);transform-origin:top left}.cropped-text[data-v-eb3d05d7]{width:220px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.mobile-preview-wrapper__phone[data-v-3f472f96]{width:282px}.mobile-preview-wrapper__phone img[data-v-3f472f96]{object-fit:cover;border-radius:44px}.mobile-preview-wrapper__content[data-v-3f472f96]{width:258px;height:450px;left:12px}[data-v-6bcaca8a] .vueperslides__parallax-wrapper{padding-bottom:110px!important}[data-v-f16f20f8] .vueperslides__bullets{pointer-events:none!important}[data-v-f16f20f8] .vueperslides__parallax-wrapper{padding-bottom:110px!important}[data-v-bb3cca55] .vueperslides__bullets{pointer-events:none!important}[data-v-bb3cca55] .vueperslides__parallax-wrapper{height:110px!important;padding-bottom:110px!important}[data-v-b09e80c4] .vueperslides__bullets{pointer-events:none!important}[data-v-b09e80c4] .vueperslides__parallax-wrapper{height:110px!important;padding-bottom:110px!important}[data-v-9bdef600] .vueperslides__parallax-wrapper{padding-bottom:110px!important}
1
+ .gap-16[data-v-5553d071],.gap-16[data-v-0e1b0c54]{gap:16px}[data-v-73199fa4] .in-button-v2__wrapper{line-height:0}[data-v-22226124] .in-segments-wrapper__button_selected,[data-v-22226124] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb;color:#0010ac;border-color:#0010ac}[data-v-2cb418af] .in-progress-wrapper__progress p span:last-child{display:none!important}[data-v-2cb418af] .in-progress-description-status{display:none!important}.view-options-wrapper[data-v-195ab6d4]{position:relative;display:inline-block}.new-tag[data-v-195ab6d4]{position:absolute;top:-8px;right:-16px;z-index:10}[data-v-195ab6d4] .guido__view-option-selection-desktop svg,[data-v-195ab6d4] .guido__view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-195ab6d4] .in-segments-wrapper__button_selected,[data-v-195ab6d4] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}[data-v-195ab6d4] .in-tooltip-wrapper__icon{cursor:pointer}.editor-toolbar[data-v-173c3a40]{gap:4px}.version-history-item[data-v-ee4b9c3f]{flex-basis:200px}.version-history[data-v-fad98586]{gap:8px}.version-history__toolbar[data-v-fad98586]{gap:4px}.view-options-wrapper[data-v-d405ca59]{position:relative;display:inline-block}.new-tag[data-v-d405ca59]{position:absolute;top:-8px;right:-16px;z-index:10}[data-v-d405ca59] .guido__verion-history-view-option-selection-desktop svg,[data-v-d405ca59] .guido__verion-history-view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-d405ca59] .in-segments-wrapper__button_selected,[data-v-d405ca59] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}[data-v-d405ca59] .in-tooltip-wrapper__icon{cursor:pointer}.auto-save-toggle[data-v-2c964af4]{position:relative}.auto-save-toggle__info-box[data-v-2c964af4]{position:absolute;top:100%;left:0;z-index:10;width:280px}.editor-actions[data-v-6e711fd7]{gap:4px}.header-wrapper[data-v-d11dd577]{min-width:1000px}.guido-loading__wrapper[data-v-07c4b2d8]{height:100%;top:75px!important;bottom:0!important}.guido-editor__wrapper[data-v-50dac6de]{--ribbon-offset: 0px;position:relative;width:100%;height:calc(100vh - 128px - var(--ribbon-offset))}.guido-editor__container[data-v-50dac6de]{width:100%;height:calc(100vh - 128px - var(--ribbon-offset))}.guido-editor__no-header[data-v-50dac6de]{height:calc(100vh - 75px - var(--ribbon-offset))}[data-v-293f1c47] .in-breadcrumb-wrapper__links{cursor:pointer}.templates-wrapper[data-v-91a26acd]{gap:16px;grid-template-columns:repeat(3,1fr)}.templates-wrapper .template-wrapper[data-v-91a26acd]{cursor:pointer}.templates-wrapper .template-wrapper .template-container[data-v-91a26acd]{height:274px;padding:2px;transition:none}.templates-wrapper .template-wrapper .template-container.selected[data-v-91a26acd]{padding:1px}.templates-wrapper .template-wrapper .template-container .thumbnail[data-v-91a26acd]{object-fit:cover;transform:scale(1)}[data-v-b9a93c6e] .guido__verion-history-view-option-selection-desktop svg,[data-v-b9a93c6e] .guido__verion-history-view-option-selection-mobile svg{margin:0 0 0 2px}[data-v-b9a93c6e] .in-segments-wrapper__button_selected,[data-v-b9a93c6e] .in-segments-wrapper__button_selected:hover{background-color:#dae1fb}.error-list[data-v-c3fd5d4b]{gap:16px}.desktop-browser-header[data-v-d86c5af5]{height:79px;min-height:79px}.desktop-browser-header__left[data-v-d86c5af5]{-webkit-user-drag:none;height:79px;width:378px}.desktop-browser-header__center[data-v-d86c5af5]{height:79px;background-repeat:repeat-x;background-size:auto 100%;background-position:left top}.desktop-browser-header__right[data-v-d86c5af5]{-webkit-user-drag:none;height:79px;width:112px}.desktop-preview[data-v-cf946232]{min-width:602px;height:70vh;min-height:583px;border-radius:10px}.desktop-preview iframe[data-v-cf946232]{min-height:504px}.iframe-wrapper[data-v-f255b2bb]{width:258px}.iframe-scaled[data-v-f255b2bb]{width:320px;height:124.0310077519%;transform:scale(.80625);transform-origin:top left}.cropped-text[data-v-eb3d05d7]{width:220px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.mobile-preview-wrapper__phone[data-v-3f472f96]{width:282px}.mobile-preview-wrapper__phone img[data-v-3f472f96]{object-fit:cover;border-radius:44px}.mobile-preview-wrapper__content[data-v-3f472f96]{width:258px;height:450px;left:12px}[data-v-6bcaca8a] .vueperslides__parallax-wrapper{padding-bottom:110px!important}[data-v-f16f20f8] .vueperslides__bullets{pointer-events:none!important}[data-v-f16f20f8] .vueperslides__parallax-wrapper{padding-bottom:110px!important}[data-v-bb3cca55] .vueperslides__bullets{pointer-events:none!important}[data-v-bb3cca55] .vueperslides__parallax-wrapper{height:110px!important;padding-bottom:110px!important}[data-v-b09e80c4] .vueperslides__bullets{pointer-events:none!important}[data-v-b09e80c4] .vueperslides__parallax-wrapper{height:110px!important;padding-bottom:110px!important}[data-v-9bdef600] .vueperslides__parallax-wrapper{padding-bottom:110px!important}
@@ -1,3 +1,3 @@
1
1
  export declare const usePreviewInteractionGuard: () => {
2
- blockPreviewInteractions: (iframe: HTMLIFrameElement) => void;
2
+ guardPreviewInteractions: (iframe: HTMLIFrameElement) => void;
3
3
  };
@@ -9,3 +9,4 @@ export declare const DATA_ATTRIBUTES: {
9
9
  readonly BLOCK_ID: "data-unsubscribe-block-id";
10
10
  };
11
11
  export declare const UNSUBSCRIBE_BLOCK_SELECTOR = ".unsubscribe-block-v2";
12
+ export declare const UNSUBSCRIBE_LINK_SELECTOR = "a[data-unsubscribe-link=\"true\"], a.unsubscribe-link";
@@ -116,12 +116,18 @@ export declare function createTextBackgroundColorControl(controlId: string, targ
116
116
  };
117
117
  };
118
118
  /**
119
- * Factory function to create a background color control for a whole extension block.
119
+ * Factory for a background-color control that paints a whole extension block (SD-145082).
120
120
  *
121
- * Stripo's built-in block-background control resolves its own target and descends to the
122
- * nearest `.esd-block-text`, which inside a Recommendation block is the title cell rather
123
- * than the block itself (SD-145082). Overriding `getTargetNodes` moves that resolution here
124
- * so the color lands on the block `<td>` only inner text blocks keep their own controls.
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.
125
131
  */
126
132
  export declare function createBlockBackgroundColorControl(controlId: string, blockRootSelector?: string): {
127
133
  new (): {
@@ -130,6 +136,7 @@ export declare function createBlockBackgroundColorControl(controlId: string, blo
130
136
  getLabels(): {
131
137
  title: string;
132
138
  };
139
+ /** Guard: redirect the borrowed button parent onto the block `<td>` so it never paints the Buy buttons. */
133
140
  getTargetNodes(root: ImmutableHtmlNode): ImmutableHtmlNode[];
134
141
  /**
135
142
  * Writes the picked background onto the block as an inline style plus a `bgcolor`
@@ -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[];
@@ -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-beta.b9402d1",
3
+ "version": "3.12.0-beta.bec0e55",
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",