Skip to content
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
22 changes: 20 additions & 2 deletions src/core/CSSLint.js
Original file line number Diff line number Diff line change
Expand Up @@ -177,13 +177,30 @@ var CSSLint = (function() {
var i = 0,
reporter,
lines,
allow = {},
report,
parser = new parserlib.css.Parser({ starHack: true, ieFilters: true,
underscoreHack: true, strict: false });

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

// find 'allow' comments
CSSLint.Util.forEach(lines, function (line, lineno) {
var allowLine = line && line.match(/\/\*[ \t]*csslint[ \t]+allow:[ \t]*([^\*]*)\*\//i),
allowRules = allowLine && allowLine[1],
allowRuleset = {};

if (allowRules) {
allowRules.toLowerCase().split(",").forEach(function(allowRule){
allowRuleset[allowRule.trim()] = true;
});
if (Object.keys(allowRuleset).length > 0) {
allow[lineno + 1] = allowRuleset;
}
}
});

if (!ruleset) {
ruleset = this.getRuleset();
}
Expand All @@ -194,7 +211,7 @@ var CSSLint = (function() {
ruleset = applyEmbeddedRuleset(text, ruleset);
}

reporter = new Reporter(lines, ruleset);
reporter = new Reporter(lines, ruleset, allow);

ruleset.errors = 2; //always report parsing errors as errors
for (i in ruleset) {
Expand All @@ -216,7 +233,8 @@ var CSSLint = (function() {
report = {
messages : reporter.messages,
stats : reporter.stats,
ruleset : reporter.ruleset
ruleset : reporter.ruleset,
allow : reporter.allow
};

//sort by line numbers, rollups at the bottom
Expand Down
18 changes: 17 additions & 1 deletion src/core/Reporter.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* @param {Object} ruleset The set of rules to work with, including if
* they are errors or warnings.
*/
function Reporter(lines, ruleset) {
function Reporter(lines, ruleset, allow) {
"use strict";

/**
Expand Down Expand Up @@ -39,6 +39,16 @@ function Reporter(lines, ruleset) {
* @type Object
*/
this.ruleset = ruleset;

/**
* Lines with specific rule messages to leave out of the report.
* @property allow
* @type Object
*/
this.allow = allow;
if(!this.allow) {
this.allow = {};
}
}

Reporter.prototype = {
Expand Down Expand Up @@ -90,6 +100,12 @@ Reporter.prototype = {
*/
report: function(message, line, col, rule) {
"use strict";

// Check if rule violation should be allowed
if (this.allow.hasOwnProperty(line) && this.allow[line].hasOwnProperty(rule.id)) {
return;
}

this.messages.push({
type : this.ruleset[rule.id] === 2 ? "error" : "warning",
line : line,
Expand Down
21 changes: 21 additions & 0 deletions tests/core/CSSLint.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,27 @@
Assert.areEqual(2, result.ruleset["adjoining-classes"]);
Assert.areEqual(1, result.ruleset["text-indent"]);
Assert.areEqual(0, result.ruleset["box-sizing"]);
},

"Allow statement on one line with one rule should be added to report": function(){
var report = CSSLint.verify(".foo.bar{}\n.baz.qux{} /* csslint allow: box-sizing */\nquux.corge{}");
Assert.isTrue(report.allow.hasOwnProperty("2"));
Assert.isTrue(report.allow["2"].hasOwnProperty("box-sizing"));
},

"Allow statement on one line with multiple rules should be added to report": function(){
var report = CSSLint.verify(".foo.bar{}\n.baz.qux{} /* csslint allow: box-sizing, box-model */\nquux.corge{}");
Assert.isTrue(report.allow.hasOwnProperty("2"));
Assert.isTrue(report.allow["2"].hasOwnProperty("box-sizing"));
Assert.isTrue(report.allow["2"].hasOwnProperty("box-model"));
},

"Allow statements on multiple lines for different rules should be added to report": function(){
var report = CSSLint.verify(".foo.bar{}\n.baz.qux{} /* csslint allow: box-sizing */\nquux.corge{}\ngrault.garply{} /* csslint allow: box-model */");
Assert.isTrue(report.allow.hasOwnProperty("2"));
Assert.isTrue(report.allow["2"].hasOwnProperty("box-sizing"));
Assert.isTrue(report.allow.hasOwnProperty("4"));
Assert.isTrue(report.allow["4"].hasOwnProperty("box-model"));
}

}));
Expand Down
24 changes: 24 additions & 0 deletions tests/core/Reporter.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,30 @@

Assert.areEqual(1, reporter.messages.length);
Assert.areEqual("error", reporter.messages[0].type);
},

"Allow statement should drop message about specific rule on specific line but not other lines": function(){
var reporter = new CSSLint._Reporter([], { "fake-rule": 1}, {"3": {"fake-rule": true}});
reporter.report("Foo", 2, 1, { id: "fake-rule" });
reporter.report("Bar", 3, 1, { id: "fake-rule" });

Assert.areEqual(1, reporter.messages.length);
},

"Allow statement should drop message about specific rule on specific line but not other rules": function(){
var reporter = new CSSLint._Reporter([], { "fake-rule": 1, "fake-rule2": 1}, {"3": {"fake-rule": true}});
reporter.report("Foo", 3, 1, { id: "fake-rule" });
reporter.report("Bar", 3, 1, { id: "fake-rule2" });

Assert.areEqual(1, reporter.messages.length);
},

"Allow statement should drop messages about multiple rules on specific line": function(){
var reporter = new CSSLint._Reporter([], { "fake-rule": 1, "fake-rule2": 1}, {"3": {"fake-rule": true, "fake-rule2": true}});
reporter.report("Foo", 3, 1, { id: "fake-rule" });
reporter.report("Bar", 3, 1, { id: "fake-rule2" });

Assert.areEqual(0, reporter.messages.length);
}

}));
Expand Down