@syncfusion/ej2-documenteditor
Version:
Feature-rich document editor control with built-in support for context menu, options pane and dialogs.
1,098 lines • 1.32 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, ImageSizeInfo } 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, ShapeBase, FootnoteEndnoteMarkerElementBox, ContentControlProperties, CheckBoxState, ContentControlListItems, XmlMapping, FillFormat, LineFormat } 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, Comment, breakCodeProperty, nsidProperty, customXmlProperty } from '../../base/index';
import { SelectionCharacterFormat } from '../index';
import { PageLayoutViewer } from '../index';
import { WCharacterStyle, WStyles } 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, revisionsProperty, lastParagraphMarkCopiedProperty, sectionFormatProperty, revisionIdProperty, paragraphFormatProperty, listsProperty, abstractListsProperty, listIdProperty, listFormatProperty, cellsProperty, rowsProperty, blocksProperty, stylesProperty, nameProperty, numberOfColumnsProperty } from '../../index';
import { SanitizeHtmlHelper } from '@syncfusion/ej2-base';
import { ChangesSingleView } from '../track-changes/track-changes-pane';
// Check box character is rendered smaller when compared to MS Word
// So, mutiplied the font side by below factor to render check box character large.
var CHECK_BOX_FACTOR = 1.35;
/**
* 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;
/**
* @private
*/
this.startParagraph = undefined;
/**
* @private
*/
this.endParagraph = undefined;
this.formFieldCounter = 1;
this.skipFieldDeleteTracking = false;
this.skipFootNoteDeleteTracking = false;
this.isForHyperlinkFormat = false;
this.isTrackingFormField = false;
this.isInsertText = false;
this.casingIndex = -1;
this.checkLastLetterSpace = '';
this.checkLastLetterSpaceDot = '';
this.pasteFootNoteType = '';
this.isInsertingText = false;
this.isInternalPaste = false;
/**
* @private
*/
this.keywordIndex = 0;
/**
* @private
*/
this.dictionaryObjcetIDIncreament = 1;
/**
* @private
*/
this.dictionaryObjectIndexIncrement = 0;
/**
* @private
*/
this.XMLFilesCount = 1;
/**
* @private
*/
this.XMLFilesNameSpaceCount = 1;
/**
* @private
*/
this.xmlData = [];
/**
* @private
*/
this.dictionaryObject = [];
/**
* @private
*/
this.isFootnoteElementRemoved = false;
/**
* @private
*/
this.isEndnoteElementRemoved = false;
/**
* @private
*/
this.handledEnter = false;
/**
* @private
*/
this.handledTextInput = 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.removedContentControlElements = [];
/**
* @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;
/**
* @private
*/
this.isMeasureParaWidth = false;
this.editStartRangeCollection = [];
this.skipReplace = false;
this.skipTableElements = false;
this.isPasteOverWriteCells = false;
this.editRangeID = [];
/**
* @private
*/
this.isImageInsert = false;
/**
* @private
*/
this.isSkipOperationsBuild = false;
/**
* @private
*/
this.isCellFormatApplied = false;
/**
* @private
*/
this.revisionData = undefined;
/**
* @private
*/
this.splittedRevisions = [];
/**
* @private
*/
this.isSkipComments = false;
/**
* @private
*/
this.isRemoteAction = false;
/**
* @private
*/
this.isIncrementalSave = false;
/**
* @private
*/
this.listFormatInfo = undefined;
/**
* @private
*/
this.listLevelNumber = 0;
/**
* @private
*/
this.isXmlMapped = false;
/**
* @private
*/
this.restrictLayout = false;
this.isAutoList = false;
/**
* @private
*/
this.isLastParaMarkCopied = false;
this.combineLastBlock = false;
/**
* @private
*/
this.remotePasteRevision = [];
/**
* @private
*/
this.isFieldOperation = false;
/**
* @private
*/
this.decreasedIndent = false;
/**
* @private
*/
this.increasedIndent = 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 () {
var currentContentControl = this.selection.currentContentControl;
if (!isNullOrUndefined(currentContentControl)) {
if (currentContentControl.contentControlProperties.lockContents || currentContentControl.contentControlProperties.type === 'DropDownList') {
return false;
}
}
else if (this.selection.checkContentControlLocked()) {
return false;
}
if (this.owner.isReadOnly) {
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.editorHistoryModule;
},
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 () {
if (this.documentHelper) {
return this.documentHelper.owner;
}
return undefined;
},
enumerable: true,
configurable: true
});
Editor.prototype.getModuleName = function () {
return 'Editor';
};
/**
* Initiates a batch update mode where multiple editing operations can be grouped together. This prevents intermediate re-layout during the execution of grouped operations, improving performance for bulk updates.
*
* @returns {void}
*/
Editor.prototype.beginBatchEdit = function () {
this.restrictLayout = true;
};
/**
* Ends the batch update mode and triggers a single re-relayout or change notification to reflect all the modifications made during the batch update.
*
* @returns {void}
*/
Editor.prototype.endBatchEdit = function () {
this.restrictLayout = false;
this.documentHelper.layout.layoutWholeDocument();
};
/**
* 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) {
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 startParagraph = this.selection.start.paragraph;
if (!this.selection.isForward) {
startParagraph = this.selection.end.paragraph;
}
var currentInline = this.selection.start.currentWidget.getInline(this.selection.start.offset, 0);
if (startParagraph.isEmpty()) {
insertFormat = startParagraph.characterFormat;
}
else if (!isNullOrUndefined(currentInline.element)) {
insertFormat = currentInline.element.characterFormat;
}
else {
insertFormat = this.copyInsertFormat(insertFormat, false);
}
var line = new LineWidget(paragraph);
var fieldBegin = new FieldElementBox(0);
fieldBegin.characterFormat.assignFormat(insertFormat);
line.children.push(fieldBegin);
var fieldCodeSpan = new TextElementBox();
fieldCodeSpan.characterFormat.assignFormat(insertFormat);
fieldCodeSpan.text = code;
line.children.push(fieldCodeSpan);
var fieldSeparator = new FieldElementBox(2);
fieldSeparator.characterFormat.assignFormat(insertFormat);
fieldSeparator.fieldBegin = fieldBegin;
fieldBegin.fieldSeparator = fieldSeparator;
line.children.push(fieldSeparator);
var fieldResultSpan = new TextElementBox();
fieldResultSpan.text = result;
fieldResultSpan.characterFormat.assignFormat(insertFormat);
if (!this.documentHelper.textHelper.isRTLText(result) && fieldResultSpan.characterFormat.bidi) {
fieldResultSpan.characterFormat.bidi = false;
}
line.children.push(fieldResultSpan);
var fieldEnd = new FieldElementBox(1);
fieldEnd.characterFormat.assignFormat(insertFormat);
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, startParagraph.paragraphFormat);
}
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;
var styleObj = this.documentHelper.styles.findByName(style);
if (clearDirectFormatting) {
this.initComplexHistory('ApplyStyle');
this.setOffsetValue(this.selection);
startPosition = this.startOffset;
endPosition = this.endOffset;
var isSelectionEmpty = this.selection.isEmpty;
this.isSkipOperationsBuild = this.owner.enableCollaborativeEditing;
if (!isNullOrUndefined(styleObj) && (styleObj instanceof WCharacterStyle && styleObj.type === 'Character')) {
this.clearFormattingInternal(false, true);
}
else {
this.clearFormattingInternal(true, true);
}
this.isSkipOperationsBuild = false;
if (isSelectionEmpty && !this.selection.isEmpty) {
this.selection.end.setPositionInternal(this.selection.start);
}
}
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;
}
// As per MSWord behaviour, when we select the bookmark whole content except bookmark start & end and cut those content, then bookmark should be removed.
var startPosition = this.selection.start;
var endPosition = this.selection.end;
var previousElementInfo = (startPosition.offset === 0) ? this.selection.getElementInfo(startPosition.currentWidget, startPosition.offset - 1) : this.selection.getElementInfo(startPosition.currentWidget, this.selection.isForward ? startPosition.offset : startPosition.offset + 1);
var nextElementInfo = (endPosition.offset === 0) ? this.selection.getElementInfo(endPosition.currentWidget, endPosition.offset - 1) : this.selection.getElementInfo(endPosition.currentWidget, this.selection.isForward ? endPosition.offset + 1 : endPosition.offset);
if (!isNullOrUndefined(previousElementInfo) && !isNullOrUndefined(nextElementInfo) && previousElementInfo.element && nextElementInfo.element
&& previousElementInfo.index !== -1 && nextElementInfo.index !== -1 && previousElementInfo.element instanceof BookmarkElementBox && nextElementInfo.element instanceof BookmarkElementBox
&& previousElementInfo.element.name === nextElementInfo.element.name &&
!(!isNullOrUndefined(previousElementInfo.element.nextElement) && !isNullOrUndefined(nextElementInfo.element.previousElement) && previousElementInfo.element.nextElement instanceof FieldElementBox && nextElementInfo.element.previousElement instanceof FieldElementBox)) {
if (this.selection.isForward) {
this.selection.start.setPositionParagraph(previousElementInfo.element.line, previousElementInfo.element.line.getOffset(previousElementInfo.element, 0));
this.selection.end.setPositionParagraph(nextElementInfo.element.line, nextElementInfo.element.line.getOffset(nextElementInfo.element, 1));
}
else {
this.selection.start.setPositionParagraph(previousElementInfo.element.line, previousElementInfo.element.line.getOffset(previousElementInfo.element, 1));
this.selection.end.setPositionParagraph(nextElementInfo.element.line, nextElementInfo.element.line.getOffset(nextElementInfo.element, 0));
}
}
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 {
typeOfProtection = restrictFormatType;
}
if (!isNullOrUndefined(limitToFormatting)) {
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 a reply to a comment.
*
* @param {string} id - The unique identifier of the comment to reply to.
* @param {string} text - The text of the reply.
* @param {CommentProperties} commentProperties - The properties of the reply (author, isResolved, dateTime).
* @returns {Comment} Returns the inserted reply comment.
*/
Editor.prototype.insertReplyComment = function (id, text, commentProperties) {
var markerData = {};
var result = this.getCommentInfo(text);
markerData = {
author: commentProperties.author ? commentProperties.author : 'Guest user',
initial: this.constructCommentInitial(commentProperties.author ? commentProperties.author : 'Guest user'),
text: isNullOrUndefined(result.innerText) ? SanitizeHtmlHelper.sanitize(text) : SanitizeHtmlHelper.sanitize(result.innerText),
commentId: Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15),
done: false,
date: commentProperties.dateTime ? HelperMethods.getUtcDate(commentProperties.dateTime) : HelperMethods.getUtcDate(),
};
var parentComment;
if (this.documentHelper.comments.length > 0) {
for (var i = 0; i < this.documentHelper.comments.length; i++) {
if (this.documentHelper.comments[i].commentId === id) {
parentComment = this.documentHelper.comments[i];
break;
}
}
}
this.replyComment(parentComment, isNullOrUndefined(result.innerText) ? text : result.innerText, result.itemData, markerData);
var commentInfo = {
author: markerData.author,
isResolved: markerData.done,
dateTime: this.parseDateTime(markerData.date),
};
var newComment = new Comment(markerData.commentId, commentInfo, text);
return newComment;
};
Editor.prototype.getCommentInfo = function (text) {
var itemData = [];
var data = [];
var result = [];
var mailtoRegex = /<a href="mailto:([^"]+)">([^<]+)<\/a>/g;
var lastIndex = 0;
var match;
while ((match = mailtoRegex.exec(text)) !== null) {
if (match.index > lastIndex) {
result.push({ text: text.substring(lastIndex, match.index) });
}
result.push({
mailto: match[1],
text: match[2]
});
lastIndex = mailtoRegex.lastIndex;
}
if (lastIndex < text.length) {
result.push({ text: text.substring(lastIndex) });
}
var innerText = '';
if (result.length > 0) {
for (var i = 0; i < result.length; i++) {
if (result[i].mailto) {
data.push({ text: result[i].text.replace('@', ''), value: result[i].mailto });
innerText += '<span contenteditable="false" class="e-mention-chip">' + result[i].text.replace('@', '') + '</span>';
}
else if (result[i].text) {
innerText += result[i].text.replace(/(\r\n|\n\r|\n|\r)/g, "<br>");
}
}
}
else if (text !== '') {
innerText = text.replace(/(\r\n|\n\r|\n|\r)/g, "<br>");
}
itemData = data;
return { itemData: itemData, innerText: innerText };
};
/**
* Inserts the comment.
*
* @param {string} text Specify the comment text to be inserted.
* @param {CommentProperties} commentProperties The properties of the comment (author, isResolved, dateTime).
* @returns {Comment}
*/
Editor.prototype.insertComment = function (text, commentProperties) {
if (isNullOrUndefined(this.selection.start) || (this.owner.isReadOnlyMode && !this.documentHelper.isCommentOnlyMode) || this.viewer.owner.enableHeaderAndFooter
|| !this.viewer.owner.enableComment || this.selection.isPlainContentControl()) {
return;
}
if (this.viewer.owner.commentReviewPane.commentPane.isEditMode) {
return this.alertBox();
}
if (isNullOrUndefined(text)) {
text = '';
}
var markerData = {};
var result = this.getCommentInfo(text);
if (!isNullOrUndefined(commentProperties)) {
var authorInternal = isNullOrUndefined(commentProperties.author) ? this.owner.currentUser : commentProperties.author;
markerData = {
author: authorInternal,
initial: this.constructCommentInitial(authorInternal),
text: SanitizeHtmlHelper.sanitize(result.innerText === '' ? text : result.innerText),
commentId: Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15),
done: commentProperties.isResolved ? commentProperties.isResolved : false,
date: commentProperties.dateTime ? HelperMethods.getUtcDate(commentProperties.dateTime) : HelperMethods.getUtcDate()
};
}
else {
markerData = {
author: this.owner.currentUser ? SanitizeHtmlHelper.sanitize(this.owner.currentUser) : 'Guest user',
initial: this.constructCommentInitial(this.owner.currentUser ? SanitizeHtmlHelper.sanitize(this.owner.currentUser) : 'Guest user'),
text: SanitizeHtmlHelper.sanitize(text),
commentId: Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15),
done: false,
date: HelperMethods.getUtcDate(),
};
}
this.insertCommentInternal(!isNullOrUndefined(result.innerText) ? result.innerText : '', markerData, result.itemData);
var commentInfo = {
author: markerData.author,
isResolved: markerData.done,
dateTime: this.parseDateTime(markerData.date),
};
var newComment = new Comment(markerData.commentId, commentInfo, text);
return newComment;
};
/**
* @private
*/
Editor.prototype.parseDateTime = function (dateTime) {
var date = new Date(dateTime);
var finalDate = new Date(date.getTime() + date.getTimezoneOffset() * 60000);
return finalDate;
};
Editor.prototype.insertCommentInternal = function (text, markerData, mentions) {
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 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(startPosition);
this.initComplexHistory('InsertComment');
var commentRangeStart = new CommentCharacterElementBox(0);
var commentRangeEnd = new CommentCharacterElementBox(1);
// Adds comment end at selection end position.
startPosition.setPositionInternal(endPosition);
this.initInsertInline(commentRangeEnd);
if (isNullOrUndefined(position.paragraph) || position.currentWidget.indexInOwner === -1) {
var startPos = this.selection.getTextPosBasedOnLogicalIndex(startIndex);
position.setPositionInternal(startPos);
}
// Adds comment end and comment at selection end position.
startPosition.setPositionInternal(position);
endPosition.setPositionInternal(position);
this.initInsertInline(commentRangeStart);
var commentAdv = new CommentElementBox(markerData.date);
if (mentions && mentions.length > 0) {
commentAdv.mentions = mentions;
}
if (this.owner.editorHistoryModule) {
this.initHistory('InsertCommentWidget');
this.owner.editorHistoryModule.currentBaseHistoryInfo.insertedText = CONTROL_CHARACTERS.Marker_Start + CONTROL_CHARACTERS.Marker_End;
this.owner.editorHistoryModule.currentBaseHistoryInfo.removedNodes.push(commentAdv);
}
this.updateCommentElement(commentAdv, commentRangeStart, commentRangeEnd, markerData);
this.addCommentWidget(commentAdv, true, true, true);
if (this.owner.isSpellCheck && commentRangeStart.previousElement && commentRangeStart.previousElement instanceof TextElementBox) {
commentRangeStart.previousElement.ischangeDetected = true;
}
if (this.owner.isSpellCheck && commentRangeEnd.previousElement && commentRangeEnd.previousElement instanceof TextElementBox && commentRangeStart.line !== commentRangeEnd.line) {
commentRangeEnd.previousElement.ischangeDetected = 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);
if (mentions && mentions.length > 0) {
comment.itemData = mentions;
}
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;
}
if (!isNullOrUndefined(commentRangeStart) && !isNullOrUndefined(commentRangeEnd)) {
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;
}
//