Comparar commits

...

70 Commits

Autor SHA1 Mensagem Data
Nathan Sobo 7e59be6461 Use atom.views.getView in WorkspaceView to preserve previous behavior
The status-bar package specs were calling atom.views.getView with the
workspace model *prior* to instantiating the SpacePen view. A weird
case, but might as well leave it working so the deprecation shim is
perfect.
2014-11-30 18:43:50 -07:00
Nathan Sobo 81422d71cb 📝 Publicize and document WorkspaceElement 2014-11-30 18:33:22 -07:00
Nathan Sobo fa242dca7a 📝 Update ViewFactory API docs 2014-11-30 18:21:31 -07:00
Nathan Sobo 2ac15bad90 Return views created via atom.views.createView from atom.views.getView
The .getView method is deprecated, but this is required to maintain the
spirit of the old behavior for now.
2014-11-30 18:06:06 -07:00
Nathan Sobo 1e6e724be7 Deprecate atom.views.getView and store view registry on WorkspaceElement
This separates the role of the ViewFactory from the ViewRegistry.
The ViewFactory creates *new* views. The ViewRegistry maintains a
persistent 1:1 mapping from models to views, and is owned by the
workspace rather than being a global service. If someone wants to 
*create* a view, they use atom.views.createView. If someone wants to
get the workspace’s view element for a given model, they call .getView
on the workspace.
2014-11-30 17:12:35 -07:00
Nathan Sobo 05e7e9fc1d Rename ViewRegistry to ViewFactory
The new ViewRegistry will be focused only on storing model::view
associations, leaving the global factory to focus on creating them.
2014-11-30 15:49:49 -07:00
Nathan Sobo 80c354aad4 💄 2014-11-30 15:44:26 -07:00
Nathan Sobo aa5c09cf0b Log a deprecation warning when models still implement .getViewClass 2014-11-30 15:43:33 -07:00
Nathan Sobo d79ca646a8 Allow params to be passed to ViewRegistry::createView
Now we call initialize on the created view instead of setModel, which
emphasizes the fact that it’s only called once and allows arbitrary
properties to be passed through during creation.
2014-11-30 15:42:14 -07:00
Nathan Sobo d8137cfcad Remove view registry references from the workspace model layer
Removed various ::getView methods from the model. Using the atom.views
global in the views for now, but going to switch them over to using a
locally assigned view registry instead in a subsequent commit.
2014-11-30 14:47:51 -07:00
Max Brunsfeld 12683571e3 ⬆️ language-coffee-script@0.38.1 2014-11-29 10:34:31 -08:00
Max Brunsfeld c0991447ff ⬆️ language-css@0.23.1 2014-11-29 10:33:16 -08:00
Max Brunsfeld f9fcb9f2e2 ⬆️ language-gfm@0.54.1 2014-11-29 10:31:59 -08:00
Max Brunsfeld 1daab1b956 ⬆️ language-go@0.19.1 2014-11-29 10:29:33 -08:00
Max Brunsfeld fc7f922de0 ⬆️ language-html@0.26.1 2014-11-29 10:27:39 -08:00
Max Brunsfeld 5f1f2cd9be ⬆️ language-hyperlink@0.12.2 2014-11-29 10:25:01 -08:00
Max Brunsfeld dca0576496 ⬆️ language-javascript@0.45.1 2014-11-29 10:21:37 -08:00
Max Brunsfeld aa7d8fb382 ⬆️ language-less@0.18.1 2014-11-29 10:20:05 -08:00
Max Brunsfeld 08f20adc35 ⬆️ language-mustache@0.10.1 2014-11-29 09:55:43 -08:00
Max Brunsfeld c5f1165f61 ⬆️ language-python@0.24.1 2014-11-29 09:53:01 -08:00
Max Brunsfeld 58499aeec7 ⬆️ language-ruby@0.42.0 2014-11-29 09:49:07 -08:00
Max Brunsfeld 83c73fc94a ⬆️ language-sass@0.26.1 2014-11-29 09:46:16 -08:00
Max Brunsfeld b28a1aa5c7 ⬆️ language-shellscript@0.10.1 2014-11-28 16:51:24 -08:00
Max Brunsfeld bcb72394f9 ⬆️ language-toml@0.14.1 2014-11-28 16:48:58 -08:00
Max Brunsfeld efe7baf140 ⬆️ language-yaml@0.20.1 2014-11-28 16:40:11 -08:00
Max Brunsfeld 4b07103fcf ⬆️ pathwatcher@2.3.5 2014-11-28 16:38:54 -08:00
Max Brunsfeld 9d60fd2322 Deprecate changeFocus option to Workspace::open
Its documentation was already removed, and it was already
deprecated in ::openSync.
2014-11-28 11:42:01 -08:00
Max Brunsfeld 71228a5f45 Merge pull request #4340 from atom/mb-add-panel-getters
Add panel getter methods to workspace
2014-11-28 10:05:35 -08:00
Max Brunsfeld 6b3ba8e332 Add panel getter methods to workspace
This will make it easier to test packages that use panels
without using the DOM
2014-11-28 09:56:02 -08:00
Nathan Sobo de619a731b Merge pull request #4315 from atom/remove-deprecations
Remove deprecations from core
2014-11-27 12:16:35 -07:00
Nathan Sobo d2283b0567 ⬆️ text-buffer 2014-11-27 11:59:07 -07:00
Nathan Sobo 2a00acfdaf Remove call to begin/commitTransaction in text-editor-spec 2014-11-27 11:58:38 -07:00
Nathan Sobo b2025ebad0 Don’t openPath on window startup for spec windows
It causes specs to fail because the window loses focus somehow when
this gets run.
2014-11-27 11:13:46 -07:00
Nathan Sobo 0b44cee8db Separate IPC messages that don’t belong in the command palette
Path opening and update signaling were both using the command-sending
IPC mechanism, but neither is actually a command. This commit adds a
second “message” channel with custom handling on the render process
side for these messages, rather than attempting to route them through
commands.
2014-11-27 10:30:50 -07:00
Nathan Sobo 5fed6199ec 💄 grammar 2014-11-27 09:23:35 -07:00
Nathan Sobo ddc04f2278 Fix spec name 2014-11-27 09:11:21 -07:00
Nathan Sobo f64a813fc6 Remove deprecated Project::setPath call 2014-11-27 09:09:33 -07:00
Nathan Sobo 68bc3f6ead Add assertions and suppress deprecation warnings in theme-manager-spec
The new expected behavior is now tested. The deprecated behavior is
also tested until we remove it later.
2014-11-27 09:03:40 -07:00
Nathan Sobo ffbcddf063 Always focus pane element when pane model is activated
Signed-off-by: Max Brunsfeld <maxbrunsfeld@gmail.com>
2014-11-26 18:25:55 -07:00
Nathan Sobo b341749d54 Add TextEditorElement::setUpdatedSynchronously
To allow testing of async editor rendering in packages. This is helpful
for overlay decorations which behave differently when rendering is
async.

Signed-off-by: Max Brunsfeld <maxbrunsfeld@gmail.com>
2014-11-26 18:13:12 -07:00
Max Brunsfeld d2ab75382a Merge pull request #4328 from atom/mb-fix-panel-attach-callbacks
In panel-element, call space pen attach hooks after attached
2014-11-26 16:20:29 -08:00
Max Brunsfeld b125565776 Call space pen attach hooks after attached 2014-11-26 15:09:20 -08:00
Ben Ogle 9cec02420c Suppress deprecations while testing legacy code path 2014-11-26 14:55:40 -08:00
Ben Ogle 6f82281b8f Use Project::getPaths() and Project::setPaths() 2014-11-26 14:55:40 -08:00
Ben Ogle ffda2386c3 Suppress deprecations for package loading. 2014-11-26 14:55:40 -08:00
Ben Ogle aefc647155 Use normalizeLineEndings: false hash 2014-11-26 14:55:39 -08:00
Ben Ogle 83455a7f3a Remove specs for deprecated methods that are tested elsewhere 2014-11-26 14:55:39 -08:00
Ben Ogle d8f64c15b8 Use project.getDirectories() 2014-11-26 14:55:39 -08:00
Ben Ogle c927e95c2c Suppress deprecations on pane-view
It’s going away anyway…
2014-11-26 14:55:39 -08:00
Ben Ogle 5b12646a44 Suppress deprecations on deprecated code path 2014-11-26 14:55:39 -08:00
Ben Ogle 68bb43ee7d Add onDidChangeTitle and onDidChangeModified methods to TestView 2014-11-26 14:55:39 -08:00
Ben Ogle 4048fb978c Suppress deprecations for package activation 2014-11-26 14:55:39 -08:00
Ben Ogle 2d885496a3 Update to new menu format 2014-11-26 14:55:39 -08:00
Ben Ogle 64222d3096 Suppress deprecations in configDefault test 2014-11-26 14:55:39 -08:00
Ben Ogle 2c7bbf8e9f Remove Project deserialize deprecation 2014-11-26 14:55:39 -08:00
Ben Ogle a45e9a1e8b Remove deprecations in config 2014-11-26 14:55:39 -08:00
Ben Ogle 3fd5ba9b3c Remove unnecessary workspaceView requires 2014-11-26 14:55:39 -08:00
Ben Ogle eb0e3df720 Suppress deprecations in workspaceView 2014-11-26 14:55:39 -08:00
Ben Ogle 60a49d9c81 nof 2014-11-26 14:55:39 -08:00
Ben Ogle 43ccf0a041 Convert require ‘atom’ to require '../src/space-pen-extensions' 2014-11-26 14:55:38 -08:00
Ben Ogle 1f6764e708 No longer require atom in the spec-helper 2014-11-26 14:55:38 -08:00
Ben Ogle 48f714d5fb Fix deprecation link colors 2014-11-26 14:54:49 -08:00
Nathan Sobo e2813b4dd9 📝 overlay decoration options in TextEditor::decorateMarker 2014-11-26 15:14:56 -07:00
Nathan Sobo 41b3d65e05 Merge pull request #4325 from atom/ns-tail-overlays
Add ‘position’ option to overlay decorations
2014-11-26 15:02:36 -07:00
Nathan Sobo 1e50985ec7 Add ‘position’ option to overlay decorations
By default overlays are positioned at the head of the given marker.
This option allows them to be positioned at the tail instead by passing
`position: ’tail’` when creating the decoration, which is useful for 
autocomplete.
2014-11-26 12:29:52 -07:00
Nathan Sobo 1d6087fcd3 Add TextEditor::getDecorations and ::getOverlayDecorations
Required for autocomplete upgrades.

