mirror of
https://github.com/pulsar-edit/pulsar.git
synced 2024-09-21 07:58:04 +03:00
commit
46762327c6
@ -1,4 +1,5 @@
|
|||||||
require '../src/atom'
|
Atom = require '../src/atom'
|
||||||
|
window.atom = new Atom()
|
||||||
{runSpecSuite} = require '../spec/jasmine-helper'
|
{runSpecSuite} = require '../spec/jasmine-helper'
|
||||||
|
|
||||||
atom.openDevTools()
|
atom.openDevTools()
|
||||||
|
@ -6,29 +6,6 @@ describe "the `atom` global", ->
|
|||||||
beforeEach ->
|
beforeEach ->
|
||||||
window.rootView = new RootView
|
window.rootView = new RootView
|
||||||
|
|
||||||
describe "base stylesheet loading", ->
|
|
||||||
beforeEach ->
|
|
||||||
rootView.append $$ -> @div class: 'editor'
|
|
||||||
rootView.attachToDom()
|
|
||||||
atom.themes.load()
|
|
||||||
atom.watchThemes()
|
|
||||||
|
|
||||||
afterEach ->
|
|
||||||
atom.themes.unload()
|
|
||||||
config.set('core.themes', [])
|
|
||||||
atom.reloadBaseStylesheets()
|
|
||||||
|
|
||||||
it "loads the correct values from the theme's ui-variables file", ->
|
|
||||||
config.set('core.themes', ['theme-with-ui-variables'])
|
|
||||||
|
|
||||||
# an override loaded in the base css
|
|
||||||
expect(rootView.css("background-color")).toBe "rgb(0, 0, 255)"
|
|
||||||
|
|
||||||
# from within the theme itself
|
|
||||||
expect($(".editor").css("padding-top")).toBe "150px"
|
|
||||||
expect($(".editor").css("padding-right")).toBe "150px"
|
|
||||||
expect($(".editor").css("padding-bottom")).toBe "150px"
|
|
||||||
|
|
||||||
describe "package lifecycle methods", ->
|
describe "package lifecycle methods", ->
|
||||||
describe ".loadPackage(name)", ->
|
describe ".loadPackage(name)", ->
|
||||||
describe "when the package has deferred deserializers", ->
|
describe "when the package has deferred deserializers", ->
|
||||||
@ -205,15 +182,15 @@ describe "the `atom` global", ->
|
|||||||
one = require.resolve("./fixtures/packages/package-with-stylesheets-manifest/stylesheets/1.css")
|
one = require.resolve("./fixtures/packages/package-with-stylesheets-manifest/stylesheets/1.css")
|
||||||
two = require.resolve("./fixtures/packages/package-with-stylesheets-manifest/stylesheets/2.less")
|
two = require.resolve("./fixtures/packages/package-with-stylesheets-manifest/stylesheets/2.less")
|
||||||
three = require.resolve("./fixtures/packages/package-with-stylesheets-manifest/stylesheets/3.css")
|
three = require.resolve("./fixtures/packages/package-with-stylesheets-manifest/stylesheets/3.css")
|
||||||
expect(stylesheetElementForId(one)).not.toExist()
|
expect(atom.themes.stylesheetElementForId(one)).not.toExist()
|
||||||
expect(stylesheetElementForId(two)).not.toExist()
|
expect(atom.themes.stylesheetElementForId(two)).not.toExist()
|
||||||
expect(stylesheetElementForId(three)).not.toExist()
|
expect(atom.themes.stylesheetElementForId(three)).not.toExist()
|
||||||
|
|
||||||
atom.activatePackage("package-with-stylesheets-manifest")
|
atom.activatePackage("package-with-stylesheets-manifest")
|
||||||
|
|
||||||
expect(stylesheetElementForId(one)).toExist()
|
expect(atom.themes.stylesheetElementForId(one)).toExist()
|
||||||
expect(stylesheetElementForId(two)).toExist()
|
expect(atom.themes.stylesheetElementForId(two)).toExist()
|
||||||
expect(stylesheetElementForId(three)).not.toExist()
|
expect(atom.themes.stylesheetElementForId(three)).not.toExist()
|
||||||
expect($('#jasmine-content').css('font-size')).toBe '1px'
|
expect($('#jasmine-content').css('font-size')).toBe '1px'
|
||||||
|
|
||||||
describe "when the metadata does not contain a 'stylesheets' manifest", ->
|
describe "when the metadata does not contain a 'stylesheets' manifest", ->
|
||||||
@ -221,14 +198,14 @@ describe "the `atom` global", ->
|
|||||||
one = require.resolve("./fixtures/packages/package-with-stylesheets/stylesheets/1.css")
|
one = require.resolve("./fixtures/packages/package-with-stylesheets/stylesheets/1.css")
|
||||||
two = require.resolve("./fixtures/packages/package-with-stylesheets/stylesheets/2.less")
|
two = require.resolve("./fixtures/packages/package-with-stylesheets/stylesheets/2.less")
|
||||||
three = require.resolve("./fixtures/packages/package-with-stylesheets/stylesheets/3.css")
|
three = require.resolve("./fixtures/packages/package-with-stylesheets/stylesheets/3.css")
|
||||||
expect(stylesheetElementForId(one)).not.toExist()
|
expect(atom.themes.stylesheetElementForId(one)).not.toExist()
|
||||||
expect(stylesheetElementForId(two)).not.toExist()
|
expect(atom.themes.stylesheetElementForId(two)).not.toExist()
|
||||||
expect(stylesheetElementForId(three)).not.toExist()
|
expect(atom.themes.stylesheetElementForId(three)).not.toExist()
|
||||||
|
|
||||||
atom.activatePackage("package-with-stylesheets")
|
atom.activatePackage("package-with-stylesheets")
|
||||||
expect(stylesheetElementForId(one)).toExist()
|
expect(atom.themes.stylesheetElementForId(one)).toExist()
|
||||||
expect(stylesheetElementForId(two)).toExist()
|
expect(atom.themes.stylesheetElementForId(two)).toExist()
|
||||||
expect(stylesheetElementForId(three)).toExist()
|
expect(atom.themes.stylesheetElementForId(three)).toExist()
|
||||||
expect($('#jasmine-content').css('font-size')).toBe '3px'
|
expect($('#jasmine-content').css('font-size')).toBe '3px'
|
||||||
|
|
||||||
describe "grammar loading", ->
|
describe "grammar loading", ->
|
||||||
@ -298,8 +275,8 @@ describe "the `atom` global", ->
|
|||||||
atom.activatePackage('package-with-serialize-error', immediate: true)
|
atom.activatePackage('package-with-serialize-error', immediate: true)
|
||||||
atom.activatePackage('package-with-serialization', immediate: true)
|
atom.activatePackage('package-with-serialization', immediate: true)
|
||||||
atom.deactivatePackages()
|
atom.deactivatePackages()
|
||||||
expect(atom.packageStates['package-with-serialize-error']).toBeUndefined()
|
expect(atom.packages.packageStates['package-with-serialize-error']).toBeUndefined()
|
||||||
expect(atom.packageStates['package-with-serialization']).toEqual someNumber: 1
|
expect(atom.packages.packageStates['package-with-serialization']).toEqual someNumber: 1
|
||||||
expect(console.error).toHaveBeenCalled()
|
expect(console.error).toHaveBeenCalled()
|
||||||
|
|
||||||
it "removes the package's grammars", ->
|
it "removes the package's grammars", ->
|
||||||
@ -320,9 +297,9 @@ describe "the `atom` global", ->
|
|||||||
one = require.resolve("./fixtures/packages/package-with-stylesheets-manifest/stylesheets/1.css")
|
one = require.resolve("./fixtures/packages/package-with-stylesheets-manifest/stylesheets/1.css")
|
||||||
two = require.resolve("./fixtures/packages/package-with-stylesheets-manifest/stylesheets/2.less")
|
two = require.resolve("./fixtures/packages/package-with-stylesheets-manifest/stylesheets/2.less")
|
||||||
three = require.resolve("./fixtures/packages/package-with-stylesheets-manifest/stylesheets/3.css")
|
three = require.resolve("./fixtures/packages/package-with-stylesheets-manifest/stylesheets/3.css")
|
||||||
expect(stylesheetElementForId(one)).not.toExist()
|
expect(atom.themes.stylesheetElementForId(one)).not.toExist()
|
||||||
expect(stylesheetElementForId(two)).not.toExist()
|
expect(atom.themes.stylesheetElementForId(two)).not.toExist()
|
||||||
expect(stylesheetElementForId(three)).not.toExist()
|
expect(atom.themes.stylesheetElementForId(three)).not.toExist()
|
||||||
|
|
||||||
it "removes the package's scoped-properties", ->
|
it "removes the package's scoped-properties", ->
|
||||||
atom.activatePackage("package-with-scoped-properties")
|
atom.activatePackage("package-with-scoped-properties")
|
||||||
|
33
spec/deserializer-manager-spec.coffee
Normal file
33
spec/deserializer-manager-spec.coffee
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
DeserializerManager = require '../src/deserializer-manager'
|
||||||
|
|
||||||
|
describe ".deserialize(state)", ->
|
||||||
|
deserializer = null
|
||||||
|
|
||||||
|
class Foo
|
||||||
|
@deserialize: ({name}) -> new Foo(name)
|
||||||
|
constructor: (@name) ->
|
||||||
|
|
||||||
|
beforeEach ->
|
||||||
|
deserializer = new DeserializerManager()
|
||||||
|
deserializer.registerDeserializer(Foo)
|
||||||
|
|
||||||
|
it "calls deserialize on the deserializer for the given state object, or returns undefined if one can't be found", ->
|
||||||
|
spyOn(console, 'warn')
|
||||||
|
object = deserializer.deserialize({ deserializer: 'Foo', name: 'Bar' })
|
||||||
|
expect(object.name).toBe 'Bar'
|
||||||
|
expect(deserializer.deserialize({ deserializer: 'Bogus' })).toBeUndefined()
|
||||||
|
|
||||||
|
describe "when the deserializer has a version", ->
|
||||||
|
beforeEach ->
|
||||||
|
Foo.version = 2
|
||||||
|
|
||||||
|
describe "when the deserialized state has a matching version", ->
|
||||||
|
it "attempts to deserialize the state", ->
|
||||||
|
object = deserializer.deserialize({ deserializer: 'Foo', version: 2, name: 'Bar' })
|
||||||
|
expect(object.name).toBe 'Bar'
|
||||||
|
|
||||||
|
describe "when the deserialized state has a non-matching version", ->
|
||||||
|
it "returns undefined", ->
|
||||||
|
expect(deserializer.deserialize({ deserializer: 'Foo', version: 3, name: 'Bar' })).toBeUndefined()
|
||||||
|
expect(deserializer.deserialize({ deserializer: 'Foo', version: 1, name: 'Bar' })).toBeUndefined()
|
||||||
|
expect(deserializer.deserialize({ deserializer: 'Foo', name: 'Bar' })).toBeUndefined()
|
@ -1,7 +1,8 @@
|
|||||||
try
|
try
|
||||||
require '../src/atom'
|
|
||||||
require '../src/window'
|
require '../src/window'
|
||||||
atom.show()
|
Atom = require '../src/atom'
|
||||||
|
window.atom = new Atom()
|
||||||
|
window.atom.show()
|
||||||
{runSpecSuite} = require './jasmine-helper'
|
{runSpecSuite} = require './jasmine-helper'
|
||||||
|
|
||||||
document.title = "Spec Suite"
|
document.title = "Spec Suite"
|
||||||
|
@ -14,12 +14,11 @@ TokenizedBuffer = require '../src/tokenized-buffer'
|
|||||||
pathwatcher = require 'pathwatcher'
|
pathwatcher = require 'pathwatcher'
|
||||||
clipboard = require 'clipboard'
|
clipboard = require 'clipboard'
|
||||||
|
|
||||||
atom.loadBaseStylesheets()
|
atom.themes.loadBaseStylesheets()
|
||||||
requireStylesheet '../static/jasmine'
|
atom.themes.requireStylesheet '../static/jasmine'
|
||||||
|
|
||||||
fixturePackagesPath = path.resolve(__dirname, './fixtures/packages')
|
fixturePackagesPath = path.resolve(__dirname, './fixtures/packages')
|
||||||
config.packageDirPaths.unshift(fixturePackagesPath)
|
atom.keymap.loadBundledKeymaps()
|
||||||
keymap.loadBundledKeymaps()
|
|
||||||
[bindingSetsToRestore, bindingSetsByFirstKeystrokeToRestore] = []
|
[bindingSetsToRestore, bindingSetsByFirstKeystrokeToRestore] = []
|
||||||
|
|
||||||
$(window).on 'core:close', -> window.close()
|
$(window).on 'core:close', -> window.close()
|
||||||
@ -36,20 +35,22 @@ specProjectPath = path.join(specDirectory, 'fixtures')
|
|||||||
|
|
||||||
beforeEach ->
|
beforeEach ->
|
||||||
$.fx.off = true
|
$.fx.off = true
|
||||||
window.project = new Project(specProjectPath)
|
atom.project = new Project(specProjectPath)
|
||||||
|
window.project = atom.project
|
||||||
|
|
||||||
window.resetTimeouts()
|
window.resetTimeouts()
|
||||||
atom.packageStates = {}
|
atom.packages.packageStates = {}
|
||||||
spyOn(atom, 'saveWindowState')
|
spyOn(atom, 'saveWindowState')
|
||||||
syntax.clearGrammarOverrides()
|
atom.syntax.clearGrammarOverrides()
|
||||||
syntax.clearProperties()
|
atom.syntax.clearProperties()
|
||||||
|
|
||||||
# used to reset keymap after each spec
|
# used to reset keymap after each spec
|
||||||
bindingSetsToRestore = _.clone(keymap.bindingSets)
|
bindingSetsToRestore = _.clone(keymap.bindingSets)
|
||||||
bindingSetsByFirstKeystrokeToRestore = _.clone(keymap.bindingSetsByFirstKeystroke)
|
bindingSetsByFirstKeystrokeToRestore = _.clone(keymap.bindingSetsByFirstKeystroke)
|
||||||
|
|
||||||
# reset config before each spec; don't load or save from/to `config.json`
|
# reset config before each spec; don't load or save from/to `config.json`
|
||||||
window.config = new Config()
|
config = new Config()
|
||||||
|
config.packageDirPaths.unshift(fixturePackagesPath)
|
||||||
spyOn(config, 'load')
|
spyOn(config, 'load')
|
||||||
spyOn(config, 'save')
|
spyOn(config, 'save')
|
||||||
config.set "editor.fontFamily", "Courier"
|
config.set "editor.fontFamily", "Courier"
|
||||||
@ -57,6 +58,8 @@ beforeEach ->
|
|||||||
config.set "editor.autoIndent", false
|
config.set "editor.autoIndent", false
|
||||||
config.set "core.disabledPackages", ["package-that-throws-an-exception"]
|
config.set "core.disabledPackages", ["package-that-throws-an-exception"]
|
||||||
config.save.reset()
|
config.save.reset()
|
||||||
|
atom.config = config
|
||||||
|
window.config = config
|
||||||
|
|
||||||
# make editor display updates synchronous
|
# make editor display updates synchronous
|
||||||
spyOn(Editor.prototype, 'requestDisplayUpdate').andCallFake -> @updateDisplay()
|
spyOn(Editor.prototype, 'requestDisplayUpdate').andCallFake -> @updateDisplay()
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
{$} = require 'atom'
|
path = require 'path'
|
||||||
|
{$, $$, fs, RootView} = require 'atom'
|
||||||
|
|
||||||
ThemeManager = require '../src/theme-manager'
|
ThemeManager = require '../src/theme-manager'
|
||||||
AtomPackage = require '../src/atom-package'
|
AtomPackage = require '../src/atom-package'
|
||||||
@ -73,3 +74,81 @@ describe "ThemeManager", ->
|
|||||||
|
|
||||||
expect(loadHandler).toHaveBeenCalled()
|
expect(loadHandler).toHaveBeenCalled()
|
||||||
expect(loadHandler.mostRecentCall.args[0]).toBeInstanceOf AtomPackage
|
expect(loadHandler.mostRecentCall.args[0]).toBeInstanceOf AtomPackage
|
||||||
|
|
||||||
|
describe "requireStylesheet(path)", ->
|
||||||
|
it "synchronously loads css at the given path and installs a style tag for it in the head", ->
|
||||||
|
cssPath = project.resolve('css.css')
|
||||||
|
lengthBefore = $('head style').length
|
||||||
|
|
||||||
|
themeManager.requireStylesheet(cssPath)
|
||||||
|
expect($('head style').length).toBe lengthBefore + 1
|
||||||
|
|
||||||
|
element = $('head style[id*="css.css"]')
|
||||||
|
expect(element.attr('id')).toBe cssPath
|
||||||
|
expect(element.text()).toBe fs.read(cssPath)
|
||||||
|
|
||||||
|
# doesn't append twice
|
||||||
|
themeManager.requireStylesheet(cssPath)
|
||||||
|
expect($('head style').length).toBe lengthBefore + 1
|
||||||
|
|
||||||
|
$('head style[id*="css.css"]').remove()
|
||||||
|
|
||||||
|
it "synchronously loads and parses less files at the given path and installs a style tag for it in the head", ->
|
||||||
|
lessPath = project.resolve('sample.less')
|
||||||
|
lengthBefore = $('head style').length
|
||||||
|
themeManager.requireStylesheet(lessPath)
|
||||||
|
expect($('head style').length).toBe lengthBefore + 1
|
||||||
|
|
||||||
|
element = $('head style[id*="sample.less"]')
|
||||||
|
expect(element.attr('id')).toBe lessPath
|
||||||
|
expect(element.text()).toBe """
|
||||||
|
#header {
|
||||||
|
color: #4d926f;
|
||||||
|
}
|
||||||
|
h2 {
|
||||||
|
color: #4d926f;
|
||||||
|
}
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
# doesn't append twice
|
||||||
|
themeManager.requireStylesheet(lessPath)
|
||||||
|
expect($('head style').length).toBe lengthBefore + 1
|
||||||
|
$('head style[id*="sample.less"]').remove()
|
||||||
|
|
||||||
|
it "supports requiring css and less stylesheets without an explicit extension", ->
|
||||||
|
themeManager.requireStylesheet path.join(__dirname, 'fixtures', 'css')
|
||||||
|
expect($('head style[id*="css.css"]').attr('id')).toBe project.resolve('css.css')
|
||||||
|
themeManager.requireStylesheet path.join(__dirname, 'fixtures', 'sample')
|
||||||
|
expect($('head style[id*="sample.less"]').attr('id')).toBe project.resolve('sample.less')
|
||||||
|
|
||||||
|
$('head style[id*="css.css"]').remove()
|
||||||
|
$('head style[id*="sample.less"]').remove()
|
||||||
|
|
||||||
|
describe ".removeStylesheet(path)", ->
|
||||||
|
it "removes styling applied by given stylesheet path", ->
|
||||||
|
cssPath = require.resolve('./fixtures/css.css')
|
||||||
|
|
||||||
|
expect($(document.body).css('font-weight')).not.toBe("bold")
|
||||||
|
themeManager.requireStylesheet(cssPath)
|
||||||
|
expect($(document.body).css('font-weight')).toBe("bold")
|
||||||
|
themeManager.removeStylesheet(cssPath)
|
||||||
|
expect($(document.body).css('font-weight')).not.toBe("bold")
|
||||||
|
|
||||||
|
describe "base stylesheet loading", ->
|
||||||
|
beforeEach ->
|
||||||
|
window.rootView = new RootView
|
||||||
|
rootView.append $$ -> @div class: 'editor'
|
||||||
|
rootView.attachToDom()
|
||||||
|
themeManager.load()
|
||||||
|
|
||||||
|
it "loads the correct values from the theme's ui-variables file", ->
|
||||||
|
config.set('core.themes', ['theme-with-ui-variables'])
|
||||||
|
|
||||||
|
# an override loaded in the base css
|
||||||
|
expect(rootView.css("background-color")).toBe "rgb(0, 0, 255)"
|
||||||
|
|
||||||
|
# from within the theme itself
|
||||||
|
expect($(".editor").css("padding-top")).toBe "150px"
|
||||||
|
expect($(".editor").css("padding-right")).toBe "150px"
|
||||||
|
expect($(".editor").css("padding-bottom")).toBe "150px"
|
||||||
|
@ -75,66 +75,6 @@ describe "Window", ->
|
|||||||
expect(window.onbeforeunload(new Event('beforeunload'))).toBeFalsy()
|
expect(window.onbeforeunload(new Event('beforeunload'))).toBeFalsy()
|
||||||
expect(atom.confirmSync).toHaveBeenCalled()
|
expect(atom.confirmSync).toHaveBeenCalled()
|
||||||
|
|
||||||
describe "requireStylesheet(path)", ->
|
|
||||||
it "synchronously loads css at the given path and installs a style tag for it in the head", ->
|
|
||||||
cssPath = project.resolve('css.css')
|
|
||||||
lengthBefore = $('head style').length
|
|
||||||
|
|
||||||
requireStylesheet(cssPath)
|
|
||||||
expect($('head style').length).toBe lengthBefore + 1
|
|
||||||
|
|
||||||
element = $('head style[id*="css.css"]')
|
|
||||||
expect(element.attr('id')).toBe cssPath
|
|
||||||
expect(element.text()).toBe fs.read(cssPath)
|
|
||||||
|
|
||||||
# doesn't append twice
|
|
||||||
requireStylesheet(cssPath)
|
|
||||||
expect($('head style').length).toBe lengthBefore + 1
|
|
||||||
|
|
||||||
$('head style[id*="css.css"]').remove()
|
|
||||||
|
|
||||||
it "synchronously loads and parses less files at the given path and installs a style tag for it in the head", ->
|
|
||||||
lessPath = project.resolve('sample.less')
|
|
||||||
lengthBefore = $('head style').length
|
|
||||||
requireStylesheet(lessPath)
|
|
||||||
expect($('head style').length).toBe lengthBefore + 1
|
|
||||||
|
|
||||||
element = $('head style[id*="sample.less"]')
|
|
||||||
expect(element.attr('id')).toBe lessPath
|
|
||||||
expect(element.text()).toBe """
|
|
||||||
#header {
|
|
||||||
color: #4d926f;
|
|
||||||
}
|
|
||||||
h2 {
|
|
||||||
color: #4d926f;
|
|
||||||
}
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
# doesn't append twice
|
|
||||||
requireStylesheet(lessPath)
|
|
||||||
expect($('head style').length).toBe lengthBefore + 1
|
|
||||||
$('head style[id*="sample.less"]').remove()
|
|
||||||
|
|
||||||
it "supports requiring css and less stylesheets without an explicit extension", ->
|
|
||||||
requireStylesheet path.join(__dirname, 'fixtures', 'css')
|
|
||||||
expect($('head style[id*="css.css"]').attr('id')).toBe project.resolve('css.css')
|
|
||||||
requireStylesheet path.join(__dirname, 'fixtures', 'sample')
|
|
||||||
expect($('head style[id*="sample.less"]').attr('id')).toBe project.resolve('sample.less')
|
|
||||||
|
|
||||||
$('head style[id*="css.css"]').remove()
|
|
||||||
$('head style[id*="sample.less"]').remove()
|
|
||||||
|
|
||||||
describe ".removeStylesheet(path)", ->
|
|
||||||
it "removes styling applied by given stylesheet path", ->
|
|
||||||
cssPath = require.resolve('./fixtures/css.css')
|
|
||||||
|
|
||||||
expect($(document.body).css('font-weight')).not.toBe("bold")
|
|
||||||
requireStylesheet(cssPath)
|
|
||||||
expect($(document.body).css('font-weight')).toBe("bold")
|
|
||||||
removeStylesheet(cssPath)
|
|
||||||
expect($(document.body).css('font-weight')).not.toBe("bold")
|
|
||||||
|
|
||||||
describe ".unloadEditorWindow()", ->
|
describe ".unloadEditorWindow()", ->
|
||||||
it "saves the serialized state of the window so it can be deserialized after reload", ->
|
it "saves the serialized state of the window so it can be deserialized after reload", ->
|
||||||
rootViewState = rootView.serialize()
|
rootViewState = rootView.serialize()
|
||||||
@ -156,38 +96,6 @@ describe "Window", ->
|
|||||||
|
|
||||||
expect(buffer.subscriptionCount()).toBe 0
|
expect(buffer.subscriptionCount()).toBe 0
|
||||||
|
|
||||||
describe ".deserialize(state)", ->
|
|
||||||
class Foo
|
|
||||||
@deserialize: ({name}) -> new Foo(name)
|
|
||||||
constructor: (@name) ->
|
|
||||||
|
|
||||||
beforeEach ->
|
|
||||||
registerDeserializer(Foo)
|
|
||||||
|
|
||||||
afterEach ->
|
|
||||||
unregisterDeserializer(Foo)
|
|
||||||
|
|
||||||
it "calls deserialize on the deserializer for the given state object, or returns undefined if one can't be found", ->
|
|
||||||
spyOn(console, 'warn')
|
|
||||||
object = deserialize({ deserializer: 'Foo', name: 'Bar' })
|
|
||||||
expect(object.name).toBe 'Bar'
|
|
||||||
expect(deserialize({ deserializer: 'Bogus' })).toBeUndefined()
|
|
||||||
|
|
||||||
describe "when the deserializer has a version", ->
|
|
||||||
beforeEach ->
|
|
||||||
Foo.version = 2
|
|
||||||
|
|
||||||
describe "when the deserialized state has a matching version", ->
|
|
||||||
it "attempts to deserialize the state", ->
|
|
||||||
object = deserialize({ deserializer: 'Foo', version: 2, name: 'Bar' })
|
|
||||||
expect(object.name).toBe 'Bar'
|
|
||||||
|
|
||||||
describe "when the deserialized state has a non-matching version", ->
|
|
||||||
it "returns undefined", ->
|
|
||||||
expect(deserialize({ deserializer: 'Foo', version: 3, name: 'Bar' })).toBeUndefined()
|
|
||||||
expect(deserialize({ deserializer: 'Foo', version: 1, name: 'Bar' })).toBeUndefined()
|
|
||||||
expect(deserialize({ deserializer: 'Foo', name: 'Bar' })).toBeUndefined()
|
|
||||||
|
|
||||||
describe "drag and drop", ->
|
describe "drag and drop", ->
|
||||||
buildDragEvent = (type, files) ->
|
buildDragEvent = (type, files) ->
|
||||||
dataTransfer =
|
dataTransfer =
|
||||||
@ -206,7 +114,7 @@ describe "Window", ->
|
|||||||
it "opens it", ->
|
it "opens it", ->
|
||||||
spyOn(atom, "open")
|
spyOn(atom, "open")
|
||||||
event = buildDragEvent("drop", [ {path: "/fake1"}, {path: "/fake2"} ])
|
event = buildDragEvent("drop", [ {path: "/fake1"}, {path: "/fake2"} ])
|
||||||
window.onDrop(event)
|
$(document).trigger(event)
|
||||||
expect(atom.open.callCount).toBe 1
|
expect(atom.open.callCount).toBe 1
|
||||||
expect(atom.open.argsForCall[0][0]).toEqual pathsToOpen: ['/fake1', '/fake2']
|
expect(atom.open.argsForCall[0][0]).toEqual pathsToOpen: ['/fake1', '/fake2']
|
||||||
|
|
||||||
@ -214,7 +122,7 @@ describe "Window", ->
|
|||||||
it "does nothing", ->
|
it "does nothing", ->
|
||||||
spyOn(atom, "open")
|
spyOn(atom, "open")
|
||||||
event = buildDragEvent("drop", [])
|
event = buildDragEvent("drop", [])
|
||||||
window.onDrop(event)
|
$(document).trigger(event)
|
||||||
expect(atom.open).not.toHaveBeenCalled()
|
expect(atom.open).not.toHaveBeenCalled()
|
||||||
|
|
||||||
describe "when a link is clicked", ->
|
describe "when a link is clicked", ->
|
||||||
|
@ -83,7 +83,8 @@ class AtomPackage extends Package
|
|||||||
|
|
||||||
activateStylesheets: ->
|
activateStylesheets: ->
|
||||||
type = if @metadata.theme then 'theme' else 'bundled'
|
type = if @metadata.theme then 'theme' else 'bundled'
|
||||||
applyStylesheet(stylesheetPath, content, type) for [stylesheetPath, content] in @stylesheets
|
for [stylesheetPath, content] in @stylesheets
|
||||||
|
atom.themes.applyStylesheet(stylesheetPath, content, type)
|
||||||
|
|
||||||
activateResources: ->
|
activateResources: ->
|
||||||
keymap.add(keymapPath, map) for [keymapPath, map] in @keymaps
|
keymap.add(keymapPath, map) for [keymapPath, map] in @keymaps
|
||||||
@ -113,7 +114,8 @@ class AtomPackage extends Package
|
|||||||
fsUtils.listSync(menusDirPath, ['cson', 'json'])
|
fsUtils.listSync(menusDirPath, ['cson', 'json'])
|
||||||
|
|
||||||
loadStylesheets: ->
|
loadStylesheets: ->
|
||||||
@stylesheets = @getStylesheetPaths().map (stylesheetPath) -> [stylesheetPath, loadStylesheet(stylesheetPath)]
|
@stylesheets = @getStylesheetPaths().map (stylesheetPath) ->
|
||||||
|
[stylesheetPath, atom.themes.loadStylesheet(stylesheetPath)]
|
||||||
|
|
||||||
getStylesheetsPath: ->
|
getStylesheetsPath: ->
|
||||||
path.join(@path, @constructor.stylesheetsDir)
|
path.join(@path, @constructor.stylesheetsDir)
|
||||||
@ -165,17 +167,17 @@ class AtomPackage extends Package
|
|||||||
syntax.removeGrammar(grammar) for grammar in @grammars
|
syntax.removeGrammar(grammar) for grammar in @grammars
|
||||||
syntax.removeProperties(scopedPropertiesPath) for [scopedPropertiesPath] in @scopedProperties
|
syntax.removeProperties(scopedPropertiesPath) for [scopedPropertiesPath] in @scopedProperties
|
||||||
keymap.remove(keymapPath) for [keymapPath] in @keymaps
|
keymap.remove(keymapPath) for [keymapPath] in @keymaps
|
||||||
removeStylesheet(stylesheetPath) for [stylesheetPath] in @stylesheets
|
atom.themes.removeStylesheet(stylesheetPath) for [stylesheetPath] in @stylesheets
|
||||||
|
|
||||||
reloadStylesheets: ->
|
reloadStylesheets: ->
|
||||||
oldSheets = _.clone(@stylesheets)
|
oldSheets = _.clone(@stylesheets)
|
||||||
@loadStylesheets()
|
@loadStylesheets()
|
||||||
removeStylesheet(stylesheetPath) for [stylesheetPath] in oldSheets
|
atom.themes.removeStylesheet(stylesheetPath) for [stylesheetPath] in oldSheets
|
||||||
@reloadStylesheet(stylesheetPath, content) for [stylesheetPath, content] in @stylesheets
|
@reloadStylesheet(stylesheetPath, content) for [stylesheetPath, content] in @stylesheets
|
||||||
|
|
||||||
reloadStylesheet: (stylesheetPath, content) ->
|
reloadStylesheet: (stylesheetPath, content) ->
|
||||||
type = if @metadata.theme then 'theme' else 'bundled'
|
type = if @metadata.theme then 'theme' else 'bundled'
|
||||||
window.applyStylesheet(stylesheetPath, content, type)
|
atom.themes.applyStylesheet(stylesheetPath, content, type)
|
||||||
|
|
||||||
requireMainModule: ->
|
requireMainModule: ->
|
||||||
return @mainModule if @mainModule?
|
return @mainModule if @mainModule?
|
||||||
|
260
src/atom.coffee
260
src/atom.coffee
@ -10,155 +10,140 @@ path = require 'path'
|
|||||||
dialog = remote.require 'dialog'
|
dialog = remote.require 'dialog'
|
||||||
app = remote.require 'app'
|
app = remote.require 'app'
|
||||||
{Document} = require 'telepath'
|
{Document} = require 'telepath'
|
||||||
ThemeManager = require './theme-manager'
|
DeserializerManager = require './deserializer-manager'
|
||||||
ContextMenuManager = require './context-menu-manager'
|
Subscriber = require './subscriber'
|
||||||
|
|
||||||
window.atom =
|
# Public: Atom global for dealing with packages, themes, menus, and the window.
|
||||||
loadedPackages: {}
|
#
|
||||||
activePackages: {}
|
# An instance of this class is always available as the `atom` global.
|
||||||
packageStates: {}
|
module.exports =
|
||||||
themes: new ThemeManager()
|
class Atom
|
||||||
contextMenu: new ContextMenuManager(remote.getCurrentWindow().loadSettings.devMode)
|
_.extend @prototype, Subscriber
|
||||||
|
|
||||||
getLoadSettings: ->
|
constructor: ->
|
||||||
@getCurrentWindow().loadSettings
|
@rootViewParentSelector = 'body'
|
||||||
|
@deserializers = new DeserializerManager()
|
||||||
|
|
||||||
|
initialize: ->
|
||||||
|
@unsubscribe()
|
||||||
|
|
||||||
|
Config = require './config'
|
||||||
|
Keymap = require './keymap'
|
||||||
|
PackageManager = require './package-manager'
|
||||||
|
Pasteboard = require './pasteboard'
|
||||||
|
Syntax = require './syntax'
|
||||||
|
ThemeManager = require './theme-manager'
|
||||||
|
ContextMenuManager = require './context-menu-manager'
|
||||||
|
|
||||||
|
@packages = new PackageManager()
|
||||||
|
|
||||||
|
#TODO Remove once packages have been updated to not touch atom.packageStates directly
|
||||||
|
@__defineGetter__ 'packageStates', => @packages.packageStates
|
||||||
|
@__defineSetter__ 'packageStates', (packageStates) => @packages.packageStates = packageStates
|
||||||
|
|
||||||
|
@subscribe @packages, 'loaded', => @watchThemes()
|
||||||
|
@themes = new ThemeManager()
|
||||||
|
@contextMenu = new ContextMenuManager(@getLoadSettings().devMode)
|
||||||
|
@config = new Config()
|
||||||
|
@pasteboard = new Pasteboard()
|
||||||
|
@keymap = new Keymap()
|
||||||
|
@syntax = deserialize(@getWindowState('syntax')) ? new Syntax()
|
||||||
|
|
||||||
getCurrentWindow: ->
|
getCurrentWindow: ->
|
||||||
remote.getCurrentWindow()
|
remote.getCurrentWindow()
|
||||||
|
|
||||||
getPackageState: (name) ->
|
# Public: Get the dimensions of this window.
|
||||||
@packageStates[name]
|
#
|
||||||
|
# Returns an object with x, y, width, and height keys.
|
||||||
|
getDimensions: ->
|
||||||
|
browserWindow = @getCurrentWindow()
|
||||||
|
[x, y] = browserWindow.getPosition()
|
||||||
|
[width, height] = browserWindow.getSize()
|
||||||
|
{x, y, width, height}
|
||||||
|
|
||||||
setPackageState: (name, state) ->
|
# Public: Set the dimensions of the window.
|
||||||
@packageStates[name] = state
|
#
|
||||||
|
# The window will be centered if either the x or y coordinate is not set
|
||||||
activatePackages: ->
|
# in the dimensions parameter.
|
||||||
@activatePackage(pack.name) for pack in @getLoadedPackages()
|
#
|
||||||
|
# * dimensions:
|
||||||
activatePackage: (name, options) ->
|
# + x:
|
||||||
if pack = @loadPackage(name, options)
|
# The new x coordinate.
|
||||||
@activePackages[pack.name] = pack
|
# + y:
|
||||||
pack.activate(options)
|
# The new y coordinate.
|
||||||
pack
|
# + width:
|
||||||
|
# The new width.
|
||||||
deactivatePackages: ->
|
# + height:
|
||||||
@deactivatePackage(pack.name) for pack in @getActivePackages()
|
# The new height.
|
||||||
|
setDimensions: ({x, y, width, height}) ->
|
||||||
deactivatePackage: (name) ->
|
browserWindow = @getCurrentWindow()
|
||||||
if pack = @getActivePackage(name)
|
browserWindow.setSize(width, height)
|
||||||
@setPackageState(pack.name, state) if state = pack.serialize?()
|
if x? and y?
|
||||||
pack.deactivate()
|
browserWindow.setPosition(x, y)
|
||||||
delete @activePackages[pack.name]
|
|
||||||
else
|
else
|
||||||
throw new Error("No active package for name '#{name}'")
|
browserWindow.center()
|
||||||
|
|
||||||
getActivePackage: (name) ->
|
restoreDimensions: (defaultDimensions={width: 800, height: 600})->
|
||||||
@activePackages[name]
|
dimensions = @getWindowState().getObject('dimensions')
|
||||||
|
dimensions = defaultDimensions unless dimensions?.width and dimensions?.height
|
||||||
|
@setDimensions(dimensions)
|
||||||
|
|
||||||
isPackageActive: (name) ->
|
getLoadSettings: ->
|
||||||
@getActivePackage(name)?
|
@getCurrentWindow().loadSettings
|
||||||
|
|
||||||
getActivePackages: ->
|
deserializeProject: ->
|
||||||
_.values(@activePackages)
|
Project = require './project'
|
||||||
|
state = @getWindowState()
|
||||||
|
@project = deserialize(state.get('project'))
|
||||||
|
unless @project?
|
||||||
|
@project = new Project(@getLoadSettings().initialPath)
|
||||||
|
state.set('project', @project.getState())
|
||||||
|
|
||||||
loadPackages: ->
|
deserializeRootView: ->
|
||||||
# Ensure atom exports is already in the require cache so the load time
|
RootView = require './root-view'
|
||||||
# of the first package isn't skewed by being the first to require atom
|
state = @getWindowState()
|
||||||
require '../exports/atom'
|
@rootView = deserialize(state.get('rootView'))
|
||||||
|
unless @rootView?
|
||||||
|
@rootView = new RootView()
|
||||||
|
state.set('rootView', @rootView.getState())
|
||||||
|
$(@rootViewParentSelector).append(@rootView)
|
||||||
|
|
||||||
@loadPackage(name) for name in @getAvailablePackageNames() when not @isPackageDisabled(name)
|
deserializePackageStates: ->
|
||||||
@watchThemes()
|
state = @getWindowState()
|
||||||
|
@packages.packageStates = state.getObject('packageStates') ? {}
|
||||||
|
state.remove('packageStates')
|
||||||
|
|
||||||
loadPackage: (name, options) ->
|
#TODO Remove theses once packages have been migrated
|
||||||
if @isPackageDisabled(name)
|
getPackageState: (args...) -> @packages.getPackageState(args...)
|
||||||
return console.warn("Tried to load disabled package '#{name}'")
|
setPackageState: (args...) -> @packages.setPackageState(args...)
|
||||||
|
activatePackages: (args...) -> @packages.activatePackages(args...)
|
||||||
if packagePath = @resolvePackagePath(name)
|
activatePackage: (args...) -> @packages.activatePackage(args...)
|
||||||
return pack if pack = @getLoadedPackage(name)
|
deactivatePackages: (args...) -> @packages.deactivatePackages(args...)
|
||||||
pack = Package.load(packagePath, options)
|
deactivatePackage: (args...) -> @packages.deactivatePackage(args...)
|
||||||
if pack.metadata.theme
|
getActivePackage: (args...) -> @packages.getActivePackage(args...)
|
||||||
@themes.register(pack)
|
isPackageActive: (args...) -> @packages.isPackageActive(args...)
|
||||||
else
|
getActivePackages: (args...) -> @packages.getActivePackages(args...)
|
||||||
@loadedPackages[pack.name] = pack
|
loadPackages: (args...) -> @packages.loadPackages(args...)
|
||||||
pack
|
loadPackage: (args...) -> @packages.loadPackage(args...)
|
||||||
else
|
unloadPackage: (args...) -> @packages.unloadPackage(args...)
|
||||||
throw new Error("Could not resolve '#{name}' to a package path")
|
resolvePackagePath: (args...) -> @packages.resolvePackagePath(args...)
|
||||||
|
isInternalPackage: (args...) -> @packages.isInternalPackage(args...)
|
||||||
unloadPackage: (name) ->
|
getLoadedPackage: (args...) -> @packages.getLoadedPackage(args...)
|
||||||
if @isPackageActive(name)
|
isPackageLoaded: (args...) -> @packages.isPackageLoaded(args...)
|
||||||
throw new Error("Tried to unload active package '#{name}'")
|
getLoadedPackages: (args...) -> @packages.getLoadedPackages(args...)
|
||||||
|
isPackageDisabled: (args...) -> @packages.isPackageDisabled(args...)
|
||||||
if pack = @getLoadedPackage(name)
|
getAvailablePackagePaths: (args...) -> @packages.getAvailablePackagePaths(args...)
|
||||||
delete @loadedPackages[pack.name]
|
getAvailablePackageNames: (args...) -> @packages.getAvailablePackageNames(args...)
|
||||||
else
|
getAvailablePackageMetadata: (args...)-> @packages.getAvailablePackageMetadata(args...)
|
||||||
throw new Error("No loaded package for name '#{name}'")
|
|
||||||
|
|
||||||
resolvePackagePath: (name) ->
|
|
||||||
return name if fsUtils.isDirectorySync(name)
|
|
||||||
|
|
||||||
packagePath = fsUtils.resolve(config.packageDirPaths..., name)
|
|
||||||
return packagePath if fsUtils.isDirectorySync(packagePath)
|
|
||||||
|
|
||||||
packagePath = path.join(window.resourcePath, 'node_modules', name)
|
|
||||||
return packagePath if @isInternalPackage(packagePath)
|
|
||||||
|
|
||||||
isInternalPackage: (packagePath) ->
|
|
||||||
{engines} = Package.loadMetadata(packagePath, true)
|
|
||||||
engines?.atom?
|
|
||||||
|
|
||||||
getLoadedPackage: (name) ->
|
|
||||||
@loadedPackages[name]
|
|
||||||
|
|
||||||
isPackageLoaded: (name) ->
|
|
||||||
@getLoadedPackage(name)?
|
|
||||||
|
|
||||||
getLoadedPackages: ->
|
|
||||||
_.values(@loadedPackages)
|
|
||||||
|
|
||||||
isPackageDisabled: (name) ->
|
|
||||||
_.include(config.get('core.disabledPackages') ? [], name)
|
|
||||||
|
|
||||||
getAvailablePackagePaths: ->
|
|
||||||
packagePaths = []
|
|
||||||
|
|
||||||
for packageDirPath in config.packageDirPaths
|
|
||||||
for packagePath in fsUtils.listSync(packageDirPath)
|
|
||||||
packagePaths.push(packagePath) if fsUtils.isDirectorySync(packagePath)
|
|
||||||
|
|
||||||
for packagePath in fsUtils.listSync(path.join(window.resourcePath, 'node_modules'))
|
|
||||||
packagePaths.push(packagePath) if @isInternalPackage(packagePath)
|
|
||||||
|
|
||||||
_.uniq(packagePaths)
|
|
||||||
|
|
||||||
getAvailablePackageNames: ->
|
|
||||||
_.uniq _.map @getAvailablePackagePaths(), (packagePath) -> path.basename(packagePath)
|
|
||||||
|
|
||||||
getAvailablePackageMetadata: ->
|
|
||||||
packages = []
|
|
||||||
for packagePath in atom.getAvailablePackagePaths()
|
|
||||||
name = path.basename(packagePath)
|
|
||||||
metadata = atom.getLoadedPackage(name)?.metadata ? Package.loadMetadata(packagePath, true)
|
|
||||||
packages.push(metadata)
|
|
||||||
packages
|
|
||||||
|
|
||||||
loadThemes: ->
|
loadThemes: ->
|
||||||
@themes.load()
|
@themes.load()
|
||||||
|
|
||||||
watchThemes: ->
|
watchThemes: ->
|
||||||
@themes.on 'reloaded', =>
|
@themes.on 'reloaded', =>
|
||||||
@reloadBaseStylesheets()
|
pack.reloadStylesheets?() for name, pack of @getLoadedPackages()
|
||||||
pack.reloadStylesheets?() for name, pack of @loadedPackages
|
|
||||||
null
|
null
|
||||||
|
|
||||||
loadBaseStylesheets: ->
|
|
||||||
requireStylesheet('bootstrap/less/bootstrap')
|
|
||||||
@reloadBaseStylesheets()
|
|
||||||
|
|
||||||
reloadBaseStylesheets: ->
|
|
||||||
requireStylesheet('../static/atom')
|
|
||||||
if nativeStylesheetPath = fsUtils.resolveOnLoadPath(process.platform, ['css', 'less'])
|
|
||||||
requireStylesheet(nativeStylesheetPath)
|
|
||||||
|
|
||||||
open: (options) ->
|
open: (options) ->
|
||||||
ipc.sendChannel('open', options)
|
ipc.sendChannel('open', options)
|
||||||
|
|
||||||
@ -210,8 +195,7 @@ window.atom =
|
|||||||
close: ->
|
close: ->
|
||||||
@getCurrentWindow().close()
|
@getCurrentWindow().close()
|
||||||
|
|
||||||
exit: (status) ->
|
exit: (status) -> app.exit(status)
|
||||||
app.exit(status)
|
|
||||||
|
|
||||||
toggleFullScreen: ->
|
toggleFullScreen: ->
|
||||||
@setFullScreen(!@isFullScreen())
|
@setFullScreen(!@isFullScreen())
|
||||||
@ -236,7 +220,7 @@ window.atom =
|
|||||||
filename = "editor-#{sha1}"
|
filename = "editor-#{sha1}"
|
||||||
|
|
||||||
if filename
|
if filename
|
||||||
path.join(config.userStoragePath, filename)
|
path.join(@config.userStoragePath, filename)
|
||||||
else
|
else
|
||||||
null
|
null
|
||||||
|
|
||||||
@ -289,8 +273,22 @@ window.atom =
|
|||||||
shell.beep()
|
shell.beep()
|
||||||
|
|
||||||
requireUserInitScript: ->
|
requireUserInitScript: ->
|
||||||
userInitScriptPath = path.join(config.configDirPath, "user.coffee")
|
userInitScriptPath = path.join(@config.configDirPath, "user.coffee")
|
||||||
try
|
try
|
||||||
require userInitScriptPath if fsUtils.isFileSync(userInitScriptPath)
|
require userInitScriptPath if fsUtils.isFileSync(userInitScriptPath)
|
||||||
catch error
|
catch error
|
||||||
console.error "Failed to load `#{userInitScriptPath}`", error.stack, error
|
console.error "Failed to load `#{userInitScriptPath}`", error.stack, error
|
||||||
|
|
||||||
|
requireWithGlobals: (id, globals={}) ->
|
||||||
|
existingGlobals = {}
|
||||||
|
for key, value of globals
|
||||||
|
existingGlobals[key] = window[key]
|
||||||
|
window[key] = value
|
||||||
|
|
||||||
|
require(id)
|
||||||
|
|
||||||
|
for key, value of existingGlobals
|
||||||
|
if value is undefined
|
||||||
|
delete window[key]
|
||||||
|
else
|
||||||
|
window[key] = value
|
||||||
|
@ -8,12 +8,6 @@ async = require 'async'
|
|||||||
pathWatcher = require 'pathwatcher'
|
pathWatcher = require 'pathwatcher'
|
||||||
|
|
||||||
configDirPath = fsUtils.absolute("~/.atom")
|
configDirPath = fsUtils.absolute("~/.atom")
|
||||||
nodeModulesDirPath = path.join(resourcePath, "node_modules")
|
|
||||||
bundledKeymapsDirPath = path.join(resourcePath, "keymaps")
|
|
||||||
userPackagesDirPath = path.join(configDirPath, "packages")
|
|
||||||
userPackageDirPaths = [userPackagesDirPath]
|
|
||||||
userPackageDirPaths.unshift(path.join(configDirPath, "dev", "packages")) if atom.getLoadSettings().devMode
|
|
||||||
userStoragePath = path.join(configDirPath, "storage")
|
|
||||||
|
|
||||||
# Public: Used to access all of Atom's configuration details.
|
# Public: Used to access all of Atom's configuration details.
|
||||||
#
|
#
|
||||||
@ -36,23 +30,26 @@ module.exports =
|
|||||||
class Config
|
class Config
|
||||||
_.extend @prototype, EventEmitter
|
_.extend @prototype, EventEmitter
|
||||||
|
|
||||||
configDirPath: configDirPath
|
|
||||||
bundledPackageDirPaths: [nodeModulesDirPath]
|
|
||||||
bundledKeymapsDirPath: bundledKeymapsDirPath
|
|
||||||
nodeModulesDirPath: nodeModulesDirPath
|
|
||||||
packageDirPaths: _.clone(userPackageDirPaths)
|
|
||||||
userPackageDirPaths: userPackageDirPaths
|
|
||||||
userStoragePath: userStoragePath
|
|
||||||
lessSearchPaths: [
|
|
||||||
path.join(resourcePath, 'static', 'variables')
|
|
||||||
path.join(resourcePath, 'static')
|
|
||||||
]
|
|
||||||
defaultSettings: null
|
defaultSettings: null
|
||||||
settings: null
|
settings: null
|
||||||
configFileHasErrors: null
|
configFileHasErrors: null
|
||||||
|
|
||||||
# Private: Created during initialization, available as `global.config`
|
# Private: Created during initialization, available as `global.config`
|
||||||
constructor: ->
|
constructor: ->
|
||||||
|
@configDirPath = configDirPath
|
||||||
|
@bundledKeymapsDirPath = path.join(resourcePath, "keymaps")
|
||||||
|
@nodeModulesDirPath = path.join(resourcePath, "node_modules")
|
||||||
|
@bundledPackageDirPaths = [@nodeModulesDirPath]
|
||||||
|
@lessSearchPaths = [
|
||||||
|
path.join(resourcePath, 'static', 'variables')
|
||||||
|
path.join(resourcePath, 'static')
|
||||||
|
]
|
||||||
|
@packageDirPaths = [path.join(configDirPath, "packages")]
|
||||||
|
if atom.getLoadSettings().devMode
|
||||||
|
@packageDirPaths.unshift(path.join(configDirPath, "dev", "packages"))
|
||||||
|
@userPackageDirPaths = _.clone(@packageDirPaths)
|
||||||
|
@userStoragePath = path.join(configDirPath, "storage")
|
||||||
|
|
||||||
@defaultSettings =
|
@defaultSettings =
|
||||||
core: _.clone(require('./root-view').configDefaults)
|
core: _.clone(require('./root-view').configDefaults)
|
||||||
editor: _.clone(require('./editor').configDefaults)
|
editor: _.clone(require('./editor').configDefaults)
|
||||||
|
38
src/deserializer-manager.coffee
Normal file
38
src/deserializer-manager.coffee
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
{Document} = require 'telepath'
|
||||||
|
|
||||||
|
module.exports =
|
||||||
|
class DeserializerManager
|
||||||
|
constructor: ->
|
||||||
|
@deserializers = {}
|
||||||
|
@deferredDeserializers = {}
|
||||||
|
|
||||||
|
registerDeserializer: (klasses...) ->
|
||||||
|
@deserializers[klass.name] = klass for klass in klasses
|
||||||
|
|
||||||
|
registerDeferredDeserializer: (name, fn) ->
|
||||||
|
@deferredDeserializers[name] = fn
|
||||||
|
|
||||||
|
unregisterDeserializer: (klasses...) ->
|
||||||
|
delete @deserializers[klass.name] for klass in klasses
|
||||||
|
|
||||||
|
deserialize: (state, params) ->
|
||||||
|
return unless state?
|
||||||
|
|
||||||
|
if deserializer = @getDeserializer(state)
|
||||||
|
stateVersion = state.get?('version') ? state.version
|
||||||
|
return if deserializer.version? and deserializer.version isnt stateVersion
|
||||||
|
if (state instanceof Document) and not deserializer.acceptsDocuments
|
||||||
|
state = state.toObject()
|
||||||
|
deserializer.deserialize(state, params)
|
||||||
|
else
|
||||||
|
console.warn "No deserializer found for", state
|
||||||
|
|
||||||
|
getDeserializer: (state) ->
|
||||||
|
return unless state?
|
||||||
|
|
||||||
|
name = state.get?('deserializer') ? state.deserializer
|
||||||
|
if @deferredDeserializers[name]
|
||||||
|
@deferredDeserializers[name]()
|
||||||
|
delete @deferredDeserializers[name]
|
||||||
|
|
||||||
|
@deserializers[name]
|
129
src/package-manager.coffee
Normal file
129
src/package-manager.coffee
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
EventEmitter = require './event-emitter'
|
||||||
|
fsUtils = require './fs-utils'
|
||||||
|
_ = require './underscore-extensions'
|
||||||
|
Package = require './package'
|
||||||
|
path = require 'path'
|
||||||
|
|
||||||
|
module.exports =
|
||||||
|
class PackageManager
|
||||||
|
_.extend @prototype, EventEmitter
|
||||||
|
|
||||||
|
constructor: ->
|
||||||
|
@loadedPackages = {}
|
||||||
|
@activePackages = {}
|
||||||
|
@packageStates = {}
|
||||||
|
|
||||||
|
getPackageState: (name) ->
|
||||||
|
@packageStates[name]
|
||||||
|
|
||||||
|
setPackageState: (name, state) ->
|
||||||
|
@packageStates[name] = state
|
||||||
|
|
||||||
|
activatePackages: ->
|
||||||
|
@activatePackage(pack.name) for pack in @getLoadedPackages()
|
||||||
|
|
||||||
|
activatePackage: (name, options) ->
|
||||||
|
if pack = @loadPackage(name, options)
|
||||||
|
@activePackages[pack.name] = pack
|
||||||
|
pack.activate(options)
|
||||||
|
pack
|
||||||
|
|
||||||
|
deactivatePackages: ->
|
||||||
|
@deactivatePackage(pack.name) for pack in @getActivePackages()
|
||||||
|
|
||||||
|
deactivatePackage: (name) ->
|
||||||
|
if pack = @getActivePackage(name)
|
||||||
|
@setPackageState(pack.name, state) if state = pack.serialize?()
|
||||||
|
pack.deactivate()
|
||||||
|
delete @activePackages[pack.name]
|
||||||
|
else
|
||||||
|
throw new Error("No active package for name '#{name}'")
|
||||||
|
|
||||||
|
getActivePackage: (name) ->
|
||||||
|
@activePackages[name]
|
||||||
|
|
||||||
|
isPackageActive: (name) ->
|
||||||
|
@getActivePackage(name)?
|
||||||
|
|
||||||
|
getActivePackages: ->
|
||||||
|
_.values(@activePackages)
|
||||||
|
|
||||||
|
loadPackages: ->
|
||||||
|
# Ensure atom exports is already in the require cache so the load time
|
||||||
|
# of the first package isn't skewed by being the first to require atom
|
||||||
|
require '../exports/atom'
|
||||||
|
|
||||||
|
@loadPackage(name) for name in @getAvailablePackageNames() when not @isPackageDisabled(name)
|
||||||
|
@trigger 'loaded'
|
||||||
|
|
||||||
|
loadPackage: (name, options) ->
|
||||||
|
if @isPackageDisabled(name)
|
||||||
|
return console.warn("Tried to load disabled package '#{name}'")
|
||||||
|
|
||||||
|
if packagePath = @resolvePackagePath(name)
|
||||||
|
return pack if pack = @getLoadedPackage(name)
|
||||||
|
pack = Package.load(packagePath, options)
|
||||||
|
if pack.metadata.theme
|
||||||
|
atom.themes.register(pack)
|
||||||
|
else
|
||||||
|
@loadedPackages[pack.name] = pack
|
||||||
|
pack
|
||||||
|
else
|
||||||
|
throw new Error("Could not resolve '#{name}' to a package path")
|
||||||
|
|
||||||
|
unloadPackage: (name) ->
|
||||||
|
if @isPackageActive(name)
|
||||||
|
throw new Error("Tried to unload active package '#{name}'")
|
||||||
|
|
||||||
|
if pack = @getLoadedPackage(name)
|
||||||
|
delete @loadedPackages[pack.name]
|
||||||
|
else
|
||||||
|
throw new Error("No loaded package for name '#{name}'")
|
||||||
|
|
||||||
|
resolvePackagePath: (name) ->
|
||||||
|
return name if fsUtils.isDirectorySync(name)
|
||||||
|
|
||||||
|
packagePath = fsUtils.resolve(config.packageDirPaths..., name)
|
||||||
|
return packagePath if fsUtils.isDirectorySync(packagePath)
|
||||||
|
|
||||||
|
packagePath = path.join(window.resourcePath, 'node_modules', name)
|
||||||
|
return packagePath if @isInternalPackage(packagePath)
|
||||||
|
|
||||||
|
isInternalPackage: (packagePath) ->
|
||||||
|
{engines} = Package.loadMetadata(packagePath, true)
|
||||||
|
engines?.atom?
|
||||||
|
|
||||||
|
getLoadedPackage: (name) ->
|
||||||
|
@loadedPackages[name]
|
||||||
|
|
||||||
|
isPackageLoaded: (name) ->
|
||||||
|
@getLoadedPackage(name)?
|
||||||
|
|
||||||
|
getLoadedPackages: ->
|
||||||
|
_.values(@loadedPackages)
|
||||||
|
|
||||||
|
isPackageDisabled: (name) ->
|
||||||
|
_.include(config.get('core.disabledPackages') ? [], name)
|
||||||
|
|
||||||
|
getAvailablePackagePaths: ->
|
||||||
|
packagePaths = []
|
||||||
|
|
||||||
|
for packageDirPath in config.packageDirPaths
|
||||||
|
for packagePath in fsUtils.listSync(packageDirPath)
|
||||||
|
packagePaths.push(packagePath) if fsUtils.isDirectorySync(packagePath)
|
||||||
|
|
||||||
|
for packagePath in fsUtils.listSync(path.join(window.resourcePath, 'node_modules'))
|
||||||
|
packagePaths.push(packagePath) if @isInternalPackage(packagePath)
|
||||||
|
|
||||||
|
_.uniq(packagePaths)
|
||||||
|
|
||||||
|
getAvailablePackageNames: ->
|
||||||
|
_.uniq _.map @getAvailablePackagePaths(), (packagePath) -> path.basename(packagePath)
|
||||||
|
|
||||||
|
getAvailablePackageMetadata: ->
|
||||||
|
packages = []
|
||||||
|
for packagePath in atom.getAvailablePackagePaths()
|
||||||
|
name = path.basename(packagePath)
|
||||||
|
metadata = atom.getLoadedPackage(name)?.metadata ? Package.loadMetadata(packagePath, true)
|
||||||
|
packages.push(metadata)
|
||||||
|
packages
|
@ -4,7 +4,7 @@ Package = require './package'
|
|||||||
AtomPackage = require './atom-package'
|
AtomPackage = require './atom-package'
|
||||||
|
|
||||||
_ = require './underscore-extensions'
|
_ = require './underscore-extensions'
|
||||||
|
$ = require './jquery-extensions'
|
||||||
fsUtils = require './fs-utils'
|
fsUtils = require './fs-utils'
|
||||||
|
|
||||||
# Private: Handles discovering and loading available themes.
|
# Private: Handles discovering and loading available themes.
|
||||||
@ -15,6 +15,7 @@ class ThemeManager
|
|||||||
constructor: ->
|
constructor: ->
|
||||||
@loadedThemes = []
|
@loadedThemes = []
|
||||||
@activeThemes = []
|
@activeThemes = []
|
||||||
|
@lessCache = null
|
||||||
|
|
||||||
# Internal-only:
|
# Internal-only:
|
||||||
register: (theme) ->
|
register: (theme) ->
|
||||||
@ -33,9 +34,85 @@ class ThemeManager
|
|||||||
getLoadedThemes: ->
|
getLoadedThemes: ->
|
||||||
_.clone(@loadedThemes)
|
_.clone(@loadedThemes)
|
||||||
|
|
||||||
|
# Internal-only:
|
||||||
|
loadBaseStylesheets: ->
|
||||||
|
@requireStylesheet('bootstrap/less/bootstrap')
|
||||||
|
@reloadBaseStylesheets()
|
||||||
|
|
||||||
|
# Internal-only:
|
||||||
|
reloadBaseStylesheets: ->
|
||||||
|
@requireStylesheet('../static/atom')
|
||||||
|
if nativeStylesheetPath = fsUtils.resolveOnLoadPath(process.platform, ['css', 'less'])
|
||||||
|
@requireStylesheet(nativeStylesheetPath)
|
||||||
|
|
||||||
|
# Internal-only:
|
||||||
|
stylesheetElementForId: (id) ->
|
||||||
|
$("""head style[id="#{id}"]""")
|
||||||
|
|
||||||
|
# Internal-only:
|
||||||
|
resolveStylesheet: (stylesheetPath) ->
|
||||||
|
if path.extname(stylesheetPath).length > 0
|
||||||
|
fsUtils.resolveOnLoadPath(stylesheetPath)
|
||||||
|
else
|
||||||
|
fsUtils.resolveOnLoadPath(stylesheetPath, ['css', 'less'])
|
||||||
|
|
||||||
|
# Public: resolves and applies the stylesheet specified by the path.
|
||||||
|
#
|
||||||
|
# * stylesheetPath: String. Can be an absolute path or the name of a CSS or
|
||||||
|
# LESS file in the stylesheets path.
|
||||||
|
#
|
||||||
|
# Returns the absolute path to the stylesheet
|
||||||
|
requireStylesheet: (stylesheetPath) ->
|
||||||
|
if fullPath = @resolveStylesheet(stylesheetPath)
|
||||||
|
content = @loadStylesheet(fullPath)
|
||||||
|
@applyStylesheet(fullPath, content)
|
||||||
|
else
|
||||||
|
throw new Error("Could not find a file at path '#{stylesheetPath}'")
|
||||||
|
|
||||||
|
fullPath
|
||||||
|
|
||||||
|
# Internal-only:
|
||||||
|
loadStylesheet: (stylesheetPath) ->
|
||||||
|
if path.extname(stylesheetPath) is '.less'
|
||||||
|
@loadLessStylesheet(stylesheetPath)
|
||||||
|
else
|
||||||
|
fsUtils.read(stylesheetPath)
|
||||||
|
|
||||||
|
# Internal-only:
|
||||||
|
loadLessStylesheet: (lessStylesheetPath) ->
|
||||||
|
unless lessCache?
|
||||||
|
LessCompileCache = require './less-compile-cache'
|
||||||
|
@lessCache = new LessCompileCache()
|
||||||
|
|
||||||
|
try
|
||||||
|
@lessCache.read(lessStylesheetPath)
|
||||||
|
catch e
|
||||||
|
console.error """
|
||||||
|
Error compiling less stylesheet: #{lessStylesheetPath}
|
||||||
|
Line number: #{e.line}
|
||||||
|
#{e.message}
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Internal-only:
|
||||||
|
removeStylesheet: (stylesheetPath) ->
|
||||||
|
unless fullPath = @resolveStylesheet(stylesheetPath)
|
||||||
|
throw new Error("Could not find a file at path '#{stylesheetPath}'")
|
||||||
|
@stylesheetElementForId(fullPath).remove()
|
||||||
|
|
||||||
|
# Internal-only:
|
||||||
|
applyStylesheet: (id, text, ttype = 'bundled') ->
|
||||||
|
styleElement = @stylesheetElementForId(id)
|
||||||
|
if styleElement.length
|
||||||
|
styleElement.text(text)
|
||||||
|
else
|
||||||
|
if $("head style.#{ttype}").length
|
||||||
|
$("head style.#{ttype}:last").after "<style class='#{ttype}' id='#{id}'>#{text}</style>"
|
||||||
|
else
|
||||||
|
$("head").append "<style class='#{ttype}' id='#{id}'>#{text}</style>"
|
||||||
|
|
||||||
# Internal-only:
|
# Internal-only:
|
||||||
unload: ->
|
unload: ->
|
||||||
removeStylesheet(@userStylesheetPath) if @userStylesheetPath?
|
@removeStylesheet(@userStylesheetPath) if @userStylesheetPath?
|
||||||
theme.deactivate() while theme = @activeThemes.pop()
|
theme.deactivate() while theme = @activeThemes.pop()
|
||||||
|
|
||||||
# Internal-only:
|
# Internal-only:
|
||||||
@ -50,7 +127,7 @@ class ThemeManager
|
|||||||
|
|
||||||
@activateTheme(themeName) for themeName in themeNames
|
@activateTheme(themeName) for themeName in themeNames
|
||||||
@loadUserStylesheet()
|
@loadUserStylesheet()
|
||||||
|
@reloadBaseStylesheets()
|
||||||
@trigger('reloaded')
|
@trigger('reloaded')
|
||||||
|
|
||||||
# Private:
|
# Private:
|
||||||
@ -118,5 +195,5 @@ class ThemeManager
|
|||||||
loadUserStylesheet: ->
|
loadUserStylesheet: ->
|
||||||
if userStylesheetPath = @getUserStylesheetPath()
|
if userStylesheetPath = @getUserStylesheetPath()
|
||||||
@userStylesheetPath = userStylesheetPath
|
@userStylesheetPath = userStylesheetPath
|
||||||
userStylesheetContents = loadStylesheet(userStylesheetPath)
|
userStylesheetContents = @loadStylesheet(userStylesheetPath)
|
||||||
applyStylesheet(userStylesheetPath, userStylesheetContents, 'userTheme')
|
@applyStylesheet(userStylesheetPath, userStylesheetContents, 'userTheme')
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
# Like sands through the hourglass, so are the days of our lives.
|
# Like sands through the hourglass, so are the days of our lives.
|
||||||
startTime = new Date().getTime()
|
startTime = new Date().getTime()
|
||||||
|
|
||||||
require './atom'
|
|
||||||
require './window'
|
require './window'
|
||||||
|
|
||||||
|
Atom = require './atom'
|
||||||
|
window.atom = new Atom()
|
||||||
window.setUpEnvironment('editor')
|
window.setUpEnvironment('editor')
|
||||||
window.startEditorWindow()
|
window.startEditorWindow()
|
||||||
console.log "Window load time: #{new Date().getTime() - startTime}ms"
|
console.log "Window load time: #{new Date().getTime() - startTime}ms"
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
$ = require './jquery-extensions'
|
$ = require './jquery-extensions'
|
||||||
_ = require './underscore-extensions'
|
_ = require './underscore-extensions'
|
||||||
ipc = require 'ipc'
|
ipc = require 'ipc'
|
||||||
remote = require 'remote'
|
shell = require 'shell'
|
||||||
Subscriber = require './subscriber'
|
Subscriber = require './subscriber'
|
||||||
fsUtils = require './fs-utils'
|
fsUtils = require './fs-utils'
|
||||||
|
|
||||||
@ -20,27 +20,43 @@ class WindowEventHandler
|
|||||||
$(atom.contextMenu.activeElement).trigger(command, args...)
|
$(atom.contextMenu.activeElement).trigger(command, args...)
|
||||||
|
|
||||||
@subscribe $(window), 'focus', -> $("body").removeClass('is-blurred')
|
@subscribe $(window), 'focus', -> $("body").removeClass('is-blurred')
|
||||||
|
|
||||||
@subscribe $(window), 'blur', -> $("body").addClass('is-blurred')
|
@subscribe $(window), 'blur', -> $("body").addClass('is-blurred')
|
||||||
|
|
||||||
@subscribe $(window), 'window:open-path', (event, {pathToOpen, initialLine}) ->
|
@subscribe $(window), 'window:open-path', (event, {pathToOpen, initialLine}) ->
|
||||||
rootView?.open(pathToOpen, {initialLine}) unless fsUtils.isDirectorySync(pathToOpen)
|
atom.rootView?.open(pathToOpen, {initialLine}) unless fsUtils.isDirectorySync(pathToOpen)
|
||||||
|
|
||||||
@subscribe $(window), 'beforeunload', =>
|
@subscribe $(window), 'beforeunload', =>
|
||||||
confirmed = rootView?.confirmClose()
|
confirmed = atom.rootView?.confirmClose()
|
||||||
atom.hide() if confirmed and not @reloadRequested and remote.getCurrentWindow().isWebViewFocused()
|
atom.hide() if confirmed and not @reloadRequested and atom.getCurrentWindow().isWebViewFocused()
|
||||||
@reloadRequested = false
|
@reloadRequested = false
|
||||||
confirmed
|
confirmed
|
||||||
|
|
||||||
|
@subscribe $(window), 'unload', ->
|
||||||
|
atom.getWindowState().set('dimensions', atom.getDimensions())
|
||||||
|
|
||||||
@subscribeToCommand $(window), 'window:toggle-full-screen', => atom.toggleFullScreen()
|
@subscribeToCommand $(window), 'window:toggle-full-screen', => atom.toggleFullScreen()
|
||||||
|
|
||||||
@subscribeToCommand $(window), 'window:close', => atom.close()
|
@subscribeToCommand $(window), 'window:close', => atom.close()
|
||||||
|
|
||||||
@subscribeToCommand $(window), 'window:reload', =>
|
@subscribeToCommand $(window), 'window:reload', =>
|
||||||
@reloadRequested = true
|
@reloadRequested = true
|
||||||
atom.reload()
|
atom.reload()
|
||||||
|
|
||||||
@subscribeToCommand $(window), 'window:toggle-dev-tools', => atom.toggleDevTools()
|
@subscribeToCommand $(window), 'window:toggle-dev-tools', => atom.toggleDevTools()
|
||||||
|
|
||||||
@subscribeToCommand $(document), 'core:focus-next', @focusNext
|
@subscribeToCommand $(document), 'core:focus-next', @focusNext
|
||||||
|
|
||||||
@subscribeToCommand $(document), 'core:focus-previous', @focusPrevious
|
@subscribeToCommand $(document), 'core:focus-previous', @focusPrevious
|
||||||
|
|
||||||
@subscribe $(document), 'keydown', keymap.handleKeyEvent
|
@subscribe $(document), 'keydown', atom.keymap.handleKeyEvent
|
||||||
|
|
||||||
|
@subscribe $(document), 'drop', (e) ->
|
||||||
|
e.preventDefault()
|
||||||
|
e.stopPropagation()
|
||||||
|
pathsToOpen = _.pluck(e.originalEvent.dataTransfer.files, 'path')
|
||||||
|
atom.open({pathsToOpen}) if pathsToOpen.length > 0
|
||||||
|
|
||||||
@subscribe $(document), 'drop', onDrop
|
|
||||||
@subscribe $(document), 'dragover', (e) ->
|
@subscribe $(document), 'dragover', (e) ->
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
@ -54,7 +70,7 @@ class WindowEventHandler
|
|||||||
openLink: (event) =>
|
openLink: (event) =>
|
||||||
location = $(event.target).attr('href')
|
location = $(event.target).attr('href')
|
||||||
if location and location[0] isnt '#' and /^https?:\/\//.test(location)
|
if location and location[0] isnt '#' and /^https?:\/\//.test(location)
|
||||||
require('shell').openExternal(location)
|
shell.openExternal(location)
|
||||||
false
|
false
|
||||||
|
|
||||||
eachTabIndexedElement: (callback) ->
|
eachTabIndexedElement: (callback) ->
|
||||||
|
@ -1,17 +1,9 @@
|
|||||||
fsUtils = require './fs-utils'
|
|
||||||
path = require 'path'
|
path = require 'path'
|
||||||
telepath = require 'telepath'
|
|
||||||
$ = require './jquery-extensions'
|
$ = require './jquery-extensions'
|
||||||
_ = require './underscore-extensions'
|
_ = require './underscore-extensions'
|
||||||
remote = require 'remote'
|
|
||||||
ipc = require 'ipc'
|
ipc = require 'ipc'
|
||||||
WindowEventHandler = require './window-event-handler'
|
WindowEventHandler = require './window-event-handler'
|
||||||
|
|
||||||
deserializers = {}
|
|
||||||
deferredDeserializers = {}
|
|
||||||
defaultWindowDimensions = {width: 800, height: 600}
|
|
||||||
lessCache = null
|
|
||||||
|
|
||||||
### Internal ###
|
### Internal ###
|
||||||
|
|
||||||
windowEventHandler = null
|
windowEventHandler = null
|
||||||
@ -28,19 +20,13 @@ displayWindow = ->
|
|||||||
# This method is called in any window needing a general environment, including specs
|
# This method is called in any window needing a general environment, including specs
|
||||||
window.setUpEnvironment = (windowMode) ->
|
window.setUpEnvironment = (windowMode) ->
|
||||||
atom.windowMode = windowMode
|
atom.windowMode = windowMode
|
||||||
window.resourcePath = remote.getCurrentWindow().loadSettings.resourcePath
|
window.resourcePath = atom.getLoadSettings().resourcePath
|
||||||
|
atom.initialize()
|
||||||
Config = require './config'
|
#TODO remove once all packages use the atom global
|
||||||
Syntax = require './syntax'
|
window.config = atom.config
|
||||||
Pasteboard = require './pasteboard'
|
window.syntax = atom.syntax
|
||||||
Keymap = require './keymap'
|
window.pasteboard = atom.pasteboard
|
||||||
|
window.keymap = atom.keymap
|
||||||
window.rootViewParentSelector = 'body'
|
|
||||||
window.config = new Config
|
|
||||||
window.syntax = deserialize(atom.getWindowState('syntax')) ? new Syntax
|
|
||||||
window.pasteboard = new Pasteboard
|
|
||||||
window.keymap = new Keymap()
|
|
||||||
|
|
||||||
|
|
||||||
# Set up the default event handlers and menus for a non-editor windows.
|
# Set up the default event handlers and menus for a non-editor windows.
|
||||||
#
|
#
|
||||||
@ -50,8 +36,8 @@ window.setUpEnvironment = (windowMode) ->
|
|||||||
# This should only be called after setUpEnvironment() has been called.
|
# This should only be called after setUpEnvironment() has been called.
|
||||||
window.setUpDefaultEvents = ->
|
window.setUpDefaultEvents = ->
|
||||||
windowEventHandler = new WindowEventHandler
|
windowEventHandler = new WindowEventHandler
|
||||||
keymap.loadBundledKeymaps()
|
atom.keymap.loadBundledKeymaps()
|
||||||
ipc.sendChannel 'update-application-menu', keymap.keystrokesByCommandForSelector('body')
|
ipc.sendChannel 'update-application-menu', atom.keymap.keystrokesByCommandForSelector('body')
|
||||||
|
|
||||||
# This method is only called when opening a real application window
|
# This method is only called when opening a real application window
|
||||||
window.startEditorWindow = ->
|
window.startEditorWindow = ->
|
||||||
@ -60,16 +46,16 @@ window.startEditorWindow = ->
|
|||||||
|
|
||||||
windowEventHandler = new WindowEventHandler
|
windowEventHandler = new WindowEventHandler
|
||||||
restoreDimensions()
|
restoreDimensions()
|
||||||
config.load()
|
atom.config.load()
|
||||||
keymap.loadBundledKeymaps()
|
atom.keymap.loadBundledKeymaps()
|
||||||
atom.loadBaseStylesheets()
|
atom.themes.loadBaseStylesheets()
|
||||||
atom.loadPackages()
|
atom.packages.loadPackages()
|
||||||
atom.loadThemes()
|
atom.themes.load()
|
||||||
deserializeEditorWindow()
|
deserializeEditorWindow()
|
||||||
atom.activatePackages()
|
atom.packages.activatePackages()
|
||||||
keymap.loadUserKeymaps()
|
atom.keymap.loadUserKeymaps()
|
||||||
atom.requireUserInitScript()
|
atom.requireUserInitScript()
|
||||||
ipc.sendChannel 'update-application-menu', keymap.keystrokesByCommandForSelector('body')
|
ipc.sendChannel 'update-application-menu', atom.keymap.keystrokesByCommandForSelector('body')
|
||||||
$(window).on 'unload', ->
|
$(window).on 'unload', ->
|
||||||
$(document.body).hide()
|
$(document.body).hide()
|
||||||
unloadEditorWindow()
|
unloadEditorWindow()
|
||||||
@ -78,188 +64,58 @@ window.startEditorWindow = ->
|
|||||||
displayWindow()
|
displayWindow()
|
||||||
|
|
||||||
window.unloadEditorWindow = ->
|
window.unloadEditorWindow = ->
|
||||||
return if not project and not rootView
|
return if not atom.project and not atom.rootView
|
||||||
windowState = atom.getWindowState()
|
windowState = atom.getWindowState()
|
||||||
windowState.set('project', project.serialize())
|
windowState.set('project', atom.project.serialize())
|
||||||
windowState.set('syntax', syntax.serialize())
|
windowState.set('syntax', atom.syntax.serialize())
|
||||||
windowState.set('rootView', rootView.serialize())
|
windowState.set('rootView', atom.rootView.serialize())
|
||||||
atom.deactivatePackages()
|
atom.packages.deactivatePackages()
|
||||||
windowState.set('packageStates', atom.packageStates)
|
windowState.set('packageStates', atom.packages.packageStates)
|
||||||
atom.saveWindowState()
|
atom.saveWindowState()
|
||||||
rootView.remove()
|
atom.rootView.remove()
|
||||||
project.destroy()
|
atom.project.destroy()
|
||||||
windowEventHandler?.unsubscribe()
|
windowEventHandler?.unsubscribe()
|
||||||
lessCache?.destroy()
|
|
||||||
window.rootView = null
|
window.rootView = null
|
||||||
window.project = null
|
window.project = null
|
||||||
|
|
||||||
window.installAtomCommand = (callback) ->
|
installAtomCommand = (callback) ->
|
||||||
commandPath = path.join(window.resourcePath, 'atom.sh')
|
commandPath = path.join(window.resourcePath, 'atom.sh')
|
||||||
require('./command-installer').install(commandPath, callback)
|
require('./command-installer').install(commandPath, callback)
|
||||||
|
|
||||||
window.installApmCommand = (callback) ->
|
installApmCommand = (callback) ->
|
||||||
commandPath = path.join(window.resourcePath, 'node_modules', '.bin', 'apm')
|
commandPath = path.join(window.resourcePath, 'node_modules', '.bin', 'apm')
|
||||||
require('./command-installer').install(commandPath, callback)
|
require('./command-installer').install(commandPath, callback)
|
||||||
|
|
||||||
window.onDrop = (e) ->
|
|
||||||
e.preventDefault()
|
|
||||||
e.stopPropagation()
|
|
||||||
pathsToOpen = _.pluck(e.originalEvent.dataTransfer.files, 'path')
|
|
||||||
atom.open({pathsToOpen}) if pathsToOpen.length > 0
|
|
||||||
|
|
||||||
window.deserializeEditorWindow = ->
|
window.deserializeEditorWindow = ->
|
||||||
RootView = require './root-view'
|
atom.deserializePackageStates()
|
||||||
Project = require './project'
|
atom.deserializeProject()
|
||||||
|
window.project = atom.project
|
||||||
|
atom.deserializeRootView()
|
||||||
|
window.rootView = atom.rootView
|
||||||
|
|
||||||
windowState = atom.getWindowState()
|
window.getDimensions = -> atom.getDimensions()
|
||||||
|
|
||||||
atom.packageStates = windowState.getObject('packageStates') ? {}
|
window.setDimensions = (args...) -> atom.setDimensions(args...)
|
||||||
windowState.remove('packageStates')
|
|
||||||
|
|
||||||
window.project = deserialize(windowState.get('project'))
|
window.restoreDimensions = (args...) -> atom.restoreDimensions(args...)
|
||||||
unless window.project?
|
|
||||||
window.project = new Project(atom.getLoadSettings().initialPath)
|
|
||||||
windowState.set('project', window.project.getState())
|
|
||||||
|
|
||||||
window.rootView = deserialize(windowState.get('rootView'))
|
|
||||||
unless window.rootView?
|
|
||||||
window.rootView = new RootView()
|
|
||||||
windowState.set('rootView', window.rootView.getState())
|
|
||||||
|
|
||||||
$(rootViewParentSelector).append(rootView)
|
|
||||||
|
|
||||||
project.on 'path-changed', ->
|
|
||||||
projectPath = project.getPath()
|
|
||||||
atom.getLoadSettings().initialPath = projectPath
|
|
||||||
|
|
||||||
window.stylesheetElementForId = (id) ->
|
|
||||||
$("""head style[id="#{id}"]""")
|
|
||||||
|
|
||||||
window.resolveStylesheet = (stylesheetPath) ->
|
|
||||||
if path.extname(stylesheetPath).length > 0
|
|
||||||
fsUtils.resolveOnLoadPath(stylesheetPath)
|
|
||||||
else
|
|
||||||
fsUtils.resolveOnLoadPath(stylesheetPath, ['css', 'less'])
|
|
||||||
|
|
||||||
# Public: resolves and applies the stylesheet specified by the path.
|
|
||||||
#
|
|
||||||
# * stylesheetPath: String. Can be an absolute path or the name of a CSS or
|
|
||||||
# LESS file in the stylesheets path.
|
|
||||||
#
|
|
||||||
# Returns the absolute path to the stylesheet
|
|
||||||
window.requireStylesheet = (stylesheetPath) ->
|
|
||||||
if fullPath = window.resolveStylesheet(stylesheetPath)
|
|
||||||
content = window.loadStylesheet(fullPath)
|
|
||||||
window.applyStylesheet(fullPath, content)
|
|
||||||
else
|
|
||||||
throw new Error("Could not find a file at path '#{stylesheetPath}'")
|
|
||||||
|
|
||||||
fullPath
|
|
||||||
|
|
||||||
window.loadStylesheet = (stylesheetPath) ->
|
|
||||||
if path.extname(stylesheetPath) is '.less'
|
|
||||||
loadLessStylesheet(stylesheetPath)
|
|
||||||
else
|
|
||||||
fsUtils.read(stylesheetPath)
|
|
||||||
|
|
||||||
window.loadLessStylesheet = (lessStylesheetPath) ->
|
|
||||||
unless lessCache?
|
|
||||||
LessCompileCache = require './less-compile-cache'
|
|
||||||
lessCache = new LessCompileCache()
|
|
||||||
|
|
||||||
try
|
|
||||||
lessCache.read(lessStylesheetPath)
|
|
||||||
catch e
|
|
||||||
console.error """
|
|
||||||
Error compiling less stylesheet: #{lessStylesheetPath}
|
|
||||||
Line number: #{e.line}
|
|
||||||
#{e.message}
|
|
||||||
"""
|
|
||||||
|
|
||||||
window.removeStylesheet = (stylesheetPath) ->
|
|
||||||
unless fullPath = window.resolveStylesheet(stylesheetPath)
|
|
||||||
throw new Error("Could not find a file at path '#{stylesheetPath}'")
|
|
||||||
window.stylesheetElementForId(fullPath).remove()
|
|
||||||
|
|
||||||
window.applyStylesheet = (id, text, ttype = 'bundled') ->
|
|
||||||
styleElement = window.stylesheetElementForId(id)
|
|
||||||
if styleElement.length
|
|
||||||
styleElement.text(text)
|
|
||||||
else
|
|
||||||
if $("head style.#{ttype}").length
|
|
||||||
$("head style.#{ttype}:last").after "<style class='#{ttype}' id='#{id}'>#{text}</style>"
|
|
||||||
else
|
|
||||||
$("head").append "<style class='#{ttype}' id='#{id}'>#{text}</style>"
|
|
||||||
|
|
||||||
window.getDimensions = ->
|
|
||||||
browserWindow = remote.getCurrentWindow()
|
|
||||||
[x, y] = browserWindow.getPosition()
|
|
||||||
[width, height] = browserWindow.getSize()
|
|
||||||
{x, y, width, height}
|
|
||||||
|
|
||||||
window.setDimensions = ({x, y, width, height}) ->
|
|
||||||
browserWindow = remote.getCurrentWindow()
|
|
||||||
browserWindow.setSize(width, height)
|
|
||||||
if x? and y?
|
|
||||||
browserWindow.setPosition(x, y)
|
|
||||||
else
|
|
||||||
browserWindow.center()
|
|
||||||
|
|
||||||
window.restoreDimensions = ->
|
|
||||||
dimensions = atom.getWindowState().getObject('dimensions')
|
|
||||||
dimensions = defaultWindowDimensions unless dimensions?.width and dimensions?.height
|
|
||||||
window.setDimensions(dimensions)
|
|
||||||
$(window).on 'unload', -> atom.getWindowState().set('dimensions', window.getDimensions())
|
|
||||||
|
|
||||||
window.onerror = ->
|
window.onerror = ->
|
||||||
atom.openDevTools()
|
atom.openDevTools()
|
||||||
|
|
||||||
window.registerDeserializers = (args...) ->
|
window.registerDeserializers = (args...) ->
|
||||||
registerDeserializer(arg) for arg in args
|
atom.deserializers.registerDeserializer(args...)
|
||||||
|
window.registerDeserializer = (args...) ->
|
||||||
window.registerDeserializer = (klass) ->
|
atom.deserializers.registerDeserializer(args...)
|
||||||
deserializers[klass.name] = klass
|
window.registerDeferredDeserializer = (args...) ->
|
||||||
|
atom.deserializers.registerDeferredDeserializer(args...)
|
||||||
window.registerDeferredDeserializer = (name, fn) ->
|
window.unregisterDeserializer = (args...) ->
|
||||||
deferredDeserializers[name] = fn
|
atom.deserializers.unregisterDeserializer(args...)
|
||||||
|
window.deserialize = (args...) ->
|
||||||
window.unregisterDeserializer = (klass) ->
|
atom.deserializers.deserialize(args...)
|
||||||
delete deserializers[klass.name]
|
window.getDeserializer = (args...) ->
|
||||||
|
atom.deserializer.getDeserializer(args...)
|
||||||
window.deserialize = (state, params) ->
|
window.requireWithGlobals = (args...) ->
|
||||||
return unless state?
|
atom.requireWithGlobals(args...)
|
||||||
if deserializer = getDeserializer(state)
|
|
||||||
stateVersion = state.get?('version') ? state.version
|
|
||||||
return if deserializer.version? and deserializer.version isnt stateVersion
|
|
||||||
if (state instanceof telepath.Document) and not deserializer.acceptsDocuments
|
|
||||||
state = state.toObject()
|
|
||||||
deserializer.deserialize(state, params)
|
|
||||||
else
|
|
||||||
console.warn "No deserializer found for", state
|
|
||||||
|
|
||||||
window.getDeserializer = (state) ->
|
|
||||||
return unless state?
|
|
||||||
|
|
||||||
name = state.get?('deserializer') ? state.deserializer
|
|
||||||
if deferredDeserializers[name]
|
|
||||||
deferredDeserializers[name]()
|
|
||||||
delete deferredDeserializers[name]
|
|
||||||
|
|
||||||
deserializers[name]
|
|
||||||
|
|
||||||
window.requireWithGlobals = (id, globals={}) ->
|
|
||||||
existingGlobals = {}
|
|
||||||
for key, value of globals
|
|
||||||
existingGlobals[key] = window[key]
|
|
||||||
window[key] = value
|
|
||||||
|
|
||||||
require(id)
|
|
||||||
|
|
||||||
for key, value of existingGlobals
|
|
||||||
if value is undefined
|
|
||||||
delete window[key]
|
|
||||||
else
|
|
||||||
window[key] = value
|
|
||||||
|
|
||||||
window.measure = (description, fn) ->
|
window.measure = (description, fn) ->
|
||||||
start = new Date().getTime()
|
start = new Date().getTime()
|
||||||
|
Loading…
Reference in New Issue
Block a user