@talrace/ngx-noder 0.0.11 → 0.0.13

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 (80) hide show
  1. package/README.md +374 -71
  2. package/esm2022/lib/apart-components/editor-title/editor-title.component.mjs +1 -1
  3. package/esm2022/lib/apart-components/editor-toolbar/components/buttons/font/font.component.mjs +2 -2
  4. package/esm2022/lib/apart-components/editor-toolbar/components/menu-dropdowns/menu-dropdowns.component.mjs +2 -5
  5. package/esm2022/lib/apart-components/editor-toolbar/editor-toolbar/editor-toolbar.component.mjs +3 -3
  6. package/esm2022/lib/editor/components/edges/edge-element.model.mjs +30 -1
  7. package/esm2022/lib/editor/components/edges/edge.component.mjs +23 -23
  8. package/esm2022/lib/editor/components/edges/edges.mjs +30 -15
  9. package/esm2022/lib/editor/components/image/components/image.component.mjs +2 -2
  10. package/esm2022/lib/editor/components/image/input-handler/image-input.handler.mjs +2 -2
  11. package/esm2022/lib/editor/components/table/components/table-cell.component.mjs +5 -3
  12. package/esm2022/lib/editor/components/table/components/table.component.mjs +7 -5
  13. package/esm2022/lib/editor/components/table/selection/table-selection.mjs +12 -5
  14. package/esm2022/lib/editor/content/display-data/display-data.mjs +4 -4
  15. package/esm2022/lib/editor/content/helpers/content-style.helper.mjs +1 -1
  16. package/esm2022/lib/editor/content/helpers/link.helper.mjs +39 -3
  17. package/esm2022/lib/editor/display/layers/text.layer.mjs +100 -75
  18. package/esm2022/lib/editor/display/print/print.helper.mjs +3 -3
  19. package/esm2022/lib/editor/display/print/print.renderer.mjs +5 -5
  20. package/esm2022/lib/editor/display/renderer.mjs +23 -25
  21. package/esm2022/lib/editor/display/virtual.renderer.mjs +10 -43
  22. package/esm2022/lib/editor/execution/edit.session.mjs +26 -16
  23. package/esm2022/lib/editor/execution/editor.mjs +88 -127
  24. package/esm2022/lib/editor/execution/regulator.service.mjs +44 -39
  25. package/esm2022/lib/editor/execution/targeting/cell-session-source.model.mjs +2 -3
  26. package/esm2022/lib/editor/execution/targeting/edge-session-source.model.mjs +2 -3
  27. package/esm2022/lib/editor/execution/targeting/main-session-source.model.mjs +2 -2
  28. package/esm2022/lib/editor/execution/targeting/session-source.model.mjs +1 -1
  29. package/esm2022/lib/editor/gadgets/history/operation-history.mjs +39 -37
  30. package/esm2022/lib/editor/interaction/editor.service.mjs +22 -22
  31. package/esm2022/lib/editor/interaction/mouse.handler.mjs +2 -2
  32. package/esm2022/lib/editor/operations/helpers/content-operations.helper.mjs +4 -4
  33. package/esm2022/lib/editor/operations/helpers/format-operations.helper.mjs +2 -2
  34. package/esm2022/lib/editor/operations/helpers/link-operations.helper.mjs +59 -7
  35. package/esm2022/lib/editor/operations/operations-helper.helper.mjs +24 -25
  36. package/esm2022/lib/editor/operations/save-commands.helper.mjs +6 -5
  37. package/esm2022/lib/editor/positioning/content.helper.mjs +10 -1
  38. package/esm2022/lib/editor/positioning/position.helper.mjs +49 -35
  39. package/esm2022/lib/editor/revision.helper.mjs +3 -1
  40. package/esm2022/lib/models/generated/delete.model.mjs +1 -1
  41. package/esm2022/lib/models/generated/link-data.model.mjs +1 -1
  42. package/esm2022/lib/models/generated/link.model.mjs +1 -1
  43. package/esm2022/lib/models/generated/restore-text-styles.model.mjs +1 -1
  44. package/esm2022/lib/models/generated/target.model.mjs +1 -1
  45. package/fesm2022/talrace-ngx-noder.mjs +672 -545
  46. package/fesm2022/talrace-ngx-noder.mjs.map +1 -1
  47. package/lib/apart-components/editor-toolbar/components/menu-dropdowns/menu-dropdowns.component.d.ts +1 -3
  48. package/lib/apart-components/editor-toolbar/editor-toolbar/editor-toolbar.component.d.ts +1 -1
  49. package/lib/editor/components/edges/edge-element.model.d.ts +9 -1
  50. package/lib/editor/components/edges/edge.component.d.ts +4 -4
  51. package/lib/editor/components/edges/edges.d.ts +8 -2
  52. package/lib/editor/components/table/components/table.component.d.ts +4 -2
  53. package/lib/editor/components/table/selection/table-selection.d.ts +5 -2
  54. package/lib/editor/content/display-data/display-data.d.ts +2 -1
  55. package/lib/editor/content/helpers/content-style.helper.d.ts +1 -1
  56. package/lib/editor/content/helpers/link.helper.d.ts +4 -1
  57. package/lib/editor/display/layers/text.layer.d.ts +8 -10
  58. package/lib/editor/display/print/print.helper.d.ts +1 -2
  59. package/lib/editor/display/print/print.renderer.d.ts +1 -2
  60. package/lib/editor/display/renderer.d.ts +9 -9
  61. package/lib/editor/display/virtual.renderer.d.ts +3 -10
  62. package/lib/editor/execution/edit.session.d.ts +7 -2
  63. package/lib/editor/execution/editor.d.ts +10 -9
  64. package/lib/editor/execution/regulator.service.d.ts +6 -4
  65. package/lib/editor/execution/targeting/cell-session-source.model.d.ts +0 -1
  66. package/lib/editor/execution/targeting/edge-session-source.model.d.ts +0 -1
  67. package/lib/editor/execution/targeting/session-source.model.d.ts +0 -1
  68. package/lib/editor/gadgets/history/operation-history.d.ts +7 -3
  69. package/lib/editor/interaction/editor.service.d.ts +13 -12
  70. package/lib/editor/operations/helpers/content-operations.helper.d.ts +1 -1
  71. package/lib/editor/operations/helpers/link-operations.helper.d.ts +7 -2
  72. package/lib/editor/operations/operations-helper.helper.d.ts +3 -3
  73. package/lib/editor/operations/save-commands.helper.d.ts +1 -1
  74. package/lib/editor/positioning/content.helper.d.ts +2 -0
  75. package/lib/editor/positioning/position.helper.d.ts +21 -6
  76. package/lib/models/generated/delete.model.d.ts +1 -1
  77. package/lib/models/generated/restore-text-styles.model.d.ts +1 -0
  78. package/lib/models/generated/target.model.d.ts +0 -1
  79. package/package.json +1 -1
  80. package/src/scss/base-editor.scss +4 -0
@@ -1,6 +1,6 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { Directive, inject, ChangeDetectorRef, HostBinding, Input, Injectable, InjectionToken, createComponent, Component, ChangeDetectionStrategy, ViewChild, EventEmitter, Output, HostListener, NgModule, Inject } from '@angular/core';
3
- import { Subject, BehaviorSubject, fromEvent, throttleTime, filter, take, takeUntil, debounceTime, distinctUntilChanged } from 'rxjs';
3
+ import { Subject, BehaviorSubject, fromEvent, throttleTime, filter, take, debounceTime, distinctUntilChanged, takeUntil } from 'rxjs';
4
4
  import { HttpHeaders } from '@angular/common/http';
5
5
  import * as i3 from '@angular/common';
6
6
  import { CommonModule } from '@angular/common';
