You've already forked sdkjs
							
							
				mirror of
				https://github.com/ONLYOFFICE/sdkjs.git
				synced 2025-11-03 14:35:35 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			1972 lines
		
	
	
		
			66 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			1972 lines
		
	
	
		
			66 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) {
 | 
						||
  'use strict';
 | 
						||
 | 
						||
  var Asc = window['Asc'];
 | 
						||
  var AscCommon = window['AscCommon'];
 | 
						||
 | 
						||
  var ConnectionState = AscCommon.ConnectionState;
 | 
						||
  var c_oEditorId = AscCommon.c_oEditorId;
 | 
						||
  var c_oCloseCode = AscCommon.c_oCloseCode;
 | 
						||
  var c_oAscServerCommandErrors = AscCommon.c_oAscServerCommandErrors;
 | 
						||
  var c_oAscForceSaveTypes = AscCommon.c_oAscForceSaveTypes;
 | 
						||
 | 
						||
  // Класс надстройка, для online и offline работы
 | 
						||
  function CDocsCoApi() {
 | 
						||
    this._CoAuthoringApi = new DocsCoApi();
 | 
						||
    this._onlineWork = false;
 | 
						||
  }
 | 
						||
 | 
						||
  CDocsCoApi.prototype.init = function(user, docid, documentCallbackUrl, token, editorType, documentFormatSave, docInfo, shardKey, wopiSrc, userSessionId, headingsColor, openCmd) {
 | 
						||
    if (this._CoAuthoringApi && this._CoAuthoringApi.isRightURL()) {
 | 
						||
      var t = this;
 | 
						||
      this._CoAuthoringApi.onAuthParticipantsChanged = function(e, id) {
 | 
						||
        t.callback_OnAuthParticipantsChanged(e, id);
 | 
						||
      };
 | 
						||
      this._CoAuthoringApi.onParticipantsChanged = function(e) {
 | 
						||
        t.callback_OnParticipantsChanged(e);
 | 
						||
      };
 | 
						||
      this._CoAuthoringApi.onMessage = function(e, clear) {
 | 
						||
        t.callback_OnMessage(e, clear);
 | 
						||
      };
 | 
						||
      this._CoAuthoringApi.onServerVersion = function(e) {
 | 
						||
      	t.callback_OnServerVersion(e);
 | 
						||
	  };
 | 
						||
      this._CoAuthoringApi.onCursor = function(e) {
 | 
						||
        t.callback_OnCursor(e);
 | 
						||
      };
 | 
						||
      this._CoAuthoringApi.onMeta = function(e) {
 | 
						||
        t.callback_OnMeta(e);
 | 
						||
      };
 | 
						||
      this._CoAuthoringApi.onSession = function(e) {
 | 
						||
        t.callback_OnSession(e);
 | 
						||
      };
 | 
						||
      this._CoAuthoringApi.onExpiredToken = function(e) {
 | 
						||
        t.callback_OnExpiredToken(e);
 | 
						||
      };
 | 
						||
      this._CoAuthoringApi.onHasForgotten = function(e) {
 | 
						||
        t.callback_OnHasForgotten(e);
 | 
						||
      };
 | 
						||
	  this._CoAuthoringApi.onForceSave = function(e) {
 | 
						||
        t.callback_OnForceSave(e);
 | 
						||
      };
 | 
						||
      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, code) {
 | 
						||
        t.callback_OnDisconnect(e, code);
 | 
						||
      };
 | 
						||
      this._CoAuthoringApi.onWarning = function(e) {
 | 
						||
        t.callback_OnWarning(e);
 | 
						||
      };
 | 
						||
      this._CoAuthoringApi.onFirstLoadChangesEnd = function(openedAt) {
 | 
						||
        t.callback_OnFirstLoadChangesEnd(openedAt);
 | 
						||
      };
 | 
						||
      this._CoAuthoringApi.onConnectionStateChanged = function(e) {
 | 
						||
        t.callback_OnConnectionStateChanged(e);
 | 
						||
      };
 | 
						||
      this._CoAuthoringApi.onSetIndexUser = function(e) {
 | 
						||
        t.callback_OnSetIndexUser(e);
 | 
						||
      };
 | 
						||
      this._CoAuthoringApi.onSpellCheckInit = function(e) {
 | 
						||
        t.callback_OnSpellCheckInit(e);
 | 
						||
      };
 | 
						||
      this._CoAuthoringApi.onSaveChanges = function(e, userId, bFirstLoad) {
 | 
						||
        t.callback_OnSaveChanges(e, userId, bFirstLoad);
 | 
						||
      };
 | 
						||
      this._CoAuthoringApi.onChangesIndex = function(changesIndex) {
 | 
						||
        t.callback_OnChangesIndex(changesIndex);
 | 
						||
      };
 | 
						||
      // Callback есть пользователей больше 1
 | 
						||
      this._CoAuthoringApi.onStartCoAuthoring = function(e, isWaitAuth) {
 | 
						||
        t.callback_OnStartCoAuthoring(e, isWaitAuth);
 | 
						||
      };
 | 
						||
      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.onDocumentOpen = function(data) {
 | 
						||
        t.callback_OnDocumentOpen(data);
 | 
						||
      };
 | 
						||
      this._CoAuthoringApi.onFirstConnect = function() {
 | 
						||
        t.callback_OnFirstConnect();
 | 
						||
      };
 | 
						||
      this._CoAuthoringApi.onLicense = function(res) {
 | 
						||
        t.callback_OnLicense(res);
 | 
						||
      };
 | 
						||
      this._CoAuthoringApi.onLicenseChanged = function(res) {
 | 
						||
        t.callback_OnLicenseChanged(res);
 | 
						||
      };
 | 
						||
      this._CoAuthoringApi.onAiPluginSettings = function(res) {
 | 
						||
        t.callback_OnAiPluginSettings(res);
 | 
						||
      };
 | 
						||
      this._CoAuthoringApi.onMiscEvent = function(res) {
 | 
						||
        t.callback_OnMiscEvent(res);
 | 
						||
      };
 | 
						||
 | 
						||
      this._CoAuthoringApi.init(user, docid, documentCallbackUrl, token, editorType, documentFormatSave, docInfo, shardKey, wopiSrc, userSessionId, headingsColor, openCmd);
 | 
						||
      this._onlineWork = true;
 | 
						||
    } else {
 | 
						||
      // Фиктивные вызовы
 | 
						||
      this.onFirstConnect();
 | 
						||
      this.onLicense(null);
 | 
						||
    }
 | 
						||
  };
 | 
						||
 | 
						||
  CDocsCoApi.prototype.getDocId = function() {
 | 
						||
    if (this._CoAuthoringApi) {
 | 
						||
      return this._CoAuthoringApi.getDocId()
 | 
						||
    }
 | 
						||
    return undefined;
 | 
						||
  };
 | 
						||
  CDocsCoApi.prototype.setDocId = function(docId) {
 | 
						||
    if (this._CoAuthoringApi) {
 | 
						||
      return this._CoAuthoringApi.setDocId(docId)
 | 
						||
    }
 | 
						||
  };
 | 
						||
  CDocsCoApi.prototype.setBinaryChanges = function(binaryChanges) {
 | 
						||
    if (this._CoAuthoringApi) {
 | 
						||
      return this._CoAuthoringApi.binaryChanges = binaryChanges;
 | 
						||
    }
 | 
						||
  };
 | 
						||
 | 
						||
  CDocsCoApi.prototype.auth = function(isViewer, opt_openCmd, opt_isIdle) {
 | 
						||
    if (this._CoAuthoringApi && this._onlineWork) {
 | 
						||
      this._CoAuthoringApi.auth(isViewer, opt_openCmd, opt_isIdle);
 | 
						||
    } else {
 | 
						||
      // Фиктивные вызовы
 | 
						||
      this.callback_OnSpellCheckInit('');
 | 
						||
      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.openDocument = function(data) {
 | 
						||
    if (this._CoAuthoringApi && this._onlineWork) {
 | 
						||
      this._CoAuthoringApi.openDocument(data);
 | 
						||
    }
 | 
						||
  };
 | 
						||
 | 
						||
  CDocsCoApi.prototype.sendRawData = function(data) {
 | 
						||
    if (this._CoAuthoringApi && this._onlineWork) {
 | 
						||
      this._CoAuthoringApi.sendRawData(data);
 | 
						||
    }
 | 
						||
  };
 | 
						||
 | 
						||
  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.sendCursor = function(cursor) {
 | 
						||
    if (this._CoAuthoringApi && this._onlineWork) {
 | 
						||
      this._CoAuthoringApi.sendCursor(cursor);
 | 
						||
    }
 | 
						||
  };
 | 
						||
 | 
						||
  CDocsCoApi.prototype.sendClientLog = function(level, msg) {
 | 
						||
    if (this._CoAuthoringApi && this._onlineWork) {
 | 
						||
      this._CoAuthoringApi.sendClientLog(level, msg);
 | 
						||
    }
 | 
						||
  };
 | 
						||
 | 
						||
  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) {
 | 
						||
          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) {
 | 
						||
          // Фиктивные вызовы
 | 
						||
          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, canUnlockDocument, canReleaseLocks) {
 | 
						||
    if (this._CoAuthoringApi && this._onlineWork) {
 | 
						||
      this._CoAuthoringApi.canUnlockDocument = canUnlockDocument;
 | 
						||
      this._CoAuthoringApi.canReleaseLocks = canReleaseLocks;
 | 
						||
      this._CoAuthoringApi.saveChanges(arrayChanges, null, deleteIndex, excelAdditionalInfo);
 | 
						||
    }
 | 
						||
  };
 | 
						||
 | 
						||
  CDocsCoApi.prototype.unLockDocument = function(isSave, canUnlockDocument, deleteIndex, canReleaseLocks) {
 | 
						||
    if (this._CoAuthoringApi && this._onlineWork) {
 | 
						||
      this._CoAuthoringApi.canUnlockDocument = canUnlockDocument;
 | 
						||
      this._CoAuthoringApi.canReleaseLocks = canReleaseLocks;
 | 
						||
      this._CoAuthoringApi.unLockDocument(isSave, deleteIndex);
 | 
						||
    }
 | 
						||
  };
 | 
						||
 | 
						||
  CDocsCoApi.prototype.getUsers = function() {
 | 
						||
    if (this._CoAuthoringApi && this._onlineWork) {
 | 
						||
      this._CoAuthoringApi.getUsers();
 | 
						||
    }
 | 
						||
  };
 | 
						||
 | 
						||
  CDocsCoApi.prototype.getUserConnectionId = function() {
 | 
						||
    if (this._CoAuthoringApi && this._onlineWork) {
 | 
						||
      return this._CoAuthoringApi.getUserConnectionId();
 | 
						||
    }
 | 
						||
    return null;
 | 
						||
  };
 | 
						||
 | 
						||
  CDocsCoApi.prototype.getParticipantName = function(userId) {
 | 
						||
    if (this._CoAuthoringApi && this._onlineWork) {
 | 
						||
      return this._CoAuthoringApi.getParticipantName(userId);
 | 
						||
    }
 | 
						||
    return "";
 | 
						||
  };
 | 
						||
  
 | 
						||
  CDocsCoApi.prototype.get_serverChangesSize = function() {
 | 
						||
    if (this._CoAuthoringApi && this._onlineWork) {
 | 
						||
      return this._CoAuthoringApi.get_serverChangesSize();
 | 
						||
    }
 | 
						||
    return 0;
 | 
						||
  };
 | 
						||
 | 
						||
  CDocsCoApi.prototype.get_indexUser = function() {
 | 
						||
    if (this._CoAuthoringApi && this._onlineWork) {
 | 
						||
      return this._CoAuthoringApi.get_indexUser();
 | 
						||
    }
 | 
						||
    return null;
 | 
						||
  };
 | 
						||
 | 
						||
  CDocsCoApi.prototype.get_isAuth = function() {
 | 
						||
    if (this._CoAuthoringApi && this._onlineWork) {
 | 
						||
      return this._CoAuthoringApi.get_isAuth();
 | 
						||
    }
 | 
						||
    return null;
 | 
						||
  };
 | 
						||
  
 | 
						||
  CDocsCoApi.prototype.get_jwt = function() {
 | 
						||
    if (this._CoAuthoringApi && this._onlineWork) {
 | 
						||
      return this._CoAuthoringApi.get_jwt();
 | 
						||
    }
 | 
						||
    return null;
 | 
						||
  };
 | 
						||
 | 
						||
  CDocsCoApi.prototype.releaseLocks = function(blockId) {
 | 
						||
    if (this._CoAuthoringApi && this._onlineWork) {
 | 
						||
      this._CoAuthoringApi.releaseLocks(blockId);
 | 
						||
    }
 | 
						||
  };
 | 
						||
 | 
						||
  CDocsCoApi.prototype.disconnect = function(opt_code, opt_reason) {
 | 
						||
    if (this._CoAuthoringApi && this._onlineWork) {
 | 
						||
      this._CoAuthoringApi.disconnect(opt_code, opt_reason);
 | 
						||
    }
 | 
						||
  };
 | 
						||
 | 
						||
  CDocsCoApi.prototype.connect = function() {
 | 
						||
    if (this._CoAuthoringApi && this._onlineWork) {
 | 
						||
      this._CoAuthoringApi.connect();
 | 
						||
    }
 | 
						||
  };
 | 
						||
 | 
						||
  CDocsCoApi.prototype.extendSession = function(idleTime) {
 | 
						||
    if (this._CoAuthoringApi && this._onlineWork) {
 | 
						||
      this._CoAuthoringApi.extendSession(idleTime);
 | 
						||
    }
 | 
						||
  };
 | 
						||
 | 
						||
	CDocsCoApi.prototype.forceSave = function() {
 | 
						||
		if (this._CoAuthoringApi && this._onlineWork) {
 | 
						||
			return this._CoAuthoringApi.forceSave();
 | 
						||
		}
 | 
						||
		return false;
 | 
						||
	};
 | 
						||
	CDocsCoApi.prototype.callPRC = function(data, timeout, callback) {
 | 
						||
		if (this._CoAuthoringApi && this._onlineWork) {
 | 
						||
			return this._CoAuthoringApi.callPRC(data, timeout, callback);
 | 
						||
		}
 | 
						||
		return false;
 | 
						||
	};
 | 
						||
 | 
						||
  CDocsCoApi.prototype.callback_OnAuthParticipantsChanged = function(e, id) {
 | 
						||
    if (this.onAuthParticipantsChanged) {
 | 
						||
      this.onAuthParticipantsChanged(e, id);
 | 
						||
    }
 | 
						||
  };
 | 
						||
 | 
						||
  CDocsCoApi.prototype.callback_OnParticipantsChanged = function(e) {
 | 
						||
    if (this.onParticipantsChanged) {
 | 
						||
      this.onParticipantsChanged(e);
 | 
						||
    }
 | 
						||
  };
 | 
						||
 | 
						||
  CDocsCoApi.prototype.callback_OnMessage = function(e, clear) {
 | 
						||
    if (this.onMessage) {
 | 
						||
      this.onMessage(e, clear);
 | 
						||
    }
 | 
						||
  };
 | 
						||
 | 
						||
  CDocsCoApi.prototype.callback_OnServerVersion = function(e) {
 | 
						||
  	if (this.onServerVersion) {
 | 
						||
      this.onServerVersion(e);
 | 
						||
	}
 | 
						||
  };
 | 
						||
 | 
						||
  CDocsCoApi.prototype.callback_OnCursor = function(e) {
 | 
						||
    if (this.onCursor) {
 | 
						||
      this.onCursor(e);
 | 
						||
    }
 | 
						||
  };
 | 
						||
 | 
						||
  CDocsCoApi.prototype.callback_OnMeta = function(e) {
 | 
						||
    if (this.onMeta) {
 | 
						||
      this.onMeta(e);
 | 
						||
    }
 | 
						||
  };
 | 
						||
 | 
						||
  CDocsCoApi.prototype.callback_OnSession = function(e) {
 | 
						||
    if (this.onSession) {
 | 
						||
      this.onSession(e);
 | 
						||
    }
 | 
						||
  };
 | 
						||
 | 
						||
  CDocsCoApi.prototype.callback_OnExpiredToken = function(e) {
 | 
						||
    if (this.onExpiredToken) {
 | 
						||
      this.onExpiredToken(e);
 | 
						||
    }
 | 
						||
  };
 | 
						||
  
 | 
						||
  CDocsCoApi.prototype.callback_OnForceSave = function(e) {
 | 
						||
    if (this.onForceSave) {
 | 
						||
      this.onForceSave(e);
 | 
						||
    }
 | 
						||
  };
 | 
						||
 | 
						||
  CDocsCoApi.prototype.callback_OnHasForgotten = function(e) {
 | 
						||
    if (this.onHasForgotten) {
 | 
						||
      this.onHasForgotten(e);
 | 
						||
    }
 | 
						||
  };
 | 
						||
 | 
						||
  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();
 | 
						||
    }
 | 
						||
  };
 | 
						||
 | 
						||
  /**
 | 
						||
   * Event об отсоединении от сервера
 | 
						||
   * @param {jQuery} e  event об отсоединении с причиной
 | 
						||
   * @param {code: AscCommon.c_oCloseCode.drop} code
 | 
						||
   */
 | 
						||
  CDocsCoApi.prototype.callback_OnDisconnect = function(e, code) {
 | 
						||
    if (this.onDisconnect) {
 | 
						||
      this.onDisconnect(e, code);
 | 
						||
    }
 | 
						||
  };
 | 
						||
 | 
						||
  CDocsCoApi.prototype.callback_OnWarning = function(e) {
 | 
						||
    if (this.onWarning) {
 | 
						||
      this.onWarning(e);
 | 
						||
    }
 | 
						||
  };
 | 
						||
 | 
						||
  CDocsCoApi.prototype.callback_OnFirstLoadChangesEnd = function(openedAt) {
 | 
						||
    if (this.onFirstLoadChangesEnd) {
 | 
						||
      this.onFirstLoadChangesEnd(openedAt);
 | 
						||
    }
 | 
						||
  };
 | 
						||
 | 
						||
  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_OnSpellCheckInit = function(e) {
 | 
						||
    if (this.onSpellCheckInit) {
 | 
						||
      this.onSpellCheckInit(e);
 | 
						||
    }
 | 
						||
  };
 | 
						||
 | 
						||
  CDocsCoApi.prototype.callback_OnSaveChanges = function(e, userId, bFirstLoad) {
 | 
						||
    if (this.onSaveChanges) {
 | 
						||
      this.onSaveChanges(e, userId, bFirstLoad);
 | 
						||
    }
 | 
						||
  };
 | 
						||
  CDocsCoApi.prototype.callback_OnChangesIndex = function(changesIndex) {
 | 
						||
    if (this.onChangesIndex) {
 | 
						||
      this.onChangesIndex(changesIndex);
 | 
						||
    }
 | 
						||
  };
 | 
						||
  CDocsCoApi.prototype.callback_OnStartCoAuthoring = function(e, isWaitAuth) {
 | 
						||
    if (this.onStartCoAuthoring) {
 | 
						||
      this.onStartCoAuthoring(e, isWaitAuth);
 | 
						||
    }
 | 
						||
  };
 | 
						||
  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);
 | 
						||
    }
 | 
						||
  };
 | 
						||
  CDocsCoApi.prototype.callback_OnDocumentOpen = function(e) {
 | 
						||
    if (this.onDocumentOpen) {
 | 
						||
      this.onDocumentOpen(e);
 | 
						||
    }
 | 
						||
  };
 | 
						||
  CDocsCoApi.prototype.callback_OnFirstConnect = function() {
 | 
						||
    if (this.onFirstConnect) {
 | 
						||
      this.onFirstConnect();
 | 
						||
    }
 | 
						||
  };
 | 
						||
  CDocsCoApi.prototype.callback_OnLicense = function(res) {
 | 
						||
    if (this.onLicense) {
 | 
						||
      this.onLicense(res);
 | 
						||
    }
 | 
						||
  };
 | 
						||
  CDocsCoApi.prototype.callback_OnLicenseChanged = function(res) {
 | 
						||
    if (this.onLicenseChanged) {
 | 
						||
      this.onLicenseChanged(res);
 | 
						||
    }
 | 
						||
  };
 | 
						||
  CDocsCoApi.prototype.callback_OnAiPluginSettings = function(res) {
 | 
						||
    if (this.onAiPluginSettings) {
 | 
						||
      this.onAiPluginSettings(res);
 | 
						||
    }
 | 
						||
  };
 | 
						||
  CDocsCoApi.prototype.callback_OnMiscEvent = function(res) {
 | 
						||
    if (this.onMiscEvent) {
 | 
						||
      this.onMiscEvent(res);
 | 
						||
    }
 | 
						||
  };
 | 
						||
 | 
						||
  function LockBufferElement(arrayBlockId, callback) {
 | 
						||
    this._arrayBlockId = arrayBlockId ? arrayBlockId.slice() : null;
 | 
						||
    this._callback = callback;
 | 
						||
  }
 | 
						||
 | 
						||
  function DocsCoApi() {
 | 
						||
    this._state = ConnectionState.None;
 | 
						||
    // Online-пользователи в документе
 | 
						||
    this._participants = {};
 | 
						||
    this._participantsTimestamp;
 | 
						||
    this._countEditUsers = 0;
 | 
						||
    this._countUsers = 0;
 | 
						||
    this._countCalls = 0;
 | 
						||
    this._waitingForResponse = {};
 | 
						||
 | 
						||
    this.isLicenseInit = false;
 | 
						||
    this._locks = {};
 | 
						||
    this._msgBuffer = [];
 | 
						||
    this._msgInputBuffer = [];
 | 
						||
    this._lockCallbacks = {};
 | 
						||
    this._lockCallbacksErrorTimerId = {};
 | 
						||
    this._saveCallback = [];
 | 
						||
    this.saveLockCallbackErrorTimeOutId = null;
 | 
						||
    this.saveCallbackErrorTimeOutId = null;
 | 
						||
    this.unSaveLockCallbackErrorTimeOutId = null;
 | 
						||
    this._id = null;
 | 
						||
    this._sessionTimeConnect = null;
 | 
						||
	this._allChangesSaved = null;
 | 
						||
	this._lastForceSaveButtonTime = -2;//-2 to allow first save without changes
 | 
						||
	this._lastForceSaveTimeoutTime = null;
 | 
						||
    this._indexUser = -1;
 | 
						||
    // Если пользователей больше 1, то совместно редактируем
 | 
						||
    this.isCoAuthoring = false;
 | 
						||
    // Мы сами отключились от совместного редактирования
 | 
						||
    this.isCloseCoAuthoring = false;
 | 
						||
 | 
						||
    //websocket payload size is limited by https://github.com/faye/faye-websocket-node#initialization-options (64 MiB)
 | 
						||
    //xhr payload size is limited by nginx param client_max_body_size (current 100MB)
 | 
						||
    //"1.5MB" is choosen to avoid disconnect(after 25s) while downloading/uploading oversized changes with 0.5Mbps connection
 | 
						||
    this.websocketMaxPayloadSize = 1572864;
 | 
						||
    this._serverChangesSize = 0;
 | 
						||
    // Текущий индекс для колличества изменений
 | 
						||
    this.currentIndex = 0;
 | 
						||
    this.currentIndexEnd = 0;
 | 
						||
    // Индекс, с которого мы начинаем сохранять изменения
 | 
						||
    this.deleteIndex = 0;
 | 
						||
    // Массив изменений
 | 
						||
    this.arrayChanges = null;
 | 
						||
    // Время последнего сохранения (для разрыва соединения)
 | 
						||
    this.lastOtherSaveTime = -1;
 | 
						||
	this.lastOwnSaveTime = -1;
 | 
						||
    // Локальный индекс изменений
 | 
						||
    this.changesIndex = 0;
 | 
						||
    //server changes index
 | 
						||
    //todo: replace changesIndex with syncChangesIndex. changesIndex has different value in single editing mode
 | 
						||
    this.syncChangesIndex = 0;
 | 
						||
    // Дополнительная информация для Excel
 | 
						||
    this.excelAdditionalInfo = null;
 | 
						||
    // Unlock document
 | 
						||
    this.canUnlockDocument = false;
 | 
						||
    // Release locks
 | 
						||
    this.canReleaseLocks = false;
 | 
						||
 | 
						||
    this._url = "";
 | 
						||
 | 
						||
    this.maxAttemptCount = 50;
 | 
						||
    this.reconnectInterval = 2000;
 | 
						||
    this.errorTimeOut = 10000;
 | 
						||
    this.errorTimeOutSave = 60000;	// ToDo стоит переделать это, т.к. могут дублироваться изменения...
 | 
						||
 | 
						||
    this._docid = null;
 | 
						||
    this._documentCallbackUrl = null;
 | 
						||
    this._token = null;
 | 
						||
    this._user = null;
 | 
						||
    this._userId = "Anonymous";
 | 
						||
    this.ownedLockBlocks = [];
 | 
						||
    this.socketio_url = null;
 | 
						||
    this.socketio = null;
 | 
						||
    this.editorType = -1;
 | 
						||
    this._isExcel = false;
 | 
						||
    this._isPresentation = false;
 | 
						||
    this._isAuth = false;
 | 
						||
    this._documentFormatSave = 0;
 | 
						||
    this.mode = undefined;
 | 
						||
    this.permissions = undefined;
 | 
						||
    this.lang = undefined;
 | 
						||
    this.openCmd = undefined;
 | 
						||
    this.jwtOpen = undefined;
 | 
						||
    this.jwtSession = undefined;
 | 
						||
    this.encrypted = undefined;
 | 
						||
    this.IsAnonymousUser = undefined;
 | 
						||
    this.coEditingMode = undefined;
 | 
						||
    this.headingsColor = undefined;
 | 
						||
    this._isReSaveAfterAuth = false;	// Флаг для сохранения после повторной авторизации (для разрыва соединения во время сохранения)
 | 
						||
    this._lockBuffer = [];
 | 
						||
    this._saveChangesChunks = [];
 | 
						||
    this._authChanges = [];
 | 
						||
    this._authOtherChanges = [];
 | 
						||
  }
 | 
						||
 | 
						||
  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.check_state = function () {
 | 
						||
		return ConnectionState.Authorized === this._state || ConnectionState.SaveChanges === this._state ||
 | 
						||
			ConnectionState.AskSaveChanges === this._state;
 | 
						||
	};
 | 
						||
 | 
						||
  DocsCoApi.prototype.get_indexUser = function() {
 | 
						||
    return this._indexUser;
 | 
						||
  };
 | 
						||
 | 
						||
  DocsCoApi.prototype.get_serverChangesSize = function() {
 | 
						||
    return this._serverChangesSize;
 | 
						||
  };
 | 
						||
 | 
						||
  DocsCoApi.prototype.get_isAuth = function() {
 | 
						||
    return this._isAuth;
 | 
						||
  };
 | 
						||
 | 
						||
  DocsCoApi.prototype.get_jwt = function() {
 | 
						||
    return this.jwtSession || this.jwtOpen;
 | 
						||
  };
 | 
						||
 | 
						||
  DocsCoApi.prototype.getSessionId = function() {
 | 
						||
    return this._id;
 | 
						||
  };
 | 
						||
 | 
						||
  DocsCoApi.prototype.getUserConnectionId = function() {
 | 
						||
    return this._userId;
 | 
						||
  };
 | 
						||
 | 
						||
  DocsCoApi.prototype.getParticipantName = function(userId) {
 | 
						||
  	if (this._participants[userId])
 | 
						||
      return this._participants[userId].asc_getUserName();
 | 
						||
    return "";
 | 
						||
  };
 | 
						||
 | 
						||
  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 || ConnectionState.AskSaveChanges === this._state) {
 | 
						||
      // Мы в режиме сохранения. Lock-и запросим после окончания.
 | 
						||
      this._lockBuffer.push(new LockBufferElement(arrayBlockId, callback));
 | 
						||
      return;
 | 
						||
    }
 | 
						||
 | 
						||
    // ask all elements in array
 | 
						||
    var t = this;
 | 
						||
    var i = 0;
 | 
						||
    var lengthArray = (arrayBlockId) ? arrayBlockId.length : 0;
 | 
						||
    var isLock = false;
 | 
						||
    var idLockInArray = null;
 | 
						||
    for (; i < lengthArray; ++i) {
 | 
						||
      idLockInArray = (this._isExcel || this._isPresentation || this._isPDF) ? 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 || this._isPDF) ? arrayBlockId[0]['guid'] : arrayBlockId[0];
 | 
						||
 | 
						||
    if (!isLock) {
 | 
						||
      if (this._lockCallbacksErrorTimerId.hasOwnProperty(idLockInArray)) {
 | 
						||
        // Два раза для одного id нельзя запрашивать lock, не дождавшись ответа
 | 
						||
        return;
 | 
						||
      }
 | 
						||
      //Ask
 | 
						||
      this._locks[idLockInArray] = {'state': 1};//1-asked for block
 | 
						||
      if (callback) {
 | 
						||
        this._lockCallbacks[idLockInArray] = callback;
 | 
						||
 | 
						||
        //Set reconnectTimeout
 | 
						||
        this._lockCallbacksErrorTimerId[idLockInArray] = window.setTimeout(function() {
 | 
						||
          if (t._lockCallbacks.hasOwnProperty(idLockInArray)) {
 | 
						||
            //Not signaled already
 | 
						||
            t._lockCallbacks[idLockInArray]({error: 'Timed out'});
 | 
						||
            delete t._lockCallbacks[idLockInArray];
 | 
						||
            delete t._lockCallbacksErrorTimerId[idLockInArray];
 | 
						||
          }
 | 
						||
        }, this.errorTimeOut);
 | 
						||
      }
 | 
						||
      this._send({"type": 'getLock', 'block': arrayBlockId});
 | 
						||
    } else {
 | 
						||
      // Вернем ошибку, т.к. залочены элементы
 | 
						||
      window.setTimeout(function() {
 | 
						||
        if (callback) {
 | 
						||
          callback({error: idLockInArray + '-lock'});
 | 
						||
        }
 | 
						||
      }, 100);
 | 
						||
    }
 | 
						||
  };
 | 
						||
 | 
						||
  DocsCoApi.prototype.askSaveChanges = function(callback) {
 | 
						||
    if (this._saveCallback[this._saveCallback.length - 1]) {
 | 
						||
      // Мы еще не отработали старый callback и ждем ответа
 | 
						||
      return;
 | 
						||
    }
 | 
						||
 | 
						||
    // Очищаем предыдущий таймер
 | 
						||
    if (null !== this.saveLockCallbackErrorTimeOutId) {
 | 
						||
      clearTimeout(this.saveLockCallbackErrorTimeOutId);
 | 
						||
    }
 | 
						||
 | 
						||
    // Проверим состояние, если мы не подсоединились, то сразу отправим ошибку
 | 
						||
    if (ConnectionState.Authorized !== this._state) {
 | 
						||
      this.saveLockCallbackErrorTimeOutId = window.setTimeout(function() {
 | 
						||
        if (callback) {
 | 
						||
          // Фиктивные вызовы
 | 
						||
          callback({error: "No connection"});
 | 
						||
        }
 | 
						||
      }, 100);
 | 
						||
      return;
 | 
						||
    }
 | 
						||
    if (callback) {
 | 
						||
      var t = this;
 | 
						||
      var indexCallback = this._saveCallback.length;
 | 
						||
      this._saveCallback[indexCallback] = callback;
 | 
						||
 | 
						||
      //Set reconnectTimeout
 | 
						||
      this.saveLockCallbackErrorTimeOutId = window.setTimeout(function() {
 | 
						||
        t.saveLockCallbackErrorTimeOutId = null;
 | 
						||
        var oTmpCallback = t._saveCallback[indexCallback];
 | 
						||
        if (oTmpCallback) {
 | 
						||
          t._saveCallback[indexCallback] = null;
 | 
						||
          //Not signaled already
 | 
						||
          oTmpCallback({error: "Timed out"});
 | 
						||
          t._state = ConnectionState.Authorized;
 | 
						||
          // Делаем отложенные lock-и
 | 
						||
          t._sendBufferedLocks();
 | 
						||
        }
 | 
						||
      }, this.errorTimeOut);
 | 
						||
    }
 | 
						||
    this._state = ConnectionState.AskSaveChanges;
 | 
						||
    this._send({"type": "isSaveLock", "syncChangesIndex": this.syncChangesIndex});
 | 
						||
  };
 | 
						||
 | 
						||
  DocsCoApi.prototype.unSaveLock = function() {
 | 
						||
    // ToDo при разрыве соединения нужно перестать делать unSaveLock!
 | 
						||
    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 /*lock is ours*/) {
 | 
						||
      //Ask
 | 
						||
      this._locks[blockId] = {"state": 0};//0-released
 | 
						||
    }
 | 
						||
  };
 | 
						||
 | 
						||
  DocsCoApi.prototype._reSaveChanges = function(reSaveType) {
 | 
						||
    this.saveChanges(this.arrayChanges, this.currentIndex, undefined, undefined, reSaveType);
 | 
						||
  };
 | 
						||
 | 
						||
  DocsCoApi.prototype.saveChanges = function(arrayChanges, currentIndex, deleteIndex, excelAdditionalInfo, reSave) {
 | 
						||
    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, endIndex;
 | 
						||
    startIndex = endIndex = this.currentIndex;
 | 
						||
    var curBytes = 0;
 | 
						||
    for (; endIndex < arrayChanges.length && curBytes < this.websocketMaxPayloadSize; ++endIndex) {
 | 
						||
      curBytes += arrayChanges[endIndex].length;
 | 
						||
    }
 | 
						||
    this.currentIndexEnd = endIndex;
 | 
						||
    if (endIndex === arrayChanges.length) {
 | 
						||
      for (var key in this._locks) if (this._locks.hasOwnProperty(key)) {
 | 
						||
        if (2 === this._locks[key].state /*lock is ours*/) {
 | 
						||
          delete this._locks[key];
 | 
						||
        }
 | 
						||
      }
 | 
						||
    }
 | 
						||
 | 
						||
    //Set errorTimeout
 | 
						||
    var t = this;
 | 
						||
    this.saveCallbackErrorTimeOutId = window.setTimeout(function() {
 | 
						||
      t.saveCallbackErrorTimeOutId = null;
 | 
						||
      t._reSaveChanges(1);
 | 
						||
    }, this.errorTimeOutSave);
 | 
						||
 | 
						||
    // Выставляем состояние сохранения
 | 
						||
    this._state = ConnectionState.SaveChanges;
 | 
						||
    if (!reSave) {
 | 
						||
      this._serverChangesSize += curBytes;
 | 
						||
    }
 | 
						||
    let _changes = this.binaryChanges ? arrayChanges.slice(startIndex, endIndex) : JSON.stringify(arrayChanges.slice(startIndex, endIndex));
 | 
						||
    this._send({'type': 'saveChanges', 'changes': _changes,
 | 
						||
      'startSaveChanges': (startIndex === 0), 'endSaveChanges': (endIndex === arrayChanges.length),
 | 
						||
      'isCoAuthoring': this.isCoAuthoring, 'isExcel': this._isExcel, 'deleteIndex': this.deleteIndex,
 | 
						||
      'excelAdditionalInfo': this.excelAdditionalInfo ? JSON.stringify(this.excelAdditionalInfo) : null,
 | 
						||
        'unlock': this.canUnlockDocument, 'releaseLocks': this.canReleaseLocks, 'reSave': reSave});
 | 
						||
  };
 | 
						||
 | 
						||
  DocsCoApi.prototype.unLockDocument = function(isSave, deleteIndex) {
 | 
						||
    this.deleteIndex = deleteIndex;
 | 
						||
    if (null != this.deleteIndex && -1 !== this.deleteIndex) {
 | 
						||
      this.deleteIndex += this.changesIndex;
 | 
						||
    }
 | 
						||
    this._send({'type': 'unLockDocument', 'isSave': isSave, 'unlock': this.canUnlockDocument,
 | 
						||
      'deleteIndex': this.deleteIndex, 'releaseLocks': this.canReleaseLocks});
 | 
						||
  };
 | 
						||
 | 
						||
  DocsCoApi.prototype.getUsers = function() {
 | 
						||
    // Специально для возможности получения после прохождения авторизации (Стоит переделать)
 | 
						||
    if (this.onAuthParticipantsChanged) {
 | 
						||
      this.onAuthParticipantsChanged(this._participants, this._userId);
 | 
						||
    }
 | 
						||
  };
 | 
						||
 | 
						||
  DocsCoApi.prototype.connect = function() {
 | 
						||
    this.isCloseCoAuthoring = false;
 | 
						||
    this.socketio.connect();
 | 
						||
  };
 | 
						||
 | 
						||
  DocsCoApi.prototype.disconnect = function(opt_code, opt_reason) {
 | 
						||
    // Отключаемся сами
 | 
						||
    this.isCloseCoAuthoring = true;
 | 
						||
    if (opt_code) {
 | 
						||
      this.onDisconnect(opt_reason, opt_code);
 | 
						||
      this.socketio.disconnect();
 | 
						||
    } else {
 | 
						||
      this._send({"type": "close"});
 | 
						||
      this._state = ConnectionState.ClosedCoAuth;
 | 
						||
    }
 | 
						||
  };
 | 
						||
 | 
						||
  DocsCoApi.prototype.extendSession = function(idleTime) {
 | 
						||
    this._send({'type': 'extendSession', 'idletime': idleTime});
 | 
						||
  };
 | 
						||
 | 
						||
	DocsCoApi.prototype.forceSave = function() {
 | 
						||
        var res = false;
 | 
						||
		var newForceSaveButtonTime = Math.max(this.lastOtherSaveTime, this.lastOwnSaveTime);
 | 
						||
		if (this._lastForceSaveButtonTime < newForceSaveButtonTime) {
 | 
						||
			this._lastForceSaveButtonTime = newForceSaveButtonTime;
 | 
						||
			this._send({'type': 'forceSaveStart'});
 | 
						||
            res = true;
 | 
						||
		}
 | 
						||
		return res;
 | 
						||
	};
 | 
						||
  DocsCoApi.prototype.callPRC = function(data, timeout, callback) {
 | 
						||
    var t = this;
 | 
						||
    var responseKey = ++this._countCalls;
 | 
						||
    this._waitingForResponse[responseKey] = callback;
 | 
						||
    if (timeout > 0) {
 | 
						||
      setTimeout(function() {
 | 
						||
        t._onPRC(responseKey, true, undefined);
 | 
						||
      }, timeout)
 | 
						||
    }
 | 
						||
    this._send({'type': 'rpc', 'responseKey': responseKey, 'data': data});
 | 
						||
    return true;
 | 
						||
  };
 | 
						||
  DocsCoApi.prototype._onPRC = function(responseKey, isTimeout, response) {
 | 
						||
    var callback = this._waitingForResponse[responseKey];
 | 
						||
    delete this._waitingForResponse[responseKey];
 | 
						||
    if (callback) {
 | 
						||
      callback(isTimeout, response);
 | 
						||
    }
 | 
						||
  };
 | 
						||
  DocsCoApi.prototype._onUpdateVersion = function() {
 | 
						||
    this._send({'type': 'updateVersion'});
 | 
						||
  };
 | 
						||
 | 
						||
  DocsCoApi.prototype.openDocument = function(data) {
 | 
						||
    this._send({"type": "openDocument", "message": data});
 | 
						||
  };
 | 
						||
 | 
						||
  DocsCoApi.prototype.sendRawData = function(data) {
 | 
						||
    this._sendRaw(data);
 | 
						||
  };
 | 
						||
 | 
						||
  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.sendCursor = function(cursor) {
 | 
						||
    if (typeof cursor === 'string') {
 | 
						||
      this._send({"type": "cursor", "cursor": cursor});
 | 
						||
    }
 | 
						||
  };
 | 
						||
 | 
						||
  DocsCoApi.prototype.sendClientLog = function(level, msg) {
 | 
						||
    this._send({'type': 'clientLog', 'level': level, 'msg': msg});
 | 
						||
  };
 | 
						||
 | 
						||
  DocsCoApi.prototype._applyPrebuffered = function () {
 | 
						||
    for (var i = 0; i < this._msgInputBuffer.length; ++i) {
 | 
						||
      this._msgInputBuffer[i]();
 | 
						||
    }
 | 
						||
    this._msgInputBuffer = [];
 | 
						||
  };
 | 
						||
  DocsCoApi.prototype._sendPrebuffered = function() {
 | 
						||
    for (var i = 0; i < this._msgBuffer.length; i++) {
 | 
						||
      this._sendRaw(this._msgBuffer[i]);
 | 
						||
    }
 | 
						||
    this._msgBuffer = [];
 | 
						||
  };
 | 
						||
 | 
						||
  DocsCoApi.prototype._send = function(data, useEncryption) {
 | 
						||
    if (!useEncryption && data && data["type"] == "saveChanges" && AscCommon.EncryptionWorker && AscCommon.EncryptionWorker.isInit())
 | 
						||
      return AscCommon.EncryptionWorker.sendChanges(this, data, AscCommon.EncryptionMessageType.Encrypt);
 | 
						||
 | 
						||
    if (data !== null && typeof data === "object") {
 | 
						||
      if (this._state > 0) {
 | 
						||
        this.socketio.emit("message", data);
 | 
						||
      } else {
 | 
						||
        this._msgBuffer.push(JSON.stringify(data));
 | 
						||
      }
 | 
						||
    }
 | 
						||
  };
 | 
						||
 | 
						||
  DocsCoApi.prototype._sendRaw = function(data) {
 | 
						||
    if (data !== null && typeof data === "string") {
 | 
						||
      if (this._state > 0) {
 | 
						||
        this.socketio.emit("message", data);
 | 
						||
      } else {
 | 
						||
        this._msgBuffer.push(data);
 | 
						||
      }
 | 
						||
    }
 | 
						||
  };
 | 
						||
 | 
						||
  DocsCoApi.prototype._onMessages = function(data, clear) {
 | 
						||
    if (this.check_state() && data["messages"] && this.onMessage) {
 | 
						||
      this.onMessage(data["messages"], clear);
 | 
						||
    }
 | 
						||
  };
 | 
						||
 | 
						||
  DocsCoApi.prototype._onServerVersion = function (data) {
 | 
						||
  	if (this.onServerVersion) {
 | 
						||
		this.onServerVersion(data['buildVersion'], data['buildNumber']);
 | 
						||
	}
 | 
						||
  };
 | 
						||
 | 
						||
  DocsCoApi.prototype._onCursor = function(data) {
 | 
						||
    if (this.check_state() && data["messages"] && this.onCursor) {
 | 
						||
      this.onCursor(data["messages"]);
 | 
						||
    }
 | 
						||
  };
 | 
						||
 | 
						||
  DocsCoApi.prototype._onMeta = function(data) {
 | 
						||
    if (data["messages"] && this.onMeta) {
 | 
						||
      this.onMeta(data["messages"]);
 | 
						||
    }
 | 
						||
  };
 | 
						||
 | 
						||
  DocsCoApi.prototype._onSession = function(data) {
 | 
						||
    if (this.check_state() && data["messages"] && this.onSession) {
 | 
						||
      this.onSession(data["messages"]);
 | 
						||
    }
 | 
						||
  };
 | 
						||
 | 
						||
  DocsCoApi.prototype._onExpiredToken = function(data) {
 | 
						||
    if (this.onExpiredToken) {
 | 
						||
      this.onExpiredToken(data);
 | 
						||
    }
 | 
						||
  };
 | 
						||
 | 
						||
  DocsCoApi.prototype._onHasForgotten = function(data) {
 | 
						||
    if (this.onHasForgotten) {
 | 
						||
      this.onHasForgotten();
 | 
						||
    }
 | 
						||
  };
 | 
						||
 | 
						||
  DocsCoApi.prototype._onRefreshToken = function(jwt) {
 | 
						||
    this.jwtOpen = undefined;
 | 
						||
    if (this.socketio) {
 | 
						||
      if (this.socketio["auth"]) {
 | 
						||
        this.socketio["auth"]["token"] = this.jwtOpen;
 | 
						||
      }
 | 
						||
      if (this.socketio.io && this.socketio.io.setOpenToken) {
 | 
						||
        this.socketio.io.setOpenToken(this.jwtOpen);
 | 
						||
      }
 | 
						||
    }
 | 
						||
    if (jwt) {
 | 
						||
      this.jwtSession = jwt;
 | 
						||
      if (this.socketio) {
 | 
						||
        if (this.socketio["auth"]) {
 | 
						||
          this.socketio["auth"]["session"] = this.jwtSession;
 | 
						||
        }
 | 
						||
        if (this.socketio.io && this.socketio.io.setSessionToken) {
 | 
						||
          this.socketio.io.setSessionToken(this.jwtSession);
 | 
						||
        }
 | 
						||
      }
 | 
						||
    }
 | 
						||
  };
 | 
						||
 | 
						||
	DocsCoApi.prototype._onForceSaveStart = function(data) {
 | 
						||
	    var code = data['code'];
 | 
						||
		if (code === c_oAscServerCommandErrors.NoError) {
 | 
						||
			this._lastForceSaveButtonTime = data['time'];
 | 
						||
            this.onForceSave({type: c_oAscForceSaveTypes.Button, start: true});
 | 
						||
        } else if (code === c_oAscServerCommandErrors.NotModified) {
 | 
						||
            this.onForceSave({type: c_oAscForceSaveTypes.Button, refuse: true});
 | 
						||
		} else {
 | 
						||
			this.onWarning(AscCommon.c_oAscServerError.Unknown);
 | 
						||
		}
 | 
						||
	};
 | 
						||
	DocsCoApi.prototype._onForceSave = function(data) {
 | 
						||
        var type = data['type'];
 | 
						||
		if (c_oAscForceSaveTypes.Button === type) {
 | 
						||
			if (this._lastForceSaveButtonTime == data['time']) {
 | 
						||
				this.onForceSave({type: type, success: data['success']});
 | 
						||
			}
 | 
						||
		} else {
 | 
						||
			if (data['start']) {
 | 
						||
                this.onForceSave({type: type, start: true});
 | 
						||
				this._lastForceSaveTimeoutTime = data['time'];
 | 
						||
			} else {
 | 
						||
				if (this._lastForceSaveTimeoutTime == data['time']) {
 | 
						||
					this.onForceSave({type: type, success: data['success']});
 | 
						||
				}
 | 
						||
			}
 | 
						||
		}
 | 
						||
	};
 | 
						||
 | 
						||
  DocsCoApi.prototype._onGetLock = function(data) {
 | 
						||
    if (this.check_state() && data["locks"]) {
 | 
						||
      for (var key in data["locks"]) {
 | 
						||
        if (data["locks"].hasOwnProperty(key)) {
 | 
						||
          var lock = data["locks"][key], blockTmp = (this._isExcel || this._isPresentation || this._isPDF) ? lock["block"]["guid"] : key, blockValue = (this._isExcel || this._isPresentation || this._isPDF) ? lock["block"] : key;
 | 
						||
          if (lock !== null) {
 | 
						||
            var changed = true;
 | 
						||
            if (this._locks[blockTmp] && 1 !== this._locks[blockTmp].state /*asked for it*/) {
 | 
						||
              //Exists
 | 
						||
              //Check lock state
 | 
						||
              changed = !(this._locks[blockTmp].state === (lock["user"] === this._userId ? 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["user"] === this._userId ? 2 : 3, "user": lock["user"], "time": lock["time"], "block": blockTmp, "blockValue": blockValue};//2-acquired by me!
 | 
						||
            }
 | 
						||
            if (this._lockCallbacks.hasOwnProperty(blockTmp)) {
 | 
						||
              if (lock["user"] === this._userId) {
 | 
						||
                //Do call back
 | 
						||
                this._lockCallbacks[blockTmp]({"lock": this._locks[blockTmp]});
 | 
						||
              } else {
 | 
						||
                this._lockCallbacks[blockTmp]({"error": "Already locked by " + lock["user"]});
 | 
						||
              }
 | 
						||
              if (this._lockCallbacksErrorTimerId.hasOwnProperty(blockTmp)) {
 | 
						||
                clearTimeout(this._lockCallbacksErrorTimerId[blockTmp]);
 | 
						||
                delete this._lockCallbacksErrorTimerId[blockTmp];
 | 
						||
              }
 | 
						||
              delete this._lockCallbacks[blockTmp];
 | 
						||
            }
 | 
						||
            if (this.onLocksAcquired && changed) {
 | 
						||
              this.onLocksAcquired(this._locks[blockTmp]);
 | 
						||
            }
 | 
						||
          }
 | 
						||
        }
 | 
						||
      }
 | 
						||
    }
 | 
						||
  };
 | 
						||
 | 
						||
  DocsCoApi.prototype._onReleaseLock = function(data) {
 | 
						||
    if (this.check_state() && 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 || this._isPDF) ? 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) {
 | 
						||
              // false - user not save changes
 | 
						||
              this.onLocksReleased(this._locks[blockTmp], false);
 | 
						||
              bSendEnd = true;
 | 
						||
            }
 | 
						||
          }
 | 
						||
        }
 | 
						||
      }
 | 
						||
      if (bSendEnd && this.onLocksReleasedEnd) {
 | 
						||
        this.onLocksReleasedEnd();
 | 
						||
      }
 | 
						||
    }
 | 
						||
  };
 | 
						||
 | 
						||
  DocsCoApi.prototype._documentOpen = function(data) {
 | 
						||
    this.onDocumentOpen(data);
 | 
						||
  };
 | 
						||
 | 
						||
  DocsCoApi.prototype._onSaveChanges = function(data, useEncryption) {
 | 
						||
    if (!this.check_state()) {
 | 
						||
      if (!this.get_isAuth()) {
 | 
						||
        this._authOtherChanges.push(data);
 | 
						||
      }
 | 
						||
      return;
 | 
						||
    }
 | 
						||
    if (!data["endSaveChanges"]) {
 | 
						||
      this._saveChangesChunks.push(data["changes"]);
 | 
						||
      return;
 | 
						||
    } else if(this._saveChangesChunks.length > 0){
 | 
						||
      this._saveChangesChunks.push(data["changes"]);
 | 
						||
      var newChanges = [];
 | 
						||
      data["changes"] = newChanges.concat.apply(newChanges, this._saveChangesChunks);
 | 
						||
      this._saveChangesChunks = [];
 | 
						||
    }
 | 
						||
 | 
						||
    if (!useEncryption && AscCommon.EncryptionWorker && AscCommon.EncryptionWorker.isInit())
 | 
						||
      return AscCommon.EncryptionWorker.sendChanges(this, data, AscCommon.EncryptionMessageType.Decrypt);
 | 
						||
    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 || this._isPDF) ? 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) {
 | 
						||
              // true - lock with save
 | 
						||
              this.onLocksReleased(this._locks[blockTmp], true);
 | 
						||
              bSendEnd = true;
 | 
						||
            }
 | 
						||
          }
 | 
						||
        }
 | 
						||
      }
 | 
						||
      if (bSendEnd && this.onLocksReleasedEnd) {
 | 
						||
        this.onLocksReleasedEnd();
 | 
						||
      }
 | 
						||
    }
 | 
						||
    this._updateChanges(data["changes"], data["changesIndex"], data["syncChangesIndex"], false);
 | 
						||
 | 
						||
    if (this.onRecalcLocks) {
 | 
						||
      this.onRecalcLocks(data["excelAdditionalInfo"]);
 | 
						||
    }
 | 
						||
  };
 | 
						||
 | 
						||
  DocsCoApi.prototype._onStartCoAuthoring = function(isStartEvent, isWaitAuth) {
 | 
						||
    if (isWaitAuth && false === this.isCoAuthoring && !this.onStartCoAuthoring) {
 | 
						||
      var errorMsg = 'Error: connection state changed waitAuth' +
 | 
						||
          ';this.onStartCoAuthoring:' + !!this.onStartCoAuthoring;
 | 
						||
      this.sendClientLog("error", "changesError: " + errorMsg);
 | 
						||
    }
 | 
						||
    if (false === this.isCoAuthoring) {
 | 
						||
      this.isCoAuthoring = true;
 | 
						||
      if (this.onStartCoAuthoring) {
 | 
						||
        this.onStartCoAuthoring(isStartEvent, isWaitAuth);
 | 
						||
      }
 | 
						||
    } else if (isWaitAuth) {
 | 
						||
      //it is a stub for unexpected situation(no direct reproduce scenery)
 | 
						||
      //isCoAuthoring is true when more then one editor, but isWaitAuth mean than server has one editor
 | 
						||
      this.canUnlockDocument = true;
 | 
						||
      this.unLockDocument(false);
 | 
						||
    }
 | 
						||
  };
 | 
						||
 | 
						||
  DocsCoApi.prototype._onEndCoAuthoring = function(isStartEvent) {
 | 
						||
    if (true === this.isCoAuthoring) {
 | 
						||
      this.isCoAuthoring = false;
 | 
						||
      if (this.onEndCoAuthoring) {
 | 
						||
        this.onEndCoAuthoring(isStartEvent);
 | 
						||
      }
 | 
						||
    }
 | 
						||
  };
 | 
						||
 | 
						||
	DocsCoApi.prototype._onSaveLock = function (data) {
 | 
						||
		if (null != data["saveLock"]) {
 | 
						||
			var indexCallback = this._saveCallback.length - 1;
 | 
						||
			var oTmpCallback = this._saveCallback[indexCallback];
 | 
						||
			if (oTmpCallback) {
 | 
						||
				// Очищаем предыдущий таймер
 | 
						||
				if (null !== this.saveLockCallbackErrorTimeOutId) {
 | 
						||
					clearTimeout(this.saveLockCallbackErrorTimeOutId);
 | 
						||
					this.saveLockCallbackErrorTimeOutId = null;
 | 
						||
				}
 | 
						||
 | 
						||
				this._saveCallback[indexCallback] = null;
 | 
						||
				oTmpCallback(data);
 | 
						||
			}
 | 
						||
		}
 | 
						||
		if (null == data["saveLock"] || data['error'] || data["saveLock"]) {
 | 
						||
			this._state = ConnectionState.Authorized;
 | 
						||
			// Делаем отложенные lock-и
 | 
						||
			this._sendBufferedLocks();
 | 
						||
		}
 | 
						||
	};
 | 
						||
 | 
						||
  DocsCoApi.prototype._onUnSaveLock = function(data) {
 | 
						||
    // Очищаем предыдущий таймер сохранения
 | 
						||
    if (null !== this.saveCallbackErrorTimeOutId) {
 | 
						||
      clearTimeout(this.saveCallbackErrorTimeOutId);
 | 
						||
      this.saveCallbackErrorTimeOutId = null;
 | 
						||
    }
 | 
						||
    // Очищаем предыдущий таймер снятия блокировки
 | 
						||
    if (null !== this.unSaveLockCallbackErrorTimeOutId) {
 | 
						||
      clearTimeout(this.unSaveLockCallbackErrorTimeOutId);
 | 
						||
      this.unSaveLockCallbackErrorTimeOutId = null;
 | 
						||
    }
 | 
						||
 | 
						||
    // Возвращаем состояние
 | 
						||
    this._state = ConnectionState.Authorized;
 | 
						||
 | 
						||
    // Делаем отложенные lock-и
 | 
						||
    this._sendBufferedLocks();
 | 
						||
 | 
						||
    if (-1 !== data['index']) {
 | 
						||
      this.changesIndex = data['index'];
 | 
						||
    }
 | 
						||
	
 | 
						||
    if (-1 !== data['time']) {
 | 
						||
      this.lastOwnSaveTime = data['time'];
 | 
						||
    }
 | 
						||
 | 
						||
    if (undefined !== data['syncChangesIndex'] && -1 !== data['syncChangesIndex']) {
 | 
						||
      this.syncChangesIndex = data['syncChangesIndex'];
 | 
						||
    }
 | 
						||
	
 | 
						||
    if (this.onUnSaveLock) {
 | 
						||
      this.onUnSaveLock();
 | 
						||
    }
 | 
						||
  };
 | 
						||
 | 
						||
  DocsCoApi.prototype._updateChanges = function(allServerChanges, changesIndex, syncChangesIndex, bFirstLoad) {
 | 
						||
    if (this.onSaveChanges) {
 | 
						||
      this.changesIndex = changesIndex;
 | 
						||
      if (undefined !== syncChangesIndex && -1 !== syncChangesIndex) {
 | 
						||
        this.syncChangesIndex = syncChangesIndex;
 | 
						||
      }
 | 
						||
      if (allServerChanges) {
 | 
						||
        for (var i = 0; i < allServerChanges.length; ++i) {
 | 
						||
          var change = allServerChanges[i];
 | 
						||
          var changesOneUser = this.binaryChanges ? new Uint8Array(change['change']) : JSON.parse(change['change']);
 | 
						||
          if (changesOneUser) {
 | 
						||
            if (change['user'] !== this._userId) {
 | 
						||
              this.lastOtherSaveTime = change['time'];
 | 
						||
            }
 | 
						||
            this._serverChangesSize += changesOneUser.length;
 | 
						||
            this.onSaveChanges(changesOneUser, change['useridoriginal'], bFirstLoad);
 | 
						||
          }
 | 
						||
        }
 | 
						||
      }
 | 
						||
      this.onChangesIndex(changesIndex);
 | 
						||
    }
 | 
						||
  };
 | 
						||
 | 
						||
  DocsCoApi.prototype._onSetIndexUser = function(data) {
 | 
						||
    if (this.onSetIndexUser) {
 | 
						||
      this.onSetIndexUser(data);
 | 
						||
    }
 | 
						||
  };
 | 
						||
  DocsCoApi.prototype._onSpellCheckInit = function(data) {
 | 
						||
    if (this.onSpellCheckInit) {
 | 
						||
      this.onSpellCheckInit(data);
 | 
						||
    }
 | 
						||
  };
 | 
						||
 | 
						||
  DocsCoApi.prototype._onSavePartChanges = function(data) {
 | 
						||
    // Очищаем предыдущий таймер
 | 
						||
    if (null !== this.saveCallbackErrorTimeOutId) {
 | 
						||
      clearTimeout(this.saveCallbackErrorTimeOutId);
 | 
						||
      this.saveCallbackErrorTimeOutId = null;
 | 
						||
    }
 | 
						||
 | 
						||
    if (-1 !== data['changesIndex']) {
 | 
						||
      this.changesIndex = data['changesIndex'];
 | 
						||
    }
 | 
						||
 | 
						||
    if (undefined !== data['syncChangesIndex'] && -1 !== data['syncChangesIndex']) {
 | 
						||
      this.syncChangesIndex = data['syncChangesIndex'];
 | 
						||
    }
 | 
						||
 | 
						||
    this.saveChanges(this.arrayChanges, this.currentIndexEnd);
 | 
						||
  };
 | 
						||
 | 
						||
  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"]) {
 | 
						||
            //Find in previous
 | 
						||
            for (i = 0; i < previousLocks.length; i++) {
 | 
						||
              if (previousLocks[i] === lock["block"] && lock["user"] === this._userId) {
 | 
						||
                //Lock is ours
 | 
						||
                previousLocks.remove(i);
 | 
						||
                break;
 | 
						||
              }
 | 
						||
            }
 | 
						||
          }
 | 
						||
        }
 | 
						||
      }
 | 
						||
      if (previousLocks.length > 0 && this.onRelockFailed) {
 | 
						||
        this.onRelockFailed(previousLocks);
 | 
						||
      }
 | 
						||
      previousLocks = [];
 | 
						||
    }
 | 
						||
  };
 | 
						||
 | 
						||
  DocsCoApi.prototype._onParticipantsChanged = function(participants, needChanged) {
 | 
						||
    var participantsNew = {};
 | 
						||
    var countEditUsersNew = 0;
 | 
						||
    var countUsersNew = 0;
 | 
						||
    var tmpUser;
 | 
						||
    var i;
 | 
						||
    var usersStateChanged = [];
 | 
						||
    if (participants) {
 | 
						||
      for (i = 0; i < participants.length; ++i) {
 | 
						||
        tmpUser = new AscCommon.asc_CUser(participants[i]);
 | 
						||
        tmpUser.setState(true);
 | 
						||
        participantsNew[tmpUser.asc_getId()] = tmpUser;
 | 
						||
        if (!tmpUser.asc_getView()) {
 | 
						||
          ++countEditUsersNew;
 | 
						||
        }
 | 
						||
        ++countUsersNew;
 | 
						||
      }
 | 
						||
    }
 | 
						||
    if (needChanged) {
 | 
						||
      for (i in this._participants) {
 | 
						||
        if (!(participantsNew[i] && this._participants[i].isEqual(participantsNew[i]))) {
 | 
						||
          tmpUser = this._participants[i];
 | 
						||
          tmpUser.setState(false);
 | 
						||
          usersStateChanged.push(tmpUser);
 | 
						||
        }
 | 
						||
      }
 | 
						||
      for (i in participantsNew) {
 | 
						||
        if (!(this._participants[i] && this._participants[i].isEqual(participantsNew[i]))) {
 | 
						||
          tmpUser = participantsNew[i];
 | 
						||
          tmpUser.setState(true);
 | 
						||
          usersStateChanged.push(tmpUser);
 | 
						||
        }
 | 
						||
      }
 | 
						||
    }
 | 
						||
    this._participants = participantsNew;
 | 
						||
    this._countEditUsers = countEditUsersNew;
 | 
						||
    this._countUsers = countUsersNew;
 | 
						||
    return usersStateChanged;
 | 
						||
  };
 | 
						||
  DocsCoApi.prototype._onAuthParticipantsChanged = function(participants) {
 | 
						||
    this._participants = {};
 | 
						||
    this._countEditUsers = 0;
 | 
						||
    this._countUsers = 0;
 | 
						||
 | 
						||
    if (participants) {
 | 
						||
      this._onParticipantsChanged(participants);
 | 
						||
 | 
						||
      if (this.onAuthParticipantsChanged) {
 | 
						||
        this.onAuthParticipantsChanged(this._participants, this._userId);
 | 
						||
      }
 | 
						||
 | 
						||
      // Посылаем эвент о совместном редактировании
 | 
						||
      if (1 < this._countEditUsers) {
 | 
						||
        this._onStartCoAuthoring(/*isStartEvent*/true);
 | 
						||
      } else {
 | 
						||
        this._onEndCoAuthoring(/*isStartEvent*/true);
 | 
						||
      }
 | 
						||
    }
 | 
						||
  };
 | 
						||
 | 
						||
  DocsCoApi.prototype._onConnectionStateChanged = function(data) {
 | 
						||
    var t = this;
 | 
						||
    if (!this.check_state()) {
 | 
						||
      this._msgInputBuffer.push(function () {
 | 
						||
        t._onConnectionStateChanged(data);
 | 
						||
      });
 | 
						||
      return;
 | 
						||
    }
 | 
						||
    var isWaitAuth = data['waitAuth'];
 | 
						||
    var usersStateChanged;
 | 
						||
    if(isWaitAuth && !(this.onConnectionStateChanged && (!this._participantsTimestamp || this._participantsTimestamp <= data['participantsTimestamp']))) {
 | 
						||
      var errorMsg = 'Error: connection state changed waitAuth' +
 | 
						||
          ';onConnectionStateChanged:' + !!this.onConnectionStateChanged +
 | 
						||
          ';this._participantsTimestamp:' + this._participantsTimestamp +
 | 
						||
          ';data.participantsTimestamp:' + data['participantsTimestamp'];
 | 
						||
      this.sendClientLog("error", "changesError: " + errorMsg);
 | 
						||
    }
 | 
						||
    if (this.onConnectionStateChanged && (!this._participantsTimestamp || this._participantsTimestamp <= data['participantsTimestamp'])) {
 | 
						||
      this._participantsTimestamp = data['participantsTimestamp'];
 | 
						||
      usersStateChanged = this._onParticipantsChanged(data['participants'], true);
 | 
						||
 | 
						||
      if (isWaitAuth && !(usersStateChanged.length > 0 && 1 < this._countEditUsers)) {
 | 
						||
        var errorMsg = 'Error: connection state changed waitAuth' +
 | 
						||
            ';usersStateChanged:' + JSON.stringify(usersStateChanged) +
 | 
						||
            ';this._countEditUsers:' + this._countEditUsers;
 | 
						||
        this.sendClientLog("error", "changesError: " + errorMsg);
 | 
						||
      }
 | 
						||
      if (usersStateChanged.length > 0) {
 | 
						||
        // Посылаем эвент о совместном редактировании
 | 
						||
        if (1 < this._countEditUsers) {
 | 
						||
          this._onStartCoAuthoring(/*isStartEvent*/false, isWaitAuth);
 | 
						||
        } else {
 | 
						||
          this._onEndCoAuthoring(/*isStartEvent*/false);
 | 
						||
        }
 | 
						||
 | 
						||
        this.onParticipantsChanged(this._participants);
 | 
						||
        for (var i = 0; i < usersStateChanged.length; ++i) {
 | 
						||
          this.onConnectionStateChanged(usersStateChanged[i]);
 | 
						||
        }
 | 
						||
      }
 | 
						||
    }
 | 
						||
  };
 | 
						||
 | 
						||
  DocsCoApi.prototype._onLicenseChanged = function (data) {
 | 
						||
    this.onLicenseChanged(data);
 | 
						||
  };
 | 
						||
 | 
						||
  DocsCoApi.prototype._onDisconnectReason = function(data) {
 | 
						||
    var code = data && data['code'] || c_oCloseCode.drop;
 | 
						||
    this.onDisconnect(data ? data['description'] : '', code);
 | 
						||
  };
 | 
						||
 | 
						||
  DocsCoApi.prototype._onDrop = function(data) {
 | 
						||
    this.disconnect();
 | 
						||
    this._onDisconnectReason(data);
 | 
						||
  };
 | 
						||
 | 
						||
  DocsCoApi.prototype._onWarning = function(data) {
 | 
						||
    this.onWarning(data.code);
 | 
						||
  };
 | 
						||
 | 
						||
  DocsCoApi.prototype._onLicense = function(data) {
 | 
						||
    if (!this.isLicenseInit) {
 | 
						||
      this.isLicenseInit = true;
 | 
						||
      this.onLicense(data['license']);
 | 
						||
      if (this.onAiPluginSettings) {
 | 
						||
        this.onAiPluginSettings(data['aiPluginSettings']);
 | 
						||
      }
 | 
						||
    }
 | 
						||
  };
 | 
						||
 | 
						||
  DocsCoApi.prototype._onAuth = function(data) {
 | 
						||
    var t = this;
 | 
						||
    this._onRefreshToken(data['jwt']);
 | 
						||
    if (true === this._isAuth) {
 | 
						||
      this._state = ConnectionState.Authorized;
 | 
						||
 | 
						||
      this._onServerVersion(data);
 | 
						||
 | 
						||
      // Мы должны только соединиться для получения файла. Совместное редактирование уже было отключено.
 | 
						||
      if (this.isCloseCoAuthoring) {
 | 
						||
        return;
 | 
						||
      }
 | 
						||
 | 
						||
      this._onLicenseChanged(data);
 | 
						||
      // Мы уже авторизовывались, нужно обновить пользователей (т.к. пользователи могли входить и выходить пока у нас не было соединения)
 | 
						||
      this._onAuthParticipantsChanged(data['participants']);
 | 
						||
 | 
						||
      //if (this.ownedLockBlocks && this.ownedLockBlocks.length > 0) {
 | 
						||
      //	this._onPreviousLocks(data["locks"], this.ownedLockBlocks);
 | 
						||
      //}
 | 
						||
      this._onMessages(data, true);
 | 
						||
      this._onGetLock(data);
 | 
						||
 | 
						||
      //Apply prebuffered
 | 
						||
      this._applyPrebuffered();
 | 
						||
 | 
						||
      if (this._isReSaveAfterAuth) {
 | 
						||
        this._isReSaveAfterAuth = false;
 | 
						||
        var callbackAskSaveChanges = function(e) {
 | 
						||
          if (false === e["saveLock"]) {
 | 
						||
            t._reSaveChanges(2);
 | 
						||
          } else {
 | 
						||
            setTimeout(function() {
 | 
						||
              t.askSaveChanges(callbackAskSaveChanges);
 | 
						||
            }, 1000);
 | 
						||
          }
 | 
						||
        };
 | 
						||
        this.askSaveChanges(callbackAskSaveChanges);
 | 
						||
      }
 | 
						||
 | 
						||
      return;
 | 
						||
    }
 | 
						||
    if (data['result'] === 1) {
 | 
						||
      // Выставляем флаг, что мы уже авторизовывались
 | 
						||
      this._isAuth = true;
 | 
						||
 | 
						||
      //TODO: add checks
 | 
						||
      this._state = ConnectionState.Authorized;
 | 
						||
      this._id = data['sessionId'];
 | 
						||
      this._indexUser = data['indexUser'];
 | 
						||
      this._userId = this._user.asc_getId() + this._indexUser;
 | 
						||
      this._sessionTimeConnect = data['sessionTimeConnect'];
 | 
						||
      if (data['settings']) {
 | 
						||
        if (data['settings']['reconnection']) {
 | 
						||
          let attempts = data['settings']['reconnection']['attempts'];
 | 
						||
          let delay = data['settings']['reconnection']['delay'];
 | 
						||
          this.socketio.io.reconnectionAttempts(attempts);
 | 
						||
          this.socketio.io.reconnectionDelay(delay);
 | 
						||
          this.socketio.io.reconnectionDelayMax(delay);
 | 
						||
        }
 | 
						||
        if (data['settings']['websocketMaxPayloadSize']) {
 | 
						||
          this.websocketMaxPayloadSize = data['settings']['websocketMaxPayloadSize'];
 | 
						||
        }
 | 
						||
      }
 | 
						||
      this._onLicenseChanged(data);
 | 
						||
      this._onAuthParticipantsChanged(data['participants']);
 | 
						||
 | 
						||
      this._onSpellCheckInit(data['g_cAscSpellCheckUrl']);
 | 
						||
      this._onSetIndexUser(this._indexUser);
 | 
						||
 | 
						||
      this._onMessages(data, false);
 | 
						||
      this._onGetLock(data);
 | 
						||
      if (data['hasForgotten']) {
 | 
						||
        this._onHasForgotten();
 | 
						||
      }
 | 
						||
 | 
						||
      // Применения изменений пользователя
 | 
						||
      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._updateAuthChanges();
 | 
						||
      // Посылать нужно всегда, т.к. на это рассчитываем при открытии
 | 
						||
      if (this.onFirstLoadChangesEnd) {
 | 
						||
        this.onFirstLoadChangesEnd(data['openedAt']);
 | 
						||
      }
 | 
						||
 | 
						||
      //Apply prebuffered
 | 
						||
      this._applyPrebuffered();
 | 
						||
 | 
						||
      //Send prebuffered
 | 
						||
      this._sendPrebuffered();
 | 
						||
    }
 | 
						||
    //TODO: Add errors
 | 
						||
  };
 | 
						||
  DocsCoApi.prototype._onAuthChanges = function(data) {
 | 
						||
    this._authChanges.push(data["changes"]);
 | 
						||
    this._send({'type': 'authChangesAck'});
 | 
						||
  };
 | 
						||
  DocsCoApi.prototype._updateAuthChanges = function() {
 | 
						||
    //todo apply changes with chunk on arrival
 | 
						||
    var changesIndex = 0, i, changes, data, indexDiff;
 | 
						||
    for (i = 0; i < this._authChanges.length; ++i) {
 | 
						||
      changes = this._authChanges[i];
 | 
						||
      changesIndex += changes.length;
 | 
						||
      this._updateChanges(changes, changesIndex, changesIndex, true);
 | 
						||
    }
 | 
						||
    this._authChanges = [];
 | 
						||
    for (i = 0; i < this._authOtherChanges.length; ++i) {
 | 
						||
      data = this._authOtherChanges[i];
 | 
						||
      indexDiff = data["changesIndex"] - changesIndex;
 | 
						||
      if (indexDiff > 0) {
 | 
						||
        if (indexDiff >= data["changes"].length) {
 | 
						||
          changes = data["changes"];
 | 
						||
        } else {
 | 
						||
          changes = data["changes"].splice(data["changes"].length - indexDiff, indexDiff);
 | 
						||
        }
 | 
						||
        changesIndex += changes.length;
 | 
						||
        this._updateChanges(changes, changesIndex, changesIndex, true);
 | 
						||
      }
 | 
						||
    }
 | 
						||
    this._authOtherChanges = [];
 | 
						||
  };
 | 
						||
 | 
						||
  DocsCoApi.prototype.init = function(user, docid, documentCallbackUrl, token, editorType, documentFormatSave, docInfo, shardKey, wopiSrc, userSessionId, headingsColor, openCmd) {
 | 
						||
    this._user = user;
 | 
						||
    this._docid = null;
 | 
						||
    this._documentCallbackUrl = documentCallbackUrl;
 | 
						||
    this._token = token;
 | 
						||
    this.ownedLockBlocks = [];
 | 
						||
    this.socketio_url = null;
 | 
						||
    this.editorType = editorType;
 | 
						||
    this._isExcel = c_oEditorId.Spreadsheet === editorType;
 | 
						||
    this._isPresentation = c_oEditorId.Presentation === editorType;
 | 
						||
    this._isPDF = Asc.editor.isPdfEditor();
 | 
						||
    this._isAuth = false;
 | 
						||
    this._documentFormatSave = documentFormatSave;
 | 
						||
	this.mode = docInfo.get_Mode();
 | 
						||
	this.permissions = docInfo.get_Permissions();
 | 
						||
	this.lang = docInfo.get_Lang();
 | 
						||
    this.openCmd = openCmd;
 | 
						||
	this.jwtOpen = docInfo.get_Token();
 | 
						||
    this.encrypted = docInfo.get_Encrypted() || docInfo.get_IsWebOpening();
 | 
						||
    this.IsAnonymousUser = docInfo.get_IsAnonymousUser();
 | 
						||
    this.coEditingMode = docInfo.asc_getCoEditingMode();
 | 
						||
    this.shardKey = shardKey;
 | 
						||
    this.wopiSrc = wopiSrc;
 | 
						||
    this.userSessionId = userSessionId;
 | 
						||
    this.headingsColor = headingsColor;
 | 
						||
 | 
						||
    this.setDocId(docid);
 | 
						||
    this._initSocksJs();
 | 
						||
  };
 | 
						||
  DocsCoApi.prototype.getDocId = function() {
 | 
						||
    return this._docid;
 | 
						||
  };
 | 
						||
  DocsCoApi.prototype.setDocId = function(docid) {
 | 
						||
    //todo возможно надо менять sockjs_url
 | 
						||
    this._docid = docid;
 | 
						||
    this.socketio_url = AscCommon.getBaseUrlPathname() + '../../../../doc/' + docid + '/c';
 | 
						||
  };
 | 
						||
  DocsCoApi.prototype.getAuthCommand = function(opt_openCmd, opt_isIdle) {
 | 
						||
    if (this._locks) {
 | 
						||
      this.ownedLockBlocks = [];
 | 
						||
      //If we already have locks
 | 
						||
      for (var block in this._locks) if (this._locks.hasOwnProperty(block)) {
 | 
						||
        var lock = this._locks[block];
 | 
						||
        if (lock["state"] === 2) {
 | 
						||
          //Our lock.
 | 
						||
          this.ownedLockBlocks.push(lock["blockValue"]);
 | 
						||
        }
 | 
						||
      }
 | 
						||
      this._locks = {};
 | 
						||
    }
 | 
						||
    return {
 | 
						||
      'type': 'auth',
 | 
						||
      'docid': this._docid,
 | 
						||
      'documentCallbackUrl': this._documentCallbackUrl,
 | 
						||
      'token': this._token,
 | 
						||
      'user': {
 | 
						||
        'id': this._user.asc_getId(),
 | 
						||
        'username': this._user.asc_getUserName(),
 | 
						||
        'firstname': this._user.asc_getFirstName(),
 | 
						||
        'lastname': this._user.asc_getLastName(),
 | 
						||
        'indexUser': this._indexUser
 | 
						||
      },
 | 
						||
      'editorType': this.editorType,
 | 
						||
      'lastOtherSaveTime': this.lastOtherSaveTime,
 | 
						||
      'block': this.ownedLockBlocks,
 | 
						||
      'sessionId': this._id,
 | 
						||
      'sessionTimeConnect': this._sessionTimeConnect,
 | 
						||
      'sessionTimeIdle': opt_isIdle >= 0 ? opt_isIdle : 0,
 | 
						||
      'documentFormatSave': this._documentFormatSave,
 | 
						||
      'isCloseCoAuthoring': this.isCloseCoAuthoring,
 | 
						||
      'openCmd': opt_openCmd,
 | 
						||
      'lang': this.lang,
 | 
						||
      'mode': this.mode,
 | 
						||
      'permissions': this.permissions,
 | 
						||
      'encrypted': this.encrypted,
 | 
						||
      'IsAnonymousUser': this.IsAnonymousUser,
 | 
						||
      'timezoneOffset': (new Date()).getTimezoneOffset(),
 | 
						||
      'headingsColor': this.headingsColor,
 | 
						||
      'coEditingMode': this.coEditingMode,
 | 
						||
      'jwtOpen': this.jwtOpen,
 | 
						||
      'jwtSession': this.jwtSession,
 | 
						||
      'time': Math.round(performance.now()),
 | 
						||
      'supportAuthChangesAck': true
 | 
						||
    };
 | 
						||
  };
 | 
						||
  // Авторизация (ее нужно делать после выставления состояния редактора view-mode)
 | 
						||
  DocsCoApi.prototype.auth = function(isViewer, opt_openCmd, opt_isIdle) {
 | 
						||
    this._send(this.getAuthCommand(opt_openCmd, opt_isIdle));
 | 
						||
  };
 | 
						||
  function CNativeSocket(settings)
 | 
						||
  {
 | 
						||
    this.engine = window['SockJS'];
 | 
						||
    this.settings = settings;
 | 
						||
    this.io = this;
 | 
						||
    this.settings["type"] = "socketio";
 | 
						||
 | 
						||
    this.events = {};
 | 
						||
  }
 | 
						||
  CNativeSocket.prototype.open = function() { return this.engine.open(this.settings); };
 | 
						||
  CNativeSocket.prototype.send = function(message) { return this.engine.send(message); };
 | 
						||
  CNativeSocket.prototype.close = function() { return this.engine.close(); };
 | 
						||
  CNativeSocket.prototype.emit = function(message, data) { return this.send(JSON.stringify(data)); };
 | 
						||
 | 
						||
  CNativeSocket.prototype.reconnectionAttempts = function(val) { this.settings["reconnectionAttempts"] = val; };
 | 
						||
  CNativeSocket.prototype.reconnectionDelay    = function(val) { this.settings["reconnectionDelay"] = val; };
 | 
						||
  CNativeSocket.prototype.reconnectionDelayMax = function(val) { this.settings["reconnectionDelayMax"] = val; };
 | 
						||
  CNativeSocket.prototype.randomizationFactor  = function(val) { this.settings["randomizationFactor"] = val; };
 | 
						||
  CNativeSocket.prototype.setOpenToken = function (val) {
 | 
						||
    if (this.settings["auth"]) {
 | 
						||
      this.settings["auth"]["token"] = val;
 | 
						||
    }
 | 
						||
  };
 | 
						||
  CNativeSocket.prototype.setSessionToken = function (val) {
 | 
						||
    if (this.settings["auth"]) {
 | 
						||
      this.settings["auth"]["session"] = val;
 | 
						||
    }
 | 
						||
  };
 | 
						||
 | 
						||
  CNativeSocket.prototype.on = function(name, callback) {
 | 
						||
    if (!this.events.hasOwnProperty(name))
 | 
						||
      this.events[name] = [];
 | 
						||
    this.events[name].push(callback);
 | 
						||
  };
 | 
						||
  CNativeSocket.prototype.onMessage = function() {
 | 
						||
    var name = arguments[0];
 | 
						||
    if (this.events.hasOwnProperty(name))
 | 
						||
    {
 | 
						||
      for (var i = 0; i < this.events[name].length; ++i)
 | 
						||
        this.events[name][i].apply(this, Array.prototype.slice.call(arguments, 1));
 | 
						||
      return true;
 | 
						||
    }
 | 
						||
    return false;
 | 
						||
  };
 | 
						||
 | 
						||
	DocsCoApi.prototype._initSocksJs = function () {
 | 
						||
      var t = this;
 | 
						||
      let socket;
 | 
						||
      let firstConnection = true;
 | 
						||
      let options = {
 | 
						||
        "path": this.socketio_url,
 | 
						||
        "transports": ["websocket", "polling"],
 | 
						||
        "closeOnBeforeunload": false,
 | 
						||
        "reconnectionAttempts": 15,
 | 
						||
        "reconnectionDelay": 500,
 | 
						||
        "reconnectionDelayMax": 10000,
 | 
						||
        "randomizationFactor": 0.5,
 | 
						||
        "auth": {
 | 
						||
          "data": this.getAuthCommand(this.openCmd),
 | 
						||
          "token": this.jwtOpen,
 | 
						||
          "session": this.jwtSession
 | 
						||
        }
 | 
						||
      };
 | 
						||
      options["query"] = {};
 | 
						||
      if (this.shardKey) {
 | 
						||
        options["query"][Asc.c_sShardKeyName] = this.shardKey;
 | 
						||
      }
 | 
						||
      if (this.wopiSrc) {
 | 
						||
        options["query"][Asc.c_sWopiSrcName] = this.wopiSrc;
 | 
						||
      }
 | 
						||
      if (this.userSessionId) {
 | 
						||
        options["query"][Asc.c_sUserSessionIdName] = this.userSessionId;
 | 
						||
      }
 | 
						||
 | 
						||
      if (window['IS_NATIVE_EDITOR']) {
 | 
						||
        socket = this.sockjs = new CNativeSocket(options);
 | 
						||
        socket.open();
 | 
						||
      } else {
 | 
						||
        let io = AscCommon.getSocketIO();
 | 
						||
        socket = io(options);
 | 
						||
      }
 | 
						||
      socket.on("connect", function () {
 | 
						||
        firstConnection = false;
 | 
						||
        t._onServerOpen();
 | 
						||
      });
 | 
						||
      socket.on("disconnect", function (reason) {
 | 
						||
        //(explicit disconnection), the client will not try to reconnect and you need to manually call
 | 
						||
        let explicit = 'io server disconnect' === reason || 'io client disconnect' === reason;
 | 
						||
        t._onServerClose(explicit);
 | 
						||
        if (!explicit) {
 | 
						||
          //explicit disconnect sends disconnect reason on its own
 | 
						||
          t.onDisconnect();
 | 
						||
        }
 | 
						||
      });
 | 
						||
      socket.on('connect_error', function (err) {
 | 
						||
        //cases: every connect error and reconnect
 | 
						||
        if (err.data) {
 | 
						||
          //cases: authorization
 | 
						||
          t._onServerClose(true);
 | 
						||
          t.onDisconnect(err.data.description, err.data.code);
 | 
						||
        } else if (firstConnection) {
 | 
						||
          firstConnection = false;
 | 
						||
          if (socket.io.opts) {
 | 
						||
            socket.io.opts.transports = ["polling", "websocket"];
 | 
						||
          }
 | 
						||
        }
 | 
						||
      });
 | 
						||
      socket.io.on("reconnect_failed", function () {
 | 
						||
        //Fired when couldn't reconnect within reconnectionAttempts.
 | 
						||
        t._onServerClose(true);
 | 
						||
        t.onDisconnect("reconnect_failed", c_oCloseCode.reconnectFailed);
 | 
						||
      });
 | 
						||
      socket.on("message", function (data) {
 | 
						||
        t._onServerMessage(data);
 | 
						||
      });
 | 
						||
      this.socketio = socket;
 | 
						||
      return socket;
 | 
						||
	};
 | 
						||
 | 
						||
	DocsCoApi.prototype._onServerOpen = function () {
 | 
						||
		this._state = ConnectionState.WaitAuth;
 | 
						||
		this.onFirstConnect();
 | 
						||
	};
 | 
						||
	DocsCoApi.prototype._onServerMessage = function (data) {
 | 
						||
		//TODO: add checks and error handling
 | 
						||
		//Get data type
 | 
						||
		var dataObject = data;
 | 
						||
		switch (dataObject['type']) {
 | 
						||
			case 'auth'        :
 | 
						||
				this._onAuth(dataObject);
 | 
						||
				break;
 | 
						||
			case 'message'      :
 | 
						||
				this._onMessages(dataObject, false);
 | 
						||
				break;
 | 
						||
			case 'cursor'       :
 | 
						||
				this._onCursor(dataObject);
 | 
						||
				break;
 | 
						||
			case 'meta' :
 | 
						||
				this._onMeta(dataObject);
 | 
						||
				break;
 | 
						||
			case 'getLock'      :
 | 
						||
				this._onGetLock(dataObject);
 | 
						||
				break;
 | 
						||
			case 'releaseLock'    :
 | 
						||
				this._onReleaseLock(dataObject);
 | 
						||
				break;
 | 
						||
			case 'connectState'    :
 | 
						||
				this._onConnectionStateChanged(dataObject);
 | 
						||
				break;
 | 
						||
			case 'saveChanges'    :
 | 
						||
				this._onSaveChanges(dataObject);
 | 
						||
				break;
 | 
						||
			case 'authChanges' :
 | 
						||
				this._onAuthChanges(dataObject);
 | 
						||
				break;
 | 
						||
			case 'saveLock'      :
 | 
						||
				this._onSaveLock(dataObject);
 | 
						||
				break;
 | 
						||
			case 'unSaveLock'    :
 | 
						||
				this._onUnSaveLock(dataObject);
 | 
						||
				break;
 | 
						||
			case 'savePartChanges'  :
 | 
						||
				this._onSavePartChanges(dataObject);
 | 
						||
				break;
 | 
						||
			case 'drop'        :
 | 
						||
				this._onDrop(dataObject);
 | 
						||
				break;
 | 
						||
			case 'disconnectReason':
 | 
						||
				this._onDisconnectReason(dataObject);
 | 
						||
				break;
 | 
						||
			case 'waitAuth'      : /*Ждем, когда придет auth, документ залочен*/
 | 
						||
				break;
 | 
						||
			case 'error'      : /*Старая версия sdk*/
 | 
						||
				this._onDrop(dataObject);
 | 
						||
				break;
 | 
						||
			case 'documentOpen'    :
 | 
						||
				this._documentOpen(dataObject);
 | 
						||
				break;
 | 
						||
			case 'warning':
 | 
						||
				this._onWarning(dataObject);
 | 
						||
				break;
 | 
						||
			case 'license':
 | 
						||
				this._onLicense(dataObject);
 | 
						||
				break;
 | 
						||
			case 'session' :
 | 
						||
				this._onSession(dataObject);
 | 
						||
				break;
 | 
						||
			case 'refreshToken' :
 | 
						||
				this._onRefreshToken(dataObject["messages"]);
 | 
						||
				break;
 | 
						||
			case 'expiredToken' :
 | 
						||
				this._onExpiredToken(dataObject);
 | 
						||
				break;
 | 
						||
			case 'forceSaveStart' :
 | 
						||
				this._onForceSaveStart(dataObject["messages"]);
 | 
						||
				break;
 | 
						||
			case 'forceSave' :
 | 
						||
				this._onForceSave(dataObject["messages"]);
 | 
						||
				break;
 | 
						||
			case 'rpc' :
 | 
						||
				this._onPRC(dataObject["responseKey"], false, dataObject["data"]);
 | 
						||
				break;
 | 
						||
			case 'updateVersion' :
 | 
						||
				this.onMiscEvent(dataObject);
 | 
						||
				break;
 | 
						||
		}
 | 
						||
	};
 | 
						||
	DocsCoApi.prototype._onServerClose = function (explicit) {
 | 
						||
		if (ConnectionState.SaveChanges === this._state) {
 | 
						||
			// Мы сохраняли изменения и разорвалось соединение
 | 
						||
			this._isReSaveAfterAuth = true;
 | 
						||
			// Очищаем предыдущий таймер
 | 
						||
			if (null !== this.saveCallbackErrorTimeOutId) {
 | 
						||
				clearTimeout(this.saveCallbackErrorTimeOutId);
 | 
						||
				this.saveCallbackErrorTimeOutId = null;
 | 
						||
			}
 | 
						||
		}
 | 
						||
		if (explicit) {
 | 
						||
			this._state = ConnectionState.ClosedAll;
 | 
						||
		} else {
 | 
						||
			this._state = ConnectionState.Reconnect;
 | 
						||
		}
 | 
						||
	};
 | 
						||
  //----------------------------------------------------------export----------------------------------------------------
 | 
						||
  window['AscCommon'] = window['AscCommon'] || {};
 | 
						||
  window['AscCommon'].CDocsCoApi = CDocsCoApi;
 | 
						||
})(window);
 |