diff --git a/spec/extensions/tree-view-spec.coffee b/spec/extensions/tree-view-spec.coffee index 7ae13d532..041096cb8 100644 --- a/spec/extensions/tree-view-spec.coffee +++ b/spec/extensions/tree-view-spec.coffee @@ -123,25 +123,47 @@ describe "TreeView", -> expect(child.directory.subscriptionCount()).toBe 0 expect(grandchild.directory.subscriptionCount()).toBe 0 - describe "when a file is clicked", -> - it "opens it in the active editor, focuses it and selects it", -> + describe "when a file is single-clicked", -> + it "selects the files and opens it in the active editor, without changing focus", -> expect(rootView.activeEditor()).toBeUndefined() - sampleJs.click() + sampleJs.trigger clickEvent(originalEvent: { detail: 1 }) expect(sampleJs).toHaveClass 'selected' expect(rootView.activeEditor().buffer.path).toBe require.resolve('fixtures/sample.js') + expect(rootView.activeEditor().isFocused).toBeFalsy() - sampleTxt.click() + sampleTxt.trigger clickEvent(originalEvent: { detail: 1 }) expect(sampleTxt).toHaveClass 'selected' expect(treeView.find('.selected').length).toBe 1 expect(rootView.activeEditor().buffer.path).toBe require.resolve('fixtures/sample.txt') + expect(rootView.activeEditor().isFocused).toBeFalsy() - describe "when a directory is clicked", -> + describe "when a file is double-clicked", -> + it "selects the file and opens it in the active editor on the first click, then changes focus to the active editor on the second", -> + sampleJs.trigger clickEvent(originalEvent: { detail: 1 }) + expect(sampleJs).toHaveClass 'selected' + expect(rootView.activeEditor().buffer.path).toBe require.resolve('fixtures/sample.js') + expect(rootView.activeEditor().isFocused).toBeFalsy() + + sampleJs.trigger clickEvent(originalEvent: { detail: 2 }) + expect(rootView.activeEditor().isFocused).toBeTruthy() + + describe "when a directory is single-clicked", -> it "is selected", -> subdir = treeView.root.find('.directory:first').view() - subdir.click() + subdir.trigger clickEvent(originalEvent: { detail: 1 }) expect(subdir).toHaveClass 'selected' + describe "when a directory is double-clicked", -> + it "toggles the directory expansion state and does not change the focus to the editor", -> + sampleJs.trigger clickEvent(originalEvent: { detail: 1 }) + subdir = treeView.root.find('.directory:first').view() + subdir.trigger clickEvent(originalEvent: { detail: 1 }) + expect(subdir).toHaveClass 'selected' + subdir.trigger clickEvent(originalEvent: { detail: 2 }) + expect(subdir).toHaveClass 'expanded' + expect(rootView.activeEditor().isFocused).toBeFalsy() + describe "when a new file is opened in the active editor", -> it "is selected in the tree view if visible", -> sampleJs.click() diff --git a/spec/spec-helper.coffee b/spec/spec-helper.coffee index b12b3fffb..bc51e1330 100644 --- a/spec/spec-helper.coffee +++ b/spec/spec-helper.coffee @@ -71,9 +71,6 @@ window.keydownEvent = (pattern, properties={}) -> event.keystroke = (new Keymap).keystrokeStringForEvent(event) event -window.clickEvent = (properties={}) -> - $.Event "click", properties - window.mouseEvent = (type, properties) -> if properties.point {point, editor} = properties @@ -83,6 +80,9 @@ window.mouseEvent = (type, properties) -> properties.originalEvent ?= {detail: 1} $.Event type, properties +window.clickEvent = (properties={}) -> + window.mouseEvent("click", properties) + window.mousedownEvent = (properties={}) -> window.mouseEvent('mousedown', properties) diff --git a/src/app/root-view.coffee b/src/app/root-view.coffee index b1b8acec0..98c07dcc3 100644 --- a/src/app/root-view.coffee +++ b/src/app/root-view.coffee @@ -94,7 +94,7 @@ class RootView extends View extension.deactivate() for name, extension of @extensions @remove() - open: (path) -> + open: (path, changeFocus=true) -> buffer = @project.open(path) if @activeEditor() @@ -103,21 +103,25 @@ class RootView extends View editor = new Editor({ buffer }) pane = new Pane(editor) @panes.append(pane) - editor.focus() + if changeFocus + editor.focus() + else + @makeEditorActive(editor) editorFocused: (editor) -> - if @panes.containsElement(editor) - previousActiveEditor = @panes.find('.editor.active').view() - previousActiveEditor?.removeClass('active').off('.root-view') + @makeEditorActive(editor) if @panes.containsElement(editor) - editor - .addClass('active') - .on 'editor-path-change.root-view', => - @trigger 'active-editor-path-change', editor.buffer.path - - if not previousActiveEditor or editor.buffer.path != previousActiveEditor.buffer.path + makeEditorActive: (editor) -> + previousActiveEditor = @panes.find('.editor.active').view() + previousActiveEditor?.removeClass('active').off('.root-view') + editor + .addClass('active') + .on 'editor-path-change.root-view', => @trigger 'active-editor-path-change', editor.buffer.path + if not previousActiveEditor or editor.buffer.path != previousActiveEditor.buffer.path + @trigger 'active-editor-path-change', editor.buffer.path + setTitle: (title='untitled') -> document.title = title diff --git a/src/extensions/tree-view/tree-view.coffee b/src/extensions/tree-view/tree-view.coffee index 2e7a4dd05..adc9f0c49 100644 --- a/src/extensions/tree-view/tree-view.coffee +++ b/src/extensions/tree-view/tree-view.coffee @@ -39,8 +39,15 @@ class TreeView extends View initialize: (@rootView) -> @on 'click', '.entry', (e) => entry = $(e.currentTarget).view() - @selectEntry(entry) - @openSelectedEntry() if (entry instanceof FileView) + switch e.originalEvent?.detail ? 1 + when 1 + @selectEntry(entry) + @openSelectedEntry() if (entry instanceof FileView) + when 2 + if entry.is('.selected.file') + @rootView.activeEditor().focus() + else if entry.is('.selected.directory') + entry.toggleExpansion() false @on 'move-up', => @moveUp() @@ -119,8 +126,7 @@ class TreeView extends View if (selectedEntry instanceof DirectoryView) selectedEntry.view().toggleExpansion() else if (selectedEntry instanceof FileView) - @rootView.open(selectedEntry.getPath()) - @rootView.focus() + @rootView.open(selectedEntry.getPath(), false) move: -> @rootView.append(new MoveDialog(@rootView.project, @selectedEntry().getPath())) diff --git a/static/tree-view.css b/static/tree-view.css index 7f3aa31a9..13d8bacf4 100644 --- a/static/tree-view.css +++ b/static/tree-view.css @@ -7,6 +7,7 @@ padding: 0 1em; cursor: default; font: 16px Inconsolata, Monaco, Courier !important; + -webkit-user-select: none; } .tree-view .disclosure-arrow {