/ src / styles-element.coffee
styles-element.coffee
 1  {Emitter, CompositeDisposable} = require 'event-kit'
 2  
 3  class StylesElement extends HTMLElement
 4    subscriptions: null
 5    context: null
 6  
 7    onDidAddStyleElement: (callback) ->
 8      @emitter.on 'did-add-style-element', callback
 9  
10    onDidRemoveStyleElement: (callback) ->
11      @emitter.on 'did-remove-style-element', callback
12  
13    onDidUpdateStyleElement: (callback) ->
14      @emitter.on 'did-update-style-element', callback
15  
16    createdCallback: ->
17      @subscriptions = new CompositeDisposable
18      @emitter = new Emitter
19      @styleElementClonesByOriginalElement = new WeakMap
20  
21    attachedCallback: ->
22      @context = @getAttribute('context') ? undefined
23  
24    detachedCallback: ->
25      @subscriptions.dispose()
26      @subscriptions = new CompositeDisposable
27  
28    attributeChangedCallback: (attrName, oldVal, newVal) ->
29      @contextChanged() if attrName is 'context'
30  
31    initialize: (@styleManager) ->
32      throw new Error("Must pass a styleManager parameter when initializing a StylesElement") unless @styleManager?
33  
34      @subscriptions.add @styleManager.observeStyleElements(@styleElementAdded.bind(this))
35      @subscriptions.add @styleManager.onDidRemoveStyleElement(@styleElementRemoved.bind(this))
36      @subscriptions.add @styleManager.onDidUpdateStyleElement(@styleElementUpdated.bind(this))
37  
38    contextChanged: ->
39      return unless @subscriptions?
40  
41      @styleElementRemoved(child) for child in Array::slice.call(@children)
42      @context = @getAttribute('context')
43      @styleElementAdded(styleElement) for styleElement in @styleManager.getStyleElements()
44      return
45  
46    styleElementAdded: (styleElement) ->
47      return unless @styleElementMatchesContext(styleElement)
48  
49      styleElementClone = styleElement.cloneNode(true)
50      styleElementClone.sourcePath = styleElement.sourcePath
51      styleElementClone.context = styleElement.context
52      styleElementClone.priority = styleElement.priority
53      @styleElementClonesByOriginalElement.set(styleElement, styleElementClone)
54  
55      priority = styleElement.priority
56      if priority?
57        for child in @children
58          if child.priority > priority
59            insertBefore = child
60            break
61  
62      @insertBefore(styleElementClone, insertBefore)
63      @emitter.emit 'did-add-style-element', styleElementClone
64  
65    styleElementRemoved: (styleElement) ->
66      return unless @styleElementMatchesContext(styleElement)
67  
68      styleElementClone = @styleElementClonesByOriginalElement.get(styleElement) ? styleElement
69      styleElementClone.remove()
70      @emitter.emit 'did-remove-style-element', styleElementClone
71  
72    styleElementUpdated: (styleElement) ->
73      return unless @styleElementMatchesContext(styleElement)
74  
75      styleElementClone = @styleElementClonesByOriginalElement.get(styleElement)
76      styleElementClone.textContent = styleElement.textContent
77      @emitter.emit 'did-update-style-element', styleElementClone
78  
79    styleElementMatchesContext: (styleElement) ->
80      not @context? or styleElement.context is @context
81  
82  module.exports = StylesElement = document.registerElement 'atom-styles', prototype: StylesElement.prototype