Comparar commits

...

258 Commits

Autor SHA1 Mensagem Data
Nathan Sobo fdfb88c8e5 Invoke handlers on detached DOM nodes 2014-10-30 09:46:31 -06:00
Nathan Sobo 0a73550213 Patch Node::add/removeEventListener to use the CommandRegistry
This ensures that all listeners slot into the correct location in a
single dispatch, regardless of whether they are added with
Node::addEventListener or via CommandRegistry::listen/capture. This
allows selector-based listeners to integrate into the rest of events
in a global way.
2014-10-29 17:09:23 -06:00
Nathan Sobo d88b8e854b Add CommandRegistry::capture and perform capture-phase dispatch 2014-10-29 15:40:36 -06:00
Nathan Sobo 3ea2746b4d Rename CommandManager::add to ::listen
This will complement a method for registering capture-phase listeners,
which will be called ::capture instead of ::listen. This is clearer than
passing a boolean argument like the native APIs do, and we need to
support capture if we’re going to take over all event handling.
2014-10-29 11:42:23 -06:00
Nathan Sobo 752ba0a698 Use default ::bubbles setting when dispatching native events w/ strings 2014-10-29 11:42:23 -06:00
Nathan Sobo a75eefcf55 Honor the ::bubbles property on dispatched events 2014-10-29 11:41:35 -06:00
Nathan Sobo 6e89c07891 Handle keydown events via CommandRegistry 2014-10-29 11:41:35 -06:00
Nathan Sobo 5a041721cd Use addEventListener in $.fn.enableKeymap 2014-10-29 11:41:35 -06:00
Nathan Sobo 3feb5568f2 Route all jQuery events via CommandRegistry unless they have namespaces 2014-10-29 11:41:35 -06:00
Nathan Sobo 5e320b39d9 Allow event objects to be dispatched via CommandRegistry::dispatch 2014-10-29 11:41:35 -06:00
Kevin Sawicki 1eaba0cb52 ⬆️ fuzzy-finder@0.60 2014-10-29 10:36:09 -07:00
Kevin Sawicki 0c590d6170 Load CoffeeScript when using a custom resource path
Load CoffeeScript early whenever the resource path a subdirectory
from process.resourcesPath

Close #3993
2014-10-29 10:21:23 -07:00
Kevin Sawicki 3df72ec173 ⬆️ apm@0.109 2014-10-29 09:51:59 -07:00
Kevin Sawicki 1456bf0d91 📝 runnung -> running 2014-10-29 09:01:18 -07:00
Kevin Sawicki edec6b9b0a 🐎 Use cached pair character information
Tokenized lines break out atomic tokens so trust the hasPairCharacter
value on the token instead of rechecking it.
2014-10-28 18:15:13 -07:00
Kevin Sawicki 9abc4580f4 Don't recompute pair boolean when building token
Pass in hasPairedCharacter to the Token constructor when it is
being broken out from the parent token instead of recomputing it.
2014-10-28 18:15:13 -07:00
Nathan Sobo 54260230c6 ⬆️ git-diff to prevent updating diffs on destroyed editors 2014-10-28 19:08:30 -06:00
Kevin Sawicki 9bd11fc2f7 Merge pull request #3989 from Bengt/patch-1
Add initial instructions to build rpm from sources, ...
2014-10-28 17:10:22 -07:00
Bengt Lüers 81586d22f4 Add initial instructions to build rpm from sources, add packaging dependency for Fedora 2014-10-29 01:09:21 +01:00
Kevin Sawicki dc824485aa Pass character codes around in TextUtils
Previously the character codes were looked up for each type of character pair.
2014-10-28 16:55:36 -07:00
Kevin Sawicki d1fcfabf0b Move comment above module.exports
Make it parseable by donna

Refs atom/donna#2
2014-10-28 16:20:11 -07:00
Nathan Sobo ea8a3a78da Don’t hide pane items that are already hidden 2014-10-28 11:23:35 -06:00
Kevin Sawicki 62f5d0f7f3 ⬆️ go-to-line@0.26 2014-10-27 16:18:21 -07:00
Kevin Sawicki b3f4d03a82 Add Red Hat install instructions
0.140 include an .rpm file on the releases page and this adds back
the install text added by @ardeshirj in #3797
2014-10-27 16:08:21 -07:00
Kevin Sawicki c2d51858b1 ⬆️ markdown-preview@0.107 2014-10-27 15:25:14 -07:00
Kevin Sawicki a5bca03a46 Prepare 0.141 2014-10-27 15:12:44 -07:00
Nathan Sobo 02d20e3155 Call legacy SpacePen remove hooks before unmounting TextEditorComponent 2014-10-27 15:29:59 -06:00
Nathan Sobo 2910e017bb Unmount TextEditorComponent when TextEditor is destroyed
We don’t want to do it when the element is detached because it might
be caused by moving the editor rather than destroying it. Unmounting
the component entirely and then remounting it causes the hidden input
to not be recycled, interfering with focus restoration. Watching for
destruction of the model is a good way to ensure we always tear down
the view at the right time without doing it prematurely.
2014-10-27 15:12:30 -06:00
Kevin Sawicki 248e164de2 ⬆️ language-ruby@0.41 2014-10-27 13:31:16 -07:00
Nathan Sobo 4d796f614c Update Tokenized/DisplayBuffer prior to TextBuffer::onDidChange handlers
Fixes #3789
2014-10-27 13:56:23 -06:00
Kevin Sawicki a8be05bb3b Clear focused window property on window closed
Closes #3806
2014-10-27 11:30:41 -07:00
Kevin Sawicki 101904e261 Upgrade to bracket-matcher@0.62 2014-10-27 11:15:53 -07:00
Nathan Sobo c0622e8bb5 ⬆️ language-coffee-script to fix jasmine snippet quotes 2014-10-27 11:55:24 -06:00
Kevin Sawicki ce5b755438 📝 Mention profile picture 2014-10-27 10:45:15 -07:00
Nathan Sobo 86781e6f9a Assign pane container before emitting onDidAddPane events
Fixes #3972
2014-10-27 11:39:42 -06:00
Kevin Sawicki a7f4a5b08e ⬆️ markdown-preview@0.106 2014-10-27 10:38:43 -07:00
Nathan Sobo 2b8167da53 Merge pull request #3974 from atom/ns-throw-on-destroyed-editors
Throw on non-release builds if translating positions on destroyed editor
2014-10-27 11:32:48 -06:00
Kevin Sawicki bb0ee8a78b ⬆️ atom-dark-syntax@0.20 2014-10-27 09:42:54 -07:00
Kevin Sawicki d1115d4c7c ⬆️ atom-light-syntax@0.21 2014-10-27 09:40:31 -07:00
Kevin Sawicki a71d7115bf ⬆️ language-sass@0.24 2014-10-27 09:37:27 -07:00
Kevin Sawicki af14a26625 Merge pull request #3965 from brunetton/master
📝 fix TextEditor::delete() doc
2014-10-27 09:13:04 -07:00
Kevin Sawicki dadd56f7a0 ⬆️ language-php@0.17 2014-10-27 09:12:30 -07:00
Kevin Sawicki 0e99b70650 🐧 Add troubleshooting for system gyp error
Closes #2824
2014-10-27 08:45:15 -07:00
Nathan Sobo 2965398062 Throw on non-release builds if translating positions on destroyed editor
It’s possible that bundled packages stray into this corner case, so I’d
like us to catch and fix misbehaving packages before exposing users to 
any exceptions. Once we go one release with this turned on, we can
enable the exception for all builds.
2014-10-27 07:38:18 -06:00
Bruno Duyé 55ace0fe99 📝 fix TextEditor::delete() doc 2014-10-25 19:35:19 +02:00
Nathan Sobo 03f7511229 ⬆️ find and replace for focus transfer fix 2014-10-24 16:14:52 -06:00
Kevin Sawicki 5f7976cada ⬆️ apm 0.108 2014-10-24 14:14:10 -07:00
Kevin Sawicki fa074431f9 Merge pull request #3953 from atom/ks-support-combining-characters
Support unicode combining characters
2014-10-24 14:13:40 -07:00
Kevin Sawicki b9239ffc57 Add spec for cursor position after pair char 2014-10-24 13:31:43 -07:00
Kevin Sawicki 06698c880f Access value on token 2014-10-24 13:31:43 -07:00
Kevin Sawicki 05dc9aad89 💄 2014-10-24 13:31:43 -07:00
Kevin Sawicki e5660e5e83 🐎 Only use String::substr for pair chars 2014-10-24 13:31:43 -07:00
Kevin Sawicki e928447eab Stored paired characters in width cache
Previously characters were treated individually even when multiple
characters would render as a single character on screen.
2014-10-24 13:31:43 -07:00
Kevin Sawicki 9b0f622ffb 📝 Mention combined characters in spec description 2014-10-24 13:31:42 -07:00
Kevin Sawicki b6cc7273a1 Add combined characters to spec 2014-10-24 13:31:42 -07:00
Kevin Sawicki 232be1f876 📝 Mention combined characters 2014-10-24 13:31:42 -07:00
Kevin Sawicki ddeec5d4d5 Treat combined characters as paired characters 2014-10-24 13:31:42 -07:00
Ben Ogle dc83f8bac7 Merge pull request #3944 from atom/bo-defer-config-load
Give scoped user settings a priority
2014-10-24 13:10:49 -07:00
Ben Ogle ae2a7769ed Upgrade scoped-property-store for priority option 2014-10-24 13:08:00 -07:00
Ben Ogle d0d6af7e55 Specs for priority 2014-10-24 13:07:14 -07:00
Ben Ogle 137df72a60 Give the user settings a priority
Base index 1000
2014-10-24 13:07:14 -07:00
Ben Ogle 2e187d3ec1 Upgrade scandal@1.0.3 for isBinary Fix 2014-10-24 11:48:03 -07:00
Ben Ogle 9f74250333 Upgrade whitespace to use scoped properties 2014-10-24 11:18:09 -07:00
Nathan Sobo de70a181c5 Upgrade text-buffer to avoid many position translation errors
Refs #3192
2014-10-24 10:55:51 -06:00
Kevin Sawicki 0272b2f281 ⬆️ spell-check@0.43 2014-10-24 09:15:09 -07:00
Kevin Sawicki 365b7bfaf9 Merge pull request #3950 from avdv/patch-1
Update linux.md
2014-10-24 09:11:35 -07:00
Claudio Bley 937ef321bd Update linux.md
You need to have python2 installed on Arch.

Otherwise you get build ENOENT errors using npm-gyp.
2014-10-24 14:08:10 +02:00
Kevin Sawicki 80a302df9e ⬆️ apm 0.107 2014-10-23 17:55:21 -07:00
Kevin Sawicki 381ee353a3 Upgrade to git-diff@0.41 2014-10-23 16:06:14 -07:00
Kevin Sawicki de3703d1ea 📝 Mark CommandRegistry and atom.commands public 2014-10-23 14:08:09 -07:00
Kevin Sawicki 0b8c4a0c7f ⬆️ image-view@0.38 2014-10-23 12:20:13 -07:00
Kevin Sawicki d299692237 Use correct 64-bith arch 2014-10-23 12:02:52 -07:00
Kevin Sawicki eaf435bd9a Merge pull request #3942 from atom/ks-fedora-dockerfile
Add Dockerfile to build an RPM on CI
2014-10-23 11:36:31 -07:00
Kevin Sawicki 8d71cbd510 📝 Mention fedora/debian checks 2014-10-23 11:10:18 -07:00
Kevin Sawicki 534ace6250 Use x64_64 as arch in rpm name 2014-10-23 11:09:48 -07:00
Kevin Sawicki 89157cdf29 Restore master only uploads 2014-10-23 10:49:05 -07:00
Kevin Sawicki ef2795ea0d Use bash 2014-10-23 10:35:18 -07:00
Kevin Sawicki 11b5bcff74 Use BUILD_ATOM_RPM_ACCESS_TOKEN 2014-10-23 10:10:05 -07:00
Kevin Sawicki d7019509e3 Return early when no token set 2014-10-23 10:01:26 -07:00
Kevin Sawicki 0417458fbb Log when token is missing 2014-10-23 09:56:44 -07:00
Kevin Sawicki ff32fff483 Add missing mkdir assignment 2014-10-23 09:28:47 -07:00
Kevin Sawicki f776678b83 Recreate rpm dir after deleting 2014-10-23 09:20:28 -07:00
Kevin Sawicki edacf02222 📝 Tweak image description 2014-10-23 09:11:13 -07:00
Kevin Sawicki 4b3d3701d5 Add rpm segment in mkrpm script 2014-10-23 09:10:16 -07:00
Kevin Sawicki dcbd1723b7 ⬆️ language-less@0.18 2014-10-23 08:58:35 -07:00
Kevin Sawicki 6c00dbd5ec ⬆️ language-less@0.17 2014-10-23 08:45:49 -07:00
Cheng Zhao 14fd4a9f7d 'enabled' is also a valid item attribute, fixes #3880 2014-10-23 10:34:15 +08:00
Kevin Sawicki b65c6da948 Add rm assignment to right task 2014-10-22 18:09:47 -07:00
Kevin Sawicki 1c1adf5beb Add missing rm assignment 2014-10-22 17:57:15 -07:00
Kevin Sawicki c1197d6390 Map BUILD_ATOM_LINUX_ACCESS_TOKEN to ATOM_ACCESS_TOKEN 2014-10-22 17:50:23 -07:00
Kevin Sawicki 7713720ba7 Drop x flag 2014-10-22 17:47:29 -07:00
Kevin Sawicki 4f1ec786f0 Add missing _ in env var 2014-10-22 17:47:13 -07:00
Kevin Sawicki 27ff02ad0e script/dockerbuild -> script/rpmbuild 2014-10-22 17:41:25 -07:00
Kevin Sawicki 738cdb6e66 Add missing _ in env var 2014-10-22 17:38:06 -07:00
Kevin Sawicki 0818e6d736 Log stack for now 2014-10-22 17:35:39 -07:00
Kevin Sawicki 6b57030bda Test uploads on this branch 2014-10-22 17:33:26 -07:00
Kevin Sawicki b64a5c93e3 Pass through needed env vars 2014-10-22 17:32:52 -07:00
Kevin Sawicki 317001b435 Do everything from dockerbuild script 2014-10-22 17:27:13 -07:00
Kevin Sawicki 4e3d15592e Upload .rpm file when available 2014-10-22 17:26:58 -07:00
Kevin Sawicki f4c40c2932 Publish build from dockerbuild 2014-10-22 17:26:35 -07:00
Kevin Sawicki 9cfc451a79 Remove RPM directory before rebuilding 2014-10-22 17:26:23 -07:00
Kevin Sawicki 198d3e90c7 Add initial rpm cibuild script 2014-10-22 17:04:59 -07:00
Kevin Sawicki 00da8a9df6 Build into rpm directory 2014-10-22 17:03:30 -07:00
Kevin Sawicki 293bd3ad3d Add initial script/dockerbuild 2014-10-22 17:03:19 -07:00
Kevin Sawicki bd0564e30d Move rpm Dockerfile to root 2014-10-22 17:03:05 -07:00
Kevin Sawicki 953940c757 Move debian Dockerfile to build folder 2014-10-22 16:53:22 -07:00
Kevin Sawicki 4ff6366d2b Add initial script/cibuild-atom-rpm 2014-10-22 16:18:05 -07:00
Kevin Sawicki 4db441f4df Add initial Fedora Dockerfile 2014-10-22 16:12:29 -07:00
Kevin Sawicki 71ef21bb70 📝 Link to roadmap issue 2014-10-22 12:59:57 -07:00
Kevin Sawicki de5e443329 Merge pull request #3925 from jfrazelle/dockerfile
Add Dockerfile.
2014-10-22 11:12:52 -07:00
Kevin Sawicki 6e15d68163 Prepare 0.140 2014-10-22 10:38:01 -07:00
Jessica Frazelle 6a3c7bcd50 Add Dockerfile.
I'm just going to leave this here.

You see I was trying to containerize a node webkit app, so I
thought why not atom. Except halfway through I realized it
actually isn't a node webkit app. I finished it anyways
because I had already started. It mounts the X11 socket
so it's a containerized desktop app.
You can do what you want with it.

But since this is OSS, I am going to give you my opinion
anyway. So here it is:
You should take this and use it as a build script, because
it seems like building this is a real PITA.

Ok that's all, enjoy.
Also this file was written in vim.
No, I'm not sorry.

