4522 lines
166 KiB
JavaScript
4522 lines
166 KiB
JavaScript
/*
|
||
* (c) Copyright Ascensio System SIA 2010-2024
|
||
*
|
||
* This program is a free software product. You can redistribute it and/or
|
||
* modify it under the terms of the GNU Affero General Public License (AGPL)
|
||
* version 3 as published by the Free Software Foundation. In accordance with
|
||
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
|
||
* that Ascensio System SIA expressly excludes the warranty of non-infringement
|
||
* of any third-party rights.
|
||
*
|
||
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
|
||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
|
||
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||
*
|
||
* You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish
|
||
* street, Riga, Latvia, EU, LV-1050.
|
||
*
|
||
* The interactive user interfaces in modified source and object code versions
|
||
* of the Program must display Appropriate Legal Notices, as required under
|
||
* Section 5 of the GNU AGPL version 3.
|
||
*
|
||
* Pursuant to Section 7(b) of the License you must retain the original Product
|
||
* logo when distributing the program. Pursuant to Section 7(e) we decline to
|
||
* grant you any rights under trademark law for use of our trademarks.
|
||
*
|
||
* All the Product's GUI elements, including illustrations and icon sets, as
|
||
* well as technical writing content are licensed under the terms of the
|
||
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
|
||
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||
*
|
||
*/
|
||
|
||
"use strict";
|
||
|
||
(function (undefined) {
|
||
|
||
const MIN_JACCARD = 0.34;
|
||
const MIN_DIFF = 0.7;
|
||
const EXCLUDED_PUNCTUATION = {};
|
||
//EXCLUDED_PUNCTUATION[46] = true;
|
||
//EXCLUDED_PUNCTUATION[95] = true;
|
||
EXCLUDED_PUNCTUATION[160] = true;
|
||
//EXCLUDED_PUNCTUATION[63] = true;
|
||
function getMockDocumentFromRuns(arrRuns) {
|
||
const arrSlice = arrRuns.slice();
|
||
arrSlice.push(new AscCommonWord.ParaRun());
|
||
arrSlice[arrSlice.length - 1].Content.push(new AscWord.CRunParagraphMark());
|
||
|
||
const mockDocument = new AscCommonWord.CMockDocument();
|
||
const mockParagraph = new AscCommonWord.CMockParagraph();
|
||
mockDocument.Content.push(mockParagraph);
|
||
mockParagraph.Content = arrSlice;
|
||
|
||
return mockDocument;
|
||
}
|
||
function getChanges(arrOriginalTextElements, arrRevisedTextElements, comparison, oMainParent, oRevisedParent) {
|
||
let arrTextPrChanges = [];
|
||
if (comparison.options.formatting) {
|
||
const oTextPrChangeCollector = new CTextPrChangeCollector(arrOriginalTextElements, arrRevisedTextElements, oMainParent, oRevisedParent, comparison.copyPr);
|
||
arrTextPrChanges = oTextPrChangeCollector.getTextPrChanges();
|
||
}
|
||
|
||
let arrReviewChanges = [];
|
||
if (comparison.needCheckReview) {
|
||
const oReviewChangeCollector = new CReviewChangeCollector(arrOriginalTextElements, arrRevisedTextElements, comparison.oComparisonMoveMarkManager, oMainParent, oRevisedParent, comparison.copyPr);
|
||
arrReviewChanges = oReviewChangeCollector.getReviewChanges();
|
||
}
|
||
|
||
let oCopyPr;
|
||
if (comparison.needCopyForResolveEqualWords) {
|
||
oCopyPr = comparison.copyPr;
|
||
}
|
||
const oCommentChangeCollector = new CCommentChangesCollector(arrOriginalTextElements, arrRevisedTextElements, oCopyPr, comparison.oCommentManager);
|
||
const arrCommentChanges = oCommentChangeCollector.getCommentChanges();
|
||
|
||
const oBookmarkChangeCollector = new CBookmarkChangesCollector(arrRevisedTextElements, oCopyPr);
|
||
const arrBookmarkChanges = oBookmarkChangeCollector.getBookmarkChanges();
|
||
|
||
const arrChanges = arrTextPrChanges.concat(arrReviewChanges, arrBookmarkChanges, arrCommentChanges);
|
||
return arrChanges.sort(function (a, b) {
|
||
if (a.elementIndex === b.elementIndex) {
|
||
if (b.innerElementIndex === a.innerElementIndex) {
|
||
return !!b.isStart - !!a.isStart;
|
||
}
|
||
return b.innerElementIndex - a.innerElementIndex;
|
||
}
|
||
return b.elementIndex - a.elementIndex;
|
||
});
|
||
}
|
||
function resolveTypesWithPartner(arrNodes, comparison) {
|
||
const arrMainElements = [];
|
||
const arrRevisedElements = [];
|
||
for (let i = 0; i < arrNodes.length; i += 1) {
|
||
const oNode = arrNodes[i];
|
||
const oMainElement = oNode.element;
|
||
const oRevisedElement = oNode.partner.element;
|
||
|
||
arrMainElements.push(oMainElement);
|
||
arrRevisedElements.push(oRevisedElement);
|
||
}
|
||
if (!arrMainElements.length) {
|
||
return;
|
||
}
|
||
|
||
const oFirstNode = arrNodes[0];
|
||
const oRevisedParent = oFirstNode.partner.par.element;
|
||
const oMainParent = oFirstNode.par.element;
|
||
|
||
|
||
const oNeedReviewWithUser = {};
|
||
const arrChanges = getChanges(arrMainElements, arrRevisedElements, comparison, oMainParent, oRevisedParent);
|
||
|
||
const oTextIterator = new CRunCollector(arrMainElements, comparison.parentParagraph);
|
||
|
||
for (let i = 0; i < arrChanges.length; i += 1) {
|
||
const oChange = arrChanges[i];
|
||
oChange.apply(oTextIterator, comparison, oNeedReviewWithUser);
|
||
}
|
||
comparison.applyResolveTypes(oNeedReviewWithUser);
|
||
}
|
||
function WordCounter() {
|
||
|
||
this.mapWords = {};
|
||
this.count = 0;
|
||
}
|
||
WordCounter.prototype.update = function(aCodes, oComparison) {
|
||
++this.count;
|
||
let text = String.fromCharCode.apply(String, aCodes);
|
||
if (!oComparison.options.caseChanges) {
|
||
text = text.toLowerCase();
|
||
}
|
||
if (!this.mapWords[text]) {
|
||
this.mapWords[text] = 0;
|
||
}
|
||
this.mapWords[text] += 1;
|
||
};
|
||
WordCounter.prototype.diff = function(other) {
|
||
let shared = 0;
|
||
for (let i in this.mapWords) {
|
||
if (other.mapWords[i]) {
|
||
shared += Math.min(other.mapWords[i], this.mapWords[i]);
|
||
}
|
||
}
|
||
return other.count + this.count - 2 * shared;
|
||
};
|
||
|
||
function changeFirstTextElement(oTextIterator, oRun)
|
||
{
|
||
const oElement = oTextIterator.getCurrentElement();
|
||
oElement.elements[0] = oRun.Content[0];
|
||
oElement.firstRun = oRun;
|
||
}
|
||
|
||
function CReviewChange(oReviewInfo)
|
||
{
|
||
this.elementIndex = -1;
|
||
this.innerElementIndex = -1;
|
||
|
||
this.reviewInfo = oReviewInfo;
|
||
this.reviewType = null;
|
||
this.moveReviewType = null
|
||
this.moveReviewMarkName = null;
|
||
|
||
this.collectRuns = [];
|
||
this.isStart = false;
|
||
this.partner = null;
|
||
this.mapRuns = {};
|
||
}
|
||
CReviewChange.prototype.apply = function (oTextIterator, comparison, oNeedReviewWithUser) {
|
||
if (this.isStart) {
|
||
this.applyStart(oTextIterator, comparison, oNeedReviewWithUser);
|
||
} else {
|
||
this.applyEnd(oTextIterator);
|
||
}
|
||
};
|
||
CReviewChange.prototype.applyStart = function (oTextIterator, comparison, oNeedReviewWithUser) {
|
||
const bIsLast = oTextIterator.elements[this.elementIndex].elements.length === this.innerElementIndex;
|
||
oTextIterator.skipTo(this.elementIndex, bIsLast ? this.innerElementIndex - 1 : this.innerElementIndex);
|
||
const oRun = oTextIterator.splitCurrentRun(bIsLast);
|
||
const oPartner = this.partner;
|
||
oPartner.dropLastRun();
|
||
oTextIterator.addToCollectBack(oRun);
|
||
if (this.elementIndex === 0 && this.innerElementIndex === 0)
|
||
{
|
||
changeFirstTextElement(oTextIterator, oRun);
|
||
}
|
||
|
||
|
||
oTextIterator.setCollectReviewRuns(null);
|
||
const arrRuns = oPartner.collectRuns;
|
||
|
||
const nPriorityReviewType = oPartner.reviewType;
|
||
const nPriorityMoveReviewType = oPartner.moveReviewType;
|
||
const sMoveReviewMarkName = oPartner.moveReviewMarkName;
|
||
const oReviewInfo = oPartner.reviewInfo;
|
||
const sReviewUserName = oReviewInfo.GetUserName();
|
||
const sReviewDate = oReviewInfo.GetDateTime();
|
||
|
||
|
||
if (!oNeedReviewWithUser[sReviewDate]) {
|
||
oNeedReviewWithUser[sReviewDate] = {};
|
||
}
|
||
|
||
if (!oNeedReviewWithUser[sReviewDate][sReviewUserName]) {
|
||
const oNeedReview = {reviewTypes: {}, moveReviewTypes: {}};
|
||
oNeedReview.reviewTypes[reviewtype_Add] = [];
|
||
oNeedReview.reviewTypes[reviewtype_Remove] = [];
|
||
oNeedReview.moveReviewTypes[Asc.c_oAscRevisionsMove.MoveTo] = [];
|
||
oNeedReview.moveReviewTypes[Asc.c_oAscRevisionsMove.MoveFrom] = [];
|
||
oNeedReviewWithUser[sReviewDate][sReviewUserName] = oNeedReview;
|
||
}
|
||
|
||
if (AscFormat.isRealNumber(nPriorityReviewType)) {
|
||
for (let i = 0; i < arrRuns.length; i += 1)
|
||
{
|
||
oNeedReviewWithUser[sReviewDate][sReviewUserName].reviewTypes[nPriorityReviewType].push({element: arrRuns[i], reviewInfo: oReviewInfo});
|
||
}
|
||
}
|
||
else if (AscFormat.isRealNumber(nPriorityMoveReviewType))
|
||
{
|
||
for (let i = 0; i < arrRuns.length; i += 1)
|
||
{
|
||
comparison.oComparisonMoveMarkManager.addMoveMarkNameRunRelation(sMoveReviewMarkName, arrRuns[i]);
|
||
comparison.oComparisonMoveMarkManager.addRunMoveMarkNameRelation(sMoveReviewMarkName, arrRuns[i]);
|
||
oNeedReviewWithUser[sReviewDate][sReviewUserName].moveReviewTypes[nPriorityMoveReviewType].push({element: arrRuns[i], reviewInfo: oReviewInfo}); }
|
||
}
|
||
};
|
||
CReviewChange.prototype.applyEnd = function (oTextIterator) {
|
||
const bIsLast = oTextIterator.elements[this.elementIndex].elements.length === this.innerElementIndex;
|
||
oTextIterator.skipTo(this.elementIndex, bIsLast ? this.innerElementIndex - 1 : this.innerElementIndex);
|
||
oTextIterator.setCollectReviewRuns(this);
|
||
oTextIterator.addToCollectCurrentRun();
|
||
const oSplitRun = oTextIterator.splitCurrentRun(bIsLast);
|
||
oTextIterator.addToCollectTextPr(oSplitRun);
|
||
};
|
||
CReviewChange.prototype.addRun = function (oRun) {
|
||
if (!this.mapRuns[oRun.Id]) {
|
||
this.mapRuns[oRun.Id] = true;
|
||
this.collectRuns.push(oRun);
|
||
}
|
||
};
|
||
|
||
CReviewChange.prototype.addRunBack = function (oRun) {
|
||
if (!this.mapRuns[oRun.Id]) {
|
||
this.mapRuns[oRun.Id] = true;
|
||
this.collectRuns.unshift(oRun);
|
||
}
|
||
};
|
||
CReviewChange.prototype.dropLastRun = function () {
|
||
const oRun = this.collectRuns.pop();
|
||
if (oRun) {
|
||
delete this.mapRuns[oRun.Id];
|
||
}
|
||
};
|
||
CReviewChange.prototype.setPosition = function (nElementIndex, nInnerElementIndex) {
|
||
this.elementIndex = nElementIndex;
|
||
this.innerElementIndex = nInnerElementIndex;
|
||
};
|
||
CReviewChange.prototype.setMoveReviewType = function (nMoveReviewType, sMoveReviewMarkName)
|
||
{
|
||
this.moveReviewType = nMoveReviewType;
|
||
this.moveReviewMarkName = sMoveReviewMarkName;
|
||
}
|
||
CReviewChange.prototype.isSimilar = function (oOtherChange) {
|
||
if (this.reviewType !== oOtherChange.reviewType) {
|
||
return false;
|
||
}
|
||
|
||
if (this.moveReviewType !== oOtherChange.moveReviewType) {
|
||
return false;
|
||
}
|
||
|
||
if (this.moveReviewMarkName !== oOtherChange.moveReviewMarkName) {
|
||
return false;
|
||
}
|
||
|
||
if (this.reviewInfo && !this.reviewInfo.IsEqual(oOtherChange.reviewInfo) || !this.reviewInfo && oOtherChange.reviewInfo) {
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
};
|
||
CReviewChange.prototype.setPartner = function (oPartner) {
|
||
this.partner = oPartner;
|
||
oPartner.partner = this;
|
||
};
|
||
CReviewChange.prototype.setReviewType = function (nReviewType)
|
||
{
|
||
this.reviewType = nReviewType;
|
||
}
|
||
|
||
function CLabelChange(arrLabels, nElementIndex, nInnerElementIndex)
|
||
{
|
||
this.labels = arrLabels;
|
||
this.elementIndex = nElementIndex;
|
||
this.innerElementIndex = nInnerElementIndex;
|
||
}
|
||
CLabelChange.prototype.apply = function (oTextIterator, comparison, oNeedReviewWithUser) {
|
||
const bIsLast = oTextIterator.elements[this.elementIndex].elements.length === this.innerElementIndex;
|
||
oTextIterator.skipTo(this.elementIndex, bIsLast ? this.innerElementIndex - 1 : this.innerElementIndex);
|
||
const oRun = oTextIterator.splitCurrentRun(bIsLast);
|
||
oTextIterator.addToCollectBack(oRun);
|
||
for (let i = this.labels.length - 1; i >= 0; i -= 1)
|
||
{
|
||
const oLabel = this.labels[i];
|
||
oTextIterator.parent.AddToContent(oTextIterator.runIndex + 1, oLabel);
|
||
}
|
||
if (this.elementIndex === 0 && this.innerElementIndex === 0)
|
||
{
|
||
const oElement = oTextIterator.getCurrentElement();
|
||
const oFirstLabel = this.labels[0];
|
||
if (oFirstLabel)
|
||
{
|
||
oElement.lastSwitchElement = oFirstLabel;
|
||
}
|
||
else
|
||
{
|
||
changeFirstTextElement(oTextIterator, oRun);
|
||
}
|
||
}
|
||
};
|
||
|
||
function CBookmarkChangesCollector(arrElements, copyPr) {
|
||
this.elements = arrElements;
|
||
this.copyPr = copyPr;
|
||
}
|
||
CBookmarkChangesCollector.prototype.getBookmarkChanges = function () {
|
||
const arrResult = [];
|
||
for (let i = this.elements.length - 1; i >= 0; i -= 1) {
|
||
const oElement = this.elements[i];
|
||
const arrInsertIndexes = oElement.getBookmarkInsertIndexes();
|
||
for (let j = 0; j < arrInsertIndexes.length; j += 1) {
|
||
const nInsertIndex = arrInsertIndexes[j];
|
||
const arrElements = this.getBookmarkElements(oElement, nInsertIndex);
|
||
arrResult.push(new CLabelChange(arrElements, i, nInsertIndex));
|
||
}
|
||
}
|
||
return arrResult;
|
||
}
|
||
CBookmarkChangesCollector.prototype.getBookmarkElements = function (oTextElement, nInsertIndex) {
|
||
const arrElements = oTextElement.bookmarks[nInsertIndex].slice();
|
||
if (this.copyPr) {
|
||
for (let i = 0; i < arrElements.length; i += 1) {
|
||
arrElements[i] = arrElements[i].Copy(false, this.copyPr);
|
||
}
|
||
}
|
||
return arrElements;
|
||
};
|
||
|
||
function CCommentChangesCollector(arrMainElements, arrRevisedElements, copyPr, oCommentManager) {
|
||
this.mainElements = arrMainElements;
|
||
this.revisedElements = arrRevisedElements;
|
||
this.commentManager = oCommentManager;
|
||
this.copyPr = copyPr;
|
||
}
|
||
CCommentChangesCollector.prototype.getCommentChanges = function () {
|
||
const arrResult = [];
|
||
for (let i = this.mainElements.length - 1; i >= 0; i -= 1) {
|
||
const oMainElement = this.mainElements[i];
|
||
const oRevisedElement = this.revisedElements[i];
|
||
const arrInsertIndexes = oRevisedElement.getCommentInsertIndexes();
|
||
for (let j = 0; j < arrInsertIndexes.length; j += 1) {
|
||
const nInsertIndex = arrInsertIndexes[j];
|
||
const arrCommentElements = this.getCommentElements(oMainElement, oRevisedElement, nInsertIndex);
|
||
arrResult.push(new CLabelChange(arrCommentElements, i, nInsertIndex));
|
||
}
|
||
}
|
||
return arrResult;
|
||
}
|
||
CCommentChangesCollector.prototype.getCommentElements = function (oMainElement, oRevisedElement, nInsertIndex) {
|
||
this.checkComments(oMainElement, oRevisedElement, nInsertIndex);
|
||
const arrElements = [];
|
||
for (let i = 0; i < oRevisedElement.comments[nInsertIndex].length; i += 1)
|
||
{
|
||
const oParaComment = oRevisedElement.comments[nInsertIndex][i].element;
|
||
arrElements.push(oParaComment);
|
||
if (oParaComment.IsCommentStart())
|
||
{
|
||
const sCommentId = oParaComment.GetCommentId();
|
||
const arrLaterMerge = this.commentManager.getMergeLater(sCommentId);
|
||
if (arrLaterMerge)
|
||
{
|
||
arrElements.push.apply(arrElements, arrLaterMerge);
|
||
}
|
||
}
|
||
}
|
||
|
||
if (this.copyPr) {
|
||
for (let i = 0; i < arrElements.length; i += 1) {
|
||
arrElements[i] = arrElements[i].Copy(false, this.copyPr);
|
||
}
|
||
}
|
||
return arrElements;
|
||
};
|
||
|
||
CCommentChangesCollector.prototype.checkComments = function (oMainElement, oRevisedElement, nInsertIndex) {
|
||
const arrRevisedComments = oRevisedElement.comments[nInsertIndex];
|
||
const arrMainComments = oMainElement.comments[nInsertIndex];
|
||
this.commentManager.checkComments(arrMainComments, arrRevisedComments, arrRevisedComments);
|
||
};
|
||
|
||
function CReviewChangeCollector(arrMainElements, arrRevisedElements, oMoveMarkManager, oMainParagraph, oRevisedParagraph, oCopyPr) {
|
||
this.mainElements = arrMainElements;
|
||
this.revisedElements = arrRevisedElements;
|
||
this.moveMarkManager = oMoveMarkManager;
|
||
this.mainParagraph = oMainParagraph;
|
||
this.revisedParagraph = oRevisedParagraph;
|
||
this.copyPr = oCopyPr;
|
||
}
|
||
CReviewChangeCollector.prototype.isSkippedElement = function (oRun) {
|
||
if (!(oRun instanceof AscCommonWord.ParaRun)) {
|
||
return true;
|
||
}
|
||
if (this.copyPr.SkipFootnoteReference) {
|
||
return oRun.IsFootEndnoteReferenceRun();
|
||
}
|
||
return false;
|
||
};
|
||
CReviewChangeCollector.prototype.getPriorityChange = function (oRevisedRun, oMainRun) {
|
||
const oRevisedReviewInfo = oRevisedRun.GetReviewInfo();
|
||
const nRevisedReviewType = oRevisedRun.GetReviewType();
|
||
const nRevisedMoveReviewType = oRevisedRun.GetReviewMoveType();
|
||
const sRevisedNameMoveMark = this.moveMarkManager.getMoveMarkNameByRun(oRevisedRun);
|
||
const oRevisedPrevAdded = oRevisedReviewInfo && oRevisedReviewInfo.GetPrevAdded();
|
||
|
||
const oMainReviewInfo = oMainRun.GetReviewInfo();
|
||
const nMainReviewType = oMainRun.GetReviewType();
|
||
const oMainPrevAdded = oMainReviewInfo && oMainReviewInfo.GetPrevAdded();
|
||
const nMainMoveReviewType = oMainRun.GetReviewMoveType();
|
||
|
||
let nPriorityReviewType;
|
||
let oPriorityReviewInfo;
|
||
let nPriorityMoveReviewType;
|
||
let bIsMove = false;
|
||
if (nRevisedReviewType !== reviewtype_Common && !(oMainPrevAdded && nMainReviewType === reviewtype_Remove)) {
|
||
if (nMainReviewType !== nRevisedReviewType) {
|
||
nPriorityReviewType = nRevisedReviewType;
|
||
oPriorityReviewInfo = oRevisedReviewInfo;
|
||
} else if (nMainReviewType === reviewtype_Remove && oRevisedPrevAdded) {
|
||
nPriorityReviewType = reviewtype_Add;
|
||
oPriorityReviewInfo = oRevisedPrevAdded;
|
||
}
|
||
}
|
||
if (nMainMoveReviewType === Asc.c_oAscRevisionsMove.NoMove && nRevisedMoveReviewType !== Asc.c_oAscRevisionsMove.NoMove) {
|
||
nPriorityMoveReviewType = nRevisedMoveReviewType;
|
||
oPriorityReviewInfo = oRevisedReviewInfo;
|
||
bIsMove = true;
|
||
}
|
||
|
||
if ((AscFormat.isRealNumber(nPriorityReviewType) || AscFormat.isRealNumber(nPriorityMoveReviewType)) && oPriorityReviewInfo)
|
||
{
|
||
const oChange = new CReviewChange(oPriorityReviewInfo);
|
||
if (bIsMove)
|
||
{
|
||
oChange.setMoveReviewType(nPriorityMoveReviewType, sRevisedNameMoveMark);
|
||
}
|
||
else
|
||
{
|
||
oChange.setReviewType(nPriorityReviewType);
|
||
}
|
||
return oChange;
|
||
}
|
||
};
|
||
CReviewChangeCollector.prototype.getRevisedLastRunIndex = function () {
|
||
const oLastElement = this.revisedElements[this.revisedElements.length - 1];
|
||
const oLastRun = oLastElement.lastRun;
|
||
return this.getLastRunIndex(oLastRun, oLastElement.elements[oLastElement.elements.length - 1], this.revisedParagraph);
|
||
};
|
||
CReviewChangeCollector.prototype.getMainLastRunIndex = function () {
|
||
const oLastElement = this.mainElements[this.mainElements.length - 1];
|
||
const oLastRun = oLastElement.lastRun;
|
||
return this.getLastRunIndex(oLastRun, oLastElement.elements[oLastElement.elements.length - 1], this.mainParagraph);
|
||
};
|
||
CReviewChangeCollector.prototype.getLastRunIndex = function (oRun, oElement, oRunParagraph) {
|
||
const oContent = oRunParagraph.Content;
|
||
for (let i = oContent.length - 1; i >= 0; i -= 1) {
|
||
if (oContent[i] === oRun) {
|
||
for (let j = oRun.Content.length - 1; j >= 0; j -= 1) {
|
||
const oRunElement = oRun.Content[j];
|
||
if (oRunElement === oElement) {
|
||
return {runIndex: i, elementIndex: j};
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return null;
|
||
};
|
||
CReviewChangeCollector.prototype.getReviewChanges = function () {
|
||
const arrResult = [];
|
||
|
||
let nElementIndex = this.revisedElements.length - 1;
|
||
let nInnerElementIndex = this.revisedElements[nElementIndex].elements.length - 1;
|
||
|
||
const oRevisedContent = this.revisedParagraph.Content;
|
||
const oMainContent = this.mainParagraph.Content;
|
||
|
||
const oLastRevisedRunInfo = this.getRevisedLastRunIndex();
|
||
const oLastMainRunInfo = this.getMainLastRunIndex();
|
||
if (!oLastMainRunInfo || !oLastRevisedRunInfo) {
|
||
return arrResult;
|
||
}
|
||
|
||
let nRevisedRunIndex = oLastRevisedRunInfo.runIndex;
|
||
let nMainRunIndex = oLastMainRunInfo.runIndex;
|
||
|
||
let bSaveOldRevisedCount = true;
|
||
let bSaveOldMainCount = true;
|
||
let nRevisedElementsCount = oLastRevisedRunInfo.elementIndex + 1;
|
||
let nMainElementsCount = oLastMainRunInfo.elementIndex + 1;
|
||
while (nRevisedRunIndex >= 0 && nMainRunIndex >= 0) {
|
||
const oRevisedRun = oRevisedContent[nRevisedRunIndex];
|
||
const oMainRun = oMainContent[nMainRunIndex];
|
||
|
||
if (!bSaveOldRevisedCount) {
|
||
nRevisedElementsCount = oRevisedRun.Content.length;
|
||
bSaveOldRevisedCount = true;
|
||
}
|
||
if (!bSaveOldMainCount) {
|
||
nMainElementsCount = oMainRun.Content.length;
|
||
bSaveOldMainCount = true;
|
||
}
|
||
if (nMainElementsCount !== 0 && nRevisedElementsCount !== 0) {
|
||
const oLastPrChange = arrResult[arrResult.length - 1];
|
||
const oPriorityChange = this.getPriorityChange(oRevisedRun, oMainRun);
|
||
if (!oPriorityChange) {
|
||
if (oLastPrChange && !oLastPrChange.isStart) {
|
||
const oStartReviewChange = new CReviewChange(null);
|
||
oStartReviewChange.isStart = true;
|
||
oStartReviewChange.setPosition(nElementIndex, nInnerElementIndex + 1);
|
||
oStartReviewChange.setPartner(oLastPrChange);
|
||
arrResult.push(oStartReviewChange);
|
||
}
|
||
} else if (oLastPrChange) {
|
||
if (oLastPrChange.isStart) {
|
||
oPriorityChange.setPosition(nElementIndex, nInnerElementIndex + 1);
|
||
arrResult.push(oPriorityChange);
|
||
} else if (!oLastPrChange.isSimilar(oPriorityChange)) {
|
||
const oStartReviewChange = new CReviewChange(null);
|
||
oStartReviewChange.isStart = true;
|
||
oStartReviewChange.setPosition(nElementIndex, nInnerElementIndex + 1);
|
||
oStartReviewChange.setPartner(oLastPrChange);
|
||
arrResult.push(oStartReviewChange);
|
||
|
||
oPriorityChange.setPosition(nElementIndex, nInnerElementIndex + 1);
|
||
arrResult.push(oPriorityChange);
|
||
}
|
||
} else {
|
||
oPriorityChange.setPosition(nElementIndex, nInnerElementIndex + 1);
|
||
arrResult.push(oPriorityChange);
|
||
}
|
||
}
|
||
|
||
while (nRevisedElementsCount !== 0 && nMainElementsCount !== 0) {
|
||
const nMinCount = Math.min(nRevisedElementsCount, nMainElementsCount);
|
||
if (nInnerElementIndex + 1 > nMinCount) {
|
||
nInnerElementIndex -= nMinCount;
|
||
nRevisedElementsCount -= nMinCount;
|
||
nMainElementsCount -= nMinCount;
|
||
} else {
|
||
nRevisedElementsCount -= nInnerElementIndex + 1;
|
||
nMainElementsCount -= nInnerElementIndex + 1;
|
||
nElementIndex -= 1;
|
||
if (this.revisedElements[nElementIndex] && this.mainElements[nElementIndex]) {
|
||
nInnerElementIndex = this.revisedElements[nElementIndex].revisedElements.length - 1;
|
||
}
|
||
}
|
||
if (nElementIndex < 0) {
|
||
const oLastPrChange = arrResult[arrResult.length - 1];
|
||
if (oLastPrChange && !oLastPrChange.isStart) {
|
||
const oStartReviewChange = new CReviewChange(null);
|
||
oStartReviewChange.isStart = true;
|
||
oStartReviewChange.setPosition(0, 0);
|
||
oStartReviewChange.setPartner(oLastPrChange);
|
||
arrResult.push(oStartReviewChange);
|
||
}
|
||
return arrResult;
|
||
}
|
||
}
|
||
if (nRevisedElementsCount === 0) {
|
||
do {
|
||
nRevisedRunIndex -= 1;
|
||
bSaveOldRevisedCount = false;
|
||
} while (this.isSkippedElement(oRevisedContent[nRevisedRunIndex]) && nRevisedRunIndex >= 0)
|
||
}
|
||
if (nMainElementsCount === 0) {
|
||
do {
|
||
nMainRunIndex -= 1;
|
||
bSaveOldMainCount = false;
|
||
} while (this.isSkippedElement(oMainContent[nMainRunIndex]) && nMainRunIndex >= 0)
|
||
}
|
||
}
|
||
return arrResult;
|
||
};
|
||
|
||
function CTextPrChange(isStart, elementIndex, innerElementIndex, textPr) {
|
||
this.isStart = !!isStart;
|
||
this.elementIndex = elementIndex;
|
||
this.innerElementIndex = innerElementIndex;
|
||
this.textPr = textPr;
|
||
this.partner = null;
|
||
this.collectRuns = [];
|
||
this.mapRuns = {};
|
||
}
|
||
|
||
CTextPrChange.prototype.apply = function (oTextIterator, comparison, oNeedReviewWithUser) {
|
||
if (this.isStart) {
|
||
this.applyStart(oTextIterator, comparison);
|
||
} else {
|
||
this.applyEnd(oTextIterator);
|
||
}
|
||
};
|
||
CTextPrChange.prototype.applyStart = function (oTextIterator, oComparison) {
|
||
const bIsLast = oTextIterator.elements[this.elementIndex].elements.length === this.innerElementIndex;
|
||
oTextIterator.skipTo(this.elementIndex, bIsLast ? this.innerElementIndex - 1 : this.innerElementIndex);
|
||
const oPartner = this.partner;
|
||
const oSplitRun = oTextIterator.splitCurrentRun(bIsLast);
|
||
oPartner.dropLastRun();
|
||
oTextIterator.addToCollectBack(oSplitRun);
|
||
if (this.elementIndex === 0 && this.innerElementIndex === 0)
|
||
{
|
||
changeFirstTextElement(oTextIterator, oSplitRun);
|
||
}
|
||
oTextIterator.setCollectTextPrRuns(null);
|
||
const arrRuns = oPartner.collectRuns;
|
||
const oNewTextPr = oPartner.textPr;
|
||
|
||
for (let i = 0; i < arrRuns.length; i += 1) {
|
||
const oRun = arrRuns[i];
|
||
const oCopyTextPr = oNewTextPr.Copy();
|
||
const oOldTextPr = oRun.GetTextPr();
|
||
const oReviewInfo = oComparison.getReviewInfo();
|
||
oCopyTextPr.SetPrChange(oOldTextPr, oReviewInfo);
|
||
oRun.SetPr(oCopyTextPr);
|
||
}
|
||
};
|
||
CTextPrChange.prototype.applyEnd = function (oTextIterator) {
|
||
const bIsLast = oTextIterator.elements[this.elementIndex].elements.length === this.innerElementIndex;
|
||
oTextIterator.skipTo(this.elementIndex, bIsLast ? this.innerElementIndex - 1 : this.innerElementIndex);
|
||
|
||
oTextIterator.setCollectTextPrRuns(this);
|
||
oTextIterator.addToCollectCurrentRun();
|
||
const oSplitRun = oTextIterator.splitCurrentRun(bIsLast);
|
||
oTextIterator.addToCollectReviewChange(oSplitRun);
|
||
};
|
||
CTextPrChange.prototype.setPartner = function (partner) {
|
||
this.partner = partner;
|
||
};
|
||
|
||
CTextPrChange.prototype.addRun = function (oRun) {
|
||
if (!this.mapRuns[oRun.Id]) {
|
||
this.mapRuns[oRun.Id] = true;
|
||
this.collectRuns.push(oRun);
|
||
}
|
||
};
|
||
|
||
CTextPrChange.prototype.addRunBack = function (oRun) {
|
||
if (!this.mapRuns[oRun.Id]) {
|
||
this.mapRuns[oRun.Id] = true;
|
||
this.collectRuns.unshift(oRun);
|
||
}
|
||
};
|
||
CTextPrChange.prototype.dropLastRun = function () {
|
||
const oRun = this.collectRuns.pop();
|
||
if (oRun) {
|
||
delete this.mapRuns[oRun.Id];
|
||
}
|
||
};
|
||
|
||
function CTextPrChangeCollector(arrMainElements, arrRevisedElements, oMainParagraph, oRevisedParagraph, oCopyPr) {
|
||
this.elements = arrRevisedElements;
|
||
this.comparedElements = arrMainElements;
|
||
this.mainParagraph = oMainParagraph;
|
||
this.revisedParagraph = oRevisedParagraph;
|
||
this.copyPr = oCopyPr;
|
||
}
|
||
CTextPrChangeCollector.prototype.isSkippedElement = CReviewChangeCollector.prototype.isSkippedElement;
|
||
CTextPrChangeCollector.prototype.getRevisedLastRunIndex = function () {
|
||
const oLastElement = this.elements[this.elements.length - 1];
|
||
const oLastRun = oLastElement.lastRun;
|
||
return this.getLastRunIndex(oLastRun, oLastElement.elements[oLastElement.elements.length - 1], this.revisedParagraph);
|
||
};
|
||
CTextPrChangeCollector.prototype.getMainLastRunIndex = function () {
|
||
const oLastElement = this.comparedElements[this.comparedElements.length - 1];
|
||
const oLastRun = oLastElement.lastRun;
|
||
return this.getLastRunIndex(oLastRun, oLastElement.elements[oLastElement.elements.length - 1], this.mainParagraph);
|
||
};
|
||
CTextPrChangeCollector.prototype.getLastRunIndex = function (oRun, oElement, oRunParagraph) {
|
||
const oContent = oRunParagraph.Content;
|
||
for (let i = oContent.length - 1; i >= 0; i -= 1) {
|
||
if (oContent[i] === oRun) {
|
||
for (let j = oRun.Content.length - 1; j >= 0; j -= 1) {
|
||
const oRunElement = oRun.Content[j];
|
||
if (oRunElement === oElement) {
|
||
return {runIndex: i, elementIndex: j};
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return null;
|
||
};
|
||
CTextPrChangeCollector.prototype.getTextPrChanges = function () {
|
||
const arrResult = [];
|
||
|
||
let nElementIndex = this.elements.length - 1;
|
||
let nInnerElementIndex = this.elements[nElementIndex].elements.length - 1;
|
||
|
||
const oRevisedContent = this.revisedParagraph.Content;
|
||
const oMainContent = this.mainParagraph.Content;
|
||
|
||
const oLastRevisedRunInfo = this.getRevisedLastRunIndex();
|
||
const oLastMainRunInfo = this.getMainLastRunIndex();
|
||
if (!oLastMainRunInfo || !oLastRevisedRunInfo) {
|
||
return arrResult;
|
||
}
|
||
|
||
let nRevisedRunIndex = oLastRevisedRunInfo.runIndex;
|
||
let nMainRunIndex = oLastMainRunInfo.runIndex;
|
||
|
||
let bSaveOldRevisedCount = true;
|
||
let bSaveOldMainCount = true;
|
||
let nRevisedElementsCount = oLastRevisedRunInfo.elementIndex + 1;
|
||
let nMainElementsCount = oLastMainRunInfo.elementIndex + 1;
|
||
while (nRevisedRunIndex >= 0 && nMainRunIndex >= 0) {
|
||
const oRevisedRun = oRevisedContent[nRevisedRunIndex];
|
||
const oMainRun = oMainContent[nMainRunIndex];
|
||
const oMainTextPr = oMainRun.Pr;
|
||
const oRevisedTextPr = oRevisedRun.Pr.Copy(undefined, this.copyPr);
|
||
|
||
if (!bSaveOldRevisedCount) {
|
||
nRevisedElementsCount = oRevisedRun.Content.length;
|
||
bSaveOldRevisedCount = true;
|
||
}
|
||
if (!bSaveOldMainCount) {
|
||
nMainElementsCount = oMainRun.Content.length;
|
||
bSaveOldMainCount = true;
|
||
}
|
||
if (nMainElementsCount !== 0 && nRevisedElementsCount !== 0) {
|
||
const oLastPrChange = arrResult[arrResult.length - 1];
|
||
if (oMainTextPr.Is_Equal(oRevisedTextPr)) {
|
||
if (oLastPrChange && !oLastPrChange.isStart) {
|
||
const oStartPrChange = new CTextPrChange(true, nElementIndex, nInnerElementIndex + 1);
|
||
oStartPrChange.setPartner(oLastPrChange);
|
||
arrResult.push(oStartPrChange);
|
||
}
|
||
} else if (oLastPrChange) {
|
||
if (oLastPrChange.isStart) {
|
||
arrResult.push(new CTextPrChange(false, nElementIndex, nInnerElementIndex + 1, oRevisedTextPr));
|
||
} else if (!oLastPrChange.textPr.Is_Equal(oRevisedTextPr)) {
|
||
const oStartPrChange = new CTextPrChange(true, nElementIndex, nInnerElementIndex + 1);
|
||
oStartPrChange.setPartner(oLastPrChange);
|
||
arrResult.push(oStartPrChange);
|
||
arrResult.push(new CTextPrChange(false, nElementIndex, nInnerElementIndex + 1, oRevisedTextPr));
|
||
}
|
||
} else {
|
||
arrResult.push(new CTextPrChange(false, nElementIndex, nInnerElementIndex + 1, oRevisedTextPr));
|
||
}
|
||
|
||
}
|
||
|
||
while (nRevisedElementsCount !== 0 && nMainElementsCount !== 0) {
|
||
const nMinCount = Math.min(nRevisedElementsCount, nMainElementsCount);
|
||
if (nInnerElementIndex + 1 > nMinCount) {
|
||
nInnerElementIndex -= nMinCount;
|
||
nRevisedElementsCount -= nMinCount;
|
||
nMainElementsCount -= nMinCount;
|
||
} else {
|
||
nRevisedElementsCount -= nInnerElementIndex + 1;
|
||
nMainElementsCount -= nInnerElementIndex + 1;
|
||
nElementIndex -= 1;
|
||
if (this.elements[nElementIndex] && this.comparedElements[nElementIndex]) {
|
||
nInnerElementIndex = this.elements[nElementIndex].elements.length - 1;
|
||
}
|
||
}
|
||
if (nElementIndex < 0) {
|
||
const oLastPrChange = arrResult[arrResult.length - 1];
|
||
if (oLastPrChange && !oLastPrChange.isStart) {
|
||
const oStartPrChange = new CTextPrChange(true, 0, 0);
|
||
oStartPrChange.setPartner(oLastPrChange);
|
||
arrResult.push(oStartPrChange);
|
||
}
|
||
return arrResult;
|
||
}
|
||
}
|
||
if (nRevisedElementsCount === 0) {
|
||
do {
|
||
nRevisedRunIndex -= 1;
|
||
bSaveOldRevisedCount = false;
|
||
} while (this.isSkippedElement(oRevisedContent[nRevisedRunIndex]) && nRevisedRunIndex >= 0)
|
||
}
|
||
if (nMainElementsCount === 0) {
|
||
do {
|
||
nMainRunIndex -= 1;
|
||
bSaveOldMainCount = false;
|
||
} while (this.isSkippedElement(oMainContent[nMainRunIndex]) && nMainRunIndex >= 0)
|
||
}
|
||
}
|
||
return arrResult;
|
||
};
|
||
|
||
function CNode(oElement, oParent)
|
||
{
|
||
this.element = oElement;
|
||
this.par = null;
|
||
this.children = [];
|
||
this.depth = 0;
|
||
this.changes = [];
|
||
this.partner = null;
|
||
this.childidx = null;
|
||
|
||
this.wordCounter = null;
|
||
if(oParent)
|
||
{
|
||
oParent.addChildNode(this);
|
||
}
|
||
}
|
||
CNode.prototype.checkLastNodeOnInsertWithResolveConflict = function(comparison, aContentToInsert, oChange) {
|
||
if (!comparison.parentParagraph) {
|
||
return true;
|
||
}
|
||
const applyingParagraph = comparison.parentParagraph;
|
||
const index = oChange.anchor.index;
|
||
if (index === this.children.length - 1) {
|
||
|
||
const oLastConflictElement = this.children[this.children.length - 2].element;
|
||
const nInsertIndex = oLastConflictElement.lastRun.GetPosInParent(applyingParagraph);
|
||
const nLastSymbolPosition = oLastConflictElement.lastRun.GetElementPosition(oLastConflictElement.elements[oLastConflictElement.elements.length - 1]);
|
||
if (nLastSymbolPosition !== -1) {
|
||
const oNewRun = oLastConflictElement.lastRun.Split2(nLastSymbolPosition + 1, applyingParagraph, nInsertIndex);
|
||
comparison.checkOriginalAndSplitRun(oNewRun, oLastConflictElement.lastRun);
|
||
this.applyInsert(aContentToInsert, [], nInsertIndex + 1, comparison);
|
||
return false;
|
||
}
|
||
}
|
||
return true;
|
||
};
|
||
CNode.prototype.getDiff = function (oAnotherNode, oComparison) {
|
||
if (this.equals(oAnotherNode, oComparison)) {
|
||
let nWordDiff = this.wordCounter.diff(oAnotherNode.wordCounter);
|
||
if (this.element instanceof AscWord.Paragraph) {
|
||
let startType;
|
||
let endType;
|
||
if (this.element.SectPr) {
|
||
startType = this.element.SectPr.Type;
|
||
}
|
||
if (oAnotherNode.element.SectPr) {
|
||
endType = oAnotherNode.element.SectPr.Type;
|
||
}
|
||
nWordDiff += endType !== startType ? 1 : 0;
|
||
}
|
||
return nWordDiff;
|
||
}
|
||
return this.wordCounter.count + oAnotherNode.wordCounter.count + 2;
|
||
};
|
||
CNode.prototype.isSpaceText = function() {
|
||
return this.element instanceof CTextElement && this.element.isSpaceText();
|
||
};
|
||
CNode.prototype.resolveTypesWithPartner = function (comparison) {
|
||
if (this.partner && this.element instanceof CTextElement) {
|
||
resolveTypesWithPartner([this], comparison);
|
||
}
|
||
};
|
||
CNode.prototype.getElement = function()
|
||
{
|
||
return this.element;
|
||
};
|
||
CNode.prototype.addBookmark = function (oBookmark, nInsertIndex)
|
||
{
|
||
if (this.element instanceof CTextElement)
|
||
{
|
||
this.element.addBookmark(oBookmark, nInsertIndex);
|
||
}
|
||
};
|
||
CNode.prototype.getLastBookmarks = function ()
|
||
{
|
||
if (this.element instanceof CTextElement)
|
||
{
|
||
return this.element.getLastBookmarks();
|
||
}
|
||
};
|
||
CNode.prototype.getFirstBookmarks = function ()
|
||
{
|
||
if (this.element instanceof CTextElement)
|
||
{
|
||
return this.element.getFirstBookmarks();
|
||
}
|
||
};
|
||
CNode.prototype.addComment = function (oBookmark, nInsertIndex)
|
||
{
|
||
if (this.element instanceof CTextElement)
|
||
{
|
||
this.element.addComment(oBookmark, nInsertIndex);
|
||
}
|
||
};
|
||
CNode.prototype.getLastComments = function ()
|
||
{
|
||
if (this.element instanceof CTextElement)
|
||
{
|
||
return this.element.getLastComments();
|
||
}
|
||
};
|
||
CNode.prototype.getFirstComments = function ()
|
||
{
|
||
if (this.element instanceof CTextElement)
|
||
{
|
||
return this.element.getFirstComments();
|
||
}
|
||
};
|
||
// debug method
|
||
CNode.prototype.getText = function()
|
||
{
|
||
return this.element.getText();
|
||
};
|
||
|
||
CNode.prototype.getContentElement = function (isStart)
|
||
{
|
||
const element = this.element;
|
||
if (isStart)
|
||
{
|
||
if (element.firstRun)
|
||
{
|
||
return element.firstRun;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (element.lastRun)
|
||
{
|
||
return element.lastRun;
|
||
}
|
||
}
|
||
if (element instanceof CCommentElement)
|
||
{
|
||
return element.element;
|
||
}
|
||
return element;
|
||
};
|
||
CNode.prototype.cleanEndOfInsert = function (aContentToInsert, oChange, comparison) {
|
||
const oNode = oChange.insert[oChange.insert.length - 1];
|
||
const oLastText = oNode.element;
|
||
const oEndOfInsertRun = oNode.getContentElement();
|
||
const oParentParagraph = (this.partner && this.partner.element) || oEndOfInsertRun.GetParent();
|
||
const applyingParagraph = this.getApplyParagraph(comparison);
|
||
const arrEndBookmarks = oNode.getLastBookmarks();
|
||
if (arrEndBookmarks)
|
||
{
|
||
for (let i = arrEndBookmarks.length - 1; i >= 0; i -= 1)
|
||
{
|
||
this.pushToArrInsertContentWithCopy(aContentToInsert, arrEndBookmarks[i], comparison);
|
||
}
|
||
}
|
||
const arrLastComments = oNode.getLastComments();
|
||
if (arrLastComments)
|
||
{
|
||
for (let i = arrLastComments.length - 1; i >= 0; i -= 1)
|
||
{
|
||
this.pushToArrInsertContentWithCopy(aContentToInsert, arrLastComments[i].element, comparison);
|
||
}
|
||
}
|
||
let k = oParentParagraph.Content.length - 1;
|
||
let lastCheckRun;
|
||
for(k; k > -1; --k)
|
||
{
|
||
// если мы встретили последний ран, где встречается слово
|
||
const oCurrentRun = oParentParagraph.Content[k];
|
||
if(oEndOfInsertRun === oCurrentRun)
|
||
{
|
||
if(oEndOfInsertRun instanceof ParaRun)
|
||
{
|
||
for(let t = oEndOfInsertRun.Content.length - 1; t > -1; --t)
|
||
{
|
||
const oNewRun = this.copyRunWithMockParagraph(oEndOfInsertRun, applyingParagraph.Paragraph || applyingParagraph, comparison);
|
||
//очищаем конец слова, которое нужно вставить
|
||
if(oLastText.elements[oLastText.elements.length - 1] === oEndOfInsertRun.Content[t])
|
||
{
|
||
if(t < oEndOfInsertRun.Content.length - 1)
|
||
{
|
||
lastCheckRun = oNewRun.Split2(t + 1);
|
||
comparison.checkOriginalAndSplitRun(oNewRun, lastCheckRun);
|
||
let reviewInfo = oEndOfInsertRun.GetReviewInfo();
|
||
this.setCommonReviewTypeWithInfo(lastCheckRun, reviewInfo ? reviewInfo.Copy() : undefined);
|
||
}
|
||
this.pushToArrInsertContent(aContentToInsert, oNewRun, comparison);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
//целиком вставим то, что встретили
|
||
this.pushToArrInsertContentWithCopy(aContentToInsert, oEndOfInsertRun, comparison);
|
||
}
|
||
break;
|
||
}
|
||
else if(oLastText === oCurrentRun)
|
||
{
|
||
//целиком вставим то, что встретили
|
||
this.pushToArrInsertContentWithCopy(aContentToInsert, oCurrentRun, comparison);
|
||
break;
|
||
}
|
||
}
|
||
return k;
|
||
};
|
||
// comparison need for extends
|
||
CNode.prototype.pushToArrInsertContent = function (aContentToInsert, elem, comparison) {
|
||
aContentToInsert.push(elem);
|
||
};
|
||
|
||
CNode.prototype.pushToArrInsertContentWithCopy = function (aContentToInsert, elem, comparison) {
|
||
if (elem instanceof AscCommon.ParaComment && !comparison.options.comments) {
|
||
return;
|
||
}
|
||
const elemCopy = elem.Copy(false, comparison.copyPr);
|
||
this.pushToArrInsertContent(aContentToInsert, elemCopy, comparison);
|
||
if (elem instanceof AscCommon.ParaComment)
|
||
{
|
||
comparison.oCommentManager.pushToArrInsertContentFromMerge(elem, aContentToInsert);
|
||
}
|
||
};
|
||
|
||
CNode.prototype.cleanStartOfInsertSameRun = function (oNewRun, oChange) {
|
||
const oNode = oChange.insert[0];
|
||
const oFirstText = oNode.element;
|
||
if(oNewRun)
|
||
{
|
||
if((oNewRun instanceof ParaRun) && oFirstText.firstRun)
|
||
{
|
||
for(let t = 0; t < oFirstText.firstRun.Content.length; ++t)
|
||
{
|
||
// удаляем начало рана до изменения в слове
|
||
if(oFirstText.elements[0] === oFirstText.firstRun.Content[t])
|
||
{
|
||
oNewRun.Remove_FromContent(0, t, false);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
};
|
||
|
||
CNode.prototype.copyRunWithMockParagraph = function (oRun, mockParagraph, comparison) {
|
||
const oTempParagraph = oRun.Paragraph;
|
||
oRun.Paragraph = mockParagraph;
|
||
const oNewRun = oRun.Copy2(comparison.copyPr);
|
||
oRun.Paragraph = oTempParagraph;
|
||
|
||
return oNewRun;
|
||
};
|
||
|
||
CNode.prototype.cleanStartOfInsertDifferentRun = function (aContentToInsert, posOfLastInsertRun, oChange, comparison) {
|
||
const oFirstNode = oChange.insert[0];
|
||
const oLastNode = oChange.insert[oChange.insert.length - 1];
|
||
const oFirstText = oFirstNode.element;
|
||
const oFirstElement = oFirstNode.getContentElement(true);
|
||
const oLastText = oLastNode.element;
|
||
const oLastElement = oLastNode.getContentElement();
|
||
const applyingParagraph = this.getApplyParagraph(comparison);
|
||
|
||
const oParentParagraph = (this.partner && this.partner.element) || oLastElement.GetParent();
|
||
let k = posOfLastInsertRun;
|
||
let lastCheckRun;
|
||
for(k -= 1; k > -1; --k)
|
||
{
|
||
const oCurRun = oParentParagraph.Content[k];
|
||
// Пока не дошли до первого рана слова, закидываем его на добавление
|
||
if(oCurRun !== oFirstElement)
|
||
{
|
||
this.pushToArrInsertContentWithCopy(aContentToInsert, oCurRun, comparison);
|
||
}
|
||
else
|
||
{
|
||
if (oCurRun instanceof AscCommonWord.ParaRun)
|
||
{
|
||
for(let t = 0; t < oCurRun.Content.length; ++t)
|
||
{
|
||
if(oFirstText.elements[0] === oCurRun.Content[t])
|
||
{
|
||
let oNewRun;
|
||
if(oLastText.lastRun === oFirstText.firstRun)
|
||
{
|
||
lastCheckRun = aContentToInsert[0];
|
||
oNewRun = lastCheckRun.Split2(t);
|
||
comparison.checkOriginalAndSplitRun(lastCheckRun, oNewRun);
|
||
}
|
||
else
|
||
{
|
||
lastCheckRun = this.copyRunWithMockParagraph(oCurRun, applyingParagraph.Paragraph || applyingParagraph, comparison);
|
||
oNewRun = lastCheckRun.Split2(t);
|
||
comparison.checkOriginalAndSplitRun(lastCheckRun, oNewRun);
|
||
this.pushToArrInsertContent(aContentToInsert, oNewRun, comparison);
|
||
let reviewInfo = oCurRun.GetReviewInfo();
|
||
this.setCommonReviewTypeWithInfo(lastCheckRun, reviewInfo ? reviewInfo.Copy() : undefined);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
this.pushToArrInsertContentWithCopy(aContentToInsert, oCurRun, comparison);
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
};
|
||
CNode.prototype.checkCommentsFromInsert = function (oChange, comparison)
|
||
{
|
||
const mapRevisedComments = {};
|
||
const arrRevisedComments = [];
|
||
for (let i = 0; i < oChange.insert.length; i += 1)
|
||
{
|
||
const oTextElement = oChange.insert[i].element;
|
||
if (oTextElement.comments)
|
||
{
|
||
for (let sInsertIndex in oTextElement.comments)
|
||
{
|
||
const arrComments = oTextElement.comments[sInsertIndex];
|
||
for (let j = 0; j < arrComments.length; j += 1)
|
||
{
|
||
const oParaComment = arrComments[j].element;
|
||
if (oParaComment.IsCommentStart())
|
||
{
|
||
delete mapRevisedComments[oParaComment.GetCommentId()];
|
||
}
|
||
else
|
||
{
|
||
mapRevisedComments[oParaComment.GetCommentId()] = arrComments[j];
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
for (let sCommentId in mapRevisedComments)
|
||
{
|
||
arrRevisedComments.push(mapRevisedComments[sCommentId]);
|
||
}
|
||
let oCheckCommentNode;
|
||
if (oChange.remove.length)
|
||
{
|
||
oCheckCommentNode = oChange.remove[oChange.remove.length - 1];
|
||
|
||
}
|
||
else
|
||
{
|
||
oCheckCommentNode = this.children[oChange.anchor.index - 1];
|
||
}
|
||
if (oCheckCommentNode && oCheckCommentNode.element.comments)
|
||
{
|
||
const nLastIndex = oCheckCommentNode.element.elements.length;
|
||
const arrMainComments = oCheckCommentNode.element.comments[nLastIndex];
|
||
comparison.oCommentManager.checkComments(arrMainComments, arrRevisedComments, arrMainComments);
|
||
}
|
||
};
|
||
CNode.prototype.getArrOfInsertsFromChanges = function (oChange, comparison) {
|
||
const aContentToInsert = [];
|
||
this.checkCommentsFromInsert(oChange, comparison);
|
||
|
||
if(oChange.insert.length > 0)
|
||
{
|
||
const oFirstNode = oChange.insert[0];
|
||
const oLastNode = oChange.insert[oChange.insert.length - 1];
|
||
const oFirstText = oFirstNode.getContentElement(true);
|
||
const oLastText = oLastNode.getContentElement();
|
||
|
||
const posLastRunOfInsert = this.cleanEndOfInsert(aContentToInsert, oChange, comparison);
|
||
|
||
// изменения находятся внутри одного рана или это один и тот же элемент
|
||
if(oFirstText === oLastText)
|
||
{
|
||
this.cleanStartOfInsertSameRun(aContentToInsert[aContentToInsert.length - 1], oChange);
|
||
}
|
||
else
|
||
{
|
||
this.cleanStartOfInsertDifferentRun(aContentToInsert, posLastRunOfInsert, oChange, comparison);
|
||
}
|
||
|
||
const arrStartBookmarks = oFirstNode.getFirstBookmarks();
|
||
if (arrStartBookmarks)
|
||
{
|
||
for (let i = arrStartBookmarks.length - 1; i >= 0; i -= 1)
|
||
this.pushToArrInsertContentWithCopy(aContentToInsert, arrStartBookmarks[i], comparison);
|
||
}
|
||
const arrStartComments = oFirstNode.getFirstComments();
|
||
if (arrStartComments)
|
||
{
|
||
for (let i = arrStartComments.length - 1; i >= 0; i -= 1)
|
||
this.pushToArrInsertContentWithCopy(aContentToInsert, arrStartComments[i].element, comparison);
|
||
}
|
||
}
|
||
return aContentToInsert;
|
||
};
|
||
|
||
|
||
CNode.prototype.applyInsertsToParagraph = function (comparison, aContentToInsert, oChange) {
|
||
if (oChange.remove.length > 0 && !comparison.isSkipWhitespaces(oChange.remove)) {
|
||
this.applyInsertsToParagraphsWithRemove(comparison, aContentToInsert, oChange);
|
||
} else {
|
||
this.applyInsertsToParagraphsWithoutRemove(comparison, aContentToInsert, oChange);
|
||
}
|
||
};
|
||
|
||
CNode.prototype.applyInsertsToParagraphsWithoutRemove = function (comparison, aContentToInsert, oChange) {
|
||
const applyingParagraph = this.getApplyParagraph(comparison);
|
||
if(aContentToInsert.length > 0)
|
||
{
|
||
const index = oChange.anchor.index;
|
||
const oChildNode = this.children[index];
|
||
if(oChildNode)
|
||
{
|
||
let oFirstText = oChildNode.element;
|
||
if (oFirstText.lastSwitchElement)
|
||
{
|
||
oFirstText = oFirstText.lastSwitchElement;
|
||
}
|
||
else if (oFirstText instanceof CCommentElement)
|
||
{
|
||
oFirstText = oFirstText.element;
|
||
}
|
||
|
||
for(let j = 0; j < applyingParagraph.Content.length; ++j)
|
||
{
|
||
if(Array.isArray(applyingParagraph.Content))
|
||
{
|
||
const oCurRun = applyingParagraph.Content[j];
|
||
// если совпали ран, после которого нужно вставлять и ран из цикла
|
||
if(oFirstText === oCurRun)
|
||
{
|
||
this.applyInsert(aContentToInsert, [], j, comparison);
|
||
return true;
|
||
}
|
||
// иначе надо посмотреть, возможно стоит вставлять элементы не после рана, а после конкретного элемента и текущий ран из цикла нужно засплитить
|
||
else if(Array.isArray(oCurRun.Content) && Array.isArray(oFirstText.elements))
|
||
{
|
||
let k = 0;
|
||
for(k; k < oCurRun.Content.length; ++k)
|
||
{
|
||
// если элементы совпали, значит, мы нашли место вставки
|
||
if(oFirstText.elements[0] === oCurRun.Content[k])
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
let bFind = false;
|
||
// проверим, не дошли ли мы просто до конца массива, ничего не встретив
|
||
if(k === oCurRun.Content.length)
|
||
{
|
||
if(oFirstText.firstRun === oCurRun)
|
||
{
|
||
k = 0;
|
||
bFind = true;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
bFind = true;
|
||
}
|
||
if(k <= oCurRun.Content.length && bFind)
|
||
{
|
||
const oNewRun = oCurRun.Split2(k, applyingParagraph, j);
|
||
comparison.checkOriginalAndSplitRun(oCurRun, oNewRun)
|
||
//TODO: think about it
|
||
this.applyInsert(aContentToInsert, [], j + 1, comparison);
|
||
return true;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return false;
|
||
};
|
||
|
||
CNode.prototype.getApplyParagraph = function (comparison) {
|
||
return comparison.parentParagraph || this.element;
|
||
};
|
||
|
||
CNode.prototype.setCommonReviewTypeWithInfo = function (element, info) {
|
||
element.SetReviewTypeWithInfo(reviewtype_Common, info);
|
||
};
|
||
|
||
CNode.prototype.prepareEndOfRemoveChange = function (oChange, comparison, arrSetRemove) {
|
||
const oApplyParagraph = this.getApplyParagraph(comparison);
|
||
const oNode = oChange.remove[oChange.remove.length - 1];
|
||
const oLastText = oNode.element;
|
||
const oEndOfRemoveRun = oNode.getContentElement();
|
||
let k = oApplyParagraph.Content.length - 1;
|
||
let nInsertPosition = -1;
|
||
|
||
for(k; k > -1; --k)
|
||
{
|
||
const oCurRun = oApplyParagraph.Content[k];
|
||
if(oCurRun === oEndOfRemoveRun)
|
||
{
|
||
if(oLastText instanceof CTextElement)
|
||
{
|
||
const arrComments = oLastText.comments[oLastText.elements.length];
|
||
arrSetRemove.push.apply(arrSetRemove, arrComments)
|
||
|
||
let t = oEndOfRemoveRun.Content.length - 1;
|
||
for(t; t > -1; t--)
|
||
{
|
||
if(oEndOfRemoveRun.Content[t] === oLastText.elements[oLastText.elements.length - 1])
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
if(t > -1)
|
||
{
|
||
nInsertPosition = k + 1;
|
||
const oNewRun = oEndOfRemoveRun.Split2(t + 1, oApplyParagraph, k);
|
||
comparison.checkOriginalAndSplitRun(oEndOfRemoveRun, oNewRun);
|
||
let reviewInfo = oEndOfRemoveRun.GetReviewInfo();
|
||
this.setCommonReviewTypeWithInfo(oNewRun, reviewInfo ? reviewInfo.Copy() : undefined);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
nInsertPosition = k + 1;
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
return {posLastRunInContent: k, nInsertPosition: nInsertPosition };
|
||
};
|
||
|
||
CNode.prototype.setReviewTypeForRemoveChanges = function (comparison, oChange, posLastRunInContent, nInsertPosition, arrSetRemoveReviewType) {
|
||
const oApplyParagraph = this.getApplyParagraph(comparison);
|
||
const oNode = oChange.remove[0];
|
||
const oFirstText = oNode.element;
|
||
const oStartOfRemoveRun = oNode.getContentElement(true);
|
||
let k = posLastRunInContent;
|
||
for(k; k > -1; --k)
|
||
{
|
||
const oChildElement = oApplyParagraph.Content[k];
|
||
if(!(oChildElement === oStartOfRemoveRun))
|
||
{
|
||
arrSetRemoveReviewType.push(oChildElement);
|
||
}
|
||
else
|
||
{
|
||
if(oChildElement instanceof ParaRun)
|
||
{
|
||
let t = 0;
|
||
for(t; t < oChildElement.Content.length; t++)
|
||
{
|
||
if(oChildElement.Content[t] === oFirstText.elements[0])
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
t = Math.min(Math.max(t, 0), oChildElement.Content.length - 1);
|
||
if(t > 0)
|
||
{
|
||
const oNewRun = oChildElement.Split2(t, oApplyParagraph, k);
|
||
comparison.checkOriginalAndSplitRun(oChildElement, oNewRun);
|
||
arrSetRemoveReviewType.push(oNewRun);
|
||
nInsertPosition++;
|
||
}
|
||
else
|
||
{
|
||
arrSetRemoveReviewType.push(oChildElement);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
arrSetRemoveReviewType.push(oChildElement);
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
return nInsertPosition;
|
||
};
|
||
|
||
CNode.prototype.applyInsert = function (arrToInsert, arrToRemove, nInsertPosition, comparison, options) {
|
||
for (let i = 0; i < arrToRemove.length; i += 1) {
|
||
comparison.setRemoveReviewType(arrToRemove[i]);
|
||
}
|
||
this.insertContentAfterRemoveChanges(arrToInsert, nInsertPosition, comparison, options);
|
||
};
|
||
|
||
CNode.prototype.applyInsertsToParagraphsWithRemove = function (comparison, aContentToInsert, oChange) {
|
||
const arrSetRemoveReviewType = [];
|
||
const infoAboutEndOfRemoveChange = this.prepareEndOfRemoveChange(oChange, comparison, arrSetRemoveReviewType);
|
||
const posLastRunInContent = infoAboutEndOfRemoveChange.posLastRunInContent;
|
||
|
||
let nInsertPosition = infoAboutEndOfRemoveChange.nInsertPosition;
|
||
nInsertPosition = this.setReviewTypeForRemoveChanges(comparison, oChange, posLastRunInContent, nInsertPosition, arrSetRemoveReviewType);
|
||
if (!comparison.options.words && !comparison.isWordsByOneSymbol && oChange.insert.length === 1 && oChange.remove.length === 1) {
|
||
aContentToInsert.reverse();
|
||
arrSetRemoveReviewType.reverse();
|
||
comparison.resolveConflicts(aContentToInsert, arrSetRemoveReviewType, this.getApplyParagraph(comparison), true);
|
||
} else {
|
||
this.applyInsert(aContentToInsert, arrSetRemoveReviewType, nInsertPosition, comparison, {needReverse: true});
|
||
}
|
||
};
|
||
|
||
CNode.prototype.insertContentAfterRemoveChanges = function (aContentToInsert, nInsertPosition, comparison) {
|
||
const oElement = this.getApplyParagraph(comparison);
|
||
if(nInsertPosition > -1)
|
||
{
|
||
for (let t = 0; t < aContentToInsert.length; t += 1) {
|
||
if(comparison.isElementForAdd(aContentToInsert[t]))
|
||
{
|
||
oElement.AddToContent(nInsertPosition, aContentToInsert[t]);
|
||
}
|
||
}
|
||
}
|
||
};
|
||
|
||
CNode.prototype.getNeighbors = function()
|
||
{
|
||
return [this.getLeftNeighbor(), this.getRightNeighbor()];
|
||
};
|
||
CNode.prototype.getLeftNeighbor = function () {
|
||
if(!this.par) {
|
||
return;
|
||
}
|
||
for (let i = this.childidx - 1; i >= 0; i -= 1) {
|
||
if (this.par.children[i].element instanceof CTextElement) {
|
||
return this.par.children[i];
|
||
}
|
||
}
|
||
};
|
||
CNode.prototype.getRightNeighbor = function () {
|
||
if(!this.par) {
|
||
return;
|
||
}
|
||
for (let i = this.childidx + 1; i < this.par.children.length; i += 1) {
|
||
if (this.par.children[i].element instanceof CTextElement) {
|
||
return this.par.children[i];
|
||
}
|
||
}
|
||
};
|
||
|
||
CNode.prototype.print = function()
|
||
{
|
||
if(this.element.print)
|
||
{
|
||
this.element.print();
|
||
}
|
||
};
|
||
CNode.prototype.getDepth = function()
|
||
{
|
||
return this.depth;
|
||
};
|
||
CNode.prototype.addChange = function(oOperation)
|
||
{
|
||
return this.changes.push(oOperation);
|
||
};
|
||
CNode.prototype.equals = function(oNode, oComparison)
|
||
{
|
||
if(this.depth === oNode.depth)
|
||
{
|
||
const oParent1 = this.par;
|
||
const oParent2 = oNode.par;
|
||
if(oParent1 && !oParent2 || !oParent1 && oParent2)
|
||
{
|
||
return false;
|
||
}
|
||
if(oParent1)
|
||
{
|
||
if(!oParent1.equals(oParent2))
|
||
{
|
||
return false;
|
||
}
|
||
}
|
||
return this.privateCompareElements(oNode, true, oComparison);
|
||
}
|
||
return false;
|
||
};
|
||
|
||
CNode.prototype.privateCompareElements = function(oNode, bCheckNeighbors, oComparison)
|
||
{
|
||
const oElement1 = this.element;
|
||
const oElement2 = oNode.element;
|
||
if(oElement1.constructor === oElement2.constructor)
|
||
{
|
||
if(typeof oElement1.Value === "number")
|
||
{
|
||
return oElement1.Value === oElement2.Value;
|
||
}
|
||
if(oElement1 instanceof CTextElement)
|
||
{
|
||
if(bCheckNeighbors && oElement1.isSpaceText() && oElement2.isSpaceText())
|
||
{
|
||
if (!oElement1.compareReviewElements(oElement2))
|
||
{
|
||
return false;
|
||
}
|
||
const aNeighbors1 = this.getNeighbors();
|
||
const aNeighbors2 = oNode.getNeighbors();
|
||
if(!aNeighbors1[0] && !aNeighbors2[0] || !aNeighbors1[1] && !aNeighbors2[1])
|
||
{
|
||
return true;
|
||
}
|
||
if(aNeighbors1[0] && aNeighbors2[0])
|
||
{
|
||
if(aNeighbors1[0].privateCompareElements(aNeighbors2[0], false, oComparison))
|
||
{
|
||
return true;
|
||
}
|
||
}
|
||
if(aNeighbors1[1] && aNeighbors2[1])
|
||
{
|
||
if(aNeighbors1[1].privateCompareElements(aNeighbors2[1], false, oComparison))
|
||
{
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
else
|
||
{
|
||
return oElement1.equals(oElement2, bCheckNeighbors, oComparison);
|
||
}
|
||
}
|
||
if (oElement1 instanceof AscCommon.CParaRevisionMove)
|
||
{
|
||
return false;
|
||
}
|
||
if(oElement1 instanceof AscCommonWord.CTable)
|
||
{
|
||
if(oElement1.TableGrid.length !== oElement2.TableGrid.length)
|
||
{
|
||
return false;
|
||
}
|
||
}
|
||
if(oElement1 instanceof AscCommonWord.CTableRow)
|
||
{
|
||
if(oElement1.Content.length !== oElement2.Content.length)
|
||
{
|
||
return false;
|
||
}
|
||
}
|
||
if(oElement1 instanceof AscCommonWord.CDocumentContent && oElement1.Parent instanceof AscCommonWord.CTableCell)
|
||
{
|
||
if(!oElement2.Parent)
|
||
{
|
||
return false;
|
||
}
|
||
if(oElement1.Parent.Index !== oElement2.Parent.Index)
|
||
{
|
||
return false;
|
||
}
|
||
}
|
||
return !(oElement1 instanceof AscCommonWord.ParaMath);
|
||
}
|
||
return false;
|
||
};
|
||
CNode.prototype.isLeaf = function()
|
||
{
|
||
return this.children.length === 0;
|
||
};
|
||
|
||
CNode.prototype.addChildNode = function(oNode)
|
||
{
|
||
oNode.childidx = this.children.length;
|
||
this.children.push(oNode);
|
||
oNode.depth = this.depth + 1;
|
||
oNode.par = this;
|
||
};
|
||
|
||
CNode.prototype.isStructure = function()
|
||
{
|
||
return !this.isLeaf();
|
||
};
|
||
|
||
|
||
CNode.prototype.forEachDescendant = function(callback, T) {
|
||
this.children.forEach(function(node) {
|
||
node.forEach(callback, T);
|
||
});
|
||
};
|
||
CNode.prototype.forEach = function(callback, T) {
|
||
callback.call(T, this);
|
||
this.children.forEach(function(node) {
|
||
node.forEach(callback, T);
|
||
});
|
||
};
|
||
|
||
CNode.prototype.forEachRight = function (callback, T) {
|
||
const arrNodes = [];
|
||
this.forEach(function (oNode) {
|
||
arrNodes.push(oNode);
|
||
});
|
||
for (let i = arrNodes.length - 1; i > -1; i -= 1) {
|
||
callback.call(T, arrNodes[i]);
|
||
}
|
||
};
|
||
|
||
CNode.prototype.setPartner = function (oNode) {
|
||
this.partner = oNode;
|
||
oNode.partner = this;
|
||
return null;
|
||
};
|
||
|
||
CNode.prototype.isComparable = function (oNode) {
|
||
if(this.element && oNode.element && this.element.constructor === oNode.element.constructor)
|
||
{
|
||
if(this.element instanceof CTable)
|
||
{
|
||
if(this.element.TableGrid.length !== oNode.element.TableGrid.length)
|
||
{
|
||
return false;
|
||
}
|
||
}
|
||
if(this.element instanceof AscWord.Paragraph)
|
||
{
|
||
if(!this.element.SectPr && oNode.element.SectPr)
|
||
{
|
||
return false;
|
||
}
|
||
if(!oNode.element.SectPr && this.element.SectPr)
|
||
{
|
||
return false;
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
return false;
|
||
};
|
||
|
||
|
||
function CCommentElement(oComment, oParaComment)
|
||
{
|
||
this.element = oParaComment;
|
||
if (oComment)
|
||
{
|
||
this.data = oComment.Data;
|
||
}
|
||
}
|
||
CCommentElement.prototype.getQuoteText = function ()
|
||
{
|
||
if (this.data)
|
||
{
|
||
return this.data.Get_QuoteText();
|
||
}
|
||
return '';
|
||
};
|
||
CCommentElement.prototype.getCommentId = function ()
|
||
{
|
||
return this.element.GetCommentId();
|
||
};
|
||
CCommentElement.prototype.getFullMergeComments = function (oAnotherElement)
|
||
{
|
||
const arrMainAnswers = this.getAnswers();
|
||
const arrAnotherAnswers = oAnotherElement.getAnswers();
|
||
const length = Math.min(arrMainAnswers.length, arrAnotherAnswers.length);
|
||
for (let i = 0; i < length; i++)
|
||
{
|
||
const sMainAnswer = arrMainAnswers[i].Get_Text();
|
||
const sAnotherAnswer = arrAnotherAnswers[i].Get_Text();
|
||
if (sMainAnswer !== sAnotherAnswer)
|
||
{
|
||
return null;
|
||
}
|
||
}
|
||
return Math.abs(arrMainAnswers.length - arrAnotherAnswers.length);
|
||
};
|
||
CCommentElement.prototype.getAnswerMap = function ()
|
||
{
|
||
const oAnswerMap = {};
|
||
const arrAnswers = this.getAnswers();
|
||
for (let i = 0; i < arrAnswers.length; i += 1)
|
||
{
|
||
const oAnswer = arrAnswers[i];
|
||
const sText = oAnswer.Get_Text();
|
||
if (!oAnswerMap[sText])
|
||
{
|
||
oAnswerMap[sText] = [];
|
||
}
|
||
oAnswerMap[sText].push(oAnswer);
|
||
}
|
||
return oAnswerMap;
|
||
};
|
||
CCommentElement.prototype.getPartMergeComments = function (oAnotherElement)
|
||
{
|
||
let nDifference = 0;
|
||
const oMainAnswerMap = this.getAnswerMap();
|
||
const oRevisedAnswerMap = oAnotherElement.getAnswerMap();
|
||
let arrData = [];
|
||
for (let sCommentText in oMainAnswerMap)
|
||
{
|
||
const arrMainAnswers = oMainAnswerMap[sCommentText];
|
||
if (oRevisedAnswerMap[sCommentText])
|
||
{
|
||
const nDeleteCount = oRevisedAnswerMap[sCommentText].length;
|
||
nDifference += Math.abs(arrMainAnswers.length - nDeleteCount);
|
||
arrMainAnswers.splice(0, nDeleteCount);
|
||
arrData = arrData.concat(arrMainAnswers);
|
||
}
|
||
else
|
||
{
|
||
arrData = arrData.concat(arrMainAnswers);
|
||
nDifference += arrMainAnswers.length;
|
||
}
|
||
}
|
||
for (let sCommentText in oRevisedAnswerMap)
|
||
{
|
||
if (!oMainAnswerMap[sCommentText])
|
||
{
|
||
nDifference += oRevisedAnswerMap[sCommentText].length;
|
||
}
|
||
}
|
||
arrData.sort(function (a, b)
|
||
{
|
||
return parseInt(a.m_sOOTime, 10) - parseInt(b.m_sOOTime, 10);
|
||
});
|
||
return {arrData: arrData, difference: nDifference};
|
||
};
|
||
|
||
CCommentElement.prototype.getDifference = function (oAnotherElement)
|
||
{
|
||
const sText = this.getText();
|
||
const sAnotherText = oAnotherElement.getText();
|
||
if (sText !== sAnotherText)
|
||
{
|
||
return null;
|
||
}
|
||
const oRes = {mainElement: this, anotherElement: oAnotherElement, quoteDifference: this.getQuoteDifference(oAnotherElement)};
|
||
const nCommentDifference = this.getFullMergeComments(oAnotherElement);
|
||
if (nCommentDifference !== null)
|
||
{
|
||
oRes.commentDifference = nCommentDifference;
|
||
return oRes;
|
||
}
|
||
const oPartDifference = this.getPartMergeComments(oAnotherElement);
|
||
oRes.commentDifference = oPartDifference.difference;
|
||
oRes.arrData = oPartDifference.arrData;
|
||
return oRes;
|
||
};
|
||
CCommentElement.prototype.getQuoteDifference = function (oAnotherElement)
|
||
{
|
||
const sMainQuoteText = this.getQuoteText();
|
||
const sAnotherQuoteText = oAnotherElement.getQuoteText();
|
||
|
||
return Math.abs(sMainQuoteText.length - sAnotherQuoteText.length);
|
||
};
|
||
CCommentElement.prototype.getText = function ()
|
||
{
|
||
if (this.data)
|
||
{
|
||
return this.data.Get_Text();
|
||
}
|
||
return '';
|
||
};
|
||
CCommentElement.prototype.getAnswers = function ()
|
||
{
|
||
if (this.data)
|
||
{
|
||
return this.data.m_aReplies;
|
||
}
|
||
return [];
|
||
};
|
||
function CTextElement()
|
||
{
|
||
this.elements = [];
|
||
this.firstRun = null;
|
||
this.lastRun = null;
|
||
this.bookmarks = {};
|
||
this.comments = {};
|
||
this.lastSwitchElement = null;
|
||
}
|
||
CTextElement.prototype.isWordBeginWith = function (oOther)
|
||
{
|
||
if (this.elements.length < oOther.elements.length) {
|
||
return false;
|
||
}
|
||
|
||
for (let i = 0; i < oOther.elements.length; i += 1)
|
||
{
|
||
const oMainElement = this.elements[i];
|
||
const oSecondaryElement = oOther.elements[i];
|
||
if (typeof oMainElement.Value !== 'number' || typeof oSecondaryElement.Value !== 'number')
|
||
{
|
||
return false;
|
||
} else if (oMainElement.Value !== oSecondaryElement.Value) {
|
||
return false;
|
||
}
|
||
}
|
||
return true;
|
||
};
|
||
CTextElement.prototype.isWordEndWith = function (oOther)
|
||
{
|
||
if (this.elements.length < oOther.elements.length) {
|
||
return false;
|
||
}
|
||
|
||
for (let i = 0; i < oOther.elements.length; i += 1)
|
||
{
|
||
const oMainElement = this.elements[this.elements.length - 1 - i];
|
||
const oSecondaryElement = oOther.elements[oOther.elements.length - 1 - i];
|
||
if (typeof oMainElement.Value !== 'number' || typeof oSecondaryElement.Value !== 'number')
|
||
{
|
||
return false;
|
||
} else if (oMainElement.Value !== oSecondaryElement.Value) {
|
||
return false;
|
||
}
|
||
}
|
||
return true;
|
||
};
|
||
CTextElement.prototype.getSortedInsertIndexesFromMap = function (arrLabels)
|
||
{
|
||
return (Object.keys(arrLabels).map(function (e) {return parseInt(e, 10);})
|
||
.sort(function (a, b) {return b - a;}));
|
||
};
|
||
CTextElement.prototype.compareReviewElements = function (oAnotherElement)
|
||
{
|
||
return true;
|
||
};
|
||
CTextElement.prototype.getBookmarkInsertIndexes = function ()
|
||
{
|
||
return this.getSortedInsertIndexesFromMap(this.bookmarks);
|
||
};
|
||
CTextElement.prototype.getCommentInsertIndexes = function ()
|
||
{
|
||
return this.getSortedInsertIndexesFromMap(this.comments);
|
||
};
|
||
CTextElement.prototype.getLastBookmarks = function ()
|
||
{
|
||
return this.bookmarks[this.elements.length];
|
||
};
|
||
CTextElement.prototype.getFirstBookmarks = function ()
|
||
{
|
||
return this.bookmarks[0];
|
||
};
|
||
CTextElement.prototype.getLastComments = function ()
|
||
{
|
||
return this.comments[this.elements.length];
|
||
};
|
||
CTextElement.prototype.getFirstComments = function ()
|
||
{
|
||
return this.comments[0];
|
||
};
|
||
CTextElement.prototype.addBookmark = function (oBookmark, nInsertIndex)
|
||
{
|
||
if (!this.bookmarks[nInsertIndex])
|
||
{
|
||
this.bookmarks[nInsertIndex] = [];
|
||
}
|
||
this.bookmarks[nInsertIndex].push(oBookmark);
|
||
};
|
||
CTextElement.prototype.addComment = function (oComment, nInsertIndex)
|
||
{
|
||
if (!this.comments[nInsertIndex])
|
||
{
|
||
this.comments[nInsertIndex] = [];
|
||
}
|
||
this.comments[nInsertIndex].push(oComment);
|
||
};
|
||
CTextElement.prototype.getPosOfStart = function () {
|
||
const startElement = this.elements[0];
|
||
return this.firstRun.GetElementPosition(startElement);
|
||
};
|
||
|
||
CTextElement.prototype.addToElements = function (element, options) {
|
||
this.elements.push(element);
|
||
};
|
||
|
||
CTextElement.prototype.getPosOfEnd = function () {
|
||
const endElement = this.elements[this.elements.length - 1];
|
||
return this.lastRun.GetElementPosition(endElement);
|
||
};
|
||
|
||
CTextElement.prototype.getElement = function (idx) {
|
||
return this.elements[idx];
|
||
};
|
||
CTextElement.prototype.checkRemoveReviewType = function () {
|
||
return false;
|
||
};
|
||
CTextElement.prototype.checkUncompletedWords = function (other) {
|
||
if (this.elements.length === other.elements.length) {
|
||
return false;
|
||
}
|
||
let oMainTextElement;
|
||
let oSecondaryTextElement;
|
||
if (this.elements.length > other.elements.length) {
|
||
oMainTextElement = this;
|
||
oSecondaryTextElement = other;
|
||
}
|
||
else {
|
||
oMainTextElement = other;
|
||
oSecondaryTextElement = this;
|
||
}
|
||
const nEndIndex = oSecondaryTextElement.elements.length - 1;
|
||
const oEndElement = oMainTextElement.elements[nEndIndex];
|
||
if (oMainTextElement.isWordBeginWith(oSecondaryTextElement)) {
|
||
return oMainTextElement.checkRemoveReviewType(nEndIndex) || AscCommon.isEastAsianScript(oEndElement.Value);
|
||
}
|
||
|
||
const nStartIndex = oMainTextElement.elements.length - oSecondaryTextElement.elements.length;
|
||
const oStartElement = oMainTextElement.elements[nStartIndex];
|
||
if (oMainTextElement.isWordEndWith(oSecondaryTextElement)) {
|
||
return oMainTextElement.checkRemoveReviewType(nStartIndex) || AscCommon.isEastAsianScript(oStartElement.Value);
|
||
}
|
||
return false;
|
||
};
|
||
CTextElement.prototype._equals = function (other, bNeedCheckReview, oComparison)
|
||
{
|
||
if(this.elements.length !== other.elements.length)
|
||
{
|
||
return false;
|
||
}
|
||
for(let i = 0; i < this.elements.length; ++i)
|
||
{
|
||
const oElement = this.getElement(i);
|
||
const oOtherElement = other.getElement(i);
|
||
if(oElement.constructor !== oOtherElement.constructor)
|
||
{
|
||
return false;
|
||
}
|
||
if(typeof oElement.Value === "number")
|
||
{
|
||
if (!oComparison.options.caseChanges) {
|
||
if (String.fromCharCode(oElement.Value).toLowerCase() !== String.fromCharCode(oOtherElement.Value).toLowerCase()) {
|
||
return false;
|
||
}
|
||
}
|
||
else if(oElement.Value !== oOtherElement.Value)
|
||
{
|
||
return false;
|
||
}
|
||
}
|
||
if(oElement instanceof ParaDrawing)
|
||
{
|
||
return oElement.IsComparable(oOtherElement)
|
||
}
|
||
}
|
||
return true;
|
||
};
|
||
CTextElement.prototype.equals = function (other, bNeedCheckReview, oComparison) {
|
||
return this._equals(other, bNeedCheckReview, oComparison) || this.checkUncompletedWords(other);
|
||
};
|
||
|
||
CTextElement.prototype.updateHash = function(oHash, oComparison){
|
||
const aCheckArray = [];
|
||
|
||
let bVal = false;
|
||
for(let i = 0; i < this.elements.length; ++i)
|
||
{
|
||
const oElement = this.elements[i];
|
||
if(AscFormat.isRealNumber(oElement.Value))
|
||
{
|
||
aCheckArray.push(oElement.Value);
|
||
bVal = true;
|
||
}
|
||
else
|
||
{
|
||
if (oElement instanceof AscWord.CRunBreak)
|
||
{
|
||
if (oElement.IsLineBreak())
|
||
{
|
||
aCheckArray.push(0x000A);
|
||
}
|
||
else
|
||
{
|
||
aCheckArray.push(0x21A1);
|
||
}
|
||
}
|
||
else if(oElement instanceof AscWord.CRunTab)
|
||
{
|
||
aCheckArray.push(0x0009);
|
||
}
|
||
else if(oElement instanceof AscWord.CRunSpace)
|
||
{
|
||
aCheckArray.push(0x20);
|
||
}
|
||
}
|
||
}
|
||
if(aCheckArray.length > 0)
|
||
{
|
||
oHash.update(aCheckArray, oComparison);
|
||
}
|
||
};
|
||
|
||
CTextElement.prototype.print = function ()
|
||
{
|
||
let sResultString = "";
|
||
for(let i = 0; i < this.elements.length; ++i)
|
||
{
|
||
if(this.elements[i] instanceof AscWord.CRunText)
|
||
{
|
||
sResultString += String.fromCharCode(this.elements[i].GetCodePoint());
|
||
}
|
||
else if(this.elements[i] instanceof AscWord.CRunSpace)
|
||
{
|
||
sResultString += " ";
|
||
}
|
||
}
|
||
//console.log(sResultString);
|
||
};
|
||
CTextElement.prototype.setFirstRun = function (oRun)
|
||
{
|
||
this.firstRun = oRun;
|
||
};
|
||
CTextElement.prototype.setLastRun = function (oRun)
|
||
{
|
||
this.lastRun = oRun;
|
||
};
|
||
|
||
CTextElement.prototype.isSpaceText = function ()
|
||
{
|
||
if(this.elements.length === 1)
|
||
{
|
||
return (this.elements[0].Type === para_Space);
|
||
}
|
||
return false;
|
||
};
|
||
|
||
//debug method
|
||
CTextElement.prototype.getText = function ()
|
||
{
|
||
return {text:this.elements.map(function (e) {return String.fromCharCode(e.Value)}).join(''), isReviewWord: this.isReviewWord, reviewElements:this.reviewElementTypes};
|
||
};
|
||
|
||
CTextElement.prototype.isParaEnd = function ()
|
||
{
|
||
if(this.elements.length === 1)
|
||
{
|
||
return (this.elements[0].Type === para_End);
|
||
}
|
||
return false;
|
||
};
|
||
|
||
CTextElement.prototype.compareFootnotes = function (oTextElement)
|
||
{
|
||
if(this.elements.length === 1 && oTextElement.elements.length === 1
|
||
&& (this.elements[0].Type === para_FootnoteReference && oTextElement.elements[0].Type === para_FootnoteReference
|
||
|| this.elements[0].Type === para_EndnoteReference && oTextElement.elements[0].Type === para_EndnoteReference))
|
||
{
|
||
let oBaseContent = this.elements[0].Footnote;
|
||
let oCompareContent = oTextElement.elements[0].Footnote;
|
||
if(oBaseContent && oCompareContent)
|
||
{
|
||
if(!AscCommon.g_oTableId.Get_ById(oBaseContent.Id))
|
||
{
|
||
const t = oBaseContent;
|
||
oBaseContent = oCompareContent;
|
||
oCompareContent = t;
|
||
}
|
||
return [oBaseContent, oCompareContent];
|
||
}
|
||
}
|
||
return null;
|
||
};
|
||
|
||
CTextElement.prototype.compareDrawings = function(oTextElement)
|
||
{
|
||
if(this.elements.length === 1 && oTextElement.elements.length === 1)
|
||
{
|
||
const oElement = this.elements[0];
|
||
const oOtherElement = oTextElement.elements[0];
|
||
if(oElement.Type === para_Drawing && oOtherElement.Type === para_Drawing)
|
||
{
|
||
if(oElement.IsComparable(oOtherElement))
|
||
{
|
||
if(AscCommon.g_oTableId.Get_ById(oElement.Id))
|
||
{
|
||
return [oElement, oOtherElement];
|
||
}
|
||
else
|
||
{
|
||
return [oOtherElement, oElement];
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return null;
|
||
};
|
||
|
||
function CMatching()
|
||
{
|
||
this.Footnotes = {};
|
||
this.Drawings = {};
|
||
}
|
||
CMatching.prototype.get = function(oNode)
|
||
{
|
||
return oNode.partner;
|
||
};
|
||
|
||
CMatching.prototype.put = function(oNode1, oNode2)
|
||
{
|
||
oNode1.setPartner(oNode2);
|
||
if(oNode1.element instanceof CTextElement)
|
||
{
|
||
const aFootnotes = oNode1.element.compareFootnotes(oNode2.element);
|
||
if(aFootnotes)
|
||
{
|
||
this.Footnotes[aFootnotes[0].Id] = aFootnotes[1];
|
||
}
|
||
else
|
||
{
|
||
const aDrawings = oNode1.element.compareDrawings(oNode2.element);
|
||
if(aDrawings)
|
||
{
|
||
this.Drawings[aDrawings[0].Id] = aDrawings[1];
|
||
}
|
||
}
|
||
}
|
||
};
|
||
|
||
function ComparisonOptions()
|
||
{
|
||
this.textBoxes = true;
|
||
this.tables = true;
|
||
this.words = true;
|
||
this.headersAndFooters = true;
|
||
this.footNotes = true;
|
||
this.caseChanges = true;
|
||
this.formatting = true;
|
||
this.whiteSpace = true;
|
||
this.comments = true;
|
||
|
||
this.insertionsAndDeletions = true;
|
||
// this.moves = true;
|
||
// this.fields = true;
|
||
}
|
||
ComparisonOptions.prototype["getInsertionsAndDeletions"] = ComparisonOptions.prototype.getInsertionsAndDeletions = function(){return this.insertionsAndDeletions;};
|
||
// ComparisonOptions.prototype["getMoves"] = ComparisonOptions.prototype.getMoves = function(){return this.moves;};
|
||
ComparisonOptions.prototype["getComments"] = ComparisonOptions.prototype.getComments = function(){return this.comments;};
|
||
ComparisonOptions.prototype["getFormatting"] = ComparisonOptions.prototype.getFormatting = function(){return this.formatting;};
|
||
ComparisonOptions.prototype["getCaseChanges"] = ComparisonOptions.prototype.getCaseChanges = function(){return this.caseChanges;};
|
||
ComparisonOptions.prototype["getWhiteSpace"] = ComparisonOptions.prototype.getWhiteSpace = function(){return this.whiteSpace;};
|
||
ComparisonOptions.prototype["getTables"] = ComparisonOptions.prototype.getTables = function(){return this.tables;};
|
||
ComparisonOptions.prototype["getHeadersAndFooters"] = ComparisonOptions.prototype.getHeadersAndFooters = function(){return this.headersAndFooters;};
|
||
ComparisonOptions.prototype["getFootNotes"] = ComparisonOptions.prototype.getFootNotes = function(){return this.footNotes;};
|
||
ComparisonOptions.prototype["getTextBoxes"] = ComparisonOptions.prototype.getTextBoxes = function(){return this.textBoxes;};
|
||
// ComparisonOptions.prototype["getFields"] = ComparisonOptions.prototype.getFields = function(){return this.fields;};
|
||
ComparisonOptions.prototype["getWords"] = ComparisonOptions.prototype.getWords = function(){return this.words;};
|
||
|
||
|
||
ComparisonOptions.prototype["putInsertionsAndDeletions"] = ComparisonOptions.prototype.putInsertionsAndDeletions = function(v){this.insertionsAndDeletions = v;};
|
||
// ComparisonOptions.prototype["putMoves"] = ComparisonOptions.prototype.putMoves = function(v){this.moves = v;};
|
||
ComparisonOptions.prototype["putComments"] = ComparisonOptions.prototype.putComments = function(v){this.comments = v;};
|
||
ComparisonOptions.prototype["putFormatting"] = ComparisonOptions.prototype.putFormatting = function(v){this.formatting = v;};
|
||
ComparisonOptions.prototype["putCaseChanges"] = ComparisonOptions.prototype.putCaseChanges = function(v){this.caseChanges = v;};
|
||
ComparisonOptions.prototype["putWhiteSpace"] = ComparisonOptions.prototype.putWhiteSpace = function(v){this.whiteSpace = v;};
|
||
ComparisonOptions.prototype["putTables"] = ComparisonOptions.prototype.putTables = function(v){this.tables = v;};
|
||
ComparisonOptions.prototype["putHeadersAndFooters"] = ComparisonOptions.prototype.putHeadersAndFooters = function(v){this.headersAndFooters = v;};
|
||
ComparisonOptions.prototype["putFootNotes"] = ComparisonOptions.prototype.putFootNotes = function(v){this.footNotes = v;};
|
||
ComparisonOptions.prototype["putTextBoxes"] = ComparisonOptions.prototype.putTextBoxes = function(v){this.textBoxes = v;};
|
||
// ComparisonOptions.prototype["putFields"] = ComparisonOptions.prototype.putFields = function(v){this.fields = v;};
|
||
ComparisonOptions.prototype["putWords"] = ComparisonOptions.prototype.putWords = function(v){this.words = v;};
|
||
|
||
|
||
function CDocumentComparison(oOriginalDocument, oRevisedDocument, oOptions, bIsWordsByOneSymbol)
|
||
{
|
||
this.originalDocument = oOriginalDocument;
|
||
this.revisedDocument = oRevisedDocument;
|
||
this.options = oOptions;
|
||
this.api = oOriginalDocument.GetApi();
|
||
this.StylesMap = {};
|
||
this.CommentsMap = {};
|
||
this.matchedNums = {};
|
||
this.checkedNums = {};
|
||
this.bSaveCustomReviewType = false;
|
||
|
||
this.copyPr = {
|
||
CopyReviewPr: false,
|
||
Comparison: this,
|
||
SkipFootnoteReference: !oOptions.footNotes
|
||
};
|
||
this.firstCheckNumId = null;
|
||
|
||
this.oComparisonMoveMarkManager = new CMoveMarkComparisonManager();
|
||
this.oBookmarkManager = new CComparisonBookmarkManager(oOriginalDocument, oRevisedDocument);
|
||
this.oCommentManager = new CComparisonCommentManager(this);
|
||
|
||
this.isWordsByOneSymbol = bIsWordsByOneSymbol;
|
||
|
||
this.needCheckReview = false;
|
||
this.needCopyForResolveEqualWords = true;
|
||
this.skipCopiedElements = false;
|
||
|
||
this.nInsertChangesType = reviewtype_Add;
|
||
this.nRemoveChangesType = reviewtype_Remove;
|
||
}
|
||
CDocumentComparison.prototype.skipCommentElementOnCopyParagraph = function (oParaComment) {
|
||
if (this.options.comments) {
|
||
return false;
|
||
}
|
||
return !this.oCommentManager.savedParaComments[oParaComment.Id];
|
||
}
|
||
CDocumentComparison.prototype.executeResolveConflictMode = function (oResolveConflictComparison, fCallback) {
|
||
const oOldCommentsMeeting = this.oCommentManager.mapCommentMeeting;
|
||
this.oCommentManager.mapCommentMeeting = {};
|
||
oResolveConflictComparison.oCommentManager = this.oCommentManager;
|
||
|
||
const oOldBookmarkMeeting = this.oBookmarkManager.mapBookmarkMeeting;
|
||
this.oBookmarkManager.mapBookmarkMeeting = {};
|
||
oResolveConflictComparison.oBookmarkManager = this.oBookmarkManager;
|
||
oResolveConflictComparison.oComparisonMoveMarkManager = this.oComparisonMoveMarkManager;
|
||
oResolveConflictComparison.CommentsMap = this.CommentsMap;
|
||
oResolveConflictComparison.StylesMap = this.StylesMap;
|
||
fCallback();
|
||
this.oBookmarkManager.mapBookmarkMeeting = oOldBookmarkMeeting;
|
||
this.oCommentManager.mapCommentMeeting = oOldCommentsMeeting;
|
||
};
|
||
CDocumentComparison.prototype.resolveConflicts = function(arrToInserts, arrToRemove, applyParagraph, bIsWordsByOneSymbol) {
|
||
if (arrToInserts.length === 0 || arrToRemove.length === 0) return;
|
||
bIsWordsByOneSymbol = bIsWordsByOneSymbol || this.isWordsByOneSymbol;
|
||
let comparison;
|
||
if (this instanceof AscCommonWord.CDocumentResolveConflictComparison) {
|
||
comparison = new AscCommonWord.CDocumentMergeComparison(this.originalDocument, this.revisedDocument, this.options, bIsWordsByOneSymbol);
|
||
} else {
|
||
|
||
comparison = new AscCommonWord.CDocumentResolveConflictComparison(this.originalDocument, this.revisedDocument, this.options, bIsWordsByOneSymbol);
|
||
}
|
||
|
||
this.executeResolveConflictMode(comparison, function () {
|
||
const originalDocument = getMockDocumentFromRuns(arrToRemove);
|
||
const revisedDocument = getMockDocumentFromRuns(arrToInserts);
|
||
comparison.parentParagraph = applyParagraph;
|
||
comparison.oComparisonMoveMarkManager.executeResolveConflictMode(function () {
|
||
comparison.compareRoots(originalDocument, revisedDocument);
|
||
});
|
||
});
|
||
};
|
||
CDocumentComparison.prototype.checkOriginalAndSplitRun = function (oOriginalRun, oSplitRun) {
|
||
|
||
};
|
||
CDocumentComparison.prototype.removeCommentsFromMap = function ()
|
||
{
|
||
for (let sCommentId in this.oCommentManager.mapDelete)
|
||
{
|
||
this.originalDocument.RemoveComment(sCommentId, true);
|
||
}
|
||
this.oCommentManager.mapDelete = {};
|
||
};
|
||
CDocumentComparison.prototype.executeWithSkipCopiedElements = function (fCallback) {
|
||
const bOldSkipCheckCopyRuns = this.skipCopiedElements;
|
||
this.skipCopiedElements = true;
|
||
fCallback();
|
||
this.skipCopiedElements = bOldSkipCheckCopyRuns;
|
||
};
|
||
CDocumentComparison.prototype.checkCopyParaRunMoveMarks = function (oNewRun, oOldRun) {
|
||
const sMoveName = this.oComparisonMoveMarkManager.getMoveMarkNameByRun(oOldRun);
|
||
this.oComparisonMoveMarkManager.addRunMoveMarkNameRelation(sMoveName, oNewRun);
|
||
const nMoveReviewType = oOldRun.GetReviewMoveType();
|
||
if (AscFormat.isRealNumber(nMoveReviewType) && nMoveReviewType !== Asc.c_oAscRevisionsMove.NoMove)
|
||
{
|
||
this.oComparisonMoveMarkManager.addMoveMarkNameRunRelation(sMoveName, oNewRun);
|
||
}
|
||
}
|
||
CDocumentComparison.prototype.checkCopyParaRun = function (oNewRun, oOldRun) {
|
||
this.checkCopyParaRunMoveMarks(oNewRun, oOldRun);
|
||
this.checkReviewInfoOfCopiedElements(oNewRun, oOldRun);
|
||
}
|
||
CDocumentComparison.prototype.checkReviewInfoOfCopiedElements = function (oNewRun, oOldRun) {
|
||
if (this.skipCopiedElements) {
|
||
return;
|
||
}
|
||
if (this.copyPr.SkipUpdateInfo)
|
||
{
|
||
this.saveReviewInfo(oNewRun, oOldRun);
|
||
} else if (this.copyPr.bSaveCustomReviewType)
|
||
{
|
||
this.saveCustomReviewInfo(oNewRun, oOldRun, this.nInsertChangesType);
|
||
} else
|
||
{
|
||
this.updateReviewInfo(oNewRun, this.nInsertChangesType);
|
||
}
|
||
};
|
||
CDocumentComparison.prototype.setRemoveReviewType = function (element) {
|
||
if(!(element.IsParaEndRun && element.IsParaEndRun()))
|
||
{
|
||
this.setReviewInfoRecursive(element, this.nRemoveChangesType);
|
||
}
|
||
};
|
||
CDocumentComparison.prototype.getUserName = function()
|
||
{
|
||
const oCore = this.revisedDocument.Core;
|
||
if(oCore && typeof oCore.lastModifiedBy === "string" && oCore.lastModifiedBy.length > 0)
|
||
{
|
||
return oCore.lastModifiedBy.split(";")[0];
|
||
}
|
||
else
|
||
{
|
||
return AscCommon.translateManager.getValue("Author");
|
||
}
|
||
};
|
||
CDocumentComparison.prototype.getLCSCallback = function (bOrig) {
|
||
const oThis = this;
|
||
return function(x, y) {
|
||
const oOrigNode = x;
|
||
const oReviseNode = y;
|
||
const oDiff = new AscCommon.Diff(oOrigNode, oReviseNode);
|
||
oDiff.equals = function(a, b)
|
||
{
|
||
return a.equals(b, oThis);
|
||
};
|
||
const oMatching = new CMatching();
|
||
oDiff.matchTrees(oMatching);
|
||
const oDeltaCollector = new AscCommon.DeltaCollector(oMatching, oOrigNode, oReviseNode);
|
||
oDeltaCollector.forEachChange(oThis.forEachChangeCallback);
|
||
oThis.compareDrawingObjectsFromMatching(oMatching, bOrig);
|
||
oThis.applyChangesToChildNode(oOrigNode);
|
||
oThis.compareNotes(oMatching);
|
||
};
|
||
};
|
||
|
||
CDocumentComparison.prototype.forEachChangeCallback = function(oOperation) {
|
||
oOperation.anchor.base.addChange(oOperation);
|
||
};
|
||
CDocumentComparison.prototype.compareElementsArray = function(aBase, aCompare, bOrig) {
|
||
if (!aBase.length || !aCompare.length) {
|
||
return;
|
||
}
|
||
const arrComparedSums = [0];
|
||
for (let i = 0; i < aCompare.length; i++) {
|
||
arrComparedSums.push(arrComparedSums[i] + aCompare[i].wordCounter.count + 1);
|
||
}
|
||
|
||
const arrBaseSums = [0];
|
||
for (let i = 0; i < aBase.length; i++) {
|
||
arrBaseSums.push(arrBaseSums[i] + aBase[i].wordCounter.count + 1);
|
||
}
|
||
|
||
const oResult = {};
|
||
const oFirstRow = {};
|
||
oResult[0] = oFirstRow;
|
||
oFirstRow[0] = {diff: aCompare[0].getDiff(aBase[0], this), baseIndex: 0, compareIndex: 0};
|
||
for (let i = 1; i < aCompare.length; i += 1) {
|
||
const nCompareSum = arrComparedSums[i];
|
||
const nTotalDiff = nCompareSum + aCompare[i].getDiff(aBase[0], this);
|
||
if (oFirstRow[i - 1].diff >= nTotalDiff) {
|
||
oFirstRow[i] = {diff: nTotalDiff, baseIndex: 0, compareIndex: i};
|
||
} else {
|
||
oFirstRow[i] = oFirstRow[i - 1];
|
||
}
|
||
}
|
||
for (let i = 1; i < aBase.length; i += 1) {
|
||
const oPreviousRow = oResult[i - 1];
|
||
const oCurrentRow = {};
|
||
oResult[i] = oCurrentRow;
|
||
const nCurTotalDiff = aBase[i].getDiff(aCompare[0], this) + arrBaseSums[i];
|
||
|
||
const oPreviousCell = oPreviousRow[0];
|
||
const nPreviousTotalDiff = oPreviousCell.diff + arrBaseSums[i + 1] - arrBaseSums[oPreviousCell.baseIndex + 1];
|
||
|
||
if (nPreviousTotalDiff >= nCurTotalDiff) {
|
||
oCurrentRow[0] = {diff: nCurTotalDiff, compareIndex: 0, baseIndex: i};
|
||
} else {
|
||
oCurrentRow[0] = oPreviousCell;
|
||
}
|
||
}
|
||
for (let i = 1; i < aBase.length; i += 1) {
|
||
const oBaseElem = aBase[i];
|
||
const oCurrentBestResult = oResult[i];
|
||
const oPreviousBestResult = oResult[i - 1];
|
||
for (let j = 1; j < aCompare.length; j++) {
|
||
const oCompareElem = aCompare[j];
|
||
|
||
const oPrevCurrentBest = oCurrentBestResult[j - 1];
|
||
const baseSum = arrBaseSums[i + 1] - arrBaseSums[oPrevCurrentBest.baseIndex + 1];
|
||
const compareSum = arrComparedSums[j + 1] - arrComparedSums[oPrevCurrentBest.compareIndex + 1];
|
||
const nPrevColumnCurDiff = baseSum + compareSum + oPrevCurrentBest.diff;
|
||
|
||
const oCurPreviousBest = oPreviousBestResult[j];
|
||
const nCurBaseSum = arrBaseSums[i + 1] - arrBaseSums[oCurPreviousBest.baseIndex + 1];
|
||
const nCurCompareSum = arrComparedSums[j + 1] - arrComparedSums[oCurPreviousBest.compareIndex + 1];
|
||
const nPrevColumnPrevDiff = nCurBaseSum + nCurCompareSum + oCurPreviousBest.diff;
|
||
|
||
const oPrevPreviousBest = oPreviousBestResult[j - 1];
|
||
const nPrevBaseSum = arrBaseSums[i] - arrBaseSums[oPrevPreviousBest.baseIndex + 1];
|
||
const nPrevCompareSum = arrComparedSums[j] - arrComparedSums[oPrevPreviousBest.compareIndex + 1];
|
||
const nDiff = oBaseElem.getDiff(oCompareElem, this);
|
||
const nCurColumnPrevDiff = nPrevBaseSum + nPrevCompareSum + oPrevPreviousBest.diff + nDiff;
|
||
|
||
if (nCurColumnPrevDiff <= nPrevColumnPrevDiff && nCurColumnPrevDiff <= nPrevColumnCurDiff) {
|
||
oCurrentBestResult[j] = {diff: nCurColumnPrevDiff, baseIndex: i, compareIndex: j};
|
||
} else if (nPrevColumnCurDiff <= nCurColumnPrevDiff && nPrevColumnCurDiff <= nPrevColumnPrevDiff) {
|
||
oCurrentBestResult[j] = oPrevCurrentBest;
|
||
} else {
|
||
oCurrentBestResult[j] = oCurPreviousBest;
|
||
}
|
||
}
|
||
}
|
||
|
||
const fLCSCallback = this.getLCSCallback(bOrig);
|
||
let curBaseIndex = aBase.length - 1;
|
||
let curCompareIndex = aCompare.length - 1;
|
||
while (curBaseIndex >= 0 && curCompareIndex >= 0) {
|
||
const curResultObject = oResult[curBaseIndex][curCompareIndex];
|
||
const oBaseElement = aBase[curResultObject.baseIndex];
|
||
const oCompareElement = aCompare[curResultObject.compareIndex];
|
||
if (oBaseElement.equals(oCompareElement)) {
|
||
oBaseElement.setPartner(oCompareElement);
|
||
if (bOrig) {
|
||
fLCSCallback(oBaseElement, oCompareElement);
|
||
} else {
|
||
fLCSCallback(oCompareElement, oBaseElement);
|
||
}
|
||
}
|
||
curBaseIndex = curResultObject.baseIndex - 1;
|
||
curCompareIndex = curResultObject.compareIndex - 1;
|
||
}
|
||
};
|
||
CDocumentComparison.prototype.compareNotes = function(oMatching)
|
||
{
|
||
for(let key in oMatching.Footnotes)
|
||
{
|
||
if(oMatching.Footnotes.hasOwnProperty(key))
|
||
{
|
||
const oBaseFootnotes = AscCommon.g_oTableId.Get_ById(key);
|
||
const oCompareFootnotes = oMatching.Footnotes[key];
|
||
if(oBaseFootnotes && oCompareFootnotes)
|
||
{
|
||
this.compareRoots(oBaseFootnotes, oCompareFootnotes);
|
||
}
|
||
}
|
||
}
|
||
};
|
||
CDocumentComparison.prototype.insertCopyTextBoxContent = function (oBaseShape, oTextBoxContent) {
|
||
oBaseShape.setTextBoxContent(oTextBoxContent.Copy(oBaseShape, editor.WordControl.m_oDrawingDocument, this.copyPr));
|
||
};
|
||
CDocumentComparison.prototype.compareShapes = function(oBaseShape, oCompareShape)
|
||
{
|
||
if(oBaseShape.textBoxContent && oCompareShape.textBoxContent)
|
||
{
|
||
this.compareRoots(oBaseShape.textBoxContent, oCompareShape.textBoxContent);
|
||
}
|
||
else if(oBaseShape.textBoxContent && !oCompareShape.textBoxContent)
|
||
{
|
||
this.setRemoveReviewType(oBaseShape.textBoxContent);
|
||
}
|
||
else if(!oBaseShape.textBoxContent && oCompareShape.textBoxContent)
|
||
{
|
||
this.insertCopyTextBoxContent(oBaseShape, oCompareShape.textBoxContent);
|
||
}
|
||
};
|
||
CDocumentComparison.prototype.updateBookmarksStack = function (oNode)
|
||
{
|
||
this.oBookmarkManager.updateBookmarksStack(oNode);
|
||
};
|
||
CDocumentComparison.prototype.updateCommentsStack = function (oNode)
|
||
{
|
||
this.oCommentManager.updateCommentsStack(oNode);
|
||
};
|
||
CDocumentComparison.prototype.createNode = function (oElement, oParent)
|
||
{
|
||
const CNodeConstructor = this.getNodeConstructor();
|
||
const oNode = new CNodeConstructor(oElement, oParent);
|
||
if (oElement instanceof CTextElement)
|
||
{
|
||
this.updateBookmarksStack(oNode);
|
||
this.updateCommentsStack(oNode);
|
||
this.oBookmarkManager.previousNode = oNode;
|
||
this.oCommentManager.previousNode = oNode;
|
||
}
|
||
return oNode;
|
||
};
|
||
CDocumentComparison.prototype.compareGroups = function(oBaseGroup, oCompareGroup)
|
||
{
|
||
const NodeConstructor = this.getNodeConstructor();
|
||
const oLCS = new AscCommon.LCS(oBaseGroup.spTree, oCompareGroup.spTree);
|
||
oLCS.equals = function(a, b) {
|
||
return a.isComparable(b);
|
||
};
|
||
|
||
const oBaseNode = this.createNode(oBaseGroup, null);
|
||
for(let nSp = 0; nSp < oBaseGroup.spTree.length; ++nSp)
|
||
{
|
||
this.createNode(oBaseGroup.spTree[nSp], oBaseNode);
|
||
}
|
||
const oCompareNode = this.createNode(oCompareGroup, null);
|
||
for(let nSp = 0; nSp < oCompareGroup.spTree.length; ++nSp)
|
||
{
|
||
this.createNode(oCompareGroup.spTree[nSp], oCompareNode);
|
||
}
|
||
const oDiff = new AscCommon.Diff(oBaseNode, oCompareNode);
|
||
oDiff.equals = function(a, b)
|
||
{
|
||
return a.isComparable(b);
|
||
};
|
||
const oMatching = new CMatching();
|
||
oDiff.matchTrees(oMatching);
|
||
const oDeltaCollector = new AscCommon.DeltaCollector(oMatching, oBaseNode, oCompareNode);
|
||
oDeltaCollector.forEachChange(function(oOperation){
|
||
oOperation.anchor.base.addChange(oOperation);
|
||
});
|
||
oBaseNode.changes.sort(function(c1, c2){return c2.anchor.index - c1.anchor.index});
|
||
for(let nChild = 0; nChild < oBaseNode.children.length; ++nChild)
|
||
{
|
||
const oChild = oBaseNode.children[nChild];
|
||
if(oChild.partner)
|
||
{
|
||
this.compareGraphicObject(oChild.element, oChild.partner.element);
|
||
}
|
||
}
|
||
for(let nChange = 0; nChange < oBaseNode.changes.length; ++nChange)
|
||
{
|
||
const oChange = oBaseNode.changes[nChange];
|
||
for(let nRemove = oChange.remove.length - 1; nRemove > -1; --nRemove)
|
||
{
|
||
const oRemoveSp = oChange.remove[nRemove].element;
|
||
this.setGraphicObjectReviewInfo(oRemoveSp, this.nRemoveChangesType);
|
||
}
|
||
for(let nInsert = oChange.insert.length - 1; nInsert > -1; --nInsert)
|
||
{
|
||
const oInsertSp = oChange.insert[nInsert].element.copy({contentCopyPr: this.copyPr});
|
||
oBaseGroup.addToSpTree(oChange.anchor.index, oInsertSp);
|
||
oInsertSp.setGroup(oBaseGroup);
|
||
}
|
||
}
|
||
};
|
||
CDocumentComparison.prototype.setGraphicObjectReviewInfo = function(oGrObj, nType)
|
||
{
|
||
switch (oGrObj.getObjectType())
|
||
{
|
||
case AscDFH.historyitem_type_Shape:
|
||
{
|
||
if(oGrObj.textBoxContent)
|
||
{
|
||
this.setReviewInfoRecursive(oGrObj.textBoxContent, nType);
|
||
}
|
||
break;
|
||
}
|
||
case AscDFH.historyitem_type_GroupShape:
|
||
{
|
||
for(let nSp = 0; nSp < oGrObj.spTree.length; ++nSp)
|
||
{
|
||
this.setGraphicObjectReviewInfo(oGrObj.spTree[nSp], nType);
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
};
|
||
|
||
CDocumentComparison.prototype.compareDrawingObjects = function (oBaseDrawing, oCompareDrawing, bOrig) {
|
||
if(oBaseDrawing && oCompareDrawing)
|
||
{
|
||
const oBaseGrObject = oBaseDrawing.GraphicObj;
|
||
const oCompareGrObject = oCompareDrawing.GraphicObj;
|
||
this.compareGraphicObject(oBaseGrObject, oCompareGrObject);
|
||
}
|
||
};
|
||
|
||
CDocumentComparison.prototype.compareDrawingObjectsFromMatching = function(oMatching, bOrig)
|
||
{
|
||
for(let key in oMatching.Drawings)
|
||
{
|
||
if(oMatching.Drawings.hasOwnProperty(key))
|
||
{
|
||
const oBaseDrawing = AscCommon.g_oTableId.Get_ById(key);
|
||
const oCompareDrawing = oMatching.Drawings[key];
|
||
this.compareDrawingObjects(oBaseDrawing, oCompareDrawing, bOrig);
|
||
}
|
||
}
|
||
};
|
||
CDocumentComparison.prototype.compareGraphicObject = function(oBaseGrObject, oCompareGrObject)
|
||
{
|
||
if(!this.options.textBoxes || !oBaseGrObject || !oCompareGrObject)
|
||
{
|
||
return;
|
||
}
|
||
const nObjectType = oBaseGrObject.getObjectType();
|
||
if(nObjectType !== oCompareGrObject.getObjectType())
|
||
{
|
||
return;
|
||
}
|
||
switch (nObjectType)
|
||
{
|
||
case AscDFH.historyitem_type_Shape:
|
||
{
|
||
this.compareShapes(oBaseGrObject, oCompareGrObject);
|
||
break;
|
||
}
|
||
case AscDFH.historyitem_type_GroupShape:
|
||
{
|
||
this.compareGroups(oBaseGrObject, oCompareGrObject);
|
||
break;
|
||
}
|
||
}
|
||
};
|
||
|
||
CDocumentComparison.prototype.applyParagraphComparison = function (oOrigRoot, oRevisedRoot) {
|
||
const aInsertContent = [];
|
||
let nRemoveCount = 0;
|
||
this.oCommentManager.generateSavedParaComments();
|
||
const bOldSkipFootnoteReference = this.copyPr.SkipFootnoteReference;
|
||
this.copyPr.SkipFootnoteReference = false;
|
||
for(let i = oOrigRoot.children.length - 1; i > -1 ; --i)
|
||
{
|
||
if(!oOrigRoot.children[i].partner)
|
||
{
|
||
this.setReviewInfoRecursive(oOrigRoot.children[i].element, this.nRemoveChangesType);
|
||
++nRemoveCount;
|
||
}
|
||
else
|
||
{
|
||
aInsertContent.length = 0;
|
||
for(let j = oOrigRoot.children[i].partner.childidx + 1;
|
||
j < oRevisedRoot.children.length && !oRevisedRoot.children[j].partner; ++j)
|
||
{
|
||
aInsertContent.push(oRevisedRoot.children[j]);
|
||
}
|
||
if(aInsertContent.length > 0)
|
||
{
|
||
this.insertNodesToDocContent(oOrigRoot.element, i + 1 + nRemoveCount, aInsertContent);
|
||
}
|
||
nRemoveCount = 0;
|
||
}
|
||
}
|
||
aInsertContent.length = 0;
|
||
for(let j = 0; j < oRevisedRoot.children.length && !oRevisedRoot.children[j].partner; ++j)
|
||
{
|
||
aInsertContent.push(oRevisedRoot.children[j]);
|
||
}
|
||
if(aInsertContent.length > 0)
|
||
{
|
||
this.insertNodesToDocContent(oOrigRoot.element, nRemoveCount, aInsertContent);
|
||
}
|
||
this.copyPr.SkipFootnoteReference = bOldSkipFootnoteReference;
|
||
};
|
||
|
||
CDocumentComparison.prototype.compareRoots = function(oRoot1, oRoot2)
|
||
{
|
||
const oOrigRoot = this.createNodeFromDocContent(oRoot1, null, null, true);
|
||
const oRevisedRoot = this.createNodeFromDocContent(oRoot2, null, null, false);
|
||
let aBase, aCompare, bOrig = true;
|
||
if(oOrigRoot.children.length <= oRevisedRoot.children.length)
|
||
{
|
||
aBase = oOrigRoot.children;
|
||
aCompare = oRevisedRoot.children;
|
||
}
|
||
else
|
||
{
|
||
bOrig = false;
|
||
aBase = oRevisedRoot.children;
|
||
aCompare = oOrigRoot.children;
|
||
}
|
||
|
||
this.compareElementsArray(aBase, aCompare, bOrig);
|
||
this.applyParagraphComparison(oOrigRoot, oRevisedRoot);
|
||
};
|
||
CDocumentComparison.prototype.compare = function(callback)
|
||
{
|
||
const oOriginalDocument = this.originalDocument;
|
||
const oRevisedDocument = this.revisedDocument;
|
||
if(!oOriginalDocument || !oRevisedDocument)
|
||
{
|
||
return;
|
||
}
|
||
this.oBookmarkManager.init(oOriginalDocument, oRevisedDocument);
|
||
const oThis = this;
|
||
const aImages = AscCommon.pptx_content_loader.End_UseFullUrl();
|
||
const oObjectsForDownload = AscCommon.GetObjectsForImageDownload(aImages);
|
||
const oApi = oOriginalDocument.GetApi();
|
||
if(!oApi)
|
||
{
|
||
return;
|
||
}
|
||
const fCallback = function (data) {
|
||
const oImageMap = {};
|
||
AscFormat.ExecuteNoHistory(function () {
|
||
AscCommon.ResetNewUrls(data, oObjectsForDownload.aUrls, oObjectsForDownload.aBuilderImagesByUrl, oImageMap);
|
||
}, oThis, []);
|
||
oOriginalDocument.StopRecalculate();
|
||
oOriginalDocument.StartAction(AscDFH.historydescription_Document_CompareDocuments);
|
||
oOriginalDocument.Start_SilentMode();
|
||
const oldTrackRevisions = oOriginalDocument.GetLocalTrackRevisions();
|
||
oOriginalDocument.SetTrackRevisions(false);
|
||
const LogicDocuments = oOriginalDocument.TrackRevisionsManager.Get_AllChangesLogicDocuments();
|
||
for (let LogicDocId in LogicDocuments)
|
||
{
|
||
const LogicDoc = AscCommon.g_oTableId.Get_ById(LogicDocId);
|
||
if (LogicDoc)
|
||
{
|
||
LogicDoc.AcceptRevisionChanges(undefined, true);
|
||
}
|
||
}
|
||
const NewNumbering = oRevisedDocument.Numbering.CopyAllNums(oOriginalDocument.Numbering);
|
||
oRevisedDocument.CopyNumberingMap = NewNumbering.NumMap;
|
||
oOriginalDocument.Numbering.AppendAbstractNums(NewNumbering.AbstractNum);
|
||
oOriginalDocument.Numbering.AppendNums(NewNumbering.Num);
|
||
for(let key in NewNumbering.NumMap)
|
||
{
|
||
if (NewNumbering.NumMap.hasOwnProperty(key))
|
||
{
|
||
oThis.checkedNums[NewNumbering.NumMap[key]] = true;
|
||
}
|
||
}
|
||
oThis.compareRoots(oOriginalDocument, oRevisedDocument);
|
||
oThis.compareSectPr(oOriginalDocument, oRevisedDocument, !oThis.options.headersAndFooters);
|
||
|
||
const oFonts = oOriginalDocument.Document_Get_AllFontNames();
|
||
const aFonts = [];
|
||
for (let i in oFonts)
|
||
{
|
||
if(oFonts.hasOwnProperty(i))
|
||
{
|
||
aFonts[aFonts.length] = new AscFonts.CFont(i);
|
||
}
|
||
}
|
||
oApi.pre_Paste(aFonts, oImageMap, function()
|
||
{
|
||
oThis.removeCommentsFromMap();
|
||
oOriginalDocument.SetTrackRevisions(oldTrackRevisions);
|
||
oOriginalDocument.End_SilentMode(false);
|
||
if (oThis.oBookmarkManager.needUpdateBookmarks)
|
||
{
|
||
oOriginalDocument.UpdateBookmarks();
|
||
}
|
||
oThis.updateCommentsQuoteText();
|
||
oOriginalDocument.Recalculate();
|
||
oOriginalDocument.UpdateInterface();
|
||
oOriginalDocument.FinalizeAction();
|
||
oApi.sync_EndAction(Asc.c_oAscAsyncActionType.BlockInteraction, Asc.c_oAscAsyncAction.SlowOperation);
|
||
callback && callback();
|
||
});
|
||
};
|
||
if (oApi.getViewMode()) {
|
||
//todo allow image upload in view mode or deny setRequestedDocument
|
||
//temp stub for bug 75266. Use images from converted document. downloadAs also relies on images from the converted document
|
||
fCallback(oObjectsForDownload.aUrls);
|
||
} else {
|
||
AscCommon.sendImgUrls(oApi, oObjectsForDownload.aUrls, fCallback, true);
|
||
}
|
||
return null;
|
||
};
|
||
CDocumentComparison.prototype.getNewParaPrWithDiff = function (oElementPr, oPartnerPr)
|
||
{
|
||
const oOldParaPr = oElementPr.Copy(undefined, undefined);
|
||
|
||
this.firstCheckNumId = oOldParaPr.NumPr && oOldParaPr.NumPr.NumId;
|
||
const oNewParaPr = oPartnerPr.Copy(undefined, this.copyPr);
|
||
this.firstCheckNumId = null;
|
||
|
||
if (oOldParaPr.Is_Equal(oNewParaPr))
|
||
{
|
||
return null;
|
||
}
|
||
oNewParaPr.PrChange = oOldParaPr;
|
||
oNewParaPr.ReviewInfo = this.getReviewInfo();
|
||
return oNewParaPr;
|
||
};
|
||
CDocumentComparison.prototype.isElementForAdd = function (oElement)
|
||
{
|
||
return !(oElement.IsParaEndRun && oElement.IsParaEndRun() || this.oBookmarkManager.isSkip(oElement));
|
||
};
|
||
CDocumentComparison.prototype.executeWithCheckInsertAndRemove = function (callback, oChange) {
|
||
this.copyPr.SkipUpdateInfo = !this.options.words && oChange.remove.length === 1 && oChange.insert.length === 1;
|
||
callback();
|
||
this.copyPr.SkipUpdateInfo = false;
|
||
};
|
||
|
||
CDocumentComparison.prototype.applyResolveTypes = function () {};
|
||
|
||
CDocumentComparison.prototype.isSkipWhitespaces = function(arrNodes) {
|
||
if (this.options.whiteSpace) {
|
||
return false;
|
||
}
|
||
|
||
for (let i = 0; i < arrNodes.length; i++) {
|
||
const oNode = arrNodes[i];
|
||
if (!oNode.isSpaceText()) {
|
||
return false;
|
||
|
||
}
|
||
}
|
||
return true;
|
||
};
|
||
CNode.prototype.updateEqualNode = function (comparison, index) {
|
||
const oPartnerNode = this.partner;
|
||
const oOriginalTextElement = this.element;
|
||
const oPartnerTextElement = oPartnerNode.element;
|
||
if (oPartnerTextElement.elements.length === oOriginalTextElement.elements.length) {
|
||
this.resolveTypesWithPartner(comparison);
|
||
} else {
|
||
const oParentNode = this.par;
|
||
const oChange = new AscCommon.AttachedOperation(
|
||
new AscCommon.Anchor(oParentNode, oParentNode, index),
|
||
AscCommon.UPDATE_FOREST_TYPE, [index],
|
||
[this], [oPartnerNode]);
|
||
const bOldComparisonWordOption = comparison.options.words;
|
||
comparison.options.words = false;
|
||
comparison.copyPr.SkipUpdateInfo = true;
|
||
const aContentToInsert = comparison.isSkipWhitespaces(oChange.insert) ? [] : oParentNode.getArrOfInsertsFromChanges(oChange, comparison); // todo: check skip on symbol comparing
|
||
oParentNode.applyInsertsToParagraph(comparison, aContentToInsert, oChange);
|
||
comparison.options.words = bOldComparisonWordOption;
|
||
comparison.copyPr.SkipUpdateInfo = false;
|
||
}
|
||
};
|
||
CDocumentComparison.prototype.applyChangesToParagraph = function(oNode)
|
||
{
|
||
oNode.changes.sort(function(c1, c2){return c2.anchor.index - c1.anchor.index});
|
||
let nLastIndex = oNode.children.length - 1;
|
||
for(let i = 0; i < oNode.changes.length; ++i)
|
||
{
|
||
const oChange = oNode.changes[i];
|
||
let arrResult = [];
|
||
for (let j = nLastIndex; j >= oChange.anchor.index; j -= 1)
|
||
{
|
||
const oChild = oNode.children[j];
|
||
if (oChild.partner && oChild.element instanceof CTextElement) {
|
||
if (oChild.element.checkUncompletedWords(oChild.partner.element)) {
|
||
resolveTypesWithPartner(arrResult, this);
|
||
arrResult = [];
|
||
oChild.updateEqualNode(this, j);
|
||
} else {
|
||
arrResult.unshift(oChild);
|
||
}
|
||
} else if (arrResult.length) {
|
||
resolveTypesWithPartner(arrResult, this);
|
||
arrResult = [];
|
||
}
|
||
}
|
||
if (arrResult.length) {
|
||
resolveTypesWithPartner(arrResult, this);
|
||
}
|
||
this.executeWithCheckInsertAndRemove(function () {
|
||
const aContentToInsert = this.isSkipWhitespaces(oChange.insert) ? [] : oNode.getArrOfInsertsFromChanges(oChange, this);
|
||
//handle removed elements
|
||
oNode.applyInsertsToParagraph(this, aContentToInsert, oChange);
|
||
}.bind(this), oChange);
|
||
|
||
nLastIndex = oChange.anchor.index - 1;
|
||
}
|
||
let arrResult = [];
|
||
for (let j = nLastIndex; j >= 0; j -= 1)
|
||
{
|
||
const oChild = oNode.children[j];
|
||
if (oChild.partner && oChild.element instanceof CTextElement) {
|
||
if (oChild.element.checkUncompletedWords(oChild.partner.element)) {
|
||
resolveTypesWithPartner(arrResult, this);
|
||
arrResult = [];
|
||
oChild.updateEqualNode(this, j);
|
||
} else {
|
||
arrResult.unshift(oChild);
|
||
}
|
||
} else if (arrResult.length) {
|
||
resolveTypesWithPartner(arrResult, this);
|
||
arrResult = [];
|
||
}
|
||
}
|
||
if (arrResult.length) {
|
||
resolveTypesWithPartner(arrResult, this);
|
||
}
|
||
this.applyChangesToChildrenOfParagraphNode(oNode);
|
||
this.applyChangesToSectPr(oNode);
|
||
};
|
||
|
||
CDocumentComparison.prototype.applyChangesToChildrenOfParagraphNode = function (oNode) {
|
||
for(let i = 0; i < oNode.children.length; ++i)
|
||
{
|
||
const oChildNode = oNode.children[i];
|
||
if(Array.isArray(oChildNode.element.Content))
|
||
{
|
||
this.applyChangesToParagraph(oChildNode);
|
||
}
|
||
else
|
||
{
|
||
for(let j = 0; j < oChildNode.children.length; ++j)
|
||
{
|
||
if(oChildNode.children[j].element instanceof CDocumentContent)
|
||
{
|
||
this.applyChangesToDocContent(oChildNode.children[j]);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
};
|
||
|
||
CDocumentComparison.prototype.applyChangesToSectPr = function (oNode) {
|
||
const oElement = oNode.element;
|
||
if(oNode.partner)
|
||
{
|
||
const oPartnerNode = oNode.partner;
|
||
const oPartnerElement = oPartnerNode.element;
|
||
if(oPartnerElement instanceof Paragraph)
|
||
{
|
||
const oNewParaPr = this.getNewParaPrWithDiff(oElement.Pr, oPartnerElement.Pr);
|
||
if(oNewParaPr)
|
||
{
|
||
oElement.Set_Pr(oNewParaPr);
|
||
}
|
||
this.compareSectPr(oElement, oPartnerElement);
|
||
}
|
||
}
|
||
};
|
||
|
||
CDocumentComparison.prototype.compareSectPr = function(oElement, oPartnerElement, bSkipCheckHeadersFooters)
|
||
{
|
||
const oOrigSectPr = oElement.SectPr;
|
||
const oReviseSectPr = oPartnerElement.SectPr;
|
||
let oOrigContent, oReviseContent;
|
||
if(!oOrigSectPr && oReviseSectPr)
|
||
{
|
||
const oLogicDocument = this.originalDocument;
|
||
const bCopyHdrFtr = true;
|
||
const SectPr = new AscWord.SectPr(oLogicDocument);
|
||
SectPr.Copy(oReviseSectPr, bCopyHdrFtr, this.copyPr);
|
||
if(oElement.Set_SectionPr)
|
||
{
|
||
oElement.Set_SectionPr(SectPr);
|
||
}
|
||
}
|
||
if(oOrigSectPr)
|
||
{
|
||
if (!bSkipCheckHeadersFooters) {
|
||
oOrigContent = oOrigSectPr.HeaderFirst && oOrigSectPr.HeaderFirst.Content;
|
||
oReviseContent = oReviseSectPr && oReviseSectPr.HeaderFirst && oReviseSectPr.HeaderFirst.Content;
|
||
if(oOrigContent && !oReviseContent)
|
||
{
|
||
this.setReviewInfoRecursive(oOrigContent, this.nRemoveChangesType);
|
||
}
|
||
else if(oOrigContent && oReviseContent)
|
||
{
|
||
this.compareRoots(oOrigContent, oReviseContent);
|
||
}
|
||
else if(!oOrigContent && oReviseContent && oReviseSectPr.HeaderFirst)
|
||
{
|
||
oOrigSectPr.Set_Header_First(oReviseSectPr.HeaderFirst.Copy(this.originalDocument, this.copyPr));
|
||
}
|
||
|
||
|
||
oOrigContent = oOrigSectPr.HeaderEven && oOrigSectPr.HeaderEven.Content;
|
||
oReviseContent = oReviseSectPr && oReviseSectPr.HeaderEven && oReviseSectPr.HeaderEven.Content;
|
||
if(oOrigContent && !oReviseContent)
|
||
{
|
||
this.setReviewInfoRecursive(oOrigContent, this.nRemoveChangesType);
|
||
}
|
||
else if(oOrigContent && oReviseContent)
|
||
{
|
||
this.compareRoots(oOrigContent, oReviseContent);
|
||
}
|
||
else if(!oOrigContent && oReviseContent && oReviseSectPr.HeaderEven)
|
||
{
|
||
oOrigSectPr.Set_Header_Even(oReviseSectPr.HeaderEven.Copy(this.originalDocument, this.copyPr));
|
||
}
|
||
|
||
|
||
oOrigContent = oOrigSectPr.HeaderDefault && oOrigSectPr.HeaderDefault.Content;
|
||
oReviseContent = oReviseSectPr && oReviseSectPr.HeaderDefault && oReviseSectPr.HeaderDefault.Content;
|
||
if(oOrigContent && !oReviseContent)
|
||
{
|
||
this.setReviewInfoRecursive(oOrigContent, this.nRemoveChangesType);
|
||
}
|
||
else if(oOrigContent && oReviseContent)
|
||
{
|
||
this.compareRoots(oOrigContent, oReviseContent);
|
||
}
|
||
else if(!oOrigContent && oReviseContent && oReviseSectPr.HeaderDefault)
|
||
{
|
||
oOrigSectPr.Set_Header_Default(oReviseSectPr.HeaderDefault.Copy(this.originalDocument, this.copyPr));
|
||
}
|
||
|
||
|
||
oOrigContent = oOrigSectPr.FooterFirst && oOrigSectPr.FooterFirst.Content;
|
||
oReviseContent = oReviseSectPr && oReviseSectPr.FooterFirst && oReviseSectPr.FooterFirst.Content;
|
||
if(oOrigContent && !oReviseContent)
|
||
{
|
||
this.setReviewInfoRecursive(oOrigContent, this.nRemoveChangesType);
|
||
}
|
||
else if(oOrigContent && oReviseContent)
|
||
{
|
||
this.compareRoots(oOrigContent, oReviseContent);
|
||
}
|
||
else if(!oOrigContent && oReviseContent && oReviseSectPr.FooterFirst)
|
||
{
|
||
oOrigSectPr.Set_Footer_First(oReviseSectPr.FooterFirst.Copy(this.originalDocument, this.copyPr));
|
||
}
|
||
|
||
|
||
oOrigContent = oOrigSectPr.FooterEven && oOrigSectPr.FooterEven.Content;
|
||
oReviseContent = oReviseSectPr && oReviseSectPr.FooterEven && oReviseSectPr.FooterEven.Content;
|
||
if(oOrigContent && !oReviseContent)
|
||
{
|
||
this.setReviewInfoRecursive(oOrigContent, this.nRemoveChangesType);
|
||
}
|
||
else if(oOrigContent && oReviseContent)
|
||
{
|
||
this.compareRoots(oOrigContent, oReviseContent);
|
||
}
|
||
else if(!oOrigContent && oReviseContent && oReviseSectPr.FooterEven)
|
||
{
|
||
oOrigSectPr.Set_Footer_Even(oReviseSectPr.FooterEven.Copy(this.originalDocument, this.copyPr));
|
||
}
|
||
|
||
|
||
oOrigContent = oOrigSectPr.FooterDefault && oOrigSectPr.FooterDefault.Content;
|
||
oReviseContent = oReviseSectPr && oReviseSectPr.FooterDefault && oReviseSectPr.FooterDefault.Content;
|
||
if(oOrigContent && !oReviseContent)
|
||
{
|
||
this.setReviewInfoRecursive(oOrigContent, this.nRemoveChangesType);
|
||
}
|
||
else if(oOrigContent && oReviseContent)
|
||
{
|
||
this.compareRoots(oOrigContent, oReviseContent);
|
||
}
|
||
else if(!oOrigContent && oReviseContent && oReviseSectPr.FooterDefault)
|
||
{
|
||
oOrigSectPr.Set_Footer_Default(oReviseSectPr.FooterDefault.Copy(this.originalDocument, this.copyPr));
|
||
}
|
||
}
|
||
if(oReviseSectPr)
|
||
{
|
||
const oReviseHeaderFirst = oReviseSectPr.HeaderFirst;
|
||
const oReviseHeaderEven = oReviseSectPr.HeaderEven;
|
||
const oReviseHeaderDefault = oReviseSectPr.HeaderDefault;
|
||
const oReviseFooterFirst = oReviseSectPr.FooterFirst;
|
||
const oReviseFooterEven = oReviseSectPr.FooterEven;
|
||
const oReviseFooterDefault = oReviseSectPr.FooterDefault;
|
||
|
||
oReviseSectPr.HeaderFirst = oOrigSectPr.HeaderFirst;
|
||
oReviseSectPr.HeaderEven = oOrigSectPr.HeaderEven;
|
||
oReviseSectPr.HeaderDefault = oOrigSectPr.HeaderDefault;
|
||
oReviseSectPr.FooterFirst = oOrigSectPr.FooterFirst;
|
||
oReviseSectPr.FooterEven = oOrigSectPr.FooterEven;
|
||
oReviseSectPr.FooterDefault = oOrigSectPr.FooterDefault;
|
||
|
||
oOrigSectPr.Copy(oReviseSectPr, false);
|
||
|
||
oReviseSectPr.HeaderFirst = oReviseHeaderFirst;
|
||
oReviseSectPr.HeaderEven = oReviseHeaderEven;
|
||
oReviseSectPr.HeaderDefault = oReviseHeaderDefault;
|
||
oReviseSectPr.FooterFirst = oReviseFooterFirst;
|
||
oReviseSectPr.FooterEven = oReviseFooterEven;
|
||
oReviseSectPr.FooterDefault = oReviseFooterDefault;
|
||
}
|
||
}
|
||
};
|
||
CDocumentComparison.prototype.applyChangesToTablePr = function (oNode) {
|
||
if (oNode.partner) {
|
||
const oMainTable = oNode.element;
|
||
const oRevisedTable = oNode.partner.element;
|
||
|
||
const oMainPr = oMainTable.Pr;
|
||
const oRevisedPr = oRevisedTable.Pr;
|
||
|
||
const sMainStyleId = oMainTable.TableStyle;
|
||
const sRevisedStyleId = this.copyStyleById(oRevisedTable.TableStyle);
|
||
|
||
const oMainTableLook = oMainTable.Get_TableLook();
|
||
const oRevisedTableLook = oMainTable.Get_TableLook();
|
||
if (oMainPr.Is_Equal(oRevisedPr) && sMainStyleId === sRevisedStyleId && (oMainTableLook && oMainTableLook.IsEqual(oRevisedTableLook) || oMainTableLook === oRevisedTableLook)) {
|
||
return;
|
||
}
|
||
if (sMainStyleId !== sRevisedStyleId) {
|
||
oMainTable.Set_TableStyle(sRevisedStyleId, true);
|
||
}
|
||
if (oRevisedTableLook) {
|
||
oMainTable.Set_TableLook(oRevisedTableLook.Copy());
|
||
} else {
|
||
oMainTable.Set_TableLook(oRevisedTableLook);
|
||
}
|
||
const oNewPr = oRevisedPr.Copy();
|
||
oNewPr.PrChange = oMainPr.Copy();
|
||
oNewPr.ReviewInfo = this.getReviewInfo();
|
||
oMainTable.Set_Pr(oNewPr);
|
||
}
|
||
}
|
||
CDocumentComparison.prototype.applyChangesToTable = function(oNode)
|
||
{
|
||
this.applyChangesToTablePr(oNode);
|
||
this.applyChangesToTableSize(oNode);
|
||
this.applyChangesToTableRows(oNode);
|
||
};
|
||
CDocumentComparison.prototype.applyChangesToTableSize = function(oNode)
|
||
{
|
||
const oElement = oNode.element;
|
||
oNode.changes.sort(function(c1, c2){return c2.anchor.index - c1.anchor.index});
|
||
for(let i = 0; i < oNode.changes.length; ++i)
|
||
{
|
||
const oChange = oNode.changes[i];
|
||
for(let j = oChange.remove.length - 1; j > -1; --j)
|
||
{
|
||
const oRow = oChange.remove[j].element;
|
||
this.setRemoveReviewType(oRow);
|
||
}
|
||
for(let j = oChange.insert.length - 1; j > -1; --j)
|
||
{
|
||
oElement.Content.splice(oChange.anchor.index, 0, oChange.insert[j].element.Copy(oElement, this.copyPr));
|
||
AscCommon.History.Add(new CChangesTableAddRow(oElement, oChange.anchor.index, [oElement.Content[oChange.anchor.index]]));
|
||
}
|
||
oElement.Internal_ReIndexing(0);
|
||
if (oElement.Content.length > 0 && oElement.Content[0].Get_CellsCount() > 0)
|
||
oElement.CurCell = oElement.Content[0].Get_Cell(0);
|
||
}
|
||
};
|
||
|
||
CDocumentComparison.prototype.applyChangesToTableRows = function(oNode)
|
||
{
|
||
for(let i = 0; i < oNode.children.length; ++i)
|
||
{
|
||
this.applyChangesToTableRow(oNode.children[i]);
|
||
}
|
||
};
|
||
CDocumentComparison.prototype.checkRowReview = function(oRowNode) {};
|
||
CDocumentComparison.prototype.addTablePrChange = function (oTablePr) {
|
||
oTablePr.PrChange = oTablePr.Copy(false);
|
||
oTablePr.ReviewInfo = this.getReviewInfo();
|
||
};
|
||
CDocumentComparison.prototype.applyChangesToTableCellPr = function (oNode) {
|
||
if (oNode.partner) {
|
||
const oMainCell = oNode.element.GetParent();
|
||
const oRevisedCell = oNode.partner.element.GetParent();
|
||
this.setTableElementChange(oMainCell, oRevisedCell);
|
||
}
|
||
};
|
||
CDocumentComparison.prototype.applyChangesToTableRowPr = function (oNode) {
|
||
if (oNode.partner) {
|
||
const oMainRow = oNode.element;
|
||
const oRevisedRow = oNode.partner.element;
|
||
this.setTableElementChange(oMainRow, oRevisedRow);
|
||
}
|
||
};
|
||
CDocumentComparison.prototype.setTableElementChange = function (oMainElement, oRevisedElement) {
|
||
const oMainPr = oMainElement.Pr;
|
||
const oRevisedPr = oRevisedElement.Pr;
|
||
|
||
if (oMainPr.Is_Equal(oRevisedPr)) {
|
||
return;
|
||
}
|
||
const oNewPr = oRevisedPr.Copy();
|
||
oNewPr.PrChange = oMainPr.Copy();
|
||
oNewPr.ReviewInfo = this.getReviewInfo();
|
||
oMainElement.Set_Pr(oNewPr);
|
||
const oTable = oMainElement.GetTable();
|
||
oTable.AddPrChange(this.copyPr);
|
||
};
|
||
CDocumentComparison.prototype.applyChangesToTableRow = function(oNode)
|
||
{
|
||
this.checkRowReview(oNode);
|
||
this.applyChangesToTableRowPr(oNode);
|
||
//TODO: handle cell inserts and removes
|
||
|
||
for(let i = 0; i < oNode.children.length; ++i)
|
||
{
|
||
const oChild = oNode.children[i];
|
||
this.applyChangesToTableCellPr(oChild);
|
||
this.applyChangesToDocContent(oChild);
|
||
}
|
||
};
|
||
CDocumentComparison.prototype.getCopyNumId = function (sNumId)
|
||
{
|
||
if (this.matchedNums[sNumId])
|
||
{
|
||
return this.matchedNums[sNumId];
|
||
}
|
||
const sCopyNumId = this.revisedDocument.CopyNumberingMap[sNumId];
|
||
if (typeof this.firstCheckNumId === 'string' && !this.checkedNums[this.firstCheckNumId] && sCopyNumId)
|
||
{
|
||
const oCopyNum = AscCommon.g_oTableId.Get_ById(sCopyNumId);
|
||
const oOrigNumbering = this.originalDocument.Numbering.Num;
|
||
if (oCopyNum && oOrigNumbering)
|
||
{
|
||
const oOrigNum = AscCommon.g_oTableId.Get_ById(this.firstCheckNumId);
|
||
if (oOrigNum && oOrigNum.IsEqual(oCopyNum))
|
||
{
|
||
this.matchedNums[sNumId] = this.firstCheckNumId;
|
||
this.checkedNums[this.firstCheckNumId] = true;
|
||
return this.firstCheckNumId;
|
||
}
|
||
}
|
||
}
|
||
return sCopyNumId === undefined ? sNumId : sCopyNumId;
|
||
};
|
||
CDocumentComparison.prototype.copyStyleById = function(sId)
|
||
{
|
||
return this.copyStyle(this.revisedDocument.Styles.Get(sId));
|
||
|
||
};
|
||
CDocumentComparison.prototype.checkNumStyleId = function (oParaPr, oOriginalStyle, oRevisedStyle) {
|
||
if (oParaPr.NumPr && oParaPr.NumPr.NumId) {
|
||
const oNumbering = this.originalDocument.GetNumbering();
|
||
const oNum = oNumbering && oNumbering.GetNum(oParaPr.NumPr.NumId);
|
||
if (oNum) {
|
||
const nLvl = oNum.GetLvlByStyle(oRevisedStyle.GetId());
|
||
if (nLvl !== -1) {
|
||
const oNumLvl = oNum.GetLvl(nLvl).Copy();
|
||
oNumLvl.SetPStyle(oOriginalStyle.GetId());
|
||
oNum.SetLvl(oNumLvl, nLvl);
|
||
}
|
||
}
|
||
}
|
||
};
|
||
CDocumentComparison.prototype.copyStyle = function(oStyle)
|
||
{
|
||
if(!oStyle)
|
||
{
|
||
return null;
|
||
}
|
||
if(this.StylesMap[oStyle.Id])
|
||
{
|
||
return this.StylesMap[oStyle.Id];
|
||
}
|
||
|
||
const sStyleId = this.originalDocument.Styles.GetStyleIdByName(oStyle.Name, false);
|
||
let oStyleCopy = this.originalDocument.Styles.Get(sStyleId);
|
||
if(oStyleCopy)
|
||
{
|
||
this.StylesMap[oStyle.Id] = sStyleId;
|
||
const oNewParaPr = this.getNewParaPrWithDiff(oStyleCopy.ParaPr, oStyle.ParaPr);
|
||
if(oNewParaPr)
|
||
{
|
||
this.checkNumStyleId(oNewParaPr, oStyleCopy, oStyle);
|
||
oStyleCopy.Set_ParaPr(oNewParaPr);
|
||
|
||
}
|
||
return sStyleId;
|
||
}
|
||
oStyleCopy = oStyle.Copy();
|
||
oStyleCopy.Set_Name(oStyle.Name);
|
||
oStyleCopy.Set_Next(oStyle.Next);
|
||
oStyleCopy.Set_Type(oStyle.Type);
|
||
oStyleCopy.Set_QFormat(oStyle.qFormat);
|
||
oStyleCopy.Set_UiPriority(oStyle.uiPriority);
|
||
oStyleCopy.Set_Hidden(oStyle.hidden);
|
||
oStyleCopy.Set_SemiHidden(oStyle.semiHidden);
|
||
oStyleCopy.Set_UnhideWhenUsed(oStyle.unhideWhenUsed);
|
||
oStyleCopy.Set_TextPr(oStyle.TextPr.Copy(undefined, this.copyPr));
|
||
const oParaPr = oStyle.ParaPr.Copy(undefined, this.copyPr);
|
||
this.checkNumStyleId(oParaPr, oStyleCopy, oStyle);
|
||
oStyleCopy.Set_ParaPr( oParaPr);
|
||
oStyleCopy.Set_TablePr(oStyle.TablePr.Copy());
|
||
oStyleCopy.Set_TableRowPr(oStyle.TableRowPr.Copy());
|
||
oStyleCopy.Set_TableCellPr(oStyle.TableCellPr.Copy());
|
||
if (undefined !== oStyle.TableBand1Horz)
|
||
{
|
||
oStyleCopy.Set_TableBand1Horz(oStyle.TableBand1Horz.Copy(this.copyPr));
|
||
oStyleCopy.Set_TableBand1Vert(oStyle.TableBand1Vert.Copy(this.copyPr));
|
||
oStyleCopy.Set_TableBand2Horz(oStyle.TableBand2Horz.Copy(this.copyPr));
|
||
oStyleCopy.Set_TableBand2Vert(oStyle.TableBand2Vert.Copy(this.copyPr));
|
||
oStyleCopy.Set_TableFirstCol(oStyle.TableFirstCol.Copy(this.copyPr));
|
||
oStyleCopy.Set_TableFirstRow(oStyle.TableFirstRow.Copy(this.copyPr));
|
||
oStyleCopy.Set_TableLastCol(oStyle.TableLastCol.Copy(this.copyPr));
|
||
oStyleCopy.Set_TableLastRow(oStyle.TableLastRow.Copy(this.copyPr));
|
||
oStyleCopy.Set_TableTLCell(oStyle.TableTLCell.Copy(this.copyPr));
|
||
oStyleCopy.Set_TableTRCell(oStyle.TableTRCell.Copy(this.copyPr));
|
||
oStyleCopy.Set_TableBLCell(oStyle.TableBLCell.Copy(this.copyPr));
|
||
oStyleCopy.Set_TableBRCell(oStyle.TableBRCell.Copy(this.copyPr));
|
||
oStyleCopy.Set_TableWholeTable(oStyle.TableWholeTable.Copy(this.copyPr));
|
||
}
|
||
if(oStyle.BasedOn)
|
||
{
|
||
oStyleCopy.Set_BasedOn(this.copyStyle(this.revisedDocument.Styles.Get(oStyle.BasedOn)));
|
||
}
|
||
this.originalDocument.Styles.Add(oStyleCopy);
|
||
this.StylesMap[oStyle.Id] = oStyleCopy.Id;
|
||
return oStyleCopy.Id;
|
||
};
|
||
CDocumentComparison.prototype.copyComment = function(sId)
|
||
{
|
||
if(!this.CommentsMap[sId])
|
||
{
|
||
const oComment = this.revisedDocument.Comments.Get_ById(sId);
|
||
if(oComment)
|
||
{
|
||
const oOrigComments = this.originalDocument.Comments;
|
||
if(oOrigComments)
|
||
{
|
||
const oOldParent = oComment.Parent;
|
||
oComment.Parent = oOrigComments;
|
||
const oCopyComment = oComment.Copy();
|
||
this.CommentsMap[sId] = oCopyComment;
|
||
this.CommentsMap[oCopyComment.GetId()] = oCopyComment;
|
||
if (this.oCommentManager.mapLink[sId])
|
||
{
|
||
this.oCommentManager.addToLink(oCopyComment.GetId(), sId);
|
||
}
|
||
this.originalDocument.Comments.Add(oCopyComment);
|
||
this.api.sync_AddComment(oCopyComment.Id, oCopyComment.Data);
|
||
oComment.Parent = oOldParent;
|
||
}
|
||
}
|
||
}
|
||
return this.CommentsMap[sId];
|
||
};
|
||
CDocumentComparison.prototype.getRevisedStyle = function(sStyleId)
|
||
{
|
||
if(this.revisedDocument)
|
||
{
|
||
return this.revisedDocument.Styles.Get(sStyleId);
|
||
}
|
||
return null;
|
||
};
|
||
CDocumentComparison.prototype.insertNodesToDocContent = function(oElement, nIndex, aInsert)
|
||
{
|
||
let k = 0;
|
||
for(let j = 0; j < aInsert.length; ++j)
|
||
{
|
||
let oChildElement;
|
||
let oOriginalElement;
|
||
if(aInsert[j].element.Get_Type)
|
||
{
|
||
oOriginalElement = aInsert[j].element;
|
||
oChildElement = oOriginalElement.Copy(oElement, oElement.DrawingDocument, this.copyPr);
|
||
}
|
||
else
|
||
{
|
||
if(aInsert[j].element.Parent && aInsert[j].element.Parent.Get_Type)
|
||
{
|
||
oOriginalElement = aInsert[j].element.Parent;
|
||
oChildElement = oOriginalElement.Copy(oElement, oElement.DrawingDocument, this.copyPr);
|
||
}
|
||
}
|
||
if(oChildElement)
|
||
{
|
||
|
||
if (oOriginalElement instanceof Paragraph) {
|
||
const oParaEnd = oOriginalElement.GetParaEndRun();
|
||
let oRunMoveMark = oParaEnd.GetLastTrackMoveMark();
|
||
if (oRunMoveMark) {
|
||
oRunMoveMark = oRunMoveMark.Copy();
|
||
const sMoveMarkName = this.oComparisonMoveMarkManager.getChangedMoveMarkName(oRunMoveMark);
|
||
oRunMoveMark.Name = sMoveMarkName;
|
||
const oCopyParaEnd = oChildElement.GetParaEndRun();
|
||
this.oComparisonMoveMarkManager.addRevisedMoveMarkToInserts(oRunMoveMark, oCopyParaEnd, oChildElement, true);
|
||
}
|
||
}
|
||
oElement.Internal_Content_Add(nIndex + k, oChildElement, false);
|
||
++k;
|
||
}
|
||
}
|
||
};
|
||
CDocumentComparison.prototype.applyChangesToChildNode = function(oChildNode)
|
||
{
|
||
const oChildElement = oChildNode.element;
|
||
if(oChildElement instanceof Paragraph || oChildElement instanceof AscCommonWord.CMockParagraph)
|
||
{
|
||
this.applyChangesToParagraph(oChildNode);
|
||
}
|
||
else if(oChildElement instanceof CDocumentContent)
|
||
{
|
||
this.applyChangesToDocContent(oChildNode);
|
||
}
|
||
else if(oChildElement instanceof CTable)
|
||
{
|
||
this.applyChangesToTable(oChildNode);
|
||
}
|
||
};
|
||
CDocumentComparison.prototype.applyChangesToDocContent = function(oNode)
|
||
{
|
||
|
||
if(oNode.partner)
|
||
{
|
||
this.compareRoots(oNode.element, oNode.partner.element);
|
||
return;
|
||
}
|
||
const oElement = oNode.element;
|
||
oNode.changes.sort(function(c1, c2){return c2.anchor.index - c1.anchor.index});
|
||
for(let i = 0; i < oNode.changes.length; ++i)
|
||
{
|
||
const oChange = oNode.changes[i];
|
||
for(let j = oChange.remove.length - 1; j > -1; --j)
|
||
{
|
||
const oChildNode = oChange.remove[j];
|
||
const oChildElement = oChildNode.element;
|
||
this.setReviewInfoRecursive(oChildElement, this.nRemoveChangesType);
|
||
}
|
||
this.insertNodesToDocContent(oElement, oChange.anchor.index + oChange.remove.length, oChange.insert);
|
||
}
|
||
for(let i = 0; i < oNode.children.length; ++i)
|
||
{
|
||
this.applyChangesToChildNode(oNode.children[i]);
|
||
}
|
||
};
|
||
CDocumentComparison.prototype.getReviewInfo = function()
|
||
{
|
||
let oReviewInfo = new AscWord.ReviewInfo();
|
||
oReviewInfo.Editor = this.api;
|
||
oReviewInfo.UserId = "";
|
||
oReviewInfo.MoveType = Asc.c_oAscRevisionsMove.NoMove;
|
||
oReviewInfo.PrevType = -1;
|
||
oReviewInfo.PrevInfo = null;
|
||
oReviewInfo.UserName = this.getUserName();
|
||
const oCore = this.revisedDocument.Core;
|
||
if(oCore && (oCore.modified instanceof Date))
|
||
{
|
||
oReviewInfo.DateTime = oCore.modified.getTime();
|
||
}
|
||
else
|
||
{
|
||
oReviewInfo.DateTime = (new Date()).getTime();
|
||
}
|
||
return oReviewInfo;
|
||
};
|
||
CDocumentComparison.prototype.getElementsForSetReviewType = function (oObject) {
|
||
if (!oObject) {
|
||
return [];
|
||
}
|
||
const arrReturnObjects = [];
|
||
const arrCheckObjects = [oObject];
|
||
|
||
while (arrCheckObjects.length) {
|
||
const oCheckObject = arrCheckObjects.pop();
|
||
if (oCheckObject.Type === para_Drawing && !this.options.textBoxes) {
|
||
continue;
|
||
}
|
||
if(oCheckObject.GetReviewInfo && oCheckObject.SetReviewTypeWithInfo)
|
||
{
|
||
arrReturnObjects.push(oCheckObject);
|
||
}
|
||
if(Array.isArray(oCheckObject.Content))
|
||
{
|
||
for(let i = 0; i < oCheckObject.Content.length; ++i)
|
||
{
|
||
arrCheckObjects.push(oCheckObject.Content[i]);
|
||
}
|
||
}
|
||
else if(AscCommon.isRealObject(oCheckObject.Content))
|
||
{
|
||
arrCheckObjects.push(oCheckObject.Content);
|
||
}
|
||
if(oCheckObject.Type === para_FootnoteReference || oCheckObject.Type === para_EndnoteReference)
|
||
{
|
||
arrCheckObjects.push(oCheckObject.Footnote);
|
||
}
|
||
if(oCheckObject.GetAllDocContents)
|
||
{
|
||
const aContents = oCheckObject.GetAllDocContents();
|
||
for(let i = 0; i < aContents.length; ++i)
|
||
{
|
||
arrCheckObjects.push(aContents[i]);
|
||
}
|
||
}
|
||
if(oCheckObject.Root)
|
||
{
|
||
arrCheckObjects.push(oCheckObject.Root);
|
||
}
|
||
if(AscCommon.isRealObject(oCheckObject.SectPr) && (oCheckObject instanceof Paragraph))
|
||
{
|
||
const oOrigSectPr = oCheckObject.SectPr;
|
||
let oOrigContent;
|
||
if(oOrigSectPr)
|
||
{
|
||
oOrigContent = oOrigSectPr.HeaderFirst && oOrigSectPr.HeaderFirst.Content;
|
||
if(oOrigContent)
|
||
{
|
||
arrCheckObjects.push(oOrigContent);
|
||
}
|
||
oOrigContent = oOrigSectPr.HeaderEven && oOrigSectPr.HeaderEven.Content;
|
||
if(oOrigContent)
|
||
{
|
||
arrCheckObjects.push(oOrigContent);
|
||
}
|
||
oOrigContent = oOrigSectPr.HeaderDefault && oOrigSectPr.HeaderDefault.Content;
|
||
if(oOrigContent)
|
||
{
|
||
arrCheckObjects.push(oOrigContent);
|
||
}
|
||
oOrigContent = oOrigSectPr.FooterFirst && oOrigSectPr.FooterFirst.Content;
|
||
if(oOrigContent)
|
||
{
|
||
arrCheckObjects.push(oOrigContent);
|
||
}
|
||
|
||
oOrigContent = oOrigSectPr.FooterEven && oOrigSectPr.FooterEven.Content;
|
||
if(oOrigContent)
|
||
{
|
||
arrCheckObjects.push(oOrigContent);
|
||
}
|
||
oOrigContent = oOrigSectPr.FooterDefault && oOrigSectPr.FooterDefault.Content;
|
||
if(oOrigContent)
|
||
{
|
||
arrCheckObjects.push(oOrigContent);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return arrReturnObjects;
|
||
};
|
||
|
||
CDocumentComparison.prototype.setReviewInfoForArray = function (arrNeedReviewObjects, nType, sCustomReviewUserName, nCustomReviewDate) {
|
||
for (let i = 0; i < arrNeedReviewObjects.length; i += 1) {
|
||
const oNeedReviewObject = arrNeedReviewObjects[i];
|
||
if (oNeedReviewObject.SetReviewTypeWithInfo) {
|
||
let oReviewInfo = this.getReviewInfo(sCustomReviewUserName, nCustomReviewDate);
|
||
let reviewType;
|
||
let moveReviewType;
|
||
if (this.bSaveCustomReviewType) {
|
||
reviewType = oNeedReviewObject.GetReviewType && oNeedReviewObject.GetReviewType();
|
||
moveReviewType = oNeedReviewObject.GetReviewMoveType && oNeedReviewObject.GetReviewMoveType();
|
||
}
|
||
const newReviewType = reviewType !== undefined && reviewType !== reviewtype_Common ? reviewType : null;
|
||
const newMoveReviewType = moveReviewType !== undefined && moveReviewType !== Asc.c_oAscRevisionsMove.NoMove ? moveReviewType : null;
|
||
if (!(AscFormat.isRealNumber(newReviewType) || AscFormat.isRealNumber(newMoveReviewType))) {
|
||
oNeedReviewObject.SetReviewTypeWithInfo(nType, oReviewInfo, false);
|
||
}
|
||
}
|
||
}
|
||
};
|
||
|
||
CDocumentComparison.prototype.setReviewInfoRecursive = function(oObject, nType)
|
||
{
|
||
const arrNeedReviewObjects = this.getElementsForSetReviewType(oObject);
|
||
this.setReviewInfoForArray(arrNeedReviewObjects, nType);
|
||
};
|
||
CDocumentComparison.prototype.saveReviewInfo = function(oNewObject, oOldObject)
|
||
{
|
||
if (oOldObject.GetReviewInfo && oNewObject.SetReviewTypeWithInfo) {
|
||
const reviewType = oOldObject.GetReviewType && oOldObject.GetReviewType();
|
||
const reviewInfo = oOldObject.GetReviewInfo();
|
||
oNewObject.SetReviewTypeWithInfo && oNewObject.SetReviewTypeWithInfo(reviewType, reviewInfo ? reviewInfo.Copy() : undefined, false);
|
||
}
|
||
};
|
||
CDocumentComparison.prototype.saveCustomReviewInfo = function(oObject, oOldObject, nType)
|
||
{
|
||
if (oOldObject.GetReviewInfo && oObject.SetReviewTypeWithInfo) {
|
||
const oldReviewType = oOldObject.GetReviewType && oOldObject.GetReviewType();
|
||
if (oldReviewType === reviewtype_Add || oldReviewType === reviewtype_Remove) {
|
||
const reviewInfo = oOldObject.GetReviewInfo().Copy();
|
||
oObject.SetReviewTypeWithInfo && oObject.SetReviewTypeWithInfo(oldReviewType, reviewInfo, false);
|
||
} else {
|
||
this.updateReviewInfo(oObject, nType);
|
||
}
|
||
}
|
||
};
|
||
CDocumentComparison.prototype.updateReviewInfo = function(oObject, nType)
|
||
{
|
||
if(oObject.GetReviewInfo && oObject.SetReviewTypeWithInfo)
|
||
{
|
||
const oReviewInfo = this.getReviewInfo();
|
||
oObject.SetReviewTypeWithInfo(nType, oReviewInfo, false);
|
||
|
||
}
|
||
};
|
||
CDocumentComparison.prototype.getNodeConstructor = function () {
|
||
return CNode;
|
||
};
|
||
|
||
CDocumentComparison.prototype.createNodeFromDocContent = function(oElement, oParentNode, oWordCounter, isOriginalDocument)
|
||
{
|
||
const oRet = this.createNode(oElement, oParentNode);
|
||
const bRoot = (oParentNode === null);
|
||
for(let i = 0; i < oElement.Content.length; ++i)
|
||
{
|
||
const oChElement = oElement.Content[i];
|
||
if(oChElement instanceof Paragraph)
|
||
{
|
||
if(bRoot)
|
||
{
|
||
oWordCounter = new WordCounter();
|
||
}
|
||
const oParagraphNode = this.createNodeFromRunContentElement(oChElement, oRet, oWordCounter, isOriginalDocument);
|
||
if(bRoot)
|
||
{
|
||
oParagraphNode.wordCounter = oWordCounter;
|
||
}
|
||
}
|
||
else if(oChElement instanceof CBlockLevelSdt)
|
||
{
|
||
if(bRoot)
|
||
{
|
||
oWordCounter = new WordCounter();
|
||
}
|
||
const oBlockNode = this.createNodeFromDocContent(oChElement.Content, oRet, oWordCounter, isOriginalDocument);
|
||
if(bRoot)
|
||
{
|
||
oBlockNode.wordCounter = oWordCounter;
|
||
}
|
||
}
|
||
else if(oChElement instanceof CTable)
|
||
{
|
||
if(this.options.getTables())
|
||
{
|
||
if(bRoot)
|
||
{
|
||
oWordCounter = new WordCounter();
|
||
}
|
||
const oTableNode = this.createNode(oChElement, oRet);
|
||
if(bRoot)
|
||
{
|
||
oWordCounter = new WordCounter();
|
||
oTableNode.wordCounter = oWordCounter;
|
||
}
|
||
for(let j = 0; j < oChElement.Content.length; ++j)
|
||
{
|
||
const oRowNode = this.createNode(oChElement.Content[j], oTableNode);
|
||
for(let k = 0; k < oChElement.Content[j].Content.length; ++k)
|
||
{
|
||
this.createNodeFromDocContent(oChElement.Content[j].Content[k].Content, oRowNode, oWordCounter, isOriginalDocument);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else if (oChElement instanceof AscCommonWord.CMockParagraph) {
|
||
if(bRoot)
|
||
{
|
||
oWordCounter = new WordCounter();
|
||
}
|
||
const oParagraphNode = this.createNodeFromRunContentElement(oChElement, oRet, oWordCounter, isOriginalDocument);
|
||
if(bRoot)
|
||
{
|
||
oParagraphNode.wordCounter = oWordCounter;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
const oNode = this.createNode(oChElement, oRet);
|
||
if(bRoot)
|
||
{
|
||
oWordCounter = new WordCounter();
|
||
oNode.wordCounter = oWordCounter;
|
||
}
|
||
}
|
||
|
||
}
|
||
return oRet;
|
||
};
|
||
|
||
CDocumentComparison.prototype.getTextElementConstructor = function () {
|
||
return CTextElement;
|
||
};
|
||
|
||
function isBreakWordElement(oRunElement) {
|
||
const bPunctuation = para_Text === oRunElement.Type && (AscCommon.g_aPunctuation[oRunElement.Value] && !EXCLUDED_PUNCTUATION[oRunElement.Value]);
|
||
return (oRunElement.Type === para_Space || oRunElement.Type === para_Tab
|
||
|| oRunElement.Type === para_Separator || oRunElement.Type === para_NewLine
|
||
|| oRunElement.Type === para_FootnoteReference
|
||
|| oRunElement.Type === para_EndnoteReference
|
||
|| bPunctuation);
|
||
}
|
||
|
||
CDocumentComparison.prototype._createNodeFromRun = function(oRun, oLastText, oWordCounter, oRet, TextElementConstructor, NodeConstructor, oReviewInfo) {
|
||
if(oRun.Content.length > 0)
|
||
{
|
||
if(!oLastText)
|
||
{
|
||
oLastText = new TextElementConstructor();
|
||
oLastText.setFirstRun(oRun);
|
||
}
|
||
if(oLastText.elements.length === 0)
|
||
{
|
||
oLastText.setFirstRun(oRun);
|
||
oLastText.setLastRun(oRun);
|
||
}
|
||
for(let j = 0; j < oRun.Content.length; ++j)
|
||
{
|
||
const oRunElement = oRun.Content[j];
|
||
if(isBreakWordElement(oRunElement) || this.isWordsByOneSymbol)
|
||
{
|
||
if(oLastText.elements.length > 0)
|
||
{
|
||
this.createNode(oLastText, oRet);
|
||
oLastText.updateHash(oWordCounter, this);
|
||
oLastText = new TextElementConstructor();
|
||
oLastText.setFirstRun(oRun);
|
||
}
|
||
if (this.options.footNotes || !(oRunElement.Type === para_FootnoteReference || oRunElement.Type === para_EndnoteReference)) {
|
||
oLastText.setLastRun(oRun);
|
||
oLastText.addToElements(oRunElement, oReviewInfo);
|
||
this.createNode(oLastText, oRet);
|
||
oLastText.updateHash(oWordCounter, this);
|
||
}
|
||
|
||
|
||
if (oLastText.elements.length > 0) {
|
||
oLastText = new TextElementConstructor();
|
||
oLastText.setFirstRun(oRun);
|
||
}
|
||
oLastText.setLastRun(oRun);
|
||
}
|
||
else if(oRunElement.Type === para_Drawing)
|
||
{
|
||
if(oLastText.elements.length > 0)
|
||
{
|
||
oLastText.updateHash(oWordCounter, this);
|
||
this.createNode(oLastText, oRet);
|
||
oLastText = new TextElementConstructor();
|
||
oLastText.setFirstRun(oRun);
|
||
oLastText.setLastRun(oRun);
|
||
}
|
||
oLastText.addToElements(oRun.Content[j], oReviewInfo);
|
||
this.createNode(oLastText, oRet);
|
||
oLastText = new TextElementConstructor();
|
||
oLastText.setFirstRun(oRun);
|
||
oLastText.setLastRun(oRun);
|
||
}
|
||
else if (oRunElement.Type === para_RevisionMove) {
|
||
if(oLastText.elements.length > 0)
|
||
{
|
||
oLastText.updateHash(oWordCounter, this);
|
||
this.createNode(oLastText, oRet);
|
||
oLastText = new TextElementConstructor();
|
||
oLastText.setFirstRun(oRun);
|
||
oLastText.setLastRun(oRun);
|
||
}
|
||
}
|
||
else if(oRunElement.Type === para_End)
|
||
{
|
||
if(oLastText.elements.length > 0)
|
||
{
|
||
oLastText.updateHash(oWordCounter, this);
|
||
this.createNode(oLastText, oRet);
|
||
oLastText = new TextElementConstructor();
|
||
oLastText.setFirstRun(oRun);
|
||
oLastText.setLastRun(oRun);
|
||
}
|
||
oLastText.setFirstRun(oRun);
|
||
oLastText.setLastRun(oRun);
|
||
// мы будем сравнивать ревью paraEnd отдельно, поскольку это единственный общий элемент в параграфе, до которого мы можем вставить любой различающийся контент
|
||
oLastText.addToElements(oRun.Content[j], {reviewType: reviewtype_Common, moveReviewType: Asc.c_oAscRevisionsMove.NoMove});
|
||
this.createNode(oLastText, oRet);
|
||
oLastText.updateHash(oWordCounter, this);
|
||
oLastText = new TextElementConstructor();
|
||
oLastText.setFirstRun(oRun);
|
||
oLastText.setLastRun(oRun);
|
||
}
|
||
else
|
||
{
|
||
if(oLastText.elements.length === 0)
|
||
{
|
||
oLastText.setFirstRun(oRun);
|
||
}
|
||
oLastText.setLastRun(oRun);
|
||
oLastText.addToElements(oRun.Content[j], oReviewInfo);
|
||
}
|
||
}
|
||
}
|
||
return oLastText;
|
||
};
|
||
|
||
CDocumentComparison.prototype.getCompareReviewInfo = function (oRun) {
|
||
|
||
};
|
||
|
||
CDocumentComparison.prototype.createNodeFromRun = function (oRun, oLastText, oWordCounter, oRet) {
|
||
const TextElementConstructor = this.getTextElementConstructor();
|
||
const NodeConstructor = this.getNodeConstructor();
|
||
const oReviewInfo = this.getCompareReviewInfo(oRun);
|
||
return this._createNodeFromRun(oRun, oLastText, oWordCounter, oRet, TextElementConstructor, NodeConstructor, oReviewInfo);
|
||
};
|
||
CDocumentComparison.prototype.createNodeFromRunContentElement = function(oElement, oParentNode, oWordCounter, isOriginalDocument)
|
||
{
|
||
this.oBookmarkManager.previousNode = null;
|
||
this.oCommentManager.previousNode = null;
|
||
const oRet = this.createNode(oElement, oParentNode);
|
||
let oLastText = null;
|
||
for(let i = 0; i < oElement.Content.length; ++i)
|
||
{
|
||
const oRun = oElement.Content[i];
|
||
if(oRun instanceof ParaRun)
|
||
{
|
||
oLastText = this.createNodeFromRun(oRun, oLastText, oWordCounter, oRet);
|
||
}
|
||
else if (oRun instanceof AscCommon.CParaRevisionMove)
|
||
{
|
||
if(oLastText && oLastText.elements.length > 0)
|
||
{
|
||
oLastText.updateHash(oWordCounter, this);
|
||
this.createNode(oLastText, oRet);
|
||
}
|
||
oLastText = null;
|
||
this.createNode(oRun, oRet);
|
||
if (!isOriginalDocument && !this.bSkipChangeMoveType) {
|
||
|
||
this.oComparisonMoveMarkManager.changeRevisedMoveMarkId(oRun, this);
|
||
this.oComparisonMoveMarkManager.updateInsertMoveMarkId(oRun);
|
||
}
|
||
this.oComparisonMoveMarkManager.updateMoveMarksStack(oRun);
|
||
|
||
oParentNode.bHaveMoveMarks = true;
|
||
}
|
||
else if (oRun instanceof AscCommonWord.CParagraphBookmark)
|
||
{
|
||
if (oLastText)
|
||
{
|
||
this.oBookmarkManager.addToStack(oRun, oLastText.elements.length);
|
||
}
|
||
else
|
||
{
|
||
this.oBookmarkManager.addToStack(oRun, 0);
|
||
}
|
||
}
|
||
else if (oRun instanceof AscCommon.ParaComment)
|
||
{
|
||
if (this.options.comments) {
|
||
const oComment = this.getComment(oRun.GetCommentId());
|
||
const oElement = new CCommentElement(oComment, oRun);
|
||
if (oLastText)
|
||
{
|
||
this.oCommentManager.addToStack(oElement, oLastText.elements.length);
|
||
}
|
||
else
|
||
{
|
||
this.oCommentManager.addToStack(oElement, 0);
|
||
}
|
||
} else {
|
||
this.oCommentManager.addToCheckSaveParaComment(oRun);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (oLastText && oLastText.elements.length > 0)
|
||
{
|
||
oLastText.updateHash(oWordCounter, this);
|
||
this.createNode(oLastText, oRet);
|
||
}
|
||
oLastText = null;
|
||
if (Array.isArray(oRun.Content))
|
||
{
|
||
this.createNodeFromRunContentElement(oRun, oRet, oWordCounter, isOriginalDocument);
|
||
}
|
||
else
|
||
{
|
||
this.createNode(oRun, oRet);
|
||
}
|
||
}
|
||
}
|
||
if(oLastText && oLastText.elements.length > 0)
|
||
{
|
||
oLastText.updateHash(oWordCounter, this);
|
||
this.createNode(oLastText, oRet);
|
||
}
|
||
return oRet;
|
||
};
|
||
CDocumentComparison.prototype.createFootNote = function()
|
||
{
|
||
return this.originalDocument.Footnotes.CreateFootnote();
|
||
};
|
||
CDocumentComparison.prototype.createEndNote = function()
|
||
{
|
||
return this.originalDocument.Endnotes.CreateEndnote();
|
||
};
|
||
CDocumentComparison.prototype.getComment = function(sId)
|
||
{
|
||
let oComment = this.originalDocument.Comments.Get_ById(sId);
|
||
if(oComment)
|
||
{
|
||
return oComment;
|
||
}
|
||
oComment = this.revisedDocument.Comments.Get_ById(sId);
|
||
return oComment || null;
|
||
};
|
||
|
||
CDocumentComparison.prototype.checkCopyParagraphElement = function (oOldItem, oNewItem, arrMoveMarks) {
|
||
return false;
|
||
};
|
||
|
||
CDocumentComparison.prototype.updateCommentsQuoteText = function ()
|
||
{
|
||
const oLogicDocument = this.originalDocument;
|
||
const oSelectionState = oLogicDocument.SaveDocumentState(false);
|
||
const oComments = oLogicDocument.GetCommentsManager();
|
||
for (let sId in oComments.m_arrCommentsById)
|
||
{
|
||
const oComment = oComments.m_arrCommentsById[sId];
|
||
if (oComment.SelectCommentText())
|
||
{
|
||
const oCommentData = oComment.GetData();
|
||
const sSelectedText = oLogicDocument.GetSelectedText(false);
|
||
if (sSelectedText !== oCommentData.GetQuoteText())
|
||
{
|
||
const oCopyData = oCommentData.Copy();
|
||
oCopyData.Set_QuoteText(sSelectedText === "" ? null : sSelectedText);
|
||
oComment.SetData(oCopyData);
|
||
this.api.sync_ChangeCommentData(oComment.Id, oCopyData);
|
||
}
|
||
}
|
||
}
|
||
oLogicDocument.LoadDocumentState(oSelectionState);
|
||
};
|
||
|
||
function CompareBinary(oApi, sBinary2, oOptions, bForceApplyChanges)
|
||
{
|
||
const oDoc1 = oApi.WordControl.m_oLogicDocument;
|
||
if(!window['NATIVE_EDITOR_ENJINE'])
|
||
{
|
||
const oCollaborativeEditing = oDoc1.CollaborativeEditing;
|
||
if(oCollaborativeEditing && !oCollaborativeEditing.Is_SingleUser())
|
||
{
|
||
oApi.sendEvent("asc_onError", Asc.c_oAscError.ID.CannotCompareInCoEditing, c_oAscError.Level.NoCritical);
|
||
return;
|
||
}
|
||
}
|
||
oApi.sync_StartAction(Asc.c_oAscAsyncActionType.BlockInteraction, Asc.c_oAscAsyncAction.SlowOperation);
|
||
const oldTrackRevisions = oDoc1.GetLocalTrackRevisions();
|
||
oDoc1.SetTrackRevisions(false);
|
||
let bHaveRevisons2 = false;
|
||
const oDoc2 = AscFormat.ExecuteNoHistory(function(){
|
||
const openParams = {disableRevisions: true, noSendComments: true, noGenerateSmartArts: true};
|
||
const oTempDocument = new CDocument(oApi.WordControl.m_oDrawingDocument, false);
|
||
const oBinaryFileReader = new AscCommonWord.BinaryFileReader(oTempDocument, openParams);
|
||
AscCommon.pptx_content_loader.Start_UseFullUrl(oApi.insertDocumentUrlsData);
|
||
if (!oBinaryFileReader.Read(sBinary2))
|
||
{
|
||
return null;
|
||
}
|
||
if(oTempDocument)
|
||
{
|
||
bHaveRevisons2 = oBinaryFileReader.oReadResult && oBinaryFileReader.oReadResult.hasRevisions;
|
||
}
|
||
return oTempDocument;
|
||
}, this, []);
|
||
oDoc1.SetTrackRevisions(oldTrackRevisions);
|
||
if(oDoc2)
|
||
{
|
||
const fCallback = function()
|
||
{
|
||
const oComp = new AscCommonWord.CDocumentComparison(oDoc1, oDoc2, oOptions ? oOptions : new ComparisonOptions());
|
||
oComp.compare();
|
||
};
|
||
|
||
if(window['NATIVE_EDITOR_ENJINE'] || bForceApplyChanges)
|
||
{
|
||
fCallback();
|
||
}
|
||
else
|
||
{
|
||
|
||
oDoc1.TrackRevisionsManager.ContinueTrackRevisions();
|
||
if(oDoc1.TrackRevisionsManager.Have_Changes() || bHaveRevisons2)
|
||
{
|
||
|
||
oApi.sync_EndAction(Asc.c_oAscAsyncActionType.BlockInteraction, Asc.c_oAscAsyncAction.SlowOperation);
|
||
oApi.sendEvent("asc_onAcceptChangesBeforeCompare", function (bAccept) {
|
||
if(bAccept){
|
||
oApi.sync_StartAction(Asc.c_oAscAsyncActionType.BlockInteraction, Asc.c_oAscAsyncAction.SlowOperation);
|
||
fCallback();
|
||
}
|
||
})
|
||
}
|
||
else
|
||
{
|
||
fCallback();
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
AscCommon.pptx_content_loader.End_UseFullUrl();
|
||
}
|
||
}
|
||
|
||
|
||
function CompareDocuments(oApi, oTmpDocument)
|
||
{
|
||
oApi.insertDocumentUrlsData = {
|
||
imageMap: oTmpDocument["GetImageMap"](), documents: [], convertCallback: function (_api, url) {
|
||
}, endCallback: function (_api) {
|
||
}
|
||
};
|
||
CompareBinary(oApi, oTmpDocument["GetBinary"](), null, true);
|
||
oApi.insertDocumentUrlsData = null;
|
||
}
|
||
|
||
function CMoveMarkComparisonManager() {
|
||
this.oChangeRevisedMarkId = {};
|
||
this.oChangeRevisedMarkIdRevert = {};
|
||
this.oRevisedMoveMarks = {};
|
||
this.oInsertMoveMarkId = {};
|
||
this.oRevisedMoveMarksInserts = {};
|
||
this.checkMoveMarks = [];
|
||
this.oRunIdMoveNameRelation = {};
|
||
this.oRevertMoveTypeByName = {};
|
||
this.moveMarksStack = [];
|
||
this.isResolveConflictMode = false;
|
||
}
|
||
|
||
CMoveMarkComparisonManager.prototype.changeRevisedMoveMarkId = function (oMoveMark, oComparison) {
|
||
if (!this.oChangeRevisedMarkId[oMoveMark.Name]) {
|
||
this.oChangeRevisedMarkId[oMoveMark.Name] = oComparison.originalDocument.TrackRevisionsManager.GetNewMoveId();
|
||
this.oChangeRevisedMarkIdRevert[this.oChangeRevisedMarkId[oMoveMark.Name]] = oMoveMark.Name;
|
||
}
|
||
oMoveMark.Name = this.oChangeRevisedMarkId[oMoveMark.Name];
|
||
};
|
||
|
||
CMoveMarkComparisonManager.prototype.updateInsertMoveMarkId = function (oMoveMark) {
|
||
this.oInsertMoveMarkId[oMoveMark.Name] = true;
|
||
|
||
if (!this.oRevisedMoveMarks[oMoveMark.Name]) {
|
||
this.oRevisedMoveMarks[oMoveMark.Name] = [];
|
||
}
|
||
this.oRevisedMoveMarks[oMoveMark.Name].push(oMoveMark);
|
||
};
|
||
|
||
CMoveMarkComparisonManager.prototype.updateMoveMarksStack = function (oMoveMark) {
|
||
if (this.isResolveConflictMode) {
|
||
return;
|
||
}
|
||
if (oMoveMark.Start) {
|
||
this.moveMarksStack.push(oMoveMark);
|
||
} else {
|
||
this.moveMarksStack.pop();
|
||
}
|
||
};
|
||
|
||
CMoveMarkComparisonManager.prototype.resetMoveMarkStack = function () {
|
||
if (this.isResolveConflictMode) {
|
||
return;
|
||
}
|
||
this.moveMarksStack = [];
|
||
};
|
||
|
||
CMoveMarkComparisonManager.prototype.addMoveMarkNameRunRelation = function (sMoveMarkName, oRun) {
|
||
if (sMoveMarkName) {
|
||
if (!this.oRevertMoveTypeByName[sMoveMarkName]) {
|
||
this.oRevertMoveTypeByName[sMoveMarkName] = [];
|
||
}
|
||
this.oRevertMoveTypeByName[sMoveMarkName].push(oRun);
|
||
}
|
||
};
|
||
|
||
CMoveMarkComparisonManager.prototype.addRunMoveMarkNameRelation = function (sMoveMarkName, oRun) {
|
||
if (sMoveMarkName) {
|
||
this.oRunIdMoveNameRelation[oRun.Id] = sMoveMarkName;
|
||
}
|
||
};
|
||
|
||
CMoveMarkComparisonManager.prototype.getChangedMoveMarkName = function (oMoveMark) {
|
||
return this.oChangeRevisedMarkId[oMoveMark.Name];
|
||
};
|
||
|
||
CMoveMarkComparisonManager.prototype.getMoveMarkNameByRun = function (oRun) {
|
||
return this.oRunIdMoveNameRelation[oRun.Id]
|
||
};
|
||
|
||
CMoveMarkComparisonManager.prototype.checkMoveMarksContentNode = function (oNode) {
|
||
if (oNode.bHaveMoveMarks) {
|
||
this.checkMoveMarks.push(oNode.element);
|
||
}
|
||
};
|
||
|
||
CMoveMarkComparisonManager.prototype.getCheckMoveMarkElements = function () {
|
||
return this.checkMoveMarks;
|
||
};
|
||
|
||
CMoveMarkComparisonManager.prototype.addRevisedMoveMarkToInserts = function (oMoveMark, oFrontElement, oParentElement, bIsParaEnd) {
|
||
if (!this.oRevisedMoveMarksInserts[oFrontElement.Id]) {
|
||
this.oRevisedMoveMarksInserts[oFrontElement.Id] = [];
|
||
}
|
||
this.oRevisedMoveMarksInserts[oFrontElement.Id].push({isParaEnd: bIsParaEnd, frontElement: oFrontElement, parentElement: oParentElement, moveMark: oMoveMark});
|
||
};
|
||
|
||
CMoveMarkComparisonManager.prototype.getRevisedMoveMarkToInserts = function () {
|
||
return this.oRevisedMoveMarksInserts;
|
||
};
|
||
|
||
CMoveMarkComparisonManager.prototype.executeResolveConflictMode = function (callback) {
|
||
const bOldModeValue = this.isResolveConflictMode;
|
||
this.isResolveConflictMode = true;
|
||
callback();
|
||
this.isResolveConflictMode = bOldModeValue;
|
||
};
|
||
|
||
function CComparisonBookmarkManager()
|
||
{
|
||
this.mapNamesForMerge = {};
|
||
this.mapIdToBookmarkId = {};
|
||
this.needUpdateBookmarks = false;
|
||
this.bookmarkStack = [];
|
||
this.previousNode = null;
|
||
}
|
||
|
||
CComparisonBookmarkManager.prototype.init = function (oMainDocument, oRevisedDocument)
|
||
{
|
||
oRevisedDocument.UpdateBookmarks();
|
||
oMainDocument.UpdateBookmarks();
|
||
const arrRevisedBookmarks = oRevisedDocument.BookmarksManager.Bookmarks;
|
||
const arrMainBookmarks = oMainDocument.BookmarksManager.Bookmarks;
|
||
for (let i = 0; i < arrRevisedBookmarks.length; i += 1)
|
||
{
|
||
const oBookmark = arrRevisedBookmarks[i][0];
|
||
this.mapNamesForMerge[oBookmark.GetBookmarkName()] = arrRevisedBookmarks[i];
|
||
}
|
||
for (let i = 0; i < arrMainBookmarks.length; i += 1)
|
||
{
|
||
const oBookmark = arrMainBookmarks[i][0];
|
||
delete this.mapNamesForMerge[oBookmark.GetBookmarkName()];
|
||
}
|
||
for (let sName in this.mapNamesForMerge)
|
||
{
|
||
this.needUpdateBookmarks = true;
|
||
const oStartBookmark = this.mapNamesForMerge[sName][0];
|
||
const oEndBookmark = this.mapNamesForMerge[sName][1];
|
||
const nNewId = oMainDocument.BookmarksManager.GetNewBookmarkId();
|
||
this.addToLink(oStartBookmark.GetId(), nNewId);
|
||
this.addToLink(oEndBookmark.GetId(), nNewId);
|
||
}
|
||
};
|
||
CComparisonBookmarkManager.prototype.addToLink = function (sId, nBookmarkId) {
|
||
this.mapIdToBookmarkId[sId] = nBookmarkId;
|
||
};
|
||
CComparisonBookmarkManager.prototype.isSkip = function (oElement)
|
||
{
|
||
if (oElement instanceof AscCommonWord.CParagraphBookmark)
|
||
{
|
||
return !this.mapIdToBookmarkId[oElement.GetId()];
|
||
}
|
||
return false;
|
||
};
|
||
CComparisonBookmarkManager.prototype.getId = function (oBookmark)
|
||
{
|
||
const sId = this.mapIdToBookmarkId[oBookmark.GetId()];
|
||
if (sId) {
|
||
return parseInt(sId, 10);
|
||
}
|
||
};
|
||
CComparisonBookmarkManager.prototype.addToStack = function (oBookmark, nInsertIndex)
|
||
{
|
||
if (!this.isSkip(oBookmark))
|
||
{
|
||
const oLabel = new CBookmarkLabel(oBookmark, nInsertIndex);
|
||
this.bookmarkStack.push(oLabel);
|
||
}
|
||
};
|
||
|
||
CComparisonBookmarkManager.prototype.updateBookmarksStack = function (oNode)
|
||
{
|
||
const arrNextStack = [];
|
||
const mapCheckAdd = {};
|
||
const oPreviousElement = this.previousNode && this.previousNode.element;
|
||
for (let i = 0; i < this.bookmarkStack.length; i += 1)
|
||
{
|
||
const oLabel = this.bookmarkStack[i];
|
||
const oBookmark = oLabel.bookmark;
|
||
if (oLabel.insertIndex === oNode.element.elements.length)
|
||
{
|
||
oLabel.insertIndex = 0;
|
||
arrNextStack.push(oLabel);
|
||
}
|
||
else if (!mapCheckAdd[oBookmark.GetBookmarkId()] && oLabel.insertIndex === 0 && (oPreviousElement instanceof CTextElement) && !oBookmark.IsStart())
|
||
{
|
||
oPreviousElement.addBookmark(oBookmark, oPreviousElement.elements.length);
|
||
}
|
||
else
|
||
{
|
||
oNode.addBookmark(oBookmark, oLabel.insertIndex);
|
||
mapCheckAdd[oBookmark.GetBookmarkId()] = true;
|
||
}
|
||
}
|
||
this.bookmarkStack = arrNextStack;
|
||
};
|
||
|
||
function CBookmarkLabel(oBookmark, nInsertIndex)
|
||
{
|
||
this.bookmark = oBookmark;
|
||
this.insertIndex = nInsertIndex;
|
||
}
|
||
|
||
function CComparisonCommentManager(comparison)
|
||
{
|
||
this.comparison = comparison;
|
||
this.commentsStack = [];
|
||
this.previousNode = null;
|
||
this.mapDelete = {};
|
||
this.mapChecked = {};
|
||
this.mapLink = {};
|
||
this.mapMergeLater = {};
|
||
this.checkSkipParaComment = {};
|
||
this.savedParaComments = {};
|
||
}
|
||
|
||
CComparisonCommentManager.prototype.addToCheckSaveParaComment = function (oParaComment) {
|
||
const sCommentId = oParaComment.GetCommentId();
|
||
if (!this.checkSkipParaComment[sCommentId]) {
|
||
this.checkSkipParaComment[sCommentId] = Array(2);
|
||
}
|
||
if (oParaComment.IsCommentStart()) {
|
||
this.checkSkipParaComment[sCommentId][0] = oParaComment;
|
||
} else {
|
||
this.checkSkipParaComment[sCommentId][1] = oParaComment;
|
||
}
|
||
};
|
||
CComparisonCommentManager.prototype.generateSavedParaComments = function () {
|
||
for (let sCommentId in this.checkSkipParaComment) {
|
||
const arrParaComments = this.checkSkipParaComment[sCommentId];
|
||
const oStartParaComment = arrParaComments[0];
|
||
const oEndParaComment = arrParaComments[1];
|
||
if (oStartParaComment && oEndParaComment) {
|
||
if (oStartParaComment.Paragraph === oEndParaComment.Paragraph && oStartParaComment.Parent === oEndParaComment.Parent) {
|
||
this.savedParaComments[oStartParaComment.Id] = true;
|
||
this.savedParaComments[oEndParaComment.Id] = true;
|
||
}
|
||
}
|
||
}
|
||
this.checkSkipParaComment = {};
|
||
}
|
||
CComparisonCommentManager.prototype.addToLink = function (sKey, sValue)
|
||
{
|
||
this.mapLink[sKey] = sValue;
|
||
};
|
||
CComparisonCommentManager.prototype.getAddedComment = function (oData)
|
||
{
|
||
const oComments = this.comparison.originalDocument.Comments;
|
||
const oComment = new AscCommon.CComment(oComments, oData);
|
||
oComments.Add(oComment);
|
||
this.comparison.api.sync_AddComment(oComment.Id, oData);
|
||
return oComment;
|
||
};
|
||
CComparisonCommentManager.prototype.getMergeLater = function (sCommentId)
|
||
{
|
||
return this.mapMergeLater[sCommentId];
|
||
};
|
||
CComparisonCommentManager.prototype.addToMergeLater = function (oParaComment, sCommentId)
|
||
{
|
||
if (!this.mapMergeLater[sCommentId])
|
||
{
|
||
this.mapMergeLater[sCommentId] = [];
|
||
}
|
||
this.mapMergeLater[sCommentId].push(oParaComment);
|
||
};
|
||
CComparisonCommentManager.prototype.pushToArrInsertContentFromMerge = function (oParaComment, arrContentToInsert)
|
||
{
|
||
if (!oParaComment.IsCommentStart())
|
||
return;
|
||
const sCommentId = oParaComment.GetCommentId();
|
||
const arrMerge = this.getMergeLater(sCommentId);
|
||
if (arrMerge)
|
||
{
|
||
arrContentToInsert.push.apply(arrContentToInsert, arrMerge);
|
||
}
|
||
};
|
||
CComparisonCommentManager.prototype.applyCommentFromData = function (oData, arrCommentElements, sRevisedQuoteText, sRevisedCommentId)
|
||
{
|
||
const oCopyData = oData.Copy();
|
||
oCopyData.Set_QuoteText(sRevisedQuoteText);
|
||
const oComment = this.getAddedComment(oCopyData);
|
||
const oStartParaComment = new AscCommon.ParaComment(true, oComment.GetId());
|
||
const oEndParaComment = new AscCommon.ParaComment(false, oComment.GetId());
|
||
oComment.SetRangeStart(oStartParaComment.GetId());
|
||
oComment.SetRangeEnd(oEndParaComment.GetId());
|
||
const oEndCommentElement = new CCommentElement(oComment, oEndParaComment);
|
||
arrCommentElements.push(oEndCommentElement);
|
||
this.addToMergeLater(oStartParaComment, sRevisedCommentId);
|
||
};
|
||
CComparisonCommentManager.prototype.getSortedFunction = function ()
|
||
{
|
||
return function (a, b)
|
||
{
|
||
const nQuoteCommentDifference = a.quoteDifference - b.quoteDifference;
|
||
if (nQuoteCommentDifference !== 0)
|
||
{
|
||
return nQuoteCommentDifference;
|
||
}
|
||
return a.commentDifference - b.commentDifference;
|
||
}
|
||
};
|
||
|
||
CComparisonCommentManager.prototype.checkComments = function (arrMainComments, arrRevisedComments, arrCommentElements)
|
||
{
|
||
if (!arrRevisedComments)
|
||
return;
|
||
if (!arrMainComments)
|
||
{
|
||
arrMainComments = [];
|
||
}
|
||
|
||
const arrComparing = [];
|
||
const fSortedFunction = this.getSortedFunction();
|
||
for (let i = 0; i < arrRevisedComments.length; i++)
|
||
{
|
||
const oRevisedElement = arrRevisedComments[i];
|
||
const sRevisedCommentId = oRevisedElement.element.GetCommentId();
|
||
const bIsStart = oRevisedElement.element.IsCommentStart();
|
||
if (!this.isChecked(sRevisedCommentId) && !bIsStart)
|
||
{
|
||
this.check(sRevisedCommentId);
|
||
for (let j = 0; j < arrMainComments.length; j++)
|
||
{
|
||
const oMainElement = arrMainComments[j];
|
||
const sMainCommentId = oMainElement.element.GetCommentId();
|
||
if (!this.isForDelete(sMainCommentId))
|
||
{
|
||
const oDifference = oMainElement.getDifference(oRevisedElement);
|
||
|
||
if (oDifference)
|
||
{
|
||
arrComparing.push(oDifference);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
arrComparing.sort(fSortedFunction);
|
||
for (let i = 0; i < arrComparing.length; i++)
|
||
{
|
||
const oMainElement = arrComparing[i].mainElement;
|
||
const oRevisedElement = arrComparing[i].anotherElement;
|
||
const sRevisedCommentId = oRevisedElement.getCommentId();
|
||
const sMainCommentId = oMainElement.getCommentId();
|
||
if (!this.mapLink[sRevisedCommentId] && !this.isForDelete(sMainCommentId))
|
||
{
|
||
if (arrComparing[i].arrData)
|
||
{
|
||
for (let j = 0; j < arrComparing[i].arrData.length; j += 1)
|
||
{
|
||
this.applyCommentFromData(arrComparing[i].arrData[j], arrCommentElements, oRevisedElement.getQuoteText(), sRevisedCommentId);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
const arrRevisedAnswers = oRevisedElement.getAnswers();
|
||
const arrMainAnswers = oMainElement.getAnswers();
|
||
const oComment = this.getComment(sRevisedCommentId);
|
||
if (oComment)
|
||
{
|
||
const oCopyData = oComment.Data.Copy();
|
||
for (let j = arrRevisedAnswers.length; j < arrMainAnswers.length; j += 1)
|
||
{
|
||
const oCopyAnswer = arrMainAnswers[j].Copy();
|
||
oCopyData.Add_Reply(oCopyAnswer);
|
||
}
|
||
oComment.SetData(oCopyData);
|
||
this.comparison.api.sync_ChangeCommentData(oComment.Id, oCopyData);
|
||
}
|
||
}
|
||
this.addToLink(sRevisedCommentId, sMainCommentId);
|
||
this.addToDelete(sMainCommentId);
|
||
}
|
||
}
|
||
};
|
||
|
||
CComparisonCommentManager.prototype.check = function (sCommentId)
|
||
{
|
||
this.mapChecked[sCommentId] = true;
|
||
};
|
||
CComparisonCommentManager.prototype.isChecked = function (sCommentId)
|
||
{
|
||
return this.mapChecked[sCommentId];
|
||
};
|
||
CComparisonCommentManager.prototype.isForDelete = function (sCommentId)
|
||
{
|
||
return this.mapDelete[sCommentId];
|
||
};
|
||
CComparisonCommentManager.prototype.addToDelete = function (sCommentId)
|
||
{
|
||
this.mapDelete[sCommentId] = true;
|
||
};
|
||
|
||
CComparisonCommentManager.prototype.getComment = function (sCommentId)
|
||
{
|
||
if (this.comparison.CommentsMap[sCommentId])
|
||
return this.comparison.CommentsMap[sCommentId];
|
||
|
||
return this.comparison.getComment(sCommentId);
|
||
};
|
||
CComparisonCommentManager.prototype.addToStack = function (oComment, nInsertIndex)
|
||
{
|
||
const oLabel = new CCommentLabel(oComment, nInsertIndex);
|
||
this.commentsStack.push(oLabel);
|
||
};
|
||
|
||
CComparisonCommentManager.prototype.updateCommentsStack = function (oNode)
|
||
{
|
||
const arrNextStack = [];
|
||
const mapCheckAdd = {};
|
||
const oPreviousElement = this.previousNode && this.previousNode.element;
|
||
for (let i = 0; i < this.commentsStack.length; i += 1)
|
||
{
|
||
const oLabel = this.commentsStack[i];
|
||
const oParaComment = oLabel.comment.element;
|
||
if (oLabel.insertIndex === oNode.element.elements.length)
|
||
{
|
||
oLabel.insertIndex = 0;
|
||
arrNextStack.push(oLabel);
|
||
}
|
||
else if (!mapCheckAdd[oParaComment.GetCommentId()] && oLabel.insertIndex === 0 && (oPreviousElement instanceof CTextElement) && !oParaComment.IsCommentStart())
|
||
{
|
||
oPreviousElement.addComment(oLabel.comment, oPreviousElement.elements.length);
|
||
}
|
||
else
|
||
{
|
||
oNode.addComment(oLabel.comment, oLabel.insertIndex);
|
||
mapCheckAdd[oParaComment.GetCommentId()] = true;
|
||
}
|
||
}
|
||
this.commentsStack = arrNextStack;
|
||
};
|
||
|
||
function CCommentLabel(oParaComment, nInsertIndex)
|
||
{
|
||
this.comment = oParaComment;
|
||
this.insertIndex = nInsertIndex;
|
||
}
|
||
|
||
function CRunCollector(arrElements, parentParagraph) {
|
||
this.elements = arrElements;
|
||
this.runIndex = null;
|
||
this.runElementIndex = null;
|
||
this.elementIndex = null;
|
||
this.innerElementIndex = null;
|
||
this.parent = null;
|
||
this.collectTextPrChange = null;
|
||
this.collectReviewChange = null;
|
||
|
||
this.init(parentParagraph);
|
||
}
|
||
|
||
CRunCollector.prototype.init = function (parentParagraph) {
|
||
this.elementIndex = this.elements.length - 1;
|
||
const oLastElement = this.elements[this.elementIndex];
|
||
this.innerElementIndex = oLastElement.elements.length - 1;
|
||
const oLastRun = oLastElement.lastRun;
|
||
const oParent = parentParagraph || oLastRun.GetParent();
|
||
this.parent = oParent;
|
||
const oContent = oParent.Content;
|
||
for (let i = oContent.length - 1; i >= 0; i -= 1) {
|
||
const oRun = oContent[i];
|
||
if (oRun === oLastRun) {
|
||
this.runIndex = i;
|
||
break;
|
||
}
|
||
}
|
||
const oLastRunElement = oLastElement.elements[this.innerElementIndex];
|
||
for (let i = oLastRun.Content.length - 1; i >= 0; i -= 1) {
|
||
const oElement = oLastRun.Content[i];
|
||
if (oElement === oLastRunElement) {
|
||
this.runElementIndex = i;
|
||
break;
|
||
}
|
||
}
|
||
};
|
||
|
||
CRunCollector.prototype.getCurrentElement = function () {
|
||
return this.elements[this.elementIndex];
|
||
};
|
||
|
||
CRunCollector.prototype.skipTo = function (elementIndex, innerElementIndex) {
|
||
while (this.elementIndex > elementIndex) {
|
||
let countElements = this.innerElementIndex + 1;
|
||
while (countElements) {
|
||
if (this.runElementIndex + 1 > countElements) {
|
||
this.runElementIndex -= countElements;
|
||
countElements = 0;
|
||
} else {
|
||
countElements -= this.runElementIndex + 1;
|
||
this.nextRun();
|
||
}
|
||
}
|
||
this.elementIndex -= 1;
|
||
const oElement = this.elements[this.elementIndex];
|
||
if (oElement) {
|
||
this.innerElementIndex = oElement.elements.length - 1;
|
||
}
|
||
}
|
||
if (this.innerElementIndex > innerElementIndex) {
|
||
let countElements = this.innerElementIndex - innerElementIndex;
|
||
while (countElements) {
|
||
if (this.runElementIndex + 1 > countElements) {
|
||
this.runElementIndex -= countElements;
|
||
countElements = 0;
|
||
} else {
|
||
countElements -= this.runElementIndex + 1;
|
||
this.nextRun();
|
||
}
|
||
}
|
||
this.innerElementIndex = innerElementIndex;
|
||
}
|
||
};
|
||
CRunCollector.prototype.dropLastCollect = function ()
|
||
{
|
||
if (this.collectTextPrChange) {
|
||
this.collectTextPrChange.dropLastRun();
|
||
}
|
||
if (this.collectReviewChange) {
|
||
this.collectReviewChange.dropLastRun();
|
||
}
|
||
};
|
||
CRunCollector.prototype.setCollectTextPrRuns = function (oChange) {
|
||
this.collectTextPrChange = oChange;
|
||
};
|
||
CRunCollector.prototype.setCollectReviewRuns = function (oChange) {
|
||
this.collectReviewChange = oChange;
|
||
}
|
||
CRunCollector.prototype.addToCollectTextPr = function (oRun) {
|
||
if (this.collectTextPrChange) {
|
||
this.collectTextPrChange.addRun(oRun);
|
||
}
|
||
};
|
||
CRunCollector.prototype.addToCollectReviewChange = function (oRun) {
|
||
if (this.collectReviewChange) {
|
||
this.collectReviewChange.addRun(oRun);
|
||
}
|
||
};
|
||
CRunCollector.prototype.addToCollectBackTextPr = function (oRun)
|
||
{
|
||
if (this.collectTextPrChange) {
|
||
this.collectTextPrChange.addRunBack(oRun);
|
||
}
|
||
};
|
||
CRunCollector.prototype.addToCollectBackReviewChange = function (oRun)
|
||
{
|
||
if (this.collectReviewChange) {
|
||
this.collectReviewChange.addRunBack(oRun);
|
||
}
|
||
};
|
||
CRunCollector.prototype.addToCollect = function (oRun)
|
||
{
|
||
this.addToCollectReviewChange(oRun);
|
||
this.addToCollectTextPr(oRun);
|
||
};
|
||
CRunCollector.prototype.addToCollectBack = function (oRun)
|
||
{
|
||
this.addToCollectBackTextPr(oRun);
|
||
this.addToCollectBackReviewChange(oRun);
|
||
};
|
||
CRunCollector.prototype.addToCollectCurrentRun = function ()
|
||
{
|
||
this.addToCollect(this.getRun());
|
||
};
|
||
CRunCollector.prototype.nextRun = function () {
|
||
do {
|
||
this.runIndex -= 1;
|
||
} while (!(this.getRun() instanceof AscCommonWord.ParaRun) && this.runIndex >= 0 || this.getRun().Content.length === 0)
|
||
const oCurRun = this.getRun();
|
||
if (oCurRun) {
|
||
this.addToCollectCurrentRun();
|
||
this.runElementIndex = oCurRun.Content.length - 1;
|
||
}
|
||
};
|
||
CRunCollector.prototype.getRun = function () {
|
||
const oContent = this.parent.Content;
|
||
return oContent[this.runIndex];
|
||
};
|
||
CRunCollector.prototype.splitCurrentRun = function (bAfter)
|
||
{
|
||
const oRun = this.getRun();
|
||
return oRun.Split2(bAfter ? this.runElementIndex + 1 : this.runElementIndex, this.parent, this.runIndex);
|
||
};
|
||
|
||
window['AscCommonWord']["CompareBinary"] = window['AscCommonWord'].CompareBinary = CompareBinary;
|
||
window['AscCommonWord']["ComparisonOptions"] = window['AscCommonWord'].ComparisonOptions = ComparisonOptions;
|
||
window['AscCommonWord']['CompareDocuments'] = CompareDocuments;
|
||
window['AscCommonWord'].CDocumentComparison = CDocumentComparison;
|
||
window['AscCommonWord'].CNode = CNode;
|
||
window['AscCommonWord'].CTextElement = CTextElement;
|
||
window['AscCommonWord'].isBreakWordElement = isBreakWordElement;
|
||
})();
|