234 lines
7.2 KiB
JavaScript
234 lines
7.2 KiB
JavaScript
// Results Component
|
|
import { LoadingProgress } from './LoadingProgress.js';
|
|
|
|
export class Results {
|
|
constructor() {
|
|
this.container = document.getElementById('results');
|
|
this.loadingProgress = new LoadingProgress(this.container);
|
|
this.init();
|
|
}
|
|
|
|
init() {
|
|
// Show welcome message initially
|
|
this.showWelcome();
|
|
}
|
|
|
|
showWelcome() {
|
|
if (this.container) {
|
|
this.container.innerHTML = `
|
|
<div class="welcome-message">
|
|
<h1>Python Documentation</h1>
|
|
<p>Search for any Python object in the sidebar to view its documentation.</p>
|
|
<p>Select a language to automatically translate the documentation.</p>
|
|
</div>
|
|
`;
|
|
}
|
|
}
|
|
|
|
showLoading(message = 'Loading documentation...', showProgress = true) {
|
|
if (this.container) {
|
|
this.loadingProgress.show(message, showProgress);
|
|
}
|
|
}
|
|
|
|
hideLoading() {
|
|
if (this.loadingProgress) {
|
|
this.loadingProgress.complete();
|
|
}
|
|
}
|
|
|
|
showError(message) {
|
|
if (this.container) {
|
|
this.container.innerHTML = `<div class="error-message">${message}</div>`;
|
|
}
|
|
}
|
|
|
|
displayDocumentation(data) {
|
|
if (!this.container) return;
|
|
|
|
const wrapper = document.createElement('div');
|
|
|
|
// Header with title
|
|
const header = document.createElement('div');
|
|
header.className = 'doc-header';
|
|
|
|
const title = document.createElement('h1');
|
|
title.className = 'doc-title';
|
|
title.textContent = data.object_name;
|
|
|
|
const meta = document.createElement('div');
|
|
meta.className = 'doc-meta';
|
|
meta.innerHTML = `
|
|
<span class="type-badge">${data.object_type || 'unknown'}</span>
|
|
${data.cached ? '<span class="doc-badge">Cached</span>' : ''}
|
|
`;
|
|
|
|
header.appendChild(title);
|
|
header.appendChild(meta);
|
|
wrapper.appendChild(header);
|
|
|
|
// Signature
|
|
if (data.signature) {
|
|
const signature = document.createElement('div');
|
|
signature.className = 'doc-signature';
|
|
signature.textContent = data.signature;
|
|
wrapper.appendChild(signature);
|
|
}
|
|
|
|
// Main documentation content
|
|
const docText = data.translated || data.original;
|
|
|
|
if (docText) {
|
|
const docSection = document.createElement('section');
|
|
docSection.className = 'doc-section';
|
|
|
|
const docTextEl = document.createElement('div');
|
|
docTextEl.className = 'doc-text';
|
|
docTextEl.textContent = docText;
|
|
|
|
docSection.appendChild(docTextEl);
|
|
wrapper.appendChild(docSection);
|
|
}
|
|
|
|
// Show original if translation exists (collapsible)
|
|
if (data.translated && data.original) {
|
|
const originalSection = document.createElement('details');
|
|
originalSection.className = 'doc-section';
|
|
originalSection.innerHTML = `
|
|
<summary style="cursor: pointer; font-weight: 500; margin-bottom: 0.5rem; color: var(--text-secondary);">
|
|
Original Documentation (English)
|
|
</summary>
|
|
<div class="doc-text" style="margin-top: 0.5rem;">${data.original}</div>
|
|
`;
|
|
wrapper.appendChild(originalSection);
|
|
}
|
|
|
|
if (!data.original && !data.translated) {
|
|
const noDoc = document.createElement('div');
|
|
noDoc.className = 'doc-text';
|
|
noDoc.textContent = 'No documentation available for this object.';
|
|
wrapper.appendChild(noDoc);
|
|
}
|
|
|
|
this.container.innerHTML = '';
|
|
this.container.appendChild(wrapper);
|
|
}
|
|
|
|
displayCourse(courseData) {
|
|
if (!this.container) return;
|
|
|
|
const wrapper = document.createElement('div');
|
|
wrapper.className = 'course-content';
|
|
|
|
const title = document.createElement('h1');
|
|
title.textContent = courseData.title || 'Python Course';
|
|
wrapper.appendChild(title);
|
|
|
|
if (courseData.sections && courseData.sections.length > 0) {
|
|
courseData.sections.forEach(section => {
|
|
const sectionDiv = this.createCourseSection(section);
|
|
wrapper.appendChild(sectionDiv);
|
|
});
|
|
}
|
|
|
|
this.container.innerHTML = '';
|
|
this.container.appendChild(wrapper);
|
|
}
|
|
|
|
createCourseSection(section) {
|
|
const sectionDiv = document.createElement('section');
|
|
sectionDiv.className = 'course-section';
|
|
sectionDiv.id = `section-${section.id || section.title.toLowerCase().replace(/\s+/g, '-')}`;
|
|
|
|
// Parse and render markdown
|
|
if (section.markdown) {
|
|
// Configure marked options
|
|
if (typeof marked !== 'undefined') {
|
|
marked.setOptions({
|
|
highlight: function(code, lang) {
|
|
if (typeof hljs !== 'undefined' && lang && hljs.getLanguage(lang)) {
|
|
try {
|
|
return hljs.highlight(code, { language: lang }).value;
|
|
} catch (err) {
|
|
console.error('Highlight error:', err);
|
|
}
|
|
}
|
|
if (typeof hljs !== 'undefined') {
|
|
return hljs.highlightAuto(code).value;
|
|
}
|
|
return code;
|
|
},
|
|
breaks: true,
|
|
gfm: true
|
|
});
|
|
|
|
// Convert markdown to HTML
|
|
const htmlContent = marked.parse(section.markdown);
|
|
|
|
// Create a container for the markdown content
|
|
const contentDiv = document.createElement('div');
|
|
contentDiv.className = 'markdown-content';
|
|
contentDiv.innerHTML = htmlContent;
|
|
|
|
// Add IDs to headings for navigation
|
|
contentDiv.querySelectorAll('h1, h2, h3, h4').forEach((heading) => {
|
|
const text = heading.textContent.trim();
|
|
const id = text.toLowerCase()
|
|
.replace(/[^\w\s-]/g, '')
|
|
.replace(/\s+/g, '-')
|
|
.replace(/-+/g, '-')
|
|
.trim();
|
|
heading.id = id;
|
|
});
|
|
|
|
// Highlight code blocks
|
|
if (typeof hljs !== 'undefined') {
|
|
contentDiv.querySelectorAll('pre code').forEach((block) => {
|
|
hljs.highlightElement(block);
|
|
});
|
|
}
|
|
|
|
sectionDiv.appendChild(contentDiv);
|
|
}
|
|
} else if (section.content && section.content.length > 0) {
|
|
// Fallback to old format
|
|
section.content.forEach(item => {
|
|
if (item.startsWith('```')) {
|
|
const codeDiv = document.createElement('pre');
|
|
codeDiv.className = 'doc-signature';
|
|
codeDiv.textContent = item.replace(/```python\n?/g, '').replace(/```/g, '').trim();
|
|
sectionDiv.appendChild(codeDiv);
|
|
} else {
|
|
const itemDiv = document.createElement('p');
|
|
itemDiv.className = 'doc-text';
|
|
itemDiv.textContent = item;
|
|
sectionDiv.appendChild(itemDiv);
|
|
}
|
|
});
|
|
}
|
|
|
|
return sectionDiv;
|
|
}
|
|
|
|
scrollToSection(section) {
|
|
const sectionId = section.id || section.title.toLowerCase().replace(/\s+/g, '-');
|
|
const sectionElement = document.getElementById(`section-${sectionId}`);
|
|
if (sectionElement) {
|
|
sectionElement.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
|
return;
|
|
}
|
|
|
|
// Try to find by heading ID
|
|
const headingId = section.title.toLowerCase()
|
|
.replace(/[^\w\s-]/g, '')
|
|
.replace(/\s+/g, '-')
|
|
.replace(/-+/g, '-')
|
|
.trim();
|
|
const headingElement = document.getElementById(headingId);
|
|
if (headingElement) {
|
|
headingElement.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
|
}
|
|
}
|
|
}
|
|
|