Skip to content

Commit 4713137

Browse files
committed
add search index file
1 parent 228e919 commit 4713137

3 files changed

Lines changed: 239224 additions & 10 deletions

File tree

scripts/main.js

Lines changed: 163 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,9 @@
3838
debounceTimer: null,
3939
entryKeys: new Set(),
4040
elements: null,
41-
deepIndexingEnabled: false
41+
deepIndexingEnabled: false,
42+
indexLoaded: false,
43+
indexFile: 'search-index.json'
4244
};
4345
var domParserInstance = null;
4446
var cachedNavFromStorage = null;
@@ -703,7 +705,47 @@
703705
});
704706

705707
updateSearchFeedback();
706-
scheduleIndexing();
708+
loadSearchIndexFromFile();
709+
}
710+
711+
function loadSearchIndexFromFile() {
712+
if (!searchState.deepIndexingEnabled) {
713+
searchState.indexLoaded = true;
714+
scheduleIndexing();
715+
return;
716+
}
717+
718+
fetch(searchState.indexFile)
719+
.then(function(response) {
720+
if (!response.ok) {
721+
throw new Error('Index file not found');
722+
}
723+
return response.json();
724+
})
725+
.then(function(indexData) {
726+
if (indexData && indexData.entries && Array.isArray(indexData.entries)) {
727+
console.log('Search index loaded from file:', indexData.entries.length, 'entries');
728+
searchState.extraEntries = indexData.entries;
729+
searchState.entryKeys.clear();
730+
searchState.baseEntries.forEach(function(entry) {
731+
searchState.entryKeys.add(entryKey(entry));
732+
});
733+
indexData.entries.forEach(function(entry) {
734+
searchState.entryKeys.add(entryKey(entry));
735+
});
736+
searchState.indexLoaded = true;
737+
searchState.indexing = false;
738+
updateSearchFeedback(searchState.activeQuery, null);
739+
if (searchState.activeQuery && searchState.activeQuery.length >= 2) {
740+
performSearch(searchState.activeQuery);
741+
}
742+
}
743+
})
744+
.catch(function(error) {
745+
console.log('Search index file not found, will build dynamically');
746+
searchState.indexLoaded = false;
747+
scheduleIndexing();
748+
});
707749
}
708750

709751
function prepareBaseSearchEntries() {
@@ -774,26 +816,60 @@
774816
return a.entry.title.localeCompare(b.entry.title);
775817
});
776818

