@talrace/ngx-noder 19.0.51 → 19.0.52

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.
@@ -9950,7 +9950,6 @@ class CommentHighlightLayer extends HighlightLayer {
9950
9950
  this.commentService = commentService;
9951
9951
  this.className = 'noder-highlight';
9952
9952
  this.selectedCommentClassName = 'noder-selected-highlight';
9953
- this.selectedCommentId = null;
9954
9953
  }
9955
9954
  update(config) {
9956
9955
  const comments = this.session.model.comments;
@@ -9972,7 +9971,7 @@ class CommentHighlightLayer extends HighlightLayer {
9972
9971
  continue;
9973
9972
  }
9974
9973
  if (!screenRange.isEmpty) {
9975
- const className = comment.commentId === this.selectedCommentId ? this.selectedCommentClassName : this.className;
9974
+ const className = comment.commentId === this.commentService.selectedCommentId ? this.selectedCommentClassName : this.className;
9976
9975
  const result = screenRange.isSingleLine
9977
9976
  ? this.drawSingleLineMarker(screenRange, className)
9978
9977
  : this.drawMultiLineMarker(screenRange, className);
@@ -9986,23 +9985,13 @@ class CommentHighlightLayer extends HighlightLayer {
9986
9985
  }
9987
9986
  }
9988
9987
  }
9989
- removeSessionComments() {
9990
- this.commentService.removeCommentsFromRender(this.session.sessionId);
9991
- }
9992
9988
  removeComment(id) {
9993
9989
  this.commentService.removeCommentFromRender(this.session.sessionId, id);
9994
9990
  }
9995
- setSelectedComment(id) {
9996
- if (this.selectedCommentId) {
9997
- this.commentService.setCommentSelected(this.selectedCommentId, false);
9998
- }
9999
- this.selectedCommentId = id;
10000
- if (id) {
10001
- this.commentService.setCommentSelected(id);
10002
- }
10003
- }
10004
9991
  clearSessionComments() {
10005
- this.commentService.removeCommentsFromRender(this.session.sessionId);
9992
+ if (this.session.model.comments.length) {
9993
+ this.commentService.removeCommentsFromRender(this.session.sessionId);
9994
+ }
10006
9995
  }
10007
9996
  requestCommentRender(highlight, id) {
10008
9997
  const element = Array.isArray(highlight) ? highlight[0] : highlight;
@@ -10200,48 +10189,6 @@ class RenderChangesModel {
10200
10189
  }
10201
10190
  }
10202
10191
 
