Pull out settings-view package into a separate repo

This commit is contained in:
Kevin Sawicki
2013-08-13 12:21:27 -07:00
parent 25378e9905
commit 184e6a14c7
14 changed files with 1 additions and 1174 deletions

View File

@@ -85,6 +85,7 @@
"link": "0.1.0",
"markdown-preview": "0.1.0",
"package-generator": "0.1.0",
"settings-view": "0.1.0",
"snippets": "0.1.0",
"spell-check": "0.1.0",
"status-bar": "0.1.0",

View File

@@ -1,2 +0,0 @@
'body':
'meta-,': 'settings-view:toggle'

View File

@@ -1,134 +0,0 @@
{$$, View} = require 'space-pen'
$ = require 'jquery'
_ = require 'underscore'
async = require 'async'
AtomPackage = require 'atom-package'
Editor = require 'editor'
###
# Internal #
###
module.exports =
class GeneralPanel extends View
@content: ->
@form id: 'general-panel', class: 'form-horizontal', =>
@div outlet: "loadingElement", class: 'alert alert-info loading-area', "Loading settings"
initialize: ->
window.setTimeout (=> @activatePackages => @showSettings()), 1
showSettings: ->
@loadingElement.hide()
@appendSettings(name, settings) for name, settings of config.getSettings()
@bindFormFields()
@bindEditors()
activatePackages: (finishedCallback) ->
iterator = (pack, callback) ->
try
if pack instanceof AtomPackage and not pack.isActive()
pack.activate({immediate: true})
catch e
console.error e
finally
callback()
async.each atom.getLoadedPackages(), iterator, finishedCallback
appendSettings: (namespace, settings) ->
return if _.isEmpty(settings)
@append $$ ->
@fieldset =>
@legend "#{_.uncamelcase(namespace)} settings"
appendSetting.call(this, namespace, name, value) for name, value of settings
bindFormFields: ->
for input in @find('input[id]').toArray()
do (input) =>
input = $(input)
name = input.attr('id')
type = input.attr('type')
@observeConfig name, (value) ->
if type is 'checkbox'
input.attr('checked', value)
else
input.val(value) if value
input.on 'change', =>
value = input.val()
if type == 'checkbox'
value = !!input.attr('checked')
else
value = @parseValue(type, value)
config.set(name, value)
bindEditors: ->
for editor in @find('.editor[id]').views()
do (editor) =>
name = editor.attr('id')
type = editor.attr('type')
@observeConfig name, (value) ->
return if value?.toString() == editor.getText()
value ?= ""
editor.setText(value.toString())
editor.getBuffer().on 'contents-modified', =>
config.set(name, @parseValue(type, editor.getText()))
parseValue: (type, value) ->
if value == ''
value = undefined
else if type == 'int'
intValue = parseInt(value)
value = intValue unless isNaN(intValue)
else if type == 'float'
floatValue = parseFloat(value)
value = floatValue unless isNaN(floatValue)
value
###
# Space Pen Helpers
###
appendSetting = (namespace, name, value) ->
return if namespace is 'core' and name is 'themes' # Handled in the Themes panel
@div class: 'control-group', =>
@div class: 'controls', =>
if _.isBoolean(value)
appendCheckbox.call(this, namespace, name, value)
else if _.isArray(value)
appendArray.call(this, namespace, name, value)
else
appendEditor.call(this, namespace, name, value)
appendCheckbox = (namespace, name, value) ->
englishName = _.uncamelcase(name)
keyPath = "#{namespace}.#{name}"
@div class: 'checkbox', =>
@label for: keyPath, =>
@input id: keyPath, type: 'checkbox'
@text englishName
appendEditor = (namespace, name, value) ->
englishName = _.uncamelcase(name)
keyPath = "#{namespace}.#{name}"
if _.isNumber(value)
type = if value % 1 == 0 then 'int' else 'float'
else
type = 'string'
@label class: 'control-label', englishName
@div class: 'controls', =>
@subview keyPath.replace('.', ''), new Editor(mini: true, attributes: {id: keyPath, type: type})
appendArray = (namespace, name, value) ->
englishName = _.uncamelcase(name)
@label class: 'control-label', englishName
@div class: 'controls', =>
@text "readOnly: " + value.join(", ")

View File