777-
var topResults = matches.slice(0, 50).map(function(item) {
819+
var topResults = matches.slice(0, 100).map(function(item) {
778820
return item.entry;
779821
});
780822

781823
renderSearchResults(topResults, query);
782824
}
783825

784826
function evaluateMatch(entry, normalizedQuery) {
785-
if (entry.titleLower === normalizedQuery) {
827+
var titleLower = entry.titleLower;
828+
var searchBlob = entry.searchBlob || '';
829+
830+
// Exact match - highest priority
831+
if (titleLower === normalizedQuery) {
786832
return 0;
787833
}
788-
if (entry.titleLower.indexOf(normalizedQuery) === 0) {
834+
835+
// Starts with query - very high priority
836+
if (titleLower.indexOf(normalizedQuery) === 0) {
789837
return 1;
790838
}
791-
if (entry.titleLower.indexOf(normalizedQuery) !== -1) {
839+
840+
// Query appears in title - high priority
841+
var titleIndex = titleLower.indexOf(normalizedQuery);
842+
if (titleIndex !== -1) {
792843
return 2;
793844
}
794-
if (entry.searchBlob && entry.searchBlob.indexOf(normalizedQuery) !== -1) {
795-
return 3;
845+
846+
// Check for word boundary matches in title (e.g., "CONTENT" matches "CONTENT_AWARE_FITTING")
847+
var titleParts = titleLower.split(/[._\s-]+/);
848+
for (var i = 0; i < titleParts.length; i++) {
849+
if (titleParts[i] === normalizedQuery) {
850+
return 2.5; // Between substring match and blob match
851+
}
852+
if (titleParts[i].indexOf(normalizedQuery) === 0) {
853+
return 3;
854+
}
855+
}
856+
857+
// Match in search blob (context, description, keywords) - lower priority
858+
if (searchBlob && searchBlob.indexOf(normalizedQuery) !== -1) {
859+
return 4;
860+
}
861+
862+
// Try fuzzy matching for partial words in search blob
863+
var queryWords = normalizedQuery.split(/\s+/);
864+
if (queryWords.length > 1 && searchBlob) {
865+
var allWordsMatch = queryWords.every(function(word) {
866+
return searchBlob.indexOf(word) !== -1;
867+
});
868+
if (allWordsMatch) {
869+
return 5;
870+
}
796871
}
872+
797873
return Infinity;
798874
}
799875

@@ -919,6 +995,10 @@
919995
searchState.indexing = false;
920996
return;
921997
}
998+
if (searchState.indexLoaded) {
999+
searchState.indexing = false;
1000+
return;
1001+
}
9221002
if (searchState.indexing || !searchState.queue.length) {
9231003
searchState.indexing = searchState.queue.length > 0;
9241004
return;
@@ -1040,7 +1120,7 @@
10401120
});
10411121
}
10421122

1043-
if (headingText.indexOf('property') !== -1) {
1123+
if (headingText.indexOf('property') !== -1 || headingText.indexOf('properties') !== -1) {
10441124
var propertyNames = collectPropertyNames(section);
10451125
var anchorId = section.getAttribute('id');
10461126
var anchorHref = anchorId ? baseHref + '#' + anchorId : baseHref;
@@ -1061,6 +1141,80 @@
10611141
});
10621142
}
10631143
}
1144+
1145+
// Index values/constants/enums (like CONTENT_AWARE_FITTING)
1146+
if (headingText.indexOf('value') !== -1 || headingText.indexOf('constant') !== -1) {
1147+
var valueRows = section.querySelectorAll('table tbody tr');
1148+
valueRows.forEach(function(row) {
1149+
var cells = row.querySelectorAll('td');
1150+
if (!cells.length) {
1151+
return;
1152+
}
1153+
var nameCell = cells[0];
1154+
var descCell = cells.length > 1 ? cells[1] : null;
1155+
1156+
// Extract the value name (e.g., "Fitting.CONTENT_AWARE_FITTING")
1157+
var clipButton = nameCell.querySelector('.clip_button');
1158+
var text = clipButton ? clipButton.textContent.trim() : nameCell.textContent.trim();
1159+
1160+
if (!text) {
1161+
return;
1162+
}
1163+
1164+
// Get description for better search context
1165+
var description = descCell ? descCell.textContent.trim() : '';
1166+
var keywords = description ? description.toLowerCase() : '';
1167+
1168+
// Use section anchor or base href
1169+
var anchorId = section.getAttribute('id');
1170+
var resolved = anchorId ? baseHref + '#' + anchorId : baseHref;
1171+
1172+
pushEntry(buildSearchEntry('value', text, resolved, {
1173+
context: pageTitle,
1174+
keywords: keywords
1175+
}));
1176+
});
1177+
}
1178+
});
1179+
1180+
// Also index all tables that might contain constants/values outside of sections
1181+
var allTables = doc.querySelectorAll('table');
1182+
allTables.forEach(function(table) {
1183+
// Check if table has class indicators or if it's in body
1184+
var inSection = table.closest('div.section');
1185+
if (inSection) {
1186+
return; // Already processed in sections
1187+
}
1188+
1189+
var rows = table.querySelectorAll('tbody tr');
1190+
rows.forEach(function(row) {
1191+
var cells = row.querySelectorAll('td');
1192+
if (cells.length < 1) {
1193+
return;
1194+
}
1195+
var nameCell = cells[0];
1196+
var descCell = cells.length > 1 ? cells[1] : null;
1197+
1198+
// Look for clip_button or structured content
1199+
var clipButton = nameCell.querySelector('.clip_button');
1200+
if (!clipButton) {
1201+
return;
1202+
}
1203+
1204+
var text = clipButton.textContent.trim();
1205+
if (!text) {
1206+
return;
1207+
}
1208+
1209+
// Get description for context
1210+
var description = descCell ? descCell.textContent.trim() : '';
1211+
var keywords = description ? description.toLowerCase() : '';
1212+
1213+
pushEntry(buildSearchEntry('constant', text, baseHref, {
1214+
context: pageTitle,
1215+
keywords: keywords
1216+
}));
1217+
});
10641218
});
10651219

10661220
return entries;

0 commit comments

Comments
 (0)