mirror of
https://github.com/hanzoai/postcss.git
synced 2026-09-24 17:01:56 +00:00
721 lines
33 KiB
HTML
721 lines
33 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<title>container.es6 - Documentation</title>
|
||
|
||
<script src="scripts/prettify/prettify.js"></script>
|
||
<script src="scripts/prettify/lang-css.js"></script>
|
||
<!--[if lt IE 9]>
|
||
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
|
||
<![endif]-->
|
||
<link type="text/css" rel="stylesheet" href="styles/prettify.css">
|
||
<link type="text/css" rel="stylesheet" href="styles/jsdoc.css">
|
||
</head>
|
||
<body>
|
||
|
||
<input type="checkbox" id="nav-trigger" class="nav-trigger" />
|
||
<label for="nav-trigger" class="navicon-button x">
|
||
<div class="navicon"></div>
|
||
</label>
|
||
|
||
<label for="nav-trigger" class="overlay"></label>
|
||
|
||
<nav>
|
||
<h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="AtRule.html">AtRule</a><ul class='methods'><li data-type='method'><a href="AtRule.html#append">append</a></li><li data-type='method'><a href="AtRule.html#each">each</a></li><li data-type='method'><a href="AtRule.html#every">every</a></li><li data-type='method'><a href="AtRule.html#index">index</a></li><li data-type='method'><a href="AtRule.html#insertAfter">insertAfter</a></li><li data-type='method'><a href="AtRule.html#insertBefore">insertBefore</a></li><li data-type='method'><a href="AtRule.html#prepend">prepend</a></li><li data-type='method'><a href="AtRule.html#removeAll">removeAll</a></li><li data-type='method'><a href="AtRule.html#removeChild">removeChild</a></li><li data-type='method'><a href="AtRule.html#replaceValues">replaceValues</a></li><li data-type='method'><a href="AtRule.html#some">some</a></li><li data-type='method'><a href="AtRule.html#walk">walk</a></li><li data-type='method'><a href="AtRule.html#walkAtRules">walkAtRules</a></li><li data-type='method'><a href="AtRule.html#walkComments">walkComments</a></li><li data-type='method'><a href="AtRule.html#walkDecls">walkDecls</a></li><li data-type='method'><a href="AtRule.html#walkRules">walkRules</a></li></ul></li><li><a href="Comment.html">Comment</a><ul class='methods'><li data-type='method'><a href="Comment.html#after">after</a></li><li data-type='method'><a href="Comment.html#before">before</a></li><li data-type='method'><a href="Comment.html#cleanRaws">cleanRaws</a></li><li data-type='method'><a href="Comment.html#clone">clone</a></li><li data-type='method'><a href="Comment.html#cloneAfter">cloneAfter</a></li><li data-type='method'><a href="Comment.html#cloneBefore">cloneBefore</a></li><li data-type='method'><a href="Comment.html#error">error</a></li><li data-type='method'><a href="Comment.html#next">next</a></li><li data-type='method'><a href="Comment.html#prev">prev</a></li><li data-type='method'><a href="Comment.html#raw">raw</a></li><li data-type='method'><a href="Comment.html#remove">remove</a></li><li data-type='method'><a href="Comment.html#replaceWith">replaceWith</a></li><li data-type='method'><a href="Comment.html#root">root</a></li><li data-type='method'><a href="Comment.html#toString">toString</a></li><li data-type='method'><a href="Comment.html#warn">warn</a></li></ul></li><li><a href="Container.html">Container</a><ul class='methods'><li data-type='method'><a href="Container.html#after">after</a></li><li data-type='method'><a href="Container.html#append">append</a></li><li data-type='method'><a href="Container.html#before">before</a></li><li data-type='method'><a href="Container.html#cleanRaws">cleanRaws</a></li><li data-type='method'><a href="Container.html#clone">clone</a></li><li data-type='method'><a href="Container.html#cloneAfter">cloneAfter</a></li><li data-type='method'><a href="Container.html#cloneBefore">cloneBefore</a></li><li data-type='method'><a href="Container.html#each">each</a></li><li data-type='method'><a href="Container.html#error">error</a></li><li data-type='method'><a href="Container.html#every">every</a></li><li data-type='method'><a href="Container.html#index">index</a></li><li data-type='method'><a href="Container.html#insertAfter">insertAfter</a></li><li data-type='method'><a href="Container.html#insertBefore">insertBefore</a></li><li data-type='method'><a href="Container.html#next">next</a></li><li data-type='method'><a href="Container.html#prepend">prepend</a></li><li data-type='method'><a href="Container.html#prev">prev</a></li><li data-type='method'><a href="Container.html#raw">raw</a></li><li data-type='method'><a href="Container.html#remove">remove</a></li><li data-type='method'><a href="Container.html#removeAll">removeAll</a></li><li data-type='method'><a href="Container.html#removeChild">removeChild</a></li><li data-type='method'><a href="Container.html#replaceValues">replaceValues</a></li><li data-type='method'><a href="Container.html#replaceWith">replaceWith</a></li><li data-type='method'><a href="Container.html#root">root</a></li><li data-type='method'><a href="Container.html#some">some</a></li><li data-type='method'><a href="Container.html#toString">toString</a></li><li data-type='method'><a href="Container.html#walk">walk</a></li><li data-type='method'><a href="Container.html#walkAtRules">walkAtRules</a></li><li data-type='method'><a href="Container.html#walkComments">walkComments</a></li><li data-type='method'><a href="Container.html#walkDecls">walkDecls</a></li><li data-type='method'><a href="Container.html#walkRules">walkRules</a></li><li data-type='method'><a href="Container.html#warn">warn</a></li></ul></li><li><a href="CssSyntaxError.html">CssSyntaxError</a><ul class='methods'><li data-type='method'><a href="CssSyntaxError.html#showSourceCode">showSourceCode</a></li><li data-type='method'><a href="CssSyntaxError.html#toString">toString</a></li></ul></li><li><a href="Declaration.html">Declaration</a><ul class='methods'><li data-type='method'><a href="Declaration.html#after">after</a></li><li data-type='method'><a href="Declaration.html#before">before</a></li><li data-type='method'><a href="Declaration.html#cleanRaws">cleanRaws</a></li><li data-type='method'><a href="Declaration.html#clone">clone</a></li><li data-type='method'><a href="Declaration.html#cloneAfter">cloneAfter</a></li><li data-type='method'><a href="Declaration.html#cloneBefore">cloneBefore</a></li><li data-type='method'><a href="Declaration.html#error">error</a></li><li data-type='method'><a href="Declaration.html#next">next</a></li><li data-type='method'><a href="Declaration.html#prev">prev</a></li><li data-type='method'><a href="Declaration.html#raw">raw</a></li><li data-type='method'><a href="Declaration.html#remove">remove</a></li><li data-type='method'><a href="Declaration.html#replaceWith">replaceWith</a></li><li data-type='method'><a href="Declaration.html#root">root</a></li><li data-type='method'><a href="Declaration.html#toString">toString</a></li><li data-type='method'><a href="Declaration.html#warn">warn</a></li></ul></li><li><a href="Input.html">Input</a><ul class='methods'><li data-type='method'><a href="Input.html#origin">origin</a></li></ul></li><li><a href="LazyResult.html">LazyResult</a><ul class='methods'><li data-type='method'><a href="LazyResult.html#catch">catch</a></li><li data-type='method'><a href="LazyResult.html#finally">finally</a></li><li data-type='method'><a href="LazyResult.html#then">then</a></li><li data-type='method'><a href="LazyResult.html#toString">toString</a></li><li data-type='method'><a href="LazyResult.html#warnings">warnings</a></li></ul></li><li><a href="Node.html">Node</a><ul class='methods'><li data-type='method'><a href="Node.html#after">after</a></li><li data-type='method'><a href="Node.html#before">before</a></li><li data-type='method'><a href="Node.html#cleanRaws">cleanRaws</a></li><li data-type='method'><a href="Node.html#clone">clone</a></li><li data-type='method'><a href="Node.html#cloneAfter">cloneAfter</a></li><li data-type='method'><a href="Node.html#cloneBefore">cloneBefore</a></li><li data-type='method'><a href="Node.html#error">error</a></li><li data-type='method'><a href="Node.html#next">next</a></li><li data-type='method'><a href="Node.html#prev">prev</a></li><li data-type='method'><a href="Node.html#raw">raw</a></li><li data-type='method'><a href="Node.html#remove">remove</a></li><li data-type='method'><a href="Node.html#replaceWith">replaceWith</a></li><li data-type='method'><a href="Node.html#root">root</a></li><li data-type='method'><a href="Node.html#toString">toString</a></li><li data-type='method'><a href="Node.html#warn">warn</a></li></ul></li><li><a href="PreviousMap.html">PreviousMap</a><ul class='methods'><li data-type='method'><a href="PreviousMap.html#consumer">consumer</a></li><li data-type='method'><a href="PreviousMap.html#withContent">withContent</a></li></ul></li><li><a href="Processor.html">Processor</a><ul class='methods'><li data-type='method'><a href="Processor.html#process">process</a></li><li data-type='method'><a href="Processor.html#use">use</a></li></ul></li><li><a href="Result.html">Result</a><ul class='methods'><li data-type='method'><a href="Result.html#toString">toString</a></li><li data-type='method'><a href="Result.html#warn">warn</a></li><li data-type='method'><a href="Result.html#warnings">warnings</a></li></ul></li><li><a href="Root.html">Root</a><ul class='methods'><li data-type='method'><a href="Root.html#after">after</a></li><li data-type='method'><a href="Root.html#append">append</a></li><li data-type='method'><a href="Root.html#before">before</a></li><li data-type='method'><a href="Root.html#cleanRaws">cleanRaws</a></li><li data-type='method'><a href="Root.html#clone">clone</a></li><li data-type='method'><a href="Root.html#cloneAfter">cloneAfter</a></li><li data-type='method'><a href="Root.html#cloneBefore">cloneBefore</a></li><li data-type='method'><a href="Root.html#each">each</a></li><li data-type='method'><a href="Root.html#error">error</a></li><li data-type='method'><a href="Root.html#every">every</a></li><li data-type='method'><a href="Root.html#index">index</a></li><li data-type='method'><a href="Root.html#insertAfter">insertAfter</a></li><li data-type='method'><a href="Root.html#insertBefore">insertBefore</a></li><li data-type='method'><a href="Root.html#next">next</a></li><li data-type='method'><a href="Root.html#prepend">prepend</a></li><li data-type='method'><a href="Root.html#prev">prev</a></li><li data-type='method'><a href="Root.html#raw">raw</a></li><li data-type='method'><a href="Root.html#remove">remove</a></li><li data-type='method'><a href="Root.html#removeAll">removeAll</a></li><li data-type='method'><a href="Root.html#removeChild">removeChild</a></li><li data-type='method'><a href="Root.html#replaceValues">replaceValues</a></li><li data-type='method'><a href="Root.html#replaceWith">replaceWith</a></li><li data-type='method'><a href="Root.html#root">root</a></li><li data-type='method'><a href="Root.html#some">some</a></li><li data-type='method'><a href="Root.html#toResult">toResult</a></li><li data-type='method'><a href="Root.html#toString">toString</a></li><li data-type='method'><a href="Root.html#walk">walk</a></li><li data-type='method'><a href="Root.html#walkAtRules">walkAtRules</a></li><li data-type='method'><a href="Root.html#walkComments">walkComments</a></li><li data-type='method'><a href="Root.html#walkDecls">walkDecls</a></li><li data-type='method'><a href="Root.html#walkRules">walkRules</a></li><li data-type='method'><a href="Root.html#warn">warn</a></li></ul></li><li><a href="Rule.html">Rule</a><ul class='methods'><li data-type='method'><a href="Rule.html#after">after</a></li><li data-type='method'><a href="Rule.html#append">append</a></li><li data-type='method'><a href="Rule.html#before">before</a></li><li data-type='method'><a href="Rule.html#cleanRaws">cleanRaws</a></li><li data-type='method'><a href="Rule.html#clone">clone</a></li><li data-type='method'><a href="Rule.html#cloneAfter">cloneAfter</a></li><li data-type='method'><a href="Rule.html#cloneBefore">cloneBefore</a></li><li data-type='method'><a href="Rule.html#each">each</a></li><li data-type='method'><a href="Rule.html#error">error</a></li><li data-type='method'><a href="Rule.html#every">every</a></li><li data-type='method'><a href="Rule.html#index">index</a></li><li data-type='method'><a href="Rule.html#insertAfter">insertAfter</a></li><li data-type='method'><a href="Rule.html#insertBefore">insertBefore</a></li><li data-type='method'><a href="Rule.html#next">next</a></li><li data-type='method'><a href="Rule.html#prepend">prepend</a></li><li data-type='method'><a href="Rule.html#prev">prev</a></li><li data-type='method'><a href="Rule.html#raw">raw</a></li><li data-type='method'><a href="Rule.html#remove">remove</a></li><li data-type='method'><a href="Rule.html#removeAll">removeAll</a></li><li data-type='method'><a href="Rule.html#removeChild">removeChild</a></li><li data-type='method'><a href="Rule.html#replaceValues">replaceValues</a></li><li data-type='method'><a href="Rule.html#replaceWith">replaceWith</a></li><li data-type='method'><a href="Rule.html#root">root</a></li><li data-type='method'><a href="Rule.html#some">some</a></li><li data-type='method'><a href="Rule.html#toString">toString</a></li><li data-type='method'><a href="Rule.html#walk">walk</a></li><li data-type='method'><a href="Rule.html#walkAtRules">walkAtRules</a></li><li data-type='method'><a href="Rule.html#walkComments">walkComments</a></li><li data-type='method'><a href="Rule.html#walkDecls">walkDecls</a></li><li data-type='method'><a href="Rule.html#walkRules">walkRules</a></li><li data-type='method'><a href="Rule.html#warn">warn</a></li></ul></li><li><a href="Warning.html">Warning</a><ul class='methods'><li data-type='method'><a href="Warning.html#toString">toString</a></li></ul></li></ul><h3>Namespaces</h3><ul><li><a href="list.html">list</a><ul class='methods'><li data-type='method'><a href="list.html#.comma">comma</a></li><li data-type='method'><a href="list.html#.space">space</a></li></ul></li><li><a href="postcss.html">postcss</a><ul class='methods'><li data-type='method'><a href="postcss.html#.atRule">atRule</a></li><li data-type='method'><a href="postcss.html#.comment">comment</a></li><li data-type='method'><a href="postcss.html#.decl">decl</a></li><li data-type='method'><a href="postcss.html#.parse">parse</a></li><li data-type='method'><a href="postcss.html#.plugin">plugin</a></li><li data-type='method'><a href="postcss.html#.root">root</a></li><li data-type='method'><a href="postcss.html#.rule">rule</a></li><li data-type='method'><a href="postcss.html#.stringify">stringify</a></li></ul></li><li><a href="vendor.html">vendor</a><ul class='methods'><li data-type='method'><a href="vendor.html#.prefix">prefix</a></li><li data-type='method'><a href="vendor.html#.unprefixed">unprefixed</a></li></ul></li></ul><h3><a href="global.html">Global</a></h3>
|
||
</nav>
|
||
|
||
<div id="main">
|
||
|
||
<h1 class="page-title">container.es6</h1>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<section>
|
||
<article>
|
||
<pre class="prettyprint source linenums"><code>import Declaration from './declaration'
|
||
import Comment from './comment'
|
||
import Node from './node'
|
||
|
||
function cleanSource (nodes) {
|
||
return nodes.map(i => {
|
||
if (i.nodes) i.nodes = cleanSource(i.nodes)
|
||
delete i.source
|
||
return i
|
||
})
|
||
}
|
||
|
||
/**
|
||
* The {@link Root}, {@link AtRule}, and {@link 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.
|
||
*
|
||
* @extends Node
|
||
* @abstract
|
||
*/
|
||
class Container extends Node {
|
||
push (child) {
|
||
child.parent = this
|
||
this.nodes.push(child)
|
||
return this
|
||
}
|
||
|
||
/**
|
||
* 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 {@link 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.
|
||
*
|
||
* @param {childIterator} callback Iterator receives each node and index.
|
||
*
|
||
* @return {false|undefined} Returns `false` if iteration was broke.
|
||
*
|
||
* @example
|
||
* 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
|
||
* })
|
||
*/
|
||
each (callback) {
|
||
if (!this.lastEach) this.lastEach = 0
|
||
if (!this.indexes) this.indexes = { }
|
||
|
||
this.lastEach += 1
|
||
const id = this.lastEach
|
||
this.indexes[id] = 0
|
||
|
||
if (!this.nodes) return undefined
|
||
|
||
let index, result
|
||
while (this.indexes[id] < this.nodes.length) {
|
||
index = this.indexes[id]
|
||
result = callback(this.nodes[index], index)
|
||
if (result === false) break
|
||
|
||
this.indexes[id] += 1
|
||
}
|
||
|
||
delete this.indexes[id]
|
||
|
||
return result
|
||
}
|
||
|
||
/**
|
||
* 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 {@link Container#each}.
|
||
*
|
||
* @param {childIterator} callback Iterator receives each node and index.
|
||
*
|
||
* @return {false|undefined} Returns `false` if iteration was broke.
|
||
*
|
||
* @example
|
||
* root.walk(node => {
|
||
* // Traverses all descendant nodes.
|
||
* })
|
||
*/
|
||
walk (callback) {
|
||
return this.each((child, i) => {
|
||
let result
|
||
try {
|
||
result = callback(child, i)
|
||
} catch (e) {
|
||
e.postcssNode = child
|
||
if (e.stack && child.source && /\n\s{4}at /.test(e.stack)) {
|
||
const s = child.source
|
||
e.stack = e.stack.replace(/\n\s{4}at /,
|
||
`$&${ s.input.from }:${ s.start.line }:${ s.start.column }$&`)
|
||
}
|
||
throw e
|
||
}
|
||
if (result !== false && child.walk) {
|
||
result = child.walk(callback)
|
||
}
|
||
return result
|
||
})
|
||
}
|
||
|
||
/**
|
||
* 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.
|
||
*
|
||
* Like {@link Container#each}, this method is safe
|
||
* to use if you are mutating arrays during iteration.
|
||
*
|
||
* @param {string|RegExp} [prop] String or regular expression
|
||
* to filter declarations by property name.
|
||
* @param {childIterator} callback Iterator receives each node and index.
|
||
*
|
||
* @return {false|undefined} Returns `false` if iteration was broke.
|
||
*
|
||
* @example
|
||
* root.walkDecls(decl => {
|
||
* checkPropertySupport(decl.prop)
|
||
* })
|
||
*
|
||
* root.walkDecls('border-radius', decl => {
|
||
* decl.remove()
|
||
* })
|
||
*
|
||
* root.walkDecls(/^background/, decl => {
|
||
* decl.value = takeFirstColorFromGradient(decl.value)
|
||
* })
|
||
*/
|
||
walkDecls (prop, callback) {
|
||
if (!callback) {
|
||
callback = prop
|
||
return this.walk((child, i) => {
|
||
if (child.type === 'decl') {
|
||
return callback(child, i)
|
||
}
|
||
})
|
||
} else if (prop instanceof RegExp) {
|
||
return this.walk((child, i) => {
|
||
if (child.type === 'decl' && prop.test(child.prop)) {
|
||
return callback(child, i)
|
||
}
|
||
})
|
||
} else {
|
||
return this.walk((child, i) => {
|
||
if (child.type === 'decl' && child.prop === prop) {
|
||
return callback(child, i)
|
||
}
|
||
})
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 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 {@link Container#each}, this method is safe
|
||
* to use if you are mutating arrays during iteration.
|
||
*
|
||
* @param {string|RegExp} [selector] String or regular expression
|
||
* to filter rules by selector.
|
||
* @param {childIterator} callback Iterator receives each node and index.
|
||
*
|
||
* @return {false|undefined} returns `false` if iteration was broke.
|
||
*
|
||
* @example
|
||
* const selectors = []
|
||
* root.walkRules(rule => {
|
||
* selectors.push(rule.selector)
|
||
* })
|
||
* console.log(`Your CSS uses ${ selectors.length } selectors`)
|
||
*/
|
||
walkRules (selector, callback) {
|
||
if (!callback) {
|
||
callback = selector
|
||
|
||
return this.walk((child, i) => {
|
||
if (child.type === 'rule') {
|
||
return callback(child, i)
|
||
}
|
||
})
|
||
} else if (selector instanceof RegExp) {
|
||
return this.walk((child, i) => {
|
||
if (child.type === 'rule' && selector.test(child.selector)) {
|
||
return callback(child, i)
|
||
}
|
||
})
|
||
} else {
|
||
return this.walk((child, i) => {
|
||
if (child.type === 'rule' && child.selector === selector) {
|
||
return callback(child, i)
|
||
}
|
||
})
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 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 {@link Container#each}, this method is safe
|
||
* to use if you are mutating arrays during iteration.
|
||
*
|
||
* @param {string|RegExp} [name] String or regular expression
|
||
* to filter at-rules by name.
|
||
* @param {childIterator} callback Iterator receives each node and index.
|
||
*
|
||
* @return {false|undefined} Returns `false` if iteration was broke.
|
||
*
|
||
* @example
|
||
* root.walkAtRules(rule => {
|
||
* if (isOld(rule.name)) rule.remove()
|
||
* })
|
||
*
|
||
* let first = false
|
||
* root.walkAtRules('charset', rule => {
|
||
* if (!first) {
|
||
* first = true
|
||
* } else {
|
||
* rule.remove()
|
||
* }
|
||
* })
|
||
*/
|
||
walkAtRules (name, callback) {
|
||
if (!callback) {
|
||
callback = name
|
||
return this.walk((child, i) => {
|
||
if (child.type === 'atrule') {
|
||
return callback(child, i)
|
||
}
|
||
})
|
||
} else if (name instanceof RegExp) {
|
||
return this.walk((child, i) => {
|
||
if (child.type === 'atrule' && name.test(child.name)) {
|
||
return callback(child, i)
|
||
}
|
||
})
|
||
} else {
|
||
return this.walk((child, i) => {
|
||
if (child.type === 'atrule' && child.name === name) {
|
||
return callback(child, i)
|
||
}
|
||
})
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Traverses the container’s descendant nodes, calling callback
|
||
* for each comment node.
|
||
*
|
||
* Like {@link Container#each}, this method is safe
|
||
* to use if you are mutating arrays during iteration.
|
||
*
|
||
* @param {childIterator} callback Iterator receives each node and index.
|
||
*
|
||
* @return {false|undefined} Returns `false` if iteration was broke.
|
||
*
|
||
* @example
|
||
* root.walkComments(comment => {
|
||
* comment.remove()
|
||
* })
|
||
*/
|
||
walkComments (callback) {
|
||
return this.walk((child, i) => {
|
||
if (child.type === 'comment') {
|
||
return callback(child, i)
|
||
}
|
||
})
|
||
}
|
||
|
||
/**
|
||
* Inserts new nodes to the end of the container.
|
||
*
|
||
* @param {...(Node|object|string|Node[])} children New nodes.
|
||
*
|
||
* @return {Node} This node for methods chain.
|
||
*
|
||
* @example
|
||
* const decl1 = postcss.decl({ prop: 'color', value: 'black' })
|
||
* const decl2 = postcss.decl({ 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')
|
||
*/
|
||
append (...children) {
|
||
for (const child of children) {
|
||
const nodes = this.normalize(child, this.last)
|
||
for (const node of nodes) this.nodes.push(node)
|
||
}
|
||
return this
|
||
}
|
||
|
||
/**
|
||
* Inserts new nodes to the start of the container.
|
||
*
|
||
* @param {...(Node|object|string|Node[])} children New nodes.
|
||
*
|
||
* @return {Node} This node for methods chain.
|
||
*
|
||
* @example
|
||
* const decl1 = postcss.decl({ prop: 'color', value: 'black' })
|
||
* const decl2 = postcss.decl({ 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')
|
||
*/
|
||
prepend (...children) {
|
||
children = children.reverse()
|
||
for (const child of children) {
|
||
const nodes = this.normalize(child, this.first, 'prepend').reverse()
|
||
for (const node of nodes) this.nodes.unshift(node)
|
||
for (const id in this.indexes) {
|
||
this.indexes[id] = this.indexes[id] + nodes.length
|
||
}
|
||
}
|
||
return this
|
||
}
|
||
|
||
cleanRaws (keepBetween) {
|
||
super.cleanRaws(keepBetween)
|
||
if (this.nodes) {
|
||
for (const node of this.nodes) node.cleanRaws(keepBetween)
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Insert new node before old node within the container.
|
||
*
|
||
* @param {Node|number} exist Child or child’s index.
|
||
* @param {Node|object|string|Node[]} add New node.
|
||
*
|
||
* @return {Node} This node for methods chain.
|
||
*
|
||
* @example
|
||
* rule.insertBefore(decl, decl.clone({ prop: '-webkit-' + decl.prop }))
|
||
*/
|
||
insertBefore (exist, add) {
|
||
exist = this.index(exist)
|
||
|
||
const type = exist === 0 ? 'prepend' : false
|
||
const nodes = this.normalize(add, this.nodes[exist], type).reverse()
|
||
for (const node of nodes) this.nodes.splice(exist, 0, node)
|
||
|
||
let index
|
||
for (const id in this.indexes) {
|
||
index = this.indexes[id]
|
||
if (exist <= index) {
|
||
this.indexes[id] = index + nodes.length
|
||
}
|
||
}
|
||
|
||
return this
|
||
}
|
||
|
||
/**
|
||
* Insert new node after old node within the container.
|
||
*
|
||
* @param {Node|number} exist Child or child’s index.
|
||
* @param {Node|object|string|Node[]} add New node.
|
||
*
|
||
* @return {Node} This node for methods chain.
|
||
*/
|
||
insertAfter (exist, add) {
|
||
exist = this.index(exist)
|
||
|
||
const nodes = this.normalize(add, this.nodes[exist]).reverse()
|
||
for (const node of nodes) this.nodes.splice(exist + 1, 0, node)
|
||
|
||
let index
|
||
for (const id in this.indexes) {
|
||
index = this.indexes[id]
|
||
if (exist < index) {
|
||
this.indexes[id] = index + nodes.length
|
||
}
|
||
}
|
||
|
||
return this
|
||
}
|
||
|
||
/**
|
||
* Removes node from the container and cleans the parent properties
|
||
* from the node and its children.
|
||
*
|
||
* @param {Node|number} child Child or child’s index.
|
||
*
|
||
* @return {Node} This node for methods chain
|
||
*
|
||
* @example
|
||
* rule.nodes.length //=> 5
|
||
* rule.removeChild(decl)
|
||
* rule.nodes.length //=> 4
|
||
* decl.parent //=> undefined
|
||
*/
|
||
removeChild (child) {
|
||
child = this.index(child)
|
||
this.nodes[child].parent = undefined
|
||
this.nodes.splice(child, 1)
|
||
|
||
let index
|
||
for (const id in this.indexes) {
|
||
index = this.indexes[id]
|
||
if (index >= child) {
|
||
this.indexes[id] = index - 1
|
||
}
|
||
}
|
||
|
||
return this
|
||
}
|
||
|
||
/**
|
||
* Removes all children from the container
|
||
* and cleans their parent properties.
|
||
*
|
||
* @return {Node} This node for methods chain.
|
||
*
|
||
* @example
|
||
* rule.removeAll()
|
||
* rule.nodes.length //=> 0
|
||
*/
|
||
removeAll () {
|
||
for (const node of this.nodes) node.parent = undefined
|
||
this.nodes = []
|
||
return this
|
||
}
|
||
|
||
/**
|
||
* 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.
|
||
*
|
||
* @param {string|RegExp} pattern Replace pattern.
|
||
* @param {object} opts Options to speed up the search.
|
||
* @param {string|string[]} opts.props An array of property names.
|
||
* @param {string} opts.fast String that’s used to narrow down
|
||
* values and speed up the regexp search.
|
||
* @param {function|string} callback String to replace pattern or callback
|
||
* that returns a new value. The callback
|
||
* will receive the same arguments
|
||
* as those passed to a function parameter
|
||
* of `String#replace`.
|
||
*
|
||
* @return {Node} This node for methods chain.
|
||
*
|
||
* @example
|
||
* root.replaceValues(/\d+rem/, { fast: 'rem' }, string => {
|
||
* return 15 * parseInt(string) + 'px'
|
||
* })
|
||
*/
|
||
replaceValues (pattern, opts, callback) {
|
||
if (!callback) {
|
||
callback = opts
|
||
opts = { }
|
||
}
|
||
|
||
this.walkDecls(decl => {
|
||
if (opts.props && opts.props.indexOf(decl.prop) === -1) return
|
||
if (opts.fast && decl.value.indexOf(opts.fast) === -1) return
|
||
|
||
decl.value = decl.value.replace(pattern, callback)
|
||
})
|
||
|
||
return this
|
||
}
|
||
|
||
/**
|
||
* Returns `true` if callback returns `true`
|
||
* for all of the container’s children.
|
||
*
|
||
* @param {childCondition} condition Iterator returns true or false.
|
||
*
|
||
* @return {boolean} Is every child pass condition.
|
||
*
|
||
* @example
|
||
* const noPrefixes = rule.every(i => i.prop[0] !== '-')
|
||
*/
|
||
every (condition) {
|
||
return this.nodes.every(condition)
|
||
}
|
||
|
||
/**
|
||
* Returns `true` if callback returns `true` for (at least) one
|
||
* of the container’s children.
|
||
*
|
||
* @param {childCondition} condition Iterator returns true or false.
|
||
*
|
||
* @return {boolean} Is some child pass condition.
|
||
*
|
||
* @example
|
||
* const hasPrefix = rule.some(i => i.prop[0] === '-')
|
||
*/
|
||
some (condition) {
|
||
return this.nodes.some(condition)
|
||
}
|
||
|
||
/**
|
||
* Returns a `child`’s index within the {@link Container#nodes} array.
|
||
*
|
||
* @param {Node} child Child of the current container.
|
||
*
|
||
* @return {number} Child index.
|
||
*
|
||
* @example
|
||
* rule.index( rule.nodes[2] ) //=> 2
|
||
*/
|
||
index (child) {
|
||
if (typeof child === 'number') {
|
||
return child
|
||
} else {
|
||
return this.nodes.indexOf(child)
|
||
}
|
||
}
|
||
|
||
/**
|
||
* The container’s first child.
|
||
*
|
||
* @type {Node}
|
||
*
|
||
* @example
|
||
* rule.first === rules.nodes[0]
|
||
*/
|
||
get first () {
|
||
if (!this.nodes) return undefined
|
||
return this.nodes[0]
|
||
}
|
||
|
||
/**
|
||
* The container’s last child.
|
||
*
|
||
* @type {Node}
|
||
*
|
||
* @example
|
||
* rule.last === rule.nodes[rule.nodes.length - 1]
|
||
*/
|
||
get last () {
|
||
if (!this.nodes) return undefined
|
||
return this.nodes[this.nodes.length - 1]
|
||
}
|
||
|
||
normalize (nodes, sample) {
|
||
if (typeof nodes === 'string') {
|
||
const parse = require('./parse')
|
||
nodes = cleanSource(parse(nodes).nodes)
|
||
} else if (Array.isArray(nodes)) {
|
||
nodes = nodes.slice(0)
|
||
for (const i of nodes) {
|
||
if (i.parent) i.parent.removeChild(i, 'ignore')
|
||
}
|
||
} else if (nodes.type === 'root') {
|
||
nodes = nodes.nodes.slice(0)
|
||
for (const i of nodes) {
|
||
if (i.parent) i.parent.removeChild(i, 'ignore')
|
||
}
|
||
} else if (nodes.type) {
|
||
nodes = [nodes]
|
||
} else if (nodes.prop) {
|
||
if (typeof nodes.value === 'undefined') {
|
||
throw new Error('Value field is missed in node creation')
|
||
} else if (typeof nodes.value !== 'string') {
|
||
nodes.value = String(nodes.value)
|
||
}
|
||
nodes = [new Declaration(nodes)]
|
||
} else if (nodes.selector) {
|
||
const Rule = require('./rule')
|
||
nodes = [new Rule(nodes)]
|
||
} else if (nodes.name) {
|
||
const AtRule = require('./at-rule')
|
||
nodes = [new AtRule(nodes)]
|
||
} else if (nodes.text) {
|
||
nodes = [new Comment(nodes)]
|
||
} else {
|
||
throw new Error('Unknown node type in node creation')
|
||
}
|
||
|
||
const processed = nodes.map(i => {
|
||
if (i.parent) i.parent.removeChild(i)
|
||
if (typeof i.raws.before === 'undefined') {
|
||
if (sample && typeof sample.raws.before !== 'undefined') {
|
||
i.raws.before = sample.raws.before.replace(/[^\s]/g, '')
|
||
}
|
||
}
|
||
i.parent = this
|
||
return i
|
||
})
|
||
|
||
return processed
|
||
}
|
||
|
||
/**
|
||
* @memberof Container#
|
||
* @member {Node[]} nodes An array containing the container’s children.
|
||
*
|
||
* @example
|
||
* const root = postcss.parse('a { color: black }')
|
||
* root.nodes.length //=> 1
|
||
* root.nodes[0].selector //=> 'a'
|
||
* root.nodes[0].nodes[0].prop //=> 'color'
|
||
*/
|
||
}
|
||
|
||
export default Container
|
||
|
||
/**
|
||
* @callback childCondition
|
||
* @param {Node} node Container child.
|
||
* @param {number} index Child index.
|
||
* @param {Node[]} nodes All container children.
|
||
* @return {boolean}
|
||
*/
|
||
|
||
/**
|
||
* @callback childIterator
|
||
* @param {Node} node Container child.
|
||
* @param {number} index Child index.
|
||
* @return {false|undefined} Returning `false` will break iteration.
|
||
*/
|
||
</code></pre>
|
||
</article>
|
||
</section>
|
||
|
||
|
||
|
||
|
||
</div>
|
||
|
||
<br class="clear">
|
||
|
||
<footer>
|
||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
||
</footer>
|
||
|
||
<script>prettyPrint();</script>
|
||
<script src="scripts/linenumber.js"></script>
|
||
</body>
|
||
</html>
|