@@ -1,78 +0,0 @@
BufferedNodeProcess = require 'buffered-node-process'
roaster = require 'roaster'
async = require 'async'
### Internal ###
renderMarkdownInMetadata = (packages, callback) ->
queue = async.queue (pack, callback) ->
operations = []
if pack.description
operations.push (callback) ->
roaster pack.description, {}, (error, html) ->
pack.descriptionHtml = html
callback()
if pack.readme
operations.push (callback) ->
roaster pack.readme, {}, (error, html) ->
pack.readmeHtml = html
callback()
async.waterfall(operations, callback)
queue.push(pack) for pack in packages
queue.drain = callback
getAvailable = (callback) ->
command = require.resolve '.bin/apm'
args = ['available', '--json']
output = []
stdout = (lines) -> output.push(lines)
exit = (code) ->
if code is 0
try
packages = JSON.parse(output.join()) ? []
catch error
callback(error)
return
if packages.length > 0
renderMarkdownInMetadata packages, -> callback(null, packages)
else
callback(null, packages)
else
callback(new Error("apm failed with code: #{code}"))
new BufferedNodeProcess({command, args, stdout, exit})
install = ({name, version}, callback) ->
activateOnSuccess = !atom.isPackageDisabled(name)
activateOnFailure = atom.isPackageActive(name)
atom.deactivatePackage(name) if atom.isPackageActive(name)
atom.unloadPackage(name) if atom.isPackageLoaded(name)
command = require.resolve '.bin/apm'
args = ['install', "#{name}@#{version}"]
exit = (code) ->
if code is 0
atom.activatePackage(name) if activateOnSuccess
callback()
else
atom.activatePackage(name) if activateOnFailure
callback(new Error("Installing '#{name}' failed."))
new BufferedNodeProcess({command, args, exit})
uninstall = ({name}, callback) ->
atom.deactivatePackage(name) if atom.isPackageActive(name)
command = require.resolve '.bin/apm'
args = ['uninstall', name]
exit = (code) ->
if code is 0
atom.unloadPackage(name) if atom.isPackageLoaded(name)
callback()
else
callback(new Error("Uninstalling '#{name}' failed."))
new BufferedNodeProcess({command, args, exit})
module.exports = {renderMarkdownInMetadata, install, uninstall, getAvailable}

View File

@@ -1,127 +0,0 @@
$ = require 'jquery'
_ = require 'underscore'
{View, $$} = require 'space-pen'
EventEmitter = require 'event-emitter'
Editor = require 'editor'
PackageView = require './package-view'
packageManager = require './package-manager'
stringScore = require 'stringscore'
### Internal ###
class PackageEventEmitter
_.extend PackageEventEmitter.prototype, EventEmitter
module.exports =
class PackagePanel extends View
@content: ->
@div class: 'package-panel', =>
@legend 'Packages'
@ul class: 'nav nav-tabs', =>
@li class: 'active', =>
@a 'Installed', =>
@span class: 'badge pull-right', outlet: 'installedCount'
@li =>
@a 'Available', =>
@span class: 'badge pull-right', outlet: 'availableCount'
@subview 'packageFilter', new Editor(mini: true, attributes: {id: 'package-filter'})
@div outlet: 'installedPackages'
@div outlet: 'availablePackages'
initialize: ->
@packageEventEmitter = new PackageEventEmitter()
@availablePackages.hide()
@loadInstalledViews()
@loadAvailableViews()
@find('.nav-tabs li').on 'click', (event) =>
return if $(event.currentTarget).hasClass('active')
@find('.nav-tabs li').toggleClass('active')
@availablePackages.toggle()
@installedPackages.toggle()
@packageEventEmitter.on 'package-installed', (error, pack) =>
@addInstalledPackage(pack) unless error?
@packageEventEmitter.on 'package-uninstalled', (error, pack) =>
@removeInstalledPackage(pack) unless error?
@packageFilter.getBuffer().on 'contents-modified', =>
@filterPackages(@packageFilter.getText())
loadInstalledViews: ->
@installedPackages.empty()
@installedPackages.append @createLoadingView('Loading installed packages\u2026')
packages = _.sortBy(atom.getAvailablePackageMetadata(), 'name')
packageManager.renderMarkdownInMetadata packages, =>
@installedPackages.empty()
for pack in packages
view = new PackageView(pack, @packageEventEmitter)
@installedPackages.append(view)
@updateInstalledCount()
loadAvailableViews: ->
@availablePackages.empty()
@availablePackages.append @createLoadingView('Loading available packages\u2026')
packageManager.getAvailable (error, @packages=[]) =>
@availablePackages.empty()
if error?
errorView = @createErrorView('Error fetching available packages.')
errorView.on 'click', => @loadAvailableViews()
@availablePackages.append errorView
console.error(error.stack ? error)
else
for pack in @packages
view = new PackageView(pack, @packageEventEmitter)
@availablePackages.append(view)
@updateAvailableCount()
createLoadingView: (text) ->
$$ ->
@div class: 'alert alert-info loading-area', text
createErrorView: (text) ->
$$ ->
@div class: 'alert alert-error', =>
@span text
@button class: 'btn btn-mini btn-retry', 'Retry'
updateInstalledCount: ->
@installedCount.text(@installedPackages.children().length)
updateAvailableCount: ->
@availableCount.text(@availablePackages.children().length)
removeInstalledPackage: ({name}) ->
@installedPackages.children("[name=#{name}]").remove()
@updateInstalledCount()
addInstalledPackage: (pack) ->
packageNames = [pack.name]
@installedPackages.children().each (index, el) -> packageNames.push(el.getAttribute('name'))
packageNames.sort()
insertAfterIndex = packageNames.indexOf(pack.name) - 1
view = new PackageView(pack, @packageEventEmitter)
if insertAfterIndex < 0
@installedPackages.prepend(view)
else
@installedPackages.children(":eq(#{insertAfterIndex})").after(view)
@updateInstalledCount()
filterPackages: (filterString) ->
for children in [@installedPackages.children(), @availablePackages.children()]
for packageView in children
name = packageView.getAttribute('name')
continue unless name
if /^\s*$/.test(filterString) or stringScore(name, filterString)
$(packageView).show()
else
$(packageView).hide()

