@talrace/ngx-noder 19.0.52 → 19.0.54

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 (28) hide show
  1. package/fesm2022/talrace-ngx-noder.mjs +964 -621
  2. package/fesm2022/talrace-ngx-noder.mjs.map +1 -1
  3. package/lib/editor/display/layers/layer.config.d.ts +0 -1
  4. package/lib/editor/display/render-changes.model.d.ts +0 -1
  5. package/lib/editor/display/renderer.d.ts +0 -2
  6. package/lib/editor/display/virtual.renderer.d.ts +0 -1
  7. package/lib/editor/execution/edit.session.d.ts +6 -2
  8. package/lib/editor/execution/editor.d.ts +13 -4
  9. package/lib/editor/execution/regulator.service.d.ts +0 -2
  10. package/lib/editor/gadgets/clipboard-handler/clipboard-handler.d.ts +23 -0
  11. package/lib/editor/gadgets/clipboard-handler/clipboard-slice.interface.d.ts +9 -0
  12. package/lib/editor/gadgets/history/operation-history.d.ts +5 -0
  13. package/lib/editor/gadgets/history/operation.type.d.ts +3 -1
  14. package/lib/editor/interaction/editor.service.d.ts +13 -0
  15. package/lib/editor/interaction/text-input.d.ts +0 -1
  16. package/lib/editor/operations/enums/command-type.enum.d.ts +3 -1
  17. package/lib/editor/operations/helpers/contents-operations.helper.d.ts +2 -0
  18. package/lib/editor/operations/helpers/format-operations.helper.d.ts +1 -0
  19. package/lib/editor/operations/helpers/indexed-element-operations.helper.d.ts +1 -0
  20. package/lib/editor/operations/helpers/link-operations.helper.d.ts +1 -0
  21. package/lib/editor/operations/helpers/range-element-operations.helper.d.ts +1 -0
  22. package/lib/editor/operations/operations-helper.helper.d.ts +2 -0
  23. package/lib/editor/operations/save-commands.helper.d.ts +4 -0
  24. package/lib/models/generated/command.model.d.ts +4 -0
  25. package/lib/models/generated/contents.model.d.ts +24 -0
  26. package/lib/models/generated/insert-contents.model.d.ts +6 -0
  27. package/lib/models/generated/replace-by-contents.model.d.ts +7 -0
  28. package/package.json +1 -1
@@ -1,6 +1,6 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { Directive, Injectable, signal, inject, ChangeDetectorRef, HostBinding, Input, InjectionToken, Component, ChangeDetectionStrategy, Inject, ViewChild, EventEmitter, Output, HostListener, createComponent, ApplicationRef, Injector, input, computed, effect, NgModule, output } from '@angular/core';
3
- import { Subject, BehaviorSubject, distinctUntilChanged, debounceTime, filter, fromEvent, take, throttleTime, startWith, takeUntil, tap, map, catchError } from 'rxjs';
3
+ import { Subject, BehaviorSubject, distinctUntilChanged, debounceTime, filter, fromEvent, take, throttleTime, startWith, takeUntil, switchMap, from, tap, map, catchError } from 'rxjs';
4
4
  import * as i1$2 from '@angular/common/http';
5
5
  import { HttpHeaders } from '@angular/common/http';
6
6
  import { ComponentPortal } from '@angular/cdk/portal';
