Skip to content

Commit 955e8cb

Browse files
committed
Merge pull request #338 from shannonmoeller/feature/embedded-rulesets
Added support for embedded rulesets. Resolves #336.
2 parents ea19b92 + 2b88b00 commit 955e8cb

File tree

3 files changed

+75
-23
lines changed

3 files changed

+75
-23
lines changed

src/cli/common.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ function cli(api){
5959
if (ignore) {
6060
ruleset = CSSLint.getRuleset();
6161
ignore.split(",").forEach(function(value){
62-
delete ruleset[value];
62+
ruleset[value] = 0;
6363
});
6464
}
6565

src/core/CSSLint.js

+63-22
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,11 @@
77
/*global parserlib, Reporter*/
88
var CSSLint = (function(){
99

10-
var rules = [],
11-
formatters = [],
12-
api = new parserlib.util.EventTarget();
13-
10+
var rules = [],
11+
formatters = [],
12+
embeddedRuleset = /\/\*csslint([^\*]*)\*\//,
13+
api = new parserlib.util.EventTarget();
14+
1415
api.version = "@VERSION@";
1516

1617
//-------------------------------------------------------------------------
@@ -34,18 +35,18 @@ var CSSLint = (function(){
3435
api.clearRules = function(){
3536
rules = [];
3637
};
37-
38+
3839
/**
3940
* Returns the rule objects.
4041
* @return An array of rule objects.
4142
* @method getRules
4243
*/
4344
api.getRules = function(){
44-
return [].concat(rules).sort(function(a,b){
45+
return [].concat(rules).sort(function(a,b){
4546
return a.id > b.id ? 1 : 0;
4647
});
4748
};
48-
49+
4950
/**
5051
* Returns a ruleset configuration object with all current rules.
5152
* @return A ruleset object.
@@ -55,14 +56,49 @@ var CSSLint = (function(){
5556
var ruleset = {},
5657
i = 0,
5758
len = rules.length;
58-
59+
5960
while (i < len){
6061
ruleset[rules[i++].id] = 1; //by default, everything is a warning
6162
}
62-
63+
6364
return ruleset;
6465
};
6566

67+
/**
68+
* Returns a ruleset object based on embedded rules.
69+
* @param {String} text A string of css containing embedded rules.
70+
* @param {Object} ruleset A ruleset object to modify.
71+
* @return {Object} A ruleset object.
72+
* @method getEmbeddedRuleset
73+
*/
74+
function applyEmbeddedRuleset(text, ruleset){
75+
var valueMap,
76+
embedded = text && text.match(embeddedRuleset),
77+
rules = embedded && embedded[1];
78+
79+
if (rules) {
80+
valueMap = {
81+
"true": 2, // true is error
82+
"": 1, // blank is warning
83+
"false": 0, // false is ignore
84+
85+
"2": 2, // explicit error
86+
"1": 1, // explicit warning
87+
"0": 0 // explicit ignore
88+
};
89+
90+
rules.toLowerCase().split(",").forEach(function(rule){
91+
var pair = rule.split(":"),
92+
property = pair[0] || "",
93+
value = pair[1] || "";
94+
95+
ruleset[property.trim()] = valueMap[value.trim()];
96+
});
97+
}
98+
99+
return ruleset;
100+
}
101+
66102
//-------------------------------------------------------------------------
67103
// Formatters
68104
//-------------------------------------------------------------------------
@@ -76,7 +112,7 @@ var CSSLint = (function(){
76112
// formatters.push(formatter);
77113
formatters[formatter.id] = formatter;
78114
};
79-
115+
80116
/**
81117
* Retrieves a formatter for use.
82118
* @param {String} formatId The name of the format to retrieve.
@@ -86,7 +122,7 @@ var CSSLint = (function(){
86122
api.getFormatter = function(formatId){
87123
return formatters[formatId];
88124
};
89-
125+
90126
/**
91127
* Formats the results in a particular format for a single file.
92128
* @param {Object} result The results returned from CSSLint.verify().
@@ -99,16 +135,16 @@ var CSSLint = (function(){
99135
api.format = function(results, filename, formatId, options) {
100136
var formatter = this.getFormatter(formatId),
101137
result = null;
102-
138+
103139
if (formatter){
104140
result = formatter.startFormat();
105141
result += formatter.formatResults(results, filename, options || {});
106142
result += formatter.endFormat();
107143
}
108-
144+
109145
return result;
110146
};
111-
147+
112148
/**
113149
* Indicates if the given format is supported.
114150
* @param {String} formatId The ID of the format to check.
@@ -144,16 +180,20 @@ var CSSLint = (function(){
144180

145181
// normalize line endings
146182
lines = text.replace(/\n\r?/g, "$split$").split('$split$');
147-
183+
148184
if (!ruleset){
149185
ruleset = this.getRuleset();
150186
}
151-
187+
188+
if (embeddedRuleset.test(text)){
189+
ruleset = applyEmbeddedRuleset(text, ruleset);
190+
}
191+
152192
reporter = new Reporter(lines, ruleset);
153-
193+
154194
ruleset.errors = 2; //always report parsing errors as errors
155195
for (i in ruleset){
156-
if(ruleset.hasOwnProperty(i)){
196+
if(ruleset.hasOwnProperty(i) && ruleset[i]){
157197
if (rules[i]){
158198
rules[i].init(parser, reporter);
159199
}
@@ -170,9 +210,10 @@ var CSSLint = (function(){
170210

171211
report = {
172212
messages : reporter.messages,
173-
stats : reporter.stats
213+
stats : reporter.stats,
214+
ruleset : reporter.ruleset
174215
};
175-
216+
176217
//sort by line numbers, rollups at the bottom
177218
report.messages.sort(function (a, b){
178219
if (a.rollup && !b.rollup){
@@ -182,8 +223,8 @@ var CSSLint = (function(){
182223
} else {
183224
return a.line - b.line;
184225
}
185-
});
186-
226+
});
227+
187228
return report;
188229
};
189230

tests/core/CSSLint.js

+11
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,17 @@
1515
"@media (max-width:400px) should not cause an error": function(){
1616
var result = CSSLint.verify("@media (max-width:400px) {}", { });
1717
Assert.areEqual(0, result.messages.length);
18+
},
19+
20+
"Embedded ruleset should be honored": function(){
21+
var result = CSSLint.verify("/*csslint bogus, adjoining-classes:true, box-sizing:false */\n.foo.bar{}", {
22+
'text-indent': 1,
23+
'box-sizing': 1
24+
});
25+
26+
Assert.areEqual(2, result.ruleset['adjoining-classes']);
27+
Assert.areEqual(1, result.ruleset['text-indent']);
28+
Assert.areEqual(0, result.ruleset['box-sizing']);
1829
}
1930

2031
}));

0 commit comments

Comments
 (0)