View File

@@ -1,187 +0,0 @@
Package = require 'package'
semver = require 'semver'
packageManager = require './package-manager'
_ = require 'underscore'
{$$, View} = require 'space-pen'
requireWithGlobals 'bootstrap/js/bootstrap-dropdown', jQuery: require 'jquery'
### Internal ###
module.exports =
class PackageView extends View
@content: ->
@div class: 'panel', =>
@div outlet: 'heading', class: 'panel-heading', =>
@span outlet: 'name'
@span outlet: 'version', class: 'label'
@span outlet: 'update', class: 'label label-info', 'Update Available'
@span outlet: 'disabedLabel', class: 'label label-warning', 'Disabled'
@div class: 'btn-group pull-right', =>
@button outlet: 'defaultAction', class: 'btn btn-small btn-primary'
@button outlet: 'dropdownButton', class: 'btn btn-small btn-primary dropdown-toggle', 'data-toggle': 'dropdown', =>
@span class: 'caret'
@ul outlet: 'dropdown', class: 'dropdown-menu', =>
@li outlet: 'enableToggle', => @a 'Disable'
@li outlet: 'homepage', => @a 'Visit homepage'
@li outlet: 'issues', => @a 'Report issue'
@div outlet: 'description'
@ul class: 'list-group list-group-flush', =>
@li outlet: 'readmeArea', class: 'list-group-item', =>
@a 'Show README', outlet: 'readmeLink'
@div class: 'readme', outlet: 'readme'
pack: null
metadata: null
installed: false
disabled: false
bundled: false
updateAvailable: false
initialize: (pack, @packageEventEmitter) ->
if pack instanceof Package
@pack = pack
@metadata = @pack.metadata
else
@metadata = pack
@updatePackageState()
@attr('name', @metadata.name)
@name.text(@metadata.name)
if version = semver.valid(@metadata.version)
@version.text(version)
else
@version.hide()
if @metadata.descriptionHtml
@description.html(@metadata.descriptionHtml)
else if @metadata.description
@description.text(@metadata.description)
else
@description.text('No further description available.')
@readme.hide()
if @metadata.readmeHtml
@readme.html(@metadata.readmeHtml)
else if @metadata.readme
@readme.text(@metadata.readme)
else
@readmeArea.hide()
@readmeLink.on 'click', =>
if @readme.isVisible()
@readme.hide()
@readmeLink.text('Show README')
else
@readme.show()
@readmeLink.text('Hide README')
homepage = @metadata.homepage
unless homepage
if _.isString(@metadata.repository)
repoUrl = @metadata.repository
else
repoUrl = @metadata.repository?.url
if repoUrl
repoUrl = repoUrl.replace(/.git$/, '')
homepage = repoUrl if require('url').parse(repoUrl).host is 'github.com'
if homepage
@homepage.find('a').attr('href', homepage)
else
@homepage.hide()
if issues = @metadata.bugs?.url
@issues.find('a').attr('href', issues)
else
@issues.hide()
@defaultAction.on 'click', =>
if @installed and @bundled
@togglePackageEnablement()
return
@defaultAction.disable()
if @installed
if @updateAvailable
@defaultAction.text('Upgrading\u2026')
packageManager.install @metadata, (error) =>
@packageEventEmitter.trigger('package-upgraded', error, @metadata)
else
@defaultAction.text('Uninstalling\u2026')
packageManager.uninstall @metadata, (error) =>
@packageEventEmitter.trigger('package-uninstalled', error, @metadata)
else
@defaultAction.text('Installing\u2026')
packageManager.install @metadata, (error) =>
@packageEventEmitter.trigger('package-installed', error, @metadata)
@updateDefaultAction()
@enableToggle.find('a').on 'click', => @togglePackageEnablement()
@observeConfig 'core.disabledPackages', =>
@updatePackageState()
@updateDefaultAction()
@updateEnabledState()
@packageEventEmitter.on 'package-installed package-uninstalled package-upgraded', (error, metadata) =>
if metadata?.name is @metadata.name
@defaultAction.enable()
@updatePackageState()
@updateDefaultAction()
togglePackageEnablement: ->
if @disabled
config.removeAtKeyPath('core.disabledPackages', @metadata.name)
else
config.pushAtKeyPath('core.disabledPackages', @metadata.name)
updatePackageState: ->
@disabled = atom.isPackageDisabled(@metadata.name)
@updateAvailable = false
@bundled = false
loadedPackage = atom.getLoadedPackage(@metadata.name)
packagePath = loadedPackage?.path ? atom.resolvePackagePath(@metadata.name)
@installed = packagePath?
if @installed
for packageDirPath in config.bundledPackageDirPaths
if packagePath.indexOf("#{packageDirPath}/") is 0
@bundled = true
break
version = loadedPackage?.metadata.version
unless version
try
version = Package.loadMetadata(@metadata.name).version
@updateAvailable = semver.gt(@metadata.version, version)
if @updateAvailable
@update.show()
else
@update.hide()
updateEnabledState: ->
enableLink = @enableToggle.find('a')
if @disabled
enableLink.text('Enable')
@disabedLabel.show()
else
enableLink.text('Disable')
@disabedLabel.hide()
@enableToggle.hide() unless @installed
updateDefaultAction: ->
if @installed
if @bundled
if @disabled
@defaultAction.text('Enable')
else
@defaultAction.text('Disable')
else
if @updateAvailable
@defaultAction.text('Upgrade')
else
@defaultAction.text('Uninstall')
else
@defaultAction.text('Install')

