@talrace/ngx-noder 0.0.12 → 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 (72) 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/menu-dropdowns/menu-dropdowns.component.mjs +2 -5
  4. package/esm2022/lib/apart-components/editor-toolbar/editor-toolbar/editor-toolbar.component.mjs +3 -3
  5. package/esm2022/lib/editor/components/edges/edge-element.model.mjs +30 -1
  6. package/esm2022/lib/editor/components/edges/edge.component.mjs +23 -23
  7. package/esm2022/lib/editor/components/edges/edges.mjs +30 -15
  8. package/esm2022/lib/editor/components/image/components/image.component.mjs +2 -2
  9. package/esm2022/lib/editor/components/image/input-handler/image-input.handler.mjs +2 -2
  10. package/esm2022/lib/editor/components/table/components/table-cell.component.mjs +5 -3
  11. package/esm2022/lib/editor/components/table/components/table.component.mjs +7 -5
  12. package/esm2022/lib/editor/components/table/selection/table-selection.mjs +12 -5
  13. package/esm2022/lib/editor/content/display-data/display-data.mjs +4 -4
  14. package/esm2022/lib/editor/content/helpers/content-style.helper.mjs +1 -1
  15. package/esm2022/lib/editor/content/helpers/link.helper.mjs +39 -3
  16. package/esm2022/lib/editor/display/layers/text.layer.mjs +100 -75
  17. package/esm2022/lib/editor/display/print/print.helper.mjs +3 -3
  18. package/esm2022/lib/editor/display/print/print.renderer.mjs +5 -5
  19. package/esm2022/lib/editor/display/renderer.mjs +23 -25
  20. package/esm2022/lib/editor/display/virtual.renderer.mjs +10 -43
  21. package/esm2022/lib/editor/execution/edit.session.mjs +24 -14
  22. package/esm2022/lib/editor/execution/editor.mjs +77 -116
  23. package/esm2022/lib/editor/execution/regulator.service.mjs +44 -39
  24. package/esm2022/lib/editor/execution/targeting/cell-session-source.model.mjs +2 -3
  25. package/esm2022/lib/editor/execution/targeting/edge-session-source.model.mjs +2 -3
  26. package/esm2022/lib/editor/execution/targeting/main-session-source.model.mjs +2 -2
  27. package/esm2022/lib/editor/execution/targeting/session-source.model.mjs +1 -1
  28. package/esm2022/lib/editor/gadgets/history/operation-history.mjs +27 -24
  29. package/esm2022/lib/editor/interaction/editor.service.mjs +22 -22
  30. package/esm2022/lib/editor/interaction/mouse.handler.mjs +2 -2
  31. package/esm2022/lib/editor/operations/helpers/format-operations.helper.mjs +2 -2
  32. package/esm2022/lib/editor/operations/helpers/link-operations.helper.mjs +59 -7
  33. package/esm2022/lib/editor/operations/operations-helper.helper.mjs +19 -21
  34. package/esm2022/lib/editor/operations/save-commands.helper.mjs +3 -2
  35. package/esm2022/lib/editor/positioning/content.helper.mjs +10 -1
  36. package/esm2022/lib/editor/positioning/position.helper.mjs +49 -35
  37. package/esm2022/lib/editor/revision.helper.mjs +3 -1
  38. package/esm2022/lib/models/generated/restore-text-styles.model.mjs +1 -1
  39. package/esm2022/lib/models/generated/target.model.mjs +1 -1
  40. package/fesm2022/talrace-ngx-noder.mjs +636 -508
  41. package/fesm2022/talrace-ngx-noder.mjs.map +1 -1
  42. package/lib/apart-components/editor-toolbar/components/menu-dropdowns/menu-dropdowns.component.d.ts +1 -3
  43. package/lib/apart-components/editor-toolbar/editor-toolbar/editor-toolbar.component.d.ts +1 -1
  44. package/lib/editor/components/edges/edge-element.model.d.ts +9 -1
  45. package/lib/editor/components/edges/edge.component.d.ts +4 -4
  46. package/lib/editor/components/edges/edges.d.ts +8 -2
  47. package/lib/editor/components/table/components/table.component.d.ts +4 -2
  48. package/lib/editor/components/table/selection/table-selection.d.ts +5 -2
  49. package/lib/editor/content/display-data/display-data.d.ts +2 -1
  50. package/lib/editor/content/helpers/content-style.helper.d.ts +1 -1
  51. package/lib/editor/content/helpers/link.helper.d.ts +4 -1
  52. package/lib/editor/display/layers/text.layer.d.ts +8 -10
  53. package/lib/editor/display/print/print.helper.d.ts +1 -2
  54. package/lib/editor/display/print/print.renderer.d.ts +1 -2
  55. package/lib/editor/display/renderer.d.ts +9 -9
  56. package/lib/editor/display/virtual.renderer.d.ts +3 -10
  57. package/lib/editor/execution/edit.session.d.ts +7 -2
  58. package/lib/editor/execution/editor.d.ts +9 -8
  59. package/lib/editor/execution/regulator.service.d.ts +6 -4
  60. package/lib/editor/execution/targeting/cell-session-source.model.d.ts +0 -1
  61. package/lib/editor/execution/targeting/edge-session-source.model.d.ts +0 -1
  62. package/lib/editor/execution/targeting/session-source.model.d.ts +0 -1
  63. package/lib/editor/gadgets/history/operation-history.d.ts +5 -1
  64. package/lib/editor/interaction/editor.service.d.ts +13 -12
  65. package/lib/editor/operations/helpers/link-operations.helper.d.ts +7 -2
  66. package/lib/editor/operations/operations-helper.helper.d.ts +2 -2
  67. package/lib/editor/positioning/content.helper.d.ts +2 -0
  68. package/lib/editor/positioning/position.helper.d.ts +21 -6
  69. package/lib/models/generated/restore-text-styles.model.d.ts +1 -0
  70. package/lib/models/generated/target.model.d.ts +0 -1
  71. package/package.json +1 -1
  72. 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() {
@@ -1633,27 +1675,8 @@ class OperationHistory {
1633
1675
  this.addToHistory(undoStep, redoStep);
1634
1676
  }
1635
1677
  pushInsertParagraph(content, 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 count = content.length;
1646
- if (model.insertIndex === 0 || previousParagraph?.insertIndex === model.insertIndex - 1) {
1647
- count++;
1648
- }
1649
- else if (currentParagraph.insertIndex === model.insertIndex) {
1650
- startIndex++;
1651
- }
1652
- else {
1653
- count = count + 2;
1654
- }
1655
- const undoStep = new DeleteModel({ startIndex, count });
1656
- this.addToHistory(undoStep, model);
1678
+ const undoStep = this.getDeleteDataForInsertParagraphs(content, model, paragraphs);
1679
+ this.addToHistory(new DeleteModel({ ...undoStep }), model);
1657
1680
  }
1658
1681
  pushInsertElement(model) {
1659
1682
  const undoStep = new DeleteModel({ startIndex: model.element.insertIndex, count: CUSTOM_ELEMENT_MARKER.length });
@@ -1688,9 +1711,9 @@ class OperationHistory {
1688
1711
  const redoStep = new DeleteModel({ startIndex: model.startIndex, count: model.text.length });
1689
1712
  this.addToHistory(model, redoStep);
1690
1713
  }
1691
- pushApplyTextStyle(startIndex, endIndex, style, formats) {
1714
+ pushApplyTextStyle(startIndex, endIndex, style, formats, linkFormats) {
1692
1715
  const redoStep = new ApplyTextStyleModel({ startIndex, endIndex, textStyle: style });
1693
- const undoStep = new RestoreTextStylesModel({ formats });
1716
+ const undoStep = new RestoreTextStylesModel({ formats, linkFormats });
1694
1717
  this.addToHistory(undoStep, redoStep);
1695
1718
  }
1696
1719
  pushApplyParagraphStyle(startIndex, endIndex, style, paragraphs) {
@@ -1801,6 +1824,28 @@ class OperationHistory {
1801
1824
  }
1802
1825
  this.editorService.historyInfo = new OperationsHistoryInfoModel(this.step, this.storage.length - 1);
1803
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
+ }
1804
1849
  }
1805
1850
 
1806
1851
  class ParagraphModel {
@@ -1942,46 +1987,67 @@ class PositionHelper {
1942
1987
  };
1943
1988
  }
1944
1989
  /**
1945
- * Converts pixel position to screen position
1990
+ * Calculates the paragraph and line index based on the given Y position.
1946
1991
  **/
1947
- static pixelToScreen(session, x, y, scrollerPosition) {
1948
- const displayData = session.displayData;
1949
- const scrollTop = session.scrollTop;
1950
- let yPos = y + scrollTop - scrollerPosition.top;
1951
- 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);
1952
1996
  if (paragraphIndex < 0) {
1953
1997
  paragraphIndex = displayData.paragraphs.length - 1;
1954
1998
  }
1955
1999
  else if (paragraphIndex > 0) {
1956
2000
  paragraphIndex--;
1957
2001
  }
1958
- const paragraphSettings = displayData.getParagraphSettings(paragraphIndex);
1959
- yPos -= paragraphSettings.distanceFromTop;
2002
+ const paragraphSettings = displayData.paragraphs[paragraphIndex].paragraphSettings;
2003
+ yPosition -= paragraphSettings.distanceFromTop;
1960
2004
  let lineIndex = 0;
1961
- while (yPos > 0 && lineIndex < paragraphSettings.textLinesInfo.length - 1) {
1962
- const line = paragraphSettings.textLinesInfo[lineIndex];
1963
- const width = line.height + line.endPageOffset + line.offsetBefore + line.offsetAfter;
1964
- 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) {
1965
2009
  break;
1966
2010
  }
1967
2011
  lineIndex++;
1968
- yPos -= width;
2012
+ yPosition -= lineHeight;
1969
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;
1970
2021
  const line = paragraphSettings.textLinesInfo[lineIndex].screenLine;
1971
- let index = 0;
1972
- 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;
1973
2024
  const tokens = LineWidthHelper.getParagraphLineDisplayTokens(session, paragraphIndex, lineIndex);
1974
2025
  if (tokens[0].displayValue === DisplayValue.emptyLine) {
1975
- return new CursorParagraph(line, index);
2026
+ return { line, indexInLine };
1976
2027
  }
1977
- while (tokens.length > index) {
1978
- if (xPos < tokens[index].width / 2) {
1979
- break;
1980
- }
1981
- xPos -= tokens[index].width;
1982
- index++;
2028
+ while (indexInLine < tokens.length && relativeX >= tokens[indexInLine].width / 2) {
2029
+ relativeX -= tokens[indexInLine].width;
2030
+ indexInLine++;
2031
+ }
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++;
1983
2049
  }
1984
- return new CursorParagraph(line, index);
2050
+ return { line, indexInLine };
1985
2051
  }
1986
2052
  static findLineInParagraphs(paragraphs, documentLine) {
1987
2053
  let index = 0;
@@ -2013,17 +2079,10 @@ class PositionHelper {
2013
2079
  }
2014
2080
  return column;
2015
2081
  }
2016
- static pixelToPage(posY, session) {
2017
- const pagesCount = session.displayData.getParagraphSettings(session.displayData.paragraphs.length - 1).lastPageNumber;
2018
- let page = 1;
2019
- while (page <= pagesCount) {
2020
- const endPagePosition = (session.displayData.pagesSpace + session.displayData.pageHeight) * page;
2021
- if (endPagePosition >= posY) {
2022
- break;
2023
- }
2024
- page++;
2025
- }
2026
- 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;
2027
2086
  }
2028
2087
  }
