1044 lines
42 KiB
JavaScript
1044 lines
42 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 (window, undefined) {
|
|
var asc = window["Asc"];
|
|
var asc_coAuthV = "3.0.8";
|
|
function CDocsCoApi(options) {
|
|
this._CoAuthoringApi = new DocsCoApi();
|
|
this._onlineWork = false;
|
|
if (options) {
|
|
this.onAuthParticipantsChanged = options.onAuthParticipantsChanged;
|
|
this.onParticipantsChanged = options.onParticipantsChanged;
|
|
this.onMessage = options.onMessage;
|
|
this.onLocksAcquired = options.onLocksAcquired;
|
|
this.onLocksReleased = options.onLocksReleased;
|
|
this.onLocksReleasedEnd = options.onLocksReleasedEnd;
|
|
this.onDisconnect = options.onDisconnect;
|
|
this.onFirstLoadChangesEnd = options.onFirstLoadChangesEnd;
|
|
this.onConnectionStateChanged = options.onConnectionStateChanged;
|
|
this.onSetIndexUser = options.onSetIndexUser;
|
|
this.onSaveChanges = options.onSaveChanges;
|
|
this.onStartCoAuthoring = options.onStartCoAuthoring;
|
|
this.onEndCoAuthoring = options.onEndCoAuthoring;
|
|
this.onUnSaveLock = options.onUnSaveLock;
|
|
this.onRecalcLocks = options.onRecalcLocks;
|
|
}
|
|
}
|
|
CDocsCoApi.prototype.init = function (user, docid, documentCallbackUrl, token, callback, editorType, documentFormatSave, isViewer) {
|
|
if (this._CoAuthoringApi && this._CoAuthoringApi.isRightURL()) {
|
|
var t = this;
|
|
this._CoAuthoringApi.onAuthParticipantsChanged = function (e, count) {
|
|
t.callback_OnAuthParticipantsChanged(e, count);
|
|
};
|
|
this._CoAuthoringApi.onParticipantsChanged = function (e, count) {
|
|
t.callback_OnParticipantsChanged(e, count);
|
|
};
|
|
this._CoAuthoringApi.onMessage = function (e, clear) {
|
|
t.callback_OnMessage(e, clear);
|
|
};
|
|
this._CoAuthoringApi.onLocksAcquired = function (e) {
|
|
t.callback_OnLocksAcquired(e);
|
|
};
|
|
this._CoAuthoringApi.onLocksReleased = function (e, bChanges) {
|
|
t.callback_OnLocksReleased(e, bChanges);
|
|
};
|
|
this._CoAuthoringApi.onLocksReleasedEnd = function () {
|
|
t.callback_OnLocksReleasedEnd();
|
|
};
|
|
this._CoAuthoringApi.onDisconnect = function (e, isDisconnectAtAll, isCloseCoAuthoring) {
|
|
t.callback_OnDisconnect(e, isDisconnectAtAll, isCloseCoAuthoring);
|
|
};
|
|
this._CoAuthoringApi.onFirstLoadChangesEnd = function () {
|
|
t.callback_OnFirstLoadChangesEnd();
|
|
};
|
|
this._CoAuthoringApi.onConnectionStateChanged = function (e) {
|
|
t.callback_OnConnectionStateChanged(e);
|
|
};
|
|
this._CoAuthoringApi.onSetIndexUser = function (e) {
|
|
t.callback_OnSetIndexUser(e);
|
|
};
|
|
this._CoAuthoringApi.onSaveChanges = function (e, userId, bFirstLoad) {
|
|
t.callback_OnSaveChanges(e, userId, bFirstLoad);
|
|
};
|
|
this._CoAuthoringApi.onStartCoAuthoring = function (e) {
|
|
t.callback_OnStartCoAuthoring(e);
|
|
};
|
|
this._CoAuthoringApi.onEndCoAuthoring = function (e) {
|
|
t.callback_OnEndCoAuthoring(e);
|
|
};
|
|
this._CoAuthoringApi.onUnSaveLock = function () {
|
|
t.callback_OnUnSaveLock();
|
|
};
|
|
this._CoAuthoringApi.onRecalcLocks = function (e) {
|
|
t.callback_OnRecalcLocks(e);
|
|
};
|
|
this._CoAuthoringApi.init(user, docid, documentCallbackUrl, token, callback, editorType, documentFormatSave, isViewer);
|
|
this._onlineWork = true;
|
|
} else {
|
|
this.callback_OnSetIndexUser("123");
|
|
this.onFirstLoadChangesEnd();
|
|
}
|
|
};
|
|
CDocsCoApi.prototype.set_url = function (url) {
|
|
if (this._CoAuthoringApi) {
|
|
this._CoAuthoringApi.set_url(url);
|
|
}
|
|
};
|
|
CDocsCoApi.prototype.get_onlineWork = function () {
|
|
return this._onlineWork;
|
|
};
|
|
CDocsCoApi.prototype.get_state = function () {
|
|
if (this._CoAuthoringApi) {
|
|
return this._CoAuthoringApi.get_state();
|
|
}
|
|
return 0;
|
|
};
|
|
CDocsCoApi.prototype.getMessages = function () {
|
|
if (this._CoAuthoringApi && this._onlineWork) {
|
|
this._CoAuthoringApi.getMessages();
|
|
}
|
|
};
|
|
CDocsCoApi.prototype.sendMessage = function (message) {
|
|
if (this._CoAuthoringApi && this._onlineWork) {
|
|
this._CoAuthoringApi.sendMessage(message);
|
|
}
|
|
};
|
|
CDocsCoApi.prototype.askLock = function (arrayBlockId, callback) {
|
|
if (this._CoAuthoringApi && this._onlineWork) {
|
|
this._CoAuthoringApi.askLock(arrayBlockId, callback);
|
|
} else {
|
|
var t = this;
|
|
window.setTimeout(function () {
|
|
if (callback && _.isFunction(callback)) {
|
|
var lengthArray = (arrayBlockId) ? arrayBlockId.length : 0;
|
|
if (0 < lengthArray) {
|
|
callback({
|
|
"lock": arrayBlockId[0]
|
|
});
|
|
for (var i = 0; i < lengthArray; ++i) {
|
|
t.callback_OnLocksAcquired({
|
|
"state": 2,
|
|
"block": arrayBlockId[i]
|
|
});
|
|
}
|
|
}
|
|
}
|
|
},
|
|
1);
|
|
}
|
|
};
|
|
CDocsCoApi.prototype.askSaveChanges = function (callback) {
|
|
if (this._CoAuthoringApi && this._onlineWork) {
|
|
this._CoAuthoringApi.askSaveChanges(callback);
|
|
} else {
|
|
window.setTimeout(function () {
|
|
if (callback && _.isFunction(callback)) {
|
|
callback({
|
|
"saveLock": false
|
|
});
|
|
}
|
|
},
|
|
100);
|
|
}
|
|
};
|
|
CDocsCoApi.prototype.unSaveLock = function () {
|
|
if (this._CoAuthoringApi && this._onlineWork) {
|
|
this._CoAuthoringApi.unSaveLock();
|
|
} else {
|
|
var t = this;
|
|
window.setTimeout(function () {
|
|
t.callback_OnUnSaveLock();
|
|
},
|
|
100);
|
|
}
|
|
};
|
|
CDocsCoApi.prototype.saveChanges = function (arrayChanges, deleteIndex, excelAdditionalInfo) {
|
|
if (this._CoAuthoringApi && this._onlineWork) {
|
|
this._CoAuthoringApi.saveChanges(arrayChanges, null, deleteIndex, excelAdditionalInfo);
|
|
}
|
|
};
|
|
CDocsCoApi.prototype.unLockDocument = function (isSave) {
|
|
if (this._CoAuthoringApi && this._onlineWork) {
|
|
this._CoAuthoringApi.unLockDocument(isSave);
|
|
}
|
|
};
|
|
CDocsCoApi.prototype.getUsers = function () {
|
|
if (this._CoAuthoringApi && this._onlineWork) {
|
|
this._CoAuthoringApi.getUsers();
|
|
}
|
|
};
|
|
CDocsCoApi.prototype.getUser = function (userId) {
|
|
if (this._CoAuthoringApi && this._onlineWork) {
|
|
return this._CoAuthoringApi.getUser(userId);
|
|
}
|
|
return null;
|
|
};
|
|
CDocsCoApi.prototype.releaseLocks = function (blockId) {
|
|
if (this._CoAuthoringApi && this._onlineWork) {
|
|
this._CoAuthoringApi.releaseLocks(blockId);
|
|
}
|
|
};
|
|
CDocsCoApi.prototype.disconnect = function () {
|
|
if (this._CoAuthoringApi && this._onlineWork) {
|
|
this._CoAuthoringApi.disconnect();
|
|
}
|
|
};
|
|
CDocsCoApi.prototype.callback_OnAuthParticipantsChanged = function (e, count) {
|
|
if (this.onAuthParticipantsChanged) {
|
|
this.onAuthParticipantsChanged(e, count);
|
|
}
|
|
};
|
|
CDocsCoApi.prototype.callback_OnParticipantsChanged = function (e, count) {
|
|
if (this.onParticipantsChanged) {
|
|
this.onParticipantsChanged(e, count);
|
|
}
|
|
};
|
|
CDocsCoApi.prototype.callback_OnMessage = function (e, clear) {
|
|
if (this.onMessage) {
|
|
this.onMessage(e, clear);
|
|
}
|
|
};
|
|
CDocsCoApi.prototype.callback_OnLocksAcquired = function (e) {
|
|
if (this.onLocksAcquired) {
|
|
this.onLocksAcquired(e);
|
|
}
|
|
};
|
|
CDocsCoApi.prototype.callback_OnLocksReleased = function (e, bChanges) {
|
|
if (this.onLocksReleased) {
|
|
this.onLocksReleased(e, bChanges);
|
|
}
|
|
};
|
|
CDocsCoApi.prototype.callback_OnLocksReleasedEnd = function () {
|
|
if (this.onLocksReleasedEnd) {
|
|
this.onLocksReleasedEnd();
|
|
}
|
|
};
|
|
CDocsCoApi.prototype.callback_OnDisconnect = function (e, isDisconnectAtAll, isCloseCoAuthoring) {
|
|
if (this.onDisconnect) {
|
|
this.onDisconnect(e, isDisconnectAtAll, isCloseCoAuthoring);
|
|
}
|
|
};
|
|
CDocsCoApi.prototype.callback_OnFirstLoadChangesEnd = function () {
|
|
if (this.onFirstLoadChangesEnd) {
|
|
this.onFirstLoadChangesEnd();
|
|
}
|
|
};
|
|
CDocsCoApi.prototype.callback_OnConnectionStateChanged = function (e) {
|
|
if (this.onConnectionStateChanged) {
|
|
this.onConnectionStateChanged(e);
|
|
}
|
|
};
|
|
CDocsCoApi.prototype.callback_OnSetIndexUser = function (e) {
|
|
if (this.onSetIndexUser) {
|
|
this.onSetIndexUser(e);
|
|
}
|
|
};
|
|
CDocsCoApi.prototype.callback_OnSaveChanges = function (e, userId, bFirstLoad) {
|
|
if (this.onSaveChanges) {
|
|
this.onSaveChanges(e, userId, bFirstLoad);
|
|
}
|
|
};
|
|
CDocsCoApi.prototype.callback_OnStartCoAuthoring = function (e) {
|
|
if (this.onStartCoAuthoring) {
|
|
this.onStartCoAuthoring(e);
|
|
}
|
|
};
|
|
CDocsCoApi.prototype.callback_OnEndCoAuthoring = function (e) {
|
|
if (this.onEndCoAuthoring) {
|
|
this.onEndCoAuthoring(e);
|
|
}
|
|
};
|
|
CDocsCoApi.prototype.callback_OnUnSaveLock = function () {
|
|
if (this.onUnSaveLock) {
|
|
this.onUnSaveLock();
|
|
}
|
|
};
|
|
CDocsCoApi.prototype.callback_OnRecalcLocks = function (e) {
|
|
if (this.onRecalcLocks) {
|
|
this.onRecalcLocks(e);
|
|
}
|
|
};
|
|
function LockBufferElement(arrayBlockId, callback) {
|
|
this._arrayBlockId = arrayBlockId;
|
|
this._callback = callback;
|
|
}
|
|
function DocsCoApi(options) {
|
|
if (options) {
|
|
this.onAuthParticipantsChanged = options.onAuthParticipantsChanged;
|
|
this.onParticipantsChanged = options.onParticipantsChanged;
|
|
this.onMessage = options.onMessage;
|
|
this.onLocksAcquired = options.onLocksAcquired;
|
|
this.onLocksReleased = options.onLocksReleased;
|
|
this.onLocksReleasedEnd = options.onLocksReleasedEnd;
|
|
this.onRelockFailed = options.onRelockFailed;
|
|
this.onDisconnect = options.onDisconnect;
|
|
this.onConnect = options.onConnect;
|
|
this.onSaveChanges = options.onSaveChanges;
|
|
this.onFirstLoadChangesEnd = options.onFirstLoadChangesEnd;
|
|
this.onConnectionStateChanged = options.onConnectionStateChanged;
|
|
this.onUnSaveLock = options.onUnSaveLock;
|
|
this.onRecalcLocks = options.onRecalcLocks;
|
|
}
|
|
this._state = ConnectionState.None;
|
|
this._participants = {};
|
|
this._countEditUsers = 0;
|
|
this._countUsers = 0;
|
|
this._locks = {};
|
|
this._msgBuffer = [];
|
|
this._lockCallbacks = {};
|
|
this._saveCallback = [];
|
|
this.saveLockCallbackErrorTimeOutId = null;
|
|
this.saveCallbackErrorTimeOutId = null;
|
|
this.unSaveLockCallbackErrorTimeOutId = null;
|
|
this._id = null;
|
|
this._indexUser = -1;
|
|
this.isCoAuthoring = false;
|
|
this.isCloseCoAuthoring = false;
|
|
this.maxCountSaveChanges = 20000;
|
|
this.currentIndex = 0;
|
|
this.deleteIndex = 0;
|
|
this.arrayChanges = null;
|
|
this.lastOtherSaveTime = -1;
|
|
this.changesIndex = 0;
|
|
this.excelAdditionalInfo = null;
|
|
this._url = "";
|
|
this.reconnectTimeout = null;
|
|
this.attemptCount = 0;
|
|
this.maxAttemptCount = 50;
|
|
this.reconnectInterval = 2000;
|
|
this.errorTimeOut = 10000;
|
|
this.errorTimeOutSave = 60000;
|
|
this._docid = null;
|
|
this._documentCallbackUrl = null;
|
|
this._token = null;
|
|
this._user = null;
|
|
this._userId = "Anonymous";
|
|
this._initCallback = null;
|
|
this.ownedLockBlocks = [];
|
|
this.sockjs_url = null;
|
|
this.sockjs = null;
|
|
this.editorType = -1;
|
|
this._isExcel = false;
|
|
this._isPresentation = false;
|
|
this._isAuth = false;
|
|
this._documentFormatSave = 0;
|
|
this._isViewer = false;
|
|
this._isReSaveAfterAuth = false;
|
|
this._lockBuffer = [];
|
|
}
|
|
DocsCoApi.prototype.isRightURL = function () {
|
|
return ("" != this._url);
|
|
};
|
|
DocsCoApi.prototype.set_url = function (url) {
|
|
this._url = url;
|
|
};
|
|
DocsCoApi.prototype.get_state = function () {
|
|
return this._state;
|
|
};
|
|
DocsCoApi.prototype.get_indexUser = function () {
|
|
return this._indexUser;
|
|
};
|
|
DocsCoApi.prototype.getSessionId = function () {
|
|
return this._id;
|
|
};
|
|
DocsCoApi.prototype.getUser = function () {
|
|
return this._user;
|
|
};
|
|
DocsCoApi.prototype.getLocks = function () {
|
|
return this._locks;
|
|
};
|
|
DocsCoApi.prototype._sendBufferedLocks = function () {
|
|
var elem;
|
|
for (var i = 0, length = this._lockBuffer.length; i < length; ++i) {
|
|
elem = this._lockBuffer[i];
|
|
this.askLock(elem._arrayBlockId, elem._callback);
|
|
}
|
|
this._lockBuffer = [];
|
|
};
|
|
DocsCoApi.prototype.askLock = function (arrayBlockId, callback) {
|
|
if (ConnectionState.SaveChanges === this._state) {
|
|
this._lockBuffer.push(new LockBufferElement(arrayBlockId, callback));
|
|
return;
|
|
}
|
|
var i = 0;
|
|
var lengthArray = (arrayBlockId) ? arrayBlockId.length : 0;
|
|
var isLock = false;
|
|
var idLockInArray = null;
|
|
for (; i < lengthArray; ++i) {
|
|
idLockInArray = (this._isExcel || this._isPresentation) ? arrayBlockId[i]["guid"] : arrayBlockId[i];
|
|
if (this._locks[idLockInArray] && 0 !== this._locks[idLockInArray].state) {
|
|
isLock = true;
|
|
break;
|
|
}
|
|
}
|
|
if (0 === lengthArray) {
|
|
isLock = true;
|
|
}
|
|
idLockInArray = (this._isExcel || this._isPresentation) ? arrayBlockId[0]["guid"] : arrayBlockId[0];
|
|
if (!isLock) {
|
|
this._locks[idLockInArray] = {
|
|
"state": 1
|
|
};
|
|
if (callback && _.isFunction(callback)) {
|
|
this._lockCallbacks[idLockInArray] = callback;
|
|
var lockCalbacks = this._lockCallbacks;
|
|
window.setTimeout(function () {
|
|
if (lockCalbacks.hasOwnProperty(idLockInArray)) {
|
|
callback({
|
|
error: "Timed out"
|
|
});
|
|
delete lockCalbacks[idLockInArray];
|
|
}
|
|
},
|
|
this.errorTimeOut);
|
|
}
|
|
this._send({
|
|
"type": "getLock",
|
|
"editorType": this.editorType,
|
|
"block": arrayBlockId
|
|
});
|
|
} else {
|
|
window.setTimeout(function () {
|
|
if (callback && _.isFunction(callback)) {
|
|
callback({
|
|
error: idLockInArray + "-lock"
|
|
});
|
|
}
|
|
},
|
|
100);
|
|
}
|
|
};
|
|
DocsCoApi.prototype.askSaveChanges = function (callback) {
|
|
if (this._saveCallback[this._saveCallback.length - 1]) {
|
|
return;
|
|
}
|
|
if (null !== this.saveLockCallbackErrorTimeOutId) {
|
|
clearTimeout(this.saveLockCallbackErrorTimeOutId);
|
|
}
|
|
if (ConnectionState.Reconnect === this._state) {
|
|
this.saveLockCallbackErrorTimeOutId = window.setTimeout(function () {
|
|
if (callback && _.isFunction(callback)) {
|
|
callback({
|
|
error: "No connection"
|
|
});
|
|
}
|
|
},
|
|
100);
|
|
return;
|
|
}
|
|
if (callback && _.isFunction(callback)) {
|
|
var t = this;
|
|
var indexCallback = this._saveCallback.length;
|
|
this._saveCallback[indexCallback] = callback;
|
|
this.saveLockCallbackErrorTimeOutId = window.setTimeout(function () {
|
|
t.saveLockCallbackErrorTimeOutId = null;
|
|
var oTmpCallback = t._saveCallback[indexCallback];
|
|
if (oTmpCallback) {
|
|
t._saveCallback[indexCallback] = null;
|
|
oTmpCallback({
|
|
error: "Timed out"
|
|
});
|
|
}
|
|
},
|
|
this.errorTimeOut);
|
|
}
|
|
this._send({
|
|
"type": "isSaveLock"
|
|
});
|
|
};
|
|
DocsCoApi.prototype.unSaveLock = function () {
|
|
var t = this;
|
|
this.unSaveLockCallbackErrorTimeOutId = window.setTimeout(function () {
|
|
t.unSaveLockCallbackErrorTimeOutId = null;
|
|
t.unSaveLock();
|
|
},
|
|
this.errorTimeOut);
|
|
this._send({
|
|
"type": "unSaveLock"
|
|
});
|
|
};
|
|
DocsCoApi.prototype.releaseLocks = function (blockId) {
|
|
if (this._locks[blockId] && 2 === this._locks[blockId].state) {
|
|
this._locks[blockId] = {
|
|
"state": 0
|
|
};
|
|
}
|
|
};
|
|
DocsCoApi.prototype._reSaveChanges = function () {
|
|
this.saveChanges(this.arrayChanges, this.currentIndex);
|
|
};
|
|
DocsCoApi.prototype.saveChanges = function (arrayChanges, currentIndex, deleteIndex, excelAdditionalInfo) {
|
|
if (null === currentIndex) {
|
|
this.deleteIndex = deleteIndex;
|
|
if (null != this.deleteIndex && -1 !== this.deleteIndex) {
|
|
this.deleteIndex += this.changesIndex;
|
|
}
|
|
this.currentIndex = 0;
|
|
this.arrayChanges = arrayChanges;
|
|
this.excelAdditionalInfo = excelAdditionalInfo;
|
|
} else {
|
|
this.currentIndex = currentIndex;
|
|
}
|
|
var startIndex = this.currentIndex * this.maxCountSaveChanges;
|
|
var endIndex = Math.min(this.maxCountSaveChanges * (this.currentIndex + 1), arrayChanges.length);
|
|
if (endIndex === arrayChanges.length) {
|
|
for (var key in this._locks) {
|
|
if (this._locks.hasOwnProperty(key)) {
|
|
if (2 === this._locks[key].state) {
|
|
delete this._locks[key];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
var t = this;
|
|
this.saveCallbackErrorTimeOutId = window.setTimeout(function () {
|
|
t.saveCallbackErrorTimeOutId = null;
|
|
t._reSaveChanges();
|
|
},
|
|
this.errorTimeOutSave);
|
|
this._state = ConnectionState.SaveChanges;
|
|
this._send({
|
|
"type": "saveChanges",
|
|
"changes": JSON.stringify(arrayChanges.slice(startIndex, endIndex)),
|
|
"startSaveChanges": (startIndex === 0),
|
|
"endSaveChanges": (endIndex === arrayChanges.length),
|
|
"isCoAuthoring": this.isCoAuthoring,
|
|
"isExcel": this._isExcel,
|
|
"deleteIndex": this.deleteIndex,
|
|
"excelAdditionalInfo": this.excelAdditionalInfo ? JSON.stringify(this.excelAdditionalInfo) : null
|
|
});
|
|
};
|
|
DocsCoApi.prototype.unLockDocument = function (isSave) {
|
|
this._send({
|
|
"type": "unLockDocument",
|
|
"isSave": isSave
|
|
});
|
|
};
|
|
DocsCoApi.prototype.getUsers = function () {
|
|
if (this.onAuthParticipantsChanged) {
|
|
this.onAuthParticipantsChanged(this._participants, this._countUsers);
|
|
}
|
|
};
|
|
DocsCoApi.prototype.getUser = function (userId) {
|
|
return this._participants[userId];
|
|
};
|
|
DocsCoApi.prototype.disconnect = function () {
|
|
this.isCloseCoAuthoring = true;
|
|
return this.sockjs.close();
|
|
};
|
|
DocsCoApi.prototype.getMessages = function () {
|
|
this._send({
|
|
"type": "getMessages"
|
|
});
|
|
};
|
|
DocsCoApi.prototype.sendMessage = function (message) {
|
|
if (typeof message === "string") {
|
|
this._send({
|
|
"type": "message",
|
|
"message": message
|
|
});
|
|
}
|
|
};
|
|
DocsCoApi.prototype._sendPrebuffered = function () {
|
|
for (var i = 0; i < this._msgBuffer.length; i++) {
|
|
this._send(this._msgBuffer[i]);
|
|
}
|
|
this._msgBuffer = [];
|
|
};
|
|
DocsCoApi.prototype._send = function (data) {
|
|
if (data !== null && typeof data === "object") {
|
|
if (this._state > 0) {
|
|
this.sockjs.send(JSON.stringify(data));
|
|
} else {
|
|
this._msgBuffer.push(data);
|
|
}
|
|
}
|
|
};
|
|
DocsCoApi.prototype._onMessages = function (data, clear) {
|
|
if (data["messages"] && this.onMessage) {
|
|
this.onMessage(data["messages"], clear);
|
|
}
|
|
};
|
|
DocsCoApi.prototype._onGetLock = function (data) {
|
|
if (data["locks"]) {
|
|
for (var key in data["locks"]) {
|
|
if (data["locks"].hasOwnProperty(key)) {
|
|
var lock = data["locks"][key],
|
|
blockTmp = (this._isExcel || this._isPresentation) ? lock["block"]["guid"] : key,
|
|
blockValue = (this._isExcel || this._isPresentation) ? lock["block"] : key;
|
|
if (lock !== null) {
|
|
var changed = true;
|
|
if (this._locks[blockTmp] && 1 !== this._locks[blockTmp].state) {
|
|
changed = !(this._locks[blockTmp].state === (lock["sessionId"] === this._id ? 2 : 3) && this._locks[blockTmp]["user"] === lock["user"] && this._locks[blockTmp]["time"] === lock["time"] && this._locks[blockTmp]["block"] === blockTmp);
|
|
}
|
|
if (changed) {
|
|
this._locks[blockTmp] = {
|
|
"state": lock["sessionId"] === this._id ? 2 : 3,
|
|
"user": lock["user"],
|
|
"time": lock["time"],
|
|
"block": blockTmp,
|
|
"blockValue": blockValue
|
|
};
|
|
}
|
|
if (this._lockCallbacks.hasOwnProperty(blockTmp) && this._lockCallbacks[blockTmp] !== null && _.isFunction(this._lockCallbacks[blockTmp])) {
|
|
if (lock["sessionId"] === this._id) {
|
|
this._lockCallbacks[blockTmp]({
|
|
"lock": this._locks[blockTmp]
|
|
});
|
|
} else {
|
|
this._lockCallbacks[blockTmp]({
|
|
"error": "Already locked by " + lock["user"]
|
|
});
|
|
}
|
|
delete this._lockCallbacks[blockTmp];
|
|
}
|
|
if (this.onLocksAcquired && changed) {
|
|
this.onLocksAcquired(this._locks[blockTmp]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
DocsCoApi.prototype._onReleaseLock = function (data) {
|
|
if (data["locks"]) {
|
|
var bSendEnd = false;
|
|
for (var block in data["locks"]) {
|
|
if (data["locks"].hasOwnProperty(block)) {
|
|
var lock = data["locks"][block],
|
|
blockTmp = (this._isExcel || this._isPresentation) ? lock["block"]["guid"] : lock["block"];
|
|
if (lock !== null) {
|
|
this._locks[blockTmp] = {
|
|
"state": 0,
|
|
"user": lock["user"],
|
|
"time": lock["time"],
|
|
"changes": lock["changes"],
|
|
"block": lock["block"]
|
|
};
|
|
if (this.onLocksReleased) {
|
|
this.onLocksReleased(this._locks[blockTmp], false);
|
|
bSendEnd = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (bSendEnd && this.onLocksReleasedEnd) {
|
|
this.onLocksReleasedEnd();
|
|
}
|
|
}
|
|
};
|
|
DocsCoApi.prototype._onSaveChanges = function (data) {
|
|
if (data["locks"]) {
|
|
var bSendEnd = false;
|
|
for (var block in data["locks"]) {
|
|
if (data["locks"].hasOwnProperty(block)) {
|
|
var lock = data["locks"][block],
|
|
blockTmp = (this._isExcel || this._isPresentation) ? lock["block"]["guid"] : lock["block"];
|
|
if (lock !== null) {
|
|
this._locks[blockTmp] = {
|
|
"state": 0,
|
|
"user": lock["user"],
|
|
"time": lock["time"],
|
|
"changes": lock["changes"],
|
|
"block": lock["block"]
|
|
};
|
|
if (this.onLocksReleased) {
|
|
this.onLocksReleased(this._locks[blockTmp], true);
|
|
bSendEnd = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (bSendEnd && this.onLocksReleasedEnd) {
|
|
this.onLocksReleasedEnd();
|
|
}
|
|
}
|
|
this._updateChanges(data["changes"], data["changesIndex"], false);
|
|
if (this.onRecalcLocks) {
|
|
this.onRecalcLocks(data["excelAdditionalInfo"]);
|
|
}
|
|
};
|
|
DocsCoApi.prototype._onStartCoAuthoring = function (isStartEvent) {
|
|
if (false === this.isCoAuthoring) {
|
|
this.isCoAuthoring = true;
|
|
if (this.onStartCoAuthoring) {
|
|
this.onStartCoAuthoring(isStartEvent);
|
|
}
|
|
}
|
|
};
|
|
DocsCoApi.prototype._onEndCoAuthoring = function (isStartEvent) {
|
|
if (true === this.isCoAuthoring) {
|
|
this.isCoAuthoring = false;
|
|
if (this.onEndCoAuthoring) {
|
|
this.onEndCoAuthoring(isStartEvent);
|
|
}
|
|
}
|
|
};
|
|
DocsCoApi.prototype._onSaveLock = function (data) {
|
|
if (undefined != data["saveLock"] && null != data["saveLock"]) {
|
|
var indexCallback = this._saveCallback.length - 1;
|
|
var oTmpCallback = this._saveCallback[indexCallback];
|
|
if (oTmpCallback) {
|
|
if (null !== this.saveLockCallbackErrorTimeOutId) {
|
|
clearTimeout(this.saveLockCallbackErrorTimeOutId);
|
|
}
|
|
this._saveCallback[indexCallback] = null;
|
|
oTmpCallback(data);
|
|
}
|
|
}
|
|
};
|
|
DocsCoApi.prototype._onUnSaveLock = function (data) {
|
|
if (null !== this.saveCallbackErrorTimeOutId) {
|
|
clearTimeout(this.saveCallbackErrorTimeOutId);
|
|
}
|
|
if (null !== this.unSaveLockCallbackErrorTimeOutId) {
|
|
clearTimeout(this.unSaveLockCallbackErrorTimeOutId);
|
|
}
|
|
this._state = ConnectionState.Authorized;
|
|
this._sendBufferedLocks();
|
|
if (-1 !== data["index"]) {
|
|
this.changesIndex = data["index"];
|
|
}
|
|
if (this.onUnSaveLock) {
|
|
this.onUnSaveLock();
|
|
}
|
|
};
|
|
DocsCoApi.prototype._updateChanges = function (allServerChanges, changesIndex, bFirstLoad) {
|
|
if (this.onSaveChanges) {
|
|
this.changesIndex = changesIndex;
|
|
if (allServerChanges) {
|
|
for (var i = 0; i < allServerChanges.length; ++i) {
|
|
var change = allServerChanges[i];
|
|
var changesOneUser = change["change"];
|
|
if (changesOneUser) {
|
|
if (change["user"] !== this._userId) {
|
|
this.lastOtherSaveTime = change["time"];
|
|
}
|
|
this.onSaveChanges(JSON.parse(changesOneUser), change["user"], bFirstLoad);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
DocsCoApi.prototype._onSetIndexUser = function (data) {
|
|
if (this.onSetIndexUser) {
|
|
this.onSetIndexUser(data);
|
|
}
|
|
};
|
|
DocsCoApi.prototype._onSavePartChanges = function (data) {
|
|
if (null !== this.saveCallbackErrorTimeOutId) {
|
|
clearTimeout(this.saveCallbackErrorTimeOutId);
|
|
}
|
|
if (-1 !== data["changesIndex"]) {
|
|
this.changesIndex = data["changesIndex"];
|
|
}
|
|
this.saveChanges(this.arrayChanges, this.currentIndex + 1);
|
|
};
|
|
DocsCoApi.prototype._onPreviousLocks = function (locks, previousLocks) {
|
|
var i = 0;
|
|
if (locks && previousLocks) {
|
|
for (var block in locks) {
|
|
if (locks.hasOwnProperty(block)) {
|
|
var lock = locks[block];
|
|
if (lock !== null && lock["block"]) {
|
|
for (i = 0; i < previousLocks.length; i++) {
|
|
if (previousLocks[i] === lock["block"] && lock["sessionId"] === this._id) {
|
|
previousLocks.remove(i);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (previousLocks.length > 0 && this.onRelockFailed) {
|
|
this.onRelockFailed(previousLocks);
|
|
}
|
|
previousLocks = [];
|
|
}
|
|
};
|
|
DocsCoApi.prototype._onAuthParticipantsChanged = function (participants) {
|
|
this._participants = {};
|
|
this._countEditUsers = 0;
|
|
this._countUsers = 0;
|
|
if (participants) {
|
|
var tmpUser;
|
|
for (var i = 0; i < participants.length; ++i) {
|
|
tmpUser = new asc.asc_CUser(participants[i]);
|
|
this._participants[tmpUser.asc_getId()] = tmpUser;
|
|
if (!tmpUser.asc_getView()) {
|
|
++this._countEditUsers;
|
|
}++this._countUsers;
|
|
}
|
|
if (this.onAuthParticipantsChanged) {
|
|
this.onAuthParticipantsChanged(this._participants, this._countUsers);
|
|
}
|
|
if (1 < this._countEditUsers) {
|
|
this._onStartCoAuthoring(true);
|
|
} else {
|
|
this._onEndCoAuthoring(true);
|
|
}
|
|
}
|
|
};
|
|
DocsCoApi.prototype._onConnectionStateChanged = function (data) {
|
|
var userStateChanged = null,
|
|
userId, stateChanged = false,
|
|
isEditUser = true;
|
|
if (undefined !== data["state"] && this.onConnectionStateChanged) {
|
|
userStateChanged = new asc.asc_CUser(data);
|
|
userId = userStateChanged.asc_getId();
|
|
isEditUser = !userStateChanged.asc_getView();
|
|
if (userStateChanged.asc_getState()) {
|
|
this._participants[userId] = userStateChanged;
|
|
++this._countUsers;
|
|
if (isEditUser) {
|
|
++this._countEditUsers;
|
|
}
|
|
stateChanged = true;
|
|
} else {
|
|
if (this._participants.hasOwnProperty(userId)) {
|
|
delete this._participants[userId];
|
|
--this._countUsers;
|
|
if (isEditUser) {
|
|
--this._countEditUsers;
|
|
}
|
|
stateChanged = true;
|
|
}
|
|
}
|
|
if (stateChanged) {
|
|
if (1 < this._countEditUsers) {
|
|
this._onStartCoAuthoring(false);
|
|
} else {
|
|
this._onEndCoAuthoring(false);
|
|
}
|
|
this.onParticipantsChanged(this._participants, this._countUsers);
|
|
this.onConnectionStateChanged(userStateChanged);
|
|
}
|
|
}
|
|
};
|
|
DocsCoApi.prototype._onDrop = function (data) {
|
|
this.disconnect();
|
|
this.onDisconnect(data ? data["description"] : "", true, this.isCloseCoAuthoring);
|
|
};
|
|
DocsCoApi.prototype._onAuth = function (data) {
|
|
if (true === this._isAuth) {
|
|
this._state = ConnectionState.Authorized;
|
|
this._onAuthParticipantsChanged(data["participants"]);
|
|
this._onMessages(data, true);
|
|
this._onGetLock(data);
|
|
if (this._isReSaveAfterAuth) {
|
|
var t = this;
|
|
var callbackAskSaveChanges = function (e) {
|
|
if (false == e["saveLock"]) {
|
|
t._reSaveChanges();
|
|
} else {
|
|
setTimeout(function () {
|
|
t.askSaveChanges(callbackAskSaveChanges);
|
|
},
|
|
1000);
|
|
}
|
|
};
|
|
this.askSaveChanges(callbackAskSaveChanges);
|
|
}
|
|
return;
|
|
}
|
|
if (data["result"] === 1) {
|
|
this._isAuth = true;
|
|
this._state = ConnectionState.Authorized;
|
|
this._id = data["sessionId"];
|
|
this._onAuthParticipantsChanged(data["participants"]);
|
|
this._onSetIndexUser(this._indexUser = data["indexUser"]);
|
|
this._userId = this._user.asc_getId() + this._indexUser;
|
|
this._onMessages(data, false);
|
|
this._onGetLock(data);
|
|
if (window["AscApplyChanges"] && window["AscChanges"]) {
|
|
var userOfflineChanges = window["AscChanges"],
|
|
changeOneUser;
|
|
for (var i = 0; i < userOfflineChanges.length; ++i) {
|
|
changeOneUser = userOfflineChanges[i];
|
|
for (var j = 0; j < changeOneUser.length; ++j) {
|
|
this.onSaveChanges(changeOneUser[j], null, true);
|
|
}
|
|
}
|
|
}
|
|
this._updateChanges(data["changes"], data["changesIndex"], true);
|
|
if (this.onFirstLoadChangesEnd) {
|
|
this.onFirstLoadChangesEnd();
|
|
}
|
|
this._sendPrebuffered();
|
|
}
|
|
if (this._initCallback) {
|
|
this._initCallback({
|
|
result: data["result"]
|
|
});
|
|
}
|
|
};
|
|
DocsCoApi.prototype.init = function (user, docid, documentCallbackUrl, token, callback, editorType, documentFormatSave, isViewer) {
|
|
this._user = user;
|
|
this._docid = docid;
|
|
this._documentCallbackUrl = documentCallbackUrl;
|
|
this._token = token;
|
|
this._initCallback = callback;
|
|
this.ownedLockBlocks = [];
|
|
this.sockjs_url = this._url + "/doc/" + docid + "/c";
|
|
this.editorType = editorType;
|
|
this._isExcel = c_oEditorId.Spreadsheet === editorType;
|
|
this._isPresentation = c_oEditorId.Presentation === editorType;
|
|
this._isAuth = false;
|
|
this._documentFormatSave = documentFormatSave;
|
|
this._isViewer = isViewer;
|
|
this._initSocksJs();
|
|
};
|
|
DocsCoApi.prototype._initSocksJs = function () {
|
|
var t = this;
|
|
var sockjs = this.sockjs = new SockJS(this.sockjs_url, null, {
|
|
debug: true
|
|
});
|
|
sockjs.onopen = function () {
|
|
if (t.reconnectTimeout) {
|
|
clearTimeout(t.reconnectTimeout);
|
|
t.attemptCount = 0;
|
|
}
|
|
t._state = ConnectionState.WaitAuth;
|
|
if (t.onConnect) {
|
|
t.onConnect();
|
|
}
|
|
if (t._locks) {
|
|
t.ownedLockBlocks = [];
|
|
for (var block in t._locks) {
|
|
if (t._locks.hasOwnProperty(block)) {
|
|
var lock = t._locks[block];
|
|
if (lock["state"] === 2) {
|
|
t.ownedLockBlocks.push(lock["blockValue"]);
|
|
}
|
|
}
|
|
}
|
|
t._locks = {};
|
|
}
|
|
t._send({
|
|
"type": "auth",
|
|
"docid": t._docid,
|
|
"documentCallbackUrl": t._documentCallbackUrl,
|
|
"token": t._token,
|
|
"user": {
|
|
"id": t._user.asc_getId(),
|
|
"name": t._user.asc_getUserName(),
|
|
"indexUser": t._indexUser
|
|
},
|
|
"editorType": t.editorType,
|
|
"lastOtherSaveTime": t.lastOtherSaveTime,
|
|
"block": t.ownedLockBlocks,
|
|
"sessionId": t._id,
|
|
"server": window.location.protocol + "//" + window.location.host + g_sMainServiceLocalUrl,
|
|
"documentFormatSave": t._documentFormatSave,
|
|
"isViewer": t._isViewer,
|
|
"version": asc_coAuthV
|
|
});
|
|
};
|
|
sockjs.onmessage = function (e) {
|
|
var dataObject = JSON.parse(e.data);
|
|
var type = dataObject.type;
|
|
switch (type) {
|
|
case "auth":
|
|
t._onAuth(dataObject);
|
|
break;
|
|
case "message":
|
|
t._onMessages(dataObject, false);
|
|
break;
|
|
case "getLock":
|
|
t._onGetLock(dataObject);
|
|
break;
|
|
case "releaseLock":
|
|
t._onReleaseLock(dataObject);
|
|
break;
|
|
case "connectState":
|
|
t._onConnectionStateChanged(dataObject);
|
|
break;
|
|
case "saveChanges":
|
|
t._onSaveChanges(dataObject);
|
|
break;
|
|
case "saveLock":
|
|
t._onSaveLock(dataObject);
|
|
break;
|
|
case "unSaveLock":
|
|
t._onUnSaveLock(dataObject);
|
|
break;
|
|
case "savePartChanges":
|
|
t._onSavePartChanges(dataObject);
|
|
break;
|
|
case "drop":
|
|
t._onDrop(dataObject);
|
|
break;
|
|
case "waitAuth":
|
|
break;
|
|
case "error":
|
|
t._onDrop(dataObject);
|
|
break;
|
|
}
|
|
};
|
|
sockjs.onclose = function (evt) {
|
|
if (ConnectionState.SaveChanges === t._state) {
|
|
t._isReSaveAfterAuth = true;
|
|
if (null !== t.saveCallbackErrorTimeOutId) {
|
|
clearTimeout(t.saveCallbackErrorTimeOutId);
|
|
}
|
|
}
|
|
t._state = ConnectionState.Reconnect;
|
|
var bIsDisconnectAtAll = t.attemptCount >= t.maxAttemptCount || t.isCloseCoAuthoring;
|
|
if (bIsDisconnectAtAll) {
|
|
t._state = ConnectionState.Closed;
|
|
}
|
|
if (t.isCloseCoAuthoring) {
|
|
return;
|
|
}
|
|
if (t.onDisconnect) {
|
|
t.onDisconnect(evt.reason, bIsDisconnectAtAll, t.isCloseCoAuthoring);
|
|
}
|
|
if (t.attemptCount < t.maxAttemptCount) {
|
|
t._tryReconnect();
|
|
}
|
|
};
|
|
return sockjs;
|
|
};
|
|
DocsCoApi.prototype._tryReconnect = function () {
|
|
var t = this;
|
|
if (this.reconnectTimeout) {
|
|
clearTimeout(this.reconnectTimeout);
|
|
}++this.attemptCount;
|
|
this.reconnectTimeout = setTimeout(function () {
|
|
delete t.sockjs;
|
|
t._initSocksJs();
|
|
},
|
|
this.reconnectInterval);
|
|
};
|
|
window["CDocsCoApi"] = CDocsCoApi;
|
|
})(window); |