/** @babel */ const Grim = require('grim') import {it, fit, ffit, fffit, beforeEach, afterEach} from './async-spec-helpers' import etch from 'etch' const getNextUpdatePromise = () => etch.getScheduler().nextUpdatePromise describe('Dock', () => { describe('when a dock is activated', () => { it('opens the dock and activates its active pane', () => { jasmine.attachToDOM(atom.workspace.getElement()) const dock = atom.workspace.getLeftDock() const didChangeVisibleSpy = jasmine.createSpy() dock.onDidChangeVisible(didChangeVisibleSpy) expect(dock.isVisible()).toBe(false) expect(document.activeElement).toBe(atom.workspace.getCenter().getActivePane().getElement()) dock.activate() expect(dock.isVisible()).toBe(true) expect(document.activeElement).toBe(dock.getActivePane().getElement()) expect(didChangeVisibleSpy).toHaveBeenCalledWith(true) }) }) describe('when a dock is hidden', () => { it('transfers focus back to the active center pane if the dock had focus', () => { jasmine.attachToDOM(atom.workspace.getElement()) const dock = atom.workspace.getLeftDock() const didChangeVisibleSpy = jasmine.createSpy() dock.onDidChangeVisible(didChangeVisibleSpy) dock.activate() expect(document.activeElement).toBe(dock.getActivePane().getElement()) expect(didChangeVisibleSpy.mostRecentCall.args[0]).toBe(true) dock.hide() expect(document.activeElement).toBe(atom.workspace.getCenter().getActivePane().getElement()) expect(didChangeVisibleSpy.mostRecentCall.args[0]).toBe(false) dock.activate() expect(document.activeElement).toBe(dock.getActivePane().getElement()) expect(didChangeVisibleSpy.mostRecentCall.args[0]).toBe(true) dock.toggle() expect(document.activeElement).toBe(atom.workspace.getCenter().getActivePane().getElement()) expect(didChangeVisibleSpy.mostRecentCall.args[0]).toBe(false) // Don't change focus if the dock was not focused in the first place const modalElement = document.createElement('div') modalElement.setAttribute('tabindex', -1) atom.workspace.addModalPanel({item: modalElement}) modalElement.focus() expect(document.activeElement).toBe(modalElement) dock.show() expect(document.activeElement).toBe(modalElement) expect(didChangeVisibleSpy.mostRecentCall.args[0]).toBe(true) dock.hide() expect(document.activeElement).toBe(modalElement) expect(didChangeVisibleSpy.mostRecentCall.args[0]).toBe(false) }) }) describe('when a pane in a dock is activated', () => { it('opens the dock', async () => { const item = { element: document.createElement('div'), getDefaultLocation() { return 'left' } } await atom.workspace.open(item, {activatePane: false}) expect(atom.workspace.getLeftDock().isVisible()).toBe(false) atom.workspace.getLeftDock().getPanes()[0].activate() expect(atom.workspace.getLeftDock().isVisible()).toBe(true) }) }) describe('activating the next pane', () => { describe('when the dock has more than one pane', () => { it('activates the next pane', () => { const dock = atom.workspace.getLeftDock() const pane1 = dock.getPanes()[0] const pane2 = pane1.splitRight() const pane3 = pane2.splitRight() pane2.activate() expect(pane1.isActive()).toBe(false) expect(pane2.isActive()).toBe(true) expect(pane3.isActive()).toBe(false) dock.activateNextPane() expect(pane1.isActive()).toBe(false) expect(pane2.isActive()).toBe(false) expect(pane3.isActive()).toBe(true) }) }) describe('when the dock has only one pane', () => { it('leaves the current pane active', () => { const dock = atom.workspace.getLeftDock() expect(dock.getPanes().length).toBe(1) const pane = dock.getPanes()[0] expect(pane.isActive()).toBe(true) dock.activateNextPane() expect(pane.isActive()).toBe(true) }) }) }) describe('activating the previous pane', () => { describe('when the dock has more than one pane', () => { it('activates the previous pane', () => { const dock = atom.workspace.getLeftDock() const pane1 = dock.getPanes()[0] const pane2 = pane1.splitRight() const pane3 = pane2.splitRight() pane2.activate() expect(pane1.isActive()).toBe(false) expect(pane2.isActive()).toBe(true) expect(pane3.isActive()).toBe(false) dock.activatePreviousPane() expect(pane1.isActive()).toBe(true) expect(pane2.isActive()).toBe(false) expect(pane3.isActive()).toBe(false) }) }) describe('when the dock has only one pane', () => { it('leaves the current pane active', () => { const dock = atom.workspace.getLeftDock() expect(dock.getPanes().length).toBe(1) const pane = dock.getPanes()[0] expect(pane.isActive()).toBe(true) dock.activatePreviousPane() expect(pane.isActive()).toBe(true) }) }) }) describe('when the dock resize handle is double-clicked', () => { describe('when the dock is open', () => { it('resizes a vertically-oriented dock to the current item\'s preferred width', async () => { jasmine.attachToDOM(atom.workspace.getElement()) const item = { element: document.createElement('div'), getDefaultLocation() { return 'left' }, getPreferredWidth() { return 142 }, getPreferredHeight() { return 122 } } await atom.workspace.open(item) const dock = atom.workspace.getLeftDock() const dockElement = dock.getElement() dock.setState({size: 300}) await getNextUpdatePromise() expect(dockElement.offsetWidth).toBe(300) dockElement.querySelector('.atom-dock-resize-handle').dispatchEvent(new MouseEvent('mousedown', {detail: 2})) await getNextUpdatePromise() expect(dockElement.offsetWidth).toBe(item.getPreferredWidth()) }) it('resizes a horizontally-oriented dock to the current item\'s preferred width', async () => { jasmine.attachToDOM(atom.workspace.getElement()) const item = { element: document.createElement('div'), getDefaultLocation() { return 'bottom' }, getPreferredWidth() { return 122 }, getPreferredHeight() { return 142 } } await atom.workspace.open(item) const dock = atom.workspace.getBottomDock() const dockElement = dock.getElement() dock.setState({size: 300}) await getNextUpdatePromise() expect(dockElement.offsetHeight).toBe(300) dockElement.querySelector('.atom-dock-resize-handle').dispatchEvent(new MouseEvent('mousedown', {detail: 2})) await getNextUpdatePromise() expect(dockElement.offsetHeight).toBe(item.getPreferredHeight()) }) }) describe('when the dock is closed', () => { it('does nothing', async () => { jasmine.attachToDOM(atom.workspace.getElement()) const item = { element: document.createElement('div'), getDefaultLocation() { return 'bottom' }, getPreferredWidth() { return 122 }, getPreferredHeight() { return 142 } } await atom.workspace.open(item, {activatePane: false}) const dockElement = atom.workspace.getBottomDock().getElement() dockElement.querySelector('.atom-dock-resize-handle').dispatchEvent(new MouseEvent('mousedown', {detail: 2})) expect(dockElement.offsetHeight).toBe(0) expect(dockElement.querySelector('.atom-dock-inner').offsetHeight).toBe(0) // The content should be masked away. expect(dockElement.querySelector('.atom-dock-mask').offsetHeight).toBe(0) }) }) }) describe('when you add an item to an empty dock', () => { describe('when the item has a preferred size', () => { it('is takes the preferred size of the item', async () => { jasmine.attachToDOM(atom.workspace.getElement()) const createItem = preferredWidth => ({ element: document.createElement('div'), getDefaultLocation() { return 'left' }, getPreferredWidth() { return preferredWidth } }) const dock = atom.workspace.getLeftDock() const dockElement = dock.getElement() expect(dock.getPaneItems()).toHaveLength(0) const item1 = createItem(111) await atom.workspace.open(item1) // It should update the width every time we go from 0 -> 1 items, not just the first. expect(dock.isVisible()).toBe(true) expect(dockElement.offsetWidth).toBe(111) dock.destroyActivePane() expect(dock.getPaneItems()).toHaveLength(0) expect(dock.isVisible()).toBe(false) const item2 = createItem(222) await atom.workspace.open(item2) expect(dock.isVisible()).toBe(true) expect(dockElement.offsetWidth).toBe(222) // Adding a second shouldn't change the size. const item3 = createItem(333) await atom.workspace.open(item3) expect(dockElement.offsetWidth).toBe(222) }) }) describe('when the item has no preferred size', () => { it('is still has an explicit size', async () => { jasmine.attachToDOM(atom.workspace.getElement()) const item = { element: document.createElement('div'), getDefaultLocation() { return 'left' } } const dock = atom.workspace.getLeftDock() expect(dock.getPaneItems()).toHaveLength(0) expect(dock.state.size).toBe(null) await atom.workspace.open(item) expect(dock.state.size).not.toBe(null) }) }) }) describe('a deserialized dock', () => { it('restores the serialized size', async () => { jasmine.attachToDOM(atom.workspace.getElement()) const item = { element: document.createElement('div'), getDefaultLocation() { return 'left' }, getPreferredWidth() { return 122 }, serialize: () => ({deserializer: 'DockTestItem'}) } const itemDeserializer = atom.deserializers.add({ name: 'DockTestItem', deserialize: () => item }) const dock = atom.workspace.getLeftDock() const dockElement = dock.getElement() await atom.workspace.open(item) dock.setState({size: 150}) expect(dockElement.offsetWidth).toBe(150) const serialized = dock.serialize() dock.setState({size: 122}) expect(dockElement.offsetWidth).toBe(122) dock.destroyActivePane() dock.deserialize(serialized, atom.deserializers) expect(dockElement.offsetWidth).toBe(150) }) it("isn't visible if it has no items", async () => { jasmine.attachToDOM(atom.workspace.getElement()) const item = { element: document.createElement('div'), getDefaultLocation() { return 'left' }, getPreferredWidth() { return 122 } } const dock = atom.workspace.getLeftDock() await atom.workspace.open(item) expect(dock.isVisible()).toBe(true) const serialized = dock.serialize() dock.deserialize(serialized, atom.deserializers) expect(dock.getPaneItems()).toHaveLength(0) expect(dock.isVisible()).toBe(false) }) }) describe('drag handling', () => { it('expands docks to match the preferred size of the dragged item', async () => { jasmine.attachToDOM(atom.workspace.getElement()) const element = document.createElement('div') element.setAttribute('is', 'tabs-tab') element.item = { element, getDefaultLocation() { return 'left' }, getPreferredWidth() { return 144 } } const dragEvent = new DragEvent('dragstart') Object.defineProperty(dragEvent, 'target', {value: element}) atom.workspace.getElement().handleDragStart(dragEvent) await getNextUpdatePromise() expect(atom.workspace.getLeftDock().refs.wrapperElement.offsetWidth).toBe(144) }) it('does nothing when text nodes are dragged', () => { jasmine.attachToDOM(atom.workspace.getElement()) const textNode = document.createTextNode('hello') const dragEvent = new DragEvent('dragstart') Object.defineProperty(dragEvent, 'target', {value: textNode}) expect(() => atom.workspace.getElement().handleDragStart(dragEvent)).not.toThrow() }) }) describe('::getActiveTextEditor()', () => { it('is deprecated', () => { spyOn(Grim, 'deprecate') atom.workspace.getLeftDock().getActiveTextEditor() expect(Grim.deprecate.callCount).toBe(1) }) }) })