slate-angular 16.1.0-next.0 → 16.1.0-next.10

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 (40) hide show
  1. package/components/children/children-outlet.component.d.ts +9 -0
  2. package/components/editable/editable.component.d.ts +1 -2
  3. package/components/string/default-string.component.d.ts +1 -1
  4. package/esm2022/components/block-card/block-card.component.mjs +2 -2
  5. package/esm2022/components/children/children-outlet.component.mjs +22 -0
  6. package/esm2022/components/children/children.component.mjs +2 -4
  7. package/esm2022/components/editable/editable.component.mjs +26 -18
  8. package/esm2022/components/leaf/token.mjs +1 -1
  9. package/esm2022/components/string/default-string.component.mjs +1 -1
  10. package/esm2022/components/string/string.component.mjs +1 -1
  11. package/esm2022/components/text/token.mjs +1 -1
  12. package/esm2022/module.mjs +7 -16
  13. package/esm2022/plugins/angular-editor.mjs +28 -7
  14. package/esm2022/plugins/with-angular.mjs +4 -4
  15. package/esm2022/public-api.mjs +3 -2
  16. package/esm2022/utils/constants.mjs +2 -0
  17. package/esm2022/utils/index.mjs +2 -1
  18. package/esm2022/utils/throttle.mjs +1 -1
  19. package/esm2022/view/base.mjs +39 -22
  20. package/esm2022/view/container.mjs +1 -1
  21. package/esm2022/view/context-change.mjs +13 -0
  22. package/esm2022/view/context.mjs +1 -1
  23. package/esm2022/view/render/leaves-render.mjs +8 -6
  24. package/esm2022/view/render/list-render.mjs +14 -12
  25. package/esm2022/view/render/utils.mjs +20 -7
  26. package/fesm2022/slate-angular.mjs +181 -102
  27. package/fesm2022/slate-angular.mjs.map +1 -1
  28. package/module.d.ts +2 -1
  29. package/package.json +7 -7
  30. package/plugins/angular-editor.d.ts +1 -1
  31. package/public-api.d.ts +2 -1
  32. package/utils/constants.d.ts +1 -0
  33. package/utils/index.d.ts +1 -0
  34. package/view/base.d.ts +9 -7
  35. package/view/{before-context-change.d.ts → context-change.d.ts} +4 -0
  36. package/view/context.d.ts +1 -3
  37. package/view/render/leaves-render.d.ts +2 -1
  38. package/view/render/list-render.d.ts +4 -3
  39. package/view/render/utils.d.ts +2 -2
  40. 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
  },
