Comparar commits

...

207 Commits

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

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

Signed-off-by: Max Brunsfeld <maxbrunsfeld@gmail.com>
2014-11-26 12:17:26 -07:00
Ben Ogle f2e74f216c Upgrade to solarized-dark-syntax to update to standard colors 2014-11-26 11:09:04 -08:00
Nathan Sobo b9950ef2df Match coordinate types when computing overlay pixel position
Heads up @benogle
2014-11-26 09:28:12 -07:00
Nathan Sobo 28eb03ed29 ⬆️ command-palette to fix exception on call to ::command
Fixes #4318
2014-11-25 20:49:17 -07:00
Ben Ogle 2843af458b Merge pull request #4307 from atom/bo-add-parse-errors
Integrate notifications into core
2014-11-25 15:59:37 -08:00
Ben Ogle 163a7587f9 Upgrade notifications for issue searching and dupe handling 2014-11-25 15:44:14 -08:00
Ben Ogle 18f83e90f7 Add isEquals to notifications 2014-11-25 15:44:14 -08:00
Ben Ogle 7094701c66 Remove the font-family variable 2014-11-25 15:44:14 -08:00
Ben Ogle d7d23f7fc9 Upgrade snippets to display a notification
when there is a parse error
2014-11-25 15:44:14 -08:00
Ben Ogle bdbc850695 Add a @font-family-monospace 2014-11-25 15:44:14 -08:00
Ben Ogle 4e0ab92827 Fix Notification::getDetail 2014-11-25 15:44:14 -08:00
Ben Ogle b662281958 Upgrade notifications to remove menus, and fix styling 2014-11-25 15:44:14 -08:00
Ben Ogle 4d2cc86ada Add notifications package as a dependency 2014-11-25 15:44:14 -08:00
Ben Ogle 19fcc1c441 💄 on message 2014-11-25 15:44:14 -08:00
Ben Ogle 1f5fa27113 Trigger a notification when there is a keymap issue 2014-11-25 15:44:14 -08:00
Ben Ogle 362bd2e61a Use atom.notifications when there is a config file error 2014-11-25 15:44:13 -08:00
Ben Ogle 4cb80d3c7e Downgrade pathwatcher in an attempt to fix build 2014-11-25 15:26:50 -08:00
Ben Ogle 7f108dab38 Merge pull request #4286 from m0x72/patch-1
Wrong Reactionary dependence
2014-11-25 12:20:43 -08:00
Ben Ogle cec5a83eff 📝 Update restoreDefault to doc scopeSelector 2014-11-25 12:10:54 -08:00
Nathan Sobo a7c3c15885 Don’t assume presence of unsubscribe method in SpacePen callRemoveHooks 2014-11-25 10:01:27 -07:00
Nathan Sobo 1c16738969 ⬆️ pathwatcher for deprecation warning fix 2014-11-25 08:51:13 -07:00
Nathan Sobo b4a456d911 Fix misinformation in deprecation warning 2014-11-25 08:19:20 -07:00
Nathan Sobo c92f805e6e Remove deprecated requires from spec-helper 2014-11-25 08:18:26 -07:00
Nathan Sobo 859a4db242 ⬆️ UI themes now that status-bar has no redundant panel classes
The UI themes now style both the legacy panel classes and the new panel
elements. Views converted to to the new panels API should remove their
legacy classes.
2014-11-25 08:09:11 -07:00
Nathan Sobo 3a94b70270 ⬆️ status-bar to remove redundant panel classes 2014-11-25 07:48:11 -07:00
Nathan Sobo 85d6689344 Merge pull request #4305 from atom/ns-add-legacy-panel-classes
Add legacy panel classes for theme support
2014-11-25 07:43:17 -07:00
Max Brunsfeld e0726b0354 Merge pull request #4309 from atom/mb-fix-panel-order
Fix ordering of panels in panel containers
2014-11-24 17:40:25 -08:00
Max Brunsfeld 0abd25ad6f Fix ordering of panels in panel containers
An off-by-one error caused new panels to be inserted later
in the document than intended.
2014-11-24 17:29:31 -08:00
Max Brunsfeld 42522686d7 ⬆️ autocomplete@0.33.1 2014-11-24 16:22:15 -08:00
Nathan Sobo 1e9a8b92f2 Fix workspace model spec now that legacy panel class is added in view 2014-11-24 17:03:32 -07:00
Nathan Sobo dda2b2e893 Don’t apply ‘tool-panel’ class to modal panels 2014-11-24 16:46:47 -07:00
Ben Ogle e04c05ffee Merge pull request #4264 from atom/bo-messages
Messages API implementation
2014-11-24 15:39:57 -08:00
Nathan Sobo 8cb0197638 Add legacy ‘from-top’ class at the view layer, not the model
This blends in to our approach with the other legacy panel classes.
2014-11-24 16:38:04 -07:00
Nathan Sobo 73763d3e41 Add legacy panel classes to support old theme selectors
Signed-off-by: Max Brunsfeld <maxbrunsfeld@gmail.com>
2014-11-24 16:37:37 -07:00
Nathan Sobo 9d1c3124ee Prepare 0.153.0 release 2014-11-24 16:29:05 -07:00
Ben Ogle aaee54bd08 Remove unnecessary error flash classes 2014-11-24 14:58:21 -08:00
Ben Ogle 1ae8862a9c Notification::getTimestamp() 2014-11-24 14:58:21 -08:00
Ben Ogle f3dd757537 Export Notification, not Message 2014-11-24 14:58:21 -08:00
Ben Ogle 68693e3ca0 Remove issue related stuff 2014-11-24 14:58:21 -08:00
Ben Ogle e24a562387 Use bug icon for fatal errors 2014-11-24 14:58:21 -08:00
Ben Ogle 9c6a5fb4fa Messages -> notifications 2014-11-24 14:58:21 -08:00
Ben Ogle 25caaa92f1 Export Message 2014-11-24 14:58:21 -08:00
Ben Ogle 78ee02f0c6 nof 2014-11-24 14:58:21 -08:00
Ben Ogle e462fdc4ce Add specs for Message 2014-11-24 14:58:21 -08:00
Ben Ogle 96d8721c9e Add some things to Message 2014-11-24 14:58:21 -08:00
Ben Ogle 568151b1a5 📝 2014-11-24 14:58:21 -08:00
Ben Ogle 3d6c9ee554 Add a MessageManager to atom.messages 2014-11-24 14:58:20 -08:00
Ben Ogle d5d6422d28 Add beginning of message system 2014-11-24 14:58:20 -08:00
Nathan Sobo 8cf24bc7de ⬇️ UI themes so we can iron out selector issues
Signed-off-by: Max Brunsfeld <maxbrunsfeld@gmail.com>
2014-11-24 15:51:11 -07:00
Nathan Sobo 5727865b94 Prepare 0.152.0 release 2014-11-24 15:18:57 -07:00
Nathan Sobo b95b86396e ⬆️ text-buffer to publicize checkpoint methods
Signed-off-by: Max Brunsfeld <maxbrunsfeld@gmail.com>
2014-11-24 14:23:49 -07:00
Nathan Sobo d75c35285c Publicize checkpoint methods and deprecate open-ended transactions
On TextEditor

Signed-off-by: Max Brunsfeld <maxbrunsfeld@gmail.com>
2014-11-24 14:23:48 -07:00
Ben Ogle a7bc7c198d Suggest space-pen 4 rather than space-pen 3 2014-11-24 13:18:42 -08:00
Nathan Sobo d2f24615c1 Delete advanced/globals.md now that we cover them in the API docs 2014-11-24 12:20:45 -07:00
Nathan Sobo e4b942e991 Modernize advanced/configuration docs 2014-11-24 12:16:53 -07:00
Nathan Sobo c9f8ffc749 💄 create-a-package.md 2014-11-24 12:02:34 -07:00
Cheng Zhao c2086eee0e ⬆️ atom-shell@0.19.4 2014-11-24 11:38:26 +08:00
Max Brunsfeld d5a66c590a Merge pull request #4288 from atom/mb-paste-leading-whitespace
Preserve first line's leading whitespace on paste
2014-11-23 10:12:51 -08:00
Max Brunsfeld b374c1a11a Preserve 1st line's leading whitespace on paste 2014-11-22 09:43:23 -08:00
Martin Riedel 509d16b65a Updated deprecation msg to reactionary-atom-fork 2014-11-22 17:49:52 +01:00
m0x72 e8e13ca645 Wrong Reactionary dependence
exports/atom.coffee requires package `reactionary` while atom only has `reactionary-atom-fork` as a dependence (https://github.com/atom/atom/blob/master/package.json#L53). Should require `reactionary-atom-fork` instead.

It's clear that `Reactionary` will soon be omitted from atom's module exports, but as long as fallbacks are provided, the `reactionary` package reference should be corrected. :)
2014-11-22 16:00:40 +01:00
Nathan Sobo 35f8e6a5a7 ⬆️ deprecation-cop to fix specs 2014-11-21 21:48:11 -07:00
Nathan Sobo 36a9ad7d90 ⬆️ atom-light-ui for 1.0 selector upgrades 2014-11-21 21:32:08 -07:00
Nathan Sobo 6ff304094f ⬆️ deprecation-cop for atom-pane-container and atom-pane-axis deprecations 2014-11-21 21:10:59 -07:00
Nathan Sobo 0e51def6be ⬆️ atom-dark-ui for 1.0 selector compatibility 2014-11-21 20:54:25 -07:00
Nathan Sobo f366a67fee ⬆️ deprecation-cop for new panel selectors 2014-11-21 20:30:19 -07:00
Max Brunsfeld f30f0de45e ⬆️ text-buffer@3.7.1 2014-11-21 17:09:23 -08:00
Nathan Sobo 9e36cd705e ⬆️ atom-dark-syntax to remove deprecated selectors 2014-11-21 18:02:43 -07:00
Max Brunsfeld 2a5081f0e0 Remove normalizeIndentOnPaste from config schema 2014-11-21 14:51:44 -08:00
Kevin Sawicki 2c93b1459e ⬆️ image-view@0.42 2014-11-21 11:57:58 -08:00
Max Brunsfeld bf83fb7b10 ⬆️ text-buffer@3.7.0 for checkpoints
Also add methods on TextEditor to expose the new checkpoint
functionality
2014-11-21 11:06:43 -08:00
Kevin Sawicki f4cc8c31b3 ⬇️ image-view@0.40
Specs are failing
2014-11-21 10:51:12 -08:00
Nathan Sobo e62ecbab6b Work around chromium bug where focus gets stolen from shadow DOM
Fixes #4255
2014-11-21 11:04:42 -07:00
Kevin Sawicki 4cef3bfef5 ⬆️ image-view@0.41 2014-11-21 09:54:18 -08:00
Kevin Sawicki 85fae83195 ⬆️ language-xml@0.25 2014-11-21 08:41:43 -08:00
Ben Ogle f79b78054c Add title to TooltipManager args 2014-11-20 18:35:01 -08:00
Kevin Sawicki e803c06b28 ⬆️ tree-view@0.134 2014-11-20 17:00:18 -08:00
Kevin Sawicki 1963a7f437 ⬆️ tree-view@0.133 2014-11-20 16:12:20 -08:00
Ben Ogle 48eb5307e6 Upgrade status bar to use the new panel api 2014-11-20 15:20:26 -08:00
Nathan Sobo 95d6ab1d4f Add legacy ‘Syntax’ deserializer for GrammarRegistry 2014-11-20 15:28:37 -07:00
Kevin Sawicki 9224c86452 ⬆️ language-gfm@0.54 2014-11-20 14:15:34 -08:00
Kevin Sawicki 0fa2b4426a ⬆️ language-javascript@0.45 2014-11-20 13:41:44 -08:00
Kevin Sawicki 1e4e59ad1c Merge pull request #3745 from atom/document-apm-sort
Document sort params on atom.io package list
2014-11-20 13:21:43 -08:00
Nathan Sobo 97a56574e0 Merge pull request #4259 from atom/ns-deprecate-syntax-global
Rename atom.syntax to atom.grammars
2014-11-20 14:11:45 -07:00
Kevin Sawicki c06fefce14 Prepare 0.151 2014-11-20 12:38:08 -08:00
Kevin Sawicki 00027e892c ⬆️ language-javascript@0.44 2014-11-20 12:16:19 -08:00
Nathan Sobo d4dee07b41 Fix window-spec for key name change in deserialized state 2014-11-20 13:12:17 -07:00
Nathan Sobo f475552673 Fix local variable name 2014-11-20 13:10:51 -07:00
Ben Ogle 6e33f10050 Upgrade deprecation cop for markdown deps + fix 2014-11-20 12:07:10 -08:00
Ben Ogle 61651db0b0 Render the deprecations as markdown 2014-11-20 11:41:53 -08:00
Ben Ogle 982346b142 Remove view system docs. They are mis-information 2014-11-20 11:27:11 -08:00
Kevin Sawicki 92ba107c89 ⬆️ fs-plus@2.3.2 2014-11-20 11:15:10 -08:00
Kevin Sawicki 7b4a9aa2e4 Patch statSyncNoException to handle non-string args
Non-string values were being coerced to strings which can cause
unexpected results.

Refs atom/atom-shell#843
Closes #4247
2014-11-20 11:15:10 -08:00
Ben Ogle 446398ad01 Upgrade default themes to fix scrollbar issues. 2014-11-20 11:06:19 -08:00
Ben Ogle 8afbab311f Merge pull request #4248 from atom/bo-deprecate-workspace-view
Deprecate workspaceView
2014-11-20 10:53:19 -08:00
Nathan Sobo 32f2a95f07 Make GrammarRegistry::selectGrammar public since we use it in specs 2014-11-20 11:44:37 -07:00
Nathan Sobo d53d01d95b Replace atom.syntax with atom.grammars 2014-11-20 11:42:49 -07:00
Nathan Sobo 131522f93d Rename Syntax to GrammarRegistry 2014-11-20 11:38:01 -07:00
Kevin Sawicki 1601a1fbfa ⬆️ encoding-selector@0.8 2014-11-20 10:27:32 -08:00
Nathan Sobo 2c89a5c82a Merge pull request #4250 from atom/ns-tooltip-manager
Replace jQuery-based tooltip API with atom.tooltips global
2014-11-20 11:26:07 -07:00
Nathan Sobo e4ec932513 Merge pull request #4258 from atom/ns-fix-memory-leaks
Fix memory leaks introduced by changes for API freeze
2014-11-20 11:22:33 -07:00
Kevin Sawicki a834920fb7 ⬆️ spell-check@0.44 2014-11-20 10:19:31 -08:00
Nathan Sobo b5edefcae8 Trigger editor:will-be-removed from SpacePen shim, not component
By the time the component is getting unmounted, we have already called
remove hooks on the SpacePen shim so subscriptions to the event have
been removed.
2014-11-20 11:13:40 -07:00
Nathan Sobo 616a94a10e Only SpacePen callRemoveHooks on removed pane item view if destroyed 2014-11-20 11:12:50 -07:00
Nathan Sobo 7034fe3b36 ⬆️ space-pen to call cleanData in callRemoveHooks to stop leaks 2014-11-20 11:02:58 -07:00
Nathan Sobo 5f68af27f5 Fix memory leak in GitRepository and convert to CompositeDisposables
We were calling @unsubscribe with the TextBuffer, which previously
unsubscribed from that object. The problem is that we were no longer
subscribing to that object directly, but only adding subscriptions to
that object. This caused us to never unsubscribe from buffers.
2014-11-20 10:56:51 -07:00
Nathan Sobo ea207f0938 📝 returned disposable 2014-11-20 09:13:36 -07:00
Nathan Sobo 732f053d4a Add atom.tooltips global 2014-11-19 19:22:11 -07:00
Nathan Sobo 78e61c3ff9 Remove ability to add tooltip with selector
It’s incompatible with returning a disposable because there’s no way
to distinguish multiple tooltips added to the body with different
selectors. Maybe someday.
2014-11-19 19:20:48 -07:00
Nathan Sobo 22c9a222c9 Return a Disposable from TooltipManager::add 2014-11-19 19:19:05 -07:00
Nathan Sobo cc4ab0d36b 📝 Document TooltipManager 2014-11-19 19:13:33 -07:00
Nathan Sobo 7bdf3b1719 Add support for keyBindingTarget to TooltipManager::add 2014-11-19 19:10:36 -07:00
Nathan Sobo 175d7811b4 Add TooltipManager
Signed-off-by: Max Brunsfeld <maxbrunsfeld@gmail.com>
2014-11-19 18:57:08 -07:00
Ben Ogle 3f3fca872b Remove the unsubscribe spy
Sorry @nathansobo, this is making the window specs fail
2014-11-19 17:46:33 -08:00
Ben Ogle 421c64347e View -> Element in docs 2014-11-19 17:46:33 -08:00
Ben Ogle 557d277e9f Remove workspaceView references from the window-specs 2014-11-19 17:46:32 -08:00
Ben Ogle 3fc514659a Remove workspaceView references from ThemeManager 2014-11-19 17:46:32 -08:00
Ben Ogle 747398f2a5 Remove workspaceView from spec-helper 2014-11-19 17:46:32 -08:00
Ben Ogle 1f51317a10 Remove workspaceView references from atom.coffee 2014-11-19 17:46:32 -08:00
Ben Ogle f592a5d11f 📝 Remove workspaceView from doc 2014-11-19 17:46:32 -08:00
Ben Ogle fb223db958 Remove workspaceView from PackageManager specs 2014-11-19 17:46:32 -08:00
Ben Ogle 1d73c57f9e Remove reference to workspaceView in window-event-handler 2014-11-19 17:46:32 -08:00
Ben Ogle 016f32d62e Add a FIXME for this workspaceView bit 2014-11-19 17:46:32 -08:00
Ben Ogle 9ee4d334b2 Reflow paragraph 2014-11-19 17:46:32 -08:00
Ben Ogle ddb16dcc6f 📝 Update doc to remove workspaceView 2014-11-19 17:46:32 -08:00
Ben Ogle 8403e6583f Deprecate atom.workspaceView 2014-11-19 17:46:32 -08:00
Ben Ogle 6bdbabecbd Add jasmine.attachToDOM 2014-11-19 17:08:54 -08:00
Kevin Sawicki 2cda86efda Prepare 0.150 2014-11-19 17:07:06 -08:00
Kevin Sawicki 46ff794c8b Don't set the update query param on Windows 2014-11-19 15:58:51 -08:00
Ben Ogle 1406fbfe03 Merge pull request #4243 from atom/bo-remove-space-pen-docs
Remove space pen views from docs
2014-11-19 14:33:53 -08:00
Ben Ogle dde13a5d4e 💄 2014-11-19 14:33:24 -08:00
Ben Ogle bfc7995aee Blacklist space pen docs from making it into our docs. 2014-11-19 14:15:43 -08:00
Ben Ogle 7fd9c75d24 Hide the space pen views in the docs 2014-11-19 14:15:18 -08:00
Nathan Sobo 677be2df82 Merge pull request #4223 from atom/ns-deprecate-style-sheet-events
Deprecate style sheet event methods on ThemeManager
2014-11-19 14:59:20 -07:00
Kevin Sawicki b3bf47dd69 Prepare 0.149 2014-11-19 12:17:49 -08:00
Nathan Sobo 49471070a3 Move public stylesheet related methods off of atom.themes
* Move atom.themes.getUserStylesheetPath to 
  atom.styles.getUserStyleSheetPath
