@lime-bundles/widget 4.1.0 → 4.1.1
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/index.cjs +148 -53
- package/dist/index.d.cts +7 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +126 -27
- package/dist/lime-bundle.global.js +18 -18
- package/dist/lime-bundle.global.js.map +1 -1
- package/docs/hydrogen.md +28 -3
- package/docs/react-nextjs.md +23 -3
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -508,7 +508,7 @@ function buildWidgetShell(typeClass, opts) {
|
|
|
508
508
|
"data-countdown": ""
|
|
509
509
|
});
|
|
510
510
|
const label2 = box("span", "lb-bundle-countdown-label");
|
|
511
|
-
label2.textContent = opts.countdownLabel ?? "
|
|
511
|
+
label2.textContent = opts.countdownLabel ?? "Limited time offer";
|
|
512
512
|
countdown.appendChild(label2);
|
|
513
513
|
countdown.appendChild(
|
|
514
514
|
box("span", "lb-bundle-countdown-timer", {
|
|
@@ -520,10 +520,12 @@ function buildWidgetShell(typeClass, opts) {
|
|
|
520
520
|
const products = box("div", typeClass + "__products lb-edge-fade");
|
|
521
521
|
root.appendChild(products);
|
|
522
522
|
root.appendChild(box("div", "lb-bundle-divider"));
|
|
523
|
-
const summary = box("div", "lb-bundle-summary"
|
|
523
|
+
const summary = box("div", "lb-bundle-summary", {
|
|
524
|
+
"data-pricing-section": ""
|
|
525
|
+
});
|
|
524
526
|
const text = box("div", "lb-bundle-summary__text");
|
|
525
527
|
const label = box("span", "lb-bundle-summary__label");
|
|
526
|
-
label.textContent = opts.summaryLabel ?? "Bundle
|
|
528
|
+
label.textContent = opts.summaryLabel ?? "Bundle total";
|
|
527
529
|
text.appendChild(label);
|
|
528
530
|
if (opts.withItemCount) {
|
|
529
531
|
label.appendChild(box("span", "", { "data-item-count": "" }));
|
|
@@ -554,6 +556,7 @@ function buildWidgetShell(typeClass, opts) {
|
|
|
554
556
|
summary.appendChild(prices);
|
|
555
557
|
root.appendChild(summary);
|
|
556
558
|
const cta = box("button", "lb-bundle-cta", {
|
|
559
|
+
"data-cta-text": opts.ctaText,
|
|
557
560
|
type: "button",
|
|
558
561
|
"data-add-bundle": ""
|
|
559
562
|
});
|
|
@@ -572,7 +575,9 @@ function buildWidgetShell(typeClass, opts) {
|
|
|
572
575
|
);
|
|
573
576
|
return { root, products, cta };
|
|
574
577
|
}
|
|
575
|
-
function buildVolumeTiers(tiers, groupLabel) {
|
|
578
|
+
function buildVolumeTiers(tiers, groupLabel, opts = {}) {
|
|
579
|
+
const showCompare = opts.showCompare !== false;
|
|
580
|
+
const showPriceEach = opts.showPriceEach !== false;
|
|
576
581
|
const group = box("div", "lb-volume__tiers lb-edge-fade", {
|
|
577
582
|
role: "radiogroup",
|
|
578
583
|
"aria-label": groupLabel,
|
|
@@ -597,8 +602,17 @@ function buildVolumeTiers(tiers, groupLabel) {
|
|
|
597
602
|
label.textContent = tier.label;
|
|
598
603
|
info.appendChild(label);
|
|
599
604
|
const price = box("span", "lb-volume__tier-price");
|
|
600
|
-
|
|
601
|
-
|
|
605
|
+
if (showCompare && (tier.percent > 0 || tier.amountCents > 0)) {
|
|
606
|
+
price.appendChild(box("span", "lb-volume__tier-compare"));
|
|
607
|
+
}
|
|
608
|
+
if (showPriceEach) {
|
|
609
|
+
price.appendChild(box("span", "", { "data-tier-price-each": "" }));
|
|
610
|
+
if (opts.unitLabel) {
|
|
611
|
+
const unit = box("span", "lb-volume__tier-unit");
|
|
612
|
+
unit.textContent = opts.unitLabel;
|
|
613
|
+
price.appendChild(unit);
|
|
614
|
+
}
|
|
615
|
+
}
|
|
602
616
|
info.appendChild(price);
|
|
603
617
|
el2.appendChild(info);
|
|
604
618
|
if (tier.badgeLabel || tier.savingsLabel) {
|
|
@@ -707,7 +721,10 @@ var DEFAULT_STRINGS = {
|
|
|
707
721
|
required: "Required",
|
|
708
722
|
soldOut: "Sold out",
|
|
709
723
|
outOfStock: "Out of stock",
|
|
710
|
-
itemsOutOfStock:
|
|
724
|
+
itemsOutOfStock: {
|
|
725
|
+
one: "__COUNT__ item out of stock",
|
|
726
|
+
other: "__COUNT__ items out of stock"
|
|
727
|
+
},
|
|
711
728
|
quantity: "Quantity",
|
|
712
729
|
increaseQuantity: "Increase quantity",
|
|
713
730
|
decreaseQuantity: "Decrease quantity",
|
|
@@ -727,11 +744,26 @@ var DEFAULT_STRINGS = {
|
|
|
727
744
|
stepsCompleted: "__COUNT__ of __TOTAL__ steps completed",
|
|
728
745
|
each: " each",
|
|
729
746
|
buyQty: "Buy __COUNT__",
|
|
747
|
+
itemCount: {
|
|
748
|
+
one: "__COUNT__ item",
|
|
749
|
+
other: "__COUNT__ items"
|
|
750
|
+
},
|
|
730
751
|
needsSpots: {
|
|
731
752
|
one: "Needs __COUNT__ spot",
|
|
732
753
|
other: "Needs __COUNT__ spots"
|
|
733
754
|
}
|
|
734
755
|
};
|
|
756
|
+
function formatItemsOutOfStock(t, count) {
|
|
757
|
+
const raw = t.itemsOutOfStock;
|
|
758
|
+
let tpl;
|
|
759
|
+
if (raw && typeof raw === "object") {
|
|
760
|
+
const form = new Intl.PluralRules(t.locale || "en").select(count);
|
|
761
|
+
tpl = raw[form] || raw.other;
|
|
762
|
+
} else {
|
|
763
|
+
tpl = raw;
|
|
764
|
+
}
|
|
765
|
+
return (tpl || "__COUNT__ items out of stock").split("__COUNT__").join(String(count));
|
|
766
|
+
}
|
|
735
767
|
|
|
736
768
|
// ../render/src/dropdown/bind.ts
|
|
737
769
|
import { dropdown } from "@lime-bundles/core";
|
|
@@ -1188,7 +1220,7 @@ function renderFixedBundle(container, bundle, outOfStockBehavior, onAddToCart, o
|
|
|
1188
1220
|
shell.cta.disabled = true;
|
|
1189
1221
|
const label = shell.cta.querySelector("[data-cta-label]");
|
|
1190
1222
|
if (label) {
|
|
1191
|
-
label.textContent = (t
|
|
1223
|
+
label.textContent = formatItemsOutOfStock(t, oosProducts.length);
|
|
1192
1224
|
}
|
|
1193
1225
|
} else {
|
|
1194
1226
|
shell.cta.addEventListener("click", () => {
|
|
@@ -2553,17 +2585,17 @@ function buildPickerModal(opts) {
|
|
|
2553
2585
|
}
|
|
2554
2586
|
|
|
2555
2587
|
// src/renderers/mix-match.ts
|
|
2556
|
-
function renderMixMatchBundle(container, bundle, outOfStockBehavior, onAddToCart, onCleanup) {
|
|
2588
|
+
function renderMixMatchBundle(container, bundle, outOfStockBehavior, onAddToCart, onCleanup, currentProductHandle) {
|
|
2557
2589
|
const wc = bundle.widgetConfig;
|
|
2558
2590
|
const t = DEFAULT_STRINGS;
|
|
2559
2591
|
const requiredQty = bundle.minQuantity || 1;
|
|
2560
2592
|
const rulesMap = mergeRuleMaps(bundle.productRules, bundle.variantRules);
|
|
2561
2593
|
const adapted = adaptProducts(bundle);
|
|
2562
|
-
const eligibleProducts = adapted.map((p) => ({
|
|
2594
|
+
const eligibleProducts = adapted.map((p, i) => ({
|
|
2563
2595
|
id: Number(p.productId),
|
|
2564
2596
|
title: p.title ?? "",
|
|
2565
2597
|
url: p.url ?? null,
|
|
2566
|
-
type: "",
|
|
2598
|
+
type: bundle.products[i]?.productType ?? "",
|
|
2567
2599
|
featuredImage: p.featuredImage ?? null,
|
|
2568
2600
|
available: p.variants.some((v) => v.available),
|
|
2569
2601
|
optionNames: p.optionNames,
|
|
@@ -2608,16 +2640,21 @@ function renderMixMatchBundle(container, bundle, outOfStockBehavior, onAddToCart
|
|
|
2608
2640
|
const overlay = buildPickerModal({
|
|
2609
2641
|
bundleGid: bundle.id,
|
|
2610
2642
|
domId: bundle.id.replace(/\D/g, ""),
|
|
2611
|
-
showSearch:
|
|
2612
|
-
showTypeFilters: false,
|
|
2643
|
+
showSearch: wc.showSearch !== false,
|
|
2644
|
+
showTypeFilters: wc.mixMatchShowTypeFilters !== false,
|
|
2613
2645
|
segmentCount: requiredQty,
|
|
2614
2646
|
wizard: false
|
|
2615
2647
|
});
|
|
2616
2648
|
shell.root.appendChild(overlay);
|
|
2649
|
+
const currentIdx = currentProductHandle ? bundle.products.findIndex((p) => p.handle === currentProductHandle) : -1;
|
|
2617
2650
|
const selectedItems = seedSelection(
|
|
2618
2651
|
eligibleProducts,
|
|
2619
2652
|
rulesMap,
|
|
2620
|
-
requiredQty
|
|
2653
|
+
requiredQty,
|
|
2654
|
+
{
|
|
2655
|
+
enabled: !!currentProductHandle,
|
|
2656
|
+
currentProductId: currentIdx !== -1 ? eligibleProducts[currentIdx]?.id ?? null : null
|
|
2657
|
+
}
|
|
2621
2658
|
);
|
|
2622
2659
|
const rowCapacity = {
|
|
2623
2660
|
remainingSpots: () => remainingUnits(selectedItems, requiredQty),
|
|
@@ -2654,7 +2691,13 @@ function renderMixMatchBundle(container, bundle, outOfStockBehavior, onAddToCart
|
|
|
2654
2691
|
shell.root,
|
|
2655
2692
|
selectedItems,
|
|
2656
2693
|
requiredQty,
|
|
2657
|
-
|
|
2694
|
+
// The shared updater reads the theme data-block shape: discount fields
|
|
2695
|
+
// flat, not nested under discountConfig. Passing the bundle itself left
|
|
2696
|
+
// `discountType` undefined, so the summary never painted.
|
|
2697
|
+
{
|
|
2698
|
+
discountType: bundle.discountConfig.discountType,
|
|
2699
|
+
discountValue: bundle.discountConfig.discountValue
|
|
2700
|
+
},
|
|
2658
2701
|
(total, type, value) => calculateDiscount(total, type, value),
|
|
2659
2702
|
updatePricing2(formatMoney)
|
|
2660
2703
|
);
|
|
@@ -2667,7 +2710,7 @@ function renderMixMatchBundle(container, bundle, outOfStockBehavior, onAddToCart
|
|
|
2667
2710
|
rulesMap,
|
|
2668
2711
|
eligibleProducts,
|
|
2669
2712
|
requiredQty,
|
|
2670
|
-
showQtySelector:
|
|
2713
|
+
showQtySelector: wc.mixMatchShowQuantitySelector !== false,
|
|
2671
2714
|
items: selectedItems,
|
|
2672
2715
|
formatMoney,
|
|
2673
2716
|
rowCapacity,
|
|
@@ -2730,6 +2773,13 @@ function renderMixMatchBundle(container, bundle, outOfStockBehavior, onAddToCart
|
|
|
2730
2773
|
onCleanup?.(bindDropdowns(shell.root));
|
|
2731
2774
|
}
|
|
2732
2775
|
|
|
2776
|
+
// src/renderers/volume.ts
|
|
2777
|
+
import {
|
|
2778
|
+
bestValueTierIndex,
|
|
2779
|
+
resolveDefaultTierIndex,
|
|
2780
|
+
resolvePopularTierIndex
|
|
2781
|
+
} from "@lime-bundles/core";
|
|
2782
|
+
|
|
2733
2783
|
// ../render/src/volume/pricing.ts
|
|
2734
2784
|
function calcTierPrice(basePrice, discountType, tierEl) {
|
|
2735
2785
|
if (discountType === "fixed_amount") {
|
|
@@ -2758,6 +2808,23 @@ function formatItemCount(qty, translations) {
|
|
|
2758
2808
|
const tpl = translations.itemCount[form] || translations.itemCount.other || "__COUNT__";
|
|
2759
2809
|
return " (" + tpl.split("__COUNT__").join(String(qty)) + ")";
|
|
2760
2810
|
}
|
|
2811
|
+
function updateAllTierPrices(allTiers, basePrice, discountType, formatMoney) {
|
|
2812
|
+
for (let i = 0; i < allTiers.length; i++) {
|
|
2813
|
+
const tierEl = allTiers[i];
|
|
2814
|
+
const priceEachEl = tierEl.querySelector(
|
|
2815
|
+
"[data-tier-price-each]"
|
|
2816
|
+
);
|
|
2817
|
+
if (priceEachEl) {
|
|
2818
|
+
priceEachEl.textContent = formatMoney(
|
|
2819
|
+
calcTierPrice(basePrice, discountType, tierEl)
|
|
2820
|
+
);
|
|
2821
|
+
}
|
|
2822
|
+
const compareEl = tierEl.querySelector(
|
|
2823
|
+
".lb-volume__tier-compare"
|
|
2824
|
+
);
|
|
2825
|
+
if (compareEl) compareEl.textContent = formatMoney(basePrice);
|
|
2826
|
+
}
|
|
2827
|
+
}
|
|
2761
2828
|
function selectTier(container, allTiers, basePrice, discountType, index, translations, formatMoney) {
|
|
2762
2829
|
for (let i = 0; i < allTiers.length; i++) {
|
|
2763
2830
|
allTiers[i].setAttribute("aria-checked", i === index ? "true" : "false");
|
|
@@ -2815,8 +2882,17 @@ function renderVolumeBundle(container, bundle, outOfStockBehavior, onAddToCart)
|
|
|
2815
2882
|
const discountType = bundle.discountConfig.discountType;
|
|
2816
2883
|
const formatMoney = intlFormatMoney(product.priceRange.minVariantPrice.currencyCode);
|
|
2817
2884
|
const t = DEFAULT_STRINGS;
|
|
2818
|
-
const
|
|
2819
|
-
const defaultIdx =
|
|
2885
|
+
const bestIdx = bestValueTierIndex(bundle.volumeTiers, discountType);
|
|
2886
|
+
const defaultIdx = resolveDefaultTierIndex(
|
|
2887
|
+
wc.defaultTier,
|
|
2888
|
+
bundle.volumeTiers.length,
|
|
2889
|
+
bestIdx
|
|
2890
|
+
);
|
|
2891
|
+
const popularIdx = resolvePopularTierIndex(
|
|
2892
|
+
wc.popularBadge?.tierIndex,
|
|
2893
|
+
wc.popularBadge?.visible !== false,
|
|
2894
|
+
bestIdx
|
|
2895
|
+
);
|
|
2820
2896
|
const tiers = bundle.volumeTiers.map((tier, i) => {
|
|
2821
2897
|
const percent = discountType === "fixed_amount" ? 0 : Math.round(tier.percentage ?? 0);
|
|
2822
2898
|
const amountCents = discountType === "fixed_amount" ? Math.round((tier.amount ?? 0) * 100) : 0;
|
|
@@ -2837,16 +2913,21 @@ function renderVolumeBundle(container, bundle, outOfStockBehavior, onAddToCart)
|
|
|
2837
2913
|
title: bundle.title,
|
|
2838
2914
|
subtitle: bundle.description,
|
|
2839
2915
|
summaryLabel: "Total",
|
|
2840
|
-
withItemCount:
|
|
2916
|
+
withItemCount: wc.pricing?.showItemCount !== false,
|
|
2841
2917
|
totalPriceSlot: true,
|
|
2842
2918
|
showSavingsBar: wc.savingsBar?.visible !== false,
|
|
2843
2919
|
showComparePrice: wc.pricing?.showCompareAtPrice !== false,
|
|
2844
2920
|
ctaText: wc.cta?.ctaText || t.addToCart || "Add to cart",
|
|
2845
2921
|
endsAt: wc.countdown?.showCountdown === false ? null : bundle.endsAt
|
|
2846
2922
|
});
|
|
2847
|
-
const group = buildVolumeTiers(tiers, "Select quantity"
|
|
2923
|
+
const group = buildVolumeTiers(tiers, "Select quantity", {
|
|
2924
|
+
showCompare: wc.pricing?.showComparePrice !== false,
|
|
2925
|
+
showPriceEach: wc.pricing?.showPerUnitPrice !== false,
|
|
2926
|
+
unitLabel: (t.each || "each").trim()
|
|
2927
|
+
});
|
|
2848
2928
|
shell.products.replaceWith(group);
|
|
2849
2929
|
const tierEls = group.querySelectorAll("[data-tier-index]");
|
|
2930
|
+
updateAllTierPrices(tierEls, basePrice, discountType, formatMoney);
|
|
2850
2931
|
let selectedIndex = defaultIdx;
|
|
2851
2932
|
const apply = () => selectTier(shell.root, tierEls, basePrice, discountType, selectedIndex, t, formatMoney);
|
|
2852
2933
|
group.addEventListener("click", (e) => {
|
|
@@ -2996,6 +3077,13 @@ function buildBogoCartItems(sides, percent, buyQty, getQty) {
|
|
|
2996
3077
|
}
|
|
2997
3078
|
|
|
2998
3079
|
// src/renderers/bogo.ts
|
|
3080
|
+
function buildBogoPlus() {
|
|
3081
|
+
const plus = document.createElement("div");
|
|
3082
|
+
plus.className = "lb-bogo__plus";
|
|
3083
|
+
plus.setAttribute("aria-hidden", "true");
|
|
3084
|
+
plus.innerHTML = '<svg width="12" height="12" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><line x1="9" y1="3" x2="9" y2="15" stroke="currentColor" stroke-width="2" stroke-linecap="round"/><line x1="3" y1="9" x2="15" y2="9" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg>';
|
|
3085
|
+
return plus;
|
|
3086
|
+
}
|
|
2999
3087
|
function renderBogoBundle(container, bundle, outOfStockBehavior, onAddToCart, onCleanup) {
|
|
3000
3088
|
const wc = bundle.widgetConfig;
|
|
3001
3089
|
const buyProduct = bundle.products.find((p) => p.id === bundle.buyProductId);
|
|
@@ -3044,6 +3132,7 @@ function renderBogoBundle(container, bundle, outOfStockBehavior, onAddToCart, on
|
|
|
3044
3132
|
const badgeText = percent >= 100 ? "Free" : percent + "% off";
|
|
3045
3133
|
sides.forEach((side, i) => {
|
|
3046
3134
|
const isGet = i === 1;
|
|
3135
|
+
if (isGet) shell.products.appendChild(buildBogoPlus());
|
|
3047
3136
|
const isOos = !side.variants.some((v) => v.available);
|
|
3048
3137
|
const row = buildRowSkeleton(side, t, {
|
|
3049
3138
|
isOos,
|
|
@@ -3072,7 +3161,7 @@ function renderBogoBundle(container, bundle, outOfStockBehavior, onAddToCart, on
|
|
|
3072
3161
|
shell.cta.disabled = true;
|
|
3073
3162
|
const label = shell.cta.querySelector("[data-cta-label]");
|
|
3074
3163
|
if (label) {
|
|
3075
|
-
label.textContent = (t
|
|
3164
|
+
label.textContent = formatItemsOutOfStock(t, oosCount);
|
|
3076
3165
|
}
|
|
3077
3166
|
} else {
|
|
3078
3167
|
shell.cta.addEventListener("click", () => {
|
|
@@ -3798,8 +3887,8 @@ function renderMultiStepBundle(container, bundle, outOfStockBehavior, onAddToCar
|
|
|
3798
3887
|
const overlay = buildPickerModal({
|
|
3799
3888
|
bundleGid: bundle.id,
|
|
3800
3889
|
domId: bundle.id.replace(/\D/g, ""),
|
|
3801
|
-
showSearch:
|
|
3802
|
-
showTypeFilters:
|
|
3890
|
+
showSearch: wc.showSearch !== false,
|
|
3891
|
+
showTypeFilters: wc.mixMatchShowTypeFilters !== false,
|
|
3803
3892
|
segmentCount: null,
|
|
3804
3893
|
wizard: true
|
|
3805
3894
|
});
|
|
@@ -3846,8 +3935,8 @@ function renderMultiStepBundle(container, bundle, outOfStockBehavior, onAddToCar
|
|
|
3846
3935
|
selections,
|
|
3847
3936
|
t,
|
|
3848
3937
|
rulesMap,
|
|
3849
|
-
showQtySelector:
|
|
3850
|
-
showTypeFilters:
|
|
3938
|
+
showQtySelector: wc.mixMatchShowQuantitySelector !== false,
|
|
3939
|
+
showTypeFilters: wc.mixMatchShowTypeFilters !== false,
|
|
3851
3940
|
formatMoney,
|
|
3852
3941
|
dropdown: void 0,
|
|
3853
3942
|
portalTarget: null,
|
|
@@ -6553,6 +6642,13 @@ var LimeBundleElement = class extends HTMLElement {
|
|
|
6553
6642
|
buyer = void 0;
|
|
6554
6643
|
shadow;
|
|
6555
6644
|
bundles = [];
|
|
6645
|
+
/**
|
|
6646
|
+
* The product handle this embed is standing on, when one can be resolved
|
|
6647
|
+
* (attribute → meta tag → /products/<handle> path). The mix-and-match
|
|
6648
|
+
* courtesy seed uses it to pre-add the current product the way the theme
|
|
6649
|
+
* widget does; null on pages with no product context.
|
|
6650
|
+
*/
|
|
6651
|
+
currentProductHandle = null;
|
|
6556
6652
|
abortController = null;
|
|
6557
6653
|
impressionCleanups = [];
|
|
6558
6654
|
/**
|
|
@@ -6672,11 +6768,12 @@ var LimeBundleElement = class extends HTMLElement {
|
|
|
6672
6768
|
try {
|
|
6673
6769
|
let bundlePromise;
|
|
6674
6770
|
let singleBundleMode = false;
|
|
6771
|
+
this.currentProductHandle = resolveProductHandle(this.productHandleAttr);
|
|
6675
6772
|
if (this.bundleGid) {
|
|
6676
6773
|
singleBundleMode = true;
|
|
6677
6774
|
bundlePromise = this.fetchSingleBundle(client, controller.signal);
|
|
6678
6775
|
} else {
|
|
6679
|
-
const handle =
|
|
6776
|
+
const handle = this.currentProductHandle;
|
|
6680
6777
|
if (!handle) {
|
|
6681
6778
|
this.teardownImpressions();
|
|
6682
6779
|
this.renderError(
|
|
@@ -6890,6 +6987,7 @@ var LimeBundleElement = class extends HTMLElement {
|
|
|
6890
6987
|
container.setAttribute("aria-label", bundle.title);
|
|
6891
6988
|
container.setAttribute("data-bundle-type", bundle.bundleType);
|
|
6892
6989
|
container.setAttribute("data-bundle-gid", bundle.id);
|
|
6990
|
+
if (bundle.endsAt) container.setAttribute("data-ends-at", bundle.endsAt);
|
|
6893
6991
|
applyWidgetConfigVars(container, bundle.widgetConfig);
|
|
6894
6992
|
this.renderCleanups.push(trackInputMode(container));
|
|
6895
6993
|
const dispatch = (lines) => this.handleAddToCart(bundle, lines);
|
|
@@ -6910,7 +7008,8 @@ var LimeBundleElement = class extends HTMLElement {
|
|
|
6910
7008
|
bundle,
|
|
6911
7009
|
this.outOfStockBehavior,
|
|
6912
7010
|
dispatch,
|
|
6913
|
-
registerCleanup
|
|
7011
|
+
registerCleanup,
|
|
7012
|
+
this.currentProductHandle
|
|
6914
7013
|
);
|
|
6915
7014
|
break;
|
|
6916
7015
|
case "volume":
|