mirror of
https://github.com/atom/atom.git
synced 2026-02-10 06:35:00 -05:00
Transform deprecated shadow DOM selectors in StyleManager
This commit is contained in:
@@ -863,7 +863,7 @@ module.exports = new Set([
|
||||
'trace', 'trace-argument', 'trace-object', 'traceback', 'tracing',
|
||||
'track_processing', 'trader', 'tradersk', 'trail', 'trailing',
|
||||
'trailing-array-separator', 'trailing-dictionary-separator', 'trailing-match',
|
||||
'trailing-whitespace', 'trait', 'traits', 'traits-keyword', 'transaction',
|
||||
'trait', 'traits', 'traits-keyword', 'transaction',
|
||||
'transcendental', 'transcludeblock', 'transcludeinline', 'transclusion',
|
||||
'transform', 'transformation', 'transient', 'transition',
|
||||
'transitionable-property-value', 'translation', 'transmission-filter',
|
||||
|
||||
@@ -202,8 +202,8 @@ class LinesTileComponent
|
||||
if @presenter.isCloseTagCode(tagCode)
|
||||
openScopeNode = openScopeNode.parentElement
|
||||
else if @presenter.isOpenTagCode(tagCode)
|
||||
scopes = @presenter.tagForCode(tagCode).replace(/\s+/g, '.').split('.').map((scope) -> "syntax--#{scope}")
|
||||
newScopeNode = @domElementPool.buildElement("span", scopes.join(' '))
|
||||
scope = @presenter.tagForCode(tagCode)
|
||||
newScopeNode = @domElementPool.buildElement("span", scope.replace(/\.+/g, ' '))
|
||||
openScopeNode.appendChild(newScopeNode)
|
||||
openScopeNode = newScopeNode
|
||||
else
|
||||
@@ -219,7 +219,7 @@ class LinesTileComponent
|
||||
|
||||
if lineText.endsWith(@presenter.displayLayer.foldCharacter)
|
||||
# Insert a zero-width non-breaking whitespace, so that
|
||||
# LinesYardstick can take the syntax--fold-marker::after pseudo-element
|
||||
# LinesYardstick can take the fold-marker::after pseudo-element
|
||||
# into account during measurements when such marker is the last
|
||||
# character on the line.
|
||||
textNode = @domElementPool.buildText(ZERO_WIDTH_NBSP)
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
const {Emitter, Disposable} = require('event-kit')
|
||||
const fs = require('fs-plus')
|
||||
const path = require('path')
|
||||
const {Emitter, Disposable} = require('event-kit')
|
||||
const postcss = require('postcss')
|
||||
const selectorParser = require('postcss-selector-parser')
|
||||
const StylesElement = require('./styles-element')
|
||||
const DEPRECATED_SYNTAX_SELECTORS = require('./deprecated-syntax-selectors')
|
||||
|
||||
// Extended: A singleton instance of this class available via `atom.styles`,
|
||||
// which you can use to globally query and observe the set of active style
|
||||
@@ -122,7 +125,7 @@ module.exports = class StyleManager {
|
||||
}
|
||||
}
|
||||
|
||||
styleElement.textContent = source
|
||||
styleElement.textContent = transformDeprecatedShadowDOMSelectors(source, params.context)
|
||||
if (updated) {
|
||||
this.emitter.emit('did-update-style-element', styleElement)
|
||||
} else {
|
||||
@@ -205,3 +208,37 @@ module.exports = class StyleManager {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function transformDeprecatedShadowDOMSelectors (css, context) {
|
||||
const root = postcss.parse(css)
|
||||
root.walkRules((rule) => {
|
||||
rule.selector = selectorParser((selectors) => {
|
||||
selectors.each((selector) => {
|
||||
const firstNode = selector.nodes[0]
|
||||
if (context === 'atom-text-editor' && firstNode.type === 'pseudo' && firstNode.value === ':host') {
|
||||
const atomTextEditorElementNode = selectorParser.tag({value: 'atom-text-editor'})
|
||||
firstNode.replaceWith(atomTextEditorElementNode)
|
||||
}
|
||||
|
||||
let targetsAtomTextEditorShadow = context === 'atom-text-editor'
|
||||
let previousNode
|
||||
selector.each((node) => {
|
||||
if (targetsAtomTextEditorShadow && node.type === 'class') {
|
||||
if (DEPRECATED_SYNTAX_SELECTORS.has(node.value) && !node.value.startsWith('syntax--')) {
|
||||
node.value = `syntax--${node.value}`
|
||||
}
|
||||
} else if (previousNode) {
|
||||
const currentNodeIsShadowPseudoClass = node.type === 'pseudo' && node.value === '::shadow'
|
||||
const previousNodeIsAtomTextEditor = previousNode.type === 'tag' && previousNode.value === 'atom-text-editor'
|
||||
if (previousNodeIsAtomTextEditor && currentNodeIsShadowPseudoClass) {
|
||||
selector.removeChild(node)
|
||||
targetsAtomTextEditorShadow = true
|
||||
}
|
||||
}
|
||||
previousNode = node
|
||||
})
|
||||
})
|
||||
}).process(rule.selector).result
|
||||
})
|
||||
return root.toString()
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user