always-semicolon.js 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. var gonzales = require('gonzales-pe');
  2. module.exports = {
  3. name: 'always-semicolon',
  4. syntax: ['css', 'less', 'sass', 'scss'],
  5. accepts: { boolean: [true] },
  6. /**
  7. * Processes tree node.
  8. * @param {node} node
  9. */
  10. process: function(node) {
  11. var nodeWithoutSemicolon;
  12. if (!node.is('block')) return;
  13. mainLoop:
  14. for (var i = node.length; i--;) {
  15. var currentNode = node.get(i);
  16. // Skip nodes that already have `;` at the end:
  17. if (currentNode.is('declarationDelimiter')) break;
  18. // Add semicolon only after declarations and includes.
  19. // If current node is include, insert semicolon right into it.
  20. // If it's declaration, look for value node:
  21. if (currentNode.is('include')) {
  22. nodeWithoutSemicolon = currentNode;
  23. } else if (currentNode.is('declaration')) {
  24. nodeWithoutSemicolon = currentNode.last('value');
  25. } else {
  26. continue;
  27. }
  28. // Check if there are spaces and comments at the end of the node:
  29. for (var j = nodeWithoutSemicolon.length; j--; ) {
  30. var lastNode = nodeWithoutSemicolon.get(j);
  31. // If the node's last child is block, do not add semicolon:
  32. // TODO: Add syntax check and run the code only for scss
  33. if (lastNode.is('block')) {
  34. break mainLoop;
  35. } else if (!lastNode.is('space') &&
  36. !lastNode.is('multilineComment') &&
  37. !lastNode.is('singlelineComment')) {
  38. j++;
  39. break;
  40. }
  41. }
  42. var declDelim = gonzales.createNode({ type: 'declarationDelimiter', content: ';' });
  43. nodeWithoutSemicolon.insert(j, declDelim);
  44. break;
  45. }
  46. },
  47. /**
  48. * Detects the value of an option at the tree node.
  49. *
  50. * @param {node} node
  51. */
  52. detect: function(node) {
  53. if (!node.is('block')) return;
  54. for (var i = node.length; i--;) {
  55. var nodeItem = node.get(i);
  56. if (nodeItem.is('declarationDelimiter')) return true;
  57. if (nodeItem.is('declaration')) return false;
  58. }
  59. }
  60. };