UNPKG

@syncfusion/ej2-documenteditor

Version:

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

1,368 lines 593 kB
import { Widget, BodyWidget, TableRowWidget, TableWidget, LineWidget, TextElementBox, ListTextElementBox, ImageElementBox, ParagraphWidget, TableCellWidget, FieldElementBox, BlockWidget, HeaderFooterWidget, BlockContainer, BookmarkElementBox, ElementBox, EditRangeStartElementBox, EditRangeEndElementBox, TabElementBox, CommentElementBox, CommentCharacterElementBox, TextFormField, CheckBoxFormField, DropDownFormField, ShapeElementBox, TextFrame, ContentControl, FieldTextElementBox, FootNoteWidget, FootnoteElementBox, ShapeBase, GroupShapeElementBox } from '../viewer/page'; import { HelperMethods, Point } from '../editor/editor-helper'; import { SelectionCharacterFormat, SelectionCellFormat, SelectionParagraphFormat, SelectionRowFormat, SelectionSectionFormat, SelectionTableFormat, SelectionImageFormat } from './selection-format'; import { PageLayoutViewer, WebLayoutViewer, WRowFormat } from '../index'; import { isNullOrUndefined, createElement, L10n, Browser } from '@syncfusion/ej2-base'; import { Dictionary } from '../../base/dictionary'; import { contentControlEvent, beforeFormFieldFillEvent, afterFormFieldFillEvent, requestNavigateEvent, CharacterRangeType, aftercontentControlFillEvent, beforecontentControlFillEvent, internalviewChangeEvent } from '../../base/index'; import { WCharacterFormat, WParagraphFormat, WParagraphStyle } from '../index'; import { HtmlExport } from '../writer/html-export'; import { Popup } from '@syncfusion/ej2-popups'; import { TextPosition, SelectionWidgetInfo, Hyperlink } from './selection-helper'; import { DropDownButton } from '@syncfusion/ej2-splitbuttons'; /* eslint-disable */ /** * Selection */ var Selection = /** @class */ (function () { /** * @param documentEditor * @private */ function Selection(documentEditor) { var _this = this; /** * @private */ this.upDownSelectionLength = 0; /** * @private */ this.isSkipLayouting = false; /** * @private */ this.isImageSelected = false; /** * @private */ this.isExcludeBookmarkStartEnd = false; this.contextTypeInternal = undefined; /** * @private */ this.caret = undefined; //Format Retrieval Field /** * @private */ this.isRetrieveFormatting = false; /** * @private */ this.isSelectCurrentWord = false; /** * @private */ this.skipFormatRetrieval = false; /** * @private */ this.isModifyingSelectionInternally = false; this.isMoveDownOrMoveUp = false; this.isSelectBookmark = false; this.isHighlightContentControlEditRegionIn = true; this.isPageUpAndDown = false; /** * @private * This will holds the selection html content to set data in clipboard. Avoid to use this field for other purpose. */ this.htmlContent = undefined; /** * @private * This will holds the selection sfdt content to set data in clipboard. Avoid to use this field for other purpose. */ this.sfdtContent = undefined; /** * @private */ this.isEndOffset = false; /** * @private */ this.isViewPasteOptions = false; /** * @private */ this.skipEditRangeRetrieval = false; /** * @private */ this.selectedWidgets = undefined; /** * @private */ this.isHighlightEditRegionIn = false; /** * @private */ this.isHighlightFormFields = false; /** * @private */ this.isHightlightEditRegionInternal = false; /** * @private */ this.isCurrentUser = false; /** * @private */ this.isHighlightNext = false; /** * @private */ this.isWebLayout = false; /** * @private */ this.contentControlHighlighters = undefined; /** * @private */ this.editRegionHighlighters = undefined; /** * @private */ this.contentControleditRegionHighlighters = undefined; /** * @private */ this.formFieldHighlighters = undefined; this.isSelectList = false; /** * @private */ this.previousSelectedFormField = undefined; /** * @private */ this.previousSelectedContentControl = undefined; /** * @private */ this.currentContentControl = undefined; /** * @private */ this.isFormatUpdated = false; /** * @private */ this.isCellPrevSelected = false; /** * @private */ this.currentFormField = undefined; /** * @private */ this.contentControls = []; this.editRangeCachePage = []; /** * @private */ this.isHomeEnd = false; /** * @private */ this.pasteOptions = function (event) { var locale = new L10n('documenteditor', _this.owner.defaultLocale); locale.setLocale(_this.owner.locale); if (event.item.text === locale.getConstant('Keep source formatting')) { _this.owner.editorModule.applyPasteOptions('KeepSourceFormatting'); } else if (event.item.text === locale.getConstant('Match destination formatting')) { _this.owner.editorModule.applyPasteOptions('MergeWithExistingFormatting'); } else if (event.item.text === locale.getConstant('NestTable')) { _this.owner.editorModule.applyTablePasteOptions('NestTable'); } else if (event.item.text === locale.getConstant('InsertAsRows')) { _this.owner.editorModule.applyTablePasteOptions('InsertAsRows'); } else if (event.item.text === locale.getConstant('InsertAsColumns')) { _this.owner.editorModule.applyTablePasteOptions('InsertAsColumns'); } else if (event.item.text === locale.getConstant('OverwriteCells')) { _this.owner.editorModule.applyTablePasteOptions('OverwriteCells'); } else { _this.owner.editorModule.applyPasteOptions('KeepTextOnly'); } }; /** * Hides caret. * * @private * @returns {void} */ this.hideCaret = function () { if (!isNullOrUndefined(_this.caret)) { _this.caret.style.display = 'none'; } }; this.owner = documentEditor; this.documentHelper = this.owner.documentHelper; this.start = new TextPosition(this.owner); this.end = new TextPosition(this.owner); this.selectedWidgets = new Dictionary(); this.characterFormatIn = new SelectionCharacterFormat(this); this.paragraphFormatIn = new SelectionParagraphFormat(this, this.documentHelper); this.sectionFormatIn = new SelectionSectionFormat(this); this.rowFormatIn = new SelectionRowFormat(this); this.cellFormatIn = new SelectionCellFormat(this); this.tableFormatIn = new SelectionTableFormat(this); this.imageFormatInternal = new SelectionImageFormat(this); this.editRangeCollection = []; this.editRegionHighlighters = new Dictionary(); this.contentControleditRegionHighlighters = new Dictionary(); this.formFieldHighlighters = new Dictionary(); } Object.defineProperty(Selection.prototype, "isHighlightEditRegion", { // Code for Comparing the offset calculated using old approach and optimized approach // /** // * @private // */ // public isNewApproach: boolean; /** * @private * @returns {boolean} - Retuens true if highlighting editing region */ get: function () { return this.isHighlightEditRegionIn; }, /** * @private */ set: function (value) { this.isHighlightEditRegionIn = value; this.onHighlight(); }, enumerable: true, configurable: true }); Object.defineProperty(Selection.prototype, "isHighlightContentControlEditRegion", { /** * @private * @returns {boolean} - Retuens true if highlighting editing region */ get: function () { return this.isHighlightContentControlEditRegionIn; }, /** * @private */ set: function (value) { this.isHighlightContentControlEditRegionIn = value; }, enumerable: true, configurable: true }); Object.defineProperty(Selection.prototype, "htmlWriter", { /** * @private */ get: function () { if (isNullOrUndefined(this.htmlWriterIn)) { this.htmlWriterIn = new HtmlExport(); } return this.htmlWriterIn; }, enumerable: true, configurable: true }); Object.defineProperty(Selection.prototype, "start", { /** * Gets the start text position of last range in the selection * * @private * @returns {TextPosition} - Returns selection start position. */ get: function () { if (!isNullOrUndefined(this.owner) && !isNullOrUndefined(this.viewer)) { if (isNullOrUndefined(this.startInternal)) { this.startInternal = this.owner.documentStart; } return this.startInternal; } return undefined; }, /** * @private */ set: function (value) { this.startInternal = value; }, enumerable: true, configurable: true }); Object.defineProperty(Selection.prototype, "characterFormat", { //Format retrieval properties /** * Gets the instance of selection character format. * * @default undefined * @aspType SelectionCharacterFormat * @returns {SelectionCharacterFormat} Returns the selection character format. */ get: function () { return this.characterFormatIn; }, enumerable: true, configurable: true }); Object.defineProperty(Selection.prototype, "paragraphFormat", { /** * Gets the instance of selection paragraph format. * * @default undefined * @aspType SelectionParagraphFormat * @returns {SelectionParagraphFormat} Returns the selection paragraph format. */ get: function () { return this.paragraphFormatIn; }, enumerable: true, configurable: true }); Object.defineProperty(Selection.prototype, "sectionFormat", { /** * Gets the instance of selection section format. * * @default undefined * @aspType SelectionSectionFormat * @returns {SelectionSectionFormat} Returns the selection section format. */ get: function () { return this.sectionFormatIn; }, enumerable: true, configurable: true }); Object.defineProperty(Selection.prototype, "tableFormat", { /** * Gets the instance of selection table format. * * @default undefined * @aspType SelectionTableFormat * @returns {SelectionTableFormat} Returns the selection table format. */ get: function () { return this.tableFormatIn; }, enumerable: true, configurable: true }); Object.defineProperty(Selection.prototype, "cellFormat", { /** * Gets the instance of selection cell format. * * @default undefined * @aspType SelectionCellFormat * @returns {SelectionCellFormat} Returns the selection cell format. */ get: function () { return this.cellFormatIn; }, enumerable: true, configurable: true }); Object.defineProperty(Selection.prototype, "rowFormat", { /** * Gets the instance of selection row format. * * @default undefined * @aspType SelectionRowFormat * @returns {SelectionRowFormat} Returns selection row format. */ get: function () { return this.rowFormatIn; }, enumerable: true, configurable: true }); Object.defineProperty(Selection.prototype, "imageFormat", { /** * Gets the instance of selection image format. * * @default undefined * @aspType SelectionImageFormat * @returns {SelectionImageFormat} Returns the selection image format. */ get: function () { return this.imageFormatInternal; }, enumerable: true, configurable: true }); Object.defineProperty(Selection.prototype, "end", { /** * Gets the start text position of selection range. * * @private * @returns {TextPosition} - Returns selection end position. */ get: function () { return this.endInternal; }, /** * For internal use * * @private */ set: function (value) { this.endInternal = value; }, enumerable: true, configurable: true }); /** * Gets the current scroll position of the document editor. * * @returns {ScrollPosition} An object containing the current scroll position * @returns {ScrollPosition.scrollTop} The vertical scroll offset in pixels from the top * @returns {ScrollPosition.scrollLeft} The horizontal scroll offset in pixels from the left */ Selection.prototype.getScrollPosition = function () { var scrollPosition = { scrollTop: this.documentHelper.viewerContainer.scrollTop, scrollLeft: this.documentHelper.viewerContainer.scrollLeft }; return scrollPosition; }; /** * Sets the scroll position of the document editor. * * @param {ScrollPosition} position - The target scroll position * @param {number} position.scrollTop - The vertical scroll offset in pixels from the top * @param {number} position.scrollLeft - The horizontal scroll offset in pixels from the left * @returns {void} */ Selection.prototype.setScrollPosition = function (position) { if (!isNullOrUndefined(position.scrollTop)) { this.documentHelper.viewerContainer.scrollTop = position.scrollTop; } if (!isNullOrUndefined(position.scrollLeft)) { this.documentHelper.viewerContainer.scrollLeft = position.scrollLeft; } }; Object.defineProperty(Selection.prototype, "startPage", { /** * Gets the page number where the selection starts. * * @returns {number} Returns the selection start page number. */ get: function () { if (!this.owner.isDocumentLoaded || isNullOrUndefined(this.viewer) || this.viewer instanceof WebLayoutViewer || isNullOrUndefined(this.documentHelper.selectionStartPage)) { return 1; } return this.documentHelper.pages.indexOf(this.documentHelper.selectionStartPage) + 1; }, enumerable: true, configurable: true }); Object.defineProperty(Selection.prototype, "endPage", { /** * Gets the page number where the selection ends. * * @returns {number} Returns the selection end page number. */ get: function () { if (!this.owner.isDocumentLoaded || isNullOrUndefined(this.viewer) || this.viewer instanceof WebLayoutViewer || isNullOrUndefined(this.documentHelper.selectionEndPage)) { return 1; } return this.documentHelper.pages.indexOf(this.documentHelper.selectionEndPage) + 1; }, enumerable: true, configurable: true }); Object.defineProperty(Selection.prototype, "isForward", { /** * Determines whether the selection direction is forward or not. * * @default false * @private * @returns {boolean} Returns isForward */ get: function () { return this.start.isExistBefore(this.end); }, enumerable: true, configurable: true }); Object.defineProperty(Selection.prototype, "isinFootnote", { /** * Determines whether the selection is in footnote or not. * * @default false * @returns {boolean} Returns true if selection is in footnote * @private */ get: function () { return this.isFootNoteParagraph(this.start.paragraph); }, enumerable: true, configurable: true }); Object.defineProperty(Selection.prototype, "isinEndnote", { /** * Determines whether the selection is in endnote or not. * * @default false * @returns {boolean} * @private */ get: function () { return this.isEndNoteParagraph(this.start.paragraph); }, enumerable: true, configurable: true }); Object.defineProperty(Selection.prototype, "isEmpty", { /** * Determines whether the start and end positions are same or not. * * @default false * @returns {boolean} * @private */ get: function () { if (isNullOrUndefined(this.start)) { return true; } return this.start.isAtSamePosition(this.end); }, enumerable: true, configurable: true }); Object.defineProperty(Selection.prototype, "startOffset", { /** * Returns the start hierarchical index. */ get: function () { return this.getHierarchicalIndexByPosition(this.start); }, enumerable: true, configurable: true }); Object.defineProperty(Selection.prototype, "endOffset", { /** * Returns the end hierarchical index. */ get: function () { return this.getHierarchicalIndexByPosition(this.end); }, enumerable: true, configurable: true }); Object.defineProperty(Selection.prototype, "isInShape", { /** * @private */ get: function () { var container = this.start.paragraph.containerWidget; do { if (container instanceof TextFrame) { return true; } if (container) { container = container.containerWidget; } } while (container); return false; }, enumerable: true, configurable: true }); Object.defineProperty(Selection.prototype, "text", { /** * Gets the text within selection. * * @default '' * @aspType string * @returns {string} Returns the text within selection. */ get: function () { return this.getText(false); }, enumerable: true, configurable: true }); Object.defineProperty(Selection.prototype, "contextType", { /** * Gets the context type of the selection. */ get: function () { return this.contextTypeInternal; }, enumerable: true, configurable: true }); Object.defineProperty(Selection.prototype, "bookmarks", { /** * Gets bookmark name collection. */ get: function () { return this.getSelBookmarks(false, false); }, enumerable: true, configurable: true }); Object.defineProperty(Selection.prototype, "sfdt", { /** * Gets the selected content of the document as SFDT(Syncfusion Document Text) file format. * * @default undefined * @returns {string} */ get: function () { if (this.owner.editorModule && !this.isEmpty) { return JSON.stringify(this.writeSfdt()); } else { return undefined; } }, enumerable: true, configurable: true }); Object.defineProperty(Selection.prototype, "fields", { /** * Gets the list of fields present within the current selection in the document. This property can be used to identify and work with field elements present in the selected text range. * * @returns {FieldStartInfo[]} An array of objects containing information about each field present in the selected text range. */ get: function () { return this.getSelBookmarks(false, true); }, enumerable: true, configurable: true }); /** * Gets the bookmark name collection in current selection. * * @param includeHidden - Decide whether to include hidden bookmark name in current selection or not. * @returns Returns the bookmark name collection in current selection. */ Selection.prototype.getBookmarks = function (includeHidden) { return this.getSelBookmarks(includeHidden, false); }; Object.defineProperty(Selection.prototype, "isCleared", { /** * @private */ get: function () { return isNullOrUndefined(this.end); }, enumerable: true, configurable: true }); Object.defineProperty(Selection.prototype, "isInField", { /** * Returns true if selection is in field. * * @returns Returns true if selection is in field; Otherwise, false. */ get: function () { if (!isNullOrUndefined(this.getHyperlinkField(true))) { return true; } return false; }, enumerable: true, configurable: true }); /** * Determines whether the current selection is within a field. * * @param includeFieldStart - Optional. If true, includes the field start in the selection check. Default is false. * @param includeFieldEnd - Optional. If true, includes the field end in the selection check. Default is false. * * @returns Returns true if the selection is within a field, false otherwise. */ Selection.prototype.isSelectionInField = function (includeFieldStart, includeFieldEnd) { if (includeFieldStart === void 0) { includeFieldStart = false; } if (includeFieldEnd === void 0) { includeFieldEnd = false; } if (!isNullOrUndefined(this.getHyperlinkField(true, includeFieldStart, includeFieldEnd, true))) { return true; } return false; }; /** * Gets the field information for the selected field. * * @returns { FieldInfo } Returns `FieldInfo` if selection is in field, otherwise `undefined` * > Returns `undefined` for text, image, table, shape. For nested fields, it returns combined field code and result. */ Selection.prototype.getFieldInfo = function () { var field = this.getHyperlinkField(true); if (!isNullOrUndefined(field)) { var code = this.getFieldCode(field); var result = this.owner.editorModule.getFieldResultText(field); return { code: code, result: result }; } return undefined; }; Selection.prototype.isFootNoteParagraph = function (paragraph) { var container = this.getContainerWidget(paragraph); if (container instanceof FootNoteWidget && container.footNoteType === 'Footnote') { return true; } else { return false; } }; Selection.prototype.isEndNoteParagraph = function (paragraph) { var container = this.getContainerWidget(paragraph); if (container instanceof FootNoteWidget && container.footNoteType === 'Endnote') { return true; } else { return false; } }; /** * @param documentEditor * @private */ Selection.prototype.isFootEndNoteParagraph = function (paragraph) { if (this.isFootNoteParagraph(paragraph)) { return true; } else if (this.isEndNoteParagraph(paragraph)) { return true; } else { return false; } }; Selection.prototype.getSelBookmarks = function (includeHidden, isField) { var bookmarkCln = []; var fieldCln = []; var bookmarks = this.documentHelper.bookmarks; var fields = this.documentHelper.fields; var start = this.start; var end = this.end; if (!this.isForward) { start = this.end; end = this.start; } var elementStart; var elementEnd; var isCellSelected = false; var selectedCells = this.getSelectedCells(); var count = isField ? fields.length : bookmarks.length; for (var i = 0; i < count; i++) { if (isField || (includeHidden || !includeHidden && bookmarks.keys[i].indexOf('_') !== 0)) { elementStart = isField ? fields[i] : bookmarks.get(bookmarks.keys[i]); elementEnd = isField ? fields[i].fieldEnd : elementStart.reference; if (isNullOrUndefined(elementEnd)) { continue; } var bmStartPos = this.getElementPosition(elementStart, false, false).startPosition; var bmEndPos = this.getElementPosition(elementEnd, true, false).startPosition; if (!isField && !isNullOrUndefined(elementEnd.properties) && this.checkIsAfterBookmark(elementEnd.properties)) { bmEndPos.offset++; } if (bmStartPos.paragraph.isInsideTable || bmEndPos.paragraph.isInsideTable) { if (selectedCells.length > 0) { if (selectedCells.indexOf(bmStartPos.paragraph.associatedCell) >= 0 || selectedCells.indexOf(bmEndPos.paragraph.associatedCell) >= 0) { isCellSelected = true; } else { isCellSelected = false; if (selectedCells.indexOf(bmStartPos.paragraph.associatedCell) < 0 || selectedCells.indexOf(bmEndPos.paragraph.associatedCell) < 0) { var endCell = end.paragraph.isInsideTable && end.paragraph.associatedCell; var bmEndPosCell = bmEndPos.paragraph.associatedCell; if (endCell && bmEndPosCell && endCell.ownerTable.equals(bmEndPosCell.ownerTable) && !(endCell.ownerTable && selectedCells.indexOf(this.getCellInTable(endCell.ownerTable, bmEndPosCell)) >= 0)) { // Bug 891131: The below code is comment to resolve the bookmark is not retrieved when selecting the table cell // continue; } } } } else { isCellSelected = false; } } else { isCellSelected = false; } if ((start.isExistAfter(bmStartPos) || start.isAtSamePosition(bmStartPos)) && (end.isExistBefore(bmEndPos) || end.isAtSamePosition(bmEndPos)) || ((bmStartPos.isExistAfter(start) || bmStartPos.isAtSamePosition(start)) && (bmEndPos.isExistBefore(end) || bmEndPos.isAtSamePosition(end))) || (bmStartPos.isExistAfter(start) && bmStartPos.isExistBefore(end) && (end.isExistAfter(bmEndPos) || end.isExistBefore(bmEndPos))) || (bmEndPos.isExistBefore(end) && bmEndPos.isExistAfter(start) && (start.isExistBefore(bmStartPos) || start.isExistAfter(bmStartPos))) || isCellSelected) { if (isField) { var fieldInfo = { field: elementStart }; fieldCln.push(fieldInfo); } else { bookmarkCln.push(elementStart.name); } } } } if (isField) { return fieldCln; } else { return bookmarkCln; } }; Selection.prototype.checkIsAfterBookmark = function (properties) { if (properties.hasOwnProperty('isAfterParagraphMark') && properties['isAfterParagraphMark']) { return true; } if (properties.hasOwnProperty('isAfterTableMark') && properties['isAfterTableMark']) { return true; } if (properties.hasOwnProperty('isAfterRowMark') && properties['isAfterRowMark']) { return true; } if (properties.hasOwnProperty('isAfterCellMark') && properties['isAfterCellMark']) { return true; } return false; }; Object.defineProperty(Selection.prototype, "viewer", { /** * * @private */ get: function () { return this.owner.viewer; }, enumerable: true, configurable: true }); Selection.prototype.getModuleName = function () { return 'Selection'; }; Selection.prototype.checkLayout = function () { if (this.owner.layoutType === 'Continuous') { this.isWebLayout = true; this.documentHelper.isHeaderFooter = true; this.owner.layoutType = 'Pages'; this.owner.viewer.destroy(); this.owner.viewer = new PageLayoutViewer(this.owner); this.documentHelper.layout.layoutWholeDocument(); } }; //Public API /** * Moves the selection to the header of current page. * * @returns {void} */ Selection.prototype.goToHeader = function () { this.checkLayout(); this.owner.enableHeaderAndFooter = true; this.enableHeadersFootersRegion(this.start.paragraph.bodyWidget.page.headerWidget, this.start.paragraph.bodyWidget.page); this.isWebLayout = false; }; /** * Moves the selection to the footer of current page. * * @returns {void} */ Selection.prototype.goToFooter = function () { this.checkLayout(); this.owner.enableHeaderAndFooter = true; this.enableHeadersFootersRegion(this.start.paragraph.bodyWidget.page.footerWidget, this.start.paragraph.bodyWidget.page); this.isWebLayout = false; }; /** * Closes the header and footer region. * * @returns {void} */ Selection.prototype.closeHeaderFooter = function () { this.disableHeaderFooter(); if (this.documentHelper.isHeaderFooter && this.owner.layoutType === 'Pages') { this.owner.layoutType = 'Continuous'; this.documentHelper.isHeaderFooter = false; } }; /** * Closes the xml Pane region. * * @returns {void} */ Selection.prototype.closeXmlPane = function () { this.disableXml(); this.owner.enableXMLPane = false; if (this.documentHelper.isHeaderFooter && this.owner.layoutType === 'Pages') { this.owner.layoutType = 'Continuous'; this.documentHelper.isHeaderFooter = false; } }; /** * Moves the selection to the start of specified page number. * * @param pageNumber Specify the page number to move selection. * @returns {void} */ Selection.prototype.goToPage = function (pageNumber) { this.owner.scrollToPage(pageNumber); if (pageNumber >= 1 && pageNumber <= this.owner.documentHelper.pages.length) { var page = this.owner.documentHelper.pages[pageNumber - 1]; this.updateTextPositionForBlockContainer(page.bodyWidgets[0]); } }; /** * Selects the entire table if the context is within table. * * @returns {void} */ Selection.prototype.selectTable = function () { if (!this.owner.enableSelection) { return; } this.selectTableInternal(); }; /** * Selects the entire row if the context is within table. * * @returns {void} */ Selection.prototype.selectRow = function () { if (!this.owner.enableSelection) { return; } this.selectTableRow(); }; /** * Selects the entire column if the context is within table. * * @returns {void} */ Selection.prototype.selectColumn = function () { if (!this.owner.enableSelection) { return; } this.selectColumnInternal(); }; /** * Selects the entire cell if the context is within table. * * @returns {void} */ Selection.prototype.selectCell = function () { if (!this.owner.enableSelection) { return; } this.selectTableCell(); }; Selection.prototype.select = function (selectionSettings, startOrEnd) { if (typeof (selectionSettings) === 'string') { var startPosition = this.getTextPosBasedOnLogicalIndex(selectionSettings); var endPosition = this.getTextPosBasedOnLogicalIndex(startOrEnd); this.selectPosition(startPosition, endPosition); } else { var point = new Point(selectionSettings.x, selectionSettings.y); var pageCoordinates = this.viewer.findFocusedPage(point, true, false, this.isPageUpAndDown); if (selectionSettings.extend) { this.moveTextPosition(pageCoordinates, this.end); } else { this.documentHelper.updateTextPositionForSelection(pageCoordinates, 1); } } }; /** * Selects the content based on the specified start and end hierarchical index. * * @param start Specify the start index to select. * @param end Specify the end index to select. * @returns {void} */ Selection.prototype.selectByHierarchicalIndex = function (start, end) { var startPosition = this.getTextPosBasedOnLogicalIndex(start); var endPosition = this.getTextPosBasedOnLogicalIndex(end); this.selectPosition(startPosition, endPosition); }; Selection.prototype.selectField = function (fieldInfo) { if (!isNullOrUndefined(fieldInfo) && fieldInfo.field) { fieldInfo = fieldInfo.field; } if (this.isInField || !isNullOrUndefined(fieldInfo)) { if (isNullOrUndefined(fieldInfo)) { fieldInfo = this.getHyperlinkField(true); } this.selectFieldInternal(fieldInfo); } }; /** * @private * @param fieldStart * @returns {void} */ Selection.prototype.selectContentControlInternal = function (fieldStart) { if (fieldStart) { var offset = fieldStart.line.getOffset(fieldStart, 1); var startPosition = new TextPosition(this.owner); var fieldEnd = fieldStart.reference; startPosition.setPositionParagraph(fieldStart.line, offset); var endoffset = fieldEnd.line.getOffset(fieldEnd, 0); var endPosition = new TextPosition(this.owner); endPosition.setPositionParagraph(fieldEnd.line, endoffset); //selects the field range this.documentHelper.selection.selectRange(startPosition, endPosition); } }; /** * @private * @param fieldStart * @returns {void} */ Selection.prototype.selectFieldInternal = function (fieldStart, isKeyBoardEvent, isReplacingFormResult) { if (fieldStart) { var formFillingMode = this.documentHelper.isFormFillProtectedMode || isReplacingFormResult; var fieldEnd = fieldStart.fieldEnd; if (formFillingMode) { fieldStart = fieldStart.fieldSeparator; } var offset = fieldStart.line.getOffset(fieldStart, formFillingMode ? 1 : 0); var startPosition = new TextPosition(this.owner); startPosition.setPositionParagraph(fieldStart.line, offset); var isBookmark = fieldStart.nextNode instanceof BookmarkElementBox; if (isBookmark && !formFillingMode && fieldStart.nextElement.reference) { fieldEnd = fieldStart.nextElement.reference; } var endoffset = fieldEnd.line.getOffset(fieldEnd, formFillingMode ? 0 : 1); var endPosition = new TextPosition(this.owner); endPosition.setPositionParagraph(fieldEnd.line, endoffset); //selects the field range this.documentHelper.selection.selectRange(startPosition, endPosition); if (!isReplacingFormResult) { this.triggerFormFillEvent(isKeyBoardEvent); } } }; /** * @private * @param contentControl * @returns {void} */ Selection.prototype.selectContentControl = function (contentControl) { if (contentControl) { var fieldEnd = contentControl.reference; var offset = contentControl.line.getOffset(contentControl, 0); var startPosition = new TextPosition(this.owner); startPosition.setPositionParagraph(contentControl.line, offset); var endoffset = fieldEnd.line.getOffset(fieldEnd, 1); var endPosition = new TextPosition(this.owner); endPosition.setPositionParagraph(fieldEnd.line, endoffset); this.documentHelper.selection.selectRange(startPosition, endPosition); } }; /** * @param shape * @private * @returns {void} */ Selection.prototype.selectShape = function (shape) { if (shape) { var offset = shape.line.getOffset(shape, 0); var startPosition = new TextPosition(this.owner); startPosition.setPositionParagraph(shape.line, offset); var endoffset = shape.line.getOffset(shape, 1); var endPosition = new TextPosition(this.owner); endPosition.setPositionParagraph(shape.line, endoffset); this.documentHelper.selection.selectRange(startPosition, endPosition); } }; /** * Toggles the bold property of selected contents. * * @private * @returns {void} */ Selection.prototype.toggleBold = function () { if (this.owner.editorModule) { this.owner.editorModule.toggleBold(); } }; /** * Toggles the italic property of selected contents. * * @private * @returns {void} */ Selection.prototype.toggleItalic = function () { if (this.owner.editorModule) { this.owner.editorModule.toggleItalic(); } }; /** * Toggles the allCaps property of selected contents. * * @private * @returns {void} */ Selection.prototype.toggleAllCaps = function () { if (this.owner.editorModule) { this.owner.editorModule.toggleAllCaps(); } }; /** * Toggles the underline property of selected contents. * * @param {Underline} underline Default value of ‘underline’ parameter is Single. * @private * @returns {void} */ Selection.prototype.toggleUnderline = function (underline) { if (this.owner.editorModule) { this.owner.editorModule.toggleUnderline(underline); } }; /** * Toggles the strike through property of selected contents. * * @param {Strikethrough} strikethrough Default value of strikethrough parameter is SingleStrike. * @private * @returns {void} */ Selection.prototype.toggleStrikethrough = function (strikethrough) { if (this.owner.editorModule) { this.owner.editorModule.toggleStrikethrough(strikethrough); } }; /** * Toggles the highlight color property of selected contents. * * @param {HighlightColor} highlightColor Default value of ‘underline’ parameter is Yellow. * @private * @returns {void} */ Selection.prototype.toggleHighlightColor = function (highlightColor) { if (this.owner.editorModule) { this.owner.editorModule.toggleHighlightColor(highlightColor); } }; /** * Toggles the subscript formatting of selected contents. * * @private * @returns {void} */ Selection.prototype.toggleSubscript = function () { if (this.owner.editorModule) { this.owner.editorModule.toggleSubscript(); } }; /** * Toggles the superscript formatting of selected contents. * * @private * @returns {void} */ Selection.prototype.toggleSuperscript = function () { if (this.owner.editorModule) { this.owner.editorModule.toggleSuperscript(); } }; /** * Toggles the text alignment property of selected contents. * * @param {TextAlignment} textAlignment Default value of ‘textAlignment parameter is TextAlignment.Left. * @private * @returns {void} */ Selection.prototype.toggleTextAlignment = function (textAlignment) { if (this.owner.editorModule) { this.owner.editorModule.toggleTextAlignment(textAlignment); } }; /** * Increases the left indent of selected paragraphs to a factor of 36 points. * * @private * @returns {void} */ Selection.prototype.increaseIndent = function () { if (this.owner.editorModule) { this.owner.editorModule.increaseIndent(); } }; /** * Decreases the left indent of selected paragraphs to a factor of 36 points. * * @private * @returns {void} */ Selection.prototype.decreaseIndent = function () { if (this.owner.editorModule) { this.owner.editorModule.decreaseIndent(); } }; /** * Fires the `requestNavigate` event if current selection context is in hyperlink. * * @returns {void} */ Selection.prototype.navigateHyperlink = function () { var fieldBegin = this.getHyperlinkField(); if (fieldBegin) { this.fireRequestNavigate(fieldBegin); } }; /** * Navigate Hyperlink * * @param fieldBegin * @private * @returns {void} */ Selection.prototype.fireRequestNavigate = function (fieldBegin) { var code = this.getFieldCode(fieldBegin); if (code.toLowerCase().indexOf('ref ') === 0 && !code.match('\\h')) { return; } var hyperlink = new Hyperlink(fieldBegin, this); var eventArgs = { isHandled: false, navigationLink: hyperlink.navigationLink, linkType: hyperlink.linkType, localReference: hyperlink.localReference, source: this.owner }; this.owner.trigger(requestNavigateEvent, eventArgs); if (!eventArgs.isHandled) { this.documentHelper.selection.navigateBookmark(hyperlink.localReference, true); } }; /** * Copies the hyperlink URL if the context is within hyperlink. * * @returns {void} */ Selection.prototype.copyHyperlink = function () { var hyperLinkField = this.getHyperlinkField(); var linkText = this.getLinkText(hyperLinkField, true); this.copyToClipboard(linkText); }; Selection.prototype.isHideSelection = function (paragraph) { var bodyWgt = paragraph.bodyWidget; var sectionFormat = bodyWgt.sectionFormat; var pageHt = sectionFormat.pageHeight - sectionFormat.footerDistance; var headerFooterHt = bodyWgt.page.boundingRectangle.height / 100 * 40; return this.contextType.indexOf('Footer') >= 0 && (paragraph.y + paragraph.height > HelperMethods.convertPointToPixel(pageHt)) || this.contextType.indexOf('Header') >= 0 && paragraph.y + paragraph.height > headerFooterHt; }; //Selection add, Highlight, remove API starts /** * @private * @returns {void} */ Selection.prototype.highlightSelection = function (isSelectionChanged, isBookmark) { if (this.owner.enableImageResizerMode) { this.owner.imageResizerModule.hideImageResizer(); } if (this.isEmpty) { if (!this.isInShape && this.isHideSelection(this.start.paragraph)) { this.hideCaret(); return; } if (this.isInShape) { this.showResizerForShape(); } this.updateCaretPosition(); } else { if (this.isForward) { this.highlightSelectedContent(this.start, this.end); } else { this.highlightSelectedContent(this.end, this.start); } if (this.documentHelper.isComposingIME) { this.updateCaretPosition(); } } this.documentHelper.updateTouchMarkPosition(); if (isSelectionChanged) { this.documentHelper.scrollToPosition(this.start, this.end, undefined, isBookmark); } }; Selection.prototype.createHighlightBorder = function (lineWidget, width, left, top, isElementBoxHighlight, contentControl) { if (width < 0) { width = 0; } var paragraph = lineWidget.paragraph; var floatingItems = []; if (paragraph.floatingElements.length > 0) { for (var k = 0; k < paragraph.floatingElements.length; k++) { var shapeElement = paragraph.floatingElements[k]; if (shapeElement.line === lineWidget) { var startTextPos = this.start; var endTextPos = this.end; if (!this.isForward) { startTextPos = this.end; endTextPos = this.start; } var offset = shapeElement.line.getOffset(shapeElement, 0); if ((startTextPos.currentWidget !== lineWidget && endTextPos.currentWidget !== lineWidget) || (startTextPos.currentWidget === lineWidget && startTextPos.offset <= offset && (endTextPos.currentWidget === lineWidget && endTextPos.offset >= offset + 1 || endTextPos.currentWidget !== lineWidget)) || (startTextPos.currentWidget !== lineWidget && endTextPos.currentWidget === lineWidget && endTextPos.offset >= offset)) { floatingItems.push(shapeElement); } } } } var page = this.getPage(lineWidget.paragraph); var height = lineWidget.height; var widgets = this.selectedWidgets; var selectionWidget = undefined; var selectionWidgetCollection = undefined; if (this.isHighlightContentControlEditRegion && !isNullOrUndefined(contentControl)) { if (width === 0) { width = this.documentHelper.textHelper.getParagraphMarkSize(paragraph.characterFormat).Width; } this.addContentControlEditRegionHighlight(lineWidget, left, width, contentControl); return; } else if (this.isHightlightEditRegionInternal) { this.addEditRegionHighlight(lineWidget, left, width); return; } else if (this.isHighlightFormFields) { this.addFormFieldHighlight(lineWidget, left, width); return; } else { if (widgets.containsKey(lineWidget)) { if (widgets.get(lineWidget) instanceof SelectionWidgetInfo) { selectionWidget = widgets.get(lineWidget); // if the line element has already added with SelectionWidgetInfo // now its need to be added as ElementBox highlighting them remove it from dictionary and add it collection. if (isElementBoxHighlight) { widgets.remove(lineWidget); selectionWidgetCollection = []; widgets.add(lineWidget, selectionWidgetCollection); } } else { selectionWidgetCollection = widgets.get(lineWidget); } } else { if (isElementBoxHighlight) { selectionWidgetCollection = []; widgets.add(lin