@@ -504,6 +504,9 @@ class EditorService {
504
504
  this._endMousePress$ = new Subject();
505
505
  this._disableSelection$ = new Subject();
506
506
  this._changedTableSize$ = new Subject();
507
+ this._changedEdgeSize$ = new Subject();
508
+ this._imageLoaded$ = new Subject();
509
+ this._changedEdge$ = new Subject();
507
510
  this._insertTableRows$ = new Subject();
508
511
  this._insertTableColumns$ = new Subject();
509
512
  this._removeTableRows$ = new Subject();
@@ -511,9 +514,6 @@ class EditorService {
511
514
  this._removeImage$ = new Subject();
512
515
  this._resizeTableColumns$ = new Subject();
513
516
  this._insertTable$ = new Subject();
514
- this._rendererUpdated$ = new Subject();
515
- this._edgeElementCopyUpdated$ = new Subject();
516
- this._changedEdgeHeight$ = new Subject();
517
517
  this._redo$ = new Subject();
518
518
  this._undo$ = new Subject();
519
519
  this._print$ = new Subject();
@@ -621,6 +621,15 @@ class EditorService {
621
621
  get changedTableSize$() {
622
622
  return this._changedTableSize$.asObservable();
623
623
  }
624
+ get changedEdgeSize$() {
625
+ return this._changedEdgeSize$.asObservable();
626
+ }
627
+ get imageLoaded$() {
628
+ return this._imageLoaded$.asObservable();
629
+ }
630
+ get changedEdge$() {
631
+ return this._changedEdge$.asObservable();
632
+ }
624
633
  get insertTableRows$() {
625
634
  return this._insertTableRows$.asObservable();
626
635
  }
@@ -642,15 +651,6 @@ class EditorService {
642
651
  get insertTable$() {
643
652
  return this._insertTable$.asObservable();
644
653
  }
645
- get rendererUpdated$() {
646
- return this._rendererUpdated$.asObservable();
647
- }
648
- get edgeElementCopyUpdated$() {
649
- return this._edgeElementCopyUpdated$.asObservable();
650
- }
651
- get changedEdgeHeight$() {
652
- return this._changedEdgeHeight$.asObservable();
653
- }
654
654
  get redo$() {
655
655
  return this._redo$.asObservable();
656
656
  }
@@ -748,6 +748,15 @@ class EditorService {
748
748
  changedTableSize(insertIndex, sessionId) {
749
749
  this._changedTableSize$.next({ insertIndex, sessionId });
750
750
  }
751
+ changedEdgeSize(edgeType, pageType) {
752
+ this._changedEdgeSize$.next({ edgeType, pageType });
753
+ }
754
+ imageLoaded(sessionId) {
755
+ this._imageLoaded$.next(sessionId);
756
+ }
757
+ changedEdge(sessionId) {
758
+ this._changedEdge$.next(sessionId);
759
+ }
751
760
  insertTableRows(insertIndex, rowsCount, targetIndex, inheritIndex, sessionId) {
752
761
  this._insertTableRows$.next({ insertIndex, rowsCount, targetIndex, inheritIndex, sessionId });
753
762
  }
@@ -772,15 +781,6 @@ class EditorService {
772
781
  insertTable(tableData) {
773
782
  this._insertTable$.next(tableData);
774
783
  }
775
- rendererUpdated(sessionId) {
776
- this._rendererUpdated$.next(sessionId);
777
- }
778
- edgeElementCopyUpdated(newElementCopy, page) {
779
- this._edgeElementCopyUpdated$.next({ newElementCopy, page });
780
- }
781
- changedEdgeHeight(type) {
782
- this._changedEdgeHeight$.next(type);
783
- }
784
784
  undo() {
785
785
  this._undo$.next();
786
786
  }
@@ -1080,6 +1080,15 @@ class ContentHelper {
1080
1080
  }
1081
1081
  });
1082
1082
  }
1083
+ static getContentFromInsertParagraph(insertParagraph) {
1084
+ if (insertParagraph.insertImage) {
1085
+ return insertParagraph.insertImage.imageData.content;
1086
+ }
1087
+ if (insertParagraph.insertTable) {
1088
+ return insertParagraph.insertTable.content;
1089
+ }
1090
+ return insertParagraph.insertText.text;
1091
+ }
1083
1092
  }
1084
1093
 
1085
1094
  class DeleteModel {
@@ -1463,12 +1472,6 @@ class InsertTabModel {
1463
1472
  }
1464
1473
  }
1465
1474
 
1466
- class LinkHelper {
1467
- static sliceSection(links, startIndex, endIndex) {
1468
- return links.filter(x => x.startIndex >= startIndex && x.endIndex <= endIndex);
1469
- }
1470
- }
1471
-
1472
1475
  class LinkModel {
1473
1476
  constructor(fields) {
1474
1477
  if (fields) {
@@ -1477,6 +1480,45 @@ class LinkModel {
1477
1480
  }
1478
1481
  }
1479
1482
 
1483
+ class LinkHelper {
1484
+ static sliceSection(links, start, end) {
1485
+ return links.map(link => LinkHelper.getPartialLink(link, start, end)).filter((link) => link !== null);
1486
+ }
1487
+ static sliceFormats(links, startIndex, endIndex) {
1488
+ const result = [];
1489
+ for (const link of links) {
1490
+ const absoluteFormats = link.formats.map(x => ({
1491
+ ...x,
1492
+ startIndex: x.startIndex + link.startIndex,
1493
+ endIndex: x.endIndex + link.startIndex
1494
+ }));
1495
+ const slicedLinkFormats = FormatHelper.sliceSection(absoluteFormats, startIndex, endIndex);
1496
+ result.push(...slicedLinkFormats);
1497
+ }
1498
+ return result;
1499
+ }
1500
+ static getPartialLink(link, selectionStart, selectionEnd) {
1501
+ if (link.endIndex < selectionStart || link.startIndex > selectionEnd) {
1502
+ return null;
1503
+ }
1504
+ const newStart = Math.max(link.startIndex, selectionStart);
1505
+ const newEnd = Math.min(link.endIndex, selectionEnd);
1506
+ const newFormats = link.formats
1507
+ .map(format => {
1508
+ const formatStart = link.startIndex + format.startIndex;
1509
+ const formatEnd = link.startIndex + format.endIndex;
1510
+ if (formatEnd < newStart || formatStart > newEnd) {
1511
+ return null;
1512
+ }
1513
+ const newFormatStart = Math.max(formatStart, newStart) - newStart;
1514
+ const newFormatEnd = Math.min(formatEnd, newEnd) - newStart;
1515
+ return new FormatModel({ ...format, startIndex: newFormatStart, endIndex: newFormatEnd });
1516
+ })
1517
+ .filter((format) => format !== null);
1518
+ return new LinkModel({ ...link, startIndex: newStart, endIndex: newEnd, formats: newFormats });
1519
+ }
1520
+ }
1521
+
1480
1522
  var MouseButton;
1481
1523
  (function (MouseButton) {
1482
1524
  MouseButton[MouseButton["Left"] = 0] = "Left";
@@ -1501,7 +1543,7 @@ class MouseHandler {
1501
1543
  this.endMousePress();
1502
1544
  this.documentMouseMove$ = fromEvent(document, 'mousemove')
1503
1545
  .pipe(throttleTime(20))
1504
- .subscribe((event) => editor.onMousePressedMove(event.clientX, event.clientY));
1546
+ .subscribe((event) => editor.onMousePressedMove(event));
1505
1547
  this.documentMouseUp$ = fromEvent(document, 'mouseup').subscribe(() => this.endMousePress());
1506
1548
  }
1507
1549
  endMousePress() {
@@ -1629,70 +1671,49 @@ class OperationHistory {
1629
1671
  }
1630
1672
  pushInsertText(insertIndex, text) {
1631
1673
  const redoStep = new InsertTextModel({ insertIndex, text });
1632
- const undoStep = new DeleteModel({ startIndex: insertIndex, endIndex: insertIndex + text.length });
1674
+ const undoStep = new DeleteModel({ startIndex: insertIndex, count: text.length });
1633
1675
  this.addToHistory(undoStep, redoStep);
1634
1676
  }
1635
- pushInsertParagraph(model, paragraphs) {
1636
- const currentParagraph = paragraphs
1637
- .slice()
1638
- .sort((a, b) => a.insertIndex - b.insertIndex)
1639
- .find(x => x.insertIndex >= model.insertIndex);
1640
- const previousParagraph = paragraphs
1641
- .slice()
1642
- .sort((a, b) => b.insertIndex - a.insertIndex)
1643
- .find(x => x.insertIndex < currentParagraph.insertIndex);
1644
- let startIndex = model.insertIndex;
1645
- let endIndex = model.insertIndex;
1646
- if (model.insertIndex === 0 || previousParagraph?.insertIndex === model.insertIndex - 1) {
1647
- endIndex++;
1648
- }
1649
- else if (currentParagraph.insertIndex === model.insertIndex) {
1650
- startIndex++;
1651
- endIndex++;
1652
- }
1653
- else {
1654
- endIndex = startIndex + 2;
1655
- }
1656
- endIndex = endIndex + (model.insertText ? model.insertText.text.length : 1);
1657
- const undoStep = new DeleteModel({ startIndex, endIndex });
1658
- this.addToHistory(undoStep, model);
1677
+ pushInsertParagraph(content, model, paragraphs) {
1678
+ const undoStep = this.getDeleteDataForInsertParagraphs(content, model, paragraphs);
1679
+ this.addToHistory(new DeleteModel({ ...undoStep }), model);
1659
1680
  }
1660
1681
  pushInsertElement(model) {
1661
- const undoStep = new DeleteModel({ startIndex: model.element.insertIndex, endIndex: model.element.insertIndex + 1 });
1682
+ const undoStep = new DeleteModel({ startIndex: model.element.insertIndex, count: CUSTOM_ELEMENT_MARKER.length });
1662
1683
  this.addToHistory(undoStep, model);
1663
1684
  }
1664
- pushInsertBreak(model, endIndex) {
1665
- const undoStep = new DeleteModel({ startIndex: model.insertIndex, endIndex });
1685
+ pushInsertBreak(model, count) {
1686
+ const undoStep = new DeleteModel({ startIndex: model.insertIndex, count });
1666
1687
  this.addToHistory(undoStep, model);
1667
1688
  }
1668
1689
  pushInsertTab(model) {
1669
- const undoStep = new DeleteModel({ startIndex: model.insertIndex, endIndex: model.insertIndex + 1 });
1690
+ const undoStep = new DeleteModel({ startIndex: model.insertIndex, count: CUSTOM_ELEMENT_MARKER.length });
1670
1691
  this.addToHistory(undoStep, model);
1671
1692
  }
1672
1693
  pushInsertImage(model) {
1673
- const undoStep = new DeleteModel({ startIndex: model.insertIndex, endIndex: model.insertIndex + 1 });
1694
+ const undoStep = new DeleteModel({ startIndex: model.insertIndex, count: CUSTOM_ELEMENT_MARKER.length });
1674
1695
  this.addToHistory(undoStep, model);
1675
1696
  }
1676
1697
  pushInsertLink(model) {
1677
- const undoStep = new DeleteModel({ startIndex: model.insertIndex, endIndex: model.endIndex });
1698
+ const undoStep = new DeleteModel({ startIndex: model.insertIndex, count: model.linkDataModel.text.length });
1678
1699
  this.addToHistory(undoStep, model);
1679
1700
  }
1680
1701
  pushInsertTable(model) {
1681
- const undoStep = new DeleteModel({ startIndex: model.insertIndex, endIndex: model.insertIndex + model.content.length });
1702
+ const undoStep = new DeleteModel({ startIndex: model.insertIndex, count: model.content.length });
1682
1703
  this.addToHistory(undoStep, model);
1683
1704
  }
1684
1705
  pushInsertStyledText(insertIndex, text, style) {
1685
1706
  const redoStep = new InsertStyledTextModel({ insertIndex, text, textStyle: style });
1686
- const undoStep = new DeleteModel({ startIndex: insertIndex, endIndex: insertIndex + text.length });
1707
+ const undoStep = new DeleteModel({ startIndex: insertIndex, count: text.length });
1687
1708
  this.addToHistory(undoStep, redoStep);
1688
1709
  }
1689
1710
  pushDelete(model) {
1690
- const redoStep = new DeleteModel({ startIndex: model.startIndex, endIndex: model.startIndex + model.text.length });
1711
+ const redoStep = new DeleteModel({ startIndex: model.startIndex, count: model.text.length });
1691
1712
  this.addToHistory(model, redoStep);
1692
1713
  }
1693
- pushApplyTextStyle(startIndex, endIndex, style, formats) {
1714
+ pushApplyTextStyle(startIndex, endIndex, style, formats, linkFormats) {
1694
1715
  const redoStep = new ApplyTextStyleModel({ startIndex, endIndex, textStyle: style });
1695
- const undoStep = new RestoreTextStylesModel({ formats });
1716
+ const undoStep = new RestoreTextStylesModel({ formats, linkFormats });
1696
1717
  this.addToHistory(undoStep, redoStep);
1697
1718
  }
1698
1719
  pushApplyParagraphStyle(startIndex, endIndex, style, paragraphs) {
@@ -1803,6 +1824,28 @@ class OperationHistory {
1803
1824
  }
1804
1825
  this.editorService.historyInfo = new OperationsHistoryInfoModel(this.step, this.storage.length - 1);
1805
1826
  }
1827
+ getDeleteDataForInsertParagraphs(content, model, paragraphs) {
1828
+ const currentParagraph = paragraphs
1829
+ .slice()
1830
+ .sort((a, b) => a.insertIndex - b.insertIndex)
1831
+ .find(x => x.insertIndex >= model.insertIndex);
1832
+ const previousParagraph = paragraphs
1833
+ .slice()
1834
+ .sort((a, b) => b.insertIndex - a.insertIndex)
1835
+ .find(x => x.insertIndex < currentParagraph.insertIndex);
1836
+ let startIndex = model.insertIndex;
1837
+ let count = content.length;
1838
+ if (model.insertIndex === 0 || previousParagraph?.insertIndex === model.insertIndex - 1) {
1839
+ count++;
1840
+ }
1841
+ else if (currentParagraph.insertIndex === model.insertIndex) {
1842
+ startIndex++;
1843
+ }
1844
+ else {
1845
+ count = count + 2;
1846
+ }
1847
+ return { startIndex, count };
1848
+ }
1806
1849
  }
1807
1850
 
1808
1851
  class ParagraphModel {
@@ -1944,46 +1987,67 @@ class PositionHelper {
1944
1987
  };
1945
1988
  }
1946
1989
  /**
1947
- * Converts pixel position to screen position
1990
+ * Calculates the paragraph and line index based on the given Y position.
1948
1991
  **/
1949
- static pixelToScreen(session, x, y, scrollerPosition) {
1950
- const displayData = session.displayData;
1951
- const scrollTop = session.scrollTop;
1952
- let yPos = y + scrollTop - scrollerPosition.top;
1953
- let paragraphIndex = displayData.paragraphs.findIndex(paragraph => paragraph.paragraphSettings.distanceFromTop > yPos);
1992
+ static getParagraphAndLineIndexFromYPosition(session, yPosition, top) {
1993
+ const { displayData, scrollTop } = session;
1994
+ yPosition += scrollTop - top;
1995
+ let paragraphIndex = displayData.paragraphs.findIndex(paragraph => paragraph.paragraphSettings.distanceFromTop > yPosition);
1954
1996
  if (paragraphIndex < 0) {
1955
1997
  paragraphIndex = displayData.paragraphs.length - 1;
1956
1998
  }
1957
1999
  else if (paragraphIndex > 0) {
1958
2000
  paragraphIndex--;
1959
2001
  }
1960
- const paragraphSettings = displayData.getParagraphSettings(paragraphIndex);
1961
- yPos -= paragraphSettings.distanceFromTop;
2002
+ const paragraphSettings = displayData.paragraphs[paragraphIndex].paragraphSettings;
2003
+ yPosition -= paragraphSettings.distanceFromTop;
1962
2004
  let lineIndex = 0;
1963
- while (yPos > 0 && lineIndex < paragraphSettings.textLinesInfo.length - 1) {
1964
- const line = paragraphSettings.textLinesInfo[lineIndex];
1965
- const width = line.height + line.endPageOffset + line.offsetBefore + line.offsetAfter;
1966
- if (yPos <= width) {
2005
+ while (yPosition > 0 && lineIndex < paragraphSettings.textLinesInfo.length - 1) {
2006
+ const lineInfo = paragraphSettings.textLinesInfo[lineIndex];
2007
+ const lineHeight = lineInfo.height + lineInfo.endPageOffset + lineInfo.offsetBefore + lineInfo.offsetAfter;
2008
+ if (yPosition <= lineHeight) {
1967
2009
  break;
1968
2010
  }
1969
2011
  lineIndex++;
1970
- yPos -= width;
2012
+ yPosition -= lineHeight;
1971
2013
  }
2014
+ return { paragraphIndex, lineIndex };
2015
+ }
2016
+ /**
2017
+ * Maps a pixel position to a screen position using half-token width comparison.
2018
+ */
2019
+ static mapPixelToClosestTokenMidpoint(session, xPixel, paragraphIndex, lineIndex, leftOffset) {
2020
+ const paragraphSettings = session.displayData.paragraphs[paragraphIndex].paragraphSettings;
1972
2021
  const line = paragraphSettings.textLinesInfo[lineIndex].screenLine;
1973
- let index = 0;
1974
- let xPos = x - scrollerPosition.left - displayData.pageMargin.left - paragraphSettings.textLinesInfo[lineIndex].paddingLeft;
2022
+ let indexInLine = 0;
2023
+ let relativeX = xPixel - leftOffset - session.displayData.pageMargin.left - paragraphSettings.textLinesInfo[lineIndex].paddingLeft;
1975
2024
  const tokens = LineWidthHelper.getParagraphLineDisplayTokens(session, paragraphIndex, lineIndex);
1976
2025
  if (tokens[0].displayValue === DisplayValue.emptyLine) {
1977
- return new CursorParagraph(line, index);
2026
+ return { line, indexInLine };
1978
2027
  }
1979
- while (tokens.length > index) {
1980
- if (xPos < tokens[index].width / 2) {
1981
- break;
1982
- }
1983
- xPos -= tokens[index].width;
1984
- index++;
2028
+ while (indexInLine < tokens.length && relativeX >= tokens[indexInLine].width / 2) {
2029
+ relativeX -= tokens[indexInLine].width;
2030
+ indexInLine++;
1985
2031
  }
1986
- return new CursorParagraph(line, index);
2032
+ return { line, indexInLine };
2033
+ }
2034
+ /**
2035
+ * Maps a pixel position to a screen position using full-token width comparison.
2036
+ */
2037
+ static mapPixelToNextTokenBoundary(session, xPixel, paragraphIndex, lineIndex, leftOffset) {
2038
+ const paragraphSettings = session.displayData.paragraphs[paragraphIndex].paragraphSettings;
2039
+ const line = paragraphSettings.textLinesInfo[lineIndex].screenLine;
2040
+ let indexInLine = 0;
2041
+ let relativeX = xPixel - leftOffset - session.displayData.pageMargin.left - paragraphSettings.textLinesInfo[lineIndex].paddingLeft;
2042
+ const tokens = LineWidthHelper.getParagraphLineDisplayTokens(session, paragraphIndex, lineIndex);
2043
+ if (tokens[0].displayValue === DisplayValue.emptyLine) {
2044
+ return { line, indexInLine };
2045
+ }
2046
+ while (indexInLine < tokens.length && relativeX >= tokens[indexInLine].width) {
2047
+ relativeX -= tokens[indexInLine].width;
2048
+ indexInLine++;
2049
+ }
2050
+ return { line, indexInLine };
1987
2051
  }
1988
2052
  static findLineInParagraphs(paragraphs, documentLine) {
1989
2053
  let index = 0;
@@ -2015,17 +2079,10 @@ class PositionHelper {
2015
2079
  }
2016
2080
  return column;
2017
2081
  }
2018
- static pixelToPage(posY, session) {
2019
- const pagesCount = session.displayData.getParagraphSettings(session.displayData.paragraphs.length - 1).lastPageNumber;
2020
- let page = 1;
2021
- while (page <= pagesCount) {
2022
- const endPagePosition = (session.displayData.pagesSpace + session.displayData.pageHeight) * page;
2023
- if (endPagePosition >= posY) {
2024
- break;
2025
- }
2026
- page++;
2027
- }
2028
- return page;
2082
+ static pixelToPage(clientY, mainSession, mainRenderer) {
2083
+ const positionY = clientY + mainSession.scrollTop - mainRenderer.container.getBoundingClientRect().top;
2084
+ const height = mainSession.displayData.pagesSpace + mainSession.displayData.pageHeight;
2085
+ return Math.floor(positionY / height) + 1;
2029
2086
  }
2030
2087
  }
2031
2088
 
@@ -2403,6 +2460,34 @@ class EdgeElementModel {
2403
2460
  }
2404
2461
  Object.assign(this, fields);
2405
2462
  }
2463
+ isNotCopy(type, pageType) {
2464
+ return this.edgeType === type && this.pageType === pageType && this.isOrigin;
2465
+ }
2466
+ isCopy(type, pageType) {
2467
+ return this.edgeType === type && this.pageType === pageType && !this.isOrigin;
2468
+ }
2469
+ isWithin(start, end) {
2470
+ return this.container.offsetTop < end && this.container.offsetTop + this.container.offsetHeight > start;
2471
+ }
2472
+ replace(model) {
2473
+ const height = this.container.offsetHeight;
2474
+ const top = this.container.offsetTop;
2475
+ const page = this.page;
2476
+ DomHelper.setStyle(this.container.style, 'height', `${model.container.offsetHeight}px`);
2477
+ DomHelper.setStyle(this.container.style, 'top', `${model.container.offsetTop}px`);
2478
+ this.page = model.page;
2479
+ DomHelper.setStyle(model.container.style, 'height', `${height}px`);
2480
+ DomHelper.setStyle(model.container.style, 'top', `${top}px`);
2481
+ model.page = page;
2482
+ }
2483
+ substitute(model) {
2484
+ DomHelper.setStyle(this.container.style, 'height', `${model.container.offsetHeight}px`);
2485
+ DomHelper.setStyle(this.container.style, 'top', `${model.container.offsetTop}px`);
2486
+ const temp = this.container;
2487
+ this.container = model.container;
2488
+ model.container = temp;
2489
+ this.isOrigin = model.isOrigin;
2490
+ }
2406
2491
  }
2407
2492
 
2408
2493
  var EdgeType;
@@ -2693,18 +2778,17 @@ class ParagraphHelper {
2693
2778
  }
2694
2779
 
2695
2780
  class TextLayer {
2696
- constructor(parentElement, session, editorService, renderingHelper = RenderingHelper) {
2781
+ constructor(parentElement, session, renderingHelper = RenderingHelper) {
2782
+ this.parentElement = parentElement;
2697
2783
  this.session = session;
2698
- this.editorService = editorService;
2699
2784
  this.renderingHelper = renderingHelper;
2700
2785
  this.edgeElements = [];
2701
- this.edgeEditingPage = null;
2702
2786
  this.pagesCountChangedHandler = (event) => {
2703
2787
  this.lines.setSizes(event.pagesCount, event.pageHeight);
2704
2788
  };
2705
2789
  this.element = document.createElement('div');
2706
2790
  this.element.className = 'noder-layer noder-text-layer';
2707
- parentElement.appendChild(this.element);
2791
+ this.parentElement.appendChild(this.element);
2708
2792
  this.lines = new Lines(this.element);
2709
2793
  this.session.displayData.addEventListener('pagesCountChanged', this.pagesCountChangedHandler);
2710
2794
  this.element.style.width = `${this.session.displayData.pageWidth}px`;
@@ -2712,31 +2796,73 @@ class TextLayer {
2712
2796
  destroy() {
2713
2797
  this.session.displayData.removeEventListener('pagesCountChanged', this.pagesCountChangedHandler);
2714
2798
  }
2799
+ updateEdge(type, pageType) {
2800
+ const pages = [];
2801
+ let index = this.edgeElements.findIndex(x => x.isCopy(type, pageType));
2802
+ while (index !== -1) {
2803
+ pages.push(this.edgeElements[index].page);
2804
+ DomHelper.removeElement(this.edgeElements[index].container);
2805
+ this.edgeElements.splice(index, 1);
2806
+ index = this.edgeElements.findIndex(x => x.isCopy(type, pageType));
2807
+ }
2808
+ const start = -this.element.offsetTop;
2809
+ const end = start + this.parentElement.clientHeight;
2810
+ for (let page of pages) {
2811
+ if (type === EdgeType.Header) {
2812
+ this.renderPageHeaderComponent(page, start, end);
2813
+ }
2814
+ else {
2815
+ this.renderPageFooterComponent(page, start, end);
2816
+ }
2817
+ }
2818
+ let origin = this.edgeElements.find(x => x.isNotCopy(type, pageType));
2819
+ if (origin) {
2820
+ const edge = this.session.customComponents.edges.getComponentByPageType(pageType, type);
2821
+ const height = this.session.customComponents.edges.getComponentHeight(edge.instance);
2822
+ const topOffset = type === EdgeType.Footer ? this.session.displayData.pageHeight - height : 0;
2823
+ const edgeTop = this.getEdgeTop(topOffset, origin.page);
2824
+ DomHelper.setStyle(origin.container.style, 'height', `${height}px`);
2825
+ DomHelper.setStyle(origin.container.style, 'top', `${edgeTop}px`);
2826
+ }
2827
+ }
2715
2828
  updateEdges(config) {
2716
2829
  DomHelper.translate(this.element, 0, -config.scrollTop);
2717
2830
  while (this.edgeElements.length) {
2718
- const removedEl = this.edgeElements.pop();
2719
- DomHelper.removeElement(removedEl.element);
2720
- }
2721
- this.renderPagesEdgeComponents(config.pages);
2722
- }
2723
- edgeEditingPageUpdated(page) {
2724
- const oldEditingPage = this.edgeEditingPage;
2725
- this.edgeEditingPage = page;
2726
- this.removeEdgeComponents([page ?? oldEditingPage]);
2727
- this.renderPagesEdgeComponents([page ?? oldEditingPage]);
2728
- }
2729
- updateEdgeByLocation(updatedPageType) {
2730
- DomHelper.translate(this.element, 0, -this.config.scrollTop);
2731
- let pagesToRender = [];
2732
- for (let edgeElement of this.edgeElements) {
2733
- if (edgeElement.pageType !== updatedPageType || pagesToRender.includes(edgeElement.page)) {
2734
- continue;
2831
+ const removed = this.edgeElements.pop();
2832
+ DomHelper.removeElement(removed.container);
2833
+ }
2834
+ const start = -this.element.offsetTop;
2835
+ const end = start + this.parentElement.clientHeight;
2836
+ for (let page of config.pages) {
2837
+ this.renderPageHeaderComponent(page, start, end);
2838
+ this.renderPageFooterComponent(page, start, end);
2839
+ }
2840
+ }
2841
+ scrollEdges(config) {
2842
+ DomHelper.translate(this.element, 0, -config.scrollTop);
2843
+ const start = -this.element.offsetTop;
2844
+ const end = start + this.parentElement.clientHeight;
2845
+ let removeIndex = this.edgeElements.findIndex(x => !x.isWithin(start, end));
2846
+ while (removeIndex !== -1) {
2847
+ const element = this.edgeElements[removeIndex];
2848
+ if (element.isOrigin) {
2849
+ const copy = this.edgeElements.find(x => x.isCopy(element.edgeType, element.pageType));
2850
+ if (copy) {
2851
+ copy.substitute(element);
2852
+ }
2853
+ }
2854
+ DomHelper.removeElement(this.edgeElements[removeIndex].container);
2855
+ this.edgeElements.splice(removeIndex, 1);
2856
+ removeIndex = this.edgeElements.findIndex(x => !x.isWithin(start, end));
2857
+ }
2858
+ for (let page of config.pages) {
2859
+ if (!this.edgeElements.some(x => x.page === page && x.edgeType === EdgeType.Header)) {
2860
+ this.renderPageHeaderComponent(page, start, end);
2861
+ }
2862
+ if (!this.edgeElements.some(x => x.page === page && x.edgeType === EdgeType.Footer)) {
2863
+ this.renderPageFooterComponent(page, start, end);
2735
2864
  }
2736
- pagesToRender.push(edgeElement.page);
2737
2865
  }
2738
- this.removeEdgeComponents(pagesToRender);
2739
- this.renderPagesEdgeComponents(pagesToRender);
2740
2866
  }
2741
2867
  updateLines(config) {
2742
2868
  DomHelper.translate(this.element, 0, -config.scrollTop);
@@ -2746,13 +2872,6 @@ class TextLayer {
2746
2872
  }
2747
2873
  this.lines.push(this.renderTextParagraph(config.contentRange));
2748
2874
  }
2749
- scrollPages(config) {
2750
- DomHelper.translate(this.element, 0, -config.scrollTop);
2751
- const removedPages = this.config.pages.filter(x => !config.pages.includes(x));
2752
- this.removeEdgeComponents(removedPages);
2753
- const newPages = config.pages.filter(x => !this.config.pages.includes(x));
2754
- this.renderPagesEdgeComponents(newPages);
2755
- }
2756
2875
  scrollLines(config) {
2757
2876
  const oldConfig = this.config;
2758
2877
  this.config = config;
@@ -2780,56 +2899,50 @@ class TextLayer {
2780
2899
  this.lines.push(lines);
2781
2900
  }
2782
2901
  }
2783
- getEdgeParagraphTop(topOffset, page) {
2784
- const paragraphTop = this.session.displayData.pagesSpace + topOffset;
2785
- return paragraphTop + (page - 1) * (this.session.displayData.pageHeight + this.session.displayData.pagesSpace);
2786
- }
2787
2902
  getParagraphTop(row) {
2788
2903
  return this.session.displayData.getDistanceFromTop(row);
2789
2904
  }
2790
- renderPagesEdgeComponents(pages) {
2791
- const displayData = this.session.displayData;
2792
- for (let page of pages) {
2793
- const header = this.session.customComponents.edges.getComponentByPage(page, EdgeType.Header);
2794
- const headerHeight = this.session.customComponents.edges.getComponentHeight(page, EdgeType.Header);
2795
- if (header) {
2796
- this.renderEdgeComponent(header, headerHeight, page);
2905
+ getEdgeTop(topOffset, page) {
2906
+ const paragraphTop = this.session.displayData.pagesSpace + topOffset;
2907
+ return paragraphTop + (page - 1) * (this.session.displayData.pageHeight + this.session.displayData.pagesSpace);
2908
+ }
2909
+ renderPageHeaderComponent(page, start, end) {
2910
+ const header = this.session.customComponents.edges.getComponentByPage(page, EdgeType.Header);
2911
+ if (header) {
2912
+ const height = this.session.customComponents.edges.getComponentHeight(header.instance);
2913
+ const edgeTop = this.getEdgeTop(0, page);
2914
+ if (edgeTop > end || edgeTop + height < start) {
2915
+ return;
2797
2916
  }
2798
- const footer = this.session.customComponents.edges.getComponentByPage(page, EdgeType.Footer);
2799
- const footerHeight = this.session.customComponents.edges.getComponentHeight(page, EdgeType.Footer);
2800
- if (footer) {
2801
- const topOffset = displayData.pageHeight - footerHeight;
2802
- this.renderEdgeComponent(footer, footerHeight, page, topOffset);
2917
+ this.renderEdgeComponent(header, height, page, edgeTop);
2918
+ }
2919
+ }
2920
+ renderPageFooterComponent(page, start, end) {
2921
+ const footer = this.session.customComponents.edges.getComponentByPage(page, EdgeType.Footer);
2922
+ if (footer) {
2923
+ const height = this.session.customComponents.edges.getComponentHeight(footer.instance);
2924
+ const topOffset = this.session.displayData.pageHeight - height;
2925
+ const edgeTop = this.getEdgeTop(topOffset, page);
2926
+ if (edgeTop > end || edgeTop + height < start) {
2927
+ return;
2803
2928
  }
2929
+ this.renderEdgeComponent(footer, height, page, edgeTop);
2804
2930
  }
2805
2931
  }
2806
- renderEdgeComponent(edgeComponent, edgeHeight, page, topOffset = 0) {
2932
+ renderEdgeComponent(component, edgeHeight, page, edgeTop) {
2807
2933
  const container = RenderingHelper.createDivContainer('noder-edge-group');
2808
- let paragraphTop = this.getEdgeParagraphTop(topOffset, page);
2809
2934
  DomHelper.setStyle(container.style, 'height', `${edgeHeight}px`);
2810
- DomHelper.setStyle(container.style, 'top', `${paragraphTop}px`);
2811
- const componentElement = edgeComponent.hostView.rootNodes[0];
2812
- if (this.edgeEditingPage === page) {
2813
- componentElement.setAttribute('data-session-id', `${edgeComponent.instance.sessionId}`);
2814
- container.appendChild(componentElement);
2815
- this.element.appendChild(container);
2816
- this.edgeElements.push(new EdgeElementModel({ page, element: container, pageType: edgeComponent.instance.model.pageType }));
2817
- return;
2818
- }
2819
- const componentCopy = componentElement.cloneNode(true);
2820
- componentCopy.setAttribute('data-session-id', `${edgeComponent.instance.sessionId}`);
2821
- container.appendChild(componentCopy);
2935
+ DomHelper.setStyle(container.style, 'top', `${edgeTop}px`);
2936
+ const componentElement = component.hostView.rootNodes[0];
2937
+ const edge = component.instance;
2938
+ const isOrigin = !this.edgeElements.some(x => x.isNotCopy(edge.type, edge.model.pageType));
2939
+ const element = isOrigin ? componentElement : componentElement.cloneNode(true);
2940
+ container.appendChild(element);
2822
2941
  this.element.appendChild(container);
2823
- this.edgeElements.push(new EdgeElementModel({ page, element: container, pageType: edgeComponent.instance.model.pageType }));
2824
- this.editorService.edgeElementCopyUpdated(componentCopy, page);
2825
- }
2826
- removeEdgeComponents(removedPages) {
2827
- let removeIndex = this.edgeElements.findIndex(x => removedPages.includes(x.page));
2828
- while (removeIndex !== -1) {
2829
- const removedElement = this.edgeElements[removeIndex];
2830
- DomHelper.removeElement(removedElement.element);
2831
- this.edgeElements.splice(removeIndex, 1);
2832
- removeIndex = this.edgeElements.findIndex(x => removedPages.includes(x.page));
2942
+ const model = new EdgeElementModel({ page, container, pageType: edge.model.pageType, edgeType: edge.type, isOrigin });
2943
+ this.edgeElements.push(model);
2944
+ if (!isOrigin) {
2945
+ element.onmouseenter = () => model.replace(this.edgeElements.find(x => x.isNotCopy(model.edgeType, model.pageType)));
2833
2946
  }
2834
2947
  }
2835
2948
  renderTextParagraph(rowsDistance) {
@@ -2845,7 +2958,7 @@ class TextLayer {
2845
2958
  DomHelper.setStyle(paragraphCell.element.style, 'padding-left', `${this.session.displayData.pageMargin.left}px`);
2846
2959
  DomHelper.setStyle(paragraphCell.element.style, 'padding-right', `${this.session.displayData.pageMargin.right}px`);
2847
2960
  const paragraphSettings = this.session.displayData.getParagraphSettings(row);
2848
- if (paragraphSettings?.numberingData.numberingId !== null) {
2961
+ if (paragraphSettings.numberingData.numberingId !== null) {
2849
2962
  const numberingElement = this.renderingHelper.renderNumberingMarker(paragraphSettings, this.element, this.session.generalProperties.scalingRatio);
2850
2963
  numberingElement.className = 'numberingMarker';
2851
2964
  paragraphCell.element.appendChild(numberingElement);
@@ -2863,10 +2976,7 @@ class TextLayer {
2863
2976
  parent.appendChild(linesContainerElement);
2864
2977
  const startIndex = this.session.displayData.positionToIndex({ row, column: 0 });
2865
2978
  const endIndex = this.session.displayData.positionToIndex({ row: row + 1, column: 0 }) - 1;
2866
- const combinedFormats = FormatStyleHelper.combineSection(this.session.model.formats, this.session.model.links, startIndex, endIndex).map(x => new FormatExtModel({
2867
- ...x,
2868
- content: this.session.model.content.substring(x.startIndex, x.endIndex + 1)
2869
- }));
2979
+ const combinedFormats = FormatStyleHelper.combineSection(this.session.model.formats, this.session.model.links, startIndex, endIndex).map(x => new FormatExtModel({ ...x, content: this.session.model.content.substring(x.startIndex, x.endIndex + 1) }));
2870
2980
  const splits = this.session.displayData.paragraphs[row].nextLineIndexes;
2871
2981
  if (splits?.length) {
2872
2982
  const distance = new DistanceModel({ start: startIndex, end: endIndex });
@@ -2891,11 +3001,11 @@ class PrintTextLayer extends TextLayer {
2891
3001
  }
2892
3002
 
2893
3003
  class PrintRenderer {
2894
- constructor(mainSession, editorService) {
3004
+ constructor(mainSession) {
2895
3005
  this.mainSession = mainSession;
2896
3006
  this.pagesCount = Math.round((mainSession.displayData.pagesSpace * 2 + mainSession.displayData.allPagesHeight) / mainSession.displayData.minHeight);
2897
3007
  this.createContent();
2898
- this.createLayers(editorService);
3008
+ this.createLayers();
2899
3009
  }
2900
3010
  renderPrintDocument() {
2901
3011
  const layerConfig = this.computeLayerConfig();
@@ -2924,8 +3034,8 @@ class PrintRenderer {
2924
3034
  this.content = document.createElement('div');
2925
3035
  this.content.className = 'noder-content print';
2926
3036
  }
2927
- createLayers(editorService) {
2928
- this.textLayer = new PrintTextLayer(this.content, this.mainSession, editorService, PrintRenderingHelper);
3037
+ createLayers() {
3038
+ this.textLayer = new PrintTextLayer(this.content, this.mainSession, PrintRenderingHelper);
2929
3039
  this.pagesLayer = new PrintPagesLayer(this.content, this.mainSession);
2930
3040
  }
2931
3041
  createDocumentHtml(layerConfig) {
@@ -2954,9 +3064,9 @@ class PrintRenderer {
2954
3064
  }
2955
3065
 
2956
3066
  class PrintHelper extends RenderingHelper {
2957
- static printDocument(session, editorService) {
3067
+ static printDocument(session) {
2958
3068
  this.removePrintContainers();
2959
- const renderer = new PrintRenderer(session, editorService);
3069
+ const renderer = new PrintRenderer(session);
2960
3070
  renderer.renderPrintDocument();
2961
3071
  this.printDocumentHtml(renderer.documentHtml);
2962
3072
  }
@@ -3236,7 +3346,7 @@ class SaveCommandsHelper {
3236
3346
  return new CommandModel({ commandType: CommandType.RemoveNumberings, removeNumberings, targets });
3237
3347
  }
3238
3348
  static getRestoreNumberingsCommand(restoreNumberings, targets) {
3239
- return new CommandModel({ commandType: CommandType.AddNumbering, restoreNumberings, targets });
3349
+ return new CommandModel({ commandType: CommandType.RestoreNumberings, restoreNumberings, targets });
3240
3350
  }
3241
3351
  static getApplyImageStyleCommand(height, width, insertIndex, targets) {
3242
3352
  const applyImageStyle = new ApplyImageStyleModel({ height, width, insertIndex });
@@ -3250,8 +3360,8 @@ class SaveCommandsHelper {
3250
3360
  const applyTextStyle = new ApplyTextStyleModel({ startIndex, endIndex, textStyle });
3251
3361
  return new CommandModel({ commandType: CommandType.ApplyTextStyle, applyTextStyle, targets });
3252
3362
  }
3253
- static getDeleteCommand(startIndex, endIndex, targets) {
3254
- const deleteModel = new DeleteModel({ startIndex, endIndex });
3363
+ static getDeleteCommand(startIndex, count, targets) {
3364
+ const deleteModel = new DeleteModel({ startIndex, count });
3255
3365
  return new CommandModel({ commandType: CommandType.Delete, delete: deleteModel, targets });
3256
3366
  }
3257
3367
  static getInsertTextCommand(text, insertIndex, targets) {
@@ -3318,7 +3428,8 @@ class SaveCommandsHelper {
3318
3428
  paragraphs: restoreModel.paragraphs,
3319
3429
  tables: restoreModel.tables,
3320
3430
  tabs: restoreModel.tabs,
3321
- text: restoreModel.text
3431
+ text: restoreModel.text,
3432
+ links: restoreModel.links
3322
3433
  });
3323
3434
  return new CommandModel({ commandType: CommandType.Restore, restore, targets });
3324
3435
  }
@@ -3997,7 +4108,7 @@ class Editor {
3997
4108
  this.session.applyToolbarStyles();
3998
4109
  this.search = new Search();
3999
4110
  this.search.set({ wrap: true });
4000
- this.subscriptions.push(this.searchOptionSubscription(), this.replaceSubscription(), this.setTextStylesSubscription(), this.setParagraphStylesSubscription(), this.changeElementStyleSubscription(), this.setNumberingTemplateTypeSubscription(), this.removeNumberingsSubscription(), this.setImageStyleSubscription(), this.createCustomComponentSubscription(), this.insertBreakSubscription(), this.insertImageSubscription(), this.insertLinkSubscription(), this.insertTextSubscription(), this.endMousePressSubscription(), this.disableSelectionSubscription(), this.changedTableSizeSubscription(), this.insertTableRowsSubscription(), this.insertTableColumnsSubscription(), this.removeTableRowsSubscription(), this.removeTableColumnsSubscription(), this.removedImageSubscription(), this.resizeTableColumnsSubscription(), this.insertTableSubscription(), this.rendererUpdatedSubscription(), this.edgeElementCopyUpdatedSubscription(), this.changedEdgeHeightSubscription(), this.undoSubscription(), this.redoSubscription(), this.clipboardDataSubscription(), this.cutSelectedSubscription(), this.copySelectedSubscription(), this.pasteFromClipboardSubscription(), this.selectAllSubscription(), this.removeSelectedSubscription(), this.printSubscription(), this.updateEdgeSubscription(), this.blurCustomComponentSubscription());
4111
+ this.subscriptions.push(this.searchOptionSubscription(), this.replaceSubscription(), this.setTextStylesSubscription(), this.setParagraphStylesSubscription(), this.changeElementStyleSubscription(), this.setNumberingTemplateTypeSubscription(), this.removeNumberingsSubscription(), this.setImageStyleSubscription(), this.createCustomComponentSubscription(), this.insertBreakSubscription(), this.insertImageSubscription(), this.insertLinkSubscription(), this.insertTextSubscription(), this.endMousePressSubscription(), this.disableSelectionSubscription(), this.changedTableSizeSubscription(), this.changedEdgeSizeSubscription(), this.imageLoadedSubscription(), this.changedEdgeSubscription(), this.insertTableRowsSubscription(), this.insertTableColumnsSubscription(), this.removeTableRowsSubscription(), this.removeTableColumnsSubscription(), this.removedImageSubscription(), this.resizeTableColumnsSubscription(), this.insertTableSubscription(), this.undoSubscription(), this.redoSubscription(), this.clipboardDataSubscription(), this.cutSelectedSubscription(), this.copySelectedSubscription(), this.pasteFromClipboardSubscription(), this.selectAllSubscription(), this.removeSelectedSubscription(), this.printSubscription(), this.updateEdgeSubscription(), this.blurCustomComponentSubscription());
4001
4112
  }
4002
4113
  destroy() {
4003
4114
  this.subscriptions.forEach(s => s?.unsubscribe());
@@ -4161,7 +4272,7 @@ class Editor {
4161
4272
  this.replaceBy(new ReplaceModel({ insertParagraph }));
4162
4273
  return;
4163
4274
  }
4164
- this.saveInsertParagraphToHistory(insertParagraph);
4275
+ this.saveInsertParagraphToHistory(insertTable.content, insertParagraph);
4165
4276
  const endPoint = this.session.insertParagraph(this.selection.cursor, insertParagraph);
4166
4277
  let lastRow = this.selection.cursor.row === endPoint.row ? endPoint.row : Infinity;
4167
4278
  this.renderer.updateLines(this.selection.cursor.row, lastRow);
@@ -4182,7 +4293,7 @@ class Editor {
4182
4293
  }
4183
4294
  replaceBy(model) {
4184
4295
  const partIndexes = ContentHelper.getSelectedPartDocumentIndexes(this.session.displayData.paragraphs, this.selection.range);
4185
- model.delete = new DeleteModel({ startIndex: partIndexes.startIndex, endIndex: partIndexes.endIndex });
4296
+ model.delete = new DeleteModel({ startIndex: partIndexes.startIndex, count: partIndexes.endIndex - partIndexes.startIndex + 1 });
4186
4297
  this.saveReplaceToHistory(this.selection.range, model);
4187
4298
  this.removeCustomElementsData();
4188
4299
  const endPosition = this.session.replace(model);
@@ -4383,8 +4494,8 @@ class Editor {
4383
4494
  command = SaveCommandsHelper.getInsertParagraphCommand(operation, this.targets);
4384
4495
  }
4385
4496
  else if (operation instanceof DeleteModel) {
4386
- this.session.removeByDocumentIndexes(operation.startIndex, operation.endIndex);
4387
- command = SaveCommandsHelper.getDeleteCommand(operation.startIndex, operation.endIndex, this.targets);
4497
+ this.session.removeByDocumentIndexes(operation.startIndex, operation.startIndex + operation.count);
4498
+ command = SaveCommandsHelper.getDeleteCommand(operation.startIndex, operation.count, this.targets);
4388
4499
  }
4389
4500
  else if (operation instanceof InsertStyledTextModel) {
4390
4501
  this.session.insertTextByDocumentIndex(operation.insertIndex, operation.text, new TextStyleModel(operation.textStyle));
@@ -4409,7 +4520,7 @@ class Editor {
4409
4520
  }
4410
4521
  else if (operation instanceof RestoreTextStylesModel) {
4411
4522
  const deepCopy = structuredClone(operation);
4412
- this.session.restoreTextStyles(deepCopy.formats);
4523
+ this.session.restoreTextStyles(deepCopy.formats, deepCopy.linkFormats);
4413
4524
  command = SaveCommandsHelper.getRestoreTextStylesCommand(deepCopy.formats, this.targets);
4414
4525
  }
4415
4526
  else if (operation instanceof RestoreParagraphStylesModel) {
@@ -4437,6 +4548,10 @@ class Editor {
4437
4548
  this.session.insertImageByDocumentIndex(operation);
4438
4549
  command = SaveCommandsHelper.getInsertImageCommand(operation, this.targets);
4439
4550
  }
4551
+ else if (operation instanceof InsertLinkModel) {
4552
+ this.session.insertLinkByDocumentIndex(operation);
4553
+ command = SaveCommandsHelper.getInsertLinkOperation(operation, this.targets);
4554
+ }
4440
4555
  else if (operation instanceof ApplyImageStyleModel) {
4441
4556
  this.session.applyImageStyle(operation);
4442
4557
  const { height, width, insertIndex } = operation;
@@ -4506,18 +4621,18 @@ class Editor {
4506
4621
  }
4507
4622
  saveRemoveToHistory(range) {
4508
4623
  const restoreModel = this.createRestoreFromSlice(range.start.row, range.start.column, range.end.row, range.end.column);
4509
- const endIndex = restoreModel.endIndex;
4624
+ const count = restoreModel.endIndex - restoreModel.startIndex + 1;
4510
4625
  restoreModel.endIndex = restoreModel.startIndex; // this is to restore in position without deleting/replacing anything in range
4511
4626
  this.history.pushDelete(restoreModel);
4512
- this.commandsService.createCommand(SaveCommandsHelper.getDeleteCommand(restoreModel.startIndex, endIndex, this.targets));
4627
+ this.commandsService.createCommand(SaveCommandsHelper.getDeleteCommand(restoreModel.startIndex, count, this.targets));
4513
4628
  }
4514
4629
  saveInsertTextToHistory(paragraph, indexInParagraph, text) {
4515
4630
  const index = ContentHelper.paragraphToDocumentIndex(this.session.displayData.paragraphs, paragraph, indexInParagraph);
4516
4631
  this.history.pushInsertText(index, text);
4517
4632
  this.commandsService.createCommand(SaveCommandsHelper.getInsertTextCommand(text, index, this.targets));
4518
4633
  }
4519
- saveInsertParagraphToHistory(model) {
4520
- this.history.pushInsertParagraph(model, this.session.model.paragraphs);
4634
+ saveInsertParagraphToHistory(content, model) {
4635
+ this.history.pushInsertParagraph(content, model, this.session.model.paragraphs);
4521
4636
  this.commandsService.createCommand(SaveCommandsHelper.getInsertParagraphCommand(model, this.targets));
4522
4637
  }
4523
4638
  saveInsertStyledTextToHistory(paragraph, indexInParagraph, text, style) {
@@ -4533,8 +4648,8 @@ class Editor {
4533
4648
  model.isOnNewParagraph =
4534
4649
  model.breakType === BreakTypes.Page &&
4535
4650
  BreakHelper.getBreakType(this.session.model, CUSTOM_ELEMENT_MARKER, model.insertIndex - 1) !== BreakTypes.Page;
4536
- const endIndex = model.isOnNewParagraph ? model.insertIndex + NEW_LINE_MARKUP.length + 1 : model.insertIndex + 1;
4537
- this.history.pushInsertBreak(model, endIndex);
4651
+ const count = model.isOnNewParagraph ? NEW_LINE_MARKUP.length + 1 : 1;
4652
+ this.history.pushInsertBreak(model, count);
4538
4653
  this.commandsService.createCommand(SaveCommandsHelper.getInsertBreakCommand(model, this.targets));
4539
4654
  }
4540
4655
  saveInsertTabToHistory(model) {
@@ -4555,7 +4670,8 @@ class Editor {
4555
4670
  }
4556
4671
  saveApplyTextStyleToHistory(startIndex, endIndex, textStyle) {
4557
4672
  const formats = FormatHelper.sliceSection(this.session.model.formats, startIndex, endIndex);
4558
- this.history.pushApplyTextStyle(startIndex, endIndex, textStyle, formats);
4673
+ const linkFormats = LinkHelper.sliceFormats(this.session.model.links, startIndex, endIndex);
4674
+ this.history.pushApplyTextStyle(startIndex, endIndex, textStyle, formats, linkFormats);
4559
4675
  this.commandsService.createCommand(SaveCommandsHelper.getApplyTextStyleCommand(startIndex, endIndex, textStyle, this.targets));
4560
4676
  }
4561
4677
  saveApplyParagraphStyleToHistory(startIndex, endIndex, paragraphStyle) {
@@ -4592,7 +4708,14 @@ class Editor {
4592
4708
  }
4593
4709
  saveReplaceToHistory(range, model) {
4594
4710
  const restoreModel = this.createRestoreFromSlice(range.start.row, range.start.column, range.end.row, range.end.column);
4595
- restoreModel.endIndex = restoreModel.startIndex + (model.insertText?.text.length ?? 1); // this is to restore in range with deleting/replacing content within
4711
+ if (model.insertParagraph) {
4712
+ const { startIndex, count } = this.history.getDeleteDataForInsertParagraphs(ContentHelper.getContentFromInsertParagraph(model.insertParagraph), model.insertParagraph, this.session.model.paragraphs);
4713
+ restoreModel.startIndex = startIndex;
4714
+ restoreModel.endIndex = startIndex + count - 1;
4715
+ }
4716
+ else {
4717
+ restoreModel.endIndex = restoreModel.startIndex + (model.insertText?.text.length ?? 1); // this is to restore in range with deleting/replacing content within
4718
+ }
4596
4719
  this.history.pushReplace(restoreModel, model);
4597
4720
  this.commandsService.createCommand(SaveCommandsHelper.getReplaceCommand(model, this.targets));
4598
4721
  }
@@ -4604,11 +4727,11 @@ class Editor {
4604
4727
  const paragraphs = IndexedElementHelper.sliceSection(this.session.model.paragraphs, startIndex, endIndex).map(x => new ParagraphModel(x));
4605
4728
  const images = IndexedElementHelper.sliceSection(this.session.model.images, startIndex, endIndex).map(x => new ImageModel(x));
4606
4729
  const tables = IndexedElementHelper.sliceSection(this.session.model.tables, startIndex, endIndex).map(x => new TableModel(x));
4607
- const elements = IndexedElementHelper.sliceSection(this.session.model.elements, startIndex, endIndex).map(x => new ElementModel({ ...x, guid: '' }));
4730
+ const elements = IndexedElementHelper.sliceSection(this.session.model.elements, startIndex, endIndex).map(x => new ElementModel({ ...x, id: 0, guid: '' }));
4608
4731
  const breaks = IndexedElementHelper.sliceSection(this.session.model.breaks, startIndex, endIndex).map(x => new BreakModel(x));
4609
4732
  const tabs = IndexedElementHelper.sliceSection(this.session.model.tabs, startIndex, endIndex).map(x => new TabModel(x));
4610
4733
  const links = LinkHelper.sliceSection(this.session.model.links, startIndex, endIndex).map(x => new LinkModel(x));
4611
- return new RestoreModel({ startIndex, endIndex, text, formats, paragraphs, images, tables, elements, breaks, tabs, links: links });
4734
+ return new RestoreModel({ startIndex, endIndex, text, formats, paragraphs, images, tables, elements, breaks, tabs, links });
4612
4735
  }
4613
4736
  createCustomElement(data) {
4614
4737
  const insertIndex = ContentHelper.paragraphToDocumentIndex(this.session.displayData.paragraphs, this.selection.range.start.row, this.selection.range.start.column);
@@ -4703,8 +4826,8 @@ class Editor {
4703
4826
  this.renderer.showCursor();
4704
4827
  }
4705
4828
  onMouseClick(event) {
4706
- const customElement = this.setCurrentSession(event.clientY, event.target);
4707
- if (customElement && customElement.tagName !== this.tableCellTagName) {
4829
+ const customElement = this.setCurrentSession(event.target);
4830
+ if (customElement && customElement.tagName !== this.tableCellTagName && customElement.tagName !== this.edgeElementTagName) {
4708
4831
  this.focusCustomComponent(customElement);
4709
4832
  }
4710
4833
  else {
@@ -4712,8 +4835,8 @@ class Editor {
4712
4835
  }
4713
4836
  }
4714
4837
  onLeftClick(event) {
4715
- const customElement = this.setCurrentSession(event.clientY, event.target);
4716
- if (customElement && customElement.tagName !== this.tableCellTagName) {
4838
+ const customElement = this.setCurrentSession(event.target);
4839
+ if (customElement && customElement.tagName !== this.tableCellTagName && customElement.tagName !== this.edgeElementTagName) {
4717
4840
  this.focusCustomComponent(customElement);
4718
4841
  return;
4719
4842
  }
@@ -4721,14 +4844,14 @@ class Editor {
4721
4844
  if (!this.textInput.isFocused) {
4722
4845
  this.textInput.input.focus();
4723
4846
  }
4724
- const position = this.renderer.screenToTextCoordinates(event.clientX, event.clientY);
4847
+ const position = this.renderer.screenToTextCoordinatesUsingMidpoint(event.clientX, event.clientY);
4725
4848
  if (event.shiftKey) {
4726
4849
  this.selection.moveSelection(position);
4727
4850
  }
4728
4851
  else if (event.ctrlKey) {
4729
- const linkModel = this.session.getLinkModel(position);
4730
- if (linkModel) {
4731
- window.open(linkModel.link);
4852
+ const link = this.getLinkModel(event);
4853
+ if (link) {
4854
+ window.open(link.link);
4732
4855
  event.preventDefault();
4733
4856
  return;
4734
4857
  }
@@ -4741,17 +4864,11 @@ class Editor {
4741
4864
  this.mouseHandler.startMousePress(this);
4742
4865
  }
4743
4866
  onDoubleClick(event) {
4744
- let isStartEditEdge = false;
4867
+ const isEdgeEdit = this.mainSession.customComponents.edges.isEdit;
4745
4868
  const customElement = this.getCustomElement(event.target);
4746
4869
  if (customElement) {
4747
4870
  const elementSessionId = +customElement.attributes.getNamedItem('data-session-id').value;
4748
- let clickedPage = null;
4749
- const isParentEdge = this.isParentEdge(customElement);
4750
- if (customElement.tagName === this.edgeElementTagName || (isParentEdge && !this.regulatorService.edgeEditingPage)) {
4751
- clickedPage = this.getClickedPage(event.clientY);
4752
- isStartEditEdge = !this.regulatorService.edgeEditingPage;
4753
- }
4754
- this.regulatorService.setCustomSessionAsCurrent(elementSessionId, clickedPage);
4871
+ this.regulatorService.setCustomSessionAsCurrent(elementSessionId);
4755
4872
  }
4756
4873
  else {
4757
4874
  this.regulatorService.setMainSessionAsCurrent();
@@ -4762,8 +4879,8 @@ class Editor {
4762
4879
  }
4763
4880
  this.blurCustomComponent();
4764
4881
  event.preventDefault();
4765
- const position = this.renderer.screenToTextCoordinates(event.clientX, event.clientY);
4766
- if (isStartEditEdge) {
4882
+ const position = this.renderer.screenToTextCoordinatesUsingMidpoint(event.clientX, event.clientY);
4883
+ if (!isEdgeEdit && this.mainSession.customComponents.edges.isEdit) {
4767
4884
  this.selection.placeCursor(position);
4768
4885
  }
4769
4886
  else {
@@ -4773,22 +4890,22 @@ class Editor {
4773
4890
  this.onSelectionChange();
4774
4891
  }
4775
4892
  onTripleClick(event) {
4776
- const customElement = this.setCurrentSession(event.clientY, event.target);
4777
- if (customElement && customElement.tagName !== this.tableCellTagName) {
4893
+ const customElement = this.setCurrentSession(event.target);
4894
+ if (customElement && customElement.tagName !== this.tableCellTagName && customElement.tagName !== this.edgeElementTagName) {
4778
4895
  this.focusCustomComponent(customElement);
4779
4896
  return;
4780
4897
  }
4781
4898
  this.blurCustomComponent();
4782
4899
  event.preventDefault();
4783
- const position = this.renderer.screenToTextCoordinates(event.clientX, event.clientY);
4900
+ const position = this.renderer.screenToTextCoordinatesUsingMidpoint(event.clientX, event.clientY);
4784
4901
  const start = new CursorParagraph(position.row, 0);
4785
4902
  const end = new CursorParagraph(position.row, this.session.displayData.getParagraphContent(position.row).length);
4786
4903
  this.selection.placeSelection(start, end);
4787
4904
  this.onSelectionChange();
4788
4905
  }
4789
4906
  onQuadClick(event) {
4790
- const customElement = this.setCurrentSession(event.clientY, event.target);
4791
- if (customElement && customElement.tagName !== this.tableCellTagName) {
4907
+ const customElement = this.setCurrentSession(event.target);
4908
+ if (customElement && customElement.tagName !== this.tableCellTagName && customElement.tagName !== this.edgeElementTagName) {
4792
4909
  this.focusCustomComponent(customElement);
4793
4910
  return;
4794
4911
  }
@@ -4808,44 +4925,33 @@ class Editor {
4808
4925
  event.stopPropagation();
4809
4926
  event.preventDefault();
4810
4927
  }
4811
- setCurrentSession(clickPositionY, element) {
4928
+ getLinkModel(event) {
4929
+ const isInsideEdge = this.isInsideEdge(event.target);
4930
+ const isEdgeEdit = this.mainSession.customComponents.edges.isEdit;
4931
+ if (!isInsideEdge || isEdgeEdit) {
4932
+ const position = this.renderer.screenToTextCoordinatesUsingBoundary(event.clientX, event.clientY);
4933
+ return this.session.getLinkModel(position);
4934
+ }
4935
+ const customElement = this.getCustomElement(event.target);
4936
+ const sessionId = +customElement.attributes.getNamedItem('data-session-id').value;
4937
+ const session = this.regulatorService.getSessionModel(sessionId);
4938
+ const position = session.renderer.screenToTextCoordinatesUsingBoundary(event.clientX, event.clientY, customElement.getBoundingClientRect());
4939
+ return session.session.getLinkModel(position);
4940
+ }
4941
+ setCurrentSession(element) {
4812
4942
  const customElement = this.getCustomElement(element);
4813
- this.blurEdgeCustomComponents(customElement);
4814
- if (!customElement) {
4943
+ const isInsideEdge = this.isInsideEdge(customElement);
4944
+ const isEdgeEdit = this.mainSession.customComponents.edges.isEdit;
4945
+ if (!customElement || (!isEdgeEdit && isInsideEdge)) {
4815
4946
  this.regulatorService.setMainSessionAsCurrent();
4947
+ return this.customElementTagNames.includes(customElement?.tagName) ? customElement : null;
4816
4948
  }
4817
- else {
4818
- const elementSessionId = +customElement.attributes.getNamedItem('data-session-id').value;
4819
- const isEdgeEditing = this.regulatorService.edgeEditingPage;
4820
- if (customElement.tagName === this.edgeElementTagName) {
4821
- if (isEdgeEditing) {
4822
- const clickedPage = this.getClickedPage(clickPositionY);
4823
- this.regulatorService.setCustomSessionAsCurrent(elementSessionId, clickedPage);
4824
- }
4825
- else {
4826
- this.regulatorService.setMainSessionAsCurrent();
4827
- }
4828
- }
4829
- else {
4830
- const isParentEdge = this.isParentEdge(customElement);
4831
- if (!isParentEdge) {
4832
- this.regulatorService.setCustomSessionAsCurrent(elementSessionId);
4833
- return customElement;
4834
- }
4835
- if (isEdgeEditing) {
4836
- const clickedPage = this.getClickedPage(clickPositionY);
4837
- this.regulatorService.setCustomSessionAsCurrent(elementSessionId, clickedPage);
4838
- return customElement;
4839
- }
4840
- else {
4841
- this.regulatorService.setMainSessionAsCurrent();
4842
- }
4843
- }
4844
- }
4845
- return null;
4949
+ const elementSessionId = +customElement.attributes.getNamedItem('data-session-id').value;
4950
+ this.regulatorService.setCustomSessionAsCurrent(elementSessionId);
4951
+ return customElement.tagName !== this.edgeElementTagName ? customElement : null;
4846
4952
  }
4847
4953
  getCustomElement(element) {
4848
- if (element.tagName === this.parentTagName) {
4954
+ if (!element || element.tagName === this.parentTagName) {
4849
4955
  return null;
4850
4956
  }
4851
4957
  else if (this.customElementTagNames.includes(element.tagName)) {
@@ -4855,21 +4961,20 @@ class Editor {
4855
4961
  return this.getCustomElement(element.parentElement);
4856
4962
  }
4857
4963
  }
4858
- isParentEdge(element) {
4859
- if (element.tagName === this.parentTagName) {
4860
- return false;
4964
+ isInsideEdge(element) {
4965
+ return !!this.getParentEdge(element);
4966
+ }
4967
+ getParentEdge(element) {
4968
+ if (!element || element.tagName === this.parentTagName) {
4969
+ return null;
4861
4970
  }
4862
4971
  else if (element.tagName === this.edgeElementTagName) {
4863
- return true;
4972
+ return element;
4864
4973
  }
4865
4974
  else {
4866
- return this.isParentEdge(element.parentElement);
4975
+ return this.getParentEdge(element.parentElement);
4867
4976
  }
4868
4977
  }
4869
- getClickedPage(mousePosition) {
4870
- const positionY = mousePosition + this.mainSession.scrollTop - this.mainRenderer.container.getBoundingClientRect().top;
4871
- return PositionHelper.pixelToPage(positionY, this.mainSession);
4872
- }
4873
4978
  /**
4874
4979
  * Returns the string of text currently highlighted.
4875
4980
  */
@@ -4924,7 +5029,7 @@ class Editor {
4924
5029
  this.editorService.keyDown(event);
4925
5030
  }
4926
5031
  onPrint() {
4927
- PrintHelper.printDocument(this.mainSession, this.editorService);
5032
+ PrintHelper.printDocument(this.mainSession);
4928
5033
  }
4929
5034
  focusCustomComponent(element) {
4930
5035
  const index = +element.attributes.getNamedItem('data-insert-index').value;
@@ -4947,25 +5052,6 @@ class Editor {
4947
5052
  this.focusedComponent = null;
4948
5053
  }
4949
5054
  }
4950
- blurEdgeCustomComponents(customElement) {
4951
- if (!this.regulatorService.edgeEditingPage || !this.focusedComponent) {
4952
- return;
4953
- }
4954
- if (!customElement ||
4955
- customElement.tagName === this.tableCellTagName ||
4956
- customElement.tagName === this.edgeElementTagName ||
4957
- +customElement.attributes.getNamedItem('data-session-id').value !== this.focusedComponent.instance.sessionId) {
4958
- this.blurCustomComponent();
4959
- return;
4960
- }
4961
- const index = +customElement.attributes.getNamedItem('data-insert-index').value;
4962
- const component = this.session.customComponents.images.find(x => x.instance.insertIndex === index) ??
4963
- this.session.customComponents.tables.find(x => x.instance.insertIndex === index) ??
4964
- this.session.customComponents.customElements.find(x => x.instance.insertIndex === index);
4965
- if (this.focusedComponent !== component) {
4966
- this.blurCustomComponent();
4967
- }
4968
- }
4969
5055
  isEmptyNumberingParagraph(paragraphIndex) {
4970
5056
  const currentLine = this.session.displayData.getParagraphContent(paragraphIndex);
4971
5057
  return currentLine.length === 0 && this.session.model.paragraphs[paragraphIndex].paragraphStyle.numberingId !== null;
@@ -5039,8 +5125,8 @@ class Editor {
5039
5125
  this.session.resizeTableColumns(resizeTableColumns);
5040
5126
  this.changedTableSize(resizeTableColumns.insertIndex, sessionId);
5041
5127
  }
5042
- onMousePressedMove(x, y) {
5043
- const position = this.renderer.screenToTextCoordinates(x, y);
5128
+ onMousePressedMove(event) {
5129
+ const position = this.renderer.screenToTextCoordinatesUsingMidpoint(event.clientX, event.clientY);
5044
5130
  const cursor = this.selection.cursor;
5045
5131
  this.selection.moveSelection(position);
5046
5132
  if (cursor.column !== this.selection.cursor.column || cursor.row !== this.selection.cursor.row) {
@@ -5131,6 +5217,15 @@ class Editor {
5131
5217
  this.changedTableSize(data.insertIndex, data.sessionId);
5132
5218
  });
5133
5219
  }
5220
+ changedEdgeSizeSubscription() {
5221
+ return this.editorService.changedEdgeSize$.subscribe(({ edgeType, pageType }) => this.mainSession.displayData.updatePageVerticalData(edgeType, pageType));
5222
+ }
5223
+ imageLoadedSubscription() {
5224
+ return this.editorService.imageLoaded$.subscribe(sessionId => this.regulatorService.getSession(sessionId).onRendered());
5225
+ }
5226
+ changedEdgeSubscription() {
5227
+ return this.editorService.changedEdge$.subscribe(sessionId => this.regulatorService.arrangeEdgeChange(sessionId));
5228
+ }
5134
5229
  insertTableRowsSubscription() {
5135
5230
  return this.editorService.insertTableRows$.subscribe(data => {
5136
5231
  this.insertTableRows(data.insertIndex, data.rowsCount, data.targetIndex, data.inheritIndex, data.sessionId);
@@ -5173,29 +5268,6 @@ class Editor {
5173
5268
  this.focus();
5174
5269
  });
5175
5270
  }
5176
- rendererUpdatedSubscription() {
5177
- return this.editorService.rendererUpdated$.subscribe(sessionId => {
5178
- const edgeTarget = this.regulatorService.getEdgeTarget(sessionId);
5179
- if (edgeTarget !== null) {
5180
- this.mainRenderer.renderer.textLayer.updateEdgeByLocation(edgeTarget.edgeData.pageType);
5181
- }
5182
- });
5183
- }
5184
- edgeElementCopyUpdatedSubscription() {
5185
- return this.editorService.edgeElementCopyUpdated$.subscribe(data => {
5186
- if (this.regulatorService.edgeEditingPage !== data.page) {
5187
- return;
5188
- }
5189
- const edgeSessionId = +data.newElementCopy.attributes.getNamedItem('data-session-id').value;
5190
- const edgeSession = this.regulatorService.sessions.find(x => x.sessionId === edgeSessionId);
5191
- edgeSession.renderer.container = data.newElementCopy.firstChild;
5192
- });
5193
- }
5194
- changedEdgeHeightSubscription() {
5195
- return this.editorService.changedEdgeHeight$.subscribe(edgeType => {
5196
- this.mainSession.displayData.updatePageVerticalData(edgeType, this.regulatorService.edgeEditingPage);
5197
- });
5198
- }
5199
5271
  undoSubscription() {
5200
5272
  return this.editorService.undo$.subscribe(() => {
5201
5273
  this.undo();
@@ -5494,7 +5566,6 @@ class CellSessionSourceModel {
5494
5566
  constructor(table, cellComponent) {
5495
5567
  this.table = table;
5496
5568
  this.cellComponent = cellComponent;
5497
- this.edgeEditPage = null;
5498
5569
  }
5499
5570
  getTarget() {
5500
5571
  const tableCell = new TableCellModel({
@@ -5502,7 +5573,7 @@ class CellSessionSourceModel {
5502
5573
  row: this.cellComponent.rowIndex,
5503
5574
  column: this.cellComponent.cellIndex
5504
5575
  });
5505
- return new TargetModel({ type: TargetType.TableCell, tableCell, edgeEditPage: this.edgeEditPage });
5576
+ return new TargetModel({ type: TargetType.TableCell, tableCell });
5506
5577
  }
5507
5578
  }
5508
5579
 
@@ -5783,8 +5854,7 @@ class NoderTableCellComponent {
5783
5854
  return;
5784
5855
  }
5785
5856
  this._allParagraphsHeight = event.pageHeight;
5786
- const cellContentHeight = this._allParagraphsHeight;
5787
- this.heightChanged(this.rowIndex, this.cellIndex, cellContentHeight);
5857
+ this.heightChanged(this.rowIndex, this.cellIndex, event.pageHeight);
5788
5858
  };
5789
5859
  }
5790
5860
  ngOnDestroy() {
@@ -5812,6 +5882,9 @@ class NoderTableCellComponent {
5812
5882
  this.editorService.disableSelection();
5813
5883
  }
5814
5884
  onStartResizing(event, border) {
5885
+ if (this.session.isWithinEdge() && !this.regulatorService.mainSession.session.customComponents.edges.isEdit) {
5886
+ return;
5887
+ }
5815
5888
  event.stopPropagation();
5816
5889
  this.startResizing(new CellResizerParametersModel(this.columnIndex, this.rowIndex, this.cellIndex, border));
5817
5890
  }
@@ -5988,13 +6061,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
5988
6061
  }] } });
5989
6062
 
5990
6063
  class TableSelection {
5991
- constructor(editorService, overlayService, rowMatrix, table, tableEl, sessionId) {
6064
+ constructor(editorService, overlayService, regulatorService, rowMatrix, table, tableEl, session) {
5992
6065
  this.editorService = editorService;
5993
6066
  this.overlayService = overlayService;
6067
+ this.regulatorService = regulatorService;
5994
6068
  this.rowMatrix = rowMatrix;
5995
6069
  this.table = table;
5996
6070
  this.tableEl = tableEl;
5997
- this.sessionId = sessionId;
6071
+ this.session = session;
5998
6072
  this.editorTagName = 'APP-NOD-EDITOR';
5999
6073
  this.tableTagName = 'APP-NOD-TABLE';
6000
6074
  this.cellTagName = 'TD';
@@ -6013,6 +6087,9 @@ class TableSelection {
6013
6087
  }
6014
6088
  addTableContextMenuSubscriptions() {
6015
6089
  this.tableContextMenu$ = fromEvent(this.tableEl, 'contextmenu').subscribe((event) => {
6090
+ if (this.session.isEdgeOrWithinEdge() && !this.regulatorService.mainSession.session.customComponents.edges.isEdit) {
6091
+ return;
6092
+ }
6016
6093
  event.preventDefault();
6017
6094
  if (this.editorService.isViewOnly) {
6018
6095
  return;
@@ -6030,13 +6107,16 @@ class TableSelection {
6030
6107
  canRemoveRows,
6031
6108
  canRemoveColumns,
6032
6109
  tableInsertIndex: this.table.insertIndex,
6033
- sessionId: this.sessionId
6110
+ sessionId: this.session.sessionId
6034
6111
  };
6035
6112
  this.overlayService.open(TableOverlayMenuComponent, data, event.x, event.y);
6036
6113
  });
6037
6114
  }
6038
6115
  addTableMouseDownSubscriptions() {
6039
6116
  this.tableMouseDown$ = fromEvent(this.tableEl, 'mousedown').subscribe((event) => {
6117
+ if (this.session.isEdgeOrWithinEdge() && !this.regulatorService.mainSession.session.customComponents.edges.isEdit) {
6118
+ return;
6119
+ }
6040
6120
  if (event.ctrlKey ||
6041
6121
  event.button === MouseButton.Right ||
6042
6122
  !this.canStartSelection(event.target)) {
@@ -6247,7 +6327,7 @@ class TableSelection {
6247
6327
  break;
6248
6328
  }
6249
6329
  if (currentElement.tagName === this.tableTagName) {
6250
- canStartSelection = this.sessionId === +currentElement.getAttribute('data-session-id');
6330
+ canStartSelection = this.session.sessionId === +currentElement.getAttribute('data-session-id');
6251
6331
  break;
6252
6332
  }
6253
6333
  currentElement = currentElement.parentElement;
@@ -6372,12 +6452,13 @@ class NoderTableComponent extends BaseNoderComponent {
6372
6452
  set table(val) {
6373
6453
  this.content = val;
6374
6454
  }
6375
- constructor(componentService, editorService, el, overlayService) {
6455
+ constructor(componentService, editorService, el, overlayService, regulatorService) {
6376
6456
  super();
6377
6457
  this.componentService = componentService;
6378
6458
  this.editorService = editorService;
6379
6459
  this.el = el;
6380
6460
  this.overlayService = overlayService;
6461
+ this.regulatorService = regulatorService;
6381
6462
  this.rowMatrix = [];
6382
6463
  this.splits = [];
6383
6464
  this.minRowHeight = 19;
@@ -6420,7 +6501,7 @@ class NoderTableComponent extends BaseNoderComponent {
6420
6501
  this.createResizer();
6421
6502
  this.el.nativeElement.appendChild(this.resizerEl);
6422
6503
  this.el.nativeElement.appendChild(this.tableEl);
6423
- this.tableSelection = new TableSelection(this.editorService, this.overlayService, this.rowMatrix, this.table, this.tableEl, this.sessionId);
6504
+ this.tableSelection = new TableSelection(this.editorService, this.overlayService, this.regulatorService, this.rowMatrix, this.table, this.tableEl, this.regulatorService.getSession(this.sessionId));
6424
6505
  }
6425
6506
  getCellSession(row, column) {
6426
6507
  return this.rowMatrix[row].cells[column].componentRef.instance.session;
@@ -6753,13 +6834,13 @@ class NoderTableComponent extends BaseNoderComponent {
6753
6834
  }
6754
6835
  }
6755
6836
  }
6756
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NoderTableComponent, deps: [{ token: ComponentService }, { token: EditorService }, { token: i0.ElementRef }, { token: OverlayService }], target: i0.ɵɵFactoryTarget.Component }); }
6837
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NoderTableComponent, deps: [{ token: ComponentService }, { token: EditorService }, { token: i0.ElementRef }, { token: OverlayService }, { token: RegulatorService }], target: i0.ɵɵFactoryTarget.Component }); }
6757
6838
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: NoderTableComponent, selector: "app-nod-table", usesInheritance: true, ngImport: i0, template: '', isInline: true, styles: [":host{position:relative}:host::ng-deep table{position:relative;border-collapse:collapse;background:transparent;empty-cells:show;border-spacing:0;overflow:visible;table-layout:fixed}:host::ng-deep td{position:relative;vertical-align:top;border:1px solid #000;margin:0;padding:0;height:inherit}:host::ng-deep .hidden-cell{display:none;cursor:not-allowed}:host::ng-deep .resizer-border{position:absolute;border:solid .5px blue;z-index:1}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
6758
6839
  }
6759
6840
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NoderTableComponent, decorators: [{
6760
6841
  type: Component,
6761
6842
  args: [{ selector: 'app-nod-table', template: '', changeDetection: ChangeDetectionStrategy.OnPush, styles: [":host{position:relative}:host::ng-deep table{position:relative;border-collapse:collapse;background:transparent;empty-cells:show;border-spacing:0;overflow:visible;table-layout:fixed}:host::ng-deep td{position:relative;vertical-align:top;border:1px solid #000;margin:0;padding:0;height:inherit}:host::ng-deep .hidden-cell{display:none;cursor:not-allowed}:host::ng-deep .resizer-border{position:absolute;border:solid .5px blue;z-index:1}\n"] }]
6762
- }], ctorParameters: () => [{ type: ComponentService }, { type: EditorService }, { type: i0.ElementRef }, { type: OverlayService }] });
6843
+ }], ctorParameters: () => [{ type: ComponentService }, { type: EditorService }, { type: i0.ElementRef }, { type: OverlayService }, { type: RegulatorService }] });
6763
6844
 
6764
6845
  class NumberingDataModel {
6765
6846
  constructor(fields) {
@@ -7312,9 +7393,9 @@ class DisplayData extends EventEmitting {
7312
7393
  destroy() {
7313
7394
  this.removeAllListeners('pagesCountChanged');
7314
7395
  }
7315
- updatePageVerticalData(edgeType, page) {
7316
- const pageVerticalData = PageHelper.getVerticalData(page, this.pagesVerticalData);
7317
- const componentHeight = this.customComponents.edges.getComponentHeight(page, edgeType);
7396
+ updatePageVerticalData(edgeType, pageType) {
7397
+ const pageVerticalData = this.pagesVerticalData.find(x => x.pageType === pageType);
7398
+ const componentHeight = this.customComponents.edges.getComponentHeightByType(pageType, edgeType);
7318
7399
  if (edgeType === EdgeType.Header) {
7319
7400
  pageVerticalData.marginTop = componentHeight > this.pageMargin.top ? componentHeight : this.pageMargin.top;
7320
7401
  }
@@ -7924,53 +8005,57 @@ class NoderEdgeComponent extends DestroyComponent {
7924
8005
  get renderer() {
7925
8006
  return this.edgeSession.renderer;
7926
8007
  }
7927
- get height() {
8008
+ get contentHeight() {
7928
8009
  return this.session.displayData.defaultVerticalData.contentHeight;
7929
8010
  }
7930
8011
  constructor(regulatorService, editorService) {
7931
8012
  super();
7932
8013
  this.regulatorService = regulatorService;
7933
8014
  this.editorService = editorService;
8015
+ this.pagesCountChangedHandler = (event) => {
8016
+ if (this._height === event.pageHeight) {
8017
+ return;
8018
+ }
8019
+ this._height = event.pageHeight;
8020
+ this.applyHeight();
8021
+ this.editorService.changedEdgeSize(this.type, this.model.pageType);
8022
+ };
7934
8023
  }
7935
8024
  ngOnDestroy() {
8025
+ this.session?.displayData.removeEventListener('pagesCountChanged', this.pagesCountChangedHandler);
7936
8026
  this.regulatorService.removeSession(this.sessionId);
7937
8027
  super.ngOnDestroy();
7938
8028
  }
7939
8029
  initialize() {
7940
8030
  this.edgeSession = this.regulatorService.addEdgeSession(this);
7941
8031
  this.sessionId = this.edgeSession.sessionId;
7942
- this._previousHeight = this.height;
8032
+ this.container.nativeElement.parentElement.setAttribute('data-session-id', `${this.sessionId}`);
7943
8033
  DomHelper.setStyle(this.container.nativeElement.style, 'overflow', 'hidden');
7944
8034
  DomHelper.setStyle(this.typeContainer.nativeElement.style, 'visibility', 'hidden');
7945
- this.setTypeContainerPosition();
7946
- this.editorService.rendererUpdated$.pipe(takeUntil(this.destroy$)).subscribe(x => this.rendererUpdated(x));
8035
+ this.applyHeight();
8036
+ this.session.displayData.addEventListener('pagesCountChanged', this.pagesCountChangedHandler);
7947
8037
  }
7948
8038
  enterEditMode() {
7949
8039
  DomHelper.addCssClass(this.container.nativeElement, this.editModeClass);
7950
8040
  DomHelper.setStyle(this.typeContainer.nativeElement.style, 'visibility', 'visible');
8041
+ this.editorService.changedEdge(this.sessionId);
7951
8042
  }
7952
8043
  leaveEditMode() {
7953
8044
  DomHelper.removeCssClass(this.container.nativeElement, this.editModeClass);
7954
8045
  DomHelper.setStyle(this.typeContainer.nativeElement.style, 'visibility', 'hidden');
8046
+ this.editorService.changedEdge(this.sessionId);
7955
8047
  }
7956
- rendererUpdated(sessionId) {
7957
- if (sessionId !== this.sessionId || this.height === this._previousHeight) {
7958
- return;
7959
- }
7960
- this.editorService.changedEdgeHeight(this.type);
7961
- this._previousHeight = this.height;
7962
- this.setTypeContainerPosition();
7963
- }
7964
- setTypeContainerPosition() {
7965
- const renderedEdgeHeight = this.height > this.generalProperties.maxEdgeHeight ? this.generalProperties.maxEdgeHeight : this.height;
7966
- DomHelper.setStyle(this.typeContainer.nativeElement.style, this.typeContainerPosition, `${renderedEdgeHeight}px`);
8048
+ applyHeight() {
8049
+ const maxHeight = this.generalProperties.maxEdgeHeight;
8050
+ const height = this.contentHeight > maxHeight ? maxHeight : this.contentHeight;
8051
+ DomHelper.setStyle(this.typeContainer.nativeElement.style, this.typeContainerPosition, `${height}px`);
7967
8052
  }
7968
8053
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NoderEdgeComponent, deps: [{ token: RegulatorService }, { token: EditorService }], target: i0.ɵɵFactoryTarget.Component }); }
7969
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: NoderEdgeComponent, selector: "app-nod-edge", inputs: { model: "model", generalProperties: "generalProperties", margins: "margins", width: "width", parentSessionId: "parentSessionId", type: "type" }, host: { properties: { "attr.data-session-id": "this.sessionId" } }, viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: true, static: true }, { propertyName: "typeContainer", first: true, predicate: ["locationType"], descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: "<div\n #container\n class=\"edit-container\"></div>\n<div\n #locationType\n class=\"location-type\"></div>\n", styles: [":host{height:100%;width:100%;background:transparent;display:block}.location-type{position:absolute;height:auto;width:auto;font-size:9pt;background-color:#f2f2f2;border:1px solid #838282;border-radius:2px;padding:4px;margin-left:5px;z-index:2}.header-edit-mode{border-bottom:1px dashed #838282}.footer-edit-mode{border-top:1px dashed #838282}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
8054
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: NoderEdgeComponent, selector: "app-nod-edge", inputs: { model: "model", generalProperties: "generalProperties", margins: "margins", width: "width", parentSessionId: "parentSessionId", type: "type" }, viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: true, static: true }, { propertyName: "typeContainer", first: true, predicate: ["locationType"], descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: "<div\n #container\n class=\"edit-container\"></div>\n<div\n #locationType\n class=\"location-type\"></div>\n", styles: [":host{height:100%;width:100%;background:transparent;display:block}.location-type{position:absolute;height:auto;width:auto;font-size:9pt;color:#333;background-color:#f2f2f2;border:1px solid #838282;border-radius:2px;padding:4px;margin-left:5px;z-index:2}.header-edit-mode{border-bottom:1px dashed #838282}.footer-edit-mode{border-top:1px dashed #838282}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
7970
8055
  }
7971
8056
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NoderEdgeComponent, decorators: [{
7972
8057
  type: Component,
7973
- args: [{ selector: 'app-nod-edge', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n #container\n class=\"edit-container\"></div>\n<div\n #locationType\n class=\"location-type\"></div>\n", styles: [":host{height:100%;width:100%;background:transparent;display:block}.location-type{position:absolute;height:auto;width:auto;font-size:9pt;background-color:#f2f2f2;border:1px solid #838282;border-radius:2px;padding:4px;margin-left:5px;z-index:2}.header-edit-mode{border-bottom:1px dashed #838282}.footer-edit-mode{border-top:1px dashed #838282}\n"] }]
8058
+ args: [{ selector: 'app-nod-edge', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n #container\n class=\"edit-container\"></div>\n<div\n #locationType\n class=\"location-type\"></div>\n", styles: [":host{height:100%;width:100%;background:transparent;display:block}.location-type{position:absolute;height:auto;width:auto;font-size:9pt;color:#333;background-color:#f2f2f2;border:1px solid #838282;border-radius:2px;padding:4px;margin-left:5px;z-index:2}.header-edit-mode{border-bottom:1px dashed #838282}.footer-edit-mode{border-top:1px dashed #838282}\n"] }]
7974
8059
  }], ctorParameters: () => [{ type: RegulatorService }, { type: EditorService }], propDecorators: { model: [{
7975
8060
  type: Input
7976
8061
  }], generalProperties: [{
@@ -7983,9 +8068,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
7983
8068
  type: Input
7984
8069
  }], type: [{
7985
8070
  type: Input
7986
- }], sessionId: [{
7987
- type: HostBinding,
7988
- args: ['attr.data-session-id']
7989
8071
  }], container: [{
7990
8072
  type: ViewChild,
7991
8073
  args: ['container', { static: true }]
@@ -7994,31 +8076,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
7994
8076
  args: ['locationType', { static: true }]
7995
8077
  }] } });
7996
8078
 
7997
- class RenderChangesModel {
7998
- get any() {
7999
- return this.cursor || this.full || this.lines || this.marker || this.selection || this.scroll || this.size || this.text;
8000
- }
8001
- constructor(fields) {
8002
- this.cursor = false;
8003
- this.full = false;
8004
- this.lines = false;
8005
- this.marker = false;
8006
- this.selection = false;
8007
- this.scroll = false;
8008
- this.size = false;
8009
- this.text = false;
8010
- if (!fields) {
8011
- return;
8012
- }
8013
- Object.assign(this, fields);
8014
- }
8015
- apply(changes) {
8016
- for (let key of Object.keys(this)) {
8017
- this[key] ||= changes[key];
8018
- }
8019
- }
8020
- }
8021
-
8022
8079
  class Edges {
8023
8080
  constructor(componentService, headers, footers, margins, pageWidth, parentSessionId, generalProperties) {
8024
8081
  this.componentService = componentService;
@@ -8026,6 +8083,7 @@ class Edges {
8026
8083
  this.generalProperties = generalProperties;
8027
8084
  this.headersComponents = [];
8028
8085
  this.footersComponents = [];
8086
+ this.isEdit = false;
8029
8087
  if (headers) {
8030
8088
  const headerMargins = new MarginModel({ ...margins, bottom: 0 });
8031
8089
  this.headersComponents = this.createComponents(headers, pageWidth, headerMargins, EdgeType.Header);
@@ -8036,6 +8094,14 @@ class Edges {
8036
8094
  }
8037
8095
  this.setEdgeNameToComponents();
8038
8096
  }
8097
+ getTypeBySessionId(sessionId) {
8098
+ let component = this.headersComponents.find(x => x.instance.sessionId === sessionId);
8099
+ if (component) {
8100
+ return { type: EdgeType.Header, pageType: component.instance.model.pageType };
8101
+ }
8102
+ component = this.footersComponents.find(x => x.instance.sessionId === sessionId);
8103
+ return { type: EdgeType.Footer, pageType: component.instance.model.pageType };
8104
+ }
8039
8105
  getComponentByPage(page, type) {
8040
8106
  const components = type === EdgeType.Header ? this.headersComponents : this.footersComponents;
8041
8107
  return this.getComponent(components, page);
@@ -8049,24 +8115,32 @@ class Edges {
8049
8115
  if (!component) {
8050
8116
  return 0;
8051
8117
  }
8052
- return component.instance.height > this.generalProperties.maxEdgeHeight
8118
+ return component.instance.contentHeight > this.generalProperties.maxEdgeHeight
8053
8119
  ? this.generalProperties.maxEdgeHeight
8054
- : component.instance.height;
8120
+ : component.instance.contentHeight;
8055
8121
  }
8056
- getComponentHeight(page, type) {
8122
+ getComponentHeight(instance) {
8123
+ const height = instance.contentHeight;
8124
+ return height > this.generalProperties.maxEdgeHeight ? this.generalProperties.maxEdgeHeight : height;
8125
+ }
8126
+ getComponentHeightByType(pageType, type) {
8057
8127
  const components = type === EdgeType.Header ? this.headersComponents : this.footersComponents;
8058
- const component = this.getComponent(components, page);
8059
- if (!component) {
8060
- return 0;
8061
- }
8062
- return component.instance.height > this.generalProperties.maxEdgeHeight
8063
- ? this.generalProperties.maxEdgeHeight
8064
- : component.instance.height;
8128
+ const height = components.find(x => x.instance.model.pageType === pageType)?.instance.contentHeight ?? 0;
8129
+ return height > this.generalProperties.maxEdgeHeight ? this.generalProperties.maxEdgeHeight : height;
8065
8130
  }
8066
- toggleEditMode(needEnable) {
8131
+ toggleEditMode(isEdit) {
8132
+ if (this.isEdit === isEdit) {
8133
+ return;
8134
+ }
8135
+ this.isEdit = isEdit;
8067
8136
  const edgeComponents = [...this.headersComponents, ...this.footersComponents];
8068
8137
  for (let component of edgeComponents) {
8069
- needEnable ? component.instance.enterEditMode() : component.instance.leaveEditMode();
8138
+ if (isEdit) {
8139
+ component.instance.enterEditMode();
8140
+ }
8141
+ else {
8142
+ component.instance.leaveEditMode();
8143
+ }
8070
8144
  }
8071
8145
  }
8072
8146
  getUniquePageTypes() {
@@ -8103,7 +8177,6 @@ class Edges {
8103
8177
  generalProperties: this.generalProperties,
8104
8178
  parentSessionId: this.parentSessionId
8105
8179
  });
8106
- componentRef.instance.renderer.renderChanges(new RenderChangesModel({ text: true }));
8107
8180
  resultComponents.push(componentRef);
8108
8181
  }
8109
8182
  return resultComponents;
@@ -8145,11 +8218,10 @@ class EdgeSessionSourceModel {
8145
8218
  constructor(pageType, type) {
8146
8219
  this.pageType = pageType;
8147
8220
  this.type = type;
8148
- this.edgeEditPage = null;
8149
8221
  }
8150
8222
  getTarget() {
8151
8223
  const edgeData = new EdgeTargetModel({ pageType: this.pageType, type: this.type });
8152
- return new TargetModel({ type: TargetType.Edge, edgeData, edgeEditPage: this.edgeEditPage });
8224
+ return new TargetModel({ type: TargetType.Edge, edgeData });
8153
8225
  }
8154
8226
  }
8155
8227
 
@@ -8219,7 +8291,7 @@ class ImageInputHandler {
8219
8291
  return;
8220
8292
  }
8221
8293
  const keyCombination = this.getKeyCombination(event);
8222
- if (this.undoRedoActions[keyCombination] && !this.editorService.isViewOnly) {
8294
+ if (this.undoRedoActions[keyCombination]) {
8223
8295
  this.undoRedoActions[keyCombination]();
8224
8296
  event.preventDefault();
8225
8297
  return;
@@ -8461,7 +8533,7 @@ class NoderImageComponent extends BaseNoderComponent {
8461
8533
  const fileSource = URL.createObjectURL(x);
8462
8534
  const image = this.createImage(fileSource);
8463
8535
  this.elementRef.nativeElement.appendChild(image);
8464
- this.editorService.rendererUpdated(this.sessionId);
8536
+ this.editorService.imageLoaded(this.sessionId);
8465
8537
  });
8466
8538
  }
8467
8539
  onResizeEnd(size) {
@@ -8614,8 +8686,8 @@ class CellModel {
8614
8686
  }
8615
8687
 
8616
8688
  class ContentOperationsHelper {
8617
- static removeContent(content, startIndex, endIndex) {
8618
- return `${content.slice(0, startIndex)}${content.slice(endIndex + 1, content.length)}`;
8689
+ static removeContent(content, startIndex, count) {
8690
+ return `${content.slice(0, startIndex)}${content.slice(startIndex + count, content.length)}`;
8619
8691
  }
8620
8692
  static insertContent(content, text, index) {
8621
8693
  const before = content.slice(0, index);
@@ -8623,7 +8695,7 @@ class ContentOperationsHelper {
8623
8695
  return `${before}${text}${after}`;
8624
8696
  }
8625
8697
  static replaceContent(content, startIndex, endIndex, text) {
8626
- const reduced = this.removeContent(content, startIndex, endIndex);
8698
+ const reduced = this.removeContent(content, startIndex, endIndex - startIndex + 1);
8627
8699
  return this.insertContent(reduced, text, startIndex);
8628
8700
  }
8629
8701
  }
@@ -8690,7 +8762,7 @@ class FormatOperationsHelper {
8690
8762
  firstIndex++;
8691
8763
  }
8692
8764
  let lastIndex = firstIndex;
8693
- while (formats[lastIndex].endIndex < endIndex) {
8765
+ while (lastIndex < formats.length - 1 && formats[lastIndex].endIndex < endIndex) {
8694
8766
  lastIndex++;
8695
8767
  }
8696
8768
  if (formats[lastIndex].endIndex > endIndex) {
@@ -8727,13 +8799,13 @@ class ImageOperationsHelper {
8727
8799
  }
8728
8800
 
8729
8801
  class LinkOperationsHelper {
8730
- static insert(links, link, startIndex, endIndex, textStyle) {
8802
+ static insert(links, link, startIndex, endIndex, linkStyle) {
8731
8803
  LinkOperationsHelper.insertContent(links, startIndex, endIndex - startIndex + 1);
8732
8804
  const linkModel = new LinkModel({
8733
8805
  startIndex: startIndex,
8734
8806
  link,
8735
8807
  endIndex,
8736
- formats: [new FormatModel({ startIndex: 0, endIndex: endIndex - startIndex, textStyle })]
8808
+ formats: [new FormatModel({ startIndex: 0, endIndex: endIndex - startIndex, textStyle: linkStyle })]
8737
8809
  });
8738
8810
  const index = links.findIndex(x => x.startIndex > linkModel.startIndex);
8739
8811
  if (index < 0) {
@@ -8743,6 +8815,10 @@ class LinkOperationsHelper {
8743
8815
  links.splice(index, 0, linkModel);
8744
8816
  }
8745
8817
  }
8818
+ static insertStyledContent(links, index, textLength, style) {
8819
+ this.insertContent(links, index, textLength);
8820
+ this.apply(links, index, index + textLength - 1, style);
8821
+ }
8746
8822
  static insertContent(links, insertIndex, textLength) {
8747
8823
  for (let link of links) {
8748
8824
  if (link.startIndex < insertIndex && link.endIndex >= insertIndex) {
@@ -8772,13 +8848,13 @@ class LinkOperationsHelper {
8772
8848
  }
8773
8849
  if (links[i].startIndex <= startIndex && links[i].endIndex >= endIndex) {
8774
8850
  const startInLink = startIndex - links[i].startIndex;
8775
- const endInLink = startInLink + length - 1;
8851
+ const endInLink = endIndex - links[i].startIndex;
8776
8852
  links[i].endIndex -= length;
8777
8853
  FormatOperationsHelper.removeContent(links[i].formats, startInLink, endInLink);
8778
8854
  continue;
8779
8855
  }
8780
8856
  if (links[i].startIndex >= startIndex && links[i].startIndex <= endIndex) {
8781
- const endInLink = links[i].startIndex - startIndex - 1;
8857
+ const endInLink = endIndex - links[i].startIndex;
8782
8858
  links[i].startIndex = startIndex;
8783
8859
  links[i].endIndex -= length;
8784
8860
  FormatOperationsHelper.removeContent(links[i].formats, 0, endInLink);
@@ -8792,16 +8868,63 @@ class LinkOperationsHelper {
8792
8868
  }
8793
8869
  }
8794
8870
  }
8795
- static restore(links, startIndex, contentLength, newlinks) {
8871
+ static restore(links, startIndex, contentLength, newLinks) {
8796
8872
  this.insertContent(links, startIndex, contentLength);
8797
8873
  let indexInElements = links.findIndex(x => x.startIndex >= startIndex);
8798
8874
  indexInElements = indexInElements === -1 ? links.length : indexInElements;
8799
- links.splice(indexInElements, 0, ...newlinks);
8875
+ links.splice(indexInElements, 0, ...newLinks);
8876
+ this.merge(links, startIndex - 1, startIndex + contentLength);
8877
+ }
8878
+ static restoreFormats(links, formats) {
8879
+ formats.forEach(x => this.apply(links, x.startIndex, x.endIndex, x.textStyle));
8800
8880
  }
8801
8881
  static replaceContent(links, startIndex, endIndex, length) {
8802
8882
  this.removeContent(links, startIndex, endIndex);
8803
8883
  this.insertContent(links, startIndex, length);
8804
8884
  }
8885
+ static apply(links, startIndex, endIndex, style) {
8886
+ for (let link of links) {
8887
+ if (link.startIndex > endIndex || link.endIndex < startIndex) {
8888
+ continue;
8889
+ }
8890
+ const start = startIndex > link.startIndex ? startIndex - link.startIndex : 0;
8891
+ FormatOperationsHelper.apply(link.formats, start, endIndex - link.startIndex, style);
8892
+ }
8893
+ }
8894
+ static merge(links, start, end) {
8895
+ const firstIndex = links.findIndex(x => x.endIndex >= start);
8896
+ for (let link of links) {
8897
+ if (link.startIndex <= start && link.endIndex >= end) {
8898
+ const newLink = links[firstIndex + 1];
8899
+ newLink.formats.forEach(x => {
8900
+ x.startIndex += newLink.startIndex - link.startIndex;
8901
+ x.endIndex += newLink.startIndex - link.startIndex;
8902
+ });
8903
+ for (let { startIndex, endIndex, textStyle } of newLink.formats) {
8904
+ FormatOperationsHelper.apply(link.formats, startIndex, endIndex - startIndex + 1, textStyle);
8905
+ }
8906
+ links.splice(firstIndex + 1, 1);
8907
+ return;
8908
+ }
8909
+ }
8910
+ let lastIndex = firstIndex;
8911
+ while (lastIndex < links.length - 1 && links[lastIndex].endIndex < end) {
8912
+ lastIndex++;
8913
+ }
8914
+ for (let i = lastIndex; i > firstIndex; i--) {
8915
+ const previous = links[i - 1];
8916
+ if (previous.endIndex + 1 === links[i].startIndex && previous.link === links[i].link) {
8917
+ previous.endIndex = links[i].endIndex;
8918
+ links[i].formats.forEach(x => {
8919
+ x.startIndex += previous.formats[previous.formats.length - 1].endIndex + 1;
8920
+ x.endIndex += previous.formats[previous.formats.length - 1].endIndex + 1;
8921
+ });
8922
+ previous.formats.push(...links[i].formats);
8923
+ links.splice(i, 1);
8924
+ FormatStyleHelper.mergeFormats(previous.formats, 0, previous.endIndex - previous.startIndex);
8925
+ }
8926
+ }
8927
+ }
8805
8928
  }
8806
8929
 
8807
8930
  class NumberingModel {
@@ -9411,7 +9534,7 @@ class OperationsHelper {
9411
9534
  this.deleteRestore(contents, command.restore);
9412
9535
  break;
9413
9536
  case CommandType.Delete:
9414
- this.delete(contents, command.delete.startIndex, command.delete.endIndex);
9537
+ this.delete(contents, command.delete.startIndex, command.delete.count);
9415
9538
  break;
9416
9539
  case CommandType.ReplaceByText: {
9417
9540
  const model = command.replaceByText;
@@ -9425,7 +9548,7 @@ class OperationsHelper {
9425
9548
  }
9426
9549
  case CommandType.RestoreTextStyles: {
9427
9550
  const model = command.restoreTextStyles;
9428
- this.restoreTextStyles(contents, model.formats);
9551
+ this.restoreTextStyles(contents, model.formats, model.linkFormats);
9429
9552
  break;
9430
9553
  }
9431
9554
  case CommandType.RestoreParagraphStyles: {
@@ -9469,12 +9592,7 @@ class OperationsHelper {
9469
9592
  }
9470
9593
  case CommandType.InsertLink: {
9471
9594
  const model = command.insertLink;
9472
- this.insertLink(contents, model.linkDataModel.text, model.linkDataModel.link, model.insertIndex, new TextStyleModel({
9473
- ...DEFAULT_TEXT_STYLE,
9474
- headingStyleId: HYPERLINK_HEADING_STYLE_ID,
9475
- underline: true,
9476
- fontColor: HYPERLINK_FONT_COLOR
9477
- }));
9595
+ this.insertLink(contents, model.linkDataModel.text, model.linkDataModel.link, model.insertIndex);
9478
9596
  break;
9479
9597
  }
9480
9598
  case CommandType.InsertTableColumns: {
@@ -9634,7 +9752,7 @@ class OperationsHelper {
9634
9752
  TabOperationsHelper.insertContent(document.tabs, index);
9635
9753
  LinkOperationsHelper.insertContent(document.links, index, 1);
9636
9754
  }
9637
- static insertLink(document, text, link, index, style) {
9755
+ static insertLink(document, text, link, index) {
9638
9756
  document.content = ContentOperationsHelper.insertContent(document.content, text, index);
9639
9757
  document.contentLength = document.content.length;
9640
9758
  FormatOperationsHelper.insertContent(document.formats, index, text.length);
@@ -9644,7 +9762,13 @@ class OperationsHelper {
9644
9762
  IndexedElementOperationsHelper.insertContent(document.elements, index, text.length);
9645
9763
  IndexedElementOperationsHelper.insertContent(document.breaks, index, text.length);
9646
9764
  IndexedElementOperationsHelper.insertContent(document.tabs, index, text.length);
9647
- LinkOperationsHelper.insert(document.links, link, index, index + text.length - 1, style);
9765
+ const formatStyle = FormatStyleHelper.getFormatAtIndex(document.formats, index).textStyle;
9766
+ LinkOperationsHelper.insert(document.links, link, index, index + text.length - 1, {
9767
+ ...formatStyle,
9768
+ fontColor: HYPERLINK_FONT_COLOR,
9769
+ underline: true,
9770
+ headingStyleId: HYPERLINK_HEADING_STYLE_ID
9771
+ });
9648
9772
  }
9649
9773
  static addNumbering(target, numberings, startIndex, endIndex, levels) {
9650
9774
  const newNumberingId = NumberingOperationsHelper.generateNumberingId(numberings);
@@ -9695,11 +9819,11 @@ class OperationsHelper {
9695
9819
  IndexedElementOperationsHelper.insertContent(document.elements, index, text.length);
9696
9820
  IndexedElementOperationsHelper.insertContent(document.breaks, index, text.length);
9697
9821
  IndexedElementOperationsHelper.insertContent(document.tabs, index, text.length);
9698
- LinkOperationsHelper.insertContent(document.links, index, text.length);
9822
+ LinkOperationsHelper.insertStyledContent(document.links, index, text.length, style);
9699
9823
  }
9700
9824
  static deleteRestore(document, model) {
9701
9825
  if (model.startIndex !== model.endIndex) {
9702
- this.delete(document, model.startIndex, model.endIndex);
9826
+ this.delete(document, model.startIndex, model.endIndex - model.startIndex);
9703
9827
  }
9704
9828
  this.restore(document, model);
9705
9829
  }
@@ -9715,9 +9839,10 @@ class OperationsHelper {
9715
9839
  IndexedElementOperationsHelper.restore(document.tabs, model.startIndex, model.text.length, model.tabs);
9716
9840
  LinkOperationsHelper.restore(document.links, model.startIndex, model.text.length, model.links);
9717
9841
  }
9718
- static delete(document, startIndex, endIndex) {
9719
- document.content = ContentOperationsHelper.removeContent(document.content, startIndex, endIndex);
9842
+ static delete(document, startIndex, count) {
9843
+ document.content = ContentOperationsHelper.removeContent(document.content, startIndex, count);
9720
9844
  document.contentLength = document.content.length;
9845
+ const endIndex = startIndex + count - 1;
9721
9846
  FormatOperationsHelper.removeContent(document.formats, startIndex, endIndex);
9722
9847
  IndexedElementOperationsHelper.removeContent(document.paragraphs, startIndex, endIndex);
9723
9848
  IndexedElementOperationsHelper.removeContent(document.images, startIndex, endIndex);
@@ -9740,7 +9865,7 @@ class OperationsHelper {
9740
9865
  LinkOperationsHelper.replaceContent(document.links, startIndex, endIndex, text.length);
9741
9866
  }
9742
9867
  static replace(document, model, contentWidth) {
9743
- this.delete(document, model.delete.startIndex, model.delete.endIndex);
9868
+ this.delete(document, model.delete.startIndex, model.delete.count);
9744
9869
  if (model.insertText) {
9745
9870
  this.insertText(document, model.insertText.text, model.insertText.insertIndex);
9746
9871
  }
@@ -9764,19 +9889,16 @@ class OperationsHelper {
9764
9889
  this.insertTable(document, model.insertTable.insertIndex, model.insertTable, contentWidth);
9765
9890
  }
9766
9891
  else if (model.insertLink) {
9767
- this.insertLink(document, model.insertLink.linkDataModel.text, model.insertLink.linkDataModel.link, model.insertLink.insertIndex, new TextStyleModel({
9768
- ...DEFAULT_TEXT_STYLE,
9769
- headingStyleId: HYPERLINK_HEADING_STYLE_ID,
9770
- underline: true,
9771
- fontColor: HYPERLINK_FONT_COLOR
9772
- }));
9892
+ this.insertLink(document, model.insertLink.linkDataModel.text, model.insertLink.linkDataModel.link, model.insertLink.insertIndex);
9773
9893
  }
9774
9894
  }
9775
9895
  static applyTextStyle(document, startIndex, endIndex, style) {
9776
9896
  FormatOperationsHelper.apply(document.formats, startIndex, endIndex, style);
9897
+ LinkOperationsHelper.apply(document.links, startIndex, endIndex, style);
9777
9898
  }
9778
- static restoreTextStyles(document, textFormats) {
9899
+ static restoreTextStyles(document, textFormats, linkFormats) {
9779
9900
  FormatOperationsHelper.restoreFormats(document.formats, textFormats);
9901
+ LinkOperationsHelper.restoreFormats(document.links, linkFormats);
9780
9902
  }
9781
9903
  static restoreParagraphStyles(document, paragraphs) {
9782
9904
  ParagraphOperationsHelper.restoreParagraphs(document.paragraphs, paragraphs);
@@ -9840,6 +9962,9 @@ class EditSession {
9840
9962
  get scrollTop() {
9841
9963
  return this.scrollBar?.scrollTop ?? 0; // only main session is scrollable
9842
9964
  }
9965
+ get scrollBarHeight() {
9966
+ return this.scrollBar?.element.clientHeight ?? 0; // only main session is scrollable
9967
+ }
9843
9968
  constructor(displayData, sessionId, customContentService, model, selection, generalProperties, editorService, customComponents, type, scrollBar) {
9844
9969
  this.displayData = displayData;
9845
9970
  this.sessionId = sessionId;
@@ -9936,6 +10061,20 @@ class EditSession {
9936
10061
  const paragraphContent = this.displayData.getParagraphContent(row);
9937
10062
  return paragraphContent.substring(startColumn || 0, endColumn || paragraphContent.length);
9938
10063
  }
10064
+ isEdgeOrWithinEdge() {
10065
+ return this.isEdge() || this.isWithinEdge();
10066
+ }
10067
+ isEdge() {
10068
+ return this.type === 'edge';
10069
+ }
10070
+ isWithinEdge() {
10071
+ return this.type === 'cellWithinEdge';
10072
+ }
10073
+ onRendered() {
10074
+ if (this.isEdgeOrWithinEdge()) {
10075
+ this.editorService.changedEdge(this.sessionId);
10076
+ }
10077
+ }
9939
10078
  removeByDocumentIndexes(startIndex, endIndex) {
9940
10079
  const startParagraphPosition = ContentHelper.documentIndexToParagraphIndex(this.displayData.paragraphs, startIndex);
9941
10080
  const endParagraphPosition = ContentHelper.documentIndexToParagraphIndex(this.displayData.paragraphs, endIndex);
@@ -10041,12 +10180,12 @@ class EditSession {
10041
10180
  const start = this.displayData.indexToPosition(applyImage.insertIndex, 0);
10042
10181
  this.displayData.updateNextLineIndexes(start.row, this.displayData.paragraphs.length - 1);
10043
10182
  }
10044
- restoreTextStyles(formats) {
10183
+ restoreTextStyles(formats, linkFormats) {
10045
10184
  const startIndex = formats[0].startIndex;
10046
10185
  const endIndex = formats[formats.length - 1].endIndex;
10047
10186
  const startParagraph = ContentHelper.documentIndexToParagraphIndex(this.displayData.paragraphs, startIndex).row;
10048
10187
  const endPosition = ContentHelper.documentIndexToParagraphWithOffset(this.displayData.paragraphs, endIndex);
10049
- OperationsHelper.restoreTextStyles(this.model, formats);
10188
+ OperationsHelper.restoreTextStyles(this.model, formats, linkFormats);
10050
10189
  this.displayData.updateNextLineIndexes(startParagraph, endPosition.row);
10051
10190
  this.selection.placeCursor(endPosition);
10052
10191
  this.applyToolbarStyles();
@@ -10079,7 +10218,7 @@ class EditSession {
10079
10218
  CustomComponentHelper.applyRemovingComponents(this.customComponents.images, partIndexes.startIndex, partIndexes.endIndex);
10080
10219
  CustomComponentHelper.applyRemovingComponents(this.customComponents.customElements, partIndexes.startIndex, partIndexes.endIndex);
10081
10220
  CustomComponentHelper.applyRemovingComponents(this.customComponents.tabs, partIndexes.startIndex, partIndexes.endIndex);
10082
- OperationsHelper.delete(this.model, partIndexes.startIndex, partIndexes.endIndex);
10221
+ OperationsHelper.delete(this.model, partIndexes.startIndex, partIndexes.endIndex - partIndexes.startIndex + 1);
10083
10222
  this.selection.placeCursor(range.start);
10084
10223
  this.displayData.resetAllNumberingInfo(range.start.row);
10085
10224
  this.displayData.updateNextLineIndexes(range.start.row, range.start.row);
@@ -10089,7 +10228,7 @@ class EditSession {
10089
10228
  this.applyToolbarStyles();
10090
10229
  }
10091
10230
  replace(model) {
10092
- this.removeByDocumentIndexes(model.delete.startIndex, model.delete.endIndex + 1);
10231
+ this.removeByDocumentIndexes(model.delete.startIndex, model.delete.startIndex + model.delete.count);
10093
10232
  let endPoint;
10094
10233
  if (model.insertText) {
10095
10234
  endPoint = this.insertTextByDocumentIndex(model.insertText.insertIndex, model.insertText.text);
@@ -10183,13 +10322,7 @@ class EditSession {
10183
10322
  }
10184
10323
  insertLink(position, linkData) {
10185
10324
  const insertIndex = ContentHelper.paragraphPositionToDocumentIndex(this.displayData.paragraphs, position);
10186
- const linkStyle = new TextStyleModel({
10187
- ...DEFAULT_TEXT_STYLE,
10188
- headingStyleId: HYPERLINK_HEADING_STYLE_ID,
10189
- underline: true,
10190
- fontColor: HYPERLINK_FONT_COLOR
10191
- });
10192
- OperationsHelper.insertLink(this.model, linkData.text, linkData.link, insertIndex, linkStyle);
10325
+ OperationsHelper.insertLink(this.model, linkData.text, linkData.link, insertIndex);
10193
10326
  const endPosition = this.displayData.insertText(position, linkData.text);
10194
10327
  this.displayData.updateNextLineIndexes(position.row, position.row);
10195
10328
  this.selection.placeCursor(endPosition);
@@ -10297,7 +10430,7 @@ class EditSession {
10297
10430
  }
10298
10431
  getStyleForCursor(index) {
10299
10432
  const link = this.model.links.find(x => x.startIndex <= index && x.endIndex > index);
10300
- if (link) {
10433
+ if (link && !this.displayData.paragraphs.some(x => x.startIndex === index)) {
10301
10434
  const indexInLink = index - link.startIndex;
10302
10435
  const linkFormat = link.formats.find(x => x.startIndex <= indexInLink && x.endIndex >= indexInLink);
10303
10436
  return [linkFormat.textStyle];
@@ -10350,7 +10483,7 @@ class EditSession {
10350
10483
  }
10351
10484
  getLinkModel(cursor) {
10352
10485
  const index = ContentHelper.paragraphPositionToDocumentIndex(this.displayData.paragraphs, cursor);
10353
- return this.model.links.find(x => x.startIndex <= index && x.endIndex > index);
10486
+ return this.model.links.find(x => x.startIndex <= index && x.endIndex >= index);
10354
10487
  }
10355
10488
  insertTableRows(insertIndex, rowsCount, targetIndex, inheritIndex) {
10356
10489
  const table = this.customComponents.tables.find(x => x.instance.insertIndex === insertIndex);
@@ -10402,7 +10535,7 @@ class GeneralPropertiesModel {
10402
10535
 
10403
10536
  class MainSessionSourceModel {
10404
10537
  getTarget() {
10405
- return new TargetModel({ type: TargetType.Document, edgeEditPage: null });
10538
+ return new TargetModel({ type: TargetType.Document });
10406
10539
  }
10407
10540
  }
10408
10541
 
@@ -10503,6 +10636,31 @@ class CursorLayer {
10503
10636
  }
10504
10637
  }
10505
10638
 
10639
+ class RenderChangesModel {
10640
+ get any() {
10641
+ return this.cursor || this.full || this.lines || this.marker || this.selection || this.scroll || this.size || this.text;
10642
+ }
10643
+ constructor(fields) {
10644
+ this.cursor = false;
10645
+ this.full = false;
10646
+ this.lines = false;
10647
+ this.marker = false;
10648
+ this.selection = false;
10649
+ this.scroll = false;
10650
+ this.size = false;
10651
+ this.text = false;
10652
+ if (!fields) {
10653
+ return;
10654
+ }
10655
+ Object.assign(this, fields);
10656
+ }
10657
+ apply(changes) {
10658
+ for (let key of Object.keys(this)) {
10659
+ this[key] ||= changes[key];
10660
+ }
10661
+ }
10662
+ }
10663
+
10506
10664
  class EventHelper {
10507
10665
  static get nextFrame() {
10508
10666
  if (!this._nextFrame) {
@@ -10662,9 +10820,8 @@ class SelectionLayer {
10662
10820
  }
10663
10821
 
10664
10822
  class Renderer extends EventEmitting {
10665
- constructor(parentContainer, editorService, session) {
10823
+ constructor(parentContainer, session) {
10666
10824
  super();
10667
- this.editorService = editorService;
10668
10825
  this.session = session;
10669
10826
  this.layerConfig = {
10670
10827
  width: 1,
@@ -10697,7 +10854,7 @@ class Renderer extends EventEmitting {
10697
10854
  this.container = parentContainer;
10698
10855
  this.container.className += ' noder-editor';
10699
10856
  this.createContentContainer();
10700
- this.textLayer = new TextLayer(this.content, this.session, this.editorService);
10857
+ this.textLayer = new TextLayer(this.content, this.session);
10701
10858
  this.selectionLayer = new SelectionLayer(this.content, 'text-selection', this.session);
10702
10859
  this.cursorLayer = new CursorLayer(this.content, this.session);
10703
10860
  this.loop = new RenderLoop(changes => this.renderChanges(changes));
@@ -10720,7 +10877,6 @@ class Renderer extends EventEmitting {
10720
10877
  // full
10721
10878
  if (changes.full) {
10722
10879
  this.renderFull();
10723
- this.editorService.rendererUpdated(this.session.sessionId);
10724
10880
  return;
10725
10881
  }
10726
10882
  if (changes.text || changes.scroll) {
@@ -10732,7 +10888,7 @@ class Renderer extends EventEmitting {
10732
10888
  if (changes.marker || changes.selection) {
10733
10889
  this.renderSelection();
10734
10890
  }
10735
- this.editorService.rendererUpdated(this.session.sessionId);
10891
+ this.session.onRendered();
10736
10892
  }
10737
10893
  /**
10738
10894
  * Triggers a partial update of the text, from the range given by the two parameters.
@@ -10747,7 +10903,7 @@ class Renderer extends EventEmitting {
10747
10903
  this.loop.schedule({ lines: true });
10748
10904
  }
10749
10905
  moveTextAreaToCursor() {
10750
- if (this.isMousePressed || !this.textarea) {
10906
+ if (!this.textarea) {
10751
10907
  return;
10752
10908
  }
10753
10909
  let cursorPosition = this.cursorLayer.cursorPosition;
@@ -10779,32 +10935,32 @@ class Renderer extends EventEmitting {
10779
10935
  updateText() {
10780
10936
  this.loop.schedule({ text: true });
10781
10937
  }
10782
- /**
10783
- * Triggers a full update of all the layers, for all the rows.
10784
- **/
10785
- updateFull(force) {
10786
- if (force) {
10787
- this.renderChanges(new RenderChangesModel({ full: true }), true);
10788
- return;
10789
- }
10790
- this.loop.schedule({ full: true });
10791
- }
10792
10938
  updateCursor() {
10793
10939
  this.loop.schedule({ cursor: true });
10794
10940
  }
10795
- screenToTextCoordinates(x, y) {
10796
- const screen = PositionHelper.pixelToScreen(this.session, x, y, this.container.getBoundingClientRect());
10797
- return PositionHelper.screenToDocument(this.session, screen.row, screen.column);
10941
+ /**
10942
+ * Converts screen coordinates to text coordinates by mapping to the closest token midpoint.
10943
+ */
10944
+ screenToTextCoordinatesUsingMidpoint(x, y, rect) {
10945
+ const { left, top } = rect ?? this.container.getBoundingClientRect();
10946
+ const { paragraphIndex, lineIndex } = PositionHelper.getParagraphAndLineIndexFromYPosition(this.session, y, top);
10947
+ const { line, indexInLine } = PositionHelper.mapPixelToClosestTokenMidpoint(this.session, x, paragraphIndex, lineIndex, left);
10948
+ return PositionHelper.screenToDocument(this.session, line, indexInLine);
10949
+ }
10950
+ /**
10951
+ * Converts screen coordinates to text coordinates by mapping to the next token boundary.
10952
+ */
10953
+ screenToTextCoordinatesUsingBoundary(x, y, rect) {
10954
+ const { left, top } = rect ?? this.container.getBoundingClientRect();
10955
+ const { paragraphIndex, lineIndex } = PositionHelper.getParagraphAndLineIndexFromYPosition(this.session, y, top);
10956
+ const { line, indexInLine } = PositionHelper.mapPixelToNextTokenBoundary(this.session, x, paragraphIndex, lineIndex, left);
10957
+ return PositionHelper.screenToDocument(this.session, line, indexInLine);
10798
10958
  }
10799
10959
  showCursor() {
10800
10960
  this.cursorLayer.showCursor();
10801
- DomHelper.addCssClass(this.container, 'ace_focus');
10802
- this.editorService.rendererUpdated(this.session.sessionId);
10803
10961
  }
10804
10962
  hideCursor() {
10805
10963
  this.cursorLayer.hideCursor();
10806
- DomHelper.removeCssClass(this.container, 'ace_focus');
10807
- this.editorService.rendererUpdated(this.session.sessionId);
10808
10964
  }
10809
10965
  destroy() {
10810
10966
  this.session.displayData.removeEventListener('pagesCountChanged', this.pagesCountChangedHandler);
@@ -10816,6 +10972,7 @@ class Renderer extends EventEmitting {
10816
10972
  this.selectionLayer.update(this.layerConfig);
10817
10973
  this.cursorLayer.update(this.layerConfig);
10818
10974
  this.moveTextAreaToCursor();
10975
+ this.session.onRendered();
10819
10976
  }
10820
10977
  renderText() {
10821
10978
  this.textLayer.updateLines(this.layerConfig);
@@ -10834,7 +10991,6 @@ class Renderer extends EventEmitting {
10834
10991
  const maxHeight = displayData.allPagesHeight;
10835
10992
  const minHeight = displayData.minHeight;
10836
10993
  const changes = new RenderChangesModel({ scroll: true });
10837
- // todo check logic after move wrapdata to display data
10838
10994
  this.layerConfig = {
10839
10995
  width: this.session.displayData.contentWidth + displayData.pageMargin.left + displayData.pageMargin.right,
10840
10996
  height: displayData.defaultVerticalData.contentHeight,
@@ -10949,12 +11105,6 @@ class SessionModel {
10949
11105
  }
10950
11106
 
10951
11107
  class VirtualRenderer {
10952
- get isMousePressed() {
10953
- return this.renderer.isMousePressed;
10954
- }
10955
- set isMousePressed(val) {
10956
- this.renderer.isMousePressed = val;
10957
- }
10958
11108
  get cursorLayer() {
10959
11109
  return this.renderer.cursorLayer;
10960
11110
  }
@@ -10976,7 +11126,7 @@ class VirtualRenderer {
10976
11126
  set layerConfig(val) {
10977
11127
  this.renderer.layerConfig = val;
10978
11128
  }
10979
- constructor(parentContainer, editorService, mainSession, scrollBar) {
11129
+ constructor(parentContainer, mainSession, scrollBar) {
10980
11130
  this.scrollBar = scrollBar;
10981
11131
  this.changes = new RenderChangesModel();
10982
11132
  this.size = {
@@ -10988,8 +11138,7 @@ class VirtualRenderer {
10988
11138
  };
10989
11139
  this.container = parentContainer;
10990
11140
  this.createScroller();
10991
- this.renderer = new Renderer(parentContainer, editorService, mainSession);
10992
- this.renderer.layerConfig = this.getDefaultLayerConfig();
11141
+ this.renderer = new Renderer(parentContainer, mainSession);
10993
11142
  this.pagesLayer = new PagesLayer(this.renderer.content, mainSession);
10994
11143
  this.scrollSubscription = this.scrollBar.scrolled$.subscribe(() => this.loop.schedule({ scroll: true }));
10995
11144
  this.createRenderLoop();
@@ -11075,7 +11224,7 @@ class VirtualRenderer {
11075
11224
  return changes;
11076
11225
  }
11077
11226
  moveTextAreaToCursor() {
11078
- if (this.isMousePressed || !this.textarea) {
11227
+ if (!this.textarea) {
11079
11228
  return;
11080
11229
  }
11081
11230
  let cursorPosition = this.cursorLayer.cursorPosition;
@@ -11100,12 +11249,6 @@ class VirtualRenderer {
11100
11249
  updateText() {
11101
11250
  this.renderer.updateText();
11102
11251
  }
11103
- /**
11104
- * Triggers a full update of all the layers, for all the rows.
11105
- **/
11106
- updateFull(force) {
11107
- this.renderer.updateFull(force);
11108
- }
11109
11252
  updateCursor() {
11110
11253
  this.renderer.updateCursor();
11111
11254
  }
@@ -11147,8 +11290,11 @@ class VirtualRenderer {
11147
11290
  this.scrollBar.setScrollTop(scrollTop);
11148
11291
  this.loop.schedule({ scroll: true });
11149
11292
  }
11150
- screenToTextCoordinates(x, y) {
11151
- return this.renderer.screenToTextCoordinates(x, y);
11293
+ screenToTextCoordinatesUsingMidpoint(x, y, rect) {
11294
+ return this.renderer.screenToTextCoordinatesUsingMidpoint(x, y, rect);
11295
+ }
11296
+ screenToTextCoordinatesUsingBoundary(x, y, rect) {
11297
+ return this.renderer.screenToTextCoordinatesUsingBoundary(x, y, rect);
11152
11298
  }
11153
11299
  showCursor() {
11154
11300
  this.renderer.showCursor();
@@ -11205,12 +11351,11 @@ class VirtualRenderer {
11205
11351
  }
11206
11352
  renderScroll(changes) {
11207
11353
  this.pagesLayer.update(this.layerConfig);
11354
+ this.renderer.textLayer.scrollEdges(this.layerConfig);
11208
11355
  if (changes.text || changes.lines) {
11209
- this.renderer.textLayer.updateEdges(this.layerConfig);
11210
11356
  this.renderer.textLayer.updateLines(this.layerConfig);
11211
11357
  }
11212
11358
  else {
11213
- this.renderer.textLayer.scrollPages(this.layerConfig);
11214
11359
  this.renderer.textLayer.scrollLines(this.layerConfig);
11215
11360
  }
11216
11361
  this.renderer.selectionLayer.update(this.layerConfig);
@@ -11235,28 +11380,6 @@ class VirtualRenderer {
11235
11380
  renderSelection() {
11236
11381
  this.renderer.renderSelection();
11237
11382
  }
11238
- getDefaultLayerConfig() {
11239
- return {
11240
- width: 1,
11241
- contentRange: new DistanceModel({ start: 0, end: 0 }),
11242
- minHeight: 1,
11243
- maxHeight: 1,
11244
- offset: 0,
11245
- height: 1,
11246
- scrollTop: 0,
11247
- pages: [],
11248
- visibleRange: {
11249
- startParagraph: 0,
11250
- startLine: 0,
11251
- startScreenLine: 0,
11252
- startScreenFullLine: 0,
11253
- endParagraph: 0,
11254
- endLine: 0,
11255
- endScreenLine: 0,
11256
- endScreenFullLine: 0
11257
- }
11258
- };
11259
- }
11260
11383
  }
11261
11384
 
11262
11385
  class CustomContentService {
@@ -11385,7 +11508,6 @@ class RegulatorService {
11385
11508
  this.componentService = componentService;
11386
11509
  this.sessions = [];
11387
11510
  this.sessionIdIncrement = 0;
11388
- this.edgeEditingPage = null;
11389
11511
  }
11390
11512
  addMainSession(model, pageWidth, scalingRatio, container) {
11391
11513
  const sessionId = ++this.sessionIdIncrement;
@@ -11411,25 +11533,26 @@ class RegulatorService {
11411
11533
  const displayData = new DisplayData(model, properties, sessionId, pageMargin, DocumentInfo.pagesSpace, pageWidth, model.pageHeight, customComponents, this.customContentService, this.editorService);
11412
11534
  const scrollBar = new ScrollBar(container.nativeElement.parentElement);
11413
11535
  const mainSession = new EditSession(displayData, sessionId, this.customContentService, model, this.selection, properties, this.editorService, customComponents, 'main', scrollBar);
11414
- displayData.updateNextLineIndexes(0, displayData.paragraphs.length - 1);
11415
- const virtualRenderer = new VirtualRenderer(container.nativeElement, this.editorService, mainSession, scrollBar);
11536
+ const virtualRenderer = new VirtualRenderer(container.nativeElement, mainSession, scrollBar);
11416
11537
  this.editorService.styles = DEFAULT_TOOLBAR_STYLES();
11417
11538
  this.mainSession = new SessionModel(mainSession, virtualRenderer, sessionId, null, new MainSessionSourceModel());
11418
11539
  this.sessions.push(this.mainSession);
11419
11540
  this.currentSession = this.mainSession;
11541
+ displayData.updateNextLineIndexes(0, displayData.paragraphs.length - 1);
11420
11542
  }
11421
11543
  addCellSession(table, margins, component, properties) {
11422
11544
  const sessionId = ++this.sessionIdIncrement;
11423
11545
  const customComponents = { images: [], tables: [], tabs: [], customElements: [], edges: null };
11424
11546
  const displayData = new DisplayData(component.cell, properties, sessionId, margins, 0, component.width, 0, customComponents, this.customContentService, this.editorService);
11425
- const session = new EditSession(displayData, sessionId, this.customContentService, component.cell, this.selection, properties, this.editorService, customComponents, 'cell');
11547
+ const sessionType = this.isWithinEdge(component.parentSessionId) ? 'cellWithinEdge' : 'cell';
11548
+ const session = new EditSession(displayData, sessionId, this.customContentService, component.cell, this.selection, properties, this.editorService, customComponents, sessionType);
11426
11549
  displayData.contentWidth = displayData.contentWidth === 0 ? 1 : displayData.contentWidth;
11427
- displayData.updateNextLineIndexes(0, displayData.paragraphs.length - 1);
11428
- const renderer = new Renderer(component.container.nativeElement, this.editorService, session);
11550
+ const renderer = new Renderer(component.container.nativeElement, session);
11429
11551
  const source = new CellSessionSourceModel(table, component);
11430
11552
  const newSession = new SessionModel(session, renderer, sessionId, component.parentSessionId, source);
11431
- newSession.renderer.updateText();
11432
11553
  this.sessions.push(newSession);
11554
+ displayData.updateNextLineIndexes(0, displayData.paragraphs.length - 1);
11555
+ newSession.renderer.updateText();
11433
11556
  return newSession;
11434
11557
  }
11435
11558
  addEdgeSession(component) {
@@ -11437,11 +11560,12 @@ class RegulatorService {
11437
11560
  const customComponents = { images: [], tables: [], tabs: [], customElements: [], edges: null };
11438
11561
  const displayData = new DisplayData(component.model, component.generalProperties, sessionId, component.margins, 0, component.width, 0, customComponents, this.customContentService, this.editorService);
11439
11562
  const session = new EditSession(displayData, sessionId, this.customContentService, component.model, this.selection, component.generalProperties, this.editorService, customComponents, 'edge');
11440
- displayData.updateNextLineIndexes(0, displayData.paragraphs.length - 1);
11441
- const renderer = new Renderer(component.container.nativeElement, this.editorService, session);
11563
+ const renderer = new Renderer(component.container.nativeElement, session);
11442
11564
  const source = new EdgeSessionSourceModel(component.model.pageType, component.type);
11443
11565
  const newSession = new SessionModel(session, renderer, sessionId, component.parentSessionId, source);
11444
11566
  this.sessions.push(newSession);
11567
+ displayData.updateNextLineIndexes(0, displayData.paragraphs.length - 1);
11568
+ newSession.renderer.updateText();
11445
11569
  return newSession;
11446
11570
  }
11447
11571
  removeSession(sessionId) {
@@ -11454,16 +11578,12 @@ class RegulatorService {
11454
11578
  if (this.mainSession.sessionId === this.currentSession.sessionId) {
11455
11579
  return;
11456
11580
  }
11457
- this.toggleEdgeEditMode();
11458
11581
  this.setCurrentSession(this.mainSession);
11459
11582
  }
11460
- setCustomSessionAsCurrent(sessionId, edgeEditingPage = null) {
11461
- if (sessionId === this.currentSession.sessionId && this.currentSession.source.edgeEditPage !== edgeEditingPage) {
11462
- this.currentSession.source.edgeEditPage = edgeEditingPage;
11463
- this.mainSession.renderer.renderer.textLayer.edgeEditingPageUpdated(edgeEditingPage);
11583
+ setCustomSessionAsCurrent(sessionId) {
11584
+ if (sessionId === this.currentSession.sessionId) {
11464
11585
  return;
11465
11586
  }
11466
- this.toggleEdgeEditMode(edgeEditingPage);
11467
11587
  this.setCurrentSessionById(sessionId);
11468
11588
  }
11469
11589
  setTargetedSessionAsCurrent(targets) {
@@ -11472,8 +11592,6 @@ class RegulatorService {
11472
11592
  return;
11473
11593
  }
11474
11594
  const session = this.sessions.find(x => x.sessionId === targetedSession.sessionId);
11475
- const edgeEditPage = targets.length ? targets[targets.length - 1].edgeEditPage : null;
11476
- this.toggleEdgeEditMode(edgeEditPage);
11477
11595
  this.setCurrentSession(session);
11478
11596
  }
11479
11597
  setCurrentSessionById(sessionId) {
@@ -11481,16 +11599,19 @@ class RegulatorService {
11481
11599
  this.setCurrentSession(this.sessions[index]);
11482
11600
  }
11483
11601
  setCurrentSession(session) {
11602
+ const previous = this.currentSession;
11484
11603
  this.selection.clearSelection();
11485
11604
  this.currentSession.renderer.hideCursor();
11486
11605
  this.currentSession.renderer.updateSelection(this.selection.range);
11487
11606
  this.currentSession = session;
11488
11607
  this.currentSession.renderer.showCursor();
11489
- this.currentSession.source.edgeEditPage = this.edgeEditingPage;
11608
+ this.arrangeEdgesForSessionChange(previous.session, session.session);
11609
+ }
11610
+ getSessionModel(sessionId) {
11611
+ return this.sessions.find(x => x.sessionId === sessionId);
11490
11612
  }
11491
11613
  getSession(sessionId) {
11492
- const session = this.sessions.find(x => x.sessionId === sessionId);
11493
- return session.session;
11614
+ return this.getSessionModel(sessionId).session;
11494
11615
  }
11495
11616
  setSelection(selection) {
11496
11617
  this.selection = selection;
@@ -11516,19 +11637,6 @@ class RegulatorService {
11516
11637
  }
11517
11638
  return result;
11518
11639
  }
11519
- getEdgeTarget(sessionId) {
11520
- let session = this.sessions.find(x => x.sessionId === sessionId);
11521
- let parentSession = this.sessions.find(x => x.sessionId === session.parentSessionId);
11522
- while (parentSession) {
11523
- const target = session.source.getTarget();
11524
- if (target.type === TargetType.Edge) {
11525
- return target;
11526
- }
11527
- session = parentSession;
11528
- parentSession = this.sessions.find(x => x.sessionId === parentSession.parentSessionId);
11529
- }
11530
- return null;
11531
- }
11532
11640
  getTargetedSession(targets) {
11533
11641
  let result = this.mainSession.session;
11534
11642
  for (const target of targets) {
@@ -11549,13 +11657,33 @@ class RegulatorService {
11549
11657
  }
11550
11658
  return result;
11551
11659
  }
11552
- toggleEdgeEditMode(edgeEditingPage = null) {
11553
- if (!this.mainSession.session.customComponents.edges || this.edgeEditingPage === edgeEditingPage) {
11660
+ isWithinEdge(sessionId) {
11661
+ return !!this.getEdgeSessionId(sessionId);
11662
+ }
11663
+ arrangeEdgeChange(sessionId) {
11664
+ const edgeSessionId = this.getEdgeSessionId(sessionId);
11665
+ const { type, pageType } = this.mainSession.session.customComponents.edges.getTypeBySessionId(edgeSessionId);
11666
+ this.mainSession.renderer.renderer.textLayer.updateEdge(type, pageType);
11667
+ }
11668
+ getEdgeSessionId(sessionId) {
11669
+ let session = this.getSession(sessionId);
11670
+ while (session && !session.isEdge()) {
11671
+ const model = this.sessions.find(x => x.sessionId === session.sessionId);
11672
+ session = model.parentSessionId ? this.getSession(model.parentSessionId) : null;
11673
+ }
11674
+ return session?.sessionId;
11675
+ }
11676
+ arrangeEdgesForSessionChange(previous, current) {
11677
+ const isPreviousEdge = previous.isEdgeOrWithinEdge();
11678
+ const isCurrentEdge = current.isEdgeOrWithinEdge();
11679
+ if (isPreviousEdge !== isCurrentEdge) {
11680
+ this.mainSession.session.customComponents.edges.toggleEditMode(isCurrentEdge);
11554
11681
  return;
11555
11682
  }
11556
- this.edgeEditingPage = edgeEditingPage;
11557
- this.mainSession.session.customComponents.edges.toggleEditMode(!!this.edgeEditingPage);
11558
- this.mainSession.renderer.renderer.textLayer.edgeEditingPageUpdated(edgeEditingPage);
11683
+ if (isPreviousEdge) {
11684
+ previous.onRendered();
11685
+ current.onRendered();
11686
+ }
11559
11687
  }
11560
11688
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: RegulatorService, deps: [{ token: CustomContentService }, { token: EditorService }, { token: ComponentService }], target: i0.ɵɵFactoryTarget.Injectable }); }
11561
11689
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: RegulatorService }); }
@@ -13540,7 +13668,6 @@ class MenuDropdownsComponent extends BaseToolbarComponent {
13540
13668
  this.showLayout = true;
13541
13669
  this.showFormat = true;
13542
13670
  this.openFileFromDisk = new EventEmitter();
13543
- this.addCustomElement = new EventEmitter();
13544
13671
  this.saveAs = new EventEmitter();
13545
13672
  this.insertPageBreak = new EventEmitter();
13546
13673
  this.createDocument = new EventEmitter();
@@ -13577,7 +13704,7 @@ class MenuDropdownsComponent extends BaseToolbarComponent {
13577
13704
  });
13578
13705
  }
13579
13706
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MenuDropdownsComponent, deps: [{ token: CustomIconService }, { token: i0.Injector }, { token: i0.ChangeDetectorRef }, { token: EditorService }], target: i0.ɵɵFactoryTarget.Component }); }
13580
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: MenuDropdownsComponent, selector: "app-nod-menu-dropdowns", inputs: { showFile: "showFile", showEdit: "showEdit", showInsert: "showInsert", showLayout: "showLayout", showFormat: "showFormat" }, outputs: { openFileFromDisk: "openFileFromDisk", addCustomElement: "addCustomElement", saveAs: "saveAs", insertPageBreak: "insertPageBreak", createDocument: "createDocument", rename: "rename", delete: "delete", openEditMenu: "openEditMenu", cutSelected: "cutSelected", copySelected: "copySelected", pasteClipboardData: "pasteClipboardData", selectAll: "selectAll", removeSelected: "removeSelected" }, viewQueries: [{ propertyName: "tableInsertMenu", first: true, predicate: ["tableInsert"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<ng-container\n *ngIf=\"{\n clipboardData: editorService.clipboardData$ | async,\n hasSelection: editorService.hasSelection$ | async,\n isViewOnly: editorService.isViewOnly$ | async\n } as data\">\n <button\n *ngIf=\"showFile\"\n id=\"menu-dropdowns-menu-file\"\n mat-button\n [matMenuTriggerFor]=\"fileMenu\"\n [matMenuTriggerRestoreFocus]=\"false\">\n File\n </button>\n <mat-menu\n #fileMenu=\"matMenu\"\n class=\"noder-modal\">\n <button\n *ngIf=\"createDocument.observed && !data.isViewOnly\"\n id=\"menu-dropdowns-menu-item-new\"\n mat-menu-item\n (click)=\"createDocument.emit()\">\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-add-new\"></mat-icon>\n <span class=\"menu-item-text\">New</span>\n </div>\n </button>\n <button\n *ngIf=\"openFileFromDisk.observed && !data.isViewOnly\"\n id=\"menu-dropdowns-menu-item-open-from\"\n mat-menu-item\n (click)=\"openFileFromDisk.emit()\">\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-open-from\"></mat-icon>\n <span class=\"menu-item-text\">Open From</span>\n <span class=\"hot-keys\">Ctrl+O</span>\n </div>\n </button>\n <button\n *ngIf=\"saveAs.observed\"\n id=\"menu-dropdowns-menu-item-save-as\"\n mat-menu-item\n (click)=\"saveAs.emit()\">\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-save\"></mat-icon>\n <span class=\"menu-item-text\">Save As</span>\n </div>\n </button>\n <button\n *ngIf=\"rename.observed\"\n id=\"menu-dropdowns-menu-item-rename\"\n mat-menu-item\n (click)=\"rename.emit()\">\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-rename\"></mat-icon>\n <span class=\"menu-item-text\">Rename</span>\n </div>\n </button>\n <button\n *ngIf=\"print.observed\"\n id=\"menu-dropdowns-menu-item-print\"\n mat-menu-item\n (click)=\"print.emit()\">\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-print\"></mat-icon>\n <span class=\"menu-item-text\">Print</span>\n <span class=\"hot-keys\">Ctrl+P</span>\n </div>\n </button>\n <button\n *ngIf=\"delete.observed\"\n id=\"menu-dropdowns-menu-item-delete\"\n mat-menu-item\n (click)=\"delete.emit()\">\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-delete\"></mat-icon>\n <span class=\"menu-item-text\">Delete</span>\n </div>\n </button>\n </mat-menu>\n <button\n *ngIf=\"showEdit\"\n id=\"menu-dropdowns-menu-edit\"\n mat-button\n [matMenuTriggerFor]=\"editMenu\"\n [matMenuTriggerRestoreFocus]=\"false\"\n (menuOpened)=\"openEditMenu.emit()\">\n Edit\n </button>\n <mat-menu\n #editMenu=\"matMenu\"\n class=\"noder-modal\">\n <button\n *ngIf=\"undo.observed\"\n id=\"menu-dropdowns-menu-item-undo\"\n mat-menu-item\n [disabled]=\"!canUndo\"\n (click)=\"undo.emit()\">\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-undo\"></mat-icon>\n <span class=\"menu-item-text\">Undo</span>\n <span class=\"hot-keys\">Ctrl+Z</span>\n </div>\n </button>\n <button\n *ngIf=\"redo.observed\"\n id=\"menu-dropdowns-menu-item-redo\"\n mat-menu-item\n [disabled]=\"!canRedo\"\n (click)=\"redo.emit()\">\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-redo\"></mat-icon>\n <span class=\"menu-item-text\">Redo</span>\n <span class=\"hot-keys\">Ctrl+Y</span>\n </div>\n </button>\n <hr class=\"noder-divider\" />\n <button\n *ngIf=\"cutSelected.observed\"\n id=\"menu-dropdowns-menu-item-cut\"\n mat-menu-item\n [disabled]=\"!data.hasSelection\"\n (click)=\"cutSelected.emit()\">\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-content-cut\"></mat-icon>\n <span class=\"menu-item-text\">Cut</span>\n <span class=\"hot-keys\">Ctrl+X</span>\n </div>\n </button>\n <button\n *ngIf=\"copySelected.observed\"\n id=\"menu-dropdowns-menu-item-copy\"\n mat-menu-item\n [disabled]=\"!data.hasSelection\"\n (click)=\"copySelected.emit()\">\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-file-copy\"></mat-icon>\n <span class=\"menu-item-text\">Copy</span>\n <span class=\"hot-keys\">Ctrl+C</span>\n </div>\n </button>\n <button\n *ngIf=\"pasteClipboardData.observed\"\n id=\"menu-dropdowns-menu-item-paste\"\n mat-menu-item\n [disabled]=\"!data.clipboardData?.length\"\n (click)=\"pasteClipboardData.emit()\">\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-content-paste\"></mat-icon>\n <span class=\"menu-item-text\">Paste</span>\n <span class=\"hot-keys\">Ctrl+V</span>\n </div>\n </button>\n <hr class=\"noder-divider\" />\n <button\n *ngIf=\"selectAll.observed\"\n id=\"menu-dropdowns-menu-item-select-all\"\n mat-menu-item\n (click)=\"selectAll.emit()\">\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-select-all\"></mat-icon>\n <span class=\"menu-item-text\">Select All</span>\n <span class=\"hot-keys\">Ctrl+A</span>\n </div>\n </button>\n <button\n *ngIf=\"removeSelected.observed\"\n id=\"menu-dropdowns-menu-item-delete-text\"\n mat-menu-item\n [disabled]=\"!data.hasSelection\"\n (click)=\"removeSelected.emit()\">\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-delete\"></mat-icon>\n <span class=\"menu-item-text\">Delete</span>\n </div>\n </button>\n </mat-menu>\n <button\n *ngIf=\"showInsert && !data.isViewOnly\"\n #insertMenuTrigger=\"matMenuTrigger\"\n id=\"menu-dropdowns-menu-insert\"\n mat-button\n [matMenuTriggerFor]=\"insertMenu\"\n [matMenuTriggerRestoreFocus]=\"false\">\n Insert\n </button>\n <mat-menu\n #insertMenu=\"matMenu\"\n class=\"noder-modal\">\n <button\n *ngIf=\"insertImage.observed\"\n id=\"menu-dropdowns-menu-item-image\"\n mat-menu-item\n (click)=\"insertImage.emit()\">\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-image\"></mat-icon>\n <span class=\"menu-item-text\">Image</span>\n </div>\n </button>\n <button\n id=\"menu-dropdowns-menu-item-table\"\n mat-menu-item\n [matMenuTriggerFor]=\"tableInsert\"\n (menuOpened)=\"showInsertTableMenu = true\"\n (menuClosed)=\"onTableInsertMenuClosed()\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-table\"></mat-icon>\n Table\n </button>\n <hr class=\"noder-divider\" />\n <button\n *ngIf=\"insertLink.observed\"\n id=\"menu-dropdowns-menu-item-link\"\n mat-menu-item\n (click)=\"insertLink.emit()\">\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-link-on\"></mat-icon>\n <span class=\"menu-item-text\">Link</span>\n <span class=\"hot-keys\">Ctrl+K</span>\n </div>\n </button>\n <button\n *ngFor=\"let element of elements\"\n id=\"menu-dropdowns-menu-item-{{ element.title }}\"\n mat-menu-item\n (click)=\"onCreateElement(element)\">\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"{{ element.icon }}\"></mat-icon>\n <span class=\"menu-item-text\">{{ element.name }}</span>\n </div>\n </button>\n <button\n id=\"menu-dropdowns-menu-item-headers-footers\"\n mat-menu-item\n class=\"hidden\"\n [matMenuTriggerFor]=\"listHeadersFootersMenu\">\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-headers-footers\"></mat-icon>\n <span class=\"menu-item-text\">Headers & Footers</span>\n </div>\n </button>\n <mat-menu\n #listHeadersFootersMenu=\"matMenu\"\n class=\"noder-modal\">\n <button\n id=\"menu-dropdowns-menu-item-header\"\n mat-menu-item>\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-header\"></mat-icon>\n <span class=\"menu-item-text\">Header</span>\n </div>\n </button>\n <button\n id=\"menu-dropdowns-menu-item-footer\"\n mat-menu-item>\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-bottom\"></mat-icon>\n <span class=\"menu-item-text\">Footer</span>\n </div>\n </button>\n </mat-menu>\n </mat-menu>\n <button\n *ngIf=\"showLayout && !data.isViewOnly\"\n id=\"menu-dropdowns-menu-layout\"\n mat-button\n [matMenuTriggerFor]=\"layoutMenu\"\n [matMenuTriggerRestoreFocus]=\"false\">\n Layout\n </button>\n <mat-menu\n #layoutMenu=\"matMenu\"\n class=\"noder-modal\">\n <button\n *ngIf=\"insertPageBreak.observed\"\n id=\"menu-dropdowns-menu-item-page-break\"\n mat-menu-item\n (click)=\"insertPageBreak.emit()\">\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-page-break\"></mat-icon>\n <span class=\"menu-item-text\">Page Break</span>\n <span class=\"hot-keys\">Ctrl+Enter</span>\n </div>\n </button>\n </mat-menu>\n <button\n *ngIf=\"showFormat && !data.isViewOnly\"\n id=\"menu-dropdowns-menu-format\"\n mat-button\n [matMenuTriggerFor]=\"formatMenu\"\n [matMenuTriggerRestoreFocus]=\"false\">\n Format\n </button>\n <mat-menu\n #formatMenu=\"matMenu\"\n class=\"noder-modal\">\n <button\n id=\"menu-dropdowns-menu-item-align\"\n mat-menu-item\n [matMenuTriggerFor]=\"listAlignMenu\">\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-format-alignleft\"></mat-icon>\n <span class=\"menu-item-text\">Align</span>\n </div>\n </button>\n <mat-menu\n #listAlignMenu=\"matMenu\"\n class=\"noder-modal\">\n <button\n id=\"menu-dropdowns-menu-item-align-left\"\n mat-menu-item\n (click)=\"onSelectFormat(alignments.Left)\">\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-format-alignleft\"></mat-icon>\n <span class=\"menu-item-text\">Left</span>\n <span class=\"hot-keys\">Ctrl+L</span>\n </div>\n </button>\n <button\n id=\"menu-dropdowns-menu-item-align-center\"\n mat-menu-item\n (click)=\"onSelectFormat(alignments.Center)\">\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-format-aligncenter\"></mat-icon>\n <span class=\"menu-item-text\">Center</span>\n <span class=\"hot-keys\">Ctrl+E</span>\n </div>\n </button>\n <button\n id=\"menu-dropdowns-menu-item-align-right\"\n mat-menu-item\n (click)=\"onSelectFormat(alignments.Right)\">\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-format-alignright\"></mat-icon>\n <span class=\"menu-item-text\">Right</span>\n <span class=\"hot-keys\">Ctrl+R</span>\n </div>\n </button>\n </mat-menu>\n <button\n id=\"menu-dropdowns-menu-item-bullets-numbering\"\n mat-menu-item\n [matMenuTriggerFor]=\"listBulletsNumberingMenu\">\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-format-bulleted\"></mat-icon>\n <span class=\"menu-item-text\">Bullets & Numbering</span>\n </div>\n </button>\n <mat-menu\n #listBulletsNumberingMenu=\"matMenu\"\n class=\"noder-modal\">\n <button\n id=\"menu-dropdowns-menu-item-bullets\"\n mat-menu-item\n [matMenuTriggerFor]=\"listBulletedMenu\">\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-format-bulleted\"></mat-icon>\n <span class=\"menu-item-text\">Bullet List Menu</span>\n </div>\n </button>\n <mat-menu\n #listBulletedMenu=\"matMenu\"\n class=\"dropdown-numbering-overlay noder-modal\"\n yPosition=\"below\">\n <div class=\"list-icon list-marker\">\n <mat-icon\n svgIcon=\"marker-1\"\n [class.selected]=\"numberingTemplateType === numberingTemplateTypes.BulletList1\"\n (click)=\"onSelectNumberingTemplate(numberingTemplateTypes.BulletList1)\"></mat-icon>\n <mat-icon\n svgIcon=\"marker-2\"\n [class.selected]=\"numberingTemplateType === numberingTemplateTypes.BulletList2\"\n (click)=\"onSelectNumberingTemplate(numberingTemplateTypes.BulletList2)\"></mat-icon>\n <mat-icon\n svgIcon=\"marker-3\"\n [class.selected]=\"numberingTemplateType === numberingTemplateTypes.BulletList3\"\n (click)=\"onSelectNumberingTemplate(numberingTemplateTypes.BulletList3)\"></mat-icon>\n </div>\n <div class=\"list-icon list-marker\">\n <mat-icon\n svgIcon=\"marker-4\"\n [class.selected]=\"numberingTemplateType === numberingTemplateTypes.BulletList4\"\n (click)=\"onSelectNumberingTemplate(numberingTemplateTypes.BulletList4)\"></mat-icon>\n <mat-icon\n svgIcon=\"marker-5\"\n [class.selected]=\"numberingTemplateType === numberingTemplateTypes.BulletList5\"\n (click)=\"onSelectNumberingTemplate(numberingTemplateTypes.BulletList5)\"></mat-icon>\n <mat-icon\n svgIcon=\"marker-6\"\n [class.selected]=\"numberingTemplateType === numberingTemplateTypes.BulletList6\"\n (click)=\"onSelectNumberingTemplate(numberingTemplateTypes.BulletList6)\"></mat-icon>\n </div>\n </mat-menu>\n <button\n id=\"menu-dropdowns-menu-item-numbering\"\n mat-menu-item\n [matMenuTriggerFor]=\"listNumberedMenu\">\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-format-numbered\"></mat-icon>\n <span class=\"menu-item-text\">Numbered List Menu</span>\n </div>\n </button>\n <mat-menu\n #listNumberedMenu=\"matMenu\"\n class=\"dropdown-numbering-overlay noder-modal\"\n yPosition=\"below\">\n <div class=\"list-icon list-number\">\n <mat-icon\n svgIcon=\"number-1\"\n [class.selected]=\"numberingTemplateType === numberingTemplateTypes.NumberList1\"\n (click)=\"onSelectNumberingTemplate(numberingTemplateTypes.NumberList1)\"></mat-icon>\n <mat-icon\n svgIcon=\"number-2\"\n [class.selected]=\"numberingTemplateType === numberingTemplateTypes.NumberList2\"\n (click)=\"onSelectNumberingTemplate(numberingTemplateTypes.NumberList2)\"></mat-icon>\n <mat-icon\n svgIcon=\"number-3\"\n [class.selected]=\"numberingTemplateType === numberingTemplateTypes.NumberList3\"\n (click)=\"onSelectNumberingTemplate(numberingTemplateTypes.NumberList3)\"></mat-icon>\n </div>\n <div class=\"list-icon list-number\">\n <mat-icon\n svgIcon=\"number-4\"\n [class.selected]=\"numberingTemplateType === numberingTemplateTypes.NumberList4\"\n (click)=\"onSelectNumberingTemplate(numberingTemplateTypes.NumberList4)\"></mat-icon>\n <mat-icon\n svgIcon=\"number-5\"\n [class.selected]=\"numberingTemplateType === numberingTemplateTypes.NumberList5\"\n (click)=\"onSelectNumberingTemplate(numberingTemplateTypes.NumberList5)\"></mat-icon>\n <mat-icon\n svgIcon=\"number-6\"\n [class.selected]=\"numberingTemplateType === numberingTemplateTypes.NumberList6\"\n (click)=\"onSelectNumberingTemplate(numberingTemplateTypes.NumberList6)\"></mat-icon>\n </div>\n </mat-menu>\n </mat-menu>\n <button\n id=\"menu-dropdowns-menu-item-text\"\n mat-menu-item\n [matMenuTriggerFor]=\"listTextMenu\">\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-format-bold\"></mat-icon>\n <span class=\"menu-item-text\">Text</span>\n </div>\n </button>\n <mat-menu\n #listTextMenu=\"matMenu\"\n class=\"noder-modal\">\n <button\n id=\"menu-dropdowns-menu-item-bold\"\n mat-menu-item\n (click)=\"onApplyBold()\">\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-format-bold\"></mat-icon>\n <span class=\"menu-item-text\">Bold</span>\n <span class=\"hot-keys\">Ctrl+B</span>\n </div>\n </button>\n <button\n id=\"menu-dropdowns-menu-item-italic\"\n mat-menu-item\n (click)=\"onApplyItalic()\">\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-format-italic\"></mat-icon>\n <span class=\"menu-item-text\">Italic</span>\n <span class=\"hot-keys\">Ctrl+I</span>\n </div>\n </button>\n <button\n id=\"menu-dropdowns-menu-item-underlined\"\n mat-menu-item\n (click)=\"onApplyUnderline()\">\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-format-underlined\"></mat-icon>\n <span class=\"menu-item-text\">Underlined</span>\n <span class=\"hot-keys\">Ctrl+U</span>\n </div>\n </button>\n </mat-menu>\n <button\n id=\"menu-dropdowns-menu-item-header-footer\"\n mat-menu-item\n class=\"hidden\">\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-headers-footers\"></mat-icon>\n <span class=\"menu-item-text\">Headers & Footers</span>\n </div>\n </button>\n </mat-menu>\n <mat-menu\n #tableInsert=\"matMenu\"\n class=\"insert-table noder-modal\">\n <app-nod-insert-table\n *ngIf=\"showInsertTableMenu\"\n (selectSizes)=\"insertTable.emit($event)\" />\n </mat-menu>\n</ng-container>\n", styles: [":host{display:flex;align-items:center;height:100%}.menu-buttons mat-icon{width:24px;height:24px;font-size:24px}.heading-menu{display:inline-flex;width:210px}.hot-keys{text-align:end;width:auto}.menu-item-text{white-space:nowrap;width:64%}.mat-mdc-menu-item .mat-icon{margin-right:4px;width:28px}.hidden{display:none}.list-marker,.list-number{margin:0 5px}.list-marker mat-icon,.list-number mat-icon{width:70px;height:80px;margin:0 5px}.list-marker mat-icon:hover,.list-number mat-icon:hover{border:none}.list-icon .selected,.list-icon .selected:hover,.list-number .selected,.list-number .selected:hover{border-width:2px;border-style:solid}\n"], dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: InsertTableComponent, selector: "app-nod-insert-table", outputs: ["selectSizes"] }, { kind: "component", type: i4.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i3$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i4$2.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i4$2.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i4$2.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
13707
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: MenuDropdownsComponent, selector: "app-nod-menu-dropdowns", inputs: { showFile: "showFile", showEdit: "showEdit", showInsert: "showInsert", showLayout: "showLayout", showFormat: "showFormat" }, outputs: { openFileFromDisk: "openFileFromDisk", saveAs: "saveAs", insertPageBreak: "insertPageBreak", createDocument: "createDocument", rename: "rename", delete: "delete", openEditMenu: "openEditMenu", cutSelected: "cutSelected", copySelected: "copySelected", pasteClipboardData: "pasteClipboardData", selectAll: "selectAll", removeSelected: "removeSelected" }, viewQueries: [{ propertyName: "tableInsertMenu", first: true, predicate: ["tableInsert"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<ng-container\n *ngIf=\"{\n clipboardData: editorService.clipboardData$ | async,\n hasSelection: editorService.hasSelection$ | async,\n isViewOnly: editorService.isViewOnly$ | async\n } as data\">\n <button\n *ngIf=\"showFile\"\n id=\"menu-dropdowns-menu-file\"\n mat-button\n [matMenuTriggerFor]=\"fileMenu\"\n [matMenuTriggerRestoreFocus]=\"false\">\n File\n </button>\n <mat-menu\n #fileMenu=\"matMenu\"\n class=\"noder-modal\">\n <button\n *ngIf=\"createDocument.observed && !data.isViewOnly\"\n id=\"menu-dropdowns-menu-item-new\"\n mat-menu-item\n (click)=\"createDocument.emit()\">\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-add-new\"></mat-icon>\n <span class=\"menu-item-text\">New</span>\n </div>\n </button>\n <button\n *ngIf=\"openFileFromDisk.observed && !data.isViewOnly\"\n id=\"menu-dropdowns-menu-item-open-from\"\n mat-menu-item\n (click)=\"openFileFromDisk.emit()\">\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-open-from\"></mat-icon>\n <span class=\"menu-item-text\">Open From</span>\n <span class=\"hot-keys\">Ctrl+O</span>\n </div>\n </button>\n <button\n *ngIf=\"saveAs.observed\"\n id=\"menu-dropdowns-menu-item-save-as\"\n mat-menu-item\n (click)=\"saveAs.emit()\">\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-save\"></mat-icon>\n <span class=\"menu-item-text\">Save As</span>\n </div>\n </button>\n <button\n *ngIf=\"rename.observed\"\n id=\"menu-dropdowns-menu-item-rename\"\n mat-menu-item\n (click)=\"rename.emit()\">\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-rename\"></mat-icon>\n <span class=\"menu-item-text\">Rename</span>\n </div>\n </button>\n <button\n *ngIf=\"print.observed\"\n id=\"menu-dropdowns-menu-item-print\"\n mat-menu-item\n (click)=\"print.emit()\">\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-print\"></mat-icon>\n <span class=\"menu-item-text\">Print</span>\n <span class=\"hot-keys\">Ctrl+P</span>\n </div>\n </button>\n <button\n *ngIf=\"delete.observed\"\n id=\"menu-dropdowns-menu-item-delete\"\n mat-menu-item\n (click)=\"delete.emit()\">\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-delete\"></mat-icon>\n <span class=\"menu-item-text\">Delete</span>\n </div>\n </button>\n </mat-menu>\n <button\n *ngIf=\"showEdit\"\n id=\"menu-dropdowns-menu-edit\"\n mat-button\n [matMenuTriggerFor]=\"editMenu\"\n [matMenuTriggerRestoreFocus]=\"false\"\n (menuOpened)=\"openEditMenu.emit()\">\n Edit\n </button>\n <mat-menu\n #editMenu=\"matMenu\"\n class=\"noder-modal\">\n <button\n *ngIf=\"undo.observed\"\n id=\"menu-dropdowns-menu-item-undo\"\n mat-menu-item\n [disabled]=\"!canUndo\"\n (click)=\"undo.emit()\">\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-undo\"></mat-icon>\n <span class=\"menu-item-text\">Undo</span>\n <span class=\"hot-keys\">Ctrl+Z</span>\n </div>\n </button>\n <button\n *ngIf=\"redo.observed\"\n id=\"menu-dropdowns-menu-item-redo\"\n mat-menu-item\n [disabled]=\"!canRedo\"\n (click)=\"redo.emit()\">\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-redo\"></mat-icon>\n <span class=\"menu-item-text\">Redo</span>\n <span class=\"hot-keys\">Ctrl+Y</span>\n </div>\n </button>\n <hr class=\"noder-divider\" />\n <button\n *ngIf=\"cutSelected.observed\"\n id=\"menu-dropdowns-menu-item-cut\"\n mat-menu-item\n [disabled]=\"!data.hasSelection\"\n (click)=\"cutSelected.emit()\">\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-content-cut\"></mat-icon>\n <span class=\"menu-item-text\">Cut</span>\n <span class=\"hot-keys\">Ctrl+X</span>\n </div>\n </button>\n <button\n *ngIf=\"copySelected.observed\"\n id=\"menu-dropdowns-menu-item-copy\"\n mat-menu-item\n [disabled]=\"!data.hasSelection\"\n (click)=\"copySelected.emit()\">\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-file-copy\"></mat-icon>\n <span class=\"menu-item-text\">Copy</span>\n <span class=\"hot-keys\">Ctrl+C</span>\n </div>\n </button>\n <button\n *ngIf=\"pasteClipboardData.observed\"\n id=\"menu-dropdowns-menu-item-paste\"\n mat-menu-item\n [disabled]=\"!data.clipboardData?.length\"\n (click)=\"pasteClipboardData.emit()\">\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-content-paste\"></mat-icon>\n <span class=\"menu-item-text\">Paste</span>\n <span class=\"hot-keys\">Ctrl+V</span>\n </div>\n </button>\n <hr class=\"noder-divider\" />\n <button\n *ngIf=\"selectAll.observed\"\n id=\"menu-dropdowns-menu-item-select-all\"\n mat-menu-item\n (click)=\"selectAll.emit()\">\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-select-all\"></mat-icon>\n <span class=\"menu-item-text\">Select All</span>\n <span class=\"hot-keys\">Ctrl+A</span>\n </div>\n </button>\n <button\n *ngIf=\"removeSelected.observed\"\n id=\"menu-dropdowns-menu-item-delete-text\"\n mat-menu-item\n [disabled]=\"!data.hasSelection\"\n (click)=\"removeSelected.emit()\">\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-delete\"></mat-icon>\n <span class=\"menu-item-text\">Delete</span>\n </div>\n </button>\n </mat-menu>\n <button\n *ngIf=\"showInsert && !data.isViewOnly\"\n #insertMenuTrigger=\"matMenuTrigger\"\n id=\"menu-dropdowns-menu-insert\"\n mat-button\n [matMenuTriggerFor]=\"insertMenu\"\n [matMenuTriggerRestoreFocus]=\"false\">\n Insert\n </button>\n <mat-menu\n #insertMenu=\"matMenu\"\n class=\"noder-modal\">\n <button\n *ngIf=\"insertImage.observed\"\n id=\"menu-dropdowns-menu-item-image\"\n mat-menu-item\n (click)=\"insertImage.emit()\">\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-image\"></mat-icon>\n <span class=\"menu-item-text\">Image</span>\n </div>\n </button>\n <button\n id=\"menu-dropdowns-menu-item-table\"\n mat-menu-item\n [matMenuTriggerFor]=\"tableInsert\"\n (menuOpened)=\"showInsertTableMenu = true\"\n (menuClosed)=\"onTableInsertMenuClosed()\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-table\"></mat-icon>\n Table\n </button>\n <hr class=\"noder-divider\" />\n <button\n *ngIf=\"insertLink.observed\"\n id=\"menu-dropdowns-menu-item-link\"\n mat-menu-item\n (click)=\"insertLink.emit()\">\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-link-on\"></mat-icon>\n <span class=\"menu-item-text\">Link</span>\n <span class=\"hot-keys\">Ctrl+K</span>\n </div>\n </button>\n <button\n *ngFor=\"let element of elements\"\n id=\"menu-dropdowns-menu-item-{{ element.title }}\"\n mat-menu-item\n (click)=\"onCreateElement(element)\">\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"{{ element.icon }}\"></mat-icon>\n <span class=\"menu-item-text\">{{ element.name }}</span>\n </div>\n </button>\n <button\n id=\"menu-dropdowns-menu-item-headers-footers\"\n mat-menu-item\n class=\"hidden\"\n [matMenuTriggerFor]=\"listHeadersFootersMenu\">\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-headers-footers\"></mat-icon>\n <span class=\"menu-item-text\">Headers & Footers</span>\n </div>\n </button>\n <mat-menu\n #listHeadersFootersMenu=\"matMenu\"\n class=\"noder-modal\">\n <button\n id=\"menu-dropdowns-menu-item-header\"\n mat-menu-item>\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-header\"></mat-icon>\n <span class=\"menu-item-text\">Header</span>\n </div>\n </button>\n <button\n id=\"menu-dropdowns-menu-item-footer\"\n mat-menu-item>\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-bottom\"></mat-icon>\n <span class=\"menu-item-text\">Footer</span>\n </div>\n </button>\n </mat-menu>\n </mat-menu>\n <button\n *ngIf=\"showLayout && !data.isViewOnly\"\n id=\"menu-dropdowns-menu-layout\"\n mat-button\n [matMenuTriggerFor]=\"layoutMenu\"\n [matMenuTriggerRestoreFocus]=\"false\">\n Layout\n </button>\n <mat-menu\n #layoutMenu=\"matMenu\"\n class=\"noder-modal\">\n <button\n *ngIf=\"insertPageBreak.observed\"\n id=\"menu-dropdowns-menu-item-page-break\"\n mat-menu-item\n (click)=\"insertPageBreak.emit()\">\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-page-break\"></mat-icon>\n <span class=\"menu-item-text\">Page Break</span>\n <span class=\"hot-keys\">Ctrl+Enter</span>\n </div>\n </button>\n </mat-menu>\n <button\n *ngIf=\"showFormat && !data.isViewOnly\"\n id=\"menu-dropdowns-menu-format\"\n mat-button\n [matMenuTriggerFor]=\"formatMenu\"\n [matMenuTriggerRestoreFocus]=\"false\">\n Format\n </button>\n <mat-menu\n #formatMenu=\"matMenu\"\n class=\"noder-modal\">\n <button\n id=\"menu-dropdowns-menu-item-align\"\n mat-menu-item\n [matMenuTriggerFor]=\"listAlignMenu\">\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-format-alignleft\"></mat-icon>\n <span class=\"menu-item-text\">Align</span>\n </div>\n </button>\n <mat-menu\n #listAlignMenu=\"matMenu\"\n class=\"noder-modal\">\n <button\n id=\"menu-dropdowns-menu-item-align-left\"\n mat-menu-item\n (click)=\"onSelectFormat(alignments.Left)\">\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-format-alignleft\"></mat-icon>\n <span class=\"menu-item-text\">Left</span>\n <span class=\"hot-keys\">Ctrl+L</span>\n </div>\n </button>\n <button\n id=\"menu-dropdowns-menu-item-align-center\"\n mat-menu-item\n (click)=\"onSelectFormat(alignments.Center)\">\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-format-aligncenter\"></mat-icon>\n <span class=\"menu-item-text\">Center</span>\n <span class=\"hot-keys\">Ctrl+E</span>\n </div>\n </button>\n <button\n id=\"menu-dropdowns-menu-item-align-right\"\n mat-menu-item\n (click)=\"onSelectFormat(alignments.Right)\">\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-format-alignright\"></mat-icon>\n <span class=\"menu-item-text\">Right</span>\n <span class=\"hot-keys\">Ctrl+R</span>\n </div>\n </button>\n </mat-menu>\n <button\n id=\"menu-dropdowns-menu-item-bullets-numbering\"\n mat-menu-item\n [matMenuTriggerFor]=\"listBulletsNumberingMenu\">\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-format-bulleted\"></mat-icon>\n <span class=\"menu-item-text\">Bullets & Numbering</span>\n </div>\n </button>\n <mat-menu\n #listBulletsNumberingMenu=\"matMenu\"\n class=\"noder-modal\">\n <button\n id=\"menu-dropdowns-menu-item-bullets\"\n mat-menu-item\n [matMenuTriggerFor]=\"listBulletedMenu\">\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-format-bulleted\"></mat-icon>\n <span class=\"menu-item-text\">Bullet List Menu</span>\n </div>\n </button>\n <mat-menu\n #listBulletedMenu=\"matMenu\"\n class=\"dropdown-numbering-overlay noder-modal\"\n yPosition=\"below\">\n <div class=\"list-icon list-marker\">\n <mat-icon\n svgIcon=\"marker-1\"\n [class.selected]=\"numberingTemplateType === numberingTemplateTypes.BulletList1\"\n (click)=\"onSelectNumberingTemplate(numberingTemplateTypes.BulletList1)\"></mat-icon>\n <mat-icon\n svgIcon=\"marker-2\"\n [class.selected]=\"numberingTemplateType === numberingTemplateTypes.BulletList2\"\n (click)=\"onSelectNumberingTemplate(numberingTemplateTypes.BulletList2)\"></mat-icon>\n <mat-icon\n svgIcon=\"marker-3\"\n [class.selected]=\"numberingTemplateType === numberingTemplateTypes.BulletList3\"\n (click)=\"onSelectNumberingTemplate(numberingTemplateTypes.BulletList3)\"></mat-icon>\n </div>\n <div class=\"list-icon list-marker\">\n <mat-icon\n svgIcon=\"marker-4\"\n [class.selected]=\"numberingTemplateType === numberingTemplateTypes.BulletList4\"\n (click)=\"onSelectNumberingTemplate(numberingTemplateTypes.BulletList4)\"></mat-icon>\n <mat-icon\n svgIcon=\"marker-5\"\n [class.selected]=\"numberingTemplateType === numberingTemplateTypes.BulletList5\"\n (click)=\"onSelectNumberingTemplate(numberingTemplateTypes.BulletList5)\"></mat-icon>\n <mat-icon\n svgIcon=\"marker-6\"\n [class.selected]=\"numberingTemplateType === numberingTemplateTypes.BulletList6\"\n (click)=\"onSelectNumberingTemplate(numberingTemplateTypes.BulletList6)\"></mat-icon>\n </div>\n </mat-menu>\n <button\n id=\"menu-dropdowns-menu-item-numbering\"\n mat-menu-item\n [matMenuTriggerFor]=\"listNumberedMenu\">\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-format-numbered\"></mat-icon>\n <span class=\"menu-item-text\">Numbered List Menu</span>\n </div>\n </button>\n <mat-menu\n #listNumberedMenu=\"matMenu\"\n class=\"dropdown-numbering-overlay noder-modal\"\n yPosition=\"below\">\n <div class=\"list-icon list-number\">\n <mat-icon\n svgIcon=\"number-1\"\n [class.selected]=\"numberingTemplateType === numberingTemplateTypes.NumberList1\"\n (click)=\"onSelectNumberingTemplate(numberingTemplateTypes.NumberList1)\"></mat-icon>\n <mat-icon\n svgIcon=\"number-2\"\n [class.selected]=\"numberingTemplateType === numberingTemplateTypes.NumberList2\"\n (click)=\"onSelectNumberingTemplate(numberingTemplateTypes.NumberList2)\"></mat-icon>\n <mat-icon\n svgIcon=\"number-3\"\n [class.selected]=\"numberingTemplateType === numberingTemplateTypes.NumberList3\"\n (click)=\"onSelectNumberingTemplate(numberingTemplateTypes.NumberList3)\"></mat-icon>\n </div>\n <div class=\"list-icon list-number\">\n <mat-icon\n svgIcon=\"number-4\"\n [class.selected]=\"numberingTemplateType === numberingTemplateTypes.NumberList4\"\n (click)=\"onSelectNumberingTemplate(numberingTemplateTypes.NumberList4)\"></mat-icon>\n <mat-icon\n svgIcon=\"number-5\"\n [class.selected]=\"numberingTemplateType === numberingTemplateTypes.NumberList5\"\n (click)=\"onSelectNumberingTemplate(numberingTemplateTypes.NumberList5)\"></mat-icon>\n <mat-icon\n svgIcon=\"number-6\"\n [class.selected]=\"numberingTemplateType === numberingTemplateTypes.NumberList6\"\n (click)=\"onSelectNumberingTemplate(numberingTemplateTypes.NumberList6)\"></mat-icon>\n </div>\n </mat-menu>\n </mat-menu>\n <button\n id=\"menu-dropdowns-menu-item-text\"\n mat-menu-item\n [matMenuTriggerFor]=\"listTextMenu\">\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-format-bold\"></mat-icon>\n <span class=\"menu-item-text\">Text</span>\n </div>\n </button>\n <mat-menu\n #listTextMenu=\"matMenu\"\n class=\"noder-modal\">\n <button\n id=\"menu-dropdowns-menu-item-bold\"\n mat-menu-item\n (click)=\"onApplyBold()\">\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-format-bold\"></mat-icon>\n <span class=\"menu-item-text\">Bold</span>\n <span class=\"hot-keys\">Ctrl+B</span>\n </div>\n </button>\n <button\n id=\"menu-dropdowns-menu-item-italic\"\n mat-menu-item\n (click)=\"onApplyItalic()\">\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-format-italic\"></mat-icon>\n <span class=\"menu-item-text\">Italic</span>\n <span class=\"hot-keys\">Ctrl+I</span>\n </div>\n </button>\n <button\n id=\"menu-dropdowns-menu-item-underlined\"\n mat-menu-item\n (click)=\"onApplyUnderline()\">\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-format-underlined\"></mat-icon>\n <span class=\"menu-item-text\">Underlined</span>\n <span class=\"hot-keys\">Ctrl+U</span>\n </div>\n </button>\n </mat-menu>\n <button\n id=\"menu-dropdowns-menu-item-header-footer\"\n mat-menu-item\n class=\"hidden\">\n <div class=\"heading-menu\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-headers-footers\"></mat-icon>\n <span class=\"menu-item-text\">Headers & Footers</span>\n </div>\n </button>\n </mat-menu>\n <mat-menu\n #tableInsert=\"matMenu\"\n class=\"insert-table noder-modal\">\n <app-nod-insert-table\n *ngIf=\"showInsertTableMenu\"\n (selectSizes)=\"insertTable.emit($event)\" />\n </mat-menu>\n</ng-container>\n", styles: [":host{display:flex;align-items:center;height:100%}.menu-buttons mat-icon{width:24px;height:24px;font-size:24px}.heading-menu{display:inline-flex;width:210px}.hot-keys{text-align:end;width:auto}.menu-item-text{white-space:nowrap;width:64%}.mat-mdc-menu-item .mat-icon{margin-right:4px;width:28px}.hidden{display:none}.list-marker,.list-number{margin:0 5px}.list-marker mat-icon,.list-number mat-icon{width:70px;height:80px;margin:0 5px}.list-marker mat-icon:hover,.list-number mat-icon:hover{border:none}.list-icon .selected,.list-icon .selected:hover,.list-number .selected,.list-number .selected:hover{border-width:2px;border-style:solid}\n"], dependencies: [{ kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: InsertTableComponent, selector: "app-nod-insert-table", outputs: ["selectSizes"] }, { kind: "component", type: i4.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i3$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i4$2.MatMenu, selector: "mat-menu", inputs: ["backdropClass", "aria-label", "aria-labelledby", "aria-describedby", "xPosition", "yPosition", "overlapTrigger", "hasBackdrop", "class", "classList"], outputs: ["closed", "close"], exportAs: ["matMenu"] }, { kind: "component", type: i4$2.MatMenuItem, selector: "[mat-menu-item]", inputs: ["role", "disabled", "disableRipple"], exportAs: ["matMenuItem"] }, { kind: "directive", type: i4$2.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", inputs: ["mat-menu-trigger-for", "matMenuTriggerFor", "matMenuTriggerData", "matMenuTriggerRestoreFocus"], outputs: ["menuOpened", "onMenuOpen", "menuClosed", "onMenuClose"], exportAs: ["matMenuTrigger"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
13581
13708
  }
13582
13709
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MenuDropdownsComponent, decorators: [{
13583
13710
  type: Component,
@@ -13594,8 +13721,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
13594
13721
  type: Input
13595
13722
  }], openFileFromDisk: [{
13596
13723
  type: Output
13597
- }], addCustomElement: [{
13598
- type: Output
13599
13724
  }], saveAs: [{
13600
13725
  type: Output
13601
13726
  }], insertPageBreak: [{
@@ -13627,7 +13752,7 @@ class FontComponent {
13627
13752
  constructor() {
13628
13753
  this.isDisabled = false;
13629
13754
  this.selectFont = new EventEmitter();
13630
- this.fonts = [DEFAULT_FONT_FAMILY, 'Verdana', 'Arial', 'Times New Roman'];
13755
+ this.fonts = ['Arial', DEFAULT_FONT_FAMILY, 'Times New Roman', 'Verdana'];
13631
13756
  this.font = DEFAULT_FONT_FAMILY;
13632
13757
  }
13633
13758
  set styles(value) {
@@ -14088,11 +14213,11 @@ class EditorToolbarComponent {
14088
14213
  this.insertTable = new EventEmitter();
14089
14214
  }
14090
14215
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EditorToolbarComponent, deps: [{ token: EditorService }], target: i0.ɵɵFactoryTarget.Component }); }
14091
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: EditorToolbarComponent, selector: "app-nod-editor-toolbar", outputs: { openFileFromDisk: "openFileFromDisk", addCustomElement: "addCustomElement", saveAs: "saveAs", print: "print", insertPageBreak: "insertPageBreak", createDocument: "createDocument", insertImage: "insertImage", rename: "rename", delete: "delete", openEditMenu: "openEditMenu", redo: "redo", undo: "undo", cutSelected: "cutSelected", copySelected: "copySelected", pasteClipboardData: "pasteClipboardData", selectAll: "selectAll", removeSelected: "removeSelected", insertLink: "insertLink", createElement: "createElement", changeParagraphStyle: "changeParagraphStyle", changeTextStyle: "changeTextStyle", setNumberingTemplateType: "setNumberingTemplateType", removeNumberings: "removeNumberings", insertTable: "insertTable" }, ngImport: i0, template: "<app-nod-menu-dropdowns\n (openFileFromDisk)=\"openFileFromDisk.emit()\"\n (addCustomElement)=\"addCustomElement.emit($event)\"\n (saveAs)=\"saveAs.emit()\"\n (print)=\"print.emit()\"\n (insertPageBreak)=\"insertPageBreak.emit()\"\n (createDocument)=\"createDocument.emit()\"\n (insertImage)=\"insertImage.emit()\"\n (rename)=\"rename.emit()\"\n (delete)=\"delete.emit()\"\n (openEditMenu)=\"openEditMenu.emit()\"\n (redo)=\"redo.emit()\"\n (undo)=\"undo.emit()\"\n (cutSelected)=\"cutSelected.emit()\"\n (copySelected)=\"copySelected.emit()\"\n (pasteClipboardData)=\"pasteClipboardData.emit()\"\n (selectAll)=\"selectAll.emit()\"\n (removeSelected)=\"removeSelected.emit()\"\n (insertLink)=\"insertLink.emit()\"\n (createElement)=\"createElement.emit($event)\"\n (changeParagraphStyle)=\"changeParagraphStyle.emit($event)\"\n (changeTextStyle)=\"changeTextStyle.emit($event)\"\n (setNumberingTemplateType)=\"setNumberingTemplateType.emit($event)\"\n (removeNumberings)=\"removeNumberings.emit()\"\n (insertTable)=\"insertTable.emit($event)\" />\n<app-nod-toolbar-actions\n *ngIf=\"(editorService.styles$ | async) && (editorService.isViewOnly$ | async) === false\"\n (print)=\"print.emit()\"\n (redo)=\"redo.emit()\"\n (undo)=\"undo.emit()\"\n (changeParagraphStyle)=\"changeParagraphStyle.emit($event)\"\n (changeTextStyle)=\"changeTextStyle.emit($event)\"\n (setNumberingTemplateType)=\"setNumberingTemplateType.emit($event)\"\n (removeNumberings)=\"removeNumberings.emit()\"\n (createElement)=\"createElement.emit($event)\"\n (insertImage)=\"insertImage.emit()\"\n (insertLink)=\"insertLink.emit()\"\n (insertTable)=\"insertTable.emit($event)\" />\n", styles: [":host ::ng-deep{display:flex;position:relative;width:100%;height:32px}app-nod-toolbar-actions{display:flex;position:absolute;align-items:center;justify-content:center;width:100%;height:100%}\n"], dependencies: [{ kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: MenuDropdownsComponent, selector: "app-nod-menu-dropdowns", inputs: ["showFile", "showEdit", "showInsert", "showLayout", "showFormat"], outputs: ["openFileFromDisk", "addCustomElement", "saveAs", "insertPageBreak", "createDocument", "rename", "delete", "openEditMenu", "cutSelected", "copySelected", "pasteClipboardData", "selectAll", "removeSelected"] }, { kind: "component", type: ToolbarActionsComponent, selector: "app-nod-toolbar-actions" }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
14216
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: EditorToolbarComponent, selector: "app-nod-editor-toolbar", outputs: { openFileFromDisk: "openFileFromDisk", addCustomElement: "addCustomElement", saveAs: "saveAs", print: "print", insertPageBreak: "insertPageBreak", createDocument: "createDocument", insertImage: "insertImage", rename: "rename", delete: "delete", openEditMenu: "openEditMenu", redo: "redo", undo: "undo", cutSelected: "cutSelected", copySelected: "copySelected", pasteClipboardData: "pasteClipboardData", selectAll: "selectAll", removeSelected: "removeSelected", insertLink: "insertLink", createElement: "createElement", changeParagraphStyle: "changeParagraphStyle", changeTextStyle: "changeTextStyle", setNumberingTemplateType: "setNumberingTemplateType", removeNumberings: "removeNumberings", insertTable: "insertTable" }, ngImport: i0, template: "<app-nod-menu-dropdowns\n (openFileFromDisk)=\"openFileFromDisk.emit()\"\n (saveAs)=\"saveAs.emit()\"\n (print)=\"print.emit()\"\n (insertPageBreak)=\"insertPageBreak.emit()\"\n (createDocument)=\"createDocument.emit()\"\n (insertImage)=\"insertImage.emit()\"\n (rename)=\"rename.emit()\"\n (delete)=\"delete.emit()\"\n (openEditMenu)=\"openEditMenu.emit()\"\n (redo)=\"redo.emit()\"\n (undo)=\"undo.emit()\"\n (cutSelected)=\"cutSelected.emit()\"\n (copySelected)=\"copySelected.emit()\"\n (pasteClipboardData)=\"pasteClipboardData.emit()\"\n (selectAll)=\"selectAll.emit()\"\n (removeSelected)=\"removeSelected.emit()\"\n (insertLink)=\"insertLink.emit()\"\n (createElement)=\"createElement.emit($event)\"\n (changeParagraphStyle)=\"changeParagraphStyle.emit($event)\"\n (changeTextStyle)=\"changeTextStyle.emit($event)\"\n (setNumberingTemplateType)=\"setNumberingTemplateType.emit($event)\"\n (removeNumberings)=\"removeNumberings.emit()\"\n (insertTable)=\"insertTable.emit($event)\" />\n<app-nod-toolbar-actions\n *ngIf=\"(editorService.styles$ | async) && (editorService.isViewOnly$ | async) === false\"\n (print)=\"print.emit()\"\n (redo)=\"redo.emit()\"\n (undo)=\"undo.emit()\"\n (changeParagraphStyle)=\"changeParagraphStyle.emit($event)\"\n (changeTextStyle)=\"changeTextStyle.emit($event)\"\n (setNumberingTemplateType)=\"setNumberingTemplateType.emit($event)\"\n (removeNumberings)=\"removeNumberings.emit()\"\n (createElement)=\"createElement.emit($event)\"\n (insertImage)=\"insertImage.emit()\"\n (insertLink)=\"insertLink.emit()\"\n (insertTable)=\"insertTable.emit($event)\" />\n", styles: [":host ::ng-deep{display:flex;position:relative;width:100%;height:32px}app-nod-toolbar-actions{display:flex;position:absolute;align-items:center;justify-content:center;width:100%;height:100%}\n"], dependencies: [{ kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: MenuDropdownsComponent, selector: "app-nod-menu-dropdowns", inputs: ["showFile", "showEdit", "showInsert", "showLayout", "showFormat"], outputs: ["openFileFromDisk", "saveAs", "insertPageBreak", "createDocument", "rename", "delete", "openEditMenu", "cutSelected", "copySelected", "pasteClipboardData", "selectAll", "removeSelected"] }, { kind: "component", type: ToolbarActionsComponent, selector: "app-nod-toolbar-actions" }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
14092
14217
  }
14093
14218
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EditorToolbarComponent, decorators: [{
14094
14219
  type: Component,
14095
- args: [{ changeDetection: ChangeDetectionStrategy.OnPush, selector: 'app-nod-editor-toolbar', template: "<app-nod-menu-dropdowns\n (openFileFromDisk)=\"openFileFromDisk.emit()\"\n (addCustomElement)=\"addCustomElement.emit($event)\"\n (saveAs)=\"saveAs.emit()\"\n (print)=\"print.emit()\"\n (insertPageBreak)=\"insertPageBreak.emit()\"\n (createDocument)=\"createDocument.emit()\"\n (insertImage)=\"insertImage.emit()\"\n (rename)=\"rename.emit()\"\n (delete)=\"delete.emit()\"\n (openEditMenu)=\"openEditMenu.emit()\"\n (redo)=\"redo.emit()\"\n (undo)=\"undo.emit()\"\n (cutSelected)=\"cutSelected.emit()\"\n (copySelected)=\"copySelected.emit()\"\n (pasteClipboardData)=\"pasteClipboardData.emit()\"\n (selectAll)=\"selectAll.emit()\"\n (removeSelected)=\"removeSelected.emit()\"\n (insertLink)=\"insertLink.emit()\"\n (createElement)=\"createElement.emit($event)\"\n (changeParagraphStyle)=\"changeParagraphStyle.emit($event)\"\n (changeTextStyle)=\"changeTextStyle.emit($event)\"\n (setNumberingTemplateType)=\"setNumberingTemplateType.emit($event)\"\n (removeNumberings)=\"removeNumberings.emit()\"\n (insertTable)=\"insertTable.emit($event)\" />\n<app-nod-toolbar-actions\n *ngIf=\"(editorService.styles$ | async) && (editorService.isViewOnly$ | async) === false\"\n (print)=\"print.emit()\"\n (redo)=\"redo.emit()\"\n (undo)=\"undo.emit()\"\n (changeParagraphStyle)=\"changeParagraphStyle.emit($event)\"\n (changeTextStyle)=\"changeTextStyle.emit($event)\"\n (setNumberingTemplateType)=\"setNumberingTemplateType.emit($event)\"\n (removeNumberings)=\"removeNumberings.emit()\"\n (createElement)=\"createElement.emit($event)\"\n (insertImage)=\"insertImage.emit()\"\n (insertLink)=\"insertLink.emit()\"\n (insertTable)=\"insertTable.emit($event)\" />\n", styles: [":host ::ng-deep{display:flex;position:relative;width:100%;height:32px}app-nod-toolbar-actions{display:flex;position:absolute;align-items:center;justify-content:center;width:100%;height:100%}\n"] }]
14220
+ args: [{ changeDetection: ChangeDetectionStrategy.OnPush, selector: 'app-nod-editor-toolbar', template: "<app-nod-menu-dropdowns\n (openFileFromDisk)=\"openFileFromDisk.emit()\"\n (saveAs)=\"saveAs.emit()\"\n (print)=\"print.emit()\"\n (insertPageBreak)=\"insertPageBreak.emit()\"\n (createDocument)=\"createDocument.emit()\"\n (insertImage)=\"insertImage.emit()\"\n (rename)=\"rename.emit()\"\n (delete)=\"delete.emit()\"\n (openEditMenu)=\"openEditMenu.emit()\"\n (redo)=\"redo.emit()\"\n (undo)=\"undo.emit()\"\n (cutSelected)=\"cutSelected.emit()\"\n (copySelected)=\"copySelected.emit()\"\n (pasteClipboardData)=\"pasteClipboardData.emit()\"\n (selectAll)=\"selectAll.emit()\"\n (removeSelected)=\"removeSelected.emit()\"\n (insertLink)=\"insertLink.emit()\"\n (createElement)=\"createElement.emit($event)\"\n (changeParagraphStyle)=\"changeParagraphStyle.emit($event)\"\n (changeTextStyle)=\"changeTextStyle.emit($event)\"\n (setNumberingTemplateType)=\"setNumberingTemplateType.emit($event)\"\n (removeNumberings)=\"removeNumberings.emit()\"\n (insertTable)=\"insertTable.emit($event)\" />\n<app-nod-toolbar-actions\n *ngIf=\"(editorService.styles$ | async) && (editorService.isViewOnly$ | async) === false\"\n (print)=\"print.emit()\"\n (redo)=\"redo.emit()\"\n (undo)=\"undo.emit()\"\n (changeParagraphStyle)=\"changeParagraphStyle.emit($event)\"\n (changeTextStyle)=\"changeTextStyle.emit($event)\"\n (setNumberingTemplateType)=\"setNumberingTemplateType.emit($event)\"\n (removeNumberings)=\"removeNumberings.emit()\"\n (createElement)=\"createElement.emit($event)\"\n (insertImage)=\"insertImage.emit()\"\n (insertLink)=\"insertLink.emit()\"\n (insertTable)=\"insertTable.emit($event)\" />\n", styles: [":host ::ng-deep{display:flex;position:relative;width:100%;height:32px}app-nod-toolbar-actions{display:flex;position:absolute;align-items:center;justify-content:center;width:100%;height:100%}\n"] }]
14096
14221
  }], ctorParameters: () => [{ type: EditorService }], propDecorators: { openFileFromDisk: [{
14097
14222
  type: Output
14098
14223
  }], addCustomElement: [{
@@ -14526,9 +14651,11 @@ class RevisionHelper {
14526
14651
  }
14527
14652
  static fillEdgesDefaultStyles(headers, footers) {
14528
14653
  for (const header of headers) {
14654
+ this.fillTablesDefaultStyles(header.tables);
14529
14655
  this.fillDefaultStyles(header);
14530
14656
  }
14531
14657
  for (const footer of footers) {
14658
+ this.fillTablesDefaultStyles(footer.tables);
14532
14659
  this.fillDefaultStyles(footer);
14533
14660
  }
14534
14661
  }