From f7bb32c4a9da81c1855d5689e77600aa3d147218 Mon Sep 17 00:00:00 2001 From: Winston Liu <50Wliu@users.noreply.github.com> Date: Thu, 2 May 2019 01:33:16 -0400 Subject: [PATCH 1/7] Only allow drag-and-drop to succeed on panes in the center workspace --- src/pane-element.js | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/pane-element.js b/src/pane-element.js index 1ef9ce17eb1..ecf32925928 100644 --- a/src/pane-element.js +++ b/src/pane-element.js @@ -53,15 +53,23 @@ class PaneElement extends HTMLElement { } } const handleDragOver = event => { - event.preventDefault() - event.stopPropagation() + const items = Array.from(event.dataTransfer.items).filter(item => item.kind === 'file') + // TextEditors are only allowed in the center workspace, so make sure this pane is in the center + if (items.length > 0 && atom.workspace.getCenter().getPanes().includes(this.getModel())) { + event.preventDefault() + event.stopPropagation() + } } const handleDrop = event => { - event.preventDefault() - event.stopPropagation() - this.getModel().activate() - const pathsToOpen = [...event.dataTransfer.files].map(file => file.path) - if (pathsToOpen.length > 0) { + const items = Array.from(event.dataTransfer.items).filter(item => item.kind === 'file') + // TextEditors are only allowed in the center workspace, so make sure this pane is in the center + if (items.length > 0 && atom.workspace.getCenter().getPanes().includes(this.getModel())) { + event.preventDefault() + event.stopPropagation() + this.getModel().activate() + + const files = items.map(item => item.getAsFile()) + const pathsToOpen = files.map(file => file.path) this.applicationDelegate.open({pathsToOpen, here: true}) } } From e951766ea063af8e4d745481ac7f8141661d9bfb Mon Sep 17 00:00:00 2001 From: Winston Liu <50Wliu@users.noreply.github.com> Date: Thu, 2 May 2019 02:38:05 -0400 Subject: [PATCH 2/7] Remove unused drag-related functions in window-event-handler --- src/window-event-handler.js | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/window-event-handler.js b/src/window-event-handler.js index 6d927e76eba..7284f55af4b 100644 --- a/src/window-event-handler.js +++ b/src/window-event-handler.js @@ -56,8 +56,6 @@ class WindowEventHandler { this.addEventListener(this.document, 'keyup', this.handleDocumentKeyEvent) this.addEventListener(this.document, 'keydown', this.handleDocumentKeyEvent) - this.addEventListener(this.document, 'drop', this.handleDocumentDrop) - this.addEventListener(this.document, 'dragover', this.handleDocumentDragover) this.addEventListener(this.document, 'contextmenu', this.handleDocumentContextmenu) this.subscriptions.add(listen(this.document, 'click', 'a', this.handleLinkClick)) this.subscriptions.add(listen(this.document, 'submit', 'form', this.handleFormSubmit)) @@ -111,17 +109,6 @@ class WindowEventHandler { event.stopImmediatePropagation() } - handleDrop (event) { - event.preventDefault() - event.stopPropagation() - } - - handleDragover (event) { - event.preventDefault() - event.stopPropagation() - event.dataTransfer.dropEffect = 'none' - } - eachTabIndexedElement (callback) { for (let element of this.document.querySelectorAll('[tabindex]')) { if (element.disabled) { continue } From 00dfa46baf114d45fac10659e1961431ab3c9f4b Mon Sep 17 00:00:00 2001 From: Winston Liu <50Wliu@users.noreply.github.com> Date: Sat, 4 May 2019 12:19:51 -0400 Subject: [PATCH 3/7] Fix specs --- spec/pane-element-spec.coffee | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/spec/pane-element-spec.coffee b/spec/pane-element-spec.coffee index 16534c9b04b..6912f5f9b76 100644 --- a/spec/pane-element-spec.coffee +++ b/spec/pane-element-spec.coffee @@ -1,18 +1,13 @@ PaneContainer = require '../src/pane-container' describe "PaneElement", -> - [paneElement, container, containerElement, pane] = [] + [paneElement, containerElement, pane] = [] beforeEach -> spyOn(atom.applicationDelegate, "open") - container = new PaneContainer - location: 'center' - config: atom.config - confirm: atom.confirm.bind(atom) - viewRegistry: atom.views - applicationDelegate: atom.applicationDelegate - containerElement = container.getElement() + container = atom.workspace.getActivePaneContainer() + containerElement = container.paneContainer.getElement() pane = container.getActivePane() paneElement = pane.getElement() @@ -247,9 +242,9 @@ describe "PaneElement", -> expect(document.activeElement).toBe paneElement describe "drag and drop", -> - buildDragEvent = (type, files) -> + buildDragEvent = (type, items) -> dataTransfer = - files: files + items: items data: {} setData: (key, value) -> @data[key] = value getData: (key) -> @data[key] @@ -260,7 +255,10 @@ describe "PaneElement", -> describe "when a file is dragged to the pane", -> it "opens it", -> - event = buildDragEvent("drop", [{path: "/fake1"}, {path: "/fake2"}]) + event = buildDragEvent("drop", [ + {kind: "file", getAsFile: () -> {path: "/fake1"}}, + {kind: "file", getAsFile: () -> {path: "/fake2"}} + ]) paneElement.dispatchEvent(event) expect(atom.applicationDelegate.open.callCount).toBe 1 expect(atom.applicationDelegate.open.argsForCall[0][0]).toEqual pathsToOpen: ['/fake1', '/fake2'], here: true From 01d7b883459be80d36f102c9281d09990f2609e0 Mon Sep 17 00:00:00 2001 From: Winston Liu <50Wliu@users.noreply.github.com> Date: Sat, 4 May 2019 12:24:13 -0400 Subject: [PATCH 4/7] Add tests for non-center workspaces --- spec/pane-element-spec.coffee | 47 ++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 17 deletions(-) diff --git a/spec/pane-element-spec.coffee b/spec/pane-element-spec.coffee index 6912f5f9b76..87eb37db312 100644 --- a/spec/pane-element-spec.coffee +++ b/spec/pane-element-spec.coffee @@ -1,5 +1,3 @@ -PaneContainer = require '../src/pane-container' - describe "PaneElement", -> [paneElement, containerElement, pane] = [] @@ -253,21 +251,36 @@ describe "PaneElement", -> event.dataTransfer = dataTransfer event - describe "when a file is dragged to the pane", -> - it "opens it", -> - event = buildDragEvent("drop", [ - {kind: "file", getAsFile: () -> {path: "/fake1"}}, - {kind: "file", getAsFile: () -> {path: "/fake2"}} - ]) - paneElement.dispatchEvent(event) - expect(atom.applicationDelegate.open.callCount).toBe 1 - expect(atom.applicationDelegate.open.argsForCall[0][0]).toEqual pathsToOpen: ['/fake1', '/fake2'], here: true - - describe "when a non-file is dragged to the pane", -> - it "does nothing", -> - event = buildDragEvent("drop", []) - paneElement.dispatchEvent(event) - expect(atom.applicationDelegate.open).not.toHaveBeenCalled() + describe "when the pane is in the center workspace", -> + describe "when a file is dragged to the pane", -> + it "opens it", -> + event = buildDragEvent("drop", [ + {kind: "file", getAsFile: () -> {path: "/fake1"}}, + {kind: "file", getAsFile: () -> {path: "/fake2"}} + ]) + paneElement.dispatchEvent(event) + expect(atom.applicationDelegate.open.callCount).toBe 1 + expect(atom.applicationDelegate.open.argsForCall[0][0]).toEqual pathsToOpen: ['/fake1', '/fake2'], here: true + + describe "when a non-file is dragged to the pane", -> + it "does nothing", -> + event = buildDragEvent("drop", []) + paneElement.dispatchEvent(event) + expect(atom.applicationDelegate.open).not.toHaveBeenCalled() + + describe "when the pane is not in the center workspace", -> + beforeEach -> + pane = atom.workspace.getLeftDock().getActivePane() + paneElement = pane.getElement() + + describe "when a drop event occurs", -> + it "does nothing", -> + event = buildDragEvent("drop", [ + {kind: "file", getAsFile: () -> {path: "/fake1"}}, + {kind: "file", getAsFile: () -> {path: "/fake2"}} + ]) + paneElement.dispatchEvent(event) + expect(atom.applicationDelegate.open).not.toHaveBeenCalled() describe "resize", -> it "shrinks independently of its contents' width", -> From df4d0eed9bb0cb13e7db6c87a66e9c093b9ccaf2 Mon Sep 17 00:00:00 2001 From: Winston Liu <50Wliu@users.noreply.github.com> Date: Sat, 4 May 2019 13:32:36 -0400 Subject: [PATCH 5/7] :shirt: --- spec/pane-element-spec.coffee | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spec/pane-element-spec.coffee b/spec/pane-element-spec.coffee index 87eb37db312..b9297253350 100644 --- a/spec/pane-element-spec.coffee +++ b/spec/pane-element-spec.coffee @@ -255,8 +255,8 @@ describe "PaneElement", -> describe "when a file is dragged to the pane", -> it "opens it", -> event = buildDragEvent("drop", [ - {kind: "file", getAsFile: () -> {path: "/fake1"}}, - {kind: "file", getAsFile: () -> {path: "/fake2"}} + {kind: "file", getAsFile: -> {path: "/fake1"}}, + {kind: "file", getAsFile: -> {path: "/fake2"}} ]) paneElement.dispatchEvent(event) expect(atom.applicationDelegate.open.callCount).toBe 1 @@ -276,8 +276,8 @@ describe "PaneElement", -> describe "when a drop event occurs", -> it "does nothing", -> event = buildDragEvent("drop", [ - {kind: "file", getAsFile: () -> {path: "/fake1"}}, - {kind: "file", getAsFile: () -> {path: "/fake2"}} + {kind: "file", getAsFile: -> {path: "/fake1"}}, + {kind: "file", getAsFile: -> {path: "/fake2"}} ]) paneElement.dispatchEvent(event) expect(atom.applicationDelegate.open).not.toHaveBeenCalled() From 2fa4c0a5de741781b263dd1d6c6339fee80fdbfd Mon Sep 17 00:00:00 2001 From: Rafael Oleza Date: Fri, 31 May 2019 19:06:04 +0200 Subject: [PATCH 6/7] Re-apply prettier JS formatter --- src/pane-element.js | 44 ++++++++++++++++++--------- src/window-event-handler.js | 60 +++++++++++++++++++++++++------------ 2 files changed, 71 insertions(+), 33 deletions(-) diff --git a/src/pane-element.js b/src/pane-element.js index 5e32bbdfde7..c3eadca1e14 100644 --- a/src/pane-element.js +++ b/src/pane-element.js @@ -53,24 +53,40 @@ class PaneElement extends HTMLElement { } }; const handleDragOver = event => { - const items = Array.from(event.dataTransfer.items).filter(item => item.kind === 'file') + const items = Array.from(event.dataTransfer.items).filter( + item => item.kind === 'file' + ); // TextEditors are only allowed in the center workspace, so make sure this pane is in the center - if (items.length > 0 && atom.workspace.getCenter().getPanes().includes(this.getModel())) { - event.preventDefault() - event.stopPropagation() + if ( + items.length > 0 && + atom.workspace + .getCenter() + .getPanes() + .includes(this.getModel()) + ) { + event.preventDefault(); + event.stopPropagation(); } - } + }; const handleDrop = event => { - const items = Array.from(event.dataTransfer.items).filter(item => item.kind === 'file') + const items = Array.from(event.dataTransfer.items).filter( + item => item.kind === 'file' + ); // TextEditors are only allowed in the center workspace, so make sure this pane is in the center - if (items.length > 0 && atom.workspace.getCenter().getPanes().includes(this.getModel())) { - event.preventDefault() - event.stopPropagation() - this.getModel().activate() - - const files = items.map(item => item.getAsFile()) - const pathsToOpen = files.map(file => file.path) - this.applicationDelegate.open({pathsToOpen, here: true}) + if ( + items.length > 0 && + atom.workspace + .getCenter() + .getPanes() + .includes(this.getModel()) + ) { + event.preventDefault(); + event.stopPropagation(); + this.getModel().activate(); + + const files = items.map(item => item.getAsFile()); + const pathsToOpen = files.map(file => file.path); + this.applicationDelegate.open({ pathsToOpen, here: true }); } }; this.addEventListener('focus', handleFocus, true); diff --git a/src/window-event-handler.js b/src/window-event-handler.js index d75c0414e2c..350ff404a45 100644 --- a/src/window-event-handler.js +++ b/src/window-event-handler.js @@ -51,24 +51,46 @@ module.exports = class WindowEventHandler { ); } - this.subscriptions.add(this.atomEnvironment.commands.add(this.document, { - 'core:focus-next': this.handleFocusNext, - 'core:focus-previous': this.handleFocusPrevious - })) - - this.addEventListener(this.window, 'beforeunload', this.handleWindowBeforeunload) - this.addEventListener(this.window, 'focus', this.handleWindowFocus) - this.addEventListener(this.window, 'blur', this.handleWindowBlur) - this.addEventListener(this.window, 'resize', this.handleWindowResize) - - this.addEventListener(this.document, 'keyup', this.handleDocumentKeyEvent) - this.addEventListener(this.document, 'keydown', this.handleDocumentKeyEvent) - this.addEventListener(this.document, 'contextmenu', this.handleDocumentContextmenu) - this.subscriptions.add(listen(this.document, 'click', 'a', this.handleLinkClick)) - this.subscriptions.add(listen(this.document, 'submit', 'form', this.handleFormSubmit)) - - this.subscriptions.add(this.applicationDelegate.onDidEnterFullScreen(this.handleEnterFullScreen)) - this.subscriptions.add(this.applicationDelegate.onDidLeaveFullScreen(this.handleLeaveFullScreen)) + this.subscriptions.add( + this.atomEnvironment.commands.add(this.document, { + 'core:focus-next': this.handleFocusNext, + 'core:focus-previous': this.handleFocusPrevious + }) + ); + + this.addEventListener( + this.window, + 'beforeunload', + this.handleWindowBeforeunload + ); + this.addEventListener(this.window, 'focus', this.handleWindowFocus); + this.addEventListener(this.window, 'blur', this.handleWindowBlur); + this.addEventListener(this.window, 'resize', this.handleWindowResize); + + this.addEventListener(this.document, 'keyup', this.handleDocumentKeyEvent); + this.addEventListener( + this.document, + 'keydown', + this.handleDocumentKeyEvent + ); + this.addEventListener( + this.document, + 'contextmenu', + this.handleDocumentContextmenu + ); + this.subscriptions.add( + listen(this.document, 'click', 'a', this.handleLinkClick) + ); + this.subscriptions.add( + listen(this.document, 'submit', 'form', this.handleFormSubmit) + ); + + this.subscriptions.add( + this.applicationDelegate.onDidEnterFullScreen(this.handleEnterFullScreen) + ); + this.subscriptions.add( + this.applicationDelegate.onDidLeaveFullScreen(this.handleLeaveFullScreen) + ); } // Wire commands that should be handled by Chromium for elements with the @@ -121,7 +143,7 @@ module.exports = class WindowEventHandler { event.stopImmediatePropagation(); } - eachTabIndexedElement (callback) { + eachTabIndexedElement(callback) { for (let element of this.document.querySelectorAll('[tabindex]')) { if (element.disabled) { continue; From e71d5594f7c9699a3e90e82d422263cd58fd4002 Mon Sep 17 00:00:00 2001 From: Winston Liu Date: Tue, 28 Sep 2021 23:54:13 +0000 Subject: [PATCH 7/7] Fix specs --- spec/pane-element-spec.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spec/pane-element-spec.js b/spec/pane-element-spec.js index 01bfb5fdeee..f2aa30d3210 100644 --- a/spec/pane-element-spec.js +++ b/spec/pane-element-spec.js @@ -290,8 +290,8 @@ describe('PaneElement', function() { describe('when a file is dragged to the pane', () => it('opens it', function() { const event = buildDragEvent('drop', [ - { path: '/fake1' }, - { path: '/fake2' } + { kind: 'file', getAsFile: () => ({ path: '/fake1' }) }, + { kind: 'file', getAsFile: () => ({ path: '/fake2' }) } ]); paneElement.dispatchEvent(event); expect(atom.applicationDelegate.open.callCount).toBe(1); @@ -318,8 +318,8 @@ describe('PaneElement', function() { describe('when a drag event occurs', () => { it('does nothing', () => { const event = buildDragEvent('drop', [ - { path: '/fake1' }, - { path: '/fake2' } + { kind: 'file', getAsFile: () => ({ path: '/fake1' }) }, + { kind: 'file', getAsFile: () => ({ path: '/fake2' }) } ]); paneElement.dispatchEvent(event); expect(atom.applicationDelegate.open).not.toHaveBeenCalled();