@worktile/theia 2.4.0 → 2.4.3

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.
Files changed (33) hide show
  1. package/bundles/worktile-theia.umd.js +979 -921
  2. package/bundles/worktile-theia.umd.js.map +1 -1
  3. package/constants/auto-format-rules.d.ts +1 -1
  4. package/esm2015/constants/auto-format-rules.js +3 -2
  5. package/esm2015/editor.component.js +4 -2
  6. package/esm2015/interfaces/auto-format.js +1 -1
  7. package/esm2015/interfaces/editor.js +1 -1
  8. package/esm2015/plugins/autoformat/autoformat.plugin.js +23 -6
  9. package/esm2015/plugins/indent/indent.editor.js +11 -13
  10. package/esm2015/plugins/indent/indent.plugin.js +15 -2
  11. package/esm2015/plugins/indent/on-keydown-indent.js +3 -5
  12. package/esm2015/plugins/index.js +2 -3
  13. package/esm2015/plugins/quick-insert/components/quick-insert.component.js +6 -2
  14. package/esm2015/plugins/quick-insert/components/quick-toolbar/quick-toolbar.component.js +14 -15
  15. package/esm2015/plugins/quick-insert/quick-insert.editor.js +17 -27
  16. package/esm2015/plugins/quick-insert/quick-insert.plugin.js +14 -13
  17. package/esm2015/plugins/table/components/table.component.js +3 -2
  18. package/esm2015/transforms/index.js +3 -2
  19. package/esm2015/transforms/insert-element-next.js +1 -1
  20. package/esm2015/transforms/insert-element-node.js +36 -0
  21. package/fesm2015/worktile-theia.js +1014 -953
  22. package/fesm2015/worktile-theia.js.map +1 -1
  23. package/interfaces/auto-format.d.ts +1 -0
  24. package/interfaces/editor.d.ts +10 -0
  25. package/package.json +1 -1
  26. package/plugins/autoformat/autoformat.plugin.d.ts +1 -2
  27. package/plugins/indent/indent.plugin.d.ts +1 -0
  28. package/plugins/indent/on-keydown-indent.d.ts +1 -1
  29. package/plugins/quick-insert/components/quick-toolbar/quick-toolbar.component.d.ts +3 -4
  30. package/plugins/quick-insert/quick-insert.editor.d.ts +3 -4
  31. package/plugins/table/components/table.component.scss +20 -17
  32. package/transforms/index.d.ts +2 -1
  33. package/transforms/insert-element-node.d.ts +2 -0
@@ -8,14 +8,14 @@ import * as i1 from 'slate-angular';
8
8
  import { BaseTextComponent, BaseElementComponent, AngularEditor, NODE_TO_PARENT, NODE_TO_INDEX, IS_SAFARI, hotkeys, getPlainText as getPlainText$1, hasBlockCard, isCardLeft, FAKE_RIGHT_BLOCK_CARD_OFFSET, ELEMENT_TO_COMPONENT, EDITOR_TO_ELEMENT, isComponentType, withAngular, SlateModule } from 'slate-angular';
9
9
  import { mixinUnsubscribe, MixinBase } from 'ngx-tethys/core';
10
10
  import isHotkey, { isKeyHotkey } from 'is-hotkey';
11
- import { Element as Element$1, Editor, Range, Node, Span, Path, Text, Point, Transforms, Operation, createEditor } from 'slate';
11
+ import { Transforms, Text, Range, Editor, Element as Element$1, Node, Span, Path, Point, Operation, createEditor } from 'slate';
12
12
  import { HistoryEditor, withHistory } from 'slate-history';
13
- import { __rest, __awaiter } from 'tslib';
14
- import * as _lodash from 'lodash';
15
13
  import marked from 'marked';
16
14
  import { TheiaConverter } from '@atinc/selene';
17
15
  import * as i1$3 from 'ngx-tethys/popover';
18
16
  import { ThyPopover } from 'ngx-tethys/popover';
17
+ import { __rest, __awaiter } from 'tslib';
18
+ import * as _lodash from 'lodash';
19
19
  import * as i2 from '@angular/cdk/overlay';
20
20
  import { Overlay, OverlayModule } from '@angular/cdk/overlay';
21
21
  import * as i1$1 from 'ngx-tethys/alert';
@@ -54,7 +54,7 @@ import { ThySharedModule } from 'ngx-tethys/shared';
54
54
  import * as i1$6 from 'ngx-tethys';
55
55
  import { coerceCssPixelValue } from '@angular/cdk/coercion';
56
56
  import { PortalInjector, ComponentPortal } from '@angular/cdk/portal';
57
- import * as i2$3 from 'ngx-tethys/list';
57
+ import * as i1$7 from 'ngx-tethys/list';
58
58
  import { ThyListModule } from 'ngx-tethys/list';
59
59
  import { ThyAutocompleteModule } from 'ngx-tethys/autocomplete';
60
60
  import { ThyAvatarModule } from 'ngx-tethys/avatar';
@@ -522,6 +522,61 @@ function idCreator(length = 5) {
522
522
  return key;
523
523
  }
524
524
 
525
+ const UNDOING = new WeakMap();
526
+ const REDOING = new WeakMap();
527
+ const withTheHistory = (editor) => {
528
+ const { undo, redo } = editor;
529
+ editor.undo = () => {
530
+ UNDOING.set(editor, true);
531
+ undo();
532
+ UNDOING.set(editor, false);
533
+ };
534
+ editor.redo = () => {
535
+ REDOING.set(editor, true);
536
+ redo();
537
+ REDOING.set(editor, false);
538
+ };
539
+ return editor;
540
+ };
541
+ const TheHistoryEditor = {
542
+ isUndoing(editor) {
543
+ return UNDOING.get(editor);
544
+ },
545
+ isRedoing(editor) {
546
+ return REDOING.get(editor);
547
+ }
548
+ };
549
+
550
+ const setMarks = (editor, marks, at) => {
551
+ Transforms.setNodes(editor, marks, {
552
+ at,
553
+ match: Text.isText,
554
+ split: true
555
+ });
556
+ };
557
+
558
+ const clearMarks = (editor) => {
559
+ const { selection } = editor;
560
+ if (!selection) {
561
+ return;
562
+ }
563
+ if (Range.isCollapsed(selection)) {
564
+ const marks = Editor.marks(editor);
565
+ for (const key in marks) {
566
+ Editor.removeMark(editor, key);
567
+ }
568
+ }
569
+ else {
570
+ const unsetMarks = {};
571
+ MarkProps.forEach(key => {
572
+ unsetMarks[key] = null;
573
+ });
574
+ setMarks(editor, unsetMarks);
575
+ }
576
+ };
577
+
578
+ const insertElement = (editor, element) => editor.insertElement(element);
579
+
525
580
  const isAncestor = (node) => Element$1.isElement(node) || Editor.isEditor(node);
526
581
 
