mirror of
https://github.com/ONLYOFFICE/sdkjs.git
synced 2025-04-18 14:24:11 +03:00
Fix issue with undone of changes when turning off and on accept changes in the live viewer
1478 lines
57 KiB
JavaScript
1478 lines
57 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(window, undefined){
|
||
|
||
var FOREIGN_CURSOR_LABEL_HIDETIME = 1500;
|
||
|
||
function CCollaborativeChanges()
|
||
{
|
||
this.m_pData = null;
|
||
this.m_oColor = null;
|
||
}
|
||
CCollaborativeChanges.prototype.Set_Data = function(pData)
|
||
{
|
||
this.m_pData = pData;
|
||
};
|
||
CCollaborativeChanges.prototype.Set_Color = function(oColor)
|
||
{
|
||
this.m_oColor = oColor;
|
||
};
|
||
CCollaborativeChanges.prototype.Set_FromUndoRedo = function(Class, Data, Binary)
|
||
{
|
||
if (!Class.Get_Id)
|
||
return false;
|
||
|
||
this.m_pData = this.private_SaveData(Binary);
|
||
return true;
|
||
};
|
||
CCollaborativeChanges.prototype.Apply_Data = function()
|
||
{
|
||
var CollaborativeEditing = AscCommon.CollaborativeEditing;
|
||
|
||
var Reader = this.private_LoadData(this.m_pData);
|
||
if ((Asc.editor || editor).binaryChanges) {
|
||
Reader.GetULong();
|
||
}
|
||
var ClassId = Reader.GetString2();
|
||
var Class = AscCommon.g_oTableId.Get_ById(ClassId);
|
||
|
||
if (!Class)
|
||
return false;
|
||
|
||
//------------------------------------------------------------------------------------------------------------------
|
||
// Новая схема
|
||
var nReaderPos = Reader.GetCurPos();
|
||
var nChangesType = Reader.GetLong();
|
||
|
||
var fChangesClass = AscDFH.changesFactory[nChangesType];
|
||
if (fChangesClass)
|
||
{
|
||
var oChange = new fChangesClass(Class);
|
||
oChange.ReadFromBinary(Reader);
|
||
|
||
if (true === CollaborativeEditing.private_AddOverallChange(oChange))
|
||
{
|
||
oChange.Load(this.m_oColor);
|
||
|
||
if (oChange.GetClass() && oChange.GetClass().SetIsRecalculated && oChange.IsNeedRecalculate())
|
||
oChange.GetClass().SetIsRecalculated(false);
|
||
|
||
}
|
||
|
||
return true;
|
||
}
|
||
else
|
||
{
|
||
CollaborativeEditing.private_AddOverallChange(this.m_pData);
|
||
// Сюда мы попадаем, когда у данного изменения нет класса и он все еще работает по старой схеме через объект
|
||
|
||
Reader.Seek2(nReaderPos);
|
||
//\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
|
||
// Старая схема
|
||
|
||
if (!Class.Load_Changes)
|
||
return false;
|
||
|
||
return Class.Load_Changes(Reader, null, this.m_oColor);
|
||
}
|
||
};
|
||
CCollaborativeChanges.prototype.private_LoadData = function(szSrc)
|
||
{
|
||
return this.GetStream(szSrc);
|
||
};
|
||
CCollaborativeChanges.prototype.GetStream = function(szSrc, offset)
|
||
{
|
||
if ((Asc.editor || editor).binaryChanges) {
|
||
return new AscCommon.FT_Stream2(szSrc, szSrc.length);
|
||
} else {
|
||
var memoryData = AscCommon.Base64.decode(szSrc, true, undefined, offset);
|
||
return new AscCommon.FT_Stream2(memoryData, memoryData.length);
|
||
}
|
||
};
|
||
CCollaborativeChanges.prototype.private_SaveData = function(Binary)
|
||
{
|
||
let Writer = AscCommon.History.BinaryWriter;
|
||
let Pos = Binary.Pos;
|
||
let Len = Binary.Len;
|
||
if ((Asc.editor || editor).binaryChanges) {
|
||
return Writer.GetDataUint8(Pos, Len);
|
||
} else {
|
||
return Len + ";" + Writer.GetBase64Memory2(Pos, Len);
|
||
}
|
||
};
|
||
CCollaborativeChanges.prototype.ToHistoryChange = function()
|
||
{
|
||
let binaryReader = this.private_LoadData(this.m_pData);
|
||
|
||
let objectId = binaryReader.GetString2();
|
||
let object = AscCommon.g_oTableId.Get_ById(objectId);
|
||
|
||
if (!object)
|
||
{
|
||
let changeType = binaryReader.GetLong();
|
||
let change = new AscDFH.changesFactory[changeType](object);
|
||
change.ReadFromBinary(binaryReader);
|
||
|
||
return null;
|
||
}
|
||
|
||
let changeType = binaryReader.GetLong();
|
||
|
||
if (!AscDFH.changesFactory[changeType])
|
||
return null;
|
||
|
||
let change = new AscDFH.changesFactory[changeType](object);
|
||
change.ReadFromBinary(binaryReader);
|
||
return change;
|
||
};
|
||
CCollaborativeChanges.ToBase64 = function(pos, len)
|
||
{
|
||
let writer = AscCommon.History.BinaryWriter;
|
||
if ((Asc.editor || editor).binaryChanges)
|
||
return writer.GetDataUint8(pos, len);
|
||
else
|
||
return len + ";" + writer.GetBase64Memory2(pos, len);
|
||
};
|
||
|
||
|
||
/**
|
||
* Базовый класс для совместного редактирования в разных редакторах
|
||
* @constructor
|
||
*/
|
||
function CCollaborativeEditingBase()
|
||
{
|
||
this.m_nUseType = 1; // 1 - 1 клиент и мы сохраняем историю, -1 - несколько клиентов, 0 - переход из -1 в 1
|
||
|
||
this.m_aUsers = []; // Список текущих пользователей, редактирующих данный документ
|
||
this.m_aChanges = []; // Массив с изменениями других пользователей
|
||
this.m_nUndoBeforeApply = 0; // The number of changes we need to undo before the other changes can be accepted
|
||
|
||
this.m_aNeedUnlock = []; // Массив со списком залоченных объектов(которые были залочены другими пользователями)
|
||
this.m_aNeedUnlock2 = []; // Массив со списком залоченных объектов(которые были залочены на данном клиенте)
|
||
this.m_aNeedLock = []; // Массив со списком залоченных объектов(которые были залочены, но еще не были добавлены на данном клиенте)
|
||
|
||
this.m_aEndActions = []; // Массив действий, которые надо выполнить после принятия чужих изменений
|
||
|
||
|
||
this.m_bGlobalLock = 0; // Запрещаем производить любые "редактирующие" действия (т.е. то, что в историю запишется)
|
||
this.m_bGlobalLockSelection = 0; // Запрещаем изменять селект и курсор
|
||
|
||
this.m_aCheckLocks = []; // Массив для проверки залоченности объектов, которые мы собираемся изменять
|
||
this.m_aCheckLocksInstance = []; // Массив для проверки залоченности объектов в случае сложного действия
|
||
|
||
this.m_aNewImages = []; // Массив со списком картинок, которые нужно будет загрузить на сервере
|
||
this.m_aDC = {}; // Массив(ассоциативный) классов DocumentContent
|
||
this.m_aChangedClasses = {}; // Массив(ассоциативный) классов, в которых есть изменения выделенные цветом
|
||
|
||
this.m_aCursorsToUpdate = {}; // Курсоры, которые нужно обновить после принятия изменений
|
||
this.m_aCursorsToUpdateShortId = {};
|
||
|
||
// // CollaborativeEditing LOG
|
||
// this.m_nErrorLog_PointChangesCount = 0;
|
||
// this.m_nErrorLog_SavedPCC = 0;
|
||
// this.m_nErrorLog_CurPointIndex = -1;
|
||
// this.m_nErrorLog_SumIndex = 0;
|
||
|
||
this.m_bFast = false;
|
||
|
||
this.m_oLogicDocument = null;
|
||
this.m_aDocumentPositions = new CDocumentPositionsManager();
|
||
this.m_aForeignCursorsPos = new CDocumentPositionsManager();
|
||
this.m_aForeignCursors = {};
|
||
this.m_aForeignCursorsId = {};
|
||
this.m_aForeignCursorsXY = {};
|
||
this.m_aForeignCursorsToShow = {};
|
||
|
||
|
||
this.m_nAllChangesSavedIndex = 0;
|
||
|
||
this.m_nRecalcIndexStart = 0;
|
||
this.m_nRecalcIndexEnd = 0;
|
||
|
||
this.CoHistory = new AscCommon.CCollaborativeHistory(this);
|
||
|
||
this.m_aAllChanges = []; // Список всех изменений
|
||
this.m_aOwnChangesIndexes = []; // Список номеров своих изменений в общем списке, которые мы можем откатить
|
||
|
||
this.m_oOwnChanges = [];
|
||
|
||
this.m_fEndLoadCallBack = null;
|
||
|
||
this.m_aExternalChanges = [];
|
||
this.m_nExternalIndex0 = -1;
|
||
this.m_nExternalIndex1 = -1;
|
||
this.m_nExternalCounter = 0;
|
||
}
|
||
|
||
CCollaborativeEditingBase.prototype.GetEditorApi = function()
|
||
{
|
||
return null;
|
||
};
|
||
CCollaborativeEditingBase.prototype.GetDrawingDocument = function()
|
||
{
|
||
return null;
|
||
};
|
||
CCollaborativeEditingBase.prototype.GetLogicDocument = function()
|
||
{
|
||
return this.m_oLogicDocument;
|
||
};
|
||
CCollaborativeEditingBase.prototype.getCoHistory = function()
|
||
{
|
||
return this.CoHistory;
|
||
};
|
||
CCollaborativeEditingBase.prototype.SetLogicDocument = function(doc)
|
||
{
|
||
this.m_oLogicDocument = doc;
|
||
};
|
||
CCollaborativeEditingBase.prototype.Clear = function()
|
||
{
|
||
this.m_nUseType = 1;
|
||
|
||
this.m_aUsers = [];
|
||
this.m_aChanges = [];
|
||
this.m_aNeedUnlock = [];
|
||
this.m_aNeedUnlock2 = [];
|
||
this.m_aNeedLock = [];
|
||
this.m_aEndActions = [];
|
||
this.m_aCheckLocks = [];
|
||
this.m_aCheckLocksInstance = [];
|
||
this.m_aNewImages = [];
|
||
|
||
this.CoHistory.clear();
|
||
};
|
||
CCollaborativeEditingBase.prototype.Set_Fast = function(bFast)
|
||
{
|
||
this.m_bFast = bFast;
|
||
|
||
if (false === bFast)
|
||
{
|
||
this.Remove_AllForeignCursors();
|
||
this.RemoveMyCursorFromOthers();
|
||
}
|
||
};
|
||
CCollaborativeEditingBase.prototype.Is_Fast = function()
|
||
{
|
||
return this.m_bFast;
|
||
};
|
||
CCollaborativeEditingBase.prototype.Is_SingleUser = function()
|
||
{
|
||
return (1 === this.m_nUseType);
|
||
};
|
||
CCollaborativeEditingBase.prototype.isCollaboration = function()
|
||
{
|
||
return (-1 === this.m_nUseType);
|
||
};
|
||
CCollaborativeEditingBase.prototype.canSendChanges = function()
|
||
{
|
||
let api = this.GetEditorApi();
|
||
return api && api.canSendChanges();
|
||
};
|
||
CCollaborativeEditingBase.prototype.getCollaborativeEditing = function()
|
||
{
|
||
return !this.Is_SingleUser();
|
||
};
|
||
CCollaborativeEditingBase.prototype.Start_CollaborationEditing = function()
|
||
{
|
||
this.m_nUseType = -1;
|
||
};
|
||
CCollaborativeEditingBase.prototype.End_CollaborationEditing = function()
|
||
{
|
||
if (this.m_nUseType <= 0)
|
||
this.m_nUseType = 0;
|
||
};
|
||
CCollaborativeEditingBase.prototype.Add_User = function(UserId)
|
||
{
|
||
if (-1 === this.Find_User(UserId))
|
||
this.m_aUsers.push(UserId);
|
||
};
|
||
CCollaborativeEditingBase.prototype.Find_User = function(UserId)
|
||
{
|
||
var Len = this.m_aUsers.length;
|
||
for (var Index = 0; Index < Len; Index++)
|
||
{
|
||
if (this.m_aUsers[Index] === UserId)
|
||
return Index;
|
||
}
|
||
|
||
return -1;
|
||
};
|
||
CCollaborativeEditingBase.prototype.Remove_User = function(UserId)
|
||
{
|
||
var Pos = this.Find_User( UserId );
|
||
if ( -1 != Pos )
|
||
this.m_aUsers.splice( Pos, 1 );
|
||
};
|
||
CCollaborativeEditingBase.prototype.Add_Changes = function(Changes)
|
||
{
|
||
this.m_aChanges.push(Changes);
|
||
};
|
||
CCollaborativeEditingBase.prototype.Add_Unlock = function(LockClass)
|
||
{
|
||
this.m_aNeedUnlock.push( LockClass );
|
||
};
|
||
CCollaborativeEditingBase.prototype.Add_Unlock2 = function(Lock)
|
||
{
|
||
this.m_aNeedUnlock2.push(Lock);
|
||
(Asc.editor || editor)._onUpdateDocumentCanSave();
|
||
};
|
||
CCollaborativeEditingBase.prototype.Have_OtherChanges = function()
|
||
{
|
||
return (0 < this.m_aChanges.length || this.m_nUndoBeforeApply > 0);
|
||
};
|
||
CCollaborativeEditingBase.prototype.Apply_Changes = function(fEndCallBack)
|
||
{
|
||
if (this.m_nUndoBeforeApply)
|
||
{
|
||
let state = this._PreUndo();
|
||
let changes = this.CoHistory.UndoGlobalChanges(this.m_nUndoBeforeApply);
|
||
this._PostUndo(state, changes);
|
||
this.m_nUndoBeforeApply = 0;
|
||
}
|
||
|
||
if (this.m_aChanges.length > 0)
|
||
{
|
||
this.GetEditorApi().sendEvent("asc_onBeforeApplyChanges");
|
||
AscFonts.IsCheckSymbols = true;
|
||
(Asc.editor || editor).WordControl.m_oLogicDocument.PauseRecalculate();
|
||
(Asc.editor || editor).WordControl.m_oLogicDocument.EndPreview_MailMergeResult();
|
||
|
||
(Asc.editor || editor).sync_StartAction(Asc.c_oAscAsyncActionType.BlockInteraction, Asc.c_oAscAsyncAction.ApplyChanges);
|
||
|
||
var DocState = this.private_SaveDocumentState();
|
||
this.Clear_NewImages();
|
||
|
||
this.Apply_OtherChanges();
|
||
|
||
// После того как мы приняли чужие изменения, мы должны залочить новые объекты, которые были залочены
|
||
this.Lock_NeedLock();
|
||
this.private_RestoreDocumentState(DocState);
|
||
this.OnStart_Load_Objects(fEndCallBack);
|
||
AscFonts.IsCheckSymbols = false;
|
||
this.GetEditorApi().sendEvent("asc_onApplyChanges");
|
||
}
|
||
else
|
||
{
|
||
if (fEndCallBack)
|
||
fEndCallBack();
|
||
}
|
||
|
||
AscCommon.CollaborativeEditing.CoHistory.InitTextRecover();
|
||
};
|
||
CCollaborativeEditingBase.prototype.Apply_OtherChanges = function()
|
||
{
|
||
// Чтобы заново созданные параграфы не отображались залоченными
|
||
AscCommon.g_oIdCounter.Set_Load( true );
|
||
|
||
if (this.m_aChanges.length > 0)
|
||
this.private_CollectOwnChanges();
|
||
|
||
this.private_SaveRecalcChangeIndex(true);
|
||
|
||
// Применяем изменения, пока они есть
|
||
var _count = this.m_aChanges.length;
|
||
for (var i = 0; i < _count; i++)
|
||
{
|
||
if (window["NATIVE_EDITOR_ENJINE"] === true && window["native"]["CheckNextChange"])
|
||
{
|
||
if (!window["native"]["CheckNextChange"]())
|
||
break;
|
||
}
|
||
|
||
var Changes = this.m_aChanges[i];
|
||
Changes.Apply_Data();
|
||
// // CollaborativeEditing LOG
|
||
// this.m_nErrorLog_PointChangesCount++;
|
||
}
|
||
|
||
this.private_SaveRecalcChangeIndex(false);
|
||
this.private_ClearChanges();
|
||
|
||
// Делаем проверки корректности новых изменений
|
||
this.Check_MergeData();
|
||
|
||
this.OnEnd_ReadForeignChanges();
|
||
AscCommon.g_oIdCounter.Set_Load( false );
|
||
};
|
||
CCollaborativeEditingBase.prototype.ValidateExternalChanges = function()
|
||
{
|
||
if (this.m_nExternalIndex0 < 0)
|
||
{
|
||
if (true === window['AscApplyChanges'] || !window['AscChanges'])
|
||
return false;
|
||
|
||
this.m_aExternalChanges = window['AscChanges'];
|
||
this.m_nExternalIndex0 = 0;
|
||
this.m_nExternalIndex1 = -1;
|
||
}
|
||
|
||
return true;
|
||
};
|
||
CCollaborativeEditingBase.prototype.GetNextExternalChange = function()
|
||
{
|
||
if (this.m_nExternalIndex0 < 0
|
||
|| this.m_nExternalIndex0 >= this.m_aExternalChanges.length)
|
||
return null;
|
||
|
||
this.m_nExternalIndex1++;
|
||
|
||
while (this.m_nExternalIndex1 >= this.m_aExternalChanges[this.m_nExternalIndex0].length)
|
||
{
|
||
this.m_nExternalIndex0++;
|
||
this.m_nExternalIndex1 = 0;
|
||
|
||
if (this.m_nExternalIndex0 >= this.m_aExternalChanges.length)
|
||
return null;
|
||
}
|
||
|
||
return this.m_aExternalChanges[this.m_nExternalIndex0][this.m_nExternalIndex1];
|
||
};
|
||
/**
|
||
* Накатываем изменения заданные через LoadExternalChanges, причем не все сразу, а последовательно по 1-ой точке
|
||
* @returns {number} возвращаем количество примененных изменений
|
||
*/
|
||
CCollaborativeEditingBase.prototype.ApplyExternalChanges = function(pointCount)
|
||
{
|
||
if (!this.ValidateExternalChanges())
|
||
return 0;
|
||
|
||
// Чтобы заново созданные параграфы не отображались залоченными
|
||
AscCommon.g_oIdCounter.Set_Load( true );
|
||
|
||
if (this.m_aChanges.length > 0)
|
||
this.private_CollectOwnChanges();
|
||
|
||
this.private_SaveRecalcChangeIndex(true);
|
||
|
||
pointCount = pointCount ? pointCount : 1;
|
||
let counter = 0;
|
||
for (let pointIndex = 0; pointIndex < pointCount; ++pointIndex)
|
||
{
|
||
let color = new CDocumentColor(191, 255, 199);
|
||
|
||
this.m_nExternalCounter++;
|
||
|
||
let isStart = false;
|
||
let binary;
|
||
while (binary = this.GetNextExternalChange())
|
||
{
|
||
let change = AscDFH.GetChange(binary);
|
||
if (!change)
|
||
{
|
||
console.log("Lost change!!!");
|
||
continue;
|
||
}
|
||
|
||
if (change.IsDescriptionChange())
|
||
{
|
||
if (isStart)
|
||
{
|
||
this.m_nExternalIndex1--;
|
||
break;
|
||
}
|
||
else
|
||
isStart = true;
|
||
}
|
||
|
||
if (this.private_AddOverallChange(change))
|
||
{
|
||
change.Load(color);
|
||
if (change.GetClass() && change.GetClass().SetIsRecalculated && change.IsNeedRecalculate())
|
||
change.GetClass().SetIsRecalculated(false);
|
||
}
|
||
|
||
counter++;
|
||
|
||
// // CollaborativeEditing LOG
|
||
// this.m_nErrorLog_PointChangesCount++;
|
||
}
|
||
|
||
if (!binary)
|
||
break;
|
||
}
|
||
|
||
|
||
this.private_SaveRecalcChangeIndex(false);
|
||
this.private_ClearChanges();
|
||
|
||
// Делаем проверки корректности новых изменений
|
||
this.Check_MergeData();
|
||
|
||
this.OnEnd_ReadForeignChanges();
|
||
|
||
AscCommon.g_oIdCounter.Set_Load( false );
|
||
|
||
(Asc.editor || editor).WordControl.m_oLogicDocument.RecalculateFromStart();
|
||
|
||
return counter;
|
||
};
|
||
CCollaborativeEditingBase.prototype.getOwnLocksLength = function()
|
||
{
|
||
return this.m_aNeedUnlock2.length;
|
||
};
|
||
CCollaborativeEditingBase.prototype.Send_Changes = function()
|
||
{
|
||
};
|
||
CCollaborativeEditingBase.prototype.Release_Locks = function()
|
||
{
|
||
};
|
||
|
||
|
||
CCollaborativeEditingBase.prototype.CheckWaitingImages = function (aImages) {
|
||
|
||
};
|
||
|
||
CCollaborativeEditingBase.prototype.SendImagesUrlsFromChanges = function (aImages) {
|
||
var rData = {}, oApi = editor || Asc['editor'], i;
|
||
if(!oApi){
|
||
return;
|
||
}
|
||
rData['type'] = 'pathurls';
|
||
rData['data'] = [];
|
||
for(i = 0; i < aImages.length; ++i)
|
||
{
|
||
rData['data'].push(aImages[i]);
|
||
}
|
||
var aImagesToLoad = [].concat(AscCommon.CollaborativeEditing.m_aNewImages);
|
||
this.CheckWaitingImages(aImagesToLoad);
|
||
AscCommon.CollaborativeEditing.m_aNewImages.length = 0;
|
||
if(false === oApi.isSaveFonts_Images){
|
||
oApi.isSaveFonts_Images = true;
|
||
}
|
||
var callback = function (isTimeout, oRes) {
|
||
var aData, i, oUrls;
|
||
if(oRes && oRes['status'] === 'ok')
|
||
{
|
||
aData = oRes['data'];
|
||
oUrls= {};
|
||
for(i = 0; i < aData.length; ++i)
|
||
{
|
||
oUrls[aImages[i]] = aData[i];
|
||
}
|
||
AscCommon.g_oDocumentUrls.addUrls(oUrls);
|
||
}
|
||
AscCommon.CollaborativeEditing.SendImagesCallback(aImagesToLoad);
|
||
};
|
||
|
||
if (!oApi.CoAuthoringApi.callPRC(rData, Asc.c_nCommonRequestTime, callback)) {
|
||
callback(false, undefined);
|
||
}
|
||
};
|
||
|
||
CCollaborativeEditingBase.prototype.SendImagesCallback = function (aImages) {
|
||
var oApi = editor || Asc['editor'];
|
||
oApi.pre_Save(aImages);
|
||
};
|
||
|
||
|
||
CCollaborativeEditingBase.prototype.CollectImagesFromChanges = function () {
|
||
var oApi = editor || Asc['editor'];
|
||
var aImages = [], sImagePath, i, sImageFromChanges, oThemeUrls = {};
|
||
var aNewImages = this.m_aNewImages;
|
||
var oMap = {};
|
||
for(i = 0; i < aNewImages.length; ++i)
|
||
{
|
||
sImageFromChanges = aNewImages[i];
|
||
if(oMap[sImageFromChanges])
|
||
{
|
||
continue;
|
||
}
|
||
oMap[sImageFromChanges] = 1;
|
||
if(sImageFromChanges.indexOf('theme') === 0 && oApi.ThemeLoader)
|
||
{
|
||
oThemeUrls[sImageFromChanges] = oApi.ThemeLoader.ThemesUrlAbs + sImageFromChanges;
|
||
}
|
||
else if (0 === sImageFromChanges.indexOf('http:') || 0 === sImageFromChanges.indexOf('data:') || 0 === sImageFromChanges.indexOf('https:') ||
|
||
0 === sImageFromChanges.indexOf('file:') || 0 === sImageFromChanges.indexOf('ftp:'))
|
||
{
|
||
}
|
||
else
|
||
{
|
||
sImagePath = AscCommon.g_oDocumentUrls.mediaPrefix + sImageFromChanges;
|
||
if(!AscCommon.g_oDocumentUrls.getUrl(sImagePath))
|
||
{
|
||
aImages.push(sImagePath);
|
||
}
|
||
}
|
||
}
|
||
AscCommon.g_oDocumentUrls.addUrls(oThemeUrls);
|
||
return aImages;
|
||
};
|
||
|
||
|
||
CCollaborativeEditingBase.prototype.OnStart_Load_Objects = function(fEndCallBack)
|
||
{
|
||
if (fEndCallBack)
|
||
this.m_fEndLoadCallBack = fEndCallBack;
|
||
|
||
this.Set_GlobalLock(true);
|
||
this.Set_GlobalLockSelection(true);
|
||
// Вызываем функцию для загрузки необходимых элементов (новые картинки и шрифты)
|
||
var aImages = this.CollectImagesFromChanges();
|
||
if(aImages.length > 0)
|
||
{
|
||
this.SendImagesUrlsFromChanges(aImages);
|
||
}
|
||
else
|
||
{
|
||
this.SendImagesCallback([].concat(this.m_aNewImages));
|
||
this.m_aNewImages.length = 0;
|
||
}
|
||
};
|
||
CCollaborativeEditingBase.prototype.OnEnd_Load_Objects = function()
|
||
{
|
||
if (this.m_fEndLoadCallBack)
|
||
{
|
||
this.m_fEndLoadCallBack();
|
||
this.m_fEndLoadCallBack = null;
|
||
}
|
||
};
|
||
//-----------------------------------------------------------------------------------
|
||
// Функции для проверки корректности новых изменений
|
||
//-----------------------------------------------------------------------------------
|
||
CCollaborativeEditingBase.prototype.Check_MergeData = function()
|
||
{
|
||
};
|
||
//-----------------------------------------------------------------------------------
|
||
// Функции для проверки залоченности объектов
|
||
//-----------------------------------------------------------------------------------
|
||
CCollaborativeEditingBase.prototype.Get_GlobalLock = function()
|
||
{
|
||
return (0 === this.m_bGlobalLock ? false : true);
|
||
};
|
||
CCollaborativeEditingBase.prototype.Set_GlobalLock = function(isLock)
|
||
{
|
||
if (isLock)
|
||
this.m_bGlobalLock++;
|
||
else
|
||
this.m_bGlobalLock = Math.max(0, this.m_bGlobalLock - 1);
|
||
};
|
||
CCollaborativeEditingBase.prototype.Set_GlobalLockSelection = function(isLock)
|
||
{
|
||
if (isLock)
|
||
this.m_bGlobalLockSelection++;
|
||
else
|
||
this.m_bGlobalLockSelection = Math.max(0, this.m_bGlobalLockSelection - 1);
|
||
};
|
||
CCollaborativeEditingBase.prototype.Get_GlobalLockSelection = function()
|
||
{
|
||
return (0 === this.m_bGlobalLockSelection ? false : true);
|
||
};
|
||
CCollaborativeEditingBase.prototype.OnStart_CheckLock = function()
|
||
{
|
||
this.m_aCheckLocks.length = 0;
|
||
this.m_aCheckLocksInstance.length = 0;
|
||
};
|
||
CCollaborativeEditingBase.prototype.Add_CheckLock = function(oItem)
|
||
{
|
||
this.m_aCheckLocks.push(oItem);
|
||
this.m_aCheckLocksInstance.push(oItem);
|
||
};
|
||
CCollaborativeEditingBase.prototype.OnEnd_CheckLock = function()
|
||
{
|
||
};
|
||
CCollaborativeEditingBase.prototype.OnCallback_AskLock = function(result)
|
||
{
|
||
};
|
||
CCollaborativeEditingBase.prototype.OnStartCheckLockInstance = function()
|
||
{
|
||
this.m_aCheckLocksInstance.length = 0;
|
||
};
|
||
CCollaborativeEditingBase.prototype.OnEndCheckLockInstance = function()
|
||
{
|
||
var isLocked = false;
|
||
for (var nIndex = 0, nCount = this.m_aCheckLocksInstance.length; nIndex < nCount; ++nIndex)
|
||
{
|
||
if (true === this.m_aCheckLocksInstance[nIndex])
|
||
{
|
||
isLocked = true;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (isLocked)
|
||
{
|
||
var nCount = this.m_aCheckLocksInstance.length;
|
||
this.m_aCheckLocks.splice(this.m_aCheckLocks.length - nCount, nCount);
|
||
}
|
||
|
||
this.m_aCheckLocksInstance.length = 0;
|
||
return isLocked;
|
||
};
|
||
//-----------------------------------------------------------------------------------
|
||
// Функции для работы с залоченными объектами, которые еще не были добавлены
|
||
//-----------------------------------------------------------------------------------
|
||
CCollaborativeEditingBase.prototype.Reset_NeedLock = function()
|
||
{
|
||
this.m_aNeedLock = {};
|
||
};
|
||
CCollaborativeEditingBase.prototype.Add_NeedLock = function(Id, sUser)
|
||
{
|
||
this.m_aNeedLock[Id] = sUser;
|
||
};
|
||
CCollaborativeEditingBase.prototype.Remove_NeedLock = function(Id)
|
||
{
|
||
delete this.m_aNeedLock[Id];
|
||
};
|
||
CCollaborativeEditingBase.prototype.Lock_NeedLock = function()
|
||
{
|
||
for ( var Id in this.m_aNeedLock )
|
||
{
|
||
var Class = AscCommon.g_oTableId.Get_ById( Id );
|
||
|
||
if ( null != Class )
|
||
{
|
||
var Lock = Class.Lock;
|
||
Lock.Set_Type( AscCommon.c_oAscLockTypes.kLockTypeOther, false );
|
||
if(Class.getObjectType && Class.getObjectType() === AscDFH.historyitem_type_Slide)
|
||
{
|
||
(Asc.editor || editor).WordControl.m_oLogicDocument.DrawingDocument.UnLockSlide && editor.WordControl.m_oLogicDocument.DrawingDocument.UnLockSlide(Class.num);
|
||
}
|
||
Lock.Set_UserId( this.m_aNeedLock[Id] );
|
||
}
|
||
}
|
||
|
||
this.Reset_NeedLock();
|
||
};
|
||
//-----------------------------------------------------------------------------------
|
||
// Функции для работы с новыми объектами, созданными на других клиентах
|
||
//-----------------------------------------------------------------------------------
|
||
CCollaborativeEditingBase.prototype.Clear_EndActions = function()
|
||
{
|
||
this.m_aEndActions.length = 0;
|
||
};
|
||
CCollaborativeEditingBase.prototype.Add_EndActions = function(Class, Data)
|
||
{
|
||
this.m_aEndActions.push({Class : Class, Data : Data});
|
||
};
|
||
CCollaborativeEditingBase.prototype.OnEnd_ReadForeignChanges = function()
|
||
{
|
||
let Count = this.m_aEndActions.length;
|
||
for (var Index = 0; Index < Count; Index++)
|
||
{
|
||
var Item = this.m_aEndActions[Index];
|
||
Item.Class.Process_EndLoad(Item.Data);
|
||
}
|
||
|
||
this.Clear_EndActions();
|
||
};
|
||
//-----------------------------------------------------------------------------------
|
||
// Функции для работы с новыми объектами, созданными на других клиентах
|
||
//-----------------------------------------------------------------------------------
|
||
CCollaborativeEditingBase.prototype.Clear_NewImages = function()
|
||
{
|
||
this.m_aNewImages.length = 0;
|
||
};
|
||
CCollaborativeEditingBase.prototype.Add_NewImage = function(Url)
|
||
{
|
||
this.m_aNewImages.push( Url );
|
||
};
|
||
//-----------------------------------------------------------------------------------
|
||
// Функции для работы с массивом m_aDC
|
||
//-----------------------------------------------------------------------------------
|
||
CCollaborativeEditingBase.prototype.Add_NewDC = function(Class)
|
||
{
|
||
var Id = Class.Get_Id();
|
||
this.m_aDC[Id] = Class;
|
||
};
|
||
CCollaborativeEditingBase.prototype.Clear_DCChanges = function()
|
||
{
|
||
for (var Id in this.m_aDC)
|
||
{
|
||
this.m_aDC[Id].Clear_ContentChanges();
|
||
}
|
||
|
||
// Очищаем массив
|
||
this.m_aDC = {};
|
||
};
|
||
CCollaborativeEditingBase.prototype.Refresh_DCChanges = function()
|
||
{
|
||
for (var Id in this.m_aDC)
|
||
{
|
||
this.m_aDC[Id].Refresh_ContentChanges();
|
||
}
|
||
|
||
this.Clear_DCChanges();
|
||
};
|
||
|
||
|
||
//-----------------------------------------------------------------------------------
|
||
// Функции для работы с массивами PosExtChangesX, PosExtChangesY
|
||
//-----------------------------------------------------------------------------------
|
||
CCollaborativeEditingBase.prototype.AddPosExtChanges = function(Item, ChangeObject){
|
||
|
||
};
|
||
CCollaborativeEditingBase.prototype.RefreshPosExtChanges = function(){
|
||
|
||
};
|
||
CCollaborativeEditingBase.prototype.RewritePosExtChanges = function(changesArr, scale, Binary_Writer)
|
||
{
|
||
};
|
||
//-----------------------------------------------------------------------------------
|
||
// Функции для работы с отметками изменений
|
||
//-----------------------------------------------------------------------------------
|
||
CCollaborativeEditingBase.prototype.Add_ChangedClass = function(Class)
|
||
{
|
||
var Id = Class.Get_Id();
|
||
this.m_aChangedClasses[Id] = Class;
|
||
};
|
||
CCollaborativeEditingBase.prototype.Clear_CollaborativeMarks = function(bRepaint)
|
||
{
|
||
for ( var Id in this.m_aChangedClasses )
|
||
{
|
||
this.m_aChangedClasses[Id].Clear_CollaborativeMarks();
|
||
}
|
||
|
||
// Очищаем массив
|
||
this.m_aChangedClasses = {};
|
||
|
||
|
||
if (true === bRepaint)
|
||
{
|
||
var oDrawingDocument = this.GetDrawingDocument();
|
||
if(oDrawingDocument)
|
||
{
|
||
oDrawingDocument.ClearCachePages();
|
||
oDrawingDocument.FirePaint();
|
||
}
|
||
}
|
||
};
|
||
CCollaborativeEditingBase.prototype.Get_CollaborativeMarks = function ()
|
||
{
|
||
return this.m_aChangedClasses;
|
||
}
|
||
//----------------------------------------------------------------------------------------------------------------------
|
||
// Функции для работы с обновлением курсоров после принятия изменений
|
||
//----------------------------------------------------------------------------------------------------------------------
|
||
CCollaborativeEditingBase.prototype.UpdateForeignCursorByAdditionalInfo = function(info)
|
||
{
|
||
if (!info)
|
||
return;
|
||
|
||
let userId = undefined !== info["UserId"] ? info["UserId"] : info.UserId;
|
||
let cursorInfo = undefined !== info["CursorInfo"] ? info["CursorInfo"] : info.CursorInfo;
|
||
let shortUserId = undefined !== info["UserShortId"] ? info["UserShortId"] : info.UserShortId;
|
||
|
||
if (!userId || !cursorInfo || !shortUserId)
|
||
return;
|
||
|
||
this.Add_ForeignCursorToUpdate(userId, cursorInfo, shortUserId);
|
||
};
|
||
CCollaborativeEditingBase.prototype.Add_ForeignCursorToUpdate = function(UserId, CursorInfo, UserShortId)
|
||
{
|
||
this.m_aCursorsToUpdate[UserId] = CursorInfo;
|
||
this.m_aCursorsToUpdateShortId[UserId] = UserShortId;
|
||
};
|
||
CCollaborativeEditingBase.prototype.private_UpdateForeignCursor = function(CursorInfo, UserId, Show, UserShortId)
|
||
{
|
||
};
|
||
CCollaborativeEditingBase.prototype.Refresh_ForeignCursors = function()
|
||
{
|
||
for (var UserId in this.m_aCursorsToUpdate)
|
||
{
|
||
var CursorInfo = this.m_aCursorsToUpdate[UserId];
|
||
this.private_UpdateForeignCursor(CursorInfo, UserId, false, this.m_aCursorsToUpdateShortId[UserId]);
|
||
this.Add_ForeignCursorToShow(UserId);
|
||
}
|
||
this.m_aCursorsToUpdate = {};
|
||
this.m_aCursorsToUpdateShortId = {};
|
||
};
|
||
//----------------------------------------------------------------------------------------------------------------------
|
||
// Функции для работы с сохраненными позициями в Word-документах. Они объявлены в базовом классе, потому что вызываются
|
||
// из общих классов Paragraph, Run, Table. Вообщем, для совместимости.
|
||
//----------------------------------------------------------------------------------------------------------------------
|
||
CCollaborativeEditingBase.prototype.Clear_DocumentPositions = function(){
|
||
this.m_aDocumentPositions.Clear_DocumentPositions();
|
||
};
|
||
CCollaborativeEditingBase.prototype.Add_DocumentPosition = function(DocumentPos){
|
||
this.m_aDocumentPositions.Add_DocumentPosition(DocumentPos);
|
||
};
|
||
CCollaborativeEditingBase.prototype.Remove_DocumentPosition = function(docPos)
|
||
{
|
||
this.m_aDocumentPositions.Remove_DocumentPosition(docPos);
|
||
};
|
||
CCollaborativeEditingBase.prototype.Add_ForeignCursor = function(UserId, DocumentPos, UserShortId){
|
||
this.m_aForeignCursorsPos.Remove_DocumentPosition(this.m_aCursorsToUpdate[UserId]);
|
||
this.m_aForeignCursors[UserId] = DocumentPos;
|
||
this.m_aForeignCursorsPos.Add_DocumentPosition(DocumentPos);
|
||
this.m_aForeignCursorsId[UserId] = UserShortId;
|
||
};
|
||
CCollaborativeEditingBase.prototype.Remove_ForeignCursor = function(UserId){
|
||
this.m_aForeignCursorsPos.Remove_DocumentPosition(this.m_aCursorsToUpdate[UserId]);
|
||
delete this.m_aForeignCursors[UserId];
|
||
};
|
||
CCollaborativeEditingBase.prototype.Remove_AllForeignCursors = function() {
|
||
for (var UserId in this.m_aForeignCursors) {
|
||
this.Remove_ForeignCursor(UserId);
|
||
}
|
||
};
|
||
CCollaborativeEditingBase.prototype.RemoveMyCursorFromOthers = function() {
|
||
// Удаляем свой курсор у других пользователей
|
||
var oApi = this.GetEditorApi();
|
||
if(!oApi) {
|
||
return;
|
||
}
|
||
oApi.CoAuthoringApi.sendCursor("");
|
||
};
|
||
CCollaborativeEditingBase.prototype.Update_DocumentPositionsOnAdd = function(Class, Pos){
|
||
this.m_aDocumentPositions.Update_DocumentPositionsOnAdd(Class, Pos);
|
||
this.m_aForeignCursorsPos.Update_DocumentPositionsOnAdd(Class, Pos);
|
||
};
|
||
CCollaborativeEditingBase.prototype.Update_DocumentPositionsOnRemove = function(Class, Pos, Count){
|
||
this.m_aDocumentPositions.Update_DocumentPositionsOnRemove(Class, Pos, Count);
|
||
this.m_aForeignCursorsPos.Update_DocumentPositionsOnRemove(Class, Pos, Count);
|
||
};
|
||
CCollaborativeEditingBase.prototype.OnStart_SplitRun = function(SplitRun, SplitPos){
|
||
this.m_aDocumentPositions.OnStart_SplitRun(SplitRun, SplitPos);
|
||
this.m_aForeignCursorsPos.OnStart_SplitRun(SplitRun, SplitPos);
|
||
};
|
||
CCollaborativeEditingBase.prototype.OnEnd_SplitRun = function(NewRun){
|
||
this.m_aDocumentPositions.OnEnd_SplitRun(NewRun);
|
||
this.m_aForeignCursorsPos.OnEnd_SplitRun(NewRun);
|
||
};
|
||
CCollaborativeEditingBase.prototype.Update_DocumentPosition = function(DocPos){
|
||
this.m_aDocumentPositions.Update_DocumentPosition(DocPos);
|
||
};
|
||
CCollaborativeEditingBase.prototype.Update_ForeignCursorPosition = function(UserId, Run, InRunPos, isRemoveLabel) {
|
||
};
|
||
CCollaborativeEditingBase.prototype.Update_ForeignCursorsPositions = function(){
|
||
};
|
||
CCollaborativeEditingBase.prototype.Check_ForeignCursorsLabels = function(X, Y, PageIndex) {
|
||
var DrawingDocument = this.GetDrawingDocument();
|
||
if(!DrawingDocument) {
|
||
return;
|
||
}
|
||
var Px7 = DrawingDocument.GetMMPerDot(7);
|
||
var Px3 = DrawingDocument.GetMMPerDot(3);
|
||
|
||
for (var UserId in this.m_aForeignCursorsXY) {
|
||
var Cursor = this.m_aForeignCursorsXY[UserId];
|
||
if ((true === Cursor.Transform && Cursor.PageIndex === PageIndex && Cursor.X0 - Px3 < X && X < Cursor.X1 + Px3 && Cursor.Y0 - Px3 < Y && Y < Cursor.Y1 + Px3)
|
||
|| (Math.abs(X - Cursor.X) < Px7 && Cursor.Y - Px3 < Y && Y < Cursor.Y + Cursor.H + Px3 && Cursor.PageIndex === PageIndex)) {
|
||
this.Show_ForeignCursorLabel(UserId);
|
||
}
|
||
}
|
||
};
|
||
CCollaborativeEditingBase.prototype.Show_ForeignCursorLabel = function(UserId) {
|
||
var Api = this.GetEditorApi();
|
||
if(!Api) {
|
||
return;
|
||
}
|
||
var DrawingDocument = this.GetDrawingDocument();
|
||
if(!DrawingDocument) {
|
||
return;
|
||
}
|
||
|
||
if (!this.m_aForeignCursorsXY[UserId])
|
||
return;
|
||
|
||
var Cursor = this.m_aForeignCursorsXY[UserId];
|
||
if (Cursor.ShowId)
|
||
clearTimeout(Cursor.ShowId);
|
||
|
||
Cursor.ShowId = setTimeout(function()
|
||
{
|
||
Cursor.ShowId = null;
|
||
Api.sendEvent("asc_onHideForeignCursorLabel", UserId);
|
||
}, AscCommon.FOREIGN_CURSOR_LABEL_HIDETIME);
|
||
|
||
var UserShortId = this.m_aForeignCursorsId[UserId] ? this.m_aForeignCursorsId[UserId] : UserId;
|
||
var Color = AscCommon.getUserColorById(UserShortId, null, true);
|
||
var Coords = DrawingDocument.Collaborative_GetTargetPosition(UserId);
|
||
if (!Color || !Coords)
|
||
return;
|
||
|
||
this.Update_ForeignCursorLabelPosition(UserId, Coords.X, Coords.Y, Color);
|
||
};
|
||
CCollaborativeEditingBase.prototype.Add_ForeignCursorToShow = function(UserId) {
|
||
this.m_aForeignCursorsToShow[UserId] = true;
|
||
};
|
||
CCollaborativeEditingBase.prototype.Remove_ForeignCursorToShow = function(UserId) {
|
||
delete this.m_aForeignCursorsToShow[UserId];
|
||
};
|
||
CCollaborativeEditingBase.prototype.Add_ForeignCursorXY = function(UserId, X, Y, PageIndex, H, Paragraph, isRemoveLabel, SheetId)
|
||
{
|
||
var Cursor;
|
||
if (!this.m_aForeignCursorsXY[UserId])
|
||
{
|
||
Cursor = {X: X, Y: Y, H: H, PageIndex: PageIndex, Transform: false, ShowId: null, SheetId: SheetId};
|
||
this.m_aForeignCursorsXY[UserId] = Cursor;
|
||
}
|
||
else
|
||
{
|
||
Cursor = this.m_aForeignCursorsXY[UserId];
|
||
if (Cursor.ShowId)
|
||
{
|
||
if (true === isRemoveLabel)
|
||
{
|
||
var Api = this.GetEditorApi();
|
||
clearTimeout(Cursor.ShowId);
|
||
Cursor.ShowId = null;
|
||
Api.sendEvent("asc_onHideForeignCursorLabel", UserId);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
Cursor.ShowId = null;
|
||
}
|
||
|
||
Cursor.X = X;
|
||
Cursor.Y = Y;
|
||
Cursor.PageIndex = PageIndex;
|
||
Cursor.H = H;
|
||
Cursor.SheetId = SheetId;
|
||
}
|
||
|
||
var Transform = Paragraph.Get_ParentTextTransform();
|
||
if (Transform)
|
||
{
|
||
Cursor.Transform = true;
|
||
var X0 = Transform.TransformPointX(Cursor.X, Cursor.Y);
|
||
var Y0 = Transform.TransformPointY(Cursor.X, Cursor.Y);
|
||
var X1 = Transform.TransformPointX(Cursor.X, Cursor.Y + Cursor.H);
|
||
var Y1 = Transform.TransformPointY(Cursor.X, Cursor.Y + Cursor.H);
|
||
|
||
Cursor.X0 = Math.min(X0, X1);
|
||
Cursor.Y0 = Math.min(Y0, Y1);
|
||
Cursor.X1 = Math.max(X0, X1);
|
||
Cursor.Y1 = Math.max(Y0, Y1);
|
||
}
|
||
else
|
||
{
|
||
Cursor.Transform = false;
|
||
}
|
||
};
|
||
CCollaborativeEditingBase.prototype.Remove_ForeignCursorXY = function(UserId) {
|
||
if (this.m_aForeignCursorsXY[UserId]) {
|
||
if (this.m_aForeignCursorsXY[UserId].ShowId) {
|
||
var Api = this.GetEditorApi();
|
||
Api.sendEvent("asc_onHideForeignCursorLabel", UserId);
|
||
clearTimeout(this.m_aForeignCursorsXY[UserId].ShowId);
|
||
}
|
||
delete this.m_aForeignCursorsXY[UserId];
|
||
}
|
||
};
|
||
CCollaborativeEditingBase.prototype.private_SaveDocumentState = function() {
|
||
var LogicDocument = (Asc.editor || editor).WordControl.m_oLogicDocument;
|
||
var DocState;
|
||
if (true !== this.Is_Fast()) {
|
||
DocState = LogicDocument.Get_SelectionState2();
|
||
this.m_aCursorsToUpdate = {};
|
||
}
|
||
else {
|
||
DocState = LogicDocument.Save_DocumentStateBeforeLoadChanges(false, true);
|
||
}
|
||
return DocState;
|
||
};
|
||
CCollaborativeEditingBase.prototype.Remove_ForeignCursorToShow = function(UserId) {
|
||
delete this.m_aForeignCursorsToShow[UserId];
|
||
};
|
||
CCollaborativeEditingBase.prototype.private_RestoreDocumentState = function(DocState) {
|
||
var LogicDocument = (Asc.editor || editor).WordControl.m_oLogicDocument;
|
||
if (true !== this.Is_Fast()) {
|
||
LogicDocument.Set_SelectionState2(DocState);
|
||
}
|
||
else {
|
||
LogicDocument.Load_DocumentStateAfterLoadChanges(DocState);
|
||
this.Refresh_ForeignCursors();
|
||
}
|
||
};
|
||
CCollaborativeEditingBase.prototype.WatchDocumentPositionsByState = function(DocState)
|
||
{
|
||
this.Clear_DocumentPositions();
|
||
|
||
if (DocState.Pos)
|
||
this.Add_DocumentPosition(DocState.Pos);
|
||
if (DocState.StartPos)
|
||
this.Add_DocumentPosition(DocState.StartPos);
|
||
if (DocState.EndPos)
|
||
this.Add_DocumentPosition(DocState.EndPos);
|
||
|
||
if (DocState.AnchorPos)
|
||
this.Add_DocumentPosition(DocState.AnchorPos);
|
||
|
||
if (DocState.FootnotesStart && DocState.FootnotesStart.Pos)
|
||
this.Add_DocumentPosition(DocState.FootnotesStart.Pos);
|
||
if (DocState.FootnotesStart && DocState.FootnotesStart.StartPos)
|
||
this.Add_DocumentPosition(DocState.FootnotesStart.StartPos);
|
||
if (DocState.FootnotesStart && DocState.FootnotesStart.EndPos)
|
||
this.Add_DocumentPosition(DocState.FootnotesStart.EndPos);
|
||
if (DocState.FootnotesEnd && DocState.FootnotesEnd.Pos)
|
||
this.Add_DocumentPosition(DocState.FootnotesEnd.Pos);
|
||
if (DocState.FootnotesEnd && DocState.FootnotesEnd.StartPos)
|
||
this.Add_DocumentPosition(DocState.FootnotesEnd.StartPos);
|
||
if (DocState.FootnotesEnd && DocState.FootnotesEnd.EndPos)
|
||
this.Add_DocumentPosition(DocState.FootnotesEnd.EndPos);
|
||
};
|
||
CCollaborativeEditingBase.prototype.UpdateDocumentPositionsByState = function(DocState)
|
||
{
|
||
if (DocState.Pos)
|
||
this.Update_DocumentPosition(DocState.Pos);
|
||
if (DocState.StartPos)
|
||
this.Update_DocumentPosition(DocState.StartPos);
|
||
if (DocState.EndPos)
|
||
this.Update_DocumentPosition(DocState.EndPos);
|
||
|
||
if (DocState.AnchorPos)
|
||
this.Update_DocumentPosition(DocState.AnchorPos);
|
||
|
||
if (DocState.FootnotesStart && DocState.FootnotesStart.Pos)
|
||
this.Update_DocumentPosition(DocState.FootnotesStart.Pos);
|
||
if (DocState.FootnotesStart && DocState.FootnotesStart.StartPos)
|
||
this.Update_DocumentPosition(DocState.FootnotesStart.StartPos);
|
||
if (DocState.FootnotesStart && DocState.FootnotesStart.EndPos)
|
||
this.Update_DocumentPosition(DocState.FootnotesStart.EndPos);
|
||
if (DocState.FootnotesEnd && DocState.FootnotesEnd.Pos)
|
||
this.Update_DocumentPosition(DocState.FootnotesEnd.Pos);
|
||
if (DocState.FootnotesEnd && DocState.FootnotesEnd.StartPos)
|
||
this.Update_DocumentPosition(DocState.FootnotesEnd.StartPos);
|
||
if (DocState.FootnotesEnd && DocState.FootnotesEnd.EndPos)
|
||
this.Update_DocumentPosition(DocState.FootnotesEnd.EndPos);
|
||
};
|
||
CCollaborativeEditingBase.prototype.Update_ForeignCursorLabelPosition = function(UserId, X, Y, Color)
|
||
{
|
||
var oApi = this.GetEditorApi();
|
||
if(!oApi) {
|
||
return;
|
||
}
|
||
var Cursor = this.m_aForeignCursorsXY[UserId];
|
||
if (!Cursor || !Cursor.ShowId)
|
||
return;
|
||
if (this.m_oLogicDocument && this.m_oLogicDocument.IsFocusOnNotes && this.m_oLogicDocument.IsFocusOnNotes())
|
||
{
|
||
Y += parseInt(oApi.WordControl.m_oNotesContainer.HtmlElement.style.top);
|
||
}
|
||
oApi.sendEvent("asc_onShowForeignCursorLabel", UserId, X, Y, new AscCommon.CColor(Color.r, Color.g, Color.b, 255));
|
||
};
|
||
CCollaborativeEditingBase.prototype.GetDocumentPositionBinary = function(oWriter, PosInfo) {
|
||
if (!PosInfo)
|
||
return null;
|
||
var BinaryPos = oWriter.GetCurPosition();
|
||
oWriter.WriteString2(PosInfo.Class.Get_Id());
|
||
oWriter.WriteLong(PosInfo.Position);
|
||
var BinaryLen = oWriter.GetCurPosition() - BinaryPos;
|
||
return (BinaryLen + ";" + oWriter.GetBase64Memory2(BinaryPos, BinaryLen));
|
||
};
|
||
//----------------------------------------------------------------------------------------------------------------------
|
||
// Private area
|
||
//----------------------------------------------------------------------------------------------------------------------
|
||
CCollaborativeEditingBase.prototype.private_ClearChanges = function()
|
||
{
|
||
this.m_aChanges = [];
|
||
this.m_oOwnChanges = [];
|
||
};
|
||
CCollaborativeEditingBase.prototype.private_CollectOwnChanges = function()
|
||
{
|
||
var StartPoint = (null === AscCommon.History.SavedIndex ? 0 : AscCommon.History.SavedIndex + 1);
|
||
var LastPoint = -1;
|
||
|
||
if (this.m_nUseType <= 0)
|
||
LastPoint = AscCommon.History.Points.length - 1;
|
||
else
|
||
LastPoint = AscCommon.History.Index;
|
||
|
||
for (var PointIndex = StartPoint; PointIndex <= LastPoint; PointIndex++)
|
||
{
|
||
var Point = AscCommon.History.Points[PointIndex];
|
||
for (var Index = 0; Index < Point.Items.length; Index++)
|
||
{
|
||
var Item = Point.Items[Index];
|
||
|
||
this.m_oOwnChanges.push(Item.Data);
|
||
}
|
||
}
|
||
};
|
||
CCollaborativeEditingBase.prototype.private_AddOverallChange = function(oChange, isSave)
|
||
{
|
||
// Здесь мы должны смержить пришедшее изменение с одним из наших изменений
|
||
for (var nIndex = 0, nCount = this.m_oOwnChanges.length; nIndex < nCount; ++nIndex)
|
||
{
|
||
if (oChange && oChange.Merge && false === oChange.Merge(this.m_oOwnChanges[nIndex]))
|
||
return false;
|
||
}
|
||
|
||
if (false !== isSave)
|
||
this.CoHistory.AddChange(oChange);
|
||
|
||
return true;
|
||
};
|
||
CCollaborativeEditingBase.prototype._PreUndo = function()
|
||
{
|
||
// Метод для перегрузки, чтобы в каждом редакторе выполнялись свои действия
|
||
return null;
|
||
};
|
||
CCollaborativeEditingBase.prototype._PostUndo = function(state, changes)
|
||
{
|
||
// Метод для перегрузки, чтобы в каждом редакторе выполнялись свои действия
|
||
};
|
||
CCollaborativeEditingBase.prototype.PreUndo = function()
|
||
{
|
||
this.m_oLogicDocument.sendEvent("asc_onBeforeUndoRedoInCollaboration");
|
||
return this._PreUndo();
|
||
};
|
||
CCollaborativeEditingBase.prototype.PostUndo = function(state, changes)
|
||
{
|
||
this._PostUndo(state, changes);
|
||
this.m_oLogicDocument.sendEvent("asc_onUndoRedoInCollaboration");
|
||
};
|
||
CCollaborativeEditingBase.prototype.UndoGlobal = function(count)
|
||
{
|
||
// If we have unaccepted changes then we first remove from them
|
||
if (this.m_aChanges.length >= count)
|
||
{
|
||
this.m_aChanges.length -= count;
|
||
count = 0;
|
||
}
|
||
else
|
||
{
|
||
count -= this.m_aChanges.length;
|
||
this.m_aChanges.length = 0;
|
||
}
|
||
|
||
if (!count)
|
||
return;
|
||
|
||
let editor = this.GetEditorApi();
|
||
if (editor.getViewMode() && !editor.isLiveViewer())
|
||
{
|
||
this.m_nUndoBeforeApply += count;
|
||
}
|
||
else
|
||
{
|
||
let state = this.PreUndo();
|
||
let changes = this.CoHistory.UndoGlobalChanges(count);
|
||
this.PostUndo(state, changes);
|
||
}
|
||
};
|
||
CCollaborativeEditingBase.prototype.UndoGlobalPoint = function()
|
||
{
|
||
// TODO: Handle unaccepted changes from this.m_aChanges
|
||
|
||
let state = this.PreUndo();
|
||
let changes = this.CoHistory.UndoGlobalPoint();
|
||
this.PostUndo(state, changes);
|
||
};
|
||
CCollaborativeEditingBase.prototype.Undo = function()
|
||
{
|
||
if (true === this.Get_GlobalLock())
|
||
return;
|
||
|
||
// TODO: Handle unaccepted changes from this.m_aChanges
|
||
|
||
let state = this.PreUndo();
|
||
let changes = this.CoHistory.UndoOwnPoint();
|
||
this.PostUndo(state, changes);
|
||
};
|
||
CCollaborativeEditingBase.prototype.CanUndoMultipleActions = function()
|
||
{
|
||
return this.CoHistory.CanUndoGlobal();
|
||
};
|
||
CCollaborativeEditingBase.prototype.GetAllChangesCount = function()
|
||
{
|
||
return this.CoHistory.GetChangeCount() - this.m_nUndoBeforeApply + this.m_aChanges.length;
|
||
};
|
||
CCollaborativeEditingBase.prototype.CanUndo = function()
|
||
{
|
||
return this.CoHistory.CanUndoOwn();
|
||
};
|
||
CCollaborativeEditingBase.prototype.private_RecalculateDocument = function(oRecalcData)
|
||
{
|
||
};
|
||
CCollaborativeEditingBase.prototype.private_SaveRecalcChangeIndex = function(isStart)
|
||
{
|
||
if (isStart)
|
||
this.m_nRecalcIndexStart = this.CoHistory.GetChangeCount();
|
||
else
|
||
this.m_nRecalcIndexEnd = this.CoHistory.GetChangeCount() - 1;
|
||
};
|
||
//----------------------------------------------------------------------------------------------------------------------
|
||
// Класс для работы с сохраненными позициями документа.
|
||
//----------------------------------------------------------------------------------------------------------------------
|
||
// Принцип следующий. Заданная позиция - это Run + Позиция внутри данного Run.
|
||
// Если заданный ран был разбит (операция Split), тогда отслеживаем куда перешла
|
||
// заданная позиция, в новый ран или осталась в старом? Если в новый, тогда сохраняем
|
||
// новый ран как отдельную позицию в массив m_aDocumentPositions, и добавляем мап
|
||
// старой позиции в новую m_aDocumentPositionsMap. В конце действия, когда нам нужно
|
||
// определить где же находистся наша позиция, мы сначала проверяем Map, если в нем есть
|
||
// конечная позиция, проверяем является ли заданная позиция валидной в документе.
|
||
// Если да, тогда выставляем ее, если нет, тогда берем Run исходной позиции, и
|
||
// пытаемся сформировать полную позицию по данному Run. Если и это не получается,
|
||
// тогда восстанавливаем позицию по измененной полной исходной позиции.
|
||
//----------------------------------------------------------------------------------------------------------------------
|
||
function CDocumentPositionsManager()
|
||
{
|
||
this.m_aDocumentPositions = [];
|
||
this.m_aDocumentPositionsSplit = [];
|
||
this.m_aDocumentPositionsMap = [];
|
||
}
|
||
CDocumentPositionsManager.prototype.Clear_DocumentPositions = function()
|
||
{
|
||
this.m_aDocumentPositions = [];
|
||
this.m_aDocumentPositionsSplit = [];
|
||
this.m_aDocumentPositionsMap = [];
|
||
};
|
||
CDocumentPositionsManager.prototype.Add_DocumentPosition = function(Position)
|
||
{
|
||
this.m_aDocumentPositions.push(Position);
|
||
};
|
||
CDocumentPositionsManager.prototype.Update_DocumentPositionsOnAdd = function(Class, Pos)
|
||
{
|
||
for (var PosIndex = 0, PosCount = this.m_aDocumentPositions.length; PosIndex < PosCount; ++PosIndex)
|
||
{
|
||
var DocPos = this.m_aDocumentPositions[PosIndex];
|
||
for (var ClassPos = 0, ClassLen = DocPos.length; ClassPos < ClassLen; ++ClassPos)
|
||
{
|
||
var _Pos = DocPos[ClassPos];
|
||
if (Class === _Pos.Class
|
||
&& undefined !== _Pos.Position
|
||
&& (_Pos.Position > Pos
|
||
|| (_Pos.Position === Pos && !(Class instanceof AscCommonWord.ParaRun))))
|
||
{
|
||
_Pos.Position++;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
};
|
||
CDocumentPositionsManager.prototype.Update_DocumentPositionsOnRemove = function(Class, Pos, Count)
|
||
{
|
||
for (var PosIndex = 0, PosCount = this.m_aDocumentPositions.length; PosIndex < PosCount; ++PosIndex)
|
||
{
|
||
var DocPos = this.m_aDocumentPositions[PosIndex];
|
||
for (var ClassPos = 0, ClassLen = DocPos.length; ClassPos < ClassLen; ++ClassPos)
|
||
{
|
||
var _Pos = DocPos[ClassPos];
|
||
if (Class === _Pos.Class && undefined !== _Pos.Position)
|
||
{
|
||
if (_Pos.Position > Pos + Count)
|
||
{
|
||
_Pos.Position -= Count;
|
||
}
|
||
else if (_Pos.Position >= Pos)
|
||
{
|
||
// Элемент, в котором находится наша позиция, удаляется. Ставим специальную отметку об этом.
|
||
_Pos.Position = Pos;
|
||
_Pos.Deleted = true;
|
||
}
|
||
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
};
|
||
CDocumentPositionsManager.prototype.OnStart_SplitRun = function(SplitRun, SplitPos)
|
||
{
|
||
this.m_aDocumentPositionsSplit = [];
|
||
|
||
for (var PosIndex = 0, PosCount = this.m_aDocumentPositions.length; PosIndex < PosCount; ++PosIndex)
|
||
{
|
||
var DocPos = this.m_aDocumentPositions[PosIndex];
|
||
for (var ClassPos = 0, ClassLen = DocPos.length; ClassPos < ClassLen; ++ClassPos)
|
||
{
|
||
var _Pos = DocPos[ClassPos];
|
||
if (SplitRun === _Pos.Class && _Pos.Position && _Pos.Position >= SplitPos)
|
||
{
|
||
this.m_aDocumentPositionsSplit.push({DocPos : DocPos, NewRunPos : _Pos.Position - SplitPos});
|
||
}
|
||
}
|
||
}
|
||
};
|
||
CDocumentPositionsManager.prototype.OnEnd_SplitRun = function(NewRun)
|
||
{
|
||
if (!NewRun)
|
||
return;
|
||
|
||
for (var PosIndex = 0, PosCount = this.m_aDocumentPositionsSplit.length; PosIndex < PosCount; ++PosIndex)
|
||
{
|
||
var NewDocPos = [];
|
||
NewDocPos.push({Class : NewRun, Position : this.m_aDocumentPositionsSplit[PosIndex].NewRunPos});
|
||
this.m_aDocumentPositions.push(NewDocPos);
|
||
this.m_aDocumentPositionsMap.push({StartPos : this.m_aDocumentPositionsSplit[PosIndex].DocPos, EndPos : NewDocPos});
|
||
}
|
||
};
|
||
CDocumentPositionsManager.prototype.Update_DocumentPosition = function(DocPos)
|
||
{
|
||
// Смотрим куда мапится заданная позиция
|
||
var NewDocPos = DocPos;
|
||
for (var PosIndex = 0, PosCount = this.m_aDocumentPositionsMap.length; PosIndex < PosCount; ++PosIndex)
|
||
{
|
||
if (this.m_aDocumentPositionsMap[PosIndex].StartPos === NewDocPos)
|
||
NewDocPos = this.m_aDocumentPositionsMap[PosIndex].EndPos;
|
||
}
|
||
|
||
// Нашли результирующую позицию. Проверим является ли она валидной для документа.
|
||
if (NewDocPos !== DocPos && NewDocPos.length === 1 && NewDocPos[0].Class instanceof AscCommonWord.ParaRun)
|
||
{
|
||
var Run = NewDocPos[0].Class;
|
||
var Para = Run.GetParagraph();
|
||
if (AscCommonWord.CanUpdatePosition(Para, Run))
|
||
{
|
||
DocPos.length = 0;
|
||
Run.GetDocumentPositionFromObject(DocPos);
|
||
DocPos.push({Class : Run, Position : NewDocPos[0].Position});
|
||
}
|
||
}
|
||
// Возможно ран с позицией переместился в другой класс
|
||
else if (DocPos.length > 0 && DocPos[DocPos.length - 1].Class instanceof AscCommonWord.ParaRun)
|
||
{
|
||
var Run = DocPos[DocPos.length - 1].Class;
|
||
var RunPos = DocPos[DocPos.length - 1].Position;
|
||
var Para = Run.GetParagraph();
|
||
if (AscCommonWord.CanUpdatePosition(Para, Run))
|
||
{
|
||
DocPos.length = 0;
|
||
Run.GetDocumentPositionFromObject(DocPos);
|
||
DocPos.push({Class : Run, Position : RunPos});
|
||
}
|
||
}
|
||
};
|
||
CDocumentPositionsManager.prototype.Remove_DocumentPosition = function(DocPos)
|
||
{
|
||
for (var Pos = 0, Count = this.m_aDocumentPositions.length; Pos < Count; ++Pos)
|
||
{
|
||
if (this.m_aDocumentPositions[Pos] === DocPos)
|
||
{
|
||
this.m_aDocumentPositions.splice(Pos, 1);
|
||
return;
|
||
}
|
||
}
|
||
};
|
||
//--------------------------------------------------------export----------------------------------------------------
|
||
window['AscCommon'] = window['AscCommon'] || {};
|
||
window['AscCommon'].FOREIGN_CURSOR_LABEL_HIDETIME = FOREIGN_CURSOR_LABEL_HIDETIME;
|
||
window['AscCommon'].CCollaborativeChanges = CCollaborativeChanges;
|
||
window['AscCommon'].CCollaborativeEditingBase = CCollaborativeEditingBase;
|
||
window['AscCommon'].CDocumentPositionsManager = CDocumentPositionsManager;
|
||
})(window);
|