Signed-off-by: Max Brunsfeld <maxbrunsfeld@gmail.com>
2014-11-26 12:17:26 -07:00
Ben Ogle f2e74f216c Upgrade to solarized-dark-syntax to update to standard colors 2014-11-26 11:09:04 -08:00
Nathan Sobo b9950ef2df Match coordinate types when computing overlay pixel position
Heads up @benogle
2014-11-26 09:28:12 -07:00
Nathan Sobo 28eb03ed29 ⬆️ command-palette to fix exception on call to ::command
Fixes #4318
2014-11-25 20:49:17 -07:00
Ben Ogle 2843af458b Merge pull request #4307 from atom/bo-add-parse-errors
Integrate notifications into core
2014-11-25 15:59:37 -08:00
64 arquivos alterados com 778 adições e 525 exclusões
+2 -1
Ver Arquivo
@@ -1,7 +1,8 @@
require '../spec/spec-helper'
path = require 'path'
{$, Point} = require 'atom'
{$} = require '../src/space-pen-extensions'
{Point} = require 'atom'
_ = require 'underscore-plus'
fs = require 'fs-plus'
Project = require '../src/project'
+4 -2
Ver Arquivo
@@ -1,5 +1,7 @@
require './benchmark-helper'
{$, _, WorkspaceView} = require 'atom'
{$} = require '../src/space-pen-extensions'
_ = require 'underscore-plus'
{WorkspaceView} = require 'atom'
TokenizedBuffer = require '../src/tokenized-buffer'
describe "editorView.", ->
@@ -7,7 +9,7 @@ describe "editorView.", ->
beforeEach ->
atom.workspaceViewParentSelector = '#jasmine-content'
atom.workspaceView = atom.views.getView(atom.workspace).__spacePenView
atom.workspaceView = atom.views.createView(atom.workspace).__spacePenView
atom.workspaceView.attachToDom()
atom.workspaceView.width(1024)
+2 -1
Ver Arquivo
@@ -33,7 +33,8 @@ unless process.env.ATOM_SHELL_INTERNAL_RUN_AS_NODE
Object.defineProperty module.exports, 'WorkspaceView', get: ->
deprecate """
Requiring `WorkspaceView` from `atom` is no longer supported.
Use `atom.views.getView(atom.workspace)` instead.
Use `document.querySelector('atom-workspace')` if you need to access
the workspace element.
"""
require '../src/workspace-view'
+19 -19
Ver Arquivo
@@ -45,7 +45,7 @@
"nslog": "^1.0.1",
"oniguruma": "^3.0.4",
"optimist": "0.4.0",
"pathwatcher": "2.3.2",
"pathwatcher": "^2.3.5",
"property-accessors": "^1",
"q": "^1.0.1",
"random-words": "0.0.1",
@@ -60,7 +60,7 @@
"serializable": "^1",
"space-pen": "3.8.2",
"temp": "0.7.0",
"text-buffer": "^3.7.2",
"text-buffer": "^3.8.0",
"theorist": "^1.0.2",
"underscore-plus": "^1.6.1",
"vm-compatibility-layer": "0.1.0"
@@ -72,7 +72,7 @@
"atom-light-ui": "0.36.0",
"base16-tomorrow-dark-theme": "0.22.0",
"base16-tomorrow-light-theme": "0.5.0",
"solarized-dark-syntax": "0.23.0",
"solarized-dark-syntax": "0.24.0",
"solarized-light-syntax": "0.13.0",
"archive-view": "0.37.0",
"autocomplete": "0.33.1",
@@ -81,7 +81,7 @@
"background-tips": "0.17.0",
"bookmarks": "0.30.0",
"bracket-matcher": "0.62.0",
"command-palette": "0.28.0",
"command-palette": "0.29.0",
"deprecation-cop": "0.18.0",
"dev-live-reload": "0.35.0",
"encoding-selector": "0.8.0",
@@ -115,35 +115,35 @@
"whitespace": "0.26.0",
"wrap-guide": "0.24.0",
"language-c": "0.31.0",
"language-coffee-script": "0.38.0",
"language-css": "0.23.0",
"language-gfm": "0.54.0",
"language-coffee-script": "0.38.1",
"language-css": "0.23.1",
"language-gfm": "0.54.1",
"language-git": "0.9.0",
"language-go": "0.19.0",
"language-html": "0.26.0",
"language-hyperlink": "0.12.0",
"language-go": "0.19.1",
"language-html": "0.26.1",
"language-hyperlink": "0.12.2",
"language-java": "0.11.0",
"language-javascript": "0.45.0",
"language-javascript": "0.45.1",
"language-json": "0.8.0",
"language-less": "0.18.0",
"language-less": "0.18.1",
"language-make": "0.12.0",
"language-mustache": "0.10.0",
"language-mustache": "0.10.1",
"language-objective-c": "0.11.0",
"language-perl": "0.9.0",
"language-php": "0.18.0",
"language-property-list": "0.7.0",
"language-python": "0.24.0",
"language-ruby": "0.41.0",
"language-python": "0.24.1",
"language-ruby": "0.42.0",
"language-ruby-on-rails": "0.18.0",
"language-sass": "0.26.0",
"language-shellscript": "0.10.0",
"language-sass": "0.26.1",
"language-shellscript": "0.10.1",
"language-source": "0.8.0",
"language-sql": "0.11.0",
"language-text": "0.6.0",
"language-todo": "0.13.0",
"language-toml": "0.14.0",
"language-toml": "0.14.1",
"language-xml": "0.25.0",
"language-yaml": "0.20.0"
"language-yaml": "0.20.1"
},
"private": true,
"scripts": {
+1 -1
Ver Arquivo
@@ -1,4 +1,4 @@
{$} = require 'atom'
{$} = require '../src/space-pen-extensions'
describe '"atom" protocol URL', ->
it 'sends the file relative in the package as response', ->
+12 -9
Ver Arquivo
@@ -1,4 +1,4 @@
{$, $$, WorkspaceView} = require 'atom'
{$, $$} = require '../src/space-pen-extensions'
Exec = require('child_process').exec
path = require 'path'
Package = require '../src/package'
@@ -30,13 +30,16 @@ describe "the `atom` global", ->
version = '36b5518'
expect(atom.isReleasedVersion()).toBe false
describe "window:update-available", ->
it "is triggered when the auto-updater sends the update-downloaded event", ->
# FIXME: We need to figure out a way minus workspaceView to handle update-available events.
atom.workspaceView = atom.views.getView(atom.workspace).__spacePenView
describe "when an update becomes available", ->
subscription = null
afterEach ->
subscription?.dispose()
it "invokes onUpdateAvailable listeners", ->
updateAvailableHandler = jasmine.createSpy("update-available-handler")
atom.workspaceView.on 'window:update-available', updateAvailableHandler
subscription = atom.onUpdateAvailable updateAvailableHandler
autoUpdater = require('remote').require('auto-updater')
autoUpdater.emit 'update-downloaded', null, "notes", "version"
@@ -44,9 +47,9 @@ describe "the `atom` global", ->
updateAvailableHandler.callCount > 0
runs ->
[event, version, notes] = updateAvailableHandler.mostRecentCall.args
expect(notes).toBe 'notes'
expect(version).toBe 'version'
{releaseVersion, releaseNotes} = updateAvailableHandler.mostRecentCall.args[0]
expect(releaseVersion).toBe 'version'
expect(releaseNotes).toBe 'notes'
describe "loading default config", ->
it 'loads the default core config', ->
+13 -1
Ver Arquivo
@@ -128,6 +128,12 @@ describe "Config", ->
expect(atom.config.get("foo")).toEqual 'a\\.b': 1, b: 2
describe ".toggle(keyPath)", ->
beforeEach ->
jasmine.snapshotDeprecations()
afterEach ->
jasmine.restoreDeprecationsSnapshot()
it "negates the boolean value of the current key path value", ->
atom.config.set('foo.a', 1)
atom.config.toggle('foo.a')
@@ -298,6 +304,12 @@ describe "Config", ->
expect(observeHandler).toHaveBeenCalledWith atom.config.get("foo.bar.baz")
describe ".getPositiveInt(keyPath, defaultValue)", ->
beforeEach ->
jasmine.snapshotDeprecations()
afterEach ->
jasmine.restoreDeprecationsSnapshot()
it "returns the proper coerced value", ->
atom.config.set('editor.preferredLineLength', 0)
expect(atom.config.getPositiveInt('editor.preferredLineLength', 80)).toBe 1
@@ -470,7 +482,7 @@ describe "Config", ->
it "does not fire the callback once the observe subscription is off'ed", ->
observeHandler.reset() # clear the initial call
observeSubscription.off()
observeSubscription.dispose()
atom.config.set('foo.bar.baz', "value 2")
expect(observeHandler).not.toHaveBeenCalled()
+28 -21
Ver Arquivo
@@ -1,4 +1,4 @@
{$$} = require 'atom'
{$$} = require '../src/space-pen-extensions'
ContextMenuManager = require '../src/context-menu-manager'
@@ -151,24 +151,31 @@ describe "ContextMenuManager", ->
shouldDisplay = false
expect(contextMenu.templateForEvent(dispatchedEvent)).toEqual []
it "allows items to be specified in the legacy format for now", ->
contextMenu.add '.parent':
'A': 'a'
'Separator 1': '-'
'B':
'C': 'c'
'Separator 2': '-'
'D': 'd'
describe "when the menus are specified in a legacy format", ->
beforeEach ->
jasmine.snapshotDeprecations()
expect(contextMenu.templateForElement(parent)).toEqual [
{label: 'A', command: 'a'}
{type: 'separator'}
{
label: 'B'
submenu: [
{label: 'C', command: 'c'}
{type: 'separator'}
{label: 'D', command: 'd'}
]
}
]
afterEach ->
jasmine.restoreDeprecationsSnapshot()
it "allows items to be specified in the legacy format for now", ->
contextMenu.add '.parent':
'A': 'a'
'Separator 1': '-'
'B':
'C': 'c'
'Separator 2': '-'
'D': 'd'
expect(contextMenu.templateForElement(parent)).toEqual [
{label: 'A', command: 'a'}
{type: 'separator'}
{
label: 'B'
submenu: [
{label: 'C', command: 'c'}
{type: 'separator'}
{label: 'D', command: 'd'}
]
}
]
@@ -9,6 +9,6 @@ module.exports =
atom.commands.add 'atom-workspace', 'activation-command', =>
@activationCommandCallCount++
editorView = atom.views.getView(atom.workspace.getActiveEditor())?.__spacePenView
editorView = document.querySelector('atom-workspace').getView(atom.workspace.getActiveEditor())?.__spacePenView
editorView?.command 'activation-command', =>
@legacyActivationCommandCallCount++
@@ -3,5 +3,6 @@
]
'context-menu':
'.test-1':
'Menu item 1': 'command-1'
'.test-1': [
{label: 'Menu item 1', command: 'command-1'}
]
@@ -3,5 +3,6 @@
]
'context-menu':
'.test-1':
'Menu item 2': 'command-2'
'.test-1': [
{label: 'Menu item 2', command: 'command-2'}
]
@@ -1,3 +1,4 @@
'context-menu':
'.test-1':
'Menu item 3': 'command-3'
'.test-1': [
{label: 'Menu item 3', command: 'command-3'}
]
+20 -10
Ver Arquivo
@@ -1,10 +1,10 @@
{$, $$, WorkspaceView} = require 'atom'
{$, $$} = require '../src/space-pen-extensions'
Package = require '../src/package'
describe "PackageManager", ->
workspaceElement = null
beforeEach ->
workspaceElement = atom.views.getView(atom.workspace)
workspaceElement = atom.views.createView(atom.workspace)
describe "::loadPackage(name)", ->
it "continues if the package has an invalid package.json", ->
@@ -98,15 +98,23 @@ describe "PackageManager", ->
expect(atom.config.set('package-with-config-schema.numbers.one', '10')).toBe true
expect(atom.config.get('package-with-config-schema.numbers.one')).toBe 10
it "still assigns configDefaults from the module though deprecated", ->
expect(atom.config.get('package-with-config-defaults.numbers.one')).toBeUndefined()
describe "when a package has configDefaults", ->
beforeEach ->
jasmine.snapshotDeprecations()
waitsForPromise ->
atom.packages.activatePackage('package-with-config-defaults')
afterEach ->
jasmine.restoreDeprecationsSnapshot()
runs ->
expect(atom.config.get('package-with-config-defaults.numbers.one')).toBe 1
expect(atom.config.get('package-with-config-defaults.numbers.two')).toBe 2
it "still assigns configDefaults from the module though deprecated", ->
expect(atom.config.get('package-with-config-defaults.numbers.one')).toBeUndefined()
waitsForPromise ->
atom.packages.activatePackage('package-with-config-defaults')
runs ->
expect(atom.config.get('package-with-config-defaults.numbers.one')).toBe 1
expect(atom.config.get('package-with-config-defaults.numbers.two')).toBe 2
describe "when the package metadata includes `activationCommands`", ->
[mainModule, promise, workspaceCommandListener] = []
@@ -136,7 +144,7 @@ describe "PackageManager", ->
atom.workspace.open()
runs ->
editorView = atom.views.getView(atom.workspace.getActiveEditor()).__spacePenView
editorView = workspaceElement.getView(atom.workspace.getActiveEditor()).__spacePenView
legacyCommandListener = jasmine.createSpy("legacyCommandListener")
editorView.command 'activation-command', legacyCommandListener
editorCommandListener = jasmine.createSpy("editorCommandListener")
@@ -514,6 +522,7 @@ describe "PackageManager", ->
themeActivator = null
beforeEach ->
jasmine.snapshotDeprecations()
spyOn(console, 'warn')
atom.packages.loadPackages()
@@ -529,6 +538,7 @@ describe "PackageManager", ->
GrammarRegistry = require '../src/grammar-registry'
atom.grammars = window.syntax = new GrammarRegistry()
jasmine.restoreDeprecationsSnapshot()
it "activates all the packages, and none of the themes", ->
atom.packages.activate()
+1 -1
Ver Arquivo
@@ -1,4 +1,4 @@
{$} = require 'atom'
{$} = require '../src/space-pen-extensions'
path = require 'path'
Package = require '../src/package'
ThemePackage = require '../src/theme-package'
+13 -8
Ver Arquivo
@@ -3,10 +3,12 @@ temp = require 'temp'
PaneContainer = require '../src/pane-container'
PaneContainerView = require '../src/pane-container-view'
PaneView = require '../src/pane-view'
{$, View, $$} = require 'atom'
{Disposable} = require 'event-kit'
{$, View, $$} = require '../src/space-pen-extensions'
ViewRegistry = require '../src/view-registry'
describe "PaneContainerView", ->
[TestView, container, pane1, pane2, pane3, deserializerDisposable] = []
[viewRegistry, TestView, container, pane1, pane2, pane3, deserializerDisposable] = []
beforeEach ->
class TestView extends View
@@ -18,8 +20,11 @@ describe "PaneContainerView", ->
getUri: -> path.join(temp.dir, @name)
save: -> @saved = true
isEqual: (other) -> @name is other?.name
onDidChangeTitle: -> new Disposable(->)
onDidChangeModified: -> new Disposable(->)
container = atom.views.getView(atom.workspace.paneContainer).__spacePenView
viewRegistry = new ViewRegistry(atom.views)
container = atom.views.createView(atom.workspace.paneContainer, {viewRegistry}).__spacePenView
pane1 = container.getRoot()
pane1.activateItem(new TestView('1'))
pane2 = pane1.splitRight(new TestView('2'))
@@ -73,7 +78,7 @@ describe "PaneContainerView", ->
describe "serialization", ->
it "can be serialized and deserialized, and correctly adjusts dimensions of deserialized panes after attach", ->
newContainer = atom.views.getView(container.model.testSerialization()).__spacePenView
newContainer = atom.views.createView(container.model.testSerialization(), {viewRegistry}).__spacePenView
expect(newContainer.find('atom-pane-axis.horizontal > :contains(1)')).toExist()
expect(newContainer.find('atom-pane-axis.horizontal > atom-pane-axis.vertical > :contains(2)')).toExist()
expect(newContainer.find('atom-pane-axis.horizontal > atom-pane-axis.vertical > :contains(3)')).toExist()
@@ -89,14 +94,14 @@ describe "PaneContainerView", ->
describe "if the 'core.destroyEmptyPanes' config option is false (the default)", ->
it "leaves the empty panes intact", ->
newContainer = atom.views.getView(container.model.testSerialization()).__spacePenView
newContainer = atom.views.createView(container.model.testSerialization(), {viewRegistry}).__spacePenView
expect(newContainer.find('atom-pane-axis.horizontal > :contains(1)')).toExist()
expect(newContainer.find('atom-pane-axis.horizontal > atom-pane-axis.vertical > atom-pane').length).toBe 2
describe "if the 'core.destroyEmptyPanes' config option is true", ->
it "removes empty panes on deserialization", ->
atom.config.set('core.destroyEmptyPanes', true)
newContainer = atom.views.getView(container.model.testSerialization()).__spacePenView
newContainer = atom.views.createView(container.model.testSerialization(), {viewRegistry}).__spacePenView
expect(newContainer.find('atom-pane-axis.horizontal, atom-pane-axis.vertical')).not.toExist()
expect(newContainer.find('> :contains(1)')).toExist()
@@ -109,7 +114,7 @@ describe "PaneContainerView", ->
item2b = new TestView('2b')
item3a = new TestView('3a')
container = atom.views.getView(new PaneContainer).__spacePenView
container = atom.views.createView(new PaneContainer, {viewRegistry}).__spacePenView
pane1 = container.getRoot()
pane1.activateItem(item1a)
container.attachToDom()
@@ -259,7 +264,7 @@ describe "PaneContainerView", ->
# |7|8|9|
# -------
container = atom.views.getView(new PaneContainer).__spacePenView
container = atom.views.createView(new PaneContainer, {viewRegistry}).__spacePenView
pane1 = container.getRoot()
pane1.activateItem(new TestView('1'))
pane4 = pane1.splitDown(new TestView('4'))
+22 -11
Ver Arquivo
@@ -1,13 +1,14 @@
PaneContainer = require '../src/pane-container'
PaneView = require '../src/pane-view'
ViewRegistry = require '../src/view-registry'
fs = require 'fs-plus'
{Emitter} = require 'event-kit'
{$, View} = require 'atom'
{Emitter, Disposable} = require 'event-kit'
{$, View} = require '../src/space-pen-extensions'
path = require 'path'
temp = require 'temp'
describe "PaneView", ->
[container, containerModel, view1, view2, editor1, editor2, pane, paneModel, deserializerDisposable] = []
[viewRegistry, container, containerModel, view1, view2, editor1, editor2, pane, paneModel, deserializerDisposable] = []
class TestView extends View
@deserialize: ({id, text}) -> new TestView({id, text})
@@ -21,10 +22,14 @@ describe "PaneView", ->
@emitter.emit 'did-change-title', 'title'
onDidChangeTitle: (callback) ->
@emitter.on 'did-change-title', callback
onDidChangeModified: -> new Disposable(->)
beforeEach ->
jasmine.snapshotDeprecations()
deserializerDisposable = atom.deserializers.add(TestView)
container = atom.views.getView(new PaneContainer).__spacePenView
viewRegistry = new ViewRegistry(atom.views)
container = atom.views.createView(new PaneContainer, {viewRegistry}).__spacePenView
containerModel = container.model
view1 = new TestView(id: 'view-1', text: 'View 1')
view2 = new TestView(id: 'view-2', text: 'View 2')
@@ -41,6 +46,7 @@ describe "PaneView", ->
afterEach ->
deserializerDisposable.dispose()
jasmine.restoreDeprecationsSnapshot()
describe "when the active pane item changes", ->
it "hides all item views except the active one", ->
@@ -155,14 +161,19 @@ describe "PaneView", ->
expect(view1.is(':visible')).toBe true
describe "when the title of the active item changes", ->
describe 'when there is no onDidChangeTitle method', ->
describe 'when there is no onDidChangeTitle method (deprecated)', ->
beforeEach ->
jasmine.snapshotDeprecations()
view1.onDidChangeTitle = null
view2.onDidChangeTitle = null
pane.activateItem(view2)
pane.activateItem(view1)
afterEach ->
jasmine.restoreDeprecationsSnapshot()
it "emits pane:active-item-title-changed", ->
activeItemTitleChangedHandler = jasmine.createSpy("activeItemTitleChangedHandler")
pane.on 'pane:active-item-title-changed', activeItemTitleChangedHandler
@@ -220,7 +231,7 @@ describe "PaneView", ->
beforeEach ->
pane2Model = paneModel.splitRight() # Can't destroy the last pane, so we add another
pane2 = containerModel.getView(pane2Model).__spacePenView
pane2 = viewRegistry.getView(pane2Model).__spacePenView
it "triggers a 'pane:removed' event with the pane", ->
removedHandler = jasmine.createSpy("removedHandler")
@@ -253,7 +264,7 @@ describe "PaneView", ->
beforeEach ->
pane2Model = paneModel.splitRight(items: [pane.copyActiveItem()])
pane2 = containerModel.getView(pane2Model).__spacePenView
pane2 = viewRegistry.getView(pane2Model).__spacePenView
expect(pane2Model.isActive()).toBe true
it "adds or removes the .active class as appropriate", ->
@@ -300,8 +311,8 @@ describe "PaneView", ->
pane2Model = pane1Model.splitRight(items: [pane1Model.copyActiveItem()])
pane3Model = pane2Model.splitDown(items: [pane2Model.copyActiveItem()])
pane2 = pane2Model._view
pane2 = containerModel.getView(pane2Model).__spacePenView
pane3 = containerModel.getView(pane3Model).__spacePenView
pane2 = viewRegistry.getView(pane2Model).__spacePenView
pane3 = viewRegistry.getView(pane3Model).__spacePenView
expect(container.find('> atom-pane-axis.horizontal > atom-pane').toArray()).toEqual [pane1[0]]
expect(container.find('> atom-pane-axis.horizontal > atom-pane-axis.vertical > atom-pane').toArray()).toEqual [pane2[0], pane3[0]]
@@ -314,13 +325,13 @@ describe "PaneView", ->
container.attachToDom()
pane.focus()
container2 = atom.views.getView(container.model.testSerialization()).__spacePenView
container2 = viewRegistry.getView(container.model.testSerialization()).__spacePenView
pane2 = container2.getRoot()
container2.attachToDom()
expect(pane2).toMatchSelector(':has(:focus)')
$(document.activeElement).blur()
container3 = atom.views.getView(container.model.testSerialization()).__spacePenView
container3 = viewRegistry.getView(container.model.testSerialization()).__spacePenView
pane3 = container3.getRoot()
container3.attachToDom()
expect(pane3).not.toMatchSelector(':has(:focus)')
+36 -35
Ver Arquivo
@@ -1,8 +1,8 @@
ViewRegistry = require '../src/view-registry'
Panel = require '../src/panel'
PanelElement = require '../src/panel-element'
PanelContainer = require '../src/panel-container'
PanelContainerElement = require '../src/panel-container-element'
ViewRegistry = require '../src/view-registry'
describe "PanelContainerElement", ->
[jasmineContent, element, container, viewRegistry] = []
@@ -13,25 +13,26 @@ describe "PanelContainerElement", ->
class TestPanelContainerItemElement extends HTMLElement
createdCallback: ->
@classList.add('test-root')
setModel: (@model) ->
initialize: ({@model}) ->
TestPanelContainerItemElement = document.registerElement 'atom-test-container-item-element', prototype: TestPanelContainerItemElement.prototype
beforeEach ->
jasmineContent = document.body.querySelector('#jasmine-content')
viewRegistry = new ViewRegistry
viewRegistry.addViewProvider
atom.views.addViewProvider
modelConstructor: Panel
viewConstructor: PanelElement
viewRegistry.addViewProvider
atom.views.addViewProvider
modelConstructor: PanelContainer
viewConstructor: PanelContainerElement
viewRegistry.addViewProvider
atom.views.addViewProvider
modelConstructor: TestPanelContainerItem
viewConstructor: TestPanelContainerItemElement
container = new PanelContainer({viewRegistry, location: 'left'})
element = container.getView()
container = new PanelContainer({location: 'left'})
viewRegistry = new ViewRegistry(atom.views)
element = viewRegistry.getView(container, {viewRegistry})
jasmineContent.appendChild(element)
it 'has a location class with value from the model', ->
@@ -44,9 +45,9 @@ describe "PanelContainerElement", ->
describe "adding and removing panels", ->
it "allows panels to be inserted at any position", ->
panel1 = new Panel({viewRegistry, item: new TestPanelContainerItem(), priority: 10})
panel2 = new Panel({viewRegistry, item: new TestPanelContainerItem(), priority: 5})
panel3 = new Panel({viewRegistry, item: new TestPanelContainerItem(), priority: 8})
panel1 = new Panel({item: new TestPanelContainerItem(), priority: 10})
panel2 = new Panel({item: new TestPanelContainerItem(), priority: 5})
panel3 = new Panel({item: new TestPanelContainerItem(), priority: 8})
container.addPanel(panel1)
container.addPanel(panel2)
@@ -60,7 +61,7 @@ describe "PanelContainerElement", ->
it "adds atom-panel elements when a new panel is added to the container; removes them when the panels are destroyed", ->
expect(element.childNodes.length).toBe 0
panel1 = new Panel({viewRegistry, item: new TestPanelContainerItem()})
panel1 = new Panel({item: new TestPanelContainerItem()})
container.addPanel(panel1)
expect(element.childNodes.length).toBe 1
expect(element.childNodes[0]).toHaveClass 'left'
@@ -69,12 +70,12 @@ describe "PanelContainerElement", ->
expect(element.childNodes[0].tagName).toBe 'ATOM-PANEL'
panel2 = new Panel({viewRegistry, item: new TestPanelContainerItem()})
panel2 = new Panel({item: new TestPanelContainerItem()})
container.addPanel(panel2)
expect(element.childNodes.length).toBe 2
expect(panel1.getView().style.display).not.toBe 'none'
expect(panel2.getView().style.display).not.toBe 'none'
expect(viewRegistry.getView(panel1).style.display).not.toBe 'none'
expect(viewRegistry.getView(panel2).style.display).not.toBe 'none'
panel1.destroy()
expect(element.childNodes.length).toBe 1
@@ -84,26 +85,26 @@ describe "PanelContainerElement", ->
describe "when the container is at the bottom location", ->
beforeEach ->
container = new PanelContainer({viewRegistry, location: 'bottom'})
element = container.getView()
container = new PanelContainer({location: 'bottom'})
element = viewRegistry.getView(container)
jasmineContent.appendChild(element)
it "adds atom-panel elements when a new panel is added to the container; removes them when the panels are destroyed", ->
expect(element.childNodes.length).toBe 0
panel1 = new Panel({viewRegistry, item: new TestPanelContainerItem(), className: 'one'})
panel1 = new Panel({item: new TestPanelContainerItem(), className: 'one'})
container.addPanel(panel1)
expect(element.childNodes.length).toBe 1
expect(element.childNodes[0]).toHaveClass 'bottom'
expect(element.childNodes[0]).toHaveClass 'tool-panel' # legacy selector support
expect(element.childNodes[0]).toHaveClass 'panel-bottom' # legacy selector support
expect(element.childNodes[0].tagName).toBe 'ATOM-PANEL'
expect(panel1.getView()).toHaveClass 'one'
expect(viewRegistry.getView(panel1)).toHaveClass 'one'
panel2 = new Panel({viewRegistry, item: new TestPanelContainerItem(), className: 'two'})
panel2 = new Panel({item: new TestPanelContainerItem(), className: 'two'})
container.addPanel(panel2)
expect(element.childNodes.length).toBe 2
expect(panel2.getView()).toHaveClass 'two'
expect(viewRegistry.getView(panel2)).toHaveClass 'two'
panel1.destroy()
expect(element.childNodes.length).toBe 1
@@ -113,34 +114,34 @@ describe "PanelContainerElement", ->
describe "when the container is modal", ->
beforeEach ->
container = new PanelContainer({viewRegistry, location: 'modal'})
element = container.getView()
container = new PanelContainer({location: 'modal'})
element = viewRegistry.getView(container)
jasmineContent.appendChild(element)
it "allows only one panel to be visible at a time", ->
panel1 = new Panel({viewRegistry, item: new TestPanelContainerItem()})
panel1 = new Panel({item: new TestPanelContainerItem()})
container.addPanel(panel1)
expect(panel1.getView().style.display).not.toBe 'none'
expect(viewRegistry.getView(panel1).style.display).not.toBe 'none'
panel2 = new Panel({viewRegistry, item: new TestPanelContainerItem()})
panel2 = new Panel({item: new TestPanelContainerItem()})
container.addPanel(panel2)
expect(panel1.getView().style.display).toBe 'none'
expect(panel2.getView().style.display).not.toBe 'none'
expect(viewRegistry.getView(panel1).style.display).toBe 'none'
expect(viewRegistry.getView(panel2).style.display).not.toBe 'none'
panel1.show()
expect(panel1.getView().style.display).not.toBe 'none'
expect(panel2.getView().style.display).toBe 'none'
expect(viewRegistry.getView(panel1).style.display).not.toBe 'none'
expect(viewRegistry.getView(panel2).style.display).toBe 'none'
it "adds the 'modal' class to panels", ->
panel1 = new Panel({viewRegistry, item: new TestPanelContainerItem()})
panel1 = new Panel({item: new TestPanelContainerItem()})
container.addPanel(panel1)
expect(panel1.getView()).toHaveClass 'modal'
expect(viewRegistry.getView(panel1)).toHaveClass 'modal'
# legacy selector support
expect(panel1.getView()).not.toHaveClass 'tool-panel'
expect(panel1.getView()).toHaveClass 'overlay'
expect(panel1.getView()).toHaveClass 'from-top'
expect(viewRegistry.getView(panel1)).not.toHaveClass 'tool-panel'
expect(viewRegistry.getView(panel1)).toHaveClass 'overlay'
expect(viewRegistry.getView(panel1)).toHaveClass 'from-top'
+4 -6
Ver Arquivo
@@ -1,16 +1,14 @@
ViewRegistry = require '../src/view-registry'
Panel = require '../src/panel'
PanelContainer = require '../src/panel-container'
describe "PanelContainer", ->
[container, viewRegistry] = []
[container] = []
class TestPanelItem
constructior: ->
beforeEach ->
viewRegistry = new ViewRegistry
container = new PanelContainer({viewRegistry})
container = new PanelContainer
describe "::addPanel(panel)", ->
it 'emits an onDidAddPanel event with the index the panel was inserted at', ->
@@ -46,7 +44,7 @@ describe "PanelContainer", ->
[initialPanel] = []
beforeEach ->
# 'left' logic is the same as 'top'
container = new PanelContainer({viewRegistry, location: 'left'})
container = new PanelContainer({location: 'left'})
initialPanel = new Panel(item: new TestPanelItem())
container.addPanel(initialPanel)
@@ -75,7 +73,7 @@ describe "PanelContainer", ->
[initialPanel] = []
beforeEach ->
# 'bottom' logic is the same as 'right'
container = new PanelContainer({viewRegistry, location: 'right'})
container = new PanelContainer({location: 'right'})
initialPanel = new Panel(item: new TestPanelItem())
container.addPanel(initialPanel)
+20 -13
Ver Arquivo
@@ -1,6 +1,6 @@
ViewRegistry = require '../src/view-registry'
Panel = require '../src/panel'
PanelElement = require '../src/panel-element'
ViewRegistry = require '../src/view-registry'
describe "PanelElement", ->
[jasmineContent, element, panel, viewRegistry] = []
@@ -11,23 +11,30 @@ describe "PanelElement", ->
class TestPanelItemElement extends HTMLElement
createdCallback: ->
@classList.add('test-root')
setModel: (@model) ->
initialize: ({@model}) ->
TestPanelItemElement = document.registerElement 'atom-test-item-element', prototype: TestPanelItemElement.prototype
beforeEach ->
jasmineContent = document.body.querySelector('#jasmine-content')
viewRegistry = new ViewRegistry
viewRegistry.addViewProvider
atom.views.addViewProvider
modelConstructor: Panel
viewConstructor: PanelElement
viewRegistry.addViewProvider
atom.views.addViewProvider
modelConstructor: TestPanelItem
viewConstructor: TestPanelItemElement
viewRegistry = new ViewRegistry(atom.views)
it "renders a view for the panel's item", ->
panel = new Panel({item: new TestPanelItem})
element = atom.views.createView(panel, {viewRegistry})
jasmineContent.appendChild(element)
expect(element.firstChild).toBe viewRegistry.getView(panel.getItem())
it 'removes the element when the panel is destroyed', ->
panel = new Panel({viewRegistry, item: new TestPanelItem})
element = panel.getView()
panel = new Panel({item: new TestPanelItem})
element = atom.views.createView(panel, {viewRegistry})
jasmineContent.appendChild(element)
expect(element.parentNode).toBe jasmineContent
@@ -36,15 +43,15 @@ describe "PanelElement", ->
describe "changing panel visibility", ->
it 'initially renders panel created with visibile: false', ->
panel = new Panel({viewRegistry, visible: false, item: new TestPanelItem})
element = panel.getView()
panel = new Panel({visible: false, item: new TestPanelItem})
element = atom.views.createView(panel, {viewRegistry})
jasmineContent.appendChild(element)
expect(element.style.display).toBe 'none'
it 'hides and shows the panel element when Panel::hide() and Panel::show() are called', ->
panel = new Panel({viewRegistry, item: new TestPanelItem})
element = panel.getView()
panel = new Panel({item: new TestPanelItem})
element = atom.views.createView(panel, {viewRegistry})
jasmineContent.appendChild(element)
expect(element.style.display).not.toBe 'none'
@@ -57,8 +64,8 @@ describe "PanelElement", ->
describe "when a class name is specified", ->
it 'initially renders panel created with visibile: false', ->
panel = new Panel({viewRegistry, className: 'some classes', item: new TestPanelItem})
element = panel.getView()
panel = new Panel({className: 'some classes', item: new TestPanelItem})
element = atom.views.createView(panel, {viewRegistry})
jasmineContent.appendChild(element)
expect(element).toHaveClass 'some'
+5 -5
Ver Arquivo
@@ -170,30 +170,30 @@ describe "Project", ->
absolutePath = fs.absolute(__dirname)
expect(atom.project.resolve(absolutePath)).toBe absolutePath
describe ".setPath(path)", ->
describe ".setPaths(path)", ->
describe "when path is a file", ->
it "sets its path to the files parent directory and updates the root directory", ->
atom.project.setPaths([require.resolve('./fixtures/dir/a')])
expect(atom.project.getPaths()[0]).toEqual path.dirname(require.resolve('./fixtures/dir/a'))
expect(atom.project.getRootDirectory().path).toEqual path.dirname(require.resolve('./fixtures/dir/a'))
expect(atom.project.getDirectories()[0].path).toEqual path.dirname(require.resolve('./fixtures/dir/a'))
describe "when path is a directory", ->
it "sets its path to the directory and updates the root directory", ->
directory = fs.absolute(path.join(__dirname, 'fixtures', 'dir', 'a-dir'))
atom.project.setPaths([directory])
expect(atom.project.getPaths()[0]).toEqual directory
expect(atom.project.getRootDirectory().path).toEqual directory
expect(atom.project.getDirectories()[0].path).toEqual directory
describe "when path is null", ->
it "sets its path and root directory to null", ->
atom.project.setPaths([])
expect(atom.project.getPaths()[0]?).toBeFalsy()
expect(atom.project.getRootDirectory()?).toBeFalsy()
expect(atom.project.getDirectories()[0]?).toBeFalsy()
it "normalizes the path to remove consecutive slashes, ., and .. segments", ->
atom.project.setPaths(["#{require.resolve('./fixtures/dir/a')}#{path.sep}b#{path.sep}#{path.sep}.."])
expect(atom.project.getPaths()[0]).toEqual path.dirname(require.resolve('./fixtures/dir/a'))
expect(atom.project.getRootDirectory().path).toEqual path.dirname(require.resolve('./fixtures/dir/a'))
expect(atom.project.getDirectories()[0].path).toEqual path.dirname(require.resolve('./fixtures/dir/a'))
describe ".replace()", ->
[filePath, commentFilePath, sampleContent, sampleCommentContent] = []
+1 -1
Ver Arquivo
@@ -1,5 +1,5 @@
SelectListView = require '../src/select-list-view'
{$, $$} = require 'atom'
{$, $$} = require '../src/space-pen-extensions'
describe "SelectListView", ->
[selectList, items, list, filterEditorView] = []
+1 -1
Ver Arquivo
@@ -1,4 +1,4 @@
{View, $, $$} = require 'atom'
{View, $, $$} = require '../src/space-pen-extensions'
describe "SpacePen extensions", ->
class TestView extends View
+18 -3
Ver Arquivo
@@ -9,13 +9,17 @@ _ = require 'underscore-plus'
fs = require 'fs-plus'
Grim = require 'grim'
KeymapManager = require '../src/keymap-extensions'
Workspace = require '../src/workspace'
# FIXME: Remove jquery from this
{$} = require '../src/space-pen-extensions'
Config = require '../src/config'
{Point} = require 'text-buffer'
Project = require '../src/project'
Workspace = require '../src/workspace'
TextEditor = require '../src/text-editor'
TextEditorView = require '../src/text-editor-view'
TextEditorElement = require '../src/text-editor-element'
TokenizedBuffer = require '../src/tokenized-buffer'
TextEditorComponent = require '../src/text-editor-component'
pathwatcher = require 'pathwatcher'
@@ -77,6 +81,8 @@ beforeEach ->
atom.commands.restoreSnapshot(commandsToRestore)
atom.styles.restoreSnapshot(styleElementsToRestore)
atom.workspaceViewParentSelector = '#jasmine-content'
window.resetTimeouts()
atom.packages.packageStates = {}
@@ -112,8 +118,7 @@ beforeEach ->
config.save.reset()
# make editor display updates synchronous
spyOn(TextEditorView.prototype, 'requestDisplayUpdate').andCallFake -> @updateDisplay()
TextEditorComponent.performSyncUpdates = true
TextEditorElement::setUpdatedSynchronously(true)
spyOn(atom, "setRepresentedFilename")
spyOn(window, "setTimeout").andCallFake window.fakeSetTimeout
@@ -197,6 +202,13 @@ jasmine.attachToDOM = (element) ->
jasmineContent = document.querySelector('#jasmine-content')
jasmineContent.appendChild(element) unless jasmineContent.contains(element)
deprecationsSnapshot = null
jasmine.snapshotDeprecations = ->
deprecationsSnapshot = Grim.getDeprecations() # suppress deprecations!!
jasmine.restoreDeprecationsSnapshot = ->
Grim.grimDeprecations = deprecationsSnapshot
addCustomMatchers = (spec) ->
spec.addMatchers
toBeInstanceOf: (expected) ->
@@ -292,6 +304,9 @@ window.waitsForPromise = (args...) ->
jasmine.getEnv().currentSpec.fail("Expected promise to be resolved, but it was rejected with #{jasmine.pp(error)}")
moveOn()
window.waitsForAnimationFrame = ->
waitsFor "next animation frame", (done) -> requestAnimationFrame(done)
window.resetTimeouts = ->
window.now = 0
window.timeoutCount = 0
-27
Ver Arquivo
@@ -105,30 +105,3 @@ describe "the `syntax` global", ->
grammar = atom.grammars.selectGrammar('foo.js')
atom.grammars.removeGrammar(grammar)
expect(atom.grammars.selectGrammar('foo.js').name).not.toBe grammar.name
describe ".getProperty(scopeDescriptor)", ->
it "returns the property with the most specific scope selector", ->
atom.grammars.addProperties(".source.coffee .string.quoted.double.coffee", foo: bar: baz: 42)
atom.grammars.addProperties(".source .string.quoted.double", foo: bar: baz: 22)
atom.grammars.addProperties(".source", foo: bar: baz: 11)
expect(atom.grammars.getProperty([".source.coffee", ".string.quoted.double.coffee"], "foo.bar.baz")).toBe 42
expect(atom.grammars.getProperty([".source.js", ".string.quoted.double.js"], "foo.bar.baz")).toBe 22
expect(atom.grammars.getProperty([".source.js", ".variable.assignment.js"], "foo.bar.baz")).toBe 11
expect(atom.grammars.getProperty([".text"], "foo.bar.baz")).toBeUndefined()
it "favors the most recently added properties in the event of a specificity tie", ->
atom.grammars.addProperties(".source.coffee .string.quoted.single", foo: bar: baz: 42)
atom.grammars.addProperties(".source.coffee .string.quoted.double", foo: bar: baz: 22)
expect(atom.grammars.getProperty([".source.coffee", ".string.quoted.single"], "foo.bar.baz")).toBe 42
expect(atom.grammars.getProperty([".source.coffee", ".string.quoted.single.double"], "foo.bar.baz")).toBe 22
describe ".removeProperties(name)", ->
it "allows properties to be removed by name", ->
atom.grammars.addProperties("a", ".source.coffee .string.quoted.double.coffee", foo: bar: baz: 42)
atom.grammars.addProperties("b", ".source .string.quoted.double", foo: bar: baz: 22)
atom.grammars.removeProperties("b")
expect(atom.grammars.getProperty([".source.js", ".string.quoted.double.js"], "foo.bar.baz")).toBeUndefined()
expect(atom.grammars.getProperty([".source.coffee", ".string.quoted.double.coffee"], "foo.bar.baz")).toBe 42
+24 -8
Ver Arquivo
@@ -3,10 +3,12 @@ _ = require 'underscore-plus'
TextEditorView = require '../src/text-editor-view'
TextEditorComponent = require '../src/text-editor-component'
ViewRegistry = require '../src/view-registry'
nbsp = String.fromCharCode(160)
describe "TextEditorComponent", ->
[contentNode, editor, wrapperView, wrapperNode, component, componentNode, verticalScrollbarNode, horizontalScrollbarNode] = []
[viewRegistry, contentNode, editor, wrapperView, wrapperNode, component, componentNode, verticalScrollbarNode, horizontalScrollbarNode] = []
[lineHeightInPixels, charWidth, nextAnimationFrame, noAnimationFrame, lineOverdrawMargin] = []
beforeEach ->
@@ -31,19 +33,22 @@ describe "TextEditorComponent", ->
atom.project.open('sample.js').then (o) -> editor = o
runs ->
viewRegistry = new ViewRegistry(atom.views)
contentNode = document.querySelector('#jasmine-content')
contentNode.style.width = '1000px'
wrapperView = new TextEditorView(editor, {lineOverdrawMargin})
wrapperView.attachToDom()
wrapperNode = wrapperView.element
wrapperNode = atom.views.createView(editor, {viewRegistry, lineOverdrawMargin})
wrapperNode.setUpdatedSynchronously(false)
jasmine.attachToDOM(wrapperNode)
{component} = wrapperView
component.performSyncUpdates = false
{component} = wrapperNode
component.setFontFamily('monospace')
component.setLineHeight(1.3)
component.setFontSize(20)
wrapperView = wrapperNode.__spacePenView
lineHeightInPixels = editor.getLineHeightInPixels()
charWidth = editor.getDefaultCharWidth()
componentNode = component.getDOMNode()
@@ -302,7 +307,7 @@ describe "TextEditorComponent", ->
it "interleaves invisible line-ending characters with indent guides on empty lines", ->
component.setShowIndentGuide(true)
editor.setTextInBufferRange([[10, 0], [11, 0]], "\r\n", false)
editor.setTextInBufferRange([[10, 0], [11, 0]], "\r\n", normalizeLineEndings: false)
nextAnimationFrame()
expect(component.lineNodeForScreenRow(10).innerHTML).toBe '<span class="indent-guide"><span class="invisible-character">C</span><span class="invisible-character">E</span></span>'
@@ -1247,7 +1252,7 @@ describe "TextEditorComponent", ->
expect(overlay.style.top).toBe position.top + editor.getLineHeightInPixels() + 'px'
describe "when the marker is not empty", ->
it "renders at the head of the marker", ->
it "renders at the head of the marker by default", ->
marker = editor.displayBuffer.markBufferRange([[2, 5], [2, 10]], invalidate: 'never')
decoration = editor.decorateMarker(marker, {type: 'overlay', item})
nextAnimationFrame()
@@ -1269,6 +1274,17 @@ describe "TextEditorComponent", ->
expect(overlay.style.left).toBe position.left + 'px'
expect(overlay.style.top).toBe position.top + editor.getLineHeightInPixels() + 'px'
it "renders at the tail of the marker when the 'position' option is 'tail'", ->
marker = editor.displayBuffer.markBufferRange([[2, 5], [2, 10]], invalidate: 'never')
decoration = editor.decorateMarker(marker, {type: 'overlay', position: 'tail', item})
nextAnimationFrame()
position = editor.pixelPositionForBufferPosition([2, 5])
overlay = component.getTopmostDOMNode().querySelector('atom-overlay')
expect(overlay.style.left).toBe position.left + 'px'
expect(overlay.style.top).toBe position.top + editor.getLineHeightInPixels() + 'px'
describe "positioning the overlay when near the edge of the editor", ->
[itemWidth, itemHeight] = []
beforeEach ->
+20
Ver Arquivo
@@ -98,3 +98,23 @@ describe "TextEditorElement", ->
verticalScrollbarNode = element.querySelector(".vertical-scrollbar")
scrollbarWidth = verticalScrollbarNode.offsetWidth - verticalScrollbarNode.clientWidth
expect(scrollbarWidth).toEqual(8)
describe "::setUpdatedSynchronously", ->
it "controls whether the text editor is updated synchronously", ->
element = new TextEditorElement
jasmine.attachToDOM(element)
element.setUpdatedSynchronously(false)
expect(element.isUpdatedSynchronously()).toBe false
element.getModel().setText("hello")
expect(element.shadowRoot.textContent).not.toContain "hello"
waitsForAnimationFrame()
runs ->
expect(element.shadowRoot.textContent).toContain "hello"
element.setUpdatedSynchronously(true)
element.getModel().setText("goodbye")
expect(element.shadowRoot.textContent).toContain "goodbye"
+7 -9
Ver Arquivo
@@ -616,7 +616,7 @@ describe "TextEditor", ->
describe "when invisible characters are enabled with hard tabs", ->
it "moves to the first character of the current line without being confused by the invisible characters", ->
atom.config.set('editor.showInvisibles', true)
buffer.setTextInRange([[1, 0], [1, Infinity]], '\t\t\ta', false)
buffer.setTextInRange([[1, 0], [1, Infinity]], '\t\t\ta', normalizeLineEndings: false)
editor.setCursorScreenPosition [1,7]
editor.moveToFirstCharacterOfLine()
@@ -3014,18 +3014,16 @@ describe "TextEditor", ->
expect(editor.isFoldedAtBufferRow(1)).toBeFalsy()
expect(editor.isFoldedAtBufferRow(2)).toBeTruthy()
describe "begin/commitTransaction()", ->
describe "::transact", ->
it "restores the selection when the transaction is undone/redone", ->
buffer.setText('1234')
editor.setSelectedBufferRange([[0, 1], [0, 3]])
editor.beginTransaction()
editor.delete()
editor.moveToEndOfLine()
editor.insertText('5')
expect(buffer.getText()).toBe '145'
editor.commitTransaction()
editor.transact ->
editor.delete()
editor.moveToEndOfLine()
editor.insertText('5')
expect(buffer.getText()).toBe '145'
editor.undo()
expect(buffer.getText()).toBe '1234'
+41 -2
Ver Arquivo
@@ -1,6 +1,6 @@
path = require 'path'
{$, $$, WorkspaceView} = require 'atom'
{$, $$} = require '../src/space-pen-extensions'
fs = require 'fs-plus'
temp = require 'temp'
@@ -20,8 +20,12 @@ describe "ThemeManager", ->
describe "theme getters and setters", ->
beforeEach ->
jasmine.snapshotDeprecations()
atom.packages.loadPackages()
afterEach ->
jasmine.restoreDeprecationsSnapshot()
it 'getLoadedThemes get all the loaded themes', ->
themes = themeManager.getLoadedThemes()
expect(themes.length).toBeGreaterThan(2)
@@ -130,15 +134,24 @@ describe "ThemeManager", ->
expect(-> atom.packages.activatePackage('a-theme-that-will-not-be-found')).toThrow()
describe "::requireStylesheet(path)", ->
beforeEach ->
jasmine.snapshotDeprecations()
afterEach ->
jasmine.restoreDeprecationsSnapshot()
it "synchronously loads css at the given path and installs a style tag for it in the head", ->
atom.styles.onDidAddStyleElement styleElementAddedHandler = jasmine.createSpy("styleElementAddedHandler")
themeManager.onDidChangeStylesheets stylesheetsChangedHandler = jasmine.createSpy("stylesheetsChangedHandler")
themeManager.onDidAddStylesheet stylesheetAddedHandler = jasmine.createSpy("stylesheetAddedHandler")
cssPath = atom.project.resolve('css.css')
lengthBefore = $('head style').length
themeManager.requireStylesheet(cssPath)
expect($('head style').length).toBe lengthBefore + 1
expect(styleElementAddedHandler).toHaveBeenCalled()
expect(stylesheetAddedHandler).toHaveBeenCalled()
expect(stylesheetsChangedHandler).toHaveBeenCalled()
@@ -148,8 +161,10 @@ describe "ThemeManager", ->
expect(element[0].sheet).toBe stylesheetAddedHandler.argsForCall[0][0]
# doesn't append twice
styleElementAddedHandler.reset()
themeManager.requireStylesheet(cssPath)
expect($('head style').length).toBe lengthBefore + 1
expect(styleElementAddedHandler).not.toHaveBeenCalled()
$('head style[id*="css.css"]').remove()
@@ -192,6 +207,7 @@ describe "ThemeManager", ->
disposable = themeManager.requireStylesheet(cssPath)
expect($(document.body).css('font-weight')).toBe("bold")
atom.styles.onDidRemoveStyleElement styleElementRemovedHandler = jasmine.createSpy("styleElementRemovedHandler")
themeManager.onDidRemoveStylesheet stylesheetRemovedHandler = jasmine.createSpy("stylesheetRemovedHandler")
themeManager.onDidChangeStylesheets stylesheetsChangedHandler = jasmine.createSpy("stylesheetsChangedHandler")
@@ -199,6 +215,7 @@ describe "ThemeManager", ->
expect($(document.body).css('font-weight')).not.toBe("bold")
expect(styleElementRemovedHandler).toHaveBeenCalled()
expect(stylesheetRemovedHandler).toHaveBeenCalled()
stylesheet = stylesheetRemovedHandler.argsForCall[0][0]
expect(stylesheet instanceof CSSStyleSheet).toBe true
@@ -209,13 +226,18 @@ describe "ThemeManager", ->
describe "base stylesheet loading", ->
workspaceElement = null
beforeEach ->
workspaceElement = atom.views.getView(atom.workspace)
jasmine.snapshotDeprecations()
workspaceElement = atom.views.createView(atom.workspace)
jasmine.attachToDOM(workspaceElement)
workspaceElement.appendChild document.createElement('atom-text-editor')
waitsForPromise ->
themeManager.activateThemes()
beforeEach ->
jasmine.restoreDeprecationsSnapshot()
it "loads the correct values from the theme's ui-variables file", ->
themeManager.onDidReloadAll reloadHandler = jasmine.createSpy()
atom.config.set('core.themes', ['theme-with-ui-variables', 'theme-with-syntax-variables'])
@@ -265,7 +287,14 @@ describe "ThemeManager", ->
expect(workspaceElement).not.toHaveClass 'theme-atom-dark-syntax'
describe "when the user stylesheet changes", ->
beforeEach ->
jasmine.snapshotDeprecations()
afterEach ->
jasmine.restoreDeprecationsSnapshot()
it "reloads it", ->
[styleElementAddedHandler, styleElementRemovedHandler] = []
[stylesheetRemovedHandler, stylesheetAddedHandler, stylesheetsChangedHandler] = []
userStylesheetPath = path.join(temp.mkdirSync("atom"), 'styles.less')
fs.writeFileSync(userStylesheetPath, 'body {border-style: dotted !important;}')
@@ -275,6 +304,9 @@ describe "ThemeManager", ->
themeManager.activateThemes()
runs ->
atom.styles.onDidRemoveStyleElement styleElementRemovedHandler = jasmine.createSpy("styleElementRemovedHandler")
atom.styles.onDidAddStyleElement styleElementAddedHandler = jasmine.createSpy("styleElementAddedHandler")
themeManager.onDidChangeStylesheets stylesheetsChangedHandler = jasmine.createSpy("stylesheetsChangedHandler")
themeManager.onDidRemoveStylesheet stylesheetRemovedHandler = jasmine.createSpy("stylesheetRemovedHandler")
themeManager.onDidAddStylesheet stylesheetAddedHandler = jasmine.createSpy("stylesheetAddedHandler")
@@ -289,14 +321,19 @@ describe "ThemeManager", ->
runs ->
expect($(document.body).css('border-style')).toBe 'dashed'
expect(styleElementRemovedHandler).toHaveBeenCalled()
expect(styleElementRemovedHandler.argsForCall[0][0].textContent).toContain 'dotted'
expect(stylesheetRemovedHandler).toHaveBeenCalled()
expect(stylesheetRemovedHandler.argsForCall[0][0].cssRules[0].style.border).toBe 'dotted'
expect(styleElementAddedHandler).toHaveBeenCalled()
expect(styleElementAddedHandler.argsForCall[0][0].textContent).toContain 'dashed'
expect(stylesheetAddedHandler).toHaveBeenCalled()
expect(stylesheetAddedHandler.argsForCall[0][0].cssRules[0].style.border).toBe 'dashed'
expect(stylesheetsChangedHandler).toHaveBeenCalled()
styleElementRemovedHandler.reset()
stylesheetRemovedHandler.reset()
stylesheetsChangedHandler.reset()
fs.removeSync(userStylesheetPath)
@@ -305,6 +342,8 @@ describe "ThemeManager", ->
themeManager.loadUserStylesheet.callCount is 2
runs ->
expect(styleElementRemovedHandler).toHaveBeenCalled()
expect(styleElementRemovedHandler.argsForCall[0][0].textContent).toContain 'dashed'
expect(stylesheetRemovedHandler).toHaveBeenCalled()
expect(stylesheetRemovedHandler.argsForCall[0][0].cssRules[0].style.border).toBe 'dashed'
expect($(document.body).css('border-style')).toBe 'none'
@@ -1,17 +1,17 @@
ViewRegistry = require '../src/view-registry'
ViewFactory = require '../src/view-factory'
{View} = require '../src/space-pen-extensions'
describe "ViewRegistry", ->
registry = null
describe "ViewFactory", ->
factory = null
beforeEach ->
registry = new ViewRegistry
factory = new ViewFactory
describe "::getView(object)", ->
describe "::createView(object, params)", ->
describe "when passed a DOM node", ->
it "returns the given DOM node", ->
node = document.createElement('div')
expect(registry.getView(node)).toBe node
expect(factory.createView(node)).toBe node
describe "when passed a SpacePen view", ->
it "returns the root node of the view with a __spacePenView property pointing at the SpacePen view", ->
@@ -19,56 +19,65 @@ describe "ViewRegistry", ->
@content: -> @div "Hello"
view = new TestView
node = registry.getView(view)
node = factory.createView(view)
expect(node.textContent).toBe "Hello"
expect(node.__spacePenView).toBe view
describe "when passed a model object", ->
describe "when a view provider is registered matching the object's constructor", ->
describe "when the provider has a viewConstructor property", ->
it "constructs a view element and assigns the model on it", ->
it "constructs a view element and calls initialize on it with the creation params", ->
class TestModel
class TestModelSubclass extends TestModel
class TestView
setModel: (@model) ->
initialize: (@params) ->
model = new TestModel
registry.addViewProvider
factory.addViewProvider
modelConstructor: TestModel
viewConstructor: TestView
view = registry.getView(model)
view = factory.createView(model, a: 1)
expect(view instanceof TestView).toBe true
expect(view.model).toBe model
expect(view.params.a).toBe 1
expect(view.params.model).toBe model
expect(view.params.viewFactory).toBe factory
subclassModel = new TestModelSubclass
view2 = registry.getView(subclassModel)
view2 = factory.createView(subclassModel)
expect(view2 instanceof TestView).toBe true
expect(view2.model).toBe subclassModel
expect(view2.params.model).toBe subclassModel
describe "when the provider has a createView method", ->
it "constructs a view element by calling the createView method with the model", ->
it "constructs a view element by calling the createView method with the creation params", ->
class TestModel
class TestView
setModel: (@model) ->
initialize: (@params) ->
registry.addViewProvider
factory.addViewProvider
modelConstructor: TestModel
createView: (model) ->
createView: (params) ->
view = new TestView
view.setModel(model)
view.initialize(params)
view
model = new TestModel
view = registry.getView(model)
view = factory.createView(model, a: 1)
expect(view instanceof TestView).toBe true
expect(view.model).toBe model
expect(view.params.a).toBe 1
expect(view.params.model).toBe model
describe "when no view provider is registered for the object's constructor", ->
describe "when the object has a .getViewClass() method", ->
describe "when the object has a .createViewClass() method", ->
beforeEach ->
jasmine.snapshotDeprecations()
afterEach ->
jasmine.restoreDeprecationsSnapshot()
it "builds an instance of the view class with the model, then returns its root node with a __spacePenView property pointing at the view", ->
class TestView extends View
@content: (model) -> @div model.name
@@ -79,29 +88,26 @@ describe "ViewRegistry", ->
getViewClass: -> TestView
model = new TestModel("hello")
node = registry.getView(model)
node = factory.createView(model)
expect(node.textContent).toBe "hello"
view = node.__spacePenView
expect(view instanceof TestView).toBe true
expect(view.model).toBe model
# returns the same DOM node for repeated calls
expect(registry.getView(model)).toBe node
describe "when the object has no .getViewClass() method", ->
describe "when the object has no .createViewClass() method", ->
it "throws an exception", ->
expect(-> registry.getView(new Object)).toThrow()
expect(-> factory.createView(new Object)).toThrow()
describe "::addViewProvider(providerSpec)", ->
it "returns a disposable that can be used to remove the provider", ->
class TestModel
class TestView
setModel: (@model) ->
disposable = registry.addViewProvider
initialize: ->
disposable = factory.addViewProvider
modelConstructor: TestModel
viewConstructor: TestView
expect(registry.getView(new TestModel) instanceof TestView).toBe true
expect(factory.createView(new TestModel) instanceof TestView).toBe true
disposable.dispose()
expect(-> registry.getView(new TestModel)).toThrow()
expect(-> factory.createView(new TestModel)).toThrow()
+6 -7
Ver Arquivo
@@ -1,4 +1,4 @@
{$, $$} = require 'atom'
{$, $$} = require '../src/space-pen-extensions'
path = require 'path'
TextEditor = require '../src/text-editor'
WindowEventHandler = require '../src/window-event-handler'
@@ -259,24 +259,23 @@ describe "Window", ->
describe "when the opened path exists", ->
it "sets the project path to the opened path", ->
$(window).trigger('window:open-path', [{pathToOpen: __filename}])
atom.getCurrentWindow().send 'message', 'open-path', pathToOpen: __filename
expect(atom.project.getPaths()[0]).toBe __dirname
describe "when the opened path does not exist but its parent directory does", ->
it "sets the project path to the opened path's parent directory", ->
$(window).trigger('window:open-path', [{pathToOpen: path.join(__dirname, 'this-path-does-not-exist.txt')}])
pathToOpen = path.join(__dirname, 'this-path-does-not-exist.txt')
atom.getCurrentWindow().send 'message', 'open-path', {pathToOpen}
expect(atom.project.getPaths()[0]).toBe __dirname
describe "when the opened path is a file", ->
it "opens it in the workspace", ->
$(window).trigger('window:open-path', [{pathToOpen: __filename}])
atom.getCurrentWindow().send 'message', 'open-path', pathToOpen: __filename
expect(atom.workspace.open.mostRecentCall.args[0]).toBe __filename
describe "when the opened path is a directory", ->
it "does not open it in the workspace", ->
$(window).trigger('window:open-path', [{pathToOpen: __dirname}])
atom.getCurrentWindow().send 'message', 'open-path', pathToOpen: __dirname
expect(atom.workspace.open.callCount).toBe 0
+22 -8
Ver Arquivo
@@ -375,7 +375,7 @@ describe "Workspace", ->
describe "document.title", ->
describe "when the project has no path", ->
it "sets the title to 'untitled'", ->
atom.project.setPath(undefined)
atom.project.setPaths([])
expect(document.title).toBe 'untitled - Atom'
describe "when the project has a path", ->
@@ -458,45 +458,59 @@ describe "Workspace", ->
expect(atom.setDocumentEdited).toHaveBeenCalledWith(false)
describe "adding panels", ->
class TestPanel
constructior: ->
class TestItem
describe '::addLeftPanel(model)', ->
it 'adds a panel to the correct panel container', ->
expect(atom.workspace.getLeftPanels().length).toBe(0)
atom.workspace.panelContainers.left.onDidAddPanel addPanelSpy = jasmine.createSpy()
panel = atom.workspace.addLeftPanel(item: new TestPanel())
model = new TestItem
panel = atom.workspace.addLeftPanel(item: model)
expect(panel).toBeDefined()
expect(addPanelSpy).toHaveBeenCalledWith({panel, index: 0})
describe '::addRightPanel(model)', ->
it 'adds a panel to the correct panel container', ->
expect(atom.workspace.getRightPanels().length).toBe(0)
atom.workspace.panelContainers.right.onDidAddPanel addPanelSpy = jasmine.createSpy()
panel = atom.workspace.addRightPanel(item: new TestPanel())
model = new TestItem
panel = atom.workspace.addRightPanel(item: model)
expect(panel).toBeDefined()
expect(addPanelSpy).toHaveBeenCalledWith({panel, index: 0})
describe '::addTopPanel(model)', ->
it 'adds a panel to the correct panel container', ->
expect(atom.workspace.getTopPanels().length).toBe(0)
atom.workspace.panelContainers.top.onDidAddPanel addPanelSpy = jasmine.createSpy()
panel = atom.workspace.addTopPanel(item: new TestPanel())
model = new TestItem
panel = atom.workspace.addTopPanel(item: model)
expect(panel).toBeDefined()
expect(addPanelSpy).toHaveBeenCalledWith({panel, index: 0})
describe '::addBottomPanel(model)', ->
it 'adds a panel to the correct panel container', ->
expect(atom.workspace.getBottomPanels().length).toBe(0)
atom.workspace.panelContainers.bottom.onDidAddPanel addPanelSpy = jasmine.createSpy()
panel = atom.workspace.addBottomPanel(item: new TestPanel())
model = new TestItem
panel = atom.workspace.addBottomPanel(item: model)
expect(panel).toBeDefined()
expect(addPanelSpy).toHaveBeenCalledWith({panel, index: 0})
describe '::addModalPanel(model)', ->
it 'adds a panel to the correct panel container', ->
expect(atom.workspace.getModalPanels().length).toBe(0)
atom.workspace.panelContainers.modal.onDidAddPanel addPanelSpy = jasmine.createSpy()
panel = atom.workspace.addModalPanel(item: new TestPanel())
model = new TestItem
panel = atom.workspace.addModalPanel(item: model)
expect(panel).toBeDefined()
expect(addPanelSpy).toHaveBeenCalledWith({panel, index: 0})
+9 -4
Ver Arquivo
@@ -1,4 +1,4 @@
{$, $$, WorkspaceView, View} = require 'atom'
{$, $$, View} = require '../src/space-pen-extensions'
Q = require 'q'
path = require 'path'
temp = require 'temp'
@@ -10,16 +10,21 @@ describe "WorkspaceView", ->
pathToOpen = null
beforeEach ->
jasmine.snapshotDeprecations()
atom.project.setPaths([atom.project.resolve('dir')])
pathToOpen = atom.project.resolve('a')
atom.workspace = new Workspace
atom.workspaceView = atom.views.getView(atom.workspace).__spacePenView
atom.workspaceView = atom.views.createView(atom.workspace).__spacePenView
atom.workspaceView.enableKeymap()
atom.workspaceView.focus()
waitsForPromise ->
atom.workspace.open(pathToOpen)
afterEach ->
jasmine.restoreDeprecationsSnapshot()
describe "@deserialize()", ->
viewState = null
@@ -29,7 +34,7 @@ describe "WorkspaceView", ->
atom.workspaceView.remove()
atom.project = atom.deserializers.deserialize(projectState)
atom.workspace = Workspace.deserialize(workspaceState)
atom.workspaceView = atom.views.getView(atom.workspace).__spacePenView
atom.workspaceView = atom.views.createView(atom.workspace).__spacePenView
atom.workspaceView.attachToDom()
describe "when the serialized WorkspaceView has an unsaved buffer", ->
@@ -274,7 +279,7 @@ describe "WorkspaceView", ->
describe 'panel containers', ->
workspaceElement = null
beforeEach ->
workspaceElement = atom.views.getView(atom.workspace)
workspaceElement = atom.views.createView(atom.workspace)
it 'inserts panel container elements in the correct places in the DOM', ->
leftContainer = workspaceElement.querySelector('atom-panel-container.left')
+11 -5
Ver Arquivo
@@ -39,7 +39,7 @@ class Atom extends Model
atom.workspaceView is no longer available.
In most cases you will not need the view. See the Workspace docs for
alternatives: https://atom.io/docs/api/latest/Workspace.
If you do need the view, please use `atom.views.getView(atom.workspace)`,
If you do need the view, please use `document.querySelector('atom-workspace')`,
which returns an HTMLElement.
"""
@@ -167,7 +167,7 @@ class Atom extends Model
# Public: A {DeserializerManager} instance
deserializers: null
# Public: A {ViewRegistry} instance
# Public: A {ViewFactory} instance
views: null
# Public: A {Workspace} instance
@@ -220,7 +220,7 @@ class Atom extends Model
Config = require './config'
KeymapManager = require './keymap-extensions'
ViewRegistry = require './view-registry'
ViewFactory = require './view-factory'
CommandRegistry = require './command-registry'
TooltipManager = require './tooltip-manager'
NotificationManager = require './notification-manager'
@@ -253,7 +253,7 @@ class Atom extends Model
@tooltips = new TooltipManager
@notifications = new NotificationManager
@commands = new CommandRegistry
@views = new ViewRegistry
@views = new ViewFactory
@packages = new PackageManager({devMode, configDirPath, resourcePath, safeMode})
@styles = new StyleManager
document.head.appendChild(new StylesElement)
@@ -681,7 +681,7 @@ class Atom extends Model
startTime = Date.now()
@workspace = Workspace.deserialize(@state.workspace) ? new Workspace
workspaceElement = @views.getView(@workspace)
workspaceElement = @views.createView(@workspace)
@__workspaceView = workspaceElement.__spacePenView
@deserializeTimings.workspace = Date.now() - startTime
@@ -783,6 +783,12 @@ class Atom extends Model
else
window[key] = value
onUpdateAvailable: (callback) ->
@emitter.on 'update-available', callback
updateAvailable: (details) ->
@emitter.emit 'update-available', details
# Deprecated: Callers should be converted to use atom.deserializers
registerRepresentationClass: ->
deprecate("Callers should be converted to use atom.deserializers")
+5 -3
Ver Arquivo
@@ -58,7 +58,7 @@ class AtomWindow
@browserWindow.loadUrl @getUrl(loadSettings)
@browserWindow.focusOnWebView() if @isSpec
@openPath(pathToOpen, initialLine, initialColumn)
@openPath(pathToOpen, initialLine, initialColumn) unless @isSpecWindow()
getUrl: (loadSettingsObj) ->
# Ignore the windowState when passing loadSettings via URL, since it could
@@ -143,10 +143,13 @@ class AtomWindow
openPath: (pathToOpen, initialLine, initialColumn) ->
if @loaded
@focus()
@sendCommand('window:open-path', {pathToOpen, initialLine, initialColumn})
@sendMessage 'open-path', {pathToOpen, initialLine, initialColumn}
else
@browserWindow.once 'window:loaded', => @openPath(pathToOpen, initialLine, initialColumn)
sendMessage: (message, detail) ->
@browserWindow.webContents.send 'message', message, detail
sendCommand: (command, args...) ->
if @isSpecWindow()
unless global.atomApplication.sendCommandToFirstResponder(command)
@@ -154,7 +157,6 @@ class AtomWindow
when 'window:reload' then @reload()
when 'window:toggle-dev-tools' then @toggleDevTools()
when 'window:close' then @close()
when 'window:update-available' then @sendCommandToBrowserWindow(command, args...) # For spec testing
else if @isWebViewFocused()
@sendCommandToBrowserWindow(command, args...)
else
+1 -1
Ver Arquivo
@@ -56,7 +56,7 @@ class AutoUpdateManager
emitUpdateAvailableEvent: (windows...) ->
return unless @releaseVersion? and @releaseNotes
for atomWindow in windows
atomWindow.sendCommand('window:update-available', [@releaseVersion, @releaseNotes])
atomWindow.sendMessage('update-available', {@releaseVersion, @releaseNotes})
setState: (state) ->
return if @state is state
+1 -1
Ver Arquivo
@@ -8,7 +8,7 @@ class ContextMenu
menu.popup(@atomWindow.browserWindow)
# It's necessary to build the event handlers in this process, otherwise
# closures are drug across processes and failed to be garbage collected
# closures are dragged across processes and failed to be garbage collected
# appropriately.
createClickHandlers: (template) ->
for item in template
+3
Ver Arquivo
@@ -889,6 +889,9 @@ class DisplayBuffer extends Model
allDecorations = allDecorations.concat(decorations) if decorations?
allDecorations
getOverlayDecorations: ->
@getDecorations().filter (decoration) -> decoration.isType('overlay')
decorationsForScreenRowRange: (startScreenRow, endScreenRow) ->
decorationsByMarkerId = {}
for marker in @findMarkers(intersectsScreenRowRange: [startScreenRow, endScreenRow])
+2 -2
Ver Arquivo
@@ -66,10 +66,10 @@ LinesComponent = React.createClass
insertionPoint = document.createElement('content')
insertionPoint.setAttribute('select', 'atom-overlay')
@overlayManager = new OverlayManager(@props.hostElement)
@overlayManager = new OverlayManager(@props.hostElement, @props.hostElement.viewRegistry)
@getDOMNode().appendChild(insertionPoint)
else
@overlayManager = new OverlayManager(@getDOMNode())
@overlayManager = new OverlayManager(@getDOMNode(), @props.hostElement.viewRegistry)
shouldComponentUpdate: (newProps) ->
return true unless isEqualForProperties(newProps, @props,
+7 -4
Ver Arquivo
@@ -1,15 +1,18 @@
module.exports =
class OverlayManager
constructor: (@container) ->
constructor: (@container, @viewRegistry) ->
@overlays = {}
render: (props) ->
{editor, overlayDecorations, lineHeightInPixels} = props
existingDecorations = null
for markerId, {isMarkerReversed, headPixelPosition, decorations} of overlayDecorations
for markerId, {headPixelPosition, tailPixelPosition, decorations} of overlayDecorations
for decoration in decorations
@renderOverlay(editor, decoration, headPixelPosition, lineHeightInPixels)
pixelPosition =
if decoration.position is 'tail' then tailPixelPosition else headPixelPosition
@renderOverlay(editor, decoration, pixelPosition, lineHeightInPixels)
existingDecorations ?= {}
existingDecorations[decoration.id] = true
@@ -22,7 +25,7 @@ class OverlayManager
return
renderOverlay: (editor, decoration, pixelPosition, lineHeightInPixels) ->
item = atom.views.getView(decoration.item)
item = @viewRegistry.getView(decoration.item)
unless overlay = @overlays[decoration.id]
overlay = @overlays[decoration.id] = document.createElement('atom-overlay')
overlay.appendChild(item)
+3 -3
Ver Arquivo
@@ -8,7 +8,7 @@ class PaneAxisElement extends HTMLElement
detachedCallback: ->
@subscriptions.dispose()
setModel: (@model) ->
initialize: ({@viewRegistry, @model}) ->
@subscriptions.add @model.onDidAddChild(@childAdded.bind(this))
@subscriptions.add @model.onDidRemoveChild(@childRemoved.bind(this))
@subscriptions.add @model.onDidReplaceChild(@childReplaced.bind(this))
@@ -22,12 +22,12 @@ class PaneAxisElement extends HTMLElement
@classList.add('vertical', 'pane-column')
childAdded: ({child, index}) ->
view = @model.getView(child)
view = @viewRegistry.getView(child)
@insertBefore(view, @children[index])
callAttachHooks(view) # for backward compatibility with SpacePen views
childRemoved: ({child}) ->
view = @model.getView(child)
view = @viewRegistry.getView(child)
view.remove()
childReplaced: ({index, oldChild, newChild}) ->
-3
Ver Arquivo
@@ -39,9 +39,6 @@ class PaneAxis extends Model
getOrientation: -> @orientation
getView: (object) ->
@container.getView(object)
getChildren: -> @children.slice()
getPanes: ->
+3 -3
Ver Arquivo
@@ -11,7 +11,7 @@ class PaneContainerElement extends HTMLElement
PaneContainerView ?= require './pane-container-view'
@__spacePenView = new PaneContainerView(this)
setModel: (@model) ->
initialize: ({@viewRegistry, @model}) ->
@subscriptions.add @model.observeRoot(@rootChanged.bind(this))
@__spacePenView.setModel(@model)
@@ -19,7 +19,7 @@ class PaneContainerElement extends HTMLElement
focusedElement = document.activeElement if @hasFocus()
@firstChild?.remove()
if root?
view = @model.getView(root)
view = @viewRegistry.getView(root)
@appendChild(view)
callAttachHooks(view)
focusedElement?.focus()
@@ -45,7 +45,7 @@ class PaneContainerElement extends HTMLElement
y = pointB.y - pointA.y
Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2))
paneView = @model.getView(@model.getActivePane())
paneView = @viewRegistry.getView(@model.getActivePane())
box = @boundingBoxForPaneView(paneView)
paneViews = _.toArray(@querySelectorAll('atom-pane'))
+3 -3
Ver Arquivo
@@ -23,7 +23,7 @@ class PaneContainerView extends View
@subscriptions.add @model.onDidChangeActivePaneItem(@onActivePaneItemChanged)
getRoot: ->
view = @model.getView(@model.getRoot())
view = @element.viewRegistry.getView(@model.getRoot())
view.__spacePenView ? view
onActivePaneItemChanged: (activeItem) =>
@@ -55,7 +55,7 @@ class PaneContainerView extends View
@getActivePaneView()
getActivePaneView: ->
@model.getView(@model.getActivePane()).__spacePenView
@element.viewRegistry.getView(@model.getActivePane()).__spacePenView
getActivePaneItem: ->
@model.getActivePaneItem()
@@ -64,7 +64,7 @@ class PaneContainerView extends View
@getActivePaneView()?.activeView
paneForUri: (uri) ->
@model.getView(@model.paneForUri(uri)).__spacePenView
@element.viewRegistry.getView(@model.paneForUri(uri)).__spacePenView
focusNextPaneView: ->
@model.activateNextPane()
+4 -9
Ver Arquivo
@@ -9,7 +9,6 @@ PaneAxisElement = require './pane-axis-element'
PaneAxis = require './pane-axis'
TextEditor = require './text-editor'
TextEditorElement = require './text-editor-element'
ViewRegistry = require './view-registry'
ItemRegistry = require './item-registry'
module.exports =
@@ -36,7 +35,6 @@ class PaneContainer extends Model
@subscriptions = new CompositeDisposable
@itemRegistry = new ItemRegistry
@viewRegistry = params?.viewRegistry ? new ViewRegistry
@registerViewProviders()
@setRoot(params?.root ? new Pane)
@@ -58,25 +56,22 @@ class PaneContainer extends Model
activePaneId: @activePane.id
registerViewProviders: ->
@viewRegistry.addViewProvider
atom.views.addViewProvider
modelConstructor: PaneContainer
viewConstructor: PaneContainerElement
@viewRegistry.addViewProvider
atom.views.addViewProvider
modelConstructor: PaneAxis
viewConstructor: PaneAxisElement
@viewRegistry.addViewProvider
atom.views.addViewProvider
modelConstructor: Pane
viewConstructor: PaneElement
@viewRegistry.addViewProvider
atom.views.addViewProvider
modelConstructor: TextEditor
viewConstructor: TextEditorElement
getView: (object) ->
@viewRegistry.getView(object)
onDidChangeRoot: (fn) ->
@emitter.on 'did-change-root', fn
+7 -7
Ver Arquivo
@@ -43,9 +43,7 @@ class PaneElement extends HTMLElement
createSpacePenShim: ->
@__spacePenView = new PaneView(this)
getModel: -> @model
setModel: (@model) ->
initialize: ({@viewRegistry, @model}) ->
@subscriptions.add @model.onDidActivate(@activated.bind(this))
@subscriptions.add @model.observeActive(@activeStatusChanged.bind(this))
@subscriptions.add @model.observeActiveItem(@activeItemChanged.bind(this))
@@ -53,8 +51,10 @@ class PaneElement extends HTMLElement
@subscriptions.add @model.onDidDestroy(@paneDestroyed.bind(this))
@__spacePenView.setModel(@model)
getModel: -> @model
activated: ->
@focus() unless @hasFocus()
@focus()
activeStatusChanged: (active) ->
if active
@@ -66,7 +66,7 @@ class PaneElement extends HTMLElement
return unless item?
hasFocus = @hasFocus()
itemView = @model.getView(item)
itemView = @viewRegistry.getView(item)
unless @itemViews.contains(itemView)
@itemViews.appendChild(itemView)
@@ -94,14 +94,14 @@ class PaneElement extends HTMLElement
itemView.style.display = 'none'
itemRemoved: ({item, index, destroyed}) ->
if viewToRemove = @model.getView(item)
if viewToRemove = @viewRegistry.getView(item)
callRemoveHooks(viewToRemove) if destroyed
viewToRemove.remove()
paneDestroyed: ->
@subscriptions.dispose()
getActiveView: -> @model.getView(@model.getActiveItem())
getActiveView: -> @viewRegistry.getView(@model.getActiveItem())
hasFocus: ->
this is document.activeElement or @contains(document.activeElement)
+5 -5
Ver Arquivo
@@ -153,15 +153,15 @@ class PaneView extends View
activeItemModifiedChanged: =>
@trigger 'pane:active-item-modified-status-changed'
@::accessor 'activeView', -> @model.getView(@activeItem)?.__spacePenView
@::accessor 'activeView', -> @element.viewRegistry.getView(@activeItem)?.__spacePenView
splitLeft: (items...) -> @model.getView(@model.splitLeft({items})).__spacePenView
splitLeft: (items...) -> @element.viewRegistry.getView(@model.splitLeft({items})).__spacePenView
splitRight: (items...) -> @model.getView(@model.splitRight({items})).__spacePenView
splitRight: (items...) -> @element.viewRegistry.getView(@model.splitRight({items})).__spacePenView
splitUp: (items...) -> @model.getView(@model.splitUp({items})).__spacePenView
splitUp: (items...) -> @element.viewRegistry.getView(@model.splitUp({items})).__spacePenView
splitDown: (items...) -> @model.getView(@model.splitDown({items})).__spacePenView
splitDown: (items...) -> @element.viewRegistry.getView(@model.splitDown({items})).__spacePenView
getContainer: -> @closest('atom-pane-container').view()
-3
Ver Arquivo
@@ -53,9 +53,6 @@ class Pane extends Model
params.activeItem = find params.items, (item) -> item.getUri?() is activeItemUri
params
getView: (object) ->
@container.getView(object)
getParent: -> @parent
setParent: (@parent) -> @parent
+3 -3
Ver Arquivo
@@ -6,14 +6,14 @@ class PanelContainerElement extends HTMLElement
getModel: -> @model
setModel: (@model) ->
initialize: ({@viewRegistry, @model}) ->
@subscriptions.add @model.onDidAddPanel(@panelAdded.bind(this))
@subscriptions.add @model.onDidRemovePanel(@panelRemoved.bind(this))
@subscriptions.add @model.onDidDestroy(@destroyed.bind(this))
@classList.add(@model.getLocation())
panelAdded: ({panel, index}) ->
panelElement = panel.getView()
panelElement = @viewRegistry.getView(panel)
panelElement.classList.add(@model.getLocation())
if @model.isModal()
panelElement.classList.add("overlay", "from-top")
@@ -32,7 +32,7 @@ class PanelContainerElement extends HTMLElement
@hideAllPanelsExcept(panel) if visible
panelRemoved: ({panel, index}) ->
@removeChild(panel.getView())
@removeChild(@viewRegistry.getView(panel))
destroyed: ->
@subscriptions.dispose()
+1 -3
Ver Arquivo
@@ -2,7 +2,7 @@
module.exports =
class PanelContainer
constructor: ({@viewRegistry, @location}) ->
constructor: ({@location}={}) ->
@emitter = new Emitter
@subscriptions = new CompositeDisposable
@panels = []
@@ -30,8 +30,6 @@ class PanelContainer
Section: Panels
###
getView: -> @viewRegistry.getView(this)
getLocation: -> @location
isModal: -> @location is 'modal'
+6 -4
Ver Arquivo
@@ -7,16 +7,18 @@ class PanelElement extends HTMLElement
getModel: -> @model
setModel: (@model) ->
view = @model.getItemView()
@appendChild(view)
callAttachHooks(view) # for backward compatibility with SpacePen views
initialize: ({@viewRegistry, @model}) ->
@appendChild(@getItemView())
@classList.add(@model.getClassName().split(' ')...) if @model.getClassName()?
@subscriptions.add @model.onDidChangeVisible(@visibleChanged.bind(this))
@subscriptions.add @model.onDidDestroy(@destroyed.bind(this))
getItemView: ->
@viewRegistry.getView(@model.getItem())
attachedCallback: ->
callAttachHooks(@getItemView()) # for backward compatibility with SpacePen views
@visibleChanged(@model.isVisible())
visibleChanged: (visible) ->
+3 -10
Ver Arquivo
@@ -14,7 +14,7 @@ class Panel
Section: Construction and Destruction
###
constructor: ({@viewRegistry, @item, @visible, @priority, @className}) ->
constructor: ({@item, @visible, @priority, @className}) ->
@emitter = new Emitter
@visible ?= true
@priority ?= 100
@@ -50,15 +50,8 @@ class Panel
Section: Panel Details
###
# Public: Gets this panel model's view DOM node.
#
# Returns an `<atom-panel>` {Element}
getView: -> @viewRegistry.getView(this)
# Public: Gets your panel contents view.
#
# Returns an {Element} or jQuery element, depeneding on how you created the panel.
getItemView: -> @viewRegistry.getView(@item)
# Public: Returns the panel's item.
getItem: -> @item
# Public: Returns a {Number} indicating this panel's priority.
getPriority: -> @priority
+1 -1
Ver Arquivo
@@ -64,7 +64,7 @@ class Project extends Model
###
serializeParams: ->
path: @path
paths: @getPaths()
buffers: _.compact(@buffers.map (buffer) -> buffer.serialize() if buffer.isRetained())
deserializeParams: (params) ->
+5 -6
Ver Arquivo
@@ -20,9 +20,6 @@ TextEditorComponent = React.createClass
displayName: 'TextEditorComponent'
mixins: [SubscriberMixin]
statics:
performSyncUpdates: false
visible: false
autoHeight: false
backgroundColor: null
@@ -242,7 +239,7 @@ TextEditorComponent = React.createClass
@updateRequestedWhilePaused = true
return
if @performSyncUpdates ? TextEditorComponent.performSyncUpdates
if @props.hostElement.isUpdatedSynchronously()
@forceUpdate()
else unless @updateRequested
@updateRequested = true
@@ -363,14 +360,16 @@ TextEditorComponent = React.createClass
filteredDecorations = {}
for markerId, decorations of decorationsByMarkerId
marker = editor.getMarker(markerId)
headBufferPosition = marker.getHeadBufferPosition()
headScreenPosition = marker.getHeadScreenPosition()
tailScreenPosition = marker.getTailScreenPosition()
if marker.isValid()
for decoration in decorations
if decoration.isType('overlay')
decorationParams = decoration.getProperties()
filteredDecorations[markerId] ?=
id: markerId
headPixelPosition: editor.pixelPositionForScreenPosition(headBufferPosition)
headPixelPosition: editor.pixelPositionForScreenPosition(headScreenPosition)
tailPixelPosition: editor.pixelPositionForScreenPosition(tailScreenPosition)
decorations: []
filteredDecorations[markerId].decorations.push decorationParams
filteredDecorations
+7
Ver Arquivo
@@ -63,6 +63,9 @@ class TextEditorElement extends HTMLElement
@component.checkForVisibilityChange()
@focus() if @focusOnAttach
initialize: ({@viewRegistry, @lineOverdrawMargin, model}) ->
@setModel(model)
setModel: (model) ->
throw new Error("Model already assigned on TextEditorElement") if @model?
return if model.isDestroyed()
@@ -153,6 +156,10 @@ class TextEditorElement extends HTMLElement
hasFocus: ->
this is document.activeElement or @contains(document.activeElement)
setUpdatedSynchronously: (@updatedSynchronously) -> @updatedSynchronously
isUpdatedSynchronously: -> @updatedSynchronously
stopEventPropagation = (commandListeners) ->
newCommandListeners = {}
for commandName, commandListener of commandListeners
+1 -1
Ver Arquivo
@@ -63,7 +63,7 @@ class TextEditorView extends View
element = new TextEditorElement
element.lineOverdrawMargin = props?.lineOverdrawMargin
element.setAttribute(name, value) for name, value of attributes if attributes?
element.setModel(model)
element.initialize({model})
return element.__spacePenView
# Handle construction with an element
+36 -9
Ver Arquivo
@@ -1263,18 +1263,33 @@ class TextEditor extends Model
# ## Arguments
#
# * `marker` A {Marker} you want this decoration to follow.
# * `decorationParams` An {Object} representing the decoration e.g. `{type: 'gutter', class: 'linter-error'}`
# * `type` There are a few supported decoration types: `gutter`, `line`, and `highlight`
# * `decorationParams` An {Object} representing the decoration e.g.
# `{type: 'gutter', class: 'linter-error'}`
# * `type` There are a few supported decoration types: `gutter`, `line`,
# `highlight`, and `overlay`. The behavior of the types are as follows:
# * `gutter` Adds the given `class` to the line numbers overlapping the
# rows spanned by the marker.
# * `line` Adds the given `class` to the lines overlapping the rows
# spanned by the marker.
# * `highlight` Creates a `.highlight` div with the nested class with up
# to 3 nested regions that fill the area spanned by the marker.
# * `overlay` Positions the view associated with the given item at the
# head or tail of the given marker, depending on the `position`
# property.
# * `class` This CSS class will be applied to the decorated line number,
# line, or highlight.
# * `onlyHead` (optional) If `true`, the decoration will only be applied to the head
# of the marker. Only applicable to the `line` and `gutter` types.
# * `onlyEmpty` (optional) If `true`, the decoration will only be applied if the
# associated marker is empty. Only applicable to the `line` and
# * `onlyHead` (optional) If `true`, the decoration will only be applied to
# the head of the marker. Only applicable to the `line` and `gutter`
# types.
# * `onlyEmpty` (optional) If `true`, the decoration will only be applied if
# the associated marker is empty. Only applicable to the `line` and
# `gutter` types.
# * `onlyNonEmpty` (optional) If `true`, the decoration will only be applied if the
# associated marker is non-empty. Only applicable to the `line` and
# gutter types.
# * `onlyNonEmpty` (optional) If `true`, the decoration will only be applied
# if the associated marker is non-empty. Only applicable to the `line`
# and gutter types.
# * `position` (optional) Only applicable to decorations of type `overlay`,
# controls where the overlay view is positioned relative to the marker.
# Values can be `'head'` (the default), or `'tail'`.
#
# Returns a {Decoration} object
decorateMarker: (marker, decorationParams) ->
@@ -1293,6 +1308,18 @@ class TextEditor extends Model
decorationsForScreenRowRange: (startScreenRow, endScreenRow) ->
@displayBuffer.decorationsForScreenRowRange(startScreenRow, endScreenRow)
# Extended: Get all decorations.
#
# Returns an {Array} of {Decoration}s.
getDecorations: ->
@displayBuffer.getDecorations()
# Extended: Get all decorations of type 'overlay'.
#
# Returns an {Array} of {Decoration}s.
getOverlayDecorations: ->
@displayBuffer.getOverlayDecorations()
decorationForId: (id) ->
@displayBuffer.decorationForId(id)
+8 -6
Ver Arquivo
@@ -333,16 +333,18 @@ class ThemeManager
isInitialLoadComplete: -> @initialLoadComplete
# FIXME: This should be moved to WorkspaceElement
addActiveThemeClasses: ->
workspaceElement = atom.views.getView(atom.workspace)
for pack in @getActiveThemes()
workspaceElement.classList.add("theme-#{pack.name}")
if workspaceElement = document.querySelector('atom-workspace')
for pack in @getActiveThemes()
workspaceElement.classList.add("theme-#{pack.name}")
return
# FIXME: This should be moved to WorkspaceElement
removeActiveThemeClasses: ->
workspaceElement = atom.views.getView(atom.workspace)
for pack in @getActiveThemes()
workspaceElement.classList.remove("theme-#{pack.name}")
if workspaceElement = document.querySelector('atom-workspace')
for pack in @getActiveThemes()
workspaceElement.classList.remove("theme-#{pack.name}")
return
refreshLessCache: ->
+106
Ver Arquivo
@@ -0,0 +1,106 @@
{Disposable} = require 'event-kit'
Grim = require 'grim'
ViewRegistry = require './view-registry'
# Essential: The `ViewFactory` can creates the appropriate views for a given
# model object based on recipes registered via {::addViewProvider}. It is
# available via `atom.views` as a singleton object.
module.exports =
class ViewFactory
constructor: ->
@providers = []
@deprecatedViewRegistry = new ViewRegistry(this)
# Essential: Add a provider that will be used by {::createView} to construct
# an element based on the constructor of the given model object.
#
# ## Examples
#
# Text editors are divided into a model and a view layer, so when you interact
# with methods like `atom.workspace.getActiveTextEditor()` you're only going
# to get the model object. We display text editors on screen by teaching the
# workspace what view constructor it should use to represent them:
#
# ```coffee
# atom.views.addViewProvider
# modelConstructor: TextEditor
# viewConstructor: TextEditorElement
# ```
#
# * `providerSpec` {Object} containing the following keys:
# * `modelConstructor` Constructor {Function} for your model.
# * `viewConstructor` (Optional) Constructor {Function} for your view. It
# should be a subclass of `HTMLElement` (that is, your view should be a
# DOM node) and have a `::setModel()` method which will be called
# immediately after construction. If you don't supply this property, you
# must supply the `createView` property with a function that never returns
# `undefined`.
# * `createView` (Optional) Factory {Function} that must return a subclass
# of `HTMLElement` or `undefined`. If this property is not present or the
# function returns `undefined`, the view provider will fall back to the
# `viewConstructor` property. If you don't provide this property, you must
# provider a `viewConstructor` property.
#
# Returns a {Disposable} on which `.dispose()` can be called to remove the
# added provider.
addViewProvider: (providerSpec) ->
@providers.push(providerSpec)
new Disposable =>
@providers = @providers.filter (provider) -> provider isnt providerSpec
getView: (object, suppressDeprecationWarning) ->
unless suppressDeprecationWarning
Grim.deprecate("Call ::getView on the workspace element instead. The atom.views global is only intended to create views.")
@deprecatedViewRegistry.getView(object)
# Essential: Create an element for the given model object based on providers
# registered via {::addViewProvider}.
#
# ## Examples
#
# ### Creating a workspace element in specs
# ```coffee
# workspaceElement = atom.views.createView(atom.workspace)
# ```
#
# * `object` The model for which to create the view. A view provider matching
# its constructor must be registered.
# * `params` (optional) An {Object} with which to initialize the view. If the
# selected view provider has a `createView` method, the params will be
# passed to it. If the view provider has a `viewConstructor` method,
# `initialize` will be called on the element after creation with the
# given params.
#
# Returns a DOM element.
createView: (object, params) ->
view =
if object instanceof HTMLElement
object
else if object?.jquery
object[0]?.__spacePenView ?= object
object[0]
else if provider = @findProvider(object)
params ?= {}
params.viewFactory = this
params.model = object
element = provider.createView?(params)
unless element?
element = new provider.viewConstructor
if not (typeof element.initialize is 'function') and (typeof element.setModel is 'function')
Grim.deprecate("Define `::initialize` instead of `::setModel` in your view. It will be passed a params hash including the model.")
element.setModel(object)
else
element.initialize(params)
element
else if viewConstructor = object?.getViewClass?()
Grim.deprecate("Add a view provider for your object on atom.views instead of implementing `::getViewClass`.")
view = new viewConstructor(object)
view[0].__spacePenView ?= view
view[0]
else
throw new Error("Can't create a view for #{object.constructor.name} instance. Please register a view provider.")
@deprecatedViewRegistry.views.set(object, view)
view
findProvider: (object) ->
@providers.find ({modelConstructor}) -> object instanceof modelConstructor
+2 -132
Ver Arquivo
@@ -1,144 +1,14 @@
{Disposable} = require 'event-kit'
# Essential: `ViewRegistry` handles the association between model and view
# types in Atom. We call this association a View Provider. As in, for a given
# model, this class can provide a view via {::getView}, as long as the
# model/view association was registered via {::addViewProvider}
#
# If you're adding your own kind of pane item, a good strategy for all but the
# simplest items is to separate the model and the view. The model handles
# application logic and is the primary point of API interaction. The view
# just handles presentation.
#
# View providers to inform the workspace how your model objects should be
# presented in the DOM. A view provider must always return a DOM node, which
# makes [HTML 5 custom elements](http://www.html5rocks.com/en/tutorials/webcomponents/customelements/)
# an ideal tool for implementing views in Atom.
#
# You can access the `ViewRegistry` object via `atom.views`.
#
# ## Examples
#
# ### Getting the workspace element
#
# ```coffee
# workspaceElement = atom.views.getView(atom.workspace)
# ```
#
# ### Getting An Editor Element
#
# ```coffee
# textEditor = atom.workspace.getActiveTextEditor()
# textEditorElement = atom.views.getView(textEditor)
# ```
#
# ### Getting A Pane Element
#
# ```coffee
# pane = atom.workspace.getActivePane()
# paneElement = atom.views.getView(pane)
# ```
module.exports =
class ViewRegistry
constructor: ->
constructor: (@viewFactory) ->
@views = new WeakMap
@providers = []
# Essential: Add a provider that will be used to construct views in the
# workspace's view layer based on model objects in its model layer.
#
# ## Examples
#
# Text editors are divided into a model and a view layer, so when you interact
# with methods like `atom.workspace.getActiveTextEditor()` you're only going
# to get the model object. We display text editors on screen by teaching the
# workspace what view constructor it should use to represent them:
#
# ```coffee
# atom.views.addViewProvider
# modelConstructor: TextEditor
# viewConstructor: TextEditorElement
# ```
#
# * `providerSpec` {Object} containing the following keys:
# * `modelConstructor` Constructor {Function} for your model.
# * `viewConstructor` (Optional) Constructor {Function} for your view. It
# should be a subclass of `HTMLElement` (that is, your view should be a
# DOM node) and have a `::setModel()` method which will be called
# immediately after construction. If you don't supply this property, you
# must supply the `createView` property with a function that never returns
# `undefined`.
# * `createView` (Optional) Factory {Function} that must return a subclass
# of `HTMLElement` or `undefined`. If this property is not present or the
# function returns `undefined`, the view provider will fall back to the
# `viewConstructor` property. If you don't provide this property, you must
# provider a `viewConstructor` property.
#
# Returns a {Disposable} on which `.dispose()` can be called to remove the
# added provider.
addViewProvider: (providerSpec) ->
@providers.push(providerSpec)
new Disposable =>
@providers = @providers.filter (provider) -> provider isnt providerSpec
# Essential: Get the view associated with an object in the workspace.
#
# If you're just *using* the workspace, you shouldn't need to access the view
# layer, but view layer access may be necessary if you want to perform DOM
# manipulation that isn't supported via the model API.
#
# ## Examples
#
# ### Getting An Editor Element
# ```coffee
# textEditor = atom.workspace.getActiveTextEditor()
# textEditorElement = atom.views.getView(textEditor)
# ```
#
# ### Getting A Pane Element
# ```coffee
# pane = atom.workspace.getActivePane()
# paneElement = atom.views.getView(pane)
# ```
#
# ### Getting The Workspace Element
#
# ```coffee
# workspaceElement = atom.views.getView(atom.workspace)
# ```
#
# * `object` The object for which you want to retrieve a view. This can be a
# pane item, a pane, or the workspace itself.
#
# Returns a DOM element.
getView: (object) ->
return unless object?
if view = @views.get(object)
view
else
view = @createView(object)
view = @viewFactory.createView(object, viewRegistry: this)
@views.set(object, view)
view
createView: (object) ->
if object instanceof HTMLElement
object
else if object?.jquery
object[0]?.__spacePenView ?= object
object[0]
else if provider = @findProvider(object)
element = provider.createView?(object)
unless element?
element = new provider.viewConstructor
element.setModel(object)
element
else if viewConstructor = object?.getViewClass?()
view = new viewConstructor(object)
view[0].__spacePenView ?= view
view[0]
else
throw new Error("Can't create a view for #{object.constructor.name} instance. Please register a view provider.")
findProvider: (object) ->
@providers.find ({modelConstructor}) -> object instanceof modelConstructor
+23 -10
Ver Arquivo
@@ -14,11 +14,32 @@ class WindowEventHandler
constructor: ->
@reloadRequested = false
@subscribe ipc, 'command', (command, args...) ->
@subscribe ipc, 'message', (message, detail) ->
switch message
when 'open-path'
{pathToOpen, initialLine, initialColumn} = detail
unless atom.project?.getPaths().length
if fs.existsSync(pathToOpen) or fs.existsSync(path.dirname(pathToOpen))
atom.project?.setPaths([pathToOpen])
unless fs.isDirectorySync(pathToOpen)
atom.workspace?.open(pathToOpen, {initialLine, initialColumn})
when 'update-available'
atom.updateAvailable(detail)
# FIXME: Remove this when deprecations are removed
{releaseVersion, releaseNotes} = detail
detail = [releaseVersion, releaseNotes]
if workspaceElement = document.querySelector('atom-workspace')
atom.commands.dispatch workspaceElement, "window:update-available", detail
@subscribe ipc, 'command', (command, args...) ->
activeElement = document.activeElement
# Use the workspace element view if body has focus
if activeElement is document.body and workspaceElement = atom.views.getView(atom.workspace)
if activeElement is document.body and workspaceElement = document.querySelector('atom-workspace')
activeElement = workspaceElement
atom.commands.dispatch(activeElement, command, args[0])
@@ -30,14 +51,6 @@ class WindowEventHandler
@subscribe $(window), 'blur', -> document.body.classList.add('is-blurred')
@subscribeToCommand $(window), 'window:open-path', (event, {pathToOpen, initialLine, initialColumn}) ->
unless atom.project?.getPath()
if fs.existsSync(pathToOpen) or fs.existsSync(path.dirname(pathToOpen))
atom.project?.setPath(pathToOpen)
unless fs.isDirectorySync(pathToOpen)
atom.workspace?.open(pathToOpen, {initialLine, initialColumn})
@subscribe $(window), 'beforeunload', =>
confirmed = atom.workspace?.confirmClose()
atom.hide() if confirmed and not @reloadRequested and atom.getCurrentWindow().isWebViewFocused()
+63 -8
Ver Arquivo
@@ -6,9 +6,37 @@ scrollbarStyle = require 'scrollbar-style'
{callAttachHooks} = require 'space-pen'
WorkspaceView = null
# Essential: The on-screen representation of the workspace. Unless you have
# an explicit need access the view layer, you should prefer using the
# {Workspace} model object via `atom.workspace`.
#
# ## Examples
#
# In specs, you can create a workspace element via the view factory and attach
# it to the DOM:
#
# ```coffee
# workspaceElement = atom.views.createElement(atom.workspace)
# jasmine.attachToDOM(workspaceElement)
#
# # Get a reference to a nested element corresponding to a model object...
# editorElement = workspaceElement.getView(atom.workspace.getActiveTextEditor)
# ```
#
# In production, you can access the singleton instance of the workspace element
# by pulling it directly from the DOM:
#
# ```coffee
# workspaceElement = document.querySelector('atom-workspace')
#
# # Careful! Direct DOM manipulation is more likely to break as Atom changes
# workspaceElement.addClass("foo")
# ```
module.exports =
class WorkspaceElement extends HTMLElement
globalTextEditorStyleSheet: null
viewRegistry: null
model: null
createdCallback: ->
@subscriptions = new CompositeDisposable
@@ -62,19 +90,20 @@ class WorkspaceElement extends HTMLElement
WorkspaceView ?= require './workspace-view'
@__spacePenView = new WorkspaceView(this)
getModel: -> @model
initialize: ({@viewFactory, @model}) ->
@viewRegistry = @viewFactory.deprecatedViewRegistry
atom.views.deprecatedViewRegistry = @viewRegistry
setModel: (@model) ->
@paneContainer = atom.views.getView(@model.paneContainer)
@paneContainer = @viewRegistry.getView(@model.paneContainer)
@verticalAxis.appendChild(@paneContainer)
@addEventListener 'focus', @handleFocus.bind(this)
@panelContainers =
top: @model.panelContainers.top.getView()
left: @model.panelContainers.left.getView()
right: @model.panelContainers.right.getView()
bottom: @model.panelContainers.bottom.getView()
modal: @model.panelContainers.modal.getView()
top: @viewRegistry.getView(@model.panelContainers.top)
left: @viewRegistry.getView(@model.panelContainers.left)
right: @viewRegistry.getView(@model.panelContainers.right)
bottom: @viewRegistry.getView(@model.panelContainers.bottom)
modal: @viewRegistry.getView(@model.panelContainers.modal)
@horizontalAxis.insertBefore(@panelContainers.left, @verticalAxis)
@horizontalAxis.appendChild(@panelContainers.right)
@@ -86,6 +115,32 @@ class WorkspaceElement extends HTMLElement
@__spacePenView.setModel(@model)
getModel: -> @model
# Essential: Get the view associated with a model in the workspace.
#
# ## Examples
#
# ### Get the active text editor's view element
# ```coffee
# # At the model level...
# activeTextEditor = atom.workspace.getActiveTextEditor()
#
# # At the view level...
# workspaceElement = document.querySelector('atom-workspace')
# textEditorElement = workspaceElement.getView(activeTextEditor)
#
# # Now manipulate the text editor's DOM at your own risk...
# ```
#
# * `model` A model object that's present in the workspace. It could be a
# workspace model object such as a {Pane} or a {Panel}, or it could be a
# third-party model such as a pane or panel's *item*.
#
# Returns a DOM element.
getView: (model) ->
@viewRegistry.getView(model)
setTextEditorFontSize: (fontSize) ->
@updateGlobalEditorStyle('font-size', fontSize + 'px')
+1 -1
Ver Arquivo
@@ -59,7 +59,7 @@ class WorkspaceView extends View
constructor: (@element) ->
unless @element?
return atom.views.getView(atom.workspace).__spacePenView
return atom.views.getView(atom.workspace, true).__spacePenView
super
@deprecateViewEvents()
+54 -26
Ver Arquivo
@@ -14,7 +14,6 @@ Panel = require './panel'
PanelElement = require './panel-element'
PanelContainer = require './panel-container'
PanelContainerElement = require './panel-container-element'
ViewRegistry = require './view-registry'
WorkspaceElement = require './workspace-element'
# Essential: Represents the state of the user interface for the entire window.
@@ -34,7 +33,6 @@ class Workspace extends Model
@delegatesProperty 'activePane', 'activePaneItem', toProperty: 'paneContainer'
@properties
viewRegistry: null
paneContainer: null
fullScreen: false
destroyedItemUris: -> []
@@ -45,16 +43,15 @@ class Workspace extends Model
@emitter = new Emitter
@openers = []
viewRegistry = atom.views
@paneContainer ?= new PaneContainer({viewRegistry})
@paneContainer ?= new PaneContainer()
@paneContainer.onDidDestroyPaneItem(@onPaneItemDestroyed)
@panelContainers =
top: new PanelContainer({viewRegistry, location: 'top'})
left: new PanelContainer({viewRegistry, location: 'left'})
right: new PanelContainer({viewRegistry, location: 'right'})
bottom: new PanelContainer({viewRegistry, location: 'bottom'})
modal: new PanelContainer({viewRegistry, location: 'modal'})
top: new PanelContainer({location: 'top'})
left: new PanelContainer({location: 'left'})
right: new PanelContainer({location: 'right'})
bottom: new PanelContainer({location: 'bottom'})
modal: new PanelContainer({location: 'modal'})
@subscribeToActiveItem()
@@ -86,7 +83,6 @@ class Workspace extends Model
for packageName in params.packagesWithActiveGrammars ? []
atom.packages.getLoadedPackage(packageName)?.loadGrammarsSync()
params.paneContainer.viewRegistry = atom.views
params.paneContainer = PaneContainer.deserialize(params.paneContainer)
params
@@ -377,11 +373,15 @@ class Workspace extends Model
# * `activatePane` A {Boolean} indicating whether to call {Pane::activate} on
# the containing pane. Defaults to `true`.
openSync: (uri='', options={}) ->
deprecate("Don't use the `changeFocus` option") if options.changeFocus?
# TODO: Remove deprecated changeFocus option
if options.changeFocus?
deprecate("The `changeFocus` option has been renamed to `activatePane`")
options.activatePane = options.changeFocus
delete options.changeFocus
{initialLine, initialColumn} = options
# TODO: Remove deprecated changeFocus option
activatePane = options.activatePane ? options.changeFocus ? true
activatePane = options.activatePane ? true
uri = atom.project.resolve(uri)
item = @activePane.itemForUri(uri)
@@ -395,7 +395,13 @@ class Workspace extends Model
item
openUriInPane: (uri, pane, options={}) ->
changeFocus = options.changeFocus ? true
# TODO: Remove deprecated changeFocus option
if options.changeFocus?
deprecate("The `changeFocus` option has been renamed to `activatePane`")
options.activatePane = options.changeFocus
delete options.changeFocus
activatePane = options.activatePane ? true
if uri?
item = pane.itemForUri(uri)
@@ -409,7 +415,7 @@ class Workspace extends Model
@paneContainer.root = pane
@itemOpened(item)
pane.activateItem(item)
pane.activate() if changeFocus
pane.activate() if activatePane
index = pane.getActiveItemIndex()
@emit "uri-opened"
@emitter.emit 'did-open', {uri, pane, item, index}
@@ -609,12 +615,16 @@ class Workspace extends Model
Section: Panels
###
# Essential: Get an {Array} of all the panel items at the bottom of the editor window.
getBottomPanels: ->
@getPanels('bottom')
# Essential: Adds a panel item to the bottom of the editor window.
#
# * `options` {Object}
# * `item` Your panel content. It can be DOM element, a jQuery element, or
# a model with a view registered via {ViewRegistry::addViewProvider}. We recommend the
# latter. See {ViewRegistry::addViewProvider} for more information.
# a model with a view registered via {ViewFactory::addViewProvider}. We recommend the
# latter. See {ViewFactory::addViewProvider} for more information.
# * `visible` (optional) {Boolean} false if you want the panel to initially be hidden
# (default: true)
# * `priority` (optional) {Number} Determines stacking order. Lower priority items are
@@ -624,12 +634,16 @@ class Workspace extends Model
addBottomPanel: (options) ->
@addPanel('bottom', options)
# Essential: Get an {Array} of all the panel items to the left of the editor window.
getLeftPanels: ->
@getPanels('left')
# Essential: Adds a panel item to the left of the editor window.
#
# * `options` {Object}
# * `item` Your panel content. It can be DOM element, a jQuery element, or
# a model with a view registered via {ViewRegistry::addViewProvider}. We recommend the
# latter. See {ViewRegistry::addViewProvider} for more information.
# a model with a view registered via {ViewFactory::addViewProvider}. We recommend the
# latter. See {ViewFactory::addViewProvider} for more information.
# * `visible` (optional) {Boolean} false if you want the panel to initially be hidden
# (default: true)
# * `priority` (optional) {Number} Determines stacking order. Lower priority items are
@@ -639,12 +653,16 @@ class Workspace extends Model
addLeftPanel: (options) ->
@addPanel('left', options)
# Essential: Get an {Array} of all the panel items to the right of the editor window.
getRightPanels: ->
@getPanels('right')
# Essential: Adds a panel item to the right of the editor window.
#
# * `options` {Object}
# * `item` Your panel content. It can be DOM element, a jQuery element, or
# a model with a view registered via {ViewRegistry::addViewProvider}. We recommend the
# latter. See {ViewRegistry::addViewProvider} for more information.
# a model with a view registered via {ViewFactory::addViewProvider}. We recommend the
# latter. See {ViewFactory::addViewProvider} for more information.
# * `visible` (optional) {Boolean} false if you want the panel to initially be hidden
# (default: true)
# * `priority` (optional) {Number} Determines stacking order. Lower priority items are
@@ -654,12 +672,16 @@ class Workspace extends Model
addRightPanel: (options) ->
@addPanel('right', options)
# Essential: Get an {Array} of all the panel items at the top of the editor window.
getTopPanels: ->
@getPanels('top')
# Essential: Adds a panel item to the top of the editor window above the tabs.
#
# * `options` {Object}
# * `item` Your panel content. It can be DOM element, a jQuery element, or
# a model with a view registered via {ViewRegistry::addViewProvider}. We recommend the
# latter. See {ViewRegistry::addViewProvider} for more information.
# a model with a view registered via {ViewFactory::addViewProvider}. We recommend the
# latter. See {ViewFactory::addViewProvider} for more information.
# * `visible` (optional) {Boolean} false if you want the panel to initially be hidden
# (default: true)
# * `priority` (optional) {Number} Determines stacking order. Lower priority items are
@@ -669,12 +691,16 @@ class Workspace extends Model
addTopPanel: (options) ->
@addPanel('top', options)
# Essential: Get an {Array} of all the modal panel items
getModalPanels: ->
@getPanels('modal')
# Essential: Adds a panel item as a modal dialog.
#
# * `options` {Object}
# * `item` Your panel content. It can be DOM element, a jQuery element, or
# a model with a view registered via {ViewRegistry::addViewProvider}. We recommend the
# latter. See {ViewRegistry::addViewProvider} for more information.
# a model with a view registered via {ViewFactory::addViewProvider}. We recommend the
# latter. See {ViewFactory::addViewProvider} for more information.
# * `visible` (optional) {Boolean} false if you want the panel to initially be hidden
# (default: true)
# * `priority` (optional) {Number} Determines stacking order. Lower priority items are
@@ -684,7 +710,9 @@ class Workspace extends Model
addModalPanel: (options={}) ->
@addPanel('modal', options)
getPanels: (location) ->
@panelContainers[location].getPanels()
addPanel: (location, options) ->
options ?= {}
options.viewRegistry = atom.views
@panelContainers[location].addPanel(new Panel(options))
+4
Ver Arquivo
@@ -140,6 +140,10 @@ body {
color: darken(#f0ad4e, 20%);
line-height: 1.4;
a {
color: darken(#f0ad4e, 15%);
}
code {
color: darken(#f0ad4e, 20%);
background: lighten(#f0ad4e, 35%);