mirror of
https://github.com/pulsar-edit/pulsar.git
synced 2024-09-20 07:28:08 +03:00
Merge branch 'master' into as-update-fs-plus
This commit is contained in:
commit
9e864fac30
@ -6,6 +6,6 @@
|
||||
"url": "https://github.com/atom/atom.git"
|
||||
},
|
||||
"dependencies": {
|
||||
"atom-package-manager": "1.16.0"
|
||||
"atom-package-manager": "1.16.1"
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ In this directory you can only find very specific build and API level documentat
|
||||
|
||||
Instructions for building Atom on various platforms from source.
|
||||
|
||||
* [macOS](./build-instructions/macos.md)
|
||||
* [macOS](./build-instructions/macOS.md)
|
||||
* [Windows](./build-instructions/windows.md)
|
||||
* [Linux](./build-instructions/linux.md)
|
||||
* [FreeBSD](./build-instructions/freebsd.md)
|
||||
|
30
package.json
30
package.json
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "atom",
|
||||
"productName": "Atom",
|
||||
"version": "1.16.0-dev",
|
||||
"version": "1.17.0-dev",
|
||||
"description": "A hackable text editor for the 21st Century.",
|
||||
"main": "./src/main-process/main.js",
|
||||
"repository": {
|
||||
@ -98,7 +98,7 @@
|
||||
"about": "1.7.5",
|
||||
"archive-view": "0.63.1",
|
||||
"autocomplete-atom-api": "0.10.0",
|
||||
"autocomplete-css": "0.15.0",
|
||||
"autocomplete-css": "0.15.1",
|
||||
"autocomplete-html": "0.7.2",
|
||||
"autocomplete-plus": "2.34.2",
|
||||
"autocomplete-snippets": "1.11.0",
|
||||
@ -113,7 +113,7 @@
|
||||
"dev-live-reload": "0.47.1",
|
||||
"encoding-selector": "0.23.2",
|
||||
"exception-reporting": "0.41.3",
|
||||
"find-and-replace": "0.207.1",
|
||||
"find-and-replace": "0.207.2",
|
||||
"fuzzy-finder": "1.5.1",
|
||||
"git-diff": "1.3.4",
|
||||
"go-to-line": "0.32.0",
|
||||
@ -141,38 +141,38 @@
|
||||
"welcome": "0.36.2",
|
||||
"whitespace": "0.36.2",
|
||||
"wrap-guide": "0.40.0",
|
||||
"language-c": "0.56.0",
|
||||
"language-c": "0.57.0",
|
||||
"language-clojure": "0.22.2",
|
||||
"language-coffee-script": "0.48.5",
|
||||
"language-csharp": "0.14.2",
|
||||
"language-css": "0.42.0",
|
||||
"language-css": "0.42.1",
|
||||
"language-gfm": "0.88.1",
|
||||
"language-git": "0.19.0",
|
||||
"language-go": "0.43.1",
|
||||
"language-html": "0.47.2",
|
||||
"language-hyperlink": "0.16.1",
|
||||
"language-java": "0.26.0",
|
||||
"language-java": "0.27.0",
|
||||
"language-javascript": "0.126.1",
|
||||
"language-json": "0.18.3",
|
||||
"language-less": "0.30.1",
|
||||
"language-json": "0.19.0",
|
||||
"language-less": "0.31.0",
|
||||
"language-make": "0.22.3",
|
||||
"language-mustache": "0.13.1",
|
||||
"language-objective-c": "0.15.1",
|
||||
"language-perl": "0.37.0",
|
||||
"language-php": "0.37.4",
|
||||
"language-property-list": "0.9.0",
|
||||
"language-php": "0.37.5",
|
||||
"language-property-list": "0.9.1",
|
||||
"language-python": "0.45.2",
|
||||
"language-ruby": "0.70.5",
|
||||
"language-ruby-on-rails": "0.25.2",
|
||||
"language-sass": "0.57.1",
|
||||
"language-sass": "0.58.0",
|
||||
"language-shellscript": "0.25.0",
|
||||
"language-source": "0.9.0",
|
||||
"language-sql": "0.25.3",
|
||||
"language-text": "0.7.1",
|
||||
"language-sql": "0.25.4",
|
||||
"language-text": "0.7.2",
|
||||
"language-todo": "0.29.1",
|
||||
"language-toml": "0.18.1",
|
||||
"language-xml": "0.34.16",
|
||||
"language-yaml": "0.28.0"
|
||||
"language-xml": "0.35.0",
|
||||
"language-yaml": "0.29.0"
|
||||
},
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
@ -13,7 +13,7 @@
|
||||
"fs-extra": "0.30.0",
|
||||
"glob": "7.0.3",
|
||||
"joanna": "0.0.8",
|
||||
"legal-eagle": "0.13.0",
|
||||
"legal-eagle": "0.14.0",
|
||||
"lodash.template": "4.4.0",
|
||||
"minidump": "0.9.0",
|
||||
"mkdirp": "0.5.1",
|
||||
|
@ -1,137 +0,0 @@
|
||||
Panel = require '../src/panel'
|
||||
PanelContainer = require '../src/panel-container'
|
||||
|
||||
describe "PanelContainerElement", ->
|
||||
[jasmineContent, element, container] = []
|
||||
|
||||
class TestPanelContainerItem
|
||||
constructior: ->
|
||||
|
||||
class TestPanelContainerItemElement extends HTMLElement
|
||||
createdCallback: ->
|
||||
@classList.add('test-root')
|
||||
initialize: (@model) ->
|
||||
this
|
||||
|
||||
TestPanelContainerItemElement = document.registerElement 'atom-test-container-item-element', prototype: TestPanelContainerItemElement.prototype
|
||||
|
||||
beforeEach ->
|
||||
jasmineContent = document.body.querySelector('#jasmine-content')
|
||||
|
||||
atom.views.addViewProvider TestPanelContainerItem, (model) ->
|
||||
new TestPanelContainerItemElement().initialize(model)
|
||||
|
||||
container = new PanelContainer({location: 'left'})
|
||||
element = atom.views.getView(container)
|
||||
jasmineContent.appendChild(element)
|
||||
|
||||
it 'has a location class with value from the model', ->
|
||||
expect(element).toHaveClass 'left'
|
||||
|
||||
it 'removes the element when the container is destroyed', ->
|
||||
expect(element.parentNode).toBe jasmineContent
|
||||
container.destroy()
|
||||
expect(element.parentNode).not.toBe jasmineContent
|
||||
|
||||
describe "adding and removing panels", ->
|
||||
it "allows panels to be inserted at any position", ->
|
||||
panel1 = new Panel({item: new TestPanelContainerItem(), priority: 10})
|
||||
panel2 = new Panel({item: new TestPanelContainerItem(), priority: 5})
|
||||
panel3 = new Panel({item: new TestPanelContainerItem(), priority: 8})
|
||||
|
||||
container.addPanel(panel1)
|
||||
container.addPanel(panel2)
|
||||
container.addPanel(panel3)
|
||||
|
||||
expect(element.childNodes[2].getModel()).toBe(panel1)
|
||||
expect(element.childNodes[1].getModel()).toBe(panel3)
|
||||
expect(element.childNodes[0].getModel()).toBe(panel2)
|
||||
|
||||
describe "when the container is at the left location", ->
|
||||
it "adds atom-panel elements when a new panel is added to the container; removes them when the panels are destroyed", ->
|
||||
expect(element.childNodes.length).toBe 0
|
||||
|
||||
panel1 = new Panel({item: new TestPanelContainerItem()})
|
||||
container.addPanel(panel1)
|
||||
expect(element.childNodes.length).toBe 1
|
||||
expect(element.childNodes[0]).toHaveClass 'left'
|
||||
expect(element.childNodes[0]).toHaveClass 'tool-panel' # legacy selector support
|
||||
expect(element.childNodes[0]).toHaveClass 'panel-left' # legacy selector support
|
||||
|
||||
expect(element.childNodes[0].tagName).toBe 'ATOM-PANEL'
|
||||
|
||||
panel2 = new Panel({item: new TestPanelContainerItem()})
|
||||
container.addPanel(panel2)
|
||||
expect(element.childNodes.length).toBe 2
|
||||
|
||||
expect(atom.views.getView(panel1).style.display).not.toBe 'none'
|
||||
expect(atom.views.getView(panel2).style.display).not.toBe 'none'
|
||||
|
||||
panel1.destroy()
|
||||
expect(element.childNodes.length).toBe 1
|
||||
|
||||
panel2.destroy()
|
||||
expect(element.childNodes.length).toBe 0
|
||||
|
||||
describe "when the container is at the bottom location", ->
|
||||
beforeEach ->
|
||||
container = new PanelContainer({location: 'bottom'})
|
||||
element = atom.views.getView(container)
|
||||
jasmineContent.appendChild(element)
|
||||
|
||||
it "adds atom-panel elements when a new panel is added to the container; removes them when the panels are destroyed", ->
|
||||
expect(element.childNodes.length).toBe 0
|
||||
|
||||
panel1 = new Panel({item: new TestPanelContainerItem(), className: 'one'})
|
||||
container.addPanel(panel1)
|
||||
expect(element.childNodes.length).toBe 1
|
||||
expect(element.childNodes[0]).toHaveClass 'bottom'
|
||||
expect(element.childNodes[0]).toHaveClass 'tool-panel' # legacy selector support
|
||||
expect(element.childNodes[0]).toHaveClass 'panel-bottom' # legacy selector support
|
||||
expect(element.childNodes[0].tagName).toBe 'ATOM-PANEL'
|
||||
expect(atom.views.getView(panel1)).toHaveClass 'one'
|
||||
|
||||
panel2 = new Panel({item: new TestPanelContainerItem(), className: 'two'})
|
||||
container.addPanel(panel2)
|
||||
expect(element.childNodes.length).toBe 2
|
||||
expect(atom.views.getView(panel2)).toHaveClass 'two'
|
||||
|
||||
panel1.destroy()
|
||||
expect(element.childNodes.length).toBe 1
|
||||
|
||||
panel2.destroy()
|
||||
expect(element.childNodes.length).toBe 0
|
||||
|
||||
describe "when the container is modal", ->
|
||||
beforeEach ->
|
||||
container = new PanelContainer({location: 'modal'})
|
||||
element = atom.views.getView(container)
|
||||
jasmineContent.appendChild(element)
|
||||
|
||||
it "allows only one panel to be visible at a time", ->
|
||||
panel1 = new Panel({item: new TestPanelContainerItem()})
|
||||
container.addPanel(panel1)
|
||||
|
||||
expect(atom.views.getView(panel1).style.display).not.toBe 'none'
|
||||
|
||||
panel2 = new Panel({item: new TestPanelContainerItem()})
|
||||
container.addPanel(panel2)
|
||||
|
||||
expect(atom.views.getView(panel1).style.display).toBe 'none'
|
||||
expect(atom.views.getView(panel2).style.display).not.toBe 'none'
|
||||
|
||||
panel1.show()
|
||||
|
||||
expect(atom.views.getView(panel1).style.display).not.toBe 'none'
|
||||
expect(atom.views.getView(panel2).style.display).toBe 'none'
|
||||
|
||||
it "adds the 'modal' class to panels", ->
|
||||
panel1 = new Panel({item: new TestPanelContainerItem()})
|
||||
container.addPanel(panel1)
|
||||
|
||||
expect(atom.views.getView(panel1)).toHaveClass 'modal'
|
||||
|
||||
# legacy selector support
|
||||
expect(atom.views.getView(panel1)).not.toHaveClass 'tool-panel'
|
||||
expect(atom.views.getView(panel1)).toHaveClass 'overlay'
|
||||
expect(atom.views.getView(panel1)).toHaveClass 'from-top'
|
165
spec/panel-container-element-spec.js
Normal file
165
spec/panel-container-element-spec.js
Normal file
@ -0,0 +1,165 @@
|
||||
'use strict'
|
||||
|
||||
/* global HTMLElement */
|
||||
|
||||
const Panel = require('../src/panel')
|
||||
const PanelContainer = require('../src/panel-container')
|
||||
|
||||
describe('PanelContainerElement', () => {
|
||||
let jasmineContent, element, container
|
||||
|
||||
class TestPanelContainerItem {
|
||||
}
|
||||
|
||||
class TestPanelContainerItemElement_ extends HTMLElement {
|
||||
createdCallback () {
|
||||
this.classList.add('test-root')
|
||||
}
|
||||
initialize (model) {
|
||||
this.model = model
|
||||
return this
|
||||
}
|
||||
}
|
||||
|
||||
const TestPanelContainerItemElement = document.registerElement(
|
||||
'atom-test-container-item-element',
|
||||
{prototype: TestPanelContainerItemElement_.prototype}
|
||||
)
|
||||
|
||||
beforeEach(() => {
|
||||
jasmineContent = document.body.querySelector('#jasmine-content')
|
||||
|
||||
atom.views.addViewProvider(
|
||||
TestPanelContainerItem,
|
||||
model => new TestPanelContainerItemElement().initialize(model)
|
||||
)
|
||||
|
||||
container = new PanelContainer({location: 'left'})
|
||||
element = atom.views.getView(container)
|
||||
jasmineContent.appendChild(element)
|
||||
})
|
||||
|
||||
it('has a location class with value from the model', () => {
|
||||
expect(element).toHaveClass('left')
|
||||
})
|
||||
|
||||
it('removes the element when the container is destroyed', () => {
|
||||
expect(element.parentNode).toBe(jasmineContent)
|
||||
container.destroy()
|
||||
expect(element.parentNode).not.toBe(jasmineContent)
|
||||
})
|
||||
|
||||
describe('adding and removing panels', () => {
|
||||
it('allows panels to be inserted at any position', () => {
|
||||
const panel1 = new Panel({item: new TestPanelContainerItem(), priority: 10})
|
||||
const panel2 = new Panel({item: new TestPanelContainerItem(), priority: 5})
|
||||
const panel3 = new Panel({item: new TestPanelContainerItem(), priority: 8})
|
||||
|
||||
container.addPanel(panel1)
|
||||
container.addPanel(panel2)
|
||||
container.addPanel(panel3)
|
||||
|
||||
expect(element.childNodes[2].getModel()).toBe(panel1)
|
||||
expect(element.childNodes[1].getModel()).toBe(panel3)
|
||||
expect(element.childNodes[0].getModel()).toBe(panel2)
|
||||
})
|
||||
|
||||
describe('when the container is at the left location', () =>
|
||||
it('adds atom-panel elements when a new panel is added to the container; removes them when the panels are destroyed', () => {
|
||||
expect(element.childNodes.length).toBe(0)
|
||||
|
||||
const panel1 = new Panel({item: new TestPanelContainerItem()})
|
||||
container.addPanel(panel1)
|
||||
expect(element.childNodes.length).toBe(1)
|
||||
expect(element.childNodes[0]).toHaveClass('left')
|
||||
expect(element.childNodes[0]).toHaveClass('tool-panel') // legacy selector support
|
||||
expect(element.childNodes[0]).toHaveClass('panel-left') // legacy selector support
|
||||
|
||||
expect(element.childNodes[0].tagName).toBe('ATOM-PANEL')
|
||||
|
||||
const panel2 = new Panel({item: new TestPanelContainerItem()})
|
||||
container.addPanel(panel2)
|
||||
expect(element.childNodes.length).toBe(2)
|
||||
|
||||
expect(atom.views.getView(panel1).style.display).not.toBe('none')
|
||||
expect(atom.views.getView(panel2).style.display).not.toBe('none')
|
||||
|
||||
panel1.destroy()
|
||||
expect(element.childNodes.length).toBe(1)
|
||||
|
||||
panel2.destroy()
|
||||
expect(element.childNodes.length).toBe(0)
|
||||
})
|
||||
)
|
||||
|
||||
describe('when the container is at the bottom location', () => {
|
||||
beforeEach(() => {
|
||||
container = new PanelContainer({location: 'bottom'})
|
||||
element = atom.views.getView(container)
|
||||
jasmineContent.appendChild(element)
|
||||
})
|
||||
|
||||
it('adds atom-panel elements when a new panel is added to the container; removes them when the panels are destroyed', () => {
|
||||
expect(element.childNodes.length).toBe(0)
|
||||
|
||||
const panel1 = new Panel({item: new TestPanelContainerItem(), className: 'one'})
|
||||
container.addPanel(panel1)
|
||||
expect(element.childNodes.length).toBe(1)
|
||||
expect(element.childNodes[0]).toHaveClass('bottom')
|
||||
expect(element.childNodes[0]).toHaveClass('tool-panel') // legacy selector support
|
||||
expect(element.childNodes[0]).toHaveClass('panel-bottom') // legacy selector support
|
||||
expect(element.childNodes[0].tagName).toBe('ATOM-PANEL')
|
||||
expect(atom.views.getView(panel1)).toHaveClass('one')
|
||||
|
||||
const panel2 = new Panel({item: new TestPanelContainerItem(), className: 'two'})
|
||||
container.addPanel(panel2)
|
||||
expect(element.childNodes.length).toBe(2)
|
||||
expect(atom.views.getView(panel2)).toHaveClass('two')
|
||||
|
||||
panel1.destroy()
|
||||
expect(element.childNodes.length).toBe(1)
|
||||
|
||||
panel2.destroy()
|
||||
expect(element.childNodes.length).toBe(0)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('when the container is modal', () => {
|
||||
beforeEach(() => {
|
||||
container = new PanelContainer({location: 'modal'})
|
||||
element = atom.views.getView(container)
|
||||
jasmineContent.appendChild(element)
|
||||
})
|
||||
|
||||
it('allows only one panel to be visible at a time', () => {
|
||||
const panel1 = new Panel({item: new TestPanelContainerItem()})
|
||||
container.addPanel(panel1)
|
||||
|
||||
expect(atom.views.getView(panel1).style.display).not.toBe('none')
|
||||
|
||||
const panel2 = new Panel({item: new TestPanelContainerItem()})
|
||||
container.addPanel(panel2)
|
||||
|
||||
expect(atom.views.getView(panel1).style.display).toBe('none')
|
||||
expect(atom.views.getView(panel2).style.display).not.toBe('none')
|
||||
|
||||
panel1.show()
|
||||
|
||||
expect(atom.views.getView(panel1).style.display).not.toBe('none')
|
||||
expect(atom.views.getView(panel2).style.display).toBe('none')
|
||||
})
|
||||
|
||||
it("adds the 'modal' class to panels", () => {
|
||||
const panel1 = new Panel({item: new TestPanelContainerItem()})
|
||||
container.addPanel(panel1)
|
||||
|
||||
expect(atom.views.getView(panel1)).toHaveClass('modal')
|
||||
|
||||
// legacy selector support
|
||||
expect(atom.views.getView(panel1)).not.toHaveClass('tool-panel')
|
||||
expect(atom.views.getView(panel1)).toHaveClass('overlay')
|
||||
expect(atom.views.getView(panel1)).toHaveClass('from-top')
|
||||
})
|
||||
})
|
||||
})
|
@ -1,113 +0,0 @@
|
||||
Panel = require '../src/panel'
|
||||
PanelContainer = require '../src/panel-container'
|
||||
|
||||
describe "PanelContainer", ->
|
||||
[container] = []
|
||||
|
||||
class TestPanelItem
|
||||
constructor: ->
|
||||
|
||||
beforeEach ->
|
||||
container = new PanelContainer
|
||||
|
||||
describe "::addPanel(panel)", ->
|
||||
it 'emits an onDidAddPanel event with the index the panel was inserted at', ->
|
||||
container.onDidAddPanel addPanelSpy = jasmine.createSpy()
|
||||
|
||||
panel1 = new Panel(item: new TestPanelItem())
|
||||
container.addPanel(panel1)
|
||||
expect(addPanelSpy).toHaveBeenCalledWith({panel: panel1, index: 0})
|
||||
|
||||
panel2 = new Panel(item: new TestPanelItem())
|
||||
container.addPanel(panel2)
|
||||
expect(addPanelSpy).toHaveBeenCalledWith({panel: panel2, index: 1})
|
||||
|
||||
describe "when a panel is destroyed", ->
|
||||
it 'emits an onDidRemovePanel event with the index of the removed item', ->
|
||||
container.onDidRemovePanel removePanelSpy = jasmine.createSpy()
|
||||
|
||||
panel1 = new Panel(item: new TestPanelItem())
|
||||
container.addPanel(panel1)
|
||||
panel2 = new Panel(item: new TestPanelItem())
|
||||
container.addPanel(panel2)
|
||||
|
||||
expect(removePanelSpy).not.toHaveBeenCalled()
|
||||
|
||||
panel2.destroy()
|
||||
expect(removePanelSpy).toHaveBeenCalledWith({panel: panel2, index: 1})
|
||||
|
||||
panel1.destroy()
|
||||
expect(removePanelSpy).toHaveBeenCalledWith({panel: panel1, index: 0})
|
||||
|
||||
describe "::destroy()", ->
|
||||
it "destroys the container and all of its panels", ->
|
||||
destroyedPanels = []
|
||||
|
||||
panel1 = new Panel(item: new TestPanelItem())
|
||||
panel1.onDidDestroy -> destroyedPanels.push(panel1)
|
||||
container.addPanel(panel1)
|
||||
|
||||
panel2 = new Panel(item: new TestPanelItem())
|
||||
panel2.onDidDestroy -> destroyedPanels.push(panel2)
|
||||
container.addPanel(panel2)
|
||||
|
||||
container.destroy()
|
||||
|
||||
expect(container.getPanels().length).toBe(0)
|
||||
expect(destroyedPanels).toEqual([panel1, panel2])
|
||||
|
||||
describe "panel priority", ->
|
||||
describe 'left / top panel container', ->
|
||||
[initialPanel] = []
|
||||
beforeEach ->
|
||||
# 'left' logic is the same as 'top'
|
||||
container = new PanelContainer({location: 'left'})
|
||||
initialPanel = new Panel(item: new TestPanelItem())
|
||||
container.addPanel(initialPanel)
|
||||
|
||||
describe 'when a panel with low priority is added', ->
|
||||
it 'is inserted at the beginning of the list', ->
|
||||
container.onDidAddPanel addPanelSpy = jasmine.createSpy()
|
||||
panel = new Panel(item: new TestPanelItem(), priority: 0)
|
||||
container.addPanel(panel)
|
||||
|
||||
expect(addPanelSpy).toHaveBeenCalledWith({panel, index: 0})
|
||||
expect(container.getPanels()[0]).toBe panel
|
||||
|
||||
describe 'when a panel with priority between two other panels is added', ->
|
||||
it 'is inserted at the between the two panels', ->
|
||||
panel = new Panel(item: new TestPanelItem(), priority: 1000)
|
||||
container.addPanel(panel)
|
||||
|
||||
container.onDidAddPanel addPanelSpy = jasmine.createSpy()
|
||||
panel = new Panel(item: new TestPanelItem(), priority: 101)
|
||||
container.addPanel(panel)
|
||||
|
||||
expect(addPanelSpy).toHaveBeenCalledWith({panel, index: 1})
|
||||
expect(container.getPanels()[1]).toBe panel
|
||||
|
||||
describe 'right / bottom panel container', ->
|
||||
[initialPanel] = []
|
||||
beforeEach ->
|
||||
# 'bottom' logic is the same as 'right'
|
||||
container = new PanelContainer({location: 'right'})
|
||||
initialPanel = new Panel(item: new TestPanelItem())
|
||||
container.addPanel(initialPanel)
|
||||
|
||||
describe 'when a panel with high priority is added', ->
|
||||
it 'is inserted at the beginning of the list', ->
|
||||
container.onDidAddPanel addPanelSpy = jasmine.createSpy()
|
||||
panel = new Panel(item: new TestPanelItem(), priority: 1000)
|
||||
container.addPanel(panel)
|
||||
|
||||
expect(addPanelSpy).toHaveBeenCalledWith({panel, index: 0})
|
||||
expect(container.getPanels()[0]).toBe panel
|
||||
|
||||
describe 'when a panel with low priority is added', ->
|
||||
it 'is inserted at the end of the list', ->
|
||||
container.onDidAddPanel addPanelSpy = jasmine.createSpy()
|
||||
panel = new Panel(item: new TestPanelItem(), priority: 0)
|
||||
container.addPanel(panel)
|
||||
|
||||
expect(addPanelSpy).toHaveBeenCalledWith({panel, index: 1})
|
||||
expect(container.getPanels()[1]).toBe panel
|
142
spec/panel-container-spec.js
Normal file
142
spec/panel-container-spec.js
Normal file
@ -0,0 +1,142 @@
|
||||
'use strict'
|
||||
|
||||
const Panel = require('../src/panel')
|
||||
const PanelContainer = require('../src/panel-container')
|
||||
|
||||
describe('PanelContainer', () => {
|
||||
let container
|
||||
|
||||
class TestPanelItem {
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
container = new PanelContainer()
|
||||
})
|
||||
|
||||
describe('::addPanel(panel)', () => {
|
||||
it('emits an onDidAddPanel event with the index the panel was inserted at', () => {
|
||||
const addPanelSpy = jasmine.createSpy()
|
||||
container.onDidAddPanel(addPanelSpy)
|
||||
|
||||
const panel1 = new Panel({item: new TestPanelItem()})
|
||||
container.addPanel(panel1)
|
||||
expect(addPanelSpy).toHaveBeenCalledWith({panel: panel1, index: 0})
|
||||
|
||||
const panel2 = new Panel({item: new TestPanelItem()})
|
||||
container.addPanel(panel2)
|
||||
expect(addPanelSpy).toHaveBeenCalledWith({panel: panel2, index: 1})
|
||||
})
|
||||
})
|
||||
|
||||
describe('when a panel is destroyed', () => {
|
||||
it('emits an onDidRemovePanel event with the index of the removed item', () => {
|
||||
const removePanelSpy = jasmine.createSpy()
|
||||
container.onDidRemovePanel(removePanelSpy)
|
||||
|
||||
const panel1 = new Panel({item: new TestPanelItem()})
|
||||
container.addPanel(panel1)
|
||||
const panel2 = new Panel({item: new TestPanelItem()})
|
||||
container.addPanel(panel2)
|
||||
|
||||
expect(removePanelSpy).not.toHaveBeenCalled()
|
||||
|
||||
panel2.destroy()
|
||||
expect(removePanelSpy).toHaveBeenCalledWith({panel: panel2, index: 1})
|
||||
|
||||
panel1.destroy()
|
||||
expect(removePanelSpy).toHaveBeenCalledWith({panel: panel1, index: 0})
|
||||
})
|
||||
})
|
||||
|
||||
describe('::destroy()', () => {
|
||||
it('destroys the container and all of its panels', () => {
|
||||
const destroyedPanels = []
|
||||
|
||||
const panel1 = new Panel({item: new TestPanelItem()})
|
||||
panel1.onDidDestroy(() => { destroyedPanels.push(panel1) })
|
||||
container.addPanel(panel1)
|
||||
|
||||
const panel2 = new Panel({item: new TestPanelItem()})
|
||||
panel2.onDidDestroy(() => { destroyedPanels.push(panel2) })
|
||||
container.addPanel(panel2)
|
||||
|
||||
container.destroy()
|
||||
|
||||
expect(container.getPanels().length).toBe(0)
|
||||
expect(destroyedPanels).toEqual([panel1, panel2])
|
||||
})
|
||||
})
|
||||
|
||||
describe('panel priority', () => {
|
||||
describe('left / top panel container', () => {
|
||||
let initialPanel
|
||||
beforeEach(() => {
|
||||
// 'left' logic is the same as 'top'
|
||||
container = new PanelContainer({location: 'left'})
|
||||
initialPanel = new Panel({item: new TestPanelItem()})
|
||||
container.addPanel(initialPanel)
|
||||
})
|
||||
|
||||
describe('when a panel with low priority is added', () => {
|
||||
it('is inserted at the beginning of the list', () => {
|
||||
const addPanelSpy = jasmine.createSpy()
|
||||
container.onDidAddPanel(addPanelSpy)
|
||||
const panel = new Panel({item: new TestPanelItem(), priority: 0})
|
||||
container.addPanel(panel)
|
||||
|
||||
expect(addPanelSpy).toHaveBeenCalledWith({panel, index: 0})
|
||||
expect(container.getPanels()[0]).toBe(panel)
|
||||
})
|
||||
})
|
||||
|
||||
describe('when a panel with priority between two other panels is added', () => {
|
||||
it('is inserted at the between the two panels', () => {
|
||||
const addPanelSpy = jasmine.createSpy()
|
||||
let panel = new Panel({item: new TestPanelItem(), priority: 1000})
|
||||
container.addPanel(panel)
|
||||
|
||||
container.onDidAddPanel(addPanelSpy)
|
||||
panel = new Panel({item: new TestPanelItem(), priority: 101})
|
||||
container.addPanel(panel)
|
||||
|
||||
expect(addPanelSpy).toHaveBeenCalledWith({panel, index: 1})
|
||||
expect(container.getPanels()[1]).toBe(panel)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('right / bottom panel container', () => {
|
||||
let initialPanel
|
||||
beforeEach(() => {
|
||||
// 'bottom' logic is the same as 'right'
|
||||
container = new PanelContainer({location: 'right'})
|
||||
initialPanel = new Panel({item: new TestPanelItem()})
|
||||
container.addPanel(initialPanel)
|
||||
})
|
||||
|
||||
describe('when a panel with high priority is added', () => {
|
||||
it('is inserted at the beginning of the list', () => {
|
||||
const addPanelSpy = jasmine.createSpy()
|
||||
container.onDidAddPanel(addPanelSpy)
|
||||
const panel = new Panel({item: new TestPanelItem(), priority: 1000})
|
||||
container.addPanel(panel)
|
||||
|
||||
expect(addPanelSpy).toHaveBeenCalledWith({panel, index: 0})
|
||||
expect(container.getPanels()[0]).toBe(panel)
|
||||
})
|
||||
})
|
||||
|
||||
describe('when a panel with low priority is added', () => {
|
||||
it('is inserted at the end of the list', () => {
|
||||
const addPanelSpy = jasmine.createSpy()
|
||||
container.onDidAddPanel(addPanelSpy)
|
||||
const panel = new Panel({item: new TestPanelItem(), priority: 0})
|
||||
container.addPanel(panel)
|
||||
|
||||
expect(addPanelSpy).toHaveBeenCalledWith({panel, index: 1})
|
||||
expect(container.getPanels()[1]).toBe(panel)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
@ -1,208 +0,0 @@
|
||||
{ipcRenderer} = require 'electron'
|
||||
path = require 'path'
|
||||
temp = require('temp').track()
|
||||
{Disposable} = require 'event-kit'
|
||||
|
||||
describe "WorkspaceElement", ->
|
||||
afterEach ->
|
||||
temp.cleanupSync()
|
||||
|
||||
describe "when the workspace element is focused", ->
|
||||
it "transfers focus to the active pane", ->
|
||||
workspaceElement = atom.views.getView(atom.workspace)
|
||||
jasmine.attachToDOM(workspaceElement)
|
||||
activePaneElement = atom.views.getView(atom.workspace.getActivePane())
|
||||
document.body.focus()
|
||||
expect(document.activeElement).not.toBe(activePaneElement)
|
||||
workspaceElement.focus()
|
||||
expect(document.activeElement).toBe(activePaneElement)
|
||||
|
||||
describe "the scrollbar visibility class", ->
|
||||
it "has a class based on the style of the scrollbar", ->
|
||||
observeCallback = null
|
||||
scrollbarStyle = require 'scrollbar-style'
|
||||
spyOn(scrollbarStyle, 'observePreferredScrollbarStyle').andCallFake (cb) ->
|
||||
observeCallback = cb
|
||||
new Disposable(->)
|
||||
|
||||
workspaceElement = atom.views.getView(atom.workspace)
|
||||
observeCallback('legacy')
|
||||
expect(workspaceElement.className).toMatch 'scrollbars-visible-always'
|
||||
|
||||
observeCallback('overlay')
|
||||
expect(workspaceElement).toHaveClass 'scrollbars-visible-when-scrolling'
|
||||
|
||||
describe "editor font styling", ->
|
||||
[editor, editorElement, workspaceElement] = []
|
||||
|
||||
beforeEach ->
|
||||
waitsForPromise -> atom.workspace.open('sample.js')
|
||||
|
||||
runs ->
|
||||
workspaceElement = atom.views.getView(atom.workspace)
|
||||
jasmine.attachToDOM(workspaceElement)
|
||||
editor = atom.workspace.getActiveTextEditor()
|
||||
editorElement = atom.views.getView(editor)
|
||||
|
||||
it "updates the font-size based on the 'editor.fontSize' config value", ->
|
||||
initialCharWidth = editor.getDefaultCharWidth()
|
||||
expect(getComputedStyle(editorElement).fontSize).toBe atom.config.get('editor.fontSize') + 'px'
|
||||
atom.config.set('editor.fontSize', atom.config.get('editor.fontSize') + 5)
|
||||
expect(getComputedStyle(editorElement).fontSize).toBe atom.config.get('editor.fontSize') + 'px'
|
||||
expect(editor.getDefaultCharWidth()).toBeGreaterThan initialCharWidth
|
||||
|
||||
it "updates the font-family based on the 'editor.fontFamily' config value", ->
|
||||
initialCharWidth = editor.getDefaultCharWidth()
|
||||
fontFamily = atom.config.get('editor.fontFamily')
|
||||
expect(getComputedStyle(editorElement).fontFamily).toBe fontFamily
|
||||
|
||||
atom.config.set('editor.fontFamily', 'sans-serif')
|
||||
fontFamily = atom.config.get('editor.fontFamily')
|
||||
expect(getComputedStyle(editorElement).fontFamily).toBe fontFamily
|
||||
expect(editor.getDefaultCharWidth()).not.toBe initialCharWidth
|
||||
|
||||
it "updates the line-height based on the 'editor.lineHeight' config value", ->
|
||||
initialLineHeight = editor.getLineHeightInPixels()
|
||||
atom.config.set('editor.lineHeight', '30px')
|
||||
expect(getComputedStyle(editorElement).lineHeight).toBe atom.config.get('editor.lineHeight')
|
||||
expect(editor.getLineHeightInPixels()).not.toBe initialLineHeight
|
||||
|
||||
it "increases or decreases the font size when a ctrl-mousewheel event occurs", ->
|
||||
atom.config.set('editor.zoomFontWhenCtrlScrolling', true)
|
||||
atom.config.set('editor.fontSize', 12)
|
||||
|
||||
# Zoom out
|
||||
editorElement.querySelector('span').dispatchEvent(new WheelEvent('mousewheel', {
|
||||
wheelDeltaY: -10,
|
||||
ctrlKey: true
|
||||
}))
|
||||
expect(atom.config.get('editor.fontSize')).toBe(11)
|
||||
|
||||
# Zoom in
|
||||
editorElement.querySelector('span').dispatchEvent(new WheelEvent('mousewheel', {
|
||||
wheelDeltaY: 10,
|
||||
ctrlKey: true
|
||||
}))
|
||||
expect(atom.config.get('editor.fontSize')).toBe(12)
|
||||
|
||||
# Not on an atom-text-editor
|
||||
workspaceElement.dispatchEvent(new WheelEvent('mousewheel', {
|
||||
wheelDeltaY: 10,
|
||||
ctrlKey: true
|
||||
}))
|
||||
expect(atom.config.get('editor.fontSize')).toBe(12)
|
||||
|
||||
# No ctrl key
|
||||
editorElement.querySelector('span').dispatchEvent(new WheelEvent('mousewheel', {
|
||||
wheelDeltaY: 10,
|
||||
}))
|
||||
expect(atom.config.get('editor.fontSize')).toBe(12)
|
||||
|
||||
atom.config.set('editor.zoomFontWhenCtrlScrolling', false)
|
||||
editorElement.querySelector('span').dispatchEvent(new WheelEvent('mousewheel', {
|
||||
wheelDeltaY: 10,
|
||||
ctrlKey: true
|
||||
}))
|
||||
expect(atom.config.get('editor.fontSize')).toBe(12)
|
||||
|
||||
describe 'panel containers', ->
|
||||
it 'inserts panel container elements in the correct places in the DOM', ->
|
||||
workspaceElement = atom.views.getView(atom.workspace)
|
||||
|
||||
leftContainer = workspaceElement.querySelector('atom-panel-container.left')
|
||||
rightContainer = workspaceElement.querySelector('atom-panel-container.right')
|
||||
expect(leftContainer.nextSibling).toBe workspaceElement.verticalAxis
|
||||
expect(rightContainer.previousSibling).toBe workspaceElement.verticalAxis
|
||||
|
||||
topContainer = workspaceElement.querySelector('atom-panel-container.top')
|
||||
bottomContainer = workspaceElement.querySelector('atom-panel-container.bottom')
|
||||
expect(topContainer.nextSibling).toBe workspaceElement.paneContainer
|
||||
expect(bottomContainer.previousSibling).toBe workspaceElement.paneContainer
|
||||
|
||||
headerContainer = workspaceElement.querySelector('atom-panel-container.header')
|
||||
footerContainer = workspaceElement.querySelector('atom-panel-container.footer')
|
||||
expect(headerContainer.nextSibling).toBe workspaceElement.horizontalAxis
|
||||
expect(footerContainer.previousSibling).toBe workspaceElement.horizontalAxis
|
||||
|
||||
modalContainer = workspaceElement.querySelector('atom-panel-container.modal')
|
||||
expect(modalContainer.parentNode).toBe workspaceElement
|
||||
|
||||
it 'stretches header/footer panels to the workspace width', ->
|
||||
workspaceElement = atom.views.getView(atom.workspace)
|
||||
jasmine.attachToDOM(workspaceElement)
|
||||
expect(workspaceElement.offsetWidth).toBeGreaterThan(0)
|
||||
|
||||
headerItem = document.createElement('div')
|
||||
atom.workspace.addHeaderPanel({item: headerItem})
|
||||
expect(headerItem.offsetWidth).toEqual(workspaceElement.offsetWidth)
|
||||
|
||||
footerItem = document.createElement('div')
|
||||
atom.workspace.addFooterPanel({item: footerItem})
|
||||
expect(footerItem.offsetWidth).toEqual(workspaceElement.offsetWidth)
|
||||
|
||||
it 'shrinks horizontal axis according to header/footer panels height', ->
|
||||
workspaceElement = atom.views.getView(atom.workspace)
|
||||
workspaceElement.style.height = '100px'
|
||||
horizontalAxisElement = workspaceElement.querySelector('atom-workspace-axis.horizontal')
|
||||
jasmine.attachToDOM(workspaceElement)
|
||||
|
||||
originalHorizontalAxisHeight = horizontalAxisElement.offsetHeight
|
||||
expect(workspaceElement.offsetHeight).toBeGreaterThan(0)
|
||||
expect(originalHorizontalAxisHeight).toBeGreaterThan(0)
|
||||
|
||||
headerItem = document.createElement('div')
|
||||
headerItem.style.height = '10px'
|
||||
atom.workspace.addHeaderPanel({item: headerItem})
|
||||
expect(headerItem.offsetHeight).toBeGreaterThan(0)
|
||||
|
||||
footerItem = document.createElement('div')
|
||||
footerItem.style.height = '15px'
|
||||
atom.workspace.addFooterPanel({item: footerItem})
|
||||
expect(footerItem.offsetHeight).toBeGreaterThan(0)
|
||||
|
||||
expect(horizontalAxisElement.offsetHeight).toEqual(originalHorizontalAxisHeight - headerItem.offsetHeight - footerItem.offsetHeight)
|
||||
|
||||
describe "the 'window:toggle-invisibles' command", ->
|
||||
it "shows/hides invisibles in all open and future editors", ->
|
||||
workspaceElement = atom.views.getView(atom.workspace)
|
||||
expect(atom.config.get('editor.showInvisibles')).toBe false
|
||||
atom.commands.dispatch(workspaceElement, 'window:toggle-invisibles')
|
||||
expect(atom.config.get('editor.showInvisibles')).toBe true
|
||||
atom.commands.dispatch(workspaceElement, 'window:toggle-invisibles')
|
||||
expect(atom.config.get('editor.showInvisibles')).toBe false
|
||||
|
||||
describe "the 'window:run-package-specs' command", ->
|
||||
it "runs the package specs for the active item's project path, or the first project path", ->
|
||||
workspaceElement = atom.views.getView(atom.workspace)
|
||||
spyOn(ipcRenderer, 'send')
|
||||
|
||||
# No project paths. Don't try to run specs.
|
||||
atom.commands.dispatch(workspaceElement, "window:run-package-specs")
|
||||
expect(ipcRenderer.send).not.toHaveBeenCalledWith("run-package-specs")
|
||||
|
||||
projectPaths = [temp.mkdirSync("dir1-"), temp.mkdirSync("dir2-")]
|
||||
atom.project.setPaths(projectPaths)
|
||||
|
||||
# No active item. Use first project directory.
|
||||
atom.commands.dispatch(workspaceElement, "window:run-package-specs")
|
||||
expect(ipcRenderer.send).toHaveBeenCalledWith("run-package-specs", path.join(projectPaths[0], "spec"))
|
||||
ipcRenderer.send.reset()
|
||||
|
||||
# Active item doesn't implement ::getPath(). Use first project directory.
|
||||
item = document.createElement("div")
|
||||
atom.workspace.getActivePane().activateItem(item)
|
||||
atom.commands.dispatch(workspaceElement, "window:run-package-specs")
|
||||
expect(ipcRenderer.send).toHaveBeenCalledWith("run-package-specs", path.join(projectPaths[0], "spec"))
|
||||
ipcRenderer.send.reset()
|
||||
|
||||
# Active item has no path. Use first project directory.
|
||||
item.getPath = -> null
|
||||
atom.commands.dispatch(workspaceElement, "window:run-package-specs")
|
||||
expect(ipcRenderer.send).toHaveBeenCalledWith("run-package-specs", path.join(projectPaths[0], "spec"))
|
||||
ipcRenderer.send.reset()
|
||||
|
||||
# Active item has path. Use project path for item path.
|
||||
item.getPath = -> path.join(projectPaths[1], "a-file.txt")
|
||||
atom.commands.dispatch(workspaceElement, "window:run-package-specs")
|
||||
expect(ipcRenderer.send).toHaveBeenCalledWith("run-package-specs", path.join(projectPaths[1], "spec"))
|
||||
ipcRenderer.send.reset()
|
232
spec/workspace-element-spec.js
Normal file
232
spec/workspace-element-spec.js
Normal file
@ -0,0 +1,232 @@
|
||||
'use strict'
|
||||
|
||||
/* global getComputedStyle, WheelEvent */
|
||||
|
||||
const {ipcRenderer} = require('electron')
|
||||
const path = require('path')
|
||||
const temp = require('temp').track()
|
||||
const {Disposable} = require('event-kit')
|
||||
|
||||
describe('WorkspaceElement', () => {
|
||||
afterEach(() => { temp.cleanupSync() })
|
||||
|
||||
describe('when the workspace element is focused', () => {
|
||||
it('transfers focus to the active pane', () => {
|
||||
const workspaceElement = atom.views.getView(atom.workspace)
|
||||
jasmine.attachToDOM(workspaceElement)
|
||||
const activePaneElement = atom.views.getView(atom.workspace.getActivePane())
|
||||
document.body.focus()
|
||||
expect(document.activeElement).not.toBe(activePaneElement)
|
||||
workspaceElement.focus()
|
||||
expect(document.activeElement).toBe(activePaneElement)
|
||||
})
|
||||
})
|
||||
|
||||
describe('the scrollbar visibility class', () => {
|
||||
it('has a class based on the style of the scrollbar', () => {
|
||||
let observeCallback
|
||||
const scrollbarStyle = require('scrollbar-style')
|
||||
spyOn(scrollbarStyle, 'observePreferredScrollbarStyle').andCallFake(cb => {
|
||||
observeCallback = cb
|
||||
return new Disposable(() => {})
|
||||
})
|
||||
|
||||
const workspaceElement = atom.views.getView(atom.workspace)
|
||||
observeCallback('legacy')
|
||||
expect(workspaceElement.className).toMatch('scrollbars-visible-always')
|
||||
|
||||
observeCallback('overlay')
|
||||
expect(workspaceElement).toHaveClass('scrollbars-visible-when-scrolling')
|
||||
})
|
||||
})
|
||||
|
||||
describe('editor font styling', () => {
|
||||
let editor, editorElement, workspaceElement
|
||||
|
||||
beforeEach(() => {
|
||||
waitsForPromise(() => atom.workspace.open('sample.js'))
|
||||
|
||||
runs(() => {
|
||||
workspaceElement = atom.views.getView(atom.workspace)
|
||||
jasmine.attachToDOM(workspaceElement)
|
||||
editor = atom.workspace.getActiveTextEditor()
|
||||
editorElement = atom.views.getView(editor)
|
||||
})
|
||||
})
|
||||
|
||||
it("updates the font-size based on the 'editor.fontSize' config value", () => {
|
||||
const initialCharWidth = editor.getDefaultCharWidth()
|
||||
expect(getComputedStyle(editorElement).fontSize).toBe(atom.config.get('editor.fontSize') + 'px')
|
||||
atom.config.set('editor.fontSize', atom.config.get('editor.fontSize') + 5)
|
||||
expect(getComputedStyle(editorElement).fontSize).toBe(atom.config.get('editor.fontSize') + 'px')
|
||||
expect(editor.getDefaultCharWidth()).toBeGreaterThan(initialCharWidth)
|
||||
})
|
||||
|
||||
it("updates the font-family based on the 'editor.fontFamily' config value", () => {
|
||||
const initialCharWidth = editor.getDefaultCharWidth()
|
||||
let fontFamily = atom.config.get('editor.fontFamily')
|
||||
expect(getComputedStyle(editorElement).fontFamily).toBe(fontFamily)
|
||||
|
||||
atom.config.set('editor.fontFamily', 'sans-serif')
|
||||
fontFamily = atom.config.get('editor.fontFamily')
|
||||
expect(getComputedStyle(editorElement).fontFamily).toBe(fontFamily)
|
||||
expect(editor.getDefaultCharWidth()).not.toBe(initialCharWidth)
|
||||
})
|
||||
|
||||
it("updates the line-height based on the 'editor.lineHeight' config value", () => {
|
||||
const initialLineHeight = editor.getLineHeightInPixels()
|
||||
atom.config.set('editor.lineHeight', '30px')
|
||||
expect(getComputedStyle(editorElement).lineHeight).toBe(atom.config.get('editor.lineHeight'))
|
||||
expect(editor.getLineHeightInPixels()).not.toBe(initialLineHeight)
|
||||
})
|
||||
|
||||
it('increases or decreases the font size when a ctrl-mousewheel event occurs', () => {
|
||||
atom.config.set('editor.zoomFontWhenCtrlScrolling', true)
|
||||
atom.config.set('editor.fontSize', 12)
|
||||
|
||||
// Zoom out
|
||||
editorElement.querySelector('span').dispatchEvent(new WheelEvent('mousewheel', {
|
||||
wheelDeltaY: -10,
|
||||
ctrlKey: true
|
||||
}))
|
||||
expect(atom.config.get('editor.fontSize')).toBe(11)
|
||||
|
||||
// Zoom in
|
||||
editorElement.querySelector('span').dispatchEvent(new WheelEvent('mousewheel', {
|
||||
wheelDeltaY: 10,
|
||||
ctrlKey: true
|
||||
}))
|
||||
expect(atom.config.get('editor.fontSize')).toBe(12)
|
||||
|
||||
// Not on an atom-text-editor
|
||||
workspaceElement.dispatchEvent(new WheelEvent('mousewheel', {
|
||||
wheelDeltaY: 10,
|
||||
ctrlKey: true
|
||||
}))
|
||||
expect(atom.config.get('editor.fontSize')).toBe(12)
|
||||
|
||||
// No ctrl key
|
||||
editorElement.querySelector('span').dispatchEvent(new WheelEvent('mousewheel', {
|
||||
wheelDeltaY: 10
|
||||
}))
|
||||
expect(atom.config.get('editor.fontSize')).toBe(12)
|
||||
|
||||
atom.config.set('editor.zoomFontWhenCtrlScrolling', false)
|
||||
editorElement.querySelector('span').dispatchEvent(new WheelEvent('mousewheel', {
|
||||
wheelDeltaY: 10,
|
||||
ctrlKey: true
|
||||
}))
|
||||
expect(atom.config.get('editor.fontSize')).toBe(12)
|
||||
})
|
||||
})
|
||||
|
||||
describe('panel containers', () => {
|
||||
it('inserts panel container elements in the correct places in the DOM', () => {
|
||||
const workspaceElement = atom.views.getView(atom.workspace)
|
||||
|
||||
const leftContainer = workspaceElement.querySelector('atom-panel-container.left')
|
||||
const rightContainer = workspaceElement.querySelector('atom-panel-container.right')
|
||||
expect(leftContainer.nextSibling).toBe(workspaceElement.verticalAxis)
|
||||
expect(rightContainer.previousSibling).toBe(workspaceElement.verticalAxis)
|
||||
|
||||
const topContainer = workspaceElement.querySelector('atom-panel-container.top')
|
||||
const bottomContainer = workspaceElement.querySelector('atom-panel-container.bottom')
|
||||
expect(topContainer.nextSibling).toBe(workspaceElement.paneContainer)
|
||||
expect(bottomContainer.previousSibling).toBe(workspaceElement.paneContainer)
|
||||
|
||||
const headerContainer = workspaceElement.querySelector('atom-panel-container.header')
|
||||
const footerContainer = workspaceElement.querySelector('atom-panel-container.footer')
|
||||
expect(headerContainer.nextSibling).toBe(workspaceElement.horizontalAxis)
|
||||
expect(footerContainer.previousSibling).toBe(workspaceElement.horizontalAxis)
|
||||
|
||||
const modalContainer = workspaceElement.querySelector('atom-panel-container.modal')
|
||||
expect(modalContainer.parentNode).toBe(workspaceElement)
|
||||
})
|
||||
|
||||
it('stretches header/footer panels to the workspace width', () => {
|
||||
const workspaceElement = atom.views.getView(atom.workspace)
|
||||
jasmine.attachToDOM(workspaceElement)
|
||||
expect(workspaceElement.offsetWidth).toBeGreaterThan(0)
|
||||
|
||||
const headerItem = document.createElement('div')
|
||||
atom.workspace.addHeaderPanel({item: headerItem})
|
||||
expect(headerItem.offsetWidth).toEqual(workspaceElement.offsetWidth)
|
||||
|
||||
const footerItem = document.createElement('div')
|
||||
atom.workspace.addFooterPanel({item: footerItem})
|
||||
expect(footerItem.offsetWidth).toEqual(workspaceElement.offsetWidth)
|
||||
})
|
||||
|
||||
it('shrinks horizontal axis according to header/footer panels height', () => {
|
||||
const workspaceElement = atom.views.getView(atom.workspace)
|
||||
workspaceElement.style.height = '100px'
|
||||
const horizontalAxisElement = workspaceElement.querySelector('atom-workspace-axis.horizontal')
|
||||
jasmine.attachToDOM(workspaceElement)
|
||||
|
||||
const originalHorizontalAxisHeight = horizontalAxisElement.offsetHeight
|
||||
expect(workspaceElement.offsetHeight).toBeGreaterThan(0)
|
||||
expect(originalHorizontalAxisHeight).toBeGreaterThan(0)
|
||||
|
||||
const headerItem = document.createElement('div')
|
||||
headerItem.style.height = '10px'
|
||||
atom.workspace.addHeaderPanel({item: headerItem})
|
||||
expect(headerItem.offsetHeight).toBeGreaterThan(0)
|
||||
|
||||
const footerItem = document.createElement('div')
|
||||
footerItem.style.height = '15px'
|
||||
atom.workspace.addFooterPanel({item: footerItem})
|
||||
expect(footerItem.offsetHeight).toBeGreaterThan(0)
|
||||
|
||||
expect(horizontalAxisElement.offsetHeight).toEqual(originalHorizontalAxisHeight - headerItem.offsetHeight - footerItem.offsetHeight)
|
||||
})
|
||||
})
|
||||
|
||||
describe("the 'window:toggle-invisibles' command", () => {
|
||||
it('shows/hides invisibles in all open and future editors', () => {
|
||||
const workspaceElement = atom.views.getView(atom.workspace)
|
||||
expect(atom.config.get('editor.showInvisibles')).toBe(false)
|
||||
atom.commands.dispatch(workspaceElement, 'window:toggle-invisibles')
|
||||
expect(atom.config.get('editor.showInvisibles')).toBe(true)
|
||||
atom.commands.dispatch(workspaceElement, 'window:toggle-invisibles')
|
||||
expect(atom.config.get('editor.showInvisibles')).toBe(false)
|
||||
})
|
||||
})
|
||||
|
||||
describe("the 'window:run-package-specs' command", () => {
|
||||
it("runs the package specs for the active item's project path, or the first project path", () => {
|
||||
const workspaceElement = atom.views.getView(atom.workspace)
|
||||
spyOn(ipcRenderer, 'send')
|
||||
|
||||
// No project paths. Don't try to run specs.
|
||||
atom.commands.dispatch(workspaceElement, 'window:run-package-specs')
|
||||
expect(ipcRenderer.send).not.toHaveBeenCalledWith('run-package-specs')
|
||||
|
||||
const projectPaths = [temp.mkdirSync('dir1-'), temp.mkdirSync('dir2-')]
|
||||
atom.project.setPaths(projectPaths)
|
||||
|
||||
// No active item. Use first project directory.
|
||||
atom.commands.dispatch(workspaceElement, 'window:run-package-specs')
|
||||
expect(ipcRenderer.send).toHaveBeenCalledWith('run-package-specs', path.join(projectPaths[0], 'spec'))
|
||||
ipcRenderer.send.reset()
|
||||
|
||||
// Active item doesn't implement ::getPath(). Use first project directory.
|
||||
const item = document.createElement('div')
|
||||
atom.workspace.getActivePane().activateItem(item)
|
||||
atom.commands.dispatch(workspaceElement, 'window:run-package-specs')
|
||||
expect(ipcRenderer.send).toHaveBeenCalledWith('run-package-specs', path.join(projectPaths[0], 'spec'))
|
||||
ipcRenderer.send.reset()
|
||||
|
||||
// Active item has no path. Use first project directory.
|
||||
item.getPath = () => null
|
||||
atom.commands.dispatch(workspaceElement, 'window:run-package-specs')
|
||||
expect(ipcRenderer.send).toHaveBeenCalledWith('run-package-specs', path.join(projectPaths[0], 'spec'))
|
||||
ipcRenderer.send.reset()
|
||||
|
||||
// Active item has path. Use project path for item path.
|
||||
item.getPath = () => path.join(projectPaths[1], 'a-file.txt')
|
||||
atom.commands.dispatch(workspaceElement, 'window:run-package-specs')
|
||||
expect(ipcRenderer.send).toHaveBeenCalledWith('run-package-specs', path.join(projectPaths[1], 'spec'))
|
||||
ipcRenderer.send.reset()
|
||||
})
|
||||
})
|
||||
})
|
@ -237,7 +237,7 @@ class AtomEnvironment extends Model
|
||||
@applicationDelegate.didChangeHistoryManager() unless e.reloaded
|
||||
@disposables.add @applicationDelegate.onDidChangeHistoryManager(=> @history.loadState())
|
||||
|
||||
new ReopenProjectMenuManager({@menu, @commands, @history, @config, open: (paths) => @open(pathsToOpen: paths)})
|
||||
(new ReopenProjectMenuManager({@menu, @commands, @history, @config, open: (paths) => @open(pathsToOpen: paths)})).update()
|
||||
|
||||
attachSaveStateListeners: ->
|
||||
saveState = _.debounce((=>
|
||||
|
@ -73,6 +73,11 @@ class AtomApplication
|
||||
@config.load()
|
||||
@fileRecoveryService = new FileRecoveryService(path.join(process.env.ATOM_HOME, "recovery"))
|
||||
@storageFolder = new StorageFolder(process.env.ATOM_HOME)
|
||||
@autoUpdateManager = new AutoUpdateManager(
|
||||
@version,
|
||||
options.test or options.benchmark or options.benchmarkTest,
|
||||
@config
|
||||
)
|
||||
|
||||
@disposable = new CompositeDisposable
|
||||
@handleEvents()
|
||||
@ -92,9 +97,7 @@ class AtomApplication
|
||||
|
||||
@config.onDidChange 'core.titleBar', @promptForRestart.bind(this)
|
||||
|
||||
@autoUpdateManager = new AutoUpdateManager(
|
||||
@version, options.test or options.benchmark or options.benchmarkTest, @resourcePath, @config
|
||||
)
|
||||
process.nextTick => @autoUpdateManager.initialize()
|
||||
@applicationMenu = new ApplicationMenu(@version, @autoUpdateManager)
|
||||
@atomProtocolHandler = new AtomProtocolHandler(@resourcePath, @safeMode)
|
||||
|
||||
|
@ -14,12 +14,11 @@ module.exports =
|
||||
class AutoUpdateManager
|
||||
Object.assign @prototype, EventEmitter.prototype
|
||||
|
||||
constructor: (@version, @testMode, resourcePath, @config) ->
|
||||
constructor: (@version, @testMode, @config) ->
|
||||
@state = IdleState
|
||||
@iconPath = path.resolve(__dirname, '..', '..', 'resources', 'atom.png')
|
||||
process.nextTick => @setupAutoUpdater()
|
||||
|
||||
setupAutoUpdater: ->
|
||||
initialize: ->
|
||||
if process.platform is 'win32'
|
||||
archSuffix = if process.arch is 'ia32' then '' else '-' + process.arch
|
||||
@feedUrl = "https://atom.io/api/updates#{archSuffix}?version=#{@version}"
|
||||
|
@ -1,45 +0,0 @@
|
||||
{CompositeDisposable} = require 'event-kit'
|
||||
|
||||
class PanelContainerElement extends HTMLElement
|
||||
createdCallback: ->
|
||||
@subscriptions = new CompositeDisposable
|
||||
|
||||
initialize: (@model, {@views}) ->
|
||||
throw new Error("Must pass a views parameter when initializing PanelContainerElements") unless @views?
|
||||
|
||||
@subscriptions.add @model.onDidAddPanel(@panelAdded.bind(this))
|
||||
@subscriptions.add @model.onDidDestroy(@destroyed.bind(this))
|
||||
@classList.add(@model.getLocation())
|
||||
this
|
||||
|
||||
getModel: -> @model
|
||||
|
||||
panelAdded: ({panel, index}) ->
|
||||
panelElement = @views.getView(panel)
|
||||
panelElement.classList.add(@model.getLocation())
|
||||
if @model.isModal()
|
||||
panelElement.classList.add("overlay", "from-top")
|
||||
else
|
||||
panelElement.classList.add("tool-panel", "panel-#{@model.getLocation()}")
|
||||
|
||||
if index >= @childNodes.length
|
||||
@appendChild(panelElement)
|
||||
else
|
||||
referenceItem = @childNodes[index]
|
||||
@insertBefore(panelElement, referenceItem)
|
||||
|
||||
if @model.isModal()
|
||||
@hideAllPanelsExcept(panel)
|
||||
@subscriptions.add panel.onDidChangeVisible (visible) =>
|
||||
@hideAllPanelsExcept(panel) if visible
|
||||
|
||||
destroyed: ->
|
||||
@subscriptions.dispose()
|
||||
@parentNode?.removeChild(this)
|
||||
|
||||
hideAllPanelsExcept: (excludedPanel) ->
|
||||
for panel in @model.getPanels()
|
||||
panel.hide() unless panel is excludedPanel
|
||||
return
|
||||
|
||||
module.exports = PanelContainerElement = document.registerElement 'atom-panel-container', prototype: PanelContainerElement.prototype
|
65
src/panel-container-element.js
Normal file
65
src/panel-container-element.js
Normal file
@ -0,0 +1,65 @@
|
||||
'use strict'
|
||||
|
||||
/* global HTMLElement */
|
||||
|
||||
const {CompositeDisposable} = require('event-kit')
|
||||
|
||||
class PanelContainerElement extends HTMLElement {
|
||||
createdCallback () {
|
||||
this.subscriptions = new CompositeDisposable()
|
||||
}
|
||||
|
||||
initialize (model, {views}) {
|
||||
this.model = model
|
||||
this.views = views
|
||||
if (this.views == null) {
|
||||
throw new Error('Must pass a views parameter when initializing PanelContainerElements')
|
||||
}
|
||||
|
||||
this.subscriptions.add(this.model.onDidAddPanel(this.panelAdded.bind(this)))
|
||||
this.subscriptions.add(this.model.onDidDestroy(this.destroyed.bind(this)))
|
||||
this.classList.add(this.model.getLocation())
|
||||
return this
|
||||
}
|
||||
|
||||
getModel () { return this.model }
|
||||
|
||||
panelAdded ({panel, index}) {
|
||||
const panelElement = this.views.getView(panel)
|
||||
panelElement.classList.add(this.model.getLocation())
|
||||
if (this.model.isModal()) {
|
||||
panelElement.classList.add('overlay', 'from-top')
|
||||
} else {
|
||||
panelElement.classList.add('tool-panel', `panel-${this.model.getLocation()}`)
|
||||
}
|
||||
|
||||
if (index >= this.childNodes.length) {
|
||||
this.appendChild(panelElement)
|
||||
} else {
|
||||
const referenceItem = this.childNodes[index]
|
||||
this.insertBefore(panelElement, referenceItem)
|
||||
}
|
||||
|
||||
if (this.model.isModal()) {
|
||||
this.hideAllPanelsExcept(panel)
|
||||
this.subscriptions.add(panel.onDidChangeVisible(visible => {
|
||||
if (visible) { this.hideAllPanelsExcept(panel) }
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
destroyed () {
|
||||
this.subscriptions.dispose()
|
||||
if (this.parentNode != null) {
|
||||
this.parentNode.removeChild(this)
|
||||
}
|
||||
}
|
||||
|
||||
hideAllPanelsExcept (excludedPanel) {
|
||||
for (let panel of this.model.getPanels()) {
|
||||
if (panel !== excludedPanel) { panel.hide() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = document.registerElement('atom-panel-container', {prototype: PanelContainerElement.prototype})
|
@ -1,71 +0,0 @@
|
||||
{Emitter, CompositeDisposable} = require 'event-kit'
|
||||
|
||||
module.exports =
|
||||
class PanelContainer
|
||||
constructor: ({@location}={}) ->
|
||||
@emitter = new Emitter
|
||||
@subscriptions = new CompositeDisposable
|
||||
@panels = []
|
||||
|
||||
destroy: ->
|
||||
panel.destroy() for panel in @getPanels()
|
||||
@subscriptions.dispose()
|
||||
@emitter.emit 'did-destroy', this
|
||||
@emitter.dispose()
|
||||
|
||||
###
|
||||
Section: Event Subscription
|
||||
###
|
||||
|
||||
onDidAddPanel: (callback) ->
|
||||
@emitter.on 'did-add-panel', callback
|
||||
|
||||
onDidRemovePanel: (callback) ->
|
||||
@emitter.on 'did-remove-panel', callback
|
||||
|
||||
onDidDestroy: (callback) ->
|
||||
@emitter.on 'did-destroy', callback
|
||||
|
||||
###
|
||||
Section: Panels
|
||||
###
|
||||
|
||||
getLocation: -> @location
|
||||
|
||||
isModal: -> @location is 'modal'
|
||||
|
||||
getPanels: -> @panels.slice()
|
||||
|
||||
addPanel: (panel) ->
|
||||
@subscriptions.add panel.onDidDestroy(@panelDestroyed.bind(this))
|
||||
|
||||
index = @getPanelIndex(panel)
|
||||
if index is @panels.length
|
||||
@panels.push(panel)
|
||||
else
|
||||
@panels.splice(index, 0, panel)
|
||||
|
||||
@emitter.emit 'did-add-panel', {panel, index}
|
||||
panel
|
||||
|
||||
panelForItem: (item) ->
|
||||
for panel in @panels
|
||||
return panel if panel.getItem() is item
|
||||
null
|
||||
|
||||
panelDestroyed: (panel) ->
|
||||
index = @panels.indexOf(panel)
|
||||
if index > -1
|
||||
@panels.splice(index, 1)
|
||||
@emitter.emit 'did-remove-panel', {panel, index}
|
||||
|
||||
getPanelIndex: (panel) ->
|
||||
priority = panel.getPriority()
|
||||
if @location in ['bottom', 'right']
|
||||
for p, i in @panels by -1
|
||||
return i + 1 if priority < p.getPriority()
|
||||
0
|
||||
else
|
||||
for p, i in @panels
|
||||
return i if priority < p.getPriority()
|
||||
@panels.length
|
91
src/panel-container.js
Normal file
91
src/panel-container.js
Normal file
@ -0,0 +1,91 @@
|
||||
'use strict'
|
||||
|
||||
const {Emitter, CompositeDisposable} = require('event-kit')
|
||||
|
||||
module.exports = class PanelContainer {
|
||||
constructor ({location} = {}) {
|
||||
this.location = location
|
||||
this.emitter = new Emitter()
|
||||
this.subscriptions = new CompositeDisposable()
|
||||
this.panels = []
|
||||
}
|
||||
|
||||
destroy () {
|
||||
for (let panel of this.getPanels()) { panel.destroy() }
|
||||
this.subscriptions.dispose()
|
||||
this.emitter.emit('did-destroy', this)
|
||||
this.emitter.dispose()
|
||||
}
|
||||
|
||||
/*
|
||||
Section: Event Subscription
|
||||
*/
|
||||
|
||||
onDidAddPanel (callback) {
|
||||
return this.emitter.on('did-add-panel', callback)
|
||||
}
|
||||
|
||||
onDidRemovePanel (callback) {
|
||||
return this.emitter.on('did-remove-panel', callback)
|
||||
}
|
||||
|
||||
onDidDestroy (callback) {
|
||||
return this.emitter.on('did-destroy', callback)
|
||||
}
|
||||
|
||||
/*
|
||||
Section: Panels
|
||||
*/
|
||||
|
||||
getLocation () { return this.location }
|
||||
|
||||
isModal () { return this.location === 'modal' }
|
||||
|
||||
getPanels () { return this.panels.slice() }
|
||||
|
||||
addPanel (panel) {
|
||||
this.subscriptions.add(panel.onDidDestroy(this.panelDestroyed.bind(this)))
|
||||
|
||||
const index = this.getPanelIndex(panel)
|
||||
if (index === this.panels.length) {
|
||||
this.panels.push(panel)
|
||||
} else {
|
||||
this.panels.splice(index, 0, panel)
|
||||
}
|
||||
|
||||
this.emitter.emit('did-add-panel', {panel, index})
|
||||
return panel
|
||||
}
|
||||
|
||||
panelForItem (item) {
|
||||
for (let panel of this.panels) {
|
||||
if (panel.getItem() === item) { return panel }
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
panelDestroyed (panel) {
|
||||
const index = this.panels.indexOf(panel)
|
||||
if (index > -1) {
|
||||
this.panels.splice(index, 1)
|
||||
this.emitter.emit('did-remove-panel', {panel, index})
|
||||
}
|
||||
}
|
||||
|
||||
getPanelIndex (panel) {
|
||||
const priority = panel.getPriority()
|
||||
if (['bottom', 'right'].includes(this.location)) {
|
||||
for (let i = this.panels.length - 1; i >= 0; i--) {
|
||||
const p = this.panels[i]
|
||||
if (priority < p.getPriority()) { return i + 1 }
|
||||
}
|
||||
return 0
|
||||
} else {
|
||||
for (let i = 0; i < this.panels.length; i++) {
|
||||
const p = this.panels[i]
|
||||
if (priority < p.getPriority()) { return i }
|
||||
}
|
||||
return this.panels.length
|
||||
}
|
||||
}
|
||||
}
|
@ -1,149 +0,0 @@
|
||||
{ipcRenderer} = require 'electron'
|
||||
path = require 'path'
|
||||
fs = require 'fs-plus'
|
||||
{CompositeDisposable} = require 'event-kit'
|
||||
scrollbarStyle = require 'scrollbar-style'
|
||||
|
||||
module.exports =
|
||||
class WorkspaceElement extends HTMLElement
|
||||
globalTextEditorStyleSheet: null
|
||||
|
||||
attachedCallback: ->
|
||||
@focus()
|
||||
|
||||
detachedCallback: ->
|
||||
@subscriptions.dispose()
|
||||
|
||||
initializeContent: ->
|
||||
@classList.add 'workspace'
|
||||
@setAttribute 'tabindex', -1
|
||||
|
||||
@verticalAxis = document.createElement('atom-workspace-axis')
|
||||
@verticalAxis.classList.add('vertical')
|
||||
|
||||
@horizontalAxis = document.createElement('atom-workspace-axis')
|
||||
@horizontalAxis.classList.add('horizontal')
|
||||
@horizontalAxis.appendChild(@verticalAxis)
|
||||
|
||||
@appendChild(@horizontalAxis)
|
||||
|
||||
observeScrollbarStyle: ->
|
||||
@subscriptions.add scrollbarStyle.observePreferredScrollbarStyle (style) =>
|
||||
switch style
|
||||
when 'legacy'
|
||||
@classList.remove('scrollbars-visible-when-scrolling')
|
||||
@classList.add("scrollbars-visible-always")
|
||||
when 'overlay'
|
||||
@classList.remove('scrollbars-visible-always')
|
||||
@classList.add("scrollbars-visible-when-scrolling")
|
||||
|
||||
observeTextEditorFontConfig: ->
|
||||
@updateGlobalTextEditorStyleSheet()
|
||||
@subscriptions.add @config.onDidChange 'editor.fontSize', @updateGlobalTextEditorStyleSheet.bind(this)
|
||||
@subscriptions.add @config.onDidChange 'editor.fontFamily', @updateGlobalTextEditorStyleSheet.bind(this)
|
||||
@subscriptions.add @config.onDidChange 'editor.lineHeight', @updateGlobalTextEditorStyleSheet.bind(this)
|
||||
|
||||
updateGlobalTextEditorStyleSheet: ->
|
||||
styleSheetSource = """
|
||||
atom-text-editor {
|
||||
font-size: #{@config.get('editor.fontSize')}px;
|
||||
font-family: #{@config.get('editor.fontFamily')};
|
||||
line-height: #{@config.get('editor.lineHeight')};
|
||||
}
|
||||
"""
|
||||
@styles.addStyleSheet(styleSheetSource, sourcePath: 'global-text-editor-styles')
|
||||
@views.performDocumentPoll()
|
||||
|
||||
initialize: (@model, {@views, @workspace, @project, @config, @styles}) ->
|
||||
throw new Error("Must pass a views parameter when initializing WorskpaceElements") unless @views?
|
||||
throw new Error("Must pass a workspace parameter when initializing WorskpaceElements") unless @workspace?
|
||||
throw new Error("Must pass a project parameter when initializing WorskpaceElements") unless @project?
|
||||
throw new Error("Must pass a config parameter when initializing WorskpaceElements") unless @config?
|
||||
throw new Error("Must pass a styles parameter when initializing WorskpaceElements") unless @styles?
|
||||
|
||||
@subscriptions = new CompositeDisposable
|
||||
@initializeContent()
|
||||
@observeScrollbarStyle()
|
||||
@observeTextEditorFontConfig()
|
||||
|
||||
@paneContainer = @views.getView(@model.paneContainer)
|
||||
@verticalAxis.appendChild(@paneContainer)
|
||||
@addEventListener 'focus', @handleFocus.bind(this)
|
||||
|
||||
@addEventListener 'mousewheel', @handleMousewheel.bind(this), true
|
||||
|
||||
@panelContainers =
|
||||
top: @views.getView(@model.panelContainers.top)
|
||||
left: @views.getView(@model.panelContainers.left)
|
||||
right: @views.getView(@model.panelContainers.right)
|
||||
bottom: @views.getView(@model.panelContainers.bottom)
|
||||
header: @views.getView(@model.panelContainers.header)
|
||||
footer: @views.getView(@model.panelContainers.footer)
|
||||
modal: @views.getView(@model.panelContainers.modal)
|
||||
|
||||
@horizontalAxis.insertBefore(@panelContainers.left, @verticalAxis)
|
||||
@horizontalAxis.appendChild(@panelContainers.right)
|
||||
|
||||
@verticalAxis.insertBefore(@panelContainers.top, @paneContainer)
|
||||
@verticalAxis.appendChild(@panelContainers.bottom)
|
||||
|
||||
@insertBefore(@panelContainers.header, @horizontalAxis)
|
||||
@appendChild(@panelContainers.footer)
|
||||
|
||||
@appendChild(@panelContainers.modal)
|
||||
|
||||
this
|
||||
|
||||
getModel: -> @model
|
||||
|
||||
handleMousewheel: (event) ->
|
||||
if event.ctrlKey and @config.get('editor.zoomFontWhenCtrlScrolling') and event.target.closest('atom-text-editor')?
|
||||
if event.wheelDeltaY > 0
|
||||
@model.increaseFontSize()
|
||||
else if event.wheelDeltaY < 0
|
||||
@model.decreaseFontSize()
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
|
||||
handleFocus: (event) ->
|
||||
@model.getActivePane().activate()
|
||||
|
||||
focusPaneViewAbove: -> @paneContainer.focusPaneViewAbove()
|
||||
|
||||
focusPaneViewBelow: -> @paneContainer.focusPaneViewBelow()
|
||||
|
||||
focusPaneViewOnLeft: -> @paneContainer.focusPaneViewOnLeft()
|
||||
|
||||
focusPaneViewOnRight: -> @paneContainer.focusPaneViewOnRight()
|
||||
|
||||
moveActiveItemToPaneAbove: (params) -> @paneContainer.moveActiveItemToPaneAbove(params)
|
||||
|
||||
moveActiveItemToPaneBelow: (params) -> @paneContainer.moveActiveItemToPaneBelow(params)
|
||||
|
||||
moveActiveItemToPaneOnLeft: (params) -> @paneContainer.moveActiveItemToPaneOnLeft(params)
|
||||
|
||||
moveActiveItemToPaneOnRight: (params) -> @paneContainer.moveActiveItemToPaneOnRight(params)
|
||||
|
||||
runPackageSpecs: ->
|
||||
if activePath = @workspace.getActivePaneItem()?.getPath?()
|
||||
[projectPath] = @project.relativizePath(activePath)
|
||||
else
|
||||
[projectPath] = @project.getPaths()
|
||||
if projectPath
|
||||
specPath = path.join(projectPath, 'spec')
|
||||
testPath = path.join(projectPath, 'test')
|
||||
if not fs.existsSync(specPath) and fs.existsSync(testPath)
|
||||
specPath = testPath
|
||||
|
||||
ipcRenderer.send('run-package-specs', specPath)
|
||||
|
||||
runBenchmarks: ->
|
||||
if activePath = @workspace.getActivePaneItem()?.getPath?()
|
||||
[projectPath] = @project.relativizePath(activePath)
|
||||
else
|
||||
[projectPath] = @project.getPaths()
|
||||
|
||||
if projectPath
|
||||
ipcRenderer.send('run-benchmarks', path.join(projectPath, 'benchmarks'))
|
||||
|
||||
module.exports = WorkspaceElement = document.registerElement 'atom-workspace', prototype: WorkspaceElement.prototype
|
184
src/workspace-element.js
Normal file
184
src/workspace-element.js
Normal file
@ -0,0 +1,184 @@
|
||||
'use strict'
|
||||
|
||||
/* global HTMLElement */
|
||||
|
||||
const {ipcRenderer} = require('electron')
|
||||
const path = require('path')
|
||||
const fs = require('fs-plus')
|
||||
const {CompositeDisposable} = require('event-kit')
|
||||
const scrollbarStyle = require('scrollbar-style')
|
||||
|
||||
class WorkspaceElement extends HTMLElement {
|
||||
attachedCallback () {
|
||||
this.focus()
|
||||
}
|
||||
|
||||
detachedCallback () {
|
||||
this.subscriptions.dispose()
|
||||
}
|
||||
|
||||
initializeContent () {
|
||||
this.classList.add('workspace')
|
||||
this.setAttribute('tabindex', -1)
|
||||
|
||||
this.verticalAxis = document.createElement('atom-workspace-axis')
|
||||
this.verticalAxis.classList.add('vertical')
|
||||
|
||||
this.horizontalAxis = document.createElement('atom-workspace-axis')
|
||||
this.horizontalAxis.classList.add('horizontal')
|
||||
this.horizontalAxis.appendChild(this.verticalAxis)
|
||||
|
||||
this.appendChild(this.horizontalAxis)
|
||||
}
|
||||
|
||||
observeScrollbarStyle () {
|
||||
this.subscriptions.add(scrollbarStyle.observePreferredScrollbarStyle(style => {
|
||||
switch (style) {
|
||||
case 'legacy':
|
||||
this.classList.remove('scrollbars-visible-when-scrolling')
|
||||
this.classList.add('scrollbars-visible-always')
|
||||
break
|
||||
case 'overlay':
|
||||
this.classList.remove('scrollbars-visible-always')
|
||||
this.classList.add('scrollbars-visible-when-scrolling')
|
||||
break
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
observeTextEditorFontConfig () {
|
||||
this.updateGlobalTextEditorStyleSheet()
|
||||
this.subscriptions.add(this.config.onDidChange('editor.fontSize', this.updateGlobalTextEditorStyleSheet.bind(this)))
|
||||
this.subscriptions.add(this.config.onDidChange('editor.fontFamily', this.updateGlobalTextEditorStyleSheet.bind(this)))
|
||||
this.subscriptions.add(this.config.onDidChange('editor.lineHeight', this.updateGlobalTextEditorStyleSheet.bind(this)))
|
||||
}
|
||||
|
||||
updateGlobalTextEditorStyleSheet () {
|
||||
const styleSheetSource = `atom-text-editor {
|
||||
font-size: ${this.config.get('editor.fontSize')}px;
|
||||
font-family: ${this.config.get('editor.fontFamily')};
|
||||
line-height: ${this.config.get('editor.lineHeight')};
|
||||
}`
|
||||
this.styles.addStyleSheet(styleSheetSource, {sourcePath: 'global-text-editor-styles'})
|
||||
this.views.performDocumentPoll()
|
||||
}
|
||||
|
||||
initialize (model, {views, workspace, project, config, styles}) {
|
||||
this.model = model
|
||||
this.views = views
|
||||
this.workspace = workspace
|
||||
this.project = project
|
||||
this.config = config
|
||||
this.styles = styles
|
||||
if (this.views == null) { throw new Error('Must pass a views parameter when initializing WorskpaceElements') }
|
||||
if (this.workspace == null) { throw new Error('Must pass a workspace parameter when initializing WorskpaceElements') }
|
||||
if (this.project == null) { throw new Error('Must pass a project parameter when initializing WorskpaceElements') }
|
||||
if (this.config == null) { throw new Error('Must pass a config parameter when initializing WorskpaceElements') }
|
||||
if (this.styles == null) { throw new Error('Must pass a styles parameter when initializing WorskpaceElements') }
|
||||
|
||||
this.subscriptions = new CompositeDisposable()
|
||||
this.initializeContent()
|
||||
this.observeScrollbarStyle()
|
||||
this.observeTextEditorFontConfig()
|
||||
|
||||
this.paneContainer = this.views.getView(this.model.paneContainer)
|
||||
this.verticalAxis.appendChild(this.paneContainer)
|
||||
this.addEventListener('focus', this.handleFocus.bind(this))
|
||||
|
||||
this.addEventListener('mousewheel', this.handleMousewheel.bind(this), true)
|
||||
|
||||
this.panelContainers = {
|
||||
top: this.views.getView(this.model.panelContainers.top),
|
||||
left: this.views.getView(this.model.panelContainers.left),
|
||||
right: this.views.getView(this.model.panelContainers.right),
|
||||
bottom: this.views.getView(this.model.panelContainers.bottom),
|
||||
header: this.views.getView(this.model.panelContainers.header),
|
||||
footer: this.views.getView(this.model.panelContainers.footer),
|
||||
modal: this.views.getView(this.model.panelContainers.modal)
|
||||
}
|
||||
|
||||
this.horizontalAxis.insertBefore(this.panelContainers.left, this.verticalAxis)
|
||||
this.horizontalAxis.appendChild(this.panelContainers.right)
|
||||
|
||||
this.verticalAxis.insertBefore(this.panelContainers.top, this.paneContainer)
|
||||
this.verticalAxis.appendChild(this.panelContainers.bottom)
|
||||
|
||||
this.insertBefore(this.panelContainers.header, this.horizontalAxis)
|
||||
this.appendChild(this.panelContainers.footer)
|
||||
|
||||
this.appendChild(this.panelContainers.modal)
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
getModel () { return this.model }
|
||||
|
||||
handleMousewheel (event) {
|
||||
if (event.ctrlKey && this.config.get('editor.zoomFontWhenCtrlScrolling') && (event.target.closest('atom-text-editor') != null)) {
|
||||
if (event.wheelDeltaY > 0) {
|
||||
this.model.increaseFontSize()
|
||||
} else if (event.wheelDeltaY < 0) {
|
||||
this.model.decreaseFontSize()
|
||||
}
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
}
|
||||
}
|
||||
|
||||
handleFocus (event) {
|
||||
this.model.getActivePane().activate()
|
||||
}
|
||||
|
||||
focusPaneViewAbove () { this.paneContainer.focusPaneViewAbove() }
|
||||
|
||||
focusPaneViewBelow () { this.paneContainer.focusPaneViewBelow() }
|
||||
|
||||
focusPaneViewOnLeft () { this.paneContainer.focusPaneViewOnLeft() }
|
||||
|
||||
focusPaneViewOnRight () { this.paneContainer.focusPaneViewOnRight() }
|
||||
|
||||
moveActiveItemToPaneAbove (params) { this.paneContainer.moveActiveItemToPaneAbove(params) }
|
||||
|
||||
moveActiveItemToPaneBelow (params) { this.paneContainer.moveActiveItemToPaneBelow(params) }
|
||||
|
||||
moveActiveItemToPaneOnLeft (params) { this.paneContainer.moveActiveItemToPaneOnLeft(params) }
|
||||
|
||||
moveActiveItemToPaneOnRight (params) { this.paneContainer.moveActiveItemToPaneOnRight(params) }
|
||||
|
||||
runPackageSpecs () {
|
||||
const activePaneItem = this.workspace.getActivePaneItem()
|
||||
const activePath = activePaneItem && typeof activePaneItem.getPath === 'function' ? activePaneItem.getPath() : null
|
||||
let projectPath
|
||||
if (activePath != null) {
|
||||
[projectPath] = this.project.relativizePath(activePath)
|
||||
} else {
|
||||
[projectPath] = this.project.getPaths()
|
||||
}
|
||||
if (projectPath) {
|
||||
let specPath = path.join(projectPath, 'spec')
|
||||
const testPath = path.join(projectPath, 'test')
|
||||
if (!fs.existsSync(specPath) && fs.existsSync(testPath)) {
|
||||
specPath = testPath
|
||||
}
|
||||
|
||||
ipcRenderer.send('run-package-specs', specPath)
|
||||
}
|
||||
}
|
||||
|
||||
runBenchmarks () {
|
||||
const activePaneItem = this.workspace.getActivePaneItem()
|
||||
const activePath = activePaneItem && typeof activePaneItem.getPath === 'function' ? activePaneItem.getPath() : null
|
||||
let projectPath
|
||||
if (activePath) {
|
||||
[projectPath] = this.project.relativizePath(activePath)
|
||||
} else {
|
||||
[projectPath] = this.project.getPaths()
|
||||
}
|
||||
|
||||
if (projectPath) {
|
||||
ipcRenderer.send('run-benchmarks', path.join(projectPath, 'benchmarks'))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = document.registerElement('atom-workspace', {prototype: WorkspaceElement.prototype})
|
Loading…
Reference in New Issue
Block a user