View File

@@ -1,92 +0,0 @@
{$$} = require 'space-pen'
ScrollView = require 'scroll-view'
$ = require 'jquery'
_ = require 'underscore'
Pane = require 'pane'
GeneralPanel = require './general-panel'
ThemePanel = require './theme-panel'
PackagePanel = require './package-panel'
Project = require 'project'
configUri = "atom://config"
###
# Internal #
###
module.exports =
class SettingsView extends ScrollView
registerDeserializer(this)
@activate: (state) ->
Project.registerOpener (filePath) ->
new SettingsView() if filePath is configUri
rootView.command 'settings-view:toggle', ->
rootView.open(configUri)
$(window).on 'window:open-settings', ->
rootView.open(configUri)
@deserialize: ({activePanelName}={}) ->
new SettingsView(activePanelName)
@content: ->
@div id: 'settings-view', tabindex: -1, =>
@div id: 'config-menu', =>
@ul id: 'panels-menu', class: 'nav nav-pills nav-stacked', outlet: 'panelMenu'
@button "Open ~/.atom", id: 'open-dot-atom', class: 'btn btn-default btn-small'
@div id: 'panels', outlet: 'panels'
activePanelName: null
initialize: (activePanelName) ->
super
@panelsByName = {}
@on 'click', '#panels-menu li a', (e) =>
@showPanel($(e.target).closest('li').attr('name'))
@on 'click', '#open-dot-atom', ->
atom.open(config.configDirPath)
@addPanel('General', new GeneralPanel)
@addPanel('Themes', new ThemePanel)
@addPanel('Packages', new PackagePanel)
@showPanel(activePanelName) if activePanelName
serialize: ->
deserializer: 'SettingsView'
activePanelName: @activePanelName
addPanel: (name, panel) ->
panelItem = $$ -> @li name: name, => @a name
@panelMenu.append(panelItem)
panel.hide()
@panelsByName[name] = panel
@panels.append(panel)
@showPanel(name) if @getPanelCount() is 1 or @panelToShow is name
getPanelCount: ->
_.values(@panelsByName).length
showPanel: (name) ->
if @panelsByName[name]
@panels.children().hide()
@panelMenu.children('.active').removeClass('active')
@panelsByName[name].show()
for editorElement in @panelsByName[name].find(".editor")
$(editorElement).view().redraw()
@panelMenu.children("[name='#{name}']").addClass('active')
@activePanelName = name
@panelToShow = null
else
@panelToShow = name
getTitle: ->
"Settings"
getUri: ->
configUri
isEqual: (other) ->
other instanceof SettingsView

View File