2029
2088
 
@@ -2401,6 +2460,34 @@ class EdgeElementModel {
2401
2460
  }
2402
2461
  Object.assign(this, fields);
2403
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
+ }
2404
2491
  }
2405
2492
 
2406
2493
  var EdgeType;
@@ -2691,18 +2778,17 @@ class ParagraphHelper {
2691
2778
  }
2692
2779
 
2693
2780
  class TextLayer {
2694
- constructor(parentElement, session, editorService, renderingHelper = RenderingHelper) {
2781
+ constructor(parentElement, session, renderingHelper = RenderingHelper) {
2782
+ this.parentElement = parentElement;
2695
2783
  this.session = session;
2696
- this.editorService = editorService;
2697
2784
  this.renderingHelper = renderingHelper;
2698
2785
  this.edgeElements = [];
2699
- this.edgeEditingPage = null;
2700
2786
  this.pagesCountChangedHandler = (event) => {
2701
2787
  this.lines.setSizes(event.pagesCount, event.pageHeight);
2702
2788
  };
2703
2789
  this.element = document.createElement('div');
2704
2790
  this.element.className = 'noder-layer noder-text-layer';
2705
- parentElement.appendChild(this.element);
2791
+ this.parentElement.appendChild(this.element);
2706
2792
  this.lines = new Lines(this.element);
2707
2793
  this.session.displayData.addEventListener('pagesCountChanged', this.pagesCountChangedHandler);
2708
2794
  this.element.style.width = `${this.session.displayData.pageWidth}px`;
@@ -2710,31 +2796,73 @@ class TextLayer {
2710
2796
  destroy() {
2711
2797
  this.session.displayData.removeEventListener('pagesCountChanged', this.pagesCountChangedHandler);
2712
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
+ }
2713
2828
  updateEdges(config) {
2714
2829
  DomHelper.translate(this.element, 0, -config.scrollTop);
2715
2830
  while (this.edgeElements.length) {
2716
- const removedEl = this.edgeElements.pop();
2717
- DomHelper.removeElement(removedEl.element);
2718
- }
2719
- this.renderPagesEdgeComponents(config.pages);
2720
- }
2721
- edgeEditingPageUpdated(page) {
2722
- const oldEditingPage = this.edgeEditingPage;
2723
- this.edgeEditingPage = page;
2724
- this.removeEdgeComponents([page ?? oldEditingPage]);
2725
- this.renderPagesEdgeComponents([page ?? oldEditingPage]);
2726
- }
2727
- updateEdgeByLocation(updatedPageType) {
2728
- DomHelper.translate(this.element, 0, -this.config.scrollTop);
2729
- let pagesToRender = [];
2730
- for (let edgeElement of this.edgeElements) {
2731
- if (edgeElement.pageType !== updatedPageType || pagesToRender.includes(edgeElement.page)) {
2732
- 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);
2733
2864
  }
2734
- pagesToRender.push(edgeElement.page);
2735
2865
  }
2736
- this.removeEdgeComponents(pagesToRender);
2737
- this.renderPagesEdgeComponents(pagesToRender);
2738
2866
  }
2739
2867
  updateLines(config) {
2740
2868
  DomHelper.translate(this.element, 0, -config.scrollTop);
@@ -2744,13 +2872,6 @@ class TextLayer {
2744
2872
  }
2745
2873
  this.lines.push(this.renderTextParagraph(config.contentRange));
2746
2874
  }
2747
- scrollPages(config) {
2748
- DomHelper.translate(this.element, 0, -config.scrollTop);
2749
- const removedPages = this.config.pages.filter(x => !config.pages.includes(x));
2750
- this.removeEdgeComponents(removedPages);
2751
- const newPages = config.pages.filter(x => !this.config.pages.includes(x));
2752
- this.renderPagesEdgeComponents(newPages);
2753
- }
2754
2875
  scrollLines(config) {
2755
2876
  const oldConfig = this.config;
2756
2877
  this.config = config;
@@ -2778,56 +2899,50 @@ class TextLayer {
2778
2899
  this.lines.push(lines);
2779
2900
  }
2780
2901
  }
2781
- getEdgeParagraphTop(topOffset, page) {
2782
- const paragraphTop = this.session.displayData.pagesSpace + topOffset;
2783
- return paragraphTop + (page - 1) * (this.session.displayData.pageHeight + this.session.displayData.pagesSpace);
2784
- }
2785
2902
  getParagraphTop(row) {
2786
2903
  return this.session.displayData.getDistanceFromTop(row);
2787
2904
  }
2788
- renderPagesEdgeComponents(pages) {
2789
- const displayData = this.session.displayData;
2790
- for (let page of pages) {
2791
- const header = this.session.customComponents.edges.getComponentByPage(page, EdgeType.Header);
2792
- const headerHeight = this.session.customComponents.edges.getComponentHeight(page, EdgeType.Header);
2793
- if (header) {
2794
- 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;
2795
2916
  }
2796
- const footer = this.session.customComponents.edges.getComponentByPage(page, EdgeType.Footer);
2797
- const footerHeight = this.session.customComponents.edges.getComponentHeight(page, EdgeType.Footer);
2798
- if (footer) {
2799
- const topOffset = displayData.pageHeight - footerHeight;
2800
- 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;
2801
2928
  }
2929
+ this.renderEdgeComponent(footer, height, page, edgeTop);
2802
2930
  }
2803
2931
  }
2804
- renderEdgeComponent(edgeComponent, edgeHeight, page, topOffset = 0) {
2932
+ renderEdgeComponent(component, edgeHeight, page, edgeTop) {
2805
2933
  const container = RenderingHelper.createDivContainer('noder-edge-group');
2806
- let paragraphTop = this.getEdgeParagraphTop(topOffset, page);
2807
2934
  DomHelper.setStyle(container.style, 'height', `${edgeHeight}px`);
2808
- DomHelper.setStyle(container.style, 'top', `${paragraphTop}px`);
2809
- const componentElement = edgeComponent.hostView.rootNodes[0];
2810
- if (this.edgeEditingPage === page) {
2811
- componentElement.setAttribute('data-session-id', `${edgeComponent.instance.sessionId}`);
2812
- container.appendChild(componentElement);
2813
- this.element.appendChild(container);
2814
- this.edgeElements.push(new EdgeElementModel({ page, element: container, pageType: edgeComponent.instance.model.pageType }));
2815
- return;
2816
- }
2817
- const componentCopy = componentElement.cloneNode(true);
2818
- componentCopy.setAttribute('data-session-id', `${edgeComponent.instance.sessionId}`);
2819
- 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);
2820
2941
  this.element.appendChild(container);
2821
- this.edgeElements.push(new EdgeElementModel({ page, element: container, pageType: edgeComponent.instance.model.pageType }));
2822
- this.editorService.edgeElementCopyUpdated(componentCopy, page);
2823
- }
2824
- removeEdgeComponents(removedPages) {
2825
- let removeIndex = this.edgeElements.findIndex(x => removedPages.includes(x.page));
2826
- while (removeIndex !== -1) {
2827
- const removedElement = this.edgeElements[removeIndex];
2828
- DomHelper.removeElement(removedElement.element);
2829
- this.edgeElements.splice(removeIndex, 1);
2830
- 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)));
2831
2946
  }
2832
2947
  }
