Block.js 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. var TYPE = require('../../tokenizer').TYPE;
  2. var WHITESPACE = TYPE.WhiteSpace;
  3. var COMMENT = TYPE.Comment;
  4. var SEMICOLON = TYPE.Semicolon;
  5. var ATRULE = TYPE.Atrule;
  6. var LEFTCURLYBRACKET = TYPE.LeftCurlyBracket;
  7. var RIGHTCURLYBRACKET = TYPE.RightCurlyBracket;
  8. function consumeRaw(startToken) {
  9. return this.Raw(startToken, 0, 0, false, true);
  10. }
  11. function consumeRule() {
  12. return this.parseWithFallback(this.Rule, consumeRaw);
  13. }
  14. function consumeRawDeclaration(startToken) {
  15. return this.Raw(startToken, 0, SEMICOLON, true, true);
  16. }
  17. function consumeDeclaration() {
  18. if (this.scanner.tokenType === SEMICOLON) {
  19. return consumeRawDeclaration.call(this, this.scanner.currentToken);
  20. }
  21. var node = this.parseWithFallback(this.Declaration, consumeRawDeclaration);
  22. if (this.scanner.tokenType === SEMICOLON) {
  23. this.scanner.next();
  24. }
  25. return node;
  26. }
  27. module.exports = {
  28. name: 'Block',
  29. structure: {
  30. children: [[
  31. 'Atrule',
  32. 'Rule',
  33. 'Declaration'
  34. ]]
  35. },
  36. parse: function(isDeclaration) {
  37. var consumer = isDeclaration ? consumeDeclaration : consumeRule;
  38. var start = this.scanner.tokenStart;
  39. var children = this.createList();
  40. this.scanner.eat(LEFTCURLYBRACKET);
  41. scan:
  42. while (!this.scanner.eof) {
  43. switch (this.scanner.tokenType) {
  44. case RIGHTCURLYBRACKET:
  45. break scan;
  46. case WHITESPACE:
  47. case COMMENT:
  48. this.scanner.next();
  49. break;
  50. case ATRULE:
  51. children.push(this.parseWithFallback(this.Atrule, consumeRaw));
  52. break;
  53. default:
  54. children.push(consumer.call(this));
  55. }
  56. }
  57. if (!this.scanner.eof) {
  58. this.scanner.eat(RIGHTCURLYBRACKET);
  59. }
  60. return {
  61. type: 'Block',
  62. loc: this.getLocation(start, this.scanner.tokenStart),
  63. children: children
  64. };
  65. },
  66. generate: function(node) {
  67. this.chunk('{');
  68. this.children(node, function(prev) {
  69. if (prev.type === 'Declaration') {
  70. this.chunk(';');
  71. }
  72. });
  73. this.chunk('}');
  74. },
  75. walkContext: 'block'
  76. };