@@ -1,72 +0,0 @@
{View, $$} = require 'space-pen'
$ = require 'jquery'
_ = require 'underscore'
###
# Internal #
###
window.jQuery = $
require 'jqueryui-browser/ui/jquery.ui.core'
require 'jqueryui-browser/ui/jquery.ui.widget'
require 'jqueryui-browser/ui/jquery.ui.mouse'
require 'jqueryui-browser/ui/jquery.ui.sortable'
require 'jqueryui-browser/ui/jquery.ui.draggable'
delete window.jQuery
module.exports =
class ThemeConfigPanel extends View
@content: ->
@div id: 'themes-config', =>
@legend "Themes"
@div id: 'theme-picker', =>
@div class: 'panel', =>
@div class: 'panel-heading', "Enabled Themes"
@ol id: 'enabled-themes', class: 'list-group list-group-flush', outlet: 'enabledThemes'
@div class: 'panel', =>
@div class: 'panel-heading', "Available Themes"
@ol id: 'available-themes', class: 'list-group list-group-flush', outlet: 'availableThemes'
constructor: ->
super
for name in atom.themes.getAvailableNames()
@availableThemes.append(@buildThemeLi(name, draggable: true))
@observeConfig "core.themes", (enabledThemes) =>
@enabledThemes.empty()
for name in enabledThemes ? []
@enabledThemes.append(@buildThemeLi(name))
@enabledThemes.sortable
receive: (e, ui) => @enabledThemeReceived($(ui.helper))
update: => @enabledThemesUpdated()
@on "click", "#enabled-themes .disable-theme", (e) =>
$(e.target).closest('li').remove()
@enabledThemesUpdated()
buildThemeLi: (name, {draggable} = {}) ->
li = $$ ->
@li class: 'list-group-item', name: name, =>
@div class: 'disable-theme pull-right'
@text name
if draggable
li.draggable
connectToSortable: '#enabled-themes'
appendTo: '#themes-config'
helper: (e) ->
target = $(e.target)
target.clone().width(target.width())
else
li
enabledThemeReceived: (helper) ->
name = helper.attr('name')
@enabledThemes.find("[name='#{name}']:not('.ui-draggable')").remove()
@enabledThemes.find(".ui-draggable").removeClass('ui-draggable')
enabledThemesUpdated: ->
config.set('core.themes', @getEnabledThemeNames())
getEnabledThemeNames: ->
$(li).attr('name') for li in @enabledThemes.children().toArray()

View File

@@ -1,3 +0,0 @@
'main': './lib/settings-view'
'deferredDeserializers': ['SettingsView']
'description': 'GUI pane for Atom settings'

View File

