UNPKG

13.2 kBTypeScriptView Raw
1import AtRule from './at-rule.js'
2import Comment from './comment.js'
3import Declaration from './declaration.js'
4import Node, { ChildNode, ChildProps, NodeProps } from './node.js'
5import Rule from './rule.js'
6
7declare namespace Container {
8 export interface ValueOptions {
9 /**
10 * String that’s used to narrow down values and speed up the regexp search.
11 */
12 fast?: string
13
14 /**
15 * An array of property names.
16 */
17 props?: string[]
18 }
19
20 export interface ContainerProps extends NodeProps {
21 nodes?: (ChildNode | ChildProps)[]
22 }
23
24 // eslint-disable-next-line @typescript-eslint/no-use-before-define
25 export { Container_ as default }
26}
27
28/**
29 * The `Root`, `AtRule`, and `Rule` container nodes
30 * inherit some common methods to help work with their children.
31 *
32 * Note that all containers can store any content. If you write a rule inside
33 * a rule, PostCSS will parse it.
34 */
35declare abstract class Container_<Child extends Node = ChildNode> extends Node {
36 /**
37 * An array containing the container’s children.
38 *
39 * ```js
40 * const root = postcss.parse('a { color: black }')
41 * root.nodes.length //=> 1
42 * root.nodes[0].selector //=> 'a'
43 * root.nodes[0].nodes[0].prop //=> 'color'
44 * ```
45 */
46 nodes: Child[]
47
48 /**
49 * Inserts new nodes to the end of the container.
50 *
51 * ```js
52 * const decl1 = new Declaration({ prop: 'color', value: 'black' })
53 * const decl2 = new Declaration({ prop: 'background-color', value: 'white' })
54 * rule.append(decl1, decl2)
55 *
56 * root.append({ name: 'charset', params: '"UTF-8"' }) // at-rule
57 * root.append({ selector: 'a' }) // rule
58 * rule.append({ prop: 'color', value: 'black' }) // declaration
59 * rule.append({ text: 'Comment' }) // comment
60 *
61 * root.append('a {}')
62 * root.first.append('color: black; z-index: 1')
63 * ```
64 *
65 * @param nodes New nodes.
66 * @return This node for methods chain.
67 */
68 append(
69 ...nodes: (ChildProps | ChildProps[] | Node | Node[] | string | string[])[]
70 ): this
71
72 assign(overrides: Container.ContainerProps | object): this
73 clone(overrides?: Partial<Container.ContainerProps>): Container<Child>
74 cloneAfter(overrides?: Partial<Container.ContainerProps>): Container<Child>
75 cloneBefore(overrides?: Partial<Container.ContainerProps>): Container<Child>
76
77 /**
78 * Iterates through the container’s immediate children,
79 * calling `callback` for each child.
80 *
81 * Returning `false` in the callback will break iteration.
82 *
83 * This method only iterates through the container’s immediate children.
84 * If you need to recursively iterate through all the container’s descendant
85 * nodes, use `Container#walk`.
86 *
87 * Unlike the for `{}`-cycle or `Array#forEach` this iterator is safe
88 * if you are mutating the array of child nodes during iteration.
89 * PostCSS will adjust the current index to match the mutations.
90 *
91 * ```js
92 * const root = postcss.parse('a { color: black; z-index: 1 }')
93 * const rule = root.first
94 *
95 * for (const decl of rule.nodes) {
96 * decl.cloneBefore({ prop: '-webkit-' + decl.prop })
97 * // Cycle will be infinite, because cloneBefore moves the current node
98 * // to the next index
99 * }
100 *
101 * rule.each(decl => {
102 * decl.cloneBefore({ prop: '-webkit-' + decl.prop })
103 * // Will be executed only for color and z-index
104 * })
105 * ```
106 *
107 * @param callback Iterator receives each node and index.
108 * @return Returns `false` if iteration was broke.
109 */
110 each(
111 callback: (node: Child, index: number) => false | void
112 ): false | undefined
113
114 /**
115 * Returns `true` if callback returns `true`
116 * for all of the container’s children.
117 *
118 * ```js
119 * const noPrefixes = rule.every(i => i.prop[0] !== '-')
120 * ```
121 *
122 * @param condition Iterator returns true or false.
123 * @return Is every child pass condition.
124 */
125 every(
126 condition: (node: Child, index: number, nodes: Child[]) => boolean
127 ): boolean
128 /**
129 * The container’s first child.
130 *
131 * ```js
132 * rule.first === rules.nodes[0]
133 * ```
134 */
135 get first(): Child | undefined
136
137 /**
138 * Returns a `child`’s index within the `Container#nodes` array.
139 *
140 * ```js
141 * rule.index( rule.nodes[2] ) //=> 2
142 * ```
143 *
144 * @param child Child of the current container.
145 * @return Child index.
146 */
147 index(child: Child | number): number
148 /**
149 * Insert new node after old node within the container.
150 *
151 * @param oldNode Child or child’s index.
152 * @param newNode New node.
153 * @return This node for methods chain.
154 */
155 insertAfter(
156 oldNode: Child | number,
157 newNode: Child | Child[] | ChildProps | ChildProps[] | string | string[]
158 ): this
159
160 /**
161 * Traverses the container’s descendant nodes, calling callback
162 * for each comment node.
163 *
164 * Like `Container#each`, this method is safe
165 * to use if you are mutating arrays during iteration.
166 *
167 * ```js
168 * root.walkComments(comment => {
169 * comment.remove()
170 * })
171 * ```
172 *
173 * @param callback Iterator receives each node and index.
174 * @return Returns `false` if iteration was broke.
175 */
176
177 /**
178 * Insert new node before old node within the container.
179 *
180 * ```js
181 * rule.insertBefore(decl, decl.clone({ prop: '-webkit-' + decl.prop }))
182 * ```
183 *
184 * @param oldNode Child or child’s index.
185 * @param newNode New node.
186 * @return This node for methods chain.
187 */
188 insertBefore(
189 oldNode: Child | number,
190 newNode: Child | Child[] | ChildProps | ChildProps[] | string | string[]
191 ): this
192 /**
193 * The container’s last child.
194 *
195 * ```js
196 * rule.last === rule.nodes[rule.nodes.length - 1]
197 * ```
198 */
199 get last(): Child | undefined
200
201 /**
202 * Inserts new nodes to the start of the container.
203 *
204 * ```js
205 * const decl1 = new Declaration({ prop: 'color', value: 'black' })
206 * const decl2 = new Declaration({ prop: 'background-color', value: 'white' })
207 * rule.prepend(decl1, decl2)
208 *
209 * root.append({ name: 'charset', params: '"UTF-8"' }) // at-rule
210 * root.append({ selector: 'a' }) // rule
211 * rule.append({ prop: 'color', value: 'black' }) // declaration
212 * rule.append({ text: 'Comment' }) // comment
213 *
214 * root.append('a {}')
215 * root.first.append('color: black; z-index: 1')
216 * ```
217 *
218 * @param nodes New nodes.
219 * @return This node for methods chain.
220 */
221 prepend(
222 ...nodes: (ChildProps | ChildProps[] | Node | Node[] | string | string[])[]
223 ): this
224
225 /**
226 * Add child to the end of the node.
227 *
228 * ```js
229 * rule.push(new Declaration({ prop: 'color', value: 'black' }))
230 * ```
231 *
232 * @param child New node.
233 * @return This node for methods chain.
234 */
235 push(child: Child): this
236
237 /**
238 * Removes all children from the container
239 * and cleans their parent properties.
240 *
241 * ```js
242 * rule.removeAll()
243 * rule.nodes.length //=> 0
244 * ```
245 *
246 * @return This node for methods chain.
247 */
248 removeAll(): this
249
250 /**
251 * Removes node from the container and cleans the parent properties
252 * from the node and its children.
253 *
254 * ```js
255 * rule.nodes.length //=> 5
256 * rule.removeChild(decl)
257 * rule.nodes.length //=> 4
258 * decl.parent //=> undefined
259 * ```
260 *
261 * @param child Child or child’s index.
262 * @return This node for methods chain.
263 */
264 removeChild(child: Child | number): this
265
266 replaceValues(
267 pattern: RegExp | string,
268 replaced: { (substring: string, ...args: any[]): string } | string
269 ): this
270
271 /**
272 * Passes all declaration values within the container that match pattern
273 * through callback, replacing those values with the returned result
274 * of callback.
275 *
276 * This method is useful if you are using a custom unit or function
277 * and need to iterate through all values.
278 *
279 * ```js
280 * root.replaceValues(/\d+rem/, { fast: 'rem' }, string => {
281 * return 15 * parseInt(string) + 'px'
282 * })
283 * ```
284 *
285 * @param pattern Replace pattern.
286 * @param {object} opts Options to speed up the search.
287 * @param callback String to replace pattern or callback
288 * that returns a new value. The callback
289 * will receive the same arguments
290 * as those passed to a function parameter
291 * of `String#replace`.
292 * @return This node for methods chain.
293 */
294 replaceValues(
295 pattern: RegExp | string,
296 options: Container.ValueOptions,
297 replaced: { (substring: string, ...args: any[]): string } | string
298 ): this
299
300 /**
301 * Returns `true` if callback returns `true` for (at least) one
302 * of the container’s children.
303 *
304 * ```js
305 * const hasPrefix = rule.some(i => i.prop[0] === '-')
306 * ```
307 *
308 * @param condition Iterator returns true or false.
309 * @return Is some child pass condition.
310 */
311 some(
312 condition: (node: Child, index: number, nodes: Child[]) => boolean
313 ): boolean
314
315 /**
316 * Traverses the container’s descendant nodes, calling callback
317 * for each node.
318 *
319 * Like container.each(), this method is safe to use
320 * if you are mutating arrays during iteration.
321 *
322 * If you only need to iterate through the container’s immediate children,
323 * use `Container#each`.
324 *
325 * ```js
326 * root.walk(node => {
327 * // Traverses all descendant nodes.
328 * })
329 * ```
330 *
331 * @param callback Iterator receives each node and index.
332 * @return Returns `false` if iteration was broke.
333 */
334 walk(
335 callback: (node: ChildNode, index: number) => false | void
336 ): false | undefined
337 /**
338 * Traverses the container’s descendant nodes, calling callback
339 * for each at-rule node.
340 *
341 * If you pass a filter, iteration will only happen over at-rules
342 * that have matching names.
343 *
344 * Like `Container#each`, this method is safe
345 * to use if you are mutating arrays during iteration.
346 *
347 * ```js
348 * root.walkAtRules(rule => {
349 * if (isOld(rule.name)) rule.remove()
350 * })
351 *
352 * let first = false
353 * root.walkAtRules('charset', rule => {
354 * if (!first) {
355 * first = true
356 * } else {
357 * rule.remove()
358 * }
359 * })
360 * ```
361 *
362 * @param name String or regular expression to filter at-rules by name.
363 * @param callback Iterator receives each node and index.
364 * @return Returns `false` if iteration was broke.
365 */
366 walkAtRules(
367 nameFilter: RegExp | string,
368 callback: (atRule: AtRule, index: number) => false | void
369 ): false | undefined
370
371 walkAtRules(
372 callback: (atRule: AtRule, index: number) => false | void
373 ): false | undefined
374
375 walkComments(
376 callback: (comment: Comment, indexed: number) => false | void
377 ): false | undefined
378
379 walkComments(
380 callback: (comment: Comment, indexed: number) => false | void
381 ): false | undefined
382
383 /**
384 * Traverses the container’s descendant nodes, calling callback
385 * for each declaration node.
386 *
387 * If you pass a filter, iteration will only happen over declarations
388 * with matching properties.
389 *
390 * ```js
391 * root.walkDecls(decl => {
392 * checkPropertySupport(decl.prop)
393 * })
394 *
395 * root.walkDecls('border-radius', decl => {
396 * decl.remove()
397 * })
398 *
399 * root.walkDecls(/^background/, decl => {
400 * decl.value = takeFirstColorFromGradient(decl.value)
401 * })
402 * ```
403 *
404 * Like `Container#each`, this method is safe
405 * to use if you are mutating arrays during iteration.
406 *
407 * @param prop String or regular expression to filter declarations
408 * by property name.
409 * @param callback Iterator receives each node and index.
410 * @return Returns `false` if iteration was broke.
411 */
412 walkDecls(
413 propFilter: RegExp | string,
414 callback: (decl: Declaration, index: number) => false | void
415 ): false | undefined
416 walkDecls(
417 callback: (decl: Declaration, index: number) => false | void
418 ): false | undefined
419 /**
420 * Traverses the container’s descendant nodes, calling callback
421 * for each rule node.
422 *
423 * If you pass a filter, iteration will only happen over rules
424 * with matching selectors.
425 *
426 * Like `Container#each`, this method is safe
427 * to use if you are mutating arrays during iteration.
428 *
429 * ```js
430 * const selectors = []
431 * root.walkRules(rule => {
432 * selectors.push(rule.selector)
433 * })
434 * console.log(`Your CSS uses ${ selectors.length } selectors`)
435 * ```
436 *
437 * @param selector String or regular expression to filter rules by selector.
438 * @param callback Iterator receives each node and index.
439 * @return Returns `false` if iteration was broke.
440 */
441 walkRules(
442 selectorFilter: RegExp | string,
443 callback: (rule: Rule, index: number) => false | void
444 ): false | undefined
445 walkRules(
446 callback: (rule: Rule, index: number) => false | void
447 ): false | undefined
448}
449
450declare class Container<Child extends Node = ChildNode> extends Container_<Child> {}
451
452export = Container