Skip to content

Commit

Permalink
Merge 11ccc85 into 89c3a11
Browse files Browse the repository at this point in the history
  • Loading branch information
tanhauhau committed Mar 15, 2019
2 parents 89c3a11 + 11ccc85 commit 29534c6
Show file tree
Hide file tree
Showing 3 changed files with 635 additions and 51 deletions.
82 changes: 70 additions & 12 deletions lib/rules/sort-styles.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@
const { astHelpers } = require('../util/stylesheet');

const {
getStyleDeclarations,
getStyleDeclarationsChunks,
getPropertiesChunks,
getStylePropertyIdentifier,
isStyleSheetDeclaration,
isEitherShortHand,
} = astHelpers;

//------------------------------------------------------------------------------
Expand All @@ -28,13 +30,55 @@ module.exports = (context) => {
const ignoreStyleProperties = options.ignoreStyleProperties;
const isValidOrder = order === 'asc' ? (a, b) => a <= b : (a, b) => a >= b;

function report(type, node, prev, current) {
const sourceCode = context.getSourceCode();

function sort(array) {
return [].concat(array).sort((a, b) => {
const identifierA = getStylePropertyIdentifier(a);
const identifierB = getStylePropertyIdentifier(b);

let sortOrder = 0;
if (isEitherShortHand(identifierA, identifierB)) {
return a.range[0] - b.range[0];
} else if (identifierA < identifierB) {
sortOrder = -1;
} else if (identifierA > identifierB) {
sortOrder = 1;
}
return sortOrder * (order === 'asc' ? 1 : -1);
});
}

function getActualRange(node) {
const range = [].concat(node.range);
range[0] = sourceCode
.getCommentsBefore(node)
.reduce((start, comment) => Math.min(start, comment.range[0]), range[0]);
return range;
}

function report(array, type, node, prev, current) {
const currentName = getStylePropertyIdentifier(current);
const prevName = getStylePropertyIdentifier(prev);
context.report({
node,
message: `Expected ${type} to be in ${order}ending order. '${currentName}' should be before '${prevName}'.`,
loc: current.key.loc,
fix(fixer) {
const sortedArray = sort(array);
return array
.map((item, i) => {
if (item !== sortedArray[i]) {
const actualRange = getActualRange(sortedArray[i]);
return fixer.replaceTextRange(
getActualRange(item),
sourceCode.text.slice(actualRange[0], actualRange[1])
);
}
return null;
})
.filter(Boolean);
},
});
}

Expand All @@ -50,8 +94,15 @@ module.exports = (context) => {
const prevName = getStylePropertyIdentifier(previous);
const currentName = getStylePropertyIdentifier(current);

if (
arrayName === 'style properties' &&
isEitherShortHand(prevName, currentName)
) {
return;
}

if (!isValidOrder(prevName, currentName)) {
return report(arrayName, node, previous, current);
return report(array, arrayName, node, previous, current);
}
}
}
Expand All @@ -62,26 +113,33 @@ module.exports = (context) => {
return;
}

const classDefinitions = getStyleDeclarations(node);
const classDefinitionsChunks = getStyleDeclarationsChunks(node);

if (!ignoreClassNames) {
checkIsSorted(classDefinitions, 'class names', node);
classDefinitionsChunks.forEach((classDefinitions) => {
checkIsSorted(classDefinitions, 'class names', node);
});
}

if (ignoreStyleProperties) return;

classDefinitions.forEach((classDefinition) => {
const styleProperties = classDefinition.value.properties;
if (!styleProperties || styleProperties.length < 2) {
return;
}

checkIsSorted(styleProperties, 'style properties', node);
classDefinitionsChunks.forEach((classDefinitions) => {
classDefinitions.forEach((classDefinition) => {
const styleProperties = classDefinition.value.properties;
if (!styleProperties || styleProperties.length < 2) {
return;
}
const stylePropertyChunks = getPropertiesChunks(styleProperties);
stylePropertyChunks.forEach((stylePropertyChunk) => {
checkIsSorted(stylePropertyChunk, 'style properties', node);
});
});
});
},
};
};

module.exports.fixable = 'code';
module.exports.schema = [
{
enum: ['asc', 'desc'],
Expand Down
66 changes: 58 additions & 8 deletions lib/util/stylesheet.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,32 +127,72 @@ const astHelpers = {
},

getStyleSheetName: function (node) {
if (node && node.id) {
return node.id.name;
}
},

getStyleDeclarations: function (node) {
if (
node &&
node.id
node.init &&
node.init.arguments &&
node.init.arguments[0] &&
node.init.arguments[0].properties
) {
return node.id.name;
return node.init.arguments[0].properties.filter(property => property.type === 'Property');
}

return [];
},

getStyleDeclarations: function (node) {
getStyleDeclarationsChunks: function (node) {
if (
node &&
node.init &&
node.init.arguments &&
node.init.arguments[0] &&
node.init.arguments[0].properties
) {
return node
.init
.arguments[0]
.properties
.filter(property => property.type === 'Property');
const properties = node.init.arguments[0].properties;
const result = [];
let chunk = [];
for (let i = 0; i < properties.length; i += 1) {
const property = properties[i];
if (property.type === 'Property') {
chunk.push(property);
} else if (chunk.length) {
result.push(chunk);
chunk = [];
}
}
if (chunk.length) {
result.push(chunk);
}
return result;
}

return [];
},

getPropertiesChunks: function (properties) {
const result = [];
let chunk = [];
for (let i = 0; i < properties.length; i += 1) {
const property = properties[i];
if (property.type === 'Property') {
chunk.push(property);
} else if (chunk.length) {
result.push(chunk);
chunk = [];
}
}
if (chunk.length) {
result.push(chunk);
}
return result;
},

getExpressionIdentifier: function (node) {
if (node) {
switch (node.type) {
Expand Down Expand Up @@ -437,6 +477,16 @@ const astHelpers = {
return [node.object.name, node.property.name].join('.');
}
},

isEitherShortHand: function (property1, property2) {
const shorthands = ['margin', 'padding', 'border', 'flex'];
if (shorthands.includes(property1)) {
return property2.startsWith(property1);
} else if (shorthands.includes(property2)) {
return property1.startsWith(property2);
}
return false;
},
};

module.exports.astHelpers = astHelpers;
Expand Down

0 comments on commit 29534c6

Please sign in to comment.