PageSourceSearch

https://flightfuelcoffee.com/s/files/1/0676/3793/6445/t/9/assets/c…t-items_v-171228637692183293801675774960.js

js flightfuelcoffee.com collected 2026-10-10 00:42:13 UTC 5,015 bytes, 166 lines download raw bytes

1document.addEventListener('alpine:init', () => {
2  Alpine.data('ThemeModule_CartItems', () => {
3    return {
4      itemsRoot: null,
5      locked: null,
6      init() {
7        this.itemsRoot = this.$root;
8
9        window.addEventListener('shapes:modalcart:afteradditem', (e) => {
10          Alpine.morph(
11            this.itemsRoot,
12            querySelectorInHTMLString(
13              '[data-cart-items]',
14              e.detail.response.sections['cart-items']
15            ).outerHTML
16          );
17        });
18
19        window.addEventListener('shapes:modalcart:cartqtychange', (e) => {
20          Alpine.morph(
21            this.itemsRoot,
22            querySelectorInHTMLString(
23              '[data-cart-items]',
24              e.detail.response.sections['cart-items']
25            ).outerHTML
26          );
27
28          this.$nextTick(() => {
29            this.itemsRoot.querySelectorAll('input').forEach((inputEl) => {
30              inputEl.value = inputEl.getAttribute('value');
31            });
32          });
33
34          const liveRegionText = parseDOMFromString(
35            e.detail.response.sections['cart-live-region']
36          ).firstElementChild.textContent;
37
38          const cartStatus = document.getElementById('cart-live-region-text');
39
40          cartStatus.textContent = liveRegionText;
41
42          cartStatus.setAttribute('aria-hidden', false);
43
44          if (e.detail.originalTarget) {
45            this.$nextTick(() => {
46              if (!this.itemsRoot.contains(e.detail.originalTarget)) {
47                let focusRoot;
48
49                if (this.itemsRoot.closest('[role="dialog"]')) {
50                  focusRoot =
51                    this.itemsRoot.closest('[role="dialog"]').parentNode;
52                } else {
53                  focusRoot = this.itemsRoot;
54                }
55
56                this.$focus.within(focusRoot).first();
57              }
58            });
59          }
60        });
61      },
62      itemQuantityChange(key, value) {
63        if (this.locked) return;
64
65        const lineItemEl = this.$el.closest('li[data-cart-item-key]');
66        const id = key ? key : lineItemEl.getAttribute('data-cart-item-key'),
67          quantity = parseInt(!isNaN(value) ? value : this.$el.value, 10),
68          sections = 'cart-items,cart-footer,cart-item-count,cart-live-region';
69
70        const config = fetchConfigDefaults();
71
72        config.body = JSON.stringify({
73          id,
74          quantity,
75          sections,
76          sections_url: window.location.pathname,
77        });
78
79        const lastValue = parseInt(this.$el.dataset.lastValue, 10);
80
81        if (quantity !== lastValue) {
82          lineItemEl.classList.add('opacity-50', 'cursor-progress');
83
84          const currentCount = Alpine.raw(Alpine.store('cart_count').count);
85
86          this.locked = lineItemEl;
87
88          fetch(theme.routes.cart_change_url, config)
89            .then((res) => res.json())
90            .then((data) => {
91              if (data.item_count === currentCount) {
92                // Quantity change had no effect -- most likely, there is no more inventory
93                const errorEl = lineItemEl.querySelector(
94                  '[data-cart-quantity-error]'
95                );
96
97                errorEl.textContent = theme.strings.cartAddError.replace(
98                  '{{ title }}',
99                  errorEl.dataset.itemTitle
100                );
101
102                errorEl.classList.remove('hidden');
103              } else {
104                document.body.dispatchEvent(
105                  new CustomEvent('shapes:modalcart:cartqtychange', {
106                    bubbles: true,
107                    detail: { response: data, originalTarget: lineItemEl },
108                  })
109                );
110              }
111            })
112            .catch(() => {
113              document.getElementById('cart-errors').textContent =
114                theme.strings.cartError;
115            })
116            .finally(() => {
117              this.locked = null;
118            });
119        }
120      },
121      removeItem(key) {
122        this.itemQuantityChange(key, 0);
123      },
124      _adjustQty(el, operation) {
125        const inputEl = el
126          .closest('li[key]')
127          .querySelector('input[type="number"]');
128
129        const lastValue = parseInt(inputEl.dataset.lastValue, 10);
130
131        let newValue;
132
133        if (operation == 'increment') {
134          newValue = lastValue + 1;
135        }
136
137        if (operation == 'decrement') {
138          if (lastValue > 1) {
139            newValue = lastValue - 1;
140          } else {
141            newValue = 1;
142          }
143        }
144
145        if (operation == 'remove') {
146          newValue = 0;
147        }
148
149        inputEl.value = newValue;
150
151        // this.$nextTick(() => {
152        inputEl.dispatchEvent(new Event('change', { bubbles: true }));
153        // });
154      },
155      increment() {
156        this._adjustQty(this.$el, 'increment');
157      },
158      decrement() {
159        this._adjustQty(this.$el, 'decrement');
160      },
161      remove() {
162        this._adjustQty(this.$el, 'remove');
163      },
164    };
165  });
166});

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.