From 79598aaae9481da505458ac64eb5891652367db8 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Mon, 13 Oct 2014 17:31:58 -0600 Subject: [PATCH] Add StyleElement This will be used to handle stylesheet rendering when we move management of loading stylesheets to the StyleManager instead of the theme manager. This sets us up for being able to render specific stylesheets in shadow roots in addition to just having global stylesheets. --- spec/spec-helper.coffee | 1 + spec/styles-element-spec.coffee | 35 +++++++++++++++++++++++++++++++++ src/atom.coffee | 2 ++ src/style-manager.coffee | 4 ++++ src/styles-element.coffee | 30 ++++++++++++++++++++++++++++ 5 files changed, 72 insertions(+) create mode 100644 spec/styles-element-spec.coffee create mode 100644 src/styles-element.coffee diff --git a/spec/spec-helper.coffee b/spec/spec-helper.coffee index 0396f4673..d428e9fe1 100644 --- a/spec/spec-helper.coffee +++ b/spec/spec-helper.coffee @@ -74,6 +74,7 @@ beforeEach -> atom.workspace = new Workspace() atom.keymaps.keyBindings = _.clone(keyBindingsToRestore) atom.commands.restoreSnapshot(commandsToRestore) + atom.styles.clear() window.resetTimeouts() atom.packages.packageStates = {} diff --git a/spec/styles-element-spec.coffee b/spec/styles-element-spec.coffee new file mode 100644 index 000000000..eaed6ebd8 --- /dev/null +++ b/spec/styles-element-spec.coffee @@ -0,0 +1,35 @@ +StylesElement = require '../src/styles-element' +StyleManager = require '../src/style-manager' + +describe "StylesElement", -> + element = null + + beforeEach -> + element = new StylesElement + document.querySelector('#jasmine-content').appendChild(element) + + it "renders a style tag for all currently active stylesheets in the style manager", -> + expect(element.children.length).toBe 0 + + disposable1 = atom.styles.addStyleSheet("a {color: red;}") + expect(element.children.length).toBe 1 + expect(element.children[0].textContent).toBe "a {color: red;}" + + disposable2 = atom.styles.addStyleSheet("a {color: blue;}") + expect(element.children.length).toBe 2 + expect(element.children[1].textContent).toBe "a {color: blue;}" + + disposable1.dispose() + expect(element.children.length).toBe 1 + expect(element.children[0].textContent).toBe "a {color: blue;}" + + it "orders style elements by group", -> + expect(element.children.length).toBe 0 + + atom.styles.addStyleSheet("a {color: red}", group: 'a') + atom.styles.addStyleSheet("a {color: blue}", group: 'b') + atom.styles.addStyleSheet("a {color: green}", group: 'a') + + expect(element.children[0].textContent).toBe "a {color: red}" + expect(element.children[1].textContent).toBe "a {color: green}" + expect(element.children[2].textContent).toBe "a {color: blue}" diff --git a/src/atom.coffee b/src/atom.coffee index a18cafe4d..6db0e59de 100644 --- a/src/atom.coffee +++ b/src/atom.coffee @@ -182,6 +182,7 @@ class Atom extends Model Clipboard = require './clipboard' Syntax = require './syntax' ThemeManager = require './theme-manager' + StyleManager = require './style-manager' ContextMenuManager = require './context-menu-manager' MenuManager = require './menu-manager' {devMode, safeMode, resourcePath} = @getLoadSettings() @@ -202,6 +203,7 @@ class Atom extends Model @commands = new CommandRegistry @packages = new PackageManager({devMode, configDirPath, resourcePath, safeMode}) @themes = new ThemeManager({packageManager: @packages, configDirPath, resourcePath, safeMode}) + @styles = new StyleManager({resourcePath}) @contextMenu = new ContextMenuManager({resourcePath, devMode}) @menu = new MenuManager({resourcePath}) @clipboard = new Clipboard() diff --git a/src/style-manager.coffee b/src/style-manager.coffee index 7099d9b2a..a451d72ed 100644 --- a/src/style-manager.coffee +++ b/src/style-manager.coffee @@ -61,3 +61,7 @@ class StyleManager sourcePath = params?.sourcePath delete @styleElementsBySourcePath[sourcePath] if sourcePath? @emitter.emit 'did-remove-style-element', styleElement + + clear: -> + @styleElements = [] + @styleElementsBySourcePath = {} diff --git a/src/styles-element.coffee b/src/styles-element.coffee new file mode 100644 index 000000000..522e6bfc0 --- /dev/null +++ b/src/styles-element.coffee @@ -0,0 +1,30 @@ +{CompositeDisposable} = require 'event-kit' + +class StylesElement extends HTMLElement + attachedCallback: -> + @subscriptions = new CompositeDisposable + @styleElementClonesByOriginalElement = new WeakMap + @subscriptions.add atom.styles.observeStyleElements(@styleElementAdded.bind(this)) + @subscriptions.add atom.styles.onDidRemoveStyleElement(@styleElementRemoved.bind(this)) + + styleElementAdded: (styleElement) -> + {group} = styleElement + styleElementClone = styleElement.cloneNode(true) + styleElementClone.group = group + @styleElementClonesByOriginalElement.set(styleElement, styleElementClone) + + if group? + for child in @children + if child.group is group and child.nextSibling?.group isnt group + insertBefore = child.nextSibling + break + + @insertBefore(styleElementClone, insertBefore) + + styleElementRemoved: (styleElement) -> + @styleElementClonesByOriginalElement.get(styleElement).remove() + + detachedCallback: -> + @subscriptions.dispose() + +module.exports = StylesElement = document.registerElement 'atom-styles', prototype: StylesElement.prototype