| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196 |
- define [
- "ide/editor/Document"
- "ide/editor/components/spellMenu"
- "ide/editor/directives/aceEditor"
- "ide/editor/directives/toggleSwitch"
- "ide/editor/controllers/SavingNotificationController"
- ], (Document) ->
- class EditorManager
- constructor: (@ide, @$scope, @localStorage) ->
- @$scope.editor = {
- sharejs_doc: null
- open_doc_id: null
- open_doc_name: null
- opening: true
- trackChanges: false
- wantTrackChanges: false
- showRichText: @showRichText()
- }
- @$scope.$on "entity:selected", (event, entity) =>
- if (@$scope.ui.view != "history" and entity.type == "doc")
- @openDoc(entity)
- @$scope.$on "entity:deleted", (event, entity) =>
- if @$scope.editor.open_doc_id == entity.id
- return if !@$scope.project.rootDoc_id
- doc = @ide.fileTreeManager.findEntityById(@$scope.project.rootDoc_id)
- return if !doc?
- @openDoc(doc)
- initialized = false
- @$scope.$on "file-tree:initialized", () =>
- if !initialized
- initialized = true
- @autoOpenDoc()
- @$scope.$on "flush-changes", () =>
- Document.flushAll()
- @$scope.$watch "editor.wantTrackChanges", (value) =>
- return if !value?
- @_syncTrackChangesState(@$scope.editor.sharejs_doc)
- showRichText: () ->
- if !window.richTextEnabled
- return false
- @localStorage("editor.mode.#{@$scope.project_id}") == 'rich-text'
- autoOpenDoc: () ->
- open_doc_id =
- @ide.localStorage("doc.open_id.#{@$scope.project_id}") or
- @$scope.project.rootDoc_id
- return if !open_doc_id?
- doc = @ide.fileTreeManager.findEntityById(open_doc_id)
- return if !doc?
- @openDoc(doc)
- openDocId: (doc_id, options = {}) ->
- doc = @ide.fileTreeManager.findEntityById(doc_id)
- return if !doc?
- @openDoc(doc, options)
- openDoc: (doc, options = {}) ->
- sl_console.log "[openDoc] Opening #{doc.id}"
- @$scope.ui.view = "editor"
- done = () =>
- if options.gotoLine?
- # allow Ace to display document before moving, delay until next tick
- # added delay to make this happen later that gotoStoredPosition in
- # CursorPositionManager
- setTimeout () =>
- @$scope.$broadcast "editor:gotoLine", options.gotoLine, options.gotoColumn
- , 0
- else if options.gotoOffset?
- setTimeout () =>
- @$scope.$broadcast "editor:gotoOffset", options.gotoOffset
- , 0
- if doc.id == @$scope.editor.open_doc_id and !options.forceReopen
- @$scope.$apply () =>
- done()
- return
- @$scope.editor.open_doc_id = doc.id
- @$scope.editor.open_doc_name = doc.name
- @ide.localStorage "doc.open_id.#{@$scope.project_id}", doc.id
- @ide.fileTreeManager.selectEntity(doc)
- @$scope.editor.opening = true
- @_openNewDocument doc, (error, sharejs_doc) =>
- if error?
- @ide.showGenericMessageModal(
- "Error opening document"
- "Sorry, something went wrong opening this document. Please try again."
- )
- return
- @_syncTrackChangesState(sharejs_doc)
- @$scope.$broadcast "doc:opened"
- @$scope.$apply () =>
- @$scope.editor.opening = false
- @$scope.editor.sharejs_doc = sharejs_doc
- done()
- _openNewDocument: (doc, callback = (error, sharejs_doc) ->) ->
- sl_console.log "[_openNewDocument] Opening..."
- current_sharejs_doc = @$scope.editor.sharejs_doc
- if current_sharejs_doc?
- sl_console.log "[_openNewDocument] Leaving existing open doc..."
- current_sharejs_doc.leaveAndCleanUp()
- @_unbindFromDocumentEvents(current_sharejs_doc)
- new_sharejs_doc = Document.getDocument @ide, doc.id
- new_sharejs_doc.join (error) =>
- return callback(error) if error?
- @_bindToDocumentEvents(doc, new_sharejs_doc)
- callback null, new_sharejs_doc
- _bindToDocumentEvents: (doc, sharejs_doc) ->
- sharejs_doc.on "error", (error, meta) =>
- if error?.message?
- message = error.message
- else if typeof error == "string"
- message = error
- else
- message = ""
- if /maxDocLength/.test(message)
- @ide.showGenericMessageModal(
- "Document Too Long"
- "Sorry, this file is too long to be edited manually. Please upload it directly."
- )
- else if /too many comments or tracked changes/.test(message)
- @ide.showGenericMessageModal(
- "Too many comments or tracked changes"
- "Sorry, this file has too many comments or tracked changes. Please try accepting or rejecting some existing changes, or resolving and deleting some comments."
- )
- else
- @ide.socket.disconnect()
- @ide.reportError(error, meta)
- @ide.showGenericMessageModal(
- "Out of sync"
- "Sorry, this file has gone out of sync and we need to do a full refresh. <br> <a href='/learn/Kb/Editor_out_of_sync_problems'>Please see this help guide for more information</a>"
- )
- @openDoc(doc, forceReopen: true)
- sharejs_doc.on "externalUpdate", (update) =>
- return if @_ignoreExternalUpdates
- @ide.showGenericMessageModal(
- "Document Updated Externally"
- "This document was just updated externally. Any recent changes you have made may have been overwritten. To see previous versions please look in the history."
- )
- _unbindFromDocumentEvents: (document) ->
- document.off()
- getCurrentDocValue: () ->
- @$scope.editor.sharejs_doc?.getSnapshot()
- getCurrentDocId: () ->
- @$scope.editor.open_doc_id
- startIgnoringExternalUpdates: () ->
- @_ignoreExternalUpdates = true
- stopIgnoringExternalUpdates: () ->
- @_ignoreExternalUpdates = false
- _syncTimeout: null
- _syncTrackChangesState: (doc) ->
- return if !doc?
- if @_syncTimeout?
- clearTimeout @_syncTimeout
- @_syncTimeout = null
- want = @$scope.editor.wantTrackChanges
- have = doc.getTrackingChanges()
- if want == have
- @$scope.editor.trackChanges = want
- return
- do tryToggle = () =>
- saved = !doc.getInflightOp()? and !doc.getPendingOp()?
- if saved
- doc.setTrackingChanges(want)
- @$scope.$apply () =>
- @$scope.editor.trackChanges = want
- else
- @_syncTimeout = setTimeout tryToggle, 100
|