527
582
  const getLastChild$1 = (node, level) => {
@@ -1321,36 +1376,6 @@ var index$1 = /*#__PURE__*/Object.freeze({
1321
1376
  someNode: someNode
1322
1377
  });
1323
1378
 
1324
- const setMarks = (editor, marks, at) => {
1325
- Transforms.setNodes(editor, marks, {
1326
- at,
1327
- match: Text.isText,
1328
- split: true
1329
- });
1330
- };
1331
-
1332
- const clearMarks = (editor) => {
1333
- const { selection } = editor;
1334
- if (!selection) {
1335
- return;
1336
- }
1337
- if (Range.isCollapsed(selection)) {
1338
- const marks = Editor.marks(editor);
1339
- for (const key in marks) {
1340
- Editor.removeMark(editor, key);
1341
- }
1342
- }
1343
- else {
1344
- const unsetMarks = {};
1345
- MarkProps.forEach(key => {
1346
- unsetMarks[key] = null;
1347
- });
1348
- setMarks(editor, unsetMarks);
1349
- }
1350
- };
1351
-
1352
- const insertElement = (editor, element) => editor.insertElement(element);
1353
-
1354
1379
  const insertElementNext = (editor, node) => {
1355
1380
  if (Range.isExpanded(editor.selection)) {
1356
1381
  Editor.deleteFragment(editor);
@@ -1564,6 +1589,40 @@ function handleContinualInsertBreak(editor, lowestBlock, type) {
1564
1589
  return false;
1565
1590
  }
1566
1591
 
1592
+ const insertElementNode = (editor, node) => {
1593
+ if (Range.isExpanded(editor.selection)) {
1594
+ Editor.deleteFragment(editor);
1595
+ }
1596
+ const isBlockCardCursor$1 = isBlockCardCursor(editor);
1597
+ const containerBlocks = getContainerBlocks(editor);
1598
+ const isContainer = isNodeTypeIn(editor, containerBlocks, { at: editor.selection });
1599
+ const [anchorBlock, anchorBlockPath] = anchorBlockEntry(editor);
1600
+ const isEmpty = Editor.isEmpty(editor, anchorBlock);
1601
+ if (isContainer && !isBlockCardCursor$1) {
1602
+ const [, containerPath] = Editor.above(editor, {
1603
+ match: n => Editor.isBlock(editor, n) && containerBlocks.includes(n.type),
1604
+ at: editor.selection
1605
+ });
1606
+ Editor.withoutNormalizing(editor, () => {
1607
+ const containerPathFirstPath = anchorBlockPath.slice(0, containerPath.length + 1);
1608
+ Transforms.insertNodes(editor, node, { at: Path.next(containerPathFirstPath), select: true });
1609
+ if (isEmpty) {
1610
+ Transforms.removeNodes(editor, { at: anchorBlockPath });
1611
+ }
1612
+ });
1613
+ return;
1614
+ }
1615
+ const nextPath = Path.next([anchorBlockPath[0]]);
1616
+ Transforms.insertNodes(editor, node, { at: nextPath });
1617
+ if (isEmpty && anchorBlockPath.length === 1) {
1618
+ Transforms.delete(editor, { at: anchorBlockPath });
1619
+ Transforms.select(editor, Editor.start(editor, anchorBlockPath));
1620
+ }
1621
+ else {
1622
+ Transforms.select(editor, Editor.start(editor, nextPath));
1623
+ }
1624
+ };
1625
+
1567
1626
  var index = /*#__PURE__*/Object.freeze({
1568
1627
  __proto__: null,
1569
1628
  setMarks: setMarks,
@@ -1583,442 +1642,23 @@ var index = /*#__PURE__*/Object.freeze({
1583
1642
  setEndSelection: setEndSelection,
1584
1643
  closeConversionHint: closeConversionHint,
1585
1644
  handleContinualDeleteBackward: handleContinualDeleteBackward,
1586
- handleContinualInsertBreak: handleContinualInsertBreak
1645
+ handleContinualInsertBreak: handleContinualInsertBreak,
1646
+ insertElementNode: insertElementNode
1587
1647
  });
1588
1648
 
1589
- const isNodeTypeList = (n) => {
1590
- return [ElementKinds.bulletedList, ElementKinds.numberedList].includes(n.type);
1591
- };
1592
-
1593
- const ListEditor = {
1594
- isList(editor, element, type) {
1595
- return Editor.isBlock(editor, element) && element.type === type;
1596
- },
1597
- toggleList(editor, type, startIndex) {
1598
- if (!editor.selection) {
1599
- return;
1600
- }
1601
- if (!startIndex) {
1602
- startIndex = 1;
1603
- }
1604
- const types = [ElementKinds.bulletedList, ElementKinds.numberedList];
1605
- Editor.withoutNormalizing(editor, () => {
1606
- const [...listItems] = Editor.nodes(editor, {
1607
- match: node => Element$1.isElement(node) && node.type === ElementKinds.listItem,
1608
- mode: 'lowest'
1609
- });
1610
- const firstListItemPath = listItems.length && listItems[0][1];
1611
- const activeListPath = listItems.length && Path.parent(firstListItemPath);
1612
- const activeListNode = listItems.length && Node.get(editor, activeListPath);
1613
- // 同级且类型相同:unwrap
1614
- const isLowestActive = listItems.length &&
1615
- listItems.every(([, path]) => activeListNode.type === type && (Path.isSibling(firstListItemPath, path) || Path.equals(firstListItemPath, path)));
1616
- if (isLowestActive) {
1617
- const upListItem = Path.parent(activeListPath);
1618
- Transforms.unwrapNodes(editor, {
1619
- at: editor.selection,
1620
- match: node => node === activeListNode,
1621
- split: true,
1622
- mode: 'lowest'
1623
- });
1624
- if (upListItem && Node.get(editor, upListItem).type === ElementKinds.listItem) {
1625
- Transforms.moveNodes(editor, {
1626
- at: editor.selection,
1627
- to: Path.next(upListItem),
1628
- match: node => Element$1.isElement(node) && node.type === ElementKinds.listItem
1629
- });
1630
- }
1631
- else {
1632
- Transforms.unwrapNodes(editor, {
1633
- match: node => Element$1.isElement(node) && node.type === ElementKinds.listItem
1634
- });
1635
- }
1636
- return;
1637
- }
1638
- // 跨级、同级且类型不同
1639
- if (activeListNode && types.includes(activeListNode.type)) {
1640
- Transforms.setNodes(editor, { type }, { match: node => Element$1.isElement(node) && node.type !== type && types.includes(node.type) });
1641
- return;
1642
- }
1643
- // wrap
1644
- this.buildListItem(editor);
1645
- // Todo: types
1646
- Transforms.wrapNodes(editor, { type, children: [], start: startIndex }, {
1647
- at: editor.selection,
1648
- match: node => Element$1.isElement(node) && node.type === ElementKinds.listItem
1649
- });
1650
- });
1651
- },
1652
- unwrapList(editor) {
1653
- Editor.withoutNormalizing(editor, () => {
1654
- unwrapNodesByType(editor, [ElementKinds.bulletedList, ElementKinds.numberedList], { split: true, mode: 'all' });
1655
- unwrapNodesByType(editor, [ElementKinds.listItem], { split: true, mode: 'all' });
1656
- });
1657
- },
1658
- wrapList(editor, type) {
1659
- Editor.withoutNormalizing(editor, () => {
1660
- const listItem = {
1661
- type: ElementKinds.listItem,
1662
- children: []
1663
- };
1664
- const list = {
1665
- type,
1666
- children: []
1667
- };
1668
- Transforms.wrapNodes(editor, list, { split: true });
1669
- Transforms.wrapNodes(editor, listItem, { split: true });
1670
- });
1671
- },
1672
- isActive(editor, type) {
1673
- const [match] = getNodesByType(editor, type);
1674
- return !!match;
1675
- },
1676
- getActiveList(editor) {
1677
- const [match] = getNodesByType(editor, LIST_BLOCK_TYPES);
1678
- return match;
1679
- },
1680
- buildListItem(editor) {
1681
- const nodes = Editor.nodes(editor, {
1682
- match: node => Editor.isBlock(editor, node),
1683
- mode: 'lowest'
1684
- });
1685
- for (const [node, path] of nodes) {
1686
- if (!Editor.isVoid(editor, node) && Element$1.isElement(node) && node.type !== ElementKinds.paragraph) {
1687
- Transforms.setNodes(editor, { type: ElementKinds.paragraph, checked: undefined }, // todo remove checked
1688
- { at: path });
1689
- }
1690
- else if (Element$1.isElement(node) && node.type === ElementKinds.paragraph) {
1691
- let { textIndent } = node;
1692
- if (textIndent) {
1693
- Transforms.setNodes(editor, { textIndent: undefined, indent: undefined }, // remove indent
1694
- { at: path });
1695
- }
1696
- }
1697
- if (Node.parent(editor, path).type !== ElementKinds.listItem) {
1698
- Transforms.wrapNodes(editor, { type: ElementKinds.listItem, children: [] }, {
1699
- at: path,
1700
- split: true
1701
- });
1702
- }
1703
- }
1704
- },
1705
- buildInsertDataChildren(node) {
1706
- const { children } = node;
1707
- const listItem = children[0];
1708
- if (isNodeTypeList(node) && Element$1.isElement(listItem) && listItem.children[0].type === ElementKinds.paragraph) {
1709
- return node;
1649
+ class TheConversionHintComponent {
1650
+ constructor() {
1651
+ this.duration = 10000;
1652
+ this.pauseOnHover = true;
1653
+ }
1654
+ mouseenter() {
1655
+ if (this.pauseOnHover) {
1656
+ this.clearCloseTimer();
1710
1657
  }
1711
- return this.buildInsertDataChildren(listItem);
1712
1658
  }
1713
- };
1714
-
1715
- const TodoItemEditor = {
1716
- isActive(editor) {
1717
- const [match] = getNodesByType(editor, ElementKinds.checkItem);
1718
- return !!match;
1719
- },
1720
- insertTodoItem(editor) {
1721
- if (!editor.selection) {
1722
- return;
1723
- }
1724
- const isActive = this.isActive(editor);
1725
- const isNumberedList = ListEditor.isActive(editor, ElementKinds.numberedList);
1726
- const isBulletedList = ListEditor.isActive(editor, ElementKinds.bulletedList);
1727
- if (isActive) {
1728
- Transforms.setNodes(editor, {
1729
- type: ElementKinds.paragraph
1730
- });
1731
- }
1732
- else {
1733
- if (isNumberedList || isBulletedList) {
1734
- ListEditor.unwrapList(editor);
1735
- }
1736
- Transforms.setNodes(editor, {
1737
- type: ElementKinds.checkItem
1738
- });
1739
- }
1740
- }
1741
- };
1742
-
1743
- const BlockquoteEditor = {
1744
- toggleBlockquote(editor) {
1745
- if (!isParagraph(editor)) {
1746
- Transforms.insertNodes(editor, {
1747
- type: ElementKinds.paragraph,
1748
- mode: 'text',
1749
- children: [
1750
- {
1751
- text: ''
1752
- }
1753
- ]
1754
- });
1755
- }
1756
- const isActive = isBlockActive(editor, ElementKinds.blockquote);
1757
- if (!isActive) {
1758
- Transforms.wrapNodes(editor, { type: ElementKinds.blockquote, children: [] }, {
1759
- mode: 'lowest'
1760
- });
1761
- }
1762
- else {
1763
- Transforms.unwrapNodes(editor, { match: n => Element$1.isElement(n) && n.type === ElementKinds.blockquote });
1764
- }
1765
- }
1766
- };
1767
-
1768
- const InlineCodeEditor = {
1769
- toggleInlineCode(editor, text) {
1770
- const isActive = InlineCodeEditor.isInlineCodeActive(editor);
1771
- if (isActive) {
1772
- InlineCodeEditor.unwrapInlineCode(editor);
1773
- return;
1774
- }
1775
- if (Range.isCollapsed(editor.selection)) {
1776
- InlineCodeEditor.wrapInlineCode(editor, text);
1777
- }
1778
- else {
1779
- const fragment = Node.fragment(editor, editor.selection)[0];
1780
- const selectNode = Node.get(fragment, []);
1781
- const selectText = Node.string(selectNode);
1782
- InlineCodeEditor.wrapInlineCode(editor, selectText);
1783
- }
1784
- },
1785
- wrapInlineCode(editor, text = '') {
1786
- if (InlineCodeEditor.isInlineCodeActive(editor)) {
1787
- InlineCodeEditor.unwrapInlineCode(editor);
1788
- }
1789
- const { selection } = editor;
1790
- const isCollapsed = selection && Range.isCollapsed(selection);
1791
- const inlineCode = {
1792
- type: ElementKinds.inlineCode,
1793
- children: isCollapsed ? [{ text: text ? text : ZERO_WIDTH_CHAR }] : []
1794
- };
1795
- if (isCollapsed) {
1796
- Transforms.insertNodes(editor, inlineCode);
1797
- }
1798
- else {
1799
- Transforms.wrapNodes(editor, inlineCode, { split: true });
1800
- }
1801
- },
1802
- unwrapInlineCode(editor) {
1803
- Transforms.unwrapNodes(editor, { match: n => Element$1.isElement(n) && n.type === ElementKinds.inlineCode });
1804
- },
1805
- isInlineCodeActive(editor, path) {
1806
- var _a;
1807
- const [inlineCode] = Editor.nodes(editor, {
1808
- at: path ? path : (_a = editor.selection) === null || _a === void 0 ? void 0 : _a.anchor.path,
1809
- match: n => Element$1.isElement(n) && n.type === ElementKinds.inlineCode
1810
- });
1811
- return !!inlineCode;
1812
- }
1813
- };
1814
-
1815
- const HeadingEditor = {
1816
- setHeading(editor, heading) {
1817
- Editor.withoutNormalizing(editor, () => {
1818
- const types = [ElementKinds.bulletedList, ElementKinds.numberedList, ElementKinds.listItem];
1819
- Transforms.unwrapNodes(editor, {
1820
- at: editor.selection,
1821
- match: n => Element$1.isElement(n) && types.includes(n.type),
1822
- mode: 'all',
1823
- split: true
1824
- });
1825
- Transforms.setNodes(editor, { type: heading });
1826
- const entry = anchorBlockEntry(editor);
1827
- const unMarks = {
1828
- [MarkTypes.fontSize]: null
1829
- };
1830
- if (entry) {
1831
- setMarks(editor, unMarks, entry[1]);
1832
- return;
1833
- }
1834
- setMarks(editor, unMarks, editor.selection);
1835
- });
1836
- },
1837
- isHeadingActive(editor, heading) {
1838
- const [match] = Editor.nodes(editor, {
1839
- match: n => Element$1.isElement(n) && n.type === heading,
1840
- universal: true
1841
- });
1842
- return !!match;
1843
- }
1844
- };
1845
-
1846
- const autoFormatRules = [
1847
- {
1848
- type: ElementKinds.heading_1,
1849
- markup: '#',
1850
- format: (editor) => {
1851
- HeadingEditor.setHeading(editor, ElementKinds.heading_1);
1852
- }
1853
- },
1854
- {
1855
- type: ElementKinds.heading_2,
1856
- markup: '##',
1857
- format: (editor) => {
1858
- HeadingEditor.setHeading(editor, ElementKinds.heading_2);
1859
- }
1860
- },
1861
- {
1862
- type: ElementKinds.heading_3,
1863
- markup: '###',
1864
- format: (editor) => {
1865
- HeadingEditor.setHeading(editor, ElementKinds.heading_3);
1866
- }
1867
- },
1868
- {
1869
- type: ElementKinds.heading_4,
1870
- markup: '####',
1871
- format: (editor) => {
1872
- HeadingEditor.setHeading(editor, ElementKinds.heading_4);
1873
- }
1874
- },
1875
- {
1876
- type: ElementKinds.heading_5,
1877
- markup: '#####',
1878
- format: (editor) => {
1879
- HeadingEditor.setHeading(editor, ElementKinds.heading_5);
1880
- }
1881
- },
1882
- {
1883
- type: ElementKinds.heading_6,
1884
- markup: '######',
1885
- format: (editor) => {
1886
- HeadingEditor.setHeading(editor, ElementKinds.heading_6);
1887
- }
1888
- },
1889
- {
1890
- type: ElementKinds.blockquote,
1891
- markup: ['>'],
1892
- format: (editor) => {
1893
- BlockquoteEditor.toggleBlockquote(editor);
1894
- }
1895
- },
1896
- {
1897
- type: MarkTypes.bold,
1898
- between: ['**', '**'],
1899
- mode: 'inline',
1900
- insertTrigger: true
1901
- },
1902
- {
1903
- type: MarkTypes.bold,
1904
- between: ['__', '__'],
1905
- mode: 'inline',
1906
- insertTrigger: true
1907
- },
1908
- {
1909
- type: MarkTypes.italic,
1910
- between: ['*', '*'],
1911
- mode: 'inline',
1912
- insertTrigger: true
1913
- },
1914
- {
1915
- type: MarkTypes.italic,
1916
- between: ['_', '_'],
1917
- mode: 'inline',
1918
- insertTrigger: true
1919
- },
1920
- {
1921
- type: ElementKinds.inlineCode,
1922
- between: ['`', '`'],
1923
- mode: 'inline',
1924
- format: (editor, text) => {
1925
- InlineCodeEditor.toggleInlineCode(editor, text);
1926
- Transforms.select(editor, Editor.after(editor, editor.selection));
1927
- }
1928
- },
1929
- {
1930
- type: MarkTypes.strike,
1931
- between: ['~~', '~~'],
1932
- mode: 'inline',
1933
- insertTrigger: true
1934
- },
1935
- {
1936
- type: ElementKinds.code,
1937
- markup: '```',
1938
- insertTrigger: true
1939
- },
1940
- {
1941
- type: ElementKinds.listItem,
1942
- markup: [],
1943
- match: (editor) => {
1944
- return isParagraph(editor) ? ['*', '-', '+'] : [];
1945
- },
1946
- format: (editor) => {
1947
- ListEditor.toggleList(editor, ElementKinds.bulletedList);
1948
- }
1949
- },
1950
- {
1951
- type: ElementKinds.listItem,
1952
- markup: [],
1953
- match: (editor, textFromBlockStart) => {
1954
- return isParagraph(editor) && /^-?\d+(\.|\))$/.test(textFromBlockStart) ? [textFromBlockStart] : [];
1955
- },
1956
- format: (editor, markup) => {
1957
- let startIndex = 1;
1958
- if (markup) {
1959
- startIndex = markup[0].split('.')[0];
1960
- if (startIndex === 0) {
1961
- startIndex = 1;
1962
- }
1963
- }
1964
- ListEditor.toggleList(editor, ElementKinds.numberedList, startIndex);
1965
- }
1966
- },
1967
- {
1968
- type: ElementKinds.checkItem,
1969
- markup: [],
1970
- match: (editor) => {
1971
- return isParagraph(editor) ? ['[]'] : [];
1972
- },
1973
- format: (editor) => {
1974
- TodoItemEditor.insertTodoItem(editor);
1975
- }
1976
- },
1977
- {
1978
- type: ElementKinds.hr,
1979
- markup: '---',
1980
- insertTrigger: true
1981
- }
1982
- ];
1983
-
1984
- const UNDOING = new WeakMap();
1985
- const REDOING = new WeakMap();
1986
- const withTheHistory = (editor) => {
1987
- const { undo, redo } = editor;
1988
- editor.undo = () => {
1989
- UNDOING.set(editor, true);
1990
- undo();
1991
- UNDOING.set(editor, false);
1992
- };
1993
- editor.redo = () => {
1994
- REDOING.set(editor, true);
1995
- redo();
1996
- REDOING.set(editor, false);
1997
- };
1998
- return editor;
1999
- };
2000
- const TheHistoryEditor = {
2001
- isUndoing(editor) {
2002
- return UNDOING.get(editor);
2003
- },
2004
- isRedoing(editor) {
2005
- return REDOING.get(editor);
2006
- }
2007
- };
2008
-
2009
- class TheConversionHintComponent {
2010
- constructor() {
2011
- this.duration = 10000;
2012
- this.pauseOnHover = true;
2013
- }
2014
- mouseenter() {
2015
- if (this.pauseOnHover) {
2016
- this.clearCloseTimer();
2017
- }
2018
- }
2019
- mouseleave() {
2020
- if (this.pauseOnHover) {
2021
- this.creatCloseTimer();
1659
+ mouseleave() {
1660
+ if (this.pauseOnHover) {
1661
+ this.creatCloseTimer();
2022
1662
  }
2023
1663
  }
2024
1664
  ngOnInit() {
@@ -3053,6 +2693,10 @@ const hasStableListItem = (listItemNode) => {
3053
2693
  return listItemNode.children.length === 1 && type === ElementKinds.paragraph;
3054
2694
  };
3055
2695
 
2696
+ const isNodeTypeList = (n) => {
2697
+ return [ElementKinds.bulletedList, ElementKinds.numberedList].includes(n.type);
2698
+ };
2699
+
3056
2700
  /**
3057
2701
  * list 中 是否是单个listItem,且listItem没有子列表
3058
2702
  */
@@ -3898,432 +3542,829 @@ const withList = ({ validLiChildrenTypes } = {}) => (editor) => {
3898
3542
  return;
3899
3543
  }
3900
3544
  }
3901
- insertData(data);
3545
+ insertData(data);
3546
+ };
3547
+ editor.onKeydown = (event) => {
3548
+ const isContinue = !onKeyDownList(event, editor);
3549
+ if (isContinue) {
3550
+ onKeydown(event);
3551
+ }
3552
+ };
3553
+ editor.normalizeNode = getListNormalizer(editor, { validLiChildrenTypes: validLiChildrenTypes });
3554
+ editor.renderElement = (element) => {
3555
+ if (element.type === ElementKinds.numberedList) {
3556
+ return TheNumberedListComponent;
3557
+ }
3558
+ if (element.type === ElementKinds.bulletedList) {
3559
+ return TheBulletedListComponent;
3560
+ }
3561
+ if (element.type === ElementKinds.listItem) {
3562
+ return TheListItemComponent;
3563
+ }
3564
+ return renderElement(element);
3565
+ };
3566
+ return editor;
3567
+ };
3568
+
3569
+ class TheTodoItemComponent extends TheBaseElementComponent {
3570
+ constructor(elementRef, cdr) {
3571
+ super(elementRef, cdr);
3572
+ this.elementRef = elementRef;
3573
+ this.cdr = cdr;
3574
+ this.checkItemClass = true;
3575
+ }
3576
+ get level() {
3577
+ var _a;
3578
+ return (_a = this.element) === null || _a === void 0 ? void 0 : _a.indent;
3579
+ }
3580
+ ngOnInit() {
3581
+ super.ngOnInit();
3582
+ }
3583
+ onCheck(checked) {
3584
+ if (this.readonly) {
3585
+ return false;
3586
+ }
3587
+ setNode(this.editor, { checked }, this.element);
3588
+ }
3589
+ }
3590
+ TheTodoItemComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: TheTodoItemComponent, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
3591
+ TheTodoItemComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.15", type: TheTodoItemComponent, selector: "div[theTodoItem]", host: { properties: { "class.the-check-item": "this.checkItemClass", "attr.the-level": "this.level" } }, usesInheritance: true, ngImport: i0, template: `
3592
+ <span contenteditable="false" class="todo-item-status">
3593
+ <input #checkbox type="checkbox" [checked]="element.checked" (click)="onCheck(checkbox.checked)" />
3594
+ </span>
3595
+ <span><slate-children [children]="children" [context]="childrenContext" [viewContext]="viewContext"></slate-children></span>
3596
+ `, isInline: true, components: [{ type: i1.SlateChildrenComponent, selector: "slate-children", inputs: ["children", "context", "viewContext"] }] });
3597
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: TheTodoItemComponent, decorators: [{
3598
+ type: Component,
3599
+ args: [{
3600
+ selector: 'div[theTodoItem]',
3601
+ template: `
3602
+ <span contenteditable="false" class="todo-item-status">
3603
+ <input #checkbox type="checkbox" [checked]="element.checked" (click)="onCheck(checkbox.checked)" />
3604
+ </span>
3605
+ <span><slate-children [children]="children" [context]="childrenContext" [viewContext]="viewContext"></slate-children></span>
3606
+ `
3607
+ }]
3608
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { checkItemClass: [{
3609
+ type: HostBinding,
3610
+ args: ['class.the-check-item']
3611
+ }], level: [{
3612
+ type: HostBinding,
3613
+ args: ['attr.the-level']
3614
+ }] } });
3615
+
3616
+ const withTodoItem = (editor) => {
3617
+ const { insertBreak, deleteBackward, renderElement } = editor;
3618
+ editor.insertBreak = () => {
3619
+ const { selection } = editor;
3620
+ if (selection && Range.isCollapsed(selection)) {
3621
+ const [match] = Editor.nodes(editor, {
3622
+ match: n => Element$1.isElement(n) && n.type === ElementKinds.checkItem
3623
+ });
3624
+ if (match) {
3625
+ const [, path] = match;
3626
+ const block = anchorBlock(editor);
3627
+ if (block && Editor.isStart(editor, selection.anchor, path) && Editor.isEmpty(editor, block)) {
3628
+ Transforms.setNodes(editor, {
3629
+ type: ElementKinds.default,
3630
+ checked: undefined
3631
+ }, {
3632
+ match: n => Element$1.isElement(n) && n.type === ElementKinds.checkItem
3633
+ });
3634
+ return;
3635
+ }
3636
+ }
3637
+ }
3638
+ insertBreak();
3639
+ const anchorBlock$1 = anchorBlock(editor);
3640
+ if (anchorBlock$1 && anchorBlock$1.type === ElementKinds.checkItem) {
3641
+ Transforms.setNodes(editor, { checked: false });
3642
+ }
3643
+ };
3644
+ editor.deleteBackward = unit => {
3645
+ const { selection } = editor;
3646
+ if (selection && Range.isCollapsed(selection)) {
3647
+ const [match] = Editor.nodes(editor, {
3648
+ match: n => Element$1.isElement(n) && n.type === ElementKinds.checkItem
3649
+ });
3650
+ if (match) {
3651
+ const [, path] = match;
3652
+ if (Editor.isStart(editor, selection.anchor, path)) {
3653
+ Transforms.setNodes(editor, { type: ElementKinds.default, checked: undefined }, {
3654
+ match: n => Element$1.isElement(n) && n.type === ElementKinds.checkItem
3655
+ });
3656
+ return;
3657
+ }
3658
+ }
3659
+ }
3660
+ deleteBackward(unit);
3661
+ };
3662
+ editor.renderElement = (element) => {
3663
+ if (element.type === ElementKinds.checkItem) {
3664
+ return TheTodoItemComponent;
3665
+ }
3666
+ return renderElement(element);
3667
+ };
3668
+ return editor;
3669
+ };
3670
+
3671
+ class TheHrComponent extends TheBaseElementComponent {
3672
+ constructor(elementRef, cdr) {
3673
+ super(elementRef, cdr);
3674
+ this.elementRef = elementRef;
3675
+ this.cdr = cdr;
3676
+ }
3677
+ ngAfterViewInit() {
3678
+ setTimeout(() => {
3679
+ const blockCardElement = this.nativeElement.closest('slate-block-card');
3680
+ if (blockCardElement) {
3681
+ blockCardElement.classList.add(`slate-block-card-${this.element.type}`);
3682
+ }
3683
+ });
3684
+ }
3685
+ }
3686
+ TheHrComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: TheHrComponent, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
3687
+ TheHrComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.15", type: TheHrComponent, selector: "the-hr, [theHr]", usesInheritance: true, ngImport: i0, template: `
3688
+ <div class="the-hr" contenteditable="false" [ngClass]="{ active: selection }">
3689
+ <hr class="the-hr" />
3690
+ <slate-children [children]="children" [context]="childrenContext" [viewContext]="viewContext"></slate-children>
3691
+ </div>
3692
+ `, isInline: true, components: [{ type: i1.SlateChildrenComponent, selector: "slate-children", inputs: ["children", "context", "viewContext"] }], directives: [{ type: i10.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
3693
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: TheHrComponent, decorators: [{
3694
+ type: Component,
3695
+ args: [{
3696
+ selector: 'the-hr, [theHr]',
3697
+ template: `
3698
+ <div class="the-hr" contenteditable="false" [ngClass]="{ active: selection }">
3699
+ <hr class="the-hr" />
3700
+ <slate-children [children]="children" [context]="childrenContext" [viewContext]="viewContext"></slate-children>
3701
+ </div>
3702
+ `
3703
+ }]
3704
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }]; } });
3705
+
3706
+ const withHr = (editor) => {
3707
+ const { isVoid, isBlockCard, renderElement } = editor;
3708
+ editor.isVoid = (element) => {
3709
+ return element.type === ElementKinds.hr || isVoid(element);
3710
+ };
3711
+ editor.isBlockCard = (element) => {
3712
+ if (element.type === ElementKinds.hr) {
3713
+ return true;
3714
+ }
3715
+ return isBlockCard(element);
3716
+ };
3717
+ editor.renderElement = (element) => {
3718
+ if (element.type === ElementKinds.hr) {
3719
+ return TheHrComponent;
3720
+ }
3721
+ return renderElement(element);
3722
+ };
3723
+ return editor;
3724
+ };
3725
+
3726
+ const withAlign = (editor) => {
3727
+ const { deleteBackward } = editor;
3728
+ editor.deleteBackward = unit => {
3729
+ const { anchor } = editor.selection;
3730
+ const node = anchorBlock(editor);
3731
+ const isVoid = Editor.isVoid(editor, node);
3732
+ const alignTypes = [Alignment.center, Alignment.right];
3733
+ const startLine = Editor.start(editor, anchor.path);
3734
+ const startLineRange = { anchor, focus: startLine };
3735
+ const beforeText = Editor.string(editor, startLineRange);
3736
+ if (!isVoid && node && node.align && alignTypes.includes(node.align) && beforeText === '') {
3737
+ const align = alignTypes.indexOf(node.align) ? Alignment.center : undefined;
3738
+ return Transforms.setNodes(editor, { align });
3739
+ }
3740
+ deleteBackward(unit);
3741
+ };
3742
+ return editor;
3743
+ };
3744
+
3745
+ const withHeading = (editor) => {
3746
+ const { insertBreak } = editor;
3747
+ editor.insertBreak = () => {
3748
+ const { selection } = editor;
3749
+ const anchorBlock = getAnchorBlockEntry(editor);
3750
+ if (anchorBlock && Range.isCollapsed(selection) && anchorBlock[0].type.startsWith('heading')) {
3751
+ if (Editor.isStart(editor, selection.anchor, anchorBlock[1])) {
3752
+ insertBreak();
3753
+ Transforms.setNodes(editor, { type: ElementKinds.paragraph }, {
3754
+ at: selection
3755
+ });
3756
+ return;
3757
+ }
3758
+ if (Editor.isEnd(editor, selection.focus, anchorBlock[1])) {
3759
+ insertBreak();
3760
+ Transforms.setNodes(editor, { type: ElementKinds.paragraph });
3761
+ return;
3762
+ }
3763
+ }
3764
+ insertBreak();
3765
+ };
3766
+ return editor;
3767
+ };
3768
+
3769
+ const withMark = () => (editor) => {
3770
+ const e = editor;
3771
+ e.removeMark = (key, shouldChange = true) => {
3772
+ const { selection } = e;
3773
+ if (selection) {
3774
+ if (Range.isExpanded(selection)) {
3775
+ Transforms.unsetNodes(e, key, {
3776
+ match: Text.isText,
3777
+ split: true
3778
+ });
3779
+ }
3780
+ else {
3781
+ const marks = Object.assign({}, (Editor.marks(e) || {}));
3782
+ delete marks[key];
3783
+ editor.marks = marks;
3784
+ const text = Editor.string(e, selection.anchor.path);
3785
+ if (text !== '') {
3786
+ Editor.setNormalizing(editor, false);
3787
+ e.insertText('');
3788
+ editor.marks = marks;
3789
+ Editor.setNormalizing(editor, true);
3790
+ }
3791
+ else {
3792
+ Transforms.unsetNodes(e, key, { at: selection.anchor.path });
3793
+ }
3794
+ if (shouldChange) {
3795
+ editor.onChange();
3796
+ }
3797
+ }
3798
+ }
3902
3799
  };
3903
- editor.onKeydown = (event) => {
3904
- const isContinue = !onKeyDownList(event, editor);
3905
- if (isContinue) {
3906
- onKeydown(event);
3800
+ e.addMark = (key, value) => {
3801
+ const { selection } = editor;
3802
+ if (selection) {
3803
+ if (Range.isExpanded(selection)) {
3804
+ Transforms.setNodes(e, { [key]: value }, { match: Text.isText, split: true });
3805
+ }
3806
+ else {
3807
+ const marks = Object.assign(Object.assign({}, (Editor.marks(e) || {})), { [key]: value });
3808
+ editor.marks = marks;
3809
+ const text = Editor.string(e, selection.anchor.path);
3810
+ if (text !== '') {
3811
+ Editor.setNormalizing(editor, false);
3812
+ e.insertText('');
3813
+ editor.marks = marks;
3814
+ Editor.setNormalizing(editor, true);
3815
+ }
3816
+ else {
3817
+ Transforms.setNodes(e, { [key]: value }, { at: selection.anchor.path });
3818
+ }
3819
+ }
3907
3820
  }
3908
3821
  };
3909
- editor.normalizeNode = getListNormalizer(editor, { validLiChildrenTypes: validLiChildrenTypes });
3910
- editor.renderElement = (element) => {
3911
- if (element.type === ElementKinds.numberedList) {
3912
- return TheNumberedListComponent;
3822
+ return e;
3823
+ };
3824
+
3825
+ const withNodeID = ({ idKey = 'id', idCreator = () => Date.now(), filterText = true, filter = () => true } = {}) => (e) => {
3826
+ const editor = e;
3827
+ const { apply, getFragment } = editor;
3828
+ const idPropsCreator = () => ({ [idKey]: idCreator() });
3829
+ editor.removedIDs = new Set();
3830
+ editor.apply = (operation) => {
3831
+ if (operation.type === 'insert_node') {
3832
+ const newFilter = (entry) => {
3833
+ const [_node] = entry;
3834
+ return filter(entry) && filterText ? Element$1.isElement(_node) : isDescendant(_node);
3835
+ };
3836
+ // fix can not find path by orign node
3837
+ let node = operation.node;
3838
+ if (!Object.isExtensible(node)) {
3839
+ node = _.cloneDeep(node);
3840
+ }
3841
+ // it will not overwrite ids once it's set as it's read-only
3842
+ mergeDeepToNodes({
3843
+ node,
3844
+ source: idPropsCreator,
3845
+ query: {
3846
+ filter: newFilter,
3847
+ }
3848
+ });
3849
+ return apply(Object.assign(Object.assign({}, operation), { node }));
3913
3850
  }
3914
- if (element.type === ElementKinds.bulletedList) {
3915
- return TheBulletedListComponent;
3851
+ if (operation.type === 'split_node' && (!filterText || operation.properties.type)) {
3852
+ let id = operation.properties[idKey];
3853
+ if (editor.removedIDs.has(id)) {
3854
+ editor.removedIDs.delete(id);
3855
+ }
3856
+ else {
3857
+ id = idCreator();
3858
+ }
3859
+ return apply(Object.assign(Object.assign({}, operation), { properties: Object.assign(Object.assign({}, operation.properties), { [idKey]: id }) }));
3916
3860
  }
3917
- if (element.type === ElementKinds.listItem) {
3918
- return TheListItemComponent;
3861
+ if (operation.type === 'merge_node' && (!filterText || operation.properties.type)) {
3862
+ editor.removedIDs.add(operation.properties[idKey]);
3919
3863
  }
3920
- return renderElement(element);
3864
+ return apply(operation);
3865
+ };
3866
+ editor.getFragment = () => {
3867
+ const fragment = _.cloneDeep(getFragment());
3868
+ return deleteElementKey(fragment, idKey);
3921
3869
  };
3922
3870
  return editor;
3923
3871
  };
3924
3872
 
3925
- class TheTodoItemComponent extends TheBaseElementComponent {
3926
- constructor(elementRef, cdr) {
3927
- super(elementRef, cdr);
3928
- this.elementRef = elementRef;
3929
- this.cdr = cdr;
3930
- this.checkItemClass = true;
3873
+ const autoFormatBlock = (editor, type, at, { preFormat, format }, markups) => {
3874
+ Transforms.delete(editor, { at });
3875
+ if (preFormat) {
3876
+ preFormat(editor);
3931
3877
  }
3932
- get level() {
3933
- var _a;
3934
- return (_a = this.element) === null || _a === void 0 ? void 0 : _a.indent;
3878
+ if (!format) {
3879
+ Transforms.setNodes(editor, { type }, { match: n => Editor.isBlock(editor, n) });
3935
3880
  }
3936
- ngOnInit() {
3937
- super.ngOnInit();
3881
+ else {
3882
+ format(editor, markups);
3938
3883
  }
3939
- onCheck(checked) {
3940
- if (this.readonly) {
3884
+ };
3885
+
3886
+ const autoFormatInline = (editor, { type, between, markup, ignoreTrim, format }) => {
3887
+ const selection = editor.selection;
3888
+ const startMarkup = between ? between[0] : markup;
3889
+ const endMarkup = between ? between[1] : '';
3890
+ let endMarkupPointBefore = selection.anchor;
3891
+ if (endMarkup) {
3892
+ endMarkupPointBefore = getPointBefore(editor, selection, {
3893
+ matchString: endMarkup
3894
+ });
3895
+ if (!endMarkupPointBefore) {
3941
3896
  return false;
3942
3897
  }
3943
- setNode(this.editor, { checked }, this.element);
3944
3898
  }
3945
- }
3946
- TheTodoItemComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: TheTodoItemComponent, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
3947
- TheTodoItemComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.15", type: TheTodoItemComponent, selector: "div[theTodoItem]", host: { properties: { "class.the-check-item": "this.checkItemClass", "attr.the-level": "this.level" } }, usesInheritance: true, ngImport: i0, template: `
3948
- <span contenteditable="false" class="todo-item-status">
3949
- <input #checkbox type="checkbox" [checked]="element.checked" (click)="onCheck(checkbox.checked)" />
3950
- </span>
3951
- <span><slate-children [children]="children" [context]="childrenContext" [viewContext]="viewContext"></slate-children></span>
3952
- `, isInline: true, components: [{ type: i1.SlateChildrenComponent, selector: "slate-children", inputs: ["children", "context", "viewContext"] }] });
3953
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: TheTodoItemComponent, decorators: [{
3954
- type: Component,
3955
- args: [{
3956
- selector: 'div[theTodoItem]',
3957
- template: `
3958
- <span contenteditable="false" class="todo-item-status">
3959
- <input #checkbox type="checkbox" [checked]="element.checked" (click)="onCheck(checkbox.checked)" />
3960
- </span>
3961
- <span><slate-children [children]="children" [context]="childrenContext" [viewContext]="viewContext"></slate-children></span>
3962
- `
3963
- }]
3964
- }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { checkItemClass: [{
3965
- type: HostBinding,
3966
- args: ['class.the-check-item']
3967
- }], level: [{
3968
- type: HostBinding,
3969
- args: ['attr.the-level']
3970
- }] } });
3971
-
3972
- const withTodoItem = (editor) => {
3973
- const { insertBreak, deleteBackward, renderElement } = editor;
3974
- editor.insertBreak = () => {
3975
- const { selection } = editor;
3976
- if (selection && Range.isCollapsed(selection)) {
3977
- const [match] = Editor.nodes(editor, {
3978
- match: n => Element$1.isElement(n) && n.type === ElementKinds.checkItem
3979
- });
3980
- if (match) {
3981
- const [, path] = match;
3982
- const block = anchorBlock(editor);
3983
- if (block && Editor.isStart(editor, selection.anchor, path) && Editor.isEmpty(editor, block)) {
3984
- Transforms.setNodes(editor, {
3985
- type: ElementKinds.default,
3986
- checked: undefined
3987
- }, {
3988
- match: n => Element$1.isElement(n) && n.type === ElementKinds.checkItem
3989
- });
3990
- return;
3991
- }
3992
- }
3993
- }
3994
- insertBreak();
3995
- const anchorBlock$1 = anchorBlock(editor);
3996
- if (anchorBlock$1 && anchorBlock$1.type === ElementKinds.checkItem) {
3997
- Transforms.setNodes(editor, { checked: false });
3998
- }
3999
- };
4000
- editor.deleteBackward = unit => {
4001
- const { selection } = editor;
4002
- if (selection && Range.isCollapsed(selection)) {
4003
- const [match] = Editor.nodes(editor, {
4004
- match: n => Element$1.isElement(n) && n.type === ElementKinds.checkItem
4005
- });
4006
- if (match) {
4007
- const [, path] = match;
4008
- if (Editor.isStart(editor, selection.anchor, path)) {
4009
- Transforms.setNodes(editor, { type: ElementKinds.default, checked: undefined }, {
4010
- match: n => Element$1.isElement(n) && n.type === ElementKinds.checkItem
4011
- });
4012
- return;
4013
- }
4014
- }
4015
- }
4016
- deleteBackward(unit);
3899
+ const startMarkupPointAfter = getPointBefore(editor, endMarkupPointBefore, {
3900
+ matchString: startMarkup,
3901
+ skipInvalid: true,
3902
+ afterMatch: true
3903
+ });
3904
+ if (!startMarkupPointAfter) {
3905
+ return false;
3906
+ }
3907
+ // found
3908
+ const markupRange = {
3909
+ anchor: startMarkupPointAfter,
3910
+ focus: endMarkupPointBefore
4017
3911
  };
4018
- editor.renderElement = (element) => {
4019
- if (element.type === ElementKinds.checkItem) {
4020
- return TheTodoItemComponent;
3912
+ if (!ignoreTrim) {
3913
+ const markupText = getText(editor, markupRange);
3914
+ if (markupText.trim() !== markupText) {
3915
+ return false;
4021
3916
  }
4022
- return renderElement(element);
4023
- };
4024
- return editor;
4025
- };
4026
-
4027
- class TheHrComponent extends TheBaseElementComponent {
4028
- constructor(elementRef, cdr) {
4029
- super(elementRef, cdr);
4030
- this.elementRef = elementRef;
4031
- this.cdr = cdr;
4032
3917
  }
4033
- ngAfterViewInit() {
4034
- setTimeout(() => {
4035
- const blockCardElement = this.nativeElement.closest('slate-block-card');
4036
- if (blockCardElement) {
4037
- blockCardElement.classList.add(`slate-block-card-${this.element.type}`);
3918
+ // delete end markup
3919
+ if (endMarkup) {
3920
+ endMarkupPointBefore = getPointBefore(editor, selection, {
3921
+ matchString: endMarkup
3922
+ });
3923
+ Transforms.delete(editor, {
3924
+ at: {
3925
+ anchor: endMarkupPointBefore,
3926
+ focus: selection.anchor
3927
+ }
3928
+ });
3929
+ }
3930
+ const startMarkupPointBefore = getPointBefore(editor, selection, {
3931
+ matchString: startMarkup,
3932
+ skipInvalid: true
3933
+ });
3934
+ if (format) {
3935
+ const markupText = getText(editor, markupRange);
3936
+ format(editor, markupText);
3937
+ // delete start to end selection
3938
+ Transforms.delete(editor, {
3939
+ at: {
3940
+ anchor: startMarkupPointBefore,
3941
+ focus: selection.anchor
3942
+ }
3943
+ });
3944
+ }
3945
+ else {
3946
+ // add mark to the text between the markups
3947
+ Transforms.select(editor, markupRange);
3948
+ editor.addMark(type, true);
3949
+ Transforms.collapse(editor, { edge: 'end' });
3950
+ editor.removeMark(type, false);
3951
+ // delete start markup
3952
+ Transforms.delete(editor, {
3953
+ at: {
3954
+ anchor: startMarkupPointBefore,
3955
+ focus: startMarkupPointAfter
4038
3956
  }
4039
3957
  });
4040
3958
  }
4041
- }
4042
- TheHrComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: TheHrComponent, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
4043
- TheHrComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.15", type: TheHrComponent, selector: "the-hr, [theHr]", usesInheritance: true, ngImport: i0, template: `
4044
- <div class="the-hr" contenteditable="false" [ngClass]="{ active: selection }">
4045
- <hr class="the-hr" />
4046
- <slate-children [children]="children" [context]="childrenContext" [viewContext]="viewContext"></slate-children>
4047
- </div>
4048
- `, isInline: true, components: [{ type: i1.SlateChildrenComponent, selector: "slate-children", inputs: ["children", "context", "viewContext"] }], directives: [{ type: i10.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
4049
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: TheHrComponent, decorators: [{
4050
- type: Component,
4051
- args: [{
4052
- selector: 'the-hr, [theHr]',
4053
- template: `
4054
- <div class="the-hr" contenteditable="false" [ngClass]="{ active: selection }">
4055
- <hr class="the-hr" />
4056
- <slate-children [children]="children" [context]="childrenContext" [viewContext]="viewContext"></slate-children>
4057
- </div>
4058
- `
4059
- }]
4060
- }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }]; } });
4061
-
4062
- const withHr = (editor) => {
4063
- const { isVoid, isBlockCard, renderElement } = editor;
4064
- editor.isVoid = (element) => {
4065
- return element.type === ElementKinds.hr || isVoid(element);
4066
- };
4067
- editor.isBlockCard = (element) => {
4068
- if (element.type === ElementKinds.hr) {
4069
- return true;
4070
- }
4071
- return isBlockCard(element);
4072
- };
4073
- editor.renderElement = (element) => {
4074
- if (element.type === ElementKinds.hr) {
4075
- return TheHrComponent;
4076
- }
4077
- return renderElement(element);
4078
- };
4079
- return editor;
3959
+ return true;
4080
3960
  };
4081
3961
 
4082
- const withAlign = (editor) => {
4083
- const { deleteBackward } = editor;
4084
- editor.deleteBackward = unit => {
4085
- const { anchor } = editor.selection;
4086
- const node = anchorBlock(editor);
4087
- const isVoid = Editor.isVoid(editor, node);
4088
- const alignTypes = [Alignment.center, Alignment.right];
4089
- const startLine = Editor.start(editor, anchor.path);
4090
- const startLineRange = { anchor, focus: startLine };
4091
- const beforeText = Editor.string(editor, startLineRange);
4092
- if (!isVoid && node && node.align && alignTypes.includes(node.align) && beforeText === '') {
4093
- const align = alignTypes.indexOf(node.align) ? Alignment.center : undefined;
4094
- return Transforms.setNodes(editor, { align });
3962
+ const ListEditor = {
3963
+ isList(editor, element, type) {
3964
+ return Editor.isBlock(editor, element) && element.type === type;
3965
+ },
3966
+ toggleList(editor, type, startIndex) {
3967
+ if (!editor.selection) {
3968
+ return;
4095
3969
  }
4096
- deleteBackward(unit);
4097
- };
4098
- return editor;
4099
- };
4100
-
4101
- const withHeading = (editor) => {
4102
- const { insertBreak } = editor;
4103
- editor.insertBreak = () => {
4104
- const { selection } = editor;
4105
- const anchorBlock = getAnchorBlockEntry(editor);
4106
- if (anchorBlock && Range.isCollapsed(selection) && anchorBlock[0].type.startsWith('heading')) {
4107
- if (Editor.isStart(editor, selection.anchor, anchorBlock[1])) {
4108
- insertBreak();
4109
- Transforms.setNodes(editor, { type: ElementKinds.paragraph }, {
4110
- at: selection
3970
+ if (!startIndex) {
3971
+ startIndex = 1;
3972
+ }
3973
+ const types = [ElementKinds.bulletedList, ElementKinds.numberedList];
3974
+ Editor.withoutNormalizing(editor, () => {
3975
+ const [...listItems] = Editor.nodes(editor, {
3976
+ match: node => Element$1.isElement(node) && node.type === ElementKinds.listItem,
3977
+ mode: 'lowest'
3978
+ });
3979
+ const firstListItemPath = listItems.length && listItems[0][1];
3980
+ const activeListPath = listItems.length && Path.parent(firstListItemPath);
3981
+ const activeListNode = listItems.length && Node.get(editor, activeListPath);
3982
+ // 同级且类型相同:unwrap
3983
+ const isLowestActive = listItems.length &&
3984
+ listItems.every(([, path]) => activeListNode.type === type && (Path.isSibling(firstListItemPath, path) || Path.equals(firstListItemPath, path)));
3985
+ if (isLowestActive) {
3986
+ const upListItem = Path.parent(activeListPath);
3987
+ Transforms.unwrapNodes(editor, {
3988
+ at: editor.selection,
3989
+ match: node => node === activeListNode,
3990
+ split: true,
3991
+ mode: 'lowest'
4111
3992
  });
3993
+ if (upListItem && Node.get(editor, upListItem).type === ElementKinds.listItem) {
3994
+ Transforms.moveNodes(editor, {
3995
+ at: editor.selection,
3996
+ to: Path.next(upListItem),
3997
+ match: node => Element$1.isElement(node) && node.type === ElementKinds.listItem
3998
+ });
3999
+ }
4000
+ else {
4001
+ Transforms.unwrapNodes(editor, {
4002
+ match: node => Element$1.isElement(node) && node.type === ElementKinds.listItem
4003
+ });
4004
+ }
4112
4005
  return;
4113
4006
  }
4114
- if (Editor.isEnd(editor, selection.focus, anchorBlock[1])) {
4115
- insertBreak();
4116
- Transforms.setNodes(editor, { type: ElementKinds.paragraph });
4007
+ // 跨级、同级且类型不同
4008
+ if (activeListNode && types.includes(activeListNode.type)) {
4009
+ Transforms.setNodes(editor, { type }, { match: node => Element$1.isElement(node) && node.type !== type && types.includes(node.type) });
4117
4010
  return;
4118
4011
  }
4119
- }
4120
- insertBreak();
4121
- };
4122
- return editor;
4123
- };
4124
-
4125
- const withMark = () => (editor) => {
4126
- const e = editor;
4127
- e.removeMark = (key, shouldChange = true) => {
4128
- const { selection } = e;
4129
- if (selection) {
4130
- if (Range.isExpanded(selection)) {
4131
- Transforms.unsetNodes(e, key, {
4132
- match: Text.isText,
4133
- split: true
4134
- });
4012
+ // wrap
4013
+ this.buildListItem(editor);
4014
+ // Todo: types
4015
+ Transforms.wrapNodes(editor, { type, children: [], start: startIndex }, {
4016
+ at: editor.selection,
4017
+ match: node => Element$1.isElement(node) && node.type === ElementKinds.listItem
4018
+ });
4019
+ });
4020
+ },
4021
+ unwrapList(editor) {
4022
+ Editor.withoutNormalizing(editor, () => {
4023
+ unwrapNodesByType(editor, [ElementKinds.bulletedList, ElementKinds.numberedList], { split: true, mode: 'all' });
4024
+ unwrapNodesByType(editor, [ElementKinds.listItem], { split: true, mode: 'all' });
4025
+ });
4026
+ },
4027
+ wrapList(editor, type) {
4028
+ Editor.withoutNormalizing(editor, () => {
4029
+ const listItem = {
4030
+ type: ElementKinds.listItem,
4031
+ children: []
4032
+ };
4033
+ const list = {
4034
+ type,
4035
+ children: []
4036
+ };
4037
+ Transforms.wrapNodes(editor, list, { split: true });
4038
+ Transforms.wrapNodes(editor, listItem, { split: true });
4039
+ });
4040
+ },
4041
+ isActive(editor, type) {
4042
+ const [match] = getNodesByType(editor, type);
4043
+ return !!match;
4044
+ },
4045
+ getActiveList(editor) {
4046
+ const [match] = getNodesByType(editor, LIST_BLOCK_TYPES);
4047
+ return match;
4048
+ },
4049
+ buildListItem(editor) {
4050
+ const nodes = Editor.nodes(editor, {
4051
+ match: node => Editor.isBlock(editor, node),
4052
+ mode: 'lowest'
4053
+ });
4054
+ for (const [node, path] of nodes) {
4055
+ if (!Editor.isVoid(editor, node) && Element$1.isElement(node) && node.type !== ElementKinds.paragraph) {
4056
+ Transforms.setNodes(editor, { type: ElementKinds.paragraph, checked: undefined }, // todo remove checked
4057
+ { at: path });
4135
4058
  }
4136
- else {
4137
- const marks = Object.assign({}, (Editor.marks(e) || {}));
4138
- delete marks[key];
4139
- editor.marks = marks;
4140
- const text = Editor.string(e, selection.anchor.path);
4141
- if (text !== '') {
4142
- Editor.setNormalizing(editor, false);
4143
- e.insertText('');
4144
- editor.marks = marks;
4145
- Editor.setNormalizing(editor, true);
4146
- }
4147
- else {
4148
- Transforms.unsetNodes(e, key, { at: selection.anchor.path });
4149
- }
4150
- if (shouldChange) {
4151
- editor.onChange();
4059
+ else if (Element$1.isElement(node) && node.type === ElementKinds.paragraph) {
4060
+ let { textIndent } = node;
4061
+ if (textIndent) {
4062
+ Transforms.setNodes(editor, { textIndent: undefined, indent: undefined }, // remove indent
4063
+ { at: path });
4152
4064
  }
4153
4065
  }
4154
- }
4155
- };
4156
- e.addMark = (key, value) => {
4157
- const { selection } = editor;
4158
- if (selection) {
4159
- if (Range.isExpanded(selection)) {
4160
- Transforms.setNodes(e, { [key]: value }, { match: Text.isText, split: true });
4066
+ if (Node.parent(editor, path).type !== ElementKinds.listItem) {
4067
+ Transforms.wrapNodes(editor, { type: ElementKinds.listItem, children: [] }, {
4068
+ at: path,
4069
+ split: true
4070
+ });
4161
4071
  }
4162
- else {
4163
- const marks = Object.assign(Object.assign({}, (Editor.marks(e) || {})), { [key]: value });
4164
- editor.marks = marks;
4165
- const text = Editor.string(e, selection.anchor.path);
4166
- if (text !== '') {
4167
- Editor.setNormalizing(editor, false);
4168
- e.insertText('');
4169
- editor.marks = marks;
4170
- Editor.setNormalizing(editor, true);
4171
- }
4172
- else {
4173
- Transforms.setNodes(e, { [key]: value }, { at: selection.anchor.path });
4174
- }
4072
+ }
4073
+ },
4074
+ buildInsertDataChildren(node) {
4075
+ const { children } = node;
4076
+ const listItem = children[0];
4077
+ if (isNodeTypeList(node) && Element$1.isElement(listItem) && listItem.children[0].type === ElementKinds.paragraph) {
4078
+ return node;
4079
+ }
4080
+ return this.buildInsertDataChildren(listItem);
4081
+ }
4082
+ };
4083
+
4084
+ const TodoItemEditor = {
4085
+ isActive(editor) {
4086
+ const [match] = getNodesByType(editor, ElementKinds.checkItem);
4087
+ return !!match;
4088
+ },
4089
+ insertTodoItem(editor) {
4090
+ if (!editor.selection) {
4091
+ return;
4092
+ }
4093
+ const isActive = this.isActive(editor);
4094
+ const isNumberedList = ListEditor.isActive(editor, ElementKinds.numberedList);
4095
+ const isBulletedList = ListEditor.isActive(editor, ElementKinds.bulletedList);
4096
+ if (isActive) {
4097
+ Transforms.setNodes(editor, {
4098
+ type: ElementKinds.paragraph
4099
+ });
4100
+ }
4101
+ else {
4102
+ if (isNumberedList || isBulletedList) {
4103
+ ListEditor.unwrapList(editor);
4175
4104
  }
4105
+ Transforms.setNodes(editor, {
4106
+ type: ElementKinds.checkItem
4107
+ });
4176
4108
  }
4177
- };
4178
- return e;
4109
+ }
4179
4110
  };
4180
4111
 
4181
- const withNodeID = ({ idKey = 'id', idCreator = () => Date.now(), filterText = true, filter = () => true } = {}) => (e) => {
4182
- const editor = e;
4183
- const { apply, getFragment } = editor;
4184
- const idPropsCreator = () => ({ [idKey]: idCreator() });
4185
- editor.removedIDs = new Set();
4186
- editor.apply = (operation) => {
4187
- if (operation.type === 'insert_node') {
4188
- const newFilter = (entry) => {
4189
- const [_node] = entry;
4190
- return filter(entry) && filterText ? Element$1.isElement(_node) : isDescendant(_node);
4191
- };
4192
- // fix can not find path by orign node
4193
- let node = operation.node;
4194
- if (!Object.isExtensible(node)) {
4195
- node = _.cloneDeep(node);
4196
- }
4197
- // it will not overwrite ids once it's set as it's read-only
4198
- mergeDeepToNodes({
4199
- node,
4200
- source: idPropsCreator,
4201
- query: {
4202
- filter: newFilter,
4203
- }
4112
+ const BlockquoteEditor = {
4113
+ toggleBlockquote(editor) {
4114
+ if (!isParagraph(editor)) {
4115
+ Transforms.insertNodes(editor, {
4116
+ type: ElementKinds.paragraph,
4117
+ mode: 'text',
4118
+ children: [
4119
+ {
4120
+ text: ''
4121
+ }
4122
+ ]
4204
4123
  });
4205
- return apply(Object.assign(Object.assign({}, operation), { node }));
4206
4124
  }
4207
- if (operation.type === 'split_node' && (!filterText || operation.properties.type)) {
4208
- let id = operation.properties[idKey];
4209
- if (editor.removedIDs.has(id)) {
4210
- editor.removedIDs.delete(id);
4211
- }
4212
- else {
4213
- id = idCreator();
4214
- }
4215
- return apply(Object.assign(Object.assign({}, operation), { properties: Object.assign(Object.assign({}, operation.properties), { [idKey]: id }) }));
4125
+ const isActive = isBlockActive(editor, ElementKinds.blockquote);
4126
+ if (!isActive) {
4127
+ Transforms.wrapNodes(editor, { type: ElementKinds.blockquote, children: [] }, {
4128
+ mode: 'lowest'
4129
+ });
4216
4130
  }
4217
- if (operation.type === 'merge_node' && (!filterText || operation.properties.type)) {
4218
- editor.removedIDs.add(operation.properties[idKey]);
4131
+ else {
4132
+ Transforms.unwrapNodes(editor, { match: n => Element$1.isElement(n) && n.type === ElementKinds.blockquote });
4219
4133
  }
4220
- return apply(operation);
4221
- };
4222
- editor.getFragment = () => {
4223
- const fragment = _.cloneDeep(getFragment());
4224
- return deleteElementKey(fragment, idKey);
4225
- };
4226
- return editor;
4134
+ }
4227
4135
  };
4228
4136
 
4229
- const autoFormatBlock = (editor, type, at, { preFormat, format }, markups) => {
4230
- Transforms.delete(editor, { at });
4231
- if (preFormat) {
4232
- preFormat(editor);
4233
- }
4234
- if (!format) {
4235
- Transforms.setNodes(editor, { type }, { match: n => Editor.isBlock(editor, n) });
4236
- }
4237
- else {
4238
- format(editor, markups);
4137
+ const InlineCodeEditor = {
4138
+ toggleInlineCode(editor, text) {
4139
+ const isActive = InlineCodeEditor.isInlineCodeActive(editor);
4140
+ if (isActive) {
4141
+ InlineCodeEditor.unwrapInlineCode(editor);
4142
+ return;
4143
+ }
4144
+ if (Range.isCollapsed(editor.selection)) {
4145
+ InlineCodeEditor.wrapInlineCode(editor, text);
4146
+ }
4147
+ else {
4148
+ const fragment = Node.fragment(editor, editor.selection)[0];
4149
+ const selectNode = Node.get(fragment, []);
4150
+ const selectText = Node.string(selectNode);
4151
+ InlineCodeEditor.wrapInlineCode(editor, selectText);
4152
+ }
4153
+ },
4154
+ wrapInlineCode(editor, text = '') {
4155
+ if (InlineCodeEditor.isInlineCodeActive(editor)) {
4156
+ InlineCodeEditor.unwrapInlineCode(editor);
4157
+ }
4158
+ const { selection } = editor;
4159
+ const isCollapsed = selection && Range.isCollapsed(selection);
4160
+ const inlineCode = {
4161
+ type: ElementKinds.inlineCode,
4162
+ children: isCollapsed ? [{ text: text ? text : ZERO_WIDTH_CHAR }] : []
4163
+ };
4164
+ if (isCollapsed) {
4165
+ Transforms.insertNodes(editor, inlineCode);
4166
+ }
4167
+ else {
4168
+ Transforms.wrapNodes(editor, inlineCode, { split: true });
4169
+ }
4170
+ },
4171
+ unwrapInlineCode(editor) {
4172
+ Transforms.unwrapNodes(editor, { match: n => Element$1.isElement(n) && n.type === ElementKinds.inlineCode });
4173
+ },
4174
+ isInlineCodeActive(editor, path) {
4175
+ var _a;
4176
+ const [inlineCode] = Editor.nodes(editor, {
4177
+ at: path ? path : (_a = editor.selection) === null || _a === void 0 ? void 0 : _a.anchor.path,
4178
+ match: n => Element$1.isElement(n) && n.type === ElementKinds.inlineCode
4179
+ });
4180
+ return !!inlineCode;
4239
4181
  }
4240
4182
  };
4241
4183
 
4242
- const autoFormatInline = (editor, { type, between, markup, ignoreTrim, format }) => {
4243
- const selection = editor.selection;
4244
- const startMarkup = between ? between[0] : markup;
4245
- const endMarkup = between ? between[1] : '';
4246
- let endMarkupPointBefore = selection.anchor;
4247
- if (endMarkup) {
4248
- endMarkupPointBefore = getPointBefore(editor, selection, {
4249
- matchString: endMarkup
4184
+ const HeadingEditor = {
4185
+ setHeading(editor, heading) {
4186
+ Editor.withoutNormalizing(editor, () => {
4187
+ const types = [ElementKinds.bulletedList, ElementKinds.numberedList, ElementKinds.listItem];
4188
+ Transforms.unwrapNodes(editor, {
4189
+ at: editor.selection,
4190
+ match: n => Element$1.isElement(n) && types.includes(n.type),
4191
+ mode: 'all',
4192
+ split: true
4193
+ });
4194
+ Transforms.setNodes(editor, { type: heading });
4195
+ const entry = anchorBlockEntry(editor);
4196
+ const unMarks = {
4197
+ [MarkTypes.fontSize]: null
4198
+ };
4199
+ if (entry) {
4200
+ setMarks(editor, unMarks, entry[1]);
4201
+ return;
4202
+ }
4203
+ setMarks(editor, unMarks, editor.selection);
4250
4204
  });
4251
- if (!endMarkupPointBefore) {
4252
- return false;
4253
- }
4254
- }
4255
- const startMarkupPointAfter = getPointBefore(editor, endMarkupPointBefore, {
4256
- matchString: startMarkup,
4257
- skipInvalid: true,
4258
- afterMatch: true
4259
- });
4260
- if (!startMarkupPointAfter) {
4261
- return false;
4205
+ },
4206
+ isHeadingActive(editor, heading) {
4207
+ const [match] = Editor.nodes(editor, {
4208
+ match: n => Element$1.isElement(n) && n.type === heading,
4209
+ universal: true
4210
+ });
4211
+ return !!match;
4262
4212
  }
4263
- // found
4264
- const markupRange = {
4265
- anchor: startMarkupPointAfter,
4266
- focus: endMarkupPointBefore
4267
- };
4268
- if (!ignoreTrim) {
4269
- const markupText = getText(editor, markupRange);
4270
- if (markupText.trim() !== markupText) {
4271
- return false;
4213
+ };
4214
+
4215
+ const defaultAutoFormatRules = [
4216
+ {
4217
+ type: ElementKinds.heading_1,
4218
+ markup: '#',
4219
+ format: (editor) => {
4220
+ HeadingEditor.setHeading(editor, ElementKinds.heading_1);
4221
+ }
4222
+ },
4223
+ {
4224
+ type: ElementKinds.heading_2,
4225
+ markup: '##',
4226
+ format: (editor) => {
4227
+ HeadingEditor.setHeading(editor, ElementKinds.heading_2);
4228
+ }
4229
+ },
4230
+ {
4231
+ type: ElementKinds.heading_3,
4232
+ markup: '###',
4233
+ format: (editor) => {
4234
+ HeadingEditor.setHeading(editor, ElementKinds.heading_3);
4235
+ }
4236
+ },
4237
+ {
4238
+ type: ElementKinds.heading_4,
4239
+ markup: '####',
4240
+ format: (editor) => {
4241
+ HeadingEditor.setHeading(editor, ElementKinds.heading_4);
4242
+ }
4243
+ },
4244
+ {
4245
+ type: ElementKinds.heading_5,
4246
+ markup: '#####',
4247
+ format: (editor) => {
4248
+ HeadingEditor.setHeading(editor, ElementKinds.heading_5);
4249
+ }
4250
+ },
4251
+ {
4252
+ type: ElementKinds.heading_6,
4253
+ markup: '######',
4254
+ format: (editor) => {
4255
+ HeadingEditor.setHeading(editor, ElementKinds.heading_6);
4256
+ }
4257
+ },
4258
+ {
4259
+ type: ElementKinds.blockquote,
4260
+ markup: ['>'],
4261
+ format: (editor) => {
4262
+ BlockquoteEditor.toggleBlockquote(editor);
4263
+ }
4264
+ },
4265
+ {
4266
+ type: MarkTypes.bold,
4267
+ between: ['**', '**'],
4268
+ mode: 'inline',
4269
+ insertTrigger: true
4270
+ },
4271
+ {
4272
+ type: MarkTypes.bold,
4273
+ between: ['__', '__'],
4274
+ mode: 'inline',
4275
+ insertTrigger: true
4276
+ },
4277
+ {
4278
+ type: MarkTypes.italic,
4279
+ between: ['*', '*'],
4280
+ mode: 'inline',
4281
+ insertTrigger: true
4282
+ },
4283
+ {
4284
+ type: MarkTypes.italic,
4285
+ between: ['_', '_'],
4286
+ mode: 'inline',
4287
+ insertTrigger: true
4288
+ },
4289
+ {
4290
+ type: ElementKinds.inlineCode,
4291
+ between: ['`', '`'],
4292
+ mode: 'inline',
4293
+ format: (editor, text) => {
4294
+ InlineCodeEditor.toggleInlineCode(editor, text);
4295
+ Transforms.select(editor, Editor.after(editor, editor.selection));
4272
4296
  }
4273
- }
4274
- // delete end markup
4275
- if (endMarkup) {
4276
- endMarkupPointBefore = getPointBefore(editor, selection, {
4277
- matchString: endMarkup
4278
- });
4279
- Transforms.delete(editor, {
4280
- at: {
4281
- anchor: endMarkupPointBefore,
4282
- focus: selection.anchor
4283
- }
4284
- });
4285
- }
4286
- const startMarkupPointBefore = getPointBefore(editor, selection, {
4287
- matchString: startMarkup,
4288
- skipInvalid: true
4289
- });
4290
- if (format) {
4291
- const markupText = getText(editor, markupRange);
4292
- format(editor, markupText);
4293
- // delete start to end selection
4294
- Transforms.delete(editor, {
4295
- at: {
4296
- anchor: startMarkupPointBefore,
4297
- focus: selection.anchor
4298
- }
4299
- });
4300
- }
4301
- else {
4302
- // add mark to the text between the markups
4303
- Transforms.select(editor, markupRange);
4304
- editor.addMark(type, true);
4305
- Transforms.collapse(editor, { edge: 'end' });
4306
- editor.removeMark(type, false);
4307
- // delete start markup
4308
- Transforms.delete(editor, {
4309
- at: {
4310
- anchor: startMarkupPointBefore,
4311
- focus: startMarkupPointAfter
4297
+ },
4298
+ {
4299
+ type: MarkTypes.strike,
4300
+ between: ['~~', '~~'],
4301
+ mode: 'inline',
4302
+ insertTrigger: true
4303
+ },
4304
+ {
4305
+ type: ElementKinds.code,
4306
+ markup: '```',
4307
+ insertTrigger: true
4308
+ },
4309
+ {
4310
+ type: ElementKinds.listItem,
4311
+ markup: [],
4312
+ match: (editor) => {
4313
+ return isParagraph(editor) ? ['*', '-', '+'] : [];
4314
+ },
4315
+ format: (editor) => {
4316
+ ListEditor.toggleList(editor, ElementKinds.bulletedList);
4317
+ }
4318
+ },
4319
+ {
4320
+ type: ElementKinds.listItem,
4321
+ key: ElementKinds.numberedList,
4322
+ markup: [],
4323
+ match: (editor, textFromBlockStart) => {
4324
+ return isParagraph(editor) && /^-?\d+(\.|\))$/.test(textFromBlockStart) ? [textFromBlockStart] : [];
4325
+ },
4326
+ format: (editor, markup) => {
4327
+ let startIndex = 1;
4328
+ if (markup) {
4329
+ startIndex = markup[0].split('.')[0];
4330
+ if (startIndex === 0) {
4331
+ startIndex = 1;
4332
+ }
4312
4333
  }
4313
- });
4334
+ ListEditor.toggleList(editor, ElementKinds.numberedList, startIndex);
4335
+ }
4336
+ },
4337
+ {
4338
+ type: ElementKinds.checkItem,
4339
+ markup: [],
4340
+ match: (editor) => {
4341
+ return isParagraph(editor) ? ['[]'] : [];
4342
+ },
4343
+ format: (editor) => {
4344
+ TodoItemEditor.insertTodoItem(editor);
4345
+ }
4346
+ },
4347
+ {
4348
+ type: ElementKinds.hr,
4349
+ markup: '---',
4350
+ insertTrigger: true
4314
4351
  }
4315
- return true;
4316
- };
4352
+ ];
4317
4353
 
4318
- const withAutoFormat = ({ rules }) => (editor) => {
4354
+ const withAutoFormat = () => (editor) => {
4319
4355
  const { insertText } = editor;
4320
4356
  editor.insertText = text => {
4321
- var _a;
4357
+ var _a, _b;
4358
+ let autoFormatRules = defaultAutoFormatRules;
4359
+ if ((_a = editor.extraAutoFormatRules) === null || _a === void 0 ? void 0 : _a.length) {
4360
+ const extraRules = mergAutoFormateRules(editor.extraAutoFormatRules);
4361
+ autoFormatRules = Object.values(extraRules);
4362
+ }
4322
4363
  if (!isCollapsed(editor.selection)) {
4323
4364
  return insertText(text);
4324
4365
  }
4325
- for (let _b of rules) {
4326
- const { query } = _b, rule = __rest(_b, ["query"]);
4366
+ for (let _c of autoFormatRules) {
4367
+ const { query } = _c, rule = __rest(_c, ["query"]);
4327
4368
  const { trigger = ' ', mode = 'block', type, markup, preFormat, format, match, between, ignoreTrim, insertTrigger, allowSameTypeAbove = false, triggerAtBlockStart = true } = rule;
4328
4369
  if (query && !query(editor, rule))
4329
4370
  continue;
@@ -4358,7 +4399,7 @@ const withAutoFormat = ({ rules }) => (editor) => {
4358
4399
  });
4359
4400
  if (!markupRange)
4360
4401
  continue;
4361
- const blockAbovePath = (_a = getBlockAbove(editor)) === null || _a === void 0 ? void 0 : _a[1];
4402
+ const blockAbovePath = (_b = getBlockAbove(editor)) === null || _b === void 0 ? void 0 : _b[1];
4362
4403
  if (!blockAbovePath)
4363
4404
  continue;
4364
4405
  // If the markup is not at the start, insert break before autoformatting.
@@ -4395,6 +4436,17 @@ const withAutoFormat = ({ rules }) => (editor) => {
4395
4436
  };
4396
4437
  return editor;
4397
4438
  };
4439
+ const mergAutoFormateRules = (extraAutoFormatRules) => {
4440
+ const combinationData = [...defaultAutoFormatRules, ...extraAutoFormatRules];
4441
+ const dataInfo = {};
4442
+ combinationData.forEach(item => {
4443
+ if (!dataInfo[item.type + item.key]) {
4444
+ dataInfo[item.type + item.key] = Object.assign({}, item);
4445
+ }
4446
+ dataInfo[item.type + item.key] = Object.assign(Object.assign({}, dataInfo[item.type + item.key]), item);
4447
+ });
4448
+ return dataInfo;
4449
+ };
4398
4450
 
4399
4451
  const withTransforms = () => (editor) => {
4400
4452
  const e = editor;
@@ -9213,8 +9265,9 @@ class TheTableComponent extends TheBaseElementComponent {
9213
9265
  setNode(this.editor, { columns }, this.element);
9214
9266
  }
9215
9267
  onRowMouseDown(event, index) {
9268
+ if (this.readonly)
9269
+ return;
9216
9270
  event.stopPropagation();
9217
- event.preventDefault();
9218
9271
  if (!this.isInTable) {
9219
9272
  const path = TheEditor.findPath(this.editor, this.element);
9220
9273
  Transforms.select(this.editor, path);
@@ -11250,26 +11303,26 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImpo
11250
11303
  }] } });
11251
11304
 
11252
11305
  class TheQuickToolbarComponent extends mixinUnsubscribe(MixinBase) {
11253
- constructor(popoverRef, elementRef) {
11306
+ constructor(elementRef, cdr) {
11254
11307
  super();
11255
- this.popoverRef = popoverRef;
11256
11308
  this.elementRef = elementRef;
11309
+ this.cdr = cdr;
11257
11310
  this.ToolbarItemMode = ToolbarItemMode;
11258
11311
  this.ToolbarActionTypes = ToolbarActionTypes;
11259
11312
  }
11260
11313
  handleMouseDown(event) {
11261
11314
  if (!this.elementRef.nativeElement.contains(event.target)) {
11262
- QuickInsertEditor.closeQuickToolbar(this.editor);
11315
+ QuickInsertEditor.closeQuickInsertToolbar(this.editor);
11263
11316
  }
11264
11317
  else {
11265
11318
  event.preventDefault();
11266
11319
  }
11267
11320
  }
11268
11321
  handleEnter() {
11269
- QuickInsertEditor.closeQuickToolbar(this.editor);
11322
+ QuickInsertEditor.closeQuickInsertToolbar(this.editor);
11270
11323
  }
11271
11324
  handleEsc() {
11272
- QuickInsertEditor.closeQuickToolbar(this.editor);
11325
+ QuickInsertEditor.closeQuickInsertToolbar(this.editor);
11273
11326
  }
11274
11327
  ngOnInit() {
11275
11328
  this.editorElement = AngularEditor.toDOMNode(this.editor, this.editor);
@@ -11294,15 +11347,15 @@ class TheQuickToolbarComponent extends mixinUnsubscribe(MixinBase) {
11294
11347
  super.ngOnDestroy();
11295
11348
  }
11296
11349
  }
11297
- TheQuickToolbarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: TheQuickToolbarComponent, deps: [{ token: i1$3.ThyPopoverRef }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
11298
- TheQuickToolbarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.15", type: TheQuickToolbarComponent, selector: "the-quick-toolbar", inputs: { editor: "editor", quickToolbarItems: "quickToolbarItems" }, host: { listeners: { "document: mousedown": "handleMouseDown($event)", "document: keydown.enter": "handleEnter()", "document: keydown.escape": "handleEsc()" } }, usesInheritance: true, ngImport: i0, template: "<thy-selection-list\n class=\"the-quick-toolbar\"\n [thyBindKeyEventContainer]=\"editorElement\"\n (thySelectionChange)=\"selectionChange($event)\"\n [thyMultiple]=\"false\"\n>\n <ng-container *ngFor=\"let item of quickToolbarItems\">\n <ng-container *ngIf=\"item.key !== ToolbarActionTypes.split; else splitLine\">\n <thy-list-option [thyValue]=\"item?.key\" (mousedown)=\"stopPropagation($event)\">\n <the-toolbar-item [editor]=\"editor\" [item]=\"item\" [itemMode]=\"ToolbarItemMode.vertical\"></the-toolbar-item>\n </thy-list-option>\n </ng-container>\n </ng-container>\n</thy-selection-list>\n\n<ng-template #splitLine>\n <nav-split-line [mode]=\"ToolbarItemMode.horizontal\"></nav-split-line>\n</ng-template>\n", components: [{ type: i2$3.ThySelectionListComponent, selector: "thy-selection-list,[thy-selection-list]", inputs: ["thyMultiple", "thyBindKeyEventContainer", "thyScrollContainer", "thyBeforeKeydown", "thyUniqueKey", "thyCompareWith", "thyLayout", "thyAutoActiveFirstItem", "thySize", "thySpaceKeyEnabled"], outputs: ["thySelectionChange"] }, { type: i5$2.ThyListOptionComponent, selector: "thy-list-option,[thy-list-option]", inputs: ["id", "thyValue", "thyDisabled"] }, { type: TheToolbarItemComponent, selector: "the-toolbar-item", inputs: ["editor", "item", "itemMode"] }, { type: NavSplitLineComponent, selector: "nav-split-line", inputs: ["mode"] }], directives: [{ type: i10.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i10.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
11350
+ TheQuickToolbarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: TheQuickToolbarComponent, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
11351
+ TheQuickToolbarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.15", type: TheQuickToolbarComponent, selector: "the-quick-toolbar", inputs: { editor: "editor", quickToolbarItems: "quickToolbarItems" }, host: { listeners: { "document: mousedown": "handleMouseDown($event)", "document: keydown.enter": "handleEnter()", "document: keydown.escape": "handleEsc()" } }, usesInheritance: true, ngImport: i0, template: "<thy-selection-list\n class=\"the-quick-toolbar\"\n [thyBindKeyEventContainer]=\"editorElement\"\n (thySelectionChange)=\"selectionChange($event)\"\n [thyMultiple]=\"false\"\n>\n <ng-container *ngFor=\"let item of quickToolbarItems\">\n <ng-container *ngIf=\"item.key !== ToolbarActionTypes.split; else splitLine\">\n <thy-list-option [thyValue]=\"item?.key\" (mousedown)=\"stopPropagation($event)\">\n <the-toolbar-item [editor]=\"editor\" [item]=\"item\" [itemMode]=\"ToolbarItemMode.vertical\"></the-toolbar-item>\n </thy-list-option>\n </ng-container>\n </ng-container>\n</thy-selection-list>\n\n<ng-template #splitLine>\n <nav-split-line [mode]=\"ToolbarItemMode.horizontal\"></nav-split-line>\n</ng-template>\n", components: [{ type: i1$7.ThySelectionListComponent, selector: "thy-selection-list,[thy-selection-list]", inputs: ["thyMultiple", "thyBindKeyEventContainer", "thyScrollContainer", "thyBeforeKeydown", "thyUniqueKey", "thyCompareWith", "thyLayout", "thyAutoActiveFirstItem", "thySize", "thySpaceKeyEnabled"], outputs: ["thySelectionChange"] }, { type: i5$2.ThyListOptionComponent, selector: "thy-list-option,[thy-list-option]", inputs: ["id", "thyValue", "thyDisabled"] }, { type: TheToolbarItemComponent, selector: "the-toolbar-item", inputs: ["editor", "item", "itemMode"] }, { type: NavSplitLineComponent, selector: "nav-split-line", inputs: ["mode"] }], directives: [{ type: i10.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i10.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
11299
11352
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: TheQuickToolbarComponent, decorators: [{
11300
11353
  type: Component,
11301
11354
  args: [{
11302
11355
  selector: 'the-quick-toolbar',
11303
11356
  templateUrl: 'quick-toolbar.component.html'
11304
11357
  }]
11305
- }], ctorParameters: function () { return [{ type: i1$3.ThyPopoverRef }, { type: i0.ElementRef }]; }, propDecorators: { editor: [{
11358
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { editor: [{
11306
11359
  type: Input
11307
11360
  }], quickToolbarItems: [{
11308
11361
  type: Input
@@ -11317,16 +11370,22 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImpo
11317
11370
  args: ['document: keydown.escape']
11318
11371
  }] } });
11319
11372
 
11320
- const OperationTypes = ['insert_text', 'remove_node', 'merge_node'];
11321
11373
  const QuickInsertEditor = {
11322
- openQuickToolbar(editor, toolbarItems, origin) {
11374
+ openQuickInsertToolbar(editor, quickToolbarItems, origin) {
11375
+ if (QuickInsertEditor.isOpenedToolbar(editor)) {
11376
+ return;
11377
+ }
11378
+ if (!origin) {
11379
+ const rootNode = AngularEditor.toDOMNode(editor, Node.ancestor(editor, [editor.selection.anchor.path[0]]));
11380
+ origin = rootNode.querySelector('[data-slate-leaf="true"]');
11381
+ }
11323
11382
  const overlay = editor.injector.get(Overlay);
11324
11383
  const viewContainerRef = editor.injector.get(ViewContainerRef);
11325
11384
  const thyPopover = editor.injector.get(ThyPopover);
11326
11385
  const quickToolbarRef = thyPopover.open(TheQuickToolbarComponent, {
11327
11386
  initialState: {
11328
11387
  editor,
11329
- quickToolbarItems: toolbarItems
11388
+ quickToolbarItems
11330
11389
  },
11331
11390
  origin,
11332
11391
  viewContainerRef: viewContainerRef,
@@ -11339,52 +11398,34 @@ const QuickInsertEditor = {
11339
11398
  scrollStrategy: overlay.scrollStrategies.reposition(),
11340
11399
  manualClosure: true
11341
11400
  });
11401
+ quickToolbarRef.componentInstance.cdr.markForCheck();
11342
11402
  THE_EDITOR_QUICK_TOOLBAR_REF.set(editor, quickToolbarRef);
11343
11403
  },
11344
- closeQuickToolbar(editor) {
11404
+ closeQuickInsertToolbar(editor) {
11345
11405
  const quickToolbarRef = THE_EDITOR_QUICK_TOOLBAR_REF.get(editor);
11346
11406
  if (quickToolbarRef) {
11347
11407
  quickToolbarRef.close();
11348
11408
  THE_EDITOR_QUICK_TOOLBAR_REF.set(editor, null);
11349
11409
  }
11350
11410
  },
11351
- isOpenToolbar(editor, opTypes = OperationTypes) {
11352
- const isCollapsedCursor = TheEditor.isFocused(editor) && editor.selection && Range.isCollapsed(editor.selection);
11353
- if (!isCollapsedCursor) {
11354
- return false;
11355
- }
11356
- const block = Node.ancestor(editor, [editor.selection.anchor.path[0]]);
11357
- const { undos } = editor.history;
11358
- const lastBatch = undos[undos.length - 1];
11359
- const lastOp = lastBatch && lastBatch[lastBatch.length - 1];
11360
- if (lastOp &&
11361
- block.children.length === 1 &&
11362
- block.type === ElementKinds.paragraph &&
11363
- Node.string(block) === QUICK_TOOLBAR_HOTKEY &&
11364
- opTypes.includes(lastOp.type) &&
11365
- (lastOp.text === QUICK_TOOLBAR_HOTKEY || lastOp.text === undefined)) {
11366
- return true;
11367
- }
11368
- return false;
11411
+ isOpenedToolbar(editor) {
11412
+ const quickToolbarRef = THE_EDITOR_QUICK_TOOLBAR_REF.get(editor);
11413
+ return !!quickToolbarRef;
11369
11414
  }
11370
11415
  };
11371
11416
 
11372
11417
  const withQuickInsert = (editor) => {
11373
11418
  const { onKeydown, deleteBackward, onChange } = editor;
11419
+ let presseingQuickInsertHotkey = false;
11374
11420
  editor.onKeydown = (event) => {
11375
11421
  if (event.key === QUICK_TOOLBAR_HOTKEY && isCleanEmptyParagraph(editor)) {
11376
- const rootNode = AngularEditor.toDOMNode(editor, Node.ancestor(editor, [editor.selection.anchor.path[0]]));
11377
- const theEditorComponent = editor.injector.get(TheEditorComponent);
11378
- const quickToolbars = theEditorComponent.quickToolbarItems;
11379
- const leafElement = rootNode.querySelector('[data-slate-leaf="true"]');
11380
- const origin = leafElement || rootNode;
11381
- QuickInsertEditor.openQuickToolbar(editor, quickToolbars, origin);
11422
+ presseingQuickInsertHotkey = true;
11382
11423
  }
11383
11424
  onKeydown(event);
11384
11425
  };
11385
11426
  editor.deleteBackward = unit => {
11386
- if (!QuickInsertEditor.isOpenToolbar(editor, ['remove_text'])) {
11387
- QuickInsertEditor.closeQuickToolbar(editor);
11427
+ if (QuickInsertEditor.isOpenedToolbar(editor)) {
11428
+ QuickInsertEditor.closeQuickInsertToolbar(editor);
11388
11429
  }
11389
11430
  deleteBackward(unit);
11390
11431
  };
@@ -11392,11 +11433,17 @@ const withQuickInsert = (editor) => {
11392
11433
  var _a;
11393
11434
  onChange();
11394
11435
  if (editor.selection) {
11436
+ const block = Node.get(editor, [editor.selection.anchor.path[0]]);
11437
+ // quick insert plus
11395
11438
  const editorComponent = editor.injector.get(TheEditorComponent);
11396
11439
  (_a = editorComponent.quickInsertInstance) === null || _a === void 0 ? void 0 : _a.checkStatus();
11397
- const block = Node.ancestor(editor, [editor.selection.anchor.path[0]]);
11398
- if (!isCleanEmptyParagraph(editor) && Node.string(block) !== QUICK_TOOLBAR_HOTKEY) {
11399
- QuickInsertEditor.closeQuickToolbar(editor);
11440
+ if (presseingQuickInsertHotkey && Node.string(block) === QUICK_TOOLBAR_HOTKEY) {
11441
+ QuickInsertEditor.openQuickInsertToolbar(editor, editorComponent.quickToolbarItems);
11442
+ presseingQuickInsertHotkey = false;
11443
+ return;
11444
+ }
11445
+ if (QuickInsertEditor.isOpenedToolbar(editor) && !isCleanEmptyParagraph(editor) && Node.string(block) !== QUICK_TOOLBAR_HOTKEY) {
11446
+ QuickInsertEditor.closeQuickInsertToolbar(editor);
11400
11447
  }
11401
11448
  }
11402
11449
  };
@@ -11691,6 +11738,78 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.15", ngImpo
11691
11738
  args: ['class.disabled']
11692
11739
  }] } });
11693
11740
 
11741
+ const onKeydownTextIndent = (editor, event, kinds, textIndentDisabled) => {
11742
+ const { selection } = editor;
11743
+ const isExpanded = Range.isExpanded(selection);
11744
+ const nodes = Array.from(Editor.nodes(editor, {
11745
+ mode: 'highest',
11746
+ match: node => Element$1.isElement(node) && kinds.includes(node.type)
11747
+ }));
11748
+ const [startBlock] = nodes;
11749
+ if (!startBlock) {
11750
+ return false;
11751
+ }
11752
+ const [block, path] = startBlock;
11753
+ const isStart = Editor.isStart(editor, selection.anchor, path);
11754
+ if (isKeyHotkey('Tab', event)) {
11755
+ event.preventDefault();
11756
+ if (startBlock && (isExpanded || isStart)) {
11757
+ if (!editor.isVoid(block)) {
11758
+ let { textIndent, type } = block;
11759
+ // do not apply first-line indentation for lists
11760
+ if (!textIndent && !textIndentDisabled.includes(type)) {
11761
+ IndentEditor.setTextIndent(editor, kinds, 2);
11762
+ return true;
11763
+ }
11764
+ else {
11765
+ IndentEditor.setIndent(editor);
11766
+ return true;
11767
+ }
11768
+ }
11769
+ }
11770
+ else {
11771
+ editor.insertText(TAB_SPACE);
11772
+ return true;
11773
+ }
11774
+ }
11775
+ if (isKeyHotkey('shift+Tab', event)) {
11776
+ if (startBlock && (isExpanded || isStart)) {
11777
+ if (!editor.isVoid(block)) {
11778
+ return IndentEditor.cancelTextIntent(editor, event, block, kinds);
11779
+ }
11780
+ }
11781
+ }
11782
+ if (selection && Range.isCollapsed(selection) && hotkeys.isDeleteBackward(event)) {
11783
+ if (startBlock && isStart) {
11784
+ return IndentEditor.cancelTextIntent(editor, event, block, kinds);
11785
+ }
11786
+ }
11787
+ return false;
11788
+ };
11789
+
11790
+ const withIndent = (kinds) => (editor) => {
11791
+ const { onKeydown } = editor;
11792
+ editor.onKeydown = (event) => {
11793
+ var _a, _b, _c, _d;
11794
+ let indentTypes = kinds;
11795
+ let disableIndentTypes = [ElementKinds.bulletedList, ElementKinds.numberedList, ElementKinds.checkItem];
11796
+ if ((_b = (_a = editor.extraIndentOptions) === null || _a === void 0 ? void 0 : _a.indentTypes) === null || _b === void 0 ? void 0 : _b.length) {
11797
+ indentTypes = mergIndentTypes(kinds, editor.extraIndentOptions.indentTypes);
11798
+ }
11799
+ if ((_d = (_c = editor.extraIndentOptions) === null || _c === void 0 ? void 0 : _c.disabledIndentTypes) === null || _d === void 0 ? void 0 : _d.length) {
11800
+ disableIndentTypes = mergIndentTypes(disableIndentTypes, editor.extraIndentOptions.disabledIndentTypes);
11801
+ }
11802
+ const isContinue = !onKeydownTextIndent(editor, event, indentTypes, disableIndentTypes);
11803
+ if (isContinue) {
11804
+ onKeydown(event);
11805
+ }
11806
+ };
11807
+ return editor;
11808
+ };
11809
+ const mergIndentTypes = (defaultTypes, indentTypes) => {
11810
+ return Array.from(new Set([...defaultTypes, ...indentTypes]));
11811
+ };
11812
+
11694
11813
  const MaxIndent = 11;
11695
11814
  const includesIndentTypes = [
11696
11815
  ElementKinds.checkItem,
@@ -11699,11 +11818,15 @@ const includesIndentTypes = [
11699
11818
  ElementKinds.paragraph,
11700
11819
  ...HEADING_TYPES
11701
11820
  ];
11821
+ const getIndentTypes = editor => {
11822
+ let indentTypes = editor.extraIndentOptions ? editor.extraIndentOptions.indentTypes : [];
11823
+ return mergIndentTypes(includesIndentTypes, indentTypes);
11824
+ };
11702
11825
  const IndentEditor = {
11703
11826
  setIndent(editor) {
11704
11827
  const nodes = Array.from(Editor.nodes(editor, {
11705
11828
  mode: 'highest',
11706
- match: n => Element$1.isElement(n) && includesIndentTypes.includes(n.type)
11829
+ match: n => Element$1.isElement(n) && getIndentTypes(editor).includes(n.type)
11707
11830
  }));
11708
11831
  const [startBlock] = nodes;
11709
11832
  if (startBlock) {
@@ -11713,7 +11836,7 @@ const IndentEditor = {
11713
11836
  if (indent <= MaxIndent) {
11714
11837
  Transforms.setNodes(editor, { indent }, {
11715
11838
  mode: 'highest',
11716
- match: n => Element$1.isElement(n) && includesIndentTypes.includes(n.type)
11839
+ match: n => Element$1.isElement(n) && getIndentTypes(editor).includes(n.type)
11717
11840
  });
11718
11841
  }
11719
11842
  }
@@ -11721,7 +11844,7 @@ const IndentEditor = {
11721
11844
  cancelIndent(editor) {
11722
11845
  const nodes = Array.from(Editor.nodes(editor, {
11723
11846
  mode: 'highest',
11724
- match: n => Element$1.isElement(n) && includesIndentTypes.includes(n.type)
11847
+ match: n => Element$1.isElement(n) && getIndentTypes(editor).includes(n.type)
11725
11848
  }));
11726
11849
  const [startBlock] = nodes;
11727
11850
  if (startBlock) {
@@ -11729,7 +11852,7 @@ const IndentEditor = {
11729
11852
  indent = indent === 1 ? null : (indent -= 1);
11730
11853
  Transforms.setNodes(editor, { indent }, {
11731
11854
  mode: 'highest',
11732
- match: n => Element$1.isElement(n) && includesIndentTypes.includes(n.type)
11855
+ match: n => Element$1.isElement(n) && getIndentTypes(editor).includes(n.type)
11733
11856
  });
11734
11857
  }
11735
11858
  },
@@ -11761,15 +11884,8 @@ const IndentEditor = {
11761
11884
  },
11762
11885
  isDisabled(editor) {
11763
11886
  if (editor.selection) {
11764
- const allowGroup = [
11765
- ElementKinds.paragraph,
11766
- ElementKinds.numberedList,
11767
- ElementKinds.bulletedList,
11768
- ElementKinds.checkItem,
11769
- ...HEADING_TYPES
11770
- ];
11771
11887
  const anchorBlock$1 = anchorBlock(editor);
11772
- return anchorBlock$1 && !allowGroup.includes(anchorBlock$1 === null || anchorBlock$1 === void 0 ? void 0 : anchorBlock$1.type);
11888
+ return anchorBlock$1 && !getIndentTypes(editor).includes(anchorBlock$1 === null || anchorBlock$1 === void 0 ? void 0 : anchorBlock$1.type);
11773
11889
  }
11774
11890
  return false;
11775
11891
  }
@@ -11799,67 +11915,6 @@ const IndentOptions = [
11799
11915
  }
11800
11916
  ];
11801
11917
 
11802
- const onKeydownTextIndent = (editor, event, kinds) => {
11803
- const { selection } = editor;
11804
- const isExpanded = Range.isExpanded(selection);
11805
- const nodes = Array.from(Editor.nodes(editor, {
11806
- mode: 'highest',
11807
- match: node => Element$1.isElement(node) && kinds.includes(node.type)
11808
- }));
11809
- const [startBlock] = nodes;
11810
- if (!startBlock) {
11811
- return false;
11812
- }
11813
- const [block, path] = startBlock;
11814
- const isStart = Editor.isStart(editor, selection.anchor, path);
11815
- const textIndentDisable = [ElementKinds.bulletedList, ElementKinds.numberedList, ElementKinds.checkItem];
11816
- if (isKeyHotkey('Tab', event)) {
11817
- event.preventDefault();
11818
- if (startBlock && (isExpanded || isStart)) {
11819
- if (!editor.isVoid(block)) {
11820
- let { textIndent, type } = block;
11821
- // do not apply first-line indentation for lists
11822
- if (!textIndent && !textIndentDisable.includes(type)) {
11823
- IndentEditor.setTextIndent(editor, kinds, 2);
11824
- return true;
11825
- }
11826
- else {
11827
- IndentEditor.setIndent(editor);
11828
- return true;
11829
- }
11830
- }
11831
- }
11832
- else {
11833
- editor.insertText(TAB_SPACE);
11834
- return true;
11835
- }
11836
- }
11837
- if (isKeyHotkey('shift+Tab', event)) {
11838
- if (startBlock && (isExpanded || isStart)) {
11839
- if (!editor.isVoid(block)) {
11840
- return IndentEditor.cancelTextIntent(editor, event, block, kinds);
11841
- }
11842
- }
11843
- }
11844
- if (selection && Range.isCollapsed(selection) && hotkeys.isDeleteBackward(event)) {
11845
- if (startBlock && isStart) {
11846
- return IndentEditor.cancelTextIntent(editor, event, block, kinds);
11847
- }
11848
- }
11849
- return false;
11850
- };
11851
-
11852
- const withIndent = (kinds) => (editor) => {
11853
- const { onKeydown } = editor;
11854
- editor.onKeydown = (event) => {
11855
- const isContinue = !onKeydownTextIndent(editor, event, kinds);
11856
- if (isContinue) {
11857
- onKeydown(event);
11858
- }
11859
- };
11860
- return editor;
11861
- };
11862
-
11863
11918
  const internalPlugins = [
11864
11919
  withTheHistory,
11865
11920
  withAutoInsertData(),
@@ -11890,7 +11945,7 @@ const internalPlugins = [
11890
11945
  }),
11891
11946
  withBlockquote,
11892
11947
  withNodeID({ idKey: ELEMENT_UNIQUE_ID, idCreator }),
11893
- withAutoFormat({ rules: autoFormatRules }),
11948
+ withAutoFormat(),
11894
11949
  withTransforms(),
11895
11950
  withTrailingNode({ type: ElementKinds.paragraph, level: 0 }),
11896
11951
  withMoveSelection,
@@ -12482,7 +12537,11 @@ class TheQuickInsertComponent {
12482
12537
  handleClick(event) {
12483
12538
  event.stopPropagation();
12484
12539
  event.preventDefault();
12485
- QuickInsertEditor.openQuickToolbar(this.editor, this.quickToolbarItems, this.iconElement.nativeElement);
12540
+ if (QuickInsertEditor.isOpenedToolbar(this.editor)) {
12541
+ QuickInsertEditor.closeQuickInsertToolbar(this.editor);
12542
+ return;
12543
+ }
12544
+ QuickInsertEditor.openQuickInsertToolbar(this.editor, this.quickToolbarItems, this.iconElement.nativeElement);
12486
12545
  }
12487
12546
  }
12488
12547
  TheQuickInsertComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.15", ngImport: i0, type: TheQuickInsertComponent, deps: [{ token: i0.Renderer2 }, { token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
@@ -12755,11 +12814,13 @@ class TheEditorComponent extends mixinUnsubscribe(MixinBase) {
12755
12814
  super.ngOnDestroy();
12756
12815
  }
12757
12816
  initialize() {
12758
- var _a, _b;
12817
+ var _a, _b, _c, _d;
12759
12818
  this.editor = withTheEditor(this.thePlugins, withHistory(withAngular(createEditor(), CLIPBOARD_FORMAT_KEY)));
12760
12819
  this.generateDecorate();
12761
12820
  this.editor.disabled = (_a = this.theOptions) === null || _a === void 0 ? void 0 : _a.disabled;
12762
12821
  this.editor.extraElementOptions = (_b = this.theOptions) === null || _b === void 0 ? void 0 : _b.extraElementOptions;
12822
+ this.editor.extraAutoFormatRules = (_c = this.theOptions) === null || _c === void 0 ? void 0 : _c.extraAutoFormatRules;
12823
+ this.editor.extraIndentOptions = (_d = this.theOptions) === null || _d === void 0 ? void 0 : _d.extraIndentOptions;
12763
12824
  setEditorUUID(this.editor, idCreator());
12764
12825
  this.theContextService.initialize({
12765
12826
  theOptions: this.theOptions,