UNPKG

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