Signed-off-by: Jessica Frazelle <jess@docker.com>
2014-10-22 10:27:25 -07:00
Kevin Sawicki dfc0df42b2 ⬆️ underscore-plus@1.6.1 2014-10-22 10:21:08 -07:00
Kevin Sawicki 452c78b735 Use local variable over calling method again 2014-10-22 09:31:45 -07:00
Kevin Sawicki 42f67033cc Merge pull request #3916 from suda/master
Setting ATOM_HOME
2014-10-22 09:31:11 -07:00
Kevin Sawicki 5c417cf9cc ⬆️ language-sass@0.23 2014-10-21 17:31:40 -07:00
Kevin Sawicki 81143af4b4 Upgrade to markdown-preview@0.105 2014-10-21 16:41:39 -07:00
Kevin Sawicki 5c048a4f13 ⬆️ less-cache@0.17 2014-10-21 15:57:00 -07:00
Kevin Sawicki 2ac9cc9ed1 ⬆️ less-cache@0.16 2014-10-21 15:51:16 -07:00
Kevin Sawicki e8f8ead53f ⬆️ donna@1.0.6 2014-10-21 15:19:18 -07:00
Kevin Sawicki f3d8c5d7ec ⬆️ language-javascript@0.42 2014-10-21 15:14:18 -07:00
Ben Ogle 7d179ef40f Revert "back to 1.0.1"
This reverts commit 375b8efc22.
2014-10-21 14:41:12 -07:00
Ben Ogle 375b8efc22 back to 1.0.1 2014-10-21 14:34:00 -07:00
Kevin Sawicki 086a011a63 Upgrade to settings-view@0.153 2014-10-21 14:30:16 -07:00
Ben Ogle 46ff52b13a UPgrade donna again 2014-10-21 14:16:30 -07:00
Ben Ogle 0ed4d07c33 Upgrade to donna@1.0.4 2014-10-21 14:13:48 -07:00
Kevin Sawicki efe3d65291 Only upload on master 2014-10-21 14:11:06 -07:00
Kevin Sawicki 8576486d06 Prepare docs when building all branches 2014-10-21 14:10:44 -07:00
Kevin Sawicki e5abca138d ⬆️ language-gfm@0.53 2014-10-21 13:50:40 -07:00
Kevin Sawicki fa24154e24 ⬆️ grunt-download-atom-shell@0.10 2014-10-21 13:50:16 -07:00
Kevin Sawicki 45c05d3b7d Merge pull request #3917 from atom/ks-packages-slug
Inline package metadata in main package.json file
2014-10-21 13:49:39 -07:00
Kevin Sawicki bf4ac1d3eb 💄 2014-10-21 13:28:09 -07:00
Kevin Sawicki 892cdae622 Return false when resource path does not match resources path 2014-10-21 13:28:09 -07:00
Kevin Sawicki f33d7ba27f 📝 store -> stored 2014-10-21 13:28:09 -07:00
Kevin Sawicki 06436ef530 📝 Remove extra to 2014-10-21 13:28:09 -07:00
Kevin Sawicki 815244bba0 Delete from local cache reference 2014-10-21 13:28:08 -07:00
Kevin Sawicki 0303ebb5e5 Add resolved main path to package cache 2014-10-21 13:28:08 -07:00
Kevin Sawicki eab791d47e Cache paths are relative to resource path 2014-10-21 13:28:08 -07:00
Kevin Sawicki 6ad96d98b8 Bypass cache when in dev mode 2014-10-21 13:28:08 -07:00
Kevin Sawicki ed4ebefdc1 Use resourcePath on PackageManager 2014-10-21 13:28:08 -07:00
Kevin Sawicki a1828fa3a6 Remove package's package.json from cache
This file is inlined in the main package.json
2014-10-21 13:28:08 -07:00
Kevin Sawicki 345c0f670c Ignore extensions from bundled packages
These are generated in their own cache
2014-10-21 13:28:08 -07:00
Kevin Sawicki d78e6fa711 Build path manually 2014-10-21 13:28:08 -07:00
Kevin Sawicki c3a6475308 Remove unused properties from metadata
Saves another ~50k
2014-10-21 13:28:08 -07:00
Kevin Sawicki 2cc9f6bee8 Use absolute keymap/menu paths 2014-10-21 13:28:08 -07:00
Kevin Sawicki 0c6fba2ce2 Remove inlined files from app directory 2014-10-21 13:28:08 -07:00
Kevin Sawicki fa72db87a2 Update task description 2014-10-21 13:28:07 -07:00
Kevin Sawicki a0d7bbdb92 Don't pretty print package.json
It is now ~400k pretty printed and ~300k without
2014-10-21 13:28:07 -07:00
Kevin Sawicki 4c3e1ef82b 💄 2014-10-21 13:28:07 -07:00
Kevin Sawicki 1056418f97 Only use cache for bundled packages 2014-10-21 13:28:07 -07:00
Kevin Sawicki 37040ad485 Use _atomPackage key from main metadata 2014-10-21 13:28:07 -07:00
Kevin Sawicki dee9cccae7 Use proper relative paths in cache 2014-10-21 13:28:07 -07:00
Kevin Sawicki 50e27854cc Cache package metadata in main package.json file 2014-10-21 13:28:07 -07:00
Ben Ogle c931071c91 Merge pull request #3910 from atom/bo-descriptor-object
Add a ScopeDescriptor object
2014-10-21 13:27:17 -07:00
Ben Ogle 498c8d21b2 Fix comments n junk 2014-10-21 13:27:01 -07:00
Ben Ogle 263b792eee Merge pull request #3907 from atom/bo-scoped-schema
Add support for scoped defaults in config schemas
2014-10-21 13:12:18 -07:00
Ben Ogle ffd3990a6b Split with the new method 2014-10-21 11:57:01 -07:00
Ben Ogle 31490ca31e Last of scopeDescriptor -> scopes from tokens 2014-10-21 11:49:49 -07:00
Ben Ogle 37159bb478 Oops, don’t call the method twice 2014-10-21 11:44:58 -07:00
Ben Ogle 16ad957609 scopeDescriptor -> scopes
Now that we have a real ScopeDescriptor object, 
these should change back!
2014-10-21 11:38:43 -07:00
Ben Ogle 137eeab4cf Return scopes arrays from deprecated methods
backward compatibility
2014-10-21 11:19:58 -07:00
Kevin Sawicki ce2076f30a Merge pull request #3909 from atom/ks-extension-cache-for-packages
Add extension cache for installed packages
2014-10-21 11:12:31 -07:00
Kevin Sawicki 8479d564f5 Enable extensions for installed packages 2014-10-21 11:02:24 -07:00
Kevin Sawicki ec6004615a Load extensions in ModuleCache.create 2014-10-21 10:59:29 -07:00
Kevin Sawicki 7e7441dc23 Merge pull request #3906 from atom/ks-change-menu-on-focus
Swap out application menus on focus
2014-10-21 10:36:14 -07:00
Kevin Sawicki 2a09d25eb1 📝 Add template 2014-10-21 10:22:50 -07:00
Kevin Sawicki d5508b338b Compare templates before swapping them out 2014-10-21 10:22:50 -07:00
Kevin Sawicki 86bd43bf73 Store each window's menu template
Restore it when the window gains focus
2014-10-21 10:22:50 -07:00
Kevin Sawicki 3075b74b64 Close the template
Menu.buildFromTemplate modifies it so copy before hand
so it can be reused
2014-10-21 10:22:50 -07:00
Kevin Sawicki 11d7437ecc Add setActiveTemplate helper 2014-10-21 10:22:49 -07:00
Cheng Zhao df439f5ada Merge pull request #3915 from atom/atom-shell-v0.18.2
Upgrade to atom-shell@0.18.2
2014-10-21 23:02:18 +08:00
Wojtek Siudzinski dc28ddbdc8 Setting ATOM_HOME 2014-10-21 16:55:10 +02:00
Nathan Sobo 49e98d368a Log a warning if a package has an incompatible main module
I’ve been tripped up by this twice now, so it would be good to provide
some feedback when it happens.
2014-10-21 08:54:16 -06:00
Cheng Zhao 02e91aa4cd ⬆️ atom-shell@0.18.2 2014-10-21 22:46:40 +08:00
Ben Ogle 14c8e9cedc Fix specs 2014-10-20 18:40:32 -07:00
Kevin Sawicki 4867e3ef14 Upgrade to tabs@0.55 2014-10-20 18:03:11 -07:00
Ben Ogle 3a70b98ae1 ScopeDescriptor::create -> fromObject 2014-10-20 17:59:28 -07:00
Ben Ogle 08f35531ba Update descriptor docs 2014-10-20 17:49:14 -07:00
Ben Ogle ce2959c0b9 Return ScopeDescriptor objects 2014-10-20 17:49:02 -07:00
Ben Ogle 4c4b82fe6c Add new ScopeDescriptor object 2014-10-20 17:29:46 -07:00
Kevin Sawicki f4c3050050 Upgrade to snippets@0.56 2014-10-20 17:14:42 -07:00
Ben Ogle 2b148b7720 Accept escaped dots in config settings keys
Fixes #3898
2014-10-20 16:58:57 -07:00
Ben Ogle c40dd16466 Upgrade to underscore-plus 1.6 2014-10-20 16:57:46 -07:00
Ben Ogle 7ffe5d1385 Add support for scoped defaults in config schemas 2014-10-20 14:52:12 -07:00
Kevin Sawicki c2ef68a435 Go back to using a concurrency of 2 2014-10-20 14:21:20 -07:00
Kevin Sawicki aa117774b3 Experiment with longer timeout on Mac CI 2014-10-20 13:52:39 -07:00
Kevin Sawicki 6b44369458 Log time taken to upload 2014-10-20 13:37:19 -07:00
Kevin Sawicki 177b3a6d14 Use all the available cores on CI 2014-10-20 13:35:09 -07:00
Ben Ogle 4d1e488ef4 Add contributing to packages to the index 2014-10-20 13:34:15 -07:00
Ben Ogle 0a39c28a79 update contributing to packages to not mention amp develop 2014-10-20 13:34:15 -07:00
Kevin Sawicki e019347ca4 Output total spec time 2014-10-20 13:28:30 -07:00
Ben Ogle b425df1d58 Merge pull request #3837 from atom/bo-panel-api
Add panel API
2014-10-20 13:25:48 -07:00
Ben Ogle 055c632ee9 Call save() in restoreDefault() for scopedSettings 2014-10-20 12:29:46 -07:00
Ben Ogle 2ac1862e5f Remove toHide matcher. 2014-10-20 12:12:21 -07:00
Ben Ogle 5a82afd333 💄 2014-10-20 12:03:48 -07:00
Kevin Sawicki 13f81a452d Upgrade to language-less@0.16 2014-10-20 10:16:22 -07:00
Kevin Sawicki c8144b7e1b Upgrade to language-yaml@0.19 2014-10-20 09:40:36 -07:00
Nathan Sobo b3b78fa926 Merge pull request #3883 from atom/ns-core-specs-from-anywhere
Allow core specs from command line in atom repository regardless of its location
2014-10-20 10:29:13 -06:00
Nathan Sobo 824c00dab3 Add environment variable to the usage string instead of at end 2014-10-20 10:12:32 -06:00
Nathan Sobo 8d331e94d2 Preserve alphabetical sort order for options 2014-10-20 10:07:40 -06:00
Nathan Sobo bc2dd9f52c Drop unnecessary encoding argument 2014-10-20 10:06:19 -06:00
Nathan Sobo 5dd9f9c5ad Fix typo in comment 2014-10-20 10:05:53 -06:00
Kevin Sawicki 3f1afec15b 📝 Link to CSON description 2014-10-20 09:01:17 -07:00
Kevin Sawicki e4705d45c4 Merge pull request #3769 from Maxhodges/keymap-advice
Warn new users we are using a little known format (cson), not the more popular json doc notation.
2014-10-20 08:58:12 -07:00
Kevin Sawicki c0846ab8a6 Upgrade to deprecation-cop@0.11 2014-10-20 08:55:36 -07:00
Kevin Sawicki bfbb262844 Merge pull request #3886 from fenuks/patch-1
Add GenericName to .desktop file
2014-10-20 08:32:13 -07:00
fenuks 5669aa39ce 🐧 Add GenericName to .desktop file, fixes #3885 2014-10-18 20:07:54 +02:00
Nathan Sobo d1f9133ef4 Merge pull request #3830 from atom/ns-extract-style-manager
Extract style manager from theme manager
2014-10-17 18:11:16 -06:00
Nathan Sobo 362c9c8588 Document ATOM_DEV_RESOURCE_PATH environment variable in atom —help 2014-10-17 18:00:45 -06:00
Nathan Sobo c63cde1cd3 Set resource path based on spec directory when running atom core specs
Fixes #3872
2014-10-17 18:00:21 -06:00
Nathan Sobo 6d937831b9 Clarify spec-directory documentation in atom executable 2014-10-17 17:18:43 -06:00
Nathan Sobo 0eacbed162 Document the resource-path option to atom executable 2014-10-17 17:18:30 -06:00
Ben Ogle 6e034c6319 Call the attach hooks after adding a view to a panel. 2014-10-17 16:04:11 -07:00
Kevin Sawicki a4f6c674ef Upgrade to timecop@0.23 2014-10-17 15:51:57 -07:00
Kevin Sawicki 405af7fb16 Track time taken to read window state
Refs atom/timecop#6
2014-10-17 15:44:59 -07:00
Ben Ogle 995e89b5f6 📝 Move panels API for the sake of the docs 2014-10-17 15:42:16 -07:00
Kevin Sawicki 6b90b83867 ⬆️ apm@0.106 2014-10-17 15:34:03 -07:00
Ben Ogle 66d469ee10 Deprecate workspace pane methods 2014-10-17 15:31:56 -07:00
Ben Ogle 657cbc9c17 📝 Doc the new panel methods 2014-10-17 15:24:20 -07:00
Ben Ogle 29ea506f93 Doc Panel class 2014-10-17 15:23:20 -07:00
Ben Ogle 155d144788 Fix spec 2014-10-17 15:23:06 -07:00
Kevin Sawicki 892f341feb ⬆️ apm@0.105 2014-10-17 14:45:52 -07:00
Kevin Sawicki d5808b5c85 Merge pull request #3867 from atom/ks-select-past-last-line
Fix selecting past the last line
2014-10-17 14:38:18 -07:00
Kevin Sawicki d6feb686c1 Mention single click 2014-10-17 14:00:26 -07:00
Kevin Sawicki 5069a5b48b Add spec for clicking past last line 2014-10-17 14:00:25 -07:00
Kevin Sawicki 8c136b18c2 Set targetLeft to Infinity when past last row 2014-10-17 14:00:25 -07:00
Kevin Sawicki f81bc4b870 Never break when past the last row 2014-10-17 14:00:25 -07:00
Adam Boesch 111b956f93 Fix cursor not being able to move within the last line of text. 2014-10-17 14:00:25 -07:00
Adam Boesch 88a95ad06b Fix cursor so clicking the below the last line of text puts the cursor at
the end of the last line.
2014-10-17 14:00:25 -07:00
Kevin Sawicki 04bd602c23 Upgrade to language-c@0.29 2014-10-17 13:59:05 -07:00
Ben Ogle de78e53b35 Add priority system to the panels 2014-10-17 13:44:40 -07:00
Kevin Sawicki fb1a866447 Prepare 0.139 2014-10-17 13:18:59 -07:00
Ben Ogle b94485eafd Set the heights of atom panels for location left and right. 2014-10-17 12:08:24 -07:00
Ben Ogle f0fd7c2682 Add hide/show ability for panels 2014-10-16 17:32:24 -07:00
Ben Ogle 3f170a8b5e Add matcher toHide() 2014-10-16 17:31:30 -07:00
Ben Ogle 37a7cfaf9a Remove location junk from panel creation 2014-10-16 17:31:13 -07:00
Ben Ogle 5683491029 Rename custom element so as not to clash 2014-10-16 17:30:54 -07:00
Ben Ogle 4ca630a7da orientation -> location 2014-10-16 16:54:08 -07:00
Ben Ogle 99aedbab89 Panel container probably not public 2014-10-16 16:49:18 -07:00
Ben Ogle 52c05eade7 Render proper atom-panels as children of containers 2014-10-16 16:48:56 -07:00
Ben Ogle 299710f08a Integrate the pane containers into the workspace 2014-10-16 16:17:44 -07:00
Ben Ogle 83e5873f3b Panel containers have the orientation 2014-10-16 16:16:49 -07:00
Ben Ogle 5c2e55861c Add panel containers 2014-10-16 15:33:28 -07:00
Ben Ogle 734a79b7ec Add initial panel API.
It can only add things to the left right now.
2014-10-16 13:44:03 -07:00
Nathan Sobo 314c525d2d Assign properties in addition to attributes for convenience 2014-10-15 15:14:13 -06:00
Nathan Sobo 04b3eef768 Fix theme-manager-specs 2014-10-15 15:14:13 -06:00
Nathan Sobo 506753a535 Subscribe to <atom-styles> element to shim events in ThemeManager
This is better than subscribing to atom.styles because the events it
emits contain the *actual* style elements we insert into the DOM.
2014-10-15 15:14:13 -06:00
Nathan Sobo a8b9e1b790 Handle style element updates in StylesElement 2014-10-15 15:14:13 -06:00
Nathan Sobo be51ccf786 Add StylesElement::onDidAdd/RemoveStyleElement 2014-10-15 15:14:13 -06:00
Nathan Sobo 65e077abd1 Use StyleManager and StylesElement to manage all stylesheet elements
For now, loading remains in the theme manager, but all application of
stylesheets is routed through atom.styles.
2014-10-15 15:14:13 -06:00
Nathan Sobo 79598aaae9 Add StyleElement
This will be used to handle stylesheet rendering when we move management
of loading stylesheets to the StyleManager instead of the theme manager.
This sets us up for being able to render specific stylesheets in shadow
roots in addition to just having global stylesheets.
2014-10-15 15:14:13 -06:00
Nathan Sobo 62a43c6fb9 Revise StyleManager API 2014-10-15 15:14:12 -06:00
Nathan Sobo 1fe1147901 Add group parameter to StyleManager::addStyleSheet
This can be used to sequence style elements at the correct location in
the cascade even if they are loaded later than elements in a subsequent
group.
2014-10-15 15:14:12 -06:00
Nathan Sobo 1c97dcd195 Add sourcePath parameter to StyleManager::addStyleSheet 2014-10-15 15:14:12 -06:00
Nathan Sobo d3371dbcd2 Start on StyleManager
This will take over raw stylesheet management from the theme manager
now that it’s becoming more complex with the need to target specific
host elements. Instead of actually adding nodes to the head of the
document, it will instead simply manage a set of stylesheets we want to
apply and leave actual DOM manipulation to <atom-styles> custom elements
that can render the set of active stylesheets in the appropriate
locations.
2014-10-15 15:14:12 -06:00
Max Hodges 6c56f2f985 Update keymap.cson 2014-10-09 16:01:41 +09:00
Max Hodges a4b959f2b8 Update keymap.cson 2014-10-09 13:26:14 +09:00
Max Hodges c59b7f6ead new users should be warned about cson
improper trailing and leading spaces can cause your bindings to fail.Since cson has very little adoption relative to json, I think it's important to warn new users that they need to understand CoffeeScript notation or else a single space could break their file. I spent one full hour today trying to get an auto-indent mapping to work. The solution involved adding one leading space!
2014-10-09 13:15:55 +09:00
85 arquivos alterados com 2168 adições e 532 exclusões
+2
Ver Arquivo
@@ -25,6 +25,8 @@ propose changes to this document in a pull request.
full stack trace and include it in the issue.
* On Mac, check Console.app for stack traces to include if reporting a crash.
* Perform a cursory search to see if a similar issue has already been submitted.
* Please setup a [profile picture](https://help.github.com/articles/how-do-i-set-up-my-profile-picture)
to make yourself recognizable and so we can all get to know each other better.
### Package Repositories
+22
Ver Arquivo
@@ -0,0 +1,22 @@
# VERSION: 0.1
# DESCRIPTION: Image to build Atom and create a .rpm file
# Base docker image
FROM fedora:20
# Install dependencies
RUN yum install -y \
make \
gcc \
gcc-c++ \
glibc-devel \
git-core \
libgnome-keyring-devel \
rpmdevtools
# Install node
RUN curl -sL https://rpm.nodesource.com/setup | bash -
RUN yum install -y nodejs
ADD . /atom
WORKDIR /atom
+14
Ver Arquivo
@@ -4,6 +4,9 @@ Atom is a hackable text editor for the 21st century, built on [atom-shell](http:
Visit [atom.io](https://atom.io) to learn more.
Visit [issue #3684](https://github.com/atom/atom/issues/3684) to learn more
about the Atom 1.0 roadmap.
## Installing
### Mac OS X
@@ -36,6 +39,17 @@ Currently only a 64-bit version is available.
The Linux version does not currently automatically update so you will need to
repeat these steps to upgrade to future releases.
### Red Hat Linux (Fedora, CentOS, Red Hat)
Currently only a 64-bit version is available.
1. Download `atom.x86_64.rpm` from the [Atom releases page](https://github.com/atom/atom/releases/latest).
2. Run `sudo yum localinstall atom.x86_64.rpm` on the downloaded package.
3. Launch Atom using the installed `atom` command.
The Linux version does not currently automatically update so you will need to
repeat these steps to upgrade to future releases.
## Building
* [Linux](docs/build-instructions/linux.md)
+1 -1
Ver Arquivo
@@ -6,6 +6,6 @@
"url": "https://github.com/atom/atom.git"
},
"dependencies": {
"atom-package-manager": "0.104.0"
"atom-package-manager": "0.109.0"
}
}
+50
Ver Arquivo
@@ -0,0 +1,50 @@
# VERSION: 0.1
# DESCRIPTION: Create the atom editor in a container
# AUTHOR: Jessica Frazelle <jessie@docker.com>
# COMMENTS:
# This file describes how to build the atom editor
# in a container with all dependencies installed.
# Tested on Debian Jessie.
# USAGE:
# # Download atom Dockerfile
# wget http://raw.githubusercontent.com/atom/atom/master/Dockerfile
#
# # Build atom image
# docker build -t atom .
#
# docker run -v /tmp/.X11-unix:/tmp/.X11-unix \
# -e DISPLAY=unix$DISPLAY atom
#
DOCKER-VERSION 1.3
# Base docker image
FROM debian:jessie
MAINTAINER Jessica Frazelle <jessie@docker.com>
# Install dependencies
RUN apt-get update && apt-get install -y \
build-essential \
ca-certificates \
curl \
git \
libasound2 \
libgconf-2-4 \
libgnome-keyring-dev \
libgtk2.0-0 \
libnss3 \
libxtst6 \
--no-install-recommends
# install node
RUN curl -sL https://deb.nodesource.com/setup | bash -
RUN apt-get install -y nodejs
# clone atom
RUN git clone https://github.com/atom/atom /src
WORKDIR /src
RUN git fetch && git checkout $(git describe --tags `git rev-list --tags --max-count=1`)
RUN script/build && script/grunt install
# Autorun atom
CMD /usr/local/bin/atom --foreground --log-file /var/log/atom.log && tail -f /var/log/atom.log
+2 -2
Ver Arquivo
@@ -7,7 +7,7 @@
},
"dependencies": {
"async": "~0.2.9",
"donna": "1.0.1",
"donna": "1.0.6",
"formidable": "~1.0.14",
"fs-plus": "2.x",
"github-releases": "~0.2.0",
@@ -18,7 +18,7 @@
"grunt-contrib-csslint": "~0.1.2",
"grunt-contrib-less": "~0.8.0",
"grunt-cson": "0.10.0",
"grunt-download-atom-shell": "~0.8.0",
"grunt-download-atom-shell": "~0.10.0",
"grunt-lesslint": "0.13.0",
"grunt-markdown": "~0.4.0",
"grunt-peg": "~1.1.0",
+1 -1
Ver Arquivo
@@ -153,7 +153,7 @@ module.exports = (grunt) ->
fs.writeFileSync path.join(appDir, 'node_modules', 'symbols-view', 'vendor', 'ctags-win32.exe.ignore'), ''
fs.writeFileSync path.join(shellAppDir, 'atom.exe.gui'), ''
dependencies = ['compile', 'generate-license:save', 'generate-module-cache']
dependencies = ['compile', 'generate-license:save', 'generate-module-cache', 'compile-packages-slug']
dependencies.push('copy-info-plist') if process.platform is 'darwin'
dependencies.push('set-exe-icon') if process.platform is 'win32'
grunt.task.run(dependencies...)
@@ -0,0 +1,54 @@
path = require 'path'
CSON = require 'season'
fs = require 'fs-plus'
_ = require 'underscore-plus'
module.exports = (grunt) ->
{spawn, rm} = require('./task-helpers')(grunt)
grunt.registerTask 'compile-packages-slug', 'Add bundled package metadata information to the main package.json file', ->
appDir = fs.realpathSync(grunt.config.get('atom.appDir'))
modulesDirectory = path.join(appDir, 'node_modules')
packages = {}
for moduleDirectory in fs.listSync(modulesDirectory)
continue if path.basename(moduleDirectory) is '.bin'
metadataPath = path.join(moduleDirectory, 'package.json')
metadata = grunt.file.readJSON(metadataPath)
continue unless metadata?.engines?.atom?
moduleCache = metadata._atomModuleCache ? {}
rm metadataPath
_.remove(moduleCache.extensions?['.json'] ? [], 'package.json')
for property in ['_from', '_id', 'dist', 'readme', 'readmeFilename']
delete metadata[property]
pack = {metadata, keymaps: {}, menus: {}}
if metadata.main
mainPath = require.resolve(path.resolve(moduleDirectory, metadata.main))
pack.main = path.relative(appDir, mainPath)
for keymapPath in fs.listSync(path.join(moduleDirectory, 'keymaps'), ['.cson', '.json'])
relativePath = path.relative(appDir, keymapPath)
pack.keymaps[relativePath] = CSON.readFileSync(keymapPath)
rm keymapPath
for menuPath in fs.listSync(path.join(moduleDirectory, 'menus'), ['.cson', '.json'])
relativePath = path.relative(appDir, menuPath)
pack.menus[relativePath] = CSON.readFileSync(menuPath)
rm menuPath
packages[metadata.name] = pack
for extension, paths of moduleCache.extensions
delete moduleCache.extensions[extension] if paths.length is 0
metadata = grunt.file.readJSON(path.join(appDir, 'package.json'))
metadata._atomPackages = packages
grunt.file.write(path.join(appDir, 'package.json'), JSON.stringify(metadata))
+1 -20
Ver Arquivo
@@ -36,23 +36,4 @@ module.exports = (grunt) ->
'react-atom-fork': metadata.dependencies['react-atom-fork']
}
validExtensions = ['.js', '.coffee', '.json', '.node']
extensions = {}
onFile = (filePath) ->
filePath = path.relative(appDir, filePath)
segments = filePath.split(path.sep)
return if segments.length > 1 and not (segments[0] in ['exports', 'node_modules', 'src', 'static', 'vendor'])
extension = path.extname(filePath)
if extension in validExtensions
extensions[extension] ?= []
extensions[extension].push(filePath)
onDirectory = -> true
files = fs.traverseTreeSync(appDir, onFile, onDirectory)
metadata._atomModuleCache.extensions = extensions
grunt.file.write(path.join(appDir, 'package.json'), JSON.stringify(metadata, null, 2))
grunt.file.write(path.join(appDir, 'package.json'), JSON.stringify(metadata))
+1 -1
Ver Arquivo
@@ -32,7 +32,7 @@ module.exports = (grunt) ->
binDir = path.join(installDir, 'bin')
shareDir = path.join(installDir, 'share', 'atom')
iconName = path.join(shareDir,'resources','app','resources','atom.png')
iconName = path.join(shareDir,'resources', 'app', 'resources', 'atom.png')
mkdir binDir
cp 'atom.sh', path.join(binDir, 'atom')
+7 -2
Ver Arquivo
@@ -3,7 +3,7 @@ path = require 'path'
_ = require 'underscore-plus'
module.exports = (grunt) ->
{spawn} = require('./task-helpers')(grunt)
{spawn, rm, mkdir} = require('./task-helpers')(grunt)
fillTemplate = (filePath, data) ->
template = _.template(String(fs.readFileSync("#{filePath}.in")))
@@ -25,6 +25,11 @@ module.exports = (grunt) ->
{name, version, description} = grunt.file.readJSON('package.json')
buildDir = grunt.config.get('atom.buildDir')
rpmDir = path.join(buildDir, 'rpm')
rm rpmDir
mkdir rpmDir
installDir = grunt.config.get('atom.installDir')
shareDir = path.join(installDir, 'share', 'atom')
iconName = path.join(shareDir, 'resources', 'app', 'resources', 'atom.png')
@@ -39,5 +44,5 @@ module.exports = (grunt) ->
if error?
done(error)
else
grunt.log.ok "Created rpm package in #{buildDir}"
grunt.log.ok "Created rpm package in #{rpmDir}"
done()
+25 -4
Ver Arquivo
@@ -20,9 +20,9 @@ module.exports = (gruntObject) ->
{cp} = require('./task-helpers')(grunt)
grunt.registerTask 'publish-build', 'Publish the built app', ->
return if process.env.JANKY_SHA1 and process.env.JANKY_BRANCH isnt 'master'
tasks = ['upload-assets']
tasks.unshift('build-docs', 'prepare-docs') if process.platform is 'darwin'
tasks = []
tasks.push('build-docs', 'prepare-docs') if process.platform is 'darwin'
tasks.push('upload-assets') if process.env.JANKY_SHA1 and process.env.JANKY_BRANCH is 'master'
grunt.task.run(tasks)
grunt.registerTask 'prepare-docs', 'Move api.json to atom-api.json', ->
@@ -31,7 +31,16 @@ module.exports = (gruntObject) ->
cp path.join(docsOutputDir, 'api.json'), path.join(buildDir, 'atom-api.json')
grunt.registerTask 'upload-assets', 'Upload the assets to a GitHub release', ->
done = @async()
doneCallback = @async()
startTime = Date.now()
done = (args...) ->
elapsedTime = Math.round((Date.now() - startTime) / 100) / 10
grunt.log.ok("Upload time: #{elapsedTime}s")
doneCallback(args...)
unless token
return done(new Error('ATOM_ACCESS_TOKEN environment variable not set'))
buildDir = grunt.config.get('atom.buildDir')
assets = getAssets()
@@ -63,9 +72,21 @@ getAssets = ->
else
arch = 'amd64'
{version} = grunt.file.readJSON('package.json')
# Check for a Debian build
sourcePath = "#{buildDir}/atom-#{version}-#{arch}.deb"
assetName = "atom-#{arch}.deb"
# Check for a Fedora build
unless fs.isFileSync(sourcePath)
rpmName = fs.readdirSync("#{buildDir}/rpm")[0]
sourcePath = "#{buildDir}/rpm/#{rpmName}"
if process.arch is 'ia32'
arch = 'i386'
else
arch = 'x86_64'
assetName = "atom.#{arch}.rpm"
{cp} = require('./task-helpers')(grunt)
cp sourcePath, path.join(buildDir, assetName)
+1 -1
Ver Arquivo
@@ -32,7 +32,7 @@ module.exports = (grunt) ->
packageJsonPath = path.join(appDir, 'package.json')
packageJson = require(packageJsonPath)
packageJson.version = version
packageJsonString = JSON.stringify(packageJson, null, 2)
packageJsonString = JSON.stringify(packageJson)
fs.writeFileSync(packageJsonPath, packageJsonString)
if process.platform is 'darwin'
+5 -3
Ver Arquivo
@@ -4,6 +4,8 @@ path = require 'path'
_ = require 'underscore-plus'
async = require 'async'
concurrency = 2
module.exports = (grunt) ->
{isAtomPackage, spawn} = require('./task-helpers')(grunt)
@@ -61,7 +63,7 @@ module.exports = (grunt) ->
continue unless isAtomPackage(packagePath)
packageSpecQueue.push(packagePath)
packageSpecQueue.concurrency = 1
packageSpecQueue.concurrency = concurrency - 1
packageSpecQueue.drain = -> callback(null, failedPackages)
runCoreSpecs = (callback) ->
@@ -84,7 +86,7 @@ module.exports = (grunt) ->
fs.unlinkSync('ci.log')
else
# TODO: Restore concurrency on Windows
packageSpecQueue.concurrency = 2
packageSpecQueue.concurrency = concurrency
callback(null, error)
@@ -102,7 +104,7 @@ module.exports = (grunt) ->
method [runCoreSpecs, runPackageSpecs], (error, results) ->
[coreSpecFailed, failedPackages] = results
elapsedTime = Math.round((Date.now() - startTime) / 100) / 10
grunt.verbose.writeln("Total spec time: #{elapsedTime}s")
grunt.log.ok("Total spec time: #{elapsedTime}s using #{concurrency} cores")
failures = failedPackages
failures.push "atom core" if coreSpecFailed
+4 -1
Ver Arquivo
@@ -42,7 +42,9 @@ atom.config.set('.source.js .function.name', 'my-package.my-setting', 'special v
## Scope Descriptors
A scope descriptor is an `Array` of `String`s describing a path from the root of the syntax tree to a token including _all_ scope names for the entire path.
A scope descriptor is an [Object][scope-descriptor] that wraps an `Array` of
`String`s. The Array describes a path from the root of the syntax tree to a
token including _all_ scope names for the entire path.
In our JavaScript example above, a scope descriptor for the function name token would be:
@@ -82,3 +84,4 @@ valueForLanguage = atom.config.get(editor.getRootScopeDescriptor(), 'my-package.
[editor-scopeDescriptorForBufferPosition]:https://atom.io/docs/api/latest/TextEditor#instance-scopeDescriptorForBufferPosition
[cursor-getScopeDescriptor]:https://atom.io/docs/api/latest/Cursor#instance-getScopeDescriptor
[scope-descriptor]:https://atom.io/docs/api/latest/ScopeDescriptor
+28 -6
Ver Arquivo
@@ -19,14 +19,14 @@ Ubuntu LTS 12.04 64-bit is the recommended platform.
* `sudo apt-get install build-essential git libgnome-keyring-dev fakeroot`
* Instructions for [Node.js](https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager#ubuntu-mint-elementary-os).
### Fedora
### Fedora / CentOS / RHEL
* `sudo yum --assumeyes install make gcc gcc-c++ glibc-devel git-core libgnome-keyring-devel`
* `sudo yum --assumeyes install make gcc gcc-c++ glibc-devel git-core libgnome-keyring-devel rpmdevtools`
* Instructions for [Node.js](https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager#fedora).
### Arch
* `sudo pacman -S base-devel git nodejs libgnome-keyring`
* `sudo pacman -S base-devel git nodejs libgnome-keyring python2`
* `export PYTHON=/usr/bin/python2` before building Atom.
## Instructions
@@ -61,13 +61,19 @@ If you have problems with permissions don't forget to prefix with `sudo`
sudo script/grunt install
```
5. *Optionally*, you may generate a `.deb` package at `$TMPDIR/atom-build`:
To use the newly installed Atom, quit and restart all running Atom instances.
5. *Optionally*, you may generate distributable packages of Atom at `$TMPDIR/atom-build`. Currenty, `.deb` and `.rpm` package types are supported. To create a `.deb` package run:
```sh
script/grunt mkdeb
```
Use the newly installed Atom by fully quitting Atom and then reopening.
To create an `.rpm` package run
```sh
script/grunt mkrpm
```
## Advanced Options
@@ -85,7 +91,7 @@ script/build --build-dir /build/atom/here
## Troubleshooting
### Exception: "TypeError: Unable to watch path"
### TypeError: Unable to watch path
If you get following error with a big traceback right after Atom starts:
@@ -115,6 +121,22 @@ have Node.js installed, or node isn't identified as Node.js on your machine.
If it's the latter, entering `sudo ln -s /usr/bin/nodejs /usr/bin/node` into
your terminal may fix the issue.
### AttributeError: 'module' object has no attribute 'script_main'
If you get following error with a big traceback while building Atom:
```
sys.exit(gyp.script_main()) AttributeError: 'module' object has no attribute 'script_main' gyp ERR!
```
you need to uninstall the system version of gyp.
On Fedora you would do the following:
```sh
sudo yum remove gyp
```
#### You can also use Alternatives
On some variants (mostly Debian based distros) it's preferable for you to use
+3 -3
Ver Arquivo
@@ -36,7 +36,7 @@
## Why do I have to use GitHub for Windows?
You don't. You can use your existing Git! GitHub for Windows's Git Shell is just
easier to set up.
easier to set up.
If you _prefer_ using your existing Git installation, make sure git's cmd directory is in your PATH env variable (e.g. `C:\Program Files (x86)\Git\cmd`) before you open your powershell or command window.
Note that you may have to open your command window as administrator. For powershell that doesn't seem to always be the case, though.
@@ -67,11 +67,11 @@ If none of this works, do install Github for Windows and use its Git shell. Make
* https://code.google.com/p/gyp/issues/detail?id=393
* `script/build` stops at installing runas with 'Failed at the runas@0.5.4 install script.'
See the next item.
* `error MSB8020: The build tools for Visual Studio 2010 (Platform Toolset = 'v100') cannot be found.`
* If you're building atom with Visual Studio 2013 try executing the following
command in your Git shell and then re-run `script/build`:
+16 -14
Ver Arquivo
@@ -9,22 +9,27 @@ in the proper package's repository.
### Cloning
The first step is creating your own clone. You can of course do this manually
with git, or you can use the `apm develop` command to create a clone based on
the package's `repository` field in the `package.json`.
The first step is creating your own clone.
For example, if you want to make changes to the `tree-view` package, run the
following command:
For example, if you want to make changes to the `tree-view` package, fork the repo on your github account, then clone it:
```
> apm develop tree-view
Cloning https://github.com/atom/tree-view ✓
> git clone git@github.com:your-username/tree-view.git
```
Next install all the dependencies:
```
> cd tree-view
> apm install
Installing modules ✓
~/.atom/dev/packages/tree-view -> ~/github/tree-view
```
This clones the `tree-view` repository to `~/github`. If you prefer a different
path, specify it via the `ATOM_REPOS_HOME` environment variable.
Now you can link it to development mode so when you run an Atom window with `atom --dev`, you will use your fork instead of the built in package:
```
> apm link -d
```
### Running in Development Mode
@@ -46,7 +51,4 @@ from the package directory to create and remove dev-mode symlinks.
### Installing Dependencies
Finally, you need to install the cloned package's dependencies by running
`apm install` within the package directory. This step is also performed
automatically the first time you run `apm develop`, but you'll want to keep
dependencies up to date by running `apm update` after pulling upstream changes.
You'll want to keep dependencies up to date by running `apm update` after pulling any upstream changes.
+1
Ver Arquivo
@@ -9,6 +9,7 @@
* [Converting a TextMate Bundle](converting-a-text-mate-bundle.md)
* [Converting a TextMate Theme](converting-a-text-mate-theme.md)
* [Contributing](contributing.md)
* [Contributing to Core Packages](contributing-to-packages.md)
* [Debugging](debugging.md)
### Advanced Topics
+4
Ver Arquivo
@@ -19,3 +19,7 @@
# You can find more information about keymaps in these guides:
# * https://atom.io/docs/latest/customizing-atom#customizing-key-bindings
# * https://atom.io/docs/latest/advanced/keymaps
#
# This file uses CoffeeScript Object Notation (CSON).
# If you are unfamiliar with CSON, you can read more about it here:
# https://github.com/bevry/cson#what-is-cson
+3
Ver Arquivo
@@ -13,3 +13,6 @@
# 'prefix': 'log'
# 'body': 'console.log $1'
#
# This file uses CoffeeScript Object Notation (CSON).
# If you are unfamiliar with CSON, you can read more about it here:
# https://github.com/bevry/cson#what-is-cson
+33 -33
Ver Arquivo
@@ -1,7 +1,7 @@
{
{
"name": "atom",
"productName": "Atom",
"version": "0.138.0",
"version": "0.141.0",
"description": "A hackable text editor for the 21st Century.",
"main": "./src/browser/main.js",
"repository": {
@@ -17,7 +17,7 @@
"url": "http://github.com/atom/atom/raw/master/LICENSE.md"
}
],
"atomShellVersion": "0.18.1",
"atomShellVersion": "0.18.2",
"dependencies": {
"async": "0.2.6",
"atom-keymap": "^2.2.1",
@@ -37,7 +37,7 @@
"guid": "0.0.10",
"jasmine-json": "~0.0",
"jasmine-tagged": "^1.1.2",
"less-cache": "0.15.0",
"less-cache": "0.17.0",
"mixto": "^1",
"mkdirp": "0.3.5",
"nslog": "^1.0.1",
@@ -50,23 +50,23 @@
"react-atom-fork": "^0.11.1",
"reactionary-atom-fork": "^1.0.0",
"runas": "1.0.1",
"scandal": "1.0.2",
"scoped-property-store": "^0.14.0",
"scandal": "1.0.3",
"scoped-property-store": "^0.15.0",
"scrollbar-style": "^1.0.2",
"season": "^1.0.2",
"semver": "2.2.1",
"serializable": "^1",
"space-pen": "3.8.0",
"temp": "0.7.0",
"text-buffer": "^3.2.9",
"text-buffer": "^3.3.0",
"theorist": "^1.0.2",
"underscore-plus": "^1.5.1",
"underscore-plus": "^1.6.1",
"vm-compatibility-layer": "0.1.0"
},
"packageDependencies": {
"atom-dark-syntax": "0.19.0",
"atom-dark-syntax": "0.20.0",
"atom-dark-ui": "0.35.0",
"atom-light-syntax": "0.20.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",
@@ -78,61 +78,61 @@
"autosave": "0.18.0",
"background-tips": "0.17.0",
"bookmarks": "0.28.0",
"bracket-matcher": "0.61.0",
"bracket-matcher": "0.62.0",
"command-palette": "0.27.0",
"deprecation-cop": "0.10.0",
"deprecation-cop": "0.11.0",
"dev-live-reload": "0.34.0",
"exception-reporting": "0.20.0",
"feedback": "0.33.0",
"find-and-replace": "0.140.0",
"fuzzy-finder": "0.58.0",
"git-diff": "0.40.0",
"go-to-line": "0.25.0",
"find-and-replace": "0.141.0",
"fuzzy-finder": "0.60.0",
"git-diff": "0.42.0",
"go-to-line": "0.26.0",
"grammar-selector": "0.35.0",
"image-view": "0.37.0",
"image-view": "0.38.0",
"incompatible-packages": "0.10.0",
"keybinding-resolver": "0.20.0",
"link": "0.26.0",
"markdown-preview": "0.104.0",
"markdown-preview": "0.107.0",
"metrics": "0.36.0",
"open-on-github": "0.30.0",
"package-generator": "0.31.0",
"release-notes": "0.36.0",
"settings-view": "0.152.0",
"snippets": "0.55.0",
"spell-check": "0.42.0",
"settings-view": "0.153.0",
"snippets": "0.56.0",
"spell-check": "0.43.0",
"status-bar": "0.46.0",
"styleguide": "0.30.0",
"symbols-view": "0.66.0",
"tabs": "0.54.0",
"timecop": "0.22.0",
"tabs": "0.55.0",
"timecop": "0.23.0",
"tree-view": "0.131.0",
"update-package-dependencies": "0.6.0",
"welcome": "0.19.0",
"whitespace": "0.25.0",
"whitespace": "0.26.0",
"wrap-guide": "0.23.0",
"language-c": "0.28.0",
"language-coffee-script": "0.36.0",
"language-c": "0.29.0",
"language-coffee-script": "0.37.0",
"language-css": "0.21.0",
"language-gfm": "0.52.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.40.0",
"language-javascript": "0.42.0",
"language-json": "0.8.0",
"language-less": "0.15.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.16.0",
"language-php": "0.17.0",
"language-property-list": "0.7.0",
"language-python": "0.21.0",
"language-ruby": "0.40.0",
"language-ruby": "0.41.0",
"language-ruby-on-rails": "0.18.0",
"language-sass": "0.22.0",
"language-sass": "0.24.0",
"language-shellscript": "0.8.0",
"language-source": "0.8.0",
"language-sql": "0.11.0",
@@ -140,7 +140,7 @@
"language-todo": "0.13.0",
"language-toml": "0.14.0",
"language-xml": "0.24.0",
"language-yaml": "0.18.0"
"language-yaml": "0.19.0"
},
"private": true,
"scripts": {
+1
Ver Arquivo
@@ -1,6 +1,7 @@
[Desktop Entry]
Name=Atom
Comment=<%= description %>
GenericName=Text Editor
Exec=<%= installDir %>/share/atom/atom %U
Icon=<%= iconName %>
Type=Application
Arquivo executável
+10
Ver Arquivo
@@ -0,0 +1,10 @@
#!/bin/bash
set -e
docker build -t atom-rpm .
docker run \
--env JANKY_SHA1="$JANKY_SHA1" \
--env JANKY_BRANCH="$JANKY_BRANCH" \
--env ATOM_ACCESS_TOKEN="$BUILD_ATOM_RPM_ACCESS_TOKEN" \
atom-rpm /atom/script/rpmbuild
+1 -1
Ver Arquivo
@@ -17,6 +17,6 @@ cp ./atom.sh $RPM_BUILD_ROOT/BUILD
cp $DESKTOP_FILE $RPM_BUILD_ROOT/BUILD
rpmbuild -ba $SPEC_FILE
cp $RPM_BUILD_ROOT/RPMS/$ARCH/atom-*.rpm $BUILD_DIRECTORY
cp $RPM_BUILD_ROOT/RPMS/$ARCH/atom-*.rpm $BUILD_DIRECTORY/rpm
rm -rf $RPM_BUILD_ROOT
Arquivo executável
+6
Ver Arquivo
@@ -0,0 +1,6 @@
#!/bin/sh
set -e
script/build
script/grunt mkrpm publish-build --stack
+126 -33
Ver Arquivo
@@ -15,14 +15,18 @@ describe "CommandRegistry", ->
document.querySelector('#jasmine-content').appendChild(parent)
registry = new CommandRegistry
atom.commands.restoreDOMEventMethods()
registry.patchDOMEventMethods()
afterEach ->
registry.restoreDOMEventMethods()
atom.commands.patchDOMEventMethods()
registry.destroy()
describe "when a command event is dispatched on an element", ->
it "invokes callbacks with selectors matching the target", ->
called = false
registry.add '.grandchild', 'command', (event) ->
registry.listen '.grandchild', 'command', (event) ->
expect(this).toBe grandchild
expect(event.type).toBe 'command'
expect(event.eventPhase).toBe Event.BUBBLING_PHASE
@@ -36,13 +40,13 @@ describe "CommandRegistry", ->
it "invokes callbacks with selectors matching ancestors of the target", ->
calls = []
registry.add '.child', 'command', (event) ->
registry.listen '.child', 'command', (event) ->
expect(this).toBe child
expect(event.target).toBe grandchild
expect(event.currentTarget).toBe child
calls.push('child')
registry.add '.parent', 'command', (event) ->
registry.listen '.parent', 'command', (event) ->
expect(this).toBe parent
expect(event.target).toBe grandchild
expect(event.currentTarget).toBe parent
@@ -53,10 +57,10 @@ describe "CommandRegistry", ->
it "invokes inline listeners prior to listeners applied via selectors", ->
calls = []
registry.add '.grandchild', 'command', -> calls.push('grandchild')
registry.add child, 'command', -> calls.push('child-inline')
registry.add '.child', 'command', -> calls.push('child')
registry.add '.parent', 'command', -> calls.push('parent')
registry.listen '.grandchild', 'command', -> calls.push('grandchild')
registry.listen child, 'command', -> calls.push('child-inline')
registry.listen '.child', 'command', -> calls.push('child')
registry.listen '.parent', 'command', -> calls.push('parent')
grandchild.dispatchEvent(new CustomEvent('command', bubbles: true))
expect(calls).toEqual ['grandchild', 'child-inline', 'child', 'parent']
@@ -65,41 +69,77 @@ describe "CommandRegistry", ->
child.classList.add('foo', 'bar')
calls = []
registry.add '.foo.bar', 'command', -> calls.push('.foo.bar')
registry.add '.foo', 'command', -> calls.push('.foo')
registry.add '.bar', 'command', -> calls.push('.bar') # specificity ties favor commands added later, like CSS
registry.listen '.foo.bar', 'command', -> calls.push('.foo.bar')
registry.listen '.foo', 'command', -> calls.push('.foo')
registry.listen '.bar', 'command', -> calls.push('.bar') # specificity ties favor commands added later, like CSS
grandchild.dispatchEvent(new CustomEvent('command', bubbles: true))
expect(calls).toEqual ['.foo.bar', '.bar', '.foo']
it "does not bubble the event if the ::bubbles property is false on the dispatched event", ->
calls = []
registry.listen '.grandchild', 'command', -> calls.push('grandchild')
registry.listen '.child', 'command', -> calls.push('child')
registry.listen '.parent', 'command', -> calls.push('parent')
grandchild.dispatchEvent(new CustomEvent('command', bubbles: false))
expect(calls).toEqual ['grandchild']
it "invokes capture-phase listeners before bubble-phase listeners", ->
calls = []
# Spot-check event details for both capture and bubbling phase
registry.capture '.grandchild', 'command', (event) ->
expect(this).toBe grandchild
expect(event.type).toBe 'command'
expect(event.eventPhase).toBe Event.CAPTURING_PHASE
expect(event.target).toBe grandchild
expect(event.currentTarget).toBe grandchild
calls.push('grandchild-capture')
registry.listen '.grandchild', 'command', (event) ->
expect(this).toBe grandchild
expect(event.type).toBe 'command'
expect(event.eventPhase).toBe Event.BUBBLING_PHASE
expect(event.target).toBe grandchild
expect(event.currentTarget).toBe grandchild
calls.push('grandchild-bubble')
registry.capture child, 'command', -> calls.push('child-inline-capture')
registry.listen child, 'command', -> calls.push('child-inline-bubble')
registry.capture '.child', 'command', -> calls.push('child-capture')
registry.capture '.parent', 'command', -> calls.push('parent-capture')
grandchild.dispatchEvent(new CustomEvent('command', bubbles: true))
expect(calls).toEqual ['parent-capture', 'child-inline-capture', 'child-capture', 'grandchild-capture', 'grandchild-bubble', 'child-inline-bubble']
it "stops bubbling through ancestors when .stopPropagation() is called on the event", ->
calls = []
registry.add '.parent', 'command', -> calls.push('parent')
registry.add '.child', 'command', -> calls.push('child-2')
registry.add '.child', 'command', (event) -> calls.push('child-1'); event.stopPropagation()
registry.listen '.parent', 'command', -> calls.push('parent')
registry.listen '.child', 'command', -> calls.push('child-2')
registry.listen '.child', 'command', (event) -> calls.push('child-1'); event.stopPropagation()
dispatchedEvent = new CustomEvent('command', bubbles: true)
spyOn(dispatchedEvent, 'stopPropagation')
grandchild.dispatchEvent(dispatchedEvent)
expect(calls).toEqual ['child-1', 'child-2']
expect(dispatchedEvent.stopPropagation).toHaveBeenCalled()
it "stops invoking callbacks when .stopImmediatePropagation() is called on the event", ->
calls = []
registry.add '.parent', 'command', -> calls.push('parent')
registry.add '.child', 'command', -> calls.push('child-2')
registry.add '.child', 'command', (event) -> calls.push('child-1'); event.stopImmediatePropagation()
registry.listen '.parent', 'command', -> calls.push('parent')
registry.listen '.child', 'command', -> calls.push('child-2')
registry.listen '.child', 'command', (event) -> calls.push('child-1'); event.stopImmediatePropagation()
dispatchedEvent = new CustomEvent('command', bubbles: true)
spyOn(dispatchedEvent, 'stopImmediatePropagation')
grandchild.dispatchEvent(dispatchedEvent)
expect(calls).toEqual ['child-1']
expect(dispatchedEvent.stopImmediatePropagation).toHaveBeenCalled()
it "forwards .preventDefault() calls from the synthetic event to the original", ->
registry.add '.child', 'command', (event) -> event.preventDefault()
registry.listen '.child', 'command', (event) -> event.preventDefault()
dispatchedEvent = new CustomEvent('command', bubbles: true)
spyOn(dispatchedEvent, 'preventDefault')
@@ -107,7 +147,7 @@ describe "CommandRegistry", ->
expect(dispatchedEvent.preventDefault).toHaveBeenCalled()
it "forwards .abortKeyBinding() calls from the synthetic event to the original", ->
registry.add '.child', 'command', (event) -> event.abortKeyBinding()
registry.listen '.child', 'command', (event) -> event.abortKeyBinding()
dispatchedEvent = new CustomEvent('command', bubbles: true)
dispatchedEvent.abortKeyBinding = jasmine.createSpy('abortKeyBinding')
@@ -117,8 +157,8 @@ describe "CommandRegistry", ->
it "allows listeners to be removed via a disposable returned by ::add", ->
calls = []
disposable1 = registry.add '.parent', 'command', -> calls.push('parent')
disposable2 = registry.add '.child', 'command', -> calls.push('child')
disposable1 = registry.listen '.parent', 'command', -> calls.push('parent')
disposable2 = registry.listen '.child', 'command', -> calls.push('child')
disposable1.dispose()
grandchild.dispatchEvent(new CustomEvent('command', bubbles: true))
@@ -132,7 +172,7 @@ describe "CommandRegistry", ->
it "allows multiple commands to be registered under one selector when called with an object", ->
calls = []
disposable = registry.add '.child',
disposable = registry.listen '.child',
'command-1': -> calls.push('command-1')
'command-2': -> calls.push('command-2')
@@ -149,10 +189,10 @@ describe "CommandRegistry", ->
describe "::findCommands({target})", ->
it "returns commands that can be invoked on the target or its ancestors", ->
registry.add '.parent', 'namespace:command-1', ->
registry.add '.child', 'namespace:command-2', ->
registry.add '.grandchild', 'namespace:command-3', ->
registry.add '.grandchild.no-match', 'namespace:command-4', ->
registry.listen '.parent', 'namespace:command-1', ->
registry.listen '.child', 'namespace:command-2', ->
registry.listen '.grandchild', 'namespace:command-3', ->
registry.listen '.grandchild.no-match', 'namespace:command-4', ->
expect(registry.findCommands(target: grandchild)[0..2]).toEqual [
{name: 'namespace:command-3', displayName: 'Namespace: Command 3'}
@@ -163,7 +203,7 @@ describe "CommandRegistry", ->
describe "::dispatch(target, commandName)", ->
it "simulates invocation of the given command ", ->
called = false
registry.add '.grandchild', 'command', (event) ->
registry.listen '.grandchild', 'command', (event) ->
expect(this).toBe grandchild
expect(event.type).toBe 'command'
expect(event.eventPhase).toBe Event.BUBBLING_PHASE
@@ -175,18 +215,42 @@ describe "CommandRegistry", ->
expect(called).toBe true
it "returns a boolean indicating whether any listeners matched the command", ->
registry.add '.grandchild', 'command', ->
registry.listen '.grandchild', 'command', ->
expect(registry.dispatch(grandchild, 'command')).toBe true
expect(registry.dispatch(grandchild, 'bogus')).toBe false
expect(registry.dispatch(parent, 'command')).toBe false
it "does not perform bubbling for native event names that should not bubble", ->
calls = []
registry.listen '.grandchild', 'focus', -> calls.push('grandchild')
registry.listen '.child', 'focus', -> calls.push('child')
registry.listen '.parent', 'focus', -> calls.push('parent')
registry.dispatch(grandchild, 'focus')
expect(calls).toEqual ['grandchild']
it "allows an event object to be passed instead of an event name", ->
called = false
registry.listen '.grandchild', 'command', (event) ->
expect(this).toBe grandchild
expect(event.type).toBe 'command'
expect(event.eventPhase).toBe Event.BUBBLING_PHASE
expect(event.target).toBe grandchild
expect(event.currentTarget).toBe grandchild
expect(event.detail).toEqual {a: 1}
called = true
registry.dispatch(grandchild, new CustomEvent('command', bubbles: true), {a: 1})
expect(called).toBe true
describe "::getSnapshot and ::restoreSnapshot", ->
it "removes all command handlers except for those in the snapshot", ->
registry.add '.parent', 'namespace:command-1', ->
registry.add '.child', 'namespace:command-2', ->
registry.listen '.parent', 'namespace:command-1', ->
registry.listen '.child', 'namespace:command-2', ->
snapshot = registry.getSnapshot()
registry.add '.grandchild', 'namespace:command-3', ->
registry.listen '.grandchild', 'namespace:command-3', ->
expect(registry.findCommands(target: grandchild)[0..2]).toEqual [
{name: 'namespace:command-3', displayName: 'Namespace: Command 3'}
@@ -201,10 +265,39 @@ describe "CommandRegistry", ->
{name: 'namespace:command-1', displayName: 'Namespace: Command 1'}
]
registry.add '.grandchild', 'namespace:command-3', ->
registry.listen '.grandchild', 'namespace:command-3', ->
registry.restoreSnapshot(snapshot)
expect(registry.findCommands(target: grandchild)[0..1]).toEqual [
{name: 'namespace:command-2', displayName: 'Namespace: Command 2'}
{name: 'namespace:command-1', displayName: 'Namespace: Command 1'}
]
describe "::addEventListener and ::removeEventListener overrides", ->
it "mixes listeners registered via ::addEventListener with selector-based listeners", ->
calls = []
registry.listen '.grandchild', 'command', -> calls.push('grandchild')
registry.listen '.child', 'command', -> calls.push('child')
registry.listen '.parent', 'command', -> calls.push('parent')
bubbleListener = -> calls.push('child-inline-bubble')
captureListener = -> calls.push('child-inline-capture')
child.addEventListener('command', bubbleListener)
child.addEventListener('command', captureListener, true)
grandchild.dispatchEvent(new CustomEvent('command', bubbles: true))
expect(calls).toEqual ['child-inline-capture', 'grandchild', 'child-inline-bubble', 'child', 'parent']
child.removeEventListener('command', bubbleListener)
child.removeEventListener('command', captureListener, true)
calls = []
grandchild.dispatchEvent(new CustomEvent('command', bubbles: true))
expect(calls).toEqual ['grandchild', 'child', 'parent']
it "invokes handlers on detached DOM nodes", ->
detachedNode = document.createElement('div')
called = false
detachedNode.addEventListener 'command', -> called = true
detachedNode.dispatchEvent(new CustomEvent('command', bubbles: true))
expect(called).toBe true
+44 -1
Ver Arquivo
@@ -122,6 +122,11 @@ describe "Config", ->
atom.config.set('.source.coffee', 'foo.bar.baz', 55)
expect(atom.config.isDefault('.source.coffee', 'foo.bar.baz')).toBe false
describe ".setDefaults(keyPath)", ->
it "sets a default when the setting's key contains an escaped dot", ->
atom.config.setDefaults("foo", 'a\\.b': 1, b: 2)
expect(atom.config.get("foo")).toEqual 'a\\.b': 1, b: 2
describe ".toggle(keyPath)", ->
it "negates the boolean value of the current key path value", ->
atom.config.set('foo.a', 1)
@@ -153,6 +158,14 @@ describe "Config", ->
atom.config.restoreDefault('a.c')
expect(atom.config.get('a.c')).toBeUndefined()
it "calls ::save()", ->
atom.config.setDefaults('a', b: 3)
atom.config.set('a.b', 4)
atom.config.save.reset()
atom.config.restoreDefault('a.c')
expect(atom.config.save.callCount).toBe 1
describe "when scoped settings are used", ->
it "restores the global default when no scoped default set", ->
atom.config.setDefaults("foo", bar: baz: 10)
@@ -173,6 +186,15 @@ describe "Config", ->
expect(atom.config.get(['.source.coffee'], 'foo.bar.baz')).toBe 42
expect(atom.config.get(['.source.coffee'], 'foo.bar.ok')).toBe 100
it "calls ::save()", ->
atom.config.setDefaults("foo", bar: baz: 10)
atom.config.addScopedSettings("default", ".source.coffee", foo: bar: baz: 42)
atom.config.set('.source.coffee', 'foo.bar.baz', 55)
atom.config.save.reset()
atom.config.restoreDefault('.source.coffee', 'foo.bar.baz')
expect(atom.config.save.callCount).toBe 1
describe ".getSettings()", ->
it "returns all settings including defaults", ->
atom.config.setDefaults("foo", bar: baz: 10)
@@ -196,7 +218,6 @@ describe "Config", ->
baz: 42
omg: 'omg'
describe ".pushAtKeyPath(keyPath, value)", ->
it "pushes the given value to the array at the key path and updates observers", ->
atom.config.set("foo.bar.baz", ["a"])
@@ -1015,6 +1036,21 @@ describe "Config", ->
expect(atom.config.set('foo.bar.arr', ['two', 'three'])).toBe true
expect(atom.config.get('foo.bar.arr')).toEqual ['two', 'three']
describe "when scoped settings are used", ->
beforeEach ->
schema =
type: 'string'
default: 'ok'
scopes:
'.source.js':
default: 'omg'
atom.config.setSchema('foo.bar.str', schema)
it 'it respects the scoped defaults', ->
expect(atom.config.get('foo.bar.str')).toBe 'ok'
expect(atom.config.get(['.source.js'], 'foo.bar.str')).toBe 'omg'
expect(atom.config.get(['.source.coffee'], 'foo.bar.str')).toBe 'ok'
describe "scoped settings", ->
describe ".get(scopeDescriptor, keyPath)", ->
it "returns the property with the most specific scope selector", ->
@@ -1039,6 +1075,13 @@ describe "Config", ->
atom.config.setDefaults("foo", hasDefault: 'ok')
expect(atom.config.get([".source.coffee", ".string.quoted.single"], "foo.hasDefault")).toBe 'ok'
describe 'setting priority', ->
describe 'when package settings are added after user settings', ->
it "returns the user's setting because the user's setting has higher priority", ->
atom.config.set(".source.coffee", "foo.bar.baz", 100)
atom.config.addScopedSettings("some-package", ".source.coffee", foo: bar: baz: 1)
expect(atom.config.get([".source.coffee"], "foo.bar.baz")).toBe 100
describe ".set(scope, keyPath, value)", ->
it "sets the value and overrides the others", ->
atom.config.addScopedSettings("config", ".source.coffee .string.quoted.double.coffee", foo: bar: baz: 42)
+5
Ver Arquivo
@@ -56,6 +56,11 @@ describe "DisplayBuffer", ->
buffer.delete([[8, 0], [10, 0]])
expect(displayBuffer.getScrollTop()).toBe 60
it "updates the display buffer prior to invoking change handlers registered on the buffer", ->
buffer.onDidChange -> expect(displayBuffer2.tokenizedLineForScreenRow(0).text).toBe "testing"
displayBuffer2 = new DisplayBuffer({buffer, tabLength})
buffer.setText("testing")
describe "soft wrapping", ->
beforeEach ->
displayBuffer.setSoftWrapped(true)
@@ -6,7 +6,7 @@ module.exports =
activate: ->
@activateCallCount++
atom.commands.add 'atom-workspace', 'activation-command', =>
atom.commands.listen 'atom-workspace', 'activation-command', =>
@activationCommandCallCount++
atom.workspaceView.getActiveView()?.command 'activation-command', =>
+2 -2
Ver Arquivo
@@ -118,7 +118,7 @@ describe "PackageManager", ->
spyOn(Package.prototype, 'requireMainModule').andCallThrough()
workspaceCommandListener = jasmine.createSpy('workspaceCommandListener')
atom.commands.add '.workspace', 'activation-command', workspaceCommandListener
atom.commands.listen '.workspace', 'activation-command', workspaceCommandListener
promise = atom.packages.activatePackage('package-with-activation-commands')
@@ -138,7 +138,7 @@ describe "PackageManager", ->
legacyCommandListener = jasmine.createSpy("legacyCommandListener")
editorView.command 'activation-command', legacyCommandListener
editorCommandListener = jasmine.createSpy("editorCommandListener")
atom.commands.add 'atom-text-editor', 'activation-command', editorCommandListener
atom.commands.listen 'atom-text-editor', 'activation-command', editorCommandListener
editorView[0].dispatchEvent(new CustomEvent('activation-command', bubbles: true))
expect(mainModule.activate.callCount).toBe 1
expect(mainModule.legacyActivationCommandCallCount).toBe 1
+63
Ver Arquivo
@@ -0,0 +1,63 @@
ViewRegistry = require '../src/view-registry'
Panel = require '../src/panel'
PanelElement = require '../src/panel-element'
PanelContainer = require '../src/panel-container'
PanelContainerElement = require '../src/panel-container-element'
describe "PanelContainerElement", ->
[jasmineContent, element, container, viewRegistry] = []
class TestPanelContainerItem
constructior: ->
class TestPanelContainerItemElement extends HTMLElement
createdCallback: ->
@classList.add('test-root')
setModel: (@model) ->
TestPanelContainerItemElement = document.registerElement 'atom-test-container-item-element', prototype: TestPanelContainerItemElement.prototype
beforeEach ->
jasmineContent = document.body.querySelector('#jasmine-content')
viewRegistry = new ViewRegistry
viewRegistry.addViewProvider
modelConstructor: Panel
viewConstructor: PanelElement
viewRegistry.addViewProvider
modelConstructor: PanelContainer
viewConstructor: PanelContainerElement
viewRegistry.addViewProvider
modelConstructor: TestPanelContainerItem
viewConstructor: TestPanelContainerItemElement
container = new PanelContainer({viewRegistry, location: 'left'})
element = container.getView()
jasmineContent.appendChild(element)
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
container.destroy()
expect(element.parentNode).not.toBe jasmineContent
describe "adding and removing panels", ->
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)
expect(element.childNodes.length).toBe 2
panel1.destroy()
expect(element.childNodes.length).toBe 1
panel2.destroy()
expect(element.childNodes.length).toBe 0
+98
Ver Arquivo
@@ -0,0 +1,98 @@
ViewRegistry = require '../src/view-registry'
Panel = require '../src/panel'
PanelContainer = require '../src/panel-container'
describe "PanelContainer", ->
[container, viewRegistry] = []
class TestPanelItem
constructior: ->
beforeEach ->
viewRegistry = new ViewRegistry
container = new PanelContainer({viewRegistry})
describe "::addPanel(panel)", ->
it 'emits an onDidAddPanel event with the index the panel was inserted at', ->
container.onDidAddPanel addPanelSpy = jasmine.createSpy()
panel1 = new Panel(item: new TestPanelItem())
container.addPanel(panel1)
expect(addPanelSpy).toHaveBeenCalledWith({panel: panel1, index: 0})
panel2 = new Panel(item: new TestPanelItem())
container.addPanel(panel2)
expect(addPanelSpy).toHaveBeenCalledWith({panel: panel2, index: 1})
describe "when a panel is destroyed", ->
it 'emits an onDidRemovePanel event with the index of the removed item', ->
container.onDidRemovePanel removePanelSpy = jasmine.createSpy()
panel1 = new Panel(item: new TestPanelItem())
container.addPanel(panel1)
panel2 = new Panel(item: new TestPanelItem())
container.addPanel(panel2)
expect(removePanelSpy).not.toHaveBeenCalled()
panel2.destroy()
expect(removePanelSpy).toHaveBeenCalledWith({panel: panel2, index: 1})
panel1.destroy()
expect(removePanelSpy).toHaveBeenCalledWith({panel: panel1, index: 0})
describe "panel priority", ->
describe 'left / top panel container', ->
[initialPanel] = []
beforeEach ->
# 'left' logic is the same as 'top'
container = new PanelContainer({viewRegistry, location: 'left'})
initialPanel = new Panel(item: new TestPanelItem())
container.addPanel(initialPanel)
describe 'when a panel with low priority is added', ->
it 'is inserted at the beginning of the list', ->
container.onDidAddPanel addPanelSpy = jasmine.createSpy()
panel = new Panel(item: new TestPanelItem(), priority: 0)
container.addPanel(panel)
expect(addPanelSpy).toHaveBeenCalledWith({panel, index: 0})
expect(container.getPanels()[0]).toBe panel
describe 'when a panel with priority between two other panels is added', ->
it 'is inserted at the between the two panels', ->
panel = new Panel(item: new TestPanelItem(), priority: 1000)
container.addPanel(panel)
container.onDidAddPanel addPanelSpy = jasmine.createSpy()
panel = new Panel(item: new TestPanelItem(), priority: 101)
container.addPanel(panel)
expect(addPanelSpy).toHaveBeenCalledWith({panel, index: 1})
expect(container.getPanels()[1]).toBe panel
describe 'right / bottom panel container', ->
[initialPanel] = []
beforeEach ->
# 'bottom' logic is the same as 'right'
container = new PanelContainer({viewRegistry, location: 'right'})
initialPanel = new Panel(item: new TestPanelItem())
container.addPanel(initialPanel)
describe 'when a panel with high priority is added', ->
it 'is inserted at the beginning of the list', ->
container.onDidAddPanel addPanelSpy = jasmine.createSpy()
panel = new Panel(item: new TestPanelItem(), priority: 1000)
container.addPanel(panel)
expect(addPanelSpy).toHaveBeenCalledWith({panel, index: 0})
expect(container.getPanels()[0]).toBe panel
describe 'when a panel with low priority is added', ->
it 'is inserted at the end of the list', ->
container.onDidAddPanel addPanelSpy = jasmine.createSpy()
panel = new Panel(item: new TestPanelItem(), priority: 0)
container.addPanel(panel)
expect(addPanelSpy).toHaveBeenCalledWith({panel, index: 1})
expect(container.getPanels()[1]).toBe panel
+56
Ver Arquivo
@@ -0,0 +1,56 @@
ViewRegistry = require '../src/view-registry'
Panel = require '../src/panel'
PanelElement = require '../src/panel-element'
describe "PanelElement", ->
[jasmineContent, element, panel, viewRegistry] = []
class TestPanelItem
constructior: ->
class TestPanelItemElement extends HTMLElement
createdCallback: ->
@classList.add('test-root')
setModel: (@model) ->
TestPanelItemElement = document.registerElement 'atom-test-item-element', prototype: TestPanelItemElement.prototype
beforeEach ->
jasmineContent = document.body.querySelector('#jasmine-content')
viewRegistry = new ViewRegistry
viewRegistry.addViewProvider
modelConstructor: Panel
viewConstructor: PanelElement
viewRegistry.addViewProvider
modelConstructor: TestPanelItem
viewConstructor: TestPanelItemElement
it 'removes the element when the panel is destroyed', ->
panel = new Panel({viewRegistry, item: new TestPanelItem})
element = panel.getView()
jasmineContent.appendChild(element)
expect(element.parentNode).toBe jasmineContent
panel.destroy()
expect(element.parentNode).not.toBe jasmineContent
describe "changing panel visibility", ->
it 'initially renders panel created with visibile: false', ->
panel = new Panel({viewRegistry, visible: false, item: new TestPanelItem})
element = panel.getView()
jasmineContent.appendChild(element)
expect(element.style.display).toBe 'none'
it 'hides and shows the panel element when Panel::hide() and Panel::show() are called', ->
panel = new Panel({viewRegistry, item: new TestPanelItem})
element = panel.getView()
jasmineContent.appendChild(element)
expect(element.style.display).not.toBe 'none'
panel.hide()
expect(element.style.display).toBe 'none'
panel.show()
expect(element.style.display).not.toBe 'none'
+23
Ver Arquivo
@@ -0,0 +1,23 @@
Panel = require '../src/panel'
describe "Panel", ->
[panel] = []
class TestPanelItem
constructior: ->
beforeEach ->
panel = new Panel(item: new TestPanelItem())
describe "changing panel visibility", ->
it 'emits an event when visibility changes', ->
panel.onDidChangeVisible spy = jasmine.createSpy()
panel.hide()
expect(panel.isVisible()).toBe false
expect(spy).toHaveBeenCalledWith(false)
spy.reset()
panel.show()
expect(panel.isVisible()).toBe true
expect(spy).toHaveBeenCalledWith(true)
+5 -8
Ver Arquivo
@@ -29,6 +29,7 @@ atom.packages.packageDirPaths.unshift(fixturePackagesPath)
atom.keymaps.loadBundledKeymaps()
keyBindingsToRestore = atom.keymaps.getKeyBindings()
commandsToRestore = atom.commands.getSnapshot()
styleElementsToRestore = atom.styles.getSnapshot()
window.addEventListener 'core:close', -> window.close()
window.addEventListener 'beforeunload', ->
@@ -44,8 +45,7 @@ Object.defineProperty document, 'title',
jasmine.getEnv().addEqualityTester(_.isEqual) # Use underscore's definition of equality for toEqual assertions
if process.platform is 'win32' and process.env.JANKY_SHA1
# Use longer timeout on Windows CI
if process.env.JANKY_SHA1 and process.platform is 'win32'
jasmine.getEnv().defaultTimeoutInterval = 60000
else
jasmine.getEnv().defaultTimeoutInterval = 5000
@@ -74,6 +74,7 @@ beforeEach ->
atom.workspace = new Workspace()
atom.keymaps.keyBindings = _.clone(keyBindingsToRestore)
atom.commands.restoreSnapshot(commandsToRestore)
atom.styles.restoreSnapshot(styleElementsToRestore)
window.resetTimeouts()
atom.packages.packageStates = {}
@@ -224,7 +225,7 @@ addCustomMatchers = (spec) ->
notText = if @isNot then " not" else ""
element = @actual
element = element.get(0) if element.jquery
@message = -> return "Expected element '#{element}' or its descendants #{notText} to show."
@message = -> return "Expected element '#{element}' or its descendants#{notText} to show."
element.style.display in ['block', 'inline-block', 'static', 'fixed']
window.keyIdentifierForKey = (key) ->
@@ -350,11 +351,7 @@ $.fn.resultOfTrigger = (type) ->
event.result
$.fn.enableKeymap = ->
@on 'keydown', (e) ->
originalEvent = e.originalEvent ? e
Object.defineProperty(originalEvent, 'target', get: -> e.target) unless originalEvent.target?
atom.keymaps.handleKeyboardEvent(originalEvent)
not e.originalEvent.defaultPrevented
@element.addEventListener 'keydown', (event) -> atom.keymaps.handleKeyboardEvent(event)
$.fn.attachToDom = ->
@appendTo($('#jasmine-content')) unless @isOnDom()
+66
Ver Arquivo
@@ -0,0 +1,66 @@
StyleManager = require '../src/style-manager'
describe "StyleManager", ->
[manager, addEvents, removeEvents, updateEvents] = []
beforeEach ->
manager = new StyleManager
addEvents = []
removeEvents = []
updateEvents = []
manager.onDidAddStyleElement (event) -> addEvents.push(event)
manager.onDidRemoveStyleElement (event) -> removeEvents.push(event)
manager.onDidUpdateStyleElement (event) -> updateEvents.push(event)
describe "::addStyleSheet(source, params)", ->
it "adds a stylesheet based on the given source and returns a disposable allowing it to be removed", ->
disposable = manager.addStyleSheet("a {color: red;}")
expect(addEvents.length).toBe 1
expect(addEvents[0].textContent).toBe "a {color: red;}"
styleElements = manager.getStyleElements()
expect(styleElements.length).toBe 1
expect(styleElements[0].textContent).toBe "a {color: red;}"
disposable.dispose()
expect(removeEvents.length).toBe 1
expect(removeEvents[0].textContent).toBe "a {color: red;}"
expect(manager.getStyleElements().length).toBe 0
describe "when a sourcePath parameter is specified", ->
it "ensures a maximum of one style element for the given source path, updating a previous if it exists", ->
disposable1 = manager.addStyleSheet("a {color: red;}", sourcePath: '/foo/bar')
expect(addEvents.length).toBe 1
expect(addEvents[0].getAttribute('source-path')).toBe '/foo/bar'
disposable2 = manager.addStyleSheet("a {color: blue;}", sourcePath: '/foo/bar')
expect(addEvents.length).toBe 1
expect(updateEvents.length).toBe 1
expect(updateEvents[0].getAttribute('source-path')).toBe '/foo/bar'
expect(updateEvents[0].textContent).toBe "a {color: blue;}"
disposable2.dispose()
addEvents = []
manager.addStyleSheet("a {color: yellow;}", sourcePath: '/foo/bar')
expect(addEvents.length).toBe 1
expect(addEvents[0].getAttribute('source-path')).toBe '/foo/bar'
expect(addEvents[0].textContent).toBe "a {color: yellow;}"
describe "when a group parameter is specified", ->
it "inserts the stylesheet at the end of any existing stylesheets for the same group", ->
manager.addStyleSheet("a {color: red}", group: 'a')
manager.addStyleSheet("a {color: blue}", group: 'b')
manager.addStyleSheet("a {color: green}", group: 'a')
expect(manager.getStyleElements().map (elt) -> elt.textContent).toEqual [
"a {color: red}"
"a {color: green}"
"a {color: blue}"
]
+54
Ver Arquivo
@@ -0,0 +1,54 @@
StylesElement = require '../src/styles-element'
StyleManager = require '../src/style-manager'
describe "StylesElement", ->
[element, addedStyleElements, removedStyleElements, updatedStyleElements] = []
beforeEach ->
element = new StylesElement
document.querySelector('#jasmine-content').appendChild(element)
addedStyleElements = []
removedStyleElements = []
updatedStyleElements = []
element.onDidAddStyleElement (element) -> addedStyleElements.push(element)
element.onDidRemoveStyleElement (element) -> removedStyleElements.push(element)
element.onDidUpdateStyleElement (element) -> updatedStyleElements.push(element)
it "renders a style tag for all currently active stylesheets in the style manager", ->
initialChildCount = element.children.length
disposable1 = atom.styles.addStyleSheet("a {color: red;}")
expect(element.children.length).toBe initialChildCount + 1
expect(element.children[initialChildCount].textContent).toBe "a {color: red;}"
expect(addedStyleElements).toEqual [element.children[initialChildCount]]
disposable2 = atom.styles.addStyleSheet("a {color: blue;}")
expect(element.children.length).toBe initialChildCount + 2
expect(element.children[initialChildCount + 1].textContent).toBe "a {color: blue;}"
expect(addedStyleElements).toEqual [element.children[initialChildCount], element.children[initialChildCount + 1]]
disposable1.dispose()
expect(element.children.length).toBe initialChildCount + 1
expect(element.children[initialChildCount].textContent).toBe "a {color: blue;}"
expect(removedStyleElements).toEqual [addedStyleElements[0]]
it "orders style elements by group", ->
initialChildCount = element.children.length
atom.styles.addStyleSheet("a {color: red}", group: 'a')
atom.styles.addStyleSheet("a {color: blue}", group: 'b')
atom.styles.addStyleSheet("a {color: green}", group: 'a')
expect(element.children[initialChildCount].textContent).toBe "a {color: red}"
expect(element.children[initialChildCount + 1].textContent).toBe "a {color: green}"
expect(element.children[initialChildCount + 2].textContent).toBe "a {color: blue}"
it "updates existing style nodes when style elements are updated", ->
initialChildCount = element.children.length
atom.styles.addStyleSheet("a {color: red;}", sourcePath: '/foo/bar')
atom.styles.addStyleSheet("a {color: blue;}", sourcePath: '/foo/bar')
expect(element.children.length).toBe initialChildCount + 1
expect(element.children[initialChildCount].textContent).toBe "a {color: blue;}"
expect(updatedStyleElements).toEqual [element.children[initialChildCount]]
+34
Ver Arquivo
@@ -698,6 +698,24 @@ describe "TextEditorComponent", ->
expect(cursorRect.left).toBe rangeRect.left
expect(cursorRect.width).toBe rangeRect.width
it "accounts for the width of paired characters when positioning cursors", ->
atom.config.set('editor.fontFamily', 'sans-serif')
editor.setText('he\u0301y') # e with an accent mark
editor.setCursorBufferPosition([0, 3])
nextAnimationFrame()
cursor = componentNode.querySelector('.cursor')
cursorRect = cursor.getBoundingClientRect()
cursorLocationTextNode = component.lineNodeForScreenRow(0).querySelector('.source.js').firstChild
range = document.createRange()
range.setStart(cursorLocationTextNode, 3)
range.setEnd(cursorLocationTextNode, 4)
rangeRect = range.getBoundingClientRect()
expect(cursorRect.left).toBe rangeRect.left
expect(cursorRect.width).toBe rangeRect.width
it "positions cursors correctly after character widths are changed via a stylesheet change", ->
atom.config.set('editor.fontFamily', 'sans-serif')
editor.setCursorScreenPosition([0, 16])
@@ -1230,6 +1248,22 @@ describe "TextEditorComponent", ->
beforeEach ->
linesNode = componentNode.querySelector('.lines')
describe "when the mouse is single-clicked below the last line", ->
it "moves the cursor to the end of file buffer position", ->
editor.setText('foo')
editor.setCursorBufferPosition([0, 0])
height = 4.5 * lineHeightInPixels
wrapperNode.style.height = height + 'px'
wrapperNode.style.width = 10 * charWidth + 'px'
component.measureHeightAndWidth()
nextAnimationFrame()
coordinates = clientCoordinatesForScreenPosition([0, 2])
coordinates.clientY = height * 2
linesNode.dispatchEvent(buildMouseEvent('mousedown', coordinates))
nextAnimationFrame()
expect(editor.getCursorScreenPosition()).toEqual [0, 3]
describe "when a non-folded line is single-clicked", ->
describe "when no modifier keys are held down", ->
it "moves the cursor to the nearest screen position", ->
+7 -7
Ver Arquivo
@@ -3660,10 +3660,10 @@ describe "TextEditor", ->
{tokens} = grammar.tokenizeLine("var i; // http://github.com")
expect(tokens[0].value).toBe "var"
expect(tokens[0].scopeDescriptor).toEqual ["source.js", "storage.modifier.js"]
expect(tokens[0].scopes).toEqual ["source.js", "storage.modifier.js"]
expect(tokens[6].value).toBe "http://github.com"
expect(tokens[6].scopeDescriptor).toEqual ["source.js", "comment.line.double-slash.js", "markup.underline.link.http.hyperlink"]
expect(tokens[6].scopes).toEqual ["source.js", "comment.line.double-slash.js", "markup.underline.link.http.hyperlink"]
describe "when the grammar is added", ->
it "retokenizes existing buffers that contain tokens that match the injection selector", ->
@@ -3675,7 +3675,7 @@ describe "TextEditor", ->
{tokens} = editor.tokenizedLineForScreenRow(0)
expect(tokens[1].value).toBe " http://github.com"
expect(tokens[1].scopeDescriptor).toEqual ["source.js", "comment.line.double-slash.js"]
expect(tokens[1].scopes).toEqual ["source.js", "comment.line.double-slash.js"]
waitsForPromise ->
atom.packages.activatePackage('language-hyperlink')
@@ -3683,7 +3683,7 @@ describe "TextEditor", ->
runs ->
{tokens} = editor.tokenizedLineForScreenRow(0)
expect(tokens[2].value).toBe "http://github.com"
expect(tokens[2].scopeDescriptor).toEqual ["source.js", "comment.line.double-slash.js", "markup.underline.link.http.hyperlink"]
expect(tokens[2].scopes).toEqual ["source.js", "comment.line.double-slash.js", "markup.underline.link.http.hyperlink"]
describe "when the grammar is updated", ->
it "retokenizes existing buffers that contain tokens that match the injection selector", ->
@@ -3695,7 +3695,7 @@ describe "TextEditor", ->
{tokens} = editor.tokenizedLineForScreenRow(0)
expect(tokens[1].value).toBe " SELECT * FROM OCTOCATS"
expect(tokens[1].scopeDescriptor).toEqual ["source.js", "comment.line.double-slash.js"]
expect(tokens[1].scopes).toEqual ["source.js", "comment.line.double-slash.js"]
waitsForPromise ->
atom.packages.activatePackage('package-with-injection-selector')
@@ -3703,7 +3703,7 @@ describe "TextEditor", ->
runs ->
{tokens} = editor.tokenizedLineForScreenRow(0)
expect(tokens[1].value).toBe " SELECT * FROM OCTOCATS"
expect(tokens[1].scopeDescriptor).toEqual ["source.js", "comment.line.double-slash.js"]
expect(tokens[1].scopes).toEqual ["source.js", "comment.line.double-slash.js"]
waitsForPromise ->
atom.packages.activatePackage('language-sql')
@@ -3711,7 +3711,7 @@ describe "TextEditor", ->
runs ->
{tokens} = editor.tokenizedLineForScreenRow(0)
expect(tokens[2].value).toBe "SELECT"
expect(tokens[2].scopeDescriptor).toEqual ["source.js", "comment.line.double-slash.js", "keyword.other.DML.sql"]
expect(tokens[2].scopes).toEqual ["source.js", "comment.line.double-slash.js", "keyword.other.DML.sql"]
describe ".normalizeTabsInBufferRange()", ->
it "normalizes tabs depending on the editor's soft tab/tab length settings", ->
+16 -2
Ver Arquivo
@@ -2,18 +2,23 @@ textUtils = require '../src/text-utils'
describe 'text utilities', ->
describe '.hasPairedCharacter(string)', ->
it 'returns true when the string contains a surrogate pair or variation sequence', ->
it 'returns true when the string contains a surrogate pair, variation sequence, or combined character', ->
expect(textUtils.hasPairedCharacter('abc')).toBe false
expect(textUtils.hasPairedCharacter('a\uD835\uDF97b\uD835\uDF97c')).toBe true
expect(textUtils.hasPairedCharacter('\uD835\uDF97')).toBe true
expect(textUtils.hasPairedCharacter('\u2714\uFE0E')).toBe true
expect(textUtils.hasPairedCharacter('e\u0301')).toBe true
expect(textUtils.hasPairedCharacter('\uD835')).toBe false
expect(textUtils.hasPairedCharacter('\uDF97')).toBe false
expect(textUtils.hasPairedCharacter('\uFE0E')).toBe false
expect(textUtils.hasPairedCharacter('\u0301')).toBe false
expect(textUtils.hasPairedCharacter('\uFE0E\uFE0E')).toBe false
expect(textUtils.hasPairedCharacter('\u0301\u0301')).toBe false
describe '.isPairedCharacter(string, index)', ->
it 'returns true when the index is the start of a high/low surrogate pair or variation sequence', ->
it 'returns true when the index is the start of a high/low surrogate pair, variation sequence, or combined character', ->
expect(textUtils.isPairedCharacter('a\uD835\uDF97b\uD835\uDF97c', 0)).toBe false
expect(textUtils.isPairedCharacter('a\uD835\uDF97b\uD835\uDF97c', 1)).toBe true
expect(textUtils.isPairedCharacter('a\uD835\uDF97b\uD835\uDF97c', 2)).toBe false
@@ -21,12 +26,21 @@ describe 'text utilities', ->
expect(textUtils.isPairedCharacter('a\uD835\uDF97b\uD835\uDF97c', 4)).toBe true
expect(textUtils.isPairedCharacter('a\uD835\uDF97b\uD835\uDF97c', 5)).toBe false
expect(textUtils.isPairedCharacter('a\uD835\uDF97b\uD835\uDF97c', 6)).toBe false
expect(textUtils.isPairedCharacter('a\u2714\uFE0E', 0)).toBe false
expect(textUtils.isPairedCharacter('a\u2714\uFE0E', 1)).toBe true
expect(textUtils.isPairedCharacter('a\u2714\uFE0E', 2)).toBe false
expect(textUtils.isPairedCharacter('a\u2714\uFE0E', 3)).toBe false
expect(textUtils.isPairedCharacter('\uD835')).toBe false
expect(textUtils.isPairedCharacter('\uDF97')).toBe false
expect(textUtils.isPairedCharacter('\uFE0E')).toBe false
expect(textUtils.isPairedCharacter('\uFE0E')).toBe false
expect(textUtils.isPairedCharacter('\uFE0E\uFE0E')).toBe false
expect(textUtils.isPairedCharacter('ae\u0301c', 0)).toBe false
expect(textUtils.isPairedCharacter('ae\u0301c', 1)).toBe true
expect(textUtils.isPairedCharacter('ae\u0301c', 2)).toBe false
expect(textUtils.isPairedCharacter('ae\u0301c', 3)).toBe false
expect(textUtils.isPairedCharacter('ae\u0301c', 4)).toBe false
+13 -13
Ver Arquivo
@@ -92,8 +92,8 @@ describe "ThemeManager", ->
runs ->
reloadHandler.reset()
expect($('style.theme')).toHaveLength 1
expect($('style.theme:eq(0)').attr('id')).toMatch /atom-dark-syntax/
expect($('style[group=theme]')).toHaveLength 1
expect($('style[group=theme]:eq(0)').attr('source-path')).toMatch /atom-dark-syntax/
atom.config.set('core.themes', ['atom-light-syntax', 'atom-dark-syntax'])
waitsFor ->
@@ -101,9 +101,9 @@ describe "ThemeManager", ->
runs ->
reloadHandler.reset()
expect($('style.theme')).toHaveLength 2
expect($('style.theme:eq(0)').attr('id')).toMatch /atom-dark-syntax/
expect($('style.theme:eq(1)').attr('id')).toMatch /atom-light-syntax/
expect($('style[group=theme]')).toHaveLength 2
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 ->
@@ -111,7 +111,7 @@ describe "ThemeManager", ->
runs ->
reloadHandler.reset()
expect($('style.theme')).toHaveLength 0
expect($('style[group=theme]')).toHaveLength 0
# atom-dark-ui has an directory path, the syntax one doesn't
atom.config.set('core.themes', ['theme-with-index-less', 'atom-dark-ui'])
@@ -119,7 +119,7 @@ describe "ThemeManager", ->
reloadHandler.callCount == 1
runs ->
expect($('style.theme')).toHaveLength 2
expect($('style[group=theme]')).toHaveLength 2
importPaths = themeManager.getImportPaths()
expect(importPaths.length).toBe 1
expect(importPaths[0]).toContain 'atom-dark-ui'
@@ -142,8 +142,8 @@ describe "ThemeManager", ->
expect(stylesheetAddedHandler).toHaveBeenCalled()
expect(stylesheetsChangedHandler).toHaveBeenCalled()
element = $('head style[id*="css.css"]')
expect(element.attr('id')).toBe themeManager.stringToId(cssPath)
element = $('head style[source-path*="css.css"]')
expect(element.attr('source-path')).toBe themeManager.stringToId(cssPath)
expect(element.text()).toBe fs.readFileSync(cssPath, 'utf8')
expect(element[0].sheet).toBe stylesheetAddedHandler.argsForCall[0][0]
@@ -159,8 +159,8 @@ describe "ThemeManager", ->
themeManager.requireStylesheet(lessPath)
expect($('head style').length).toBe lengthBefore + 1
element = $('head style[id*="sample.less"]')
expect(element.attr('id')).toBe themeManager.stringToId(lessPath)
element = $('head style[source-path*="sample.less"]')
expect(element.attr('source-path')).toBe themeManager.stringToId(lessPath)
expect(element.text()).toBe """
#header {
color: #4d926f;
@@ -178,9 +178,9 @@ describe "ThemeManager", ->
it "supports requiring css and less stylesheets without an explicit extension", ->
themeManager.requireStylesheet path.join(__dirname, 'fixtures', 'css')
expect($('head style[id*="css.css"]').attr('id')).toBe themeManager.stringToId(atom.project.resolve('css.css'))
expect($('head style[source-path*="css.css"]').attr('source-path')).toBe themeManager.stringToId(atom.project.resolve('css.css'))
themeManager.requireStylesheet path.join(__dirname, 'fixtures', 'sample')
expect($('head style[id*="sample.less"]').attr('id')).toBe themeManager.stringToId(atom.project.resolve('sample.less'))
expect($('head style[source-path*="sample.less"]').attr('source-path')).toBe themeManager.stringToId(atom.project.resolve('sample.less'))
$('head style[id*="css.css"]').remove()
$('head style[id*="sample.less"]').remove()
+42 -42
Ver Arquivo
@@ -51,12 +51,12 @@ describe "TokenizedBuffer", ->
it "initially creates un-tokenized screen lines, then tokenizes lines chunk at a time in the background", ->
line0 = tokenizedBuffer.tokenizedLineForRow(0)
expect(line0.tokens.length).toBe 1
expect(line0.tokens[0]).toEqual(value: line0.text, scopeDescriptor: ['source.js'])
expect(line0.tokens[0]).toEqual(value: line0.text, scopes: ['source.js'])
line11 = tokenizedBuffer.tokenizedLineForRow(11)
expect(line11.tokens.length).toBe 2
expect(line11.tokens[0]).toEqual(value: " ", scopeDescriptor: ['source.js'], isAtomic: true)
expect(line11.tokens[1]).toEqual(value: "return sort(Array.apply(this, arguments));", scopeDescriptor: ['source.js'])
expect(line11.tokens[0]).toEqual(value: " ", scopes: ['source.js'], isAtomic: true)
expect(line11.tokens[1]).toEqual(value: "return sort(Array.apply(this, arguments));", scopes: ['source.js'])
# background tokenization has not begun
expect(tokenizedBuffer.tokenizedLineForRow(0).ruleStack).toBeUndefined()
@@ -149,10 +149,10 @@ describe "TokenizedBuffer", ->
it "updates tokens to reflect the change", ->
buffer.setTextInRange([[0, 0], [2, 0]], "foo()\n7\n")
expect(tokenizedBuffer.tokenizedLineForRow(0).tokens[1]).toEqual(value: '(', scopeDescriptor: ['source.js', 'meta.brace.round.js'])
expect(tokenizedBuffer.tokenizedLineForRow(1).tokens[0]).toEqual(value: '7', scopeDescriptor: ['source.js', 'constant.numeric.js'])
expect(tokenizedBuffer.tokenizedLineForRow(0).tokens[1]).toEqual(value: '(', scopes: ['source.js', 'meta.brace.round.js'])
expect(tokenizedBuffer.tokenizedLineForRow(1).tokens[0]).toEqual(value: '7', scopes: ['source.js', 'constant.numeric.js'])
# line 2 is unchanged
expect(tokenizedBuffer.tokenizedLineForRow(2).tokens[2]).toEqual(value: 'if', scopeDescriptor: ['source.js', 'keyword.control.js'])
expect(tokenizedBuffer.tokenizedLineForRow(2).tokens[2]).toEqual(value: 'if', scopes: ['source.js', 'keyword.control.js'])
expect(changeHandler).toHaveBeenCalled()
[event] = changeHandler.argsForCall[0]
@@ -164,7 +164,7 @@ describe "TokenizedBuffer", ->
buffer.insert([5, 30], '/* */')
changeHandler.reset()
buffer.insert([2, 0], '/*')
expect(tokenizedBuffer.tokenizedLineForRow(3).tokens[0].scopeDescriptor).toEqual ['source.js']
expect(tokenizedBuffer.tokenizedLineForRow(3).tokens[0].scopes).toEqual ['source.js']
expect(changeHandler).toHaveBeenCalled()
[event] = changeHandler.argsForCall[0]
delete event.bufferChange
@@ -172,9 +172,9 @@ describe "TokenizedBuffer", ->
changeHandler.reset()
advanceClock()
expect(tokenizedBuffer.tokenizedLineForRow(3).tokens[0].scopeDescriptor).toEqual ['source.js', 'comment.block.js']
expect(tokenizedBuffer.tokenizedLineForRow(4).tokens[0].scopeDescriptor).toEqual ['source.js', 'comment.block.js']
expect(tokenizedBuffer.tokenizedLineForRow(5).tokens[0].scopeDescriptor).toEqual ['source.js', 'comment.block.js']
expect(tokenizedBuffer.tokenizedLineForRow(3).tokens[0].scopes).toEqual ['source.js', 'comment.block.js']
expect(tokenizedBuffer.tokenizedLineForRow(4).tokens[0].scopes).toEqual ['source.js', 'comment.block.js']
expect(tokenizedBuffer.tokenizedLineForRow(5).tokens[0].scopes).toEqual ['source.js', 'comment.block.js']
expect(changeHandler).toHaveBeenCalled()
[event] = changeHandler.argsForCall[0]
delete event.bufferChange
@@ -185,23 +185,23 @@ describe "TokenizedBuffer", ->
buffer.insert([5, 0], '*/')
buffer.insert([1, 0], 'var ')
expect(tokenizedBuffer.tokenizedLineForRow(1).tokens[0].scopeDescriptor).toEqual ['source.js', 'comment.block.js']
expect(tokenizedBuffer.tokenizedLineForRow(1).tokens[0].scopes).toEqual ['source.js', 'comment.block.js']
describe "when lines are both updated and removed", ->
it "updates tokens to reflect the change", ->
buffer.setTextInRange([[1, 0], [3, 0]], "foo()")
# previous line 0 remains
expect(tokenizedBuffer.tokenizedLineForRow(0).tokens[0]).toEqual(value: 'var', scopeDescriptor: ['source.js', 'storage.modifier.js'])
expect(tokenizedBuffer.tokenizedLineForRow(0).tokens[0]).toEqual(value: 'var', scopes: ['source.js', 'storage.modifier.js'])
# previous line 3 should be combined with input to form line 1
expect(tokenizedBuffer.tokenizedLineForRow(1).tokens[0]).toEqual(value: 'foo', scopeDescriptor: ['source.js'])
expect(tokenizedBuffer.tokenizedLineForRow(1).tokens[6]).toEqual(value: '=', scopeDescriptor: ['source.js', 'keyword.operator.js'])
expect(tokenizedBuffer.tokenizedLineForRow(1).tokens[0]).toEqual(value: 'foo', scopes: ['source.js'])
expect(tokenizedBuffer.tokenizedLineForRow(1).tokens[6]).toEqual(value: '=', scopes: ['source.js', 'keyword.operator.js'])
# lines below deleted regions should be shifted upward
expect(tokenizedBuffer.tokenizedLineForRow(2).tokens[2]).toEqual(value: 'while', scopeDescriptor: ['source.js', 'keyword.control.js'])
expect(tokenizedBuffer.tokenizedLineForRow(3).tokens[4]).toEqual(value: '=', scopeDescriptor: ['source.js', 'keyword.operator.js'])
expect(tokenizedBuffer.tokenizedLineForRow(4).tokens[4]).toEqual(value: '<', scopeDescriptor: ['source.js', 'keyword.operator.js'])
expect(tokenizedBuffer.tokenizedLineForRow(2).tokens[2]).toEqual(value: 'while', scopes: ['source.js', 'keyword.control.js'])
expect(tokenizedBuffer.tokenizedLineForRow(3).tokens[4]).toEqual(value: '=', scopes: ['source.js', 'keyword.operator.js'])
expect(tokenizedBuffer.tokenizedLineForRow(4).tokens[4]).toEqual(value: '<', scopes: ['source.js', 'keyword.operator.js'])
expect(changeHandler).toHaveBeenCalled()
[event] = changeHandler.argsForCall[0]
@@ -214,8 +214,8 @@ describe "TokenizedBuffer", ->
changeHandler.reset()
buffer.setTextInRange([[2, 0], [3, 0]], '/*')
expect(tokenizedBuffer.tokenizedLineForRow(2).tokens[0].scopeDescriptor).toEqual ['source.js', 'comment.block.js', 'punctuation.definition.comment.js']
expect(tokenizedBuffer.tokenizedLineForRow(3).tokens[0].scopeDescriptor).toEqual ['source.js']
expect(tokenizedBuffer.tokenizedLineForRow(2).tokens[0].scopes).toEqual ['source.js', 'comment.block.js', 'punctuation.definition.comment.js']
expect(tokenizedBuffer.tokenizedLineForRow(3).tokens[0].scopes).toEqual ['source.js']
expect(changeHandler).toHaveBeenCalled()
[event] = changeHandler.argsForCall[0]
delete event.bufferChange
@@ -223,8 +223,8 @@ describe "TokenizedBuffer", ->
changeHandler.reset()
advanceClock()
expect(tokenizedBuffer.tokenizedLineForRow(3).tokens[0].scopeDescriptor).toEqual ['source.js', 'comment.block.js']
expect(tokenizedBuffer.tokenizedLineForRow(4).tokens[0].scopeDescriptor).toEqual ['source.js', 'comment.block.js']
expect(tokenizedBuffer.tokenizedLineForRow(3).tokens[0].scopes).toEqual ['source.js', 'comment.block.js']
expect(tokenizedBuffer.tokenizedLineForRow(4).tokens[0].scopes).toEqual ['source.js', 'comment.block.js']
expect(changeHandler).toHaveBeenCalled()
[event] = changeHandler.argsForCall[0]
delete event.bufferChange
@@ -235,19 +235,19 @@ describe "TokenizedBuffer", ->
buffer.setTextInRange([[1, 0], [2, 0]], "foo()\nbar()\nbaz()\nquux()")
# previous line 0 remains
expect(tokenizedBuffer.tokenizedLineForRow(0).tokens[0]).toEqual( value: 'var', scopeDescriptor: ['source.js', 'storage.modifier.js'])
expect(tokenizedBuffer.tokenizedLineForRow(0).tokens[0]).toEqual( value: 'var', scopes: ['source.js', 'storage.modifier.js'])
# 3 new lines inserted
expect(tokenizedBuffer.tokenizedLineForRow(1).tokens[0]).toEqual(value: 'foo', scopeDescriptor: ['source.js'])
expect(tokenizedBuffer.tokenizedLineForRow(2).tokens[0]).toEqual(value: 'bar', scopeDescriptor: ['source.js'])
expect(tokenizedBuffer.tokenizedLineForRow(3).tokens[0]).toEqual(value: 'baz', scopeDescriptor: ['source.js'])
expect(tokenizedBuffer.tokenizedLineForRow(1).tokens[0]).toEqual(value: 'foo', scopes: ['source.js'])
expect(tokenizedBuffer.tokenizedLineForRow(2).tokens[0]).toEqual(value: 'bar', scopes: ['source.js'])
expect(tokenizedBuffer.tokenizedLineForRow(3).tokens[0]).toEqual(value: 'baz', scopes: ['source.js'])
# previous line 2 is joined with quux() on line 4
expect(tokenizedBuffer.tokenizedLineForRow(4).tokens[0]).toEqual(value: 'quux', scopeDescriptor: ['source.js'])
expect(tokenizedBuffer.tokenizedLineForRow(4).tokens[4]).toEqual(value: 'if', scopeDescriptor: ['source.js', 'keyword.control.js'])
expect(tokenizedBuffer.tokenizedLineForRow(4).tokens[0]).toEqual(value: 'quux', scopes: ['source.js'])
expect(tokenizedBuffer.tokenizedLineForRow(4).tokens[4]).toEqual(value: 'if', scopes: ['source.js', 'keyword.control.js'])
# previous line 3 is pushed down to become line 5
expect(tokenizedBuffer.tokenizedLineForRow(5).tokens[4]).toEqual(value: '=', scopeDescriptor: ['source.js', 'keyword.operator.js'])
expect(tokenizedBuffer.tokenizedLineForRow(5).tokens[4]).toEqual(value: '=', scopes: ['source.js', 'keyword.operator.js'])
expect(changeHandler).toHaveBeenCalled()
[event] = changeHandler.argsForCall[0]
@@ -264,17 +264,17 @@ describe "TokenizedBuffer", ->
[event] = changeHandler.argsForCall[0]
delete event.bufferChange
expect(event).toEqual(start: 2, end: 2, delta: 2)
expect(tokenizedBuffer.tokenizedLineForRow(2).tokens[0].scopeDescriptor).toEqual ['source.js', 'comment.block.js', 'punctuation.definition.comment.js']
expect(tokenizedBuffer.tokenizedLineForRow(3).tokens[0].scopeDescriptor).toEqual ['source.js', 'comment.block.js']
expect(tokenizedBuffer.tokenizedLineForRow(4).tokens[0].scopeDescriptor).toEqual ['source.js', 'comment.block.js']
expect(tokenizedBuffer.tokenizedLineForRow(5).tokens[0].scopeDescriptor).toEqual ['source.js']
expect(tokenizedBuffer.tokenizedLineForRow(2).tokens[0].scopes).toEqual ['source.js', 'comment.block.js', 'punctuation.definition.comment.js']
expect(tokenizedBuffer.tokenizedLineForRow(3).tokens[0].scopes).toEqual ['source.js', 'comment.block.js']
expect(tokenizedBuffer.tokenizedLineForRow(4).tokens[0].scopes).toEqual ['source.js', 'comment.block.js']
expect(tokenizedBuffer.tokenizedLineForRow(5).tokens[0].scopes).toEqual ['source.js']
changeHandler.reset()
advanceClock() # tokenize invalidated lines in background
expect(tokenizedBuffer.tokenizedLineForRow(5).tokens[0].scopeDescriptor).toEqual ['source.js', 'comment.block.js']
expect(tokenizedBuffer.tokenizedLineForRow(6).tokens[0].scopeDescriptor).toEqual ['source.js', 'comment.block.js']
expect(tokenizedBuffer.tokenizedLineForRow(7).tokens[0].scopeDescriptor).toEqual ['source.js', 'comment.block.js']
expect(tokenizedBuffer.tokenizedLineForRow(8).tokens[0].scopeDescriptor).not.toBe ['source.js', 'comment.block.js']
expect(tokenizedBuffer.tokenizedLineForRow(5).tokens[0].scopes).toEqual ['source.js', 'comment.block.js']
expect(tokenizedBuffer.tokenizedLineForRow(6).tokens[0].scopes).toEqual ['source.js', 'comment.block.js']
expect(tokenizedBuffer.tokenizedLineForRow(7).tokens[0].scopes).toEqual ['source.js', 'comment.block.js']
expect(tokenizedBuffer.tokenizedLineForRow(8).tokens[0].scopes).not.toBe ['source.js', 'comment.block.js']
expect(changeHandler).toHaveBeenCalled()
[event] = changeHandler.argsForCall[0]
@@ -343,7 +343,7 @@ describe "TokenizedBuffer", ->
expect(tokens[0].value).toBe "#"
expect(tokens[1].value).toBe " Econ 101"
expect(tokens[2].value).toBe tabAsSpaces
expect(tokens[2].scopeDescriptor).toEqual tokens[1].scopeDescriptor
expect(tokens[2].scopes).toEqual tokens[1].scopes
expect(tokens[2].isAtomic).toBeTruthy()
expect(tokens[3].value).toBe ""
@@ -526,7 +526,7 @@ describe "TokenizedBuffer", ->
fullyTokenize(tokenizedBuffer)
{tokens} = tokenizedBuffer.tokenizedLineForRow(0)
expect(tokens[0]).toEqual value: "<div class='name'>", scopeDescriptor: ["text.html.ruby"]
expect(tokens[0]).toEqual value: "<div class='name'>", scopes: ["text.html.ruby"]
waitsForPromise ->
atom.packages.activatePackage('language-html')
@@ -534,7 +534,7 @@ describe "TokenizedBuffer", ->
runs ->
fullyTokenize(tokenizedBuffer)
{tokens} = tokenizedBuffer.tokenizedLineForRow(0)
expect(tokens[0]).toEqual value: '<', scopeDescriptor: ["text.html.ruby","meta.tag.block.any.html","punctuation.definition.tag.begin.html"]
expect(tokens[0]).toEqual value: '<', scopes: ["text.html.ruby","meta.tag.block.any.html","punctuation.definition.tag.begin.html"]
describe ".tokenForPosition(position)", ->
afterEach ->
@@ -545,9 +545,9 @@ describe "TokenizedBuffer", ->
buffer = atom.project.bufferForPathSync('sample.js')
tokenizedBuffer = new TokenizedBuffer({buffer})
fullyTokenize(tokenizedBuffer)
expect(tokenizedBuffer.tokenForPosition([1,0]).scopeDescriptor).toEqual ["source.js"]
expect(tokenizedBuffer.tokenForPosition([1,1]).scopeDescriptor).toEqual ["source.js"]
expect(tokenizedBuffer.tokenForPosition([1,2]).scopeDescriptor).toEqual ["source.js", "storage.modifier.js"]
expect(tokenizedBuffer.tokenForPosition([1,0]).scopes).toEqual ["source.js"]
expect(tokenizedBuffer.tokenForPosition([1,1]).scopes).toEqual ["source.js"]
expect(tokenizedBuffer.tokenForPosition([1,2]).scopes).toEqual ["source.js", "storage.modifier.js"]
describe ".bufferRangeForScopeAtPosition(selector, position)", ->
beforeEach ->
+1 -1
Ver Arquivo
@@ -28,7 +28,7 @@ describe "TokenizedLine", ->
ensureValidScopeTree(child, scopeDescriptor.concat([scopeTree.scope]))
else
expect(scopeTree).toBe tokens[tokenIndex++]
expect(scopeDescriptor).toEqual scopeTree.scopeDescriptor
expect(scopeDescriptor).toEqual scopeTree.scopes
waitsForPromise ->
atom.project.open('coffee.coffee').then (o) -> editor = o
+2 -5
Ver Arquivo
@@ -14,14 +14,9 @@ describe "Window", ->
loadSettings.initialPath = initialPath
loadSettings
atom.project.destroy()
windowEventHandler = new WindowEventHandler()
atom.deserializeEditorWindow()
projectPath = atom.project.getPaths()[0]
afterEach ->
windowEventHandler.unsubscribe()
$(window).off 'beforeunload'
describe "when the window is loaded", ->
it "doesn't have .is-blurred on the body tag", ->
expect($("body")).not.toHaveClass("is-blurred")
@@ -107,6 +102,8 @@ describe "Window", ->
describe ".removeEditorWindow()", ->
it "unsubscribes from all buffers", ->
spyOn(atom.windowEventHandler, 'unsubscribe') # don't unsubscribe from window events
waitsForPromise ->
atom.workspace.open("sample.js")
+36
Ver Arquivo
@@ -456,3 +456,39 @@ describe "Workspace", ->
expect(item2.isModified()).toBe false
expect(atom.setDocumentEdited).toHaveBeenCalledWith(false)
describe "adding panels", ->
class TestPanel
constructior: ->
describe '::addLeftPanel(model)', ->
it 'adds a panel to the correct panel container', ->
atom.workspace.panelContainers.left.onDidAddPanel addPanelSpy = jasmine.createSpy()
panel = atom.workspace.addLeftPanel(item: new TestPanel())
expect(panel).toBeDefined()
expect(addPanelSpy).toHaveBeenCalledWith({panel, index: 0})
describe '::addRightPanel(model)', ->
it 'adds a panel to the correct panel container', ->
atom.workspace.panelContainers.right.onDidAddPanel addPanelSpy = jasmine.createSpy()
panel = atom.workspace.addRightPanel(item: new TestPanel())
expect(panel).toBeDefined()
expect(addPanelSpy).toHaveBeenCalledWith({panel, index: 0})
describe '::addTopPanel(model)', ->
it 'adds a panel to the correct panel container', ->
atom.workspace.panelContainers.top.onDidAddPanel addPanelSpy = jasmine.createSpy()
panel = atom.workspace.addTopPanel(item: new TestPanel())
expect(panel).toBeDefined()
expect(addPanelSpy).toHaveBeenCalledWith({panel, index: 0})
describe '::addBottomPanel(model)', ->
it 'adds a panel to the correct panel container', ->
atom.workspace.panelContainers.bottom.onDidAddPanel addPanelSpy = jasmine.createSpy()
panel = atom.workspace.addBottomPanel(item: new TestPanel())
expect(panel).toBeDefined()
expect(addPanelSpy).toHaveBeenCalledWith({panel, index: 0})
+16
Ver Arquivo
@@ -270,3 +270,19 @@ describe "WorkspaceView", ->
atom.config.set('editor.lineHeight', '30px')
expect(getComputedStyle(editorNode).lineHeight).toBe atom.config.get('editor.lineHeight')
expect(editor.getLineHeightInPixels()).not.toBe initialLineHeight
describe 'panel containers', ->
workspaceElement = null
beforeEach ->
workspaceElement = atom.workspace.getView(atom.workspace)
it 'inserts panel container elements in the correct places in the DOM', ->
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[location="top"]')
bottomContainer = workspaceElement.querySelector('atom-panel-container[location="bottom"]')
expect(topContainer.nextSibling).toBe workspaceElement.paneContainer
expect(bottomContainer.previousSibling).toBe workspaceElement.paneContainer
+14 -3
Ver Arquivo
@@ -14,6 +14,7 @@ fs = require 'fs-plus'
{$} = require './space-pen-extensions'
WindowEventHandler = require './window-event-handler'
StylesElement = require './styles-element'
# Essential: Atom global for dealing with packages, themes, menus, and the window.
#
@@ -29,7 +30,10 @@ class Atom extends Model
#
# Returns an Atom instance, fully initialized
@loadOrCreate: (mode) ->
@deserialize(@loadState(mode)) ? new this({mode, @version})
startTime = Date.now()
atom = @deserialize(@loadState(mode)) ? new this({mode, @version})
atom.deserializeTimings.atom = Date.now() - startTime
atom
# Deserializes the Atom environment from a state object
@deserialize: (state) ->
@@ -103,7 +107,7 @@ class Atom extends Model
Section: Properties
###
# Experimental: A {CommandRegistry} instance
# Public: A {CommandRegistry} instance
commands: null
# Public: A {Config} instance
@@ -152,6 +156,7 @@ class Atom extends Model
{@mode} = @state
DeserializerManager = require './deserializer-manager'
@deserializers = new DeserializerManager()
@deserializeTimings = {}
# Sets up the basic services that should be available in all modes
# (both spec and application).
@@ -182,6 +187,7 @@ class Atom extends Model
Clipboard = require './clipboard'
Syntax = require './syntax'
ThemeManager = require './theme-manager'
StyleManager = require './style-manager'
ContextMenuManager = require './context-menu-manager'
MenuManager = require './menu-manager'
{devMode, safeMode, resourcePath} = @getLoadSettings()
@@ -196,11 +202,17 @@ class Atom extends Model
# Make react.js faster
process.env.NODE_ENV ?= 'production' unless devMode
# Set Atom's home so packages don't have to guess it
process.env.ATOM_HOME = configDirPath
@config = new Config({configDirPath, resourcePath})
@keymaps = new KeymapManager({configDirPath, resourcePath})
@keymap = @keymaps # Deprecated
@commands = new CommandRegistry
@commands.patchDOMEventMethods()
@packages = new PackageManager({devMode, configDirPath, resourcePath, safeMode})
@styles = new StyleManager
document.head.appendChild(new StylesElement)
@themes = new ThemeManager({packageManager: @packages, configDirPath, resourcePath, safeMode})
@contextMenu = new ContextMenuManager({resourcePath, devMode})
@menu = new MenuManager({resourcePath})
@@ -597,7 +609,6 @@ class Atom extends Model
delete @state.packageStates
deserializeEditorWindow: ->
@deserializeTimings = {}
@deserializePackageStates()
@deserializeProject()
@deserializeWorkspaceView()
+31 -5
Ver Arquivo
@@ -10,24 +10,50 @@ _ = require 'underscore-plus'
module.exports =
class ApplicationMenu
constructor: (@version) ->
@menu = Menu.buildFromTemplate @getDefaultTemplate()
Menu.setApplicationMenu @menu
@windowTemplates = new WeakMap()
@setActiveTemplate(@getDefaultTemplate())
global.atomApplication.autoUpdateManager.on 'state-changed', (state) =>
@showUpdateMenuItem(state)
# Public: Updates the entire menu with the given keybindings.
#
# window - The BrowserWindow this menu template is associated with.
# template - The Object which describes the menu to display.
# keystrokesByCommand - An Object where the keys are commands and the values
# are Arrays containing the keystroke.
update: (template, keystrokesByCommand) ->
update: (window, template, keystrokesByCommand) ->
return unless window is @lastFocusedWindow
@translateTemplate(template, keystrokesByCommand)
@substituteVersion(template)
@menu = Menu.buildFromTemplate(template)
Menu.setApplicationMenu(@menu)
@windowTemplates.set(window, template)
@setActiveTemplate(template)
@showUpdateMenuItem(global.atomApplication.autoUpdateManager.getState())
setActiveTemplate: (template) ->
unless _.isEqual(template, @activeTemplate)
@activeTemplate = template
@menu = Menu.buildFromTemplate(_.deepClone(template))
Menu.setApplicationMenu(@menu)
# Register a BrowserWindow with this application menu.
addWindow: (window) ->
@lastFocusedWindow ?= window
focusHandler = =>
@lastFocusedWindow = window
if template = @windowTemplates.get(window)
@setActiveTemplate(template)
window.on 'focus', focusHandler
window.once 'closed', =>
@lastFocusedWindow = null if window is @lastFocusedWindow
@windowTemplates.delete(window)
window.removeListener 'focus', focusHandler
@enableWindowSpecificItems(true)
# Flattens the given menu and submenu items into an single Array.
#
# menu - A complete menu configuration object for atom-shell's menu API.
+3 -2
Ver Arquivo
@@ -97,7 +97,7 @@ class AtomApplication
# Public: Adds the {AtomWindow} to the global window list.
addWindow: (window) ->
@windows.push window
@applicationMenu?.enableWindowSpecificItems(true)
@applicationMenu?.addWindow(window.browserWindow)
window.once 'window:loaded', =>
@autoUpdateManager.emitUpdateAvailableEvent(window)
@@ -215,7 +215,8 @@ class AtomApplication
@promptForPath({window})
ipc.on 'update-application-menu', (event, template, keystrokesByCommand) =>
@applicationMenu.update(template, keystrokesByCommand)
win = BrowserWindow.fromWebContents(event.sender)
@applicationMenu.update(win, template, keystrokesByCommand)
ipc.on 'run-package-specs', (event, specDirectory) =>
@runSpecs({resourcePath: global.devResourcePath, specDirectory: specDirectory, exitWhenDone: false})
+18 -3
Ver Arquivo
@@ -78,13 +78,18 @@ parseCommandLine = ->
Folder paths will open in an existing window if that folder has already been
opened or a new window if it hasn't.
Environment Variables:
ATOM_DEV_RESOURCE_PATH The path from which Atom loads source code in dev mode.
Defaults to `~/github/atom`.
"""
options.alias('d', 'dev').boolean('d').describe('d', 'Run in development mode.')
options.alias('f', 'foreground').boolean('f').describe('f', 'Keep the browser process in the foreground.')
options.alias('h', 'help').boolean('h').describe('h', 'Print this usage message.')
options.alias('l', 'log-file').string('l').describe('l', 'Log all output to file.')
options.alias('n', 'new-window').boolean('n').describe('n', 'Open a new window.')
options.alias('s', 'spec-directory').string('s').describe('s', 'Set the spec directory (default: Atom\'s spec directory).')
options.alias('r', 'resource-path').string('r').describe('r', 'Set the path to the Atom source directory and enable dev-mode.')
options.alias('s', 'spec-directory').string('s').describe('s', 'Set the directory from which to run package specs (default: Atom\'s spec directory).')
options.boolean('safe').describe('safe', 'Do not load packages from ~/.atom/packages or ~/.atom/dev/packages.')
options.alias('t', 'test').boolean('t').describe('t', 'Run the specified specs and exit with error code on failures.')
options.alias('v', 'version').boolean('v').describe('v', 'Print the version.')
@@ -113,8 +118,18 @@ parseCommandLine = ->
if args['resource-path']
devMode = true
resourcePath = args['resource-path']
else if devMode
resourcePath = global.devResourcePath
else
# Set resourcePath based on the specDirectory if running specs on atom core
if specDirectory?
packageDirectoryPath = path.join(specDirectory, '..')
packageManifestPath = path.join(packageDirectoryPath, 'package.json')
if fs.statSyncNoException(packageManifestPath)
try
packageManifest = JSON.parse(fs.readFileSync(packageManifestPath))
resourcePath = packageDirectoryPath if packageManifest.name is 'atom'
if devMode
resourcePath ?= global.devResourcePath
unless fs.statSyncNoException(resourcePath)
resourcePath = path.dirname(path.dirname(__dirname))
+177 -42
Ver Arquivo
@@ -1,17 +1,50 @@
{Emitter, Disposable, CompositeDisposable} = require 'event-kit'
{specificity} = require 'clear-cut'
_ = require 'underscore-plus'
Grim = require 'grim'
{$} = require './space-pen-extensions'
SequenceCount = 0
SpecificityCache = {}
NativeEventBubbling =
abort: false
beforeinput: true
blur: false
click: true
compositionstart: true
compositionupdate: true
compositionend: true
dblclick: true
error: false
focus: false
focusin: true
focusout: true
input: true
keydown: true
keyup: true
load: false
mousedown: true
mouseenter: false
mouseleave: false
mousemove: true
mouseout: true
mouseover: true
mouseup: true
resize: false
scroll: false
select: true
textInput: true
unload: false
wheel: true
mousewheel: true
module.exports =
# Experimental: Associates listener functions with commands in a
# context-sensitive way using CSS selectors. You can access a global instance of
# this class via `atom.commands`, and commands registered there will be
# presented in the command palette.
# Public: Associates listener functions with commands in a context-sensitive way
# using CSS selectors. You can access a global instance of this class via
# `atom.commands`, and commands registered there will be presented in the
# command palette.
#
# The global command registry facilitates a style of event handling known as
# *event delegation* that was popularized by jQuery. Atom commands are expressed
@@ -35,16 +68,22 @@ module.exports =
# Here is a command that inserts the current date in an editor:
#
# ```coffee
# atom.commands.add 'atom-text-editor',
# atom.commands.listen 'atom-text-editor',
# 'user:insert-date': (event) ->
# editor = $(this).view().getModel()
# # soon the above above line will be:
# # editor = @getModel()
# editor.insertText(new Date().toLocaleString())
# ```
module.exports =
class CommandRegistry
patchedDOMEventMethods: false
originalAddEventListener: Node::addEventListener
originalRemoveEventListener: Node::removeEventListener
constructor: (@rootNode) ->
@registeredCommands = {}
@registeredCommandsByInlineNode = new WeakMap
@selectorBasedListenersByCommandName = {}
@inlineListenersByCommandName = {}
@emitter = new Emitter
@@ -53,6 +92,52 @@ class CommandRegistry
for commandName of @registeredCommands
window.removeEventListener(commandName, @handleCommandEvent, true)
patchDOMEventMethods: ->
if @patchedDOMEventMethods
throw new Error("Already patched DOM event methods for this registry.")
else
@patchedDOMEventMethods = true
registry = this
disposablesByEventName = {}
@originalAddEventListener = Node::addEventListener
@originalRemoveEventListener = Node::originalRemoveEventListener
Node::addEventListener = (eventName, callback, useCapture=false) ->
return unless callback?
target = this
disposable = registry.listen(target, eventName, callback, useCapture)
disposablesByEventName[eventName] ?= {}
disposablesByUseCapture = disposablesByEventName[eventName]
disposablesByUseCapture[useCapture] ?= new WeakMap
disposablesByTarget = disposablesByUseCapture[useCapture]
disposablesByTarget.set(target, new WeakMap) unless disposablesByTarget.has(target)
disposablesByCallback = disposablesByTarget.get(target)
disposablesByCallback.set(callback, new CompositeDisposable) unless disposablesByCallback.has(callback)
disposablesByCallback.get(callback).add(disposable)
return
Node::removeEventListener = (eventName, callback, useCapture=false) ->
return unless callback?
target = this
disposablesByEventName[eventName]?[useCapture]?.get(target)?.get(callback)?.dispose()
return
restoreDOMEventMethods: ->
Node::addEventListener = @originalAddEventListener
Node::removeEventListener = @originalRemoveEventListener
@patchedDOMEventMethods = false
addEventListener: (target, eventName, callback, useCapture) ->
@originalAddEventListener.call(target, eventName, callback, useCapture)
removeEventListener: (target, eventName, callback, useCapture) ->
@originalRemoveEventListener.call(target, eventName, callback, useCapture)
# Public: Add one or more command listeners associated with a selector.
#
# ## Arguments: Registering One Command
@@ -78,23 +163,30 @@ class CommandRegistry
#
# Returns a {Disposable} on which `.dispose()` can be called to remove the
# added command handler(s).
add: (target, commandName, callback) ->
listen: (target, commandName, callback, useCapture=false) ->
if typeof commandName is 'object'
commands = commandName
disposable = new CompositeDisposable
for commandName, callback of commands
disposable.add @add(target, commandName, callback)
disposable.add @listen(target, commandName, callback, useCapture)
return disposable
if typeof target is 'string'
@addSelectorBasedListener(target, commandName, callback)
@addSelectorBasedListener(target, commandName, callback, useCapture)
else
@addInlineListener(target, commandName, callback)
@addInlineListener(target, commandName, callback, useCapture)
addSelectorBasedListener: (selector, commandName, callback) ->
add: (target, commandName, callback) ->
Grim.deprecate("Use CommandRegistry::listen instead")
@listen(target, commandName, callback)
capture: (target, commandName, callback) ->
@listen(target, commandName, callback, true)
addSelectorBasedListener: (selector, commandName, callback, useCapture) ->
@selectorBasedListenersByCommandName[commandName] ?= []
listenersForCommand = @selectorBasedListenersByCommandName[commandName]
listener = new SelectorBasedListener(selector, callback)
listener = new SelectorBasedListener(selector, callback, useCapture)
listenersForCommand.push(listener)
@commandRegistered(commandName)
@@ -103,17 +195,17 @@ class CommandRegistry
listenersForCommand.splice(listenersForCommand.indexOf(listener), 1)
delete @selectorBasedListenersByCommandName[commandName] if listenersForCommand.length is 0
addInlineListener: (element, commandName, callback) ->
addInlineListener: (element, commandName, callback, useCapture) ->
@inlineListenersByCommandName[commandName] ?= new WeakMap
listenersForCommand = @inlineListenersByCommandName[commandName]
unless listenersForElement = listenersForCommand.get(element)
listenersForElement = []
listenersForCommand.set(element, listenersForElement)
listener = new InlineListener(callback)
listener = new InlineListener(callback, useCapture)
listenersForElement.push(listener)
@commandRegistered(commandName)
@commandRegistered(commandName, element)
new Disposable ->
listenersForElement.splice(listenersForElement.indexOf(listener), 1)
@@ -161,11 +253,17 @@ class CommandRegistry
# processed.
#
# * `target` The DOM node at which to start bubbling the command event.
# * `commandName` {String} indicating the name of the command to dispatch.
dispatch: (target, commandName, detail) ->
event = new CustomEvent(commandName, {bubbles: true, detail})
# * `event` {String} indicating the name of the command to dispatch or a
# DOM event object.
# * `detail` The detail to associate with the dispatched DOM event. If present
# overrides the `detail` of the `event` if it is a DOM event object.
dispatch: (target, event, detail) ->
if typeof event is 'string'
event = new CustomEvent(event, {bubbles: NativeEventBubbling[event] ? true})
eventWithTarget = Object.create event,
target: value: target
detail: value: detail ? event.detail
preventDefault: value: ->
stopPropagation: value: ->
stopImmediatePropagation: value: ->
@@ -186,56 +284,93 @@ class CommandRegistry
@selectorBasedListenersByCommandName[commandName] = listeners.slice()
handleCommandEvent: (originalEvent) =>
originalEvent.stopImmediatePropagation()
propagationStopped = false
immediatePropagationStopped = false
matched = false
currentTarget = originalEvent.target
invokedListener = false
{target, type} = originalEvent
currentTarget = null
bubbles = NativeEventBubbling[type] ? originalEvent.bubbles
syntheticEvent = Object.create originalEvent,
eventPhase: value: Event.BUBBLING_PHASE
eventPhase: get: -> eventPhase
currentTarget: get: -> currentTarget
preventDefault: value: ->
originalEvent.preventDefault()
stopPropagation: value: ->
originalEvent.stopPropagation()
propagationStopped = true
stopImmediatePropagation: value: ->
originalEvent.stopImmediatePropagation()
propagationStopped = true
immediatePropagationStopped = true
preventDefault: value: ->
originalEvent.preventDefault()
abortKeyBinding: value: ->
originalEvent.abortKeyBinding?()
@emitter.emit 'will-dispatch', syntheticEvent
loop
listeners = @inlineListenersByCommandName[originalEvent.type]?.get(currentTarget) ? []
if currentTarget.webkitMatchesSelector?
selectorBasedListeners =
(@selectorBasedListenersByCommandName[originalEvent.type] ? [])
.filter (listener) -> currentTarget.webkitMatchesSelector(listener.selector)
.sort (a, b) -> a.compare(b)
listeners = listeners.concat(selectorBasedListeners)
path = @getBubblePath(target)
matched = true if listeners.length > 0
for listener in listeners
# Capture phase: Invoke listeners registered via {::capture}, starting with
# the window and moving downward towards the event target.
eventPhase = Event.CAPTURING_PHASE
for pathIndex in [(path.length - 1)..0]
currentTarget = path[pathIndex]
listeners = @listenersForNode(currentTarget, type)
for listener in listeners when listener.useCapture
break if immediatePropagationStopped
invokedListener = true
listener.callback.call(currentTarget, syntheticEvent)
break if propagationStopped
return invokedListener if propagationStopped
# Bubble phase: Invoke listeners registered via {::listen}, starting with
# the event target and moving upward towards the window. If the event's
# `.bubbles` property is false, we abort after dispatching on the target.
eventPhase = Event.BUBBLING_PHASE
for currentTarget in path
listeners = @listenersForNode(currentTarget, type)
for listener in listeners when not listener.useCapture
break if immediatePropagationStopped
invokedListener = true
listener.callback.call(currentTarget, syntheticEvent)
break if currentTarget is window
break unless bubbles
break if propagationStopped
currentTarget = currentTarget.parentNode ? window
matched
invokedListener
commandRegistered: (commandName) ->
commandRegistered: (commandName, inlineNode) ->
unless @registeredCommands[commandName]
window.addEventListener(commandName, @handleCommandEvent, true)
@addEventListener(window, commandName, @handleCommandEvent, true)
@registeredCommands[commandName] = true
if inlineNode? and not @registeredCommandsByInlineNode.get(inlineNode)?[commandName]
@addEventListener(inlineNode, commandName, @handleCommandEvent, true)
@registeredCommandsByInlineNode.set(inlineNode, {}) unless @registeredCommandsByInlineNode.has(inlineNode)
@registeredCommandsByInlineNode.get(inlineNode)[commandName] = true
getBubblePath: (target) ->
path = []
currentTarget = target
loop
path.push(currentTarget)
break if currentTarget is window
currentTarget = currentTarget.parentNode ? window
path
listenersForNode: (node, eventType) ->
listeners = @inlineListenersByCommandName[eventType]?.get(node) ? []
if node.matches?
selectorBasedListeners =
(@selectorBasedListenersByCommandName[eventType] ? [])
.filter (listener) -> node.matches(listener.selector)
.sort (a, b) -> a.compare(b)
listeners = listeners.concat(selectorBasedListeners)
listeners
class SelectorBasedListener
constructor: (@selector, @callback) ->
constructor: (@selector, @callback, @useCapture) ->
@specificity = (SpecificityCache[@selector] ?= specificity(@selector))
@sequenceNumber = SequenceCount++
@@ -244,4 +379,4 @@ class SelectorBasedListener
other.sequenceNumber - @sequenceNumber
class InlineListener
constructor: (@callback) ->
constructor: (@callback, @useCapture) ->
+61 -31
Ver Arquivo
@@ -9,6 +9,7 @@ pathWatcher = require 'pathwatcher'
{deprecate} = require 'grim'
ScopedPropertyStore = require 'scoped-property-store'
ScopeDescriptor = require './scope-descriptor'
# Essential: Used to access all of Atom's configuration details.
#
@@ -313,6 +314,7 @@ class Config
@settings = {}
@scopedSettingsStore = new ScopedPropertyStore
@usersScopedSettings = new CompositeDisposable
@usersScopedSettingPriority = {priority: 1000}
@configFileHasErrors = false
@configFilePath = fs.resolve(@configDirPath, 'config', ['json', 'cson'])
@configFilePath ?= path.join(@configDirPath, 'config.cson')
@@ -335,7 +337,7 @@ class Config
# # do stuff with value
# ```
#
# * `scopeDescriptor` (optional) {Array} of {String}s describing a path from
# * `scopeDescriptor` (optional) {ScopeDescriptor} describing a path from
# the root of the syntax tree to a token. Get one by calling
# {editor.getLastCursor().getScopeDescriptor()}. See {::get} for examples.
# See [the scopes docs](https://atom.io/docs/latest/advanced/scopes-and-scope-descriptors)
@@ -351,7 +353,7 @@ class Config
if args.length is 2
# observe(keyPath, callback)
[keyPath, callback, scopeDescriptor, options] = args
else if args.length is 3 and Array.isArray(scopeDescriptor)
else if args.length is 3 and (Array.isArray(scopeDescriptor) or scopeDescriptor instanceof ScopeDescriptor)
# observe(scopeDescriptor, keyPath, callback)
[scopeDescriptor, keyPath, callback, options] = args
else if args.length is 3 and _.isString(scopeDescriptor) and _.isObject(keyPath)
@@ -373,7 +375,7 @@ class Config
# Essential: Add a listener for changes to a given key path. If `keyPath` is
# not specified, your callback will be called on changes to any key.
#
# * `scopeDescriptor` (optional) {Array} of {String}s describing a path from
# * `scopeDescriptor` (optional) {ScopeDescriptor} describing a path from
# the root of the syntax tree to a token. Get one by calling
# {editor.getLastCursor().getScopeDescriptor()}. See {::get} for examples.
# See [the scopes docs](https://atom.io/docs/latest/advanced/scopes-and-scope-descriptors)
@@ -444,7 +446,7 @@ class Config
# atom.config.get(scopeDescriptor, 'editor.tabLength') # => 2
# ```
#
# * `scopeDescriptor` (optional) {Array} of {String}s describing a path from
# * `scopeDescriptor` (optional) {ScopeDescriptor} describing a path from
# the root of the syntax tree to a token. Get one by calling
# {editor.getLastCursor().getScopeDescriptor()}
# See [the scopes docs](https://atom.io/docs/latest/advanced/scopes-and-scope-descriptors)
@@ -536,7 +538,8 @@ class Config
settings = @scopedSettingsStore.propertiesForSourceAndSelector('user-config', scopeSelector)
@scopedSettingsStore.removePropertiesForSourceAndSelector('user-config', scopeSelector)
_.setValueForKeyPath(settings, keyPath, undefined)
@addScopedSettings('user-config', scopeSelector, settings)
@addScopedSettings('user-config', scopeSelector, settings, @usersScopedSettingPriority)
@save() unless @configFileHasErrors
@getDefault(scopeSelector, keyPath)
else
@set(keyPath, _.valueForKeyPath(@defaultSettings, keyPath))
@@ -589,7 +592,7 @@ class Config
# Returns an {Object} eg. `{type: 'integer', default: 23, minimum: 1}`.
# Returns `null` when the keyPath has no schema specified.
getSchema: (keyPath) ->
keys = keyPath.split('.')
keys = splitKeyPath(keyPath)
schema = @schema
for key in keys
break unless schema?
@@ -669,7 +672,7 @@ class Config
rootSchema = @schema
if keyPath
for key in keyPath.split('.')
for key in splitKeyPath(keyPath)
rootSchema.type = 'object'
rootSchema.properties ?= {}
properties = rootSchema.properties
@@ -678,6 +681,7 @@ class Config
_.extend rootSchema, schema
@setDefaults(keyPath, @extractDefaultsFromSchema(schema))
@setScopedDefaultsFromSchema(keyPath, schema)
load: ->
@initializeConfigDirectory()
@@ -753,7 +757,7 @@ class Config
unsetUnspecifiedValues = (keyPath, value) =>
if isPlainObject(value)
keys = if keyPath? then keyPath.split('.') else []
keys = splitKeyPath(keyPath)
for key, childValue of value
continue unless value.hasOwnProperty(key)
unsetUnspecifiedValues(keys.concat([key]).join('.'), childValue)
@@ -766,7 +770,7 @@ class Config
setRecursive: (keyPath, value) ->
if isPlainObject(value)
keys = if keyPath? then keyPath.split('.') else []
keys = splitKeyPath(keyPath)
for key, childValue of value
continue unless value.hasOwnProperty(key)
@setRecursive(keys.concat([key]).join('.'), childValue)
@@ -809,8 +813,8 @@ class Config
isSubKeyPath: (keyPath, subKeyPath) ->
return false unless keyPath? and subKeyPath?
pathSubTokens = subKeyPath.split('.')
pathTokens = keyPath.split('.').slice(0, pathSubTokens.length)
pathSubTokens = splitKeyPath(subKeyPath)
pathTokens = splitKeyPath(keyPath).slice(0, pathSubTokens.length)
_.isEqual(pathTokens, pathSubTokens)
setRawDefault: (keyPath, value) ->
@@ -821,7 +825,7 @@ class Config
setDefaults: (keyPath, defaults) ->
if defaults? and isPlainObject(defaults)
keys = if keyPath? then keyPath.split('.') else []
keys = splitKeyPath(keyPath)
for key, childValue of defaults
continue unless defaults.hasOwnProperty(key)
@setDefaults(keys.concat([key]).join('.'), childValue)
@@ -832,6 +836,32 @@ class Config
catch e
console.warn("'#{keyPath}' could not set the default. Attempted default: #{JSON.stringify(defaults)}; Schema: #{JSON.stringify(@getSchema(keyPath))}")
# `schema` will look something like this
#
# ```coffee
# type: 'string'
# default: 'ok'
# scopes:
# '.source.js':
# default: 'omg'
# ```
setScopedDefaultsFromSchema: (keyPath, schema) ->
if schema.scopes? and isPlainObject(schema.scopes)
scopedDefaults = {}
for scope, scopeSchema of schema.scopes
continue unless scopeSchema.hasOwnProperty('default')
scopedDefaults[scope] = {}
_.setValueForKeyPath(scopedDefaults[scope], keyPath, scopeSchema.default)
@scopedSettingsStore.addProperties('schema-default', scopedDefaults)
if schema.type is 'object' and schema.properties? and isPlainObject(schema.properties)
keys = splitKeyPath(keyPath)
for key, childValue of schema.properties
continue unless schema.properties.hasOwnProperty(key)
@setScopedDefaultsFromSchema(keys.concat([key]).join('.'), childValue)
return
extractDefaultsFromSchema: (schema) ->
if schema.default?
schema.default
@@ -852,13 +882,13 @@ class Config
resetUserScopedSettings: (newScopedSettings) ->
@usersScopedSettings?.dispose()
@usersScopedSettings = new CompositeDisposable
@usersScopedSettings.add @scopedSettingsStore.addProperties('user-config', newScopedSettings)
@usersScopedSettings.add @scopedSettingsStore.addProperties('user-config', newScopedSettings, @usersScopedSettingPriority)
@emitter.emit 'did-change'
addScopedSettings: (source, selector, value) ->
addScopedSettings: (source, selector, value, options) ->
settingsBySelector = {}
settingsBySelector[selector] = value
disposable = @scopedSettingsStore.addProperties(source, settingsBySelector)
disposable = @scopedSettingsStore.addProperties(source, settingsBySelector, options)
@emitter.emit 'did-change'
new Disposable =>
disposable.dispose()
@@ -872,12 +902,12 @@ class Config
settingsBySelector = {}
settingsBySelector[selector] = value
@usersScopedSettings.add @scopedSettingsStore.addProperties('user-config', settingsBySelector)
@usersScopedSettings.add @scopedSettingsStore.addProperties('user-config', settingsBySelector, @usersScopedSettingPriority)
@emitter.emit 'did-change'
getRawScopedValue: (scopeDescriptor, keyPath) ->
scopeChain = @scopeChainForScopeDescriptor(scopeDescriptor)
@scopedSettingsStore.getPropertyValue(scopeChain, keyPath)
scopeDescriptor = ScopeDescriptor.fromObject(scopeDescriptor)
@scopedSettingsStore.getPropertyValue(scopeDescriptor.getScopeChain(), keyPath)
observeScopedKeyPath: (scopeDescriptor, keyPath, callback) ->
oldValue = @get(scopeDescriptor, keyPath)
@@ -904,19 +934,8 @@ class Config
# * language mode uses it for one thing.
# * autocomplete uses it for editor.completions
settingsForScopeDescriptor: (scopeDescriptor, keyPath) ->
scopeChain = scopeDescriptor
.map (scope) ->
scope = ".#{scope}" unless scope[0] is '.'
scope
.join(' ')
@scopedSettingsStore.getProperties(scopeChain, keyPath)
scopeChainForScopeDescriptor: (scopeDescriptor) ->
scopeDescriptor
.map (scope) ->
scope = ".#{scope}" unless scope[0] is '.'
scope
.join(' ')
scopeDescriptor = ScopeDescriptor.fromObject(scopeDescriptor)
@scopedSettingsStore.getProperties(scopeDescriptor.getScopeChain(), keyPath)
# Base schema enforcers. These will coerce raw input into the specified type,
# and will throw an error when the value cannot be coerced. Throwing the error
@@ -1016,3 +1035,14 @@ Config.addSchemaEnforcers
isPlainObject = (value) ->
_.isObject(value) and not _.isArray(value) and not _.isFunction(value) and not _.isString(value)
splitKeyPath = (keyPath) ->
return [] unless keyPath?
startIndex = 0
keyPathArray = []
for char, i in keyPath
if char is '.' and (i is 0 or keyPath[i-1] != '\\')
keyPathArray.push keyPath.substring(startIndex, i)
startIndex = i + 1
keyPathArray.push keyPath.substr(startIndex, keyPath.length)
keyPathArray
+2 -2
Ver Arquivo
@@ -216,12 +216,12 @@ class Cursor extends Model
# Public: Retrieves the scope descriptor for the cursor's current position.
#
# Returns an {Array} of {String}s.
# Returns a {ScopeDescriptor}
getScopeDescriptor: ->
@editor.scopeDescriptorForBufferPosition(@getBufferPosition())
getScopes: ->
Grim.deprecate 'Use Cursor::getScopeDescriptor() instead'
@getScopeDescriptor()
@getScopeDescriptor().getScopesArray()
# Public: Returns true if this cursor has no non-whitespace characters before
# its current position.
+33 -8
Ver Arquivo
@@ -650,11 +650,21 @@ class DisplayBuffer extends Model
left = 0
column = 0
for token in @tokenizedLineForScreenRow(targetRow).tokens
charWidths = @getScopedCharWidths(token.scopeDescriptor)
for char in token.value
charWidths = @getScopedCharWidths(token.scopes)
valueIndex = 0
while valueIndex < token.value.length
if token.hasPairedCharacter
char = token.value.substr(valueIndex, 2)
charLength = 2
valueIndex += 2
else
char = token.value[valueIndex]
charLength = 1
valueIndex++
return {top, left} if column is targetColumn
left += charWidths[char] ? defaultCharWidth unless char is '\0'
column++
column += charLength
{top, left}
screenPositionForPixelPosition: (pixelPosition) ->
@@ -662,18 +672,29 @@ class DisplayBuffer extends Model
targetLeft = pixelPosition.left
defaultCharWidth = @defaultCharWidth
row = Math.floor(targetTop / @getLineHeightInPixels())
targetLeft = Infinity if row > @getLastRow()
row = Math.min(row, @getLastRow())
row = Math.max(0, row)
left = 0
column = 0
for token in @tokenizedLineForScreenRow(row).tokens
charWidths = @getScopedCharWidths(token.scopeDescriptor)
for char in token.value
charWidths = @getScopedCharWidths(token.scopes)
valueIndex = 0
while valueIndex < token.value.length
if token.hasPairedCharacter
char = token.value.substr(valueIndex, 2)
charLength = 2
valueIndex += 2
else
char = token.value[valueIndex]
charLength = 1
valueIndex++
charWidth = charWidths[char] ? defaultCharWidth
break if targetLeft <= left + (charWidth / 2)
left += charWidth
column++
column += charLength
new Point(row, column)
@@ -714,6 +735,10 @@ class DisplayBuffer extends Model
#
# Returns a {Point}.
screenPositionForBufferPosition: (bufferPosition, options) ->
# 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)
for screenRow in [startScreenRow...endScreenRow]
@@ -756,7 +781,7 @@ class DisplayBuffer extends Model
#
# bufferPosition - A {Point} in the {TextBuffer}
#
# Returns an {Array} of {String}s.
# Returns a {ScopeDescriptor}.
scopeDescriptorForBufferPosition: (bufferPosition) ->
@tokenizedBuffer.scopeDescriptorForPosition(bufferPosition)
@@ -1051,7 +1076,7 @@ class DisplayBuffer extends Model
marker.notifyObservers(textChanged: false)
destroyed: ->
marker.unsubscribe() for marker in @getMarkers()
marker.unsubscribe() for id, marker of @markers
@tokenizedBuffer.destroy()
@unsubscribe()
+17 -7
Ver Arquivo
@@ -200,7 +200,7 @@ LinesComponent = React.createClass
firstTrailingWhitespacePosition = text.search(/\s*$/)
lineIsWhitespaceOnly = firstTrailingWhitespacePosition is 0
for token in tokens
innerHTML += @updateScopeStack(scopeStack, token.scopeDescriptor)
innerHTML += @updateScopeStack(scopeStack, token.scopes)
hasIndentGuide = not mini and showIndentGuide and (token.hasLeadingWhitespace() or (token.hasTrailingWhitespace() and lineIsWhitespaceOnly))
innerHTML += token.getValueAsHtml({hasIndentGuide})
@@ -308,10 +308,20 @@ LinesComponent = React.createClass
iterator = null
charIndex = 0
for {value, scopeDescriptor}, tokenIndex in tokenizedLine.tokens
charWidths = editor.getScopedCharWidths(scopeDescriptor)
for {value, scopes, hasPairedCharacter} in tokenizedLine.tokens
charWidths = editor.getScopedCharWidths(scopes)
valueIndex = 0
while valueIndex < value.length
if hasPairedCharacter
char = value.substr(valueIndex, 2)
charLength = 2
valueIndex += 2
else
char = value[valueIndex]
charLength = 1
valueIndex++
for char in value
continue if char is '\0'
unless charWidths[char]?
@@ -329,11 +339,11 @@ LinesComponent = React.createClass
i = charIndex - textNodeIndex
rangeForMeasurement.setStart(textNode, i)
rangeForMeasurement.setEnd(textNode, i + 1)
rangeForMeasurement.setEnd(textNode, i + charLength)
charWidth = rangeForMeasurement.getBoundingClientRect().width
editor.setScopedCharWidth(scopeDescriptor, char, charWidth)
editor.setScopedCharWidth(scopes, char, charWidth)
charIndex++
charIndex += charLength
@measuredLines.add(tokenizedLine)
+1 -1
Ver Arquivo
@@ -44,7 +44,7 @@ normalizeLabel = (label) ->
label.replace(/\&/g, '')
cloneMenuItem = (item) ->
item = _.pick(item, 'type', 'label', 'command', 'submenu', 'commandDetail')
item = _.pick(item, 'type', 'label', 'enabled', 'command', 'submenu', 'commandDetail')
if item.submenu?
item.submenu = item.submenu.map (submenuItem) -> cloneMenuItem(submenuItem)
item
+41 -6
Ver Arquivo
@@ -107,6 +107,40 @@ loadFolderCompatibility = (modulePath, rootPath, rootMetadata, moduleCache) ->
return
loadExtensions = (modulePath, rootPath, rootMetadata, moduleCache) ->
fs = require 'fs-plus'
extensions = ['.js', '.coffee', '.json', '.node']
nodeModulesPath = path.join(rootPath, 'node_modules')
onFile = (filePath) ->
filePath = path.relative(rootPath, filePath)
segments = filePath.split(path.sep)
return if 'test' in segments
return if 'tests' in segments
return if 'spec' in segments
return if 'specs' in segments
return if segments.length > 1 and not (segments[0] in ['exports', 'lib', 'node_modules', 'src', 'static', 'vendor'])
extension = path.extname(filePath)
if extension in extensions
moduleCache.extensions[extension] ?= []
moduleCache.extensions[extension].push(filePath)
onDirectory = (childPath) ->
# Don't include extensions from bundled packages
# These are generated and stored in the package's own metadata cache
if rootMetadata.name is 'atom'
parentPath = path.dirname(childPath)
if parentPath is nodeModulesPath
packageName = path.basename(childPath)
return false if rootMetadata.packageDependencies?.hasOwnProperty(packageName)
true
fs.traverseTreeSync(rootPath, onFile, onDirectory)
return
satisfies = (version, rawRange) ->
unless parsedRange = cache.ranges[rawRange]
parsedRange = new Range(rawRange)
@@ -158,7 +192,7 @@ resolveModulePath = (relativePath, parentModule) ->
return
registerBuiltins = (devMode) ->
if devMode
if devMode or not cache.resourcePath.startsWith("#{process.resourcesPath}#{path.sep}")
fs = require 'fs-plus'
atomCoffeePath = path.join(cache.resourcePath, 'exports', 'atom.coffee')
cache.builtins.atom = atomCoffeePath if fs.isFileSync(atomCoffeePath)
@@ -215,10 +249,12 @@ exports.create = (modulePath) ->
moduleCache =
version: 1
dependencies: []
extensions: {}
folders: []
loadDependencies(modulePath, modulePath, metadata, moduleCache)
loadFolderCompatibility(modulePath, modulePath, metadata, moduleCache)
loadExtensions(modulePath, modulePath, metadata, moduleCache)
metadata._atomModuleCache = moduleCache
fs.writeFileSync(metadataPath, JSON.stringify(metadata, null, 2))
@@ -265,11 +301,10 @@ exports.add = (directoryPath, metadata) ->
else
cache.folders[directoryPath] = entry.dependencies
if directoryPath is cache.resourcePath
for extension, paths of cacheToAdd.extensions
cache.extensions[extension] ?= new Set()
for filePath in paths
cache.extensions[extension].add("#{directoryPath}#{path.sep}#{filePath}")
for extension, paths of cacheToAdd.extensions
cache.extensions[extension] ?= new Set()
for filePath in paths
cache.extensions[extension].add("#{directoryPath}#{path.sep}#{filePath}")
return
+2 -2
Ver Arquivo
@@ -29,11 +29,11 @@ module.exports =
class PackageManager
EmitterMixin.includeInto(this)
constructor: ({configDirPath, devMode, safeMode, @resourcePath}) ->
constructor: ({configDirPath, @devMode, safeMode, @resourcePath}) ->
@emitter = new Emitter
@packageDirPaths = []
unless safeMode
if devMode
if @devMode
@packageDirPaths.push(path.join(configDirPath, "dev", "packages"))
@packageDirPaths.push(path.join(configDirPath, "packages"))
+50 -15
Ver Arquivo
@@ -13,6 +13,11 @@ $ = null # Defer require in case this is in the window-less browser process
ModuleCache = require './module-cache'
ScopedProperties = require './scoped-properties'
try
packagesCache = require('../package.json')?._atomPackages ? {}
catch error
packagesCache = {}
# Loads and activates a package's main module and resources such as
# stylesheets, keymaps, grammar, editor properties, and menus.
module.exports =
@@ -21,14 +26,25 @@ class Package
@stylesheetsDir: 'stylesheets'
@isBundledPackagePath: (packagePath) ->
if atom.packages.devMode
return false unless atom.packages.resourcePath.startsWith("#{process.resourcesPath}#{path.sep}")
@resourcePathWithTrailingSlash ?= "#{atom.packages.resourcePath}#{path.sep}"
packagePath?.startsWith(@resourcePathWithTrailingSlash)
@loadMetadata: (packagePath, ignoreErrors=false) ->
if metadataPath = CSON.resolve(path.join(packagePath, 'package'))
try
metadata = CSON.readFileSync(metadataPath)
catch error
throw error unless ignoreErrors
packageName = path.basename(packagePath)
if @isBundledPackagePath(packagePath)
metadata = packagesCache[packageName]?.metadata
unless metadata?
if metadataPath = CSON.resolve(path.join(packagePath, 'package'))
try
metadata = CSON.readFileSync(metadataPath)
catch error
throw error unless ignoreErrors
metadata ?= {}
metadata.name = path.basename(packagePath)
metadata.name = packageName
metadata
keymaps: null
@@ -47,6 +63,7 @@ class Package
constructor: (@path, @metadata) ->
@emitter = new Emitter
@metadata ?= Package.loadMetadata(@path)
@bundledPackage = Package.isBundledPackagePath(@path)
@name = @metadata?.name ? path.basename(@path)
ModuleCache.add(@path, @metadata)
@reset()
@@ -177,10 +194,16 @@ class Package
@scopedPropertiesActivated = true
loadKeymaps: ->
@keymaps = @getKeymapPaths().map (keymapPath) -> [keymapPath, CSON.readFileSync(keymapPath)]
if @bundledPackage and packagesCache[@name]?
@keymaps = (["#{atom.packages.resourcePath}#{path.sep}#{keymapPath}", keymapObject] for keymapPath, keymapObject of packagesCache[@name].keymaps)
else
@keymaps = @getKeymapPaths().map (keymapPath) -> [keymapPath, CSON.readFileSync(keymapPath)]
loadMenus: ->
@menus = @getMenuPaths().map (menuPath) -> [menuPath, CSON.readFileSync(menuPath)]
if @bundledPackage and packagesCache[@name]?
@menus = (["#{atom.packages.resourcePath}#{path.sep}#{menuPath}", menuObject] for menuPath, menuObject of packagesCache[@name].menus)
else
@menus = @getMenuPaths().map (menuPath) -> [menuPath, CSON.readFileSync(menuPath)]
getKeymapPaths: ->
keymapsDirPath = path.join(@path, 'keymaps')
@@ -314,19 +337,31 @@ class Package
requireMainModule: ->
return @mainModule if @mainModule?
return unless @isCompatible()
unless @isCompatible()
console.warn """
Failed to require the main module of '#{@name}' because it requires an incompatible native module.
Run `apm rebuild` in the package directory to resolve.
"""
return
mainModulePath = @getMainModulePath()
@mainModule = require(mainModulePath) if fs.isFileSync(mainModulePath)
getMainModulePath: ->
return @mainModulePath if @resolvedMainModulePath
@resolvedMainModulePath = true
mainModulePath =
if @metadata.main
path.join(@path, @metadata.main)
if @bundledPackage and packagesCache[@name]?
if packagesCache[@name].main
@mainModulePath = "#{atom.packages.resourcePath}#{path.sep}#{packagesCache[@name].main}"
else
path.join(@path, 'index')
@mainModulePath = fs.resolveExtension(mainModulePath, ["", _.keys(require.extensions)...])
@mainModulePath = null
else
mainModulePath =
if @metadata.main
path.join(@path, @metadata.main)
else
path.join(@path, 'index')
@mainModulePath = fs.resolveExtension(mainModulePath, ["", _.keys(require.extensions)...])
hasActivationCommands: ->
for selector, commands of @getActivationCommands()
@@ -340,7 +375,7 @@ class Package
do (selector, command) =>
# Add dummy command so it appears in menu.
# The real command will be registered on package activation
@activationCommandSubscriptions.add atom.commands.add selector, command, ->
@activationCommandSubscriptions.add atom.commands.listen selector, command, ->
@activationCommandSubscriptions.add atom.commands.onWillDispatch (event) =>
return unless event.type is command
currentTarget = event.target
+3 -2
Ver Arquivo
@@ -107,8 +107,9 @@ class PaneElement extends HTMLElement
hideItemView: (itemView) ->
inlineDisplayStyle = itemView.style.display
@inlineDisplayStyles.set(itemView, inlineDisplayStyle) if inlineDisplayStyle?
itemView.style.display = 'none'
unless inlineDisplayStyle is 'none'
@inlineDisplayStyles.set(itemView, inlineDisplayStyle) if inlineDisplayStyle?
itemView.style.display = 'none'
itemRemoved: ({item, index, destroyed}) ->
if viewToRemove = @model.getView(item)
+3 -2
Ver Arquivo
@@ -63,8 +63,9 @@ class Pane extends Model
getContainer: -> @container
setContainer: (container) ->
container.didAddPane({pane: this}) unless container is @container
@container = container
unless container is @container
@container = container
container.didAddPane({pane: this})
###
Section: Event Subscription
+30
Ver Arquivo
@@ -0,0 +1,30 @@
{CompositeDisposable} = require 'event-kit'
class PanelContainerElement extends HTMLElement
createdCallback: ->
@subscriptions = new CompositeDisposable
getModel: -> @model
setModel: (@model) ->
@subscriptions.add @model.onDidAddPanel(@panelAdded.bind(this))
@subscriptions.add @model.onDidRemovePanel(@panelRemoved.bind(this))
@subscriptions.add @model.onDidDestroy(@destroyed.bind(this))
@setAttribute('location', @model.getLocation())
panelAdded: ({panel, index}) ->
if index >= @childNodes.length
@appendChild(panel.getView())
else
referenceItem = @childNodes[index + 1]
@insertBefore(panel.getView(), referenceItem)
panelRemoved: ({panel, index}) ->
@removeChild(@childNodes[index])
destroyed: ->
@subscriptions.dispose()
@parentNode?.removeChild(this)
module.exports = PanelContainerElement = document.registerElement 'atom-panel-container', prototype: PanelContainerElement.prototype
+66
Ver Arquivo
@@ -0,0 +1,66 @@
{Emitter, CompositeDisposable} = require 'event-kit'
module.exports =
class PanelContainer
constructor: ({@viewRegistry, @location}) ->
@emitter = new Emitter
@subscriptions = new CompositeDisposable
@panels = []
destroy: ->
pane.destroy() for pane in @getPanels()
@subscriptions.dispose()
@emitter.emit 'did-destroy', this
@emitter.dispose()
###
Section: Event Subscription
###
onDidAddPanel: (callback) ->
@emitter.on 'did-add-panel', callback
onDidRemovePanel: (callback) ->
@emitter.on 'did-remove-panel', callback
onDidDestroy: (callback) ->
@emitter.on 'did-destroy', callback
###
Section: Panels
###
getView: -> @viewRegistry.getView(this)
getLocation: -> @location
getPanels: -> @panels
addPanel: (panel) ->
@subscriptions.add panel.onDidDestroy(@panelDestoryed.bind(this))
index = @getPanelIndex(panel)
if index is @panels.length
@panels.push(panel)
else
@panels.splice(index, 0, panel)
@emitter.emit 'did-add-panel', {panel, index}
panel
panelDestoryed: (panel) ->
index = @panels.indexOf(panel)
if index > -1
@panels.splice(index, 1)
@emitter.emit 'did-remove-panel', {panel, index}
getPanelIndex: (panel) ->
priority = panel.getPriority()
if @location in ['bottom', 'right']
for p, i in @panels by -1
return i + 1 if priority < p.getPriority()
0
else
for p, i in @panels
return i if priority < p.getPriority()
@panels.length
+31
Ver Arquivo
@@ -0,0 +1,31 @@
{CompositeDisposable} = require 'event-kit'
{callAttachHooks} = require './space-pen-extensions'
class PanelElement extends HTMLElement
createdCallback: ->
@subscriptions = new CompositeDisposable
getModel: -> @model
setModel: (@model) ->
view = @model.getItemView()
@appendChild(view)
callAttachHooks(view) # for backward compatibility with SpacePen views
@subscriptions.add @model.onDidChangeVisible(@visibleChanged.bind(this))
@subscriptions.add @model.onDidDestroy(@destroyed.bind(this))
attachedCallback: ->
@visibleChanged(@model.isVisible())
visibleChanged: (visible) ->
if visible
@style.display = null
else
@style.display = 'none'
destroyed: ->
@subscriptions.dispose()
@parentNode?.removeChild(this)
module.exports = PanelElement = document.registerElement 'atom-panel', prototype: PanelElement.prototype
+78
Ver Arquivo
@@ -0,0 +1,78 @@
{Emitter} = require 'event-kit'
# Extended: A container representing a panel on the edges of the editor window.
# You should not create a `Panel` directly, instead use {Workspace::addTopPanel}
# and friends to add panels.
#
# Examples: [tree-view](https://github.com/atom/tree-view),
# [status-bar](https://github.com/atom/status-bar),
# and [find-and-replace](https://github.com/atom/find-and-replace) all use
# panels.
module.exports =
class Panel
###
Section: Construction and Destruction
###
constructor: ({@viewRegistry, @item, @visible, @priority}) ->
@emitter = new Emitter
@visible ?= true
@priority ?= 100
# Public: Destroy and remove this panel from the UI.
destroy: ->
@emitter.emit 'did-destroy', this
###
Section: Event Subscription
###
# Public: Invoke the given callback when the pane hidden or shown.
#
# * `callback` {Function} to be called when the pane is destroyed.
# * `visible` {Boolean} true when the panel has been shown
#
# Returns a {Disposable} on which `.dispose()` can be called to unsubscribe.
onDidChangeVisible: (callback) ->
@emitter.on 'did-change-visible', callback
# Public: Invoke the given callback when the pane is destroyed.
#
# * `callback` {Function} to be called when the pane is destroyed.
# * `panel` {Panel} this panel
#
# Returns a {Disposable} on which `.dispose()` can be called to unsubscribe.
onDidDestroy: (callback) ->
@emitter.on 'did-destroy', callback
###
Section: Panel Details
###
# Public: Gets this panel model's view DOM node.
#
# Returns an `<atom-panel>` {Element}
getView: -> @viewRegistry.getView(this)
# Public: Gets your panel contents view.
#
# Returns an {Element} or jQuery element, depeneding on how you created the panel.
getItemView: -> @viewRegistry.getView(@item)
# Public: Returns a {Number} indicating this panel's priority.
getPriority: -> @priority
# Public: Returns a {Boolean} true when the panel is visible.
isVisible: -> @visible
# Public: Hide this panel
hide: ->
wasVisible = @visible
@visible = false
@emitter.emit 'did-change-visible', @visible if wasVisible
# Public: Show this panel
show: ->
wasVisible = @visible
@visible = true
@emitter.emit 'did-change-visible', @visible unless wasVisible
+46
Ver Arquivo
@@ -0,0 +1,46 @@
# Extended: Wraps an {Array} of `String`s. The Array describes a path from the
# root of the syntax tree to a token including _all_ scope names for the entire
# path.
#
# Methods that take a `ScopeDescriptor` will also accept an {Array} of {Strings}
# scope names e.g. `['.source.js']`.
#
# You can use `ScopeDescriptor`s to get language-specific config settings via
# {Config::get}.
#
# You should not need to create a `ScopeDescriptor` directly.
#
# * {Editor::getRootScopeDescriptor} to get the language's descriptor.
# * {Editor::scopeDescriptorForBufferPosition} to get the descriptor at a
# specific position in the buffer.
# * {Cursor::getScopeDescriptor} to get a cursor's descriptor based on position.
#
# See the [scopes and scope descriptor guide](https://atom.io/docs/v0.138.0/advanced/scopes-and-scope-descriptors)
# for more information.
module.exports =
class ScopeDescriptor
@fromObject: (scopes) ->
if scopes instanceof ScopeDescriptor
scopes
else
new ScopeDescriptor({scopes})
###
Section: Construction and Destruction
###
# Public: Create a {ScopeDescriptor} object.
#
# * `object` {Object}
# * `scopes` {Array} of {String}s
constructor: ({@scopes}) ->
# Public: Returns an {Array} of {String}s
getScopesArray: -> @scopes
getScopeChain: ->
@scopes
.map (scope) ->
scope = ".#{scope}" unless scope[0] is '.'
scope
.join(' ')
+34 -27
Ver Arquivo
@@ -15,46 +15,53 @@ SpacePen.callRemoveHooks = (element) ->
view.unsubscribe() for view in SpacePen.viewsForElement(element)
SpacePenCallRemoveHooks(element)
NativeEventNames = new Set
NativeEventNames.add(nativeEvent) for nativeEvent in ["blur", "focus", "focusin",
"focusout", "load", "resize", "scroll", "unload", "click", "dblclick", "mousedown",
"mouseup", "mousemove", "mouseover", "mouseout", "mouseenter", "mouseleave", "change",
"select", "submit", "keydown", "keypress", "keyup", "error", "contextmenu", "textInput",
"textinput"]
JQueryTrigger = jQuery.fn.trigger
jQuery.fn.trigger = (eventName, data) ->
if NativeEventNames.has(eventName) or typeof eventName is 'object'
JQueryTrigger.call(this, eventName, data)
jQuery.fn.trigger = (event, data) ->
if typeof event is 'object'
{type, target, originalEvent} = event
if originalEvent?
originalEvent.type ?= type
event = originalEvent
else
type = event
specialTrigger = jQuery.event.special[event]?.trigger
# Don't deal with namespaces
return JQueryTrigger.apply(this, arguments) unless type.indexOf('.') is -1
if target?
atom.commands.dispatch(target, event, data)
else
for element in this
atom.commands.dispatch(element, eventName, data)
this
continue if specialTrigger?.apply(element) is false
atom.commands.dispatch(element, event, data)
this
# Allow command registry integration with focusin and focusout events
# Otherwise jQuery registers these event handlers in a special way for bubbling
# compatibility
delete jQuery.event.special.focusin
delete jQuery.event.special.focusout
HandlersByOriginalHandler = new WeakMap
CommandDisposablesByElement = new WeakMap
AddEventListener = (element, type, listener) ->
if NativeEventNames.has(type)
element.addEventListener(type, listener)
else
disposable = atom.commands.add(element, type, listener)
disposable = atom.commands.listen(element, type, listener)
unless disposablesByType = CommandDisposablesByElement.get(element)
disposablesByType = {}
CommandDisposablesByElement.set(element, disposablesByType)
unless disposablesByType = CommandDisposablesByElement.get(element)
disposablesByType = {}
CommandDisposablesByElement.set(element, disposablesByType)
unless disposablesByListener = disposablesByType[type]
disposablesByListener = new WeakMap
disposablesByType[type] = disposablesByListener
unless disposablesByListener = disposablesByType[type]
disposablesByListener = new WeakMap
disposablesByType[type] = disposablesByListener
disposablesByListener.set(listener, disposable)
disposablesByListener.set(listener, disposable)
RemoveEventListener = (element, type, listener) ->
if NativeEventNames.has(type)
element.removeEventListener(type, listener)
else
CommandDisposablesByElement.get(element)?[type]?.get(listener)?.dispose()
CommandDisposablesByElement.get(element)?[type]?.get(listener)?.dispose()
JQueryEventAdd = jQuery.event.add
jQuery.event.add = (elem, types, originalHandler, data, selector) ->
+86
Ver Arquivo
@@ -0,0 +1,86 @@
{Emitter, Disposable} = require 'event-kit'
module.exports =
class StyleManager
constructor: ->
@emitter = new Emitter
@styleElements = []
@styleElementsBySourcePath = {}
observeStyleElements: (callback) ->
callback(styleElement) for styleElement in @getStyleElements()
@onDidAddStyleElement(callback)
onDidAddStyleElement: (callback) ->
@emitter.on 'did-add-style-element', callback
onDidRemoveStyleElement: (callback) ->
@emitter.on 'did-remove-style-element', callback
onDidUpdateStyleElement: (callback) ->
@emitter.on 'did-update-style-element', callback
getStyleElements: ->
@styleElements.slice()
addStyleSheet: (source, params) ->
sourcePath = params?.sourcePath
group = params?.group
if sourcePath? and styleElement = @styleElementsBySourcePath[sourcePath]
updated = true
else
styleElement = document.createElement('style')
if sourcePath?
styleElement.sourcePath = sourcePath
styleElement.setAttribute('source-path', sourcePath)
if context?
styleElement.context = context
styleElement.setAttribute('context', context)
if group?
styleElement.group = group
styleElement.setAttribute('group', group)
styleElement.textContent = source
if updated
@emitter.emit 'did-update-style-element', styleElement
else
@addStyleElement(styleElement)
new Disposable => @removeStyleElement(styleElement)
addStyleElement: (styleElement) ->
{sourcePath, group} = styleElement
if group?
for existingElement, index in @styleElements
if existingElement.group is group
insertIndex = index + 1
else
break if insertIndex?
insertIndex ?= @styleElements.length
@styleElements.splice(insertIndex, 0, styleElement)
@styleElementsBySourcePath[sourcePath] ?= styleElement if sourcePath?
@emitter.emit 'did-add-style-element', styleElement
removeStyleElement: (styleElement) ->
index = @styleElements.indexOf(styleElement)
unless index is -1
@styleElements.splice(index, 1)
delete @styleElementsBySourcePath[styleElement.sourcePath] if styleElement.sourcePath?
@emitter.emit 'did-remove-style-element', styleElement
getSnapshot: ->
@styleElements.slice()
restoreSnapshot: (styleElementsToRestore) ->
for styleElement in @getStyleElements()
@removeStyleElement(styleElement) unless styleElement in styleElementsToRestore
existingStyleElements = @getStyleElements()
for styleElement in styleElementsToRestore
@addStyleElement(styleElement) unless styleElement in existingStyleElements
+50
Ver Arquivo
@@ -0,0 +1,50 @@
{Emitter, CompositeDisposable} = require 'event-kit'
class StylesElement extends HTMLElement
createdCallback: ->
@emitter = new Emitter
onDidAddStyleElement: (callback) ->
@emitter.on 'did-add-style-element', callback
onDidRemoveStyleElement: (callback) ->
@emitter.on 'did-remove-style-element', callback
onDidUpdateStyleElement: (callback) ->
@emitter.on 'did-update-style-element', callback
attachedCallback: ->
@subscriptions = new CompositeDisposable
@styleElementClonesByOriginalElement = new WeakMap
@subscriptions.add atom.styles.observeStyleElements(@styleElementAdded.bind(this))
@subscriptions.add atom.styles.onDidRemoveStyleElement(@styleElementRemoved.bind(this))
@subscriptions.add atom.styles.onDidUpdateStyleElement(@styleElementUpdated.bind(this))
styleElementAdded: (styleElement) ->
styleElementClone = styleElement.cloneNode(true)
@styleElementClonesByOriginalElement.set(styleElement, styleElementClone)
group = styleElement.getAttribute('group')
if group?
for child in @children
if child.getAttribute('group') is group and child.nextSibling?.getAttribute('group') isnt group
insertBefore = child.nextSibling
break
@insertBefore(styleElementClone, insertBefore)
@emitter.emit 'did-add-style-element', styleElementClone
styleElementRemoved: (styleElement) ->
styleElementClone = @styleElementClonesByOriginalElement.get(styleElement)
styleElementClone.remove()
@emitter.emit 'did-remove-style-element', styleElementClone
styleElementUpdated: (styleElement) ->
styleElementClone = @styleElementClonesByOriginalElement.get(styleElement)
styleElementClone.textContent = styleElement.textContent
@emitter.emit 'did-update-style-element', styleElementClone
detachedCallback: ->
@subscriptions.dispose()
module.exports = StylesElement = document.registerElement 'atom-styles', prototype: StylesElement.prototype
+1 -1
Ver Arquivo
@@ -32,7 +32,7 @@ class Syntax extends GrammarRegistry
serialize: ->
{deserializer: @constructor.name, @grammarOverridesByPath}
createToken: (value, scopeDescriptor) -> new Token({value, scopeDescriptor})
createToken: (value, scopes) -> new Token({value, scopes})
# Deprecated: Used by settings-view to display snippets for packages
@::accessor 'propertyStore', ->
+10 -5
Ver Arquivo
@@ -55,6 +55,8 @@ TextEditorComponent = React.createClass
hasSelection = editor.getLastSelection()? and !editor.getLastSelection().isEmpty()
style = {}
@performedInitialMeasurement = false if editor.isDestroyed()
if @performedInitialMeasurement
renderedRowRange = @getRenderedRowRange()
[renderedStartRow, renderedEndRow] = renderedRowRange
@@ -227,10 +229,10 @@ TextEditorComponent = React.createClass
@props.editor.setVisible(true)
@performedInitialMeasurement = true
@updatesPaused = false
@forceUpdate() if @updateRequestedWhilePaused
@forceUpdate() if @updateRequestedWhilePaused and @canUpdate()
requestUpdate: ->
return unless @isMounted()
return unless @canUpdate()
if @updatesPaused
@updateRequestedWhilePaused = true
@@ -242,7 +244,10 @@ TextEditorComponent = React.createClass
@updateRequested = true
requestAnimationFrame =>
@updateRequested = false
@forceUpdate() if @isMounted()
@forceUpdate() if @canUpdate()
canUpdate: ->
@isMounted() and @props.editor.isAlive()
requestAnimationFrame: (fn) ->
@updatesPaused = true
@@ -250,7 +255,7 @@ TextEditorComponent = React.createClass
requestAnimationFrame =>
fn()
@updatesPaused = false
if @updateRequestedWhilePaused and @isMounted()
if @updateRequestedWhilePaused and @canUpdate()
@updateRequestedWhilePaused = false
@forceUpdate()
@@ -773,7 +778,7 @@ TextEditorComponent = React.createClass
if position is 'absolute' or height
if @autoHeight
@autoHeight = false
@forceUpdate() unless @updatesPaused
@forceUpdate() if not @updatesPaused and @canUpdate()
clientHeight = scrollViewNode.clientHeight
editor.setHeight(clientHeight) if clientHeight > 0
+7 -3
Ver Arquivo
@@ -1,4 +1,4 @@
{View, $} = require 'space-pen'
{View, $, callRemoveHooks} = require 'space-pen'
React = require 'react-atom-fork'
{defaults} = require 'underscore-plus'
TextBuffer = require 'text-buffer'
@@ -37,10 +37,13 @@ class TextEditorElement extends HTMLElement
setModel: (model) ->
throw new Error("Model already assigned on TextEditorElement") if @model?
return if model.isDestroyed()
@model = model
@mountComponent()
@addGrammarScopeAttribute()
@model.onDidChangeGrammar => @addGrammarScopeAttribute()
@model.onDidDestroy => @unmountComponent()
@__spacePenView.setModel(@model)
@model
@@ -68,6 +71,7 @@ class TextEditorElement extends HTMLElement
unmountComponent: ->
return unless @component?.isMounted()
callRemoveHooks(this)
React.unmountComponentAtNode(this)
@component = null
@@ -99,7 +103,7 @@ stopCommandEventPropagation = (commandListeners) ->
commandListener.call(this, event)
newCommandListeners
atom.commands.add 'atom-text-editor', stopCommandEventPropagation(
atom.commands.listen 'atom-text-editor', stopCommandEventPropagation(
'core:move-left': -> @getModel().moveLeft()
'core:move-right': -> @getModel().moveRight()
'core:select-left': -> @getModel().selectLeft()
@@ -149,7 +153,7 @@ atom.commands.add 'atom-text-editor', stopCommandEventPropagation(
'editor:lower-case': -> @getModel().lowerCase()
)
atom.commands.add 'atom-text-editor:not(.mini)', stopCommandEventPropagation(
atom.commands.listen 'atom-text-editor:not(.mini)', stopCommandEventPropagation(
'core:move-up': -> @getModel().moveUp()
'core:move-down': -> @getModel().moveDown()
'core:move-to-top': -> @getModel().moveToTop()
+18 -15
Ver Arquivo
@@ -487,7 +487,7 @@ class TextEditor extends Model
when 'decoration-updated'
deprecate("Use Decoration::onDidChangeProperties instead. You will get the decoration back from `TextEditor::decorateMarker()`")
when 'decoration-changed'
deprecate("Use Marker::onDidChange instead. eg. `editor::decorateMarker(...).getMarker().onDidChange()`")
deprecate("Use Marker::onDidChange instead. e.g. `editor::decorateMarker(...).getMarker().onDidChange()`")
when 'screen-lines-changed'
deprecate("Use TextEditor::onDidChange instead")
@@ -752,7 +752,7 @@ class TextEditor extends Model
@insertText('\n')
# Essential: For each selection, if the selection is empty, delete the character
# preceding the cursor. Otherwise delete the selected text.
# following the cursor. Otherwise delete the selected text.
delete: ->
@mutateSelectedText (selection) -> selection.delete()
@@ -1216,7 +1216,7 @@ class TextEditor extends Model
# ## Arguments
#
# * `marker` A {Marker} you want this decoration to follow.
# * `decorationParams` An {Object} representing the decoration eg. `{type: 'gutter', class: 'linter-error'}`
# * `decorationParams` An {Object} representing the decoration e.g. `{type: 'gutter', class: 'linter-error'}`
# * `type` There are a few supported decoration types: `gutter`, `line`, and `highlight`
# * `class` This CSS class will be applied to the decorated line number,
# line, or highlight.
@@ -2370,8 +2370,8 @@ class TextEditor extends Model
Section: Managing Syntax Scopes
###
# Essential: Returns the scope descriptor that includes the language. eg.
# `['.source.ruby']`, or `['.source.coffee']`. You can use this with
# Essential: Returns a {ScopeDescriptor} that includes this editor's language.
# e.g. `['.source.ruby']`, or `['.source.coffee']`. You can use this with
# {Config::get} to get language specific config values.
getRootScopeDescriptor: ->
@displayBuffer.getRootScopeDescriptor()
@@ -2385,11 +2385,12 @@ class TextEditor extends Model
#
# * `bufferPosition` A {Point} or {Array} of [row, column].
#
# Returns an {Array} of {String}s.
scopeDescriptorForBufferPosition: (bufferPosition) -> @displayBuffer.scopeDescriptorForBufferPosition(bufferPosition)
# Returns a {ScopeDescriptor}.
scopeDescriptorForBufferPosition: (bufferPosition) ->
@displayBuffer.scopeDescriptorForBufferPosition(bufferPosition)
scopesForBufferPosition: (bufferPosition) ->
deprecate 'Use ::scopeDescriptorForBufferPosition instead'
@scopeDescriptorForBufferPosition(bufferPosition)
deprecate 'Use ::scopeDescriptorForBufferPosition instead. The return value has changed! It now returns a `ScopeDescriptor`'
@scopeDescriptorForBufferPosition(bufferPosition).getScopesArray()
# Extended: Get the range in buffer coordinates of all tokens surrounding the
# cursor that match the given scope selector.
@@ -2397,14 +2398,16 @@ class TextEditor extends Model
# For example, if you wanted to find the string surrounding the cursor, you
# could call `editor.bufferRangeForScopeAtCursor(".string.quoted")`.
#
# * `scopeSelector` {String} selector. e.g. `'.source.ruby'`
#
# Returns a {Range}.
bufferRangeForScopeAtCursor: (selector) ->
@displayBuffer.bufferRangeForScopeAtPosition(selector, @getCursorBufferPosition())
bufferRangeForScopeAtCursor: (scopeSelector) ->
@displayBuffer.bufferRangeForScopeAtPosition(scopeSelector, @getCursorBufferPosition())
# Extended: Determine if the given row is entirely a comment
isBufferRowCommented: (bufferRow) ->
if match = @lineTextForBufferRow(bufferRow).match(/\S/)
scopeDescriptor = @tokenForBufferPosition([bufferRow, match.index]).scopeDescriptor
scopeDescriptor = @tokenForBufferPosition([bufferRow, match.index]).scopes
@commentScopeSelector ?= new TextMateScopeSelector('comment.*')
@commentScopeSelector.matches(scopeDescriptor)
@@ -2415,10 +2418,10 @@ class TextEditor extends Model
tokenForBufferPosition: (bufferPosition) -> @displayBuffer.tokenForBufferPosition(bufferPosition)
scopesAtCursor: ->
deprecate 'Use editor.getLastCursor().scopesAtCursor() instead'
@getLastCursor().getScopeDescriptor()
deprecate 'Use editor.getLastCursor().getScopeDescriptor() instead'
@getLastCursor().getScopeDescriptor().getScopesArray()
getCursorScopes: ->
deprecate 'Use editor.getLastCursor().scopesAtCursor() instead'
deprecate 'Use editor.getLastCursor().getScopeDescriptor() instead'
@scopesAtCursor()
###
+44 -21
Ver Arquivo
@@ -1,41 +1,64 @@
isHighSurrogate = (string, index) ->
0xD800 <= string.charCodeAt(index) <= 0xDBFF
isHighSurrogate = (charCode) ->
0xD800 <= charCode <= 0xDBFF
isLowSurrogate = (string, index) ->
0xDC00 <= string.charCodeAt(index) <= 0xDFFF
isLowSurrogate = (charCode) ->
0xDC00 <= charCode <= 0xDFFF
isVariationSelector = (string, index) ->
0xFE00 <= string.charCodeAt(index) <= 0xFE0F
isVariationSelector = (charCode) ->
0xFE00 <= charCode <= 0xFE0F
# Is the character at the given index the start of a high/low surrogate pair?
isCombiningCharacter = (charCode) ->
0x0300 <= charCode <= 0x036F or
0x1AB0 <= charCode <= 0x1AFF or
0x1DC0 <= charCode <= 0x1DFF or
0x20D0 <= charCode <= 0x20FF or
0xFE20 <= charCode <= 0xFE2F
# Are the given character codes a high/low surrogate pair?
#
# * `string` The {String} to check for a surrogate pair.
# * `index` The {Number} index to look for a surrogate pair at.
# * `charCodeA` The first character code {Number}.
# * `charCode2` The second character code {Number}.
#
# Return a {Boolean}.
isSurrogatePair = (string, index=0) ->
isHighSurrogate(string, index) and isLowSurrogate(string, index + 1)
isSurrogatePair = (charCodeA, charCodeB) ->
isHighSurrogate(charCodeA) and isLowSurrogate(charCodeB)
# Is the character at the given index the start of a variation sequence?
# Are the given character codes a variation sequence?
#
# * `string` The {String} to check for a variation sequence.
# * `index` The {Number} index to look for a variation sequence at.
# * `charCodeA` The first character code {Number}.
# * `charCode2` The second character code {Number}.
#
# Return a {Boolean}.
isVariationSequence = (string, index=0) ->
not isVariationSelector(string, index) and isVariationSelector(string, index + 1)
isVariationSequence = (charCodeA, charCodeB) ->
not isVariationSelector(charCodeA) and isVariationSelector(charCodeB)
# Are the given character codes a combined character pair?
#
# * `charCodeA` The first character code {Number}.
# * `charCode2` The second character code {Number}.
#
# Return a {Boolean}.
isCombinedCharacter = (charCodeA, charCodeB) ->
not isCombiningCharacter(charCodeA) and isCombiningCharacter(charCodeB)
# Is the character at the given index the start of high/low surrogate pair
# or a variation sequence?
# a variation sequence, or a combined character?
#
# * `string` The {String} to check for a surrogate pair or variation sequence.
# * `index` The {Number} index to look for a surrogate pair at.
# * `string` The {String} to check for a surrogate pair, variation sequence,
# or combined character.
# * `index` The {Number} index to look for a surrogate pair, variation
# sequence, or combined character.
#
# Return a {Boolean}.
isPairedCharacter = (string, index=0) ->
isSurrogatePair(string, index) or isVariationSequence(string, index)
charCodeA = string.charCodeAt(index)
charCodeB = string.charCodeAt(index + 1)
isSurrogatePair(charCodeA, charCodeB) or
isVariationSequence(charCodeA, charCodeB) or
isCombinedCharacter(charCodeA, charCodeB)
# Does the given string contain at least surrogate pair or variation sequence?
# Does the given string contain at least surrogate pair, variation sequence,
# or combined character?
#
# * `string` The {String} to check for the presence of paired characters.
#
+34 -50
Ver Arquivo
@@ -19,9 +19,39 @@ class ThemeManager
constructor: ({@packageManager, @resourcePath, @configDirPath, @safeMode}) ->
@emitter = new Emitter
@styleSheetDisposablesBySourcePath = {}
@lessCache = null
@initialLoadComplete = false
@packageManager.registerPackageActivator(this, ['theme'])
@sheetsByStyleElement = new WeakMap
stylesElement = document.head.querySelector('atom-styles')
stylesElement.onDidAddStyleElement @styleElementAdded.bind(this)
stylesElement.onDidRemoveStyleElement @styleElementRemoved.bind(this)
stylesElement.onDidUpdateStyleElement @styleElementUpdated.bind(this)
styleElementAdded: (styleElement) ->
{sheet} = styleElement
@sheetsByStyleElement.set(styleElement, sheet)
@emit 'stylesheet-added', sheet
@emitter.emit 'did-add-stylesheet', sheet
@emit 'stylesheets-changed'
@emitter.emit 'did-change-stylesheets'
styleElementRemoved: (styleElement) ->
sheet = @sheetsByStyleElement.get(styleElement)
@emit 'stylesheet-removed', sheet
@emitter.emit 'did-remove-stylesheet', sheet
@emit 'stylesheets-changed'
@emitter.emit 'did-change-stylesheets'
styleElementUpdated: ({sheet}) ->
@emit 'stylesheet-removed', sheet
@emitter.emit 'did-remove-stylesheet', sheet
@emit 'stylesheet-added', sheet
@emitter.emit 'did-add-stylesheet', sheet
@emit 'stylesheets-changed'
@emitter.emit 'did-change-stylesheets'
###
Section: Event Subscription
@@ -188,7 +218,6 @@ class ThemeManager
if fullPath = @resolveStylesheet(stylesheetPath)
content = @loadStylesheet(fullPath)
@applyStylesheet(fullPath, content, type)
new Disposable => @removeStylesheet(fullPath)
else
throw new Error("Could not find a file at path '#{stylesheetPath}'")
@@ -204,8 +233,7 @@ class ThemeManager
@userStylesheetPath = userStylesheetPath
@userStylesheetFile = new File(userStylesheetPath)
@userStylesheetFile.on 'contents-changed moved removed', =>
@loadUserStylesheet()
@userStylesheetFile.on 'contents-changed moved removed', => @loadUserStylesheet()
userStylesheetContents = @loadStylesheet(userStylesheetPath, true)
@applyStylesheet(userStylesheetPath, userStylesheetContents, 'userTheme')
@@ -219,7 +247,7 @@ class ThemeManager
@requireStylesheet(nativeStylesheetPath)
stylesheetElementForId: (id) ->
document.head.querySelector("""style[id="#{id}"]""")
document.head.querySelector("atom-styles style[source-path=\"#{id}\"]")
resolveStylesheet: (stylesheetPath) ->
if path.extname(stylesheetPath).length > 0
@@ -256,40 +284,10 @@ class ThemeManager
"""
removeStylesheet: (stylesheetPath) ->
fullPath = @resolveStylesheet(stylesheetPath) ? stylesheetPath
element = @stylesheetElementForId(@stringToId(fullPath))
if element?
{sheet} = element
element.remove()
@emit 'stylesheet-removed', sheet
@emitter.emit 'did-remove-stylesheet', sheet
@emit 'stylesheets-changed'
@emitter.emit 'did-change-stylesheets'
@styleSheetDisposablesBySourcePath[stylesheetPath]?.dispose()
applyStylesheet: (path, text, type='bundled') ->
styleId = @stringToId(path)
styleElement = @stylesheetElementForId(styleId)
if styleElement?
@emit 'stylesheet-removed', styleElement.sheet
@emitter.emit 'did-remove-stylesheet', styleElement.sheet
styleElement.textContent = text
else
styleElement = document.createElement('style')
styleElement.setAttribute('class', type)
styleElement.setAttribute('id', styleId)
styleElement.textContent = text
elementToInsertBefore = _.last(document.head.querySelectorAll("style.#{type}"))?.nextElementSibling
if elementToInsertBefore?
document.head.insertBefore(styleElement, elementToInsertBefore)
else
document.head.appendChild(styleElement)
@emit 'stylesheet-added', styleElement.sheet
@emitter.emit 'did-add-stylesheet', styleElement.sheet
@emit 'stylesheets-changed'
@emitter.emit 'did-change-stylesheets'
@styleSheetDisposablesBySourcePath[path] = atom.styles.addStyleSheet(text, sourcePath: path, group: type)
###
Section: Private
@@ -358,17 +356,3 @@ class ThemeManager
themePaths.push(path.join(themePath, Package.stylesheetsDir))
themePaths.filter (themePath) -> fs.isDirectorySync(themePath)
updateGlobalEditorStyle: (property, value) ->
unless styleNode = @stylesheetElementForId('global-editor-styles')
@applyStylesheet('global-editor-styles', 'atom-text-editor {}')
styleNode = @stylesheetElementForId('global-editor-styles')
{sheet} = styleNode
editorRule = sheet.cssRules[0]
editorRule.style[property] = value
@emit 'stylesheet-updated', sheet
@emitter.emit 'did-update-stylesheet', sheet
@emit 'stylesheets-changed'
@emitter.emit 'did-change-stylesheets'
+14 -20
Ver Arquivo
@@ -14,35 +14,28 @@ module.exports =
class Token
value: null
hasPairedCharacter: false
scopeDescriptor: null
scopes: null
isAtomic: null
isHardTab: null
firstNonWhitespaceIndex: null
firstTrailingWhitespaceIndex: null
hasInvisibleCharacters: false
Object.defineProperty @::, 'scopes', get: ->
deprecate 'Use ::scopeDescriptor instead'
@scopeDescriptor
constructor: ({@value, @scopeDescriptor, @isAtomic, @bufferDelta, @isHardTab}) ->
constructor: ({@value, @scopes, @isAtomic, @bufferDelta, @isHardTab, @hasPairedCharacter}) ->
@screenDelta = @value.length
@bufferDelta ?= @screenDelta
@hasPairedCharacter = textUtils.hasPairedCharacter(@value)
@hasPairedCharacter ?= textUtils.hasPairedCharacter(@value)
isEqual: (other) ->
# TODO: scopes is deprecated. This is here for the sake of lang package tests
scopeDescriptor = other.scopeDescriptor ? other.scopes
deprecate 'Test the Token for `scopeDescriptor` rather than `scopes`' if other.scopes?
@value == other.value and _.isEqual(@scopeDescriptor, scopeDescriptor) and !!@isAtomic == !!other.isAtomic
@value == other.value and _.isEqual(@scopes, other.scopes) and !!@isAtomic == !!other.isAtomic
isBracket: ->
/^meta\.brace\b/.test(_.last(@scopeDescriptor))
/^meta\.brace\b/.test(_.last(@scopes))
splitAt: (splitIndex) ->
leftToken = new Token(value: @value.substring(0, splitIndex), scopeDescriptor: @scopeDescriptor)
rightToken = new Token(value: @value.substring(splitIndex), scopeDescriptor: @scopeDescriptor)
leftToken = new Token(value: @value.substring(0, splitIndex), scopes: @scopes)
rightToken = new Token(value: @value.substring(splitIndex), scopes: @scopes)
if @firstNonWhitespaceIndex?
leftToken.firstNonWhitespaceIndex = Math.min(splitIndex, @firstNonWhitespaceIndex)
@@ -101,7 +94,7 @@ class Token
else
breakOutLeadingSoftTabs = false
value = match[0]
token = new Token({value, @scopeDescriptor})
token = new Token({value, @scopes})
column += token.value.length
outputTokens.push(token)
@@ -115,7 +108,7 @@ class Token
while index < @value.length
if textUtils.isPairedCharacter(@value, index)
if nonPairStart isnt index
outputTokens.push(new Token({value: @value[nonPairStart...index], @scopeDescriptor}))
outputTokens.push(new Token({value: @value[nonPairStart...index], @scopes}))
outputTokens.push(@buildPairedCharacterToken(@value, index))
index += 2
nonPairStart = index
@@ -123,15 +116,16 @@ class Token
index++
if nonPairStart isnt index
outputTokens.push(new Token({value: @value[nonPairStart...index], @scopeDescriptor}))
outputTokens.push(new Token({value: @value[nonPairStart...index], @scopes}))
outputTokens
buildPairedCharacterToken: (value, index) ->
new Token(
value: value[index..index + 1]
scopeDescriptor: @scopeDescriptor
scopes: @scopes
isAtomic: true
hasPairedCharacter: true
)
buildHardTabToken: (tabLength, column) ->
@@ -144,7 +138,7 @@ class Token
tabStop = tabLength - (column % tabLength)
new Token(
value: _.multiplyString(" ", tabStop)
scopeDescriptor: @scopeDescriptor
scopes: @scopes
bufferDelta: if isHardTab then 1 else tabStop
isAtomic: true
isHardTab: isHardTab
@@ -155,7 +149,7 @@ class Token
matchesScopeSelector: (selector) ->
targetClasses = selector.replace(StartDotRegex, '').split('.')
_.any @scopeDescriptor, (scope) ->
_.any @scopes, (scope) ->
scopeClasses = scope.split('.')
_.isSubset(targetClasses, scopeClasses)
+6 -5
Ver Arquivo
@@ -6,6 +6,7 @@ EmitterMixin = require('emissary').Emitter
Serializable = require 'serializable'
TokenizedLine = require './tokenized-line'
Token = require './token'
ScopeDescriptor = require './scope-descriptor'
Grim = require 'grim'
module.exports =
@@ -28,7 +29,7 @@ class TokenizedBuffer extends Model
@subscribe atom.syntax.onDidAddGrammar(@grammarAddedOrUpdated)
@subscribe atom.syntax.onDidUpdateGrammar(@grammarAddedOrUpdated)
@subscribe @buffer.onDidChange (e) => @handleBufferChange(e)
@subscribe @buffer.preemptDidChange (e) => @handleBufferChange(e)
@subscribe @buffer.onDidChangePath (@bufferPath) => @reloadGrammar()
@reloadGrammar()
@@ -79,7 +80,7 @@ class TokenizedBuffer extends Model
return if grammar is @grammar
@unsubscribe(@grammar) if @grammar
@grammar = grammar
@rootScopeDescriptor = [@grammar.scopeName]
@rootScopeDescriptor = new ScopeDescriptor(scopes: [@grammar.scopeName])
@currentGrammarScore = score ? grammar.getScore(@buffer.getPath(), @buffer.getText())
@subscribe @grammar.onDidUpdate => @retokenizeLines()
@@ -105,7 +106,7 @@ class TokenizedBuffer extends Model
hasTokenForSelector: (selector) ->
for {tokens} in @tokenizedLines
for token in tokens
return true if selector.matches(token.scopeDescriptor)
return true if selector.matches(token.scopes)
false
retokenizeLines: ->
@@ -247,7 +248,7 @@ class TokenizedBuffer extends Model
buildPlaceholderTokenizedLineForRow: (row) ->
line = @buffer.lineForRow(row)
tokens = [new Token(value: line, scopeDescriptor: [@grammar.scopeName])]
tokens = [new Token(value: line, scopes: [@grammar.scopeName])]
tabLength = @getTabLength()
indentLevel = @indentLevelForRow(row)
lineEnding = @buffer.lineEndingForRow(row)
@@ -303,7 +304,7 @@ class TokenizedBuffer extends Model
0
scopeDescriptorForPosition: (position) ->
@tokenForPosition(position).scopeDescriptor
new ScopeDescriptor(scopes: @tokenForPosition(position).scopes)
tokenForPosition: (position) ->
{row, column} = Point.fromObject(position)
+3 -3
Ver Arquivo
@@ -194,9 +194,9 @@ class TokenizedLine
isComment: ->
for token in @tokens
continue if token.scopeDescriptor.length is 1
continue if token.scopes.length is 1
continue if token.isOnlyWhitespace()
for scope in token.scopeDescriptor
for scope in token.scopes
return true if _.contains(scope.split('.'), 'comment')
break
false
@@ -226,7 +226,7 @@ class TokenizedLine
scopeStack = []
for token in @tokens
@updateScopeStack(scopeStack, token.scopeDescriptor)
@updateScopeStack(scopeStack, token.scopes)
_.last(scopeStack).children.push(token)
@scopeTree = scopeStack[0]
+1 -1
Ver Arquivo
@@ -65,7 +65,7 @@ class WindowEventHandler
@subscribeToCommand $(document), 'core:focus-previous', @focusPrevious
document.addEventListener 'keydown', @onKeydown
atom.commands.listen window, 'keydown', @onKeydown
@subscribe $(document), 'drop', (e) ->
e.preventDefault()
+32 -8
Ver Arquivo
@@ -8,8 +8,11 @@ WorkspaceView = null
module.exports =
class WorkspaceElement extends HTMLElement
globalTextEditorStyleSheet: null
createdCallback: ->
@subscriptions = new CompositeDisposable
@initializeGlobalTextEditorStyleSheet()
@initializeContent()
@observeScrollbarStyle()
@observeTextEditorFontConfig()
@@ -22,6 +25,10 @@ class WorkspaceElement extends HTMLElement
detachedCallback: ->
@model.destroy()
initializeGlobalTextEditorStyleSheet: ->
atom.styles.addStyleSheet('atom-text-editor {}', sourcePath: 'global-text-editor-styles')
@globalTextEditorStyleSheet = document.head.querySelector('style[source-path="global-text-editor-styles"]').sheet
initializeContent: ->
@classList.add 'workspace'
@setAttribute 'tabindex', -1
@@ -46,9 +53,9 @@ class WorkspaceElement extends HTMLElement
@classList.add("scrollbars-visible-when-scrolling")
observeTextEditorFontConfig: ->
@subscriptions.add atom.config.observe 'editor.fontSize', @setTextEditorFontSize
@subscriptions.add atom.config.observe 'editor.fontFamily', @setTextEditorFontFamily
@subscriptions.add atom.config.observe 'editor.lineHeight', @setTextEditorLineHeight
@subscriptions.add atom.config.observe 'editor.fontSize', @setTextEditorFontSize.bind(this)
@subscriptions.add atom.config.observe 'editor.fontFamily', @setTextEditorFontFamily.bind(this)
@subscriptions.add atom.config.observe 'editor.lineHeight', @setTextEditorLineHeight.bind(this)
createSpacePenShim: ->
WorkspaceView ?= require './workspace-view'
@@ -65,16 +72,33 @@ class WorkspaceElement extends HTMLElement
window.addEventListener 'focus', handleWindowFocus
@subscriptions.add(new Disposable -> window.removeEventListener 'focus', handleWindowFocus)
@panelContainers =
top: @model.panelContainers.top.getView()
left: @model.panelContainers.left.getView()
right: @model.panelContainers.right.getView()
bottom: @model.panelContainers.bottom.getView()
@horizontalAxis.insertBefore(@panelContainers.left, @verticalAxis)
@horizontalAxis.appendChild(@panelContainers.right)
@verticalAxis.insertBefore(@panelContainers.top, @paneContainer)
@verticalAxis.appendChild(@panelContainers.bottom)
@__spacePenView.setModel(@model)
setTextEditorFontSize: (fontSize) ->
atom.themes.updateGlobalEditorStyle('font-size', fontSize + 'px')
@updateGlobalEditorStyle('font-size', fontSize + 'px')
setTextEditorFontFamily: (fontFamily) ->
atom.themes.updateGlobalEditorStyle('font-family', fontFamily)
@updateGlobalEditorStyle('font-family', fontFamily)
setTextEditorLineHeight: (lineHeight) ->
atom.themes.updateGlobalEditorStyle('line-height', lineHeight)
@updateGlobalEditorStyle('line-height', lineHeight)
updateGlobalEditorStyle: (property, value) ->
editorRule = @globalTextEditorStyleSheet.cssRules[0]
editorRule.style[property] = value
atom.themes.emitter.emit 'did-update-stylesheet', @globalTextEditorStyleSheet
handleFocus: (event) ->
@model.getActivePane().activate()
@@ -90,7 +114,7 @@ class WorkspaceElement extends HTMLElement
focusPaneViewOnRight: -> @paneContainer.focusPaneViewOnRight()
atom.commands.add 'atom-workspace',
atom.commands.listen 'atom-workspace',
'window:increase-font-size': -> @getModel().increaseFontSize()
'window:decrease-font-size': -> @getModel().decreaseFontSize()
'window:reset-font-size': -> @getModel().resetFontSize()
@@ -136,6 +160,6 @@ atom.commands.add 'atom-workspace',
'core:save-as': -> @getModel().saveActivePaneItemAs()
if process.platform is 'darwin'
atom.commands.add 'atom-workspace', 'window:install-shell-commands', -> @getModel().installShellCommands()
atom.commands.listen 'atom-workspace', 'window:install-shell-commands', -> @getModel().installShellCommands()
module.exports = WorkspaceElement = document.registerElement 'atom-workspace', prototype: WorkspaceElement.prototype
+8 -31
Ver Arquivo
@@ -141,59 +141,36 @@ class WorkspaceView extends View
Section: Adding elements to the workspace
###
# Essential: Prepend an element or view to the panels at the top of the
# workspace.
#
# * `element` jQuery object or DOM element
prependToTop: (element) ->
deprecate 'Please use Workspace::addTopPanel() instead'
@vertical.prepend(element)
# Essential: Append an element or view to the panels at the top of the workspace.
#
# * `element` jQuery object or DOM element
appendToTop: (element) ->
deprecate 'Please use Workspace::addTopPanel() instead'
@panes.before(element)
# Essential: Prepend an element or view to the panels at the bottom of the
# workspace.
#
# * `element` jQuery object or DOM element
prependToBottom: (element) ->
deprecate 'Please use Workspace::addBottomPanel() instead'
@panes.after(element)
# Essential: Append an element or view to the panels at the bottom of the
# workspace.
#
# * `element` jQuery object or DOM element
appendToBottom: (element) ->
deprecate 'Please use Workspace::addBottomPanel() instead'
@vertical.append(element)
# Essential: Prepend an element or view to the panels at the left of the
# workspace.
#
# * `element` jQuery object or DOM element
prependToLeft: (element) ->
deprecate 'Please use Workspace::addLeftPanel() instead'
@horizontal.prepend(element)
# Essential: Append an element or view to the panels at the left of the
# workspace.
#
# * `element` jQuery object or DOM element
appendToLeft: (element) ->
deprecate 'Please use Workspace::addLeftPanel() instead'
@vertical.before(element)
# Essential: Prepend an element or view to the panels at the right of the
# workspace.
#
# * `element` jQuery object or DOM element
prependToRight: (element) ->
deprecate 'Please use Workspace::addRightPanel() instead'
@vertical.after(element)
# Essential: Append an element or view to the panels at the right of the
# workspace.
#
# * `element` jQuery object or DOM element
appendToRight: (element) ->
deprecate 'Please use Workspace::addRightPanel() instead'
@horizontal.append(element)
###
+92 -1
Ver Arquivo
@@ -10,6 +10,10 @@ Grim = require 'grim'
TextEditor = require './text-editor'
PaneContainer = require './pane-container'
Pane = require './pane'
Panel = require './panel'
PanelElement = require './panel-element'
PanelContainer = require './panel-container'
PanelContainerElement = require './panel-container-element'
ViewRegistry = require './view-registry'
WorkspaceElement = require './workspace-element'
@@ -45,6 +49,12 @@ class Workspace extends Model
@paneContainer ?= new PaneContainer({@viewRegistry})
@paneContainer.onDidDestroyPaneItem(@onPaneItemDestroyed)
@panelContainers =
top: new PanelContainer({@viewRegistry, location: 'top'})
left: new PanelContainer({@viewRegistry, location: 'left'})
right: new PanelContainer({@viewRegistry, location: 'right'})
bottom: new PanelContainer({@viewRegistry, location: 'bottom'})
@subscribeToActiveItem()
@addOpener (filePath) =>
@@ -62,6 +72,14 @@ class Workspace extends Model
modelConstructor: Workspace
viewConstructor: WorkspaceElement
@addViewProvider
modelConstructor: PanelContainer
viewConstructor: PanelContainerElement
@addViewProvider
modelConstructor: Panel
viewConstructor: PanelElement
# Called by the Serializable mixin during deserialization
deserializeParams: (params) ->
for packageName in params.packagesWithActiveGrammars ? []
@@ -384,6 +402,8 @@ class Workspace extends Model
item ?= opener(atom.project.resolve(uri), options) for opener in @getOpeners() when !item
item ?= atom.project.open(uri, options)
console.profile('open')
Q(item)
.then (item) =>
if not pane
@@ -395,6 +415,7 @@ class Workspace extends Model
index = pane.getActiveItemIndex()
@emit "uri-opened"
@emitter.emit 'did-open', {uri, pane, item, index}
console.profileEnd('open')
item
.catch (error) ->
console.error(error.stack ? error)
@@ -578,6 +599,76 @@ class Workspace extends Model
@paneContainer.destroy()
@activeItemSubscriptions?.dispose()
###
Section: Panels
###
# Essential: Adds a panel item to the bottom of the editor window.
#
# * `options` {Object}
# * `item` Your panel content. It can be DOM element, a jQuery element, or
# a model with a view registered via {::addViewProvider}. We recommend the
# latter. See {::addViewProvider} for more information.
# * `visible` (optional) {Boolean} false if you want the panel to initially be hidden
# (default: true)
# * `priority` (optional) {Number} Determines stacking order. Lower priority items are
# forced closer to the edges of the window. (default: 100)
#
# Returns a {Panel}
addBottomPanel: (options) ->
@addPanel('bottom', options)
# Essential: Adds a panel item to the left of the editor window.
#
# * `options` {Object}
# * `item` Your panel content. It can be DOM element, a jQuery element, or
# a model with a view registered via {::addViewProvider}. We recommend the
# latter. See {::addViewProvider} for more information.
# * `visible` (optional) {Boolean} false if you want the panel to initially be hidden
# (default: true)
# * `priority` (optional) {Number} Determines stacking order. Lower priority items are
# forced closer to the edges of the window. (default: 100)
#
# Returns a {Panel}
addLeftPanel: (options) ->
@addPanel('left', options)
# Essential: Adds a panel item to the right of the editor window.
#
# * `options` {Object}
# * `item` Your panel content. It can be DOM element, a jQuery element, or
# a model with a view registered via {::addViewProvider}. We recommend the
# latter. See {::addViewProvider} for more information.
# * `visible` (optional) {Boolean} false if you want the panel to initially be hidden
# (default: true)
# * `priority` (optional) {Number} Determines stacking order. Lower priority items are
# forced closer to the edges of the window. (default: 100)
#
# Returns a {Panel}
addRightPanel: (options) ->
@addPanel('right', options)
# Essential: Adds a panel item to the top of the editor window above the tabs.
#
# * `options` {Object}
# * `item` Your panel content. It can be DOM element, a jQuery element, or
# a model with a view registered via {::addViewProvider}. We recommend the
# latter. See {::addViewProvider} for more information.
# * `visible` (optional) {Boolean} false if you want the panel to initially be hidden
# (default: true)
# * `priority` (optional) {Number} Determines stacking order. Lower priority items are
# forced closer to the edges of the window. (default: 100)
#
# Returns a {Panel}
addTopPanel: (options) ->
@addPanel('top', options)
addPanel: (location, options) ->
options ?= {}
options.viewRegistry = @viewRegistry
@panelContainers[location].addPanel(new Panel(options))
###
Section: View Management
###
@@ -628,7 +719,7 @@ class Workspace extends Model
# makes [HTML 5 custom elements](http://www.html5rocks.com/en/tutorials/webcomponents/customelements/)
# an ideal tool for implementing views in Atom.
#
# ## Example
# ## Examples
#
# Text editors are divided into a model and a view layer, so when you interact
# with methods like `atom.workspace.getActiveTextEditor()` you're only going
+4 -2
Ver Arquivo
@@ -5,8 +5,10 @@ window.onload = function() {
// Skip "?loadSettings=".
var loadSettings = JSON.parse(decodeURIComponent(location.search.substr(14)));
var devMode = loadSettings.devMode || !loadSettings.resourcePath.startsWith(process.resourcesPath + require('path').sep);
// Require before the module cache in dev mode
if (loadSettings.devMode) {
if (devMode) {
require('coffee-script').register();
}
@@ -25,7 +27,7 @@ window.onload = function() {
require('vm-compatibility-layer');
if (!loadSettings.devMode) {
if (!devMode) {
require('coffee-script').register();
}
+11
Ver Arquivo
@@ -1,5 +1,16 @@
@import "ui-variables";
atom-panel-container[location="left"],
atom-panel-container[location="right"] {
display: -webkit-flex;
-webkit-flex-direction: row;
-webkit-align-items: stretch;
height: 100%;
atom-panel {
height: 100%;
}
}
// Override bootstrap styles here.
.panel {
border-radius: 0;