Comparar commits

..

2 Commits

Autor SHA1 Mensagem Data
Nathan Sobo c8b92526ec Group editor.increase/decreaseIndentPattern settings under editor.indent
Since these settings are paired, we don’t want to retrieve settings
from two different scopes for a given usage. This also emits a
deprecation warning when the old settings are used.
2014-12-11 10:49:20 -07:00
Nathan Sobo 92a9c7aef6 Move editor.commentStart/End properties to editor.comment.start/end
And emit a deprecation warning
2014-12-11 10:36:47 -07:00
164 arquivos alterados com 2903 adições e 5423 exclusões
+1 -7
Ver Arquivo
@@ -74,7 +74,7 @@ For more information on how to work with Atom's official packages, see
* Limit the first line to 72 characters or less
* Reference issues and pull requests liberally
* Consider starting the commit message with an applicable emoji:
* :art: `:art:` when improving the format/structure of the code
* :lipstick: `:lipstick:` when improving the format/structure of the code
* :racehorse: `:racehorse:` when improving performance
* :non-potable_water: `:non-potable_water:` when plugging memory leaks
* :memo: `:memo:` when writing docs
@@ -87,8 +87,6 @@ For more information on how to work with Atom's official packages, see
* :white_check_mark: `:white_check_mark:` when adding tests
* :lock: `:lock:` when dealing with security
* :arrow_up: `:arrow_up:` when upgrading dependencies
* :arrow_down: `:arrow_down:` when downgrading dependencies
* :shirt: `:shirt:` when removing linter warnings
## CoffeeScript Styleguide
@@ -100,10 +98,6 @@ For more information on how to work with Atom's official packages, see
* Avoid spaces inside the curly-braces of hash literals:
* `{a: 1, b: 2}` instead of `{ a: 1, b: 2 }`
* Include a single line of whitespace between methods.
* Capitalize initialisms and acronyms in names, except for the first word, which
should be lower-case:
* `getURI` instead of `getUri`
* `uriToOpen` instead of `URIToOpen`
## Documentation Styleguide
+1 -1
Ver Arquivo
@@ -6,6 +6,6 @@
"url": "https://github.com/atom/atom.git"
},
"dependencies": {
"atom-package-manager": "0.123.0"
"atom-package-manager": "0.113.0"
}
}
-2
Ver Arquivo
@@ -198,7 +198,6 @@ module.exports = (grunt) ->
outputDir: 'atom-shell'
downloadDir: atomShellDownloadDir
rebuild: true # rebuild native modules after atom-shell is updated
token: process.env.ATOM_ACCESS_TOKEN
'create-windows-installer':
appDirectory: shellAppDir
@@ -206,7 +205,6 @@ module.exports = (grunt) ->
authors: 'GitHub Inc.'
loadingGif: path.resolve(__dirname, '..', 'resources', 'win', 'loading.gif')
iconUrl: 'https://raw.githubusercontent.com/atom/atom/master/resources/win/atom.ico'
setupIcon: path.resolve(__dirname, '..', 'resources', 'win', 'atom.ico')
shell:
'kill-atom':
+5 -5
Ver Arquivo
@@ -12,19 +12,19 @@
"fs-plus": "2.x",
"github-releases": "~0.2.0",
"grunt": "~0.4.1",
"grunt-atom-shell-installer": "^0.20.0",
"grunt-atom-shell-installer": "^0.13.0",
"grunt-cli": "~0.1.9",
"grunt-coffeelint": "git+https://github.com/atom/grunt-coffeelint.git#cfb99aa99811d52687969532bd5a98011ed95bfe",
"grunt-contrib-coffee": "~0.12.0",
"grunt-contrib-coffee": "~0.9.0",
"grunt-contrib-csslint": "~0.1.2",
"grunt-contrib-less": "~0.8.0",
"grunt-cson": "0.14.0",
"grunt-download-atom-shell": "~0.11.0",
"grunt-cson": "0.10.0",
"grunt-download-atom-shell": "~0.10.0",
"grunt-lesslint": "0.13.0",
"grunt-peg": "~1.1.0",
"grunt-shell": "~0.3.1",
"harmony-collections": "~0.3.8",
"legal-eagle": "~0.8.0",
"legal-eagle": "~0.6.0",
"minidump": "~0.8",
"npm": "~1.4.5",
"rcedit": "~0.3.0",
+6 -12
Ver Arquivo
@@ -21,9 +21,7 @@ module.exports = (grunt) ->
mkdir appDir
if process.platform isnt 'win32'
cp 'atom.sh', path.join(appDir, 'atom.sh')
cp 'atom.sh', path.join(appDir, 'atom.sh')
cp 'package.json', path.join(appDir, 'package.json')
packageDirectories = []
@@ -71,7 +69,6 @@ module.exports = (grunt) ->
path.join('build', 'Release', 'obj')
path.join('build', 'Release', '.deps')
path.join('vendor', 'apm')
path.join('resources', 'linux')
path.join('resources', 'mac')
path.join('resources', 'win')
@@ -144,10 +141,7 @@ module.exports = (grunt) ->
cp 'spec', path.join(appDir, 'spec')
cp 'src', path.join(appDir, 'src'), filter: /.+\.(cson|coffee)$/
cp 'static', path.join(appDir, 'static')
cp path.join('apm', 'node_modules', 'atom-package-manager'), path.join(appDir, 'apm'), filter: filterNodeModule
if process.platform isnt 'win32'
fs.symlinkSync(path.join('..', '..', 'bin', 'apm'), path.join(appDir, 'apm', 'node_modules', '.bin', 'apm'))
cp 'apm', path.join(appDir, 'apm'), filter: filterNodeModule
if process.platform is 'darwin'
grunt.file.recurse path.join('resources', 'mac'), (sourcePath, rootDirectory, subDirectory='', filename) ->
@@ -155,10 +149,10 @@ module.exports = (grunt) ->
grunt.file.copy(sourcePath, path.resolve(appDir, '..', subDirectory, filename))
if process.platform is 'win32'
cp path.join('resources', 'win', 'atom.cmd'), path.join(shellAppDir, 'resources', 'cli', 'atom.cmd')
cp path.join('resources', 'win', 'atom.sh'), path.join(shellAppDir, 'resources', 'cli', 'atom.sh')
cp path.join('resources', 'win', 'atom.js'), path.join(shellAppDir, 'resources', 'cli', 'atom.js')
cp path.join('resources', 'win', 'apm.sh'), path.join(shellAppDir, 'resources', 'cli', 'apm.sh')
# Set up chocolatey ignore and gui files
fs.writeFileSync path.join(appDir, 'apm', 'node_modules', 'atom-package-manager', 'bin', 'node.exe.ignore'), ''
fs.writeFileSync path.join(appDir, 'node_modules', 'symbols-view', 'vendor', 'ctags-win32.exe.ignore'), ''
fs.writeFileSync path.join(shellAppDir, 'atom.exe.gui'), ''
dependencies = ['compile', 'generate-license:save', 'generate-module-cache', 'compile-packages-slug']
dependencies.push('copy-info-plist') if process.platform is 'darwin'
+1
Ver Arquivo
@@ -1,3 +1,4 @@
fs = require 'fs'
path = require 'path'
_ = require 'underscore-plus'
fs = require 'fs-plus'
-4
Ver Arquivo
@@ -35,10 +35,6 @@ module.exports =
MIT/X11
"""
'cheerio@0.15.0':
repository: "https://github.com/cheeriojs/cheerio"
license: 'MIT'
source: 'https://github.com/cheeriojs/cheerio/blob/master/package.json'
'specificity@0.1.3':
repository: 'https://github.com/keeganstreet/specificity'
license: 'MIT'
+3 -15
Ver Arquivo
@@ -1,5 +1,4 @@
path = require 'path'
fs = require 'fs'
LessCache = require 'less-cache'
@@ -26,10 +25,7 @@ module.exports = (grunt) ->
for theme in configuration
# TODO Use AtomPackage class once it runs outside of an Atom context
themePath = path.resolve('node_modules', theme)
if fs.existsSync(path.join(themePath, 'stylesheets'))
stylesheetsDir = path.join(themePath, 'stylesheets')
else
stylesheetsDir = path.join(themePath, 'styles')
stylesheetsDir = path.join(themePath, 'stylesheets')
{main} = grunt.file.readJSON(path.join(themePath, 'package.json'))
main ?= 'index.less'
mainPath = path.join(themePath, main)
@@ -42,18 +38,10 @@ module.exports = (grunt) ->
resourcePath: path.resolve('.')
importPaths: importPaths
cssForFile = (file) ->
baseVarImports = """
@import "variables/ui-variables";
@import "variables/syntax-variables";
"""
less = fs.readFileSync(file, 'utf8')
lessCache.cssForFile(file, [baseVarImports, less].join('\n'))
for file in @filesSrc
grunt.verbose.writeln("File #{file.cyan} created in cache.")
cssForFile(file)
lessCache.readFileSync(file)
for file in themeMains
grunt.verbose.writeln("File #{file.cyan} created in cache.")
cssForFile(file)
lessCache.readFileSync(file)
+2 -25
Ver Arquivo
@@ -101,7 +101,7 @@ getAssets = ->
logError = (message, error, details) ->
grunt.log.error(message)
grunt.log.error(error.message ? error) if error?
grunt.log.error(require('util').inspect(details)) if details
grunt.log.error(details) if details
zipAssets = (buildDir, assets, callback) ->
zip = (directory, sourcePath, assetName, callback) ->
@@ -142,30 +142,7 @@ getAtomDraftRelease = (callback) ->
firstDraft.assets = assets
callback(null, firstDraft)
else
createAtomDraftRelease(callback)
createAtomDraftRelease = (callback) ->
{version} = require('../../package.json')
options =
uri: 'https://api.github.com/repos/atom/atom/releases'
method: 'POST'
headers: defaultHeaders
json:
tag_name: "v#{version}"
name: version
draft: true
body: """
### Notable Changes
* Something new
"""
request options, (error, response, body='') ->
if error? or response.statusCode isnt 201
logError("Creating atom/atom draft release failed", error, body)
callback(error ? new Error(response.statusCode))
else
callback(null, body)
callback(new Error('No draft release in atom/atom repo'))
deleteRelease = (release) ->
options =
-16
Ver Arquivo
@@ -11,20 +11,6 @@ module.exports = (grunt) ->
packageSpecQueue = null
logDeprecations = (label, {stderr}={}) ->
return unless process.env.JANKY_SHA1
stderr ?= ''
deprecatedStart = stderr.indexOf('Calls to deprecated functions')
return if deprecatedStart is -1
grunt.log.error(label)
stderr = stderr.substring(deprecatedStart)
stderr = stderr.replace(/^\s*\[[^\]]+\]\s+/gm, '')
stderr = stderr.replace(/source: .*$/gm, '')
stderr = stderr.replace(/^"/gm, '')
stderr = stderr.replace(/",\s*$/gm, '')
grunt.log.error(stderr)
getAppPath = ->
contentsDir = grunt.config.get('atom.contentsDir')
switch process.platform
@@ -68,7 +54,6 @@ module.exports = (grunt) ->
fs.unlinkSync(path.join(packagePath, 'ci.log'))
failedPackages.push path.basename(packagePath) if error
logDeprecations("#{path.basename(packagePath)} Specs", results)
callback()
modulesDirectory = path.resolve('node_modules')
@@ -102,7 +87,6 @@ module.exports = (grunt) ->
else
# TODO: Restore concurrency on Windows
packageSpecQueue.concurrency = concurrency
logDeprecations('Core Specs', results)
callback(null, error)
+22
Ver Arquivo
@@ -0,0 +1,22 @@
path = require 'path'
module.exports = (grunt) ->
grunt.registerTask 'update-octicons', 'Update octicon font and LESS variables', ->
pathToOcticons = path.resolve('..', 'octicons')
if grunt.file.isDir(pathToOcticons)
# Copy font-file
fontSrc = path.join(pathToOcticons, 'octicons', 'octicons.woff')
fontDest = path.resolve('static', 'octicons.woff')
grunt.file.copy(fontSrc, fontDest)
# Update Octicon UTF codes
glyphsSrc = path.join(pathToOcticons, 'data', 'glyphs.yml')
output = []
for {css, code} in grunt.file.readYAML(glyphsSrc)
output.push "@#{css}: \"\\#{code}\";"
octiconUtfDest = path.resolve('static', 'variables', 'octicon-utf-codes.less')
grunt.file.write(octiconUtfDest, "#{output.join('\n')}\n")
else
grunt.log.error("octicons repo must be cloned to #{pathToOcticons}")
false
+1 -1
Ver Arquivo
@@ -3,7 +3,7 @@
## Structure of a Keymap File
Keymap files are encoded as JSON or CSON files containing nested hashes. They
work much like style sheets, but instead of applying style properties to elements
work much like stylesheets, but instead of applying style properties to elements
matching the selector, they specify the meaning of keystrokes on elements
matching the selector. Here is an example of some bindings that apply when
keystrokes pass through `atom-text-editor` elements:
+8 -9
Ver Arquivo
@@ -30,8 +30,8 @@ All requests that take parameters require `application/json`.
Parameters:
- **page** (optional)
- **sort** (optional) - One of `downloads`, `created_at`, `updated_at`, `stars`. Defaults to `downloads`
- **direction** (optional) - `asc` or `desc`. Defaults to `desc`. `stars` can only be ordered `desc`
- **sort** (optional, values: `created_at`, `updated_at`, `downloads`)
- **direction** (optional, values: `asc`, `desc`)
Returns a list of all packages in the following format:
```json
@@ -61,18 +61,17 @@ Link: <https://www.atom.io/api/packages?page=1>; rel="self",
By default, results are sorted by download count, descending.
### Searching packages
#### GET /api/packages/search
Parameters:
- **q** (required) - Search query
- **page** (optional)
- **sort** (optional) - One of `downloads`, `created_at`, `updated_at`, `stars`. Defaults to the relevance of the search query.
- **direction** (optional) - `asc` or `desc`. Defaults to `desc`.
- **q** String query to search
- **sort** (optional, values: `created_at`, `updated_at`, `downloads`)
- **direction** (optional, values: `asc`, `desc`)
Returns results in the same format as [listing packages](#listing-packages).
Returns a list of all packages in the same format as `/api/packages`.
By default, results sorted by relevance to search query.
### Showing package details
+1 -5
Ver Arquivo
@@ -26,17 +26,13 @@ Ubuntu LTS 12.04 64-bit is the recommended platform.
### Arch
* `sudo pacman -S gconf base-devel git nodejs libgnome-keyring python2`
* `sudo pacman -S base-devel git nodejs libgnome-keyring python2`
* `export PYTHON=/usr/bin/python2` before building Atom.
### Slackware
* `sbopkg -k -i node -i atom`
### openSUSE
* `sudo zypper install nodejs make gcc gcc-c++ glibc-devel git-core libgnome-keyring-devel rpmdevtools`
## Instructions
If you have problems with permissions don't forget to prefix with `sudo`
+10 -10
Ver Arquivo
@@ -15,7 +15,7 @@ my-package/
menus/
spec/
snippets/
styles/
stylesheets/
index.coffee
package.json
```
@@ -38,10 +38,10 @@ In addition to the regular [npm package.json keys][npm-keys] available, Atom
package.json files have their own additions.
- `main` (**Required**): the path to the CoffeeScript file that's the entry point
to your package.
- `styles` (**Optional**): an Array of Strings identifying the order of the
to your package
- `stylesheets` (**Optional**): an Array of Strings identifying the order of the
style sheets your package needs to load. If not specified, style sheets in the
_styles_ directory are added alphabetically.
_stylesheets_ directory are added alphabetically.
- `keymaps`(**Optional**): an Array of Strings identifying the order of the
key mappings your package needs to load. If not specified, mappings in the
_keymaps_ directory are added alphabetically.
@@ -121,10 +121,10 @@ like you.
## Style Sheets
Style sheets for your package should be placed in the _styles_ directory.
Style sheets for your package should be placed in the _stylesheets_ directory.
Any style sheets in this directory will be loaded and attached to the DOM when
your package is activated. Style sheets can be written as CSS or [LESS], but
LESS is recommended.
your package is activated. Style sheets can be written as CSS or [LESS] (but
LESS is recommended).
Ideally, you won't need much in the way of styling. We've provided a standard
set of components which define both the colors and UI elements for any package
@@ -138,7 +138,7 @@ taken from the active theme's [ui-variables.less][ui-variables]. For more
information, see the [theme variables docs][theme-variables]. If you follow this
guideline, your package will look good out of the box with any theme!
An optional `styleSheets` array in your _package.json_ can list the style sheets
An optional `stylesheets` array in your _package.json_ can list the style sheets
by name to specify a loading order; otherwise, style sheets are loaded
alphabetically.
@@ -418,8 +418,8 @@ all the other available commands.
[underscore]: http://underscorejs.org/
[jasmine]: http://jasmine.github.io
[cson]: https://github.com/atom/season
[LESS]: http://lesscss.org
[ui-variables]: https://github.com/atom/atom-dark-ui/blob/master/styles/ui-variables.less
[less]: http://lesscss.org
[ui-variables]: https://github.com/atom/atom-dark-ui/blob/master/stylesheets/ui-variables.less
[first-package]: your-first-package.html
[convert-bundle]: converting-a-text-mate-bundle.html
[convert-theme]: converting-a-text-mate-theme.html
+6 -8
Ver Arquivo
@@ -1,8 +1,8 @@
# Creating a Theme
Atom's interface is rendered using HTML, and it's styled via [LESS] which is a
superset of CSS. Don't worry if you haven't heard of LESS before; it's just like
CSS, but with a few handy extensions.
Atom's interface is rendered using HTML, and it's styled via [LESS] (a superset
of CSS). Don't worry if you haven't heard of LESS before; it's just like CSS,
but with a few handy extensions.
Atom supports two types of themes: _UI_ and _syntax_. UI themes style
elements such as the tree view, the tabs, drop-down lists, and the status bar.
@@ -42,10 +42,10 @@ _Motif_ theme listed in the _Syntax Theme_ drop-down. Select it from the menu to
activate it, now when you open an editor you should see that your new
_motif-syntax_ theme in action.
Open up _styles/colors.less_ to change the various colors variables which
Open up _stylesheets/colors.less_ to change the various colors variables which
have been already been defined. For example, turn `@red` into `#f4c2c1`.
Then open _styles/base.less_ and modify the various selectors that have
Then open _stylesheets/base.less_ and modify the various selectors that have
been already been defined. These selectors style different parts of code in the
editor such as comments, strings and the line numbers in the gutter.
@@ -59,8 +59,6 @@ window in dev mode. To open a Dev Mode Atom window run `atom --dev .` in the
terminal, use `cmd-shift-o` or use the _View > Developer > Open in Dev Mode_
menu. When you edit your theme, changes will instantly be reflected!
> Note: It's advised to _not_ specify a `font-family` in your syntax theme because it will override the Font Family field in Atom's settings. If you still like to recommend a font that goes well with your theme, we recommend you do so in your README.
## Creating an Interface Theme
Interface themes **must** provide a `ui-variables.less` file which contains all
@@ -131,7 +129,7 @@ _styleguide_, or use the shortcut `cmd-ctrl-shift-g`.
![styleguide-img]
[atomio]: http://atom.io/packages
[LESS]: http://lesscss.org/
[less]: http://lesscss.org/
[git]: http://git-scm.com/
[atom]: https://atom.io/
[package.json]: ./creating-a-package.html#package-json
+1 -2
Ver Arquivo
@@ -54,7 +54,7 @@ You can also use `apm` to find new packages to install:
## Customizing Key Bindings
Atom keymaps work similarly to style sheets. Just as style sheets use selectors
Atom keymaps work similarly to stylesheets. Just as stylesheets use selectors
to apply styles to elements, Atom keymaps use selectors to associate keystrokes
with events in specific contexts. Here's a small example, excerpted from Atom's
built-in keymaps:
@@ -105,7 +105,6 @@ You can open this file in an editor from the _Atom > Open Your Config_ menu.
- `core`
- `disabledPackages`: An array of package names to disable
- `excludeVcsIgnoredPaths`: Don't search within files specified by _.gitignore_
- `followSymlinks`: Follow symlinks when searching and scanning root directory
- `ignoredNames`: File names to ignore across all of Atom
- `projectHome`: The directory where projects are assumed to be located
- `themes`: An array of theme names to load, in cascading order
+1 -12
Ver Arquivo
@@ -3,8 +3,7 @@
Atom provides several tools to help you understand unexpected behavior and debug problems. This guide describes some of those tools and a few approaches to help you debug and provide more helpful information when [submitting issues]:
* [Update to the latest version](#update-to-the-latest-version)
* [Check for linked packages](#check-for-linked-packages)
* [Check Atom and package settings](#check-atom-and-package-settings)
* [Check Atom and package settings](#check-atom-and-package-settings)
* [Check the keybindings](#check-the-keybindings)
* [Check if the problem shows up in safe mode](#check-if-the-problem-shows-up-in-safe-mode)
* [Check your config files](#check-your-config-files)
@@ -25,16 +24,6 @@ $ atom --version
Head on over to the [list of releases][atom releases] and see if there's a more recent release. You can update to the most recent release by downloading Atom from the releases page, or with the in-app auto-updater. The in-app auto-updater checks for and downloads a new version after you restart Atom, or if you use the Atom > Check for Update menu option.
## Check for linked packages
If you develop or contribute to Atom packages, there may be left-over packages linked to your `~/.atom/packages` or `~/.atom/dev/packages` directories. You can use:
```shell
$ apm links
```
to list all linked development packages. You can remove the links using the `apm unlink` command. See `apm unlink --help` for details.
## Check Atom and package settings
In some cases, unexpected behavior might be caused by misconfigured or unconfigured settings in Atom or in one of the packages.
+1 -1
Ver Arquivo
@@ -34,7 +34,7 @@ files. If you are using Git you can use `cmd-shift-b` to search the list of
files modified and untracked in your project's repository.
You can also use the tree view to navigate to a file. To open and focus the
tree view, press `ctrl-0`. The tree view can be toggled open and closed with
the tree view, press `ctrl-0`. The tree view can be toggled open and closed with
`cmd-\`.
#### Adding, Moving, Deleting Files
-625
Ver Arquivo
@@ -1,625 +0,0 @@
# Upgrading your package to 1.0 APIs
Atom is rapidly approaching 1.0. Much of the effort leading up to the 1.0 has been cleaning up APIs in an attempt to future proof, and make a more pleasant experience developing packages.
This document will guide you through the large bits of upgrading your package to work with 1.0 APIs.
## TL;DR
We've set deprecation messages and errors in strategic places to help make sure you don't miss anything. You should be able to get 95% of the way to an updated package just by fixing errors and deprecations. There are a couple of things you can do to get the full effect of all the errors and deprecations.
### Use atom-space-pen-views
If you use any class from `require 'atom'` with a `$` or `View` in the name, add the `atom-space-pen-views` module to your package's `package.json` file's dependencies:
```js
{
"dependencies": {
"atom-space-pen-views": "^2.0.3"
}
}
```
Then run `apm install` in your package directory.
### Require views from atom-space-pen-views
Anywhere you are requiring one of the following from `atom` you need to require them from `atom-space-pen-views` instead.
```coffee
# require these from 'atom-space-pen-views' rather than 'atom'
$
$$
$$$
View
TextEditorView
ScrollView
SelectListView
```
So this:
```coffee
# Old way
{$, TextEditorView, View, GitRepository} = require 'atom'
```
Would be replaced by this:
```coffee
# New way
{GitRepository} = require 'atom'
{$, TextEditorView, View} = require 'atom-space-pen-views'
```
### Run specs and test your package
You wrote specs, right!? Here's where they shine. Run them with `cmd-shift-P`, and search for `run package specs`. It will show all the deprecation messages and errors.
### Update the engines field in package.json
When you are deprecation free and all done converting, upgrade the `engines` field in your package.json:
```json
{
"engines": {
"atom": ">=0.174.0, <2.0.0"
}
}
```
### Examples
We have upgraded all the core packages. Please see [this issue](https://github.com/atom/atom/issues/4011) for a link to all the upgrade PRs.
## Deprecations
All of the methods in Atom core that have changes will emit deprecation messages when called. These messages are shown in two places: your **package specs**, and in **Deprecation Cop**.
### Specs
Just run your specs, and all the deprecations will be displayed in yellow.
![spec-deps](https://cloud.githubusercontent.com/assets/69169/5637943/b85114ba-95b5-11e4-8681-b81ea8f556d7.png)
### Deprecation Cop
Run an atom window in dev mode (`atom -d`) with your package loaded, and open Deprecation Cop (search for `deprecation` in the command palette). Deprecated methods will be appear in Deprecation Cop only after they have been called.
![dep-cop](https://cloud.githubusercontent.com/assets/69169/5637914/6e702fa2-95b5-11e4-92cc-a236ddacee21.png)
When deprecation cop is open, and deprecated methods are called, a `Refresh` button will appear in the top right of the Deprecation Cop interface. So exercise your package, then come back to Deprecation Cop and click the `Refresh` button.
## Upgrading your Views
Previous to 1.0, views were baked into Atom core. These views were based on jQuery and `space-pen`. They looked something like this:
```coffee
# The old way: getting views from atom
{$, TextEditorView, View} = require 'atom'
module.exports =
class SomeView extends View
@content: ->
@div class: 'find-and-replace', =>
@div class: 'block', =>
@subview 'myEditor', new TextEditorView(mini: true)
#...
```
### The New
`require 'atom'` no longer provides view helpers or jQuery. Atom core is now 'view agnostic'. The preexisting view system is available from a new npm package: `atom-space-pen-views`.
`atom-space-pen-views` now provides jQuery, `space-pen` views, and Atom specific views:
```coffee
# These are now provided by atom-space-pen-views
$
$$
$$$
View
TextEditorView
ScrollView
SelectListView
```
### Adding the module dependencies
To use the new views, you need to specify the `atom-space-pen-views` module in your package's `package.json` file's dependencies:
```js
{
"dependencies": {
"atom-space-pen-views": "^2.0.3"
}
}
```
`space-pen` bundles jQuery. If you do not need `space-pen` or any of the views, you can require jQuery directly.
```js
{
"dependencies": {
"jquery": "^2"
}
}
```
### Converting your views
Sometimes it is as simple as converting the requires at the top of each view page. I assume you read the 'TL;DR' section and have updated all of your requires.
### Upgrading classes extending any space-pen View
#### `afterAttach` and `beforeRemove` updated
The `afterAttach` and `beforeRemove` hooks have been replaced with
`attached` and `detached` and the semantics have changed.
`afterAttach` was called whenever the node was attached to another DOM node, even if that parent node wasn't present in the DOM. `afterAttach` also was called with a boolean indicating whether or not the element and its parents were on the DOM. Now the `attached` hook is _only_ called when the node and all of its parents are actually on the DOM, and is not called with a boolean.
`beforeRemove` was only called when `$.fn.remove` was called, which was typically used when the node was completely removed from the DOM. The new `detached` hook is called whenever the DOM node is _detached_, which could happen if the node is being detached for reattachment later. In short, if `beforeRemove` is called the node is never coming back. With `detached` it might be attached again later.
```coffee
# Old way
{View} = require 'atom'
class MyView extends View
afterAttach: (onDom) ->
#...
beforeRemove: ->
#...
```
```coffee
# New way
{View} = require 'atom-space-pen-views'
class MyView extends View
attached: ->
# Always called with the equivalent of @afterAttach(true)!
#...
detached: ->
#...
```
#### `subscribe` and `subscribeToCommand` methods removed
The `subscribe` and `subscribeToCommand` methods have been removed. See the Eventing and Disposables section for more info.
### Upgrading to the new TextEditorView
All of the atom-specific methods available on the `TextEditorView` have been moved to the `TextEditor`, available via `TextEditorView::getModel`. See the [`TextEditorView` docs][TextEditorView] and [`TextEditor` docs][TextEditor] for more info.
### Upgrading classes extending ScrollView
The `ScrollView` has very minor changes.
You can no longer use `@off` to remove default behavior for `core:move-up`, `core:move-down`, etc.
```coffee
# Old way to turn off default behavior
class ResultsView extends ScrollView
initialize: (@model) ->
super()
# turn off default scrolling behavior from ScrollView
@off 'core:move-up'
@off 'core:move-down'
@off 'core:move-left'
@off 'core:move-right'
```
```coffee
# New way to turn off default behavior
class ResultsView extends ScrollView
initialize: (@model) ->
disposable = super()
# turn off default scrolling behavior from ScrollView
disposable.dispose()
```
* Check out [an example](https://github.com/atom/find-and-replace/pull/311/files#diff-9) from find-and-replace.
* See the [docs][ScrollView] for all the options.
### Upgrading classes extending SelectListView
Your SelectListView might look something like this:
```coffee
# Old!
class CommandPaletteView extends SelectListView
initialize: ->
super()
@addClass('command-palette overlay from-top')
atom.workspaceView.command 'command-palette:toggle', => @toggle()
confirmed: ({name, jQuery}) ->
@cancel()
# do something with the result
toggle: ->
if @hasParent()
@cancel()
else
@attach()
attach: ->
@storeFocusedElement()
items = [] # TODO: build items
@setItems(items)
atom.workspaceView.append(this)
@focusFilterEditor()
confirmed: ({name, jQuery}) ->
@cancel()
```
This attaches and detaches itself from the dom when toggled, canceling magically detaches it from the DOM, and it uses the classes `overlay` and `from-top`.
The new SelectListView no longer automatically detaches itself from the DOM when cancelled. It's up to you to implement whatever cancel beahavior you want. Using the new APIs to mimic the sematics of the old class, it should look like this:
```coffee
# New!
class CommandPaletteView extends SelectListView
initialize: ->
super()
# no more need for the `overlay` and `from-top` classes
@addClass('command-palette')
atom.commands.add 'atom-workspace', 'command-palette:toggle', => @toggle()
# You need to implement the `cancelled` method and hide.
cancelled: ->
@hide()
confirmed: ({name, jQuery}) ->
@cancel()
# do something with the result
toggle: ->
# Toggling now checks panel visibility,
# and hides / shows rather than attaching to / detaching from the DOM.
if @panel?.isVisible()
@cancel()
else
@show()
show: ->
# Now you will add your select list as a modal panel to the workspace
@panel ?= atom.workspace.addModalPanel(item: this)
@panel.show()
@storeFocusedElement()
items = [] # TODO: build items
@setItems(items)
@focusFilterEditor()
hide: ->
@panel?.hide()
```
* And check out the [conversion of CommandPaletteView][selectlistview-example] as a real-world example.
* See the [SelectListView docs][SelectListView] for all options.
## Using the model layer rather than the view layer
The API no longer exposes any specialized view objects or view classes. `atom.workspaceView`, and all the view classes: `WorkspaceView`, `EditorView`, `PaneView`, etc. have been globally deprecated.
Nearly all of the atom-specific actions performed by the old view objects can now be managed via the model layer. For example, here's adding a panel to the interface using the `atom.workspace` model instead of the `workspaceView`:
```coffee
# Old!
div = document.createElement('div')
atom.workspaceView.appendToTop(div)
```
```coffee
# New!
div = document.createElement('div')
atom.workspace.addTopPanel(item: div)
```
For actions that still require the view, such as dispatching commands or munging css classes, you'll access the view via the `atom.views.getView()` method. This will return a subclass of `HTMLElement` rather than a jQuery object or an instance of a deprecated view class (e.g. `WorkspaceView`).
```coffee
# Old!
workspaceView = atom.workspaceView
editorView = workspaceView.getActiveEditorView()
paneView = editorView.getPaneView()
```
```coffee
# New!
# Generally, just use the models
workspace = atom.workspace
editor = workspace.getActiveTextEditor()
pane = editor.getPane()
# If you need views, get them with `getView`
workspaceElement = atom.views.getView(atom.workspace)
editorElement = atom.views.getView(editor)
paneElement = atom.views.getView(pane)
```
## Updating Specs
`atom.workspaceView`, the `WorkspaceView` class and the `EditorView` class have been deprecated. These two objects are used heavily throughout specs, mostly to dispatch events and commands. This section will explain how to remove them while still retaining the ability to dispatch events and commands.
### Removing WorkspaceView references
`WorkspaceView` has been deprecated. Everything you could do on the view, you can now do on the `Workspace` model.
Requiring `WorkspaceView` from `atom` and accessing any methods on it will throw a deprecation warning. Many specs lean heavily on `WorkspaceView` to trigger commands and fetch `EditorView` objects.
Your specs might contain something like this:
```coffee
# Old!
{WorkspaceView} = require 'atom'
describe 'FindView', ->
beforeEach ->
atom.workspaceView = new WorkspaceView()
```
Instead, we will use the `atom.views.getView()` method. This will return a plain `HTMLElement`, not a `WorkspaceView` or jQuery object.
```coffee
# New!
describe 'FindView', ->
workspaceElement = null
beforeEach ->
workspaceElement = atom.views.getView(atom.workspace)
```
### Attaching the workspace to the DOM
The workspace needs to be attached to the DOM in some cases. For example, view hooks only work (`attached()` on `View`, `attachedCallback()` on custom elements) when there is a descendant attached to the DOM.
You might see this in your specs:
```coffee
# Old!
atom.workspaceView.attachToDom()
```
Change it to:
```coffee
# New!
jasmine.attachToDOM(workspaceElement)
```
### Removing EditorView references
Like `WorkspaceView`, `EditorView` has been deprecated. Everything you needed to do on the view you are now able to do on the `TextEditor` model.
In many cases, you will not even need to get the editor's view anymore. Any of those instances should be updated to use the `TextEditor` instance instead. You should really only need the editor's view when you plan on triggering a command on the view in a spec.
Your specs might contain something like this:
```coffee
# Old!
describe 'Something', ->
[editorView] = []
beforeEach ->
editorView = atom.workspaceView.getActiveView()
```
We're going to use `atom.views.getView()` again to get the editor element. As in the case of the `workspaceElement`, `getView` will return a subclass of `HTMLElement` rather than an `EditorView` or jQuery object.
```coffee
# New!
describe 'Something', ->
[editor, editorElement] = []
beforeEach ->
editor = atom.workspace.getActiveTextEditor()
editorElement = atom.views.getView(editor)
```
### Dispatching commands
Since the `editorElement` objects are no longer `jQuery` objects, they no longer support `trigger()`. Additionally, Atom has a new command dispatcher, `atom.commands`, that we use rather than commandeering jQuery's `trigger` method.
From this:
```coffee
# Old!
workspaceView.trigger 'a-package:toggle'
editorView.trigger 'find-and-replace:show'
```
To this:
```coffee
# New!
atom.commands.dispatch workspaceElement, 'a-package:toggle'
atom.commands.dispatch editorElement, 'find-and-replace:show'
```
## Eventing and Disposables
A couple large things changed with respect to events:
1. All model events are now exposed as event subscription methods that return [`Disposable`][disposable] objects
1. The `subscribe()` method is no longer available on `space-pen` `View` objects
1. An Emitter is now provided from `require 'atom'`
### Consuming Events
All events from the Atom API are now methods that return a [`Disposable`][disposable] object, on which you can call `dispose()` to unsubscribe.
```coffee
# Old!
editor.on 'changed', ->
```
```coffee
# New!
disposable = editor.onDidChange ->
# You can unsubscribe at some point in the future via `dispose()`
disposable.dispose()
```
Deprecation warnings will guide you toward the correct methods.
#### Using a CompositeDisposable
You can group multiple disposables into a single disposable with a `CompositeDisposable`.
```coffee
{CompositeDisposable} = require 'atom'
class Something
constructor: ->
editor = atom.workspace.getActiveTextEditor()
@disposables = new CompositeDisposable
@disposables.add editor.onDidChange ->
@disposables.add editor.onDidChangePath ->
destroy: ->
@disposables.dispose()
```
### Removing View::subscribe and Subscriber::subscribe calls
There were a couple permutations of `subscribe()`. In these examples, a `CompositeDisposable` is used as it will commonly be useful where conversion is necessary.
#### subscribe(unsubscribable)
This one is very straight forward.
```coffee
# Old!
@subscribe editor.on 'changed', ->
```
```coffee
# New!
disposables = new CompositeDisposable
disposables.add editor.onDidChange ->
```
#### subscribe(modelObject, event, method)
When the modelObject is an Atom model object, the change is very simple. Just use the correct event method, and add it to your CompositeDisposable.
```coffee
# Old!
@subscribe editor, 'changed', ->
```
```coffee
# New!
disposables = new CompositeDisposable
disposables.add editor.onDidChange ->
```
#### subscribe(jQueryObject, selector(optional), event, method)
Things are a little more complicated when subscribing to a DOM or jQuery element. Atom no longer provides helpers for subscribing to elements. You can use jQuery or the native DOM APIs, whichever you prefer.
```coffee
# Old!
@subscribe $(window), 'focus', ->
```
```coffee
# New!
{Disposable, CompositeDisposable} = require 'atom'
disposables = new CompositeDisposable
# New with jQuery
focusCallback = ->
$(window).on 'focus', focusCallback
disposables.add new Disposable ->
$(window).off 'focus', focusCallback
# New with native APIs
focusCallback = ->
window.addEventListener 'focus', focusCallback
disposables.add new Disposable ->
window.removeEventListener 'focus', focusCallback
```
### Providing Events: Using the Emitter
You no longer need to require `emissary` to get an emitter. We now provide an `Emitter` class from `require 'atom'`. We have a specific pattern for use of the `Emitter`. Rather than mixing it in, we instantiate a member variable, and create explicit subscription methods. For more information see the [`Emitter` docs][emitter].
```coffee
# New!
{Emitter} = require 'atom'
class Something
constructor: ->
@emitter = new Emitter
destroy: ->
@emitter.dispose()
onDidChange: (callback) ->
@emitter.on 'did-change', callback
methodThatFiresAChange: ->
@emitter.emit 'did-change', {data: 2}
# Using the evented class
something = new Something
something.onDidChange (eventObject) ->
console.log eventObject.data # => 2
something.methodThatFiresAChange()
```
## Subscribing To Commands
`$.fn.command` and `View::subscribeToCommand` are no longer available. Now we use `atom.commands.add`, and collect the results in a `CompositeDisposable`. See [the docs][commands-add] for more info.
```coffee
# Old!
atom.workspaceView.command 'core:close core:cancel', ->
# When inside a View class, you might see this
@subscribeToCommand 'core:close core:cancel', ->
```
```coffee
# New!
@disposables.add atom.commands.add 'atom-workspace',
'core:close': ->
'core:cancel': ->
# You can register commands directly on individual DOM elements in addition to
# using selectors. When in a View class, you should have a `@element` object
# available. `@element` is a plain HTMLElement object
@disposables.add atom.commands.add @element,
'core:close': ->
'core:cancel': ->
```
## Upgrading your stylesheet's selectors
Many selectors have changed, and we have introduced the [Shadow DOM][shadowdom] to the editor. See [Upgrading Your Package Selectors guide][upgrading-selectors] for more information in upgrading your package stylesheets.
## Help us improve this guide!
Did you hit something painful that wasn't in here? Want to reword some bit of it? Find something incorrect? Please edit [this file][guide], and send a pull request. Contributions are greatly appreciated.
[texteditorview]:https://github.com/atom/atom-space-pen-views#texteditorview
[scrollview]:https://github.com/atom/atom-space-pen-views#scrollview
[selectlistview]:https://github.com/atom/atom-space-pen-views#selectlistview
[selectlistview-example]:https://github.com/atom/command-palette/pull/19/files
[emitter]:https://atom.io/docs/api/latest/Emitter
[texteditor]:https://atom.io/docs/api/latest/TextEditor
[disposable]:https://atom.io/docs/api/latest/Disposable
[commands-add]:https://atom.io/docs/api/latest/CommandRegistry#instance-add
[upgrading-selectors]:upgrading-your-ui-theme
[shadowdom]:http://blog.atom.io/2014/11/18/avoiding-style-pollution-with-the-shadow-dom.html
[guide]:https://github.com/atom/atom/blob/master/docs/upgrading/upgrading-your-package.md
+5 -2
Ver Arquivo
@@ -6,16 +6,19 @@ Syntax themes are specifically intended to style only text editor content, so th
When theme style sheets are loaded into the text editor's shadow DOM, selectors intended to target the editor from the *outside* no longer make sense. Styles targeting the `.editor` and `.editor-colors` classes instead need to target the `:host` pseudo-element, which matches against the containing `atom-text-editor` node. Check out the [Shadow DOM 201][host-pseudo-element] article for more information about the `:host` pseudo-element.
Here's an example from Atom's light syntax theme. Note that the `atom-text-editor` selector intended to target the editor from the outside has been retained to allow the theme to keep working during the transition phase when it is possible to disable the shadow DOM.
Here's an example from Atom's light syntax theme. Note that the previous selectors intended to target the editor from the outside have been retained to allow the theme to keep working during the transition phase when it is possible to disable the shadow DOM.
```css
atom-text-editor, :host { /* :host added */
.editor-colors, :host { /* :host added */
background-color: @syntax-background-color;
color: @syntax-text-color;
}
.editor, :host { /* :host added */
.invisible-character {
color: @syntax-invisible-character-color;
}
/* more nested selectors... */
}
```
+4 -4
Ver Arquivo
@@ -1,6 +1,6 @@
# Upgrading Your UI Theme Or Package Selectors
In addition to changes in Atom's scripting API, we'll also be making some breaking changes to Atom's DOM structure, requiring style sheets and keymaps in both packages and themes to be updated.
In addition to changes in Atom's scripting API, we'll also be making some breaking changes to Atom's DOM structure, requiring stylesheets and keymaps in both packages and themes to be updated.
## Deprecation Cop
@@ -121,12 +121,12 @@ The selector features discussed above allow you to target shadow DOM content wit
```
my-ui-theme/
styles/
stylesheets/
index.less # loaded globally
index.atom-text-editor.less # loaded in the text editor shadow DOM
```
Check out this [style sheet](https://github.com/atom/decoration-example/blob/master/styles/decoration-example.atom-text-editor.less) from the decoration-example package for an example of context-targeting.
Check out this [style sheet](https://github.com/atom/decoration-example/blob/master/stylesheets/decoration-example.atom-text-editor.less) from the decoration-example package for an example of context-targeting.
Inside a context-targeted style sheet, there's no need to use the `::shadow` or `/deep/` expressions. If you want to refer to the element containing the shadow root, you can use the `::host` pseudo-element.
@@ -134,4 +134,4 @@ During the transition phase, style sheets targeting the `atom-text-editor` conte
[shadow-dom-101]: http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom
[shadow-dom-201]: http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom-201#toc-style-cat-hat
[find-and-replace]: https://github.com/atom/find-and-replace/blob/95351f261bc384960a69b66bf12eae8002da63f9/styles/find-and-replace.less#L10
[find-and-replace]: https://github.com/atom/find-and-replace/blob/95351f261bc384960a69b66bf12eae8002da63f9/stylesheets/find-and-replace.less#L10
-7
Ver Arquivo
@@ -127,10 +127,3 @@ describe "when a test is written", ->
expect("apples").toEqual("apples")
expect("oranges").not.toEqual("apples")
```
### Running on CI
It is now easy to run the specs in a CI environment like Travis and AppVeyor. See the
[Travis CI For Your Packages](http://blog.atom.io/2014/04/25/ci-for-your-packages.html)
and [AppVeyor CI For Your Packages](http://blog.atom.io/2014/07/28/windows-ci-for-your-packages.html)
posts for more details.
+4 -4
Ver Arquivo
@@ -88,17 +88,17 @@ run the `ascii-art:convert` command it will output 'Hello, World!'
Now let's add a key binding to trigger the `ascii-art:convert` command. Open
_keymaps/ascii-art.cson_ and add a key binding linking `ctrl-alt-a` to the
`ascii-art:convert` command. You can delete the pre-existing key binding since
you don't need it anymore. When finished, the file will have this:
you don't need it anymore. When finished, the file will look like this:
```coffeescript
'atom-text-editor':
'ctrl-alt-a': 'ascii-art:convert'
'cmd-alt-a': 'ascii-art:convert'
```
Notice `atom-text-editor` on the first line. Just like CSS, keymap selectors
*scope* key bindings so they only apply to specific elements. In this case, our
binding is only active for elements matching the `atom-text-editor` selector. If
the Tree View has focus, pressing `ctrl-alt-a` won't trigger the
the Tree View has focus, pressing `cmd-alt-a` won't trigger the
`ascii-art:convert` command. But if the editor has focus, the
`ascii-art:convert` method *will* be triggered. More information on key bindings
can be found in the [keymaps](advanced/keymaps.html) documentation.
@@ -142,7 +142,7 @@ convert: ->
selection.insertText("\n#{asciiArt}\n")
```
Select some text in an editor window and hit `ctrl-alt-a`. :tada: You're now an
Select some text in an editor window and hit `cmd-alt-a`. :tada: You're now an
ASCII art professional!
## Further reading
+2 -2
Ver Arquivo
@@ -1,7 +1,7 @@
# Your keymap
#
# Atom keymaps work similarly to style sheets. Just as style sheets use
# selectors to apply styles to elements, Atom keymaps use selectors to associate
# Atom keymaps work similarly to stylesheets. Just as stylesheets use selectors
# to apply styles to elements, Atom keymaps use selectors to associate
# keystrokes with events in specific contexts.
#
# You can create a new keybinding in this file by typing "key" and then hitting
+1 -5
Ver Arquivo
@@ -12,14 +12,10 @@
}
// style the background and foreground colors on the atom-text-editor-element
// itself
atom-text-editor {
}
// To style other content in the text editor's shadow DOM, use the ::shadow
// expression
atom-text-editor::shadow .cursor {
atom-text-editor .cursor {
}
+16 -16
Ver Arquivo
@@ -40,11 +40,11 @@ unless process.env.ATOM_SHELL_INTERNAL_RUN_AS_NODE
Object.defineProperty module.exports, '$', get: ->
deprecate """
Requiring `$` from `atom` is no longer supported.
If you are using `space-pen`, please require `$` from `atom-space-pen-views`. Otherwise require `jquery` instead:
`{$} = require 'atom-space-pen-views'`
If you are using `space-pen`, please require `$` from `space-pen`. Otherwise require `jquery` instead:
`{$} = require 'space-pen'`
or
`$ = require 'jquery'`
Add `"atom-space-pen-views": "^2.0.3"` to your package dependencies.
Add `"space-pen": "^4"` to your package dependencies.
Or add `"jquery": "^2"` to your package dependencies.
"""
$
@@ -52,27 +52,27 @@ unless process.env.ATOM_SHELL_INTERNAL_RUN_AS_NODE
Object.defineProperty module.exports, '$$', get: ->
deprecate """
Requiring `$$` from `atom` is no longer supported.
Please require `atom-space-pen-views` instead:
`{$$} = require 'atom-space-pen-views'`
Add `"atom-space-pen-views": "^2.0.3"` to your package dependencies.
Please require `space-pen` instead:
`{$$} = require 'space-pen'`
Add `"space-pen": "^4"` to your package dependencies.
"""
$$
Object.defineProperty module.exports, '$$$', get: ->
deprecate """
Requiring `$$$` from `atom` is no longer supported.
Please require `atom-space-pen-views` instead:
`{$$$} = require 'atom-space-pen-views'`
Add `"atom-space-pen-views": "^2.0.3"` to your package dependencies.
Please require `space-pen` instead:
`{$$$} = require 'space-pen'`
Add `"space-pen": "^4"` to your package dependencies.
"""
$$$
Object.defineProperty module.exports, 'View', get: ->
deprecate """
Requiring `View` from `atom` is no longer supported.
Please require `atom-space-pen-views` instead:
`{View} = require 'atom-space-pen-views'`
Add `"atom-space-pen-views": "^2.0.3"` to your package dependencies.
Please require `space-pen` instead:
`{View} = require 'space-pen'`
Add `"space-pen": "^4"` to your package dependencies.
"""
View
@@ -81,7 +81,7 @@ unless process.env.ATOM_SHELL_INTERNAL_RUN_AS_NODE
Requiring `EditorView` from `atom` is no longer supported.
Please require `TextEditorView` from `atom-space-pen-view` instead:
`{TextEditorView} = require 'atom-space-pen-views'`
Add `"atom-space-pen-views": "^2.0.3"` to your package dependencies.
Add `"atom-space-pen-views": "^0"` to your package dependencies.
"""
require '../src/text-editor-view'
@@ -90,7 +90,7 @@ unless process.env.ATOM_SHELL_INTERNAL_RUN_AS_NODE
Requiring `TextEditorView` from `atom` is no longer supported.
Please require `TextEditorView` from `atom-space-pen-view` instead:
`{TextEditorView} = require 'atom-space-pen-views'`
Add `"atom-space-pen-views": "^2.0.3"` to your package dependencies.
Add `"atom-space-pen-views": "^0"` to your package dependencies.
"""
require '../src/text-editor-view'
@@ -100,7 +100,7 @@ unless process.env.ATOM_SHELL_INTERNAL_RUN_AS_NODE
Please require `ScrollView` from `atom-space-pen-view` instead:
`{ScrollView} = require 'atom-space-pen-views'`
Note that the API has changed slightly! Please read the docs at https://github.com/atom/atom-space-pen-views
Add `"atom-space-pen-views": "^2.0.3"` to your package dependencies.
Add `"atom-space-pen-views": "^0"` to your package dependencies.
"""
require '../src/scroll-view'
@@ -110,7 +110,7 @@ unless process.env.ATOM_SHELL_INTERNAL_RUN_AS_NODE
Please require `SelectListView` from `atom-space-pen-view` instead:
`{SelectListView} = require 'atom-space-pen-views'`
Note that the API has changed slightly! Please read the docs at https://github.com/atom/atom-space-pen-views
Add `"atom-space-pen-views": "^2.0.3"` to your package dependencies.
Add `"atom-space-pen-views": "^0"` to your package dependencies.
"""
require '../src/select-list-view'
+1 -1
Ver Arquivo
@@ -202,7 +202,7 @@
]
'context-menu':
'atom-text-editor, .overlayer': [
'.overlayer': [
{label: 'Undo', command: 'core:undo'}
{label: 'Redo', command: 'core:redo'}
{type: 'separator'}
+1 -1
Ver Arquivo
@@ -160,7 +160,7 @@
]
'context-menu':
'atom-text-editor, .overlayer': [
'.overlayer': [
{label: 'Undo', command: 'core:undo'}
{label: 'Redo', command: 'core:redo'}
{type: 'separator'}
+1 -1
Ver Arquivo
@@ -181,7 +181,7 @@
]
'context-menu':
'atom-text-editor, .overlayer': [
'.overlayer': [
{label: 'Undo', command: 'core:undo'}
{label: 'Redo', command: 'core:redo'}
{type: 'separator'}
+89 -91
Ver Arquivo
@@ -1,7 +1,7 @@
{
"name": "atom",
"productName": "Atom",
"version": "0.175.0",
"version": "0.157.0",
"description": "A hackable text editor for the 21st Century.",
"main": "./src/browser/main.js",
"repository": {
@@ -17,24 +17,23 @@
"url": "http://github.com/atom/atom/raw/master/LICENSE.md"
}
],
"atomShellVersion": "0.20.5",
"atomShellVersion": "0.19.4",
"dependencies": {
"async": "0.2.6",
"atom-keymap": "^2.5.2",
"atom-keymap": "^2.3.0",
"bootstrap": "git+https://github.com/atom/bootstrap.git#6af81906189f1747fd6c93479e3d998ebe041372",
"clear-cut": "0.4.0",
"coffee-script": "1.8.0",
"coffeestack": "0.8.0",
"color": "^0.7.3",
"coffee-script": "1.7.0",
"coffeestack": "0.7.0",
"delegato": "^1",
"emissary": "^1.3.1",
"event-kit": "^1.0.1",
"first-mate": "^2.2.4",
"event-kit": "0.8.1",
"first-mate": "^2.2.0",
"fs-plus": "^2.3.2",
"fstream": "0.1.24",
"fuzzaldrin": "^2.1",
"git-utils": "^2.2",
"grim": "1.1.0",
"git-utils": "^2.1.5",
"grim": "0.12.0",
"guid": "0.0.10",
"jasmine-json": "~0.0",
"jasmine-tagged": "^1.1.2",
@@ -44,110 +43,109 @@
"mixto": "^1",
"mkdirp": "0.3.5",
"nslog": "^1.0.1",
"oniguruma": "^3.0.6",
"oniguruma": "^3.0.4",
"optimist": "0.4.0",
"pathwatcher": "^2.6.1",
"pathwatcher": "^2.3.5",
"property-accessors": "^1",
"q": "^1.0.1",
"random-words": "0.0.1",
"react-atom-fork": "^0.11.4",
"react-atom-fork": "^0.11.1",
"reactionary-atom-fork": "^1.0.0",
"runas": "1.0.1",
"scandal": "1.0.3",
"scoped-property-store": "^0.16.2",
"scoped-property-store": "^0.15.0",
"scrollbar-style": "^1.0.2",
"season": "^5.0.5",
"season": "^1.0.2",
"semver": "2.2.1",
"serializable": "^1",
"service-hub": "^0.2.0",
"service-hub": "^0.1.0",
"space-pen": "3.8.2",
"stacktrace-parser": "0.1.1",
"temp": "0.7.0",
"text-buffer": "^3.10.1",
"text-buffer": "^3.8.2",
"theorist": "^1.0.2",
"underscore-plus": "^1.6.6",
"underscore-plus": "^1.6.1",
"vm-compatibility-layer": "0.1.0"
},
"packageDependencies": {
"atom-dark-syntax": "0.26.0",
"atom-dark-ui": "0.46.0",
"atom-light-syntax": "0.26.0",
"atom-light-ui": "0.40.0",
"base16-tomorrow-dark-theme": "0.25.0",
"base16-tomorrow-light-theme": "0.8.0",
"solarized-dark-syntax": "0.32.0",
"solarized-light-syntax": "0.19.0",
"archive-view": "0.44.0",
"autocomplete": "0.43.0",
"autoflow": "0.21.0",
"autosave": "0.20.0",
"background-tips": "0.21.0",
"bookmarks": "0.35.0",
"bracket-matcher": "0.69.0",
"command-palette": "0.34.0",
"deprecation-cop": "0.32.0",
"dev-live-reload": "0.39.0",
"encoding-selector": "0.17.0",
"atom-dark-syntax": "0.23.0",
"atom-dark-ui": "0.42.0",
"atom-light-syntax": "0.22.0",
"atom-light-ui": "0.36.0",
"base16-tomorrow-dark-theme": "0.22.0",
"base16-tomorrow-light-theme": "0.5.0",
"solarized-dark-syntax": "0.26.0",
"solarized-light-syntax": "0.13.0",
"archive-view": "0.40.0",
"autocomplete": "0.34.0",
"autoflow": "0.19.0",
"autosave": "0.19.0",
"background-tips": "0.18.0",
"bookmarks": "0.31.0",
"bracket-matcher": "0.64.0",
"command-palette": "0.30.0",
"deprecation-cop": "0.18.0",
"dev-live-reload": "0.35.0",
"encoding-selector": "0.10.0",
"exception-reporting": "0.21.0",
"find-and-replace": "0.156.0",
"fuzzy-finder": "0.65.0",
"git-diff": "0.49.0",
"go-to-line": "0.30.0",
"grammar-selector": "0.44.0",
"image-view": "0.47.0",
"incompatible-packages": "0.21.0",
"keybinding-resolver": "0.27.0",
"link": "0.29.0",
"markdown-preview": "0.124.0",
"metrics": "0.41.0",
"notifications": "0.25.0",
"open-on-github": "0.32.0",
"package-generator": "0.37.0",
"release-notes": "0.46.0",
"settings-view": "0.174.0",
"snippets": "0.70.0",
"spell-check": "0.51.0",
"status-bar": "0.57.0",
"styleguide": "0.42.0",
"symbols-view": "0.79.0",
"tabs": "0.64.0",
"timecop": "0.27.0",
"tree-view": "0.148.0",
"find-and-replace": "0.152.0",
"fuzzy-finder": "0.62.0",
"git-diff": "0.45.0",
"go-to-line": "0.27.0",
"grammar-selector": "0.37.0",
"image-view": "0.43.0",
"incompatible-packages": "0.15.0",
"keybinding-resolver": "0.23.0",
"link": "0.28.0",
"markdown-preview": "0.112.0",
"metrics": "0.39.0",
"notifications": "0.13.0",
"open-on-github": "0.31.0",
"package-generator": "0.33.0",
"release-notes": "0.36.0",
"settings-view": "0.161.0",
"snippets": "0.58.0",
"spell-check": "0.44.0",
"status-bar": "0.53.0",
"styleguide": "0.34.0",
"symbols-view": "0.70.0",
"tabs": "0.57.0",
"timecop": "0.24.0",
"tree-view": "0.137.0",
"update-package-dependencies": "0.7.0",
"welcome": "0.21.0",
"whitespace": "0.28.0",
"wrap-guide": "0.30.0",
"language-c": "0.37.0",
"language-clojure": "0.10.0",
"language-coffee-script": "0.39.0",
"language-css": "0.26.0",
"language-gfm": "0.63.0",
"language-git": "0.10.0",
"language-go": "0.21.0",
"language-html": "0.28.0",
"whitespace": "0.27.0",
"wrap-guide": "0.26.0",
"language-c": "0.33.0",
"language-clojure": "0.9.0",
"language-coffee-script": "0.38.1",
"language-css": "0.23.1",
"language-gfm": "0.55.0",
"language-git": "0.9.0",
"language-go": "0.19.1",
"language-html": "0.26.1",
"language-hyperlink": "0.12.2",
"language-java": "0.14.0",
"language-javascript": "0.55.0",
"language-json": "0.11.0",
"language-less": "0.24.0",
"language-make": "0.13.0",
"language-java": "0.13.0",
"language-javascript": "0.48.0",
"language-json": "0.10.0",
"language-less": "0.21.0",
"language-make": "0.12.0",
"language-mustache": "0.11.0",
"language-objective-c": "0.15.0",
"language-perl": "0.10.0",
"language-php": "0.20.0",
"language-property-list": "0.8.0",
"language-python": "0.30.0",
"language-ruby": "0.47.0",
"language-objective-c": "0.12.0",
"language-perl": "0.9.0",
"language-php": "0.18.0",
"language-property-list": "0.7.0",
"language-python": "0.26.0",
"language-ruby": "0.44.0",
"language-ruby-on-rails": "0.18.0",
"language-sass": "0.31.0",
"language-shellscript": "0.12.0",
"language-source": "0.9.0",
"language-sql": "0.14.0",
"language-sass": "0.28.0",
"language-shellscript": "0.10.1",
"language-source": "0.8.0",
"language-sql": "0.11.0",
"language-text": "0.6.0",
"language-todo": "0.15.0",
"language-toml": "0.15.0",
"language-xml": "0.27.0",
"language-yaml": "0.22.0"
"language-todo": "0.14.0",
"language-toml": "0.14.1",
"language-xml": "0.25.0",
"language-yaml": "0.21.0"
},
"private": true,
"scripts": {
Arquivo binário não exibido.

Antes

Largura:  |  Altura:  |  Tamanho: 628 KiB

Depois

Largura:  |  Altura:  |  Tamanho: 284 KiB

+1 -1
Ver Arquivo
@@ -1,6 +1,6 @@
Package: <%= name %>
Version: <%= version %>
Depends: git, gconf2, gconf-service, libgtk2.0-0, libudev0 | libudev1, libgcrypt11, libnotify4, libxtst6, libnss3, python, gvfs-bin, xdg-utils
Depends: gconf2, gconf-service, libgtk2.0-0, libudev0 | libudev1, libgcrypt11, libnotify4, libxtst6, libnss3, python, gvfs-bin, xdg-utils
Suggests: libgnome-keyring0, gir1.2-gnomekeyring-1.0
Section: <%= section %>
Priority: optional
Arquivo binário não exibido.
Arquivo binário não exibido.
-3
Ver Arquivo
@@ -1,3 +0,0 @@
#!/bin/sh
"$0/../../app/apm/bin/node.exe" "$0/../../app/apm/lib/cli.js" "$@"
-22
Ver Arquivo
@@ -1,22 +0,0 @@
@echo off
SET EXPECT_OUTPUT=
FOR %%a IN (%*) DO (
IF /I "%%a"=="-f" SET EXPECT_OUTPUT=YES
IF /I "%%a"=="--foreground" SET EXPECT_OUTPUT=YES
IF /I "%%a"=="-h" SET EXPECT_OUTPUT=YES
IF /I "%%a"=="--help" SET EXPECT_OUTPUT=YES
IF /I "%%a"=="-t" SET EXPECT_OUTPUT=YES
IF /I "%%a"=="--test" SET EXPECT_OUTPUT=YES
IF /I "%%a"=="-v" SET EXPECT_OUTPUT=YES
IF /I "%%a"=="--version" SET EXPECT_OUTPUT=YES
IF /I "%%a"=="-w" SET EXPECT_OUTPUT=YES
IF /I "%%a"=="--wait" SET EXPECT_OUTPUT=YES
)
IF "%EXPECT_OUTPUT%"=="YES" (
"%~dp0\..\..\atom.exe" %*
) ELSE (
"%~dp0\..\app\apm\bin\node.exe" "%~dp0\atom.js" %*
)
Arquivo binário não exibido.

Antes

Largura:  |  Altura:  |  Tamanho: 182 KiB

Depois

Largura:  |  Altura:  |  Tamanho: 141 KiB

-9
Ver Arquivo
@@ -1,9 +0,0 @@
var path = require('path');
var spawn = require('child_process').spawn;
var atomCommandPath = path.resolve(__dirname, '..', '..', 'atom.exe');
var arguments = process.argv.slice(2);
arguments.unshift('--executed-from', process.cwd());
var options = {detached: true, stdio: 'ignore'};
spawn(atomCommandPath, arguments, options);
process.exit(0);
-22
Ver Arquivo
@@ -1,22 +0,0 @@
#!/bin/sh
while getopts ":fhtvw-:" opt; do
case "$opt" in
-)
case "${OPTARG}" in
foreground|help|test|version|wait)
EXPECT_OUTPUT=1
;;
esac
;;
f|h|t|v|w)
EXPECT_OUTPUT=1
;;
esac
done
if [ $EXPECT_OUTPUT ]; then
"$0/../../../atom.exe" "$@"
else
"$0/../../app/apm/bin/node.exe" "$0/../atom.js" "$@"
fi
-2
Ver Arquivo
@@ -4,9 +4,7 @@ set -e
docker build -t atom-rpm .
docker run \
--rm \
--env JANKY_SHA1="$JANKY_SHA1" \
--env JANKY_BRANCH="$JANKY_BRANCH" \
--env ATOM_ACCESS_TOKEN="$BUILD_ATOM_RPM_ACCESS_TOKEN" \
atom-rpm /atom/script/rpmbuild
docker rmi atom-rpm
+1 -1
Ver Arquivo
@@ -117,7 +117,7 @@ class AtomReporter extends View
@div class: 'result-message fail deprecation-message', =>
@raw marked(deprecation.message)
for stack in deprecation.getStacks()
for stack in deprecation.stacks
fullStack = stack.map ({functionName, location}) ->
if functionName is '<unknown>'
" at #{location}"
-1
Ver Arquivo
@@ -54,7 +54,6 @@ describe "the `atom` global", ->
describe "loading default config", ->
it 'loads the default core config', ->
expect(atom.config.get('core.excludeVcsIgnoredPaths')).toBe true
expect(atom.config.get('core.followSymlinks')).toBe false
expect(atom.config.get('editor.showInvisibles')).toBe false
describe "window onerror handler", ->
-33
Ver Arquivo
@@ -1,5 +1,3 @@
ChildProcess = require 'child_process'
path = require 'path'
BufferedProcess = require '../src/buffered-process'
describe "BufferedProcess", ->
@@ -42,34 +40,3 @@ describe "BufferedProcess", ->
expect(window.onerror).toHaveBeenCalled()
expect(window.onerror.mostRecentCall.args[0]).toContain 'Failed to spawn command `bad-command-nope`'
expect(window.onerror.mostRecentCall.args[4].name).toBe 'BufferedProcessError'
describe "on Windows", ->
originalPlatform = null
beforeEach ->
# Prevent any commands from actually running and affecting the host
originalSpawn = ChildProcess.spawn
spyOn(ChildProcess, 'spawn').andCallFake ->
# Just spawn something that won't actually modify the host
if originalPlatform is 'win32'
originalSpawn('dir')
else
originalSpawn('ls')
originalPlatform = process.platform
Object.defineProperty process, 'platform', value: 'win32'
afterEach ->
Object.defineProperty process, 'platform', value: originalPlatform
describe "when the explorer command is spawned on Windows", ->
it "doesn't quote arguments of the form /root,C...", ->
new BufferedProcess({command: 'explorer.exe', args: ['/root,C:\\foo']})
expect(ChildProcess.spawn.argsForCall[0][1][2]).toBe '"explorer.exe /root,C:\\foo"'
it "spawns the command using a cmd.exe wrapper", ->
new BufferedProcess({command: 'dir'})
expect(path.basename(ChildProcess.spawn.argsForCall[0][0])).toBe 'cmd.exe'
expect(ChildProcess.spawn.argsForCall[0][1][0]).toBe '/s'
expect(ChildProcess.spawn.argsForCall[0][1][1]).toBe '/c'
expect(ChildProcess.spawn.argsForCall[0][1][2]).toBe '"dir"'
+872 -1220
Ver Arquivo
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
+4 -9
Ver Arquivo
@@ -351,16 +351,11 @@ describe "DisplayBuffer", ->
expect(displayBuffer.tokenizedLineForScreenRow(1).text).toMatch /^10/
describe "when there is another display buffer pointing to the same buffer", ->
it "does not consider folds to be nested inside of folds from the other display buffer", ->
it "does not create folds in the other display buffer", ->
otherDisplayBuffer = new DisplayBuffer({buffer, tabLength})
otherDisplayBuffer.createFold(1, 5)
displayBuffer.createFold(2, 4)
expect(otherDisplayBuffer.foldsStartingAtBufferRow(2).length).toBe 0
expect(displayBuffer.tokenizedLineForScreenRow(2).text).toBe '2'
expect(displayBuffer.tokenizedLineForScreenRow(3).text).toBe '5'
describe "when the buffer changes", ->
[fold1, fold2] = []
beforeEach ->
@@ -1063,7 +1058,7 @@ describe "DisplayBuffer", ->
[marker, decoration, decorationProperties] = []
beforeEach ->
marker = displayBuffer.markBufferRange([[2, 13], [3, 15]])
decorationProperties = {type: 'line-number', class: 'one'}
decorationProperties = {type: 'gutter', class: 'one'}
decoration = displayBuffer.decorateMarker(marker, decorationProperties)
it "can add decorations associated with markers and remove them", ->
@@ -1084,11 +1079,11 @@ describe "DisplayBuffer", ->
describe "when a decoration is updated via Decoration::update()", ->
it "emits an 'updated' event containing the new and old params", ->
decoration.onDidChangeProperties updatedSpy = jasmine.createSpy()
decoration.setProperties type: 'line-number', class: 'two'
decoration.setProperties type: 'gutter', class: 'two'
{oldProperties, newProperties} = updatedSpy.mostRecentCall.args[0]
expect(oldProperties).toEqual decorationProperties
expect(newProperties).toEqual type: 'line-number', class: 'two', id: decoration.id
expect(newProperties).toEqual type: 'gutter', class: 'two', id: decoration.id
describe "::getDecorations(properties)", ->
it "returns decorations matching the given optional properties", ->
@@ -1,5 +0,0 @@
class TestItem
getUri: -> "test"
exports.activate = ->
atom.workspace.addOpener -> new TestItem
@@ -1,4 +0,0 @@
{
"name": "package-with-empty-keymap",
"version": "1.0.0"
}
@@ -1,4 +0,0 @@
{
"name": "package-with-empty-menu",
"version": "1.0.0"
}
@@ -0,0 +1,6 @@
'.source.omg':
'editor':
'increaseIndentPattern': '^a'
'decreaseIndentPattern': '^z'
'commentStart': '/*'
'commentEnd': '*/'
@@ -1,3 +0,0 @@
'.source.omg':
'editor':
'increaseIndentPattern': '^a'
@@ -1 +0,0 @@
styleSheets: ['2', '1']
@@ -1 +1 @@
styleSheets: ['2', '1']
stylesheets: ['2', '1']
@@ -1,4 +1,4 @@
{
"theme": "ui",
"styleSheets": ["editor.less"]
"stylesheets": ["editor.less"]
}
+1 -1
Ver Arquivo
@@ -1,4 +1,4 @@
{
"theme": "ui",
"styleSheets": ["first.css", "second.less", "last.css"]
"stylesheets": ["first.css", "second.less", "last.css"]
}
@@ -1,4 +1,4 @@
{
"theme": "syntax",
"styleSheets": ["editor.less"]
"stylesheets": ["editor.less"]
}
+1 -1
Ver Arquivo
@@ -1,4 +1,4 @@
{
"theme": "ui",
"styleSheets": ["editor.less"]
"stylesheets": ["editor.less"]
}
-1
Ver Arquivo
@@ -1,3 +1,2 @@
module.exports = ->
emit("some-event", 1, 2, 3)
'hello'
-4
Ver Arquivo
@@ -259,10 +259,6 @@ describe "GitRepository", ->
editor.getBuffer().emitter.emit 'did-change-path'
expect(statusHandler.callCount).toBe 1
it "stops listening to the buffer when the repository is destroyed (regression)", ->
atom.project.getRepositories()[0].destroy()
expect(-> editor.save()).not.toThrow()
describe "when a project is deserialized", ->
[buffer, project2] = []
-3
Ver Arquivo
@@ -25,9 +25,6 @@ module.exports.runSpecSuite = (specSuite, logFile, logErrors=true) ->
log(str)
onComplete: (runner) ->
fs.closeSync(logStream) if logStream?
if process.env.JANKY_SHA1
grim = require 'grim'
grim.logDeprecations() if grim.getDeprecationsLength() > 0
atom.exit(runner.results().failedCount > 0 ? 1 : 0)
else
AtomReporter = require './atom-reporter'
-17
Ver Arquivo
@@ -381,23 +381,6 @@ describe "LanguageMode", ->
expect(languageMode.isFoldableAtBufferRow(3)).toBe false
expect(languageMode.isFoldableAtBufferRow(4)).toBe true
describe ".foldAllAtIndentLevel(indentLevel)", ->
it "folds blocks of text at the given indentation level", ->
languageMode.foldAllAtIndentLevel(0)
expect(editor.lineTextForScreenRow(0)).toBe "var quicksort = function () {"
expect(editor.getLastScreenRow()).toBe 0
languageMode.foldAllAtIndentLevel(1)
expect(editor.lineTextForScreenRow(0)).toBe "var quicksort = function () {"
expect(editor.lineTextForScreenRow(1)).toBe " var sort = function(items) {"
expect(editor.getLastScreenRow()).toBe 4
languageMode.foldAllAtIndentLevel(2)
expect(editor.lineTextForScreenRow(0)).toBe "var quicksort = function () {"
expect(editor.lineTextForScreenRow(1)).toBe " var sort = function(items) {"
expect(editor.lineTextForScreenRow(2)).toBe " if (items.length <= 1) return items;"
expect(editor.getLastScreenRow()).toBe 9
describe "folding with comments", ->
beforeEach ->
waitsForPromise ->
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
+8 -8
Ver Arquivo
@@ -9,14 +9,14 @@ describe "Package", ->
spyOn(atom, 'inDevMode').andReturn(false)
it "does not activate it", ->
packagePath = atom.project.getDirectories()[0]?.resolve('packages/package-with-incompatible-native-module')
packagePath = atom.project.resolve('packages/package-with-incompatible-native-module')
pack = new Package(packagePath)
expect(pack.isCompatible()).toBe false
expect(pack.incompatibleModules[0].name).toBe 'native-module'
expect(pack.incompatibleModules[0].path).toBe path.join(packagePath, 'node_modules', 'native-module')
it "caches the incompatible native modules in local storage", ->
packagePath = atom.project.getDirectories()[0]?.resolve('packages/package-with-incompatible-native-module')
packagePath = atom.project.resolve('packages/package-with-incompatible-native-module')
cacheKey = null
cacheItem = null
@@ -46,14 +46,14 @@ describe "Package", ->
describe "when the theme contains a single style file", ->
it "loads and applies css", ->
expect($("atom-text-editor").css("padding-bottom")).not.toBe "1234px"
themePath = atom.project.getDirectories()[0]?.resolve('packages/theme-with-index-css')
themePath = atom.project.resolve('packages/theme-with-index-css')
theme = new ThemePackage(themePath)
theme.activate()
expect($("atom-text-editor").css("padding-top")).toBe "1234px"
it "parses, loads and applies less", ->
expect($("atom-text-editor").css("padding-bottom")).not.toBe "1234px"
themePath = atom.project.getDirectories()[0]?.resolve('packages/theme-with-index-less')
themePath = atom.project.resolve('packages/theme-with-index-less')
theme = new ThemePackage(themePath)
theme.activate()
expect($("atom-text-editor").css("padding-top")).toBe "4321px"
@@ -64,7 +64,7 @@ describe "Package", ->
expect($("atom-text-editor").css("padding-right")).not.toBe("102px")
expect($("atom-text-editor").css("padding-bottom")).not.toBe("103px")
themePath = atom.project.getDirectories()[0]?.resolve('packages/theme-with-package-file')
themePath = atom.project.resolve('packages/theme-with-package-file')
theme = new ThemePackage(themePath)
theme.activate()
expect($("atom-text-editor").css("padding-top")).toBe("101px")
@@ -77,7 +77,7 @@ describe "Package", ->
expect($("atom-text-editor").css("padding-right")).not.toBe "20px"
expect($("atom-text-editor").css("padding-bottom")).not.toBe "30px"
themePath = atom.project.getDirectories()[0]?.resolve('packages/theme-without-package-file')
themePath = atom.project.resolve('packages/theme-without-package-file')
theme = new ThemePackage(themePath)
theme.activate()
expect($("atom-text-editor").css("padding-top")).toBe "10px"
@@ -86,7 +86,7 @@ describe "Package", ->
describe "reloading a theme", ->
beforeEach ->
themePath = atom.project.getDirectories()[0]?.resolve('packages/theme-with-package-file')
themePath = atom.project.resolve('packages/theme-with-package-file')
theme = new ThemePackage(themePath)
theme.activate()
@@ -97,7 +97,7 @@ describe "Package", ->
describe "events", ->
beforeEach ->
themePath = atom.project.getDirectories()[0]?.resolve('packages/theme-with-package-file')
themePath = atom.project.resolve('packages/theme-with-package-file')
theme = new ThemePackage(themePath)
theme.activate()
+1 -1
Ver Arquivo
@@ -129,7 +129,7 @@ describe "PaneContainer", ->
beforeEach ->
class TestItem
shouldPromptToSave: -> true
getURI: -> 'test'
getUri: -> 'test'
container = new PaneContainer
container.getRoot().splitRight()
+1 -1
Ver Arquivo
@@ -16,7 +16,7 @@ describe "PaneContainerView", ->
@content: -> @div tabindex: -1
initialize: (@name) -> @text(@name)
serialize: -> { deserializer: 'TestView', @name }
getURI: -> path.join(temp.dir, @name)
getUri: -> path.join(temp.dir, @name)
save: -> @saved = true
isEqual: (other) -> @name is other?.name
onDidChangeTitle: -> new Disposable(->)
+12 -12
Ver Arquivo
@@ -9,7 +9,7 @@ describe "Pane", ->
class Item extends Model
@deserialize: ({name, uri}) -> new this(name, uri)
constructor: (@name, @uri) ->
getURI: -> @uri
getUri: -> @uri
getPath: -> @path
serialize: -> {deserializer: 'Item', @name, @uri}
isEqual: (other) -> @name is other?.name
@@ -231,18 +231,18 @@ describe "Pane", ->
expect(pane.getActiveItem()).toBe item1
describe "if the item is modified", ->
itemURI = null
itemUri = null
beforeEach ->
item1.shouldPromptToSave = -> true
item1.save = jasmine.createSpy("save")
item1.saveAs = jasmine.createSpy("saveAs")
item1.getURI = -> itemURI
item1.getUri = -> itemUri
describe "if the [Save] option is selected", ->
describe "when the item has a uri", ->
it "saves the item before destroying it", ->
itemURI = "test"
itemUri = "test"
spyOn(atom, 'confirm').andReturn(0)
pane.destroyItem(item1)
@@ -252,7 +252,7 @@ describe "Pane", ->
describe "when the item has no uri", ->
it "presents a save-as dialog, then saves the item with the given uri before removing and destroying it", ->
itemURI = null
itemUri = null
spyOn(atom, 'showSaveDialogSync').andReturn("/selected/path")
spyOn(atom, 'confirm').andReturn(0)
@@ -404,15 +404,15 @@ describe "Pane", ->
pane.saveActiveItemAs()
expect(atom.showSaveDialogSync).not.toHaveBeenCalled()
describe "::itemForURI(uri)", ->
it "returns the item for which a call to .getURI() returns the given uri", ->
describe "::itemForUri(uri)", ->
it "returns the item for which a call to .getUri() returns the given uri", ->
pane = new Pane(items: [new Item("A"), new Item("B"), new Item("C"), new Item("D")])
[item1, item2, item3] = pane.getItems()
item1.uri = "a"
item2.uri = "b"
expect(pane.itemForURI("a")).toBe item1
expect(pane.itemForURI("b")).toBe item2
expect(pane.itemForURI("bogus")).toBeUndefined()
expect(pane.itemForUri("a")).toBe item1
expect(pane.itemForUri("b")).toBe item2
expect(pane.itemForUri("bogus")).toBeUndefined()
describe "::moveItem(item, index)", ->
[pane, item1, item2, item3, item4] = []
@@ -589,7 +589,7 @@ describe "Pane", ->
[item1, item2] = pane.getItems()
item1.shouldPromptToSave = -> true
item1.getURI = -> "/test/path"
item1.getUri = -> "/test/path"
item1.save = jasmine.createSpy("save")
spyOn(atom, 'confirm').andReturn(0)
@@ -604,7 +604,7 @@ describe "Pane", ->
[item1, item2] = pane.getItems()
item1.shouldPromptToSave = -> true
item1.getURI = -> "/test/path"
item1.getUri = -> "/test/path"
item1.save = jasmine.createSpy("save")
spyOn(atom, 'confirm').andReturn(1)
+1 -1
Ver Arquivo
@@ -15,7 +15,7 @@ describe "PaneView", ->
initialize: ({@id, @text}) ->
@emitter = new Emitter
serialize: -> { deserializer: 'TestView', @id, @text }
getURI: -> @id
getUri: -> @id
isEqual: (other) -> other? and @id == other.id and @text == other.text
changeTitle: ->
@emitter.emit 'did-change-title', 'title'
+308 -51
Ver Arquivo
@@ -4,11 +4,12 @@ Project = require '../src/project'
_ = require 'underscore-plus'
fs = require 'fs-plus'
path = require 'path'
platform = require './spec-helper-platform'
BufferedProcess = require '../src/buffered-process'
describe "Project", ->
beforeEach ->
atom.project.setPaths([atom.project.getDirectories()[0]?.resolve('dir')])
atom.project.setPaths([atom.project.resolve('dir')])
describe "serialization", ->
deserializedProject = null
@@ -37,32 +38,6 @@ describe "Project", ->
deserializedProject.getBuffers()[0].destroy()
expect(deserializedProject.getBuffers().length).toBe 0
it "does not deserialize buffers when their path is a directory that exists", ->
pathToOpen = path.join(temp.mkdirSync(), 'file.txt')
waitsForPromise ->
atom.project.open(pathToOpen)
runs ->
expect(atom.project.getBuffers().length).toBe 1
fs.mkdirSync(pathToOpen)
deserializedProject = atom.project.testSerialization()
expect(deserializedProject.getBuffers().length).toBe 0
it "does not deserialize buffers when their path is inaccessible", ->
pathToOpen = path.join(temp.mkdirSync(), 'file.txt')
fs.writeFileSync(pathToOpen, '')
waitsForPromise ->
atom.project.open(pathToOpen)
runs ->
expect(atom.project.getBuffers().length).toBe 1
fs.chmodSync(pathToOpen, '000')
deserializedProject = atom.project.testSerialization()
expect(deserializedProject.getBuffers().length).toBe 0
describe "when an editor is saved and the project has no path", ->
it "sets the project's path to the saved file's parent directory", ->
tempFile = temp.openSync().path
@@ -77,29 +52,6 @@ describe "Project", ->
editor.saveAs(tempFile)
expect(atom.project.getPaths()[0]).toBe path.dirname(tempFile)
describe "when a watch error is thrown from the TextBuffer", ->
editor = null
beforeEach ->
waitsForPromise ->
atom.project.open(require.resolve('./fixtures/dir/a')).then (o) -> editor = o
it "creates a warning notification", ->
atom.notifications.onDidAddNotification noteSpy = jasmine.createSpy()
error = new Error('SomeError')
error.eventType = 'resurrect'
editor.buffer.emitter.emit 'will-throw-watch-error',
handle: jasmine.createSpy()
error: error
expect(noteSpy).toHaveBeenCalled()
notification = noteSpy.mostRecentCall.args[0]
expect(notification.getType()).toBe 'warning'
expect(notification.getDetail()).toBe 'SomeError'
expect(notification.getMessage()).toContain '`resurrect`'
expect(notification.getMessage()).toContain 'fixtures/dir/a'
describe ".open(path)", ->
[absolutePath, newBufferHandler] = []
@@ -158,7 +110,7 @@ describe "Project", ->
expect(newBufferHandler).toHaveBeenCalledWith(editor.buffer)
it "returns number of read bytes as progress indicator", ->
filePath = atom.project.getDirectories()[0]?.resolve 'a'
filePath = atom.project.resolve 'a'
totalBytes = 0
promise = atom.project.open(filePath)
promise.progress (bytesRead) -> totalBytes = bytesRead
@@ -197,6 +149,27 @@ describe "Project", ->
atom.project.bufferForPath("b").then (anotherBuffer) ->
expect(anotherBuffer).not.toBe buffer
describe ".resolve(uri)", ->
describe "when passed an absolute or relative path", ->
it "returns an absolute path based on the atom.project's root", ->
absolutePath = require.resolve('./fixtures/dir/a')
expect(atom.project.resolve('a')).toBe absolutePath
expect(atom.project.resolve(absolutePath + '/../a')).toBe absolutePath
expect(atom.project.resolve('a/../a')).toBe absolutePath
expect(atom.project.resolve()).toBeUndefined()
describe "when passed a uri with a scheme", ->
it "does not modify uris that begin with a scheme", ->
expect(atom.project.resolve('http://zombo.com')).toBe 'http://zombo.com'
describe "when the project has no path", ->
it "returns undefined for relative URIs", ->
atom.project.setPaths([])
expect(atom.project.resolve('test.txt')).toBeUndefined()
expect(atom.project.resolve('http://github.com')).toBe 'http://github.com'
absolutePath = fs.absolute(__dirname)
expect(atom.project.resolve(absolutePath)).toBe absolutePath
describe ".setPaths(path)", ->
describe "when path is a file", ->
it "sets its path to the files parent directory and updates the root directory", ->
@@ -222,6 +195,290 @@ describe "Project", ->
expect(atom.project.getPaths()[0]).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] = []
beforeEach ->
atom.project.setPaths([atom.project.resolve('../')])
filePath = atom.project.resolve('sample.js')
commentFilePath = atom.project.resolve('sample-with-comments.js')
sampleContent = fs.readFileSync(filePath).toString()
sampleCommentContent = fs.readFileSync(commentFilePath).toString()
afterEach ->
fs.writeFileSync(filePath, sampleContent)
fs.writeFileSync(commentFilePath, sampleCommentContent)
describe "when a file doesn't exist", ->
it "calls back with an error", ->
errors = []
missingPath = path.resolve('/not-a-file.js')
expect(fs.existsSync(missingPath)).toBeFalsy()
waitsForPromise ->
atom.project.replace /items/gi, 'items', [missingPath], (result, error) ->
errors.push(error)
runs ->
expect(errors).toHaveLength 1
expect(errors[0].path).toBe missingPath
describe "when called with unopened files", ->
it "replaces properly", ->
results = []
waitsForPromise ->
atom.project.replace /items/gi, 'items', [filePath], (result) ->
results.push(result)
runs ->
expect(results).toHaveLength 1
expect(results[0].filePath).toBe filePath
expect(results[0].replacements).toBe 6
describe "when a buffer is already open", ->
it "replaces properly and saves when not modified", ->
editor = null
results = []
waitsForPromise ->
atom.project.open('sample.js').then (o) -> editor = o
runs ->
expect(editor.isModified()).toBeFalsy()
waitsForPromise ->
atom.project.replace /items/gi, 'items', [filePath], (result) ->
results.push(result)
runs ->
expect(results).toHaveLength 1
expect(results[0].filePath).toBe filePath
expect(results[0].replacements).toBe 6
expect(editor.isModified()).toBeFalsy()
it "does not replace when the path is not specified", ->
editor = null
results = []
waitsForPromise ->
atom.project.open('sample-with-comments.js').then (o) -> editor = o
waitsForPromise ->
atom.project.replace /items/gi, 'items', [commentFilePath], (result) ->
results.push(result)
runs ->
expect(results).toHaveLength 1
expect(results[0].filePath).toBe commentFilePath
it "does NOT save when modified", ->
editor = null
results = []
waitsForPromise ->
atom.project.open('sample.js').then (o) -> editor = o
runs ->
editor.buffer.setTextInRange([[0,0],[0,0]], 'omg')
expect(editor.isModified()).toBeTruthy()
waitsForPromise ->
atom.project.replace /items/gi, 'okthen', [filePath], (result) ->
results.push(result)
runs ->
expect(results).toHaveLength 1
expect(results[0].filePath).toBe filePath
expect(results[0].replacements).toBe 6
expect(editor.isModified()).toBeTruthy()
describe ".scan(options, callback)", ->
describe "when called with a regex", ->
it "calls the callback with all regex results in all files in the project", ->
results = []
waitsForPromise ->
atom.project.scan /(a)+/, (result) ->
results.push(result)
runs ->
expect(results).toHaveLength(3)
expect(results[0].filePath).toBe atom.project.resolve('a')
expect(results[0].matches).toHaveLength(3)
expect(results[0].matches[0]).toEqual
matchText: 'aaa'
lineText: 'aaa bbb'
lineTextOffset: 0
range: [[0, 0], [0, 3]]
it "works with with escaped literals (like $ and ^)", ->
results = []
waitsForPromise ->
atom.project.scan /\$\w+/, (result) -> results.push(result)
runs ->
expect(results.length).toBe 1
{filePath, matches} = results[0]
expect(filePath).toBe atom.project.resolve('a')
expect(matches).toHaveLength 1
expect(matches[0]).toEqual
matchText: '$bill'
lineText: 'dollar$bill'
lineTextOffset: 0
range: [[2, 6], [2, 11]]
it "works on evil filenames", ->
platform.generateEvilFiles()
atom.project.setPaths([path.join(__dirname, 'fixtures', 'evil-files')])
paths = []
matches = []
waitsForPromise ->
atom.project.scan /evil/, (result) ->
paths.push(result.filePath)
matches = matches.concat(result.matches)
runs ->
_.each(matches, (m) -> expect(m.matchText).toEqual 'evil')
if platform.isWindows()
expect(paths.length).toBe 3
expect(paths[0]).toMatch /a_file_with_utf8.txt$/
expect(paths[1]).toMatch /file with spaces.txt$/
expect(path.basename(paths[2])).toBe "utfa\u0306.md"
else
expect(paths.length).toBe 5
expect(paths[0]).toMatch /a_file_with_utf8.txt$/
expect(paths[1]).toMatch /file with spaces.txt$/
expect(paths[2]).toMatch /goddam\nnewlines$/m
expect(paths[3]).toMatch /quote".txt$/m
expect(path.basename(paths[4])).toBe "utfa\u0306.md"
it "ignores case if the regex includes the `i` flag", ->
results = []
waitsForPromise ->
atom.project.scan /DOLLAR/i, (result) -> results.push(result)
runs ->
expect(results).toHaveLength 1
describe "when the core.excludeVcsIgnoredPaths config is truthy", ->
[projectPath, ignoredPath] = []
beforeEach ->
sourceProjectPath = path.join(__dirname, 'fixtures', 'git', 'working-dir')
projectPath = path.join(temp.mkdirSync("atom"))
writerStream = fstream.Writer(projectPath)
fstream.Reader(sourceProjectPath).pipe(writerStream)
waitsFor (done) ->
writerStream.on 'close', done
writerStream.on 'error', done
runs ->
fs.rename(path.join(projectPath, 'git.git'), path.join(projectPath, '.git'))
ignoredPath = path.join(projectPath, 'ignored.txt')
fs.writeFileSync(ignoredPath, 'this match should not be included')
afterEach ->
fs.removeSync(projectPath) if fs.existsSync(projectPath)
it "excludes ignored files", ->
atom.project.setPaths([projectPath])
atom.config.set('core.excludeVcsIgnoredPaths', true)
resultHandler = jasmine.createSpy("result found")
waitsForPromise ->
atom.project.scan /match/, (results) ->
resultHandler()
runs ->
expect(resultHandler).not.toHaveBeenCalled()
it "includes only files when a directory filter is specified", ->
projectPath = path.join(path.join(__dirname, 'fixtures', 'dir'))
atom.project.setPaths([projectPath])
filePath = path.join(projectPath, 'a-dir', 'oh-git')
paths = []
matches = []
waitsForPromise ->
atom.project.scan /aaa/, paths: ["a-dir#{path.sep}"], (result) ->
paths.push(result.filePath)
matches = matches.concat(result.matches)
runs ->
expect(paths.length).toBe 1
expect(paths[0]).toBe filePath
expect(matches.length).toBe 1
it "includes files and folders that begin with a '.'", ->
projectPath = temp.mkdirSync()
filePath = path.join(projectPath, '.text')
fs.writeFileSync(filePath, 'match this')
atom.project.setPaths([projectPath])
paths = []
matches = []
waitsForPromise ->
atom.project.scan /match this/, (result) ->
paths.push(result.filePath)
matches = matches.concat(result.matches)
runs ->
expect(paths.length).toBe 1
expect(paths[0]).toBe filePath
expect(matches.length).toBe 1
it "excludes values in core.ignoredNames", ->
projectPath = path.join(__dirname, 'fixtures', 'git', 'working-dir')
ignoredNames = atom.config.get("core.ignoredNames")
ignoredNames.push("a")
atom.config.set("core.ignoredNames", ignoredNames)
resultHandler = jasmine.createSpy("result found")
waitsForPromise ->
atom.project.scan /dollar/, (results) ->
resultHandler()
runs ->
expect(resultHandler).not.toHaveBeenCalled()
it "scans buffer contents if the buffer is modified", ->
editor = null
results = []
waitsForPromise ->
atom.project.open('a').then (o) ->
editor = o
editor.setText("Elephant")
waitsForPromise ->
atom.project.scan /a|Elephant/, (result) -> results.push result
runs ->
expect(results).toHaveLength 3
resultForA = _.find results, ({filePath}) -> path.basename(filePath) == 'a'
expect(resultForA.matches).toHaveLength 1
expect(resultForA.matches[0].matchText).toBe 'Elephant'
it "ignores buffers outside the project", ->
editor = null
results = []
waitsForPromise ->
atom.project.open(temp.openSync().path).then (o) ->
editor = o
editor.setText("Elephant")
waitsForPromise ->
atom.project.scan /Elephant/, (result) -> results.push result
runs ->
expect(results).toHaveLength 0
describe ".eachBuffer(callback)", ->
beforeEach ->
atom.project.bufferForPathSync('a')
+6 -10
Ver Arquivo
@@ -84,10 +84,6 @@ beforeEach ->
atom.workspaceViewParentSelector = '#jasmine-content'
window.resetTimeouts()
spyOn(_._, "now").andCallFake -> window.now
spyOn(window, "setTimeout").andCallFake window.fakeSetTimeout
spyOn(window, "clearTimeout").andCallFake window.fakeClearTimeout
atom.packages.packageStates = {}
serializedWindowState = null
@@ -106,9 +102,9 @@ beforeEach ->
spyOn(atom.menu, 'sendToBrowserProcess')
# reset config before each spec; don't load or save from/to `config.json`
spyOn(Config::, 'load')
spyOn(Config::, 'save')
config = new Config({resourcePath, configDirPath: atom.getConfigDirPath()})
spyOn(config, 'load')
spyOn(config, 'save')
atom.config = config
atom.loadConfig()
config.set "core.destroyEmptyPanes", false
@@ -118,8 +114,6 @@ beforeEach ->
config.set "core.disabledPackages", ["package-that-throws-an-exception",
"package-with-broken-package-json", "package-with-broken-keymap"]
config.set "editor.useShadowDOM", true
advanceClock(1000)
window.setTimeout.reset()
config.load.reset()
config.save.reset()
@@ -127,6 +121,8 @@ beforeEach ->
TextEditorElement::setUpdatedSynchronously(true)
spyOn(atom, "setRepresentedFilename")
spyOn(window, "setTimeout").andCallFake window.fakeSetTimeout
spyOn(window, "clearTimeout").andCallFake window.fakeClearTimeout
spyOn(pathwatcher.File.prototype, "detectResurrectionAfterDelay").andCallFake -> @detectResurrection()
spyOn(TextEditor.prototype, "shouldPromptToSave").andReturn false
@@ -208,10 +204,10 @@ jasmine.attachToDOM = (element) ->
deprecationsSnapshot = null
jasmine.snapshotDeprecations = ->
deprecationsSnapshot = _.clone(Grim.deprecations)
deprecationsSnapshot = Grim.getDeprecations() # suppress deprecations!!
jasmine.restoreDeprecationsSnapshot = ->
Grim.deprecations = deprecationsSnapshot
Grim.grimDeprecations = deprecationsSnapshot
addCustomMatchers = (spec) ->
spec.addMatchers
-104
Ver Arquivo
@@ -1,104 +0,0 @@
ChildProcess = require 'child_process'
{EventEmitter} = require 'events'
fs = require 'fs-plus'
path = require 'path'
temp = require 'temp'
SquirrelUpdate = require '../src/browser/squirrel-update'
describe "Windows squirrel updates", ->
tempHomeDirectory = null
beforeEach ->
# Prevent the actually home directory from being manipulated
tempHomeDirectory = temp.mkdirSync('atom-temp-home-')
spyOn(fs, 'getHomeDirectory').andReturn(tempHomeDirectory)
# Prevent any commands from actually running and affecting the host
originalSpawn = ChildProcess.spawn
spyOn(ChildProcess, 'spawn').andCallFake (command, args) ->
if path.basename(command) is 'Update.exe' and args?[0] is '--createShortcut'
fs.writeFileSync(path.join(tempHomeDirectory, 'Desktop', 'Atom.lnk'), '')
# Just spawn something that won't actually modify the host
if process.platform is 'win32'
originalSpawn('dir')
else
originalSpawn('ls')
it "ignores errors spawning Squirrel", ->
jasmine.unspy(ChildProcess, 'spawn')
spyOn(ChildProcess, 'spawn').andCallFake -> throw new Error("EBUSY")
app = quit: jasmine.createSpy('quit')
expect(SquirrelUpdate.handleStartupEvent(app, '--squirrel-install')).toBe true
waitsFor ->
app.quit.callCount is 1
it "quits the app on all squirrel events", ->
app = quit: jasmine.createSpy('quit')
expect(SquirrelUpdate.handleStartupEvent(app, '--squirrel-install')).toBe true
waitsFor ->
app.quit.callCount is 1
runs ->
app.quit.reset()
expect(SquirrelUpdate.handleStartupEvent(app, '--squirrel-updated')).toBe true
waitsFor ->
app.quit.callCount is 1
runs ->
app.quit.reset()
expect(SquirrelUpdate.handleStartupEvent(app, '--squirrel-uninstall')).toBe true
waitsFor ->
app.quit.callCount is 1
runs ->
app.quit.reset()
expect(SquirrelUpdate.handleStartupEvent(app, '--squirrel-obsolete')).toBe true
waitsFor ->
app.quit.callCount is 1
runs ->
expect(SquirrelUpdate.handleStartupEvent(app, '--not-squirrel')).toBe false
it "keeps the desktop shortcut deleted on updates if it was previously deleted after install", ->
desktopShortcutPath = path.join(tempHomeDirectory, 'Desktop', 'Atom.lnk')
expect(fs.existsSync(desktopShortcutPath)).toBe false
app = quit: jasmine.createSpy('quit')
expect(SquirrelUpdate.handleStartupEvent(app, '--squirrel-install')).toBe true
waitsFor ->
app.quit.callCount is 1
runs ->
app.quit.reset()
expect(fs.existsSync(desktopShortcutPath)).toBe true
fs.removeSync(desktopShortcutPath)
expect(fs.existsSync(desktopShortcutPath)).toBe false
expect(SquirrelUpdate.handleStartupEvent(app, '--squirrel-updated')).toBe true
waitsFor ->
app.quit.callCount is 1
runs ->
expect(fs.existsSync(desktopShortcutPath)).toBe false
describe ".restartAtom", ->
it "quits the app and spawns a new one", ->
app = new EventEmitter()
app.quit = jasmine.createSpy('quit')
SquirrelUpdate.restartAtom(app)
expect(app.quit.callCount).toBe 1
expect(ChildProcess.spawn.callCount).toBe 0
app.emit('will-quit')
expect(ChildProcess.spawn.callCount).toBe 1
expect(path.basename(ChildProcess.spawn.argsForCall[0][0])).toBe 'atom.cmd'
+6 -8
Ver Arquivo
@@ -53,16 +53,14 @@ describe "StyleManager", ->
expect(addEvents[0].getAttribute('source-path')).toBe '/foo/bar'
expect(addEvents[0].textContent).toBe "a {color: yellow;}"
describe "when a priority parameter is specified", ->
it "inserts the style sheet based on the priority", ->
manager.addStyleSheet("a {color: red}", priority: 1)
manager.addStyleSheet("a {color: blue}", priority: 0)
manager.addStyleSheet("a {color: green}", priority: 2)
manager.addStyleSheet("a {color: yellow}", priority: 1)
describe "when a group parameter is specified", ->
it "inserts the stylesheet at the end of any existing stylesheets for the same group", ->
manager.addStyleSheet("a {color: red}", group: 'a')
manager.addStyleSheet("a {color: blue}", group: 'b')
manager.addStyleSheet("a {color: green}", group: 'a')
expect(manager.getStyleElements().map (elt) -> elt.textContent).toEqual [
"a {color: blue}"
"a {color: red}"
"a {color: yellow}"
"a {color: green}"
"a {color: blue}"
]
+7 -9
Ver Arquivo
@@ -32,18 +32,16 @@ describe "StylesElement", ->
expect(element.children[initialChildCount].textContent).toBe "a {color: blue;}"
expect(removedStyleElements).toEqual [addedStyleElements[0]]
it "orders style elements by priority", ->
it "orders style elements by group", ->
initialChildCount = element.children.length
atom.styles.addStyleSheet("a {color: red}", priority: 1)
atom.styles.addStyleSheet("a {color: blue}", priority: 0)
atom.styles.addStyleSheet("a {color: green}", priority: 2)
atom.styles.addStyleSheet("a {color: yellow}", priority: 1)
atom.styles.addStyleSheet("a {color: red}", group: 'a')
atom.styles.addStyleSheet("a {color: blue}", group: 'b')
atom.styles.addStyleSheet("a {color: green}", group: 'a')
expect(element.children[initialChildCount].textContent).toBe "a {color: blue}"
expect(element.children[initialChildCount + 1].textContent).toBe "a {color: red}"
expect(element.children[initialChildCount + 2].textContent).toBe "a {color: yellow}"
expect(element.children[initialChildCount + 3].textContent).toBe "a {color: green}"
expect(element.children[initialChildCount].textContent).toBe "a {color: red}"
expect(element.children[initialChildCount + 1].textContent).toBe "a {color: green}"
expect(element.children[initialChildCount + 2].textContent).toBe "a {color: blue}"
it "updates existing style nodes when style elements are updated", ->
initialChildCount = element.children.length
-23
Ver Arquivo
@@ -20,26 +20,3 @@ describe "Task", ->
expect(handlerResult).toBe 'hello'
expect(childProcess.kill).toHaveBeenCalled()
expect(processErrored).toBe false
it "calls listeners registered with ::on when events are emitted in the task", ->
task = new Task(require.resolve('./fixtures/task-spec-handler'))
eventSpy = jasmine.createSpy('eventSpy')
task.on("some-event", eventSpy)
waitsFor (done) -> task.start(done)
runs ->
expect(eventSpy).toHaveBeenCalledWith(1, 2, 3)
it "unregisters listeners when the Disposable returned by ::on is disposed", ->
task = new Task(require.resolve('./fixtures/task-spec-handler'))
eventSpy = jasmine.createSpy('eventSpy')
disposable = task.on("some-event", eventSpy)
disposable.dispose()
waitsFor (done) -> task.start(done)
runs ->
expect(eventSpy).not.toHaveBeenCalled()
+69 -107
Ver Arquivo
@@ -429,7 +429,7 @@ describe "TextEditorComponent", ->
it "excludes the null byte from character measurement", ->
editor.setText("a\0b")
nextAnimationFrame()
expect(wrapperNode.pixelPositionForScreenPosition([0, Infinity]).left).toEqual 2 * charWidth
expect(editor.pixelPositionForScreenPosition([0, Infinity]).left).toEqual 2 * charWidth
describe "when there is a fold", ->
it "renders a fold marker on the folded line", ->
@@ -552,29 +552,14 @@ describe "TextEditorComponent", ->
nextAnimationFrame()
expect(lineNumbersNode.style.backgroundColor).toBe 'rgb(255, 0, 0)'
it "hides or shows the gutter based on the '::isGutterVisible' property on the model and the global 'editor.showLineNumbers' config setting", ->
expect(component.refs.gutter?).toBe true
editor.setGutterVisible(false)
nextAnimationFrame()
expect(component.refs.gutter?).toBe false
atom.config.set("editor.showLineNumbers", false)
expect(nextAnimationFrame).toBe noAnimationFrame
expect(component.refs.gutter?).toBe false
editor.setGutterVisible(true)
expect(nextAnimationFrame).toBe noAnimationFrame
expect(component.refs.gutter?).toBe false
atom.config.set("editor.showLineNumbers", true)
nextAnimationFrame()
expect(component.refs.gutter?).toBe true
expect(component.lineNumberNodeForScreenRow(3)?).toBe true
describe "when the editor.showLineNumbers config is false", ->
it "doesn't render any line numbers", ->
expect(component.refs.gutter).toBeDefined()
atom.config.set("editor.showLineNumbers", false)
expect(component.refs.gutter).not.toBeDefined()
atom.config.set("editor.showLineNumbers", true)
expect(component.refs.gutter).toBeDefined()
expect(component.lineNumberNodeForScreenRow(3)).toBeDefined()
describe "fold decorations", ->
describe "rendering fold decorations", ->
@@ -770,6 +755,7 @@ describe "TextEditorComponent", ->
expect(cursorNode.offsetWidth).toBe charWidth
it "blinks cursors when they aren't moving", ->
spyOn(_._, 'now').andCallFake -> window.now # Ensure _.debounce is based on our fake spec timeline
cursorsNode = componentNode.querySelector('.cursors')
expect(cursorsNode.classList.contains('blink-off')).toBe false
@@ -816,7 +802,7 @@ describe "TextEditorComponent", ->
nextAnimationFrame()
cursorNode = componentNode.querySelector('.cursor')
{left} = wrapperNode.pixelPositionForScreenPosition([1, 10])
{left} = editor.pixelPositionForScreenPosition([1, 10])
expect(cursorNode.style['-webkit-transform']).toBe "translate(#{left}px, #{editor.getLineHeightInPixels()}px)"
describe "selection rendering", ->
@@ -910,7 +896,7 @@ describe "TextEditorComponent", ->
nextAnimationFrame()
selectionNode = componentNode.querySelector('.region')
expect(selectionNode.offsetTop).toBe editor.getLineHeightInPixels()
expect(selectionNode.offsetLeft).toBe wrapperNode.pixelPositionForScreenPosition([1, 6]).left
expect(selectionNode.offsetLeft).toBe editor.pixelPositionForScreenPosition([1, 6]).left
it "will flash the selection when flash:true is passed to editor::setSelectedBufferRange", ->
editor.setSelectedBufferRange([[1, 6], [1, 10]], flash: true)
@@ -931,7 +917,7 @@ describe "TextEditorComponent", ->
beforeEach ->
marker = editor.displayBuffer.markBufferRange([[2, 13], [3, 15]], invalidate: 'inside')
decorationParams = {type: ['line-number', 'line'], class: 'a'}
decorationParams = {type: ['gutter', 'line'], class: 'a'}
decoration = editor.decorateMarker(marker, decorationParams)
nextAnimationFrame()
@@ -946,7 +932,7 @@ describe "TextEditorComponent", ->
# Add decorations that are out of range
marker2 = editor.displayBuffer.markBufferRange([[9, 0], [9, 0]])
editor.decorateMarker(marker2, type: ['line-number', 'line'], class: 'b')
editor.decorateMarker(marker2, type: ['gutter', 'line'], class: 'b')
nextAnimationFrame()
# Scroll decorations into view
@@ -970,7 +956,7 @@ describe "TextEditorComponent", ->
marker.destroy()
marker = editor.markBufferRange([[0, 0], [0, 2]])
editor.decorateMarker(marker, type: ['line-number', 'line'], class: 'b')
editor.decorateMarker(marker, type: ['gutter', 'line'], class: 'b')
nextAnimationFrame()
expect(lineNumberHasClass(0, 'b')).toBe true
expect(lineNumberHasClass(1, 'b')).toBe false
@@ -1039,7 +1025,7 @@ describe "TextEditorComponent", ->
describe "when the decoration's 'onlyHead' property is true", ->
it "only applies the decoration's class to lines containing the marker's head", ->
editor.decorateMarker(marker, type: ['line-number', 'line'], class: 'only-head', onlyHead: true)
editor.decorateMarker(marker, type: ['gutter', 'line'], class: 'only-head', onlyHead: true)
nextAnimationFrame()
expect(lineAndLineNumberHaveClass(1, 'only-head')).toBe false
expect(lineAndLineNumberHaveClass(2, 'only-head')).toBe false
@@ -1048,7 +1034,7 @@ describe "TextEditorComponent", ->
describe "when the decoration's 'onlyEmpty' property is true", ->
it "only applies the decoration when its marker is empty", ->
editor.decorateMarker(marker, type: ['line-number', 'line'], class: 'only-empty', onlyEmpty: true)
editor.decorateMarker(marker, type: ['gutter', 'line'], class: 'only-empty', onlyEmpty: true)
nextAnimationFrame()
expect(lineAndLineNumberHaveClass(2, 'only-empty')).toBe false
expect(lineAndLineNumberHaveClass(3, 'only-empty')).toBe false
@@ -1060,7 +1046,7 @@ describe "TextEditorComponent", ->
describe "when the decoration's 'onlyNonEmpty' property is true", ->
it "only applies the decoration when its marker is non-empty", ->
editor.decorateMarker(marker, type: ['line-number', 'line'], class: 'only-non-empty', onlyNonEmpty: true)
editor.decorateMarker(marker, type: ['gutter', 'line'], class: 'only-non-empty', onlyNonEmpty: true)
nextAnimationFrame()
expect(lineAndLineNumberHaveClass(2, 'only-non-empty')).toBe true
expect(lineAndLineNumberHaveClass(3, 'only-non-empty')).toBe true
@@ -1245,7 +1231,7 @@ describe "TextEditorComponent", ->
decoration = editor.decorateMarker(marker, {type: 'overlay', item})
nextAnimationFrame()
position = wrapperNode.pixelPositionForBufferPosition([2, 5])
position = editor.pixelPositionForBufferPosition([2, 5])
overlay = component.getTopmostDOMNode().querySelector('atom-overlay')
expect(overlay.style.left).toBe position.left + 'px'
@@ -1255,7 +1241,7 @@ describe "TextEditorComponent", ->
editor.moveRight()
nextAnimationFrame()
position = wrapperNode.pixelPositionForBufferPosition([2, 7])
position = editor.pixelPositionForBufferPosition([2, 7])
expect(overlay.style.left).toBe position.left + 'px'
expect(overlay.style.top).toBe position.top + editor.getLineHeightInPixels() + 'px'
@@ -1266,7 +1252,7 @@ describe "TextEditorComponent", ->
decoration = editor.decorateMarker(marker, {type: 'overlay', item})
nextAnimationFrame()
position = wrapperNode.pixelPositionForBufferPosition([2, 10])
position = editor.pixelPositionForBufferPosition([2, 10])
overlay = component.getTopmostDOMNode().querySelector('atom-overlay')
expect(overlay.style.left).toBe position.left + 'px'
@@ -1277,7 +1263,7 @@ describe "TextEditorComponent", ->
decoration = editor.decorateMarker(marker, {type: 'overlay', item})
nextAnimationFrame()
position = wrapperNode.pixelPositionForBufferPosition([2, 5])
position = editor.pixelPositionForBufferPosition([2, 5])
overlay = component.getTopmostDOMNode().querySelector('atom-overlay')
expect(overlay.style.left).toBe position.left + 'px'
@@ -1288,7 +1274,7 @@ describe "TextEditorComponent", ->
decoration = editor.decorateMarker(marker, {type: 'overlay', position: 'tail', item})
nextAnimationFrame()
position = wrapperNode.pixelPositionForBufferPosition([2, 5])
position = editor.pixelPositionForBufferPosition([2, 5])
overlay = component.getTopmostDOMNode().querySelector('atom-overlay')
expect(overlay.style.left).toBe position.left + 'px'
@@ -1318,7 +1304,7 @@ describe "TextEditorComponent", ->
decoration = editor.decorateMarker(marker, {type: 'overlay', item})
nextAnimationFrame()
position = wrapperNode.pixelPositionForBufferPosition([0, 26])
position = editor.pixelPositionForBufferPosition([0, 26])
overlay = component.getTopmostDOMNode().querySelector('atom-overlay')
expect(overlay.style.left).toBe position.left + 'px'
@@ -1327,7 +1313,7 @@ describe "TextEditorComponent", ->
editor.insertText('a')
nextAnimationFrame()
position = wrapperNode.pixelPositionForBufferPosition([0, 27])
position = editor.pixelPositionForBufferPosition([0, 27])
expect(overlay.style.left).toBe position.left - itemWidth + 'px'
expect(overlay.style.top).toBe position.top + editor.getLineHeightInPixels() + 'px'
@@ -1337,7 +1323,7 @@ describe "TextEditorComponent", ->
decoration = editor.decorateMarker(marker, {type: 'overlay', item})
nextAnimationFrame()
position = wrapperNode.pixelPositionForBufferPosition([4, 0])
position = editor.pixelPositionForBufferPosition([4, 0])
overlay = component.getTopmostDOMNode().querySelector('atom-overlay')
expect(overlay.style.left).toBe position.left + 'px'
@@ -1346,7 +1332,7 @@ describe "TextEditorComponent", ->
editor.insertNewline()
nextAnimationFrame()
position = wrapperNode.pixelPositionForBufferPosition([5, 0])
position = editor.pixelPositionForBufferPosition([5, 0])
expect(overlay.style.left).toBe position.left + 'px'
expect(overlay.style.top).toBe position.top - itemHeight + 'px'
@@ -1368,7 +1354,7 @@ describe "TextEditorComponent", ->
decoration = editor.decorateMarker(marker, {type: 'overlay', item})
nextAnimationFrame()
position = wrapperNode.pixelPositionForBufferPosition([0, 2])
position = editor.pixelPositionForBufferPosition([0, 2])
overlay = component.getTopmostDOMNode().querySelector('atom-overlay')
expect(overlay.style.left).toBe position.left + 'px'
@@ -1377,7 +1363,7 @@ describe "TextEditorComponent", ->
editor.insertText('a')
nextAnimationFrame()
position = wrapperNode.pixelPositionForBufferPosition([0, 3])
position = editor.pixelPositionForBufferPosition([0, 3])
expect(overlay.style.left).toBe position.left + 'px'
expect(overlay.style.top).toBe position.top + editor.getLineHeightInPixels() + 'px'
@@ -1387,7 +1373,7 @@ describe "TextEditorComponent", ->
decoration = editor.decorateMarker(marker, {type: 'overlay', item})
nextAnimationFrame()
position = wrapperNode.pixelPositionForBufferPosition([1, 0])
position = editor.pixelPositionForBufferPosition([1, 0])
overlay = component.getTopmostDOMNode().querySelector('atom-overlay')
expect(overlay.style.left).toBe position.left + 'px'
@@ -1396,7 +1382,7 @@ describe "TextEditorComponent", ->
editor.insertNewline()
nextAnimationFrame()
position = wrapperNode.pixelPositionForBufferPosition([2, 0])
position = editor.pixelPositionForBufferPosition([2, 0])
expect(overlay.style.left).toBe position.left + 'px'
expect(overlay.style.top).toBe position.top + editor.getLineHeightInPixels() + 'px'
@@ -1409,7 +1395,7 @@ describe "TextEditorComponent", ->
decoration = editor.decorateMarker(marker, {type: 'overlay', item})
nextAnimationFrame()
position = wrapperNode.pixelPositionForBufferPosition([0, 28])
position = editor.pixelPositionForBufferPosition([0, 28])
overlay = component.getTopmostDOMNode().querySelector('atom-overlay')
expect(overlay.style.left).toBe position.left + 'px'
@@ -1418,7 +1404,7 @@ describe "TextEditorComponent", ->
editor.insertText('a')
nextAnimationFrame()
position = wrapperNode.pixelPositionForBufferPosition([0, 29])
position = editor.pixelPositionForBufferPosition([0, 29])
expect(overlay.style.left).toBe position.left - itemWidth + 'px'
expect(overlay.style.top).toBe position.top + editor.getLineHeightInPixels() + 'px'
@@ -1429,7 +1415,7 @@ describe "TextEditorComponent", ->
decoration = editor.decorateMarker(marker, {type: 'overlay', item})
nextAnimationFrame()
position = wrapperNode.pixelPositionForBufferPosition([6, 0])
position = editor.pixelPositionForBufferPosition([6, 0])
overlay = component.getTopmostDOMNode().querySelector('atom-overlay')
expect(overlay.style.left).toBe position.left + 'px'
@@ -1438,7 +1424,7 @@ describe "TextEditorComponent", ->
editor.insertNewline()
nextAnimationFrame()
position = wrapperNode.pixelPositionForBufferPosition([7, 0])
position = editor.pixelPositionForBufferPosition([7, 0])
expect(overlay.style.left).toBe position.left + 'px'
expect(overlay.style.top).toBe position.top - itemHeight + 'px'
@@ -1626,22 +1612,6 @@ describe "TextEditorComponent", ->
expect(nextAnimationFrame).toBe noAnimationFrame
expect(editor.getSelectedScreenRange()).toEqual [[2, 4], [6, 8]]
describe "when the editor is destroyed while dragging", ->
it "cleans up the handlers for window.mouseup and window.mousemove", ->
linesNode.dispatchEvent(buildMouseEvent('mousedown', clientCoordinatesForScreenPosition([2, 4]), which: 1))
linesNode.dispatchEvent(buildMouseEvent('mousemove', clientCoordinatesForScreenPosition([6, 8]), which: 1))
nextAnimationFrame()
spyOn(window, 'removeEventListener').andCallThrough()
linesNode.dispatchEvent(buildMouseEvent('mousemove', clientCoordinatesForScreenPosition([6, 10]), which: 1))
editor.destroy()
nextAnimationFrame()
call.args.pop() for call in window.removeEventListener.calls
expect(window.removeEventListener).toHaveBeenCalledWith('mouseup')
expect(window.removeEventListener).toHaveBeenCalledWith('mousemove')
describe "when a line is folded", ->
beforeEach ->
editor.foldBufferRow 4
@@ -2062,6 +2032,8 @@ describe "TextEditorComponent", ->
expect(component.mouseWheelScreenRow).toBe null
it "clears the mouseWheelScreenRow after a delay even if the event does not cause scrolling", ->
spyOn(_._, 'now').andCallFake -> window.now # Ensure _.debounce is based on our fake spec timeline
expect(editor.getScrollTop()).toBe 0
lineNode = componentNode.querySelector('.line')
@@ -2517,8 +2489,7 @@ describe "TextEditorComponent", ->
describe "when the 'mini' property is true", ->
beforeEach ->
editor.setMini(true)
nextAnimationFrame()
component.setProps(mini: true)
it "does not render the gutter", ->
expect(componentNode.querySelector('.gutter')).toBeNull()
@@ -2606,9 +2577,9 @@ describe "TextEditorComponent", ->
describe 'soft wrap settings', ->
beforeEach ->
atom.config.set 'editor.softWrap', true, scopeSelector: '.source.coffee'
atom.config.set 'editor.preferredLineLength', 17, scopeSelector: '.source.coffee'
atom.config.set 'editor.softWrapAtPreferredLineLength', true, scopeSelector: '.source.coffee'
atom.config.set '.source.coffee', 'editor.softWrap', true
atom.config.set '.source.coffee', 'editor.preferredLineLength', 17
atom.config.set '.source.coffee', 'editor.softWrapAtPreferredLineLength', true
editor.setEditorWidthInChars(20)
coffeeEditor.setEditorWidthInChars(20)
@@ -2618,18 +2589,18 @@ describe "TextEditorComponent", ->
expect(coffeeEditor.lineTextForScreenRow(3)).toEqual ' return items '
it 'updates the wrapped lines when editor.preferredLineLength changes', ->
atom.config.set 'editor.preferredLineLength', 20, scopeSelector: '.source.coffee'
atom.config.set '.source.coffee', 'editor.preferredLineLength', 20
expect(coffeeEditor.lineTextForScreenRow(2)).toEqual ' return items if '
it 'updates the wrapped lines when editor.softWrapAtPreferredLineLength changes', ->
atom.config.set 'editor.softWrapAtPreferredLineLength', false, scopeSelector: '.source.coffee'
atom.config.set '.source.coffee', 'editor.softWrapAtPreferredLineLength', false
expect(coffeeEditor.lineTextForScreenRow(2)).toEqual ' return items if '
it 'updates the wrapped lines when editor.softWrap changes', ->
atom.config.set 'editor.softWrap', false, scopeSelector: '.source.coffee'
atom.config.set '.source.coffee', 'editor.softWrap', false
expect(coffeeEditor.lineTextForScreenRow(2)).toEqual ' return items if items.length <= 1'
atom.config.set 'editor.softWrap', true, scopeSelector: '.source.coffee'
atom.config.set '.source.coffee', 'editor.softWrap', true
expect(coffeeEditor.lineTextForScreenRow(3)).toEqual ' return items '
it 'updates the wrapped lines when the grammar changes', ->
@@ -2657,11 +2628,11 @@ describe "TextEditorComponent", ->
tab: 'F'
cr: 'E'
atom.config.set 'editor.showInvisibles', true, scopeSelector: '.source.js'
atom.config.set 'editor.invisibles', jsInvisibles, scopeSelector: '.source.js'
atom.config.set '.source.js', 'editor.showInvisibles', true
atom.config.set '.source.js', 'editor.invisibles', jsInvisibles
atom.config.set 'editor.showInvisibles', false, scopeSelector: '.source.coffee'
atom.config.set 'editor.invisibles', coffeeInvisibles, scopeSelector: '.source.coffee'
atom.config.set '.source.coffee', 'editor.showInvisibles', false
atom.config.set '.source.coffee', 'editor.invisibles', coffeeInvisibles
editor.setText " a line with tabs\tand spaces \n"
nextAnimationFrame()
@@ -2677,7 +2648,7 @@ describe "TextEditorComponent", ->
it "re-renders the invisibles when the invisible settings change", ->
jsGrammar = editor.getGrammar()
editor.setGrammar(coffeeEditor.getGrammar())
atom.config.set 'editor.showInvisibles', true, scopeSelector: '.source.coffee'
atom.config.set '.source.coffee', 'editor.showInvisibles', true
nextAnimationFrame()
expect(component.lineNodeForScreenRow(0).textContent).toBe "#{coffeeInvisibles.space}a line with tabs#{coffeeInvisibles.tab}and spaces#{coffeeInvisibles.space}#{coffeeInvisibles.eol}"
@@ -2686,7 +2657,7 @@ describe "TextEditorComponent", ->
space: 'E'
tab: 'W'
cr: 'I'
atom.config.set 'editor.invisibles', newInvisibles, scopeSelector: '.source.coffee'
atom.config.set '.source.coffee', 'editor.invisibles', newInvisibles
nextAnimationFrame()
expect(component.lineNodeForScreenRow(0).textContent).toBe "#{newInvisibles.space}a line with tabs#{newInvisibles.tab}and spaces#{newInvisibles.space}#{newInvisibles.eol}"
@@ -2696,8 +2667,8 @@ describe "TextEditorComponent", ->
describe 'editor.showIndentGuide', ->
beforeEach ->
atom.config.set 'editor.showIndentGuide', true, scopeSelector: '.source.js'
atom.config.set 'editor.showIndentGuide', false, scopeSelector: '.source.coffee'
atom.config.set '.source.js', 'editor.showIndentGuide', true
atom.config.set '.source.coffee', 'editor.showIndentGuide', false
it "has an 'indent-guide' class when scoped editor.showIndentGuide is true, but not when scoped editor.showIndentGuide is false", ->
line1LeafNodes = getLeafNodes(component.lineNodeForScreenRow(1))
@@ -2718,7 +2689,7 @@ describe "TextEditorComponent", ->
expect(line1LeafNodes[0].classList.contains('indent-guide')).toBe true
expect(line1LeafNodes[1].classList.contains('indent-guide')).toBe false
atom.config.set 'editor.showIndentGuide', false, scopeSelector: '.source.js'
atom.config.set '.source.js', 'editor.showIndentGuide', false
line1LeafNodes = getLeafNodes(component.lineNodeForScreenRow(1))
expect(line1LeafNodes[0].textContent).toBe ' '
@@ -2726,35 +2697,26 @@ describe "TextEditorComponent", ->
expect(line1LeafNodes[1].classList.contains('indent-guide')).toBe false
describe "middle mouse paste on Linux", ->
originalPlatform = null
beforeEach ->
originalPlatform = process.platform
Object.defineProperty process, 'platform', value: 'linux'
afterEach ->
Object.defineProperty process, 'platform', value: originalPlatform
it "pastes the previously selected text at the clicked location", ->
jasmine.unspy(window, 'setTimeout')
clipboardWrittenTo = false
it "pastes the previously selected text", ->
spyOn(require('ipc'), 'send').andCallFake (eventName, selectedText) ->
if eventName is 'write-text-to-selection-clipboard'
require('clipboard').writeText(selectedText, 'selection')
clipboardWrittenTo = true
atom.clipboard.write('')
component.trackSelectionClipboard()
component.listenForMiddleMousePaste()
editor.setCursorBufferPosition([10, 0])
componentNode.querySelector('.scroll-view').dispatchEvent(buildMouseEvent('mouseup', which: 2))
expect(atom.clipboard.read()).toBe ''
expect(editor.lineTextForBufferRow(10)).toBe ''
editor.setSelectedBufferRange([[1, 6], [1, 10]])
editor.setCursorBufferPosition([10, 0])
componentNode.querySelector('.scroll-view').dispatchEvent(buildMouseEvent('mouseup', which: 2))
waitsFor ->
clipboardWrittenTo
runs ->
componentNode.querySelector('.scroll-view').dispatchEvent(buildMouseEvent('mousedown', clientCoordinatesForScreenPosition([10, 0]), button: 1))
componentNode.querySelector('.scroll-view').dispatchEvent(buildMouseEvent('mouseup', clientCoordinatesForScreenPosition([10, 0]), which: 2))
expect(atom.clipboard.read()).toBe 'sort'
expect(editor.lineTextForBufferRow(10)).toBe 'sort'
expect(atom.clipboard.read()).toBe 'sort'
expect(editor.lineTextForBufferRow(10)).toBe 'sort'
buildMouseEvent = (type, properties...) ->
properties = extend({bubbles: true, cancelable: true}, properties...)
@@ -2767,14 +2729,14 @@ describe "TextEditorComponent", ->
event
clientCoordinatesForScreenPosition = (screenPosition) ->
positionOffset = wrapperNode.pixelPositionForScreenPosition(screenPosition)
positionOffset = editor.pixelPositionForScreenPosition(screenPosition)
scrollViewClientRect = componentNode.querySelector('.scroll-view').getBoundingClientRect()
clientX = scrollViewClientRect.left + positionOffset.left - editor.getScrollLeft()
clientY = scrollViewClientRect.top + positionOffset.top - editor.getScrollTop()
{clientX, clientY}
clientCoordinatesForScreenRowInGutter = (screenRow) ->
positionOffset = wrapperNode.pixelPositionForScreenPosition([screenRow, 1])
positionOffset = editor.pixelPositionForScreenPosition([screenRow, 1])
gutterClientRect = componentNode.querySelector('.gutter').getBoundingClientRect()
clientX = gutterClientRect.left + positionOffset.left - editor.getScrollLeft()
clientY = gutterClientRect.top + positionOffset.top - editor.getScrollTop()
+3 -52
Ver Arquivo
@@ -10,21 +10,16 @@ describe "TextEditorElement", ->
jasmineContent = document.body.querySelector('#jasmine-content')
describe "instantiation", ->
it "honors the 'mini' attribute", ->
it "honors the mini attribute", ->
jasmineContent.innerHTML = "<atom-text-editor mini>"
element = jasmineContent.firstChild
expect(element.getModel().isMini()).toBe true
it "honors the 'placeholder-text' attribute", ->
it "honors the placeholder-text attribute", ->
jasmineContent.innerHTML = "<atom-text-editor placeholder-text='testing'>"
element = jasmineContent.firstChild
expect(element.getModel().getPlaceholderText()).toBe 'testing'
it "honors the 'gutter-hidden' attribute", ->
jasmineContent.innerHTML = "<atom-text-editor gutter-hidden>"
element = jasmineContent.firstChild
expect(element.getModel().isGutterVisible()).toBe false
it "honors the text content", ->
jasmineContent.innerHTML = "<atom-text-editor>testing</atom-text-editor>"
element = jasmineContent.firstChild
@@ -37,34 +32,6 @@ describe "TextEditorElement", ->
element.setModel(model)
expect(element.hasAttribute('mini')).toBe true
describe "when the editor is attached to the DOM", ->
describe "when the editor.useShadowDOM config option is true", ->
it "mounts the react component and unmounts when removed from the dom", ->
atom.config.set('editor.useShadowDOM', true)
element = new TextEditorElement
jasmine.attachToDOM(element)
component = element.component
expect(component.isMounted()).toBe true
element.remove()
expect(component.isMounted()).toBe false
jasmine.attachToDOM(element)
expect(element.component.isMounted()).toBe true
describe "when the editor.useShadowDOM config option is false", ->
it "mounts the react component and unmounts when removed from the dom", ->
atom.config.set('editor.useShadowDOM', false)
element = new TextEditorElement
jasmine.attachToDOM(element)
component = element.component
expect(component.isMounted()).toBe true
element.getModel().destroy()
expect(component.isMounted()).toBe false
describe "focus and blur handling", ->
describe "when the editor.useShadowDOM config option is true", ->
it "proxies focus/blur events to/from the hidden input inside the shadow root", ->
@@ -103,22 +70,6 @@ describe "TextEditorElement", ->
document.body.focus()
expect(blurCalled).toBe true
describe "when focused while a parent node is being attached to the DOM", ->
class ElementThatFocusesChild extends HTMLDivElement
attachedCallback: ->
@firstChild.focus()
document.registerElement("element-that-focuses-child",
prototype: ElementThatFocusesChild.prototype
)
it "proxies the focus event to the hidden input", ->
element = new TextEditorElement
parentElement = document.createElement("element-that-focuses-child")
parentElement.appendChild(element)
jasmineContent.appendChild(parentElement)
expect(element.shadowRoot.activeElement).toBe element.shadowRoot.querySelector('input')
describe "when the themes finish loading", ->
[themeReloadCallback, initialThemeLoadComplete, element] = []
@@ -128,7 +79,7 @@ describe "TextEditorElement", ->
spyOn(atom.themes, 'isInitialLoadComplete').andCallFake ->
initialThemeLoadComplete
spyOn(atom.themes, 'onDidChangeActiveThemes').andCallFake (fn) ->
spyOn(atom.themes, 'onDidReloadAll').andCallFake (fn) ->
themeReloadCallback = fn
atom.config.set("editor.useShadowDOM", false)
+11 -50
Ver Arquivo
@@ -62,6 +62,7 @@ describe "TextEditor", ->
atom.workspace.open('sample.less', initialLine: 5).then (o) -> editor = o
runs ->
buffer = editor.buffer
expect(editor.getLastCursor().getBufferPosition().row).toEqual 5
expect(editor.getLastCursor().getBufferPosition().column).toEqual 0
@@ -73,37 +74,10 @@ describe "TextEditor", ->
atom.workspace.open('sample.less', initialColumn: 8).then (o) -> editor = o
runs ->
buffer = editor.buffer
expect(editor.getLastCursor().getBufferPosition().row).toEqual 0
expect(editor.getLastCursor().getBufferPosition().column).toEqual 8
describe "when the editor is reopened with an initialLine option", ->
it "positions the cursor on the specified line", ->
editor = null
waitsForPromise ->
atom.workspace.open('sample.less', initialLine: 5).then (o) -> editor = o
waitsForPromise ->
atom.workspace.open('sample.less', initialLine: 4).then (o) -> editor = o
runs ->
expect(editor.getLastCursor().getBufferPosition().row).toEqual 4
expect(editor.getLastCursor().getBufferPosition().column).toEqual 0
describe "when the editor is reopened with an initialColumn option", ->
it "positions the cursor on the specified column", ->
editor = null
waitsForPromise ->
atom.workspace.open('sample.less', initialColumn: 8).then (o) -> editor = o
waitsForPromise ->
atom.workspace.open('sample.less', initialColumn: 7).then (o) -> editor = o
runs ->
expect(editor.getLastCursor().getBufferPosition().row).toEqual 0
expect(editor.getLastCursor().getBufferPosition().column).toEqual 7
describe ".copy()", ->
it "returns a different edit session with the same initial state", ->
editor.setSelectedBufferRange([[1, 2], [3, 4]])
@@ -944,15 +918,6 @@ describe "TextEditor", ->
editor.undo()
expect(editor.getScrollTop()).toBe 0
describe '.logCursorScope()', ->
beforeEach ->
spyOn(atom.notifications, 'addInfo')
it 'opens a notification', ->
editor.logCursorScope()
expect(atom.notifications.addInfo).toHaveBeenCalled()
describe "selection", ->
selection = null
@@ -1362,7 +1327,7 @@ describe "TextEditor", ->
coffeeEditor.selectWordsContainingCursors()
expect(coffeeEditor.getSelectedBufferRange()).toEqual [[0, 6], [0, 15]]
atom.config.set 'editor.nonWordCharacters', 'qusort', scopeSelector: '.source.coffee'
atom.config.set '.source.coffee', 'editor.nonWordCharacters', 'qusort'
coffeeEditor.setCursorBufferPosition [0, 9]
coffeeEditor.selectWordsContainingCursors()
@@ -3311,7 +3276,7 @@ describe "TextEditor", ->
atom.packages.unloadPackages()
it 'returns correct values based on the scope of the set grammars', ->
atom.config.set 'editor.tabLength', 6, scopeSelector: '.source.coffee'
atom.config.set '.source.coffee', 'editor.tabLength', 6
expect(editor.getTabLength()).toBe 2
expect(coffeeEditor.getTabLength()).toBe 6
@@ -3333,12 +3298,12 @@ describe "TextEditor", ->
expect(editor.getTabLength()).toBe 2
expect(editor.tokenizedLineForScreenRow(5).tokens[0].firstNonWhitespaceIndex).toBe 2
atom.config.set 'editor.tabLength', 6, scopeSelector: '.source.js'
atom.config.set '.source.js', 'editor.tabLength', 6
expect(editor.getTabLength()).toBe 6
expect(editor.tokenizedLineForScreenRow(5).tokens[0].firstNonWhitespaceIndex).toBe 6
it 'updates the tab length when the grammar changes', ->
atom.config.set 'editor.tabLength', 6, scopeSelector: '.source.coffee'
atom.config.set '.source.coffee', 'editor.tabLength', 6
expect(editor.getTabLength()).toBe 2
expect(editor.tokenizedLineForScreenRow(5).tokens[0].firstNonWhitespaceIndex).toBe 2
@@ -3455,11 +3420,11 @@ describe "TextEditor", ->
describe "when the cursor is before whitespace", ->
it "retains the whitespace following the cursor on the new line", ->
editor.setText(" var sort = function() {}")
editor.setCursorScreenPosition([0, 12])
editor.setCursorScreenPosition([0, 23])
editor.insertNewline()
expect(buffer.lineForRow(0)).toBe ' var sort ='
expect(buffer.lineForRow(1)).toBe ' function() {}'
expect(buffer.lineForRow(0)).toBe ' var sort = function()'
expect(buffer.lineForRow(1)).toBe ' {}'
expect(editor.getCursorScreenPosition()).toEqual [1, 2]
describe "when inserted text matches a decrease indent pattern", ->
@@ -3508,8 +3473,8 @@ describe "TextEditor", ->
atom.project.open('coffee.coffee', autoIndent: false).then (o) -> coffeeEditor = o
runs ->
atom.config.set('editor.autoIndent', true, scopeSelector: '.source.js')
atom.config.set('editor.autoIndent', false, scopeSelector: '.source.coffee')
atom.config.set('.source.js', 'editor.autoIndent', true)
atom.config.set('.source.coffee', 'editor.autoIndent', false)
afterEach: ->
atom.packages.deactivatePackages()
@@ -3801,12 +3766,8 @@ describe "TextEditor", ->
it "updates the grammar based on grammar overrides", ->
expect(editor.getGrammar().name).toBe 'JavaScript'
atom.grammars.setGrammarOverrideForPath(editor.getPath(), 'source.coffee')
callback = jasmine.createSpy('callback')
editor.onDidChangeGrammar(callback)
editor.reloadGrammar()
expect(editor.getGrammar().name).toBe 'CoffeeScript'
expect(callback.callCount).toBe 1
expect(callback.argsForCall[0][0]).toBe atom.grammars.grammarForScopeName('source.coffee')
describe "when the editor's grammar has an injection selector", ->
beforeEach ->
+101 -140
Ver Arquivo
@@ -73,90 +73,65 @@ describe "ThemeManager", ->
describe "when the core.themes config value changes", ->
it "add/removes stylesheets to reflect the new config value", ->
themeManager.onDidChangeActiveThemes didChangeActiveThemesHandler = jasmine.createSpy()
themeManager.onDidReloadAll reloadHandler = jasmine.createSpy()
spyOn(atom.styles, 'getUserStyleSheetPath').andCallFake -> null
waitsForPromise ->
themeManager.activateThemes()
runs ->
didChangeActiveThemesHandler.reset()
reloadHandler.reset()
atom.config.set('core.themes', [])
waitsFor ->
didChangeActiveThemesHandler.callCount == 1
reloadHandler.callCount == 1
runs ->
didChangeActiveThemesHandler.reset()
reloadHandler.reset()
expect($('style.theme')).toHaveLength 0
atom.config.set('core.themes', ['atom-dark-ui'])
waitsFor ->
didChangeActiveThemesHandler.callCount == 1
reloadHandler.callCount == 1
runs ->
didChangeActiveThemesHandler.reset()
expect($('style[priority=1]')).toHaveLength 2
expect($('style[priority=1]:eq(0)').attr('source-path')).toMatch /atom-dark-ui/
reloadHandler.reset()
expect($('style[group=theme]')).toHaveLength 2
expect($('style[group=theme]:eq(0)').attr('source-path')).toMatch /atom-dark-ui/
atom.config.set('core.themes', ['atom-light-ui', 'atom-dark-ui'])
waitsFor ->
didChangeActiveThemesHandler.callCount == 1
reloadHandler.callCount == 1
runs ->
didChangeActiveThemesHandler.reset()
expect($('style[priority=1]')).toHaveLength 2
expect($('style[priority=1]:eq(0)').attr('source-path')).toMatch /atom-dark-ui/
expect($('style[priority=1]:eq(1)').attr('source-path')).toMatch /atom-light-ui/
reloadHandler.reset()
expect($('style[group=theme]')).toHaveLength 2
expect($('style[group=theme]:eq(0)').attr('source-path')).toMatch /atom-dark-ui/
expect($('style[group=theme]:eq(1)').attr('source-path')).toMatch /atom-light-ui/
atom.config.set('core.themes', [])
waitsFor ->
didChangeActiveThemesHandler.callCount == 1
reloadHandler.callCount == 1
runs ->
didChangeActiveThemesHandler.reset()
expect($('style[priority=1]')).toHaveLength 2
reloadHandler.reset()
expect($('style[group=theme]')).toHaveLength 2
# atom-dark-ui has an directory path, the syntax one doesn't
atom.config.set('core.themes', ['theme-with-index-less', 'atom-dark-ui'])
waitsFor ->
didChangeActiveThemesHandler.callCount == 1
reloadHandler.callCount == 1
runs ->
expect($('style[priority=1]')).toHaveLength 2
expect($('style[group=theme]')).toHaveLength 2
importPaths = themeManager.getImportPaths()
expect(importPaths.length).toBe 1
expect(importPaths[0]).toContain 'atom-dark-ui'
it 'adds theme-* classes to the workspace for each active theme', ->
workspaceElement = atom.views.getView(atom.workspace)
themeManager.onDidChangeActiveThemes didChangeActiveThemesHandler = jasmine.createSpy()
waitsForPromise ->
themeManager.activateThemes()
runs ->
expect(workspaceElement).toHaveClass 'theme-atom-dark-ui'
themeManager.onDidChangeActiveThemes didChangeActiveThemesHandler = jasmine.createSpy()
atom.config.set('core.themes', ['theme-with-ui-variables', 'theme-with-syntax-variables'])
waitsFor ->
didChangeActiveThemesHandler.callCount > 0
runs ->
# `theme-` twice as it prefixes the name with `theme-`
expect(workspaceElement).toHaveClass 'theme-theme-with-ui-variables'
expect(workspaceElement).toHaveClass 'theme-theme-with-syntax-variables'
expect(workspaceElement).not.toHaveClass 'theme-atom-dark-ui'
expect(workspaceElement).not.toHaveClass 'theme-atom-dark-syntax'
describe "when a theme fails to load", ->
it "logs a warning", ->
spyOn(console, 'warn')
atom.packages.activatePackage('a-theme-that-will-not-be-found')
expect(console.warn.callCount).toBe 1
expect(console.warn.argsForCall[0][0]).toContain "Could not resolve 'a-theme-that-will-not-be-found'"
expect(-> atom.packages.activatePackage('a-theme-that-will-not-be-found')).toThrow()
describe "::requireStylesheet(path)", ->
beforeEach ->
@@ -170,7 +145,7 @@ describe "ThemeManager", ->
themeManager.onDidChangeStylesheets stylesheetsChangedHandler = jasmine.createSpy("stylesheetsChangedHandler")
themeManager.onDidAddStylesheet stylesheetAddedHandler = jasmine.createSpy("stylesheetAddedHandler")
cssPath = atom.project.getDirectories()[0]?.resolve('css.css')
cssPath = atom.project.resolve('css.css')
lengthBefore = $('head style').length
themeManager.requireStylesheet(cssPath)
@@ -194,7 +169,7 @@ describe "ThemeManager", ->
$('head style[id*="css.css"]').remove()
it "synchronously loads and parses less files at the given path and installs a style tag for it in the head", ->
lessPath = atom.project.getDirectories()[0]?.resolve('sample.less')
lessPath = atom.project.resolve('sample.less')
lengthBefore = $('head style').length
themeManager.requireStylesheet(lessPath)
expect($('head style').length).toBe lengthBefore + 1
@@ -218,9 +193,9 @@ describe "ThemeManager", ->
it "supports requiring css and less stylesheets without an explicit extension", ->
themeManager.requireStylesheet path.join(__dirname, 'fixtures', 'css')
expect($('head style[source-path*="css.css"]').attr('source-path')).toBe themeManager.stringToId(atom.project.getDirectories()[0]?.resolve('css.css'))
expect($('head style[source-path*="css.css"]').attr('source-path')).toBe themeManager.stringToId(atom.project.resolve('css.css'))
themeManager.requireStylesheet path.join(__dirname, 'fixtures', 'sample')
expect($('head style[source-path*="sample.less"]').attr('source-path')).toBe themeManager.stringToId(atom.project.getDirectories()[0]?.resolve('sample.less'))
expect($('head style[source-path*="sample.less"]').attr('source-path')).toBe themeManager.stringToId(atom.project.resolve('sample.less'))
$('head style[id*="css.css"]').remove()
$('head style[id*="sample.less"]').remove()
@@ -248,9 +223,11 @@ describe "ThemeManager", ->
expect(stylesheetsChangedHandler).toHaveBeenCalled()
describe "base style sheet loading", ->
describe "base stylesheet loading", ->
workspaceElement = null
beforeEach ->
jasmine.snapshotDeprecations()
workspaceElement = atom.views.getView(atom.workspace)
jasmine.attachToDOM(workspaceElement)
workspaceElement.appendChild document.createElement('atom-text-editor')
@@ -258,12 +235,15 @@ describe "ThemeManager", ->
waitsForPromise ->
themeManager.activateThemes()
beforeEach ->
jasmine.restoreDeprecationsSnapshot()
it "loads the correct values from the theme's ui-variables file", ->
themeManager.onDidChangeActiveThemes didChangeActiveThemesHandler = jasmine.createSpy()
themeManager.onDidReloadAll reloadHandler = jasmine.createSpy()
atom.config.set('core.themes', ['theme-with-ui-variables', 'theme-with-syntax-variables'])
waitsFor ->
didChangeActiveThemesHandler.callCount > 0
reloadHandler.callCount > 0
runs ->
# an override loaded in the base css
@@ -276,11 +256,11 @@ describe "ThemeManager", ->
describe "when there is a theme with incomplete variables", ->
it "loads the correct values from the fallback ui-variables", ->
themeManager.onDidChangeActiveThemes didChangeActiveThemesHandler = jasmine.createSpy()
themeManager.onDidReloadAll reloadHandler = jasmine.createSpy()
atom.config.set('core.themes', ['theme-with-incomplete-ui-variables', 'theme-with-syntax-variables'])
waitsFor ->
didChangeActiveThemesHandler.callCount > 0
reloadHandler.callCount > 0
runs ->
# an override loaded in the base css
@@ -289,104 +269,85 @@ describe "ThemeManager", ->
# from within the theme itself
expect($("atom-text-editor").css("background-color")).toBe "rgb(0, 152, 255)"
describe "user stylesheet", ->
userStylesheetPath = null
describe "theme classes on the workspace", ->
it 'adds theme-* classes to the workspace for each active theme', ->
expect(workspaceElement).toHaveClass 'theme-atom-dark-ui'
themeManager.onDidReloadAll reloadHandler = jasmine.createSpy()
atom.config.set('core.themes', ['theme-with-ui-variables', 'theme-with-syntax-variables'])
waitsFor ->
reloadHandler.callCount > 0
runs ->
# `theme-` twice as it prefixes the name with `theme-`
expect(workspaceElement).toHaveClass 'theme-theme-with-ui-variables'
expect(workspaceElement).toHaveClass 'theme-theme-with-syntax-variables'
expect(workspaceElement).not.toHaveClass 'theme-atom-dark-ui'
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;}')
spyOn(atom.styles, 'getUserStyleSheetPath').andReturn userStylesheetPath
describe "when the user stylesheet changes", ->
beforeEach ->
jasmine.snapshotDeprecations()
waitsForPromise ->
themeManager.activateThemes()
afterEach ->
jasmine.restoreDeprecationsSnapshot()
runs ->
atom.styles.onDidRemoveStyleElement styleElementRemovedHandler = jasmine.createSpy("styleElementRemovedHandler")
atom.styles.onDidAddStyleElement styleElementAddedHandler = jasmine.createSpy("styleElementAddedHandler")
it "reloads it", ->
[styleElementAddedHandler, styleElementRemovedHandler] = []
[stylesheetRemovedHandler, stylesheetAddedHandler, stylesheetsChangedHandler] = []
themeManager.onDidChangeStylesheets stylesheetsChangedHandler = jasmine.createSpy("stylesheetsChangedHandler")
themeManager.onDidRemoveStylesheet stylesheetRemovedHandler = jasmine.createSpy("stylesheetRemovedHandler")
themeManager.onDidAddStylesheet stylesheetAddedHandler = jasmine.createSpy("stylesheetAddedHandler")
spyOn(themeManager, 'loadUserStylesheet').andCallThrough()
waitsForPromise ->
themeManager.activateThemes()
expect($(document.body).css('border-style')).toBe 'dotted'
fs.writeFileSync(userStylesheetPath, 'body {border-style: dashed}')
runs ->
atom.styles.onDidRemoveStyleElement styleElementRemovedHandler = jasmine.createSpy("styleElementRemovedHandler")
atom.styles.onDidAddStyleElement styleElementAddedHandler = jasmine.createSpy("styleElementAddedHandler")
waitsFor ->
themeManager.loadUserStylesheet.callCount is 1
themeManager.onDidChangeStylesheets stylesheetsChangedHandler = jasmine.createSpy("stylesheetsChangedHandler")
themeManager.onDidRemoveStylesheet stylesheetRemovedHandler = jasmine.createSpy("stylesheetRemovedHandler")
themeManager.onDidAddStylesheet stylesheetAddedHandler = jasmine.createSpy("stylesheetAddedHandler")
spyOn(themeManager, 'loadUserStylesheet').andCallThrough()
runs ->
expect($(document.body).css('border-style')).toBe 'dashed'
expect($(document.body).css('border-style')).toBe 'dotted'
fs.writeFileSync(userStylesheetPath, 'body {border-style: 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'
waitsFor ->
themeManager.loadUserStylesheet.callCount is 1
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'
runs ->
expect($(document.body).css('border-style')).toBe 'dashed'
expect(stylesheetsChangedHandler).toHaveBeenCalled()
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'
styleElementRemovedHandler.reset()
stylesheetRemovedHandler.reset()
stylesheetsChangedHandler.reset()
fs.removeSync(userStylesheetPath)
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'
waitsFor ->
themeManager.loadUserStylesheet.callCount is 2
expect(stylesheetsChangedHandler).toHaveBeenCalled()
styleElementRemovedHandler.reset()
stylesheetRemovedHandler.reset()
stylesheetsChangedHandler.reset()
fs.removeSync(userStylesheetPath)
waitsFor ->
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'
expect(stylesheetsChangedHandler).toHaveBeenCalled()
describe "when there is an error reading the stylesheet", ->
addErrorHandler = null
beforeEach ->
themeManager.loadUserStylesheet()
spyOn(themeManager.lessCache, 'cssForFile').andCallFake ->
throw new Error('EACCES permission denied "styles.less"')
atom.notifications.onDidAddNotification addErrorHandler = jasmine.createSpy()
it "creates an error notification", ->
themeManager.loadUserStylesheet()
expect(addErrorHandler).toHaveBeenCalled()
note = addErrorHandler.mostRecentCall.args[0]
expect(note.getType()).toBe 'error'
expect(note.getMessage()).toContain 'Error loading'
describe "when there is an error watching the user stylesheet", ->
addErrorHandler = null
beforeEach ->
{File} = require 'pathwatcher'
spyOn(File::, 'on').andCallFake (event) ->
if event.indexOf('contents-changed') > -1
throw new Error('Unable to watch path')
spyOn(themeManager, 'loadStylesheet').andReturn ''
atom.notifications.onDidAddNotification addErrorHandler = jasmine.createSpy()
it "creates an error notification", ->
themeManager.loadUserStylesheet()
expect(addErrorHandler).toHaveBeenCalled()
note = addErrorHandler.mostRecentCall.args[0]
expect(note.getType()).toBe 'error'
expect(note.getMessage()).toContain 'Unable to watch path'
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'
expect(stylesheetsChangedHandler).toHaveBeenCalled()
describe "when a non-existent theme is present in the config", ->
beforeEach ->
@@ -397,7 +358,7 @@ describe "ThemeManager", ->
themeManager.activateThemes()
it 'uses the default dark UI and syntax themes and logs a warning', ->
activeThemeNames = themeManager.getActiveThemeNames()
activeThemeNames = themeManager.getActiveNames()
expect(console.warn.callCount).toBe 2
expect(activeThemeNames.length).toBe(2)
expect(activeThemeNames).toContain('atom-dark-ui')
@@ -415,7 +376,7 @@ describe "ThemeManager", ->
themeManager.activateThemes()
it 'uses the enabled themes', ->
activeThemeNames = themeManager.getActiveThemeNames()
activeThemeNames = themeManager.getActiveNames()
expect(activeThemeNames.length).toBe(2)
expect(activeThemeNames).toContain('atom-light-ui')
expect(activeThemeNames).toContain('atom-dark-syntax')
@@ -428,7 +389,7 @@ describe "ThemeManager", ->
themeManager.activateThemes()
it 'uses the default dark UI and syntax themes', ->
activeThemeNames = themeManager.getActiveThemeNames()
activeThemeNames = themeManager.getActiveNames()
expect(activeThemeNames.length).toBe(2)
expect(activeThemeNames).toContain('atom-dark-ui')
expect(activeThemeNames).toContain('atom-dark-syntax')
@@ -441,7 +402,7 @@ describe "ThemeManager", ->
themeManager.activateThemes()
it 'uses the default dark UI theme', ->
activeThemeNames = themeManager.getActiveThemeNames()
activeThemeNames = themeManager.getActiveNames()
expect(activeThemeNames.length).toBe(2)
expect(activeThemeNames).toContain('atom-dark-ui')
expect(activeThemeNames).toContain('atom-light-syntax')
@@ -454,7 +415,7 @@ describe "ThemeManager", ->
themeManager.activateThemes()
it 'uses the default dark syntax theme', ->
activeThemeNames = themeManager.getActiveThemeNames()
activeThemeNames = themeManager.getActiveNames()
expect(activeThemeNames.length).toBe(2)
expect(activeThemeNames).toContain('atom-light-ui')
expect(activeThemeNames).toContain('atom-dark-syntax')
+3 -3
Ver Arquivo
@@ -14,14 +14,14 @@ describe "ViewRegistry", ->
expect(registry.getView(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", ->
it "returns the root node of the view with a __spacePenView property pointing at the SpacePen view", ->
class TestView extends View
@content: -> @div "Hello"
view = new TestView
node = registry.getView(view)
expect(node.textContent).toBe "Hello"
expect(node.spacePenView).toBe view
expect(node.__spacePenView).toBe view
describe "when passed a model object", ->
describe "when a view provider is registered matching the object's constructor", ->
@@ -62,7 +62,7 @@ describe "ViewRegistry", ->
node = registry.getView(model)
expect(node.textContent).toBe "hello"
view = node.spacePenView
view = node.__spacePenView
expect(view instanceof TestView).toBe true
expect(view.model).toBe model
-8
Ver Arquivo
@@ -169,14 +169,6 @@ describe "Window", ->
$("<a href='#scroll-me'>link</a>").appendTo(document.body).click().remove()
expect(shell.openExternal).not.toHaveBeenCalled()
describe "when a form is submitted", ->
it "prevents the default so that the window's URL isn't changed", ->
submitSpy = jasmine.createSpy('submit')
$(document).on('submit', 'form', submitSpy)
$("<form>foo</form>").appendTo(document.body).submit().remove()
expect(submitSpy.callCount).toBe 1
expect(submitSpy.argsForCall[0][0].isDefaultPrevented()).toBe true
describe "core:focus-next and core:focus-previous", ->
describe "when there is no currently focused element", ->
it "focuses the element with the lowest/highest tabindex", ->

Alguns arquivos não foram exibidos porque demasiados arquivos foram alterados neste diff Mostrar Mais