@@ -1,153 +0,0 @@
PackagePanel = require '../lib/package-panel'
packageManager = require '../lib/package-manager'
_ = require 'underscore'
describe "PackagePanel", ->
[panel, configObserver] = []
beforeEach ->
installedPackages = [
{
name: 'p1'
version: '3.2.1'
}
{
name: 'p2'
version: '1.2.3'
}
{
name: 'p3'
version: '5.8.5'
}
]
availablePackages = [
{
name: 'p4'
version: '3.2.1'
homepage: 'http://p4.io'
}
{
name: 'p5'
version: '1.2.3'
repository: url: 'http://github.com/atom/p5.git'
bugs: url: 'http://github.com/atom/p5/issues'
}
{
name: 'p6'
version: '5.8.5'
}
]
spyOn(packageManager, 'getAvailable').andCallFake (callback) ->
callback(null, availablePackages)
spyOn(packageManager, 'uninstall').andCallFake (pack, callback) ->
_.remove(installedPackages, pack)
callback()
spyOn(packageManager, 'install').andCallFake (pack, callback) ->
installedPackages.push(pack)
callback()
spyOn(atom, 'getAvailablePackageMetadata').andReturn(installedPackages)
spyOn(atom, 'resolvePackagePath').andCallFake (name) ->
if _.contains(_.pluck(installedPackages, 'name'), name)
"/tmp/atom-packages/#{name}"
configObserver = jasmine.createSpy("configObserver")
observeSubscription = config.observe('core.disabledPackages', configObserver)
config.set('core.disabledPackages', ['p1', 'p3'])
configObserver.reset()
jasmine.unspy(window, "setTimeout")
panel = new PackagePanel
waitsFor ->
panel.installedPackages.children().length == 3
describe 'Installed tab', ->
it "lists all installed packages with a link to enable or disable the package", ->
p1View = panel.installedPackages.find("[name='p1']").view()
expect(p1View).toExist()
expect(p1View.enableToggle.find('a').text()).toBe 'Enable'
p2View = panel.installedPackages.find("[name='p2']").view()
expect(p2View).toExist()
expect(p2View.enableToggle.find('a').text()).toBe 'Disable'
p3View = panel.installedPackages.find("[name='p3']").view()
expect(p3View).toExist()
expect(p3View.enableToggle.find('a').text()).toBe 'Enable'
describe "when the core.disabledPackages array changes", ->
it "updates the checkboxes for newly disabled / enabled packages", ->
config.set('core.disabledPackages', ['p2'])
p1View = panel.installedPackages.find("[name='p1']").view()
expect(p1View.enableToggle.find('a').text()).toBe 'Disable'
p2View = panel.installedPackages.find("[name='p2']").view()
expect(p2View.enableToggle.find('a').text()).toBe 'Enable'
p3View = panel.installedPackages.find("[name='p3']").view()
expect(p3View.enableToggle.find('a').text()).toBe 'Disable'
describe "when the disable link is clicked", ->
it "adds the package name to the disabled packages array", ->
p2View = panel.installedPackages.find("[name='p2']").view()
p2View.enableToggle.find('a').click()
expect(configObserver).toHaveBeenCalledWith(['p1', 'p3', 'p2'])
describe "when the enable link is clicked", ->
it "removes the package name from the disabled packages array", ->
p3View = panel.installedPackages.find("[name='p3']").view()
p3View.enableToggle.find('a').click()
expect(configObserver).toHaveBeenCalledWith(['p1'])
describe "when Uninstall is clicked", ->
it "removes the package from the tab", ->
expect(panel.installedPackages.find("[name='p1']")).toExist()
p1View = panel.installedPackages.find("[name='p1']").view()
expect(p1View.defaultAction.text()).toBe 'Uninstall'
p1View.defaultAction.click()
expect(panel.installedPackages.find("[name='p1']")).not.toExist()
describe 'Available tab', ->
it 'lists all available packages', ->
panel.find("li a:contains(Available)").click()
panel.attachToDom()
expect(panel.availablePackages.children('.panel').length).toBe 3
p4View = panel.availablePackages.children('.panel:eq(0)').view()
p5View = panel.availablePackages.children('.panel:eq(1)').view()
p6View = panel.availablePackages.children('.panel:eq(2)').view()
expect(p4View.name.text()).toBe 'p4'
expect(p5View.name.text()).toBe 'p5'
expect(p6View.name.text()).toBe 'p6'
expect(p4View.version.text()).toBe '3.2.1'
expect(p5View.version.text()).toBe '1.2.3'
expect(p6View.version.text()).toBe '5.8.5'
p4View.dropdownButton.click()
expect(p4View.homepage).toBeVisible()
expect(p4View.homepage.find('a').attr('href')).toBe 'http://p4.io'
expect(p4View.issues).toBeHidden()
p5View.dropdownButton.click()
expect(p5View.homepage).toBeVisible()
expect(p5View.homepage.find('a').attr('href')).toBe 'http://github.com/atom/p5'
expect(p5View.issues).toBeVisible()
expect(p5View.issues.find('a').attr('href')).toBe 'http://github.com/atom/p5/issues'
p6View.dropdownButton.click()
expect(p6View.homepage).toBeHidden()
expect(p6View.issues).toBeHidden()
describe "when Install is clicked", ->
it "adds the package to the Installed tab", ->
expect(panel.installedPackages.find("[name='p4']")).not.toExist()
expect(panel.availablePackages.find("[name='p4']")).toExist()
p4View = panel.availablePackages.find("[name='p4']").view()
expect(p4View.defaultAction.text()).toBe 'Install'
p4View.defaultAction.click()
expect(panel.installedPackages.find("[name='p4']")).toExist()
expect(p4View.defaultAction.text()).toBe 'Uninstall'

View File

