Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | 2x 7x 7x 7x 7x 21x 6x 6x 2x 4x 4x 6x 15x 15x 17x 17x 21x 2x 2x 2x 19x 19x 15x 17x 14x 3x 17x 7x 1x 19x 2x 3x 19x 3x 6x 9x 6x 4x 4x 2x | import { Root } from 'postcss'
import * as postcss from 'postcss'
// postcss-selector-parser does have typings but it's problematic to work with.
const selectorParser = require('postcss-selector-parser')
export default postcss.plugin('add-id', (options: any) => (root: Root) => {
const id: string = options
const keyframes = Object.create(null)
root.each(function rewriteSelector(node: any) {
if (!node.selector) {
// handle media queries
Eif (node.type === 'atrule') {
if (node.name === 'media' || node.name === 'supports') {
node.each(rewriteSelector)
} else Eif (/-?keyframes$/.test(node.name)) {
// register keyframes
keyframes[node.params] = node.params = node.params + '-' + id
}
}
return
}
node.selector = selectorParser((selectors: any) => {
selectors.each((selector: any) => {
let node: any = null
selector.each((n: any) => {
// ">>>" combinator
if (n.type === 'combinator' && n.value === '>>>') {
n.value = ' '
n.spaces.before = n.spaces.after = ''
return false
}
// /deep/ alias for >>>, since >>> doesn't work in SASS
Iif (n.type === 'tag' && n.value === '/deep/') {
const prev = n.prev()
if (prev && prev.type === 'combinator' && prev.value === ' ') {
prev.remove()
}
n.remove()
return false
}
if (n.type !== 'pseudo' && n.type !== 'combinator') {
node = n
}
})
if (node) {
node.spaces.after = ''
} else {
// For deep selectors & standalone pseudo selectors,
// the attribute selectors are prepended rather than appended.
// So all leading spaces must be eliminated to avoid problems.
selector.first.spaces.before = ''
}
selector.insertAfter(
node,
selectorParser.attribute({
attribute: id
})
)
})
}).processSync(node.selector)
})
// If keyframes are found in this <style>, find and rewrite animation names
// in declarations.
// Caveat: this only works for keyframes and animation rules in the same
// <style> element.
if (Object.keys(keyframes).length) {
root.walkDecls(decl => {
// individual animation-name declaration
if (/^(-\w+-)?animation-name$/.test(decl.prop)) {
decl.value = decl.value
.split(',')
.map(v => keyframes[v.trim()] || v.trim())
.join(',')
}
// shorthand
if (/^(-\w+-)?animation$/.test(decl.prop)) {
decl.value = decl.value
.split(',')
.map(v => {
const vals = v.trim().split(/\s+/)
const i = vals.findIndex(val => keyframes[val])
if (i !== -1) {
vals.splice(i, 1, keyframes[vals[i]])
return vals.join(' ')
} else {
return v
}
})
.join(',')
}
})
}
})
|