@syncfusion/ej2-documenteditor
Version:
Feature-rich document editor control with built-in support for context menu, options pane and dialogs.
957 lines • 800 kB
JavaScript
/* eslint-disable */
import { isNullOrUndefined } from '@syncfusion/ej2-base';
import { Dictionary } from '../../base/dictionary';
import { CharacterRangeType } from '../../base/types';
import { HelperMethods, Point, WrapPosition } from '../editor/editor-helper';
import { WBorder, WBorders, WCharacterFormat, WParagraphFormat } from '../format/index';
import { WListLevel } from '../list/list-level';
import { BlockContainer, BlockWidget, BodyWidget, BookmarkElementBox, EditRangeEndElementBox, EditRangeStartElementBox, ElementBox, FieldElementBox, FieldTextElementBox, HeaderFooterWidget, ImageElementBox, LineWidget, ListTextElementBox, Margin, ParagraphWidget, Rect, TabElementBox, TableCellWidget, TableRowWidget, TableWidget, TextElementBox, Widget, CheckBoxFormField, DropDownFormField, ShapeElementBox, TextFrame, ContentControl, FootnoteElementBox, FootNoteWidget, ShapeBase, CommentCharacterElementBox, FootnoteEndnoteMarkerElementBox } from './page';
import { PageLayoutViewer, WebLayoutViewer } from './viewer';
import { TextHelper } from './text-helper';
// Check box character is rendered smaller when compared to MS Word
// So, mutiplied the font side by below factor to render check box character large.
var CHECK_BOX_FACTOR = 1.35;
/**
* @private
*/
var Layout = /** @class */ (function () {
function Layout(documentHelper) {
/**
* @private
*/
this.islayoutFootnote = false;
/**
* @private
*/
this.isMultiColumnDoc = false;
/**
* @private
*/
this.allowLayout = true;
/**
* @private
*/
this.isReplaceAll = false;
/**
* @private
*/
this.isTextFormat = false;
/**
* @private
*/
this.isSectionBreakCont = false;
/**
* @private
*/
this.isReplacingAll = false;
/**
* @private
*/
this.footHeight = 0;
/**
* @private
*/
this.existFootnoteHeight = 0;
/**
* @private
*/
this.isfootMove = false;
/**
* @private
*/
this.footnoteHeight = 0;
/**
* @private
*/
this.isTableFootNote = false;
/**
* @private
*/
this.isRelayout = false;
/**
* @private
*/
this.isRelayoutneed = false;
/**
* @private
*/
this.isOverlapFloatTable = false;
this.isInitialLoad = true;
/**
* @private
*/
this.isInsertFormField = false;
this.fieldBegin = undefined;
this.maxTextHeight = 0;
this.maxBaseline = 0;
this.maxTextBaseline = 0;
this.isFieldCode = false;
this.isRtlFieldCode = false;
this.isRTLLayout = false;
this.isSkipFirstLineIndent = false;
this.currentCell = undefined;
this.isFootnoteContentChanged = false;
this.isEndnoteContentChanged = false;
this.keepWithNext = false;
this.is2013Justification = false;
this.nextElementToLayout = undefined;
this.endNoteHeight = 0;
this.isMultiColumnSplit = false;
this.isMultiColumnLayout = false;
this.skipUpdateContainerWidget = false;
this.isIFfield = false;
this.isLayoutWhole = false;
/**
* @private
*/
this.isBidiReLayout = false;
/**
* @private
*/
this.defaultTabWidthPixel = 48;
/**
* @private
*/
this.isRelayoutFootnote = false;
this.isRelayoutOverlap = false;
this.skipRelayoutOverlap = false;
this.isWrapText = false;
this.isYPositionUpdated = false;
this.isXPositionUpdated = false;
this.hasFloatingElement = false;
this.isFootNoteLayoutStart = false;
this.wrapPosition = [];
this.shiftedFloatingItemsFromTable = [];
this.isDocumentContainsRtl = false;
/**
* @private
*/
this.isPastingContent = false;
this.layoutedFootnoteElement = [];
/**
* @private
*/
this.isAllColumnHasAutoWidthType = false;
this.documentHelper = documentHelper;
}
Layout.prototype.isSameStyle = function (currentParagraph, isAfterSpacing) {
var nextOrPrevSibling = undefined;
if (isAfterSpacing) {
if (currentParagraph.nextWidget instanceof ParagraphWidget) {
nextOrPrevSibling = currentParagraph.nextWidget;
}
}
else {
if (currentParagraph.previousWidget instanceof ParagraphWidget) {
nextOrPrevSibling = currentParagraph.previousWidget;
}
}
if (isNullOrUndefined(nextOrPrevSibling)) {
//Need to skip contextual spacing behavior when document is not Word 2013 and paragraph preserved inside the table cell with AllowSpaceOfSameStyleInTable compatiblity options.
if (currentParagraph.paragraphFormat.contextualSpacing && (currentParagraph.isInsideTable ? (!this.documentHelper.allowSpaceOfSameStyleInTable || this.documentHelper.compatibilityMode === 'Word2013') : false)) {
if (currentParagraph.index === 0) {
nextOrPrevSibling = this.updateFirstParagraphSpacingBasedOnContextualSpacing(currentParagraph, isAfterSpacing);
}
else if (currentParagraph.index === currentParagraph.associatedCell.childWidgets.length - 1) {
nextOrPrevSibling = this.updateLastParagraphSpacingBasedOnContextualSpacing(currentParagraph);
if (nextOrPrevSibling === currentParagraph) {
return true;
}
}
}
if (isNullOrUndefined(nextOrPrevSibling)) {
return false;
}
}
if (nextOrPrevSibling instanceof ParagraphWidget && currentParagraph.paragraphFormat.baseStyle === nextOrPrevSibling.paragraphFormat.baseStyle && (currentParagraph.isInsideTable ? !this.documentHelper.allowSpaceOfSameStyleInTable : true)) {
if (currentParagraph.paragraphFormat.listFormat.listId >= 0 && nextOrPrevSibling.paragraphFormat.listFormat.listId >= 0) {
if (!currentParagraph.paragraphFormat.contextualSpacing) {
if (isAfterSpacing && currentParagraph.paragraphFormat.spaceAfterAuto) {
return true;
}
else if (!isAfterSpacing && currentParagraph.paragraphFormat.spaceBeforeAuto) {
return true;
}
}
}
return currentParagraph.paragraphFormat.contextualSpacing;
}
return false;
};
Layout.prototype.updateFirstParagraphSpacingBasedOnContextualSpacing = function (paragraph, isAfterSpacing) {
var ownerCell = paragraph.associatedCell;
var ownerRow = ownerCell.ownerRow;
var ownerTable = ownerRow.ownerTable;
var nextOrPrevSibling;
if (isAfterSpacing) {
nextOrPrevSibling = isNullOrUndefined(paragraph.nextRenderedWidget) ? (!isNullOrUndefined(ownerCell.nextRenderedWidget) ? ownerCell.nextRenderedWidget.firstChild : undefined) : paragraph.nextRenderedWidget;
}
else {
nextOrPrevSibling = isNullOrUndefined(paragraph.previousRenderedWidget) ? (!isNullOrUndefined(ownerCell.previousRenderedWidget) ? ownerCell.previousRenderedWidget.firstChild : undefined) : paragraph.previousRenderedWidget;
}
if (ownerCell.index === 0 && paragraph.index === 0) {
if (ownerRow.index === 0) {
if (ownerTable.isInsideTable && ownerTable.index == 0) {
nextOrPrevSibling = this.checkOwnerTablePrevItem(ownerTable, paragraph);
}
else {
//If paragraph is preserved in first row first cell means, need to check owner table previous sibling.
var ownerTablePrevSibling = ownerTable.previousRenderedWidget;
return ownerTablePrevSibling;
}
}
else {
if (isNullOrUndefined(nextOrPrevSibling) && paragraph.paragraphFormat.baseStyle.name === "Normal" && paragraph.paragraphFormat.listFormat.listId < 0) {
return paragraph;
}
return nextOrPrevSibling;
}
}
else if (paragraph.index === 0 && !isAfterSpacing) {
//If para is first item in any cell excluding first cell, need to check previous cell last item.
var prevCell = ownerRow.childWidgets[ownerCell.index - 1];
var prevCelllastItem = prevCell.childWidgets[prevCell.childWidgets.length - 1];
//if previous cell last item is table means skip before spacing value no need to check any paragraph styles.
if (prevCelllastItem instanceof TableWidget && paragraph.paragraphFormat.baseStyle.name === "Normal" && paragraph.paragraphFormat.listFormat.listId < 0) {
return paragraph;
}
}
return nextOrPrevSibling;
};
Layout.prototype.updateLastParagraphSpacingBasedOnContextualSpacing = function (paragraph) {
var ownerCell = paragraph.associatedCell;
var ownerRow = ownerCell.ownerRow;
var nextCellFirstItem;
if (ownerCell.index === ownerRow.childWidgets.length - 1 && paragraph.index === ownerCell.childWidgets.length - 1) {
if (paragraph.paragraphFormat.baseStyle.name === "Normal" && paragraph.paragraphFormat.listFormat.listId < 0) {
//If para preserved in last item in cell and cell is last cell in current row means its after spacing value not considered.
return paragraph;
}
}
else if (paragraph.index === ownerCell.childWidgets.length - 1) {
//If current para is last item in current cell then need to check next cell first item.
var nextCell = ownerRow.childWidgets[ownerCell.index + 1];
nextCellFirstItem = nextCell.firstChild;
//If next cell first item is table then need to check inner table first para.
//This is applicable for multiple nested table so when first item is table it try to get its first paragraph.
while (nextCellFirstItem instanceof TableWidget) {
nextCellFirstItem = nextCellFirstItem.childWidgets[0].childWidgets[0].childWidgets[0];
}
}
return nextCellFirstItem;
};
Layout.prototype.checkOwnerTablePrevItem = function (ownerTable, paragraph) {
var row = ownerTable.associatedCell.ownerRow;
var prevSibling;
if (row.index > 0) {
if (paragraph.paragraphFormat.baseStyle.name === "Normal" && paragraph.paragraphFormat.listFormat.listId < 0) {
return paragraph;
}
}
else {
if (row.ownerTable.isInsideTable && row.ownerTable.index === 0) {
this.checkOwnerTablePrevItem(row.ownerTable, paragraph);
}
else {
var prevSibling_1 = row.ownerTable.previousRenderedWidget;
return prevSibling_1;
}
}
return prevSibling;
};
Object.defineProperty(Layout.prototype, "viewer", {
get: function () {
return this.documentHelper.owner.viewer;
},
enumerable: true,
configurable: true
});
Layout.prototype.layout = function () {
// Todo: Need to handle complete document layout(relayout).
//const page: Page = this.documentHelper.pages[0];
//const body: BodyWidget = page.bodyWidgets[0];
};
/**
* Releases un-managed and - optionally - managed resources.
*
* @returns {void}
*/
Layout.prototype.destroy = function () {
this.documentHelper = undefined;
this.value = undefined;
this.allowLayout = undefined;
this.isInitialLoad = undefined;
this.fieldBegin = undefined;
this.maxTextHeight = undefined;
this.maxBaseline = undefined;
this.maxTextBaseline = undefined;
this.isSkipFirstLineIndent = undefined;
this.isFieldCode = undefined;
this.footnoteHeight = undefined;
this.isMultiColumnDoc = undefined;
this.isIFfield = undefined;
this.isPastingContent = undefined;
};
/**
* @private
* @returns {void}
*/
Layout.prototype.layoutWholeDocument = function (isLayoutChanged, skipClearContent) {
this.isInitialLoad = true;
this.isLayoutWhole = true;
var startPosition = undefined;
var endPosition = undefined;
var startIndex = undefined;
var endIndex = undefined;
if (this.documentHelper.selection) {
startPosition = this.documentHelper.selection.start;
endPosition = this.documentHelper.selection.end;
if (startPosition.isExistAfter(endPosition)) {
startPosition = this.documentHelper.selection.end.clone();
endPosition = this.documentHelper.selection.start.clone();
}
if (this.documentHelper.owner.layoutType == 'Continuous' && (this.documentHelper.selection.isinEndnote || this.documentHelper.selection.isinFootnote)) {
this.documentHelper.selection.footnoteReferenceElement(startPosition, endPosition);
startPosition = endPosition;
}
var startInfo = this.documentHelper.selection.getParagraphInfo(startPosition);
var endInfo = this.documentHelper.selection.getParagraphInfo(endPosition);
startIndex = this.documentHelper.selection.getHierarchicalIndex(startInfo.paragraph, startInfo.offset.toString());
endIndex = this.documentHelper.selection.getHierarchicalIndex(endInfo.paragraph, endInfo.offset.toString());
}
this.documentHelper.renderedLists.clear();
this.documentHelper.renderedLevelOverrides = [];
// this.viewer.owner.isLayoutEnabled = true;
var sections = this.documentHelper.combineSection();
if (!skipClearContent) {
this.documentHelper.clearContent();
}
// this.documentHelper.layout.isRelayout = false;
this.layoutItems(sections, true);
// this.documentHelper.layout.isRelayout = true;
this.documentHelper.owner.isShiftingEnabled = false;
if (this.documentHelper.selection && this.documentHelper.owner.editorModule) {
this.documentHelper.owner.editorModule.setPositionForCurrentIndex(startPosition, startIndex);
this.documentHelper.owner.editorModule.setPositionForCurrentIndex(endPosition, endIndex);
this.documentHelper.selection.selectPosition(startPosition, endPosition);
this.documentHelper.owner.editorModule.reLayout(this.documentHelper.selection, undefined, isLayoutChanged);
}
this.isLayoutWhole = false;
this.isInitialLoad = false;
};
Layout.prototype.layoutItems = function (sections, isReLayout, isContinuousSection) {
var _this = this;
var page;
var height = 0;
var width = 0;
for (var i = 0; i < sections.length; i++) {
var section = sections[i];
if (!this.documentHelper.owner.enableLayout) {
this.viewer.createNewPage(section);
}
else {
if (section.sectionFormat.numberOfColumns > 1) {
this.isMultiColumnDoc = true;
}
var nextSection = sections[i + 1];
this.viewer.columnLayoutArea.setColumns(section.sectionFormat);
var lastpage = this.documentHelper.pages[this.documentHelper.pages.length - 1];
var bodyWidget = void 0;
if (!isNullOrUndefined(lastpage) && !isNullOrUndefined(lastpage.bodyWidgets[lastpage.bodyWidgets.length - 1]) && lastpage.bodyWidgets[lastpage.bodyWidgets.length - 1].childWidgets.length === 0 && !isNullOrUndefined(lastpage.bodyWidgets[lastpage.bodyWidgets.length - 1].previousSplitWidget)) {
bodyWidget = lastpage.bodyWidgets[lastpage.bodyWidgets.length - 1].previousSplitWidget;
}
/* eslint-disable-next-line max-len */
// If page break next para is section last para and it is empty then ms word will layout in the section break in previous para. So checking the next para into existing behaviour.
if (i > 0 && !isNullOrUndefined(bodyWidget) && !isNullOrUndefined(bodyWidget.lastChild) && !(bodyWidget.lastChild instanceof TableWidget)) {
var lastChild_1 = bodyWidget.lastChild;
var previousWidget = lastChild_1.previousRenderedWidget;
if (lastChild_1.isSectionBreak && previousWidget instanceof ParagraphWidget && previousWidget.isEndsWithPageBreak) {
lastChild_1 = previousWidget;
}
if ((this.documentHelper.compatibilityMode === 'Word2013' && (lastChild_1.isEndsWithPageBreak || lastChild_1.isEndsWithColumnBreak)) && lastpage.bodyWidgets[0].childWidgets.length === 0) {
var removedPages = this.documentHelper.pages.splice(this.documentHelper.pages.length - 1, 1);
removedPages[0].destroy();
lastpage = this.documentHelper.pages[this.documentHelper.pages.length - 1];
}
}
var breakCode = section.sectionFormat.breakCode;
var prevSection = undefined;
if (i !== 0 && this.documentHelper.compatibilityMode === 'Word2010' && breakCode === 'NewColumn') {
var splitWidgets = sections[i - 1].getSplitWidgets();
prevSection = splitWidgets[splitWidgets.length - 1];
if (prevSection.sectionFormat.columns.length > 1 && section.sectionFormat.columns.length > 1 && prevSection.sectionFormat.columns.length === section.sectionFormat.columns.length && prevSection.sectionFormat.columns.length - 1 !== prevSection.columnIndex && !(prevSection.lastChild instanceof ParagraphWidget && prevSection.lastChild.isEndsWithPageBreak)) {
var nextColumn = this.viewer.columnLayoutArea.getNextColumnByBodyWidget(prevSection);
if (!isNullOrUndefined(nextColumn)) {
section.columnIndex = nextColumn.index;
section.isWord2010NextColumn = true;
section.y = prevSection.y;
this.viewer.clientActiveArea.height -= section.y - this.viewer.clientActiveArea.y;
this.viewer.clientActiveArea.y = section.y;
}
}
}
if (!section.isWord2010NextColumn && breakCode !== 'NoBreak') {
breakCode = 'NewPage';
}
// We are layouting the section last paragraph in previous paragraph if its empty So if previous paragraph is page break then we need to create new page.
var lastChild = void 0;
if (i !== 0) {
lastChild = lastpage.bodyWidgets[lastpage.bodyWidgets.length - 1].lastChild;
if (lastChild) {
var previousWidget = lastChild.previousRenderedWidget;
if (lastChild instanceof ParagraphWidget && lastChild.isSectionBreak && previousWidget instanceof ParagraphWidget) {
lastChild = previousWidget;
}
}
}
if ((i === 0 && !isContinuousSection) || (i !== 0 && !section.isWord2010NextColumn && (isNullOrUndefined(breakCode) || breakCode === 'NewPage' || height !== section.sectionFormat.pageHeight || width !== section.sectionFormat.pageWidth || (!isNullOrUndefined(lastChild) && lastChild.isEndsWithPageBreak)))) {
page = this.viewer.createNewPage(section);
}
else {
var clientY = this.documentHelper.viewer.clientActiveArea.y;
var clientHeight = this.documentHelper.viewer.clientActiveArea.height;
if (isContinuousSection) {
var section_1 = this.getBodyWidget(lastpage.bodyWidgets[lastpage.bodyWidgets.length - 1], true);
var height_1 = this.getNextWidgetHeight(section_1);
this.viewer.updateClientArea(section_1, section_1.page);
clientHeight = this.viewer.clientActiveArea.height - (height_1 - this.viewer.clientActiveArea.y);
clientY = height_1;
isContinuousSection = false;
}
//if (i - 1 > 0) {
page = lastpage;
//}
page.bodyWidgets.push(section);
page.bodyWidgets[page.bodyWidgets.length - 1].page = page;
this.documentHelper.viewer.updateClientArea(section, page);
this.documentHelper.viewer.clientActiveArea.y = clientY;
this.documentHelper.viewer.clientActiveArea.height = clientHeight;
}
height = section.sectionFormat.pageHeight;
width = section.sectionFormat.pageWidth;
this.addBodyWidget(this.viewer.clientActiveArea, section);
if (this.documentHelper.pages.length > 1) {
var pageIndex = 0;
for (var i_1 = 0; i_1 < this.documentHelper.pages.length; i_1++) {
var prevPage = this.documentHelper.pages[i_1];
var prevSectionIndex = prevPage.sectionIndex;
var index = section.index;
if (prevSectionIndex > index || prevPage === page) {
break;
}
pageIndex++;
}
if (pageIndex < this.documentHelper.pages.length - 1) {
this.documentHelper.insertPage(pageIndex, page);
}
}
this.layoutSection(section, 0, nextSection);
if (section.isWord2010NextColumn && !isNullOrUndefined(prevSection)) {
var sectionHeight = this.getNextWidgetHeight(prevSection);
if (this.viewer.clientActiveArea.y < sectionHeight) {
this.viewer.updateClientArea(prevSection, prevSection.page);
this.viewer.clientActiveArea.height = this.viewer.clientActiveArea.height - (sectionHeight - this.viewer.clientActiveArea.y);
this.viewer.clientActiveArea.y = sectionHeight;
}
}
}
}
if (!isReLayout) {
this.layoutComments(this.documentHelper.comments);
}
if (this.documentHelper.owner.enableLayout) {
this.updateFieldElements();
}
else if (this.documentHelper.owner.layoutType === 'Pages') {
for (var i = 0; i < this.documentHelper.footnoteCollection.length; i++) {
this.layoutFootEndNoteElement(this.documentHelper.footnoteCollection[i]);
}
}
if (this.documentHelper.owner.layoutType === 'Pages') {
this.layoutEndNoteElement();
}
/* tslint:disable:align */
setTimeout(function () {
if (_this.documentHelper) {
_this.documentHelper.isScrollHandler = true;
// if (this.documentHelper.owner.isSpellCheck && this.documentHelper.owner.spellChecker.enableOptimizedSpellCheck) {
// this.documentHelper.triggerElementsOnLoading = true;
// }
_this.viewer.updateScrollBars();
_this.documentHelper.isScrollHandler = false;
_this.isInitialLoad = false;
}
}, 50);
};
/**
* @private
*/
Layout.prototype.layoutComments = function (comments) {
if (!isNullOrUndefined(comments)) {
this.viewer.owner.commentReviewPane.layoutComments(comments);
}
};
Layout.prototype.layoutSection = function (section, index, nextSection) {
var block = section.firstChild;
var nextBlock;
var prevBlock;
do {
if (!this.isLayoutWhole && block instanceof TableWidget && block.tableFormat.preferredWidthType === 'Auto'
&& !block.tableFormat.allowAutoFit) {
block.calculateGrid();
}
if (!isNullOrUndefined(block)) {
this.viewer.updateClientAreaForBlock(block, true, undefined, true, true);
var bodyIndex = block.containerWidget.indexInOwner;
nextBlock = this.layoutBlock(block, index);
index = 0;
this.viewer.updateClientAreaForBlock(block, false);
prevBlock = block;
block = nextBlock;
}
} while (block);
block = section.firstChild;
if (this.viewer instanceof PageLayoutViewer && section.sectionFormat.numberOfColumns > 1 && !isNullOrUndefined(nextSection) && nextSection.sectionFormat.breakCode === 'NoBreak' && (section.sectionFormat.breakCode === 'NoBreak' || (section.sectionIndex === section.page.bodyWidgets[0].sectionIndex))) {
if (this.getColumnBreak(section)) {
var splittedSection = section.getSplitWidgets();
var bodyWidget = splittedSection[splittedSection.length - 1];
if (!isNullOrUndefined(section.page.nextPage)) {
this.splitBodyWidgetBasedOnColumn(bodyWidget);
}
else {
var firstBody = this.getBodyWidget(bodyWidget, true);
this.viewer.updateClientArea(firstBody, firstBody.page);
var height = this.getNextWidgetHeight(firstBody);
this.viewer.clientActiveArea.height -= height - this.viewer.clientActiveArea.y;
this.viewer.clientActiveArea.y = height;
}
}
else {
if (!isNullOrUndefined(section.page.nextPage)) {
section = this.documentHelper.pages[this.documentHelper.pages.length - 1].bodyWidgets[0];
}
this.splitBodyWidgetBasedOnColumn(section);
}
}
var page;
if (block && block.bodyWidget && block.bodyWidget.page) {
page = block.bodyWidget.page;
}
while (page) {
if (page.footnoteWidget) {
this.layoutfootNote(page.footnoteWidget);
page = page.nextPage;
}
else {
page = page.nextPage;
}
}
page = undefined;
block = undefined;
};
/**
* @private
*
*/
Layout.prototype.reLayoutMultiColumn = function (section, isFirstBlock, blockIndex) {
this.isInitialLoad = true;
section = section.getSplitWidgets()[0];
this.combineMultiColumnForRelayout(section);
if (section.sectionFormat.numberOfColumns > 1) {
this.isMultiColumnDoc = true;
}
this.isMultiColumnSplit = false;
var previousSection = section.previousRenderedWidget;
var nextSection = section.nextRenderedWidget;
var isUpdatedClientArea = false;
// Section's Y position is not updated properly when the two sections combined and layouted.
if (!isFirstBlock && !isNullOrUndefined(section.firstChild) && section.firstChild instanceof ParagraphWidget && section.y !== section.firstChild.y) {
section.y = section.firstChild.y;
}
if (isFirstBlock && nextSection && section.page !== nextSection.page && section.firstChild instanceof ParagraphWidget) {
var paragraph = section.firstChild;
var lineHeight = 0;
if (paragraph.isEmpty()) {
lineHeight = this.documentHelper.textHelper.getParagraphMarkSize(paragraph.characterFormat).Height;
}
else {
var firstLine = paragraph.childWidgets[0];
lineHeight = this.getMaxElementHeight(firstLine);
}
var previousBlock = paragraph.previousRenderedWidget;
if (section.y === this.viewer.clientActiveArea.y && lineHeight > this.viewer.clientActiveArea.height) {
previousBlock = isNullOrUndefined(previousBlock) ? paragraph : previousBlock;
this.moveBlocksToNextPage(previousBlock);
this.viewer.columnLayoutArea.setColumns(section.sectionFormat);
this.viewer.updateClientArea(section, section.page);
isUpdatedClientArea = true;
}
}
else if (!isNullOrUndefined(previousSection) && previousSection.page !== section.page && section.firstChild instanceof ParagraphWidget && previousSection.lastChild instanceof ParagraphWidget) {
var previousParagraph = previousSection.lastChild;
var paragraph = section.firstChild;
if (section instanceof BodyWidget && previousSection.lastChild && previousParagraph instanceof ParagraphWidget && previousSection.sectionFormat.breakCode === 'NoBreak' && section.page.index !== previousSection.page.index && section.index !== previousSection.index) {
var bodyWidget = previousSection;
if (bodyWidget.sectionFormat.columns.length > 1) {
bodyWidget = this.getBodyWidget(bodyWidget, true);
}
var bottom = HelperMethods.round((this.getNextWidgetHeight(bodyWidget) + paragraph.height), 2);
// Bug 858530: Shift the widgets to previous container widget if the client height is not enough to place this widget.
if (!previousSection.lastChild.isEndsWithPageBreak && !previousSection.lastChild.isEndsWithColumnBreak
&& bottom <= HelperMethods.round(this.viewer.clientActiveArea.bottom, 2)) {
var page = previousSection.page;
var nextPage = section.page;
for (var j = 0; j < nextPage.bodyWidgets.length; j++) {
var nextBodyWidget = nextPage.bodyWidgets[j];
nextPage.bodyWidgets.splice(nextPage.bodyWidgets.indexOf(nextBodyWidget), 1);
page.bodyWidgets.splice(page.bodyWidgets.length, 0, nextBodyWidget);
nextBodyWidget.page = page;
j--;
}
section.y = this.viewer.clientActiveArea.y;
this.documentHelper.removeEmptyPages();
}
}
}
if (!isUpdatedClientArea) {
this.viewer.columnLayoutArea.setColumns(section.sectionFormat);
this.viewer.updateClientArea(section, section.page);
this.viewer.clientActiveArea.height -= section.y - this.viewer.clientActiveArea.y;
this.viewer.clientActiveArea.y = section.y;
}
this.addBodyWidget(this.viewer.clientActiveArea, section);
this.clearBlockWidget(section.childWidgets, true, true, true);
this.isMultiColumnLayout = true;
this.reLayoutMultiColumnBlock(section, nextSection, blockIndex);
this.isMultiColumnLayout = false;
this.isInitialLoad = false;
var splitSections = section.getSplitWidgets();
var lastSection = splitSections[splitSections.length - 1];
var firstBody = this.getBodyWidget(lastSection, true);
this.viewer.updateClientArea(firstBody, firstBody.page);
var height = this.getNextWidgetHeight(firstBody);
this.viewer.clientActiveArea.height -= height - this.viewer.clientActiveArea.y;
this.viewer.clientActiveArea.y = height;
if (!isNullOrUndefined(lastSection) && !isNullOrUndefined(lastSection.nextRenderedWidget)) {
nextSection = lastSection.nextRenderedWidget;
var clientY = this.documentHelper.viewer.clientActiveArea.y;
var clientHeight = this.documentHelper.viewer.clientActiveArea.height;
this.documentHelper.viewer.updateClientArea(nextSection, nextSection.page);
this.documentHelper.viewer.clientActiveArea.y = clientY;
this.documentHelper.viewer.clientActiveArea.height = clientHeight;
this.documentHelper.blockToShift = nextSection.firstChild;
}
if (isNullOrUndefined(lastSection.nextRenderedWidget) ||
(!isNullOrUndefined(lastSection.nextRenderedWidget) && lastSection.sectionFormat.breakCode !== 'NoBreak' && lastSection.nextRenderedWidget.sectionFormat.pageHeight !== lastSection.sectionFormat.pageHeight && lastSection.nextRenderedWidget.sectionFormat.pageWidth !== lastSection.sectionFormat.pageWidth)) {
this.documentHelper.blockToShift = undefined;
}
};
Layout.prototype.combineMultiColumnForRelayout = function (section) {
var splitSections = section.getSplitWidgets();
var firstSection = splitSections[0];
section = splitSections[splitSections.length - 1];
while (section !== firstSection) {
var prevSection = section.previousRenderedWidget;
var isPreviousSplit = false;
for (var i = 0; i < section.childWidgets.length; i++) {
if (section.childWidgets[i] instanceof BlockWidget && !isNullOrUndefined(section.childWidgets[i].previousSplitWidget)
&& !isNullOrUndefined(section.childWidgets[i].previousSplitWidget.previousSplitWidget)
&& section.childWidgets[i].previousSplitWidget.bodyWidget.page !== section.childWidgets[i].previousSplitWidget.previousSplitWidget.bodyWidget.page) {
isPreviousSplit = true;
}
if ((section.childWidgets[i] instanceof BlockWidget && !isNullOrUndefined(section.childWidgets[i].previousSplitWidget) && section.childWidgets[i].previousSplitWidget.bodyWidget.page === section.childWidgets[i].bodyWidget.page && !isPreviousSplit)) {
section.childWidgets[i].combineWidget(this.viewer);
if (prevSection.lastChild instanceof TableWidget) {
this.updateCellHeightInCombinedTable(prevSection.lastChild);
}
i--;
continue;
}
prevSection.childWidgets.push(section.childWidgets[i]);
section.childWidgets[i].containerWidget = prevSection;
section.childWidgets[i].containerWidget.page = prevSection.page;
section.childWidgets.splice(0, 1);
i--;
}
section = section.previousRenderedWidget;
}
this.documentHelper.removeEmptyPages();
};
Layout.prototype.reLayoutMultiColumnBlock = function (section, nextSection, blockIndex) {
var block = section.firstChild;
var nextBlock;
do {
if (block instanceof TableWidget && block.tableFormat.preferredWidthType === 'Auto'
&& !block.tableFormat.allowAutoFit) {
block.calculateGrid();
}
if (!isNullOrUndefined(block)) {
this.viewer.updateClientAreaForBlock(block, true, undefined, true);
nextBlock = this.layoutBlock(block, 0, block.index < blockIndex ? true : false);
this.viewer.updateClientAreaForBlock(block, false);
block = nextBlock;
}
} while (block && section.getSplitWidgets().indexOf(block.bodyWidget) !== -1);
block = section.firstChild;
if (this.viewer instanceof PageLayoutViewer && section.sectionFormat.numberOfColumns > 1 && !isNullOrUndefined(nextSection) && nextSection.sectionFormat.breakCode === 'NoBreak' && (section.sectionFormat.breakCode === 'NoBreak' || (section.sectionIndex === section.page.bodyWidgets[0].sectionIndex))) {
var splittedSection = section.getSplitWidgets();
var bodyWidget = splittedSection[splittedSection.length - 1];
if (this.getColumnBreak(section)) {
if (section.page !== bodyWidget.page) {
this.splitBodyWidgetBasedOnColumn(bodyWidget);
}
else {
var firstBody = this.getBodyWidget(bodyWidget, true);
this.viewer.updateClientArea(firstBody, firstBody.page);
var height = this.getNextWidgetHeight(firstBody);
this.viewer.clientActiveArea.height -= height - this.viewer.clientActiveArea.y;
this.viewer.clientActiveArea.y = height;
}
}
else if (!isNullOrUndefined(section.page.nextPage)) {
this.splitBodyWidgetBasedOnColumn(bodyWidget);
}
}
};
Layout.prototype.splitBodyWidgetBasedOnColumn = function (section) {
section = this.getBodyWidget(section, true);
var firstSection = section;
this.isMultiColumnSplit = true;
if (!this.isInitialLoad && section.sectionFormat.equalWidth) {
var previousStartIndex = this.documentHelper.selection.startOffset;
var previousEndIndex = this.documentHelper.selection.endOffset;
this.combineMultiColumn(section);
this.layoutMultiColumnBody(section, false);
if (previousStartIndex !== this.documentHelper.selection.startOffset) {
this.documentHelper.selection.select(previousStartIndex, previousEndIndex);
}
}
this.combineMultiColumn(section);
var lineCountInfo = this.getCountOrLine(section, undefined, undefined, true);
var totalHeight = lineCountInfo.lineCount;
var lineToBeSplit = Math.round(totalHeight / section.sectionFormat.numberOfColumns);
while (section) {
var lineCountInfo_1 = this.getCountOrLine(section, lineToBeSplit, true, false);
var line = lineCountInfo_1.lineWidget;
var lineIndexInCell = lineCountInfo_1.lineCount;
if (!isNullOrUndefined(line)) {
if (line.paragraph.containerWidget instanceof BodyWidget) {
this.moveToNextLine(line, true, line.indexInOwner);
}
else if (line.paragraph.containerWidget instanceof TableCellWidget) {
var table = [line.paragraph.containerWidget.ownerTable];
var rows = [line.paragraph.containerWidget.ownerRow];
var index = line.paragraph.containerWidget.index;
if (table[table.length - 1].isInsideTable) {
table[table.length - 1] = this.getParentTable(table[table.length - 1]);
rows[rows.length - 1] = this.getParentRow(rows[rows.length - 1]);
}
this.updateWidgetsToTable(table, rows, rows[rows.length - 1], false, lineIndexInCell, index, true);
var tableWidget = table[table.length - 1];
var rowWidget = rows[rows.length - 1];
var nextRow = rowWidget.nextRenderedWidget;
while (nextRow) {
this.clearRowWidget(nextRow, true, true, false);
nextRow = this.layoutRow(table, nextRow);
nextRow = nextRow.nextRenderedWidget;
}
if (!isNullOrUndefined(tableWidget.nextRenderedWidget) && section.sectionFormat.equalWidth) {
this.documentHelper.blockToShift = tableWidget.nextRenderedWidget;
this.documentHelper.layout.shiftLayoutedItems(false);
}
}
var firstBody = this.getBodyWidget(line.paragraph.bodyWidget, true);
var lastBody = this.getBodyWidget(firstBody, false);
if (!firstBody.sectionFormat.equalWidth && lastBody.sectionFormat.numberOfColumns - 1 === lastBody.columnIndex && isNullOrUndefined(lastBody.nextSplitWidget)) {
var nonEqualBody = firstBody;
var initialCount = (this.getCountOrLine(firstBody)).lineCount;
this.layoutMultiColumnBody(nonEqualBody, true);
var finalCount = (this.getCountOrLine(firstBody)).lineCount;
if (initialCount !== finalCount) {
this.splitBodyWidgetBasedOnColumn(firstBody);
}
}
if (isNullOrUndefined(lastBody.nextSplitWidget)) {
this.viewer.updateClientArea(firstBody, firstBody.page);
var height = this.getNextWidgetHeight(firstBody);
this.viewer.clientActiveArea.height -= height - this.viewer.clientActiveArea.y;
this.viewer.clientActiveArea.y = height;
this.viewer.clientArea.y = this.viewer.clientActiveArea.y;
this.viewer.clientArea.height = this.viewer.clientActiveArea.height;
}
}
section = section.nextRenderedWidget;
if (!isNullOrUndefined(section) && section.columnIndex === section.sectionFormat.numberOfColumns - 1) {
break;
}
}
this.isMultiColumnSplit = false;
if (!this.isInitialLoad) {
section = this.getBodyWidget(firstSection, false);
if (!isNullOrUndefined(section.nextRenderedWidget)) {
this.documentHelper.blockToShift = section.nextRenderedWidget.firstChild;
}
}
};
/**
* @private
*/
Layout.prototype.getColumnBreak = function (section) {
var firstBody = this.getBodyWidget(section, true);
if (firstBody.sectionFormat.numberOfColumns <= 1) {
return false;
}
while (firstBody) {
if (firstBody.lastChild instanceof ParagraphWidget && firstBody.lastChild.isEndsWithColumnBreak) {
return true;
}
if (isNullOrUndefined(firstBody.nextRenderedWidget) || firstBody.index !== firstBody.nextRenderedWidget.index) {
break;
}
firstBody = firstBody.nextRenderedWidget;
}
return false;
};
Layout.prototype.layoutMultiColumnBody = function (nonEqualBody, updatePosition) {
var skipPosition = false;
while (nonEqualBody) {
if (!skipPosition) {
this.viewer.updateClientArea(nonEqualBody, nonEqualBody.page);
this.viewer.clientActiveArea.height -= nonEqualBody.y - this.viewer.clientActiveArea.y;
if (nonEqualBody instanceof FootNoteWidget) {
this.viewer.clientArea.height = Number.POSITIVE_INFINITY;
this.viewer.clientActiveArea.height = Number.POSITIVE_INFINITY;
}
else {
this.viewer.clientActiveArea.y = nonEqualBody.y;
}
}
skipPosition = updatePosition ? false : true;
for (var i = 0; i < nonEqualBody.childWidgets.length; i++) {
var block = nonEqualBody.childWidgets[i];
if (block instanceof TableWidget) {
this.clearTableWidget(block, true, true, true);
}
this.viewer.updateClientAreaForBlock(block, true);
var isUpdatedList = false;
if (block instanceof ParagraphWidget && !isNullOrUndefined(block.paragraphFormat)
&& block.paragraphFormat.listFormat.listId !== -1) {
isUpdatedList = block.paragraphFormat.listFormat.listLevelNumber === 0 ? true : false;
}
this.layoutBlock(block, 0, isUpdatedList);
this.viewer.updateClientAreaForBlock(block, false);
}
if (nonEqualBody.columnIndex === nonEqualBody.sectionFormat.numberOfColumns - 1 || (!isNullOrUndefined(nonEqualBody.nextRenderedWidget) && nonEqualBody.sectionIndex !== nonEqualBody.nextRenderedWidget.sectionIndex)) {
break;
}
nonEqualBody = nonEqualBody.nextRenderedWidget;
}
};
Layout.prototype.getNextWidgetHeight = function (body) {
var height = 0;
var updatedHeight = 0;
while (body && body.childWidgets.length > 0) {
var lastChild = body.lastChild;
if (lastChild instanceof ParagraphWidget && lastChild.isSectionBreak && lastChild.previousRenderedWidget instanceof TableWidget && this.documentHelper.compatibilityMode !== 'Word2013') {
lastChild = lastChild.previousRenderedWidget;
}
height = lastChild.height;
if (lastChild instanceof TableWidget) {
height = this.getHeight(lastChild);
}
height += lastChild.y;
if (height > updatedHeight) {
updatedHeight = height;
}
if (!isNullOrUndefined(body) && body.columnIndex === body.sectionFormat.numberOfColumns - 1 || body.sectionFormat.numberOfColumns === 0 || (!isNullOrUndefined(body.nextRenderedWidget) && body.sectionIndex !== body.nextRenderedWidget.sectionIndex)) {
break;
}
body = body.nextRenderedWidget;
}
return updatedHeight;
};
Layout.prototype.getHeight = function (block) {
var height = 0;
for (var i = 0; i < block.childWidgets.length; i++) {
height += block.childWidgets[i].height;
}
return height;
};
Layout.prototype.getBookmarkMargin = function (lineWidget) {
var height = 0;
for (var i = 0; i < lineWidget.children.length; i++) {
var element = lineWidget.children[i];
if (!isNullOrUndefined(element.margin) && element instanceof BookmarkElementBox) {
height = element.margin.top + element.margin.bottom;
break;
}
}
return height;
};
Layout.prototype.getCountOrLine = function (section, lineToBeSplit, isSplit, getHeight) {
var totalNoOflines = 0;
var line;
var count = 0;
var skip = false;
var maxHeight = 0;
var lineIndexInCell = 0;
var splitCountLine;
var lineMargin = 0;
while (section) {
for (var i = 0; i < section.childWidgets.length; i++) {
var block = section.childWidgets[i];
if (block instanceof ParagraphWidget) {
//In ms word last paragraph of body widget is renderd in previous paragraph. So no need to calculate the last para
if (block.isSectionBreak) {
continue;
}
for (var j = 0; j < block.childWidgets.length; j++) {
var lineWidget = block.childWidgets[j];
lineMargin = 0;
if (!isNullOrUndefined(lineWidget.margin)) {
lineMargin = lineWidget.margin.top + lineWidget.margin.bottom + this.getBookmarkMargin(lineWidget);
}
if (!isSplit) {
totalNoOflines++;
maxHeight += lineWidget.height - lineMargin;
}
else {
maxHeight += lineWidget.height - lineMargin;
if (Math.round(lineToBeSplit) < Math.round(maxHeight)) {
line = block.childWidgets[j];
skip = true;
count = 0;
break;
}
else {
count++;
}
}
}
}
else if (block instanceof TableWidget) {
splitCountLine = this.getCountOrLineTable(block, lineToBeSplit, isSplit, maxHeight, false, getHeight);
if (getHeight) {
maxHeight += splitCountLine.lineCount;
}
else if (!isSplit) {
totalNoOflines += splitCountLine.lineCount;
}
else if (isNullOrUndefined(splitCountLine.lineWidget)) {
// count = splitCountLine.lineCount;
maxHeight = splitCountLine.lineCount;
}
else {
line = splitCountLine.lineWidget;
lineIndexInCell = splitCountLine.lineCount;
skip = true;
}
}
if (skip && isSplit) {
break;
}
}
if (skip && isSplit) {
break;
}
if (!isNullOrUndefined(section.nextRenderedWidget) && section.index !== section.nex