10203
- class EventHelper {
10204
- static get nextFrame() {
10205
- if (!this._nextFrame) {
10206
- const nextFrame = (callback) => {
10207
- setTimeout(callback, 17);
10208
- };
10209
- this._nextFrame =
10210
- window.requestAnimationFrame ||
10211
- window['webkitRequestAnimationFrame'] ||
10212
- window['mozRequestAnimationFrame'] ||
10213
- window['msRequestAnimationFrame'] ||
10214
- window['oRequestAnimationFrame'] ||
10215
- nextFrame;
10216
- }
10217
- return this._nextFrame;
10218
- }
10219
- }
10220
-
10221
- class RenderLoop {
10222
- constructor(onRender) {
10223
- this.changes = new RenderChangesModel();
10224
- this.flush = () => {
10225
- const changes = this.changes;
10226
- if (changes.any) {
10227
- this.changes = new RenderChangesModel();
10228
- onRender(changes);
10229
- }
10230
- if (this.changes.any) {
10231
- this.schedule();
10232
- }
10233
- };
10234
- }
10235
- schedule(changes) {
10236
- if (changes) {
10237
- this.changes.apply(changes);
10238
- }
10239
- if (this.changes) {
10240
- EventHelper.nextFrame(this.flush);
10241
- }
10242
- }
10243
- }
10244
-
10245
10192
  class CustomElementInfo {
10246
10193
  constructor(init) {
10247
10194
  Object.assign(this, init);
@@ -10605,9 +10552,11 @@ class Renderer extends EventEmitting {
10605
10552
  get paragraphsAppeared$() {
10606
10553
  return this.paragraphsAppeared.asObservable();
10607
10554
  }
10608
- constructor(parentContainer, commentsService, session) {
10555
+ constructor(parentContainer, commentsService, session, loop) {
10609
10556
  super();
10610
10557
  this.session = session;
10558
+ this.loop = loop;
10559
+ this.grammarChecksEnabled = false;
10611
10560
  this.layerConfig = {
10612
10561
  width: 1,
10613
10562
  contentRange: new DistanceModel({ start: 0, end: 0 }), // paragraphs
@@ -10637,7 +10586,7 @@ class Renderer extends EventEmitting {
10637
10586
  width: 1
10638
10587
  };
10639
10588
  this.pagesCountChangedHandler = () => {
10640
- this.loop.schedule({ lines: true, selection: true });
10589
+ this.scheduleChanges({ lines: true, selection: true });
10641
10590
  };
10642
10591
  this.container = parentContainer;
10643
10592
  this.container.className += ' noder-editor';
@@ -10649,10 +10598,10 @@ class Renderer extends EventEmitting {
10649
10598
  this.commentsLayer = new CommentHighlightLayer(this.content, 'comments-highlight', this.session, commentsService);
10650
10599
  this.cursorLayer = new CursorLayer(this.content, this.session);
10651
10600
  this.dragAndDropSelectionLayer = new SelectionLayer(this.content, 'drag-and-drop-selection', this.session);
10652
- this.loop = new RenderLoop(changes => this.renderChanges(changes));
10601
+ loop.registerSession(this.session.sessionId, changes => this.renderChanges(changes));
10653
10602
  this.session.displayData.addEventListener('pagesCountChanged', this.pagesCountChangedHandler);
10654
10603
  this.visibilitySubscription = this.visibilitySubject
10655
- .pipe(debounceTime(3000), filter(x => x))
10604
+ .pipe(filter(() => this.grammarChecksEnabled), debounceTime(3000), filter(x => x))
10656
10605
  .subscribe(() => this.paragraphsScrolledIntoView());
10657
10606
  }
10658
10607
  renderChanges(changes, force) {
@@ -10721,7 +10670,7 @@ class Renderer extends EventEmitting {
10721
10670
  if (lastRow < this.layerConfig.contentRange.start || firstRow > this.layerConfig.contentRange.end) {
10722
10671
  return;
10723
10672
  }
10724
- this.loop.schedule({ lines: true });
10673
+ this.scheduleChanges({ lines: true });
10725
10674
  }
10726
10675
  moveTextAreaToCursor() {
10727
10676
  if (!this.textarea) {
@@ -10743,38 +10692,38 @@ class Renderer extends EventEmitting {
10743
10692
  updateSelection(range) {
10744
10693
  if (range.isEmpty && this.selectionLayer.marker) {
10745
10694
  this.selectionLayer.marker = null;
10746
- this.loop.schedule({ selection: true });
10695
+ this.scheduleChanges({ selection: true });
10747
10696
  }
10748
10697
  else if (!range.isEmpty && !this.selectionLayer.marker?.isEqual(range)) {
10749
10698
  this.selectionLayer.marker = range;
10750
- this.loop.schedule({ selection: true });
10699
+ this.scheduleChanges({ selection: true });
10751
10700
  }
10752
10701
  }
10753
10702
  updateSearchHighlights(ranges) {
10754
10703
  if (this.searchHighlightLayer.markers.length !== ranges.length ||
10755
10704
  !this.searchHighlightLayer.markers.every(x => ranges.some(y => x.isEqual(y)))) {
10756
10705
  this.searchHighlightLayer.markers = ranges;
10757
- this.loop.schedule({ search: true });
10706
+ this.scheduleChanges({ search: true });
10758
10707
  }
10759
10708
  }
10760
10709
  updateCustomElementHighlights(ranges) {
10761
10710
  this.searchHighlightLayer.customElementsRanges = ranges;
10762
- this.loop.schedule({ search: true });
10711
+ this.scheduleChanges({ search: true });
10763
10712
  }
10764
10713
  updateActiveSearchHighlight(active) {
10765
10714
  this.searchHighlightLayer.active = active;
10766
- this.loop.schedule({ search: true });
10715
+ this.scheduleChanges({ search: true });
10767
10716
  }
10768
10717
  updateGrammarHighlights(paragraphId, errors) {
10769
10718
  this.grammarHighlightLayer.setErrors(paragraphId, errors);
10770
- this.loop.schedule({ grammar: true });
10719
+ this.scheduleChanges({ grammar: true });
10771
10720
  }
10772
10721
  removeGrammarHighlights(paragraphId) {
10773
10722
  this.grammarHighlightLayer.removeParagraphHighlights(paragraphId);
10774
10723
  }
10775
10724
  clearGrammarHighlights() {
10776
10725
  this.grammarHighlightLayer.clearHighlights();
10777
- this.loop.schedule({ grammar: true });
10726
+ this.scheduleChanges({ grammar: true });
10778
10727
  }
10779
10728
  paragraphsScrolledIntoView() {
10780
10729
  if (!this.layerConfig.visibleRange) {
@@ -10787,11 +10736,11 @@ class Renderer extends EventEmitting {
10787
10736
  updateDragAndDropSelection(range) {
10788
10737
  if (range.isEmpty && this.dragAndDropSelectionLayer.marker) {
10789
10738
  this.dragAndDropSelectionLayer.marker = null;
10790
- this.loop.schedule({ dragAndDrop: true });
10739
+ this.scheduleChanges({ dragAndDrop: true });
10791
10740
  }
10792
10741
  else if (!range.isEmpty && !this.dragAndDropSelectionLayer.marker?.isEqual(range)) {
10793
10742
  this.dragAndDropSelectionLayer.marker = range;
10794
- this.loop.schedule({ dragAndDrop: true });
10743
+ this.scheduleChanges({ dragAndDrop: true });
10795
10744
  }
10796
10745
  }
10797
10746
  clearDragAndDropSelection() {
@@ -10799,7 +10748,7 @@ class Renderer extends EventEmitting {
10799
10748
  return;
10800
10749
  }
10801
10750
  this.dragAndDropSelectionLayer.marker = null;
10802
- this.loop.schedule({ dragAndDrop: true });
10751
+ this.scheduleChanges({ dragAndDrop: true });
10803
10752
  }
10804
10753
  setVisibility(isVisible) {
10805
10754
  if (this.isVisible !== isVisible) {
@@ -10807,23 +10756,23 @@ class Renderer extends EventEmitting {
10807
10756
  if (!isVisible) {
10808
10757
  this.commentsLayer.clearSessionComments();
10809
10758
  }
10810
- this.loop.schedule({ visibilityChanged: true });
10759
+ this.scheduleChanges({ visibilityChanged: true });
10811
10760
  }
10812
10761
  }
10813
10762
  /**
10814
10763
  * Triggers a full update of the text, for all the rows.
10815
10764
  **/
10816
10765
  updateText() {
10817
- this.loop.schedule({ text: true });
10766
+ this.scheduleChanges({ text: true });
10818
10767
  }
10819
10768
  updateTextAndCursor() {
10820
- this.loop.schedule({ text: true, cursor: true });
10769
+ this.scheduleChanges({ text: true, cursor: true });
10821
10770
  }
10822
10771
  updateMarker() {
10823
- this.loop.schedule({ marker: true });
10772
+ this.scheduleChanges({ marker: true });
10824
10773
  }
10825
10774
  updateCursor() {
10826
- this.loop.schedule({ cursor: true });
10775
+ this.scheduleChanges({ cursor: true });
10827
10776
  }
10828
10777
  // tokenDivider - used to measure if token fits (1 - should be fully fit, 2 - half of token, 3 - third part, ...) to be included
10829
10778
  screenToParagraph(x, y, tokenDivider = 1, rect) {
@@ -10880,14 +10829,11 @@ class Renderer extends EventEmitting {
10880
10829
  renderCommentHighlights() {
10881
10830
  this.commentsLayer.update(this.layerConfig);
10882
10831
  }
10883
- setSelectedComment(comment) {
10884
- this.commentsLayer.setSelectedComment(comment);
10885
- }
10886
10832
  removeComment(id) {
10887
10833
  this.commentsLayer.removeComment(id);
10888
10834
  }
10889
10835
  clearComments() {
10890
- this.commentsLayer.removeSessionComments();
10836
+ this.commentsLayer.clearSessionComments();
10891
10837
  }
10892
10838
  setCommentsVisibility(value) {
10893
10839
  if (!value) {
@@ -10895,6 +10841,9 @@ class Renderer extends EventEmitting {
10895
10841
  }
10896
10842
  this.commentsLayer.enabled = value;
10897
10843
  }
10844
+ scheduleChanges(changes) {
10845
+ this.loop.schedule(this.session.sessionId, changes);
10846
+ }
10898
10847
  renderDragAndDropSelection() {
10899
10848
  this.dragAndDropSelectionLayer.update(this.layerConfig);
10900
10849
  }
@@ -10925,6 +10874,65 @@ class Renderer extends EventEmitting {
10925
10874
  }
10926
10875
  }
10927
10876
 
10877
+ class EventHelper {
10878
+ static get nextFrame() {
10879
+ if (!this._nextFrame) {
10880
+ const nextFrame = (callback) => {
10881
+ setTimeout(callback, 17);
10882
+ };
10883
+ this._nextFrame =
10884
+ window.requestAnimationFrame ||
10885
+ window['webkitRequestAnimationFrame'] ||
10886
+ window['mozRequestAnimationFrame'] ||
10887
+ window['msRequestAnimationFrame'] ||
10888
+ window['oRequestAnimationFrame'] ||
10889
+ nextFrame;
10890
+ }
10891
+ return this._nextFrame;
10892
+ }
10893
+ }
10894
+
10895
+ class RenderLoop {
10896
+ constructor() {
10897
+ this.sessionCallbacks = new Map();
10898
+ this.sessionChanges = new Map();
10899
+ this.flush = () => {
10900
+ const sessionsToRender = Array.from(this.sessionChanges.entries());
10901
+ const hasChanges = sessionsToRender.filter(([_, changes]) => changes.any);
10902
+ if (!hasChanges.length) {
10903
+ return;
10904
+ }
10905
+ for (const [sessionId, changes] of hasChanges) {
10906
+ const callback = this.sessionCallbacks.get(sessionId);
10907
+ callback(new RenderChangesModel(changes));
10908
+ this.sessionChanges.set(sessionId, new RenderChangesModel());
10909
+ }
10910
+ const hasMoreChanges = Array.from(this.sessionChanges.values()).some(changes => changes.any);
10911
+ if (hasMoreChanges) {
10912
+ EventHelper.nextFrame(this.flush);
10913
+ }
10914
+ };
10915
+ }
10916
+ registerSession(sessionId, onRender) {
10917
+ this.sessionCallbacks.set(sessionId, onRender);
10918
+ if (!this.sessionChanges.has(sessionId)) {
10919
+ this.sessionChanges.set(sessionId, new RenderChangesModel());
10920
+ }
10921
+ }
10922
+ unregisterSession(sessionId) {
10923
+ this.sessionCallbacks.delete(sessionId);
10924
+ this.sessionChanges.delete(sessionId);
10925
+ }
10926
+ schedule(sessionId, changes) {
10927
+ if (changes) {
10928
+ this.sessionChanges.get(sessionId).apply(changes);
10929
+ }
10930
+ if (this.sessionChanges.get(sessionId).any) {
10931
+ EventHelper.nextFrame(this.flush);
10932
+ }
10933
+ }
10934
+ }
10935
+
10928
10936
  /**
10929
10937
  * Represents a vertical scroll bar.
10930
10938
  * @class ScrollBar
@@ -11046,13 +11054,17 @@ class CommentLayer {
11046
11054
  constructor(parentEl) {
11047
11055
  this.commentPadding = 8;
11048
11056
  this.rendersBySession = new Map();
11057
+ this.enabled = false;
11049
11058
  this.element = document.createElement('div');
11050
11059
  this.element.className = `noder-comments-layer`;
11051
11060
  parentEl.appendChild(this.element);
11052
11061
  }
11062
+ enable() {
11063
+ this.enabled = true;
11064
+ }
11053
11065
  disable() {
11054
- this.rendersBySession.clear();
11055
- this.renderComments();
11066
+ this.enabled = false;
11067
+ this.element.innerHTML = '';
11056
11068
  }
11057
11069
  scrollComments(offsetY) {
11058
11070
  for (const [sessionId, comments] of this.rendersBySession) {
@@ -11065,6 +11077,9 @@ class CommentLayer {
11065
11077
  }
11066
11078
  }
11067
11079
  renderComments() {
11080
+ if (!this.enabled) {
11081
+ return;
11082
+ }
11068
11083
  this.element.innerHTML = '';
11069
11084
  const topOffset = this.element.getBoundingClientRect().top;
11070
11085
  const sortedComments = Array.from(this.rendersBySession.values())
@@ -11256,12 +11271,6 @@ class VirtualRenderer {
11256
11271
  get cursorLayer() {
11257
11272
  return this.renderer.cursorLayer;
11258
11273
  }
11259
- get loop() {
11260
- return this.renderer.loop;
11261
- }
11262
- set loop(val) {
11263
- this.renderer.loop = val;
11264
- }
11265
11274
  get textarea() {
11266
11275
  return this.renderer.textarea;
11267
11276
  }
@@ -11277,10 +11286,12 @@ class VirtualRenderer {
11277
11286
  get paragraphsAppeared$() {
11278
11287
  return this.renderer.paragraphsAppeared.asObservable();
11279
11288
  }
11280
- constructor(parentContainer, mainSession, commentService, scrollBar) {
11289
+ constructor(parentContainer, mainSession, commentService, loop, scrollBar) {
11281
11290
  this.commentService = commentService;
11291
+ this.loop = loop;
11282
11292
  this.scrollBar = scrollBar;
11283
11293
  this.changes = new RenderChangesModel();
11294
+ this.grammarChecksEnabled = false;
11284
11295
  this.size = {
11285
11296
  width: 0,
11286
11297
  height: 0,
@@ -11291,18 +11302,19 @@ class VirtualRenderer {
11291
11302
  this.paragraphsScrolledIntoViewSubject = new Subject();
11292
11303
  this.container = parentContainer;
11293
11304
  this.createScroller();
11294
- this.renderer = new Renderer(parentContainer, commentService, mainSession);
11305
+ this.renderer = new Renderer(parentContainer, commentService, mainSession, loop);
11306
+ loop.registerSession(0, changes => this.renderChanges(changes));
11295
11307
  this.pagesLayer = new PagesLayer(this.renderer.content, mainSession);
11296
11308
  this.edgesLayer = new EdgesLayer(this.renderer.content, mainSession);
11297
11309
  this.commentLayer = new CommentLayer(this.renderer.content);
11298
11310
  this.scrollSubscription = this.scrollBar.scrolled$.subscribe(x => {
11299
11311
  this.commentLayer.scrollComments(x);
11300
- this.loop.schedule({ scroll: true, comments: true });
11312
+ this.scheduleChanges({ scroll: true, comments: true });
11301
11313
  });
11302
- this.createRenderLoop();
11303
11314
  this.paragraphsScrolledIntoViewSubscription = this.paragraphsScrolledIntoViewSubject
11304
- .pipe(debounceTime(3000))
11315
+ .pipe(filter(() => this.grammarChecksEnabled), debounceTime(3000))
11305
11316
  .subscribe(() => this.paragraphsScrolledIntoView());
11317
+ this.scheduleChanges({ full: true });
11306
11318
  }
11307
11319
  renderChanges(changes, force) {
11308
11320
  changes.apply(this.changes);
@@ -11381,7 +11393,7 @@ class VirtualRenderer {
11381
11393
  this.renderChanges(changes, true);
11382
11394
  }
11383
11395
  else {
11384
- this.loop.schedule(changes);
11396
+ this.scheduleChanges(changes);
11385
11397
  }
11386
11398
  this.scrollBar.setScrollTop(0);
11387
11399
  }
@@ -11411,21 +11423,28 @@ class VirtualRenderer {
11411
11423
  this.size.dirty = !width || !height;
11412
11424
  return changes;
11413
11425
  }
11414
- setSelectedComment(commentId) {
11415
- this.renderer.setSelectedComment(commentId);
11426
+ setSelectedComment(id) {
11427
+ const oldId = this.commentService.selectedCommentId;
11428
+ this.commentService.setSelectedComment(id);
11429
+ if (this.commentService.selectedCommentId !== oldId) {
11430
+ this.scheduleChanges({ comments: true });
11431
+ }
11416
11432
  }
11417
11433
  setCommentsVisibility(value) {
11418
11434
  if (value && !this.commentsSubscription) {
11435
+ this.commentLayer.enable();
11419
11436
  this.commentsSubscription = this.commentService.commentRenderRequests$.subscribe(x => {
11420
11437
  this.commentLayer.applyChanges(x);
11421
- this.loop.schedule({ comments: true });
11438
+ setTimeout(() => this.scheduleChanges({ comments: true }));
11422
11439
  });
11423
11440
  }
11424
11441
  else {
11442
+ this.commentLayer.disable();
11425
11443
  this.commentsSubscription?.unsubscribe();
11426
11444
  this.commentsSubscription = null;
11427
11445
  }
11428
11446
  this.renderer.setCommentsVisibility(value);
11447
+ this.scheduleChanges({ comments: true });
11429
11448
  }
11430
11449
  removeComment(id) {
11431
11450
  this.renderer.removeComment(id);
@@ -11492,6 +11511,9 @@ class VirtualRenderer {
11492
11511
  setVisibility(isVisible) {
11493
11512
  this.renderer.setVisibility(isVisible);
11494
11513
  }
11514
+ scheduleChanges(changes) {
11515
+ this.loop.schedule(0, changes);
11516
+ }
11495
11517
  scrollSelectionIntoView(anchor, lead, offset) {
11496
11518
  // first scroll anchor into view then scroll lead into view
11497
11519
  this.scrollCursorIntoView(anchor, offset);
@@ -11511,7 +11533,7 @@ class VirtualRenderer {
11511
11533
  top -= offset * this.container.scrollHeight;
11512
11534
  }
11513
11535
  this.scrollBar.setScrollTop(top);
11514
- this.loop.schedule({ scroll: true });
11536
+ this.scheduleChanges({ scroll: true });
11515
11537
  }
11516
11538
  else if (this.scrollBar.scrollTop + this.container.scrollHeight < top + position.height) {
11517
11539
  if (offset) {
@@ -11519,7 +11541,7 @@ class VirtualRenderer {
11519
11541
  }
11520
11542
  top += position.height - this.container.scrollHeight;
11521
11543
  this.scrollBar.setScrollTop(top);
11522
- this.loop.schedule({ scroll: true });
11544
+ this.scheduleChanges({ scroll: true });
11523
11545
  }
11524
11546
  }
11525
11547
  scrollBy(deltaY) {
@@ -11529,7 +11551,7 @@ class VirtualRenderer {
11529
11551
  const scrollTop = this.scrollBar.scrollTop + deltaY;
11530
11552
  this.scrollBar.setScrollTop(scrollTop);
11531
11553
  this.commentLayer.scrollComments(deltaY);
11532
- this.loop.schedule({ scroll: true, comments: true });
11554
+ this.scheduleChanges({ scroll: true, comments: true });
11533
11555
  }
11534
11556
  // tokenDivider - used to measure if token fits (1 - should be fully fit, 2 - half of token, 3 - third part, ...) to be included
11535
11557
  screenToParagraph(x, y, tokenDivider = 1, rect) {
@@ -11595,11 +11617,6 @@ class VirtualRenderer {
11595
11617
  this.scroller.className = 'noder-scroller';
11596
11618
  this.container.appendChild(this.scroller);
11597
11619
  }
11598
- createRenderLoop() {
11599
- this.loop = new RenderLoop(changes => this.renderChanges(changes));
11600
- this.renderer.loop = this.loop;
11601
- this.loop.schedule({ full: true });
11602
- }
11603
11620
  renderScroll(changes) {
11604
11621
  this.pagesLayer.update(this.layerConfig);
11605
11622
  this.edgesLayer.scrollEdges(this.layerConfig);
@@ -11792,6 +11809,7 @@ class CommentRenderService {
11792
11809
  this.applicationRef = inject(ApplicationRef);
11793
11810
  this.injector = inject(Injector);
11794
11811
  this.commentRenderRequests = new Subject();
11812
+ this.selectedCommentId = null;
11795
11813
  }
11796
11814
  requestCommentsRender(sessionId, renderRequests) {
11797
11815
  const requests = [];
@@ -11825,9 +11843,17 @@ class CommentRenderService {
11825
11843
  removeCommentsFromRender(sessionId) {
11826
11844
  this.commentRenderRequests.next(new RemoveCommentsFromDom(sessionId));
11827
11845
  }
11828
- setCommentSelected(id, selected = true) {
11846
+ setSelectedComment(id) {
11847
+ if (this.selectedCommentId === id) {
11848
+ return;
11849
+ }
11850
+ if (this.selectedCommentId) {
11851
+ const oldComponentRef = this.componentInstances.find(x => x.instance.id === this.selectedCommentId);
11852
+ oldComponentRef?.instance.setSelected(false);
11853
+ }
11829
11854
  const componentRef = this.componentInstances.find(x => x.instance.id === id);
11830
- componentRef?.instance.setSelected(selected);
11855
+ componentRef?.instance.setSelected(true);
11856
+ this.selectedCommentId = id;
11831
11857
  }
11832
11858
  createComponentRef(id) {
11833
11859
  const ref = createComponent(this.componentType, {
@@ -11857,6 +11883,7 @@ class RegulatorService {
11857
11883
  this.grammarEnabled = false;
11858
11884
  this.selectedCommentSessionId = null;
11859
11885
  this.selectedCommentId = null;
11886
+ this.renderLoop = new RenderLoop();
11860
11887
  this.grammarChecker = new GrammarChecker(this.grammarService);
11861
11888
  this.observer = this.initializeIntersectionObserver();
11862
11889
  }
@@ -11885,9 +11912,9 @@ class RegulatorService {
11885
11912
  const displayData = new DisplayData(model, properties, sessionId, model.pageFormats, DocumentInfo.pagesSpace, customComponents, this.customContentService, this.editorService);
11886
11913
  const scrollBar = new ScrollBar(container.nativeElement.parentElement);
11887
11914
  const mainSession = new EditSession(displayData, sessionId, this.customContentService, this.commentRenderService, model, this.selection, properties, this.editorService, customComponents, 'main', scrollBar);
11888
- const virtualRenderer = new VirtualRenderer(container.nativeElement, mainSession, this.commentRenderService, scrollBar);
11915
+ this.mainRenderer = new VirtualRenderer(container.nativeElement, mainSession, this.commentRenderService, this.renderLoop, scrollBar);
11889
11916
  this.editorService.styles = DEFAULT_TOOLBAR_STYLES();
11890
- this.mainSession = new SessionModel(mainSession, virtualRenderer, sessionId, null, new MainSessionSourceModel(), container.nativeElement);
11917
+ this.mainSession = new SessionModel(mainSession, this.mainRenderer, sessionId, null, new MainSessionSourceModel(), container.nativeElement);
11891
11918
  this.sessions.push(this.mainSession);
11892
11919
  this.currentSession = this.mainSession;
11893
11920
  displayData.updateNextLineIndexes(0, displayData.paragraphs.length - 1);
@@ -11903,7 +11930,7 @@ class RegulatorService {
11903
11930
  const session = new EditSession(displayData, sessionId, this.customContentService, this.commentRenderService, component.cell, this.selection, component.generalProperties, this.editorService, customComponents, sessionType);
11904
11931
  displayData.pagesFormat[0].contentWidth =
11905
11932
  displayData.pagesFormat[0].contentWidth === 0 ? 1 : displayData.pagesFormat[0].contentWidth;
11906
- const renderer = new Renderer(component.container.nativeElement, this.commentRenderService, session);
11933
+ const renderer = new Renderer(component.container.nativeElement, this.commentRenderService, session, this.renderLoop);
11907
11934
  const source = new CellSessionSourceModel(component.table, component);
11908
11935
  const newSession = new SessionModel(session, renderer, sessionId, component.parentSessionId, source, nativeElement);
11909
11936
  this.sessions.push(newSession);
@@ -11920,7 +11947,7 @@ class RegulatorService {
11920
11947
  const customComponents = { images: [], tables: [], tabs: [], customElements: [], edges: null };
11921
11948
  const displayData = new DisplayData(component.model, component.generalProperties, sessionId, this.getPageFormats(component.margins, component.width), 0, customComponents, this.customContentService, this.editorService);
11922
11949
  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);
11923
- const renderer = new Renderer(component.container.nativeElement, this.commentRenderService, session);
11950
+ const renderer = new Renderer(component.container.nativeElement, this.commentRenderService, session, this.renderLoop);
11924
11951
  const source = new EdgeSessionSourceModel(component.model.pageType, component.type);
11925
11952
  const newSession = new SessionModel(session, renderer, sessionId, component.parentSessionId, source, nativeElement);
11926
11953
  this.sessions.push(newSession);
@@ -12080,7 +12107,7 @@ class RegulatorService {
12080
12107
  setCommentsVisibility(value) {
12081
12108
  for (const sessionModel of this.sessions) {
12082
12109
  sessionModel.renderer.setCommentsVisibility(value);
12083
- sessionModel.renderer.loop.schedule({ commentHighlights: true });
12110
+ sessionModel.renderer.scheduleChanges({ commentHighlights: true });
12084
12111
  }
12085
12112
  }
12086
12113
  setSelectedComment(commentId) {
@@ -12089,36 +12116,38 @@ class RegulatorService {
12089
12116
  return;
12090
12117
  }
12091
12118
  const sessionModel = this.getSessionModel(this.selectedCommentSessionId);
12092
- sessionModel.renderer.setSelectedComment(null);
12093
- sessionModel.renderer.loop.schedule({ commentHighlights: true });
12119
+ this.mainRenderer.setSelectedComment(null);
12120
+ sessionModel.renderer.scheduleChanges({ commentHighlights: true });
12094
12121
  return;
12095
12122
  }
12123
+ this.mainRenderer.setSelectedComment(commentId);
12096
12124
  const newSelectedSession = this.sessions.find(x => x.session.model.comments.some(c => c.commentId === commentId));
12097
12125
  if (this.selectedCommentSessionId && this.selectedCommentSessionId !== newSelectedSession.sessionId) {
12098
12126
  const sessionModel = this.getSessionModel(this.selectedCommentSessionId);
12099
- sessionModel.renderer.setSelectedComment(null);
12100
- sessionModel.renderer.loop.schedule({ commentHighlights: true });
12127
+ sessionModel.renderer.scheduleChanges({ commentHighlights: true });
12128
+ newSelectedSession.renderer.scheduleChanges({ commentHighlights: true });
12101
12129
  }
12102
12130
  else {
12103
- newSelectedSession.renderer.setSelectedComment(commentId);
12104
- newSelectedSession.renderer.loop.schedule({ commentHighlights: true });
12131
+ newSelectedSession.renderer.scheduleChanges({ commentHighlights: true });
12105
12132
  }
12106
12133
  this.selectedCommentId = commentId;
12107
12134
  this.selectedCommentSessionId = newSelectedSession.sessionId;
12108
12135
  }
12109
12136
  setSelectedCommentAtCursor() {
12110
12137
  const comment = this.currentSession.session.getCommentAtCursor();
12138
+ this.mainRenderer.setSelectedComment(comment?.commentId);
12111
12139
  if (this.selectedCommentId && this.selectedCommentId !== comment?.commentId) {
12112
12140
  const sessionModel = this.getSessionModel(this.selectedCommentSessionId);
12113
- sessionModel.renderer.setSelectedComment(null);
12114
- sessionModel.renderer.loop.schedule({ commentHighlights: true });
12141
+ sessionModel.renderer.scheduleChanges({ commentHighlights: true });
12115
12142
  }
12116
12143
  if (comment) {
12117
- this.currentSession.renderer.setSelectedComment(comment.commentId);
12118
- this.currentSession.renderer.loop.schedule({ commentHighlights: true });
12144
+ this.currentSession.renderer.scheduleChanges({ commentHighlights: true });
12119
12145
  this.selectedCommentId = comment.commentId;
12120
12146
  this.selectedCommentSessionId = this.currentSession.sessionId;
12147
+ return;
12121
12148
  }
12149
+ this.selectedCommentId = null;
12150
+ this.selectedCommentSessionId = null;
12122
12151
  }
12123
12152
  isWithinEdge(sessionId) {
12124
12153
  return !!this.getEdgeSessionId(sessionId);
@@ -12147,12 +12176,14 @@ class RegulatorService {
12147
12176
  for (const session of this.sessions) {
12148
12177
  this.grammarChecker.registerSession(session);
12149
12178
  session.renderer.paragraphsScrolledIntoView();
12179
+ session.renderer.grammarChecksEnabled = true;
12150
12180
  }
12151
12181
  return;
12152
12182
  }
12153
12183
  for (const session of this.sessions) {
12154
12184
  this.grammarChecker.unregisterSession(session.sessionId);
12155
12185
  session.renderer.clearGrammarHighlights();
12186
+ session.renderer.grammarChecksEnabled = false;
12156
12187
  }
12157
12188
  }
12158
12189
  getEdgeSessionId(sessionId) {
@@ -15990,8 +16021,8 @@ class Editor {
15990
16021
  this.commentCreateRequests = this.commentCreateRequests.filter(x => x.reqId !== reqId);
15991
16022
  commentModel.commentId = commentId;
15992
16023
  sessionModel.session.addComment(commentModel);
15993
- sessionModel.renderer.setSelectedComment(commentModel.commentId);
15994
- sessionModel.renderer.loop.schedule({ commentHighlights: true });
16024
+ this.mainRenderer.setSelectedComment(commentModel.commentId);
16025
+ sessionModel.renderer.scheduleChanges({ commentHighlights: true });
15995
16026
  this.saveAttachCommentToHistory(commentModel);
15996
16027
  }
15997
16028
  onCommentRemoved(id) {
@@ -16000,7 +16031,7 @@ class Editor {
16000
16031
  session.renderer.removeComment(id);
16001
16032
  this.saveRemoveCommentToHistory(comment, session.source.getTarget());
16002
16033
  this.editorService.removeCommentData([id]);
16003
- session.renderer.loop.schedule({ commentHighlights: true });
16034
+ session.renderer.scheduleChanges({ commentHighlights: true });
16004
16035
  }
16005
16036
  onCommentTextReplace(commentId, newText) {
16006
16037
  const { session, comment } = this.regulatorService.getComment(commentId);
@@ -16033,7 +16064,7 @@ class Editor {
16033
16064
  window.removeEventListener('resize', this.rerenderResize);
16034
16065
  }
16035
16066
  rerenderMarker() {
16036
- this.renderer.loop.schedule({ marker: true });
16067
+ this.renderer.scheduleChanges({ marker: true });
16037
16068
  }
16038
16069
  onBlur() {
16039
16070
  if (!this.textInput.isFocused) {
@@ -16371,7 +16402,7 @@ class Editor {
16371
16402
  this.editorService.paragraphStyle(this.model.paragraphs[0].paragraphStyle);
16372
16403
  this.regulatorService.addMainSession(this.model, scalingRatio, this.container);
16373
16404
  }
16374
- onSelectionChange() {
16405
+ onSelectionChange(isMouseSelection = false) {
16375
16406
  this.session.applyToolbarStyles();
16376
16407
  this.renderer.updateSelection(this.selection.selectedRange);
16377
16408
  if (this.selection.isEmpty) {
@@ -16387,7 +16418,7 @@ class Editor {
16387
16418
  this.editorService.setPageFormat(pageFormat.pageFormatModel);
16388
16419
  this.rerenderMarker();
16389
16420
  this.regulatorService.setSelectedCommentAtCursor();
16390
- if (!this.selection.isEmpty && this.commentsVisible) {
16421
+ if (!this.selection.isEmpty && this.commentsVisible && !isMouseSelection) {
16391
16422
  const paragraphPos = this.session.selection.cursor;
16392
16423
  const cursor = PositionHelper.paragraphToPixel(this.session, paragraphPos.row, paragraphPos.column);
16393
16424
  const mainRect = this.mainRenderer.container.getBoundingClientRect();
@@ -16398,7 +16429,7 @@ class Editor {
16398
16429
  }
16399
16430
  }
16400
16431
  onContentChange() {
16401
- this.renderer.loop.schedule({ commentHighlights: true });
16432
+ this.renderer.scheduleChanges({ commentHighlights: true });
16402
16433
  if (this.search.term) {
16403
16434
  this.find(this.search.term);
16404
16435
  }
@@ -16502,7 +16533,7 @@ class Editor {
16502
16533
  const cursor = this.selection.cursor;
16503
16534
  this.selection.moveSelection(position);
16504
16535
  if (cursor.column !== this.selection.cursor.column || cursor.row !== this.selection.cursor.row) {
16505
- this.onSelectionChange();
16536
+ this.onSelectionChange(true);
16506
16537
  }
16507
16538
  this.scrollCursorIntoMainView();
16508
16539
  }
@@ -16603,7 +16634,7 @@ class Editor {
16603
16634
  viewOnlyModeSubscription() {
16604
16635
  return this.editorService.isViewOnly$.subscribe(() => {
16605
16636
  this.selection?.clearSelection();
16606
- this.renderer.loop.schedule({ grammar: true });
16637
+ this.renderer.scheduleChanges({ grammar: true });
16607
16638
  });
16608
16639
  }
16609
16640
  applyLeftMarginPageFormatSubscription() {
@@ -16931,7 +16962,7 @@ class Editor {
16931
16962
  ];
16932
16963
  }
16933
16964
  rerenderCommentsSubscription() {
16934
- return this.editorService.commentSizeChanged$.subscribe(() => this.mainRenderer.loop.schedule({ comments: true }));
16965
+ return this.editorService.commentSizeChanged$.subscribe(() => this.mainRenderer.scheduleChanges({ comments: true }));
16935
16966
  }
16936
16967
  selectCommentSubscription() {
16937
16968
  return this.editorService.setCommentSelected$.subscribe(x => this.regulatorService.setSelectedComment(x));