Comparar commits

..

23 Commits

Autor SHA1 Mensagem Data
Nathan Sobo 57a0febbef ⬆️ atom-space-pen-views for bugfix 2014-11-03 18:02:42 -07:00
Nathan Sobo b274955539 ⬆️ atom-space-pen-views for bugfix 2014-11-03 17:47:00 -07:00
Nathan Sobo a9f72ed535 Continue to use legacy attach hooks on exported legacy space pen views 2014-11-03 17:37:03 -07:00
Nathan Sobo 4991df24df ⬆️ atom-space-pen-views 2014-11-03 17:27:11 -07:00
Nathan Sobo baf2de8f26 Allow Jasmine jQuery matchers to work on any instance of jQuery 2014-11-03 17:24:00 -07:00
Nathan Sobo ce97372cfb Upgrade jQuery to make $.fn.view interoperable 2014-11-03 17:23:29 -07:00
Nathan Sobo 710b1033fe Inject Atom’s view prototype as the prototype of the new SpacePen view
This way the attached and detached hooks still work as expected, but
we get all the Atom-specific functionality too.
2014-11-03 15:46:58 -07:00
Nathan Sobo f4082d5ae6 Avoid adjusting prototypes of SpacePenViews globally
The only constructors that get their prototypes adjusted are the ones
that are exported from exports/atom.coffee.
2014-11-03 14:47:33 -07:00
Nathan Sobo 0c12d9f5de ⬆️ atom-space-pen-views and enhance deprecated exported views
The atom-space-pen-views library now imports its own version of SpacePen
without a lot of the extensions that we add in the version we export
in Atom. In order to maintain the same functionality in the views we
export, we need to update their prototypes to point at the enhanced
SpacePen views instead.
2014-11-03 13:46:51 -07:00
Nathan Sobo eabca9422d Export event-kit classes from exports/atom.coffee
CompositeDisposable is needed by TextEditorView, which is now extracted
to the atom-space-pen-views library.
2014-11-03 13:43:20 -07:00
Nathan Sobo 2728ae9fa6 Add TextEditorElement onDidAttach/Detach for space-pen TextEditorView 2014-11-03 13:42:09 -07:00
Nathan Sobo bf90940a83 Remove unused requires 2014-11-03 11:42:13 -07:00
Nathan Sobo 20d06d0a09 Extract SelectList stylesheet to atom-space-pen-views library 2014-11-03 11:37:26 -07:00
Nathan Sobo 753e295660 Extract ScrollView to atom-space-pen-views library 2014-11-03 11:30:16 -07:00
Nathan Sobo ebc579af6f ⬆️ atom-space-pen-views for bugfix 2014-10-30 17:56:06 -06:00
Nathan Sobo 1d9d31ffd3 Extract SeletListView to atom-space-pen-views library 2014-10-30 17:37:24 -06:00
Nathan Sobo f9d146c6d4 Extract TextEditorView to atom-space-pen-views library 2014-10-30 17:28:37 -06:00
Nathan Sobo ae576a9202 Export TextEditorElement from atom module 2014-10-30 17:00:21 -06:00
Nathan Sobo 25556e1d08 Import View and $ from atom exports 2014-10-30 16:58:09 -06:00
Nathan Sobo c95b638b57 Use Grim.deprecate instead of assigning deprecate local 2014-10-30 16:50:47 -06:00
Nathan Sobo 223afada7f Eliminate TextEditor dependency in TextEditorView shim 2014-10-30 16:50:32 -06:00
Nathan Sobo 9b04b82dc1 Eliminate unused requires in text-editor-view.coffee 2014-10-30 16:36:28 -06:00
Nathan Sobo ef24886243 Construct a TextBuffer automatically in TextEditor if none is provided 2014-10-30 16:35:16 -06:00
62 arquivos alterados com 656 adições e 1968 exclusões
+1 -1
Ver Arquivo
@@ -63,7 +63,7 @@ if [ $OS == 'Mac' ]; then
"$ATOM_PATH/$ATOM_APP_NAME/Contents/MacOS/Atom" --executed-from="$(pwd)" --pid=$$ "$@"
exit $?
else
open -a "$ATOM_PATH/$ATOM_APP_NAME" -n --args --executed-from="$(pwd)" --pid=$$ --path-environment="$PATH" "$@"
open -a "$ATOM_PATH/$ATOM_APP_NAME" -n --args --executed-from="$(pwd)" --pid=$$ "$@"
fi
elif [ $OS == 'Linux' ]; then
SCRIPT=$(readlink -f "$0")
+35 -4
Ver Arquivo
@@ -1,4 +1,5 @@
{Point, Range} = require 'text-buffer'
{Emitter, Disposable, CompositeDisposable} = require 'event-kit'
{deprecate} = require 'grim'
module.exports =
@@ -13,19 +14,49 @@ module.exports =
unless process.env.ATOM_SHELL_INTERNAL_RUN_AS_NODE
{$, $$, $$$, View} = require '../src/space-pen-extensions'
module.exports.Emitter = Emitter
module.exports.Disposable = Disposable
module.exports.CompositeDisposable = CompositeDisposable
module.exports.$ = $
module.exports.$$ = $$
module.exports.$$$ = $$$
module.exports.TextEditorView = require '../src/text-editor-view'
module.exports.ScrollView = require '../src/scroll-view'
module.exports.SelectListView = require '../src/select-list-view'
module.exports.Task = require '../src/task'
module.exports.View = View
module.exports.TextEditorElement = require '../src/text-editor-element'
module.exports.Task = require '../src/task'
module.exports.WorkspaceView = require '../src/workspace-view'
module.exports.Workspace = require '../src/workspace'
module.exports.React = require 'react-atom-fork'
module.exports.Reactionary = require 'reactionary-atom-fork'
# Export deprecated SpacePen views.
# Adjust their prototype chain to inherit from our extend version of SpacePen
#
# We avoid using/assigning a cached module for these classes in order to
# prevent polluting every required version with these changes. The only
# versions that should get their prototypes adjusted are the ones exported
# here.
uncachedRequire = (id) ->
modulePath = require.resolve(id)
delete require.cache[modulePath]
loadedModule = require(modulePath)
delete require.cache[modulePath]
loadedModule
TextEditorView = uncachedRequire 'atom-space-pen-views/lib/text-editor-view'
ScrollView = uncachedRequire 'atom-space-pen-views/lib/scroll-view'
SelectListView = uncachedRequire 'atom-space-pen-views/lib/select-list-view'
# Make Atom's modified SpacePen View prototype the prototype of the imported View
TextEditorView.prototype.__proto__.__proto__ = View.prototype
TextEditorView.prototype.__proto__.useLegacyAttachHooks = true
module.exports.TextEditorView = TextEditorView
module.exports.ScrollView = ScrollView
module.exports.SelectListView = SelectListView
Object.defineProperty module.exports, 'Git', get: ->
deprecate "Please require `GitRepository` instead of `Git`: `{GitRepository} = require 'atom'`"
module.exports.GitRepository
-3
Ver Arquivo
@@ -15,9 +15,6 @@
'shift-tab': 'editor:outdent-selected-rows'
'ctrl-K': 'editor:delete-line'
'.select-list atom-text-editor.mini':
'enter': 'core:confirm'
'.tool-panel.panel-left, .tool-panel.panel-right':
'escape': 'tool-panel:unfocus'
-2
Ver Arquivo
@@ -14,8 +14,6 @@
'ctrl-alt-i': 'window:toggle-dev-tools'
'ctrl-alt-p': 'window:run-package-specs'
'ctrl-alt-s': 'application:run-all-specs'
'ctrl-alt-o': 'application:open-dev'
'ctrl-shift-o': 'application:open-folder'
'F11': 'window:toggle-full-screen'
# Sublime Parity
+17 -16
Ver Arquivo
@@ -1,4 +1,4 @@
{
{
"name": "atom",
"productName": "Atom",
"version": "0.142.0",
@@ -17,10 +17,11 @@
"url": "http://github.com/atom/atom/raw/master/LICENSE.md"
}
],
"atomShellVersion": "0.19.1",
"atomShellVersion": "0.18.2",
"dependencies": {
"async": "0.2.6",
"atom-keymap": "^2.2.1",
"atom-space-pen-views": "^0.11.0",
"bootstrap": "git+https://github.com/atom/bootstrap.git#6af81906189f1747fd6c93479e3d998ebe041372",
"clear-cut": "0.4.0",
"coffee-script": "1.7.0",
@@ -56,9 +57,9 @@
"season": "^1.0.2",
"semver": "2.2.1",
"serializable": "^1",
"space-pen": "3.8.0",
"space-pen": "^3.8.1",
"temp": "0.7.0",
"text-buffer": "^3.5.1",
"text-buffer": "^3.4",
"theorist": "^1.0.2",
"underscore-plus": "^1.6.1",
"vm-compatibility-layer": "0.1.0"
@@ -73,7 +74,7 @@
"solarized-dark-syntax": "0.22.0",
"solarized-light-syntax": "0.12.0",
"archive-view": "0.37.0",
"autocomplete": "0.33.0",
"autocomplete": "0.32.0",
"autoflow": "0.18.0",
"autosave": "0.18.0",
"background-tips": "0.17.0",
@@ -84,7 +85,7 @@
"dev-live-reload": "0.35.0",
"encoding-selector": "0.5.0",
"exception-reporting": "0.20.0",
"find-and-replace": "0.143.0",
"find-and-replace": "0.141.0",
"fuzzy-finder": "0.60.0",
"git-diff": "0.42.0",
"go-to-line": "0.26.0",
@@ -93,25 +94,25 @@
"incompatible-packages": "0.10.0",
"keybinding-resolver": "0.20.0",
"link": "0.26.0",
"markdown-preview": "0.109.0",
"metrics": "0.37.0",
"markdown-preview": "0.107.0",
"metrics": "0.36.0",
"open-on-github": "0.30.0",
"package-generator": "0.32.0",
"package-generator": "0.31.0",
"release-notes": "0.36.0",
"settings-view": "0.154.0",
"snippets": "0.56.0",
"spell-check": "0.43.0",
"status-bar": "0.46.0",
"styleguide": "0.30.0",
"symbols-view": "0.67.0",
"symbols-view": "0.66.0",
"tabs": "0.55.0",
"timecop": "0.23.0",
"tree-view": "0.132.0",
"tree-view": "0.131.0",
"update-package-dependencies": "0.6.0",
"welcome": "0.19.0",
"whitespace": "0.26.0",
"wrap-guide": "0.23.0",
"language-c": "0.30.0",
"language-c": "0.29.0",
"language-coffee-script": "0.37.0",
"language-css": "0.21.0",
"language-gfm": "0.53.0",
@@ -120,20 +121,20 @@
"language-html": "0.26.0",
"language-hyperlink": "0.12.0",
"language-java": "0.11.0",
"language-javascript": "0.43.0",
"language-javascript": "0.42.0",
"language-json": "0.8.0",
"language-less": "0.18.0",
"language-make": "0.12.0",
"language-mustache": "0.10.0",
"language-objective-c": "0.11.0",
"language-perl": "0.9.0",
"language-php": "0.18.0",
"language-php": "0.17.0",
"language-property-list": "0.7.0",
"language-python": "0.22.0",
"language-python": "0.21.0",
"language-ruby": "0.41.0",
"language-ruby-on-rails": "0.18.0",
"language-sass": "0.24.0",
"language-shellscript": "0.9.0",
"language-shellscript": "0.8.0",
"language-source": "0.8.0",
"language-sql": "0.11.0",
"language-text": "0.6.0",
+3
Ver Arquivo
@@ -4,6 +4,9 @@ Release: 0.1%{?dist}
Summary: Atom is a hackable text editor for the 21st century
License: MIT
URL: https://atom.io/
BuildConflicts: gyp
BuildRequires: make, gcc, gcc-c++, glibc-devel, git-core, libgnome-keyring-devel
Requires: libgnome-keyring
AutoReqProv: no # Avoid libchromiumcontent.so missing dependency
%description
@@ -1 +0,0 @@
a { color: red }
+35 -59
Ver Arquivo
@@ -48,10 +48,9 @@ describe "PackageManager", ->
describe "when called multiple times", ->
it "it only calls activate on the package once", ->
spyOn(Package.prototype, 'activateNow').andCallThrough()
waitsForPromise ->
atom.packages.activatePackage('package-with-index')
waitsForPromise ->
atom.packages.activatePackage('package-with-index')
atom.packages.activatePackage('package-with-index')
atom.packages.activatePackage('package-with-index')
waitsForPromise ->
atom.packages.activatePackage('package-with-index')
@@ -183,10 +182,8 @@ describe "PackageManager", ->
pack.mainModule.someNumber = 77
atom.packages.deactivatePackage("package-with-serialization")
spyOn(pack.mainModule, 'activate').andCallThrough()
waitsForPromise ->
atom.packages.activatePackage("package-with-serialization")
runs ->
expect(pack.mainModule.activate).toHaveBeenCalledWith({someNumber: 77})
atom.packages.activatePackage("package-with-serialization")
expect(pack.mainModule.activate).toHaveBeenCalledWith({someNumber: 77})
it "logs warning instead of throwing an exception if the package fails to load", ->
atom.config.set("core.disabledPackages", [])
@@ -205,13 +202,11 @@ describe "PackageManager", ->
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element2[0])).toHaveLength 0
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element3[0])).toHaveLength 0
waitsForPromise ->
atom.packages.activatePackage("package-with-keymaps")
atom.packages.activatePackage("package-with-keymaps")
runs ->
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element1[0])[0].command).toBe "test-1"
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element2[0])[0].command).toBe "test-2"
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element3[0])).toHaveLength 0
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element1[0])[0].command).toBe "test-1"
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element2[0])[0].command).toBe "test-2"
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element3[0])).toHaveLength 0
describe "when the metadata contains a 'keymaps' manifest", ->
it "loads only the keymaps specified by the manifest, in the specified order", ->
@@ -220,13 +215,11 @@ describe "PackageManager", ->
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element1[0])).toHaveLength 0
waitsForPromise ->
atom.packages.activatePackage("package-with-keymaps-manifest")
atom.packages.activatePackage("package-with-keymaps-manifest")
runs ->
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element1[0])[0].command).toBe 'keymap-1'
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-n', target:element1[0])[0].command).toBe 'keymap-2'
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-y', target:element3[0])).toHaveLength 0
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element1[0])[0].command).toBe 'keymap-1'
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-n', target:element1[0])[0].command).toBe 'keymap-2'
expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-y', target:element3[0])).toHaveLength 0
describe "menu loading", ->
beforeEach ->
@@ -239,16 +232,14 @@ describe "PackageManager", ->
expect(atom.contextMenu.templateForElement(element)).toEqual []
waitsForPromise ->
atom.packages.activatePackage("package-with-menus")
atom.packages.activatePackage("package-with-menus")
runs ->
expect(atom.menu.template.length).toBe 2
expect(atom.menu.template[0].label).toBe "Second to Last"
expect(atom.menu.template[1].label).toBe "Last"
expect(atom.contextMenu.templateForElement(element)[0].label).toBe "Menu item 1"
expect(atom.contextMenu.templateForElement(element)[1].label).toBe "Menu item 2"
expect(atom.contextMenu.templateForElement(element)[2].label).toBe "Menu item 3"
expect(atom.menu.template.length).toBe 2
expect(atom.menu.template[0].label).toBe "Second to Last"
expect(atom.menu.template[1].label).toBe "Last"
expect(atom.contextMenu.templateForElement(element)[0].label).toBe "Menu item 1"
expect(atom.contextMenu.templateForElement(element)[1].label).toBe "Menu item 2"
expect(atom.contextMenu.templateForElement(element)[2].label).toBe "Menu item 3"
describe "when the metadata contains a 'menus' manifest", ->
it "loads only the menus specified by the manifest, in the specified order", ->
@@ -256,15 +247,13 @@ describe "PackageManager", ->
expect(atom.contextMenu.templateForElement(element)).toEqual []
waitsForPromise ->
atom.packages.activatePackage("package-with-menus-manifest")
atom.packages.activatePackage("package-with-menus-manifest")
runs ->
expect(atom.menu.template[0].label).toBe "Second to Last"
expect(atom.menu.template[1].label).toBe "Last"
expect(atom.contextMenu.templateForElement(element)[0].label).toBe "Menu item 2"
expect(atom.contextMenu.templateForElement(element)[1].label).toBe "Menu item 1"
expect(atom.contextMenu.templateForElement(element)[2]).toBeUndefined()
expect(atom.menu.template[0].label).toBe "Second to Last"
expect(atom.menu.template[1].label).toBe "Last"
expect(atom.contextMenu.templateForElement(element)[0].label).toBe "Menu item 2"
expect(atom.contextMenu.templateForElement(element)[1].label).toBe "Menu item 1"
expect(atom.contextMenu.templateForElement(element)[2]).toBeUndefined()
describe "stylesheet loading", ->
describe "when the metadata contains a 'stylesheets' manifest", ->
@@ -281,14 +270,12 @@ describe "PackageManager", ->
expect(atom.themes.stylesheetElementForId(two)).toBeNull()
expect(atom.themes.stylesheetElementForId(three)).toBeNull()
waitsForPromise ->
atom.packages.activatePackage("package-with-stylesheets-manifest")
atom.packages.activatePackage("package-with-stylesheets-manifest")
runs ->
expect(atom.themes.stylesheetElementForId(one)).not.toBeNull()
expect(atom.themes.stylesheetElementForId(two)).not.toBeNull()
expect(atom.themes.stylesheetElementForId(three)).toBeNull()
expect($('#jasmine-content').css('font-size')).toBe '1px'
expect(atom.themes.stylesheetElementForId(one)).not.toBeNull()
expect(atom.themes.stylesheetElementForId(two)).not.toBeNull()
expect(atom.themes.stylesheetElementForId(three)).toBeNull()
expect($('#jasmine-content').css('font-size')).toBe '1px'
describe "when the metadata does not contain a 'stylesheets' manifest", ->
it "loads all stylesheets from the stylesheets directory", ->
@@ -305,22 +292,11 @@ describe "PackageManager", ->
expect(atom.themes.stylesheetElementForId(two)).toBeNull()
expect(atom.themes.stylesheetElementForId(three)).toBeNull()
waitsForPromise ->
atom.packages.activatePackage("package-with-stylesheets")
runs ->
expect(atom.themes.stylesheetElementForId(one)).not.toBeNull()
expect(atom.themes.stylesheetElementForId(two)).not.toBeNull()
expect(atom.themes.stylesheetElementForId(three)).not.toBeNull()
expect($('#jasmine-content').css('font-size')).toBe '3px'
it "assigns the stylesheet's context based on the filename", ->
waitsForPromise ->
atom.packages.activatePackage("package-with-stylesheets")
runs ->
element = atom.styles.getStyleElements().find (element) -> element.context is 'test-context'
expect(element).toBeDefined()
expect(atom.themes.stylesheetElementForId(one)).not.toBeNull()
expect(atom.themes.stylesheetElementForId(two)).not.toBeNull()
expect(atom.themes.stylesheetElementForId(three)).not.toBeNull()
expect($('#jasmine-content').css('font-size')).toBe '3px'
describe "grammar loading", ->
it "loads the package's grammars", ->
+1 -1
Ver Arquivo
@@ -92,7 +92,7 @@ describe "Package", ->
it "reloads without readding to the stylesheets list", ->
expect(theme.getStylesheetPaths().length).toBe 3
theme.reloadStylesheets()
theme.reloadStylesheet(theme.getStylesheetPaths()[0])
expect(theme.getStylesheetPaths().length).toBe 3
describe "events", ->
+11 -66
Ver Arquivo
@@ -43,76 +43,21 @@ describe "PanelContainerElement", ->
expect(element.parentNode).not.toBe jasmineContent
describe "adding and removing panels", ->
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
it "adds atom-panel elements when a new panel is added to the container; removes them when the panels are destroyed", ->
expect(element.childNodes.length).toBe 0
panel1 = new Panel({viewRegistry, item: new TestPanelContainerItem()})
container.addPanel(panel1)
expect(element.childNodes.length).toBe 1
expect(element.childNodes[0].getAttribute('location')).toBe 'left'
expect(element.childNodes[0].tagName).toBe 'ATOM-PANEL'
panel2 = new Panel({viewRegistry, item: new TestPanelContainerItem()})
container.addPanel(panel2)
expect(element.childNodes.length).toBe 2
expect(panel1.getView().style.display).not.toBe 'none'
expect(panel2.getView().style.display).not.toBe 'none'
panel1.destroy()
expect(element.childNodes.length).toBe 1
panel2.destroy()
expect(element.childNodes.length).toBe 0
describe "when the container is at the bottom location", ->
beforeEach ->
container = new PanelContainer({viewRegistry, location: 'bottom'})
element = container.getView()
jasmineContent.appendChild(element)
it "adds atom-panel elements when a new panel is added to the container; removes them when the panels are destroyed", ->
expect(element.childNodes.length).toBe 0
panel1 = new Panel({viewRegistry, item: new TestPanelContainerItem(), className: 'one'})
container.addPanel(panel1)
expect(element.childNodes.length).toBe 1
expect(element.childNodes[0].getAttribute('location')).toBe 'bottom'
expect(element.childNodes[0].tagName).toBe 'ATOM-PANEL'
expect(panel1.getView()).toHaveClass 'one'
panel2 = new Panel({viewRegistry, item: new TestPanelContainerItem(), className: 'two'})
container.addPanel(panel2)
expect(element.childNodes.length).toBe 2
expect(panel2.getView()).toHaveClass 'two'
panel1.destroy()
expect(element.childNodes.length).toBe 1
panel2.destroy()
expect(element.childNodes.length).toBe 0
describe "when the container is modal", ->
beforeEach ->
container = new PanelContainer({viewRegistry, location: 'modal'})
element = container.getView()
jasmineContent.appendChild(element)
it "allows only one panel to be visible at a time", ->
panel1 = new Panel({viewRegistry, item: new TestPanelContainerItem()})
panel1 = new Panel({viewRegistry, item: new TestPanelContainerItem(), location: 'left'})
container.addPanel(panel1)
expect(element.childNodes.length).toBe 1
expect(panel1.getView().style.display).not.toBe 'none'
expect(element.childNodes[0].tagName).toBe 'ATOM-PANEL'
panel2 = new Panel({viewRegistry, item: new TestPanelContainerItem()})
panel2 = new Panel({viewRegistry, item: new TestPanelContainerItem(), location: 'left'})
container.addPanel(panel2)
expect(element.childNodes.length).toBe 2
expect(panel1.getView().style.display).toBe 'none'
expect(panel2.getView().style.display).not.toBe 'none'
panel1.destroy()
expect(element.childNodes.length).toBe 1
panel1.show()
expect(panel1.getView().style.display).not.toBe 'none'
expect(panel2.getView().style.display).toBe 'none'
panel2.destroy()
expect(element.childNodes.length).toBe 0
-9
Ver Arquivo
@@ -54,12 +54,3 @@ describe "PanelElement", ->
panel.show()
expect(element.style.display).not.toBe 'none'
describe "when a class name is specified", ->
it 'initially renders panel created with visibile: false', ->
panel = new Panel({viewRegistry, className: 'some classes', item: new TestPanelItem})
element = panel.getView()
jasmineContent.appendChild(element)
expect(element).toHaveClass 'some'
expect(element).toHaveClass 'classes'
-212
Ver Arquivo
@@ -1,212 +0,0 @@
SelectListView = require '../src/select-list-view'
{$, $$} = require 'atom'
describe "SelectListView", ->
[selectList, items, list, filterEditorView] = []
beforeEach ->
items = [
["A", "Alpha"], ["B", "Bravo"], ["C", "Charlie"],
["D", "Delta"], ["E", "Echo"], ["F", "Foxtrot"]
]
selectList = new SelectListView
selectList.setMaxItems(4)
selectList.getFilterKey = -> 1
selectList.viewForItem = (item) ->
$$ -> @li item[1], class: item[0]
selectList.confirmed = jasmine.createSpy('confirmed hook')
selectList.cancelled = jasmine.createSpy('cancelled hook')
selectList.setItems(items)
{list, filterEditorView} = selectList
describe "when an array is assigned", ->
it "populates the list with up to maxItems items, based on the liForElement function", ->
expect(list.find('li').length).toBe selectList.maxItems
expect(list.find('li:eq(0)')).toHaveText 'Alpha'
expect(list.find('li:eq(0)')).toHaveClass 'A'
describe "viewForItem(item)", ->
it "allows raw DOM elements to be returned", ->
selectList.viewForItem = (item) ->
li = document.createElement('li')
li.classList.add(item[0])
li.innerText = item[1]
li
selectList.setItems(items)
expect(list.find('li').length).toBe selectList.maxItems
expect(list.find('li:eq(0)')).toHaveText 'Alpha'
expect(list.find('li:eq(0)')).toHaveClass 'A'
expect(selectList.getSelectedItem()).toBe items[0]
it "allows raw HTML to be returned", ->
selectList.viewForItem = (item) ->
"<li>#{item}</li>"
selectList.setItems(['Bermuda', 'Bahama'])
expect(list.find('li:eq(0)')).toHaveText 'Bermuda'
expect(selectList.getSelectedItem()).toBe 'Bermuda'
describe "when the text of the mini editor changes", ->
beforeEach ->
selectList.attachToDom()
it "filters the elements in the list based on the scoreElement function and selects the first item", ->
filterEditorView.getEditor().insertText('la')
window.advanceClock(selectList.inputThrottle)
expect(list.find('li').length).toBe 2
expect(list.find('li:contains(Alpha)')).toExist()
expect(list.find('li:contains(Delta)')).toExist()
expect(list.find('li:first')).toHaveClass 'selected'
expect(selectList.error).not.toBeVisible()
it "displays an error if there are no matches, removes error when there are matches", ->
filterEditorView.getEditor().insertText('nothing will match this')
window.advanceClock(selectList.inputThrottle)
expect(list.find('li').length).toBe 0
expect(selectList.error).not.toBeHidden()
filterEditorView.getEditor().setText('la')
window.advanceClock(selectList.inputThrottle)
expect(list.find('li').length).toBe 2
expect(selectList.error).not.toBeVisible()
it "displays no elements until the array has been set on the list", ->
selectList.items = null
selectList.list.empty()
filterEditorView.getEditor().insertText('la')
window.advanceClock(selectList.inputThrottle)
expect(list.find('li').length).toBe 0
expect(selectList.error).toBeHidden()
selectList.setItems(items)
expect(list.find('li').length).toBe 2
describe "when core:move-up / core:move-down are triggered on the filterEditorView", ->
it "selects the previous / next item in the list, or wraps around to the other side", ->
expect(list.find('li:first')).toHaveClass 'selected'
filterEditorView.trigger 'core:move-up'
expect(list.find('li:first')).not.toHaveClass 'selected'
expect(list.find('li:last')).toHaveClass 'selected'
filterEditorView.trigger 'core:move-down'
expect(list.find('li:first')).toHaveClass 'selected'
expect(list.find('li:last')).not.toHaveClass 'selected'
filterEditorView.trigger 'core:move-down'
expect(list.find('li:eq(0)')).not.toHaveClass 'selected'
expect(list.find('li:eq(1)')).toHaveClass 'selected'
filterEditorView.trigger 'core:move-down'
expect(list.find('li:eq(1)')).not.toHaveClass 'selected'
expect(list.find('li:eq(2)')).toHaveClass 'selected'
filterEditorView.trigger 'core:move-up'
expect(list.find('li:eq(2)')).not.toHaveClass 'selected'
expect(list.find('li:eq(1)')).toHaveClass 'selected'
it "scrolls to keep the selected item in view", ->
selectList.attachToDom()
itemHeight = list.find('li').outerHeight()
list.height(itemHeight * 2)
filterEditorView.trigger 'core:move-down'
filterEditorView.trigger 'core:move-down'
expect(list.scrollBottom()).toBe itemHeight * 3
filterEditorView.trigger 'core:move-down'
expect(list.scrollBottom()).toBe itemHeight * 4
filterEditorView.trigger 'core:move-up'
filterEditorView.trigger 'core:move-up'
expect(list.scrollTop()).toBe itemHeight
describe "the core:confirm event", ->
describe "when there is an item selected (because the list in not empty)", ->
it "triggers the selected hook with the selected array element", ->
filterEditorView.trigger 'core:move-down'
filterEditorView.trigger 'core:move-down'
filterEditorView.trigger 'core:confirm'
expect(selectList.confirmed).toHaveBeenCalledWith(items[2])
describe "when there is no item selected (because the list is empty)", ->
beforeEach ->
selectList.attachToDom()
it "does not trigger the confirmed hook", ->
filterEditorView.getEditor().insertText("i will never match anything")
window.advanceClock(selectList.inputThrottle)
expect(list.find('li')).not.toExist()
filterEditorView.trigger 'core:confirm'
expect(selectList.confirmed).not.toHaveBeenCalled()
it "does trigger the cancelled hook", ->
filterEditorView.getEditor().insertText("i will never match anything")
window.advanceClock(selectList.inputThrottle)
expect(list.find('li')).not.toExist()
filterEditorView.trigger 'core:confirm'
expect(selectList.cancelled).toHaveBeenCalled()
describe "when a list item is clicked", ->
it "selects the item on mousedown and confirms it on mouseup", ->
item = list.find('li:eq(1)')
item.mousedown()
expect(item).toHaveClass 'selected'
item.mouseup()
expect(selectList.confirmed).toHaveBeenCalledWith(items[1])
describe "the core:cancel event", ->
it "triggers the cancelled hook and detaches and empties the select list", ->
spyOn(selectList, 'detach')
filterEditorView.trigger 'core:cancel'
expect(selectList.cancelled).toHaveBeenCalled()
expect(selectList.detach).toHaveBeenCalled()
expect(selectList.list).toBeEmpty()
describe "when the mini editor loses focus", ->
it "triggers the cancelled hook and detaches the select list", ->
spyOn(selectList, 'detach')
filterEditorView.trigger 'blur'
expect(selectList.cancelled).toHaveBeenCalled()
expect(selectList.detach).toHaveBeenCalled()
describe "the core:move-to-top event", ->
it "scrolls to the top, selects the first element, and does not bubble the event", ->
selectList.attachToDom()
moveToTopHandler = jasmine.createSpy("moveToTopHandler")
selectList.parent().on 'core:move-to-top', moveToTopHandler
selectList.trigger 'core:move-down'
expect(list.find('li:eq(1)')).toHaveClass 'selected'
selectList.trigger 'core:move-to-top'
expect(list.find('li:first')).toHaveClass 'selected'
expect(moveToTopHandler).not.toHaveBeenCalled()
describe "the core:move-to-bottom event", ->
it "scrolls to the bottom, selects the last element, and does not bubble the event", ->
selectList.attachToDom()
moveToBottomHandler = jasmine.createSpy("moveToBottomHandler")
selectList.parent().on 'core:move-to-bottom', moveToBottomHandler
expect(list.find('li:first')).toHaveClass 'selected'
selectList.trigger 'core:move-to-bottom'
expect(list.find('li:last')).toHaveClass 'selected'
expect(moveToBottomHandler).not.toHaveBeenCalled()
+7 -6
Ver Arquivo
@@ -14,7 +14,6 @@ Config = require '../src/config'
{Point} = require 'text-buffer'
Project = require '../src/project'
TextEditor = require '../src/text-editor'
TextEditorView = require '../src/text-editor-view'
TokenizedBuffer = require '../src/tokenized-buffer'
TextEditorComponent = require '../src/text-editor-component'
pathwatcher = require 'pathwatcher'
@@ -106,12 +105,10 @@ beforeEach ->
config.set "editor.autoIndent", false
config.set "core.disabledPackages", ["package-that-throws-an-exception",
"package-with-broken-package-json", "package-with-broken-keymap"]
config.set "editor.useShadowDOM", true
config.load.reset()
config.save.reset()
# make editor display updates synchronous
spyOn(TextEditorView.prototype, 'requestDisplayUpdate').andCallFake -> @updateDisplay()
TextEditorComponent.performSyncUpdates = true
spyOn(atom, "setRepresentedFilename")
@@ -220,7 +217,7 @@ addCustomMatchers = (spec) ->
@message = -> return "Expected element '" + @actual + "' or its descendants" + notText + " to have focus."
element = @actual
element = element.get(0) if element.jquery
element is document.activeElement or element.contains(document.activeElement)
element.webkitMatchesSelector(":focus") or element.querySelector(":focus")
toShow: ->
notText = if @isNot then " not" else ""
@@ -339,8 +336,12 @@ window.setEditorWidthInChars = (editorView, widthInChars, charWidth=editorView.c
$(window).trigger 'resize' # update width of editor view's on-screen lines
window.setEditorHeightInLines = (editorView, heightInLines, lineHeight=editorView.lineHeight) ->
editorView.height(editorView.getEditor().getLineHeightInPixels() * heightInLines)
editorView.component?.measureHeightAndWidth()
if editorView.hasClass('react')
editorView.height(editorView.getEditor().getLineHeightInPixels() * heightInLines)
editorView.component?.measureHeightAndWidth()
else
editorView.height(lineHeight * heightInLines + editorView.renderedLines.position().top)
$(window).trigger 'resize' # update editor view's on-screen lines
$.fn.resultOfTrigger = (type) ->
event = $.Event(type)
-21
Ver Arquivo
@@ -52,24 +52,3 @@ describe "StylesElement", ->
expect(element.children.length).toBe initialChildCount + 1
expect(element.children[initialChildCount].textContent).toBe "a {color: blue;}"
expect(updatedStyleElements).toEqual [element.children[initialChildCount]]
it "only includes style elements matching the 'context' attribute", ->
initialChildCount = element.children.length
atom.styles.addStyleSheet("a {color: red;}", context: 'test-context')
atom.styles.addStyleSheet("a {color: green;}")
expect(element.children.length).toBe initialChildCount + 1
expect(element.children[initialChildCount].textContent).toBe "a {color: green;}"
element.setAttribute('context', 'test-context')
expect(element.children.length).toBe 1
expect(element.children[0].textContent).toBe "a {color: red;}"
atom.styles.addStyleSheet("a {color: blue;}", context: 'test-context')
atom.styles.addStyleSheet("a {color: yellow;}")
expect(element.children.length).toBe 2
expect(element.children[0].textContent).toBe "a {color: red;}"
expect(element.children[1].textContent).toBe "a {color: blue;}"
+7 -9
Ver Arquivo
@@ -1,7 +1,7 @@
_ = require 'underscore-plus'
{extend, flatten, toArray, last} = _
TextEditorView = require '../src/text-editor-view'
{TextEditorView} = require 'atom'
TextEditorComponent = require '../src/text-editor-component'
nbsp = String.fromCharCode(160)
@@ -721,11 +721,11 @@ describe "TextEditorComponent", ->
editor.setCursorScreenPosition([0, 16])
nextAnimationFrame()
atom.styles.addStyleSheet """
atom.themes.applyStylesheet 'test', """
.function.js {
font-weight: bold;
}
""", context: 'atom-text-editor'
"""
nextAnimationFrame() # update based on new measurements
cursor = componentNode.querySelector('.cursor')
@@ -1537,9 +1537,8 @@ describe "TextEditorComponent", ->
it "transfers focus to the hidden input", ->
expect(document.activeElement).toBe document.body
wrapperNode.focus()
expect(document.activeElement).toBe wrapperNode
expect(wrapperNode.shadowRoot.activeElement).toBe inputNode
componentNode.focus()
expect(document.activeElement).toBe inputNode
it "adds the 'is-focused' class to the editor when the hidden input is focused", ->
expect(document.activeElement).toBe document.body
@@ -1668,13 +1667,12 @@ describe "TextEditorComponent", ->
component.measureHeightAndWidth()
nextAnimationFrame()
atom.styles.addStyleSheet """
atom.themes.applyStylesheet "test", """
::-webkit-scrollbar {
width: 8px;
height: 8px;
}
""", context: 'atom-text-editor'
"""
nextAnimationFrame()
scrollbarCornerNode = componentNode.querySelector('.scrollbar-corner')
+13 -38
Ver Arquivo
@@ -19,43 +19,18 @@ describe "TextEditorElement", ->
element = jasmineContent.firstChild
expect(element.getModel().getPlaceholderText()).toBe 'testing'
describe "focus and blur handling", ->
describe "when the editor.useShadowDOM config option is true", ->
it "proxies focus/blur events to/from the hidden input inside the shadow root", ->
atom.config.set('editor.useShadowDOM', true)
describe "::focus()", ->
it "transfers focus to the hidden text area and does not emit 'focusout' or 'blur' events", ->
element = new TextEditorElement
jasmineContent.appendChild(element)
element = new TextEditorElement
jasmineContent.appendChild(element)
focusoutCalled = false
element.addEventListener 'focusout', -> focusoutCalled = true
blurCalled = false
element.addEventListener 'blur', -> blurCalled = true
blurCalled = false
element.addEventListener 'blur', -> blurCalled = true
element.focus()
expect(blurCalled).toBe false
expect(element.hasFocus()).toBe true
expect(document.activeElement).toBe element
expect(element.shadowRoot.activeElement).toBe element.shadowRoot.querySelector('input')
document.body.focus()
expect(blurCalled).toBe true
describe "when the editor.useShadowDOM config option is false", ->
afterEach ->
document.head.querySelector('atom-styles[context="atom-text-editor"]').remove()
it "proxies focus/blur events to/from the hidden input", ->
atom.config.set('editor.useShadowDOM', false)
element = new TextEditorElement
jasmineContent.appendChild(element)
blurCalled = false
element.addEventListener 'blur', -> blurCalled = true
element.focus()
expect(blurCalled).toBe false
expect(element.hasFocus()).toBe true
expect(document.activeElement).toBe element.querySelector('input')
document.body.focus()
expect(blurCalled).toBe true
element.focus()
expect(focusoutCalled).toBe false
expect(blurCalled).toBe false
expect(element.hasFocus()).toBe true
expect(element.querySelector('input')).toBe document.activeElement
-15
Ver Arquivo
@@ -1805,16 +1805,6 @@ describe "TextEditor", ->
expect(willInsertSpy).toHaveBeenCalled()
expect(didInsertSpy).not.toHaveBeenCalled()
describe "when the undo option is set to 'skip'", ->
beforeEach ->
editor.setSelectedBufferRange([[1, 2], [1, 2]])
it "does not undo the skipped operation", ->
range = editor.insertText('x')
range = editor.insertText('y', undo: 'skip')
editor.undo()
expect(buffer.lineForRow(1)).toBe ' yvar sort = function(items) {'
describe ".insertNewline()", ->
describe "when there is a single cursor", ->
describe "when the cursor is at the beginning of a line", ->
@@ -3110,11 +3100,6 @@ describe "TextEditor", ->
expect(editor.getTabLength()).toBe 6
expect(editor.tokenizedLineForScreenRow(5).tokens[0].firstNonWhitespaceIndex).toBe 6
changeHandler = jasmine.createSpy('changeHandler')
editor.onDidChange(changeHandler)
editor.setTabLength(6)
expect(changeHandler).not.toHaveBeenCalled()
it 'retokenizes when the editor.tabLength setting is updated', ->
expect(editor.getTabLength()).toBe 2
expect(editor.tokenizedLineForScreenRow(5).tokens[0].firstNonWhitespaceIndex).toBe 2
+13 -13
Ver Arquivo
@@ -85,16 +85,7 @@ describe "ThemeManager", ->
runs ->
reloadHandler.reset()
expect($('style.theme')).toHaveLength 0
atom.config.set('core.themes', ['atom-dark-ui'])
waitsFor ->
reloadHandler.callCount == 1
runs ->
reloadHandler.reset()
expect($('style[group=theme]')).toHaveLength 1
expect($('style[group=theme]:eq(0)').attr('source-path')).toMatch /atom-dark-ui/
atom.config.set('core.themes', ['atom-light-ui', 'atom-dark-ui'])
atom.config.set('core.themes', ['atom-dark-syntax'])
waitsFor ->
reloadHandler.callCount == 1
@@ -102,8 +93,17 @@ describe "ThemeManager", ->
runs ->
reloadHandler.reset()
expect($('style[group=theme]')).toHaveLength 2
expect($('style[group=theme]:eq(0)').attr('source-path')).toMatch /atom-dark-ui/
expect($('style[group=theme]:eq(1)').attr('source-path')).toMatch /atom-light-ui/
expect($('style[group=theme]:eq(1)').attr('source-path')).toMatch /atom-dark-syntax/
atom.config.set('core.themes', ['atom-light-syntax', 'atom-dark-syntax'])
waitsFor ->
reloadHandler.callCount == 1
runs ->
reloadHandler.reset()
expect($('style[group=theme]')).toHaveLength 2
expect($('style[group=theme]:eq(0)').attr('source-path')).toMatch /atom-dark-syntax/
expect($('style[group=theme]:eq(1)').attr('source-path')).toMatch /atom-light-syntax/
atom.config.set('core.themes', [])
waitsFor ->
@@ -111,7 +111,7 @@ describe "ThemeManager", ->
runs ->
reloadHandler.reset()
expect($('style[group=theme]')).toHaveLength 1
expect($('style[group=theme]')).toHaveLength 2
# atom-dark-ui has an directory path, the syntax one doesn't
atom.config.set('core.themes', ['theme-with-index-less', 'atom-dark-ui'])
-9
Ver Arquivo
@@ -492,12 +492,3 @@ describe "Workspace", ->
expect(panel).toBeDefined()
expect(addPanelSpy).toHaveBeenCalledWith({panel, index: 0})
describe '::addModalPanel(model)', ->
it 'adds a panel to the correct panel container', ->
atom.workspace.panelContainers.modal.onDidAddPanel addPanelSpy = jasmine.createSpy()
panel = atom.workspace.addModalPanel(item: new TestPanel())
expect(panel).toBeDefined()
expect(addPanelSpy).toHaveBeenCalledWith({panel, index: 0})
expect(panel.getClassName()).toBe 'overlay from-top' # the default
+1 -5
Ver Arquivo
@@ -1,8 +1,7 @@
{$, $$, WorkspaceView, View} = require 'atom'
{$, $$, WorkspaceView, View, TextEditorView} = require 'atom'
Q = require 'q'
path = require 'path'
temp = require 'temp'
TextEditorView = require '../src/text-editor-view'
PaneView = require '../src/pane-view'
Workspace = require '../src/workspace'
@@ -286,6 +285,3 @@ describe "WorkspaceView", ->
bottomContainer = workspaceElement.querySelector('atom-panel-container[location="bottom"]')
expect(topContainer.nextSibling).toBe workspaceElement.paneContainer
expect(bottomContainer.previousSibling).toBe workspaceElement.paneContainer
modalContainer = workspaceElement.querySelector('atom-panel-container[location="modal"]')
expect(modalContainer.parentNode).toBe workspaceElement
-10
Ver Arquivo
@@ -177,7 +177,6 @@ class Atom extends Model
@executeJavaScriptInDevTools('InspectorFrontendAPI.showConsole()')
@lastUncaughtError = Array::slice.call(arguments)
@emit 'uncaught-error', arguments...
@emitter.emit 'did-throw-error', arguments...
@unsubscribe()
@setBodyPlatformClass()
@@ -248,15 +247,6 @@ class Atom extends Model
onDidBeep: (callback) ->
@emitter.on 'did-beep', callback
# Extended: Invoke the given callback whenever there is an unhandled error.
#
# * `callback` {Function} to be called whenever there is an unhandled error
# * `errorMessage` {String}
#
# Returns a {Disposable} on which `.dispose()` can be called to unsubscribe.
onDidThrowError: (callback) ->
@emitter.on 'did-throw-error', callback
###
Section: Atom Details
###
+1 -1
Ver Arquivo
@@ -70,7 +70,7 @@ class AtomApplication
@autoUpdateManager = new AutoUpdateManager(@version)
@applicationMenu = new ApplicationMenu(@version)
@atomProtocolHandler = new AtomProtocolHandler(@resourcePath, @safeMode)
@atomProtocolHandler = new AtomProtocolHandler(@resourcePath)
@listenForArgumentsFromNewProcess()
@setupJavaScriptArguments()
+12 -29
Ver Arquivo
@@ -5,26 +5,16 @@ protocol = require 'protocol'
# Handles requests with 'atom' protocol.
#
# It's created by {AtomApplication} upon instantiation and is used to create a
# custom resource loader for 'atom://' URLs.
#
# The following directories are searched in order:
# * ~/.atom/assets
# * ~/.atom/dev/packages (unless in safe mode)
# * ~/.atom/packages
# * RESOURCE_PATH/node_modules
#
# It's created by {AtomApplication} upon instantiation, and is used to create a
# custom resource loader by adding the 'atom' custom protocol.
module.exports =
class AtomProtocolHandler
constructor: (resourcePath, safeMode) ->
@loadPaths = []
@dotAtomDirectory = path.join(app.getHomeDir(), '.atom')
unless safeMode
@loadPaths.push(path.join(@dotAtomDirectory, 'dev', 'packages'))
@loadPaths.push(path.join(@dotAtomDirectory, 'packages'))
@loadPaths.push(path.join(resourcePath, 'node_modules'))
constructor: (@resourcePath) ->
@loadPaths = [
path.join(app.getHomeDir(), '.atom', 'dev', 'packages')
path.join(app.getHomeDir(), '.atom', 'packages')
path.join(@resourcePath, 'node_modules')
]
@registerAtomProtocol()
@@ -32,14 +22,7 @@ class AtomProtocolHandler
registerAtomProtocol: ->
protocol.registerProtocol 'atom', (request) =>
relativePath = path.normalize(request.url.substr(7))
if relativePath.indexOf('assets/') is 0
assetsPath = path.join(@dotAtomDirectory, relativePath)
filePath = assetsPath if fs.statSyncNoException(assetsPath).isFile?()
unless filePath
for loadPath in @loadPaths
filePath = path.join(loadPath, relativePath)
break if fs.statSyncNoException(filePath).isFile?()
new protocol.RequestFileJob(filePath)
for loadPath in @loadPaths
filePath = path.join(loadPath, relativePath)
break if fs.statSyncNoException(filePath).isFile?()
return new protocol.RequestFileJob(filePath)
-4
Ver Arquivo
@@ -134,10 +134,6 @@ parseCommandLine = ->
unless fs.statSyncNoException(resourcePath)
resourcePath = path.dirname(path.dirname(__dirname))
# On Yosemite the $PATH is not inherited by the "open" command, so we have to
# explicitly pass it by command line, see http://git.io/YC8_Ew.
process.env.PATH = args['path-environment'] if args['path-environment']
{resourcePath, pathsToOpen, executedFrom, test, version, pidToKillWhenClosed, devMode, safeMode, newWindow, specDirectory, logFile}
start()
-5
Ver Arquivo
@@ -109,11 +109,6 @@ module.exports =
type: 'boolean'
default: true
description: 'Disabling will improve editor font rendering but reduce scrolling performance.'
useShadowDOM:
type: 'boolean'
default: false
title: 'Use Shadow DOM'
description: 'Enable to test out themes and packages with the new shadow DOM before it ships by default.'
confirmCheckoutHeadRevision:
type: 'boolean'
default: true
+2 -6
Ver Arquivo
@@ -16,12 +16,12 @@ GutterComponent = React.createClass
measuredWidth: null
render: ->
{scrollHeight, scrollViewHeight, backgroundColor, gutterBackgroundColor} = @props
{scrollHeight, scrollViewHeight, onMouseDown, backgroundColor, gutterBackgroundColor} = @props
if gutterBackgroundColor isnt 'rbga(0, 0, 0, 0)'
backgroundColor = gutterBackgroundColor
div className: 'gutter',
div className: 'gutter', onClick: @onClick, onMouseDown: @onMouseDown,
div className: 'line-numbers', ref: 'lineNumbers', style:
height: Math.max(scrollHeight, scrollViewHeight)
WebkitTransform: @getTransform()
@@ -45,10 +45,6 @@ GutterComponent = React.createClass
@appendDummyLineNumber()
@updateLineNumbers() if @props.performedInitialMeasurement
node = @getDOMNode()
node.addEventListener 'click', @onClick
node.addEventListener 'mousedown', @onMouseDown
# Only update the gutter if the visible row range has changed or if a
# non-zero-delta change to the screen lines has occurred within the current
# visible row range.
-6
Ver Arquivo
@@ -21,11 +21,5 @@ HighlightsComponent = React.createClass
highlightComponents
componentDidMount: ->
if atom.config.get('editor.useShadowDOM')
insertionPoint = document.createElement('content')
insertionPoint.setAttribute('select', '.underlayer')
@getDOMNode().appendChild(insertionPoint)
shouldComponentUpdate: (newProps) ->
not isEqualForProperties(newProps, @props, 'highlightDecorations', 'lineHeightInPixels', 'defaultCharWidth', 'scopedCharacterWidthsChangeCount')
+10 -5
Ver Arquivo
@@ -7,17 +7,16 @@ InputComponent = React.createClass
displayName: 'InputComponent'
render: ->
{className, style} = @props
{className, style, onFocus, onBlur} = @props
input {className, style, 'data-react-skip-selection-restoration': true}
input {className, style, onFocus, onBlur, 'data-react-skip-selection-restoration': true}
getInitialState: ->
{lastChar: ''}
componentDidMount: ->
node = @getDOMNode()
node.addEventListener 'paste', @onPaste
node.addEventListener 'compositionupdate', @onCompositionUpdate
@getDOMNode().addEventListener 'paste', @onPaste
@getDOMNode().addEventListener 'compositionupdate', @onCompositionUpdate
# Don't let text accumulate in the input forever, but avoid excessive reflows
componentDidUpdate: ->
@@ -35,5 +34,11 @@ InputComponent = React.createClass
onPaste: (e) ->
e.preventDefault()
onFocus: ->
@props.onFocus?()
onBlur: ->
@props.onBlur?()
focus: ->
@getDOMNode().focus()
-6
Ver Arquivo
@@ -57,12 +57,6 @@ LinesComponent = React.createClass
@lineIdsByScreenRow = {}
@renderedDecorationsByLineId = {}
componentDidMount: ->
if atom.config.get('editor.useShadowDOM')
insertionPoint = document.createElement('content')
insertionPoint.setAttribute('select', '.overlayer')
@getDOMNode().appendChild(insertionPoint)
shouldComponentUpdate: (newProps) ->
return true unless isEqualForProperties(newProps, @props,
'renderedRowRange', 'lineDecorations', 'highlightDecorations', 'lineHeightInPixels', 'defaultCharWidth',
+9 -16
Ver Arquivo
@@ -50,7 +50,6 @@ class Package
keymaps: null
menus: null
stylesheets: null
stylesheetDisposables: null
grammars: null
scopedProperties: null
mainModulePath: null
@@ -176,16 +175,9 @@ class Package
activateStylesheets: ->
return if @stylesheetsActivated
group = @getStylesheetType()
@stylesheetDisposables = new CompositeDisposable
for [sourcePath, source] in @stylesheets
if match = path.basename(sourcePath).match(/[^.]*\.([^.]*)\./)
context = match[1]
else if @metadata.theme is 'syntax'
context = 'atom-text-editor'
@stylesheetDisposables.add(atom.styles.addStyleSheet(source, {sourcePath, group, context}))
type = @getStylesheetType()
for [stylesheetPath, content] in @stylesheets
atom.themes.applyStylesheet(stylesheetPath, content, type)
@stylesheetsActivated = true
activateResources: ->
@@ -328,7 +320,7 @@ class Package
deactivateResources: ->
grammar.deactivate() for grammar in @grammars
scopedProperties.deactivate() for scopedProperties in @scopedProperties
@stylesheetDisposables?.dispose()
atom.themes.removeStylesheet(stylesheetPath) for [stylesheetPath] in @stylesheets
@activationDisposables?.dispose()
@stylesheetsActivated = false
@grammarsActivated = false
@@ -337,10 +329,11 @@ class Package
reloadStylesheets: ->
oldSheets = _.clone(@stylesheets)
@loadStylesheets()
@stylesheetDisposables.dispose()
@stylesheetDisposables = new CompositeDisposable
@stylesheetsActivated = false
@activateStylesheets()
atom.themes.removeStylesheet(stylesheetPath) for [stylesheetPath] in oldSheets
@reloadStylesheet(stylesheetPath, content) for [stylesheetPath, content] in @stylesheets
reloadStylesheet: (stylesheetPath, content) ->
atom.themes.applyStylesheet(stylesheetPath, content, @getStylesheetType())
requireMainModule: ->
return @mainModule if @mainModule?
+3 -11
Ver Arquivo
@@ -28,17 +28,9 @@ class PaneElement extends HTMLElement
@itemViews.setAttribute 'class', 'item-views'
subscribeToDOMEvents: ->
handleFocus = (event) =>
@model.focus()
if event.target is this and view = @getActiveView()
view.focus()
event.stopPropagation()
handleBlur = (event) =>
@model.blur() unless @contains(event.relatedTarget)
@addEventListener 'focus', handleFocus, true
@addEventListener 'blur', handleBlur, true
@addEventListener 'focusin', => @model.focus()
@addEventListener 'focusout', => @model.blur()
@addEventListener 'focus', => @getActiveView()?.focus()
createSpacePenShim: ->
@__spacePenView = new PaneView(this)
+3 -15
Ver Arquivo
@@ -14,29 +14,17 @@ class PanelContainerElement extends HTMLElement
@setAttribute('location', @model.getLocation())
panelAdded: ({panel, index}) ->
panelElement = panel.getView()
panelElement.setAttribute('location', @model.getLocation())
if index >= @childNodes.length
@appendChild(panelElement)
@appendChild(panel.getView())
else
referenceItem = @childNodes[index + 1]
@insertBefore(panelElement, referenceItem)
if @model.isModal()
@hideAllPanelsExcept(panel)
@subscriptions.add panel.onDidChangeVisible (visible) =>
@hideAllPanelsExcept(panel) if visible
@insertBefore(panel.getView(), referenceItem)
panelRemoved: ({panel, index}) ->
@removeChild(panel.getView())
@removeChild(@childNodes[index])
destroyed: ->
@subscriptions.dispose()
@parentNode?.removeChild(this)
hideAllPanelsExcept: (excludedPanel) ->
for panel in @model.getPanels()
panel.hide() unless panel is excludedPanel
return
module.exports = PanelContainerElement = document.registerElement 'atom-panel-container', prototype: PanelContainerElement.prototype
+3 -5
Ver Arquivo
@@ -8,7 +8,7 @@ class PanelContainer
@panels = []
destroy: ->
panel.destroy() for panel in @getPanels()
pane.destroy() for pane in @getPanels()
@subscriptions.dispose()
@emitter.emit 'did-destroy', this
@emitter.dispose()
@@ -34,12 +34,10 @@ class PanelContainer
getLocation: -> @location
isModal: -> @location is 'modal'
getPanels: -> @panels
addPanel: (panel) ->
@subscriptions.add panel.onDidDestroy(@panelDestroyed.bind(this))
@subscriptions.add panel.onDidDestroy(@panelDestoryed.bind(this))
index = @getPanelIndex(panel)
if index is @panels.length
@@ -50,7 +48,7 @@ class PanelContainer
@emitter.emit 'did-add-panel', {panel, index}
panel
panelDestroyed: (panel) ->
panelDestoryed: (panel) ->
index = @panels.indexOf(panel)
if index > -1
@panels.splice(index, 1)
-1
Ver Arquivo
@@ -12,7 +12,6 @@ class PanelElement extends HTMLElement
@appendChild(view)
callAttachHooks(view) # for backward compatibility with SpacePen views
@classList.add(@model.getClassName().split(' ')...) if @model.getClassName()?
@subscriptions.add @model.onDidChangeVisible(@visibleChanged.bind(this))
@subscriptions.add @model.onDidDestroy(@destroyed.bind(this))
+1 -4
Ver Arquivo
@@ -14,7 +14,7 @@ class Panel
Section: Construction and Destruction
###
constructor: ({@viewRegistry, @item, @visible, @priority, @className}) ->
constructor: ({@viewRegistry, @item, @visible, @priority}) ->
@emitter = new Emitter
@visible ?= true
@priority ?= 100
@@ -22,7 +22,6 @@ class Panel
# Public: Destroy and remove this panel from the UI.
destroy: ->
@emitter.emit 'did-destroy', this
@emitter.dispose()
###
Section: Event Subscription
@@ -63,8 +62,6 @@ class Panel
# Public: Returns a {Number} indicating this panel's priority.
getPriority: -> @priority
getClassName: -> @className
# Public: Returns a {Boolean} true when the panel is visible.
isVisible: -> @visible
-38
Ver Arquivo
@@ -1,38 +0,0 @@
{View} = require './space-pen-extensions'
# Extended: Represents a view that scrolls.
#
# Handles several core events to update scroll position:
#
# * `core:move-up` Scrolls the view up
# * `core:move-down` Scrolls the view down
# * `core:page-up` Scrolls the view up by the height of the page
# * `core:page-down` Scrolls the view down by the height of the page
# * `core:move-to-top` Scrolls the editor to the top
# * `core:move-to-bottom` Scroll the editor to the bottom
#
# Subclasses must call `super` if overriding the `initialize` method.
#
# ## Examples
#
# ```coffee
# {ScrollView} = require 'atom'
#
# class MyView extends ScrollView
# @content: ->
# @div()
#
# initialize: ->
# super
# @text('super long content that will scroll')
# ```
#
module.exports =
class ScrollView extends View
initialize: ->
@on 'core:move-up', => @scrollUp()
@on 'core:move-down', => @scrollDown()
@on 'core:page-up', => @pageUp()
@on 'core:page-down', => @pageDown()
@on 'core:move-to-top', => @scrollToTop()
@on 'core:move-to-bottom', => @scrollToBottom()
+1 -6
Ver Arquivo
@@ -23,7 +23,7 @@ ScrollbarComponent = React.createClass
style.right = verticalScrollbarWidth if scrollableInOppositeDirection
style.height = horizontalScrollbarHeight
div {className, style},
div {className, style, @onScroll},
switch orientation
when 'vertical'
div className: 'scrollbar-content', style: {height: scrollHeight}
@@ -36,11 +36,6 @@ ScrollbarComponent = React.createClass
unless orientation is 'vertical' or orientation is 'horizontal'
throw new Error("Must specify an orientation property of 'vertical' or 'horizontal'")
@getDOMNode().addEventListener 'scroll', @onScroll
componentWillUnmount: ->
@getDOMNode().removeEventListener 'scroll', @onScroll
shouldComponentUpdate: (newProps) ->
return true if newProps.visible isnt @props.visible
-312
Ver Arquivo
@@ -1,312 +0,0 @@
{$, View} = require './space-pen-extensions'
TextEditorView = require './text-editor-view'
fuzzyFilter = require('fuzzaldrin').filter
# Essential: 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.
#
# Subclasses must implement the following methods:
#
# * {::viewForItem}
# * {::confirmed}
#
# ## Requiring in packages
#
# ```coffee
# {SelectListView} = require 'atom'
#
# class MySelectListView extends SelectListView
# initialize: ->
# super
# @addClass('overlay from-top')
# @setItems(['Hello', 'World'])
# atom.workspaceView.append(this)
# @focusFilterEditor()
#
# viewForItem: (item) ->
# "<li>#{item}</li>"
#
# confirmed: (item) ->
# console.log("#{item} was selected")
# ```
module.exports =
class SelectListView extends View
@content: ->
@div class: 'select-list', =>
@subview 'filterEditorView', new TextEditorView(mini: true)
@div class: 'error-message', outlet: 'error'
@div class: 'loading', outlet: 'loadingArea', =>
@span class: 'loading-message', outlet: 'loading'
@span class: 'badge', outlet: 'loadingBadge'
@ol class: 'list-group', outlet: 'list'
maxItems: Infinity
scheduleTimeout: null
inputThrottle: 50
cancelling: false
###
Section: Construction
###
# Essential: Initialize the select list view.
#
# This method can be overridden by subclasses but `super` should always
# be called.
initialize: ->
@filterEditorView.getEditor().getBuffer().onDidChange =>
@schedulePopulateList()
@filterEditorView.on 'blur', =>
@cancel() unless @cancelling
# This prevents the focusout event from firing on the filter editor view
# when the list is scrolled by clicking the scrollbar and dragging.
@list.on 'mousedown', ({target}) =>
false if target is @list[0]
@on 'core:move-up', =>
@selectPreviousItemView()
@on 'core:move-down', =>
@selectNextItemView()
@on 'core:move-to-top', =>
@selectItemView(@list.find('li:first'))
@list.scrollToTop()
false
@on 'core:move-to-bottom', =>
@selectItemView(@list.find('li:last'))
@list.scrollToBottom()
false
@on 'core:confirm', => @confirmSelection()
@on 'core:cancel', => @cancel()
@list.on 'mousedown', 'li', (e) =>
@selectItemView($(e.target).closest('li'))
e.preventDefault()
@list.on 'mouseup', 'li', (e) =>
@confirmSelection() if $(e.target).closest('li').hasClass('selected')
e.preventDefault()
###
Section: Methods that must be overridden
###
# Essential: Create a view for the given model item.
#
# This method must be overridden by subclasses.
#
# This is called when the item is about to appended to the list view.
#
# * `item` The model item being rendered. This will always be one of the items
# previously passed to {::setItems}.
#
# Returns a String of HTML, DOM element, jQuery object, or View.
viewForItem: (item) ->
throw new Error("Subclass must implement a viewForItem(item) method")
# Essential: Callback function for when an item is selected.
#
# This method must be overridden by subclasses.
#
# * `item` The selected model item. This will always be one of the items
# previously passed to {::setItems}.
#
# Returns a DOM element, jQuery object, or {View}.
confirmed: (item) ->
throw new Error("Subclass must implement a confirmed(item) method")
###
Section: Managing the list of items
###
# Essential: Set the array of items to display in the list.
#
# This should be model items not actual views. {::viewForItem} will be
# called to render the item when it is being appended to the list view.
#
# * `items` The {Array} of model items to display in the list (default: []).
setItems: (@items=[]) ->
@populateList()
@setLoading()
# Essential: Get the model item that is currently selected in the list view.
#
# Returns a model item.
getSelectedItem: ->
@getSelectedItemView().data('select-list-item')
# Extended: Get the property name to use when filtering items.
#
# This method may be overridden by classes to allow fuzzy filtering based
# on a specific property of the item objects.
#
# For example if the objects you pass to {::setItems} are of the type
# `{"id": 3, "name": "Atom"}` then you would return `"name"` from this method
# to fuzzy filter by that property when text is entered into this view's
# editor.
#
# Returns the property name to fuzzy filter by.
getFilterKey: ->
# Extended: Get the filter query to use when fuzzy filtering the visible
# elements.
#
# By default this method returns the text in the mini editor but it can be
# overridden by subclasses if needed.
#
# Returns a {String} to use when fuzzy filtering the elements to display.
getFilterQuery: ->
@filterEditorView.getEditor().getText()
# Extended: Set the maximum numbers of items to display in the list.
#
# * `maxItems` The maximum {Number} of items to display.
setMaxItems: (@maxItems) ->
# Extended: Populate the list view with the model items previously set by
# calling {::setItems}.
#
# Subclasses may override this method but should always call `super`.
populateList: ->
return unless @items?
filterQuery = @getFilterQuery()
if filterQuery.length
filteredItems = fuzzyFilter(@items, filterQuery, key: @getFilterKey())
else
filteredItems = @items
@list.empty()
if filteredItems.length
@setError(null)
for i in [0...Math.min(filteredItems.length, @maxItems)]
item = filteredItems[i]
itemView = $(@viewForItem(item))
itemView.data('select-list-item', item)
@list.append(itemView)
@selectItemView(@list.find('li:first'))
else
@setError(@getEmptyMessage(@items.length, filteredItems.length))
###
Section: Messages to the user
###
# Essential: Set the error message to display.
#
# * `message` The {String} error message (default: '').
setError: (message='') ->
if message.length is 0
@error.text('').hide()
else
@setLoading()
@error.text(message).show()
# Essential: Set the loading message to display.
#
# * `message` The {String} loading message (default: '').
setLoading: (message='') ->
if message.length is 0
@loading.text("")
@loadingBadge.text("")
@loadingArea.hide()
else
@setError()
@loading.text(message)
@loadingArea.show()
# Extended: Get the message to display when there are no items.
#
# Subclasses may override this method to customize the message.
#
# * `itemCount` The {Number} of items in the array specified to {::setItems}
# * `filteredItemCount` The {Number} of items that pass the fuzzy filter test.
#
# Returns a {String} message (default: 'No matches found').
getEmptyMessage: (itemCount, filteredItemCount) -> 'No matches found'
###
Section: View Actions
###
# Essential: Cancel and close this select list view.
#
# This restores focus to the previously focused element if
# {::storeFocusedElement} was called prior to this view being attached.
cancel: ->
@list.empty()
@cancelling = true
filterEditorViewFocused = @filterEditorView.isFocused
@cancelled()
@detach()
@restoreFocus() if filterEditorViewFocused
@cancelling = false
clearTimeout(@scheduleTimeout)
# Extended: Focus the fuzzy filter editor view.
focusFilterEditor: ->
@filterEditorView.focus()
# Extended: Store the currently focused element. This element will be given
# back focus when {::cancel} is called.
storeFocusedElement: ->
@previouslyFocusedElement = $(document.activeElement)
###
Section: Private
###
selectPreviousItemView: ->
view = @getSelectedItemView().prev()
view = @list.find('li:last') unless view.length
@selectItemView(view)
selectNextItemView: ->
view = @getSelectedItemView().next()
view = @list.find('li:first') unless view.length
@selectItemView(view)
selectItemView: (view) ->
return unless view.length
@list.find('.selected').removeClass('selected')
view.addClass('selected')
@scrollToItemView(view)
scrollToItemView: (view) ->
scrollTop = @list.scrollTop()
desiredTop = view.position().top + scrollTop
desiredBottom = desiredTop + view.outerHeight()
if desiredTop < scrollTop
@list.scrollTop(desiredTop)
else if desiredBottom > @list.scrollBottom()
@list.scrollBottom(desiredBottom)
restoreFocus: ->
if @previouslyFocusedElement?.isOnDom()
@previouslyFocusedElement.focus()
else
atom.workspaceView.focus()
cancelled: ->
@filterEditorView.getEditor().setText('')
getSelectedItemView: ->
@list.find('li.selected')
confirmSelection: ->
item = @getSelectedItem()
if item?
@confirmed(item)
else
@cancel()
schedulePopulateList: ->
clearTimeout(@scheduleTimeout)
populateCallback = =>
@populateList() if @isOnDom()
@scheduleTimeout = setTimeout(populateCallback, @inputThrottle)
+1 -2
Ver Arquivo
@@ -348,7 +348,6 @@ class Selection extends Model
# * `autoIndentNewline` if `true`, indent newline appropriately.
# * `autoDecreaseIndent` if `true`, decreases indent level appropriately
# (for example, when a closing bracket is inserted).
# * `normalizeLineEndings` (optional) {Boolean} (default: true)
# * `undo` if `skip`, skips the undo stack for this operation.
insertText: (text, options={}) ->
oldBufferRange = @getBufferRange()
@@ -360,7 +359,7 @@ class Selection extends Model
if options.indentBasis? and not options.autoIndent
text = @normalizeIndents(text, options.indentBasis)
newBufferRange = @editor.buffer.setTextInRange(oldBufferRange, text, pick(options, 'undo', 'normalizeLineEndings'))
newBufferRange = @editor.buffer.setTextInRange(oldBufferRange, text, pick(options, 'undo'))
if options.select
@setBufferRange(newBufferRange, reversed: wasReversed)
-15
Ver Arquivo
@@ -27,9 +27,6 @@ jQuery.fn.trigger = (eventName, data) ->
if NativeEventNames.has(eventName) or typeof eventName is 'object'
JQueryTrigger.call(this, eventName, data)
else
data ?= {}
data.jQueryTrigger = true
for element in this
atom.commands.dispatch(element, eventName, data)
this
@@ -81,18 +78,6 @@ jQuery.event.remove = (elem, types, originalHandler, selector, mappedTypes) ->
handler = HandlersByOriginalHandler.get(originalHandler) ? originalHandler
JQueryEventRemove(elem, types, handler, selector, mappedTypes, RemoveEventListener if atom?.commands?)
JQueryContains = jQuery.contains
jQuery.contains = (a, b) ->
shadowRoot = null
currentNode = b
while currentNode
if currentNode instanceof ShadowRoot and a.contains(currentNode.host)
return true
currentNode = currentNode.parentNode
JQueryContains.call(this, a, b)
tooltipDefaults =
delay:
show: 1000
-1
Ver Arquivo
@@ -25,7 +25,6 @@ class StyleManager
addStyleSheet: (source, params) ->
sourcePath = params?.sourcePath
context = params?.context
group = params?.group
if sourcePath? and styleElement = @styleElementsBySourcePath[sourcePath]
+7 -35
Ver Arquivo
@@ -1,8 +1,8 @@
{Emitter, CompositeDisposable} = require 'event-kit'
class StylesElement extends HTMLElement
subscriptions: null
context: null
createdCallback: ->
@emitter = new Emitter
onDidAddStyleElement: (callback) ->
@emitter.on 'did-add-style-element', callback
@@ -13,42 +13,15 @@ class StylesElement extends HTMLElement
onDidUpdateStyleElement: (callback) ->
@emitter.on 'did-update-style-element', callback
createdCallback: ->
@emitter = new Emitter
@styleElementClonesByOriginalElement = new WeakMap
attachedCallback: ->
@initialize()
detachedCallback: ->
@subscriptions.dispose()
@subscriptions = null
attributeChangedCallback: (attrName, oldVal, newVal) ->
@contextChanged() if attrName is 'context'
initialize: ->
return if @subscriptions?
@subscriptions = new CompositeDisposable
@context = @getAttribute('context') ? undefined
@styleElementClonesByOriginalElement = new WeakMap
@subscriptions.add atom.styles.observeStyleElements(@styleElementAdded.bind(this))
@subscriptions.add atom.styles.onDidRemoveStyleElement(@styleElementRemoved.bind(this))
@subscriptions.add atom.styles.onDidUpdateStyleElement(@styleElementUpdated.bind(this))
contextChanged: ->
return unless @subscriptions?
@styleElementRemoved(child) for child in Array::slice.call(@children)
@context = @getAttribute('context')
@styleElementAdded(styleElement) for styleElement in atom.styles.getStyleElements()
styleElementAdded: (styleElement) ->
return unless styleElement.context is @context
styleElementClone = styleElement.cloneNode(true)
styleElementClone.context = styleElement.context
@styleElementClonesByOriginalElement.set(styleElement, styleElementClone)
group = styleElement.getAttribute('group')
@@ -62,17 +35,16 @@ class StylesElement extends HTMLElement
@emitter.emit 'did-add-style-element', styleElementClone
styleElementRemoved: (styleElement) ->
return unless styleElement.context is @context
styleElementClone = @styleElementClonesByOriginalElement.get(styleElement) ? styleElement
styleElementClone = @styleElementClonesByOriginalElement.get(styleElement)
styleElementClone.remove()
@emitter.emit 'did-remove-style-element', styleElementClone
styleElementUpdated: (styleElement) ->
return unless styleElement.context is @context
styleElementClone = @styleElementClonesByOriginalElement.get(styleElement)
styleElementClone.textContent = styleElement.textContent
@emitter.emit 'did-update-style-element', styleElementClone
detachedCallback: ->
@subscriptions.dispose()
module.exports = StylesElement = document.registerElement 'atom-styles', prototype: StylesElement.prototype
+34 -37
Ver Arquivo
@@ -93,7 +93,7 @@ TextEditorComponent = React.createClass
className += ' is-focused' if focused
className += ' has-selection' if hasSelection
div {className, style},
div {className, style, tabIndex: -1},
if @shouldRenderGutter()
GutterComponent {
ref: 'gutter', onMouseDown: @onGutterMouseDown, lineDecorations,
@@ -102,11 +102,13 @@ TextEditorComponent = React.createClass
@useHardwareAcceleration, @performedInitialMeasurement, @backgroundColor, @gutterBackgroundColor
}
div ref: 'scrollView', className: 'scroll-view',
div ref: 'scrollView', className: 'scroll-view', onMouseDown: @onMouseDown,
InputComponent
ref: 'input'
className: 'hidden-input'
style: hiddenInputStyle
onFocus: @onInputFocused
onBlur: @onInputBlurred
LinesComponent {
ref: 'lines',
@@ -173,14 +175,14 @@ TextEditorComponent = React.createClass
@setScrollSensitivity(atom.config.get('editor.scrollSensitivity'))
componentDidMount: ->
{editor, stylesElement} = @props
{editor} = @props
@observeEditor()
@listenForDOMEvents()
@subscribe stylesElement.onDidAddStyleElement @onStylesheetsChanged
@subscribe stylesElement.onDidUpdateStyleElement @onStylesheetsChanged
@subscribe stylesElement.onDidRemoveStyleElement @onStylesheetsChanged
@subscribe atom.themes.onDidAddStylesheet @onStylesheetsChanged
@subscribe atom.themes.onDidUpdateStylesheet @onStylesheetsChanged
@subscribe atom.themes.onDidRemoveStylesheet @onStylesheetsChanged
unless atom.themes.isInitialLoadComplete()
@subscribe atom.themes.onDidReloadAll @onStylesheetsChanged
@subscribe scrollbarStyle.changes, @refreshScrollbars
@@ -191,9 +193,9 @@ TextEditorComponent = React.createClass
@checkForVisibilityChange()
componentWillUnmount: ->
{editor, hostElement} = @props
{editor, parentView} = @props
hostElement.__spacePenView.trigger 'editor:will-be-removed', [hostElement.__spacePenView]
parentView.__spacePenView.trigger 'editor:will-be-removed', [parentView.__spacePenView]
@unsubscribe()
@scopedConfigSubscriptions.dispose()
window.removeEventListener 'resize', @requestHeightAndWidthMeasurement
@@ -213,9 +215,9 @@ TextEditorComponent = React.createClass
if @props.editor.isAlive()
@updateParentViewFocusedClassIfNeeded(prevState)
@updateParentViewMiniClassIfNeeded(prevState)
@props.hostElement.__spacePenView.trigger 'cursor:moved' if cursorMoved
@props.hostElement.__spacePenView.trigger 'selection:changed' if selectionChanged
@props.hostElement.__spacePenView.trigger 'editor:display-updated'
@props.parentView.__spacePenView.trigger 'cursor:moved' if cursorMoved
@props.parentView.__spacePenView.trigger 'selection:changed' if selectionChanged
@props.parentView.__spacePenView.trigger 'editor:display-updated'
becameVisible: ->
@updatesPaused = true
@@ -259,7 +261,7 @@ TextEditorComponent = React.createClass
@forceUpdate()
getTopmostDOMNode: ->
@props.hostElement
@props.parentView
getRenderedRowRange: ->
{editor, lineOverdrawMargin} = @props
@@ -376,8 +378,8 @@ TextEditorComponent = React.createClass
listenForDOMEvents: ->
node = @getDOMNode()
node.addEventListener 'mousewheel', @onMouseWheel
node.addEventListener 'focus', @onFocus # For some reason, React's built in focus events seem to bubble
node.addEventListener 'textInput', @onTextInput
@refs.scrollView.getDOMNode().addEventListener 'mousedown', @onMouseDown
scrollViewNode = @refs.scrollView.getDOMNode()
scrollViewNode.addEventListener 'scroll', @onScrollViewScroll
@@ -413,9 +415,6 @@ TextEditorComponent = React.createClass
observeConfig: ->
@subscribe atom.config.observe 'editor.useHardwareAcceleration', @setUseHardwareAcceleration
@subscribe atom.config.onDidChange 'editor.fontSize', @sampleFontStyling
@subscribe atom.config.onDidChange 'editor.fontFamily', @sampleFontStyling
@subscribe atom.config.onDidChange 'editor.lineHeight', @sampleFontStyling
onGrammarChanged: ->
{editor} = @props
@@ -429,14 +428,8 @@ TextEditorComponent = React.createClass
subscriptions.add atom.config.observe scopeDescriptor, 'editor.showLineNumbers', @setShowLineNumbers
subscriptions.add atom.config.observe scopeDescriptor, 'editor.scrollSensitivity', @setScrollSensitivity
focused: ->
if @isMounted()
@setState(focused: true)
@refs.input.focus()
blurred: ->
if @isMounted()
@setState(focused: false)
onFocus: ->
@refs.input.focus() if @isMounted()
onTextInput: (event) ->
event.stopPropagation()
@@ -459,6 +452,12 @@ TextEditorComponent = React.createClass
inputNode.value = event.data if editor.insertText(event.data)
onInputFocused: ->
@setState(focused: true)
onInputBlurred: ->
@setState(focused: false)
onVerticalScroll: (scrollTop) ->
{editor} = @props
@@ -622,11 +621,11 @@ TextEditorComponent = React.createClass
else
editor.setSelectedScreenRange([tailPosition, [dragRow + 1, 0]], preserveFolds: true)
onStylesheetsChanged: (styleElement) ->
onStylesheetsChanged: (stylesheet) ->
return unless @performedInitialMeasurement
return unless atom.themes.isInitialLoadComplete()
@refreshScrollbars() if not styleElement.sheet? or @containsScrollbarSelector(styleElement.sheet)
@refreshScrollbars() if not stylesheet? or @containsScrollbarSelector(stylesheet)
@sampleFontStyling()
@sampleBackgroundColors()
@remeasureCharacterWidths()
@@ -772,10 +771,10 @@ TextEditorComponent = React.createClass
measureHeightAndWidth: ->
return unless @isMounted()
{editor, hostElement} = @props
{editor, parentView} = @props
scrollViewNode = @refs.scrollView.getDOMNode()
{position} = getComputedStyle(hostElement)
{height} = hostElement.style
{position} = getComputedStyle(parentView)
{height} = parentView.style
if position is 'absolute' or height
if @autoHeight
@@ -807,9 +806,9 @@ TextEditorComponent = React.createClass
@remeasureCharacterWidths()
sampleBackgroundColors: (suppressUpdate) ->
{hostElement} = @props
{parentView} = @props
{showLineNumbers} = @state
{backgroundColor} = getComputedStyle(hostElement)
{backgroundColor} = getComputedStyle(parentView)
if backgroundColor isnt @backgroundColor
@backgroundColor = backgroundColor
@@ -908,10 +907,10 @@ TextEditorComponent = React.createClass
lineNumberNodeForScreenRow: (screenRow) -> @refs.gutter.lineNumberNodeForScreenRow(screenRow)
screenRowForNode: (node) ->
while node?
while node isnt document
if screenRow = node.dataset.screenRow
return parseInt(screenRow)
node = node.parentElement
node = node.parentNode
null
getFontSize: ->
@@ -978,13 +977,11 @@ TextEditorComponent = React.createClass
updateParentViewFocusedClassIfNeeded: (prevState) ->
if prevState.focused isnt @state.focused
@props.hostElement.classList.toggle('is-focused', @state.focused)
@props.rootElement.classList.toggle('is-focused', @state.focused)
@props.parentView.classList.toggle('is-focused', @state.focused)
updateParentViewMiniClassIfNeeded: (prevProps) ->
if prevProps.mini isnt @props.mini
@props.hostElement.classList.toggle('mini', @props.mini)
@props.rootElement.classList.toggle('mini', @props.mini)
@props.parentView.classList.toggle('mini', @props.mini)
runScrollBenchmark: ->
unless process.env.NODE_ENV is 'production'
+24 -47
Ver Arquivo
@@ -1,4 +1,5 @@
{View, $, callRemoveHooks} = require 'space-pen'
{callRemoveHooks} = require 'space-pen'
{Emitter} = require 'event-kit'
React = require 'react-atom-fork'
{defaults} = require 'underscore-plus'
TextBuffer = require 'text-buffer'
@@ -6,8 +7,6 @@ TextEditor = require './text-editor'
TextEditorComponent = require './text-editor-component'
TextEditorView = null
GlobalStylesElement = null
class TextEditorElement extends HTMLElement
model: null
componentDescriptor: null
@@ -15,44 +14,27 @@ class TextEditorElement extends HTMLElement
lineOverdrawMargin: null
focusOnAttach: false
onDidAttach: (callback) ->
@emitter.on 'did-attach', callback
onDidDetach: (callback) ->
@emitter.on 'did-detach', callback
createdCallback: ->
@subscriptions =
@emitter = new Emitter
@initializeContent()
@createSpacePenShim()
@addEventListener 'focus', @focused.bind(this)
@addEventListener 'focusout', @focusedOut.bind(this)
@addEventListener 'blur', @blurred.bind(this)
initializeContent: (attributes) ->
@classList.add('editor')
@classList.add('editor', 'react', 'editor-colors')
@setAttribute('tabindex', -1)
if atom.config.get('editor.useShadowDOM')
@createShadowRoot()
@stylesElement = document.createElement('atom-styles')
@stylesElement.setAttribute('context', 'atom-text-editor')
@stylesElement.initialize()
@rootElement = document.createElement('div')
@rootElement.classList.add('shadow')
@shadowRoot.appendChild(@stylesElement)
@shadowRoot.appendChild(@rootElement)
else
unless GlobalStylesElement?
GlobalStylesElement = document.createElement('atom-styles')
GlobalStylesElement.setAttribute('context', 'atom-text-editor')
GlobalStylesElement.initialize()
document.head.appendChild(GlobalStylesElement)
@stylesElement = GlobalStylesElement
@rootElement = this
@rootElement.classList.add('editor', 'editor-colors')
createSpacePenShim: ->
TextEditorView ?= require './text-editor-view'
TextEditorView ?= require('atom').TextEditorView
@__spacePenView = new TextEditorView(this)
attachedCallback: ->
@@ -60,6 +42,10 @@ class TextEditorElement extends HTMLElement
@mountComponent() unless @component?.isMounted()
@component.checkForVisibilityChange()
@focus() if @focusOnAttach
@emitter.emit 'did-attach'
detachedCallback: ->
@emitter.emit 'did-detach'
setModel: (model) ->
throw new Error("Model already assigned on TextEditorElement") if @model?
@@ -90,19 +76,12 @@ class TextEditorElement extends HTMLElement
mountComponent: ->
@componentDescriptor ?= TextEditorComponent(
hostElement: this
rootElement: @rootElement
stylesElement: @stylesElement
parentView: this
editor: @model
mini: @model.mini
lineOverdrawMargin: @lineOverdrawMargin
)
@component = React.renderComponent(@componentDescriptor, @rootElement)
unless atom.config.get('editor.useShadowDOM')
inputNode = @component.refs.input.getDOMNode()
inputNode.addEventListener 'focus', @focused.bind(this)
inputNode.addEventListener 'blur', => @dispatchEvent(new FocusEvent('blur', bubbles: false))
@component = React.renderComponent(@componentDescriptor, this)
unmountComponent: ->
return unless @component?.isMounted()
@@ -112,17 +91,15 @@ class TextEditorElement extends HTMLElement
focused: ->
if @component?
@component.focused()
@component.onFocus()
else
@focusOnAttach = true
blurred: (event) ->
unless atom.config.get('editor.useShadowDOM')
if event.relatedTarget is @component?.refs.input?.getDOMNode()
event.stopImmediatePropagation()
return
focusedOut: (event) ->
event.stopImmediatePropagation() if @contains(event.relatedTarget)
@component?.blurred()
blurred: (event) ->
event.stopImmediatePropagation() if @contains(event.relatedTarget)
addGrammarScopeAttribute: ->
grammarScope = @model.getGrammar()?.scopeName?.replace(/\./g, ' ')
-328
Ver Arquivo
@@ -1,328 +0,0 @@
{View, $} = require 'space-pen'
React = require 'react-atom-fork'
{defaults} = require 'underscore-plus'
TextBuffer = require 'text-buffer'
TextEditor = require './text-editor'
TextEditorElement = require './text-editor-element'
TextEditorComponent = require './text-editor-component'
{deprecate} = require 'grim'
# Public: 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
# to do are on {TextEditor}.
#
# ## Examples
#
# Requiring in packages
#
# ```coffee
# {TextEditorView} = require 'atom'
#
# miniEditorView = new TextEditorView(mini: true)
# ```
#
# Iterating over the open editor views
#
# ```coffee
# for editorView in atom.workspaceView.getEditorViews()
# console.log(editorView.getModel().getPath())
# ```
#
# Subscribing to every current and future editor
#
# ```coffee
# atom.workspace.eachEditorView (editorView) ->
# console.log(editorView.getModel().getPath())
# ```
module.exports =
class TextEditorView extends View
# The constructor for setting up an `TextEditorView` instance.
#
# * `modelOrParams` Either an {TextEditor}, or an object with one property, `mini`.
# If `mini` is `true`, a "miniature" `TextEditor` is constructed.
# Typically, this is ideal for scenarios where you need an Atom editor,
# but without all the chrome, like scrollbars, gutter, _e.t.c._.
#
constructor: (modelOrParams, props) ->
# Handle direct construction with an editor or params
unless modelOrParams instanceof HTMLElement
if modelOrParams instanceof TextEditor
model = modelOrParams
else
{editor, mini, placeholderText, attributes} = modelOrParams
model = editor ? new TextEditor
buffer: new TextBuffer
softWrapped: false
tabLength: 2
softTabs: true
mini: mini
placeholderText: placeholderText
element = new TextEditorElement
element.lineOverdrawMargin = props?.lineOverdrawMargin
element.setAttribute(name, value) for name, value of attributes if attributes?
element.setModel(model)
return element.__spacePenView
# Handle construction with an element
@element = modelOrParams
super
setModel: (@model) ->
@editor = @model
@root = $(@element.rootElement)
@scrollView = @root.find('.scroll-view')
if atom.config.get('editor.useShadowDOM')
@underlayer = $("<div class='underlayer'></div>").appendTo(this)
@overlayer = $("<div class='overlayer'></div>").appendTo(this)
else
@underlayer = @find('.highlights').addClass('underlayer')
@overlayer = @find('.lines').addClass('overlayer')
@hiddenInput = @root.find('.hidden-input')
@hiddenInput.on = (args...) =>
args[0] = 'blur' if args[0] is 'focusout'
$::on.apply(this, args)
@subscribe atom.config.observe 'editor.showLineNumbers', =>
@gutter = @root.find('.gutter')
@gutter.removeClassFromAllLines = (klass) =>
deprecate('Use decorations instead: http://blog.atom.io/2014/07/24/decorations.html')
@gutter.find('.line-number').removeClass(klass)
@gutter.getLineNumberElement = (bufferRow) =>
deprecate('Use decorations instead: http://blog.atom.io/2014/07/24/decorations.html')
@gutter.find("[data-buffer-row='#{bufferRow}']")
@gutter.addClassToLine = (bufferRow, klass) =>
deprecate('Use decorations instead: http://blog.atom.io/2014/07/24/decorations.html')
lines = @gutter.find("[data-buffer-row='#{bufferRow}']")
lines.addClass(klass)
lines.length > 0
find: ->
shadowResult = @root.find.apply(@root, arguments)
if shadowResult.length > 0
shadowResult
else
super
# Public: Get the underlying editor model for this view.
#
# Returns an {TextEditor}
getModel: -> @model
getEditor: -> @model
Object.defineProperty @::, 'lineHeight', get: -> @model.getLineHeightInPixels()
Object.defineProperty @::, 'charWidth', get: -> @model.getDefaultCharWidth()
Object.defineProperty @::, 'firstRenderedScreenRow', get: -> @component.getRenderedRowRange()[0]
Object.defineProperty @::, 'lastRenderedScreenRow', get: -> @component.getRenderedRowRange()[1]
Object.defineProperty @::, 'active', get: -> @is(@getPaneView()?.activeView)
Object.defineProperty @::, 'isFocused', get: -> document.activeElement is @element or document.activeElement is @element.component?.refs.input.getDOMNode()
Object.defineProperty @::, 'mini', get: -> @component?.props.mini
Object.defineProperty @::, 'component', get: -> @element?.component
afterAttach: (onDom) ->
return unless onDom
return if @attached
@attached = true
@trigger 'editor:attached', [this]
beforeRemove: ->
@trigger 'editor:detached', [this]
@attached = false
remove: (selector, keepData) ->
@model.destroy() unless keepData
super
scrollTop: (scrollTop) ->
if scrollTop?
@model.setScrollTop(scrollTop)
else
@model.getScrollTop()
scrollLeft: (scrollLeft) ->
if scrollLeft?
@model.setScrollLeft(scrollLeft)
else
@model.getScrollLeft()
scrollToBottom: ->
deprecate 'Use TextEditor::scrollToBottom instead. You can get the editor via editorView.getModel()'
@model.setScrollBottom(Infinity)
scrollToScreenPosition: (screenPosition, options) ->
deprecate 'Use TextEditor::scrollToScreenPosition instead. You can get the editor via editorView.getModel()'
@model.scrollToScreenPosition(screenPosition, options)
scrollToBufferPosition: (bufferPosition, options) ->
deprecate 'Use TextEditor::scrollToBufferPosition instead. You can get the editor via editorView.getModel()'
@model.scrollToBufferPosition(bufferPosition, options)
scrollToCursorPosition: ->
deprecate 'Use TextEditor::scrollToCursorPosition instead. You can get the editor via editorView.getModel()'
@model.scrollToCursorPosition()
pixelPositionForBufferPosition: (bufferPosition) ->
deprecate 'Use TextEditor::pixelPositionForBufferPosition instead. You can get the editor via editorView.getModel()'
@model.pixelPositionForBufferPosition(bufferPosition)
pixelPositionForScreenPosition: (screenPosition) ->
deprecate 'Use TextEditor::pixelPositionForScreenPosition instead. You can get the editor via editorView.getModel()'
@model.pixelPositionForScreenPosition(screenPosition)
appendToLinesView: (view) ->
view.css('position', 'absolute')
view.css('z-index', 1)
@overlayer.append(view)
unmountComponent: ->
React.unmountComponentAtNode(@element) if @component.isMounted()
splitLeft: ->
deprecate """
Use Pane::splitLeft instead.
To duplicate this editor into the split use:
editorView.getPaneView().getModel().splitLeft(copyActiveItem: true)
"""
pane = @getPaneView()
pane?.splitLeft(pane?.copyActiveItem()).activeView
splitRight: ->
deprecate """
Use Pane::splitRight instead.
To duplicate this editor into the split use:
editorView.getPaneView().getModel().splitRight(copyActiveItem: true)
"""
pane = @getPaneView()
pane?.splitRight(pane?.copyActiveItem()).activeView
splitUp: ->
deprecate """
Use Pane::splitUp instead.
To duplicate this editor into the split use:
editorView.getPaneView().getModel().splitUp(copyActiveItem: true)
"""
pane = @getPaneView()
pane?.splitUp(pane?.copyActiveItem()).activeView
splitDown: ->
deprecate """
Use Pane::splitDown instead.
To duplicate this editor into the split use:
editorView.getPaneView().getModel().splitDown(copyActiveItem: true)
"""
pane = @getPaneView()
pane?.splitDown(pane?.copyActiveItem()).activeView
# Public: Get this {TextEditorView}'s {PaneView}.
#
# Returns a {PaneView}
getPaneView: ->
@parent('.item-views').parents('atom-pane').view()
getPane: ->
deprecate 'Use TextEditorView::getPaneView() instead'
@getPaneView()
show: ->
super
@component?.checkForVisibilityChange()
hide: ->
super
@component?.checkForVisibilityChange()
pageDown: ->
deprecate('Use editorView.getModel().pageDown()')
@model.pageDown()
pageUp: ->
deprecate('Use editorView.getModel().pageUp()')
@model.pageUp()
getFirstVisibleScreenRow: ->
deprecate 'Use TextEditor::getFirstVisibleScreenRow instead. You can get the editor via editorView.getModel()'
@model.getFirstVisibleScreenRow()
getLastVisibleScreenRow: ->
deprecate 'Use TextEditor::getLastVisibleScreenRow instead. You can get the editor via editorView.getModel()'
@model.getLastVisibleScreenRow()
getFontFamily: ->
deprecate 'This is going away. Use atom.config.get("editor.fontFamily") instead'
@component?.getFontFamily()
setFontFamily: (fontFamily) ->
deprecate 'This is going away. Use atom.config.set("editor.fontFamily", "my-font") instead'
@component?.setFontFamily(fontFamily)
getFontSize: ->
deprecate 'This is going away. Use atom.config.get("editor.fontSize") instead'
@component?.getFontSize()
setFontSize: (fontSize) ->
deprecate 'This is going away. Use atom.config.set("editor.fontSize", 12) instead'
@component?.setFontSize(fontSize)
setLineHeight: (lineHeight) ->
deprecate 'This is going away. Use atom.config.set("editor.lineHeight", 1.5) instead'
@component.setLineHeight(lineHeight)
setWidthInChars: (widthInChars) ->
@component.getDOMNode().style.width = (@model.getDefaultCharWidth() * widthInChars) + 'px'
setShowIndentGuide: (showIndentGuide) ->
deprecate 'This is going away. Use atom.config.set("editor.showIndentGuide", true|false) instead'
@component.setShowIndentGuide(showIndentGuide)
setSoftWrap: (softWrapped) ->
deprecate 'Use TextEditor::setSoftWrapped instead. You can get the editor via editorView.getModel()'
@model.setSoftWrapped(softWrapped)
setShowInvisibles: (showInvisibles) ->
deprecate 'This is going away. Use atom.config.set("editor.showInvisibles", true|false) instead'
@component.setShowInvisibles(showInvisibles)
getText: ->
@model.getText()
setText: (text) ->
@model.setText(text)
insertText: (text) ->
@model.insertText(text)
isInputEnabled: ->
@component.isInputEnabled()
setInputEnabled: (inputEnabled) ->
@component.setInputEnabled(inputEnabled)
requestDisplayUpdate: ->
deprecate('Please remove from your code. ::requestDisplayUpdate no longer does anything')
updateDisplay: ->
deprecate('Please remove from your code. ::updateDisplay no longer does anything')
resetDisplay: ->
deprecate('Please remove from your code. ::resetDisplay no longer does anything')
redraw: ->
deprecate('Please remove from your code. ::redraw no longer does anything')
setPlaceholderText: (placeholderText) ->
deprecate('Use TextEditor::setPlaceholderText instead. eg. editorView.getModel().setPlaceholderText(text)')
@model.setPlaceholderText(placeholderText)
lineElementForScreenRow: (screenRow) ->
$(@component.lineNodeForScreenRow(screenRow))
+3 -5
Ver Arquivo
@@ -6,7 +6,7 @@ Delegator = require 'delegato'
{Model} = require 'theorist'
EmitterMixin = require('emissary').Emitter
{CompositeDisposable, Emitter} = require 'event-kit'
{Point, Range} = require 'text-buffer'
{Point, Range} = TextBuffer = require 'text-buffer'
LanguageMode = require './language-mode'
DisplayBuffer = require './display-buffer'
Cursor = require './cursor'
@@ -84,6 +84,7 @@ class TextEditor extends Model
@cursors = []
@selections = []
buffer ?= new TextBuffer
@displayBuffer ?= new DisplayBuffer({buffer, tabLength, softWrapped})
@buffer = @displayBuffer.buffer
@softTabs = @usesSoftTabs() ? @softTabs ? atom.config.get('editor.softTabs') ? true
@@ -737,12 +738,9 @@ class TextEditor extends Model
#
# * `range` A {Range} or range-compatible {Array}.
# * `text` A {String}
# * `options` (optional) {Object}
# * `normalizeLineEndings` (optional) {Boolean} (default: true)
# * `undo` (optional) {String} 'skip' will skip the undo system
#
# Returns the {Range} of the newly-inserted text.
setTextInBufferRange: (range, text, options) -> @getBuffer().setTextInRange(range, text, options)
setTextInBufferRange: (range, text, normalizeLineEndings) -> @getBuffer().setTextInRange(range, text, normalizeLineEndings)
# Essential: For each selection, replace the selected text with the given text.
#
+1 -4
Ver Arquivo
@@ -241,7 +241,7 @@ class ThemeManager
@applyStylesheet(userStylesheetPath, userStylesheetContents, 'userTheme')
loadBaseStylesheets: ->
@requireStylesheet('../static/bootstrap')
@requireStylesheet('bootstrap/less/bootstrap')
@reloadBaseStylesheets()
reloadBaseStylesheets: ->
@@ -249,9 +249,6 @@ class ThemeManager
if nativeStylesheetPath = fs.resolveOnLoadPath(process.platform, ['css', 'less'])
@requireStylesheet(nativeStylesheetPath)
textEditorStylesPath = path.join(@resourcePath, 'static', 'text-editor-shadow.less')
atom.styles.addStyleSheet(@loadLessStylesheet(textEditorStylesPath), sourcePath: textEditorStylesPath, context: 'atom-text-editor')
stylesheetElementForId: (id) ->
document.head.querySelector("atom-styles style[source-path=\"#{id}\"]")
+1 -4
Ver Arquivo
@@ -125,10 +125,7 @@ class TokenizedBuffer extends Model
getTabLength: ->
@tabLength ? @configSettings.tabLength
setTabLength: (tabLength) ->
return if tabLength is @tabLength
@tabLength = tabLength
setTabLength: (@tabLength) ->
@retokenizeLines()
setInvisibles: (invisibles) ->
+2 -1
Ver Arquivo
@@ -1,4 +1,5 @@
{Disposable} = require 'event-kit'
{jQuery} = require './space-pen-extensions'
# Essential: `ViewRegistry` handles the association between model and view
# types in Atom. We call this association a View Provider. As in, for a given
@@ -124,7 +125,7 @@ class ViewRegistry
createView: (object) ->
if object instanceof HTMLElement
object
else if object?.jquery
else if object instanceof jQuery
object[0]?.__spacePenView ?= object
object[0]
else if provider = @findProvider(object)
-3
Ver Arquivo
@@ -77,7 +77,6 @@ class WorkspaceElement extends HTMLElement
left: @model.panelContainers.left.getView()
right: @model.panelContainers.right.getView()
bottom: @model.panelContainers.bottom.getView()
modal: @model.panelContainers.modal.getView()
@horizontalAxis.insertBefore(@panelContainers.left, @verticalAxis)
@horizontalAxis.appendChild(@panelContainers.right)
@@ -85,8 +84,6 @@ class WorkspaceElement extends HTMLElement
@verticalAxis.insertBefore(@panelContainers.top, @paneContainer)
@verticalAxis.appendChild(@panelContainers.bottom)
@appendChild(@panelContainers.modal)
@__spacePenView.setModel(@model)
setTextEditorFontSize: (fontSize) ->
-16
Ver Arquivo
@@ -262,22 +262,6 @@ class WorkspaceView extends View
deprecate('Use Workspace::onDidOpen instead')
originalWorkspaceViewOn.apply(this, arguments)
TextEditorView = require './text-editor-view'
originalEditorViewOn = TextEditorView::on
TextEditorView::on = (eventName) ->
switch eventName
when 'cursor:moved'
deprecate('Use TextEditor::onDidChangeCursorPosition instead')
when 'editor:attached'
deprecate('Use TextEditor::onDidAddTextEditor instead')
when 'editor:detached'
deprecate('Use TextEditor::onDidDestroy instead')
when 'editor:will-be-removed'
deprecate('Use TextEditor::onDidDestroy instead')
when 'selection:changed'
deprecate('Use TextEditor::onDidChangeSelectionRange instead')
originalEditorViewOn.apply(this, arguments)
originalPaneViewOn = PaneView::on
PaneView::on = (eventName) ->
switch eventName
-18
Ver Arquivo
@@ -54,7 +54,6 @@ class Workspace extends Model
left: new PanelContainer({viewRegistry, location: 'left'})
right: new PanelContainer({viewRegistry, location: 'right'})
bottom: new PanelContainer({viewRegistry, location: 'bottom'})
modal: new PanelContainer({viewRegistry, location: 'modal'})
@subscribeToActiveItem()
@@ -661,23 +660,6 @@ class Workspace extends Model
addTopPanel: (options) ->
@addPanel('top', options)
# 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.
# * `visible` (optional) {Boolean} false if you want the panel to initially be hidden
# (default: true)
# * `priority` (optional) {Number} Determines stacking order. Lower priority items are
# forced closer to the edges of the window. (default: 100)
#
# Returns a {Panel}
addModalPanel: (options={}) ->
# TODO: remove these default classes. They are to supoprt existing themes.
options.className ?= 'overlay from-top'
@addPanel('modal', options)
addPanel: (location, options) ->
options ?= {}
options.viewRegistry = atom.views
+3 -3
Ver Arquivo
@@ -10,19 +10,19 @@
@import "octicon-mixins";
@import "workspace-view";
@import "bootstrap-overrides";
@import "bootstrap";
@import "buttons";
@import "icons";
@import "links";
@import "panes";
@import "panels";
@import "sections";
@import "overlay";
@import "lists";
@import "popover-list";
@import "messages";
@import "markdown";
@import "text-editor-light";
@import "select-list";
@import "editor";
@import "syntax";
@import "utilities";
@import "octicons";
-14
Ver Arquivo
@@ -1,14 +0,0 @@
@import "ui-variables";
.nav {
> li > a {
border-radius: @component-border-radius;
}
> li > a:hover {
background-color: @background-color-highlight;
}
&.nav-pills > li.active > a {
background-color: @background-color-selected;
}
}
+12 -28
Ver Arquivo
@@ -1,30 +1,14 @@
// Core variables and mixins
@import "../node_modules/bootstrap/less/variables.less";
@import "../node_modules/bootstrap/less/mixins.less";
@import "ui-variables";
// Reset
@import "../node_modules/bootstrap/less/normalize.less";
.nav {
> li > a {
border-radius: @component-border-radius;
}
> li > a:hover {
background-color: @background-color-highlight;
}
// Core CSS
@import "../node_modules/bootstrap/less/scaffolding.less";
@import "../node_modules/bootstrap/less/type.less";
@import "../node_modules/bootstrap/less/code.less";
@import "../node_modules/bootstrap/less/grid.less";
@import "../node_modules/bootstrap/less/tables.less";
@import "../node_modules/bootstrap/less/forms.less";
@import "../node_modules/bootstrap/less/buttons.less";
// Components
@import "../node_modules/bootstrap/less/button-groups.less";
@import "../node_modules/bootstrap/less/input-groups.less";
@import "../node_modules/bootstrap/less/navs.less";
@import "../node_modules/bootstrap/less/labels.less";
@import "../node_modules/bootstrap/less/badges.less";
@import "../node_modules/bootstrap/less/alerts.less";
@import "../node_modules/bootstrap/less/list-group.less";
// Components w/ JavaScript
@import "../node_modules/bootstrap/less/tooltip.less";
// Utility classes
@import "../node_modules/bootstrap/less/utilities.less";
&.nav-pills > li.active > a {
background-color: @background-color-selected;
}
}
+310
Ver Arquivo
@@ -0,0 +1,310 @@
@import "ui-variables";
@import "octicon-utf-codes";
@import "octicon-mixins";
atom-text-editor.react {
.editor-contents {
width: 100%;
}
.underlayer {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
z-index: -2;
}
.lines {
min-width: 100%;
}
.cursor {
z-index: 4;
pointer-events: none;
}
.editor-contents.is-focused .cursor {
visibility: visible;
}
.cursors.blink-off .cursor {
opacity: 0;
}
.horizontal-scrollbar {
position: absolute;
left: 0;
right: 0;
bottom: 0;
height: 15px;
overflow-x: auto;
overflow-y: hidden;
z-index: 3;
.scrollbar-content {
height: 15px;
}
}
.vertical-scrollbar {
overflow-x: hidden;
}
.scrollbar-corner {
position: absolute;
overflow: auto;
bottom: 0;
right: 0;
}
.scroll-view {
overflow: hidden;
z-index: 0;
}
.scroll-view-content {
position: relative;
width: 100%;
}
.gutter {
.line-number {
white-space: nowrap;
padding-left: .5em;
.icon-right {
padding: 0 .4em;
&:before {
text-align: center;
}
}
}
}
}
atom-text-editor.mini {
font-size: @input-font-size;
line-height: @component-line-height;
max-height: @component-line-height + 2; // +2 for borders
.placeholder-text {
position: absolute;
color: @text-color-subtle;
}
}
atom-text-editor {
z-index: 0;
font-family: Inconsolata, Monaco, Consolas, 'Courier New', Courier;
line-height: 1.3;
}
atom-text-editor, .editor-contents {
overflow: hidden;
cursor: text;
display: -webkit-flex;
-webkit-user-select: none;
position: relative;
}
atom-text-editor .gutter .line-number.cursor-line {
opacity: 1;
}
atom-text-editor .gutter {
overflow: hidden;
text-align: right;
cursor: default;
min-width: 1em;
box-sizing: border-box;
}
atom-text-editor .gutter .line-number {
padding-left: .5em;
opacity: 0.6;
}
atom-text-editor .gutter .line-numbers {
position: relative;
}
atom-text-editor .gutter .line-number.folded.cursor-line {
opacity: 1;
}
atom-text-editor .gutter .line-number .icon-right {
.octicon(chevron-down, 0.8em);
display: inline-block;
visibility: hidden;
padding-left: .1em;
padding-right: .5em;
opacity: .6;
}
atom-text-editor .gutter:hover .line-number.foldable .icon-right {
visibility: visible;
&:before {
content: @chevron-down;
}
&:hover {
opacity: 1;
}
}
atom-text-editor .gutter, atom-text-editor .gutter:hover {
.line-number.folded .icon-right {
.octicon(chevron-right, 0.8em);
visibility: visible;
&:before { // chevron-right renders too far right compared to chevron-down
position: relative;
left: -.1em;
content: @chevron-right;
}
}
}
atom-text-editor .fold-marker {
cursor: default;
}
atom-text-editor .fold-marker:after {
.icon(0.8em, inline);
content: @ellipsis;
padding-left: 0.2em;
}
atom-text-editor .line.cursor-line .fold-marker:after {
opacity: 1;
}
atom-text-editor.is-blurred .line.cursor-line {
background: rgba(0, 0, 0, 0);
}
atom-text-editor .invisible-character {
font-weight: normal !important;
font-style: normal !important;
}
atom-text-editor .indent-guide {
display: inline-block;
box-shadow: inset 1px 0;
}
atom-text-editor .vertical-scrollbar,
atom-text-editor .horizontal-scrollbar {
cursor: default;
}
atom-text-editor .vertical-scrollbar {
position: absolute;
top: 0;
right: 0;
bottom: 0;
width: 15px;
overflow-y: auto;
z-index: 3;
}
atom-text-editor .scroll-view {
overflow-x: auto;
overflow-y: hidden;
-webkit-flex: 1;
min-width: 0;
position: relative;
}
atom-text-editor.soft-wrap .scroll-view {
overflow-x: hidden;
}
atom-text-editor .underlayer {
z-index: 0;
position: absolute;
min-height: 100%;
}
atom-text-editor .lines {
position: relative;
z-index: 1;
}
atom-text-editor .overlayer {
z-index: 2;
position: absolute;
}
atom-text-editor .line {
white-space: pre;
}
atom-text-editor .line span {
vertical-align: top;
}
atom-text-editor .cursor {
position: absolute;
border-left: 1px solid;
}
atom-text-editor .cursor,
atom-text-editor.is-focused .cursor.blink-off {
visibility: hidden;
}
atom-text-editor.is-focused .cursor {
visibility: visible;
}
.cursor.hidden-cursor {
display: none;
}
atom-text-editor .hidden-input {
padding: 0;
border: 0;
position: absolute;
z-index: -1;
top: 0;
left: 0;
opacity: 0;
width: 1px;
}
atom-text-editor .highlight {
background: none;
padding: 0;
}
atom-text-editor .highlight .region,
atom-text-editor .selection .region {
position: absolute;
pointer-events: none;
z-index: -1;
}
atom-text-editor.mini:not(.react) {
height: auto;
line-height: 25px;
.cursor {
width: 2px;
line-height: 20px;
margin-top: 2px;
}
.gutter {
display: none;
}
.scroll-view {
overflow: hidden;
}
}
+57
Ver Arquivo
@@ -0,0 +1,57 @@
@import "ui-variables";
.overlay {
position: absolute;
left: 50%;
width: 500px;
margin-left: -250px;
z-index: 9999;
box-sizing: border-box;
background-color: #fff;
padding: 10px;
h1 {
margin-top: 0;
color: @text-color-highlight;
font-size: 1.6em;
font-weight: bold;
}
h2 {
font-size: 1.3em;
}
}
.overlay atom-text-editor.mini {
margin-bottom: 10px;
}
.overlay .message {
padding-top: 5px;
font-size: 11px;
}
.overlay.mini {
width: 200px;
margin-left: -100px;
font-size: 12px;
}
.overlay.from-top {
top: 0;
border-top: none;
border-top-left-radius: 0;
border-top-right-radius: 0;
}
.overlay.from-bottom {
bottom: 0;
border-bottom: none;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
.overlay.floating {
left: auto;
}
+11 -97
Ver Arquivo
@@ -1,7 +1,17 @@
@import "ui-variables";
// Override bootstrap styles here.
atom-panel-container[location="left"],
atom-panel-container[location="right"] {
display: -webkit-flex;
-webkit-flex-direction: row;
-webkit-align-items: stretch;
height: 100%;
atom-panel {
height: 100%;
}
}
// Override bootstrap styles here.
.panel {
border-radius: 0;
border: none;
@@ -15,8 +25,6 @@
}
}
// interstitial panels
.inset-panel {
.panel-heading {
border-radius: @component-border-radius @component-border-radius 0 0;
@@ -40,97 +48,3 @@
top: -5px;
}
}
// Tool panels
atom-panel-container[location="left"],
atom-panel-container[location="right"] {
display: -webkit-flex;
-webkit-flex-direction: row;
-webkit-align-items: stretch;
height: 100%;
atom-panel {
height: 100%;
}
}
atom-panel {
display: block;
}
atom-panel[location="top"],
atom-panel[location="bottom"],
atom-panel[location="left"],
atom-panel[location="right"] {
background-color: @tool-panel-background-color;
}
// deprecated
.tool-panel {
position: relative;
background-color: @tool-panel-background-color;
}
// Modal panels
.overlay, // deprecated .overlay
atom-panel[location="modal"] {
position: absolute;
left: 50%;
width: 500px;
margin-left: -250px;
z-index: 9999;
box-sizing: border-box;
color: @text-color;
background-color: @overlay-background-color;
padding: 10px;
h1 {
margin-top: 0;
color: @text-color-highlight;
font-size: 1.6em;
font-weight: bold;
}
h2 {
font-size: 1.3em;
}
atom-text-editor.mini {
margin-bottom: 10px;
}
.message {
padding-top: 5px;
font-size: 11px;
}
&.mini {
width: 200px;
margin-left: -100px;
font-size: 12px;
}
}
// deprecated: from-top, from-bottom
.overlay.from-top,
atom-panel[location="modal"] {
top: 0;
border-top: none;
border-top-left-radius: 0;
border-top-right-radius: 0;
}
// TODO: Remove these!
.overlay.from-bottom {
bottom: 0;
border-bottom: none;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
.overlay.floating {
left: auto;
}
-40
Ver Arquivo
@@ -1,40 +0,0 @@
@import "ui-variables";
@import "octicon-mixins";
.select-list {
.loading {
.loading-message {
.octicon(hourglass);
&:before {
font-size: 1.1em;
width: 1.1em;
height: 1.1em;
margin-right: 5px;
}
}
.badge {
margin-left: 10px;
}
}
ol.list-group {
position: relative;
overflow-y: auto;
max-height: 312px;
margin: @component-padding 0 0 0;
padding: 0;
li {
display: block;
.primary-line,
.secondary-line {
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
}
}
}
-13
Ver Arquivo
@@ -1,13 +0,0 @@
@import "ui-variables";
atom-text-editor {
display: block;
font-family: Inconsolata, Monaco, Consolas, 'Courier New', Courier;
line-height: 1.3;
}
atom-text-editor.mini {
font-size: @input-font-size;
line-height: @component-line-height;
max-height: @component-line-height + 2; // +2 for borders
}
-286
Ver Arquivo
@@ -1,286 +0,0 @@
@import "ui-variables";
@import "octicon-utf-codes";
@import "octicon-mixins";
.editor-contents {
width: 100%;
}
.editor.shadow, .editor.shadow .editor-contents {
height: 100%;
width: 100%;
}
.underlayer {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
z-index: -2;
}
.lines {
min-width: 100%;
}
.cursor {
z-index: 4;
pointer-events: none;
box-sizing: border-box;
}
.cursors.blink-off .cursor {
opacity: 0;
}
.horizontal-scrollbar {
position: absolute;
left: 0;
right: 0;
bottom: 0;
height: 15px;
overflow-x: auto;
overflow-y: hidden;
z-index: 3;
.scrollbar-content {
height: 15px;
}
}
.vertical-scrollbar {
overflow-x: hidden;
}
.scrollbar-corner {
position: absolute;
overflow: auto;
bottom: 0;
right: 0;
}
.scroll-view {
overflow: hidden;
z-index: 0;
}
.scroll-view-content {
position: relative;
width: 100%;
}
.gutter {
.line-number {
white-space: nowrap;
padding-left: .5em;
.icon-right {
padding: 0 .4em;
&:before {
text-align: center;
}
}
}
}
.placeholder-text {
position: absolute;
color: @text-color-subtle;
}
.editor {
z-index: 0;
}
.editor, .editor-contents {
overflow: hidden;
cursor: text;
display: -webkit-flex;
-webkit-user-select: none;
position: relative;
}
.gutter .line-number.cursor-line {
opacity: 1;
}
.gutter {
overflow: hidden;
text-align: right;
cursor: default;
min-width: 1em;
box-sizing: border-box;
}
.gutter .line-number {
padding-left: .5em;
opacity: 0.6;
}
.gutter .line-numbers {
position: relative;
}
.gutter .line-number.folded.cursor-line {
opacity: 1;
}
.gutter .line-number .icon-right {
.octicon(chevron-down, 0.8em);
display: inline-block;
visibility: hidden;
padding-left: .1em;
padding-right: .5em;
opacity: .6;
}
.gutter:hover .line-number.foldable .icon-right {
visibility: visible;
&:before {
content: @chevron-down;
}
&:hover {
opacity: 1;
}
}
.gutter, .gutter:hover {
.line-number.folded .icon-right {
.octicon(chevron-right, 0.8em);
visibility: visible;
&:before { // chevron-right renders too far right compared to chevron-down
position: relative;
left: -.1em;
content: @chevron-right;
}
}
}
.fold-marker {
cursor: default;
}
.fold-marker:after {
.icon(0.8em, inline);
content: @ellipsis;
padding-left: 0.2em;
}
.line.cursor-line .fold-marker:after {
opacity: 1;
}
atom-text-editor::shadow.is-blurred .line.cursor-line {
background: rgba(0, 0, 0, 0);
}
.invisible-character {
font-weight: normal !important;
font-style: normal !important;
}
.indent-guide {
display: inline-block;
box-shadow: inset 1px 0;
}
.vertical-scrollbar,
.horizontal-scrollbar {
cursor: default;
}
.vertical-scrollbar {
position: absolute;
top: 0;
right: 0;
bottom: 0;
width: 15px;
overflow-y: auto;
z-index: 3;
}
.scroll-view {
overflow-x: auto;
overflow-y: hidden;
-webkit-flex: 1;
min-width: 0;
position: relative;
}
atom-text-editor::shadow.soft-wrap .scroll-view {
overflow-x: hidden;
}
.underlayer {
z-index: 0;
position: absolute;
min-height: 100%;
}
.lines {
position: relative;
z-index: 1;
}
.overlayer {
z-index: 2;
position: absolute;
}
.line {
white-space: pre;
}
.line span {
vertical-align: top;
}
.cursor {
position: absolute;
border-left: 1px solid;
}
.cursor {
visibility: hidden;
}
.is-focused .cursor {
visibility: visible;
}
.is-focused .cursor.blink-off {
visibility: hidden;
}
.cursor.hidden-cursor {
display: none;
}
.hidden-input {
padding: 0;
border: 0;
position: absolute;
z-index: -1;
top: 0;
left: 0;
opacity: 0;
width: 1px;
}
.highlight {
background: none;
padding: 0;
}
.highlight .region,
.selection .region {
position: absolute;
pointer-events: none;
z-index: -1;
}
+1 -1
Ver Arquivo
@@ -141,7 +141,7 @@ jasmine.JQuery.matchersClass = {};
if (this.actual instanceof HTMLElement) {
this.actual = jQuery(this.actual);
}
if (this.actual instanceof jQuery) {
if (this.actual instanceof jQuery || this.actual && this.actual.jquery) {
var result = jQueryMatchers[methodName].apply(this, arguments);
this.actual = jasmine.JQuery.elementToString(this.actual);
return result;