mirror of
https://github.com/atom/atom.git
synced 2026-04-28 03:01:47 -04:00
Merge branch 'as-snapshot-atom-environment' into as-ns-optimize-stylesheets-loading
# Conflicts: # script/package.json # script/tdd # src/atom-environment.coffee # src/context-menu-manager.coffee # src/keymap-extensions.coffee # src/theme-manager.coffee # src/workspace-element.coffee
This commit is contained in:
@@ -277,3 +277,14 @@ class ApplicationDelegate
|
||||
|
||||
emitDidSavePath: (path) ->
|
||||
ipcRenderer.sendSync('did-save-path', path)
|
||||
|
||||
resolveProxy: (requestId, url) ->
|
||||
ipcRenderer.send('resolve-proxy', requestId, url)
|
||||
|
||||
onDidResolveProxy: (callback) ->
|
||||
outerCallback = (event, requestId, proxy) ->
|
||||
callback(requestId, proxy)
|
||||
|
||||
ipcRenderer.on('did-resolve-proxy', outerCallback)
|
||||
new Disposable ->
|
||||
ipcRenderer.removeListener('did-resolve-proxy', outerCallback)
|
||||
|
||||
@@ -134,6 +134,7 @@ class AtomEnvironment extends Model
|
||||
constructor: (params={}) ->
|
||||
{@applicationDelegate, @clipboard, @enablePersistence, onlyLoadBaseStyleSheets} = params
|
||||
|
||||
@nextProxyRequestId = 0
|
||||
@unloaded = false
|
||||
@loadTime = null
|
||||
@emitter = new Emitter
|
||||
@@ -186,7 +187,9 @@ class AtomEnvironment extends Model
|
||||
|
||||
@autoUpdater = new AutoUpdateManager({@applicationDelegate})
|
||||
|
||||
@keymaps.loadBundledKeymaps()
|
||||
if @keymaps.canLoadBundledKeymapsFromMemory()
|
||||
@keymaps.loadBundledKeymaps()
|
||||
|
||||
@registerDefaultCommands()
|
||||
@registerDefaultOpeners()
|
||||
@registerDefaultDeserializers()
|
||||
@@ -216,8 +219,14 @@ class AtomEnvironment extends Model
|
||||
}
|
||||
@config.initialize({@configDirPath, resourcePath, projectHomeSchema: ConfigSchema.projectHome})
|
||||
|
||||
@menu.initialize({resourcePath})
|
||||
@contextMenu.initialize({resourcePath, devMode})
|
||||
|
||||
@keymaps.configDirPath = @configDirPath
|
||||
@keymaps.resourcePath = resourcePath
|
||||
@keymaps.devMode = devMode
|
||||
unless @keymaps.canLoadBundledKeymapsFromMemory()
|
||||
@keymaps.loadBundledKeymaps()
|
||||
|
||||
@commands.attach(@window)
|
||||
|
||||
@@ -225,8 +234,6 @@ class AtomEnvironment extends Model
|
||||
@packages.initialize({devMode, @configDirPath, resourcePath, safeMode})
|
||||
@themes.initialize({@configDirPath, resourcePath, safeMode})
|
||||
|
||||
@menu.initialize({resourcePath})
|
||||
@contextMenu.initialize({resourcePath, devMode})
|
||||
@commandInstaller.initialize(@getVersion())
|
||||
@workspace.initialize()
|
||||
@autoUpdater.initialize()
|
||||
@@ -248,6 +255,7 @@ class AtomEnvironment extends Model
|
||||
|
||||
@observeAutoHideMenuBar()
|
||||
|
||||
@history.initialize(@window.localStorage)
|
||||
@disposables.add @applicationDelegate.onDidChangeHistoryManager(=> @history.loadState())
|
||||
|
||||
attachSaveStateListeners: ->
|
||||
@@ -783,8 +791,13 @@ class AtomEnvironment extends Model
|
||||
uninstallUncaughtErrorHandler: ->
|
||||
@window.onerror = @previousWindowErrorHandler
|
||||
|
||||
installWindowEventHandler: ->
|
||||
@windowEventHandler = new WindowEventHandler({atomEnvironment: this, @applicationDelegate})
|
||||
@windowEventHandler.initialize(@window, @document)
|
||||
|
||||
uninstallWindowEventHandler: ->
|
||||
@windowEventHandler?.unsubscribe()
|
||||
@windowEventHandler = null
|
||||
|
||||
###
|
||||
Section: Messaging the User
|
||||
@@ -1001,6 +1014,16 @@ class AtomEnvironment extends Model
|
||||
|
||||
return
|
||||
|
||||
resolveProxy: (url) ->
|
||||
return new Promise (resolve, reject) =>
|
||||
requestId = @nextProxyRequestId++
|
||||
disposable = @applicationDelegate.onDidResolveProxy (id, proxy) ->
|
||||
if id is requestId
|
||||
disposable.dispose()
|
||||
resolve(proxy)
|
||||
|
||||
@applicationDelegate.resolveProxy(requestId, url)
|
||||
|
||||
# Preserve this deprecation until 2.0. Sorry. Should have removed Q sooner.
|
||||
Promise.prototype.done = (callback) ->
|
||||
deprecate("Atom now uses ES6 Promises instead of Q. Call promise.then instead of promise.done")
|
||||
|
||||
@@ -50,7 +50,7 @@ class ContextMenuManager
|
||||
|
||||
loadPlatformItems: ->
|
||||
if platformContextMenu?
|
||||
@add(platformContextMenu, false)
|
||||
@add(platformContextMenu, @devMode ? false)
|
||||
else
|
||||
menusDirPath = path.join(@resourcePath, 'menus')
|
||||
platformMenuPath = fs.resolve(menusDirPath, process.platform, ['cson', 'json'])
|
||||
|
||||
@@ -17,6 +17,10 @@ export class HistoryManager {
|
||||
this.disposables.add(project.onDidChangePaths((projectPaths) => this.addProject(projectPaths)))
|
||||
}
|
||||
|
||||
initialize (localStorage) {
|
||||
this.localStorage = localStorage
|
||||
}
|
||||
|
||||
destroy () {
|
||||
this.disposables.dispose()
|
||||
}
|
||||
@@ -93,7 +97,11 @@ export class HistoryManager {
|
||||
}
|
||||
|
||||
async loadState () {
|
||||
const history = await this.stateStore.load('history-manager')
|
||||
let history = await this.stateStore.load('history-manager')
|
||||
if (!history) {
|
||||
history = JSON.parse(this.localStorage.getItem('history'))
|
||||
}
|
||||
|
||||
if (history && history.projects) {
|
||||
this.projects = history.projects.filter(p => Array.isArray(p.paths) && p.paths.length > 0).map(p => new HistoryProject(p.paths, new Date(p.lastOpened)))
|
||||
this.didChangeProjects({reloaded: true})
|
||||
@@ -106,12 +114,6 @@ export class HistoryManager {
|
||||
const projects = this.projects.map(p => ({paths: p.paths, lastOpened: p.lastOpened}))
|
||||
await this.stateStore.save('history-manager', {projects})
|
||||
}
|
||||
|
||||
async importProjectHistory () {
|
||||
for (let project of await HistoryImporter.getAllProjects()) {
|
||||
await this.addProject(project.paths, project.lastOpened)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function arrayEquivalent (a, b) {
|
||||
@@ -134,32 +136,3 @@ export class HistoryProject {
|
||||
set lastOpened (lastOpened) { this._lastOpened = lastOpened }
|
||||
get lastOpened () { return this._lastOpened }
|
||||
}
|
||||
|
||||
class HistoryImporter {
|
||||
static async getStateStoreCursor () {
|
||||
const db = await atom.stateStore.dbPromise
|
||||
const store = db.transaction(['states']).objectStore('states')
|
||||
return store.openCursor()
|
||||
}
|
||||
|
||||
static async getAllProjects (stateStore) {
|
||||
const request = await HistoryImporter.getStateStoreCursor()
|
||||
return new Promise((resolve, reject) => {
|
||||
const rows = []
|
||||
request.onerror = reject
|
||||
request.onsuccess = event => {
|
||||
const cursor = event.target.result
|
||||
if (cursor) {
|
||||
let project = cursor.value.value.project
|
||||
let storedAt = cursor.value.storedAt
|
||||
if (project && project.paths && storedAt) {
|
||||
rows.push(new HistoryProject(project.paths, new Date(Date.parse(storedAt))))
|
||||
}
|
||||
cursor.continue()
|
||||
} else {
|
||||
resolve(rows)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,14 +56,16 @@ export default async function () {
|
||||
TextEditor.setClipboard(clipboard)
|
||||
|
||||
const applicationDelegate = new ApplicationDelegate()
|
||||
global.atom = new AtomEnvironment({
|
||||
const environmentParams = {
|
||||
applicationDelegate,
|
||||
window,
|
||||
document,
|
||||
clipboard,
|
||||
configDirPath: process.env.ATOM_HOME,
|
||||
enablePersistence: false
|
||||
})
|
||||
}
|
||||
global.atom = new AtomEnvironment(environmentParams)
|
||||
global.atom.initialize(environmentParams)
|
||||
|
||||
// Prevent benchmarks from modifying application menus
|
||||
global.atom.menu.sendToBrowserProcess = function () { }
|
||||
|
||||
@@ -79,7 +79,9 @@ module.exports = ({blobStore}) ->
|
||||
params.clipboard = clipboard unless params.hasOwnProperty("clipboard")
|
||||
params.blobStore = blobStore unless params.hasOwnProperty("blobStore")
|
||||
params.onlyLoadBaseStyleSheets = true unless params.hasOwnProperty("onlyLoadBaseStyleSheets")
|
||||
new AtomEnvironment(params)
|
||||
atomEnvironment = new AtomEnvironment(params)
|
||||
atomEnvironment.initialize(params)
|
||||
atomEnvironment
|
||||
|
||||
promise = testRunner({
|
||||
logFile, headless, testPaths, buildAtomEnvironment, buildDefaultApplicationDelegate, legacyTestRunner
|
||||
|
||||
@@ -11,11 +11,14 @@ KeymapManager::onDidLoadBundledKeymaps = (callback) ->
|
||||
KeymapManager::onDidLoadUserKeymap = (callback) ->
|
||||
@emitter.on 'did-load-user-keymap', callback
|
||||
|
||||
KeymapManager::canLoadBundledKeymapsFromMemory = ->
|
||||
bundledKeymaps?
|
||||
|
||||
KeymapManager::loadBundledKeymaps = ->
|
||||
if bundledKeymaps?
|
||||
for keymapName, keymap of bundledKeymaps
|
||||
keymapPath = "<embedded>/#{keymapName}"
|
||||
@add(keymapPath, keymap, 0, false)
|
||||
@add(keymapPath, keymap, 0, @devMode ? false)
|
||||
else
|
||||
keymapsPath = path.join(@resourcePath, 'keymaps')
|
||||
@loadKeymap(keymapsPath)
|
||||
|
||||
@@ -80,6 +80,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()
|
||||
@@ -99,9 +104,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)
|
||||
|
||||
@@ -287,6 +290,9 @@ class AtomApplication
|
||||
@disposable.add ipcHelpers.on ipcMain, 'restart-application', =>
|
||||
@restart()
|
||||
|
||||
@disposable.add ipcHelpers.on ipcMain, 'resolve-proxy', (event, requestId, url) ->
|
||||
event.sender.session.resolveProxy url, (proxy) -> event.sender.send('did-resolve-proxy', requestId, proxy)
|
||||
|
||||
@disposable.add ipcHelpers.on ipcMain, 'did-change-history-manager', (event) =>
|
||||
for atomWindow in @windows
|
||||
webContents = atomWindow.browserWindow.webContents
|
||||
|
||||
@@ -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,5 +1,5 @@
|
||||
if (typeof snapshotResult !== 'undefined') {
|
||||
snapshotResult.setGlobals(global, process, global, {}, require)
|
||||
snapshotResult.setGlobals(global, process, global, {}, require) // eslint-disable-line no-undef
|
||||
}
|
||||
|
||||
const startTime = Date.now()
|
||||
|
||||
@@ -36,7 +36,6 @@ class NativeCompileCache {
|
||||
|
||||
overrideModuleCompile () {
|
||||
let self = this
|
||||
let resolvedArgv = null
|
||||
// Here we override Node's module.js
|
||||
// (https://github.com/atom/node/blob/atom/lib/module.js#L378), changing
|
||||
// only the bits that affect compilation in order to use the cached one.
|
||||
|
||||
@@ -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', priority: -1})
|
||||
@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', priority: -1})
|
||||
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})
|
||||
@@ -58,12 +58,6 @@ module.exports = class Workspace extends Model {
|
||||
this.defaultDirectorySearcher = new DefaultDirectorySearcher()
|
||||
this.consumeServices(this.packageManager)
|
||||
|
||||
// One cannot simply .bind here since it could be used as a component with
|
||||
// Etch, in which case it'd be `new`d. And when it's `new`d, `this` is always
|
||||
// the newly created object.
|
||||
const realThis = this
|
||||
this.buildTextEditor = (params) => Workspace.prototype.buildTextEditor.call(realThis, params)
|
||||
|
||||
this.panelContainers = {
|
||||
top: new PanelContainer({location: 'top'}),
|
||||
left: new PanelContainer({location: 'left'}),
|
||||
|
||||
Reference in New Issue
Block a user