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.
@@ -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
@@ -131,6 +131,17 @@ var MarkdownParser = class {
131
131
  html = html.replace(new RegExp("(?<!_)_(?!_)(.+?)(?<!_)_(?!_)", "g"), '<em><span class="syntax-marker">_</span>$1<span class="syntax-marker">_</span></em>');
132
132
  return html;
133
133
  }
134
+ /**
135
+ * Parse strikethrough text
136
+ * Supports both single (~) and double (~~) tildes, but rejects 3+ tildes
137
+ * @param {string} html - HTML with potential strikethrough markdown
138
+ * @returns {string} HTML with strikethrough styling
139
+ */
140
+ static parseStrikethrough(html) {
141
+ html = html.replace(new RegExp("(?<!~)~~(?!~)(.+?)(?<!~)~~(?!~)", "g"), '<del><span class="syntax-marker">~~</span>$1<span class="syntax-marker">~~</span></del>');
142
+ html = html.replace(new RegExp("(?<!~)~(?!~)(.+?)(?<!~)~(?!~)", "g"), '<del><span class="syntax-marker">~</span>$1<span class="syntax-marker">~</span></del>');
143
+ return html;
144
+ }
134
145
  /**
135
146
  * Parse inline code
136
147
  * @param {string} html - HTML with potential code markdown
@@ -193,6 +204,7 @@ var MarkdownParser = class {
193
204
  sanctuaries.set(placeholder, match);
194
205
  return placeholder;
195
206
  });
207
+ html = this.parseStrikethrough(html);
196
208
  html = this.parseBold(html);
197
209
  html = this.parseItalic(html);
198
210
  sanctuaries.forEach((content, placeholder) => {
@@ -327,6 +339,17 @@ var MarkdownParser = class {
327
339
  container.insertBefore(currentList, child);
328
340
  listType = newType;
329
341
  }
342
+ const indentationNodes = [];
343
+ for (const node of child.childNodes) {
344
+ if (node.nodeType === 3 && node.textContent.match(/^\u00A0+$/)) {
345
+ indentationNodes.push(node.cloneNode(true));
346
+ } else if (node === listItem) {
347
+ break;
348
+ }
349
+ }
350
+ indentationNodes.forEach((node) => {
351
+ listItem.insertBefore(node, listItem.firstChild);
352
+ });
330
353
  currentList.appendChild(listItem);
331
354
  child.remove();
332
355
  } else {
@@ -344,15 +367,35 @@ var MarkdownParser = class {
344
367
  static postProcessHTMLManual(html) {
345
368
  let processed = html;
346
369
  processed = processed.replace(/((?:<div>(?:&nbsp;)*<li class="bullet-list">.*?<\/li><\/div>\s*)+)/gs, (match) => {
347
- const items = match.match(/<li class="bullet-list">.*?<\/li>/gs) || [];
348
- if (items.length > 0) {
370
+ const divs = match.match(/<div>(?:&nbsp;)*<li class="bullet-list">.*?<\/li><\/div>/gs) || [];
371
+ if (divs.length > 0) {
372
+ const items = divs.map((div) => {
373
+ const indentMatch = div.match(/<div>((?:&nbsp;)*)<li/);
374
+ const listItemMatch = div.match(/<li class="bullet-list">.*?<\/li>/);
375
+ if (indentMatch && listItemMatch) {
376
+ const indentation = indentMatch[1];
377
+ const listItem = listItemMatch[0];
378
+ return listItem.replace(/<li class="bullet-list">/, `<li class="bullet-list">${indentation}`);
379
+ }
380
+ return listItemMatch ? listItemMatch[0] : "";
381
+ }).filter(Boolean);
349
382
  return "<ul>" + items.join("") + "</ul>";
350
383
  }
351
384
  return match;
352
385
  });
353
386
  processed = processed.replace(/((?:<div>(?:&nbsp;)*<li class="ordered-list">.*?<\/li><\/div>\s*)+)/gs, (match) => {
354
- const items = match.match(/<li class="ordered-list">.*?<\/li>/gs) || [];
355
- if (items.length > 0) {
387
+ const divs = match.match(/<div>(?:&nbsp;)*<li class="ordered-list">.*?<\/li><\/div>/gs) || [];
388
+ if (divs.length > 0) {
389
+ const items = divs.map((div) => {
390
+ const indentMatch = div.match(/<div>((?:&nbsp;)*)<li/);
391
+ const listItemMatch = div.match(/<li class="ordered-list">.*?<\/li>/);
392
+ if (indentMatch && listItemMatch) {
393
+ const indentation = indentMatch[1];
394
+ const listItem = listItemMatch[0];
395
+ return listItem.replace(/<li class="ordered-list">/, `<li class="ordered-list">${indentation}`);
396
+ }
397
+ return listItemMatch ? listItemMatch[0] : "";
398
+ }).filter(Boolean);
356
399
  return "<ol>" + items.join("") + "</ol>";
357
400
  }
358
401
  return match;
@@ -373,9 +416,147 @@ var MarkdownParser = class {
373
416
  });
374
417
  return processed;
375
418
  }
419
+ /**
420
+ * Get list context at cursor position
421
+ * @param {string} text - Full text content
422
+ * @param {number} cursorPosition - Current cursor position
423
+ * @returns {Object} List context information
424
+ */
425
+ static getListContext(text, cursorPosition) {
426
+ const lines = text.split("\n");
427
+ let currentPos = 0;
428
+ let lineIndex = 0;
429
+ let lineStart = 0;
430
+ for (let i = 0; i < lines.length; i++) {
431
+ const lineLength = lines[i].length;
432
+ if (currentPos + lineLength >= cursorPosition) {
433
+ lineIndex = i;
434
+ lineStart = currentPos;
435
+ break;
436
+ }
437
+ currentPos += lineLength + 1;
438
+ }
439
+ const currentLine = lines[lineIndex];
440
+ const lineEnd = lineStart + currentLine.length;
441
+ const checkboxMatch = currentLine.match(this.LIST_PATTERNS.checkbox);
442
+ if (checkboxMatch) {
443
+ return {
444
+ inList: true,
445
+ listType: "checkbox",
446
+ indent: checkboxMatch[1],
447
+ marker: "-",
448
+ checked: checkboxMatch[2] === "x",
449
+ content: checkboxMatch[3],
450
+ lineStart,
451
+ lineEnd,
452
+ markerEndPos: lineStart + checkboxMatch[1].length + checkboxMatch[2].length + 5
453
+ // indent + "- [ ] "
454
+ };
455
+ }
456
+ const bulletMatch = currentLine.match(this.LIST_PATTERNS.bullet);
457
+ if (bulletMatch) {
458
+ return {
459
+ inList: true,
460
+ listType: "bullet",
461
+ indent: bulletMatch[1],
462
+ marker: bulletMatch[2],
463
+ content: bulletMatch[3],
464
+ lineStart,
465
+ lineEnd,
466
+ markerEndPos: lineStart + bulletMatch[1].length + bulletMatch[2].length + 1
467
+ // indent + marker + space
468
+ };
469
+ }
470
+ const numberedMatch = currentLine.match(this.LIST_PATTERNS.numbered);
471
+ if (numberedMatch) {
472
+ return {
473
+ inList: true,
474
+ listType: "numbered",
475
+ indent: numberedMatch[1],
476
+ marker: parseInt(numberedMatch[2]),
477
+ content: numberedMatch[3],
478
+ lineStart,
479
+ lineEnd,
480
+ markerEndPos: lineStart + numberedMatch[1].length + numberedMatch[2].length + 2
481
+ // indent + number + ". "
482
+ };
483
+ }
484
+ return {
485
+ inList: false,
486
+ listType: null,
487
+ indent: "",
488
+ marker: null,
489
+ content: currentLine,
490
+ lineStart,
491
+ lineEnd,
492
+ markerEndPos: lineStart
493
+ };
494
+ }
495
+ /**
496
+ * Create a new list item based on context
497
+ * @param {Object} context - List context from getListContext
498
+ * @returns {string} New list item text
499
+ */
500
+ static createNewListItem(context) {
501
+ switch (context.listType) {
502
+ case "bullet":
503
+ return `${context.indent}${context.marker} `;
504
+ case "numbered":
505
+ return `${context.indent}${context.marker + 1}. `;
506
+ case "checkbox":
507
+ return `${context.indent}- [ ] `;
508
+ default:
509
+ return "";
510
+ }
511
+ }
512
+ /**
513
+ * Renumber all numbered lists in text
514
+ * @param {string} text - Text containing numbered lists
515
+ * @returns {string} Text with renumbered lists
516
+ */
517
+ static renumberLists(text) {
518
+ const lines = text.split("\n");
519
+ const numbersByIndent = /* @__PURE__ */ new Map();
520
+ let inList = false;
521
+ const result = lines.map((line) => {
522
+ const match = line.match(this.LIST_PATTERNS.numbered);
523
+ if (match) {
524
+ const indent = match[1];
525
+ const indentLevel = indent.length;
526
+ const content = match[3];
527
+ if (!inList) {
528
+ numbersByIndent.clear();
529
+ }
530
+ const currentNumber = (numbersByIndent.get(indentLevel) || 0) + 1;
531
+ numbersByIndent.set(indentLevel, currentNumber);
532
+ for (const [level] of numbersByIndent) {
533
+ if (level > indentLevel) {
534
+ numbersByIndent.delete(level);
535
+ }
536
+ }
537
+ inList = true;
538
+ return `${indent}${currentNumber}. ${content}`;
539
+ } else {
540
+ if (line.trim() === "" || !line.match(/^\s/)) {
541
+ inList = false;
542
+ numbersByIndent.clear();
543
+ }
544
+ return line;
545
+ }
546
+ });
547
+ return result.join("\n");
548
+ }
376
549
  };
