@useinsider/guido 3.20.2-beta.87fb8ae → 3.21.0-beta.1bd7edd

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/README.md +1 -0
  2. package/dist/@types/config/schemas.js +41 -39
  3. package/dist/@types/display-condition.js +25 -0
  4. package/dist/components/Guido.vue.js +6 -6
  5. package/dist/components/Guido.vue2.js +86 -83
  6. package/dist/components/organisms/AutoSaveController.vue2.js +10 -9
  7. package/dist/components/organisms/display-conditions/CodeEditorField.vue.js +20 -0
  8. package/dist/components/organisms/display-conditions/CodeEditorField.vue2.js +30 -0
  9. package/dist/components/organisms/display-conditions/DisplayConditionCreateDrawer.vue.js +30 -0
  10. package/dist/components/organisms/display-conditions/DisplayConditionCreateDrawer.vue2.js +71 -0
  11. package/dist/components/organisms/display-conditions/DisplayConditionSelectDrawer.vue.js +34 -0
  12. package/dist/components/organisms/display-conditions/DisplayConditionSelectDrawer.vue2.js +57 -0
  13. package/dist/components/organisms/display-conditions/DisplayConditionsHost.vue.js +17 -0
  14. package/dist/components/organisms/display-conditions/DisplayConditionsHost.vue2.js +22 -0
  15. package/dist/components/organisms/header/EditorActions.vue.js +4 -4
  16. package/dist/components/organisms/header/EditorActions.vue2.js +53 -51
  17. package/dist/components/organisms/validation/ValidationErrorDrawer.vue.js +3 -3
  18. package/dist/components/organisms/validation/ValidationErrorDrawer.vue2.js +23 -22
  19. package/dist/composables/useAutoSave.js +46 -44
  20. package/dist/composables/useBlocksConfig.js +32 -24
  21. package/dist/composables/useDisplayConditions.js +102 -0
  22. package/dist/composables/useSave.js +26 -23
  23. package/dist/composables/useSaveValidation.js +113 -114
  24. package/dist/composables/useSaveValidationRollout.js +17 -6
  25. package/dist/composables/useStripo.js +4 -3
  26. package/dist/enums/academy.js +1 -0
  27. package/dist/enums/display-condition.js +12 -0
  28. package/dist/extensions/Blocks/Items/block.js +43 -42
  29. package/dist/extensions/Blocks/Recommendation/store/recommendation.js +9 -5
  30. package/dist/extensions/Blocks/Unsubscribe/block.js +70 -75
  31. package/dist/extensions/DisplayConditions/bridge.js +17 -0
  32. package/dist/extensions/DisplayConditions/constants.js +17 -0
  33. package/dist/extensions/DisplayConditions/control.js +178 -0
  34. package/dist/extensions/DisplayConditions/display-conditions.css.js +201 -0
  35. package/dist/extensions/DisplayConditions/extension.js +28 -0
  36. package/dist/extensions/DisplayConditions/iconsRegistry.js +20 -0
  37. package/dist/extensions/DisplayConditions/library.js +27 -0
  38. package/dist/extensions/DisplayConditions/settingsPanel.js +17 -0
  39. package/dist/guido.css +1 -1
  40. package/dist/node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js +272 -192
  41. package/dist/node_modules/valibot/dist/index.js +297 -261
  42. package/dist/package.json.js +1 -1
  43. package/dist/services/displayConditionApi.js +39 -0
  44. package/dist/services/settingsApi.js +11 -0
  45. package/dist/src/@types/config/schemas.d.ts +4 -0
  46. package/dist/src/@types/display-condition.d.ts +59 -0
  47. package/dist/src/components/Guido.vue.d.ts +1 -1
  48. package/dist/src/components/organisms/display-conditions/CodeEditorField.vue.d.ts +43 -0
  49. package/dist/src/components/organisms/display-conditions/DisplayConditionCreateDrawer.vue.d.ts +2 -0
  50. package/dist/src/components/organisms/display-conditions/DisplayConditionSelectDrawer.vue.d.ts +2 -0
  51. package/dist/src/components/organisms/display-conditions/DisplayConditionsHost.vue.d.ts +2 -0
  52. package/dist/src/components/organisms/header/EditorActions.vue.d.ts +1 -1
  53. package/dist/src/components/organisms/header/HeaderWrapper.vue.d.ts +1 -1
  54. package/dist/src/components/organisms/header/RightSlot.vue.d.ts +1 -1
  55. package/dist/src/composables/useAutoSave.d.ts +4 -1
  56. package/dist/src/composables/useConfig.d.ts +2 -0
  57. package/dist/src/composables/useDisplayConditions.d.ts +16 -0
  58. package/dist/src/composables/useSaveValidationRollout.d.ts +1 -0
  59. package/dist/src/enums/academy.d.ts +1 -0
  60. package/dist/src/enums/display-condition.d.ts +15 -0
  61. package/dist/src/extensions/Blocks/Checkbox/controls/blockBackground/index.d.ts +1 -0
  62. package/dist/src/extensions/Blocks/CouponBlock/controls/index.d.ts +8 -0
  63. package/dist/src/extensions/Blocks/Items/controls/index.d.ts +40 -0
  64. package/dist/src/extensions/Blocks/RadioButton/controls/blockBackground/index.d.ts +1 -0
  65. package/dist/src/extensions/Blocks/Recommendation/controls/blockBackground/index.d.ts +1 -0
  66. package/dist/src/extensions/Blocks/Recommendation/controls/button/index.d.ts +11 -0
  67. package/dist/src/extensions/Blocks/Recommendation/controls/customAttribute/index.d.ts +7 -0
  68. package/dist/src/extensions/Blocks/Recommendation/controls/image/index.d.ts +2 -0
  69. package/dist/src/extensions/Blocks/Recommendation/controls/name/index.d.ts +7 -0
  70. package/dist/src/extensions/Blocks/Recommendation/controls/oldPrice/index.d.ts +7 -0
  71. package/dist/src/extensions/Blocks/Recommendation/controls/omnibusDiscount/index.d.ts +7 -0
  72. package/dist/src/extensions/Blocks/Recommendation/controls/omnibusPrice/index.d.ts +7 -0
  73. package/dist/src/extensions/Blocks/Recommendation/controls/price/index.d.ts +7 -0
  74. package/dist/src/extensions/Blocks/Recommendation/controls/title/index.d.ts +7 -0
  75. package/dist/src/extensions/Blocks/Recommendation/store/recommendation.d.ts +1 -0
  76. package/dist/src/extensions/Blocks/Unsubscribe/block.d.ts +1 -6
  77. package/dist/src/extensions/Blocks/_Boilerplate/controls/blockBackground/index.d.ts +1 -0
  78. package/dist/src/extensions/Blocks/controlFactories.d.ts +22 -0
  79. package/dist/src/extensions/DisplayConditions/bridge.d.ts +6 -0
  80. package/dist/src/extensions/DisplayConditions/constants.d.ts +14 -0
  81. package/dist/src/extensions/DisplayConditions/control.d.ts +23 -0
  82. package/dist/src/extensions/DisplayConditions/extension.d.ts +2 -0
  83. package/dist/src/extensions/DisplayConditions/iconsRegistry.d.ts +4 -0
  84. package/dist/src/extensions/DisplayConditions/library.d.ts +8 -0
  85. package/dist/src/extensions/DisplayConditions/settingsPanel.d.ts +5 -0
  86. package/dist/src/mock/api/display-conditions.d.ts +2 -0
  87. package/dist/src/services/displayConditionApi.d.ts +8 -0
  88. package/dist/src/services/settingsApi.d.ts +6 -0
  89. package/dist/src/stores/config.d.ts +166 -0
  90. package/dist/src/stores/display-condition.d.ts +81 -0
  91. package/dist/src/stores/setup-settings.d.ts +4 -0
  92. package/dist/src/utils/displayCondition.d.ts +10 -0
  93. package/dist/src/utils/protectTableText.d.ts +2 -0
  94. package/dist/static/styles/components/button.css.js +5 -0
  95. package/dist/stores/config.js +13 -6
  96. package/dist/stores/display-condition.js +28 -0
  97. package/dist/stores/setup-settings.js +10 -0
  98. package/dist/utils/displayCondition.js +26 -0
  99. package/dist/utils/pairProductVariables.js +15 -14
  100. package/dist/utils/protectTableText.js +22 -0
  101. package/package.json +4 -4
