overtype 1.2.0 → 1.2.1
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 +821 -956
- package/dist/overtype.cjs.map +4 -4
- package/dist/overtype.esm.js +23 -9
- package/dist/overtype.esm.js.map +2 -2
- package/dist/overtype.js +23 -9
- package/dist/overtype.js.map +2 -2
- package/dist/overtype.min.js +23 -23
- package/package.json +1 -1
- package/src/overtype.js +30 -9
package/dist/overtype.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* OverType v1.2.
|
|
2
|
+
* OverType v1.2.1
|
|
3
3
|
* A lightweight markdown editor library with perfect WYSIWYG alignment
|
|
4
4
|
* @license MIT
|
|
5
5
|
* @author Demo User
|
|
@@ -387,997 +387,848 @@ var MarkdownParser = class {
|
|
|
387
387
|
// Track link index for anchor naming
|
|
388
388
|
__publicField(MarkdownParser, "linkIndex", 0);
|
|
389
389
|
|
|
390
|
-
// node_modules/markdown-actions/dist/markdown-actions.js
|
|
391
|
-
var
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
var
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
390
|
+
// node_modules/markdown-actions/dist/markdown-actions.esm.js
|
|
391
|
+
var __defProp2 = Object.defineProperty;
|
|
392
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
393
|
+
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
394
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
395
|
+
var __defNormalProp2 = (obj, key, value) => key in obj ? __defProp2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
396
|
+
var __spreadValues = (a, b) => {
|
|
397
|
+
for (var prop in b || (b = {}))
|
|
398
|
+
if (__hasOwnProp2.call(b, prop))
|
|
399
|
+
__defNormalProp2(a, prop, b[prop]);
|
|
400
|
+
if (__getOwnPropSymbols)
|
|
401
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
402
|
+
if (__propIsEnum.call(b, prop))
|
|
402
403
|
__defNormalProp2(a, prop, b[prop]);
|
|
403
|
-
if (__getOwnPropSymbols)
|
|
404
|
-
for (var prop of __getOwnPropSymbols(b)) {
|
|
405
|
-
if (__propIsEnum.call(b, prop))
|
|
406
|
-
__defNormalProp2(a, prop, b[prop]);
|
|
407
|
-
}
|
|
408
|
-
return a;
|
|
409
|
-
};
|
|
410
|
-
var __export2 = (target, all) => {
|
|
411
|
-
for (var name in all)
|
|
412
|
-
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
413
|
-
};
|
|
414
|
-
var __copyProps2 = (to, from, except, desc) => {
|
|
415
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
416
|
-
for (let key of __getOwnPropNames2(from))
|
|
417
|
-
if (!__hasOwnProp2.call(to, key) && key !== except)
|
|
418
|
-
__defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
|
|
419
404
|
}
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
prefix: "- [ ] ",
|
|
487
|
-
multiline: true,
|
|
488
|
-
surroundWithNewlines: true
|
|
489
|
-
},
|
|
490
|
-
header1: { prefix: "# " },
|
|
491
|
-
header2: { prefix: "## " },
|
|
492
|
-
header3: { prefix: "### " },
|
|
493
|
-
header4: { prefix: "#### " },
|
|
494
|
-
header5: { prefix: "##### " },
|
|
495
|
-
header6: { prefix: "###### " }
|
|
405
|
+
return a;
|
|
406
|
+
};
|
|
407
|
+
var FORMATS = {
|
|
408
|
+
bold: {
|
|
409
|
+
prefix: "**",
|
|
410
|
+
suffix: "**",
|
|
411
|
+
trimFirst: true
|
|
412
|
+
},
|
|
413
|
+
italic: {
|
|
414
|
+
prefix: "_",
|
|
415
|
+
suffix: "_",
|
|
416
|
+
trimFirst: true
|
|
417
|
+
},
|
|
418
|
+
code: {
|
|
419
|
+
prefix: "`",
|
|
420
|
+
suffix: "`",
|
|
421
|
+
blockPrefix: "```",
|
|
422
|
+
blockSuffix: "```"
|
|
423
|
+
},
|
|
424
|
+
link: {
|
|
425
|
+
prefix: "[",
|
|
426
|
+
suffix: "](url)",
|
|
427
|
+
replaceNext: "url",
|
|
428
|
+
scanFor: "https?://"
|
|
429
|
+
},
|
|
430
|
+
bulletList: {
|
|
431
|
+
prefix: "- ",
|
|
432
|
+
multiline: true,
|
|
433
|
+
unorderedList: true
|
|
434
|
+
},
|
|
435
|
+
numberedList: {
|
|
436
|
+
prefix: "1. ",
|
|
437
|
+
multiline: true,
|
|
438
|
+
orderedList: true
|
|
439
|
+
},
|
|
440
|
+
quote: {
|
|
441
|
+
prefix: "> ",
|
|
442
|
+
multiline: true,
|
|
443
|
+
surroundWithNewlines: true
|
|
444
|
+
},
|
|
445
|
+
taskList: {
|
|
446
|
+
prefix: "- [ ] ",
|
|
447
|
+
multiline: true,
|
|
448
|
+
surroundWithNewlines: true
|
|
449
|
+
},
|
|
450
|
+
header1: { prefix: "# " },
|
|
451
|
+
header2: { prefix: "## " },
|
|
452
|
+
header3: { prefix: "### " },
|
|
453
|
+
header4: { prefix: "#### " },
|
|
454
|
+
header5: { prefix: "##### " },
|
|
455
|
+
header6: { prefix: "###### " }
|
|
456
|
+
};
|
|
457
|
+
function getDefaultStyle() {
|
|
458
|
+
return {
|
|
459
|
+
prefix: "",
|
|
460
|
+
suffix: "",
|
|
461
|
+
blockPrefix: "",
|
|
462
|
+
blockSuffix: "",
|
|
463
|
+
multiline: false,
|
|
464
|
+
replaceNext: "",
|
|
465
|
+
prefixSpace: false,
|
|
466
|
+
scanFor: "",
|
|
467
|
+
surroundWithNewlines: false,
|
|
468
|
+
orderedList: false,
|
|
469
|
+
unorderedList: false,
|
|
470
|
+
trimFirst: false
|
|
496
471
|
};
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
}
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
}
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
472
|
+
}
|
|
473
|
+
function mergeWithDefaults(format) {
|
|
474
|
+
return __spreadValues(__spreadValues({}, getDefaultStyle()), format);
|
|
475
|
+
}
|
|
476
|
+
var debugMode = false;
|
|
477
|
+
function getDebugMode() {
|
|
478
|
+
return debugMode;
|
|
479
|
+
}
|
|
480
|
+
function debugLog(funcName, message, data) {
|
|
481
|
+
if (!debugMode)
|
|
482
|
+
return;
|
|
483
|
+
console.group(`\u{1F50D} ${funcName}`);
|
|
484
|
+
console.log(message);
|
|
485
|
+
if (data) {
|
|
486
|
+
console.log("Data:", data);
|
|
487
|
+
}
|
|
488
|
+
console.groupEnd();
|
|
489
|
+
}
|
|
490
|
+
function debugSelection(textarea, label) {
|
|
491
|
+
if (!debugMode)
|
|
492
|
+
return;
|
|
493
|
+
const selected = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd);
|
|
494
|
+
console.group(`\u{1F4CD} Selection: ${label}`);
|
|
495
|
+
console.log("Position:", `${textarea.selectionStart}-${textarea.selectionEnd}`);
|
|
496
|
+
console.log("Selected text:", JSON.stringify(selected));
|
|
497
|
+
console.log("Length:", selected.length);
|
|
498
|
+
const before = textarea.value.slice(Math.max(0, textarea.selectionStart - 10), textarea.selectionStart);
|
|
499
|
+
const after = textarea.value.slice(textarea.selectionEnd, Math.min(textarea.value.length, textarea.selectionEnd + 10));
|
|
500
|
+
console.log("Context:", JSON.stringify(before) + "[SELECTION]" + JSON.stringify(after));
|
|
501
|
+
console.groupEnd();
|
|
502
|
+
}
|
|
503
|
+
function debugResult(result) {
|
|
504
|
+
if (!debugMode)
|
|
505
|
+
return;
|
|
506
|
+
console.group("\u{1F4DD} Result");
|
|
507
|
+
console.log("Text to insert:", JSON.stringify(result.text));
|
|
508
|
+
console.log("New selection:", `${result.selectionStart}-${result.selectionEnd}`);
|
|
509
|
+
console.groupEnd();
|
|
510
|
+
}
|
|
511
|
+
var canInsertText = null;
|
|
512
|
+
function insertText(textarea, { text, selectionStart, selectionEnd }) {
|
|
513
|
+
const debugMode2 = getDebugMode();
|
|
514
|
+
if (debugMode2) {
|
|
515
|
+
console.group("\u{1F527} insertText");
|
|
516
|
+
console.log("Current selection:", `${textarea.selectionStart}-${textarea.selectionEnd}`);
|
|
517
|
+
console.log("Text to insert:", JSON.stringify(text));
|
|
518
|
+
console.log("New selection to set:", selectionStart, "-", selectionEnd);
|
|
519
|
+
}
|
|
520
|
+
textarea.focus();
|
|
521
|
+
const originalSelectionStart = textarea.selectionStart;
|
|
522
|
+
const originalSelectionEnd = textarea.selectionEnd;
|
|
523
|
+
const before = textarea.value.slice(0, originalSelectionStart);
|
|
524
|
+
const after = textarea.value.slice(originalSelectionEnd);
|
|
525
|
+
if (debugMode2) {
|
|
526
|
+
console.log("Before text (last 20):", JSON.stringify(before.slice(-20)));
|
|
527
|
+
console.log("After text (first 20):", JSON.stringify(after.slice(0, 20)));
|
|
528
|
+
console.log("Selected text being replaced:", JSON.stringify(textarea.value.slice(originalSelectionStart, originalSelectionEnd)));
|
|
529
|
+
}
|
|
530
|
+
const originalValue = textarea.value;
|
|
531
|
+
const hasSelection = originalSelectionStart !== originalSelectionEnd;
|
|
532
|
+
if (canInsertText === null || canInsertText === true) {
|
|
533
|
+
textarea.contentEditable = "true";
|
|
534
|
+
try {
|
|
535
|
+
canInsertText = document.execCommand("insertText", false, text);
|
|
536
|
+
if (debugMode2)
|
|
537
|
+
console.log("execCommand returned:", canInsertText, "for text with", text.split("\n").length, "lines");
|
|
538
|
+
} catch (error) {
|
|
539
|
+
canInsertText = false;
|
|
540
|
+
if (debugMode2)
|
|
541
|
+
console.log("execCommand threw error:", error);
|
|
530
542
|
}
|
|
531
|
-
|
|
532
|
-
}
|
|
533
|
-
function debugSelection(textarea, label) {
|
|
534
|
-
if (!debugMode)
|
|
535
|
-
return;
|
|
536
|
-
const selected = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd);
|
|
537
|
-
console.group(`\u{1F4CD} Selection: ${label}`);
|
|
538
|
-
console.log("Position:", `${textarea.selectionStart}-${textarea.selectionEnd}`);
|
|
539
|
-
console.log("Selected text:", JSON.stringify(selected));
|
|
540
|
-
console.log("Length:", selected.length);
|
|
541
|
-
const before = textarea.value.slice(Math.max(0, textarea.selectionStart - 10), textarea.selectionStart);
|
|
542
|
-
const after = textarea.value.slice(textarea.selectionEnd, Math.min(textarea.value.length, textarea.selectionEnd + 10));
|
|
543
|
-
console.log("Context:", JSON.stringify(before) + "[SELECTION]" + JSON.stringify(after));
|
|
544
|
-
console.groupEnd();
|
|
543
|
+
textarea.contentEditable = "false";
|
|
545
544
|
}
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
console.group("\u{1F4DD} Result");
|
|
550
|
-
console.log("Text to insert:", JSON.stringify(result.text));
|
|
551
|
-
console.log("New selection:", `${result.selectionStart}-${result.selectionEnd}`);
|
|
552
|
-
console.groupEnd();
|
|
545
|
+
if (debugMode2) {
|
|
546
|
+
console.log("canInsertText before:", canInsertText);
|
|
547
|
+
console.log("execCommand result:", canInsertText);
|
|
553
548
|
}
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
const
|
|
549
|
+
if (canInsertText) {
|
|
550
|
+
const expectedValue = before + text + after;
|
|
551
|
+
const actualValue = textarea.value;
|
|
557
552
|
if (debugMode2) {
|
|
558
|
-
console.
|
|
559
|
-
console.log("
|
|
560
|
-
console.log("Text to insert:", JSON.stringify(text));
|
|
561
|
-
console.log("New selection to set:", selectionStart, "-", selectionEnd);
|
|
553
|
+
console.log("Expected length:", expectedValue.length);
|
|
554
|
+
console.log("Actual length:", actualValue.length);
|
|
562
555
|
}
|
|
563
|
-
|
|
564
|
-
const originalSelectionStart = textarea.selectionStart;
|
|
565
|
-
const originalSelectionEnd = textarea.selectionEnd;
|
|
566
|
-
const before = textarea.value.slice(0, originalSelectionStart);
|
|
567
|
-
const after = textarea.value.slice(originalSelectionEnd);
|
|
568
|
-
if (debugMode2) {
|
|
569
|
-
console.log("Before text (last 20):", JSON.stringify(before.slice(-20)));
|
|
570
|
-
console.log("After text (first 20):", JSON.stringify(after.slice(0, 20)));
|
|
571
|
-
console.log("Selected text being replaced:", JSON.stringify(textarea.value.slice(originalSelectionStart, originalSelectionEnd)));
|
|
572
|
-
}
|
|
573
|
-
const originalValue = textarea.value;
|
|
574
|
-
const hasSelection = originalSelectionStart !== originalSelectionEnd;
|
|
575
|
-
if (canInsertText === null || canInsertText === true) {
|
|
576
|
-
textarea.contentEditable = "true";
|
|
577
|
-
try {
|
|
578
|
-
canInsertText = document.execCommand("insertText", false, text);
|
|
579
|
-
if (debugMode2)
|
|
580
|
-
console.log("execCommand returned:", canInsertText, "for text with", text.split("\n").length, "lines");
|
|
581
|
-
} catch (error) {
|
|
582
|
-
canInsertText = false;
|
|
583
|
-
if (debugMode2)
|
|
584
|
-
console.log("execCommand threw error:", error);
|
|
585
|
-
}
|
|
586
|
-
textarea.contentEditable = "false";
|
|
587
|
-
}
|
|
588
|
-
if (debugMode2) {
|
|
589
|
-
console.log("canInsertText before:", canInsertText);
|
|
590
|
-
console.log("execCommand result:", canInsertText);
|
|
591
|
-
}
|
|
592
|
-
if (canInsertText) {
|
|
593
|
-
const expectedValue = before + text + after;
|
|
594
|
-
const actualValue = textarea.value;
|
|
556
|
+
if (actualValue !== expectedValue) {
|
|
595
557
|
if (debugMode2) {
|
|
596
|
-
console.log("
|
|
597
|
-
console.log("
|
|
598
|
-
|
|
599
|
-
if (actualValue !== expectedValue) {
|
|
600
|
-
if (debugMode2) {
|
|
601
|
-
console.log("execCommand changed the value but not as expected");
|
|
602
|
-
console.log("Expected:", JSON.stringify(expectedValue.slice(0, 100)));
|
|
603
|
-
console.log("Actual:", JSON.stringify(actualValue.slice(0, 100)));
|
|
604
|
-
}
|
|
558
|
+
console.log("execCommand changed the value but not as expected");
|
|
559
|
+
console.log("Expected:", JSON.stringify(expectedValue.slice(0, 100)));
|
|
560
|
+
console.log("Actual:", JSON.stringify(actualValue.slice(0, 100)));
|
|
605
561
|
}
|
|
606
562
|
}
|
|
607
|
-
|
|
563
|
+
}
|
|
564
|
+
if (!canInsertText) {
|
|
565
|
+
if (debugMode2)
|
|
566
|
+
console.log("Using manual insertion");
|
|
567
|
+
if (textarea.value === originalValue) {
|
|
608
568
|
if (debugMode2)
|
|
609
|
-
console.log("
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
try {
|
|
614
|
-
document.execCommand("ms-beginUndoUnit");
|
|
615
|
-
} catch (e) {
|
|
616
|
-
}
|
|
617
|
-
textarea.value = before + text + after;
|
|
618
|
-
try {
|
|
619
|
-
document.execCommand("ms-endUndoUnit");
|
|
620
|
-
} catch (e) {
|
|
621
|
-
}
|
|
622
|
-
textarea.dispatchEvent(new CustomEvent("input", { bubbles: true, cancelable: true }));
|
|
623
|
-
} else {
|
|
624
|
-
if (debugMode2)
|
|
625
|
-
console.log("Value was changed by execCommand, skipping manual insertion");
|
|
569
|
+
console.log("Value unchanged, doing manual replacement");
|
|
570
|
+
try {
|
|
571
|
+
document.execCommand("ms-beginUndoUnit");
|
|
572
|
+
} catch (e) {
|
|
626
573
|
}
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
574
|
+
textarea.value = before + text + after;
|
|
575
|
+
try {
|
|
576
|
+
document.execCommand("ms-endUndoUnit");
|
|
577
|
+
} catch (e) {
|
|
578
|
+
}
|
|
579
|
+
textarea.dispatchEvent(new CustomEvent("input", { bubbles: true, cancelable: true }));
|
|
632
580
|
} else {
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
if (debugMode2) {
|
|
636
|
-
console.log("Final value length:", textarea.value.length);
|
|
637
|
-
console.groupEnd();
|
|
638
|
-
}
|
|
639
|
-
}
|
|
640
|
-
function setUndoMethod(method) {
|
|
641
|
-
switch (method) {
|
|
642
|
-
case "native":
|
|
643
|
-
canInsertText = true;
|
|
644
|
-
break;
|
|
645
|
-
case "manual":
|
|
646
|
-
canInsertText = false;
|
|
647
|
-
break;
|
|
648
|
-
case "auto":
|
|
649
|
-
canInsertText = null;
|
|
650
|
-
break;
|
|
581
|
+
if (debugMode2)
|
|
582
|
+
console.log("Value was changed by execCommand, skipping manual insertion");
|
|
651
583
|
}
|
|
652
584
|
}
|
|
653
|
-
|
|
654
|
-
|
|
585
|
+
if (debugMode2)
|
|
586
|
+
console.log("Setting selection range:", selectionStart, selectionEnd);
|
|
587
|
+
if (selectionStart != null && selectionEnd != null) {
|
|
588
|
+
textarea.setSelectionRange(selectionStart, selectionEnd);
|
|
589
|
+
} else {
|
|
590
|
+
textarea.setSelectionRange(originalSelectionStart, textarea.selectionEnd);
|
|
655
591
|
}
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
index--;
|
|
660
|
-
}
|
|
661
|
-
return index;
|
|
592
|
+
if (debugMode2) {
|
|
593
|
+
console.log("Final value length:", textarea.value.length);
|
|
594
|
+
console.groupEnd();
|
|
662
595
|
}
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
596
|
+
}
|
|
597
|
+
function isMultipleLines(string) {
|
|
598
|
+
return string.trim().split("\n").length > 1;
|
|
599
|
+
}
|
|
600
|
+
function wordSelectionStart(text, i) {
|
|
601
|
+
let index = i;
|
|
602
|
+
while (text[index] && text[index - 1] != null && !text[index - 1].match(/\s/)) {
|
|
603
|
+
index--;
|
|
670
604
|
}
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
}
|
|
679
|
-
if (textarea.selectionEnd >= counter && textarea.selectionEnd < counter + lineLength) {
|
|
680
|
-
if (index === lines.length - 1) {
|
|
681
|
-
textarea.selectionEnd = Math.min(counter + lines[index].length, textarea.value.length);
|
|
682
|
-
} else {
|
|
683
|
-
textarea.selectionEnd = counter + lineLength - 1;
|
|
684
|
-
}
|
|
685
|
-
}
|
|
686
|
-
counter += lineLength;
|
|
687
|
-
}
|
|
605
|
+
return index;
|
|
606
|
+
}
|
|
607
|
+
function wordSelectionEnd(text, i, multiline) {
|
|
608
|
+
let index = i;
|
|
609
|
+
const breakpoint = multiline ? /\n/ : /\s/;
|
|
610
|
+
while (text[index] && !text[index].match(breakpoint)) {
|
|
611
|
+
index++;
|
|
688
612
|
}
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
613
|
+
return index;
|
|
614
|
+
}
|
|
615
|
+
function expandSelectionToLine(textarea) {
|
|
616
|
+
const lines = textarea.value.split("\n");
|
|
617
|
+
let counter = 0;
|
|
618
|
+
for (let index = 0; index < lines.length; index++) {
|
|
619
|
+
const lineLength = lines[index].length + 1;
|
|
620
|
+
if (textarea.selectionStart >= counter && textarea.selectionStart < counter + lineLength) {
|
|
621
|
+
textarea.selectionStart = counter;
|
|
622
|
+
}
|
|
623
|
+
if (textarea.selectionEnd >= counter && textarea.selectionEnd < counter + lineLength) {
|
|
624
|
+
if (index === lines.length - 1) {
|
|
625
|
+
textarea.selectionEnd = Math.min(counter + lines[index].length, textarea.value.length);
|
|
626
|
+
} else {
|
|
627
|
+
textarea.selectionEnd = counter + lineLength - 1;
|
|
701
628
|
}
|
|
702
629
|
}
|
|
703
|
-
|
|
630
|
+
counter += lineLength;
|
|
704
631
|
}
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
const
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
632
|
+
}
|
|
633
|
+
function expandSelectedText(textarea, prefixToUse, suffixToUse, multiline = false) {
|
|
634
|
+
if (textarea.selectionStart === textarea.selectionEnd) {
|
|
635
|
+
textarea.selectionStart = wordSelectionStart(textarea.value, textarea.selectionStart);
|
|
636
|
+
textarea.selectionEnd = wordSelectionEnd(textarea.value, textarea.selectionEnd, multiline);
|
|
637
|
+
} else {
|
|
638
|
+
const expandedSelectionStart = textarea.selectionStart - prefixToUse.length;
|
|
639
|
+
const expandedSelectionEnd = textarea.selectionEnd + suffixToUse.length;
|
|
640
|
+
const beginsWithPrefix = textarea.value.slice(expandedSelectionStart, textarea.selectionStart) === prefixToUse;
|
|
641
|
+
const endsWithSuffix = textarea.value.slice(textarea.selectionEnd, expandedSelectionEnd) === suffixToUse;
|
|
642
|
+
if (beginsWithPrefix && endsWithSuffix) {
|
|
643
|
+
textarea.selectionStart = expandedSelectionStart;
|
|
644
|
+
textarea.selectionEnd = expandedSelectionEnd;
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
return textarea.value.slice(textarea.selectionStart, textarea.selectionEnd);
|
|
648
|
+
}
|
|
649
|
+
function newlinesToSurroundSelectedText(textarea) {
|
|
650
|
+
const beforeSelection = textarea.value.slice(0, textarea.selectionStart);
|
|
651
|
+
const afterSelection = textarea.value.slice(textarea.selectionEnd);
|
|
652
|
+
const breaksBefore = beforeSelection.match(/\n*$/);
|
|
653
|
+
const breaksAfter = afterSelection.match(/^\n*/);
|
|
654
|
+
const newlinesBeforeSelection = breaksBefore ? breaksBefore[0].length : 0;
|
|
655
|
+
const newlinesAfterSelection = breaksAfter ? breaksAfter[0].length : 0;
|
|
656
|
+
let newlinesToAppend = "";
|
|
657
|
+
let newlinesToPrepend = "";
|
|
658
|
+
if (beforeSelection.match(/\S/) && newlinesBeforeSelection < 2) {
|
|
659
|
+
newlinesToAppend = "\n".repeat(2 - newlinesBeforeSelection);
|
|
660
|
+
}
|
|
661
|
+
if (afterSelection.match(/\S/) && newlinesAfterSelection < 2) {
|
|
662
|
+
newlinesToPrepend = "\n".repeat(2 - newlinesAfterSelection);
|
|
663
|
+
}
|
|
664
|
+
return { newlinesToAppend, newlinesToPrepend };
|
|
665
|
+
}
|
|
666
|
+
function applyLineOperation(textarea, operation, options = {}) {
|
|
667
|
+
const originalStart = textarea.selectionStart;
|
|
668
|
+
const originalEnd = textarea.selectionEnd;
|
|
669
|
+
const noInitialSelection = originalStart === originalEnd;
|
|
670
|
+
const value = textarea.value;
|
|
671
|
+
let lineStart = originalStart;
|
|
672
|
+
while (lineStart > 0 && value[lineStart - 1] !== "\n") {
|
|
673
|
+
lineStart--;
|
|
674
|
+
}
|
|
675
|
+
if (noInitialSelection) {
|
|
676
|
+
let lineEnd = originalStart;
|
|
677
|
+
while (lineEnd < value.length && value[lineEnd] !== "\n") {
|
|
678
|
+
lineEnd++;
|
|
719
679
|
}
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
const end = textarea.selectionEnd;
|
|
725
|
-
const scrollTop = textarea.scrollTop;
|
|
726
|
-
callback();
|
|
727
|
-
textarea.selectionStart = start;
|
|
728
|
-
textarea.selectionEnd = end;
|
|
729
|
-
textarea.scrollTop = scrollTop;
|
|
680
|
+
textarea.selectionStart = lineStart;
|
|
681
|
+
textarea.selectionEnd = lineEnd;
|
|
682
|
+
} else {
|
|
683
|
+
expandSelectionToLine(textarea);
|
|
730
684
|
}
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
const
|
|
734
|
-
const
|
|
735
|
-
const
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
685
|
+
const result = operation(textarea);
|
|
686
|
+
if (options.adjustSelection) {
|
|
687
|
+
const selectedText = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd);
|
|
688
|
+
const isRemoving = selectedText.startsWith(options.prefix);
|
|
689
|
+
const adjusted = options.adjustSelection(isRemoving, originalStart, originalEnd, lineStart);
|
|
690
|
+
result.selectionStart = adjusted.start;
|
|
691
|
+
result.selectionEnd = adjusted.end;
|
|
692
|
+
} else if (options.prefix) {
|
|
693
|
+
const selectedText = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd);
|
|
694
|
+
const isRemoving = selectedText.startsWith(options.prefix);
|
|
740
695
|
if (noInitialSelection) {
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
696
|
+
if (isRemoving) {
|
|
697
|
+
result.selectionStart = Math.max(originalStart - options.prefix.length, lineStart);
|
|
698
|
+
result.selectionEnd = result.selectionStart;
|
|
699
|
+
} else {
|
|
700
|
+
result.selectionStart = originalStart + options.prefix.length;
|
|
701
|
+
result.selectionEnd = result.selectionStart;
|
|
744
702
|
}
|
|
745
|
-
textarea.selectionStart = lineStart;
|
|
746
|
-
textarea.selectionEnd = lineEnd;
|
|
747
703
|
} else {
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
if (options.adjustSelection) {
|
|
752
|
-
const selectedText = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd);
|
|
753
|
-
const isRemoving = selectedText.startsWith(options.prefix);
|
|
754
|
-
const adjusted = options.adjustSelection(isRemoving, originalStart, originalEnd, lineStart);
|
|
755
|
-
result.selectionStart = adjusted.start;
|
|
756
|
-
result.selectionEnd = adjusted.end;
|
|
757
|
-
} else if (options.prefix) {
|
|
758
|
-
const selectedText = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd);
|
|
759
|
-
const isRemoving = selectedText.startsWith(options.prefix);
|
|
760
|
-
if (noInitialSelection) {
|
|
761
|
-
if (isRemoving) {
|
|
762
|
-
result.selectionStart = Math.max(originalStart - options.prefix.length, lineStart);
|
|
763
|
-
result.selectionEnd = result.selectionStart;
|
|
764
|
-
} else {
|
|
765
|
-
result.selectionStart = originalStart + options.prefix.length;
|
|
766
|
-
result.selectionEnd = result.selectionStart;
|
|
767
|
-
}
|
|
704
|
+
if (isRemoving) {
|
|
705
|
+
result.selectionStart = Math.max(originalStart - options.prefix.length, lineStart);
|
|
706
|
+
result.selectionEnd = Math.max(originalEnd - options.prefix.length, lineStart);
|
|
768
707
|
} else {
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
result.selectionEnd = Math.max(originalEnd - options.prefix.length, lineStart);
|
|
772
|
-
} else {
|
|
773
|
-
result.selectionStart = originalStart + options.prefix.length;
|
|
774
|
-
result.selectionEnd = originalEnd + options.prefix.length;
|
|
775
|
-
}
|
|
708
|
+
result.selectionStart = originalStart + options.prefix.length;
|
|
709
|
+
result.selectionEnd = originalEnd + options.prefix.length;
|
|
776
710
|
}
|
|
777
711
|
}
|
|
778
|
-
return result;
|
|
779
712
|
}
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
713
|
+
return result;
|
|
714
|
+
}
|
|
715
|
+
function blockStyle(textarea, style) {
|
|
716
|
+
let newlinesToAppend;
|
|
717
|
+
let newlinesToPrepend;
|
|
718
|
+
const { prefix, suffix, blockPrefix, blockSuffix, replaceNext, prefixSpace, scanFor, surroundWithNewlines, trimFirst } = style;
|
|
719
|
+
const originalSelectionStart = textarea.selectionStart;
|
|
720
|
+
const originalSelectionEnd = textarea.selectionEnd;
|
|
721
|
+
let selectedText = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd);
|
|
722
|
+
let prefixToUse = isMultipleLines(selectedText) && blockPrefix && blockPrefix.length > 0 ? `${blockPrefix}
|
|
788
723
|
` : prefix;
|
|
789
|
-
|
|
724
|
+
let suffixToUse = isMultipleLines(selectedText) && blockSuffix && blockSuffix.length > 0 ? `
|
|
790
725
|
${blockSuffix}` : suffix;
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
} else {
|
|
816
|
-
selectionEnd = selectionStart + replacementText.length;
|
|
817
|
-
}
|
|
818
|
-
return { text: replacementText, selectionStart, selectionEnd };
|
|
819
|
-
} else if (!hasReplaceNext) {
|
|
820
|
-
let replacementText = prefixToUse + selectedText + suffixToUse;
|
|
821
|
-
selectionStart = originalSelectionStart + prefixToUse.length;
|
|
822
|
-
selectionEnd = originalSelectionEnd + prefixToUse.length;
|
|
823
|
-
const whitespaceEdges = selectedText.match(/^\s*|\s*$/g);
|
|
824
|
-
if (trimFirst && whitespaceEdges) {
|
|
825
|
-
const leadingWhitespace = whitespaceEdges[0] || "";
|
|
826
|
-
const trailingWhitespace = whitespaceEdges[1] || "";
|
|
827
|
-
replacementText = leadingWhitespace + prefixToUse + selectedText.trim() + suffixToUse + trailingWhitespace;
|
|
828
|
-
selectionStart += leadingWhitespace.length;
|
|
829
|
-
selectionEnd -= trailingWhitespace.length;
|
|
830
|
-
}
|
|
831
|
-
return { text: replacementText, selectionStart, selectionEnd };
|
|
832
|
-
} else if (scanFor && scanFor.length > 0 && selectedText.match(scanFor)) {
|
|
833
|
-
suffixToUse = suffixToUse.replace(replaceNext, selectedText);
|
|
834
|
-
const replacementText = prefixToUse + suffixToUse;
|
|
835
|
-
selectionStart = selectionEnd = selectionStart + prefixToUse.length;
|
|
836
|
-
return { text: replacementText, selectionStart, selectionEnd };
|
|
726
|
+
if (prefixSpace) {
|
|
727
|
+
const beforeSelection = textarea.value[textarea.selectionStart - 1];
|
|
728
|
+
if (textarea.selectionStart !== 0 && beforeSelection != null && !beforeSelection.match(/\s/)) {
|
|
729
|
+
prefixToUse = ` ${prefixToUse}`;
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
selectedText = expandSelectedText(textarea, prefixToUse, suffixToUse, style.multiline);
|
|
733
|
+
let selectionStart = textarea.selectionStart;
|
|
734
|
+
let selectionEnd = textarea.selectionEnd;
|
|
735
|
+
const hasReplaceNext = replaceNext && replaceNext.length > 0 && suffixToUse.indexOf(replaceNext) > -1 && selectedText.length > 0;
|
|
736
|
+
if (surroundWithNewlines) {
|
|
737
|
+
const ref = newlinesToSurroundSelectedText(textarea);
|
|
738
|
+
newlinesToAppend = ref.newlinesToAppend;
|
|
739
|
+
newlinesToPrepend = ref.newlinesToPrepend;
|
|
740
|
+
prefixToUse = newlinesToAppend + prefix;
|
|
741
|
+
suffixToUse += newlinesToPrepend;
|
|
742
|
+
}
|
|
743
|
+
if (selectedText.startsWith(prefixToUse) && selectedText.endsWith(suffixToUse)) {
|
|
744
|
+
const replacementText = selectedText.slice(prefixToUse.length, selectedText.length - suffixToUse.length);
|
|
745
|
+
if (originalSelectionStart === originalSelectionEnd) {
|
|
746
|
+
let position = originalSelectionStart - prefixToUse.length;
|
|
747
|
+
position = Math.max(position, selectionStart);
|
|
748
|
+
position = Math.min(position, selectionStart + replacementText.length);
|
|
749
|
+
selectionStart = selectionEnd = position;
|
|
837
750
|
} else {
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
751
|
+
selectionEnd = selectionStart + replacementText.length;
|
|
752
|
+
}
|
|
753
|
+
return { text: replacementText, selectionStart, selectionEnd };
|
|
754
|
+
} else if (!hasReplaceNext) {
|
|
755
|
+
let replacementText = prefixToUse + selectedText + suffixToUse;
|
|
756
|
+
selectionStart = originalSelectionStart + prefixToUse.length;
|
|
757
|
+
selectionEnd = originalSelectionEnd + prefixToUse.length;
|
|
758
|
+
const whitespaceEdges = selectedText.match(/^\s*|\s*$/g);
|
|
759
|
+
if (trimFirst && whitespaceEdges) {
|
|
760
|
+
const leadingWhitespace = whitespaceEdges[0] || "";
|
|
761
|
+
const trailingWhitespace = whitespaceEdges[1] || "";
|
|
762
|
+
replacementText = leadingWhitespace + prefixToUse + selectedText.trim() + suffixToUse + trailingWhitespace;
|
|
763
|
+
selectionStart += leadingWhitespace.length;
|
|
764
|
+
selectionEnd -= trailingWhitespace.length;
|
|
765
|
+
}
|
|
766
|
+
return { text: replacementText, selectionStart, selectionEnd };
|
|
767
|
+
} else if (scanFor && scanFor.length > 0 && selectedText.match(scanFor)) {
|
|
768
|
+
suffixToUse = suffixToUse.replace(replaceNext, selectedText);
|
|
769
|
+
const replacementText = prefixToUse + suffixToUse;
|
|
770
|
+
selectionStart = selectionEnd = selectionStart + prefixToUse.length;
|
|
771
|
+
return { text: replacementText, selectionStart, selectionEnd };
|
|
772
|
+
} else {
|
|
773
|
+
const replacementText = prefixToUse + selectedText + suffixToUse;
|
|
774
|
+
selectionStart = selectionStart + prefixToUse.length + selectedText.length + suffixToUse.indexOf(replaceNext);
|
|
775
|
+
selectionEnd = selectionStart + replaceNext.length;
|
|
776
|
+
return { text: replacementText, selectionStart, selectionEnd };
|
|
843
777
|
}
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
778
|
+
}
|
|
779
|
+
function multilineStyle(textarea, style) {
|
|
780
|
+
const { prefix, suffix, surroundWithNewlines } = style;
|
|
781
|
+
let text = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd);
|
|
782
|
+
let selectionStart = textarea.selectionStart;
|
|
783
|
+
let selectionEnd = textarea.selectionEnd;
|
|
784
|
+
const lines = text.split("\n");
|
|
785
|
+
const undoStyle = lines.every((line) => line.startsWith(prefix) && (!suffix || line.endsWith(suffix)));
|
|
786
|
+
if (undoStyle) {
|
|
787
|
+
text = lines.map((line) => {
|
|
788
|
+
let result = line.slice(prefix.length);
|
|
789
|
+
if (suffix) {
|
|
790
|
+
result = result.slice(0, result.length - suffix.length);
|
|
791
|
+
}
|
|
792
|
+
return result;
|
|
793
|
+
}).join("\n");
|
|
794
|
+
selectionEnd = selectionStart + text.length;
|
|
795
|
+
} else {
|
|
796
|
+
text = lines.map((line) => prefix + line + (suffix || "")).join("\n");
|
|
797
|
+
if (surroundWithNewlines) {
|
|
798
|
+
const { newlinesToAppend, newlinesToPrepend } = newlinesToSurroundSelectedText(textarea);
|
|
799
|
+
selectionStart += newlinesToAppend.length;
|
|
859
800
|
selectionEnd = selectionStart + text.length;
|
|
860
|
-
|
|
861
|
-
text = lines.map((line) => prefix + line + (suffix || "")).join("\n");
|
|
862
|
-
if (surroundWithNewlines) {
|
|
863
|
-
const { newlinesToAppend, newlinesToPrepend } = newlinesToSurroundSelectedText(textarea);
|
|
864
|
-
selectionStart += newlinesToAppend.length;
|
|
865
|
-
selectionEnd = selectionStart + text.length;
|
|
866
|
-
text = newlinesToAppend + text + newlinesToPrepend;
|
|
867
|
-
}
|
|
801
|
+
text = newlinesToAppend + text + newlinesToPrepend;
|
|
868
802
|
}
|
|
869
|
-
return { text, selectionStart, selectionEnd };
|
|
870
803
|
}
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
text: result.join("\n"),
|
|
881
|
-
processed: shouldUndoOrderedList
|
|
882
|
-
};
|
|
883
|
-
}
|
|
884
|
-
function undoUnorderedListStyle(text) {
|
|
885
|
-
const lines = text.split("\n");
|
|
886
|
-
const unorderedListPrefix = "- ";
|
|
887
|
-
const shouldUndoUnorderedList = lines.every((line) => line.startsWith(unorderedListPrefix));
|
|
888
|
-
let result = lines;
|
|
889
|
-
if (shouldUndoUnorderedList) {
|
|
890
|
-
result = lines.map((line) => line.slice(unorderedListPrefix.length));
|
|
891
|
-
}
|
|
892
|
-
return {
|
|
893
|
-
text: result.join("\n"),
|
|
894
|
-
processed: shouldUndoUnorderedList
|
|
895
|
-
};
|
|
804
|
+
return { text, selectionStart, selectionEnd };
|
|
805
|
+
}
|
|
806
|
+
function undoOrderedListStyle(text) {
|
|
807
|
+
const lines = text.split("\n");
|
|
808
|
+
const orderedListRegex = /^\d+\.\s+/;
|
|
809
|
+
const shouldUndoOrderedList = lines.every((line) => orderedListRegex.test(line));
|
|
810
|
+
let result = lines;
|
|
811
|
+
if (shouldUndoOrderedList) {
|
|
812
|
+
result = lines.map((line) => line.replace(orderedListRegex, ""));
|
|
896
813
|
}
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
814
|
+
return {
|
|
815
|
+
text: result.join("\n"),
|
|
816
|
+
processed: shouldUndoOrderedList
|
|
817
|
+
};
|
|
818
|
+
}
|
|
819
|
+
function undoUnorderedListStyle(text) {
|
|
820
|
+
const lines = text.split("\n");
|
|
821
|
+
const unorderedListPrefix = "- ";
|
|
822
|
+
const shouldUndoUnorderedList = lines.every((line) => line.startsWith(unorderedListPrefix));
|
|
823
|
+
let result = lines;
|
|
824
|
+
if (shouldUndoUnorderedList) {
|
|
825
|
+
result = lines.map((line) => line.slice(unorderedListPrefix.length));
|
|
903
826
|
}
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
undoResultOppositeList = undoOrderedListStyle(undoResult.text);
|
|
915
|
-
pristineText = undoResultOppositeList.text;
|
|
916
|
-
}
|
|
917
|
-
return [undoResult, undoResultOppositeList, pristineText];
|
|
827
|
+
return {
|
|
828
|
+
text: result.join("\n"),
|
|
829
|
+
processed: shouldUndoUnorderedList
|
|
830
|
+
};
|
|
831
|
+
}
|
|
832
|
+
function makePrefix(index, unorderedList) {
|
|
833
|
+
if (unorderedList) {
|
|
834
|
+
return "- ";
|
|
835
|
+
} else {
|
|
836
|
+
return `${index + 1}. `;
|
|
918
837
|
}
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
838
|
+
}
|
|
839
|
+
function clearExistingListStyle(style, selectedText) {
|
|
840
|
+
let undoResult;
|
|
841
|
+
let undoResultOppositeList;
|
|
842
|
+
let pristineText;
|
|
843
|
+
if (style.orderedList) {
|
|
844
|
+
undoResult = undoOrderedListStyle(selectedText);
|
|
845
|
+
undoResultOppositeList = undoUnorderedListStyle(undoResult.text);
|
|
846
|
+
pristineText = undoResultOppositeList.text;
|
|
847
|
+
} else {
|
|
848
|
+
undoResult = undoUnorderedListStyle(selectedText);
|
|
849
|
+
undoResultOppositeList = undoOrderedListStyle(undoResult.text);
|
|
850
|
+
pristineText = undoResultOppositeList.text;
|
|
851
|
+
}
|
|
852
|
+
return [undoResult, undoResultOppositeList, pristineText];
|
|
853
|
+
}
|
|
854
|
+
function listStyle(textarea, style) {
|
|
855
|
+
const noInitialSelection = textarea.selectionStart === textarea.selectionEnd;
|
|
856
|
+
let selectionStart = textarea.selectionStart;
|
|
857
|
+
let selectionEnd = textarea.selectionEnd;
|
|
858
|
+
expandSelectionToLine(textarea);
|
|
859
|
+
const selectedText = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd);
|
|
860
|
+
const [undoResult, undoResultOppositeList, pristineText] = clearExistingListStyle(style, selectedText);
|
|
861
|
+
const prefixedLines = pristineText.split("\n").map((value, index) => {
|
|
862
|
+
return `${makePrefix(index, style.unorderedList)}${value}`;
|
|
863
|
+
});
|
|
864
|
+
const totalPrefixLength = prefixedLines.reduce((previousValue, _currentValue, currentIndex) => {
|
|
865
|
+
return previousValue + makePrefix(currentIndex, style.unorderedList).length;
|
|
866
|
+
}, 0);
|
|
867
|
+
const totalPrefixLengthOppositeList = prefixedLines.reduce((previousValue, _currentValue, currentIndex) => {
|
|
868
|
+
return previousValue + makePrefix(currentIndex, !style.unorderedList).length;
|
|
869
|
+
}, 0);
|
|
870
|
+
if (undoResult.processed) {
|
|
947
871
|
if (noInitialSelection) {
|
|
948
|
-
selectionStart = Math.max(selectionStart
|
|
872
|
+
selectionStart = Math.max(selectionStart - makePrefix(0, style.unorderedList).length, 0);
|
|
949
873
|
selectionEnd = selectionStart;
|
|
950
874
|
} else {
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
875
|
+
selectionStart = textarea.selectionStart;
|
|
876
|
+
selectionEnd = textarea.selectionEnd - totalPrefixLength;
|
|
877
|
+
}
|
|
878
|
+
return { text: pristineText, selectionStart, selectionEnd };
|
|
879
|
+
}
|
|
880
|
+
const { newlinesToAppend, newlinesToPrepend } = newlinesToSurroundSelectedText(textarea);
|
|
881
|
+
const text = newlinesToAppend + prefixedLines.join("\n") + newlinesToPrepend;
|
|
882
|
+
if (noInitialSelection) {
|
|
883
|
+
selectionStart = Math.max(selectionStart + makePrefix(0, style.unorderedList).length + newlinesToAppend.length, 0);
|
|
884
|
+
selectionEnd = selectionStart;
|
|
885
|
+
} else {
|
|
886
|
+
if (undoResultOppositeList.processed) {
|
|
887
|
+
selectionStart = Math.max(textarea.selectionStart + newlinesToAppend.length, 0);
|
|
888
|
+
selectionEnd = textarea.selectionEnd + newlinesToAppend.length + totalPrefixLength - totalPrefixLengthOppositeList;
|
|
889
|
+
} else {
|
|
890
|
+
selectionStart = Math.max(textarea.selectionStart + newlinesToAppend.length, 0);
|
|
891
|
+
selectionEnd = textarea.selectionEnd + newlinesToAppend.length + totalPrefixLength;
|
|
958
892
|
}
|
|
959
|
-
|
|
960
|
-
}
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
}
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
}
|
|
992
|
-
const prefixLength = style.unorderedList ? 2 : 3;
|
|
993
|
-
return {
|
|
994
|
-
start: selStart + prefixLength,
|
|
995
|
-
end: selStart + prefixLength
|
|
996
|
-
};
|
|
997
|
-
}
|
|
893
|
+
}
|
|
894
|
+
return { text, selectionStart, selectionEnd };
|
|
895
|
+
}
|
|
896
|
+
function applyListStyle(textarea, style) {
|
|
897
|
+
const result = applyLineOperation(
|
|
898
|
+
textarea,
|
|
899
|
+
(ta) => listStyle(ta, style),
|
|
900
|
+
{
|
|
901
|
+
// Custom selection adjustment for lists
|
|
902
|
+
adjustSelection: (isRemoving, selStart, selEnd, lineStart) => {
|
|
903
|
+
const currentLine = textarea.value.slice(lineStart, textarea.selectionEnd);
|
|
904
|
+
const orderedListRegex = /^\d+\.\s+/;
|
|
905
|
+
const unorderedListRegex = /^- /;
|
|
906
|
+
const hasOrderedList = orderedListRegex.test(currentLine);
|
|
907
|
+
const hasUnorderedList = unorderedListRegex.test(currentLine);
|
|
908
|
+
const isRemovingCurrent = style.orderedList && hasOrderedList || style.unorderedList && hasUnorderedList;
|
|
909
|
+
if (selStart === selEnd) {
|
|
910
|
+
if (isRemovingCurrent) {
|
|
911
|
+
const prefixMatch = currentLine.match(style.orderedList ? orderedListRegex : unorderedListRegex);
|
|
912
|
+
const prefixLength = prefixMatch ? prefixMatch[0].length : 0;
|
|
913
|
+
return {
|
|
914
|
+
start: Math.max(selStart - prefixLength, lineStart),
|
|
915
|
+
end: Math.max(selStart - prefixLength, lineStart)
|
|
916
|
+
};
|
|
917
|
+
} else if (hasOrderedList || hasUnorderedList) {
|
|
918
|
+
const oldPrefixMatch = currentLine.match(hasOrderedList ? orderedListRegex : unorderedListRegex);
|
|
919
|
+
const oldPrefixLength = oldPrefixMatch ? oldPrefixMatch[0].length : 0;
|
|
920
|
+
const newPrefixLength = style.unorderedList ? 2 : 3;
|
|
921
|
+
const adjustment = newPrefixLength - oldPrefixLength;
|
|
922
|
+
return {
|
|
923
|
+
start: selStart + adjustment,
|
|
924
|
+
end: selStart + adjustment
|
|
925
|
+
};
|
|
998
926
|
} else {
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
end: Math.max(selEnd - prefixLength, lineStart)
|
|
1005
|
-
};
|
|
1006
|
-
} else if (hasOrderedList || hasUnorderedList) {
|
|
1007
|
-
const oldPrefixMatch = currentLine.match(hasOrderedList ? orderedListRegex : unorderedListRegex);
|
|
1008
|
-
const oldPrefixLength = oldPrefixMatch ? oldPrefixMatch[0].length : 0;
|
|
1009
|
-
const newPrefixLength = style.unorderedList ? 2 : 3;
|
|
1010
|
-
const adjustment = newPrefixLength - oldPrefixLength;
|
|
1011
|
-
return {
|
|
1012
|
-
start: selStart + adjustment,
|
|
1013
|
-
end: selEnd + adjustment
|
|
1014
|
-
};
|
|
1015
|
-
} else {
|
|
1016
|
-
const prefixLength = style.unorderedList ? 2 : 3;
|
|
1017
|
-
return {
|
|
1018
|
-
start: selStart + prefixLength,
|
|
1019
|
-
end: selEnd + prefixLength
|
|
1020
|
-
};
|
|
1021
|
-
}
|
|
927
|
+
const prefixLength = style.unorderedList ? 2 : 3;
|
|
928
|
+
return {
|
|
929
|
+
start: selStart + prefixLength,
|
|
930
|
+
end: selStart + prefixLength
|
|
931
|
+
};
|
|
1022
932
|
}
|
|
1023
|
-
}
|
|
1024
|
-
}
|
|
1025
|
-
);
|
|
1026
|
-
insertText(textarea, result);
|
|
1027
|
-
}
|
|
1028
|
-
function getActiveFormats2(textarea) {
|
|
1029
|
-
if (!textarea)
|
|
1030
|
-
return [];
|
|
1031
|
-
const formats = [];
|
|
1032
|
-
const { selectionStart, selectionEnd, value } = textarea;
|
|
1033
|
-
const lines = value.split("\n");
|
|
1034
|
-
let lineStart = 0;
|
|
1035
|
-
let currentLine = "";
|
|
1036
|
-
for (const line of lines) {
|
|
1037
|
-
if (selectionStart >= lineStart && selectionStart <= lineStart + line.length) {
|
|
1038
|
-
currentLine = line;
|
|
1039
|
-
break;
|
|
1040
|
-
}
|
|
1041
|
-
lineStart += line.length + 1;
|
|
1042
|
-
}
|
|
1043
|
-
if (currentLine.startsWith("- ")) {
|
|
1044
|
-
if (currentLine.startsWith("- [ ] ") || currentLine.startsWith("- [x] ")) {
|
|
1045
|
-
formats.push("task-list");
|
|
1046
|
-
} else {
|
|
1047
|
-
formats.push("bullet-list");
|
|
1048
|
-
}
|
|
1049
|
-
}
|
|
1050
|
-
if (/^\d+\.\s/.test(currentLine)) {
|
|
1051
|
-
formats.push("numbered-list");
|
|
1052
|
-
}
|
|
1053
|
-
if (currentLine.startsWith("> ")) {
|
|
1054
|
-
formats.push("quote");
|
|
1055
|
-
}
|
|
1056
|
-
if (currentLine.startsWith("# "))
|
|
1057
|
-
formats.push("header");
|
|
1058
|
-
if (currentLine.startsWith("## "))
|
|
1059
|
-
formats.push("header-2");
|
|
1060
|
-
if (currentLine.startsWith("### "))
|
|
1061
|
-
formats.push("header-3");
|
|
1062
|
-
const lookBehind = Math.max(0, selectionStart - 10);
|
|
1063
|
-
const lookAhead = Math.min(value.length, selectionEnd + 10);
|
|
1064
|
-
const surrounding = value.slice(lookBehind, lookAhead);
|
|
1065
|
-
if (surrounding.includes("**")) {
|
|
1066
|
-
const beforeCursor = value.slice(Math.max(0, selectionStart - 100), selectionStart);
|
|
1067
|
-
const afterCursor = value.slice(selectionEnd, Math.min(value.length, selectionEnd + 100));
|
|
1068
|
-
const lastOpenBold = beforeCursor.lastIndexOf("**");
|
|
1069
|
-
const nextCloseBold = afterCursor.indexOf("**");
|
|
1070
|
-
if (lastOpenBold !== -1 && nextCloseBold !== -1) {
|
|
1071
|
-
formats.push("bold");
|
|
1072
|
-
}
|
|
1073
|
-
}
|
|
1074
|
-
if (surrounding.includes("_")) {
|
|
1075
|
-
const beforeCursor = value.slice(Math.max(0, selectionStart - 100), selectionStart);
|
|
1076
|
-
const afterCursor = value.slice(selectionEnd, Math.min(value.length, selectionEnd + 100));
|
|
1077
|
-
const lastOpenItalic = beforeCursor.lastIndexOf("_");
|
|
1078
|
-
const nextCloseItalic = afterCursor.indexOf("_");
|
|
1079
|
-
if (lastOpenItalic !== -1 && nextCloseItalic !== -1) {
|
|
1080
|
-
formats.push("italic");
|
|
1081
|
-
}
|
|
1082
|
-
}
|
|
1083
|
-
if (surrounding.includes("`")) {
|
|
1084
|
-
const beforeCursor = value.slice(Math.max(0, selectionStart - 100), selectionStart);
|
|
1085
|
-
const afterCursor = value.slice(selectionEnd, Math.min(value.length, selectionEnd + 100));
|
|
1086
|
-
if (beforeCursor.includes("`") && afterCursor.includes("`")) {
|
|
1087
|
-
formats.push("code");
|
|
1088
|
-
}
|
|
1089
|
-
}
|
|
1090
|
-
if (surrounding.includes("[") && surrounding.includes("]")) {
|
|
1091
|
-
const beforeCursor = value.slice(Math.max(0, selectionStart - 100), selectionStart);
|
|
1092
|
-
const afterCursor = value.slice(selectionEnd, Math.min(value.length, selectionEnd + 100));
|
|
1093
|
-
const lastOpenBracket = beforeCursor.lastIndexOf("[");
|
|
1094
|
-
const nextCloseBracket = afterCursor.indexOf("]");
|
|
1095
|
-
if (lastOpenBracket !== -1 && nextCloseBracket !== -1) {
|
|
1096
|
-
const afterBracket = value.slice(selectionEnd + nextCloseBracket + 1, selectionEnd + nextCloseBracket + 10);
|
|
1097
|
-
if (afterBracket.startsWith("(")) {
|
|
1098
|
-
formats.push("link");
|
|
1099
|
-
}
|
|
1100
|
-
}
|
|
1101
|
-
}
|
|
1102
|
-
return formats;
|
|
1103
|
-
}
|
|
1104
|
-
function hasFormat(textarea, format) {
|
|
1105
|
-
const activeFormats = getActiveFormats2(textarea);
|
|
1106
|
-
return activeFormats.includes(format);
|
|
1107
|
-
}
|
|
1108
|
-
function expandSelection(textarea, options = {}) {
|
|
1109
|
-
if (!textarea)
|
|
1110
|
-
return;
|
|
1111
|
-
const { toWord, toLine, toFormat } = options;
|
|
1112
|
-
const { selectionStart, selectionEnd, value } = textarea;
|
|
1113
|
-
if (toLine) {
|
|
1114
|
-
const lines = value.split("\n");
|
|
1115
|
-
let lineStart = 0;
|
|
1116
|
-
let lineEnd = 0;
|
|
1117
|
-
let currentPos = 0;
|
|
1118
|
-
for (const line of lines) {
|
|
1119
|
-
if (selectionStart >= currentPos && selectionStart <= currentPos + line.length) {
|
|
1120
|
-
lineStart = currentPos;
|
|
1121
|
-
lineEnd = currentPos + line.length;
|
|
1122
|
-
break;
|
|
1123
|
-
}
|
|
1124
|
-
currentPos += line.length + 1;
|
|
1125
|
-
}
|
|
1126
|
-
textarea.selectionStart = lineStart;
|
|
1127
|
-
textarea.selectionEnd = lineEnd;
|
|
1128
|
-
} else if (toWord && selectionStart === selectionEnd) {
|
|
1129
|
-
let start = selectionStart;
|
|
1130
|
-
let end = selectionEnd;
|
|
1131
|
-
while (start > 0 && !/\s/.test(value[start - 1])) {
|
|
1132
|
-
start--;
|
|
1133
|
-
}
|
|
1134
|
-
while (end < value.length && !/\s/.test(value[end])) {
|
|
1135
|
-
end++;
|
|
1136
|
-
}
|
|
1137
|
-
textarea.selectionStart = start;
|
|
1138
|
-
textarea.selectionEnd = end;
|
|
1139
|
-
}
|
|
1140
|
-
}
|
|
1141
|
-
function toggleBold3(textarea) {
|
|
1142
|
-
if (!textarea || textarea.disabled || textarea.readOnly)
|
|
1143
|
-
return;
|
|
1144
|
-
debugLog("toggleBold", "Starting");
|
|
1145
|
-
debugSelection(textarea, "Before");
|
|
1146
|
-
const style = mergeWithDefaults(FORMATS.bold);
|
|
1147
|
-
const result = blockStyle(textarea, style);
|
|
1148
|
-
debugResult(result);
|
|
1149
|
-
insertText(textarea, result);
|
|
1150
|
-
debugSelection(textarea, "After");
|
|
1151
|
-
}
|
|
1152
|
-
function toggleItalic3(textarea) {
|
|
1153
|
-
if (!textarea || textarea.disabled || textarea.readOnly)
|
|
1154
|
-
return;
|
|
1155
|
-
const style = mergeWithDefaults(FORMATS.italic);
|
|
1156
|
-
const result = blockStyle(textarea, style);
|
|
1157
|
-
insertText(textarea, result);
|
|
1158
|
-
}
|
|
1159
|
-
function toggleCode2(textarea) {
|
|
1160
|
-
if (!textarea || textarea.disabled || textarea.readOnly)
|
|
1161
|
-
return;
|
|
1162
|
-
const style = mergeWithDefaults(FORMATS.code);
|
|
1163
|
-
const result = blockStyle(textarea, style);
|
|
1164
|
-
insertText(textarea, result);
|
|
1165
|
-
}
|
|
1166
|
-
function insertLink3(textarea, options = {}) {
|
|
1167
|
-
if (!textarea || textarea.disabled || textarea.readOnly)
|
|
1168
|
-
return;
|
|
1169
|
-
const selectedText = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd);
|
|
1170
|
-
let style = mergeWithDefaults(FORMATS.link);
|
|
1171
|
-
const isURL = selectedText && selectedText.match(/^https?:\/\//);
|
|
1172
|
-
if (isURL && !options.url) {
|
|
1173
|
-
style.suffix = `](${selectedText})`;
|
|
1174
|
-
style.replaceNext = "";
|
|
1175
|
-
} else if (options.url) {
|
|
1176
|
-
style.suffix = `](${options.url})`;
|
|
1177
|
-
style.replaceNext = "";
|
|
1178
|
-
}
|
|
1179
|
-
if (options.text && !selectedText) {
|
|
1180
|
-
const pos = textarea.selectionStart;
|
|
1181
|
-
textarea.value = textarea.value.slice(0, pos) + options.text + textarea.value.slice(pos);
|
|
1182
|
-
textarea.selectionStart = pos;
|
|
1183
|
-
textarea.selectionEnd = pos + options.text.length;
|
|
1184
|
-
}
|
|
1185
|
-
const result = blockStyle(textarea, style);
|
|
1186
|
-
insertText(textarea, result);
|
|
1187
|
-
}
|
|
1188
|
-
function toggleBulletList3(textarea) {
|
|
1189
|
-
if (!textarea || textarea.disabled || textarea.readOnly)
|
|
1190
|
-
return;
|
|
1191
|
-
const style = mergeWithDefaults(FORMATS.bulletList);
|
|
1192
|
-
applyListStyle(textarea, style);
|
|
1193
|
-
}
|
|
1194
|
-
function toggleNumberedList3(textarea) {
|
|
1195
|
-
if (!textarea || textarea.disabled || textarea.readOnly)
|
|
1196
|
-
return;
|
|
1197
|
-
const style = mergeWithDefaults(FORMATS.numberedList);
|
|
1198
|
-
applyListStyle(textarea, style);
|
|
1199
|
-
}
|
|
1200
|
-
function toggleQuote2(textarea) {
|
|
1201
|
-
if (!textarea || textarea.disabled || textarea.readOnly)
|
|
1202
|
-
return;
|
|
1203
|
-
debugLog("toggleQuote", "Starting");
|
|
1204
|
-
debugSelection(textarea, "Initial");
|
|
1205
|
-
const style = mergeWithDefaults(FORMATS.quote);
|
|
1206
|
-
const result = applyLineOperation(
|
|
1207
|
-
textarea,
|
|
1208
|
-
(ta) => multilineStyle(ta, style),
|
|
1209
|
-
{ prefix: style.prefix }
|
|
1210
|
-
);
|
|
1211
|
-
debugResult(result);
|
|
1212
|
-
insertText(textarea, result);
|
|
1213
|
-
debugSelection(textarea, "Final");
|
|
1214
|
-
}
|
|
1215
|
-
function toggleTaskList2(textarea) {
|
|
1216
|
-
if (!textarea || textarea.disabled || textarea.readOnly)
|
|
1217
|
-
return;
|
|
1218
|
-
const style = mergeWithDefaults(FORMATS.taskList);
|
|
1219
|
-
const result = applyLineOperation(
|
|
1220
|
-
textarea,
|
|
1221
|
-
(ta) => multilineStyle(ta, style),
|
|
1222
|
-
{ prefix: style.prefix }
|
|
1223
|
-
);
|
|
1224
|
-
insertText(textarea, result);
|
|
1225
|
-
}
|
|
1226
|
-
function insertHeader(textarea, level = 1, toggle = false) {
|
|
1227
|
-
if (!textarea || textarea.disabled || textarea.readOnly)
|
|
1228
|
-
return;
|
|
1229
|
-
if (level < 1 || level > 6)
|
|
1230
|
-
level = 1;
|
|
1231
|
-
debugLog("insertHeader", `============ START ============`);
|
|
1232
|
-
debugLog("insertHeader", `Level: ${level}, Toggle: ${toggle}`);
|
|
1233
|
-
debugLog("insertHeader", `Initial cursor: ${textarea.selectionStart}-${textarea.selectionEnd}`);
|
|
1234
|
-
const headerKey = `header${level === 1 ? "1" : level}`;
|
|
1235
|
-
const style = mergeWithDefaults(FORMATS[headerKey] || FORMATS.header1);
|
|
1236
|
-
debugLog("insertHeader", `Style prefix: "${style.prefix}"`);
|
|
1237
|
-
const value = textarea.value;
|
|
1238
|
-
const originalStart = textarea.selectionStart;
|
|
1239
|
-
const originalEnd = textarea.selectionEnd;
|
|
1240
|
-
let lineStart = originalStart;
|
|
1241
|
-
while (lineStart > 0 && value[lineStart - 1] !== "\n") {
|
|
1242
|
-
lineStart--;
|
|
1243
|
-
}
|
|
1244
|
-
let lineEnd = originalEnd;
|
|
1245
|
-
while (lineEnd < value.length && value[lineEnd] !== "\n") {
|
|
1246
|
-
lineEnd++;
|
|
1247
|
-
}
|
|
1248
|
-
const currentLineContent = value.slice(lineStart, lineEnd);
|
|
1249
|
-
debugLog("insertHeader", `Current line (before): "${currentLineContent}"`);
|
|
1250
|
-
const existingHeaderMatch = currentLineContent.match(/^(#{1,6})\s*/);
|
|
1251
|
-
const existingLevel = existingHeaderMatch ? existingHeaderMatch[1].length : 0;
|
|
1252
|
-
const existingPrefixLength = existingHeaderMatch ? existingHeaderMatch[0].length : 0;
|
|
1253
|
-
debugLog("insertHeader", `Existing header check:`);
|
|
1254
|
-
debugLog("insertHeader", ` - Match: ${existingHeaderMatch ? `"${existingHeaderMatch[0]}"` : "none"}`);
|
|
1255
|
-
debugLog("insertHeader", ` - Existing level: ${existingLevel}`);
|
|
1256
|
-
debugLog("insertHeader", ` - Existing prefix length: ${existingPrefixLength}`);
|
|
1257
|
-
debugLog("insertHeader", ` - Target level: ${level}`);
|
|
1258
|
-
const shouldToggleOff = toggle && existingLevel === level;
|
|
1259
|
-
debugLog("insertHeader", `Should toggle OFF: ${shouldToggleOff} (toggle=${toggle}, existingLevel=${existingLevel}, level=${level})`);
|
|
1260
|
-
const result = applyLineOperation(
|
|
1261
|
-
textarea,
|
|
1262
|
-
(ta) => {
|
|
1263
|
-
const currentLine = ta.value.slice(ta.selectionStart, ta.selectionEnd);
|
|
1264
|
-
debugLog("insertHeader", `Line in operation: "${currentLine}"`);
|
|
1265
|
-
const cleanedLine = currentLine.replace(/^#{1,6}\s*/, "");
|
|
1266
|
-
debugLog("insertHeader", `Cleaned line: "${cleanedLine}"`);
|
|
1267
|
-
let newLine;
|
|
1268
|
-
if (shouldToggleOff) {
|
|
1269
|
-
debugLog("insertHeader", "ACTION: Toggling OFF - removing header");
|
|
1270
|
-
newLine = cleanedLine;
|
|
1271
|
-
} else if (existingLevel > 0) {
|
|
1272
|
-
debugLog("insertHeader", `ACTION: Replacing H${existingLevel} with H${level}`);
|
|
1273
|
-
newLine = style.prefix + cleanedLine;
|
|
1274
933
|
} else {
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
debugLog("insertHeader", `New line: "${newLine}"`);
|
|
1279
|
-
return {
|
|
1280
|
-
text: newLine,
|
|
1281
|
-
selectionStart: ta.selectionStart,
|
|
1282
|
-
selectionEnd: ta.selectionEnd
|
|
1283
|
-
};
|
|
1284
|
-
},
|
|
1285
|
-
{
|
|
1286
|
-
prefix: style.prefix,
|
|
1287
|
-
// Custom selection adjustment for headers
|
|
1288
|
-
adjustSelection: (isRemoving, selStart, selEnd, lineStartPos) => {
|
|
1289
|
-
debugLog("insertHeader", `Adjusting selection:`);
|
|
1290
|
-
debugLog("insertHeader", ` - isRemoving param: ${isRemoving}`);
|
|
1291
|
-
debugLog("insertHeader", ` - shouldToggleOff: ${shouldToggleOff}`);
|
|
1292
|
-
debugLog("insertHeader", ` - selStart: ${selStart}, selEnd: ${selEnd}`);
|
|
1293
|
-
debugLog("insertHeader", ` - lineStartPos: ${lineStartPos}`);
|
|
1294
|
-
if (shouldToggleOff) {
|
|
1295
|
-
const adjustment = Math.max(selStart - existingPrefixLength, lineStartPos);
|
|
1296
|
-
debugLog("insertHeader", ` - Removing header, adjusting by -${existingPrefixLength}`);
|
|
934
|
+
if (isRemovingCurrent) {
|
|
935
|
+
const prefixMatch = currentLine.match(style.orderedList ? orderedListRegex : unorderedListRegex);
|
|
936
|
+
const prefixLength = prefixMatch ? prefixMatch[0].length : 0;
|
|
1297
937
|
return {
|
|
1298
|
-
start:
|
|
1299
|
-
end:
|
|
938
|
+
start: Math.max(selStart - prefixLength, lineStart),
|
|
939
|
+
end: Math.max(selEnd - prefixLength, lineStart)
|
|
1300
940
|
};
|
|
1301
|
-
} else if (
|
|
1302
|
-
const
|
|
1303
|
-
|
|
941
|
+
} else if (hasOrderedList || hasUnorderedList) {
|
|
942
|
+
const oldPrefixMatch = currentLine.match(hasOrderedList ? orderedListRegex : unorderedListRegex);
|
|
943
|
+
const oldPrefixLength = oldPrefixMatch ? oldPrefixMatch[0].length : 0;
|
|
944
|
+
const newPrefixLength = style.unorderedList ? 2 : 3;
|
|
945
|
+
const adjustment = newPrefixLength - oldPrefixLength;
|
|
1304
946
|
return {
|
|
1305
|
-
start: selStart +
|
|
1306
|
-
end: selEnd +
|
|
947
|
+
start: selStart + adjustment,
|
|
948
|
+
end: selEnd + adjustment
|
|
1307
949
|
};
|
|
1308
950
|
} else {
|
|
1309
|
-
|
|
951
|
+
const prefixLength = style.unorderedList ? 2 : 3;
|
|
1310
952
|
return {
|
|
1311
|
-
start: selStart +
|
|
1312
|
-
end: selEnd +
|
|
953
|
+
start: selStart + prefixLength,
|
|
954
|
+
end: selEnd + prefixLength
|
|
1313
955
|
};
|
|
1314
956
|
}
|
|
1315
957
|
}
|
|
1316
958
|
}
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
959
|
+
}
|
|
960
|
+
);
|
|
961
|
+
insertText(textarea, result);
|
|
962
|
+
}
|
|
963
|
+
function getActiveFormats(textarea) {
|
|
964
|
+
if (!textarea)
|
|
965
|
+
return [];
|
|
966
|
+
const formats = [];
|
|
967
|
+
const { selectionStart, selectionEnd, value } = textarea;
|
|
968
|
+
const lines = value.split("\n");
|
|
969
|
+
let lineStart = 0;
|
|
970
|
+
let currentLine = "";
|
|
971
|
+
for (const line of lines) {
|
|
972
|
+
if (selectionStart >= lineStart && selectionStart <= lineStart + line.length) {
|
|
973
|
+
currentLine = line;
|
|
974
|
+
break;
|
|
975
|
+
}
|
|
976
|
+
lineStart += line.length + 1;
|
|
977
|
+
}
|
|
978
|
+
if (currentLine.startsWith("- ")) {
|
|
979
|
+
if (currentLine.startsWith("- [ ] ") || currentLine.startsWith("- [x] ")) {
|
|
980
|
+
formats.push("task-list");
|
|
981
|
+
} else {
|
|
982
|
+
formats.push("bullet-list");
|
|
983
|
+
}
|
|
984
|
+
}
|
|
985
|
+
if (/^\d+\.\s/.test(currentLine)) {
|
|
986
|
+
formats.push("numbered-list");
|
|
987
|
+
}
|
|
988
|
+
if (currentLine.startsWith("> ")) {
|
|
989
|
+
formats.push("quote");
|
|
990
|
+
}
|
|
991
|
+
if (currentLine.startsWith("# "))
|
|
992
|
+
formats.push("header");
|
|
993
|
+
if (currentLine.startsWith("## "))
|
|
994
|
+
formats.push("header-2");
|
|
995
|
+
if (currentLine.startsWith("### "))
|
|
996
|
+
formats.push("header-3");
|
|
997
|
+
const lookBehind = Math.max(0, selectionStart - 10);
|
|
998
|
+
const lookAhead = Math.min(value.length, selectionEnd + 10);
|
|
999
|
+
const surrounding = value.slice(lookBehind, lookAhead);
|
|
1000
|
+
if (surrounding.includes("**")) {
|
|
1001
|
+
const beforeCursor = value.slice(Math.max(0, selectionStart - 100), selectionStart);
|
|
1002
|
+
const afterCursor = value.slice(selectionEnd, Math.min(value.length, selectionEnd + 100));
|
|
1003
|
+
const lastOpenBold = beforeCursor.lastIndexOf("**");
|
|
1004
|
+
const nextCloseBold = afterCursor.indexOf("**");
|
|
1005
|
+
if (lastOpenBold !== -1 && nextCloseBold !== -1) {
|
|
1006
|
+
formats.push("bold");
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1009
|
+
if (surrounding.includes("_")) {
|
|
1010
|
+
const beforeCursor = value.slice(Math.max(0, selectionStart - 100), selectionStart);
|
|
1011
|
+
const afterCursor = value.slice(selectionEnd, Math.min(value.length, selectionEnd + 100));
|
|
1012
|
+
const lastOpenItalic = beforeCursor.lastIndexOf("_");
|
|
1013
|
+
const nextCloseItalic = afterCursor.indexOf("_");
|
|
1014
|
+
if (lastOpenItalic !== -1 && nextCloseItalic !== -1) {
|
|
1015
|
+
formats.push("italic");
|
|
1016
|
+
}
|
|
1017
|
+
}
|
|
1018
|
+
if (surrounding.includes("`")) {
|
|
1019
|
+
const beforeCursor = value.slice(Math.max(0, selectionStart - 100), selectionStart);
|
|
1020
|
+
const afterCursor = value.slice(selectionEnd, Math.min(value.length, selectionEnd + 100));
|
|
1021
|
+
if (beforeCursor.includes("`") && afterCursor.includes("`")) {
|
|
1022
|
+
formats.push("code");
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
1025
|
+
if (surrounding.includes("[") && surrounding.includes("]")) {
|
|
1026
|
+
const beforeCursor = value.slice(Math.max(0, selectionStart - 100), selectionStart);
|
|
1027
|
+
const afterCursor = value.slice(selectionEnd, Math.min(value.length, selectionEnd + 100));
|
|
1028
|
+
const lastOpenBracket = beforeCursor.lastIndexOf("[");
|
|
1029
|
+
const nextCloseBracket = afterCursor.indexOf("]");
|
|
1030
|
+
if (lastOpenBracket !== -1 && nextCloseBracket !== -1) {
|
|
1031
|
+
const afterBracket = value.slice(selectionEnd + nextCloseBracket + 1, selectionEnd + nextCloseBracket + 10);
|
|
1032
|
+
if (afterBracket.startsWith("(")) {
|
|
1033
|
+
formats.push("link");
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
1037
|
+
return formats;
|
|
1038
|
+
}
|
|
1039
|
+
function toggleBold(textarea) {
|
|
1040
|
+
if (!textarea || textarea.disabled || textarea.readOnly)
|
|
1041
|
+
return;
|
|
1042
|
+
debugLog("toggleBold", "Starting");
|
|
1043
|
+
debugSelection(textarea, "Before");
|
|
1044
|
+
const style = mergeWithDefaults(FORMATS.bold);
|
|
1045
|
+
const result = blockStyle(textarea, style);
|
|
1046
|
+
debugResult(result);
|
|
1047
|
+
insertText(textarea, result);
|
|
1048
|
+
debugSelection(textarea, "After");
|
|
1049
|
+
}
|
|
1050
|
+
function toggleItalic(textarea) {
|
|
1051
|
+
if (!textarea || textarea.disabled || textarea.readOnly)
|
|
1052
|
+
return;
|
|
1053
|
+
const style = mergeWithDefaults(FORMATS.italic);
|
|
1054
|
+
const result = blockStyle(textarea, style);
|
|
1055
|
+
insertText(textarea, result);
|
|
1056
|
+
}
|
|
1057
|
+
function toggleCode(textarea) {
|
|
1058
|
+
if (!textarea || textarea.disabled || textarea.readOnly)
|
|
1059
|
+
return;
|
|
1060
|
+
const style = mergeWithDefaults(FORMATS.code);
|
|
1061
|
+
const result = blockStyle(textarea, style);
|
|
1062
|
+
insertText(textarea, result);
|
|
1063
|
+
}
|
|
1064
|
+
function insertLink(textarea, options = {}) {
|
|
1065
|
+
if (!textarea || textarea.disabled || textarea.readOnly)
|
|
1066
|
+
return;
|
|
1067
|
+
const selectedText = textarea.value.slice(textarea.selectionStart, textarea.selectionEnd);
|
|
1068
|
+
let style = mergeWithDefaults(FORMATS.link);
|
|
1069
|
+
const isURL = selectedText && selectedText.match(/^https?:\/\//);
|
|
1070
|
+
if (isURL && !options.url) {
|
|
1071
|
+
style.suffix = `](${selectedText})`;
|
|
1072
|
+
style.replaceNext = "";
|
|
1073
|
+
} else if (options.url) {
|
|
1074
|
+
style.suffix = `](${options.url})`;
|
|
1075
|
+
style.replaceNext = "";
|
|
1076
|
+
}
|
|
1077
|
+
if (options.text && !selectedText) {
|
|
1078
|
+
const pos = textarea.selectionStart;
|
|
1079
|
+
textarea.value = textarea.value.slice(0, pos) + options.text + textarea.value.slice(pos);
|
|
1080
|
+
textarea.selectionStart = pos;
|
|
1081
|
+
textarea.selectionEnd = pos + options.text.length;
|
|
1082
|
+
}
|
|
1083
|
+
const result = blockStyle(textarea, style);
|
|
1084
|
+
insertText(textarea, result);
|
|
1085
|
+
}
|
|
1086
|
+
function toggleBulletList(textarea) {
|
|
1087
|
+
if (!textarea || textarea.disabled || textarea.readOnly)
|
|
1088
|
+
return;
|
|
1089
|
+
const style = mergeWithDefaults(FORMATS.bulletList);
|
|
1090
|
+
applyListStyle(textarea, style);
|
|
1091
|
+
}
|
|
1092
|
+
function toggleNumberedList(textarea) {
|
|
1093
|
+
if (!textarea || textarea.disabled || textarea.readOnly)
|
|
1094
|
+
return;
|
|
1095
|
+
const style = mergeWithDefaults(FORMATS.numberedList);
|
|
1096
|
+
applyListStyle(textarea, style);
|
|
1097
|
+
}
|
|
1098
|
+
function toggleQuote(textarea) {
|
|
1099
|
+
if (!textarea || textarea.disabled || textarea.readOnly)
|
|
1100
|
+
return;
|
|
1101
|
+
debugLog("toggleQuote", "Starting");
|
|
1102
|
+
debugSelection(textarea, "Initial");
|
|
1103
|
+
const style = mergeWithDefaults(FORMATS.quote);
|
|
1104
|
+
const result = applyLineOperation(
|
|
1105
|
+
textarea,
|
|
1106
|
+
(ta) => multilineStyle(ta, style),
|
|
1107
|
+
{ prefix: style.prefix }
|
|
1108
|
+
);
|
|
1109
|
+
debugResult(result);
|
|
1110
|
+
insertText(textarea, result);
|
|
1111
|
+
debugSelection(textarea, "Final");
|
|
1112
|
+
}
|
|
1113
|
+
function toggleTaskList(textarea) {
|
|
1114
|
+
if (!textarea || textarea.disabled || textarea.readOnly)
|
|
1115
|
+
return;
|
|
1116
|
+
const style = mergeWithDefaults(FORMATS.taskList);
|
|
1117
|
+
const result = applyLineOperation(
|
|
1118
|
+
textarea,
|
|
1119
|
+
(ta) => multilineStyle(ta, style),
|
|
1120
|
+
{ prefix: style.prefix }
|
|
1121
|
+
);
|
|
1122
|
+
insertText(textarea, result);
|
|
1123
|
+
}
|
|
1124
|
+
function insertHeader(textarea, level = 1, toggle = false) {
|
|
1125
|
+
if (!textarea || textarea.disabled || textarea.readOnly)
|
|
1126
|
+
return;
|
|
1127
|
+
if (level < 1 || level > 6)
|
|
1128
|
+
level = 1;
|
|
1129
|
+
debugLog("insertHeader", `============ START ============`);
|
|
1130
|
+
debugLog("insertHeader", `Level: ${level}, Toggle: ${toggle}`);
|
|
1131
|
+
debugLog("insertHeader", `Initial cursor: ${textarea.selectionStart}-${textarea.selectionEnd}`);
|
|
1132
|
+
const headerKey = `header${level === 1 ? "1" : level}`;
|
|
1133
|
+
const style = mergeWithDefaults(FORMATS[headerKey] || FORMATS.header1);
|
|
1134
|
+
debugLog("insertHeader", `Style prefix: "${style.prefix}"`);
|
|
1135
|
+
const value = textarea.value;
|
|
1136
|
+
const originalStart = textarea.selectionStart;
|
|
1137
|
+
const originalEnd = textarea.selectionEnd;
|
|
1138
|
+
let lineStart = originalStart;
|
|
1139
|
+
while (lineStart > 0 && value[lineStart - 1] !== "\n") {
|
|
1140
|
+
lineStart--;
|
|
1141
|
+
}
|
|
1142
|
+
let lineEnd = originalEnd;
|
|
1143
|
+
while (lineEnd < value.length && value[lineEnd] !== "\n") {
|
|
1144
|
+
lineEnd++;
|
|
1145
|
+
}
|
|
1146
|
+
const currentLineContent = value.slice(lineStart, lineEnd);
|
|
1147
|
+
debugLog("insertHeader", `Current line (before): "${currentLineContent}"`);
|
|
1148
|
+
const existingHeaderMatch = currentLineContent.match(/^(#{1,6})\s*/);
|
|
1149
|
+
const existingLevel = existingHeaderMatch ? existingHeaderMatch[1].length : 0;
|
|
1150
|
+
const existingPrefixLength = existingHeaderMatch ? existingHeaderMatch[0].length : 0;
|
|
1151
|
+
debugLog("insertHeader", `Existing header check:`);
|
|
1152
|
+
debugLog("insertHeader", ` - Match: ${existingHeaderMatch ? `"${existingHeaderMatch[0]}"` : "none"}`);
|
|
1153
|
+
debugLog("insertHeader", ` - Existing level: ${existingLevel}`);
|
|
1154
|
+
debugLog("insertHeader", ` - Existing prefix length: ${existingPrefixLength}`);
|
|
1155
|
+
debugLog("insertHeader", ` - Target level: ${level}`);
|
|
1156
|
+
const shouldToggleOff = toggle && existingLevel === level;
|
|
1157
|
+
debugLog("insertHeader", `Should toggle OFF: ${shouldToggleOff} (toggle=${toggle}, existingLevel=${existingLevel}, level=${level})`);
|
|
1158
|
+
const result = applyLineOperation(
|
|
1159
|
+
textarea,
|
|
1160
|
+
(ta) => {
|
|
1161
|
+
const currentLine = ta.value.slice(ta.selectionStart, ta.selectionEnd);
|
|
1162
|
+
debugLog("insertHeader", `Line in operation: "${currentLine}"`);
|
|
1163
|
+
const cleanedLine = currentLine.replace(/^#{1,6}\s*/, "");
|
|
1164
|
+
debugLog("insertHeader", `Cleaned line: "${cleanedLine}"`);
|
|
1165
|
+
let newLine;
|
|
1166
|
+
if (shouldToggleOff) {
|
|
1167
|
+
debugLog("insertHeader", "ACTION: Toggling OFF - removing header");
|
|
1168
|
+
newLine = cleanedLine;
|
|
1169
|
+
} else if (existingLevel > 0) {
|
|
1170
|
+
debugLog("insertHeader", `ACTION: Replacing H${existingLevel} with H${level}`);
|
|
1171
|
+
newLine = style.prefix + cleanedLine;
|
|
1349
1172
|
} else {
|
|
1350
|
-
|
|
1173
|
+
debugLog("insertHeader", "ACTION: Adding new header");
|
|
1174
|
+
newLine = style.prefix + cleanedLine;
|
|
1175
|
+
}
|
|
1176
|
+
debugLog("insertHeader", `New line: "${newLine}"`);
|
|
1177
|
+
return {
|
|
1178
|
+
text: newLine,
|
|
1179
|
+
selectionStart: ta.selectionStart,
|
|
1180
|
+
selectionEnd: ta.selectionEnd
|
|
1181
|
+
};
|
|
1182
|
+
},
|
|
1183
|
+
{
|
|
1184
|
+
prefix: style.prefix,
|
|
1185
|
+
// Custom selection adjustment for headers
|
|
1186
|
+
adjustSelection: (isRemoving, selStart, selEnd, lineStartPos) => {
|
|
1187
|
+
debugLog("insertHeader", `Adjusting selection:`);
|
|
1188
|
+
debugLog("insertHeader", ` - isRemoving param: ${isRemoving}`);
|
|
1189
|
+
debugLog("insertHeader", ` - shouldToggleOff: ${shouldToggleOff}`);
|
|
1190
|
+
debugLog("insertHeader", ` - selStart: ${selStart}, selEnd: ${selEnd}`);
|
|
1191
|
+
debugLog("insertHeader", ` - lineStartPos: ${lineStartPos}`);
|
|
1192
|
+
if (shouldToggleOff) {
|
|
1193
|
+
const adjustment = Math.max(selStart - existingPrefixLength, lineStartPos);
|
|
1194
|
+
debugLog("insertHeader", ` - Removing header, adjusting by -${existingPrefixLength}`);
|
|
1195
|
+
return {
|
|
1196
|
+
start: adjustment,
|
|
1197
|
+
end: selStart === selEnd ? adjustment : Math.max(selEnd - existingPrefixLength, lineStartPos)
|
|
1198
|
+
};
|
|
1199
|
+
} else if (existingPrefixLength > 0) {
|
|
1200
|
+
const prefixDiff = style.prefix.length - existingPrefixLength;
|
|
1201
|
+
debugLog("insertHeader", ` - Replacing header, adjusting by ${prefixDiff}`);
|
|
1202
|
+
return {
|
|
1203
|
+
start: selStart + prefixDiff,
|
|
1204
|
+
end: selEnd + prefixDiff
|
|
1205
|
+
};
|
|
1206
|
+
} else {
|
|
1207
|
+
debugLog("insertHeader", ` - Adding header, adjusting by +${style.prefix.length}`);
|
|
1208
|
+
return {
|
|
1209
|
+
start: selStart + style.prefix.length,
|
|
1210
|
+
end: selEnd + style.prefix.length
|
|
1211
|
+
};
|
|
1212
|
+
}
|
|
1351
1213
|
}
|
|
1352
|
-
}
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
getActiveFormats: getActiveFormats22,
|
|
1371
|
-
hasFormat: hasFormat2,
|
|
1372
|
-
expandSelection: expandSelection2,
|
|
1373
|
-
applyCustomFormat,
|
|
1374
|
-
preserveSelection,
|
|
1375
|
-
setUndoMethod,
|
|
1376
|
-
setDebugMode,
|
|
1377
|
-
getDebugMode
|
|
1378
|
-
};
|
|
1379
|
-
return __toCommonJS2(src_exports);
|
|
1380
|
-
})();
|
|
1214
|
+
}
|
|
1215
|
+
);
|
|
1216
|
+
debugLog("insertHeader", `Final result: text="${result.text}", cursor=${result.selectionStart}-${result.selectionEnd}`);
|
|
1217
|
+
debugLog("insertHeader", `============ END ============`);
|
|
1218
|
+
insertText(textarea, result);
|
|
1219
|
+
}
|
|
1220
|
+
function toggleH1(textarea) {
|
|
1221
|
+
insertHeader(textarea, 1, true);
|
|
1222
|
+
}
|
|
1223
|
+
function toggleH2(textarea) {
|
|
1224
|
+
insertHeader(textarea, 2, true);
|
|
1225
|
+
}
|
|
1226
|
+
function toggleH3(textarea) {
|
|
1227
|
+
insertHeader(textarea, 3, true);
|
|
1228
|
+
}
|
|
1229
|
+
function getActiveFormats2(textarea) {
|
|
1230
|
+
return getActiveFormats(textarea);
|
|
1231
|
+
}
|
|
1381
1232
|
|
|
1382
1233
|
// src/shortcuts.js
|
|
1383
1234
|
var ShortcutsManager = class {
|
|
@@ -1446,19 +1297,19 @@ var ShortcutsManager = class {
|
|
|
1446
1297
|
try {
|
|
1447
1298
|
switch (action) {
|
|
1448
1299
|
case "toggleBold":
|
|
1449
|
-
(
|
|
1300
|
+
toggleBold(textarea);
|
|
1450
1301
|
break;
|
|
1451
1302
|
case "toggleItalic":
|
|
1452
|
-
(
|
|
1303
|
+
toggleItalic(textarea);
|
|
1453
1304
|
break;
|
|
1454
1305
|
case "insertLink":
|
|
1455
|
-
(
|
|
1306
|
+
insertLink(textarea);
|
|
1456
1307
|
break;
|
|
1457
1308
|
case "toggleBulletList":
|
|
1458
|
-
(
|
|
1309
|
+
toggleBulletList(textarea);
|
|
1459
1310
|
break;
|
|
1460
1311
|
case "toggleNumberedList":
|
|
1461
|
-
(
|
|
1312
|
+
toggleNumberedList(textarea);
|
|
1462
1313
|
break;
|
|
1463
1314
|
}
|
|
1464
1315
|
textarea.dispatchEvent(new Event("input", { bubbles: true }));
|
|
@@ -2546,37 +2397,37 @@ var Toolbar = class {
|
|
|
2546
2397
|
try {
|
|
2547
2398
|
switch (action) {
|
|
2548
2399
|
case "toggleBold":
|
|
2549
|
-
(
|
|
2400
|
+
toggleBold(textarea);
|
|
2550
2401
|
break;
|
|
2551
2402
|
case "toggleItalic":
|
|
2552
|
-
(
|
|
2403
|
+
toggleItalic(textarea);
|
|
2553
2404
|
break;
|
|
2554
2405
|
case "insertH1":
|
|
2555
|
-
(
|
|
2406
|
+
toggleH1(textarea);
|
|
2556
2407
|
break;
|
|
2557
2408
|
case "insertH2":
|
|
2558
|
-
(
|
|
2409
|
+
toggleH2(textarea);
|
|
2559
2410
|
break;
|
|
2560
2411
|
case "insertH3":
|
|
2561
|
-
(
|
|
2412
|
+
toggleH3(textarea);
|
|
2562
2413
|
break;
|
|
2563
2414
|
case "insertLink":
|
|
2564
|
-
(
|
|
2415
|
+
insertLink(textarea);
|
|
2565
2416
|
break;
|
|
2566
2417
|
case "toggleCode":
|
|
2567
|
-
(
|
|
2418
|
+
toggleCode(textarea);
|
|
2568
2419
|
break;
|
|
2569
2420
|
case "toggleBulletList":
|
|
2570
|
-
(
|
|
2421
|
+
toggleBulletList(textarea);
|
|
2571
2422
|
break;
|
|
2572
2423
|
case "toggleNumberedList":
|
|
2573
|
-
(
|
|
2424
|
+
toggleNumberedList(textarea);
|
|
2574
2425
|
break;
|
|
2575
2426
|
case "toggleQuote":
|
|
2576
|
-
(
|
|
2427
|
+
toggleQuote(textarea);
|
|
2577
2428
|
break;
|
|
2578
2429
|
case "toggleTaskList":
|
|
2579
|
-
(
|
|
2430
|
+
toggleTaskList(textarea);
|
|
2580
2431
|
break;
|
|
2581
2432
|
case "toggle-plain":
|
|
2582
2433
|
const isPlain = this.editor.container.classList.contains("plain-mode");
|
|
@@ -2596,7 +2447,7 @@ var Toolbar = class {
|
|
|
2596
2447
|
if (!textarea)
|
|
2597
2448
|
return;
|
|
2598
2449
|
try {
|
|
2599
|
-
const activeFormats = (
|
|
2450
|
+
const activeFormats = getActiveFormats2(textarea);
|
|
2600
2451
|
Object.entries(this.buttons).forEach(([name, button]) => {
|
|
2601
2452
|
let isActive = false;
|
|
2602
2453
|
switch (name) {
|
|
@@ -3272,21 +3123,35 @@ var _OverType = class _OverType {
|
|
|
3272
3123
|
const after = value.substring(end);
|
|
3273
3124
|
const lines = selection.split("\n");
|
|
3274
3125
|
const outdented = lines.map((line) => line.replace(/^ /, "")).join("\n");
|
|
3275
|
-
|
|
3276
|
-
|
|
3277
|
-
|
|
3126
|
+
if (document.execCommand) {
|
|
3127
|
+
this.textarea.setSelectionRange(start, end);
|
|
3128
|
+
document.execCommand("insertText", false, outdented);
|
|
3129
|
+
} else {
|
|
3130
|
+
this.textarea.value = before + outdented + after;
|
|
3131
|
+
this.textarea.selectionStart = start;
|
|
3132
|
+
this.textarea.selectionEnd = start + outdented.length;
|
|
3133
|
+
}
|
|
3278
3134
|
} else if (start !== end) {
|
|
3279
3135
|
const before = value.substring(0, start);
|
|
3280
3136
|
const selection = value.substring(start, end);
|
|
3281
3137
|
const after = value.substring(end);
|
|
3282
3138
|
const lines = selection.split("\n");
|
|
3283
3139
|
const indented = lines.map((line) => " " + line).join("\n");
|
|
3284
|
-
|
|
3285
|
-
|
|
3286
|
-
|
|
3140
|
+
if (document.execCommand) {
|
|
3141
|
+
this.textarea.setSelectionRange(start, end);
|
|
3142
|
+
document.execCommand("insertText", false, indented);
|
|
3143
|
+
} else {
|
|
3144
|
+
this.textarea.value = before + indented + after;
|
|
3145
|
+
this.textarea.selectionStart = start;
|
|
3146
|
+
this.textarea.selectionEnd = start + indented.length;
|
|
3147
|
+
}
|
|
3287
3148
|
} else {
|
|
3288
|
-
|
|
3289
|
-
|
|
3149
|
+
if (document.execCommand) {
|
|
3150
|
+
document.execCommand("insertText", false, " ");
|
|
3151
|
+
} else {
|
|
3152
|
+
this.textarea.value = value.substring(0, start) + " " + value.substring(end);
|
|
3153
|
+
this.textarea.selectionStart = this.textarea.selectionEnd = start + 2;
|
|
3154
|
+
}
|
|
3290
3155
|
}
|
|
3291
3156
|
this.textarea.dispatchEvent(new Event("input", { bubbles: true }));
|
|
3292
3157
|
return;
|