* Deprecate atom.themes.requireStylesheet
2014-11-19 10:31:03 -07:00
Nathan Sobo be7111f007 Deprecate style sheet events on ThemeManager
They are now supplanted by methods on the StyleManager located at
`atom.styles`.
2014-11-18 10:57:07 -07:00
Nathan Sobo 59c28c0f76 Clarify documentation 2014-11-18 10:56:28 -07:00
Nathan Sobo 27331cb379 Publicize and document StyleManager 2014-11-18 10:50:55 -07:00
Nathan Sobo d3f2798472 💄 2014-11-17 16:55:30 -07:00
Daniel Hengeveld fc90a3c2ba Document search endpoint 2014-10-07 15:20:05 -07:00
Daniel Hengeveld 382a06028c Document sort params on package list 2014-10-07 12:08:37 -07:00
96 arquivos alterados com 1637 adições e 960 exclusões
+2 -1
Ver Arquivo
@@ -1,7 +1,8 @@
require '../spec/spec-helper'
path = require 'path'
{$, Point} = require 'atom'
{$} = require '../src/space-pen-extensions'
{Point} = require 'atom'
_ = require 'underscore-plus'
fs = require 'fs-plus'
Project = require '../src/project'
+4 -2
Ver Arquivo
@@ -1,5 +1,7 @@
require './benchmark-helper'
{$, _, WorkspaceView} = require 'atom'
{$} = require '../src/space-pen-extensions'
_ = require 'underscore-plus'
{WorkspaceView} = require 'atom'
TokenizedBuffer = require '../src/tokenized-buffer'
describe "editorView.", ->
@@ -7,7 +9,7 @@ describe "editorView.", ->
beforeEach ->
atom.workspaceViewParentSelector = '#jasmine-content'
atom.workspaceView = atom.views.getView(atom.workspace).__spacePenView
atom.workspaceView = atom.views.createView(atom.workspace).__spacePenView
atom.workspaceView.attachToDom()
atom.workspaceView.width(1024)
+5
Ver Arquivo
@@ -6,12 +6,17 @@ _ = require 'underscore-plus'
donna = require 'donna'
tello = require 'tello'
moduleBlacklist = [
'space-pen'
]
module.exports = (grunt) ->
getClassesToInclude = ->
modulesPath = path.resolve(__dirname, '..', '..', 'node_modules')
classes = {}
fs.traverseTreeSync modulesPath, (modulePath) ->
return false if modulePath.match(/node_modules/g).length > 1 # dont need the dependencies of the dependencies
return false if path.basename(modulePath) in moduleBlacklist
return true unless path.basename(modulePath) is 'package.json'
return true unless fs.isFileSync(modulePath)
+25 -24
Ver Arquivo
@@ -11,32 +11,34 @@ value of a namespaced config key with `atom.config.get`:
@showInvisibles() if atom.config.get "editor.showInvisibles"
```
Or you can use the `::subscribe` with `atom.config.observe` to track changes
from any view object.
Or you can subscribe via `atom.config.observe` to track changes from any view
object.
```coffeescript
{View} = require 'space-pen'
class MyView extends View
initialize: ->
@subscribe atom.config.observe 'editor.fontSize', (newValue, {previous}) =>
@adjustFontSize()
attached: ->
@fontSizeObserveSubscription =
atom.config.observe 'editor.fontSize', (newValue, {previous}) =>
@adjustFontSize()
detached: ->
@fontSizeObserveSubscription.dispose()
```
The `atom.config.observe` method will call the given callback immediately with
the current value for the specified key path, and it will also call it in the
future whenever the value of that key path changes.
future whenever the value of that key path changes. If you only want to invoke
the callback when the next time the value changes, use `atom.config.onDidChange`
instead.
Subscriptions made with `::subscribe` are automatically canceled when the
view is removed. You can cancel config subscriptions manually via the
`off` method on the subscription object that `atom.config.observe` returns.
```coffeescript
fontSizeSubscription = atom.config.observe 'editor.fontSize', (newValue, {previous}) =>
@adjustFontSize()
# ... later on
fontSizeSubscription.off() # Stop observing
```
Subscription methods return *disposable* subscription objects. Note in the
example above how we save the subscription to the `@fontSizeObserveSubscription`
instance variable and dispose of it when the view is detached. To group multiple
subscriptions together, you can add them all to a
[`CompositeDisposable`][composite-disposable] that you dispose when the view is
detached.
### Writing Config Settings
@@ -48,10 +50,9 @@ but you can programmatically write to it with `atom.config.set`:
atom.config.set("core.showInvisibles", true)
```
You can also use `setDefaults`, which will assign default values for keys that
are always overridden by values assigned with `set`. Defaults are not written
out to the the `config.json` file to prevent it from becoming cluttered.
If you're exposing package configuration via specific key paths, you'll want to
associate them with a schema in your package's main module. Read more about
schemas in the [config API docs][config-api].
```coffeescript
atom.config.setDefaults("editor", fontSize: 18, showInvisibles: true)
```
[composite-disposable]: https://atom.io/docs/api/latest/CompositeDisposable
[config-api]: https://atom.io/docs/api/latest/Config
-34
Ver Arquivo
@@ -1,34 +0,0 @@
# Globals
Atom exposes several services through singleton objects accessible via the
`atom` global:
* atom
* workspace:
Manipulate and query the state of the user interface for the current
window. Open editors, manipulate panes.
* workspaceView:
Similar to workspace, but provides access to the root of all views in the
current window.
* project:
Access the directory associated with the current window. Load editors,
perform project-wide searches, register custom openers for special file
types.
* config:
Read, write, and observe user configuration settings.
* keymap:
Add and query the currently active keybindings.
* deserializers:
Deserialize instances from their state objects and register deserializers.
* packages:
Activate, deactivate, and query user packages.
* themes:
Activate, deactivate, and query user themes.
* contextMenu:
Register context menus.
* menu:
Register application menus.
* pasteboard:
Read from and write to the system pasteboard.
* syntax:
Assign and query syntactically-scoped properties.
-58
Ver Arquivo
@@ -1,58 +0,0 @@
## Atom's View System
### SpacePen Basics
Atom's view system is built around the [SpacePen] view framework. SpacePen
view objects inherit from the jQuery prototype, and wrap DOM nodes
View objects are actually jQuery wrappers around DOM fragments, supporting all
the typical jQuery traversal and manipulation methods. In addition, view objects
have methods that are view-specific. For example, you could call both general
and view-specific on the global `atom.workspaceView` instance:
```coffeescript
atom.workspaceView.find('atom-text-editor.active') # standard jQuery method
atom.workspaceView.getActiveEditor() # view-specific method
```
If you retrieve a jQuery wrapper for an element associated with a view, use the
`.view()` method to retrieve the element's view object:
```coffeescript
# this is a plain jQuery object; you can't call view-specific methods
editorElement = atom.workspaceView.find('atom-text-editor.active')
# get the view object by calling `.view()` to call view-specific methods
editorView = editorElement.view()
editorView.setCursorBufferPosition([1, 2])
```
Refer to the [SpacePen] documentation for more details.
### WorkspaceView
The root of Atom's view hierarchy is a global called `atom.workspaceView`, which is a
singleton instance of the `WorkspaceView` view class. The root view fills the entire
window, and contains every other view. If you open Atom's inspector with
`alt-cmd-i`, you can see the internal structure of `WorkspaceView`:
![WorkspaceView in the inspector][workspaceview-inspector]
#### Panes
The `WorkspaceView` contains `prependToBottom/Top/Left/Right` and
`appendToBottom/Top/Left/Right` methods, which are used to add Tool Panels. Tool
panels are elements that take up screen real estate not devoted to text editing.
In the example above, the `TreeView` is appended to the left, and the
`CommandPanel` is appended to the top.
```coffeescript
# place a view to the left of the panes
atom.workspaceView.appendToLeft(new MyView)
# place a view below the panes
atom.workspaceView.appendToBottom(new MyOtherView)
```
[spacepen]: http://github.com/nathansobo/space-pen
[workspaceView-inspector]: https://f.cloud.github.com/assets/1424/1091631/1932c2d6-166b-11e3-8adf-9690fe82d3b8.png
+16
Ver Arquivo
@@ -30,6 +30,8 @@ All requests that take parameters require `application/json`.
Parameters:
- **page** (optional)
- **sort** (optional, values: `created_at`, `updated_at`, `downloads`)
- **direction** (optional, values: `asc`, `desc`)
Returns a list of all packages in the following format:
```json
@@ -57,6 +59,20 @@ Link: <https://www.atom.io/api/packages?page=1>; rel="self",
<https://www.atom.io/api/packages?page=2>; rel="next"
```
By default, results are sorted by download count, descending.
#### GET /api/packages/search
Parameters:
- **q** String query to search
- **sort** (optional, values: `created_at`, `updated_at`, `downloads`)
- **direction** (optional, values: `asc`, `desc`)
Returns a list of all packages in the same format as `/api/packages`.
By default, results sorted by relevance to search query.
### Showing package details
#### GET /api/packages/:package_name
+21 -20
Ver Arquivo
@@ -40,7 +40,7 @@ package.json files have their own additions.
- `main` (**Required**): the path to the CoffeeScript file that's the entry point
to your package
- `stylesheets` (**Optional**): an Array of Strings identifying the order of the
stylesheets your package needs to load. If not specified, stylesheets in the
style sheets your package needs to load. If not specified, style sheets in the
_stylesheets_ directory are added alphabetically.
- `keymaps`(**Optional**): an Array of Strings identifying the order of the
key mappings your package needs to load. If not specified, mappings in the
@@ -119,27 +119,27 @@ Also, please collaborate with us if you need an API that doesn't exist. Our goal
is to build out Atom's API organically based on the needs of package authors
like you.
## Stylesheets
## Style Sheets
Stylesheets for your package should be placed in the _stylesheets_ directory.
Any stylesheets in this directory will be loaded and attached to the DOM when
your package is activated. Stylesheets can be written as CSS or [LESS] (but LESS
is recommended).
Style sheets for your package should be placed in the _stylesheets_ directory.
Any style sheets in this directory will be loaded and attached to the DOM when
your package is activated. Style sheets can be written as CSS or [LESS] (but
LESS is recommended).
Ideally, you won't need much in the way of styling. We've provided a standard
set of components which define both the colors and UI elements for any package
that fits into Atom seamlessly. You can view all of Atom's UI components by opening
the styleguide: open the command palette (`cmd-shift-P`) and search for _styleguide_,
or just type `cmd-ctrl-shift-G`.
that fits into Atom seamlessly. You can view all of Atom's UI components by
opening the styleguide: open the command palette (`cmd-shift-P`) and search for
_styleguide_, or just type `cmd-ctrl-shift-G`.
If you _do_ need special styling, try to keep only structural styles in the package
stylesheets. If you _must_ specify colors and sizing, these should be taken from
the active theme's [ui-variables.less][ui-variables]. For more information, see the
[theme variables docs][theme-variables]. If you follow this guideline, your package
will look good out of the box with any theme!
If you _do_ need special styling, try to keep only structural styles in the
package style sheets. If you _must_ specify colors and sizing, these should be
taken from the active theme's [ui-variables.less][ui-variables]. For more
information, see the [theme variables docs][theme-variables]. If you follow this
guideline, your package will look good out of the box with any theme!
An optional `stylesheets` array in your _package.json_ can list the stylesheets
by name to specify a loading order; otherwise, stylesheets are loaded
An optional `stylesheets` array in your _package.json_ can list the style sheets
by name to specify a loading order; otherwise, style sheets are loaded
alphabetically.
## Keymaps
@@ -157,9 +157,9 @@ loaded in alphabetical order. An optional `keymaps` array in your _package.json_
can specify which keymaps to load and in what order.
Keybindings are executed by determining which element the keypress occurred on. In
the example above, `changer:magic` command is executed when pressing `ctrl-V` on
the `.tree-view-scroller` element.
Keybindings are executed by determining which element the keypress occurred on.
In the example above, `changer:magic` command is executed when pressing `ctrl-V`
on the `.tree-view-scroller` element.
See the [main keymaps documentation][keymaps] for more detailed information on
how keymaps work.
@@ -195,7 +195,8 @@ with your package that aren't tied to a specific element:
```
To add your own item to the application menu, simply create a top level `menu`
key in any menu configuration file in _menus_. This can be a JSON or [CSON] file.
key in any menu configuration file in _menus_. This can be a JSON or [CSON]
file.
The menu templates you specify are merged with all other templates provided
by other packages in the order which they were loaded.
-1
Ver Arquivo
@@ -118,7 +118,6 @@ You can open this file in an editor from the _Atom > Open Your Config_ menu.
- `cr`: Carriage return (for Microsoft-style line endings)
- `eol`: `\n` characters
- `space`: Leading and trailing space characters
- `normalizeIndentOnPaste`: Enable/disable conversion of pasted tabs to spaces
- `preferredLineLength`: Identifies the length of a line (defaults to `80`)
- `showInvisibles`: Whether to render placeholders for invisible characters (defaults to `false`)
- `showIndentGuide`: Show/hide indent indicators within the editor
-1
Ver Arquivo
@@ -18,7 +18,6 @@
* [Developing Node Modules](advanced/node-modules.md)
* [Keymaps](advanced/keymaps.md)
* [Serialization](advanced/serialization.md)
* [View System](advanced/view-system.md)
* [Scopes and Scope Descriptors](advanced/scopes-and-scope-descriptors.md)
### Upgrading to 1.0 APIs
+12 -12
Ver Arquivo
@@ -49,7 +49,7 @@ Register the command in _lib/ascii-art.coffee_:
```coffeescript
module.exports =
activate: ->
atom.workspaceView.command "ascii-art:convert", => @convert()
atom.commands.add 'atom-workspace', "ascii-art:convert", => @convert()
convert: ->
# This assumes the active pane item is an editor
@@ -57,10 +57,10 @@ module.exports =
editor.insertText('Hello, World!')
```
The `atom.workspaceView.command` method takes a command name and a callback. The
callback executes when the command is triggered. In this case, when the command
is triggered the callback will call the `convert` method and insert 'Hello,
World!'.
The `atom.commands.add` method takes a selector, command name, and a callback.
The callback executes when the command is triggered on an element matching the
selector. In this case, when the command is triggered the callback will call the
`convert` method and insert 'Hello, World!'.
## Reload the Package
@@ -95,13 +95,13 @@ you don't need it anymore. When finished, the file will look like this:
'cmd-alt-a': 'ascii-art:convert'
```
Notice `atom-text-editor` on the first line. Just like CSS, keymap selectors *scope* key
bindings so they only apply to specific elements. In this case, our binding is
only active for elements matching the `atom-text-editor` selector. If the Tree View has
focus, pressing `cmd-alt-a` won't trigger the `ascii-art:convert` command. But
if the editor has focus, the `ascii-art:convert` method *will* be triggered.
More information on key bindings can be found in the
[keymaps](advanced/keymaps.html) documentation.
Notice `atom-text-editor` on the first line. Just like CSS, keymap selectors
*scope* key bindings so they only apply to specific elements. In this case, our
binding is only active for elements matching the `atom-text-editor` selector. If
the Tree View has focus, pressing `cmd-alt-a` won't trigger the
`ascii-art:convert` command. But if the editor has focus, the
`ascii-art:convert` method *will* be triggered. More information on key bindings
can be found in the [keymaps](advanced/keymaps.html) documentation.
Now reload the window and verify that the key binding works! You can also verify
that it **doesn't** work when the Tree View is focused.
+9 -7
Ver Arquivo
@@ -6,6 +6,7 @@ module.exports =
BufferedNodeProcess: require '../src/buffered-node-process'
BufferedProcess: require '../src/buffered-process'
GitRepository: require '../src/git-repository'
Notification: require '../src/notification'
Point: Point
Range: Range
Emitter: Emitter
@@ -32,7 +33,8 @@ unless process.env.ATOM_SHELL_INTERNAL_RUN_AS_NODE
Object.defineProperty module.exports, 'WorkspaceView', get: ->
deprecate """
Requiring `WorkspaceView` from `atom` is no longer supported.
Use `atom.view.getView(atom.workspace)` instead.
Use `document.querySelector('atom-workspace')` if you need to access
the workspace element.
"""
require '../src/workspace-view'
@@ -43,7 +45,7 @@ unless process.env.ATOM_SHELL_INTERNAL_RUN_AS_NODE
`{$} = require 'space-pen'`
or
`$ = require 'jquery'`
Add `"space-pen": "^3"` to your package dependencies.
Add `"space-pen": "^4"` to your package dependencies.
Or add `"jquery": "^2"` to your package dependencies.
"""
$
@@ -53,7 +55,7 @@ unless process.env.ATOM_SHELL_INTERNAL_RUN_AS_NODE
Requiring `$$` from `atom` is no longer supported.
Please require `space-pen` instead:
`{$$} = require 'space-pen'`
Add `"space-pen": "^3"` to your package dependencies.
Add `"space-pen": "^4"` to your package dependencies.
"""
$$
@@ -62,7 +64,7 @@ unless process.env.ATOM_SHELL_INTERNAL_RUN_AS_NODE
Requiring `$$$` from `atom` is no longer supported.
Please require `space-pen` instead:
`{$$$} = require 'space-pen'`
Add `"space-pen": "^3"` to your package dependencies.
Add `"space-pen": "^4"` to your package dependencies.
"""
$$$
@@ -71,7 +73,7 @@ unless process.env.ATOM_SHELL_INTERNAL_RUN_AS_NODE
Requiring `View` from `atom` is no longer supported.
Please require `space-pen` instead:
`{View} = require 'space-pen'`
Add `"space-pen": "^3"` to your package dependencies.
Add `"space-pen": "^4"` to your package dependencies.
"""
View
@@ -118,8 +120,8 @@ unless process.env.ATOM_SHELL_INTERNAL_RUN_AS_NODE
require 'react-atom-fork'
Object.defineProperty module.exports, 'Reactionary', get: ->
deprecate "Please require `reactionary` instead: `Reactionary = require 'reactionary'`. Add `\"reactionary\": \"^0.9\"` to your package dependencies."
require 'reactionary'
deprecate "Please require `reactionary-atom-fork` instead: `Reactionary = require 'reactionary-atom-fork'`. Add `\"reactionary-atom-fork\": \"^0.9\"` to your package dependencies."
require 'reactionary-atom-fork'
Object.defineProperty module.exports, 'Git', get: ->
deprecate "Please require `GitRepository` instead of `Git`: `{GitRepository} = require 'atom'`"
+38 -36
Ver Arquivo
@@ -1,7 +1,7 @@
{
"name": "atom",
"productName": "Atom",
"version": "0.148.0",
"version": "0.153.0",
"description": "A hackable text editor for the 21st Century.",
"main": "./src/browser/main.js",
"repository": {
@@ -17,10 +17,10 @@
"url": "http://github.com/atom/atom/raw/master/LICENSE.md"
}
],
"atomShellVersion": "0.19.2",
"atomShellVersion": "0.19.4",
"dependencies": {
"async": "0.2.6",
"atom-keymap": "^2.2.2",
"atom-keymap": "^2.3.0",
"bootstrap": "git+https://github.com/atom/bootstrap.git#6af81906189f1747fd6c93479e3d998ebe041372",
"clear-cut": "0.4.0",
"coffee-script": "1.7.0",
@@ -29,7 +29,7 @@
"emissary": "^1.3.1",
"event-kit": "0.7.2",
"first-mate": "^2.2.0",
"fs-plus": "^2.3.1",
"fs-plus": "^2.3.2",
"fstream": "0.1.24",
"fuzzaldrin": "^2.1",
"git-utils": "^2.1.5",
@@ -39,12 +39,13 @@
"jasmine-tagged": "^1.1.2",
"jquery": "^2.1.1",
"less-cache": "0.19.0",
"marked": "^0.3",
"mixto": "^1",
"mkdirp": "0.3.5",
"nslog": "^1.0.1",
"oniguruma": "^3.0.4",
"optimist": "0.4.0",
"pathwatcher": "^2.3.2",
"pathwatcher": "^2.3.5",
"property-accessors": "^1",
"q": "^1.0.1",
"random-words": "0.0.1",
@@ -57,91 +58,92 @@
"season": "^1.0.2",
"semver": "2.2.1",
"serializable": "^1",
"space-pen": "3.8.1",
"space-pen": "3.8.2",
"temp": "0.7.0",
"text-buffer": "^3.6.1",
"text-buffer": "^3.8.0",
"theorist": "^1.0.2",
"underscore-plus": "^1.6.1",
"vm-compatibility-layer": "0.1.0"
},
"packageDependencies": {
"atom-dark-syntax": "0.22.0",
"atom-dark-ui": "0.39.0",
"atom-dark-syntax": "0.23.0",
"atom-dark-ui": "0.42.0",
"atom-light-syntax": "0.22.0",
"atom-light-ui": "0.33.0",
"atom-light-ui": "0.36.0",
"base16-tomorrow-dark-theme": "0.22.0",
"base16-tomorrow-light-theme": "0.5.0",
"solarized-dark-syntax": "0.23.0",
"solarized-dark-syntax": "0.24.0",
"solarized-light-syntax": "0.13.0",
"archive-view": "0.37.0",
"autocomplete": "0.33.0",
"autocomplete": "0.33.1",
"autoflow": "0.18.0",
"autosave": "0.18.0",
"background-tips": "0.17.0",
"bookmarks": "0.30.0",
"bracket-matcher": "0.62.0",
"command-palette": "0.28.0",
"deprecation-cop": "0.14.0",
"command-palette": "0.29.0",
"deprecation-cop": "0.18.0",
"dev-live-reload": "0.35.0",
"encoding-selector": "0.7.0",
"encoding-selector": "0.8.0",
"exception-reporting": "0.20.0",
"find-and-replace": "0.147.0",
"fuzzy-finder": "0.60.0",
"git-diff": "0.43.0",
"go-to-line": "0.26.0",
"grammar-selector": "0.37.0",
"image-view": "0.40.0",
"image-view": "0.42.0",
"incompatible-packages": "0.10.0",
"keybinding-resolver": "0.20.0",
"link": "0.26.0",
"markdown-preview": "0.110.0",
"metrics": "0.39.0",
"notifications": "0.4.0",
"open-on-github": "0.30.0",
"package-generator": "0.32.0",
"release-notes": "0.36.0",
"settings-view": "0.161.0",
"snippets": "0.56.0",
"spell-check": "0.43.0",
"status-bar": "0.46.0",
"snippets": "0.57.0",
"spell-check": "0.44.0",
"status-bar": "0.48.0",
"styleguide": "0.30.0",
"symbols-view": "0.68.0",
"tabs": "0.56.0",
"timecop": "0.23.0",
"tree-view": "0.132.0",
"tree-view": "0.134.0",
"update-package-dependencies": "0.6.0",
"welcome": "0.19.0",
"whitespace": "0.26.0",
"wrap-guide": "0.24.0",
"language-c": "0.31.0",
"language-coffee-script": "0.38.0",
"language-css": "0.23.0",
"language-gfm": "0.53.0",
"language-coffee-script": "0.38.1",
"language-css": "0.23.1",
"language-gfm": "0.54.1",
"language-git": "0.9.0",
"language-go": "0.19.0",
"language-html": "0.26.0",
"language-hyperlink": "0.12.0",
"language-go": "0.19.1",
"language-html": "0.26.1",
"language-hyperlink": "0.12.2",
"language-java": "0.11.0",
"language-javascript": "0.43.0",
"language-javascript": "0.45.1",
"language-json": "0.8.0",
"language-less": "0.18.0",
"language-less": "0.18.1",
"language-make": "0.12.0",
"language-mustache": "0.10.0",
"language-mustache": "0.10.1",
"language-objective-c": "0.11.0",
"language-perl": "0.9.0",
"language-php": "0.18.0",
"language-property-list": "0.7.0",
"language-python": "0.24.0",
"language-ruby": "0.41.0",
"language-python": "0.24.1",
"language-ruby": "0.42.0",
"language-ruby-on-rails": "0.18.0",
"language-sass": "0.26.0",
"language-shellscript": "0.10.0",
"language-sass": "0.26.1",
"language-shellscript": "0.10.1",
"language-source": "0.8.0",
"language-sql": "0.11.0",
"language-text": "0.6.0",
"language-todo": "0.13.0",
"language-toml": "0.14.0",
"language-xml": "0.24.0",
"language-yaml": "0.20.0"
"language-toml": "0.14.1",
"language-xml": "0.25.0",
"language-yaml": "0.20.1"
},
"private": true,
"scripts": {
+1 -1
Ver Arquivo
@@ -1,4 +1,4 @@
{$} = require 'atom'
{$} = require '../src/space-pen-extensions'
describe '"atom" protocol URL', ->
it 'sends the file relative in the package as response', ->
+3 -1
Ver Arquivo
@@ -3,6 +3,7 @@ _ = require 'underscore-plus'
{convertStackTrace} = require 'coffeestack'
{View, $, $$} = require '../src/space-pen-extensions'
grim = require 'grim'
marked = require 'marked'
sourceMaps = {}
formatStackTrace = (spec, message='', stackTrace) ->
@@ -110,7 +111,8 @@ class AtomReporter extends View
for deprecation in deprecations
@deprecationList.append $$ ->
@div class: 'padded', =>
@div class: 'result-message fail deprecation-message', deprecation.message
@div class: 'result-message fail deprecation-message', =>
@raw marked(deprecation.message)
for stack in deprecation.stacks
fullStack = stack.map ({functionName, location}) ->
+13 -10
Ver Arquivo
@@ -1,13 +1,10 @@
{$, $$, WorkspaceView} = require 'atom'
{$, $$} = require '../src/space-pen-extensions'
Exec = require('child_process').exec
path = require 'path'
Package = require '../src/package'
ThemeManager = require '../src/theme-manager'
describe "the `atom` global", ->
beforeEach ->
atom.workspaceView = atom.views.getView(atom.workspace).__spacePenView
describe 'window sizing methods', ->
describe '::getPosition and ::setPosition', ->
it 'sets the position of the window, and can retrieve the position just set', ->
@@ -33,10 +30,16 @@ describe "the `atom` global", ->
version = '36b5518'
expect(atom.isReleasedVersion()).toBe false
describe "window:update-available", ->
it "is triggered when the auto-updater sends the update-downloaded event", ->
describe "when an update becomes available", ->
subscription = null
afterEach ->
subscription?.dispose()
it "invokes onUpdateAvailable listeners", ->
updateAvailableHandler = jasmine.createSpy("update-available-handler")
atom.workspaceView.on 'window:update-available', updateAvailableHandler
subscription = atom.onUpdateAvailable updateAvailableHandler
autoUpdater = require('remote').require('auto-updater')
autoUpdater.emit 'update-downloaded', null, "notes", "version"
@@ -44,9 +47,9 @@ describe "the `atom` global", ->
updateAvailableHandler.callCount > 0
runs ->
[event, version, notes] = updateAvailableHandler.mostRecentCall.args
expect(notes).toBe 'notes'
expect(version).toBe 'version'
{releaseVersion, releaseNotes} = updateAvailableHandler.mostRecentCall.args[0]
expect(releaseVersion).toBe 'version'
expect(releaseNotes).toBe 'notes'
describe "loading default config", ->
it 'loads the default core config', ->
+15 -2
Ver Arquivo
@@ -128,6 +128,12 @@ describe "Config", ->
expect(atom.config.get("foo")).toEqual 'a\\.b': 1, b: 2
describe ".toggle(keyPath)", ->
beforeEach ->
jasmine.snapshotDeprecations()
afterEach ->
jasmine.restoreDeprecationsSnapshot()
it "negates the boolean value of the current key path value", ->
atom.config.set('foo.a', 1)
atom.config.toggle('foo.a')
@@ -298,6 +304,12 @@ describe "Config", ->
expect(observeHandler).toHaveBeenCalledWith atom.config.get("foo.bar.baz")
describe ".getPositiveInt(keyPath, defaultValue)", ->
beforeEach ->
jasmine.snapshotDeprecations()
afterEach ->
jasmine.restoreDeprecationsSnapshot()
it "returns the proper coerced value", ->
atom.config.set('editor.preferredLineLength', 0)
expect(atom.config.getPositiveInt('editor.preferredLineLength', 80)).toBe 1
@@ -470,7 +482,7 @@ describe "Config", ->
it "does not fire the callback once the observe subscription is off'ed", ->
observeHandler.reset() # clear the initial call
observeSubscription.off()
observeSubscription.dispose()
atom.config.set('foo.bar.baz', "value 2")
expect(observeHandler).not.toHaveBeenCalled()
@@ -554,11 +566,13 @@ describe "Config", ->
describe "when the config file contains invalid cson", ->
beforeEach ->
spyOn(console, 'error')
spyOn(atom.notifications, 'addError')
fs.writeFileSync(atom.config.configFilePath, "{{{{{")
it "logs an error to the console and does not overwrite the config file on a subsequent save", ->
atom.config.loadUserConfig()
expect(console.error).toHaveBeenCalled()
expect(atom.notifications.addError.callCount).toBe 1
atom.config.set("hair", "blonde") # trigger a save
expect(atom.config.save).not.toHaveBeenCalled()
@@ -692,7 +706,6 @@ describe "Config", ->
expect(atom.config.get(['.source.ruby'], 'foo.bar')).toBe 'baz'
expect(atom.config.get(['.source.ruby'], 'foo.scoped')).toBe true
describe "when the config file changes to omit a setting with a default", ->
it "resets the setting back to the default", ->
fs.writeFileSync(atom.config.configFilePath, "foo: { baz: 'new'}")
+28 -21
Ver Arquivo
@@ -1,4 +1,4 @@
{$$} = require 'atom'
{$$} = require '../src/space-pen-extensions'
ContextMenuManager = require '../src/context-menu-manager'
@@ -151,24 +151,31 @@ describe "ContextMenuManager", ->
shouldDisplay = false
expect(contextMenu.templateForEvent(dispatchedEvent)).toEqual []
it "allows items to be specified in the legacy format for now", ->
contextMenu.add '.parent':
'A': 'a'
'Separator 1': '-'
'B':
'C': 'c'
'Separator 2': '-'
'D': 'd'
describe "when the menus are specified in a legacy format", ->
beforeEach ->
jasmine.snapshotDeprecations()
expect(contextMenu.templateForElement(parent)).toEqual [
{label: 'A', command: 'a'}
{type: 'separator'}
{
label: 'B'
submenu: [
{label: 'C', command: 'c'}
{type: 'separator'}
{label: 'D', command: 'd'}
]
}
]
afterEach ->
jasmine.restoreDeprecationsSnapshot()
it "allows items to be specified in the legacy format for now", ->
contextMenu.add '.parent':
'A': 'a'
'Separator 1': '-'
'B':
'C': 'c'
'Separator 2': '-'
'D': 'd'
expect(contextMenu.templateForElement(parent)).toEqual [
{label: 'A', command: 'a'}
{type: 'separator'}
{
label: 'B'
submenu: [
{label: 'C', command: 'c'}
{type: 'separator'}
{label: 'D', command: 'd'}
]
}
]
@@ -9,5 +9,6 @@ module.exports =
atom.commands.add 'atom-workspace', 'activation-command', =>
@activationCommandCallCount++
atom.workspaceView.getActiveView()?.command 'activation-command', =>
editorView = document.querySelector('atom-workspace').getView(atom.workspace.getActiveEditor())?.__spacePenView
editorView?.command 'activation-command', =>
@legacyActivationCommandCallCount++
@@ -3,5 +3,6 @@
]
'context-menu':
'.test-1':
'Menu item 1': 'command-1'
'.test-1': [
{label: 'Menu item 1', command: 'command-1'}
]
@@ -3,5 +3,6 @@
]
'context-menu':
'.test-1':
'Menu item 2': 'command-2'
'.test-1': [
{label: 'Menu item 2', command: 'command-2'}
]
@@ -1,3 +1,4 @@
'context-menu':
'.test-1':
'Menu item 3': 'command-3'
'.test-1': [
{label: 'Menu item 3', command: 'command-3'}
]
+57
Ver Arquivo
@@ -0,0 +1,57 @@
NotificationManager = require '../src/notification-manager'
describe "NotificationManager", ->
[manager] = []
beforeEach ->
manager = new NotificationManager
describe "the atom global", ->
it "has a notifications instance", ->
expect(atom.notifications instanceof NotificationManager).toBe true
describe "adding events", ->
addSpy = null
beforeEach ->
addSpy = jasmine.createSpy()
manager.onDidAddNotification(addSpy)
it "emits an event when a notification has been added", ->
manager.add('error', 'Some error!', icon: 'someIcon')
expect(addSpy).toHaveBeenCalled()
notification = addSpy.mostRecentCall.args[0]
expect(notification.getType()).toBe 'error'
expect(notification.getMessage()).toBe 'Some error!'
expect(notification.getIcon()).toBe 'someIcon'
it "emits a fatal error ::addFatalError has been called", ->
manager.addFatalError('Some error!', icon: 'someIcon')
expect(addSpy).toHaveBeenCalled()
notification = addSpy.mostRecentCall.args[0]
expect(notification.getType()).toBe 'fatal'
it "emits an error ::addError has been called", ->
manager.addError('Some error!', icon: 'someIcon')
expect(addSpy).toHaveBeenCalled()
notification = addSpy.mostRecentCall.args[0]
expect(notification.getType()).toBe 'error'
it "emits a warning notification ::addWarning has been called", ->
manager.addWarning('Something!', icon: 'someIcon')
expect(addSpy).toHaveBeenCalled()
notification = addSpy.mostRecentCall.args[0]
expect(notification.getType()).toBe 'warning'
it "emits an info notification ::addInfo has been called", ->
manager.addInfo('Something!', icon: 'someIcon')
expect(addSpy).toHaveBeenCalled()
notification = addSpy.mostRecentCall.args[0]
expect(notification.getType()).toBe 'info'
it "emits a success notification ::addSuccess has been called", ->
manager.addSuccess('Something!', icon: 'someIcon')
expect(addSpy).toHaveBeenCalled()
notification = addSpy.mostRecentCall.args[0]
expect(notification.getType()).toBe 'success'
+18
Ver Arquivo
@@ -0,0 +1,18 @@
Notification = require '../src/notification'
describe "Notification", ->
[notification] = []
describe "::getTimestamp()", ->
it "returns a Date object", ->
notification = new Notification('error', 'message!')
expect(notification.getTimestamp() instanceof Date).toBe true
describe "::getIcon()", ->
it "returns a default when no icon specified", ->
notification = new Notification('error', 'message!')
expect(notification.getIcon()).toBe 'flame'
it "returns the icon specified", ->
notification = new Notification('error', 'message!', icon: 'my-icon')
expect(notification.getIcon()).toBe 'my-icon'
+37 -26
Ver Arquivo
@@ -1,9 +1,10 @@
{$, $$, WorkspaceView} = require 'atom'
{$, $$} = require '../src/space-pen-extensions'
Package = require '../src/package'
describe "PackageManager", ->
workspaceElement = null
beforeEach ->
atom.workspaceView = atom.views.getView(atom.workspace).__spacePenView
workspaceElement = atom.views.createView(atom.workspace)
describe "::loadPackage(name)", ->
it "continues if the package has an invalid package.json", ->
@@ -97,21 +98,29 @@ describe "PackageManager", ->
expect(atom.config.set('package-with-config-schema.numbers.one', '10')).toBe true
expect(atom.config.get('package-with-config-schema.numbers.one')).toBe 10
it "still assigns configDefaults from the module though deprecated", ->
expect(atom.config.get('package-with-config-defaults.numbers.one')).toBeUndefined()
describe "when a package has configDefaults", ->
beforeEach ->
jasmine.snapshotDeprecations()
waitsForPromise ->
atom.packages.activatePackage('package-with-config-defaults')
afterEach ->
jasmine.restoreDeprecationsSnapshot()
runs ->
expect(atom.config.get('package-with-config-defaults.numbers.one')).toBe 1
expect(atom.config.get('package-with-config-defaults.numbers.two')).toBe 2
it "still assigns configDefaults from the module though deprecated", ->
expect(atom.config.get('package-with-config-defaults.numbers.one')).toBeUndefined()
waitsForPromise ->
atom.packages.activatePackage('package-with-config-defaults')
runs ->
expect(atom.config.get('package-with-config-defaults.numbers.one')).toBe 1
expect(atom.config.get('package-with-config-defaults.numbers.two')).toBe 2
describe "when the package metadata includes `activationCommands`", ->
[mainModule, promise, workspaceCommandListener] = []
beforeEach ->
atom.workspaceView.attachToDom()
jasmine.attachToDOM(workspaceElement)
mainModule = require './fixtures/packages/package-with-activation-commands/index'
mainModule.legacyActivationCommandCallCount = 0
mainModule.activationCommandCallCount = 0
@@ -125,29 +134,29 @@ describe "PackageManager", ->
it "defers requiring/activating the main module until an activation event bubbles to the root view", ->
expect(promise.isFulfilled()).not.toBeTruthy()
atom.workspaceView[0].dispatchEvent(new CustomEvent('activation-command', bubbles: true))
workspaceElement.dispatchEvent(new CustomEvent('activation-command', bubbles: true))
waitsForPromise ->
promise
it "triggers the activation event on all handlers registered during activation", ->
waitsForPromise ->
atom.workspaceView.open()
atom.workspace.open()
runs ->
editorView = atom.workspaceView.getActiveView()
editorView = workspaceElement.getView(atom.workspace.getActiveEditor()).__spacePenView
legacyCommandListener = jasmine.createSpy("legacyCommandListener")
editorView.command 'activation-command', legacyCommandListener
editorCommandListener = jasmine.createSpy("editorCommandListener")
atom.commands.add 'atom-text-editor', 'activation-command', editorCommandListener
editorView[0].dispatchEvent(new CustomEvent('activation-command', bubbles: true))
atom.commands.dispatch(editorView[0], 'activation-command')
expect(mainModule.activate.callCount).toBe 1
expect(mainModule.legacyActivationCommandCallCount).toBe 1
expect(mainModule.activationCommandCallCount).toBe 1
expect(legacyCommandListener.callCount).toBe 1
expect(editorCommandListener.callCount).toBe 1
expect(workspaceCommandListener.callCount).toBe 1
editorView[0].dispatchEvent(new CustomEvent('activation-command', bubbles: true))
atom.commands.dispatch(editorView[0], 'activation-command')
expect(mainModule.legacyActivationCommandCallCount).toBe 2
expect(mainModule.activationCommandCallCount).toBe 2
expect(legacyCommandListener.callCount).toBe 2
@@ -349,8 +358,8 @@ describe "PackageManager", ->
atom.packages.activatePackage('package-with-grammars')
runs ->
expect(atom.syntax.selectGrammar('a.alot').name).toBe 'Alot'
expect(atom.syntax.selectGrammar('a.alittle').name).toBe 'Alittle'
expect(atom.grammars.selectGrammar('a.alot').name).toBe 'Alot'
expect(atom.grammars.selectGrammar('a.alittle').name).toBe 'Alittle'
describe "scoped-property loading", ->
it "loads the scoped properties", ->
@@ -362,13 +371,13 @@ describe "PackageManager", ->
describe "converted textmate packages", ->
it "loads the package's grammars", ->
expect(atom.syntax.selectGrammar("file.rb").name).toBe "Null Grammar"
expect(atom.grammars.selectGrammar("file.rb").name).toBe "Null Grammar"
waitsForPromise ->
atom.packages.activatePackage('language-ruby')
runs ->
expect(atom.syntax.selectGrammar("file.rb").name).toBe "Ruby"
expect(atom.grammars.selectGrammar("file.rb").name).toBe "Ruby"
it "loads the translated scoped properties", ->
expect(atom.config.get(['.source.ruby'], 'editor.commentStart')).toBeUndefined()
@@ -454,8 +463,8 @@ describe "PackageManager", ->
runs ->
atom.packages.deactivatePackage('package-with-grammars')
expect(atom.syntax.selectGrammar('a.alot').name).toBe 'Null Grammar'
expect(atom.syntax.selectGrammar('a.alittle').name).toBe 'Null Grammar'
expect(atom.grammars.selectGrammar('a.alot').name).toBe 'Null Grammar'
expect(atom.grammars.selectGrammar('a.alittle').name).toBe 'Null Grammar'
it "removes the package's keymaps", ->
waitsForPromise ->
@@ -490,15 +499,15 @@ describe "PackageManager", ->
describe "textmate packages", ->
it "removes the package's grammars", ->
expect(atom.syntax.selectGrammar("file.rb").name).toBe "Null Grammar"
expect(atom.grammars.selectGrammar("file.rb").name).toBe "Null Grammar"
waitsForPromise ->
atom.packages.activatePackage('language-ruby')
runs ->
expect(atom.syntax.selectGrammar("file.rb").name).toBe "Ruby"
expect(atom.grammars.selectGrammar("file.rb").name).toBe "Ruby"
atom.packages.deactivatePackage('language-ruby')
expect(atom.syntax.selectGrammar("file.rb").name).toBe "Null Grammar"
expect(atom.grammars.selectGrammar("file.rb").name).toBe "Null Grammar"
it "removes the package's scoped properties", ->
waitsForPromise ->
@@ -513,6 +522,7 @@ describe "PackageManager", ->
themeActivator = null
beforeEach ->
jasmine.snapshotDeprecations()
spyOn(console, 'warn')
atom.packages.loadPackages()
@@ -526,8 +536,9 @@ describe "PackageManager", ->
atom.packages.deactivatePackages()
atom.packages.unloadPackages()
Syntax = require '../src/syntax'
atom.syntax = window.syntax = new Syntax()
GrammarRegistry = require '../src/grammar-registry'
atom.grammars = window.syntax = new GrammarRegistry()
jasmine.restoreDeprecationsSnapshot()
it "activates all the packages, and none of the themes", ->
atom.packages.activate()
+1 -1
Ver Arquivo
@@ -1,4 +1,4 @@
{$} = require 'atom'
{$} = require '../src/space-pen-extensions'
path = require 'path'
Package = require '../src/package'
ThemePackage = require '../src/theme-package'
+13 -8
Ver Arquivo
@@ -3,10 +3,12 @@ temp = require 'temp'
PaneContainer = require '../src/pane-container'
PaneContainerView = require '../src/pane-container-view'
PaneView = require '../src/pane-view'
{$, View, $$} = require 'atom'
{Disposable} = require 'event-kit'
{$, View, $$} = require '../src/space-pen-extensions'
ViewRegistry = require '../src/view-registry'
describe "PaneContainerView", ->
[TestView, container, pane1, pane2, pane3, deserializerDisposable] = []
[viewRegistry, TestView, container, pane1, pane2, pane3, deserializerDisposable] = []
beforeEach ->
class TestView extends View
@@ -18,8 +20,11 @@ describe "PaneContainerView", ->
getUri: -> path.join(temp.dir, @name)
save: -> @saved = true
isEqual: (other) -> @name is other?.name
onDidChangeTitle: -> new Disposable(->)
onDidChangeModified: -> new Disposable(->)
container = atom.views.getView(atom.workspace.paneContainer).__spacePenView
viewRegistry = new ViewRegistry(atom.views)
container = atom.views.createView(atom.workspace.paneContainer, {viewRegistry}).__spacePenView
pane1 = container.getRoot()
pane1.activateItem(new TestView('1'))
pane2 = pane1.splitRight(new TestView('2'))
@@ -73,7 +78,7 @@ describe "PaneContainerView", ->
describe "serialization", ->
it "can be serialized and deserialized, and correctly adjusts dimensions of deserialized panes after attach", ->
newContainer = atom.views.getView(container.model.testSerialization()).__spacePenView
newContainer = atom.views.createView(container.model.testSerialization(), {viewRegistry}).__spacePenView
expect(newContainer.find('atom-pane-axis.horizontal > :contains(1)')).toExist()
expect(newContainer.find('atom-pane-axis.horizontal > atom-pane-axis.vertical > :contains(2)')).toExist()
expect(newContainer.find('atom-pane-axis.horizontal > atom-pane-axis.vertical > :contains(3)')).toExist()
@@ -89,14 +94,14 @@ describe "PaneContainerView", ->
describe "if the 'core.destroyEmptyPanes' config option is false (the default)", ->
it "leaves the empty panes intact", ->
newContainer = atom.views.getView(container.model.testSerialization()).__spacePenView
newContainer = atom.views.createView(container.model.testSerialization(), {viewRegistry}).__spacePenView
expect(newContainer.find('atom-pane-axis.horizontal > :contains(1)')).toExist()
expect(newContainer.find('atom-pane-axis.horizontal > atom-pane-axis.vertical > atom-pane').length).toBe 2
describe "if the 'core.destroyEmptyPanes' config option is true", ->
it "removes empty panes on deserialization", ->
atom.config.set('core.destroyEmptyPanes', true)
newContainer = atom.views.getView(container.model.testSerialization()).__spacePenView
newContainer = atom.views.createView(container.model.testSerialization(), {viewRegistry}).__spacePenView
expect(newContainer.find('atom-pane-axis.horizontal, atom-pane-axis.vertical')).not.toExist()
expect(newContainer.find('> :contains(1)')).toExist()
@@ -109,7 +114,7 @@ describe "PaneContainerView", ->
item2b = new TestView('2b')
item3a = new TestView('3a')
container = atom.views.getView(new PaneContainer).__spacePenView
container = atom.views.createView(new PaneContainer, {viewRegistry}).__spacePenView
pane1 = container.getRoot()
pane1.activateItem(item1a)
container.attachToDom()
@@ -259,7 +264,7 @@ describe "PaneContainerView", ->
# |7|8|9|
# -------
container = atom.views.getView(new PaneContainer).__spacePenView
container = atom.views.createView(new PaneContainer, {viewRegistry}).__spacePenView
pane1 = container.getRoot()
pane1.activateItem(new TestView('1'))
pane4 = pane1.splitDown(new TestView('4'))
+22 -11
Ver Arquivo
@@ -1,13 +1,14 @@
PaneContainer = require '../src/pane-container'
PaneView = require '../src/pane-view'
ViewRegistry = require '../src/view-registry'
fs = require 'fs-plus'
{Emitter} = require 'event-kit'
{$, View} = require 'atom'
{Emitter, Disposable} = require 'event-kit'
{$, View} = require '../src/space-pen-extensions'
path = require 'path'
temp = require 'temp'
describe "PaneView", ->
[container, containerModel, view1, view2, editor1, editor2, pane, paneModel, deserializerDisposable] = []
[viewRegistry, container, containerModel, view1, view2, editor1, editor2, pane, paneModel, deserializerDisposable] = []
class TestView extends View
@deserialize: ({id, text}) -> new TestView({id, text})
@@ -21,10 +22,14 @@ describe "PaneView", ->
@emitter.emit 'did-change-title', 'title'
onDidChangeTitle: (callback) ->
@emitter.on 'did-change-title', callback
onDidChangeModified: -> new Disposable(->)
beforeEach ->
jasmine.snapshotDeprecations()
deserializerDisposable = atom.deserializers.add(TestView)
container = atom.views.getView(new PaneContainer).__spacePenView
viewRegistry = new ViewRegistry(atom.views)
container = atom.views.createView(new PaneContainer, {viewRegistry}).__spacePenView
containerModel = container.model
view1 = new TestView(id: 'view-1', text: 'View 1')
view2 = new TestView(id: 'view-2', text: 'View 2')
@@ -41,6 +46,7 @@ describe "PaneView", ->
afterEach ->
deserializerDisposable.dispose()
jasmine.restoreDeprecationsSnapshot()
describe "when the active pane item changes", ->
it "hides all item views except the active one", ->
@@ -155,14 +161,19 @@ describe "PaneView", ->
expect(view1.is(':visible')).toBe true
describe "when the title of the active item changes", ->
describe 'when there is no onDidChangeTitle method', ->
describe 'when there is no onDidChangeTitle method (deprecated)', ->
beforeEach ->
jasmine.snapshotDeprecations()
view1.onDidChangeTitle = null
view2.onDidChangeTitle = null
pane.activateItem(view2)
pane.activateItem(view1)
afterEach ->
jasmine.restoreDeprecationsSnapshot()
it "emits pane:active-item-title-changed", ->
activeItemTitleChangedHandler = jasmine.createSpy("activeItemTitleChangedHandler")
pane.on 'pane:active-item-title-changed', activeItemTitleChangedHandler
@@ -220,7 +231,7 @@ describe "PaneView", ->
beforeEach ->
pane2Model = paneModel.splitRight() # Can't destroy the last pane, so we add another
pane2 = containerModel.getView(pane2Model).__spacePenView
pane2 = viewRegistry.getView(pane2Model).__spacePenView
it "triggers a 'pane:removed' event with the pane", ->
removedHandler = jasmine.createSpy("removedHandler")
@@ -253,7 +264,7 @@ describe "PaneView", ->
beforeEach ->
pane2Model = paneModel.splitRight(items: [pane.copyActiveItem()])
pane2 = containerModel.getView(pane2Model).__spacePenView
pane2 = viewRegistry.getView(pane2Model).__spacePenView
expect(pane2Model.isActive()).toBe true
it "adds or removes the .active class as appropriate", ->
@@ -300,8 +311,8 @@ describe "PaneView", ->
pane2Model = pane1Model.splitRight(items: [pane1Model.copyActiveItem()])
pane3Model = pane2Model.splitDown(items: [pane2Model.copyActiveItem()])
pane2 = pane2Model._view
pane2 = containerModel.getView(pane2Model).__spacePenView
pane3 = containerModel.getView(pane3Model).__spacePenView
pane2 = viewRegistry.getView(pane2Model).__spacePenView
pane3 = viewRegistry.getView(pane3Model).__spacePenView
expect(container.find('> atom-pane-axis.horizontal > atom-pane').toArray()).toEqual [pane1[0]]
expect(container.find('> atom-pane-axis.horizontal > atom-pane-axis.vertical > atom-pane').toArray()).toEqual [pane2[0], pane3[0]]
@@ -314,13 +325,13 @@ describe "PaneView", ->
container.attachToDom()
pane.focus()
container2 = atom.views.getView(container.model.testSerialization()).__spacePenView
container2 = viewRegistry.getView(container.model.testSerialization()).__spacePenView
pane2 = container2.getRoot()
container2.attachToDom()
expect(pane2).toMatchSelector(':has(:focus)')
$(document.activeElement).blur()
container3 = atom.views.getView(container.model.testSerialization()).__spacePenView
container3 = viewRegistry.getView(container.model.testSerialization()).__spacePenView
pane3 = container3.getRoot()
container3.attachToDom()
expect(pane3).not.toMatchSelector(':has(:focus)')
+56 -27
Ver Arquivo
@@ -1,8 +1,8 @@
ViewRegistry = require '../src/view-registry'
Panel = require '../src/panel'
PanelElement = require '../src/panel-element'
PanelContainer = require '../src/panel-container'
PanelContainerElement = require '../src/panel-container-element'
ViewRegistry = require '../src/view-registry'
describe "PanelContainerElement", ->
[jasmineContent, element, container, viewRegistry] = []
@@ -13,25 +13,26 @@ describe "PanelContainerElement", ->
class TestPanelContainerItemElement extends HTMLElement
createdCallback: ->
@classList.add('test-root')
setModel: (@model) ->
initialize: ({@model}) ->
TestPanelContainerItemElement = document.registerElement 'atom-test-container-item-element', prototype: TestPanelContainerItemElement.prototype
beforeEach ->
jasmineContent = document.body.querySelector('#jasmine-content')
viewRegistry = new ViewRegistry
viewRegistry.addViewProvider
atom.views.addViewProvider
modelConstructor: Panel
viewConstructor: PanelElement
viewRegistry.addViewProvider
atom.views.addViewProvider
modelConstructor: PanelContainer
viewConstructor: PanelContainerElement
viewRegistry.addViewProvider
atom.views.addViewProvider
modelConstructor: TestPanelContainerItem
viewConstructor: TestPanelContainerItemElement
container = new PanelContainer({viewRegistry, location: 'left'})
element = container.getView()
container = new PanelContainer({location: 'left'})
viewRegistry = new ViewRegistry(atom.views)
element = viewRegistry.getView(container, {viewRegistry})
jasmineContent.appendChild(element)
it 'has a location class with value from the model', ->
@@ -43,23 +44,38 @@ describe "PanelContainerElement", ->
expect(element.parentNode).not.toBe jasmineContent
describe "adding and removing panels", ->
it "allows panels to be inserted at any position", ->
panel1 = new Panel({item: new TestPanelContainerItem(), priority: 10})
panel2 = new Panel({item: new TestPanelContainerItem(), priority: 5})
panel3 = new Panel({item: new TestPanelContainerItem(), priority: 8})
container.addPanel(panel1)
container.addPanel(panel2)
container.addPanel(panel3)
expect(element.childNodes[2].getModel()).toBe(panel1)
expect(element.childNodes[1].getModel()).toBe(panel3)
expect(element.childNodes[0].getModel()).toBe(panel2)
describe "when the container is at the left location", ->
it "adds atom-panel elements when a new panel is added to the container; removes them when the panels are destroyed", ->
expect(element.childNodes.length).toBe 0
panel1 = new Panel({viewRegistry, item: new TestPanelContainerItem()})
panel1 = new Panel({item: new TestPanelContainerItem()})
container.addPanel(panel1)
expect(element.childNodes.length).toBe 1
expect(element.childNodes[0]).toHaveClass 'left'
expect(element.childNodes[0]).toHaveClass 'tool-panel' # legacy selector support
expect(element.childNodes[0]).toHaveClass 'panel-left' # legacy selector support
expect(element.childNodes[0].tagName).toBe 'ATOM-PANEL'
panel2 = new Panel({viewRegistry, item: new TestPanelContainerItem()})
panel2 = new Panel({item: new TestPanelContainerItem()})
container.addPanel(panel2)
expect(element.childNodes.length).toBe 2
expect(panel1.getView().style.display).not.toBe 'none'
expect(panel2.getView().style.display).not.toBe 'none'
expect(viewRegistry.getView(panel1).style.display).not.toBe 'none'
expect(viewRegistry.getView(panel2).style.display).not.toBe 'none'
panel1.destroy()
expect(element.childNodes.length).toBe 1
@@ -69,24 +85,26 @@ describe "PanelContainerElement", ->
describe "when the container is at the bottom location", ->
beforeEach ->
container = new PanelContainer({viewRegistry, location: 'bottom'})
element = container.getView()
container = new PanelContainer({location: 'bottom'})
element = viewRegistry.getView(container)
jasmineContent.appendChild(element)
it "adds atom-panel elements when a new panel is added to the container; removes them when the panels are destroyed", ->
expect(element.childNodes.length).toBe 0
panel1 = new Panel({viewRegistry, item: new TestPanelContainerItem(), className: 'one'})
panel1 = new Panel({item: new TestPanelContainerItem(), className: 'one'})
container.addPanel(panel1)
expect(element.childNodes.length).toBe 1
expect(element.childNodes[0]).toHaveClass 'bottom'
expect(element.childNodes[0]).toHaveClass 'tool-panel' # legacy selector support
expect(element.childNodes[0]).toHaveClass 'panel-bottom' # legacy selector support
expect(element.childNodes[0].tagName).toBe 'ATOM-PANEL'
expect(panel1.getView()).toHaveClass 'one'
expect(viewRegistry.getView(panel1)).toHaveClass 'one'
panel2 = new Panel({viewRegistry, item: new TestPanelContainerItem(), className: 'two'})
panel2 = new Panel({item: new TestPanelContainerItem(), className: 'two'})
container.addPanel(panel2)
expect(element.childNodes.length).toBe 2
expect(panel2.getView()).toHaveClass 'two'
expect(viewRegistry.getView(panel2)).toHaveClass 'two'
panel1.destroy()
expect(element.childNodes.length).toBe 1
@@ -96,23 +114,34 @@ describe "PanelContainerElement", ->
describe "when the container is modal", ->
beforeEach ->
container = new PanelContainer({viewRegistry, location: 'modal'})
element = container.getView()
container = new PanelContainer({location: 'modal'})
element = viewRegistry.getView(container)
jasmineContent.appendChild(element)
it "allows only one panel to be visible at a time", ->
panel1 = new Panel({viewRegistry, item: new TestPanelContainerItem()})
panel1 = new Panel({item: new TestPanelContainerItem()})
container.addPanel(panel1)
expect(panel1.getView().style.display).not.toBe 'none'
expect(viewRegistry.getView(panel1).style.display).not.toBe 'none'
panel2 = new Panel({viewRegistry, item: new TestPanelContainerItem()})
panel2 = new Panel({item: new TestPanelContainerItem()})
container.addPanel(panel2)
expect(panel1.getView().style.display).toBe 'none'
expect(panel2.getView().style.display).not.toBe 'none'
expect(viewRegistry.getView(panel1).style.display).toBe 'none'
expect(viewRegistry.getView(panel2).style.display).not.toBe 'none'
panel1.show()
expect(panel1.getView().style.display).not.toBe 'none'
expect(panel2.getView().style.display).toBe 'none'
expect(viewRegistry.getView(panel1).style.display).not.toBe 'none'
expect(viewRegistry.getView(panel2).style.display).toBe 'none'
it "adds the 'modal' class to panels", ->
panel1 = new Panel({item: new TestPanelContainerItem()})
container.addPanel(panel1)
expect(viewRegistry.getView(panel1)).toHaveClass 'modal'
# legacy selector support
expect(viewRegistry.getView(panel1)).not.toHaveClass 'tool-panel'
expect(viewRegistry.getView(panel1)).toHaveClass 'overlay'
expect(viewRegistry.getView(panel1)).toHaveClass 'from-top'
+4 -6
Ver Arquivo
@@ -1,16 +1,14 @@
ViewRegistry = require '../src/view-registry'
Panel = require '../src/panel'
PanelContainer = require '../src/panel-container'
describe "PanelContainer", ->
[container, viewRegistry] = []
[container] = []
class TestPanelItem
constructior: ->
beforeEach ->
viewRegistry = new ViewRegistry
container = new PanelContainer({viewRegistry})
container = new PanelContainer
describe "::addPanel(panel)", ->
it 'emits an onDidAddPanel event with the index the panel was inserted at', ->
@@ -46,7 +44,7 @@ describe "PanelContainer", ->
[initialPanel] = []
beforeEach ->
# 'left' logic is the same as 'top'
container = new PanelContainer({viewRegistry, location: 'left'})
container = new PanelContainer({location: 'left'})
initialPanel = new Panel(item: new TestPanelItem())
container.addPanel(initialPanel)
@@ -75,7 +73,7 @@ describe "PanelContainer", ->
[initialPanel] = []
beforeEach ->
# 'bottom' logic is the same as 'right'
container = new PanelContainer({viewRegistry, location: 'right'})
container = new PanelContainer({location: 'right'})
initialPanel = new Panel(item: new TestPanelItem())
container.addPanel(initialPanel)
+20 -13
Ver Arquivo
@@ -1,6 +1,6 @@
ViewRegistry = require '../src/view-registry'
Panel = require '../src/panel'
PanelElement = require '../src/panel-element'
ViewRegistry = require '../src/view-registry'
describe "PanelElement", ->
[jasmineContent, element, panel, viewRegistry] = []
@@ -11,23 +11,30 @@ describe "PanelElement", ->
class TestPanelItemElement extends HTMLElement
createdCallback: ->
@classList.add('test-root')
setModel: (@model) ->
initialize: ({@model}) ->
TestPanelItemElement = document.registerElement 'atom-test-item-element', prototype: TestPanelItemElement.prototype
beforeEach ->
jasmineContent = document.body.querySelector('#jasmine-content')
viewRegistry = new ViewRegistry
viewRegistry.addViewProvider
atom.views.addViewProvider
modelConstructor: Panel
viewConstructor: PanelElement
viewRegistry.addViewProvider
atom.views.addViewProvider
modelConstructor: TestPanelItem
viewConstructor: TestPanelItemElement
viewRegistry = new ViewRegistry(atom.views)
it "renders a view for the panel's item", ->
panel = new Panel({item: new TestPanelItem})
element = atom.views.createView(panel, {viewRegistry})
jasmineContent.appendChild(element)
expect(element.firstChild).toBe viewRegistry.getView(panel.getItem())
it 'removes the element when the panel is destroyed', ->
panel = new Panel({viewRegistry, item: new TestPanelItem})
element = panel.getView()
panel = new Panel({item: new TestPanelItem})
element = atom.views.createView(panel, {viewRegistry})
jasmineContent.appendChild(element)
expect(element.parentNode).toBe jasmineContent
@@ -36,15 +43,15 @@ describe "PanelElement", ->
describe "changing panel visibility", ->
it 'initially renders panel created with visibile: false', ->
panel = new Panel({viewRegistry, visible: false, item: new TestPanelItem})
element = panel.getView()
panel = new Panel({visible: false, item: new TestPanelItem})
element = atom.views.createView(panel, {viewRegistry})
jasmineContent.appendChild(element)
expect(element.style.display).toBe 'none'
it 'hides and shows the panel element when Panel::hide() and Panel::show() are called', ->
panel = new Panel({viewRegistry, item: new TestPanelItem})
element = panel.getView()
panel = new Panel({item: new TestPanelItem})
element = atom.views.createView(panel, {viewRegistry})
jasmineContent.appendChild(element)
expect(element.style.display).not.toBe 'none'
@@ -57,8 +64,8 @@ describe "PanelElement", ->
describe "when a class name is specified", ->
it 'initially renders panel created with visibile: false', ->
panel = new Panel({viewRegistry, className: 'some classes', item: new TestPanelItem})
element = panel.getView()
panel = new Panel({className: 'some classes', item: new TestPanelItem})
element = atom.views.createView(panel, {viewRegistry})
jasmineContent.appendChild(element)
expect(element).toHaveClass 'some'
+5 -5
Ver Arquivo
@@ -170,30 +170,30 @@ describe "Project", ->
absolutePath = fs.absolute(__dirname)
expect(atom.project.resolve(absolutePath)).toBe absolutePath
describe ".setPath(path)", ->
describe ".setPaths(path)", ->
describe "when path is a file", ->
it "sets its path to the files parent directory and updates the root directory", ->
atom.project.setPaths([require.resolve('./fixtures/dir/a')])
expect(atom.project.getPaths()[0]).toEqual path.dirname(require.resolve('./fixtures/dir/a'))
expect(atom.project.getRootDirectory().path).toEqual path.dirname(require.resolve('./fixtures/dir/a'))
expect(atom.project.getDirectories()[0].path).toEqual path.dirname(require.resolve('./fixtures/dir/a'))
describe "when path is a directory", ->
it "sets its path to the directory and updates the root directory", ->
directory = fs.absolute(path.join(__dirname, 'fixtures', 'dir', 'a-dir'))
atom.project.setPaths([directory])
expect(atom.project.getPaths()[0]).toEqual directory
expect(atom.project.getRootDirectory().path).toEqual directory
expect(atom.project.getDirectories()[0].path).toEqual directory
describe "when path is null", ->
it "sets its path and root directory to null", ->
atom.project.setPaths([])
expect(atom.project.getPaths()[0]?).toBeFalsy()
expect(atom.project.getRootDirectory()?).toBeFalsy()
expect(atom.project.getDirectories()[0]?).toBeFalsy()
it "normalizes the path to remove consecutive slashes, ., and .. segments", ->
atom.project.setPaths(["#{require.resolve('./fixtures/dir/a')}#{path.sep}b#{path.sep}#{path.sep}.."])
expect(atom.project.getPaths()[0]).toEqual path.dirname(require.resolve('./fixtures/dir/a'))
expect(atom.project.getRootDirectory().path).toEqual path.dirname(require.resolve('./fixtures/dir/a'))
expect(atom.project.getDirectories()[0].path).toEqual path.dirname(require.resolve('./fixtures/dir/a'))
describe ".replace()", ->
[filePath, commentFilePath, sampleContent, sampleCommentContent] = []
+1 -1
Ver Arquivo
@@ -1,5 +1,5 @@
SelectListView = require '../src/select-list-view'
{$, $$} = require 'atom'
{$, $$} = require '../src/space-pen-extensions'
describe "SelectListView", ->
[selectList, items, list, filterEditorView] = []
+1 -1
Ver Arquivo
@@ -1,4 +1,4 @@
{View, $, $$} = require 'atom'
{View, $, $$} = require '../src/space-pen-extensions'
describe "SpacePen extensions", ->
class TestView extends View
+28 -7
Ver Arquivo
@@ -9,12 +9,17 @@ _ = require 'underscore-plus'
fs = require 'fs-plus'
Grim = require 'grim'
KeymapManager = require '../src/keymap-extensions'
{$, WorkspaceView, Workspace} = require 'atom'
# FIXME: Remove jquery from this
{$} = require '../src/space-pen-extensions'
Config = require '../src/config'
{Point} = require 'text-buffer'
Project = require '../src/project'
Workspace = require '../src/workspace'
TextEditor = require '../src/text-editor'
TextEditorView = require '../src/text-editor-view'
TextEditorElement = require '../src/text-editor-element'
TokenizedBuffer = require '../src/tokenized-buffer'
TextEditorComponent = require '../src/text-editor-component'
pathwatcher = require 'pathwatcher'
@@ -76,13 +81,15 @@ beforeEach ->
atom.commands.restoreSnapshot(commandsToRestore)
atom.styles.restoreSnapshot(styleElementsToRestore)
atom.workspaceViewParentSelector = '#jasmine-content'
window.resetTimeouts()
atom.packages.packageStates = {}
serializedWindowState = null
spyOn(atom, 'saveSync')
atom.syntax.clearGrammarOverrides()
atom.grammars.clearGrammarOverrides()
spy = spyOn(atom.packages, 'resolvePackagePath').andCallFake (packageName) ->
if specPackageName and packageName is specPackageName
@@ -111,8 +118,7 @@ beforeEach ->
config.save.reset()
# make editor display updates synchronous
spyOn(TextEditorView.prototype, 'requestDisplayUpdate').andCallFake -> @updateDisplay()
TextEditorComponent.performSyncUpdates = true
TextEditorElement::setUpdatedSynchronously(true)
spyOn(atom, "setRepresentedFilename")
spyOn(window, "setTimeout").andCallFake window.fakeSetTimeout
@@ -135,8 +141,9 @@ afterEach ->
atom.menu.template = []
atom.contextMenu.clear()
atom.workspaceView?.remove?()
atom.workspaceView = null
atom.workspace?.destroy()
atom.workspace = null
atom.__workspaceView = null
delete atom.state.workspace
atom.project?.destroy()
@@ -150,7 +157,7 @@ afterEach ->
jasmine.unspy(atom, 'saveSync')
ensureNoPathSubscriptions()
atom.syntax.clearObservers()
atom.grammars.clearObservers()
waits(0) # yield to ui thread to make screen update more frequently
ensureNoPathSubscriptions = ->
@@ -191,6 +198,17 @@ jasmine.unspy = (object, methodName) ->
throw new Error("Not a spy") unless object[methodName].hasOwnProperty('originalValue')
object[methodName] = object[methodName].originalValue
jasmine.attachToDOM = (element) ->
jasmineContent = document.querySelector('#jasmine-content')
jasmineContent.appendChild(element) unless jasmineContent.contains(element)
deprecationsSnapshot = null
jasmine.snapshotDeprecations = ->
deprecationsSnapshot = Grim.getDeprecations() # suppress deprecations!!
jasmine.restoreDeprecationsSnapshot = ->
Grim.grimDeprecations = deprecationsSnapshot
addCustomMatchers = (spec) ->
spec.addMatchers
toBeInstanceOf: (expected) ->
@@ -286,6 +304,9 @@ window.waitsForPromise = (args...) ->
jasmine.getEnv().currentSpec.fail("Expected promise to be resolved, but it was rejected with #{jasmine.pp(error)}")
moveOn()
window.waitsForAnimationFrame = ->
waitsFor "next animation frame", (done) -> requestAnimationFrame(done)
window.resetTimeouts = ->
window.now = 0
window.timeoutCount = 0
+29 -56
Ver Arquivo
@@ -23,10 +23,10 @@ describe "the `syntax` global", ->
describe "serialization", ->
it "remembers grammar overrides by path", ->
filePath = '/foo/bar/file.js'
expect(atom.syntax.selectGrammar(filePath).name).not.toBe 'Ruby'
atom.syntax.setGrammarOverrideForPath(filePath, 'source.ruby')
syntax2 = atom.deserializers.deserialize(atom.syntax.serialize())
syntax2.addGrammar(grammar) for grammar in atom.syntax.grammars when grammar isnt atom.syntax.nullGrammar
expect(atom.grammars.selectGrammar(filePath).name).not.toBe 'Ruby'
atom.grammars.setGrammarOverrideForPath(filePath, 'source.ruby')
syntax2 = atom.deserializers.deserialize(atom.grammars.serialize())
syntax2.addGrammar(grammar) for grammar in atom.grammars.grammars when grammar isnt atom.grammars.nullGrammar
expect(syntax2.selectGrammar(filePath).name).toBe 'Ruby'
describe ".selectGrammar(filePath)", ->
@@ -35,15 +35,15 @@ describe "the `syntax` global", ->
atom.packages.activatePackage('language-git')
runs ->
expect(atom.syntax.selectGrammar("file.js").name).toBe "JavaScript" # based on extension (.js)
expect(atom.syntax.selectGrammar(path.join(temp.dir, '.git', 'config')).name).toBe "Git Config" # based on end of the path (.git/config)
expect(atom.syntax.selectGrammar("Rakefile").name).toBe "Ruby" # based on the file's basename (Rakefile)
expect(atom.syntax.selectGrammar("curb").name).toBe "Null Grammar"
expect(atom.syntax.selectGrammar("/hu.git/config").name).toBe "Null Grammar"
expect(atom.grammars.selectGrammar("file.js").name).toBe "JavaScript" # based on extension (.js)
expect(atom.grammars.selectGrammar(path.join(temp.dir, '.git', 'config')).name).toBe "Git Config" # based on end of the path (.git/config)
expect(atom.grammars.selectGrammar("Rakefile").name).toBe "Ruby" # based on the file's basename (Rakefile)
expect(atom.grammars.selectGrammar("curb").name).toBe "Null Grammar"
expect(atom.grammars.selectGrammar("/hu.git/config").name).toBe "Null Grammar"
it "uses the filePath's shebang line if the grammar cannot be determined by the extension or basename", ->
filePath = require.resolve("./fixtures/shebang")
expect(atom.syntax.selectGrammar(filePath).name).toBe "Ruby"
expect(atom.grammars.selectGrammar(filePath).name).toBe "Ruby"
it "uses the number of newlines in the first line regex to determine the number of lines to test against", ->
waitsForPromise ->
@@ -51,28 +51,28 @@ describe "the `syntax` global", ->
runs ->
fileContent = "first-line\n<html>"
expect(atom.syntax.selectGrammar("dummy.coffee", fileContent).name).toBe "CoffeeScript"
expect(atom.grammars.selectGrammar("dummy.coffee", fileContent).name).toBe "CoffeeScript"
fileContent = '<?xml version="1.0" encoding="UTF-8"?>'
expect(atom.syntax.selectGrammar("grammar.tmLanguage", fileContent).name).toBe "Null Grammar"
expect(atom.grammars.selectGrammar("grammar.tmLanguage", fileContent).name).toBe "Null Grammar"
fileContent += '\n<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">'
expect(atom.syntax.selectGrammar("grammar.tmLanguage", fileContent).name).toBe "Property List (XML)"
expect(atom.grammars.selectGrammar("grammar.tmLanguage", fileContent).name).toBe "Property List (XML)"
it "doesn't read the file when the file contents are specified", ->
filePath = require.resolve("./fixtures/shebang")
filePathContents = fs.readFileSync(filePath, 'utf8')
spyOn(fs, 'read').andCallThrough()
expect(atom.syntax.selectGrammar(filePath, filePathContents).name).toBe "Ruby"
expect(atom.grammars.selectGrammar(filePath, filePathContents).name).toBe "Ruby"
expect(fs.read).not.toHaveBeenCalled()
it "allows the default grammar to be overridden for a path", ->
filePath = '/foo/bar/file.js'
expect(atom.syntax.selectGrammar(filePath).name).not.toBe 'Ruby'
atom.syntax.setGrammarOverrideForPath(filePath, 'source.ruby')
expect(atom.syntax.selectGrammar(filePath).name).toBe 'Ruby'
atom.syntax.clearGrammarOverrideForPath(filePath)
expect(atom.syntax.selectGrammar(filePath).name).not.toBe 'Ruby'
expect(atom.grammars.selectGrammar(filePath).name).not.toBe 'Ruby'
atom.grammars.setGrammarOverrideForPath(filePath, 'source.ruby')
expect(atom.grammars.selectGrammar(filePath).name).toBe 'Ruby'
atom.grammars.clearGrammarOverrideForPath(filePath)
expect(atom.grammars.selectGrammar(filePath).name).not.toBe 'Ruby'
describe "when multiple grammars have matching fileTypes", ->
it "selects the grammar with the longest fileType match", ->
@@ -82,8 +82,8 @@ describe "the `syntax` global", ->
scopeName: 'source1'
fileTypes: ['test']
)
grammar1 = atom.syntax.loadGrammarSync(grammarPath1)
expect(atom.syntax.selectGrammar('more.test', '')).toBe grammar1
grammar1 = atom.grammars.loadGrammarSync(grammarPath1)
expect(atom.grammars.selectGrammar('more.test', '')).toBe grammar1
grammarPath2 = temp.path(suffix: '.json')
fs.writeFileSync grammarPath2, JSON.stringify(
@@ -91,44 +91,17 @@ describe "the `syntax` global", ->
scopeName: 'source2'
fileTypes: ['test', 'more.test']
)
grammar2 = atom.syntax.loadGrammarSync(grammarPath2)
expect(atom.syntax.selectGrammar('more.test', '')).toBe grammar2
grammar2 = atom.grammars.loadGrammarSync(grammarPath2)
expect(atom.grammars.selectGrammar('more.test', '')).toBe grammar2
describe "when there is no file path", ->
it "does not throw an exception (regression)", ->
expect(-> atom.syntax.selectGrammar(null, '#!/usr/bin/ruby')).not.toThrow()
expect(-> atom.syntax.selectGrammar(null, '')).not.toThrow()
expect(-> atom.syntax.selectGrammar(null, null)).not.toThrow()
expect(-> atom.grammars.selectGrammar(null, '#!/usr/bin/ruby')).not.toThrow()
expect(-> atom.grammars.selectGrammar(null, '')).not.toThrow()
expect(-> atom.grammars.selectGrammar(null, null)).not.toThrow()
describe ".removeGrammar(grammar)", ->
it "removes the grammar, so it won't be returned by selectGrammar", ->
grammar = atom.syntax.selectGrammar('foo.js')
atom.syntax.removeGrammar(grammar)
expect(atom.syntax.selectGrammar('foo.js').name).not.toBe grammar.name
describe ".getProperty(scopeDescriptor)", ->
it "returns the property with the most specific scope selector", ->
atom.syntax.addProperties(".source.coffee .string.quoted.double.coffee", foo: bar: baz: 42)
atom.syntax.addProperties(".source .string.quoted.double", foo: bar: baz: 22)
atom.syntax.addProperties(".source", foo: bar: baz: 11)
expect(atom.syntax.getProperty([".source.coffee", ".string.quoted.double.coffee"], "foo.bar.baz")).toBe 42
expect(atom.syntax.getProperty([".source.js", ".string.quoted.double.js"], "foo.bar.baz")).toBe 22
expect(atom.syntax.getProperty([".source.js", ".variable.assignment.js"], "foo.bar.baz")).toBe 11
expect(atom.syntax.getProperty([".text"], "foo.bar.baz")).toBeUndefined()
it "favors the most recently added properties in the event of a specificity tie", ->
atom.syntax.addProperties(".source.coffee .string.quoted.single", foo: bar: baz: 42)
atom.syntax.addProperties(".source.coffee .string.quoted.double", foo: bar: baz: 22)
expect(atom.syntax.getProperty([".source.coffee", ".string.quoted.single"], "foo.bar.baz")).toBe 42
expect(atom.syntax.getProperty([".source.coffee", ".string.quoted.single.double"], "foo.bar.baz")).toBe 22
describe ".removeProperties(name)", ->
it "allows properties to be removed by name", ->
atom.syntax.addProperties("a", ".source.coffee .string.quoted.double.coffee", foo: bar: baz: 42)
atom.syntax.addProperties("b", ".source .string.quoted.double", foo: bar: baz: 22)
atom.syntax.removeProperties("b")
expect(atom.syntax.getProperty([".source.js", ".string.quoted.double.js"], "foo.bar.baz")).toBeUndefined()
expect(atom.syntax.getProperty([".source.coffee", ".string.quoted.double.coffee"], "foo.bar.baz")).toBe 42
grammar = atom.grammars.selectGrammar('foo.js')
atom.grammars.removeGrammar(grammar)
expect(atom.grammars.selectGrammar('foo.js').name).not.toBe grammar.name
+25 -9
Ver Arquivo
@@ -3,10 +3,12 @@ _ = require 'underscore-plus'
TextEditorView = require '../src/text-editor-view'
TextEditorComponent = require '../src/text-editor-component'
ViewRegistry = require '../src/view-registry'
nbsp = String.fromCharCode(160)
describe "TextEditorComponent", ->
[contentNode, editor, wrapperView, wrapperNode, component, componentNode, verticalScrollbarNode, horizontalScrollbarNode] = []
[viewRegistry, contentNode, editor, wrapperView, wrapperNode, component, componentNode, verticalScrollbarNode, horizontalScrollbarNode] = []
[lineHeightInPixels, charWidth, nextAnimationFrame, noAnimationFrame, lineOverdrawMargin] = []
beforeEach ->
@@ -31,19 +33,22 @@ describe "TextEditorComponent", ->
atom.project.open('sample.js').then (o) -> editor = o
runs ->
viewRegistry = new ViewRegistry(atom.views)
contentNode = document.querySelector('#jasmine-content')
contentNode.style.width = '1000px'
wrapperView = new TextEditorView(editor, {lineOverdrawMargin})
wrapperView.attachToDom()
wrapperNode = wrapperView.element
wrapperNode = atom.views.createView(editor, {viewRegistry, lineOverdrawMargin})
wrapperNode.setUpdatedSynchronously(false)
jasmine.attachToDOM(wrapperNode)
{component} = wrapperView
component.performSyncUpdates = false
{component} = wrapperNode
component.setFontFamily('monospace')
component.setLineHeight(1.3)
component.setFontSize(20)
wrapperView = wrapperNode.__spacePenView
lineHeightInPixels = editor.getLineHeightInPixels()
charWidth = editor.getDefaultCharWidth()
componentNode = component.getDOMNode()
@@ -302,7 +307,7 @@ describe "TextEditorComponent", ->
it "interleaves invisible line-ending characters with indent guides on empty lines", ->
component.setShowIndentGuide(true)
editor.setTextInBufferRange([[10, 0], [11, 0]], "\r\n", false)
editor.setTextInBufferRange([[10, 0], [11, 0]], "\r\n", normalizeLineEndings: false)
nextAnimationFrame()
expect(component.lineNodeForScreenRow(10).innerHTML).toBe '<span class="indent-guide"><span class="invisible-character">C</span><span class="invisible-character">E</span></span>'
@@ -1247,7 +1252,7 @@ describe "TextEditorComponent", ->
expect(overlay.style.top).toBe position.top + editor.getLineHeightInPixels() + 'px'
describe "when the marker is not empty", ->
it "renders at the head of the marker", ->
it "renders at the head of the marker by default", ->
marker = editor.displayBuffer.markBufferRange([[2, 5], [2, 10]], invalidate: 'never')
decoration = editor.decorateMarker(marker, {type: 'overlay', item})
nextAnimationFrame()
@@ -1269,6 +1274,17 @@ describe "TextEditorComponent", ->
expect(overlay.style.left).toBe position.left + 'px'
expect(overlay.style.top).toBe position.top + editor.getLineHeightInPixels() + 'px'
it "renders at the tail of the marker when the 'position' option is 'tail'", ->
marker = editor.displayBuffer.markBufferRange([[2, 5], [2, 10]], invalidate: 'never')
decoration = editor.decorateMarker(marker, {type: 'overlay', position: 'tail', item})
nextAnimationFrame()
position = editor.pixelPositionForBufferPosition([2, 5])
overlay = component.getTopmostDOMNode().querySelector('atom-overlay')
expect(overlay.style.left).toBe position.left + 'px'
expect(overlay.style.top).toBe position.top + editor.getLineHeightInPixels() + 'px'
describe "positioning the overlay when near the edge of the editor", ->
[itemWidth, itemHeight] = []
beforeEach ->
@@ -2532,7 +2548,7 @@ describe "TextEditorComponent", ->
describe "grammar data attributes", ->
it "adds and updates the grammar data attribute based on the current grammar", ->
expect(wrapperNode.dataset.grammar).toBe 'source js'
editor.setGrammar(atom.syntax.nullGrammar)
editor.setGrammar(atom.grammars.nullGrammar)
expect(wrapperNode.dataset.grammar).toBe 'text plain null-grammar'
describe "encoding data attributes", ->
+20
Ver Arquivo
@@ -98,3 +98,23 @@ describe "TextEditorElement", ->
verticalScrollbarNode = element.querySelector(".vertical-scrollbar")
scrollbarWidth = verticalScrollbarNode.offsetWidth - verticalScrollbarNode.clientWidth
expect(scrollbarWidth).toEqual(8)
describe "::setUpdatedSynchronously", ->
it "controls whether the text editor is updated synchronously", ->
element = new TextEditorElement
jasmine.attachToDOM(element)
element.setUpdatedSynchronously(false)
expect(element.isUpdatedSynchronously()).toBe false
element.getModel().setText("hello")
expect(element.shadowRoot.textContent).not.toContain "hello"
waitsForAnimationFrame()
runs ->
expect(element.shadowRoot.textContent).toContain "hello"
element.setUpdatedSynchronously(true)
element.getModel().setText("goodbye")
expect(element.shadowRoot.textContent).toContain "goodbye"
+36 -63
Ver Arquivo
@@ -616,7 +616,7 @@ describe "TextEditor", ->
describe "when invisible characters are enabled with hard tabs", ->
it "moves to the first character of the current line without being confused by the invisible characters", ->
atom.config.set('editor.showInvisibles', true)
buffer.setTextInRange([[1, 0], [1, Infinity]], '\t\t\ta', false)
buffer.setTextInRange([[1, 0], [1, Infinity]], '\t\t\ta', normalizeLineEndings: false)
editor.setCursorScreenPosition [1,7]
editor.moveToFirstCharacterOfLine()
@@ -2607,69 +2607,44 @@ describe "TextEditor", ->
atom.clipboard.write(" z();")
editor.setCursorBufferPosition([1, Infinity])
editor.pasteText()
console.log JSON.stringify(editor.lineTextForBufferRow(1))
expect(editor.lineTextForBufferRow(1)).toBe(" y(); z();")
describe "when `autoIndentOnPaste` is false", ->
beforeEach ->
atom.config.set('editor.autoIndentOnPaste', false)
describe "when the inserted text contains no newlines", ->
it "does not adjust the indentation level of the text", ->
editor.setCursorBufferPosition([5, 2])
editor.insertText("foo", indentBasis: 5)
expect(editor.lineTextForBufferRow(5)).toBe " foo current = items.shift();"
describe "when the cursor is indented further than the original copied text", ->
it "increases the indentation of the copied lines to match", ->
editor.setSelectedBufferRange([[1, 2], [3, 0]])
editor.copySelectedText()
it "does not adjust the whitespace if there are preceding characters", ->
copyText(" foo")
editor.setCursorBufferPosition([5, 30])
editor.setCursorBufferPosition([5, 6])
editor.pasteText()
expect(editor.lineTextForBufferRow(5)).toBe " current = items.shift(); foo"
expect(editor.lineTextForBufferRow(5)).toBe " var sort = function(items) {"
expect(editor.lineTextForBufferRow(6)).toBe " if (items.length <= 1) return items;"
describe "when the inserted text contains newlines", ->
describe "when the cursor is preceded only by whitespace characters", ->
it "normalizes indented lines to each cursor's current indentation level", ->
editor.setSelectedBufferRanges([
[[1,2], [3,0]],
[[4,4], [6,0]]
])
editor.copySelectedText()
expect(atom.clipboard.read()).toEqual """
var sort = function(items) {
if (items.length <= 1) return items;
describe "when the cursor is indented less far than the original copied text", ->
it "decreases the indentation of the copied lines to match", ->
editor.setSelectedBufferRange([[6, 6], [8, 0]])
editor.copySelectedText()
while(items.length > 0) {
current = items.shift();
editor.setCursorBufferPosition([1, 2])
editor.pasteText()
"""
expect(editor.lineTextForBufferRow(1)).toBe " current < pivot ? left.push(current) : right.push(current);"
expect(editor.lineTextForBufferRow(2)).toBe "}"
editor.setCursorBufferPosition([0,0])
editor.insertNewlineAbove()
editor.setSelectedBufferRanges([
[[0,0], [0,0]],
[[1,0], [1,0]]
])
editor.pasteText()
describe "when the first copied line has leading whitespace", ->
it "preserves the line's leading whitespace", ->
editor.setSelectedBufferRange([[4, 0], [6, 0]])
editor.copySelectedText()
expect(editor.lineTextForBufferRow(0)).toBe "var sort = function(items) {"
console.log JSON.stringify(editor.lineTextForBufferRow(1))
expect(editor.lineTextForBufferRow(1)).toBe " if (items.length <= 1) return items;"
expect(editor.lineTextForBufferRow(2)).toBe ""
expect(editor.lineTextForBufferRow(3)).toBe "while(items.length > 0) {"
expect(editor.lineTextForBufferRow(4)).toBe " current = items.shift();"
editor.setCursorBufferPosition([0, 0])
editor.pasteText()
describe "when the cursor is preceded by non-whitespace characters", ->
it "normalizes the indentation level of all lines based on the level of the existing first line", ->
copyText(" while (true) {\n foo();\n }\n", {startColumn: 0})
editor.setCursorBufferPosition([1, Infinity])
editor.pasteText()
expect(editor.lineTextForBufferRow(1)).toBe " var sort = function(items) {while (true) {"
expect(editor.lineTextForBufferRow(2)).toBe " foo();"
expect(editor.lineTextForBufferRow(3)).toBe " }"
expect(editor.lineTextForBufferRow(4)).toBe ""
expect(editor.lineTextForBufferRow(0)).toBe " while(items.length > 0) {"
expect(editor.lineTextForBufferRow(1)).toBe " current = items.shift();"
describe 'when the clipboard has many selections', ->
beforeEach ->
@@ -3039,18 +3014,16 @@ describe "TextEditor", ->
expect(editor.isFoldedAtBufferRow(1)).toBeFalsy()
expect(editor.isFoldedAtBufferRow(2)).toBeTruthy()
describe "begin/commitTransaction()", ->
describe "::transact", ->
it "restores the selection when the transaction is undone/redone", ->
buffer.setText('1234')
editor.setSelectedBufferRange([[0, 1], [0, 3]])
editor.beginTransaction()
editor.delete()
editor.moveToEndOfLine()
editor.insertText('5')
expect(buffer.getText()).toBe '145'
editor.commitTransaction()
editor.transact ->
editor.delete()
editor.moveToEndOfLine()
editor.insertText('5')
expect(buffer.getText()).toBe '145'
editor.undo()
expect(buffer.getText()).toBe '1234'
@@ -3357,17 +3330,17 @@ describe "TextEditor", ->
it "switches to the better-matched grammar and re-tokenizes the buffer", ->
editor.destroy()
jsGrammar = atom.syntax.selectGrammar('a.js')
atom.syntax.removeGrammar(jsGrammar)
jsGrammar = atom.grammars.selectGrammar('a.js')
atom.grammars.removeGrammar(jsGrammar)
waitsForPromise ->
atom.workspace.open('sample.js', autoIndent: false).then (o) -> editor = o
runs ->
expect(editor.getGrammar()).toBe atom.syntax.nullGrammar
expect(editor.getGrammar()).toBe atom.grammars.nullGrammar
expect(editor.tokenizedLineForScreenRow(0).tokens.length).toBe 1
atom.syntax.addGrammar(jsGrammar)
atom.grammars.addGrammar(jsGrammar)
expect(editor.getGrammar()).toBe jsGrammar
expect(editor.tokenizedLineForScreenRow(0).tokens.length).toBeGreaterThan 1
@@ -3787,7 +3760,7 @@ describe "TextEditor", ->
it "updates the grammar based on grammar overrides", ->
expect(editor.getGrammar().name).toBe 'JavaScript'
atom.syntax.setGrammarOverrideForPath(editor.getPath(), 'source.coffee')
atom.grammars.setGrammarOverrideForPath(editor.getPath(), 'source.coffee')
editor.reloadGrammar()
expect(editor.getGrammar().name).toBe 'CoffeeScript'
@@ -3805,7 +3778,7 @@ describe "TextEditor", ->
atom.packages.activatePackage('language-hyperlink')
runs ->
grammar = atom.syntax.selectGrammar("text.js")
grammar = atom.grammars.selectGrammar("text.js")
{tokens} = grammar.tokenizeLine("var i; // http://github.com")
expect(tokens[0].value).toBe "var"
+53 -13
Ver Arquivo
@@ -1,6 +1,6 @@
path = require 'path'
{$, $$, WorkspaceView} = require 'atom'
{$, $$} = require '../src/space-pen-extensions'
fs = require 'fs-plus'
temp = require 'temp'
@@ -20,8 +20,12 @@ describe "ThemeManager", ->
describe "theme getters and setters", ->
beforeEach ->
jasmine.snapshotDeprecations()
atom.packages.loadPackages()
afterEach ->
jasmine.restoreDeprecationsSnapshot()
it 'getLoadedThemes get all the loaded themes', ->
themes = themeManager.getLoadedThemes()
expect(themes.length).toBeGreaterThan(2)
@@ -70,7 +74,7 @@ describe "ThemeManager", ->
describe "when the core.themes config value changes", ->
it "add/removes stylesheets to reflect the new config value", ->
themeManager.onDidReloadAll reloadHandler = jasmine.createSpy()
spyOn(themeManager, 'getUserStylesheetPath').andCallFake -> null
spyOn(atom.styles, 'getUserStyleSheetPath').andCallFake -> null
waitsForPromise ->
themeManager.activateThemes()
@@ -130,15 +134,24 @@ describe "ThemeManager", ->
expect(-> atom.packages.activatePackage('a-theme-that-will-not-be-found')).toThrow()
describe "::requireStylesheet(path)", ->
beforeEach ->
jasmine.snapshotDeprecations()
afterEach ->
jasmine.restoreDeprecationsSnapshot()
it "synchronously loads css at the given path and installs a style tag for it in the head", ->
atom.styles.onDidAddStyleElement styleElementAddedHandler = jasmine.createSpy("styleElementAddedHandler")
themeManager.onDidChangeStylesheets stylesheetsChangedHandler = jasmine.createSpy("stylesheetsChangedHandler")
themeManager.onDidAddStylesheet stylesheetAddedHandler = jasmine.createSpy("stylesheetAddedHandler")
cssPath = atom.project.resolve('css.css')
lengthBefore = $('head style').length
themeManager.requireStylesheet(cssPath)
expect($('head style').length).toBe lengthBefore + 1
expect(styleElementAddedHandler).toHaveBeenCalled()
expect(stylesheetAddedHandler).toHaveBeenCalled()
expect(stylesheetsChangedHandler).toHaveBeenCalled()
@@ -148,8 +161,10 @@ describe "ThemeManager", ->
expect(element[0].sheet).toBe stylesheetAddedHandler.argsForCall[0][0]
# doesn't append twice
styleElementAddedHandler.reset()
themeManager.requireStylesheet(cssPath)
expect($('head style').length).toBe lengthBefore + 1
expect(styleElementAddedHandler).not.toHaveBeenCalled()
$('head style[id*="css.css"]').remove()
@@ -192,6 +207,7 @@ describe "ThemeManager", ->
disposable = themeManager.requireStylesheet(cssPath)
expect($(document.body).css('font-weight')).toBe("bold")
atom.styles.onDidRemoveStyleElement styleElementRemovedHandler = jasmine.createSpy("styleElementRemovedHandler")
themeManager.onDidRemoveStylesheet stylesheetRemovedHandler = jasmine.createSpy("stylesheetRemovedHandler")
themeManager.onDidChangeStylesheets stylesheetsChangedHandler = jasmine.createSpy("stylesheetsChangedHandler")
@@ -199,6 +215,7 @@ describe "ThemeManager", ->
expect($(document.body).css('font-weight')).not.toBe("bold")
expect(styleElementRemovedHandler).toHaveBeenCalled()
expect(stylesheetRemovedHandler).toHaveBeenCalled()
stylesheet = stylesheetRemovedHandler.argsForCall[0][0]
expect(stylesheet instanceof CSSStyleSheet).toBe true
@@ -207,14 +224,20 @@ describe "ThemeManager", ->
expect(stylesheetsChangedHandler).toHaveBeenCalled()
describe "base stylesheet loading", ->
workspaceElement = null
beforeEach ->
atom.workspaceView = atom.views.getView(atom.workspace).__spacePenView
atom.workspaceView.append $('<atom-text-editor>')
atom.workspaceView.attachToDom()
jasmine.snapshotDeprecations()
workspaceElement = atom.views.createView(atom.workspace)
jasmine.attachToDOM(workspaceElement)
workspaceElement.appendChild document.createElement('atom-text-editor')
waitsForPromise ->
themeManager.activateThemes()
beforeEach ->
jasmine.restoreDeprecationsSnapshot()
it "loads the correct values from the theme's ui-variables file", ->
themeManager.onDidReloadAll reloadHandler = jasmine.createSpy()
atom.config.set('core.themes', ['theme-with-ui-variables', 'theme-with-syntax-variables'])
@@ -224,7 +247,7 @@ describe "ThemeManager", ->
runs ->
# an override loaded in the base css
expect(atom.workspaceView.css("background-color")).toBe "rgb(0, 0, 255)"
expect(getComputedStyle(workspaceElement)["background-color"]).toBe "rgb(0, 0, 255)"
# from within the theme itself
expect($("atom-text-editor").css("padding-top")).toBe "150px"
@@ -241,14 +264,14 @@ describe "ThemeManager", ->
runs ->
# an override loaded in the base css
expect(atom.workspaceView.css("background-color")).toBe "rgb(0, 0, 255)"
expect(getComputedStyle(workspaceElement)["background-color"]).toBe "rgb(0, 0, 255)"
# from within the theme itself
expect($("atom-text-editor").css("background-color")).toBe "rgb(0, 152, 255)"
describe "theme classes on the workspace", ->
it 'adds theme-* classes to the workspace for each active theme', ->
expect(atom.workspaceView).toHaveClass 'theme-atom-dark-ui'
expect(workspaceElement).toHaveClass 'theme-atom-dark-ui'
themeManager.onDidReloadAll reloadHandler = jasmine.createSpy()
atom.config.set('core.themes', ['theme-with-ui-variables', 'theme-with-syntax-variables'])
@@ -258,22 +281,32 @@ describe "ThemeManager", ->
runs ->
# `theme-` twice as it prefixes the name with `theme-`
expect(atom.workspaceView).toHaveClass 'theme-theme-with-ui-variables'
expect(atom.workspaceView).toHaveClass 'theme-theme-with-syntax-variables'
expect(atom.workspaceView).not.toHaveClass 'theme-atom-dark-ui'
expect(atom.workspaceView).not.toHaveClass 'theme-atom-dark-syntax'
expect(workspaceElement).toHaveClass 'theme-theme-with-ui-variables'
expect(workspaceElement).toHaveClass 'theme-theme-with-syntax-variables'
expect(workspaceElement).not.toHaveClass 'theme-atom-dark-ui'
expect(workspaceElement).not.toHaveClass 'theme-atom-dark-syntax'
describe "when the user stylesheet changes", ->
beforeEach ->
jasmine.snapshotDeprecations()
afterEach ->
jasmine.restoreDeprecationsSnapshot()
it "reloads it", ->
[styleElementAddedHandler, styleElementRemovedHandler] = []
[stylesheetRemovedHandler, stylesheetAddedHandler, stylesheetsChangedHandler] = []
userStylesheetPath = path.join(temp.mkdirSync("atom"), 'styles.less')
fs.writeFileSync(userStylesheetPath, 'body {border-style: dotted !important;}')
spyOn(themeManager, 'getUserStylesheetPath').andReturn userStylesheetPath
spyOn(atom.styles, 'getUserStyleSheetPath').andReturn userStylesheetPath
waitsForPromise ->
themeManager.activateThemes()
runs ->
atom.styles.onDidRemoveStyleElement styleElementRemovedHandler = jasmine.createSpy("styleElementRemovedHandler")
atom.styles.onDidAddStyleElement styleElementAddedHandler = jasmine.createSpy("styleElementAddedHandler")
themeManager.onDidChangeStylesheets stylesheetsChangedHandler = jasmine.createSpy("stylesheetsChangedHandler")
themeManager.onDidRemoveStylesheet stylesheetRemovedHandler = jasmine.createSpy("stylesheetRemovedHandler")
themeManager.onDidAddStylesheet stylesheetAddedHandler = jasmine.createSpy("stylesheetAddedHandler")
@@ -288,14 +321,19 @@ describe "ThemeManager", ->
runs ->
expect($(document.body).css('border-style')).toBe 'dashed'
expect(styleElementRemovedHandler).toHaveBeenCalled()
expect(styleElementRemovedHandler.argsForCall[0][0].textContent).toContain 'dotted'
expect(stylesheetRemovedHandler).toHaveBeenCalled()
expect(stylesheetRemovedHandler.argsForCall[0][0].cssRules[0].style.border).toBe 'dotted'
expect(styleElementAddedHandler).toHaveBeenCalled()
expect(styleElementAddedHandler.argsForCall[0][0].textContent).toContain 'dashed'
expect(stylesheetAddedHandler).toHaveBeenCalled()
expect(stylesheetAddedHandler.argsForCall[0][0].cssRules[0].style.border).toBe 'dashed'
expect(stylesheetsChangedHandler).toHaveBeenCalled()
styleElementRemovedHandler.reset()
stylesheetRemovedHandler.reset()
stylesheetsChangedHandler.reset()
fs.removeSync(userStylesheetPath)
@@ -304,6 +342,8 @@ describe "ThemeManager", ->
themeManager.loadUserStylesheet.callCount is 2
runs ->
expect(styleElementRemovedHandler).toHaveBeenCalled()
expect(styleElementRemovedHandler.argsForCall[0][0].textContent).toContain 'dashed'
expect(stylesheetRemovedHandler).toHaveBeenCalled()
expect(stylesheetRemovedHandler.argsForCall[0][0].cssRules[0].style.border).toBe 'dashed'
expect($(document.body).css('border-style')).toBe 'none'
+1 -1
Ver Arquivo
@@ -522,7 +522,7 @@ describe "TokenizedBuffer", ->
buffer = atom.project.bufferForPathSync()
buffer.setText "<div class='name'><%= User.find(2).full_name %></div>"
tokenizedBuffer = new TokenizedBuffer({buffer})
tokenizedBuffer.setGrammar(atom.syntax.selectGrammar('test.erb'))
tokenizedBuffer.setGrammar(atom.grammars.selectGrammar('test.erb'))
fullyTokenize(tokenizedBuffer)
{tokens} = tokenizedBuffer.tokenizedLineForRow(0)
+72
Ver Arquivo
@@ -0,0 +1,72 @@
TooltipManager = require '../src/tooltip-manager'
{$} = require '../src/space-pen-extensions'
describe "TooltipManager", ->
[manager, element] = []
beforeEach ->
manager = new TooltipManager
element = document.createElement('div')
element.classList.add('foo')
jasmine.attachToDOM(element)
hover = (element, fn) ->
$(element).trigger 'mouseenter'
advanceClock(manager.defaults.delay.show)
fn()
$(element).trigger 'mouseleave'
advanceClock(manager.defaults.delay.hide)
describe "::add(target, options)", ->
describe "when the target is an element", ->
it "creates a tooltip based on the given options when hovering over the target element", ->
manager.add element, title: "Title"
hover element, ->
expect(document.body.querySelector(".tooltip")).toHaveText("Title")
describe "when a keyBindingCommand is specified", ->
describe "when a title is specified", ->
it "appends the key binding corresponding to the command to the title", ->
atom.keymaps.add 'test',
'.foo': 'ctrl-x ctrl-y': 'test-command'
'.bar': 'ctrl-x ctrl-z': 'test-command'
manager.add element, title: "Title", keyBindingCommand: 'test-command'
hover element, ->
tooltipElement = document.body.querySelector(".tooltip")
expect(tooltipElement).toHaveText "Title ⌃X ⌃Y"
describe "when no title is specified", ->
it "shows the key binding corresponding to the command alone", ->
atom.keymaps.add 'test', '.foo': 'ctrl-x ctrl-y': 'test-command'
manager.add element, keyBindingCommand: 'test-command'
hover element, ->
tooltipElement = document.body.querySelector(".tooltip")
expect(tooltipElement).toHaveText "⌃X ⌃Y"
describe "when a keyBindingTarget is specified", ->
it "looks up the key binding relative to the target", ->
atom.keymaps.add 'test',
'.bar': 'ctrl-x ctrl-z': 'test-command'
'.foo': 'ctrl-x ctrl-y': 'test-command'
manager.add element, keyBindingCommand: 'test-command', keyBindingTarget: element
hover element, ->
tooltipElement = document.body.querySelector(".tooltip")
expect(tooltipElement).toHaveText "⌃X ⌃Y"
describe "when .dispose() is called on the returned disposable", ->
it "no longer displays the tooltip on hover", ->
disposable = manager.add element, title: "Title"
hover element, ->
expect(document.body.querySelector(".tooltip")).toHaveText("Title")
disposable.dispose()
hover element, ->
expect(document.body.querySelector(".tooltip")).toBeNull()
@@ -1,17 +1,17 @@
ViewRegistry = require '../src/view-registry'
ViewFactory = require '../src/view-factory'
{View} = require '../src/space-pen-extensions'
describe "ViewRegistry", ->
registry = null
describe "ViewFactory", ->
factory = null
beforeEach ->
registry = new ViewRegistry
factory = new ViewFactory
describe "::getView(object)", ->
describe "::createView(object, params)", ->
describe "when passed a DOM node", ->
it "returns the given DOM node", ->
node = document.createElement('div')
expect(registry.getView(node)).toBe node
expect(factory.createView(node)).toBe node
describe "when passed a SpacePen view", ->
it "returns the root node of the view with a __spacePenView property pointing at the SpacePen view", ->
@@ -19,56 +19,65 @@ describe "ViewRegistry", ->
@content: -> @div "Hello"
view = new TestView
node = registry.getView(view)
node = factory.createView(view)
expect(node.textContent).toBe "Hello"
expect(node.__spacePenView).toBe view
describe "when passed a model object", ->
describe "when a view provider is registered matching the object's constructor", ->
describe "when the provider has a viewConstructor property", ->
it "constructs a view element and assigns the model on it", ->
it "constructs a view element and calls initialize on it with the creation params", ->
class TestModel
class TestModelSubclass extends TestModel
class TestView
setModel: (@model) ->
initialize: (@params) ->
model = new TestModel
registry.addViewProvider
factory.addViewProvider
modelConstructor: TestModel
viewConstructor: TestView
view = registry.getView(model)
view = factory.createView(model, a: 1)
expect(view instanceof TestView).toBe true
expect(view.model).toBe model
expect(view.params.a).toBe 1
expect(view.params.model).toBe model
expect(view.params.viewFactory).toBe factory
subclassModel = new TestModelSubclass
view2 = registry.getView(subclassModel)
view2 = factory.createView(subclassModel)
expect(view2 instanceof TestView).toBe true
expect(view2.model).toBe subclassModel
expect(view2.params.model).toBe subclassModel
describe "when the provider has a createView method", ->
it "constructs a view element by calling the createView method with the model", ->
it "constructs a view element by calling the createView method with the creation params", ->
class TestModel
class TestView
setModel: (@model) ->
initialize: (@params) ->
registry.addViewProvider
factory.addViewProvider
modelConstructor: TestModel
createView: (model) ->
createView: (params) ->
view = new TestView
view.setModel(model)
view.initialize(params)
view
model = new TestModel
view = registry.getView(model)
view = factory.createView(model, a: 1)
expect(view instanceof TestView).toBe true
expect(view.model).toBe model
expect(view.params.a).toBe 1
expect(view.params.model).toBe model
describe "when no view provider is registered for the object's constructor", ->
describe "when the object has a .getViewClass() method", ->
describe "when the object has a .createViewClass() method", ->
beforeEach ->
jasmine.snapshotDeprecations()
afterEach ->
jasmine.restoreDeprecationsSnapshot()
it "builds an instance of the view class with the model, then returns its root node with a __spacePenView property pointing at the view", ->
class TestView extends View
@content: (model) -> @div model.name
@@ -79,29 +88,26 @@ describe "ViewRegistry", ->
getViewClass: -> TestView
model = new TestModel("hello")
node = registry.getView(model)
node = factory.createView(model)
expect(node.textContent).toBe "hello"
view = node.__spacePenView
expect(view instanceof TestView).toBe true
expect(view.model).toBe model
# returns the same DOM node for repeated calls
expect(registry.getView(model)).toBe node
describe "when the object has no .getViewClass() method", ->
describe "when the object has no .createViewClass() method", ->
it "throws an exception", ->
expect(-> registry.getView(new Object)).toThrow()
expect(-> factory.createView(new Object)).toThrow()
describe "::addViewProvider(providerSpec)", ->
it "returns a disposable that can be used to remove the provider", ->
class TestModel
class TestView
setModel: (@model) ->
disposable = registry.addViewProvider
initialize: ->
disposable = factory.addViewProvider
modelConstructor: TestModel
viewConstructor: TestView
expect(registry.getView(new TestModel) instanceof TestView).toBe true
expect(factory.createView(new TestModel) instanceof TestView).toBe true
disposable.dispose()
expect(-> registry.getView(new TestModel)).toThrow()
expect(-> factory.createView(new TestModel)).toThrow()
+11 -12
Ver Arquivo
@@ -1,4 +1,4 @@
{$, $$} = require 'atom'
{$, $$} = require '../src/space-pen-extensions'
path = require 'path'
TextEditor = require '../src/text-editor'
WindowEventHandler = require '../src/window-event-handler'
@@ -95,13 +95,13 @@ describe "Window", ->
describe ".unloadEditorWindow()", ->
it "saves the serialized state of the window so it can be deserialized after reload", ->
workspaceState = atom.workspace.serialize()
syntaxState = atom.syntax.serialize()
syntaxState = atom.grammars.serialize()
projectState = atom.project.serialize()
atom.unloadEditorWindow()
expect(atom.state.workspace).toEqual workspaceState
expect(atom.state.syntax).toEqual syntaxState
expect(atom.state.grammars).toEqual syntaxState
expect(atom.state.project).toEqual projectState
expect(atom.saveSync).toHaveBeenCalled()
@@ -112,9 +112,9 @@ describe "Window", ->
runs ->
buffer = atom.workspace.getActivePaneItem().buffer
pane = atom.workspaceView.getActivePaneView()
pane.splitRight(pane.copyActiveItem())
expect(atom.workspaceView.find('atom-text-editor').length).toBe 2
pane = atom.workspace.getActivePane()
pane.splitRight(copyActiveItem: true)
expect(atom.workspace.getTextEditors().length).toBe 2
atom.removeEditorWindow()
@@ -259,24 +259,23 @@ describe "Window", ->
describe "when the opened path exists", ->
it "sets the project path to the opened path", ->
$(window).trigger('window:open-path', [{pathToOpen: __filename}])
atom.getCurrentWindow().send 'message', 'open-path', pathToOpen: __filename
expect(atom.project.getPaths()[0]).toBe __dirname
describe "when the opened path does not exist but its parent directory does", ->
it "sets the project path to the opened path's parent directory", ->
$(window).trigger('window:open-path', [{pathToOpen: path.join(__dirname, 'this-path-does-not-exist.txt')}])
pathToOpen = path.join(__dirname, 'this-path-does-not-exist.txt')
atom.getCurrentWindow().send 'message', 'open-path', {pathToOpen}
expect(atom.project.getPaths()[0]).toBe __dirname
describe "when the opened path is a file", ->
it "opens it in the workspace", ->
$(window).trigger('window:open-path', [{pathToOpen: __filename}])
atom.getCurrentWindow().send 'message', 'open-path', pathToOpen: __filename
expect(atom.workspace.open.mostRecentCall.args[0]).toBe __filename
describe "when the opened path is a directory", ->
it "does not open it in the workspace", ->
$(window).trigger('window:open-path', [{pathToOpen: __dirname}])
atom.getCurrentWindow().send 'message', 'open-path', pathToOpen: __dirname
expect(atom.workspace.open.callCount).toBe 0
+22 -9
Ver Arquivo
@@ -375,7 +375,7 @@ describe "Workspace", ->
describe "document.title", ->
describe "when the project has no path", ->
it "sets the title to 'untitled'", ->
atom.project.setPath(undefined)
atom.project.setPaths([])
expect(document.title).toBe 'untitled - Atom'
describe "when the project has a path", ->
@@ -458,46 +458,59 @@ describe "Workspace", ->
expect(atom.setDocumentEdited).toHaveBeenCalledWith(false)
describe "adding panels", ->
class TestPanel
constructior: ->
class TestItem
describe '::addLeftPanel(model)', ->
it 'adds a panel to the correct panel container', ->
expect(atom.workspace.getLeftPanels().length).toBe(0)
atom.workspace.panelContainers.left.onDidAddPanel addPanelSpy = jasmine.createSpy()
panel = atom.workspace.addLeftPanel(item: new TestPanel())
model = new TestItem
panel = atom.workspace.addLeftPanel(item: model)
expect(panel).toBeDefined()
expect(addPanelSpy).toHaveBeenCalledWith({panel, index: 0})
describe '::addRightPanel(model)', ->
it 'adds a panel to the correct panel container', ->
expect(atom.workspace.getRightPanels().length).toBe(0)
atom.workspace.panelContainers.right.onDidAddPanel addPanelSpy = jasmine.createSpy()
panel = atom.workspace.addRightPanel(item: new TestPanel())
model = new TestItem
panel = atom.workspace.addRightPanel(item: model)
expect(panel).toBeDefined()
expect(addPanelSpy).toHaveBeenCalledWith({panel, index: 0})
describe '::addTopPanel(model)', ->
it 'adds a panel to the correct panel container', ->
expect(atom.workspace.getTopPanels().length).toBe(0)
atom.workspace.panelContainers.top.onDidAddPanel addPanelSpy = jasmine.createSpy()
panel = atom.workspace.addTopPanel(item: new TestPanel())
model = new TestItem
panel = atom.workspace.addTopPanel(item: model)
expect(panel).toBeDefined()
expect(addPanelSpy).toHaveBeenCalledWith({panel, index: 0})
describe '::addBottomPanel(model)', ->
it 'adds a panel to the correct panel container', ->
expect(atom.workspace.getBottomPanels().length).toBe(0)
atom.workspace.panelContainers.bottom.onDidAddPanel addPanelSpy = jasmine.createSpy()
panel = atom.workspace.addBottomPanel(item: new TestPanel())
model = new TestItem
panel = atom.workspace.addBottomPanel(item: model)
expect(panel).toBeDefined()
expect(addPanelSpy).toHaveBeenCalledWith({panel, index: 0})
describe '::addModalPanel(model)', ->
it 'adds a panel to the correct panel container', ->
expect(atom.workspace.getModalPanels().length).toBe(0)
atom.workspace.panelContainers.modal.onDidAddPanel addPanelSpy = jasmine.createSpy()
panel = atom.workspace.addModalPanel(item: new TestPanel())
model = new TestItem
panel = atom.workspace.addModalPanel(item: model)
expect(panel).toBeDefined()
expect(addPanelSpy).toHaveBeenCalledWith({panel, index: 0})
expect(panel.getClassName()).toBe 'overlay from-top' # the default
+9 -4
Ver Arquivo
@@ -1,4 +1,4 @@
{$, $$, WorkspaceView, View} = require 'atom'
{$, $$, View} = require '../src/space-pen-extensions'
Q = require 'q'
path = require 'path'
temp = require 'temp'
@@ -10,16 +10,21 @@ describe "WorkspaceView", ->
pathToOpen = null
beforeEach ->
jasmine.snapshotDeprecations()
atom.project.setPaths([atom.project.resolve('dir')])
pathToOpen = atom.project.resolve('a')
atom.workspace = new Workspace
atom.workspaceView = atom.views.getView(atom.workspace).__spacePenView
atom.workspaceView = atom.views.createView(atom.workspace).__spacePenView
atom.workspaceView.enableKeymap()
atom.workspaceView.focus()
waitsForPromise ->
atom.workspace.open(pathToOpen)
afterEach ->
jasmine.restoreDeprecationsSnapshot()
describe "@deserialize()", ->
viewState = null
@@ -29,7 +34,7 @@ describe "WorkspaceView", ->
atom.workspaceView.remove()
atom.project = atom.deserializers.deserialize(projectState)
atom.workspace = Workspace.deserialize(workspaceState)
atom.workspaceView = atom.views.getView(atom.workspace).__spacePenView
atom.workspaceView = atom.views.createView(atom.workspace).__spacePenView
atom.workspaceView.attachToDom()
describe "when the serialized WorkspaceView has an unsaved buffer", ->
@@ -274,7 +279,7 @@ describe "WorkspaceView", ->
describe 'panel containers', ->
workspaceElement = null
beforeEach ->
workspaceElement = atom.views.getView(atom.workspace)
workspaceElement = atom.views.createView(atom.workspace)
it 'inserts panel container elements in the correct places in the DOM', ->
leftContainer = workspaceElement.querySelector('atom-panel-container.left')
+60 -19
Ver Arquivo
@@ -5,6 +5,7 @@ path = require 'path'
remote = require 'remote'
screen = require 'screen'
shell = require 'shell'
{deprecate} = require 'grim'
_ = require 'underscore-plus'
{deprecate} = require 'grim'
@@ -33,6 +34,23 @@ class Atom extends Model
startTime = Date.now()
atom = @deserialize(@loadState(mode)) ? new this({mode, @version})
atom.deserializeTimings.atom = Date.now() - startTime
workspaceViewDeprecationMessage = """
atom.workspaceView is no longer available.
In most cases you will not need the view. See the Workspace docs for
alternatives: https://atom.io/docs/api/latest/Workspace.
If you do need the view, please use `document.querySelector('atom-workspace')`,
which returns an HTMLElement.
"""
Object.defineProperty atom, 'workspaceView',
get: ->
deprecate(workspaceViewDeprecationMessage)
atom.__workspaceView
set: (newValue) ->
deprecate(workspaceViewDeprecationMessage)
atom.__workspaceView = newValue
atom
# Deserializes the Atom environment from a state object
@@ -125,11 +143,17 @@ class Atom extends Model
# Public: A {KeymapManager} instance
keymaps: null
# Public: A {TooltipManager} instance
tooltips: null
# Experimental: A {NotificationManager} instance
notifications: null
# Public: A {Project} instance
project: null
# Public: A {Syntax} instance
syntax: null
# Public: A {GrammarRegistry} instance
grammars: null
# Public: A {PackageManager} instance
packages: null
@@ -137,18 +161,18 @@ class Atom extends Model
# Public: A {ThemeManager} instance
themes: null
# Public: A {StyleManager} instance
styles: null
# Public: A {DeserializerManager} instance
deserializers: null
# Public: A {ViewRegistry} instance
# Public: A {ViewFactory} instance
views: null
# Public: A {Workspace} instance
workspace: null
# Public: A {WorkspaceView} instance
workspaceView: null
###
Section: Construction and Destruction
###
@@ -196,11 +220,13 @@ class Atom extends Model
Config = require './config'
KeymapManager = require './keymap-extensions'
ViewRegistry = require './view-registry'
ViewFactory = require './view-factory'
CommandRegistry = require './command-registry'
TooltipManager = require './tooltip-manager'
NotificationManager = require './notification-manager'
PackageManager = require './package-manager'
Clipboard = require './clipboard'
Syntax = require './syntax'
GrammarRegistry = require './grammar-registry'
ThemeManager = require './theme-manager'
StyleManager = require './style-manager'
ContextMenuManager = require './context-menu-manager'
@@ -223,8 +249,11 @@ class Atom extends Model
@config = new Config({configDirPath, resourcePath})
@keymaps = new KeymapManager({configDirPath, resourcePath})
@keymap = @keymaps # Deprecated
@keymaps.subscribeToFileReadFailure()
@tooltips = new TooltipManager
@notifications = new NotificationManager
@commands = new CommandRegistry
@views = new ViewRegistry
@views = new ViewFactory
@packages = new PackageManager({devMode, configDirPath, resourcePath, safeMode})
@styles = new StyleManager
document.head.appendChild(new StylesElement)
@@ -233,7 +262,11 @@ class Atom extends Model
@menu = new MenuManager({resourcePath})
@clipboard = new Clipboard()
@syntax = @deserializers.deserialize(@state.syntax) ? new Syntax()
@grammars = @deserializers.deserialize(@state.grammars ? @state.syntax) ? new GrammarRegistry()
Object.defineProperty this, 'syntax', get: ->
deprecate "The atom.syntax global is deprecated. Use atom.grammars instead."
@grammars
@subscribe @packages.onDidActivateAll => @watchThemes()
@@ -544,9 +577,9 @@ class Atom extends Model
@displayWindow({maximize})
unloadEditorWindow: ->
return if not @project and not @workspaceView
return if not @project
@state.syntax = @syntax.serialize()
@state.grammars = @grammars.serialize()
@state.project = @project.serialize()
@state.workspace = @workspace.serialize()
@packages.deactivatePackages()
@@ -555,10 +588,10 @@ class Atom extends Model
@windowState = null
removeEditorWindow: ->
return if not @project and not @workspaceView
return if not @project
@workspaceView?.remove()
@workspaceView = null
@workspace?.destroy()
@workspace = null
@project?.destroy()
@project = null
@@ -571,7 +604,7 @@ class Atom extends Model
# Essential: Visually and audibly trigger a beep.
beep: ->
shell.beep() if @config.get('core.audioBeep')
@workspaceView.trigger 'beep'
@__workspaceView.trigger 'beep'
@emitter.emit 'did-beep'
# Essential: A flexible way to open a dialog akin to an alert dialog.
@@ -647,11 +680,13 @@ class Atom extends Model
startTime = Date.now()
@workspace = Workspace.deserialize(@state.workspace) ? new Workspace
@workspaceView = @views.getView(@workspace).__spacePenView
workspaceElement = @views.createView(@workspace)
@__workspaceView = workspaceElement.__spacePenView
@deserializeTimings.workspace = Date.now() - startTime
@keymaps.defaultTarget = @workspaceView[0]
$(@workspaceViewParentSelector).append(@workspaceView)
@keymaps.defaultTarget = workspaceElement
document.querySelector(@workspaceViewParentSelector).appendChild(workspaceElement)
deserializePackageStates: ->
@packages.packageStates = @state.packageStates ? {}
@@ -748,6 +783,12 @@ class Atom extends Model
else
window[key] = value
onUpdateAvailable: (callback) ->
@emitter.on 'update-available', callback
updateAvailable: (details) ->
@emitter.emit 'update-available', details
# Deprecated: Callers should be converted to use atom.deserializers
registerRepresentationClass: ->
deprecate("Callers should be converted to use atom.deserializers")
+5 -3
Ver Arquivo
@@ -58,7 +58,7 @@ class AtomWindow
@browserWindow.loadUrl @getUrl(loadSettings)
@browserWindow.focusOnWebView() if @isSpec
@openPath(pathToOpen, initialLine, initialColumn)
@openPath(pathToOpen, initialLine, initialColumn) unless @isSpecWindow()
getUrl: (loadSettingsObj) ->
# Ignore the windowState when passing loadSettings via URL, since it could
@@ -143,10 +143,13 @@ class AtomWindow
openPath: (pathToOpen, initialLine, initialColumn) ->
if @loaded
@focus()
@sendCommand('window:open-path', {pathToOpen, initialLine, initialColumn})
@sendMessage 'open-path', {pathToOpen, initialLine, initialColumn}
else
@browserWindow.once 'window:loaded', => @openPath(pathToOpen, initialLine, initialColumn)
sendMessage: (message, detail) ->
@browserWindow.webContents.send 'message', message, detail
sendCommand: (command, args...) ->
if @isSpecWindow()
unless global.atomApplication.sendCommandToFirstResponder(command)
@@ -154,7 +157,6 @@ class AtomWindow
when 'window:reload' then @reload()
when 'window:toggle-dev-tools' then @toggleDevTools()
when 'window:close' then @close()
when 'window:update-available' then @sendCommandToBrowserWindow(command, args...) # For spec testing
else if @isWebViewFocused()
@sendCommandToBrowserWindow(command, args...)
else
+7 -2
Ver Arquivo
@@ -15,7 +15,12 @@ class AutoUpdateManager
constructor: (@version) ->
@state = IdleState
@feedUrl = "https://atom.io/api/updates?version=#{@version}"
if process.platform is 'win32'
# Squirrel for Windows can't handle query params
# https://github.com/Squirrel/Squirrel.Windows/issues/132
@feedUrl = 'https://atom.io/api/updates'
else
@feedUrl = "https://atom.io/api/updates?version=#{@version}"
process.nextTick => @setupAutoUpdater()
@@ -51,7 +56,7 @@ class AutoUpdateManager
emitUpdateAvailableEvent: (windows...) ->
return unless @releaseVersion? and @releaseNotes
for atomWindow in windows
atomWindow.sendCommand('window:update-available', [@releaseVersion, @releaseNotes])
atomWindow.sendMessage('update-available', {@releaseVersion, @releaseNotes})
setState: (state) ->
return if @state is state
+1 -1
Ver Arquivo
@@ -8,7 +8,7 @@ class ContextMenu
menu.popup(@atomWindow.browserWindow)
# It's necessary to build the event handlers in this process, otherwise
# closures are drug across processes and failed to be garbage collected
# closures are dragged across processes and failed to be garbage collected
# appropriately.
createClickHandlers: (template) ->
for item in template
+10
Ver Arquivo
@@ -13,6 +13,16 @@ process.on 'uncaughtException', (error={}) ->
nslog(error.message) if error.message?
nslog(error.stack) if error.stack?
# Patch fs.statSyncNoException/fs.lstatSyncNoException to fail for non-strings
# https://github.com/atom/atom-shell/issues/843
{lstatSyncNoException, statSyncNoException} = fs
fs.statSyncNoException = (pathToStat) ->
return false unless pathToStat and typeof pathToStat is 'string'
statSyncNoException(pathToStat)
fs.lstatSyncNoException = (pathToStat) ->
return false unless pathToStat and typeof pathToStat is 'string'
lstatSyncNoException(pathToStat)
start = ->
if process.platform is 'win32'
SquirrelUpdate = require './squirrel-update'
-3
Ver Arquivo
@@ -119,9 +119,6 @@ module.exports =
autoIndentOnPaste:
type: 'boolean'
default: true
normalizeIndentOnPaste:
type: 'boolean'
default: true
nonWordCharacters:
type: 'string'
default: "/\\()\"':,.;<>~!@#$%^&*|+=[]{}`?-"
+12 -4
Ver Arquivo
@@ -526,6 +526,9 @@ class Config
# Extended: Restore the global setting at `keyPath` to its default value.
#
# * `scopeSelector` (optional) {String}. eg. '.source.ruby'
# See [the scopes docs](https://atom.io/docs/latest/advanced/scopes-and-scope-descriptors)
# for more information.
# * `keyPath` The {String} name of the key.
#
# Returns the new value.
@@ -721,21 +724,26 @@ class Config
@configFileHasErrors = false
catch error
@configFileHasErrors = true
console.error "Failed to load user config '#{@configFilePath}'", error.message
console.error error.stack
@notifyFailure('Failed to load config.cson', error)
observeUserConfig: ->
try
@watchSubscription ?= pathWatcher.watch @configFilePath, (eventType) =>
@loadUserConfig() if eventType is 'change' and @watchSubscription?
catch error
console.error "Failed to watch user config '#{@configFilePath}'", error.message
console.error error.stack
@notifyFailure('Failed to watch user config', error)
unobserveUserConfig: ->
@watchSubscription?.close()
@watchSubscription = null
notifyFailure: (errorMessage, error) ->
message = "#{errorMessage}"
detail = error.stack
atom.notifications.addError(message, {detail, closable: true})
console.error message
console.error detail
save: ->
allSettings = global: @settings
allSettings = _.extend allSettings, @scopedSettingsStore.propertiesForSource('user-config')
+3
Ver Arquivo
@@ -889,6 +889,9 @@ class DisplayBuffer extends Model
allDecorations = allDecorations.concat(decorations) if decorations?
allDecorations
getOverlayDecorations: ->
@getDecorations().filter (decoration) -> decoration.isType('overlay')
decorationsForScreenRowRange: (startScreenRow, endScreenRow) ->
decorationsByMarkerId = {}
for marker in @findMarkers(intersectsScreenRowRange: [startScreenRow, endScreenRow])
+16 -11
Ver Arquivo
@@ -1,9 +1,8 @@
{basename, join} = require 'path'
_ = require 'underscore-plus'
{Subscriber} = require 'emissary'
EmitterMixin = require('emissary').Emitter
{Emitter} = require 'event-kit'
{Emitter, Disposable, CompositeDisposable} = require 'event-kit'
fs = require 'fs-plus'
GitUtils = require 'git-utils'
{deprecate} = require 'grim'
@@ -45,7 +44,6 @@ Task = require './task'
module.exports =
class GitRepository
EmitterMixin.includeInto(this)
Subscriber.includeInto(this)
@exists: (path) ->
if git = @open(path)
@@ -75,6 +73,8 @@ class GitRepository
constructor: (path, options={}) ->
@emitter = new Emitter
@subscriptions = new CompositeDisposable
@repo = GitUtils.open(path)
unless @repo?
throw new Error("No Git repository found searching path: #{path}")
@@ -88,13 +88,15 @@ class GitRepository
refreshOnWindowFocus ?= true
if refreshOnWindowFocus
{$} = require './space-pen-extensions'
@subscribe $(window), 'focus', =>
onWindowFocus = =>
@refreshIndex()
@refreshStatus()
window.addEventListener 'focus', onWindowFocus
@subscriptions.add new Disposable(-> window.removeEventListener 'focus', onWindowFocus)
if @project?
@subscribe @project.eachBuffer (buffer) => @subscribeToBuffer(buffer)
@subscriptions.add @project.eachBuffer (buffer) => @subscribeToBuffer(buffer)
# Public: Destroy this {GitRepository} object.
#
@@ -109,7 +111,7 @@ class GitRepository
@repo.release()
@repo = null
@unsubscribe()
@subscriptions.dispose()
###
Section: Event Subscription
@@ -403,10 +405,13 @@ class GitRepository
if path = buffer.getPath()
@getPathStatus(path)
@subscribe buffer.onDidSave(getBufferPathStatus)
@subscribe buffer.onDidReload(getBufferPathStatus)
@subscribe buffer.onDidChangePath(getBufferPathStatus)
@subscribe buffer.onDidDestroy => @unsubscribe(buffer)
bufferSubscriptions = new CompositeDisposable
bufferSubscriptions.add buffer.onDidSave(getBufferPathStatus)
bufferSubscriptions.add buffer.onDidReload(getBufferPathStatus)
bufferSubscriptions.add buffer.onDidChangePath(getBufferPathStatus)
bufferSubscriptions.add buffer.onDidDestroy =>
bufferSubscriptions.dispose()
@subscriptions.remove(bufferSubscriptions)
# Subscribes to editor view event.
checkoutHeadForEditor: (editor) ->
@@ -2,7 +2,8 @@ _ = require 'underscore-plus'
{deprecate} = require 'grim'
{specificity} = require 'clear-cut'
{Subscriber} = require 'emissary'
{GrammarRegistry, ScopeSelector} = require 'first-mate'
FirstMate = require 'first-mate'
{ScopeSelector} = FirstMate
ScopedPropertyStore = require 'scoped-property-store'
PropertyAccessors = require 'property-accessors'
@@ -11,20 +12,22 @@ Token = require './token'
# Extended: Syntax class holding the grammars used for tokenizing.
#
# An instance of this class is always available as the `atom.syntax` global.
# An instance of this class is always available as the `atom.grammars` global.
#
# The Syntax class also contains properties for things such as the
# language-specific comment regexes. See {::getProperty} for more details.
module.exports =
class Syntax extends GrammarRegistry
class GrammarRegistry extends FirstMate.GrammarRegistry
PropertyAccessors.includeInto(this)
Subscriber.includeInto(this)
atom.deserializers.add(this)
@deserialize: ({grammarOverridesByPath}) ->
syntax = new Syntax()
syntax.grammarOverridesByPath = grammarOverridesByPath
syntax
grammarRegistry = new GrammarRegistry()
grammarRegistry.grammarOverridesByPath = grammarOverridesByPath
grammarRegistry
atom.deserializers.add(this)
atom.deserializers.add(name: 'Syntax', deserialize: @deserialize) # Support old serialization
constructor: ->
super(maxTokensPerLine: 100)
@@ -34,6 +37,17 @@ class Syntax extends GrammarRegistry
createToken: (value, scopes) -> new Token({value, scopes})
# Extended: Select a grammar for the given file path and file contents.
#
# This picks the best match by checking the file path and contents against
# each grammar.
#
# * `filePath` A {String} file path.
# * `fileContents` A {String} of text for the file path.
#
# Returns a {Grammar}, never null.
selectGrammar: (filePath, fileContents) -> super
# Deprecated: Used by settings-view to display snippets for packages
@::accessor 'propertyStore', ->
deprecate("Do not use this. Use a public method on Config")
+4
Ver Arquivo
@@ -23,6 +23,10 @@ KeymapManager::loadUserKeymap = ->
if fs.isFileSync(userKeymapPath)
@loadKeymap(userKeymapPath, watch: true, suppressErrors: true)
KeymapManager::subscribeToFileReadFailure = ->
this.onDidFailToReadFile (error) ->
atom.notifications.addError('Failed to load keymap.cson', {detail: error.stack, closable: true})
# This enables command handlers registered via jQuery to call
# `.abortKeyBinding()` on the `jQuery.Event` object passed to the handler.
jQuery.Event::abortKeyBinding = ->
+2 -2
Ver Arquivo
@@ -66,10 +66,10 @@ LinesComponent = React.createClass
insertionPoint = document.createElement('content')
insertionPoint.setAttribute('select', 'atom-overlay')
@overlayManager = new OverlayManager(@props.hostElement)
@overlayManager = new OverlayManager(@props.hostElement, @props.hostElement.viewRegistry)
@getDOMNode().appendChild(insertionPoint)
else
@overlayManager = new OverlayManager(@getDOMNode())
@overlayManager = new OverlayManager(@getDOMNode(), @props.hostElement.viewRegistry)
shouldComponentUpdate: (newProps) ->
return true unless isEqualForProperties(newProps, @props,
+44
Ver Arquivo
@@ -0,0 +1,44 @@
{Emitter, Disposable} = require 'event-kit'
Notification = require '../src/notification'
# Experimental: Allows messaging the user. This will likely change, dont use
# quite yet!
module.exports =
class NotificationManager
constructor: ->
@notifications = []
@emitter = new Emitter
###
Section: Events
###
onDidAddNotification: (callback) ->
@emitter.on 'did-add-notification', callback
###
Section: Adding Notifications
###
addSuccess: (message, options) ->
@addNotification(new Notification('success', message, options))
addInfo: (message, options) ->
@addNotification(new Notification('info', message, options))
addWarning: (message, options) ->
@addNotification(new Notification('warning', message, options))
addError: (message, options) ->
@addNotification(new Notification('error', message, options))
addFatalError: (message, options) ->
@addNotification(new Notification('fatal', message, options))
add: (type, message, options) ->
@addNotification(new Notification(type, message, options))
addNotification: (notification) ->
@notifications.push(notification)
@emitter.emit('did-add-notification', notification)
notification
+33
Ver Arquivo
@@ -0,0 +1,33 @@
# Experimental: This will likely change, do not use.
module.exports =
class Notification
constructor: (@type, @message, @options={}) ->
@timestamp = new Date()
getOptions: -> @options
getType: -> @type
getMessage: -> @message
getTimestamp: -> @timestamp
getDetail: -> @options.detail
isEqual: (other) ->
@getMessage() == other.getMessage() \
and @getType() == other.getType() \
and @getDetail() == other.getDetail()
isClosable: ->
!!@options.closable
getIcon: ->
return @options.icon if @options.icon?
switch @type
when 'fatal' then 'bug'
when 'error' then 'flame'
when 'warning' then 'alert'
when 'info' then 'info'
when 'success' then 'check'
+7 -4
Ver Arquivo
@@ -1,15 +1,18 @@
module.exports =
class OverlayManager
constructor: (@container) ->
constructor: (@container, @viewRegistry) ->
@overlays = {}
render: (props) ->
{editor, overlayDecorations, lineHeightInPixels} = props
existingDecorations = null
for markerId, {isMarkerReversed, headPixelPosition, decorations} of overlayDecorations
for markerId, {headPixelPosition, tailPixelPosition, decorations} of overlayDecorations
for decoration in decorations
@renderOverlay(editor, decoration, headPixelPosition, lineHeightInPixels)
pixelPosition =
if decoration.position is 'tail' then tailPixelPosition else headPixelPosition
@renderOverlay(editor, decoration, pixelPosition, lineHeightInPixels)
existingDecorations ?= {}
existingDecorations[decoration.id] = true
@@ -22,7 +25,7 @@ class OverlayManager
return
renderOverlay: (editor, decoration, pixelPosition, lineHeightInPixels) ->
item = atom.views.getView(decoration.item)
item = @viewRegistry.getView(decoration.item)
unless overlay = @overlays[decoration.id]
overlay = @overlays[decoration.id] = document.createElement('atom-overlay')
overlay.appendChild(item)
+2 -2
Ver Arquivo
@@ -254,7 +254,7 @@ class Package
grammarPaths = fs.listSync(grammarsDirPath, ['json', 'cson'])
for grammarPath in grammarPaths
try
grammar = atom.syntax.readGrammarSync(grammarPath)
grammar = atom.grammars.readGrammarSync(grammarPath)
grammar.packageName = @name
@grammars.push(grammar)
grammar.activate()
@@ -268,7 +268,7 @@ class Package
return Q() if @grammarsLoaded
loadGrammar = (grammarPath, callback) =>
atom.syntax.readGrammar grammarPath, (error, grammar) =>
atom.grammars.readGrammar grammarPath, (error, grammar) =>
if error?
console.warn("Failed to load grammar: #{grammarPath}", error.stack ? error)
else
+3 -3
Ver Arquivo
@@ -8,7 +8,7 @@ class PaneAxisElement extends HTMLElement
detachedCallback: ->
@subscriptions.dispose()
setModel: (@model) ->
initialize: ({@viewRegistry, @model}) ->
@subscriptions.add @model.onDidAddChild(@childAdded.bind(this))
@subscriptions.add @model.onDidRemoveChild(@childRemoved.bind(this))
@subscriptions.add @model.onDidReplaceChild(@childReplaced.bind(this))
@@ -22,12 +22,12 @@ class PaneAxisElement extends HTMLElement
@classList.add('vertical', 'pane-column')
childAdded: ({child, index}) ->
view = @model.getView(child)
view = @viewRegistry.getView(child)
@insertBefore(view, @children[index])
callAttachHooks(view) # for backward compatibility with SpacePen views
childRemoved: ({child}) ->
view = @model.getView(child)
view = @viewRegistry.getView(child)
view.remove()
childReplaced: ({index, oldChild, newChild}) ->
-3
Ver Arquivo
@@ -39,9 +39,6 @@ class PaneAxis extends Model
getOrientation: -> @orientation
getView: (object) ->
@container.getView(object)
getChildren: -> @children.slice()
getPanes: ->
+3 -3
Ver Arquivo
@@ -11,7 +11,7 @@ class PaneContainerElement extends HTMLElement
PaneContainerView ?= require './pane-container-view'
@__spacePenView = new PaneContainerView(this)
setModel: (@model) ->
initialize: ({@viewRegistry, @model}) ->
@subscriptions.add @model.observeRoot(@rootChanged.bind(this))
@__spacePenView.setModel(@model)
@@ -19,7 +19,7 @@ class PaneContainerElement extends HTMLElement
focusedElement = document.activeElement if @hasFocus()
@firstChild?.remove()
if root?
view = @model.getView(root)
view = @viewRegistry.getView(root)
@appendChild(view)
callAttachHooks(view)
focusedElement?.focus()
@@ -45,7 +45,7 @@ class PaneContainerElement extends HTMLElement
y = pointB.y - pointA.y
Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2))
paneView = @model.getView(@model.getActivePane())
paneView = @viewRegistry.getView(@model.getActivePane())
box = @boundingBoxForPaneView(paneView)
paneViews = _.toArray(@querySelectorAll('atom-pane'))
+3 -3
Ver Arquivo
@@ -23,7 +23,7 @@ class PaneContainerView extends View
@subscriptions.add @model.onDidChangeActivePaneItem(@onActivePaneItemChanged)
getRoot: ->
view = @model.getView(@model.getRoot())
view = @element.viewRegistry.getView(@model.getRoot())
view.__spacePenView ? view
onActivePaneItemChanged: (activeItem) =>
@@ -55,7 +55,7 @@ class PaneContainerView extends View
@getActivePaneView()
getActivePaneView: ->
@model.getView(@model.getActivePane()).__spacePenView
@element.viewRegistry.getView(@model.getActivePane()).__spacePenView
getActivePaneItem: ->
@model.getActivePaneItem()
@@ -64,7 +64,7 @@ class PaneContainerView extends View
@getActivePaneView()?.activeView
paneForUri: (uri) ->
@model.getView(@model.paneForUri(uri)).__spacePenView
@element.viewRegistry.getView(@model.paneForUri(uri)).__spacePenView
focusNextPaneView: ->
@model.activateNextPane()
+4 -9
Ver Arquivo
@@ -9,7 +9,6 @@ PaneAxisElement = require './pane-axis-element'
PaneAxis = require './pane-axis'
TextEditor = require './text-editor'
TextEditorElement = require './text-editor-element'
ViewRegistry = require './view-registry'
ItemRegistry = require './item-registry'
module.exports =
@@ -36,7 +35,6 @@ class PaneContainer extends Model
@subscriptions = new CompositeDisposable
@itemRegistry = new ItemRegistry
@viewRegistry = params?.viewRegistry ? new ViewRegistry
@registerViewProviders()
@setRoot(params?.root ? new Pane)
@@ -58,25 +56,22 @@ class PaneContainer extends Model
activePaneId: @activePane.id
registerViewProviders: ->
@viewRegistry.addViewProvider
atom.views.addViewProvider
modelConstructor: PaneContainer
viewConstructor: PaneContainerElement
@viewRegistry.addViewProvider
atom.views.addViewProvider
modelConstructor: PaneAxis
viewConstructor: PaneAxisElement
@viewRegistry.addViewProvider
atom.views.addViewProvider
modelConstructor: Pane
viewConstructor: PaneElement
@viewRegistry.addViewProvider
atom.views.addViewProvider
modelConstructor: TextEditor
viewConstructor: TextEditorElement
getView: (object) ->
@viewRegistry.getView(object)
onDidChangeRoot: (fn) ->
@emitter.on 'did-change-root', fn
+8 -8
Ver Arquivo
@@ -43,9 +43,7 @@ class PaneElement extends HTMLElement
createSpacePenShim: ->
@__spacePenView = new PaneView(this)
getModel: -> @model
setModel: (@model) ->
initialize: ({@viewRegistry, @model}) ->
@subscriptions.add @model.onDidActivate(@activated.bind(this))
@subscriptions.add @model.observeActive(@activeStatusChanged.bind(this))
@subscriptions.add @model.observeActiveItem(@activeItemChanged.bind(this))
@@ -53,8 +51,10 @@ class PaneElement extends HTMLElement
@subscriptions.add @model.onDidDestroy(@paneDestroyed.bind(this))
@__spacePenView.setModel(@model)
getModel: -> @model
activated: ->
@focus() unless @hasFocus()
@focus()
activeStatusChanged: (active) ->
if active
@@ -66,7 +66,7 @@ class PaneElement extends HTMLElement
return unless item?
hasFocus = @hasFocus()
itemView = @model.getView(item)
itemView = @viewRegistry.getView(item)
unless @itemViews.contains(itemView)
@itemViews.appendChild(itemView)
@@ -94,14 +94,14 @@ class PaneElement extends HTMLElement
itemView.style.display = 'none'
itemRemoved: ({item, index, destroyed}) ->
if viewToRemove = @model.getView(item)
callRemoveHooks(viewToRemove)
if viewToRemove = @viewRegistry.getView(item)
callRemoveHooks(viewToRemove) if destroyed
viewToRemove.remove()
paneDestroyed: ->
@subscriptions.dispose()
getActiveView: -> @model.getView(@model.getActiveItem())
getActiveView: -> @viewRegistry.getView(@model.getActiveItem())
hasFocus: ->
this is document.activeElement or @contains(document.activeElement)
+5 -5
Ver Arquivo
@@ -153,15 +153,15 @@ class PaneView extends View
activeItemModifiedChanged: =>
@trigger 'pane:active-item-modified-status-changed'
@::accessor 'activeView', -> @model.getView(@activeItem)?.__spacePenView
@::accessor 'activeView', -> @element.viewRegistry.getView(@activeItem)?.__spacePenView
splitLeft: (items...) -> @model.getView(@model.splitLeft({items})).__spacePenView
splitLeft: (items...) -> @element.viewRegistry.getView(@model.splitLeft({items})).__spacePenView
splitRight: (items...) -> @model.getView(@model.splitRight({items})).__spacePenView
splitRight: (items...) -> @element.viewRegistry.getView(@model.splitRight({items})).__spacePenView
splitUp: (items...) -> @model.getView(@model.splitUp({items})).__spacePenView
splitUp: (items...) -> @element.viewRegistry.getView(@model.splitUp({items})).__spacePenView
splitDown: (items...) -> @model.getView(@model.splitDown({items})).__spacePenView
splitDown: (items...) -> @element.viewRegistry.getView(@model.splitDown({items})).__spacePenView
getContainer: -> @closest('atom-pane-container').view()
-3
Ver Arquivo
@@ -53,9 +53,6 @@ class Pane extends Model
params.activeItem = find params.items, (item) -> item.getUri?() is activeItemUri
params
getView: (object) ->
@container.getView(object)
getParent: -> @parent
setParent: (@parent) -> @parent
+9 -4
Ver Arquivo
@@ -6,19 +6,24 @@ class PanelContainerElement extends HTMLElement
getModel: -> @model
setModel: (@model) ->
initialize: ({@viewRegistry, @model}) ->
@subscriptions.add @model.onDidAddPanel(@panelAdded.bind(this))
@subscriptions.add @model.onDidRemovePanel(@panelRemoved.bind(this))
@subscriptions.add @model.onDidDestroy(@destroyed.bind(this))
@classList.add(@model.getLocation())
panelAdded: ({panel, index}) ->
panelElement = panel.getView()
panelElement = @viewRegistry.getView(panel)
panelElement.classList.add(@model.getLocation())
if @model.isModal()
panelElement.classList.add("overlay", "from-top")
else
panelElement.classList.add("tool-panel", "panel-#{@model.getLocation()}")
if index >= @childNodes.length
@appendChild(panelElement)
else
referenceItem = @childNodes[index + 1]
referenceItem = @childNodes[index]
@insertBefore(panelElement, referenceItem)
if @model.isModal()
@@ -27,7 +32,7 @@ class PanelContainerElement extends HTMLElement
@hideAllPanelsExcept(panel) if visible
panelRemoved: ({panel, index}) ->
@removeChild(panel.getView())
@removeChild(@viewRegistry.getView(panel))
destroyed: ->
@subscriptions.dispose()
+1 -3
Ver Arquivo
@@ -2,7 +2,7 @@
module.exports =
class PanelContainer
constructor: ({@viewRegistry, @location}) ->
constructor: ({@location}={}) ->
@emitter = new Emitter
@subscriptions = new CompositeDisposable
@panels = []
@@ -30,8 +30,6 @@ class PanelContainer
Section: Panels
###
getView: -> @viewRegistry.getView(this)
getLocation: -> @location
isModal: -> @location is 'modal'
+6 -4
Ver Arquivo
@@ -7,16 +7,18 @@ class PanelElement extends HTMLElement
getModel: -> @model
setModel: (@model) ->
view = @model.getItemView()
@appendChild(view)
callAttachHooks(view) # for backward compatibility with SpacePen views
initialize: ({@viewRegistry, @model}) ->
@appendChild(@getItemView())
@classList.add(@model.getClassName().split(' ')...) if @model.getClassName()?
@subscriptions.add @model.onDidChangeVisible(@visibleChanged.bind(this))
@subscriptions.add @model.onDidDestroy(@destroyed.bind(this))
getItemView: ->
@viewRegistry.getView(@model.getItem())
attachedCallback: ->
callAttachHooks(@getItemView()) # for backward compatibility with SpacePen views
@visibleChanged(@model.isVisible())
visibleChanged: (visible) ->
+3 -10
Ver Arquivo
@@ -14,7 +14,7 @@ class Panel
Section: Construction and Destruction
###
constructor: ({@viewRegistry, @item, @visible, @priority, @className}) ->
constructor: ({@item, @visible, @priority, @className}) ->
@emitter = new Emitter
@visible ?= true
@priority ?= 100
@@ -50,15 +50,8 @@ class Panel
Section: Panel Details
###
# Public: Gets this panel model's view DOM node.
#
# Returns an `<atom-panel>` {Element}
getView: -> @viewRegistry.getView(this)
# Public: Gets your panel contents view.
#
# Returns an {Element} or jQuery element, depeneding on how you created the panel.
getItemView: -> @viewRegistry.getView(@item)
# Public: Returns the panel's item.
getItem: -> @item
# Public: Returns a {Number} indicating this panel's priority.
getPriority: -> @priority
+1 -1
Ver Arquivo
@@ -64,7 +64,7 @@ class Project extends Model
###
serializeParams: ->
path: @path
paths: @getPaths()
buffers: _.compact(@buffers.map (buffer) -> buffer.serialize() if buffer.isRetained())
deserializeParams: (params) ->
+1 -1
Ver Arquivo
@@ -1,6 +1,6 @@
{View} = require './space-pen-extensions'
# Extended: Represents a view that scrolls.
# Deprecated: Represents a view that scrolls.
#
# Handles several core events to update scroll position:
#
+1 -1
Ver Arquivo
@@ -2,7 +2,7 @@
TextEditorView = require './text-editor-view'
fuzzyFilter = require('fuzzaldrin').filter
# Essential: Provides a view that renders a list of items with an editor that
# Deprecated: Provides a view that renders a list of items with an editor that
# filters the items. Used by many packages such as the fuzzy-finder,
# command-palette, symbols-view and autocomplete.
#
+23 -34
Ver Arquivo
@@ -359,8 +359,11 @@ class Selection extends Model
@clear()
@cursor.needsAutoscroll = @cursor.isLastCursor()
precedingText = @editor.getTextInRange([[oldBufferRange.start.row, 0], oldBufferRange.start])
startLevel = @editor.indentLevelForLine(precedingText)
if options.indentBasis? and not options.autoIndent
text = @normalizeIndents(text, options.indentBasis)
text = @adjustIndent(text, startLevel - options.indentBasis)
newBufferRange = @editor.buffer.setTextInRange(oldBufferRange, text, pick(options, 'undo', 'normalizeLineEndings'))
@@ -562,8 +565,10 @@ class Selection extends Model
# cursor's horizontal position. (default: false)
copy: (maintainClipboard=false, fullLine=false) ->
return if @isEmpty()
selectionText = @editor.buffer.getTextInRange(@getBufferRange())
selectionIndentation = @editor.indentationForBufferRow(@getBufferRange().start.row)
{start, end} = @getBufferRange()
selectionText = @editor.getTextInRange([start, end])
precedingText = @editor.getTextInRange([[start.row, 0], start])
startLevel = @editor.indentLevelForLine(precedingText)
if maintainClipboard
{text: clipboardText, metadata} = atom.clipboard.readWithMetadata()
@@ -572,16 +577,17 @@ class Selection extends Model
metadata.selections = [{
text: clipboardText,
indentBasis: metadata.indentBasis,
fullLine: metadata.fullLine,
}]
metadata.selections.push({
text: selectionText,
indentBasis: selectionIndentation,
indentBasis: startLevel,
fullLine: fullLine
})
atom.clipboard.write([clipboardText, selectionText].join("\n"), metadata)
else
atom.clipboard.write(selectionText, {
indentBasis: selectionIndentation,
indentBasis: startLevel,
fullLine: fullLine
})
@@ -591,34 +597,22 @@ class Selection extends Model
@editor.createFold(range.start.row, range.end.row)
@cursor.setBufferPosition([range.end.row + 1, 0])
# Public: Indents the given text to the suggested level based on the grammar.
# Public: Increases the indentation level of
#
# * `text` The {String} to indent within the selection.
# * `indentBasis` The beginning indent level.
normalizeIndents: (text, indentBasis) ->
textPrecedingCursor = @cursor.getCurrentBufferLine()[0...@cursor.getBufferColumn()]
isCursorInsideExistingLine = /\S/.test(textPrecedingCursor)
# * `indentIncrease` The beginning indent level.
adjustIndent: (text, indentIncrease) ->
lines = text.split('\n')
firstLineIndentLevel = @editor.indentLevelForLine(lines[0])
if isCursorInsideExistingLine
minimumIndentLevel = @editor.indentationForBufferRow(@cursor.getBufferRow())
else
minimumIndentLevel = @cursor.getIndentLevel()
normalizedLines = []
for line, i in lines
if i == 0
indentLevel = 0
else if line == '' # remove all indentation from empty lines
indentLevel = 0
for line, i in lines when i > 0
if indentIncrease == 0
continue
else if indentIncrease > 0
lines[i] = @editor.buildIndentString(indentIncrease) + line
else
lineIndentLevel = @editor.indentLevelForLine(lines[i])
indentLevel = minimumIndentLevel + (lineIndentLevel - indentBasis)
normalizedLines.push(@setIndentationForLine(line, indentLevel))
normalizedLines.join('\n')
currentIndentLevel = @editor.indentLevelForLine(lines[i])
indentLevel = Math.max(0, currentIndentLevel + indentIncrease)
lines[i] = line.replace(/^[\t ]+/, @editor.buildIndentString(indentLevel))
lines.join('\n')
# Indent the current line(s).
#
@@ -651,11 +645,6 @@ class Selection extends Model
for row in [start..end]
@editor.buffer.insert([row, 0], @editor.getTabText()) unless @editor.buffer.lineLengthForRow(row) == 0
setIndentationForLine: (line, indentLevel) ->
desiredIndentLevel = Math.max(0, indentLevel)
desiredIndentString = @editor.buildIndentString(desiredIndentLevel)
line.replace(/^[\t ]*/, desiredIndentString)
###
Section: Managing multiple selections
###
+1 -1
Ver Arquivo
@@ -12,7 +12,7 @@ jQuery.cleanData = (elements) ->
SpacePenCallRemoveHooks = SpacePen.callRemoveHooks
SpacePen.callRemoveHooks = (element) ->
view.unsubscribe() for view in SpacePen.viewsForElement(element)
view.unsubscribe?() for view in SpacePen.viewsForElement(element)
SpacePenCallRemoveHooks(element)
NativeEventNames = new Set
+80
Ver Arquivo
@@ -1,5 +1,12 @@
fs = require 'fs-plus'
path = require 'path'
{Emitter, Disposable} = require 'event-kit'
# Extended: A singleton instance of this class available via `atom.styles`,
# which you can use to globally query and observe the set of active style
# sheets. The `StyleManager` doesn't add any style elements to the DOM on its
# own, but is instead subscribed to by individual `<atom-styles>` elements,
# which clone and attach style elements in different contexts.
module.exports =
class StyleManager
constructor: ->
@@ -7,19 +14,78 @@ class StyleManager
@styleElements = []
@styleElementsBySourcePath = {}
###
Section: Event Subscription
###
# Extended: Invoke `callback` for all current and future style elements.
#
# * `callback` {Function} that is called with style elements.
# * `styleElement` An `HTMLStyleElement` instance. The `.sheet` property
# will be null because this element isn't attached to the DOM. If you want
# to attach this element to the DOM, be sure to clone it first by calling
# `.cloneNode(true)` on it. The style element will also have the following
# non-standard properties:
# * `sourcePath` A {String} containing the path from which the style
# element was loaded.
# * `context` A {String} indicating the target context of the style
# element.
#
# Returns a {Disposable} on which `.dispose()` can be called to cancel the
# subscription.
observeStyleElements: (callback) ->
callback(styleElement) for styleElement in @getStyleElements()
@onDidAddStyleElement(callback)
# Extended: Invoke `callback` when a style element is added.
#
# * `callback` {Function} that is called with style elements.
# * `styleElement` An `HTMLStyleElement` instance. The `.sheet` property
# will be null because this element isn't attached to the DOM. If you want
# to attach this element to the DOM, be sure to clone it first by calling
# `.cloneNode(true)` on it. The style element will also have the following
# non-standard properties:
# * `sourcePath` A {String} containing the path from which the style
# element was loaded.
# * `context` A {String} indicating the target context of the style
# element.
#
# Returns a {Disposable} on which `.dispose()` can be called to cancel the
# subscription.
onDidAddStyleElement: (callback) ->
@emitter.on 'did-add-style-element', callback
# Extended: Invoke `callback` when a style element is removed.
#
# * `callback` {Function} that is called with style elements.
# * `styleElement` An `HTMLStyleElement` instance.
#
# Returns a {Disposable} on which `.dispose()` can be called to cancel the
# subscription.
onDidRemoveStyleElement: (callback) ->
@emitter.on 'did-remove-style-element', callback
# Extended: Invoke `callback` when an existing style element is updated.
#
# * `callback` {Function} that is called with style elements.
# * `styleElement` An `HTMLStyleElement` instance. The `.sheet` property
# will be null because this element isn't attached to the DOM. The style
# element will also have the following non-standard properties:
# * `sourcePath` A {String} containing the path from which the style
# element was loaded.
# * `context` A {String} indicating the target context of the style
# element.
#
# Returns a {Disposable} on which `.dispose()` can be called to cancel the
# subscription.
onDidUpdateStyleElement: (callback) ->
@emitter.on 'did-update-style-element', callback
###
Section: Reading Style Elements
###
# Extended: Get all loaded style elements.
getStyleElements: ->
@styleElements.slice()
@@ -85,3 +151,17 @@ class StyleManager
existingStyleElements = @getStyleElements()
for styleElement in styleElementsToRestore
@addStyleElement(styleElement) unless styleElement in existingStyleElements
###
Section: Paths
###
# Extended: Get the path of the user style sheet in `~/.atom`.
#
# Returns a {String}.
getUserStyleSheetPath: ->
stylesheetPath = fs.resolve(path.join(atom.getConfigDirPath(), 'styles'), ['css', 'less'])
if fs.isFileSync(stylesheetPath)
stylesheetPath
else
path.join(atom.getConfigDirPath(), 'styles.less')
+5 -7
Ver Arquivo
@@ -20,9 +20,6 @@ TextEditorComponent = React.createClass
displayName: 'TextEditorComponent'
mixins: [SubscriberMixin]
statics:
performSyncUpdates: false
visible: false
autoHeight: false
backgroundColor: null
@@ -199,7 +196,6 @@ TextEditorComponent = React.createClass
componentWillUnmount: ->
{editor, hostElement} = @props
hostElement.__spacePenView.trigger 'editor:will-be-removed', [hostElement.__spacePenView]
@unsubscribe()
@scopedConfigSubscriptions.dispose()
window.removeEventListener 'resize', @requestHeightAndWidthMeasurement
@@ -243,7 +239,7 @@ TextEditorComponent = React.createClass
@updateRequestedWhilePaused = true
return
if @performSyncUpdates ? TextEditorComponent.performSyncUpdates
if @props.hostElement.isUpdatedSynchronously()
@forceUpdate()
else unless @updateRequested
@updateRequested = true
@@ -364,14 +360,16 @@ TextEditorComponent = React.createClass
filteredDecorations = {}
for markerId, decorations of decorationsByMarkerId
marker = editor.getMarker(markerId)
headBufferPosition = marker.getHeadBufferPosition()
headScreenPosition = marker.getHeadScreenPosition()
tailScreenPosition = marker.getTailScreenPosition()
if marker.isValid()
for decoration in decorations
if decoration.isType('overlay')
decorationParams = decoration.getProperties()
filteredDecorations[markerId] ?=
id: markerId
headPixelPosition: editor.pixelPositionForScreenPosition(headBufferPosition)
headPixelPosition: editor.pixelPositionForScreenPosition(headScreenPosition)
tailPixelPosition: editor.pixelPositionForScreenPosition(tailScreenPosition)
decorations: []
filteredDecorations[markerId].decorations.push decorationParams
filteredDecorations
+20 -1
Ver Arquivo
@@ -63,6 +63,9 @@ class TextEditorElement extends HTMLElement
@component.checkForVisibilityChange()
@focus() if @focusOnAttach
initialize: ({@viewRegistry, @lineOverdrawMargin, model}) ->
@setModel(model)
setModel: (model) ->
throw new Error("Model already assigned on TextEditorElement") if @model?
return if model.isDestroyed()
@@ -103,7 +106,9 @@ class TextEditorElement extends HTMLElement
)
@component = React.renderComponent(@componentDescriptor, @rootElement)
unless @useShadowDOM
if @useShadowDOM
@shadowRoot.addEventListener('blur', @shadowRootBlurred.bind(this), true)
else
inputNode = @component.refs.input.getDOMNode()
inputNode.addEventListener 'focus', @focused.bind(this)
inputNode.addEventListener 'blur', => @dispatchEvent(new FocusEvent('blur', bubbles: false))
@@ -128,6 +133,16 @@ class TextEditorElement extends HTMLElement
@component?.blurred()
# Work around what seems to be a bug in Chromium. Focus can be stolen from the
# hidden input when clicking on the gutter and transferred to the
# already-focused host element. The host element never gets a 'focus' event
# however, which leaves us in a limbo state where the text editor element is
# focused but the hidden input isn't focused. This always refocuses the hidden
# input if a blur event occurs in the shadow DOM that is transferring focus
# back to the host element.
shadowRootBlurred: (event) ->
@component.focused() if event.relatedTarget is this
addGrammarScopeAttribute: ->
grammarScope = @model.getGrammar()?.scopeName?.replace(/\./g, ' ')
@dataset.grammar = grammarScope
@@ -141,6 +156,10 @@ class TextEditorElement extends HTMLElement
hasFocus: ->
this is document.activeElement or @contains(document.activeElement)
setUpdatedSynchronously: (@updatedSynchronously) -> @updatedSynchronously
isUpdatedSynchronously: -> @updatedSynchronously
stopEventPropagation = (commandListeners) ->
newCommandListeners = {}
for commandName, commandListener of commandListeners
+3 -2
Ver Arquivo
@@ -7,7 +7,7 @@ TextEditorElement = require './text-editor-element'
TextEditorComponent = require './text-editor-component'
{deprecate} = require 'grim'
# Public: Represents the entire visual pane in Atom.
# Deprecated: Represents the entire visual pane in Atom.
#
# The TextEditorView manages the {TextEditor}, which manages the file buffers.
# `TextEditorView` is intentionally sparse. Most of the things you'll want
@@ -63,7 +63,7 @@ class TextEditorView extends View
element = new TextEditorElement
element.lineOverdrawMargin = props?.lineOverdrawMargin
element.setAttribute(name, value) for name, value of attributes if attributes?
element.setModel(model)
element.initialize({model})
return element.__spacePenView
# Handle construction with an element
@@ -138,6 +138,7 @@ class TextEditorView extends View
beforeRemove: ->
@trigger 'editor:detached', [this]
@trigger 'editor:will-be-removed', [this]
@attached = false
remove: (selector, keepData) ->
+67 -25
Ver Arquivo
@@ -1098,34 +1098,49 @@ class TextEditor extends Model
# abort the transaction, call {::abortTransaction} to terminate the function's
# execution and revert any changes performed up to the abortion.
#
# * `groupingInterval` (optional) This is the sames as the `groupingInterval`
# parameter in {::beginTransaction}
# * `fn` A {Function} to call inside the transaction.
transact: (groupingInterval, fn) -> @buffer.transact(groupingInterval, fn)
# Extended: Start an open-ended transaction.
#
# Call {::commitTransaction} or {::abortTransaction} to terminate the
# transaction. If you nest calls to transactions, only the outermost
# transaction is considered. You must match every begin with a matching
# commit, but a single call to abort will cancel all nested transactions.
#
# * `groupingInterval` (optional) The {Number} of milliseconds for which this
# transaction should be considered 'groupable' after it begins. If a transaction
# with a positive `groupingInterval` is committed while the previous transaction is
# still 'groupable', the two transactions are merged with respect to undo and redo.
# * `fn` A {Function} to call inside the transaction.
transact: (groupingInterval, fn) -> @buffer.transact(groupingInterval, fn)
# Deprecated: Start an open-ended transaction.
beginTransaction: (groupingInterval) -> @buffer.beginTransaction(groupingInterval)
# Extended: Commit an open-ended transaction started with {::beginTransaction}
# and push it to the undo stack.
#
# If transactions are nested, only the outermost commit takes effect.
# Deprecated: Commit an open-ended transaction started with {::beginTransaction}.
commitTransaction: -> @buffer.commitTransaction()
# Extended: Abort an open transaction, undoing any operations performed so far
# within the transaction.
abortTransaction: -> @buffer.abortTransaction()
# Extended: Create a pointer to the current state of the buffer for use
# with {::revertToCheckpoint} and {::groupChangesSinceCheckpoint}.
#
# Returns a checkpoint value.
createCheckpoint: -> @buffer.createCheckpoint()
# Extended: Revert the buffer to the state it was in when the given
# checkpoint was created.
#
# The redo stack will be empty following this operation, so changes since the
# checkpoint will be lost. If the given checkpoint is no longer present in the
# undo history, no changes will be made to the buffer and this method will
# return `false`.
#
# Returns a {Boolean} indicating whether the operation succeeded.
revertToCheckpoint: (checkpoint) -> @buffer.revertToCheckpoint(checkpoint)
# Extended: Group all changes since the given checkpoint into a single
# transaction for purposes of undo/redo.
#
# If the given checkpoint is no longer present in the undo history, no
# grouping will be performed and this method will return `false`.
#
# Returns a {Boolean} indicating whether the operation succeeded.
groupChangesSinceCheckpoint: (checkpoint) -> @buffer.groupChangesSinceCheckpoint(checkpoint)
###
Section: TextEditor Coordinates
###
@@ -1248,18 +1263,33 @@ class TextEditor extends Model
# ## Arguments
#
# * `marker` A {Marker} you want this decoration to follow.
# * `decorationParams` An {Object} representing the decoration e.g. `{type: 'gutter', class: 'linter-error'}`
# * `type` There are a few supported decoration types: `gutter`, `line`, and `highlight`
# * `decorationParams` An {Object} representing the decoration e.g.
# `{type: 'gutter', class: 'linter-error'}`
# * `type` There are a few supported decoration types: `gutter`, `line`,
# `highlight`, and `overlay`. The behavior of the types are as follows:
# * `gutter` Adds the given `class` to the line numbers overlapping the
# rows spanned by the marker.
# * `line` Adds the given `class` to the lines overlapping the rows
# spanned by the marker.
# * `highlight` Creates a `.highlight` div with the nested class with up
# to 3 nested regions that fill the area spanned by the marker.
# * `overlay` Positions the view associated with the given item at the
# head or tail of the given marker, depending on the `position`
# property.
# * `class` This CSS class will be applied to the decorated line number,
# line, or highlight.
# * `onlyHead` (optional) If `true`, the decoration will only be applied to the head
# of the marker. Only applicable to the `line` and `gutter` types.
# * `onlyEmpty` (optional) If `true`, the decoration will only be applied if the
# associated marker is empty. Only applicable to the `line` and
# * `onlyHead` (optional) If `true`, the decoration will only be applied to
# the head of the marker. Only applicable to the `line` and `gutter`
# types.
# * `onlyEmpty` (optional) If `true`, the decoration will only be applied if
# the associated marker is empty. Only applicable to the `line` and
# `gutter` types.
# * `onlyNonEmpty` (optional) If `true`, the decoration will only be applied if the
# associated marker is non-empty. Only applicable to the `line` and
# gutter types.
# * `onlyNonEmpty` (optional) If `true`, the decoration will only be applied
# if the associated marker is non-empty. Only applicable to the `line`
# and gutter types.
# * `position` (optional) Only applicable to decorations of type `overlay`,
# controls where the overlay view is positioned relative to the marker.
# Values can be `'head'` (the default), or `'tail'`.
#
# Returns a {Decoration} object
decorateMarker: (marker, decorationParams) ->
@@ -1278,6 +1308,18 @@ class TextEditor extends Model
decorationsForScreenRowRange: (startScreenRow, endScreenRow) ->
@displayBuffer.decorationsForScreenRowRange(startScreenRow, endScreenRow)
# Extended: Get all decorations.
#
# Returns an {Array} of {Decoration}s.
getDecorations: ->
@displayBuffer.getDecorations()
# Extended: Get all decorations of type 'overlay'.
#
# Returns an {Array} of {Decoration}s.
getOverlayDecorations: ->
@displayBuffer.getOverlayDecorations()
decorationForId: (id) ->
@displayBuffer.decorationForId(id)
+31 -29
Ver Arquivo
@@ -6,7 +6,7 @@ EmitterMixin = require('emissary').Emitter
{File} = require 'pathwatcher'
fs = require 'fs-plus'
Q = require 'q'
{deprecate} = require 'grim'
Grim = require 'grim'
Package = require './package'
@@ -57,61 +57,66 @@ class ThemeManager
Section: Event Subscription
###
# Essential: Invoke `callback` when all styles have been reloaded.
# Essential: Invoke `callback` when style sheet changes associated with
# updating the list of active themes have completed.
#
# * `callback` {Function}
onDidReloadAll: (callback) ->
@emitter.on 'did-reload-all', callback
# Essential: Invoke `callback` when a stylesheet has been added to the dom.
# Deprecated: Invoke `callback` when a stylesheet has been added to the dom.
#
# * `callback` {Function}
# * `stylesheet` {StyleSheet} the style node
#
# Returns a {Disposable} on which `.dispose()` can be called to unsubscribe.
onDidAddStylesheet: (callback) ->
Grim.deprecate("Use atom.styles.onDidAddStyleElement instead")
@emitter.on 'did-add-stylesheet', callback
# Essential: Invoke `callback` when a stylesheet has been removed from the dom.
# Deprecated: Invoke `callback` when a stylesheet has been removed from the dom.
#
# * `callback` {Function}
# * `stylesheet` {StyleSheet} the style node
#
# Returns a {Disposable} on which `.dispose()` can be called to unsubscribe.
onDidRemoveStylesheet: (callback) ->
Grim.deprecate("Use atom.styles.onDidRemoveStyleElement instead")
@emitter.on 'did-remove-stylesheet', callback
# Essential: Invoke `callback` when a stylesheet has been updated.
# Deprecated: Invoke `callback` when a stylesheet has been updated.
#
# * `callback` {Function}
# * `stylesheet` {StyleSheet} the style node
#
# Returns a {Disposable} on which `.dispose()` can be called to unsubscribe.
onDidUpdateStylesheet: (callback) ->
Grim.deprecate("Use atom.styles.onDidUpdateStyleElement instead")
@emitter.on 'did-update-stylesheet', callback
# Essential: Invoke `callback` when any stylesheet has been updated, added, or removed.
# Deprecated: Invoke `callback` when any stylesheet has been updated, added, or removed.
#
# * `callback` {Function}
#
# Returns a {Disposable} on which `.dispose()` can be called to unsubscribe.
onDidChangeStylesheets: (callback) ->
Grim.deprecate("Use atom.styles.onDidAdd/RemoveStyleElement instead")
@emitter.on 'did-change-stylesheets', callback
on: (eventName) ->
switch eventName
when 'reloaded'
deprecate 'Use ThemeManager::onDidReloadAll instead'
Grim.deprecate 'Use ThemeManager::onDidReloadAll instead'
when 'stylesheet-added'
deprecate 'Use ThemeManager::onDidAddStylesheet instead'
Grim.deprecate 'Use ThemeManager::onDidAddStylesheet instead'
when 'stylesheet-removed'
deprecate 'Use ThemeManager::onDidRemoveStylesheet instead'
Grim.deprecate 'Use ThemeManager::onDidRemoveStylesheet instead'
when 'stylesheet-updated'
deprecate 'Use ThemeManager::onDidUpdateStylesheet instead'
Grim.deprecate 'Use ThemeManager::onDidUpdateStylesheet instead'
when 'stylesheets-changed'
deprecate 'Use ThemeManager::onDidChangeStylesheets instead'
Grim.deprecate 'Use ThemeManager::onDidChangeStylesheets instead'
else
deprecate 'ThemeManager::on is deprecated. Use event subscription methods instead.'
Grim.deprecate 'ThemeManager::on is deprecated. Use event subscription methods instead.'
EmitterMixin::on.apply(this, arguments)
###
@@ -197,18 +202,15 @@ class ThemeManager
atom.config.set('core.themes', enabledThemeNames)
###
Section: Managing Stylesheets
Section: Private
###
# Public: Returns the {String} path to the user's stylesheet under ~/.atom
# Returns the {String} path to the user's stylesheet under ~/.atom
getUserStylesheetPath: ->
stylesheetPath = fs.resolve(path.join(@configDirPath, 'styles'), ['css', 'less'])
if fs.isFileSync(stylesheetPath)
stylesheetPath
else
path.join(@configDirPath, 'styles.less')
Grim.deprecate("Call atom.styles.getUserStyleSheetPath() instead")
atom.styles.getUserStyleSheetPath()
# Public: Resolve and apply the stylesheet specified by the path.
# Resolve and apply the stylesheet specified by the path.
#
# This supports both CSS and Less stylsheets.
#
@@ -231,7 +233,7 @@ class ThemeManager
loadUserStylesheet: ->
@unwatchUserStylesheet()
userStylesheetPath = @getUserStylesheetPath()
userStylesheetPath = atom.styles.getUserStyleSheetPath()
return unless fs.isFileSync(userStylesheetPath)
@userStylesheetPath = userStylesheetPath
@@ -292,10 +294,6 @@ class ThemeManager
applyStylesheet: (path, text, type='bundled') ->
@styleSheetDisposablesBySourcePath[path] = atom.styles.addStyleSheet(text, sourcePath: path, group: type)
###
Section: Private
###
stringToId: (string) ->
string.replace(/\\/g, '/')
@@ -335,14 +333,18 @@ class ThemeManager
isInitialLoadComplete: -> @initialLoadComplete
# FIXME: This should be moved to WorkspaceElement
addActiveThemeClasses: ->
for pack in @getActiveThemes()
atom.workspaceView?[0]?.classList.add("theme-#{pack.name}")
if workspaceElement = document.querySelector('atom-workspace')
for pack in @getActiveThemes()
workspaceElement.classList.add("theme-#{pack.name}")
return
# FIXME: This should be moved to WorkspaceElement
removeActiveThemeClasses: ->
for pack in @getActiveThemes()
atom.workspaceView?[0]?.classList.remove("theme-#{pack.name}")
if workspaceElement = document.querySelector('atom-workspace')
for pack in @getActiveThemes()
workspaceElement.classList.remove("theme-#{pack.name}")
return
refreshLessCache: ->
+3 -3
Ver Arquivo
@@ -26,8 +26,8 @@ class TokenizedBuffer extends Model
constructor: ({@buffer, @tabLength, @invisibles}) ->
@emitter = new Emitter
@subscribe atom.syntax.onDidAddGrammar(@grammarAddedOrUpdated)
@subscribe atom.syntax.onDidUpdateGrammar(@grammarAddedOrUpdated)
@subscribe atom.grammars.onDidAddGrammar(@grammarAddedOrUpdated)
@subscribe atom.grammars.onDidUpdateGrammar(@grammarAddedOrUpdated)
@subscribe @buffer.preemptDidChange (e) => @handleBufferChange(e)
@subscribe @buffer.onDidChangePath (@bufferPath) => @reloadGrammar()
@@ -98,7 +98,7 @@ class TokenizedBuffer extends Model
@emitter.emit 'did-change-grammar', grammar
reloadGrammar: ->
if grammar = atom.syntax.selectGrammar(@buffer.getPath(), @buffer.getText())
if grammar = atom.grammars.selectGrammar(@buffer.getPath(), @buffer.getText())
@setGrammar(grammar)
else
throw new Error("No grammar found for path: #{path}")
+60
Ver Arquivo
@@ -0,0 +1,60 @@
_ = require 'underscore-plus'
{Disposable} = require 'event-kit'
{$} = require './space-pen-extensions'
# Essential: Associates tooltips with HTML elements or selectors.
module.exports =
class TooltipManager
defaults:
delay:
show: 1000
hide: 100
container: 'body'
html: true
placement: 'auto top'
viewportPadding: 2
# Essential: Add a tooltip to the given element.
#
# * `target` An `HTMLElement`
# * `options` See http://getbootstrap.com/javascript/#tooltips for a full list
# of options. You can also supply the following additional options:
# * `title` {String} Text in the tip.
# * `keyBindingCommand` A {String} containing a command name. If you specify
# this option and a key binding exists that matches the command, it will
# be appended to the title or rendered alone if no title is specified.
# * `keyBindingTarget` An `HTMLElement` on which to look up the key binding.
# If this option is not supplied, the first of all matching key bindings
# for the given command will be rendered.
#
# Returns a {Disposable} on which `.dispose()` can be called to remove the
# tooltip.
add: (target, options) ->
requireBootstrapTooltip()
{keyBindingCommand, keyBindingTarget} = options
if keyBindingCommand?
bindings = atom.keymaps.findKeyBindings(command: keyBindingCommand, target: keyBindingTarget)
if options.title?
options.title += " " + getKeystroke(bindings)
else
options.title = getKeystroke(bindings)
$target = $(target)
$target.tooltip(_.defaults(options, @defaults))
new Disposable -> $target.tooltip('destroy')
humanizeKeystrokes = (keystroke) ->
keystrokes = keystroke.split(' ')
keystrokes = (_.humanizeKeystroke(stroke) for stroke in keystrokes)
keystrokes.join(' ')
getKeystroke = (bindings) ->
if bindings?.length
"<span class=\"keystroke\">#{humanizeKeystrokes(bindings[0].keystrokes)}</span>"
else
requireBootstrapTooltip = _.once ->
atom.requireWithGlobals('bootstrap/js/tooltip', {jQuery: $})
+106
Ver Arquivo
@@ -0,0 +1,106 @@
{Disposable} = require 'event-kit'
Grim = require 'grim'
ViewRegistry = require './view-registry'
# Essential: The `ViewFactory` can creates the appropriate views for a given
# model object based on recipes registered via {::addViewProvider}. It is
# available via `atom.views` as a singleton object.
module.exports =
class ViewFactory
constructor: ->
@providers = []
@deprecatedViewRegistry = new ViewRegistry(this)
# Essential: Add a provider that will be used by {::createView} to construct
# an element based on the constructor of the given model object.
#
# ## Examples
#
# Text editors are divided into a model and a view layer, so when you interact
# with methods like `atom.workspace.getActiveTextEditor()` you're only going
# to get the model object. We display text editors on screen by teaching the
# workspace what view constructor it should use to represent them:
#
# ```coffee
# atom.views.addViewProvider
# modelConstructor: TextEditor
# viewConstructor: TextEditorElement
# ```
#
# * `providerSpec` {Object} containing the following keys:
# * `modelConstructor` Constructor {Function} for your model.
# * `viewConstructor` (Optional) Constructor {Function} for your view. It
# should be a subclass of `HTMLElement` (that is, your view should be a
# DOM node) and have a `::setModel()` method which will be called
# immediately after construction. If you don't supply this property, you
# must supply the `createView` property with a function that never returns
# `undefined`.
# * `createView` (Optional) Factory {Function} that must return a subclass
# of `HTMLElement` or `undefined`. If this property is not present or the
# function returns `undefined`, the view provider will fall back to the
# `viewConstructor` property. If you don't provide this property, you must
# provider a `viewConstructor` property.
#
# Returns a {Disposable} on which `.dispose()` can be called to remove the
# added provider.
addViewProvider: (providerSpec) ->
@providers.push(providerSpec)
new Disposable =>
@providers = @providers.filter (provider) -> provider isnt providerSpec
getView: (object, suppressDeprecationWarning) ->
unless suppressDeprecationWarning
Grim.deprecate("Call ::getView on the workspace element instead. The atom.views global is only intended to create views.")
@deprecatedViewRegistry.getView(object)
# Essential: Create an element for the given model object based on providers
# registered via {::addViewProvider}.
#
# ## Examples
#
# ### Creating a workspace element in specs
# ```coffee
# workspaceElement = atom.views.createView(atom.workspace)
# ```
#
# * `object` The model for which to create the view. A view provider matching
# its constructor must be registered.
# * `params` (optional) An {Object} with which to initialize the view. If the
# selected view provider has a `createView` method, the params will be
# passed to it. If the view provider has a `viewConstructor` method,
# `initialize` will be called on the element after creation with the
# given params.
#
# Returns a DOM element.
createView: (object, params) ->
view =
if object instanceof HTMLElement
object
else if object?.jquery
object[0]?.__spacePenView ?= object
object[0]
else if provider = @findProvider(object)
params ?= {}
params.viewFactory = this
params.model = object
element = provider.createView?(params)
unless element?
element = new provider.viewConstructor
if not (typeof element.initialize is 'function') and (typeof element.setModel is 'function')
Grim.deprecate("Define `::initialize` instead of `::setModel` in your view. It will be passed a params hash including the model.")
element.setModel(object)
else
element.initialize(params)
element
else if viewConstructor = object?.getViewClass?()
Grim.deprecate("Add a view provider for your object on atom.views instead of implementing `::getViewClass`.")
view = new viewConstructor(object)
view[0].__spacePenView ?= view
view[0]
else
throw new Error("Can't create a view for #{object.constructor.name} instance. Please register a view provider.")
@deprecatedViewRegistry.views.set(object, view)
view
findProvider: (object) ->
@providers.find ({modelConstructor}) -> object instanceof modelConstructor
+2 -132
Ver Arquivo
@@ -1,144 +1,14 @@
{Disposable} = require 'event-kit'
# Essential: `ViewRegistry` handles the association between model and view
# types in Atom. We call this association a View Provider. As in, for a given
# model, this class can provide a view via {::getView}, as long as the
# model/view association was registered via {::addViewProvider}
#
# If you're adding your own kind of pane item, a good strategy for all but the
# simplest items is to separate the model and the view. The model handles
# application logic and is the primary point of API interaction. The view
# just handles presentation.
#
# View providers to inform the workspace how your model objects should be
# presented in the DOM. A view provider must always return a DOM node, which
# makes [HTML 5 custom elements](http://www.html5rocks.com/en/tutorials/webcomponents/customelements/)
# an ideal tool for implementing views in Atom.
#
# You can access the `ViewRegistry` object via `atom.views`.
#
# ## Examples
#
# ### Getting the workspace element
#
# ```coffee
# workspaceElement = atom.views.getView(atom.workspace)
# ```
#
# ### Getting An Editor Element
#
# ```coffee
# textEditor = atom.workspace.getActiveTextEditor()
# textEditorElement = atom.views.getView(textEditor)
# ```
#
# ### Getting A Pane Element
#
# ```coffee
# pane = atom.workspace.getActivePane()
# paneElement = atom.views.getView(pane)
# ```
module.exports =
class ViewRegistry
constructor: ->
constructor: (@viewFactory) ->
@views = new WeakMap
@providers = []
# Essential: Add a provider that will be used to construct views in the
# workspace's view layer based on model objects in its model layer.
#
# ## Examples
#
# Text editors are divided into a model and a view layer, so when you interact
# with methods like `atom.workspace.getActiveTextEditor()` you're only going
# to get the model object. We display text editors on screen by teaching the
# workspace what view constructor it should use to represent them:
#
# ```coffee
# atom.views.addViewProvider
# modelConstructor: TextEditor
# viewConstructor: TextEditorElement
# ```
#
# * `providerSpec` {Object} containing the following keys:
# * `modelConstructor` Constructor {Function} for your model.
# * `viewConstructor` (Optional) Constructor {Function} for your view. It
# should be a subclass of `HTMLElement` (that is, your view should be a
# DOM node) and have a `::setModel()` method which will be called
# immediately after construction. If you don't supply this property, you
# must supply the `createView` property with a function that never returns
# `undefined`.
# * `createView` (Optional) Factory {Function} that must return a subclass
# of `HTMLElement` or `undefined`. If this property is not present or the
# function returns `undefined`, the view provider will fall back to the
# `viewConstructor` property. If you don't provide this property, you must
# provider a `viewConstructor` property.
#
# Returns a {Disposable} on which `.dispose()` can be called to remove the
# added provider.
addViewProvider: (providerSpec) ->
@providers.push(providerSpec)
new Disposable =>
@providers = @providers.filter (provider) -> provider isnt providerSpec
# Essential: Get the view associated with an object in the workspace.
#
# If you're just *using* the workspace, you shouldn't need to access the view
# layer, but view layer access may be necessary if you want to perform DOM
# manipulation that isn't supported via the model API.
#
# ## Examples
#
# ### Getting An Editor View
# ```coffee
# textEditor = atom.workspace.getActiveTextEditor()
# textEditorView = atom.views.getView(textEditor)
# ```
#
# ### Getting A Pane View
# ```coffee
# pane = atom.workspace.getActivePane()
# paneView = atom.views.getView(pane)
# ```
#
# ### Getting The Workspace View
#
# ```coffee
# workspaceView = atom.views.getView(atom.workspace)
# ```
#
# * `object` The object for which you want to retrieve a view. This can be a
# pane item, a pane, or the workspace itself.
#
# Returns a DOM element.
getView: (object) ->
return unless object?
if view = @views.get(object)
view
else
view = @createView(object)
view = @viewFactory.createView(object, viewRegistry: this)
@views.set(object, view)
view
createView: (object) ->
if object instanceof HTMLElement
object
else if object?.jquery
object[0]?.__spacePenView ?= object
object[0]
else if provider = @findProvider(object)
element = provider.createView?(object)
unless element?
element = new provider.viewConstructor
element.setModel(object)
element
else if viewConstructor = object?.getViewClass?()
view = new viewConstructor(object)
view[0].__spacePenView ?= view
view[0]
else
throw new Error("Can't create a view for #{object.constructor.name} instance. Please register a view provider.")
findProvider: (object) ->
@providers.find ({modelConstructor}) -> object instanceof modelConstructor
+27 -12
Ver Arquivo
@@ -14,12 +14,35 @@ class WindowEventHandler
constructor: ->
@reloadRequested = false
@subscribe ipc, 'message', (message, detail) ->
switch message
when 'open-path'
{pathToOpen, initialLine, initialColumn} = detail
unless atom.project?.getPaths().length
if fs.existsSync(pathToOpen) or fs.existsSync(path.dirname(pathToOpen))
atom.project?.setPaths([pathToOpen])
unless fs.isDirectorySync(pathToOpen)
atom.workspace?.open(pathToOpen, {initialLine, initialColumn})
when 'update-available'
atom.updateAvailable(detail)
# FIXME: Remove this when deprecations are removed
{releaseVersion, releaseNotes} = detail
detail = [releaseVersion, releaseNotes]
if workspaceElement = document.querySelector('atom-workspace')
atom.commands.dispatch workspaceElement, "window:update-available", detail
@subscribe ipc, 'command', (command, args...) ->
activeElement = document.activeElement
# Use root view if body has focus
if activeElement is document.body and atom.workspaceView?
activeElement = atom.workspaceView
$(activeElement).trigger(command, args...)
# Use the workspace element view if body has focus
if activeElement is document.body and workspaceElement = document.querySelector('atom-workspace')
activeElement = workspaceElement
atom.commands.dispatch(activeElement, command, args[0])
@subscribe ipc, 'context-command', (command, args...) ->
$(atom.contextMenu.activeElement).trigger(command, args...)
@@ -28,14 +51,6 @@ class WindowEventHandler
@subscribe $(window), 'blur', -> document.body.classList.add('is-blurred')
@subscribeToCommand $(window), 'window:open-path', (event, {pathToOpen, initialLine, initialColumn}) ->
unless atom.project?.getPath()
if fs.existsSync(pathToOpen) or fs.existsSync(path.dirname(pathToOpen))
atom.project?.setPath(pathToOpen)
unless fs.isDirectorySync(pathToOpen)
atom.workspace?.open(pathToOpen, {initialLine, initialColumn})
@subscribe $(window), 'beforeunload', =>
confirmed = atom.workspace?.confirmClose()
atom.hide() if confirmed and not @reloadRequested and atom.getCurrentWindow().isWebViewFocused()
+63 -8
Ver Arquivo
@@ -6,9 +6,37 @@ scrollbarStyle = require 'scrollbar-style'
{callAttachHooks} = require 'space-pen'
WorkspaceView = null
# Essential: The on-screen representation of the workspace. Unless you have
# an explicit need access the view layer, you should prefer using the
# {Workspace} model object via `atom.workspace`.
#
# ## Examples
#
# In specs, you can create a workspace element via the view factory and attach
# it to the DOM:
#
# ```coffee
# workspaceElement = atom.views.createElement(atom.workspace)
# jasmine.attachToDOM(workspaceElement)
#
# # Get a reference to a nested element corresponding to a model object...
# editorElement = workspaceElement.getView(atom.workspace.getActiveTextEditor)
# ```
#
# In production, you can access the singleton instance of the workspace element
# by pulling it directly from the DOM:
#
# ```coffee
# workspaceElement = document.querySelector('atom-workspace')
#
# # Careful! Direct DOM manipulation is more likely to break as Atom changes
# workspaceElement.addClass("foo")
# ```
module.exports =
class WorkspaceElement extends HTMLElement
globalTextEditorStyleSheet: null
viewRegistry: null
model: null
createdCallback: ->
@subscriptions = new CompositeDisposable
@@ -62,19 +90,20 @@ class WorkspaceElement extends HTMLElement
WorkspaceView ?= require './workspace-view'
@__spacePenView = new WorkspaceView(this)
getModel: -> @model
initialize: ({@viewFactory, @model}) ->
@viewRegistry = @viewFactory.deprecatedViewRegistry
atom.views.deprecatedViewRegistry = @viewRegistry
setModel: (@model) ->
@paneContainer = atom.views.getView(@model.paneContainer)
@paneContainer = @viewRegistry.getView(@model.paneContainer)
@verticalAxis.appendChild(@paneContainer)
@addEventListener 'focus', @handleFocus.bind(this)
@panelContainers =
top: @model.panelContainers.top.getView()
left: @model.panelContainers.left.getView()
right: @model.panelContainers.right.getView()
bottom: @model.panelContainers.bottom.getView()
modal: @model.panelContainers.modal.getView()
top: @viewRegistry.getView(@model.panelContainers.top)
left: @viewRegistry.getView(@model.panelContainers.left)
right: @viewRegistry.getView(@model.panelContainers.right)
bottom: @viewRegistry.getView(@model.panelContainers.bottom)
modal: @viewRegistry.getView(@model.panelContainers.modal)
@horizontalAxis.insertBefore(@panelContainers.left, @verticalAxis)
@horizontalAxis.appendChild(@panelContainers.right)
@@ -86,6 +115,32 @@ class WorkspaceElement extends HTMLElement
@__spacePenView.setModel(@model)
getModel: -> @model
# Essential: Get the view associated with a model in the workspace.
#
# ## Examples
#
# ### Get the active text editor's view element
# ```coffee
# # At the model level...
# activeTextEditor = atom.workspace.getActiveTextEditor()
#
# # At the view level...
# workspaceElement = document.querySelector('atom-workspace')
# textEditorElement = workspaceElement.getView(activeTextEditor)
#
# # Now manipulate the text editor's DOM at your own risk...
# ```
#
# * `model` A model object that's present in the workspace. It could be a
# workspace model object such as a {Pane} or a {Panel}, or it could be a
# third-party model such as a pane or panel's *item*.
#
# Returns a DOM element.
getView: (model) ->
@viewRegistry.getView(model)
setTextEditorFontSize: (fontSize) ->
@updateGlobalEditorStyle('font-size', fontSize + 'px')
+2 -2
Ver Arquivo
@@ -12,7 +12,7 @@ PaneView = require './pane-view'
PaneContainerView = require './pane-container-view'
TextEditor = require './text-editor'
# Extended: The top-level view for the entire window. An instance of this class is
# Deprecated: The top-level view for the entire window. An instance of this class is
# available via the `atom.workspaceView` global.
#
# It is backed by a model object, an instance of {Workspace}, which is available
@@ -59,7 +59,7 @@ class WorkspaceView extends View
constructor: (@element) ->
unless @element?
return atom.views.getView(atom.workspace).__spacePenView
return atom.views.getView(atom.workspace, true).__spacePenView
super
@deprecateViewEvents()
+57 -31
Ver Arquivo
@@ -14,7 +14,6 @@ Panel = require './panel'
PanelElement = require './panel-element'
PanelContainer = require './panel-container'
PanelContainerElement = require './panel-container-element'
ViewRegistry = require './view-registry'
WorkspaceElement = require './workspace-element'
# Essential: Represents the state of the user interface for the entire window.
@@ -34,7 +33,6 @@ class Workspace extends Model
@delegatesProperty 'activePane', 'activePaneItem', toProperty: 'paneContainer'
@properties
viewRegistry: null
paneContainer: null
fullScreen: false
destroyedItemUris: -> []
@@ -45,23 +43,22 @@ class Workspace extends Model
@emitter = new Emitter
@openers = []
viewRegistry = atom.views
@paneContainer ?= new PaneContainer({viewRegistry})
@paneContainer ?= new PaneContainer()
@paneContainer.onDidDestroyPaneItem(@onPaneItemDestroyed)
@panelContainers =
top: new PanelContainer({viewRegistry, location: 'top'})
left: new PanelContainer({viewRegistry, location: 'left'})
right: new PanelContainer({viewRegistry, location: 'right'})
bottom: new PanelContainer({viewRegistry, location: 'bottom'})
modal: new PanelContainer({viewRegistry, location: 'modal'})
top: new PanelContainer({location: 'top'})
left: new PanelContainer({location: 'left'})
right: new PanelContainer({location: 'right'})
bottom: new PanelContainer({location: 'bottom'})
modal: new PanelContainer({location: 'modal'})
@subscribeToActiveItem()
@addOpener (filePath) =>
switch filePath
when 'atom://.atom/stylesheet'
@open(atom.themes.getUserStylesheetPath())
@open(atom.styles.getUserStyleSheetPath())
when 'atom://.atom/keymap'
@open(atom.keymaps.getUserKeymapPath())
when 'atom://.atom/config'
@@ -86,7 +83,6 @@ class Workspace extends Model
for packageName in params.packagesWithActiveGrammars ? []
atom.packages.getLoadedPackage(packageName)?.loadGrammarsSync()
params.paneContainer.viewRegistry = atom.views
params.paneContainer = PaneContainer.deserialize(params.paneContainer)
params
@@ -105,13 +101,13 @@ class Workspace extends Model
packageNames.push(packageName)
for scopeName in includedGrammarScopes ? []
addGrammar(atom.syntax.grammarForScopeName(scopeName))
addGrammar(atom.grammars.grammarForScopeName(scopeName))
editors = @getTextEditors()
addGrammar(editor.getGrammar()) for editor in editors
if editors.length > 0
for grammar in atom.syntax.getGrammars() when grammar.injectionSelector
for grammar in atom.grammars.getGrammars() when grammar.injectionSelector
addGrammar(grammar)
_.uniq(packageNames)
@@ -377,11 +373,15 @@ class Workspace extends Model
# * `activatePane` A {Boolean} indicating whether to call {Pane::activate} on
# the containing pane. Defaults to `true`.
openSync: (uri='', options={}) ->
deprecate("Don't use the `changeFocus` option") if options.changeFocus?
# TODO: Remove deprecated changeFocus option
if options.changeFocus?
deprecate("The `changeFocus` option has been renamed to `activatePane`")
options.activatePane = options.changeFocus
delete options.changeFocus
{initialLine, initialColumn} = options
# TODO: Remove deprecated changeFocus option
activatePane = options.activatePane ? options.changeFocus ? true
activatePane = options.activatePane ? true
uri = atom.project.resolve(uri)
item = @activePane.itemForUri(uri)
@@ -395,7 +395,13 @@ class Workspace extends Model
item
openUriInPane: (uri, pane, options={}) ->
changeFocus = options.changeFocus ? true
# TODO: Remove deprecated changeFocus option
if options.changeFocus?
deprecate("The `changeFocus` option has been renamed to `activatePane`")
options.activatePane = options.changeFocus
delete options.changeFocus
activatePane = options.activatePane ? true
if uri?
item = pane.itemForUri(uri)
@@ -409,7 +415,7 @@ class Workspace extends Model
@paneContainer.root = pane
@itemOpened(item)
pane.activateItem(item)
pane.activate() if changeFocus
pane.activate() if activatePane
index = pane.getActiveItemIndex()
@emit "uri-opened"
@emitter.emit 'did-open', {uri, pane, item, index}
@@ -609,12 +615,16 @@ class Workspace extends Model
Section: Panels
###
# Essential: Get an {Array} of all the panel items at the bottom of the editor window.
getBottomPanels: ->
@getPanels('bottom')
# Essential: Adds a panel item to the bottom of the editor window.
#
# * `options` {Object}
# * `item` Your panel content. It can be DOM element, a jQuery element, or
# a model with a view registered via {ViewRegistry::addViewProvider}. We recommend the
# latter. See {ViewRegistry::addViewProvider} for more information.
# a model with a view registered via {ViewFactory::addViewProvider}. We recommend the
# latter. See {ViewFactory::addViewProvider} for more information.
# * `visible` (optional) {Boolean} false if you want the panel to initially be hidden
# (default: true)
# * `priority` (optional) {Number} Determines stacking order. Lower priority items are
@@ -624,12 +634,16 @@ class Workspace extends Model
addBottomPanel: (options) ->
@addPanel('bottom', options)
# Essential: Get an {Array} of all the panel items to the left of the editor window.
getLeftPanels: ->
@getPanels('left')
# Essential: Adds a panel item to the left of the editor window.
#
# * `options` {Object}
# * `item` Your panel content. It can be DOM element, a jQuery element, or
# a model with a view registered via {ViewRegistry::addViewProvider}. We recommend the
# latter. See {ViewRegistry::addViewProvider} for more information.
# a model with a view registered via {ViewFactory::addViewProvider}. We recommend the
# latter. See {ViewFactory::addViewProvider} for more information.
# * `visible` (optional) {Boolean} false if you want the panel to initially be hidden
# (default: true)
# * `priority` (optional) {Number} Determines stacking order. Lower priority items are
@@ -639,12 +653,16 @@ class Workspace extends Model
addLeftPanel: (options) ->
@addPanel('left', options)
# Essential: Get an {Array} of all the panel items to the right of the editor window.
getRightPanels: ->
@getPanels('right')
# Essential: Adds a panel item to the right of the editor window.
#
# * `options` {Object}
# * `item` Your panel content. It can be DOM element, a jQuery element, or
# a model with a view registered via {ViewRegistry::addViewProvider}. We recommend the
# latter. See {ViewRegistry::addViewProvider} for more information.
# a model with a view registered via {ViewFactory::addViewProvider}. We recommend the
# latter. See {ViewFactory::addViewProvider} for more information.
# * `visible` (optional) {Boolean} false if you want the panel to initially be hidden
# (default: true)
# * `priority` (optional) {Number} Determines stacking order. Lower priority items are
@@ -654,12 +672,16 @@ class Workspace extends Model
addRightPanel: (options) ->
@addPanel('right', options)
# Essential: Get an {Array} of all the panel items at the top of the editor window.
getTopPanels: ->
@getPanels('top')
# Essential: Adds a panel item to the top of the editor window above the tabs.
#
# * `options` {Object}
# * `item` Your panel content. It can be DOM element, a jQuery element, or
# a model with a view registered via {ViewRegistry::addViewProvider}. We recommend the
# latter. See {ViewRegistry::addViewProvider} for more information.
# a model with a view registered via {ViewFactory::addViewProvider}. We recommend the
# latter. See {ViewFactory::addViewProvider} for more information.
# * `visible` (optional) {Boolean} false if you want the panel to initially be hidden
# (default: true)
# * `priority` (optional) {Number} Determines stacking order. Lower priority items are
@@ -669,12 +691,16 @@ class Workspace extends Model
addTopPanel: (options) ->
@addPanel('top', options)
# Essential: Get an {Array} of all the modal panel items
getModalPanels: ->
@getPanels('modal')
# Essential: Adds a panel item as a modal dialog.
#
# * `options` {Object}
# * `item` Your panel content. It can be DOM element, a jQuery element, or
# a model with a view registered via {ViewRegistry::addViewProvider}. We recommend the
# latter. See {ViewRegistry::addViewProvider} for more information.
# a model with a view registered via {ViewFactory::addViewProvider}. We recommend the
# latter. See {ViewFactory::addViewProvider} for more information.
# * `visible` (optional) {Boolean} false if you want the panel to initially be hidden
# (default: true)
# * `priority` (optional) {Number} Determines stacking order. Lower priority items are
@@ -682,11 +708,11 @@ class Workspace extends Model
#
# Returns a {Panel}
addModalPanel: (options={}) ->
# TODO: remove these default classes. They are to supoprt existing themes.
options.className ?= 'overlay from-top'
@addPanel('modal', options)
getPanels: (location) ->
@panelContainers[location].getPanels()
addPanel: (location, options) ->
options ?= {}
options.viewRegistry = atom.views
@panelContainers[location].addPanel(new Panel(options))
+18
Ver Arquivo
@@ -2,8 +2,26 @@ window.onload = function() {
try {
var startTime = Date.now();
var fs = require('fs');
var path = require('path');
// Patch fs.statSyncNoException/fs.lstatSyncNoException to fail for non-strings
// https://github.com/atom/atom-shell/issues/843
var statSyncNoException = fs.statSyncNoException;
var lstatSyncNoException = fs.lstatSyncNoException;
fs.statSyncNoException = function(pathToStat) {
if (pathToStat && typeof pathToStat === 'string')
return statSyncNoException(pathToStat);
else
return false;
};
fs.lstatSyncNoException = function(pathToStat) {
if (pathToStat && typeof pathToStat === 'string')
return lstatSyncNoException(pathToStat);
else
return false;
};
// Skip "?loadSettings=".
var loadSettings = JSON.parse(decodeURIComponent(location.search.substr(14)));
+12 -1
Ver Arquivo
@@ -136,7 +136,18 @@ body {
}
.result-message.deprecation-message {
color: #f0ad4e;
font-weight: normal;
color: darken(#f0ad4e, 20%);
line-height: 1.4;
a {
color: darken(#f0ad4e, 15%);
}
code {
color: darken(#f0ad4e, 20%);
background: lighten(#f0ad4e, 35%);
}
}
.stack-trace {
-10
Ver Arquivo
@@ -64,13 +64,3 @@ div > .inline-block-tight:last-child {
margin-left: 0;
}
}
.error {
-webkit-animation: flash-error 0.3s ease-in;
}
@-webkit-keyframes flash-error {
0% { background: @background-color-error; }
100% { background: auto; }
}