UNPKG

@syncfusion/ej2-documenteditor

Version:

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

1,355 lines 556 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 } 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 } 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; /** * @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 = []; /** * @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 }); 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); }, 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 }); /** * 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); }; 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 }); /** * 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) { var bookmarkCln = []; var bookmarks = this.documentHelper.bookmarks; var start = this.start; var end = this.end; if (!this.isForward) { start = this.end; end = this.start; } var bookmrkStart; var bookmrkEnd; var isCellSelected = false; var selectedCells = this.getSelectedCells(); for (var i = 0; i < bookmarks.length; i++) { if (includeHidden || !includeHidden && bookmarks.keys[i].indexOf('_') !== 0) { bookmrkStart = bookmarks.get(bookmarks.keys[i]); bookmrkEnd = bookmrkStart.reference; if (isNullOrUndefined(bookmrkEnd)) { continue; } var bmStartPos = this.getElementPosition(bookmrkStart).startPosition; var bmEndPos = this.getElementPosition(bookmrkEnd, true).startPosition; 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) { bookmarkCln.push(bookmrkStart.name); } } } return bookmarkCln; }; 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.owner.editorModule.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); 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); }; /** * Selects the current field if selection is in field * * @param fieldStart Specify the field start to select. * @returns {void} */ Selection.prototype.selectField = function (fieldStart) { if (this.isInField || !isNullOrUndefined(fieldStart)) { if (isNullOrUndefined(fieldStart)) { fieldStart = this.getHyperlinkField(true); } this.selectFieldInternal(fieldStart); } }; /** * @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.selectContentConterol = 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(lineWidget, selectionWidgetCollection); } else { var wrapPosition = this.getWrapPosition(lineWidget, paragraph); if (wrapPosition.length > 0) { var selectionWidgetInfos = this.splitSelectionHighlightPosition(left, width, wrapPosition); if (selectionWidgetInfos.length > 0) { selectionWidgetInfos[0].floatingItems = floatingItems; widgets.add(lineWidget, selectionWidgetInfos); this.renderHighlight(page, lineWidget, selectionWidgetInfos, top, floatingItems); return; } else { selectionWidget = new SelectionWidgetInfo(left, width); selectionWidget.floatingItems = floatingItems; widgets.add(lineWidget, selectionWidget); } } else { selectionWidget = new SelectionWidgetInfo(left, width); selectionWidget.floatingItems = floatingItems; widgets.add(lineWidget, selectionWidget); } } } if (selectionWidget === undefined) { selectionWidget = new SelectionWidgetInfo(left, width); selectionWidget.floatingItems = floatingItems; widgets.add(lineWidget, selectionWidget); } } this.renderHighlight(page, lineWidget, [selectionWidget], top, floatingItems); if (isElementBoxHighlight) { selectionWidgetCollection.push(selectionWidget); } }; Selection.prototype.renderHighlight = function (page, lineWidget, selectionWidget, top, floatingItems) { var documentHelper = this.owner.documentHelper; var pageTop = this.getPageTop(page); var pageLeft = page.boundingRectangle.x; var height = lineWidget.height; if (this.viewer.containerTop <= pageTop || pageTop < this.viewer.containerTop + documentHelper.selectionCanvas.height) { var zoomFactor = documentHelper.zoomFactor; this.clipSelection(page, pageTop); for (var i = 0; i < selectionWidget.length; i++) { var selectedWidget = selectionWidget[i]; var left = selectedWidget.left; var width = selectedWidget.width; if (this.documentHelper.isComposingIME) { this.renderDashLine(documentHelper.selectionContext, page, lineWidget, (pageLeft + (left * zoomFactor)) - this.viewer.containerLeft, top, width * zoomFactor, height); } else { this.documentHelper.selectionContext.fillStyle = 'gray'; documentHelper.selectionContext.globalAlpha = 0.4; documentHelper.selectionContext.fillRect((pageLeft + (left * zoomFactor)) - this.viewer.containerLeft, (pageTop + (top * zoomFactor)) - this.viewer.containerTop, width * zoomFactor, height * zoomFactor); } } if (floatingItems.length > 0) { for (var z = 0; z < floatingItems.length; z++) { var left = floatingItems[z].x; var shapeTop = floatingItems[z].y; var shapeWidth = floatingItems[z].width; var shapeHeight = floatingItems[z].height; documentHelper.selectionContext.fillRect((pageLeft + (left * zoomFactor)) - this.viewer.containerLeft, (pageTop + (shapeTop * zoomFactor)) - this.viewer.containerTop, shapeWidth * zoomFactor, shapeHeight * zoomFactor); } } documentHelper.selectionContext.restore(); } }; Selection.prototype.getWrapPosition = function (lineWidget, paragraph) { var bodyWidget = paragraph.bodyWidget; if (!isNullOrUndefined(bodyWidget) && bodyWidget.floatingElements.length > 0 && lineWidget.children.length > 0) { v