@syncfusion/ej2-documenteditor
Version:
Feature-rich document editor control with built-in support for context menu, options pane and dialogs.
1,086 lines • 1.03 MB
JavaScript
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
import { TextPosition, ImageInfo } from '../selection/selection-helper';
import { ParagraphWidget, LineWidget, ElementBox, TextElementBox, Margin, ImageElementBox, BlockWidget, BlockContainer, BodyWidget, TableWidget, TableCellWidget, TableRowWidget, Widget, ListTextElementBox, BookmarkElementBox, HeaderFooterWidget, FieldTextElementBox, TabElementBox, EditRangeStartElementBox, EditRangeEndElementBox, CommentElementBox, CommentCharacterElementBox, CheckBoxFormField, DropDownFormField, TextFormField, ShapeElementBox, TextFrame, ContentControl, FootnoteElementBox, FootNoteWidget } from '../viewer/page';
import { WCharacterFormat } from '../format/character-format';
import { HelperMethods, Base64 } from './editor-helper';
import { isNullOrUndefined, Browser, classList, L10n } from '@syncfusion/ej2-base';
import { WParagraphFormat, WSectionFormat, WListFormat, WTableFormat, WRowFormat, WCellFormat, WBorder, WBorders, WTabStop } from '../index';
import { WList } from '../list/list';
import { WAbstractList } from '../list/abstract-list';
import { WListLevel } from '../list/list-level';
import { WLevelOverride } from '../list/level-override';
import { FieldElementBox } from '../viewer/page';
import { protectionTypeChangeEvent, imagesProperty, abstractListIdProperty } from '../../base/index';
import { SelectionCharacterFormat } from '../index';
import { PageLayoutViewer } from '../index';
import { WCharacterStyle } from '../format/style';
import { HistoryInfo } from '../editor-history/index';
import { TableResizer } from './table-resizer';
import { Dictionary } from '../../base/dictionary';
import { WParagraphStyle } from '../format/style';
import { CONTROL_CHARACTERS } from '../../base/types';
import { showSpinner, hideSpinner } from '@syncfusion/ej2-popups';
import { DialogUtility } from '@syncfusion/ej2-popups';
import { Revision } from '../track-changes/track-changes';
import { XmlHttpRequestHandler } from '../../base/ajax-helper';
import { beforeCommentActionEvent, trackChangeEvent, beforeXmlHttpRequestSend, internalStyleCollectionChange } from '../../base/index';
import { SectionBreakType } from '../../base/types';
import { sectionsProperty, commentsProperty, bidiProperty, revisionsProperty, lastParagraphMarkCopiedProperty, sectionFormatProperty, revisionIdProperty, contextualSpacingProperty, keepWithNextProperty, keepLinesTogetherProperty, widowControlProperty, outlineLevelProperty, numberFormatProperty, startAtProperty, paragraphFormatProperty, listsProperty, abstractListsProperty, listIdProperty, listLevelNumberProperty, leftIndentProperty, rightIndentProperty, firstLineIndentProperty, textAlignmentProperty, afterSpacingProperty, beforeSpacingProperty, lineSpacingProperty, lineSpacingTypeProperty, listFormatProperty, cellsProperty, rowsProperty, blocksProperty, listLevelPatternProperty, levelsProperty, stylesProperty, nameProperty } from '../../index';
import { SanitizeHtmlHelper } from '@syncfusion/ej2-base';
import { ChangesSingleView } from '../track-changes/track-changes-pane';
/**
* Editor module
*/
var Editor = /** @class */ (function () {
/**
* Initialize the editor module
*
* @param {DocumentHelper} documentHelper - Document helper
* @private
*/
function Editor(documentHelper) {
var _this = this;
this.nodes = [];
this.editHyperlinkInternal = false;
this.startParagraph = undefined;
this.endParagraph = undefined;
this.formFieldCounter = 1;
this.skipFieldDeleteTracking = false;
this.skipFootNoteDeleteTracking = false;
this.isForHyperlinkFormat = false;
this.isTrackingFormField = false;
this.isInsertText = false;
this.keywordIndex = 0;
/**
* @private
*/
this.isFootnoteElementRemoved = false;
/**
* @private
*/
this.isEndnoteElementRemoved = false;
/**
* @private
*/
this.handledEnter = false;
/**
* @private
*/
this.removeEditRange = false;
/**
* @private
*/
this.isRemoveRevision = false;
/**
* @private
*/
this.isFootNoteInsert = false;
/**
* @private
*/
this.isTableInsert = false;
/**
* @private
*/
this.isFootNote = false;
/**
* @private
*/
this.isHandledComplex = false;
/**
* @private
*/
this.isUserInsert = false;
/**
* @private
*/
this.tableResize = undefined;
/**
* @private
*/
this.tocStyles = {};
/**
* @private
*/
this.triggerPageSpellCheck = true;
/**
* @private
*/
this.chartType = false;
/**
* @private
*/
this.removedBookmarkElements = [];
/**
* @private
*/
this.removedEditRangeStartElements = [];
/**
* @private
*/
this.removedEditRangeEndElements = [];
/**
* @private
*/
this.tocBookmarkId = 0;
/**
* @private
*/
this.copiedData = undefined;
/**
* @private
*/
this.isPasteContentCheck = false;
this.pageRefFields = {};
this.delBlockContinue = false;
this.delBlock = undefined;
this.delSection = undefined;
/**
* @private
*/
this.isInsertingTOC = false;
this.editStartRangeCollection = [];
this.skipReplace = false;
this.skipTableElements = false;
this.editRangeID = [];
/**
* @private
*/
this.isImageInsert = false;
/**
* @private
*/
this.isSkipOperationsBuild = false;
/**
* @private
*/
this.revisionData = [];
/**
* @private
*/
this.splittedRevisions = [];
/**
* @private
*/
this.isSkipComments = false;
/**
* @private
*/
this.isRemoteAction = false;
/**
* @private
*/
this.listNumberFormat = '';
/**
* @private
*/
this.listLevelNumber = 0;
/**
* @private
*/
this.isXmlMapped = false;
this.combineLastBlock = false;
/* eslint-disable @typescript-eslint/no-explicit-any */
/**
* @private
*/
this.copiedContent = '';
/**
* @private
*/
this.copiedTextContent = '';
/**
* @private
*/
this.previousParaFormat = undefined;
this.previousCharFormat = undefined;
this.previousSectionFormat = undefined;
this.pasteTextPosition = undefined;
//public isSkipHistory: boolean = false;
/**
* @private
*/
this.isPaste = false;
/**
* @private
*/
this.isPasteListUpdated = false;
/**
* @private
*/
this.isHtmlPaste = false;
/**
* @private
*/
this.isInsertField = false;
/**
* @private
*/
this.isBordersAndShadingDialog = false;
/**
* @private
*/
this.pasteImageIndex = undefined;
/**
* @private
* @returns {void}
*/
this.onTextInputInternal = function () {
if (Browser.isDevice) {
var documentHelper = _this.documentHelper;
var nbsp = new RegExp(String.fromCharCode(160), 'g');
var lineFeed = new RegExp(String.fromCharCode(10), 'g');
documentHelper.prefix = documentHelper.prefix.replace(nbsp, ' ').replace(lineFeed, ' ');
var text = documentHelper.editableDiv.textContent.replace(nbsp, ' ').replace(lineFeed, ' ');
var textBoxText = text.substring(2);
if (documentHelper.isCompositionStart && documentHelper.isCompositionUpdated) {
documentHelper.isCompositionUpdated = false;
if (!documentHelper.owner.isReadOnlyMode && documentHelper.owner.isDocumentLoaded && _this.canEditContentControl) {
if (documentHelper.prefix.substring(2) !== textBoxText) {
if (_this.selection.isEmpty) {
/* eslint-disable-next-line max-len */
_this.selection.start.setPositionForLineWidget(documentHelper.selection.start.currentWidget, _this.selection.start.offset - (documentHelper.prefix.length - 2));
_this.handleTextInput(textBoxText);
documentHelper.prefix = '@' + String.fromCharCode(160) + textBoxText;
}
else {
_this.handleTextInput(textBoxText);
documentHelper.prefix = '@' + String.fromCharCode(160) + textBoxText;
}
}
}
return;
}
else if (documentHelper.isCompositionStart && documentHelper.isCompositionEnd && documentHelper.suffix === '') {
if (documentHelper.prefix.substring(2) !== textBoxText) {
if (_this.selection.isEmpty && documentHelper.isCompositionStart) {
documentHelper.isCompositionStart = false;
/* eslint-disable-next-line max-len */
_this.selection.start.setPositionForLineWidget(documentHelper.selection.start.currentWidget, _this.selection.start.offset - documentHelper.prefix.substring(2).length);
_this.selection.retrieveCurrentFormatProperties();
if (documentHelper.suffix === '' || textBoxText === '') {
_this.handleTextInput(textBoxText);
}
}
else if (!_this.selection.isEmpty) {
documentHelper.isCompositionStart = false;
_this.handleTextInput(textBoxText);
}
}
else if (textBoxText === '') {
documentHelper.isCompositionStart = false;
_this.handleBackKey();
}
else if (documentHelper.prefix.substring(2) === textBoxText && documentHelper.suffix === '') {
documentHelper.isCompositionStart = false;
_this.handleTextInput(' ');
}
documentHelper.isCompositionEnd = false;
return;
}
else if (documentHelper.isCompositionEnd || documentHelper.isCompositionStart && !documentHelper.isCompositionUpdated) {
if (textBoxText.length < documentHelper.prefix.length &&
/* eslint-disable-next-line max-len */
textBoxText === documentHelper.prefix.substring(2, documentHelper.prefix.length - 1) || documentHelper.editableDiv.innerText.length < 2) {
_this.handleBackKey();
return;
}
else if (documentHelper.suffix !== '' &&
documentHelper.editableDiv.innerText[documentHelper.editableDiv.innerText.length - 1] !== String.fromCharCode(160)) {
documentHelper.isCompositionStart = false;
//When cursor is placed in between a word and chosen a word from predicted words.
/* eslint-disable-next-line max-len */
_this.selection.start.setPositionForLineWidget(documentHelper.selection.start.currentWidget, _this.selection.start.offset - (documentHelper.prefix.length - 2));
/* eslint-disable-next-line max-len */
_this.selection.end.setPositionForLineWidget(documentHelper.selection.end.currentWidget, _this.selection.end.offset + documentHelper.suffix.length);
//Retrieve the character format properties. Since the selection was changed manually.
_this.selection.retrieveCurrentFormatProperties();
_this.handleTextInput(textBoxText);
return;
}
}
if (text !== '\r' && text !== '\b' && text !== String.fromCharCode(27) && !documentHelper.owner.isReadOnlyMode && documentHelper.isControlPressed === false && _this.canEditContentControl) {
if (text === '@' || text[0] !== '@' || text === '' || text.length < documentHelper.prefix.length &&
textBoxText === documentHelper.prefix.substring(2, documentHelper.prefix.length - 1)) {
_this.handleBackKey();
if (documentHelper.editableDiv.innerText.length < 2) {
_this.predictText();
}
}
else if (text.indexOf(documentHelper.prefix) === 0 && text.length > documentHelper.prefix.length) {
_this.handleTextInput(text.substring(documentHelper.prefix.length));
}
else if (text.indexOf(documentHelper.prefix) === -1 && text[text.length - 1] !== String.fromCharCode(160)
&& text[text.length - 1] !== ' ') {
if ((textBoxText.charAt(0).toLowerCase() + textBoxText.slice(1)) === documentHelper.prefix.substring(2)) {
/* eslint-disable-next-line max-len */
_this.selection.start.setPositionParagraph(documentHelper.selection.start.currentWidget, _this.selection.start.offset - (documentHelper.prefix.length - 2));
}
_this.handleTextInput(textBoxText);
}
else if (text.length !== 2) {
_this.handleTextInput(' ');
}
}
}
else {
var text = _this.documentHelper.editableDiv.innerText;
if (text !== String.fromCharCode(160)) {
if (text !== '\r' && text !== '\b' && text !== String.fromCharCode(27) && !_this.owner.isReadOnlyMode && _this.documentHelper.isControlPressed === false && _this.canEditContentControl) {
_this.handleTextInput(text);
}
}
else {
_this.handleTextInput(' ');
}
_this.documentHelper.editableDiv.innerText = '';
}
};
/**
* Fired on paste.
*
* @param {ClipboardEvent} event - Specfies clipboard event
* @private
* @returns {void}
*/
this.onPaste = function (event) {
if (!_this.owner.isReadOnlyMode && _this.canEditContentControl) {
_this.pasteInternal(event);
}
event.preventDefault();
};
this.documentHelper = documentHelper;
if (!isNullOrUndefined(this.documentHelper)) {
this.tableResize = new TableResizer(this.documentHelper.owner);
}
this.base64 = new Base64();
}
Object.defineProperty(Editor.prototype, "restrictFormatting", {
/**
* @private
* @returns {boolean} - Returns the restrict formatting
*/
get: function () {
return this.documentHelper.isDocumentProtected && (this.documentHelper.restrictFormatting
|| (!this.documentHelper.restrictFormatting && !this.selection.isSelectionInEditRegion()))
&& this.documentHelper.protectionType !== 'RevisionsOnly';
},
enumerable: true,
configurable: true
});
Object.defineProperty(Editor.prototype, "restrictEditing", {
/**
* @private
* @returns {boolean} - Returns the restrict editing
*/
get: function () {
return this.documentHelper.isDocumentProtected && ((this.documentHelper.protectionType === 'ReadOnly' || this.documentHelper.isCommentOnlyMode)
&& !this.selection.isSelectionInEditRegion() || this.documentHelper.protectionType === 'FormFieldsOnly');
},
enumerable: true,
configurable: true
});
Object.defineProperty(Editor.prototype, "canEditContentControl", {
/**
* @private
* @returns {boolean} - Returns the can edit content control.
*/
get: function () {
if (this.owner.isReadOnlyMode) {
return false;
}
if (this.selection.checkContentControlLocked()) {
return false;
}
return true;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Editor.prototype, "viewer", {
get: function () {
if (!isNullOrUndefined(this.owner)) {
return this.owner.viewer;
}
return undefined;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Editor.prototype, "editorHistory", {
get: function () {
return this.documentHelper.owner.editorHistory;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Editor.prototype, "selection", {
get: function () {
if (this.documentHelper) {
return this.documentHelper.selection;
}
return undefined;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Editor.prototype, "owner", {
get: function () {
return this.documentHelper.owner;
},
enumerable: true,
configurable: true
});
Editor.prototype.getModuleName = function () {
return 'Editor';
};
/**
* Sets the field information for the selected field.
*
* @param { FieldInfo } fieldInfo – Specifies the field information.
* @returns {void}
* > Nested field gets replaced completely with the specified field information.
*/
Editor.prototype.setFieldInfo = function (fieldInfo) {
var field = this.selection.getHyperlinkField(true);
if (!isNullOrUndefined(field)) {
this.selection.selectField();
this.insertField(fieldInfo.code, fieldInfo.result);
}
};
/**
* Inserts the specified field at cursor position.
*
* @param {string} code Specify the field code.
* @param {string} result Specify the field result.
* @returns {void}
*/
Editor.prototype.insertField = function (code, result) {
code = HelperMethods.sanitizeString(code);
if (!isNullOrUndefined(result)) {
result = HelperMethods.sanitizeString(result);
}
this.isInsertField = true;
var fieldCode = code;
fieldCode = HelperMethods.trimStart(fieldCode);
if (fieldCode.substring(0, 8) === 'NUMPAGES') {
this.insertPageCount(result);
}
else if (fieldCode.substring(0, 4) === 'PAGE') {
this.insertPageNumber(result);
}
else {
if (isNullOrUndefined(result)) {
if (fieldCode.substring(0, 10) === 'MERGEFIELD') {
fieldCode = fieldCode.substring(10).trim();
var index = fieldCode.indexOf('\\*');
result = '«' + fieldCode.substring(0, index).trim() + '»';
}
}
var paragraph = new ParagraphWidget();
var insertFormat = new WCharacterFormat();
var selectionFormat = this.copyInsertFormat(insertFormat, false);
var line = new LineWidget(paragraph);
var fieldBegin = new FieldElementBox(0);
fieldBegin.characterFormat.mergeFormat(selectionFormat);
line.children.push(fieldBegin);
var fieldCodeSpan = new TextElementBox();
fieldCodeSpan.characterFormat.mergeFormat(selectionFormat);
fieldCodeSpan.text = code;
line.children.push(fieldCodeSpan);
var fieldSeparator = new FieldElementBox(2);
fieldSeparator.characterFormat.mergeFormat(selectionFormat);
fieldSeparator.fieldBegin = fieldBegin;
fieldBegin.fieldSeparator = fieldSeparator;
line.children.push(fieldSeparator);
var fieldResultSpan = new TextElementBox();
fieldResultSpan.text = result;
fieldResultSpan.characterFormat.mergeFormat(selectionFormat);
line.children.push(fieldResultSpan);
var fieldEnd = new FieldElementBox(1);
fieldEnd.characterFormat.mergeFormat(selectionFormat);
fieldEnd.fieldSeparator = fieldSeparator;
fieldEnd.fieldBegin = fieldBegin;
fieldBegin.fieldEnd = fieldEnd;
fieldSeparator.fieldEnd = fieldEnd;
line.children.push(fieldEnd);
fieldBegin.line = line;
paragraph.childWidgets.push(line);
this.documentHelper.fields.push(fieldBegin);
var section = new BodyWidget();
section.sectionFormat = new WSectionFormat(section);
section.childWidgets.push(paragraph);
this.pasteContentsInternal([section], false);
}
this.isInsertField = false;
};
/**
* @private
*/
Editor.prototype.isLinkedStyle = function (styleName) {
var styleObj = this.documentHelper.styles.findByName(styleName);
return !isNullOrUndefined(styleObj.link);
};
/**
* Applies the specified style for paragraph.
*
* @param {string} style Specify the style name to apply.
* @param {boolean} clearDirectFormatting - Removes manual formatting (formatting not applied using a style)
* from the selected text, to match the formatting of the applied style. Default value is false.
* @returns {void}
*/
Editor.prototype.applyStyle = function (style, clearDirectFormatting) {
clearDirectFormatting = isNullOrUndefined(clearDirectFormatting) ? false : clearDirectFormatting;
var startPosition = undefined;
var endPosition = undefined;
if (clearDirectFormatting) {
this.initComplexHistory('ApplyStyle');
this.setOffsetValue(this.selection);
startPosition = this.startOffset;
endPosition = this.endOffset;
var isSelectionEmpty = this.selection.isEmpty;
this.clearFormattingInternal(!this.isLinkedStyle(style));
if (isSelectionEmpty && !this.selection.isEmpty) {
this.selection.end.setPositionInternal(this.selection.start);
}
}
var styleObj = this.documentHelper.styles.findByName(style);
if (styleObj !== undefined) {
if (styleObj instanceof WCharacterStyle && styleObj.type === 'Character') {
if (this.selection.isEmpty) {
var offset = this.selection.start.offset;
var preservedStartPosition = this.selection.start.clone();
var preservedEndPosition = this.selection.end.clone();
this.selection.selectCurrentWord();
if (offset === this.selection.start.offset || offset === this.selection.end.offset - 1) {
this.selection.start = preservedStartPosition;
this.selection.end = preservedEndPosition;
this.selection.characterFormat.copyFormat(styleObj.characterFormat);
}
else {
this.onApplyCharacterFormat('styleName', styleObj, false, true);
}
}
else {
this.onApplyCharacterFormat('styleName', styleObj, false, true);
}
}
else {
this.onApplyParagraphFormat('styleName', styleObj, false, true);
}
}
else {
/* eslint-disable-next-line max-len */
this.documentHelper.owner.parser.parseStyle(JSON.parse(this.getCompleteStyles()), JSON.parse(this.documentHelper.preDefinedStyles.get(style)), this.documentHelper.styles);
this.applyStyle(style);
}
if (this.editorHistory && this.editorHistory.currentHistoryInfo && this.editorHistory.currentHistoryInfo.action === 'ApplyStyle') {
this.startOffset = startPosition;
this.endOffset = endPosition;
this.editorHistory.updateComplexHistory();
}
this.startParagraph = undefined;
this.endParagraph = undefined;
};
// Public Implementation Starts
/**
* Moves the selected content in the document editor control to clipboard.
*
* @returns {void}
*/
Editor.prototype.cut = function () {
if (this.owner.isReadOnlyMode || this.selection.isEmpty || !this.canEditContentControl) {
return;
}
this.selection.copySelectedContent(true);
this.documentHelper.owner.parser.isCutPerformed = true;
};
/**
* Inserts the editing region in the current selection range for the specified user.
*
* @param {string} user Specifies the native rendering
* @returns {void}
*/
Editor.prototype.insertEditingRegion = function (user) {
this.insertEditRangeElement(user && user !== '' ? user : 'Everyone');
};
Editor.prototype.enforceProtection = function (credential, restrictFormatType, isReadOnly) {
var typeOfProtection;
var limitToFormatting;
if (typeof (restrictFormatType) === 'boolean') {
typeOfProtection = isReadOnly ? 'ReadOnly' : this.documentHelper.protectionType;
limitToFormatting = restrictFormatType;
}
else {
limitToFormatting = true;
typeOfProtection = restrictFormatType;
}
this.documentHelper.restrictFormatting = limitToFormatting;
this.documentHelper.protectionType = typeOfProtection;
this.selection.isHighlightEditRegion = true;
this.addProtection(credential, this.documentHelper.protectionType, false);
};
Editor.prototype.enforceProtectionAsync = function (credential, restrictFormatType, isReadOnly) {
return __awaiter(this, void 0, void 0, function () {
var typeOfProtection, limitToFormatting;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
if (typeof (restrictFormatType) === 'boolean') {
typeOfProtection = isReadOnly ? 'ReadOnly' : this.documentHelper.protectionType;
limitToFormatting = restrictFormatType;
}
else {
limitToFormatting = true;
typeOfProtection = restrictFormatType;
}
this.documentHelper.restrictFormatting = limitToFormatting;
this.documentHelper.protectionType = typeOfProtection;
this.selection.isHighlightEditRegion = true;
return [4 /*yield*/, this.addProtection(credential, this.documentHelper.protectionType, true)];
case 1:
_a.sent();
return [2 /*return*/];
}
});
});
};
Editor.prototype.getCommentHierarchicalIndex = function (comment) {
var index = '';
while (comment.ownerComment) {
if (!isNullOrUndefined(comment.ownerComment)) {
index = comment.ownerComment.replyComments.indexOf(comment) + ';' + index;
comment = comment.ownerComment;
}
else {
index = comment.replyComments.indexOf(comment) + ';' + index;
comment = comment;
}
}
index = 'C;' + this.documentHelper.comments.indexOf(comment) + ';' + index;
return index;
};
Editor.prototype.alertBox = function () {
var localObj = new L10n('documenteditor', this.owner.defaultLocale);
localObj.setLocale(this.owner.locale);
DialogUtility.alert({
title: localObj.getConstant('Information'),
content: localObj.getConstant('Multiple Comment')
});
};
/**
* Inserts the comment.
*
* @param {string} text Specify the comment text to be inserted.
* @returns {void}
*/
// Comment implementation starts
Editor.prototype.insertComment = function (text) {
if (isNullOrUndefined(this.selection.start) || (this.owner.isReadOnlyMode && !this.documentHelper.isCommentOnlyMode) || this.viewer.owner.enableHeaderAndFooter
|| !this.viewer.owner.enableComment) {
return;
}
if (this.viewer.owner.commentReviewPane.commentPane.isEditMode) {
return this.alertBox();
}
if (isNullOrUndefined(text)) {
text = '';
}
this.insertCommentInternal(text);
};
Editor.prototype.insertCommentInternal = function (text) {
this.documentHelper.layout.allowLayout = false;
if (this.selection.isEmpty) {
// If selection is at paragraph end, move selection to previous word similar to MS Word
if (this.selection.start.isAtSamePosition(this.selection.end) && this.selection.start.isAtParagraphEnd) {
var startOffset = this.selection.start.offset;
this.selection.start.offset = startOffset - 1 !== -1 ? startOffset - 1 : startOffset;
}
this.selection.selectCurrentWord();
}
// If paragraph mark selected, remove paragraph mark selection
if (this.selection.isParagraphLastLine(this.selection.end.currentWidget)
&& this.selection.end.offset === this.selection.getLineLength(this.selection.end.currentWidget) + 1) {
this.selection.end.offset -= 1;
}
var paragraphInfo = this.selection.getParagraphInfo(this.selection.start);
var startIndex = this.selection.getHierarchicalIndex(paragraphInfo.paragraph, paragraphInfo.offset.toString());
var endParagraphInfo = this.selection.getParagraphInfo(this.selection.end);
var endIndex = this.selection.getHierarchicalIndex(endParagraphInfo.paragraph, endParagraphInfo.offset.toString());
this.initComplexHistory('InsertComment');
var startPosition = this.selection.start;
var endPosition = this.selection.end;
var position = new TextPosition(this.owner);
if (!this.selection.isForward) {
startPosition = this.selection.end;
endPosition = this.selection.start;
}
// Clones the end position.
position.setPositionInternal(endPosition);
var commentRangeStart = new CommentCharacterElementBox(0);
var commentRangeEnd = new CommentCharacterElementBox(1);
var isSameLine = startPosition.currentWidget === endPosition.currentWidget;
// Adds comment start at selection start position.
endPosition.setPositionInternal(startPosition);
this.initInsertInline(commentRangeStart);
if (isNullOrUndefined(position.paragraph) ||
(position.currentWidget && position.currentWidget.children.length === 0 && position.currentWidget.indexInOwner === -1)) {
var endPos = this.selection.getTextPosBasedOnLogicalIndex(endIndex);
position.setPositionInternal(endPos);
}
// Updates the cloned position, since comment start is added in the same line.
if (isSameLine) {
position.setPositionParagraph(position.currentWidget, position.offset + commentRangeStart.length);
}
// Adds comment end and comment at selection end position.
startPosition.setPositionInternal(position);
endPosition.setPositionInternal(position);
this.initInsertInline(commentRangeEnd);
var commentAdv = new CommentElementBox(HelperMethods.getUtcDate());
if (this.owner.editorHistory) {
this.initHistory('InsertCommentWidget');
this.owner.editorHistory.currentBaseHistoryInfo.insertedText = CONTROL_CHARACTERS.Marker_Start + CONTROL_CHARACTERS.Marker_End;
this.owner.editorHistory.currentBaseHistoryInfo.removedNodes.push(commentAdv);
}
var markerData = {
author: this.owner.currentUser ? this.owner.currentUser : 'Guest user',
initial: this.constructCommentInitial(commentAdv.author),
text: SanitizeHtmlHelper.sanitize(text),
commentId: Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15),
};
this.updateCommentElement(commentAdv, commentRangeStart, commentRangeEnd, markerData);
this.addCommentWidget(commentAdv, true, true, true);
if (this.editorHistory) {
this.editorHistory.currentBaseHistoryInfo.insertPosition = this.getCommentHierarchicalIndex(commentAdv);
this.editorHistory.updateHistory();
}
// this.selection.selectPosition(this.selection.getTextPosBasedOnLogicalIndex(startIndex), this.selection.getTextPosBasedOnLogicalIndex(endIndex));
if (this.editorHistory) {
this.editorHistory.updateComplexHistory();
}
this.reLayout(this.selection, false);
this.documentHelper.layout.allowLayout = true;
if (!this.isUserInsert) {
var comment = this.owner.commentReviewPane.commentPane.comments.get(commentAdv);
comment.postComment();
}
};
/**
* @private
*/
Editor.prototype.updateCommentElement = function (commentAdv, commentRangeStart, commentRangeEnd, markerData) {
commentAdv.author = markerData.author;
commentAdv.initial = markerData.initial;
commentAdv.text = markerData.text;
commentAdv.commentId = markerData.commentId;
if (!isNullOrUndefined(markerData.done)) {
commentAdv.isResolved = markerData.done;
}
if (!isNullOrUndefined(markerData.isReply)) {
commentAdv.isReply = markerData.isReply;
}
commentRangeStart.comment = commentAdv;
commentRangeStart.commentId = commentAdv.commentId;
commentRangeEnd.comment = commentAdv;
commentRangeEnd.commentId = commentAdv.commentId;
commentAdv.commentStart = commentRangeStart;
commentAdv.commentEnd = commentRangeEnd;
return commentAdv;
};
/**
* Deletes all the comments in the current document.
*
* @returns {void}
*/
Editor.prototype.deleteAllComments = function () {
if (this.documentHelper.comments.length === 0) {
return;
}
// this.documentHelper.clearSearchHighlight();
this.initComplexHistory('DeleteAllComments');
this.owner.isLayoutEnabled = false;
var historyInfo;
if (this.editorHistory && this.editorHistory.currentHistoryInfo) {
historyInfo = this.editorHistory.currentHistoryInfo;
}
while (this.documentHelper.comments.length > 0) {
var comment = this.documentHelper.comments[0];
this.initComplexHistory('DeleteComment');
this.deleteCommentInternal(comment);
if (this.editorHistory && this.editorHistory.currentHistoryInfo) {
historyInfo.addModifiedAction(this.editorHistory.currentHistoryInfo);
}
}
this.selection.selectContent(this.owner.documentStart, true);
if (this.editorHistory) {
this.editorHistory.currentHistoryInfo = historyInfo;
this.editorHistory.updateComplexHistory();
}
};
/**
* Deletes the current selected comment.
*
* @returns {void}
*/
Editor.prototype.deleteComment = function () {
if ((this.owner.isReadOnlyMode && !this.documentHelper.isCommentOnlyMode) || isNullOrUndefined(this.owner) || isNullOrUndefined(this.owner.viewer)
|| isNullOrUndefined(this.owner.documentHelper.currentSelectedComment) || this.owner.enableHeaderAndFooter
|| !this.viewer.owner.enableComment) {
return;
}
this.deleteCommentInternal(this.owner.documentHelper.currentSelectedComment);
};
/**
* @param {CommentElementBox} comment - Specified the comment element box
* @private
* @returns {void}
*/
Editor.prototype.deleteCommentInternal = function (comment) {
this.initComplexHistory('DeleteComment');
if (comment) {
if (comment.replyComments.length > 0) {
for (var i = comment.replyComments.length - 1; i >= 0; i--) {
this.deleteCommentInternal(comment.replyComments[i]);
}
}
this.deleteCommentWidgetInternal(comment);
var commentStart = comment.commentStart;
var commentEnd = comment.commentEnd;
if (commentEnd.indexInOwner !== -1) {
this.removeInline(commentEnd);
}
if (commentStart.indexInOwner !== -1) {
this.removeInline(commentStart);
}
commentStart.removeCommentMark();
}
if (this.editorHistory) {
this.editorHistory.updateComplexHistory();
}
};
Editor.prototype.deleteCommentWidgetInternal = function (comment) {
if (this.owner.editorHistory) {
this.initHistory('DeleteCommentWidget');
this.owner.editorHistory.currentBaseHistoryInfo.insertPosition = this.getCommentHierarchicalIndex(comment);
this.owner.editorHistory.currentBaseHistoryInfo.removedNodes.push(comment);
}
this.deleteCommentWidget(comment);
if (this.editorHistory) {
this.editorHistory.updateHistory();
}
};
/**
* @param {CommentElementBox} comment - Specified the comment element box
* @private
* @returns {void}
*/
Editor.prototype.deleteCommentWidget = function (comment) {
var commentIndex = this.documentHelper.comments.indexOf(comment);
if (commentIndex !== -1) {
this.documentHelper.comments.splice(commentIndex, 1);
}
else if (comment.isReply && comment.ownerComment) {
commentIndex = comment.ownerComment.replyComments.indexOf(comment);
comment.ownerComment.replyComments.splice(commentIndex, 1);
}
if (this.owner.commentReviewPane) {
this.owner.commentReviewPane.deleteComment(comment);
if (this.documentHelper.currentSelectedComment === comment) {
this.documentHelper.currentSelectedComment = undefined;
}
}
};
/**
* @param {CommentElementBox} comment - Specified the comment element box
* @private
* @returns {void}
*/
Editor.prototype.resolveComment = function (comment) {
if (this.owner.isReadOnlyMode && !this.documentHelper.isCommentOnlyMode) {
return;
}
var eventArgs = { author: comment.author, cancel: false, type: 'Resolve' };
this.owner.trigger(beforeCommentActionEvent, eventArgs);
if (eventArgs.cancel && eventArgs.type === 'Resolve') {
return;
}
this.initHistory('ResolveComment');
if (this.editorHistory && this.editorHistory.currentBaseHistoryInfo) {
this.editorHistory.currentBaseHistoryInfo.removedNodes.push(comment);
}
this.resolveOrReopenComment(comment, true);
};
/**
* @param {CommentElementBox} comment - Specified the comment element box
* @private
* @returns {void}
*/
Editor.prototype.reopenComment = function (comment) {
if (this.owner.isReadOnlyMode && !this.documentHelper.isCommentOnlyMode) {
return;
}
var eventArgs = { author: comment.author, cancel: false, type: 'Reopen' };
this.owner.trigger(beforeCommentActionEvent, eventArgs);
if (eventArgs.cancel && eventArgs.type === 'Reopen') {
return;
}
this.initHistory('ResolveComment');
if (this.editorHistory && this.editorHistory.currentBaseHistoryInfo) {
this.editorHistory.currentBaseHistoryInfo.removedNodes.push(comment);
}
this.resolveOrReopenComment(comment, false);
};
/**
* @private
*/
Editor.prototype.resolveOrReopenComment = function (comment, resolve) {
comment.isResolved = resolve;
for (var i = 0; i < comment.replyComments.length; i++) {
comment.replyComments[i].isResolved = resolve;
}
if (this.owner.commentReviewPane) {
if (resolve) {
this.owner.commentReviewPane.resolveComment(comment);
}
else {
this.owner.commentReviewPane.reopenComment(comment);
}
}
this.reLayout(this.selection, false, false);
};
/**
* @param {CommentElementBox} parentComment - Specified the parent comment
* @param {string} text - Specified the text.
* @private
* @returns {void}
*/
Editor.prototype.replyComment = function (parentComment, text) {
if (this.owner.isReadOnlyMode && !this.documentHelper.isCommentOnlyMode) {
return;
}
var commentWidget = parentComment;
if (parentComment) {
this.initComplexHistory('InsertComment');
var currentCmtStart = commentWidget.commentStart;
var currentCmtEnd = commentWidget.commentEnd;
var offset = currentCmtStart.line.getOffset(currentCmtStart, 1);
var startPosition = new TextPosition(this.documentHelper.owner);
startPosition.setPositionParagraph(currentCmtStart.line, offset);
var endOffset = currentCmtEnd.line.getOffset(currentCmtEnd, 1);
var endPosition = new TextPosition(this.documentHelper.owner);
endPosition.setPositionParagraph(currentCmtEnd.line, endOffset);
this.selection.start.setPositionInternal(startPosition);
this.selection.end.setPositionInternal(endPosition);
startPosition = this.selection.start;
endPosition = this.selection.end;
var position = new TextPosition(this.owner);
// Clones the end position.
position.setPositionInternal(endPosition);
var commentRangeStart = new CommentCharacterElementBox(0);
var commentRangeEnd = new CommentCharacterElementBox(1);
var isAtSameLine = startPosition.currentWidget === endPosition.currentWidget;
// Adds comment start at selection start position.
endPosition.setPositionInternal(startPosition);
var lineIndex = position.currentWidget.indexInOwner;
this.initInsertInline(commentRangeStart);
if (position.currentWidget.indexInOwner === -1) {
position.currentWidget = position.currentWidget.paragraph.childWidgets[lineIndex];
}
// Updates the cloned position, since comment start is added in the same paragraph.
if (isAtSameLine) {
position.setPositionParagraph(position.currentWidget, position.offset + commentRangeStart.length);
}
// Adds comment end and comment at selection end position.
startPosition.setPositionInternal(position);
endPosition.setPositionInternal(position);
this.initInsertInline(commentRangeEnd);
var replyComment = new CommentElementBox(HelperMethods.getUtcDate());
replyComment.author = this.owner.currentUser ? this.owner.currentUser : 'Guest user';
replyComment.text = text ? text : '';
replyComment.commentId = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
replyComment.isReply = true;
commentWidget.replyComments.push(replyComment);
replyComment.ownerComment = commentWidget;
if (this.owner.editorHistory) {
this.initHistory('InsertCommentWidget');
this.owner.editorHistory.currentBaseHistoryInfo.removedNodes.push(replyComment);
this.owner.editorHistory.currentBaseHistoryInfo.insertedText = CONTROL_CHARACTERS.Marker_Start + CONTROL_CHARACTERS.Marker_End;
}
commentRangeStart.comment = replyComment;
commentRangeStart.commentId = replyComment.commentId;
commentRangeEnd.comment = replyComment;
commentRangeEnd.commentId = replyComment.commentId;
replyComment.commentStart = commentRangeStart;
replyComment.commentEnd = commentRangeEnd;
if (this.owner.commentReviewPane) {
this.owner.commentReviewPane.addReply(replyComment, false, true);
}
if (this.editorHistory) {
this.editorHistory.currentBaseHistoryInfo.insertPosition = this.getCommentHierarchicalIndex(replyComment);
this.editorHistory.updateHistory();
}
if (this.editorHistory) {
this.editorHistory.updateComplexHistory();
}
this.isSkipOperationsBuild = true;
this.reLayout(this.selection);
}
};
Editor.prototype.removeInline = function (element) {
this.selection.start.setPositionParagraph(element.line, element.line.getOffset(element, 0));
this.selection.end.setPositionParagraph(this.selection.start.currentWidget, this.selection.start.offset + element.length);
this.initHistory('RemoveInline');
if (this.editorHistory && this.editorHistory.currentBaseHistoryInfo) {
this.updateHistoryPosition(this.selection.start, true);
}
this.removeSelectedContents(this.documentHelper.selection);
if (this.editorHistory) {
this.editorHistory.updateHistory();
}
this.fireContentChange();
};
/**
* @param {CommentElementBox} commentWidget - Specifies the comment
* @param {boolean} isNewComment - Specifies is new comment
* @param {boolean} showComments - Specifies show comments
* @param {boolean} selectComment - Specified select comment
* @private
* @returns {void}
*/
Editor.prototype.addCommentWidget = function (commentWidget, isNewComment, showComments, selectComment) {
if (this.documentHelper.comments.indexOf(commentWidget) === -1) {
var isInserted = fals