UNPKG

@syncfusion/ej2-documenteditor

Version:

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

879 lines (878 loc) 190 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; /** * @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.editorHistory; }, 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.selection.isTableSelected(true) || this.owner.selection.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 && value !== '' && !isNullOrUndefined(value) && value.indexOf('C') === -1) { //TODO: Insert position not needed in all the cases. Need to optimize it. this.insertIndex = this.owner.selection.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 () { if (this.owner.enableCollaborativeEditing) { //TODO: Need to consider formard and backward selection var start = void 0; var end = void 0; if (this.action == 'RemoveEditRange') { var startEdit = this.owner.selection.getEditRangeStartElement(); var position = this.owner.selection.getPosition(startEdit); start = position.startPosition; end = position.endPosition; } else { start = this.owner.selection.start.clone(); end = this.owner.selection.end.clone(); this.updateTableSelection(start, end); } this.startIndex = this.owner.selection.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.selection.isEndOffset = true; this.endIndex = this.owner.selection.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.selection.isEndOffset = false; if (this.owner.selection.isForward) { this.startIndex -= this.owner.selection.getTableRelativeValue(start, end); } else { this.endIndex -= this.owner.selection.getTableRelativeValue(end, 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"); } var blockInfo = this.owner.selection.getParagraphInfo(this.owner.selection.start); this.selectionStart = this.owner.selection.getHierarchicalIndex(blockInfo.paragraph, blockInfo.offset.toString()); blockInfo = this.owner.selection.getParagraphInfo(this.owner.selection.end); this.selectionEnd = this.owner.selection.getHierarchicalIndex(blockInfo.paragraph, blockInfo.offset.toString()); }; BaseHistoryInfo.prototype.updateTableSelection = function (startPosition, endPosition) { var start = startPosition; var end = endPosition; if (!this.owner.selection.isForward) { start = endPosition; end = startPosition; } if (start.paragraph.isInsideTable) { var firstPara = this.owner.selection.getFirstParagraph(start.paragraph.associatedCell); if (end.paragraph.isInsideTable) { if (!start.paragraph.associatedCell.equals(end.paragraph.associatedCell)) { var lastPara = this.owner.selection.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.selection.getLastParagraph(end.paragraph.associatedCell); end.setPositionParagraph(lastPara.lastChild, lastPara.lastChild.getEndOffset() + 1); } }; BaseHistoryInfo.prototype.splitOperationForDelete = function (startPosition, endPosition) { var start = startPosition; var end = endPosition; if (!this.owner.selection.isForward) { start = endPosition; end = startPosition; } if (!start.paragraph.isInsideTable && end.paragraph.isInsideTable && (this.action === 'BackSpace' || this.action === 'Delete')) { var lastParagraph = this.owner.selection.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.selection.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.selection.getPositionInfoForHeaderFooter(paragraphInfo, { position: 0, done: false }, table).position; this.startIndex = tableStart + 1; this.cellOperation.push(this.getDeleteOperation(this.action)); 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)); } } }; 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.editor.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.editorHistory.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.editor.addReplyComment(comment, this.insertPosition); } else { this.owner.editor.addCommentWidget(comment, false, true, true); } } } else { var commentElement = this.owner.editor.getCommentElementBox(editPosition); this.owner.editor.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.editor.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.editor.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.editor.listNumberFormat !== '') { var abstractList = this.documentHelper.lists[0].abstractList.levels[this.owner.editor.listLevelNumber]; var currentListLevelPattern = abstractList.listLevelPattern; var currentNUmberFormat = abstractList.numberFormat; abstractList.listLevelPattern = this.owner.editor.listLevelPattern; abstractList.numberFormat = this.owner.editor.listNumberFormat; this.owner.editor.listLevelPattern = currentListLevelPattern; this.owner.editor.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) { //TODO: Need to consider formard and backward selection. this.insertIndex = this.owner.selection.getAbsolutePositionFromRelativePosition(this.insertPosition); this.startIndex = this.insertIndex; this.endIndex = this.owner.selection.getAbsolutePositionFromRelativePosition(this.endPosition); } var isForwardSelection = TextPosition.isForwardSelection(start, end); if (this.modifiedProperties.length > 0 || this.action === 'Selection' || this.action === 'ClearCharacterFormat' || this.action === 'ClearParagraphFormat') { selectionStartTextPosition = this.owner.selection.getTextPosBasedOnLogicalIndex(start); selectionEndTextPosition = this.owner.selection.getTextPosBasedOnLogicalIndex(end); this.revertModifiedProperties(selectionStartTextPosition, selectionEndTextPosition); } else { var sel = this.owner.selection; var deletedNodes = this.removedNodes; if (this.removedNodes.length > 0) { 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.selection.select(this.selectionEnd, this.selectionEnd); if (this.owner.selection.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]); 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 (insertTextPosition.isAtSamePosition(endTextPosition)) { sel.selectContent(insertTextPosition, true); } else { sel.selectPosition(insertTextPosition, endTextPosition); } if (this.action === 'InsertHyperlink' && this.editorHistory.isRedoing) { var fieldBegin = this.owner.selection.getHyperlinkField(); if (!isNullOrUndefined(fieldBegin)) { var offset = (fieldBegin.line).getOffset(fieldBegin, 0); insertTextPosition.setPositionParagraph(fieldBegin.line, offset); this.owner.selection.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; 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.editorHistory.isUndoing) { this.owner.editor.deleteSelectedContents(sel, true); } } if (!insertTextPosition.isAtSamePosition(endTextPosition)) { 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.selection.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.editor.combineSectionInternal(this.owner.selection, section, insertTextPosition.paragraph.containerWidget); this.owner.editorModule.layoutWholeDocument(); } } var isRedoAction = (this.editorHistory.isRedoing && !isRemoveContent); isRemoveContent = this.lastElementRevision ? false : isRemoveContent; this.revertModifiedNodes(deletedNodes, isRedoAction, isForwardSelection ? start : end, start === end); if (isRemoveContent) { this.removeContent(insertTextPosition, endTextPosition, true); } //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.selection.getTextPosBasedOnLogicalIndex(this.selectionStart); selectionEndTextPosition = this.owner.selection.getTextPosBasedOnLogicalIndex(this.selectionEnd); } else { selectionStartTextPosition = this.owner.selection.getTextPosBasedOnLogicalIndex(start); selectionEndTextPosition = this.owner.selection.getTextPosBasedOnLogicalIndex(end); } this.owner.selection.selectRange(selectionStartTextPosition, selectionEndTextPosition); this.documentHelper.updateFocus(); isSelectionChanged = true; } this.owner.trackChangesPane.isTrackingPageBreak = false; // Updates insert position of history info instance. this.insertPosition = start; this.endPosition = end; 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.selection, this.owner.selection.isEmpty); if (this.editorHistory.isUndoing && this.action === 'SectionBreak') { this.owner.editorModule.layoutWholeDocument(); } if (isSelectionChanged) { this.documentHelper.scrollToPosition(this.owner.selection.start, this.owner.selection.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.selection.getTextPosBasedOnLogicalIndex(this.selectionStart); var widget = selectionStartTextPosition.currentWidget; this.documentHelper.selection.highlightListText(widget); } } }; BaseHistoryInfo.prototype.removeContent = function (insertTextPosition, endTextPosition, skipDeletecell) { //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.selection.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.selection, isDelete, skipDeletecell); } }; BaseHistoryInfo.prototype.updateEndRevisionInfo = function () { this.lastElementRevision = this.checkAdjacentNodeForMarkedRevision(this.lastElementRevision); var currentRevision = this.retrieveEndPosition(this.lastElementRevision); var blockInfo = this.owner.selection.getParagraphInfo(currentRevision); if (blockInfo.paragraph.getLength() == blockInfo.offset && !blockInfo.paragraph.isInsideTable) { blockInfo.offset++; } this.endRevisionLogicalIndex = this.owner.selection.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.selection.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.selection, true); break; case 'Delete': editor.singleDelete(this.owner.selection, 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.selection, true); break; case 'SectionBreakContinuous': editor.insertSection(this.owner.selection, 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.selection.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.selection.getPositionInfoForHeaderFooter(paragraphInfo, { position: 0, done: false }, block).position; this.endIndex = this.startIndex + this.owner.selection.getBlockLength(undefined, block, 0, { done: false }, true, undefined, undefined); this.cellOperation.push(this.getDeleteOperation('Delete')); } 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 { deletedNodes.splice(deletedNodes.indexOf(lastNode), 1); } } else if (lastNode instanceof TableWidget && !(this.action === 'RemoveRowTrack')) { this.owner.editorModule.insertBlock(lastNode); } else { this.insertRemovedNodes(deletedNodes, deletedNodes[deletedNodes.length - 1]); } } else { var initialStart = start; var block = this.owner.editorModule.getBlock({ index: initialStart }).node; // initialStart = blockObj.position; if (deletedNodes.length > 0 && (this.action === 'BackSpace' && isEmptySelection || (!(block instanceof TableWidget) && !(block instanceof HeaderFooterWidget)))) { var lastNode = deletedNodes[0]; if (lastNode instanceof BodyWidget && !isNullOrUndefined(deletedNodes[1])) { lastNode = deletedNodes[1]; } if (this.action === 'TrackingPageBreak' || ((this.action === 'SectionBreak' || this.action === 'SectionBreakContinuous') && lastNode instanceof BodyWidget || !isNullOrUndefined(this.editorHistory.currentHistoryInfo) && this.editorHistory.currentHistoryInfo.action === 'PageBreak')) { lastNode = deletedNodes[1]; } if (lastNode instanceof WCharacterFormat) { var newParagraph = new ParagraphWidget(); newParagraph.characterFormat = lastNode; this.owner.editorModule.insertNewParagraphWidget(newParagraph, true); deletedNodes.splice(deletedNodes.indexOf(lastNode), 1); block = newParagraph; } if (lastNode instanceof ParagraphWidget && this.owner.selection.start.offset > 0) { this.owner.editorModule.insertNewParagraphWidget(lastNode, true); if (lastNode.characterFormat.removedIds.length > 0) { this.owner.editor.constructRevisionFromID(lastNode.characterFormat, undefined); } deletedNodes.splice(deletedNodes.indexOf(lastNode), 1); if (isNullOrUndefined(block)) { var nextBlock = this.documentHelper.selection.getNextParagraphBlock(lastNode.getSplitWidgets().pop()); this.owner.selection.getNextRenderedBlock(lastNode); var startParagraph = this.owner.selection.start.paragraph; if (nextBlock && startParagraph && startParagraph.bodyWidget instanceof BodyWidget && !startParagraph.isInsideTable && !this.owner.selection.isinEndnote && !this.owner.selection.isinFootnote && !startParagraph.bodyWidget.equals(nextBlock.bodyWidget)) { nextBlock = undefined; } if (isNullOrUndefined(nextBlock)) { //Sets the selection as starting of last paragraph. this.owner.selection.selectParagraphInternal(lastNode, true); } } } if (lastNode instanceof TableWidget && this.owner.selection.start.offset > 0) { var firstBlock = deletedNodes[deletedNodes.length - 1]; if (firstBlock instanceof ParagraphWidget) { this.owner.editorModule.insertNewParagraphWidget(firstBlock, true); deletedNodes.splice(deletedNodes.indexOf(firstBlock), 1); if (isNullOrUndefined(block)) { var nextBlock = this.documentHelper.selection.getNextParagraphBlock(firstBlock.getSplitWidgets().pop()); if (isNullOrUndefined(nextBlock)) { //Sets the selection as starting of last paragraph. this.owner.selection.selectParagraphInternal(firstBlock, true); } } } } } if (deletedNodes.length > 0) { var firstNode = deletedNodes[deletedNodes.length - 1]; if (block instanceof TableWidget) { block = block.combineWidget(this.viewer); if (firstNode instanceof TableWidget) { this.owner.editorModule.insertTableInternal(block, firstNode, true); deletedNodes.splice(deletedNodes.indexOf(firstNode), 1); this.insertPosition = start; var nextWidget = firstNode.getSplitWidgets().pop(); if (nextWidget.nextRenderedWidget instanceof TableWidget) { block = nextWidget.nextRenderedWidget; } else { initialStart = start; block = this.owner.editorModule.getBlock({ index: initialStart }).node; } } } //Checks if first node is paragraph and current insert position is paragraph end. if (firstNode instanceof ParagraphWidget && this.owner.selection.start.offset > 0 && this.owner.selection.start.offset === this.owner.selection.getLineLength(this.owner.selection.start.paragraph.lastChild)) { var editor = this.owner.editorModule; editor.insertNewParagraphWidget(firstNode, false); if (firstNode.characterFormat.removedIds.length > 0) { this.owner.editor.constructRevisionFromID(firstNode.characterFormat, undefined); } deletedNodes.splice(deletedNodes.indexOf(firstNode), 1); //Removes the intermediate empty paragraph instance. if (this.action !== 'Paste') { editor.removeBlock(this.owner.selection.start.paragraph); } var paragraph = this.documentHelper.selection.getNextParagraphBlock(firstNode.getSplitWidgets().pop()); if (!isNullOrUndefined(paragraph)) { this.owner.selection.selectParagraphInternal(paragraph, true); } }