checkEmptyLineBefore.js 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. let stylelint = require('stylelint');
  2. const { isString } = require('../../utils/validateType');
  3. let addEmptyLineBefore = require('./addEmptyLineBefore');
  4. let hasEmptyLineBefore = require('./hasEmptyLineBefore');
  5. let removeEmptyLinesBefore = require('./removeEmptyLinesBefore');
  6. let ruleName = require('./ruleName');
  7. let messages = require('./messages');
  8. module.exports = function checkEmptyLineBefore({
  9. firstPropData,
  10. secondPropData,
  11. propsCount,
  12. lastKnownSeparatedGroup,
  13. context,
  14. emptyLineBeforeUnspecified,
  15. emptyLineMinimumPropertyThreshold,
  16. isFixEnabled,
  17. primaryOption,
  18. result,
  19. }) {
  20. let firstPropIsSpecified = Boolean(firstPropData.orderData);
  21. let secondPropIsSpecified = Boolean(secondPropData.orderData);
  22. // Check newlines between groups
  23. let firstPropGroup = firstPropIsSpecified
  24. ? firstPropData.orderData.separatedGroup
  25. : lastKnownSeparatedGroup;
  26. let secondPropGroup = secondPropIsSpecified
  27. ? secondPropData.orderData.separatedGroup
  28. : lastKnownSeparatedGroup;
  29. // eslint-disable-next-line no-param-reassign
  30. lastKnownSeparatedGroup = secondPropGroup;
  31. let startOfSpecifiedGroup = secondPropIsSpecified && firstPropGroup !== secondPropGroup;
  32. let startOfUnspecifiedGroup = firstPropIsSpecified && !secondPropIsSpecified;
  33. if (startOfSpecifiedGroup || startOfUnspecifiedGroup) {
  34. // Get an array of just the property groups, remove any solo properties
  35. let groups = primaryOption.filter((item) => !isString(item));
  36. let emptyLineBefore =
  37. groups[secondPropGroup - 2] && groups[secondPropGroup - 2].emptyLineBefore;
  38. if (startOfUnspecifiedGroup) {
  39. emptyLineBefore = emptyLineBeforeUnspecified;
  40. }
  41. // Threshold logic
  42. let belowEmptyLineThreshold = propsCount < emptyLineMinimumPropertyThreshold;
  43. let emptyLineThresholdInsertLines =
  44. emptyLineBefore === 'threshold' && !belowEmptyLineThreshold;
  45. let emptyLineThresholdRemoveLines =
  46. emptyLineBefore === 'threshold' && belowEmptyLineThreshold;
  47. if (
  48. (emptyLineBefore === 'always' || emptyLineThresholdInsertLines) &&
  49. !hasEmptyLineBefore(secondPropData.node)
  50. ) {
  51. if (isFixEnabled) {
  52. addEmptyLineBefore(secondPropData.node, context.newline);
  53. } else {
  54. stylelint.utils.report({
  55. message: messages.expectedEmptyLineBefore(secondPropData.name),
  56. node: secondPropData.node,
  57. result,
  58. ruleName,
  59. });
  60. }
  61. } else if (
  62. (emptyLineBefore === 'never' || emptyLineThresholdRemoveLines) &&
  63. hasEmptyLineBefore(secondPropData.node)
  64. ) {
  65. if (isFixEnabled) {
  66. removeEmptyLinesBefore(secondPropData.node, context.newline);
  67. } else {
  68. stylelint.utils.report({
  69. message: messages.rejectedEmptyLineBefore(secondPropData.name),
  70. node: secondPropData.node,
  71. result,
  72. ruleName,
  73. });
  74. }
  75. }
  76. }
  77. // Check newlines between properties inside a group
  78. if (
  79. firstPropIsSpecified &&
  80. secondPropIsSpecified &&
  81. firstPropData.orderData.groupPosition === secondPropData.orderData.groupPosition
  82. ) {
  83. if (
  84. secondPropData.orderData.noEmptyLineBeforeInsideGroup &&
  85. hasEmptyLineBefore(secondPropData.node)
  86. ) {
  87. if (isFixEnabled) {
  88. removeEmptyLinesBefore(secondPropData.node, context.newline);
  89. } else {
  90. stylelint.utils.report({
  91. message: messages.rejectedEmptyLineBefore(secondPropData.name),
  92. node: secondPropData.node,
  93. result,
  94. ruleName,
  95. });
  96. }
  97. }
  98. }
  99. };