slate-angular 16.1.0-next.2 → 16.1.0-next.20

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 (42) hide show
  1. package/components/children/children-outlet.component.d.ts +9 -0
  2. package/components/editable/editable.component.d.ts +1 -1
  3. package/components/string/default-string.component.d.ts +1 -1
  4. package/components/text/void-text.component.d.ts +0 -1
  5. package/esm2022/components/block-card/block-card.component.mjs +2 -2
  6. package/esm2022/components/children/children-outlet.component.mjs +22 -0
  7. package/esm2022/components/children/children.component.mjs +2 -4
  8. package/esm2022/components/editable/editable.component.mjs +36 -20
  9. package/esm2022/components/leaf/token.mjs +1 -1
  10. package/esm2022/components/string/default-string.component.mjs +1 -1
  11. package/esm2022/components/string/string.component.mjs +1 -1
  12. package/esm2022/components/text/token.mjs +1 -1
  13. package/esm2022/components/text/void-text.component.mjs +2 -6
  14. package/esm2022/module.mjs +7 -16
  15. package/esm2022/plugins/angular-editor.mjs +61 -17
  16. package/esm2022/plugins/with-angular.mjs +5 -4
  17. package/esm2022/public-api.mjs +3 -2
  18. package/esm2022/utils/constants.mjs +2 -0
  19. package/esm2022/utils/index.mjs +2 -1
  20. package/esm2022/utils/throttle.mjs +1 -1
  21. package/esm2022/view/base.mjs +59 -22
  22. package/esm2022/view/container.mjs +1 -1
  23. package/esm2022/view/context-change.mjs +13 -0
  24. package/esm2022/view/context.mjs +1 -1
  25. package/esm2022/view/render/leaves-render.mjs +8 -6
  26. package/esm2022/view/render/list-render.mjs +57 -15
  27. package/esm2022/view/render/utils.mjs +25 -14
  28. package/fesm2022/slate-angular.mjs +294 -111
  29. package/fesm2022/slate-angular.mjs.map +1 -1
  30. package/module.d.ts +2 -1
  31. package/package.json +7 -7
  32. package/plugins/angular-editor.d.ts +17 -6
  33. package/public-api.d.ts +2 -1
  34. package/utils/constants.d.ts +1 -0
  35. package/utils/index.d.ts +1 -0
  36. package/view/base.d.ts +11 -7
  37. package/view/{before-context-change.d.ts → context-change.d.ts} +4 -0
  38. package/view/context.d.ts +2 -3
  39. package/view/render/leaves-render.d.ts +2 -1
  40. package/view/render/list-render.d.ts +7 -3
  41. package/view/render/utils.d.ts +3 -3
  42. package/esm2022/view/before-context-change.mjs +0 -7
@@ -1,4 +1,4 @@
1
- import { Editor, Range, Transforms, Path, Element, Text as Text$1, Node } from 'slate';
1
+ import { Editor, Range, Element, Transforms, Path, Text as Text$1, Node } from 'slate';
2
2
  import { isKeyHotkey } from 'is-hotkey';
3
3
  import * as i0 from '@angular/core';
4
4
  import { TemplateRef, Component, ChangeDetectionStrategy, ViewChild, Directive, Input, InjectionToken, ComponentRef, IterableDiffers, HostBinding, inject, ViewContainerRef, forwardRef, ElementRef, Inject, NgModule } from '@angular/core';
@@ -415,7 +415,7 @@ const AngularEditor = {
415
415
  const [start, end] = Range.edges(selection);
416
416
  const endBlock = Editor.above(editor, {
417
417
  at: end,
418
- match: node => Editor.isBlock(editor, node)
418
+ match: node => Element.isElement(node) && Editor.isBlock(editor, node)
419
419
  });
420
420
  return Editor.isStart(editor, end, endBlock[1]);
421
421
  },
