PageSourceSearch

https://services.unitedbaristas.com/wp-content/plugins/iwocapay-pa…/includes/cart-banner-pricing.js?ver=1.15.2

js unitedbaristas.com collected 2026-10-04 02:40:34 UTC 5,137 bytes, 136 lines download raw bytes

1// Shared cart-banner pricing engine. Every cart-banner surface (classic cart,
2// classic checkout, block cart/checkout, drag-drop block, shortcode) renders a
3// bare <iwocapay-price-calculator-cart-banner> marker and defers ALL pricing to
4// this one module, so the surfaces can't drift apart (the lesson from Magento's
5// shared cart-pricing module).
6//
7// The marker carries NO price server-side — this fetches the live basket figures
8// client-side, so it's correct under full-page caching and re-renders on cart
9// change. Amounts come back pre-formatted (e.g. "£137.50") from PHP; the
10// component does no maths, it just displays what it's given.
11(function () {
12    var TAG = "iwocapay-price-calculator-cart-banner";
13    var MARKER_ATTR = "data-iwocapay-cart-banner";
14
15    // Fire the view event only once the banner actually intersects the viewport.
16    // A cart banner can sit below the fold or in a collapsed panel — present and
17    // eligible in the DOM long before the customer sees it. The dedup (in-memory
18    // + 24h localStorage) lives in fireIwocapayBannerEvent, so this only gates on
19    // visibility. Falls back to firing immediately where IO is unavailable.
20    var viewObserver =
21        typeof window.IntersectionObserver !== "undefined"
22            ? new window.IntersectionObserver(function (entries, observer) {
23                  entries.forEach(function (entry) {
24                      if (entry.isIntersecting) {
25                          observer.unobserve(entry.target);
26                          fireView();
27                      }
28                  });
29              })
30            : null;
31
32    function fireView() {
33        if (window.fireIwocapayBannerEvent) {
34            window.fireIwocapayBannerEvent("CUSTOMER_VIEWED_CART_BANNER", {
35                isDeprecated: false,
36            });
37        }
38    }
39
40    function observeForView(el) {
41        if (viewObserver) {
42            viewObserver.observe(el);
43        } else {
44            fireView();
45        }
46    }
47
48    // Ensure the marker holds exactly one banner element to feed attributes into.
49    function ensureBanner(marker) {
50        var banner = marker.querySelector(TAG);
51        if (!banner) {
52            banner = document.createElement(TAG);
53            marker.appendChild(banner);
54        }
55        return banner;
56    }
57
58    function applyPricing(marker, data) {
59        // Ineligible (out of the £150–£30k band, no enabled terms, or an
60        // unavailable cart) — hide the whole marker, leave nothing half-rendered.
61        if (!data || !data.eligible || !data.terms || !data.terms.length) {
62            marker.style.display = "none";
63            return;
64        }
65
66        var banner = ensureBanner(marker);
67        banner.setAttribute("theme", data.theme || "dark");
68        banner.setAttribute("includes-vat", data.includes_vat ? "true" : "false");
69
70        data.terms.forEach(function (term) {
71            // "3_months" -> "3-months" for the paired amount/interest attributes.
72            var suffix = term.duration.replace(/_/g, "-");
73            banner.setAttribute("amount-" + suffix, term.amount);
74            banner.setAttribute("interest-" + suffix, term.interest);
75        });
76
77        marker.style.display = "";
78        observeForView(banner);
79    }
80
81    function render(marker) {
82        if (!marker || !window.iwocapayCartBanner || !window.jQuery) {
83            return;
84        }
85
86        window.jQuery.ajax({
87            url: window.iwocapayCartBanner.ajaxUrl,
88            type: "POST",
89            data: { action: "get_cart_banner_pricing" },
90            dataType: "json",
91            success: function (data) {
92                applyPricing(marker, data);
93            },
94            error: function () {
95                marker.style.display = "none";
96            },
97        });
98    }
99
100    function renderAll() {
101        var markers = document.querySelectorAll("[" + MARKER_ATTR + "]");
102        Array.prototype.forEach.call(markers, render);
103    }
104
105    // Exposed so the block SlotFill can render a marker it inserts into the React
106    // tree, and re-render it on the block cart store's totals changes.
107    window.iwocapayCartBannerRender = render;
108    window.iwocapayCartBannerRenderAll = renderAll;
109
110    // updated_checkout fires on many classic-checkout interactions (address,
111    // shipping method, payment-method select), not just total changes — debounce
112    // so a burst collapses into a single re-fetch instead of one roundtrip each.
113    function debounce(fn, wait) {
114        var timer;
115        return function () {
116            clearTimeout(timer);
117            timer = setTimeout(fn, wait);
118        };
119    }
120
121    function init() {
122        renderAll();
123        if (window.jQuery) {
124            // Classic cart/checkout re-render on the standard WooCommerce cart events.
125            window
126                .jQuery(document.body)
127                .on("updated_cart_totals wc_cart_emptied updated_checkout", debounce(renderAll, 300));
128        }
129    }
130
131    if (document.readyState === "loading") {
132        document.addEventListener("DOMContentLoaded", init);
133    } else {
134        init();
135    }
136})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.