@@ -1,80 +0,0 @@
GeneralPanel = require '../lib/general-panel'
Editor = require 'editor'
describe "GeneralPanel", ->
panel = null
getValueForId = (id) ->
element = panel.find("##{id.replace('.', '\\.')}")
if element.is("input")
element.attr('checked')?
else
element.view().getText()
setValueForId = (id, value) ->
element = panel.find("##{id.replace('.', '\\.')}")
if element.is("input")
element.attr('checked', if value then 'checked' else '')
element.change()
else
element.view().setText(value?.toString())
window.advanceClock(10000) # wait for contents-modified to be triggered
beforeEach ->
config.set('foo.int', 22)
config.set('foo.float', 0.1)
config.set('foo.boolean', true)
config.set('foo.string', 'hey')
panel = new GeneralPanel()
spyOn(panel, "showSettings").andCallThrough()
window.advanceClock(10000)
waitsFor ->
panel.showSettings.callCount > 0
it "automatically binds named fields to their corresponding config keys", ->
expect(getValueForId('foo.int')).toBe '22'
expect(getValueForId('foo.float')).toBe '0.1'
expect(getValueForId('foo.boolean')).toBeTruthy()
expect(getValueForId('foo.string')).toBe 'hey'
config.set('foo.int', 222)
config.set('foo.float', 0.11)
config.set('foo.boolean', false)
config.set('foo.string', 'hey again')
expect(getValueForId('foo.int')).toBe '222'
expect(getValueForId('foo.float')).toBe '0.11'
expect(getValueForId('foo.boolean')).toBeFalsy()
expect(getValueForId('foo.string')).toBe 'hey again'
setValueForId('foo.int', 90)
setValueForId('foo.float', 89.2)
setValueForId('foo.string', "oh hi")
setValueForId('foo.boolean', true)
expect(config.get('foo.int')).toBe 90
expect(config.get('foo.float')).toBe 89.2
expect(config.get('foo.boolean')).toBe true
expect(config.get('foo.string')).toBe 'oh hi'
setValueForId('foo.int', '')
setValueForId('foo.float', '')
setValueForId('foo.string', '')
expect(config.get('foo.int')).toBeUndefined()
expect(config.get('foo.float')).toBeUndefined()
expect(config.get('foo.string')).toBeUndefined()
it "does not save the config value until it has been changed to a new value", ->
observeHandler = jasmine.createSpy("observeHandler")
config.observe "foo.int", observeHandler
observeHandler.reset()
window.advanceClock(10000) # wait for contents-modified to be triggered
expect(observeHandler).not.toHaveBeenCalled()
setValueForId('foo.int', 2)
expect(observeHandler).toHaveBeenCalled()
observeHandler.reset()
setValueForId('foo.int', 2)
expect(observeHandler).not.toHaveBeenCalled()

View File

@@ -1,46 +0,0 @@
SettingsView = require '../lib/settings-view'
{$$} = require 'space-pen'
describe "SettingsView", ->
settingsView = null
beforeEach ->
settingsView = new SettingsView
describe "serialization", ->
it "remembers which panel was visible", ->
settingsView.showPanel('Packages')
newSettingsView = deserialize(settingsView.serialize())
settingsView.remove()
newSettingsView.attachToDom()
expect(newSettingsView.activePanelName).toBe 'Packages'
it "shows the previously active panel if it is added after deserialization", ->
settingsView.addPanel('Panel 1', $$ -> @div id: 'panel-1')
settingsView.showPanel('Panel 1')
newSettingsView = deserialize(settingsView.serialize())
settingsView.remove()
newSettingsView.attachToDom()
newSettingsView.addPanel('Panel 1', $$ -> @div id: 'panel-1')
expect(newSettingsView.activePanelName).toBe 'Panel 1'
describe ".addPanel(name, view)", ->
it "adds a menu entry to the left and a panel that can be activated by clicking it", ->
settingsView.addPanel('Panel 1', $$ -> @div id: 'panel-1')
settingsView.addPanel('Panel 2', $$ -> @div id: 'panel-2')
expect(settingsView.panelMenu.find('li a:contains(Panel 1)')).toExist()
expect(settingsView.panelMenu.find('li a:contains(Panel 2)')).toExist()
expect(settingsView.panelMenu.children(':first')).toHaveClass 'active'
settingsView.attachToDom()
settingsView.panelMenu.find('li a:contains(Panel 1)').click()
expect(settingsView.panelMenu.children('.active').length).toBe 1
expect(settingsView.panelMenu.find('li:contains(Panel 1)')).toHaveClass('active')
expect(settingsView.panels.find('#panel-1')).toBeVisible()
expect(settingsView.panels.find('#panel-2')).toBeHidden()
settingsView.panelMenu.find('li a:contains(Panel 2)').click()
expect(settingsView.panelMenu.children('.active').length).toBe 1
expect(settingsView.panelMenu.find('li:contains(Panel 2)')).toHaveClass('active')
expect(settingsView.panels.find('#panel-1')).toBeHidden()
expect(settingsView.panels.find('#panel-2')).toBeVisible()

View File

