overtype 1.2.2 → 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/dist/overtype.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * OverType v1.2.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>(?:&nbsp;)*<li class="bullet-list">.*?<\/li><\/div>\s*)+)/gs, (match) => {
371
- const items = match.match(/<li class="bullet-list">.*?<\/li>/gs) || [];
372
- if (items.length > 0) {
394
+ const divs = match.match(/<div>(?:&nbsp;)*<li class="bullet-list">.*?<\/li><\/div>/gs) || [];
395
+ if (divs.length > 0) {
396
+ const items = divs.map((div) => {
397
+ const indentMatch = div.match(/<div>((?:&nbsp;)*)<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>(?:&nbsp;)*<li class="ordered-list">.*?<\/li><\/div>\s*)+)/gs, (match) => {
378
- const items = match.match(/<li class="ordered-list">.*?<\/li>/gs) || [];
379
- if (items.length > 0) {
411
+ const divs = match.match(/<div>(?:&nbsp;)*<li class="ordered-list">.*?<\/li><\/div>/gs) || [];
412
+ if (divs.length > 0) {
413
+ const items = divs.map((div) => {
414
+ const indentMatch = div.match(/<div>((?:&nbsp;)*)<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;
@@ -397,9 +440,147 @@ var MarkdownParser = class {
397
440
  });
398
441
  return processed;
399
442
  }
443
+ /**
444
+ * Get list context at cursor position
445
+ * @param {string} text - Full text content
446
+ * @param {number} cursorPosition - Current cursor position
447
+ * @returns {Object} List context information
448
+ */
449
+ static getListContext(text, cursorPosition) {
450
+ const lines = text.split("\n");
451
+ let currentPos = 0;
452
+ let lineIndex = 0;
453
+ let lineStart = 0;
454
+ for (let i = 0; i < lines.length; i++) {
455
+ const lineLength = lines[i].length;
456
+ if (currentPos + lineLength >= cursorPosition) {
457
+ lineIndex = i;
458
+ lineStart = currentPos;
459
+ break;
460
+ }
461
+ currentPos += lineLength + 1;
462
+ }
463
+ const currentLine = lines[lineIndex];
464
+ const lineEnd = lineStart + currentLine.length;
465
+ const checkboxMatch = currentLine.match(this.LIST_PATTERNS.checkbox);
466
+ if (checkboxMatch) {
467
+ return {
468
+ inList: true,
469
+ listType: "checkbox",
470
+ indent: checkboxMatch[1],
471
+ marker: "-",
472
+ checked: checkboxMatch[2] === "x",
473
+ content: checkboxMatch[3],
474
+ lineStart,
475
+ lineEnd,
476
+ markerEndPos: lineStart + checkboxMatch[1].length + checkboxMatch[2].length + 5
477
+ // indent + "- [ ] "
478
+ };
479
+ }
480
+ const bulletMatch = currentLine.match(this.LIST_PATTERNS.bullet);
481
+ if (bulletMatch) {
482
+ return {
483
+ inList: true,
484
+ listType: "bullet",
485
+ indent: bulletMatch[1],
486
+ marker: bulletMatch[2],
487
+ content: bulletMatch[3],
488
+ lineStart,
489
+ lineEnd,
490
+ markerEndPos: lineStart + bulletMatch[1].length + bulletMatch[2].length + 1
491
+ // indent + marker + space
492
+ };
493
+ }
494
+ const numberedMatch = currentLine.match(this.LIST_PATTERNS.numbered);
495
+ if (numberedMatch) {
496
+ return {
497
+ inList: true,
498
+ listType: "numbered",
499
+ indent: numberedMatch[1],
500
+ marker: parseInt(numberedMatch[2]),
501
+ content: numberedMatch[3],
502
+ lineStart,
503
+ lineEnd,
504
+ markerEndPos: lineStart + numberedMatch[1].length + numberedMatch[2].length + 2
505
+ // indent + number + ". "
506
+ };
507
+ }
508
+ return {
509
+ inList: false,
510
+ listType: null,
511
+ indent: "",
512
+ marker: null,
513
+ content: currentLine,
514
+ lineStart,
515
+ lineEnd,
516
+ markerEndPos: lineStart
517
+ };
518
+ }
519
+ /**
520
+ * Create a new list item based on context
521
+ * @param {Object} context - List context from getListContext
522
+ * @returns {string} New list item text
523
+ */
524
+ static createNewListItem(context) {
525
+ switch (context.listType) {
526
+ case "bullet":
527
+ return `${context.indent}${context.marker} `;
528
+ case "numbered":
529
+ return `${context.indent}${context.marker + 1}. `;
530
+ case "checkbox":
531
+ return `${context.indent}- [ ] `;
532
+ default:
533
+ return "";
534
+ }
535
+ }
536
+ /**
537
+ * Renumber all numbered lists in text
538
+ * @param {string} text - Text containing numbered lists
539
+ * @returns {string} Text with renumbered lists
540
+ */
541
+ static renumberLists(text) {
542
+ const lines = text.split("\n");
543
+ const numbersByIndent = /* @__PURE__ */ new Map();
544
+ let inList = false;
545
+ const result = lines.map((line) => {
546
+ const match = line.match(this.LIST_PATTERNS.numbered);
547
+ if (match) {
548
+ const indent = match[1];
549
+ const indentLevel = indent.length;
550
+ const content = match[3];
551
+ if (!inList) {
552
+ numbersByIndent.clear();
553
+ }
554
+ const currentNumber = (numbersByIndent.get(indentLevel) || 0) + 1;
555
+ numbersByIndent.set(indentLevel, currentNumber);
556
+ for (const [level] of numbersByIndent) {
557
+ if (level > indentLevel) {
558
+ numbersByIndent.delete(level);
559
+ }
560
+ }
561
+ inList = true;
562
+ return `${indent}${currentNumber}. ${content}`;
563
+ } else {
564
+ if (line.trim() === "" || !line.match(/^\s/)) {
565
+ inList = false;
566
+ numbersByIndent.clear();
567
+ }
568
+ return line;
569
+ }
570
+ });
571
+ return result.join("\n");
572
+ }
400
573
  };
401
574
  // Track link index for anchor naming
402
575
  __publicField(MarkdownParser, "linkIndex", 0);
576
+ /**
577
+ * List pattern definitions
578
+ */
579
+ __publicField(MarkdownParser, "LIST_PATTERNS", {
580
+ bullet: /^(\s*)([-*+])\s+(.*)$/,
581
+ numbered: /^(\s*)(\d+)\.\s+(.*)$/,
582
+ checkbox: /^(\s*)-\s+\[([ x])\]\s+(.*)$/
583
+ });
403
584
 
404
585
  // node_modules/markdown-actions/dist/markdown-actions.esm.js
405
586
  var __defProp2 = Object.defineProperty;
@@ -1780,6 +1961,14 @@ function generateStyles(options = {}) {
1780
1961
  font-style: italic !important;
1781
1962
  }
1782
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
+
1783
1972
  /* Inline code */
1784
1973
  .overtype-wrapper .overtype-preview code {
1785
1974
  background: var(--code-bg, rgba(244, 211, 94, 0.4)) !important;
@@ -1923,10 +2112,10 @@ function generateStyles(options = {}) {
1923
2112
  height: 8px !important;
1924
2113
  background: #4caf50 !important;
1925
2114
  border-radius: 50% !important;
1926
- animation: pulse 2s infinite !important;
2115
+ animation: overtype-pulse 2s infinite !important;
1927
2116
  }
1928
2117
 
1929
- @keyframes pulse {
2118
+ @keyframes overtype-pulse {
1930
2119
  0%, 100% { opacity: 1; transform: scale(1); }
1931
2120
  50% { opacity: 0.6; transform: scale(1.2); }
1932
2121
  }
@@ -1934,19 +2123,19 @@ function generateStyles(options = {}) {
1934
2123
 
1935
2124
  /* Toolbar Styles */
1936
2125
  .overtype-toolbar {
1937
- display: flex;
1938
- align-items: center;
1939
- gap: 4px;
2126
+ display: flex !important;
2127
+ align-items: center !important;
2128
+ gap: 4px !important;
1940
2129
  padding: 8px !important; /* Override reset */
1941
2130
  background: var(--toolbar-bg, var(--bg-primary, #f8f9fa)) !important; /* Override reset */
1942
2131
  overflow-x: auto !important; /* Allow horizontal scrolling */
1943
2132
  overflow-y: hidden !important; /* Hide vertical overflow */
1944
- -webkit-overflow-scrolling: touch;
1945
- flex-shrink: 0;
2133
+ -webkit-overflow-scrolling: touch !important;
2134
+ flex-shrink: 0 !important;
1946
2135
  height: auto !important;
1947
2136
  grid-row: 1 !important; /* Always first row in grid */
1948
2137
  position: relative !important; /* Override reset */
1949
- z-index: 100; /* Ensure toolbar is above wrapper */
2138
+ z-index: 100 !important; /* Ensure toolbar is above wrapper */
1950
2139
  scrollbar-width: thin; /* Thin scrollbar on Firefox */
1951
2140
  }
1952
2141
 
@@ -2328,20 +2517,67 @@ var eyeIcon = `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke
2328
2517
 
2329
2518
  // src/toolbar.js
2330
2519
  var Toolbar = class {
2331
- constructor(editor) {
2520
+ constructor(editor, buttonConfig = null) {
2332
2521
  this.editor = editor;
2333
2522
  this.container = null;
2334
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;
2335
2570
  }
2336
2571
  /**
2337
2572
  * Create and attach toolbar to editor
2338
2573
  */
2339
2574
  create() {
2575
+ var _a;
2340
2576
  this.container = document.createElement("div");
2341
2577
  this.container.className = "overtype-toolbar";
2342
2578
  this.container.setAttribute("role", "toolbar");
2343
2579
  this.container.setAttribute("aria-label", "Text formatting");
2344
- const buttonConfig = [
2580
+ const buttonConfig = (_a = this.buttonConfig) != null ? _a : [
2345
2581
  { name: "bold", icon: boldIcon, title: "Bold (Ctrl+B)", action: "toggleBold" },
2346
2582
  { name: "italic", icon: italicIcon, title: "Italic (Ctrl+I)", action: "toggleItalic" },
2347
2583
  { separator: true },
@@ -2435,6 +2671,9 @@ var Toolbar = class {
2435
2671
  insertLink(textarea);
2436
2672
  break;
2437
2673
  case "toggleCode":
2674
+ if (this.isInsideLink(textarea)) {
2675
+ return;
2676
+ }
2438
2677
  toggleCode(textarea);
2439
2678
  break;
2440
2679
  case "toggleBulletList":
@@ -2650,29 +2889,29 @@ var LinkTooltip = class {
2650
2889
  position: absolute;
2651
2890
  position-anchor: var(--target-anchor, --link-0);
2652
2891
  position-area: block-end center;
2653
- margin-top: 8px;
2892
+ margin-top: 8px !important;
2654
2893
 
2655
- background: #333;
2656
- color: white;
2657
- padding: 6px 10px;
2658
- border-radius: 16px;
2659
- font-size: 12px;
2660
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
2661
- display: none;
2662
- z-index: 10000;
2663
- cursor: pointer;
2664
- box-shadow: 0 2px 8px rgba(0,0,0,0.3);
2665
- max-width: 300px;
2666
- white-space: nowrap;
2667
- overflow: hidden;
2668
- 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;
2669
2908
 
2670
2909
  position-try: most-width block-end inline-end, flip-inline, block-start center;
2671
2910
  position-visibility: anchors-visible;
2672
2911
  }
2673
2912
 
2674
2913
  .overtype-link-tooltip.visible {
2675
- display: flex;
2914
+ display: flex !important;
2676
2915
  }
2677
2916
  }
2678
2917
  `;
@@ -2820,7 +3059,8 @@ var _OverType = class _OverType {
2820
3059
  this.shortcuts = new ShortcutsManager(this);
2821
3060
  this.linkTooltip = new LinkTooltip(this);
2822
3061
  if (this.options.toolbar) {
2823
- this.toolbar = new Toolbar(this);
3062
+ const toolbarButtons = typeof this.options.toolbar === "object" ? this.options.toolbar.buttons : null;
3063
+ this.toolbar = new Toolbar(this, toolbarButtons);
2824
3064
  this.toolbar.create();
2825
3065
  this.textarea.addEventListener("selectionchange", () => {
2826
3066
  this.toolbar.updateButtonStates();
@@ -2872,7 +3112,9 @@ var _OverType = class _OverType {
2872
3112
  showActiveLineRaw: false,
2873
3113
  showStats: false,
2874
3114
  toolbar: false,
2875
- statsFormatter: null
3115
+ statsFormatter: null,
3116
+ smartLists: true
3117
+ // Enable smart list continuation
2876
3118
  };
2877
3119
  const { theme, colors, ...cleanOptions } = options;
2878
3120
  return {
@@ -3165,11 +3407,113 @@ var _OverType = class _OverType {
3165
3407
  this.textarea.dispatchEvent(new Event("input", { bubbles: true }));
3166
3408
  return;
3167
3409
  }
3410
+ if (event.key === "Enter" && !event.shiftKey && !event.metaKey && !event.ctrlKey && this.options.smartLists) {
3411
+ if (this.handleSmartListContinuation()) {
3412
+ event.preventDefault();
3413
+ return;
3414
+ }
3415
+ }
3168
3416
  const handled = this.shortcuts.handleKeydown(event);
3169
3417
  if (!handled && this.options.onKeydown) {
3170
3418
  this.options.onKeydown(event, this);
3171
3419
  }
3172
3420
  }
3421
+ /**
3422
+ * Handle smart list continuation
3423
+ * @returns {boolean} Whether the event was handled
3424
+ */
3425
+ handleSmartListContinuation() {
3426
+ const textarea = this.textarea;
3427
+ const cursorPos = textarea.selectionStart;
3428
+ const context = MarkdownParser.getListContext(textarea.value, cursorPos);
3429
+ if (!context || !context.inList)
3430
+ return false;
3431
+ if (context.content.trim() === "" && cursorPos >= context.markerEndPos) {
3432
+ this.deleteListMarker(context);
3433
+ return true;
3434
+ }
3435
+ if (cursorPos > context.markerEndPos && cursorPos < context.lineEnd) {
3436
+ this.splitListItem(context, cursorPos);
3437
+ } else {
3438
+ this.insertNewListItem(context);
3439
+ }
3440
+ if (context.listType === "numbered") {
3441
+ this.scheduleNumberedListUpdate();
3442
+ }
3443
+ return true;
3444
+ }
3445
+ /**
3446
+ * Delete list marker and exit list
3447
+ * @private
3448
+ */
3449
+ deleteListMarker(context) {
3450
+ this.textarea.setSelectionRange(context.lineStart, context.markerEndPos);
3451
+ document.execCommand("delete");
3452
+ this.textarea.dispatchEvent(new Event("input", { bubbles: true }));
3453
+ }
3454
+ /**
3455
+ * Insert new list item
3456
+ * @private
3457
+ */
3458
+ insertNewListItem(context) {
3459
+ const newItem = MarkdownParser.createNewListItem(context);
3460
+ document.execCommand("insertText", false, "\n" + newItem);
3461
+ this.textarea.dispatchEvent(new Event("input", { bubbles: true }));
3462
+ }
3463
+ /**
3464
+ * Split list item at cursor position
3465
+ * @private
3466
+ */
3467
+ splitListItem(context, cursorPos) {
3468
+ const textAfterCursor = context.content.substring(cursorPos - context.markerEndPos);
3469
+ this.textarea.setSelectionRange(cursorPos, context.lineEnd);
3470
+ document.execCommand("delete");
3471
+ const newItem = MarkdownParser.createNewListItem(context);
3472
+ document.execCommand("insertText", false, "\n" + newItem + textAfterCursor);
3473
+ const newCursorPos = this.textarea.selectionStart - textAfterCursor.length;
3474
+ this.textarea.setSelectionRange(newCursorPos, newCursorPos);
3475
+ this.textarea.dispatchEvent(new Event("input", { bubbles: true }));
3476
+ }
3477
+ /**
3478
+ * Schedule numbered list renumbering
3479
+ * @private
3480
+ */
3481
+ scheduleNumberedListUpdate() {
3482
+ if (this.numberUpdateTimeout) {
3483
+ clearTimeout(this.numberUpdateTimeout);
3484
+ }
3485
+ this.numberUpdateTimeout = setTimeout(() => {
3486
+ this.updateNumberedLists();
3487
+ }, 10);
3488
+ }
3489
+ /**
3490
+ * Update/renumber all numbered lists
3491
+ * @private
3492
+ */
3493
+ updateNumberedLists() {
3494
+ const value = this.textarea.value;
3495
+ const cursorPos = this.textarea.selectionStart;
3496
+ const newValue = MarkdownParser.renumberLists(value);
3497
+ if (newValue !== value) {
3498
+ let offset = 0;
3499
+ const oldLines = value.split("\n");
3500
+ const newLines = newValue.split("\n");
3501
+ let charCount = 0;
3502
+ for (let i = 0; i < oldLines.length && charCount < cursorPos; i++) {
3503
+ if (oldLines[i] !== newLines[i]) {
3504
+ const diff = newLines[i].length - oldLines[i].length;
3505
+ if (charCount + oldLines[i].length < cursorPos) {
3506
+ offset += diff;
3507
+ }
3508
+ }
3509
+ charCount += oldLines[i].length + 1;
3510
+ }
3511
+ this.textarea.value = newValue;
3512
+ const newCursorPos = cursorPos + offset;
3513
+ this.textarea.setSelectionRange(newCursorPos, newCursorPos);
3514
+ this.textarea.dispatchEvent(new Event("input", { bubbles: true }));
3515
+ }
3516
+ }
3173
3517
  /**
3174
3518
  * Handle scroll events
3175
3519
  * @private
@@ -3198,24 +3542,36 @@ var _OverType = class _OverType {
3198
3542
  }
3199
3543
  /**
3200
3544
  * Get the rendered HTML of the current content
3201
- * @param {boolean} processForPreview - If true, post-processes HTML for preview mode (consolidates lists/code blocks)
3545
+ * @param {Object} options - Rendering options
3546
+ * @param {boolean} options.cleanHTML - If true, removes syntax markers and OverType-specific classes
3202
3547
  * @returns {string} Rendered HTML
3203
3548
  */
3204
- getRenderedHTML(processForPreview = false) {
3549
+ getRenderedHTML(options = {}) {
3205
3550
  const markdown = this.getValue();
3206
3551
  let html = MarkdownParser.parse(markdown);
3207
- if (processForPreview) {
3208
- html = MarkdownParser.postProcessHTML(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, "");
3209
3556
  }
3210
3557
  return html;
3211
3558
  }
3212
3559
  /**
3213
3560
  * Get the current preview element's HTML
3561
+ * This includes all syntax markers and OverType styling
3214
3562
  * @returns {string} Current preview HTML (as displayed)
3215
3563
  */
3216
3564
  getPreviewHTML() {
3217
3565
  return this.preview.innerHTML;
3218
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
+ }
3219
3575
  /**
3220
3576
  * Focus the editor
3221
3577
  */
@@ -3534,9 +3890,6 @@ OverType.ShortcutsManager = ShortcutsManager;
3534
3890
  OverType.themes = { solar, cave: getTheme("cave") };
3535
3891
  OverType.getTheme = getTheme;
3536
3892
  OverType.currentTheme = solar;
3537
- if (typeof window !== "undefined" && typeof window.document !== "undefined") {
3538
- window.OverType = OverType;
3539
- }
3540
3893
  var overtype_default = OverType;
3541
3894
  // Annotate the CommonJS export names for ESM import in node:
3542
3895
  0 && (module.exports = {