overtype 1.2.3 → 1.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +36 -15
- package/dist/overtype.cjs +150 -39
- package/dist/overtype.cjs.map +2 -2
- package/dist/overtype.d.ts +169 -0
- package/dist/overtype.esm.js +150 -39
- package/dist/overtype.esm.js.map +2 -2
- package/dist/overtype.js +155 -39
- package/dist/overtype.js.map +2 -2
- package/dist/overtype.min.js +84 -68
- package/package.json +4 -2
- package/src/link-tooltip.js +16 -16
- package/src/overtype.d.ts +23 -1
- package/src/overtype.js +22 -12
- package/src/parser.js +127 -68
- package/src/styles.js +16 -8
- package/src/toolbar.js +63 -2
package/README.md
CHANGED
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
# OverType
|
|
2
2
|
|
|
3
|
-
A lightweight markdown editor library with perfect WYSIWYG alignment using an invisible textarea overlay technique. Includes optional toolbar. ~
|
|
3
|
+
A lightweight markdown editor library with perfect WYSIWYG alignment using an invisible textarea overlay technique. Includes optional toolbar. ~84KB minified with all features.
|
|
4
|
+
|
|
5
|
+
## Live Examples
|
|
6
|
+
|
|
7
|
+
🎮 **Try it out**: [Interactive demos on overtype.dev](https://overtype.dev)
|
|
8
|
+
- [Basic Editor](https://overtype.dev/#basic-editor)
|
|
9
|
+
- [With Toolbar](https://overtype.dev/#toolbar)
|
|
10
|
+
- [Multiple Instances](https://overtype.dev/#multiple-instances)
|
|
11
|
+
- [View Modes](https://overtype.dev/#view-modes)
|
|
12
|
+
- [Custom Themes](https://overtype.dev/#custom-themes)
|
|
13
|
+
- [All Markdown Features](https://overtype.dev/#markdown-features)
|
|
4
14
|
|
|
5
15
|
## Features
|
|
6
16
|
|
|
@@ -9,7 +19,7 @@ A lightweight markdown editor library with perfect WYSIWYG alignment using an in
|
|
|
9
19
|
- ⌨️ **Keyboard shortcuts** - Common markdown shortcuts (Cmd/Ctrl+B for bold, etc.)
|
|
10
20
|
- 📱 **Mobile optimized** - Responsive design with mobile-specific styles
|
|
11
21
|
- 🔄 **DOM persistence aware** - Recovers from existing DOM (perfect for HyperClay and similar platforms)
|
|
12
|
-
- 🚀 **Lightweight** - ~
|
|
22
|
+
- 🚀 **Lightweight** - ~84KB minified
|
|
13
23
|
- 🎯 **Optional toolbar** - Clean, minimal toolbar with all essential formatting
|
|
14
24
|
- ✨ **Smart shortcuts** - Keyboard shortcuts with selection preservation
|
|
15
25
|
- 📝 **Smart list continuation** - GitHub-style automatic list continuation on Enter
|
|
@@ -25,7 +35,7 @@ We overlap an invisible textarea on top of styled output, giving the illusion of
|
|
|
25
35
|
|
|
26
36
|
| Feature | OverType | HyperMD | Milkdown | TUI Editor | EasyMDE |
|
|
27
37
|
|---------|----------|---------|----------|------------|---------|
|
|
28
|
-
| **Size** | ~
|
|
38
|
+
| **Size** | ~84KB | 364.02 KB | 344.51 KB | 560.99 KB | 323.69 KB |
|
|
29
39
|
| **Dependencies** | Bundled | CodeMirror | ProseMirror + plugins | Multiple libs | CodeMirror |
|
|
30
40
|
| **Setup** | Single file | Complex config | Build step required | Complex config | Moderate |
|
|
31
41
|
| **Approach** | Invisible textarea | ContentEditable | ContentEditable | ContentEditable | CodeMirror |
|
|
@@ -212,20 +222,26 @@ const [editor] = new OverType('#editor', {
|
|
|
212
222
|
const markdown = editor.getValue();
|
|
213
223
|
// Returns: "# Title\n\n**Bold** text with [links](https://example.com)"
|
|
214
224
|
|
|
215
|
-
// Get rendered HTML for
|
|
225
|
+
// Get rendered HTML with syntax markers (for debugging/inspection)
|
|
216
226
|
const html = editor.getRenderedHTML();
|
|
217
|
-
// Returns
|
|
227
|
+
// Returns HTML with <span class="syntax-marker"> elements visible
|
|
218
228
|
|
|
219
|
-
// Get HTML
|
|
220
|
-
const
|
|
221
|
-
// Returns HTML
|
|
229
|
+
// Get clean HTML for export (no OverType-specific markup)
|
|
230
|
+
const cleanHTML = editor.getRenderedHTML({ cleanHTML: true });
|
|
231
|
+
// Returns clean HTML suitable for saving/exporting
|
|
222
232
|
|
|
223
|
-
//
|
|
233
|
+
// Convenience method for clean HTML
|
|
234
|
+
const exportHTML = editor.getCleanHTML();
|
|
235
|
+
// Same as getRenderedHTML({ cleanHTML: true })
|
|
236
|
+
|
|
237
|
+
// Get the current preview element's HTML (actual DOM content)
|
|
224
238
|
const previewHTML = editor.getPreviewHTML();
|
|
225
239
|
// Returns exactly what's shown in the editor's preview layer
|
|
226
240
|
|
|
227
|
-
// Example:
|
|
228
|
-
|
|
241
|
+
// Example: Export clean HTML to server
|
|
242
|
+
const htmlToSave = editor.getCleanHTML(); // No syntax markers
|
|
243
|
+
// Example: Clone exact preview appearance
|
|
244
|
+
document.getElementById('clone').innerHTML = editor.getPreviewHTML();
|
|
229
245
|
```
|
|
230
246
|
|
|
231
247
|
### Stats Bar
|
|
@@ -371,11 +387,12 @@ editor.getValue()
|
|
|
371
387
|
editor.setValue(markdown)
|
|
372
388
|
|
|
373
389
|
// Get rendered HTML of the current content
|
|
374
|
-
editor.getRenderedHTML()
|
|
375
|
-
editor.getRenderedHTML(true)
|
|
390
|
+
editor.getRenderedHTML() // With syntax markers (for debugging)
|
|
391
|
+
editor.getRenderedHTML({ cleanHTML: true }) // Clean HTML without OverType markup
|
|
392
|
+
editor.getCleanHTML() // Alias for getRenderedHTML({ cleanHTML: true })
|
|
376
393
|
|
|
377
394
|
// Get the current preview element's HTML
|
|
378
|
-
editor.getPreviewHTML() //
|
|
395
|
+
editor.getPreviewHTML() // Actual DOM content from preview layer
|
|
379
396
|
|
|
380
397
|
// Change theme
|
|
381
398
|
editor.setTheme('cave') // Built-in theme name
|
|
@@ -566,7 +583,7 @@ MIT
|
|
|
566
583
|
- **Pluggable parser system** - Support for any programming language or syntax
|
|
567
584
|
- **Parser registry** - Automatic language detection by file extension or MIME type
|
|
568
585
|
- **Cleaner separation** - Extracted the overlay technique without markdown-specific features
|
|
569
|
-
- **Smaller footprint** - ~
|
|
586
|
+
- **Smaller footprint** - ~84KB minified (vs OverType's ~78KB)
|
|
570
587
|
|
|
571
588
|
Key components extracted from OverType to Synesthesia:
|
|
572
589
|
- The transparent textarea overlay technique for perfect WYSIWYG alignment
|
|
@@ -581,3 +598,7 @@ If you need a markdown editor with toolbar and formatting features, use OverType
|
|
|
581
598
|
|
|
582
599
|
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
583
600
|
|
|
601
|
+
---
|
|
602
|
+
|
|
603
|
+
Ready for another radical idea?
|
|
604
|
+
[Let's remove every layer of the web application stack.](https://hyperclay.com)
|
package/dist/overtype.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* OverType v1.2.
|
|
2
|
+
* OverType v1.2.4
|
|
3
3
|
* A lightweight markdown editor library with perfect WYSIWYG alignment
|
|
4
4
|
* @license MIT
|
|
5
5
|
* @author Demo User
|
|
@@ -155,6 +155,17 @@ var MarkdownParser = class {
|
|
|
155
155
|
html = html.replace(new RegExp("(?<!_)_(?!_)(.+?)(?<!_)_(?!_)", "g"), '<em><span class="syntax-marker">_</span>$1<span class="syntax-marker">_</span></em>');
|
|
156
156
|
return html;
|
|
157
157
|
}
|
|
158
|
+
/**
|
|
159
|
+
* Parse strikethrough text
|
|
160
|
+
* Supports both single (~) and double (~~) tildes, but rejects 3+ tildes
|
|
161
|
+
* @param {string} html - HTML with potential strikethrough markdown
|
|
162
|
+
* @returns {string} HTML with strikethrough styling
|
|
163
|
+
*/
|
|
164
|
+
static parseStrikethrough(html) {
|
|
165
|
+
html = html.replace(new RegExp("(?<!~)~~(?!~)(.+?)(?<!~)~~(?!~)", "g"), '<del><span class="syntax-marker">~~</span>$1<span class="syntax-marker">~~</span></del>');
|
|
166
|
+
html = html.replace(new RegExp("(?<!~)~(?!~)(.+?)(?<!~)~(?!~)", "g"), '<del><span class="syntax-marker">~</span>$1<span class="syntax-marker">~</span></del>');
|
|
167
|
+
return html;
|
|
168
|
+
}
|
|
158
169
|
/**
|
|
159
170
|
* Parse inline code
|
|
160
171
|
* @param {string} html - HTML with potential code markdown
|
|
@@ -217,6 +228,7 @@ var MarkdownParser = class {
|
|
|
217
228
|
sanctuaries.set(placeholder, match);
|
|
218
229
|
return placeholder;
|
|
219
230
|
});
|
|
231
|
+
html = this.parseStrikethrough(html);
|
|
220
232
|
html = this.parseBold(html);
|
|
221
233
|
html = this.parseItalic(html);
|
|
222
234
|
sanctuaries.forEach((content, placeholder) => {
|
|
@@ -351,6 +363,17 @@ var MarkdownParser = class {
|
|
|
351
363
|
container.insertBefore(currentList, child);
|
|
352
364
|
listType = newType;
|
|
353
365
|
}
|
|
366
|
+
const indentationNodes = [];
|
|
367
|
+
for (const node of child.childNodes) {
|
|
368
|
+
if (node.nodeType === 3 && node.textContent.match(/^\u00A0+$/)) {
|
|
369
|
+
indentationNodes.push(node.cloneNode(true));
|
|
370
|
+
} else if (node === listItem) {
|
|
371
|
+
break;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
indentationNodes.forEach((node) => {
|
|
375
|
+
listItem.insertBefore(node, listItem.firstChild);
|
|
376
|
+
});
|
|
354
377
|
currentList.appendChild(listItem);
|
|
355
378
|
child.remove();
|
|
356
379
|
} else {
|
|
@@ -368,15 +391,35 @@ var MarkdownParser = class {
|
|
|
368
391
|
static postProcessHTMLManual(html) {
|
|
369
392
|
let processed = html;
|
|
370
393
|
processed = processed.replace(/((?:<div>(?: )*<li class="bullet-list">.*?<\/li><\/div>\s*)+)/gs, (match) => {
|
|
371
|
-
const
|
|
372
|
-
if (
|
|
394
|
+
const divs = match.match(/<div>(?: )*<li class="bullet-list">.*?<\/li><\/div>/gs) || [];
|
|
395
|
+
if (divs.length > 0) {
|
|
396
|
+
const items = divs.map((div) => {
|
|
397
|
+
const indentMatch = div.match(/<div>((?: )*)<li/);
|
|
398
|
+
const listItemMatch = div.match(/<li class="bullet-list">.*?<\/li>/);
|
|
399
|
+
if (indentMatch && listItemMatch) {
|
|
400
|
+
const indentation = indentMatch[1];
|
|
401
|
+
const listItem = listItemMatch[0];
|
|
402
|
+
return listItem.replace(/<li class="bullet-list">/, `<li class="bullet-list">${indentation}`);
|
|
403
|
+
}
|
|
404
|
+
return listItemMatch ? listItemMatch[0] : "";
|
|
405
|
+
}).filter(Boolean);
|
|
373
406
|
return "<ul>" + items.join("") + "</ul>";
|
|
374
407
|
}
|
|
375
408
|
return match;
|
|
376
409
|
});
|
|
377
410
|
processed = processed.replace(/((?:<div>(?: )*<li class="ordered-list">.*?<\/li><\/div>\s*)+)/gs, (match) => {
|
|
378
|
-
const
|
|
379
|
-
if (
|
|
411
|
+
const divs = match.match(/<div>(?: )*<li class="ordered-list">.*?<\/li><\/div>/gs) || [];
|
|
412
|
+
if (divs.length > 0) {
|
|
413
|
+
const items = divs.map((div) => {
|
|
414
|
+
const indentMatch = div.match(/<div>((?: )*)<li/);
|
|
415
|
+
const listItemMatch = div.match(/<li class="ordered-list">.*?<\/li>/);
|
|
416
|
+
if (indentMatch && listItemMatch) {
|
|
417
|
+
const indentation = indentMatch[1];
|
|
418
|
+
const listItem = listItemMatch[0];
|
|
419
|
+
return listItem.replace(/<li class="ordered-list">/, `<li class="ordered-list">${indentation}`);
|
|
420
|
+
}
|
|
421
|
+
return listItemMatch ? listItemMatch[0] : "";
|
|
422
|
+
}).filter(Boolean);
|
|
380
423
|
return "<ol>" + items.join("") + "</ol>";
|
|
381
424
|
}
|
|
382
425
|
return match;
|
|
@@ -1918,6 +1961,14 @@ function generateStyles(options = {}) {
|
|
|
1918
1961
|
font-style: italic !important;
|
|
1919
1962
|
}
|
|
1920
1963
|
|
|
1964
|
+
/* Strikethrough text */
|
|
1965
|
+
.overtype-wrapper .overtype-preview del {
|
|
1966
|
+
color: var(--del, #ee964b) !important;
|
|
1967
|
+
text-decoration: line-through !important;
|
|
1968
|
+
text-decoration-color: var(--del, #ee964b) !important;
|
|
1969
|
+
text-decoration-thickness: 1px !important;
|
|
1970
|
+
}
|
|
1971
|
+
|
|
1921
1972
|
/* Inline code */
|
|
1922
1973
|
.overtype-wrapper .overtype-preview code {
|
|
1923
1974
|
background: var(--code-bg, rgba(244, 211, 94, 0.4)) !important;
|
|
@@ -2061,10 +2112,10 @@ function generateStyles(options = {}) {
|
|
|
2061
2112
|
height: 8px !important;
|
|
2062
2113
|
background: #4caf50 !important;
|
|
2063
2114
|
border-radius: 50% !important;
|
|
2064
|
-
animation: pulse 2s infinite !important;
|
|
2115
|
+
animation: overtype-pulse 2s infinite !important;
|
|
2065
2116
|
}
|
|
2066
2117
|
|
|
2067
|
-
@keyframes pulse {
|
|
2118
|
+
@keyframes overtype-pulse {
|
|
2068
2119
|
0%, 100% { opacity: 1; transform: scale(1); }
|
|
2069
2120
|
50% { opacity: 0.6; transform: scale(1.2); }
|
|
2070
2121
|
}
|
|
@@ -2072,19 +2123,19 @@ function generateStyles(options = {}) {
|
|
|
2072
2123
|
|
|
2073
2124
|
/* Toolbar Styles */
|
|
2074
2125
|
.overtype-toolbar {
|
|
2075
|
-
display: flex;
|
|
2076
|
-
align-items: center;
|
|
2077
|
-
gap: 4px;
|
|
2126
|
+
display: flex !important;
|
|
2127
|
+
align-items: center !important;
|
|
2128
|
+
gap: 4px !important;
|
|
2078
2129
|
padding: 8px !important; /* Override reset */
|
|
2079
2130
|
background: var(--toolbar-bg, var(--bg-primary, #f8f9fa)) !important; /* Override reset */
|
|
2080
2131
|
overflow-x: auto !important; /* Allow horizontal scrolling */
|
|
2081
2132
|
overflow-y: hidden !important; /* Hide vertical overflow */
|
|
2082
|
-
-webkit-overflow-scrolling: touch;
|
|
2083
|
-
flex-shrink: 0;
|
|
2133
|
+
-webkit-overflow-scrolling: touch !important;
|
|
2134
|
+
flex-shrink: 0 !important;
|
|
2084
2135
|
height: auto !important;
|
|
2085
2136
|
grid-row: 1 !important; /* Always first row in grid */
|
|
2086
2137
|
position: relative !important; /* Override reset */
|
|
2087
|
-
z-index: 100; /* Ensure toolbar is above wrapper */
|
|
2138
|
+
z-index: 100 !important; /* Ensure toolbar is above wrapper */
|
|
2088
2139
|
scrollbar-width: thin; /* Thin scrollbar on Firefox */
|
|
2089
2140
|
}
|
|
2090
2141
|
|
|
@@ -2466,20 +2517,67 @@ var eyeIcon = `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke
|
|
|
2466
2517
|
|
|
2467
2518
|
// src/toolbar.js
|
|
2468
2519
|
var Toolbar = class {
|
|
2469
|
-
constructor(editor) {
|
|
2520
|
+
constructor(editor, buttonConfig = null) {
|
|
2470
2521
|
this.editor = editor;
|
|
2471
2522
|
this.container = null;
|
|
2472
2523
|
this.buttons = {};
|
|
2524
|
+
this.buttonConfig = buttonConfig;
|
|
2525
|
+
}
|
|
2526
|
+
/**
|
|
2527
|
+
* Check if cursor/selection is inside a markdown link
|
|
2528
|
+
* @param {HTMLTextAreaElement} textarea - The textarea element
|
|
2529
|
+
* @returns {boolean} True if inside a link
|
|
2530
|
+
*/
|
|
2531
|
+
isInsideLink(textarea) {
|
|
2532
|
+
const value = textarea.value;
|
|
2533
|
+
const start = textarea.selectionStart;
|
|
2534
|
+
const end = textarea.selectionEnd;
|
|
2535
|
+
let insideLink = false;
|
|
2536
|
+
let openBracket = -1;
|
|
2537
|
+
let closeBracket = -1;
|
|
2538
|
+
for (let i = start - 1; i >= 0; i--) {
|
|
2539
|
+
if (value[i] === "[") {
|
|
2540
|
+
openBracket = i;
|
|
2541
|
+
break;
|
|
2542
|
+
}
|
|
2543
|
+
if (value[i] === "\n") {
|
|
2544
|
+
break;
|
|
2545
|
+
}
|
|
2546
|
+
}
|
|
2547
|
+
if (openBracket >= 0) {
|
|
2548
|
+
for (let i = end; i < value.length - 1; i++) {
|
|
2549
|
+
if (value[i] === "]" && value[i + 1] === "(") {
|
|
2550
|
+
closeBracket = i;
|
|
2551
|
+
break;
|
|
2552
|
+
}
|
|
2553
|
+
if (value[i] === "\n") {
|
|
2554
|
+
break;
|
|
2555
|
+
}
|
|
2556
|
+
}
|
|
2557
|
+
}
|
|
2558
|
+
if (openBracket >= 0 && closeBracket >= 0) {
|
|
2559
|
+
for (let i = closeBracket + 2; i < value.length; i++) {
|
|
2560
|
+
if (value[i] === ")") {
|
|
2561
|
+
insideLink = true;
|
|
2562
|
+
break;
|
|
2563
|
+
}
|
|
2564
|
+
if (value[i] === "\n" || value[i] === " ") {
|
|
2565
|
+
break;
|
|
2566
|
+
}
|
|
2567
|
+
}
|
|
2568
|
+
}
|
|
2569
|
+
return insideLink;
|
|
2473
2570
|
}
|
|
2474
2571
|
/**
|
|
2475
2572
|
* Create and attach toolbar to editor
|
|
2476
2573
|
*/
|
|
2477
2574
|
create() {
|
|
2575
|
+
var _a;
|
|
2478
2576
|
this.container = document.createElement("div");
|
|
2479
2577
|
this.container.className = "overtype-toolbar";
|
|
2480
2578
|
this.container.setAttribute("role", "toolbar");
|
|
2481
2579
|
this.container.setAttribute("aria-label", "Text formatting");
|
|
2482
|
-
const buttonConfig = [
|
|
2580
|
+
const buttonConfig = (_a = this.buttonConfig) != null ? _a : [
|
|
2483
2581
|
{ name: "bold", icon: boldIcon, title: "Bold (Ctrl+B)", action: "toggleBold" },
|
|
2484
2582
|
{ name: "italic", icon: italicIcon, title: "Italic (Ctrl+I)", action: "toggleItalic" },
|
|
2485
2583
|
{ separator: true },
|
|
@@ -2573,6 +2671,9 @@ var Toolbar = class {
|
|
|
2573
2671
|
insertLink(textarea);
|
|
2574
2672
|
break;
|
|
2575
2673
|
case "toggleCode":
|
|
2674
|
+
if (this.isInsideLink(textarea)) {
|
|
2675
|
+
return;
|
|
2676
|
+
}
|
|
2576
2677
|
toggleCode(textarea);
|
|
2577
2678
|
break;
|
|
2578
2679
|
case "toggleBulletList":
|
|
@@ -2788,29 +2889,29 @@ var LinkTooltip = class {
|
|
|
2788
2889
|
position: absolute;
|
|
2789
2890
|
position-anchor: var(--target-anchor, --link-0);
|
|
2790
2891
|
position-area: block-end center;
|
|
2791
|
-
margin-top: 8px;
|
|
2892
|
+
margin-top: 8px !important;
|
|
2792
2893
|
|
|
2793
|
-
background: #333;
|
|
2794
|
-
color: white;
|
|
2795
|
-
padding: 6px 10px;
|
|
2796
|
-
border-radius: 16px;
|
|
2797
|
-
font-size: 12px;
|
|
2798
|
-
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
2799
|
-
display: none;
|
|
2800
|
-
z-index: 10000;
|
|
2801
|
-
cursor: pointer;
|
|
2802
|
-
box-shadow: 0 2px 8px rgba(0,0,0,0.3);
|
|
2803
|
-
max-width: 300px;
|
|
2804
|
-
white-space: nowrap;
|
|
2805
|
-
overflow: hidden;
|
|
2806
|
-
text-overflow: ellipsis;
|
|
2894
|
+
background: #333 !important;
|
|
2895
|
+
color: white !important;
|
|
2896
|
+
padding: 6px 10px !important;
|
|
2897
|
+
border-radius: 16px !important;
|
|
2898
|
+
font-size: 12px !important;
|
|
2899
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif !important;
|
|
2900
|
+
display: none !important;
|
|
2901
|
+
z-index: 10000 !important;
|
|
2902
|
+
cursor: pointer !important;
|
|
2903
|
+
box-shadow: 0 2px 8px rgba(0,0,0,0.3) !important;
|
|
2904
|
+
max-width: 300px !important;
|
|
2905
|
+
white-space: nowrap !important;
|
|
2906
|
+
overflow: hidden !important;
|
|
2907
|
+
text-overflow: ellipsis !important;
|
|
2807
2908
|
|
|
2808
2909
|
position-try: most-width block-end inline-end, flip-inline, block-start center;
|
|
2809
2910
|
position-visibility: anchors-visible;
|
|
2810
2911
|
}
|
|
2811
2912
|
|
|
2812
2913
|
.overtype-link-tooltip.visible {
|
|
2813
|
-
display: flex;
|
|
2914
|
+
display: flex !important;
|
|
2814
2915
|
}
|
|
2815
2916
|
}
|
|
2816
2917
|
`;
|
|
@@ -2958,7 +3059,8 @@ var _OverType = class _OverType {
|
|
|
2958
3059
|
this.shortcuts = new ShortcutsManager(this);
|
|
2959
3060
|
this.linkTooltip = new LinkTooltip(this);
|
|
2960
3061
|
if (this.options.toolbar) {
|
|
2961
|
-
this.toolbar
|
|
3062
|
+
const toolbarButtons = typeof this.options.toolbar === "object" ? this.options.toolbar.buttons : null;
|
|
3063
|
+
this.toolbar = new Toolbar(this, toolbarButtons);
|
|
2962
3064
|
this.toolbar.create();
|
|
2963
3065
|
this.textarea.addEventListener("selectionchange", () => {
|
|
2964
3066
|
this.toolbar.updateButtonStates();
|
|
@@ -3440,24 +3542,36 @@ var _OverType = class _OverType {
|
|
|
3440
3542
|
}
|
|
3441
3543
|
/**
|
|
3442
3544
|
* Get the rendered HTML of the current content
|
|
3443
|
-
* @param {
|
|
3545
|
+
* @param {Object} options - Rendering options
|
|
3546
|
+
* @param {boolean} options.cleanHTML - If true, removes syntax markers and OverType-specific classes
|
|
3444
3547
|
* @returns {string} Rendered HTML
|
|
3445
3548
|
*/
|
|
3446
|
-
getRenderedHTML(
|
|
3549
|
+
getRenderedHTML(options = {}) {
|
|
3447
3550
|
const markdown = this.getValue();
|
|
3448
3551
|
let html = MarkdownParser.parse(markdown);
|
|
3449
|
-
if (
|
|
3450
|
-
html =
|
|
3552
|
+
if (options.cleanHTML) {
|
|
3553
|
+
html = html.replace(/<span class="syntax-marker[^"]*">.*?<\/span>/g, "");
|
|
3554
|
+
html = html.replace(/\sclass="(bullet-list|ordered-list|code-fence|hr-marker|blockquote|url-part)"/g, "");
|
|
3555
|
+
html = html.replace(/\sclass=""/g, "");
|
|
3451
3556
|
}
|
|
3452
3557
|
return html;
|
|
3453
3558
|
}
|
|
3454
3559
|
/**
|
|
3455
3560
|
* Get the current preview element's HTML
|
|
3561
|
+
* This includes all syntax markers and OverType styling
|
|
3456
3562
|
* @returns {string} Current preview HTML (as displayed)
|
|
3457
3563
|
*/
|
|
3458
3564
|
getPreviewHTML() {
|
|
3459
3565
|
return this.preview.innerHTML;
|
|
3460
3566
|
}
|
|
3567
|
+
/**
|
|
3568
|
+
* Get clean HTML without any OverType-specific markup
|
|
3569
|
+
* Useful for exporting to other formats or storage
|
|
3570
|
+
* @returns {string} Clean HTML suitable for export
|
|
3571
|
+
*/
|
|
3572
|
+
getCleanHTML() {
|
|
3573
|
+
return this.getRenderedHTML({ cleanHTML: true });
|
|
3574
|
+
}
|
|
3461
3575
|
/**
|
|
3462
3576
|
* Focus the editor
|
|
3463
3577
|
*/
|
|
@@ -3776,9 +3890,6 @@ OverType.ShortcutsManager = ShortcutsManager;
|
|
|
3776
3890
|
OverType.themes = { solar, cave: getTheme("cave") };
|
|
3777
3891
|
OverType.getTheme = getTheme;
|
|
3778
3892
|
OverType.currentTheme = solar;
|
|
3779
|
-
if (typeof window !== "undefined" && typeof window.document !== "undefined") {
|
|
3780
|
-
window.OverType = OverType;
|
|
3781
|
-
}
|
|
3782
3893
|
var overtype_default = OverType;
|
|
3783
3894
|
// Annotate the CommonJS export names for ESM import in node:
|
|
3784
3895
|
0 && (module.exports = {
|