@@ -610,13 +610,17 @@ const AngularEditor = {
610
610
  /**
611
611
  * Find a Slate node from a native DOM `element`.
612
612
  */
613
- toSlateNode(editor, domNode) {
613
+ toSlateNode(editor, domNode, options) {
614
+ const { suppressThrow } = options || { suppressThrow: false };
614
615
  let domEl = isDOMElement(domNode) ? domNode : domNode.parentElement;
615
616
  if (domEl && !domEl.hasAttribute('data-slate-node')) {
616
617
  domEl = domEl.closest(`[data-slate-node]`);
617
618
  }
618
619
  const node = domEl ? ELEMENT_TO_NODE.get(domEl) : null;
619
620
  if (!node) {
621
+ if (suppressThrow) {
622
+ return null;
623
+ }
620
624
  throw new Error(`Cannot resolve a Slate node from DOM node: ${domEl}`);
621
625
  }
622
626
  return node;
@@ -632,12 +636,12 @@ const AngularEditor = {
632
636
  if (x == null || y == null) {
633
637
  throw new Error(`Cannot resolve a Slate range from a DOM event: ${event}`);
634
638
  }
635
- const node = AngularEditor.toSlateNode(editor, event.target);
639
+ const node = AngularEditor.toSlateNode(editor, event.target, { suppressThrow: false });
636
640
  const path = AngularEditor.findPath(editor, node);
637
641
  // If the drop target is inside a void node, move it into either the
638
642
  // next or previous node, depending on which side the `x` and `y`
639
643
  // coordinates are closest to.
640
- if (Editor.isVoid(editor, node)) {
644
+ if (Element.isElement(node) && Editor.isVoid(editor, node)) {
641
645
  const rect = target.getBoundingClientRect();
642
646
  const isPrev = editor.isInline(node) ? x - rect.left < rect.left + rect.width - x : y - rect.top < rect.top + rect.height - y;
643
647
  const edge = Editor.point(editor, path, {
@@ -668,18 +672,25 @@ const AngularEditor = {
668
672
  throw new Error(`Cannot resolve a Slate range from a DOM event: ${event}`);
669
673
  }
670
674
  // Resolve a Slate range from the DOM range.
671
- const range = AngularEditor.toSlateRange(editor, domRange);
675
+ const range = AngularEditor.toSlateRange(editor, domRange, { suppressThrow: false });
672
676
  return range;
673
677
  },
674
- isLeafInEditor(editor, leafNode) {
678
+ isLeafInEditor(editor, leafNode, options) {
679
+ const { suppressThrow } = options;
675
680
  const textNode = leafNode.closest('[data-slate-node="text"]');
676
- const node = AngularEditor.toSlateNode(editor, textNode);
677
- return AngularEditor.isNodeInEditor(editor, node);
681
+ const node = AngularEditor.toSlateNode(editor, textNode, { suppressThrow });
682
+ if (node && AngularEditor.isNodeInEditor(editor, node)) {
683
+ return true;
684
+ }
685
+ else {
686
+ return false;
687
+ }
678
688
  },
679
689
  /**
680
690
  * Find a Slate point from a DOM selection's `domNode` and `domOffset`.
681
691
  */
682
- toSlatePoint(editor, domPoint) {
692
+ toSlatePoint(editor, domPoint, options) {
693
+ const { exactMatch, suppressThrow } = options;
683
694
  const [domNode] = domPoint;
684
695
  const [nearestNode, nearestOffset] = normalizeDOMPoint(domPoint);
685
696
  let parentNode = nearestNode.parentNode;
@@ -726,7 +737,7 @@ const AngularEditor = {
726
737
  let domNode = null;
727
738
  // Calculate how far into the text node the `nearestNode` is, so that we
728
739
  // can determine what the offset relative to the text node is.
729
- if (leafNode && AngularEditor.isLeafInEditor(editor, leafNode)) {
740
+ if (leafNode && AngularEditor.isLeafInEditor(editor, leafNode, { suppressThrow: true })) {
730
741
  textNode = leafNode.closest('[data-slate-node="text"]');
731
742
  const window = AngularEditor.getWindow(editor);
732
743
  const range = window.document.createRange();
@@ -768,19 +779,26 @@ const AngularEditor = {
768
779
  }
769
780
  }
770
781
  if (!textNode) {
782
+ if (suppressThrow) {
783
+ return null;
784
+ }
771
785
  throw new Error(`Cannot resolve a Slate point from DOM point: ${domPoint}`);
772
786
  }
773
787
  // COMPAT: If someone is clicking from one Slate editor into another,
774
788
  // the select event fires twice, once for the old editor's `element`
775
789
  // first, and then afterwards for the correct `element`. (2017/03/03)
776
- const slateNode = AngularEditor.toSlateNode(editor, textNode);
790
+ const slateNode = AngularEditor.toSlateNode(editor, textNode, { suppressThrow });
791
+ if (!slateNode && suppressThrow) {
792
+ return null;
793
+ }
777
794
  const path = AngularEditor.findPath(editor, slateNode);
778
795
  return { path, offset };
779
796
  },
780
797
  /**
781
798
  * Find a Slate range from a DOM range or selection.
782
799
  */
783
- toSlateRange(editor, domRange) {
800
+ toSlateRange(editor, domRange, options) {
801
+ const { exactMatch, suppressThrow } = options || {};
784
802
  const el = isDOMSelection(domRange) ? domRange.anchorNode : domRange.startContainer;
785
803
  let anchorNode;
786
804
  let anchorOffset;
@@ -815,9 +833,35 @@ const AngularEditor = {
815
833
  if (anchorNode == null || focusNode == null || anchorOffset == null || focusOffset == null) {
816
834
  throw new Error(`Cannot resolve a Slate range from DOM range: ${domRange}`);
817
835
  }
818
- const anchor = AngularEditor.toSlatePoint(editor, [anchorNode, anchorOffset]);
819
- const focus = isCollapsed ? anchor : AngularEditor.toSlatePoint(editor, [focusNode, focusOffset]);
820
- return { anchor, focus };
836
+ // COMPAT: Triple-clicking a word in chrome will sometimes place the focus
837
+ // inside a `contenteditable="false"` DOM node following the word, which
838
+ // will cause `toSlatePoint` to throw an error. (2023/03/07)
839
+ if ('getAttribute' in focusNode &&
840
+ focusNode.getAttribute('contenteditable') === 'false' &&
841
+ focusNode.getAttribute('data-slate-void') !== 'true') {
842
+ focusNode = anchorNode;
843
+ focusOffset = anchorNode.textContent?.length || 0;
844
+ }
845
+ const anchor = AngularEditor.toSlatePoint(editor, [anchorNode, anchorOffset], { suppressThrow, exactMatch });
846
+ if (!anchor) {
847
+ return null;
848
+ }
849
+ const focus = isCollapsed ? anchor : AngularEditor.toSlatePoint(editor, [focusNode, focusOffset], { suppressThrow, exactMatch });
850
+ if (!focus) {
851
+ return null;
852
+ }
853
+ let range = { anchor: anchor, focus: focus };
854
+ // if the selection is a hanging range that ends in a void
855
+ // and the DOM focus is an Element
856
+ // (meaning that the selection ends before the element)
857
+ // unhang the range to avoid mistakenly including the void
858
+ if (Range.isExpanded(range) &&
859
+ Range.isForward(range) &&
860
+ isDOMElement(focusNode) &&
861
+ Editor.void(editor, { at: range.focus, mode: 'highest' })) {
862
+ range = Editor.unhangRange(editor, range, { voids: true });
863
+ }
864
+ return range;
821
865
  },
822
866
  isLeafBlock(editor, node) {
823
867
  return Element.isElement(node) && !editor.isInline(node) && Editor.hasInlines(editor, node);
@@ -836,7 +880,7 @@ const AngularEditor = {
836
880
  },
837
881
  toSlateCardEntry(editor, node) {
838
882
  const element = node.parentElement.closest('.slate-block-card')?.querySelector('[card-target="card-center"]').firstElementChild;
839
- const slateNode = AngularEditor.toSlateNode(editor, element);
883
+ const slateNode = AngularEditor.toSlateNode(editor, element, { suppressThrow: false });
840
884
  const path = AngularEditor.findPath(editor, slateNode);
841
885
  return [slateNode, path];
842
886
  },
@@ -1009,6 +1053,24 @@ function normalize(document) {
1009
1053
  return document.filter(value => Element.isElement(value) && isValid(value));
1010
1054
  }
1011
1055
 
1056
+ const createThrottleRAF = () => {
1057
+ let timerId = null;
1058
+ const throttleRAF = (fn) => {
1059
+ const scheduleFunc = () => {
1060
+ timerId = requestAnimationFrame(() => {
1061
+ timerId = null;
1062
+ fn();
1063
+ });
1064
+ };
1065
+ if (timerId !== null) {
1066
+ cancelAnimationFrame(timerId);
1067
+ timerId = null;
1068
+ }
1069
+ scheduleFunc();
1070
+ };
1071
+ return throttleRAF;
1072
+ };
1073
+
1012
1074
  /**
1013
1075
  * Utilities for single-line deletion
1014
1076
  */
@@ -1062,7 +1124,7 @@ const withAngular = (editor, clipboardFormatKey = 'x-slate-fragment') => {
1062
1124
  }
1063
1125
  if (editor.selection && Range.isCollapsed(editor.selection)) {
1064
1126
  const parentBlockEntry = Editor.above(editor, {
1065
- match: n => Editor.isBlock(editor, n),
1127
+ match: n => Element.isElement(n) && Editor.isBlock(editor, n),
1066
1128
  at: editor.selection
1067
1129
  });
1068
1130
  if (parentBlockEntry) {
@@ -1212,7 +1274,7 @@ const withAngular = (editor, clipboardFormatKey = 'x-slate-fragment') => {
1212
1274
  }
1213
1275
  else {
1214
1276
  const node = Node.parent(editor, selection.anchor.path);
1215
- if (Editor.isVoid(editor, node)) {
1277
+ if (Element.isElement(node) && Editor.isVoid(editor, node)) {
1216
1278
  Transforms.delete(editor);
1217
1279
  }
1218
1280
  }
@@ -1255,6 +1317,7 @@ const withAngular = (editor, clipboardFormatKey = 'x-slate-fragment') => {
1255
1317
  e.onKeydown = () => { };
1256
1318
  e.onClick = () => { };
1257
1319
  e.isBlockCard = element => false;
1320
+ e.isExpanded = element => true;
1258
1321
  e.onError = (errorData) => {
1259
1322
  if (errorData.nativeError) {
1260
1323
  console.error(errorData.nativeError);
@@ -1694,8 +1757,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.1", ngImpor
1694
1757
  selector: 'slate-children',
1695
1758
  template: ``,
1696
1759
  changeDetection: ChangeDetectionStrategy.OnPush,
1697
- standalone: true,
1698
- imports: [NgFor]
1760
+ standalone: true
1699
1761
  }]
1700
1762
  }], propDecorators: { children: [{
1701
1763
  type: Input
@@ -1716,6 +1778,12 @@ function hasBeforeContextChange(value) {
1716
1778
  }
1717
1779
  return false;
1718
1780
  }
1781
+ function hasAfterContextChange(value) {
1782
+ if (value.afterContextChange) {
1783
+ return true;
1784
+ }
1785
+ return false;
1786
+ }
1719
1787
 
1720
1788
  class SlateBlockCard {
1721
1789
  get nativeElement() {
@@ -1728,7 +1796,6 @@ class SlateBlockCard {
1728
1796
  this.elementRef = elementRef;
1729
1797
  }
1730
1798
  ngOnInit() {
1731
- this.append();
1732
1799
  this.nativeElement.classList.add(`slate-block-card`);
1733
1800
  }
1734
1801
  append() {
@@ -1736,6 +1803,7 @@ class SlateBlockCard {
1736
1803
  }
1737
1804
  initializeCenter(rootNodes) {
1738
1805
  this.centerRootNodes = rootNodes;
1806
+ this.append();
1739
1807
  }
1740
1808
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.1", ngImport: i0, type: SlateBlockCard, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
1741
1809
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.1", type: SlateBlockCard, isStandalone: true, selector: "slate-block-card, [slateBlockCard]", viewQueries: [{ propertyName: "centerContianer", first: true, predicate: ["centerContianer"], descendants: true, static: true }], ngImport: i0, template: "<span card-target=\"card-left\" class=\"card-left\">{{ '\\uFEFF' }}</span>\n<div card-target=\"card-center\" #centerContianer></div>\n<span card-target=\"card-right\" class=\"card-right\">{{ '\\uFEFF' }}</span>\n" }); }
@@ -1768,12 +1836,9 @@ function createEmbeddedViewOrComponent(viewType, context, viewContext, viewConta
1768
1836
  return componentRef;
1769
1837
  }
1770
1838
  }
1771
- function renderView(view) {
1772
- if (view instanceof ComponentRef) {
1773
- view.changeDetectorRef.detectChanges();
1774
- }
1775
- else {
1776
- view.detectChanges();
1839
+ function executeAfterViewInit(view) {
1840
+ if (view instanceof ComponentRef && view.instance.afterViewInit) {
1841
+ view.instance.afterViewInit();
1777
1842
  }
1778
1843
  }
1779
1844
  function updateContext(view, newContext, viewContext) {
@@ -1789,14 +1854,20 @@ function updateContext(view, newContext, viewContext) {
1789
1854
  view.detectChanges();
1790
1855
  }
1791
1856
  }
1792
- function mount(views, blockCards, outletElement) {
1857
+ function mount(views, blockCards, outletParent, outletElement) {
1793
1858
  if (views.length > 0) {
1794
- const result = [];
1859
+ const fragment = document.createDocumentFragment();
1795
1860
  views.forEach((view, index) => {
1796
1861
  const blockCard = blockCards ? blockCards[index] : undefined;
1797
- result.push(...getRootNodes(view, blockCard));
1862
+ fragment.append(...getRootNodes(view, blockCard));
1798
1863
  });
1799
- outletElement.prepend(...result);
1864
+ if (outletElement) {
1865
+ outletElement.parentElement.insertBefore(fragment, outletElement);
1866
+ outletElement.remove();
1867
+ }
1868
+ else {
1869
+ outletParent.prepend(fragment);
1870
+ }
1800
1871
  }
1801
1872
  }
1802
1873
  function getRootNodes(ref, blockCard) {
@@ -1815,7 +1886,8 @@ function getRootNodes(ref, blockCard) {
1815
1886
  const result = [];
1816
1887
  ref.rootNodes.forEach(rootNode => {
1817
1888
  const isHTMLElement = rootNode instanceof HTMLElement;
1818
- if (isHTMLElement && result.every(item => !item.contains(rootNode))) {
1889
+ const isSlateNodeOfLeaf = isHTMLElement && (rootNode.hasAttribute('data-slate-node') || rootNode.hasAttribute('data-slate-leaf'));
1890
+ if (isSlateNodeOfLeaf && result.every(item => !item.contains(rootNode))) {
1819
1891
  result.push(rootNode);
1820
1892
  }
1821
1893
  if (!isHTMLElement) {
@@ -1825,7 +1897,7 @@ function getRootNodes(ref, blockCard) {
1825
1897
  return result;
1826
1898
  }
1827
1899
  }
1828
- function mountOnItemChange(index, item, views, blockCards, outletElement, viewContext) {
1900
+ function mountOnItemChange(index, item, views, blockCards, outletParent, firstRootNode, viewContext) {
1829
1901
  const view = views[index];
1830
1902
  let rootNodes = getRootNodes(view);
1831
1903
  if (blockCards) {
@@ -1836,7 +1908,14 @@ function mountOnItemChange(index, item, views, blockCards, outletElement, viewCo
1836
1908
  }
1837
1909
  }
1838
1910
  if (index === 0) {
1839
- outletElement.prepend(...rootNodes);
1911
+ if (firstRootNode) {
1912
+ rootNodes.forEach(rootNode => {
1913
+ firstRootNode.insertAdjacentElement('beforebegin', rootNode);
1914
+ });
1915
+ }
1916
+ else {
1917
+ outletParent.prepend(...rootNodes);
1918
+ }
1840
1919
  }
1841
1920
  else {
1842
1921
  const previousView = views[index - 1];
@@ -1851,19 +1930,23 @@ function mountOnItemChange(index, item, views, blockCards, outletElement, viewCo
1851
1930
  }
1852
1931
 
1853
1932
  class ListRender {
1854
- constructor(viewContext, viewContainerRef, getOutletElement) {
1933
+ constructor(viewContext, viewContainerRef, getOutletParent, getOutletElement) {
1855
1934
  this.viewContext = viewContext;
1856
1935
  this.viewContainerRef = viewContainerRef;
1936
+ this.getOutletParent = getOutletParent;
1857
1937
  this.getOutletElement = getOutletElement;
1858
1938
  this.views = [];
1939
+ this.addedViews = [];
1859
1940
  this.blockCards = [];
1860
1941
  this.contexts = [];
1861
1942
  this.viewTypes = [];
1943
+ this.differ = null;
1862
1944
  this.initialized = false;
1863
1945
  }
1864
- initialize(children, parent, parentPath, childrenContext) {
1946
+ initialize(children, parent, childrenContext) {
1865
1947
  this.initialized = true;
1866
1948
  this.children = children;
1949
+ const parentPath = AngularEditor.findPath(this.viewContext.editor, parent);
1867
1950
  children.forEach((descendant, index) => {
1868
1951
  NODE_TO_INDEX.set(descendant, index);
1869
1952
  NODE_TO_PARENT.set(descendant, parent);
@@ -1872,23 +1955,32 @@ class ListRender {
1872
1955
  const view = createEmbeddedViewOrComponent(viewType, context, this.viewContext, this.viewContainerRef);
1873
1956
  const blockCard = createBlockCard(descendant, view, this.viewContainerRef, this.viewContext);
1874
1957
  this.views.push(view);
1958
+ this.addedViews.push(view);
1875
1959
  this.contexts.push(context);
1876
1960
  this.viewTypes.push(viewType);
1877
1961
  this.blockCards.push(blockCard);
1878
1962
  });
1879
- mount(this.views, this.blockCards, this.getOutletElement());
1963
+ mount(this.views, this.blockCards, this.getOutletParent(), this.getOutletElement());
1880
1964
  const newDiffers = this.viewContainerRef.injector.get(IterableDiffers);
1881
1965
  this.differ = newDiffers.find(children).create(trackBy$1(this.viewContext));
1882
1966
  this.differ.diff(children);
1967
+ if (parent === this.viewContext.editor) {
1968
+ this.afterViewInit();
1969
+ }
1883
1970
  }
1884
- update(children, parent, parentPath, childrenContext) {
1885
- if (!this.initialized) {
1886
- this.initialize(children, parent, parentPath, childrenContext);
1971
+ update(children, parent, childrenContext) {
1972
+ if (!this.initialized || this.children.length === 0) {
1973
+ this.initialize(children, parent, childrenContext);
1887
1974
  return;
1888
1975
  }
1889
- const outletElement = this.getOutletElement();
1976
+ if (!this.differ) {
1977
+ throw new Error('Exception: Can not find differ ');
1978
+ }
1979
+ const outletParent = this.getOutletParent();
1890
1980
  const diffResult = this.differ.diff(children);
1981
+ const parentPath = AngularEditor.findPath(this.viewContext.editor, parent);
1891
1982
  if (diffResult) {
1983
+ let firstRootNode = getRootNodes(this.views[0], this.blockCards[0])[0];
1892
1984
  const newContexts = [];
1893
1985
  const newViewTypes = [];
1894
1986
  const newViews = [];
@@ -1906,8 +1998,9 @@ class ListRender {
1906
1998
  blockCard = createBlockCard(record.item, view, this.viewContainerRef, this.viewContext);
1907
1999
  newContexts.push(context);
1908
2000
  newViews.push(view);
2001
+ this.addedViews.push(view);
1909
2002
  newBlockCards.push(blockCard);
1910
- mountOnItemChange(record.currentIndex, record.item, newViews, newBlockCards, outletElement, this.viewContext);
2003
+ mountOnItemChange(record.currentIndex, record.item, newViews, newBlockCards, outletParent, firstRootNode, this.viewContext);
1911
2004
  }
1912
2005
  else {
1913
2006
  const previousView = this.views[record.previousIndex];
@@ -1916,6 +2009,7 @@ class ListRender {
1916
2009
  const previousBlockCard = this.blockCards[record.previousIndex];
1917
2010
  if (previousViewType !== viewType) {
1918
2011
  view = createEmbeddedViewOrComponent(viewType, context, this.viewContext, this.viewContainerRef);
2012
+ this.addedViews.push(view);
1919
2013
  blockCard = createBlockCard(record.item, view, this.viewContainerRef, this.viewContext);
1920
2014
  const firstRootNode = getRootNodes(previousView, previousBlockCard)[0];
1921
2015
  const newRootNodes = getRootNodes(view, blockCard);
@@ -1938,7 +2032,7 @@ class ListRender {
1938
2032
  newBlockCards.push(blockCard);
1939
2033
  }
1940
2034
  });
1941
- diffResult.forEachOperation((record) => {
2035
+ diffResult.forEachOperation(record => {
1942
2036
  // removed
1943
2037
  if (record.currentIndex === null) {
1944
2038
  const view = this.views[record.previousIndex];
@@ -1948,7 +2042,7 @@ class ListRender {
1948
2042
  }
1949
2043
  // moved
1950
2044
  if (record.previousIndex !== null && record.currentIndex !== null) {
1951
- mountOnItemChange(record.currentIndex, record.item, newViews, newBlockCards, outletElement, this.viewContext);
2045
+ mountOnItemChange(record.currentIndex, record.item, newViews, newBlockCards, outletParent, firstRootNode, this.viewContext);
1952
2046
  // Solve the block-card DOMElement loss when moving nodes
1953
2047
  newBlockCards[record.currentIndex]?.instance.append();
1954
2048
  }
@@ -1958,10 +2052,15 @@ class ListRender {
1958
2052
  this.contexts = newContexts;
1959
2053
  this.children = children;
1960
2054
  this.blockCards = newBlockCards;
2055
+ if (parent === this.viewContext.editor) {
2056
+ this.afterViewInit();
2057
+ }
1961
2058
  }
1962
2059
  else {
1963
2060
  const newContexts = [];
1964
2061
  this.children.forEach((child, index) => {
2062
+ NODE_TO_INDEX.set(child, index);
2063
+ NODE_TO_PARENT.set(child, parent);
1965
2064
  let context = getContext$1(index, child, parentPath, childrenContext, this.viewContext);
1966
2065
  const previousContext = this.contexts[index];
1967
2066
  if (memoizedContext(this.viewContext, child, previousContext, context)) {
@@ -1975,6 +2074,28 @@ class ListRender {
1975
2074
  this.contexts = newContexts;
1976
2075
  }
1977
2076
  }
2077
+ afterViewInit() {
2078
+ this.addedViews.forEach(view => {
2079
+ executeAfterViewInit(view);
2080
+ });
2081
+ this.addedViews = [];
2082
+ }
2083
+ destroy() {
2084
+ this.children.forEach((element, index) => {
2085
+ if (this.views[index]) {
2086
+ this.views[index].destroy();
2087
+ }
2088
+ if (this.blockCards[index]) {
2089
+ this.blockCards[index].destroy();
2090
+ }
2091
+ });
2092
+ this.views = [];
2093
+ this.blockCards = [];
2094
+ this.contexts = [];
2095
+ this.viewTypes = [];
2096
+ this.initialized = false;
2097
+ this.differ = null;
2098
+ }
1978
2099
  }
1979
2100
  function getContext$1(index, item, parentPath, childrenContext, viewContext) {
1980
2101
  if (Element.isElement(item)) {
@@ -1984,7 +2105,6 @@ function getContext$1(index, item, parentPath, childrenContext, viewContext) {
1984
2105
  const isVoid = viewContext.editor.isVoid(item);
1985
2106
  const elementContext = {
1986
2107
  element: item,
1987
- path: parentPath.concat(index),
1988
2108
  ...computedContext,
1989
2109
  attributes: {
1990
2110
  'data-slate-node': 'element',
@@ -1998,7 +2118,7 @@ function getContext$1(index, item, parentPath, childrenContext, viewContext) {
1998
2118
  }
1999
2119
  if (isVoid) {
2000
2120
  elementContext.attributes['data-slate-void'] = true;
2001
- elementContext.attributes.contenteditable = false;
2121
+ elementContext.contentEditable = false;
2002
2122
  }
2003
2123
  return elementContext;
2004
2124
  }
@@ -2035,7 +2155,7 @@ function getCommonContext(index, item, parentPath, viewContext, childrenContext)
2035
2155
  }
2036
2156
  }
2037
2157
  catch (error) {
2038
- this.options.viewContext.editor.onError({
2158
+ viewContext.editor.onError({
2039
2159
  code: SlateErrorCode.GetStartPointError,
2040
2160
  nativeError: error
2041
2161
  });
@@ -2059,6 +2179,7 @@ function createBlockCard(item, view, viewContainerRef, viewContext) {
2059
2179
  injector: viewContainerRef.injector
2060
2180
  });
2061
2181
  blockCardComponentRef.instance.initializeCenter(rootNodes);
2182
+ blockCardComponentRef.changeDetectorRef.detectChanges();
2062
2183
  return blockCardComponentRef;
2063
2184
  }
2064
2185
  else {
@@ -2093,9 +2214,10 @@ function memoizedTextContext(prev, next) {
2093
2214
  }
2094
2215
 
2095
2216
  class LeavesRender {
2096
- constructor(viewContext, viewContainerRef, getOutletElement) {
2217
+ constructor(viewContext, viewContainerRef, getOutletParent, getOutletElement) {
2097
2218
  this.viewContext = viewContext;
2098
2219
  this.viewContainerRef = viewContainerRef;
2220
+ this.getOutletParent = getOutletParent;
2099
2221
  this.getOutletElement = getOutletElement;
2100
2222
  this.views = [];
2101
2223
  this.contexts = [];
@@ -2113,16 +2235,17 @@ class LeavesRender {
2113
2235
  this.contexts.push(context);
2114
2236
  this.viewTypes.push(viewType);
2115
2237
  });
2116
- mount(this.views, null, this.getOutletElement());
2238
+ mount(this.views, null, this.getOutletParent(), this.getOutletElement());
2117
2239
  const newDiffers = this.viewContainerRef.injector.get(IterableDiffers);
2118
2240
  this.differ = newDiffers.find(this.leaves).create(trackBy(this.viewContext));
2119
2241
  this.differ.diff(this.leaves);
2120
2242
  }
2121
2243
  update(context) {
2122
2244
  const { leaves, contexts } = this.getLeaves(context);
2123
- const outletElement = this.getOutletElement();
2245
+ const outletParent = this.getOutletParent();
2124
2246
  const diffResult = this.differ.diff(leaves);
2125
2247
  if (diffResult) {
2248
+ let firstRootNode = getRootNodes(this.views[0])[0];
2126
2249
  const newContexts = [];
2127
2250
  const newViewTypes = [];
2128
2251
  const newViews = [];
@@ -2135,7 +2258,7 @@ class LeavesRender {
2135
2258
  view = createEmbeddedViewOrComponent(viewType, context, this.viewContext, this.viewContainerRef);
2136
2259
  newContexts.push(context);
2137
2260
  newViews.push(view);
2138
- mountOnItemChange(record.currentIndex, record.item, newViews, null, outletElement, this.viewContext);
2261
+ mountOnItemChange(record.currentIndex, record.item, newViews, null, outletParent, firstRootNode, this.viewContext);
2139
2262
  }
2140
2263
  else {
2141
2264
  const previousView = this.views[record.previousIndex];
@@ -2160,7 +2283,7 @@ class LeavesRender {
2160
2283
  view.destroy();
2161
2284
  });
2162
2285
  diffResult.forEachMovedItem(record => {
2163
- mountOnItemChange(record.currentIndex, record.item, newViews, null, outletElement, this.viewContext);
2286
+ mountOnItemChange(record.currentIndex, record.item, newViews, null, outletParent, firstRootNode, this.viewContext);
2164
2287
  });
2165
2288
  this.viewTypes = newViewTypes;
2166
2289
  this.views = newViews;
@@ -2194,6 +2317,26 @@ function trackBy(viewContext) {
2194
2317
  };
2195
2318
  }
2196
2319
 
2320
+ class SlateChildrenOutlet {
2321
+ constructor(elementRef) {
2322
+ this.elementRef = elementRef;
2323
+ }
2324
+ getNativeElement() {
2325
+ return this.elementRef.nativeElement;
2326
+ }
2327
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.1", ngImport: i0, type: SlateChildrenOutlet, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
2328
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.1", type: SlateChildrenOutlet, isStandalone: true, selector: "slate-children-outlet", ngImport: i0, template: ``, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2329
+ }
2330
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.1", ngImport: i0, type: SlateChildrenOutlet, decorators: [{
2331
+ type: Component,
2332
+ args: [{
2333
+ selector: 'slate-children-outlet',
2334
+ template: ``,
2335
+ changeDetection: ChangeDetectionStrategy.OnPush,
2336
+ standalone: true
2337
+ }]
2338
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }]; } });
2339
+
2197
2340
  /**
2198
2341
  * base class for custom element component or text component
2199
2342
  */
@@ -2204,6 +2347,12 @@ class BaseComponent {
2204
2347
  }
2205
2348
  this._context = value;
2206
2349
  this.onContextChange();
2350
+ if (this.initialized) {
2351
+ this.cdr.detectChanges();
2352
+ }
2353
+ if (hasAfterContextChange(this)) {
2354
+ this.afterContextChange();
2355
+ }
2207
2356
  }
2208
2357
  get context() {
2209
2358
  return this._context;
@@ -2217,6 +2366,7 @@ class BaseComponent {
2217
2366
  constructor(elementRef, cdr) {
2218
2367
  this.elementRef = elementRef;
2219
2368
  this.cdr = cdr;
2369
+ this.initialized = false;
2220
2370
  }
2221
2371
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.1", ngImport: i0, type: BaseComponent, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive }); }
2222
2372
  static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.1", type: BaseComponent, inputs: { context: "context", viewContext: "viewContext" }, ngImport: i0 }); }
@@ -2234,7 +2384,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.1", ngImpor
2234
2384
  class BaseLeafComponent extends BaseComponent {
2235
2385
  constructor() {
2236
2386
  super(...arguments);
2237
- this.initialized = false;
2238
2387
  this.isSlateLeaf = true;
2239
2388
  }
2240
2389
  get text() {
@@ -2250,7 +2399,6 @@ class BaseLeafComponent extends BaseComponent {
2250
2399
  if (!this.initialized) {
2251
2400
  return;
2252
2401
  }
2253
- this.cdr.detectChanges();
2254
2402
  }
2255
2403
  renderPlaceholder() {
2256
2404
  // issue-1: IME input was interrupted
@@ -2303,10 +2451,15 @@ class BaseElementComponent extends BaseComponent {
2303
2451
  constructor() {
2304
2452
  super(...arguments);
2305
2453
  this.viewContainerRef = inject(ViewContainerRef);
2306
- this.initialized = false;
2307
- this.getOutletElement = () => {
2454
+ this.getOutletParent = () => {
2308
2455
  return this.elementRef.nativeElement;
2309
2456
  };
2457
+ this.getOutletElement = () => {
2458
+ if (this.childrenOutletInstance) {
2459
+ return this.childrenOutletInstance.getNativeElement();
2460
+ }
2461
+ return null;
2462
+ };
2310
2463
  }
2311
2464
  get element() {
2312
2465
  return this._context && this._context.element;
@@ -2314,9 +2467,6 @@ class BaseElementComponent extends BaseComponent {
2314
2467
  get selection() {
2315
2468
  return this._context && this._context.selection;
2316
2469
  }
2317
- get path() {
2318
- return this._context && this._context.path;
2319
- }
2320
2470
  get decorations() {
2321
2471
  return this._context && this._context.decorations;
2322
2472
  }
@@ -2337,8 +2487,16 @@ class BaseElementComponent extends BaseComponent {
2337
2487
  this.nativeElement.setAttribute(key, this._context.attributes[key]);
2338
2488
  }
2339
2489
  this.initialized = true;
2340
- this.listRender = new ListRender(this.viewContext, this.viewContainerRef, this.getOutletElement);
2341
- this.listRender.initialize(this.children, this.element, this.path, this.childrenContext);
2490
+ this.listRender = new ListRender(this.viewContext, this.viewContainerRef, this.getOutletParent, this.getOutletElement);
2491
+ if (this.editor.isExpanded(this.element)) {
2492
+ this.listRender.initialize(this.children, this.element, this.childrenContext);
2493
+ }
2494
+ }
2495
+ afterViewInit() {
2496
+ if (this._context.contentEditable !== undefined) {
2497
+ this.nativeElement.setAttribute('contenteditable', this._context.contentEditable + '');
2498
+ }
2499
+ this.listRender.afterViewInit();
2342
2500
  }
2343
2501
  updateWeakMap() {
2344
2502
  NODE_TO_ELEMENT.set(this.element, this.nativeElement);
@@ -2349,6 +2507,7 @@ class BaseElementComponent extends BaseComponent {
2349
2507
  if (NODE_TO_ELEMENT.get(this.element) === this.nativeElement) {
2350
2508
  NODE_TO_ELEMENT.delete(this.element);
2351
2509
  }
2510
+ ELEMENT_TO_NODE.delete(this.nativeElement);
2352
2511
  if (ELEMENT_TO_COMPONENT.get(this.element) === this) {
2353
2512
  ELEMENT_TO_COMPONENT.delete(this.element);
2354
2513
  }
@@ -2359,8 +2518,17 @@ class BaseElementComponent extends BaseComponent {
2359
2518
  if (!this.initialized) {
2360
2519
  return;
2361
2520
  }
2362
- this.listRender.update(this.children, this.element, this.path, this.childrenContext);
2363
- this.cdr.detectChanges();
2521
+ this.updateChildrenView();
2522
+ }
2523
+ updateChildrenView() {
2524
+ if (this.editor.isExpanded(this.element)) {
2525
+ this.listRender.update(this.children, this.element, this.childrenContext);
2526
+ }
2527
+ else {
2528
+ if (this.listRender.initialized) {
2529
+ this.listRender.destroy();
2530
+ }
2531
+ }
2364
2532
  }
2365
2533
  getChildrenContext() {
2366
2534
  return {
@@ -2372,29 +2540,37 @@ class BaseElementComponent extends BaseComponent {
2372
2540
  };
2373
2541
  }
2374
2542
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.1", ngImport: i0, type: BaseElementComponent, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
2375
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.1", type: BaseElementComponent, usesInheritance: true, ngImport: i0 }); }
2543
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.1", type: BaseElementComponent, viewQueries: [{ propertyName: "childrenOutletInstance", first: true, predicate: SlateChildrenOutlet, descendants: true, static: true }], usesInheritance: true, ngImport: i0 }); }
2376
2544
  }
2377
2545
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.1", ngImport: i0, type: BaseElementComponent, decorators: [{
2378
2546
  type: Directive
2379
- }] });
2547
+ }], propDecorators: { childrenOutletInstance: [{
2548
+ type: ViewChild,
2549
+ args: [SlateChildrenOutlet, { static: true }]
2550
+ }] } });
2380
2551
  /**
2381
2552
  * base class for custom text component
2382
2553
  */
2383
2554
  class BaseTextComponent extends BaseComponent {
2384
2555
  constructor() {
2385
2556
  super(...arguments);
2386
- this.initialized = false;
2387
2557
  this.viewContainerRef = inject(ViewContainerRef);
2388
- this.getOutletElement = () => {
2558
+ this.getOutletParent = () => {
2389
2559
  return this.elementRef.nativeElement;
2390
2560
  };
2561
+ this.getOutletElement = () => {
2562
+ if (this.childrenOutletInstance) {
2563
+ return this.childrenOutletInstance.getNativeElement();
2564
+ }
2565
+ return null;
2566
+ };
2391
2567
  }
2392
2568
  get text() {
2393
2569
  return this._context && this._context.text;
2394
2570
  }
2395
2571
  ngOnInit() {
2396
2572
  this.initialized = true;
2397
- this.leavesRender = new LeavesRender(this.viewContext, this.viewContainerRef, this.getOutletElement);
2573
+ this.leavesRender = new LeavesRender(this.viewContext, this.viewContainerRef, this.getOutletParent, this.getOutletElement);
2398
2574
  this.leavesRender.initialize(this.context);
2399
2575
  }
2400
2576
  updateWeakMap() {
@@ -2405,6 +2581,7 @@ class BaseTextComponent extends BaseComponent {
2405
2581
  if (NODE_TO_ELEMENT.get(this.text) === this.nativeElement) {
2406
2582
  NODE_TO_ELEMENT.delete(this.text);
2407
2583
  }
2584
+ ELEMENT_TO_NODE.delete(this.nativeElement);
2408
2585
  }
2409
2586
  onContextChange() {
2410
2587
  this.updateWeakMap();
@@ -2412,14 +2589,16 @@ class BaseTextComponent extends BaseComponent {
2412
2589
  return;
2413
2590
  }
2414
2591
  this.leavesRender.update(this.context);
2415
- this.cdr.detectChanges();
2416
2592
  }
2417
2593
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.1", ngImport: i0, type: BaseTextComponent, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
2418
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.1", type: BaseTextComponent, usesInheritance: true, ngImport: i0 }); }
2594
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.1", type: BaseTextComponent, viewQueries: [{ propertyName: "childrenOutletInstance", first: true, predicate: SlateChildrenOutlet, descendants: true, static: true }], usesInheritance: true, ngImport: i0 }); }
2419
2595
  }
2420
2596
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.1", ngImport: i0, type: BaseTextComponent, decorators: [{
2421
2597
  type: Directive
2422
- }] });
2598
+ }], propDecorators: { childrenOutletInstance: [{
2599
+ type: ViewChild,
2600
+ args: [SlateChildrenOutlet, { static: true }]
2601
+ }] } });
2423
2602
 
2424
2603
  class SlateLeaves extends ViewContainer {
2425
2604
  constructor() {
@@ -2444,17 +2623,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.1", ngImpor
2444
2623
 
2445
2624
  class SlateVoidText extends BaseTextComponent {
2446
2625
  ngOnInit() {
2447
- this.isLeafBlock = AngularEditor.isLeafBlock(this.viewContext.editor, this.context.parent);
2448
2626
  super.ngOnInit();
2449
2627
  }
2450
2628
  ngOnChanges() {
2451
2629
  if (!this.initialized) {
2452
2630
  return;
2453
2631
  }
2454
- this.isLeafBlock = AngularEditor.isLeafBlock(this.viewContext.editor, this.context.parent);
2455
2632
  }
2456
2633
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.1", ngImport: i0, type: SlateVoidText, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
2457
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.1", type: SlateVoidText, isStandalone: true, selector: "span[slateVoidText]", host: { attributes: { "data-slate-spacer": "true", "data-slate-node": "text" }, properties: { "attr.contenteditable": "isLeafBlock" }, classAttribute: "slate-spacer" }, usesInheritance: true, usesOnChanges: true, ngImport: i0, template: ``, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2634
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.1", type: SlateVoidText, isStandalone: true, selector: "span[slateVoidText]", host: { attributes: { "data-slate-spacer": "true", "data-slate-node": "text" }, classAttribute: "slate-spacer" }, usesInheritance: true, usesOnChanges: true, ngImport: i0, template: ``, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2458
2635
  }
2459
2636
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.1", ngImport: i0, type: SlateVoidText, decorators: [{
2460
2637
  type: Component,
@@ -2463,7 +2640,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.1", ngImpor
2463
2640
  template: ``,
2464
2641
  changeDetection: ChangeDetectionStrategy.OnPush,
2465
2642
  host: {
2466
- '[attr.contenteditable]': 'isLeafBlock',
2467
2643
  'data-slate-spacer': 'true',
2468
2644
  class: 'slate-spacer',
2469
2645
  'data-slate-node': 'text'
@@ -2819,6 +2995,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.1", ngImpor
2819
2995
 
2820
2996
  const SLATE_DEFAULT_LEAF_COMPONENT_TOKEN = new InjectionToken('slate-default-leaf-token');
2821
2997
 
2998
+ const TRIPLE_CLICK = 3;
2999
+
2822
3000
  // not correctly clipboardData on beforeinput
2823
3001
  const forceOnDOMPaste = IS_SAFARI;
2824
3002
  class SlateEditable {
@@ -2857,7 +3035,7 @@ class SlateEditable {
2857
3035
  this.dataSlateNode = 'value';
2858
3036
  this.dataGramm = false;
2859
3037
  this.viewContainerRef = inject(ViewContainerRef);
2860
- this.getOutletElement = () => {
3038
+ this.getOutletParent = () => {
2861
3039
  return this.elementRef.nativeElement;
2862
3040
  };
2863
3041
  }
@@ -2885,7 +3063,7 @@ class SlateEditable {
2885
3063
  // add browser class
2886
3064
  let browserClass = IS_FIREFOX ? 'firefox' : IS_SAFARI ? 'safari' : '';
2887
3065
  browserClass && this.elementRef.nativeElement.classList.add(browserClass);
2888
- this.listRender = new ListRender(this.viewContext, this.viewContainerRef, this.getOutletElement);
3066
+ this.listRender = new ListRender(this.viewContext, this.viewContainerRef, this.getOutletParent, () => null);
2889
3067
  }
2890
3068
  ngOnChanges(simpleChanges) {
2891
3069
  if (!this.initialized) {
@@ -2927,10 +3105,10 @@ class SlateEditable {
2927
3105
  }
2928
3106
  this.initializeContext();
2929
3107
  if (!this.listRender.initialized) {
2930
- this.listRender.initialize(this.editor.children, this.editor, [], this.context);
3108
+ this.listRender.initialize(this.editor.children, this.editor, this.context);
2931
3109
  }
2932
3110
  else {
2933
- this.listRender.update(this.editor.children, this.editor, [], this.context);
3111
+ this.listRender.update(this.editor.children, this.editor, this.context);
2934
3112
  }
2935
3113
  this.cdr.markForCheck();
2936
3114
  }
@@ -2984,12 +3162,11 @@ class SlateEditable {
2984
3162
  hasDomSelectionInEditor = true;
2985
3163
  }
2986
3164
  // If the DOM selection is in the editor and the editor selection is already correct, we're done.
2987
- if (hasDomSelection &&
2988
- hasDomSelectionInEditor &&
2989
- selection &&
2990
- hasStringTarget(domSelection) &&
2991
- Range.equals(AngularEditor.toSlateRange(this.editor, domSelection), selection)) {
2992
- return;
3165
+ if (hasDomSelection && hasDomSelectionInEditor && selection && hasStringTarget(domSelection)) {
3166
+ const rangeFromDOMSelection = AngularEditor.toSlateRange(this.editor, domSelection, { suppressThrow: true });
3167
+ if (rangeFromDOMSelection && Range.equals(rangeFromDOMSelection, selection)) {
3168
+ return;
3169
+ }
2993
3170
  }
2994
3171
  // prevent updating native selection when active element is void element
2995
3172
  if (isTargetInsideVoid(this.editor, activeElement)) {
@@ -3000,7 +3177,7 @@ class SlateEditable {
3000
3177
  // but Slate's value is not being updated through any operation
3001
3178
  // and thus it doesn't transform selection on its own
3002
3179
  if (selection && !AngularEditor.hasRange(this.editor, selection)) {
3003
- this.editor.selection = AngularEditor.toSlateRange(this.editor, domSelection);
3180
+ this.editor.selection = AngularEditor.toSlateRange(this.editor, domSelection, { suppressThrow: false });
3004
3181
  return;
3005
3182
  }
3006
3183
  // Otherwise the DOM selection is out of sync, so update it.
@@ -3048,7 +3225,7 @@ class SlateEditable {
3048
3225
  ngDoCheck() { }
3049
3226
  forceRender() {
3050
3227
  this.updateContext();
3051
- this.listRender.update(this.editor.children, this.editor, [], this.context);
3228
+ this.listRender.update(this.editor.children, this.editor, this.context);
3052
3229
  // repair collaborative editing when Chinese input is interrupted by other users' cursors
3053
3230
  // when the DOMElement where the selection is located is removed
3054
3231
  // the compositionupdate and compositionend events will no longer be fired
@@ -3087,7 +3264,7 @@ class SlateEditable {
3087
3264
  render() {
3088
3265
  const changed = this.updateContext();
3089
3266
  if (changed) {
3090
- this.listRender.update(this.editor.children, this.editor, [], this.context);
3267
+ this.listRender.update(this.editor.children, this.editor, this.context);
3091
3268
  }
3092
3269
  }
3093
3270
  updateContext() {
@@ -3422,7 +3599,23 @@ class SlateEditable {
3422
3599
  const end = Editor.end(this.editor, path);
3423
3600
  const startVoid = Editor.void(this.editor, { at: start });
3424
3601
  const endVoid = Editor.void(this.editor, { at: end });
3425
- if (startVoid && endVoid && Path.equals(startVoid[1], endVoid[1])) {
3602
+ if (event.detail === TRIPLE_CLICK && path.length >= 1) {
3603
+ let blockPath = path;
3604
+ if (!(Element.isElement(node) && Editor.isBlock(this.editor, node))) {
3605
+ const block = Editor.above(this.editor, {
3606
+ match: n => Element.isElement(n) && Editor.isBlock(this.editor, n),
3607
+ at: path
3608
+ });
3609
+ blockPath = block?.[1] ?? path.slice(0, 1);
3610
+ }
3611
+ const range = Editor.range(this.editor, blockPath);
3612
+ Transforms.select(this.editor, range);
3613
+ return;
3614
+ }
3615
+ if (startVoid &&
3616
+ endVoid &&
3617
+ Path.equals(startVoid[1], endVoid[1]) &&
3618
+ !(AngularEditor.isBlockCardLeftCursor(this.editor) || AngularEditor.isBlockCardRightCursor(this.editor))) {
3426
3619
  const range = Editor.range(this.editor, start);
3427
3620
  Transforms.select(this.editor, range);
3428
3621
  }
@@ -3488,7 +3681,7 @@ class SlateEditable {
3488
3681
  // that drops are allowed. Editable content is droppable by
3489
3682
  // default, and calling `preventDefault` hides the cursor.
3490
3683
  const node = AngularEditor.toSlateNode(this.editor, event.target);
3491
- if (Editor.isVoid(this.editor, node)) {
3684
+ if (Element.isElement(node) && Editor.isVoid(this.editor, node)) {
3492
3685
  event.preventDefault();
3493
3686
  }
3494
3687
  }
@@ -3497,7 +3690,7 @@ class SlateEditable {
3497
3690
  if (!this.readonly && hasTarget(this.editor, event.target) && !this.isDOMEventHandled(event, this.dragStart)) {
3498
3691
  const node = AngularEditor.toSlateNode(this.editor, event.target);
3499
3692
  const path = AngularEditor.findPath(this.editor, node);
3500
- const voidMatch = Editor.isVoid(this.editor, node) || Editor.void(this.editor, { at: path, voids: true });
3693
+ const voidMatch = Element.isElement(node) && (Editor.isVoid(this.editor, node) || Editor.void(this.editor, { at: path, voids: true }));
3501
3694
  // If starting a drag on a void node, make sure it is selected
3502
3695
  // so that it shows up in the selection's fragment.
3503
3696
  if (voidMatch) {
@@ -3759,7 +3952,7 @@ class SlateEditable {
3759
3952
  const currentNode = Node.parent(editor, selection.anchor.path);
3760
3953
  if (Element.isElement(currentNode) &&
3761
3954
  Editor.isVoid(editor, currentNode) &&
3762
- Editor.isInline(editor, currentNode)) {
3955
+ (Editor.isInline(editor, currentNode) || Editor.isBlock(editor, currentNode))) {
3763
3956
  event.preventDefault();
3764
3957
  Editor.deleteBackward(editor, {
3765
3958
  unit: 'block'
@@ -4019,8 +4212,8 @@ const hasTarget = (editor, target) => {
4019
4212
  * Check if the target is inside void and in the editor.
4020
4213
  */
4021
4214
  const isTargetInsideVoid = (editor, target) => {
4022
- const slateNode = hasTarget(editor, target) && AngularEditor.toSlateNode(editor, target);
4023
- return Editor.isVoid(editor, slateNode);
4215
+ const slateNode = hasTarget(editor, target) && AngularEditor.toSlateNode(editor, target, { suppressThrow: true });
4216
+ return slateNode && Element.isElement(slateNode) && Editor.isVoid(editor, slateNode);
4024
4217
  };
4025
4218
  const hasStringTarget = (domSelection) => {
4026
4219
  return ((domSelection.anchorNode.parentElement.hasAttribute('data-slate-string') ||
@@ -4076,12 +4269,8 @@ class SlateModule {
4076
4269
  SlateBlockCard,
4077
4270
  SlateLeaves,
4078
4271
  SlateDefaultLeaf,
4079
- SlateDefaultString], exports: [SlateEditable,
4080
- SlateChildren,
4081
- SlateElement,
4082
- SlateLeaves,
4083
- SlateString,
4084
- SlateDefaultString] }); }
4272
+ SlateDefaultString,
4273
+ SlateChildrenOutlet], exports: [SlateEditable, SlateChildren, SlateChildrenOutlet, SlateElement, SlateLeaves, SlateString, SlateDefaultString] }); }
4085
4274
  static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.2.1", ngImport: i0, type: SlateModule, providers: [
4086
4275
  {
4087
4276
  provide: SLATE_DEFAULT_ELEMENT_COMPONENT_TOKEN,
@@ -4105,16 +4294,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.1", ngImpor
4105
4294
  SlateBlockCard,
4106
4295
  SlateLeaves,
4107
4296
  SlateDefaultLeaf,
4108
- SlateDefaultString
4109
- ],
4110
- exports: [
4111
- SlateEditable,
4112
- SlateChildren,
4113
- SlateElement,
4114
- SlateLeaves,
4115
- SlateString,
4116
- SlateDefaultString
4297
+ SlateDefaultString,
4298
+ SlateChildrenOutlet
4117
4299
  ],
4300
+ exports: [SlateEditable, SlateChildren, SlateChildrenOutlet, SlateElement, SlateLeaves, SlateString, SlateDefaultString],
4118
4301
  providers: [
4119
4302
  {
4120
4303
  provide: SLATE_DEFAULT_ELEMENT_COMPONENT_TOKEN,
@@ -4132,5 +4315,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.1", ngImpor
4132
4315
  * Generated bundle index. Do not edit.
4133
4316
  */
4134
4317
 
4135
- export { AngularEditor, BaseComponent, BaseElementComponent, BaseLeafComponent, BaseTextComponent, DOMComment, DOMElement, DOMNode, DOMRange, DOMSelection, DOMStaticRange, DOMText, EDITOR_TO_ELEMENT, EDITOR_TO_ON_CHANGE, EDITOR_TO_PLACEHOLDER, EDITOR_TO_WINDOW, ELEMENT_TO_COMPONENT, ELEMENT_TO_NODE, FAKE_LEFT_BLOCK_CARD_OFFSET, FAKE_RIGHT_BLOCK_CARD_OFFSET, HAS_BEFORE_INPUT_SUPPORT, IS_ANDROID, IS_APPLE, IS_CHROME, IS_CHROME_LEGACY, IS_CLICKING, IS_DRAGGING, IS_EDGE_LEGACY, IS_FIREFOX, IS_FIREFOX_LEGACY, IS_FOCUSED, IS_IOS, IS_QQBROWSER, IS_READONLY, IS_SAFARI, IS_UC_MOBILE, IS_WECHATBROWSER, KEY_TO_ELEMENT, Key, NODE_TO_ELEMENT, NODE_TO_INDEX, NODE_TO_KEY, NODE_TO_PARENT, PLACEHOLDER_SYMBOL, SlateChildren, SlateDefaultString, SlateEditable, SlateElement, SlateErrorCode, SlateLeaves, SlateModule, SlateString, check, defaultScrollSelectionIntoView, getCardTargetAttribute, getClipboardData, getDefaultView, getEditableChild, getEditableChildAndIndex, getPlainText, getSlateFragmentAttribute, hasBeforeContextChange, hasBlockCard, hasBlockCardWithNode, hasEditableTarget, hasShadowRoot, hotkeys, isCardCenterByTargetAttr, isCardLeft, isCardLeftByTargetAttr, isCardRightByTargetAttr, isComponentType, isDOMComment, isDOMElement, isDOMNode, isDOMSelection, isDOMText, isDecoratorRangeListEqual, isEmpty, isPlainTextOnlyPaste, isTemplateRef, isValid, normalize, normalizeDOMPoint, shallowCompare, withAngular };
4318
+ export { AngularEditor, BaseComponent, BaseElementComponent, BaseLeafComponent, BaseTextComponent, DOMComment, DOMElement, DOMNode, DOMRange, DOMSelection, DOMStaticRange, DOMText, EDITOR_TO_ELEMENT, EDITOR_TO_ON_CHANGE, EDITOR_TO_PLACEHOLDER, EDITOR_TO_WINDOW, ELEMENT_TO_COMPONENT, ELEMENT_TO_NODE, FAKE_LEFT_BLOCK_CARD_OFFSET, FAKE_RIGHT_BLOCK_CARD_OFFSET, HAS_BEFORE_INPUT_SUPPORT, IS_ANDROID, IS_APPLE, IS_CHROME, IS_CHROME_LEGACY, IS_CLICKING, IS_DRAGGING, IS_EDGE_LEGACY, IS_FIREFOX, IS_FIREFOX_LEGACY, IS_FOCUSED, IS_IOS, IS_QQBROWSER, IS_READONLY, IS_SAFARI, IS_UC_MOBILE, IS_WECHATBROWSER, KEY_TO_ELEMENT, Key, NODE_TO_ELEMENT, NODE_TO_INDEX, NODE_TO_KEY, NODE_TO_PARENT, PLACEHOLDER_SYMBOL, SlateChildren, SlateChildrenOutlet, SlateDefaultString, SlateEditable, SlateElement, SlateErrorCode, SlateLeaves, SlateModule, SlateString, check, createThrottleRAF, defaultScrollSelectionIntoView, getCardTargetAttribute, getClipboardData, getDefaultView, getEditableChild, getEditableChildAndIndex, getPlainText, getSlateFragmentAttribute, hasAfterContextChange, hasBeforeContextChange, hasBlockCard, hasBlockCardWithNode, hasEditableTarget, hasShadowRoot, hotkeys, isCardCenterByTargetAttr, isCardLeft, isCardLeftByTargetAttr, isCardRightByTargetAttr, isComponentType, isDOMComment, isDOMElement, isDOMNode, isDOMSelection, isDOMText, isDecoratorRangeListEqual, isEmpty, isPlainTextOnlyPaste, isTemplateRef, isValid, normalize, normalizeDOMPoint, shallowCompare, withAngular };
4136
4319
  //# sourceMappingURL=slate-angular.mjs.map