node.d.ts 11 KB

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