/**
* HTML Generator - Create standalone or external-resources HTML files
*
* Generates complete HTML documents that use TestDrive-JSUI with two modes:
* 1. Standalone (default): All JS/CSS embedded inline
* 2. External: References external files under _jsui/ directory
*
* Usage:
* ```javascript
* const generator = new HTMLGenerator({
* title: 'My Document',
* markdown: '# Hello World',
* standalone: true // or false for external mode
* });
*
* const html = generator.generate();
* ```
*/
class HTMLGenerator {
constructor(options = {}) {
this.options = {
title: options.title || 'TestDrive-JSUI Editor',
description: options.description || 'Interactive markdown editor',
markdown: options.markdown || '# Welcome\n\nStart editing...',
mode: options.mode || 'edit', // 'edit' or 'view'
theme: options.theme || 'github',
standalone: options.standalone !== false, // default true
controls: {
editControl: options.controls?.editControl !== false,
statusControl: options.controls?.statusControl !== false,
contentsControl: options.controls?.contentsControl !== false,
debugControl: options.controls?.debugControl || false
},
shortcuts: options.shortcuts !== false,
autosave: options.autosave || false,
baseUrl: options.baseUrl || '_jsui', // For external mode
includeMarkedJS: options.includeMarkedJS !== false // Include marked.js CDN
};
}
/**
* Generate HTML document
*/
generate() {
if (this.options.standalone) {
return this.generateStandalone();
} else {
return this.generateExternal();
}
}
/**
* Generate standalone HTML with all resources embedded
*/
generateStandalone() {
return `
${this.escapeHtml(this.options.title)}
${this.generateInlineStyles()}
${this.generateHeader()}
${this.generateContainer()}
${this.generateMarkedJS()}
${this.generateInlineScripts()}
${this.generateInitScript()}
`;
}
/**
* Generate HTML with external resource references
*/
generateExternal() {
const baseUrl = this.options.baseUrl;
return `
${this.escapeHtml(this.options.title)}
${this.generateHeader()}
${this.generateContainer()}
${this.generateMarkedJS()}
${this.generateInitScript()}
`;
}
/**
* Generate header section
*/
generateHeader() {
if (!this.options.description) {
return '';
}
return `
`;
}
/**
* Generate container div
*/
generateContainer() {
return `
`;
}
/**
* Generate marked.js CDN script
*/
generateMarkedJS() {
if (!this.options.includeMarkedJS) {
return '';
}
return `
`;
}
/**
* Generate inline styles for standalone mode
*/
generateInlineStyles() {
return ` `;
}
/**
* Generate inline JavaScript for standalone mode
*
* Note: In a real implementation, this would read and embed actual JS files.
* For now, it provides a placeholder comment.
*/
generateInlineScripts() {
return `
`;
}
/**
* Generate initialization script
*/
generateInitScript() {
const config = {
container: '#editor-container',
markdown: this.options.markdown,
mode: this.options.mode,
theme: this.options.theme,
controls: this.options.controls,
shortcuts: this.options.shortcuts,
autosave: this.options.autosave
};
return ` `;
}
/**
* Escape HTML special characters
*/
escapeHtml(text) {
const map = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": '''
};
return text.replace(/[&<>"']/g, m => map[m]);
}
/**
* Save generated HTML to file (Node.js only)
*/
saveToFile(filename) {
if (typeof require === 'undefined') {
throw new Error('saveToFile() requires Node.js environment');
}
const fs = require('fs');
const html = this.generate();
fs.writeFileSync(filename, html, 'utf8');
return filename;
}
/**
* Download generated HTML (browser only)
*/
download(filename = 'testdrive-jsui-editor.html') {
const html = this.generate();
const blob = new Blob([html], { type: 'text/html' });
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = filename;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
URL.revokeObjectURL(url);
}
}
// Export for module systems or attach to global
if (typeof module !== 'undefined' && module.exports) {
module.exports = HTMLGenerator;
} else {
window.HTMLGenerator = HTMLGenerator;
}