Files
2026-03-10 18:04:25 -07:00

198 lines
5.7 KiB
JavaScript

/**
* Enhanced Search Main Entry Point
* Loads search engine and page manager for enhanced search page
* Does NOT interfere with default search behavior
*/
// Prevent multiple initializations
if (typeof window.EnhancedSearch !== 'undefined') {
} else {
// Import modules (will be loaded dynamically)
class EnhancedSearch {
constructor(options = {}) {
this.options = {
placeholder: options.placeholder || 'Search documentation...',
maxResults: options.maxResults || 20,
minQueryLength: 2,
highlightClass: 'search-highlight',
...options
};
this.isLoaded = false;
// Module instances
this.documentLoader = null;
this.searchEngine = null;
this.searchPageManager = null;
this.utils = null;
this.init();
}
async init() {
try {
// Load required modules
await this.loadModules();
// Initialize core modules
this.utils = new Utils();
this.documentLoader = new DocumentLoader();
this.searchEngine = new SearchEngine(this.utils);
// Load documents and initialize search engine (always needed)
await this.documentLoader.loadDocuments();
await this.searchEngine.initialize(this.documentLoader.getDocuments());
// Check if we're on the search page
const isSearchPage = this.isSearchPage();
if (isSearchPage) {
this.searchPageManager = new SearchPageManager();
}
this.isLoaded = true;
} catch (error) {
this.fallbackToDefaultSearch();
}
}
isSearchPage() {
return window.location.pathname.includes('/search') ||
window.location.pathname.includes('/search.html') ||
window.location.pathname.endsWith('search/') ||
document.querySelector('#enhanced-search-page-input') !== null ||
document.querySelector('#enhanced-search-page-results') !== null;
}
async loadModules() {
const moduleNames = [
'Utils',
'DocumentLoader',
'SearchEngine',
'SearchPageManager'
];
// Load modules with smart path resolution
const modulePromises = moduleNames.map(name =>
this.loadModuleWithFallback(name)
);
await Promise.all(modulePromises);
}
async loadModuleWithFallback(moduleName) {
const possiblePaths = this.getModulePaths(moduleName);
for (const path of possiblePaths) {
try {
await this.loadModule(path);
return;
} catch (error) {
// Continue to next path
}
}
throw new Error(`Failed to load module ${moduleName} from any path`);
}
getModulePaths(moduleName) {
const fileName = `${moduleName}.js`;
// Calculate nesting level to determine correct _static path
const pathParts = window.location.pathname.split('/').filter(part => part.length > 0);
const htmlFile = pathParts[pathParts.length - 1];
// Remove the HTML file from the count if it exists
let nestingLevel = pathParts.length;
if (htmlFile && htmlFile.endsWith('.html')) {
nestingLevel--;
}
// Build the correct _static path based on nesting level
const staticPrefix = nestingLevel > 0 ? '../'.repeat(nestingLevel) : './';
const staticPath = `${staticPrefix}_static`;
// Search assets only has modules directory
const moduleDir = 'modules';
// Generate paths in order of likelihood
const paths = [];
// 1. Most likely path based on calculated nesting
paths.push(`${staticPath}/${moduleDir}/${fileName}`);
// 2. Fallback static paths (for different nesting scenarios)
paths.push(`_static/${moduleDir}/${fileName}`);
paths.push(`./_static/${moduleDir}/${fileName}`);
if (nestingLevel > 1) {
paths.push(`../_static/${moduleDir}/${fileName}`);
}
// 3. Legacy fallback paths
paths.push(`./modules/${fileName}`);
paths.push(`../modules/${fileName}`);
paths.push(`modules/${fileName}`);
return paths;
}
async loadModule(src) {
return new Promise((resolve, reject) => {
const script = document.createElement('script');
script.src = src;
script.onload = resolve;
script.onerror = () => reject(new Error(`Failed to load module: ${src}`));
document.head.appendChild(script);
});
}
// Public API methods
search(query) {
if (!this.searchEngine) {
return [];
}
return this.searchEngine.search(query);
}
renderResults(results, query) {
// Use SearchPageManager for search page rendering
return '';
}
fallbackToDefaultSearch() {
// Don't interfere with default search - just fallback
}
getDocuments() {
return this.documentLoader ? this.documentLoader.getDocuments() : [];
}
get documents() {
return this.getDocuments();
}
getSearchEngine() {
return this.searchEngine;
}
getOptions() {
return this.options;
}
}
// Initialize the enhanced search system
window.EnhancedSearch = EnhancedSearch;
// Auto-initialize
document.addEventListener('DOMContentLoaded', function() {
// Create the global instance
window.enhancedSearchInstance = new EnhancedSearch({
placeholder: 'Search NVIDIA documentation...',
maxResults: 50
});
});
} // End of duplicate prevention check