ruby_css_lint 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (118) hide show
  1. data/.document +5 -0
  2. data/Gemfile +13 -0
  3. data/LICENSE.txt +20 -0
  4. data/README.rdoc +19 -0
  5. data/Rakefile +71 -0
  6. data/VERSION +1 -0
  7. data/csslint/CHANGELOG +286 -0
  8. data/csslint/LICENSE +20 -0
  9. data/csslint/README.md +25 -0
  10. data/csslint/build.xml +242 -0
  11. data/csslint/demos/CSSLintDemo.htm +105 -0
  12. data/csslint/demos/demo.css +43 -0
  13. data/csslint/lib/js.jar +0 -0
  14. data/csslint/lib/jshint.js +3963 -0
  15. data/csslint/lib/parserlib.js +6295 -0
  16. data/csslint/lib/yuitest-rhino-cli.js +3955 -0
  17. data/csslint/lib/yuitest.js +4561 -0
  18. data/csslint/npm/package.json +30 -0
  19. data/csslint/release/csslint-node.js +9125 -0
  20. data/csslint/release/csslint-rhino.js +9390 -0
  21. data/csslint/release/csslint-tests.js +1921 -0
  22. data/csslint/release/csslint-worker.js +9148 -0
  23. data/csslint/release/csslint-wsh.js +9477 -0
  24. data/csslint/release/csslint.js +9127 -0
  25. data/csslint/release/npm/cli.js +307 -0
  26. data/csslint/release/npm/lib/csslint-node.js +9125 -0
  27. data/csslint/release/npm/package.json +30 -0
  28. data/csslint/src/cli/common.js +215 -0
  29. data/csslint/src/cli/node.js +87 -0
  30. data/csslint/src/cli/rhino.js +47 -0
  31. data/csslint/src/cli/wsh.js +134 -0
  32. data/csslint/src/core/CSSLint.js +181 -0
  33. data/csslint/src/core/Reporter.js +161 -0
  34. data/csslint/src/core/Util.js +62 -0
  35. data/csslint/src/formatters/checkstyle-xml.js +109 -0
  36. data/csslint/src/formatters/compact.js +59 -0
  37. data/csslint/src/formatters/csslint-xml.js +68 -0
  38. data/csslint/src/formatters/lint-xml.js +69 -0
  39. data/csslint/src/formatters/text.js +64 -0
  40. data/csslint/src/rules/adjoining-classes.js +45 -0
  41. data/csslint/src/rules/box-model.js +93 -0
  42. data/csslint/src/rules/box-sizing.js +28 -0
  43. data/csslint/src/rules/compatible-vendor-prefixes.js +171 -0
  44. data/csslint/src/rules/display-property-grouping.js +117 -0
  45. data/csslint/src/rules/duplicate-background-images.js +37 -0
  46. data/csslint/src/rules/duplicate-properties.js +46 -0
  47. data/csslint/src/rules/empty-rules.js +34 -0
  48. data/csslint/src/rules/errors.js +23 -0
  49. data/csslint/src/rules/fallback-colors.js +67 -0
  50. data/csslint/src/rules/floats.js +36 -0
  51. data/csslint/src/rules/font-faces.js +30 -0
  52. data/csslint/src/rules/font-sizes.js +35 -0
  53. data/csslint/src/rules/gradients.js +69 -0
  54. data/csslint/src/rules/ids.js +50 -0
  55. data/csslint/src/rules/import.js +23 -0
  56. data/csslint/src/rules/important.js +37 -0
  57. data/csslint/src/rules/known-properties.js +29 -0
  58. data/csslint/src/rules/outline-none.js +73 -0
  59. data/csslint/src/rules/overqualified-elements.js +63 -0
  60. data/csslint/src/rules/qualified-headings.js +38 -0
  61. data/csslint/src/rules/regex-selectors.js +44 -0
  62. data/csslint/src/rules/rules-count.js +28 -0
  63. data/csslint/src/rules/shorthand.js +87 -0
  64. data/csslint/src/rules/star-property-hack.js +27 -0
  65. data/csslint/src/rules/text-indent.js +53 -0
  66. data/csslint/src/rules/underscore-property-hack.js +27 -0
  67. data/csslint/src/rules/unique-headings.js +74 -0
  68. data/csslint/src/rules/universal-selector.js +35 -0
  69. data/csslint/src/rules/unqualified-attributes.js +42 -0
  70. data/csslint/src/rules/vendor-prefix.js +143 -0
  71. data/csslint/src/rules/zero-units.js +34 -0
  72. data/csslint/src/worker/Worker.js +26 -0
  73. data/csslint/tests/all-rules.js +64 -0
  74. data/csslint/tests/core/CSSLint.js +22 -0
  75. data/csslint/tests/core/Reporter.js +36 -0
  76. data/csslint/tests/css/width-100.html +76 -0
  77. data/csslint/tests/formatters/checkstyle-xml.js +44 -0
  78. data/csslint/tests/formatters/compact.js +47 -0
  79. data/csslint/tests/formatters/csslint-xml.js +42 -0
  80. data/csslint/tests/formatters/lint-xml.js +43 -0
  81. data/csslint/tests/formatters/text.js +36 -0
  82. data/csslint/tests/rules/adjoining-classes.js +31 -0
  83. data/csslint/tests/rules/box-model.js +211 -0
  84. data/csslint/tests/rules/box-sizing.js +23 -0
  85. data/csslint/tests/rules/compatible-vendor-prefixes.js +56 -0
  86. data/csslint/tests/rules/display-property-grouping.js +213 -0
  87. data/csslint/tests/rules/duplicate-background-images.js +25 -0
  88. data/csslint/tests/rules/duplicate-properties.js +54 -0
  89. data/csslint/tests/rules/empty-rules.js +18 -0
  90. data/csslint/tests/rules/errors.js +17 -0
  91. data/csslint/tests/rules/fallback-colors.js +162 -0
  92. data/csslint/tests/rules/floats.js +35 -0
  93. data/csslint/tests/rules/font-faces.js +28 -0
  94. data/csslint/tests/rules/font-sizes.js +30 -0
  95. data/csslint/tests/rules/gradients.js +60 -0
  96. data/csslint/tests/rules/ids.js +25 -0
  97. data/csslint/tests/rules/import.js +18 -0
  98. data/csslint/tests/rules/important.js +27 -0
  99. data/csslint/tests/rules/known-properties.js +44 -0
  100. data/csslint/tests/rules/outline-none.js +50 -0
  101. data/csslint/tests/rules/overqualified-elements.js +41 -0
  102. data/csslint/tests/rules/qualified-headings.js +19 -0
  103. data/csslint/tests/rules/regex-selectors.js +52 -0
  104. data/csslint/tests/rules/shorthand.js +36 -0
  105. data/csslint/tests/rules/star-property-hack.js +24 -0
  106. data/csslint/tests/rules/text-indent.js +55 -0
  107. data/csslint/tests/rules/underscore-property-hack.js +24 -0
  108. data/csslint/tests/rules/unique-headings.js +47 -0
  109. data/csslint/tests/rules/universal-selector.js +31 -0
  110. data/csslint/tests/rules/unqualified-attributes.js +37 -0
  111. data/csslint/tests/rules/vendor-prefix.js +76 -0
  112. data/csslint/tests/rules/zero-units.js +44 -0
  113. data/csslint/tests/testrunner.htm +138 -0
  114. data/js.jar +0 -0
  115. data/lib/ruby_css_lint.rb +168 -0
  116. data/test/helper.rb +17 -0
  117. data/test/test_ruby_css_lint.rb +7 -0
  118. 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
+ });