PageSourceSearch

https://www.atlasroofing.com/resources/js/components/product-variations.js?v=20261001065826

js atlasroofing.com collected 2026-10-01 13:59:07 UTC 7,486 bytes, 207 lines download raw bytes

1document.addEventListener('alpine:init', () => {
2    Alpine.data('filters', (productUid, rawShingles) => ({
3        productUid: productUid,
4        blends: [],
5        selectedBlends: [],
6        shingles: {},
7        favorites: {},
8        cookieName: `global-product-color-favorites`,
9        activePlant: window.getCookie('atlas_active_plant') || null,
10        activePlantTitle: window.getCookie('atlas_active_plant_title') || '',
11        zipInput: window.getCookie('atlas_active_zip') || '',
12        zipError: '',
13
14        init () {
15            const shingles = JSON.parse(rawShingles)
16
17            this.shingles = shingles.reduce((acc, i) => {
18                acc[i.uid] = i
19                return acc
20            }, {})
21
22            this.restoreFavorites()
23        },
24
25        toggleFav (uid) {
26            if (uid in this.favorites) {
27                delete this.favorites[uid]
28            } else {
29                this.favorites[uid] = this.shingles[uid].title
30            }
31
32            this.persistFavoritesInCookies()
33        },
34
35        restoreFavorites () {
36            const cookie = window.getCookie(this.cookieName)
37
38            if (!cookie.length) {
39                return
40            }
41
42            const favs = JSON.parse(cookie)
43            favs.map(i => {
44                if (i in this.shingles) {
45                    this.favorites[i] = this.shingles[i]?.title
46                } else {
47                    delete this.favorites[i]
48                }
49            }, {})
50            this.persistFavoritesInCookies()
51        },
52
53        persistFavoritesInCookies () {
54            window.setCookie(
55                this.cookieName,
56                JSON.stringify(Object.keys(this.favorites)),
57                30
58            )
59        },
60
61        canDisplay(blends) {
62            blends = JSON.parse(blends)
63            return !this.selectedBlends.length || blends.some(b => this.selectedBlends.includes(b))
64        },
65
66        _zipDebounce: null,
67        isSearching: false,
68
69        onZipInput() {
70            clearTimeout(this._zipDebounce);
71            this.zipError = '';
72            const zip = (this.zipInput || '').replace(/\D/g, '');
73            this.zipInput = zip;
74
75            if (zip.length === 0) {
76                this.clearLocation();
77                return;
78            }
79
80            if (zip.length < 5 && this.activePlant) {
81                this.activePlant = null;
82                this.activePlantTitle = '';
83                window.setCookie('atlas_active_plant', '', -1);
84                window.setCookie('atlas_active_plant_title', '', -1);
85                window.setCookie('atlas_active_zip', '', -1);
86            }
87
88            if (zip.length >= 5) {
89                this._zipDebounce = setTimeout(() => this.lookupZip(), 150);
90            }
91        },
92
93        async lookupZip() {
94            this.zipError = '';
95            const zip = (this.zipInput || '').trim().slice(0, 5);
96            if (zip.length < 5) return;
97            this.isSearching = true;
98            try {
99                const res = await fetch(`/api/zip-lookup/${zip}`);
100                const data = await res.json();
101                if (data.success && data.plant) {
102                    this.activePlant = data.plant.slug;
103                    this.activePlantTitle = data.plant.title;
104                    window.setSessionCookie('atlas_active_plant', data.plant.slug);
105                    window.setSessionCookie('atlas_active_plant_title', data.plant.title);
106                    window.setSessionCookie('atlas_active_zip', zip);
107                } else if (data.success) {
108                    // ZIP resolved to no active plant — silently fall back to All Locations
109                    this.activePlant = null;
110                    this.activePlantTitle = '';
111                    window.setCookie('atlas_active_plant', '', -1);
112                    window.setCookie('atlas_active_plant_title', '', -1);
113                    window.setCookie('atlas_active_zip', '', -1);
114                } else {
115                    this.zipError = data.error || 'No results found for this ZIP code.';
116                }
117            } catch (e) {
118                this.zipError = 'Unable to look up location. Please try again.';
119            } finally {
120                this.isSearching = false;
121            }
122        },
123
124        clearLocation() {
125            this.activePlant = null;
126            this.activePlantTitle = '';
127            this.zipInput = '';
128            this.zipError = '';
129            window.setCookie('atlas_active_plant', '', -1);
130            window.setCookie('atlas_active_plant_title', '', -1);
131            window.setCookie('atlas_active_zip', '', -1);
132        },
133
134        getColorImage(nationalUrl, regionalJson) {
135            if (this.activePlant) {
136                try {
137                    const regional = JSON.parse(regionalJson || '{}');
138                    if (regional[this.activePlant] && regional[this.activePlant].colorImage) {
139                        return regional[this.activePlant].colorImage;
140                    }
141                } catch (e) {}
142            }
143            return nationalUrl;
144        },
145
146        getHoverImage(nationalUrl, regionalJson) {
147            if (this.activePlant) {
148                try {
149                    const regional = JSON.parse(regionalJson || '{}');
150                    if (regional[this.activePlant] && regional[this.activePlant].hoverColorImage) {
151                        return regional[this.activePlant].hoverColorImage;
152                    }
153                } catch (e) {}
154            }
155            return nationalUrl;
156        },
157
158        // Whether this swatch has any image to display.
159        // Hides swatches with no national image and no regional match
160        // to avoid broken-image renders.
161        hasImage(nationalUrl, regionalJson) {
162            if (nationalUrl && nationalUrl.length) return true;
163            if (this.activePlant) {
164                try {
165                    const regional = JSON.parse(regionalJson || '{}');
166                    if (regional[this.activePlant] && regional[this.activePlant].colorImage) {
167                        return true;
168                    }
169                } catch (e) {}
170            }
171            return false;
172        },
173    }))
174})
175
176// video modal
177// autofilling modal on watch video button click
178$('#productVideoModal').on('show.bs.modal', function (event) {
179    var action = $(event.relatedTarget) // Button that triggered the modal
180    var videoUrl = action.data('video')
181    var imageUrl=action.data('image')
182    var youtubeMedia = action.data('youtube')
183        if(imageUrl!=''){
184            $('#videoDiv').empty()
185            $('#videoDiv').append('<img src='+imageUrl+' class="w-100 rounded-1" height="540px">')
186        }
187        if (videoUrl!=='') {
188            $('#videoDiv').empty()
189            $('#videoDiv').append(
190                '<video width="100%" height="540px" controls><source src="' +
191                    videoUrl +
192                    '">Your browser does not support the video tag.</video>'
193            )
194        } 
195        if(youtubeMedia!=''){   
196            $('#videoDiv').empty()         
197            $('#videoDiv').append(
198                '<iframe class="w-100 rounded-1" height="540px" src="https://youtube.com/embed/' +
199                    youtubeMedia +
200                    '" frameborder="0" allowfullscreen></iframe>'
201            )
202        }
203    
204})
205$('#productVideoModal').on('hide.bs.modal', () => {
206    $('#videoDiv').empty()
207})

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.