sorting.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. const postcss = require('postcss');
  2. const _ = require('lodash');
  3. const shorthandData = require('./shorthandData');
  4. module.exports = {
  5. sortDeclarations,
  6. sortDeclarationsAlphabetically,
  7. sortByIndexes,
  8. };
  9. function sortDeclarations(a, b) {
  10. // If unprefixed prop names are the same, compare the prefixed versions
  11. if (a.node.type === 'decl' && b.node.type === 'decl' && a.unprefixedName === b.unprefixedName) {
  12. // If first property has no prefix and second property has prefix
  13. if (!postcss.vendor.prefix(a.name).length && postcss.vendor.prefix(b.name).length) {
  14. return 1;
  15. }
  16. if (postcss.vendor.prefix(a.name).length && !postcss.vendor.prefix(b.name).length) {
  17. return -1;
  18. }
  19. }
  20. if (!_.isUndefined(a.orderData) && !_.isUndefined(b.orderData)) {
  21. // If a and b have the same group index, and a's property index is
  22. // higher than b's property index, in a sorted list a appears after
  23. // b:
  24. if (a.orderData.propertyIndex !== b.orderData.propertyIndex) {
  25. return a.orderData.propertyIndex - b.orderData.propertyIndex;
  26. }
  27. }
  28. if (
  29. a.unspecifiedPropertiesPosition === 'bottom' ||
  30. a.unspecifiedPropertiesPosition === 'bottomAlphabetical' ||
  31. b.unspecifiedPropertiesPosition === 'bottomAlphabetical'
  32. ) {
  33. if (!_.isUndefined(a.orderData) && _.isUndefined(b.orderData)) {
  34. return -1;
  35. }
  36. if (_.isUndefined(a.orderData) && !_.isUndefined(b.orderData)) {
  37. return 1;
  38. }
  39. }
  40. if (a.unspecifiedPropertiesPosition === 'top') {
  41. if (!_.isUndefined(a.orderData) && _.isUndefined(b.orderData)) {
  42. return 1;
  43. }
  44. if (_.isUndefined(a.orderData) && !_.isUndefined(b.orderData)) {
  45. return -1;
  46. }
  47. }
  48. if (a.unspecifiedPropertiesPosition === 'bottomAlphabetical') {
  49. if (_.isUndefined(a.orderData) && _.isUndefined(b.orderData)) {
  50. return sortDeclarationsAlphabetically(a, b);
  51. }
  52. }
  53. // If a and b have the same group index and the same property index,
  54. // in a sorted list they appear in the same order they were in
  55. // original array:
  56. return a.initialIndex - b.initialIndex;
  57. }
  58. function isShorthand(a, b) {
  59. const longhands = shorthandData[a] || [];
  60. return longhands.includes(b);
  61. }
  62. function sortDeclarationsAlphabetically(a, b) {
  63. if (isShorthand(a.unprefixedName, b.unprefixedName)) {
  64. return -1;
  65. }
  66. if (isShorthand(b.unprefixedName, a.unprefixedName)) {
  67. return 1;
  68. }
  69. if (a.unprefixedName === b.unprefixedName) {
  70. if (a.node.type === 'decl' && b.node.type === 'decl') {
  71. // If first property has no prefix and second property has prefix
  72. if (!postcss.vendor.prefix(a.name).length && postcss.vendor.prefix(b.name).length) {
  73. return 1;
  74. }
  75. if (postcss.vendor.prefix(a.name).length && !postcss.vendor.prefix(b.name).length) {
  76. return -1;
  77. }
  78. }
  79. return a.initialIndex - b.initialIndex;
  80. }
  81. return a.unprefixedName <= b.unprefixedName ? -1 : 1;
  82. }
  83. function sortByIndexes(a, b) {
  84. // If a and b have the same group index, and a's property index is
  85. // higher than b's property index, in a sorted list a appears after
  86. // b:
  87. if (a.position !== b.position) {
  88. return a.position - b.position;
  89. }
  90. // If a and b have the same group index and the same property index,
  91. // in a sorted list they appear in the same order they were in
  92. // original array:
  93. return a.initialIndex - b.initialIndex;
  94. }