Skip to content

Added support for embedded rulesets. Resolves #336. #338

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jan 17, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/cli/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ function cli(api){
if (ignore) {
ruleset = CSSLint.getRuleset();
ignore.split(",").forEach(function(value){
delete ruleset[value];
ruleset[value] = 0;
});
}

Expand Down
85 changes: 63 additions & 22 deletions src/core/CSSLint.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@
/*global parserlib, Reporter*/
var CSSLint = (function(){

var rules = [],
formatters = [],
api = new parserlib.util.EventTarget();

var rules = [],
formatters = [],
embeddedRuleset = /\/\*csslint([^\*]*)\*\//,
api = new parserlib.util.EventTarget();

api.version = "@VERSION@";

//-------------------------------------------------------------------------
Expand All @@ -34,18 +35,18 @@ var CSSLint = (function(){
api.clearRules = function(){
rules = [];
};

/**
* Returns the rule objects.
* @return An array of rule objects.
* @method getRules
*/
api.getRules = function(){
return [].concat(rules).sort(function(a,b){
return [].concat(rules).sort(function(a,b){
return a.id > b.id ? 1 : 0;
});
};

/**
* Returns a ruleset configuration object with all current rules.
* @return A ruleset object.
Expand All @@ -55,14 +56,49 @@ var CSSLint = (function(){
var ruleset = {},
i = 0,
len = rules.length;

while (i < len){
ruleset[rules[i++].id] = 1; //by default, everything is a warning
}

return ruleset;
};

/**
* Returns a ruleset object based on embedded rules.
* @param {String} text A string of css containing embedded rules.
* @param {Object} ruleset A ruleset object to modify.
* @return {Object} A ruleset object.
* @method getEmbeddedRuleset
*/
function applyEmbeddedRuleset(text, ruleset){
var valueMap,
embedded = text && text.match(embeddedRuleset),
rules = embedded && embedded[1];

if (rules) {
valueMap = {
"true": 2, // true is error
"": 1, // blank is warning
"false": 0, // false is ignore

"2": 2, // explicit error
"1": 1, // explicit warning
"0": 0 // explicit ignore
};

rules.toLowerCase().split(",").forEach(function(rule){
var pair = rule.split(":"),
property = pair[0] || "",
value = pair[1] || "";

ruleset[property.trim()] = valueMap[value.trim()];
});
}

return ruleset;
}

//-------------------------------------------------------------------------
// Formatters
//-------------------------------------------------------------------------
Expand All @@ -76,7 +112,7 @@ var CSSLint = (function(){
// formatters.push(formatter);
formatters[formatter.id] = formatter;
};

/**
* Retrieves a formatter for use.
* @param {String} formatId The name of the format to retrieve.
Expand All @@ -86,7 +122,7 @@ var CSSLint = (function(){
api.getFormatter = function(formatId){
return formatters[formatId];
};

/**
* Formats the results in a particular format for a single file.
* @param {Object} result The results returned from CSSLint.verify().
Expand All @@ -99,16 +135,16 @@ var CSSLint = (function(){
api.format = function(results, filename, formatId, options) {
var formatter = this.getFormatter(formatId),
result = null;

if (formatter){
result = formatter.startFormat();
result += formatter.formatResults(results, filename, options || {});
result += formatter.endFormat();
}

return result;
};

/**
* Indicates if the given format is supported.
* @param {String} formatId The ID of the format to check.
Expand Down Expand Up @@ -144,16 +180,20 @@ var CSSLint = (function(){

// normalize line endings
lines = text.replace(/\n\r?/g, "$split$").split('$split$');

if (!ruleset){
ruleset = this.getRuleset();
}


if (embeddedRuleset.test(text)){
ruleset = applyEmbeddedRuleset(text, ruleset);
}

reporter = new Reporter(lines, ruleset);

ruleset.errors = 2; //always report parsing errors as errors
for (i in ruleset){
if(ruleset.hasOwnProperty(i)){
if(ruleset.hasOwnProperty(i) && ruleset[i]){
if (rules[i]){
rules[i].init(parser, reporter);
}
Expand All @@ -170,9 +210,10 @@ var CSSLint = (function(){

report = {
messages : reporter.messages,
stats : reporter.stats
stats : reporter.stats,
ruleset : reporter.ruleset
};

//sort by line numbers, rollups at the bottom
report.messages.sort(function (a, b){
if (a.rollup && !b.rollup){
Expand All @@ -182,8 +223,8 @@ var CSSLint = (function(){
} else {
return a.line - b.line;
}
});
});

return report;
};

Expand Down
11 changes: 11 additions & 0 deletions tests/core/CSSLint.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,17 @@
"@media (max-width:400px) should not cause an error": function(){
var result = CSSLint.verify("@media (max-width:400px) {}", { });
Assert.areEqual(0, result.messages.length);
},

"Embedded ruleset should be honored": function(){
var result = CSSLint.verify("/*csslint bogus, adjoining-classes:true, box-sizing:false */\n.foo.bar{}", {
'text-indent': 1,
'box-sizing': 1
});

Assert.areEqual(2, result.ruleset['adjoining-classes']);
Assert.areEqual(1, result.ruleset['text-indent']);
Assert.areEqual(0, result.ruleset['box-sizing']);
}

}));
Expand Down