377
550
  // Track link index for anchor naming
378
551
  __publicField(MarkdownParser, "linkIndex", 0);
552
+ /**
553
+ * List pattern definitions
554
+ */
555
+ __publicField(MarkdownParser, "LIST_PATTERNS", {
556
+ bullet: /^(\s*)([-*+])\s+(.*)$/,
557
+ numbered: /^(\s*)(\d+)\.\s+(.*)$/,
558
+ checkbox: /^(\s*)-\s+\[([ x])\]\s+(.*)$/
559
+ });
379
560
 
380
561
  // node_modules/markdown-actions/dist/markdown-actions.esm.js
381
562
  var __defProp2 = Object.defineProperty;
@@ -1756,6 +1937,14 @@ function generateStyles(options = {}) {
1756
1937
  font-style: italic !important;
1757
1938
  }
1758
1939
 
1940
+ /* Strikethrough text */
1941
+ .overtype-wrapper .overtype-preview del {
1942
+ color: var(--del, #ee964b) !important;
1943
+ text-decoration: line-through !important;
1944
+ text-decoration-color: var(--del, #ee964b) !important;
1945
+ text-decoration-thickness: 1px !important;
1946
+ }
1947
+
1759
1948
  /* Inline code */
1760
1949
  .overtype-wrapper .overtype-preview code {
1761
1950
  background: var(--code-bg, rgba(244, 211, 94, 0.4)) !important;
@@ -1899,10 +2088,10 @@ function generateStyles(options = {}) {
1899
2088
  height: 8px !important;
1900
2089
  background: #4caf50 !important;
1901
2090
  border-radius: 50% !important;
1902
- animation: pulse 2s infinite !important;
2091
+ animation: overtype-pulse 2s infinite !important;
1903
2092
  }
1904
2093
 
1905
- @keyframes pulse {
2094
+ @keyframes overtype-pulse {
1906
2095
  0%, 100% { opacity: 1; transform: scale(1); }
1907
2096
  50% { opacity: 0.6; transform: scale(1.2); }
1908
2097
  }
@@ -1910,19 +2099,19 @@ function generateStyles(options = {}) {
1910
2099
 
1911
2100
  /* Toolbar Styles */
1912
2101
  .overtype-toolbar {
1913
- display: flex;
1914
- align-items: center;
1915
- gap: 4px;
2102
+ display: flex !important;
2103
+ align-items: center !important;
2104
+ gap: 4px !important;
1916
2105
  padding: 8px !important; /* Override reset */
1917
2106
  background: var(--toolbar-bg, var(--bg-primary, #f8f9fa)) !important; /* Override reset */
1918
2107
  overflow-x: auto !important; /* Allow horizontal scrolling */
1919
2108
  overflow-y: hidden !important; /* Hide vertical overflow */
1920
- -webkit-overflow-scrolling: touch;
1921
- flex-shrink: 0;
2109
+ -webkit-overflow-scrolling: touch !important;
2110
+ flex-shrink: 0 !important;
1922
2111
  height: auto !important;
1923
2112
  grid-row: 1 !important; /* Always first row in grid */
1924
2113
  position: relative !important; /* Override reset */
1925
- z-index: 100; /* Ensure toolbar is above wrapper */
2114
+ z-index: 100 !important; /* Ensure toolbar is above wrapper */
1926
2115
  scrollbar-width: thin; /* Thin scrollbar on Firefox */
1927
2116
  }
1928
2117
 
@@ -2304,20 +2493,67 @@ var eyeIcon = `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke
2304
2493
 
2305
2494
  // src/toolbar.js
2306
2495
  var Toolbar = class {
2307
- constructor(editor) {
2496
+ constructor(editor, buttonConfig = null) {
2308
2497
  this.editor = editor;
2309
2498
  this.container = null;
2310
2499
  this.buttons = {};
2500
+ this.buttonConfig = buttonConfig;
2501
+ }
2502
+ /**
2503
+ * Check if cursor/selection is inside a markdown link
2504
+ * @param {HTMLTextAreaElement} textarea - The textarea element
2505
+ * @returns {boolean} True if inside a link
2506
+ */
2507
+ isInsideLink(textarea) {
2508
+ const value = textarea.value;
2509
+ const start = textarea.selectionStart;
2510
+ const end = textarea.selectionEnd;
2511
+ let insideLink = false;
2512
+ let openBracket = -1;
2513
+ let closeBracket = -1;
2514
+ for (let i = start - 1; i >= 0; i--) {
2515
+ if (value[i] === "[") {
2516
+ openBracket = i;
2517
+ break;
2518
+ }
2519
+ if (value[i] === "\n") {
2520
+ break;
2521
+ }
2522
+ }
2523
+ if (openBracket >= 0) {
2524
+ for (let i = end; i < value.length - 1; i++) {
2525
+ if (value[i] === "]" && value[i + 1] === "(") {
2526
+ closeBracket = i;
2527
+ break;
2528
+ }
2529
+ if (value[i] === "\n") {
2530
+ break;
2531
+ }
2532
+ }
2533
+ }
2534
+ if (openBracket >= 0 && closeBracket >= 0) {
2535
+ for (let i = closeBracket + 2; i < value.length; i++) {
2536
+ if (value[i] === ")") {
2537
+ insideLink = true;
2538
+ break;
2539
+ }
2540
+ if (value[i] === "\n" || value[i] === " ") {
2541
+ break;
2542
+ }
2543
+ }
2544
+ }
2545
+ return insideLink;
2311
2546
  }
2312
2547
  /**
2313
2548
  * Create and attach toolbar to editor
2314
2549
  */
2315
2550
  create() {
2551
+ var _a;
2316
2552
  this.container = document.createElement("div");
2317
2553
  this.container.className = "overtype-toolbar";
2318
2554
  this.container.setAttribute("role", "toolbar");
2319
2555
  this.container.setAttribute("aria-label", "Text formatting");
2320
- const buttonConfig = [
2556
+ const buttonConfig = (_a = this.buttonConfig) != null ? _a : [
2321
2557
  { name: "bold", icon: boldIcon, title: "Bold (Ctrl+B)", action: "toggleBold" },
2322
2558
  { name: "italic", icon: italicIcon, title: "Italic (Ctrl+I)", action: "toggleItalic" },
2323
2559
  { separator: true },
@@ -2411,6 +2647,9 @@ var Toolbar = class {
2411
2647
  insertLink(textarea);
2412
2648
  break;
2413
2649
  case "toggleCode":
2650
+ if (this.isInsideLink(textarea)) {
2651
+ return;
2652
+ }
2414
2653
  toggleCode(textarea);
2415
2654
  break;
2416
2655
  case "toggleBulletList":
@@ -2626,29 +2865,29 @@ var LinkTooltip = class {
2626
2865
  position: absolute;
2627
2866
  position-anchor: var(--target-anchor, --link-0);
2628
2867
  position-area: block-end center;
2629
- margin-top: 8px;
2868
+ margin-top: 8px !important;
2630
2869
 
2631
- background: #333;
2632
- color: white;
2633
- padding: 6px 10px;
2634
- border-radius: 16px;
2635
- font-size: 12px;
2636
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
2637
- display: none;
2638
- z-index: 10000;
2639
- cursor: pointer;
2640
- box-shadow: 0 2px 8px rgba(0,0,0,0.3);
2641
- max-width: 300px;
2642
- white-space: nowrap;
2643
- overflow: hidden;
2644
- text-overflow: ellipsis;
2870
+ background: #333 !important;
2871
+ color: white !important;
2872
+ padding: 6px 10px !important;
2873
+ border-radius: 16px !important;
2874
+ font-size: 12px !important;
2875
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif !important;
2876
+ display: none !important;
2877
+ z-index: 10000 !important;
2878
+ cursor: pointer !important;
2879
+ box-shadow: 0 2px 8px rgba(0,0,0,0.3) !important;
2880
+ max-width: 300px !important;
2881
+ white-space: nowrap !important;
2882
+ overflow: hidden !important;
2883
+ text-overflow: ellipsis !important;
2645
2884
 
2646
2885
  position-try: most-width block-end inline-end, flip-inline, block-start center;
2647
2886
  position-visibility: anchors-visible;
2648
2887
  }
2649
2888
 
2650
2889
  .overtype-link-tooltip.visible {
2651
- display: flex;
2890
+ display: flex !important;
2652
2891
  }
2653
2892
  }
2654
2893
  `;
@@ -2796,7 +3035,8 @@ var _OverType = class _OverType {
2796
3035
  this.shortcuts = new ShortcutsManager(this);
2797
3036
  this.linkTooltip = new LinkTooltip(this);
2798
3037
  if (this.options.toolbar) {
2799
- this.toolbar = new Toolbar(this);
3038
+ const toolbarButtons = typeof this.options.toolbar === "object" ? this.options.toolbar.buttons : null;
3039
+ this.toolbar = new Toolbar(this, toolbarButtons);
2800
3040
  this.toolbar.create();
2801
3041
  this.textarea.addEventListener("selectionchange", () => {
2802
3042
  this.toolbar.updateButtonStates();
@@ -2848,7 +3088,9 @@ var _OverType = class _OverType {
2848
3088
  showActiveLineRaw: false,
2849
3089
  showStats: false,
2850
3090
  toolbar: false,
2851
- statsFormatter: null
3091
+ statsFormatter: null,
3092
+ smartLists: true
3093
+ // Enable smart list continuation
2852
3094
  };
2853
3095
  const { theme, colors, ...cleanOptions } = options;
2854
3096
  return {
@@ -3141,11 +3383,113 @@ var _OverType = class _OverType {
3141
3383
  this.textarea.dispatchEvent(new Event("input", { bubbles: true }));
3142
3384
  return;
3143
3385
  }
3386
+ if (event.key === "Enter" && !event.shiftKey && !event.metaKey && !event.ctrlKey && this.options.smartLists) {
3387
+ if (this.handleSmartListContinuation()) {
3388
+ event.preventDefault();
3389
+ return;
3390
+ }
3391
+ }
3144
3392
  const handled = this.shortcuts.handleKeydown(event);
3145
3393
  if (!handled && this.options.onKeydown) {
3146
3394
  this.options.onKeydown(event, this);
3147
3395
  }
3148
3396
  }
3397
+ /**
3398
+ * Handle smart list continuation
3399
+ * @returns {boolean} Whether the event was handled
3400
+ */
3401
+ handleSmartListContinuation() {
3402
+ const textarea = this.textarea;
3403
+ const cursorPos = textarea.selectionStart;
3404
+ const context = MarkdownParser.getListContext(textarea.value, cursorPos);
3405
+ if (!context || !context.inList)
3406
+ return false;
3407
+ if (context.content.trim() === "" && cursorPos >= context.markerEndPos) {
3408
+ this.deleteListMarker(context);
3409
+ return true;
3410
+ }
3411
+ if (cursorPos > context.markerEndPos && cursorPos < context.lineEnd) {
3412
+ this.splitListItem(context, cursorPos);
3413
+ } else {
3414
+ this.insertNewListItem(context);
3415
+ }
3416
+ if (context.listType === "numbered") {
3417
+ this.scheduleNumberedListUpdate();
3418
+ }
3419
+ return true;
3420
+ }
3421
+ /**
3422
+ * Delete list marker and exit list
3423
+ * @private
3424
+ */
3425
+ deleteListMarker(context) {
3426
+ this.textarea.setSelectionRange(context.lineStart, context.markerEndPos);
3427
+ document.execCommand("delete");
3428
+ this.textarea.dispatchEvent(new Event("input", { bubbles: true }));
3429
+ }
3430
+ /**
3431
+ * Insert new list item
3432
+ * @private
3433
+ */
3434
+ insertNewListItem(context) {
3435
+ const newItem = MarkdownParser.createNewListItem(context);
3436
+ document.execCommand("insertText", false, "\n" + newItem);
3437
+ this.textarea.dispatchEvent(new Event("input", { bubbles: true }));
3438
+ }
3439
+ /**
3440
+ * Split list item at cursor position
3441
+ * @private
3442
+ */
3443
+ splitListItem(context, cursorPos) {
3444
+ const textAfterCursor = context.content.substring(cursorPos - context.markerEndPos);
3445
+ this.textarea.setSelectionRange(cursorPos, context.lineEnd);
3446
+ document.execCommand("delete");
3447
+ const newItem = MarkdownParser.createNewListItem(context);
3448
+ document.execCommand("insertText", false, "\n" + newItem + textAfterCursor);
3449
+ const newCursorPos = this.textarea.selectionStart - textAfterCursor.length;
3450
+ this.textarea.setSelectionRange(newCursorPos, newCursorPos);
3451
+ this.textarea.dispatchEvent(new Event("input", { bubbles: true }));
3452
+ }
3453
+ /**
3454
+ * Schedule numbered list renumbering
3455
+ * @private
3456
+ */
3457
+ scheduleNumberedListUpdate() {
3458
+ if (this.numberUpdateTimeout) {
3459
+ clearTimeout(this.numberUpdateTimeout);
3460
+ }
3461
+ this.numberUpdateTimeout = setTimeout(() => {
3462
+ this.updateNumberedLists();
3463
+ }, 10);
3464
+ }
3465
+ /**
3466
+ * Update/renumber all numbered lists
3467
+ * @private
3468
+ */
3469
+ updateNumberedLists() {
3470
+ const value = this.textarea.value;
3471
+ const cursorPos = this.textarea.selectionStart;
3472
+ const newValue = MarkdownParser.renumberLists(value);
3473
+ if (newValue !== value) {
3474
+ let offset = 0;
3475
+ const oldLines = value.split("\n");
3476
+ const newLines = newValue.split("\n");
3477
+ let charCount = 0;
3478
+ for (let i = 0; i < oldLines.length && charCount < cursorPos; i++) {
3479
+ if (oldLines[i] !== newLines[i]) {
3480
+ const diff = newLines[i].length - oldLines[i].length;
3481
+ if (charCount + oldLines[i].length < cursorPos) {
3482
+ offset += diff;
3483
+ }
3484
+ }
3485
+ charCount += oldLines[i].length + 1;
3486
+ }
3487
+ this.textarea.value = newValue;
3488
+ const newCursorPos = cursorPos + offset;
3489
+ this.textarea.setSelectionRange(newCursorPos, newCursorPos);
3490
+ this.textarea.dispatchEvent(new Event("input", { bubbles: true }));
3491
+ }
3492
+ }
3149
3493
  /**
3150
3494
  * Handle scroll events
3151
3495
  * @private
@@ -3174,24 +3518,36 @@ var _OverType = class _OverType {
3174
3518
  }
3175
3519
  /**
3176
3520
  * Get the rendered HTML of the current content
3177
- * @param {boolean} processForPreview - If true, post-processes HTML for preview mode (consolidates lists/code blocks)
3521
+ * @param {Object} options - Rendering options
3522
+ * @param {boolean} options.cleanHTML - If true, removes syntax markers and OverType-specific classes
3178
3523
  * @returns {string} Rendered HTML
3179
3524
  */
3180
- getRenderedHTML(processForPreview = false) {
3525
+ getRenderedHTML(options = {}) {
3181
3526
  const markdown = this.getValue();
3182
3527
  let html = MarkdownParser.parse(markdown);
3183
- if (processForPreview) {
3184
- html = MarkdownParser.postProcessHTML(html);
3528
+ if (options.cleanHTML) {
3529
+ html = html.replace(/<span class="syntax-marker[^"]*">.*?<\/span>/g, "");
3530
+ html = html.replace(/\sclass="(bullet-list|ordered-list|code-fence|hr-marker|blockquote|url-part)"/g, "");
3531
+ html = html.replace(/\sclass=""/g, "");
3185
3532
  }
3186
3533
  return html;
3187
3534
  }
3188
3535
  /**
3189
3536
  * Get the current preview element's HTML
3537
+ * This includes all syntax markers and OverType styling
3190
3538
  * @returns {string} Current preview HTML (as displayed)
3191
3539
  */
3192
3540
  getPreviewHTML() {
3193
3541
  return this.preview.innerHTML;
3194
3542
  }
3543
+ /**
3544
+ * Get clean HTML without any OverType-specific markup
3545
+ * Useful for exporting to other formats or storage
3546
+ * @returns {string} Clean HTML suitable for export
3547
+ */
3548
+ getCleanHTML() {
3549
+ return this.getRenderedHTML({ cleanHTML: true });
3550
+ }
3195
3551
  /**
3196
3552
  * Focus the editor
3197
3553
  */
@@ -3510,9 +3866,6 @@ OverType.ShortcutsManager = ShortcutsManager;
3510
3866
  OverType.themes = { solar, cave: getTheme("cave") };
3511
3867
  OverType.getTheme = getTheme;
3512
3868
  OverType.currentTheme = solar;
3513
- if (typeof window !== "undefined" && typeof window.document !== "undefined") {
3514
- window.OverType = OverType;
3515
- }
3516
3869
  var overtype_default = OverType;
3517
3870
  export {
3518
3871
  OverType,