@@ -1,49 +0,0 @@
$ = require 'jquery'
ThemePanel = require '../lib/theme-panel'
describe "ThemePanel", ->
panel = null
beforeEach ->
config.set('core.themes', ['atom-dark-ui', 'atom-dark-syntax'])
panel = new ThemePanel
describe "when an enabled theme is reloced in the themes list", ->
it "updates the 'core.themes' config key to reflect the new order", ->
li = panel.enabledThemes.children(':first').detach()
panel.enabledThemes.append(li)
panel.enabledThemes.sortable('option', 'update')()
expect(config.get('core.themes')).toEqual ['atom-dark-syntax', 'atom-dark-ui']
describe "when a theme is dragged into the enabled themes list", ->
it "updates the 'core.themes' config key to reflect the themes in the enabled list", ->
dragHelper = panel.availableThemes.find("li[name='atom-light-ui']").clone()
panel.enabledThemes.prepend(dragHelper)
panel.enabledThemes.sortable('option', 'receive')(null, helper: dragHelper[0])
panel.enabledThemes.sortable('option', 'update')()
expect(config.get('core.themes')).toEqual ['atom-light-ui', 'atom-dark-ui', 'atom-dark-syntax']
describe "when the theme is already present in the enabled list", ->
it "removes the previous instance of the theme, updating the order based on the location of drag", ->
dragHelper = panel.availableThemes.find("li[name='atom-dark-ui']").clone()
panel.enabledThemes.append(dragHelper)
panel.enabledThemes.sortable('option', 'receive')(null, helper: dragHelper[0])
panel.enabledThemes.sortable('option', 'update')()
expect(config.get('core.themes')).toEqual ['atom-dark-syntax', 'atom-dark-ui']
dragHelper = panel.availableThemes.find("li[name='atom-dark-ui']").clone()
panel.enabledThemes.prepend(dragHelper)
panel.enabledThemes.sortable('option', 'receive')(null, helper: dragHelper[0])
panel.enabledThemes.sortable('option', 'update')()
expect(config.get('core.themes')).toEqual ['atom-dark-ui', 'atom-dark-syntax']
describe "when the disable icon is clicked on a theme li", ->
it "removes the theme from the list and the 'core.themes' array", ->
panel.enabledThemes.find('li:first .disable-theme').click()
expect(panel.getEnabledThemeNames()).toEqual ['atom-dark-syntax']
expect(config.get('core.themes')).toEqual ['atom-dark-syntax']
describe "when the 'core.config' key is updated", ->
it "refreshes the enabled themes list", ->
config.set('core.themes', ['atom-light-ui', 'atom-light-syntax'])
expect(panel.getEnabledThemeNames()).toEqual ['atom-light-ui', 'atom-light-syntax']

View File

@@ -1,151 +0,0 @@
@import "bootstrap/less/variables.less";
@import "octicon-mixins.less";
#settings-view {
background: white;
display: -webkit-flex;
#config-menu {
display: -webkit-flex;
-webkit-flex-direction: column;
#panels-menu {
width: 150px;
margin-left: @line-height-base;
margin-top: @line-height-base;
-webkit-flex-grow: 1;
li a {
cursor: pointer;
}
}
#open-dot-atom {
width: 150px;
margin-left: @line-height-base;
margin-bottom: @line-height-base;
}
}
#panels {
-webkit-flex: 1;
-webkit-flex-flow: column;
display: -webkit-flex;
padding: @line-height-base;
position: relative;
overflow-y: auto;
> div {
-webkit-flex: 1;
}
.editor {
padding-left: 0.25em;
border: 1px solid #aaa;
box-shadow: 1px 1px 1px 0 #888 inset;
}
}
#themes-config {
height: 100%;
display: -webkit-flex;
-webkit-flex-flow: column;
#theme-picker {
-webkit-flex: 1;
display: -webkit-flex;
min-height: 0;
.panel {
-webkit-flex: 1;
display: -webkit-flex;
-webkit-flex-flow: column;
min-height: 0;
&:first-child { margin-right: @line-height-base / 2; }
&:last-child { margin-left: @line-height-base / 2; }
.panel-heading {
margin-bottom: 0;
}
ol {
margin-top: 0;
-webkit-flex: 1;
min-height: 0;
overflow: auto;
li {
-webkit-user-select: none;
cursor: default;
padding-right: 15px;
&:first-child { border-top: 0; }
}
}
#enabled-themes {
li:hover .disable-theme {
.octicon(x);
color: #888;
cursor: pointer;
&:hover { color: #000; }
}
}
}
}
li.ui-draggable-dragging, li.ui-sortable-helper {
border: 0;
box-sizing: content-box;
background: white;
border-radius: 0;
box-shadow: 0 0 5px rgba(0, 0, 0, .5);
}
}
#packages {
white-space: nowrap;
.package-enabled {
width: 30px;
text-align: center;
}
}
#package-filter {
margin: 1em 0;
}
.btn-retry {
margin-left: 10px;
}
.readme {
margin-top: 10px;
}
.panel-heading .label {
margin-left: 10px;
}
.loading-area {
span {
.octicon(hourglass);
&:before {
font-size: 1.1em;
width: 1.1em;
height: 1.1em;
margin-right: 5px;
}
}
}
.package-panel {
.nav {
margin-bottom: 10px;
.badge {
margin-left: 5px;
}
}
}
}