@@ -637,7 +637,7 @@ const AngularEditor = {
637
637
  // If the drop target is inside a void node, move it into either the
638
638
  // next or previous node, depending on which side the `x` and `y`
639
639
  // coordinates are closest to.
640
- if (Editor.isVoid(editor, node)) {
640
+ if (Element.isElement(node) && Editor.isVoid(editor, node)) {
641
641
  const rect = target.getBoundingClientRect();
642
642
  const isPrev = editor.isInline(node) ? x - rect.left < rect.left + rect.width - x : y - rect.top < rect.top + rect.height - y;
643
643
  const edge = Editor.point(editor, path, {
@@ -751,9 +751,10 @@ const AngularEditor = {
751
751
  else if (voidNode) {
752
752
  // For void nodes, the element with the offset key will be a cousin, not an
753
753
  // ancestor, so find it by going down from the nearest void parent.
754
- leafNode = voidNode.querySelector('[data-slate-leaf]');
755
- parentNode = voidNode.querySelector('[data-slate-length="0"]');
756
- textNode = leafNode.closest('[data-slate-node="text"]');
754
+ const spacer = voidNode.querySelector('[data-slate-spacer="true"]');
755
+ leafNode = spacer.firstElementChild;
756
+ parentNode = leafNode.firstElementChild;
757
+ textNode = spacer;
757
758
  domNode = leafNode;
758
759
  offset = domNode.textContent.length;
759
760
  }
@@ -814,9 +815,29 @@ const AngularEditor = {
814
815
  if (anchorNode == null || focusNode == null || anchorOffset == null || focusOffset == null) {
815
816
  throw new Error(`Cannot resolve a Slate range from DOM range: ${domRange}`);
816
817
  }
818
+ // COMPAT: Triple-clicking a word in chrome will sometimes place the focus
819
+ // inside a `contenteditable="false"` DOM node following the word, which
820
+ // will cause `toSlatePoint` to throw an error. (2023/03/07)
821
+ if ('getAttribute' in focusNode &&
822
+ focusNode.getAttribute('contenteditable') === 'false' &&
823
+ focusNode.getAttribute('data-slate-void') !== 'true') {
824
+ focusNode = anchorNode;
825
+ focusOffset = anchorNode.textContent?.length || 0;
826
+ }
817
827
  const anchor = AngularEditor.toSlatePoint(editor, [anchorNode, anchorOffset]);
818
828
  const focus = isCollapsed ? anchor : AngularEditor.toSlatePoint(editor, [focusNode, focusOffset]);
819
- return { anchor, focus };
829
+ let range = { anchor: anchor, focus: focus };
830
+ // if the selection is a hanging range that ends in a void
831
+ // and the DOM focus is an Element
832
+ // (meaning that the selection ends before the element)
833
+ // unhang the range to avoid mistakenly including the void
834
+ if (Range.isExpanded(range) &&
835
+ Range.isForward(range) &&
836
+ isDOMElement(focusNode) &&
837
+ Editor.void(editor, { at: range.focus, mode: 'highest' })) {
838
+ range = Editor.unhangRange(editor, range, { voids: true });
839
+ }
840
+ return range;
820
841
  },
821
842
  isLeafBlock(editor, node) {
822
843
  return Element.isElement(node) && !editor.isInline(node) && Editor.hasInlines(editor, node);
@@ -1008,6 +1029,24 @@ function normalize(document) {
1008
1029
  return document.filter(value => Element.isElement(value) && isValid(value));
1009
1030
  }
1010
1031
 
1032
+ const createThrottleRAF = () => {
1033
+ let timerId = null;
1034
+ const throttleRAF = (fn) => {
1035
+ const scheduleFunc = () => {
1036
+ timerId = requestAnimationFrame(() => {
1037
+ timerId = null;
1038
+ fn();
1039
+ });
1040
+ };
1041
+ if (timerId !== null) {
1042
+ cancelAnimationFrame(timerId);
1043
+ timerId = null;
1044
+ }
1045
+ scheduleFunc();
1046
+ };
1047
+ return throttleRAF;
1048
+ };
1049
+
1011
1050
  /**
1012
1051
  * Utilities for single-line deletion
1013
1052
  */
@@ -1061,7 +1100,7 @@ const withAngular = (editor, clipboardFormatKey = 'x-slate-fragment') => {
1061
1100
  }
1062
1101
  if (editor.selection && Range.isCollapsed(editor.selection)) {
1063
1102
  const parentBlockEntry = Editor.above(editor, {
1064
- match: n => Editor.isBlock(editor, n),
1103
+ match: n => Element.isElement(n) && Editor.isBlock(editor, n),
1065
1104
  at: editor.selection
1066
1105
  });
1067
1106
  if (parentBlockEntry) {
@@ -1211,7 +1250,7 @@ const withAngular = (editor, clipboardFormatKey = 'x-slate-fragment') => {
1211
1250
  }
1212
1251
  else {
1213
1252
  const node = Node.parent(editor, selection.anchor.path);
1214
- if (Editor.isVoid(editor, node)) {
1253
+ if (Element.isElement(node) && Editor.isVoid(editor, node)) {
1215
1254
  Transforms.delete(editor);
1216
1255
  }
1217
1256
  }
@@ -1693,8 +1732,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.1", ngImpor
1693
1732
  selector: 'slate-children',
1694
1733
  template: ``,
1695
1734
  changeDetection: ChangeDetectionStrategy.OnPush,
1696
- standalone: true,
1697
- imports: [NgFor]
1735
+ standalone: true
1698
1736
  }]
1699
1737
  }], propDecorators: { children: [{
1700
1738
  type: Input
@@ -1715,6 +1753,12 @@ function hasBeforeContextChange(value) {
1715
1753
  }
1716
1754
  return false;
1717
1755
  }
1756
+ function hasAfterContextChange(value) {
1757
+ if (value.afterContextChange) {
1758
+ return true;
1759
+ }
1760
+ return false;
1761
+ }
1718
1762
 
1719
1763
  class SlateBlockCard {
1720
1764
  get nativeElement() {
@@ -1727,7 +1771,6 @@ class SlateBlockCard {
1727
1771
  this.elementRef = elementRef;
1728
1772
  }
1729
1773
  ngOnInit() {
1730
- this.append();
1731
1774
  this.nativeElement.classList.add(`slate-block-card`);
1732
1775
  }
1733
1776
  append() {
@@ -1735,6 +1778,7 @@ class SlateBlockCard {
1735
1778
  }
1736
1779
  initializeCenter(rootNodes) {
1737
1780
  this.centerRootNodes = rootNodes;
1781
+ this.append();
1738
1782
  }
1739
1783
  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 }); }
1740
1784
  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" }); }
@@ -1788,14 +1832,20 @@ function updateContext(view, newContext, viewContext) {
1788
1832
  view.detectChanges();
1789
1833
  }
1790
1834
  }
1791
- function mount(views, blockCards, outletElement) {
1835
+ function mount(views, blockCards, outletParent, outletElement) {
1792
1836
  if (views.length > 0) {
1793
- const result = [];
1837
+ const fragment = document.createDocumentFragment();
1794
1838
  views.forEach((view, index) => {
1795
1839
  const blockCard = blockCards ? blockCards[index] : undefined;
1796
- result.push(...getRootNodes(view, blockCard));
1840
+ fragment.append(...getRootNodes(view, blockCard));
1797
1841
  });
1798
- outletElement.append(...result);
1842
+ if (outletElement) {
1843
+ outletElement.parentElement.insertBefore(fragment, outletElement);
1844
+ outletElement.remove();
1845
+ }
1846
+ else {
1847
+ outletParent.prepend(fragment);
1848
+ }
1799
1849
  }
1800
1850
  }
1801
1851
  function getRootNodes(ref, blockCard) {
@@ -1824,7 +1874,7 @@ function getRootNodes(ref, blockCard) {
1824
1874
  return result;
1825
1875
  }
1826
1876
  }
1827
- function mountOnItemChange(index, item, views, blockCards, outletElement, viewContext) {
1877
+ function mountOnItemChange(index, item, views, blockCards, outletParent, firstRootNode, viewContext) {
1828
1878
  const view = views[index];
1829
1879
  let rootNodes = getRootNodes(view);
1830
1880
  if (blockCards) {
@@ -1835,7 +1885,14 @@ function mountOnItemChange(index, item, views, blockCards, outletElement, viewCo
1835
1885
  }
1836
1886
  }
1837
1887
  if (index === 0) {
1838
- outletElement.prepend(...rootNodes);
1888
+ if (firstRootNode) {
1889
+ rootNodes.forEach(rootNode => {
1890
+ firstRootNode.insertAdjacentElement('beforebegin', rootNode);
1891
+ });
1892
+ }
1893
+ else {
1894
+ outletParent.prepend(...rootNodes);
1895
+ }
1839
1896
  }
1840
1897
  else {
1841
1898
  const previousView = views[index - 1];
@@ -1850,9 +1907,10 @@ function mountOnItemChange(index, item, views, blockCards, outletElement, viewCo
1850
1907
  }
1851
1908
 
1852
1909
  class ListRender {
1853
- constructor(viewContext, viewContainerRef, getOutletElement) {
1910
+ constructor(viewContext, viewContainerRef, getOutletParent, getOutletElement) {
1854
1911
  this.viewContext = viewContext;
1855
1912
  this.viewContainerRef = viewContainerRef;
1913
+ this.getOutletParent = getOutletParent;
1856
1914
  this.getOutletElement = getOutletElement;
1857
1915
  this.views = [];
1858
1916
  this.blockCards = [];
@@ -1860,9 +1918,10 @@ class ListRender {
1860
1918
  this.viewTypes = [];
1861
1919
  this.initialized = false;
1862
1920
  }
1863
- initialize(children, parent, parentPath, childrenContext) {
1921
+ initialize(children, parent, childrenContext) {
1864
1922
  this.initialized = true;
1865
1923
  this.children = children;
1924
+ const parentPath = AngularEditor.findPath(this.viewContext.editor, parent);
1866
1925
  children.forEach((descendant, index) => {
1867
1926
  NODE_TO_INDEX.set(descendant, index);
1868
1927
  NODE_TO_PARENT.set(descendant, parent);
@@ -1875,19 +1934,21 @@ class ListRender {
1875
1934
  this.viewTypes.push(viewType);
1876
1935
  this.blockCards.push(blockCard);
1877
1936
  });
1878
- mount(this.views, this.blockCards, this.getOutletElement());
1937
+ mount(this.views, this.blockCards, this.getOutletParent(), this.getOutletElement());
1879
1938
  const newDiffers = this.viewContainerRef.injector.get(IterableDiffers);
1880
1939
  this.differ = newDiffers.find(children).create(trackBy$1(this.viewContext));
1881
1940
  this.differ.diff(children);
1882
1941
  }
1883
- update(children, parent, parentPath, childrenContext) {
1942
+ update(children, parent, childrenContext) {
1884
1943
  if (!this.initialized) {
1885
- this.initialize(children, parent, parentPath, childrenContext);
1944
+ this.initialize(children, parent, childrenContext);
1886
1945
  return;
1887
1946
  }
1888
- const outletElement = this.getOutletElement();
1947
+ const outletParent = this.getOutletParent();
1889
1948
  const diffResult = this.differ.diff(children);
1949
+ const parentPath = AngularEditor.findPath(this.viewContext.editor, parent);
1890
1950
  if (diffResult) {
1951
+ let firstRootNode = getRootNodes(this.views[0], this.blockCards[0])[0];
1891
1952
  const newContexts = [];
1892
1953
  const newViewTypes = [];
1893
1954
  const newViews = [];
@@ -1906,7 +1967,7 @@ class ListRender {
1906
1967
  newContexts.push(context);
1907
1968
  newViews.push(view);
1908
1969
  newBlockCards.push(blockCard);
1909
- mountOnItemChange(record.currentIndex, record.item, newViews, newBlockCards, outletElement, this.viewContext);
1970
+ mountOnItemChange(record.currentIndex, record.item, newViews, newBlockCards, outletParent, firstRootNode, this.viewContext);
1910
1971
  }
1911
1972
  else {
1912
1973
  const previousView = this.views[record.previousIndex];
@@ -1937,7 +1998,7 @@ class ListRender {
1937
1998
  newBlockCards.push(blockCard);
1938
1999
  }
1939
2000
  });
1940
- diffResult.forEachOperation((record) => {
2001
+ diffResult.forEachOperation(record => {
1941
2002
  // removed
1942
2003
  if (record.currentIndex === null) {
1943
2004
  const view = this.views[record.previousIndex];
@@ -1947,7 +2008,7 @@ class ListRender {
1947
2008
  }
1948
2009
  // moved
1949
2010
  if (record.previousIndex !== null && record.currentIndex !== null) {
1950
- mountOnItemChange(record.currentIndex, record.item, newViews, newBlockCards, outletElement, this.viewContext);
2011
+ mountOnItemChange(record.currentIndex, record.item, newViews, newBlockCards, outletParent, firstRootNode, this.viewContext);
1951
2012
  // Solve the block-card DOMElement loss when moving nodes
1952
2013
  newBlockCards[record.currentIndex]?.instance.append();
1953
2014
  }
@@ -1983,7 +2044,6 @@ function getContext$1(index, item, parentPath, childrenContext, viewContext) {
1983
2044
  const isVoid = viewContext.editor.isVoid(item);
1984
2045
  const elementContext = {
1985
2046
  element: item,
1986
- path: parentPath.concat(index),
1987
2047
  ...computedContext,
1988
2048
  attributes: {
1989
2049
  'data-slate-node': 'element',
@@ -1997,7 +2057,6 @@ function getContext$1(index, item, parentPath, childrenContext, viewContext) {
1997
2057
  }
1998
2058
  if (isVoid) {
1999
2059
  elementContext.attributes['data-slate-void'] = true;
2000
- elementContext.attributes.contenteditable = false;
2001
2060
  }
2002
2061
  return elementContext;
2003
2062
  }
@@ -2092,9 +2151,10 @@ function memoizedTextContext(prev, next) {
2092
2151
  }
2093
2152
 
2094
2153
  class LeavesRender {
2095
- constructor(viewContext, viewContainerRef, getOutletElement) {
2154
+ constructor(viewContext, viewContainerRef, getOutletParent, getOutletElement) {
2096
2155
  this.viewContext = viewContext;
2097
2156
  this.viewContainerRef = viewContainerRef;
2157
+ this.getOutletParent = getOutletParent;
2098
2158
  this.getOutletElement = getOutletElement;
2099
2159
  this.views = [];
2100
2160
  this.contexts = [];
@@ -2112,16 +2172,17 @@ class LeavesRender {
2112
2172
  this.contexts.push(context);
2113
2173
  this.viewTypes.push(viewType);
2114
2174
  });
2115
- mount(this.views, null, this.getOutletElement());
2175
+ mount(this.views, null, this.getOutletParent(), this.getOutletElement());
2116
2176
  const newDiffers = this.viewContainerRef.injector.get(IterableDiffers);
2117
2177
  this.differ = newDiffers.find(this.leaves).create(trackBy(this.viewContext));
2118
2178
  this.differ.diff(this.leaves);
2119
2179
  }
2120
2180
  update(context) {
2121
2181
  const { leaves, contexts } = this.getLeaves(context);
2122
- const outletElement = this.getOutletElement();
2182
+ const outletParent = this.getOutletParent();
2123
2183
  const diffResult = this.differ.diff(leaves);
2124
2184
  if (diffResult) {
2185
+ let firstRootNode = getRootNodes(this.views[0])[0];
2125
2186
  const newContexts = [];
2126
2187
  const newViewTypes = [];
2127
2188
  const newViews = [];
@@ -2134,7 +2195,7 @@ class LeavesRender {
2134
2195
  view = createEmbeddedViewOrComponent(viewType, context, this.viewContext, this.viewContainerRef);
2135
2196
  newContexts.push(context);
2136
2197
  newViews.push(view);
2137
- mountOnItemChange(record.currentIndex, record.item, newViews, null, outletElement, this.viewContext);
2198
+ mountOnItemChange(record.currentIndex, record.item, newViews, null, outletParent, firstRootNode, this.viewContext);
2138
2199
  }
2139
2200
  else {
2140
2201
  const previousView = this.views[record.previousIndex];
@@ -2159,7 +2220,7 @@ class LeavesRender {
2159
2220
  view.destroy();
2160
2221
  });
2161
2222
  diffResult.forEachMovedItem(record => {
2162
- mountOnItemChange(record.currentIndex, record.item, newViews, null, outletElement, this.viewContext);
2223
+ mountOnItemChange(record.currentIndex, record.item, newViews, null, outletParent, firstRootNode, this.viewContext);
2163
2224
  });
2164
2225
  this.viewTypes = newViewTypes;
2165
2226
  this.views = newViews;
@@ -2193,6 +2254,26 @@ function trackBy(viewContext) {
2193
2254
  };
2194
2255
  }
2195
2256
 
2257
+ class SlateChildrenOutlet {
2258
+ constructor(elementRef) {
2259
+ this.elementRef = elementRef;
2260
+ }
2261
+ getNativeElement() {
2262
+ return this.elementRef.nativeElement;
2263
+ }
2264
+ 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 }); }
2265
+ 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 }); }
2266
+ }
2267
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.1", ngImport: i0, type: SlateChildrenOutlet, decorators: [{
2268
+ type: Component,
2269
+ args: [{
2270
+ selector: 'slate-children-outlet',
2271
+ template: ``,
2272
+ changeDetection: ChangeDetectionStrategy.OnPush,
2273
+ standalone: true
2274
+ }]
2275
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }]; } });
2276
+
2196
2277
  /**
2197
2278
  * base class for custom element component or text component
2198
2279
  */
@@ -2203,6 +2284,12 @@ class BaseComponent {
2203
2284
  }
2204
2285
  this._context = value;
2205
2286
  this.onContextChange();
2287
+ if (this.initialized) {
2288
+ this.cdr.detectChanges();
2289
+ }
2290
+ if (hasAfterContextChange(this)) {
2291
+ this.afterContextChange();
2292
+ }
2206
2293
  }
2207
2294
  get context() {
2208
2295
  return this._context;
@@ -2216,6 +2303,7 @@ class BaseComponent {
2216
2303
  constructor(elementRef, cdr) {
2217
2304
  this.elementRef = elementRef;
2218
2305
  this.cdr = cdr;
2306
+ this.initialized = false;
2219
2307
  }
2220
2308
  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 }); }
2221
2309
  static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.1", type: BaseComponent, inputs: { context: "context", viewContext: "viewContext" }, ngImport: i0 }); }
@@ -2233,7 +2321,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.1", ngImpor
2233
2321
  class BaseLeafComponent extends BaseComponent {
2234
2322
  constructor() {
2235
2323
  super(...arguments);
2236
- this.initialized = false;
2237
2324
  this.isSlateLeaf = true;
2238
2325
  }
2239
2326
  get text() {
@@ -2249,7 +2336,6 @@ class BaseLeafComponent extends BaseComponent {
2249
2336
  if (!this.initialized) {
2250
2337
  return;
2251
2338
  }
2252
- this.cdr.detectChanges();
2253
2339
  }
2254
2340
  renderPlaceholder() {
2255
2341
  // issue-1: IME input was interrupted
@@ -2302,10 +2388,15 @@ class BaseElementComponent extends BaseComponent {
2302
2388
  constructor() {
2303
2389
  super(...arguments);
2304
2390
  this.viewContainerRef = inject(ViewContainerRef);
2305
- this.initialized = false;
2306
- this.getOutletElement = () => {
2391
+ this.getOutletParent = () => {
2307
2392
  return this.elementRef.nativeElement;
2308
2393
  };
2394
+ this.getOutletElement = () => {
2395
+ if (this.childrenOutletInstance) {
2396
+ return this.childrenOutletInstance.getNativeElement();
2397
+ }
2398
+ return null;
2399
+ };
2309
2400
  }
2310
2401
  get element() {
2311
2402
  return this._context && this._context.element;
@@ -2313,9 +2404,6 @@ class BaseElementComponent extends BaseComponent {
2313
2404
  get selection() {
2314
2405
  return this._context && this._context.selection;
2315
2406
  }
2316
- get path() {
2317
- return this._context && this._context.path;
2318
- }
2319
2407
  get decorations() {
2320
2408
  return this._context && this._context.decorations;
2321
2409
  }
@@ -2336,8 +2424,8 @@ class BaseElementComponent extends BaseComponent {
2336
2424
  this.nativeElement.setAttribute(key, this._context.attributes[key]);
2337
2425
  }
2338
2426
  this.initialized = true;
2339
- this.listRender = new ListRender(this.viewContext, this.viewContainerRef, this.getOutletElement);
2340
- this.listRender.initialize(this.children, this.element, this.path, this.childrenContext);
2427
+ this.listRender = new ListRender(this.viewContext, this.viewContainerRef, this.getOutletParent, this.getOutletElement);
2428
+ this.listRender.initialize(this.children, this.element, this.childrenContext);
2341
2429
  }
2342
2430
  updateWeakMap() {
2343
2431
  NODE_TO_ELEMENT.set(this.element, this.nativeElement);
@@ -2358,8 +2446,7 @@ class BaseElementComponent extends BaseComponent {
2358
2446
  if (!this.initialized) {
2359
2447
  return;
2360
2448
  }
2361
- this.listRender.update(this.children, this.element, this.path, this.childrenContext);
2362
- this.cdr.detectChanges();
2449
+ this.listRender.update(this.children, this.element, this.childrenContext);
2363
2450
  }
2364
2451
  getChildrenContext() {
2365
2452
  return {
@@ -2371,29 +2458,37 @@ class BaseElementComponent extends BaseComponent {
2371
2458
  };
2372
2459
  }
2373
2460
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.1", ngImport: i0, type: BaseElementComponent, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
2374
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.1", type: BaseElementComponent, usesInheritance: true, ngImport: i0 }); }
2461
+ 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 }); }
2375
2462
  }
2376
2463
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.1", ngImport: i0, type: BaseElementComponent, decorators: [{
2377
2464
  type: Directive
2378
- }] });
2465
+ }], propDecorators: { childrenOutletInstance: [{
2466
+ type: ViewChild,
2467
+ args: [SlateChildrenOutlet, { static: true }]
2468
+ }] } });
2379
2469
  /**
2380
2470
  * base class for custom text component
2381
2471
  */
2382
2472
  class BaseTextComponent extends BaseComponent {
2383
2473
  constructor() {
2384
2474
  super(...arguments);
2385
- this.initialized = false;
2386
2475
  this.viewContainerRef = inject(ViewContainerRef);
2387
- this.getOutletElement = () => {
2476
+ this.getOutletParent = () => {
2388
2477
  return this.elementRef.nativeElement;
2389
2478
  };
2479
+ this.getOutletElement = () => {
2480
+ if (this.childrenOutletInstance) {
2481
+ return this.childrenOutletInstance.getNativeElement();
2482
+ }
2483
+ return null;
2484
+ };
2390
2485
  }
2391
2486
  get text() {
2392
2487
  return this._context && this._context.text;
2393
2488
  }
2394
2489
  ngOnInit() {
2395
2490
  this.initialized = true;
2396
- this.leavesRender = new LeavesRender(this.viewContext, this.viewContainerRef, this.getOutletElement);
2491
+ this.leavesRender = new LeavesRender(this.viewContext, this.viewContainerRef, this.getOutletParent, this.getOutletElement);
2397
2492
  this.leavesRender.initialize(this.context);
2398
2493
  }
2399
2494
  updateWeakMap() {
@@ -2411,14 +2506,16 @@ class BaseTextComponent extends BaseComponent {
2411
2506
  return;
2412
2507
  }
2413
2508
  this.leavesRender.update(this.context);
2414
- this.cdr.detectChanges();
2415
2509
  }
2416
2510
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.1", ngImport: i0, type: BaseTextComponent, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
2417
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.1", type: BaseTextComponent, usesInheritance: true, ngImport: i0 }); }
2511
+ 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 }); }
2418
2512
  }
2419
2513
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.1", ngImport: i0, type: BaseTextComponent, decorators: [{
2420
2514
  type: Directive
2421
- }] });
2515
+ }], propDecorators: { childrenOutletInstance: [{
2516
+ type: ViewChild,
2517
+ args: [SlateChildrenOutlet, { static: true }]
2518
+ }] } });
2422
2519
 
