ruby_css_lint 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.document +5 -0
- data/Gemfile +13 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +19 -0
- data/Rakefile +71 -0
- data/VERSION +1 -0
- data/csslint/CHANGELOG +286 -0
- data/csslint/LICENSE +20 -0
- data/csslint/README.md +25 -0
- data/csslint/build.xml +242 -0
- data/csslint/demos/CSSLintDemo.htm +105 -0
- data/csslint/demos/demo.css +43 -0
- data/csslint/lib/js.jar +0 -0
- data/csslint/lib/jshint.js +3963 -0
- data/csslint/lib/parserlib.js +6295 -0
- data/csslint/lib/yuitest-rhino-cli.js +3955 -0
- data/csslint/lib/yuitest.js +4561 -0
- data/csslint/npm/package.json +30 -0
- data/csslint/release/csslint-node.js +9125 -0
- data/csslint/release/csslint-rhino.js +9390 -0
- data/csslint/release/csslint-tests.js +1921 -0
- data/csslint/release/csslint-worker.js +9148 -0
- data/csslint/release/csslint-wsh.js +9477 -0
- data/csslint/release/csslint.js +9127 -0
- data/csslint/release/npm/cli.js +307 -0
- data/csslint/release/npm/lib/csslint-node.js +9125 -0
- data/csslint/release/npm/package.json +30 -0
- data/csslint/src/cli/common.js +215 -0
- data/csslint/src/cli/node.js +87 -0
- data/csslint/src/cli/rhino.js +47 -0
- data/csslint/src/cli/wsh.js +134 -0
- data/csslint/src/core/CSSLint.js +181 -0
- data/csslint/src/core/Reporter.js +161 -0
- data/csslint/src/core/Util.js +62 -0
- data/csslint/src/formatters/checkstyle-xml.js +109 -0
- data/csslint/src/formatters/compact.js +59 -0
- data/csslint/src/formatters/csslint-xml.js +68 -0
- data/csslint/src/formatters/lint-xml.js +69 -0
- data/csslint/src/formatters/text.js +64 -0
- data/csslint/src/rules/adjoining-classes.js +45 -0
- data/csslint/src/rules/box-model.js +93 -0
- data/csslint/src/rules/box-sizing.js +28 -0
- data/csslint/src/rules/compatible-vendor-prefixes.js +171 -0
- data/csslint/src/rules/display-property-grouping.js +117 -0
- data/csslint/src/rules/duplicate-background-images.js +37 -0
- data/csslint/src/rules/duplicate-properties.js +46 -0
- data/csslint/src/rules/empty-rules.js +34 -0
- data/csslint/src/rules/errors.js +23 -0
- data/csslint/src/rules/fallback-colors.js +67 -0
- data/csslint/src/rules/floats.js +36 -0
- data/csslint/src/rules/font-faces.js +30 -0
- data/csslint/src/rules/font-sizes.js +35 -0
- data/csslint/src/rules/gradients.js +69 -0
- data/csslint/src/rules/ids.js +50 -0
- data/csslint/src/rules/import.js +23 -0
- data/csslint/src/rules/important.js +37 -0
- data/csslint/src/rules/known-properties.js +29 -0
- data/csslint/src/rules/outline-none.js +73 -0
- data/csslint/src/rules/overqualified-elements.js +63 -0
- data/csslint/src/rules/qualified-headings.js +38 -0
- data/csslint/src/rules/regex-selectors.js +44 -0
- data/csslint/src/rules/rules-count.js +28 -0
- data/csslint/src/rules/shorthand.js +87 -0
- data/csslint/src/rules/star-property-hack.js +27 -0
- data/csslint/src/rules/text-indent.js +53 -0
- data/csslint/src/rules/underscore-property-hack.js +27 -0
- data/csslint/src/rules/unique-headings.js +74 -0
- data/csslint/src/rules/universal-selector.js +35 -0
- data/csslint/src/rules/unqualified-attributes.js +42 -0
- data/csslint/src/rules/vendor-prefix.js +143 -0
- data/csslint/src/rules/zero-units.js +34 -0
- data/csslint/src/worker/Worker.js +26 -0
- data/csslint/tests/all-rules.js +64 -0
- data/csslint/tests/core/CSSLint.js +22 -0
- data/csslint/tests/core/Reporter.js +36 -0
- data/csslint/tests/css/width-100.html +76 -0
- data/csslint/tests/formatters/checkstyle-xml.js +44 -0
- data/csslint/tests/formatters/compact.js +47 -0
- data/csslint/tests/formatters/csslint-xml.js +42 -0
- data/csslint/tests/formatters/lint-xml.js +43 -0
- data/csslint/tests/formatters/text.js +36 -0
- data/csslint/tests/rules/adjoining-classes.js +31 -0
- data/csslint/tests/rules/box-model.js +211 -0
- data/csslint/tests/rules/box-sizing.js +23 -0
- data/csslint/tests/rules/compatible-vendor-prefixes.js +56 -0
- data/csslint/tests/rules/display-property-grouping.js +213 -0
- data/csslint/tests/rules/duplicate-background-images.js +25 -0
- data/csslint/tests/rules/duplicate-properties.js +54 -0
- data/csslint/tests/rules/empty-rules.js +18 -0
- data/csslint/tests/rules/errors.js +17 -0
- data/csslint/tests/rules/fallback-colors.js +162 -0
- data/csslint/tests/rules/floats.js +35 -0
- data/csslint/tests/rules/font-faces.js +28 -0
- data/csslint/tests/rules/font-sizes.js +30 -0
- data/csslint/tests/rules/gradients.js +60 -0
- data/csslint/tests/rules/ids.js +25 -0
- data/csslint/tests/rules/import.js +18 -0
- data/csslint/tests/rules/important.js +27 -0
- data/csslint/tests/rules/known-properties.js +44 -0
- data/csslint/tests/rules/outline-none.js +50 -0
- data/csslint/tests/rules/overqualified-elements.js +41 -0
- data/csslint/tests/rules/qualified-headings.js +19 -0
- data/csslint/tests/rules/regex-selectors.js +52 -0
- data/csslint/tests/rules/shorthand.js +36 -0
- data/csslint/tests/rules/star-property-hack.js +24 -0
- data/csslint/tests/rules/text-indent.js +55 -0
- data/csslint/tests/rules/underscore-property-hack.js +24 -0
- data/csslint/tests/rules/unique-headings.js +47 -0
- data/csslint/tests/rules/universal-selector.js +31 -0
- data/csslint/tests/rules/unqualified-attributes.js +37 -0
- data/csslint/tests/rules/vendor-prefix.js +76 -0
- data/csslint/tests/rules/zero-units.js +44 -0
- data/csslint/tests/testrunner.htm +138 -0
- data/js.jar +0 -0
- data/lib/ruby_css_lint.rb +168 -0
- data/test/helper.rb +17 -0
- data/test/test_ruby_css_lint.rb +7 -0
- metadata +240 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Rule: Don't use IDs for selectors.
|
|
3
|
+
*/
|
|
4
|
+
/*global CSSLint*/
|
|
5
|
+
CSSLint.addRule({
|
|
6
|
+
|
|
7
|
+
//rule information
|
|
8
|
+
id: "ids",
|
|
9
|
+
name: "Disallow IDs in selectors",
|
|
10
|
+
desc: "Selectors should not contain IDs.",
|
|
11
|
+
browsers: "All",
|
|
12
|
+
|
|
13
|
+
//initialization
|
|
14
|
+
init: function(parser, reporter){
|
|
15
|
+
var rule = this;
|
|
16
|
+
parser.addListener("startrule", function(event){
|
|
17
|
+
var selectors = event.selectors,
|
|
18
|
+
selector,
|
|
19
|
+
part,
|
|
20
|
+
modifier,
|
|
21
|
+
idCount,
|
|
22
|
+
i, j, k;
|
|
23
|
+
|
|
24
|
+
for (i=0; i < selectors.length; i++){
|
|
25
|
+
selector = selectors[i];
|
|
26
|
+
idCount = 0;
|
|
27
|
+
|
|
28
|
+
for (j=0; j < selector.parts.length; j++){
|
|
29
|
+
part = selector.parts[j];
|
|
30
|
+
if (part.type == parser.SELECTOR_PART_TYPE){
|
|
31
|
+
for (k=0; k < part.modifiers.length; k++){
|
|
32
|
+
modifier = part.modifiers[k];
|
|
33
|
+
if (modifier.type == "id"){
|
|
34
|
+
idCount++;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (idCount == 1){
|
|
41
|
+
reporter.report("Don't use IDs in selectors.", selector.line, selector.col, rule);
|
|
42
|
+
} else if (idCount > 1){
|
|
43
|
+
reporter.report(idCount + " IDs in the selector, really?", selector.line, selector.col, rule);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Rule: Don't use @import, use <link> instead.
|
|
3
|
+
*/
|
|
4
|
+
/*global CSSLint*/
|
|
5
|
+
CSSLint.addRule({
|
|
6
|
+
|
|
7
|
+
//rule information
|
|
8
|
+
id: "import",
|
|
9
|
+
name: "Disallow @import",
|
|
10
|
+
desc: "Don't use @import, use <link> instead.",
|
|
11
|
+
browsers: "All",
|
|
12
|
+
|
|
13
|
+
//initialization
|
|
14
|
+
init: function(parser, reporter){
|
|
15
|
+
var rule = this;
|
|
16
|
+
|
|
17
|
+
parser.addListener("import", function(event){
|
|
18
|
+
reporter.report("@import prevents parallel downloads, use <link> instead.", event.line, event.col, rule);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
});
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Rule: Make sure !important is not overused, this could lead to specificity
|
|
3
|
+
* war. Display a warning on !important declarations, an error if it's
|
|
4
|
+
* used more at least 10 times.
|
|
5
|
+
*/
|
|
6
|
+
/*global CSSLint*/
|
|
7
|
+
CSSLint.addRule({
|
|
8
|
+
|
|
9
|
+
//rule information
|
|
10
|
+
id: "important",
|
|
11
|
+
name: "Disallow !important",
|
|
12
|
+
desc: "Be careful when using !important declaration",
|
|
13
|
+
browsers: "All",
|
|
14
|
+
|
|
15
|
+
//initialization
|
|
16
|
+
init: function(parser, reporter){
|
|
17
|
+
var rule = this,
|
|
18
|
+
count = 0;
|
|
19
|
+
|
|
20
|
+
//warn that important is used and increment the declaration counter
|
|
21
|
+
parser.addListener("property", function(event){
|
|
22
|
+
if (event.important === true){
|
|
23
|
+
count++;
|
|
24
|
+
reporter.report("Use of !important", event.line, event.col, rule);
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
//if there are more than 10, show an error
|
|
29
|
+
parser.addListener("endstylesheet", function(){
|
|
30
|
+
reporter.stat("important", count);
|
|
31
|
+
if (count >= 10){
|
|
32
|
+
reporter.rollupWarn("Too many !important declarations (" + count + "), try to use less than 10 to avoid specificity issues.", rule);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
});
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Rule: Properties should be known (listed in CSS3 specification) or
|
|
3
|
+
* be a vendor-prefixed property.
|
|
4
|
+
*/
|
|
5
|
+
/*global CSSLint*/
|
|
6
|
+
CSSLint.addRule({
|
|
7
|
+
|
|
8
|
+
//rule information
|
|
9
|
+
id: "known-properties",
|
|
10
|
+
name: "Require use of known properties",
|
|
11
|
+
desc: "Properties should be known (listed in CSS3 specification) or be a vendor-prefixed property.",
|
|
12
|
+
browsers: "All",
|
|
13
|
+
|
|
14
|
+
//initialization
|
|
15
|
+
init: function(parser, reporter){
|
|
16
|
+
var rule = this;
|
|
17
|
+
|
|
18
|
+
parser.addListener("property", function(event){
|
|
19
|
+
var name = event.property.text.toLowerCase();
|
|
20
|
+
|
|
21
|
+
// the check is handled entirely by the parser-lib (https://github.com/nzakas/parser-lib)
|
|
22
|
+
if (event.invalid) {
|
|
23
|
+
reporter.report(event.invalid.message, event.line, event.col, rule);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
});
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Rule: outline: none or outline: 0 should only be used in a :focus rule
|
|
3
|
+
* and only if there are other properties in the same rule.
|
|
4
|
+
*/
|
|
5
|
+
/*global CSSLint*/
|
|
6
|
+
CSSLint.addRule({
|
|
7
|
+
|
|
8
|
+
//rule information
|
|
9
|
+
id: "outline-none",
|
|
10
|
+
name: "Disallow outline: none",
|
|
11
|
+
desc: "Use of outline: none or outline: 0 should be limited to :focus rules.",
|
|
12
|
+
browsers: "All",
|
|
13
|
+
tags: ["Accessibility"],
|
|
14
|
+
|
|
15
|
+
//initialization
|
|
16
|
+
init: function(parser, reporter){
|
|
17
|
+
var rule = this,
|
|
18
|
+
lastRule;
|
|
19
|
+
|
|
20
|
+
function startRule(event){
|
|
21
|
+
if (event.selectors){
|
|
22
|
+
lastRule = {
|
|
23
|
+
line: event.line,
|
|
24
|
+
col: event.col,
|
|
25
|
+
selectors: event.selectors,
|
|
26
|
+
propCount: 0,
|
|
27
|
+
outline: false
|
|
28
|
+
};
|
|
29
|
+
} else {
|
|
30
|
+
lastRule = null;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function endRule(event){
|
|
35
|
+
if (lastRule){
|
|
36
|
+
if (lastRule.outline){
|
|
37
|
+
if (lastRule.selectors.toString().toLowerCase().indexOf(":focus") == -1){
|
|
38
|
+
reporter.report("Outlines should only be modified using :focus.", lastRule.line, lastRule.col, rule);
|
|
39
|
+
} else if (lastRule.propCount == 1) {
|
|
40
|
+
reporter.report("Outlines shouldn't be hidden unless other visual changes are made.", lastRule.line, lastRule.col, rule);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
parser.addListener("startrule", startRule);
|
|
47
|
+
parser.addListener("startfontface", startRule);
|
|
48
|
+
parser.addListener("startpage", startRule);
|
|
49
|
+
parser.addListener("startpagemargin", startRule);
|
|
50
|
+
parser.addListener("startkeyframerule", startRule);
|
|
51
|
+
|
|
52
|
+
parser.addListener("property", function(event){
|
|
53
|
+
var name = event.property.text.toLowerCase(),
|
|
54
|
+
value = event.value;
|
|
55
|
+
|
|
56
|
+
if (lastRule){
|
|
57
|
+
lastRule.propCount++;
|
|
58
|
+
if (name == "outline" && (value == "none" || value == "0")){
|
|
59
|
+
lastRule.outline = true;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
parser.addListener("endrule", endRule);
|
|
66
|
+
parser.addListener("endfontface", endRule);
|
|
67
|
+
parser.addListener("endpage", endRule);
|
|
68
|
+
parser.addListener("endpagemargin", endRule);
|
|
69
|
+
parser.addListener("endkeyframerule", endRule);
|
|
70
|
+
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
});
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Rule: Don't use classes or IDs with elements (a.foo or a#foo).
|
|
3
|
+
*/
|
|
4
|
+
/*global CSSLint*/
|
|
5
|
+
CSSLint.addRule({
|
|
6
|
+
|
|
7
|
+
//rule information
|
|
8
|
+
id: "overqualified-elements",
|
|
9
|
+
name: "Disallow overqualified elements",
|
|
10
|
+
desc: "Don't use classes or IDs with elements (a.foo or a#foo).",
|
|
11
|
+
browsers: "All",
|
|
12
|
+
|
|
13
|
+
//initialization
|
|
14
|
+
init: function(parser, reporter){
|
|
15
|
+
var rule = this,
|
|
16
|
+
classes = {};
|
|
17
|
+
|
|
18
|
+
parser.addListener("startrule", function(event){
|
|
19
|
+
var selectors = event.selectors,
|
|
20
|
+
selector,
|
|
21
|
+
part,
|
|
22
|
+
modifier,
|
|
23
|
+
i, j, k;
|
|
24
|
+
|
|
25
|
+
for (i=0; i < selectors.length; i++){
|
|
26
|
+
selector = selectors[i];
|
|
27
|
+
|
|
28
|
+
for (j=0; j < selector.parts.length; j++){
|
|
29
|
+
part = selector.parts[j];
|
|
30
|
+
if (part.type == parser.SELECTOR_PART_TYPE){
|
|
31
|
+
for (k=0; k < part.modifiers.length; k++){
|
|
32
|
+
modifier = part.modifiers[k];
|
|
33
|
+
if (part.elementName && modifier.type == "id"){
|
|
34
|
+
reporter.report("Element (" + part + ") is overqualified, just use " + modifier + " without element name.", part.line, part.col, rule);
|
|
35
|
+
} else if (modifier.type == "class"){
|
|
36
|
+
|
|
37
|
+
if (!classes[modifier]){
|
|
38
|
+
classes[modifier] = [];
|
|
39
|
+
}
|
|
40
|
+
classes[modifier].push({ modifier: modifier, part: part });
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
parser.addListener("endstylesheet", function(){
|
|
49
|
+
|
|
50
|
+
var prop;
|
|
51
|
+
for (prop in classes){
|
|
52
|
+
if (classes.hasOwnProperty(prop)){
|
|
53
|
+
|
|
54
|
+
//one use means that this is overqualified
|
|
55
|
+
if (classes[prop].length == 1 && classes[prop][0].part.elementName){
|
|
56
|
+
reporter.report("Element (" + classes[prop][0].part + ") is overqualified, just use " + classes[prop][0].modifier + " without element name.", classes[prop][0].part.line, classes[prop][0].part.col, rule);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
});
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Rule: Headings (h1-h6) should not be qualified (namespaced).
|
|
3
|
+
*/
|
|
4
|
+
/*global CSSLint*/
|
|
5
|
+
CSSLint.addRule({
|
|
6
|
+
|
|
7
|
+
//rule information
|
|
8
|
+
id: "qualified-headings",
|
|
9
|
+
name: "Disallow qualified headings",
|
|
10
|
+
desc: "Headings should not be qualified (namespaced).",
|
|
11
|
+
browsers: "All",
|
|
12
|
+
|
|
13
|
+
//initialization
|
|
14
|
+
init: function(parser, reporter){
|
|
15
|
+
var rule = this;
|
|
16
|
+
|
|
17
|
+
parser.addListener("startrule", function(event){
|
|
18
|
+
var selectors = event.selectors,
|
|
19
|
+
selector,
|
|
20
|
+
part,
|
|
21
|
+
i, j;
|
|
22
|
+
|
|
23
|
+
for (i=0; i < selectors.length; i++){
|
|
24
|
+
selector = selectors[i];
|
|
25
|
+
|
|
26
|
+
for (j=0; j < selector.parts.length; j++){
|
|
27
|
+
part = selector.parts[j];
|
|
28
|
+
if (part.type == parser.SELECTOR_PART_TYPE){
|
|
29
|
+
if (part.elementName && /h[1-6]/.test(part.elementName.toString()) && j > 0){
|
|
30
|
+
reporter.report("Heading (" + part.elementName + ") should not be qualified.", part.line, part.col, rule);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
});
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Rule: Selectors that look like regular expressions are slow and should be avoided.
|
|
3
|
+
*/
|
|
4
|
+
/*global CSSLint*/
|
|
5
|
+
CSSLint.addRule({
|
|
6
|
+
|
|
7
|
+
//rule information
|
|
8
|
+
id: "regex-selectors",
|
|
9
|
+
name: "Disallow selectors that look like regexs",
|
|
10
|
+
desc: "Selectors that look like regular expressions are slow and should be avoided.",
|
|
11
|
+
browsers: "All",
|
|
12
|
+
|
|
13
|
+
//initialization
|
|
14
|
+
init: function(parser, reporter){
|
|
15
|
+
var rule = this;
|
|
16
|
+
|
|
17
|
+
parser.addListener("startrule", function(event){
|
|
18
|
+
var selectors = event.selectors,
|
|
19
|
+
selector,
|
|
20
|
+
part,
|
|
21
|
+
modifier,
|
|
22
|
+
i, j, k;
|
|
23
|
+
|
|
24
|
+
for (i=0; i < selectors.length; i++){
|
|
25
|
+
selector = selectors[i];
|
|
26
|
+
for (j=0; j < selector.parts.length; j++){
|
|
27
|
+
part = selector.parts[j];
|
|
28
|
+
if (part.type == parser.SELECTOR_PART_TYPE){
|
|
29
|
+
for (k=0; k < part.modifiers.length; k++){
|
|
30
|
+
modifier = part.modifiers[k];
|
|
31
|
+
if (modifier.type == "attribute"){
|
|
32
|
+
if (/([\~\|\^\$\*]=)/.test(modifier)){
|
|
33
|
+
reporter.report("Attribute selectors with " + RegExp.$1 + " are slow!", modifier.line, modifier.col, rule);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
});
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Rule: Total number of rules should not exceed x.
|
|
3
|
+
*/
|
|
4
|
+
/*global CSSLint*/
|
|
5
|
+
CSSLint.addRule({
|
|
6
|
+
|
|
7
|
+
//rule information
|
|
8
|
+
id: "rules-count",
|
|
9
|
+
name: "Rules Count",
|
|
10
|
+
desc: "Track how many rules there are.",
|
|
11
|
+
browsers: "All",
|
|
12
|
+
|
|
13
|
+
//initialization
|
|
14
|
+
init: function(parser, reporter){
|
|
15
|
+
var rule = this,
|
|
16
|
+
count = 0;
|
|
17
|
+
|
|
18
|
+
//count each rule
|
|
19
|
+
parser.addListener("startrule", function(){
|
|
20
|
+
count++;
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
parser.addListener("endstylesheet", function(){
|
|
24
|
+
reporter.stat("rule-count", count);
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
});
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Rule: Use shorthand properties where possible.
|
|
3
|
+
*
|
|
4
|
+
*/
|
|
5
|
+
/*global CSSLint*/
|
|
6
|
+
CSSLint.addRule({
|
|
7
|
+
|
|
8
|
+
//rule information
|
|
9
|
+
id: "shorthand",
|
|
10
|
+
name: "Require shorthand properties",
|
|
11
|
+
desc: "Use shorthand properties where possible.",
|
|
12
|
+
browsers: "All",
|
|
13
|
+
|
|
14
|
+
//initialization
|
|
15
|
+
init: function(parser, reporter){
|
|
16
|
+
var rule = this,
|
|
17
|
+
prop, i, len,
|
|
18
|
+
propertiesToCheck = {},
|
|
19
|
+
properties,
|
|
20
|
+
mapping = {
|
|
21
|
+
"margin": [
|
|
22
|
+
"margin-top",
|
|
23
|
+
"margin-bottom",
|
|
24
|
+
"margin-left",
|
|
25
|
+
"margin-right"
|
|
26
|
+
],
|
|
27
|
+
"padding": [
|
|
28
|
+
"padding-top",
|
|
29
|
+
"padding-bottom",
|
|
30
|
+
"padding-left",
|
|
31
|
+
"padding-right"
|
|
32
|
+
]
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
//initialize propertiesToCheck
|
|
36
|
+
for (prop in mapping){
|
|
37
|
+
if (mapping.hasOwnProperty(prop)){
|
|
38
|
+
for (i=0, len=mapping[prop].length; i < len; i++){
|
|
39
|
+
propertiesToCheck[mapping[prop][i]] = prop;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function startRule(event){
|
|
45
|
+
properties = {};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
//event handler for end of rules
|
|
49
|
+
function endRule(event){
|
|
50
|
+
|
|
51
|
+
var prop, i, len, total;
|
|
52
|
+
|
|
53
|
+
//check which properties this rule has
|
|
54
|
+
for (prop in mapping){
|
|
55
|
+
if (mapping.hasOwnProperty(prop)){
|
|
56
|
+
total=0;
|
|
57
|
+
|
|
58
|
+
for (i=0, len=mapping[prop].length; i < len; i++){
|
|
59
|
+
total += properties[mapping[prop][i]] ? 1 : 0;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (total == mapping[prop].length){
|
|
63
|
+
reporter.report("The properties " + mapping[prop].join(", ") + " can be replaced by " + prop + ".", event.line, event.col, rule);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
parser.addListener("startrule", startRule);
|
|
70
|
+
parser.addListener("startfontface", startRule);
|
|
71
|
+
|
|
72
|
+
//check for use of "font-size"
|
|
73
|
+
parser.addListener("property", function(event){
|
|
74
|
+
var name = event.property.toString().toLowerCase(),
|
|
75
|
+
value = event.value.parts[0].value;
|
|
76
|
+
|
|
77
|
+
if (propertiesToCheck[name]){
|
|
78
|
+
properties[name] = 1;
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
parser.addListener("endrule", endRule);
|
|
83
|
+
parser.addListener("endfontface", endRule);
|
|
84
|
+
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
});
|