style: Improve markdown editor styling and functionality
- Update dark mode button icon and styling - Add styling for new collection button - Apply default iframe styles in preview pane - Adjust vertical divider height in header buttons - Improve handling of JSX-like attributes in markdown - Add support for new collection functionality - Refine file loading logic in view mode - Improve dark mode toggle icon and integration - Update UI for edit/view mode toggle button
This commit is contained in:
@@ -33,9 +33,14 @@ async function autoLoadPageInViewMode() {
|
||||
|
||||
// If we found a page to load, load it
|
||||
if (pageToLoad) {
|
||||
await editor.loadFile(pageToLoad);
|
||||
// Highlight the file in the tree and expand parent directories
|
||||
fileTree.selectAndExpandPath(pageToLoad);
|
||||
// Use fileTree.onFileSelect to handle both text and binary files
|
||||
if (fileTree.onFileSelect) {
|
||||
fileTree.onFileSelect({ path: pageToLoad, isDirectory: false });
|
||||
} else {
|
||||
// Fallback to direct loading (for text files only)
|
||||
await editor.loadFile(pageToLoad);
|
||||
fileTree.selectAndExpandPath(pageToLoad);
|
||||
}
|
||||
} else {
|
||||
// No files found, show empty state message
|
||||
editor.previewElement.innerHTML = `
|
||||
@@ -397,6 +402,9 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||
// Highlight the file in the tree
|
||||
fileTree.selectAndExpandPath(item.path);
|
||||
|
||||
// Save as last viewed page (for binary files too)
|
||||
editor.saveLastViewedPage(item.path);
|
||||
|
||||
// Update URL to reflect current file
|
||||
updateURL(currentCollection, item.path, isEditMode);
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ class DarkMode {
|
||||
this.isDark = !this.isDark;
|
||||
localStorage.setItem(Config.STORAGE_KEYS.DARK_MODE, this.isDark);
|
||||
this.apply();
|
||||
|
||||
|
||||
Logger.debug(`Dark mode ${this.isDark ? 'enabled' : 'disabled'}`);
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ class DarkMode {
|
||||
if (this.isDark) {
|
||||
document.body.classList.add('dark-mode');
|
||||
const btn = document.getElementById('darkModeBtn');
|
||||
if (btn) btn.textContent = '☀️';
|
||||
if (btn) btn.innerHTML = '<i class="bi bi-sun-fill"></i>';
|
||||
|
||||
// Update mermaid theme
|
||||
if (window.mermaid) {
|
||||
@@ -36,7 +36,7 @@ class DarkMode {
|
||||
} else {
|
||||
document.body.classList.remove('dark-mode');
|
||||
const btn = document.getElementById('darkModeBtn');
|
||||
if (btn) btn.textContent = '🌙';
|
||||
if (btn) btn.innerHTML = '<i class="bi bi-moon-fill"></i>';
|
||||
|
||||
// Update mermaid theme
|
||||
if (window.mermaid) {
|
||||
|
||||
@@ -336,6 +336,60 @@ class MarkdownEditor {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert JSX-style attributes to HTML attributes
|
||||
* Handles style={{...}} and boolean attributes like allowFullScreen={true}
|
||||
*/
|
||||
convertJSXToHTML(content) {
|
||||
Logger.debug('Converting JSX to HTML...');
|
||||
|
||||
// Convert style={{...}} to style="..."
|
||||
// This regex finds style={{...}} and converts the object notation to CSS string
|
||||
content = content.replace(/style=\{\{([^}]+)\}\}/g, (match, styleContent) => {
|
||||
Logger.debug(`Found JSX style: ${match}`);
|
||||
|
||||
// Parse the object-like syntax and convert to CSS
|
||||
const cssRules = styleContent
|
||||
.split(',')
|
||||
.map(rule => {
|
||||
const colonIndex = rule.indexOf(':');
|
||||
if (colonIndex === -1) return '';
|
||||
|
||||
const key = rule.substring(0, colonIndex).trim();
|
||||
const value = rule.substring(colonIndex + 1).trim();
|
||||
|
||||
if (!key || !value) return '';
|
||||
|
||||
// Convert camelCase to kebab-case (e.g., paddingTop -> padding-top)
|
||||
const cssKey = key.replace(/([A-Z])/g, '-$1').toLowerCase();
|
||||
|
||||
// Remove quotes from value
|
||||
let cssValue = value.replace(/^['"]|['"]$/g, '');
|
||||
|
||||
return `${cssKey}: ${cssValue}`;
|
||||
})
|
||||
.filter(rule => rule)
|
||||
.join('; ');
|
||||
|
||||
Logger.debug(`Converted to CSS: style="${cssRules}"`);
|
||||
return `style="${cssRules}"`;
|
||||
});
|
||||
|
||||
// Convert boolean attributes like allowFullScreen={true} to allowfullscreen
|
||||
content = content.replace(/(\w+)=\{true\}/g, (match, attrName) => {
|
||||
Logger.debug(`Found boolean attribute: ${match}`);
|
||||
// Convert camelCase to lowercase for HTML attributes
|
||||
const htmlAttr = attrName.toLowerCase();
|
||||
Logger.debug(`Converted to: ${htmlAttr}`);
|
||||
return htmlAttr;
|
||||
});
|
||||
|
||||
// Remove attributes set to {false}
|
||||
content = content.replace(/\s+\w+=\{false\}/g, '');
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render preview from markdown content
|
||||
* Can be called with explicit content (for view mode) or from editor (for edit mode)
|
||||
@@ -355,11 +409,12 @@ class MarkdownEditor {
|
||||
}
|
||||
|
||||
try {
|
||||
// Step 1: Process macros
|
||||
let processedContent = markdown;
|
||||
// Step 0: Convert JSX-style syntax to HTML
|
||||
let processedContent = this.convertJSXToHTML(markdown);
|
||||
|
||||
// Step 1: Process macros
|
||||
if (this.macroProcessor) {
|
||||
const processingResult = await this.macroProcessor.processMacros(markdown);
|
||||
const processingResult = await this.macroProcessor.processMacros(processedContent);
|
||||
processedContent = processingResult.content;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user