ui.shipaid.com 0.3.146 → 0.3.148

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/widget.es.js CHANGED
@@ -1,6 +1,19 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
3
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
+ function getIdFromShopifyGid(gid) {
5
+ var _a;
6
+ return ((_a = gid == null ? void 0 : gid.match(/\d+/)) == null ? void 0 : _a[0]) ?? null;
7
+ }
8
+ const normalizeVariantId$1 = (value) => {
9
+ if (value === null || value === void 0) return null;
10
+ if (typeof value === "number") return String(value);
11
+ if (typeof value === "string") {
12
+ const numericId = getIdFromShopifyGid(value);
13
+ return numericId ?? value;
14
+ }
15
+ return null;
16
+ };
4
17
  const getExcludedProducts = (store) => {
5
18
  const excludedProductSkus = Array.isArray(
6
19
  store == null ? void 0 : store.excludedProductSkus
@@ -28,26 +41,43 @@ function calculateProtectionTotal(store, protectionProduct, cart) {
28
41
  throw new Error("Tried to find protection variant, but protection settings for this store are missing.");
29
42
  }
30
43
  const { excludedProductSkus, excludedProductTags, excludedProductIds } = getExcludedProducts(store);
44
+ const excludedVariantIdSet = new Set(
45
+ excludedProductIds.map((id) => String(id))
46
+ );
47
+ const protectionVariantIdSet = new Set(
48
+ ((protectionProduct == null ? void 0 : protectionProduct.variants) ?? []).map((variant) => normalizeVariantId$1(variant == null ? void 0 : variant.id)).filter((id) => Boolean(id))
49
+ );
50
+ const isProtectionVariant = (item) => {
51
+ const normalizedId = normalizeVariantId$1(item.variant_id);
52
+ if (!normalizedId) return false;
53
+ if (protectionVariantIdSet.has(normalizedId)) return true;
54
+ return protectionVariantIdSet.has(String(normalizedId));
55
+ };
31
56
  const isItemExcluded = (item) => {
57
+ if (isProtectionVariant(item)) return false;
32
58
  if (item.isVirtualProduct) {
33
59
  return true;
34
- } else if (item.sku && excludedProductSkus.includes(item.sku.trim())) {
60
+ }
61
+ if (item.sku && excludedProductSkus.includes(item.sku.trim())) {
35
62
  return true;
36
- } else if (item.tags && item.tags.some((t2) => excludedProductTags.includes(t2.toLowerCase().trim()))) {
63
+ }
64
+ if (item.tags && item.tags.some((t2) => excludedProductTags.includes(t2.toLowerCase().trim()))) {
37
65
  return true;
38
- } else if (item.variant_id && excludedProductIds.includes(item.variant_id)) {
66
+ }
67
+ const normalizedId = normalizeVariantId$1(item.variant_id);
68
+ if (normalizedId && excludedVariantIdSet.has(normalizedId)) {
39
69
  return true;
40
70
  }
41
71
  return false;
42
72
  };
73
+ const protectionVariantsInCart = ((_a = cart.items) == null ? void 0 : _a.filter((item) => isProtectionVariant(item))) ?? [];
74
+ const protectionVariantsInCartTotal = protectionVariantsInCart.reduce(
75
+ (total, item) => total + (Number(item.final_line_price) || 0),
76
+ 0
77
+ );
43
78
  const itemTotal = (cart.items ?? []).reduce((total, item) => {
44
- return isItemExcluded(item) ? total - item.final_line_price : total;
45
- }, cart.total_price || 0);
46
- const protectionVariantsInCart = ((_a = cart.items) == null ? void 0 : _a.filter((item) => {
47
- var _a2;
48
- return (_a2 = protectionProduct == null ? void 0 : protectionProduct.variants) == null ? void 0 : _a2.some((variant) => variant.id === item.variant_id);
49
- })) ?? [];
50
- const protectionVariantsInCartTotal = protectionVariantsInCart.reduce((total, item) => total + item.final_line_price, 0);
79
+ return isItemExcluded(item) ? total - (Number(item.final_line_price) || 0) : total;
80
+ }, Number(cart.total_price) || 0);
51
81
  const cartTotal = itemTotal - protectionVariantsInCartTotal;
52
82
  const allowZeroCartValueProtection = (_b = store.widgetConfigurations) == null ? void 0 : _b.allowZeroCartValueProtection;
53
83
  if (!allowZeroCartValueProtection) {
@@ -98,10 +128,6 @@ function findProtectionVariant(store, protectionProduct, protectionFee) {
98
128
  }
99
129
  return matchingVariant;
100
130
  }
101
- function getIdFromShopifyGid(gid) {
102
- var _a;
103
- return ((_a = gid == null ? void 0 : gid.match(/\d+/)) == null ? void 0 : _a[0]) ?? null;
104
- }
105
131
  const common = { calculateProtectionTotal, findProtectionVariant };
106
132
  /**
107
133
  * @license
@@ -3101,6 +3127,7 @@ var SHIPAID_EVENTS = /* @__PURE__ */ ((SHIPAID_EVENTS2) => {
3101
3127
  })(SHIPAID_EVENTS || {});
3102
3128
  var EXTERNAL_EVENTS = /* @__PURE__ */ ((EXTERNAL_EVENTS2) => {
3103
3129
  EXTERNAL_EVENTS2["CART_UPDATE"] = "cart:update";
3130
+ EXTERNAL_EVENTS2["CART_UPDATED"] = "cart:updated";
3104
3131
  EXTERNAL_EVENTS2["VARIANT_CHANGE"] = "variant:change";
3105
3132
  return EXTERNAL_EVENTS2;
3106
3133
  })(EXTERNAL_EVENTS || {});
