PageSourceSearch

https://coldpress.co.uk/cdn/shop/t/4/assets/app.min.js?v=176938839107203747651718102476

js coldpress.co.uk collected 2026-10-05 10:29:25 UTC 15,734 bytes, 570 lines download raw bytes

1window.lazySizesConfig = window.lazySizesConfig || {};
2window.lazySizesConfig.expand = 150;
3window.lazySizesConfig.loadMode = 1;
4window.lazySizesConfig.loadHidden = false;
5
6gsap.defaults({
7  ease: 'power1.out'
8});
9
10gsap.config({
11  nullTargetWarn: false
12});
13
14if (typeof debounce === 'undefined') {
15  function debounce(fn, wait) {
16    let t;
17    return (...args) => {
18      clearTimeout(t);
19      t = setTimeout(() => fn.apply(this, args), wait);
20    };
21  }
22}
23
24/**
25 *  @class
26 *  @function ProductCard
27 */
28if (!customElements.get('product-card')) {
29  class ProductCard extends HTMLElement {
30    constructor() {
31      super();
32      this.quick_add = this.querySelector('.product-card--add-to-cart-button-simple');
33    }
34    connectedCallback() {
35      if (this.quick_add) {
36        this.enableQuickAdd();
37      }
38    }
39    enableQuickAdd() {
40      this.quick_add.addEventListener('click', this.quickAdd.bind(this));
41    }
42
43    quickAdd(evt) {
44      evt.preventDefault();
45      if (this.quick_add.disabled) {
46        return;
47      }
48      this.quick_add.classList.add('loading');
49      this.classList.add('thb-loading');
50      this.quick_add.innerHTML = window.theme.strings.addingToCart;
51      this.quick_add.setAttribute('aria-disabled', true);
52
53      const config = {
54        method: 'POST',
55        headers: {
56          'X-Requested-With': 'XMLHttpRequest',
57          'Accept': 'application/javascript'
58        }
59      };
60
61      let formData = new FormData(this.form);
62
63      formData.append('id', this.quick_add.dataset.productId);
64      formData.append('quantity', 1);
65      formData.append('sections', this.getSectionsToRender().map((section) => section.section));
66      formData.append('sections_url', window.location.pathname);
67
68      config.body = formData;
69
70      fetch(`${theme.routes.cart_add_url}`, config)
71        .then((response) => response.json())
72        .then((response) => {
73          if (response.status) {
74            return;
75          }
76          this.renderContents(response);
77
78          dispatchCustomEvent('cart:item-added', {
79            product: response.hasOwnProperty('items') ? response.items[0] : response
80          });
81        })
82        .catch((e) => {
83          console.error(e);
84        })
85        .finally(() => {
86          this.quick_add.innerHTML = window.theme.strings.addToCart;
87          this.classList.remove('thb-loading');
88          this.quick_add.classList.remove('loading');
89          this.quick_add.removeAttribute('aria-disabled');
90        });
91
92      return false;
93    }
94    getSectionsToRender() {
95      return [{
96        id: 'Cart',
97        section: 'main-cart',
98        selector: '.thb-cart-form'
99      },
100      {
101        id: 'Cart-Drawer',
102        section: 'cart-drawer',
103        selector: '.cart-drawer'
104      },
105      {
106        id: 'cart-drawer-toggle',
107        section: 'cart-bubble',
108        selector: '.float_count'
109      }];
110    }
111    renderContents(parsedState) {
112      this.getSectionsToRender().forEach((section => {
113        if (!document.getElementById(section.id)) {
114          return;
115        }
116        const elementToReplace = document.getElementById(section.id).querySelector(section.selector) || document.getElementById(section.id);
117        elementToReplace.innerHTML = this.getSectionInnerHTML(parsedState.sections[section.section], section.selector);
118
119        if (section.id == 'Cart-Drawer') {
120          if (typeof CartDrawer !== 'undefined') {
121            new CartDrawer();
122          }
123        }
124        if (section.id == 'Cart') {
125          if (typeof Cart !== 'undefined') {
126            new Cart().renderContents(parsedState);
127          }
128        }
129      }));
130
131      let quick_shop = document.getElementById('Quick-Drawer'),
132        cart_drawer = document.getElementById('Cart-Drawer'),
133        latency = 100;
134
135      if (cart_drawer && quick_shop?.contains(this)) {
136
137        quick_shop.querySelector('.thb-close').click();
138
139        latency = 750;
140      }
141
142      setTimeout(() => {
143        document.getElementById('cart-drawer-toggle').click();
144        dispatchCustomEvent('cart-drawer:open');
145      }, latency);
146
147    }
148    getSectionInnerHTML(html, selector = '.shopify-section') {
149      return new DOMParser()
150        .parseFromString(html, 'text/html')
151        .querySelector(selector).innerHTML;
152    }
153  }
154  customElements.define('product-card', ProductCard);
155}
156
157/**
158 *  @class
159 *  @function LocalizationForm
160 */
161if (!customElements.get('localization-form')) {
162  class LocalizationForm extends HTMLElement {
163    constructor() {
164      super();
165      this.form = this.querySelector('form');
166      this.inputs = this.form.querySelectorAll('[name="locale_code"], [name="country_code"]');
167      this.debouncedOnSubmit = debounce((event) => {
168        this.onSubmitHandler(event);
169      }, 200);
170      this.inputs.forEach(item => item.addEventListener('change', this.debouncedOnSubmit.bind(this)));
171    }
172    onSubmitHandler(event) {
173      if (this.form) this.form.submit();
174    }
175  }
176  customElements.define('localization-form', LocalizationForm);
177}
178
179/**
180 *  @class
181 *  @function CartDrawer
182 */
183class CartDrawer {
184
185  constructor(args) {
186    this.container = document.getElementById('Cart-Drawer');
187    this.wrapper = document.getElementById('wrapper');
188    this.cc = document.querySelector('.click-capture');
189
190    if (!this.container) {
191      return;
192    }
193    this.close = this.container.querySelector('.thb-close');
194    this.button = document.getElementById('cart-drawer-toggle');
195
196    // Add functionality to buttons
197    this.setupCartAnimation();
198
199    // Setup Events
200    this.setupEventListeners();
201
202    // Notes Toggle
203    this.notesToggle();
204
205    // Remove buttons
206    this.removeProductEvent();
207
208    // Terms checkbox
209    this.termsCheckbox();
210  }
211  setupCartAnimation() {
212    this.tl = gsap.timeline({
213      paused: true,
214      onStart: () => {
215        this.wrapper.classList.add('open-cc');
216        gsap.set(this.container, {
217          visibility: "visible"
218        });
219      },
220      onReverseComplete: () => {
221        this.wrapper.classList.remove('open-cc');
222        gsap.set(this.container, {
223          clearProps: "transform"
224        });
225        this.container.blur();
226      },
227      onComplete: () => {
228        this.container.focus();
229        dispatchCustomEvent('cart-drawer:open');
230      }
231    });
232    this.tl.clear();
233    this.tl
234      .to(this.container, {
235        x: "0%",
236        duration: 0.25
237      }, "start")
238      .fromTo(this.container.querySelectorAll('.mini_cart_item, .mini-cart__row, .mini-cart__notes, .mini-cart__buttons'), {
239        x: "30",
240        opacity: 0
241      }, {
242        duration: 0.25,
243        x: "0",
244        opacity: 1,
245        stagger: 0.05
246      }, "start+=0.2");
247  }
248  closeDrawer() {
249    this.tl.timeScale(1.5).reverse();
250  }
251  setupEventListeners() {
252    this.debouncedOnChange = debounce((event) => {
253      this.onChange(event);
254    }, 300);
255
256    document.addEventListener('cart:refresh', (event) => {
257      this.refresh();
258    });
259
260    this.container.addEventListener('change', this.debouncedOnChange.bind(this));
261
262    this.button.addEventListener('click', (e) => {
263
264      if (document.body.classList.contains('template-cart')) {
265        return false;
266      }
267      this.tl.timeScale(1).play();
268      e.preventDefault();
269    });
270
271    this.cc.addEventListener('click', this.closeDrawer.bind(this));
272    this.close.addEventListener('click', this.closeDrawer.bind(this));
273
274    document.addEventListener('keyup', (e) => {
275      if (e.code) {
276        if (e.code.toUpperCase() === 'ESCAPE') {
277          this.closeDrawer();
278        }
279      }
280    });
281  }
282  onChange(event) {
283    if (event.target.classList.contains('qty')) {
284      this.updateQuantity(event.target.dataset.index, event.target.value);
285    }
286  }
287  removeProductEvent() {
288    let removes = this.container.querySelectorAll('.remove');
289
290    removes.forEach((remove) => {
291      remove.addEventListener('click', (event) => {
292        this.updateQuantity(event.target.dataset.index, '0');
293
294        event.preventDefault();
295      });
296    });
297  }
298  getSectionsToRender() {
299    return [{
300      id: 'Cart-Drawer',
301      section: 'cart-drawer',
302      selector: '.side-panel-content'
303    },
304    {
305      id: 'cart-drawer-toggle',
306      section: 'cart-bubble',
307      selector: '.float_count'
308    }];
309  }
310  getSectionInnerHTML(html, selector) {
311    return new DOMParser()
312      .parseFromString(html, 'text/html')
313      .querySelector(selector).innerHTML;
314  }
315  termsCheckbox() {
316    let terms_checkbox = this.container.querySelector('#CartDrawerTerms'),
317      checkout_button = this.container.querySelector('.button.checkout');
318
319    if (terms_checkbox && checkout_button) {
320      terms_checkbox.setCustomValidity(theme.strings.requiresTerms);
321      checkout_button.addEventListener('click', function (e) {
322        if (!terms_checkbox.checked) {
323          terms_checkbox.reportValidity();
324          terms_checkbox.focus();
325          e.preventDefault();
326        }
327      });
328    }
329  }
330  notesToggle() {
331    let notes_toggle = document.getElementById('order-note-toggle');
332
333    if (!notes_toggle) {
334      return;
335    }
336
337    notes_toggle.addEventListener('click', function () {
338      notes_toggle.classList.toggle('active');
339    });
340    notes_toggle.nextElementSibling.querySelector('.button').addEventListener('click', () => {
341      notes_toggle.classList.remove('active');
342      this.saveNotes();
343    });
344  }
345  saveNotes() {
346    fetch(`${theme.routes.cart_update_url}.js`, {
347      method: 'POST',
348      headers: {
349        'Content-Type': 'application/json',
350        'Accept': `application/json`
351      },
352      body: JSON.stringify({
353        'note': document.getElementById('mini-cart__notes').value
354      })
355    });
356  }
357  updateQuantity(line, quantity) {
358    this.container.querySelector(`#CartDrawerItem-${line}`).classList.add('thb-loading');
359    const body = JSON.stringify({
360      line,
361      quantity,
362      sections: this.getSectionsToRender().map((section) => section.section),
363      sections_url: window.location.pathname
364    });
365
366    dispatchCustomEvent('line-item:change:start', {
367      quantity: quantity
368    });
369    fetch(`${theme.routes.cart_change_url}`, {
370      method: 'POST',
371      headers: {
372        'Content-Type': 'application/json',
373        'Accept': `application/json`
374      },
375      ...{
376        body
377      }
378    })
379      .then((response) => {
380        return response.text();
381      })
382      .then((state) => {
383        const parsedState = JSON.parse(state);
384
385        this.getSectionsToRender().forEach((section => {
386          const elementToReplace = document.getElementById(section.id).querySelector(section.selector) || document.getElementById(section.id);
387
388          if (parsedState.sections) {
389            elementToReplace.innerHTML = this.getSectionInnerHTML(parsedState.sections[section.section], section.selector);
390          }
391        }));
392        this.removeProductEvent();
393        this.notesToggle();
394        this.termsCheckbox();
395        dispatchCustomEvent('line-item:change:end', {
396          quantity: quantity,
397          cart: parsedState
398        });
399        if (this.container.querySelector(`#CartDrawerItem-${line}`)) {
400          this.container.querySelector(`#CartDrawerItem-${line}`).classList.remove('thb-loading');
401        }
402      });
403  }
404  refresh() {
405    let sections = 'cart-drawer,cart-bubble';
406    fetch(`${window.location.pathname}?sections=${sections}`)
407      .then((response) => {
408        return response.text();
409      })
410      .then((state) => {
411        const parsedState = JSON.parse(state);
412
413        this.getSectionsToRender().forEach((section => {
414          const elementToReplace = document.getElementById(section.id).querySelector(section.selector) || document.getElementById(section.id);
415
416          elementToReplace.innerHTML = this.getSectionInnerHTML(parsedState[section.section], section.selector);
417        }));
418
419        this.removeProductEvent();
420        this.notesToggle();
421        this.termsCheckbox();
422      });
423  }
424}
425
426/**
427 *  @class
428 *  @function Animation
429 */
430class ScrollAnimation {
431  constructor() {
432    this.elements = document.querySelectorAll('.animation');
433    this.args = {
434      duration: 0.75,
435      ease: 'power1.out',
436      autoAlpha: 1,
437      x: 0,
438      y: 0,
439      z: 0,
440      scale: 1,
441      rotationZ: '0deg',
442      rotationX: '0deg',
443      rotationY: '0deg',
444      stagger: 0.3,
445    };
446
447    this.setupScrollTrigger();
448  }
449  setupScrollTrigger() {
450
451    ScrollTrigger.config({ limitCallbacks: true });
452    ScrollTrigger.batch(this.elements, {
453      onEnter: batch => gsap.to(batch, this.args),
454      onEnterBack: batch => gsap.to(batch, this.args),
455    });
456    window.dispatchEvent(new Event('scroll'));
457  }
458}
459
460/**
461 *  @class
462 *  @function RetinaJS
463 */
464if (typeof RetinaJS == 'undefined') {
465  class RetinaJS {
466    constructor() {
467      this.elements = document.querySelectorAll('img.retina_size:not(.retina_active)');
468
469      this.elements.forEach(function (elem) {
470        let w = elem.getAttribute('width'),
471          h = elem.getAttribute('height');
472
473        elem.setAttribute('width', w / 2);
474
475        if (h) {
476          elem.setAttribute('height', h / 2);
477        }
478
479        elem.classList.add('retina_active');
480      });
481    }
482  }
483  new RetinaJS();
484}
485
486/**
487 *  @class
488 *  @function ModalDialog
489 */
490if (!customElements.get('modal-dialog')) {
491  class ModalDialog extends HTMLElement {
492    constructor() {
493      super();
494      this.querySelector('[id^="ModalClose-"]').addEventListener(
495        'click',
496        this.hide.bind(this)
497      );
498      this.addEventListener('keyup', (event) => {
499        if (event.code.toUpperCase() === 'ESCAPE') this.hide();
500      });
501      if (this.classList.contains('media-modal')) {
502        this.addEventListener('pointerup', (event) => {
503          if (event.pointerType === 'mouse' && !event.target.closest('product-model')) this.hide();
504        });
505      } else {
506        this.addEventListener('click', (event) => {
507          if (event.target.nodeName === 'MODAL-DIALOG') this.hide();
508        });
509      }
510    }
511
512    connectedCallback() {
513      if (this.moved) return;
514      this.moved = true;
515      document.body.querySelector('#wrapper').appendChild(this);
516    }
517
518    show(opener) {
519      this.openedBy = opener;
520      document.body.classList.add('overflow-hidden');
521      this.setAttribute('open', '');
522    }
523
524    hide() {
525      document.body.classList.remove('overflow-hidden');
526      this.removeAttribute('open');
527      this.querySelectorAll('.js-youtube').forEach((video) => {
528        video.contentWindow.postMessage('{"event":"command","func":"' + 'pauseVideo' + '","args":""}', '*');
529      });
530      this.querySelectorAll('.js-vimeo').forEach((video) => {
531        video.contentWindow.postMessage('{"method":"pause"}', '*');
532      });
533      this.querySelectorAll('video').forEach((video) => video.pause());
534    }
535  }
536  customElements.define('modal-dialog', ModalDialog);
537  class ModalOpener extends HTMLElement {
538    constructor() {
539      super();
540
541      const button = this.querySelector('button');
542
543      if (!button) return;
544      button.addEventListener('click', () => {
545        const modal = document.querySelector(this.getAttribute('data-modal'));
546        if (modal) modal.show(button);
547      });
548    }
549  }
550  customElements.define('modal-opener', ModalOpener);
551}
552
553
554window.addEventListener('resize', () => {
555  document.querySelectorAll('.footer .widget--menu').forEach((detail) => {
556    if (window.innerWidth < 768) {
557      detail.removeAttribute('open');
558    } else {
559      detail.setAttribute('open', '');
560    }
561  });
562});
563window.addEventListener('DOMContentLoaded', () => {
564  if (typeof CartDrawer !== 'undefined') {
565    new CartDrawer({ animations: true });
566  }
567  if (typeof ScrollAnimation !== 'undefined') {
568    new ScrollAnimation();
569  }
570});

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.