Document.coffee 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. define [
  2. "editor/ShareJsDoc"
  3. "libs/backbone"
  4. ], (ShareJsDoc) ->
  5. class Document
  6. @getDocument: (ide, doc_id) ->
  7. @openDocs ||= {}
  8. if !@openDocs[doc_id]?
  9. @openDocs[doc_id] = new Document(ide, doc_id)
  10. return @openDocs[doc_id]
  11. constructor: (@ide, @doc_id) ->
  12. @connected = @ide.socket.socket.connected
  13. @joined = false
  14. @wantToBeJoined = false
  15. @_bindToEditorEvents()
  16. @_bindToSocketEvents()
  17. attachToAce: (ace) ->
  18. @doc?.attachToAce(ace)
  19. detachFromAce: () ->
  20. @doc?.detachFromAce()
  21. getSnapshot: () ->
  22. @doc?.getSnapshot()
  23. getType: () ->
  24. @doc?.getType()
  25. _bindToSocketEvents: () ->
  26. @_onUpdateAppliedHandler = (update) => @_onUpdateApplied(update)
  27. @ide.socket.on "otUpdateApplied", @_onUpdateAppliedHandler
  28. @_onErrorHandler = (error, update) => @_onError(error, update)
  29. @ide.socket.on "otUpdateError", @_onErrorHandler
  30. @_onDisconnectHandler = (error) => @_onDisconnect(error)
  31. @ide.socket.on "disconnect", @_onDisconnectHandler
  32. _bindToEditorEvents: () ->
  33. @_onReconnectHandler = (update) => @_onReconnect(update)
  34. @ide.on "afterJoinProject", @_onReconnectHandler
  35. unBindFromSocketEvents: () ->
  36. @ide.socket.removeListener "otUpdateApplied", @_onUpdateAppliedHandler
  37. @ide.socket.removeListener "otUpdateError", @_onUpdateErrorHandler
  38. @ide.socket.removeListener "disconnect", @_onDisconnectHandler
  39. unBindFromEditorEvents: () ->
  40. @ide.off "afterJoinProject", @_onReconnectHandler
  41. leaveAndCleanUp: () ->
  42. @leave (error) =>
  43. @_cleanUp()
  44. join: (callback = (error) ->) ->
  45. @wantToBeJoined = true
  46. @_cancelLeave()
  47. if @connected
  48. return @_joinDoc callback
  49. else
  50. @_joinCallbacks ||= []
  51. @_joinCallbacks.push callback
  52. leave: (callback = (error) ->) ->
  53. @wantToBeJoined = false
  54. @_cancelJoin()
  55. if (@doc? and @doc.hasBufferedOps())
  56. @_leaveCallbacks ||= []
  57. @_leaveCallbacks.push callback
  58. else if !@connected
  59. callback()
  60. else
  61. @_leaveDoc(callback)
  62. _cancelLeave: () ->
  63. if @_leaveCallbacks?
  64. delete @_leaveCallbacks
  65. _cancelJoin: () ->
  66. if @_joinCallbacks?
  67. delete @_joinCallbacks
  68. _onUpdateApplied: (update) ->
  69. if update?.doc == @doc_id and @doc?
  70. @doc.processUpdateFromServer update
  71. if !@wantToBeJoined
  72. @leave()
  73. _onDisconnect: () ->
  74. @connected = false
  75. @joined = false
  76. @doc?.updateConnectionState "disconnected"
  77. _onReconnect: () ->
  78. @connected = true
  79. if @wantToBeJoined or @doc?.hasBufferedOps()
  80. @_joinDoc (error) =>
  81. return @_onError(error) if error?
  82. @doc.updateConnectionState "ok"
  83. @doc.flushPendingOps()
  84. @_callJoinCallbacks()
  85. _callJoinCallbacks: () ->
  86. for callback in @_joinCallbacks or []
  87. callback()
  88. delete @_joinCallbacks
  89. _joinDoc: (callback = (error) ->) ->
  90. if @doc?
  91. @ide.socket.emit 'joinDoc', @doc_id, @doc.getVersion(), (error, docLines, version, updates) =>
  92. return callback(error) if error?
  93. @joined = true
  94. @doc.catchUp( updates )
  95. callback()
  96. else
  97. @ide.socket.emit 'joinDoc', @doc_id, (error, docLines, version) =>
  98. return callback(error) if error?
  99. @joined = true
  100. @doc = new ShareJsDoc @doc_id, docLines, version, @ide.socket
  101. @_bindToShareJsDocEvents()
  102. callback()
  103. _leaveDoc: (callback = (error) ->) ->
  104. @ide.socket.emit 'leaveDoc', @doc_id, (error) =>
  105. return callback(error) if error?
  106. @joined = false
  107. for callback in @_leaveCallbacks or []
  108. callback(error)
  109. delete @_leaveCallbacks
  110. callback(error)
  111. _cleanUp: () ->
  112. delete Document.openDocs[@doc_id]
  113. @unBindFromEditorEvents()
  114. @unBindFromSocketEvents()
  115. _bindToShareJsDocEvents: () ->
  116. @doc.on "error", (error, meta) => @_onError error, meta
  117. @doc.on "externalUpdate", () => @trigger "externalUpdate"
  118. @doc.on "remoteop", () => @trigger "remoteop"
  119. @doc.on "op:sent", () => @trigger "op:sent"
  120. @doc.on "op:acknowledged", () => @trigger "op:acknowledged"
  121. _onError: (error, meta = {}) ->
  122. console.error "ShareJS error", error, meta
  123. ga?('send', 'event', 'error', "shareJsError", "#{error.message} - #{ide.socket.socket.transport.name}" )
  124. @ide.socket.disconnect()
  125. meta.doc_id = @doc_id
  126. @ide.reportError(error, meta)
  127. @doc?.clearInflightAndPendingOps()
  128. @_cleanUp()
  129. @trigger "error", error
  130. _.extend(Document::, Backbone.Events)
  131. return Document