Files
DocumentServer-v-9.2.0/sdkjs/slide/Editor/CollaborativeEditing.js
T
Yajbir Singh f1b860b25c
check / markdownlint (push) Has been cancelled
check / spellchecker (push) Has been cancelled
updated
2025-12-11 19:03:17 +05:30

647 lines
23 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";
/**
*
* @constructor
* @extends {AscCommon.CCollaborativeEditingBase}
*/
function CCollaborativeEditing()
{
AscCommon.CCollaborativeEditingBase.call(this);
this.PosExtChangesX = [];
this.PosExtChangesY = [];
this.ScaleX = null;
this.ScaleY = null;
}
CCollaborativeEditing.prototype = Object.create(AscCommon.CCollaborativeEditingBase.prototype);
CCollaborativeEditing.prototype.constructor = CCollaborativeEditing;
CCollaborativeEditing.prototype.GetEditorApi = function()
{
return Asc.editor;
};
CCollaborativeEditing.prototype.GetDrawingDocument = function()
{
return Asc.editor.getDrawingDocument();
};
CCollaborativeEditing.prototype.GetPresentation = function()
{
return Asc.editor.private_GetLogicDocument();
};
CCollaborativeEditing.prototype.Send_Changes = function(IsUserSave, AdditionalInfo, IsUpdateInterface, isAfterAskSave)
{
// Пересчитываем позиции
this.Refresh_DCChanges();
this.RefreshPosExtChanges();
// Генерируем свои изменения
let StartPoint = ( null === AscCommon.History.SavedIndex ? 0 : AscCommon.History.SavedIndex + 1 );
let LastPoint = -1;
if ( this.m_nUseType <= 0 )
{
// (ненужные точки предварительно удаляем)
AscCommon.History.Clear_Redo();
LastPoint = AscCommon.History.Points.length - 1;
}
else
{
LastPoint = AscCommon.History.Index;
}
// Просчитаем сколько изменений на сервер пересылать не надо
let SumIndex = 0;
let StartPoint2 = Math.min( StartPoint, LastPoint + 1 );
for ( let PointIndex = 0; PointIndex < StartPoint2; PointIndex++ )
{
let Point = AscCommon.History.Points[PointIndex];
SumIndex += Point.Items.length;
}
let deleteIndex = ( null === AscCommon.History.SavedIndex ? null : SumIndex );
let aChanges = [], aChanges2 = [];
for ( let PointIndex = StartPoint; PointIndex <= LastPoint; PointIndex++ )
{
let Point = AscCommon.History.Points[PointIndex];
AscCommon.History.Update_PointInfoItem(PointIndex, StartPoint, LastPoint, SumIndex, deleteIndex);
for ( let Index = 0; Index < Point.Items.length; Index++ )
{
let Item = Point.Items[Index];
let oChanges = new AscCommon.CCollaborativeChanges();
oChanges.Set_FromUndoRedo( Item.Class, Item.Data, Item.Binary );
aChanges2.push(Item.Data);
aChanges.push( oChanges.m_pData );
}
}
// Пока пользователь сидит один, мы не чистим его локи до тех пор пока не зайдет второй
let bCollaborative = this.getCollaborativeEditing();
let num_arr = [];
let drawingDocument = this.GetDrawingDocument();
let presentation = this.GetPresentation();
if (bCollaborative)
{
let map = this.Release_Locks();
let UnlockCount2 = this.m_aNeedUnlock2.length;
for (let Index = 0; Index < UnlockCount2; Index++ )
{
let Class = this.m_aNeedUnlock2[Index];
Class.Lock.Set_Type( AscCommon.c_oAscLockTypes.kLockTypeNone, false);
if(Class instanceof AscCommon.CCore)
{
Asc.editor.sendEvent("asc_onLockCore", false);
}
let check_obj = null;
if(Class.getObjectType)
{
if(Class.isDrawing && AscCommon.isRealObject(Class.parent))
{
let nParentNum = Class.getParentNum();
if(nParentNum !== -1)
{
map[nParentNum] = true;
}
check_obj =
{
"type": c_oAscLockTypeElemPresentation.Object,
"slideId": Class.parent.Get_Id(),
"objId": Class.Get_Id(),
"guid": Class.Get_Id()
};
}
else if(AscFormat.isSlideLikeObject(Class))
{
check_obj =
{
"type": c_oAscLockTypeElemPresentation.Slide,
"val": Class.Get_Id(),
"guid": Class.Get_Id()
};
}
else if(Class instanceof AscCommon.CComment){
if(Class.Parent && Class.Parent.slide){
if(Class.Parent.slide === presentation){
check_obj =
{
"type": c_oAscLockTypeElemPresentation.Slide,
"val": presentation.commentsLock.Get_Id(),
"guid": presentation.commentsLock.Get_Id()
};
}
else {
if(Class.Parent.slide.deleteLock){
check_obj =
{
"type": c_oAscLockTypeElemPresentation.Object,
"slideId": Class.Parent.slide.deleteLock.Get_Id(),
"objId": Class.Get_Id(),
"guid": Class.Get_Id()
};
map[Class.Parent.slide.num] = true;
}
}
}
}
if(check_obj)
Asc.editor.CoAuthoringApi.releaseLocks( check_obj );
}
}
if(Asc.editor.WordControl.m_oDrawingDocument.IsLockObjectsEnable)
{
for(let key in map)
{
if(map.hasOwnProperty(key))
{
num_arr.push(parseInt(key, 10));
}
}
num_arr.sort(AscCommon.fSortAscending);
}
this.m_aNeedUnlock.length = 0;
this.m_aNeedUnlock2.length = 0;
}
if (0 < aChanges.length || null !== deleteIndex)
{
this.CoHistory.AddOwnChanges(aChanges2, deleteIndex);
Asc.editor.CoAuthoringApi.saveChanges(aChanges, deleteIndex, AdditionalInfo, editor.canUnlockDocument2, bCollaborative);
AscCommon.History.CanNotAddChanges = true;
} else
Asc.editor.CoAuthoringApi.unLockDocument(!!isAfterAskSave, editor.canUnlockDocument2, null, bCollaborative);
Asc.editor.canUnlockDocument2 = false;
if ( -1 === this.m_nUseType )
{
// Чистим Undo/Redo только во время совместного редактирования
AscCommon.History.Clear();
AscCommon.History.SavedIndex = null;
}
else if ( 0 === this.m_nUseType )
{
// Чистим Undo/Redo только во время совместного редактирования
AscCommon.History.Clear();
AscCommon.History.SavedIndex = null;
this.m_nUseType = 1;
}
else
{
// Обновляем точку последнего сохранения в истории
AscCommon.History.Reset_SavedIndex(IsUserSave);
}
for(let i = 0; i < num_arr.length; ++i)
{
Asc.editor.WordControl.m_oDrawingDocument.OnRecalculateSlide(num_arr[i]);
}
if(num_arr.length > 0)
{
Asc.editor.WordControl.m_oDrawingDocument.OnEndRecalculate();
}
let oSlide = presentation.GetCurrentSlide();
if(oSlide && oSlide.notesShape){
Asc.editor.WordControl.m_oDrawingDocument.Notes_OnRecalculate(presentation.CurPage, oSlide.NotesWidth, oSlide.getNotesHeight());
}
presentation.Document_UpdateInterfaceState();
presentation.Document_UpdateUndoRedoState();
// drawingDocument.ClearCachePages();
// drawingDocument.FirePaint();
};
CCollaborativeEditing.prototype.Release_Locks = function()
{
let map_redraw = {};
let UnlockCount = this.m_aNeedUnlock.length;
let presentation = this.GetPresentation();
for ( let Index = 0; Index < UnlockCount; Index++ )
{
let CurLockType = this.m_aNeedUnlock[Index].Lock.Get_Type();
let Class = this.m_aNeedUnlock[Index];
if ( AscCommon.c_oAscLockTypes.kLockTypeOther3 != CurLockType && AscCommon.c_oAscLockTypes.kLockTypeOther != CurLockType )
{
Class.Lock.Set_Type( AscCommon.c_oAscLockTypes.kLockTypeNone, false);
if ( Class instanceof AscCommonSlide.PropLocker )
{
let object = AscCommon.g_oTableId.Get_ById(Class.objectId);
if(object instanceof AscCommonSlide.CPresentation)
{
if(Class === presentation.themeLock)
{
Asc.editor.sendEvent("asc_onUnLockDocumentTheme");
}
else if(Class === presentation.schemeLock)
{
Asc.editor.sendEvent("asc_onUnLockDocumentSchema");
}
else if(Class === presentation.slideSizeLock)
{
Asc.editor.sendEvent("asc_onUnLockDocumentProps");
}
else if(Class === presentation.viewPrLock)
{
Asc.editor.sendEvent("asc_onUnLockViewProps");
}
else if (Class === presentation.hdrFtrLock)
{
Asc.editor.sendEvent("asc_onUnLockSlideHdrFtrApplyToAll");
}
}
}
if(Class instanceof AscCommon.CComment)
{
Asc.editor.sync_UnLockComment(Class.Get_Id());
if(Class.Parent && Class.Parent.slide && presentation !== Class.Parent.slide)
{
map_redraw[Class.Parent.slide.num] = true;
}
}
if(Class instanceof AscCommon.CCore)
{
Asc.editor.sendEvent("asc_onLockCore", false);
}
}
else if ( AscCommon.c_oAscLockTypes.kLockTypeOther3 === CurLockType )
{
Class.Lock.Set_Type( AscCommon.c_oAscLockTypes.kLockTypeOther, false);
}
if(Class.isDrawing)
{
let nIdx = Class.getParentNum();
if(nIdx !== -1)
{
map_redraw[nIdx] = true;
}
}
}
return map_redraw;
};
CCollaborativeEditing.prototype.OnEnd_Load_Objects = function()
{
// Данная функция вызывается, когда загрузились внешние объекты (картинки и шрифты)
// Снимаем лок
AscCommon.CollaborativeEditing.Set_GlobalLock(false);
AscCommon.CollaborativeEditing.Set_GlobalLockSelection(false);
// Запускаем полный пересчет документа
let LogicDocument = this.GetPresentation();
const arrChanges = this.CoHistory.GetAllChanges();
const oRecalcData = LogicDocument.History.Get_RecalcData(null, arrChanges, this.m_nRecalcIndexStart, this.m_nRecalcIndexEnd);
LogicDocument.Recalculate(oRecalcData);
LogicDocument.Document_UpdateSelectionState();
LogicDocument.Document_UpdateInterfaceState();
Asc.editor.sync_EndAction(Asc.c_oAscAsyncActionType.BlockInteraction, Asc.c_oAscAsyncAction.ApplyChanges);
};
CCollaborativeEditing.prototype.OnEnd_CheckLock = function(DontLockInFastMode)
{
let drawingDocument = this.GetDrawingDocument();
let aIds = [];
let Count = this.m_aCheckLocks.length;
for ( let Index = 0; Index < Count; Index++ )
{
let oItem = this.m_aCheckLocks[Index];
if ( true === oItem ) // сравниваем по значению и типу обязательно
return true;
else if ( false !== oItem )
aIds.push( oItem );
}
if (true === DontLockInFastMode && true === this.Is_Fast())
return false;
if ( aIds.length > 0 )
{
// Отправляем запрос на сервер со списком Id
Asc.editor.CoAuthoringApi.askLock( aIds, this.OnCallback_AskLock );
// Ставим глобальный лок, только во время совместного редактирования
if ( -1 === this.m_nUseType )
{
this.Set_GlobalLock(true);
}
else
{
// Пробегаемся по массиву и проставляем, что залочено нами
Count = this.m_aCheckLocks.length;
for ( let Index = 0; Index < Count; Index++ )
{
let oItem = this.m_aCheckLocks[Index];
let items = [];
switch(oItem["type"])
{
case c_oAscLockTypeElemPresentation.Object:
{
items.push(oItem["objId"]);
items.push(oItem["slideId"]);
break;
}
case c_oAscLockTypeElemPresentation.Slide:
{
items.push(oItem["val"]);
break;
}
case c_oAscLockTypeElemPresentation.Presentation:
{
break;
}
}
for(let i = 0; i < items.length; ++i)
{
let item = items[i];
if ( true !== item && false !== item ) // сравниваем по значению и типу обязательно
{
let Class = AscCommon.g_oTableId.Get_ById( item );
if ( null != Class )
{
Class.Lock.Set_Type( AscCommon.c_oAscLockTypes.kLockTypeMine, false );
this.Add_Unlock2( Class );
}
}
}
}
this.m_aCheckLocks.length = 0;
}
}
return false;
};
CCollaborativeEditing.prototype.OnCallback_AskLock = function(result)
{
let presentation = AscCommon.CollaborativeEditing.GetPresentation();
if (true === AscCommon.CollaborativeEditing.Get_GlobalLock())
{
if (!Asc.editor.checkLongActionCallback(AscCommon.CollaborativeEditing.OnCallback_AskLock, result))
return;
// Снимаем глобальный лок
AscCommon.CollaborativeEditing.Set_GlobalLock(false);
if (result["lock"])
{
// Пробегаемся по массиву и проставляем, что залочено нами
let Count = AscCommon.CollaborativeEditing.m_aCheckLocks.length;
for ( let Index = 0; Index < Count; Index++ )
{
let oItem = AscCommon.CollaborativeEditing.m_aCheckLocks[Index];
let item;
switch(oItem["type"])
{
case c_oAscLockTypeElemPresentation.Object:
{
item = oItem["objId"];
break;
}
case c_oAscLockTypeElemPresentation.Slide:
{
item = oItem["val"];
break;
}
case c_oAscLockTypeElemPresentation.Presentation:
{
break;
}
}
if ( true !== oItem && false !== oItem ) // сравниваем по значению и типу обязательно
{
let Class = AscCommon.g_oTableId.Get_ById( item );
if ( null != Class )
{
Class.Lock.Set_Type( AscCommon.c_oAscLockTypes.kLockTypeMine );
AscCommon.CollaborativeEditing.Add_Unlock2( Class );
}
}
}
}
else if (result["error"])
{
// Если у нас началось редактирование диаграммы, а вернулось, что ее редактировать нельзя,
// посылаем сообщение о закрытии редактора диаграмм.
if (Asc.editor.frameManager.isLoadingChartEditor)
Asc.editor.sync_closeChartEditor();
if (Asc.editor.frameManager.isLoadingOleEditor)
Asc.editor.sync_closeOleEditor();
// Делаем откат на 1 шаг назад и удаляем из Undo/Redo эту последнюю точку
presentation.Document_Undo();
AscCommon.History.Clear_Redo();
}
}
Asc.editor.frameManager.endLoadChartEditor();
Asc.editor.frameManager.endLoadOleEditor();
};
CCollaborativeEditing.prototype.AddPosExtChanges = function(Item, ChangeObject)
{
if(ChangeObject.IsHorizontal())
{
this.PosExtChangesX.push(Item);
}
else
{
this.PosExtChangesY.push(Item);
}
};
CCollaborativeEditing.prototype.RewritePosExtChanges = function(changesArr, scale)
{
for(let i = 0; i < changesArr.length; ++i)
{
let changes = changesArr[i];
let data = changes.Data;
data.New *= scale;
data.Old *= scale;
let Binary_Writer = AscCommon.History.BinaryWriter;
let Binary_Pos = Binary_Writer.GetCurPosition();
if (Asc.editor.binaryChanges) {
Binary_Writer.WriteWithLen(this, function () {
Binary_Writer.WriteString2(changes.Class.Get_Id());
Binary_Writer.WriteLong(changes.Data.Type);
changes.Data.WriteToBinary(Binary_Writer);
});
} else {
Binary_Writer.WriteString2(changes.Class.Get_Id());
Binary_Writer.WriteLong(changes.Data.Type);
changes.Data.WriteToBinary(Binary_Writer);
}
let Binary_Len = Binary_Writer.GetCurPosition() - Binary_Pos;
changes.Binary.Pos = Binary_Pos;
changes.Binary.Len = Binary_Len;
}
};
CCollaborativeEditing.prototype.RefreshPosExtChanges = function()
{
if(this.ScaleX != null && this.ScaleY != null)
{
this.RewritePosExtChanges(this.PosExtChangesX, this.ScaleX);
this.RewritePosExtChanges(this.PosExtChangesY, this.ScaleY);
}
this.PosExtChangesX.length = 0;
this.PosExtChangesY.length = 0;
this.ScaleX = null;
this.ScaleY = null;
};
CCollaborativeEditing.prototype.Update_ForeignCursorsPositions = function()
{
let DrawingDocument = this.GetDrawingDocument();
let oPresentation = this.GetPresentation();
let oTargetDocContentOrTable;
let oCurController = oPresentation.GetCurrentController();
if(oCurController){
oTargetDocContentOrTable = oCurController.getTargetDocContent(undefined, true);
}
if(!oTargetDocContentOrTable){
for (let UserId in this.m_aForeignCursors){
DrawingDocument.Collaborative_RemoveTarget(UserId);
}
return;
}
let bTable = (oTargetDocContentOrTable instanceof AscCommonWord.CTable);
for (let UserId in this.m_aForeignCursors){
let DocPos = this.m_aForeignCursors[UserId];
if (!DocPos || DocPos.length <= 0)
continue;
this.m_aForeignCursorsPos.Update_DocumentPosition(DocPos);
let Run = DocPos[DocPos.length - 1].Class;
let InRunPos = DocPos[DocPos.length - 1].Position;
this.Update_ForeignCursorPosition(UserId, Run, InRunPos, false, oTargetDocContentOrTable, bTable);
}
};
CCollaborativeEditing.prototype.Update_ForeignCursorPosition = function(UserId, Run, InRunPos, isRemoveLabel, oTargetDocContentOrTable, bTable){
if (!(Run instanceof AscCommonWord.ParaRun))
return;
let DrawingDocument = this.GetDrawingDocument();
let oPresentation = this.GetPresentation();
let Paragraph = Run.GetParagraph();
if (!Paragraph || !Paragraph.Parent){
DrawingDocument.Collaborative_RemoveTarget(UserId);
return;
}
if(!bTable){
if(oTargetDocContentOrTable !== Paragraph.Parent){
DrawingDocument.Collaborative_RemoveTarget(UserId);
return;
}
}
else{
if(!Paragraph.Parent.Parent || !Paragraph.Parent.Parent.Row ||
!Paragraph.Parent.Parent.Row.Table || Paragraph.Parent.Parent.Row.Table !== oTargetDocContentOrTable){
DrawingDocument.Collaborative_RemoveTarget(UserId);
return;
}
}
let ParaContentPos = Paragraph.Get_PosByElement(Run);
if (!ParaContentPos){
DrawingDocument.Collaborative_RemoveTarget(UserId);
return;
}
ParaContentPos.Update(InRunPos, ParaContentPos.GetDepth() + 1);
let XY = Paragraph.Get_XYByContentPos(ParaContentPos);
if (XY && XY.Height > 0.001){
let ShortId = this.m_aForeignCursorsId[UserId] ? this.m_aForeignCursorsId[UserId] : UserId;
DrawingDocument.Collaborative_UpdateTarget(UserId, ShortId, XY.X, XY.Y, XY.Height, oPresentation.CurPage, Paragraph.Get_ParentTextTransform());
this.Add_ForeignCursorXY(UserId, XY.X, XY.Y, XY.PageNum, XY.Height, Paragraph, isRemoveLabel);
if (true === this.m_aForeignCursorsToShow[UserId]){
this.Show_ForeignCursorLabel(UserId);
this.Remove_ForeignCursorToShow(UserId);
}
}
else{
DrawingDocument.Collaborative_RemoveTarget(UserId);
this.Remove_ForeignCursorXY(UserId);
this.Remove_ForeignCursorToShow(UserId);
}
};
CCollaborativeEditing.prototype.private_RecalculateDocument = function(arrChanges){
this.GetPresentation().Recalculate(AscCommon.History.Get_RecalcData(null, arrChanges));
};
CCollaborativeEditing.prototype.private_UpdateForeignCursor = function(CursorInfo, UserId, Show, UserShortId)
{
this.GetPresentation().Update_ForeignCursor(CursorInfo, UserId, Show, UserShortId);
};
CCollaborativeEditing.prototype._PreUndo = function() {
let logicDocument = this.m_oLogicDocument;
logicDocument.DrawingDocument.EndTrackTable(null, true);
logicDocument.TurnOffCheckChartSelection();
return this.private_SaveDocumentState();
};
CCollaborativeEditing.prototype._PostUndo = function(state, changes) {
this.private_RestoreDocumentState(state);
this.private_RecalculateDocument(changes);
let logicDocument = this.m_oLogicDocument;
logicDocument.TurnOnCheckChartSelection();
logicDocument.UpdateSelection();
logicDocument.UpdateInterface();
logicDocument.UpdateRulers();
};
//--------------------------------------------------------export----------------------------------------------------
window['AscCommon'] = window['AscCommon'] || {};
window['AscCommon'].SlideCollaborativeEditing = CCollaborativeEditing;