slate-angular 19.3.1 → 19.4.0-next.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/components/editable/editable.component.d.ts +2 -10
  2. package/components/element.flavour.d.ts +7 -0
  3. package/components/leaf/leaf.flavour.d.ts +8 -0
  4. package/components/string/string-render.d.ts +39 -0
  5. package/components/string/string.component.d.ts +4 -26
  6. package/components/text/default-text.flavour.d.ts +12 -0
  7. package/fesm2022/slate-angular.mjs +1107 -1171
  8. package/fesm2022/slate-angular.mjs.map +1 -1
  9. package/module.d.ts +4 -13
  10. package/package.json +1 -1
  11. package/plugins/angular-editor.d.ts +2 -1
  12. package/public-api.d.ts +3 -5
  13. package/types/view.d.ts +2 -1
  14. package/utils/view.d.ts +1 -0
  15. package/utils/weak-maps.d.ts +2 -1
  16. package/view/base.d.ts +19 -17
  17. package/view/context.d.ts +1 -8
  18. package/view/flavour/base.d.ts +19 -0
  19. package/view/flavour/element.d.ts +27 -0
  20. package/view/flavour/index.d.ts +5 -0
  21. package/view/flavour/leaf.d.ts +17 -0
  22. package/view/flavour/ref.d.ts +5 -0
  23. package/view/flavour/text.d.ts +16 -0
  24. package/view/render/list-render.d.ts +2 -1
  25. package/view/render/utils.d.ts +5 -4
  26. package/components/children/children.component.d.ts +0 -11
  27. package/components/element/default-element.component.d.ts +0 -6
  28. package/components/element/default-element.component.token.d.ts +0 -4
  29. package/components/element/element.component.d.ts +0 -6
  30. package/components/leaf/default-leaf.component.d.ts +0 -9
  31. package/components/leaf/token.d.ts +0 -4
  32. package/components/leaves/leaves.component.d.ts +0 -12
  33. package/components/string/default-string.component.d.ts +0 -20
  34. package/components/string/template.component.d.ts +0 -9
  35. package/components/text/default-text.component.d.ts +0 -6
  36. package/components/text/token.d.ts +0 -5
  37. package/components/text/void-text.component.d.ts +0 -9
  38. package/view/container-item.d.ts +0 -32
  39. package/view/container.d.ts +0 -18
@@ -2,7 +2,7 @@ import { Editor, Range, Element, Transforms, Text as Text$1, Node, Path } from '
2
2
  import { EDITOR_TO_ELEMENT, NODE_TO_ELEMENT, DOMEditor, normalizeDOMPoint, isDOMSelection, IS_CHROME as IS_CHROME$1, hasShadowRoot, isDOMElement, NODE_TO_PARENT, NODE_TO_INDEX, IS_FOCUSED, isDOMNode, withDOM, NODE_TO_KEY, ELEMENT_TO_NODE, getDefaultView, EDITOR_TO_WINDOW, IS_READ_ONLY, EDITOR_TO_ON_CHANGE, TRIPLE_CLICK, isPlainTextOnlyPaste } from 'slate-dom';
3
3
  import { isKeyHotkey } from 'is-hotkey';
4
4
  import * as i0 from '@angular/core';
5
- import { TemplateRef, ViewChild, ChangeDetectionStrategy, Component, InjectionToken, ComponentRef, IterableDiffers, inject, ElementRef, ChangeDetectorRef, Input, Directive, HostBinding, ViewContainerRef, forwardRef, Inject, NgModule } from '@angular/core';
5
+ import { TemplateRef, ViewChild, Component, ComponentRef, IterableDiffers, inject, ViewContainerRef, forwardRef, HostBinding, Input, ChangeDetectionStrategy, NgModule, ElementRef, ChangeDetectorRef, Directive } from '@angular/core';
6
6
  import { direction } from 'direction';
7
7
  import scrollIntoView from 'scroll-into-view-if-needed';
8
8
  import { Subject } from 'rxjs';
@@ -572,6 +572,9 @@ function isTemplateRef(value) {
572
572
  function isComponentType(value) {
573
573
  return !isTemplateRef(value);
574
574
  }
575
+ function isFlavourType(value) {
576
+ return value && value.isFlavour === true;
577
+ }
575
578
 
576
579
  const shallowCompare = (obj1, obj2) => Object.keys(obj1).length === Object.keys(obj2).length &&
577
580
  Object.keys(obj1).every(key => obj2.hasOwnProperty(key) && obj1[key] === obj2[key]);
@@ -1033,15 +1036,15 @@ const withAngular = (editor, clipboardFormatKey = 'x-slate-fragment') => {
1033
1036
  }
1034
1037
  };
1035
1038
  e.insertData = async (data) => {
1036
- if (!(await e.customInsertFragmentData(data))) {
1039
+ if (!(await e.customInsertFragmentData(data, null))) {
1037
1040
  e.insertTextData(data);
1038
1041
  }
1039
1042
  };
1040
- e.customInsertFragmentData = async (data) => {
1043
+ e.customInsertFragmentData = async (data, contextClipboardData) => {
1041
1044
  /**
1042
1045
  * Checking copied fragment from application/x-slate-fragment or data-slate-fragment
1043
1046
  */
1044
- const clipboardData = await getClipboardData(data);
1047
+ const clipboardData = contextClipboardData || (await getClipboardData(data));
1045
1048
  if (clipboardData && clipboardData.elements) {
1046
1049
  e.insertFragment(clipboardData.elements);
1047
1050
  return true;
@@ -1477,24 +1480,6 @@ var SlateErrorCode;
1477
1480
  SlateErrorCode[SlateErrorCode["InvalidValueError"] = 4100] = "InvalidValueError";
1478
1481
  })(SlateErrorCode || (SlateErrorCode = {}));
1479
1482
 
1480
- class SlateStringTemplate {
1481
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SlateStringTemplate, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1482
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: SlateStringTemplate, isStandalone: true, selector: "slate-string-template", viewQueries: [{ propertyName: "compatibleStringTemplate", first: true, predicate: ["compatibleStringTemplate"], descendants: true, read: TemplateRef, static: true }, { propertyName: "voidStringTemplate", first: true, predicate: ["voidStringTemplate"], descendants: true, read: TemplateRef, static: true }, { propertyName: "emptyTextTemplate", first: true, predicate: ["emptyTextTemplate"], descendants: true, read: TemplateRef, static: true }], ngImport: i0, template: "<ng-template #compatibleStringTemplate let-context=\"context\" let-viewContext=\"viewContext\">\n <!-- Compatible with Chinese input in Chrome with \\n -->\n <span editable-text data-slate-string=\"true\"\n >{{ context.text }}<span data-slate-zero-width>{{ '\\uFEFF' }}</span></span\n >\n</ng-template>\n<ng-template #voidStringTemplate let-context=\"context\" let-viewContext=\"viewContext\">\n <span editable-text data-slate-zero-width=\"z\" attr.data-slate-length=\"{{ context.elementStringLength }}\">{{ '\\uFEFF' }}</span>\n</ng-template>\n<ng-template #emptyTextTemplate let-context=\"context\" let-viewContext=\"viewContext\">\n <span editable-text data-slate-zero-width=\"z\" data-slate-length=\"0\">{{ '\\uFEFF' }}</span>\n</ng-template>\n", changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1483
- }
1484
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SlateStringTemplate, decorators: [{
1485
- type: Component,
1486
- args: [{ selector: 'slate-string-template', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, template: "<ng-template #compatibleStringTemplate let-context=\"context\" let-viewContext=\"viewContext\">\n <!-- Compatible with Chinese input in Chrome with \\n -->\n <span editable-text data-slate-string=\"true\"\n >{{ context.text }}<span data-slate-zero-width>{{ '\\uFEFF' }}</span></span\n >\n</ng-template>\n<ng-template #voidStringTemplate let-context=\"context\" let-viewContext=\"viewContext\">\n <span editable-text data-slate-zero-width=\"z\" attr.data-slate-length=\"{{ context.elementStringLength }}\">{{ '\\uFEFF' }}</span>\n</ng-template>\n<ng-template #emptyTextTemplate let-context=\"context\" let-viewContext=\"viewContext\">\n <span editable-text data-slate-zero-width=\"z\" data-slate-length=\"0\">{{ '\\uFEFF' }}</span>\n</ng-template>\n" }]
1487
- }], propDecorators: { compatibleStringTemplate: [{
1488
- type: ViewChild,
1489
- args: ['compatibleStringTemplate', { read: TemplateRef, static: true }]
1490
- }], voidStringTemplate: [{
1491
- type: ViewChild,
1492
- args: ['voidStringTemplate', { read: TemplateRef, static: true }]
1493
- }], emptyTextTemplate: [{
1494
- type: ViewChild,
1495
- args: ['emptyTextTemplate', { read: TemplateRef, static: true }]
1496
- }] } });
1497
-
1498
1483
  function restoreDom(editor, execute) {
1499
1484
  const editable = EDITOR_TO_ELEMENT.get(editor);
1500
1485
  let observer = new MutationObserver(mutations => {
@@ -1527,45 +1512,53 @@ function restoreDom(editor, execute) {
1527
1512
  }, 0);
1528
1513
  }
1529
1514
 
1530
- const SLATE_DEFAULT_ELEMENT_COMPONENT_TOKEN = new InjectionToken('slate-default-element-token');
1531
-
1532
- const SLATE_DEFAULT_TEXT_COMPONENT_TOKEN = new InjectionToken('slate-default-text-token');
1533
- const SLATE_DEFAULT_VOID_TEXT_COMPONENT_TOKEN = new InjectionToken('slate-default-void-text-token');
1534
-
1535
- class SlateChildrenOutlet {
1515
+ class SlateBlockCard {
1516
+ get nativeElement() {
1517
+ return this.elementRef.nativeElement;
1518
+ }
1519
+ get centerContainerElement() {
1520
+ return this.centerContianer.nativeElement;
1521
+ }
1536
1522
  constructor(elementRef) {
1537
1523
  this.elementRef = elementRef;
1538
1524
  }
1539
- getNativeElement() {
1540
- return this.elementRef.nativeElement;
1525
+ ngOnInit() {
1526
+ this.nativeElement.classList.add(`slate-block-card`);
1541
1527
  }
1542
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SlateChildrenOutlet, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
1543
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: SlateChildrenOutlet, isStandalone: true, selector: "slate-children-outlet", ngImport: i0, template: ``, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1528
+ append() {
1529
+ this.centerRootNodes.forEach(rootNode => !this.centerContainerElement.contains(rootNode) && this.centerContainerElement.appendChild(rootNode));
1530
+ }
1531
+ initializeCenter(rootNodes) {
1532
+ this.centerRootNodes = rootNodes;
1533
+ this.append();
1534
+ }
1535
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SlateBlockCard, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
1536
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", 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" }); }
1544
1537
  }
1545
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SlateChildrenOutlet, decorators: [{
1538
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SlateBlockCard, decorators: [{
1546
1539
  type: Component,
1547
- args: [{
1548
- selector: 'slate-children-outlet',
1549
- template: ``,
1550
- changeDetection: ChangeDetectionStrategy.OnPush,
1551
- standalone: true
1552
- }]
1553
- }], ctorParameters: () => [{ type: i0.ElementRef }] });
1540
+ args: [{ selector: 'slate-block-card, [slateBlockCard]', standalone: true, 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" }]
1541
+ }], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { centerContianer: [{
1542
+ type: ViewChild,
1543
+ args: ['centerContianer', { static: true }]
1544
+ }] } });
1554
1545
 