2833
2948
  renderTextParagraph(rowsDistance) {
@@ -2843,7 +2958,7 @@ class TextLayer {
2843
2958
  DomHelper.setStyle(paragraphCell.element.style, 'padding-left', `${this.session.displayData.pageMargin.left}px`);
2844
2959
  DomHelper.setStyle(paragraphCell.element.style, 'padding-right', `${this.session.displayData.pageMargin.right}px`);
2845
2960
  const paragraphSettings = this.session.displayData.getParagraphSettings(row);
2846
- if (paragraphSettings?.numberingData.numberingId !== null) {
2961
+ if (paragraphSettings.numberingData.numberingId !== null) {
2847
2962
  const numberingElement = this.renderingHelper.renderNumberingMarker(paragraphSettings, this.element, this.session.generalProperties.scalingRatio);
2848
2963
  numberingElement.className = 'numberingMarker';
2849
2964
  paragraphCell.element.appendChild(numberingElement);
@@ -2861,10 +2976,7 @@ class TextLayer {
2861
2976
  parent.appendChild(linesContainerElement);
2862
2977
  const startIndex = this.session.displayData.positionToIndex({ row, column: 0 });
2863
2978
  const endIndex = this.session.displayData.positionToIndex({ row: row + 1, column: 0 }) - 1;
2864
- const combinedFormats = FormatStyleHelper.combineSection(this.session.model.formats, this.session.model.links, startIndex, endIndex).map(x => new FormatExtModel({
2865
- ...x,
2866
- content: this.session.model.content.substring(x.startIndex, x.endIndex + 1)
2867
- }));
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) }));
2868
2980
  const splits = this.session.displayData.paragraphs[row].nextLineIndexes;
2869
2981
  if (splits?.length) {
2870
2982
  const distance = new DistanceModel({ start: startIndex, end: endIndex });
@@ -2889,11 +3001,11 @@ class PrintTextLayer extends TextLayer {
2889
3001
  }
2890
3002
 
2891
3003
  class PrintRenderer {
2892
- constructor(mainSession, editorService) {
3004
+ constructor(mainSession) {
2893
3005
  this.mainSession = mainSession;
2894
3006
  this.pagesCount = Math.round((mainSession.displayData.pagesSpace * 2 + mainSession.displayData.allPagesHeight) / mainSession.displayData.minHeight);
2895
3007
  this.createContent();
2896
- this.createLayers(editorService);
3008
+ this.createLayers();
2897
3009
  }
2898
3010
  renderPrintDocument() {
2899
3011
  const layerConfig = this.computeLayerConfig();
@@ -2922,8 +3034,8 @@ class PrintRenderer {
2922
3034
  this.content = document.createElement('div');
2923
3035
  this.content.className = 'noder-content print';
2924
3036
  }
2925
- createLayers(editorService) {
2926
- this.textLayer = new PrintTextLayer(this.content, this.mainSession, editorService, PrintRenderingHelper);
3037
+ createLayers() {
3038
+ this.textLayer = new PrintTextLayer(this.content, this.mainSession, PrintRenderingHelper);
2927
3039
  this.pagesLayer = new PrintPagesLayer(this.content, this.mainSession);
2928
3040
  }
2929
3041
  createDocumentHtml(layerConfig) {
@@ -2952,9 +3064,9 @@ class PrintRenderer {
2952
3064
  }
2953
3065
 
2954
3066
  class PrintHelper extends RenderingHelper {
2955
- static printDocument(session, editorService) {
3067
+ static printDocument(session) {
2956
3068
  this.removePrintContainers();
2957
- const renderer = new PrintRenderer(session, editorService);
3069
+ const renderer = new PrintRenderer(session);
2958
3070
  renderer.renderPrintDocument();
2959
3071
  this.printDocumentHtml(renderer.documentHtml);
2960
3072
  }
@@ -3316,7 +3428,8 @@ class SaveCommandsHelper {
3316
3428
  paragraphs: restoreModel.paragraphs,
3317
3429
  tables: restoreModel.tables,
3318
3430
  tabs: restoreModel.tabs,
3319
- text: restoreModel.text
3431
+ text: restoreModel.text,
3432
+ links: restoreModel.links
3320
3433
  });
3321
3434
  return new CommandModel({ commandType: CommandType.Restore, restore, targets });
3322
3435
  }
@@ -3995,7 +4108,7 @@ class Editor {
3995
4108
  this.session.applyToolbarStyles();
3996
4109
  this.search = new Search();
3997
4110
  this.search.set({ wrap: true });
3998
- 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());
3999
4112
  }
4000
4113
  destroy() {
4001
4114
  this.subscriptions.forEach(s => s?.unsubscribe());
@@ -4407,7 +4520,7 @@ class Editor {
4407
4520
  }
4408
4521
  else if (operation instanceof RestoreTextStylesModel) {
4409
4522
  const deepCopy = structuredClone(operation);
4410
- this.session.restoreTextStyles(deepCopy.formats);
4523
+ this.session.restoreTextStyles(deepCopy.formats, deepCopy.linkFormats);
4411
4524
  command = SaveCommandsHelper.getRestoreTextStylesCommand(deepCopy.formats, this.targets);
4412
4525
  }
4413
4526
  else if (operation instanceof RestoreParagraphStylesModel) {
@@ -4435,6 +4548,10 @@ class Editor {
4435
4548
  this.session.insertImageByDocumentIndex(operation);
4436
4549
  command = SaveCommandsHelper.getInsertImageCommand(operation, this.targets);
4437
4550
  }
4551
+ else if (operation instanceof InsertLinkModel) {
4552
+ this.session.insertLinkByDocumentIndex(operation);
4553
+ command = SaveCommandsHelper.getInsertLinkOperation(operation, this.targets);
4554
+ }
4438
4555
  else if (operation instanceof ApplyImageStyleModel) {
4439
4556
  this.session.applyImageStyle(operation);
4440
4557
  const { height, width, insertIndex } = operation;
@@ -4553,7 +4670,8 @@ class Editor {
4553
4670
  }
4554
4671
  saveApplyTextStyleToHistory(startIndex, endIndex, textStyle) {
4555
4672
  const formats = FormatHelper.sliceSection(this.session.model.formats, startIndex, endIndex);
4556
- 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);
4557
4675
  this.commandsService.createCommand(SaveCommandsHelper.getApplyTextStyleCommand(startIndex, endIndex, textStyle, this.targets));
4558
4676
  }
4559
4677
  saveApplyParagraphStyleToHistory(startIndex, endIndex, paragraphStyle) {
@@ -4590,7 +4708,14 @@ class Editor {
4590
4708
  }
4591
4709
  saveReplaceToHistory(range, model) {
4592
4710
  const restoreModel = this.createRestoreFromSlice(range.start.row, range.start.column, range.end.row, range.end.column);
4593
- 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
+ }
4594
4719
  this.history.pushReplace(restoreModel, model);
4595
4720
  this.commandsService.createCommand(SaveCommandsHelper.getReplaceCommand(model, this.targets));
4596
4721
  }
@@ -4606,7 +4731,7 @@ class Editor {
4606
4731
  const breaks = IndexedElementHelper.sliceSection(this.session.model.breaks, startIndex, endIndex).map(x => new BreakModel(x));
4607
4732
  const tabs = IndexedElementHelper.sliceSection(this.session.model.tabs, startIndex, endIndex).map(x => new TabModel(x));
4608
4733
  const links = LinkHelper.sliceSection(this.session.model.links, startIndex, endIndex).map(x => new LinkModel(x));
4609
- 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 });
4610
4735
  }
4611
4736
  createCustomElement(data) {
4612
4737
  const insertIndex = ContentHelper.paragraphToDocumentIndex(this.session.displayData.paragraphs, this.selection.range.start.row, this.selection.range.start.column);
@@ -4701,8 +4826,8 @@ class Editor {
4701
4826
  this.renderer.showCursor();
4702
4827
  }
4703
4828
  onMouseClick(event) {
4704
- const customElement = this.setCurrentSession(event.clientY, event.target);
4705
- if (customElement && customElement.tagName !== this.tableCellTagName) {
4829
+ const customElement = this.setCurrentSession(event.target);
4830
+ if (customElement && customElement.tagName !== this.tableCellTagName && customElement.tagName !== this.edgeElementTagName) {
4706
4831
  this.focusCustomComponent(customElement);
4707
4832
  }
4708
4833
  else {
@@ -4710,8 +4835,8 @@ class Editor {
4710
4835
  }
4711
4836
  }
4712
4837
  onLeftClick(event) {
4713
- const customElement = this.setCurrentSession(event.clientY, event.target);
4714
- if (customElement && customElement.tagName !== this.tableCellTagName) {
4838
+ const customElement = this.setCurrentSession(event.target);
4839
+ if (customElement && customElement.tagName !== this.tableCellTagName && customElement.tagName !== this.edgeElementTagName) {
4715
4840
  this.focusCustomComponent(customElement);
4716
4841
  return;
4717
4842
  }
@@ -4719,14 +4844,14 @@ class Editor {
4719
4844
  if (!this.textInput.isFocused) {
4720
4845
  this.textInput.input.focus();
4721
4846
  }
4722
- const position = this.renderer.screenToTextCoordinates(event.clientX, event.clientY);
4847
+ const position = this.renderer.screenToTextCoordinatesUsingMidpoint(event.clientX, event.clientY);
4723
4848
  if (event.shiftKey) {
4724
4849
  this.selection.moveSelection(position);
4725
4850
  }
4726
4851
  else if (event.ctrlKey) {
4727
- const linkModel = this.session.getLinkModel(position);
4728
- if (linkModel) {
4729
- window.open(linkModel.link);
4852
+ const link = this.getLinkModel(event);
4853
+ if (link) {
4854
+ window.open(link.link);
4730
4855
  event.preventDefault();
4731
4856
  return;
4732
4857
  }
@@ -4739,17 +4864,11 @@ class Editor {
4739
4864
  this.mouseHandler.startMousePress(this);
4740
4865
  }
4741
4866
  onDoubleClick(event) {
4742
- let isStartEditEdge = false;
4867
+ const isEdgeEdit = this.mainSession.customComponents.edges.isEdit;
4743
4868
  const customElement = this.getCustomElement(event.target);
4744
4869
  if (customElement) {
4745
4870
  const elementSessionId = +customElement.attributes.getNamedItem('data-session-id').value;
4746
- let clickedPage = null;
4747
- const isParentEdge = this.isParentEdge(customElement);
4748
- if (customElement.tagName === this.edgeElementTagName || (isParentEdge && !this.regulatorService.edgeEditingPage)) {
4749
- clickedPage = this.getClickedPage(event.clientY);
4750
- isStartEditEdge = !this.regulatorService.edgeEditingPage;
4751
- }
4752
- this.regulatorService.setCustomSessionAsCurrent(elementSessionId, clickedPage);
4871
+ this.regulatorService.setCustomSessionAsCurrent(elementSessionId);
4753
4872
  }
4754
4873
  else {
4755
4874
  this.regulatorService.setMainSessionAsCurrent();
@@ -4760,8 +4879,8 @@ class Editor {
4760
4879
  }
4761
4880
  this.blurCustomComponent();
4762
4881
  event.preventDefault();
4763
- const position = this.renderer.screenToTextCoordinates(event.clientX, event.clientY);
4764
- if (isStartEditEdge) {
4882
+ const position = this.renderer.screenToTextCoordinatesUsingMidpoint(event.clientX, event.clientY);
4883
+ if (!isEdgeEdit && this.mainSession.customComponents.edges.isEdit) {
4765
4884
  this.selection.placeCursor(position);
4766
4885
  }
4767
4886
  else {
@@ -4771,22 +4890,22 @@ class Editor {
4771
4890
  this.onSelectionChange();
4772
4891
  }
4773
4892
  onTripleClick(event) {
4774
- const customElement = this.setCurrentSession(event.clientY, event.target);
4775
- if (customElement && customElement.tagName !== this.tableCellTagName) {
4893
+ const customElement = this.setCurrentSession(event.target);
4894
+ if (customElement && customElement.tagName !== this.tableCellTagName && customElement.tagName !== this.edgeElementTagName) {
4776
4895
  this.focusCustomComponent(customElement);
4777
4896
  return;
4778
4897
  }
4779
4898
  this.blurCustomComponent();
4780
4899
  event.preventDefault();
4781
- const position = this.renderer.screenToTextCoordinates(event.clientX, event.clientY);
4900
+ const position = this.renderer.screenToTextCoordinatesUsingMidpoint(event.clientX, event.clientY);
4782
4901
  const start = new CursorParagraph(position.row, 0);
4783
4902
  const end = new CursorParagraph(position.row, this.session.displayData.getParagraphContent(position.row).length);
4784
4903
  this.selection.placeSelection(start, end);
4785
4904
  this.onSelectionChange();
4786
4905
  }
4787
4906
  onQuadClick(event) {
4788
- const customElement = this.setCurrentSession(event.clientY, event.target);
4789
- if (customElement && customElement.tagName !== this.tableCellTagName) {
4907
+ const customElement = this.setCurrentSession(event.target);
4908
+ if (customElement && customElement.tagName !== this.tableCellTagName && customElement.tagName !== this.edgeElementTagName) {
4790
4909
  this.focusCustomComponent(customElement);
4791
4910
  return;
4792
4911
  }
@@ -4806,44 +4925,33 @@ class Editor {
4806
4925
  event.stopPropagation();
4807
4926
  event.preventDefault();
4808
4927
  }
4809
- 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) {
4810
4942
  const customElement = this.getCustomElement(element);
4811
- this.blurEdgeCustomComponents(customElement);
4812
- if (!customElement) {
4943
+ const isInsideEdge = this.isInsideEdge(customElement);
4944
+ const isEdgeEdit = this.mainSession.customComponents.edges.isEdit;
4945
+ if (!customElement || (!isEdgeEdit && isInsideEdge)) {
4813
4946
  this.regulatorService.setMainSessionAsCurrent();
4947
+ return this.customElementTagNames.includes(customElement?.tagName) ? customElement : null;
4814
4948
  }
4815
- else {
4816
- const elementSessionId = +customElement.attributes.getNamedItem('data-session-id').value;
4817
- const isEdgeEditing = this.regulatorService.edgeEditingPage;
4818
- if (customElement.tagName === this.edgeElementTagName) {
4819
- if (isEdgeEditing) {
4820
- const clickedPage = this.getClickedPage(clickPositionY);
4821
- this.regulatorService.setCustomSessionAsCurrent(elementSessionId, clickedPage);
4822
- }
4823
- else {
4824
- this.regulatorService.setMainSessionAsCurrent();
4825
- }
4826
- }
4827
- else {
4828
- const isParentEdge = this.isParentEdge(customElement);
4829
- if (!isParentEdge) {
4830
- this.regulatorService.setCustomSessionAsCurrent(elementSessionId);
4831
- return customElement;
4832
- }
4833
- if (isEdgeEditing) {
4834
- const clickedPage = this.getClickedPage(clickPositionY);
4835
- this.regulatorService.setCustomSessionAsCurrent(elementSessionId, clickedPage);
4836
- return customElement;
4837
- }
4838
- else {
4839
- this.regulatorService.setMainSessionAsCurrent();
4840
- }
4841
- }
4842
- }
4843
- 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;
4844
4952
  }
4845
4953
  getCustomElement(element) {
4846
- if (element.tagName === this.parentTagName) {
4954
+ if (!element || element.tagName === this.parentTagName) {
4847
4955
  return null;
4848
4956
  }
4849
4957
  else if (this.customElementTagNames.includes(element.tagName)) {
@@ -4853,21 +4961,20 @@ class Editor {
4853
4961
  return this.getCustomElement(element.parentElement);
4854
4962
  }
4855
4963
  }
4856
- isParentEdge(element) {
4857
- if (element.tagName === this.parentTagName) {
4858
- return false;
4964
+ isInsideEdge(element) {
4965
+ return !!this.getParentEdge(element);
4966
+ }
4967
+ getParentEdge(element) {
4968
+ if (!element || element.tagName === this.parentTagName) {
4969
+ return null;
4859
4970
  }
4860
4971
  else if (element.tagName === this.edgeElementTagName) {
4861
- return true;
4972
+ return element;
4862
4973
  }
4863
4974
  else {
4864
- return this.isParentEdge(element.parentElement);
4975
+ return this.getParentEdge(element.parentElement);
4865
4976
  }
4866
4977
  }
4867
- getClickedPage(mousePosition) {
4868
- const positionY = mousePosition + this.mainSession.scrollTop - this.mainRenderer.container.getBoundingClientRect().top;
4869
- return PositionHelper.pixelToPage(positionY, this.mainSession);
4870
- }
4871
4978
  /**
4872
4979
  * Returns the string of text currently highlighted.
4873
4980
  */
@@ -4922,7 +5029,7 @@ class Editor {
4922
5029
  this.editorService.keyDown(event);
4923
5030
  }
4924
5031
  onPrint() {
4925
- PrintHelper.printDocument(this.mainSession, this.editorService);
5032
+ PrintHelper.printDocument(this.mainSession);
4926
5033
  }
4927
5034
  focusCustomComponent(element) {
4928
5035
  const index = +element.attributes.getNamedItem('data-insert-index').value;
@@ -4945,25 +5052,6 @@ class Editor {
4945
5052
  this.focusedComponent = null;
4946
5053
  }
4947
5054
  }
4948
- blurEdgeCustomComponents(customElement) {
4949
- if (!this.regulatorService.edgeEditingPage || !this.focusedComponent) {
4950
- return;
4951
- }
4952
- if (!customElement ||
4953
- customElement.tagName === this.tableCellTagName ||
4954
- customElement.tagName === this.edgeElementTagName ||
4955
- +customElement.attributes.getNamedItem('data-session-id').value !== this.focusedComponent.instance.sessionId) {
4956
- this.blurCustomComponent();
4957
- return;
4958
- }
4959
- const index = +customElement.attributes.getNamedItem('data-insert-index').value;
4960
- const component = this.session.customComponents.images.find(x => x.instance.insertIndex === index) ??
4961
- this.session.customComponents.tables.find(x => x.instance.insertIndex === index) ??
4962
- this.session.customComponents.customElements.find(x => x.instance.insertIndex === index);
4963
- if (this.focusedComponent !== component) {
4964
- this.blurCustomComponent();
4965
- }
4966
- }
4967
5055
  isEmptyNumberingParagraph(paragraphIndex) {
4968
5056
  const currentLine = this.session.displayData.getParagraphContent(paragraphIndex);
4969
5057
  return currentLine.length === 0 && this.session.model.paragraphs[paragraphIndex].paragraphStyle.numberingId !== null;
@@ -5037,8 +5125,8 @@ class Editor {
5037
5125
  this.session.resizeTableColumns(resizeTableColumns);
5038
5126
  this.changedTableSize(resizeTableColumns.insertIndex, sessionId);
5039
5127
  }
5040
- onMousePressedMove(x, y) {
5041
- const position = this.renderer.screenToTextCoordinates(x, y);
5128
+ onMousePressedMove(event) {
5129
+ const position = this.renderer.screenToTextCoordinatesUsingMidpoint(event.clientX, event.clientY);
5042
5130
  const cursor = this.selection.cursor;
5043
5131
  this.selection.moveSelection(position);
5044
5132
  if (cursor.column !== this.selection.cursor.column || cursor.row !== this.selection.cursor.row) {
@@ -5129,6 +5217,15 @@ class Editor {
5129
5217
  this.changedTableSize(data.insertIndex, data.sessionId);
5130
5218
  });
5131
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
+ }
5132
5229
  insertTableRowsSubscription() {
5133
5230
  return this.editorService.insertTableRows$.subscribe(data => {
5134
5231
  this.insertTableRows(data.insertIndex, data.rowsCount, data.targetIndex, data.inheritIndex, data.sessionId);
@@ -5171,29 +5268,6 @@ class Editor {
5171
5268
  this.focus();
5172
5269
  });
5173
5270
  }
5174
- rendererUpdatedSubscription() {
5175
- return this.editorService.rendererUpdated$.subscribe(sessionId => {
5176
- const edgeTarget = this.regulatorService.getEdgeTarget(sessionId);
5177
- if (edgeTarget !== null) {
5178
- this.mainRenderer.renderer.textLayer.updateEdgeByLocation(edgeTarget.edgeData.pageType);
5179
- }
5180
- });
5181
- }
5182
- edgeElementCopyUpdatedSubscription() {
5183
- return this.editorService.edgeElementCopyUpdated$.subscribe(data => {
5184
- if (this.regulatorService.edgeEditingPage !== data.page) {
5185
- return;
5186
- }
5187
- const edgeSessionId = +data.newElementCopy.attributes.getNamedItem('data-session-id').value;
5188
- const edgeSession = this.regulatorService.sessions.find(x => x.sessionId === edgeSessionId);
5189
- edgeSession.renderer.container = data.newElementCopy.firstChild;
5190
- });
5191
- }
5192
- changedEdgeHeightSubscription() {
5193
- return this.editorService.changedEdgeHeight$.subscribe(edgeType => {
5194
- this.mainSession.displayData.updatePageVerticalData(edgeType, this.regulatorService.edgeEditingPage);
5195
- });
5196
- }
5197
5271
  undoSubscription() {
5198
5272
  return this.editorService.undo$.subscribe(() => {
5199
5273
  this.undo();
@@ -5492,7 +5566,6 @@ class CellSessionSourceModel {
5492
5566
  constructor(table, cellComponent) {
5493
5567
  this.table = table;
5494
5568
  this.cellComponent = cellComponent;
5495
- this.edgeEditPage = null;
5496
5569
  }
5497
5570
  getTarget() {
5498
5571
  const tableCell = new TableCellModel({
@@ -5500,7 +5573,7 @@ class CellSessionSourceModel {
5500
5573
  row: this.cellComponent.rowIndex,
5501
5574
  column: this.cellComponent.cellIndex
5502
5575
  });
5503
- return new TargetModel({ type: TargetType.TableCell, tableCell, edgeEditPage: this.edgeEditPage });
5576
+ return new TargetModel({ type: TargetType.TableCell, tableCell });
5504
5577
  }
5505
5578
  }
5506
5579
 
@@ -5781,8 +5854,7 @@ class NoderTableCellComponent {
5781
5854
  return;
5782
5855
  }
5783
5856
  this._allParagraphsHeight = event.pageHeight;
5784
- const cellContentHeight = this._allParagraphsHeight;
5785
- this.heightChanged(this.rowIndex, this.cellIndex, cellContentHeight);
5857
+ this.heightChanged(this.rowIndex, this.cellIndex, event.pageHeight);
5786
5858
  };
5787
5859
  }
5788
5860
  ngOnDestroy() {
@@ -5810,6 +5882,9 @@ class NoderTableCellComponent {
5810
5882
  this.editorService.disableSelection();
5811
5883
  }
5812
5884
  onStartResizing(event, border) {
5885
+ if (this.session.isWithinEdge() && !this.regulatorService.mainSession.session.customComponents.edges.isEdit) {
5886
+ return;
5887
+ }
5813
5888
  event.stopPropagation();
5814
5889
  this.startResizing(new CellResizerParametersModel(this.columnIndex, this.rowIndex, this.cellIndex, border));
5815
5890
  }
@@ -5986,13 +6061,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
5986
6061
  }] } });
5987
6062
 
5988
6063
  class TableSelection {
5989
- constructor(editorService, overlayService, rowMatrix, table, tableEl, sessionId) {
6064
+ constructor(editorService, overlayService, regulatorService, rowMatrix, table, tableEl, session) {
5990
6065
  this.editorService = editorService;
5991
6066
  this.overlayService = overlayService;
6067
+ this.regulatorService = regulatorService;
5992
6068
  this.rowMatrix = rowMatrix;
5993
6069
  this.table = table;
5994
6070
  this.tableEl = tableEl;
5995
- this.sessionId = sessionId;
6071
+ this.session = session;
5996
6072
  this.editorTagName = 'APP-NOD-EDITOR';
5997
6073
  this.tableTagName = 'APP-NOD-TABLE';
5998
6074
  this.cellTagName = 'TD';
@@ -6011,6 +6087,9 @@ class TableSelection {
6011
6087
  }
6012
6088
  addTableContextMenuSubscriptions() {
6013
6089
  this.tableContextMenu$ = fromEvent(this.tableEl, 'contextmenu').subscribe((event) => {
6090
+ if (this.session.isEdgeOrWithinEdge() && !this.regulatorService.mainSession.session.customComponents.edges.isEdit) {
6091
+ return;
6092
+ }
6014
6093
  event.preventDefault();
6015
6094
  if (this.editorService.isViewOnly) {
6016
6095
  return;
@@ -6028,13 +6107,16 @@ class TableSelection {
6028
6107
  canRemoveRows,
6029
6108
  canRemoveColumns,
6030
6109
  tableInsertIndex: this.table.insertIndex,
6031
- sessionId: this.sessionId
6110
+ sessionId: this.session.sessionId
6032
6111
  };
6033
6112
  this.overlayService.open(TableOverlayMenuComponent, data, event.x, event.y);
6034
6113
  });
6035
6114
  }
6036
6115
  addTableMouseDownSubscriptions() {
6037
6116
  this.tableMouseDown$ = fromEvent(this.tableEl, 'mousedown').subscribe((event) => {
6117
+ if (this.session.isEdgeOrWithinEdge() && !this.regulatorService.mainSession.session.customComponents.edges.isEdit) {
6118
+ return;
6119
+ }
6038
6120
  if (event.ctrlKey ||
6039
6121
  event.button === MouseButton.Right ||
6040
6122
  !this.canStartSelection(event.target)) {
@@ -6245,7 +6327,7 @@ class TableSelection {
6245
6327
  break;
6246
6328
  }
6247
6329
  if (currentElement.tagName === this.tableTagName) {
6248
- canStartSelection = this.sessionId === +currentElement.getAttribute('data-session-id');
6330
+ canStartSelection = this.session.sessionId === +currentElement.getAttribute('data-session-id');
6249
6331
  break;
6250
6332
  }
6251
6333
  currentElement = currentElement.parentElement;
@@ -6370,12 +6452,13 @@ class NoderTableComponent extends BaseNoderComponent {
6370
6452
  set table(val) {
6371
6453
  this.content = val;
6372
6454
  }
6373
- constructor(componentService, editorService, el, overlayService) {
6455
+ constructor(componentService, editorService, el, overlayService, regulatorService) {
6374
6456
  super();
6375
6457
  this.componentService = componentService;
6376
6458
  this.editorService = editorService;
6377
6459
  this.el = el;
6378
6460
  this.overlayService = overlayService;
6461
+ this.regulatorService = regulatorService;
6379
6462
  this.rowMatrix = [];
6380
6463
  this.splits = [];
6381
6464
  this.minRowHeight = 19;
@@ -6418,7 +6501,7 @@ class NoderTableComponent extends BaseNoderComponent {
6418
6501
  this.createResizer();
6419
6502
  this.el.nativeElement.appendChild(this.resizerEl);
6420
6503
  this.el.nativeElement.appendChild(this.tableEl);
6421
- 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));
6422
6505
  }
6423
6506
  getCellSession(row, column) {
6424
6507
  return this.rowMatrix[row].cells[column].componentRef.instance.session;
@@ -6751,13 +6834,13 @@ class NoderTableComponent extends BaseNoderComponent {
6751
6834
  }
6752
6835
  }
6753
6836
  }
6754
- 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 }); }
6755
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 }); }
6756
6839
  }
6757
6840
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NoderTableComponent, decorators: [{
6758
6841
  type: Component,
6759
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"] }]
6760
- }], ctorParameters: () => [{ type: ComponentService }, { type: EditorService }, { type: i0.ElementRef }, { type: OverlayService }] });
6843
+ }], ctorParameters: () => [{ type: ComponentService }, { type: EditorService }, { type: i0.ElementRef }, { type: OverlayService }, { type: RegulatorService }] });
6761
6844
 
6762
6845
  class NumberingDataModel {
6763
6846
  constructor(fields) {
@@ -7310,9 +7393,9 @@ class DisplayData extends EventEmitting {
7310
7393
  destroy() {
7311
7394
  this.removeAllListeners('pagesCountChanged');
7312
7395
  }
7313
- updatePageVerticalData(edgeType, page) {
7314
- const pageVerticalData = PageHelper.getVerticalData(page, this.pagesVerticalData);
7315
- 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);
7316
7399
  if (edgeType === EdgeType.Header) {
7317
7400
  pageVerticalData.marginTop = componentHeight > this.pageMargin.top ? componentHeight : this.pageMargin.top;
7318
7401
  }
@@ -7922,53 +8005,57 @@ class NoderEdgeComponent extends DestroyComponent {
7922
8005
  get renderer() {
7923
8006
  return this.edgeSession.renderer;
7924
8007
  }
7925
- get height() {
8008
+ get contentHeight() {
7926
8009
  return this.session.displayData.defaultVerticalData.contentHeight;
7927
8010
  }
7928
8011
  constructor(regulatorService, editorService) {
7929
8012
  super();
7930
8013
  this.regulatorService = regulatorService;
7931
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
+ };
7932
8023
  }
7933
8024
  ngOnDestroy() {
8025
+ this.session?.displayData.removeEventListener('pagesCountChanged', this.pagesCountChangedHandler);
7934
8026
  this.regulatorService.removeSession(this.sessionId);
7935
8027
  super.ngOnDestroy();
7936
8028
  }
7937
8029
  initialize() {
7938
8030
  this.edgeSession = this.regulatorService.addEdgeSession(this);
7939
8031
  this.sessionId = this.edgeSession.sessionId;
7940
- this._previousHeight = this.height;
8032
+ this.container.nativeElement.parentElement.setAttribute('data-session-id', `${this.sessionId}`);
7941
8033
  DomHelper.setStyle(this.container.nativeElement.style, 'overflow', 'hidden');
7942
8034
  DomHelper.setStyle(this.typeContainer.nativeElement.style, 'visibility', 'hidden');
7943
- this.setTypeContainerPosition();
7944
- this.editorService.rendererUpdated$.pipe(takeUntil(this.destroy$)).subscribe(x => this.rendererUpdated(x));
8035
+ this.applyHeight();
8036
+ this.session.displayData.addEventListener('pagesCountChanged', this.pagesCountChangedHandler);
7945
8037
  }
7946
8038
  enterEditMode() {
7947
8039
  DomHelper.addCssClass(this.container.nativeElement, this.editModeClass);
7948
8040
  DomHelper.setStyle(this.typeContainer.nativeElement.style, 'visibility', 'visible');
8041
+ this.editorService.changedEdge(this.sessionId);
7949
8042
  }
7950
8043
  leaveEditMode() {
7951
8044
  DomHelper.removeCssClass(this.container.nativeElement, this.editModeClass);
7952
8045
  DomHelper.setStyle(this.typeContainer.nativeElement.style, 'visibility', 'hidden');
8046
+ this.editorService.changedEdge(this.sessionId);
7953
8047
  }
7954
- rendererUpdated(sessionId) {
7955
- if (sessionId !== this.sessionId || this.height === this._previousHeight) {
7956
- return;
7957
- }
7958
- this.editorService.changedEdgeHeight(this.type);
7959
- this._previousHeight = this.height;
7960
- this.setTypeContainerPosition();
7961
- }
7962
- setTypeContainerPosition() {
7963
- const renderedEdgeHeight = this.height > this.generalProperties.maxEdgeHeight ? this.generalProperties.maxEdgeHeight : this.height;
7964
- 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`);
7965
8052
  }
7966
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 }); }
7967
- 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 }); }
7968
8055
  }
7969
8056
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NoderEdgeComponent, decorators: [{
7970
8057
  type: Component,
7971
- 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"] }]
7972
8059
  }], ctorParameters: () => [{ type: RegulatorService }, { type: EditorService }], propDecorators: { model: [{
7973
8060
  type: Input
7974
8061
  }], generalProperties: [{
@@ -7981,9 +8068,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
7981
8068
  type: Input
7982
8069
  }], type: [{
7983
8070
  type: Input
7984
- }], sessionId: [{
7985
- type: HostBinding,
7986
- args: ['attr.data-session-id']
7987
8071
  }], container: [{
7988
8072
  type: ViewChild,
7989
8073
  args: ['container', { static: true }]
@@ -7992,31 +8076,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
7992
8076
  args: ['locationType', { static: true }]
7993
8077
  }] } });
7994
8078
 
7995
- class RenderChangesModel {
7996
- get any() {
7997
- return this.cursor || this.full || this.lines || this.marker || this.selection || this.scroll || this.size || this.text;
7998
- }
7999
- constructor(fields) {
8000
- this.cursor = false;
8001
- this.full = false;
8002
- this.lines = false;
8003
- this.marker = false;
8004
- this.selection = false;
8005
- this.scroll = false;
8006
- this.size = false;
8007
- this.text = false;
8008
- if (!fields) {
8009
- return;
8010
- }
8011
- Object.assign(this, fields);
8012
- }
8013
- apply(changes) {
8014
- for (let key of Object.keys(this)) {
8015
- this[key] ||= changes[key];
8016
- }
8017
- }
8018
- }
8019
-
8020
8079
  class Edges {
8021
8080
  constructor(componentService, headers, footers, margins, pageWidth, parentSessionId, generalProperties) {
8022
8081
  this.componentService = componentService;
@@ -8024,6 +8083,7 @@ class Edges {
8024
8083
  this.generalProperties = generalProperties;
8025
8084
  this.headersComponents = [];
8026
8085
  this.footersComponents = [];
8086
+ this.isEdit = false;
8027
8087
  if (headers) {
8028
8088
  const headerMargins = new MarginModel({ ...margins, bottom: 0 });
8029
8089
  this.headersComponents = this.createComponents(headers, pageWidth, headerMargins, EdgeType.Header);
@@ -8034,6 +8094,14 @@ class Edges {
8034
8094
  }
8035
8095
  this.setEdgeNameToComponents();
8036
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
+ }
8037
8105
  getComponentByPage(page, type) {
8038
8106
  const components = type === EdgeType.Header ? this.headersComponents : this.footersComponents;
8039
8107
  return this.getComponent(components, page);
@@ -8047,24 +8115,32 @@ class Edges {
8047
8115
  if (!component) {
8048
8116
  return 0;
8049
8117
  }
8050
- return component.instance.height > this.generalProperties.maxEdgeHeight
8118
+ return component.instance.contentHeight > this.generalProperties.maxEdgeHeight
8051
8119
  ? this.generalProperties.maxEdgeHeight
8052
- : component.instance.height;
8120
+ : component.instance.contentHeight;
8121
+ }
8122
+ getComponentHeight(instance) {
8123
+ const height = instance.contentHeight;
8124
+ return height > this.generalProperties.maxEdgeHeight ? this.generalProperties.maxEdgeHeight : height;
8053
8125
  }
8054
- getComponentHeight(page, type) {
8126
+ getComponentHeightByType(pageType, type) {
8055
8127
  const components = type === EdgeType.Header ? this.headersComponents : this.footersComponents;
8056
- const component = this.getComponent(components, page);
8057
- if (!component) {
8058
- return 0;
8059
- }
8060
- return component.instance.height > this.generalProperties.maxEdgeHeight
8061
- ? this.generalProperties.maxEdgeHeight
8062
- : 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;
8063
8130
  }
8064
- toggleEditMode(needEnable) {
8131
+ toggleEditMode(isEdit) {
8132
+ if (this.isEdit === isEdit) {
8133
+ return;
8134
+ }
8135
+ this.isEdit = isEdit;
8065
8136
  const edgeComponents = [...this.headersComponents, ...this.footersComponents];
8066
8137
  for (let component of edgeComponents) {
8067
- needEnable ? component.instance.enterEditMode() : component.instance.leaveEditMode();
8138
+ if (isEdit) {
8139
+ component.instance.enterEditMode();
8140
+ }
8141
+ else {
8142
+ component.instance.leaveEditMode();
8143
+ }
8068
8144
  }
8069
8145
  }
8070
8146
  getUniquePageTypes() {
@@ -8101,7 +8177,6 @@ class Edges {
8101
8177
  generalProperties: this.generalProperties,
8102
8178
  parentSessionId: this.parentSessionId
8103
8179
  });
8104
- componentRef.instance.renderer.renderChanges(new RenderChangesModel({ text: true }));
8105
8180
  resultComponents.push(componentRef);
8106
8181
  }
8107
8182
  return resultComponents;
@@ -8143,11 +8218,10 @@ class EdgeSessionSourceModel {
8143
8218
  constructor(pageType, type) {
8144
8219
  this.pageType = pageType;
8145
8220
  this.type = type;
8146
- this.edgeEditPage = null;
8147
8221
  }
8148
8222
  getTarget() {
8149
8223
  const edgeData = new EdgeTargetModel({ pageType: this.pageType, type: this.type });
8150
- return new TargetModel({ type: TargetType.Edge, edgeData, edgeEditPage: this.edgeEditPage });
8224
+ return new TargetModel({ type: TargetType.Edge, edgeData });
8151
8225
  }
8152
8226
  }
8153
8227
 
@@ -8217,7 +8291,7 @@ class ImageInputHandler {
8217
8291
  return;
8218
8292
  }
8219
8293
  const keyCombination = this.getKeyCombination(event);
8220
- if (this.undoRedoActions[keyCombination] && !this.editorService.isViewOnly) {
8294
+ if (this.undoRedoActions[keyCombination]) {
8221
8295
  this.undoRedoActions[keyCombination]();
8222
8296
  event.preventDefault();
8223
8297
  return;
@@ -8459,7 +8533,7 @@ class NoderImageComponent extends BaseNoderComponent {
8459
8533
  const fileSource = URL.createObjectURL(x);
8460
8534
  const image = this.createImage(fileSource);
8461
8535
  this.elementRef.nativeElement.appendChild(image);
8462
- this.editorService.rendererUpdated(this.sessionId);
8536
+ this.editorService.imageLoaded(this.sessionId);
8463
8537
  });
8464
8538
  }
8465
8539
  onResizeEnd(size) {
@@ -8688,7 +8762,7 @@ class FormatOperationsHelper {
8688
8762
  firstIndex++;
8689
8763
  }
8690
8764
  let lastIndex = firstIndex;
8691
- while (formats[lastIndex].endIndex < endIndex) {
8765
+ while (lastIndex < formats.length - 1 && formats[lastIndex].endIndex < endIndex) {
8692
8766
  lastIndex++;
8693
8767
  }
8694
8768
  if (formats[lastIndex].endIndex > endIndex) {
@@ -8725,13 +8799,13 @@ class ImageOperationsHelper {
8725
8799
  }
8726
8800
 
8727
8801
  class LinkOperationsHelper {
8728
- static insert(links, link, startIndex, endIndex, textStyle) {
8802
+ static insert(links, link, startIndex, endIndex, linkStyle) {
8729
8803
  LinkOperationsHelper.insertContent(links, startIndex, endIndex - startIndex + 1);
8730
8804
  const linkModel = new LinkModel({
8731
8805
  startIndex: startIndex,
8732
8806
  link,
8733
8807
  endIndex,
8734
- formats: [new FormatModel({ startIndex: 0, endIndex: endIndex - startIndex, textStyle })]
8808
+ formats: [new FormatModel({ startIndex: 0, endIndex: endIndex - startIndex, textStyle: linkStyle })]
8735
8809
  });
8736
8810
  const index = links.findIndex(x => x.startIndex > linkModel.startIndex);
8737
8811
  if (index < 0) {
@@ -8741,6 +8815,10 @@ class LinkOperationsHelper {
8741
8815
  links.splice(index, 0, linkModel);
8742
8816
  }
8743
8817
  }
8818
+ static insertStyledContent(links, index, textLength, style) {
8819
+ this.insertContent(links, index, textLength);
8820
+ this.apply(links, index, index + textLength - 1, style);
8821
+ }
8744
8822
  static insertContent(links, insertIndex, textLength) {
8745
8823
  for (let link of links) {
8746
8824
  if (link.startIndex < insertIndex && link.endIndex >= insertIndex) {
@@ -8770,13 +8848,13 @@ class LinkOperationsHelper {
8770
8848
  }
8771
8849
  if (links[i].startIndex <= startIndex && links[i].endIndex >= endIndex) {
8772
8850
  const startInLink = startIndex - links[i].startIndex;
8773
- const endInLink = startInLink + length - 1;
8851
+ const endInLink = endIndex - links[i].startIndex;
8774
8852
  links[i].endIndex -= length;
8775
8853
  FormatOperationsHelper.removeContent(links[i].formats, startInLink, endInLink);
8776
8854
  continue;
8777
8855
  }
8778
8856
  if (links[i].startIndex >= startIndex && links[i].startIndex <= endIndex) {
8779
- const endInLink = links[i].startIndex - startIndex - 1;
8857
+ const endInLink = endIndex - links[i].startIndex;
8780
8858
  links[i].startIndex = startIndex;
8781
8859
  links[i].endIndex -= length;
8782
8860
  FormatOperationsHelper.removeContent(links[i].formats, 0, endInLink);
@@ -8790,16 +8868,63 @@ class LinkOperationsHelper {
8790
8868
  }
8791
8869
  }
8792
8870
  }
8793
- static restore(links, startIndex, contentLength, newlinks) {
8871
+ static restore(links, startIndex, contentLength, newLinks) {
8794
8872
  this.insertContent(links, startIndex, contentLength);
8795
8873
  let indexInElements = links.findIndex(x => x.startIndex >= startIndex);
8796
8874
  indexInElements = indexInElements === -1 ? links.length : indexInElements;
8797
- 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));
8798
8880
  }
8799
8881
  static replaceContent(links, startIndex, endIndex, length) {
8800
8882
  this.removeContent(links, startIndex, endIndex);
8801
8883
  this.insertContent(links, startIndex, length);
8802
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
+ }
8803
8928
  }
8804
8929
 
8805
8930
  class NumberingModel {
@@ -9423,7 +9548,7 @@ class OperationsHelper {
9423
9548
  }
9424
9549
  case CommandType.RestoreTextStyles: {
9425
9550
  const model = command.restoreTextStyles;
9426
- this.restoreTextStyles(contents, model.formats);
9551
+ this.restoreTextStyles(contents, model.formats, model.linkFormats);
9427
9552
  break;
9428
9553
  }
9429
9554
  case CommandType.RestoreParagraphStyles: {
@@ -9467,12 +9592,7 @@ class OperationsHelper {
9467
9592
  }
9468
9593
  case CommandType.InsertLink: {
9469
9594
  const model = command.insertLink;
9470
- this.insertLink(contents, model.linkDataModel.text, model.linkDataModel.link, model.insertIndex, new TextStyleModel({
9471
- ...DEFAULT_TEXT_STYLE,
9472
- headingStyleId: HYPERLINK_HEADING_STYLE_ID,
9473
- underline: true,
9474
- fontColor: HYPERLINK_FONT_COLOR
9475
- }));
9595
+ this.insertLink(contents, model.linkDataModel.text, model.linkDataModel.link, model.insertIndex);
9476
9596
  break;
9477
9597
  }
9478
9598
  case CommandType.InsertTableColumns: {
@@ -9632,7 +9752,7 @@ class OperationsHelper {
9632
9752
  TabOperationsHelper.insertContent(document.tabs, index);
9633
9753
  LinkOperationsHelper.insertContent(document.links, index, 1);
9634
9754
  }
9635
- static insertLink(document, text, link, index, style) {
9755
+ static insertLink(document, text, link, index) {
9636
9756
  document.content = ContentOperationsHelper.insertContent(document.content, text, index);
9637
9757
  document.contentLength = document.content.length;
9638
9758
  FormatOperationsHelper.insertContent(document.formats, index, text.length);
@@ -9642,7 +9762,13 @@ class OperationsHelper {
9642
9762
  IndexedElementOperationsHelper.insertContent(document.elements, index, text.length);
9643
9763
  IndexedElementOperationsHelper.insertContent(document.breaks, index, text.length);
9644
9764
  IndexedElementOperationsHelper.insertContent(document.tabs, index, text.length);
9645
- 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
+ });
9646
9772
  }
9647
9773
  static addNumbering(target, numberings, startIndex, endIndex, levels) {
9648
9774
  const newNumberingId = NumberingOperationsHelper.generateNumberingId(numberings);
@@ -9693,11 +9819,11 @@ class OperationsHelper {
9693
9819
  IndexedElementOperationsHelper.insertContent(document.elements, index, text.length);
9694
9820
  IndexedElementOperationsHelper.insertContent(document.breaks, index, text.length);
9695
9821
  IndexedElementOperationsHelper.insertContent(document.tabs, index, text.length);
9696
- LinkOperationsHelper.insertContent(document.links, index, text.length);
9822
+ LinkOperationsHelper.insertStyledContent(document.links, index, text.length, style);
9697
9823
  }
9698
9824
  static deleteRestore(document, model) {
9699
9825
  if (model.startIndex !== model.endIndex) {
9700
- this.delete(document, model.startIndex, model.endIndex - model.startIndex + 1);
9826
+ this.delete(document, model.startIndex, model.endIndex - model.startIndex);
9701
9827
  }
9702
9828
  this.restore(document, model);
9703
9829
  }
@@ -9763,19 +9889,16 @@ class OperationsHelper {
9763
9889
  this.insertTable(document, model.insertTable.insertIndex, model.insertTable, contentWidth);
9764
9890
  }
9765
9891
  else if (model.insertLink) {
9766
- this.insertLink(document, model.insertLink.linkDataModel.text, model.insertLink.linkDataModel.link, model.insertLink.insertIndex, new TextStyleModel({
9767
- ...DEFAULT_TEXT_STYLE,
9768
- headingStyleId: HYPERLINK_HEADING_STYLE_ID,
9769
- underline: true,
9770
- fontColor: HYPERLINK_FONT_COLOR
9771
- }));
9892
+ this.insertLink(document, model.insertLink.linkDataModel.text, model.insertLink.linkDataModel.link, model.insertLink.insertIndex);
9772
9893
  }
9773
9894
  }
9774
9895
  static applyTextStyle(document, startIndex, endIndex, style) {
9775
9896
  FormatOperationsHelper.apply(document.formats, startIndex, endIndex, style);
9897
+ LinkOperationsHelper.apply(document.links, startIndex, endIndex, style);
9776
9898
  }
9777
- static restoreTextStyles(document, textFormats) {
9899
+ static restoreTextStyles(document, textFormats, linkFormats) {
9778
9900
  FormatOperationsHelper.restoreFormats(document.formats, textFormats);
9901
+ LinkOperationsHelper.restoreFormats(document.links, linkFormats);
9779
9902
  }
9780
9903
  static restoreParagraphStyles(document, paragraphs) {
9781
9904
  ParagraphOperationsHelper.restoreParagraphs(document.paragraphs, paragraphs);
@@ -9839,6 +9962,9 @@ class EditSession {
9839
9962
  get scrollTop() {
9840
9963
  return this.scrollBar?.scrollTop ?? 0; // only main session is scrollable
9841
9964
  }
9965
+ get scrollBarHeight() {
9966
+ return this.scrollBar?.element.clientHeight ?? 0; // only main session is scrollable
9967
+ }
9842
9968
  constructor(displayData, sessionId, customContentService, model, selection, generalProperties, editorService, customComponents, type, scrollBar) {
9843
9969
  this.displayData = displayData;
9844
9970
  this.sessionId = sessionId;
@@ -9935,6 +10061,20 @@ class EditSession {
9935
10061
  const paragraphContent = this.displayData.getParagraphContent(row);
9936
10062
  return paragraphContent.substring(startColumn || 0, endColumn || paragraphContent.length);
9937
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
+ }
9938
10078
  removeByDocumentIndexes(startIndex, endIndex) {
9939
10079
  const startParagraphPosition = ContentHelper.documentIndexToParagraphIndex(this.displayData.paragraphs, startIndex);
9940
10080
  const endParagraphPosition = ContentHelper.documentIndexToParagraphIndex(this.displayData.paragraphs, endIndex);
@@ -10040,12 +10180,12 @@ class EditSession {
10040
10180
  const start = this.displayData.indexToPosition(applyImage.insertIndex, 0);
10041
10181
  this.displayData.updateNextLineIndexes(start.row, this.displayData.paragraphs.length - 1);
10042
10182
  }
10043
- restoreTextStyles(formats) {
10183
+ restoreTextStyles(formats, linkFormats) {
10044
10184
  const startIndex = formats[0].startIndex;
10045
10185
  const endIndex = formats[formats.length - 1].endIndex;
10046
10186
  const startParagraph = ContentHelper.documentIndexToParagraphIndex(this.displayData.paragraphs, startIndex).row;
10047
10187
  const endPosition = ContentHelper.documentIndexToParagraphWithOffset(this.displayData.paragraphs, endIndex);
10048
- OperationsHelper.restoreTextStyles(this.model, formats);
10188
+ OperationsHelper.restoreTextStyles(this.model, formats, linkFormats);
10049
10189
  this.displayData.updateNextLineIndexes(startParagraph, endPosition.row);
10050
10190
  this.selection.placeCursor(endPosition);
10051
10191
  this.applyToolbarStyles();
@@ -10182,13 +10322,7 @@ class EditSession {
10182
10322
  }
10183
10323
  insertLink(position, linkData) {
10184
10324
  const insertIndex = ContentHelper.paragraphPositionToDocumentIndex(this.displayData.paragraphs, position);
10185
- const linkStyle = new TextStyleModel({
10186
- ...DEFAULT_TEXT_STYLE,
10187
- headingStyleId: HYPERLINK_HEADING_STYLE_ID,
10188
- underline: true,
10189
- fontColor: HYPERLINK_FONT_COLOR
10190
- });
10191
- OperationsHelper.insertLink(this.model, linkData.text, linkData.link, insertIndex, linkStyle);
10325
+ OperationsHelper.insertLink(this.model, linkData.text, linkData.link, insertIndex);
10192
10326
  const endPosition = this.displayData.insertText(position, linkData.text);
10193
10327
  this.displayData.updateNextLineIndexes(position.row, position.row);
10194
10328
  this.selection.placeCursor(endPosition);
@@ -10296,7 +10430,7 @@ class EditSession {
10296
10430
  }
10297
10431
  getStyleForCursor(index) {
10298
10432
  const link = this.model.links.find(x => x.startIndex <= index && x.endIndex > index);
10299
- if (link) {
10433
+ if (link && !this.displayData.paragraphs.some(x => x.startIndex === index)) {
10300
10434
  const indexInLink = index - link.startIndex;
10301
10435
  const linkFormat = link.formats.find(x => x.startIndex <= indexInLink && x.endIndex >= indexInLink);
10302
10436
  return [linkFormat.textStyle];
@@ -10349,7 +10483,7 @@ class EditSession {
10349
10483
  }
10350
10484
  getLinkModel(cursor) {
10351
10485
  const index = ContentHelper.paragraphPositionToDocumentIndex(this.displayData.paragraphs, cursor);
10352
- 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);
10353
10487
  }
10354
10488
  insertTableRows(insertIndex, rowsCount, targetIndex, inheritIndex) {
10355
10489
  const table = this.customComponents.tables.find(x => x.instance.insertIndex === insertIndex);
@@ -10401,7 +10535,7 @@ class GeneralPropertiesModel {
10401
10535
 
10402
10536
  class MainSessionSourceModel {
10403
10537
  getTarget() {
10404
- return new TargetModel({ type: TargetType.Document, edgeEditPage: null });
10538
+ return new TargetModel({ type: TargetType.Document });
10405
10539
  }
10406
10540
  }
10407
10541
 
@@ -10502,6 +10636,31 @@ class CursorLayer {
10502
10636
  }
10503
10637
  }
10504
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
+
10505
10664
  class EventHelper {
10506
10665
  static get nextFrame() {
10507
10666
  if (!this._nextFrame) {
@@ -10661,9 +10820,8 @@ class SelectionLayer {
10661
10820
  }
10662
10821
 
10663
10822
  class Renderer extends EventEmitting {
10664
- constructor(parentContainer, editorService, session) {
10823
+ constructor(parentContainer, session) {
10665
10824
  super();
10666
- this.editorService = editorService;
10667
10825
  this.session = session;
10668
10826
  this.layerConfig = {
10669
10827
  width: 1,
@@ -10696,7 +10854,7 @@ class Renderer extends EventEmitting {
10696
10854
  this.container = parentContainer;
10697
10855
  this.container.className += ' noder-editor';
10698
10856
  this.createContentContainer();
10699
- this.textLayer = new TextLayer(this.content, this.session, this.editorService);
10857
+ this.textLayer = new TextLayer(this.content, this.session);
10700
10858
  this.selectionLayer = new SelectionLayer(this.content, 'text-selection', this.session);
10701
10859
  this.cursorLayer = new CursorLayer(this.content, this.session);
10702
10860
  this.loop = new RenderLoop(changes => this.renderChanges(changes));
@@ -10719,7 +10877,6 @@ class Renderer extends EventEmitting {
10719
10877
  // full
10720
10878
  if (changes.full) {
10721
10879
  this.renderFull();
10722
- this.editorService.rendererUpdated(this.session.sessionId);
10723
10880
  return;
10724
10881
  }
10725
10882
  if (changes.text || changes.scroll) {
@@ -10731,7 +10888,7 @@ class Renderer extends EventEmitting {
10731
10888
  if (changes.marker || changes.selection) {
10732
10889
  this.renderSelection();
10733
10890
  }
10734
- this.editorService.rendererUpdated(this.session.sessionId);
10891
+ this.session.onRendered();
10735
10892
  }
10736
10893
  /**
10737
10894
  * Triggers a partial update of the text, from the range given by the two parameters.
@@ -10746,7 +10903,7 @@ class Renderer extends EventEmitting {
10746
10903
  this.loop.schedule({ lines: true });
10747
10904
  }
10748
10905
  moveTextAreaToCursor() {
10749
- if (this.isMousePressed || !this.textarea) {
10906
+ if (!this.textarea) {
10750
10907
  return;
10751
10908
  }
10752
10909
  let cursorPosition = this.cursorLayer.cursorPosition;
@@ -10778,32 +10935,32 @@ class Renderer extends EventEmitting {
10778
10935
  updateText() {
10779
10936
  this.loop.schedule({ text: true });
10780
10937
  }
10781
- /**
10782
- * Triggers a full update of all the layers, for all the rows.
10783
- **/
10784
- updateFull(force) {
10785
- if (force) {
10786
- this.renderChanges(new RenderChangesModel({ full: true }), true);
10787
- return;
10788
- }
10789
- this.loop.schedule({ full: true });
10790
- }
10791
10938
  updateCursor() {
10792
10939
  this.loop.schedule({ cursor: true });
10793
10940
  }
10794
- screenToTextCoordinates(x, y) {
10795
- const screen = PositionHelper.pixelToScreen(this.session, x, y, this.container.getBoundingClientRect());
10796
- 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);
10797
10958
  }
10798
10959
  showCursor() {
10799
10960
  this.cursorLayer.showCursor();
10800
- DomHelper.addCssClass(this.container, 'ace_focus');
10801
- this.editorService.rendererUpdated(this.session.sessionId);
10802
10961
  }
10803
10962
  hideCursor() {
10804
10963
  this.cursorLayer.hideCursor();
10805
- DomHelper.removeCssClass(this.container, 'ace_focus');
10806
- this.editorService.rendererUpdated(this.session.sessionId);
10807
10964
  }
10808
10965
  destroy() {
10809
10966
  this.session.displayData.removeEventListener('pagesCountChanged', this.pagesCountChangedHandler);
@@ -10815,6 +10972,7 @@ class Renderer extends EventEmitting {
10815
10972
  this.selectionLayer.update(this.layerConfig);
10816
10973
  this.cursorLayer.update(this.layerConfig);
10817
10974
  this.moveTextAreaToCursor();
10975
+ this.session.onRendered();
10818
10976
  }
10819
10977
  renderText() {
10820
10978
  this.textLayer.updateLines(this.layerConfig);
@@ -10833,7 +10991,6 @@ class Renderer extends EventEmitting {
10833
10991
  const maxHeight = displayData.allPagesHeight;
10834
10992
  const minHeight = displayData.minHeight;
10835
10993
  const changes = new RenderChangesModel({ scroll: true });
10836
- // todo check logic after move wrapdata to display data
10837
10994
  this.layerConfig = {
10838
10995
  width: this.session.displayData.contentWidth + displayData.pageMargin.left + displayData.pageMargin.right,
10839
10996
  height: displayData.defaultVerticalData.contentHeight,
@@ -10948,12 +11105,6 @@ class SessionModel {
10948
11105
  }
10949
11106
 
10950
11107
  class VirtualRenderer {
10951
- get isMousePressed() {
10952
- return this.renderer.isMousePressed;
10953
- }
10954
- set isMousePressed(val) {
10955
- this.renderer.isMousePressed = val;
10956
- }
10957
11108
  get cursorLayer() {
10958
11109
  return this.renderer.cursorLayer;
10959
11110
  }
@@ -10975,7 +11126,7 @@ class VirtualRenderer {
10975
11126
  set layerConfig(val) {
10976
11127
  this.renderer.layerConfig = val;
10977
11128
  }
10978
- constructor(parentContainer, editorService, mainSession, scrollBar) {
11129
+ constructor(parentContainer, mainSession, scrollBar) {
10979
11130
  this.scrollBar = scrollBar;
10980
11131
  this.changes = new RenderChangesModel();
10981
11132
  this.size = {
@@ -10987,8 +11138,7 @@ class VirtualRenderer {
10987
11138
  };
10988
11139
  this.container = parentContainer;
10989
11140
  this.createScroller();
10990
- this.renderer = new Renderer(parentContainer, editorService, mainSession);
10991
- this.renderer.layerConfig = this.getDefaultLayerConfig();
11141
+ this.renderer = new Renderer(parentContainer, mainSession);
10992
11142
  this.pagesLayer = new PagesLayer(this.renderer.content, mainSession);
10993
11143
  this.scrollSubscription = this.scrollBar.scrolled$.subscribe(() => this.loop.schedule({ scroll: true }));
10994
11144
  this.createRenderLoop();
@@ -11074,7 +11224,7 @@ class VirtualRenderer {
11074
11224
  return changes;
11075
11225
  }
11076
11226
  moveTextAreaToCursor() {
11077
- if (this.isMousePressed || !this.textarea) {
11227
+ if (!this.textarea) {
11078
11228
  return;
11079
11229
  }
11080
11230
  let cursorPosition = this.cursorLayer.cursorPosition;
@@ -11099,12 +11249,6 @@ class VirtualRenderer {
11099
11249
  updateText() {
11100
11250
  this.renderer.updateText();
11101
11251
  }
11102
- /**
11103
- * Triggers a full update of all the layers, for all the rows.
11104
- **/
11105
- updateFull(force) {
11106
- this.renderer.updateFull(force);
11107
- }
11108
11252
  updateCursor() {
11109
11253
  this.renderer.updateCursor();
11110
11254
  }
@@ -11146,8 +11290,11 @@ class VirtualRenderer {
11146
11290
  this.scrollBar.setScrollTop(scrollTop);
11147
11291
  this.loop.schedule({ scroll: true });
11148
11292
  }
11149
- screenToTextCoordinates(x, y) {
11150
- 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);
11151
11298
  }
11152
11299
  showCursor() {
11153
11300
  this.renderer.showCursor();
@@ -11204,12 +11351,11 @@ class VirtualRenderer {
11204
11351
  }
11205
11352
  renderScroll(changes) {
11206
11353
  this.pagesLayer.update(this.layerConfig);
11354
+ this.renderer.textLayer.scrollEdges(this.layerConfig);
11207
11355
  if (changes.text || changes.lines) {
11208
- this.renderer.textLayer.updateEdges(this.layerConfig);
11209
11356
  this.renderer.textLayer.updateLines(this.layerConfig);
11210
11357
  }
11211
11358
  else {
11212
- this.renderer.textLayer.scrollPages(this.layerConfig);
11213
11359
  this.renderer.textLayer.scrollLines(this.layerConfig);
11214
11360
  }
11215
11361
  this.renderer.selectionLayer.update(this.layerConfig);
@@ -11234,28 +11380,6 @@ class VirtualRenderer {
11234
11380
  renderSelection() {
11235
11381
  this.renderer.renderSelection();
11236
11382
  }
11237
- getDefaultLayerConfig() {
11238
- return {
11239
- width: 1,
11240
- contentRange: new DistanceModel({ start: 0, end: 0 }),
11241
- minHeight: 1,
11242
- maxHeight: 1,
11243
- offset: 0,
11244
- height: 1,
11245
- scrollTop: 0,
11246
- pages: [],
11247
- visibleRange: {
11248
- startParagraph: 0,
11249
- startLine: 0,
11250
- startScreenLine: 0,
11251
- startScreenFullLine: 0,
11252
- endParagraph: 0,
11253
- endLine: 0,
11254
- endScreenLine: 0,
11255
- endScreenFullLine: 0
11256
- }
11257
- };
11258
- }
11259
11383
  }
11260
11384
 
11261
11385
  class CustomContentService {
@@ -11384,7 +11508,6 @@ class RegulatorService {
11384
11508
  this.componentService = componentService;
11385
11509
  this.sessions = [];
11386
11510
  this.sessionIdIncrement = 0;
11387
- this.edgeEditingPage = null;
11388
11511
  }
11389
11512
  addMainSession(model, pageWidth, scalingRatio, container) {
11390
11513
  const sessionId = ++this.sessionIdIncrement;
@@ -11410,25 +11533,26 @@ class RegulatorService {
11410
11533
  const displayData = new DisplayData(model, properties, sessionId, pageMargin, DocumentInfo.pagesSpace, pageWidth, model.pageHeight, customComponents, this.customContentService, this.editorService);
11411
11534
  const scrollBar = new ScrollBar(container.nativeElement.parentElement);
11412
11535
  const mainSession = new EditSession(displayData, sessionId, this.customContentService, model, this.selection, properties, this.editorService, customComponents, 'main', scrollBar);
11413
- displayData.updateNextLineIndexes(0, displayData.paragraphs.length - 1);
11414
- const virtualRenderer = new VirtualRenderer(container.nativeElement, this.editorService, mainSession, scrollBar);
11536
+ const virtualRenderer = new VirtualRenderer(container.nativeElement, mainSession, scrollBar);
11415
11537
  this.editorService.styles = DEFAULT_TOOLBAR_STYLES();
11416
11538
  this.mainSession = new SessionModel(mainSession, virtualRenderer, sessionId, null, new MainSessionSourceModel());
11417
11539
  this.sessions.push(this.mainSession);
11418
11540
  this.currentSession = this.mainSession;
11541
+ displayData.updateNextLineIndexes(0, displayData.paragraphs.length - 1);
11419
11542
  }
11420
11543
  addCellSession(table, margins, component, properties) {
11421
11544
  const sessionId = ++this.sessionIdIncrement;
11422
11545
  const customComponents = { images: [], tables: [], tabs: [], customElements: [], edges: null };
11423
11546
  const displayData = new DisplayData(component.cell, properties, sessionId, margins, 0, component.width, 0, customComponents, this.customContentService, this.editorService);
11424
- 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);
11425
11549
  displayData.contentWidth = displayData.contentWidth === 0 ? 1 : displayData.contentWidth;
11426
- displayData.updateNextLineIndexes(0, displayData.paragraphs.length - 1);
11427
- const renderer = new Renderer(component.container.nativeElement, this.editorService, session);
11550
+ const renderer = new Renderer(component.container.nativeElement, session);
11428
11551
  const source = new CellSessionSourceModel(table, component);
11429
11552
  const newSession = new SessionModel(session, renderer, sessionId, component.parentSessionId, source);
11430
- newSession.renderer.updateText();
11431
11553
  this.sessions.push(newSession);
11554
+ displayData.updateNextLineIndexes(0, displayData.paragraphs.length - 1);
11555
+ newSession.renderer.updateText();
11432
11556
  return newSession;
11433
11557
  }
11434
11558
  addEdgeSession(component) {
@@ -11436,11 +11560,12 @@ class RegulatorService {
11436
11560
  const customComponents = { images: [], tables: [], tabs: [], customElements: [], edges: null };
11437
11561
  const displayData = new DisplayData(component.model, component.generalProperties, sessionId, component.margins, 0, component.width, 0, customComponents, this.customContentService, this.editorService);
11438
11562
  const session = new EditSession(displayData, sessionId, this.customContentService, component.model, this.selection, component.generalProperties, this.editorService, customComponents, 'edge');
11439
- displayData.updateNextLineIndexes(0, displayData.paragraphs.length - 1);
11440
- const renderer = new Renderer(component.container.nativeElement, this.editorService, session);
11563
+ const renderer = new Renderer(component.container.nativeElement, session);
11441
11564
  const source = new EdgeSessionSourceModel(component.model.pageType, component.type);
11442
11565
  const newSession = new SessionModel(session, renderer, sessionId, component.parentSessionId, source);
11443
11566
  this.sessions.push(newSession);
11567
+ displayData.updateNextLineIndexes(0, displayData.paragraphs.length - 1);
11568
+ newSession.renderer.updateText();
11444
11569
  return newSession;
11445
11570
  }
11446
11571
  removeSession(sessionId) {
@@ -11453,16 +11578,12 @@ class RegulatorService {
11453
11578
  if (this.mainSession.sessionId === this.currentSession.sessionId) {
11454
11579
  return;
11455
11580
  }
11456
- this.toggleEdgeEditMode();
11457
11581
  this.setCurrentSession(this.mainSession);
11458
11582
  }
11459
- setCustomSessionAsCurrent(sessionId, edgeEditingPage = null) {
11460
- if (sessionId === this.currentSession.sessionId && this.currentSession.source.edgeEditPage !== edgeEditingPage) {
11461
- this.currentSession.source.edgeEditPage = edgeEditingPage;
11462
- this.mainSession.renderer.renderer.textLayer.edgeEditingPageUpdated(edgeEditingPage);
11583
+ setCustomSessionAsCurrent(sessionId) {
11584
+ if (sessionId === this.currentSession.sessionId) {
11463
11585
  return;
11464
11586
  }
11465
- this.toggleEdgeEditMode(edgeEditingPage);
11466
11587
  this.setCurrentSessionById(sessionId);
11467
11588
  }
11468
11589
  setTargetedSessionAsCurrent(targets) {
@@ -11471,8 +11592,6 @@ class RegulatorService {
11471
11592
  return;
11472
11593
  }
11473
11594
  const session = this.sessions.find(x => x.sessionId === targetedSession.sessionId);
11474
- const edgeEditPage = targets.length ? targets[targets.length - 1].edgeEditPage : null;
11475
- this.toggleEdgeEditMode(edgeEditPage);
11476
11595
  this.setCurrentSession(session);
11477
11596
  }
11478
11597
  setCurrentSessionById(sessionId) {
@@ -11480,16 +11599,19 @@ class RegulatorService {
11480
11599
  this.setCurrentSession(this.sessions[index]);
11481
11600
  }
11482
11601
  setCurrentSession(session) {
11602
+ const previous = this.currentSession;
11483
11603
  this.selection.clearSelection();
11484
11604
  this.currentSession.renderer.hideCursor();
11485
11605
  this.currentSession.renderer.updateSelection(this.selection.range);
11486
11606
  this.currentSession = session;
11487
11607
  this.currentSession.renderer.showCursor();
11488
- 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);
11489
11612
  }
11490
11613
  getSession(sessionId) {
11491
- const session = this.sessions.find(x => x.sessionId === sessionId);
11492
- return session.session;
11614
+ return this.getSessionModel(sessionId).session;
11493
11615
  }
11494
11616
  setSelection(selection) {
11495
11617
  this.selection = selection;
@@ -11515,19 +11637,6 @@ class RegulatorService {
11515
11637
  }
11516
11638
  return result;
11517
11639
  }
11518
- getEdgeTarget(sessionId) {
11519
- let session = this.sessions.find(x => x.sessionId === sessionId);
11520
- let parentSession = this.sessions.find(x => x.sessionId === session.parentSessionId);
11521
- while (parentSession) {
11522
- const target = session.source.getTarget();
11523
- if (target.type === TargetType.Edge) {
11524
- return target;
11525
- }
11526
- session = parentSession;
11527
- parentSession = this.sessions.find(x => x.sessionId === parentSession.parentSessionId);
11528
- }
11529
- return null;
11530
- }
11531
11640
  getTargetedSession(targets) {
11532
11641
  let result = this.mainSession.session;
11533
11642
  for (const target of targets) {
@@ -11548,13 +11657,33 @@ class RegulatorService {
11548
11657
  }
11549
11658
  return result;
11550
11659
  }
11551
- toggleEdgeEditMode(edgeEditingPage = null) {
11552
- 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);
11553
11681
  return;
11554
11682
  }
11555
- this.edgeEditingPage = edgeEditingPage;
11556
- this.mainSession.session.customComponents.edges.toggleEditMode(!!this.edgeEditingPage);
11557
- this.mainSession.renderer.renderer.textLayer.edgeEditingPageUpdated(edgeEditingPage);
11683
+ if (isPreviousEdge) {
11684
+ previous.onRendered();
11685
+ current.onRendered();
11686
+ }
11558
11687
  }
11559
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 }); }
11560
11689
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: RegulatorService }); }
@@ -13539,7 +13668,6 @@ class MenuDropdownsComponent extends BaseToolbarComponent {
13539
13668
  this.showLayout = true;
13540
13669
  this.showFormat = true;
13541
13670
  this.openFileFromDisk = new EventEmitter();
13542
- this.addCustomElement = new EventEmitter();
13543
13671
  this.saveAs = new EventEmitter();
13544
13672
  this.insertPageBreak = new EventEmitter();
13545
13673
  this.createDocument = new EventEmitter();
@@ -13576,7 +13704,7 @@ class MenuDropdownsComponent extends BaseToolbarComponent {
13576
13704
  });
13577
13705
  }
13578
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 }); }
13579
- 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 }); }
13580
13708
  }
13581
13709
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MenuDropdownsComponent, decorators: [{
13582
13710
  type: Component,
@@ -13593,8 +13721,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
13593
13721
  type: Input
13594
13722
  }], openFileFromDisk: [{
13595
13723
  type: Output
13596
- }], addCustomElement: [{
13597
- type: Output
13598
13724
  }], saveAs: [{
13599
13725
  type: Output
13600
13726
  }], insertPageBreak: [{
@@ -14087,11 +14213,11 @@ class EditorToolbarComponent {
14087
14213
  this.insertTable = new EventEmitter();
14088
14214
  }
14089
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 }); }
14090
- 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 }); }
14091
14217
  }
14092
14218
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: EditorToolbarComponent, decorators: [{
14093
14219
  type: Component,
14094
- 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"] }]
14095
14221
  }], ctorParameters: () => [{ type: EditorService }], propDecorators: { openFileFromDisk: [{
14096
14222
  type: Output
14097
14223
  }], addCustomElement: [{
@@ -14525,9 +14651,11 @@ class RevisionHelper {
14525
14651
  }
14526
14652
  static fillEdgesDefaultStyles(headers, footers) {
14527
14653
  for (const header of headers) {
14654
+ this.fillTablesDefaultStyles(header.tables);
14528
14655
  this.fillDefaultStyles(header);
14529
14656
  }
14530
14657
  for (const footer of footers) {
14658
+ this.fillTablesDefaultStyles(footer.tables);
14531
14659
  this.fillDefaultStyles(footer);
14532
14660
  }
14533
14661
  }