node.d.ts 13 KB

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