@@ -3479,6 +3506,93 @@ const openCarousel = (from) => {
3479
3506
  } catch {
3480
3507
  }
3481
3508
  };
3509
+ const ensureLearnMoreCarousel = (store) => {
3510
+ var _a, _b;
3511
+ try {
3512
+ const existing = document.querySelector("shipaid-learn-more-carousel");
3513
+ if (existing) return;
3514
+ const el = document.createElement("shipaid-learn-more-carousel");
3515
+ const isGreenEnabled = Boolean((_a = store == null ? void 0 : store.greenProtection) == null ? void 0 : _a.enabled);
3516
+ const isFreeGiftEnabled = Boolean((_b = store == null ? void 0 : store.freeGifts) == null ? void 0 : _b.enabled);
3517
+ if (isGreenEnabled) el.setAttribute("green-protection", "true");
3518
+ if (isFreeGiftEnabled) el.setAttribute("free-gift", "true");
3519
+ el.setAttribute("carousel-state", "close");
3520
+ document.body.appendChild(el);
3521
+ } catch {
3522
+ }
3523
+ };
3524
+ const refreshShopifyCartUI = async () => {
3525
+ try {
3526
+ const sectionIds = ["cart-drawer", "cart-icon-bubble", "main-cart-items"];
3527
+ const url = `/?sections=${encodeURIComponent(sectionIds.join(","))}`;
3528
+ const res = await fetch(url, { credentials: "same-origin" });
3529
+ if (!res.ok) return;
3530
+ const htmlById = await res.json().catch(() => null);
3531
+ if (!htmlById || typeof htmlById !== "object") return;
3532
+ for (const id of Object.keys(htmlById)) {
3533
+ const html = htmlById[id];
3534
+ if (typeof html !== "string") continue;
3535
+ const tmp = document.createElement("div");
3536
+ tmp.innerHTML = html;
3537
+ if (id === "cart-drawer") {
3538
+ try {
3539
+ const newDrawer = tmp.querySelector("cart-drawer");
3540
+ const oldDrawer = document.querySelector("cart-drawer");
3541
+ if (newDrawer && oldDrawer) {
3542
+ const shouldBeEmpty = newDrawer.classList.contains("is-empty");
3543
+ if (shouldBeEmpty) oldDrawer.classList.add("is-empty");
3544
+ else oldDrawer.classList.remove("is-empty");
3545
+ }
3546
+ } catch {
3547
+ }
3548
+ try {
3549
+ const newDrawerItems = tmp.querySelector("cart-drawer-items");
3550
+ const oldDrawerItems = document.querySelector("cart-drawer cart-drawer-items, .cart-drawer cart-drawer-items");
3551
+ if (newDrawerItems && oldDrawerItems) {
3552
+ oldDrawerItems.outerHTML = newDrawerItems.outerHTML;
3553
+ }
3554
+ } catch {
3555
+ }
3556
+ const newItems = tmp.querySelector("#CartDrawer-CartItems");
3557
+ const oldItems = document.getElementById("CartDrawer-CartItems");
3558
+ if (newItems && oldItems) {
3559
+ oldItems.outerHTML = newItems.outerHTML;
3560
+ }
3561
+ const newFooter = tmp.querySelector(".cart-drawer__footer");
3562
+ const oldFooter = document.querySelector(".cart-drawer .cart-drawer__footer");
3563
+ if (newFooter && oldFooter) {
3564
+ oldFooter.outerHTML = newFooter.outerHTML;
3565
+ }
3566
+ const newCtas = tmp.querySelector(".cart__ctas");
3567
+ const oldCtas = document.querySelector(".cart-drawer .cart__ctas");
3568
+ if (newCtas && oldCtas) {
3569
+ oldCtas.outerHTML = newCtas.outerHTML;
3570
+ }
3571
+ continue;
3572
+ }
3573
+ if (id === "main-cart-items") {
3574
+ const newMainItems = tmp.querySelector("#main-cart-items");
3575
+ const oldMainItems = document.getElementById("main-cart-items");
3576
+ if (newMainItems && oldMainItems) {
3577
+ oldMainItems.outerHTML = newMainItems.outerHTML;
3578
+ } else {
3579
+ const section = document.getElementById("shopify-section-main-cart-items");
3580
+ if (section) section.outerHTML = html;
3581
+ }
3582
+ continue;
3583
+ }
3584
+ if (id === "cart-icon-bubble") {
3585
+ const newBubble = tmp.querySelector("#cart-icon-bubble, [data-cart-count-bubble]");
3586
+ const oldBubble = document.querySelector("#cart-icon-bubble, [data-cart-count-bubble]");
3587
+ if (newBubble && oldBubble) {
3588
+ oldBubble.replaceWith(newBubble);
3589
+ }
3590
+ continue;
3591
+ }
3592
+ }
3593
+ } catch {
3594
+ }
3595
+ };
3482
3596
  var __defProp$2 = Object.defineProperty;
