From 2698925d10c0228aef5d41ce46ce3bc395f44f64 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Wed, 7 Aug 2013 10:40:46 -0700 Subject: [PATCH] Reload stylesheets when core.themes config changes Extracted a new ThemeManager class to encapsulate all the theme work previously done directly in atom global. Closes #642 --- spec/app/theme-manager-spec.coffee | 25 +++++++++++ src/app/atom.coffee | 32 +------------- src/app/theme-manager.coffee | 43 +++++++++++++++++++ src/app/theme.coffee | 12 +++--- src/app/window.coffee | 2 +- .../settings-view/lib/theme-panel.coffee | 2 +- 6 files changed, 78 insertions(+), 38 deletions(-) create mode 100644 spec/app/theme-manager-spec.coffee create mode 100644 src/app/theme-manager.coffee diff --git a/spec/app/theme-manager-spec.coffee b/spec/app/theme-manager-spec.coffee new file mode 100644 index 000000000..7e2d9116d --- /dev/null +++ b/spec/app/theme-manager-spec.coffee @@ -0,0 +1,25 @@ +$ = require 'jquery' + +Theme = require 'theme' +ThemeManager = require 'theme-manager' + +describe "ThemeManager", -> + describe "when the core.themes config value changes", -> + it "add/removes stylesheets to reflect the new config value", -> + themeManager = new ThemeManager() + spyOn(themeManager, 'getUserStylesheetPath').andCallFake -> null + themeManager.load() + config.set('core.themes', []) + expect($('style.userTheme').length).toBe 0 + + config.set('core.themes', ['atom-dark-syntax']) + expect($('style.userTheme').length).toBe 1 + expect($('style.userTheme:eq(0)').attr('id')).toBe Theme.resolve('atom-dark-syntax') + + config.set('core.themes', ['atom-light-syntax', 'atom-dark-syntax']) + expect($('style.userTheme').length).toBe 2 + expect($('style.userTheme:eq(0)').attr('id')).toBe Theme.resolve('atom-light-syntax') + expect($('style.userTheme:eq(1)').attr('id')).toBe Theme.resolve('atom-dark-syntax') + + config.set('core.themes', []) + expect($('style.userTheme').length).toBe 0 diff --git a/src/app/atom.coffee b/src/app/atom.coffee index e7903b868..7aa4b3cf4 100644 --- a/src/app/atom.coffee +++ b/src/app/atom.coffee @@ -2,19 +2,19 @@ fsUtils = require 'fs-utils' $ = require 'jquery' _ = require 'underscore' Package = require 'package' -Theme = require 'theme' ipc = require 'ipc' remote = require 'remote' crypto = require 'crypto' path = require 'path' dialog = remote.require 'dialog' telepath = require 'telepath' +ThemeManager = require 'theme-manager' window.atom = - loadedThemes: [] loadedPackages: {} activePackages: {} packageStates: {} + themes: new ThemeManager() getLoadSettings: -> remote.getCurrentWindow().loadSettings @@ -126,34 +126,6 @@ window.atom = packages.push(metadata) packages - loadThemes: -> - themeNames = config.get("core.themes") - themeNames = [themeNames] unless _.isArray(themeNames) - @loadTheme(themeName) for themeName in themeNames - @loadUserStylesheet() - - getAvailableThemePaths: -> - themePaths = [] - for themeDirPath in config.themeDirPaths - themePaths.push(fsUtils.listSync(themeDirPath, ['', '.tmTheme', '.css', 'less'])...) - _.uniq(themePaths) - - getAvailableThemeNames: -> - path.basename(themePath).split('.')[0] for themePath in @getAvailableThemePaths() - - loadTheme: (name) -> - @loadedThemes.push Theme.load(name) - - loadUserStylesheet: -> - userStylesheetPath = fsUtils.resolve(path.join(config.configDirPath, 'user'), ['css', 'less']) - if fsUtils.isFileSync(userStylesheetPath) - userStyleesheetContents = loadStylesheet(userStylesheetPath) - applyStylesheet(userStylesheetPath, userStyleesheetContents, 'userTheme') - - getAtomThemeStylesheets: -> - themeNames = config.get("core.themes") ? ['atom-dark-ui', 'atom-dark-syntax'] - themeNames = [themeNames] unless _.isArray(themeNames) - open: (url...) -> ipc.sendChannel('open', [url...]) diff --git a/src/app/theme-manager.coffee b/src/app/theme-manager.coffee new file mode 100644 index 000000000..7ae4eae42 --- /dev/null +++ b/src/app/theme-manager.coffee @@ -0,0 +1,43 @@ +path = require 'path' + +_ = require 'underscore' + +fsUtils = require 'fs-utils' +Theme = require 'theme' + +module.exports = +class ThemeManager + constructor: -> + @loadedThemes = [] + + getAvailablePaths: -> + themePaths = [] + for themeDirPath in config.themeDirPaths + themePaths.push(fsUtils.listSync(themeDirPath, ['', '.tmTheme', '.css', 'less'])...) + _.uniq(themePaths) + + getAvailableNames: -> + path.basename(themePath).split('.')[0] for themePath in @getAvailablePaths() + + load: -> + config.observe 'core.themes', (themeNames) => + removeStylesheet(@userStylesheetPath) if @userStylesheetPath? + theme.deactivate() while theme = @loadedThemes.pop() + themeNames = [themeNames] unless _.isArray(themeNames) + @loadTheme(themeName) for themeName in themeNames + @loadUserStylesheet() + + loadTheme: (name) -> @loadedThemes.push(Theme.load(name)) + + getUserStylesheetPath: -> + stylesheetPath = fsUtils.resolve(path.join(config.configDirPath, 'user'), ['css', 'less']) + if fsUtils.isFileSync(stylesheetPath) + stylesheetPath + else + null + + loadUserStylesheet: -> + if userStylesheetPath = @getUserStylesheetPath() + @userStylesheetPath = userStylesheetPath + userStylesheetContents = loadStylesheet(userStylesheetPath) + applyStylesheet(userStylesheetPath, userStylesheetContents, 'userTheme') diff --git a/src/app/theme.coffee b/src/app/theme.coffee index b7aea0119..1b55ff390 100644 --- a/src/app/theme.coffee +++ b/src/app/theme.coffee @@ -4,17 +4,17 @@ fsUtils = require 'fs-utils' module.exports = class Theme - @stylesheets: null + @resolve: (name) -> + if fsUtils.exists(name) + name + else + fsUtils.resolve(config.themeDirPaths..., name, ['', '.tmTheme', '.css', 'less']) @load: (name) -> TextMateTheme = require 'text-mate-theme' AtomTheme = require 'atom-theme' - if fsUtils.exists(name) - path = name - else - path = fsUtils.resolve(config.themeDirPaths..., name, ['', '.tmTheme', '.css', 'less']) - + path = Theme.resolve(name) throw new Error("No theme exists named '#{name}'") unless path theme = diff --git a/src/app/window.coffee b/src/app/window.coffee index e38b123e7..ba6c66f0d 100644 --- a/src/app/window.coffee +++ b/src/app/window.coffee @@ -50,7 +50,7 @@ window.startEditorWindow = -> restoreDimensions() config.load() keymap.loadBundledKeymaps() - atom.loadThemes() + atom.themes.load() atom.loadPackages() deserializeEditorWindow() atom.activatePackages() diff --git a/src/packages/settings-view/lib/theme-panel.coffee b/src/packages/settings-view/lib/theme-panel.coffee index 0e992025a..34091c4c4 100644 --- a/src/packages/settings-view/lib/theme-panel.coffee +++ b/src/packages/settings-view/lib/theme-panel.coffee @@ -29,7 +29,7 @@ class ThemeConfigPanel extends View constructor: -> super - for name in atom.getAvailableThemeNames() + for name in atom.themes.getAvailableNames() @availableThemes.append(@buildThemeLi(name, draggable: true)) @observeConfig "core.themes", (enabledThemes) =>