web 3d图形渲染器
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

585 lines
13 KiB

  1. # API Documentation
  2. *Please use only this documented API when working with the parser. Methods
  3. not documented here are subject to change at any point.*
  4. <!-- toc -->
  5. - [`parser` function](#parser-function)
  6. * [`parser.atword([props])`](#parseratwordprops)
  7. * [`parser.colon([props])`](#parsercolonprops)
  8. * [`parser.comma([props])`](#parsercommaprops)
  9. * [`parser.comment([props])`](#parsercommentprops)
  10. * [`parser.func([props])`](#parserfuncprops)
  11. * [`parser.number([props])`](#parsernumberprops)
  12. * [`parser.operator([props])`](#parseroperatorprops)
  13. * [`parser.paren([props])`](#parserparenprops)
  14. * [`parser.string([props])`](#parserstringprops)
  15. * [`parser.value([props])`](#parservalueprops)
  16. * [`parser.word([props])`](#parserwordprops)
  17. * [`parser.unicodeRange([props])`](#parserunicoderangeprops)
  18. - [Node types](#node-types)
  19. * [`node.type`](#nodetype)
  20. * [`node.parent`](#nodeparent)
  21. * [`node.toString()`, `String(node)`, or `'' + node`](#nodetostring-stringnode-or---node)
  22. * [`node.next()` & `node.prev()`](#nodenext--nodeprev)
  23. * [`node.replaceWith(node)`](#nodereplacewithnode)
  24. * [`node.remove()`](#noderemove)
  25. * [`node.clone()`](#nodeclone)
  26. * [`node.raws`](#noderaws)
  27. * [`node.source`](#nodesource)
  28. * [`node.sourceIndex`](#nodesourceindex)
  29. - [Container types](#container-types)
  30. * [`container.nodes`](#containernodes)
  31. * [`container.first` & `container.last`](#containerfirst--containerlast)
  32. * [`container.at(index)`](#containeratindex)
  33. * [`container.index(node)`](#containerindexnode)
  34. * [`container.length`](#containerlength)
  35. * [`container.each(callback)`](#containereachcallback)
  36. * [`container.walk(callback)`](#containerwalkcallback)
  37. * [`container.walk` proxies](#containerwalk-proxies)
  38. * [`container.prepend(node)` & `container.append(node)`](#containerprependnode--containerappendnode)
  39. * [`container.insertBefore(old, new)` & `container.insertAfter(old, new)`](#containerinsertbeforeold-new--containerinsertafterold-new)
  40. * [`container.removeChild(node)`](#containerremovechildnode)
  41. * [`container.removeAll()` or `container.empty()`](#containerremoveall-or-containerempty)
  42. - [Root nodes`](#root-nodes)
  43. - [Value nodes](#value-nodes)
  44. <!-- tocstop -->
  45. ## `parser` function
  46. This is the module's main entry point, and returns a `new Parser`.
  47. ```js
  48. let parser = require('postcss-values-parser');
  49. let ast = parser(source) // tokenizes the source string
  50. .parse(); // parses the tokens and returns an AST
  51. ```
  52. ### `parser.atword([props])`
  53. Creates a new AtWord value.
  54. ```js
  55. parser.atword({ value: '@foo' });
  56. // → @foo
  57. ```
  58. Arguments:
  59. * `props (object)`: The new node's properties.
  60. ### `parser.colon([props])`
  61. Creates a new colon Node.
  62. ```js
  63. parser.colon({ value: ':' });
  64. // → :
  65. ```
  66. Arguments:
  67. * `props (object)`: The new node's properties. If no properties are specified,
  68. the default value of `:` will be used. It's not recommended to deviate from this.
  69. ### `parser.comma([props])`
  70. Creates a new comma Node.
  71. ```js
  72. parser.comma({ value: ',' });
  73. // → ,
  74. ```
  75. Arguments:
  76. * `props (object)`: The new node's properties. If no properties are specified,
  77. the default value of `,` will be used. It's not recommended to deviate from this.
  78. ### `parser.comment([props])`
  79. Creates a new comment.
  80. ```js
  81. parser.comment({ value: 'Affirmative, Dave. I read you.' });
  82. // → /* Affirmative, Dave. I read you. */
  83. ```
  84. ```js
  85. parser.comment({ value: 'Affirmative, Dave. I read you.', inline: true });
  86. // → // Affirmative, Dave. I read you.
  87. ```
  88. Arguments:
  89. * `props (object)`: The new node's properties.
  90. ### `parser.func([props])`
  91. Creates a new function value Container node.
  92. ```js
  93. let func = parser.func({ value: 'calc' });
  94. func.append(parser.paren());
  95. func.append(parser.paren({ value: ')' }));
  96. func.toString();
  97. // → calc()
  98. ```
  99. Arguments:
  100. * `props (object)`: The new node's properties.
  101. ### `parser.number([props])`
  102. Creates a new number Node.
  103. ```js
  104. parser.number({ value: 10, unit: 'px' });
  105. // → 10px
  106. ```
  107. Arguments:
  108. * `props (object)`: The new node's properties.
  109. ### `parser.operator([props])`
  110. Creates a new operator Node.
  111. ```js
  112. parser.operator({ value: '+' });
  113. // → +
  114. ```
  115. Arguments:
  116. * `props (object)`: The new node's properties.
  117. ### `parser.paren([props])`
  118. Creates a new parenthesis Node.
  119. ```js
  120. parser.paren();
  121. // → (
  122. parser.paren({ value: ')' });
  123. // → )
  124. ```
  125. Arguments:
  126. * `props (object)`: The new node's properties. If no value is specified, the
  127. default value of `(` will be used.
  128. ### `parser.string([props])`
  129. Creates a new string node.
  130. ```js
  131. parser.string();
  132. // → (empty)
  133. parser.string({ value: 'hello', quote: '"' });
  134. // → "hello"
  135. ```
  136. Arguments:
  137. * `props (object)`: The new node's properties. Note: If no `quote` property is
  138. specified, the default value of `'` will be used.
  139. ### `parser.value([props])`
  140. Creates a new value Node. This node acts as the container for all values within
  141. the Root node, but can be created for convenience.
  142. ### `parser.word([props])`
  143. Creates a new word Node. A `Word` is anything that doesn't fall into one of the
  144. other node types.
  145. ```js
  146. let word = parser.word({ value: '#fff' });
  147. // → #fff
  148. word.isHex;
  149. // → true
  150. word.isColor;
  151. // → true
  152. ```
  153. Arguments:
  154. * `props (object)`: The new node's properties.
  155. ### `parser.unicodeRange([props])`
  156. Creates a new unicode range Node.
  157. ```js
  158. parser.unicodeRange({ value: 'U+26' });
  159. // → U+26
  160. ```
  161. Arguments:
  162. * `props (object)`: The new node's properties.
  163. ## Node types
  164. ### `node.type`
  165. A string representation of the node type. It can be one of the following;
  166. `atword`, `colon`, `comma`, `comment`, `func`, `number`, `operator`,
  167. `paren`, `string`, `unicoderange`, `value`, `word`.
  168. ```js
  169. parser.word({ value: '#fff' }).type;
  170. // → 'word'
  171. ```
  172. ### `node.parent`
  173. Returns the parent node.
  174. ```js
  175. root.nodes[0].parent === root;
  176. ```
  177. ### `node.toString()`, `String(node)`, or `'' + node`
  178. Returns a string representation of the node.
  179. ```js
  180. let color = parser.word({ value: '#fff' });
  181. console.log(String(color));
  182. // → #fff
  183. ```
  184. ### `node.next()` & `node.prev()`
  185. Returns the next/previous child of the parent node.
  186. ```js
  187. let next = func.next();
  188. if (next && next.type !== 'paren') {
  189. throw new Error('Unclosed function parenthesis!');
  190. }
  191. ```
  192. ### `node.replaceWith(node)`
  193. Replace a node with another.
  194. ```js
  195. let ast = parser('#fff').parse();
  196. let word = ast.first.first;
  197. let atword = parser.atword({ value: '@purple' });
  198. word.replaceWith(atword);
  199. ```
  200. Arguments:
  201. * `node`: The node to substitute the original with.
  202. ### `node.remove()`
  203. Removes the node from its parent node.
  204. ```js
  205. if (node.type === 'word') {
  206. node.remove();
  207. }
  208. ```
  209. ### `node.clone()`
  210. Returns a copy of a node, detached from any parent containers that the
  211. original might have had.
  212. ```js
  213. let word = parser.word({ value: '#fff' });
  214. let cloned = word.clone();
  215. cloned.value = '#fff';
  216. String(cloned);
  217. // → #000
  218. String(word);
  219. // → #fff
  220. ```
  221. ### `node.raws`
  222. Extra whitespaces around the node will be assigned to `node.raws.before` and
  223. `node.raws.after`. Spaces in this context have no semantic meaning, but may
  224. be useful for inspection:
  225. ```css
  226. 1px solid black
  227. ```
  228. Any space following a node/segement is assigned to the next node's
  229. `raws.before` property, unless the node with the trailing space is the only
  230. node in the set.
  231. ```js
  232. let source = 'calc(something about mary)';
  233. let ast = parser(source).parse();
  234. let func = ast.first.first;
  235. let something = func.first.next();
  236. let about = something.next();
  237. something.raws.after;
  238. // → (empty)
  239. about.raws.before;
  240. // → ' '
  241. ```
  242. Additionally, any space remaining after the last node in a
  243. set will be assigned to the last non-symbol child's `raws.after` property.
  244. For example:
  245. ```js
  246. let source = 'calc(something )';
  247. let ast = parser(source).parse();
  248. let func = ast.first.first;
  249. let something = func.first.next();
  250. something.raws.after;
  251. // → ' '
  252. ```
  253. ### `node.source`
  254. An object describing the node's start/end, line/column source position.
  255. Within the following CSS, the `.bar` class node ...
  256. ```css
  257. .foo,
  258. .bar {}
  259. ```
  260. ... will contain the following `source` object.
  261. ```js
  262. source: {
  263. start: {
  264. line: 2,
  265. column: 3
  266. },
  267. end: {
  268. line: 2,
  269. column: 6
  270. }
  271. }
  272. ```
  273. ### `node.sourceIndex`
  274. The zero-based index of the node within the original source string.
  275. Within the following CSS, the `.baz` class node will have a `sourceIndex` of `12`.
  276. ```css
  277. .foo, .bar, .baz {}
  278. ```
  279. ## Container types
  280. The `root`, `node`, and `pseudo` nodes have some helper methods for working
  281. with their children.
  282. ### `container.nodes`
  283. An array of the container's children.
  284. ```js
  285. // Input: h1 h2
  286. nodes.at(0).nodes.length // → 3
  287. nodes.at(0).nodes[0].value // → 'h1'
  288. nodes.at(0).nodes[1].value // → ' '
  289. ```
  290. ### `container.first` & `container.last`
  291. The first/last child of the container.
  292. ```js
  293. node.first === node.nodes[0];
  294. node.last === node.nodes[node.nodes.length - 1];
  295. ```
  296. ### `container.at(index)`
  297. Returns the node at position `index`.
  298. ```js
  299. node.at(0) === node.first;
  300. node.at(0) === node.nodes[0];
  301. ```
  302. Arguments:
  303. * `index`: The index of the node to return.
  304. ### `container.index(node)`
  305. Return the index of the node within its container.
  306. ```js
  307. node.index(node.nodes[2]) // → 2
  308. ```
  309. Arguments:
  310. * `node`: A node within the current container.
  311. ### `container.length`
  312. Proxy to the length of the container's nodes.
  313. ```js
  314. container.length === container.nodes.length
  315. ```
  316. ### `container.each(callback)`
  317. Iterate the container's immediate children, calling `callback` for each child.
  318. You may return `false` within the callback to break the iteration.
  319. ```js
  320. let className;
  321. nodes.each(function (node, index) {
  322. if (node.type === 'class') {
  323. className = node.value;
  324. return false;
  325. }
  326. });
  327. ```
  328. Note that unlike `Array#forEach()`, this iterator is safe to use whilst adding
  329. or removing nodes from the container.
  330. Arguments:
  331. * `callback (function)`: A function to call for each node, which receives `node`
  332. and `index` arguments.
  333. ### `container.walk(callback)`
  334. Like `container#each`, but will also iterate child nodes as long as they are
  335. `container` types.
  336. ```js
  337. nodes.walk(function (node, index) {
  338. // all nodes
  339. });
  340. ```
  341. Arguments:
  342. * `callback (function)`: A function to call for each node, which receives `node`
  343. and `index` arguments.
  344. This iterator is safe to use whilst mutating `container.nodes`,
  345. like `container#each`.
  346. ### `container.walk` proxies
  347. The container class provides proxy methods for iterating over types of nodes,
  348. so that it is easier to write modules that target specific nodes. Those
  349. methods are:
  350. * `container.walkAtWords`
  351. * `container.walkColons`
  352. * `container.walkCommas`
  353. * `container.walkComments`
  354. * `container.walkFunctionNodes`
  355. * `container.walkNumberNodes`
  356. * `container.walkOperators`
  357. * `container.walkParenthesis`
  358. * `container.walkStringNodes`
  359. * `container.walkUnicodeRanges`
  360. * `container.walkWords`
  361. ### `container.prepend(node)` & `container.append(node)`
  362. Add a node to the start/end of the container. Note that doing so will set
  363. the parent property of the node to this container.
  364. ```js
  365. let color = parser.word({ value: '#fff' });
  366. node.append(color);
  367. ```
  368. Arguments:
  369. * `node`: The node to add.
  370. ### `container.insertBefore(old, new)` & `container.insertAfter(old, new)`
  371. Add a node before or after an existing node in a container:
  372. ```js
  373. nodes.walk(function (node) {
  374. if (node.type !== 'word') {
  375. let colon = parser.colon();
  376. node.parent.insertAfter(node, colon);
  377. }
  378. });
  379. ```
  380. Arguments:
  381. * `old`: The existing node in the container.
  382. * `new`: The new node to add before/after the existing node.
  383. ### `container.removeChild(node)`
  384. Remove the node from the container. Note that you can also use
  385. `node.remove()` if you would like to remove just a single node.
  386. ```js
  387. node.length // → 2
  388. node.remove(word)
  389. node.length // → 1;
  390. word.parent // undefined
  391. ```
  392. Arguments:
  393. * `node`: The node to remove.
  394. ### `container.removeAll()` or `container.empty()`
  395. Remove all children from the container.
  396. ```js
  397. node.removeAll();
  398. node.length // → 0
  399. ```
  400. ## Root nodes`
  401. A root node represents the top-level Container for Value nodes. Indeed, all
  402. a root's `toString()` method does is join its node children with a ','.
  403. Other than this, it has no special functionality and acts like a container.
  404. ## Value nodes
  405. A Value node represents a single compound node. For example, this
  406. node string `1px solid black`, is represented as three distinct nodes.
  407. It has no special functionality of its own.