3483
3597
  var __decorateClass$2 = (decorators, target, key, kind) => {
3484
3598
  var result = void 0;
@@ -3527,7 +3641,39 @@ const _ShipAidWidget = class _ShipAidWidget extends s$1 {
3527
3641
  };
3528
3642
  this.intervalId = null;
3529
3643
  this._sellingPlanId = null;
3530
- this._pendingLearnMoreSource = null;
3644
+ this._isUpdatingShipAid = false;
3645
+ this._lastCartEventAt = 0;
3646
+ this._isReplacingCartSections = false;
3647
+ this._onShipAidCartEvent = (event) => {
3648
+ var _a2, _b2;
3649
+ if (((_b2 = (_a2 = event == null ? void 0 : event.detail) == null ? void 0 : _a2.data) == null ? void 0 : _b2.source) === "shipaid-widget") return;
3650
+ if (this._isUpdatingShipAid) return;
3651
+ const now = Date.now();
3652
+ if (now - this._lastCartEventAt < 500) return;
3653
+ this._lastCartEventAt = now;
3654
+ try {
3655
+ this.updateCart().catch(() => {
3656
+ });
3657
+ } catch {
3658
+ }
3659
+ };
3660
+ this._onShipAidInternalCartUpdated = (event) => {
3661
+ var _a2, _b2, _c2, _d;
3662
+ const src = ((_b2 = (_a2 = event == null ? void 0 : event.detail) == null ? void 0 : _a2.data) == null ? void 0 : _b2.source) || ((_c2 = event == null ? void 0 : event.detail) == null ? void 0 : _c2.source);
3663
+ if (src === "shipaid-widget") return;
3664
+ if (this._isUpdatingShipAid) return;
3665
+ const providedCart = (_d = event == null ? void 0 : event.detail) == null ? void 0 : _d.cart;
3666
+ try {
3667
+ if (providedCart) {
3668
+ this.updateCart(providedCart).catch(() => {
3669
+ });
3670
+ } else {
3671
+ this.updateCart().catch(() => {
3672
+ });
3673
+ }
3674
+ } catch {
3675
+ }
3676
+ };
3531
3677
  this._handleHelpClick = (event) => {
3532
3678
  if (event) event.preventDefault();
3533
3679
  this._toggleBenefits();
@@ -3614,8 +3760,7 @@ const _ShipAidWidget = class _ShipAidWidget extends s$1 {
3614
3760
  }
3615
3761
  }
3616
3762
  _openLearnMore(source) {
3617
- this._popup = "learn-more";
3618
- this._pendingLearnMoreSource = source;
3763
+ openCarousel(source);
3619
3764
  if (this.persistPopup) {
3620
3765
  this.setPopupKey();
3621
3766
  }
@@ -3727,11 +3872,16 @@ const _ShipAidWidget = class _ShipAidWidget extends s$1 {
3727
3872
  async _handleRefresh(input) {
3728
3873
  const isCart = Reflect.has(input, "items");
3729
3874
  if (this.shouldRefreshOnUpdate) return window.location.reload();
3730
- if (!isCart) await this.updateCart();
3875
+ if (isCart) {
3876
+ await this.updateCart(input, { dispatchExternalEvents: true });
3877
+ } else {
3878
+ await this.updateCart(void 0, { dispatchExternalEvents: true });
3879
+ }
3731
3880
  this._dispatchEvent(SHIPAID_EVENTS.CART_UPDATED, {
3732
3881
  protection: this._hasProtectionInCart,
3733
3882
  cart: isCart ? input : this._cart,
3734
- lineItem: !isCart ? input : this._protectionCartItem
3883
+ lineItem: !isCart ? input : this._protectionCartItem,
3884
+ data: { source: "shipaid-widget" }
3735
3885
  });
3736
3886
  }
3737
3887
  /** Given the current order, it calculates the protection total according to the store protection settings. */
@@ -3995,9 +4145,28 @@ const _ShipAidWidget = class _ShipAidWidget extends s$1 {
3995
4145
  return this._hasProtectionInCart;
3996
4146
  }
3997
4147
  /** Update the internal cart, which will trigger any protection fee updates */
3998
- async updateCart(cart) {
4148
+ async updateCart(cart, options) {
3999
4149
  if (!cart) cart = await this._fetchCart();
4000
4150
  this._cart = cart;
4151
+ const shouldDispatchExternal = (options == null ? void 0 : options.dispatchExternalEvents) ?? false;
4152
+ if (shouldDispatchExternal) {
4153
+ try {
4154
+ document.dispatchEvent(new CustomEvent(EXTERNAL_EVENTS.CART_UPDATE, {
4155
+ detail: { data: { source: "shipaid-widget" }, cart }
4156
+ }));
4157
+ window.dispatchEvent(new CustomEvent(EXTERNAL_EVENTS.CART_UPDATE, {
4158
+ detail: { data: { source: "shipaid-widget" }, cart }
4159
+ }));
4160
+ } catch {
4161
+ }
4162
+ }
4163
+ try {
4164
+ this._isReplacingCartSections = true;
4165
+ await refreshShopifyCartUI();
4166
+ } catch {
4167
+ } finally {
4168
+ this._isReplacingCartSections = false;
4169
+ }
4001
4170
  }
4002
4171
  async addCartProtectionVariant() {
4003
4172
  var _a, _b;
@@ -4116,12 +4285,28 @@ const _ShipAidWidget = class _ShipAidWidget extends s$1 {
4116
4285
  /** Add ShipAid shipping protection. */
4117
4286
  async addProtection() {
4118
4287
  var _a, _b;
4288
+ if (this._isUpdatingShipAid) {
4289
+ return;
4290
+ }
4119
4291
  try {
4292
+ this._isUpdatingShipAid = true;
4293
+ this._disableCheckoutButtons();
4120
4294
  if (!this._store) throw new Error("Store has not been loaded.");
4121
- if (!((_a = this._cart) == null ? void 0 : _a.items)) throw new Error("Cart has not been loaded.");
4122
- if (!((_b = this._protectionVariant) == null ? void 0 : _b.id)) {
4295
+ if (!((_a = this._protectionVariant) == null ? void 0 : _a.id)) {
4123
4296
  throw new Error("No protection variant found.");
4124
4297
  }
4298
+ this._cart = await this._fetchCart();
4299
+ if (!((_b = this._cart) == null ? void 0 : _b.items)) throw new Error("Cart has not been loaded.");
4300
+ const existingProtection = this._cart.items.find((item) => {
4301
+ var _a2, _b2;
4302
+ return (_b2 = (_a2 = this._protectionProduct) == null ? void 0 : _a2.variants) == null ? void 0 : _b2.some(
4303
+ (variant) => variant.id === item.variant_id
4304
+ );
4305
+ });
4306
+ if (existingProtection) {
4307
+ this._hasProtectionInCart = true;
4308
+ return;
4309
+ }
4125
4310
  this._setState("loading");
4126
4311
  const cart = await this.addCartProtectionVariant();
4127
4312
  await this._handleRefresh(cart);
@@ -4132,11 +4317,15 @@ const _ShipAidWidget = class _ShipAidWidget extends s$1 {
4132
4317
  } finally {
4133
4318
  this._cart = await this._fetchCart();
4134
4319
  this._setState("success");
4320
+ this._isUpdatingShipAid = false;
4321
+ this._enableCheckoutButtons();
4135
4322
  }
4136
4323
  }
4137
4324
  /** Remove ShipAid shipping protection. */
4138
4325
  async removeProtection() {
4139
4326
  try {
4327
+ this._isUpdatingShipAid = true;
4328
+ this._disableCheckoutButtons();
4140
4329
  if (!this._store) throw new Error("Store has not been loaded.");
4141
4330
  if (!this._protectionCartItem) {
4142
4331
  throw new Error("Protection product not found.");
@@ -4155,6 +4344,8 @@ const _ShipAidWidget = class _ShipAidWidget extends s$1 {
4155
4344
  } finally {
4156
4345
  this._cart = await this._fetchCart();
4157
4346
  this._setState("success");
4347
+ this._isUpdatingShipAid = false;
4348
+ this._enableCheckoutButtons();
4158
4349
  }
4159
4350
  }
4160
4351
  /** Try adding ShipAid shipping protection during polling if applicable */
@@ -4162,6 +4353,7 @@ const _ShipAidWidget = class _ShipAidWidget extends s$1 {
4162
4353
  var _a, _b, _c, _d, _e, _f;
4163
4354
  if (!((_a = this._store) == null ? void 0 : _a.widgetAutoOptIn) || this.useShipAidCheckout) return;
4164
4355
  if (!((_b = this._cart) == null ? void 0 : _b.items) || !((_c = this._cart) == null ? void 0 : _c.item_count)) return;
4356
+ if (this._isUpdatingShipAid) return;
4165
4357
  const protectionCartItemIndex = (_d = this._cart.items) == null ? void 0 : _d.findIndex((item) => {
4166
4358
  var _a2, _b2;
4167
4359
  return (_b2 = (_a2 = this._protectionProduct) == null ? void 0 : _a2.variants) == null ? void 0 : _b2.some(
@@ -4187,46 +4379,68 @@ const _ShipAidWidget = class _ShipAidWidget extends s$1 {
4187
4379
  }
4188
4380
  }
4189
4381
  async handleMultipleProtectionVariants() {
4190
- var _a, _b, _c, _d, _e;
4382
+ var _a, _b, _c;
4191
4383
  if (!((_a = this._cart) == null ? void 0 : _a.items) || !((_b = this._cart) == null ? void 0 : _b.item_count)) return;
4192
- let count = 0;
4384
+ const protectionItems = [];
4193
4385
  (_c = this._cart.items) == null ? void 0 : _c.forEach((item) => {
4194
4386
  var _a2, _b2;
4195
4387
  const isProtectionItem = (_b2 = (_a2 = this._protectionProduct) == null ? void 0 : _a2.variants) == null ? void 0 : _b2.some(
4196
4388
  (variant) => variant.id === item.variant_id
4197
4389
  );
4198
- if (isProtectionItem) count++;
4390
+ if (isProtectionItem) {
4391
+ protectionItems.push(item);
4392
+ }
4199
4393
  });
4200
- if (count > 1) {
4201
- const protectionCartItemIndex = (_d = this._cart.items) == null ? void 0 : _d.findIndex((item) => {
4202
- var _a2, _b2;
4203
- return (_b2 = (_a2 = this._protectionProduct) == null ? void 0 : _a2.variants) == null ? void 0 : _b2.some(
4204
- (variant) => variant.id === item.variant_id
4205
- );
4394
+ if (protectionItems.length > 1) {
4395
+ for (let i3 = 1; i3 < protectionItems.length; i3++) {
4396
+ await this.updateCartProtectionVariant(0, protectionItems[i3]);
4397
+ }
4398
+ this._cart = await this._fetchCart();
4399
+ return await this._handleRefresh(this._cart);
4400
+ }
4401
+ }
4402
+ /** Disable checkout buttons while updating protection */
4403
+ _disableCheckoutButtons() {
4404
+ var _a, _b;
4405
+ try {
4406
+ const providedSelector = (_b = (_a = this._store) == null ? void 0 : _a.widgetConfigurations) == null ? void 0 : _b.checkoutButtonSelector;
4407
+ const selectors = providedSelector ? providedSelector.split(",").map((s3) => s3.trim()).filter(Boolean) : DEFAULT_CHECKOUT_SELECTORS;
4408
+ const buttons = /* @__PURE__ */ new Set();
4409
+ selectors.forEach((selector) => {
4410
+ try {
4411
+ document.querySelectorAll(selector).forEach((btn) => {
4412
+ buttons.add(btn);
4413
+ });
4414
+ } catch (e3) {
4415
+ }
4206
4416
  });
4207
- const protectionCartItem = (_e = this._cart) == null ? void 0 : _e.items[protectionCartItemIndex];
4208
- const cart = await this.updateCartProtectionVariant(
4209
- 0,
4210
- protectionCartItem
4211
- );
4212
- return await this._handleRefresh(cart);
4417
+ buttons.forEach((button) => {
4418
+ button.setAttribute("disabled", "true");
4419
+ button.style.opacity = "0.6";
4420
+ button.style.pointerEvents = "none";
4421
+ button.setAttribute("data-shipaid-disabled", "true");
4422
+ });
4423
+ } catch (error) {
4424
+ console.error("[ShipAid] Error disabling checkout buttons:", error);
4425
+ }
4426
+ }
4427
+ /** Re-enable checkout buttons after updating protection */
4428
+ _enableCheckoutButtons() {
4429
+ try {
4430
+ const buttons = document.querySelectorAll('[data-shipaid-disabled="true"]');
4431
+ buttons.forEach((button) => {
4432
+ button.removeAttribute("disabled");
4433
+ button.style.opacity = "";
4434
+ button.style.pointerEvents = "";
4435
+ button.removeAttribute("data-shipaid-disabled");
4436
+ });
4437
+ } catch (error) {
4438
+ console.error("[ShipAid] Error enabling checkout buttons:", error);
4213
4439
  }
4214
4440
  }
4215
4441
  /** Templates */
4216
4442
  learnMorePopupTemplate() {
4217
- var _a, _b, _c, _d;
4218
- const carousel = document.querySelector("shipaid-learn-more-carousel");
4219
- const isGreenEnabled = Boolean((_b = (_a = this._store) == null ? void 0 : _a.greenProtection) == null ? void 0 : _b.enabled);
4220
- const isFreeGiftEnabled = Boolean((_d = (_c = this._store) == null ? void 0 : _c.freeGifts) == null ? void 0 : _d.enabled);
4221
- if (carousel) return;
4222
- return x`
4223
- <shipaid-learn-more-carousel
4224
- carousel-state=${this._popup === "learn-more" ? "open" : "close"}
4225
- free-gift=${isFreeGiftEnabled}
4226
- green-protection=${isGreenEnabled}
4227
- >
4228
- </shipaid-learn-more-carousel>
4229
- `;
4443
+ return null;
4230
4444
  }
4231
4445
  confirmationPopupTemplate() {
4232
4446
  return x`
@@ -4806,15 +5020,14 @@ const _ShipAidWidget = class _ShipAidWidget extends s$1 {
4806
5020
  renderPopups() {
4807
5021
  if (this.persistPopup) {
4808
5022
  this._popup = this.shouldPersistPopup();
4809
- if (this._popup === "learn-more" && !this._pendingLearnMoreSource) {
4810
- this._pendingLearnMoreSource = "shipaid-widget";
5023
+ if (this._popup === "learn-more") {
5024
+ openCarousel("shipaid-widget");
5025
+ this._popup = null;
4811
5026
  }
4812
5027
  }
4813
5028
  switch (this._popup) {
4814
5029
  case "confirmation":
4815
5030
  return this.confirmationPopupTemplate();
4816
- case "learn-more":
4817
- return this.learnMorePopupTemplate();
4818
5031
  default:
4819
5032
  return null;
4820
5033
  }
@@ -4959,57 +5172,103 @@ const _ShipAidWidget = class _ShipAidWidget extends s$1 {
4959
5172
  await use(this.lang);
4960
5173
  this.hasLoadedStrings = true;
4961
5174
  this.fetchInterceptorCleanup = interceptFetch(async (args, promise) => {
4962
- var _a, _b, _c, _d;
5175
+ var _a, _b;
4963
5176
  if ((_b = (_a = args[1]) == null ? void 0 : _a.headers) == null ? void 0 : _b["X-ShipAid"]) {
4964
5177
  return;
4965
5178
  }
4966
5179
  if (!args[0].startsWith("/cart/change") && !args[0].startsWith("/cart/update")) {
4967
5180
  return;
4968
5181
  }
4969
- const buttonSelector = ((_d = (_c = this._store) == null ? void 0 : _c.widgetConfigurations) == null ? void 0 : _d.checkoutButtonSelector) || 'button[type="submit"][name="checkout"][form="cart"]';
4970
- const button = document.querySelector(buttonSelector);
4971
- console.log("q", button);
4972
- if (!button) {
5182
+ if (this._isUpdatingShipAid) {
4973
5183
  return;
4974
5184
  }
4975
- button.setAttribute("disabled", "true");
4976
- console.debug("button", "t");
4977
5185
  try {
5186
+ this._isUpdatingShipAid = true;
5187
+ this._disableCheckoutButtons();
4978
5188
  await promise;
4979
5189
  await this.updateCart();
4980
- await this.updateProtection();
5190
+ await this.updateProtection(true);
5191
+ } catch (error) {
5192
+ console.error("[ShipAid] Interceptor error:", error);
4981
5193
  } finally {
4982
- button.removeAttribute("disabled");
4983
- console.debug("button", "f");
5194
+ this._isUpdatingShipAid = false;
5195
+ this._enableCheckoutButtons();
4984
5196
  }
4985
5197
  });
5198
+ try {
5199
+ document.addEventListener(EXTERNAL_EVENTS.CART_UPDATE, this._onShipAidCartEvent);
5200
+ } catch {
5201
+ }
5202
+ try {
5203
+ window.addEventListener(EXTERNAL_EVENTS.CART_UPDATE, this._onShipAidCartEvent);
5204
+ } catch {
5205
+ }
5206
+ try {
5207
+ document.addEventListener(SHIPAID_EVENTS.CART_UPDATED, this._onShipAidInternalCartUpdated);
5208
+ } catch {
5209
+ }
4986
5210
  }
4987
5211
  disconnectedCallback() {
4988
5212
  var _a;
4989
5213
  super.disconnectedCallback();
4990
5214
  (_a = this.fetchInterceptorCleanup) == null ? void 0 : _a.call(this);
5215
+ try {
5216
+ document.removeEventListener(EXTERNAL_EVENTS.CART_UPDATE, this._onShipAidCartEvent);
5217
+ } catch {
5218
+ }
5219
+ try {
5220
+ window.removeEventListener(EXTERNAL_EVENTS.CART_UPDATE, this._onShipAidCartEvent);
5221
+ } catch {
5222
+ }
5223
+ try {
5224
+ document.removeEventListener(SHIPAID_EVENTS.CART_UPDATED, this._onShipAidInternalCartUpdated);
5225
+ } catch {
5226
+ }
4991
5227
  }
4992
- async updateProtection() {
4993
- var _a, _b, _c, _d;
5228
+ async updateProtection(force = false) {
5229
+ var _a, _b, _c;
4994
5230
  this._cartLastUpdated = /* @__PURE__ */ new Date();
4995
5231
  if (!((_a = this._cart) == null ? void 0 : _a.items)) return;
4996
- const protectionCartItemIndex = (_b = this._cart.items) == null ? void 0 : _b.findIndex((item) => {
5232
+ if (this._isUpdatingShipAid && !force) {
5233
+ return;
5234
+ }
5235
+ const allProtectionItems = this._cart.items.filter((item) => {
4997
5236
  var _a2, _b2;
4998
5237
  return (_b2 = (_a2 = this._protectionProduct) == null ? void 0 : _a2.variants) == null ? void 0 : _b2.some(
4999
5238
  (variant) => variant.id === item.variant_id
5000
5239
  );
5001
5240
  });
5002
- const protectionCartItem = (_c = this._cart) == null ? void 0 : _c.items[protectionCartItemIndex];
5241
+ if (allProtectionItems.length > 1) {
5242
+ try {
5243
+ this._isUpdatingShipAid = true;
5244
+ this._disableCheckoutButtons();
5245
+ for (let i3 = 1; i3 < allProtectionItems.length; i3++) {
5246
+ await this.updateCartProtectionVariant(0, allProtectionItems[i3]);
5247
+ await new Promise((resolve) => setTimeout(resolve, 100));
5248
+ }
5249
+ this._cart = await this._fetchCart();
5250
+ } finally {
5251
+ this._isUpdatingShipAid = false;
5252
+ this._enableCheckoutButtons();
5253
+ }
5254
+ }
5255
+ const protectionCartItemIndex = ((_b = this._cart.items) == null ? void 0 : _b.findIndex((item) => {
5256
+ var _a2, _b2;
5257
+ return (_b2 = (_a2 = this._protectionProduct) == null ? void 0 : _a2.variants) == null ? void 0 : _b2.some(
5258
+ (variant) => variant.id === item.variant_id
5259
+ );
5260
+ })) ?? -1;
5261
+ const protectionCartItem = protectionCartItemIndex >= 0 && this._cart.items ? this._cart.items[protectionCartItemIndex] : void 0;
5003
5262
  this._hasProtectionInCart = !!protectionCartItem;
5004
5263
  if (!this._store) return;
5005
5264
  const protectionFee = await this.calculateProtectionTotal(this._cart);
5006
5265
  if (this._cart.item_count > 0 && !!protectionCartItem && (this._cart.total_price === (protectionCartItem == null ? void 0 : protectionCartItem.final_line_price) || !protectionFee)) {
5007
- const cart2 = await this.updateCartProtectionVariant(
5266
+ const cart = await this.updateCartProtectionVariant(
5008
5267
  0,
5009
5268
  protectionCartItem
5010
5269
  );
5011
5270
  sessionStorage.removeItem(LOCAL_STORAGE_KEY);
5012
- return await this._handleRefresh(cart2);
5271
+ return await this._handleRefresh(cart);
5013
5272
  }
5014
5273
  const protectionVariant = this._findProtectionVariant(protectionFee);
5015
5274
  if (!protectionFee) {
@@ -5026,7 +5285,7 @@ const _ShipAidWidget = class _ShipAidWidget extends s$1 {
5026
5285
  logger.error("No matching protection variant found.");
5027
5286
  return;
5028
5287
  }
5029
- if (!((_d = this._protectionVariant) == null ? void 0 : _d.id)) {
5288
+ if (!((_c = this._protectionVariant) == null ? void 0 : _c.id)) {
5030
5289
  this._shouldShowWidget = false;
5031
5290
  return;
5032
5291
  }
@@ -5034,7 +5293,7 @@ const _ShipAidWidget = class _ShipAidWidget extends s$1 {
5034
5293
  this._sellingPlanId = await this.getSubscription(this._cart);
5035
5294
  }
5036
5295
  if (!protectionCartItem) return;
5037
- if (this.supportSubscriptions && !this.useShipAidCheckout) {
5296
+ if (this.supportSubscriptions && !this.useShipAidCheckout && this._cart.items) {
5038
5297
  const itemWithSubscription = this._cart.items.find(
5039
5298
  (item) => {
5040
5299
  var _a2;
@@ -5050,38 +5309,60 @@ const _ShipAidWidget = class _ShipAidWidget extends s$1 {
5050
5309
  shouldUpdateSubscription = false;
5051
5310
  }
5052
5311
  if (shouldUpdateSubscription) {
5053
- const cart2 = await this.updateCartProtectionVariant(
5054
- 1,
5055
- protectionCartItem
5056
- );
5057
- await this._handleRefresh(cart2);
5312
+ try {
5313
+ this._isUpdatingShipAid = true;
5314
+ this._disableCheckoutButtons();
5315
+ const cart = await this.updateCartProtectionVariant(
5316
+ 1,
5317
+ protectionCartItem
5318
+ );
5319
+ await this._handleRefresh(cart);
5320
+ } finally {
5321
+ this._isUpdatingShipAid = false;
5322
+ this._enableCheckoutButtons();
5323
+ }
5058
5324
  }
5059
5325
  }
5060
- if (protectionVariant.id === protectionCartItem.variant_id) {
5326
+ if (protectionCartItem && protectionVariant.id === protectionCartItem.variant_id) {
5061
5327
  this._protectionCartItem = {
5062
5328
  ...protectionCartItem,
5063
5329
  index: protectionCartItemIndex,
5064
5330
  position: protectionCartItemIndex + 1
5065
5331
  };
5066
5332
  if (protectionCartItem.quantity === 1) return;
5067
- const cart2 = await this.updateCartProtectionVariant(
5068
- 1,
5069
- protectionCartItem
5333
+ try {
5334
+ this._isUpdatingShipAid = true;
5335
+ this._disableCheckoutButtons();
5336
+ const cart = await this.updateCartProtectionVariant(
5337
+ 1,
5338
+ protectionCartItem
5339
+ );
5340
+ this._handleRefreshCart();
5341
+ await this._handleRefresh(cart);
5342
+ } finally {
5343
+ this._isUpdatingShipAid = false;
5344
+ this._enableCheckoutButtons();
5345
+ }
5346
+ return;
5347
+ }
5348
+ try {
5349
+ this._isUpdatingShipAid = true;
5350
+ this._disableCheckoutButtons();
5351
+ const updatePayload = {
5352
+ updates: {
5353
+ [protectionCartItem.variant_id]: 0,
5354
+ [protectionVariant.id]: 1
5355
+ }
5356
+ };
5357
+ const cart = await this._fetch.post(
5358
+ "/cart/update.js",
5359
+ updatePayload
5070
5360
  );
5071
- this._handleRefreshCart();
5072
- return await this._handleRefresh(cart2);
5361
+ await this.updateCart(cart, { dispatchExternalEvents: true });
5362
+ } finally {
5363
+ this._isUpdatingShipAid = false;
5364
+ this._enableCheckoutButtons();
5073
5365
  }
5074
- const updatePayload = {
5075
- updates: {
5076
- [protectionCartItem.variant_id]: 0,
5077
- [protectionVariant.id]: 1
5078
- }
5079
- };
5080
- const cart = await this._fetch.post(
5081
- "/cart/update.js",
5082
- updatePayload
5083
- );
5084
- await this._handleRefresh(cart);
5085
5366
  }
5086
5367
  render() {
5087
5368
  useOnce(this, async () => {
@@ -5139,6 +5420,7 @@ const _ShipAidWidget = class _ShipAidWidget extends s$1 {
5139
5420
  return;
5140
5421
  }
5141
5422
  this._hasFinishedSetup = true;
5423
+ ensureLearnMoreCarousel(this._store);
5142
5424
  this._dispatchEvent(SHIPAID_EVENTS.LOADED, this._store);
5143
5425
  setTimeout(async () => {
5144
5426
  var _a2, _b2, _c2, _d2;
@@ -5200,24 +5482,6 @@ const _ShipAidWidget = class _ShipAidWidget extends s$1 {
5200
5482
  this,
5201
5483
  () => {
5202
5484
  D(this.renderPopups(), document.body);
5203
- if (this._popup === "learn-more") {
5204
- const source = this._pendingLearnMoreSource ?? "shipaid-widget";
5205
- this._pendingLearnMoreSource = null;
5206
- requestAnimationFrame(() => {
5207
- try {
5208
- window.dispatchEvent(
5209
- new CustomEvent(SHIPAID_EVENTS.LEARN_MORE_OPENED, {
5210
- detail: { source }
5211
- })
5212
- );
5213
- } catch (error) {
5214
- const message = error instanceof Error ? error.message : String(error);
5215
- logger.error(`Failed to open ShipAid learn more carousel: ${message}`);
5216
- }
5217
- });
5218
- } else {
5219
- this._pendingLearnMoreSource = null;
5220
- }
5221
5485
  },
5222
5486
  [this._popup]
5223
5487
  );
@@ -5851,74 +6115,8 @@ class ShipAidCheckoutPlus extends s$1 {
5851
6115
  }
5852
6116
  async _refreshShopifyCartUI() {
5853
6117
  try {
5854
- const sectionIds = ["cart-drawer", "cart-icon-bubble", "main-cart-items"];
5855
- const url = `/?sections=${encodeURIComponent(sectionIds.join(","))}`;
5856
- const res = await fetch(url, { credentials: "same-origin" });
5857
- if (!res.ok) return;
5858
- const htmlById = await res.json().catch(() => null);
5859
- if (!htmlById || typeof htmlById !== "object") return;
5860
6118
  this._isReplacingCartSections = true;
5861
- for (const id of Object.keys(htmlById)) {
5862
- const html2 = htmlById[id];
5863
- if (typeof html2 !== "string") continue;
5864
- const tmp = document.createElement("div");
5865
- tmp.innerHTML = html2;
5866
- if (id === "cart-drawer") {
5867
- try {
5868
- const newDrawer = tmp.querySelector("cart-drawer");
5869
- const oldDrawer = document.querySelector("cart-drawer");
5870
- if (newDrawer && oldDrawer) {
5871
- const shouldBeEmpty = newDrawer.classList.contains("is-empty");
5872
- if (shouldBeEmpty) oldDrawer.classList.add("is-empty");
5873
- else oldDrawer.classList.remove("is-empty");
5874
- }
5875
- } catch {
5876
- }
5877
- try {
5878
- const newDrawerItems = tmp.querySelector("cart-drawer-items");
5879
- const oldDrawerItems = document.querySelector("cart-drawer cart-drawer-items, .cart-drawer cart-drawer-items");
5880
- if (newDrawerItems && oldDrawerItems) {
5881
- oldDrawerItems.outerHTML = newDrawerItems.outerHTML;
5882
- }
5883
- } catch {
5884
- }
5885
- const newItems = tmp.querySelector("#CartDrawer-CartItems");
5886
- const oldItems = document.getElementById("CartDrawer-CartItems");
5887
- if (newItems && oldItems) {
5888
- oldItems.outerHTML = newItems.outerHTML;
5889
- }
5890
- const newFooter = tmp.querySelector(".cart-drawer__footer");
5891
- const oldFooter = document.querySelector(".cart-drawer .cart-drawer__footer");
5892
- if (newFooter && oldFooter) {
5893
- oldFooter.outerHTML = newFooter.outerHTML;
5894
- }
5895
- const newCtas = tmp.querySelector(".cart__ctas");
5896
- const oldCtas = document.querySelector(".cart-drawer .cart__ctas");
5897
- if (newCtas && oldCtas) {
5898
- oldCtas.outerHTML = newCtas.outerHTML;
5899
- }
5900
- continue;
5901
- }
5902
- if (id === "main-cart-items") {
5903
- const newMainItems = tmp.querySelector("#main-cart-items");
5904
- const oldMainItems = document.getElementById("main-cart-items");
5905
- if (newMainItems && oldMainItems) {
5906
- oldMainItems.outerHTML = newMainItems.outerHTML;
5907
- } else {
5908
- const section = document.getElementById("shopify-section-main-cart-items");
5909
- if (section) section.outerHTML = html2;
5910
- }
5911
- continue;
5912
- }
5913
- if (id === "cart-icon-bubble") {
5914
- const newBubble = tmp.querySelector("#cart-icon-bubble, [data-cart-count-bubble]");
5915
- const oldBubble = document.querySelector("#cart-icon-bubble, [data-cart-count-bubble]");
5916
- if (newBubble && oldBubble) {
5917
- oldBubble.replaceWith(newBubble);
5918
- }
5919
- continue;
5920
- }
5921
- }
6119
+ await refreshShopifyCartUI();
5922
6120
  } catch {
5923
6121
  } finally {
5924
6122
  this._isReplacingCartSections = false;
@@ -5983,19 +6181,7 @@ class ShipAidCheckoutPlus extends s$1 {
5983
6181
  }
5984
6182
  }
5985
6183
  _ensureLearnMoreCarousel() {
5986
- var _a, _b, _c, _d;
5987
- try {
5988
- const existing = document.querySelector("shipaid-learn-more-carousel");
5989
- if (existing) return;
5990
- const el = document.createElement("shipaid-learn-more-carousel");
5991
- const isGreenEnabled = Boolean((_b = (_a = this._store) == null ? void 0 : _a.greenProtection) == null ? void 0 : _b.enabled);
5992
- const isFreeGiftEnabled = Boolean((_d = (_c = this._store) == null ? void 0 : _c.freeGifts) == null ? void 0 : _d.enabled);
5993
- if (isGreenEnabled) el.setAttribute("green-protection", "true");
5994
- if (isFreeGiftEnabled) el.setAttribute("free-gift", "true");
5995
- el.setAttribute("carousel-state", "close");
5996
- document.body.appendChild(el);
5997
- } catch {
5998
- }
6184
+ ensureLearnMoreCarousel(this._store);
5999
6185
  }
6000
6186
  _shouldShowWidget() {
6001
6187
  var _a;
@@ -6004,7 +6190,6 @@ class ShipAidCheckoutPlus extends s$1 {
6004
6190
  console.warn("[ShipAid] Plan is not active, skipping widget mount");
6005
6191
  return false;
6006
6192
  }
6007
- if (!this._hasCheckoutButtons) return false;
6008
6193
  return ((_a = this._store.checkoutPlus) == null ? void 0 : _a.enabled) === true;
6009
6194
  }
6010
6195
  updated(changed) {
@@ -6201,6 +6386,7 @@ class ShipAidCheckoutPlus extends s$1 {
6201
6386
  this._hasCheckoutButtons = false;
6202
6387
  return;
6203
6388
  }
6389
+ this._hasCheckoutButtons = true;
6204
6390
  if (this.isClone) {
6205
6391
  const target = matches[0];
6206
6392
  this._originalCheckoutButton = target;
@@ -6599,7 +6785,7 @@ class ShipAidCheckoutPlus extends s$1 {
6599
6785
  }
6600
6786
  render() {
6601
6787
  var _a, _b, _c, _d, _e;
6602
- if (!this._hasFinishedSetup || !this._shouldShowWidget()) return A;
6788
+ if (!this._hasFinishedSetup || !this._shouldShowWidget() || !this._hasCheckoutButtons) return A;
6603
6789
  const isGreen = Boolean((_b = (_a = this._store) == null ? void 0 : _a.greenProtection) == null ? void 0 : _b.enabled);
6604
6790
  const isFreeGiftEnabled = Boolean((_d = (_c = this._store) == null ? void 0 : _c.freeGifts) == null ? void 0 : _d.enabled);
6605
6791
  const iconImg = isGreen || isFreeGiftEnabled ? ShipAidImpactIcon : ShipAidBlueIcon;