Files
DocumentServer-v-9.2.0/sdkjs/word/Editor/revisions/track-revisions-manager.js
Yajbir Singh f1b860b25c
Some checks failed
check / markdownlint (push) Has been cancelled
check / spellchecker (push) Has been cancelled
updated
2025-12-11 19:03:17 +05:30

1401 lines
40 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* (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(window)
{
let elementToCheck = {};
function checkElementInRevision(element)
{
if (!element)
return;
let logicDocument = element.GetLogicDocument();
if (!element.GetLogicDocument())
{
elementToCheck[element.GetId()] = element;
return;
}
if (!logicDocument || !logicDocument.IsDocumentEditor())
return;
logicDocument.GetTrackRevisionsManager().CheckElement(element);
}
function haveElementToCheck()
{
for (let id in elementToCheck)
{
return true;
}
return false;
}
function flushElementToCheck()
{
for (let id in elementToCheck)
{
let element = elementToCheck[id];
let logicDocument = element.GetLogicDocument();
if (!logicDocument || !logicDocument.IsDocumentEditor())
continue;
logicDocument.GetTrackRevisionsManager().CheckElement(elementToCheck[id]);
}
elementToCheck = {};
}
// ВАЖНО: CheckArray - специальный массив-дублер для мапа CheckMap, для более быстрого выполнения функции
// ContinueTrackRevisions. Заметим, что на функции CompleteTrackChangesForElements мы не выкидываем
// элемент из CheckArray, но выкидываем из CheckMap. Это не страшно, т.к. при последующей проверке по
// массиву CheckArray элемент в CheckMap просто не найдется, а из CheckArray мы его выкинем, и, тем самым,
// CheckArray и CheckMap синхронизуются.
/**
* Класс для отслеживания изменений в режиме рецензирования
* @param {AscWord.CDocument} oLogicDocument
* @constructor
*/
function CTrackRevisionsManager(oLogicDocument)
{
this.LogicDocument = oLogicDocument;
this.CheckMap = {}; // Элементы, которые нужно проверить
this.CheckArray = []; // Дублирующий массив элементов, которые мы проверяем в ContinueTrackRevisions
this.Changes = {}; // Объект с ключом - Id параграфа, в котором лежит массив изменений
this.ChangesOutline = []; // Упорядоченный массив с объектами, в которых есть изменения в рецензировании
this.CurChange = null; // Текущее изменение
this.CurElement = null; // Элемент с текущим изменением
this.SelectedChanges = []; // Список изменений, попавших в выделение
this.PrevSelectedChanges = [];
this.PrevShowChanges = true;
this.MoveId = 1;
this.MoveMarks = {};
this.ProcessMove = null;
this.SkipPreDeleteMoveMarks = false;
}
/**
* Отправляем элемент на проверку на наличие рецензирования
* @param oElement {AscWord.Paragraph | AscWord.CTable}
*/
CTrackRevisionsManager.prototype.CheckElement = function(oElement)
{
if (!(oElement instanceof AscWord.Paragraph) && !(oElement instanceof AscWord.CTable))
return;
let Id = oElement.GetId();
if (!this.CheckMap[Id])
{
this.CheckMap[Id] = oElement;
this.CheckArray.push(oElement);
}
};
/**
* Добавляем изменение в рецензировании по Id элемента
* @param sId {string}
* @param oChange {CRevisionsChange}
*/
CTrackRevisionsManager.prototype.AddChange = function(sId, oChange)
{
if (this.private_CheckChangeObject(sId))
this.Changes[sId].push(oChange);
};
/**
* Получаем массив изменений заданного элемента
* @param sElementId
* @returns {CRevisionsChange[]}
*/
CTrackRevisionsManager.prototype.GetElementChanges = function(sElementId)
{
if (this.Changes[sElementId])
return this.Changes[sElementId];
return [];
};
CTrackRevisionsManager.prototype.ContinueTrackRevisions = function(isComplete)
{
if (this.IsAllChecked())
return;
flushElementToCheck();
var nStartTime = performance.now();
// За раз обрабатываем не больше 500 параграфов либо не больше 4мс по времени,
// чтобы не подвешивать клиент на открытии файлов
const nMaxCounter = 500;
let nCounter = 0;
var bNeedUpdate = false;
let nIndex = this.CheckArray.length - 1;
for (; nIndex >= 0; --nIndex)
{
if (this.private_TrackChangesForSingleElement(this.CheckArray[nIndex].GetId()))
bNeedUpdate = true;
if (true !== isComplete)
{
++nCounter;
if (nCounter >= nMaxCounter || (performance.now() - nStartTime) > 4)
break;
}
}
this.CheckArray.length = nIndex < 0 ? 0 : nIndex;
// TODO: Сделать нормальную проверку, что текущий параграф или текущее выделение попала в проверенные элементы
//if (bNeedUpdate)
this.LogicDocument.UpdateInterface();
};
/**
* Ищем следующее изменение
* @returns {?CRevisionsChange}
*/
CTrackRevisionsManager.prototype.GetNextChange = function()
{
if (this.CurChange && this.CurChange.IsComplexChange())
{
var arrChanges = this.CurChange.GetSimpleChanges();
this.CurChange = null;
this.CurElement = null;
if (arrChanges.length > 0)
{
this.CurChange = arrChanges[arrChanges.length - 1];
this.CurElement = this.CurChange.GetElement();
if (!this.CurElement || !this.Changes[this.CurElement.GetId()])
{
this.CurChange = null;
this.CurElement = null;
}
}
}
var oChange = this.private_GetNextChange();
if (oChange && oChange.IsMove() && !oChange.IsComplexChange())
{
oChange = this.CollectMoveChange(oChange);
this.CurChange = oChange;
}
return oChange;
};
CTrackRevisionsManager.prototype.private_GetNextChange = function()
{
var oInitialCurChange = this.CurChange;
var oInitialCurElement = this.CurElement;
var oNextElement = null;
if (null !== this.CurChange && null !== this.CurElement && this.Changes[this.CurElement.GetId()])
{
var arrChangesArray = this.Changes[this.CurElement.GetId()];
var nChangeIndex = -1;
for (var nIndex = 0, nCount = arrChangesArray.length; nIndex < nCount; ++nIndex)
{
if (this.CurChange === arrChangesArray[nIndex])
{
nChangeIndex = nIndex;
break;
}
}
if (-1 !== nChangeIndex && nChangeIndex < arrChangesArray.length - 1)
{
this.CurChange = arrChangesArray[nChangeIndex + 1];
return this.CurChange;
}
oNextElement = this.LogicDocument.GetRevisionsChangeElement(1, this.CurElement);
}
else
{
var oSearchEngine = this.LogicDocument.private_GetRevisionsChangeElement(1, null);
oNextElement = oSearchEngine.GetFoundedElement();
if (null !== oNextElement && oNextElement === oSearchEngine.GetCurrentElement())
{
var arrNextChangesArray = this.Changes[oNextElement.GetId()];
if (arrNextChangesArray && arrNextChangesArray.length > 0)
{
if (oNextElement instanceof Paragraph)
{
var ParaContentPos = oNextElement.Get_ParaContentPos(oNextElement.IsSelectionUse(), true);
for (var nChangeIndex = 0, nCount = arrNextChangesArray.length; nChangeIndex < nCount; ++nChangeIndex)
{
var ChangeEndPos = arrNextChangesArray[nChangeIndex].get_EndPos();
if (ParaContentPos.Compare(ChangeEndPos) <= 0)
{
this.CurChange = arrNextChangesArray[nChangeIndex];
this.CurElement = oNextElement;
return this.CurChange;
}
}
}
else if (oNextElement instanceof CTable && oNextElement.IsCellSelection())
{
var arrSelectedCells = oNextElement.GetSelectionArray();
if (arrSelectedCells.length > 0)
{
var nTableRow = arrSelectedCells[0].Row;
for (var nChangeIndex = 0, nCount = arrNextChangesArray.length; nChangeIndex < nCount; ++nChangeIndex)
{
var nStartRow = arrNextChangesArray[nChangeIndex].get_StartPos();
if (nTableRow <= nStartRow)
{
this.CurChange = arrNextChangesArray[nChangeIndex];
this.CurElement = oNextElement;
return this.CurChange;
}
}
}
}
oNextElement = this.LogicDocument.GetRevisionsChangeElement(1, oNextElement);
}
}
}
if (null !== oNextElement)
{
var arrNextChangesArray = this.Changes[oNextElement.GetId()];
if (arrNextChangesArray && arrNextChangesArray.length > 0)
{
this.CurChange = arrNextChangesArray[0];
this.CurElement = oNextElement;
return this.CurChange;
}
}
if (null !== oInitialCurChange && null !== oInitialCurElement)
{
this.CurChange = oInitialCurChange;
this.CurElement = oInitialCurElement;
return oInitialCurChange;
}
this.CurChange = null;
this.CurElement = null;
return null;
};
/**
* Ищем следующее изменение
* @returns {?CRevisionsChange}
*/
CTrackRevisionsManager.prototype.GetPrevChange = function()
{
if (this.CurChange && this.CurChange.IsComplexChange())
{
var arrChanges = this.CurChange.GetSimpleChanges();
this.CurChange = null;
this.CurElement = null;
if (arrChanges.length > 0)
{
this.CurChange = arrChanges[0];
this.CurElement = this.CurChange.GetElement();
if (!this.CurElement || !this.Changes[this.CurElement.GetId()])
{
this.CurChange = null;
this.CurElement = null;
}
}
}
var oChange = this.private_GetPrevChange();
if (oChange && oChange.IsMove() && !oChange.IsComplexChange())
{
oChange = this.CollectMoveChange(oChange);
this.CurChange = oChange;
}
return oChange;
};
CTrackRevisionsManager.prototype.private_GetPrevChange = function()
{
var oInitialCurChange = this.CurChange;
var oInitialCurElement = this.CurElement;
var oPrevElement = null;
if (null !== this.CurChange && null !== this.CurElement)
{
var arrChangesArray = this.Changes[this.CurElement.GetId()];
var nChangeIndex = -1;
for (var nIndex = 0, nCount = arrChangesArray.length; nIndex < nCount; ++nIndex)
{
if (this.CurChange === arrChangesArray[nIndex])
{
nChangeIndex = nIndex;
break;
}
}
if (-1 !== nChangeIndex && nChangeIndex > 0)
{
this.CurChange = arrChangesArray[nChangeIndex - 1];
return this.CurChange;
}
oPrevElement = this.LogicDocument.GetRevisionsChangeElement(-1, this.CurElement);
}
else
{
var SearchEngine = this.LogicDocument.private_GetRevisionsChangeElement(-1, null);
oPrevElement = SearchEngine.GetFoundedElement();
if (null !== oPrevElement && oPrevElement === SearchEngine.GetCurrentElement())
{
var arrPrevChangesArray = this.Changes[oPrevElement.GetId()];
if (undefined !== arrPrevChangesArray && arrPrevChangesArray.length > 0)
{
if (oPrevElement instanceof Paragraph)
{
var ParaContentPos = oPrevElement.Get_ParaContentPos(oPrevElement.IsSelectionUse(), true);
for (var ChangeIndex = arrPrevChangesArray.length - 1; ChangeIndex >= 0; ChangeIndex--)
{
var ChangeStartPos = arrPrevChangesArray[ChangeIndex].get_StartPos();
if (ParaContentPos.Compare(ChangeStartPos) >= 0)
{
this.CurChange = arrPrevChangesArray[ChangeIndex];
this.CurElement = oPrevElement;
return this.CurChange;
}
}
}
else if (oPrevElement instanceof CTable && oPrevElement.IsCellSelection())
{
var arrSelectedCells = oPrevElement.GetSelectionArray();
if (arrSelectedCells.length > 0)
{
var nTableRow = arrSelectedCells[0].Row;
for (var nChangeIndex = arrPrevChangesArray.length - 1; nChangeIndex >= 0; --nChangeIndex)
{
var nStartRow = arrPrevChangesArray[nChangeIndex].get_StartPos();
if (nTableRow >= nStartRow)
{
this.CurChange = arrPrevChangesArray[nChangeIndex];
this.CurElement = oPrevElement;
return this.CurChange;
}
}
}
}
oPrevElement = this.LogicDocument.GetRevisionsChangeElement(-1, oPrevElement);
}
}
}
if (null !== oPrevElement)
{
var arrPrevChangesArray = this.Changes[oPrevElement.GetId()];
if (undefined !== arrPrevChangesArray && arrPrevChangesArray.length > 0)
{
this.CurChange = arrPrevChangesArray[arrPrevChangesArray.length - 1];
this.CurElement = oPrevElement;
return this.CurChange;
}
}
if (null !== oInitialCurChange && null !== oInitialCurElement)
{
this.CurChange = oInitialCurChange;
this.CurElement = oInitialCurElement;
return oInitialCurChange;
}
this.CurChange = null;
this.CurElement = null;
return null;
};
/**
* Проверяем есть ли непримененные изменения в документе
* @returns {boolean}
*/
CTrackRevisionsManager.prototype.Have_Changes = function()
{
var oTableId = this.LogicDocument ? this.LogicDocument.GetTableId() : null;
for (var sElementId in this.Changes)
{
var oElement = oTableId ? oTableId.Get_ById(sElementId) : null;
if (!oElement || !oElement.IsUseInDocument || !oElement.IsUseInDocument())
continue;
if (this.Changes[sElementId].length > 0)
return true;
}
return false;
};
/**
* Проверяем есть ли изменения, сделанные другими пользователями
* @returns {boolean}
*/
CTrackRevisionsManager.prototype.HaveOtherUsersChanges = function()
{
var sUserId = this.LogicDocument.GetUserId(false);
for (var sParaId in this.Changes)
{
var oParagraph = AscCommon.g_oTableId.Get_ById(sParaId);
if (!oParagraph || !oParagraph.IsUseInDocument())
continue;
for (var nIndex = 0, nCount = this.Changes[sParaId].length; nIndex < nCount; ++nIndex)
{
var oChange = this.Changes[sParaId][nIndex];
if (oChange.get_UserId() !== sUserId)
return true;
}
}
return false;
};
CTrackRevisionsManager.prototype.ClearCurrentChange = function()
{
this.CurChange = null;
this.CurElement = null;
};
CTrackRevisionsManager.prototype.SetCurrentChange = function(oCurChange)
{
if (oCurChange)
{
this.CurChange = oCurChange;
this.CurElement = oCurChange.GetElement();
}
};
CTrackRevisionsManager.prototype.GetCurrentChangeElement = function()
{
return this.CurElement;
};
CTrackRevisionsManager.prototype.GetCurrentChange = function()
{
return this.CurChange;
};
CTrackRevisionsManager.prototype.InitSelectedChanges = function()
{
var oEditorApi = this.LogicDocument.GetApi();
if (!oEditorApi)
return;
oEditorApi.sync_BeginCatchRevisionsChanges();
oEditorApi.sync_EndCatchRevisionsChanges();
};
CTrackRevisionsManager.prototype.ClearSelectedChanges = function()
{
if (this.SelectedChanges.length > 0)
{
var oEditorApi = this.LogicDocument.GetApi();
if (!oEditorApi)
return;
oEditorApi.sync_BeginCatchRevisionsChanges();
oEditorApi.sync_EndCatchRevisionsChanges();
}
this.SelectedChanges = [];
};
/**
* Добавляем изменение, видимое в текущей позиции
* @param oChange
*/
CTrackRevisionsManager.prototype.AddSelectedChange = function(oChange)
{
if (this.CurChange)
return;
if (oChange && c_oAscRevisionsChangeType.MoveMark === oChange.get_Type())
return;
if (oChange.IsMove() && !oChange.IsComplexChange())
oChange = this.CollectMoveChange(oChange);
for (var nIndex = 0, nCount = this.SelectedChanges.length; nIndex < nCount; ++nIndex)
{
var oVisChange = this.SelectedChanges[nIndex];
if (oVisChange.IsComplexChange() && !oChange.IsComplexChange())
{
var arrSimpleChanges = oVisChange.GetSimpleChanges();
for (var nSimpleIndex = 0, nSimpleCount = arrSimpleChanges.length; nSimpleIndex < nSimpleCount; ++nSimpleIndex)
{
if (arrSimpleChanges[nSimpleIndex] === oChange)
return;
}
}
else if (!oVisChange.IsComplexChange() && oChange.IsComplexChange())
{
var arrSimpleChanges = oChange.GetSimpleChanges();
for (var nSimpleIndex = 0, nSimpleCount = arrSimpleChanges.length; nSimpleIndex < nSimpleCount; ++nSimpleIndex)
{
if (arrSimpleChanges[nSimpleIndex] === oVisChange)
{
this.SelectedChanges.splice(nIndex, 1);
nCount--;
nIndex--;
break;
}
}
}
else if (oVisChange.IsComplexChange() && oChange.IsComplexChange())
{
var arrVisSC = oVisChange.GetSimpleChanges();
var arrChangeSC = oChange.GetSimpleChanges();
var isEqual = false;
if (arrVisSC.length === arrChangeSC.length)
{
isEqual = true;
for (var nSimpleIndex = 0, nSimplesCount = arrVisSC.length; nSimpleIndex < nSimplesCount; ++nSimpleIndex)
{
if (arrVisSC[nSimpleIndex] !== arrChangeSC[nSimpleIndex])
{
isEqual = false;
break;
}
}
}
if (isEqual)
return;
}
else if (oChange === oVisChange)
{
return;
}
}
this.SelectedChanges.push(oChange);
};
CTrackRevisionsManager.prototype.GetSelectedChanges = function()
{
return this.SelectedChanges;
};
CTrackRevisionsManager.prototype.BeginCollectChanges = function(bSaveCurrentChange)
{
if (!this.IsAllChecked())
return;
this.PrevSelectedChanges = this.SelectedChanges;
this.SelectedChanges = [];
if (true !== bSaveCurrentChange)
{
this.ClearCurrentChange();
}
else if (this.CurElement && this.CurChange)
{
var oSelectionBounds = this.CurElement.GetSelectionBounds();
var oBounds = oSelectionBounds.Direction > 0 ? oSelectionBounds.Start : oSelectionBounds.End;
if (oBounds)
{
var X = this.LogicDocument.Get_PageLimits(oBounds.Page).XLimit;
this.CurChange.put_InternalPos(X, oBounds.Y, oBounds.Page);
this.SelectedChanges.push(this.CurChange);
}
}
};
CTrackRevisionsManager.prototype.EndCollectChanges = function()
{
if (!this.IsAllChecked())
return;
var oEditor = this.LogicDocument.GetApi();
if (this.CurChange)
this.SelectedChanges = [this.CurChange];
var isPositionChanged = false;
var isArrayChanged = false;
var isShowChanges = this.CurChange || !this.LogicDocument.IsTextSelectionUse();
var nChangesCount = this.SelectedChanges.length;
if (this.PrevSelectedChanges.length !== nChangesCount || this.PrevShowChanges !== isShowChanges)
{
isArrayChanged = true;
}
else if (0 !== nChangesCount)
{
for (var nChangeIndex = 0; nChangeIndex < nChangesCount; ++nChangeIndex)
{
if (this.SelectedChanges[nChangeIndex] !== this.PrevSelectedChanges[nChangeIndex])
{
isArrayChanged = true;
break;
}
else if (this.SelectedChanges[nChangeIndex].IsPositionChanged())
{
isPositionChanged = true;
}
}
}
if (isArrayChanged)
{
oEditor.sync_BeginCatchRevisionsChanges();
if (nChangesCount > 0)
{
var oPos = this.private_GetSelectedChangesXY();
for (var ChangeIndex = 0; ChangeIndex < nChangesCount; ChangeIndex++)
{
var Change = this.SelectedChanges[ChangeIndex];
Change.put_XY(oPos.X, oPos.Y);
oEditor.sync_AddRevisionsChange(Change);
}
}
oEditor.sync_EndCatchRevisionsChanges(isShowChanges);
}
else if (isPositionChanged)
{
this.UpdateSelectedChangesPosition(oEditor);
}
this.PrevShowChanges = isShowChanges;
};
CTrackRevisionsManager.prototype.UpdateSelectedChangesPosition = function(oEditor)
{
if (this.SelectedChanges.length > 0)
{
var oPos = this.private_GetSelectedChangesXY();
oEditor.sync_UpdateRevisionsChangesPosition(oPos.X, oPos.Y);
}
};
CTrackRevisionsManager.prototype.private_GetSelectedChangesXY = function()
{
if (!this.SelectedChanges.length)
return {X : 0, Y : 0};
let change = this.SelectedChanges[0];
let element = change.GetElement();
if (!element)
return {X : 0, Y : 0};
let x = change.GetInternalPosX();
let y = change.GetInternalPosY();
let page = change.GetInternalPosPageNum();
let transform = element.Get_ParentTextTransform();
if (transform)
y = transform.TransformPointY(x, y);
let drawingCoords = this.LogicDocument.getDrawingDocument().ConvertCoordsToCursorWR(x, y, page);
return {X : drawingCoords.X, Y : drawingCoords.Y};
};
CTrackRevisionsManager.prototype.Get_AllChangesLogicDocuments = function()
{
this.CompleteTrackChanges();
var LogicDocuments = {};
for (var ParaId in this.Changes)
{
var Para = AscCommon.g_oTableId.Get_ById(ParaId);
if (Para && Para.Get_Parent())
{
LogicDocuments[Para.Get_Parent().Get_Id()] = true;
}
}
return LogicDocuments;
};
CTrackRevisionsManager.prototype.GetChangeRelatedParagraphs = function(oChange, bAccept)
{
var oRelatedParas = {};
if (oChange.IsComplexChange())
{
var arrSimpleChanges = oChange.GetSimpleChanges();
for (var nIndex = 0, nCount = arrSimpleChanges.length; nIndex < nCount; ++nIndex)
{
this.private_GetChangeRelatedParagraphs(arrSimpleChanges[nIndex], bAccept, oRelatedParas);
}
}
else
{
this.private_GetChangeRelatedParagraphs(oChange, bAccept, oRelatedParas);
}
return this.private_ConvertParagraphsObjectToArray(oRelatedParas);
};
CTrackRevisionsManager.prototype.private_GetChangeRelatedParagraphs = function(oChange, bAccept, oRelatedParas)
{
if (oChange)
{
var nType = oChange.GetType();
var oElement = oChange.GetElement();
if (oElement && oElement.IsUseInDocument())
{
oRelatedParas[oElement.GetId()] = true;
if ((c_oAscRevisionsChangeType.ParaAdd === nType && true !== bAccept) || (c_oAscRevisionsChangeType.ParaRem === nType && true === bAccept))
{
var oLogicDocument = oElement.GetParent();
var nParaIndex = oElement.GetIndex();
if (oLogicDocument && -1 !== nParaIndex)
{
if (nParaIndex < oLogicDocument.GetElementsCount() - 1)
{
var oNextElement = oLogicDocument.GetElement(nParaIndex + 1);
if (oNextElement && oNextElement.IsParagraph())
oRelatedParas[oNextElement.GetId()] = true;
}
}
}
}
}
};
CTrackRevisionsManager.prototype.private_ConvertParagraphsObjectToArray = function(ParagraphsObject)
{
var ParagraphsArray = [];
for (var ParaId in ParagraphsObject)
{
var Para = AscCommon.g_oTableId.Get_ById(ParaId);
if (null !== Para)
{
ParagraphsArray.push(Para);
}
}
return ParagraphsArray;
};
CTrackRevisionsManager.prototype.Get_AllChangesRelatedParagraphs = function(bAccept)
{
var RelatedParas = {};
for (var ParaId in this.Changes)
{
for (var ChangeIndex = 0, ChangesCount = this.Changes[ParaId].length; ChangeIndex < ChangesCount; ++ChangeIndex)
{
var Change = this.Changes[ParaId][ChangeIndex];
this.private_GetChangeRelatedParagraphs(Change, bAccept, RelatedParas);
}
}
return this.private_ConvertParagraphsObjectToArray(RelatedParas);
};
CTrackRevisionsManager.prototype.Get_AllChangesRelatedParagraphsBySelectedParagraphs = function(SelectedParagraphs, bAccept)
{
var RelatedParas = {};
for (var ParaIndex = 0, ParasCount = SelectedParagraphs.length; ParaIndex < ParasCount; ++ParaIndex)
{
var Para = SelectedParagraphs[ParaIndex];
var ParaId = Para.Get_Id();
if (this.Changes[ParaId] && this.Changes[ParaId].length > 0)
{
RelatedParas[ParaId] = true;
if (true === Para.Selection_CheckParaEnd())
{
var CheckNext = false;
for (var ChangeIndex = 0, ChangesCount = this.Changes[ParaId].length; ChangeIndex < ChangesCount; ++ChangeIndex)
{
var ChangeType = this.Changes[ParaId][ChangeIndex].get_Type();
if ((c_oAscRevisionsChangeType.ParaAdd === ChangeType && true !== bAccept) || (c_oAscRevisionsChangeType.ParaRem === ChangeType && true === bAccept))
{
CheckNext = true;
break;
}
}
if (true === CheckNext)
{
var NextElement = Para.Get_DocumentNext();
if (null !== NextElement && type_Paragraph === NextElement.Get_Type())
{
RelatedParas[NextElement.Get_Id()] = true;
}
}
}
}
}
return this.private_ConvertParagraphsObjectToArray(RelatedParas);
};
CTrackRevisionsManager.prototype.Get_AllChanges = function()
{
this.CompleteTrackChanges();
return this.Changes;
};
CTrackRevisionsManager.prototype.IsAllChecked = function()
{
return (!this.CheckArray.length && !haveElementToCheck());
};
/**
* Завершаем проверку всех элементов на наличие рецензирования
*/
CTrackRevisionsManager.prototype.CompleteTrackChanges = function()
{
while (!this.IsAllChecked())
this.ContinueTrackRevisions();
};
/**
* Завершаем проверку рецензирования для заданных элементов
* @param arrElements
* @returns {boolean}
*/
CTrackRevisionsManager.prototype.CompleteTrackChangesForElements = function(arrElements)
{
var isChecked = false;
for (var nIndex = 0, nCount = arrElements.length; nIndex < nCount; ++nIndex)
{
if (this.private_TrackChangesForSingleElement(arrElements[nIndex].GetId()))
isChecked = true;
}
return isChecked;
};
CTrackRevisionsManager.prototype.private_TrackChangesForSingleElement = function(Id)
{
if (!this.CheckMap[Id])
return false;
let oElement = this.CheckMap[Id];
delete this.CheckMap[Id];
if (!oElement.IsUseInDocument())
return false;
let isHaveChanges = !!this.Changes[Id];
this.private_RemoveChangeObject(Id);
oElement.CheckRevisionsChanges(this);
return !(!isHaveChanges && !this.Changes[Id]);
};
/**
* При чтении файла обновляем Id перетаскиваний в рецензировании
* @param sMoveId
*/
CTrackRevisionsManager.prototype.UpdateMoveId = function(sMoveId)
{
if (0 === sMoveId.indexOf("move"))
{
var nId = parseInt(sMoveId.substring(4));
if (!isNaN(nId))
this.MoveId = Math.max(this.MoveId, nId);
}
};
/**
* Возвращаем новый идентификатор перемещений
* @returns {string}
*/
CTrackRevisionsManager.prototype.GetNewMoveId = function()
{
this.MoveId++;
return "move" + this.MoveId;
};
CTrackRevisionsManager.prototype.RegisterMoveMark = function(oMark)
{
if (this.LogicDocument && this.LogicDocument.PrintSelection)
return;
if (!oMark)
return;
var sMarkId = oMark.GetMarkId();
var isFrom = oMark.IsFrom();
var isStart = oMark.IsStart();
this.UpdateMoveId(sMarkId);
if (!this.MoveMarks[sMarkId])
{
this.MoveMarks[sMarkId] = {
From : {
Start : null,
End : null
},
To : {
Start : null,
End : null
}
};
}
if (isFrom)
{
if (isStart)
this.MoveMarks[sMarkId].From.Start = oMark;
else
this.MoveMarks[sMarkId].From.End = oMark;
}
else
{
if (isStart)
this.MoveMarks[sMarkId].To.Start = oMark;
else
this.MoveMarks[sMarkId].To.End = oMark;
}
};
CTrackRevisionsManager.prototype.UnregisterMoveMark = function(oMark)
{
if (this.LogicDocument && this.LogicDocument.PrintSelection)
return;
if (!oMark)
return;
var sMarkId = oMark.GetMarkId();
delete this.MoveMarks[sMarkId];
// TODO: Возможно тут нужно проделать дополнительные действия
};
CTrackRevisionsManager.prototype.private_CheckChangeObject = function(sId)
{
var oElement = AscCommon.g_oTableId.Get_ById(sId);
if (!oElement)
return false;
if (!this.Changes[sId])
this.Changes[sId] = [];
var nDeletePosition = -1;
for (var nIndex = 0, nCount = this.ChangesOutline.length; nIndex < nCount; ++nIndex)
{
if (this.ChangesOutline[nIndex].GetId() === sId)
{
nDeletePosition = nIndex;
break;
}
}
var oDocPos = oElement.GetDocumentPositionFromObject();
if (!oDocPos)
return;
var nAddPosition = -1;
for (var nIndex = 0, nCount = this.ChangesOutline.length; nIndex < nCount; ++nIndex)
{
var oTempDocPos = this.ChangesOutline[nIndex].GetDocumentPositionFromObject();
if (this.private_CompareDocumentPositions(oDocPos, oTempDocPos) < 0)
{
nAddPosition = nIndex;
break;
}
}
if (-1 === nAddPosition)
nAddPosition = this.ChangesOutline.length;
if (nAddPosition === nDeletePosition || (-1 !== nAddPosition && -1 !== nDeletePosition && nDeletePosition === nAddPosition - 1))
return true;
if (-1 !== nDeletePosition)
{
this.ChangesOutline.splice(nDeletePosition, 1);
if (nAddPosition > nDeletePosition)
nAddPosition--;
}
this.ChangesOutline.splice(nAddPosition, 0, oElement);
return true;
};
CTrackRevisionsManager.prototype.private_CompareDocumentPositions = function(oDocPos1, oDocPos2)
{
if (oDocPos1.Class !== oDocPos2.Class)
{
// TODO: Здесь нужно доработать сравнение позиций, когда они из разных частей документа
if (oDocPos1.Class instanceof CDocument)
return -1;
else if (oDocPos1.Class instanceof CDocument)
return 1;
else
return 1;
}
for (var nIndex = 0, nCount = oDocPos1.length; nIndex < nCount; ++nIndex)
{
if (oDocPos2.length <= nIndex)
return 1;
if (oDocPos1[nIndex].Position < oDocPos2[nIndex].Position)
return -1;
else if (oDocPos1[nIndex].Position > oDocPos2[nIndex].Position)
return 1;
}
return 0;
};
CTrackRevisionsManager.prototype.private_RemoveChangeObject = function(sId)
{
if (this.Changes[sId])
delete this.Changes[sId];
for (var nIndex = 0, nCount = this.ChangesOutline.length; nIndex < nCount; ++nIndex)
{
if (this.ChangesOutline[nIndex].GetId() === sId)
{
this.ChangesOutline.splice(nIndex, 1);
return;
}
}
};
/**
* Собираем изменение связанное с переносом
* @param {CRevisionsChange} oChange
* @returns {CRevisionsChange}
*/
CTrackRevisionsManager.prototype.CollectMoveChange = function(oChange)
{
var isFrom = c_oAscRevisionsChangeType.TextRem === oChange.GetType() || c_oAscRevisionsChangeType.ParaRem === oChange.GetType() || (c_oAscRevisionsChangeType.MoveMark === oChange.GetType() && oChange.GetValue().IsFrom());
var nStartIndex = -1;
var oStartChange = null;
var oElement = oChange.GetElement();
if (!oElement)
return oChange;
var nDeep = 0;
var nSearchIndex = -1;
for (var nIndex = 0, nCount = this.ChangesOutline.length; nIndex < nCount; ++nIndex)
{
if (this.ChangesOutline[nIndex] === oElement)
{
nSearchIndex = nIndex;
break;
}
}
if (-1 === nSearchIndex)
return oChange;
var isStart = false;
for (var nIndex = nSearchIndex; nIndex >= 0; --nIndex)
{
var arrCurChanges = this.Changes[this.ChangesOutline[nIndex].GetId()];
if (!arrCurChanges)
{
isStart = true;
continue;
}
for (var nChangeIndex = arrCurChanges.length - 1; nChangeIndex >= 0; --nChangeIndex)
{
var oCurChange = arrCurChanges[nChangeIndex];
if (!isStart)
{
if (oCurChange === oChange)
isStart = true;
}
if (isStart)
{
var nCurChangeType = oCurChange.GetType();
if (nCurChangeType === c_oAscRevisionsChangeType.MoveMark)
{
var oMoveMark = oCurChange.GetValue();
if ((isFrom && oMoveMark.IsFrom()) || (!isFrom && !oMoveMark.IsFrom()))
{
if (oMoveMark.IsStart())
{
if (nDeep > 0)
{
nDeep--;
}
else if (nDeep === 0)
{
nStartIndex = nIndex;
oStartChange = oCurChange;
break;
}
}
else if (oCurChange !== oChange)
{
nDeep++;
}
}
}
}
}
if (oStartChange)
break;
isStart = true;
}
if (!oStartChange || -1 === nStartIndex)
return oChange;
var sValue = "";
var arrChanges = [oStartChange];
isStart = false;
nDeep = 0;
var isEnd = false;
for (var nIndex = nStartIndex, nCount = this.ChangesOutline.length; nIndex < nCount; ++nIndex)
{
var arrCurChanges = this.Changes[this.ChangesOutline[nIndex].GetId()];
for (var nChangeIndex = 0, nChangesCount = arrCurChanges.length; nChangeIndex < nChangesCount; ++nChangeIndex)
{
var oCurChange = arrCurChanges[nChangeIndex];
if (!isStart)
{
if (oCurChange === oStartChange)
isStart = true;
}
else
{
var nCurChangeType = oCurChange.GetType();
if (isFrom)
{
if (c_oAscRevisionsChangeType.TextRem === nCurChangeType || c_oAscRevisionsChangeType.ParaRem === nCurChangeType)
{
if (0 === nDeep)
{
sValue += c_oAscRevisionsChangeType.TextRem === nCurChangeType ? oCurChange.GetValue() : "\n";
arrChanges.push(oCurChange);
}
}
else if (c_oAscRevisionsChangeType.MoveMark === nCurChangeType && oCurChange.GetValue().IsFrom())
{
if (oCurChange.GetValue().IsStart())
{
nDeep++;
}
else if (nDeep > 0)
{
nDeep--;
}
else
{
arrChanges.push(oCurChange);
isEnd = true;
break;
}
}
}
else
{
if (c_oAscRevisionsChangeType.TextAdd === nCurChangeType || c_oAscRevisionsChangeType.ParaAdd === nCurChangeType)
{
if (0 === nDeep)
{
sValue += c_oAscRevisionsChangeType.TextAdd === nCurChangeType ? oCurChange.GetValue() : "\n";
arrChanges.push(oCurChange);
}
}
else if (c_oAscRevisionsChangeType.MoveMark === nCurChangeType && !oCurChange.GetValue().IsFrom())
{
if (oCurChange.GetValue().IsStart())
{
nDeep++;
}
else if (nDeep > 0)
{
nDeep--;
}
else
{
arrChanges.push(oCurChange);
isEnd = true;
break;
}
}
}
}
}
if (!isStart)
return oChange;
if (isEnd)
break;
}
var sMoveId = oStartChange.GetValue().GetMarkId();
var isDown = null;
for (var nIndex = 0, nCount = this.ChangesOutline.length; nIndex < nCount; ++nIndex)
{
var arrCurChanges = this.Changes[this.ChangesOutline[nIndex].GetId()];
if (!arrCurChanges)
continue;
for (var nChangeIndex = 0, nChangesCount = arrCurChanges.length; nChangeIndex < nChangesCount; ++nChangeIndex)
{
var oCurChange = arrCurChanges[nChangeIndex];
if (c_oAscRevisionsChangeType.MoveMark === oCurChange.GetType())
{
var oMark = oCurChange.GetValue();
if (sMoveId === oMark.GetMarkId())
{
isDown = !!oMark.IsFrom();
break;
}
}
}
if (null !== isDown)
break;
}
if (!isEnd || null === isDown)
return oChange;
var oMoveChange = new CRevisionsChange();
oMoveChange.SetType(isFrom ? c_oAscRevisionsChangeType.TextRem : c_oAscRevisionsChangeType.TextAdd);
oMoveChange.SetValue(sValue);
oMoveChange.SetElement(oStartChange.GetElement());
oMoveChange.SetUserId(oStartChange.GetUserId());
oMoveChange.SetUserName(oStartChange.GetUserName());
oMoveChange.SetDateTime(oStartChange.GetDateTime());
oMoveChange.SetMoveType(isFrom ? Asc.c_oAscRevisionsMove.MoveFrom : Asc.c_oAscRevisionsMove.MoveTo);
oMoveChange.SetSimpleChanges(arrChanges);
oMoveChange.SetMoveId(sMoveId);
oMoveChange.SetMovedDown(isDown);
oMoveChange.SetXY(oChange.GetX(), oChange.GetY());
oMoveChange.SetInternalPos(oChange.GetInternalPosX(), oChange.GetInternalPosY(), oChange.GetInternalPosPageNum());
return oMoveChange;
};
/**
* Получаем массив всех изменений связанных с заданным переносом
* @param {string} sMoveId
* @returns {CRevisionsChange[]}
*/
CTrackRevisionsManager.prototype.GetAllMoveChanges = function(sMoveId)
{
var oStartFromChange = null;
var oStartToChange = null;
for (var sElementId in this.Changes)
{
var arrElementChanges = this.Changes[sElementId];
for (var nChangeIndex = 0, nChangesCount = arrElementChanges.length; nChangeIndex < nChangesCount; ++nChangeIndex)
{
var oCurChange = arrElementChanges[nChangeIndex];
if (c_oAscRevisionsChangeType.MoveMark === oCurChange.GetType() && sMoveId === oCurChange.GetValue().GetMarkId() && oCurChange.GetValue().IsStart())
{
if (oCurChange.GetValue().IsFrom())
oStartFromChange = oCurChange;
else
oStartToChange = oCurChange;
}
}
if (oStartFromChange && oStartToChange)
break;
}
if (!oStartFromChange || !oStartToChange)
return {From : [], To : []};
return {
From : this.CollectMoveChange(oStartFromChange).GetSimpleChanges(),
To : this.CollectMoveChange(oStartToChange).GetSimpleChanges()
};
};
/**
* Начинаем процесс обработки(принятия или отклонения) перетаскивания текста
* @param sMoveId {string} идентификатор перетаскивания
* @param sUserId {string} идентификатор пользователя
* @returns {CTrackRevisionsMoveProcessEngine}
*/
CTrackRevisionsManager.prototype.StartProcessReviewMove = function(sMoveId, sUserId)
{
return (this.ProcessMove = new CTrackRevisionsMoveProcessEngine(sMoveId, sUserId));
};
/**
* Завершаем процесс обработки перетаскивания текста
*/
CTrackRevisionsManager.prototype.EndProcessReviewMove = function()
{
// TODO: Здесь нужно сделать обработку MovesToDelete
this.ProcessMove = null;
};
/**
* Проверям, запущен ли процесс обрабокти перетаскивания текста
* @returns {?CTrackRevisionsMoveProcessEngine}
*/
CTrackRevisionsManager.prototype.GetProcessTrackMove = function()
{
return this.ProcessMove;
};
/**
* Получаем метки переноса
* @param sMarkId
*/
CTrackRevisionsManager.prototype.GetMoveMarks = function(sMarkId)
{
return this.MoveMarks[sMarkId];
};
/**
* Получаем элементарное изменение связанное с заданным переносом, относящееся к метке переноса
* @param {string} sMoveId
* @param {boolean} isFrom
* @param {boolean} isStart
*/
CTrackRevisionsManager.prototype.GetMoveMarkChange = function(sMoveId, isFrom, isStart)
{
this.CompleteTrackChanges();
var oMoveChanges = this.GetAllMoveChanges(sMoveId);
var arrChanges = isFrom ? oMoveChanges.From : oMoveChanges.To;
for (var nIndex = 0, nCount = arrChanges.length; nIndex < nCount; ++nIndex)
{
var oChange = arrChanges[nIndex];
if (Asc.c_oAscRevisionsChangeType.MoveMark === oChange.GetType())
{
var oMark = oChange.GetValue();
if (oMark.IsFrom() === isFrom && oMark.IsStart() === isStart)
{
return oChange;
}
}
}
return null;
};
//--------------------------------------------------------export----------------------------------------------------
window['AscWord'].CTrackRevisionsManager = CTrackRevisionsManager;
window['AscWord'].checkElementInRevision = checkElementInRevision;
})(window);