2423
2520
  class SlateLeaves extends ViewContainer {
2424
2521
  constructor() {
@@ -2818,23 +2915,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.1", ngImpor
2818
2915
 
2819
2916
  const SLATE_DEFAULT_LEAF_COMPONENT_TOKEN = new InjectionToken('slate-default-leaf-token');
2820
2917
 
2821
- const createThrottleRAF = () => {
2822
- let timerId = null;
2823
- const throttleRAF = (fn) => {
2824
- const scheduleFunc = () => {
2825
- timerId = requestAnimationFrame(() => {
2826
- timerId = null;
2827
- fn();
2828
- });
2829
- };
2830
- if (timerId !== null) {
2831
- cancelAnimationFrame(timerId);
2832
- timerId = null;
2833
- }
2834
- scheduleFunc();
2835
- };
2836
- return throttleRAF;
2837
- };
2918
+ const TRIPLE_CLICK = 3;
2838
2919
 
2839
2920
  // not correctly clipboardData on beforeinput
2840
2921
  const forceOnDOMPaste = IS_SAFARI;
@@ -2874,10 +2955,9 @@ class SlateEditable {
2874
2955
  this.dataSlateNode = 'value';
2875
2956
  this.dataGramm = false;
2876
2957
  this.viewContainerRef = inject(ViewContainerRef);
2877
- this.getOutletElement = () => {
2958
+ this.getOutletParent = () => {
2878
2959
  return this.elementRef.nativeElement;
2879
2960
  };
2880
- this.throttleRAF = createThrottleRAF();
2881
2961
  }
2882
2962
  ngOnInit() {
2883
2963
  this.editor.injector = this.injector;
@@ -2903,7 +2983,7 @@ class SlateEditable {
2903
2983
  // add browser class
2904
2984
  let browserClass = IS_FIREFOX ? 'firefox' : IS_SAFARI ? 'safari' : '';
2905
2985
  browserClass && this.elementRef.nativeElement.classList.add(browserClass);
2906
- this.listRender = new ListRender(this.viewContext, this.viewContainerRef, this.getOutletElement);
2986
+ this.listRender = new ListRender(this.viewContext, this.viewContainerRef, this.getOutletParent, () => null);
2907
2987
  }
2908
2988
  ngOnChanges(simpleChanges) {
2909
2989
  if (!this.initialized) {
@@ -2945,10 +3025,10 @@ class SlateEditable {
2945
3025
  }
2946
3026
  this.initializeContext();
2947
3027
  if (!this.listRender.initialized) {
2948
- this.listRender.initialize(this.editor.children, this.editor, [], this.context);
3028
+ this.listRender.initialize(this.editor.children, this.editor, this.context);
2949
3029
  }
2950
3030
  else {
2951
- this.listRender.update(this.editor.children, this.editor, [], this.context);
3031
+ this.listRender.update(this.editor.children, this.editor, this.context);
2952
3032
  }
2953
3033
  this.cdr.markForCheck();
2954
3034
  }
@@ -3030,15 +3110,11 @@ class SlateEditable {
3030
3110
  // we need to check and do the right thing here.
3031
3111
  if (Range.isBackward(selection)) {
3032
3112
  // eslint-disable-next-line max-len
3033
- this.throttleRAF(() => {
3034
- domSelection.setBaseAndExtent(newDomRange.endContainer, newDomRange.endOffset, newDomRange.startContainer, newDomRange.startOffset);
3035
- });
3113
+ domSelection.setBaseAndExtent(newDomRange.endContainer, newDomRange.endOffset, newDomRange.startContainer, newDomRange.startOffset);
3036
3114
  }
3037
3115
  else {
3038
3116
  // eslint-disable-next-line max-len
3039
- this.throttleRAF(() => {
3040
- domSelection.setBaseAndExtent(newDomRange.startContainer, newDomRange.startOffset, newDomRange.endContainer, newDomRange.endOffset);
3041
- });
3117
+ domSelection.setBaseAndExtent(newDomRange.startContainer, newDomRange.startOffset, newDomRange.endContainer, newDomRange.endOffset);
3042
3118
  }
3043
3119
  }
3044
3120
  else {
@@ -3070,7 +3146,7 @@ class SlateEditable {
3070
3146
  ngDoCheck() { }
3071
3147
  forceRender() {
3072
3148
  this.updateContext();
3073
- this.listRender.update(this.editor.children, this.editor, [], this.context);
3149
+ this.listRender.update(this.editor.children, this.editor, this.context);
3074
3150
  // repair collaborative editing when Chinese input is interrupted by other users' cursors
3075
3151
  // when the DOMElement where the selection is located is removed
3076
3152
  // the compositionupdate and compositionend events will no longer be fired
@@ -3109,7 +3185,7 @@ class SlateEditable {
3109
3185
  render() {
3110
3186
  const changed = this.updateContext();
3111
3187
  if (changed) {
3112
- this.listRender.update(this.editor.children, this.editor, [], this.context);
3188
+ this.listRender.update(this.editor.children, this.editor, this.context);
3113
3189
  }
3114
3190
  }
3115
3191
  updateContext() {
@@ -3444,6 +3520,19 @@ class SlateEditable {
3444
3520
  const end = Editor.end(this.editor, path);
3445
3521
  const startVoid = Editor.void(this.editor, { at: start });
3446
3522
  const endVoid = Editor.void(this.editor, { at: end });
3523
+ if (event.detail === TRIPLE_CLICK && path.length >= 1) {
3524
+ let blockPath = path;
3525
+ if (!(Element.isElement(node) && Editor.isBlock(this.editor, node))) {
3526
+ const block = Editor.above(this.editor, {
3527
+ match: n => Element.isElement(n) && Editor.isBlock(this.editor, n),
3528
+ at: path
3529
+ });
3530
+ blockPath = block?.[1] ?? path.slice(0, 1);
3531
+ }
3532
+ const range = Editor.range(this.editor, blockPath);
3533
+ Transforms.select(this.editor, range);
3534
+ return;
3535
+ }
3447
3536
  if (startVoid && endVoid && Path.equals(startVoid[1], endVoid[1])) {
3448
3537
  const range = Editor.range(this.editor, start);
3449
3538
  Transforms.select(this.editor, range);
@@ -3510,7 +3599,7 @@ class SlateEditable {
3510
3599
  // that drops are allowed. Editable content is droppable by
3511
3600
  // default, and calling `preventDefault` hides the cursor.
3512
3601
  const node = AngularEditor.toSlateNode(this.editor, event.target);
3513
- if (Editor.isVoid(this.editor, node)) {
3602
+ if (Element.isElement(node) && Editor.isVoid(this.editor, node)) {
3514
3603
  event.preventDefault();
3515
3604
  }
3516
3605
  }
@@ -3519,7 +3608,7 @@ class SlateEditable {
3519
3608
  if (!this.readonly && hasTarget(this.editor, event.target) && !this.isDOMEventHandled(event, this.dragStart)) {
3520
3609
  const node = AngularEditor.toSlateNode(this.editor, event.target);
3521
3610
  const path = AngularEditor.findPath(this.editor, node);
3522
- const voidMatch = Editor.isVoid(this.editor, node) || Editor.void(this.editor, { at: path, voids: true });
3611
+ const voidMatch = Element.isElement(node) && (Editor.isVoid(this.editor, node) || Editor.void(this.editor, { at: path, voids: true }));
3523
3612
  // If starting a drag on a void node, make sure it is selected
3524
3613
  // so that it shows up in the selection's fragment.
3525
3614
  if (voidMatch) {
@@ -4042,7 +4131,7 @@ const hasTarget = (editor, target) => {
4042
4131
  */
4043
4132
  const isTargetInsideVoid = (editor, target) => {
4044
4133
  const slateNode = hasTarget(editor, target) && AngularEditor.toSlateNode(editor, target);
4045
- return Editor.isVoid(editor, slateNode);
4134
+ return Element.isElement(slateNode) && Editor.isVoid(editor, slateNode);
4046
4135
  };
4047
4136
  const hasStringTarget = (domSelection) => {
4048
4137
  return ((domSelection.anchorNode.parentElement.hasAttribute('data-slate-string') ||
@@ -4098,12 +4187,8 @@ class SlateModule {
4098
4187
  SlateBlockCard,
4099
4188
  SlateLeaves,
4100
4189
  SlateDefaultLeaf,
4101
- SlateDefaultString], exports: [SlateEditable,
4102
- SlateChildren,
4103
- SlateElement,
4104
- SlateLeaves,
4105
- SlateString,
4106
- SlateDefaultString] }); }
4190
+ SlateDefaultString,
4191
+ SlateChildrenOutlet], exports: [SlateEditable, SlateChildren, SlateChildrenOutlet, SlateElement, SlateLeaves, SlateString, SlateDefaultString] }); }
4107
4192
  static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.2.1", ngImport: i0, type: SlateModule, providers: [
4108
4193
  {
4109
4194
  provide: SLATE_DEFAULT_ELEMENT_COMPONENT_TOKEN,
@@ -4127,16 +4212,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.1", ngImpor
4127
4212
  SlateBlockCard,
4128
4213
  SlateLeaves,
4129
4214
  SlateDefaultLeaf,
4130
- SlateDefaultString
4131
- ],
4132
- exports: [
4133
- SlateEditable,
4134
- SlateChildren,
4135
- SlateElement,
4136
- SlateLeaves,
4137
- SlateString,
4138
- SlateDefaultString
4215
+ SlateDefaultString,
4216
+ SlateChildrenOutlet
4139
4217
  ],
4218
+ exports: [SlateEditable, SlateChildren, SlateChildrenOutlet, SlateElement, SlateLeaves, SlateString, SlateDefaultString],
4140
4219
  providers: [
4141
4220
  {
4142
4221
  provide: SLATE_DEFAULT_ELEMENT_COMPONENT_TOKEN,
@@ -4154,5 +4233,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.1", ngImpor
4154
4233
  * Generated bundle index. Do not edit.
4155
4234
  */
4156
4235
 
4157
- 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 };
4236
+ 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 };
4158
4237
  //# sourceMappingURL=slate-angular.mjs.map