diff --git a/services/web/public/coffee/ide/editor/directives/aceEditor.coffee b/services/web/public/coffee/ide/editor/directives/aceEditor.coffee index 617b41b845..ef6db538c4 100644 --- a/services/web/public/coffee/ide/editor/directives/aceEditor.coffee +++ b/services/web/public/coffee/ide/editor/directives/aceEditor.coffee @@ -10,13 +10,14 @@ define [ "ide/editor/directives/aceEditor/spell-check/SpellCheckAdapter" "ide/editor/directives/aceEditor/highlights/HighlightsManager" "ide/editor/directives/aceEditor/cursor-position/CursorPositionManager" + "ide/editor/directives/aceEditor/cursor-position/CursorPositionAdapter" "ide/editor/directives/aceEditor/track-changes/TrackChangesManager" "ide/editor/directives/aceEditor/metadata/MetadataManager" "ide/metadata/services/metadata" "ide/graphics/services/graphics" "ide/preamble/services/preamble" "ide/files/services/files" -], (App, Ace, SearchBox, Vim, ModeList, UndoManager, AutoCompleteManager, SpellCheckManager, SpellCheckAdapter, HighlightsManager, CursorPositionManager, TrackChangesManager, MetadataManager) -> +], (App, Ace, SearchBox, Vim, ModeList, UndoManager, AutoCompleteManager, SpellCheckManager, SpellCheckAdapter, HighlightsManager, CursorPositionManager, CursorPositionAdapter, TrackChangesManager, MetadataManager) -> EditSession = ace.require('ace/edit_session').EditSession ModeList = ace.require('ace/ext/modelist') Vim = ace.require('ace/keyboard/vim').Vim @@ -108,7 +109,7 @@ define [ undoManager = new UndoManager(scope, editor, element) highlightsManager = new HighlightsManager(scope, editor, element) - cursorPositionManager = new CursorPositionManager(scope, editor, element, localStorage) + cursorPositionManager = new CursorPositionManager(scope, new CursorPositionAdapter(editor), localStorage) trackChangesManager = new TrackChangesManager(scope, editor, element) metadataManager = new MetadataManager(scope, editor, element, metadata) autoCompleteManager = new AutoCompleteManager(scope, editor, element, metadataManager, graphics, preamble, files) @@ -380,6 +381,21 @@ define [ editor.off 'changeSession', onSessionChangeForSpellCheck editor.off 'nativecontextmenu', spellCheckManager.onContextMenu + onSessionChangeForCursorPosition = (e) -> + cursorPositionManager.onSessionChange(e) + e.oldSession?.selection.off 'changeCursor', cursorPositionManager.onCursorChange + e.session.selection.on 'changeCursor', cursorPositionManager.onCursorChange + + initCursorPosition = () -> + cursorPositionManager.init() + editor.on 'changeSession', onSessionChangeForCursorPosition + onSessionChangeForCursorPosition({ session: editor.getSession() }) # Force initial setup + $(window).on "unload", () -> + cursorPositionManager.onUnload(editor.getSession()) + + tearDownCursorPosition = () -> + editor.off 'changeSession', onSessionChangeForCursorPosition + attachToAce = (sharejs_doc) -> lines = sharejs_doc.getSnapshot().split("\n") session = editor.getSession() @@ -426,6 +442,7 @@ define [ # now ready to edit document editor.setReadOnly(scope.readOnly) # respect the readOnly setting, normally false initSpellCheck() + initCursorPosition() resetScrollMargins() @@ -488,6 +505,7 @@ define [ scope.$on '$destroy', () -> if scope.sharejsDoc? tearDownSpellCheck() + tearDownCursorPosition() detachFromAce(scope.sharejsDoc) session = editor.getSession() session?.destroy() diff --git a/services/web/public/coffee/ide/editor/directives/aceEditor/cursor-position/CursorPositionAdapter.coffee b/services/web/public/coffee/ide/editor/directives/aceEditor/cursor-position/CursorPositionAdapter.coffee new file mode 100644 index 0000000000..6c8c051f8a --- /dev/null +++ b/services/web/public/coffee/ide/editor/directives/aceEditor/cursor-position/CursorPositionAdapter.coffee @@ -0,0 +1,35 @@ +define [ + "ide/editor/AceShareJsCodec" +], (AceShareJsCodec) -> + class CursorPositionAdapter + constructor: (@editor) -> + + getCursor: () -> + @editor.getCursorPosition() + + getCursorForSession: (session) -> + session.selection.getCursor() + + getScrollTopForSession: (session) -> + session.getScrollTop() + + setCursor: (pos) -> + pos = pos.cursorPosition or { row: 0, column: 0 } + @editor.moveCursorToPosition(pos) + + setScrollTop: (pos) -> + pos = pos.scrollTop or 0 + @editor.getSession().setScrollTop(pos) + + clearSelection: () -> + @editor.selection.clearSelection() + + gotoLine: (line, column) -> + @editor.gotoLine(line, column) + @editor.scrollToLine(line, true, true) # centre and animate + @editor.focus() + + gotoOffset: (offset) -> + lines = @editor.getSession().getDocument().getAllLines() + position = AceShareJsCodec.shareJsOffsetToAcePosition(offset, lines) + @gotoLine(position.row + 1, position.column) diff --git a/services/web/public/coffee/ide/editor/directives/aceEditor/cursor-position/CursorPositionManager.coffee b/services/web/public/coffee/ide/editor/directives/aceEditor/cursor-position/CursorPositionManager.coffee index 119aa471e1..2b6ab3eeaf 100644 --- a/services/web/public/coffee/ide/editor/directives/aceEditor/cursor-position/CursorPositionManager.coffee +++ b/services/web/public/coffee/ide/editor/directives/aceEditor/cursor-position/CursorPositionManager.coffee @@ -1,75 +1,60 @@ -define [ - "ide/editor/AceShareJsCodec" -], (AceShareJsCodec) -> +define [], () -> class CursorPositionManager - constructor: (@$scope, @editor, @element, @localStorage) -> - - onChangeCursor = (e) => - @emitCursorUpdateEvent(e) - - @editor.on "changeSession", (e) => - if e.oldSession? - @storeCursorPosition(e.oldSession) - @storeScrollTopPosition(e.oldSession) - - @doc_id = @$scope.sharejsDoc?.doc_id - - e.oldSession?.selection.off 'changeCursor', onChangeCursor - e.session.selection.on 'changeCursor', onChangeCursor - - setTimeout () => - @gotoStoredPosition() - , 0 - - $(window).on "unload", () => - @storeCursorPosition(@editor.getSession()) - @storeScrollTopPosition(@editor.getSession()) - + constructor: (@$scope, @adapter, @localStorage) -> @$scope.$on "#{@$scope.name}:gotoLine", (e, line, column) => if line? setTimeout () => - @gotoLine(line, column) + @adapter.gotoLine(line, column) , 10 # Hack: Must happen after @gotoStoredPosition @$scope.$on "#{@$scope.name}:gotoOffset", (e, offset) => if offset? setTimeout () => - @gotoOffset(offset) + @adapter.gotoOffset(offset) , 10 # Hack: Must happen after @gotoStoredPosition @$scope.$on "#{@$scope.name}:clearSelection", (e) => - @editor.selection.clearSelection() + @adapter.clearSelection() + + init: () -> + @emitCursorUpdateEvent() + + onSessionChange: (e) => + if e.oldSession? + @storeCursorPosition(e.oldSession) + @storeScrollTopPosition(e.oldSession) + + @doc_id = @$scope.sharejsDoc?.doc_id + + setTimeout () => + @gotoStoredPosition() + , 0 + + onUnload: (session) => + @storeCursorPosition(session) + @storeScrollTopPosition(session) + + onCursorChange: () => + @emitCursorUpdateEvent() storeScrollTopPosition: (session) -> if @doc_id? docPosition = @localStorage("doc.position.#{@doc_id}") || {} - docPosition.scrollTop = session.getScrollTop() + docPosition.scrollTop = @adapter.getScrollTopForSession(session) @localStorage("doc.position.#{@doc_id}", docPosition) storeCursorPosition: (session) -> if @doc_id? docPosition = @localStorage("doc.position.#{@doc_id}") || {} - docPosition.cursorPosition = session.selection.getCursor() + docPosition.cursorPosition = @adapter.getCursorForSession(session) @localStorage("doc.position.#{@doc_id}", docPosition) - + emitCursorUpdateEvent: () -> - cursor = @editor.getCursorPosition() + cursor = @adapter.getCursor() @$scope.$emit "cursor:#{@$scope.name}:update", cursor gotoStoredPosition: () -> return if !@doc_id? pos = @localStorage("doc.position.#{@doc_id}") || {} - @ignoreCursorPositionChanges = true - @editor.moveCursorToPosition(pos.cursorPosition or {row: 0, column: 0}) - @editor.getSession().setScrollTop(pos.scrollTop or 0) - delete @ignoreCursorPositionChanges - - gotoLine: (line, column) -> - @editor.gotoLine(line, column) - @editor.scrollToLine(line,true,true) # centre and animate - @editor.focus() - - gotoOffset: (offset) -> - lines = @editor.getSession().getDocument().getAllLines() - position = AceShareJsCodec.shareJsOffsetToAcePosition(offset, lines) - @gotoLine(position.row + 1, position.column) \ No newline at end of file + @adapter.setCursor(pos) + @adapter.setScrollTop(pos)