@talrace/ngx-noder 19.0.51 → 19.0.53
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.
- package/fesm2022/talrace-ngx-noder.mjs +1067 -653
- package/fesm2022/talrace-ngx-noder.mjs.map +1 -1
- package/lib/editor/display/layers/comment-highlight.layer.d.ts +0 -3
- package/lib/editor/display/layers/comment.layer.d.ts +2 -0
- package/lib/editor/display/renderer.d.ts +5 -3
- package/lib/editor/display/renderloop.d.ts +6 -3
- package/lib/editor/display/virtual.renderer.d.ts +6 -5
- package/lib/editor/execution/edit.session.d.ts +6 -2
- package/lib/editor/execution/editor.d.ts +14 -5
- package/lib/editor/execution/regulator.service.d.ts +3 -0
- package/lib/editor/gadgets/clipboard-handler/clipboard-handler.d.ts +23 -0
- package/lib/editor/gadgets/clipboard-handler/clipboard-slice.interface.d.ts +9 -0
- package/lib/editor/gadgets/comment/comment-render.service.d.ts +2 -1
- package/lib/editor/gadgets/history/operation-history.d.ts +5 -0
- package/lib/editor/gadgets/history/operation.type.d.ts +3 -1
- package/lib/editor/interaction/editor.service.d.ts +13 -0
- package/lib/editor/interaction/text-input.d.ts +0 -1
- package/lib/editor/operations/enums/command-type.enum.d.ts +3 -1
- package/lib/editor/operations/helpers/contents-operations.helper.d.ts +2 -0
- package/lib/editor/operations/helpers/format-operations.helper.d.ts +1 -0
- package/lib/editor/operations/helpers/indexed-element-operations.helper.d.ts +1 -0
- package/lib/editor/operations/helpers/link-operations.helper.d.ts +1 -0
- package/lib/editor/operations/helpers/range-element-operations.helper.d.ts +1 -0
- package/lib/editor/operations/operations-helper.helper.d.ts +2 -0
- package/lib/editor/operations/save-commands.helper.d.ts +4 -0
- package/lib/models/generated/command.model.d.ts +4 -0
- package/lib/models/generated/contents.model.d.ts +24 -0
- package/lib/models/generated/insert-contents.model.d.ts +6 -0
- package/lib/models/generated/replace-by-contents.model.d.ts +7 -0
- 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
|
-
|
|
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
|
|
2039
|
-
|
|
2040
|
-
|
|
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
|
-
|
|
2101
|
-
|
|
2102
|
-
this.mouseUp$?.unsubscribe();
|
|
2101
|
+
static sliceContent(content, startIndex, count) {
|
|
2102
|
+
return content.slice(startIndex, startIndex + count);
|
|
2103
2103
|
}
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
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
|
-
|
|
2114
|
-
this.
|
|
2115
|
-
this.
|
|
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
|
|
2166
|
-
constructor(
|
|
2167
|
-
|
|
2168
|
-
|
|
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
|
|
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
|
|
2199
|
-
static
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
const
|
|
2204
|
-
|
|
2205
|
-
|
|
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
|
|
2210
|
-
|
|
2211
|
-
|
|
2632
|
+
class ImageDataModel {
|
|
2633
|
+
constructor(fields) {
|
|
2634
|
+
if (fields) {
|
|
2635
|
+
Object.assign(this, fields);
|
|
2636
|
+
}
|
|
2212
2637
|
}
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
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) {
|
|
@@ -2943,14 +3333,6 @@ class OperationHistory {
|
|
|
2943
3333
|
}
|
|
2944
3334
|
}
|
|
2945
3335
|
|
|
2946
|
-
class BreakModel {
|
|
2947
|
-
constructor(fields) {
|
|
2948
|
-
if (fields) {
|
|
2949
|
-
Object.assign(this, fields);
|
|
2950
|
-
}
|
|
2951
|
-
}
|
|
2952
|
-
}
|
|
2953
|
-
|
|
2954
3336
|
class IndexedElementOperationsHelper {
|
|
2955
3337
|
static removeContent(elements, startIndex, endIndex) {
|
|
2956
3338
|
const length = endIndex - startIndex + 1;
|
|
@@ -2981,165 +3363,43 @@ class IndexedElementOperationsHelper {
|
|
|
2981
3363
|
x.insertIndex += length;
|
|
2982
3364
|
}
|
|
2983
3365
|
});
|
|
2984
|
-
}
|
|
2985
|
-
static
|
|
2986
|
-
this.insertContent(elements,
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
|
|
2998
|
-
|
|
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);
|
|
3076
|
-
}
|
|
3077
|
-
}
|
|
3078
|
-
}
|
|
3079
|
-
|
|
3080
|
-
class RangeElementHelper {
|
|
3081
|
-
static removeContent(elements, startIndex, endIndex) {
|
|
3082
|
-
const length = endIndex - startIndex + 1;
|
|
3083
|
-
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;
|
|
3096
|
-
}
|
|
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;
|
|
3105
|
-
}
|
|
3106
|
-
element.startIndex -= length;
|
|
3107
|
-
element.endIndex -= length;
|
|
3108
|
-
}
|
|
3109
|
-
}
|
|
3110
|
-
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;
|
|
3118
|
-
}
|
|
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
|
-
|
|
3123
|
-
|
|
3124
|
-
|
|
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
|
-
|
|
3129
|
-
|
|
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
|
-
|
|
3138
|
-
|
|
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
|
|
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.
|
|
9476
|
-
this.
|
|
9477
|
-
this.
|
|
9478
|
-
this.
|
|
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.
|
|
9569
|
-
this.
|
|
9570
|
-
this.
|
|
9571
|
-
this.
|
|
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
|
-
|
|
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
|
-
|
|
9884
|
+
insertElementComponents(elements, restoreIndex, restoreEndIndex) {
|
|
9588
9885
|
for (const model of elements) {
|
|
9589
9886
|
if (model.insertIndex < restoreIndex) {
|
|
9590
9887
|
continue;
|
|
@@ -9950,7 +10247,6 @@ class CommentHighlightLayer extends HighlightLayer {
|
|
|
9950
10247
|
this.commentService = commentService;
|
|
9951
10248
|
this.className = 'noder-highlight';
|
|
9952
10249
|
this.selectedCommentClassName = 'noder-selected-highlight';
|
|
9953
|
-
this.selectedCommentId = null;
|
|
9954
10250
|
}
|
|
9955
10251
|
update(config) {
|
|
9956
10252
|
const comments = this.session.model.comments;
|
|
@@ -9972,7 +10268,7 @@ class CommentHighlightLayer extends HighlightLayer {
|
|
|
9972
10268
|
continue;
|
|
9973
10269
|
}
|
|
9974
10270
|
if (!screenRange.isEmpty) {
|
|
9975
|
-
const className = comment.commentId === this.selectedCommentId ? this.selectedCommentClassName : this.className;
|
|
10271
|
+
const className = comment.commentId === this.commentService.selectedCommentId ? this.selectedCommentClassName : this.className;
|
|
9976
10272
|
const result = screenRange.isSingleLine
|
|
9977
10273
|
? this.drawSingleLineMarker(screenRange, className)
|
|
9978
10274
|
: this.drawMultiLineMarker(screenRange, className);
|
|
@@ -9986,23 +10282,13 @@ class CommentHighlightLayer extends HighlightLayer {
|
|
|
9986
10282
|
}
|
|
9987
10283
|
}
|
|
9988
10284
|
}
|
|
9989
|
-
removeSessionComments() {
|
|
9990
|
-
this.commentService.removeCommentsFromRender(this.session.sessionId);
|
|
9991
|
-
}
|
|
9992
10285
|
removeComment(id) {
|
|
9993
10286
|
this.commentService.removeCommentFromRender(this.session.sessionId, id);
|
|
9994
10287
|
}
|
|
9995
|
-
setSelectedComment(id) {
|
|
9996
|
-
if (this.selectedCommentId) {
|
|
9997
|
-
this.commentService.setCommentSelected(this.selectedCommentId, false);
|
|
9998
|
-
}
|
|
9999
|
-
this.selectedCommentId = id;
|
|
10000
|
-
if (id) {
|
|
10001
|
-
this.commentService.setCommentSelected(id);
|
|
10002
|
-
}
|
|
10003
|
-
}
|
|
10004
10288
|
clearSessionComments() {
|
|
10005
|
-
|
|
10289
|
+
if (this.session.model.comments.length) {
|
|
10290
|
+
this.commentService.removeCommentsFromRender(this.session.sessionId);
|
|
10291
|
+
}
|
|
10006
10292
|
}
|
|
10007
10293
|
requestCommentRender(highlight, id) {
|
|
10008
10294
|
const element = Array.isArray(highlight) ? highlight[0] : highlight;
|
|
@@ -10200,48 +10486,6 @@ class RenderChangesModel {
|
|
|
10200
10486
|
}
|
|
10201
10487
|
}
|
|
10202
10488
|
|
|
10203
|
-
class EventHelper {
|
|
10204
|
-
static get nextFrame() {
|
|
10205
|
-
if (!this._nextFrame) {
|
|
10206
|
-
const nextFrame = (callback) => {
|
|
10207
|
-
setTimeout(callback, 17);
|
|
10208
|
-
};
|
|
10209
|
-
this._nextFrame =
|
|
10210
|
-
window.requestAnimationFrame ||
|
|
10211
|
-
window['webkitRequestAnimationFrame'] ||
|
|
10212
|
-
window['mozRequestAnimationFrame'] ||
|
|
10213
|
-
window['msRequestAnimationFrame'] ||
|
|
10214
|
-
window['oRequestAnimationFrame'] ||
|
|
10215
|
-
nextFrame;
|
|
10216
|
-
}
|
|
10217
|
-
return this._nextFrame;
|
|
10218
|
-
}
|
|
10219
|
-
}
|
|
10220
|
-
|
|
10221
|
-
class RenderLoop {
|
|
10222
|
-
constructor(onRender) {
|
|
10223
|
-
this.changes = new RenderChangesModel();
|
|
10224
|
-
this.flush = () => {
|
|
10225
|
-
const changes = this.changes;
|
|
10226
|
-
if (changes.any) {
|
|
10227
|
-
this.changes = new RenderChangesModel();
|
|
10228
|
-
onRender(changes);
|
|
10229
|
-
}
|
|
10230
|
-
if (this.changes.any) {
|
|
10231
|
-
this.schedule();
|
|
10232
|
-
}
|
|
10233
|
-
};
|
|
10234
|
-
}
|
|
10235
|
-
schedule(changes) {
|
|
10236
|
-
if (changes) {
|
|
10237
|
-
this.changes.apply(changes);
|
|
10238
|
-
}
|
|
10239
|
-
if (this.changes) {
|
|
10240
|
-
EventHelper.nextFrame(this.flush);
|
|
10241
|
-
}
|
|
10242
|
-
}
|
|
10243
|
-
}
|
|
10244
|
-
|
|
10245
10489
|
class CustomElementInfo {
|
|
10246
10490
|
constructor(init) {
|
|
10247
10491
|
Object.assign(this, init);
|
|
@@ -10605,9 +10849,11 @@ class Renderer extends EventEmitting {
|
|
|
10605
10849
|
get paragraphsAppeared$() {
|
|
10606
10850
|
return this.paragraphsAppeared.asObservable();
|
|
10607
10851
|
}
|
|
10608
|
-
constructor(parentContainer, commentsService, session) {
|
|
10852
|
+
constructor(parentContainer, commentsService, session, loop) {
|
|
10609
10853
|
super();
|
|
10610
10854
|
this.session = session;
|
|
10855
|
+
this.loop = loop;
|
|
10856
|
+
this.grammarChecksEnabled = false;
|
|
10611
10857
|
this.layerConfig = {
|
|
10612
10858
|
width: 1,
|
|
10613
10859
|
contentRange: new DistanceModel({ start: 0, end: 0 }), // paragraphs
|
|
@@ -10637,7 +10883,7 @@ class Renderer extends EventEmitting {
|
|
|
10637
10883
|
width: 1
|
|
10638
10884
|
};
|
|
10639
10885
|
this.pagesCountChangedHandler = () => {
|
|
10640
|
-
this.
|
|
10886
|
+
this.scheduleChanges({ lines: true, selection: true });
|
|
10641
10887
|
};
|
|
10642
10888
|
this.container = parentContainer;
|
|
10643
10889
|
this.container.className += ' noder-editor';
|
|
@@ -10649,10 +10895,10 @@ class Renderer extends EventEmitting {
|
|
|
10649
10895
|
this.commentsLayer = new CommentHighlightLayer(this.content, 'comments-highlight', this.session, commentsService);
|
|
10650
10896
|
this.cursorLayer = new CursorLayer(this.content, this.session);
|
|
10651
10897
|
this.dragAndDropSelectionLayer = new SelectionLayer(this.content, 'drag-and-drop-selection', this.session);
|
|
10652
|
-
this.
|
|
10898
|
+
loop.registerSession(this.session.sessionId, changes => this.renderChanges(changes));
|
|
10653
10899
|
this.session.displayData.addEventListener('pagesCountChanged', this.pagesCountChangedHandler);
|
|
10654
10900
|
this.visibilitySubscription = this.visibilitySubject
|
|
10655
|
-
.pipe(debounceTime(3000), filter(x => x))
|
|
10901
|
+
.pipe(filter(() => this.grammarChecksEnabled), debounceTime(3000), filter(x => x))
|
|
10656
10902
|
.subscribe(() => this.paragraphsScrolledIntoView());
|
|
10657
10903
|
}
|
|
10658
10904
|
renderChanges(changes, force) {
|
|
@@ -10721,7 +10967,7 @@ class Renderer extends EventEmitting {
|
|
|
10721
10967
|
if (lastRow < this.layerConfig.contentRange.start || firstRow > this.layerConfig.contentRange.end) {
|
|
10722
10968
|
return;
|
|
10723
10969
|
}
|
|
10724
|
-
this.
|
|
10970
|
+
this.scheduleChanges({ lines: true });
|
|
10725
10971
|
}
|
|
10726
10972
|
moveTextAreaToCursor() {
|
|
10727
10973
|
if (!this.textarea) {
|
|
@@ -10743,38 +10989,38 @@ class Renderer extends EventEmitting {
|
|
|
10743
10989
|
updateSelection(range) {
|
|
10744
10990
|
if (range.isEmpty && this.selectionLayer.marker) {
|
|
10745
10991
|
this.selectionLayer.marker = null;
|
|
10746
|
-
this.
|
|
10992
|
+
this.scheduleChanges({ selection: true });
|
|
10747
10993
|
}
|
|
10748
10994
|
else if (!range.isEmpty && !this.selectionLayer.marker?.isEqual(range)) {
|
|
10749
10995
|
this.selectionLayer.marker = range;
|
|
10750
|
-
this.
|
|
10996
|
+
this.scheduleChanges({ selection: true });
|
|
10751
10997
|
}
|
|
10752
10998
|
}
|
|
10753
10999
|
updateSearchHighlights(ranges) {
|
|
10754
11000
|
if (this.searchHighlightLayer.markers.length !== ranges.length ||
|
|
10755
11001
|
!this.searchHighlightLayer.markers.every(x => ranges.some(y => x.isEqual(y)))) {
|
|
10756
11002
|
this.searchHighlightLayer.markers = ranges;
|
|
10757
|
-
this.
|
|
11003
|
+
this.scheduleChanges({ search: true });
|
|
10758
11004
|
}
|
|
10759
11005
|
}
|
|
10760
11006
|
updateCustomElementHighlights(ranges) {
|
|
10761
11007
|
this.searchHighlightLayer.customElementsRanges = ranges;
|
|
10762
|
-
this.
|
|
11008
|
+
this.scheduleChanges({ search: true });
|
|
10763
11009
|
}
|
|
10764
11010
|
updateActiveSearchHighlight(active) {
|
|
10765
11011
|
this.searchHighlightLayer.active = active;
|
|
10766
|
-
this.
|
|
11012
|
+
this.scheduleChanges({ search: true });
|
|
10767
11013
|
}
|
|
10768
11014
|
updateGrammarHighlights(paragraphId, errors) {
|
|
10769
11015
|
this.grammarHighlightLayer.setErrors(paragraphId, errors);
|
|
10770
|
-
this.
|
|
11016
|
+
this.scheduleChanges({ grammar: true });
|
|
10771
11017
|
}
|
|
10772
11018
|
removeGrammarHighlights(paragraphId) {
|
|
10773
11019
|
this.grammarHighlightLayer.removeParagraphHighlights(paragraphId);
|
|
10774
11020
|
}
|
|
10775
11021
|
clearGrammarHighlights() {
|
|
10776
11022
|
this.grammarHighlightLayer.clearHighlights();
|
|
10777
|
-
this.
|
|
11023
|
+
this.scheduleChanges({ grammar: true });
|
|
10778
11024
|
}
|
|
10779
11025
|
paragraphsScrolledIntoView() {
|
|
10780
11026
|
if (!this.layerConfig.visibleRange) {
|
|
@@ -10787,11 +11033,11 @@ class Renderer extends EventEmitting {
|
|
|
10787
11033
|
updateDragAndDropSelection(range) {
|
|
10788
11034
|
if (range.isEmpty && this.dragAndDropSelectionLayer.marker) {
|
|
10789
11035
|
this.dragAndDropSelectionLayer.marker = null;
|
|
10790
|
-
this.
|
|
11036
|
+
this.scheduleChanges({ dragAndDrop: true });
|
|
10791
11037
|
}
|
|
10792
11038
|
else if (!range.isEmpty && !this.dragAndDropSelectionLayer.marker?.isEqual(range)) {
|
|
10793
11039
|
this.dragAndDropSelectionLayer.marker = range;
|
|
10794
|
-
this.
|
|
11040
|
+
this.scheduleChanges({ dragAndDrop: true });
|
|
10795
11041
|
}
|
|
10796
11042
|
}
|
|
10797
11043
|
clearDragAndDropSelection() {
|
|
@@ -10799,7 +11045,7 @@ class Renderer extends EventEmitting {
|
|
|
10799
11045
|
return;
|
|
10800
11046
|
}
|
|
10801
11047
|
this.dragAndDropSelectionLayer.marker = null;
|
|
10802
|
-
this.
|
|
11048
|
+
this.scheduleChanges({ dragAndDrop: true });
|
|
10803
11049
|
}
|
|
10804
11050
|
setVisibility(isVisible) {
|
|
10805
11051
|
if (this.isVisible !== isVisible) {
|
|
@@ -10807,23 +11053,23 @@ class Renderer extends EventEmitting {
|
|
|
10807
11053
|
if (!isVisible) {
|
|
10808
11054
|
this.commentsLayer.clearSessionComments();
|
|
10809
11055
|
}
|
|
10810
|
-
this.
|
|
11056
|
+
this.scheduleChanges({ visibilityChanged: true });
|
|
10811
11057
|
}
|
|
10812
11058
|
}
|
|
10813
11059
|
/**
|
|
10814
11060
|
* Triggers a full update of the text, for all the rows.
|
|
10815
11061
|
**/
|
|
10816
11062
|
updateText() {
|
|
10817
|
-
this.
|
|
11063
|
+
this.scheduleChanges({ text: true });
|
|
10818
11064
|
}
|
|
10819
11065
|
updateTextAndCursor() {
|
|
10820
|
-
this.
|
|
11066
|
+
this.scheduleChanges({ text: true, cursor: true });
|
|
10821
11067
|
}
|
|
10822
11068
|
updateMarker() {
|
|
10823
|
-
this.
|
|
11069
|
+
this.scheduleChanges({ marker: true });
|
|
10824
11070
|
}
|
|
10825
11071
|
updateCursor() {
|
|
10826
|
-
this.
|
|
11072
|
+
this.scheduleChanges({ cursor: true });
|
|
10827
11073
|
}
|
|
10828
11074
|
// tokenDivider - used to measure if token fits (1 - should be fully fit, 2 - half of token, 3 - third part, ...) to be included
|
|
10829
11075
|
screenToParagraph(x, y, tokenDivider = 1, rect) {
|
|
@@ -10880,14 +11126,11 @@ class Renderer extends EventEmitting {
|
|
|
10880
11126
|
renderCommentHighlights() {
|
|
10881
11127
|
this.commentsLayer.update(this.layerConfig);
|
|
10882
11128
|
}
|
|
10883
|
-
setSelectedComment(comment) {
|
|
10884
|
-
this.commentsLayer.setSelectedComment(comment);
|
|
10885
|
-
}
|
|
10886
11129
|
removeComment(id) {
|
|
10887
11130
|
this.commentsLayer.removeComment(id);
|
|
10888
11131
|
}
|
|
10889
11132
|
clearComments() {
|
|
10890
|
-
this.commentsLayer.
|
|
11133
|
+
this.commentsLayer.clearSessionComments();
|
|
10891
11134
|
}
|
|
10892
11135
|
setCommentsVisibility(value) {
|
|
10893
11136
|
if (!value) {
|
|
@@ -10895,6 +11138,9 @@ class Renderer extends EventEmitting {
|
|
|
10895
11138
|
}
|
|
10896
11139
|
this.commentsLayer.enabled = value;
|
|
10897
11140
|
}
|
|
11141
|
+
scheduleChanges(changes) {
|
|
11142
|
+
this.loop.schedule(this.session.sessionId, changes);
|
|
11143
|
+
}
|
|
10898
11144
|
renderDragAndDropSelection() {
|
|
10899
11145
|
this.dragAndDropSelectionLayer.update(this.layerConfig);
|
|
10900
11146
|
}
|
|
@@ -10925,6 +11171,65 @@ class Renderer extends EventEmitting {
|
|
|
10925
11171
|
}
|
|
10926
11172
|
}
|
|
10927
11173
|
|
|
11174
|
+
class EventHelper {
|
|
11175
|
+
static get nextFrame() {
|
|
11176
|
+
if (!this._nextFrame) {
|
|
11177
|
+
const nextFrame = (callback) => {
|
|
11178
|
+
setTimeout(callback, 17);
|
|
11179
|
+
};
|
|
11180
|
+
this._nextFrame =
|
|
11181
|
+
window.requestAnimationFrame ||
|
|
11182
|
+
window['webkitRequestAnimationFrame'] ||
|
|
11183
|
+
window['mozRequestAnimationFrame'] ||
|
|
11184
|
+
window['msRequestAnimationFrame'] ||
|
|
11185
|
+
window['oRequestAnimationFrame'] ||
|
|
11186
|
+
nextFrame;
|
|
11187
|
+
}
|
|
11188
|
+
return this._nextFrame;
|
|
11189
|
+
}
|
|
11190
|
+
}
|
|
11191
|
+
|
|
11192
|
+
class RenderLoop {
|
|
11193
|
+
constructor() {
|
|
11194
|
+
this.sessionCallbacks = new Map();
|
|
11195
|
+
this.sessionChanges = new Map();
|
|
11196
|
+
this.flush = () => {
|
|
11197
|
+
const sessionsToRender = Array.from(this.sessionChanges.entries());
|
|
11198
|
+
const hasChanges = sessionsToRender.filter(([_, changes]) => changes.any);
|
|
11199
|
+
if (!hasChanges.length) {
|
|
11200
|
+
return;
|
|
11201
|
+
}
|
|
11202
|
+
for (const [sessionId, changes] of hasChanges) {
|
|
11203
|
+
const callback = this.sessionCallbacks.get(sessionId);
|
|
11204
|
+
callback(new RenderChangesModel(changes));
|
|
11205
|
+
this.sessionChanges.set(sessionId, new RenderChangesModel());
|
|
11206
|
+
}
|
|
11207
|
+
const hasMoreChanges = Array.from(this.sessionChanges.values()).some(changes => changes.any);
|
|
11208
|
+
if (hasMoreChanges) {
|
|
11209
|
+
EventHelper.nextFrame(this.flush);
|
|
11210
|
+
}
|
|
11211
|
+
};
|
|
11212
|
+
}
|
|
11213
|
+
registerSession(sessionId, onRender) {
|
|
11214
|
+
this.sessionCallbacks.set(sessionId, onRender);
|
|
11215
|
+
if (!this.sessionChanges.has(sessionId)) {
|
|
11216
|
+
this.sessionChanges.set(sessionId, new RenderChangesModel());
|
|
11217
|
+
}
|
|
11218
|
+
}
|
|
11219
|
+
unregisterSession(sessionId) {
|
|
11220
|
+
this.sessionCallbacks.delete(sessionId);
|
|
11221
|
+
this.sessionChanges.delete(sessionId);
|
|
11222
|
+
}
|
|
11223
|
+
schedule(sessionId, changes) {
|
|
11224
|
+
if (changes) {
|
|
11225
|
+
this.sessionChanges.get(sessionId).apply(changes);
|
|
11226
|
+
}
|
|
11227
|
+
if (this.sessionChanges.get(sessionId).any) {
|
|
11228
|
+
EventHelper.nextFrame(this.flush);
|
|
11229
|
+
}
|
|
11230
|
+
}
|
|
11231
|
+
}
|
|
11232
|
+
|
|
10928
11233
|
/**
|
|
10929
11234
|
* Represents a vertical scroll bar.
|
|
10930
11235
|
* @class ScrollBar
|
|
@@ -11046,13 +11351,17 @@ class CommentLayer {
|
|
|
11046
11351
|
constructor(parentEl) {
|
|
11047
11352
|
this.commentPadding = 8;
|
|
11048
11353
|
this.rendersBySession = new Map();
|
|
11354
|
+
this.enabled = false;
|
|
11049
11355
|
this.element = document.createElement('div');
|
|
11050
11356
|
this.element.className = `noder-comments-layer`;
|
|
11051
11357
|
parentEl.appendChild(this.element);
|
|
11052
11358
|
}
|
|
11359
|
+
enable() {
|
|
11360
|
+
this.enabled = true;
|
|
11361
|
+
}
|
|
11053
11362
|
disable() {
|
|
11054
|
-
this.
|
|
11055
|
-
this.
|
|
11363
|
+
this.enabled = false;
|
|
11364
|
+
this.element.innerHTML = '';
|
|
11056
11365
|
}
|
|
11057
11366
|
scrollComments(offsetY) {
|
|
11058
11367
|
for (const [sessionId, comments] of this.rendersBySession) {
|
|
@@ -11065,6 +11374,9 @@ class CommentLayer {
|
|
|
11065
11374
|
}
|
|
11066
11375
|
}
|
|
11067
11376
|
renderComments() {
|
|
11377
|
+
if (!this.enabled) {
|
|
11378
|
+
return;
|
|
11379
|
+
}
|
|
11068
11380
|
this.element.innerHTML = '';
|
|
11069
11381
|
const topOffset = this.element.getBoundingClientRect().top;
|
|
11070
11382
|
const sortedComments = Array.from(this.rendersBySession.values())
|
|
@@ -11256,12 +11568,6 @@ class VirtualRenderer {
|
|
|
11256
11568
|
get cursorLayer() {
|
|
11257
11569
|
return this.renderer.cursorLayer;
|
|
11258
11570
|
}
|
|
11259
|
-
get loop() {
|
|
11260
|
-
return this.renderer.loop;
|
|
11261
|
-
}
|
|
11262
|
-
set loop(val) {
|
|
11263
|
-
this.renderer.loop = val;
|
|
11264
|
-
}
|
|
11265
11571
|
get textarea() {
|
|
11266
11572
|
return this.renderer.textarea;
|
|
11267
11573
|
}
|
|
@@ -11277,10 +11583,12 @@ class VirtualRenderer {
|
|
|
11277
11583
|
get paragraphsAppeared$() {
|
|
11278
11584
|
return this.renderer.paragraphsAppeared.asObservable();
|
|
11279
11585
|
}
|
|
11280
|
-
constructor(parentContainer, mainSession, commentService, scrollBar) {
|
|
11586
|
+
constructor(parentContainer, mainSession, commentService, loop, scrollBar) {
|
|
11281
11587
|
this.commentService = commentService;
|
|
11588
|
+
this.loop = loop;
|
|
11282
11589
|
this.scrollBar = scrollBar;
|
|
11283
11590
|
this.changes = new RenderChangesModel();
|
|
11591
|
+
this.grammarChecksEnabled = false;
|
|
11284
11592
|
this.size = {
|
|
11285
11593
|
width: 0,
|
|
11286
11594
|
height: 0,
|
|
@@ -11291,18 +11599,19 @@ class VirtualRenderer {
|
|
|
11291
11599
|
this.paragraphsScrolledIntoViewSubject = new Subject();
|
|
11292
11600
|
this.container = parentContainer;
|
|
11293
11601
|
this.createScroller();
|
|
11294
|
-
this.renderer = new Renderer(parentContainer, commentService, mainSession);
|
|
11602
|
+
this.renderer = new Renderer(parentContainer, commentService, mainSession, loop);
|
|
11603
|
+
loop.registerSession(0, changes => this.renderChanges(changes));
|
|
11295
11604
|
this.pagesLayer = new PagesLayer(this.renderer.content, mainSession);
|
|
11296
11605
|
this.edgesLayer = new EdgesLayer(this.renderer.content, mainSession);
|
|
11297
11606
|
this.commentLayer = new CommentLayer(this.renderer.content);
|
|
11298
11607
|
this.scrollSubscription = this.scrollBar.scrolled$.subscribe(x => {
|
|
11299
11608
|
this.commentLayer.scrollComments(x);
|
|
11300
|
-
this.
|
|
11609
|
+
this.scheduleChanges({ scroll: true, comments: true });
|
|
11301
11610
|
});
|
|
11302
|
-
this.createRenderLoop();
|
|
11303
11611
|
this.paragraphsScrolledIntoViewSubscription = this.paragraphsScrolledIntoViewSubject
|
|
11304
|
-
.pipe(debounceTime(3000))
|
|
11612
|
+
.pipe(filter(() => this.grammarChecksEnabled), debounceTime(3000))
|
|
11305
11613
|
.subscribe(() => this.paragraphsScrolledIntoView());
|
|
11614
|
+
this.scheduleChanges({ full: true });
|
|
11306
11615
|
}
|
|
11307
11616
|
renderChanges(changes, force) {
|
|
11308
11617
|
changes.apply(this.changes);
|
|
@@ -11381,7 +11690,7 @@ class VirtualRenderer {
|
|
|
11381
11690
|
this.renderChanges(changes, true);
|
|
11382
11691
|
}
|
|
11383
11692
|
else {
|
|
11384
|
-
this.
|
|
11693
|
+
this.scheduleChanges(changes);
|
|
11385
11694
|
}
|
|
11386
11695
|
this.scrollBar.setScrollTop(0);
|
|
11387
11696
|
}
|
|
@@ -11411,21 +11720,28 @@ class VirtualRenderer {
|
|
|
11411
11720
|
this.size.dirty = !width || !height;
|
|
11412
11721
|
return changes;
|
|
11413
11722
|
}
|
|
11414
|
-
setSelectedComment(
|
|
11415
|
-
this.
|
|
11723
|
+
setSelectedComment(id) {
|
|
11724
|
+
const oldId = this.commentService.selectedCommentId;
|
|
11725
|
+
this.commentService.setSelectedComment(id);
|
|
11726
|
+
if (this.commentService.selectedCommentId !== oldId) {
|
|
11727
|
+
this.scheduleChanges({ comments: true });
|
|
11728
|
+
}
|
|
11416
11729
|
}
|
|
11417
11730
|
setCommentsVisibility(value) {
|
|
11418
11731
|
if (value && !this.commentsSubscription) {
|
|
11732
|
+
this.commentLayer.enable();
|
|
11419
11733
|
this.commentsSubscription = this.commentService.commentRenderRequests$.subscribe(x => {
|
|
11420
11734
|
this.commentLayer.applyChanges(x);
|
|
11421
|
-
this.
|
|
11735
|
+
setTimeout(() => this.scheduleChanges({ comments: true }));
|
|
11422
11736
|
});
|
|
11423
11737
|
}
|
|
11424
11738
|
else {
|
|
11739
|
+
this.commentLayer.disable();
|
|
11425
11740
|
this.commentsSubscription?.unsubscribe();
|
|
11426
11741
|
this.commentsSubscription = null;
|
|
11427
11742
|
}
|
|
11428
11743
|
this.renderer.setCommentsVisibility(value);
|
|
11744
|
+
this.scheduleChanges({ comments: true });
|
|
11429
11745
|
}
|
|
11430
11746
|
removeComment(id) {
|
|
11431
11747
|
this.renderer.removeComment(id);
|
|
@@ -11492,6 +11808,9 @@ class VirtualRenderer {
|
|
|
11492
11808
|
setVisibility(isVisible) {
|
|
11493
11809
|
this.renderer.setVisibility(isVisible);
|
|
11494
11810
|
}
|
|
11811
|
+
scheduleChanges(changes) {
|
|
11812
|
+
this.loop.schedule(0, changes);
|
|
11813
|
+
}
|
|
11495
11814
|
scrollSelectionIntoView(anchor, lead, offset) {
|
|
11496
11815
|
// first scroll anchor into view then scroll lead into view
|
|
11497
11816
|
this.scrollCursorIntoView(anchor, offset);
|
|
@@ -11511,7 +11830,7 @@ class VirtualRenderer {
|
|
|
11511
11830
|
top -= offset * this.container.scrollHeight;
|
|
11512
11831
|
}
|
|
11513
11832
|
this.scrollBar.setScrollTop(top);
|
|
11514
|
-
this.
|
|
11833
|
+
this.scheduleChanges({ scroll: true });
|
|
11515
11834
|
}
|
|
11516
11835
|
else if (this.scrollBar.scrollTop + this.container.scrollHeight < top + position.height) {
|
|
11517
11836
|
if (offset) {
|
|
@@ -11519,7 +11838,7 @@ class VirtualRenderer {
|
|
|
11519
11838
|
}
|
|
11520
11839
|
top += position.height - this.container.scrollHeight;
|
|
11521
11840
|
this.scrollBar.setScrollTop(top);
|
|
11522
|
-
this.
|
|
11841
|
+
this.scheduleChanges({ scroll: true });
|
|
11523
11842
|
}
|
|
11524
11843
|
}
|
|
11525
11844
|
scrollBy(deltaY) {
|
|
@@ -11529,7 +11848,7 @@ class VirtualRenderer {
|
|
|
11529
11848
|
const scrollTop = this.scrollBar.scrollTop + deltaY;
|
|
11530
11849
|
this.scrollBar.setScrollTop(scrollTop);
|
|
11531
11850
|
this.commentLayer.scrollComments(deltaY);
|
|
11532
|
-
this.
|
|
11851
|
+
this.scheduleChanges({ scroll: true, comments: true });
|
|
11533
11852
|
}
|
|
11534
11853
|
// tokenDivider - used to measure if token fits (1 - should be fully fit, 2 - half of token, 3 - third part, ...) to be included
|
|
11535
11854
|
screenToParagraph(x, y, tokenDivider = 1, rect) {
|
|
@@ -11595,11 +11914,6 @@ class VirtualRenderer {
|
|
|
11595
11914
|
this.scroller.className = 'noder-scroller';
|
|
11596
11915
|
this.container.appendChild(this.scroller);
|
|
11597
11916
|
}
|
|
11598
|
-
createRenderLoop() {
|
|
11599
|
-
this.loop = new RenderLoop(changes => this.renderChanges(changes));
|
|
11600
|
-
this.renderer.loop = this.loop;
|
|
11601
|
-
this.loop.schedule({ full: true });
|
|
11602
|
-
}
|
|
11603
11917
|
renderScroll(changes) {
|
|
11604
11918
|
this.pagesLayer.update(this.layerConfig);
|
|
11605
11919
|
this.edgesLayer.scrollEdges(this.layerConfig);
|
|
@@ -11792,6 +12106,7 @@ class CommentRenderService {
|
|
|
11792
12106
|
this.applicationRef = inject(ApplicationRef);
|
|
11793
12107
|
this.injector = inject(Injector);
|
|
11794
12108
|
this.commentRenderRequests = new Subject();
|
|
12109
|
+
this.selectedCommentId = null;
|
|
11795
12110
|
}
|
|
11796
12111
|
requestCommentsRender(sessionId, renderRequests) {
|
|
11797
12112
|
const requests = [];
|
|
@@ -11825,9 +12140,17 @@ class CommentRenderService {
|
|
|
11825
12140
|
removeCommentsFromRender(sessionId) {
|
|
11826
12141
|
this.commentRenderRequests.next(new RemoveCommentsFromDom(sessionId));
|
|
11827
12142
|
}
|
|
11828
|
-
|
|
12143
|
+
setSelectedComment(id) {
|
|
12144
|
+
if (this.selectedCommentId === id) {
|
|
12145
|
+
return;
|
|
12146
|
+
}
|
|
12147
|
+
if (this.selectedCommentId) {
|
|
12148
|
+
const oldComponentRef = this.componentInstances.find(x => x.instance.id === this.selectedCommentId);
|
|
12149
|
+
oldComponentRef?.instance.setSelected(false);
|
|
12150
|
+
}
|
|
11829
12151
|
const componentRef = this.componentInstances.find(x => x.instance.id === id);
|
|
11830
|
-
componentRef?.instance.setSelected(
|
|
12152
|
+
componentRef?.instance.setSelected(true);
|
|
12153
|
+
this.selectedCommentId = id;
|
|
11831
12154
|
}
|
|
11832
12155
|
createComponentRef(id) {
|
|
11833
12156
|
const ref = createComponent(this.componentType, {
|
|
@@ -11857,6 +12180,7 @@ class RegulatorService {
|
|
|
11857
12180
|
this.grammarEnabled = false;
|
|
11858
12181
|
this.selectedCommentSessionId = null;
|
|
11859
12182
|
this.selectedCommentId = null;
|
|
12183
|
+
this.renderLoop = new RenderLoop();
|
|
11860
12184
|
this.grammarChecker = new GrammarChecker(this.grammarService);
|
|
11861
12185
|
this.observer = this.initializeIntersectionObserver();
|
|
11862
12186
|
}
|
|
@@ -11885,9 +12209,9 @@ class RegulatorService {
|
|
|
11885
12209
|
const displayData = new DisplayData(model, properties, sessionId, model.pageFormats, DocumentInfo.pagesSpace, customComponents, this.customContentService, this.editorService);
|
|
11886
12210
|
const scrollBar = new ScrollBar(container.nativeElement.parentElement);
|
|
11887
12211
|
const mainSession = new EditSession(displayData, sessionId, this.customContentService, this.commentRenderService, model, this.selection, properties, this.editorService, customComponents, 'main', scrollBar);
|
|
11888
|
-
|
|
12212
|
+
this.mainRenderer = new VirtualRenderer(container.nativeElement, mainSession, this.commentRenderService, this.renderLoop, scrollBar);
|
|
11889
12213
|
this.editorService.styles = DEFAULT_TOOLBAR_STYLES();
|
|
11890
|
-
this.mainSession = new SessionModel(mainSession,
|
|
12214
|
+
this.mainSession = new SessionModel(mainSession, this.mainRenderer, sessionId, null, new MainSessionSourceModel(), container.nativeElement);
|
|
11891
12215
|
this.sessions.push(this.mainSession);
|
|
11892
12216
|
this.currentSession = this.mainSession;
|
|
11893
12217
|
displayData.updateNextLineIndexes(0, displayData.paragraphs.length - 1);
|
|
@@ -11903,7 +12227,7 @@ class RegulatorService {
|
|
|
11903
12227
|
const session = new EditSession(displayData, sessionId, this.customContentService, this.commentRenderService, component.cell, this.selection, component.generalProperties, this.editorService, customComponents, sessionType);
|
|
11904
12228
|
displayData.pagesFormat[0].contentWidth =
|
|
11905
12229
|
displayData.pagesFormat[0].contentWidth === 0 ? 1 : displayData.pagesFormat[0].contentWidth;
|
|
11906
|
-
const renderer = new Renderer(component.container.nativeElement, this.commentRenderService, session);
|
|
12230
|
+
const renderer = new Renderer(component.container.nativeElement, this.commentRenderService, session, this.renderLoop);
|
|
11907
12231
|
const source = new CellSessionSourceModel(component.table, component);
|
|
11908
12232
|
const newSession = new SessionModel(session, renderer, sessionId, component.parentSessionId, source, nativeElement);
|
|
11909
12233
|
this.sessions.push(newSession);
|
|
@@ -11920,7 +12244,7 @@ class RegulatorService {
|
|
|
11920
12244
|
const customComponents = { images: [], tables: [], tabs: [], customElements: [], edges: null };
|
|
11921
12245
|
const displayData = new DisplayData(component.model, component.generalProperties, sessionId, this.getPageFormats(component.margins, component.width), 0, customComponents, this.customContentService, this.editorService);
|
|
11922
12246
|
const session = new EditSession(displayData, sessionId, this.customContentService, this.commentRenderService, component.model, this.selection, component.generalProperties, this.editorService, customComponents, 'edge', null, component.type, component.model.pageType);
|
|
11923
|
-
const renderer = new Renderer(component.container.nativeElement, this.commentRenderService, session);
|
|
12247
|
+
const renderer = new Renderer(component.container.nativeElement, this.commentRenderService, session, this.renderLoop);
|
|
11924
12248
|
const source = new EdgeSessionSourceModel(component.model.pageType, component.type);
|
|
11925
12249
|
const newSession = new SessionModel(session, renderer, sessionId, component.parentSessionId, source, nativeElement);
|
|
11926
12250
|
this.sessions.push(newSession);
|
|
@@ -12080,7 +12404,7 @@ class RegulatorService {
|
|
|
12080
12404
|
setCommentsVisibility(value) {
|
|
12081
12405
|
for (const sessionModel of this.sessions) {
|
|
12082
12406
|
sessionModel.renderer.setCommentsVisibility(value);
|
|
12083
|
-
sessionModel.renderer.
|
|
12407
|
+
sessionModel.renderer.scheduleChanges({ commentHighlights: true });
|
|
12084
12408
|
}
|
|
12085
12409
|
}
|
|
12086
12410
|
setSelectedComment(commentId) {
|
|
@@ -12089,36 +12413,38 @@ class RegulatorService {
|
|
|
12089
12413
|
return;
|
|
12090
12414
|
}
|
|
12091
12415
|
const sessionModel = this.getSessionModel(this.selectedCommentSessionId);
|
|
12092
|
-
|
|
12093
|
-
sessionModel.renderer.
|
|
12416
|
+
this.mainRenderer.setSelectedComment(null);
|
|
12417
|
+
sessionModel.renderer.scheduleChanges({ commentHighlights: true });
|
|
12094
12418
|
return;
|
|
12095
12419
|
}
|
|
12420
|
+
this.mainRenderer.setSelectedComment(commentId);
|
|
12096
12421
|
const newSelectedSession = this.sessions.find(x => x.session.model.comments.some(c => c.commentId === commentId));
|
|
12097
12422
|
if (this.selectedCommentSessionId && this.selectedCommentSessionId !== newSelectedSession.sessionId) {
|
|
12098
12423
|
const sessionModel = this.getSessionModel(this.selectedCommentSessionId);
|
|
12099
|
-
sessionModel.renderer.
|
|
12100
|
-
|
|
12424
|
+
sessionModel.renderer.scheduleChanges({ commentHighlights: true });
|
|
12425
|
+
newSelectedSession.renderer.scheduleChanges({ commentHighlights: true });
|
|
12101
12426
|
}
|
|
12102
12427
|
else {
|
|
12103
|
-
newSelectedSession.renderer.
|
|
12104
|
-
newSelectedSession.renderer.loop.schedule({ commentHighlights: true });
|
|
12428
|
+
newSelectedSession.renderer.scheduleChanges({ commentHighlights: true });
|
|
12105
12429
|
}
|
|
12106
12430
|
this.selectedCommentId = commentId;
|
|
12107
12431
|
this.selectedCommentSessionId = newSelectedSession.sessionId;
|
|
12108
12432
|
}
|
|
12109
12433
|
setSelectedCommentAtCursor() {
|
|
12110
12434
|
const comment = this.currentSession.session.getCommentAtCursor();
|
|
12435
|
+
this.mainRenderer.setSelectedComment(comment?.commentId);
|
|
12111
12436
|
if (this.selectedCommentId && this.selectedCommentId !== comment?.commentId) {
|
|
12112
12437
|
const sessionModel = this.getSessionModel(this.selectedCommentSessionId);
|
|
12113
|
-
sessionModel.renderer.
|
|
12114
|
-
sessionModel.renderer.loop.schedule({ commentHighlights: true });
|
|
12438
|
+
sessionModel.renderer.scheduleChanges({ commentHighlights: true });
|
|
12115
12439
|
}
|
|
12116
12440
|
if (comment) {
|
|
12117
|
-
this.currentSession.renderer.
|
|
12118
|
-
this.currentSession.renderer.loop.schedule({ commentHighlights: true });
|
|
12441
|
+
this.currentSession.renderer.scheduleChanges({ commentHighlights: true });
|
|
12119
12442
|
this.selectedCommentId = comment.commentId;
|
|
12120
12443
|
this.selectedCommentSessionId = this.currentSession.sessionId;
|
|
12444
|
+
return;
|
|
12121
12445
|
}
|
|
12446
|
+
this.selectedCommentId = null;
|
|
12447
|
+
this.selectedCommentSessionId = null;
|
|
12122
12448
|
}
|
|
12123
12449
|
isWithinEdge(sessionId) {
|
|
12124
12450
|
return !!this.getEdgeSessionId(sessionId);
|
|
@@ -12147,12 +12473,14 @@ class RegulatorService {
|
|
|
12147
12473
|
for (const session of this.sessions) {
|
|
12148
12474
|
this.grammarChecker.registerSession(session);
|
|
12149
12475
|
session.renderer.paragraphsScrolledIntoView();
|
|
12476
|
+
session.renderer.grammarChecksEnabled = true;
|
|
12150
12477
|
}
|
|
12151
12478
|
return;
|
|
12152
12479
|
}
|
|
12153
12480
|
for (const session of this.sessions) {
|
|
12154
12481
|
this.grammarChecker.unregisterSession(session.sessionId);
|
|
12155
12482
|
session.renderer.clearGrammarHighlights();
|
|
12483
|
+
session.renderer.grammarChecksEnabled = false;
|
|
12156
12484
|
}
|
|
12157
12485
|
}
|
|
12158
12486
|
getEdgeSessionId(sessionId) {
|
|
@@ -13763,6 +14091,17 @@ class RemoveWithParagraphModel {
|
|
|
13763
14091
|
}
|
|
13764
14092
|
}
|
|
13765
14093
|
|
|
14094
|
+
class ReplaceByContentsModel {
|
|
14095
|
+
constructor(fields) {
|
|
14096
|
+
if (fields) {
|
|
14097
|
+
if (fields.contents) {
|
|
14098
|
+
fields.contents = new ContentsModel(fields.contents);
|
|
14099
|
+
}
|
|
14100
|
+
Object.assign(this, fields);
|
|
14101
|
+
}
|
|
14102
|
+
}
|
|
14103
|
+
}
|
|
14104
|
+
|
|
13766
14105
|
class ReplaceModel {
|
|
13767
14106
|
constructor(fields) {
|
|
13768
14107
|
if (fields) {
|
|
@@ -13862,6 +14201,9 @@ class CommandModel {
|
|
|
13862
14201
|
if (fields.insertBreak) {
|
|
13863
14202
|
fields.insertBreak = new InsertBreakModel(fields.insertBreak);
|
|
13864
14203
|
}
|
|
14204
|
+
if (fields.insertContents) {
|
|
14205
|
+
fields.insertContents = new InsertContentsModel(fields.insertContents);
|
|
14206
|
+
}
|
|
13865
14207
|
if (fields.insertElement) {
|
|
13866
14208
|
fields.insertElement = new InsertElementModel(fields.insertElement);
|
|
13867
14209
|
}
|
|
@@ -13919,6 +14261,9 @@ class CommandModel {
|
|
|
13919
14261
|
if (fields.replace) {
|
|
13920
14262
|
fields.replace = new ReplaceModel(fields.replace);
|
|
13921
14263
|
}
|
|
14264
|
+
if (fields.replaceByContents) {
|
|
14265
|
+
fields.replaceByContents = new ReplaceByContentsModel(fields.replaceByContents);
|
|
14266
|
+
}
|
|
13922
14267
|
if (fields.replaceByRestore) {
|
|
13923
14268
|
fields.replaceByRestore = new ReplaceByRestoreModel(fields.replaceByRestore);
|
|
13924
14269
|
}
|
|
@@ -14047,6 +14392,12 @@ class SaveCommandsHelper {
|
|
|
14047
14392
|
static getReplaceByRestoreCommand(replaceByRestore, targets) {
|
|
14048
14393
|
return new CommandModel({ commandType: CommandType.ReplaceByRestore, replaceByRestore, targets });
|
|
14049
14394
|
}
|
|
14395
|
+
static getInsertContentsCommand(model, targets) {
|
|
14396
|
+
return new CommandModel({ commandType: CommandType.InsertContents, insertContents: model, targets });
|
|
14397
|
+
}
|
|
14398
|
+
static getReplaceByContentsModel(model, targets) {
|
|
14399
|
+
return new CommandModel({ commandType: CommandType.ReplaceByContents, replaceByContents: model, targets });
|
|
14400
|
+
}
|
|
14050
14401
|
static getMoveRangeCommand(model, targets) {
|
|
14051
14402
|
return new CommandModel({ commandType: CommandType.MoveRange, moveRange: model, targets });
|
|
14052
14403
|
}
|
|
@@ -14815,10 +15166,6 @@ class TextInput {
|
|
|
14815
15166
|
parentElement.insertBefore(this.input, parentElement.firstChild);
|
|
14816
15167
|
this.isFocused = document.activeElement === this.input;
|
|
14817
15168
|
}
|
|
14818
|
-
getClipboardData(event) {
|
|
14819
|
-
const mime = 'text/plain';
|
|
14820
|
-
return event.clipboardData.getData(mime);
|
|
14821
|
-
}
|
|
14822
15169
|
getInsertText() {
|
|
14823
15170
|
const data = this.input.value;
|
|
14824
15171
|
const selectionStart = this.input.selectionStart;
|
|
@@ -14940,12 +15287,13 @@ class Editor {
|
|
|
14940
15287
|
this.inputHandler = new InputHandler(this.textInput.input, this);
|
|
14941
15288
|
this.documentHandler = new DocumentHandler(this);
|
|
14942
15289
|
this.dragAndDrop = new DragAndDrop(this.container.nativeElement);
|
|
15290
|
+
this.clipboardHandler = new ClipboardHandler(this.clipboard);
|
|
14943
15291
|
this.initResizeListener();
|
|
14944
15292
|
this.focus();
|
|
14945
15293
|
this.session.applyToolbarStyles();
|
|
14946
15294
|
this.onSetCommentsVisibility(!!this.model.comments.length);
|
|
14947
15295
|
this.search = new Search(editorService);
|
|
14948
|
-
this.subscriptions.push(this.changedEdgeSizeSubscription(), this.changedEdgeSubscription(), this.changedTableSizeSubscription(), this.
|
|
15296
|
+
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());
|
|
14949
15297
|
}
|
|
14950
15298
|
destroy() {
|
|
14951
15299
|
this.subscriptions.forEach(s => s?.unsubscribe());
|
|
@@ -15005,9 +15353,6 @@ class Editor {
|
|
|
15005
15353
|
const y = rect.top + cursor.pageY + cursor.height;
|
|
15006
15354
|
this.overlayService.open(component, { textKey }, x, y);
|
|
15007
15355
|
}
|
|
15008
|
-
cut() {
|
|
15009
|
-
this.removeSelected();
|
|
15010
|
-
}
|
|
15011
15356
|
insert(text) {
|
|
15012
15357
|
const sanitizedText = text.replace(this.emojiRegex, ' ');
|
|
15013
15358
|
if (this.selection.isEmpty) {
|
|
@@ -15039,6 +15384,11 @@ class Editor {
|
|
|
15039
15384
|
this.onSelectionChange();
|
|
15040
15385
|
this.onContentChange();
|
|
15041
15386
|
}
|
|
15387
|
+
insertSlice(sliceData) {
|
|
15388
|
+
const slice = sliceData.data;
|
|
15389
|
+
const revisionId = sliceData.source.revisionId;
|
|
15390
|
+
this.editorService.requestContentsInsertion(slice, revisionId);
|
|
15391
|
+
}
|
|
15042
15392
|
removeLeft() {
|
|
15043
15393
|
if (this.selection.isEmpty) {
|
|
15044
15394
|
this.selection.selectLeft(this.session);
|
|
@@ -15481,7 +15831,7 @@ class Editor {
|
|
|
15481
15831
|
command = SaveCommandsHelper.getInsertTextCommand(text, insertIndex, this.targets);
|
|
15482
15832
|
}
|
|
15483
15833
|
else if (operation instanceof DeleteModel) {
|
|
15484
|
-
this.session.removeByDocumentIndexes(operation.startIndex, operation.startIndex + operation.count);
|
|
15834
|
+
this.session.removeByDocumentIndexes(operation.startIndex, operation.startIndex + operation.count - 1);
|
|
15485
15835
|
command = SaveCommandsHelper.getDeleteCommand(operation.startIndex, operation.count, this.targets);
|
|
15486
15836
|
}
|
|
15487
15837
|
else if (operation instanceof InsertStyledTextModel) {
|
|
@@ -15676,6 +16026,16 @@ class Editor {
|
|
|
15676
16026
|
this.session.applyNewNumberingForParagraphs(operation.levels, operation.insertIndexes);
|
|
15677
16027
|
command = SaveCommandsHelper.getApplyNewNumberingForParagraphsCommand(operation.insertIndexes, operation.levels, this.targets);
|
|
15678
16028
|
}
|
|
16029
|
+
else if (operation instanceof InsertContentsModel) {
|
|
16030
|
+
const deepCopy = structuredClone(operation.contents);
|
|
16031
|
+
this.session.insertContents(operation.insertIndex, deepCopy);
|
|
16032
|
+
command = SaveCommandsHelper.getInsertContentsCommand(operation, this.targets);
|
|
16033
|
+
}
|
|
16034
|
+
else if (operation instanceof ReplaceByContentsModel) {
|
|
16035
|
+
const deepCopy = structuredClone(operation.contents);
|
|
16036
|
+
this.session.replaceByContents(operation.startIndex, operation.count, deepCopy);
|
|
16037
|
+
command = SaveCommandsHelper.getReplaceByContentsModel(operation, this.targets);
|
|
16038
|
+
}
|
|
15679
16039
|
else {
|
|
15680
16040
|
throw new Error('Undo/redo is not implemented for the Operation');
|
|
15681
16041
|
}
|
|
@@ -15806,6 +16166,22 @@ class Editor {
|
|
|
15806
16166
|
this.history.pushMoveRange(undoModel, redoModel, sourceRange);
|
|
15807
16167
|
this.commandsService.createCommand(SaveCommandsHelper.getMoveRangeCommand(redoModel, []));
|
|
15808
16168
|
}
|
|
16169
|
+
saveInsertContentsToHistory(redoModel) {
|
|
16170
|
+
const startIndex = redoModel.insertIndex;
|
|
16171
|
+
const undoModel = new DeleteModel({ startIndex, count: redoModel.contents.content.length });
|
|
16172
|
+
this.history.pushInsertContents(undoModel, redoModel);
|
|
16173
|
+
this.commandsService.createCommand(SaveCommandsHelper.getInsertContentsCommand(redoModel, this.targets));
|
|
16174
|
+
}
|
|
16175
|
+
saveReplaceByContentsToHistory(redoModel) {
|
|
16176
|
+
const undoSlice = ContentsOperationsHelper.GetRelativeContentSlice(this.session.model, redoModel.startIndex, redoModel.count);
|
|
16177
|
+
const undoModel = new ReplaceByContentsModel({
|
|
16178
|
+
startIndex: redoModel.startIndex,
|
|
16179
|
+
contents: undoSlice,
|
|
16180
|
+
count: redoModel.contents.content.length
|
|
16181
|
+
});
|
|
16182
|
+
this.history.pushReplaceByContents(undoModel, redoModel);
|
|
16183
|
+
this.commandsService.createCommand(SaveCommandsHelper.getReplaceByContentsModel(redoModel, this.targets));
|
|
16184
|
+
}
|
|
15809
16185
|
saveReplaceToHistory(range, model) {
|
|
15810
16186
|
const restoreModel = this.session.createRestoreFromSlice(range.start, range.end);
|
|
15811
16187
|
this.history.pushReplace(restoreModel, model);
|
|
@@ -15949,29 +16325,42 @@ class Editor {
|
|
|
15949
16325
|
this.showInsertOverlay(text);
|
|
15950
16326
|
}
|
|
15951
16327
|
onCut(event) {
|
|
15952
|
-
|
|
15953
|
-
const
|
|
15954
|
-
if (!
|
|
16328
|
+
const text = this.getSelectedText();
|
|
16329
|
+
const slice = this.getSelectedSlice();
|
|
16330
|
+
if (!text && !slice) {
|
|
15955
16331
|
return;
|
|
15956
16332
|
}
|
|
15957
|
-
this.editorService.
|
|
15958
|
-
this.
|
|
15959
|
-
this.cut();
|
|
16333
|
+
this.clipboardHandler.copyEvent(event, text, slice, this.editorService.revisionId);
|
|
16334
|
+
this.removeSelected();
|
|
15960
16335
|
this.scrollCursorIntoMainView();
|
|
16336
|
+
this.editorService.setClipboardData(text);
|
|
15961
16337
|
}
|
|
15962
16338
|
onCopy(event) {
|
|
15963
|
-
|
|
15964
|
-
const
|
|
15965
|
-
if (!
|
|
16339
|
+
const text = this.getSelectedText();
|
|
16340
|
+
const slice = this.getSelectedSlice();
|
|
16341
|
+
if (!text && !slice) {
|
|
15966
16342
|
return;
|
|
15967
16343
|
}
|
|
15968
|
-
this.editorService.
|
|
15969
|
-
this.
|
|
16344
|
+
this.clipboardHandler.copyEvent(event, text, slice, this.editorService.revisionId);
|
|
16345
|
+
this.editorService.setClipboardData(text);
|
|
15970
16346
|
}
|
|
15971
16347
|
onPaste(event) {
|
|
15972
|
-
|
|
15973
|
-
|
|
15974
|
-
|
|
16348
|
+
const { text, sliceData } = this.clipboardHandler.readEvent(event);
|
|
16349
|
+
if (sliceData) {
|
|
16350
|
+
this.pasteData(text, sliceData);
|
|
16351
|
+
return;
|
|
16352
|
+
}
|
|
16353
|
+
this.clipboardHandler // If slice not found in event should check navigation clipboard for data.
|
|
16354
|
+
.readAsync()
|
|
16355
|
+
.then(asyncData => {
|
|
16356
|
+
if (text === asyncData.text && asyncData.sliceData) {
|
|
16357
|
+
this.pasteData(asyncData.text, asyncData.sliceData);
|
|
16358
|
+
}
|
|
16359
|
+
else if (text) {
|
|
16360
|
+
this.pasteData(text, null);
|
|
16361
|
+
}
|
|
16362
|
+
})
|
|
16363
|
+
.catch(() => { });
|
|
15975
16364
|
}
|
|
15976
16365
|
onCreateComment(commentType) {
|
|
15977
16366
|
const { startIndex, endIndex } = ContentHelper.getSelectedPartDocumentIndexes(this.session.displayData.paragraphs, this.selection.range);
|
|
@@ -15990,8 +16379,8 @@ class Editor {
|
|
|
15990
16379
|
this.commentCreateRequests = this.commentCreateRequests.filter(x => x.reqId !== reqId);
|
|
15991
16380
|
commentModel.commentId = commentId;
|
|
15992
16381
|
sessionModel.session.addComment(commentModel);
|
|
15993
|
-
|
|
15994
|
-
sessionModel.renderer.
|
|
16382
|
+
this.mainRenderer.setSelectedComment(commentModel.commentId);
|
|
16383
|
+
sessionModel.renderer.scheduleChanges({ commentHighlights: true });
|
|
15995
16384
|
this.saveAttachCommentToHistory(commentModel);
|
|
15996
16385
|
}
|
|
15997
16386
|
onCommentRemoved(id) {
|
|
@@ -16000,7 +16389,7 @@ class Editor {
|
|
|
16000
16389
|
session.renderer.removeComment(id);
|
|
16001
16390
|
this.saveRemoveCommentToHistory(comment, session.source.getTarget());
|
|
16002
16391
|
this.editorService.removeCommentData([id]);
|
|
16003
|
-
session.renderer.
|
|
16392
|
+
session.renderer.scheduleChanges({ commentHighlights: true });
|
|
16004
16393
|
}
|
|
16005
16394
|
onCommentTextReplace(commentId, newText) {
|
|
16006
16395
|
const { session, comment } = this.regulatorService.getComment(commentId);
|
|
@@ -16033,7 +16422,7 @@ class Editor {
|
|
|
16033
16422
|
window.removeEventListener('resize', this.rerenderResize);
|
|
16034
16423
|
}
|
|
16035
16424
|
rerenderMarker() {
|
|
16036
|
-
this.renderer.
|
|
16425
|
+
this.renderer.scheduleChanges({ marker: true });
|
|
16037
16426
|
}
|
|
16038
16427
|
onBlur() {
|
|
16039
16428
|
if (!this.textInput.isFocused) {
|
|
@@ -16279,6 +16668,19 @@ class Editor {
|
|
|
16279
16668
|
this.onSelectionChange();
|
|
16280
16669
|
this.onContentChange();
|
|
16281
16670
|
}
|
|
16671
|
+
insertContent(insertIndex, contents) {
|
|
16672
|
+
const insertContents = new InsertContentsModel({ insertIndex, contents });
|
|
16673
|
+
this.saveInsertContentsToHistory(insertContents);
|
|
16674
|
+
this.session.insertContents(insertIndex, structuredClone(contents));
|
|
16675
|
+
this.onSelectionChange();
|
|
16676
|
+
}
|
|
16677
|
+
replaceByContents(startIndex, endIndex, contents) {
|
|
16678
|
+
const count = endIndex - startIndex + 1;
|
|
16679
|
+
const replaceByContents = new ReplaceByContentsModel({ startIndex, count, contents });
|
|
16680
|
+
this.saveReplaceByContentsToHistory(replaceByContents);
|
|
16681
|
+
this.session.replaceByContents(startIndex, count, structuredClone(contents));
|
|
16682
|
+
this.onSelectionChange();
|
|
16683
|
+
}
|
|
16282
16684
|
moveRange(model) {
|
|
16283
16685
|
this.regulatorService.setTargetedSessionAsCurrent(model.targetTargets);
|
|
16284
16686
|
const sourceSession = this.regulatorService.getTargetedSession(model.sourceTargets);
|
|
@@ -16362,6 +16764,13 @@ class Editor {
|
|
|
16362
16764
|
});
|
|
16363
16765
|
return textInterval;
|
|
16364
16766
|
}
|
|
16767
|
+
getSelectedSlice() {
|
|
16768
|
+
const selectionRange = this.selection.selectedRange;
|
|
16769
|
+
if (selectionRange.isEmpty) {
|
|
16770
|
+
return null;
|
|
16771
|
+
}
|
|
16772
|
+
return this.session.getContentsSlice(selectionRange.start, selectionRange.end);
|
|
16773
|
+
}
|
|
16365
16774
|
initMainSession() {
|
|
16366
16775
|
const pageWidth = this.customPageWidth ?? Math.max(...this.model.pageFormats.map(x => x.pageWidth));
|
|
16367
16776
|
this.container.nativeElement.style.maxWidth = `${pageWidth}px`;
|
|
@@ -16371,7 +16780,7 @@ class Editor {
|
|
|
16371
16780
|
this.editorService.paragraphStyle(this.model.paragraphs[0].paragraphStyle);
|
|
16372
16781
|
this.regulatorService.addMainSession(this.model, scalingRatio, this.container);
|
|
16373
16782
|
}
|
|
16374
|
-
onSelectionChange() {
|
|
16783
|
+
onSelectionChange(isMouseSelection = false) {
|
|
16375
16784
|
this.session.applyToolbarStyles();
|
|
16376
16785
|
this.renderer.updateSelection(this.selection.selectedRange);
|
|
16377
16786
|
if (this.selection.isEmpty) {
|
|
@@ -16387,7 +16796,7 @@ class Editor {
|
|
|
16387
16796
|
this.editorService.setPageFormat(pageFormat.pageFormatModel);
|
|
16388
16797
|
this.rerenderMarker();
|
|
16389
16798
|
this.regulatorService.setSelectedCommentAtCursor();
|
|
16390
|
-
if (!this.selection.isEmpty && this.commentsVisible) {
|
|
16799
|
+
if (!this.selection.isEmpty && this.commentsVisible && !isMouseSelection) {
|
|
16391
16800
|
const paragraphPos = this.session.selection.cursor;
|
|
16392
16801
|
const cursor = PositionHelper.paragraphToPixel(this.session, paragraphPos.row, paragraphPos.column);
|
|
16393
16802
|
const mainRect = this.mainRenderer.container.getBoundingClientRect();
|
|
@@ -16398,7 +16807,7 @@ class Editor {
|
|
|
16398
16807
|
}
|
|
16399
16808
|
}
|
|
16400
16809
|
onContentChange() {
|
|
16401
|
-
this.renderer.
|
|
16810
|
+
this.renderer.scheduleChanges({ commentHighlights: true });
|
|
16402
16811
|
if (this.search.term) {
|
|
16403
16812
|
this.find(this.search.term);
|
|
16404
16813
|
}
|
|
@@ -16502,7 +16911,7 @@ class Editor {
|
|
|
16502
16911
|
const cursor = this.selection.cursor;
|
|
16503
16912
|
this.selection.moveSelection(position);
|
|
16504
16913
|
if (cursor.column !== this.selection.cursor.column || cursor.row !== this.selection.cursor.row) {
|
|
16505
|
-
this.onSelectionChange();
|
|
16914
|
+
this.onSelectionChange(true);
|
|
16506
16915
|
}
|
|
16507
16916
|
this.scrollCursorIntoMainView();
|
|
16508
16917
|
}
|
|
@@ -16603,7 +17012,7 @@ class Editor {
|
|
|
16603
17012
|
viewOnlyModeSubscription() {
|
|
16604
17013
|
return this.editorService.isViewOnly$.subscribe(() => {
|
|
16605
17014
|
this.selection?.clearSelection();
|
|
16606
|
-
this.renderer.
|
|
17015
|
+
this.renderer.scheduleChanges({ grammar: true });
|
|
16607
17016
|
});
|
|
16608
17017
|
}
|
|
16609
17018
|
applyLeftMarginPageFormatSubscription() {
|
|
@@ -16846,49 +17255,59 @@ class Editor {
|
|
|
16846
17255
|
}
|
|
16847
17256
|
cutSelectedSubscription() {
|
|
16848
17257
|
return this.editorService.cutSelected$.subscribe(() => {
|
|
16849
|
-
this.
|
|
17258
|
+
const text = this.getSelectedText();
|
|
17259
|
+
const slice = this.getSelectedSlice();
|
|
17260
|
+
if (!text && !slice) {
|
|
17261
|
+
return;
|
|
17262
|
+
}
|
|
17263
|
+
this.clipboardHandler.copyAsync(text, slice, this.editorService.revisionId).catch(() => { });
|
|
17264
|
+
this.removeSelected();
|
|
17265
|
+
this.scrollCursorIntoMainView();
|
|
17266
|
+
this.editorService.setClipboardData(text);
|
|
16850
17267
|
});
|
|
16851
17268
|
}
|
|
16852
17269
|
copySelectedSubscription() {
|
|
16853
17270
|
return this.editorService.copySelected$.subscribe(() => {
|
|
16854
|
-
this.
|
|
17271
|
+
const text = this.getSelectedText();
|
|
17272
|
+
const slice = this.getSelectedSlice();
|
|
17273
|
+
if (!text && !slice) {
|
|
17274
|
+
return;
|
|
17275
|
+
}
|
|
17276
|
+
this.clipboardHandler.copyAsync(text, slice, this.editorService.revisionId).catch(() => { });
|
|
17277
|
+
this.editorService.setClipboardData(text);
|
|
16855
17278
|
});
|
|
16856
17279
|
}
|
|
16857
17280
|
pasteFromClipboardSubscription() {
|
|
16858
|
-
return this.editorService.pasteFromClipboard
|
|
16859
|
-
this.
|
|
16860
|
-
|
|
16861
|
-
|
|
16862
|
-
// continue regardless error
|
|
16863
|
-
});
|
|
17281
|
+
return this.editorService.pasteFromClipboard$
|
|
17282
|
+
.pipe(switchMap(() => from(this.clipboardHandler.readAsync())))
|
|
17283
|
+
.subscribe(({ text, sliceData }) => {
|
|
17284
|
+
this.pasteData(text, sliceData);
|
|
16864
17285
|
});
|
|
16865
17286
|
}
|
|
16866
|
-
|
|
16867
|
-
|
|
16868
|
-
|
|
16869
|
-
|
|
16870
|
-
|
|
16871
|
-
|
|
16872
|
-
|
|
16873
|
-
|
|
16874
|
-
|
|
16875
|
-
|
|
16876
|
-
|
|
16877
|
-
|
|
17287
|
+
pasteData(text, sliceData) {
|
|
17288
|
+
if (sliceData) {
|
|
17289
|
+
this.insertSlice(sliceData);
|
|
17290
|
+
}
|
|
17291
|
+
else if (text) {
|
|
17292
|
+
const insertText = text.replace(/\r\n/g, '\n').replace(/\t/g, ' ');
|
|
17293
|
+
this.insert(insertText);
|
|
17294
|
+
this.scrollCursorIntoMainView();
|
|
17295
|
+
}
|
|
17296
|
+
}
|
|
17297
|
+
insertContentsSubscription() {
|
|
17298
|
+
return this.editorService.insertContents$.subscribe(contents => {
|
|
17299
|
+
const start = this.selection.range.start;
|
|
17300
|
+
const startIndex = ContentHelper.paragraphToDocumentIndex(this.session.displayData.paragraphs, start.row, start.column);
|
|
17301
|
+
if (this.selection.isEmpty) {
|
|
17302
|
+
this.insertContent(startIndex, contents);
|
|
16878
17303
|
}
|
|
16879
17304
|
else {
|
|
16880
|
-
|
|
17305
|
+
const end = this.selection.range.end;
|
|
17306
|
+
const endIndex = ContentHelper.paragraphToDocumentIndex(this.session.displayData.paragraphs, end.row, end.column) - 1;
|
|
17307
|
+
this.replaceByContents(startIndex, endIndex, contents);
|
|
16881
17308
|
}
|
|
16882
17309
|
});
|
|
16883
17310
|
}
|
|
16884
|
-
pasteData(data) {
|
|
16885
|
-
if (!data) {
|
|
16886
|
-
return;
|
|
16887
|
-
}
|
|
16888
|
-
const text = data.replace(/\r\n/g, '\n').replace(/\t/g, ' ');
|
|
16889
|
-
this.insert(text);
|
|
16890
|
-
this.scrollCursorIntoMainView();
|
|
16891
|
-
}
|
|
16892
17311
|
selectAllSubscription() {
|
|
16893
17312
|
return this.editorService.selectAll$.subscribe(() => {
|
|
16894
17313
|
this.selection.selectAll(this.session.model);
|
|
@@ -16900,11 +17319,6 @@ class Editor {
|
|
|
16900
17319
|
this.removeSelected();
|
|
16901
17320
|
});
|
|
16902
17321
|
}
|
|
16903
|
-
clipboardDataSubscription() {
|
|
16904
|
-
return this.editorService.clipboardData$.subscribe(data => {
|
|
16905
|
-
this.clipboardData = data;
|
|
16906
|
-
});
|
|
16907
|
-
}
|
|
16908
17322
|
commandCreatedForEdges() {
|
|
16909
17323
|
return this.commandsService.createCommand$
|
|
16910
17324
|
.pipe(filter(x => !!x.targets.find(y => !!y.edgeData)))
|
|
@@ -16931,7 +17345,7 @@ class Editor {
|
|
|
16931
17345
|
];
|
|
16932
17346
|
}
|
|
16933
17347
|
rerenderCommentsSubscription() {
|
|
16934
|
-
return this.editorService.commentSizeChanged$.subscribe(() => this.mainRenderer.
|
|
17348
|
+
return this.editorService.commentSizeChanged$.subscribe(() => this.mainRenderer.scheduleChanges({ comments: true }));
|
|
16935
17349
|
}
|
|
16936
17350
|
selectCommentSubscription() {
|
|
16937
17351
|
return this.editorService.setCommentSelected$.subscribe(x => this.regulatorService.setSelectedComment(x));
|