PageSourceSearch

https://www.salesianos.pt/wp-content/plugins/sdb-missao-dom-bosco-main/assets/js/front.js?ver=3.0.0

js salesianos.pt collected 2026-10-02 03:10:29 UTC 8,687 bytes, 280 lines download raw bytes

1(function(){
2    'use strict';
3
4    function config(){
5        return window.SDB_MDB || {};
6    }
7
8    function announce(wrap, message){
9        const status = wrap.querySelector('.sdb-mdb-load-status');
10        if(status){
11            status.textContent = message || '';
12        }
13    }
14
15    function format(template, value){
16        return String(template || '').replace('%d', String(value));
17    }
18
19    function getGrid(wrap){
20        return wrap.querySelector('.sdb-mdb-grid');
21    }
22
23    function getLoadMoreButton(wrap){
24        return wrap.querySelector('.sdb-mdb-load-more');
25    }
26
27    function setLoadingState(wrap, isLoading){
28        const grid = getGrid(wrap);
29        const button = getLoadMoreButton(wrap);
30
31        wrap.dataset.loading = isLoading ? '1' : '0';
32
33        if(grid){
34            grid.setAttribute('aria-busy', isLoading ? 'true' : 'false');
35        }
36
37        if(button){
38            button.disabled = isLoading;
39            if(isLoading){
40                button.setAttribute('aria-busy', 'true');
41            } else {
42                button.removeAttribute('aria-busy');
43            }
44        }
45    }
46
47    function updateLoadMoreButton(wrap, hasMore){
48        const button = getLoadMoreButton(wrap);
49        if(!button){
50            return;
51        }
52
53        button.hidden = wrap.dataset.loadMore !== '1' || !hasMore;
54        button.disabled = false;
55        button.removeAttribute('aria-busy');
56    }
57
58    function requestParams(wrap, page, type){
59        const settings = config();
60        return new URLSearchParams({
61            action: settings.action || 'sdb_mdb_load_projects',
62            page: String(page),
63            per_page: wrap.dataset.perPage || '9',
64            type: type || '',
65            status: wrap.dataset.status || '',
66            tag: wrap.dataset.tag || '',
67            featured: wrap.dataset.featured || '0'
68        });
69    }
70
71    async function fetchProjects(wrap, page, type){
72        const settings = config();
73        if(!settings.ajaxUrl){
74            throw new Error('AJAX endpoint unavailable');
75        }
76
77        const response = await fetch(settings.ajaxUrl, {
78            method: 'POST',
79            credentials: 'same-origin',
80            cache: 'no-store',
81            headers: {
82                'Accept': 'application/json',
83                'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
84            },
85            body: requestParams(wrap, page, type).toString()
86        });
87
88        if(!response.ok){
89            throw new Error('Request failed');
90        }
91
92        const payload = await response.json();
93        if(!payload || payload.success !== true || !payload.data){
94            throw new Error('Invalid response');
95        }
96
97        return payload.data;
98    }
99
100    function updateActiveTab(wrap, activeTab){
101        const grid = getGrid(wrap);
102
103        wrap.querySelectorAll('.sdb-mdb-filters [role="tab"]').forEach(function(tab){
104            const isActive = tab === activeTab;
105            tab.classList.toggle('is-active', isActive);
106            tab.setAttribute('aria-selected', isActive ? 'true' : 'false');
107            tab.tabIndex = isActive ? 0 : -1;
108        });
109
110        if(grid && activeTab.id){
111            grid.setAttribute('aria-labelledby', activeTab.id);
112        }
113    }
114
115    function updateLocation(type){
116        if(!window.history || !window.history.replaceState){
117            return;
118        }
119
120        const url = new URL(window.location.href);
121        if(type){
122            url.searchParams.set('mdb_tipo', type);
123        } else {
124            url.searchParams.delete('mdb_tipo');
125        }
126
127        window.history.replaceState({}, '', url.toString());
128    }
129
130    async function requestProjects(wrap, options){
131        const grid = getGrid(wrap);
132        const settings = config();
133        const page = options.page || 1;
134        const type = typeof options.type === 'string' ? options.type : (wrap.dataset.type || '');
135
136        if(!grid || wrap.dataset.loading === '1'){
137            return false;
138        }
139
140        setLoadingState(wrap, true);
141        announce(wrap, settings.loading || 'A carregar projetos…');
142
143        try {
144            const data = await fetchProjects(wrap, page, type);
145            const html = data.html || '';
146
147            if(options.replace){
148                grid.innerHTML = html;
149            } else if(html){
150                grid.insertAdjacentHTML('beforeend', html);
151            }
152
153            wrap.dataset.page = String(data.page || page);
154            wrap.dataset.maxPages = String(data.max_pages || 1);
155            wrap.dataset.type = type;
156            updateLoadMoreButton(wrap, Boolean(data.has_more));
157
158            if(options.activeTab){
159                updateActiveTab(wrap, options.activeTab);
160                updateLocation(type);
161            }
162
163            if(data.has_more){
164                announce(wrap, format(settings.loaded || 'Foram carregados %d projetos adicionais.', data.count || 0));
165            } else {
166                announce(wrap, settings.done || 'Todos os projetos disponíveis foram carregados.');
167            }
168
169            return true;
170        } catch(error){
171            updateLoadMoreButton(wrap, true);
172            announce(wrap, settings.error || 'Não foi possível carregar os projetos. Tente novamente.');
173            return false;
174        } finally {
175            setLoadingState(wrap, false);
176        }
177    }
178
179    function loadMore(button){
180        const wrap = button.closest('.sdb-mdb-progressive');
181        if(!wrap || button.disabled){
182            return;
183        }
184
185        const currentPage = parseInt(wrap.dataset.page || '1', 10);
186        requestProjects(wrap, {
187            page: currentPage + 1,
188            type: wrap.dataset.type || '',
189            replace: false
190        });
191    }
192
193    function selectTab(tab){
194        const wrap = tab.closest('.sdb-mdb-progressive');
195        if(!wrap || tab.getAttribute('aria-selected') === 'true'){
196            return;
197        }
198
199        requestProjects(wrap, {
200            page: 1,
201            type: tab.dataset.filter || '',
202            replace: true,
203            activeTab: tab
204        });
205    }
206
207    function handleTabKeydown(event, tab){
208        const tabs = Array.from(tab.closest('[role="tablist"]').querySelectorAll('[role="tab"]'));
209        const currentIndex = tabs.indexOf(tab);
210        let nextIndex = currentIndex;
211
212        if(event.key === 'ArrowRight'){
213            nextIndex = (currentIndex + 1) % tabs.length;
214        } else if(event.key === 'ArrowLeft'){
215            nextIndex = (currentIndex - 1 + tabs.length) % tabs.length;
216        } else if(event.key === 'Home'){
217            nextIndex = 0;
218        } else if(event.key === 'End'){
219            nextIndex = tabs.length - 1;
220        } else {
221            return;
222        }
223
224        event.preventDefault();
225        tabs[nextIndex].focus();
226        tabs[nextIndex].click();
227    }
228
229    function initializeWrap(wrap){
230        if(wrap.dataset.mdbInteractiveInit === '1'){
231            return;
232        }
233
234        wrap.dataset.mdbInteractiveInit = '1';
235        const button = getLoadMoreButton(wrap);
236        updateLoadMoreButton(wrap, Boolean(button && !button.hidden));
237    }
238
239    function initialize(){
240        document.querySelectorAll('.sdb-mdb-progressive').forEach(initializeWrap);
241    }
242
243    if(document.readyState === 'loading'){
244        document.addEventListener('DOMContentLoaded', initialize);
245    } else {
246        initialize();
247    }
248
249    document.addEventListener('click', function(event){
250        const galleryButton = event.target && event.target.closest ? event.target.closest('.sdb-mdb-gallery-toggle') : null;
251        if(galleryButton){
252            const gallery = document.getElementById(galleryButton.dataset.target);
253            if(gallery){
254                gallery.hidden = !gallery.hidden;
255                galleryButton.setAttribute('aria-expanded', String(!gallery.hidden));
256            }
257            return;
258        }
259
260        const tab = event.target && event.target.closest ? event.target.closest('.sdb-mdb-filters [role="tab"]') : null;
261        if(tab){
262            event.preventDefault();
263            selectTab(tab);
264            return;
265        }
266
267        const loadMoreButton = event.target && event.target.closest ? event.target.closest('.sdb-mdb-load-more') : null;
268        if(loadMoreButton){
269            event.preventDefault();
270            loadMore(loadMoreButton);
271        }
272    });
273
274    document.addEventListener('keydown', function(event){
275        const tab = event.target && event.target.closest ? event.target.closest('.sdb-mdb-filters [role="tab"]') : null;
276        if(tab){
277            handleTabKeydown(event, tab);
278        }
279    });
280})();

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.