checkNodeForOrder.js 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. const stylelint = require('stylelint');
  2. const postcss = require('postcss');
  3. const postcssSorting = require('postcss-sorting');
  4. const { isProperty } = require('../../utils');
  5. const checkOrder = require('./checkOrder');
  6. const getNodeData = require('./getNodeData');
  7. const createFlatOrder = require('./createFlatOrder');
  8. const ruleName = require('./ruleName');
  9. const messages = require('./messages');
  10. module.exports = function checkNodeForOrder({
  11. node,
  12. originalNode,
  13. isFixEnabled,
  14. primaryOption,
  15. unspecified,
  16. result,
  17. expectedOrder,
  18. }) {
  19. if (isFixEnabled) {
  20. let allPropertiesData = getAllPropertiesData(node);
  21. let shouldFixOrder = false;
  22. // Check if there order violation to avoid running re-ordering unnecessery
  23. allPropertiesData.forEach(function checkEveryPropForOrder2(propertyData, index) {
  24. // Skip first decl
  25. if (index === 0) {
  26. return;
  27. }
  28. // return early if we know there is a violation and auto fix should be applied
  29. if (shouldFixOrder) {
  30. return;
  31. }
  32. let previousPropertyData = allPropertiesData[index - 1];
  33. let checkedOrder = checkOrder({
  34. firstPropertyData: previousPropertyData,
  35. secondPropertyData: propertyData,
  36. unspecified,
  37. allPropertiesData: allPropertiesData.slice(0, index),
  38. });
  39. if (!checkedOrder.isCorrect) {
  40. shouldFixOrder = true;
  41. }
  42. });
  43. if (shouldFixOrder) {
  44. let sortingOptions = {
  45. 'properties-order': createFlatOrder(primaryOption),
  46. 'unspecified-properties-position':
  47. unspecified === 'ignore' ? 'bottom' : unspecified,
  48. };
  49. // creating PostCSS Root node with current node as a child,
  50. // so PostCSS Sorting can process it
  51. let tempRoot = postcss.root({ nodes: [originalNode] });
  52. postcssSorting(sortingOptions)(tempRoot);
  53. }
  54. }
  55. getAllPropertiesData(node).forEach((propertyData, index, listOfProperties) => {
  56. // Skip first decl
  57. if (index === 0) {
  58. return;
  59. }
  60. const previousPropertyData = listOfProperties[index - 1];
  61. const checkedOrder = checkOrder({
  62. firstPropertyData: previousPropertyData,
  63. secondPropertyData: propertyData,
  64. unspecified,
  65. allPropertiesData: listOfProperties.slice(0, index),
  66. });
  67. if (!checkedOrder.isCorrect) {
  68. const { orderData } = checkedOrder.secondNode;
  69. stylelint.utils.report({
  70. message: messages.expected(
  71. checkedOrder.secondNode.name,
  72. checkedOrder.firstNode.name,
  73. orderData && orderData.groupName
  74. ),
  75. node: checkedOrder.secondNode.node,
  76. result,
  77. ruleName,
  78. });
  79. }
  80. });
  81. function getAllPropertiesData(inputNode) {
  82. return inputNode.nodes
  83. .filter((item) => isProperty(item))
  84. .map((item) => getNodeData(item, expectedOrder));
  85. }
  86. };