checkNode.js 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. const stylelint = require('stylelint');
  2. const sortNode = require('postcss-sorting/lib/order/sortNode');
  3. const checkOrder = require('./checkOrder');
  4. const getOrderData = require('./getOrderData');
  5. const ruleName = require('./ruleName');
  6. const messages = require('./messages');
  7. module.exports = function checkNode({
  8. node,
  9. isFixEnabled,
  10. orderInfo,
  11. primaryOption,
  12. result,
  13. unspecified,
  14. }) {
  15. if (isFixEnabled) {
  16. let shouldFix = false;
  17. let allNodesData = [];
  18. node.each(function processEveryNode(child) {
  19. // return early if we know there is a violation and auto fix should be applied
  20. if (shouldFix) {
  21. return;
  22. }
  23. let { shouldSkip, isCorrectOrder } = handleCycle(child, allNodesData);
  24. if (shouldSkip) {
  25. return;
  26. }
  27. if (!isCorrectOrder) {
  28. shouldFix = true;
  29. }
  30. });
  31. if (shouldFix) {
  32. sortNode(node, primaryOption);
  33. }
  34. }
  35. let allNodesData = [];
  36. node.each(function processEveryNode(child) {
  37. let { shouldSkip, isCorrectOrder, nodeData, previousNodeData } = handleCycle(
  38. child,
  39. allNodesData
  40. );
  41. if (shouldSkip) {
  42. return;
  43. }
  44. if (isCorrectOrder) {
  45. return;
  46. }
  47. stylelint.utils.report({
  48. message: messages.expected(nodeData.description, previousNodeData.description),
  49. node: child,
  50. result,
  51. ruleName,
  52. });
  53. });
  54. function handleCycle(child, allNodes) {
  55. // Skip comments
  56. if (child.type === 'comment') {
  57. return {
  58. shouldSkip: true,
  59. };
  60. }
  61. // Receive node description and expectedPosition
  62. let nodeOrderData = getOrderData(orderInfo, child);
  63. let nodeData = {
  64. node: child,
  65. description: nodeOrderData.description,
  66. expectedPosition: nodeOrderData.expectedPosition,
  67. };
  68. allNodes.push(nodeData);
  69. let previousNodeData = allNodes[allNodes.length - 2]; // eslint-disable-line unicorn/prefer-at -- Need to support older Node.js
  70. // Skip first node
  71. if (!previousNodeData) {
  72. return {
  73. shouldSkip: true,
  74. };
  75. }
  76. return {
  77. isCorrectOrder: checkOrder({
  78. firstNodeData: previousNodeData,
  79. secondNodeData: nodeData,
  80. allNodesData: allNodes,
  81. isFixEnabled,
  82. result,
  83. unspecified,
  84. }),
  85. nodeData,
  86. previousNodeData,
  87. };
  88. }
  89. };