@@ -626,6 +626,7 @@ class PageFormatModel {
626
626
  class EditorService {
627
627
  constructor() {
628
628
  this._styles$ = new BehaviorSubject({});
629
+ this._revisionId$ = new BehaviorSubject(0);
629
630
  this._receiveTextStyle$ = new Subject();
630
631
  this._isViewOnly$ = new BehaviorSubject(false);
631
632
  this._isViewOnly = false;
@@ -719,6 +720,8 @@ class EditorService {
719
720
  this._setCommentsVisibility$ = new Subject();
720
721
  this._getCommentText$ = new Subject();
721
722
  this._replaceCommentText$ = new Subject();
723
+ this._requestContentsInsertion$ = new Subject();
724
+ this._insertContents$ = new Subject();
722
725
  this._startNewList$ = new Subject();
723
726
  this._continueNumbering$ = new Subject();
724
727
  this._setNumberingValue$ = new Subject();
@@ -732,6 +735,9 @@ class EditorService {
732
735
  get styles$() {
733
736
  return this._styles$.asObservable();
734
737
  }
738
+ get revisionId() {
739
+ return this._revisionId$.value;
740
+ }
735
741
  get receiveTextStyle$() {
736
742
  return this._receiveTextStyle$.asObservable();
737
743
  }
@@ -1024,6 +1030,12 @@ class EditorService {
1024
1030
  get replaceCommentText$() {
1025
1031
  return this._replaceCommentText$.asObservable();
1026
1032
  }
1033
+ get requestContentsInsertion$() {
1034
+ return this._requestContentsInsertion$.asObservable();
1035
+ }
1036
+ get insertContents$() {
1037
+ return this._insertContents$.asObservable();
1038
+ }
1027
1039
  get startNewList$() {
1028
1040
  return this._startNewList$.asObservable();
1029
1041
  }
@@ -1033,6 +1045,12 @@ class EditorService {
1033
1045
  get setNumberingValue$() {
1034
1046
  return this._setNumberingValue$.asObservable();
1035
1047
  }
1048
+ requestContentsInsertion(contents, from) {
1049
+ this._requestContentsInsertion$.next({ contents, from });
1050
+ }
1051
+ insertContents(contents) {
1052
+ this._insertContents$.next(contents);
1053
+ }
1036
1054
  startNewList() {
1037
1055
  this._startNewList$.next();
1038
1056
  }
@@ -1090,6 +1108,9 @@ class EditorService {
1090
1108
  }
1091
1109
  this._currentPage$.next(value);
1092
1110
  }
1111
+ setRevisionId(id) {
1112
+ this._revisionId$.next(id);
1113
+ }
1093
1114
  receiveTextStyle(component) {
1094
1115
  this._receiveTextStyle$.next(component);
1095
1116
  }
@@ -1666,6 +1687,8 @@ var CommandType;
1666
1687
  CommandType[CommandType["RemoveComment"] = 39] = "RemoveComment";
1667
1688
  CommandType[CommandType["ApplyNumberingLevels"] = 40] = "ApplyNumberingLevels";
1668
1689
  CommandType[CommandType["ApplyNewNumberingForParagraphs"] = 41] = "ApplyNewNumberingForParagraphs";
1690
+ CommandType[CommandType["InsertContents"] = 42] = "InsertContents";
1691
+ CommandType[CommandType["ReplaceByContents"] = 43] = "ReplaceByContents";
1669
1692
  })(CommandType || (CommandType = {}));
1670
1693
 
1671
1694
  class PageNumbersModel {
@@ -1824,6 +1847,112 @@ class BreakHelper {
1824
1847
  }
1825
1848
  }
1826
1849
 
1850
+ class ClipboardHandler {
1851
+ constructor(cdkClipboard) {
1852
+ this.cdkClipboard = cdkClipboard;
1853
+ this.sliceMime = 'application/x-noder-slice+json';
1854
+ this.webSliceMime = `web ${this.sliceMime}`;
1855
+ this.internalState = null;
1856
+ }
1857
+ copyEvent(event, text, slice, revisionId) {
1858
+ if (!event.clipboardData) {
1859
+ this.copyAsync(text, slice, revisionId).catch(() => { });
1860
+ return;
1861
+ }
1862
+ event.preventDefault();
1863
+ const sliceData = this.createSliceData(slice, revisionId);
1864
+ event.clipboardData.setData('text/plain', text);
1865
+ event.clipboardData.setData(this.webSliceMime, JSON.stringify(sliceData));
1866
+ this.internalState = { text, sliceData };
1867
+ this.copyAsync(text, slice, revisionId, false).catch(() => { }); // event not update navigation clipboard! Need update both!
1868
+ }
1869
+ readEvent(event) {
1870
+ if (!event.clipboardData) {
1871
+ return { text: null, sliceData: null };
1872
+ }
1873
+ event.preventDefault();
1874
+ const text = event.clipboardData.getData('text/plain');
1875
+ const sliceJson = event.clipboardData.getData(this.webSliceMime);
1876
+ const sliceData = this.getClipboardSlice(text, sliceJson);
1877
+ return { text: text || null, sliceData };
1878
+ }
1879
+ async copyAsync(text, slice, revisionId, useFallback = true) {
1880
+ const sliceData = this.createSliceData(slice, revisionId);
1881
+ try {
1882
+ const textBlob = new Blob([text], { type: 'text/plain' });
1883
+ const sliceBlob = new Blob([JSON.stringify(sliceData)], { type: this.webSliceMime });
1884
+ const clipboardItem = new ClipboardItem({
1885
+ // eslint-disable-next-line @typescript-eslint/naming-convention
1886
+ 'text/plain': Promise.resolve(textBlob), // Promise for Safari
1887
+ [this.webSliceMime]: Promise.resolve(sliceBlob)
1888
+ });
1889
+ await navigator.clipboard.write([clipboardItem]);
1890
+ }
1891
+ catch {
1892
+ if (useFallback) {
1893
+ this.cdkClipboard.copy(text);
1894
+ }
1895
+ }
1896
+ this.internalState = { text, sliceData };
1897
+ }
1898
+ async readAsync() {
1899
+ try {
1900
+ const items = await navigator.clipboard.read();
1901
+ const item = items[0];
1902
+ if (!item) {
1903
+ return { text: null, sliceData: null };
1904
+ }
1905
+ let text = null;
1906
+ let jsonSliceData = null;
1907
+ if (item.types.includes(this.webSliceMime)) {
1908
+ const sliceBlob = await item.getType(this.webSliceMime);
1909
+ jsonSliceData = await sliceBlob.text();
1910
+ }
1911
+ if (item.types.includes('text/plain')) {
1912
+ const textBlob = await item.getType('text/plain');
1913
+ text = await textBlob.text();
1914
+ }
1915
+ const sliceData = this.getClipboardSlice(text || '', jsonSliceData || '');
1916
+ return { text, sliceData };
1917
+ }
1918
+ catch {
1919
+ return await this.readFallback();
1920
+ }
1921
+ }
1922
+ getClipboardSlice(clipboardText, clipboardSliceData) {
1923
+ if (this.internalState && this.internalState.text === clipboardText) {
1924
+ return this.internalState.sliceData;
1925
+ }
1926
+ if (!clipboardSliceData) {
1927
+ return null;
1928
+ }
1929
+ try {
1930
+ return JSON.parse(clipboardSliceData);
1931
+ }
1932
+ catch {
1933
+ return null;
1934
+ }
1935
+ }
1936
+ async readFallback() {
1937
+ try {
1938
+ const text = await navigator.clipboard.readText();
1939
+ const sliceData = this.getClipboardSlice(text, '');
1940
+ return { text, sliceData };
1941
+ }
1942
+ catch {
1943
+ return { text: null, sliceData: null };
1944
+ }
1945
+ }
1946
+ createSliceData(slice, revisionId) {
1947
+ return {
1948
+ type: 'NODER_SLICE',
1949
+ version: 1,
1950
+ source: { revisionId },
1951
+ data: slice
1952
+ };
1953
+ }
1954
+ }
1955
+
1827
1956
  const COMMENT_TYPES = new InjectionToken('COMMENT_TYPES');
1828
1957
 
1829
1958
  class OverlayService {
@@ -1957,77 +2086,7 @@ class ContentHelper {
1957
2086
  }
1958
2087
  }
1959
2088
 
1960
- const CONTEXT_MENU_HEIGHT = 210;
1961
- const CONTEXT_MENU_WIDTH = 320;
1962
- class ContextMenuComponent {
1963
- constructor(editorService, overlayService) {
1964
- this.editorService = editorService;
1965
- this.overlayService = overlayService;
1966
- }
1967
- ngOnDestroy() {
1968
- this.overlayService.close();
1969
- }
1970
- onCopy() {
1971
- this.editorService.copySelected();
1972
- this.overlayService.close();
1973
- }
1974
- onPaste() {
1975
- this.editorService.pasteFromClipboard();
1976
- this.overlayService.close();
1977
- }
1978
- onCut() {
1979
- this.editorService.cutSelected();
1980
- this.overlayService.close();
1981
- }
1982
- onStartNewList() {
1983
- this.editorService.startNewList();
1984
- this.overlayService.close();
1985
- }
1986
- onContinueNumbering() {
1987
- this.editorService.continueNumbering();
1988
- this.overlayService.close();
1989
- }
1990
- onSetNumberingValue() {
1991
- this.overlayService.close(AfterCloseOverlayActions.OpenSetNumberingValue);
1992
- }
1993
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: ContextMenuComponent, deps: [{ token: EditorService }, { token: OverlayService }], target: i0.ɵɵFactoryTarget.Component }); }
1994
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.5", type: ContextMenuComponent, isStandalone: true, selector: "app-nod-context-menu", inputs: { hasNumbering: "hasNumbering", hasSelection: "hasSelection", disableContinueNumber: "disableContinueNumber" }, host: { properties: { "style.height.px": "210", "style.width.px": "320" } }, ngImport: i0, template: "<button\n mat-button\n (click)=\"onCopy()\"\n [disabled]=\"!hasSelection\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-copy\" />\n {{ 'NODER.LABEL.COPY' | translate }}\n</button>\n<button\n mat-button\n (click)=\"onPaste()\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-paste\" />\n {{ 'NODER.LABEL.PASTE' | translate }}\n</button>\n<button\n mat-button\n (click)=\"onCut()\"\n [disabled]=\"!hasSelection\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-cut\" />\n {{ 'NODER.LABEL.CUT' | translate }}\n</button>\n<div class=\"separator\"></div>\n<button\n mat-button\n (click)=\"onStartNewList()\"\n [disabled]=\"!hasNumbering\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-restart-numbering\" />\n {{ 'NODER.LABEL.START_NEW_LIST' | translate }}\n</button>\n<button\n mat-button\n (click)=\"onContinueNumbering()\"\n [disabled]=\"!hasNumbering || disableContinueNumber\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-continue-numbering\" />\n {{ 'NODER.LABEL.CONTINUE_NUMBERING' | translate }}\n</button>\n<button\n mat-button\n (click)=\"onSetNumberingValue()\"\n [disabled]=\"!hasNumbering\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-starting-value\" />\n {{ 'NODER.LABEL.SET_NUMBERING_VALUE' | translate }}\n</button>\n", styles: [":host{display:flex;padding:8px 16px;flex-direction:column;align-items:flex-start;gap:4px;border-radius:8px;box-shadow:2px 2px 8px #21212129}.separator{width:288px;height:1px}button{width:100%;justify-content:start;min-height:28px;height:28px}\n"], dependencies: [{ kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i4.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i6.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1995
- }
1996
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: ContextMenuComponent, decorators: [{
1997
- type: Component,
1998
- args: [{ selector: 'app-nod-context-menu', changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatButtonModule, TranslateModule, MatIconModule], host: {
1999
- '[style.height.px]': `${CONTEXT_MENU_HEIGHT}`,
2000
- '[style.width.px]': `${CONTEXT_MENU_WIDTH}`
2001
- }, template: "<button\n mat-button\n (click)=\"onCopy()\"\n [disabled]=\"!hasSelection\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-copy\" />\n {{ 'NODER.LABEL.COPY' | translate }}\n</button>\n<button\n mat-button\n (click)=\"onPaste()\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-paste\" />\n {{ 'NODER.LABEL.PASTE' | translate }}\n</button>\n<button\n mat-button\n (click)=\"onCut()\"\n [disabled]=\"!hasSelection\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-cut\" />\n {{ 'NODER.LABEL.CUT' | translate }}\n</button>\n<div class=\"separator\"></div>\n<button\n mat-button\n (click)=\"onStartNewList()\"\n [disabled]=\"!hasNumbering\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-restart-numbering\" />\n {{ 'NODER.LABEL.START_NEW_LIST' | translate }}\n</button>\n<button\n mat-button\n (click)=\"onContinueNumbering()\"\n [disabled]=\"!hasNumbering || disableContinueNumber\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-continue-numbering\" />\n {{ 'NODER.LABEL.CONTINUE_NUMBERING' | translate }}\n</button>\n<button\n mat-button\n (click)=\"onSetNumberingValue()\"\n [disabled]=\"!hasNumbering\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-starting-value\" />\n {{ 'NODER.LABEL.SET_NUMBERING_VALUE' | translate }}\n</button>\n", styles: [":host{display:flex;padding:8px 16px;flex-direction:column;align-items:flex-start;gap:4px;border-radius:8px;box-shadow:2px 2px 8px #21212129}.separator{width:288px;height:1px}button{width:100%;justify-content:start;min-height:28px;height:28px}\n"] }]
2002
- }], ctorParameters: () => [{ type: EditorService }, { type: OverlayService }], propDecorators: { hasNumbering: [{
2003
- type: Input
2004
- }], hasSelection: [{
2005
- type: Input
2006
- }], disableContinueNumber: [{
2007
- type: Input
2008
- }] } });
2009
-
2010
- class CreateEdgesModel {
2011
- constructor(fields) {
2012
- if (fields) {
2013
- Object.assign(this, fields);
2014
- }
2015
- }
2016
- }
2017
-
2018
- const PARENT_TAG = 'APP-NOD-EDITOR';
2019
- const TABLE_CELL_TAG = 'APP-NOD-TABLE-CELL';
2020
- const EDGE_TAG = 'APP-NOD-EDGE';
2021
- const IMAGE_TAG = 'APP-NOD-IMAGE';
2022
- const CUSTOM_TAG = 'app-nod-custom-element';
2023
-
2024
- class CustomElementSearchResult {
2025
- constructor(init) {
2026
- Object.assign(this, init);
2027
- }
2028
- }
2029
-
2030
- class DeleteModel {
2089
+ class BreakModel {
2031
2090
  constructor(fields) {
2032
2091
  if (fields) {
2033
2092
  Object.assign(this, fields);
@@ -2035,98 +2094,24 @@ class DeleteModel {
2035
2094
  }
2036
2095
  }
2037
2096
 
2038
- class BaseHandler {
2039
- constructor() {
2040
- this.actions = {};
2041
- }
2042
- getKeyCombination(event) {
2043
- let result = event.metaKey ? 'Command-' : '';
2044
- if (event.ctrlKey) {
2045
- result = `${result}Ctrl-`;
2046
- }
2047
- if (event.altKey) {
2048
- result = `${result}Alt-`;
2049
- }
2050
- if (event.shiftKey) {
2051
- result = `${result}Shift-`;
2052
- }
2053
- return `${result}${event.code}`;
2054
- }
2055
- }
2056
-
2057
- class DocumentHandler extends BaseHandler {
2058
- constructor(editor) {
2059
- super();
2060
- this.documentKeyDown$ = fromEvent(document, 'keydown').subscribe((event) => this.onKeyDown(event));
2061
- this.contextMenu$ = fromEvent(document, 'contextmenu').subscribe(event => event.preventDefault());
2062
- this.fillActions(editor);
2063
- }
2064
- destroy() {
2065
- this.documentKeyDown$?.unsubscribe();
2066
- this.contextMenu$.unsubscribe();
2067
- }
2068
- onKeyDown(event) {
2069
- const keyCombination = this.getKeyCombination(event);
2070
- if (this.actions[keyCombination]) {
2071
- this.actions[keyCombination](event);
2072
- }
2073
- else {
2074
- return;
2075
- }
2076
- event.preventDefault();
2077
- }
2078
- fillActions(editor) {
2079
- this.actions['Ctrl-KeyP'] = () => editor.onPrint();
2080
- this.actions['Ctrl-KeyO'] = (event) => editor.onHotKeyDown(event);
2081
- }
2082
- }
2083
-
2084
- class DragAndDrop {
2085
- constructor(editorContainer) {
2086
- this.editorContainer = editorContainer;
2087
- this.onMove$ = new Subject();
2088
- this.onDrop$ = new Subject();
2089
- }
2090
- onStart(session, range) {
2091
- if (this.isDragging) {
2092
- return;
2093
- }
2094
- this.isDragging = true;
2095
- this.editorContainer.classList.add('drag-and-drop-progress');
2096
- this.sourceSession = session;
2097
- this.sourceRange = range;
2098
- this.initListeners();
2097
+ class ContentOperationsHelper {
2098
+ static removeContent(content, startIndex, count) {
2099
+ return `${content.slice(0, startIndex)}${content.slice(startIndex + count, content.length)}`;
2099
2100
  }
2100
- destroyListeners() {
2101
- this.mouseMove$?.unsubscribe();
2102
- this.mouseUp$?.unsubscribe();
2101
+ static sliceContent(content, startIndex, count) {
2102
+ return content.slice(startIndex, startIndex + count);
2103
2103
  }
2104
- onEnd() {
2105
- this.destroyListeners();
2106
- if (!this.isDragging) {
2107
- return;
2108
- }
2109
- this.isDragging = false;
2110
- this.editorContainer.classList.remove('drag-and-drop-progress');
2111
- this.onDrop$.next({ sourceSession: this.sourceSession, sourceRange: this.sourceRange });
2104
+ static insertContent(content, text, index) {
2105
+ const before = content.slice(0, index);
2106
+ const after = content.slice(index, content.length);
2107
+ return `${before}${text}${after}`;
2112
2108
  }
2113
- initListeners() {
2114
- this.destroyListeners();
2115
- this.mouseMove$ = fromEvent(document, 'mousemove')
2116
- .pipe(throttleTime(20))
2117
- .subscribe(event => this.onMove$.next(event));
2118
- this.mouseUp$ = fromEvent(document, 'mouseup')
2119
- .pipe(take(1))
2120
- .subscribe(() => this.onEnd());
2109
+ static replaceContent(content, startIndex, endIndex, text) {
2110
+ const reduced = this.removeContent(content, startIndex, endIndex - startIndex + 1);
2111
+ return this.insertContent(reduced, text, startIndex);
2121
2112
  }
2122
2113
  }
2123
2114
 
2124
- var EdgeType;
2125
- (function (EdgeType) {
2126
- EdgeType[EdgeType["Header"] = 0] = "Header";
2127
- EdgeType[EdgeType["Footer"] = 1] = "Footer";
2128
- })(EdgeType || (EdgeType = {}));
2129
-
2130
2115
  class ElementModel {
2131
2116
  constructor(fields) {
2132
2117
  if (fields) {
@@ -2162,58 +2147,504 @@ class FormatHelper {
2162
2147
  }
2163
2148
  }
2164
2149
 
2165
- class GrammarPopupComponent {
2166
- constructor(editorService, overlayService) {
2167
- this.editorService = editorService;
2168
- this.overlayService = overlayService;
2169
- }
2170
- onSuggestionClick(index) {
2171
- this.editorService.applyGrammarSuggestion(this.error, index, this.paragraphIndex);
2172
- this.overlayService.close();
2173
- }
2174
- onIgnoreClick() {
2175
- this.editorService.ignoreGrammarSuggestion(this.error);
2176
- this.overlayService.close();
2150
+ class BordersStyleModel {
2151
+ constructor(fields) {
2152
+ if (fields) {
2153
+ Object.assign(this, fields);
2154
+ }
2177
2155
  }
2178
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: GrammarPopupComponent, deps: [{ token: EditorService }, { token: OverlayService }], target: i0.ɵɵFactoryTarget.Component }); }
2179
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.5", type: GrammarPopupComponent, isStandalone: true, selector: "app-nod-grammar-popup", inputs: { error: "error", paragraphIndex: "paragraphIndex" }, ngImport: i0, template: "<span class=\"message\">{{ error.message }}</span>\n<div class=\"options\">\n @for (suggestion of error.replacements; track i; let i = $index) {\n <span\n class=\"suggestion\"\n (click)=\"onSuggestionClick(i)\">\n {{ suggestion }}\n </span>\n }\n</div>\n<button\n mat-button\n class=\"ignore\"\n (click)=\"onIgnoreClick()\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-ignore\"></mat-icon>\n <span>\n {{ 'NODER.LABEL.IGNORE' | translate }}\n </span>\n</button>\n", styles: [":host{border-radius:8px;display:flex;flex-direction:column;padding:8px;max-width:500px;gap:5px}.message{flex:1;display:flex;align-items:center;justify-content:center;text-align:center;font-size:12px}.options{display:flex;flex-flow:column wrap;justify-content:center;gap:5px;padding:10px 0;border-bottom-width:1px;border-bottom-style:solid}.suggestion{font-weight:600;font-size:14px;cursor:pointer;text-decoration:underline;padding:3px 8px}.ignore{margin-left:auto;font-size:12px;letter-spacing:0;cursor:pointer;height:32px}.ignore mat-icon{margin-right:4px}\n"], dependencies: [{ kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i4.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i6.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2180
2156
  }
2181
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: GrammarPopupComponent, decorators: [{
2182
- type: Component,
2183
- args: [{ selector: 'app-nod-grammar-popup', changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatButtonModule, MatIconModule, TranslateModule], standalone: true, template: "<span class=\"message\">{{ error.message }}</span>\n<div class=\"options\">\n @for (suggestion of error.replacements; track i; let i = $index) {\n <span\n class=\"suggestion\"\n (click)=\"onSuggestionClick(i)\">\n {{ suggestion }}\n </span>\n }\n</div>\n<button\n mat-button\n class=\"ignore\"\n (click)=\"onIgnoreClick()\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-ignore\"></mat-icon>\n <span>\n {{ 'NODER.LABEL.IGNORE' | translate }}\n </span>\n</button>\n", styles: [":host{border-radius:8px;display:flex;flex-direction:column;padding:8px;max-width:500px;gap:5px}.message{flex:1;display:flex;align-items:center;justify-content:center;text-align:center;font-size:12px}.options{display:flex;flex-flow:column wrap;justify-content:center;gap:5px;padding:10px 0;border-bottom-width:1px;border-bottom-style:solid}.suggestion{font-weight:600;font-size:14px;cursor:pointer;text-decoration:underline;padding:3px 8px}.ignore{margin-left:auto;font-size:12px;letter-spacing:0;cursor:pointer;height:32px}.ignore mat-icon{margin-right:4px}\n"] }]
2184
- }], ctorParameters: () => [{ type: EditorService }, { type: OverlayService }], propDecorators: { error: [{
2185
- type: Input
2186
- }], paragraphIndex: [{
2187
- type: Input
2188
- }] } });
2189
2157
 
2190
- class ImageDataModel {
2158
+ class ImageModel {
2191
2159
  constructor(fields) {
2192
2160
  if (fields) {
2161
+ if (fields.border) {
2162
+ fields.border = new BordersStyleModel(fields.border);
2163
+ }
2193
2164
  Object.assign(this, fields);
2194
2165
  }
2195
2166
  }
2196
2167
  }
2197
2168
 
2198
- class ImageHelper {
2199
- static getImageWithAllowedSize(imageData, maxWidth) {
2200
- if (imageData.width <= maxWidth) {
2201
- return imageData;
2202
- }
2203
- const aspectRatio = imageData.width / imageData.height;
2204
- const height = maxWidth / aspectRatio;
2205
- return new ImageDataModel({ width: Math.round(maxWidth), height: Math.round(height), content: imageData.content });
2169
+ class IndexedElementHelper {
2170
+ static sliceSection(elements, startIndex, endIndex) {
2171
+ return elements.filter(x => x.insertIndex >= startIndex && x.insertIndex <= endIndex);
2172
+ }
2173
+ static shiftIndexes(elements, offset) {
2174
+ for (const element of elements) {
2175
+ element.insertIndex += offset;
2176
+ }
2177
+ }
2178
+ }
2179
+
2180
+ class LinkModel {
2181
+ constructor(fields) {
2182
+ if (fields) {
2183
+ Object.assign(this, fields);
2184
+ }
2185
+ }
2186
+ }
2187
+
2188
+ class LinkHelper {
2189
+ static sliceSection(links, start, end) {
2190
+ return links.map(link => LinkHelper.getPartialLink(link, start, end)).filter(x => x !== null);
2191
+ }
2192
+ static shiftIndexes(links, offset) {
2193
+ for (const link of links) {
2194
+ link.startIndex += offset;
2195
+ link.endIndex += offset;
2196
+ }
2197
+ }
2198
+ static sliceFormats(links, startIndex, endIndex) {
2199
+ const result = [];
2200
+ for (const link of links) {
2201
+ const absoluteFormats = link.formats.map(x => new FormatModel({ ...x, startIndex: x.startIndex + link.startIndex, endIndex: x.endIndex + link.startIndex }));
2202
+ const slicedLinkFormats = FormatHelper.sliceSection(absoluteFormats, startIndex, endIndex);
2203
+ result.push(...slicedLinkFormats);
2204
+ }
2205
+ return result;
2206
+ }
2207
+ static getPartialLink(link, selectionStart, selectionEnd) {
2208
+ if (link.endIndex < selectionStart || link.startIndex > selectionEnd) {
2209
+ return null;
2210
+ }
2211
+ const newStart = Math.max(link.startIndex, selectionStart);
2212
+ const newEnd = Math.min(link.endIndex, selectionEnd);
2213
+ const formats = link.formats
2214
+ .map(format => {
2215
+ const formatStart = link.startIndex + format.startIndex;
2216
+ const formatEnd = link.startIndex + format.endIndex;
2217
+ if (formatEnd < newStart || formatStart > newEnd) {
2218
+ return null;
2219
+ }
2220
+ const newFormatStart = Math.max(formatStart, newStart) - newStart;
2221
+ const newFormatEnd = Math.min(formatEnd, newEnd) - newStart;
2222
+ const textStyle = new TextStyleModel(format.textStyle);
2223
+ return new FormatModel({ startIndex: newFormatStart, endIndex: newFormatEnd, textStyle });
2224
+ })
2225
+ .filter(x => x !== null);
2226
+ return new LinkModel({ ...link, startIndex: newStart, endIndex: newEnd, formats });
2227
+ }
2228
+ }
2229
+
2230
+ class PageFormatHelper {
2231
+ static sliceSection(content, start, end) {
2232
+ if (content instanceof DocxModel) {
2233
+ return content.pageFormats.filter(x => x.insertIndex !== 0 && x.insertIndex >= start && x.insertIndex <= end);
2234
+ }
2235
+ return [];
2236
+ }
2237
+ static shiftIndexes(pagesFormats, offset) {
2238
+ for (const pageFormat of pagesFormats) {
2239
+ if (pageFormat.insertIndex === 0) {
2240
+ return;
2241
+ }
2242
+ pageFormat.insertIndex += offset;
2243
+ }
2244
+ }
2245
+ }
2246
+
2247
+ class ParagraphModel {
2248
+ constructor(fields) {
2249
+ if (fields) {
2250
+ if (fields.paragraphStyle) {
2251
+ fields.paragraphStyle = new ParagraphStyleModel(fields.paragraphStyle);
2252
+ }
2253
+ Object.assign(this, fields);
2254
+ }
2255
+ }
2256
+ }
2257
+
2258
+ class RangeElementHelper {
2259
+ static removeContent(elements, startIndex, endIndex) {
2260
+ const length = endIndex - startIndex + 1;
2261
+ for (let i = elements.length - 1; i >= 0; i--) {
2262
+ const element = elements[i];
2263
+ if (element.endIndex < startIndex) {
2264
+ continue;
2265
+ }
2266
+ if (element.startIndex < startIndex) {
2267
+ if (element.endIndex > endIndex) {
2268
+ element.endIndex -= length;
2269
+ }
2270
+ else {
2271
+ element.endIndex = startIndex - 1;
2272
+ }
2273
+ continue;
2274
+ }
2275
+ if (element.startIndex >= startIndex && element.startIndex <= endIndex) {
2276
+ if (element.endIndex <= endIndex) {
2277
+ elements.splice(i, 1);
2278
+ continue;
2279
+ }
2280
+ element.startIndex -= element.startIndex - startIndex;
2281
+ element.endIndex -= endIndex - element.startIndex;
2282
+ continue;
2283
+ }
2284
+ element.startIndex -= length;
2285
+ element.endIndex -= length;
2286
+ }
2287
+ }
2288
+ static insertContent(elements, index, length) {
2289
+ for (const element of elements) {
2290
+ if (element.startIndex >= index) {
2291
+ element.startIndex += length;
2292
+ element.endIndex += length;
2293
+ }
2294
+ else if (element.endIndex > index) {
2295
+ element.endIndex += length;
2296
+ }
2297
+ }
2298
+ }
2299
+ static insertRelative(elements, insertIndex, insertLength, insertElements) {
2300
+ this.insertContent(elements, insertIndex, insertLength);
2301
+ if (insertElements.length === 0) {
2302
+ return;
2303
+ }
2304
+ for (const element of insertElements) {
2305
+ element.startIndex += insertIndex;
2306
+ element.endIndex += insertIndex;
2307
+ }
2308
+ const targetIndex = elements.findIndex(x => x.startIndex === insertIndex);
2309
+ if (targetIndex < 0) {
2310
+ elements.push(...insertElements);
2311
+ }
2312
+ else {
2313
+ elements.splice(targetIndex, 0, ...insertElements);
2314
+ }
2315
+ }
2316
+ static restore(elements, index, contentLength, newElements) {
2317
+ RangeElementHelper.insertContent(elements, index, contentLength);
2318
+ const nextElement = elements.find(x => x.startIndex >= index);
2319
+ const indexInElements = nextElement !== undefined ? elements.indexOf(nextElement) : elements.length;
2320
+ elements.splice(indexInElements, 0, ...newElements);
2321
+ }
2322
+ static replaceContent(elements, startIndex, endIndex, length) {
2323
+ RangeElementHelper.removeContent(elements, startIndex, endIndex);
2324
+ RangeElementHelper.insertContent(elements, startIndex, length);
2325
+ }
2326
+ static shiftIndexes(elements, offset) {
2327
+ for (const element of elements) {
2328
+ element.startIndex += offset;
2329
+ element.endIndex += offset;
2330
+ }
2331
+ }
2332
+ static sliceSection(elements, startIndex, endIndex) {
2333
+ return elements.filter(x => x.startIndex >= startIndex && x.endIndex <= endIndex);
2334
+ }
2335
+ }
2336
+
2337
+ class RestoreModel {
2338
+ constructor(fields) {
2339
+ if (fields) {
2340
+ Object.assign(this, fields);
2341
+ }
2342
+ }
2343
+ }
2344
+
2345
+ class ContentsModel {
2346
+ constructor(fields) {
2347
+ if (fields) {
2348
+ Object.assign(this, fields);
2349
+ }
2350
+ }
2351
+ }
2352
+
2353
+ class TableModel {
2354
+ constructor(fields) {
2355
+ if (fields) {
2356
+ if (fields.margins) {
2357
+ fields.margins = new MarginsModel(fields.margins);
2358
+ }
2359
+ Object.assign(this, fields);
2360
+ }
2361
+ }
2362
+ }
2363
+
2364
+ class TabModel {
2365
+ constructor(fields) {
2366
+ if (fields) {
2367
+ Object.assign(this, fields);
2368
+ }
2369
+ }
2370
+ }
2371
+
2372
+ class ContentsOperationsHelper {
2373
+ static GetRestoreFromSlice(contents, startIndex, count) {
2374
+ const text = ContentOperationsHelper.sliceContent(contents.content, startIndex, count);
2375
+ const endIndex = startIndex + count - 1;
2376
+ const formats = FormatHelper.sliceSection(contents.formats, startIndex, endIndex);
2377
+ const paragraphs = IndexedElementHelper.sliceSection(contents.paragraphs, startIndex, endIndex).map(x => new ParagraphModel(x));
2378
+ const images = IndexedElementHelper.sliceSection(contents.images, startIndex, endIndex).map(x => new ImageModel(x));
2379
+ const tables = IndexedElementHelper.sliceSection(contents.tables, startIndex, endIndex).map(x => new TableModel(x));
2380
+ const elements = IndexedElementHelper.sliceSection(contents.elements, startIndex, endIndex).map(x => new ElementModel(x));
2381
+ const comments = RangeElementHelper.sliceSection(contents.comments, startIndex, endIndex);
2382
+ const breaks = IndexedElementHelper.sliceSection(contents.breaks, startIndex, endIndex).map(x => new BreakModel(x));
2383
+ const tabs = IndexedElementHelper.sliceSection(contents.tabs, startIndex, endIndex).map(x => new TabModel(x));
2384
+ const links = LinkHelper.sliceSection(contents.links, startIndex, endIndex).map(x => new LinkModel(x));
2385
+ const pageFormats = PageFormatHelper.sliceSection(contents, startIndex, endIndex).map(x => new PageFormatModel(x));
2386
+ return new RestoreModel({
2387
+ insertIndex: startIndex,
2388
+ text,
2389
+ formats,
2390
+ paragraphs,
2391
+ images,
2392
+ tables,
2393
+ elements,
2394
+ breaks,
2395
+ tabs,
2396
+ links,
2397
+ pageFormats,
2398
+ comments
2399
+ });
2400
+ }
2401
+ static GetRelativeContentSlice(contents, startIndex, count) {
2402
+ const content = ContentOperationsHelper.sliceContent(contents.content, startIndex, count);
2403
+ const endIndex = startIndex + count - 1;
2404
+ const formats = FormatHelper.sliceSection(contents.formats, startIndex, endIndex).map(x => new FormatModel(x));
2405
+ const paragraphs = IndexedElementHelper.sliceSection(contents.paragraphs, startIndex, endIndex).map(x => new ParagraphModel(x));
2406
+ const images = IndexedElementHelper.sliceSection(contents.images, startIndex, endIndex).map(x => new ImageModel(x));
2407
+ const tables = IndexedElementHelper.sliceSection(contents.tables, startIndex, endIndex).map(x => new TableModel(x));
2408
+ const elements = IndexedElementHelper.sliceSection(contents.elements, startIndex, endIndex).map(x => new ElementModel(x));
2409
+ const comments = RangeElementHelper.sliceSection(contents.comments, startIndex, endIndex).map(x => new CommentModel(x));
2410
+ const breaks = IndexedElementHelper.sliceSection(contents.breaks, startIndex, endIndex).map(x => new BreakModel(x));
2411
+ const tabs = IndexedElementHelper.sliceSection(contents.tabs, startIndex, endIndex).map(x => new TabModel(x));
2412
+ const links = LinkHelper.sliceSection(contents.links, startIndex, endIndex).map(x => new LinkModel(x));
2413
+ FormatHelper.shiftIndexes(formats, -startIndex);
2414
+ IndexedElementHelper.shiftIndexes(paragraphs, -startIndex);
2415
+ IndexedElementHelper.shiftIndexes(images, -startIndex);
2416
+ IndexedElementHelper.shiftIndexes(tables, -startIndex);
2417
+ IndexedElementHelper.shiftIndexes(elements, -startIndex);
2418
+ IndexedElementHelper.shiftIndexes(breaks, -startIndex);
2419
+ IndexedElementHelper.shiftIndexes(tabs, -startIndex);
2420
+ RangeElementHelper.shiftIndexes(comments, -startIndex);
2421
+ LinkHelper.shiftIndexes(links, -startIndex);
2422
+ return new ContentsModel({
2423
+ content,
2424
+ formats,
2425
+ paragraphs,
2426
+ images,
2427
+ tables,
2428
+ elements,
2429
+ breaks,
2430
+ tabs,
2431
+ links,
2432
+ comments
2433
+ });
2434
+ }
2435
+ }
2436
+
2437
+ const CONTEXT_MENU_HEIGHT = 210;
2438
+ const CONTEXT_MENU_WIDTH = 320;
2439
+ class ContextMenuComponent {
2440
+ constructor(editorService, overlayService) {
2441
+ this.editorService = editorService;
2442
+ this.overlayService = overlayService;
2443
+ }
2444
+ ngOnDestroy() {
2445
+ this.overlayService.close();
2446
+ }
2447
+ onCopy() {
2448
+ this.editorService.copySelected();
2449
+ this.overlayService.close();
2450
+ }
2451
+ onPaste() {
2452
+ this.editorService.pasteFromClipboard();
2453
+ this.overlayService.close();
2454
+ }
2455
+ onCut() {
2456
+ this.editorService.cutSelected();
2457
+ this.overlayService.close();
2458
+ }
2459
+ onStartNewList() {
2460
+ this.editorService.startNewList();
2461
+ this.overlayService.close();
2462
+ }
2463
+ onContinueNumbering() {
2464
+ this.editorService.continueNumbering();
2465
+ this.overlayService.close();
2466
+ }
2467
+ onSetNumberingValue() {
2468
+ this.overlayService.close(AfterCloseOverlayActions.OpenSetNumberingValue);
2469
+ }
2470
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: ContextMenuComponent, deps: [{ token: EditorService }, { token: OverlayService }], target: i0.ɵɵFactoryTarget.Component }); }
2471
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.5", type: ContextMenuComponent, isStandalone: true, selector: "app-nod-context-menu", inputs: { hasNumbering: "hasNumbering", hasSelection: "hasSelection", disableContinueNumber: "disableContinueNumber" }, host: { properties: { "style.height.px": "210", "style.width.px": "320" } }, ngImport: i0, template: "<button\n mat-button\n (click)=\"onCopy()\"\n [disabled]=\"!hasSelection\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-copy\" />\n {{ 'NODER.LABEL.COPY' | translate }}\n</button>\n<button\n mat-button\n (click)=\"onPaste()\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-paste\" />\n {{ 'NODER.LABEL.PASTE' | translate }}\n</button>\n<button\n mat-button\n (click)=\"onCut()\"\n [disabled]=\"!hasSelection\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-cut\" />\n {{ 'NODER.LABEL.CUT' | translate }}\n</button>\n<div class=\"separator\"></div>\n<button\n mat-button\n (click)=\"onStartNewList()\"\n [disabled]=\"!hasNumbering\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-restart-numbering\" />\n {{ 'NODER.LABEL.START_NEW_LIST' | translate }}\n</button>\n<button\n mat-button\n (click)=\"onContinueNumbering()\"\n [disabled]=\"!hasNumbering || disableContinueNumber\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-continue-numbering\" />\n {{ 'NODER.LABEL.CONTINUE_NUMBERING' | translate }}\n</button>\n<button\n mat-button\n (click)=\"onSetNumberingValue()\"\n [disabled]=\"!hasNumbering\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-starting-value\" />\n {{ 'NODER.LABEL.SET_NUMBERING_VALUE' | translate }}\n</button>\n", styles: [":host{display:flex;padding:8px 16px;flex-direction:column;align-items:flex-start;gap:4px;border-radius:8px;box-shadow:2px 2px 8px #21212129}.separator{width:288px;height:1px}button{width:100%;justify-content:start;min-height:28px;height:28px}\n"], dependencies: [{ kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i4.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i6.TranslatePipe, name: "translate" }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2472
+ }
2473
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: ContextMenuComponent, decorators: [{
2474
+ type: Component,
2475
+ args: [{ selector: 'app-nod-context-menu', changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatButtonModule, TranslateModule, MatIconModule], host: {
2476
+ '[style.height.px]': `${CONTEXT_MENU_HEIGHT}`,
2477
+ '[style.width.px]': `${CONTEXT_MENU_WIDTH}`
2478
+ }, template: "<button\n mat-button\n (click)=\"onCopy()\"\n [disabled]=\"!hasSelection\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-copy\" />\n {{ 'NODER.LABEL.COPY' | translate }}\n</button>\n<button\n mat-button\n (click)=\"onPaste()\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-paste\" />\n {{ 'NODER.LABEL.PASTE' | translate }}\n</button>\n<button\n mat-button\n (click)=\"onCut()\"\n [disabled]=\"!hasSelection\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-cut\" />\n {{ 'NODER.LABEL.CUT' | translate }}\n</button>\n<div class=\"separator\"></div>\n<button\n mat-button\n (click)=\"onStartNewList()\"\n [disabled]=\"!hasNumbering\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-restart-numbering\" />\n {{ 'NODER.LABEL.START_NEW_LIST' | translate }}\n</button>\n<button\n mat-button\n (click)=\"onContinueNumbering()\"\n [disabled]=\"!hasNumbering || disableContinueNumber\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-continue-numbering\" />\n {{ 'NODER.LABEL.CONTINUE_NUMBERING' | translate }}\n</button>\n<button\n mat-button\n (click)=\"onSetNumberingValue()\"\n [disabled]=\"!hasNumbering\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-starting-value\" />\n {{ 'NODER.LABEL.SET_NUMBERING_VALUE' | translate }}\n</button>\n", styles: [":host{display:flex;padding:8px 16px;flex-direction:column;align-items:flex-start;gap:4px;border-radius:8px;box-shadow:2px 2px 8px #21212129}.separator{width:288px;height:1px}button{width:100%;justify-content:start;min-height:28px;height:28px}\n"] }]
2479
+ }], ctorParameters: () => [{ type: EditorService }, { type: OverlayService }], propDecorators: { hasNumbering: [{
2480
+ type: Input
2481
+ }], hasSelection: [{
2482
+ type: Input
2483
+ }], disableContinueNumber: [{
2484
+ type: Input
2485
+ }] } });
2486
+
2487
+ class CreateEdgesModel {
2488
+ constructor(fields) {
2489
+ if (fields) {
2490
+ Object.assign(this, fields);
2491
+ }
2492
+ }
2493
+ }
2494
+
2495
+ const PARENT_TAG = 'APP-NOD-EDITOR';
2496
+ const TABLE_CELL_TAG = 'APP-NOD-TABLE-CELL';
2497
+ const EDGE_TAG = 'APP-NOD-EDGE';
2498
+ const IMAGE_TAG = 'APP-NOD-IMAGE';
2499
+ const CUSTOM_TAG = 'app-nod-custom-element';
2500
+
2501
+ class CustomElementSearchResult {
2502
+ constructor(init) {
2503
+ Object.assign(this, init);
2504
+ }
2505
+ }
2506
+
2507
+ class DeleteModel {
2508
+ constructor(fields) {
2509
+ if (fields) {
2510
+ Object.assign(this, fields);
2511
+ }
2512
+ }
2513
+ }
2514
+
2515
+ class BaseHandler {
2516
+ constructor() {
2517
+ this.actions = {};
2518
+ }
2519
+ getKeyCombination(event) {
2520
+ let result = event.metaKey ? 'Command-' : '';
2521
+ if (event.ctrlKey) {
2522
+ result = `${result}Ctrl-`;
2523
+ }
2524
+ if (event.altKey) {
2525
+ result = `${result}Alt-`;
2526
+ }
2527
+ if (event.shiftKey) {
2528
+ result = `${result}Shift-`;
2529
+ }
2530
+ return `${result}${event.code}`;
2531
+ }
2532
+ }
2533
+
2534
+ class DocumentHandler extends BaseHandler {
2535
+ constructor(editor) {
2536
+ super();
2537
+ this.documentKeyDown$ = fromEvent(document, 'keydown').subscribe((event) => this.onKeyDown(event));
2538
+ this.contextMenu$ = fromEvent(document, 'contextmenu').subscribe(event => event.preventDefault());
2539
+ this.fillActions(editor);
2540
+ }
2541
+ destroy() {
2542
+ this.documentKeyDown$?.unsubscribe();
2543
+ this.contextMenu$.unsubscribe();
2544
+ }
2545
+ onKeyDown(event) {
2546
+ const keyCombination = this.getKeyCombination(event);
2547
+ if (this.actions[keyCombination]) {
2548
+ this.actions[keyCombination](event);
2549
+ }
2550
+ else {
2551
+ return;
2552
+ }
2553
+ event.preventDefault();
2554
+ }
2555
+ fillActions(editor) {
2556
+ this.actions['Ctrl-KeyP'] = () => editor.onPrint();
2557
+ this.actions['Ctrl-KeyO'] = (event) => editor.onHotKeyDown(event);
2558
+ }
2559
+ }
2560
+
2561
+ class DragAndDrop {
2562
+ constructor(editorContainer) {
2563
+ this.editorContainer = editorContainer;
2564
+ this.onMove$ = new Subject();
2565
+ this.onDrop$ = new Subject();
2566
+ }
2567
+ onStart(session, range) {
2568
+ if (this.isDragging) {
2569
+ return;
2570
+ }
2571
+ this.isDragging = true;
2572
+ this.editorContainer.classList.add('drag-and-drop-progress');
2573
+ this.sourceSession = session;
2574
+ this.sourceRange = range;
2575
+ this.initListeners();
2576
+ }
2577
+ destroyListeners() {
2578
+ this.mouseMove$?.unsubscribe();
2579
+ this.mouseUp$?.unsubscribe();
2580
+ }
2581
+ onEnd() {
2582
+ this.destroyListeners();
2583
+ if (!this.isDragging) {
2584
+ return;
2585
+ }
2586
+ this.isDragging = false;
2587
+ this.editorContainer.classList.remove('drag-and-drop-progress');
2588
+ this.onDrop$.next({ sourceSession: this.sourceSession, sourceRange: this.sourceRange });
2589
+ }
2590
+ initListeners() {
2591
+ this.destroyListeners();
2592
+ this.mouseMove$ = fromEvent(document, 'mousemove')
2593
+ .pipe(throttleTime(20))
2594
+ .subscribe(event => this.onMove$.next(event));
2595
+ this.mouseUp$ = fromEvent(document, 'mouseup')
2596
+ .pipe(take(1))
2597
+ .subscribe(() => this.onEnd());
2598
+ }
2599
+ }
2600
+
2601
+ var EdgeType;
2602
+ (function (EdgeType) {
2603
+ EdgeType[EdgeType["Header"] = 0] = "Header";
2604
+ EdgeType[EdgeType["Footer"] = 1] = "Footer";
2605
+ })(EdgeType || (EdgeType = {}));
2606
+
2607
+ class GrammarPopupComponent {
2608
+ constructor(editorService, overlayService) {
2609
+ this.editorService = editorService;
2610
+ this.overlayService = overlayService;
2611
+ }
2612
+ onSuggestionClick(index) {
2613
+ this.editorService.applyGrammarSuggestion(this.error, index, this.paragraphIndex);
2614
+ this.overlayService.close();
2615
+ }
2616
+ onIgnoreClick() {
2617
+ this.editorService.ignoreGrammarSuggestion(this.error);
2618
+ this.overlayService.close();
2206
2619
  }
2620
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: GrammarPopupComponent, deps: [{ token: EditorService }, { token: OverlayService }], target: i0.ɵɵFactoryTarget.Component }); }
2621
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.5", type: GrammarPopupComponent, isStandalone: true, selector: "app-nod-grammar-popup", inputs: { error: "error", paragraphIndex: "paragraphIndex" }, ngImport: i0, template: "<span class=\"message\">{{ error.message }}</span>\n<div class=\"options\">\n @for (suggestion of error.replacements; track i; let i = $index) {\n <span\n class=\"suggestion\"\n (click)=\"onSuggestionClick(i)\">\n {{ suggestion }}\n </span>\n }\n</div>\n<button\n mat-button\n class=\"ignore\"\n (click)=\"onIgnoreClick()\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-ignore\"></mat-icon>\n <span>\n {{ 'NODER.LABEL.IGNORE' | translate }}\n </span>\n</button>\n", styles: [":host{border-radius:8px;display:flex;flex-direction:column;padding:8px;max-width:500px;gap:5px}.message{flex:1;display:flex;align-items:center;justify-content:center;text-align:center;font-size:12px}.options{display:flex;flex-flow:column wrap;justify-content:center;gap:5px;padding:10px 0;border-bottom-width:1px;border-bottom-style:solid}.suggestion{font-weight:600;font-size:14px;cursor:pointer;text-decoration:underline;padding:3px 8px}.ignore{margin-left:auto;font-size:12px;letter-spacing:0;cursor:pointer;height:32px}.ignore mat-icon{margin-right:4px}\n"], dependencies: [{ kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i4.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "pipe", type: i6.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2207
2622
  }
2623
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: GrammarPopupComponent, decorators: [{
2624
+ type: Component,
2625
+ args: [{ selector: 'app-nod-grammar-popup', changeDetection: ChangeDetectionStrategy.OnPush, imports: [MatButtonModule, MatIconModule, TranslateModule], standalone: true, template: "<span class=\"message\">{{ error.message }}</span>\n<div class=\"options\">\n @for (suggestion of error.replacements; track i; let i = $index) {\n <span\n class=\"suggestion\"\n (click)=\"onSuggestionClick(i)\">\n {{ suggestion }}\n </span>\n }\n</div>\n<button\n mat-button\n class=\"ignore\"\n (click)=\"onIgnoreClick()\">\n <mat-icon\n fontSet=\"noder-icon\"\n fontIcon=\"icon-ignore\"></mat-icon>\n <span>\n {{ 'NODER.LABEL.IGNORE' | translate }}\n </span>\n</button>\n", styles: [":host{border-radius:8px;display:flex;flex-direction:column;padding:8px;max-width:500px;gap:5px}.message{flex:1;display:flex;align-items:center;justify-content:center;text-align:center;font-size:12px}.options{display:flex;flex-flow:column wrap;justify-content:center;gap:5px;padding:10px 0;border-bottom-width:1px;border-bottom-style:solid}.suggestion{font-weight:600;font-size:14px;cursor:pointer;text-decoration:underline;padding:3px 8px}.ignore{margin-left:auto;font-size:12px;letter-spacing:0;cursor:pointer;height:32px}.ignore mat-icon{margin-right:4px}\n"] }]
2626
+ }], ctorParameters: () => [{ type: EditorService }, { type: OverlayService }], propDecorators: { error: [{
2627
+ type: Input
2628
+ }], paragraphIndex: [{
2629
+ type: Input
2630
+ }] } });
2208
2631
 
2209
- class IndexedElementHelper {
2210
- static sliceSection(elements, startIndex, endIndex) {
2211
- return elements.filter(x => x.insertIndex >= startIndex && x.insertIndex <= endIndex);
2632
+ class ImageDataModel {
2633
+ constructor(fields) {
2634
+ if (fields) {
2635
+ Object.assign(this, fields);
2636
+ }
2212
2637
  }
2213
- static shiftIndexes(elements, offset) {
2214
- for (const element of elements) {
2215
- element.insertIndex += offset;
2638
+ }
2639
+
2640
+ class ImageHelper {
2641
+ static getImageWithAllowedSize(imageData, maxWidth) {
2642
+ if (imageData.width <= maxWidth) {
2643
+ return imageData;
2216
2644
  }
2645
+ const aspectRatio = imageData.width / imageData.height;
2646
+ const height = maxWidth / aspectRatio;
2647
+ return new ImageDataModel({ width: Math.round(maxWidth), height: Math.round(height), content: imageData.content });
2217
2648
  }
2218
2649
  }
2219
2650
 
@@ -2373,6 +2804,17 @@ class InsertBreakModel {
2373
2804
  }
2374
2805
  }
2375
2806
 
2807
+ class InsertContentsModel {
2808
+ constructor(fields) {
2809
+ if (fields) {
2810
+ if (fields.contents) {
2811
+ fields.contents = new ContentsModel(fields.contents);
2812
+ }
2813
+ Object.assign(this, fields);
2814
+ }
2815
+ }
2816
+ }
2817
+
2376
2818
  class InsertElementModel {
2377
2819
  constructor(fields) {
2378
2820
  if (fields) {
@@ -2476,56 +2918,6 @@ class InsertTextModel {
2476
2918
  }
2477
2919
  }
2478
2920
 
2479
- class LinkModel {
2480
- constructor(fields) {
2481
- if (fields) {
2482
- Object.assign(this, fields);
2483
- }
2484
- }
2485
- }
2486
-
2487
- class LinkHelper {
2488
- static sliceSection(links, start, end) {
2489
- return links.map(link => LinkHelper.getPartialLink(link, start, end)).filter(x => x !== null);
2490
- }
2491
- static shiftIndexes(links, offset) {
2492
- for (const link of links) {
2493
- link.startIndex += offset;
2494
- link.endIndex += offset;
2495
- }
2496
- }
2497
- static sliceFormats(links, startIndex, endIndex) {
2498
- const result = [];
2499
- for (const link of links) {
2500
- const absoluteFormats = link.formats.map(x => new FormatModel({ ...x, startIndex: x.startIndex + link.startIndex, endIndex: x.endIndex + link.startIndex }));
2501
- const slicedLinkFormats = FormatHelper.sliceSection(absoluteFormats, startIndex, endIndex);
2502
- result.push(...slicedLinkFormats);
2503
- }
2504
- return result;
2505
- }
2506
- static getPartialLink(link, selectionStart, selectionEnd) {
2507
- if (link.endIndex < selectionStart || link.startIndex > selectionEnd) {
2508
- return null;
2509
- }
2510
- const newStart = Math.max(link.startIndex, selectionStart);
2511
- const newEnd = Math.min(link.endIndex, selectionEnd);
2512
- const formats = link.formats
2513
- .map(format => {
2514
- const formatStart = link.startIndex + format.startIndex;
2515
- const formatEnd = link.startIndex + format.endIndex;
2516
- if (formatEnd < newStart || formatStart > newEnd) {
2517
- return null;
2518
- }
2519
- const newFormatStart = Math.max(formatStart, newStart) - newStart;
2520
- const newFormatEnd = Math.min(formatEnd, newEnd) - newStart;
2521
- const textStyle = new TextStyleModel(format.textStyle);
2522
- return new FormatModel({ startIndex: newFormatStart, endIndex: newFormatEnd, textStyle });
2523
- })
2524
- .filter(x => x !== null);
2525
- return new LinkModel({ ...link, startIndex: newStart, endIndex: newEnd, formats });
2526
- }
2527
- }
2528
-
2529
2921
  var MouseButton;
2530
2922
  (function (MouseButton) {
2531
2923
  MouseButton[MouseButton["Left"] = 0] = "Left";
@@ -2658,14 +3050,6 @@ class RemoveTableRowsModel {
2658
3050
  }
2659
3051
  }
2660
3052
 
2661
- class RestoreModel {
2662
- constructor(fields) {
2663
- if (fields) {
2664
- Object.assign(this, fields);
2665
- }
2666
- }
2667
- }
2668
-
2669
3053
  class ReplaceByRestoreModel {
2670
3054
  constructor(fields) {
2671
3055
  if (fields) {
@@ -2875,6 +3259,12 @@ class OperationHistory {
2875
3259
  pushMoveRange(restore, replace, selection) {
2876
3260
  this.addToHistory(restore, replace, selection, []);
2877
3261
  }
3262
+ pushInsertContents(undo, redo) {
3263
+ this.addToHistory(undo, redo);
3264
+ }
3265
+ pushReplaceByContents(undo, redo) {
3266
+ this.addToHistory(undo, redo);
3267
+ }
2878
3268
  pushReplace(restore, replace) {
2879
3269
  let count = replace.insertText ? replace.insertText.text.length : 1;
2880
3270
  if (replace.insertTable?.insertParagraphBefore) {
@@ -2932,214 +3322,84 @@ class OperationHistory {
2932
3322
  targets ??= this.regulatorService.getCurrentSessionTargets();
2933
3323
  const cursor = selection?.start ?? this.regulatorService.selection.cursor;
2934
3324
  const anchor = selection?.end ?? this.regulatorService.selection.anchor;
2935
- this.step++;
2936
- this.storage.splice(this.step, this.storage.length);
2937
- this.storage.push({ undo: undoStep, redo: redoStep, targets, cursor, anchor });
2938
- if (this.storage.length > this.MAX_HISTORY) {
2939
- this.storage.splice(0, 1);
2940
- this.step--;
2941
- }
2942
- this.editorService.historyInfo = new OperationsHistoryInfoModel(this.step, this.storage.length - 1);
2943
- }
2944
- }
2945
-
2946
- class BreakModel {
2947
- constructor(fields) {
2948
- if (fields) {
2949
- Object.assign(this, fields);
2950
- }
2951
- }
2952
- }
2953
-
2954
- class IndexedElementOperationsHelper {
2955
- static removeContent(elements, startIndex, endIndex) {
2956
- const length = endIndex - startIndex + 1;
2957
- for (let i = elements.length - 1; i >= 0; i--) {
2958
- if (elements[i].insertIndex >= startIndex && elements[i].insertIndex <= endIndex) {
2959
- elements.splice(i, 1);
2960
- }
2961
- }
2962
- elements.forEach(x => {
2963
- if (x.insertIndex > endIndex) {
2964
- x.insertIndex -= length;
2965
- }
2966
- });
2967
- }
2968
- static insert(elements, element, length = 1) {
2969
- this.insertContent(elements, element.insertIndex, length);
2970
- const index = elements.findIndex(x => x.insertIndex > element.insertIndex);
2971
- if (index < 0) {
2972
- elements.push(element);
2973
- }
2974
- else {
2975
- elements.splice(index, 0, element);
2976
- }
2977
- }
2978
- static insertContent(elements, index, length) {
2979
- elements.forEach(x => {
2980
- if (x.insertIndex >= index) {
2981
- x.insertIndex += length;
2982
- }
2983
- });
2984
- }
2985
- static restore(elements, index, contentLength, newElements) {
2986
- this.insertContent(elements, index, contentLength);
2987
- let indexInElements = elements.findIndex(x => x.insertIndex >= index);
2988
- indexInElements = indexInElements === -1 ? elements.length : indexInElements;
2989
- elements.splice(indexInElements, 0, ...newElements);
2990
- }
2991
- static replaceContent(elements, startIndex, endIndex, length) {
2992
- this.removeContent(elements, startIndex, endIndex);
2993
- this.insertContent(elements, startIndex, length);
2994
- }
2995
- }
2996
-
2997
- class BreakOperationsHelper {
2998
- static insertContent(elements, index, breakType, length) {
2999
- const element = new BreakModel({ insertIndex: index, breakType });
3000
- IndexedElementOperationsHelper.insert(elements, element, length);
3001
- }
3002
- }
3003
-
3004
- class CellModel {
3005
- constructor(fields) {
3006
- if (fields) {
3007
- if (fields.margins) {
3008
- fields.margins = new MarginsModel(fields.margins);
3009
- }
3010
- Object.assign(this, fields);
3011
- }
3012
- }
3013
- }
3014
-
3015
- class ContentOperationsHelper {
3016
- static removeContent(content, startIndex, count) {
3017
- return `${content.slice(0, startIndex)}${content.slice(startIndex + count, content.length)}`;
3018
- }
3019
- static sliceContent(content, startIndex, count) {
3020
- return content.slice(startIndex, startIndex + count);
3021
- }
3022
- static insertContent(content, text, index) {
3023
- const before = content.slice(0, index);
3024
- const after = content.slice(index, content.length);
3025
- return `${before}${text}${after}`;
3026
- }
3027
- static replaceContent(content, startIndex, endIndex, text) {
3028
- const reduced = this.removeContent(content, startIndex, endIndex - startIndex + 1);
3029
- return this.insertContent(reduced, text, startIndex);
3030
- }
3031
- }
3032
-
3033
- class BordersStyleModel {
3034
- constructor(fields) {
3035
- if (fields) {
3036
- Object.assign(this, fields);
3037
- }
3038
- }
3039
- }
3040
-
3041
- class ImageModel {
3042
- constructor(fields) {
3043
- if (fields) {
3044
- if (fields.border) {
3045
- fields.border = new BordersStyleModel(fields.border);
3046
- }
3047
- Object.assign(this, fields);
3048
- }
3049
- }
3050
- }
3051
-
3052
- class PageFormatHelper {
3053
- static sliceSection(content, start, end) {
3054
- if (content instanceof DocxModel) {
3055
- return content.pageFormats.filter(x => x.insertIndex !== 0 && x.insertIndex >= start && x.insertIndex <= end);
3056
- }
3057
- return [];
3058
- }
3059
- static shiftIndexes(pagesFormats, offset) {
3060
- for (const pageFormat of pagesFormats) {
3061
- if (pageFormat.insertIndex === 0) {
3062
- return;
3063
- }
3064
- pageFormat.insertIndex += offset;
3065
- }
3066
- }
3067
- }
3068
-
3069
- class ParagraphModel {
3070
- constructor(fields) {
3071
- if (fields) {
3072
- if (fields.paragraphStyle) {
3073
- fields.paragraphStyle = new ParagraphStyleModel(fields.paragraphStyle);
3074
- }
3075
- Object.assign(this, fields);
3325
+ this.step++;
3326
+ this.storage.splice(this.step, this.storage.length);
3327
+ this.storage.push({ undo: undoStep, redo: redoStep, targets, cursor, anchor });
3328
+ if (this.storage.length > this.MAX_HISTORY) {
3329
+ this.storage.splice(0, 1);
3330
+ this.step--;
3076
3331
  }
3332
+ this.editorService.historyInfo = new OperationsHistoryInfoModel(this.step, this.storage.length - 1);
3077
3333
  }
3078
3334
  }
3079
3335
 
3080
- class RangeElementHelper {
3336
+ class IndexedElementOperationsHelper {
3081
3337
  static removeContent(elements, startIndex, endIndex) {
3082
3338
  const length = endIndex - startIndex + 1;
3083
3339
  for (let i = elements.length - 1; i >= 0; i--) {
3084
- const element = elements[i];
3085
- if (element.endIndex < startIndex) {
3086
- continue;
3087
- }
3088
- if (element.startIndex < startIndex) {
3089
- if (element.endIndex > endIndex) {
3090
- element.endIndex -= length;
3091
- }
3092
- else {
3093
- element.endIndex = startIndex - 1;
3094
- }
3095
- continue;
3340
+ if (elements[i].insertIndex >= startIndex && elements[i].insertIndex <= endIndex) {
3341
+ elements.splice(i, 1);
3096
3342
  }
3097
- if (element.startIndex >= startIndex && element.startIndex <= endIndex) {
3098
- if (element.endIndex <= endIndex) {
3099
- elements.splice(i, 1);
3100
- continue;
3101
- }
3102
- element.startIndex -= element.startIndex - startIndex;
3103
- element.endIndex -= endIndex - element.startIndex;
3104
- continue;
3343
+ }
3344
+ elements.forEach(x => {
3345
+ if (x.insertIndex > endIndex) {
3346
+ x.insertIndex -= length;
3105
3347
  }
3106
- element.startIndex -= length;
3107
- element.endIndex -= length;
3348
+ });
3349
+ }
3350
+ static insert(elements, element, length = 1) {
3351
+ this.insertContent(elements, element.insertIndex, length);
3352
+ const index = elements.findIndex(x => x.insertIndex > element.insertIndex);
3353
+ if (index < 0) {
3354
+ elements.push(element);
3355
+ }
3356
+ else {
3357
+ elements.splice(index, 0, element);
3108
3358
  }
3109
3359
  }
3110
3360
  static insertContent(elements, index, length) {
3111
- for (const element of elements) {
3112
- if (element.startIndex >= index) {
3113
- element.startIndex += length;
3114
- element.endIndex += length;
3115
- }
3116
- else if (element.endIndex > index) {
3117
- element.endIndex += length;
3361
+ elements.forEach(x => {
3362
+ if (x.insertIndex >= index) {
3363
+ x.insertIndex += length;
3118
3364
  }
3365
+ });
3366
+ }
3367
+ static insertRelative(elements, insertIndex, insertLength, insertElements) {
3368
+ this.insertContent(elements, insertIndex, insertLength);
3369
+ if (insertElements.length === 0) {
3370
+ return;
3371
+ }
3372
+ for (const element of insertElements) {
3373
+ element.insertIndex += insertIndex;
3374
+ }
3375
+ const targetIndex = elements.findIndex(x => x.insertIndex > insertIndex);
3376
+ if (targetIndex < 0) {
3377
+ elements.push(...insertElements);
3378
+ }
3379
+ else {
3380
+ elements.splice(targetIndex, 0, ...insertElements);
3119
3381
  }
3120
3382
  }
3121
3383
  static restore(elements, index, contentLength, newElements) {
3122
- RangeElementHelper.insertContent(elements, index, contentLength);
3123
- const nextElement = elements.find(x => x.startIndex >= index);
3124
- const indexInElements = nextElement !== undefined ? elements.indexOf(nextElement) : elements.length;
3384
+ this.insertContent(elements, index, contentLength);
3385
+ let indexInElements = elements.findIndex(x => x.insertIndex >= index);
3386
+ indexInElements = indexInElements === -1 ? elements.length : indexInElements;
3125
3387
  elements.splice(indexInElements, 0, ...newElements);
3126
3388
  }
3127
3389
  static replaceContent(elements, startIndex, endIndex, length) {
3128
- RangeElementHelper.removeContent(elements, startIndex, endIndex);
3129
- RangeElementHelper.insertContent(elements, startIndex, length);
3130
- }
3131
- static shiftIndexes(elements, offset) {
3132
- for (const element of elements) {
3133
- element.startIndex += offset;
3134
- element.endIndex += offset;
3135
- }
3390
+ this.removeContent(elements, startIndex, endIndex);
3391
+ this.insertContent(elements, startIndex, length);
3136
3392
  }
3137
- static sliceSection(elements, startIndex, endIndex) {
3138
- return elements.filter(x => x.startIndex >= startIndex && x.endIndex <= endIndex);
3393
+ }
3394
+
3395
+ class BreakOperationsHelper {
3396
+ static insertContent(elements, index, breakType, length) {
3397
+ const element = new BreakModel({ insertIndex: index, breakType });
3398
+ IndexedElementOperationsHelper.insert(elements, element, length);
3139
3399
  }
3140
3400
  }
3141
3401
 
3142
- class TableModel {
3402
+ class CellModel {
3143
3403
  constructor(fields) {
3144
3404
  if (fields) {
3145
3405
  if (fields.margins) {
@@ -3150,45 +3410,6 @@ class TableModel {
3150
3410
  }
3151
3411
  }
3152
3412
 
3153
- class TabModel {
3154
- constructor(fields) {
3155
- if (fields) {
3156
- Object.assign(this, fields);
3157
- }
3158
- }
3159
- }
3160
-
3161
- class ContentsOperationsHelper {
3162
- static GetRestoreFromSlice(contents, startIndex, count) {
3163
- const text = ContentOperationsHelper.sliceContent(contents.content, startIndex, count);
3164
- const endIndex = startIndex + count - 1;
3165
- const formats = FormatHelper.sliceSection(contents.formats, startIndex, endIndex);
3166
- const paragraphs = IndexedElementHelper.sliceSection(contents.paragraphs, startIndex, endIndex).map(x => new ParagraphModel(x));
3167
- const images = IndexedElementHelper.sliceSection(contents.images, startIndex, endIndex).map(x => new ImageModel(x));
3168
- const tables = IndexedElementHelper.sliceSection(contents.tables, startIndex, endIndex).map(x => new TableModel(x));
3169
- const elements = IndexedElementHelper.sliceSection(contents.elements, startIndex, endIndex).map(x => new ElementModel(x));
3170
- const comments = RangeElementHelper.sliceSection(contents.comments, startIndex, endIndex);
3171
- const breaks = IndexedElementHelper.sliceSection(contents.breaks, startIndex, endIndex).map(x => new BreakModel(x));
3172
- const tabs = IndexedElementHelper.sliceSection(contents.tabs, startIndex, endIndex).map(x => new TabModel(x));
3173
- const links = LinkHelper.sliceSection(contents.links, startIndex, endIndex).map(x => new LinkModel(x));
3174
- const pageFormats = PageFormatHelper.sliceSection(contents, startIndex, endIndex).map(x => new PageFormatModel(x));
3175
- return new RestoreModel({
3176
- insertIndex: startIndex,
3177
- text,
3178
- formats,
3179
- paragraphs,
3180
- images,
3181
- tables,
3182
- elements,
3183
- breaks,
3184
- tabs,
3185
- links,
3186
- pageFormats,
3187
- comments
3188
- });
3189
- }
3190
- }
3191
-
3192
3413
  class EdgeModel {
3193
3414
  constructor(fields) {
3194
3415
  if (fields) {
@@ -3252,6 +3473,14 @@ class FormatOperationsHelper {
3252
3473
  }
3253
3474
  });
3254
3475
  }
3476
+ static insertRelative(formats, insertIndex, insertLength, insertFormats) {
3477
+ this.insertContent(formats, insertIndex, insertLength);
3478
+ for (const format of insertFormats) {
3479
+ format.startIndex += insertIndex;
3480
+ format.endIndex += insertIndex;
3481
+ this.apply(formats, format.startIndex, format.endIndex, format.textStyle);
3482
+ }
3483
+ }
3255
3484
  static insertStyledContent(formats, index, textLength, style) {
3256
3485
  this.insertContent(formats, index, textLength);
3257
3486
  this.apply(formats, index, index + textLength - 1, style);
@@ -3354,6 +3583,24 @@ class LinkOperationsHelper {
3354
3583
  }
3355
3584
  }
3356
3585
  }
3586
+ static insertRelative(links, insertIndex, insertLength, insertLinks) {
3587
+ this.insertContent(links, insertIndex, insertLength);
3588
+ if (insertLinks.length === 0) {
3589
+ return;
3590
+ }
3591
+ for (const link of links) {
3592
+ link.startIndex += insertIndex;
3593
+ link.endIndex += insertIndex;
3594
+ }
3595
+ const targetIndex = links.findIndex(x => x.startIndex === insertIndex);
3596
+ if (targetIndex < 0) {
3597
+ links.push(...insertLinks);
3598
+ }
3599
+ else {
3600
+ links.splice(targetIndex, 0, ...insertLinks);
3601
+ }
3602
+ this.merge(links, insertIndex - 1, insertIndex + insertLength);
3603
+ }
3357
3604
  static removeContent(links, startIndex, endIndex) {
3358
3605
  const length = endIndex - startIndex + 1;
3359
3606
  for (let i = links.length - 1; i >= 0; i--) {
@@ -5778,6 +6025,17 @@ class OperationsHelper {
5778
6025
  this.removeComment(document, model.commentId);
5779
6026
  break;
5780
6027
  }
6028
+ case CommandType.InsertContents: {
6029
+ const model = command.insertContents;
6030
+ this.insertContents(contents, model.insertIndex, model.contents);
6031
+ break;
6032
+ }
6033
+ case CommandType.ReplaceByContents: {
6034
+ const model = command.replaceByContents;
6035
+ this.delete(contents, model.startIndex, model.count);
6036
+ this.insertContents(contents, model.startIndex, model.contents);
6037
+ break;
6038
+ }
5781
6039
  }
5782
6040
  });
5783
6041
  }
@@ -6033,6 +6291,22 @@ class OperationsHelper {
6033
6291
  document.comments = document.comments.filter(x => x.commentId !== commentId);
6034
6292
  return comment;
6035
6293
  }
6294
+ static insertContents(contents, insertIndex, insertContents) {
6295
+ const contentLength = insertContents.content.length;
6296
+ contents.content = ContentOperationsHelper.insertContent(contents.content, insertContents.content, insertIndex);
6297
+ IndexedElementOperationsHelper.insertRelative(contents.paragraphs, insertIndex, contentLength, insertContents.paragraphs);
6298
+ IndexedElementOperationsHelper.insertRelative(contents.images, insertIndex, contentLength, insertContents.images);
6299
+ IndexedElementOperationsHelper.insertRelative(contents.tables, insertIndex, contentLength, insertContents.tables);
6300
+ IndexedElementOperationsHelper.insertRelative(contents.elements, insertIndex, contentLength, insertContents.elements);
6301
+ IndexedElementOperationsHelper.insertRelative(contents.breaks, insertIndex, contentLength, insertContents.breaks);
6302
+ IndexedElementOperationsHelper.insertRelative(contents.tabs, insertIndex, contentLength, insertContents.tabs);
6303
+ FormatOperationsHelper.insertRelative(contents.formats, insertIndex, contentLength, insertContents.formats);
6304
+ RangeElementHelper.insertRelative(contents.comments, insertIndex, contentLength, insertContents.comments);
6305
+ LinkOperationsHelper.insertRelative(contents.links, insertIndex, contentLength, insertContents.links);
6306
+ if (contents instanceof DocxModel) {
6307
+ PageFormatOperationsHelper.insertContent(contents, insertIndex, contentLength);
6308
+ }
6309
+ }
6036
6310
  static replace(document, contents, model) {
6037
6311
  this.delete(document, model.delete.startIndex, model.delete.count);
6038
6312
  if (model.insertText) {
@@ -9162,7 +9436,7 @@ class EditSession {
9162
9436
  }
9163
9437
  removeByDocumentIndexes(startIndex, endIndex) {
9164
9438
  const startParagraphPosition = ContentHelper.documentIndexToParagraphIndex(this.displayData.paragraphs, startIndex);
9165
- const endParagraphPosition = ContentHelper.documentIndexToParagraphIndex(this.displayData.paragraphs, endIndex);
9439
+ const endParagraphPosition = ContentHelper.documentIndexToParagraphIndex(this.displayData.paragraphs, endIndex + 1);
9166
9440
  this.remove(new Range(startParagraphPosition, endParagraphPosition));
9167
9441
  }
9168
9442
  insertTextByDocumentIndex(index, text, style) {
@@ -9313,7 +9587,7 @@ class EditSession {
9313
9587
  this.applyToolbarStyles();
9314
9588
  }
9315
9589
  replace(model) {
9316
- this.removeByDocumentIndexes(model.delete.startIndex, model.delete.startIndex + model.delete.count);
9590
+ this.removeByDocumentIndexes(model.delete.startIndex, model.delete.startIndex + model.delete.count - 1);
9317
9591
  let endPoint;
9318
9592
  if (model.insertText) {
9319
9593
  endPoint = this.insertTextByDocumentIndex(model.insertText.insertIndex, model.insertText.text);
@@ -9348,7 +9622,7 @@ class EditSession {
9348
9622
  this.removeNumberings(paragraphIndex, paragraphIndex);
9349
9623
  }
9350
9624
  this.applyParagraphStyle(paragraphIndex, paragraphIndex, model.paragraphStyle);
9351
- this.removeByDocumentIndexes(model.startIndex, model.startIndex + model.count);
9625
+ this.removeByDocumentIndexes(model.startIndex, model.startIndex + model.count - 1);
9352
9626
  }
9353
9627
  restoreWithParagraph(model) {
9354
9628
  this.restore(model.restore);
@@ -9453,6 +9727,23 @@ class EditSession {
9453
9727
  OperationsHelper.applyTableCellsStyles(this.model, model);
9454
9728
  table.instance.updateTable();
9455
9729
  }
9730
+ insertContents(insertIndex, contents) {
9731
+ OperationsHelper.insertContents(this.model, insertIndex, contents);
9732
+ const endIndex = insertIndex + contents.content.length - 1;
9733
+ this.insertComponents(this.model.tables, this.customComponents.tables, NoderTableComponent, insertIndex, endIndex);
9734
+ this.insertComponents(this.model.images, this.customComponents.images, NoderImageComponent, insertIndex, endIndex);
9735
+ this.insertComponents(this.model.tabs, this.customComponents.tabs, NoderTabComponent, insertIndex, endIndex);
9736
+ this.insertElementComponents(this.model.elements, insertIndex, endIndex);
9737
+ const startPosition = ContentHelper.documentIndexToParagraphIndex(this.displayData.paragraphs, insertIndex);
9738
+ const endPosition = this.displayData.insertText(startPosition, contents.content);
9739
+ this.displayData.updateNextLineIndexes(startPosition.row, endPosition.row);
9740
+ this.selection.placeSelection(endPosition, endPosition);
9741
+ this.applyToolbarStyles();
9742
+ }
9743
+ replaceByContents(startIndex, count, contents) {
9744
+ this.removeByDocumentIndexes(startIndex, startIndex + count - 1);
9745
+ this.insertContents(startIndex, contents);
9746
+ }
9456
9747
  removeMoveRange(moveModel) {
9457
9748
  const endIndex = moveModel.sourceStartIndex + moveModel.sourceCount - 1;
9458
9749
  const startPosition = this.displayData.indexToPosition(moveModel.sourceStartIndex, 0);
@@ -9472,10 +9763,10 @@ class EditSession {
9472
9763
  restoreMoveRange(restoreModel, moveModel, _sourceSessionId) {
9473
9764
  const moveIndex = OperationsHelper.restoreMoveRange(this.model, moveModel, restoreModel);
9474
9765
  const endIndex = moveIndex + moveModel.sourceCount;
9475
- this.restoreComponents(this.model.tables, this.customComponents.tables, NoderTableComponent, moveIndex, endIndex);
9476
- this.restoreComponents(this.model.images, this.customComponents.images, NoderImageComponent, moveIndex, endIndex);
9477
- this.restoreComponents(this.model.tabs, this.customComponents.tabs, NoderTabComponent, moveIndex, endIndex);
9478
- this.restoreElementComponents(this.model.elements, moveIndex, endIndex);
9766
+ this.insertComponents(this.model.tables, this.customComponents.tables, NoderTableComponent, moveIndex, endIndex);
9767
+ this.insertComponents(this.model.images, this.customComponents.images, NoderImageComponent, moveIndex, endIndex);
9768
+ this.insertComponents(this.model.tabs, this.customComponents.tabs, NoderTabComponent, moveIndex, endIndex);
9769
+ this.insertElementComponents(this.model.elements, moveIndex, endIndex);
9479
9770
  const startPosition = ContentHelper.documentIndexToParagraphIndex(this.displayData.paragraphs, moveIndex);
9480
9771
  const endPosition = this.displayData.insertText(startPosition, restoreModel.text);
9481
9772
  this.displayData.updateNextLineIndexes(startPosition.row, endPosition.row);
@@ -9491,6 +9782,12 @@ class EditSession {
9491
9782
  const endIndex = this.displayData.positionToIndex(range.end);
9492
9783
  return positionIndex >= startIndex && positionIndex < endIndex;
9493
9784
  }
9785
+ getContentsSlice(start, end) {
9786
+ const startIndex = ContentHelper.paragraphPositionToDocumentIndex(this.displayData.paragraphs, start);
9787
+ const endIndex = ContentHelper.paragraphPositionToDocumentIndex(this.displayData.paragraphs, end) - 1;
9788
+ const count = endIndex - startIndex + 1;
9789
+ return ContentsOperationsHelper.GetRelativeContentSlice(this.model, startIndex, count);
9790
+ }
9494
9791
  createRestoreFromSlice(start, end) {
9495
9792
  const startIndex = ContentHelper.paragraphToDocumentIndex(this.displayData.paragraphs, start.row, start.column);
9496
9793
  const endIndex = ContentHelper.paragraphToDocumentIndex(this.displayData.paragraphs, end.row, end.column) - 1;
@@ -9557,7 +9854,7 @@ class EditSession {
9557
9854
  return [format.textStyle];
9558
9855
  }
9559
9856
  replaceByRestore(model) {
9560
- this.removeByDocumentIndexes(model.delete.startIndex, model.delete.startIndex + model.delete.count);
9857
+ this.removeByDocumentIndexes(model.delete.startIndex, model.delete.startIndex + model.delete.count - 1);
9561
9858
  this.restore(model.restore);
9562
9859
  }
9563
9860
  restore(model) {
@@ -9565,15 +9862,15 @@ class EditSession {
9565
9862
  OperationsHelper.restore(this.model, model);
9566
9863
  const endPoint = this.displayData.insertText(paragraphPosition, model.text);
9567
9864
  const restoreEndIndex = model.insertIndex + model.text.length;
9568
- this.restoreComponents(this.model.tables, this.customComponents.tables, NoderTableComponent, model.insertIndex, restoreEndIndex);
9569
- this.restoreComponents(this.model.images, this.customComponents.images, NoderImageComponent, model.insertIndex, restoreEndIndex);
9570
- this.restoreComponents(this.model.tabs, this.customComponents.tabs, NoderTabComponent, model.insertIndex, restoreEndIndex);
9571
- this.restoreElementComponents(this.model.elements, model.insertIndex, restoreEndIndex);
9865
+ this.insertComponents(this.model.tables, this.customComponents.tables, NoderTableComponent, model.insertIndex, restoreEndIndex);
9866
+ this.insertComponents(this.model.images, this.customComponents.images, NoderImageComponent, model.insertIndex, restoreEndIndex);
9867
+ this.insertComponents(this.model.tabs, this.customComponents.tabs, NoderTabComponent, model.insertIndex, restoreEndIndex);
9868
+ this.insertElementComponents(this.model.elements, model.insertIndex, restoreEndIndex);
9572
9869
  this.displayData.updateNextLineIndexes(paragraphPosition.row, endPoint.row);
9573
9870
  this.selection.placeCursor(endPoint);
9574
9871
  this.applyToolbarStyles();
9575
9872
  }
9576
- restoreComponents(models, components, componentType, restoreIndex, restoreEndIndex) {
9873
+ insertComponents(models, components, componentType, restoreIndex, restoreEndIndex) {
9577
9874
  for (const model of models) {
9578
9875
  if (model.insertIndex < restoreIndex) {
9579
9876
  continue;
@@ -9584,7 +9881,7 @@ class EditSession {
9584
9881
  this.addComponent(components, model, componentType);
9585
9882
  }
9586
9883
  }
9587
- restoreElementComponents(elements, restoreIndex, restoreEndIndex) {
9884
+ insertElementComponents(elements, restoreIndex, restoreEndIndex) {
9588
9885
  for (const model of elements) {
9589
9886
  if (model.insertIndex < restoreIndex) {
9590
9887
  continue;
@@ -9953,7 +10250,7 @@ class CommentHighlightLayer extends HighlightLayer {
9953
10250
  }
9954
10251
  update(config) {
9955
10252
  const comments = this.session.model.comments;
9956
- if (!config?.isVisible || !comments?.length || !this.enabled) {
10253
+ if (!comments?.length || !this.enabled) {
9957
10254
  this.element.innerHTML = '';
9958
10255
  return;
9959
10256
  }
@@ -10094,6 +10391,12 @@ class CursorLayer {
10094
10391
  }
10095
10392
  }
10096
10393
 
10394
+ class CustomElementInfo {
10395
+ constructor(init) {
10396
+ Object.assign(this, init);
10397
+ }
10398
+ }
10399
+
10097
10400
  class GrammarHighlightLayer extends HighlightLayer {
10098
10401
  constructor(parentEl, cssClass, session) {
10099
10402
  super(parentEl, cssClass, session);
@@ -10101,7 +10404,7 @@ class GrammarHighlightLayer extends HighlightLayer {
10101
10404
  this.errorsByParagraph = new Map();
10102
10405
  }
10103
10406
  update(config) {
10104
- if (!config?.isVisible || !this.errorsByParagraph.size || this.session.editorService.isViewOnly) {
10407
+ if (!this.errorsByParagraph.size || this.session.editorService.isViewOnly) {
10105
10408
  this.element.innerHTML = '';
10106
10409
  return;
10107
10410
  }
@@ -10159,8 +10462,7 @@ class RenderChangesModel {
10159
10462
  this.scroll ||
10160
10463
  this.size ||
10161
10464
  this.text ||
10162
- this.dragAndDrop ||
10163
- this.visibilityChanged);
10465
+ this.dragAndDrop);
10164
10466
  }
10165
10467
  constructor(fields) {
10166
10468
  this.cursor = false;
@@ -10176,7 +10478,6 @@ class RenderChangesModel {
10176
10478
  this.size = false;
10177
10479
  this.text = false;
10178
10480
  this.dragAndDrop = false;
10179
- this.visibilityChanged = false;
10180
10481
  if (!fields) {
10181
10482
  return;
10182
10483
  }
@@ -10189,12 +10490,6 @@ class RenderChangesModel {
10189
10490
  }
10190
10491
  }
10191
10492
 
10192
- class CustomElementInfo {
10193
- constructor(init) {
10194
- Object.assign(this, init);
10195
- }
10196
- }
10197
-
10198
10493
  class SearchHighlightLayer extends HighlightLayer {
10199
10494
  constructor(parentEl, cssClass, session) {
10200
10495
  super(parentEl, cssClass, session);
@@ -10204,9 +10499,6 @@ class SearchHighlightLayer extends HighlightLayer {
10204
10499
  this.customElementsRanges = [];
10205
10500
  }
10206
10501
  update(config) {
10207
- if (!config?.isVisible) {
10208
- return;
10209
- }
10210
10502
  this.config = config;
10211
10503
  this.selectionIndex = 0;
10212
10504
  this.getVisibleCustomElementResults(config);
@@ -10574,10 +10866,8 @@ class Renderer extends EventEmitting {
10574
10866
  endLine: 0,
10575
10867
  endScreenLine: 0,
10576
10868
  endScreenFullLine: 0
10577
- },
10578
- isVisible: false
10869
+ }
10579
10870
  };
10580
- this.isVisible = false;
10581
10871
  this.changes = new RenderChangesModel();
10582
10872
  this.paragraphsAppeared = new Subject();
10583
10873
  this.visibilitySubject = new Subject();
@@ -10619,8 +10909,7 @@ class Renderer extends EventEmitting {
10619
10909
  changes.scroll ||
10620
10910
  changes.search ||
10621
10911
  changes.grammar ||
10622
- changes.commentHighlights ||
10623
- changes.visibilityChanged) {
10912
+ changes.commentHighlights) {
10624
10913
  changes.apply(this.computeLayerConfig());
10625
10914
  DomHelper.translate(this.content, 0, -this.layerConfig.offset);
10626
10915
  DomHelper.setStyle(this.content.style, 'width', `${this.layerConfig.width}px`);
@@ -10652,12 +10941,6 @@ class Renderer extends EventEmitting {
10652
10941
  if (changes.dragAndDrop) {
10653
10942
  this.renderDragAndDropSelection();
10654
10943
  }
10655
- if (changes.visibilityChanged) {
10656
- this.renderSearchHighlights();
10657
- this.renderGrammarHighlights();
10658
- this.renderCommentHighlights();
10659
- this.visibilitySubject.next(this.isVisible);
10660
- }
10661
10944
  this.session.onRendered();
10662
10945
  }
10663
10946
  /**
@@ -10707,10 +10990,22 @@ class Renderer extends EventEmitting {
10707
10990
  }
10708
10991
  }
10709
10992
  updateCustomElementHighlights(ranges) {
10710
- this.searchHighlightLayer.customElementsRanges = ranges;
10711
- this.scheduleChanges({ search: true });
10993
+ if (this.searchHighlightLayer.customElementsRanges.length !== ranges.length ||
10994
+ !this.searchHighlightLayer.customElementsRanges.every(x => ranges.some(z => x.location.isEqual(z.location)))) {
10995
+ this.searchHighlightLayer.customElementsRanges = ranges;
10996
+ this.scheduleChanges({ search: true });
10997
+ }
10712
10998
  }
10713
10999
  updateActiveSearchHighlight(active) {
11000
+ if (this.searchHighlightLayer.active === active ||
11001
+ (this.searchHighlightLayer.active instanceof Range &&
11002
+ active instanceof Range &&
11003
+ this.searchHighlightLayer.active.isEqual(active)) ||
11004
+ (this.searchHighlightLayer.active instanceof CustomElementInfo &&
11005
+ active instanceof CustomElementInfo &&
11006
+ this.searchHighlightLayer.active.location.isEqual(active.location))) {
11007
+ return;
11008
+ }
10714
11009
  this.searchHighlightLayer.active = active;
10715
11010
  this.scheduleChanges({ search: true });
10716
11011
  }
@@ -10750,15 +11045,6 @@ class Renderer extends EventEmitting {
10750
11045
  this.dragAndDropSelectionLayer.marker = null;
10751
11046
  this.scheduleChanges({ dragAndDrop: true });
10752
11047
  }
10753
- setVisibility(isVisible) {
10754
- if (this.isVisible !== isVisible) {
10755
- this.isVisible = isVisible;
10756
- if (!isVisible) {
10757
- this.commentsLayer.clearSessionComments();
10758
- }
10759
- this.scheduleChanges({ visibilityChanged: true });
10760
- }
10761
- }
10762
11048
  /**
10763
11049
  * Triggers a full update of the text, for all the rows.
10764
11050
  **/
@@ -10857,8 +11143,7 @@ class Renderer extends EventEmitting {
10857
11143
  contentRange: new DistanceModel({ start: 0, end: displayData.paragraphs.filter(x => x.paragraphSettings).length - 1 }),
10858
11144
  maxHeight,
10859
11145
  offset: 0,
10860
- scrollTop: this.session.scrollTop,
10861
- isVisible: this.isVisible
11146
+ scrollTop: this.session.scrollTop
10862
11147
  };
10863
11148
  return changes;
10864
11149
  }
@@ -11329,14 +11614,7 @@ class VirtualRenderer {
11329
11614
  return;
11330
11615
  }
11331
11616
  // text, scrolling and resize changes can cause the view port size to change
11332
- if (changes.full ||
11333
- changes.size ||
11334
- changes.text ||
11335
- changes.lines ||
11336
- changes.scroll ||
11337
- changes.search ||
11338
- changes.grammar ||
11339
- changes.visibilityChanged) {
11617
+ if (changes.full || changes.size || changes.text || changes.lines || changes.scroll || changes.search || changes.grammar) {
11340
11618
  changes.apply(this.computeLayerConfig());
11341
11619
  DomHelper.translate(this.renderer.content, 0, -this.layerConfig.offset);
11342
11620
  DomHelper.setStyle(this.renderer.content.style, 'width', `${this.layerConfig.width}px`);
@@ -11377,9 +11655,6 @@ class VirtualRenderer {
11377
11655
  if (changes.dragAndDrop) {
11378
11656
  this.renderDragAndDropSelection();
11379
11657
  }
11380
- if (changes.visibilityChanged) {
11381
- this.renderSearchHighlights();
11382
- }
11383
11658
  }
11384
11659
  /**
11385
11660
  * Triggers a resize of the editor
@@ -11508,9 +11783,6 @@ class VirtualRenderer {
11508
11783
  updateCursor() {
11509
11784
  this.renderer.updateCursor();
11510
11785
  }
11511
- setVisibility(isVisible) {
11512
- this.renderer.setVisibility(isVisible);
11513
- }
11514
11786
  scheduleChanges(changes) {
11515
11787
  this.loop.schedule(0, changes);
11516
11788
  }
@@ -11570,6 +11842,10 @@ class VirtualRenderer {
11570
11842
  this.renderer.clearGrammarHighlights();
11571
11843
  }
11572
11844
  paragraphsScrolledIntoView() {
11845
+ if (!this.layerConfig.visibleRange) {
11846
+ this.renderer.paragraphsAppeared.next(this.renderer.session.displayData.paragraphs);
11847
+ return;
11848
+ }
11573
11849
  const paragraphs = this.renderer.session.displayData.paragraphs.slice(this.layerConfig.visibleRange.startParagraph, this.layerConfig.visibleRange.endParagraph + 1);
11574
11850
  this.renderer.paragraphsAppeared.next(paragraphs);
11575
11851
  }
@@ -11607,8 +11883,7 @@ class VirtualRenderer {
11607
11883
  offset: 0,
11608
11884
  visibleRange,
11609
11885
  scrollTop: this.scrollBar.scrollTop,
11610
- pages: visibleRange.pages,
11611
- isVisible: true
11886
+ pages: visibleRange.pages
11612
11887
  };
11613
11888
  return changes;
11614
11889
  }
@@ -11885,7 +12160,6 @@ class RegulatorService {
11885
12160
  this.selectedCommentId = null;
11886
12161
  this.renderLoop = new RenderLoop();
11887
12162
  this.grammarChecker = new GrammarChecker(this.grammarService);
11888
- this.observer = this.initializeIntersectionObserver();
11889
12163
  }
11890
12164
  addMainSession(model, scalingRatio, container) {
11891
12165
  const sessionId = ++this.sessionIdIncrement;
@@ -11939,7 +12213,6 @@ class RegulatorService {
11939
12213
  if (this.grammarEnabled) {
11940
12214
  this.grammarChecker.registerSession(newSession);
11941
12215
  }
11942
- this.observer.observe(nativeElement);
11943
12216
  return newSession;
11944
12217
  }
11945
12218
  addEdgeSession(component, nativeElement) {
@@ -11956,14 +12229,12 @@ class RegulatorService {
11956
12229
  if (this.grammarEnabled) {
11957
12230
  this.grammarChecker.registerSession(newSession);
11958
12231
  }
11959
- this.observer.observe(nativeElement);
11960
12232
  return newSession;
11961
12233
  }
11962
12234
  removeSession(sessionId) {
11963
12235
  const index = this.sessions.findIndex(x => x.sessionId === sessionId);
11964
12236
  this.sessions[index].session.destroy();
11965
12237
  this.sessions[index].renderer.destroy();
11966
- this.observer.unobserve(this.sessions[index].nativeElement);
11967
12238
  this.sessions.splice(index, 1);
11968
12239
  this.grammarChecker.unregisterSession(sessionId);
11969
12240
  }
@@ -12221,19 +12492,6 @@ class RegulatorService {
12221
12492
  })
12222
12493
  ];
12223
12494
  }
12224
- initializeIntersectionObserver() {
12225
- const options = {
12226
- root: null,
12227
- rootMargin: '50px',
12228
- threshold: 0.01
12229
- };
12230
- return new IntersectionObserver(entries => {
12231
- entries.forEach(entry => {
12232
- const sessionId = +entry.target.getAttribute('data-session-id');
12233
- this.getSessionModel(sessionId)?.renderer.setVisibility(entry.isIntersecting);
12234
- });
12235
- }, options);
12236
- }
12237
12495
  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 }); }
12238
12496
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: RegulatorService }); }
12239
12497
  }
@@ -13699,8 +13957,7 @@ class PrintRenderer {
13699
13957
  maxHeight,
13700
13958
  offset: 0,
13701
13959
  pages,
13702
- scrollTop: 0,
13703
- isVisible: true
13960
+ scrollTop: 0
13704
13961
  };
13705
13962
  }
13706
13963
  createContent() {
@@ -13794,6 +14051,17 @@ class RemoveWithParagraphModel {
13794
14051
  }
13795
14052
  }
13796
14053
 
14054
+ class ReplaceByContentsModel {
14055
+ constructor(fields) {
14056
+ if (fields) {
14057
+ if (fields.contents) {
14058
+ fields.contents = new ContentsModel(fields.contents);
14059
+ }
14060
+ Object.assign(this, fields);
14061
+ }
14062
+ }
14063
+ }
14064
+
13797
14065
  class ReplaceModel {
13798
14066
  constructor(fields) {
13799
14067
  if (fields) {
@@ -13893,6 +14161,9 @@ class CommandModel {
13893
14161
  if (fields.insertBreak) {
13894
14162
  fields.insertBreak = new InsertBreakModel(fields.insertBreak);
13895
14163
  }
14164
+ if (fields.insertContents) {
14165
+ fields.insertContents = new InsertContentsModel(fields.insertContents);
14166
+ }
13896
14167
  if (fields.insertElement) {
13897
14168
  fields.insertElement = new InsertElementModel(fields.insertElement);
13898
14169
  }
@@ -13950,6 +14221,9 @@ class CommandModel {
13950
14221
  if (fields.replace) {
13951
14222
  fields.replace = new ReplaceModel(fields.replace);
13952
14223
  }
14224
+ if (fields.replaceByContents) {
14225
+ fields.replaceByContents = new ReplaceByContentsModel(fields.replaceByContents);
14226
+ }
13953
14227
  if (fields.replaceByRestore) {
13954
14228
  fields.replaceByRestore = new ReplaceByRestoreModel(fields.replaceByRestore);
13955
14229
  }
@@ -14078,6 +14352,12 @@ class SaveCommandsHelper {
14078
14352
  static getReplaceByRestoreCommand(replaceByRestore, targets) {
14079
14353
  return new CommandModel({ commandType: CommandType.ReplaceByRestore, replaceByRestore, targets });
14080
14354
  }
14355
+ static getInsertContentsCommand(model, targets) {
14356
+ return new CommandModel({ commandType: CommandType.InsertContents, insertContents: model, targets });
14357
+ }
14358
+ static getReplaceByContentsModel(model, targets) {
14359
+ return new CommandModel({ commandType: CommandType.ReplaceByContents, replaceByContents: model, targets });
14360
+ }
14081
14361
  static getMoveRangeCommand(model, targets) {
14082
14362
  return new CommandModel({ commandType: CommandType.MoveRange, moveRange: model, targets });
14083
14363
  }
@@ -14846,10 +15126,6 @@ class TextInput {
14846
15126
  parentElement.insertBefore(this.input, parentElement.firstChild);
14847
15127
  this.isFocused = document.activeElement === this.input;
14848
15128
  }
14849
- getClipboardData(event) {
14850
- const mime = 'text/plain';
14851
- return event.clipboardData.getData(mime);
14852
- }
14853
15129
  getInsertText() {
14854
15130
  const data = this.input.value;
14855
15131
  const selectionStart = this.input.selectionStart;
@@ -14971,12 +15247,13 @@ class Editor {
14971
15247
  this.inputHandler = new InputHandler(this.textInput.input, this);
14972
15248
  this.documentHandler = new DocumentHandler(this);
14973
15249
  this.dragAndDrop = new DragAndDrop(this.container.nativeElement);
15250
+ this.clipboardHandler = new ClipboardHandler(this.clipboard);
14974
15251
  this.initResizeListener();
14975
15252
  this.focus();
14976
15253
  this.session.applyToolbarStyles();
14977
15254
  this.onSetCommentsVisibility(!!this.model.comments.length);
14978
15255
  this.search = new Search(editorService);
14979
- 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.selectSpacingSubscription(), this.selectBeforeSubscription(), this.selectAfterSubscription(), 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.toggleGrammarChecksSubscription(), 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(), this.getCommentTextSubscription(), this.replaceCommentTextSubscription(), this.startNewListSubscription(), this.continueNumberingSubscription(), this.setNumberingValueSubscription());
15256
+ this.subscriptions.push(this.changedEdgeSizeSubscription(), this.changedEdgeSubscription(), this.changedTableSizeSubscription(), 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.selectSpacingSubscription(), this.selectBeforeSubscription(), this.selectAfterSubscription(), 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.toggleGrammarChecksSubscription(), 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(), this.getCommentTextSubscription(), this.replaceCommentTextSubscription(), this.startNewListSubscription(), this.continueNumberingSubscription(), this.setNumberingValueSubscription(), this.insertContentsSubscription());
14980
15257
  }
14981
15258
  destroy() {
14982
15259
  this.subscriptions.forEach(s => s?.unsubscribe());
@@ -15036,9 +15313,6 @@ class Editor {
15036
15313
  const y = rect.top + cursor.pageY + cursor.height;
15037
15314
  this.overlayService.open(component, { textKey }, x, y);
15038
15315
  }
15039
- cut() {
15040
- this.removeSelected();
15041
- }
15042
15316
  insert(text) {
15043
15317
  const sanitizedText = text.replace(this.emojiRegex, ' ');
15044
15318
  if (this.selection.isEmpty) {
@@ -15070,6 +15344,11 @@ class Editor {
15070
15344
  this.onSelectionChange();
15071
15345
  this.onContentChange();
15072
15346
  }
15347
+ insertSlice(sliceData) {
15348
+ const slice = sliceData.data;
15349
+ const revisionId = sliceData.source.revisionId;
15350
+ this.editorService.requestContentsInsertion(slice, revisionId);
15351
+ }
15073
15352
  removeLeft() {
15074
15353
  if (this.selection.isEmpty) {
15075
15354
  this.selection.selectLeft(this.session);
@@ -15512,7 +15791,7 @@ class Editor {
15512
15791
  command = SaveCommandsHelper.getInsertTextCommand(text, insertIndex, this.targets);
15513
15792
  }
15514
15793
  else if (operation instanceof DeleteModel) {
15515
- this.session.removeByDocumentIndexes(operation.startIndex, operation.startIndex + operation.count);
15794
+ this.session.removeByDocumentIndexes(operation.startIndex, operation.startIndex + operation.count - 1);
15516
15795
  command = SaveCommandsHelper.getDeleteCommand(operation.startIndex, operation.count, this.targets);
15517
15796
  }
15518
15797
  else if (operation instanceof InsertStyledTextModel) {
@@ -15707,6 +15986,16 @@ class Editor {
15707
15986
  this.session.applyNewNumberingForParagraphs(operation.levels, operation.insertIndexes);
15708
15987
  command = SaveCommandsHelper.getApplyNewNumberingForParagraphsCommand(operation.insertIndexes, operation.levels, this.targets);
15709
15988
  }
15989
+ else if (operation instanceof InsertContentsModel) {
15990
+ const deepCopy = structuredClone(operation.contents);
15991
+ this.session.insertContents(operation.insertIndex, deepCopy);
15992
+ command = SaveCommandsHelper.getInsertContentsCommand(operation, this.targets);
15993
+ }
15994
+ else if (operation instanceof ReplaceByContentsModel) {
15995
+ const deepCopy = structuredClone(operation.contents);
15996
+ this.session.replaceByContents(operation.startIndex, operation.count, deepCopy);
15997
+ command = SaveCommandsHelper.getReplaceByContentsModel(operation, this.targets);
15998
+ }
15710
15999
  else {
15711
16000
  throw new Error('Undo/redo is not implemented for the Operation');
15712
16001
  }
@@ -15837,6 +16126,22 @@ class Editor {
15837
16126
  this.history.pushMoveRange(undoModel, redoModel, sourceRange);
15838
16127
  this.commandsService.createCommand(SaveCommandsHelper.getMoveRangeCommand(redoModel, []));
15839
16128
  }
16129
+ saveInsertContentsToHistory(redoModel) {
16130
+ const startIndex = redoModel.insertIndex;
16131
+ const undoModel = new DeleteModel({ startIndex, count: redoModel.contents.content.length });
16132
+ this.history.pushInsertContents(undoModel, redoModel);
16133
+ this.commandsService.createCommand(SaveCommandsHelper.getInsertContentsCommand(redoModel, this.targets));
16134
+ }
16135
+ saveReplaceByContentsToHistory(redoModel) {
16136
+ const undoSlice = ContentsOperationsHelper.GetRelativeContentSlice(this.session.model, redoModel.startIndex, redoModel.count);
16137
+ const undoModel = new ReplaceByContentsModel({
16138
+ startIndex: redoModel.startIndex,
16139
+ contents: undoSlice,
16140
+ count: redoModel.contents.content.length
16141
+ });
16142
+ this.history.pushReplaceByContents(undoModel, redoModel);
16143
+ this.commandsService.createCommand(SaveCommandsHelper.getReplaceByContentsModel(redoModel, this.targets));
16144
+ }
15840
16145
  saveReplaceToHistory(range, model) {
15841
16146
  const restoreModel = this.session.createRestoreFromSlice(range.start, range.end);
15842
16147
  this.history.pushReplace(restoreModel, model);
@@ -15980,29 +16285,42 @@ class Editor {
15980
16285
  this.showInsertOverlay(text);
15981
16286
  }
15982
16287
  onCut(event) {
15983
- event.preventDefault();
15984
- const data = this.getSelectedText();
15985
- if (!data) {
16288
+ const text = this.getSelectedText();
16289
+ const slice = this.getSelectedSlice();
16290
+ if (!text && !slice) {
15986
16291
  return;
15987
16292
  }
15988
- this.editorService.setClipboardData(data);
15989
- this.clipboard.copy(data);
15990
- this.cut();
16293
+ this.clipboardHandler.copyEvent(event, text, slice, this.editorService.revisionId);
16294
+ this.removeSelected();
15991
16295
  this.scrollCursorIntoMainView();
16296
+ this.editorService.setClipboardData(text);
15992
16297
  }
15993
16298
  onCopy(event) {
15994
- event.preventDefault();
15995
- const data = this.getSelectedText();
15996
- if (!data) {
16299
+ const text = this.getSelectedText();
16300
+ const slice = this.getSelectedSlice();
16301
+ if (!text && !slice) {
15997
16302
  return;
15998
16303
  }
15999
- this.editorService.setClipboardData(data);
16000
- this.clipboard.copy(data);
16304
+ this.clipboardHandler.copyEvent(event, text, slice, this.editorService.revisionId);
16305
+ this.editorService.setClipboardData(text);
16001
16306
  }
16002
16307
  onPaste(event) {
16003
- event.preventDefault();
16004
- const data = this.textInput.getClipboardData(event);
16005
- this.pasteData(data);
16308
+ const { text, sliceData } = this.clipboardHandler.readEvent(event);
16309
+ if (sliceData) {
16310
+ this.pasteData(text, sliceData);
16311
+ return;
16312
+ }
16313
+ this.clipboardHandler // If slice not found in event should check navigation clipboard for data.
16314
+ .readAsync()
16315
+ .then(asyncData => {
16316
+ if (text === asyncData.text && asyncData.sliceData) {
16317
+ this.pasteData(asyncData.text, asyncData.sliceData);
16318
+ }
16319
+ else if (text) {
16320
+ this.pasteData(text, null);
16321
+ }
16322
+ })
16323
+ .catch(() => { });
16006
16324
  }
16007
16325
  onCreateComment(commentType) {
16008
16326
  const { startIndex, endIndex } = ContentHelper.getSelectedPartDocumentIndexes(this.session.displayData.paragraphs, this.selection.range);
@@ -16310,6 +16628,19 @@ class Editor {
16310
16628
  this.onSelectionChange();
16311
16629
  this.onContentChange();
16312
16630
  }
16631
+ insertContent(insertIndex, contents) {
16632
+ const insertContents = new InsertContentsModel({ insertIndex, contents });
16633
+ this.saveInsertContentsToHistory(insertContents);
16634
+ this.session.insertContents(insertIndex, structuredClone(contents));
16635
+ this.onSelectionChange();
16636
+ }
16637
+ replaceByContents(startIndex, endIndex, contents) {
16638
+ const count = endIndex - startIndex + 1;
16639
+ const replaceByContents = new ReplaceByContentsModel({ startIndex, count, contents });
16640
+ this.saveReplaceByContentsToHistory(replaceByContents);
16641
+ this.session.replaceByContents(startIndex, count, structuredClone(contents));
16642
+ this.onSelectionChange();
16643
+ }
16313
16644
  moveRange(model) {
16314
16645
  this.regulatorService.setTargetedSessionAsCurrent(model.targetTargets);
16315
16646
  const sourceSession = this.regulatorService.getTargetedSession(model.sourceTargets);
@@ -16393,6 +16724,13 @@ class Editor {
16393
16724
  });
16394
16725
  return textInterval;
16395
16726
  }
16727
+ getSelectedSlice() {
16728
+ const selectionRange = this.selection.selectedRange;
16729
+ if (selectionRange.isEmpty) {
16730
+ return null;
16731
+ }
16732
+ return this.session.getContentsSlice(selectionRange.start, selectionRange.end);
16733
+ }
16396
16734
  initMainSession() {
16397
16735
  const pageWidth = this.customPageWidth ?? Math.max(...this.model.pageFormats.map(x => x.pageWidth));
16398
16736
  this.container.nativeElement.style.maxWidth = `${pageWidth}px`;
@@ -16877,49 +17215,59 @@ class Editor {
16877
17215
  }
16878
17216
  cutSelectedSubscription() {
16879
17217
  return this.editorService.cutSelected$.subscribe(() => {
16880
- this.onCut(new ClipboardEvent('cut'));
17218
+ const text = this.getSelectedText();
17219
+ const slice = this.getSelectedSlice();
17220
+ if (!text && !slice) {
17221
+ return;
17222
+ }
17223
+ this.clipboardHandler.copyAsync(text, slice, this.editorService.revisionId).catch(() => { });
17224
+ this.removeSelected();
17225
+ this.scrollCursorIntoMainView();
17226
+ this.editorService.setClipboardData(text);
16881
17227
  });
16882
17228
  }
16883
17229
  copySelectedSubscription() {
16884
17230
  return this.editorService.copySelected$.subscribe(() => {
16885
- this.onCopy(new ClipboardEvent('copy'));
17231
+ const text = this.getSelectedText();
17232
+ const slice = this.getSelectedSlice();
17233
+ if (!text && !slice) {
17234
+ return;
17235
+ }
17236
+ this.clipboardHandler.copyAsync(text, slice, this.editorService.revisionId).catch(() => { });
17237
+ this.editorService.setClipboardData(text);
16886
17238
  });
16887
17239
  }
16888
17240
  pasteFromClipboardSubscription() {
16889
- return this.editorService.pasteFromClipboard$.subscribe(() => {
16890
- this.readClipboard()
16891
- .then(data => this.pasteData(data))
16892
- .catch(() => {
16893
- // continue regardless error
16894
- });
17241
+ return this.editorService.pasteFromClipboard$
17242
+ .pipe(switchMap(() => from(this.clipboardHandler.readAsync())))
17243
+ .subscribe(({ text, sliceData }) => {
17244
+ this.pasteData(text, sliceData);
16895
17245
  });
16896
17246
  }
16897
- async readClipboard() {
16898
- const read = await navigator.permissions.query({ name: 'clipboard-read' });
16899
- return new Promise(resolve => {
16900
- if (navigator.clipboard && read.state != 'denied') {
16901
- navigator.clipboard
16902
- .readText()
16903
- .then(data => {
16904
- resolve(data);
16905
- })
16906
- .catch(() => {
16907
- // continue regardless error
16908
- });
17247
+ pasteData(text, sliceData) {
17248
+ if (sliceData) {
17249
+ this.insertSlice(sliceData);
17250
+ }
17251
+ else if (text) {
17252
+ const insertText = text.replace(/\r\n/g, '\n').replace(/\t/g, ' ');
17253
+ this.insert(insertText);
17254
+ this.scrollCursorIntoMainView();
17255
+ }
17256
+ }
17257
+ insertContentsSubscription() {
17258
+ return this.editorService.insertContents$.subscribe(contents => {
17259
+ const start = this.selection.range.start;
17260
+ const startIndex = ContentHelper.paragraphToDocumentIndex(this.session.displayData.paragraphs, start.row, start.column);
17261
+ if (this.selection.isEmpty) {
17262
+ this.insertContent(startIndex, contents);
16909
17263
  }
16910
17264
  else {
16911
- resolve(this.clipboardData);
17265
+ const end = this.selection.range.end;
17266
+ const endIndex = ContentHelper.paragraphToDocumentIndex(this.session.displayData.paragraphs, end.row, end.column) - 1;
17267
+ this.replaceByContents(startIndex, endIndex, contents);
16912
17268
  }
16913
17269
  });
16914
17270
  }
16915
- pasteData(data) {
16916
- if (!data) {
16917
- return;
16918
- }
16919
- const text = data.replace(/\r\n/g, '\n').replace(/\t/g, ' ');
16920
- this.insert(text);
16921
- this.scrollCursorIntoMainView();
16922
- }
16923
17271
  selectAllSubscription() {
16924
17272
  return this.editorService.selectAll$.subscribe(() => {
16925
17273
  this.selection.selectAll(this.session.model);
@@ -16931,11 +17279,6 @@ class Editor {
16931
17279
  this.removeSelected();
16932
17280
  });
16933
17281
  }
16934
- clipboardDataSubscription() {
16935
- return this.editorService.clipboardData$.subscribe(data => {
16936
- this.clipboardData = data;
16937
- });
16938
- }
16939
17282
  commandCreatedForEdges() {
16940
17283
  return this.commandsService.createCommand$
16941
17284
  .pipe(filter(x => !!x.targets.find(y => !!y.edgeData)))