import { postcss } from "https://deno.land/x/bundler@0.6.5/deps.ts";
const { Container } = postcss;
The Root
, AtRule
, and Rule
container nodes
inherit some common methods to help work with their children.
Note that all containers can store any content. If you write a rule inside a rule, PostCSS will parse it.
Properties
The container’s first child.
rule.first === rules.nodes[0]
The container’s last child.
rule.last === rule.nodes[rule.nodes.length - 1]
An array containing the container’s children.
const root = postcss.parse('a { color: black }')
root.nodes.length //=> 1
root.nodes[0].selector //=> 'a'
root.nodes[0].nodes[0].prop //=> 'color'
Methods
Inserts new nodes to the end of the container.
const decl1 = new Declaration({ prop: 'color', value: 'black' })
const decl2 = new Declaration({ prop: 'background-color', value: 'white' })
rule.append(decl1, decl2)
root.append({ name: 'charset', params: '"UTF-8"' }) // at-rule
root.append({ selector: 'a' }) // rule
rule.append({ prop: 'color', value: 'black' }) // declaration
rule.append({ text: 'Comment' }) // comment
root.append('a {}')
root.first.append('color: black; z-index: 1')
Iterates through the container’s immediate children,
calling callback
for each child.
Returning false
in the callback will break iteration.
This method only iterates through the container’s immediate children.
If you need to recursively iterate through all the container’s descendant
nodes, use Container#walk
.
Unlike the for {}
-cycle or Array#forEach
this iterator is safe
if you are mutating the array of child nodes during iteration.
PostCSS will adjust the current index to match the mutations.
const root = postcss.parse('a { color: black; z-index: 1 }')
const rule = root.first
for (const decl of rule.nodes) {
decl.cloneBefore({ prop: '-webkit-' + decl.prop })
// Cycle will be infinite, because cloneBefore moves the current node
// to the next index
}
rule.each(decl => {
decl.cloneBefore({ prop: '-webkit-' + decl.prop })
// Will be executed only for color and z-index
})
Returns true
if callback returns true
for all of the container’s children.
const noPrefixes = rule.every(i => i.prop[0] !== '-')
Returns a child
’s index within the Container#nodes
array.
rule.index( rule.nodes[2] ) //=> 2
Insert new node after old node within the container.
Insert new node before old node within the container.
rule.insertBefore(decl, decl.clone({ prop: '-webkit-' + decl.prop }))
Inserts new nodes to the start of the container.
const decl1 = new Declaration({ prop: 'color', value: 'black' })
const decl2 = new Declaration({ prop: 'background-color', value: 'white' })
rule.prepend(decl1, decl2)
root.append({ name: 'charset', params: '"UTF-8"' }) // at-rule
root.append({ selector: 'a' }) // rule
rule.append({ prop: 'color', value: 'black' }) // declaration
rule.append({ text: 'Comment' }) // comment
root.append('a {}')
root.first.append('color: black; z-index: 1')
Add child to the end of the node.
rule.push(new Declaration({ prop: 'color', value: 'black' }))
Removes all children from the container and cleans their parent properties.
rule.removeAll()
rule.nodes.length //=> 0
Removes node from the container and cleans the parent properties from the node and its children.
rule.nodes.length //=> 5
rule.removeChild(decl)
rule.nodes.length //=> 4
decl.parent //=> undefined
Passes all declaration values within the container that match pattern through callback, replacing those values with the returned result of callback.
This method is useful if you are using a custom unit or function and need to iterate through all values.
root.replaceValues(/\d+rem/, { fast: 'rem' }, string => {
return 15 * parseInt(string) + 'px'
})
Returns true
if callback returns true
for (at least) one
of the container’s children.
const hasPrefix = rule.some(i => i.prop[0] === '-')
Traverses the container’s descendant nodes, calling callback for each node.
Like container.each(), this method is safe to use if you are mutating arrays during iteration.
If you only need to iterate through the container’s immediate children,
use Container#each
.
root.walk(node => {
// Traverses all descendant nodes.
})
Traverses the container’s descendant nodes, calling callback for each at-rule node.
If you pass a filter, iteration will only happen over at-rules that have matching names.
Like Container#each
, this method is safe
to use if you are mutating arrays during iteration.
root.walkAtRules(rule => {
if (isOld(rule.name)) rule.remove()
})
let first = false
root.walkAtRules('charset', rule => {
if (!first) {
first = true
} else {
rule.remove()
}
})
Traverses the container’s descendant nodes, calling callback for each comment node.
Like Container#each
, this method is safe
to use if you are mutating arrays during iteration.
root.walkComments(comment => {
comment.remove()
})
Traverses the container’s descendant nodes, calling callback for each declaration node.
If you pass a filter, iteration will only happen over declarations with matching properties.
root.walkDecls(decl => {
checkPropertySupport(decl.prop)
})
root.walkDecls('border-radius', decl => {
decl.remove()
})
root.walkDecls(/^background/, decl => {
decl.value = takeFirstColorFromGradient(decl.value)
})
Like Container#each
, this method is safe
to use if you are mutating arrays during iteration.
Traverses the container’s descendant nodes, calling callback for each rule node.
If you pass a filter, iteration will only happen over rules with matching selectors.
Like Container#each
, this method is safe
to use if you are mutating arrays during iteration.
const selectors = []
root.walkRules(rule => {
selectors.push(rule.selector)
})
console.log(`Your CSS uses ${ selectors.length } selectors`)