Comparar commits

..

5 Commits

Autor SHA1 Mensagem Data
Ben Ogle 6cd1029253 Fix casing on polymer modules 2014-10-30 13:58:09 -07:00
Ben Ogle 4356d86214 Add polymer-expressions 2014-10-30 13:58:09 -07:00
Ben Ogle f8820c53fa Add all polymer projects into the global space 2014-10-30 13:58:09 -07:00
Ben Ogle 00ed26e8ab Move requiring of html-require into atom.coffee 2014-10-30 13:58:09 -07:00
Ben Ogle dfcce37a0a Add HTMLRequire 2014-10-30 13:58:08 -07:00
149 arquivos alterados com 2020 adições e 4213 exclusões
+1 -1
Ver Arquivo
@@ -6,6 +6,6 @@
"url": "https://github.com/atom/atom.git"
},
"dependencies": {
"atom-package-manager": "0.111.0"
"atom-package-manager": "0.109.0"
}
}
+1 -1
Ver Arquivo
@@ -63,7 +63,7 @@ if [ $OS == 'Mac' ]; then
"$ATOM_PATH/$ATOM_APP_NAME/Contents/MacOS/Atom" --executed-from="$(pwd)" --pid=$$ "$@"
exit $?
else
open -a "$ATOM_PATH/$ATOM_APP_NAME" -n --args --executed-from="$(pwd)" --pid=$$ --path-environment="$PATH" "$@"
open -a "$ATOM_PATH/$ATOM_APP_NAME" -n --args --executed-from="$(pwd)" --pid=$$ "$@"
fi
elif [ $OS == 'Linux' ]; then
SCRIPT=$(readlink -f "$0")
+22 -9
Ver Arquivo
@@ -6,6 +6,7 @@ os = require 'os'
# modules work under node v0.11.x.
require 'vm-compatibility-layer'
fm = require 'json-front-matter'
_ = require 'underscore-plus'
packageJson = require '../package.json'
@@ -21,9 +22,9 @@ module.exports = (grunt) ->
grunt.loadNpmTasks('grunt-contrib-csslint')
grunt.loadNpmTasks('grunt-contrib-coffee')
grunt.loadNpmTasks('grunt-contrib-less')
grunt.loadNpmTasks('grunt-markdown')
grunt.loadNpmTasks('grunt-shell')
grunt.loadNpmTasks('grunt-download-atom-shell')
grunt.loadNpmTasks('grunt-atom-shell-installer')
grunt.loadNpmTasks('grunt-peg')
grunt.loadTasks('tasks')
@@ -193,19 +194,32 @@ module.exports = (grunt) ->
'static/**/*.less'
]
markdown:
guides:
files: [
expand: true
cwd: 'docs'
src: '**/*.md'
dest: 'docs/output/'
ext: '.html'
]
options:
template: 'docs/template.jst'
templateContext:
tag: "v#{major}.#{minor}"
markdownOptions:
gfm: true
preCompile: (src, context) ->
parsed = fm.parse(src)
_.extend(context, parsed.attributes)
parsed.body
'download-atom-shell':
version: packageJson.atomShellVersion
outputDir: 'atom-shell'
downloadDir: atomShellDownloadDir
rebuild: true # rebuild native modules after atom-shell is updated
'create-windows-installer':
appDirectory: shellAppDir
outputDirectory: path.join(buildDir, 'installer')
authors: 'GitHub Inc.'
loadingGif: path.resolve(__dirname, '..', 'resources', 'win', 'loading.gif')
iconUrl: 'https://raw.githubusercontent.com/atom/atom/master/resources/win/atom.ico'
shell:
'kill-atom':
command: killCommand
@@ -223,7 +237,6 @@ module.exports = (grunt) ->
ciTasks.push('dump-symbols') if process.platform isnt 'win32'
ciTasks.push('set-version', 'check-licenses', 'lint')
ciTasks.push('mkdeb') if process.platform is 'linux'
ciTasks.push('create-windows-installer') if process.platform is 'win32'
ciTasks.push('test') if process.platform is 'darwin'
ciTasks.push('codesign')
ciTasks.push('publish-build')
+7 -4
Ver Arquivo
@@ -7,12 +7,11 @@
},
"dependencies": {
"async": "~0.2.9",
"donna": "1.0.7",
"donna": "1.0.6",
"formidable": "~1.0.14",
"fs-plus": "2.x",
"github-releases": "~0.2.0",
"grunt": "~0.4.1",
"grunt-atom-shell-installer": "^0.10.0",
"grunt-cli": "~0.1.9",
"grunt-coffeelint": "git+https://github.com/atom/grunt-coffeelint.git#cfb99aa99811d52687969532bd5a98011ed95bfe",
"grunt-contrib-coffee": "~0.9.0",
@@ -21,13 +20,17 @@
"grunt-cson": "0.10.0",
"grunt-download-atom-shell": "~0.10.0",
"grunt-lesslint": "0.13.0",
"grunt-markdown": "~0.4.0",
"grunt-peg": "~1.1.0",
"grunt-shell": "~0.3.1",
"harmony-collections": "~0.3.8",
"legal-eagle": "~0.6.0",
"json-front-matter": "~0.1.3",
"legal-eagle": "~0.4.0",
"minidump": "~0.8",
"normalize-package-data": "0.2.12",
"npm": "~1.4.5",
"rcedit": "~0.3.0",
"rcedit": "~0.1.2",
"read-package-json": "1.1.8",
"request": "~2.27.0",
"rimraf": "~2.2.2",
"runas": "~1.0.1",
-1
Ver Arquivo
@@ -11,7 +11,6 @@ module.exports = (grunt) ->
appDir = grunt.config.get('atom.appDir')
rm shellAppDir
rm path.join(buildDir, 'installer')
mkdir path.dirname(buildDir)
if process.platform is 'darwin'
+2 -1
Ver Arquivo
@@ -1,3 +1,4 @@
module.exports = (grunt) ->
grunt.registerTask 'check-licenses', 'Report the licenses of all dependencies', ->
legalEagle = require 'legal-eagle'
@@ -12,7 +13,7 @@ module.exports = (grunt) ->
legalEagle options, (err, summary) ->
if err?
console.error(err)
process.exit 1
exit 1
for key of summary
delete summary[key] if key.match /^atom@/
+1 -1
Ver Arquivo
@@ -36,7 +36,7 @@ module.exports = (grunt) ->
spawn {cmd, args}, (error) ->
return callback(error) if error?
setupExePath = path.resolve(grunt.config.get('atom.buildDir'), 'installer', 'AtomSetup.exe')
setupExePath = path.join(grunt.config.get('atom.shellAppDir'), '..', 'Releases', 'setup.exe')
if fs.isFileSync(setupExePath)
args = [setupExePath]
spawn {cmd, args}, (error) -> callback(error)
+46
Ver Arquivo
@@ -0,0 +1,46 @@
fs = require 'fs'
path = require 'path'
_ = require 'underscore-plus'
module.exports = (grunt) ->
{spawn, rm} = require('./task-helpers')(grunt)
grunt.registerTask 'create-installer', 'Create the Windows installer', ->
return unless process.platform is 'win32'
done = @async()
buildDir = grunt.config.get('atom.buildDir')
atomDir = path.join(buildDir, 'Atom')
releasesDir = path.join(buildDir, 'Releases')
atomGitHubToken = process.env.ATOM_ACCESS_TOKEN
packageInfo = grunt.file.readJSON(path.join(atomDir, 'resources', 'app', 'package.json'))
inputTemplate = grunt.file.read(path.join('build', 'windows', 'atom.nuspec.erb'))
# NB: Build server has some sort of stamp on the version number
packageInfo.version = packageInfo.version.replace(/-.*$/, '')
targetNuspecPath = path.join(buildDir, 'atom.nuspec')
grunt.file.write(targetNuspecPath, _.template(inputTemplate, packageInfo))
# We use the previous releases to build deltas for the current release,
# sync down the existing releases directory by rolling through GitHub releases
cmd = 'build/windows/SyncGitHubReleases.exe'
args = ['-r', releasesDir, '-u', 'https://github.com/atom/atom', '-t', atomGitHubToken]
spawn {cmd, args}, (error, result, code) ->
if error?
grunt.log.error "ATOM_ACCESS_TOKEN environment variable not set or invalid, can't download old releases; continuing anyways"
cmd = 'build/windows/nuget.exe'
args = ['pack', targetNuspecPath, '-BasePath', atomDir, '-OutputDirectory', buildDir]
spawn {cmd, args}, (error, result, code) ->
return done(error) if error?
pkgs = pkg for pkg in fs.readdirSync(buildDir) when path.extname(pkg) is '.nupkg'
cmd = 'build/windows/update.com'
args = ['--releasify', path.join(buildDir, pkgs), '-r', releasesDir, '-g', 'build/windows/install-spinner.gif']
spawn {cmd, args}, (error, result, code) -> done(error)
-5
Ver Arquivo
@@ -6,17 +6,12 @@ _ = require 'underscore-plus'
donna = require 'donna'
tello = require 'tello'
moduleBlacklist = [
'space-pen'
]
module.exports = (grunt) ->
getClassesToInclude = ->
modulesPath = path.resolve(__dirname, '..', '..', 'node_modules')
classes = {}
fs.traverseTreeSync modulesPath, (modulePath) ->
return false if modulePath.match(/node_modules/g).length > 1 # dont need the dependencies of the dependencies
return false if path.basename(modulePath) in moduleBlacklist
return true unless path.basename(modulePath) is 'package.json'
return true unless fs.isFileSync(modulePath)
+10 -26
Ver Arquivo
@@ -54,11 +54,6 @@ module.exports = (gruntObject) ->
uploadAssets(release, buildDir, assets, done)
getAssets = ->
{cp} = require('./task-helpers')(grunt)
{version} = grunt.file.readJSON('package.json')
buildDir = grunt.config.get('atom.buildDir')
switch process.platform
when 'darwin'
[
@@ -67,16 +62,16 @@ getAssets = ->
{assetName: 'atom-api.json', sourcePath: 'atom-api.json'}
]
when 'win32'
assets = [{assetName: 'atom-windows.zip', sourcePath: 'Atom'}]
for squirrelAsset in ['AtomSetup.exe', 'RELEASES', "atom-#{version}-full.nupkg"]
cp path.join(buildDir, 'installer', squirrelAsset), path.join(buildDir, squirrelAsset)
assets.push({assetName: squirrelAsset, sourcePath: assetName})
assets
[
{assetName: 'atom-windows.zip', sourcePath: 'Atom'}
]
when 'linux'
buildDir = grunt.config.get('atom.buildDir')
if process.arch is 'ia32'
arch = 'i386'
else
arch = 'amd64'
{version} = grunt.file.readJSON('package.json')
# Check for a Debian build
sourcePath = "#{buildDir}/atom-#{version}-#{arch}.deb"
@@ -92,6 +87,7 @@ getAssets = ->
arch = 'x86_64'
assetName = "atom.#{arch}.rpm"
{cp} = require('./task-helpers')(grunt)
cp sourcePath, path.join(buildDir, assetName)
[
@@ -127,22 +123,10 @@ getAtomDraftRelease = (callback) ->
logError('Fetching atom/atom releases failed', error, releases)
callback(error)
else
[firstDraft] = releases.filter ({draft}) -> draft
if firstDraft?
options =
uri: firstDraft.assets_url
method: 'GET'
headers: defaultHeaders
json: true
request options, (error, response, assets=[]) ->
if error? or response.statusCode isnt 200
logError('Fetching draft release assets failed', error, assets)
callback(error ? new Error(response.statusCode))
else
firstDraft.assets = assets
callback(null, firstDraft)
else
callback(new Error('No draft release in atom/atom repo'))
for release in releases when release.draft
callback(null, release)
return
callback(new Error('No draft release in atom/atom repo'))
deleteRelease = (release) ->
options =
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
+32
Ver Arquivo
@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id><%= name %></id>
<version><%= version %></version>
<authors>The Atom Community</authors>
<owners>The Atom Community</owners>
<iconUrl>https://raw.githubusercontent.com/atom/atom/master/resources/win/atom.ico</iconUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description><%= description %></description>
</metadata>
<files>
<file src="locales\**" target="lib\net45\locales" />
<file src="resources\**" target="lib\net45\resources" />
<file src="*.pak" target="lib\net45" />
<file src="atom.exe" target="lib\net45\atom.exe" />
<file src="atom.exe.gui" target="lib\net45\atom.exe.gui" />
<file src="chromiumcontent.dll" target="lib\net45\chromiumcontent.dll" />
<file src="d3dcompiler_43.dll" target="lib\net45\d3dcompiler_43.dll" />
<file src="ffmpegsumo.dll" target="lib\net45\ffmpegsumo.dll" />
<file src="icudtl.dat" target="lib\net45\icudtl.dat" />
<file src="libEGL.dll" target="lib\net45\libEGL.dll" />
<file src="libGLESv2.dll" target="lib\net45\libGLESv2.dll" />
<file src="LICENSE" target="lib\net45\LICENSE" />
<file src="msvcp120.dll" target="lib\net45\msvcp120.dll" />
<file src="msvcr120.dll" target="lib\net45\msvcr120.dll" />
<file src="vccorlib120.dll" target="lib\net45\vccorlib120.dll" />
<file src="version" target="lib\net45\version" />
<file src="xinput1_3.dll" target="lib\net45\xinput1_3.dll" />
</files>
</package>
Arquivo binário não exibido.

Depois

Largura:  |  Altura:  |  Tamanho: 43 KiB

+57 -2
Ver Arquivo
@@ -1,5 +1,60 @@
# Welcome to the Atom Docs
# Welcome to the Atom API Documentation
![Atom](https://cloud.githubusercontent.com/assets/72919/2874231/3af1db48-d3dd-11e3-98dc-6066f8bc766f.png)
TODO: Write when docs move to a dedicated repo.
## FAQ
### Where do I start?
Check out [EditorView][EditorView] and [Editor][Editor] classes for a good
overview of the main editor API.
### How do I access these classes?
Check out the [Atom][Atom] class docs to see what globals are available and
what they provide.
You can also require many of these classes in your package via:
```coffee
{EditorView} = require 'atom'
```
The classes available from `require 'atom'` are:
* [BufferedProcess][BufferedProcess]
* [BufferedNodeProcess][BufferedNodeProcess]
* [EditorView][EditorView]
* [Git][Git]
* [Point][Point]
* [Range][Range]
* [ScrollView][ScrollView]
* [SelectListView][SelectListView]
* [View][View]
* [WorkspaceView][WorkspaceView]
* [Workspace][Workspace]
### How do I create a package?
You probably want to read the [creating a package][creating-a-package]
doc first and come back here when you are done.
### Where are the node docs?
Atom ships with node 0.11.10 and the comprehensive node API docs are available
[here][node-docs].
[Atom]: ../classes/Atom.html
[BufferedProcess]: ../classes/BufferedProcess.html
[BufferedNodeProcess]: ../classes/BufferedNodeProcess.html
[Editor]: ../classes/Editor.html
[EditorView]: ../classes/EditorView.html
[Git]: ../classes/Git.html
[Point]: ../classes/Point.html
[Range]: ../classes/Range.html
[ScrollView]: ../classes/ScrollView.html
[SelectListView]: ../classes/SelectListView.html
[View]: ../classes/View.html
[WorkspaceView]: ../classes/WorkspaceView.html
[Workspace]: ../classes/Workspace.html
[creating-a-package]: https://atom.io/docs/latest/creating-a-package
[node-docs]: http://nodejs.org/docs/v0.11.10/api
+24 -25
Ver Arquivo
@@ -11,34 +11,32 @@ value of a namespaced config key with `atom.config.get`:
@showInvisibles() if atom.config.get "editor.showInvisibles"
```
Or you can subscribe via `atom.config.observe` to track changes from any view
object.
Or you can use the `::subscribe` with `atom.config.observe` to track changes
from any view object.
```coffeescript
{View} = require 'space-pen'
class MyView extends View
attached: ->
@fontSizeObserveSubscription =
atom.config.observe 'editor.fontSize', (newValue, {previous}) =>
@adjustFontSize()
detached: ->
@fontSizeObserveSubscription.dispose()
initialize: ->
@subscribe atom.config.observe 'editor.fontSize', (newValue, {previous}) =>
@adjustFontSize()
```
The `atom.config.observe` method will call the given callback immediately with
the current value for the specified key path, and it will also call it in the
future whenever the value of that key path changes. If you only want to invoke
the callback when the next time the value changes, use `atom.config.onDidChange`
instead.
future whenever the value of that key path changes.
Subscription methods return *disposable* subscription objects. Note in the
example above how we save the subscription to the `@fontSizeObserveSubscription`
instance variable and dispose of it when the view is detached. To group multiple
subscriptions together, you can add them all to a
[`CompositeDisposable`][composite-disposable] that you dispose when the view is
detached.
Subscriptions made with `::subscribe` are automatically canceled when the
view is removed. You can cancel config subscriptions manually via the
`off` method on the subscription object that `atom.config.observe` returns.
```coffeescript
fontSizeSubscription = atom.config.observe 'editor.fontSize', (newValue, {previous}) =>
@adjustFontSize()
# ... later on
fontSizeSubscription.off() # Stop observing
```
### Writing Config Settings
@@ -50,9 +48,10 @@ but you can programmatically write to it with `atom.config.set`:
atom.config.set("core.showInvisibles", true)
```
If you're exposing package configuration via specific key paths, you'll want to
associate them with a schema in your package's main module. Read more about
schemas in the [config API docs][config-api].
You can also use `setDefaults`, which will assign default values for keys that
are always overridden by values assigned with `set`. Defaults are not written
out to the the `config.json` file to prevent it from becoming cluttered.
[composite-disposable]: https://atom.io/docs/api/latest/CompositeDisposable
[config-api]: https://atom.io/docs/api/latest/Config
```coffeescript
atom.config.setDefaults("editor", fontSize: 18, showInvisibles: true)
```
+34
Ver Arquivo
@@ -0,0 +1,34 @@
# Globals
Atom exposes several services through singleton objects accessible via the
`atom` global:
* atom
* workspace:
Manipulate and query the state of the user interface for the current
window. Open editors, manipulate panes.
* workspaceView:
Similar to workspace, but provides access to the root of all views in the
current window.
* project:
Access the directory associated with the current window. Load editors,
perform project-wide searches, register custom openers for special file
types.
* config:
Read, write, and observe user configuration settings.
* keymap:
Add and query the currently active keybindings.
* deserializers:
Deserialize instances from their state objects and register deserializers.
* packages:
Activate, deactivate, and query user packages.
* themes:
Activate, deactivate, and query user themes.
* contextMenu:
Register context menus.
* menu:
Register application menus.
* pasteboard:
Read from and write to the system pasteboard.
* syntax:
Assign and query syntactically-scoped properties.
+3 -3
Ver Arquivo
@@ -16,7 +16,7 @@ keystrokes pass through `atom-text-editor` elements:
'ctrl-shift-e': 'editor:select-to-end-of-line'
'cmd-left': 'editor:move-to-first-character-of-line'
'atom-text-editor:not([mini])'
'atom-text-editor:not(.mini)'
'cmd-alt-[': 'editor:fold-current-row'
'cmd-alt-]': 'editor:unfold-current-row'
```
@@ -27,8 +27,8 @@ patterns* to *commands*. When an element with the `atom-text-editor` class is fo
`editor:delete-to-beginning-of-line` is emitted on the `atom-text-editor` element.
The second selector group also targets editors, but only if they don't have the
`mini` attribute. In this example, the commands for code folding don't really
make sense on mini-editors, so the selector restricts them to regular editors.
`.mini` class. In this example, the commands for code folding don't really make
sense on mini-editors, so the selector restricts them to regular editors.
### Keystroke Patterns
+58
Ver Arquivo
@@ -0,0 +1,58 @@
## Atom's View System
### SpacePen Basics
Atom's view system is built around the [SpacePen] view framework. SpacePen
view objects inherit from the jQuery prototype, and wrap DOM nodes
View objects are actually jQuery wrappers around DOM fragments, supporting all
the typical jQuery traversal and manipulation methods. In addition, view objects
have methods that are view-specific. For example, you could call both general
and view-specific on the global `atom.workspaceView` instance:
```coffeescript
atom.workspaceView.find('atom-text-editor.active') # standard jQuery method
atom.workspaceView.getActiveEditor() # view-specific method
```
If you retrieve a jQuery wrapper for an element associated with a view, use the
`.view()` method to retrieve the element's view object:
```coffeescript
# this is a plain jQuery object; you can't call view-specific methods
editorElement = atom.workspaceView.find('atom-text-editor.active')
# get the view object by calling `.view()` to call view-specific methods
editorView = editorElement.view()
editorView.setCursorBufferPosition([1, 2])
```
Refer to the [SpacePen] documentation for more details.
### WorkspaceView
The root of Atom's view hierarchy is a global called `atom.workspaceView`, which is a
singleton instance of the `WorkspaceView` view class. The root view fills the entire
window, and contains every other view. If you open Atom's inspector with
`alt-cmd-i`, you can see the internal structure of `WorkspaceView`:
![WorkspaceView in the inspector][workspaceview-inspector]
#### Panes
The `WorkspaceView` contains `prependToBottom/Top/Left/Right` and
`appendToBottom/Top/Left/Right` methods, which are used to add Tool Panels. Tool
panels are elements that take up screen real estate not devoted to text editing.
In the example above, the `TreeView` is appended to the left, and the
`CommandPanel` is appended to the top.
```coffeescript
# place a view to the left of the panes
atom.workspaceView.appendToLeft(new MyView)
# place a view below the panes
atom.workspaceView.appendToBottom(new MyOtherView)
```
[spacepen]: http://github.com/nathansobo/space-pen
[workspaceView-inspector]: https://f.cloud.github.com/assets/1424/1091631/1932c2d6-166b-11e3-8adf-9690fe82d3b8.png
-16
Ver Arquivo
@@ -30,8 +30,6 @@ All requests that take parameters require `application/json`.
Parameters:
- **page** (optional)
- **sort** (optional, values: `created_at`, `updated_at`, `downloads`)
- **direction** (optional, values: `asc`, `desc`)
Returns a list of all packages in the following format:
```json
@@ -59,20 +57,6 @@ Link: <https://www.atom.io/api/packages?page=1>; rel="self",
<https://www.atom.io/api/packages?page=2>; rel="next"
```
By default, results are sorted by download count, descending.
#### GET /api/packages/search
Parameters:
- **q** String query to search
- **sort** (optional, values: `created_at`, `updated_at`, `downloads`)
- **direction** (optional, values: `asc`, `desc`)
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
#### GET /api/packages/:package_name
+1 -1
Ver Arquivo
@@ -43,7 +43,7 @@ If you have problems with permissions don't forget to prefix with `sudo`
2. Checkout the latest Atom release:
```sh
git fetch -p
git fetch
git checkout $(git describe --tags `git rev-list --tags --max-count=1`)
```
+20 -21
Ver Arquivo
@@ -40,7 +40,7 @@ package.json files have their own additions.
- `main` (**Required**): the path to the CoffeeScript file that's the entry point
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
stylesheets your package needs to load. If not specified, stylesheets in the
_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
@@ -119,27 +119,27 @@ Also, please collaborate with us if you need an API that doesn't exist. Our goal
is to build out Atom's API organically based on the needs of package authors
like you.
## Style Sheets
## Stylesheets
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).
Stylesheets for your package should be placed in the _stylesheets_ directory.
Any stylesheets in this directory will be loaded and attached to the DOM when
your package is activated. Stylesheets 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
that fits into Atom seamlessly. You can view all of Atom's UI components by
opening the styleguide: open the command palette (`cmd-shift-P`) and search for
_styleguide_, or just type `cmd-ctrl-shift-G`.
that fits into Atom seamlessly. You can view all of Atom's UI components by opening
the styleguide: open the command palette (`cmd-shift-P`) and search for _styleguide_,
or just type `cmd-ctrl-shift-G`.
If you _do_ need special styling, try to keep only structural styles in the
package style sheets. If you _must_ specify colors and sizing, these should be
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!
If you _do_ need special styling, try to keep only structural styles in the package
stylesheets. If you _must_ specify colors and sizing, these should be 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
by name to specify a loading order; otherwise, style sheets are loaded
An optional `stylesheets` array in your _package.json_ can list the stylesheets
by name to specify a loading order; otherwise, stylesheets are loaded
alphabetically.
## Keymaps
@@ -157,9 +157,9 @@ loaded in alphabetical order. An optional `keymaps` array in your _package.json_
can specify which keymaps to load and in what order.
Keybindings are executed by determining which element the keypress occurred on.
In the example above, `changer:magic` command is executed when pressing `ctrl-V`
on the `.tree-view-scroller` element.
Keybindings are executed by determining which element the keypress occurred on. In
the example above, `changer:magic` command is executed when pressing `ctrl-V` on
the `.tree-view-scroller` element.
See the [main keymaps documentation][keymaps] for more detailed information on
how keymaps work.
@@ -195,8 +195,7 @@ with your package that aren't tied to a specific element:
```
To add your own item to the application menu, simply create a top level `menu`
key in any menu configuration file in _menus_. This can be a JSON or [CSON]
file.
key in any menu configuration file in _menus_. This can be a JSON or [CSON] file.
The menu templates you specify are merged with all other templates provided
by other packages in the order which they were loaded.
+2 -1
Ver Arquivo
@@ -63,7 +63,7 @@ built-in keymaps:
'atom-text-editor':
'enter': 'editor:newline'
'atom-text-editor[mini] input':
'atom-text-editor.mini input':
'enter': 'core:confirm'
```
@@ -118,6 +118,7 @@ You can open this file in an editor from the _Atom > Open Your Config_ menu.
- `cr`: Carriage return (for Microsoft-style line endings)
- `eol`: `\n` characters
- `space`: Leading and trailing space characters
- `normalizeIndentOnPaste`: Enable/disable conversion of pasted tabs to spaces
- `preferredLineLength`: Identifies the length of a line (defaults to `80`)
- `showInvisibles`: Whether to render placeholders for invisible characters (defaults to `false`)
- `showIndentGuide`: Show/hide indent indicators within the editor
+1 -5
Ver Arquivo
@@ -18,9 +18,5 @@
* [Developing Node Modules](advanced/node-modules.md)
* [Keymaps](advanced/keymaps.md)
* [Serialization](advanced/serialization.md)
* [View System](advanced/view-system.md)
* [Scopes and Scope Descriptors](advanced/scopes-and-scope-descriptors.md)
### Upgrading to 1.0 APIs
* [Upgrading Your UI Theme Or Package Selectors](upgrading/upgrading-your-ui-theme.md)
* [Upgrading Your Syntax Theme](upgrading/upgrading-your-syntax-theme.md)
+150
Ver Arquivo
@@ -0,0 +1,150 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap-theme.min.css">
<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="../../assets/js/html5shiv.js"></script>
<script src="../../assets/js/respond.min.js"></script>
<![endif]-->
<title>Atom - <%= title %></title>
<style>
/*github.com style (c) Vasily Polovnyov <vast@whiteants.net>*/
pre code {
display: block; padding: 0.5em;
color: #333;
background: #f8f8ff
}
pre .comment,
pre .template_comment,
pre .diff .header,
pre .javadoc {
color: #998;
font-style: italic
}
pre .keyword,
pre .css .rule .keyword,
pre .winutils,
pre .javascript .title,
pre .nginx .title,
pre .subst,
pre .request,
pre .status {
color: #333;
font-weight: bold
}
pre .number,
pre .hexcolor,
pre .ruby .constant {
color: #099;
}
pre .string,
pre .tag .value,
pre .phpdoc,
pre .tex .formula {
color: #d14
}
pre .title,
pre .id {
color: #900;
font-weight: bold
}
pre .javascript .title,
pre .lisp .title,
pre .clojure .title,
pre .subst {
font-weight: normal
}
pre .class .title,
pre .haskell .type,
pre .vhdl .literal,
pre .tex .command {
color: #458;
font-weight: bold
}
pre .tag,
pre .tag .title,
pre .rules .property,
pre .django .tag .keyword {
color: #000080;
font-weight: normal
}
pre .attribute,
pre .variable,
pre .lisp .body {
color: #008080
}
pre .regexp {
color: #009926
}
pre .class {
color: #458;
font-weight: bold
}
pre .symbol,
pre .ruby .symbol .string,
pre .lisp .keyword,
pre .tex .special,
pre .prompt {
color: #990073
}
pre .built_in,
pre .lisp .title,
pre .clojure .built_in {
color: #0086b3
}
pre .preprocessor,
pre .pi,
pre .doctype,
pre .shebang,
pre .cdata {
color: #999;
font-weight: bold
}
pre .deletion {
background: #fdd
}
pre .addition {
background: #dfd
}
pre .diff .change {
background: #0086b3
}
pre .chunk {
color: #aaa
}
body {
padding-top: 50px;
}
</style>
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/<%= tag %>/index.html">Atom Documentation</a>
</div>
<div class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li><a href="/docs/api/<%= tag %>/api/index.html">API</a></li>
</ul>
</div><!--/.nav-collapse -->
</div>
</div>
<div class="container">
<%= content %>
</div>
</body>
</html>
@@ -1,27 +0,0 @@
# Upgrading Your Syntax Theme
Text editor content is now rendered in the shadow DOM, which shields it from being styled by global style sheets to protect against accidental style pollution. For more background on the shadow DOM, check out the [Shadow DOM 101][shadow-dom-101] on HTML 5 Rocks.
Syntax themes are specifically intended to style only text editor content, so they are automatically loaded directly into the text editor's shadow DOM when it is enabled. This happens automatically when the the theme's `package.json` contains a `theme: "syntax"` declaration, so you don't need to change anything to target the appropriate context.
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 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
.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... */
}
```
[shadow-dom-101]: http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom
[host-pseudo-element]: http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom-201#toc-style-host
-137
Ver Arquivo
@@ -1,137 +0,0 @@
# 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 stylesheets and keymaps in both packages and themes to be updated.
## Deprecation Cop
Deprecation cop will list usages of deprecated selector patterns to guide you. You can access it via the command palette (`cmd-shift-p`, then search for `Deprecation`). It breaks the deprecations down by package:
![dep-cop](https://cloud.githubusercontent.com/assets/69169/5078860/d38a5df4-6e64-11e4-95b6-eb585ee9bbfc.png)
## Custom Tags
Rather than adding classes to standard HTML elements to indicate their role, Atom now uses custom element names. For example, `<div class="workspace">` has now been replaced with `<atom-workspace>`. Selectors should be updated accordingly. Note that tag names have lower specificity than classes in CSS, so you'll need to take care in converting things.
Old Selector | New Selector
--------------------|--------------------------------
`.editor` | `atom-text-editor`
`.editor.mini` | `atom-text-editor[mini]`
`.workspace` | `atom-workspace`
`.horizontal` | `atom-workspace-axis.horizontal`
`.vertical` | `atom-workspace-axis.vertical`
`.pane-container` | `atom-pane-conatiner`
`.pane` | `atom-pane`
`.tool-panel` | `atom-panel`
`.panel-top` | `atom-panel.top`
`.panel-bottom` | `atom-panel.bottom`
`.panel-left` | `atom-panel.left`
`.panel-right` | `atom-panel.right`
`.overlay` | `atom-panel.modal`
## Supporting the Shadow DOM
Text editor content is now rendered in the shadow DOM, which shields it from being styled by global style sheets to protect against accidental style pollution. For more background on the shadow DOM, check out the [Shadow DOM 101][shadow-dom-101] on HTML 5 Rocks. If you need to style text editor content in a UI theme, you'll need to circumvent this protection for any rules that target the text editor's content. Some examples of the kinds of UI theme styles needing to be updated:
* Highlight decorations
* Gutter decorations
* Line decorations
* Scrollbar styling
* Anything targeting a child selector of `.editor`
During a transition phase, it will be possible to enable or disable the text editor's shadow DOM in the settings, so themes will need to be compatible with both approaches.
### Shadow DOM Selectors
Chromium provides two tools for bypassing shadow boundaries, the `::shadow` pseudo-element and the `/deep/` combinator. For an in-depth explanation of styling the shadow DOM, see the [Shadow DOM 201][shadow-dom-201] article on HTML 5 Rocks.
#### ::shadow
The `::shadow` pseudo-element allows you to bypass a single shadow root. For example, say you want to update a highlight decoration for a linter package. Initially, the style looks as follows:
```css
// Without shadow DOM support
atom-text-editor .highlight.my-linter {
background: hotpink;
}
```
In order for this style to apply with the shadow DOM enabled, you will need to add a second selector with the `::shadow` pseudo-element. You should leave the original selector in place so your theme continues to work with the shadow DOM disabled during the transition period.
```css
// With shadow DOM support
atom-text-editor .highlight.my-linter,
atom-text-editor::shadow .highlight.my-linter {
background: hotpink;
}
```
Check out the [find-and-replace][find-and-replace] package for another example of using `::shadow` to pierce the shadow DOM.
#### /deep/
The `/deep/` combinator overrides *all* shadow boundaries, making it useful for rules you want to apply globally such as scrollbar styling. Here's a snippet containing scrollbar styling for the Atom Dark UI theme before shadow DOM support:
```css
// Without shadow DOM support
.scrollbars-visible-always {
::-webkit-scrollbar {
width: 8px;
height: 8px;
}
::-webkit-scrollbar-track,
::-webkit-scrollbar-corner {
background: @scrollbar-background-color;
}
::-webkit-scrollbar-thumb {
background: @scrollbar-color;
border-radius: 5px;
box-shadow: 0 0 1px black inset;
}
}
```
To style scrollbars even inside of the shadow DOM, each rule needs to be prefixed with `/deep/`. We use `/deep/` instead of `::shadow` because we don't care about the selector of the host element in this case. We just want our styling to apply everywhere.
```css
// With shadow DOM support using /deep/
.scrollbars-visible-always {
/deep/ ::-webkit-scrollbar {
width: 8px;
height: 8px;
}
/deep/ ::-webkit-scrollbar-track,
/deep/ ::-webkit-scrollbar-corner {
background: @scrollbar-background-color;
}
/deep/ ::-webkit-scrollbar-thumb {
background: @scrollbar-color;
border-radius: 5px;
box-shadow: 0 0 1px black inset;
}
}
```
### Context-Targeted Style Sheets
The selector features discussed above allow you to target shadow DOM content with specific selectors, but Atom also allows you to target a specific shadow DOM context with an entire style sheet. The context into which a style sheet is loaded is based on the file name. If you want to load a style sheet into the editor, name it with the `.atom-text-editor.less` or `.atom-text-editor.css` extensions.
```
my-ui-theme/
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/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.
During the transition phase, style sheets targeting the `atom-text-editor` context will *also* be loaded globally. Make sure you update your selectors in a way that maintains compatibility with the shadow DOM being disabled. That means if you use a `::host` pseudo element, you should also include the same style rule matches against `atom-text-editor`.
[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/stylesheets/find-and-replace.less#L10
+12 -12
Ver Arquivo
@@ -49,7 +49,7 @@ Register the command in _lib/ascii-art.coffee_:
```coffeescript
module.exports =
activate: ->
atom.commands.add 'atom-workspace', "ascii-art:convert", => @convert()
atom.workspaceView.command "ascii-art:convert", => @convert()
convert: ->
# This assumes the active pane item is an editor
@@ -57,10 +57,10 @@ module.exports =
editor.insertText('Hello, World!')
```
The `atom.commands.add` method takes a selector, command name, and a callback.
The callback executes when the command is triggered on an element matching the
selector. In this case, when the command is triggered the callback will call the
`convert` method and insert 'Hello, World!'.
The `atom.workspaceView.command` method takes a command name and a callback. The
callback executes when the command is triggered. In this case, when the command
is triggered the callback will call the `convert` method and insert 'Hello,
World!'.
## Reload the Package
@@ -95,13 +95,13 @@ you don't need it anymore. When finished, the file will look like this:
'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 `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.
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 `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.
Now reload the window and verify that the key binding works! You can also verify
that it **doesn't** work when the Tree View is focused.
+7 -4
Ver Arquivo
@@ -4,8 +4,11 @@
# after packages are loaded/activated and after the previous editor state
# has been restored.
#
# An example hack to log to the console when each text editor is saved.
# An example hack to make opened Markdown files always be soft wrapped:
#
# atom.workspace.observeTextEditors (editor) ->
# editor.onDidSave ->
# console.log "Saved! #{editor.getPath()}"
# path = require 'path'
#
# atom.workspaceView.eachEditorView (editorView) ->
# editor = editorView.getEditor()
# if path.extname(editor.getPath()) is '.md'
# editor.setSoftWrapped(true)
+1 -1
Ver Arquivo
@@ -12,7 +12,7 @@
# 'atom-text-editor':
# 'enter': 'editor:newline'
#
# 'atom-workspace':
# '.workspace':
# 'ctrl-shift-p': 'core:move-up'
# 'ctrl-p': 'core:move-down'
#
+16 -108
Ver Arquivo
@@ -1,127 +1,35 @@
{Point, Range} = require 'text-buffer'
{Emitter, Disposable, CompositeDisposable} = require 'event-kit'
{deprecate} = require 'grim'
module.exports =
BufferedNodeProcess: require '../src/buffered-node-process'
BufferedProcess: require '../src/buffered-process'
GitRepository: require '../src/git-repository'
Notification: require '../src/notification'
Point: Point
Range: Range
Emitter: Emitter
Disposable: Disposable
CompositeDisposable: CompositeDisposable
# The following classes can't be used from a Task handler and should therefore
# only be exported when not running as a child node process
unless process.env.ATOM_SHELL_INTERNAL_RUN_AS_NODE
module.exports.Task = require '../src/task'
module.exports.TextEditor = require '../src/text-editor'
{$, $$, $$$, View} = require '../src/space-pen-extensions'
Object.defineProperty module.exports, 'Workspace', get: ->
deprecate """
Requiring `Workspace` from `atom` is no longer supported.
If you need this, please open an issue on
https://github.com/atom/atom/issues/new
And let us know what you are using it for.
"""
require '../src/workspace'
Object.defineProperty module.exports, 'WorkspaceView', get: ->
deprecate """
Requiring `WorkspaceView` from `atom` is no longer supported.
Use `atom.views.getView(atom.workspace)` instead.
"""
require '../src/workspace-view'
Object.defineProperty module.exports, '$', get: ->
deprecate """
Requiring `$` from `atom` is no longer supported.
If you are using `space-pen`, please require `$` from `space-pen`. Otherwise require `jquery` instead:
`{$} = require 'space-pen'`
or
`$ = require 'jquery'`
Add `"space-pen": "^4"` to your package dependencies.
Or add `"jquery": "^2"` to your package dependencies.
"""
$
Object.defineProperty module.exports, '$$', get: ->
deprecate """
Requiring `$$` from `atom` is no longer supported.
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 `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 `space-pen` instead:
`{View} = require 'space-pen'`
Add `"space-pen": "^4"` to your package dependencies.
"""
View
Object.defineProperty module.exports, 'EditorView', get: ->
deprecate """
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": "^0"` to your package dependencies.
"""
require '../src/text-editor-view'
Object.defineProperty module.exports, 'TextEditorView', get: ->
deprecate """
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": "^0"` to your package dependencies.
"""
require '../src/text-editor-view'
Object.defineProperty module.exports, 'ScrollView', get: ->
deprecate """
Requiring `ScrollView` from `atom` is no longer supported.
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": "^0"` to your package dependencies.
"""
require '../src/scroll-view'
Object.defineProperty module.exports, 'SelectListView', get: ->
deprecate """
Requiring `SelectListView` from `atom` is no longer supported.
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": "^0"` to your package dependencies.
"""
require '../src/select-list-view'
Object.defineProperty module.exports, 'React', get: ->
deprecate "Please require `react-atom-fork` instead: `React = require 'react-atom-fork'`. Add `\"react-atom-fork\": \"^0.11\"` to your package dependencies."
require 'react-atom-fork'
Object.defineProperty module.exports, 'Reactionary', get: ->
deprecate "Please require `reactionary-atom-fork` instead: `Reactionary = require 'reactionary-atom-fork'`. Add `\"reactionary-atom-fork\": \"^0.9\"` to your package dependencies."
require 'reactionary-atom-fork'
module.exports.$ = $
module.exports.$$ = $$
module.exports.$$$ = $$$
module.exports.TextEditorView = require '../src/text-editor-view'
module.exports.ScrollView = require '../src/scroll-view'
module.exports.SelectListView = require '../src/select-list-view'
module.exports.Task = require '../src/task'
module.exports.View = View
module.exports.WorkspaceView = require '../src/workspace-view'
module.exports.Workspace = require '../src/workspace'
module.exports.React = require 'react-atom-fork'
module.exports.Reactionary = require 'reactionary-atom-fork'
Object.defineProperty module.exports, 'Git', get: ->
deprecate "Please require `GitRepository` instead of `Git`: `{GitRepository} = require 'atom'`"
module.exports.GitRepository
Object.defineProperty module.exports, 'EditorView', get: ->
deprecate "Please require `TextEditorView` instead of `EditorView`: `{TextEditorView} = require 'atom'`"
module.exports.TextEditorView
+2 -5
Ver Arquivo
@@ -5,7 +5,7 @@
'shift-home': 'editor:select-to-first-character-of-line'
'shift-end': 'editor:select-to-end-of-line'
'atom-text-editor:not([mini])':
'atom-text-editor:not(.mini)':
# Atom Specific
'ctrl-C': 'editor:copy-path'
@@ -15,13 +15,10 @@
'shift-tab': 'editor:outdent-selected-rows'
'ctrl-K': 'editor:delete-line'
'.select-list atom-text-editor[mini]':
'enter': 'core:confirm'
'.tool-panel.panel-left, .tool-panel.panel-right':
'escape': 'tool-panel:unfocus'
'atom-text-editor !important, atom-text-editor[mini] !important':
'atom-text-editor !important, atom-text-editor.mini !important':
'escape': 'editor:consolidate-selections'
# allow standard input fields to work correctly
+2 -4
Ver Arquivo
@@ -29,8 +29,6 @@
'ctrl-alt-cmd-l': 'window:reload'
'alt-cmd-i': 'window:toggle-dev-tools'
'cmd-alt-ctrl-p': 'window:run-package-specs'
'ctrl-shift-left': 'pane:move-item-left'
'ctrl-shift-right': 'pane:move-item-right'
# Sublime Parity
'cmd-,': 'application:show-settings'
@@ -112,7 +110,7 @@
# Apple Specific
'cmd-backspace': 'editor:delete-to-beginning-of-line'
'cmd-shift-backspace': 'editor:delete-to-beginning-of-line'
'cmd-delete': 'editor:delete-to-end-of-line'
'cmd-delete': 'editor:delete-to-beginning-of-line'
'ctrl-A': 'editor:select-to-first-character-of-line'
'ctrl-E': 'editor:select-to-end-of-line'
'cmd-left': 'editor:move-to-first-character-of-line'
@@ -136,7 +134,7 @@
'cmd-l': 'editor:select-line'
'ctrl-t': 'editor:transpose'
'atom-workspace atom-text-editor:not([mini])':
'atom-workspace atom-text-editor:not(.mini)':
# Atom specific
'alt-cmd-z': 'editor:checkout-head-revision'
'cmd-<': 'editor:scroll-to-cursor'
+1 -3
Ver Arquivo
@@ -12,8 +12,6 @@
'ctrl-alt-s': 'application:run-all-specs'
'ctrl-alt-o': 'application:open-dev'
'ctrl-shift-o': 'application:open-folder'
'ctrl-shift-pageup': 'pane:move-item-left'
'ctrl-shift-pagedown': 'pane:move-item-right'
'F11': 'window:toggle-full-screen'
# Sublime Parity
@@ -101,7 +99,7 @@
'ctrl-k ctrl-l': 'editor:lower-case'
'ctrl-l': 'editor:select-line'
'atom-workspace atom-text-editor:not([mini])':
'atom-workspace atom-text-editor:not(.mini)':
# Atom specific
'alt-ctrl-z': 'editor:checkout-head-revision'
'ctrl-<': 'editor:scroll-to-cursor'
+1 -5
Ver Arquivo
@@ -14,10 +14,6 @@
'ctrl-alt-i': 'window:toggle-dev-tools'
'ctrl-alt-p': 'window:run-package-specs'
'ctrl-alt-s': 'application:run-all-specs'
'ctrl-alt-o': 'application:open-dev'
'ctrl-shift-o': 'application:open-folder'
'ctrl-shift-left': 'pane:move-item-left'
'ctrl-shift-right': 'pane:move-item-right'
'F11': 'window:toggle-full-screen'
# Sublime Parity
@@ -98,7 +94,7 @@
'ctrl-k ctrl-l': 'editor:lower-case'
'ctrl-l': 'editor:select-line'
'atom-workspace atom-text-editor:not([mini])':
'atom-workspace atom-text-editor:not(.mini)':
# Atom specific
'alt-ctrl-z': 'editor:checkout-head-revision'
'ctrl-<': 'editor:scroll-to-cursor'
-1
Ver Arquivo
@@ -94,7 +94,6 @@
submenu: [
{ label: '&Reload', command: 'window:reload' }
{ label: 'Toggle &Full Screen', command: 'window:toggle-full-screen' }
{ label: 'Toggle Menu Bar', command: 'window:toggle-menu-bar' }
{
label: 'Developer'
submenu: [
+2 -3
Ver Arquivo
@@ -93,7 +93,6 @@
submenu: [
{ label: '&Reload', command: 'window:reload' }
{ label: 'Toggle &Full Screen', command: 'window:toggle-full-screen' }
{ label: 'Toggle Menu Bar', command: 'window:toggle-menu-bar' }
{
label: 'Panes'
submenu: [
@@ -110,7 +109,7 @@
{ label: 'Focus Pane On Left', command: 'window:focus-pane-on-left' }
{ label: 'Focus Pane On Right', command: 'window:focus-pane-on-right' }
{ type: 'separator' }
{ label: 'Close Pane', command: 'pane:close' }
{ label: 'Close pane', command: 'pane:close' }
]
}
{
@@ -163,7 +162,7 @@
submenu: [
{ label: 'View &Terms of Use', command: 'application:open-terms-of-use' }
{ label: 'View &License', command: 'application:open-license' }
{ label: 'VERSION', enabled: false }
{ label: "VERSION", enabled: false }
{ type: 'separator' }
{ label: '&Documentation', command: 'application:open-documentation' }
{ label: 'Roadmap', command: 'application:open-roadmap' }
+53 -51
Ver Arquivo
@@ -1,7 +1,7 @@
{
{
"name": "atom",
"productName": "Atom",
"version": "0.153.0",
"version": "0.142.0",
"description": "A hackable text editor for the 21st Century.",
"main": "./src/browser/main.js",
"repository": {
@@ -17,10 +17,10 @@
"url": "http://github.com/atom/atom/raw/master/LICENSE.md"
}
],
"atomShellVersion": "0.19.4",
"atomShellVersion": "0.18.2",
"dependencies": {
"async": "0.2.6",
"atom-keymap": "^2.3.0",
"atom-keymap": "^2.2.1",
"bootstrap": "git+https://github.com/atom/bootstrap.git#6af81906189f1747fd6c93479e3d998ebe041372",
"clear-cut": "0.4.0",
"coffee-script": "1.7.0",
@@ -29,7 +29,7 @@
"emissary": "^1.3.1",
"event-kit": "0.7.2",
"first-mate": "^2.2.0",
"fs-plus": "^2.3.2",
"fs-plus": "^2.3.1",
"fstream": "0.1.24",
"fuzzaldrin": "^2.1",
"git-utils": "^2.1.5",
@@ -37,15 +37,13 @@
"guid": "0.0.10",
"jasmine-json": "~0.0",
"jasmine-tagged": "^1.1.2",
"jquery": "^2.1.1",
"less-cache": "0.19.0",
"marked": "^0.3",
"less-cache": "0.17.0",
"mixto": "^1",
"mkdirp": "0.3.5",
"nslog": "^1.0.1",
"oniguruma": "^3.0.4",
"optimist": "0.4.0",
"pathwatcher": "2.3.2",
"pathwatcher": "^2.3.2",
"property-accessors": "^1",
"q": "^1.0.1",
"random-words": "0.0.1",
@@ -58,92 +56,96 @@
"season": "^1.0.2",
"semver": "2.2.1",
"serializable": "^1",
"space-pen": "3.8.2",
"space-pen": "3.8.0",
"temp": "0.7.0",
"text-buffer": "^3.7.2",
"text-buffer": "^3.4",
"theorist": "^1.0.2",
"underscore-plus": "^1.6.1",
"vm-compatibility-layer": "0.1.0"
"vm-compatibility-layer": "0.1.0",
"elmer": "^0.0",
"Node-bind": "git://github.com/Polymer/NodeBind.git#0.4.2",
"observe-js": "git://github.com/Polymer/observe-js.git#0.4.2",
"polymer-expressions": "git://github.com/Polymer/polymer-expressions.git#0.4.2",
"TemplateBinding": "git://github.com/Polymer/TemplateBinding.git#0.4.2"
},
"packageDependencies": {
"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.23.0",
"solarized-light-syntax": "0.13.0",
"atom-dark-syntax": "0.20.0",
"atom-dark-ui": "0.35.0",
"atom-light-syntax": "0.21.0",
"atom-light-ui": "0.30.0",
"base16-tomorrow-dark-theme": "0.21.0",
"base16-tomorrow-light-theme": "0.4.0",
"solarized-dark-syntax": "0.22.0",
"solarized-light-syntax": "0.12.0",
"archive-view": "0.37.0",
"autocomplete": "0.33.1",
"autocomplete": "0.32.0",
"autoflow": "0.18.0",
"autosave": "0.18.0",
"background-tips": "0.17.0",
"bookmarks": "0.30.0",
"bookmarks": "0.28.0",
"bracket-matcher": "0.62.0",
"command-palette": "0.28.0",
"deprecation-cop": "0.18.0",
"command-palette": "0.27.0",
"deprecation-cop": "0.11.0",
"dev-live-reload": "0.35.0",
"encoding-selector": "0.8.0",
"encoding-selector": "0.5.0",
"exception-reporting": "0.20.0",
"find-and-replace": "0.147.0",
"find-and-replace": "0.141.0",
"fuzzy-finder": "0.60.0",
"git-diff": "0.43.0",
"git-diff": "0.42.0",
"go-to-line": "0.26.0",
"grammar-selector": "0.37.0",
"image-view": "0.42.0",
"image-view": "0.40.0",
"incompatible-packages": "0.10.0",
"keybinding-resolver": "0.20.0",
"link": "0.26.0",
"markdown-preview": "0.110.0",
"metrics": "0.39.0",
"notifications": "0.4.0",
"markdown-preview": "0.107.0",
"metrics": "0.36.0",
"open-on-github": "0.30.0",
"package-generator": "0.32.0",
"package-generator": "0.31.0",
"release-notes": "0.36.0",
"settings-view": "0.161.0",
"snippets": "0.57.0",
"spell-check": "0.44.0",
"status-bar": "0.48.0",
"settings-view": "0.154.0",
"snippets": "0.56.0",
"spell-check": "0.43.0",
"status-bar": "0.46.0",
"styleguide": "0.30.0",
"symbols-view": "0.68.0",
"tabs": "0.56.0",
"symbols-view": "0.66.0",
"tabs": "0.55.0",
"timecop": "0.23.0",
"tree-view": "0.134.0",
"tree-view": "0.131.0",
"update-package-dependencies": "0.6.0",
"welcome": "0.19.0",
"whitespace": "0.26.0",
"wrap-guide": "0.24.0",
"language-c": "0.31.0",
"language-coffee-script": "0.38.0",
"language-css": "0.23.0",
"language-gfm": "0.54.0",
"wrap-guide": "0.23.0",
"language-c": "0.29.0",
"language-coffee-script": "0.37.0",
"language-css": "0.21.0",
"language-gfm": "0.53.0",
"language-git": "0.9.0",
"language-go": "0.19.0",
"language-html": "0.26.0",
"language-hyperlink": "0.12.0",
"language-java": "0.11.0",
"language-javascript": "0.45.0",
"language-javascript": "0.42.0",
"language-json": "0.8.0",
"language-less": "0.18.0",
"language-make": "0.12.0",
"language-mustache": "0.10.0",
"language-objective-c": "0.11.0",
"language-perl": "0.9.0",
"language-php": "0.18.0",
"language-php": "0.17.0",
"language-property-list": "0.7.0",
"language-python": "0.24.0",
"language-python": "0.21.0",
"language-ruby": "0.41.0",
"language-ruby-on-rails": "0.18.0",
"language-sass": "0.26.0",
"language-shellscript": "0.10.0",
"language-sass": "0.24.0",
"language-shellscript": "0.8.0",
"language-source": "0.8.0",
"language-sql": "0.11.0",
"language-text": "0.6.0",
"language-todo": "0.13.0",
"language-toml": "0.14.0",
"language-xml": "0.25.0",
"language-yaml": "0.20.0"
"language-xml": "0.24.0",
"language-yaml": "0.19.0"
},
"private": true,
"scripts": {
+1 -2
Ver Arquivo
@@ -1,7 +1,6 @@
Package: <%= name %>
Version: <%= version %>
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
Depends: python (>= 2.6), libc6
Section: <%= section %>
Priority: optional
Architecture: <%= arch %>
+3
Ver Arquivo
@@ -4,6 +4,9 @@ Release: 0.1%{?dist}
Summary: Atom is a hackable text editor for the 21st century
License: MIT
URL: https://atom.io/
BuildConflicts: gyp
BuildRequires: make, gcc, gcc-c++, glibc-devel, git-core, libgnome-keyring-devel
Requires: libgnome-keyring
AutoReqProv: no # Avoid libchromiumcontent.so missing dependency
%description
Arquivo binário não exibido.

Antes

Largura:  |  Altura:  |  Tamanho: 274 KiB

-3
Ver Arquivo
@@ -34,9 +34,6 @@ exports.safeSpawn = function(command, args, options, callback) {
var child = childProcess.spawn(command, args, options);
child.stderr.pipe(process.stderr);
child.stdout.pipe(process.stdout);
child.on('error', function(error) {
console.error('Command \'' + command + '\' failed: ' + error.message);
});
child.on('exit', function(code) {
if (code != 0)
process.exit(code);
+1 -3
Ver Arquivo
@@ -3,7 +3,6 @@ _ = require 'underscore-plus'
{convertStackTrace} = require 'coffeestack'
{View, $, $$} = require '../src/space-pen-extensions'
grim = require 'grim'
marked = require 'marked'
sourceMaps = {}
formatStackTrace = (spec, message='', stackTrace) ->
@@ -111,8 +110,7 @@ class AtomReporter extends View
for deprecation in deprecations
@deprecationList.append $$ ->
@div class: 'padded', =>
@div class: 'result-message fail deprecation-message', =>
@raw marked(deprecation.message)
@div class: 'result-message fail deprecation-message', deprecation.message
for stack in deprecation.stacks
fullStack = stack.map ({functionName, location}) ->
+14 -68
Ver Arquivo
@@ -5,6 +5,9 @@ Package = require '../src/package'
ThemeManager = require '../src/theme-manager'
describe "the `atom` global", ->
beforeEach ->
atom.workspaceView = atom.views.getView(atom.workspace).__spacePenView
describe 'window sizing methods', ->
describe '::getPosition and ::setPosition', ->
it 'sets the position of the window, and can retrieve the position just set', ->
@@ -32,9 +35,6 @@ describe "the `atom` global", ->
describe "window:update-available", ->
it "is triggered when the auto-updater sends the update-downloaded event", ->
# FIXME: We need to figure out a way minus workspaceView to handle update-available events.
atom.workspaceView = atom.views.getView(atom.workspace).__spacePenView
updateAvailableHandler = jasmine.createSpy("update-available-handler")
atom.workspaceView.on 'window:update-available', updateAvailableHandler
autoUpdater = require('remote').require('auto-updater')
@@ -53,71 +53,17 @@ describe "the `atom` global", ->
expect(atom.config.get('core.excludeVcsIgnoredPaths')).toBe true
expect(atom.config.get('editor.showInvisibles')).toBe false
describe "window onerror handler", ->
beforeEach ->
spyOn atom, 'openDevTools'
spyOn atom, 'executeJavaScriptInDevTools'
it 'loads the templating globals', ->
jasmineContent = document.body.querySelector('#jasmine-content')
Template = require './fixtures/html-template.html'
Model = {message: 'test!', number: 10}
it "will open the dev tools when an error is triggered", ->
try
a + 1
catch e
window.onerror.call(window, e.toString(), 'abc', 2, 3, e)
jasmineContent.appendChild(Template.clone())
jasmineContent.querySelector('template').model = Model
expect(atom.openDevTools).toHaveBeenCalled()
expect(atom.executeJavaScriptInDevTools).toHaveBeenCalled()
waits 0
describe "::onWillThrowError", ->
willThrowSpy = null
beforeEach ->
willThrowSpy = jasmine.createSpy()
it "is called when there is an error", ->
error = null
atom.onWillThrowError(willThrowSpy)
try
a + 1
catch e
error = e
window.onerror.call(window, e.toString(), 'abc', 2, 3, e)
delete willThrowSpy.mostRecentCall.args[0].preventDefault
expect(willThrowSpy).toHaveBeenCalledWith
message: error.toString()
url: 'abc'
line: 2
column: 3
originalError: error
it "will not show the devtools when preventDefault() is called", ->
willThrowSpy.andCallFake (errorObject) -> errorObject.preventDefault()
atom.onWillThrowError(willThrowSpy)
try
a + 1
catch e
window.onerror.call(window, e.toString(), 'abc', 2, 3, e)
expect(willThrowSpy).toHaveBeenCalled()
expect(atom.openDevTools).not.toHaveBeenCalled()
expect(atom.executeJavaScriptInDevTools).not.toHaveBeenCalled()
describe "::onDidThrowError", ->
didThrowSpy = null
beforeEach ->
didThrowSpy = jasmine.createSpy()
it "is called when there is an error", ->
error = null
atom.onDidThrowError(didThrowSpy)
try
a + 1
catch e
error = e
window.onerror.call(window, e.toString(), 'abc', 2, 3, e)
expect(didThrowSpy).toHaveBeenCalledWith
message: error.toString()
url: 'abc'
line: 2
column: 3
originalError: error
runs ->
# apparently template rendering is async
expect(jasmineContent.querySelector('.test-message').textContent).toBe 'test!'
expect(jasmineContent.querySelector('.test-number').textContent).toBe '20'
+1 -9
Ver Arquivo
@@ -1,5 +1,4 @@
CommandRegistry = require '../src/command-registry'
_ = require 'underscore-plus'
describe "CommandRegistry", ->
[registry, parent, child, grandchild] = []
@@ -155,15 +154,8 @@ describe "CommandRegistry", ->
registry.add '.grandchild', 'namespace:command-3', ->
registry.add '.grandchild.no-match', 'namespace:command-4', ->
registry.add grandchild, 'namespace:inline-command-1', ->
registry.add child, 'namespace:inline-command-2', ->
commands = registry.findCommands(target: grandchild)
nonJqueryCommands = _.reject commands, (cmd) -> cmd.jQuery
expect(nonJqueryCommands).toEqual [
{name: 'namespace:inline-command-1', displayName: 'Namespace: Inline Command 1'}
expect(registry.findCommands(target: grandchild)[0..2]).toEqual [
{name: 'namespace:command-3', displayName: 'Namespace: Command 3'}
{name: 'namespace:inline-command-2', displayName: 'Namespace: Inline Command 2'}
{name: 'namespace:command-2', displayName: 'Namespace: Command 2'}
{name: 'namespace:command-1', displayName: 'Namespace: Command 1'}
]
+1 -48
Ver Arquivo
@@ -195,52 +195,6 @@ describe "Config", ->
atom.config.restoreDefault('.source.coffee', 'foo.bar.baz')
expect(atom.config.save.callCount).toBe 1
it "does not call ::save or add a scoped property when no value has been set", ->
# see https://github.com/atom/atom/issues/4175
atom.config.setDefaults("foo", bar: baz: 10)
atom.config.restoreDefault('.source.coffee', 'foo.bar.baz')
expect(atom.config.get(['.source.coffee'], 'foo.bar.baz')).toBe 10
expect(atom.config.save).not.toHaveBeenCalled()
scopedProperties = atom.config.scopedSettingsStore.propertiesForSource('user-config')
expect(scopedProperties['.coffee.source']).toBeUndefined()
it "removes the scoped value when it was the only set value on the object", ->
spyOn(CSON, 'writeFileSync')
jasmine.unspy atom.config, 'save'
atom.config.setDefaults("foo", bar: baz: 10)
atom.config.set('.source.coffee', 'foo.bar.baz', 55)
atom.config.set('.source.coffee', 'foo.bar.zfoo', 20)
CSON.writeFileSync.reset()
expect(atom.config.get(['.source.coffee'], 'foo.bar.baz')).toBe 55
atom.config.restoreDefault('.source.coffee', 'foo.bar.baz')
expect(atom.config.get(['.source.coffee'], 'foo.bar.baz')).toBe 10
expect(atom.config.get(['.source.coffee'], 'foo.bar.zfoo')).toBe 20
expect(CSON.writeFileSync).toHaveBeenCalled()
properties = CSON.writeFileSync.mostRecentCall.args[1]
expect(properties['.coffee.source']).toEqual
foo:
bar:
zfoo: 20
CSON.writeFileSync.reset()
atom.config.restoreDefault('.source.coffee', 'foo.bar.zfoo')
expect(CSON.writeFileSync).toHaveBeenCalled()
properties = CSON.writeFileSync.mostRecentCall.args[1]
expect(properties['.coffee.source']).toBeUndefined()
it "does not call ::save when the value is already at the default", ->
atom.config.setDefaults("foo", bar: baz: 10)
atom.config.set('.source.coffee', 'foo.bar.baz', 55)
atom.config.save.reset()
atom.config.restoreDefault('.source.coffee', 'foo.bar.ok')
expect(atom.config.save).not.toHaveBeenCalled()
expect(atom.config.get(['.source.coffee'], 'foo.bar.baz')).toBe 55
describe ".getSettings()", ->
it "returns all settings including defaults", ->
atom.config.setDefaults("foo", bar: baz: 10)
@@ -554,13 +508,11 @@ describe "Config", ->
describe "when the config file contains invalid cson", ->
beforeEach ->
spyOn(console, 'error')
spyOn(atom.notifications, 'addError')
fs.writeFileSync(atom.config.configFilePath, "{{{{{")
it "logs an error to the console and does not overwrite the config file on a subsequent save", ->
atom.config.loadUserConfig()
expect(console.error).toHaveBeenCalled()
expect(atom.notifications.addError.callCount).toBe 1
atom.config.set("hair", "blonde") # trigger a save
expect(atom.config.save).not.toHaveBeenCalled()
@@ -694,6 +646,7 @@ describe "Config", ->
expect(atom.config.get(['.source.ruby'], 'foo.bar')).toBe 'baz'
expect(atom.config.get(['.source.ruby'], 'foo.scoped')).toBe true
describe "when the config file changes to omit a setting with a default", ->
it "resets the setting back to the default", ->
fs.writeFileSync(atom.config.configFilePath, "foo: { baz: 'new'}")
+2
Ver Arquivo
@@ -0,0 +1,2 @@
<div class="one">text</div>
<span class="two">text</span>
+4
Ver Arquivo
@@ -0,0 +1,4 @@
<template bind="{{}}">
<div class="test-message">{{message}}</div>
<div class="test-number">{{number * 2}}</div>
</template>
@@ -9,6 +9,5 @@ module.exports =
atom.commands.add 'atom-workspace', 'activation-command', =>
@activationCommandCallCount++
editorView = atom.views.getView(atom.workspace.getActiveEditor())?.__spacePenView
editorView?.command 'activation-command', =>
atom.workspaceView.getActiveView()?.command 'activation-command', =>
@legacyActivationCommandCallCount++
@@ -1 +0,0 @@
a { color: red }
+13
Ver Arquivo
@@ -0,0 +1,13 @@
describe "HTMLRequire", ->
it "requires the html file and places it into a document fragment", ->
html = require './fixtures/html-require.html'
docFragment = html.getDocumentFragment()
expect(docFragment.children.length).toBe 2
expect(docFragment.querySelector('.one').tagName).toBe 'DIV'
describe '.clone()', ->
it "returns a cloned document fragment", ->
html = require './fixtures/html-require.html'
docFragment = html.clone()
expect(docFragment.children.length).toBe 2
expect(docFragment.querySelector('.one').tagName).toBe 'DIV'
+2 -3
Ver Arquivo
@@ -96,13 +96,12 @@ describe "LanguageMode", ->
buffer.setText("//this is a single line comment")
expect(languageMode.rowRangeForCommentAtBufferRow(0)).toBeUndefined()
describe ".suggestedIndentForBufferRow", ->
it "bases indentation off of the previous non-blank line", ->
describe "suggestedIndentForBufferRow", ->
it "returns the suggested indentation based on auto-indent/outdent rules", ->
expect(languageMode.suggestedIndentForBufferRow(0)).toBe 0
expect(languageMode.suggestedIndentForBufferRow(1)).toBe 1
expect(languageMode.suggestedIndentForBufferRow(2)).toBe 2
expect(languageMode.suggestedIndentForBufferRow(9)).toBe 1
expect(languageMode.suggestedIndentForBufferRow(11)).toBe 1
describe "rowRangeForParagraphAtBufferRow", ->
describe "with code and comments", ->
-57
Ver Arquivo
@@ -1,57 +0,0 @@
NotificationManager = require '../src/notification-manager'
describe "NotificationManager", ->
[manager] = []
beforeEach ->
manager = new NotificationManager
describe "the atom global", ->
it "has a notifications instance", ->
expect(atom.notifications instanceof NotificationManager).toBe true
describe "adding events", ->
addSpy = null
beforeEach ->
addSpy = jasmine.createSpy()
manager.onDidAddNotification(addSpy)
it "emits an event when a notification has been added", ->
manager.add('error', 'Some error!', icon: 'someIcon')
expect(addSpy).toHaveBeenCalled()
notification = addSpy.mostRecentCall.args[0]
expect(notification.getType()).toBe 'error'
expect(notification.getMessage()).toBe 'Some error!'
expect(notification.getIcon()).toBe 'someIcon'
it "emits a fatal error ::addFatalError has been called", ->
manager.addFatalError('Some error!', icon: 'someIcon')
expect(addSpy).toHaveBeenCalled()
notification = addSpy.mostRecentCall.args[0]
expect(notification.getType()).toBe 'fatal'
it "emits an error ::addError has been called", ->
manager.addError('Some error!', icon: 'someIcon')
expect(addSpy).toHaveBeenCalled()
notification = addSpy.mostRecentCall.args[0]
expect(notification.getType()).toBe 'error'
it "emits a warning notification ::addWarning has been called", ->
manager.addWarning('Something!', icon: 'someIcon')
expect(addSpy).toHaveBeenCalled()
notification = addSpy.mostRecentCall.args[0]
expect(notification.getType()).toBe 'warning'
it "emits an info notification ::addInfo has been called", ->
manager.addInfo('Something!', icon: 'someIcon')
expect(addSpy).toHaveBeenCalled()
notification = addSpy.mostRecentCall.args[0]
expect(notification.getType()).toBe 'info'
it "emits a success notification ::addSuccess has been called", ->
manager.addSuccess('Something!', icon: 'someIcon')
expect(addSpy).toHaveBeenCalled()
notification = addSpy.mostRecentCall.args[0]
expect(notification.getType()).toBe 'success'
-18
Ver Arquivo
@@ -1,18 +0,0 @@
Notification = require '../src/notification'
describe "Notification", ->
[notification] = []
describe "::getTimestamp()", ->
it "returns a Date object", ->
notification = new Notification('error', 'message!')
expect(notification.getTimestamp() instanceof Date).toBe true
describe "::getIcon()", ->
it "returns a default when no icon specified", ->
notification = new Notification('error', 'message!')
expect(notification.getIcon()).toBe 'flame'
it "returns the icon specified", ->
notification = new Notification('error', 'message!', icon: 'my-icon')
expect(notification.getIcon()).toBe 'my-icon'
+55 -101
Ver Arquivo
@@ -2,9 +2,8 @@
Package = require '../src/package'
describe "PackageManager", ->
workspaceElement = null
beforeEach ->
workspaceElement = atom.views.getView(atom.workspace)
atom.workspaceView = atom.views.getView(atom.workspace).__spacePenView
describe "::loadPackage(name)", ->
it "continues if the package has an invalid package.json", ->
@@ -49,10 +48,9 @@ describe "PackageManager", ->
describe "when called multiple times", ->
it "it only calls activate on the package once", ->
spyOn(Package.prototype, 'activateNow').andCallThrough()
waitsForPromise ->
atom.packages.activatePackage('package-with-index')
waitsForPromise ->
atom.packages.activatePackage('package-with-index')
atom.packages.activatePackage('package-with-index')
atom.packages.activatePackage('package-with-index')
waitsForPromise ->
atom.packages.activatePackage('package-with-index')
@@ -112,7 +110,7 @@ describe "PackageManager", ->
[mainModule, promise, workspaceCommandListener] = []
beforeEach ->
jasmine.attachToDOM(workspaceElement)
atom.workspaceView.attachToDom()
mainModule = require './fixtures/packages/package-with-activation-commands/index'
mainModule.legacyActivationCommandCallCount = 0
mainModule.activationCommandCallCount = 0
@@ -126,29 +124,29 @@ describe "PackageManager", ->
it "defers requiring/activating the main module until an activation event bubbles to the root view", ->
expect(promise.isFulfilled()).not.toBeTruthy()
workspaceElement.dispatchEvent(new CustomEvent('activation-command', bubbles: true))
atom.workspaceView[0].dispatchEvent(new CustomEvent('activation-command', bubbles: true))
waitsForPromise ->
promise
it "triggers the activation event on all handlers registered during activation", ->
waitsForPromise ->
atom.workspace.open()
atom.workspaceView.open()
runs ->
editorView = atom.views.getView(atom.workspace.getActiveEditor()).__spacePenView
editorView = atom.workspaceView.getActiveView()
legacyCommandListener = jasmine.createSpy("legacyCommandListener")
editorView.command 'activation-command', legacyCommandListener
editorCommandListener = jasmine.createSpy("editorCommandListener")
atom.commands.add 'atom-text-editor', 'activation-command', editorCommandListener
atom.commands.dispatch(editorView[0], 'activation-command')
editorView[0].dispatchEvent(new CustomEvent('activation-command', bubbles: true))
expect(mainModule.activate.callCount).toBe 1
expect(mainModule.legacyActivationCommandCallCount).toBe 1
expect(mainModule.activationCommandCallCount).toBe 1
expect(legacyCommandListener.callCount).toBe 1
expect(editorCommandListener.callCount).toBe 1
expect(workspaceCommandListener.callCount).toBe 1
atom.commands.dispatch(editorView[0], 'activation-command')
editorView[0].dispatchEvent(new CustomEvent('activation-command', bubbles: true))
expect(mainModule.legacyActivationCommandCallCount).toBe 2
expect(mainModule.activationCommandCallCount).toBe 2
expect(legacyCommandListener.callCount).toBe 2
@@ -184,10 +182,8 @@ describe "PackageManager", ->
pack.mainModule.someNumber = 77
atom.packages.deactivatePackage("package-with-serialization")
spyOn(pack.mainModule, 'activate').andCallThrough()
waitsForPromise ->
atom.packages.activatePackage("package-with-serialization")
runs ->
expect(pack.mainModule.activate).toHaveBeenCalledWith({someNumber: 77})
atom.packages.activatePackage("package-with-serialization")
expect(pack.mainModule.activate).toHaveBeenCalledWith({someNumber: 77})
it "logs warning instead of throwing an exception if the package fails to load", ->
atom.config.set("core.disabledPackages", [])
@@ -206,13 +202,11 @@ describe "PackageManager", ->
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element2[0])).toHaveLength 0
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element3[0])).toHaveLength 0
waitsForPromise ->
atom.packages.activatePackage("package-with-keymaps")
atom.packages.activatePackage("package-with-keymaps")
runs ->
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element1[0])[0].command).toBe "test-1"
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element2[0])[0].command).toBe "test-2"
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element3[0])).toHaveLength 0
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element1[0])[0].command).toBe "test-1"
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element2[0])[0].command).toBe "test-2"
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element3[0])).toHaveLength 0
describe "when the metadata contains a 'keymaps' manifest", ->
it "loads only the keymaps specified by the manifest, in the specified order", ->
@@ -221,13 +215,11 @@ describe "PackageManager", ->
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element1[0])).toHaveLength 0
waitsForPromise ->
atom.packages.activatePackage("package-with-keymaps-manifest")
atom.packages.activatePackage("package-with-keymaps-manifest")
runs ->
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element1[0])[0].command).toBe 'keymap-1'
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-n', target:element1[0])[0].command).toBe 'keymap-2'
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-y', target:element3[0])).toHaveLength 0
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element1[0])[0].command).toBe 'keymap-1'
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-n', target:element1[0])[0].command).toBe 'keymap-2'
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-y', target:element3[0])).toHaveLength 0
describe "menu loading", ->
beforeEach ->
@@ -240,16 +232,14 @@ describe "PackageManager", ->
expect(atom.contextMenu.templateForElement(element)).toEqual []
waitsForPromise ->
atom.packages.activatePackage("package-with-menus")
atom.packages.activatePackage("package-with-menus")
runs ->
expect(atom.menu.template.length).toBe 2
expect(atom.menu.template[0].label).toBe "Second to Last"
expect(atom.menu.template[1].label).toBe "Last"
expect(atom.contextMenu.templateForElement(element)[0].label).toBe "Menu item 1"
expect(atom.contextMenu.templateForElement(element)[1].label).toBe "Menu item 2"
expect(atom.contextMenu.templateForElement(element)[2].label).toBe "Menu item 3"
expect(atom.menu.template.length).toBe 2
expect(atom.menu.template[0].label).toBe "Second to Last"
expect(atom.menu.template[1].label).toBe "Last"
expect(atom.contextMenu.templateForElement(element)[0].label).toBe "Menu item 1"
expect(atom.contextMenu.templateForElement(element)[1].label).toBe "Menu item 2"
expect(atom.contextMenu.templateForElement(element)[2].label).toBe "Menu item 3"
describe "when the metadata contains a 'menus' manifest", ->
it "loads only the menus specified by the manifest, in the specified order", ->
@@ -257,15 +247,13 @@ describe "PackageManager", ->
expect(atom.contextMenu.templateForElement(element)).toEqual []
waitsForPromise ->
atom.packages.activatePackage("package-with-menus-manifest")
atom.packages.activatePackage("package-with-menus-manifest")
runs ->
expect(atom.menu.template[0].label).toBe "Second to Last"
expect(atom.menu.template[1].label).toBe "Last"
expect(atom.contextMenu.templateForElement(element)[0].label).toBe "Menu item 2"
expect(atom.contextMenu.templateForElement(element)[1].label).toBe "Menu item 1"
expect(atom.contextMenu.templateForElement(element)[2]).toBeUndefined()
expect(atom.menu.template[0].label).toBe "Second to Last"
expect(atom.menu.template[1].label).toBe "Last"
expect(atom.contextMenu.templateForElement(element)[0].label).toBe "Menu item 2"
expect(atom.contextMenu.templateForElement(element)[1].label).toBe "Menu item 1"
expect(atom.contextMenu.templateForElement(element)[2]).toBeUndefined()
describe "stylesheet loading", ->
describe "when the metadata contains a 'stylesheets' manifest", ->
@@ -282,67 +270,33 @@ describe "PackageManager", ->
expect(atom.themes.stylesheetElementForId(two)).toBeNull()
expect(atom.themes.stylesheetElementForId(three)).toBeNull()
waitsForPromise ->
atom.packages.activatePackage("package-with-stylesheets-manifest")
atom.packages.activatePackage("package-with-stylesheets-manifest")
runs ->
expect(atom.themes.stylesheetElementForId(one)).not.toBeNull()
expect(atom.themes.stylesheetElementForId(two)).not.toBeNull()
expect(atom.themes.stylesheetElementForId(three)).toBeNull()
expect($('#jasmine-content').css('font-size')).toBe '1px'
expect(atom.themes.stylesheetElementForId(one)).not.toBeNull()
expect(atom.themes.stylesheetElementForId(two)).not.toBeNull()
expect(atom.themes.stylesheetElementForId(three)).toBeNull()
expect($('#jasmine-content').css('font-size')).toBe '1px'
describe "when the metadata does not contain a 'stylesheets' manifest", ->
it "loads all stylesheets from the stylesheets directory", ->
one = require.resolve("./fixtures/packages/package-with-stylesheets/stylesheets/1.css")
two = require.resolve("./fixtures/packages/package-with-stylesheets/stylesheets/2.less")
three = require.resolve("./fixtures/packages/package-with-stylesheets/stylesheets/3.test-context.css")
four = require.resolve("./fixtures/packages/package-with-stylesheets/stylesheets/4.css")
three = require.resolve("./fixtures/packages/package-with-stylesheets/stylesheets/3.css")
one = atom.themes.stringToId(one)
two = atom.themes.stringToId(two)
three = atom.themes.stringToId(three)
four = atom.themes.stringToId(four)
expect(atom.themes.stylesheetElementForId(one)).toBeNull()
expect(atom.themes.stylesheetElementForId(two)).toBeNull()
expect(atom.themes.stylesheetElementForId(three)).toBeNull()
expect(atom.themes.stylesheetElementForId(four)).toBeNull()
waitsForPromise ->
atom.packages.activatePackage("package-with-stylesheets")
runs ->
expect(atom.themes.stylesheetElementForId(one)).not.toBeNull()
expect(atom.themes.stylesheetElementForId(two)).not.toBeNull()
expect(atom.themes.stylesheetElementForId(three)).not.toBeNull()
expect(atom.themes.stylesheetElementForId(four)).not.toBeNull()
expect($('#jasmine-content').css('font-size')).toBe '3px'
it "assigns the stylesheet's context based on the filename", ->
waitsForPromise ->
atom.packages.activatePackage("package-with-stylesheets")
runs ->
count = 0
for styleElement in atom.styles.getStyleElements()
if styleElement.sourcePath.match /1.css/
expect(styleElement.context).toBe undefined
count++
if styleElement.sourcePath.match /2.less/
expect(styleElement.context).toBe undefined
count++
if styleElement.sourcePath.match /3.test-context.css/
expect(styleElement.context).toBe 'test-context'
count++
if styleElement.sourcePath.match /4.css/
expect(styleElement.context).toBe undefined
count++
expect(count).toBe 4
expect(atom.themes.stylesheetElementForId(one)).not.toBeNull()
expect(atom.themes.stylesheetElementForId(two)).not.toBeNull()
expect(atom.themes.stylesheetElementForId(three)).not.toBeNull()
expect($('#jasmine-content').css('font-size')).toBe '3px'
describe "grammar loading", ->
it "loads the package's grammars", ->
@@ -350,8 +304,8 @@ describe "PackageManager", ->
atom.packages.activatePackage('package-with-grammars')
runs ->
expect(atom.grammars.selectGrammar('a.alot').name).toBe 'Alot'
expect(atom.grammars.selectGrammar('a.alittle').name).toBe 'Alittle'
expect(atom.syntax.selectGrammar('a.alot').name).toBe 'Alot'
expect(atom.syntax.selectGrammar('a.alittle').name).toBe 'Alittle'
describe "scoped-property loading", ->
it "loads the scoped properties", ->
@@ -363,13 +317,13 @@ describe "PackageManager", ->
describe "converted textmate packages", ->
it "loads the package's grammars", ->
expect(atom.grammars.selectGrammar("file.rb").name).toBe "Null Grammar"
expect(atom.syntax.selectGrammar("file.rb").name).toBe "Null Grammar"
waitsForPromise ->
atom.packages.activatePackage('language-ruby')
runs ->
expect(atom.grammars.selectGrammar("file.rb").name).toBe "Ruby"
expect(atom.syntax.selectGrammar("file.rb").name).toBe "Ruby"
it "loads the translated scoped properties", ->
expect(atom.config.get(['.source.ruby'], 'editor.commentStart')).toBeUndefined()
@@ -455,8 +409,8 @@ describe "PackageManager", ->
runs ->
atom.packages.deactivatePackage('package-with-grammars')
expect(atom.grammars.selectGrammar('a.alot').name).toBe 'Null Grammar'
expect(atom.grammars.selectGrammar('a.alittle').name).toBe 'Null Grammar'
expect(atom.syntax.selectGrammar('a.alot').name).toBe 'Null Grammar'
expect(atom.syntax.selectGrammar('a.alittle').name).toBe 'Null Grammar'
it "removes the package's keymaps", ->
waitsForPromise ->
@@ -491,15 +445,15 @@ describe "PackageManager", ->
describe "textmate packages", ->
it "removes the package's grammars", ->
expect(atom.grammars.selectGrammar("file.rb").name).toBe "Null Grammar"
expect(atom.syntax.selectGrammar("file.rb").name).toBe "Null Grammar"
waitsForPromise ->
atom.packages.activatePackage('language-ruby')
runs ->
expect(atom.grammars.selectGrammar("file.rb").name).toBe "Ruby"
expect(atom.syntax.selectGrammar("file.rb").name).toBe "Ruby"
atom.packages.deactivatePackage('language-ruby')
expect(atom.grammars.selectGrammar("file.rb").name).toBe "Null Grammar"
expect(atom.syntax.selectGrammar("file.rb").name).toBe "Null Grammar"
it "removes the package's scoped properties", ->
waitsForPromise ->
@@ -527,8 +481,8 @@ describe "PackageManager", ->
atom.packages.deactivatePackages()
atom.packages.unloadPackages()
GrammarRegistry = require '../src/grammar-registry'
atom.grammars = window.syntax = new GrammarRegistry()
Syntax = require '../src/syntax'
atom.syntax = window.syntax = new Syntax()
it "activates all the packages, and none of the themes", ->
atom.packages.activate()
+1 -1
Ver Arquivo
@@ -92,7 +92,7 @@ describe "Package", ->
it "reloads without readding to the stylesheets list", ->
expect(theme.getStylesheetPaths().length).toBe 3
theme.reloadStylesheets()
theme.reloadStylesheet(theme.getStylesheetPaths()[0])
expect(theme.getStylesheetPaths().length).toBe 3
describe "events", ->
-7
Ver Arquivo
@@ -33,13 +33,6 @@ describe "PaneContainer", ->
[pane1B, pane2B, pane3B] = containerB.getPanes()
expect(containerB.getActivePane()).toBe pane3B
it "makes the first pane active if no pane exists for the activePaneId", ->
pane3A.activate()
state = containerA.serialize()
state.activePaneId = -22
containerB = atom.deserializers.deserialize(state)
expect(containerB.getActivePane()).toBe containerB.getPanes()[0]
it "does not allow the root pane to be destroyed", ->
container = new PaneContainer
container.getRoot().destroy()
-49
Ver Arquivo
@@ -146,24 +146,6 @@ describe "Pane", ->
pane.activateNextItem()
expect(pane.getActiveItem()).toBe item1
describe "::moveItemRight() and ::moveItemLeft()", ->
it "moves the active item to the right and left, without looping around at either end", ->
pane = new Pane(items: [new Item("A"), new Item("B"), new Item("C")])
[item1, item2, item3] = pane.getItems()
pane.activateItemAtIndex(0)
expect(pane.getActiveItem()).toBe item1
pane.moveItemLeft()
expect(pane.getItems()).toEqual [item1, item2, item3]
pane.moveItemRight()
expect(pane.getItems()).toEqual [item2, item1, item3]
pane.moveItemLeft()
expect(pane.getItems()).toEqual [item1, item2, item3]
pane.activateItemAtIndex(2)
expect(pane.getActiveItem()).toBe item3
pane.moveItemRight()
expect(pane.getItems()).toEqual [item1, item2, item3]
describe "::activateItemAtIndex(index)", ->
it "activates the item at the given index", ->
pane = new Pane(items: [new Item("A"), new Item("B"), new Item("C")])
@@ -583,37 +565,6 @@ describe "Pane", ->
expect(pane1.isActive()).toBe false
expect(pane2.isActive()).toBe true
describe "::close()", ->
it "prompts to save unsaved items before destroying the pane", ->
pane = new Pane(items: [new Item("A"), new Item("B")])
[item1, item2] = pane.getItems()
item1.shouldPromptToSave = -> true
item1.getUri = -> "/test/path"
item1.save = jasmine.createSpy("save")
spyOn(atom, 'confirm').andReturn(0)
pane.close()
expect(atom.confirm).toHaveBeenCalled()
expect(item1.save).toHaveBeenCalled()
expect(pane.isDestroyed()).toBe true
it "does not destroy the pane if cancel is called", ->
pane = new Pane(items: [new Item("A"), new Item("B")])
[item1, item2] = pane.getItems()
item1.shouldPromptToSave = -> true
item1.getUri = -> "/test/path"
item1.save = jasmine.createSpy("save")
spyOn(atom, 'confirm').andReturn(1)
pane.close()
expect(atom.confirm).toHaveBeenCalled()
expect(item1.save).not.toHaveBeenCalled()
expect(pane.isDestroyed()).toBe false
describe "::destroy()", ->
[container, pane1, pane2] = []
-3
Ver Arquivo
@@ -144,15 +144,12 @@ describe "PaneView", ->
describe "when an item is moved to another pane", ->
it "detaches the item's view rather than removing it", ->
container.attachToDom()
expect(view1.is(':visible')).toBe true
paneModel2 = paneModel.splitRight()
view1.data('preservative', 1234)
paneModel.moveItemToPane(view1, paneModel2, 1)
expect(view1.data('preservative')).toBe 1234
paneModel2.activateItemAtIndex(1)
expect(view1.data('preservative')).toBe 1234
expect(view1.is(':visible')).toBe true
describe "when the title of the active item changes", ->
describe 'when there is no onDidChangeTitle method', ->
+15 -98
Ver Arquivo
@@ -34,8 +34,8 @@ describe "PanelContainerElement", ->
element = container.getView()
jasmineContent.appendChild(element)
it 'has a location class with value from the model', ->
expect(element).toHaveClass 'left'
it 'has a location attribute with value from the model', ->
expect(element.getAttribute('location')).toBe 'left'
it 'removes the element when the container is destroyed', ->
expect(element.parentNode).toBe jasmineContent
@@ -43,104 +43,21 @@ describe "PanelContainerElement", ->
expect(element.parentNode).not.toBe jasmineContent
describe "adding and removing panels", ->
it "allows panels to be inserted at any position", ->
panel1 = new Panel({viewRegistry, item: new TestPanelContainerItem(), priority: 10})
panel2 = new Panel({viewRegistry, item: new TestPanelContainerItem(), priority: 5})
panel3 = new Panel({viewRegistry, item: new TestPanelContainerItem(), priority: 8})
it "adds atom-panel elements when a new panel is added to the container; removes them when the panels are destroyed", ->
expect(element.childNodes.length).toBe 0
panel1 = new Panel({viewRegistry, item: new TestPanelContainerItem(), location: 'left'})
container.addPanel(panel1)
expect(element.childNodes.length).toBe 1
expect(element.childNodes[0].tagName).toBe 'ATOM-PANEL'
panel2 = new Panel({viewRegistry, item: new TestPanelContainerItem(), location: 'left'})
container.addPanel(panel2)
container.addPanel(panel3)
expect(element.childNodes.length).toBe 2
expect(element.childNodes[2].getModel()).toBe(panel1)
expect(element.childNodes[1].getModel()).toBe(panel3)
expect(element.childNodes[0].getModel()).toBe(panel2)
panel1.destroy()
expect(element.childNodes.length).toBe 1
describe "when the container is at the left location", ->
it "adds atom-panel elements when a new panel is added to the container; removes them when the panels are destroyed", ->
expect(element.childNodes.length).toBe 0
panel1 = new Panel({viewRegistry, item: new TestPanelContainerItem()})
container.addPanel(panel1)
expect(element.childNodes.length).toBe 1
expect(element.childNodes[0]).toHaveClass 'left'
expect(element.childNodes[0]).toHaveClass 'tool-panel' # legacy selector support
expect(element.childNodes[0]).toHaveClass 'panel-left' # legacy selector support
expect(element.childNodes[0].tagName).toBe 'ATOM-PANEL'
panel2 = new Panel({viewRegistry, item: new TestPanelContainerItem()})
container.addPanel(panel2)
expect(element.childNodes.length).toBe 2
expect(panel1.getView().style.display).not.toBe 'none'
expect(panel2.getView().style.display).not.toBe 'none'
panel1.destroy()
expect(element.childNodes.length).toBe 1
panel2.destroy()
expect(element.childNodes.length).toBe 0
describe "when the container is at the bottom location", ->
beforeEach ->
container = new PanelContainer({viewRegistry, location: 'bottom'})
element = container.getView()
jasmineContent.appendChild(element)
it "adds atom-panel elements when a new panel is added to the container; removes them when the panels are destroyed", ->
expect(element.childNodes.length).toBe 0
panel1 = new Panel({viewRegistry, item: new TestPanelContainerItem(), className: 'one'})
container.addPanel(panel1)
expect(element.childNodes.length).toBe 1
expect(element.childNodes[0]).toHaveClass 'bottom'
expect(element.childNodes[0]).toHaveClass 'tool-panel' # legacy selector support
expect(element.childNodes[0]).toHaveClass 'panel-bottom' # legacy selector support
expect(element.childNodes[0].tagName).toBe 'ATOM-PANEL'
expect(panel1.getView()).toHaveClass 'one'
panel2 = new Panel({viewRegistry, item: new TestPanelContainerItem(), className: 'two'})
container.addPanel(panel2)
expect(element.childNodes.length).toBe 2
expect(panel2.getView()).toHaveClass 'two'
panel1.destroy()
expect(element.childNodes.length).toBe 1
panel2.destroy()
expect(element.childNodes.length).toBe 0
describe "when the container is modal", ->
beforeEach ->
container = new PanelContainer({viewRegistry, location: 'modal'})
element = container.getView()
jasmineContent.appendChild(element)
it "allows only one panel to be visible at a time", ->
panel1 = new Panel({viewRegistry, item: new TestPanelContainerItem()})
container.addPanel(panel1)
expect(panel1.getView().style.display).not.toBe 'none'
panel2 = new Panel({viewRegistry, item: new TestPanelContainerItem()})
container.addPanel(panel2)
expect(panel1.getView().style.display).toBe 'none'
expect(panel2.getView().style.display).not.toBe 'none'
panel1.show()
expect(panel1.getView().style.display).not.toBe 'none'
expect(panel2.getView().style.display).toBe 'none'
it "adds the 'modal' class to panels", ->
panel1 = new Panel({viewRegistry, item: new TestPanelContainerItem()})
container.addPanel(panel1)
expect(panel1.getView()).toHaveClass 'modal'
# legacy selector support
expect(panel1.getView()).not.toHaveClass 'tool-panel'
expect(panel1.getView()).toHaveClass 'overlay'
expect(panel1.getView()).toHaveClass 'from-top'
panel2.destroy()
expect(element.childNodes.length).toBe 0
-9
Ver Arquivo
@@ -54,12 +54,3 @@ describe "PanelElement", ->
panel.show()
expect(element.style.display).not.toBe 'none'
describe "when a class name is specified", ->
it 'initially renders panel created with visibile: false', ->
panel = new Panel({viewRegistry, className: 'some classes', item: new TestPanelItem})
element = panel.getView()
jasmineContent.appendChild(element)
expect(element).toHaveClass 'some'
expect(element).toHaveClass 'classes'
+1 -1
Ver Arquivo
@@ -184,7 +184,7 @@ describe "SelectListView", ->
describe "when the mini editor loses focus", ->
it "triggers the cancelled hook and detaches the select list", ->
spyOn(selectList, 'detach')
filterEditorView.trigger 'blur'
filterEditorView.hiddenInput.trigger 'focusout'
expect(selectList.cancelled).toHaveBeenCalled()
expect(selectList.detach).toHaveBeenCalled()
+12 -15
Ver Arquivo
@@ -9,8 +9,7 @@ _ = require 'underscore-plus'
fs = require 'fs-plus'
Grim = require 'grim'
KeymapManager = require '../src/keymap-extensions'
Workspace = require '../src/workspace'
{$} = require '../src/space-pen-extensions'
{$, WorkspaceView, Workspace} = require 'atom'
Config = require '../src/config'
{Point} = require 'text-buffer'
Project = require '../src/project'
@@ -83,7 +82,7 @@ beforeEach ->
serializedWindowState = null
spyOn(atom, 'saveSync')
atom.grammars.clearGrammarOverrides()
atom.syntax.clearGrammarOverrides()
spy = spyOn(atom.packages, 'resolvePackagePath').andCallFake (packageName) ->
if specPackageName and packageName is specPackageName
@@ -107,7 +106,6 @@ beforeEach ->
config.set "editor.autoIndent", false
config.set "core.disabledPackages", ["package-that-throws-an-exception",
"package-with-broken-package-json", "package-with-broken-keymap"]
config.set "editor.useShadowDOM", true
config.load.reset()
config.save.reset()
@@ -136,9 +134,8 @@ afterEach ->
atom.menu.template = []
atom.contextMenu.clear()
atom.workspace?.destroy()
atom.workspace = null
atom.__workspaceView = null
atom.workspaceView?.remove?()
atom.workspaceView = null
delete atom.state.workspace
atom.project?.destroy()
@@ -152,7 +149,7 @@ afterEach ->
jasmine.unspy(atom, 'saveSync')
ensureNoPathSubscriptions()
atom.grammars.clearObservers()
atom.syntax.clearObservers()
waits(0) # yield to ui thread to make screen update more frequently
ensureNoPathSubscriptions = ->
@@ -193,10 +190,6 @@ jasmine.unspy = (object, methodName) ->
throw new Error("Not a spy") unless object[methodName].hasOwnProperty('originalValue')
object[methodName] = object[methodName].originalValue
jasmine.attachToDOM = (element) ->
jasmineContent = document.querySelector('#jasmine-content')
jasmineContent.appendChild(element) unless jasmineContent.contains(element)
addCustomMatchers = (spec) ->
spec.addMatchers
toBeInstanceOf: (expected) ->
@@ -226,7 +219,7 @@ addCustomMatchers = (spec) ->
@message = -> return "Expected element '" + @actual + "' or its descendants" + notText + " to have focus."
element = @actual
element = element.get(0) if element.jquery
element is document.activeElement or element.contains(document.activeElement)
element.webkitMatchesSelector(":focus") or element.querySelector(":focus")
toShow: ->
notText = if @isNot then " not" else ""
@@ -345,8 +338,12 @@ window.setEditorWidthInChars = (editorView, widthInChars, charWidth=editorView.c
$(window).trigger 'resize' # update width of editor view's on-screen lines
window.setEditorHeightInLines = (editorView, heightInLines, lineHeight=editorView.lineHeight) ->
editorView.height(editorView.getEditor().getLineHeightInPixels() * heightInLines)
editorView.component?.measureHeightAndWidth()
if editorView.hasClass('react')
editorView.height(editorView.getEditor().getLineHeightInPixels() * heightInLines)
editorView.component?.measureHeightAndWidth()
else
editorView.height(lineHeight * heightInLines + editorView.renderedLines.position().top)
$(window).trigger 'resize' # update editor view's on-screen lines
$.fn.resultOfTrigger = (type) ->
event = $.Event(type)
-53
Ver Arquivo
@@ -52,56 +52,3 @@ describe "StylesElement", ->
expect(element.children.length).toBe initialChildCount + 1
expect(element.children[initialChildCount].textContent).toBe "a {color: blue;}"
expect(updatedStyleElements).toEqual [element.children[initialChildCount]]
it "only includes style elements matching the 'context' attribute", ->
initialChildCount = element.children.length
atom.styles.addStyleSheet("a {color: red;}", context: 'test-context')
atom.styles.addStyleSheet("a {color: green;}")
expect(element.children.length).toBe initialChildCount + 2
expect(element.children[initialChildCount].textContent).toBe "a {color: red;}"
expect(element.children[initialChildCount + 1].textContent).toBe "a {color: green;}"
element.setAttribute('context', 'test-context')
expect(element.children.length).toBe 1
expect(element.children[0].textContent).toBe "a {color: red;}"
atom.styles.addStyleSheet("a {color: blue;}", context: 'test-context')
atom.styles.addStyleSheet("a {color: yellow;}")
expect(element.children.length).toBe 2
expect(element.children[0].textContent).toBe "a {color: red;}"
expect(element.children[1].textContent).toBe "a {color: blue;}"
describe "atom-text-editor shadow DOM selector upgrades", ->
beforeEach ->
element.setAttribute('context', 'atom-text-editor')
spyOn(console, 'warn')
it "upgrades selectors containing .editor-colors", ->
atom.styles.addStyleSheet(".editor-colors {background: black;}", context: 'atom-text-editor')
expect(element.firstChild.sheet.cssRules[0].selectorText).toBe ':host'
it "upgrades selectors containing .editor", ->
atom.styles.addStyleSheet """
.editor {background: black;}
.editor.mini {background: black;}
.editor:focus {background: black;}
""", context: 'atom-text-editor'
expect(element.firstChild.sheet.cssRules[0].selectorText).toBe ':host'
expect(element.firstChild.sheet.cssRules[1].selectorText).toBe ':host(.mini)'
expect(element.firstChild.sheet.cssRules[2].selectorText).toBe ':host(:focus)'
it "defers selector upgrade until the element is attached", ->
element = new StylesElement
element.setAttribute('context', 'atom-text-editor')
element.initialize()
atom.styles.addStyleSheet ".editor {background: black;}", context: 'atom-text-editor'
expect(element.firstChild.sheet).toBeNull()
document.querySelector('#jasmine-content').appendChild(element)
expect(element.firstChild.sheet.cssRules[0].selectorText).toBe ':host'
+45 -45
Ver Arquivo
@@ -23,10 +23,10 @@ describe "the `syntax` global", ->
describe "serialization", ->
it "remembers grammar overrides by path", ->
filePath = '/foo/bar/file.js'
expect(atom.grammars.selectGrammar(filePath).name).not.toBe 'Ruby'
atom.grammars.setGrammarOverrideForPath(filePath, 'source.ruby')
syntax2 = atom.deserializers.deserialize(atom.grammars.serialize())
syntax2.addGrammar(grammar) for grammar in atom.grammars.grammars when grammar isnt atom.grammars.nullGrammar
expect(atom.syntax.selectGrammar(filePath).name).not.toBe 'Ruby'
atom.syntax.setGrammarOverrideForPath(filePath, 'source.ruby')
syntax2 = atom.deserializers.deserialize(atom.syntax.serialize())
syntax2.addGrammar(grammar) for grammar in atom.syntax.grammars when grammar isnt atom.syntax.nullGrammar
expect(syntax2.selectGrammar(filePath).name).toBe 'Ruby'
describe ".selectGrammar(filePath)", ->
@@ -35,15 +35,15 @@ describe "the `syntax` global", ->
atom.packages.activatePackage('language-git')
runs ->
expect(atom.grammars.selectGrammar("file.js").name).toBe "JavaScript" # based on extension (.js)
expect(atom.grammars.selectGrammar(path.join(temp.dir, '.git', 'config')).name).toBe "Git Config" # based on end of the path (.git/config)
expect(atom.grammars.selectGrammar("Rakefile").name).toBe "Ruby" # based on the file's basename (Rakefile)
expect(atom.grammars.selectGrammar("curb").name).toBe "Null Grammar"
expect(atom.grammars.selectGrammar("/hu.git/config").name).toBe "Null Grammar"
expect(atom.syntax.selectGrammar("file.js").name).toBe "JavaScript" # based on extension (.js)
expect(atom.syntax.selectGrammar(path.join(temp.dir, '.git', 'config')).name).toBe "Git Config" # based on end of the path (.git/config)
expect(atom.syntax.selectGrammar("Rakefile").name).toBe "Ruby" # based on the file's basename (Rakefile)
expect(atom.syntax.selectGrammar("curb").name).toBe "Null Grammar"
expect(atom.syntax.selectGrammar("/hu.git/config").name).toBe "Null Grammar"
it "uses the filePath's shebang line if the grammar cannot be determined by the extension or basename", ->
filePath = require.resolve("./fixtures/shebang")
expect(atom.grammars.selectGrammar(filePath).name).toBe "Ruby"
expect(atom.syntax.selectGrammar(filePath).name).toBe "Ruby"
it "uses the number of newlines in the first line regex to determine the number of lines to test against", ->
waitsForPromise ->
@@ -51,28 +51,28 @@ describe "the `syntax` global", ->
runs ->
fileContent = "first-line\n<html>"
expect(atom.grammars.selectGrammar("dummy.coffee", fileContent).name).toBe "CoffeeScript"
expect(atom.syntax.selectGrammar("dummy.coffee", fileContent).name).toBe "CoffeeScript"
fileContent = '<?xml version="1.0" encoding="UTF-8"?>'
expect(atom.grammars.selectGrammar("grammar.tmLanguage", fileContent).name).toBe "Null Grammar"
expect(atom.syntax.selectGrammar("grammar.tmLanguage", fileContent).name).toBe "Null Grammar"
fileContent += '\n<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">'
expect(atom.grammars.selectGrammar("grammar.tmLanguage", fileContent).name).toBe "Property List (XML)"
expect(atom.syntax.selectGrammar("grammar.tmLanguage", fileContent).name).toBe "Property List (XML)"
it "doesn't read the file when the file contents are specified", ->
filePath = require.resolve("./fixtures/shebang")
filePathContents = fs.readFileSync(filePath, 'utf8')
spyOn(fs, 'read').andCallThrough()
expect(atom.grammars.selectGrammar(filePath, filePathContents).name).toBe "Ruby"
expect(atom.syntax.selectGrammar(filePath, filePathContents).name).toBe "Ruby"
expect(fs.read).not.toHaveBeenCalled()
it "allows the default grammar to be overridden for a path", ->
filePath = '/foo/bar/file.js'
expect(atom.grammars.selectGrammar(filePath).name).not.toBe 'Ruby'
atom.grammars.setGrammarOverrideForPath(filePath, 'source.ruby')
expect(atom.grammars.selectGrammar(filePath).name).toBe 'Ruby'
atom.grammars.clearGrammarOverrideForPath(filePath)
expect(atom.grammars.selectGrammar(filePath).name).not.toBe 'Ruby'
expect(atom.syntax.selectGrammar(filePath).name).not.toBe 'Ruby'
atom.syntax.setGrammarOverrideForPath(filePath, 'source.ruby')
expect(atom.syntax.selectGrammar(filePath).name).toBe 'Ruby'
atom.syntax.clearGrammarOverrideForPath(filePath)
expect(atom.syntax.selectGrammar(filePath).name).not.toBe 'Ruby'
describe "when multiple grammars have matching fileTypes", ->
it "selects the grammar with the longest fileType match", ->
@@ -82,8 +82,8 @@ describe "the `syntax` global", ->
scopeName: 'source1'
fileTypes: ['test']
)
grammar1 = atom.grammars.loadGrammarSync(grammarPath1)
expect(atom.grammars.selectGrammar('more.test', '')).toBe grammar1
grammar1 = atom.syntax.loadGrammarSync(grammarPath1)
expect(atom.syntax.selectGrammar('more.test', '')).toBe grammar1
grammarPath2 = temp.path(suffix: '.json')
fs.writeFileSync grammarPath2, JSON.stringify(
@@ -91,44 +91,44 @@ describe "the `syntax` global", ->
scopeName: 'source2'
fileTypes: ['test', 'more.test']
)
grammar2 = atom.grammars.loadGrammarSync(grammarPath2)
expect(atom.grammars.selectGrammar('more.test', '')).toBe grammar2
grammar2 = atom.syntax.loadGrammarSync(grammarPath2)
expect(atom.syntax.selectGrammar('more.test', '')).toBe grammar2
describe "when there is no file path", ->
it "does not throw an exception (regression)", ->
expect(-> atom.grammars.selectGrammar(null, '#!/usr/bin/ruby')).not.toThrow()
expect(-> atom.grammars.selectGrammar(null, '')).not.toThrow()
expect(-> atom.grammars.selectGrammar(null, null)).not.toThrow()
expect(-> atom.syntax.selectGrammar(null, '#!/usr/bin/ruby')).not.toThrow()
expect(-> atom.syntax.selectGrammar(null, '')).not.toThrow()
expect(-> atom.syntax.selectGrammar(null, null)).not.toThrow()
describe ".removeGrammar(grammar)", ->
it "removes the grammar, so it won't be returned by selectGrammar", ->
grammar = atom.grammars.selectGrammar('foo.js')
atom.grammars.removeGrammar(grammar)
expect(atom.grammars.selectGrammar('foo.js').name).not.toBe grammar.name
grammar = atom.syntax.selectGrammar('foo.js')
atom.syntax.removeGrammar(grammar)
expect(atom.syntax.selectGrammar('foo.js').name).not.toBe grammar.name
describe ".getProperty(scopeDescriptor)", ->
it "returns the property with the most specific scope selector", ->
atom.grammars.addProperties(".source.coffee .string.quoted.double.coffee", foo: bar: baz: 42)
atom.grammars.addProperties(".source .string.quoted.double", foo: bar: baz: 22)
atom.grammars.addProperties(".source", foo: bar: baz: 11)
atom.syntax.addProperties(".source.coffee .string.quoted.double.coffee", foo: bar: baz: 42)
atom.syntax.addProperties(".source .string.quoted.double", foo: bar: baz: 22)
atom.syntax.addProperties(".source", foo: bar: baz: 11)
expect(atom.grammars.getProperty([".source.coffee", ".string.quoted.double.coffee"], "foo.bar.baz")).toBe 42
expect(atom.grammars.getProperty([".source.js", ".string.quoted.double.js"], "foo.bar.baz")).toBe 22
expect(atom.grammars.getProperty([".source.js", ".variable.assignment.js"], "foo.bar.baz")).toBe 11
expect(atom.grammars.getProperty([".text"], "foo.bar.baz")).toBeUndefined()
expect(atom.syntax.getProperty([".source.coffee", ".string.quoted.double.coffee"], "foo.bar.baz")).toBe 42
expect(atom.syntax.getProperty([".source.js", ".string.quoted.double.js"], "foo.bar.baz")).toBe 22
expect(atom.syntax.getProperty([".source.js", ".variable.assignment.js"], "foo.bar.baz")).toBe 11
expect(atom.syntax.getProperty([".text"], "foo.bar.baz")).toBeUndefined()
it "favors the most recently added properties in the event of a specificity tie", ->
atom.grammars.addProperties(".source.coffee .string.quoted.single", foo: bar: baz: 42)
atom.grammars.addProperties(".source.coffee .string.quoted.double", foo: bar: baz: 22)
atom.syntax.addProperties(".source.coffee .string.quoted.single", foo: bar: baz: 42)
atom.syntax.addProperties(".source.coffee .string.quoted.double", foo: bar: baz: 22)
expect(atom.grammars.getProperty([".source.coffee", ".string.quoted.single"], "foo.bar.baz")).toBe 42
expect(atom.grammars.getProperty([".source.coffee", ".string.quoted.single.double"], "foo.bar.baz")).toBe 22
expect(atom.syntax.getProperty([".source.coffee", ".string.quoted.single"], "foo.bar.baz")).toBe 42
expect(atom.syntax.getProperty([".source.coffee", ".string.quoted.single.double"], "foo.bar.baz")).toBe 22
describe ".removeProperties(name)", ->
it "allows properties to be removed by name", ->
atom.grammars.addProperties("a", ".source.coffee .string.quoted.double.coffee", foo: bar: baz: 42)
atom.grammars.addProperties("b", ".source .string.quoted.double", foo: bar: baz: 22)
atom.syntax.addProperties("a", ".source.coffee .string.quoted.double.coffee", foo: bar: baz: 42)
atom.syntax.addProperties("b", ".source .string.quoted.double", foo: bar: baz: 22)
atom.grammars.removeProperties("b")
expect(atom.grammars.getProperty([".source.js", ".string.quoted.double.js"], "foo.bar.baz")).toBeUndefined()
expect(atom.grammars.getProperty([".source.coffee", ".string.quoted.double.coffee"], "foo.bar.baz")).toBe 42
atom.syntax.removeProperties("b")
expect(atom.syntax.getProperty([".source.js", ".string.quoted.double.js"], "foo.bar.baz")).toBeUndefined()
expect(atom.syntax.getProperty([".source.coffee", ".string.quoted.double.coffee"], "foo.bar.baz")).toBe 42
+7 -278
Ver Arquivo
@@ -721,11 +721,11 @@ describe "TextEditorComponent", ->
editor.setCursorScreenPosition([0, 16])
nextAnimationFrame()
atom.styles.addStyleSheet """
atom.themes.applyStylesheet 'test', """
.function.js {
font-weight: bold;
}
""", context: 'atom-text-editor'
"""
nextAnimationFrame() # update based on new measurements
cursor = componentNode.querySelector('.cursor')
@@ -1131,13 +1131,6 @@ describe "TextEditorComponent", ->
regions = componentNode.querySelectorAll('.test-highlight .region')
expect(regions.length).toBe 2
it "renders classes on the regions directly if 'deprecatedRegionClass' option is defined", ->
decoration = editor.decorateMarker(marker, type: 'highlight', class: 'test-highlight', deprecatedRegionClass: 'test-highlight-region')
nextAnimationFrame()
regions = componentNode.querySelectorAll('.test-highlight .region.test-highlight-region')
expect(regions.length).toBe 2
describe "when flashing a decoration via Decoration::flash()", ->
highlightNode = null
beforeEach ->
@@ -1203,221 +1196,6 @@ describe "TextEditorComponent", ->
expect(componentNode.querySelector('.test-highlight')).toBeFalsy()
expect(componentNode.querySelector('.new-test-highlight')).toBeTruthy()
describe "overlay decoration rendering", ->
[item] = []
beforeEach ->
item = document.createElement('div')
item.classList.add 'overlay-test'
describe "when the marker is empty", ->
it "renders an overlay decoration when added and removes the overlay when the decoration is destroyed", ->
marker = editor.displayBuffer.markBufferRange([[2, 13], [2, 13]], invalidate: 'never')
decoration = editor.decorateMarker(marker, {type: 'overlay', item})
nextAnimationFrame()
overlay = component.getTopmostDOMNode().querySelector('atom-overlay .overlay-test')
expect(overlay).toBe item
decoration.destroy()
nextAnimationFrame()
overlay = component.getTopmostDOMNode().querySelector('atom-overlay .overlay-test')
expect(overlay).toBe null
it "renders in the correct position on initial display and when the marker moves", ->
editor.setCursorBufferPosition([2, 5])
marker = editor.getLastCursor().getMarker()
decoration = editor.decorateMarker(marker, {type: 'overlay', item})
nextAnimationFrame()
position = editor.pixelPositionForBufferPosition([2, 5])
overlay = component.getTopmostDOMNode().querySelector('atom-overlay')
expect(overlay.style.left).toBe position.left + 'px'
expect(overlay.style.top).toBe position.top + editor.getLineHeightInPixels() + 'px'
editor.moveRight()
editor.moveRight()
nextAnimationFrame()
position = editor.pixelPositionForBufferPosition([2, 7])
expect(overlay.style.left).toBe position.left + 'px'
expect(overlay.style.top).toBe position.top + editor.getLineHeightInPixels() + 'px'
describe "when the marker is not empty", ->
it "renders at the head of the marker", ->
marker = editor.displayBuffer.markBufferRange([[2, 5], [2, 10]], invalidate: 'never')
decoration = editor.decorateMarker(marker, {type: 'overlay', item})
nextAnimationFrame()
position = editor.pixelPositionForBufferPosition([2, 10])
overlay = component.getTopmostDOMNode().querySelector('atom-overlay')
expect(overlay.style.left).toBe position.left + 'px'
expect(overlay.style.top).toBe position.top + editor.getLineHeightInPixels() + 'px'
it "renders at the head of the marker when the marker is reversed", ->
marker = editor.displayBuffer.markBufferRange([[2, 5], [2, 10]], invalidate: 'never', reversed: true)
decoration = editor.decorateMarker(marker, {type: 'overlay', item})
nextAnimationFrame()
position = editor.pixelPositionForBufferPosition([2, 5])
overlay = component.getTopmostDOMNode().querySelector('atom-overlay')
expect(overlay.style.left).toBe position.left + 'px'
expect(overlay.style.top).toBe position.top + editor.getLineHeightInPixels() + 'px'
describe "positioning the overlay when near the edge of the editor", ->
[itemWidth, itemHeight] = []
beforeEach ->
itemWidth = 4 * editor.getDefaultCharWidth()
itemHeight = 4 * editor.getLineHeightInPixels()
gutterWidth = componentNode.querySelector('.gutter').offsetWidth
windowWidth = gutterWidth + 30 * editor.getDefaultCharWidth()
windowHeight = 9 * editor.getLineHeightInPixels()
item.style.width = itemWidth + 'px'
item.style.height = itemHeight + 'px'
wrapperNode.style.width = windowWidth + 'px'
wrapperNode.style.height = windowHeight + 'px'
component.measureHeightAndWidth()
nextAnimationFrame()
it "flips horizontally when near the right edge", ->
marker = editor.displayBuffer.markBufferRange([[0, 26], [0, 26]], invalidate: 'never')
decoration = editor.decorateMarker(marker, {type: 'overlay', item})
nextAnimationFrame()
position = editor.pixelPositionForBufferPosition([0, 26])
overlay = component.getTopmostDOMNode().querySelector('atom-overlay')
expect(overlay.style.left).toBe position.left + 'px'
expect(overlay.style.top).toBe position.top + editor.getLineHeightInPixels() + 'px'
editor.insertText('a')
nextAnimationFrame()
position = editor.pixelPositionForBufferPosition([0, 27])
expect(overlay.style.left).toBe position.left - itemWidth + 'px'
expect(overlay.style.top).toBe position.top + editor.getLineHeightInPixels() + 'px'
it "flips vertically when near the bottom edge", ->
marker = editor.displayBuffer.markBufferRange([[4, 0], [4, 0]], invalidate: 'never')
decoration = editor.decorateMarker(marker, {type: 'overlay', item})
nextAnimationFrame()
position = editor.pixelPositionForBufferPosition([4, 0])
overlay = component.getTopmostDOMNode().querySelector('atom-overlay')
expect(overlay.style.left).toBe position.left + 'px'
expect(overlay.style.top).toBe position.top + editor.getLineHeightInPixels() + 'px'
editor.insertNewline()
nextAnimationFrame()
position = editor.pixelPositionForBufferPosition([5, 0])
expect(overlay.style.left).toBe position.left + 'px'
expect(overlay.style.top).toBe position.top - itemHeight + 'px'
describe "when the editor is very small", ->
beforeEach ->
gutterWidth = componentNode.querySelector('.gutter').offsetWidth
windowWidth = gutterWidth + 6 * editor.getDefaultCharWidth()
windowHeight = 6 * editor.getLineHeightInPixels()
wrapperNode.style.width = windowWidth + 'px'
wrapperNode.style.height = windowHeight + 'px'
component.measureHeightAndWidth()
nextAnimationFrame()
it "does not flip horizontally and force the overlay to have a negative left", ->
marker = editor.displayBuffer.markBufferRange([[0, 2], [0, 2]], invalidate: 'never')
decoration = editor.decorateMarker(marker, {type: 'overlay', item})
nextAnimationFrame()
position = editor.pixelPositionForBufferPosition([0, 2])
overlay = component.getTopmostDOMNode().querySelector('atom-overlay')
expect(overlay.style.left).toBe position.left + 'px'
expect(overlay.style.top).toBe position.top + editor.getLineHeightInPixels() + 'px'
editor.insertText('a')
nextAnimationFrame()
position = editor.pixelPositionForBufferPosition([0, 3])
expect(overlay.style.left).toBe position.left + 'px'
expect(overlay.style.top).toBe position.top + editor.getLineHeightInPixels() + 'px'
it "does not flip vertically and force the overlay to have a negative top", ->
marker = editor.displayBuffer.markBufferRange([[1, 0], [1, 0]], invalidate: 'never')
decoration = editor.decorateMarker(marker, {type: 'overlay', item})
nextAnimationFrame()
position = editor.pixelPositionForBufferPosition([1, 0])
overlay = component.getTopmostDOMNode().querySelector('atom-overlay')
expect(overlay.style.left).toBe position.left + 'px'
expect(overlay.style.top).toBe position.top + editor.getLineHeightInPixels() + 'px'
editor.insertNewline()
nextAnimationFrame()
position = editor.pixelPositionForBufferPosition([2, 0])
expect(overlay.style.left).toBe position.left + 'px'
expect(overlay.style.top).toBe position.top + editor.getLineHeightInPixels() + 'px'
describe "when editor scroll position is not 0", ->
it "flips horizontally when near the right edge", ->
editor.setScrollLeft(2 * editor.getDefaultCharWidth())
marker = editor.displayBuffer.markBufferRange([[0, 28], [0, 28]], invalidate: 'never')
decoration = editor.decorateMarker(marker, {type: 'overlay', item})
nextAnimationFrame()
position = editor.pixelPositionForBufferPosition([0, 28])
overlay = component.getTopmostDOMNode().querySelector('atom-overlay')
expect(overlay.style.left).toBe position.left + 'px'
expect(overlay.style.top).toBe position.top + editor.getLineHeightInPixels() + 'px'
editor.insertText('a')
nextAnimationFrame()
position = editor.pixelPositionForBufferPosition([0, 29])
expect(overlay.style.left).toBe position.left - itemWidth + 'px'
expect(overlay.style.top).toBe position.top + editor.getLineHeightInPixels() + 'px'
it "flips vertically when near the bottom edge", ->
editor.setScrollTop(2 * editor.getLineHeightInPixels())
marker = editor.displayBuffer.markBufferRange([[6, 0], [6, 0]], invalidate: 'never')
decoration = editor.decorateMarker(marker, {type: 'overlay', item})
nextAnimationFrame()
position = editor.pixelPositionForBufferPosition([6, 0])
overlay = component.getTopmostDOMNode().querySelector('atom-overlay')
expect(overlay.style.left).toBe position.left + 'px'
expect(overlay.style.top).toBe position.top + editor.getLineHeightInPixels() + 'px'
editor.insertNewline()
nextAnimationFrame()
position = editor.pixelPositionForBufferPosition([7, 0])
expect(overlay.style.left).toBe position.left + 'px'
expect(overlay.style.top).toBe position.top - itemHeight + 'px'
describe "hidden input field", ->
it "renders the hidden input field at the position of the last cursor if the cursor is on screen and the editor is focused", ->
editor.setVerticalScrollMargin(0)
@@ -1759,9 +1537,8 @@ describe "TextEditorComponent", ->
it "transfers focus to the hidden input", ->
expect(document.activeElement).toBe document.body
wrapperNode.focus()
expect(document.activeElement).toBe wrapperNode
expect(wrapperNode.shadowRoot.activeElement).toBe inputNode
componentNode.focus()
expect(document.activeElement).toBe inputNode
it "adds the 'is-focused' class to the editor when the hidden input is focused", ->
expect(document.activeElement).toBe document.body
@@ -1890,13 +1667,12 @@ describe "TextEditorComponent", ->
component.measureHeightAndWidth()
nextAnimationFrame()
atom.styles.addStyleSheet """
atom.themes.applyStylesheet "test", """
::-webkit-scrollbar {
width: 8px;
height: 8px;
}
""", context: 'atom-text-editor'
"""
nextAnimationFrame()
scrollbarCornerNode = componentNode.querySelector('.scrollbar-corner')
@@ -2146,31 +1922,6 @@ describe "TextEditorComponent", ->
expect(nextAnimationFrame).toBe noAnimationFrame
expect(editor.lineTextForBufferRow(0)).toBe 'var quicksort = function () {'
it "groups events that occur close together in time into single undo entries", ->
currentTime = 0
spyOn(Date, 'now').andCallFake -> currentTime
atom.config.set('editor.undoGroupingInterval', 100)
editor.setText("")
componentNode.dispatchEvent(buildTextInputEvent(data: 'x', target: inputNode))
currentTime += 99
componentNode.dispatchEvent(buildTextInputEvent(data: 'y', target: inputNode))
currentTime += 99
componentNode.dispatchEvent(new CustomEvent('editor:duplicate-lines', bubbles: true, cancelable: true))
currentTime += 100
componentNode.dispatchEvent(new CustomEvent('editor:duplicate-lines', bubbles: true, cancelable: true))
expect(editor.getText()).toBe "xy\nxy\nxy"
componentNode.dispatchEvent(new CustomEvent('core:undo', bubbles: true, cancelable: true))
expect(editor.getText()).toBe "xy\nxy"
componentNode.dispatchEvent(new CustomEvent('core:undo', bubbles: true, cancelable: true))
expect(editor.getText()).toBe ""
describe "when IME composition is used to insert international characters", ->
inputNode = null
@@ -2532,7 +2283,7 @@ describe "TextEditorComponent", ->
describe "grammar data attributes", ->
it "adds and updates the grammar data attribute based on the current grammar", ->
expect(wrapperNode.dataset.grammar).toBe 'source js'
editor.setGrammar(atom.grammars.nullGrammar)
editor.setGrammar(atom.syntax.nullGrammar)
expect(wrapperNode.dataset.grammar).toBe 'text plain null-grammar'
describe "encoding data attributes", ->
@@ -2684,28 +2435,6 @@ describe "TextEditorComponent", ->
expect(line1LeafNodes[0].classList.contains('indent-guide')).toBe false
expect(line1LeafNodes[1].classList.contains('indent-guide')).toBe false
describe "middle mouse paste on Linux", ->
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')
atom.clipboard.write('')
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))
expect(atom.clipboard.read()).toBe 'sort'
expect(editor.lineTextForBufferRow(10)).toBe 'sort'
buildMouseEvent = (type, properties...) ->
properties = extend({bubbles: true, cancelable: true}, properties...)
properties.detail ?= 1
+11 -75
Ver Arquivo
@@ -1,5 +1,4 @@
TextEditorElement = require '../src/text-editor-element'
TextEditor = require '../src/text-editor'
# The rest of text-editor-component-spec will be moved to this file when React
# is eliminated. This covers only concerns related to the wrapper element for now
@@ -20,81 +19,18 @@ describe "TextEditorElement", ->
element = jasmineContent.firstChild
expect(element.getModel().getPlaceholderText()).toBe 'testing'
describe "when the model is assigned", ->
it "adds the 'mini' attribute if .isMini() returns true on the model", ->
describe "::focus()", ->
it "transfers focus to the hidden text area and does not emit 'focusout' or 'blur' events", ->
element = new TextEditorElement
model = new TextEditor(mini: true)
element.setModel(model)
expect(element.hasAttribute('mini')).toBe true
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", ->
atom.config.set('editor.useShadowDOM', true)
element = new TextEditorElement
jasmineContent.appendChild(element)
blurCalled = false
element.addEventListener 'blur', -> blurCalled = true
element.focus()
expect(blurCalled).toBe false
expect(element.hasFocus()).toBe true
expect(document.activeElement).toBe element
expect(element.shadowRoot.activeElement).toBe element.shadowRoot.querySelector('input')
document.body.focus()
expect(blurCalled).toBe true
describe "when the editor.useShadowDOM config option is false", ->
it "proxies focus/blur events to/from the hidden input", ->
atom.config.set('editor.useShadowDOM', false)
element = new TextEditorElement
jasmineContent.appendChild(element)
blurCalled = false
element.addEventListener 'blur', -> blurCalled = true
element.focus()
expect(blurCalled).toBe false
expect(element.hasFocus()).toBe true
expect(document.activeElement).toBe element.querySelector('input')
document.body.focus()
expect(blurCalled).toBe true
describe "when the themes finish loading", ->
[themeReloadCallback, initialThemeLoadComplete, element] = []
beforeEach ->
themeReloadCallback = null
initialThemeLoadComplete = false
spyOn(atom.themes, 'isInitialLoadComplete').andCallFake ->
initialThemeLoadComplete
spyOn(atom.themes, 'onDidReloadAll').andCallFake (fn) ->
themeReloadCallback = fn
atom.config.set("editor.useShadowDOM", false)
element = new TextEditorElement()
element.style.height = '200px'
element.getModel().setText [0..20].join("\n")
it "re-renders the scrollbar", ->
jasmineContent.appendChild(element)
atom.styles.addStyleSheet """
::-webkit-scrollbar {
width: 8px;
}
"""
focusoutCalled = false
element.addEventListener 'focusout', -> focusoutCalled = true
blurCalled = false
element.addEventListener 'blur', -> blurCalled = true
initialThemeLoadComplete = true
themeReloadCallback()
verticalScrollbarNode = element.querySelector(".vertical-scrollbar")
scrollbarWidth = verticalScrollbarNode.offsetWidth - verticalScrollbarNode.clientWidth
expect(scrollbarWidth).toEqual(8)
element.focus()
expect(focusoutCalled).toBe false
expect(blurCalled).toBe false
expect(element.hasFocus()).toBe true
expect(element.querySelector('input')).toBe document.activeElement
+245 -356
Ver Arquivo
@@ -98,13 +98,12 @@ describe "TextEditor", ->
expect(editor2.isFoldedAtBufferRow(4)).not.toBe editor.isFoldedAtBufferRow(4)
describe "config defaults", ->
it "uses the `editor.tabLength`, `editor.softWrap`, and `editor.softTabs`, and `core.fileEncoding` config values", ->
it "uses the `editor.tabLength`, `editor.softWrap`, and `editor.softTabs` config values", ->
editor1 = null
editor2 = null
atom.config.set('editor.tabLength', 4)
atom.config.set('editor.softWrap', true)
atom.config.set('editor.softTabs', false)
atom.config.set('core.fileEncoding', 'utf16le')
waitsForPromise ->
atom.workspace.open('a').then (o) -> editor1 = o
@@ -113,12 +112,10 @@ describe "TextEditor", ->
expect(editor1.getTabLength()).toBe 4
expect(editor1.isSoftWrapped()).toBe true
expect(editor1.getSoftTabs()).toBe false
expect(editor1.getEncoding()).toBe 'utf16le'
atom.config.set('editor.tabLength', 8)
atom.config.set('editor.softWrap', false)
atom.config.set('editor.softTabs', true)
atom.config.set('core.fileEncoding', 'macroman')
waitsForPromise ->
atom.workspace.open('b').then (o) -> editor2 = o
@@ -127,7 +124,6 @@ describe "TextEditor", ->
expect(editor2.getTabLength()).toBe 8
expect(editor2.isSoftWrapped()).toBe false
expect(editor2.getSoftTabs()).toBe true
expect(editor2.getEncoding()).toBe 'macroman'
describe "title", ->
describe ".getTitle()", ->
@@ -1162,21 +1158,6 @@ describe "TextEditor", ->
editor.selectLinesContainingCursors()
expect(editor.getSelectedBufferRange()).toEqual [[0,0], [2,0]]
it "autoscrolls to the selection", ->
editor.manageScrollPosition = true
editor.setLineHeightInPixels(10)
editor.setDefaultCharWidth(10)
editor.setHeight(50)
editor.setWidth(50)
editor.setHorizontalScrollbarHeight(0)
editor.setCursorScreenPosition([5, 6])
editor.scrollToTop()
expect(editor.getScrollTop()).toBe 0
editor.selectLinesContainingCursors()
expect(editor.getScrollBottom()).toBe (7 + editor.getVerticalScrollMargin()) * 10
describe ".selectToBeginningOfWord()", ->
it "selects text from cusor position to beginning of word", ->
editor.setCursorScreenPosition [0,13]
@@ -1824,16 +1805,6 @@ describe "TextEditor", ->
expect(willInsertSpy).toHaveBeenCalled()
expect(didInsertSpy).not.toHaveBeenCalled()
describe "when the undo option is set to 'skip'", ->
beforeEach ->
editor.setSelectedBufferRange([[1, 2], [1, 2]])
it "does not undo the skipped operation", ->
range = editor.insertText('x')
range = editor.insertText('y', undo: 'skip')
editor.undo()
expect(buffer.lineForRow(1)).toBe ' yvar sort = function(items) {'
describe ".insertNewline()", ->
describe "when there is a single cursor", ->
describe "when the cursor is at the beginning of a line", ->
@@ -2477,33 +2448,17 @@ describe "TextEditor", ->
expect(editor.getCursorScreenPosition()).toEqual [0, editor.getTabLength() * 2]
describe "clipboard operations", ->
beforeEach ->
editor.setSelectedBufferRanges([[[0, 4], [0, 13]], [[1, 6], [1, 10]]])
describe ".cutSelectedText()", ->
it "removes the selected text from the buffer and places it on the clipboard", ->
editor.setSelectedBufferRanges([[[0, 4], [0, 13]], [[1, 6], [1, 10]]])
editor.cutSelectedText()
expect(buffer.lineForRow(0)).toBe "var = function () {"
expect(buffer.lineForRow(1)).toBe " var = function(items) {"
expect(clipboard.readText()).toBe 'quicksort\nsort'
describe "when no text is selected", ->
beforeEach ->
editor.setSelectedBufferRanges([
[[0, 0], [0, 0]],
[[5, 0], [5, 0]],
])
it "cuts the lines on which there are cursors", ->
editor.cutSelectedText()
expect(buffer.getLineCount()).toBe(11)
expect(buffer.lineForRow(1)).toBe(" if (items.length <= 1) return items;")
expect(buffer.lineForRow(4)).toBe(" current < pivot ? left.push(current) : right.push(current);")
expect(atom.clipboard.read()).toEqual """
var quicksort = function () {
current = items.shift();
"""
describe ".cutToEndOfLine()", ->
describe "when soft wrap is on", ->
it "cuts up to the end of the line", ->
@@ -2542,165 +2497,37 @@ describe "TextEditor", ->
expect(buffer.lineForRow(1)).toBe " var sort = function(items) {"
expect(buffer.lineForRow(2)).toBe " if (items.length <= 1) return items;"
expect(clipboard.readText()).toBe 'quicksort\nsort\nitems'
expect(atom.clipboard.read()).toEqual """
quicksort
sort
items
"""
describe "when no text is selected", ->
beforeEach ->
editor.setSelectedBufferRanges([
[[1, 5], [1, 5]],
[[5, 8], [5, 8]]
])
it "copies the lines on which there are cursors", ->
editor.copySelectedText()
expect(atom.clipboard.read()).toEqual([
" var sort = function(items) {\n"
" current = items.shift();\n"
].join("\n"))
expect(editor.getSelectedBufferRanges()).toEqual([
[[1, 5], [1, 5]],
[[5, 8], [5, 8]]
])
expect(atom.clipboard.readWithMetadata().metadata.selections).toEqual([
'quicksort'
'sort'
'items'
])
describe ".pasteText()", ->
copyText = (text, {startColumn, textEditor}={}) ->
startColumn ?= 0
textEditor ?= editor
textEditor.setCursorBufferPosition([0, 0])
textEditor.insertText(text)
numberOfNewlines = text.match(/\n/g)?.length
endColumn = text.match(/[^\n]*$/)[0]?.length
textEditor.getLastSelection().setBufferRange([[0,startColumn], [numberOfNewlines,endColumn]])
textEditor.cutSelectedText()
it "pastes text into the buffer", ->
editor.setSelectedBufferRanges([[[0, 4], [0, 13]], [[1, 6], [1, 10]]])
atom.clipboard.write('first')
editor.pasteText()
expect(editor.lineTextForBufferRow(0)).toBe "var first = function () {"
expect(editor.lineTextForBufferRow(1)).toBe " var first = function(items) {"
describe "when `autoIndentOnPaste` is true", ->
beforeEach ->
atom.config.set("editor.autoIndentOnPaste", true)
describe "when only whitespace precedes the cursor", ->
it "auto-indents the lines spanned by the pasted text", ->
atom.clipboard.write("console.log(x);\nconsole.log(y);\n")
editor.setCursorBufferPosition([5, 2])
editor.pasteText()
expect(editor.lineTextForBufferRow(5)).toBe(" console.log(x);")
expect(editor.lineTextForBufferRow(6)).toBe(" console.log(y);")
describe "when non-whitespace characters precede the cursor", ->
it "does not auto-indent the first line being pasted", ->
editor.setText """
if (x) {
y();
}
"""
atom.clipboard.write(" z();")
editor.setCursorBufferPosition([1, Infinity])
editor.pasteText()
expect(editor.lineTextForBufferRow(1)).toBe(" y(); z();")
describe "when `autoIndentOnPaste` is false", ->
beforeEach ->
atom.config.set('editor.autoIndentOnPaste', false)
describe "when the cursor is indented further than the original copied text", ->
it "increases the indentation of the copied lines to match", ->
editor.setSelectedBufferRange([[1, 2], [3, 0]])
editor.copySelectedText()
editor.setCursorBufferPosition([5, 6])
editor.pasteText()
expect(editor.lineTextForBufferRow(5)).toBe " var sort = function(items) {"
expect(editor.lineTextForBufferRow(6)).toBe " if (items.length <= 1) return items;"
describe "when the cursor is indented less far than the original copied text", ->
it "decreases the indentation of the copied lines to match", ->
editor.setSelectedBufferRange([[6, 6], [8, 0]])
editor.copySelectedText()
editor.setCursorBufferPosition([1, 2])
editor.pasteText()
expect(editor.lineTextForBufferRow(1)).toBe " current < pivot ? left.push(current) : right.push(current);"
expect(editor.lineTextForBufferRow(2)).toBe "}"
describe "when the first copied line has leading whitespace", ->
it "preserves the line's leading whitespace", ->
editor.setSelectedBufferRange([[4, 0], [6, 0]])
editor.copySelectedText()
editor.setCursorBufferPosition([0, 0])
editor.pasteText()
expect(editor.lineTextForBufferRow(0)).toBe " while(items.length > 0) {"
expect(editor.lineTextForBufferRow(1)).toBe " current = items.shift();"
describe 'when the clipboard has many selections', ->
beforeEach ->
atom.config.set("editor.autoIndentOnPaste", false)
editor.setSelectedBufferRanges([[[0, 4], [0, 13]], [[1, 6], [1, 10]]])
editor.copySelectedText()
it "pastes each selection separately into the buffer", ->
editor.copySelectedText()
editor.moveRight()
editor.insertText("_")
atom.clipboard.write('first\nsecond', {selections: ['first', 'second'] })
editor.pasteText()
expect(editor.lineTextForBufferRow(0)).toBe "var quicksort_quicksort = function () {"
expect(editor.lineTextForBufferRow(1)).toBe " var sort_sort = function(items) {"
expect(editor.lineTextForBufferRow(0)).toBe "var first = function () {"
expect(editor.lineTextForBufferRow(1)).toBe " var second = function(items) {"
describe 'and the selections count does not match', ->
beforeEach ->
editor.setSelectedBufferRanges([[[0, 4], [0, 13]]])
it "pastes the whole text into the buffer", ->
atom.clipboard.write('first\nsecond\nthird', {selections: ['first', 'second', 'third'] })
editor.pasteText()
expect(editor.lineTextForBufferRow(0)).toBe "var quicksort"
expect(editor.lineTextForBufferRow(1)).toBe "sort = function () {"
expect(editor.lineTextForBufferRow(0)).toBe "var first"
expect(editor.lineTextForBufferRow(1)).toBe "second"
expect(editor.lineTextForBufferRow(2)).toBe "third = function () {"
describe "when a full line was cut", ->
beforeEach ->
editor.setCursorBufferPosition([2, 13])
editor.cutSelectedText()
editor.setCursorBufferPosition([2, 13])
it "pastes the line above the cursor and retains the cursor's column", ->
editor.pasteText()
expect(editor.lineTextForBufferRow(2)).toBe(" if (items.length <= 1) return items;")
expect(editor.lineTextForBufferRow(3)).toBe(" var pivot = items.shift(), current, left = [], right = [];")
expect(editor.getCursorBufferPosition()).toEqual([3, 13])
describe "when a full line was copied", ->
beforeEach ->
editor.setCursorBufferPosition([2, 13])
editor.copySelectedText()
describe "when there is a selection", ->
it "overwrites the selection as with any copied text", ->
editor.setSelectedBufferRange([[1, 2], [1, Infinity]])
editor.pasteText()
expect(editor.lineTextForBufferRow(1)).toBe(" if (items.length <= 1) return items;")
expect(editor.lineTextForBufferRow(2)).toBe(" ")
expect(editor.lineTextForBufferRow(3)).toBe(" if (items.length <= 1) return items;")
expect(editor.getCursorBufferPosition()).toEqual([2, 2])
describe "when there is no selection", ->
it "pastes the line above the cursor and retains the cursor's column", ->
editor.pasteText()
expect(editor.lineTextForBufferRow(2)).toBe(" if (items.length <= 1) return items;")
expect(editor.lineTextForBufferRow(3)).toBe(" if (items.length <= 1) return items;")
expect(editor.getCursorBufferPosition()).toEqual([3, 13])
expect(editor.lineTextForBufferRow(3)).toBe " var first"
expect(editor.lineTextForBufferRow(4)).toBe "second"
expect(editor.lineTextForBufferRow(5)).toBe "third = function(items) {"
describe ".indentSelectedRows()", ->
describe "when nothing is selected", ->
@@ -2831,18 +2658,6 @@ describe "TextEditor", ->
expect(editor.getSelectedBufferRange()).toEqual [[0, 1], [3, 0]]
describe ".autoIndentSelectedRows", ->
it "auto-indents the selection", ->
editor.setCursorBufferPosition([2, 0])
editor.insertText("function() {\ninside=true\n}\n i=1\n")
editor.getLastSelection().setBufferRange([[2,0], [6,0]])
editor.autoIndentSelectedRows()
expect(editor.lineTextForBufferRow(2)).toBe " function() {"
expect(editor.lineTextForBufferRow(3)).toBe " inside=true"
expect(editor.lineTextForBufferRow(4)).toBe " }"
expect(editor.lineTextForBufferRow(5)).toBe " i=1"
describe ".toggleLineCommentsInSelection()", ->
it "toggles comments on the selected lines", ->
editor.setSelectedBufferRange([[4, 5], [7, 5]])
@@ -3285,11 +3100,6 @@ describe "TextEditor", ->
expect(editor.getTabLength()).toBe 6
expect(editor.tokenizedLineForScreenRow(5).tokens[0].firstNonWhitespaceIndex).toBe 6
changeHandler = jasmine.createSpy('changeHandler')
editor.onDidChange(changeHandler)
editor.setTabLength(6)
expect(changeHandler).not.toHaveBeenCalled()
it 'retokenizes when the editor.tabLength setting is updated', ->
expect(editor.getTabLength()).toBe 2
expect(editor.tokenizedLineForScreenRow(5).tokens[0].firstNonWhitespaceIndex).toBe 2
@@ -3332,159 +3142,251 @@ describe "TextEditor", ->
it "switches to the better-matched grammar and re-tokenizes the buffer", ->
editor.destroy()
jsGrammar = atom.grammars.selectGrammar('a.js')
atom.grammars.removeGrammar(jsGrammar)
jsGrammar = atom.syntax.selectGrammar('a.js')
atom.syntax.removeGrammar(jsGrammar)
waitsForPromise ->
atom.workspace.open('sample.js', autoIndent: false).then (o) -> editor = o
runs ->
expect(editor.getGrammar()).toBe atom.grammars.nullGrammar
expect(editor.getGrammar()).toBe atom.syntax.nullGrammar
expect(editor.tokenizedLineForScreenRow(0).tokens.length).toBe 1
atom.grammars.addGrammar(jsGrammar)
atom.syntax.addGrammar(jsGrammar)
expect(editor.getGrammar()).toBe jsGrammar
expect(editor.tokenizedLineForScreenRow(0).tokens.length).toBeGreaterThan 1
describe "editor.autoIndent", ->
describe "when editor.autoIndent is false (default)", ->
describe "when `indent` is triggered", ->
it "does not auto-indent the line", ->
editor.setCursorBufferPosition([1, 30])
editor.insertText("\n ")
expect(editor.lineTextForBufferRow(2)).toBe " "
describe "auto-indent", ->
copyText = (text, {startColumn, textEditor}={}) ->
startColumn ?= 0
textEditor ?= editor
textEditor.setCursorBufferPosition([0, 0])
textEditor.insertText(text)
numberOfNewlines = text.match(/\n/g)?.length
endColumn = text.match(/[^\n]*$/)[0]?.length
textEditor.getLastSelection().setBufferRange([[0,startColumn], [numberOfNewlines,endColumn]])
textEditor.cutSelectedText()
atom.config.set("editor.autoIndent", false)
editor.indent()
expect(editor.lineTextForBufferRow(2)).toBe " "
describe "editor.autoIndent", ->
describe "when editor.autoIndent is false (default)", ->
describe "when `indent` is triggered", ->
it "does not auto-indent the line", ->
editor.setCursorBufferPosition([1, 30])
editor.insertText("\n ")
expect(editor.lineTextForBufferRow(2)).toBe " "
describe "when editor.autoIndent is true", ->
beforeEach ->
atom.config.set("editor.autoIndent", true)
describe "when `indent` is triggered", ->
it "auto-indents the line", ->
editor.setCursorBufferPosition([1, 30])
editor.insertText("\n ")
expect(editor.lineTextForBufferRow(2)).toBe " "
atom.config.set("editor.autoIndent", false)
editor.indent()
expect(editor.lineTextForBufferRow(2)).toBe " "
describe "when editor.autoIndent is true", ->
beforeEach ->
atom.config.set("editor.autoIndent", true)
editor.indent()
describe "when `indent` is triggered", ->
it "auto-indents the line", ->
editor.setCursorBufferPosition([1, 30])
editor.insertText("\n ")
expect(editor.lineTextForBufferRow(2)).toBe " "
atom.config.set("editor.autoIndent", true)
editor.indent()
expect(editor.lineTextForBufferRow(2)).toBe " "
describe "when a newline is added", ->
describe "when the line preceding the newline adds a new level of indentation", ->
it "indents the newline to one additional level of indentation beyond the preceding line", ->
editor.setCursorBufferPosition([1, Infinity])
editor.insertText('\n')
expect(editor.indentationForBufferRow(2)).toBe editor.indentationForBufferRow(1) + 1
describe "when the line preceding the newline does't add a level of indentation", ->
it "indents the new line to the same level a as the preceding line", ->
editor.setCursorBufferPosition([5, 14])
editor.insertText('\n')
expect(editor.indentationForBufferRow(6)).toBe editor.indentationForBufferRow(5)
describe "when the line preceding the newline is a comment", ->
it "maintains the indent of the commented line", ->
editor.setCursorBufferPosition([0, 0])
editor.insertText(' //')
editor.setCursorBufferPosition([0, Infinity])
editor.insertText('\n')
expect(editor.indentationForBufferRow(1)).toBe 2
it "does not indent the line preceding the newline", ->
editor.setCursorBufferPosition([2, 0])
editor.insertText(' var this-line-should-be-indented-more\n')
expect(editor.indentationForBufferRow(1)).toBe 1
atom.config.set("editor.autoIndent", true)
editor.setCursorBufferPosition([2, Infinity])
editor.insertText('\n')
expect(editor.indentationForBufferRow(1)).toBe 1
expect(editor.indentationForBufferRow(2)).toBe 1
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, 23])
editor.insertNewline()
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", ->
describe "when the preceding line matches an increase indent pattern", ->
it "decreases the indentation to match that of the preceding line", ->
editor.setCursorBufferPosition([1, Infinity])
editor.insertText('\n')
expect(editor.indentationForBufferRow(2)).toBe editor.indentationForBufferRow(1) + 1
editor.insertText('}')
expect(editor.indentationForBufferRow(2)).toBe editor.indentationForBufferRow(1)
describe "when the preceding line doesn't match an increase indent pattern", ->
it "decreases the indentation to be one level below that of the preceding line", ->
editor.setCursorBufferPosition([3, Infinity])
editor.insertText('\n ')
expect(editor.indentationForBufferRow(4)).toBe editor.indentationForBufferRow(3)
editor.insertText('}')
expect(editor.indentationForBufferRow(4)).toBe editor.indentationForBufferRow(3) - 1
it "doesn't break when decreasing the indentation on a row that has no indentation", ->
editor.setCursorBufferPosition([12, Infinity])
editor.insertText("\n}; # too many closing brackets!")
expect(editor.lineTextForBufferRow(13)).toBe "}; # too many closing brackets!"
describe "when inserted text does not match a decrease indent pattern", ->
it "does not decrease the indentation", ->
editor.setCursorBufferPosition([12, 0])
editor.insertText(' ')
expect(editor.lineTextForBufferRow(12)).toBe ' };'
editor.insertText('\t\t')
expect(editor.lineTextForBufferRow(12)).toBe ' \t\t};'
describe "when the current line does not match a decrease indent pattern", ->
it "leaves the line unchanged", ->
editor.setCursorBufferPosition([2, 4])
expect(editor.indentationForBufferRow(2)).toBe editor.indentationForBufferRow(1) + 1
editor.insertText('foo')
expect(editor.indentationForBufferRow(2)).toBe editor.indentationForBufferRow(1) + 1
describe 'when scoped settings are used', ->
coffeeEditor = null
beforeEach ->
waitsForPromise ->
atom.packages.activatePackage('language-coffee-script')
waitsForPromise ->
atom.project.open('coffee.coffee', autoIndent: false).then (o) -> coffeeEditor = o
runs ->
atom.config.set('.source.js', 'editor.autoIndent', true)
atom.config.set('.source.coffee', 'editor.autoIndent', false)
afterEach: ->
atom.packages.deactivatePackages()
atom.packages.unloadPackages()
it "does not auto-indent the line for javascript files", ->
editor.setCursorBufferPosition([1, 30])
editor.insertText("\n")
expect(editor.lineTextForBufferRow(2)).toBe " "
describe "when a newline is added", ->
describe "when the line preceding the newline adds a new level of indentation", ->
it "indents the newline to one additional level of indentation beyond the preceding line", ->
editor.setCursorBufferPosition([1, Infinity])
editor.insertText('\n')
expect(editor.indentationForBufferRow(2)).toBe editor.indentationForBufferRow(1) + 1
coffeeEditor.setCursorBufferPosition([1, 18])
coffeeEditor.insertText("\n")
expect(coffeeEditor.lineTextForBufferRow(2)).toBe ""
describe "when the line preceding the newline does't add a level of indentation", ->
it "indents the new line to the same level a as the preceding line", ->
editor.setCursorBufferPosition([5, 14])
editor.insertText('\n')
expect(editor.indentationForBufferRow(6)).toBe editor.indentationForBufferRow(5)
describe "when the line preceding the newline is a comment", ->
it "maintains the indent of the commented line", ->
editor.setCursorBufferPosition([0, 0])
editor.insertText(' //')
editor.setCursorBufferPosition([0, Infinity])
editor.insertText('\n')
expect(editor.indentationForBufferRow(1)).toBe 2
describe "when the line preceding the newline contains only whitespace", ->
it "bases the new line's indentation on only the preceding line", ->
editor.setCursorBufferPosition([6, Infinity])
editor.insertText("\n ")
expect(editor.getCursorBufferPosition()).toEqual([7, 2])
editor.insertNewline()
editor.logScreenLines()
expect(editor.lineTextForBufferRow(8)).toBe(" ")
it "does not indent the line preceding the newline", ->
editor.setCursorBufferPosition([2, 0])
editor.insertText(' var this-line-should-be-indented-more\n')
expect(editor.indentationForBufferRow(1)).toBe 1
atom.config.set("editor.autoIndent", true)
editor.setCursorBufferPosition([2, Infinity])
editor.insertText('\n')
expect(editor.indentationForBufferRow(1)).toBe 1
expect(editor.indentationForBufferRow(2)).toBe 1
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, 23])
editor.insertNewline()
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", ->
describe "when the preceding line matches an increase indent pattern", ->
it "decreases the indentation to match that of the preceding line", ->
editor.setCursorBufferPosition([1, Infinity])
editor.insertText('\n')
expect(editor.indentationForBufferRow(2)).toBe editor.indentationForBufferRow(1) + 1
editor.insertText('}')
expect(editor.indentationForBufferRow(2)).toBe editor.indentationForBufferRow(1)
describe "when the preceding line doesn't match an increase indent pattern", ->
it "decreases the indentation to be one level below that of the preceding line", ->
editor.setCursorBufferPosition([3, Infinity])
editor.insertText('\n ')
expect(editor.indentationForBufferRow(4)).toBe editor.indentationForBufferRow(3)
editor.insertText('}')
expect(editor.indentationForBufferRow(4)).toBe editor.indentationForBufferRow(3) - 1
it "doesn't break when decreasing the indentation on a row that has no indentation", ->
editor.setCursorBufferPosition([12, Infinity])
editor.insertText("\n}; # too many closing brackets!")
expect(editor.lineTextForBufferRow(13)).toBe "}; # too many closing brackets!"
describe "when inserted text does not match a decrease indent pattern", ->
it "does not decrease the indentation", ->
editor.setCursorBufferPosition([12, 0])
editor.insertText(' ')
expect(editor.lineTextForBufferRow(12)).toBe ' };'
editor.insertText('\t\t')
expect(editor.lineTextForBufferRow(12)).toBe ' \t\t};'
describe "when the current line does not match a decrease indent pattern", ->
it "leaves the line unchanged", ->
editor.setCursorBufferPosition([2, 4])
expect(editor.indentationForBufferRow(2)).toBe editor.indentationForBufferRow(1) + 1
editor.insertText('foo')
expect(editor.indentationForBufferRow(2)).toBe editor.indentationForBufferRow(1) + 1
describe 'when scoped settings are used', ->
coffeeEditor = null
describe "editor.normalizeIndentOnPaste", ->
beforeEach ->
waitsForPromise ->
atom.packages.activatePackage('language-coffee-script')
waitsForPromise ->
atom.project.open('coffee.coffee', autoIndent: false).then (o) -> coffeeEditor = o
atom.config.set('editor.normalizeIndentOnPaste', true)
runs ->
atom.config.set('.source.js', 'editor.autoIndent', true)
atom.config.set('.source.coffee', 'editor.autoIndent', false)
it "does not normalize the indentation level of the text when editor.normalizeIndentOnPaste is false", ->
copyText(" function() {\nvar cool = 1;\n }\n")
atom.config.set('editor.normalizeIndentOnPaste', false)
editor.setCursorBufferPosition([5, 2])
editor.pasteText()
expect(editor.lineTextForBufferRow(5)).toBe " function() {"
expect(editor.lineTextForBufferRow(6)).toBe "var cool = 1;"
expect(editor.lineTextForBufferRow(7)).toBe " }"
afterEach: ->
atom.packages.deactivatePackages()
atom.packages.unloadPackages()
describe "when the inserted text contains no newlines", ->
it "does not adjust the indentation level of the text", ->
editor.setCursorBufferPosition([5, 2])
editor.insertText("foo", indentBasis: 5)
expect(editor.lineTextForBufferRow(5)).toBe " foo current = items.shift();"
it "does not auto-indent the line for javascript files", ->
editor.setCursorBufferPosition([1, 30])
editor.insertText("\n")
expect(editor.lineTextForBufferRow(2)).toBe " "
it "does not adjust the whitespace if there are preceding characters", ->
copyText(" foo")
editor.setCursorBufferPosition([5, 30])
editor.pasteText()
coffeeEditor.setCursorBufferPosition([1, 18])
coffeeEditor.insertText("\n")
expect(coffeeEditor.lineTextForBufferRow(2)).toBe ""
expect(editor.lineTextForBufferRow(5)).toBe " current = items.shift(); foo"
describe "when the inserted text contains newlines", ->
describe "when the cursor is preceded only by whitespace characters", ->
it "normalizes indented lines to the cursor's current indentation level", ->
copyText(" while (true) {\n foo();\n }\n", {startColumn: 2})
editor.setCursorBufferPosition([3, 4])
editor.pasteText()
expect(editor.lineTextForBufferRow(3)).toBe " while (true) {"
expect(editor.lineTextForBufferRow(4)).toBe " foo();"
expect(editor.lineTextForBufferRow(5)).toBe " }"
expect(editor.lineTextForBufferRow(6)).toBe "var pivot = items.shift(), current, left = [], right = [];"
describe "when the cursor is preceded by non-whitespace characters", ->
it "normalizes the indentation level of all lines based on the level of the existing first line", ->
copyText(" while (true) {\n foo();\n }\n", {startColumn: 0})
editor.setCursorBufferPosition([1, Infinity])
editor.pasteText()
expect(editor.lineTextForBufferRow(1)).toBe " var sort = function(items) {while (true) {"
expect(editor.lineTextForBufferRow(2)).toBe " foo();"
expect(editor.lineTextForBufferRow(3)).toBe " }"
expect(editor.lineTextForBufferRow(4)).toBe ""
describe 'when scoped settings are used', ->
coffeeEditor = null
beforeEach ->
waitsForPromise ->
atom.packages.activatePackage('language-coffee-script')
waitsForPromise ->
atom.project.open('coffee.coffee', autoIndent: false).then (o) -> coffeeEditor = o
runs ->
atom.config.set('.source.js', 'editor.normalizeIndentOnPaste', true)
atom.config.set('.source.coffee', 'editor.normalizeIndentOnPaste', false)
afterEach: ->
atom.packages.deactivatePackages()
atom.packages.unloadPackages()
it "normalizes the indentation level based on scoped settings", ->
copyText(" while (true) {\n foo();\n }\n", {startColumn: 2, textEditor: coffeeEditor})
coffeeEditor.setCursorBufferPosition([4, 4])
coffeeEditor.pasteText()
expect(coffeeEditor.lineTextForBufferRow(4)).toBe " while (true) {"
expect(coffeeEditor.lineTextForBufferRow(5)).toBe " foo();"
expect(coffeeEditor.lineTextForBufferRow(6)).toBe " }"
copyText(" while (true) {\n foo();\n }\n", {startColumn: 2})
editor.setCursorBufferPosition([3, 4])
editor.pasteText()
expect(editor.lineTextForBufferRow(3)).toBe " while (true) {"
expect(editor.lineTextForBufferRow(4)).toBe " foo();"
expect(editor.lineTextForBufferRow(5)).toBe " }"
it "autoIndentSelectedRows auto-indents the selection", ->
editor.setCursorBufferPosition([2, 0])
editor.insertText("function() {\ninside=true\n}\n i=1\n")
editor.getLastSelection().setBufferRange([[2,0], [6,0]])
editor.autoIndentSelectedRows()
expect(editor.lineTextForBufferRow(2)).toBe " function() {"
expect(editor.lineTextForBufferRow(3)).toBe " inside=true"
expect(editor.lineTextForBufferRow(4)).toBe " }"
expect(editor.lineTextForBufferRow(5)).toBe " i=1"
describe "soft and hard tabs", ->
afterEach ->
@@ -3506,19 +3408,6 @@ describe "TextEditor", ->
runs ->
expect(editor.softTabs).toBe false
it "uses hard tabs in Makefile files", ->
# FIXME remove once this is handled by a scoped setting in the
# language-make package
waitsForPromise ->
atom.packages.activatePackage('language-make')
waitsForPromise ->
atom.project.open('Makefile').then (o) -> editor = o
runs ->
expect(editor.softTabs).toBe false
describe ".destroy()", ->
it "destroys all markers associated with the edit session", ->
expect(buffer.getMarkerCount()).toBeGreaterThan 0
@@ -3762,7 +3651,7 @@ describe "TextEditor", ->
it "updates the grammar based on grammar overrides", ->
expect(editor.getGrammar().name).toBe 'JavaScript'
atom.grammars.setGrammarOverrideForPath(editor.getPath(), 'source.coffee')
atom.syntax.setGrammarOverrideForPath(editor.getPath(), 'source.coffee')
editor.reloadGrammar()
expect(editor.getGrammar().name).toBe 'CoffeeScript'
@@ -3780,7 +3669,7 @@ describe "TextEditor", ->
atom.packages.activatePackage('language-hyperlink')
runs ->
grammar = atom.grammars.selectGrammar("text.js")
grammar = atom.syntax.selectGrammar("text.js")
{tokens} = grammar.tokenizeLine("var i; // http://github.com")
expect(tokens[0].value).toBe "var"
+17 -18
Ver Arquivo
@@ -70,7 +70,7 @@ describe "ThemeManager", ->
describe "when the core.themes config value changes", ->
it "add/removes stylesheets to reflect the new config value", ->
themeManager.onDidReloadAll reloadHandler = jasmine.createSpy()
spyOn(atom.styles, 'getUserStyleSheetPath').andCallFake -> null
spyOn(themeManager, 'getUserStylesheetPath').andCallFake -> null
waitsForPromise ->
themeManager.activateThemes()
@@ -85,7 +85,7 @@ describe "ThemeManager", ->
runs ->
reloadHandler.reset()
expect($('style.theme')).toHaveLength 0
atom.config.set('core.themes', ['atom-dark-ui'])
atom.config.set('core.themes', ['atom-dark-syntax'])
waitsFor ->
reloadHandler.callCount == 1
@@ -93,8 +93,8 @@ describe "ThemeManager", ->
runs ->
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'])
expect($('style[group=theme]:eq(1)').attr('source-path')).toMatch /atom-dark-syntax/
atom.config.set('core.themes', ['atom-light-syntax', 'atom-dark-syntax'])
waitsFor ->
reloadHandler.callCount == 1
@@ -102,8 +102,8 @@ describe "ThemeManager", ->
runs ->
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/
expect($('style[group=theme]:eq(0)').attr('source-path')).toMatch /atom-dark-syntax/
expect($('style[group=theme]:eq(1)').attr('source-path')).toMatch /atom-light-syntax/
atom.config.set('core.themes', [])
waitsFor ->
@@ -207,11 +207,10 @@ describe "ThemeManager", ->
expect(stylesheetsChangedHandler).toHaveBeenCalled()
describe "base stylesheet loading", ->
workspaceElement = null
beforeEach ->
workspaceElement = atom.views.getView(atom.workspace)
jasmine.attachToDOM(workspaceElement)
workspaceElement.appendChild document.createElement('atom-text-editor')
atom.workspaceView = atom.views.getView(atom.workspace).__spacePenView
atom.workspaceView.append $('<atom-text-editor>')
atom.workspaceView.attachToDom()
waitsForPromise ->
themeManager.activateThemes()
@@ -225,7 +224,7 @@ describe "ThemeManager", ->
runs ->
# an override loaded in the base css
expect(getComputedStyle(workspaceElement)["background-color"]).toBe "rgb(0, 0, 255)"
expect(atom.workspaceView.css("background-color")).toBe "rgb(0, 0, 255)"
# from within the theme itself
expect($("atom-text-editor").css("padding-top")).toBe "150px"
@@ -242,14 +241,14 @@ describe "ThemeManager", ->
runs ->
# an override loaded in the base css
expect(getComputedStyle(workspaceElement)["background-color"]).toBe "rgb(0, 0, 255)"
expect(atom.workspaceView.css("background-color")).toBe "rgb(0, 0, 255)"
# from within the theme itself
expect($("atom-text-editor").css("background-color")).toBe "rgb(0, 152, 255)"
describe "theme classes on the workspace", ->
it 'adds theme-* classes to the workspace for each active theme', ->
expect(workspaceElement).toHaveClass 'theme-atom-dark-ui'
expect(atom.workspaceView).toHaveClass 'theme-atom-dark-ui'
themeManager.onDidReloadAll reloadHandler = jasmine.createSpy()
atom.config.set('core.themes', ['theme-with-ui-variables', 'theme-with-syntax-variables'])
@@ -259,17 +258,17 @@ describe "ThemeManager", ->
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'
expect(atom.workspaceView).toHaveClass 'theme-theme-with-ui-variables'
expect(atom.workspaceView).toHaveClass 'theme-theme-with-syntax-variables'
expect(atom.workspaceView).not.toHaveClass 'theme-atom-dark-ui'
expect(atom.workspaceView).not.toHaveClass 'theme-atom-dark-syntax'
describe "when the user stylesheet changes", ->
it "reloads it", ->
[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
spyOn(themeManager, 'getUserStylesheetPath').andReturn userStylesheetPath
waitsForPromise ->
themeManager.activateThemes()
+1 -1
Ver Arquivo
@@ -522,7 +522,7 @@ describe "TokenizedBuffer", ->
buffer = atom.project.bufferForPathSync()
buffer.setText "<div class='name'><%= User.find(2).full_name %></div>"
tokenizedBuffer = new TokenizedBuffer({buffer})
tokenizedBuffer.setGrammar(atom.grammars.selectGrammar('test.erb'))
tokenizedBuffer.setGrammar(atom.syntax.selectGrammar('test.erb'))
fullyTokenize(tokenizedBuffer)
{tokens} = tokenizedBuffer.tokenizedLineForRow(0)
-72
Ver Arquivo
@@ -1,72 +0,0 @@
TooltipManager = require '../src/tooltip-manager'
{$} = require '../src/space-pen-extensions'
describe "TooltipManager", ->
[manager, element] = []
beforeEach ->
manager = new TooltipManager
element = document.createElement('div')
element.classList.add('foo')
jasmine.attachToDOM(element)
hover = (element, fn) ->
$(element).trigger 'mouseenter'
advanceClock(manager.defaults.delay.show)
fn()
$(element).trigger 'mouseleave'
advanceClock(manager.defaults.delay.hide)
describe "::add(target, options)", ->
describe "when the target is an element", ->
it "creates a tooltip based on the given options when hovering over the target element", ->
manager.add element, title: "Title"
hover element, ->
expect(document.body.querySelector(".tooltip")).toHaveText("Title")
describe "when a keyBindingCommand is specified", ->
describe "when a title is specified", ->
it "appends the key binding corresponding to the command to the title", ->
atom.keymaps.add 'test',
'.foo': 'ctrl-x ctrl-y': 'test-command'
'.bar': 'ctrl-x ctrl-z': 'test-command'
manager.add element, title: "Title", keyBindingCommand: 'test-command'
hover element, ->
tooltipElement = document.body.querySelector(".tooltip")
expect(tooltipElement).toHaveText "Title ⌃X ⌃Y"
describe "when no title is specified", ->
it "shows the key binding corresponding to the command alone", ->
atom.keymaps.add 'test', '.foo': 'ctrl-x ctrl-y': 'test-command'
manager.add element, keyBindingCommand: 'test-command'
hover element, ->
tooltipElement = document.body.querySelector(".tooltip")
expect(tooltipElement).toHaveText "⌃X ⌃Y"
describe "when a keyBindingTarget is specified", ->
it "looks up the key binding relative to the target", ->
atom.keymaps.add 'test',
'.bar': 'ctrl-x ctrl-z': 'test-command'
'.foo': 'ctrl-x ctrl-y': 'test-command'
manager.add element, keyBindingCommand: 'test-command', keyBindingTarget: element
hover element, ->
tooltipElement = document.body.querySelector(".tooltip")
expect(tooltipElement).toHaveText "⌃X ⌃Y"
describe "when .dispose() is called on the returned disposable", ->
it "no longer displays the tooltip on hover", ->
disposable = manager.add element, title: "Title"
hover element, ->
expect(document.body.querySelector(".tooltip")).toHaveText("Title")
disposable.dispose()
hover element, ->
expect(document.body.querySelector(".tooltip")).toBeNull()
+5 -5
Ver Arquivo
@@ -95,13 +95,13 @@ describe "Window", ->
describe ".unloadEditorWindow()", ->
it "saves the serialized state of the window so it can be deserialized after reload", ->
workspaceState = atom.workspace.serialize()
syntaxState = atom.grammars.serialize()
syntaxState = atom.syntax.serialize()
projectState = atom.project.serialize()
atom.unloadEditorWindow()
expect(atom.state.workspace).toEqual workspaceState
expect(atom.state.grammars).toEqual syntaxState
expect(atom.state.syntax).toEqual syntaxState
expect(atom.state.project).toEqual projectState
expect(atom.saveSync).toHaveBeenCalled()
@@ -112,9 +112,9 @@ describe "Window", ->
runs ->
buffer = atom.workspace.getActivePaneItem().buffer
pane = atom.workspace.getActivePane()
pane.splitRight(copyActiveItem: true)
expect(atom.workspace.getTextEditors().length).toBe 2
pane = atom.workspaceView.getActivePaneView()
pane.splitRight(pane.copyActiveItem())
expect(atom.workspaceView.find('atom-text-editor').length).toBe 2
atom.removeEditorWindow()
-8
Ver Arquivo
@@ -492,11 +492,3 @@ describe "Workspace", ->
expect(panel).toBeDefined()
expect(addPanelSpy).toHaveBeenCalledWith({panel, index: 0})
describe '::addModalPanel(model)', ->
it 'adds a panel to the correct panel container', ->
atom.workspace.panelContainers.modal.onDidAddPanel addPanelSpy = jasmine.createSpy()
panel = atom.workspace.addModalPanel(item: new TestPanel())
expect(panel).toBeDefined()
expect(addPanelSpy).toHaveBeenCalledWith({panel, index: 0})
+4 -7
Ver Arquivo
@@ -277,15 +277,12 @@ describe "WorkspaceView", ->
workspaceElement = atom.views.getView(atom.workspace)
it 'inserts panel container elements in the correct places in the DOM', ->
leftContainer = workspaceElement.querySelector('atom-panel-container.left')
rightContainer = workspaceElement.querySelector('atom-panel-container.right')
leftContainer = workspaceElement.querySelector('atom-panel-container[location="left"]')
rightContainer = workspaceElement.querySelector('atom-panel-container[location="right"]')
expect(leftContainer.nextSibling).toBe workspaceElement.verticalAxis
expect(rightContainer.previousSibling).toBe workspaceElement.verticalAxis
topContainer = workspaceElement.querySelector('atom-panel-container.top')
bottomContainer = workspaceElement.querySelector('atom-panel-container.bottom')
topContainer = workspaceElement.querySelector('atom-panel-container[location="top"]')
bottomContainer = workspaceElement.querySelector('atom-panel-container[location="bottom"]')
expect(topContainer.nextSibling).toBe workspaceElement.paneContainer
expect(bottomContainer.previousSibling).toBe workspaceElement.paneContainer
modalContainer = workspaceElement.querySelector('atom-panel-container.modal')
expect(modalContainer.parentNode).toBe workspaceElement
+34 -101
Ver Arquivo
@@ -5,7 +5,6 @@ path = require 'path'
remote = require 'remote'
screen = require 'screen'
shell = require 'shell'
{deprecate} = require 'grim'
_ = require 'underscore-plus'
{deprecate} = require 'grim'
@@ -34,23 +33,6 @@ class Atom extends Model
startTime = Date.now()
atom = @deserialize(@loadState(mode)) ? new this({mode, @version})
atom.deserializeTimings.atom = Date.now() - startTime
workspaceViewDeprecationMessage = """
atom.workspaceView is no longer available.
In most cases you will not need the view. See the Workspace docs for
alternatives: https://atom.io/docs/api/latest/Workspace.
If you do need the view, please use `atom.views.getView(atom.workspace)`,
which returns an HTMLElement.
"""
Object.defineProperty atom, 'workspaceView',
get: ->
deprecate(workspaceViewDeprecationMessage)
atom.__workspaceView
set: (newValue) ->
deprecate(workspaceViewDeprecationMessage)
atom.__workspaceView = newValue
atom
# Deserializes the Atom environment from a state object
@@ -143,17 +125,11 @@ class Atom extends Model
# Public: A {KeymapManager} instance
keymaps: null
# Public: A {TooltipManager} instance
tooltips: null
# Experimental: A {NotificationManager} instance
notifications: null
# Public: A {Project} instance
project: null
# Public: A {GrammarRegistry} instance
grammars: null
# Public: A {Syntax} instance
syntax: null
# Public: A {PackageManager} instance
packages: null
@@ -161,9 +137,6 @@ class Atom extends Model
# Public: A {ThemeManager} instance
themes: null
# Public: A {StyleManager} instance
styles: null
# Public: A {DeserializerManager} instance
deserializers: null
@@ -173,6 +146,9 @@ class Atom extends Model
# Public: A {Workspace} instance
workspace: null
# Public: A {WorkspaceView} instance
workspaceView: null
###
Section: Construction and Destruction
###
@@ -197,24 +173,14 @@ class Atom extends Model
require('grim').deprecate = ->
window.onerror = =>
@openDevTools()
@executeJavaScriptInDevTools('InspectorFrontendAPI.showConsole()')
@lastUncaughtError = Array::slice.call(arguments)
[message, url, line, column, originalError] = @lastUncaughtError
eventObject = {message, url, line, column, originalError}
openDevTools = true
eventObject.preventDefault = -> openDevTools = false
@emitter.emit 'will-throw-error', eventObject
if openDevTools
@openDevTools()
@executeJavaScriptInDevTools('InspectorFrontendAPI.showConsole()')
@emit 'uncaught-error', arguments...
@emitter.emit 'did-throw-error', {message, url, line, column, originalError}
@unsubscribe()
@setBodyPlatformClass()
@requireTemplatingGlobals()
@loadTime = null
@@ -222,11 +188,9 @@ class Atom extends Model
KeymapManager = require './keymap-extensions'
ViewRegistry = require './view-registry'
CommandRegistry = require './command-registry'
TooltipManager = require './tooltip-manager'
NotificationManager = require './notification-manager'
PackageManager = require './package-manager'
Clipboard = require './clipboard'
GrammarRegistry = require './grammar-registry'
Syntax = require './syntax'
ThemeManager = require './theme-manager'
StyleManager = require './style-manager'
ContextMenuManager = require './context-menu-manager'
@@ -249,9 +213,6 @@ class Atom extends Model
@config = new Config({configDirPath, resourcePath})
@keymaps = new KeymapManager({configDirPath, resourcePath})
@keymap = @keymaps # Deprecated
@keymaps.subscribeToFileReadFailure()
@tooltips = new TooltipManager
@notifications = new NotificationManager
@commands = new CommandRegistry
@views = new ViewRegistry
@packages = new PackageManager({devMode, configDirPath, resourcePath, safeMode})
@@ -262,11 +223,7 @@ class Atom extends Model
@menu = new MenuManager({resourcePath})
@clipboard = new Clipboard()
@grammars = @deserializers.deserialize(@state.grammars ? @state.syntax) ? new GrammarRegistry()
Object.defineProperty this, 'syntax', get: ->
deprecate "The atom.syntax global is deprecated. Use atom.grammars instead."
@grammars
@syntax = @deserializers.deserialize(@state.syntax) ? new Syntax()
@subscribe @packages.onDidActivateAll => @watchThemes()
@@ -291,36 +248,6 @@ class Atom extends Model
onDidBeep: (callback) ->
@emitter.on 'did-beep', callback
# Extended: Invoke the given callback when there is an unhandled error, but
# before the devtools pop open
#
# * `callback` {Function} to be called whenever there is an unhandled error
# * `event` {Object}
# * `originalError` {Object} the original error object
# * `message` {String} the original error object
# * `url` {String} Url to the file where the error originated.
# * `line` {Number}
# * `column` {Number}
# * `preventDefault` {Function} call this to avoid popping up the dev tools.
#
# Returns a {Disposable} on which `.dispose()` can be called to unsubscribe.
onWillThrowError: (callback) ->
@emitter.on 'will-throw-error', callback
# Extended: Invoke the given callback whenever there is an unhandled error.
#
# * `callback` {Function} to be called whenever there is an unhandled error
# * `event` {Object}
# * `originalError` {Object} the original error object
# * `message` {String} the original error object
# * `url` {String} Url to the file where the error originated.
# * `line` {Number}
# * `column` {Number}
#
# Returns a {Disposable} on which `.dispose()` can be called to unsubscribe.
onDidThrowError: (callback) ->
@emitter.on 'did-throw-error', callback
###
Section: Atom Details
###
@@ -567,19 +494,15 @@ class Atom extends Model
@packages.activate()
@keymaps.loadUserKeymap()
@requireUserInitScript() unless safeMode
@menu.update()
@subscribe @config.onDidChange 'core.autoHideMenuBar', ({newValue}) =>
@setAutoHideMenuBar(newValue)
@setAutoHideMenuBar(true) if @config.get('core.autoHideMenuBar')
maximize = dimensions?.maximized and process.platform isnt 'darwin'
@displayWindow({maximize})
unloadEditorWindow: ->
return if not @project
return if not @project and not @workspaceView
@state.grammars = @grammars.serialize()
@state.syntax = @syntax.serialize()
@state.project = @project.serialize()
@state.workspace = @workspace.serialize()
@packages.deactivatePackages()
@@ -588,10 +511,10 @@ class Atom extends Model
@windowState = null
removeEditorWindow: ->
return if not @project
return if not @project and not @workspaceView
@workspace?.destroy()
@workspace = null
@workspaceView?.remove()
@workspaceView = null
@project?.destroy()
@project = null
@@ -604,7 +527,7 @@ class Atom extends Model
# Essential: Visually and audibly trigger a beep.
beep: ->
shell.beep() if @config.get('core.audioBeep')
@__workspaceView.trigger 'beep'
@workspaceView.trigger 'beep'
@emitter.emit 'did-beep'
# Essential: A flexible way to open a dialog akin to an alert dialog.
@@ -680,13 +603,11 @@ class Atom extends Model
startTime = Date.now()
@workspace = Workspace.deserialize(@state.workspace) ? new Workspace
workspaceElement = @views.getView(@workspace)
@__workspaceView = workspaceElement.__spacePenView
@workspaceView = @views.getView(@workspace).__spacePenView
@deserializeTimings.workspace = Date.now() - startTime
@keymaps.defaultTarget = workspaceElement
document.querySelector(@workspaceViewParentSelector).appendChild(workspaceElement)
@keymaps.defaultTarget = @workspaceView[0]
$(@workspaceViewParentSelector).append(@workspaceView)
deserializePackageStates: ->
@packages.packageStates = @state.packageStates ? {}
@@ -794,6 +715,18 @@ class Atom extends Model
setBodyPlatformClass: ->
document.body.classList.add("platform-#{process.platform}")
setAutoHideMenuBar: (autoHide) ->
ipc.send('call-window-method', 'setAutoHideMenuBar', autoHide)
ipc.send('call-window-method', 'setMenuBarVisibility', !autoHide)
requireTemplatingGlobals: ->
require('./html-require').register()
# This is required by the polymer stuff. It can be noop'd because
# Object.observe is built into chrome.
global.Platform =
performMicrotaskCheckpoint: ->
require 'Node-bind/src/NodeBind'
require 'TemplateBinding/src/TemplateBinding'
require 'observe-js'
global.esprima = require('polymer-expressions/third_party/esprima/esprima').esprima
{PolymerExpressions} = require 'polymer-expressions/src/polymer-expressions'
HTMLTemplateElement.prototype.bindingDelegate = new PolymerExpressions
+1 -6
Ver Arquivo
@@ -70,7 +70,7 @@ class AtomApplication
@autoUpdateManager = new AutoUpdateManager(@version)
@applicationMenu = new ApplicationMenu(@version)
@atomProtocolHandler = new AtomProtocolHandler(@resourcePath, @safeMode)
@atomProtocolHandler = new AtomProtocolHandler(@resourcePath)
@listenForArgumentsFromNewProcess()
@setupJavaScriptArguments()
@@ -238,11 +238,6 @@ class AtomApplication
win = BrowserWindow.fromWebContents(event.sender)
win[method](args...)
clipboard = null
ipc.on 'write-text-to-selection-clipboard', (event, selectedText) ->
clipboard ?= require 'clipboard'
clipboard.writeText(selectedText, 'selection')
# Public: Executes the given command.
#
# If it isn't handled globally, delegate to the currently focused window.
+12 -29
Ver Arquivo
@@ -5,26 +5,16 @@ protocol = require 'protocol'
# Handles requests with 'atom' protocol.
#
# It's created by {AtomApplication} upon instantiation and is used to create a
# custom resource loader for 'atom://' URLs.
#
# The following directories are searched in order:
# * ~/.atom/assets
# * ~/.atom/dev/packages (unless in safe mode)
# * ~/.atom/packages
# * RESOURCE_PATH/node_modules
#
# It's created by {AtomApplication} upon instantiation, and is used to create a
# custom resource loader by adding the 'atom' custom protocol.
module.exports =
class AtomProtocolHandler
constructor: (resourcePath, safeMode) ->
@loadPaths = []
@dotAtomDirectory = path.join(app.getHomeDir(), '.atom')
unless safeMode
@loadPaths.push(path.join(@dotAtomDirectory, 'dev', 'packages'))
@loadPaths.push(path.join(@dotAtomDirectory, 'packages'))
@loadPaths.push(path.join(resourcePath, 'node_modules'))
constructor: (@resourcePath) ->
@loadPaths = [
path.join(app.getHomeDir(), '.atom', 'dev', 'packages')
path.join(app.getHomeDir(), '.atom', 'packages')
path.join(@resourcePath, 'node_modules')
]
@registerAtomProtocol()
@@ -32,14 +22,7 @@ class AtomProtocolHandler
registerAtomProtocol: ->
protocol.registerProtocol 'atom', (request) =>
relativePath = path.normalize(request.url.substr(7))
if relativePath.indexOf('assets/') is 0
assetsPath = path.join(@dotAtomDirectory, relativePath)
filePath = assetsPath if fs.statSyncNoException(assetsPath).isFile?()
unless filePath
for loadPath in @loadPaths
filePath = path.join(loadPath, relativePath)
break if fs.statSyncNoException(filePath).isFile?()
new protocol.RequestFileJob(filePath)
for loadPath in @loadPaths
filePath = path.join(loadPath, relativePath)
break if fs.statSyncNoException(filePath).isFile?()
return new protocol.RequestFileJob(filePath)
+22 -9
Ver Arquivo
@@ -15,20 +15,15 @@ class AutoUpdateManager
constructor: (@version) ->
@state = IdleState
if process.platform is 'win32'
# Squirrel for Windows can't handle query params
# https://github.com/Squirrel/Squirrel.Windows/issues/132
@feedUrl = 'https://atom.io/api/updates'
else
@feedUrl = "https://atom.io/api/updates?version=#{@version}"
@feedUrl = "https://atom.io/api/updates?version=#{@version}"
process.nextTick => @setupAutoUpdater()
setupAutoUpdater: ->
autoUpdater = require 'auto-updater'
if process.platform is 'win32'
autoUpdater = require './auto-updater-win32'
else
autoUpdater = require 'auto-updater'
autoUpdater.checkForUpdates = => @checkForUpdatesShim()
autoUpdater.setFeedUrl @feedUrl
@@ -53,6 +48,24 @@ class AutoUpdateManager
unless /\w{7}/.test(@version)
@check(hidePopups: true)
# Windows doesn't have an auto-updater, so use this method to shim the events.
checkForUpdatesShim: ->
autoUpdater.emit 'checking-for-update'
https = require 'https'
request = https.get @feedUrl, (response) ->
if response.statusCode == 200
body = ""
response.on 'data', (chunk) -> body += chunk
response.on 'end', ->
{notes, name} = JSON.parse(body)
autoUpdater.emit 'update-downloaded', null, notes, name
else
autoUpdater.emit 'update-not-available'
request.on 'error', (error) ->
autoUpdater.emit 'error', null, error.message
emitUpdateAvailableEvent: (windows...) ->
return unless @releaseVersion? and @releaseNotes
for atomWindow in windows
-69
Ver Arquivo
@@ -1,69 +0,0 @@
{EventEmitter} = require 'events'
_ = require 'underscore-plus'
shellAutoUpdater = require 'auto-updater'
SquirrelUpdate = require './squirrel-update'
class AutoUpdater
_.extend @prototype, EventEmitter.prototype
setFeedUrl: (@updateUrl) ->
quitAndInstall: ->
unless SquirrelUpdate.existsSync()
shellAutoUpdater.quitAndInstall()
return
@installUpdate (error) ->
return if error?
SquirrelUpdate.spawn ['--processStart', 'atom.exe'], ->
shellAutoUpdater.quitAndInstall()
downloadUpdate: (callback) ->
SquirrelUpdate.spawn ['--download', @updateUrl], (error, stdout) ->
return callback(error) if error?
try
# Last line of output is the JSON details about the releases
json = stdout.trim().split('\n').pop()
update = JSON.parse(json)?.releasesToApply?.pop?()
catch error
error.stdout = stdout
return callback(error)
callback(null, update)
installUpdate: (callback) ->
SquirrelUpdate.spawn(['--update', @updateUrl], callback)
checkForUpdates: ->
throw new Error('Update URL is not set') unless @updateUrl
@emit 'checking-for-update'
unless SquirrelUpdate.existsSync()
@emit 'update-not-available'
return
@downloadUpdate (error, update) =>
if error?
console.log "Failed to download: #{error.message} - #{error.code} - #{error.stdout}"
@emit 'update-not-available'
return
unless update?
@emit 'update-not-available'
return
@installUpdate (error) =>
if error?
console.log "Failed to update: #{error.message} - #{error.code} - #{error.stdout}"
@emit 'update-not-available'
return
console.log "Updated to #{update.version}"
@emit 'update-available'
@emit 'update-downloaded', {}, update.releaseNotes, update.version, new Date(), 'https://atom.io', => @quitAndInstall()
module.exports = new AutoUpdater()
-18
Ver Arquivo
@@ -13,21 +13,7 @@ process.on 'uncaughtException', (error={}) ->
nslog(error.message) if error.message?
nslog(error.stack) if error.stack?
# Patch fs.statSyncNoException/fs.lstatSyncNoException to fail for non-strings
# https://github.com/atom/atom-shell/issues/843
{lstatSyncNoException, statSyncNoException} = fs
fs.statSyncNoException = (pathToStat) ->
return false unless pathToStat and typeof pathToStat is 'string'
statSyncNoException(pathToStat)
fs.lstatSyncNoException = (pathToStat) ->
return false unless pathToStat and typeof pathToStat is 'string'
lstatSyncNoException(pathToStat)
start = ->
if process.platform is 'win32'
SquirrelUpdate = require './squirrel-update'
return if SquirrelUpdate.handleStartupEvent()
args = parseCommandLine()
addPathToOpen = (event, pathToOpen) ->
@@ -148,10 +134,6 @@ parseCommandLine = ->
unless fs.statSyncNoException(resourcePath)
resourcePath = path.dirname(path.dirname(__dirname))
# On Yosemite the $PATH is not inherited by the "open" command, so we have to
# explicitly pass it by command line, see http://git.io/YC8_Ew.
process.env.PATH = args['path-environment'] if args['path-environment']
{resourcePath, pathsToOpen, executedFrom, test, version, pidToKillWhenClosed, devMode, safeMode, newWindow, specDirectory, logFile}
start()
-198
Ver Arquivo
@@ -1,198 +0,0 @@
app = require 'app'
ChildProcess = require 'child_process'
fs = require 'fs-plus'
path = require 'path'
rootAtomFolder = path.resolve(process.execPath, '..', '..')
binFolder = path.join(rootAtomFolder, 'bin')
updateDotExe = path.join(rootAtomFolder, 'Update.exe')
exeName = path.basename(process.execPath)
if process.env.SystemRoot
system32Path = path.join(process.env.SystemRoot, 'System32')
regPath = path.join(system32Path, 'reg.exe')
setxPath = path.join(system32Path, 'setx.exe')
else
regPath = 'reg.exe'
setxPath = 'setx.exe'
# Registry keys used for context menu
fileKeyPath = 'HKCU\\Software\\Classes\\*\\shell\\Atom'
directoryKeyPath = 'HKCU\\Software\\Classes\\directory\\shell\\Atom'
backgroundKeyPath = 'HKCU\\Software\\Classes\\directory\\background\\shell\\Atom'
environmentKeyPath = 'HKCU\\Environment'
# Spawn a command and invoke the callback when it completes with an error
# and the output from standard out.
spawn = (command, args, callback) ->
spawnedProcess = ChildProcess.spawn(command, args)
stdout = ''
spawnedProcess.stdout.on 'data', (data) -> stdout += data
error = null
spawnedProcess.on 'error', (processError) -> error ?= processError
spawnedProcess.on 'close', (code, signal) ->
error ?= new Error("Command failed: #{signal ? code}") if code isnt 0
error?.code ?= code
error?.stdout ?= stdout
callback(error, stdout)
# Spawn reg.exe and callback when it completes
spawnReg = (args, callback) ->
spawn(regPath, args, callback)
# Spawn setx.exe and callback when it completes
spawnSetx = (args, callback) ->
spawn(setxPath, args, callback)
# Spawn the Update.exe with the given arguments and invoke the callback when
# the command completes.
spawnUpdate = (args, callback) ->
spawn(updateDotExe, args, callback)
# Install the Open with Atom explorer context menu items via the registry.
installContextMenu = (callback) ->
addToRegistry = (args, callback) ->
args.unshift('add')
args.push('/f')
spawnReg(args, callback)
installMenu = (keyPath, arg, callback) ->
args = [keyPath, '/ve', '/d', 'Open with Atom']
addToRegistry args, ->
args = [keyPath, '/v', 'Icon', '/d', process.execPath]
addToRegistry args, ->
args = ["#{keyPath}\\command", '/ve', '/d', "#{process.execPath} \"#{arg}\""]
addToRegistry(args, callback)
installMenu fileKeyPath, '%1', ->
installMenu directoryKeyPath, '%1', ->
installMenu(backgroundKeyPath, '%V', callback)
# Get the user's PATH environment variable registry value.
getPath = (callback) ->
spawnReg ['query', environmentKeyPath, '/v', 'Path'], (error, stdout) ->
if error?
if error.code is 1
# The query failed so the Path does not exist yet in the registry
return callback(null, '')
else
return callback(error)
# Registry query output is in the form:
#
# HKEY_CURRENT_USER\Environment
# Path REG_SZ C:\a\folder\on\the\path;C\another\folder
#
lines = stdout.split(/[\r\n]+/).filter (line) -> line
segments = lines[lines.length - 1]?.split(' ')
if segments[1] is 'Path' and segments.length >= 3
pathEnv = segments?[3..].join(' ')
callback(null, pathEnv)
else
callback(new Error('Registry query for PATH failed'))
# Uninstall the Open with Atom explorer context menu items via the registry.
uninstallContextMenu = (callback) ->
deleteFromRegistry = (keyPath, callback) ->
spawnReg(['delete', keyPath, '/f'], callback)
deleteFromRegistry fileKeyPath, ->
deleteFromRegistry directoryKeyPath, ->
deleteFromRegistry(backgroundKeyPath, callback)
# Add atom and apm to the PATH
#
# This is done by adding .cmd shims to the root bin folder in the Atom
# install directory that point to the newly installed versions inside
# the versioned app directories.
addCommandsToPath = (callback) ->
installCommands = (callback) ->
atomCommandPath = path.join(binFolder, 'atom.cmd')
relativeExePath = path.relative(binFolder, process.execPath)
atomCommand = """
@echo off
"%~dp0\\#{relativeExePath}" %*
"""
apmCommandPath = path.join(binFolder, 'apm.cmd')
relativeApmPath = path.relative(binFolder, path.join(process.resourcesPath, 'app', 'apm', 'node_modules', 'atom-package-manager', 'bin', 'apm.cmd'))
apmCommand = """
@echo off
"%~dp0\\#{relativeApmPath}" %*
"""
fs.writeFile atomCommandPath, atomCommand, ->
fs.writeFile apmCommandPath, apmCommand, ->
callback()
addBinToPath = (pathSegments, callback) ->
pathSegments.push(binFolder)
newPathEnv = pathSegments.join(';')
spawnSetx(['Path', newPathEnv], callback)
installCommands (error) ->
return callback(error) if error?
getPath (error, pathEnv) ->
return callback(error) if error?
pathSegments = pathEnv.split(/;+/).filter (pathSegment) -> pathSegment
if pathSegments.indexOf(binFolder) is -1
addBinToPath(pathSegments, callback)
else
callback()
# Remove atom and apm from the PATH
removeCommandsFromPath = (callback) ->
getPath (error, pathEnv) ->
return callback(error) if error?
pathSegments = pathEnv.split(/;+/).filter (pathSegment) ->
pathSegment and pathSegment isnt binFolder
newPathEnv = pathSegments.join(';')
if pathEnv isnt newPathEnv
spawnSetx(['Path', newPathEnv], callback)
else
callback()
# Create a desktop and start menu shortcut by using the command line API
# provided by Squirrel's Update.exe
createShortcut = (callback) ->
spawnUpdate(['--createShortcut', exeName], callback)
# Remove the desktop and start menu shortcuts by using the command line API
# provided by Squirrel's Update.exe
removeShortcut = (callback) ->
spawnUpdate(['--removeShortcut', exeName], callback)
exports.spawn = spawnUpdate
# Is the Update.exe installed with Atom?
exports.existsSync = ->
fs.existsSync(updateDotExe)
# Handle squirrel events denoted by --squirrel-* command line arguments.
exports.handleStartupEvent = ->
switch process.argv[1]
when '--squirrel-install', '--squirrel-updated'
createShortcut ->
installContextMenu ->
addCommandsToPath ->
app.quit()
true
when '--squirrel-uninstall'
removeShortcut ->
uninstallContextMenu ->
removeCommandsFromPath ->
app.quit()
true
when '--squirrel-obsolete'
app.quit()
true
else
false
+15 -14
Ver Arquivo
@@ -35,7 +35,9 @@ SpecificityCache = {}
# ```coffee
# atom.commands.add 'atom-text-editor',
# 'user:insert-date': (event) ->
# editor = @getModel()
# editor = $(this).view().getModel()
# # soon the above above line will be:
# # editor = @getModel()
# editor.insertText(new Date().toLocaleString())
# ```
module.exports =
@@ -128,26 +130,25 @@ class CommandRegistry
# * `jQuery` Present if the command was registered with the legacy
# `$::command` method.
findCommands: ({target}) ->
commandNames = new Set
commands = []
currentTarget = target
loop
for name, listeners of @inlineListenersByCommandName
if listeners.has(currentTarget) and not commandNames.has(name)
commandNames.add(name)
commands.push({name, displayName: _.humanizeEventName(name)})
for commandName, listeners of @selectorBasedListenersByCommandName
for listener in listeners
if currentTarget.webkitMatchesSelector?(listener.selector)
unless commandNames.has(commandName)
commandNames.add(commandName)
commands.push
name: commandName
displayName: _.humanizeEventName(commandName)
commands.push
name: commandName
displayName: _.humanizeEventName(commandName)
break if currentTarget is window
currentTarget = currentTarget.parentNode ? window
break if currentTarget is @rootNode
currentTarget = currentTarget.parentNode
break unless currentTarget?
for name, displayName of $(target).events() when displayName
commands.push({name, displayName, jQuery: true})
for name, displayName of $(window).events() when displayName
commands.push({name, displayName, jQuery: true})
commands
+1 -59
Ver Arquivo
@@ -35,47 +35,6 @@ module.exports =
destroyEmptyPanes:
type: 'boolean'
default: true
fileEncoding:
description: 'Default character set encoding to use when reading and writing files.'
type: 'string'
default: 'utf8'
enum: [
'cp437',
'eucjp',
'euckr',
'gbk',
'iso88591',
'iso885910',
'iso885913',
'iso885914',
'iso885915',
'iso885916',
'iso88592',
'iso88593',
'iso88594',
'iso88595',
'iso88596',
'iso88597',
'iso88597',
'iso88598',
'koi8r',
'koi8u',
'macroman',
'shiftjis',
'utf16be',
'utf16le',
'utf8',
'windows1250',
'windows1251',
'windows1252',
'windows1253',
'windows1254',
'windows1255',
'windows1256',
'windows1257',
'windows1258',
'windows866'
]
editor:
type: 'object'
@@ -115,8 +74,7 @@ module.exports =
autoIndent:
type: 'boolean'
default: true
description: 'Automatically indent the cursor when inserting a newline'
autoIndentOnPaste:
normalizeIndentOnPaste:
type: 'boolean'
default: true
nonWordCharacters:
@@ -147,20 +105,10 @@ module.exports =
scrollPastEnd:
type: 'boolean'
default: false
undoGroupingInterval:
type: 'integer'
default: 500
minimum: 0
description: 'Time interval in milliseconds within which operations will be grouped together in the undo history'
useHardwareAcceleration:
type: 'boolean'
default: true
description: 'Disabling will improve editor font rendering but reduce scrolling performance.'
useShadowDOM:
type: 'boolean'
default: false
title: 'Use Shadow DOM'
description: 'Enable to test out themes and packages with the new shadow DOM before it ships by default.'
confirmCheckoutHeadRevision:
type: 'boolean'
default: true
@@ -184,9 +132,3 @@ module.exports =
type: 'boolean'
default: process.platform isnt 'darwin'
description: 'Increase/decrease the editor font size when pressing the Ctrl key and scrolling the mouse up/down.'
if process.platform in ['win32', 'linux']
module.exports.core.properties.autoHideMenuBar =
type: 'boolean'
default: false
description: 'Automatically hide the menu bar and toggle it by pressing Alt. This is only supported on Windows & Linux.'
+9 -31
Ver Arquivo
@@ -526,9 +526,6 @@ class Config
# Extended: Restore the global setting at `keyPath` to its default value.
#
# * `scopeSelector` (optional) {String}. eg. '.source.ruby'
# See [the scopes docs](https://atom.io/docs/latest/advanced/scopes-and-scope-descriptors)
# for more information.
# * `keyPath` The {String} name of the key.
#
# Returns the new value.
@@ -539,13 +536,11 @@ class Config
if scopeSelector?
settings = @scopedSettingsStore.propertiesForSourceAndSelector('user-config', scopeSelector)
if _.valueForKeyPath(settings, keyPath)?
@scopedSettingsStore.removePropertiesForSourceAndSelector('user-config', scopeSelector)
_.setValueForKeyPath(settings, keyPath, undefined)
settings = withoutEmptyObjects(settings)
@addScopedSettings('user-config', scopeSelector, settings, @usersScopedSettingPriority) if settings?
@save() unless @configFileHasErrors
@getDefault(scopeSelector, keyPath)
@scopedSettingsStore.removePropertiesForSourceAndSelector('user-config', scopeSelector)
_.setValueForKeyPath(settings, keyPath, undefined)
@addScopedSettings('user-config', scopeSelector, settings, @usersScopedSettingPriority)
@save() unless @configFileHasErrors
@getDefault(scopeSelector, keyPath)
else
@set(keyPath, _.valueForKeyPath(@defaultSettings, keyPath))
@get(keyPath)
@@ -724,26 +719,21 @@ class Config
@configFileHasErrors = false
catch error
@configFileHasErrors = true
@notifyFailure('Failed to load config.cson', error)
console.error "Failed to load user config '#{@configFilePath}'", error.message
console.error error.stack
observeUserConfig: ->
try
@watchSubscription ?= pathWatcher.watch @configFilePath, (eventType) =>
@loadUserConfig() if eventType is 'change' and @watchSubscription?
catch error
@notifyFailure('Failed to watch user config', error)
console.error "Failed to watch user config '#{@configFilePath}'", error.message
console.error error.stack
unobserveUserConfig: ->
@watchSubscription?.close()
@watchSubscription = null
notifyFailure: (errorMessage, error) ->
message = "#{errorMessage}"
detail = error.stack
atom.notifications.addError(message, {detail, closable: true})
console.error message
console.error detail
save: ->
allSettings = global: @settings
allSettings = _.extend allSettings, @scopedSettingsStore.propertiesForSource('user-config')
@@ -1056,15 +1046,3 @@ splitKeyPath = (keyPath) ->
startIndex = i + 1
keyPathArray.push keyPath.substr(startIndex, keyPath.length)
keyPathArray
withoutEmptyObjects = (object) ->
resultObject = undefined
if isPlainObject(object)
for key, value of object
newValue = withoutEmptyObjects(value)
if newValue?
resultObject ?= {}
resultObject[key] = newValue
else
resultObject = object
resultObject
+2 -2
Ver Arquivo
@@ -76,8 +76,8 @@ class ContextMenuManager
# * `event` The click event that deployed the context menu.
add: (itemsBySelector) ->
# Detect deprecated file path as first argument
if itemsBySelector? and typeof itemsBySelector isnt 'object'
Grim.deprecate("ContextMenuManager::add has changed to take a single object as its argument. Please consult the documentation.")
unless typeof itemsBySelector is 'object'
Grim.deprecate("ContextMenuManage::add has changed to take a single object as its argument. Please consult the documentation.")
itemsBySelector = arguments[1]
devMode = arguments[2]?.devMode
+45 -61
Ver Arquivo
@@ -17,7 +17,7 @@ class Cursor extends Model
visible: true
needsAutoscroll: null
# Instantiated by a {TextEditor}
# Instantiated by an {TextEditor}
constructor: ({@editor, @marker, id}) ->
@emitter = new Emitter
@@ -171,10 +171,6 @@ class Cursor extends Model
Section: Cursor Position Details
###
# Public: Returns the underlying {Marker} for the cursor.
# Useful with overlay {Decoration}s.
getMarker: -> @marker
# Public: Identifies if the cursor is surrounded by whitespace.
#
# "Surrounded" here means that the character directly before and after the
@@ -396,7 +392,7 @@ class Cursor extends Model
# Public: Moves the cursor to the next word boundary.
moveToNextWordBoundary: ->
if position = @getNextWordBoundaryBufferPosition()
if position = @getMoveNextWordBoundaryBufferPosition()
@setBufferPosition(position)
# Public: Moves the cursor to the beginning of the buffer line, skipping all
@@ -424,61 +420,6 @@ class Cursor extends Model
Section: Local Positions and Ranges
###
# Public: Returns buffer position of previous word boundary. It might be on
# the current word, or the previous word.
#
# * `options` (optional) {Object} with the following keys:
# * `wordRegex` A {RegExp} indicating what constitutes a "word"
# (default: {::wordRegExp})
getPreviousWordBoundaryBufferPosition: (options = {}) ->
currentBufferPosition = @getBufferPosition()
previousNonBlankRow = @editor.buffer.previousNonBlankRow(currentBufferPosition.row)
scanRange = [[previousNonBlankRow, 0], currentBufferPosition]
beginningOfWordPosition = null
@editor.backwardsScanInBufferRange (options.wordRegex ? @wordRegExp()), scanRange, ({range, stop}) ->
if range.start.row < currentBufferPosition.row and currentBufferPosition.column > 0
# force it to stop at the beginning of each line
beginningOfWordPosition = new Point(currentBufferPosition.row, 0)
else if range.end.isLessThan(currentBufferPosition)
beginningOfWordPosition = range.end
else
beginningOfWordPosition = range.start
if not beginningOfWordPosition?.isEqual(currentBufferPosition)
stop()
beginningOfWordPosition or currentBufferPosition
# Public: Returns buffer position of the next word boundary. It might be on
# the current word, or the previous word.
#
# * `options` (optional) {Object} with the following keys:
# * `wordRegex` A {RegExp} indicating what constitutes a "word"
# (default: {::wordRegExp})
getNextWordBoundaryBufferPosition: (options = {}) ->
currentBufferPosition = @getBufferPosition()
scanRange = [currentBufferPosition, @editor.getEofBufferPosition()]
endOfWordPosition = null
@editor.scanInBufferRange (options.wordRegex ? @wordRegExp()), scanRange, ({range, stop}) ->
if range.start.row > currentBufferPosition.row
# force it to stop at the beginning of each line
endOfWordPosition = new Point(range.start.row, 0)
else if range.start.isGreaterThan(currentBufferPosition)
endOfWordPosition = range.start
else
endOfWordPosition = range.end
if not endOfWordPosition?.isEqual(currentBufferPosition)
stop()
endOfWordPosition or currentBufferPosition
getMoveNextWordBoundaryBufferPosition: (options) ->
deprecate 'Use `::getNextWordBoundaryBufferPosition(options)` instead'
@getNextWordBoundaryBufferPosition(options)
# Public: Retrieves the buffer position of where the current word starts.
#
# * `options` (optional) An {Object} with the following keys:
@@ -511,6 +452,49 @@ class Cursor extends Model
else
currentBufferPosition
# Public: Retrieves buffer position of previous word boundary. It might be on
# the current word, or the previous word.
getPreviousWordBoundaryBufferPosition: (options = {}) ->
currentBufferPosition = @getBufferPosition()
previousNonBlankRow = @editor.buffer.previousNonBlankRow(currentBufferPosition.row)
scanRange = [[previousNonBlankRow, 0], currentBufferPosition]
beginningOfWordPosition = null
@editor.backwardsScanInBufferRange (options.wordRegex ? @wordRegExp()), scanRange, ({range, stop}) ->
if range.start.row < currentBufferPosition.row and currentBufferPosition.column > 0
# force it to stop at the beginning of each line
beginningOfWordPosition = new Point(currentBufferPosition.row, 0)
else if range.end.isLessThan(currentBufferPosition)
beginningOfWordPosition = range.end
else
beginningOfWordPosition = range.start
if not beginningOfWordPosition?.isEqual(currentBufferPosition)
stop()
beginningOfWordPosition or currentBufferPosition
# Public: Retrieves buffer position of the next word boundary. It might be on
# the current word, or the previous word.
getMoveNextWordBoundaryBufferPosition: (options = {}) ->
currentBufferPosition = @getBufferPosition()
scanRange = [currentBufferPosition, @editor.getEofBufferPosition()]
endOfWordPosition = null
@editor.scanInBufferRange (options.wordRegex ? @wordRegExp()), scanRange, ({range, stop}) ->
if range.start.row > currentBufferPosition.row
# force it to stop at the beginning of each line
endOfWordPosition = new Point(range.start.row, 0)
else if range.start.isGreaterThan(currentBufferPosition)
endOfWordPosition = range.start
else
endOfWordPosition = range.end
if not endOfWordPosition?.isEqual(currentBufferPosition)
stop()
endOfWordPosition or currentBufferPosition
# Public: Retrieves the buffer position of where the current word ends.
#
# * `options` (optional) {Object} with the following keys:
+4 -3
Ver Arquivo
@@ -735,7 +735,9 @@ class DisplayBuffer extends Model
#
# Returns a {Point}.
screenPositionForBufferPosition: (bufferPosition, options) ->
throw new Error("This TextEditor has been destroyed") if @isDestroyed()
# TODO: Expand this exception to cover all versions once we burn it in on non-release builds
if @isDestroyed() and not atom.isReleasedVersion()
throw new Error("This TextEditor has been destroyed")
{ row, column } = @buffer.clipPosition(bufferPosition)
[startScreenRow, endScreenRow] = @rowMap.screenRowRangeForBufferRow(row)
@@ -1075,9 +1077,8 @@ class DisplayBuffer extends Model
destroyed: ->
marker.unsubscribe() for id, marker of @markers
@scopedConfigSubscriptions.dispose()
@unsubscribe()
@tokenizedBuffer.destroy()
@unsubscribe()
logLines: (start=0, end=@getLastRow()) ->
for row in [start..end]
+11 -16
Ver Arquivo
@@ -1,8 +1,9 @@
{basename, join} = require 'path'
_ = require 'underscore-plus'
{Subscriber} = require 'emissary'
EmitterMixin = require('emissary').Emitter
{Emitter, Disposable, CompositeDisposable} = require 'event-kit'
{Emitter} = require 'event-kit'
fs = require 'fs-plus'
GitUtils = require 'git-utils'
{deprecate} = require 'grim'
@@ -44,6 +45,7 @@ Task = require './task'
module.exports =
class GitRepository
EmitterMixin.includeInto(this)
Subscriber.includeInto(this)
@exists: (path) ->
if git = @open(path)
@@ -73,8 +75,6 @@ class GitRepository
constructor: (path, options={}) ->
@emitter = new Emitter
@subscriptions = new CompositeDisposable
@repo = GitUtils.open(path)
unless @repo?
throw new Error("No Git repository found searching path: #{path}")
@@ -88,15 +88,13 @@ class GitRepository
refreshOnWindowFocus ?= true
if refreshOnWindowFocus
onWindowFocus = =>
{$} = require './space-pen-extensions'
@subscribe $(window), 'focus', =>
@refreshIndex()
@refreshStatus()
window.addEventListener 'focus', onWindowFocus
@subscriptions.add new Disposable(-> window.removeEventListener 'focus', onWindowFocus)
if @project?
@subscriptions.add @project.eachBuffer (buffer) => @subscribeToBuffer(buffer)
@subscribe @project.eachBuffer (buffer) => @subscribeToBuffer(buffer)
# Public: Destroy this {GitRepository} object.
#
@@ -111,7 +109,7 @@ class GitRepository
@repo.release()
@repo = null
@subscriptions.dispose()
@unsubscribe()
###
Section: Event Subscription
@@ -405,13 +403,10 @@ class GitRepository
if path = buffer.getPath()
@getPathStatus(path)
bufferSubscriptions = new CompositeDisposable
bufferSubscriptions.add buffer.onDidSave(getBufferPathStatus)
bufferSubscriptions.add buffer.onDidReload(getBufferPathStatus)
bufferSubscriptions.add buffer.onDidChangePath(getBufferPathStatus)
bufferSubscriptions.add buffer.onDidDestroy =>
bufferSubscriptions.dispose()
@subscriptions.remove(bufferSubscriptions)
@subscribe buffer.onDidSave(getBufferPathStatus)
@subscribe buffer.onDidReload(getBufferPathStatus)
@subscribe buffer.onDidChangePath(getBufferPathStatus)
@subscribe buffer.onDidDestroy => @unsubscribe(buffer)
# Subscribes to editor view event.
checkoutHeadForEditor: (editor) ->
+2 -6
Ver Arquivo
@@ -16,12 +16,12 @@ GutterComponent = React.createClass
measuredWidth: null
render: ->
{scrollHeight, scrollViewHeight, backgroundColor, gutterBackgroundColor} = @props
{scrollHeight, scrollViewHeight, onMouseDown, backgroundColor, gutterBackgroundColor} = @props
if gutterBackgroundColor isnt 'rbga(0, 0, 0, 0)'
backgroundColor = gutterBackgroundColor
div className: 'gutter',
div className: 'gutter', onClick: @onClick, onMouseDown: @onMouseDown,
div className: 'line-numbers', ref: 'lineNumbers', style:
height: Math.max(scrollHeight, scrollViewHeight)
WebkitTransform: @getTransform()
@@ -45,10 +45,6 @@ GutterComponent = React.createClass
@appendDummyLineNumber()
@updateLineNumbers() if @props.performedInitialMeasurement
node = @getDOMNode()
node.addEventListener 'click', @onClick
node.addEventListener 'mousedown', @onMouseDown
# Only update the gutter if the visible row range has changed or if a
# non-zero-delta change to the screen lines has occurred within the current
# visible row range.
+9 -16
Ver Arquivo
@@ -14,9 +14,9 @@ HighlightComponent = React.createClass
div {className},
if endPixelPosition.top is startPixelPosition.top
@renderSingleLineRegions(decoration.deprecatedRegionClass)
@renderSingleLineRegions()
else
@renderMultiLineRegions(decoration.deprecatedRegionClass)
@renderMultiLineRegions()
componentDidMount: ->
{editor, decoration} = @props
@@ -41,32 +41,25 @@ HighlightComponent = React.createClass
removeFlashClass = -> node.classList.remove(flash.class)
@flashTimeoutId = setTimeout(removeFlashClass, flash.duration)
renderSingleLineRegions: (regionClass) ->
renderSingleLineRegions: ->
{startPixelPosition, endPixelPosition, lineHeightInPixels} = @props
className = 'region'
className += " #{regionClass}" if regionClass?
[
div className: className, key: 0, style:
div className: 'region', key: 0, style:
top: startPixelPosition.top
height: lineHeightInPixels
left: startPixelPosition.left
width: endPixelPosition.left - startPixelPosition.left
]
renderMultiLineRegions: (regionClass) ->
renderMultiLineRegions: ->
{startPixelPosition, endPixelPosition, lineHeightInPixels} = @props
className = 'region'
className += " #{regionClass}" if regionClass?
regions = []
index = 0
# First row, extending from selection start to the right side of screen
regions.push(
div className: className, key: index++, style:
div className: 'region', key: index++, style:
top: startPixelPosition.top
left: startPixelPosition.left
height: lineHeightInPixels
@@ -76,7 +69,7 @@ HighlightComponent = React.createClass
# Middle rows, extending from left side to right side of screen
if endPixelPosition.top - startPixelPosition.top > lineHeightInPixels
regions.push(
div className: className, key: index++, style:
div className: 'region', key: index++, style:
top: startPixelPosition.top + lineHeightInPixels
height: endPixelPosition.top - startPixelPosition.top - lineHeightInPixels
left: 0
@@ -85,7 +78,7 @@ HighlightComponent = React.createClass
# Last row, extending from left side of screen to selection end
regions.push(
div className: className, key: index, style:
div className: 'region', key: index, style:
top: endPixelPosition.top
height: lineHeightInPixels
left: 0
@@ -95,4 +88,4 @@ HighlightComponent = React.createClass
regions
shouldComponentUpdate: (newProps) ->
not isEqualForProperties(newProps, @props, 'startPixelPosition', 'endPixelPosition', 'lineHeightInPixels', 'decoration')
not isEqualForProperties(newProps, @props, 'startPixelPosition', 'endPixelPosition', 'lineHeightInPixels')
+1 -7
Ver Arquivo
@@ -17,15 +17,9 @@ HighlightsComponent = React.createClass
highlightComponents = []
for markerId, {startPixelPosition, endPixelPosition, decorations} of highlightDecorations
for decoration in decorations
highlightComponents.push(HighlightComponent({editor, key: "#{markerId}-#{decoration.id}", startPixelPosition, endPixelPosition, decoration, lineHeightInPixels}))
highlightComponents.push(HighlightComponent({editor, key: "#{markerId}-#{decoration.class}", startPixelPosition, endPixelPosition, decoration, lineHeightInPixels}))
highlightComponents
componentDidMount: ->
if atom.config.get('editor.useShadowDOM')
insertionPoint = document.createElement('content')
insertionPoint.setAttribute('select', '.underlayer')
@getDOMNode().appendChild(insertionPoint)
shouldComponentUpdate: (newProps) ->
not isEqualForProperties(newProps, @props, 'highlightDecorations', 'lineHeightInPixels', 'defaultCharWidth', 'scopedCharacterWidthsChangeCount')
+19
Ver Arquivo
@@ -0,0 +1,19 @@
fs = require 'fs'
# Public:
module.exports =
class HTMLRequire
@register: ->
require.extensions['.html'] = (module, filePath) ->
html = fs.readFileSync(filePath, 'utf8')
template = document.createElement('template')
template.innerHTML = html
docFragment = template.content
module.exports = new HTMLRequire(template.content)
constructor: (@documentFragment) ->
getDocumentFragment: -> @documentFragment
clone: ->
@documentFragment.cloneNode(true)
+10 -5
Ver Arquivo
@@ -7,17 +7,16 @@ InputComponent = React.createClass
displayName: 'InputComponent'
render: ->
{className, style} = @props
{className, style, onFocus, onBlur} = @props
input {className, style, 'data-react-skip-selection-restoration': true}
input {className, style, onFocus, onBlur, 'data-react-skip-selection-restoration': true}
getInitialState: ->
{lastChar: ''}
componentDidMount: ->
node = @getDOMNode()
node.addEventListener 'paste', @onPaste
node.addEventListener 'compositionupdate', @onCompositionUpdate
@getDOMNode().addEventListener 'paste', @onPaste
@getDOMNode().addEventListener 'compositionupdate', @onCompositionUpdate
# Don't let text accumulate in the input forever, but avoid excessive reflows
componentDidUpdate: ->
@@ -35,5 +34,11 @@ InputComponent = React.createClass
onPaste: (e) ->
e.preventDefault()
onFocus: ->
@props.onFocus?()
onBlur: ->
@props.onBlur?()
focus: ->
@getDOMNode().focus()

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