529 lines
22 KiB
JavaScript
529 lines
22 KiB
JavaScript
/*
|
|
* (c) Copyright Ascensio System SIA 2010-2015
|
|
*
|
|
* 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 Lubanas st. 125a-25, Riga, Latvia,
|
|
* EU, LV-1021.
|
|
*
|
|
* 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 CHistory(Document) {
|
|
this.Index = -1;
|
|
this.SavedIndex = null;
|
|
this.ForceSave = false;
|
|
this.RecIndex = -1;
|
|
this.Points = [];
|
|
this.Document = Document;
|
|
this.RecalculateData = {
|
|
Inline: {
|
|
Pos: -1,
|
|
PageNum: 0
|
|
},
|
|
Flow: [],
|
|
HdrFtr: [],
|
|
Drawings: {
|
|
All: false,
|
|
Map: {},
|
|
ThemeInfo: null
|
|
}
|
|
};
|
|
this.TurnOffHistory = false;
|
|
this.MinorChanges = false;
|
|
this.BinaryWriter = new CMemory();
|
|
this.FileCheckSum = 0;
|
|
this.FileSize = 0;
|
|
}
|
|
CHistory.prototype = {
|
|
Update_FileDescription: function (oStream) {
|
|
var pData = oStream.data;
|
|
var nSize = oStream.size;
|
|
this.FileCheckSum = g_oCRC32.Calculate_ByByteArray(pData, nSize);
|
|
this.FileSize = nSize;
|
|
},
|
|
Update_PointInfoItem: function (PointIndex, StartPoint, LastPoint, SumIndex, DeletedIndex) {
|
|
var Point = this.Points[PointIndex];
|
|
if (Point) {
|
|
var Class = g_oTableId;
|
|
if (Point.Items.length > 0) {
|
|
var FirstItem = Point.Items[0];
|
|
if (FirstItem.Class === Class && historyitem_TableId_Description === FirstItem.Data.Type) {
|
|
Point.Items.splice(0, 1);
|
|
}
|
|
}
|
|
var Data = {
|
|
Type: historyitem_TableId_Description,
|
|
FileCheckSum: this.FileCheckSum,
|
|
FileSize: this.FileSize,
|
|
Description: Point.Description,
|
|
ItemsCount: Point.Items.length,
|
|
PointIndex: PointIndex,
|
|
StartPoint: StartPoint,
|
|
LastPoint: LastPoint,
|
|
SumIndex: SumIndex,
|
|
DeletedIndex: DeletedIndex
|
|
};
|
|
var Binary_Pos = this.BinaryWriter.GetCurPosition();
|
|
this.BinaryWriter.WriteString2(Class.Get_Id());
|
|
Class.Save_Changes(Data, this.BinaryWriter);
|
|
var Binary_Len = this.BinaryWriter.GetCurPosition() - Binary_Pos;
|
|
var Item = {
|
|
Class: Class,
|
|
Data: Data,
|
|
Binary: {
|
|
Pos: Binary_Pos,
|
|
Len: Binary_Len
|
|
},
|
|
NeedRecalc: false
|
|
};
|
|
Point.Items.splice(0, 0, Item);
|
|
}
|
|
},
|
|
Is_Clear: function () {
|
|
if (this.Points.length <= 0) {
|
|
return true;
|
|
}
|
|
return false;
|
|
},
|
|
Clear: function () {
|
|
this.Index = -1;
|
|
this.SavedIndex = null;
|
|
this.ForceSave = false;
|
|
this.Points.length = 0;
|
|
this.Internal_RecalcData_Clear();
|
|
},
|
|
Can_Undo: function () {
|
|
if (this.Index >= 0) {
|
|
return true;
|
|
}
|
|
return false;
|
|
},
|
|
Can_Redo: function () {
|
|
if (this.Points.length > 0 && this.Index < this.Points.length - 1) {
|
|
return true;
|
|
}
|
|
return false;
|
|
},
|
|
Undo: function () {
|
|
this.Check_UninonLastPoints();
|
|
if (true != this.Can_Undo()) {
|
|
return null;
|
|
}
|
|
if (editor) {
|
|
editor.setUserAlive();
|
|
}
|
|
if (this.Index === this.Points.length - 1) {
|
|
this.LastState = this.Document.Get_SelectionState();
|
|
}
|
|
this.Document.Selection_Remove();
|
|
var Point = this.Points[this.Index--];
|
|
this.Internal_RecalcData_Clear();
|
|
for (var Index = Point.Items.length - 1; Index >= 0; Index--) {
|
|
var Item = Point.Items[Index];
|
|
Item.Class.Undo(Item.Data);
|
|
Item.Class.Refresh_RecalcData(Item.Data);
|
|
}
|
|
this.Document.Set_SelectionState(Point.State);
|
|
return this.RecalculateData;
|
|
},
|
|
Redo: function () {
|
|
if (true != this.Can_Redo()) {
|
|
return null;
|
|
}
|
|
if (editor) {
|
|
editor.setUserAlive();
|
|
}
|
|
this.Document.Selection_Remove();
|
|
var Point = this.Points[++this.Index];
|
|
this.Internal_RecalcData_Clear();
|
|
for (var Index = 0; Index < Point.Items.length; Index++) {
|
|
var Item = Point.Items[Index];
|
|
Item.Class.Redo(Item.Data);
|
|
Item.Class.Refresh_RecalcData(Item.Data);
|
|
}
|
|
var State = null;
|
|
if (this.Index === this.Points.length - 1) {
|
|
State = this.LastState;
|
|
} else {
|
|
State = this.Points[this.Index + 1].State;
|
|
}
|
|
this.Document.Set_SelectionState(State);
|
|
return this.RecalculateData;
|
|
},
|
|
Create_NewPoint: function (Description) {
|
|
if (this.Index < this.SavedIndex && null !== this.SavedIndex) {
|
|
this.SavedIndex = this.Index;
|
|
this.ForceSave = true;
|
|
}
|
|
this.Clear_Additional();
|
|
this.Check_UninonLastPoints();
|
|
var State = this.Document.Get_SelectionState();
|
|
var Items = [];
|
|
var Time = new Date().getTime();
|
|
this.Points[++this.Index] = {
|
|
State: State,
|
|
Items: Items,
|
|
Time: Time,
|
|
Additional: {},
|
|
Description: Description
|
|
};
|
|
this.Points.length = this.Index + 1;
|
|
},
|
|
Remove_LastPoint: function () {
|
|
this.Index--;
|
|
this.Points.length = this.Index + 1;
|
|
},
|
|
Clear_Redo: function () {
|
|
this.Points.length = this.Index + 1;
|
|
},
|
|
Add: function (Class, Data) {
|
|
if (true === this.TurnOffHistory) {
|
|
return;
|
|
}
|
|
if (this.Index < 0) {
|
|
return;
|
|
}
|
|
if (editor) {
|
|
editor.setUserAlive();
|
|
}
|
|
if (this.RecIndex >= this.Index) {
|
|
this.RecIndex = this.Index - 1;
|
|
}
|
|
var Binary_Pos = this.BinaryWriter.GetCurPosition();
|
|
this.BinaryWriter.WriteString2(Class.Get_Id());
|
|
Class.Save_Changes(Data, this.BinaryWriter);
|
|
var Binary_Len = this.BinaryWriter.GetCurPosition() - Binary_Pos;
|
|
var Item = {
|
|
Class: Class,
|
|
Data: Data,
|
|
Binary: {
|
|
Pos: Binary_Pos,
|
|
Len: Binary_Len
|
|
},
|
|
NeedRecalc: !this.MinorChanges
|
|
};
|
|
this.Points[this.Index].Items.push(Item);
|
|
var bZIndexManager = !(typeof ZIndexManager === "undefined");
|
|
var bPresentation = !(typeof CPresentation === "undefined");
|
|
var bSlide = !(typeof Slide === "undefined");
|
|
if ((Class instanceof CDocument && (historyitem_Document_AddItem === Data.Type || historyitem_Document_RemoveItem === Data.Type)) || (Class instanceof CDocumentContent && (historyitem_DocumentContent_AddItem === Data.Type || historyitem_DocumentContent_RemoveItem === Data.Type)) || (Class instanceof CTable && (historyitem_Table_AddRow === Data.Type || historyitem_Table_RemoveRow === Data.Type)) || (Class instanceof CTableRow && (historyitem_TableRow_AddCell === Data.Type || historyitem_TableRow_RemoveCell === Data.Type)) || (Class instanceof Paragraph && (historyitem_Paragraph_AddItem === Data.Type || historyitem_Paragraph_RemoveItem === Data.Type)) || (Class instanceof ParaHyperlink && (historyitem_Hyperlink_AddItem === Data.Type || historyitem_Hyperlink_RemoveItem === Data.Type)) || (Class instanceof ParaRun && (historyitem_ParaRun_AddItem === Data.Type || historyitem_ParaRun_RemoveItem === Data.Type)) || (bZIndexManager && Class instanceof ZIndexManager && (historyitem_ZIndexManagerRemoveItem === Data.Type || historyitem_ZIndexManagerAddItem === Data.Type)) || (bPresentation && Class instanceof CPresentation && (historyitem_Presentation_AddSlide === Data.Type || historyitem_Presentation_RemoveSlide === Data.Type)) || (bSlide && Class instanceof Slide && (historyitem_SlideAddToSpTree === Data.Type || historyitem_SlideRemoveFromSpTree === Data.Type))) {
|
|
var bAdd = ((Class instanceof CDocument && historyitem_Document_AddItem === Data.Type) || (Class instanceof CDocumentContent && historyitem_DocumentContent_AddItem === Data.Type) || (Class instanceof CTable && historyitem_Table_AddRow === Data.Type) || (Class instanceof CTableRow && historyitem_TableRow_AddCell === Data.Type) || (Class instanceof Paragraph && historyitem_Paragraph_AddItem === Data.Type) || (Class instanceof ParaHyperlink && historyitem_Hyperlink_AddItem === Data.Type) || (Class instanceof ParaRun && historyitem_ParaRun_AddItem === Data.Type) || (bZIndexManager && Class instanceof ZIndexManager && historyitem_ZIndexManagerAddItem === Data.Type) || (bPresentation && Class instanceof CPresentation && (historyitem_Presentation_AddSlide === Data.Type)) || (bSlide && Class instanceof Slide && (historyitem_SlideAddToSpTree === Data.Type))) ? true : false;
|
|
var Count = 1;
|
|
if ((Class instanceof Paragraph) || (Class instanceof ParaHyperlink) || (Class instanceof ParaRun) || (Class instanceof CDocument && historyitem_Document_RemoveItem === Data.Type) || (Class instanceof CDocumentContent && historyitem_DocumentContent_RemoveItem === Data.Type)) {
|
|
Count = Data.Items.length;
|
|
}
|
|
var ContentChanges = new CContentChangesElement((bAdd == true ? contentchanges_Add : contentchanges_Remove), Data.Pos, Count, Item);
|
|
Class.Add_ContentChanges(ContentChanges);
|
|
CollaborativeEditing.Add_NewDC(Class);
|
|
}
|
|
if (CollaborativeEditing.AddPosExtChanges && Class instanceof CXfrm) {
|
|
if (historyitem_Xfrm_SetOffX === Data.Type || historyitem_Xfrm_SetOffY === Data.Type || historyitem_Xfrm_SetExtX === Data.Type || historyitem_Xfrm_SetExtY === Data.Type || historyitem_Xfrm_SetChOffX === Data.Type || historyitem_Xfrm_SetChOffY === Data.Type || historyitem_Xfrm_SetChExtX === Data.Type || historyitem_Xfrm_SetChExtY === Data.Type) {
|
|
CollaborativeEditing.AddPosExtChanges(Item, historyitem_Xfrm_SetOffX === Data.Type || historyitem_Xfrm_SetExtX === Data.Type || historyitem_Xfrm_SetChOffX === Data.Type || historyitem_Xfrm_SetChExtX === Data.Type);
|
|
}
|
|
}
|
|
},
|
|
Internal_RecalcData_Clear: function () {
|
|
this.RecalculateData = {
|
|
Inline: {
|
|
Pos: -1,
|
|
PageNum: 0
|
|
},
|
|
Flow: [],
|
|
HdrFtr: [],
|
|
Drawings: {
|
|
All: false,
|
|
Map: {},
|
|
ThemeInfo: null
|
|
}
|
|
};
|
|
},
|
|
RecalcData_Add: function (Data) {
|
|
if ("undefined" === typeof(Data) || null === Data) {
|
|
return;
|
|
}
|
|
switch (Data.Type) {
|
|
case historyrecalctype_Flow:
|
|
var bNew = true;
|
|
for (var Index = 0; Index < this.RecalculateData.Flow.length; Index++) {
|
|
if (this.RecalculateData.Flow[Index] === Data.Data) {
|
|
bNew = false;
|
|
break;
|
|
}
|
|
}
|
|
if (true === bNew) {
|
|
this.RecalculateData.Flow.push(Data.Data);
|
|
}
|
|
break;
|
|
case historyrecalctype_HdrFtr:
|
|
if (null === Data.Data) {
|
|
break;
|
|
}
|
|
var bNew = true;
|
|
for (var Index = 0; Index < this.RecalculateData.HdrFtr.length; Index++) {
|
|
if (this.RecalculateData.HdrFtr[Index] === Data.Data) {
|
|
bNew = false;
|
|
break;
|
|
}
|
|
}
|
|
if (true === bNew) {
|
|
this.RecalculateData.HdrFtr.push(Data.Data);
|
|
}
|
|
break;
|
|
case historyrecalctype_Inline:
|
|
if ((Data.Data.Pos < this.RecalculateData.Inline.Pos) || (Data.Data.Pos === this.RecalculateData.Inline.Pos && Data.Data.PageNum < this.RecalculateData.Inline.PageNum) || this.RecalculateData.Inline.Pos < 0) {
|
|
this.RecalculateData.Inline.Pos = Data.Data.Pos;
|
|
this.RecalculateData.Inline.PageNum = Data.Data.PageNum;
|
|
}
|
|
break;
|
|
case historyrecalctype_Drawing:
|
|
if (!this.RecalculateData.Drawings.All) {
|
|
if (Data.All) {
|
|
this.RecalculateData.Drawings.All = true;
|
|
} else {
|
|
if (Data.Theme) {
|
|
this.RecalculateData.Drawings.ThemeInfo = {
|
|
Theme: true,
|
|
ArrInd: Data.ArrInd
|
|
};
|
|
} else {
|
|
if (Data.ColorScheme) {
|
|
this.RecalculateData.Drawings.ThemeInfo = {
|
|
ColorScheme: true,
|
|
ArrInd: Data.ArrInd
|
|
};
|
|
} else {
|
|
this.RecalculateData.Drawings.Map[Data.Object.Get_Id()] = Data.Object;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
},
|
|
Check_UninonLastPoints: function () {
|
|
if (true === this.Document.TurnOffRecalc) {
|
|
return;
|
|
}
|
|
if (this.Points.length < 2) {
|
|
return;
|
|
}
|
|
var Point1 = this.Points[this.Points.length - 2];
|
|
var Point2 = this.Points[this.Points.length - 1];
|
|
if (Point1.Items.length > 63) {
|
|
return;
|
|
}
|
|
var PrevItem = null;
|
|
var Class = null;
|
|
for (var Index = 0; Index < Point1.Items.length; Index++) {
|
|
var Item = Point1.Items[Index];
|
|
if (null === Class) {
|
|
Class = Item.Class;
|
|
} else {
|
|
if (Class != Item.Class || "undefined" === typeof(Class.Check_HistoryUninon) || false === Class.Check_HistoryUninon(PrevItem.Data, Item.Data)) {
|
|
return;
|
|
}
|
|
}
|
|
PrevItem = Item;
|
|
}
|
|
for (var Index = 0; Index < Point2.Items.length; Index++) {
|
|
var Item = Point2.Items[Index];
|
|
if (Class != Item.Class || "undefined" === typeof(Class.Check_HistoryUninon) || false === Class.Check_HistoryUninon(PrevItem.Data, Item.Data)) {
|
|
return;
|
|
}
|
|
PrevItem = Item;
|
|
}
|
|
var NewPoint = {
|
|
State: Point1.State,
|
|
Items: Point1.Items.concat(Point2.Items),
|
|
Time: Point1.Time,
|
|
Additional: {},
|
|
Description: historydescription_Document_AddLetter
|
|
};
|
|
if (this.SavedIndex >= this.Points.length - 2 && null !== this.SavedIndex) {
|
|
this.SavedIndex = this.Points.length - 3;
|
|
this.ForceSave = true;
|
|
}
|
|
this.Points.splice(this.Points.length - 2, 2, NewPoint);
|
|
if (this.Index >= this.Points.length) {
|
|
var DiffIndex = -this.Index + (this.Points.length - 1);
|
|
this.Index += DiffIndex;
|
|
this.RecIndex = Math.max(-1, this.RecIndex + DiffIndex);
|
|
}
|
|
},
|
|
TurnOff: function () {
|
|
this.TurnOffHistory = true;
|
|
},
|
|
TurnOn: function () {
|
|
this.TurnOffHistory = false;
|
|
},
|
|
Is_On: function () {
|
|
return (false === this.TurnOffHistory ? true : false);
|
|
},
|
|
Reset_SavedIndex: function () {
|
|
this.SavedIndex = this.Index;
|
|
this.ForceSave = false;
|
|
},
|
|
Have_Changes: function () {
|
|
if (-1 === this.Index && null === this.SavedIndex && false === this.ForceSave) {
|
|
return false;
|
|
}
|
|
if (this.Index != this.SavedIndex || true === this.ForceSave) {
|
|
return true;
|
|
}
|
|
return false;
|
|
},
|
|
Get_RecalcData: function () {
|
|
if (this.Index >= 0) {
|
|
this.Internal_RecalcData_Clear();
|
|
for (var Pos = this.RecIndex + 1; Pos <= this.Index; Pos++) {
|
|
var Point = this.Points[Pos];
|
|
for (var Index = 0; Index < Point.Items.length; Index++) {
|
|
var Item = Point.Items[Index];
|
|
if (true === Item.NeedRecalc) {
|
|
Item.Class.Refresh_RecalcData(Item.Data);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return this.RecalculateData;
|
|
},
|
|
Reset_RecalcIndex: function () {
|
|
this.RecIndex = this.Index;
|
|
},
|
|
Is_SimpleChanges: function () {
|
|
var Count, Items;
|
|
if (this.Index - this.RecIndex !== 1 && this.RecIndex >= -1) {
|
|
Items = [];
|
|
Count = 0;
|
|
for (var PointIndex = this.RecIndex + 1; PointIndex <= this.Index; PointIndex++) {
|
|
Items = Items.concat(this.Points[PointIndex].Items);
|
|
Count += this.Points[PointIndex].Items.length;
|
|
}
|
|
} else {
|
|
if (this.Index >= 0) {
|
|
var Point = this.Points[this.Index];
|
|
Count = Point.Items.length;
|
|
Items = Point.Items;
|
|
} else {
|
|
return [];
|
|
}
|
|
}
|
|
if (Items.length > 0) {
|
|
var Class = Items[0].Class;
|
|
for (var Index = 1; Index < Count; Index++) {
|
|
var Item = Items[Index];
|
|
if (Class !== Item.Class) {
|
|
return [];
|
|
}
|
|
}
|
|
if (Class instanceof ParaRun && Class.Is_SimpleChanges(Items)) {
|
|
return [Items[0]];
|
|
}
|
|
}
|
|
return [];
|
|
},
|
|
Set_Additional_ExtendDocumentToPos: function () {
|
|
if (this.Index >= 0) {
|
|
this.Points[this.Index].Additional.ExtendDocumentToPos = true;
|
|
}
|
|
},
|
|
Is_ExtendDocumentToPos: function () {
|
|
if (undefined === this.Points[this.Index] || undefined === this.Points[this.Index].Additional || undefined === this.Points[this.Index].Additional.ExtendDocumentToPos) {
|
|
return false;
|
|
}
|
|
return true;
|
|
},
|
|
Clear_Additional: function () {
|
|
if (this.Index >= 0) {
|
|
this.Points[this.Index].Additional = {};
|
|
}
|
|
if (true === editor.isMarkerFormat) {
|
|
editor.sync_MarkerFormatCallback(false);
|
|
}
|
|
},
|
|
Get_EditingTime: function (dTime) {
|
|
var Count = this.Points.length;
|
|
var TimeLine = [];
|
|
for (var Index = 0; Index < Count; Index++) {
|
|
var PointTime = this.Points[Index].Time;
|
|
TimeLine.push({
|
|
t0: PointTime - dTime,
|
|
t1: PointTime
|
|
});
|
|
}
|
|
Count = TimeLine.length;
|
|
for (var Index = 1; Index < Count; Index++) {
|
|
var CurrEl = TimeLine[Index];
|
|
var PrevEl = TimeLine[Index - 1];
|
|
if (CurrEl.t0 <= PrevEl.t1) {
|
|
PrevEl.t1 = CurrEl.t1;
|
|
TimeLine.splice(Index, 1);
|
|
Index--;
|
|
Count--;
|
|
}
|
|
}
|
|
Count = TimeLine.length;
|
|
var OverallTime = 0;
|
|
for (var Index = 0; Index < Count; Index++) {
|
|
OverallTime += TimeLine[Index].t1 - TimeLine[Index].t0;
|
|
}
|
|
return OverallTime;
|
|
}
|
|
};
|
|
var History = null;
|
|
function CRC32() {
|
|
this.m_aTable = [];
|
|
this.private_InitTable();
|
|
}
|
|
CRC32.prototype.private_InitTable = function () {
|
|
var CRC_POLY = 3988292384;
|
|
var nChar;
|
|
for (var nIndex = 0; nIndex < 256; nIndex++) {
|
|
nChar = nIndex;
|
|
for (var nCounter = 0; nCounter < 8; nCounter++) {
|
|
nChar = ((nChar & 1) ? ((nChar >>> 1) ^ CRC_POLY) : (nChar >>> 1));
|
|
}
|
|
this.m_aTable[nIndex] = nChar;
|
|
}
|
|
};
|
|
CRC32.prototype.Calculate_ByString = function (sStr, nSize) {
|
|
var CRC_MASK = 3523407757;
|
|
var nCRC = 0 ^ (-1);
|
|
for (var nIndex = 0; nIndex < nSize; nIndex++) {
|
|
nCRC = this.m_aTable[(nCRC ^ sStr.charCodeAt(nIndex)) & 255] ^ (nCRC >>> 8);
|
|
nCRC ^= CRC_MASK;
|
|
}
|
|
return (nCRC ^ (-1)) >>> 0;
|
|
};
|
|
CRC32.prototype.Calculate_ByByteArray = function (aArray, nSize) {
|
|
var CRC_MASK = 3523407757;
|
|
var nCRC = 0 ^ (-1);
|
|
for (var nIndex = 0; nIndex < nSize; nIndex++) {
|
|
nCRC = (nCRC >>> 8) ^ this.m_aTable[(nCRC ^ aArray[nIndex]) & 255];
|
|
nCRC ^= CRC_MASK;
|
|
}
|
|
return (nCRC ^ (-1)) >>> 0;
|
|
};
|
|
var g_oCRC32 = new CRC32(); |