1555
- function hasBeforeContextChange(value) {
1556
- if (value.beforeContextChange) {
1557
- return true;
1558
- }
1559
- return false;
1560
- }
1561
- function hasAfterContextChange(value) {
1562
- if (value.afterContextChange) {
1563
- return true;
1546
+ class FlavourRef {
1547
+ destroy() {
1548
+ this.instance.onDestroy();
1564
1549
  }
1565
- return false;
1566
1550
  }
1567
1551
 
1568
- function createEmbeddedViewOrComponent(viewType, context, viewContext, viewContainerRef) {
1552
+ function createEmbeddedViewOrComponentOrFlavour(viewType, context, viewContext, viewContainerRef) {
1553
+ if (isFlavourType(viewType)) {
1554
+ const flavourRef = new FlavourRef();
1555
+ flavourRef.instance = new viewType();
1556
+ flavourRef.instance.context = context;
1557
+ flavourRef.instance.viewContext = viewContext;
1558
+ flavourRef.instance.viewContainerRef = viewContainerRef;
1559
+ flavourRef.instance.onInit();
1560
+ return flavourRef;
1561
+ }
1569
1562
  if (isTemplateRef(viewType)) {
1570
1563
  const embeddedViewContext = {
1571
1564
  context,
@@ -1586,6 +1579,10 @@ function createEmbeddedViewOrComponent(viewType, context, viewContext, viewConta
1586
1579
  }
1587
1580
  }
1588
1581
  function updateContext(view, newContext, viewContext) {
1582
+ if (view instanceof FlavourRef) {
1583
+ view.instance.context = newContext;
1584
+ return;
1585
+ }
1589
1586
  if (view instanceof ComponentRef) {
1590
1587
  view.instance.context = newContext;
1591
1588
  }
@@ -1615,6 +1612,9 @@ function getRootNodes(ref, blockCard) {
1615
1612
  if (blockCard) {
1616
1613
  return [blockCard.instance.nativeElement];
1617
1614
  }
1615
+ if (ref instanceof FlavourRef) {
1616
+ return [ref.instance.nativeElement];
1617
+ }
1618
1618
  if (ref instanceof ComponentRef) {
1619
1619
  ref.hostView.rootNodes.forEach(ele => {
1620
1620
  if (!(ele instanceof HTMLElement)) {
@@ -1670,498 +1670,166 @@ function mountOnItemChange(index, item, views, blockCards, outletParent, firstRo
1670
1670
  }
1671
1671
  }
1672
1672
 
1673
- class LeavesRender {
1674
- constructor(viewContext, viewContainerRef, getOutletParent, getOutletElement) {
1675
- this.viewContext = viewContext;
1676
- this.viewContainerRef = viewContainerRef;
1677
- this.getOutletParent = getOutletParent;
1678
- this.getOutletElement = getOutletElement;
1679
- this.views = [];
1680
- this.contexts = [];
1681
- this.viewTypes = [];
1673
+ function hasBeforeContextChange(value) {
1674
+ if (value.beforeContextChange) {
1675
+ return true;
1682
1676
  }
1683
- initialize(context) {
1684
- const { decoratedLeaves, contexts } = this.getLeaves(context);
1685
- this.decoratedLeaves = decoratedLeaves;
1686
- this.contexts = contexts;
1687
- this.decoratedLeaves.forEach((leaf, index) => {
1688
- const context = getContext$1(index, this.contexts);
1689
- const viewType = getViewType$1(context, this.viewContext);
1690
- const view = createEmbeddedViewOrComponent(viewType, context, this.viewContext, this.viewContainerRef);
1691
- this.views.push(view);
1692
- this.contexts.push(context);
1693
- this.viewTypes.push(viewType);
1694
- });
1695
- mount(this.views, null, this.getOutletParent(), this.getOutletElement());
1696
- const newDiffers = this.viewContainerRef.injector.get(IterableDiffers);
1697
- this.differ = newDiffers.find(this.decoratedLeaves).create(trackBy$1(this.viewContext));
1698
- this.differ.diff(this.decoratedLeaves);
1677
+ return false;
1678
+ }
1679
+ function hasAfterContextChange(value) {
1680
+ if (value.afterContextChange) {
1681
+ return true;
1699
1682
  }
1700
- update(context) {
1701
- const { decoratedLeaves, contexts } = this.getLeaves(context);
1702
- const outletParent = this.getOutletParent();
1703
- const diffResult = this.differ.diff(decoratedLeaves);
1704
- if (diffResult) {
1705
- let firstRootNode = getRootNodes(this.views[0])[0];
1706
- const newContexts = [];
1707
- const newViewTypes = [];
1708
- const newViews = [];
1709
- diffResult.forEachItem(record => {
1710
- let context = getContext$1(record.currentIndex, contexts);
1711
- const viewType = getViewType$1(context, this.viewContext);
1712
- newViewTypes.push(viewType);
1713
- let view;
1714
- if (record.previousIndex === null) {
1715
- view = createEmbeddedViewOrComponent(viewType, context, this.viewContext, this.viewContainerRef);
1716
- newContexts.push(context);
1717
- newViews.push(view);
1718
- mountOnItemChange(record.currentIndex, record.item, newViews, null, outletParent, firstRootNode, this.viewContext);
1719
- }
1720
- else {
1721
- const previousView = this.views[record.previousIndex];
1722
- const previousViewType = this.viewTypes[record.previousIndex];
1723
- if (previousViewType !== viewType) {
1724
- view = createEmbeddedViewOrComponent(viewType, context, this.viewContext, this.viewContainerRef);
1725
- const firstRootNode = getRootNodes(previousView, null)[0];
1726
- const newRootNodes = getRootNodes(view, null);
1727
- firstRootNode.replaceWith(...newRootNodes);
1728
- previousView.destroy();
1729
- }
1730
- else {
1731
- view = previousView;
1732
- updateContext(previousView, context, this.viewContext);
1733
- }
1734
- newContexts.push(context);
1735
- newViews.push(view);
1736
- }
1737
- });
1738
- diffResult.forEachRemovedItem(record => {
1739
- const view = this.views[record.previousIndex];
1740
- view.destroy();
1741
- });
1742
- diffResult.forEachMovedItem(record => {
1743
- mountOnItemChange(record.currentIndex, record.item, newViews, null, outletParent, firstRootNode, this.viewContext);
1744
- });
1745
- this.viewTypes = newViewTypes;
1746
- this.views = newViews;
1747
- this.contexts = newContexts;
1748
- this.decoratedLeaves = decoratedLeaves;
1683
+ return false;
1684
+ }
1685
+
1686
+ class BaseFlavour {
1687
+ constructor() {
1688
+ this.initialized = false;
1689
+ }
1690
+ static { this.isFlavour = true; }
1691
+ set context(value) {
1692
+ if (hasBeforeContextChange(this)) {
1693
+ this.beforeContextChange(value);
1694
+ }
1695
+ this._context = value;
1696
+ this.onContextChange();
1697
+ if (hasAfterContextChange(this)) {
1698
+ this.afterContextChange();
1749
1699
  }
1750
1700
  }
1751
- getLeaves(context) {
1752
- const decoratedLeaves = Text$1.decorations(context.text, context.decorations);
1753
- const contexts = decoratedLeaves.map((decoratedLeaf, index) => {
1754
- return {
1755
- leaf: decoratedLeaf.leaf,
1756
- leafPosition: decoratedLeaf.position,
1757
- text: context.text,
1758
- parent: context.parent,
1759
- index,
1760
- isLast: context.isLast && index === decoratedLeaves.length - 1
1761
- };
1762
- });
1763
- return { decoratedLeaves, contexts };
1701
+ get context() {
1702
+ return this._context;
1703
+ }
1704
+ get editor() {
1705
+ return this.viewContext && this.viewContext.editor;
1764
1706
  }
1765
- }
1766
- function getContext$1(index, leafContexts) {
1767
- return leafContexts[index];
1768
- }
1769
- function getViewType$1(leafContext, viewContext) {
1770
- return (viewContext.renderLeaf && viewContext.renderLeaf(leafContext.leaf)) || viewContext.defaultLeaf;
1771
- }
1772
- function trackBy$1(viewContext) {
1773
- return (index, node) => {
1774
- return index;
1775
- };
1776
1707
  }
1777
1708
 
1778
- class SlateBlockCard {
1779
- get nativeElement() {
1780
- return this.elementRef.nativeElement;
1709
+ class BaseElementFlavour extends BaseFlavour {
1710
+ constructor() {
1711
+ super(...arguments);
1712
+ this.getOutletParent = () => {
1713
+ return this.nativeElement;
1714
+ };
1715
+ this.getOutletElement = () => {
1716
+ return this.nativeElement.querySelector('.children-outlet');
1717
+ };
1781
1718
  }
1782
- get centerContainerElement() {
1783
- return this.centerContianer.nativeElement;
1719
+ get element() {
1720
+ return this._context && this._context.element;
1784
1721
  }
1785
- constructor(elementRef) {
1786
- this.elementRef = elementRef;
1722
+ get selection() {
1723
+ return this._context && this._context.selection;
1787
1724
  }
1788
- ngOnInit() {
1789
- this.nativeElement.classList.add(`slate-block-card`);
1725
+ get decorations() {
1726
+ return this._context && this._context.decorations;
1790
1727
  }
1791
- append() {
1792
- this.centerRootNodes.forEach(rootNode => !this.centerContainerElement.contains(rootNode) && this.centerContainerElement.appendChild(rootNode));
1728
+ get children() {
1729
+ return this._context && this._context.element.children;
1793
1730
  }
1794
- initializeCenter(rootNodes) {
1795
- this.centerRootNodes = rootNodes;
1796
- this.append();
1731
+ get isCollapsed() {
1732
+ return this.selection && Range.isCollapsed(this.selection);
1797
1733
  }
1798
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SlateBlockCard, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
1799
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", 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" }); }
1800
- }
1801
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SlateBlockCard, decorators: [{
1802
- type: Component,
1803
- args: [{ selector: 'slate-block-card, [slateBlockCard]', standalone: true, 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" }]
1804
- }], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { centerContianer: [{
1805
- type: ViewChild,
1806
- args: ['centerContianer', { static: true }]
1807
- }] } });
1808
-
1809
- class ListRender {
1810
- constructor(viewContext, viewContainerRef, getOutletParent, getOutletElement) {
1811
- this.viewContext = viewContext;
1812
- this.viewContainerRef = viewContainerRef;
1813
- this.getOutletParent = getOutletParent;
1814
- this.getOutletElement = getOutletElement;
1815
- this.views = [];
1816
- // private addedViews: (EmbeddedViewRef<any> | ComponentRef<any>)[] = [];
1817
- this.blockCards = [];
1818
- this.contexts = [];
1819
- this.viewTypes = [];
1820
- this.differ = null;
1821
- this.initialized = false;
1734
+ get isCollapsedAndNonReadonly() {
1735
+ return this.selection && Range.isCollapsed(this.selection) && !this.readonly;
1822
1736
  }
1823
- initialize(children, parent, childrenContext) {
1737
+ get readonly() {
1738
+ return this._context && this._context.readonly;
1739
+ }
1740
+ onInit() {
1824
1741
  this.initialized = true;
1825
- this.children = children;
1826
- const parentPath = AngularEditor.findPath(this.viewContext.editor, parent);
1827
- children.forEach((descendant, index) => {
1828
- NODE_TO_INDEX.set(descendant, index);
1829
- NODE_TO_PARENT.set(descendant, parent);
1830
- const context = getContext(index, descendant, parentPath, childrenContext, this.viewContext);
1831
- const viewType = getViewType(descendant, parent, this.viewContext);
1832
- const view = createEmbeddedViewOrComponent(viewType, context, this.viewContext, this.viewContainerRef);
1833
- const blockCard = createBlockCard(descendant, view, this.viewContainerRef, this.viewContext);
1834
- this.views.push(view);
1835
- this.contexts.push(context);
1836
- this.viewTypes.push(viewType);
1837
- this.blockCards.push(blockCard);
1838
- });
1839
- mount(this.views, this.blockCards, this.getOutletParent(), this.getOutletElement());
1840
- const newDiffers = this.viewContainerRef.injector.get(IterableDiffers);
1841
- this.differ = newDiffers.find(children).create(trackBy(this.viewContext));
1842
- this.differ.diff(children);
1843
- if (parent === this.viewContext.editor) {
1844
- executeAfterViewInit(this.viewContext.editor);
1845
- }
1846
- }
1847
- update(children, parent, childrenContext) {
1848
- if (!this.initialized || this.children.length === 0) {
1849
- this.initialize(children, parent, childrenContext);
1850
- return;
1851
- }
1852
- if (!this.differ) {
1853
- throw new Error('Exception: Can not find differ ');
1854
- }
1855
- const outletParent = this.getOutletParent();
1856
- const diffResult = this.differ.diff(children);
1857
- const parentPath = AngularEditor.findPath(this.viewContext.editor, parent);
1858
- if (diffResult) {
1859
- let firstRootNode = getRootNodes(this.views[0], this.blockCards[0])[0];
1860
- const newContexts = [];
1861
- const newViewTypes = [];
1862
- const newViews = [];
1863
- const newBlockCards = [];
1864
- diffResult.forEachItem(record => {
1865
- NODE_TO_INDEX.set(record.item, record.currentIndex);
1866
- NODE_TO_PARENT.set(record.item, parent);
1867
- let context = getContext(record.currentIndex, record.item, parentPath, childrenContext, this.viewContext);
1868
- const viewType = getViewType(record.item, parent, this.viewContext);
1869
- newViewTypes.push(viewType);
1870
- let view;
1871
- let blockCard;
1872
- if (record.previousIndex === null) {
1873
- view = createEmbeddedViewOrComponent(viewType, context, this.viewContext, this.viewContainerRef);
1874
- blockCard = createBlockCard(record.item, view, this.viewContainerRef, this.viewContext);
1875
- newContexts.push(context);
1876
- newViews.push(view);
1877
- newBlockCards.push(blockCard);
1878
- mountOnItemChange(record.currentIndex, record.item, newViews, newBlockCards, outletParent, firstRootNode, this.viewContext);
1879
- }
1880
- else {
1881
- const previousView = this.views[record.previousIndex];
1882
- const previousViewType = this.viewTypes[record.previousIndex];
1883
- const previousContext = this.contexts[record.previousIndex];
1884
- const previousBlockCard = this.blockCards[record.previousIndex];
1885
- if (previousViewType !== viewType) {
1886
- view = createEmbeddedViewOrComponent(viewType, context, this.viewContext, this.viewContainerRef);
1887
- blockCard = createBlockCard(record.item, view, this.viewContainerRef, this.viewContext);
1888
- const firstRootNode = getRootNodes(previousView, previousBlockCard)[0];
1889
- const newRootNodes = getRootNodes(view, blockCard);
1890
- firstRootNode.replaceWith(...newRootNodes);
1891
- previousView.destroy();
1892
- previousBlockCard?.destroy();
1893
- }
1894
- else {
1895
- view = previousView;
1896
- blockCard = previousBlockCard;
1897
- if (memoizedContext(this.viewContext, record.item, previousContext, context)) {
1898
- context = previousContext;
1899
- }
1900
- else {
1901
- updateContext(previousView, context, this.viewContext);
1902
- }
1903
- }
1904
- newContexts.push(context);
1905
- newViews.push(view);
1906
- newBlockCards.push(blockCard);
1907
- }
1908
- });
1909
- diffResult.forEachOperation(record => {
1910
- // removed
1911
- if (record.currentIndex === null) {
1912
- const view = this.views[record.previousIndex];
1913
- const blockCard = this.blockCards[record.previousIndex];
1914
- view.destroy();
1915
- blockCard?.destroy();
1916
- }
1917
- // moved
1918
- if (record.previousIndex !== null && record.currentIndex !== null) {
1919
- mountOnItemChange(record.currentIndex, record.item, newViews, newBlockCards, outletParent, firstRootNode, this.viewContext);
1920
- // Solve the block-card DOMElement loss when moving nodes
1921
- newBlockCards[record.currentIndex]?.instance.append();
1922
- }
1923
- });
1924
- this.viewTypes = newViewTypes;
1925
- this.views = newViews;
1926
- this.contexts = newContexts;
1927
- this.children = children;
1928
- this.blockCards = newBlockCards;
1929
- if (parent === this.viewContext.editor) {
1930
- executeAfterViewInit(this.viewContext.editor);
1931
- }
1742
+ this.render();
1743
+ for (const key in this._context.attributes) {
1744
+ this.nativeElement.setAttribute(key, this._context.attributes[key]);
1932
1745
  }
1933
- else {
1934
- const newContexts = [];
1935
- this.children.forEach((child, index) => {
1936
- NODE_TO_INDEX.set(child, index);
1937
- NODE_TO_PARENT.set(child, parent);
1938
- let context = getContext(index, child, parentPath, childrenContext, this.viewContext);
1939
- const previousContext = this.contexts[index];
1940
- if (memoizedContext(this.viewContext, child, previousContext, context)) {
1941
- context = previousContext;
1942
- }
1943
- else {
1944
- updateContext(this.views[index], context, this.viewContext);
1945
- }
1946
- newContexts.push(context);
1947
- });
1948
- this.contexts = newContexts;
1746
+ this.updateWeakMap();
1747
+ this.listRender = new ListRender(this.viewContext, this.viewContainerRef, this.getOutletParent, this.getOutletElement);
1748
+ if (this.editor.isExpanded(this.element)) {
1749
+ this.listRender.initialize(this.children, this.element, this.childrenContext);
1949
1750
  }
1950
- }
1951
- destroy() {
1952
- this.children.forEach((element, index) => {
1953
- if (this.views[index]) {
1954
- this.views[index].destroy();
1955
- }
1956
- if (this.blockCards[index]) {
1957
- this.blockCards[index].destroy();
1958
- }
1751
+ addAfterViewInitQueue(this.editor, () => {
1752
+ this.afterViewInit();
1959
1753
  });
1960
- this.views = [];
1961
- this.blockCards = [];
1962
- this.contexts = [];
1963
- this.viewTypes = [];
1964
- this.initialized = false;
1965
- this.differ = null;
1966
1754
  }
1967
- }
1968
- function getContext(index, item, parentPath, childrenContext, viewContext) {
1969
- if (Element.isElement(item)) {
1970
- const computedContext = getCommonContext(index, item, parentPath, viewContext, childrenContext);
1971
- const key = AngularEditor.findKey(viewContext.editor, item);
1972
- const isInline = viewContext.editor.isInline(item);
1973
- const isVoid = viewContext.editor.isVoid(item);
1974
- const elementContext = {
1975
- element: item,
1976
- ...computedContext,
1977
- attributes: {
1978
- 'data-slate-node': 'element',
1979
- 'data-slate-key': key.id
1980
- },
1981
- decorate: childrenContext.decorate,
1982
- readonly: childrenContext.readonly
1983
- };
1984
- if (isInline) {
1985
- elementContext.attributes['data-slate-inline'] = true;
1755
+ afterViewInit() {
1756
+ if (this._context.contentEditable !== undefined) {
1757
+ this.nativeElement.setAttribute('contenteditable', this._context.contentEditable + '');
1986
1758
  }
1987
- if (isVoid) {
1988
- elementContext.attributes['data-slate-void'] = true;
1759
+ }
1760
+ updateWeakMap() {
1761
+ NODE_TO_ELEMENT.set(this.element, this.nativeElement);
1762
+ ELEMENT_TO_NODE.set(this.nativeElement, this.element);
1763
+ ELEMENT_TO_COMPONENT.set(this.element, this);
1764
+ }
1765
+ onDestroy() {
1766
+ if (NODE_TO_ELEMENT.get(this.element) === this.nativeElement) {
1767
+ NODE_TO_ELEMENT.delete(this.element);
1989
1768
  }
1990
- // add contentEditable for block element only to avoid chinese input be broken
1991
- if (isVoid && !isInline) {
1992
- elementContext.contentEditable = false;
1769
+ ELEMENT_TO_NODE.delete(this.nativeElement);
1770
+ if (ELEMENT_TO_COMPONENT.get(this.element) === this) {
1771
+ ELEMENT_TO_COMPONENT.delete(this.element);
1993
1772
  }
1994
- return elementContext;
1773
+ this.nativeElement?.remove();
1995
1774
  }
1996
- else {
1997
- const computedContext = getCommonContext(index, item, parentPath, viewContext, childrenContext);
1998
- const isLeafBlock = AngularEditor.isLeafBlock(viewContext.editor, childrenContext.parent);
1999
- const textContext = {
2000
- decorations: computedContext.decorations,
2001
- isLast: isLeafBlock && index === childrenContext.parent.children.length - 1,
2002
- parent: childrenContext.parent,
2003
- text: item
2004
- };
2005
- return textContext;
1775
+ onContextChange() {
1776
+ this.childrenContext = this.getChildrenContext();
1777
+ if (!this.initialized) {
1778
+ return;
1779
+ }
1780
+ this.rerender();
1781
+ this.updateWeakMap();
1782
+ this.updateChildrenView();
2006
1783
  }
2007
- }
2008
- function getCommonContext(index, item, parentPath, viewContext, childrenContext) {
2009
- const p = parentPath.concat(index);
2010
- try {
2011
- const ds = childrenContext.decorate([item, p]);
2012
- // [list-render] performance optimization: reduce the number of calls to the `Editor.range(viewContext.editor, p)` method
2013
- if (childrenContext.selection || childrenContext.decorations.length > 0) {
2014
- const range = Editor.range(viewContext.editor, p);
2015
- const sel = childrenContext.selection && Range.intersection(range, childrenContext.selection);
2016
- for (const dec of childrenContext.decorations) {
2017
- const d = Range.intersection(dec, range);
2018
- if (d) {
2019
- ds.push(d);
2020
- }
2021
- }
2022
- return { selection: sel, decorations: ds };
1784
+ updateChildrenView() {
1785
+ if (this.editor.isExpanded(this.element)) {
1786
+ this.listRender.update(this.children, this.element, this.childrenContext);
2023
1787
  }
2024
1788
  else {
2025
- return { selection: null, decorations: ds };
1789
+ if (this.listRender.initialized) {
1790
+ this.listRender.destroy();
1791
+ }
2026
1792
  }
2027
1793
  }
2028
- catch (error) {
2029
- viewContext.editor.onError({
2030
- code: SlateErrorCode.GetStartPointError,
2031
- nativeError: error
2032
- });
2033
- return { selection: null, decorations: [] };
1794
+ getChildrenContext() {
1795
+ return {
1796
+ parent: this._context.element,
1797
+ selection: this._context.selection,
1798
+ decorations: this._context.decorations,
1799
+ decorate: this._context.decorate,
1800
+ readonly: this._context.readonly
1801
+ };
2034
1802
  }
2035
1803
  }
2036
- function getViewType(item, parent, viewContext) {
2037
- if (Element.isElement(item)) {
2038
- return (viewContext.renderElement && viewContext.renderElement(item)) || viewContext.defaultElement;
1804
+
1805
+ class DefaultElementFlavour extends BaseElementFlavour {
1806
+ render() {
1807
+ const nativeElement = document.createElement('div');
1808
+ this.nativeElement = nativeElement;
2039
1809
  }
2040
- else {
2041
- const isVoid = viewContext.editor.isVoid(parent);
2042
- return isVoid ? viewContext.defaultVoidText : (viewContext.renderText && viewContext.renderText(item)) || viewContext.defaultText;
1810
+ rerender() {
1811
+ // No-op
2043
1812
  }
2044
1813
  }
2045
- function createBlockCard(item, view, viewContainerRef, viewContext) {
2046
- const isBlockCard = viewContext.editor.isBlockCard(item);
2047
- if (isBlockCard) {
2048
- const rootNodes = getRootNodes(view);
2049
- const blockCardComponentRef = viewContainerRef.createComponent(SlateBlockCard, {
2050
- injector: viewContainerRef.injector
2051
- });
2052
- blockCardComponentRef.instance.initializeCenter(rootNodes);
2053
- blockCardComponentRef.changeDetectorRef.detectChanges();
2054
- return blockCardComponentRef;
1814
+
1815
+ class BaseLeafFlavour extends BaseFlavour {
1816
+ get text() {
1817
+ return this.context && this.context.text;
2055
1818
  }
2056
- else {
2057
- return null;
1819
+ get leaf() {
1820
+ return this.context && this.context.leaf;
2058
1821
  }
2059
- }
2060
- function trackBy(viewContext) {
2061
- return (index, node) => {
2062
- return viewContext.trackBy(node) || AngularEditor.findKey(viewContext.editor, node);
2063
- };
2064
- }
2065
- function memoizedContext(viewContext, descendant, prev, next) {
2066
- if (Element.isElement(descendant)) {
2067
- return memoizedElementContext(viewContext, prev, next);
2068
- }
2069
- else {
2070
- return memoizedTextContext(prev, next);
2071
- }
2072
- }
2073
- function memoizedElementContext(viewContext, prev, next) {
2074
- return (prev.element === next.element &&
2075
- (!viewContext.isStrictDecorate || prev.decorate === next.decorate) &&
2076
- prev.readonly === next.readonly &&
2077
- isDecoratorRangeListEqual(prev.decorations, next.decorations) &&
2078
- (prev.selection === next.selection || (!!prev.selection && !!next.selection && Range.equals(prev.selection, next.selection))));
2079
- }
2080
- function memoizedTextContext(prev, next) {
2081
- return (next.parent === prev.parent &&
2082
- next.isLast === prev.isLast &&
2083
- next.text === prev.text &&
2084
- isDecoratorRangeListEqual(next.decorations, prev.decorations));
2085
- }
2086
- function addAfterViewInitQueue(editor, afterViewInitCallback) {
2087
- const queue = getAfterViewInitQueue(editor);
2088
- queue.push(afterViewInitCallback);
2089
- EDITOR_TO_AFTER_VIEW_INIT_QUEUE.set(editor, queue);
2090
- }
2091
- function getAfterViewInitQueue(editor) {
2092
- return EDITOR_TO_AFTER_VIEW_INIT_QUEUE.get(editor) || [];
2093
- }
2094
- function clearAfterViewInitQueue(editor) {
2095
- EDITOR_TO_AFTER_VIEW_INIT_QUEUE.set(editor, []);
2096
- }
2097
- function executeAfterViewInit(editor) {
2098
- const queue = getAfterViewInitQueue(editor);
2099
- queue.forEach(callback => callback());
2100
- clearAfterViewInitQueue(editor);
2101
- }
2102
-
2103
- /**
2104
- * base class for custom element component or text component
2105
- */
2106
- class BaseComponent {
2107
- constructor() {
2108
- this.initialized = false;
2109
- this.elementRef = inject(ElementRef);
2110
- this.cdr = inject(ChangeDetectorRef);
2111
- }
2112
- set context(value) {
2113
- if (hasBeforeContextChange(this)) {
2114
- this.beforeContextChange(value);
2115
- }
2116
- this._context = value;
2117
- this.onContextChange();
2118
- if (this.initialized) {
2119
- this.cdr.detectChanges();
2120
- }
2121
- if (hasAfterContextChange(this)) {
2122
- this.afterContextChange();
2123
- }
2124
- }
2125
- get context() {
2126
- return this._context;
2127
- }
2128
- get editor() {
2129
- return this.viewContext && this.viewContext.editor;
2130
- }
2131
- get nativeElement() {
2132
- return this.elementRef.nativeElement;
2133
- }
2134
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: BaseComponent, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2135
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.14", type: BaseComponent, isStandalone: true, inputs: { context: "context", viewContext: "viewContext" }, ngImport: i0 }); }
2136
- }
2137
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: BaseComponent, decorators: [{
2138
- type: Directive
2139
- }], propDecorators: { context: [{
2140
- type: Input
2141
- }], viewContext: [{
2142
- type: Input
2143
- }] } });
2144
- /**
2145
- * base class for custom leaf component
2146
- */
2147
- class BaseLeafComponent extends BaseComponent {
2148
- constructor() {
2149
- super(...arguments);
2150
- this.isSlateLeaf = true;
2151
- }
2152
- get text() {
2153
- return this.context && this.context.text;
2154
- }
2155
- get leaf() {
2156
- return this.context && this.context.leaf;
2157
- }
2158
- ngOnInit() {
1822
+ onInit() {
1823
+ this.render();
1824
+ this.renderPlaceholder();
2159
1825
  this.initialized = true;
2160
1826
  }
2161
1827
  onContextChange() {
2162
1828
  if (!this.initialized) {
2163
1829
  return;
2164
1830
  }
1831
+ this.rerender();
1832
+ this.renderPlaceholder();
2165
1833
  }
2166
1834
  renderPlaceholder() {
2167
1835
  // issue-1: IME input was interrupted
@@ -2208,142 +1876,309 @@ class BaseLeafComponent extends BaseComponent {
2208
1876
  this.nativeElement.classList.remove('leaf-with-placeholder');
2209
1877
  }
2210
1878
  }
2211
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: BaseLeafComponent, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
2212
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.14", type: BaseLeafComponent, isStandalone: true, host: { properties: { "attr.data-slate-leaf": "this.isSlateLeaf" } }, usesInheritance: true, ngImport: i0 }); }
1879
+ onDestroy() {
1880
+ this.nativeElement?.remove();
1881
+ }
2213
1882
  }
2214
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: BaseLeafComponent, decorators: [{
2215
- type: Directive
2216
- }], propDecorators: { isSlateLeaf: [{
2217
- type: HostBinding,
2218
- args: ['attr.data-slate-leaf']
2219
- }] } });
2220
- /**
2221
- * base class for custom element component
2222
- */
2223
- class BaseElementComponent extends BaseComponent {
2224
- constructor() {
2225
- super(...arguments);
2226
- this.viewContainerRef = inject(ViewContainerRef);
2227
- this.getOutletParent = () => {
2228
- return this.elementRef.nativeElement;
2229
- };
2230
- this.getOutletElement = () => {
2231
- if (this.childrenOutletInstance) {
2232
- return this.childrenOutletInstance.getNativeElement();
2233
- }
2234
- return null;
2235
- };
1883
+
1884
+ var StringType;
1885
+ (function (StringType) {
1886
+ StringType["normalString"] = "normalString";
1887
+ StringType["lineBreakEmptyString"] = "lineBreakEmptyString";
1888
+ StringType["normalEmptyText"] = "normalEmptyText";
1889
+ StringType["compatibleString"] = "compatibleString";
1890
+ StringType["voidString"] = "voidString";
1891
+ })(StringType || (StringType = {}));
1892
+ class SlateStringRender {
1893
+ constructor(context, viewContext) {
1894
+ this.context = context;
1895
+ this.viewContext = viewContext;
2236
1896
  }
2237
- get element() {
2238
- return this._context && this._context.element;
1897
+ // COMPAT: If the text is empty, it's because it's on the edge of an inline
1898
+ // node, so we render a zero-width space so that the selection can be
1899
+ // inserted next to it still.
1900
+ isEmptyText() {
1901
+ return this.context.leaf.text === '';
2239
1902
  }
2240
- get selection() {
2241
- return this._context && this._context.selection;
1903
+ // COMPAT: Browsers will collapse trailing new lines at the end of blocks,
1904
+ // so we need to add an extra trailing new lines to prevent that.
1905
+ isCompatibleString() {
1906
+ return this.context.isLast && this.context.leaf.text.slice(-1) === '\n';
2242
1907
  }
2243
- get decorations() {
2244
- return this._context && this._context.decorations;
1908
+ // COMPAT: Render text inside void nodes with a zero-width space.
1909
+ // So the node can contain selection but the text is not visible.
1910
+ isVoid() {
1911
+ return this.viewContext.editor.isVoid(this.context.parent);
2245
1912
  }
2246
- get children() {
2247
- return this._context && this._context.element.children;
1913
+ get leaf() {
1914
+ return this.context && this.context.leaf;
2248
1915
  }
2249
- get isCollapsed() {
2250
- return this.selection && Range.isCollapsed(this.selection);
1916
+ // COMPAT: If this is the last text node in an empty block, render a zero-
1917
+ // width space that will convert into a line break when copying and pasting
1918
+ // to support expected plain text.
1919
+ isLineBreakEmptyString() {
1920
+ return (this.context.leaf.text === '' &&
1921
+ this.context.parent.children[this.context.parent.children.length - 1] === this.context.text &&
1922
+ !this.viewContext.editor.isInline(this.context.parent) &&
1923
+ // [list-render] performance optimization: reduce the number of calls to the `Editor.string(editor, path)` method
1924
+ isEmpty(this.viewContext.editor, this.context.parent));
2251
1925
  }
2252
- get isCollapsedAndNonReadonly() {
2253
- return this.selection && Range.isCollapsed(this.selection) && !this.readonly;
1926
+ createStringNode(type) {
1927
+ let newNativeElement;
1928
+ switch (type) {
1929
+ case StringType.lineBreakEmptyString:
1930
+ newNativeElement = createLineBreakEmptyStringDOM(this.getElementStringLength());
1931
+ break;
1932
+ case StringType.voidString:
1933
+ case StringType.normalEmptyText:
1934
+ newNativeElement = createEmptyOrVoidStringNode();
1935
+ break;
1936
+ case StringType.compatibleString:
1937
+ newNativeElement = createCompatibleStringNode(this.leaf.text);
1938
+ break;
1939
+ case StringType.normalString:
1940
+ newNativeElement = createDefaultStringNode(this.leaf.text);
1941
+ break;
1942
+ default:
1943
+ newNativeElement = createDefaultStringNode(this.leaf.text);
1944
+ }
1945
+ return newNativeElement;
2254
1946
  }
2255
- get readonly() {
2256
- return this._context && this._context.readonly;
1947
+ render() {
1948
+ this.type = this.getType();
1949
+ this.nativeElement = this.createStringNode(this.type);
1950
+ return this.nativeElement;
2257
1951
  }
2258
- ngOnInit() {
2259
- for (const key in this._context.attributes) {
2260
- this.nativeElement.setAttribute(key, this._context.attributes[key]);
2261
- }
2262
- this.initialized = true;
2263
- this.listRender = new ListRender(this.viewContext, this.viewContainerRef, this.getOutletParent, this.getOutletElement);
2264
- if (this.editor.isExpanded(this.element)) {
2265
- this.listRender.initialize(this.children, this.element, this.childrenContext);
1952
+ getType() {
1953
+ if (this.isLineBreakEmptyString()) {
1954
+ return StringType.lineBreakEmptyString;
2266
1955
  }
2267
- addAfterViewInitQueue(this.editor, () => {
2268
- this.afterViewInit();
2269
- });
2270
- }
2271
- afterViewInit() {
2272
- if (this._context.contentEditable !== undefined) {
2273
- this.nativeElement.setAttribute('contenteditable', this._context.contentEditable + '');
1956
+ if (this.isVoid()) {
1957
+ return StringType.voidString;
2274
1958
  }
2275
- }
2276
- updateWeakMap() {
2277
- NODE_TO_ELEMENT.set(this.element, this.nativeElement);
2278
- ELEMENT_TO_NODE.set(this.nativeElement, this.element);
2279
- ELEMENT_TO_COMPONENT.set(this.element, this);
2280
- }
2281
- ngOnDestroy() {
2282
- if (NODE_TO_ELEMENT.get(this.element) === this.nativeElement) {
2283
- NODE_TO_ELEMENT.delete(this.element);
1959
+ if (this.isEmptyText()) {
1960
+ return StringType.normalEmptyText;
2284
1961
  }
2285
- ELEMENT_TO_NODE.delete(this.nativeElement);
2286
- if (ELEMENT_TO_COMPONENT.get(this.element) === this) {
2287
- ELEMENT_TO_COMPONENT.delete(this.element);
1962
+ if (this.isCompatibleString()) {
1963
+ return StringType.compatibleString;
2288
1964
  }
1965
+ return StringType.normalString;
2289
1966
  }
2290
- onContextChange() {
2291
- this.childrenContext = this.getChildrenContext();
2292
- this.updateWeakMap();
2293
- if (!this.initialized) {
1967
+ update(context, viewContext) {
1968
+ this.context = context;
1969
+ this.viewContext = viewContext;
1970
+ const type = this.getType();
1971
+ if (type !== this.type) {
1972
+ const newNativeElement = this.createStringNode(type);
1973
+ this.nativeElement.replaceWith(newNativeElement);
1974
+ this.nativeElement = newNativeElement;
1975
+ this.type = type;
2294
1976
  return;
2295
1977
  }
2296
- this.updateChildrenView();
2297
- }
2298
- updateChildrenView() {
2299
- if (this.editor.isExpanded(this.element)) {
2300
- this.listRender.update(this.children, this.element, this.childrenContext);
2301
- }
2302
- else {
2303
- if (this.listRender.initialized) {
2304
- this.listRender.destroy();
2305
- }
1978
+ if (this.type === StringType.normalString) {
1979
+ this.nativeElement.textContent = this.leaf.text;
2306
1980
  }
2307
1981
  }
2308
- getChildrenContext() {
2309
- return {
2310
- parent: this._context.element,
2311
- selection: this._context.selection,
2312
- decorations: this._context.decorations,
2313
- decorate: this._context.decorate,
2314
- readonly: this._context.readonly
2315
- };
1982
+ getElementStringLength() {
1983
+ return Node.string(this.context.parent).length;
2316
1984
  }
2317
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: BaseElementComponent, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
2318
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.14", type: BaseElementComponent, isStandalone: true, viewQueries: [{ propertyName: "childrenOutletInstance", first: true, predicate: SlateChildrenOutlet, descendants: true, static: true }], usesInheritance: true, ngImport: i0 }); }
2319
1985
  }
2320
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: BaseElementComponent, decorators: [{
2321
- type: Directive
2322
- }], propDecorators: { childrenOutletInstance: [{
2323
- type: ViewChild,
2324
- args: [SlateChildrenOutlet, { static: true }]
2325
- }] } });
1986
+ const createDefaultStringNode = (text) => {
1987
+ const stringNode = document.createElement('span');
1988
+ stringNode.textContent = text;
1989
+ stringNode.setAttribute('data-slate-string', 'true');
1990
+ stringNode.setAttribute('editable-text', '');
1991
+ return stringNode;
1992
+ };
1993
+ const createEmptyOrVoidStringNode = () => {
1994
+ const stringNode = document.createElement('span');
1995
+ stringNode.setAttribute('data-slate-string', 'true');
1996
+ stringNode.setAttribute('data-slate-zero-width', 'z');
1997
+ stringNode.setAttribute('data-slate-length', '0');
1998
+ const zeroWidthSpace = document.createTextNode('\uFEFF');
1999
+ stringNode.appendChild(zeroWidthSpace);
2000
+ stringNode.setAttribute('editable-text', '');
2001
+ return stringNode;
2002
+ };
2003
+ const createCompatibleStringNode = (text) => {
2004
+ const stringNode = document.createElement('span');
2005
+ stringNode.setAttribute('data-slate-string', 'true');
2006
+ stringNode.textContent = text;
2007
+ stringNode.setAttribute('editable-text', '');
2008
+ const zeroWidthSpan = document.createElement('span');
2009
+ const zeroWidthSpace = document.createTextNode('\uFEFF');
2010
+ zeroWidthSpan.setAttribute('data-slate-zero-width', '');
2011
+ zeroWidthSpan.appendChild(zeroWidthSpace);
2012
+ stringNode.appendChild(zeroWidthSpan);
2013
+ return stringNode;
2014
+ };
2015
+ const createLineBreakEmptyStringDOM = (elementStringLength) => {
2016
+ const stringNode = document.createElement('span');
2017
+ stringNode.setAttribute('data-slate-zero-width', 'n');
2018
+ stringNode.setAttribute('data-slate-length', `${elementStringLength}`);
2019
+ const zeroWidthSpace = document.createTextNode(`\uFEFF`);
2020
+ stringNode.appendChild(zeroWidthSpace);
2021
+ const brNode = document.createElement('br');
2022
+ stringNode.appendChild(brNode);
2023
+ stringNode.setAttribute('editable-text', '');
2024
+ return stringNode;
2025
+ };
2326
2026
  /**
2327
- * base class for custom text component
2027
+ * TODO: remove when bump slate
2028
+ * copy from slate
2029
+ * @param editor
2030
+ * @param element
2031
+ * @returns
2328
2032
  */
2329
- class BaseTextComponent extends BaseComponent {
2033
+ const isEmpty = (editor, element) => {
2034
+ const { children } = element;
2035
+ const [first] = children;
2036
+ return children.length === 0 || (children.length === 1 && Text$1.isText(first) && first.text === '' && !editor.isVoid(element));
2037
+ };
2038
+
2039
+ class DefaultLeafFlavour extends BaseLeafFlavour {
2330
2040
  constructor() {
2331
2041
  super(...arguments);
2332
- this.viewContainerRef = inject(ViewContainerRef);
2333
- this.getOutletParent = () => {
2334
- return this.elementRef.nativeElement;
2335
- };
2336
- this.getOutletElement = () => {
2337
- if (this.childrenOutletInstance) {
2338
- return this.childrenOutletInstance.getNativeElement();
2339
- }
2340
- return null;
2341
- };
2042
+ this.stringRender = null;
2342
2043
  }
2343
- get text() {
2044
+ render() {
2045
+ const leafNode = createDefaultLeafNode();
2046
+ this.stringRender = new SlateStringRender(this.context, this.viewContext);
2047
+ const stringNode = this.stringRender.render();
2048
+ leafNode.appendChild(stringNode);
2049
+ this.nativeElement = leafNode;
2050
+ }
2051
+ rerender() {
2052
+ this.stringRender?.update(this.context, this.viewContext);
2053
+ }
2054
+ }
2055
+ const createDefaultLeafNode = () => {
2056
+ const span = document.createElement('span');
2057
+ span.setAttribute('data-slate-leaf', 'true');
2058
+ return span;
2059
+ };
2060
+
2061
+ class LeavesRender {
2062
+ constructor(viewContext, viewContainerRef, getOutletParent, getOutletElement) {
2063
+ this.viewContext = viewContext;
2064
+ this.viewContainerRef = viewContainerRef;
2065
+ this.getOutletParent = getOutletParent;
2066
+ this.getOutletElement = getOutletElement;
2067
+ this.views = [];
2068
+ this.contexts = [];
2069
+ this.viewTypes = [];
2070
+ }
2071
+ initialize(context) {
2072
+ const { decoratedLeaves, contexts } = this.getLeaves(context);
2073
+ this.decoratedLeaves = decoratedLeaves;
2074
+ this.contexts = contexts;
2075
+ this.decoratedLeaves.forEach((leaf, index) => {
2076
+ const context = getContext$1(index, this.contexts);
2077
+ const viewType = getViewType$1(context, this.viewContext);
2078
+ const view = createEmbeddedViewOrComponentOrFlavour(viewType, context, this.viewContext, this.viewContainerRef);
2079
+ this.views.push(view);
2080
+ this.contexts.push(context);
2081
+ this.viewTypes.push(viewType);
2082
+ });
2083
+ mount(this.views, null, this.getOutletParent(), this.getOutletElement());
2084
+ const newDiffers = this.viewContext.editor.injector.get(IterableDiffers);
2085
+ this.differ = newDiffers.find(this.decoratedLeaves).create(trackBy$1(this.viewContext));
2086
+ this.differ.diff(this.decoratedLeaves);
2087
+ }
2088
+ update(context) {
2089
+ const { decoratedLeaves, contexts } = this.getLeaves(context);
2090
+ const outletParent = this.getOutletParent();
2091
+ const diffResult = this.differ.diff(decoratedLeaves);
2092
+ if (diffResult) {
2093
+ let firstRootNode = getRootNodes(this.views[0])[0];
2094
+ const newContexts = [];
2095
+ const newViewTypes = [];
2096
+ const newViews = [];
2097
+ diffResult.forEachItem(record => {
2098
+ let context = getContext$1(record.currentIndex, contexts);
2099
+ const viewType = getViewType$1(context, this.viewContext);
2100
+ newViewTypes.push(viewType);
2101
+ let view;
2102
+ if (record.previousIndex === null) {
2103
+ view = createEmbeddedViewOrComponentOrFlavour(viewType, context, this.viewContext, this.viewContainerRef);
2104
+ newContexts.push(context);
2105
+ newViews.push(view);
2106
+ mountOnItemChange(record.currentIndex, record.item, newViews, null, outletParent, firstRootNode, this.viewContext);
2107
+ }
2108
+ else {
2109
+ const previousView = this.views[record.previousIndex];
2110
+ const previousViewType = this.viewTypes[record.previousIndex];
2111
+ if (previousViewType !== viewType) {
2112
+ view = createEmbeddedViewOrComponentOrFlavour(viewType, context, this.viewContext, this.viewContainerRef);
2113
+ const firstRootNode = getRootNodes(previousView, null)[0];
2114
+ const newRootNodes = getRootNodes(view, null);
2115
+ firstRootNode.replaceWith(...newRootNodes);
2116
+ previousView.destroy();
2117
+ }
2118
+ else {
2119
+ view = previousView;
2120
+ updateContext(previousView, context, this.viewContext);
2121
+ }
2122
+ newContexts.push(context);
2123
+ newViews.push(view);
2124
+ }
2125
+ });
2126
+ diffResult.forEachRemovedItem(record => {
2127
+ const view = this.views[record.previousIndex];
2128
+ view.destroy();
2129
+ });
2130
+ diffResult.forEachMovedItem(record => {
2131
+ mountOnItemChange(record.currentIndex, record.item, newViews, null, outletParent, firstRootNode, this.viewContext);
2132
+ });
2133
+ this.viewTypes = newViewTypes;
2134
+ this.views = newViews;
2135
+ this.contexts = newContexts;
2136
+ this.decoratedLeaves = decoratedLeaves;
2137
+ }
2138
+ }
2139
+ getLeaves(context) {
2140
+ const decoratedLeaves = Text$1.decorations(context.text, context.decorations);
2141
+ const contexts = decoratedLeaves.map((decoratedLeaf, index) => {
2142
+ return {
2143
+ leaf: decoratedLeaf.leaf,
2144
+ leafPosition: decoratedLeaf.position,
2145
+ text: context.text,
2146
+ parent: context.parent,
2147
+ index,
2148
+ isLast: context.isLast && index === decoratedLeaves.length - 1
2149
+ };
2150
+ });
2151
+ return { decoratedLeaves, contexts };
2152
+ }
2153
+ }
2154
+ function getContext$1(index, leafContexts) {
2155
+ return leafContexts[index];
2156
+ }
2157
+ function getViewType$1(leafContext, viewContext) {
2158
+ return (viewContext.renderLeaf && viewContext.renderLeaf(leafContext.leaf)) || DefaultLeafFlavour;
2159
+ }
2160
+ function trackBy$1(viewContext) {
2161
+ return (index, node) => {
2162
+ return index;
2163
+ };
2164
+ }
2165
+
2166
+ class BaseTextFlavour extends BaseFlavour {
2167
+ constructor() {
2168
+ super(...arguments);
2169
+ this.getOutletParent = () => {
2170
+ return this.nativeElement;
2171
+ };
2172
+ this.getOutletElement = () => {
2173
+ return this.nativeElement.querySelector('.children-outlet');
2174
+ };
2175
+ }
2176
+ get text() {
2344
2177
  return this._context && this._context.text;
2345
2178
  }
2346
- ngOnInit() {
2179
+ onInit() {
2180
+ this.render();
2181
+ this.updateWeakMap();
2347
2182
  this.initialized = true;
2348
2183
  this.leavesRender = new LeavesRender(this.viewContext, this.viewContainerRef, this.getOutletParent, this.getOutletElement);
2349
2184
  this.leavesRender.initialize(this.context);
@@ -2352,390 +2187,337 @@ class BaseTextComponent extends BaseComponent {
2352
2187
  ELEMENT_TO_NODE.set(this.nativeElement, this.text);
2353
2188
  NODE_TO_ELEMENT.set(this.text, this.nativeElement);
2354
2189
  }
2355
- ngOnDestroy() {
2190
+ onDestroy() {
2356
2191
  if (NODE_TO_ELEMENT.get(this.text) === this.nativeElement) {
2357
2192
  NODE_TO_ELEMENT.delete(this.text);
2358
2193
  }
2359
2194
  ELEMENT_TO_NODE.delete(this.nativeElement);
2195
+ this.nativeElement?.remove();
2360
2196
  }
2361
2197
  onContextChange() {
2362
- this.updateWeakMap();
2363
2198
  if (!this.initialized) {
2364
2199
  return;
2365
2200
  }
2201
+ this.rerender();
2202
+ this.updateWeakMap();
2366
2203
  this.leavesRender.update(this.context);
2367
2204
  }
2368
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: BaseTextComponent, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
2369
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.14", type: BaseTextComponent, isStandalone: true, viewQueries: [{ propertyName: "childrenOutletInstance", first: true, predicate: SlateChildrenOutlet, descendants: true, static: true }], usesInheritance: true, ngImport: i0 }); }
2370
2205
  }
2371
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: BaseTextComponent, decorators: [{
2372
- type: Directive
2373
- }], propDecorators: { childrenOutletInstance: [{
2374
- type: ViewChild,
2375
- args: [SlateChildrenOutlet, { static: true }]
2376
- }] } });
2377
2206
 
2378
- class SlateVoidText extends BaseTextComponent {
2379
- ngOnInit() {
2380
- super.ngOnInit();
2381
- }
2382
- ngOnChanges() {
2383
- if (!this.initialized) {
2384
- return;
2385
- }
2207
+ class DefaultTextFlavour extends BaseTextFlavour {
2208
+ render() {
2209
+ const { nativeElement } = createText(this.text.text);
2210
+ this.nativeElement = nativeElement;
2386
2211
  }
2387
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SlateVoidText, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
2388
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", 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 }); }
2389
- }
2390
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SlateVoidText, decorators: [{
2391
- type: Component,
2392
- args: [{
2393
- selector: 'span[slateVoidText]',
2394
- template: ``,
2395
- changeDetection: ChangeDetectionStrategy.OnPush,
2396
- host: {
2397
- 'data-slate-spacer': 'true',
2398
- class: 'slate-spacer',
2399
- 'data-slate-node': 'text'
2400
- }
2401
- }]
2402
- }] });
2403
-
2404
- class SlateDefaultText extends BaseTextComponent {
2405
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SlateDefaultText, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
2406
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: SlateDefaultText, isStandalone: true, selector: "span[slateDefaultText]", host: { attributes: { "data-slate-node": "text" } }, usesInheritance: true, ngImport: i0, template: ``, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2212
+ rerender() { }
2407
2213
  }
2408
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SlateDefaultText, decorators: [{
2409
- type: Component,
2410
- args: [{
2411
- selector: 'span[slateDefaultText]',
2412
- template: ``,
2413
- changeDetection: ChangeDetectionStrategy.OnPush,
2414
- host: {
2415
- 'data-slate-node': 'text'
2416
- }
2417
- }]
2418
- }] });
2419
-
2420
- class SlateDefaultElement extends BaseElementComponent {
2421
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SlateDefaultElement, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
2422
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: SlateDefaultElement, isStandalone: true, selector: "div[slateDefaultElement]", usesInheritance: true, ngImport: i0, template: ``, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2214
+ class VoidTextFlavour extends BaseTextFlavour {
2215
+ render() {
2216
+ const { nativeElement } = createText(this.text.text);
2217
+ this.nativeElement = nativeElement;
2218
+ this.nativeElement.setAttribute('data-slate-spacer', 'true');
2219
+ this.nativeElement.classList.add('slate-spacer');
2220
+ }
2221
+ rerender() { }
2423
2222
  }
2424
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SlateDefaultElement, decorators: [{
2425
- type: Component,
2426
- args: [{
2427
- selector: 'div[slateDefaultElement]',
2428
- template: ``,
2429
- changeDetection: ChangeDetectionStrategy.OnPush
2430
- }]
2431
- }] });
2223
+ const createText = (text) => {
2224
+ const nativeElement = document.createElement('span');
2225
+ nativeElement.setAttribute('data-slate-node', 'text');
2226
+ return { nativeElement };
2227
+ };
2432
2228
 
2433
- /**
2434
- * Dynamically create/update components or templates
2435
- * Provide rootNodes for the view container
2436
- * If the dynamically created component uses onpush mode, then it must call markForCheck when setting the context
2437
- */
2438
- class ViewContainerItem {
2439
- constructor() {
2229
+ class ListRender {
2230
+ constructor(viewContext, viewContainerRef, getOutletParent, getOutletElement) {
2231
+ this.viewContext = viewContext;
2232
+ this.viewContainerRef = viewContainerRef;
2233
+ this.getOutletParent = getOutletParent;
2234
+ this.getOutletElement = getOutletElement;
2235
+ this.views = [];
2236
+ this.blockCards = [];
2237
+ this.contexts = [];
2238
+ this.viewTypes = [];
2239
+ this.differ = null;
2440
2240
  this.initialized = false;
2441
- this.viewContainerRef = inject(ViewContainerRef);
2442
- }
2443
- get rootNodes() {
2444
- return this.getRootNodes();
2445
- }
2446
- getRootNodes() {
2447
- if (this.embeddedViewRef) {
2448
- return this.embeddedViewRef.rootNodes.filter(rootNode => isDOMElement(rootNode));
2449
- }
2450
- if (this.componentRef) {
2451
- return [this.componentRef.instance.nativeElement];
2452
- }
2453
- return [];
2454
- }
2455
- destroyView() {
2456
- if (this.embeddedViewRef) {
2457
- this.embeddedViewRef.destroy();
2458
- this.embeddedViewRef = null;
2459
- }
2460
- if (this.componentRef) {
2461
- this.componentRef.destroy();
2462
- this.componentRef = null;
2463
- }
2464
2241
  }
2465
- createView() {
2242
+ initialize(children, parent, childrenContext) {
2466
2243
  this.initialized = true;
2467
- this.viewType = this.getViewType();
2468
- const context = this.getContext();
2469
- if (isTemplateRef(this.viewType)) {
2470
- this.embeddedViewContext = {
2471
- context,
2472
- viewContext: this.viewContext
2473
- };
2474
- const embeddedViewRef = this.viewContainerRef.createEmbeddedView(this.viewType, this.embeddedViewContext);
2475
- this.embeddedViewRef = embeddedViewRef;
2476
- }
2477
- if (isComponentType(this.viewType)) {
2478
- const componentRef = this.viewContainerRef.createComponent(this.viewType);
2479
- componentRef.instance.viewContext = this.viewContext;
2480
- componentRef.instance.context = context;
2481
- this.componentRef = componentRef;
2482
- }
2483
- }
2484
- updateView() {
2485
- const viewType = this.getViewType();
2486
- const context = this.getContext();
2487
- if (this.viewType === viewType) {
2488
- if (this.componentRef) {
2489
- if (this.memoizedContext(this.componentRef.instance.context, context)) {
2490
- return;
2491
- }
2492
- this.componentRef.instance.context = context;
2493
- }
2494
- if (this.embeddedViewRef) {
2495
- if (this.memoizedContext(this.embeddedViewContext.context, context)) {
2496
- return;
2497
- }
2498
- this.embeddedViewContext.context = context;
2499
- }
2500
- }
2501
- else {
2502
- this.viewType = viewType;
2503
- const firstRootNode = this.rootNodes[0];
2504
- if (isTemplateRef(this.viewType)) {
2505
- this.embeddedViewContext = {
2506
- context,
2507
- viewContext: this.viewContext
2508
- };
2509
- const embeddedViewRef = this.viewContainerRef.createEmbeddedView(this.viewType, this.embeddedViewContext);
2510
- firstRootNode.replaceWith(...embeddedViewRef.rootNodes.filter(rootNode => isDOMElement(rootNode)));
2511
- this.destroyView();
2512
- this.embeddedViewRef = embeddedViewRef;
2513
- }
2514
- if (isComponentType(this.viewType)) {
2515
- const componentRef = this.viewContainerRef.createComponent(this.viewType);
2516
- componentRef.instance.viewContext = this.viewContext;
2517
- componentRef.instance.context = context;
2518
- firstRootNode.replaceWith(componentRef.instance.nativeElement);
2519
- this.destroyView();
2520
- this.componentRef = componentRef;
2521
- }
2244
+ this.children = children;
2245
+ const parentPath = AngularEditor.findPath(this.viewContext.editor, parent);
2246
+ children.forEach((descendant, index) => {
2247
+ NODE_TO_INDEX.set(descendant, index);
2248
+ NODE_TO_PARENT.set(descendant, parent);
2249
+ const context = getContext(index, descendant, parentPath, childrenContext, this.viewContext);
2250
+ const viewType = getViewType(descendant, parent, this.viewContext);
2251
+ const view = createEmbeddedViewOrComponentOrFlavour(viewType, context, this.viewContext, this.viewContainerRef);
2252
+ const blockCard = createBlockCard(descendant, view, this.viewContainerRef, this.viewContext);
2253
+ this.views.push(view);
2254
+ this.contexts.push(context);
2255
+ this.viewTypes.push(viewType);
2256
+ this.blockCards.push(blockCard);
2257
+ });
2258
+ mount(this.views, this.blockCards, this.getOutletParent(), this.getOutletElement());
2259
+ const newDiffers = this.viewContext.editor.injector.get(IterableDiffers);
2260
+ this.differ = newDiffers.find(children).create(trackBy(this.viewContext));
2261
+ this.differ.diff(children);
2262
+ if (parent === this.viewContext.editor) {
2263
+ executeAfterViewInit(this.viewContext.editor);
2522
2264
  }
2523
2265
  }
2524
- appendBlockCardElement() {
2525
- if (this.blockCardComponentRef) {
2526
- this.blockCardComponentRef.instance.append();
2266
+ update(children, parent, childrenContext) {
2267
+ if (!this.initialized || this.children.length === 0) {
2268
+ this.initialize(children, parent, childrenContext);
2269
+ return;
2527
2270
  }
2528
- }
2529
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ViewContainerItem, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2530
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.14", type: ViewContainerItem, isStandalone: true, inputs: { viewContext: "viewContext" }, ngImport: i0 }); }
2531
- }
2532
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ViewContainerItem, decorators: [{
2533
- type: Directive
2534
- }], propDecorators: { viewContext: [{
2535
- type: Input
2536
- }] } });
2537
-
2538
- class SlateDefaultString extends BaseComponent {
2539
- beforeContextChange(value) {
2540
- if (this.context) {
2541
- if (this.context.type === 'lineBreakEmptyString') {
2542
- if (value.type === 'string') {
2543
- this.removeLineBreakEmptyStringDOM();
2271
+ if (!this.differ) {
2272
+ throw new Error('Exception: Can not find differ ');
2273
+ }
2274
+ const outletParent = this.getOutletParent();
2275
+ const diffResult = this.differ.diff(children);
2276
+ const parentPath = AngularEditor.findPath(this.viewContext.editor, parent);
2277
+ if (diffResult) {
2278
+ let firstRootNode = getRootNodes(this.views[0], this.blockCards[0])[0];
2279
+ const newContexts = [];
2280
+ const newViewTypes = [];
2281
+ const newViews = [];
2282
+ const newBlockCards = [];
2283
+ diffResult.forEachItem(record => {
2284
+ NODE_TO_INDEX.set(record.item, record.currentIndex);
2285
+ NODE_TO_PARENT.set(record.item, parent);
2286
+ let context = getContext(record.currentIndex, record.item, parentPath, childrenContext, this.viewContext);
2287
+ const viewType = getViewType(record.item, parent, this.viewContext);
2288
+ newViewTypes.push(viewType);
2289
+ let view;
2290
+ let blockCard;
2291
+ if (record.previousIndex === null) {
2292
+ view = createEmbeddedViewOrComponentOrFlavour(viewType, context, this.viewContext, this.viewContainerRef);
2293
+ blockCard = createBlockCard(record.item, view, this.viewContainerRef, this.viewContext);
2294
+ newContexts.push(context);
2295
+ newViews.push(view);
2296
+ newBlockCards.push(blockCard);
2297
+ mountOnItemChange(record.currentIndex, record.item, newViews, newBlockCards, outletParent, firstRootNode, this.viewContext);
2544
2298
  }
2545
2299
  else {
2546
- this.textNode?.remove();
2547
- this.brNode?.remove();
2548
- }
2549
- }
2550
- if (this.context.type === 'string') {
2551
- if (value.type === 'lineBreakEmptyString') {
2552
- this.removeStringDOM();
2553
- }
2554
- }
2555
- }
2556
- }
2557
- onContextChange() {
2558
- if (this.context.type === 'string') {
2559
- this.createStringDOM();
2560
- }
2561
- else if (this.context.type === 'lineBreakEmptyString') {
2562
- this.createLineBreakEmptyStringDOM();
2300
+ const previousView = this.views[record.previousIndex];
2301
+ const previousViewType = this.viewTypes[record.previousIndex];
2302
+ const previousContext = this.contexts[record.previousIndex];
2303
+ const previousBlockCard = this.blockCards[record.previousIndex];
2304
+ if (previousViewType !== viewType) {
2305
+ view = createEmbeddedViewOrComponentOrFlavour(viewType, context, this.viewContext, this.viewContainerRef);
2306
+ blockCard = createBlockCard(record.item, view, this.viewContainerRef, this.viewContext);
2307
+ const firstRootNode = getRootNodes(previousView, previousBlockCard)[0];
2308
+ const newRootNodes = getRootNodes(view, blockCard);
2309
+ firstRootNode.replaceWith(...newRootNodes);
2310
+ previousView.destroy();
2311
+ previousBlockCard?.destroy();
2312
+ }
2313
+ else {
2314
+ view = previousView;
2315
+ blockCard = previousBlockCard;
2316
+ if (memoizedContext(this.viewContext, record.item, previousContext, context)) {
2317
+ context = previousContext;
2318
+ }
2319
+ else {
2320
+ updateContext(previousView, context, this.viewContext);
2321
+ }
2322
+ }
2323
+ newContexts.push(context);
2324
+ newViews.push(view);
2325
+ newBlockCards.push(blockCard);
2326
+ }
2327
+ });
2328
+ diffResult.forEachOperation(record => {
2329
+ // removed
2330
+ if (record.currentIndex === null) {
2331
+ const view = this.views[record.previousIndex];
2332
+ const blockCard = this.blockCards[record.previousIndex];
2333
+ view.destroy();
2334
+ blockCard?.destroy();
2335
+ }
2336
+ // moved
2337
+ if (record.previousIndex !== null && record.currentIndex !== null) {
2338
+ mountOnItemChange(record.currentIndex, record.item, newViews, newBlockCards, outletParent, firstRootNode, this.viewContext);
2339
+ // Solve the block-card DOMElement loss when moving nodes
2340
+ newBlockCards[record.currentIndex]?.instance.append();
2341
+ }
2342
+ });
2343
+ this.viewTypes = newViewTypes;
2344
+ this.views = newViews;
2345
+ this.contexts = newContexts;
2346
+ this.children = children;
2347
+ this.blockCards = newBlockCards;
2348
+ if (parent === this.viewContext.editor) {
2349
+ executeAfterViewInit(this.viewContext.editor);
2350
+ }
2563
2351
  }
2564
- }
2565
- createLineBreakEmptyStringDOM() {
2566
- this.nativeElement.setAttribute('data-slate-zero-width', 'n');
2567
- this.nativeElement.setAttribute('data-slate-length', `${this.context.elementStringLength}`);
2568
- this.textNode = document.createTextNode(`\uFEFF`);
2569
- this.brNode = document.createElement('br');
2570
- this.nativeElement.append(this.textNode, this.brNode);
2571
- }
2572
- removeLineBreakEmptyStringDOM() {
2573
- this.brNode?.remove();
2574
- // remove zero width character
2575
- const zeroWidthCharacterIndex = this.textNode?.textContent.indexOf(`\uFEFF`);
2576
- this.textNode?.deleteData(zeroWidthCharacterIndex, 1);
2577
- this.nativeElement.removeAttribute('data-slate-zero-width');
2578
- this.nativeElement.removeAttribute('data-slate-length');
2579
- }
2580
- createStringDOM() {
2581
- this.nativeElement.setAttribute('data-slate-string', 'true');
2582
- this.updateStringDOM();
2583
- }
2584
- updateStringDOM() {
2585
- // Avoid breaking some browser default behaviors, such as spellCheck, android composition input state
2586
- if (this.nativeElement.textContent !== this.context.text) {
2587
- this.nativeElement.textContent = this.context.text;
2352
+ else {
2353
+ const newContexts = [];
2354
+ this.children.forEach((child, index) => {
2355
+ NODE_TO_INDEX.set(child, index);
2356
+ NODE_TO_PARENT.set(child, parent);
2357
+ let context = getContext(index, child, parentPath, childrenContext, this.viewContext);
2358
+ const previousContext = this.contexts[index];
2359
+ if (memoizedContext(this.viewContext, child, previousContext, context)) {
2360
+ context = previousContext;
2361
+ }
2362
+ else {
2363
+ updateContext(this.views[index], context, this.viewContext);
2364
+ }
2365
+ newContexts.push(context);
2366
+ });
2367
+ this.contexts = newContexts;
2588
2368
  }
2589
2369
  }
2590
- removeStringDOM() {
2591
- this.nativeElement.removeAttribute('data-slate-string');
2592
- this.nativeElement.textContent = '';
2593
- }
2594
- ngOnInit() {
2595
- this.nativeElement.setAttribute('editable-text', '');
2370
+ destroy() {
2371
+ this.children.forEach((element, index) => {
2372
+ if (this.views[index]) {
2373
+ this.views[index].destroy();
2374
+ }
2375
+ if (this.blockCards[index]) {
2376
+ this.blockCards[index].destroy();
2377
+ }
2378
+ });
2379
+ this.views = [];
2380
+ this.blockCards = [];
2381
+ this.contexts = [];
2382
+ this.viewTypes = [];
2383
+ this.initialized = false;
2384
+ this.differ = null;
2596
2385
  }
2597
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SlateDefaultString, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
2598
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: SlateDefaultString, isStandalone: true, selector: "span[slateDefaultString]", usesInheritance: true, ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2599
2386
  }
2600
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SlateDefaultString, decorators: [{
2601
- type: Component,
2602
- args: [{
2603
- selector: 'span[slateDefaultString]',
2604
- template: '',
2605
- changeDetection: ChangeDetectionStrategy.OnPush,
2606
- standalone: true
2607
- }]
2608
- }] });
2609
-
2610
- class SlateString extends ViewContainerItem {
2611
- constructor() {
2612
- super(...arguments);
2613
- this.elementRef = inject(ElementRef);
2614
- this.viewContainerRef = inject(ViewContainerRef);
2615
- }
2616
- ngOnInit() {
2617
- this.createView();
2618
- }
2619
- ngOnChanges() {
2620
- if (!this.initialized) {
2621
- return;
2387
+ function getContext(index, item, parentPath, childrenContext, viewContext) {
2388
+ if (Element.isElement(item)) {
2389
+ const computedContext = getCommonContext(index, item, parentPath, viewContext, childrenContext);
2390
+ const key = AngularEditor.findKey(viewContext.editor, item);
2391
+ const isInline = viewContext.editor.isInline(item);
2392
+ const isVoid = viewContext.editor.isVoid(item);
2393
+ const elementContext = {
2394
+ element: item,
2395
+ ...computedContext,
2396
+ attributes: {
2397
+ 'data-slate-node': 'element',
2398
+ 'data-slate-key': key.id
2399
+ },
2400
+ decorate: childrenContext.decorate,
2401
+ readonly: childrenContext.readonly
2402
+ };
2403
+ if (isInline) {
2404
+ elementContext.attributes['data-slate-inline'] = true;
2622
2405
  }
2623
- this.updateView();
2624
- }
2625
- ngAfterViewInit() {
2626
- this.elementRef.nativeElement.remove();
2627
- }
2628
- // COMPAT: If this is the last text node in an empty block, render a zero-
2629
- // width space that will convert into a line break when copying and pasting
2630
- // to support expected plain text.
2631
- isLineBreakEmptyString() {
2632
- return (this.context.leaf.text === '' &&
2633
- this.context.parent.children[this.context.parent.children.length - 1] === this.context.text &&
2634
- !this.viewContext.editor.isInline(this.context.parent) &&
2635
- // [list-render] performance optimization: reduce the number of calls to the `Editor.string(editor, path)` method
2636
- isEmpty(this.viewContext.editor, this.context.parent));
2637
- }
2638
- // COMPAT: If the text is empty, it's because it's on the edge of an inline
2639
- // node, so we render a zero-width space so that the selection can be
2640
- // inserted next to it still.
2641
- isEmptyText() {
2642
- return this.context.leaf.text === '';
2643
- }
2644
- // COMPAT: Browsers will collapse trailing new lines at the end of blocks,
2645
- // so we need to add an extra trailing new lines to prevent that.
2646
- isCompatibleString() {
2647
- return this.context.isLast && this.context.leaf.text.slice(-1) === '\n';
2648
- }
2649
- // COMPAT: Render text inside void nodes with a zero-width space.
2650
- // So the node can contain selection but the text is not visible.
2651
- isVoid() {
2652
- return this.viewContext.editor.isVoid(this.context.parent);
2653
- }
2654
- getViewType() {
2655
- if (this.isVoid()) {
2656
- return this.viewContext.templateComponent.voidStringTemplate;
2406
+ if (isVoid) {
2407
+ elementContext.attributes['data-slate-void'] = true;
2657
2408
  }
2658
- if (this.isLineBreakEmptyString()) {
2659
- return SlateDefaultString;
2409
+ // add contentEditable for block element only to avoid chinese input be broken
2410
+ if (isVoid && !isInline) {
2411
+ elementContext.contentEditable = false;
2660
2412
  }
2661
- if (this.isEmptyText()) {
2662
- return this.viewContext.templateComponent.emptyTextTemplate;
2413
+ return elementContext;
2414
+ }
2415
+ else {
2416
+ const computedContext = getCommonContext(index, item, parentPath, viewContext, childrenContext);
2417
+ const isLeafBlock = AngularEditor.isLeafBlock(viewContext.editor, childrenContext.parent);
2418
+ const textContext = {
2419
+ decorations: computedContext.decorations,
2420
+ isLast: isLeafBlock && index === childrenContext.parent.children.length - 1,
2421
+ parent: childrenContext.parent,
2422
+ text: item
2423
+ };
2424
+ return textContext;
2425
+ }
2426
+ }
2427
+ function getCommonContext(index, item, parentPath, viewContext, childrenContext) {
2428
+ const p = parentPath.concat(index);
2429
+ try {
2430
+ const ds = childrenContext.decorate([item, p]);
2431
+ // [list-render] performance optimization: reduce the number of calls to the `Editor.range(viewContext.editor, p)` method
2432
+ if (childrenContext.selection || childrenContext.decorations.length > 0) {
2433
+ const range = Editor.range(viewContext.editor, p);
2434
+ const sel = childrenContext.selection && Range.intersection(range, childrenContext.selection);
2435
+ for (const dec of childrenContext.decorations) {
2436
+ const d = Range.intersection(dec, range);
2437
+ if (d) {
2438
+ ds.push(d);
2439
+ }
2440
+ }
2441
+ return { selection: sel, decorations: ds };
2663
2442
  }
2664
- if (this.isCompatibleString()) {
2665
- return this.viewContext.templateComponent.compatibleStringTemplate;
2443
+ else {
2444
+ return { selection: null, decorations: ds };
2666
2445
  }
2667
- return SlateDefaultString;
2668
2446
  }
2669
- getType() {
2670
- if (this.isLineBreakEmptyString()) {
2671
- return 'lineBreakEmptyString';
2672
- }
2673
- return 'string';
2447
+ catch (error) {
2448
+ viewContext.editor.onError({
2449
+ code: SlateErrorCode.GetStartPointError,
2450
+ nativeError: error
2451
+ });
2452
+ return { selection: null, decorations: [] };
2674
2453
  }
2675
- getContext() {
2676
- const stringType = this.getType();
2677
- return {
2678
- text: this.context.leaf.text,
2679
- elementStringLength: Node.string(this.context.parent).length,
2680
- type: stringType
2681
- };
2454
+ }
2455
+ function getViewType(item, parent, viewContext) {
2456
+ if (Element.isElement(item)) {
2457
+ return (viewContext.renderElement && viewContext.renderElement(item)) || DefaultElementFlavour;
2682
2458
  }
2683
- memoizedContext(prev, next) {
2684
- return false;
2459
+ else {
2460
+ const isVoid = viewContext.editor.isVoid(parent);
2461
+ return isVoid ? VoidTextFlavour : (viewContext.renderText && viewContext.renderText(item)) || DefaultTextFlavour;
2685
2462
  }
2686
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SlateString, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
2687
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: SlateString, isStandalone: true, selector: "span[slateString]", inputs: { context: "context" }, usesInheritance: true, usesOnChanges: true, ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2688
2463
  }
2689
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SlateString, decorators: [{
2690
- type: Component,
2691
- args: [{
2692
- selector: 'span[slateString]',
2693
- template: '',
2694
- changeDetection: ChangeDetectionStrategy.OnPush,
2695
- standalone: true
2696
- }]
2697
- }], propDecorators: { context: [{
2698
- type: Input
2699
- }] } });
2700
- /**
2701
- * TODO: remove when bump slate
2702
- * copy from slate
2703
- * @param editor
2704
- * @param element
2705
- * @returns
2706
- */
2707
- const isEmpty = (editor, element) => {
2708
- const { children } = element;
2709
- const [first] = children;
2710
- return children.length === 0 || (children.length === 1 && Text$1.isText(first) && first.text === '' && !editor.isVoid(element));
2711
- };
2712
-
2713
- class SlateDefaultLeaf extends BaseLeafComponent {
2714
- onContextChange() {
2715
- super.onContextChange();
2716
- this.renderPlaceholder();
2464
+ function createBlockCard(item, view, viewContainerRef, viewContext) {
2465
+ const isBlockCard = viewContext.editor.isBlockCard(item);
2466
+ if (isBlockCard) {
2467
+ const rootNodes = getRootNodes(view);
2468
+ const blockCardComponentRef = viewContainerRef.createComponent(SlateBlockCard, {
2469
+ injector: viewContainerRef.injector
2470
+ });
2471
+ blockCardComponentRef.instance.initializeCenter(rootNodes);
2472
+ blockCardComponentRef.changeDetectorRef.detectChanges();
2473
+ return blockCardComponentRef;
2717
2474
  }
2718
- ngOnDestroy() {
2719
- // Because the placeholder span is not in the current component, it is destroyed along with the current component
2720
- this.destroyPlaceholder();
2475
+ else {
2476
+ return null;
2721
2477
  }
2722
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SlateDefaultLeaf, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
2723
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: SlateDefaultLeaf, isStandalone: true, selector: "span[slateDefaultLeaf]", host: { attributes: { "data-slate-leaf": "true" } }, usesInheritance: true, ngImport: i0, template: `<span slateString [context]="context" [viewContext]="viewContext"><span></span></span>`, isInline: true, dependencies: [{ kind: "component", type: SlateString, selector: "span[slateString]", inputs: ["context"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2724
2478
  }
2725
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SlateDefaultLeaf, decorators: [{
2726
- type: Component,
2727
- args: [{
2728
- selector: 'span[slateDefaultLeaf]',
2729
- template: `<span slateString [context]="context" [viewContext]="viewContext"><span></span></span>`,
2730
- changeDetection: ChangeDetectionStrategy.OnPush,
2731
- host: {
2732
- 'data-slate-leaf': 'true'
2733
- },
2734
- imports: [SlateString]
2735
- }]
2736
- }] });
2737
-
2738
- const SLATE_DEFAULT_LEAF_COMPONENT_TOKEN = new InjectionToken('slate-default-leaf-token');
2479
+ function trackBy(viewContext) {
2480
+ return (index, node) => {
2481
+ return viewContext.trackBy(node) || AngularEditor.findKey(viewContext.editor, node);
2482
+ };
2483
+ }
2484
+ function memoizedContext(viewContext, descendant, prev, next) {
2485
+ if (Element.isElement(descendant)) {
2486
+ return memoizedElementContext(viewContext, prev, next);
2487
+ }
2488
+ else {
2489
+ return memoizedTextContext(prev, next);
2490
+ }
2491
+ }
2492
+ function memoizedElementContext(viewContext, prev, next) {
2493
+ return (prev.element === next.element &&
2494
+ (!viewContext.isStrictDecorate || prev.decorate === next.decorate) &&
2495
+ prev.readonly === next.readonly &&
2496
+ isDecoratorRangeListEqual(prev.decorations, next.decorations) &&
2497
+ (prev.selection === next.selection || (!!prev.selection && !!next.selection && Range.equals(prev.selection, next.selection))));
2498
+ }
2499
+ function memoizedTextContext(prev, next) {
2500
+ return (next.parent === prev.parent &&
2501
+ next.isLast === prev.isLast &&
2502
+ next.text === prev.text &&
2503
+ isDecoratorRangeListEqual(next.decorations, prev.decorations));
2504
+ }
2505
+ function addAfterViewInitQueue(editor, afterViewInitCallback) {
2506
+ const queue = getAfterViewInitQueue(editor);
2507
+ queue.push(afterViewInitCallback);
2508
+ EDITOR_TO_AFTER_VIEW_INIT_QUEUE.set(editor, queue);
2509
+ }
2510
+ function getAfterViewInitQueue(editor) {
2511
+ return EDITOR_TO_AFTER_VIEW_INIT_QUEUE.get(editor) || [];
2512
+ }
2513
+ function clearAfterViewInitQueue(editor) {
2514
+ EDITOR_TO_AFTER_VIEW_INIT_QUEUE.set(editor, []);
2515
+ }
2516
+ function executeAfterViewInit(editor) {
2517
+ const queue = getAfterViewInitQueue(editor);
2518
+ queue.forEach(callback => callback());
2519
+ clearAfterViewInitQueue(editor);
2520
+ }
2739
2521
 
2740
2522
  // not correctly clipboardData on beforeinput
2741
2523
  const forceOnDOMPaste = IS_SAFARI;
@@ -2743,16 +2525,12 @@ class SlateEditable {
2743
2525
  get hasBeforeInputSupport() {
2744
2526
  return HAS_BEFORE_INPUT_SUPPORT;
2745
2527
  }
2746
- constructor(elementRef, renderer2, cdr, ngZone, injector, defaultElement, defaultText, defaultVoidText, defaultLeaf) {
2528
+ constructor(elementRef, renderer2, cdr, ngZone, injector) {
2747
2529
  this.elementRef = elementRef;
2748
2530
  this.renderer2 = renderer2;
2749
2531
  this.cdr = cdr;
2750
2532
  this.ngZone = ngZone;
2751
2533
  this.injector = injector;
2752
- this.defaultElement = defaultElement;
2753
- this.defaultText = defaultText;
2754
- this.defaultVoidText = defaultVoidText;
2755
- this.defaultLeaf = defaultLeaf;
2756
2534
  this.destroy$ = new Subject();
2757
2535
  this.isComposing = false;
2758
2536
  this.isDraggingInternally = false;
@@ -2774,6 +2552,7 @@ class SlateEditable {
2774
2552
  this.dataSlateEditor = true;
2775
2553
  this.dataSlateNode = 'value';
2776
2554
  this.dataGramm = false;
2555
+ //#endregion
2777
2556
  this.viewContainerRef = inject(ViewContainerRef);
2778
2557
  this.getOutletParent = () => {
2779
2558
  return this.elementRef.nativeElement;
@@ -2798,8 +2577,6 @@ class SlateEditable {
2798
2577
  });
2799
2578
  this.initializeViewContext();
2800
2579
  this.initializeContext();
2801
- // remove unused DOM, just keep templateComponent instance
2802
- this.templateElementRef.nativeElement.remove();
2803
2580
  // add browser class
2804
2581
  let browserClass = IS_FIREFOX ? 'firefox' : IS_SAFARI ? 'safari' : '';
2805
2582
  browserClass && this.elementRef.nativeElement.classList.add(browserClass);
@@ -2835,7 +2612,9 @@ class SlateEditable {
2835
2612
  this.editor.children = value;
2836
2613
  this.initializeContext();
2837
2614
  if (!this.listRender.initialized) {
2615
+ console.time('initialize list render');
2838
2616
  this.listRender.initialize(this.editor.children, this.editor, this.context);
2617
+ console.timeEnd('initialize list render');
2839
2618
  }
2840
2619
  else {
2841
2620
  this.listRender.update(this.editor.children, this.editor, this.context);
@@ -2970,7 +2749,7 @@ class SlateEditable {
2970
2749
  if (this.isComposing) {
2971
2750
  // Composition input text be not rendered when user composition input with selection is expanded
2972
2751
  // At this time, the following matching conditions are met, assign isComposing to false, and the status is wrong
2973
- // this time condition is true and isComposiing is assigned false
2752
+ // this time condition is true and isComposing is assigned false
2974
2753
  // Therefore, need to wait for the composition input text to be rendered before performing condition matching
2975
2754
  setTimeout(() => {
2976
2755
  const textNode = Node.get(this.editor, this.editor.selection.anchor.path);
@@ -3035,12 +2814,7 @@ class SlateEditable {
3035
2814
  renderLeaf: this.renderLeaf,
3036
2815
  renderText: this.renderText,
3037
2816
  trackBy: this.trackBy,
3038
- isStrictDecorate: this.isStrictDecorate,
3039
- templateComponent: this.templateComponent,
3040
- defaultElement: this.defaultElement,
3041
- defaultText: this.defaultText,
3042
- defaultVoidText: this.defaultVoidText,
3043
- defaultLeaf: this.defaultLeaf
2817
+ isStrictDecorate: this.isStrictDecorate
3044
2818
  };
3045
2819
  }
3046
2820
  composePlaceholderDecorate(editor) {
@@ -3765,30 +3539,14 @@ class SlateEditable {
3765
3539
  this.destroy$.complete();
3766
3540
  EDITOR_TO_ON_CHANGE.delete(this.editor);
3767
3541
  }
3768
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SlateEditable, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.ChangeDetectorRef }, { token: i0.NgZone }, { token: i0.Injector }, { token: SLATE_DEFAULT_ELEMENT_COMPONENT_TOKEN }, { token: SLATE_DEFAULT_TEXT_COMPONENT_TOKEN }, { token: SLATE_DEFAULT_VOID_TEXT_COMPONENT_TOKEN }, { token: SLATE_DEFAULT_LEAF_COMPONENT_TOKEN }], target: i0.ɵɵFactoryTarget.Component }); }
3542
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SlateEditable, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.ChangeDetectorRef }, { token: i0.NgZone }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Component }); }
3769
3543
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: SlateEditable, isStandalone: true, selector: "slate-editable", inputs: { editor: "editor", renderElement: "renderElement", renderLeaf: "renderLeaf", renderText: "renderText", decorate: "decorate", placeholderDecorate: "placeholderDecorate", scrollSelectionIntoView: "scrollSelectionIntoView", isStrictDecorate: "isStrictDecorate", trackBy: "trackBy", readonly: "readonly", placeholder: "placeholder", beforeInput: "beforeInput", blur: "blur", click: "click", compositionEnd: "compositionEnd", compositionUpdate: "compositionUpdate", compositionStart: "compositionStart", copy: "copy", cut: "cut", dragOver: "dragOver", dragStart: "dragStart", dragEnd: "dragEnd", drop: "drop", focus: "focus", keydown: "keydown", paste: "paste", spellCheck: "spellCheck", autoCorrect: "autoCorrect", autoCapitalize: "autoCapitalize" }, host: { properties: { "attr.contenteditable": "readonly ? undefined : true", "attr.role": "readonly ? undefined : 'textbox'", "attr.spellCheck": "!hasBeforeInputSupport ? false : spellCheck", "attr.autoCorrect": "!hasBeforeInputSupport ? 'false' : autoCorrect", "attr.autoCapitalize": "!hasBeforeInputSupport ? 'false' : autoCapitalize", "attr.data-slate-editor": "this.dataSlateEditor", "attr.data-slate-node": "this.dataSlateNode", "attr.data-gramm": "this.dataGramm" }, classAttribute: "slate-editable-container" }, providers: [
3770
3544
  {
3771
3545
  provide: NG_VALUE_ACCESSOR,
3772
3546
  useExisting: forwardRef(() => SlateEditable),
3773
3547
  multi: true
3774
- },
3775
- {
3776
- provide: SLATE_DEFAULT_ELEMENT_COMPONENT_TOKEN,
3777
- useValue: SlateDefaultElement
3778
- },
3779
- {
3780
- provide: SLATE_DEFAULT_TEXT_COMPONENT_TOKEN,
3781
- useValue: SlateDefaultText
3782
- },
3783
- {
3784
- provide: SLATE_DEFAULT_VOID_TEXT_COMPONENT_TOKEN,
3785
- useValue: SlateVoidText
3786
- },
3787
- {
3788
- provide: SLATE_DEFAULT_LEAF_COMPONENT_TOKEN,
3789
- useValue: SlateDefaultLeaf
3790
3548
  }
3791
- ], viewQueries: [{ propertyName: "templateComponent", first: true, predicate: ["templateComponent"], descendants: true, static: true }, { propertyName: "templateElementRef", first: true, predicate: ["templateComponent"], descendants: true, read: ElementRef, static: true }], usesOnChanges: true, ngImport: i0, template: "<slate-string-template #templateComponent></slate-string-template>\n", dependencies: [{ kind: "component", type: SlateStringTemplate, selector: "slate-string-template" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3549
+ ], usesOnChanges: true, ngImport: i0, template: "", changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3792
3550
  }
3793
3551
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SlateEditable, decorators: [{
3794
3552
  type: Component,
@@ -3804,37 +3562,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
3804
3562
  provide: NG_VALUE_ACCESSOR,
3805
3563
  useExisting: forwardRef(() => SlateEditable),
3806
3564
  multi: true
3807
- },
3808
- {
3809
- provide: SLATE_DEFAULT_ELEMENT_COMPONENT_TOKEN,
3810
- useValue: SlateDefaultElement
3811
- },
3812
- {
3813
- provide: SLATE_DEFAULT_TEXT_COMPONENT_TOKEN,
3814
- useValue: SlateDefaultText
3815
- },
3816
- {
3817
- provide: SLATE_DEFAULT_VOID_TEXT_COMPONENT_TOKEN,
3818
- useValue: SlateVoidText
3819
- },
3820
- {
3821
- provide: SLATE_DEFAULT_LEAF_COMPONENT_TOKEN,
3822
- useValue: SlateDefaultLeaf
3823
3565
  }
3824
- ], imports: [SlateStringTemplate], template: "<slate-string-template #templateComponent></slate-string-template>\n" }]
3825
- }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i0.ChangeDetectorRef }, { type: i0.NgZone }, { type: i0.Injector }, { type: undefined, decorators: [{
3826
- type: Inject,
3827
- args: [SLATE_DEFAULT_ELEMENT_COMPONENT_TOKEN]
3828
- }] }, { type: undefined, decorators: [{
3829
- type: Inject,
3830
- args: [SLATE_DEFAULT_TEXT_COMPONENT_TOKEN]
3831
- }] }, { type: undefined, decorators: [{
3832
- type: Inject,
3833
- args: [SLATE_DEFAULT_VOID_TEXT_COMPONENT_TOKEN]
3834
- }] }, { type: undefined, decorators: [{
3835
- type: Inject,
3836
- args: [SLATE_DEFAULT_LEAF_COMPONENT_TOKEN]
3837
- }] }], propDecorators: { editor: [{
3566
+ ], imports: [], template: "" }]
3567
+ }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i0.ChangeDetectorRef }, { type: i0.NgZone }, { type: i0.Injector }], propDecorators: { editor: [{
3838
3568
  type: Input
3839
3569
  }], renderElement: [{
3840
3570
  type: Input
@@ -3901,12 +3631,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
3901
3631
  }], dataGramm: [{
3902
3632
  type: HostBinding,
3903
3633
  args: ['attr.data-gramm']
3904
- }], templateComponent: [{
3905
- type: ViewChild,
3906
- args: ['templateComponent', { static: true }]
3907
- }], templateElementRef: [{
3908
- type: ViewChild,
3909
- args: ['templateComponent', { static: true, read: ElementRef }]
3910
3634
  }] } });
3911
3635
  const defaultScrollSelectionIntoView = (editor, domRange) => {
3912
3636
  // This was affecting the selection of multiple blocks and dragging behavior,
@@ -3924,173 +3648,385 @@ const defaultScrollSelectionIntoView = (editor, domRange) => {
3924
3648
  return;
3925
3649
  }
3926
3650
  }
3927
- leafEl.getBoundingClientRect = domRange.getBoundingClientRect.bind(domRange);
3928
- scrollIntoView(leafEl, {
3929
- scrollMode: 'if-needed'
3651
+ leafEl.getBoundingClientRect = domRange.getBoundingClientRect.bind(domRange);
3652
+ scrollIntoView(leafEl, {
3653
+ scrollMode: 'if-needed'
3654
+ });
3655
+ delete leafEl.getBoundingClientRect;
3656
+ }
3657
+ };
3658
+ /**
3659
+ * Check if the target is inside void and in the editor.
3660
+ */
3661
+ const isTargetInsideVoid = (editor, target) => {
3662
+ let slateNode = null;
3663
+ try {
3664
+ slateNode = AngularEditor.hasTarget(editor, target) && AngularEditor.toSlateNode(editor, target);
3665
+ }
3666
+ catch (error) { }
3667
+ return slateNode && Element.isElement(slateNode) && Editor.isVoid(editor, slateNode);
3668
+ };
3669
+ const hasStringTarget = (domSelection) => {
3670
+ return ((domSelection.anchorNode.parentElement.hasAttribute('data-slate-string') ||
3671
+ domSelection.anchorNode.parentElement.hasAttribute('data-slate-zero-width')) &&
3672
+ (domSelection.focusNode.parentElement.hasAttribute('data-slate-string') ||
3673
+ domSelection.focusNode.parentElement.hasAttribute('data-slate-zero-width')));
3674
+ };
3675
+ /**
3676
+ * remove default insert from composition
3677
+ * @param text
3678
+ */
3679
+ const preventInsertFromComposition = (event, editor) => {
3680
+ const types = ['compositionend', 'insertFromComposition'];
3681
+ if (!types.includes(event.type)) {
3682
+ return;
3683
+ }
3684
+ const insertText = event.data;
3685
+ const window = AngularEditor.getWindow(editor);
3686
+ const domSelection = window.getSelection();
3687
+ // ensure text node insert composition input text
3688
+ if (insertText && domSelection.anchorNode instanceof Text && domSelection.anchorNode.textContent.endsWith(insertText)) {
3689
+ const textNode = domSelection.anchorNode;
3690
+ textNode.splitText(textNode.length - insertText.length).remove();
3691
+ }
3692
+ };
3693
+
3694
+ class SlateChildrenOutlet {
3695
+ constructor(elementRef) {
3696
+ this.elementRef = elementRef;
3697
+ }
3698
+ getNativeElement() {
3699
+ return this.elementRef.nativeElement;
3700
+ }
3701
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SlateChildrenOutlet, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
3702
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: SlateChildrenOutlet, isStandalone: true, selector: "slate-children-outlet", ngImport: i0, template: ``, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3703
+ }
3704
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SlateChildrenOutlet, decorators: [{
3705
+ type: Component,
3706
+ args: [{
3707
+ selector: 'slate-children-outlet',
3708
+ template: ``,
3709
+ changeDetection: ChangeDetectionStrategy.OnPush,
3710
+ standalone: true
3711
+ }]
3712
+ }], ctorParameters: () => [{ type: i0.ElementRef }] });
3713
+
3714
+ class SlateString {
3715
+ ngOnInit() { }
3716
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SlateString, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3717
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: SlateString, isStandalone: true, selector: "span[slateString]", inputs: { context: "context", viewContext: "viewContext" }, ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3718
+ }
3719
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SlateString, decorators: [{
3720
+ type: Component,
3721
+ args: [{
3722
+ selector: 'span[slateString]',
3723
+ template: '',
3724
+ changeDetection: ChangeDetectionStrategy.OnPush,
3725
+ standalone: true
3726
+ }]
3727
+ }], propDecorators: { context: [{
3728
+ type: Input
3729
+ }], viewContext: [{
3730
+ type: Input
3731
+ }] } });
3732
+
3733
+ class SlateModule {
3734
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SlateModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
3735
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.2.14", ngImport: i0, type: SlateModule, imports: [CommonModule, SlateEditable, SlateBlockCard, SlateChildrenOutlet, SlateString], exports: [SlateEditable, SlateChildrenOutlet, SlateString] }); }
3736
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SlateModule, imports: [CommonModule] }); }
3737
+ }
3738
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SlateModule, decorators: [{
3739
+ type: NgModule,
3740
+ args: [{
3741
+ imports: [CommonModule, SlateEditable, SlateBlockCard, SlateChildrenOutlet, SlateString],
3742
+ exports: [SlateEditable, SlateChildrenOutlet, SlateString],
3743
+ providers: []
3744
+ }]
3745
+ }] });
3746
+
3747
+ /**
3748
+ * base class for custom element component or text component
3749
+ */
3750
+ class BaseComponent {
3751
+ constructor() {
3752
+ this.initialized = false;
3753
+ this.elementRef = inject(ElementRef);
3754
+ this.cdr = inject(ChangeDetectorRef);
3755
+ }
3756
+ set context(value) {
3757
+ if (hasBeforeContextChange(this)) {
3758
+ this.beforeContextChange(value);
3759
+ }
3760
+ this._context = value;
3761
+ this.onContextChange();
3762
+ if (this.initialized) {
3763
+ this.cdr.detectChanges();
3764
+ }
3765
+ if (hasAfterContextChange(this)) {
3766
+ this.afterContextChange();
3767
+ }
3768
+ }
3769
+ get context() {
3770
+ return this._context;
3771
+ }
3772
+ get editor() {
3773
+ return this.viewContext && this.viewContext.editor;
3774
+ }
3775
+ get nativeElement() {
3776
+ return this.elementRef.nativeElement;
3777
+ }
3778
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: BaseComponent, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
3779
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.14", type: BaseComponent, isStandalone: true, inputs: { context: "context", viewContext: "viewContext" }, ngImport: i0 }); }
3780
+ }
3781
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: BaseComponent, decorators: [{
3782
+ type: Directive
3783
+ }], propDecorators: { context: [{
3784
+ type: Input
3785
+ }], viewContext: [{
3786
+ type: Input
3787
+ }] } });
3788
+ /**
3789
+ * base class for custom element component
3790
+ */
3791
+ class BaseElementComponent extends BaseComponent {
3792
+ constructor() {
3793
+ super(...arguments);
3794
+ this.viewContainerRef = inject(ViewContainerRef);
3795
+ this.getOutletParent = () => {
3796
+ return this.elementRef.nativeElement;
3797
+ };
3798
+ this.getOutletElement = () => {
3799
+ if (this.childrenOutletInstance) {
3800
+ return this.childrenOutletInstance.getNativeElement();
3801
+ }
3802
+ return null;
3803
+ };
3804
+ }
3805
+ get element() {
3806
+ return this._context && this._context.element;
3807
+ }
3808
+ get selection() {
3809
+ return this._context && this._context.selection;
3810
+ }
3811
+ get decorations() {
3812
+ return this._context && this._context.decorations;
3813
+ }
3814
+ get children() {
3815
+ return this._context && this._context.element.children;
3816
+ }
3817
+ get isCollapsed() {
3818
+ return this.selection && Range.isCollapsed(this.selection);
3819
+ }
3820
+ get isCollapsedAndNonReadonly() {
3821
+ return this.selection && Range.isCollapsed(this.selection) && !this.readonly;
3822
+ }
3823
+ get readonly() {
3824
+ return this._context && this._context.readonly;
3825
+ }
3826
+ ngOnInit() {
3827
+ for (const key in this._context.attributes) {
3828
+ this.nativeElement.setAttribute(key, this._context.attributes[key]);
3829
+ }
3830
+ this.initialized = true;
3831
+ this.listRender = new ListRender(this.viewContext, this.viewContainerRef, this.getOutletParent, this.getOutletElement);
3832
+ if (this.editor.isExpanded(this.element)) {
3833
+ this.listRender.initialize(this.children, this.element, this.childrenContext);
3834
+ }
3835
+ addAfterViewInitQueue(this.editor, () => {
3836
+ this.afterViewInit();
3930
3837
  });
3931
- delete leafEl.getBoundingClientRect;
3932
3838
  }
3933
- };
3934
- /**
3935
- * Check if the target is inside void and in the editor.
3936
- */
3937
- const isTargetInsideVoid = (editor, target) => {
3938
- let slateNode = null;
3939
- try {
3940
- slateNode = AngularEditor.hasTarget(editor, target) && AngularEditor.toSlateNode(editor, target);
3839
+ afterViewInit() {
3840
+ if (this._context.contentEditable !== undefined) {
3841
+ this.nativeElement.setAttribute('contenteditable', this._context.contentEditable + '');
3842
+ }
3941
3843
  }
3942
- catch (error) { }
3943
- return slateNode && Element.isElement(slateNode) && Editor.isVoid(editor, slateNode);
3944
- };
3945
- const hasStringTarget = (domSelection) => {
3946
- return ((domSelection.anchorNode.parentElement.hasAttribute('data-slate-string') ||
3947
- domSelection.anchorNode.parentElement.hasAttribute('data-slate-zero-width')) &&
3948
- (domSelection.focusNode.parentElement.hasAttribute('data-slate-string') ||
3949
- domSelection.focusNode.parentElement.hasAttribute('data-slate-zero-width')));
3950
- };
3951
- /**
3952
- * remove default insert from composition
3953
- * @param text
3954
- */
3955
- const preventInsertFromComposition = (event, editor) => {
3956
- const types = ['compositionend', 'insertFromComposition'];
3957
- if (!types.includes(event.type)) {
3958
- return;
3844
+ updateWeakMap() {
3845
+ NODE_TO_ELEMENT.set(this.element, this.nativeElement);
3846
+ ELEMENT_TO_NODE.set(this.nativeElement, this.element);
3847
+ ELEMENT_TO_COMPONENT.set(this.element, this);
3959
3848
  }
3960
- const insertText = event.data;
3961
- const window = AngularEditor.getWindow(editor);
3962
- const domSelection = window.getSelection();
3963
- // ensure text node insert composition input text
3964
- if (insertText && domSelection.anchorNode instanceof Text && domSelection.anchorNode.textContent.endsWith(insertText)) {
3965
- const textNode = domSelection.anchorNode;
3966
- textNode.splitText(textNode.length - insertText.length).remove();
3849
+ ngOnDestroy() {
3850
+ if (NODE_TO_ELEMENT.get(this.element) === this.nativeElement) {
3851
+ NODE_TO_ELEMENT.delete(this.element);
3852
+ }
3853
+ ELEMENT_TO_NODE.delete(this.nativeElement);
3854
+ if (ELEMENT_TO_COMPONENT.get(this.element) === this) {
3855
+ ELEMENT_TO_COMPONENT.delete(this.element);
3856
+ }
3967
3857
  }
3968
- };
3969
-
3970
- class SlateElement extends BaseElementComponent {
3971
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SlateElement, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
3972
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: SlateElement, isStandalone: true, selector: "[slateElement]", usesInheritance: true, ngImport: i0, template: '<ng-content></ng-content>', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3858
+ onContextChange() {
3859
+ this.childrenContext = this.getChildrenContext();
3860
+ this.updateWeakMap();
3861
+ if (!this.initialized) {
3862
+ return;
3863
+ }
3864
+ this.updateChildrenView();
3865
+ }
3866
+ updateChildrenView() {
3867
+ if (this.editor.isExpanded(this.element)) {
3868
+ this.listRender.update(this.children, this.element, this.childrenContext);
3869
+ }
3870
+ else {
3871
+ if (this.listRender.initialized) {
3872
+ this.listRender.destroy();
3873
+ }
3874
+ }
3875
+ }
3876
+ getChildrenContext() {
3877
+ return {
3878
+ parent: this._context.element,
3879
+ selection: this._context.selection,
3880
+ decorations: this._context.decorations,
3881
+ decorate: this._context.decorate,
3882
+ readonly: this._context.readonly
3883
+ };
3884
+ }
3885
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: BaseElementComponent, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
3886
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.14", type: BaseElementComponent, isStandalone: true, viewQueries: [{ propertyName: "childrenOutletInstance", first: true, predicate: SlateChildrenOutlet, descendants: true, static: true }], usesInheritance: true, ngImport: i0 }); }
3973
3887
  }
3974
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SlateElement, decorators: [{
3975
- type: Component,
3976
- args: [{
3977
- selector: '[slateElement]',
3978
- template: '<ng-content></ng-content>',
3979
- changeDetection: ChangeDetectionStrategy.OnPush
3980
- }]
3981
- }] });
3982
-
3888
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: BaseElementComponent, decorators: [{
3889
+ type: Directive
3890
+ }], propDecorators: { childrenOutletInstance: [{
3891
+ type: ViewChild,
3892
+ args: [SlateChildrenOutlet, { static: true }]
3893
+ }] } });
3983
3894
  /**
3984
- * @deprecated
3985
- * the special container for angular template
3986
- * Add the rootNodes of each child component to the parentElement
3987
- * Remove useless DOM elements, eg: comment...
3895
+ * base class for custom text component
3988
3896
  */
3989
- class ViewContainer {
3990
- constructor(elementRef, differs) {
3991
- this.elementRef = elementRef;
3992
- this.differs = differs;
3897
+ class BaseTextComponent extends BaseComponent {
3898
+ constructor() {
3899
+ super(...arguments);
3900
+ this.viewContainerRef = inject(ViewContainerRef);
3901
+ this.getOutletParent = () => {
3902
+ return this.elementRef.nativeElement;
3903
+ };
3904
+ this.getOutletElement = () => {
3905
+ if (this.childrenOutletInstance) {
3906
+ return this.childrenOutletInstance.getNativeElement();
3907
+ }
3908
+ return null;
3909
+ };
3910
+ }
3911
+ get text() {
3912
+ return this._context && this._context.text;
3913
+ }
3914
+ ngOnInit() {
3915
+ this.initialized = true;
3916
+ this.leavesRender = new LeavesRender(this.viewContext, this.viewContainerRef, this.getOutletParent, this.getOutletElement);
3917
+ this.leavesRender.initialize(this.context);
3918
+ }
3919
+ updateWeakMap() {
3920
+ ELEMENT_TO_NODE.set(this.nativeElement, this.text);
3921
+ NODE_TO_ELEMENT.set(this.text, this.nativeElement);
3922
+ }
3923
+ ngOnDestroy() {
3924
+ if (NODE_TO_ELEMENT.get(this.text) === this.nativeElement) {
3925
+ NODE_TO_ELEMENT.delete(this.text);
3926
+ }
3927
+ ELEMENT_TO_NODE.delete(this.nativeElement);
3928
+ }
3929
+ onContextChange() {
3930
+ this.updateWeakMap();
3931
+ if (!this.initialized) {
3932
+ return;
3933
+ }
3934
+ this.leavesRender.update(this.context);
3993
3935
  }
3994
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ViewContainer, deps: [{ token: i0.ElementRef }, { token: i0.IterableDiffers }], target: i0.ɵɵFactoryTarget.Directive }); }
3995
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.14", type: ViewContainer, isStandalone: true, inputs: { viewContext: "viewContext" }, ngImport: i0 }); }
3936
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: BaseTextComponent, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
3937
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.14", type: BaseTextComponent, isStandalone: true, viewQueries: [{ propertyName: "childrenOutletInstance", first: true, predicate: SlateChildrenOutlet, descendants: true, static: true }], usesInheritance: true, ngImport: i0 }); }
3996
3938
  }
3997
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ViewContainer, decorators: [{
3939
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: BaseTextComponent, decorators: [{
3998
3940
  type: Directive
3999
- }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.IterableDiffers }], propDecorators: { viewContext: [{
4000
- type: Input
4001
- }] } });
4002
-
4003
- class SlateChildren extends ViewContainer {
4004
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SlateChildren, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
4005
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: SlateChildren, isStandalone: true, selector: "slate-children", inputs: { children: "children", context: "context", viewContext: "viewContext" }, usesInheritance: true, ngImport: i0, template: ``, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4006
- }
4007
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SlateChildren, decorators: [{
4008
- type: Component,
4009
- args: [{
4010
- selector: 'slate-children',
4011
- template: ``,
4012
- changeDetection: ChangeDetectionStrategy.OnPush,
4013
- standalone: true
4014
- }]
4015
- }], propDecorators: { children: [{
4016
- type: Input
4017
- }], context: [{
4018
- type: Input
4019
- }], viewContext: [{
4020
- type: Input
3941
+ }], propDecorators: { childrenOutletInstance: [{
3942
+ type: ViewChild,
3943
+ args: [SlateChildrenOutlet, { static: true }]
4021
3944
  }] } });
4022
-
4023
- class SlateLeaves extends ViewContainer {
3945
+ /**
3946
+ * base class for custom leaf component
3947
+ */
3948
+ class BaseLeafComponent extends BaseComponent {
4024
3949
  constructor() {
4025
3950
  super(...arguments);
4026
- this.initialized = false;
3951
+ this.stringRender = null;
3952
+ this.isSlateLeaf = true;
4027
3953
  }
4028
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SlateLeaves, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
4029
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: SlateLeaves, isStandalone: true, selector: "slate-leaves", inputs: { context: "context" }, usesInheritance: true, ngImport: i0, template: ``, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4030
- }
4031
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SlateLeaves, decorators: [{
4032
- type: Component,
4033
- args: [{
4034
- selector: 'slate-leaves',
4035
- template: ``,
4036
- changeDetection: ChangeDetectionStrategy.OnPush,
4037
- imports: []
4038
- }]
4039
- }], propDecorators: { context: [{
4040
- type: Input
4041
- }] } });
4042
-
4043
- class SlateModule {
4044
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SlateModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
4045
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.2.14", ngImport: i0, type: SlateModule, imports: [CommonModule,
4046
- SlateEditable,
4047
- SlateDefaultElement,
4048
- SlateElement,
4049
- SlateVoidText,
4050
- SlateDefaultText,
4051
- SlateString,
4052
- SlateStringTemplate,
4053
- SlateChildren,
4054
- SlateBlockCard,
4055
- SlateLeaves,
4056
- SlateDefaultLeaf,
4057
- SlateDefaultString,
4058
- SlateChildrenOutlet], exports: [SlateEditable, SlateChildren, SlateChildrenOutlet, SlateElement, SlateLeaves, SlateString, SlateDefaultString] }); }
4059
- static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SlateModule, providers: [
4060
- {
4061
- provide: SLATE_DEFAULT_ELEMENT_COMPONENT_TOKEN,
4062
- useValue: SlateDefaultElement
3954
+ get text() {
3955
+ return this.context && this.context.text;
3956
+ }
3957
+ get leaf() {
3958
+ return this.context && this.context.leaf;
3959
+ }
3960
+ ngOnInit() {
3961
+ this.initialized = true;
3962
+ }
3963
+ onContextChange() {
3964
+ if (!this.initialized) {
3965
+ this.stringRender = new SlateStringRender(this.context, this.viewContext);
3966
+ const stringNode = this.stringRender.render();
3967
+ this.nativeElement.appendChild(stringNode);
3968
+ }
3969
+ else {
3970
+ this.stringRender?.update(this.context, this.viewContext);
3971
+ }
3972
+ if (!this.initialized) {
3973
+ return;
3974
+ }
3975
+ }
3976
+ renderPlaceholder() {
3977
+ // issue-1: IME input was interrupted
3978
+ // issue-2: IME input focus jumping
3979
+ // Issue occurs when the span node of the placeholder is before the slateString span node
3980
+ if (this.context.leaf['placeholder']) {
3981
+ if (!this.placeholderElement) {
3982
+ this.createPlaceholder();
3983
+ }
3984
+ this.updatePlaceholder();
3985
+ }
3986
+ else {
3987
+ this.destroyPlaceholder();
3988
+ }
3989
+ }
3990
+ createPlaceholder() {
3991
+ const placeholderElement = document.createElement('span');
3992
+ placeholderElement.innerText = this.context.leaf['placeholder'];
3993
+ placeholderElement.contentEditable = 'false';
3994
+ placeholderElement.setAttribute('data-slate-placeholder', 'true');
3995
+ this.placeholderElement = placeholderElement;
3996
+ this.nativeElement.classList.add('leaf-with-placeholder');
3997
+ this.nativeElement.appendChild(placeholderElement);
3998
+ setTimeout(() => {
3999
+ const editorElement = this.nativeElement.closest('.the-editor-typo');
4000
+ const editorContentHeight = getContentHeight(editorElement);
4001
+ if (editorContentHeight > 0) {
4002
+ // Not supported webkitLineClamp exceeds height hiding
4003
+ placeholderElement.style.maxHeight = `${editorContentHeight}px`;
4063
4004
  }
4064
- ], imports: [CommonModule] }); }
4005
+ const lineClamp = Math.floor(editorContentHeight / this.nativeElement.offsetHeight) || 0;
4006
+ placeholderElement.style.webkitLineClamp = `${Math.max(lineClamp, 1)}`;
4007
+ });
4008
+ }
4009
+ updatePlaceholder() {
4010
+ if (this.placeholderElement.innerText !== this.context.leaf['placeholder']) {
4011
+ this.placeholderElement.innerText = this.context.leaf['placeholder'];
4012
+ }
4013
+ }
4014
+ destroyPlaceholder() {
4015
+ if (this.placeholderElement) {
4016
+ this.placeholderElement.remove();
4017
+ this.placeholderElement = null;
4018
+ this.nativeElement.classList.remove('leaf-with-placeholder');
4019
+ }
4020
+ }
4021
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: BaseLeafComponent, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
4022
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.14", type: BaseLeafComponent, isStandalone: true, host: { properties: { "attr.data-slate-leaf": "this.isSlateLeaf" } }, usesInheritance: true, ngImport: i0 }); }
4065
4023
  }
4066
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: SlateModule, decorators: [{
4067
- type: NgModule,
4068
- args: [{
4069
- imports: [
4070
- CommonModule,
4071
- SlateEditable,
4072
- SlateDefaultElement,
4073
- SlateElement,
4074
- SlateVoidText,
4075
- SlateDefaultText,
4076
- SlateString,
4077
- SlateStringTemplate,
4078
- SlateChildren,
4079
- SlateBlockCard,
4080
- SlateLeaves,
4081
- SlateDefaultLeaf,
4082
- SlateDefaultString,
4083
- SlateChildrenOutlet
4084
- ],
4085
- exports: [SlateEditable, SlateChildren, SlateChildrenOutlet, SlateElement, SlateLeaves, SlateString, SlateDefaultString],
4086
- providers: [
4087
- {
4088
- provide: SLATE_DEFAULT_ELEMENT_COMPONENT_TOKEN,
4089
- useValue: SlateDefaultElement
4090
- }
4091
- ]
4092
- }]
4093
- }] });
4024
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: BaseLeafComponent, decorators: [{
4025
+ type: Directive
4026
+ }], propDecorators: { isSlateLeaf: [{
4027
+ type: HostBinding,
4028
+ args: ['attr.data-slate-leaf']
4029
+ }] } });
4094
4030
 
4095
4031
  /*
4096
4032
  * Public API Surface of slate-angular
@@ -4100,5 +4036,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImpo
4100
4036
  * Generated bundle index. Do not edit.
4101
4037
  */
4102
4038
 
4103
- export { AngularEditor, BaseComponent, BaseElementComponent, BaseLeafComponent, BaseTextComponent, EDITOR_TO_AFTER_VIEW_INIT_QUEUE, ELEMENT_TO_COMPONENT, FAKE_LEFT_BLOCK_CARD_OFFSET, FAKE_RIGHT_BLOCK_CARD_OFFSET, HAS_BEFORE_INPUT_SUPPORT, IS_ANDROID, IS_APPLE, IS_CHROME, IS_CHROME_LEGACY, IS_EDGE_LEGACY, IS_FIREFOX, IS_FIREFOX_LEGACY, IS_IOS, IS_QQBROWSER, IS_SAFARI, IS_UC_MOBILE, IS_WECHATBROWSER, PLACEHOLDER_SYMBOL, SlateChildren, SlateChildrenOutlet, SlateDefaultString, SlateEditable, SlateElement, SlateErrorCode, SlateFragmentAttributeKey, SlateLeaves, SlateModule, SlateString, blobAsString, buildHTMLText, check, completeTable, createClipboardData, createThrottleRAF, defaultScrollSelectionIntoView, fallbackCopyText, getCardTargetAttribute, getClipboardData, getClipboardFromHTMLText, getContentHeight, getDataTransferClipboard, getDataTransferClipboardText, getNavigatorClipboard, getPlainText, getSelection, getSlateFragmentAttribute, hasAfterContextChange, hasBeforeContextChange, hasBlockCard, hasBlockCardWithNode, hotkeys, isCardCenterByTargetAttr, isCardLeft, isCardLeftByTargetAttr, isCardRightByTargetAttr, isClipboardFile, isClipboardReadSupported, isClipboardWriteSupported, isClipboardWriteTextSupported, isComponentType, isDOMText, isDecoratorRangeListEqual, isEmpty, isInvalidTable, isTemplateRef, isValid, normalize, setClipboardData, setDataTransferClipboard, setDataTransferClipboardText, setNavigatorClipboard, shallowCompare, stripHtml, withAngular };
4039
+ export { AngularEditor, BaseComponent, BaseElementComponent, BaseElementFlavour, BaseFlavour, BaseLeafComponent, BaseLeafFlavour, BaseTextComponent, BaseTextFlavour, DefaultTextFlavour, EDITOR_TO_AFTER_VIEW_INIT_QUEUE, ELEMENT_TO_COMPONENT, FAKE_LEFT_BLOCK_CARD_OFFSET, FAKE_RIGHT_BLOCK_CARD_OFFSET, FlavourRef, HAS_BEFORE_INPUT_SUPPORT, IS_ANDROID, IS_APPLE, IS_CHROME, IS_CHROME_LEGACY, IS_EDGE_LEGACY, IS_FIREFOX, IS_FIREFOX_LEGACY, IS_IOS, IS_QQBROWSER, IS_SAFARI, IS_UC_MOBILE, IS_WECHATBROWSER, PLACEHOLDER_SYMBOL, SlateChildrenOutlet, SlateEditable, SlateErrorCode, SlateFragmentAttributeKey, SlateModule, SlateString, VoidTextFlavour, blobAsString, buildHTMLText, check, completeTable, createClipboardData, createText, createThrottleRAF, defaultScrollSelectionIntoView, fallbackCopyText, getCardTargetAttribute, getClipboardData, getClipboardFromHTMLText, getContentHeight, getDataTransferClipboard, getDataTransferClipboardText, getNavigatorClipboard, getPlainText, getSelection, getSlateFragmentAttribute, hasAfterContextChange, hasBeforeContextChange, hasBlockCard, hasBlockCardWithNode, hotkeys, isCardCenterByTargetAttr, isCardLeft, isCardLeftByTargetAttr, isCardRightByTargetAttr, isClipboardFile, isClipboardReadSupported, isClipboardWriteSupported, isClipboardWriteTextSupported, isComponentType, isDOMText, isDecoratorRangeListEqual, isFlavourType, isInvalidTable, isTemplateRef, isValid, normalize, setClipboardData, setDataTransferClipboard, setDataTransferClipboardText, setNavigatorClipboard, shallowCompare, stripHtml, withAngular };
4104
4040
  //# sourceMappingURL=slate-angular.mjs.map