12
12
const { astHelpers } = require ( '../util/stylesheet' ) ;
13
13
14
14
const {
15
- getStyleDeclarations,
15
+ getStyleDeclarationsChunks,
16
+ getPropertiesChunks,
16
17
getStylePropertyIdentifier,
17
18
isStyleSheetDeclaration,
19
+ isEitherShortHand,
18
20
} = astHelpers ;
19
21
20
22
//------------------------------------------------------------------------------
@@ -28,13 +30,54 @@ module.exports = (context) => {
28
30
const ignoreStyleProperties = options . ignoreStyleProperties ;
29
31
const isValidOrder = order === 'asc' ? ( a , b ) => a <= b : ( a , b ) => a >= b ;
30
32
31
- function report ( type , node , prev , current ) {
33
+ const sourceCode = context . getSourceCode ( ) ;
34
+
35
+ function sort ( array ) {
36
+ return [ ] . concat ( array ) . sort ( ( a , b ) => {
37
+ const identifierA = getStylePropertyIdentifier ( a ) ;
38
+ const identifierB = getStylePropertyIdentifier ( b ) ;
39
+
40
+ let sortOrder = 0 ;
41
+ if ( isEitherShortHand ( identifierA , identifierB ) ) {
42
+ return a . range [ 0 ] - b . range [ 0 ] ;
43
+ } else if ( identifierA < identifierB ) {
44
+ sortOrder = - 1 ;
45
+ } else if ( identifierA > identifierB ) {
46
+ sortOrder = 1 ;
47
+ }
48
+ return sortOrder * ( order === 'asc' ? 1 : - 1 ) ;
49
+ } ) ;
50
+ }
51
+
52
+ function report ( array , type , node , prev , current ) {
32
53
const currentName = getStylePropertyIdentifier ( current ) ;
33
54
const prevName = getStylePropertyIdentifier ( prev ) ;
55
+ const hasComments = array
56
+ . map ( prop => sourceCode . getComments ( prop ) )
57
+ . reduce (
58
+ ( hasComment , comment ) =>
59
+ hasComment || comment . leading . length > 0 || comment . trailing > 0 ,
60
+ false
61
+ ) ;
62
+
34
63
context . report ( {
35
64
node,
36
65
message : `Expected ${ type } to be in ${ order } ending order. '${ currentName } ' should be before '${ prevName } '.` ,
37
66
loc : current . key . loc ,
67
+ fix : hasComments ? undefined : ( fixer ) => {
68
+ const sortedArray = sort ( array ) ;
69
+ return array
70
+ . map ( ( item , i ) => {
71
+ if ( item !== sortedArray [ i ] ) {
72
+ return fixer . replaceText (
73
+ item ,
74
+ sourceCode . getText ( sortedArray [ i ] )
75
+ ) ;
76
+ }
77
+ return null ;
78
+ } )
79
+ . filter ( Boolean ) ;
80
+ } ,
38
81
} ) ;
39
82
}
40
83
@@ -50,8 +93,15 @@ module.exports = (context) => {
50
93
const prevName = getStylePropertyIdentifier ( previous ) ;
51
94
const currentName = getStylePropertyIdentifier ( current ) ;
52
95
96
+ if (
97
+ arrayName === 'style properties' &&
98
+ isEitherShortHand ( prevName , currentName )
99
+ ) {
100
+ return ;
101
+ }
102
+
53
103
if ( ! isValidOrder ( prevName , currentName ) ) {
54
- return report ( arrayName , node , previous , current ) ;
104
+ return report ( array , arrayName , node , previous , current ) ;
55
105
}
56
106
}
57
107
}
@@ -62,26 +112,33 @@ module.exports = (context) => {
62
112
return ;
63
113
}
64
114
65
- const classDefinitions = getStyleDeclarations ( node ) ;
115
+ const classDefinitionsChunks = getStyleDeclarationsChunks ( node ) ;
66
116
67
117
if ( ! ignoreClassNames ) {
68
- checkIsSorted ( classDefinitions , 'class names' , node ) ;
118
+ classDefinitionsChunks . forEach ( ( classDefinitions ) => {
119
+ checkIsSorted ( classDefinitions , 'class names' , node ) ;
120
+ } ) ;
69
121
}
70
122
71
123
if ( ignoreStyleProperties ) return ;
72
124
73
- classDefinitions . forEach ( ( classDefinition ) => {
74
- const styleProperties = classDefinition . value . properties ;
75
- if ( ! styleProperties || styleProperties . length < 2 ) {
76
- return ;
77
- }
78
-
79
- checkIsSorted ( styleProperties , 'style properties' , node ) ;
125
+ classDefinitionsChunks . forEach ( ( classDefinitions ) => {
126
+ classDefinitions . forEach ( ( classDefinition ) => {
127
+ const styleProperties = classDefinition . value . properties ;
128
+ if ( ! styleProperties || styleProperties . length < 2 ) {
129
+ return ;
130
+ }
131
+ const stylePropertyChunks = getPropertiesChunks ( styleProperties ) ;
132
+ stylePropertyChunks . forEach ( ( stylePropertyChunk ) => {
133
+ checkIsSorted ( stylePropertyChunk , 'style properties' , node ) ;
134
+ } ) ;
135
+ } ) ;
80
136
} ) ;
81
137
} ,
82
138
} ;
83
139
} ;
84
140
141
+ module . exports . fixable = 'code' ;
85
142
module . exports . schema = [
86
143
{
87
144
enum : [ 'asc' , 'desc' ] ,
0 commit comments