UNPKG

@syncfusion/ej2-documenteditor

Version:

Feature-rich document editor control with built-in support for context menu, options pane and dialogs.

891 lines 220 kB
import { WParagraphFormat } from '../format/paragraph-format'; import { WSectionFormat } from '../format/section-format'; import { WCharacterFormat } from '../format/character-format'; import { WListFormat } from '../format/list-format'; import { HistoryInfo } from '../index'; import { ModifiedLevel, RowHistoryFormat, TableHistoryInfo } from './history-helper'; import { BlockWidget, ParagraphWidget, BodyWidget, TableCellWidget, FieldElementBox, TableWidget, TableRowWidget, BookmarkElementBox, HeaderFooterWidget, CheckBoxFormField, TextFrame, TextElementBox, FootnoteElementBox, ImageElementBox } from '../viewer/page'; import { Dictionary } from '../../base/dictionary'; import { abstractListsProperty, listIdProperty, listsProperty, nsidProperty } from '../../index'; import { TextPosition, ImageSizeInfo } from '../index'; import { isNullOrUndefined } from '@syncfusion/ej2-base'; import { ElementBox, CommentCharacterElementBox } from '../viewer/page'; import { WTableFormat, WRowFormat, WCellFormat, WParagraphStyle } from '../format/index'; import { HelperMethods } from '../editor/editor-helper'; import { CONTROL_CHARACTERS } from '../../base/types'; // Code for Comparing the offset calculated using old approach and optimized approach // /** // * @private // */ // export class MyError extends Error { // constructor(message: string) { // super(message); // } // } // export function throwCustomError(condition: boolean, message: string) { // if (condition) { // throw new MyError(message); // } // } /** * @private */ var BaseHistoryInfo = /** @class */ (function () { function BaseHistoryInfo(node) { this.cellOperation = []; this.splittedRevisions = []; this.isRemovedNodes = false; this.modifiedFormatOperation = []; this.revisionOperation = []; /** * @private */ this.markerData = []; this.ownerIn = node; this.documentHelper = node.documentHelper; this.modifiedPropertiesIn = []; this.modifiedNodeLength = []; this.removedNodesIn = []; this.insertedNodes = []; } Object.defineProperty(BaseHistoryInfo.prototype, "owner", { //Properties //gets owner control get: function () { return this.ownerIn; }, enumerable: true, configurable: true }); Object.defineProperty(BaseHistoryInfo.prototype, "editorHistory", { get: function () { return this.owner.editorHistoryModule; }, enumerable: true, configurable: true }); Object.defineProperty(BaseHistoryInfo.prototype, "action", { get: function () { return this.actionIn; }, set: function (value) { this.actionIn = value; if (this.owner.enableCollaborativeEditing && !this.editorHistory.isUndoing && this.cellOperation.length == 0) { if (value === 'DeleteColumn' || value === 'DeleteCells' || value === 'ClearCells' || value === 'MergeCells') { if (!(this.owner.selectionModule.isTableSelected(true) || this.owner.selectionModule.isRowSelect()) || value === 'ClearCells' || value === 'MergeCells') { this.insertedText = CONTROL_CHARACTERS.Cell; this.deleteColumnOperation(this.action); } } else if (value === 'Accept Change' || value === 'Reject Change') { this.createAcceptRejectOperation(this.action); } else if (value === 'SectionBreak') { this.insertedText = CONTROL_CHARACTERS.Section_Break; this.type = "NewPage"; } else if (value === 'SectionBreakContinuous') { this.insertedText = CONTROL_CHARACTERS.Section_Break; this.type = "Continuous"; } } }, enumerable: true, configurable: true }); Object.defineProperty(BaseHistoryInfo.prototype, "modifiedProperties", { get: function () { return this.modifiedPropertiesIn; }, enumerable: true, configurable: true }); Object.defineProperty(BaseHistoryInfo.prototype, "removedNodes", { /* eslint-enable */ get: function () { return this.removedNodesIn; }, enumerable: true, configurable: true }); Object.defineProperty(BaseHistoryInfo.prototype, "selectionStart", { //gets or sets selection start get: function () { return this.selectionStartIn; }, set: function (value) { this.selectionStartIn = value; }, enumerable: true, configurable: true }); Object.defineProperty(BaseHistoryInfo.prototype, "selectionEnd", { get: function () { return this.selectionEndIn; }, set: function (value) { this.selectionEndIn = value; }, enumerable: true, configurable: true }); Object.defineProperty(BaseHistoryInfo.prototype, "insertPosition", { get: function () { return this.insertPositionIn; }, set: function (value) { this.insertPositionIn = value; if (this.owner.enableCollaborativeEditing && !this.owner.editorModule.isRemoteAction && value !== '' && !isNullOrUndefined(value) && value.indexOf('C') === -1) { //TODO: Insert position not needed in all the cases. Need to optimize it. this.insertIndex = this.owner.selectionModule.getAbsolutePositionFromRelativePosition(value); // Code for Comparing the offset calculated using old approach and optimized approach // this.owner.selection.isNewApproach = true; // this.newInsertIndex = this.owner.selection.getAbsolutePositionFromRelativePosition(value); // this.owner.selection.isNewApproach = false; // throwCustomError(this.newInsertIndex !== this.insertIndex, "New InsertIndex " + this.newInsertIndex + " and old insertIndex " + this.insertIndex + " doesnot match"); } }, enumerable: true, configurable: true }); Object.defineProperty(BaseHistoryInfo.prototype, "endPosition", { get: function () { return this.endPositionIn; }, set: function (value) { this.endPositionIn = value; }, enumerable: true, configurable: true }); Object.defineProperty(BaseHistoryInfo.prototype, "viewer", { get: function () { return this.ownerIn.viewer; }, enumerable: true, configurable: true }); BaseHistoryInfo.prototype.updateSelection = function () { this.updateCollaborativeSelection(); var blockInfo = this.owner.selectionModule.getParagraphInfo(this.owner.selectionModule.start); this.selectionStart = this.owner.selectionModule.getHierarchicalIndex(blockInfo.paragraph, blockInfo.offset.toString()); blockInfo = this.owner.selectionModule.getParagraphInfo(this.owner.selectionModule.end); this.selectionEnd = this.owner.selectionModule.getHierarchicalIndex(blockInfo.paragraph, blockInfo.offset.toString()); }; BaseHistoryInfo.prototype.updateCollaborativeSelection = function () { if (this.owner.enableCollaborativeEditing && !this.owner.editorModule.isRemoteAction) { //TODO: Need to consider formard and backward selection var start = void 0; var end = void 0; if (this.action == 'RemoveEditRange') { var startEdit = this.owner.selectionModule.getEditRangeStartElement(); var position = this.owner.selectionModule.getPosition(startEdit); start = position.startPosition; end = position.endPosition; } else { start = this.owner.selectionModule.start.clone(); end = this.owner.selectionModule.end.clone(); this.updateTableSelection(start, end); } this.startIndex = this.owner.selectionModule.getAbsolutePositionFromRelativePosition(start); // Code for Comparing the offset calculated using old approach and optimized approach // this.owner.selection.isNewApproach = true; // this.newStartIndex = this.owner.selection.getAbsolutePositionFromRelativePosition(start); // this.owner.selection.isNewApproach = false; this.owner.selectionModule.isEndOffset = true; this.endIndex = this.owner.selectionModule.getAbsolutePositionFromRelativePosition(end); // Code for Comparing the offset calculated using old approach and optimized approach // this.owner.selection.isNewApproach = true; // this.newEndIndex = this.owner.selection.getAbsolutePositionFromRelativePosition(end); // this.owner.selection.isNewApproach = false; this.owner.selectionModule.isEndOffset = false; var isForward = this.owner.selectionModule.isForward; if (isForward) { this.startIndex -= this.owner.selectionModule.getTableRelativeValue(start, end); } else { this.endIndex -= this.owner.selectionModule.getTableRelativeValue(end, start); } if (this.action === 'BackSpace' || this.action === 'Delete') { var isParagraphStart = isForward ? (start.paragraph.equals(end.paragraph) && start.isAtParagraphStart) : (start.paragraph.equals(end.paragraph) && end.isAtParagraphStart); if ((isParagraphStart || !start.paragraph.equals(end.paragraph))) { if (isForward) { this.endIndex += this.paraInclude(end); } else { this.startIndex += this.paraInclude(start); } } } this.splitOperationForDelete(start, end); // Code for Comparing the offset calculated using old approach and optimized approach // throwCustomError(this.newStartIndex !== this.startIndex, "New StartIndex " + this.newStartIndex + " and old StartIndex " + this.startIndex + " doesnot match"); // throwCustomError(this.newEndIndex !== this.endIndex, "New EndIndex " + this.newEndIndex + " and old EndIndex " + this.endIndex + " doesnot match"); } }; BaseHistoryInfo.prototype.paraInclude = function (position) { var paragrapthInfo = this.owner.selectionModule.getParagraphInfo(position); if (position.paragraph.getTotalLength() < paragrapthInfo.offset) { if (!(position.paragraph.isInsideTable && position.paragraph.equals(position.paragraph.associatedCell.lastChild))) { return 1; } } return 0; }; /** * This method will set position when the multple cell selected. */ BaseHistoryInfo.prototype.updateTableSelection = function (startPosition, endPosition) { var start = startPosition; var end = endPosition; if (!this.owner.selectionModule.isForward) { start = endPosition; end = startPosition; } if (start.paragraph.isInsideTable) { var firstPara = this.owner.selectionModule.getFirstParagraph(start.paragraph.associatedCell); if (end.paragraph.isInsideTable) { if (!start.paragraph.associatedCell.equals(end.paragraph.associatedCell)) { var lastPara = this.owner.selectionModule.getLastParagraph(end.paragraph.associatedCell); start.setPosition(firstPara.firstChild, true); end.setPositionParagraph(lastPara.lastChild, lastPara.lastChild.getEndOffset() + 1); } } else { start.setPosition(firstPara.firstChild, true); } } else if (end.paragraph.isInsideTable) { var lastPara = this.owner.selectionModule.getLastParagraph(end.paragraph.associatedCell); end.setPositionParagraph(lastPara.lastChild, lastPara.lastChild.getEndOffset() + 1); } }; /** * start is para and end is in row. */ BaseHistoryInfo.prototype.splitOperationForDelete = function (startPosition, endPosition) { // when start is para and end is row. we are building the operation like: // fisrt delete the end table from table start to selection end. // second need to paste the content from the start para and need to paste it in the next row. // third delete the start paragraph to before wiget of end table. var start = startPosition; var end = endPosition; if (!this.owner.selectionModule.isForward) { start = endPosition; end = startPosition; } if (!start.paragraph.isInsideTable && end.paragraph.isInsideTable && (this.action === 'BackSpace' || this.action === 'Delete')) { var lastParagraph = this.owner.selectionModule.getLastBlockInLastCell(end.paragraph.associatedCell.ownerTable); if (!lastParagraph.associatedCell.equals(end.paragraph.associatedCell)) { var PasteLength = this.startIndex; var endLineWidget = start.currentWidget; var endOffset = start.offset; start.setPosition(start.paragraph.firstChild, true); this.startIndex = this.owner.selectionModule.getAbsolutePositionFromRelativePosition(start); var startIndex = this.startIndex; var table = this.owner.documentHelper.layout.getParentTable(end.paragraph.associatedCell.ownerTable); var paragraphInfo = { 'paragraph': null, 'offset': 0 }; var tableStart = this.owner.selectionModule.getPositionInfoForHeaderFooter(paragraphInfo, { position: 0, done: false }, table).position; // Table start will get the offset for table. So adding plus one to row offset. this.startIndex = tableStart + 1; this.cellOperation.push(this.getDeleteOperation(this.action)); // This will add the paste content in first and first cell so adding plus 3. this.startIndex = tableStart + 3; if (endOffset !== 0) { this.pasteContent = this.owner.sfdtExportModule.write((this.owner.documentEditorSettings.optimizeSfdt ? 1 : 0), start.currentWidget, start.offset, endLineWidget, endOffset, false, true); this.cellOperation.push(this.getPasteOpertion(this.pasteContent, PasteLength - startIndex)); } this.endIndex = tableStart; this.startIndex = startIndex; this.cellOperation.push(this.getDeleteOperation(this.action)); } } if (this.action === 'PasteColumn' || this.action === 'PasteOverwrite' || this.action === 'PasteRow') { //when inserting new colomn in paste. first deleting the table and inserting the whole table. var table = startPosition.paragraph.associatedCell.ownerTable; var paragraphInfo = { 'paragraph': null, 'offset': 0 }; this.startIndex = this.owner.selectionModule.getPositionInfoForHeaderFooter(paragraphInfo, { position: 0, done: false }, table).position; this.endIndex = this.startIndex + this.owner.selectionModule.getBlockLength(undefined, table, 0, { done: false }, true, undefined, undefined); } }; BaseHistoryInfo.prototype.setBookmarkInfo = function (bookmark) { this.removedNodes.push({ 'bookmark': bookmark, 'startIndex': bookmark.indexInOwner, 'endIndex': bookmark.reference.indexInOwner }); }; BaseHistoryInfo.prototype.setFormFieldInfo = function (field, value) { this.removedNodes.push({ 'formField': field, 'value': value }); }; BaseHistoryInfo.prototype.setEditRangeInfo = function (editStart) { this.removedNodes.push({ 'editStart': editStart, 'startIndex': editStart.indexInOwner, 'endIndex': editStart.editRangeEnd.indexInOwner }); }; BaseHistoryInfo.prototype.revertFormTextFormat = function () { /* eslint-disable @typescript-eslint/no-explicit-any */ var fieldInfo = this.removedNodes[0]; var text = fieldInfo.value; /* eslint-enable @typescript-eslint/no-explicit-any */ var formField = fieldInfo.formField; if (this.editorHistory.isUndoing) { this.owner.editorModule.applyTextFormatInternal(formField, text); this.editorHistory.recordChanges(this); } else { text = HelperMethods.formatText(formField.formFieldData.format, text); this.owner.editorModule.applyTextFormatInternal(formField, text); this.editorHistory.undoStack.push(this); } }; BaseHistoryInfo.prototype.revertFormField = function () { /* eslint-disable @typescript-eslint/no-explicit-any */ var fieldInfo = this.removedNodes[0]; /* eslint-enable @typescript-eslint/no-explicit-any */ var field = fieldInfo.formField; if (field.formFieldData instanceof CheckBoxFormField) { this.owner.editorModule.toggleCheckBoxFormField(field, true, fieldInfo.value); } else { this.owner.editorModule.updateFormField(field, fieldInfo.value); } }; BaseHistoryInfo.prototype.revertBookmark = function () { var bookmarkInfo = this.removedNodes[0]; var bookmark = bookmarkInfo.bookmark; if (this.editorHistory.isUndoing) { var markerData = this.owner.editorModule.getMarkerData(bookmark); this.documentHelper.bookmarks.add(bookmark.name, bookmark); this.markerData.push(markerData); bookmark.line.children.splice(bookmarkInfo.startIndex, 0, bookmark); var previousNode = bookmark.previousNode; if (previousNode instanceof FieldElementBox && !isNullOrUndefined(previousNode.formFieldData)) { previousNode.formFieldData.name = bookmark.name; } this.markerData.push(markerData); bookmark.reference.line.children.splice(bookmarkInfo.endIndex, 0, bookmark.reference); this.editorHistory.recordChanges(this); if (this.owner.documentEditorSettings.showBookmarks == true) { this.viewer.updateScrollBars(); } this.owner.editorModule.fireContentChange(); } else { this.owner.editorModule.deleteBookmarkInternal(bookmark); this.editorHistory.undoStack.push(this); } }; BaseHistoryInfo.prototype.revertComment = function () { var editPosition = this.insertPosition; var comment = this.removedNodes[0]; var insert = false; if (this.action === 'ResolveComment') { this.editorHistory.currentBaseHistoryInfo = this; this.owner.editorModule.resolveOrReopenComment(comment, !comment.isResolved); return; } if (this.action === 'EditComment') { var modifiedCommentObject = this.modifiedProperties[0]; this.editorHistory.currentBaseHistoryInfo = this; var commentView = this.owner.commentReviewPane.commentPane.comments.get(comment); commentView.commentText.innerText = modifiedCommentObject.text; modifiedCommentObject.text = comment.text; comment.text = commentView.commentText.innerText; this.owner.editorHistoryModule.updateHistory(); this.owner.fireContentChange(); return; } if (this.action === 'InsertCommentWidget') { insert = (this.editorHistory.isRedoing); } else if (this.action === 'DeleteCommentWidget') { insert = (this.editorHistory.isUndoing); } if (insert) { if (comment) { this.insertedElement = comment.clone(); if (comment.isReply) { this.owner.editorModule.addReplyComment(comment, this.insertPosition); } else { this.owner.editorModule.addCommentWidget(comment, false, true, true); } } } else { var commentElement = this.owner.editorModule.getCommentElementBox(editPosition); this.owner.editorModule.deleteCommentWidget(commentElement); } }; BaseHistoryInfo.prototype.revertEditRangeRegion = function () { var editRangeInfo = this.removedNodes[0]; var editStart = editRangeInfo.editStart; if (this.editorHistory.isUndoing) { var user = editStart.user === '' ? editStart.group : editStart.user; this.owner.editorModule.updateRangeCollection(editStart, user); this.markerData.push(this.owner.editorModule.getMarkerData(editStart)); this.markerData.push(this.owner.editorModule.getMarkerData(editStart.editRangeEnd)); editStart.line.children.splice(editRangeInfo.startIndex, 0, editStart); editStart.editRangeEnd.line.children.splice(editRangeInfo.endIndex, 0, editStart.editRangeEnd); this.editorHistory.recordChanges(this); } else { this.owner.editorModule.removeUserRestrictionsInternal(editStart); this.editorHistory.undoStack.push(this); } this.owner.editorModule.fireContentChange(); }; /* eslint-disable */ BaseHistoryInfo.prototype.revert = function () { if (this.action === 'FormTextFormat') { this.revertFormTextFormat(); return; } if (this.action === 'UpdateFormField') { this.revertFormField(); return; } if (this.action === 'DeleteBookmark') { this.revertBookmark(); return; } if (this.action === 'RemoveEditRange') { this.revertEditRangeRegion(); return; } if (this.action === 'InsertCommentWidget' || this.action === 'DeleteCommentWidget' || this.action === 'ResolveComment' || this.action === 'EditComment') { this.revertComment(); return; } if (this.action === 'ListFormat' && this.owner.editorModule.listNumberFormat !== '') { var abstractList = this.documentHelper.lists[0].abstractList.levels[this.owner.editorModule.listLevelNumber]; var currentListLevelPattern = abstractList.listLevelPattern; var currentNUmberFormat = abstractList.numberFormat; abstractList.listLevelPattern = this.owner.editorModule.listLevelPattern; abstractList.numberFormat = this.owner.editorModule.listNumberFormat; this.owner.editorModule.listLevelPattern = currentListLevelPattern; this.owner.editorModule.listNumberFormat = currentNUmberFormat; } this.owner.isShiftingEnabled = true; var selectionStartTextPosition = undefined; var selectionEndTextPosition = undefined; var start = this.selectionStart; var end = this.selectionEnd; this.collabStart = this.selectionStart; this.collabEnd = this.selectionEnd; if (this.owner.enableCollaborativeEditing) { if (!isNullOrUndefined(this.insertPosition)) { this.insertIndex = this.owner.selectionModule.getAbsolutePositionFromRelativePosition(this.insertPosition); } if (!isNullOrUndefined(this.endPosition)) { this.updateCollaborativeSelection(); } this.startIndex = this.insertIndex; } var isForwardSelection = TextPosition.isForwardSelection(start, end); if (this.modifiedProperties.length > 0 || this.action === 'Selection' || this.action === 'ClearCharacterFormat' || this.action === 'ClearParagraphFormat') { selectionStartTextPosition = this.owner.selectionModule.getTextPosBasedOnLogicalIndex(start); selectionEndTextPosition = this.owner.selectionModule.getTextPosBasedOnLogicalIndex(end); this.revertModifiedProperties(selectionStartTextPosition, selectionEndTextPosition); } else { var sel = this.owner.selectionModule; var deletedNodes = this.removedNodes; if (this.removedNodes.length > 0) { if (this.action === 'InsertTable' && this.editorHistory.isRedoing) { for (var i = 0; i < this.removedNodes.length; i++) { this.insertedNodes.push(this.removedNodes[parseInt(i.toString(), 10)]); } } this.isRemovedNodes = true; } this.removedNodesIn = []; if (isNullOrUndefined(this.endPosition)) { this.endPosition = this.insertPosition; } var isForward = TextPosition.isForwardSelection(this.insertPosition, this.endPosition); var insertTextPosition = sel.getTextPosBasedOnLogicalIndex(isForward ? this.insertPosition : this.endPosition); var endTextPosition = sel.getTextPosBasedOnLogicalIndex(isForward ? this.endPosition : this.insertPosition); // Set the endRevisionLogicalIndex based on undo stack value when the selection contains a table with the above paragraph (undoing). if (this.action === 'RemoveRowTrack' && this.editorHistory.isUndoing) { this.owner.selectionModule.select(this.selectionEnd, this.selectionEnd); if (this.owner.selectionModule.start.paragraph.isInsideTable) { this.endRevisionLogicalIndex = this.selectionEnd; } } if (this.editorHistory.isUndoing) { if (this.lastElementRevision && isNullOrUndefined(this.endRevisionLogicalIndex)) { this.updateEndRevisionInfo(); } else if (this.action === 'RemoveRowTrack') { this.endRevisionLogicalIndex = this.selectionEnd; } } if (this.action === 'ClearRevisions') { this.undoRevisionForElements(insertTextPosition, endTextPosition, deletedNodes[deletedNodes.length - 1]); this.removedNodes.push(deletedNodes[deletedNodes.length - 1]); deletedNodes = []; } if (this.action === 'Uppercase') { sel.selectPosition(insertTextPosition, endTextPosition); this.editorHistory.currentBaseHistoryInfo = this; var editModule = this.owner.editorModule; editModule.changeSelectedTextCase(sel, insertTextPosition, endTextPosition, this.action.toString(), deletedNodes); editModule.reLayout(sel); return; } if (this.action === 'Lowercase') { sel.selectPosition(insertTextPosition, endTextPosition); this.editorHistory.currentBaseHistoryInfo = this; var editModule = this.owner.editorModule; editModule.changeSelectedTextCase(sel, insertTextPosition, endTextPosition, this.action.toString(), deletedNodes); editModule.reLayout(sel); return; } if (this.action === 'CapitalizeEachWord') { sel.selectPosition(insertTextPosition, endTextPosition); this.editorHistory.currentBaseHistoryInfo = this; var editModule = this.owner.editorModule; editModule.changeSelectedTextCase(sel, insertTextPosition, endTextPosition, this.action.toString(), deletedNodes); editModule.reLayout(sel); return; } if (this.action === 'SentenceCase') { sel.selectPosition(insertTextPosition, endTextPosition); this.editorHistory.currentBaseHistoryInfo = this; var editModule = this.owner.editorModule; editModule.changeSelectedTextCase(sel, insertTextPosition, endTextPosition, this.action.toString(), deletedNodes); editModule.reLayout(sel); return; } if (this.action === 'ToggleCase') { sel.selectPosition(insertTextPosition, endTextPosition); this.editorHistory.currentBaseHistoryInfo = this; var editModule = this.owner.editorModule; editModule.changeSelectedTextCase(sel, insertTextPosition, endTextPosition, this.action.toString(), deletedNodes); editModule.reLayout(sel); return; } if (insertTextPosition.isAtSamePosition(endTextPosition)) { sel.selectContent(insertTextPosition, true); } else { sel.selectPosition(insertTextPosition, endTextPosition); } if (this.action === 'InsertHyperlink' && this.editorHistory.isRedoing) { var fieldBegin = this.owner.selectionModule.getHyperlinkField(); if (!isNullOrUndefined(fieldBegin)) { var offset = (fieldBegin.line).getOffset(fieldBegin, 0); insertTextPosition.setPositionParagraph(fieldBegin.line, offset); this.owner.selectionModule.start.setPositionInternal(insertTextPosition); offset = fieldBegin.fieldEnd.line.getOffset(fieldBegin.fieldEnd, 1); endTextPosition.setPositionParagraph(fieldBegin.fieldEnd.line, offset); } } this.editorHistory.currentBaseHistoryInfo = this; this.selectionStart = this.insertPosition; this.insertPosition = undefined; this.selectionEnd = this.endPosition; this.endPosition = undefined; // Use this property to skip deletion if already selected content deleted case. var isRemoveContent = false; if (this.endRevisionLogicalIndex && deletedNodes.length > 0) { if (this.editorHistory.isUndoing || (this.editorHistory.isRedoing && insertTextPosition.isAtSamePosition(endTextPosition))) { var currentPosition = sel.getTextPosBasedOnLogicalIndex(this.endRevisionLogicalIndex); sel.selectPosition(insertTextPosition, currentPosition); if (this.owner.enableCollaborativeEditing) { this.endIndex = this.owner.selectionModule.getAbsolutePositionFromRelativePosition(currentPosition); } } if (this.editorHistory.isUndoing) { this.owner.editorModule.deleteSelectedContents(sel, true); isRemoveContent = true; } } if (!insertTextPosition.isAtSamePosition(endTextPosition) && !isRemoveContent) { isRemoveContent = this.action === 'BackSpace' || this.action === 'Delete' || this.action === 'ClearCells' || this.action === 'DeleteCells'; var skipDelete = (deletedNodes.length > 0 && this.action === 'ParaMarkTrack') || this.action === 'ClearRevisions' || this.action === 'AcceptTOC'; if (!(isRemoveContent) && this.action !== 'MergeCells' && this.action !== 'InsertRowAbove' && this.action !== 'InsertRowBelow' && this.action !== 'InsertColumnLeft' && this.action !== 'InsertColumnRight' && this.action !== 'Borders' && this.action !== 'DeleteTable' && this.action !== 'DeleteColumn' && this.action !== 'DeleteRow') { sel.end.setPositionInternal(endTextPosition); if (!this.owner.selectionModule.isEmpty && !skipDelete) { if (this.editorHistory.isRedoing && this.action !== 'Accept Change' && this.action !== 'ParaMarkTrack' && this.action !== 'ParaMarkReject' && this.action !== 'RemoveRowTrack') { this.owner.editorModule.removeSelectedContents(sel); } else { this.owner.editorModule.deleteSelectedContents(sel, true); } if (!isNullOrUndefined(this.editorHistory.currentHistoryInfo) && this.editorHistory.currentHistoryInfo.action === 'PageBreak' && this.documentHelper.blockToShift) { this.documentHelper.layout.shiftLayoutedItems(false); } } } } else if (this.action === 'SectionBreakContinuous' && insertTextPosition && this.editorHistory.isUndoing) { if (insertTextPosition.offset === 0 && !isNullOrUndefined(insertTextPosition.paragraph.previousRenderedWidget) && insertTextPosition.paragraph.previousRenderedWidget instanceof ParagraphWidget && insertTextPosition.paragraph.previousRenderedWidget.isEndsWithPageBreak && insertTextPosition.paragraph.containerWidget instanceof BodyWidget && insertTextPosition.currentWidget === insertTextPosition.currentWidget.paragraph.firstChild && insertTextPosition.paragraph.containerWidget.sectionFormat.breakCode === 'NoBreak') { var section = insertTextPosition.paragraph.previousRenderedWidget.containerWidget; this.owner.editorModule.combineSectionInternal(this.owner.selectionModule, section, insertTextPosition.paragraph.containerWidget); this.owner.editorModule.layoutWholeDocument(); } } else { isRemoveContent = false; if (!insertTextPosition.isAtSamePosition(endTextPosition)) { isRemoveContent = this.action === 'BackSpace' || this.action === 'Delete' || this.action === 'ClearCells' || this.action === 'DeleteCells'; } } var isRedoAction = (this.editorHistory.isRedoing && !isRemoveContent); isRemoveContent = this.lastElementRevision ? false : isRemoveContent; this.revertModifiedNodes(deletedNodes, isRedoAction, isForwardSelection ? start : end, start === end); // Use this property to delete table or cell based on history action. var isDeletecell = false; if (this.action === 'DeleteCells') { isDeletecell = true; } if (isRemoveContent) { this.removeContent(insertTextPosition, endTextPosition, isDeletecell); } //this.owner.editorModule.reLayout(this.documentHelper.selection); } var isSelectionChanged = false; var updateSelection = false; if (!isNullOrUndefined(this.editorHistory.currentHistoryInfo) && (this.editorHistory.currentHistoryInfo.action === 'Reject All' || this.editorHistory.currentHistoryInfo.action === 'Accept All' || this.editorHistory.currentHistoryInfo.action === 'Paste')) { updateSelection = true; } if (!this.owner.trackChangesPane.isTrackingPageBreak && ((this.editorHistory.isUndoing || this.endRevisionLogicalIndex || this.action === 'RemoveRowTrack' || updateSelection) && isNullOrUndefined(this.editorHistory.currentHistoryInfo) || updateSelection) || ((this.action === 'InsertRowAbove' || this.action === 'Borders' || this.action === 'InsertRowBelow' || this.action === 'InsertColumnLeft' || this.action === 'InsertColumnRight' || this.action === 'Accept Change' || this.action === 'PasteColumn' || this.action === 'PasteRow' || this.action === 'PasteOverwrite' || this.action === 'PasteNested') && (this.editorHistory.isRedoing || this.editorHistory.currentHistoryInfo.action === 'Paste'))) { if (this.action === 'RemoveRowTrack' && this.editorHistory.isRedoing) { selectionStartTextPosition = this.owner.selectionModule.getTextPosBasedOnLogicalIndex(this.selectionStart); selectionEndTextPosition = this.owner.selectionModule.getTextPosBasedOnLogicalIndex(this.selectionEnd); } else { selectionStartTextPosition = this.owner.selectionModule.getTextPosBasedOnLogicalIndex(start); selectionEndTextPosition = this.owner.selectionModule.getTextPosBasedOnLogicalIndex(end); } this.owner.selectionModule.selectRange(selectionStartTextPosition, selectionEndTextPosition); this.documentHelper.updateFocus(); isSelectionChanged = true; } this.owner.trackChangesPane.isTrackingPageBreak = false; var index = this.insertIndex; // Updates insert position of history info instance. this.insertPosition = start; this.endPosition = end; if (this.action === 'InsertHyperlink') { this.insertIndex = index; } if (!isNullOrUndefined(this.editorHistory.currentHistoryInfo) && (this.editorHistory.currentHistoryInfo.action === 'Accept All' || this.editorHistory.currentHistoryInfo.action === 'Reject All' || this.editorHistory.currentHistoryInfo.action === 'RemoveComment')) { if (this.owner.documentHelper.blockToShift) { this.owner.documentHelper.layout.shiftLayoutedItems(false); } } this.owner.editorModule.reLayout(this.owner.selectionModule, this.owner.selectionModule.isEmpty); if (this.editorHistory.isUndoing && this.action === 'SectionBreak') { this.owner.editorModule.isSkipOperationsBuild = true; this.owner.editorModule.layoutWholeDocument(); this.owner.editorModule.isSkipOperationsBuild = false; } if (isSelectionChanged) { this.documentHelper.scrollToPosition(this.owner.selectionModule.start, this.owner.selectionModule.end); } this.highlightListText(); }; BaseHistoryInfo.prototype.highlightListText = function () { if (!isNullOrUndefined(this.editorHistory.currentHistoryInfo)) { if (this.action === 'ListCharacterFormat' || (this.editorHistory.currentHistoryInfo.action === 'ListSelect' && this.action === 'ListFormat')) { var selectionStartTextPosition = this.owner.selectionModule.getTextPosBasedOnLogicalIndex(this.selectionStart); var widget = selectionStartTextPosition.currentWidget; this.documentHelper.selection.highlightListText(widget); } } }; BaseHistoryInfo.prototype.removeContent = function (insertTextPosition, endTextPosition, isDeletecell) { //If the base parent of the insert text position and end text position is null //then the paragraphs already removed. //Example scenario: In table editing that is delete cells operation // we will backed up the entire table ad it will be replaced on undo operation. //At that time if the positions are in table //which is already replaced in undo (revert modified nodes method) then the base parent of the paragraph will be null. //So again, selecting the content and deleting is unnecessary // and it will cause improper position updates and null reference exceptions. if ((!isNullOrUndefined(insertTextPosition.paragraph.containerWidget) && insertTextPosition.paragraph.containerWidget instanceof BodyWidget && (!isNullOrUndefined(endTextPosition.paragraph.containerWidget) && endTextPosition.paragraph.containerWidget instanceof BodyWidget)) || (!isNullOrUndefined(insertTextPosition.paragraph.containerWidget) && !isNullOrUndefined(endTextPosition.paragraph.containerWidget) && insertTextPosition.paragraph.containerWidget instanceof TableCellWidget && endTextPosition.paragraph.containerWidget instanceof TableCellWidget && !isNullOrUndefined(insertTextPosition.paragraph.bodyWidget)) || (!isNullOrUndefined(insertTextPosition.paragraph.containerWidget) && !isNullOrUndefined(endTextPosition.paragraph.containerWidget) && insertTextPosition.paragraph.containerWidget instanceof TextFrame && endTextPosition.paragraph.containerWidget instanceof TextFrame)) { //Removes if any empty paragraph is added while delete. this.owner.selectionModule.selectRange(insertTextPosition, endTextPosition); this.documentHelper.updateFocus(); var isDelete = false; if (this.action === 'BackSpace' || this.action === 'Uppercase' || this.action === 'RemoveRowTrack') { isDelete = true; } this.owner.editorModule.deleteSelectedContents(this.owner.selectionModule, isDelete, isDeletecell); } }; BaseHistoryInfo.prototype.updateEndRevisionInfo = function () { this.lastElementRevision = this.checkAdjacentNodeForMarkedRevision(this.lastElementRevision); var currentRevision = this.retrieveEndPosition(this.lastElementRevision); var blockInfo = this.owner.selectionModule.getParagraphInfo(currentRevision); if (blockInfo.paragraph.getLength() == blockInfo.offset && !blockInfo.paragraph.isInsideTable) { blockInfo.offset++; } this.endRevisionLogicalIndex = this.owner.selectionModule.getHierarchicalIndex(blockInfo.paragraph, blockInfo.offset.toString()); this.lastElementRevision.isMarkedForRevision = false; }; BaseHistoryInfo.prototype.retrieveEndPosition = function (elementBox) { var endPosition = new TextPosition(this.owner); var offset = elementBox.line.getOffset(elementBox, 0) + elementBox.length; endPosition.setPositionFromLine(elementBox.line, offset); return endPosition; }; /** * Method to retrieve exact spitted node which is marked as last available element. * * @param {ElementBox} elementBox - Specifies the element box * @returns {ElementBox} - Returns element box */ BaseHistoryInfo.prototype.checkAdjacentNodeForMarkedRevision = function (elementBox) { var nextItem = elementBox.nextNode; var markedNode; while (!isNullOrUndefined(nextItem) && nextItem.isMarkedForRevision) { markedNode = nextItem; nextItem = nextItem.nextNode; } return !isNullOrUndefined(markedNode) ? markedNode : elementBox; }; BaseHistoryInfo.prototype.revertModifiedProperties = function (start, end) { if (this.action === 'CellFormat' || this.action === 'CellOptions' || this.action === 'TableOptions') { this.owner.isShiftingEnabled = false; } this.owner.selectionModule.selectRange(start, end); this.documentHelper.updateFocus(); if (this.action === 'RowResizing' || this.action === 'CellResizing') { this.revertResizing(); } else if (this.action === 'CellOptions' || this.action === 'TableOptions') { this.revertTableDialogProperties(this.action); } else if (this.action !== 'Selection') { this.revertProperties(); } }; // Redoes the Action BaseHistoryInfo.prototype.redoAction = function () { var editor = this.owner.editorModule; this.action = this.action; switch (this.action) { case 'BackSpace': editor.singleBackspace(this.owner.selectionModule, true); break; case 'Delete': editor.singleDelete(this.owner.selectionModule, true); break; case 'DeleteTable': editor.deleteTable(); break; case 'DeleteColumn': editor.deleteColumn(); break; case 'DeleteRow': editor.deleteRow(); break; case 'MergeCells': editor.mergeSelectedCellsInTable(); break; case 'InsertRowAbove': editor.insertRow(true); break; case 'InsertRowBelow': editor.insertRow(false); break; case 'InsertColumnLeft': editor.insertColumn(true); break; case 'InsertColumnRight': editor.insertColumn(true); break; case 'SectionBreak': editor.insertSection(this.owner.selectionModule, true); break; case 'SectionBreakContinuous': editor.insertSection(this.owner.selectionModule, true, undefined, true); break; case 'TableAutoFitToContents': editor.autoFitTable('FitToContents'); break; case 'TableAutoFitToWindow': editor.autoFitTable('FitToWindow'); break; case 'TableFixedColumnWidth': editor.autoFitTable('FixedColumnWidth'); break; case 'RemoveRowTrack': this.owner.selectionModule.handleAcceptReject(true); break; } }; BaseHistoryInfo.prototype.revertModifiedNodes = function (deletedNodes, isRedoAction, start, isEmptySelection) { if (isRedoAction && (this.action === 'BackSpace' || this.action === 'Delete' || this.action === 'DeleteTable' || this.action === 'DeleteColumn' || this.action === 'DeleteRow' || this.action === 'InsertRowAbove' || this.action === 'InsertRowBelow' || this.action === 'InsertColumnLeft' || this.action === 'InsertColumnRight' || this.action === 'MergeCells' || this.action === 'SectionBreak' || this.action === 'SectionBreakContinuous' || this.action === 'TableAutoFitToContents' || this.action === 'TableAutoFitToWindow' || this.action === 'TableFixedColumnWidth' || this.action === 'PasteColumn' || this.action === 'PasteOverwrite' || this.action === 'PasteNested')) { this.redoAction(); if (this.action === 'SectionBreak' || this.action === 'SectionBreakContinuous') { return; } } if (deletedNodes.length > 0) { //tslint:disable-next-line:max-line-length if ((this.editorHistory.isUndoing && (this.action === 'RemoveRowTrack' || this.action === 'DeleteCells' || this.action === 'DeleteColumn' || this.action === 'DeleteRow' || this.action === 'MergeCells')) || (this.action === 'InsertRowAbove' || this.action === 'InsertRowBelow' || this.action === 'InsertColumnLeft' //tslint:disable-next-line:max-line-length || this.action === 'ClearCells' || this.action === 'InsertColumnRight' || this.action === 'Borders' || this.action === 'TableAutoFitToContents' || this.action === 'TableAutoFitToWindow' || this.action === 'TableFixedColumnWidth' || this.action === 'RemoveRowTrack' || this.action === 'PasteColumn' || this.action === 'PasteRow' || this.action === 'PasteOverwrite' || this.action === 'PasteNested')) { var insertIndex = this.selectionStart; var block = this.owner.editorModule.getBlock({ index: insertIndex }).node; var lastNode = deletedNodes[deletedNodes.length - 1]; if ((block instanceof TableWidget || block.previousRenderedWidget instanceof TableWidget || block.isInsideTable) && lastNode instanceof TableWidget) { if (block instanceof ParagraphWidget && !block.isInsideTable) { block = block.previousRenderedWidget; } else if (block instanceof ParagraphWidget && block.isInsideTable) { block = block.associatedCell.ownerTable; } block = block.combineWidget(this.viewer); if (this.owner.enableCollaborativeEditing) { var paragraphInfo = { 'paragraph': null, 'offset': 0 }; this.startIndex = this.owner.selectionModule.getPositionInfoForHeaderFooter(paragraphInfo, { position: 0, done: false }, block).position; this.endIndex = this.startIndex + this.owner.selectionModule.getBlockLength(undefined, block, 0, { done: false }, true, undefined, undefined); var operation = this.getDeleteOperation('Delete'); if (this.owner.enableTrackChanges) { if (isNullOrUndefined(operation.markerData)) { operation.markerData = {}; } operation.markerData.isSkipTracking = true; } this.cellOperation.push(operation); } this.owner.editorModule.insertTableInternal(block, lastNode, false); if (this.action === 'PasteColumn' || this.action === 'PasteRow' || this.action === 'PasteOverwrite' || this.action === 'PasteNested') { this.removedNodes.push(block); } else { d