PageSourceSearch

https://brustersonline.com/BrustersCom/js/gtm.js?v=12

js brustersonline.com collected 2026-09-29 00:16:27 UTC 6,467 bytes, 259 lines download raw bytes

1// gtm.js
2function getStoreNumber() {
3    var query = window.location.search.substring(1);
4    var vars = query.split("&");
5
6    for (var i = 0; i < vars.length; i++) {
7        var pair = vars[i].split("=");
8        if (pair[0] === "number") {
9            var num = parseInt(pair[1], 10);
10            return isNaN(num) ? null : num;
11        }
12    }
13    return null;
14}
15
16function matches(el, selector) {
17    var fn =
18        el.matches ||
19        el.matchesSelector ||
20        el.webkitMatchesSelector ||
21        el.mozMatchesSelector ||
22        el.msMatchesSelector;
23
24    return fn ? fn.call(el, selector) : false;
25}
26
27function closest(el, selector) {
28    while (el) {
29        if (matches(el, selector)) {
30            return el;
31        }
32        el = el.parentElement;
33    }
34    return null;
35}
36
37
38
39
40(function () {
41    window.dataLayer = window.dataLayer || [];
42
43    var DEBUG = true;
44    var TEST_MODE = false;        // 👈 turn on to restrict again
45    var TEST_STORE_NUMBER = 999; // 👈 only allow GTM events for this store
46
47    function pushEvent(payload) {
48        var storeNumber = getStoreNumber();
49
50        // 🚫 Block events for non-test stores
51        if (TEST_MODE && storeNumber !== TEST_STORE_NUMBER) {
52            if (DEBUG && console.debug) {
53                console.debug(
54                    "GTM event blocked (non-test store):",
55                    storeNumber,
56                    payload.event
57                );
58            }
59            return;
60        }
61
62        // Attach store number consistently
63        payload.store_number = storeNumber;
64
65        // Clear previous ecommerce object (GA4 requirement)
66        window.dataLayer.push({ ecommerce: null });
67        window.dataLayer.push(payload);
68
69        if (DEBUG && window.console && console.debug) {
70            console.debug("GTM event pushed:", payload);
71        }
72    }
73
74    window.GTM = {
75        pushEvent: pushEvent
76    };
77})();
78
79
80
81(function () {
82
83    function handleViewItem(e) {
84        var btn = closest(e.target,'[data-item-id]');
85        if (!btn) return;
86
87        if (btn.__gtmViewed) return;
88        btn.__gtmViewed = true;
89
90        var price = parseFloat(btn.dataset.itemPrice || "0");
91        var storeNumber = getStoreNumber();
92
93        window.GTM.pushEvent({
94            event: "view_item",
95
96            // ✅ Store-level metadata
97            store_number: storeNumber,
98
99            ecommerce: {
100                currency: "USD",
101                value: price,
102                items: [{
103                    item_id: btn.dataset.itemId,
104                    item_name: btn.dataset.itemName,
105                    item_category: btn.dataset.sectionName || "",
106                    price: price,
107                    quantity: 1
108                }]
109            }
110        });
111    }
112
113    document.addEventListener("click", handleViewItem, true);
114
115})();
116
117(function () {
118
119    function handleViewCart(e) {
120        var trigger = closest(e.target,'#cartIcon, #checkoutButtonConfirmation');
121        if (!trigger) return;
122
123        if (!cart || cart.length === 0) return;
124
125        var ga4Items = buildGA4ItemsFromCart(cart);
126
127        var totalValue = ga4Items.reduce(function (sum, i) {
128            return sum + (i.price * i.quantity);
129        }, 0);
130
131
132        window.GTM.pushEvent({
133            event: "view_cart",
134            store_number: getStoreNumber(),
135            ecommerce: {
136                currency: "USD",
137                value: +totalValue.toFixed(2),
138                items: ga4Items
139            }
140        });
141    }
142
143    document.addEventListener("click", handleViewCart, true);
144
145})();
146
147(function () {
148
149    function handleBeginCheckout(e) {
150        var btn = closest(e.target,'#checkoutButton');
151        if (!btn) return;
152
153        if (!cart || cart.length === 0) return;
154
155        var ga4Items = buildGA4ItemsFromCart(cart);
156
157        var totalValue = ga4Items.reduce(function (sum, i) {
158            return sum + (i.price * i.quantity);
159        }, 0);
160
161
162        // Optional coupon (only include if you have it)
163        var coupon = "";
164        var couponEl = document.getElementById("discountCode");
165
166        if (couponEl && couponEl.value) {
167            coupon = couponEl.value.trim();
168        }
169
170        if (coupon === "") coupon = null;
171
172
173        var payload = {
174            event: "begin_checkout",
175            store_number: getStoreNumber(),
176            ecommerce: {
177                currency: "USD",
178                value: +totalValue.toFixed(2),
179                items: ga4Items
180            }
181        };
182
183        // GA4 supports coupon at ecommerce level for begin_checkout
184        if (coupon) {
185            payload.ecommerce.coupon = coupon;
186        }
187
188        window.GTM.pushEvent(payload);
189    }
190
191    document.addEventListener("click", handleBeginCheckout, true);
192
193})();
194
195
196function fireAddPaymentInfo(paymentType) {
197    var order = getOrderFromHiddenField();
198    if (!order || order.length === 0) return;
199
200    var ga4Items = buildGA4ItemsFromOrder(order);
201
202    var totalValue = ga4Items.reduce(function (sum, i) {
203        return sum + (i.price * i.quantity);
204    }, 0);
205
206
207    var coupon = null;
208
209    if (order[0].discountcode) {
210        coupon = String(order[0].discountcode).trim();
211        if (coupon === "") coupon = null;
212    }
213
214
215    var payload = {
216        event: "add_payment_info",
217        store_number: getStoreNumber(),
218        ecommerce: {
219            currency: "USD",
220            value: +totalValue.toFixed(2),
221            payment_type: paymentType,
222            items: ga4Items
223        }
224    };
225
226    if (coupon) {
227        payload.ecommerce.coupon = coupon;
228    }
229
230    window.GTM.pushEvent(payload);
231}
232
233(function () {
234
235    function handlePaymentClick(e) {
236        // Credit Card
237        if (closest(e.target, "#sq-creditcard")) {
238            fireAddPaymentInfo("Credit Card");
239            return;
240        }
241
242        // Google Pay
243        if (closest(e.target, "#gpay-button-online-api-id")) {
244            fireAddPaymentInfo("Google Pay");
245            return;
246        }
247
248        // Apple Pay
249        if (closest(e.target, "#sq-apple-pay")) {
250            fireAddPaymentInfo("Apple Pay");
251            return;
252        }
253    }
254
255    document.addEventListener("click", handlePaymentClick, true);
256
257})();
258
259

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.