Transform deprecated shadow DOM selectors in StyleManager

This commit is contained in:
Antonio Scandurra
2016-10-04 11:22:41 +02:00
parent 92a3c2f4b2
commit 80fc448b8d
8 changed files with 133 additions and 152 deletions

View File

@@ -1,9 +1,4 @@
{Emitter, CompositeDisposable} = require 'event-kit'
selectorProcessor = require 'postcss-selector-parser'
SPATIAL_DECORATIONS = new Set([
'invisible-character', 'hard-tab', 'leading-whitespace',
'trailing-whitespace', 'eol', 'indent-guide', 'fold-marker'
])
class StylesElement extends HTMLElement
subscriptions: null
@@ -24,9 +19,6 @@ class StylesElement extends HTMLElement
@styleElementClonesByOriginalElement = new WeakMap
attachedCallback: ->
for styleElement in @children
@upgradeDeprecatedSelectors(styleElement)
@context = @getAttribute('context') ? undefined
detachedCallback: ->
@@ -68,7 +60,6 @@ class StylesElement extends HTMLElement
break
@insertBefore(styleElementClone, insertBefore)
@upgradeDeprecatedSelectors(styleElementClone)
@emitter.emit 'did-add-style-element', styleElementClone
styleElementRemoved: (styleElement) ->
@@ -88,52 +79,4 @@ class StylesElement extends HTMLElement
styleElementMatchesContext: (styleElement) ->
not @context? or styleElement.context is @context
upgradeDeprecatedSelectors: (styleElement) ->
return unless styleElement.sheet?
transformDeprecatedShadowSelectors = (selectors) ->
selectors.each (selector) ->
isSyntaxSelector = not selector.some((node) ->
(node.type is 'tag' and node.value is 'atom-text-editor') or
(node.type is 'class' and node.value is 'region') or
(node.type is 'class' and node.value is 'wrap-guide') or
(node.type is 'class' and /spell-check/.test(node.value))
)
previousNode = null
selector.each (node) ->
isShadowPseudoClass = node.type is 'pseudo' and node.value is '::shadow'
isHostPseudoClass = node.type is 'pseudo' and node.value is ':host'
if isHostPseudoClass and not previousNode?
newNode = selectorProcessor.tag({value: 'atom-text-editor'})
node.replaceWith(newNode)
previousNode = newNode
else if isShadowPseudoClass and previousNode?.type is 'tag' and previousNode?.value is 'atom-text-editor'
selector.removeChild(node)
else
if styleElement.context is 'atom-text-editor' and node.type is 'class'
if (isSyntaxSelector and not node.value.startsWith('syntax--')) or SPATIAL_DECORATIONS.has(node.value)
node.value = 'syntax--' + node.value
previousNode = node
upgradedSelectors = []
for rule in styleElement.sheet.cssRules when rule.selectorText?
inputSelector = rule.selectorText
outputSelector = rule.selectorText
outputSelector = selectorProcessor(transformDeprecatedShadowSelectors).process(outputSelector).result
if inputSelector isnt outputSelector
rule.selectorText = outputSelector
upgradedSelectors.push({inputSelector, outputSelector})
if upgradedSelectors.length > 0
upgradedSelectorsText = upgradedSelectors.map(({inputSelector, outputSelector}) -> "`#{inputSelector}` => `#{outputSelector}`").join('\n')
console.warn("""
Shadow DOM for `atom-text-editor` elements has been removed. This means
should stop using :host and ::shadow pseudo-selectors, and prepend all
your syntax selectors with `syntax--`. To prevent breakage with existing
stylesheets, we have automatically upgraded the following selectors in
`#{styleElement.sourcePath}`:
#{upgradedSelectorsText}
""")
module.exports = StylesElement = document.registerElement 'atom-styles', prototype: StylesElement.prototype