UNPKG

12.4 kBTypeScriptView Raw
1import Declaration, { DeclarationProps } from './declaration.js'
2import Comment, { CommentProps } from './comment.js'
3import { Stringifier, Syntax } from './postcss.js'
4import AtRule, { AtRuleProps } from './at-rule.js'
5import Rule, { RuleProps } from './rule.js'
6import { WarningOptions } from './warning.js'
7import CssSyntaxError from './css-syntax-error.js'
8import Result from './result.js'
9import Input from './input.js'
10import Root from './root.js'
11import Document from './document.js'
12import Container from './container.js'
13
14export type ChildNode = AtRule | Rule | Declaration | Comment
15
16export type AnyNode = AtRule | Rule | Declaration | Comment | Root | Document
17
18export type ChildProps =
19 | AtRuleProps
20 | RuleProps
21 | DeclarationProps
22 | CommentProps
23
24export interface Position {
25 /**
26 * Source offset in file. It starts from 0.
27 */
28 offset: number
29
30 /**
31 * Source line in file. In contrast to `offset` it starts from 1.
32 */
33 column: number
34
35 /**
36 * Source column in file.
37 */
38 line: number
39}
40
41export interface Range {
42 /**
43 * Start position, inclusive.
44 */
45 start: Position
46
47 /**
48 * End position, exclusive.
49 */
50 end: Position
51}
52
53export interface Source {
54 /**
55 * The file source of the node.
56 */
57 input: Input
58 /**
59 * The inclusive starting position of the node’s source.
60 */
61 start?: Position
62 /**
63 * The inclusive ending position of the node's source.
64 */
65 end?: Position
66}
67
68export interface NodeProps {
69 source?: Source
70}
71
72interface NodeErrorOptions {
73 /**
74 * Plugin name that created this error. PostCSS will set it automatically.
75 */
76 plugin?: string
77 /**
78 * A word inside a node's string, that should be highlighted as source
79 * of error.
80 */
81 word?: string
82 /**
83 * An index inside a node's string that should be highlighted as source
84 * of error.
85 */
86 index?: number
87 /**
88 * An ending index inside a node's string that should be highlighted as
89 * source of error.
90 */
91 endIndex?: number
92}
93
94/**
95 * All node classes inherit the following common methods.
96 *
97 * You should not extend this classes to create AST for selector or value
98 * parser.
99 */
100export default abstract class Node {
101 /**
102 * tring representing the node’s type. Possible values are `root`, `atrule`,
103 * `rule`, `decl`, or `comment`.
104 *
105 * ```js
106 * new Declaration({ prop: 'color', value: 'black' }).type //=> 'decl'
107 * ```
108 */
109 type: string
110
111 /**
112 * The node’s parent node.
113 *
114 * ```js
115 * root.nodes[0].parent === root
116 * ```
117 */
118 parent: Document | Container | undefined
119
120 /**
121 * The input source of the node.
122 *
123 * The property is used in source map generation.
124 *
125 * If you create a node manually (e.g., with `postcss.decl()`),
126 * that node will not have a `source` property and will be absent
127 * from the source map. For this reason, the plugin developer should
128 * consider cloning nodes to create new ones (in which case the new node’s
129 * source will reference the original, cloned node) or setting
130 * the `source` property manually.
131 *
132 * ```js
133 * decl.source.input.from //=> '/home/ai/a.sass'
134 * decl.source.start //=> { line: 10, column: 2 }
135 * decl.source.end //=> { line: 10, column: 12 }
136 * ```
137 *
138 * ```js
139 * // Bad
140 * const prefixed = postcss.decl({
141 * prop: '-moz-' + decl.prop,
142 * value: decl.value
143 * })
144 *
145 * // Good
146 * const prefixed = decl.clone({ prop: '-moz-' + decl.prop })
147 * ```
148 *
149 * ```js
150 * if (atrule.name === 'add-link') {
151 * const rule = postcss.rule({ selector: 'a', source: atrule.source })
152 * atrule.parent.insertBefore(atrule, rule)
153 * }
154 * ```
155 */
156 source?: Source
157
158 /**
159 * Information to generate byte-to-byte equal node string as it was
160 * in the origin input.
161 *
162 * Every parser saves its own properties,
163 * but the default CSS parser uses:
164 *
165 * * `before`: the space symbols before the node. It also stores `*`
166 * and `_` symbols before the declaration (IE hack).
167 * * `after`: the space symbols after the last child of the node
168 * to the end of the node.
169 * * `between`: the symbols between the property and value
170 * for declarations, selector and `{` for rules, or last parameter
171 * and `{` for at-rules.
172 * * `semicolon`: contains true if the last child has
173 * an (optional) semicolon.
174 * * `afterName`: the space between the at-rule name and its parameters.
175 * * `left`: the space symbols between `/*` and the comment’s text.
176 * * `right`: the space symbols between the comment’s text
177 * and <code>*&#47;</code>.
178 * * `important`: the content of the important statement,
179 * if it is not just `!important`.
180 *
181 * PostCSS cleans selectors, declaration values and at-rule parameters
182 * from comments and extra spaces, but it stores origin content in raws
183 * properties. As such, if you don’t change a declaration’s value,
184 * PostCSS will use the raw value with comments.
185 *
186 * ```js
187 * const root = postcss.parse('a {\n color:black\n}')
188 * root.first.first.raws //=> { before: '\n ', between: ':' }
189 * ```
190 */
191 raws: any
192
193 /**
194 * @param defaults Value for node properties.
195 */
196 constructor(defaults?: object)
197
198 /**
199 * Returns a `CssSyntaxError` instance containing the original position
200 * of the node in the source, showing line and column numbers and also
201 * a small excerpt to facilitate debugging.
202 *
203 * If present, an input source map will be used to get the original position
204 * of the source, even from a previous compilation step
205 * (e.g., from Sass compilation).
206 *
207 * This method produces very useful error messages.
208 *
209 * ```js
210 * if (!variables[name]) {
211 * throw decl.error(`Unknown variable ${name}`, { word: name })
212 * // CssSyntaxError: postcss-vars:a.sass:4:3: Unknown variable $black
213 * // color: $black
214 * // a
215 * // ^
216 * // background: white
217 * }
218 * ```
219 *
220 * @param message Error description.
221 * @param opts Options.
222 *
223 * @return Error object to throw it.
224 */
225 error(message: string, options?: NodeErrorOptions): CssSyntaxError
226
227 /**
228 * This method is provided as a convenience wrapper for `Result#warn`.
229 *
230 * ```js
231 * Declaration: {
232 * bad: (decl, { result }) => {
233 * decl.warn(result, 'Deprecated property bad')
234 * }
235 * }
236 * ```
237 *
238 * @param result The `Result` instance that will receive the warning.
239 * @param text Warning message.
240 * @param opts Warning Options.
241 *
242 * @return Created warning object.
243 */
244 warn(result: Result, text: string, opts?: WarningOptions): void
245
246 /**
247 * Removes the node from its parent and cleans the parent properties
248 * from the node and its children.
249 *
250 * ```js
251 * if (decl.prop.match(/^-webkit-/)) {
252 * decl.remove()
253 * }
254 * ```
255 *
256 * @return Node to make calls chain.
257 */
258 remove(): this
259
260 /**
261 * Returns a CSS string representing the node.
262 *
263 * ```js
264 * new Rule({ selector: 'a' }).toString() //=> "a {}"
265 * ```
266 *
267 * @param stringifier A syntax to use in string generation.
268 * @return CSS string of this node.
269 */
270 toString(stringifier?: Stringifier | Syntax): string
271
272 /**
273 * Assigns properties to the current node.
274 *
275 * ```js
276 * decl.assign({ prop: 'word-wrap', value: 'break-word' })
277 * ```
278 *
279 * @param overrides New properties to override the node.
280 * @return Current node to methods chain.
281 */
282 assign(overrides: object): this
283
284 /**
285 * Returns an exact clone of the node.
286 *
287 * The resulting cloned node and its (cloned) children will retain
288 * code style properties.
289 *
290 * ```js
291 * decl.raws.before //=> "\n "
292 * const cloned = decl.clone({ prop: '-moz-' + decl.prop })
293 * cloned.raws.before //=> "\n "
294 * cloned.toString() //=> -moz-transform: scale(0)
295 * ```
296 *
297 * @param overrides New properties to override in the clone.
298 * @return Clone of the node.
299 */
300 clone(overrides?: object): this
301
302 /**
303 * Shortcut to clone the node and insert the resulting cloned node
304 * before the current node.
305 *
306 * ```js
307 * decl.cloneBefore({ prop: '-moz-' + decl.prop })
308 * ```
309 *
310 * @param overrides Mew properties to override in the clone.
311 *
312 * @return New node
313 */
314 cloneBefore(overrides?: object): this
315
316 /**
317 * Shortcut to clone the node and insert the resulting cloned node
318 * after the current node.
319 *
320 * @param overrides New properties to override in the clone.
321 * @return New node.
322 */
323 cloneAfter(overrides?: object): this
324
325 /**
326 * Inserts node(s) before the current node and removes the current node.
327 *
328 * ```js
329 * AtRule: {
330 * mixin: atrule => {
331 * atrule.replaceWith(mixinRules[atrule.params])
332 * }
333 * }
334 * ```
335 *
336 * @param nodes Mode(s) to replace current one.
337 * @return Current node to methods chain.
338 */
339 replaceWith(
340 ...nodes: (ChildNode | ChildProps | ChildNode[] | ChildProps[])[]
341 ): this
342
343 /**
344 * Returns the next child of the node’s parent.
345 * Returns `undefined` if the current node is the last child.
346 *
347 * ```js
348 * if (comment.text === 'delete next') {
349 * const next = comment.next()
350 * if (next) {
351 * next.remove()
352 * }
353 * }
354 * ```
355 *
356 * @return Next node.
357 */
358 next(): ChildNode | undefined
359
360 /**
361 * Returns the previous child of the node’s parent.
362 * Returns `undefined` if the current node is the first child.
363 *
364 * ```js
365 * const annotation = decl.prev()
366 * if (annotation.type === 'comment') {
367 * readAnnotation(annotation.text)
368 * }
369 * ```
370 *
371 * @return Previous node.
372 */
373 prev(): ChildNode | undefined
374
375 /**
376 * Insert new node before current node to current node’s parent.
377 *
378 * Just alias for `node.parent.insertBefore(node, add)`.
379 *
380 * ```js
381 * decl.before('content: ""')
382 * ```
383 *
384 * @param newNode New node.
385 * @return This node for methods chain.
386 */
387 before(newNode: Node | ChildProps | string | Node[]): this
388
389 /**
390 * Insert new node after current node to current node’s parent.
391 *
392 * Just alias for `node.parent.insertAfter(node, add)`.
393 *
394 * ```js
395 * decl.after('color: black')
396 * ```
397 *
398 * @param newNode New node.
399 * @return This node for methods chain.
400 */
401 after(newNode: Node | ChildProps | string | Node[]): this
402
403 /**
404 * Finds the Root instance of the node’s tree.
405 *
406 * ```js
407 * root.nodes[0].nodes[0].root() === root
408 * ```
409 *
410 * @return Root parent.
411 */
412 root(): Root
413
414 /**
415 * Returns a `Node#raws` value. If the node is missing
416 * the code style property (because the node was manually built or cloned),
417 * PostCSS will try to autodetect the code style property by looking
418 * at other nodes in the tree.
419 *
420 * ```js
421 * const root = postcss.parse('a { background: white }')
422 * root.nodes[0].append({ prop: 'color', value: 'black' })
423 * root.nodes[0].nodes[1].raws.before //=> undefined
424 * root.nodes[0].nodes[1].raw('before') //=> ' '
425 * ```
426 *
427 * @param prop Name of code style property.
428 * @param defaultType Name of default value, it can be missed
429 * if the value is the same as prop.
430 * @return {string} Code style value.
431 */
432 raw(prop: string, defaultType?: string): string
433
434 /**
435 * Clear the code style properties for the node and its children.
436 *
437 * ```js
438 * node.raws.before //=> ' '
439 * node.cleanRaws()
440 * node.raws.before //=> undefined
441 * ```
442 *
443 * @param keepBetween Keep the `raws.between` symbols.
444 */
445 cleanRaws(keepBetween?: boolean): void
446
447 /**
448 * Fix circular links on `JSON.stringify()`.
449 *
450 * @return Cleaned object.
451 */
452 toJSON(): object
453
454 /**
455 * Convert string index to line/column.
456 *
457 * @param index The symbol number in the node’s string.
458 * @return Symbol position in file.
459 */
460 positionInside(index: number): Position
461
462 /**
463 * Get the position for a word or an index inside the node.
464 *
465 * @param opts Options.
466 * @return Position.
467 */
468 positionBy(opts?: Pick<WarningOptions, 'word' | 'index'>): Position
469
470 /**
471 * Get the range for a word or start and end index inside the node.
472 * The start index is inclusive; the end index is exclusive.
473 *
474 * @param opts Options.
475 * @return Range.
476 */
477 rangeBy(opts?: Pick<WarningOptions, 'word' | 'index' | 'endIndex'>): Range
478}
479
\No newline at end of file