@@ -25,6 +25,9 @@ function W(t) {
25
25
  return e && e.token === u.get(t) ? e.outcome : !1;
26
26
  }
27
27
  let l = null;
28
+ const X = () => {
29
+ l == null || l();
30
+ };
28
31
  function D() {
29
32
  return {
30
33
  cardsInRow: x,
@@ -80,7 +83,7 @@ function G() {
80
83
  adoptedSizeVersion: 0
81
84
  };
82
85
  }
83
- const X = () => ({
86
+ const Y = () => ({
84
87
  recommendationCampaignUrls: {},
85
88
  activePredictiveAlgorithms: [],
86
89
  languages: {},
@@ -95,8 +98,8 @@ const X = () => ({
95
98
  currentRecommendationId: null,
96
99
  strategyPanelOpen: !1,
97
100
  configVersion: 0
98
- }), ht = V("guidoRecommendationExtension", {
99
- state: () => X(),
101
+ }), St = V("guidoRecommendationExtension", {
102
+ state: () => Y(),
100
103
  getters: {
101
104
  // ====================================================================
102
105
  // Proxy Getters — Backward Compatible Access to Current Block State
@@ -472,7 +475,7 @@ const X = () => ({
472
475
  },
473
476
  /** Lets the editor tear the return listeners down when it unmounts. */
474
477
  disposeStrategyPageReturn() {
475
- l == null || l();
478
+ X();
476
479
  },
477
480
  /**
478
481
  * Opens Smart Recommender's strategy creation page. Every return refreshes the list so the
@@ -805,5 +808,6 @@ const X = () => ({
805
808
  }
806
809
  });
807
810
  export {
808
- ht as useRecommendationExtensionStore
811
+ X as disposeStrategyPageReturnListeners,
812
+ St as useRecommendationExtensionStore
809
813
  };
@@ -1,42 +1,48 @@
1
- var S = Object.defineProperty;
2
- var f = (c, o, e) => o in c ? S(c, o, { enumerable: !0, configurable: !0, writable: !0, value: e }) : c[o] = e;
3
- var a = (c, o, e) => f(c, typeof o != "symbol" ? o + "" : o, e);
1
+ var y = Object.defineProperty;
2
+ var I = (c, o, e) => o in c ? y(c, o, { enumerable: !0, configurable: !0, writable: !0, value: e }) : c[o] = e;
3
+ var g = (c, o, e) => I(c, typeof o != "symbol" ? o + "" : o, e);
4
4
  import { useToaster as L } from "../../../composables/useToaster.js";
5
- import { ToasterTypeOptions as A } from "../../../enums/toaster.js";
6
- import { PAGE_TYPES as h } from "../../../enums/unsubscribe.js";
7
- import { useEditorStore as y } from "../../../stores/editor.js";
8
- import { useUnsubscribeStore as l } from "../../../stores/unsubscribe.js";
9
- import { Block as T, BlockCompositionType as I, ContextActionType as B, ModificationDescription as d, BlockType as v } from "../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
10
- import { getDefaultTemplate as C } from "./template.js";
11
- import { UNSUBSCRIBE_BLOCK_SELECTOR as m, DATA_ATTRIBUTES as n, UNSUBSCRIBE_EVENTS as b } from "./utils/constants.js";
12
- import { parsePageList as _ } from "./utils/utils.js";
13
- const N = "unsubscribe-block", E = 'a[data-unsubscribe-link="true"]', U = "{{ins-unsubscribe-link}}", R = "https://academy.insiderone.com/docs/adding-unsubscribe-pages-into-emails", D = "Removing the unsubscribe text leaves an empty block, but an active unsubscribe link is required. Undo your last action to restore the text, or delete the unsubscribe block entirely.", w = {
14
- [h.GLOBAL_UNSUBSCRIBE]: "{{ins-global-unsubscribe-link}}",
15
- [h.SUBSCRIPTION_PREFERENCE_CENTER]: "{{ins-preferences-unsubscribe-link}}"
16
- }, P = 3;
17
- class W extends T {
5
+ import { ToasterTypeOptions as C } from "../../../enums/toaster.js";
6
+ import { PAGE_TYPES as m } from "../../../enums/unsubscribe.js";
7
+ import { useEditorStore as N } from "../../../stores/editor.js";
8
+ import { useUnsubscribeStore as a } from "../../../stores/unsubscribe.js";
9
+ import { Block as U, BlockCompositionType as R, ContextActionType as f, ModificationDescription as u, BlockType as v } from "../../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
10
+ import { getDefaultTemplate as D } from "./template.js";
11
+ import { UNSUBSCRIBE_BLOCK_SELECTOR as B, DATA_ATTRIBUTES as n, UNSUBSCRIBE_EVENTS as h } from "./utils/constants.js";
12
+ import { parsePageList as S } from "./utils/utils.js";
13
+ const w = "unsubscribe-block", E = 'a[data-unsubscribe-link="true"]', P = "{{ins-unsubscribe-link}}", x = "https://academy.insiderone.com/docs/adding-unsubscribe-pages-into-emails", G = "Removing the unsubscribe text leaves an empty block, but an active unsubscribe link is required. Undo your last action to restore the text, or delete the unsubscribe block entirely.", M = {
14
+ [m.GLOBAL_UNSUBSCRIBE]: "{{ins-global-unsubscribe-link}}",
15
+ [m.SUBSCRIPTION_PREFERENCE_CENTER]: "{{ins-preferences-unsubscribe-link}}"
16
+ }, O = 3;
17
+ let d = null, p = null;
18
+ const A = () => {
19
+ d && (document.removeEventListener(h.SELECT, d), d = null);
20
+ }, T = () => {
21
+ p && (document.removeEventListener(h.CANCEL, p), p = null);
22
+ }, q = () => {
23
+ A(), T();
24
+ };
25
+ class J extends U {
18
26
  constructor() {
19
27
  super();
20
- a(this, "selectEventListener", null);
21
- a(this, "cancelEventListener", null);
22
- a(this, "currentNode");
28
+ g(this, "currentNode");
23
29
  // Per-block "did this instance have a link last time we saw it?" tracking.
24
30
  // Keyed by the stable `data-unsubscribe-block-id` we assign, because
25
31
  // ImmutableHtmlNode instances are recreated on every document mutation and
26
32
  // can't be used as Map keys directly. A singleton boolean here would be
27
33
  // polluted across blocks since Stripo fires onDocumentChanged per-instance.
28
- a(this, "linkStateByBlockId", /* @__PURE__ */ new Map());
34
+ g(this, "linkStateByBlockId", /* @__PURE__ */ new Map());
29
35
  // Per-block prepend retry counter for the leading text guard (SD-143097).
30
- a(this, "guardAttemptsByBlockId", /* @__PURE__ */ new Map());
36
+ g(this, "guardAttemptsByBlockId", /* @__PURE__ */ new Map());
31
37
  }
32
38
  getId() {
33
- return N;
39
+ return w;
34
40
  }
35
41
  getIcon() {
36
42
  return "unsubscribe-icon";
37
43
  }
38
44
  getBlockCompositionType() {
39
- return I.BLOCK;
45
+ return R.BLOCK;
40
46
  }
41
47
  getName() {
42
48
  return this.api.translate("Unsubscribe Block");
@@ -45,16 +51,16 @@ class W extends T {
45
51
  return this.api.translate("Unsubscribe Block Description");
46
52
  }
47
53
  getTemplate() {
48
- return C();
54
+ return D();
49
55
  }
50
56
  getContextActionsIds() {
51
- return [B.MOVE, B.REMOVE];
57
+ return [f.MOVE, f.REMOVE];
52
58
  }
53
59
  onSelect(e) {
54
- if (this.currentNode = e, y().isPreviewModeOpen)
60
+ if (this.currentNode = e, N().isPreviewModeOpen)
55
61
  return;
56
62
  const t = this._getOrAssignBlockId(e);
57
- t && this.linkStateByBlockId.set(t, this._hasUnsubscribeLink(e)), this._setupSelectEventListener(), this._setupCancelEventListener(t), !("getAttribute" in e && e.getAttribute("data-migration")) && (this._resetStoreState(), t && (l().pendingBlockId = t), this._loadBlockState(e), this._checkExistingBlocks(), this._openDrawer());
63
+ t && this.linkStateByBlockId.set(t, this._hasUnsubscribeLink(e)), this._setupSelectEventListener(), this._setupCancelEventListener(t), !("getAttribute" in e && e.getAttribute("data-migration")) && (this._resetStoreState(), t && (a().pendingBlockId = t), this._loadBlockState(e), this._checkExistingBlocks(), this._openDrawer());
58
64
  }
59
65
  onCreated(e) {
60
66
  this._ensureLeadingTextGuard(e);
@@ -62,7 +68,7 @@ class W extends T {
62
68
  onDocumentInit() {
63
69
  try {
64
70
  const e = this.api.getDocumentRoot();
65
- e && "querySelectorAll" in e && e.querySelectorAll(m).forEach((t) => {
71
+ e && "querySelectorAll" in e && e.querySelectorAll(B).forEach((t) => {
66
72
  this._ensureLeadingTextGuard(t);
67
73
  });
68
74
  } catch {
@@ -77,13 +83,10 @@ class W extends T {
77
83
  this.linkStateByBlockId.get(t) === !0 && !s && this._warnLinkRemoved(), this.linkStateByBlockId.set(t, s);
78
84
  }
79
85
  onDelete(e) {
80
- this._removeEventListeners(), this._removeBlockTemplatesFromStore(e), this._resetStoreState();
86
+ q(), this._removeBlockTemplatesFromStore(e), this._resetStoreState();
81
87
  const t = this._readBlockId(e);
82
88
  t && (this.linkStateByBlockId.delete(t), this.guardAttemptsByBlockId.delete(t));
83
89
  }
84
- onDestroy() {
85
- this._removeEventListeners(), this.currentNode = void 0, this.linkStateByBlockId.clear(), this.guardAttemptsByBlockId.clear();
86
- }
87
90
  /**
88
91
  * Guarantees a plain-text node before the link's wrapper inside the <p>.
89
92
  * Without it the only caret position left of the link is inside the anchor,
@@ -102,20 +105,20 @@ class W extends T {
102
105
  return;
103
106
  const i = s.previousSibling();
104
107
  if (!!(i && i.getType() === "text" && i.getTextContent())) {
105
- const p = this._readBlockId(e);
106
- p && this.guardAttemptsByBlockId.delete(p);
108
+ const b = this._readBlockId(e);
109
+ b && this.guardAttemptsByBlockId.delete(b);
107
110
  return;
108
111
  }
109
- const g = this._getOrAssignBlockId(e);
110
- if (!g)
112
+ const k = this._getOrAssignBlockId(e);
113
+ if (!k)
111
114
  return;
112
- const k = this.guardAttemptsByBlockId.get(g) ?? 0;
113
- if (!(k >= P)) {
114
- this.guardAttemptsByBlockId.set(g, k + 1);
115
+ const _ = this.guardAttemptsByBlockId.get(k) ?? 0;
116
+ if (!(_ >= O)) {
117
+ this.guardAttemptsByBlockId.set(k, _ + 1);
115
118
  try {
116
- this.api.getDocumentModifier().modifyHtml(r).prepend("&nbsp;").apply(new d("Ensure unsubscribe link text guard"));
117
- } catch (p) {
118
- console.warn("[UnsubscribeBlock] Failed to ensure link text guard:", p);
119
+ this.api.getDocumentModifier().modifyHtml(r).prepend("&nbsp;").apply(new u("Ensure unsubscribe link text guard"));
120
+ } catch (b) {
121
+ console.warn("[UnsubscribeBlock] Failed to ensure link text guard:", b);
119
122
  }
120
123
  }
121
124
  }
@@ -139,7 +142,7 @@ class W extends T {
139
142
  return null;
140
143
  const s = this._generateNextBlockId();
141
144
  try {
142
- this.api.getDocumentModifier().modifyHtml(e).setAttribute(n.BLOCK_ID, s).apply(new d(`Assign unsubscribe block id ${s}`));
145
+ this.api.getDocumentModifier().modifyHtml(e).setAttribute(n.BLOCK_ID, s).apply(new u(`Assign unsubscribe block id ${s}`));
143
146
  } catch (r) {
144
147
  return console.warn("[UnsubscribeBlock] Failed to assign block id:", r), null;
145
148
  }
@@ -154,10 +157,10 @@ class W extends T {
154
157
  let e = 0;
155
158
  try {
156
159
  const t = this.api.getDocumentRoot();
157
- t && "querySelectorAll" in t && t.querySelectorAll(m).forEach((r) => {
160
+ t && "querySelectorAll" in t && t.querySelectorAll(B).forEach((r) => {
158
161
  if ("getAttribute" in r) {
159
- const i = r.getAttribute(n.BLOCK_ID), u = i ? parseInt(i) : 0;
160
- u > e && (e = u);
162
+ const i = r.getAttribute(n.BLOCK_ID), l = i ? parseInt(i) : 0;
163
+ l > e && (e = l);
161
164
  }
162
165
  });
163
166
  } catch {
@@ -168,12 +171,12 @@ class W extends T {
168
171
  try {
169
172
  const { showToaster: e } = L();
170
173
  e({
171
- type: A.Warning,
172
- message: this.api.translate(D),
174
+ type: C.Warning,
175
+ message: this.api.translate(G),
173
176
  actionButton: {
174
177
  text: this.api.translate("Visit Academy"),
175
178
  onClick: () => {
176
- window.open(R, "_blank", "noopener,noreferrer");
179
+ window.open(x, "_blank", "noopener,noreferrer");
177
180
  }
178
181
  }
179
182
  });
@@ -182,35 +185,26 @@ class W extends T {
182
185
  }
183
186
  }
184
187
  _setupSelectEventListener() {
185
- this._removeSelectEventListener(), this.selectEventListener = (e) => {
188
+ A(), d = (e) => {
186
189
  const t = e, { collectionType: s, selectedPages: r } = t.detail;
187
190
  this._updateBlock(s, r.join(","));
188
- }, document.addEventListener(b.SELECT, this.selectEventListener);
189
- }
190
- _removeSelectEventListener() {
191
- this.selectEventListener && (document.removeEventListener(b.SELECT, this.selectEventListener), this.selectEventListener = null);
191
+ }, document.addEventListener(h.SELECT, d);
192
192
  }
193
193
  _setupCancelEventListener(e) {
194
- this._removeCancelEventListener(), this.cancelEventListener = (t) => {
194
+ T(), p = (t) => {
195
195
  const { detail: s } = t;
196
196
  ((s == null ? void 0 : s.blockId) ?? null) === e && this._handleCancel();
197
- }, document.addEventListener(b.CANCEL, this.cancelEventListener);
198
- }
199
- _removeCancelEventListener() {
200
- this.cancelEventListener && (document.removeEventListener(b.CANCEL, this.cancelEventListener), this.cancelEventListener = null);
197
+ }, document.addEventListener(h.CANCEL, p);
201
198
  }
202
199
  _handleCancel() {
203
200
  try {
204
201
  if (!this.currentNode)
205
202
  return;
206
- this.api.getDocumentModifier().modifyHtml(this.currentNode).replaceWith(`<${v.EMPTY_CONTAINER}/>`).apply(new d("Removed unsubscribe block due to cancel"));
203
+ this.api.getDocumentModifier().modifyHtml(this.currentNode).replaceWith(`<${v.EMPTY_CONTAINER}/>`).apply(new u("Removed unsubscribe block due to cancel"));
207
204
  } catch (e) {
208
205
  console.warn("[UnsubscribeBlock] Failed to remove unsubscribe block:", e);
209
206
  }
210
207
  }
211
- _removeEventListeners() {
212
- this._removeSelectEventListener(), this._removeCancelEventListener();
213
- }
214
208
  _updateBlock(e, t) {
215
209
  if (!this.currentNode || !("querySelector" in this.currentNode))
216
210
  return;
@@ -218,28 +212,28 @@ class W extends T {
218
212
  if (!s)
219
213
  return;
220
214
  const r = this._getMergeTag(e);
221
- this.api.getDocumentModifier().modifyHtml(s).setAttribute("href", r).apply(new d(`Updated unsubscribe link to ${r}`)), this.api.getDocumentModifier().modifyHtml(this.currentNode).setAttribute(n.PAGE_TYPE, e.toString()).setAttribute(n.PAGE_LIST, t).apply(new d("Updated unsubscribe block metadata"));
215
+ this.api.getDocumentModifier().modifyHtml(s).setAttribute("href", r).apply(new u(`Updated unsubscribe link to ${r}`)), this.api.getDocumentModifier().modifyHtml(this.currentNode).setAttribute(n.PAGE_TYPE, e.toString()).setAttribute(n.PAGE_LIST, t).apply(new u("Updated unsubscribe block metadata"));
222
216
  }
223
217
  _getMergeTag(e) {
224
- return w[e] ?? U;
218
+ return M[e] ?? P;
225
219
  }
226
220
  _openDrawer() {
227
221
  if (!(this.currentNode && this.currentNode.getAttribute("data-unsubscribe-page-type")))
228
222
  try {
229
- const e = l();
223
+ const e = a();
230
224
  e.typeSelectionDrawerStatus = !0;
231
225
  } catch (e) {
232
226
  console.error("[UnsubscribeBlock] Failed to open drawer:", e);
233
227
  }
234
228
  }
235
229
  _checkExistingBlocks() {
236
- const e = l();
237
- e.isGlobalUnsubscribeDisabled = !1, e.isSubscriptionPreferencesCenterDisabled = !1, this.api.getDocumentRoot().querySelectorAll(m).forEach((s) => {
230
+ const e = a();
231
+ e.isGlobalUnsubscribeDisabled = !1, e.isSubscriptionPreferencesCenterDisabled = !1, this.api.getDocumentRoot().querySelectorAll(B).forEach((s) => {
238
232
  if ("getAttribute" in s) {
239
233
  const r = s.getAttribute(n.PAGE_TYPE);
240
234
  if (r) {
241
235
  const i = Number(r);
242
- i === h.GLOBAL_UNSUBSCRIBE ? e.isGlobalUnsubscribeDisabled = !0 : i === h.SUBSCRIPTION_PREFERENCE_CENTER && (e.isSubscriptionPreferencesCenterDisabled = !0);
236
+ i === m.GLOBAL_UNSUBSCRIBE ? e.isGlobalUnsubscribeDisabled = !0 : i === m.SUBSCRIPTION_PREFERENCE_CENTER && (e.isSubscriptionPreferencesCenterDisabled = !0);
243
237
  }
244
238
  }
245
239
  });
@@ -250,11 +244,11 @@ class W extends T {
250
244
  const t = e.getAttribute(n.PAGE_TYPE), s = e.getAttribute(n.PAGE_LIST);
251
245
  if (!t || !s)
252
246
  return;
253
- const r = l(), i = Number(t), u = _(s);
254
- await r.fetchTemplates(), r.setCollectionWithoutAutoSelection(i), r.loadSelectedTemplates(u);
247
+ const r = a(), i = Number(t), l = S(s);
248
+ await r.fetchTemplates(), r.setCollectionWithoutAutoSelection(i), r.loadSelectedTemplates(l);
255
249
  }
256
250
  _resetStoreState() {
257
- l().$reset();
251
+ a().$reset();
258
252
  }
259
253
  _removeBlockTemplatesFromStore(e) {
260
254
  if (!("getAttribute" in e))
@@ -262,11 +256,12 @@ class W extends T {
262
256
  const t = e.getAttribute(n.PAGE_LIST);
263
257
  if (!t)
264
258
  return;
265
- const s = l(), r = _(t);
259
+ const s = a(), r = S(t);
266
260
  s.removeUnsubscribePages(r);
267
261
  }
268
262
  }
269
263
  export {
270
- N as UNSUBSCRIBE_BLOCK_ID,
271
- W as UnsubscribeBlock
264
+ w as UNSUBSCRIBE_BLOCK_ID,
265
+ J as UnsubscribeBlock,
266
+ q as disposeUnsubscribeListeners
272
267
  };
@@ -0,0 +1,17 @@
1
+ import { DisplayConditionEvent as e } from "../../enums/display-condition.js";
2
+ let n = null;
3
+ const p = (E, t) => {
4
+ n == null || n();
5
+ const i = (o) => {
6
+ n == null || n(), t.onApply(o.detail.condition);
7
+ }, m = () => {
8
+ var o;
9
+ n == null || n(), (o = t.onCancel) == null || o.call(t);
10
+ };
11
+ document.addEventListener(e.APPLY, i), document.addEventListener(e.CANCEL, m), n = () => {
12
+ document.removeEventListener(e.APPLY, i), document.removeEventListener(e.CANCEL, m), n = null;
13
+ }, document.dispatchEvent(new CustomEvent(e.OPEN, { detail: E }));
14
+ };
15
+ export {
16
+ p as requestDisplayCondition
17
+ };
@@ -0,0 +1,17 @@
1
+ import { BlockType as o } from "../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
2
+ const n = "conditions", t = "guido-display-conditions-control", c = 10, s = [o.STRIPE, o.STRUCTURE, o.CONTAINER], d = {
3
+ PLUS: "guido-display-condition-plus",
4
+ EDIT: "guido-display-condition-edit",
5
+ TRASH: "guido-display-condition-trash",
6
+ CHEVRON: "guido-display-condition-chevron"
7
+ }, e = ["applyConditionSwitcher", "applyCondition", "displayConditions"], I = "You can add Display Condition by selecting an existing condition or creating a new one to show specific content.", O = "You can create or select a display condition to control content visibility based on your recipients' properties or events.";
8
+ export {
9
+ O as APPLIED_DESCRIPTION,
10
+ e as BUILT_IN_CONDITION_CONTROLS,
11
+ t as CONDITIONS_CONTROL_ID,
12
+ n as CONDITIONS_TAB_ID,
13
+ s as CONDITION_BLOCK_TYPES,
14
+ d as CONDITION_ICONS,
15
+ I as EMPTY_DESCRIPTION,
16
+ c as MAX_COLLAPSED_LINES
17
+ };
@@ -0,0 +1,178 @@
1
+ var O = Object.defineProperty;
2
+ var $ = (o, s, i) => s in o ? O(o, s, { enumerable: !0, configurable: !0, writable: !0, value: i }) : o[s] = i;
3
+ var u = (o, s, i) => $(o, typeof s != "symbol" ? s + "" : s, i);
4
+ import { CommonControl as S } from "../Blocks/common-control.js";
5
+ import { toAppliedCondition as w, parseSource as N } from "../../utils/displayCondition.js";
6
+ import { escapeHtml as f } from "../../utils/htmlEscape.js";
7
+ import { ModificationDescription as D, UIElementType as b, UEAttr as I } from "../../node_modules/@stripoinc/ui-editor-extensions/dist/esm/index.js";
8
+ import { requestDisplayCondition as E } from "./bridge.js";
9
+ import { CONDITIONS_CONTROL_ID as x, APPLIED_DESCRIPTION as M, EMPTY_DESCRIPTION as T, MAX_COLLAPSED_LINES as v, CONDITION_ICONS as g } from "./constants.js";
10
+ const r = ".guido-display-conditions", L = { id: 0, name: "", description: "", beforeScript: "", afterScript: "" }, _ = (o) => `<${b.ICON} ${I.ICON.src}="${o}"></${b.ICON}>`, c = (o, s, i, t = !1) => `<button type="button" class="${s}" id="${o}"${t ? " hidden" : ""}>${i}</button>`;
11
+ class B extends S {
12
+ constructor() {
13
+ super(...arguments);
14
+ u(this, "expanded", !1);
15
+ u(this, "listeners", []);
16
+ u(this, "resizeObserver", null);
17
+ u(this, "detachOutsideClick", null);
18
+ }
19
+ getId() {
20
+ return x;
21
+ }
22
+ getTemplate() {
23
+ return `
24
+ <div class="guido-display-conditions">
25
+ <div class="guido-display-conditions__header">
26
+ <p class="guido-display-conditions__title">${this.api.translate("Display Conditions")}</p>
27
+ <p class="guido-display-conditions__description" data-dc-description></p>
28
+ </div>
29
+ <div class="guido-display-conditions__empty" data-dc-empty>
30
+ ${c(
31
+ "guido__btn-add-display-condition",
32
+ "guido-display-conditions__add",
33
+ `${_(g.PLUS)}<span>${this.api.translate("Add Display Condition")}</span>`
34
+ )}
35
+ <div class="guido-display-conditions__menu" data-dc-menu hidden>
36
+ ${c(
37
+ "guido__btn-display-condition-create",
38
+ "guido-display-conditions__menu-item",
39
+ this.api.translate("Create New Condition")
40
+ )}
41
+ ${c(
42
+ "guido__btn-display-condition-select",
43
+ "guido-display-conditions__menu-item",
44
+ this.api.translate("Select Saved Condition")
45
+ )}
46
+ </div>
47
+ </div>
48
+ <div class="guido-display-conditions__applied" data-dc-applied hidden>
49
+ <div class="guido-display-conditions__code-box">
50
+ <p class="guido-display-conditions__name" data-dc-name></p>
51
+ <div class="guido-display-conditions__sections" data-dc-sections>
52
+ <p class="guido-display-conditions__section-label">
53
+ ${this.api.translate("Code Before Module")}
54
+ </p>
55
+ <pre class="guido-display-conditions__code" data-dc-before></pre>
56
+ <p class="guido-display-conditions__section-label" data-dc-after-label>
57
+ ${this.api.translate("Code After Module")}
58
+ </p>
59
+ <pre class="guido-display-conditions__code" data-dc-after></pre>
60
+ </div>
61
+ ${c(
62
+ "guido__btn-display-condition-toggle",
63
+ "guido-display-conditions__toggle",
64
+ `${_(g.CHEVRON)}<span data-dc-toggle-label></span>`,
65
+ !0
66
+ )}
67
+ </div>
68
+ <div class="guido-display-conditions__actions">
69
+ ${c(
70
+ "guido__btn-edit-display-condition",
71
+ "guido-display-conditions__action guido-display-conditions__action--edit",
72
+ `${_(g.EDIT)}<span>${this.api.translate("Edit")}</span>`
73
+ )}
74
+ ${c(
75
+ "guido__btn-remove-display-condition",
76
+ "guido-display-conditions__action guido-display-conditions__action--remove",
77
+ `${_(g.TRASH)}<span>${this.api.translate("Remove")}</span>`
78
+ )}
79
+ </div>
80
+ </div>
81
+ </div>
82
+ `;
83
+ }
84
+ onRender() {
85
+ this.teardown(), this.wire("#guido__btn-add-display-condition", () => this.toggleMenu()), this.wire("#guido__btn-display-condition-create", () => this.openDrawer("create")), this.wire("#guido__btn-display-condition-select", () => this.openDrawer("select")), this.wire("#guido__btn-edit-display-condition", () => this.openDrawer("edit")), this.wire("#guido__btn-remove-display-condition", () => this.applyCondition(null)), this.wire("#guido__btn-display-condition-toggle", () => {
86
+ this.expanded = !this.expanded, this.paint();
87
+ }), this.observeCodeSize(), this.paint();
88
+ }
89
+ onTemplateNodeUpdated(i) {
90
+ const t = i !== this.currentNode;
91
+ super.onTemplateNodeUpdated(i), t && (this.expanded = !1, this.toggleMenu(!1)), this.paint();
92
+ }
93
+ onDestroy() {
94
+ super.onDestroy(), this.teardown();
95
+ }
96
+ getCondition() {
97
+ var t;
98
+ const i = this.currentNode;
99
+ return w((t = i == null ? void 0 : i.getDisplayCondition) == null ? void 0 : t.call(i));
100
+ }
101
+ toggleMenu(i) {
102
+ var n, d, a;
103
+ const t = (n = this.getContainer()) == null ? void 0 : n.querySelector(`${r} [data-dc-menu]`);
104
+ if (!t)
105
+ return;
106
+ t.hidden = i === void 0 ? !t.hidden : !i, (d = this.detachOutsideClick) == null || d.call(this), t.hidden || this.listenOutsideClick();
107
+ const e = (a = this.getContainer()) == null ? void 0 : a.querySelector(`${r} #guido__btn-add-display-condition`);
108
+ t.style.width = !t.hidden && e ? `${e.getBoundingClientRect().width}px` : "";
109
+ }
110
+ listenOutsideClick() {
111
+ const i = this.getContainer(), t = (e) => {
112
+ e.composedPath().some((d) => d instanceof HTMLElement && d.matches(`${r} [data-dc-menu], ${r} #guido__btn-add-display-condition`)) || this.toggleMenu(!1);
113
+ };
114
+ i == null || i.addEventListener("pointerdown", t, !0), this.detachOutsideClick = () => {
115
+ i == null || i.removeEventListener("pointerdown", t, !0), this.detachOutsideClick = null;
116
+ };
117
+ }
118
+ openDrawer(i) {
119
+ this.toggleMenu(!1), E(
120
+ { mode: i, current: i === "edit" ? this.getCondition() : null },
121
+ { onApply: (t) => this.applyCondition(t) }
122
+ );
123
+ }
124
+ applyCondition(i) {
125
+ if (!this.currentNode)
126
+ return;
127
+ const t = this.api.getDocumentModifier().modifyHtml(this.currentNode);
128
+ i ? t.setDisplayCondition(i) : t.setDisplayCondition(L), t.apply(new D(
129
+ i ? `Set display condition ${i.name}` : "Remove display condition"
130
+ ));
131
+ }
132
+ wire(i, t) {
133
+ var n;
134
+ const e = (n = this.getContainer()) == null ? void 0 : n.querySelector(`${r} ${i}`);
135
+ e && (e.addEventListener("click", t), this.listeners.push({ element: e, handler: t }));
136
+ }
137
+ teardown() {
138
+ var i, t;
139
+ this.listeners.forEach(({ element: e, handler: n }) => e.removeEventListener("click", n)), this.listeners = [], (i = this.resizeObserver) == null || i.disconnect(), this.resizeObserver = null, (t = this.detachOutsideClick) == null || t.call(this);
140
+ }
141
+ // Line counts depend on layout: the panel font loads late and the panel can be resized.
142
+ observeCodeSize() {
143
+ var t;
144
+ const i = (t = this.getContainer()) == null ? void 0 : t.querySelectorAll(`${r} .guido-display-conditions__code`);
145
+ !(i != null && i.length) || typeof ResizeObserver > "u" || (this.resizeObserver = new ResizeObserver(() => this.paint()), i.forEach((e) => {
146
+ var n;
147
+ return (n = this.resizeObserver) == null ? void 0 : n.observe(e);
148
+ }));
149
+ }
150
+ paint() {
151
+ var C;
152
+ const i = (C = this.getContainer()) == null ? void 0 : C.querySelector(r);
153
+ if (!i)
154
+ return;
155
+ const t = this.getCondition(), e = (h) => i.querySelector(h);
156
+ if (e("[data-dc-empty]").hidden = !!t, e("[data-dc-applied]").hidden = !t, e("[data-dc-description]").textContent = this.api.translate(t ? M : T), !t)
157
+ return;
158
+ e("[data-dc-name]").textContent = t.name, e("#guido__btn-edit-display-condition").hidden = N(t) !== "inline";
159
+ const n = e("[data-dc-sections]"), d = e("[data-dc-before]"), a = e("[data-dc-after]");
160
+ d.innerHTML = f(t.beforeScript), a.innerHTML = f(t.afterScript), a.hidden = !t.afterScript, e("[data-dc-after-label]").hidden = !t.afterScript, n.style.maxHeight = "";
161
+ const l = parseFloat(getComputedStyle(d).lineHeight) || 24, p = (h) => h.hidden ? 0 : Math.round(h.scrollHeight / l), y = p(d) + p(a) > v, m = e("#guido__btn-display-condition-toggle");
162
+ m.hidden = !y, m.classList.toggle("is-expanded", this.expanded), e("[data-dc-toggle-label]").textContent = this.api.translate(this.expanded ? "Show Less" : "Show More"), y && !this.expanded && (n.style.maxHeight = `${this.collapsedHeight(n, [d, a], l)}px`);
163
+ }
164
+ // Labels do not count toward the line limit, so the cut lands after the 10th rendered code line.
165
+ collapsedHeight(i, t, e) {
166
+ const { top: n } = i.getBoundingClientRect();
167
+ let d = v, a = 0;
168
+ return t.filter((l) => !l.hidden).forEach((l) => {
169
+ if (d <= 0)
170
+ return;
171
+ const p = Math.min(d, Math.round(l.scrollHeight / e));
172
+ a = l.getBoundingClientRect().top - n + p * e, d -= p;
173
+ }), a;
174
+ }
175
+ }
176
+ export {
177
+ B as DisplayConditionsControl
178
+ };