@syncfusion/ej2-documenteditor
Version:
Feature-rich document editor control with built-in support for context menu, options pane and dialogs.
1,115 lines (1,114 loc) • 124 kB
JavaScript
import { Widget, BodyWidget, TableRowWidget, TableWidget, LineWidget, ElementBox, TextElementBox, ListTextElementBox, ImageElementBox, ParagraphWidget, TableCellWidget, FieldElementBox, BlockContainer, BookmarkElementBox, CommentCharacterElementBox, ContentControl } from '../index';
import { HelperMethods } from '../index';
import { Point } from '../index';
import { isNullOrUndefined } from '@syncfusion/ej2-base';
import { EditRangeEndElementBox } from '../viewer/page';
/* eslint-disable */
/**
* @private
*/
var TextPosition = /** @class */ (function () {
function TextPosition(owner) {
/**
* @private
*/
this.location = new Point(0, 0);
/**
* @private
*/
this.isUpdateLocation = true;
this.owner = owner;
this.documentHelper = this.owner.documentHelper;
}
Object.defineProperty(TextPosition.prototype, "paragraph", {
/**
* @private
*/
get: function () {
return this.currentWidget.paragraph;
},
enumerable: true,
configurable: true
});
Object.defineProperty(TextPosition.prototype, "isAtParagraphStart", {
/**
* @private
*/
get: function () {
return this.currentWidget.paragraph && this.currentWidget === this.currentWidget.paragraph.firstChild && this.offset === this.owner.selectionModule.getStartOffset(this.paragraph);
},
enumerable: true,
configurable: true
});
Object.defineProperty(TextPosition.prototype, "isAtParagraphEnd", {
/**
* @private
*/
get: function () {
return this.owner.selectionModule.isParagraphLastLine(this.currentWidget)
&& this.offset === this.owner.selectionModule.getLineLength(this.currentWidget);
},
enumerable: true,
configurable: true
});
Object.defineProperty(TextPosition.prototype, "isCurrentParaBidi", {
/**
* @private
*/
get: function () {
if (!isNullOrUndefined(this.currentWidget.paragraph)) {
return this.currentWidget.paragraph.paragraphFormat.bidi;
}
return false;
},
enumerable: true,
configurable: true
});
Object.defineProperty(TextPosition.prototype, "selection", {
/**
* @private
*/
get: function () {
return this.owner.selectionModule;
},
enumerable: true,
configurable: true
});
Object.defineProperty(TextPosition.prototype, "hierarchicalPosition", {
/**
* Gets the hierarchical position of logical text position in the document
*
* @returns {string}
*/
get: function () {
return this.getHierarchicalIndexInternal();
},
enumerable: true,
configurable: true
});
Object.defineProperty(TextPosition.prototype, "viewer", {
get: function () {
return this.owner.viewer;
},
enumerable: true,
configurable: true
});
/**
* Return clone of current text position
*
* @private
*/
TextPosition.prototype.clone = function () {
var textPosition = new TextPosition(this.owner);
textPosition.currentWidget = this.currentWidget;
textPosition.offset = this.offset;
textPosition.location = this.location;
return textPosition;
};
/**
* @private
*/
TextPosition.prototype.containsRtlText = function (widget) {
for (var i = 0; i < widget.children.length; i++) {
if (widget.children[i].isRightToLeft) {
return true;
}
}
return false;
};
/**
* Set text position for paragraph and inline
*
* @private
*/
TextPosition.prototype.setPositionForSelection = function (line, element, index, physicalLocation) {
//Set the start end position
var isParagraphEnd = false;
if (isNullOrUndefined(element)) {
this.currentWidget = line;
}
else {
this.currentWidget = element.line;
if (element.nextNode instanceof FieldElementBox && index > element.length) {
isParagraphEnd = this.selection.isLastRenderedInline(element, element.length);
}
}
this.location = physicalLocation;
if (isParagraphEnd) {
this.offset = this.selection.getParagraphLength(this.currentWidget.paragraph) + 1;
}
else {
this.offset = this.currentWidget.getOffset(element, index);
}
};
/**
* Set text position
*
* @private
*/
TextPosition.prototype.setPositionFromLine = function (line, offset, location) {
this.currentWidget = line;
this.offset = offset;
if (location instanceof Point) {
this.location.copy(location);
}
};
/**
* Set text position
*
* @private
*/
TextPosition.prototype.setPosition = function (line, positionAtStart) {
this.currentWidget = line;
this.offset = positionAtStart ? this.selection.getStartOffset(line.paragraph)
: line.paragraph.lastChild.getEndOffset() + 1;
this.updatePhysicalPosition(true);
};
/**
* Set position for text position
*
* @private
*/
TextPosition.prototype.setPositionInternal = function (textPosition) {
this.currentWidget = textPosition.currentWidget;
this.offset = textPosition.offset;
this.location = textPosition.location;
};
/**
* Set position for current index
*
* @private
*/
TextPosition.prototype.setPositionForCurrentIndex = function (hierarchicalIndex) {
var index = { index: hierarchicalIndex };
var paragraph = this.getParagraphWidget(index); //ref hierarchicalIndex
this.offset = parseFloat(index.index);
this.setPositionParagraph(paragraph, this.offset);
};
/**
* Get Page
*
*/
TextPosition.prototype.getPage = function (position) {
var page;
var index = position.index.indexOf(';');
var newValue = '0';
if (index >= 0) {
newValue = position.index.substring(0, index);
position.index = position.index.substring(index).replace(';', '');
}
index = parseInt(newValue, 10);
page = this.documentHelper.pages[index];
return page;
};
/**
* @private
*/
TextPosition.prototype.getParagraphWidget = function (position) {
if (isNullOrUndefined(position.index)) {
return undefined;
}
var page = this.getPage(position);
var child = this.getLineWidget(undefined, position, page);
return child;
};
/**
* @private
*/
TextPosition.prototype.getLineWidget = function (widget, position, page) {
if (isNullOrUndefined(position.index)) {
return undefined;
}
var index = position.index.indexOf(';');
var value = '0';
if (index >= 0) {
value = position.index.substring(0, index);
position.index = position.index.substring(index).replace(';', '');
}
if (value === 'H' || value === 'F') {
if (value === 'H') {
widget = page.headerWidget;
}
else {
widget = page.footerWidget;
}
}
else if (value === 'FN' || value === 'EN') {
var index1 = position.index.indexOf(';');
var value1 = position.index.substring(0, index1);
position.index = position.index.substring(index1).replace(';', '');
if (value === 'FN') {
widget = page.footnoteWidget.bodyWidgets[value1];
}
else {
widget = page.endnoteWidget.bodyWidgets[value1];
}
}
else if (!isNullOrUndefined(page)) {
if (parseInt(value, 10) < page.bodyWidgets.length) {
widget = page.bodyWidgets[parseInt(value, 10)];
}
else {
widget = page.bodyWidgets[0];
}
}
index = parseInt(value, 10);
if (widget instanceof BlockContainer) {
index = position.index.indexOf(';');
value = '0';
value = position.index.substring(0, index);
position.index = position.index.substring(index).replace(';', '');
index = parseInt(value, 10);
}
if (widget instanceof TableRowWidget && index >= widget.childWidgets.length) {
position.index = '0;0';
index = widget.childWidgets.length - 1;
}
if (index >= 0 && index < widget.childWidgets.length) {
var child = widget.childWidgets[index];
if (child instanceof LineWidget) {
if (position.index.indexOf(';') > 0) {
position.index = '0';
}
return child;
}
if (child instanceof Widget) {
if (position.index.indexOf(';') > 0) {
return this.getLineWidget(child, position);
}
else {
//If table is shifted to previous text position then return the first paragraph within table.
if (child instanceof TableWidget) {
return this.getLineWidget(this.documentHelper.getFirstParagraphInFirstCell(child), position);
}
else if (child instanceof TableRowWidget && position.index.indexOf(';') === -1) {
return this.documentHelper.getFirstParagraphInFirstCell(child.ownerTable).childWidgets[0];
}
return undefined;
}
}
}
else if (widget.nextRenderedWidget instanceof Widget) {
position.index = '0';
if (widget.nextRenderedWidget instanceof TableWidget) {
return this.documentHelper.getFirstParagraphInFirstCell(widget.nextRenderedWidget).firstChild;
}
return this.getLineWidget(widget.nextRenderedWidget, position);
}
return undefined;
};
/**
* Update physical location of paragraph
*
* @private
*/
TextPosition.prototype.updatePhysicalPosition = function (moveNextLine) {
if (this.currentWidget && this.owner.isLayoutEnabled && this.isUpdateLocation) {
this.location = this.selection.getPhysicalPositionInternal(this.currentWidget, this.offset, moveNextLine);
}
};
/**
* Return true if text position are in same paragraph and offset
*
* @private
*/
TextPosition.prototype.isAtSamePosition = function (textPosition) {
return this.currentWidget === textPosition.currentWidget
&& this.offset === textPosition.offset;
};
/**
* Return true if text position is in same paragraph index
* @private
*/
TextPosition.prototype.isInSameParagraphIndex = function (textPosition) {
if (isNullOrUndefined(textPosition)) {
throw new Error('textPosition is undefined.');
}
return this.paragraph.index === textPosition.paragraph.index;
};
/**
* Return true if text position is in same paragraph
*
* @private
*/
TextPosition.prototype.isInSameParagraph = function (textPosition) {
if (isNullOrUndefined(textPosition)) {
throw new Error('textPosition is undefined.');
}
return this.paragraph === textPosition.paragraph;
};
/**
* Return true if start and end is in same list
*
* @private
*/
TextPosition.prototype.isInSameListParagraph = function (textPosition) {
if (isNullOrUndefined(textPosition)) {
throw new Error('textPosition is undefined.');
}
return this.paragraph.paragraphFormat.listFormat.listId === textPosition.paragraph.paragraphFormat.listFormat.listId;
};
/**
* Return true is current text position exist before given text position
*
* @private
*/
TextPosition.prototype.isExistBefore = function (textPosition) {
if (isNullOrUndefined(textPosition)) {
throw new Error('textPosition is undefined.');
}
if (this.currentWidget === textPosition.currentWidget) {
return this.offset < textPosition.offset;
}
var currentParagraph = this.currentWidget.paragraph;
var paragraph = textPosition.currentWidget.paragraph;
if (currentParagraph === paragraph) {
return currentParagraph.childWidgets.indexOf(this.currentWidget) < paragraph.childWidgets.indexOf(textPosition.currentWidget);
}
if (currentParagraph.containerWidget === paragraph.containerWidget) {
if (currentParagraph.isInsideTable) {
return currentParagraph.associatedCell.childWidgets.indexOf(currentParagraph) <
paragraph.associatedCell.childWidgets.indexOf(paragraph);
//handle after header footer implementation
// } else if ((this.currentParagraph).owner instanceof WHeaderFooter) {
// return ((this.currentParagraph).owner as WHeaderFooter).blocks.indexOf((this.currentParagraph)) <
// ((textPosition.currentParagraph).owner as WHeaderFooter).blocks.indexOf((textPosition.currentParagraph));
}
else {
return (currentParagraph.containerWidget.childWidgets.indexOf(currentParagraph)) <
(paragraph.containerWidget.childWidgets.indexOf(paragraph));
}
}
return this.owner.selectionModule.isExistBefore(currentParagraph, paragraph);
};
/**
* Return true is current text position exist after given text position
*
* @private
*/
TextPosition.prototype.isExistAfter = function (textPosition) {
if (isNullOrUndefined(textPosition)) {
throw new Error('textPosition is undefined.');
}
if (this.currentWidget === textPosition.currentWidget) {
return this.offset > textPosition.offset;
}
if (this.currentWidget.paragraph === textPosition.currentWidget.paragraph) {
return this.currentWidget.paragraph.childWidgets.indexOf(this.currentWidget) >
textPosition.currentWidget.paragraph.childWidgets.indexOf(textPosition.currentWidget);
}
var startParagraph = this.currentWidget.paragraph;
var endParagraph = textPosition.currentWidget.paragraph;
if (!isNullOrUndefined(startParagraph) && !isNullOrUndefined(endParagraph)) {
if (startParagraph.containerWidget instanceof BodyWidget && endParagraph.containerWidget instanceof BodyWidget &&
startParagraph.containerWidget === endParagraph.containerWidget) {
if (startParagraph.isInsideTable && endParagraph.isInsideTable) {
return startParagraph.associatedCell.childWidgets.indexOf(startParagraph) >
endParagraph.associatedCell.childWidgets.indexOf(endParagraph);
// } else if ((this.currentParagraph).owner instanceof WHeaderFooter) {
// return ((this.currentParagraph).owner as WHeaderFooter).blocks.indexOf((this.currentParagraph)) >
// ((textPosition.currentParagraph).owner as WHeaderFooter).blocks.indexOf((textPosition.currentParagraph));
}
else {
return (startParagraph.containerWidget.childWidgets.indexOf(startParagraph) >
(endParagraph.containerWidget.childWidgets.indexOf(endParagraph)));
}
}
return this.owner.selectionModule.isExistAfter(startParagraph, endParagraph);
}
return false;
};
/**
* Return hierarchical index of current text position
*
* @private
*/
TextPosition.prototype.getHierarchicalIndexInternal = function () {
return this.getHierarchicalIndex(this.currentWidget, this.offset.toString());
};
/**
* @private
*/
TextPosition.prototype.getHierarchicalIndex = function (line, hierarchicalIndex) {
var node = line;
if (node) {
return node.getHierarchicalIndex(hierarchicalIndex);
}
return hierarchicalIndex;
};
/**
* @private
*/
TextPosition.prototype.setPositionParagraph = function (line, offsetInLine, isRetrieveBookmark) {
this.currentWidget = line;
this.offset = offsetInLine;
if (!isRetrieveBookmark) {
this.updatePhysicalPosition(true);
}
};
/**
* @private
*/
TextPosition.prototype.setPositionForLineWidget = function (lineWidget, offset) {
var lineLength = this.selection.getLineLength(lineWidget);
var lineIndex = lineWidget.paragraph.childWidgets.indexOf(lineWidget);
if (lineWidget.isLastLine()) {
if (!isNullOrUndefined(lineWidget.paragraph.bodyWidget.footNoteReference)) {
lineLength = lineLength + lineWidget.paragraph.bodyWidget.footNoteReference.text.length;
}
else {
lineLength = lineLength + 1;
}
}
if (offset > lineLength) {
var nextLineWidget = void 0;
if (lineIndex >= lineWidget.paragraph.childWidgets.length - 1) {
var nextBlock = this.selection.getNextRenderedBlock(lineWidget.paragraph);
if (nextBlock && nextBlock.index === lineWidget.paragraph.index) {
nextLineWidget = nextBlock.firstChild;
}
}
else {
nextLineWidget = lineWidget.paragraph.childWidgets[lineIndex + 1];
}
this.setPositionForLineWidget(nextLineWidget, offset - lineLength);
return;
}
else if (offset < 0) {
var prevLine = lineWidget.paragraph.childWidgets[lineIndex - 1];
var currentOffSet = this.selection.getLineLength(prevLine) + offset;
this.setPositionForLineWidget(prevLine, currentOffSet);
return;
}
else {
this.currentWidget = lineWidget;
this.offset = offset;
}
this.updatePhysicalPosition(true);
};
/**
* move to next text position
*
* @private
*/
TextPosition.prototype.moveNextPosition = function (isNavigate) {
if (isNullOrUndefined(isNavigate)) {
isNavigate = true;
}
var inline = this.selection.getNextStartInline(this.currentWidget, this.offset);
if (inline instanceof FieldElementBox && inline.fieldType === 0 && !isNullOrUndefined(inline.fieldEnd)) {
if (isNavigate) {
this.moveNextPositionInternal(inline);
this.moveNextPosition();
return;
}
else {
var line = inline.fieldEnd.line;
var fieldEnd = inline.fieldEnd;
var fieldEndOffset = line.getOffset(fieldEnd, 1);
var fieldEndIndex = this.getHierarchicalIndex(line, fieldEndOffset.toString());
if (TextPosition.isForwardSelection(this.selection.end.getHierarchicalIndexInternal(), fieldEndIndex)) {
//If field end is after selection end, extend selection end to field end.
this.selection.end.moveToInline(inline.fieldEnd, 1);
return;
}
this.moveToInline(inline.fieldEnd, 1);
}
}
var nextOffset = this.selection.getNextValidOffset(this.currentWidget, this.offset);
var lineIndex = this.paragraph.childWidgets.indexOf(this.currentWidget);
var index = 0;
if (nextOffset > this.offset) {
this.offset = nextOffset;
var info = this.currentWidget.getInline(this.offset, index);
inline = info.element;
index = info.index;
if (!isNullOrUndefined(inline) && index === inline.length && (inline.nextNode instanceof FieldElementBox
|| inline.nextNode instanceof BookmarkElementBox)) {
var nextValidInline = this.documentHelper.getNextValidElement(inline.nextNode);
//Moves to field end mark or Bookmark end.
if (nextValidInline instanceof FieldElementBox && nextValidInline.fieldType === 1
|| nextValidInline instanceof BookmarkElementBox && nextValidInline.bookmarkType === 1) {
inline = nextValidInline;
this.currentWidget = inline.line;
this.offset = this.currentWidget.getOffset(inline, this.documentHelper.isFormFillProtectedMode ? 0 : 1);
}
}
}
else if (lineIndex + 1 < this.paragraph.childWidgets.length) {
var nextLineWidget = this.paragraph.childWidgets[lineIndex + 1];
while (nextLineWidget && nextLineWidget.height === 0) {
if (isNullOrUndefined(nextLineWidget.nextLine)) {
var block = this.selection.getNextParagraphBlock(nextLineWidget.paragraph);
if (!isNullOrUndefined(block)) {
this.currentWidget = nextLineWidget;
this.updateOffsetToNextParagraph(index, false);
return;
}
}
nextLineWidget = nextLineWidget.nextLine;
}
if (nextLineWidget) {
this.currentWidget = nextLineWidget;
this.offset = this.selection.getStartLineOffset(this.currentWidget);
}
var inlineObj = this.currentWidget.getInline(this.offset, index);
inline = inlineObj.element;
index = inlineObj.index;
if (inline instanceof FieldElementBox && inline.fieldType === 0) {
this.offset++;
}
}
else {
this.updateOffsetToNextParagraph(index, false, isNavigate);
}
//Gets physical position in current page.
this.updatePhysicalPosition(true);
};
/**
* Move text position to previous paragraph inside table
*
* @private
*/
TextPosition.prototype.moveToPreviousParagraphInTable = function (selection) {
var previousParagraph;
var currentPara = this.currentWidget.paragraph;
if (currentPara.isInsideTable) {
previousParagraph = selection.getPreviousSelectionCell(currentPara.associatedCell);
}
else {
previousParagraph = selection.getPreviousParagraphBlock(currentPara);
}
if (isNullOrUndefined(previousParagraph)) {
return;
}
this.currentWidget = previousParagraph.childWidgets[previousParagraph.childWidgets.length - 1];
this.offset = this.currentWidget.getEndOffset() + 1;
};
TextPosition.prototype.nextValidVisibleBlock = function (visibleBlock, isStart) {
var currentValidVisibleBlock = visibleBlock;
while (visibleBlock && ((visibleBlock.characterFormat.hidden && visibleBlock.height === 0) || (!visibleBlock.isEmpty() && !visibleBlock.characterFormat.hidden && visibleBlock.height === 0 && visibleBlock.firstChild.children[0].characterFormat.hidden))) {
visibleBlock = isStart ? this.selection.getNextParagraphBlock(visibleBlock) : this.selection.getPreviousParagraphBlock(visibleBlock);
}
if (isNullOrUndefined(visibleBlock)) {
return currentValidVisibleBlock;
}
return visibleBlock;
};
TextPosition.prototype.setPositionForValidLine = function (cell, isNext, positionAtStart) {
var visibleBlock;
if (!isNext) {
visibleBlock = this.selection.getLastParagraph(cell);
visibleBlock = this.nextValidVisibleBlock(visibleBlock, false);
this.setPosition(this.getValidVisibleLine(visibleBlock.childWidgets[visibleBlock.childWidgets.length - 1], isNext), positionAtStart);
}
else {
visibleBlock = this.selection.getFirstParagraph(cell);
visibleBlock = this.nextValidVisibleBlock(visibleBlock, true);
this.setPosition(this.getValidVisibleLine(visibleBlock.childWidgets[0], isNext), positionAtStart);
}
};
TextPosition.prototype.updateOffsetToNextParagraph = function (indexInInline, isHighlight, isNavigate) {
//Moves to owner and get next paragraph.
var inline;
var positionAtStart = false;
var nextParagraph = undefined;
var lineIndex = this.paragraph.childWidgets.indexOf(this.currentWidget);
if (!isHighlight) {
nextParagraph = this.selection.getNextParagraphBlock(this.paragraph);
nextParagraph = this.nextValidVisibleBlock(nextParagraph, true);
}
else if (lineIndex + 1 < this.paragraph.childWidgets.length) {
var nextLineWidget = this.paragraph.childWidgets[lineIndex + 1];
if (nextLineWidget) {
this.currentWidget = nextLineWidget;
this.offset = 1;
}
}
else {
nextParagraph = this.selection.getNextSelectionBlock(this.paragraph);
if (!isNullOrUndefined(nextParagraph)) {
if (nextParagraph.containerWidget instanceof TableCellWidget) {
if (this.selection.start.paragraph.isInsideTable) {
var containerCell = this.selection.getContainerCellOf(this.selection.start.paragraph.associatedCell, nextParagraph.associatedCell);
positionAtStart = !containerCell.ownerTable.contains(nextParagraph.associatedCell);
}
else {
positionAtStart = true;
}
}
}
}
if (!isNullOrUndefined(nextParagraph) && nextParagraph.childWidgets.length > 0) {
if (!positionAtStart) {
this.currentWidget = this.getValidVisibleLine(nextParagraph.firstChild, true);
this.offset = isHighlight ? 1 : this.selection.getStartLineOffset(this.currentWidget, isNavigate);
}
else {
this.currentWidget = this.getValidVisibleLine(nextParagraph.lastChild, false);
this.offset = this.selection.getLineLength(this.currentWidget) + 1;
}
}
var inlineObj = this.currentWidget.getInline(this.offset, indexInInline);
inline = inlineObj.element;
indexInInline = inlineObj.index;
if (inline instanceof FieldElementBox && inline.fieldType === 0) {
this.offset++;
}
};
TextPosition.prototype.getValidVisibleLine = function (visibleLine, isNext) {
var currentVisibleLine = visibleLine;
if (isNext) {
while (visibleLine && visibleLine.height === 0) {
visibleLine = visibleLine.nextLine;
}
}
else {
while (visibleLine && visibleLine.height === 0) {
visibleLine = visibleLine.previousLine;
}
}
if (visibleLine) {
return visibleLine;
}
return currentVisibleLine;
};
TextPosition.prototype.updateOffsetToPrevPosition = function (index, isHighlight) {
var inlineInfo;
var inline;
var lineIndex = this.paragraph.childWidgets.indexOf(this.currentWidget);
var prevOffset = this.selection.getPreviousValidOffset(this.currentWidget, this.offset);
var isMoveToVisibleBlock = true;
if (this.offset > prevOffset) {
this.offset = prevOffset;
isMoveToVisibleBlock = false;
}
else if (lineIndex > 0) {
var prevLineWidget = this.paragraph.childWidgets[lineIndex - 1];
while (prevLineWidget && prevLineWidget.height === 0) {
if (isNullOrUndefined(prevLineWidget.previousLine)) {
var block = this.selection.getPreviousParagraphBlock(prevLineWidget.paragraph);
if (!isNullOrUndefined(block)) {
this.currentWidget = prevLineWidget;
isMoveToVisibleBlock = true;
break;
}
}
prevLineWidget = prevLineWidget.previousLine;
}
if (prevLineWidget) {
isMoveToVisibleBlock = false;
this.currentWidget = prevLineWidget;
var endOffset = this.currentWidget.getEndOffset();
this.offset = endOffset > 0 ? endOffset - 1 : endOffset;
var length_1 = 0;
var visibleElement = this.selection.getElementInfo(this.currentWidget, this.offset).element;
while (!isNullOrUndefined(visibleElement) && visibleElement.characterFormat.hidden) {
length_1 += visibleElement.length;
visibleElement = visibleElement.previousElement;
}
this.offset -= length_1;
}
}
if (isMoveToVisibleBlock) {
//Moves to owner and get previous paragraph.
var previousParagraph = undefined;
var positionAtStart = false;
if (!isHighlight) {
previousParagraph = this.selection.getPreviousParagraphBlock(this.paragraph);
previousParagraph = this.nextValidVisibleBlock(previousParagraph, false);
}
else {
previousParagraph = this.selection.getPreviousSelectionBlock(this.paragraph);
if (!isNullOrUndefined(previousParagraph)) {
if (previousParagraph.containerWidget instanceof TableCellWidget) {
if (this.selection.start.paragraph.isInsideTable) {
var containerCell = this.selection.getContainerCellOf(this.selection.start.paragraph.associatedCell, previousParagraph.associatedCell);
positionAtStart = !containerCell.ownerTable.contains(previousParagraph.associatedCell);
}
else {
positionAtStart = true;
}
}
}
}
if (!isNullOrUndefined(previousParagraph)) {
if (!positionAtStart) {
this.currentWidget = this.getValidVisibleLine(previousParagraph.lastChild, false);
// line end with page break and updating offset before page break.
this.offset = (this.currentWidget.isEndsWithPageBreak || this.currentWidget.isEndsWithColumnBreak) ? this.currentWidget.getEndOffset() - 1 : this.currentWidget.getEndOffset();
}
else {
this.currentWidget = this.getValidVisibleLine(previousParagraph.firstChild, true);
this.offset = this.selection.getStartLineOffset(this.currentWidget);
}
}
}
index = 0;
inlineInfo = this.currentWidget.getInline(this.offset, index);
inline = inlineInfo.element;
index = inlineInfo.index;
if (inline instanceof EditRangeEndElementBox) {
for (var i = this.currentWidget.children.length - 1; i >= 0; i--) {
inline = this.currentWidget.children[i];
if (inline instanceof EditRangeEndElementBox) {
this.offset--;
}
else {
break;
}
}
}
if (inline instanceof FieldElementBox && inline.fieldType === 0) {
this.offset++;
}
if (inline instanceof FieldElementBox) {
//Checks if field character is part of rendered field, otherwise moves to previous rendered content.
var previousInline = this.selection.getPreviousValidElement(inline);
if (!isNullOrUndefined(previousInline)) {
inline = previousInline;
this.currentWidget = inline.line;
this.offset = this.currentWidget.getOffset(inline, inline.length);
if (inline instanceof FieldElementBox && inline.fieldType === 0) {
this.offset--;
}
}
}
//Gets physical position in current page.
this.updatePhysicalPosition(true);
};
/**
* Moves the text position to start of the next paragraph.
*/
TextPosition.prototype.moveToNextParagraphStartInternal = function () {
var paragraph = this.currentWidget.paragraph;
if (!isNullOrUndefined(this.selection.getNextParagraphBlock(paragraph))) {
this.currentWidget = this.selection.getNextParagraphBlock(paragraph).firstChild;
this.offset = this.selection.getStartOffset(paragraph);
this.updatePhysicalPosition(true);
}
};
/**
* Move to previous position
*
* @private
*/
TextPosition.prototype.movePreviousPosition = function () {
var index = 0;
var inlineInfo = this.currentWidget.getInline(this.offset, index);
var inline = inlineInfo.element;
index = inlineInfo.index;
var lineIndex = this.paragraph.childWidgets.indexOf(this.currentWidget);
if (inline instanceof FieldElementBox && inline.fieldType === 1 && !isNullOrUndefined(inline.fieldBegin)
|| inline instanceof BookmarkElementBox) {
this.movePreviousPositionInternal(inline);
}
this.updateOffsetToPrevPosition(index, false);
};
/**
* Move to next position
*
* @private
*/
TextPosition.prototype.moveNextPositionInternal = function (fieldBegin) {
var inline;
if (isNullOrUndefined(fieldBegin.fieldSeparator)) {
inline = fieldBegin.fieldEnd;
}
else {
inline = fieldBegin.fieldSeparator;
this.currentWidget = inline.line;
if (this.currentWidget === fieldBegin.fieldEnd.line && !this.selection.hasValidInline(this.paragraph, inline, fieldBegin.fieldEnd)) {
inline = fieldBegin.fieldEnd;
}
}
this.currentWidget = inline.line;
this.offset = this.currentWidget.getOffset(inline, 1);
};
/**
* Move text position backward
*
* @private
*/
TextPosition.prototype.moveBackward = function () {
var indexInInline = 0;
var inlineObj = this.currentWidget.getInline(this.offset, indexInInline);
var inline = inlineObj.element;
indexInInline = inlineObj.index;
if (!this.owner.selectionModule.isEmpty && !isNullOrUndefined(inline)) {
var nextInline = this.selection.getNextRenderedElementBox(inline, indexInInline);
if (nextInline instanceof FieldElementBox && nextInline.fieldType === 0) {
var hierarchicalIndex = this.owner.selectionModule.start.getHierarchicalIndexInternal();
var fieldEndOffset = nextInline.fieldEnd.line.getOffset(nextInline.fieldEnd, 1);
var fieldEndIndex = this.getHierarchicalIndex(nextInline.fieldEnd.line, fieldEndOffset.toString());
if (!TextPosition.isForwardSelection(fieldEndIndex, hierarchicalIndex)) {
//If field end is after selection start, move selection start to field end.
this.owner.selectionModule.start.setPositionParagraph(nextInline.fieldEnd.line, fieldEndOffset);
return;
}
}
}
if (inline instanceof FieldElementBox && inline.fieldType === 1 && !isNullOrUndefined(inline.fieldBegin)) {
var hierarchicalIndex = this.owner.selectionModule.start.getHierarchicalIndexInternal();
var fieldEndOffset = inline.line.getOffset(inline, 1);
var fieldEndIndex = this.getHierarchicalIndex(inline.line, fieldEndOffset.toString());
if (!TextPosition.isForwardSelection(hierarchicalIndex, fieldEndIndex)) {
//If field end is after selection start, extend selection end to field begin.
var fieldBeginOffset = inline.fieldBegin.line.getOffset(inline.fieldBegin, 0);
this.currentWidget = inline.fieldBegin.line;
this.offset = fieldBeginOffset;
//Updates physical position in current page.
this.updatePhysicalPosition(true);
return;
}
this.movePreviousPositionInternal(inline);
}
this.updateOffsetToPrevPosition(indexInInline, true);
};
/**
* Move text position forward
*
* @private
*/
TextPosition.prototype.moveForward = function () {
var indexInInline = 0;
var inlineObj = this.currentWidget.getInline(this.offset, indexInInline);
var inline = inlineObj.element;
indexInInline = inlineObj.index;
if (!isNullOrUndefined(inline)) {
if (!this.owner.selectionModule.isEmpty && indexInInline === inline.length && inline instanceof FieldElementBox
&& inline.fieldType === 1) {
var hierarchicalIndex = this.owner.selectionModule.start.getHierarchicalIndexInternal();
var fieldBeginOffset = inline.fieldBegin.line.getOffset(inline.fieldBegin, 0);
var fieldBeginIndex = this.getHierarchicalIndex(inline.fieldBegin.line, fieldBeginOffset.toString());
if (!TextPosition.isForwardSelection(hierarchicalIndex, fieldBeginIndex)) {
//If field begin is before selection start, move selection start to field begin.
this.owner.selectionModule.start.setPositionParagraph(inline.fieldBegin.line, fieldBeginOffset);
return;
}
}
inline = this.selection.getNextRenderedElementBox(inline, indexInInline);
}
if (inline instanceof FieldElementBox && !isNullOrUndefined(inline.fieldEnd)) {
var selectionStartParagraph = this.owner.selectionModule.start.paragraph;
var selectionStartIndex = 0;
var selectionStartInlineObj = selectionStartParagraph.getInline(this.owner.selectionModule.start.offset, selectionStartIndex);
var selectionStartInline = selectionStartInlineObj.element;
selectionStartIndex = selectionStartInlineObj.index;
var nextRenderInline = this.selection.getNextRenderedElementBox(selectionStartInline, selectionStartIndex);
if (nextRenderInline === inline) {
this.moveNextPositionInternal(inline);
}
else {
//If selection start is before field begin, extend selection end to field end.
inline = inline.fieldEnd;
this.currentWidget = inline.line;
this.offset = this.currentWidget.getOffset(inline, 1);
//Updates physical position in current page.
this.updatePhysicalPosition(true);
return;
}
}
else if ((inline instanceof FieldElementBox)
&& (inline.fieldType === 0 || inline.fieldType === 1)) {
this.currentWidget = inline.line;
this.offset = this.currentWidget.getOffset(inline, 1);
}
indexInInline = 0;
var nextOffset = this.selection.getNextValidOffset(this.currentWidget, this.offset);
var length = this.selection.getLineLength(this.currentWidget);
var isParagraphEnd = this.selection.isParagraphLastLine(this.currentWidget);
if (this.offset < nextOffset) {
this.offset = nextOffset;
var inlineObj_1 = this.currentWidget.getInline(this.offset, indexInInline);
inline = inlineObj_1.element;
indexInInline = inlineObj_1.index;
if (!isNullOrUndefined(inline) && indexInInline === inline.length && inline.nextNode instanceof FieldElementBox) {
var nextValidInline = this.documentHelper.getNextValidElement(inline.nextNode);
//Moves to field end mark.
if (nextValidInline instanceof FieldElementBox && nextValidInline.fieldType === 1) {
inline = nextValidInline;
this.offset = this.currentWidget.getOffset(inline, 1);
}
}
}
else if (this.offset === nextOffset && inline instanceof FieldElementBox && inline.fieldType === 1 &&
inline.previousNode instanceof ImageElementBox) {
this.offset = nextOffset;
}
else if (this.offset === nextOffset && this.offset < length + 1 && isParagraphEnd) {
this.offset = length + 1;
}
else {
this.updateOffsetToNextParagraph(indexInInline, true);
}
//Gets physical position in current page.
this.updatePhysicalPosition(true);
};
/**
* Move to given inline
*
* @private
*/
TextPosition.prototype.moveToInline = function (inline, index) {
this.currentWidget = inline.line;
this.offset = this.currentWidget.getOffset(inline, index);
//Updates physical position in current page.
this.updatePhysicalPosition(true);
};
/**
* Return true is start element exist before end element
*
* @private
*/
TextPosition.isForwardSelection = function (start, end) {
if (start === end) {
return true;
}
start = start.replace(/S;/g, '');
end = end.replace(/S;/g, '');
start = start.replace(/C;/g, '');
end = end.replace(/C;/g, '');
start = start.replace(/H;/g, '');
end = end.replace(/H;/g, '');
start = start.replace(/F;/g, '');
end = end.replace(/F;/g, '');
start = start.replace(/FN;/g, '');
end = end.replace(/FN;/g, '');
start = start.replace(/EN;/g, '');
end = end.replace(/EN;/g, '');
var selectionStart = start.split(';');
var selectionEnd = end.split(';');
var length = selectionStart.length;
if (length > selectionEnd.length) {
length = selectionEnd.length - 1;
}
for (var i = 0; i < length; i++) {
var startOffset = parseFloat(selectionStart[i]);
var endOffset = parseFloat(selectionEnd[i]);
if (startOffset !== endOffset) {
return startOffset < endOffset;
}
}
return false;
};
/**
* Move to previous position offset
*
* @param fieldEnd
* @private
*/
TextPosition.prototype.movePreviousPositionInternal = function (fieldEnd) {
var inline;
if (fieldEnd instanceof FieldElementBox && isNullOrUndefined(fieldEnd.fieldSeparator)) {
inline = this.selection.getPreviousValidElement(fieldEnd.fieldBegin);
}
else {
inline = this.selection.getPreviousValidElement(fieldEnd);
}
this.currentWidget = inline.line;
var index = inline instanceof FieldElementBox || inline instanceof BookmarkElementBox ? 0 : inline.length;
this.offset = this.currentWidget.getOffset(inline, index);
};
/**
* Moves the text position to start of the word.
*
* @param type
* @private
*/
TextPosition.prototype.moveToWordStartInternal = function (type) {
var endOffset = this.currentWidget.getEndOffset();
var currentPara = this.currentWidget.paragraph;
var selection = this.selection;
if (type === 2 && (this.offset === endOffset || this.offset === endOffset + 1)) {
return;
}
if (this.offset === endOffset + 1) {
this.offset = endOffset;
}
else if (this.offset === selection.getStartOffset(currentPara) && this.currentWidget === currentPara.childWidgets[0]) {
var previousParagraph = selection.getPreviousParagraphBlock(currentPara);
if (isNullOrUndefined(previousParagraph)) {
return;
}
this.currentWidget = previousParagraph.childWidgets[previousParagraph.childWidgets.length - 1];
this.offset = this.currentWidget.getEndOffset();
}
else {
if (this.offset === selection.getStartLineOffset(this.currentWidget)) {
var lineIndex = currentPara.childWidgets.indexOf(this.currentWidget);
if (lineIndex - 1 >= 0) {
this.currentWidget = currentPara.childWidgets[lineIndex - 1];
this.offset = this.currentWidget.getEndOffset();
}
}
var isStarted = false;
var endSelection = false;
var indexInInline = 0;
var inlineObj = this.currentWidget.getInline(this.offset, indexInInline);
var inline = inlineObj.element;
indexInInline = inlineObj.index;
this.getPreviousWordOffset(inline, selection, indexInInline, type, (inline instanceof FieldElementBox && inline.fieldType === 1), isStarted, endSelection, this);
}
if (type === 1) {
this.calculateOffset();
}
this.updatePhysicalPosition(true);
};
TextPosition.prototype.getNextWordOffset = function (inline, indexInInline, type, isInField, endSelection, endPosition, excludeSpace) {
if (inline instanceof TextElementBox) {
this.getNextWordOffsetSpan(inline, indexInInline, type, isInField, endSelection, endPosition, excludeSpace);
}
else if (inline instanceof ImageElementBox) {
this.getNextWordOffsetImage(inline, indexInInline, type, isInField, endSelection, endPosition, excludeSpace);
}
else if (inline instanceof FieldElementBox && inline.fieldType === 0) {
this.getNextWordOffsetFieldBegin(inline, indexInInline, type, isInField, endSelection, endPosition, excludeSpace);
}
else if ((inline instanceof FieldElementBox && inline.fieldType === 2) || (inline instanceof BookmarkElementBox && inline.bookmarkType === 0)) {
this.getNextWordOffsetFieldSeparator(inline, indexInInline, type, isInField, endSelection, endPosition, excludeSpace);
}
else if ((inline instanceof FieldElementBox && inline.fieldType === 1) || (inline instanceof BookmarkElementBox && inline.bookmarkType === 1)) {
this.getNextWordOffsetFieldEnd(inline, indexInInline, type, isInField, endSelection, endPosition, excludeSpace);
}
else if (inline instanceof CommentCharacterElementBox) {
this.getNextWordOffsetComment(inline, indexInInline, type, isInField, endSelection, endPosition, excludeSpace);
}
else if (inline instanceof ContentControl) {
this.getNextWordOffsetContentControl(inline, indexInInline, type, isInField, endSelection, endPosition, excludeSpace);
}
};
TextPosition.prototype.getNextWordOffsetFieldBegin = function (fieldBegin, indexInInline, type, isInField, endSelection, endPosition, excludeSpace) {
var startOffset = fieldBegin.line.getOffset(fieldBegin, 0);
var endOffset = startOffset + fieldBegin.length;
if (isNullOrUndefined(fieldBegin.fieldSeparator)) {
this.getNextWordOffsetFieldEnd(fieldBegin.fieldEnd, 0, type, isInField, endSelection, endPosition, excludeSpace);
}
else if (type === 0) {
this.getNextWordOffsetFieldSeparator(fieldBegin.fieldSeparator, 0, type, isInField, endSelection, endPosition, excludeSpace);
}
else if (!isNullOrUndefined(fieldBegin.fieldEnd)) {
var inline = fieldBegin.fieldSeparator;
if (inline.line.paragraph === fieldBegin.fieldEnd.line.paragraph && !this.selection.hasValidInline(inline.line.paragraph, inline, fieldBegin.fieldEnd)) {
inline = fieldBegin.fieldEnd;
}
this.getNextWordOffset(inline, 0, type, !(endPosition.paragraph === fieldBegin.line.paragraph && endPosition.offset === startOffset), endSelection, endPosition, excludeSpace);
if (endSelection && !isNullOrUndefined(fieldBegin.fieldSeparator) && (endPosition.paragraph === fieldBegin.line.paragraph) && (endPosition.offset === fieldBegin.fieldSeparator.line.getOffset(fieldBegin.fieldSeparator, fieldBegin.fieldSeparator.length))) {
endPosition.setPositionParagraph(fieldBegin.line, startOffset);
return;
}
if (!endSelection) {
endPosition.setPositionParagraph(fieldBegin.fieldEnd.line, fieldBegin.fieldEnd.line.getOffset(fieldBegin.fieldEnd, fieldBegin.fieldEnd.length));
}
}
};
TextPosition.prototype.getNextWordOffsetImage = function (image, indexInInline, type, isInField, endSelection, endPosition, excludeSpace) {
if (isInField) {
endPosition.setPositionParagraph(image.line, image.line.getOffset(image, indexInInline));
endSelection = false;
return;
}
if (indexInInline === 0) {
var startOffset = image.line.getOffset(image, 0);
endSelection = true;
if (endPosition.offset === startOffset) {