diff --git a/script.js b/script.js index bdc06f3..dd4a2ea 100644 --- a/script.js +++ b/script.js @@ -382,6 +382,18 @@ window.changeSemester = function (sem) { renderPDFs(); }; +function prepareSearchIndex() { + // ⚡ Bolt: Optimize search by pre-calculating the search string. + // This avoids repeatedly calling toLowerCase() during search input events. + pdfDatabase.forEach(pdf => { + const t = pdf.title || ''; + const d = pdf.description || ''; + const c = pdf.category || ''; + const a = pdf.author || ''; + pdf._searchStr = (t + ' ' + d + ' ' + c + ' ' + a).toLowerCase(); + }); +} + async function syncClassSwitcher() { const classSelect = document.getElementById('classSelect'); if (!classSelect) return; @@ -451,6 +463,7 @@ async function loadPDFDatabase() { if (shouldUseCache) { pdfDatabase = cachedData; + prepareSearchIndex(); // --- FIX: CALL THIS TO POPULATE UI --- syncClassSwitcher(); renderSemesterTabs(); @@ -474,6 +487,8 @@ async function loadPDFDatabase() { data: pdfDatabase })); + prepareSearchIndex(); + // --- FIX: CALL THIS TO POPULATE UI --- syncClassSwitcher(); renderPDFs(); @@ -874,9 +889,17 @@ function showSkeletons() { grid.innerHTML = skeletonHTML; } +const HTML_ESCAPE_MAP = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''' +}; + const escapeHtml = (text) => { if (!text) return ''; - return text.replace(/&/g, "&").replace(//g, ">").replace(/"/g, """).replace(/'/g, "'"); + return text.replace(/[&<>"']/g, (m) => HTML_ESCAPE_MAP[m]); }; function renderPDFs() { @@ -915,10 +938,13 @@ function renderPDFs() { matchesCategory = currentCategory === 'all' || pdf.category === currentCategory; } - const matchesSearch = pdf.title.toLowerCase().includes(searchTerm) || - pdf.description.toLowerCase().includes(searchTerm) || - pdf.category.toLowerCase().includes(searchTerm) || - pdf.author.toLowerCase().includes(searchTerm); + // ⚡ Bolt: Use pre-calculated search string for performance + const matchesSearch = pdf._searchStr + ? pdf._searchStr.includes(searchTerm) + : (pdf.title || '').toLowerCase().includes(searchTerm) || + (pdf.description || '').toLowerCase().includes(searchTerm) || + (pdf.category || '').toLowerCase().includes(searchTerm) || + (pdf.author || '').toLowerCase().includes(searchTerm); // Update return statement to include matchesClass return matchesSemester && matchesClass && matchesCategory && matchesSearch; diff --git a/verification.png b/verification.png deleted file mode 100644 index 77025f3..0000000 Binary files a/verification.png and /dev/null differ