Merge pull request #94 from gamosoft/features/fix-syntax-overlay
Features/fix syntax overlay
This commit is contained in:
commit
a723250e4c
|
|
@ -631,18 +631,20 @@ function noteApp() {
|
||||||
// Store code blocks and inline code with placeholders to protect from other patterns
|
// Store code blocks and inline code with placeholders to protect from other patterns
|
||||||
const codePlaceholders = [];
|
const codePlaceholders = [];
|
||||||
|
|
||||||
// Frontmatter (must be at start) - protect it
|
// Code blocks FIRST - protect them before anything else
|
||||||
html = html.replace(/^(---\n[\s\S]*?\n---)/m, (match) => {
|
|
||||||
codePlaceholders.push('<span class="md-frontmatter">' + match + '</span>');
|
|
||||||
return `\x00CODE${codePlaceholders.length - 1}\x00`;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Code blocks - protect them
|
|
||||||
html = html.replace(/(```[\s\S]*?```)/g, (match) => {
|
html = html.replace(/(```[\s\S]*?```)/g, (match) => {
|
||||||
codePlaceholders.push('<span class="md-codeblock">' + match + '</span>');
|
codePlaceholders.push('<span class="md-codeblock">' + match + '</span>');
|
||||||
return `\x00CODE${codePlaceholders.length - 1}\x00`;
|
return `\x00CODE${codePlaceholders.length - 1}\x00`;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Frontmatter (must be at VERY start of document, not any line)
|
||||||
|
if (html.startsWith('---\n')) {
|
||||||
|
html = html.replace(/^(---\n[\s\S]*?\n---)/, (match) => {
|
||||||
|
codePlaceholders.push('<span class="md-frontmatter">' + match + '</span>');
|
||||||
|
return `\x00CODE${codePlaceholders.length - 1}\x00`;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Inline code - protect it
|
// Inline code - protect it
|
||||||
html = html.replace(/`([^`\n]+)`/g, (match) => {
|
html = html.replace(/`([^`\n]+)`/g, (match) => {
|
||||||
codePlaceholders.push('<span class="md-code">' + match + '</span>');
|
codePlaceholders.push('<span class="md-code">' + match + '</span>');
|
||||||
|
|
@ -681,6 +683,10 @@ function noteApp() {
|
||||||
// Restore protected code blocks
|
// Restore protected code blocks
|
||||||
html = html.replace(/\x00CODE(\d+)\x00/g, (match, index) => codePlaceholders[parseInt(index)]);
|
html = html.replace(/\x00CODE(\d+)\x00/g, (match, index) => codePlaceholders[parseInt(index)]);
|
||||||
|
|
||||||
|
// Add trailing space to match textarea's phantom line for cursor
|
||||||
|
// This ensures the overlay and textarea have the same content height
|
||||||
|
html += '\n ';
|
||||||
|
|
||||||
return html;
|
return html;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -431,11 +431,29 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Editor styling */
|
/* Editor styling */
|
||||||
.editor-textarea {
|
/* Shared editor styles - MUST be identical for textarea and overlay */
|
||||||
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
|
.editor-textarea,
|
||||||
|
.syntax-overlay {
|
||||||
|
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', monospace;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1.6;
|
||||||
tab-size: 2;
|
tab-size: 2;
|
||||||
|
letter-spacing: normal;
|
||||||
|
word-spacing: normal;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
word-wrap: break-word;
|
||||||
|
overflow-wrap: break-word;
|
||||||
|
padding: 1.5rem;
|
||||||
|
margin: 0;
|
||||||
|
border: none;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.editor-textarea {
|
||||||
background-color: var(--bg-primary) !important;
|
background-color: var(--bg-primary) !important;
|
||||||
color: var(--text-primary) !important;
|
color: var(--text-primary) !important;
|
||||||
|
resize: none;
|
||||||
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Syntax Highlighting Overlay */
|
/* Syntax Highlighting Overlay */
|
||||||
|
|
@ -448,6 +466,8 @@
|
||||||
.editor-wrapper .editor-textarea {
|
.editor-wrapper .editor-textarea {
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
|
flex: 1;
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
.editor-wrapper.syntax-highlight .editor-textarea {
|
.editor-wrapper.syntax-highlight .editor-textarea {
|
||||||
color: transparent !important;
|
color: transparent !important;
|
||||||
|
|
@ -457,18 +477,17 @@
|
||||||
.syntax-overlay {
|
.syntax-overlay {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
inset: 0;
|
inset: 0;
|
||||||
padding: 1.5rem;
|
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
white-space: pre-wrap;
|
overflow: auto;
|
||||||
word-wrap: break-word;
|
|
||||||
overflow: hidden;
|
|
||||||
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
|
|
||||||
font-size: inherit;
|
|
||||||
line-height: inherit;
|
|
||||||
tab-size: 2;
|
|
||||||
color: var(--text-primary);
|
color: var(--text-primary);
|
||||||
background-color: var(--bg-primary);
|
background-color: var(--bg-primary);
|
||||||
z-index: 0;
|
z-index: 0;
|
||||||
|
/* Hide scrollbars but allow programmatic scrolling */
|
||||||
|
scrollbar-width: none; /* Firefox */
|
||||||
|
-ms-overflow-style: none; /* IE/Edge */
|
||||||
|
}
|
||||||
|
.syntax-overlay::-webkit-scrollbar {
|
||||||
|
display: none; /* Chrome/Safari */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Zen Mode Styles */
|
/* Zen Mode Styles */
|
||||||
|
|
@ -487,10 +506,7 @@
|
||||||
.zen-mode-active .zen-editor-container .editor-wrapper {
|
.zen-mode-active .zen-editor-container .editor-wrapper {
|
||||||
background-color: var(--bg-primary);
|
background-color: var(--bg-primary);
|
||||||
}
|
}
|
||||||
.zen-mode-active .zen-editor-container .editor-textarea {
|
.zen-mode-active .zen-editor-container .editor-textarea,
|
||||||
font-size: 18px;
|
|
||||||
line-height: 1.8;
|
|
||||||
}
|
|
||||||
.zen-mode-active .zen-editor-container .syntax-overlay {
|
.zen-mode-active .zen-editor-container .syntax-overlay {
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
line-height: 1.8;
|
line-height: 1.8;
|
||||||
|
|
@ -535,7 +551,7 @@
|
||||||
.syntax-overlay .md-heading { color: var(--accent-primary); font-weight: 600; }
|
.syntax-overlay .md-heading { color: var(--accent-primary); font-weight: 600; }
|
||||||
.syntax-overlay .md-bold { color: var(--text-primary); font-weight: 700; }
|
.syntax-overlay .md-bold { color: var(--text-primary); font-weight: 700; }
|
||||||
.syntax-overlay .md-italic { color: var(--text-secondary); font-style: italic; }
|
.syntax-overlay .md-italic { color: var(--text-secondary); font-style: italic; }
|
||||||
.syntax-overlay .md-code { color: var(--accent-secondary, var(--accent-primary)); background: var(--bg-tertiary); padding: 1px 3px; border-radius: 3px; }
|
.syntax-overlay .md-code { color: var(--accent-secondary, var(--accent-primary)); background: var(--bg-tertiary); border-radius: 2px; }
|
||||||
.syntax-overlay .md-link { color: var(--link-color, var(--accent-primary)); }
|
.syntax-overlay .md-link { color: var(--link-color, var(--accent-primary)); }
|
||||||
.syntax-overlay .md-link-url { color: var(--text-tertiary); }
|
.syntax-overlay .md-link-url { color: var(--text-tertiary); }
|
||||||
.syntax-overlay .md-list { color: var(--accent-primary); }
|
.syntax-overlay .md-list { color: var(--accent-primary); }
|
||||||
|
|
@ -2089,7 +2105,7 @@
|
||||||
@dragenter="onEditorDragEnter($event)"
|
@dragenter="onEditorDragEnter($event)"
|
||||||
@dragleave="onEditorDragLeave($event)"
|
@dragleave="onEditorDragLeave($event)"
|
||||||
@paste="handlePaste($event)"
|
@paste="handlePaste($event)"
|
||||||
:class="'flex-1 w-full p-6 resize-none focus:outline-none editor-textarea' + (draggedItem && dropTarget === 'editor' ? ' link-drop-target' : '')"
|
:class="'flex-1 w-full resize-none focus:outline-none editor-textarea' + (draggedItem && dropTarget === 'editor' ? ' link-drop-target' : '')"
|
||||||
:style="'background-color: var(--bg-primary); color: var(--text-primary);' + (draggedItem && dropTarget === 'editor' ? ' outline: 2px dashed var(--accent-primary); outline-offset: -2px; box-shadow: 0 0 20px var(--accent-light);' : '')"
|
:style="'background-color: var(--bg-primary); color: var(--text-primary);' + (draggedItem && dropTarget === 'editor' ? ' outline: 2px dashed var(--accent-primary); outline-offset: -2px; box-shadow: 0 0 20px var(--accent-light);' : '')"
|
||||||
:placeholder="draggedItem && dropTarget === 'editor' ? '💡 Drop here to insert at cursor position...' : 'Start writing in markdown...'"
|
:placeholder="draggedItem && dropTarget === 'editor' ? '💡 Drop here to insert at cursor position...' : 'Start writing in markdown...'"
|
||||||
></textarea>
|
></textarea>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue