@talrace/ngx-noder 19.0.33 → 19.0.35

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 (55) hide show
  1. package/assets/i18n/noder.en.json +2 -1
  2. package/assets/i18n/noder.es.json +2 -1
  3. package/assets/i18n/noder.ru.json +2 -1
  4. package/fesm2022/talrace-ngx-noder.mjs +1032 -269
  5. package/fesm2022/talrace-ngx-noder.mjs.map +1 -1
  6. package/lib/editor/components/comment-popup/comment-popup.component.d.ts +11 -0
  7. package/lib/editor/content/display-data/line-info.model.d.ts +1 -0
  8. package/lib/editor/content/display-data/text-line-info.d.ts +1 -0
  9. package/lib/editor/display/layers/comment-highlight.layer.d.ts +15 -0
  10. package/lib/editor/display/layers/comment.layer.d.ts +13 -0
  11. package/lib/editor/display/layers/highlight.layer.d.ts +3 -3
  12. package/lib/editor/display/render-changes.interface.d.ts +1 -0
  13. package/lib/editor/display/render-changes.model.d.ts +1 -0
  14. package/lib/editor/display/renderer.d.ts +7 -1
  15. package/lib/editor/display/virtual.renderer.d.ts +7 -1
  16. package/lib/editor/editor.module.d.ts +23 -18
  17. package/lib/editor/execution/edit.session.d.ts +8 -1
  18. package/lib/editor/execution/editor.d.ts +22 -1
  19. package/lib/editor/execution/regulator.service.d.ts +8 -1
  20. package/lib/editor/gadgets/comment/base-comment.component.d.ts +19 -0
  21. package/lib/editor/gadgets/comment/comment-render.service.d.ts +27 -0
  22. package/lib/editor/gadgets/comment/models/remove-comment-dom.model.d.ts +5 -0
  23. package/lib/editor/gadgets/comment/models/remove-comments-dom.model.d.ts +4 -0
  24. package/lib/editor/gadgets/comment/models/render-comment.model.d.ts +10 -0
  25. package/lib/editor/gadgets/comment/models/render-comments.model.d.ts +6 -0
  26. package/lib/editor/gadgets/history/operation-history.d.ts +3 -0
  27. package/lib/editor/gadgets/history/operation.type.d.ts +3 -1
  28. package/lib/editor/gadgets/scrollbar.d.ts +1 -1
  29. package/lib/editor/interaction/editor.service.d.ts +32 -2
  30. package/lib/editor/interaction/mouse.handler.d.ts +2 -1
  31. package/lib/editor/operations/enums/command-type.enum.d.ts +3 -1
  32. package/lib/editor/operations/helpers/range-element-operations.helper.d.ts +9 -0
  33. package/lib/editor/operations/operations-helper.helper.d.ts +5 -2
  34. package/lib/editor/operations/save-commands.helper.d.ts +4 -0
  35. package/lib/editor/positioning/content.helper.d.ts +2 -0
  36. package/lib/editor/positioning/range.interface.d.ts +4 -0
  37. package/lib/models/generated/attach-comment.model.d.ts +5 -0
  38. package/lib/models/generated/cell.model.d.ts +2 -0
  39. package/lib/models/generated/command.model.d.ts +4 -0
  40. package/lib/models/generated/comment.model.d.ts +6 -0
  41. package/lib/models/generated/docx.model.d.ts +2 -0
  42. package/lib/models/generated/edge.model.d.ts +2 -0
  43. package/lib/models/generated/remove-comment.model.d.ts +4 -0
  44. package/lib/models/generated/restore.model.d.ts +2 -0
  45. package/package.json +1 -1
  46. package/public-api.d.ts +1 -0
  47. package/src/_ngx-noder.theme.scss +3 -1
  48. package/src/assets/fonts/nc-iconfont.eot +0 -0
  49. package/src/assets/fonts/nc-iconfont.scss +12 -0
  50. package/src/assets/fonts/nc-iconfont.svg +5 -1
  51. package/src/assets/fonts/nc-iconfont.ttf +0 -0
  52. package/src/assets/fonts/nc-iconfont.woff +0 -0
  53. package/src/lib/apart-components/editor-toolbar/components/toolbar-actions/_toolbar-actions.theme.scss +12 -0
  54. package/src/lib/editor/components/comment-popup/_theme.scss +9 -0
  55. package/src/scss/base-editor.scss +40 -0
@@ -1,21 +1,21 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Directive, Injectable, signal, inject, ChangeDetectorRef, HostBinding, Input, Component, ChangeDetectionStrategy, ViewChild, InjectionToken, createComponent, EventEmitter, Output, HostListener, Inject, input, computed, effect, NgModule } from '@angular/core';
3
- import { Subject, BehaviorSubject, distinctUntilChanged, debounceTime, filter, fromEvent, throttleTime, take, startWith, takeUntil, tap, map, catchError } from 'rxjs';
2
+ import { Directive, Injectable, signal, inject, ChangeDetectorRef, HostBinding, Input, Component, ChangeDetectionStrategy, ViewChild, InjectionToken, createComponent, EventEmitter, Output, HostListener, ApplicationRef, Injector, Inject, input, computed, effect, NgModule } from '@angular/core';
3
+ import { Subject, BehaviorSubject, distinctUntilChanged, debounceTime, filter, fromEvent, take, throttleTime, startWith, takeUntil, tap, map, catchError } from 'rxjs';
4
4
  import * as i1$2 from '@angular/common/http';
5
5
  import { HttpHeaders } from '@angular/common/http';
6
+ import { ComponentPortal } from '@angular/cdk/portal';
7
+ import * as i1 from '@angular/cdk/overlay';
8
+ import { OverlayConfig } from '@angular/cdk/overlay';
6
9
  import * as i4 from '@angular/material/button';
7
10
  import { MatButtonModule } from '@angular/material/button';
11
+ import * as i5 from '@angular/material/icon';
12
+ import { MatIconModule } from '@angular/material/icon';
8
13
  import * as i3 from '@ngx-translate/core';
9
14
  import { TranslateModule } from '@ngx-translate/core';
10
- import { ComponentPortal } from '@angular/cdk/portal';
11
- import * as i1 from '@angular/cdk/overlay';
12
- import { OverlayConfig } from '@angular/cdk/overlay';
13
15
  import * as i3$1 from '@angular/common';
14
16
  import { CommonModule, AsyncPipe } from '@angular/common';
15
17
  import * as i2 from '@angular/forms';
16
18
  import { FormControl, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms';
17
- import * as i5 from '@angular/material/icon';
18
- import { MatIconModule } from '@angular/material/icon';
19
19
  import * as i6 from '@angular/material/input';
20
20
  import { MatInputModule } from '@angular/material/input';
21
21
  import * as i5$2 from '@angular/material/tooltip';
@@ -32,9 +32,10 @@ import { MatSelectModule } from '@angular/material/select';
32
32
  import * as i3$2 from '@angular/material/core';
33
33
  import * as i10 from '@angular/material/sidenav';
34
34
  import { MatSidenavModule } from '@angular/material/sidenav';
35
- import { TranslateHttpLoader } from '@ngx-translate/http-loader';
36
35
  import * as i4$1 from '@angular/material/menu';
37
36
  import { MatMenuModule } from '@angular/material/menu';
37
+ import { TextFieldModule } from '@angular/cdk/text-field';
38
+ import { TranslateHttpLoader } from '@ngx-translate/http-loader';
38
39
  import * as i4$2 from '@angular/material/expansion';
39
40
  import { MatExpansionModule } from '@angular/material/expansion';
40
41
  import * as i2$1 from '@angular/platform-browser';
@@ -145,10 +146,10 @@ const DEFAULT_PARAGRAPH_STYLE = new ParagraphStyleModel({
145
146
  alignment: Alignment$1.left,
146
147
  backgroundColor: DEFAULT_BACKGROUND_COLOR,
147
148
  headingStyleId: DEFAULT_HEADING_STYLE_ID,
148
- indentFirstLine: 0,
149
- indentHanging: 0,
150
- indentLeft: 0,
151
- indentRight: 0,
149
+ indentFirstLine: null,
150
+ indentHanging: null,
151
+ indentLeft: null,
152
+ indentRight: null,
152
153
  lineSpacing: 1,
153
154
  spaceAfter: 0,
154
155
  spaceBefore: 0,
@@ -622,6 +623,7 @@ class EditorService {
622
623
  this._changedEdgeSize$ = new Subject();
623
624
  this._imageLoaded$ = new Subject();
624
625
  this._changedEdge$ = new Subject();
626
+ this._addCommentAtSelection$ = new Subject();
625
627
  this._insertTableRows$ = new Subject();
626
628
  this._insertTableColumns$ = new Subject();
627
629
  this._removeTableRows$ = new Subject();
@@ -648,6 +650,8 @@ class EditorService {
648
650
  this._removeLeft$ = new Subject();
649
651
  this._removeCustomElementsData$ = new Subject();
650
652
  this._restoreCustomElementsData$ = new Subject();
653
+ this._removeCommentData$ = new Subject();
654
+ this._restoreCommentData$ = new Subject();
651
655
  this._currentPage$ = new BehaviorSubject(1);
652
656
  this._lastPageNumber$ = new BehaviorSubject(1);
653
657
  this._applyDocumentPageFormat$ = new Subject();
@@ -664,6 +668,12 @@ class EditorService {
664
668
  paragraphStyle: new ParagraphStyleModel(),
665
669
  numberingModel: null
666
670
  });
671
+ this._commentSizeChanged$ = new Subject();
672
+ this._createComment$ = new Subject();
673
+ this._commentCreated$ = new Subject();
674
+ this._removeComment$ = new Subject();
675
+ this._setCommentSelected$ = new Subject();
676
+ this._setCommentsVisibility$ = new Subject();
667
677
  }
668
678
  set styles(value) {
669
679
  this._styles$.next({ ...value });
@@ -788,6 +798,9 @@ class EditorService {
788
798
  get changedEdge$() {
789
799
  return this._changedEdge$.asObservable();
790
800
  }
801
+ get addCommentAtSelection$() {
802
+ return this._addCommentAtSelection$.asObservable();
803
+ }
791
804
  get insertTableRows$() {
792
805
  return this._insertTableRows$.asObservable();
793
806
  }
@@ -873,6 +886,12 @@ class EditorService {
873
886
  get restoreCustomElementsData$() {
874
887
  return this._restoreCustomElementsData$.asObservable();
875
888
  }
889
+ get removeCommentData$() {
890
+ return this._removeCommentData$.asObservable();
891
+ }
892
+ get restoreCommentData$() {
893
+ return this._restoreCommentData$.asObservable();
894
+ }
876
895
  get currentPage() {
877
896
  return this._currentPage$.value;
878
897
  }
@@ -921,6 +940,24 @@ class EditorService {
921
940
  get paragraphStyle$() {
922
941
  return this._paragraphStyle$.asObservable();
923
942
  }
943
+ get commentSizeChanged$() {
944
+ return this._commentSizeChanged$.asObservable();
945
+ }
946
+ get createComment$() {
947
+ return this._createComment$.asObservable();
948
+ }
949
+ get commentCreated$() {
950
+ return this._commentCreated$.asObservable();
951
+ }
952
+ get removeComment$() {
953
+ return this._removeComment$.asObservable();
954
+ }
955
+ get setCommentSelected$() {
956
+ return this._setCommentSelected$.asObservable();
957
+ }
958
+ get setCommentsVisibility$() {
959
+ return this._setCommentsVisibility$.asObservable();
960
+ }
924
961
  tabSettings(value) {
925
962
  this._tabSettings$.next(value);
926
963
  }
@@ -1126,6 +1163,12 @@ class EditorService {
1126
1163
  restoreCustomElementsData(elements) {
1127
1164
  this._restoreCustomElementsData$.next(elements);
1128
1165
  }
1166
+ removeCommentData(commentIds) {
1167
+ this._removeCommentData$.next(commentIds);
1168
+ }
1169
+ restoreCommentData(commentIds) {
1170
+ this._restoreCommentData$.next(commentIds);
1171
+ }
1129
1172
  setNewSearchTerm(term) {
1130
1173
  this._searchTerm$.next(term);
1131
1174
  }
@@ -1162,6 +1205,27 @@ class EditorService {
1162
1205
  ignoreGrammarSuggestion(error) {
1163
1206
  this._ignoreGrammarError$.next(error);
1164
1207
  }
1208
+ addCommentAtSelection() {
1209
+ this._addCommentAtSelection$.next();
1210
+ }
1211
+ commentSizeChanged() {
1212
+ this._commentSizeChanged$.next();
1213
+ }
1214
+ createComment(reqId) {
1215
+ this._createComment$.next(reqId);
1216
+ }
1217
+ commentCreated(commentId, reqId) {
1218
+ this._commentCreated$.next({ commentId, reqId });
1219
+ }
1220
+ removeComment(id) {
1221
+ this._removeComment$.next(id);
1222
+ }
1223
+ setCommentSelected(id) {
1224
+ this._setCommentSelected$.next(id);
1225
+ }
1226
+ setCommentsVisibility(value) {
1227
+ this._setCommentsVisibility$.next(value);
1228
+ }
1165
1229
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: EditorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1166
1230
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: EditorService }); }
1167
1231
  }
@@ -1304,6 +1368,38 @@ class DefaultImageApiService {
1304
1368
  }
1305
1369
  }
1306
1370
 
1371
+ class BaseCommentComponent {
1372
+ constructor(elementRef, editorService) {
1373
+ this.elementRef = elementRef;
1374
+ this.editorService = editorService;
1375
+ this.resizeObserver = new ResizeObserver(entries => {
1376
+ const height = entries[0].borderBoxSize[0].blockSize;
1377
+ if (!height || this.height === height) {
1378
+ return;
1379
+ }
1380
+ this.height = height;
1381
+ this.editorService.commentSizeChanged();
1382
+ });
1383
+ }
1384
+ setSelected(value) {
1385
+ this.selected = value;
1386
+ }
1387
+ setEditing(value) {
1388
+ this.editing = value;
1389
+ }
1390
+ markAsNew() {
1391
+ this.setSelected(true);
1392
+ this.setEditing(true);
1393
+ this.isNew = true;
1394
+ }
1395
+ initialize() {
1396
+ this.resizeObserver.observe(this.elementRef.nativeElement);
1397
+ }
1398
+ destroy() {
1399
+ this.resizeObserver.disconnect();
1400
+ }
1401
+ }
1402
+
1307
1403
  class GrammarService {
1308
1404
  constructor() {
1309
1405
  this.debounceTime = 3000;
@@ -1442,6 +1538,8 @@ var CommandType;
1442
1538
  CommandType[CommandType["RestorePageFormats"] = 35] = "RestorePageFormats";
1443
1539
  CommandType[CommandType["ApplyParagraphs"] = 36] = "ApplyParagraphs";
1444
1540
  CommandType[CommandType["ApplyTableCellsStyles"] = 37] = "ApplyTableCellsStyles";
1541
+ CommandType[CommandType["AttachComment"] = 38] = "AttachComment";
1542
+ CommandType[CommandType["RemoveComment"] = 39] = "RemoveComment";
1445
1543
  })(CommandType || (CommandType = {}));
1446
1544
 
1447
1545
  class PageNumbersModel {
@@ -1539,6 +1637,25 @@ class ApplyTextStyleModel {
1539
1637
  }
1540
1638
  }
1541
1639
 
1640
+ class CommentModel {
1641
+ constructor(fields) {
1642
+ if (fields) {
1643
+ Object.assign(this, fields);
1644
+ }
1645
+ }
1646
+ }
1647
+
1648
+ class AttachCommentModel {
1649
+ constructor(fields) {
1650
+ if (fields) {
1651
+ if (fields.comment) {
1652
+ fields.comment = new CommentModel(fields.comment);
1653
+ }
1654
+ Object.assign(this, fields);
1655
+ }
1656
+ }
1657
+ }
1658
+
1542
1659
  const CUSTOM_ELEMENT_MARKER = '*';
1543
1660
  const TABLE_MARKER = '#';
1544
1661
 
@@ -1558,6 +1675,82 @@ class BreakHelper {
1558
1675
  }
1559
1676
  }
1560
1677
 
1678
+ class OverlayService {
1679
+ constructor(overlay) {
1680
+ this.overlay = overlay;
1681
+ this.overlayResult = new Subject();
1682
+ }
1683
+ open(component, data, xPosition, yPosition) {
1684
+ this.close();
1685
+ this.overlayRef = this.overlay.create(this.getOverlayConfig(xPosition, yPosition));
1686
+ const ref = this.overlayRef.attach(new ComponentPortal(component));
1687
+ Object.assign(ref.instance, data);
1688
+ this.clickSubscription();
1689
+ return this.overlayResult.asObservable();
1690
+ }
1691
+ close(value) {
1692
+ this.overlayResult.next(value);
1693
+ this.openedSubscription?.unsubscribe();
1694
+ if (this.overlayRef) {
1695
+ this.overlayRef.dispose();
1696
+ this.overlayRef = null;
1697
+ }
1698
+ }
1699
+ clickSubscription() {
1700
+ this.openedSubscription = fromEvent(document, 'mousedown')
1701
+ .pipe(filter(event => {
1702
+ const clickTarget = event.target;
1703
+ return (this.overlayRef &&
1704
+ !this.overlayRef.overlayElement.contains(clickTarget) &&
1705
+ this.overlayRef.overlayElement.parentElement.parentElement.children.length === 1);
1706
+ }), take(1))
1707
+ .subscribe(() => this.close());
1708
+ }
1709
+ getOverlayConfig(xPosition, yPosition) {
1710
+ return new OverlayConfig({
1711
+ hasBackdrop: false,
1712
+ backdropClass: 'noder-backdrop',
1713
+ positionStrategy: this.getOverlayPosition(xPosition, yPosition),
1714
+ scrollStrategy: this.overlay.scrollStrategies.reposition()
1715
+ });
1716
+ }
1717
+ getOverlayPosition(xPosition, yPosition) {
1718
+ return this.overlay.position().global().left(`${xPosition}px`).top(`${yPosition}px`);
1719
+ }
1720
+ scroll(deltaY) {
1721
+ // todo: close overlay when out of visible area
1722
+ if (!this.overlayRef) {
1723
+ return;
1724
+ }
1725
+ const x = this.overlayRef.overlayElement.offsetLeft;
1726
+ const y = this.overlayRef.overlayElement.offsetTop - deltaY;
1727
+ const strategy = this.overlay.position().global().left(`${x}px`).top(`${y}px`);
1728
+ this.overlayRef.updatePositionStrategy(strategy);
1729
+ }
1730
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: OverlayService, deps: [{ token: i1.Overlay }], target: i0.ɵɵFactoryTarget.Injectable }); }
1731
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: OverlayService }); }
1732
+ }
1733
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: OverlayService, decorators: [{
1734
+ type: Injectable
1735
+ }], ctorParameters: () => [{ type: i1.Overlay }] });
1736
+
1737
+ class CommentPopupComponent {
1738
+ constructor(editorService, overlayService) {
1739
+ this.editorService = editorService;
1740
+ this.overlayService = overlayService;
1741
+ }
1742
+ addComment() {
1743
+ this.editorService.addCommentAtSelection();
1744
+ this.overlayService.close();
1745
+ }
1746
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: CommentPopupComponent, deps: [{ token: EditorService }, { token: OverlayService }], target: i0.ɵɵFactoryTarget.Component }); }
1747
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.5", type: CommentPopupComponent, isStandalone: false, selector: "app-nod-comment-popup", ngImport: i0, template: "<button\n mat-stroked-button\n (click)=\"addComment()\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-comment\"></mat-icon>\n</button>\n", styles: [":host{min-height:30px;border-radius:8px}button{min-width:0}.mat-icon{display:flex;justify-content:center;align-items:center;margin:0}\n"], dependencies: [{ 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: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1748
+ }
1749
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: CommentPopupComponent, decorators: [{
1750
+ type: Component,
1751
+ args: [{ selector: 'app-nod-comment-popup', changeDetection: ChangeDetectionStrategy.OnPush, standalone: false, template: "<button\n mat-stroked-button\n (click)=\"addComment()\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-comment\"></mat-icon>\n</button>\n", styles: [":host{min-height:30px;border-radius:8px}button{min-width:0}.mat-icon{display:flex;justify-content:center;align-items:center;margin:0}\n"] }]
1752
+ }], ctorParameters: () => [{ type: EditorService }, { type: OverlayService }] });
1753
+
1561
1754
  class CursorParagraph {
1562
1755
  constructor(row, column) {
1563
1756
  this.row = row;
@@ -1604,6 +1797,9 @@ class ContentHelper {
1604
1797
  }
1605
1798
  });
1606
1799
  }
1800
+ static getCommentsInRange(comments, startIndex, endIndex) {
1801
+ return comments.filter(x => x.startIndex >= startIndex && x.endIndex <= endIndex);
1802
+ }
1607
1803
  }
1608
1804
 
1609
1805
  class CreateEdgesModel {
@@ -1755,65 +1951,6 @@ class FormatHelper {
1755
1951
 
1756
1952
  const POPUP_HEIGHT = 150;
1757
1953
 
1758
- class OverlayService {
1759
- constructor(overlay) {
1760
- this.overlay = overlay;
1761
- this.overlayResult = new Subject();
1762
- }
1763
- open(component, data, xPosition, yPosition) {
1764
- this.close();
1765
- this.overlayRef = this.overlay.create(this.getOverlayConfig(xPosition, yPosition));
1766
- const ref = this.overlayRef.attach(new ComponentPortal(component));
1767
- Object.assign(ref.instance, data);
1768
- this.clickSubscription();
1769
- return this.overlayResult.asObservable();
1770
- }
1771
- close(value) {
1772
- this.overlayResult.next(value);
1773
- this.openedSubscription?.unsubscribe();
1774
- if (this.overlayRef) {
1775
- this.overlayRef.dispose();
1776
- this.overlayRef = null;
1777
- }
1778
- }
1779
- clickSubscription() {
1780
- this.openedSubscription = fromEvent(document, 'mousedown')
1781
- .pipe(filter(event => {
1782
- const clickTarget = event.target;
1783
- return (this.overlayRef &&
1784
- !this.overlayRef.overlayElement.contains(clickTarget) &&
1785
- this.overlayRef.overlayElement.parentElement.parentElement.children.length === 1);
1786
- }), take(1))
1787
- .subscribe(() => this.close());
1788
- }
1789
- getOverlayConfig(xPosition, yPosition) {
1790
- return new OverlayConfig({
1791
- hasBackdrop: false,
1792
- backdropClass: 'noder-backdrop',
1793
- positionStrategy: this.getOverlayPosition(xPosition, yPosition),
1794
- scrollStrategy: this.overlay.scrollStrategies.reposition()
1795
- });
1796
- }
1797
- getOverlayPosition(xPosition, yPosition) {
1798
- return this.overlay.position().global().left(`${xPosition}px`).top(`${yPosition}px`);
1799
- }
1800
- scroll(deltaY) {
1801
- // todo: close overlay when out of visible area
1802
- if (!this.overlayRef) {
1803
- return;
1804
- }
1805
- const x = this.overlayRef.overlayElement.offsetLeft;
1806
- const y = this.overlayRef.overlayElement.offsetTop - deltaY;
1807
- const strategy = this.overlay.position().global().left(`${x}px`).top(`${y}px`);
1808
- this.overlayRef.updatePositionStrategy(strategy);
1809
- }
1810
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: OverlayService, deps: [{ token: i1.Overlay }], target: i0.ɵɵFactoryTarget.Injectable }); }
1811
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: OverlayService }); }
1812
- }
1813
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: OverlayService, decorators: [{
1814
- type: Injectable
1815
- }], ctorParameters: () => [{ type: i1.Overlay }] });
1816
-
1817
1954
  class GrammarPopupComponent {
1818
1955
  constructor(editorService, overlayService) {
1819
1956
  this.editorService = editorService;
@@ -2194,6 +2331,7 @@ var MouseButton;
2194
2331
 
2195
2332
  class MouseHandler {
2196
2333
  constructor(container, editor) {
2334
+ this.clickableElements = ['.noder-comment'];
2197
2335
  this.clicks = 0;
2198
2336
  this.containerWheel$ = fromEvent(container, 'wheel')
2199
2337
  .pipe(throttleTime(20))
@@ -2203,20 +2341,26 @@ class MouseHandler {
2203
2341
  destroy() {
2204
2342
  this.containerWheel$?.unsubscribe();
2205
2343
  this.containerMouseDown$?.unsubscribe();
2206
- this.endMousePress();
2344
+ this.endMousePress(null, null);
2207
2345
  }
2208
2346
  startMousePress(editor) {
2209
- this.endMousePress();
2347
+ this.endMousePress(editor, null);
2210
2348
  this.documentMouseMove$ = fromEvent(document, 'mousemove')
2211
2349
  .pipe(throttleTime(20))
2212
2350
  .subscribe((event) => editor.onMousePressedMove(event));
2213
- this.documentMouseUp$ = fromEvent(document, 'mouseup').subscribe(() => this.endMousePress());
2351
+ this.documentMouseUp$ = fromEvent(document, 'mouseup').subscribe((event) => this.endMousePress(editor, event));
2214
2352
  }
2215
- endMousePress() {
2353
+ endMousePress(editor, event) {
2216
2354
  this.documentMouseMove$?.unsubscribe();
2217
2355
  this.documentMouseUp$?.unsubscribe();
2356
+ editor?.onMousePressEnd(event);
2218
2357
  }
2219
2358
  onMultiMouseDown(event, editor) {
2359
+ for (const element of this.clickableElements) {
2360
+ if (event.target.closest(element)) {
2361
+ return;
2362
+ }
2363
+ }
2220
2364
  if (event.button !== MouseButton.Left) {
2221
2365
  editor.onMouseClick(event);
2222
2366
  return;
@@ -2256,6 +2400,14 @@ let CellDataModel$1 = class CellDataModel {
2256
2400
  }
2257
2401
  };
2258
2402
 
2403
+ class RemoveCommentModel {
2404
+ constructor(fields) {
2405
+ if (fields) {
2406
+ Object.assign(this, fields);
2407
+ }
2408
+ }
2409
+ }
2410
+
2259
2411
  class RemoveEdgesModel {
2260
2412
  constructor(fields) {
2261
2413
  if (fields) {
@@ -2351,6 +2503,16 @@ class OperationHistory {
2351
2503
  this.step = -1;
2352
2504
  this.editorService.historyInfo = new OperationsHistoryInfoModel(this.step, this.storage.length - 1);
2353
2505
  }
2506
+ pushAttachComment(comment) {
2507
+ const redoStep = new AttachCommentModel({ comment: comment });
2508
+ const undoStep = new RemoveCommentModel({ commentId: comment.commentId });
2509
+ this.addToHistory(undoStep, redoStep);
2510
+ }
2511
+ pushRemoveComment(comment) {
2512
+ const redoStep = new RemoveCommentModel({ commentId: comment.commentId });
2513
+ const undoStep = new AttachCommentModel({ comment: comment });
2514
+ this.addToHistory(undoStep, redoStep);
2515
+ }
2354
2516
  pushInsertText(insertIndex, text) {
2355
2517
  const redoStep = new InsertTextModel({ insertIndex, text });
2356
2518
  const undoStep = new DeleteModel({ startIndex: insertIndex, count: text.length });
@@ -2695,6 +2857,67 @@ class ParagraphModel {
2695
2857
  }
2696
2858
  }
2697
2859
 
2860
+ class RangeElementHelper {
2861
+ static removeContent(elements, startIndex, endIndex) {
2862
+ const length = endIndex - startIndex + 1;
2863
+ for (let i = elements.length - 1; i >= 0; i--) {
2864
+ const element = elements[i];
2865
+ if (element.endIndex < startIndex) {
2866
+ continue;
2867
+ }
2868
+ if (element.startIndex < startIndex) {
2869
+ if (element.endIndex > endIndex) {
2870
+ element.endIndex -= length;
2871
+ }
2872
+ else {
2873
+ element.endIndex = startIndex;
2874
+ }
2875
+ continue;
2876
+ }
2877
+ if (element.startIndex >= startIndex && element.startIndex <= endIndex) {
2878
+ if (element.endIndex <= endIndex) {
2879
+ elements.splice(i, 1);
2880
+ continue;
2881
+ }
2882
+ element.startIndex = endIndex;
2883
+ continue;
2884
+ }
2885
+ element.startIndex -= length;
2886
+ element.endIndex -= length;
2887
+ }
2888
+ }
2889
+ static insertContent(elements, index, length) {
2890
+ for (const element of elements) {
2891
+ if (element.startIndex >= index) {
2892
+ element.startIndex += length;
2893
+ element.endIndex += length;
2894
+ }
2895
+ else if (element.endIndex >= index) {
2896
+ element.endIndex += length;
2897
+ }
2898
+ }
2899
+ }
2900
+ static restore(elements, index, contentLength, newElements) {
2901
+ RangeElementHelper.insertContent(elements, index, contentLength);
2902
+ const nextElement = elements.find(x => x.startIndex >= index);
2903
+ const indexInElements = nextElement !== undefined ? elements.indexOf(nextElement) : elements.length;
2904
+ elements.splice(indexInElements, 0, ...newElements);
2905
+ }
2906
+ static replaceContent(elements, startIndex, endIndex, length) {
2907
+ RangeElementHelper.removeContent(elements, startIndex, endIndex);
2908
+ RangeElementHelper.insertContent(elements, startIndex, length);
2909
+ }
2910
+ static shiftIndexes(elements, offset) {
2911
+ for (const element of elements) {
2912
+ element.startIndex += offset;
2913
+ element.endIndex += offset;
2914
+ }
2915
+ }
2916
+ static sliceSection(elements, startIndex, endIndex) {
2917
+ return elements.filter(x => x.startIndex >= startIndex && x.endIndex <= endIndex);
2918
+ }
2919
+ }
2920
+
2698
2921
  class TableModel {
2699
2922
  constructor(fields) {
2700
2923
  if (fields) {
@@ -2723,6 +2946,7 @@ class ContentsOperationsHelper {
2723
2946
  const images = IndexedElementHelper.sliceSection(contents.images, startIndex, endIndex).map(x => new ImageModel(x));
2724
2947
  const tables = IndexedElementHelper.sliceSection(contents.tables, startIndex, endIndex).map(x => new TableModel(x));
2725
2948
  const elements = IndexedElementHelper.sliceSection(contents.elements, startIndex, endIndex).map(x => new ElementModel(x));
2949
+ const comments = RangeElementHelper.sliceSection(contents.comments, startIndex, endIndex);
2726
2950
  const breaks = IndexedElementHelper.sliceSection(contents.breaks, startIndex, endIndex).map(x => new BreakModel(x));
2727
2951
  const tabs = IndexedElementHelper.sliceSection(contents.tabs, startIndex, endIndex).map(x => new TabModel(x));
2728
2952
  const links = LinkHelper.sliceSection(contents.links, startIndex, endIndex).map(x => new LinkModel(x));
@@ -2738,7 +2962,8 @@ class ContentsOperationsHelper {
2738
2962
  breaks,
2739
2963
  tabs,
2740
2964
  links,
2741
- pageFormats
2965
+ pageFormats,
2966
+ comments
2742
2967
  });
2743
2968
  }
2744
2969
  }
@@ -2763,6 +2988,7 @@ class EdgesOperationsHelper {
2763
2988
  paragraphs: [new ParagraphModel({ insertIndex: 0, paragraphStyle: DEFAULT_PARAGRAPH_STYLE })],
2764
2989
  tables: [],
2765
2990
  tabs: [],
2991
+ comments: [],
2766
2992
  links: []
2767
2993
  }));
2768
2994
  }
@@ -4494,6 +4720,7 @@ var VerticalMerge;
4494
4720
  class TableOperationsHelper {
4495
4721
  static insertContent(tables, insertIndex, columnsCount, rowsCount, contentWidth) {
4496
4722
  let rows = [];
4723
+ const columnWidth = Math.round(contentWidth / columnsCount);
4497
4724
  for (let i = 0; i < rowsCount; i++) {
4498
4725
  let cells = [];
4499
4726
  for (let j = 0; j < columnsCount; j++) {
@@ -4507,13 +4734,14 @@ class TableOperationsHelper {
4507
4734
  tables: [],
4508
4735
  tabs: [],
4509
4736
  links: [],
4737
+ comments: [],
4738
+ width: columnWidth,
4510
4739
  widthType: 'dxa'
4511
4740
  });
4512
4741
  cells.push(cell);
4513
4742
  }
4514
4743
  rows.push(new RowModel({ cells: cells }));
4515
4744
  }
4516
- const columnWidth = Math.round(contentWidth / columnsCount);
4517
4745
  const columns = [];
4518
4746
  for (let i = 0; i < columnsCount; i++) {
4519
4747
  const column = new ColumnModel({
@@ -4607,7 +4835,8 @@ class TableOperationsHelper {
4607
4835
  verticalMerge: this.getCellVerticalMerge(matrix[inheritIndex].cells[i].verticalMerge, targetIndex, inheritIndex),
4608
4836
  tables: [],
4609
4837
  tabs: [],
4610
- links: []
4838
+ links: [],
4839
+ comments: []
4611
4840
  });
4612
4841
  newCells.push(newCell);
4613
4842
  }
@@ -5189,7 +5418,7 @@ class OperationsHelper {
5189
5418
  }
5190
5419
  case CommandType.InsertTableColumns: {
5191
5420
  const model = command.insertTableColumns;
5192
- const contentWidth = this.getContentWidth(document, contents);
5421
+ const contentWidth = this.getContentWidth(document, contents, model.insertIndex);
5193
5422
  this.insertTableColumns(contents, model.insertIndex, model.count, model.targetIndex, model.inheritIndex, contentWidth);
5194
5423
  break;
5195
5424
  }
@@ -5200,7 +5429,7 @@ class OperationsHelper {
5200
5429
  }
5201
5430
  case CommandType.RemoveTableColumns: {
5202
5431
  const model = command.removeTableColumns;
5203
- const contentWidth = this.getContentWidth(document, contents);
5432
+ const contentWidth = this.getContentWidth(document, contents, model.insertIndex);
5204
5433
  this.removeTableColumns(contents, model.insertIndex, model.startIndex, model.endIndex, contentWidth);
5205
5434
  break;
5206
5435
  }
@@ -5215,8 +5444,9 @@ class OperationsHelper {
5215
5444
  break;
5216
5445
  }
5217
5446
  case CommandType.InsertTable: {
5218
- const contentWidth = this.getContentWidth(document, contents);
5219
- this.insertTable(contents, command.insertTable, contentWidth);
5447
+ const model = command.insertTable;
5448
+ const contentWidth = this.getContentWidth(document, contents, model.insertIndex);
5449
+ this.insertTable(contents, model, contentWidth);
5220
5450
  break;
5221
5451
  }
5222
5452
  case CommandType.ApplyImageStyle: {
@@ -5235,8 +5465,7 @@ class OperationsHelper {
5235
5465
  break;
5236
5466
  }
5237
5467
  case CommandType.Replace: {
5238
- const contentWidth = this.getContentWidth(document, contents);
5239
- this.replace(contents, command.replace, contentWidth);
5468
+ this.replace(document, contents, command.replace);
5240
5469
  break;
5241
5470
  }
5242
5471
  case CommandType.CreateEdges: {
@@ -5305,6 +5534,16 @@ class OperationsHelper {
5305
5534
  this.applyTableCellsStyles(contents, model);
5306
5535
  break;
5307
5536
  }
5537
+ case CommandType.AttachComment: {
5538
+ const model = command.attachComment;
5539
+ this.addComment(document, model.comment);
5540
+ break;
5541
+ }
5542
+ case CommandType.RemoveComment: {
5543
+ const model = command.removeComment;
5544
+ this.removeComment(document, model.commentId);
5545
+ break;
5546
+ }
5308
5547
  }
5309
5548
  });
5310
5549
  }
@@ -5332,20 +5571,25 @@ class OperationsHelper {
5332
5571
  IndexedElementHelper.shiftIndexes(restore.elements, offset);
5333
5572
  IndexedElementHelper.shiftIndexes(restore.breaks, offset);
5334
5573
  IndexedElementHelper.shiftIndexes(restore.tabs, offset);
5574
+ RangeElementHelper.shiftIndexes(restore.comments, offset);
5335
5575
  LinkHelper.shiftIndexes(restore.links, offset);
5336
5576
  PageFormatHelper.shiftIndexes(restore.pageFormats, offset);
5337
5577
  this.restore(targetContents, restore);
5338
5578
  return moveIndex;
5339
5579
  }
5340
- static getContentWidth(document, contents) {
5341
- let contentWidth = 0;
5342
- const defaultPageFormat = document.pageFormats[document.pageFormats.length - 1];
5580
+ static getContentWidth(document, contents, insertIndex = 0) {
5581
+ let contentWidth;
5343
5582
  if (contents instanceof CellModel) {
5344
5583
  const margins = (contents.margins?.left ?? 0) + (contents.margins?.right ?? 0);
5345
5584
  contentWidth = contents.width - margins;
5346
5585
  }
5586
+ else if (contents instanceof EdgeModel) {
5587
+ const pageFormat = document.pageFormats[document.pageFormats.length - 1];
5588
+ contentWidth = pageFormat.pageWidth - pageFormat.marginLeft - pageFormat.marginRight;
5589
+ }
5347
5590
  else {
5348
- contentWidth = defaultPageFormat.pageWidth - defaultPageFormat.marginLeft - defaultPageFormat.marginRight;
5591
+ const pageFormat = document.pageFormats.findLast(x => x.insertIndex <= insertIndex) ?? document.pageFormats[document.pageFormats.length - 1];
5592
+ contentWidth = pageFormat.pageWidth - pageFormat.marginLeft - pageFormat.marginRight;
5349
5593
  }
5350
5594
  return contentWidth;
5351
5595
  }
@@ -5358,6 +5602,7 @@ class OperationsHelper {
5358
5602
  IndexedElementOperationsHelper.insertContent(document.elements, index, text.length);
5359
5603
  IndexedElementOperationsHelper.insertContent(document.breaks, index, text.length);
5360
5604
  IndexedElementOperationsHelper.insertContent(document.tabs, index, text.length);
5605
+ RangeElementHelper.insertContent(document.comments, index, text.length);
5361
5606
  LinkOperationsHelper.insertContent(document.links, index, text.length);
5362
5607
  PageFormatOperationsHelper.insertContent(document, index, text.length);
5363
5608
  }
@@ -5370,6 +5615,7 @@ class OperationsHelper {
5370
5615
  IndexedElementOperationsHelper.insert(document.elements, element.element);
5371
5616
  IndexedElementOperationsHelper.insertContent(document.breaks, element.element.insertIndex, 1);
5372
5617
  IndexedElementOperationsHelper.insertContent(document.tabs, element.element.insertIndex, 1);
5618
+ RangeElementHelper.insertContent(document.comments, element.element.insertIndex, 1);
5373
5619
  LinkOperationsHelper.insertContent(document.links, element.element.insertIndex, 1);
5374
5620
  PageFormatOperationsHelper.insertContent(document, element.element.insertIndex, 1);
5375
5621
  }
@@ -5382,6 +5628,7 @@ class OperationsHelper {
5382
5628
  IndexedElementOperationsHelper.insertContent(document.elements, index, text.length);
5383
5629
  BreakOperationsHelper.insertContent(document.breaks, index + text.length - 1, breakType, text.length);
5384
5630
  IndexedElementOperationsHelper.insertContent(document.tabs, index, text.length);
5631
+ RangeElementHelper.insertContent(document.comments, index, text.length);
5385
5632
  LinkOperationsHelper.insertContent(document.links, index, text.length);
5386
5633
  PageFormatOperationsHelper.insertContent(document, index, text.length);
5387
5634
  }
@@ -5394,6 +5641,7 @@ class OperationsHelper {
5394
5641
  IndexedElementOperationsHelper.insertContent(document.elements, index, 1);
5395
5642
  IndexedElementOperationsHelper.insertContent(document.breaks, index, 1);
5396
5643
  TabOperationsHelper.insertContent(document.tabs, index);
5644
+ RangeElementHelper.insertContent(document.comments, index, 1);
5397
5645
  LinkOperationsHelper.insertContent(document.links, index, 1);
5398
5646
  PageFormatOperationsHelper.insertContent(document, index, 1);
5399
5647
  }
@@ -5406,6 +5654,7 @@ class OperationsHelper {
5406
5654
  IndexedElementOperationsHelper.insertContent(document.elements, index, text.length);
5407
5655
  IndexedElementOperationsHelper.insertContent(document.breaks, index, text.length);
5408
5656
  IndexedElementOperationsHelper.insertContent(document.tabs, index, text.length);
5657
+ RangeElementHelper.insertContent(document.comments, index, text.length);
5409
5658
  PageFormatOperationsHelper.insertContent(document, index, text.length);
5410
5659
  const formatStyle = FormatStyleHelper.getFormatAtIndex(document.formats, index).textStyle;
5411
5660
  LinkOperationsHelper.insert(document.links, link, index, text.length, {
@@ -5463,6 +5712,7 @@ class OperationsHelper {
5463
5712
  IndexedElementOperationsHelper.insertContent(document.breaks, index, 1);
5464
5713
  ImageOperationsHelper.insertContent(document.images, index, imageData);
5465
5714
  IndexedElementOperationsHelper.insertContent(document.tabs, index, 1);
5715
+ RangeElementHelper.insertContent(document.comments, index, 1);
5466
5716
  LinkOperationsHelper.insertContent(document.links, index, 1);
5467
5717
  PageFormatOperationsHelper.insertContent(document, index, 1);
5468
5718
  }
@@ -5482,6 +5732,7 @@ class OperationsHelper {
5482
5732
  IndexedElementOperationsHelper.insertContent(document.breaks, index, 1);
5483
5733
  TableOperationsHelper.insertContent(document.tables, index, tableModel.columnsCount, tableModel.rowsCount, contentWidth);
5484
5734
  IndexedElementOperationsHelper.insertContent(document.tabs, index, 1);
5735
+ RangeElementHelper.insertContent(document.comments, index, 1);
5485
5736
  LinkOperationsHelper.insertContent(document.links, index, 1);
5486
5737
  PageFormatOperationsHelper.insertContent(document, index, 1);
5487
5738
  if (tableModel.insertParagraphAfter) {
@@ -5506,6 +5757,7 @@ class OperationsHelper {
5506
5757
  IndexedElementOperationsHelper.insertContent(document.elements, index, text.length);
5507
5758
  IndexedElementOperationsHelper.insertContent(document.breaks, index, text.length);
5508
5759
  IndexedElementOperationsHelper.insertContent(document.tabs, index, text.length);
5760
+ RangeElementHelper.insertContent(document.comments, index, text.length);
5509
5761
  LinkOperationsHelper.insertStyledContent(document.links, index, text.length, style);
5510
5762
  PageFormatOperationsHelper.insertContent(document, index, text.length);
5511
5763
  }
@@ -5518,6 +5770,7 @@ class OperationsHelper {
5518
5770
  IndexedElementOperationsHelper.restore(document.elements, model.insertIndex, model.text.length, model.elements);
5519
5771
  IndexedElementOperationsHelper.restore(document.breaks, model.insertIndex, model.text.length, model.breaks);
5520
5772
  IndexedElementOperationsHelper.restore(document.tabs, model.insertIndex, model.text.length, model.tabs);
5773
+ RangeElementHelper.restore(document.comments, model.insertIndex, model.text.length, model.comments);
5521
5774
  PageFormatOperationsHelper.restore(document, model.insertIndex, model.text.length, model.pageFormats);
5522
5775
  LinkOperationsHelper.restore(document.links, model.insertIndex, model.text.length, model.links);
5523
5776
  }
@@ -5531,6 +5784,7 @@ class OperationsHelper {
5531
5784
  IndexedElementOperationsHelper.removeContent(document.elements, startIndex, endIndex);
5532
5785
  IndexedElementOperationsHelper.removeContent(document.breaks, startIndex, endIndex);
5533
5786
  IndexedElementOperationsHelper.removeContent(document.tabs, startIndex, endIndex);
5787
+ RangeElementHelper.removeContent(document.comments, startIndex, endIndex);
5534
5788
  PageFormatOperationsHelper.removeContent(document, startIndex, endIndex);
5535
5789
  LinkOperationsHelper.removeContent(document.links, startIndex, endIndex);
5536
5790
  }
@@ -5543,32 +5797,43 @@ class OperationsHelper {
5543
5797
  IndexedElementOperationsHelper.replaceContent(document.elements, startIndex, endIndex, text.length);
5544
5798
  IndexedElementOperationsHelper.replaceContent(document.breaks, startIndex, endIndex, text.length);
5545
5799
  IndexedElementOperationsHelper.replaceContent(document.tabs, startIndex, endIndex, text.length);
5800
+ RangeElementHelper.replaceContent(document.comments, startIndex, endIndex, text.length);
5546
5801
  PageFormatOperationsHelper.replaceContent(document, startIndex, endIndex, text.length);
5547
5802
  LinkOperationsHelper.replaceContent(document.links, startIndex, endIndex, text.length);
5548
5803
  }
5549
- static replace(document, model, contentWidth) {
5804
+ static addComment(document, comment) {
5805
+ document.comments.push(comment);
5806
+ }
5807
+ static removeComment(document, commentId) {
5808
+ const comment = document.comments.find(x => x.commentId === commentId);
5809
+ document.comments = document.comments.filter(x => x.commentId !== commentId);
5810
+ return comment;
5811
+ }
5812
+ static replace(document, contents, model) {
5550
5813
  this.delete(document, model.delete.startIndex, model.delete.count);
5551
5814
  if (model.insertText) {
5552
- this.insertText(document, model.insertText.text, model.insertText.insertIndex);
5815
+ this.insertText(contents, model.insertText.text, model.insertText.insertIndex);
5553
5816
  }
5554
5817
  else if (model.insertElement) {
5555
- this.insertElement(document, model.insertElement);
5818
+ this.insertElement(contents, model.insertElement);
5556
5819
  }
5557
5820
  else if (model.insertTab) {
5558
- this.insertTab(document, model.insertTab.insertIndex);
5821
+ this.insertTab(contents, model.insertTab.insertIndex);
5559
5822
  }
5560
5823
  else if (model.insertBreak) {
5561
5824
  const text = model.insertBreak.isOnNewParagraph ? `${NEW_LINE_MARKUP}${CUSTOM_ELEMENT_MARKER}` : CUSTOM_ELEMENT_MARKER;
5562
- this.insertBreak(document, text, model.insertBreak.insertIndex, model.insertBreak.breakType);
5825
+ this.insertBreak(contents, text, model.insertBreak.insertIndex, model.insertBreak.breakType);
5563
5826
  }
5564
5827
  else if (model.insertImage) {
5565
- this.insertImage(document, model.insertImage.insertIndex, model.insertImage.imageData);
5828
+ this.insertImage(contents, model.insertImage.insertIndex, model.insertImage.imageData);
5566
5829
  }
5567
5830
  else if (model.insertTable) {
5568
- this.insertTable(document, model.insertTable, contentWidth);
5831
+ const insertTableModel = model.insertTable;
5832
+ const contentWidth = this.getContentWidth(document, contents, insertTableModel.insertIndex);
5833
+ this.insertTable(contents, insertTableModel, contentWidth);
5569
5834
  }
5570
5835
  else if (model.insertLink) {
5571
- this.insertLink(document, model.insertLink.linkDataModel.text, model.insertLink.linkDataModel.link, model.insertLink.insertIndex);
5836
+ this.insertLink(contents, model.insertLink.linkDataModel.text, model.insertLink.linkDataModel.link, model.insertLink.insertIndex);
5572
5837
  }
5573
5838
  }
5574
5839
  static applyTextStyle(document, startIndex, endIndex, style) {
@@ -5910,11 +6175,12 @@ class PositionHelper {
5910
6175
  const numberingOffsetLeft = paragraphSettings.numberingData.numberingId === null
5911
6176
  ? 0
5912
6177
  : paragraphSettings.numberingData.width + paragraphSettings.numberingData.paddingLeft;
5913
- if (lineIndex === 0 &&
5914
- (textLineInfo.indentFirstLine ||
6178
+ if (textLineInfo.isNumbering &&
6179
+ lineIndex === 0 &&
6180
+ (textLineInfo.indentFirstLine !== null ||
5915
6181
  (numberingOffsetLeft - textLineInfo.indentLeft > 0 &&
5916
- numberingOffsetLeft - textLineInfo.indentLeft < textLineInfo.markerWidth))) {
5917
- return DEFAULT_OFFSET_AFTER_NUMBERING_MARKER;
6182
+ numberingOffsetLeft - textLineInfo.indentLeft <= textLineInfo.markerWidth))) {
6183
+ return textLineInfo.markerWidth;
5918
6184
  }
5919
6185
  return 0;
5920
6186
  }
@@ -5991,7 +6257,7 @@ class RenderingHelper {
5991
6257
  lineEl.className = 'noder-line';
5992
6258
  if (lineInfo) {
5993
6259
  const paddingLeft = ScalingHelper.scale(lineInfo.paddingLeft, scalingRatio);
5994
- const marginLeft = numberingOffsetLeft > 0 ? -numberingOffsetLeft : 0;
6260
+ const marginLeft = numberingOffsetLeft !== null ? -numberingOffsetLeft : 0;
5995
6261
  // eslint-disable-next-line prettier/prettier
5996
6262
  let styleString = `padding-left:${paddingLeft}px;height:${lineInfo.height + lineInfo.offsetAfter}px;margin-top:${lineInfo.offsetBefore}px;margin-bottom:${lineInfo.endPageOffset}px;margin-left:${marginLeft}px;background-color:${lineInfo.backgroundColor};`;
5997
6263
  if (lineInfo.wordSpacing) {
@@ -6021,10 +6287,11 @@ class RenderingHelper {
6021
6287
  ? 0
6022
6288
  : currentParagraph.numberingData.width + currentParagraph.numberingData.paddingLeft;
6023
6289
  let markerWidth = 0;
6024
- if (currentParagraph.textLinesInfo[0].indentFirstLine ||
6025
- (numberingOffsetLeft - currentParagraph.textLinesInfo[0].indentLeft > 0 &&
6026
- numberingOffsetLeft - currentParagraph.textLinesInfo[0].indentLeft < currentParagraph.textLinesInfo[0].markerWidth)) {
6027
- markerWidth = DEFAULT_OFFSET_AFTER_NUMBERING_MARKER;
6290
+ if (currentParagraph.textLinesInfo[0].isNumbering &&
6291
+ (currentParagraph.textLinesInfo[0].indentFirstLine !== null ||
6292
+ (numberingOffsetLeft - currentParagraph.textLinesInfo[0].indentLeft > 0 &&
6293
+ numberingOffsetLeft - currentParagraph.textLinesInfo[0].indentLeft < currentParagraph.textLinesInfo[0].markerWidth))) {
6294
+ markerWidth = currentParagraph.textLinesInfo[0].markerWidth;
6028
6295
  }
6029
6296
  let lineEl = RenderingHelper.createLineElement(currentParagraph.textLinesInfo[splitIndex], numberingOffsetLeft - markerWidth, scalingRatio);
6030
6297
  domContent.parentNode.appendChild(lineEl);
@@ -6896,9 +7163,10 @@ class TextLayer {
6896
7163
  ? 0
6897
7164
  : paragraphSettings.numberingData.width + paragraphSettings.numberingData.paddingLeft - markerWidth;
6898
7165
  let offset = 0;
6899
- if (numberingOffsetLeft - paragraphSettings.textLinesInfo[0].indentLeft > 0 &&
7166
+ if (paragraphSettings.textLinesInfo[0].isNumbering &&
7167
+ numberingOffsetLeft - paragraphSettings.textLinesInfo[0].indentLeft > 0 &&
6900
7168
  numberingOffsetLeft - paragraphSettings.textLinesInfo[0].indentLeft < paragraphSettings.textLinesInfo[0].markerWidth) {
6901
- offset = DEFAULT_OFFSET_AFTER_NUMBERING_MARKER;
7169
+ offset = paragraphSettings.textLinesInfo[0].markerWidth;
6902
7170
  }
6903
7171
  const lineInfo = paragraphSettings.textLinesInfo[0];
6904
7172
  const lastLineEl = this.renderingHelper.createLineElement(lineInfo, numberingOffsetLeft - offset, this.session.generalProperties.scalingRatio);
@@ -7221,6 +7489,9 @@ class CommandModel {
7221
7489
  if (fields.applyTextStyle) {
7222
7490
  fields.applyTextStyle = new ApplyTextStyleModel(fields.applyTextStyle);
7223
7491
  }
7492
+ if (fields.attachComment) {
7493
+ fields.attachComment = new AttachCommentModel(fields.attachComment);
7494
+ }
7224
7495
  if (fields.createEdges) {
7225
7496
  fields.createEdges = new CreateEdgesModel(fields.createEdges);
7226
7497
  }
@@ -7263,6 +7534,9 @@ class CommandModel {
7263
7534
  if (fields.moveRange) {
7264
7535
  fields.moveRange = new MoveRangeModel(fields.moveRange);
7265
7536
  }
7537
+ if (fields.removeComment) {
7538
+ fields.removeComment = new RemoveCommentModel(fields.removeComment);
7539
+ }
7266
7540
  if (fields.removeEdges) {
7267
7541
  fields.removeEdges = new RemoveEdgesModel(fields.removeEdges);
7268
7542
  }
@@ -7441,6 +7715,12 @@ class SaveCommandsHelper {
7441
7715
  static getRestorePageFormatsCommand(restorePageFormats, targets) {
7442
7716
  return new CommandModel({ commandType: CommandType.RestorePageFormats, restorePageFormats, targets });
7443
7717
  }
7718
+ static getAttachCommentCommand(attachComment, targets) {
7719
+ return new CommandModel({ commandType: CommandType.AttachComment, attachComment, targets });
7720
+ }
7721
+ static getRemoveCommentCommand(removeComment, targets) {
7722
+ return new CommandModel({ commandType: CommandType.RemoveComment, removeComment, targets });
7723
+ }
7444
7724
  static getApplyDocumentPageFormatCommand(applyDocumentPageFormat, targets) {
7445
7725
  return new CommandModel({ commandType: CommandType.ApplyDocumentPageFormat, applyDocumentPageFormat, targets });
7446
7726
  }
@@ -8255,6 +8535,7 @@ class Editor {
8255
8535
  this.edgeElementTagName = 'APP-NOD-EDGE';
8256
8536
  this.imageTagName = 'APP-NOD-IMAGE';
8257
8537
  this.subscriptions = [];
8538
+ this.commentCreateRequests = [];
8258
8539
  this.emojiRegex = /\p{Extended_Pictographic}(?:\p{Emoji_Modifier}|\u{200D}\p{Extended_Pictographic})*/gu;
8259
8540
  this.isRerenderSubscriptionOpen = true;
8260
8541
  this.rerenderResize = () => {
@@ -8282,8 +8563,9 @@ class Editor {
8282
8563
  this.initResizeListener();
8283
8564
  this.focus();
8284
8565
  this.session.applyToolbarStyles();
8566
+ this.onSetCommentsVisibility(!!this.model.comments.length);
8285
8567
  this.search = new Search(editorService);
8286
- this.subscriptions.push(this.changedEdgeSizeSubscription(), this.changedEdgeSubscription(), this.changedTableSizeSubscription(), this.clipboardDataSubscription(), this.copySelectedSubscription(), this.createCustomComponentSubscription(), this.replaceByCustomComponentSubscription(), this.cutSelectedSubscription(), this.disableSelectionSubscription(), this.endMousePressSubscription(), this.imageLoadedSubscription(), this.insertBreakSubscription(), this.insertImageSubscription(), this.insertLinkSubscription(), this.insertTableColumnsSubscription(), this.insertTableRowsSubscription(), this.insertTableSubscription(), this.updateTableBorderStyleSubscription(), this.updateTableBorderWidthSubscription(), this.updateTableBordersSubscription(), this.insertTextSubscription(), this.pasteFromClipboardSubscription(), this.printSubscription(), this.redoSubscription(), this.removeLeftSubscription(), this.removeNumberingsSubscription(), this.removeRightSubscription(), this.removeSelectedSubscription(), this.removeTableColumnsSubscription(), this.removeTableRowsSubscription(), this.removeTableSubscription(), this.rerenderSubscription(), this.resizeTableColumnsSubscription(), ...this.searchOptionSubscriptions(), ...this.replaceSubscription(), this.grammarReplaceSubscription(), this.ignoreGrammarErrorSubscription(), this.selectAllSubscription(), this.setImageStyleSubscription(), this.setNumberingTemplateTypeSubscription(), this.setParagraphStylesSubscription(), this.setTextStylesSubscription(), this.undoSubscription(), this.updateEdgeSubscription(), this.viewOnlyModeSubscription(), this.applyPageFormatSubscription(), this.applyRightMarginPageFormatSubscription(), this.applyLeftMarginPageFormatSubscription(), this.insertPageFormatSubscription(), this.applyDocumentPageFormatSubscription(), this.dragMoveSubscription(), this.dragDropSubscription(), this.applyFirstLinePositionSubscription(), this.applyRightIndentParagraphSubscription(), this.applyLeftIndentParagraphSubscription(), this.applyTabSettingsSubscription(), this.commandCreatedForEdges());
8568
+ this.subscriptions.push(this.changedEdgeSizeSubscription(), this.changedEdgeSubscription(), this.changedTableSizeSubscription(), this.clipboardDataSubscription(), this.copySelectedSubscription(), this.createCustomComponentSubscription(), this.replaceByCustomComponentSubscription(), this.cutSelectedSubscription(), this.disableSelectionSubscription(), this.endMousePressSubscription(), this.imageLoadedSubscription(), this.insertBreakSubscription(), this.insertImageSubscription(), this.insertLinkSubscription(), this.insertTableColumnsSubscription(), this.insertTableRowsSubscription(), this.insertTableSubscription(), this.updateTableBorderStyleSubscription(), this.updateTableBorderWidthSubscription(), this.updateTableBordersSubscription(), this.insertTextSubscription(), this.pasteFromClipboardSubscription(), this.printSubscription(), this.redoSubscription(), this.removeLeftSubscription(), this.removeNumberingsSubscription(), this.removeRightSubscription(), this.removeSelectedSubscription(), this.removeTableColumnsSubscription(), this.removeTableRowsSubscription(), this.removeTableSubscription(), this.rerenderSubscription(), this.resizeTableColumnsSubscription(), ...this.searchOptionSubscriptions(), ...this.replaceSubscription(), this.grammarReplaceSubscription(), this.ignoreGrammarErrorSubscription(), this.selectAllSubscription(), this.setImageStyleSubscription(), this.setNumberingTemplateTypeSubscription(), this.setParagraphStylesSubscription(), this.setTextStylesSubscription(), this.undoSubscription(), this.updateEdgeSubscription(), this.viewOnlyModeSubscription(), this.applyPageFormatSubscription(), this.applyRightMarginPageFormatSubscription(), this.applyLeftMarginPageFormatSubscription(), this.insertPageFormatSubscription(), this.applyDocumentPageFormatSubscription(), this.dragMoveSubscription(), this.dragDropSubscription(), this.applyFirstLinePositionSubscription(), this.applyRightIndentParagraphSubscription(), this.applyLeftIndentParagraphSubscription(), this.applyTabSettingsSubscription(), this.commandCreatedForEdges(), ...this.commentCreationSubscriptions(), this.removeCommentSubscription(), this.rerenderCommentsSubscription(), this.selectCommentSubscription(), this.setComentsVisibilitySubscription());
8287
8569
  }
8288
8570
  destroy() {
8289
8571
  this.subscriptions.forEach(s => s?.unsubscribe());
@@ -8431,9 +8713,9 @@ class Editor {
8431
8713
  if (paragraph.paragraphSettings.numberingData.numberingId && paragraph.paragraphSettings.numberingData.level <= 6) {
8432
8714
  this.applyParagraphStyles(new ParagraphStyleModel({
8433
8715
  numberingLevel: paragraph.paragraphSettings.numberingData.level + 1,
8434
- indentLeft: 0,
8435
- indentFirstLine: 0,
8436
- indentHanging: 0
8716
+ indentLeft: null,
8717
+ indentFirstLine: null,
8718
+ indentHanging: null
8437
8719
  }));
8438
8720
  return;
8439
8721
  }
@@ -8459,9 +8741,9 @@ class Editor {
8459
8741
  }
8460
8742
  this.applyParagraphStyles(new ParagraphStyleModel({
8461
8743
  numberingLevel: paragraph.paragraphSettings.numberingData.level - 1,
8462
- indentLeft: 0,
8463
- indentFirstLine: 0,
8464
- indentHanging: 0
8744
+ indentLeft: null,
8745
+ indentFirstLine: null,
8746
+ indentHanging: null
8465
8747
  }));
8466
8748
  return;
8467
8749
  }
@@ -8563,7 +8845,7 @@ class Editor {
8563
8845
  const partIndexes = ContentHelper.getSelectedPartDocumentIndexes(this.session.displayData.paragraphs, this.selection.range);
8564
8846
  model.delete = new DeleteModel({ startIndex: partIndexes.startIndex, count: partIndexes.endIndex - partIndexes.startIndex + 1 });
8565
8847
  this.saveReplaceToHistory(this.selection.range, model);
8566
- this.removeCustomElementsData();
8848
+ this.removeExternalData();
8567
8849
  const endPosition = this.session.replace(model);
8568
8850
  this.onDocumentChange(new Range(this.selection.cursor, endPosition));
8569
8851
  this.onSelectionChange();
@@ -8770,6 +9052,7 @@ class Editor {
8770
9052
  const deepCopy = structuredClone(operation);
8771
9053
  this.editorService.restoreCustomElementsData(deepCopy.elements);
8772
9054
  this.session.restore(deepCopy);
9055
+ this.editorService.restoreCommentData(operation.comments.map(x => x.commentId));
8773
9056
  command = SaveCommandsHelper.getRestoreCommand(deepCopy, this.targets);
8774
9057
  }
8775
9058
  else if (operation instanceof ApplyTextStyleModel) {
@@ -8885,6 +9168,7 @@ class Editor {
8885
9168
  const deepCopy = structuredClone(operation);
8886
9169
  this.editorService.restoreCustomElementsData(deepCopy.restore.elements);
8887
9170
  this.session.restoreWithParagraph(deepCopy);
9171
+ this.editorService.restoreCommentData(operation.restore.comments.map(x => x.commentId));
8888
9172
  command = SaveCommandsHelper.getRestoreWithParagraphCommand(deepCopy, this.targets);
8889
9173
  }
8890
9174
  else if (operation instanceof MoveRangeModel) {
@@ -8920,8 +9204,19 @@ class Editor {
8920
9204
  const deepCopy = structuredClone(operation);
8921
9205
  this.editorService.restoreCustomElementsData(deepCopy.restore.elements);
8922
9206
  this.session.replaceByRestore(structuredClone(deepCopy));
9207
+ this.editorService.restoreCommentData(operation.restore.comments.map(x => x.commentId));
8923
9208
  command = SaveCommandsHelper.getReplaceByRestoreCommand(structuredClone(deepCopy), this.targets);
8924
9209
  }
9210
+ else if (operation instanceof AttachCommentModel) {
9211
+ this.session.addComment(operation.comment);
9212
+ this.editorService.restoreCommentData([operation.comment.commentId]);
9213
+ command = SaveCommandsHelper.getAttachCommentCommand(operation, this.targets);
9214
+ }
9215
+ else if (operation instanceof RemoveCommentModel) {
9216
+ this.session.removeComment(operation.commentId);
9217
+ this.editorService.removeCommentData([operation.commentId]);
9218
+ command = SaveCommandsHelper.getRemoveCommentCommand(operation, this.targets);
9219
+ }
8925
9220
  else if (operation instanceof ApplyParagraphsModel) {
8926
9221
  const deepCopy = structuredClone(operation);
8927
9222
  this.session.applyParagraphs(deepCopy.paragraphs);
@@ -8938,6 +9233,14 @@ class Editor {
8938
9233
  this.commandsService.createCommand(command);
8939
9234
  this.renderer.updateCursor();
8940
9235
  }
9236
+ saveAttachCommentToHistory(commentModel) {
9237
+ this.history.pushAttachComment(commentModel);
9238
+ this.commandsService.createCommand(SaveCommandsHelper.getAttachCommentCommand(new AttachCommentModel({ comment: commentModel }), this.targets));
9239
+ }
9240
+ saveRemoveCommentToHistory(comment, target) {
9241
+ this.history.pushRemoveComment(comment);
9242
+ this.commandsService.createCommand(SaveCommandsHelper.getRemoveCommentCommand(new RemoveCommentModel({ commentId: comment.commentId }), [target]));
9243
+ }
8941
9244
  saveRemoveToHistory(range) {
8942
9245
  const restore = this.session.createRestoreFromSlice(range.start, range.end);
8943
9246
  this.history.pushDelete(restore);
@@ -9114,7 +9417,7 @@ class Editor {
9114
9417
  }
9115
9418
  else {
9116
9419
  this.saveRemoveToHistory(range);
9117
- this.removeCustomElementsData();
9420
+ this.removeExternalData();
9118
9421
  this.session.remove(range);
9119
9422
  this.onSelectionChange();
9120
9423
  this.onContentChange();
@@ -9135,18 +9438,22 @@ class Editor {
9135
9438
  paragraphStyle: new ParagraphStyleModel({ ...lastParagraph.paragraphStyle })
9136
9439
  });
9137
9440
  this.saveRemoveWithParagraphToHistory(operation, reversed);
9138
- this.removeCustomElementsData();
9441
+ this.removeExternalData();
9139
9442
  this.session.removeWithParagraph(operation);
9140
9443
  this.onSelectionChange();
9141
9444
  this.onContentChange();
9142
9445
  }
9143
- removeCustomElementsData() {
9446
+ removeExternalData() {
9144
9447
  const startIndex = ContentHelper.paragraphPositionToDocumentIndex(this.session.displayData.paragraphs, this.selection.range.start);
9145
9448
  const endIndex = ContentHelper.paragraphPositionToDocumentIndex(this.session.displayData.paragraphs, this.selection.range.end) - 1;
9146
9449
  const elements = IndexedElementHelper.sliceSection(this.session.model.elements, startIndex, endIndex).slice();
9147
9450
  if (elements.length) {
9148
9451
  this.editorService.removeCustomElementsData(elements);
9149
9452
  }
9453
+ const comments = ContentHelper.getCommentsInRange(this.session.model.comments, startIndex, endIndex);
9454
+ if (comments.length) {
9455
+ this.editorService.removeCommentData(comments.map(x => x.commentId));
9456
+ }
9150
9457
  }
9151
9458
  removeOrLowerNestingNumbering(paragraph) {
9152
9459
  if (paragraph.paragraphSettings.numberingData.level > 0) {
@@ -9190,6 +9497,39 @@ class Editor {
9190
9497
  const data = this.textInput.getClipboardData(event);
9191
9498
  this.pasteData(data);
9192
9499
  }
9500
+ onCreateComment() {
9501
+ const startIndex = ContentHelper.paragraphPositionToDocumentIndex(this.session.displayData.paragraphs, this.selection.range.start);
9502
+ const endIndex = ContentHelper.paragraphPositionToDocumentIndex(this.session.displayData.paragraphs, this.selection.range.end);
9503
+ const reqId = Date.now();
9504
+ const comment = new CommentModel({ startIndex, endIndex });
9505
+ this.commentCreateRequests.push({ sessionId: this.session.sessionId, reqId, comment });
9506
+ this.editorService.createComment(reqId);
9507
+ }
9508
+ onCommentCreated(reqId, commentId) {
9509
+ const request = this.commentCreateRequests.find(x => x.reqId === reqId);
9510
+ const commentModel = request.comment;
9511
+ if (!commentModel) {
9512
+ return;
9513
+ }
9514
+ const sessionModel = this.regulatorService.getSessionModel(request.sessionId);
9515
+ this.commentCreateRequests = this.commentCreateRequests.filter(x => x.reqId !== reqId);
9516
+ commentModel.commentId = commentId;
9517
+ sessionModel.session.addComment(commentModel);
9518
+ sessionModel.renderer.setSelectedComment(commentModel.commentId);
9519
+ sessionModel.renderer.loop.schedule({ comments: true });
9520
+ this.saveAttachCommentToHistory(commentModel);
9521
+ }
9522
+ onCommentRemoved(id) {
9523
+ const { session, target } = this.regulatorService.getCommentTarget(id);
9524
+ const comment = session.session.removeComment(id);
9525
+ this.saveRemoveCommentToHistory(comment, target);
9526
+ this.editorService.removeCommentData([id]);
9527
+ session.renderer.loop.schedule({ comments: true });
9528
+ }
9529
+ onSetCommentsVisibility(value) {
9530
+ this.commentsVisible = value;
9531
+ this.regulatorService.setCommentsVisibility(value);
9532
+ }
9193
9533
  initResizeListener() {
9194
9534
  window.addEventListener('resize', this.rerenderResize);
9195
9535
  }
@@ -9312,6 +9652,7 @@ class Editor {
9312
9652
  const range = this.session.getWordRange(position.row, position.column);
9313
9653
  this.selection.placeSelection(range.start, range.end);
9314
9654
  }
9655
+ this.setCommentPopup(event);
9315
9656
  this.onSelectionChange();
9316
9657
  }
9317
9658
  onTripleClick(event) {
@@ -9325,6 +9666,7 @@ class Editor {
9325
9666
  const start = new CursorParagraph(position.row, 0);
9326
9667
  const end = new CursorParagraph(position.row, this.session.displayData.getParagraphContent(position.row).length);
9327
9668
  this.selection.placeSelection(start, end);
9669
+ this.setCommentPopup(event);
9328
9670
  this.onSelectionChange();
9329
9671
  }
9330
9672
  onQuadClick(event) {
@@ -9335,19 +9677,31 @@ class Editor {
9335
9677
  }
9336
9678
  event.preventDefault();
9337
9679
  this.selection.selectAll(this.session.model);
9680
+ this.setCommentPopup(event);
9338
9681
  this.onSelectionChange();
9339
9682
  }
9340
9683
  onMouseWheel(event) {
9341
9684
  if (event.ctrlKey) {
9342
9685
  return;
9343
9686
  }
9687
+ event.stopPropagation();
9688
+ event.preventDefault();
9344
9689
  const factor = 0.35;
9345
9690
  const scrollSpeed = 4;
9346
- const deltaY = event.deltaY * factor * scrollSpeed;
9691
+ let deltaY = event.deltaY * factor * scrollSpeed;
9692
+ const scrollTop = this.mainRenderer.scrollBar.scrollTop;
9693
+ const maxScroll = this.mainSession.displayData.allPagesHeight - this.mainRenderer.size.scrollerHeight;
9694
+ if (scrollTop + deltaY < 0) {
9695
+ deltaY = -scrollTop;
9696
+ }
9697
+ else if (scrollTop + deltaY > maxScroll) {
9698
+ deltaY = maxScroll - scrollTop;
9699
+ }
9700
+ if (deltaY === 0) {
9701
+ return;
9702
+ }
9347
9703
  this.onScroll(deltaY);
9348
9704
  this.overlayService.scroll(deltaY);
9349
- event.stopPropagation();
9350
- event.preventDefault();
9351
9705
  }
9352
9706
  onScroll(deltaY) {
9353
9707
  this.mainRenderer.scrollBy(deltaY);
@@ -9505,8 +9859,18 @@ class Editor {
9505
9859
  this.editorService.paragraphStyle(paragraphStyle, numbering);
9506
9860
  this.editorService.setPageFormat(pageFormat.pageFormatModel);
9507
9861
  this.rerenderMarker();
9862
+ this.updateSelectedComment();
9863
+ if (!this.selection.isEmpty && this.commentsVisible) {
9864
+ const cursor = PositionHelper.documentToPixel(this.session, this.session.selection.cursor);
9865
+ const mainRect = this.mainRenderer.container.getBoundingClientRect();
9866
+ const rect = this.renderer.container.getBoundingClientRect();
9867
+ const hintX = mainRect.right - 20;
9868
+ const hintY = rect.top + cursor.pageY + cursor.lineHeight / 2 - 20;
9869
+ this.overlayService.open(CommentPopupComponent, {}, hintX, hintY);
9870
+ }
9508
9871
  }
9509
9872
  onContentChange() {
9873
+ this.renderer.loop.schedule({ comments: true });
9510
9874
  if (this.search.term) {
9511
9875
  this.find(this.search.term);
9512
9876
  }
@@ -9616,6 +9980,9 @@ class Editor {
9616
9980
  }
9617
9981
  this.scrollCursorIntoMainView();
9618
9982
  }
9983
+ onMousePressEnd(event) {
9984
+ this.setCommentPopup(event);
9985
+ }
9619
9986
  provideTextStyle(component) {
9620
9987
  const session = this.regulatorService.getSession(component.sessionId);
9621
9988
  const format = session.model.formats.find(x => x.startIndex <= component.insertIndex && x.endIndex >= component.insertIndex);
@@ -9776,7 +10143,7 @@ class Editor {
9776
10143
  }
9777
10144
  applyFirstLinePositionSubscription() {
9778
10145
  return this.editorService.firstLinePosition$.subscribe(x => {
9779
- const value = x > 0 ? { indentFirstLine: x, indentHanging: 0 } : { indentHanging: Math.abs(x), indentFirstLine: 0 };
10146
+ const value = x > 0 ? { indentFirstLine: x, indentHanging: null } : { indentHanging: Math.abs(x), indentFirstLine: null };
9780
10147
  this.applyParagraphsMargin(value);
9781
10148
  });
9782
10149
  }
@@ -9829,7 +10196,7 @@ class Editor {
9829
10196
  }
9830
10197
  endMousePressSubscription() {
9831
10198
  return this.editorService.endMousePress$.subscribe(() => {
9832
- this.mouseHandler.endMousePress();
10199
+ this.mouseHandler.endMousePress(this, null);
9833
10200
  });
9834
10201
  }
9835
10202
  disableSelectionSubscription() {
@@ -10025,6 +10392,28 @@ class Editor {
10025
10392
  }
10026
10393
  });
10027
10394
  }
10395
+ commentCreationSubscriptions() {
10396
+ return [
10397
+ this.editorService.addCommentAtSelection$.subscribe(() => this.onCreateComment()),
10398
+ this.editorService.commentCreated$.subscribe(x => this.onCommentCreated(x.reqId, x.commentId))
10399
+ ];
10400
+ }
10401
+ rerenderCommentsSubscription() {
10402
+ return this.editorService.commentSizeChanged$.subscribe(() => this.mainRenderer.loop.schedule({ comments: true }));
10403
+ }
10404
+ selectCommentSubscription() {
10405
+ return this.editorService.setCommentSelected$.subscribe(x => {
10406
+ for (const session of this.regulatorService.sessions) {
10407
+ session.renderer.setSelectedComment(x);
10408
+ }
10409
+ });
10410
+ }
10411
+ removeCommentSubscription() {
10412
+ return this.editorService.removeComment$.subscribe(x => this.onCommentRemoved(x));
10413
+ }
10414
+ setComentsVisibilitySubscription() {
10415
+ return this.editorService.setCommentsVisibility$.subscribe(x => this.onSetCommentsVisibility(x));
10416
+ }
10028
10417
  recreateMainSession() {
10029
10418
  while (this.regulatorService.sessions.length > 0) {
10030
10419
  const session = this.regulatorService.sessions[0];
@@ -10070,6 +10459,28 @@ class Editor {
10070
10459
  sessionModel.session.selection.placeCursor(this.search.currentMatch.range.start);
10071
10460
  this.renderer.updateCursor();
10072
10461
  }
10462
+ setCommentPopup(event) {
10463
+ if (this.selection.range.isEmpty || !this.commentsVisible) {
10464
+ return;
10465
+ }
10466
+ const cursor = PositionHelper.documentToPixel(this.session, this.session.selection.cursor);
10467
+ const mainRect = this.mainRenderer.container.getBoundingClientRect();
10468
+ const rect = this.renderer.container.getBoundingClientRect();
10469
+ const hintX = mainRect.right - 20;
10470
+ const hintY = rect.top + cursor.pageY + cursor.lineHeight / 2 - 20;
10471
+ this.overlayService.open(CommentPopupComponent, {}, hintX, hintY);
10472
+ event?.stopPropagation();
10473
+ }
10474
+ updateSelectedComment() {
10475
+ for (const session of this.regulatorService.sessions) {
10476
+ if (!this.selection.range.isEmpty || session.session !== this.session) {
10477
+ session.renderer.setSelectedComment(null);
10478
+ continue;
10479
+ }
10480
+ const comment = session.session.getCommentAtCursor();
10481
+ session.renderer.setSelectedComment(comment?.commentId);
10482
+ }
10483
+ }
10073
10484
  }
10074
10485
 
10075
10486
  const EDITOR_VERSION = '2';
@@ -10320,6 +10731,7 @@ class DisplayTokenHelper {
10320
10731
  }
10321
10732
  info.width += wrapToken.width;
10322
10733
  }
10734
+ info.maxAscent = maxAscent;
10323
10735
  info.height = maxAscent + maxDescent;
10324
10736
  info.offsetAfter = info.height * (info.lineSpacing - 1);
10325
10737
  return info;
@@ -11692,13 +12104,13 @@ class NumberingHelper {
11692
12104
  paragraph.numberingData.markerTextStyle = markerTextStyle;
11693
12105
  paragraph.numberingData.width = markerSizes.width;
11694
12106
  paragraph.numberingData.height = markerSizes.height;
11695
- const indentLeft = paragraphStyle.indentLeft ? paragraphStyle.indentLeft : numberingLevel.indentLeft;
12107
+ const indentLeft = paragraphStyle.indentLeft !== null ? paragraphStyle.indentLeft : numberingLevel.indentLeft;
11696
12108
  let indent = 0;
11697
- if (!paragraphStyle.indentHanging && !paragraphStyle.indentFirstLine) {
12109
+ if (paragraphStyle.indentHanging === null && paragraphStyle.indentFirstLine === null) {
11698
12110
  indent = -numberingLevel.indentHanging;
11699
12111
  }
11700
12112
  else {
11701
- indent = paragraphStyle.indentHanging ? -paragraphStyle.indentHanging : paragraphStyle.indentFirstLine;
12113
+ indent = paragraphStyle.indentHanging !== null ? -paragraphStyle.indentHanging : paragraphStyle.indentFirstLine;
11702
12114
  }
11703
12115
  paragraph.numberingData.paddingLeft = indentLeft + indent;
11704
12116
  }
@@ -12468,7 +12880,7 @@ class DisplayData extends EventEmitting {
12468
12880
  const isLastLineOfParagraph = !wrapLimit || prevToken.isLineBreak;
12469
12881
  if (paragraphStyle.alignment === Alignment$1.justify && !isLastLineOfParagraph && wrapTokens.length > 1) {
12470
12882
  let currentLineWidth = 0;
12471
- let spaceCount = 0;
12883
+ let spaceCount = wrapTokens[0].markerWidth ? 1 : 0;
12472
12884
  for (let i = 0; i < wrapTokens.length; i++) {
12473
12885
  const token = wrapTokens[i];
12474
12886
  currentLineWidth += token.width;
@@ -12483,7 +12895,7 @@ class DisplayData extends EventEmitting {
12483
12895
  }
12484
12896
  const { left, right, firstLine, hanging } = lineInfo.indent;
12485
12897
  const indent = left + right + firstLine - hanging || 0;
12486
- const availableWidth = pageFormat.contentWidth - indent;
12898
+ const availableWidth = pageFormat.contentWidth - indent - wrapTokens[0].markerWidth;
12487
12899
  const whitespaceDeficit = availableWidth - currentLineWidth;
12488
12900
  if (spaceCount > 0 && whitespaceDeficit > 0) {
12489
12901
  lineInfo.wordSpacing = whitespaceDeficit / spaceCount;
@@ -12550,7 +12962,7 @@ class DisplayData extends EventEmitting {
12550
12962
  indentBefore: lineInfo.offsetBefore,
12551
12963
  indentAfter: lineInfo.offsetAfter,
12552
12964
  lineSpacing: lineInfo.lineSpacing,
12553
- markerWidth: lineInfo.markerWidth,
12965
+ markerWidth: isFirstCharacter && lineInfo.isNumbering ? lineInfo.markerWidth : 0,
12554
12966
  isNumbering: lineInfo.isNumbering,
12555
12967
  isPageBreak: breakType === BreakTypes.Page,
12556
12968
  isLineBreak: breakType === BreakTypes.TextWrapping,
@@ -12681,7 +13093,7 @@ class DisplayData extends EventEmitting {
12681
13093
  indentBefore: lineInfo.offsetBefore,
12682
13094
  indentAfter: lineInfo.offsetAfter,
12683
13095
  lineSpacing: lineInfo.lineSpacing,
12684
- markerWidth: lineInfo.markerWidth,
13096
+ markerWidth: isFirstCharacter && lineInfo.isNumbering ? lineInfo.markerWidth : 0,
12685
13097
  isPageBreak: breakType === BreakTypes.Page,
12686
13098
  isLineBreak: breakType === BreakTypes.TextWrapping,
12687
13099
  isTab: false,
@@ -12804,16 +13216,17 @@ class DisplayData extends EventEmitting {
12804
13216
  markerWidth = markerSizes.width;
12805
13217
  let indentHanging = levelModel.indentHanging;
12806
13218
  let indentFirstLine = DEFAULT_PARAGRAPH_STYLE.indentFirstLine;
12807
- if (paragraph.paragraphStyle.indentFirstLine || paragraph.paragraphStyle.indentHanging) {
12808
- if (paragraph.paragraphStyle.indentFirstLine) {
13219
+ if (paragraph.paragraphStyle.indentFirstLine !== null || paragraph.paragraphStyle.indentHanging !== null) {
13220
+ if (paragraph.paragraphStyle.indentFirstLine !== null) {
12809
13221
  indentFirstLine = paragraph.paragraphStyle.indentFirstLine;
12810
- indentHanging = 0;
13222
+ indentHanging = null;
12811
13223
  }
12812
13224
  else {
12813
- indentHanging = paragraph.paragraphStyle.indentHanging ? paragraph.paragraphStyle.indentHanging : levelModel.indentHanging;
13225
+ indentHanging =
13226
+ paragraph.paragraphStyle.indentHanging !== null ? paragraph.paragraphStyle.indentHanging : levelModel.indentHanging;
12814
13227
  }
12815
13228
  }
12816
- const indent = new IndentModel(indentFirstLine, indentHanging, paragraph.paragraphStyle.indentLeft ? paragraph.paragraphStyle.indentLeft : levelModel.indentLeft, paragraph.paragraphStyle.indentRight ?? DEFAULT_PARAGRAPH_STYLE.indentRight);
13229
+ const indent = new IndentModel(indentFirstLine, indentHanging, paragraph.paragraphStyle.indentLeft !== null ? paragraph.paragraphStyle.indentLeft : levelModel.indentLeft, paragraph.paragraphStyle.indentRight ?? DEFAULT_PARAGRAPH_STYLE.indentRight);
12817
13230
  return { indent, markerWidth: markerWidth + markerWidth / marker.length };
12818
13231
  }
12819
13232
  getLineInfoFromTextLine(index) {
@@ -12883,7 +13296,7 @@ class DisplayData extends EventEmitting {
12883
13296
  if (displayTokens[0].isTable || (displayTokens[0].breaksLine && displayTokens.length === 1)) {
12884
13297
  return 1;
12885
13298
  }
12886
- const maxRowWidth = contentWidth - displayTokens[0].indentRight;
13299
+ const maxRowWidth = contentWidth - displayTokens[0].indentRight - displayTokens[0].markerWidth;
12887
13300
  let sum = displayTokens[0].indentLeft + displayTokens[0].indentFirstLine - displayTokens[0].indentHanging || 0;
12888
13301
  let prevTabIndex = null;
12889
13302
  let tabCenter = null;
@@ -13775,10 +14188,11 @@ class EditSession {
13775
14188
  get paragraphInfoChanges$() {
13776
14189
  return this.displayData.ParagraphInfoChanges$;
13777
14190
  }
13778
- constructor(displayData, sessionId, customContentService, model, selection, generalProperties, editorService, customComponents, type, scrollBar, edgeType) {
14191
+ constructor(displayData, sessionId, customContentService, commentRenderService, model, selection, generalProperties, editorService, customComponents, type, scrollBar, edgeType, pageType) {
13779
14192
  this.displayData = displayData;
13780
14193
  this.sessionId = sessionId;
13781
14194
  this.customContentService = customContentService;
14195
+ this.commentRenderService = commentRenderService;
13782
14196
  this.model = model;
13783
14197
  this.selection = selection;
13784
14198
  this.generalProperties = generalProperties;
@@ -13787,6 +14201,7 @@ class EditSession {
13787
14201
  this.type = type;
13788
14202
  this.scrollBar = scrollBar;
13789
14203
  this.edgeType = edgeType;
14204
+ this.pageType = pageType;
13790
14205
  this.tokenRe = new RegExp('^[' + UnicodeHelper.wordChars + '\\$_]+', 'g');
13791
14206
  this.nonTokenRe = new RegExp('^(?:[^' + UnicodeHelper.wordChars + '\\$_]|\\s])+', 'g');
13792
14207
  }
@@ -14135,6 +14550,17 @@ class EditSession {
14135
14550
  this.selection.placeCursor(endPosition);
14136
14551
  return endPosition;
14137
14552
  }
14553
+ addComment(comment) {
14554
+ OperationsHelper.addComment(this.model, comment);
14555
+ this.commentRenderService.createNewComment(comment.commentId);
14556
+ }
14557
+ removeComment(commentId) {
14558
+ return OperationsHelper.removeComment(this.model, commentId);
14559
+ }
14560
+ getCommentAtCursor() {
14561
+ const index = ContentHelper.paragraphPositionToDocumentIndex(this.displayData.paragraphs, this.selection.cursor);
14562
+ return this.model.comments.find(x => index >= x.startIndex && index <= x.endIndex);
14563
+ }
14138
14564
  insertElement(position, element) {
14139
14565
  const insertIndex = ContentHelper.paragraphPositionToDocumentIndex(this.displayData.paragraphs, position);
14140
14566
  const insertElement = new InsertElementModel({ element: new ElementModel({ insertIndex, ...element }) });
@@ -14605,108 +15031,6 @@ class MainSessionSourceModel {
14605
15031
  }
14606
15032
  }
14607
15033
 
14608
- class CursorLayer {
14609
- constructor(parentElement, session) {
14610
- this.session = session;
14611
- this.blinkInterval = 1000;
14612
- this.layer = document.createElement('div');
14613
- this.layer.className = 'noder-layer noder-cursor-layer';
14614
- parentElement.appendChild(this.layer);
14615
- this.cursor = document.createElement('div');
14616
- this.cursor.className = 'noder-cursor';
14617
- this.layer.appendChild(this.cursor);
14618
- this.hideCursor();
14619
- }
14620
- hideCursor() {
14621
- this.isVisible = false;
14622
- DomHelper.addCssClass(this.layer, 'noder-hidden-cursors');
14623
- this.removeAnimationClass();
14624
- }
14625
- showCursor() {
14626
- this.isVisible = true;
14627
- DomHelper.removeCssClass(this.layer, 'noder-hidden-cursors');
14628
- this.addAnimationClass();
14629
- }
14630
- showStaticCursor() {
14631
- this.isVisible = true;
14632
- DomHelper.removeCssClass(this.layer, 'noder-hidden-cursors');
14633
- this.removeAnimationClass();
14634
- }
14635
- detectVisibility() {
14636
- const selectionRange = this.session.selection.selectedRange;
14637
- if (selectionRange.isEmpty) {
14638
- DomHelper.removeCssClass(this.layer, 'selecting');
14639
- return;
14640
- }
14641
- DomHelper.addCssClass(this.layer, 'selecting');
14642
- }
14643
- update(config) {
14644
- this.cursorPosition = this.getPixelPosition();
14645
- this.drawCursor(config.maxHeight);
14646
- this.detectVisibility();
14647
- this.restartAnimation();
14648
- }
14649
- getPixelPosition(position) {
14650
- if (!position) {
14651
- position = this.session.selection.cursor;
14652
- }
14653
- return PositionHelper.documentToPixel(this.session, position);
14654
- }
14655
- addTextStylesToCursor() {
14656
- const textStyle = this.session.editorService.styles;
14657
- DomHelper.setStyle(this.cursor.style, 'border-color', textStyle.fontColor);
14658
- DomHelper.setStyle(this.cursor.style, 'fontSize', `${textStyle.fontSize}px`);
14659
- if (textStyle.italic) {
14660
- DomHelper.setStyle(this.cursor.style, '-webkit-transform', 'skewX(-13deg)');
14661
- }
14662
- else {
14663
- DomHelper.setStyle(this.cursor.style, '-webkit-transform', 'skewX(0)');
14664
- }
14665
- const metricSize = FontMetrics.measureCharSize('EMPTY_LINE', ContentStyleHelper.getFontStylesString(new TextStyleModel({
14666
- italic: textStyle.italic,
14667
- bold: textStyle.bold,
14668
- fontSize: textStyle.fontSize,
14669
- fontFamily: textStyle.fontFamily
14670
- })));
14671
- const fontMetricHeight = metricSize.ascent + metricSize.descent;
14672
- const maxHeight = this.cursorPosition.sizeMax.ascent + this.cursorPosition.sizeMax.descent;
14673
- const fontShoulders = fontMetricHeight - metricSize.font;
14674
- const offset = metricSize.descent - fontShoulders;
14675
- let top = this.cursorPosition.pageY + this.cursorPosition.sizeMax.ascent - metricSize.font + offset;
14676
- if (fontMetricHeight !== maxHeight && maxHeight >= this.cursorPosition.lineHeight) {
14677
- top -= maxHeight - this.cursorPosition.lineHeight;
14678
- }
14679
- DomHelper.setStyle(this.cursor.style, 'top', `${top < 0 ? 0 : top}px`);
14680
- DomHelper.setStyle(this.cursor.style, 'height', `${fontMetricHeight}px`);
14681
- }
14682
- restartAnimation() {
14683
- this.removeAnimationClass();
14684
- if (!this.isVisible) {
14685
- return;
14686
- }
14687
- this.addAnimationClass();
14688
- }
14689
- drawCursor(maxLayerHeight) {
14690
- const isCursorInView = this.cursorPosition.pageY >= 0 && this.cursorPosition.pageY < maxLayerHeight;
14691
- if (!isCursorInView) {
14692
- DomHelper.setStyle(this.cursor.style, 'display', 'none');
14693
- return;
14694
- }
14695
- DomHelper.setStyle(this.cursor.style, 'display', 'block');
14696
- const currentSize = this.cursorPosition.sizeCurrent;
14697
- DomHelper.setStyle(this.cursor.style, 'left', `${this.cursorPosition.pageX}px`);
14698
- DomHelper.setStyle(this.cursor.style, 'width', `${currentSize.width}px`);
14699
- this.addTextStylesToCursor();
14700
- }
14701
- removeAnimationClass() {
14702
- DomHelper.removeCssClass(this.layer, 'noder-animate-blinking');
14703
- }
14704
- addAnimationClass() {
14705
- this.cursor.style.animationDuration = `${this.blinkInterval}ms`;
14706
- DomHelper.addCssClass(this.layer, 'noder-animate-blinking');
14707
- }
14708
- }
14709
-
14710
15034
  class HighlightLayer {
14711
15035
  constructor(parentEl, cssClass, session) {
14712
15036
  this.session = session;
@@ -14726,6 +15050,7 @@ class HighlightLayer {
14726
15050
  }
14727
15051
  selectionElement.style.cssText = cssPosition;
14728
15052
  selectionElement.className = cssClass;
15053
+ return selectionElement;
14729
15054
  }
14730
15055
  getTop(row) {
14731
15056
  const paragraphs = this.session.displayData.paragraphs;
@@ -14751,6 +15076,7 @@ class HighlightLayer {
14751
15076
  paragraphInfo.lineTopOffset -
14752
15077
  this.session.scrollTop;
14753
15078
  const padding = this.session.displayData.pagesFormat[this.session.displayData.pagesFormat.length - 1].pageFormatModel.marginLeft;
15079
+ const results = [];
14754
15080
  for (let i = 0; i < textLinesInfo.length; i++) {
14755
15081
  const lineInfo = textLinesInfo[i].textLinesInfo;
14756
15082
  const paragraphLineIndex = textLinesInfo[i].paragraphSettings.textLinesInfo.findIndex(x => x === textLinesInfo[i].textLinesInfo);
@@ -14763,9 +15089,10 @@ class HighlightLayer {
14763
15089
  ? 0
14764
15090
  : textLinesInfo[i].paragraphSettings.numberingData.width + textLinesInfo[i].paragraphSettings.numberingData.paddingLeft;
14765
15091
  if (paragraphLineIndex === 0 &&
15092
+ lineInfo.isNumbering &&
14766
15093
  (lineInfo.indentFirstLine ||
14767
- (numberingOffsetLeft - lineInfo.indentLeft > 0 && numberingOffsetLeft - lineInfo.indentLeft < lineInfo.markerWidth))) {
14768
- markerWidth = lineInfo.markerWidth ?? 0;
15094
+ (numberingOffsetLeft - lineInfo.indentLeft > 0 && numberingOffsetLeft - lineInfo.indentLeft <= lineInfo.markerWidth))) {
15095
+ markerWidth = lineInfo.markerWidth;
14769
15096
  }
14770
15097
  const left = lineInfo.paddingLeft + padding + lineInfo.offsetMargin + markerWidth;
14771
15098
  let style;
@@ -14783,9 +15110,11 @@ class HighlightLayer {
14783
15110
  let width = lineInfo.width + (lineInfo.wordSpacingWidth ?? 0);
14784
15111
  style = this.getMarkerStyle(lineInfo.height, width, top, left);
14785
15112
  }
14786
- this.renderHighlight(style, cssClass);
15113
+ const result = this.renderHighlight(style, cssClass);
14787
15114
  top += lineInfo.height + lineInfo.offsetAfter + lineInfo.endPageOffset;
15115
+ results.push(result);
14788
15116
  }
15117
+ return results;
14789
15118
  }
14790
15119
  // Draws a marker which covers part or whole width of a single screen line
14791
15120
  drawSingleLineMarker(range, cssClass) {
@@ -14795,17 +15124,20 @@ class HighlightLayer {
14795
15124
  const width = rangeInfo.screenWidth;
14796
15125
  const top = this.getTop(range.start.row);
14797
15126
  const left = rangeInfo.leftPos;
14798
- this.renderHighlight(this.getMarkerStyle(height, width, top, left), cssClass);
15127
+ return this.renderHighlight(this.getMarkerStyle(height, width, top, left), cssClass);
14799
15128
  }
14800
15129
  drawCustomElementHighlight(elementInfo, cssClass, screenParentRange) {
14801
- const elementIndex = this.session.displayData.paragraphs[elementInfo.parentRange.start.row].startIndex + elementInfo.parentRange.start.column;
15130
+ const lineIndex = elementInfo.parentRange.start.row;
15131
+ const paragraph = this.session.displayData.paragraphs[lineIndex];
15132
+ const lineInfo = paragraph.paragraphSettings.textLinesInfo.find(x => x.screenLine === lineIndex);
15133
+ const elementIndex = paragraph.startIndex + elementInfo.parentRange.start.column;
14802
15134
  const element = this.session.customComponents.customElements.find(x => x.instance.content.insertIndex === elementIndex);
14803
15135
  if (!element) {
14804
15136
  return;
14805
15137
  }
14806
15138
  const top = this.getTop(screenParentRange.start.row);
14807
15139
  const info = this.getRangeInfo(this.session, screenParentRange);
14808
- this.renderHighlight(this.getMarkerStyle(elementInfo.location.height, elementInfo.location.width, top + elementInfo.location.top, info.leftPos + elementInfo.location.left), cssClass);
15140
+ this.renderHighlight(this.getMarkerStyle(elementInfo.location.height, elementInfo.location.width, top + lineInfo.maxAscent - elementInfo.location.height + elementInfo.location.top, info.leftPos + elementInfo.location.left), cssClass);
14809
15141
  }
14810
15142
  getRangeInfo(session, range) {
14811
15143
  const start = range.start;
@@ -14823,6 +15155,167 @@ class HighlightLayer {
14823
15155
  }
14824
15156
  }
14825
15157
 
15158
+ class CommentHighlightLayer extends HighlightLayer {
15159
+ constructor(parentEl, cssClass, session, commentService) {
15160
+ super(parentEl, cssClass, session);
15161
+ this.commentService = commentService;
15162
+ this.className = 'noder-highlight';
15163
+ this.selectedCommentClassName = 'noder-selected-highlight';
15164
+ this.selectedCommentId = null;
15165
+ }
15166
+ update(config) {
15167
+ const comments = this.session.model.comments;
15168
+ if (!config?.isVisible || !comments?.length || !this.enabled) {
15169
+ this.element.innerHTML = '';
15170
+ this.commentService.removeCommentsFromRender(this.session.sessionId);
15171
+ return;
15172
+ }
15173
+ this.config = config;
15174
+ this.selectionIndex = 0;
15175
+ const commentRenderRequests = [];
15176
+ for (const comment of comments) {
15177
+ const startPosition = ContentHelper.documentIndexToParagraphIndex(this.session.displayData.paragraphs, comment.startIndex);
15178
+ const endPosition = ContentHelper.documentIndexToParagraphIndex(this.session.displayData.paragraphs, comment.endIndex);
15179
+ const range = new Range(startPosition, endPosition);
15180
+ const screenRange = range.toScreenRange(this.session);
15181
+ if (config.visibleRange &&
15182
+ (screenRange.end.row < config.visibleRange.startScreenLine || screenRange.start.row > config.visibleRange.endScreenLine)) {
15183
+ this.commentService.removeCommentFromRender(this.session.sessionId, comment.commentId);
15184
+ continue;
15185
+ }
15186
+ if (!screenRange.isEmpty) {
15187
+ const className = comment.commentId === this.selectedCommentId ? this.selectedCommentClassName : this.className;
15188
+ const result = screenRange.isSingleLine
15189
+ ? this.drawSingleLineMarker(screenRange, className)
15190
+ : this.drawMultiLineMarker(screenRange, className);
15191
+ commentRenderRequests.push(this.requestCommentRender(result, comment.commentId));
15192
+ }
15193
+ }
15194
+ this.commentService.requestCommentsRender(this.session.sessionId, commentRenderRequests);
15195
+ if (this.selectionIndex !== -1) {
15196
+ while (this.selectionIndex < this.element.childElementCount) {
15197
+ this.element.removeChild(this.element.lastChild);
15198
+ }
15199
+ }
15200
+ }
15201
+ setSelectedComment(id) {
15202
+ if (this.selectedCommentId) {
15203
+ this.commentService.setCommentSelected(this.selectedCommentId, false);
15204
+ }
15205
+ this.selectedCommentId = id;
15206
+ if (id) {
15207
+ this.commentService.setCommentSelected(id);
15208
+ }
15209
+ }
15210
+ requestCommentRender(highlight, id) {
15211
+ const element = Array.isArray(highlight) ? highlight[0] : highlight;
15212
+ const rect = element.getBoundingClientRect();
15213
+ return { commentId: id, top: rect.top, left: rect.left };
15214
+ }
15215
+ }
15216
+
15217
+ class CursorLayer {
15218
+ constructor(parentElement, session) {
15219
+ this.session = session;
15220
+ this.blinkInterval = 1000;
15221
+ this.layer = document.createElement('div');
15222
+ this.layer.className = 'noder-layer noder-cursor-layer';
15223
+ parentElement.appendChild(this.layer);
15224
+ this.cursor = document.createElement('div');
15225
+ this.cursor.className = 'noder-cursor';
15226
+ this.layer.appendChild(this.cursor);
15227
+ this.hideCursor();
15228
+ }
15229
+ hideCursor() {
15230
+ this.isVisible = false;
15231
+ DomHelper.addCssClass(this.layer, 'noder-hidden-cursors');
15232
+ this.removeAnimationClass();
15233
+ }
15234
+ showCursor() {
15235
+ this.isVisible = true;
15236
+ DomHelper.removeCssClass(this.layer, 'noder-hidden-cursors');
15237
+ this.addAnimationClass();
15238
+ }
15239
+ showStaticCursor() {
15240
+ this.isVisible = true;
15241
+ DomHelper.removeCssClass(this.layer, 'noder-hidden-cursors');
15242
+ this.removeAnimationClass();
15243
+ }
15244
+ detectVisibility() {
15245
+ const selectionRange = this.session.selection.selectedRange;
15246
+ if (selectionRange.isEmpty) {
15247
+ DomHelper.removeCssClass(this.layer, 'selecting');
15248
+ return;
15249
+ }
15250
+ DomHelper.addCssClass(this.layer, 'selecting');
15251
+ }
15252
+ update(config) {
15253
+ this.cursorPosition = this.getPixelPosition();
15254
+ this.drawCursor(config.maxHeight);
15255
+ this.detectVisibility();
15256
+ this.restartAnimation();
15257
+ }
15258
+ getPixelPosition(position) {
15259
+ if (!position) {
15260
+ position = this.session.selection.cursor;
15261
+ }
15262
+ return PositionHelper.documentToPixel(this.session, position);
15263
+ }
15264
+ addTextStylesToCursor() {
15265
+ const textStyle = this.session.editorService.styles;
15266
+ DomHelper.setStyle(this.cursor.style, 'border-color', textStyle.fontColor);
15267
+ DomHelper.setStyle(this.cursor.style, 'fontSize', `${textStyle.fontSize}px`);
15268
+ if (textStyle.italic) {
15269
+ DomHelper.setStyle(this.cursor.style, '-webkit-transform', 'skewX(-13deg)');
15270
+ }
15271
+ else {
15272
+ DomHelper.setStyle(this.cursor.style, '-webkit-transform', 'skewX(0)');
15273
+ }
15274
+ const metricSize = FontMetrics.measureCharSize('EMPTY_LINE', ContentStyleHelper.getFontStylesString(new TextStyleModel({
15275
+ italic: textStyle.italic,
15276
+ bold: textStyle.bold,
15277
+ fontSize: textStyle.fontSize,
15278
+ fontFamily: textStyle.fontFamily
15279
+ })));
15280
+ const fontMetricHeight = metricSize.ascent + metricSize.descent;
15281
+ const maxHeight = this.cursorPosition.sizeMax.ascent + this.cursorPosition.sizeMax.descent;
15282
+ const fontShoulders = fontMetricHeight - metricSize.font;
15283
+ const offset = metricSize.descent - fontShoulders;
15284
+ let top = this.cursorPosition.pageY + this.cursorPosition.sizeMax.ascent - metricSize.font + offset;
15285
+ if (fontMetricHeight !== maxHeight && maxHeight >= this.cursorPosition.lineHeight) {
15286
+ top -= maxHeight - this.cursorPosition.lineHeight;
15287
+ }
15288
+ DomHelper.setStyle(this.cursor.style, 'top', `${top < 0 ? 0 : top}px`);
15289
+ DomHelper.setStyle(this.cursor.style, 'height', `${fontMetricHeight}px`);
15290
+ }
15291
+ restartAnimation() {
15292
+ this.removeAnimationClass();
15293
+ if (!this.isVisible) {
15294
+ return;
15295
+ }
15296
+ this.addAnimationClass();
15297
+ }
15298
+ drawCursor(maxLayerHeight) {
15299
+ const isCursorInView = this.cursorPosition.pageY >= 0 && this.cursorPosition.pageY < maxLayerHeight;
15300
+ if (!isCursorInView) {
15301
+ DomHelper.setStyle(this.cursor.style, 'display', 'none');
15302
+ return;
15303
+ }
15304
+ DomHelper.setStyle(this.cursor.style, 'display', 'block');
15305
+ const currentSize = this.cursorPosition.sizeCurrent;
15306
+ DomHelper.setStyle(this.cursor.style, 'left', `${this.cursorPosition.pageX}px`);
15307
+ DomHelper.setStyle(this.cursor.style, 'width', `${currentSize.width}px`);
15308
+ this.addTextStylesToCursor();
15309
+ }
15310
+ removeAnimationClass() {
15311
+ DomHelper.removeCssClass(this.layer, 'noder-animate-blinking');
15312
+ }
15313
+ addAnimationClass() {
15314
+ this.cursor.style.animationDuration = `${this.blinkInterval}ms`;
15315
+ DomHelper.addCssClass(this.layer, 'noder-animate-blinking');
15316
+ }
15317
+ }
15318
+
14826
15319
  class GrammarHighlightLayer extends HighlightLayer {
14827
15320
  constructor(parentEl, cssClass, session) {
14828
15321
  super(parentEl, cssClass, session);
@@ -14880,6 +15373,7 @@ class RenderChangesModel {
14880
15373
  this.selection ||
14881
15374
  this.search ||
14882
15375
  this.grammar ||
15376
+ this.comments ||
14883
15377
  this.scroll ||
14884
15378
  this.size ||
14885
15379
  this.text ||
@@ -14894,6 +15388,7 @@ class RenderChangesModel {
14894
15388
  this.selection = false;
14895
15389
  this.search = false;
14896
15390
  this.grammar = false;
15391
+ this.comments = false;
14897
15392
  this.scroll = false;
14898
15393
  this.size = false;
14899
15394
  this.text = false;
@@ -15119,7 +15614,7 @@ class Renderer extends EventEmitting {
15119
15614
  get ParagraphsAppeared$() {
15120
15615
  return this.ParagraphsAppeared.asObservable();
15121
15616
  }
15122
- constructor(parentContainer, session) {
15617
+ constructor(parentContainer, commentsService, session) {
15123
15618
  super();
15124
15619
  this.session = session;
15125
15620
  this.layerConfig = {
@@ -15160,6 +15655,7 @@ class Renderer extends EventEmitting {
15160
15655
  this.selectionLayer = new SelectionLayer(this.content, 'text-selection', this.session);
15161
15656
  this.searchHighlightLayer = new SearchHighlightLayer(this.content, 'text-search-highlight', this.session);
15162
15657
  this.grammarHighlightLayer = new GrammarHighlightLayer(this.content, 'grammar-highlight', this.session);
15658
+ this.commentsLayer = new CommentHighlightLayer(this.content, 'comments-highlight', this.session, commentsService);
15163
15659
  this.cursorLayer = new CursorLayer(this.content, this.session);
15164
15660
  this.dragAndDropSelectionLayer = new SelectionLayer(this.content, 'drag-and-drop-selection', this.session);
15165
15661
  this.loop = new RenderLoop(changes => this.renderChanges(changes));
@@ -15182,6 +15678,8 @@ class Renderer extends EventEmitting {
15182
15678
  changes.lines ||
15183
15679
  changes.scroll ||
15184
15680
  changes.search ||
15681
+ changes.grammar ||
15682
+ changes.comments ||
15185
15683
  changes.visibilityChanged) {
15186
15684
  changes.apply(this.computeLayerConfig());
15187
15685
  DomHelper.translate(this.content, 0, -this.layerConfig.offset);
@@ -15208,12 +15706,16 @@ class Renderer extends EventEmitting {
15208
15706
  if (changes.grammar) {
15209
15707
  this.renderGrammarHighlights();
15210
15708
  }
15709
+ if (changes.comments) {
15710
+ this.renderComments();
15711
+ }
15211
15712
  if (changes.dragAndDrop) {
15212
15713
  this.renderDragAndDropSelection();
15213
15714
  }
15214
15715
  if (changes.visibilityChanged) {
15215
15716
  this.renderSearchHighlights();
15216
15717
  this.renderGrammarHighlights();
15718
+ this.renderComments();
15217
15719
  this.visibilitySubject.next(this.isVisible);
15218
15720
  }
15219
15721
  this.session.onRendered();
@@ -15354,6 +15856,8 @@ class Renderer extends EventEmitting {
15354
15856
  this.textLayer.updateLines(this.layerConfig);
15355
15857
  this.selectionLayer.update(this.layerConfig);
15356
15858
  this.searchHighlightLayer.update(this.layerConfig);
15859
+ this.grammarHighlightLayer.update(this.layerConfig);
15860
+ this.commentsLayer.update(this.layerConfig);
15357
15861
  this.cursorLayer.update(this.layerConfig);
15358
15862
  this.moveTextAreaToCursor();
15359
15863
  this.session.onRendered();
@@ -15376,6 +15880,16 @@ class Renderer extends EventEmitting {
15376
15880
  renderGrammarHighlights() {
15377
15881
  this.grammarHighlightLayer.update(this.layerConfig);
15378
15882
  }
15883
+ renderComments() {
15884
+ this.commentsLayer.update(this.layerConfig);
15885
+ }
15886
+ setSelectedComment(comment) {
15887
+ this.commentsLayer.setSelectedComment(comment);
15888
+ this.commentsLayer.update(this.layerConfig);
15889
+ }
15890
+ setCommentsVisibility(value) {
15891
+ this.commentsLayer.enabled = value;
15892
+ }
15379
15893
  renderDragAndDropSelection() {
15380
15894
  this.dragAndDropSelectionLayer.update(this.layerConfig);
15381
15895
  }
@@ -15467,12 +15981,13 @@ class ScrollBar {
15467
15981
  }
15468
15982
  onScroll() {
15469
15983
  if (!this.skipEvent) {
15984
+ const prevTop = this._scrollTop;
15470
15985
  this._scrollTop = this.element.scrollTop;
15471
15986
  if (this.coeff !== 1) {
15472
15987
  const height = this.element.clientHeight / this.scrollHeight;
15473
15988
  this._scrollTop = (this._scrollTop * (1 - height)) / (this.coeff - height);
15474
15989
  }
15475
- this._scrolled$.next();
15990
+ this._scrolled$.next(this._scrollTop - prevTop);
15476
15991
  }
15477
15992
  this.skipEvent = false;
15478
15993
  }
@@ -15499,6 +16014,127 @@ class ScrollBar {
15499
16014
  }
15500
16015
  }
15501
16016
 
16017
+ class RemoveCommentFromDom {
16018
+ constructor(sessionId, id) {
16019
+ this.sessionId = sessionId;
16020
+ this.id = id;
16021
+ }
16022
+ }
16023
+
16024
+ class RemoveCommentsFromDom {
16025
+ constructor(sessionId) {
16026
+ this.sessionId = sessionId;
16027
+ }
16028
+ }
16029
+
16030
+ class RenderComments {
16031
+ constructor(sessionId, renderRequests) {
16032
+ this.sessionId = sessionId;
16033
+ this.renderRequests = renderRequests;
16034
+ }
16035
+ }
16036
+
16037
+ class CommentLayer {
16038
+ constructor(parentEl, commentService) {
16039
+ this.commentPadding = 8;
16040
+ this.rendersBySession = new Map();
16041
+ this.element = document.createElement('div');
16042
+ this.element.className = `noder-comments-layer`;
16043
+ parentEl.appendChild(this.element);
16044
+ this.commentSubscription = commentService.commentRenderRequests$.subscribe(x => {
16045
+ this.applyChanges(x);
16046
+ this.renderComments();
16047
+ });
16048
+ }
16049
+ destroy() {
16050
+ this.commentSubscription.unsubscribe();
16051
+ }
16052
+ scrollComments(offsetY) {
16053
+ for (const [sessionId, comments] of this.rendersBySession) {
16054
+ if (sessionId === 1) {
16055
+ continue;
16056
+ }
16057
+ for (const comment of comments) {
16058
+ comment.highlightTop -= offsetY;
16059
+ }
16060
+ }
16061
+ }
16062
+ renderComments() {
16063
+ this.element.innerHTML = '';
16064
+ const topOffset = this.element.getBoundingClientRect().top;
16065
+ const sortedComments = Array.from(this.rendersBySession.values())
16066
+ .reduce((acc, x) => acc.concat(x), [])
16067
+ .toSorted((x, y) => (x.highlightTop !== y.highlightTop ? x.highlightTop - y.highlightTop : x.highlightLeft - y.highlightLeft));
16068
+ const selectedIndex = sortedComments.findIndex(x => x.commentRef.instance.selected);
16069
+ if (selectedIndex >= 0) {
16070
+ const selectedComment = sortedComments[selectedIndex];
16071
+ const selectedCommentRange = this.drawCommentComponent(selectedComment.commentRef, selectedComment.highlightTop - topOffset);
16072
+ let lastCommentBounds = selectedCommentRange;
16073
+ for (let i = selectedIndex - 1; i >= 0; i--) {
16074
+ const comment = sortedComments[i];
16075
+ const height = comment.commentRef.instance.height;
16076
+ let top = comment.highlightTop - topOffset;
16077
+ if (top + height >= lastCommentBounds.from) {
16078
+ top = lastCommentBounds.from - height;
16079
+ }
16080
+ lastCommentBounds = this.drawCommentComponent(comment.commentRef, top);
16081
+ }
16082
+ lastCommentBounds = selectedCommentRange;
16083
+ for (let i = selectedIndex + 1; i < sortedComments.length; i++) {
16084
+ const comment = sortedComments[i];
16085
+ let top = comment.highlightTop - topOffset;
16086
+ if (top <= lastCommentBounds.to) {
16087
+ top = lastCommentBounds.to;
16088
+ }
16089
+ lastCommentBounds = this.drawCommentComponent(comment.commentRef, top);
16090
+ }
16091
+ return;
16092
+ }
16093
+ let lastCommentBounds = { from: 0, to: 0 };
16094
+ for (let i = selectedIndex + 1; i < sortedComments.length; i++) {
16095
+ const comment = sortedComments[i];
16096
+ let top = comment.highlightTop - topOffset;
16097
+ if (top <= lastCommentBounds.to) {
16098
+ top = lastCommentBounds.to;
16099
+ }
16100
+ lastCommentBounds = this.drawCommentComponent(comment.commentRef, top);
16101
+ }
16102
+ }
16103
+ applyChanges(changes) {
16104
+ if (changes instanceof RemoveCommentsFromDom) {
16105
+ this.rendersBySession.delete(changes.sessionId);
16106
+ return;
16107
+ }
16108
+ if (changes instanceof RenderComments) {
16109
+ this.rendersBySession.set(changes.sessionId, changes.renderRequests);
16110
+ return;
16111
+ }
16112
+ if (changes instanceof RemoveCommentFromDom) {
16113
+ const requests = this.rendersBySession.get(changes.sessionId);
16114
+ if (!requests) {
16115
+ return;
16116
+ }
16117
+ const index = requests.findIndex(x => x.commentId === changes.id);
16118
+ if (index > -1) {
16119
+ requests.splice(index, 1);
16120
+ }
16121
+ return;
16122
+ }
16123
+ }
16124
+ drawCommentComponent(commentRef, top) {
16125
+ const domElem = commentRef.hostView.rootNodes[0];
16126
+ this.element.appendChild(domElem);
16127
+ const cssPosition = `top:${top}px;left:20px`;
16128
+ domElem.style.cssText = cssPosition;
16129
+ const selected = commentRef.instance.selected ? 'selected' : '';
16130
+ domElem.className = `noder-comment ${selected}`;
16131
+ if (commentRef.instance.editing && commentRef.instance.selected) {
16132
+ commentRef.instance.focusTextArea();
16133
+ }
16134
+ return { from: top - this.commentPadding, to: top + commentRef.instance.height + this.commentPadding };
16135
+ }
16136
+ }
16137
+
15502
16138
  class VirtualRenderer {
15503
16139
  get cursorLayer() {
15504
16140
  return this.renderer.cursorLayer;
@@ -15524,7 +16160,7 @@ class VirtualRenderer {
15524
16160
  get ParagraphsAppeared$() {
15525
16161
  return this.renderer.ParagraphsAppeared.asObservable();
15526
16162
  }
15527
- constructor(parentContainer, mainSession, scrollBar) {
16163
+ constructor(parentContainer, mainSession, commentService, scrollBar) {
15528
16164
  this.scrollBar = scrollBar;
15529
16165
  this.changes = new RenderChangesModel();
15530
16166
  this.size = {
@@ -15537,10 +16173,14 @@ class VirtualRenderer {
15537
16173
  this.paragraphsScrolledIntoViewSubject = new Subject();
15538
16174
  this.container = parentContainer;
15539
16175
  this.createScroller();
15540
- this.renderer = new Renderer(parentContainer, mainSession);
16176
+ this.renderer = new Renderer(parentContainer, commentService, mainSession);
15541
16177
  this.pagesLayer = new PagesLayer(this.renderer.content, mainSession);
15542
16178
  this.edgesLayer = new EdgesLayer(this.renderer.content, mainSession);
15543
- this.scrollSubscription = this.scrollBar.scrolled$.subscribe(() => this.loop.schedule({ scroll: true }));
16179
+ this.commentLayer = new CommentLayer(this.renderer.content, commentService);
16180
+ this.scrollSubscription = this.scrollBar.scrolled$.subscribe(x => {
16181
+ this.loop.schedule({ scroll: true });
16182
+ this.commentLayer.scrollComments(x);
16183
+ });
15544
16184
  this.createRenderLoop();
15545
16185
  this.paragraphsScrolledIntoViewSubscription = this.paragraphsScrolledIntoViewSubject
15546
16186
  .pipe(debounceTime(3000))
@@ -15587,6 +16227,7 @@ class VirtualRenderer {
15587
16227
  }
15588
16228
  if (changes.cursor) {
15589
16229
  this.renderCursor();
16230
+ this.renderComments();
15590
16231
  }
15591
16232
  if (changes.marker || changes.selection) {
15592
16233
  this.renderSelection();
@@ -15597,6 +16238,9 @@ class VirtualRenderer {
15597
16238
  if (changes.grammar) {
15598
16239
  this.renderGrammarHighlights();
15599
16240
  }
16241
+ if (changes.comments) {
16242
+ this.renderComments();
16243
+ }
15600
16244
  if (changes.dragAndDrop) {
15601
16245
  this.renderDragAndDropSelection();
15602
16246
  }
@@ -15646,6 +16290,12 @@ class VirtualRenderer {
15646
16290
  this.size.dirty = !width || !height;
15647
16291
  return changes;
15648
16292
  }
16293
+ setSelectedComment(commentId) {
16294
+ this.renderer.setSelectedComment(commentId);
16295
+ }
16296
+ setCommentsVisibility(value) {
16297
+ this.renderer.setCommentsVisibility(value);
16298
+ }
15649
16299
  moveTextAreaToCursor() {
15650
16300
  if (!this.textarea) {
15651
16301
  return;
@@ -15741,6 +16391,7 @@ class VirtualRenderer {
15741
16391
  }
15742
16392
  const scrollTop = this.scrollBar.scrollTop + deltaY;
15743
16393
  this.scrollBar.setScrollTop(scrollTop);
16394
+ this.commentLayer.scrollComments(deltaY);
15744
16395
  this.loop.schedule({ scroll: true });
15745
16396
  }
15746
16397
  screenToTextCoordinatesUsingMidpoint(x, y, rect) {
@@ -15762,6 +16413,7 @@ class VirtualRenderer {
15762
16413
  DomHelper.removeElement(this.scrollBar.element);
15763
16414
  this.pagesLayer.destroy();
15764
16415
  this.renderer.destroy();
16416
+ this.commentLayer.destroy();
15765
16417
  this.scrollSubscription?.unsubscribe();
15766
16418
  this.paragraphsScrolledIntoViewSubscription?.unsubscribe();
15767
16419
  }
@@ -15815,8 +16467,10 @@ class VirtualRenderer {
15815
16467
  this.renderer.textLayer.scrollLines(this.layerConfig);
15816
16468
  }
15817
16469
  this.renderer.selectionLayer.update(this.layerConfig);
16470
+ this.renderer.dragAndDropSelectionLayer.update(this.layerConfig);
15818
16471
  this.renderer.searchHighlightLayer.update(this.layerConfig);
15819
16472
  this.renderer.grammarHighlightLayer.update(this.layerConfig);
16473
+ this.renderer.commentsLayer.update(this.layerConfig);
15820
16474
  if (!this.renderer.cursorLayer.isVisible) {
15821
16475
  return;
15822
16476
  }
@@ -15827,6 +16481,7 @@ class VirtualRenderer {
15827
16481
  this.pagesLayer.update(this.layerConfig);
15828
16482
  this.edgesLayer.update(this.layerConfig);
15829
16483
  this.paragraphsScrolledIntoViewSubject.next();
16484
+ this.commentLayer.renderComments();
15830
16485
  this.renderer.renderFull();
15831
16486
  }
15832
16487
  renderText() {
@@ -15848,6 +16503,9 @@ class VirtualRenderer {
15848
16503
  renderDragAndDropSelection() {
15849
16504
  this.renderer.renderDragAndDropSelection();
15850
16505
  }
16506
+ renderComments() {
16507
+ this.renderer.renderComments();
16508
+ }
15851
16509
  paragraphsScrolledIntoView() {
15852
16510
  const paragraphs = this.renderer.session.displayData.paragraphs.slice(this.layerConfig.visibleRange.startParagraph, this.layerConfig.visibleRange.endParagraph);
15853
16511
  this.renderer.ParagraphsAppeared.next(paragraphs);
@@ -15938,7 +16596,7 @@ class CustomContentService {
15938
16596
  indentRight: lineInfo.indent.right,
15939
16597
  indentBefore: lineInfo.offsetBefore,
15940
16598
  indentAfter: lineInfo.offsetAfter,
15941
- markerWidth: lineInfo.markerWidth,
16599
+ markerWidth: isFirst && lineInfo.isNumbering ? lineInfo.markerWidth : 0,
15942
16600
  isNumbering: lineInfo.isNumbering,
15943
16601
  isPageBreak: false,
15944
16602
  isLineBreak: false,
@@ -15966,12 +16624,86 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImpor
15966
16624
  type: Injectable
15967
16625
  }], ctorParameters: () => [{ type: ComponentService }, { type: i0.Injector }] });
15968
16626
 
16627
+ class RenderComment {
16628
+ constructor(comment, sessionId, top, left) {
16629
+ this.commentRef = comment;
16630
+ this.commentId = comment.instance.id;
16631
+ this.sessionId = sessionId;
16632
+ this.highlightTop = top;
16633
+ this.highlightLeft = left;
16634
+ }
16635
+ }
16636
+
16637
+ class CommentRenderService {
16638
+ get commentRenderRequests$() {
16639
+ return this.commentRenderRequests.asObservable();
16640
+ }
16641
+ constructor(componentType) {
16642
+ this.componentType = componentType;
16643
+ this.componentInstances = [];
16644
+ this.applicationRef = inject(ApplicationRef);
16645
+ this.injector = inject(Injector);
16646
+ this.commentRenderRequests = new Subject();
16647
+ }
16648
+ requestCommentsRender(sessionId, renderRequests) {
16649
+ const requests = [];
16650
+ for (const request of renderRequests) {
16651
+ let componentRef;
16652
+ const existingComponentRef = this.componentInstances.find(x => x.instance.id === request.commentId);
16653
+ if (existingComponentRef) {
16654
+ componentRef = existingComponentRef;
16655
+ }
16656
+ else {
16657
+ componentRef = this.createComponentRef(request.commentId);
16658
+ componentRef.instance.initialize();
16659
+ this.componentInstances.push(componentRef);
16660
+ }
16661
+ requests.push(new RenderComment(componentRef, sessionId, request.top, request.left));
16662
+ }
16663
+ this.commentRenderRequests.next(new RenderComments(sessionId, requests));
16664
+ }
16665
+ createNewComment(id) {
16666
+ const componentRef = this.createComponentRef(id);
16667
+ componentRef.instance.markAsNew();
16668
+ componentRef.instance.initialize();
16669
+ this.componentInstances.push(componentRef);
16670
+ }
16671
+ removeCommentFromRender(sessionId, id) {
16672
+ if (!this.componentInstances.some(x => x.instance.id === id)) {
16673
+ return;
16674
+ }
16675
+ this.commentRenderRequests.next(new RemoveCommentFromDom(sessionId, id));
16676
+ }
16677
+ removeCommentsFromRender(sessionId) {
16678
+ this.commentRenderRequests.next(new RemoveCommentsFromDom(sessionId));
16679
+ }
16680
+ setCommentSelected(id, selected = true) {
16681
+ const componentRef = this.componentInstances.find(x => x.instance.id === id);
16682
+ componentRef?.instance.setSelected(selected);
16683
+ }
16684
+ createComponentRef(id) {
16685
+ const ref = createComponent(this.componentType, {
16686
+ environmentInjector: this.applicationRef.injector,
16687
+ elementInjector: this.injector
16688
+ });
16689
+ this.applicationRef.attachView(ref.hostView);
16690
+ ref.instance.id = id;
16691
+ return ref;
16692
+ }
16693
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: CommentRenderService, deps: [{ token: i0.Type }], target: i0.ɵɵFactoryTarget.Injectable }); }
16694
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: CommentRenderService }); }
16695
+ }
16696
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: CommentRenderService, decorators: [{
16697
+ type: Injectable
16698
+ }], ctorParameters: () => [{ type: i0.Type }] });
16699
+
15969
16700
  class RegulatorService {
15970
- constructor(customContentService, editorService, componentService, grammarService) {
16701
+ constructor(customContentService, editorService, componentService, grammarService, commentRenderService) {
15971
16702
  this.customContentService = customContentService;
15972
16703
  this.editorService = editorService;
15973
16704
  this.componentService = componentService;
15974
16705
  this.grammarService = grammarService;
16706
+ this.commentRenderService = commentRenderService;
15975
16707
  this.sessions = [];
15976
16708
  this.sessionIdIncrement = 0;
15977
16709
  this.grammarChecker = new GrammarChecker(this.grammarService);
@@ -16000,8 +16732,8 @@ class RegulatorService {
16000
16732
  const customComponents = { images: [], tables: [], tabs: [], customElements: [], edges: edges };
16001
16733
  const displayData = new DisplayData(model, properties, sessionId, model.pageFormats, DocumentInfo.pagesSpace, customComponents, this.customContentService, this.editorService);
16002
16734
  const scrollBar = new ScrollBar(container.nativeElement.parentElement);
16003
- const mainSession = new EditSession(displayData, sessionId, this.customContentService, model, this.selection, properties, this.editorService, customComponents, 'main', scrollBar);
16004
- const virtualRenderer = new VirtualRenderer(container.nativeElement, mainSession, scrollBar);
16735
+ const mainSession = new EditSession(displayData, sessionId, this.customContentService, this.commentRenderService, model, this.selection, properties, this.editorService, customComponents, 'main', scrollBar);
16736
+ const virtualRenderer = new VirtualRenderer(container.nativeElement, mainSession, this.commentRenderService, scrollBar);
16005
16737
  this.editorService.styles = DEFAULT_TOOLBAR_STYLES();
16006
16738
  this.mainSession = new SessionModel(mainSession, virtualRenderer, sessionId, null, new MainSessionSourceModel());
16007
16739
  this.sessions.push(this.mainSession);
@@ -16014,10 +16746,10 @@ class RegulatorService {
16014
16746
  const customComponents = { images: [], tables: [], tabs: [], customElements: [], edges: null };
16015
16747
  const displayData = new DisplayData(component.cell, properties, sessionId, this.getPageFormats(margins, component.width), 0, customComponents, this.customContentService, this.editorService);
16016
16748
  const sessionType = this.isWithinEdge(component.parentSessionId) ? 'cellWithinEdge' : 'cell';
16017
- const session = new EditSession(displayData, sessionId, this.customContentService, component.cell, this.selection, properties, this.editorService, customComponents, sessionType);
16749
+ const session = new EditSession(displayData, sessionId, this.customContentService, this.commentRenderService, component.cell, this.selection, properties, this.editorService, customComponents, sessionType);
16018
16750
  displayData.pagesFormat[0].contentWidth =
16019
16751
  displayData.pagesFormat[0].contentWidth === 0 ? 1 : displayData.pagesFormat[0].contentWidth;
16020
- const renderer = new Renderer(component.container.nativeElement, session);
16752
+ const renderer = new Renderer(component.container.nativeElement, this.commentRenderService, session);
16021
16753
  const source = new CellSessionSourceModel(table, component);
16022
16754
  const newSession = new SessionModel(session, renderer, sessionId, component.parentSessionId, source);
16023
16755
  this.sessions.push(newSession);
@@ -16030,8 +16762,8 @@ class RegulatorService {
16030
16762
  const sessionId = ++this.sessionIdIncrement;
16031
16763
  const customComponents = { images: [], tables: [], tabs: [], customElements: [], edges: null };
16032
16764
  const displayData = new DisplayData(component.model, component.generalProperties, sessionId, this.getPageFormats(component.margins, component.width), 0, customComponents, this.customContentService, this.editorService);
16033
- const session = new EditSession(displayData, sessionId, this.customContentService, component.model, this.selection, component.generalProperties, this.editorService, customComponents, 'edge', null, component.type);
16034
- const renderer = new Renderer(component.container.nativeElement, session);
16765
+ const session = new EditSession(displayData, sessionId, this.customContentService, this.commentRenderService, component.model, this.selection, component.generalProperties, this.editorService, customComponents, 'edge', null, component.type, component.model.pageType);
16766
+ const renderer = new Renderer(component.container.nativeElement, this.commentRenderService, session);
16035
16767
  const source = new EdgeSessionSourceModel(component.model.pageType, component.type);
16036
16768
  const newSession = new SessionModel(session, renderer, sessionId, component.parentSessionId, source);
16037
16769
  this.sessions.push(newSession);
@@ -16076,7 +16808,8 @@ class RegulatorService {
16076
16808
  this.selection.clearSelection();
16077
16809
  if (this.currentSession.session.isEdge()) {
16078
16810
  this.sessions.forEach(x => {
16079
- if (x.session.edgeType === this.currentSession.session.edgeType) {
16811
+ if (x.session.edgeType === this.currentSession.session.edgeType &&
16812
+ x.session.pageType === this.currentSession.session.pageType) {
16080
16813
  x.renderer.hideCursor();
16081
16814
  }
16082
16815
  });
@@ -16088,7 +16821,7 @@ class RegulatorService {
16088
16821
  this.currentSession = session;
16089
16822
  if (session.session.isEdge()) {
16090
16823
  this.sessions.forEach(x => {
16091
- if (x.session.edgeType === session.session.edgeType) {
16824
+ if (x.session.edgeType === session.session.edgeType && x.session.pageType === this.currentSession.session.pageType) {
16092
16825
  x.renderer.showCursor();
16093
16826
  this.arrangeEdgesForSessionChange(previous.session, x.session);
16094
16827
  }
@@ -16105,7 +16838,8 @@ class RegulatorService {
16105
16838
  return;
16106
16839
  }
16107
16840
  this.sessions.forEach(x => {
16108
- if (x.session.edgeType === this.currentSession.session.edgeType) {
16841
+ if (x.session.edgeType === this.currentSession.session.edgeType &&
16842
+ x.session.pageType === this.currentSession.session.pageType) {
16109
16843
  x.renderer.updateSelection(this.selection.selectedRange);
16110
16844
  if (this.selection.isEmpty) {
16111
16845
  x.renderer.updateCursor();
@@ -16164,6 +16898,20 @@ class RegulatorService {
16164
16898
  }
16165
16899
  return result;
16166
16900
  }
16901
+ getCommentTarget(commentId) {
16902
+ for (const session of this.sessions) {
16903
+ if (session.session.model.comments.some(x => x.commentId === commentId)) {
16904
+ return { session, target: session.source.getTarget() };
16905
+ }
16906
+ }
16907
+ return null;
16908
+ }
16909
+ setCommentsVisibility(value) {
16910
+ for (const sessionModel of this.sessions) {
16911
+ sessionModel.renderer.setCommentsVisibility(value);
16912
+ sessionModel.renderer.loop.schedule({ comments: true });
16913
+ }
16914
+ }
16167
16915
  isWithinEdge(sessionId) {
16168
16916
  return !!this.getEdgeSessionId(sessionId);
16169
16917
  }
@@ -16177,7 +16925,9 @@ class RegulatorService {
16177
16925
  return;
16178
16926
  }
16179
16927
  this.sessions.forEach(x => {
16180
- if (x.session.isEdge() && x.session.edgeType === this.currentSession.session.edgeType) {
16928
+ if (x.session.isEdge() &&
16929
+ x.session.edgeType === this.currentSession.session.edgeType &&
16930
+ x.session.pageType === this.currentSession.session.pageType) {
16181
16931
  x.session.updateDisplayData();
16182
16932
  x.renderer.updateTextAndCursor();
16183
16933
  }
@@ -16218,12 +16968,12 @@ class RegulatorService {
16218
16968
  })
16219
16969
  ];
16220
16970
  }
16221
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: RegulatorService, deps: [{ token: CustomContentService }, { token: EditorService }, { token: ComponentService }, { token: GrammarService }], target: i0.ɵɵFactoryTarget.Injectable }); }
16971
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: RegulatorService, deps: [{ token: CustomContentService }, { token: EditorService }, { token: ComponentService }, { token: GrammarService }, { token: CommentRenderService }], target: i0.ɵɵFactoryTarget.Injectable }); }
16222
16972
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: RegulatorService }); }
16223
16973
  }
16224
16974
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: RegulatorService, decorators: [{
16225
16975
  type: Injectable
16226
- }], ctorParameters: () => [{ type: CustomContentService }, { type: EditorService }, { type: ComponentService }, { type: GrammarService }] });
16976
+ }], ctorParameters: () => [{ type: CustomContentService }, { type: EditorService }, { type: ComponentService }, { type: GrammarService }, { type: CommentRenderService }] });
16227
16977
 
16228
16978
  class CommandsService {
16229
16979
  constructor() {
@@ -16432,9 +17182,9 @@ class EditorRulerComponent {
16432
17182
  this.editorService.paragraphStyle$.pipe(takeUntilDestroyed()).subscribe(({ paragraphStyle, numberingModel }) => {
16433
17183
  const numberingIndentLeft = numberingModel?.levels[paragraphStyle.numberingLevel].indentLeft ?? 0;
16434
17184
  const numberingIndentHanging = numberingModel?.levels[paragraphStyle.numberingLevel].indentHanging ?? 0;
16435
- const indentLeft = paragraphStyle.indentLeft === 0 ? numberingIndentLeft : paragraphStyle.indentLeft;
16436
- const firstLine = paragraphStyle.indentHanging ? -paragraphStyle.indentHanging : paragraphStyle.indentFirstLine;
16437
- this.firstLine.set(firstLine === 0 ? -numberingIndentHanging : firstLine);
17185
+ const indentLeft = paragraphStyle.indentLeft === null ? numberingIndentLeft : paragraphStyle.indentLeft;
17186
+ const firstLine = paragraphStyle.indentHanging !== null ? -paragraphStyle.indentHanging : paragraphStyle.indentFirstLine;
17187
+ this.firstLine.set(firstLine === null ? -numberingIndentHanging : firstLine);
16438
17188
  this.leftIndent.set(indentLeft);
16439
17189
  this.rightIndent.set(paragraphStyle.indentRight);
16440
17190
  });
@@ -16781,12 +17531,17 @@ class EditorModule {
16781
17531
  { provide: EXTERNAL_ELEMENT_SIDENAV, useValue: new ExternalSidenavModel(options?.sidenav) },
16782
17532
  { provide: EXTERNAL_ELEMENT_SERVICE, useClass: options?.elementService ?? ExternalElementService },
16783
17533
  { provide: InsertOverlays, useValue: new InsertOverlays(options?.insertOverlays) },
16784
- { provide: ImageApiService, useClass: options?.imageApiService ?? DefaultImageApiService }
17534
+ { provide: ImageApiService, useClass: options?.imageApiService ?? DefaultImageApiService },
17535
+ {
17536
+ provide: CommentRenderService,
17537
+ useFactory: () => new CommentRenderService(options?.commentComponent)
17538
+ }
16785
17539
  ]
16786
17540
  };
16787
17541
  }
16788
17542
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: EditorModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
16789
17543
  static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.0.5", ngImport: i0, type: EditorModule, declarations: [EditorComponent,
17544
+ CommentPopupComponent,
16790
17545
  NoderEdgeComponent,
16791
17546
  NoderImageComponent,
16792
17547
  NoderTabComponent,
@@ -16796,9 +17551,11 @@ class EditorModule {
16796
17551
  TableOverlayMenuComponent], imports: [CommonModule,
16797
17552
  EditorRulerComponent,
16798
17553
  EditorSearchBarComponent,
17554
+ TextFieldModule,
16799
17555
  MatButtonModule,
16800
17556
  MatDialogModule,
16801
17557
  MatIconModule,
17558
+ MatMenuModule,
16802
17559
  MatSidenavModule,
16803
17560
  MatTooltipModule,
16804
17561
  ReactiveFormsModule,
@@ -16806,9 +17563,11 @@ class EditorModule {
16806
17563
  static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: EditorModule, providers: [ComponentService, CustomContentService, OverlayService, RegulatorService, ExternalElementService, CommandsService], imports: [CommonModule,
16807
17564
  EditorRulerComponent,
16808
17565
  EditorSearchBarComponent,
17566
+ TextFieldModule,
16809
17567
  MatButtonModule,
16810
17568
  MatDialogModule,
16811
17569
  MatIconModule,
17570
+ MatMenuModule,
16812
17571
  MatSidenavModule,
16813
17572
  MatTooltipModule,
16814
17573
  ReactiveFormsModule,
@@ -16819,6 +17578,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImpor
16819
17578
  args: [{
16820
17579
  declarations: [
16821
17580
  EditorComponent,
17581
+ CommentPopupComponent,
16822
17582
  NoderEdgeComponent,
16823
17583
  NoderImageComponent,
16824
17584
  NoderTabComponent,
@@ -16831,9 +17591,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImpor
16831
17591
  CommonModule,
16832
17592
  EditorRulerComponent,
16833
17593
  EditorSearchBarComponent,
17594
+ TextFieldModule,
16834
17595
  MatButtonModule,
16835
17596
  MatDialogModule,
16836
17597
  MatIconModule,
17598
+ MatMenuModule,
16837
17599
  MatSidenavModule,
16838
17600
  MatTooltipModule,
16839
17601
  ReactiveFormsModule,
@@ -18999,6 +19761,7 @@ class RevisionHelper {
18999
19761
  tabs: [],
19000
19762
  headers: [],
19001
19763
  footers: [],
19764
+ comments: [],
19002
19765
  defaultTabWidth: DEFAULT_TAB_WIDTH
19003
19766
  });
19004
19767
  }
@@ -19190,5 +19953,5 @@ class OperationModel {
19190
19953
  * Generated bundle index. Do not edit.
19191
19954
  */
19192
19955
 
19193
- export { AddLinkDialogComponent, AddLinkMobileComponent, Alignment, BaseNoderComponent, Borders, BreakTypes, CommandModel, CommandType, CommandsService, ConfirmDialogComponent, DEFAULT_BACKGROUND_COLOR, DEFAULT_EDGE_MAX_HEIGHT_MULTIPLIER, DEFAULT_FONT_COLOR, DEFAULT_FONT_FAMILY, DEFAULT_FONT_SIZE, DEFAULT_HEADINGS, DEFAULT_HEADING_STYLE_ID, DEFAULT_OFFSET_AFTER_NUMBERING_MARKER, DEFAULT_PARAGRAPH_STYLE, DEFAULT_TAB_WIDTH, DEFAULT_TEXT_STYLE, DEFAULT_TOOLBAR_STYLES, DefaultImageApiService, DestroyComponent, DocumentInfo, DocumentModel, DocumentNameModel, DocxModel, DomHelper, EditorComponent, EditorMobileToolbarComponent, EditorModule, EditorService, EditorTitleComponent, EditorTitleMobileComponent, EditorToolbarComponent, EditorToolbarMode, EditorToolbarModule, EditorToolbarService, ElementDataModel, ElementModel, ExternalComponent, ExternalElementModel, ExternalElementService, FileSourceModel, FontMetrics, FormatStyleHelper, GrammarService, HYPERLINK_FONT_COLOR, HYPERLINK_HEADING_STYLE_ID, ImageApiService, ImageDataModel, LastDocumentRevisionModel, LineStyles, MenuDropdownsComponent, MenuDropdownsMobileComponent, Mode, NEW_LINE_MARKUP, NoderTranslateLoader, NumberingLevelModel, OperationModel, OperationsHistoryInfoModel, PageSetupComponent, PageType, ParagraphStyleModel, RevisionHelper, RevisionModel, SearchResultLocation, TextFormatMobileComponent, TextStyleModel, ToolbarActionsComponent };
19956
+ export { AddLinkDialogComponent, AddLinkMobileComponent, Alignment, BaseCommentComponent, BaseNoderComponent, Borders, BreakTypes, CommandModel, CommandType, CommandsService, ConfirmDialogComponent, DEFAULT_BACKGROUND_COLOR, DEFAULT_EDGE_MAX_HEIGHT_MULTIPLIER, DEFAULT_FONT_COLOR, DEFAULT_FONT_FAMILY, DEFAULT_FONT_SIZE, DEFAULT_HEADINGS, DEFAULT_HEADING_STYLE_ID, DEFAULT_OFFSET_AFTER_NUMBERING_MARKER, DEFAULT_PARAGRAPH_STYLE, DEFAULT_TAB_WIDTH, DEFAULT_TEXT_STYLE, DEFAULT_TOOLBAR_STYLES, DefaultImageApiService, DestroyComponent, DocumentInfo, DocumentModel, DocumentNameModel, DocxModel, DomHelper, EditorComponent, EditorMobileToolbarComponent, EditorModule, EditorService, EditorTitleComponent, EditorTitleMobileComponent, EditorToolbarComponent, EditorToolbarMode, EditorToolbarModule, EditorToolbarService, ElementDataModel, ElementModel, ExternalComponent, ExternalElementModel, ExternalElementService, FileSourceModel, FontMetrics, FormatStyleHelper, GrammarService, HYPERLINK_FONT_COLOR, HYPERLINK_HEADING_STYLE_ID, ImageApiService, ImageDataModel, LastDocumentRevisionModel, LineStyles, MenuDropdownsComponent, MenuDropdownsMobileComponent, Mode, NEW_LINE_MARKUP, NoderTranslateLoader, NumberingLevelModel, OperationModel, OperationsHistoryInfoModel, PageSetupComponent, PageType, ParagraphStyleModel, RevisionHelper, RevisionModel, SearchResultLocation, TextFormatMobileComponent, TextStyleModel, ToolbarActionsComponent };
19194
19957
  //# sourceMappingURL=talrace-ngx-noder.mjs.map