diff --git a/Gruntfile.js b/Gruntfile.js index 0f6f285d..2e428b61 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -217,25 +217,25 @@ module.exports = function(grunt) { }); // These plugins provide necessary tasks. + grunt.loadNpmTasks('grunt-contrib-clean'); grunt.loadNpmTasks('grunt-contrib-concat'); + grunt.loadNpmTasks('grunt-contrib-copy'); grunt.loadNpmTasks('grunt-contrib-jshint'); grunt.loadNpmTasks('grunt-contrib-watch'); - grunt.loadNpmTasks('grunt-contrib-clean'); - grunt.loadNpmTasks('grunt-contrib-copy'); grunt.loadNpmTasks('grunt-include-replace'); // Default task. grunt.registerTask('default', ['test']); - - //Alias for + + //Alias for grunt.registerTask('lint', ['jshint']); - + //Testing grunt.registerTask('test', ['clean:build', 'jshint', 'concat', 'yuitest']); grunt.registerTask('rhino', ['clean:build', 'jshint', 'concat', 'test_rhino']); grunt.registerTask('release', ['test', 'clean:release', 'copy:release', 'includereplace:release', 'changelog']); - + //Run the YUITest suite grunt.registerMultiTask('yuitest', 'Run the YUITests for the project', function() { /*jshint evil:true, node: true */ @@ -249,12 +249,12 @@ module.exports = function(grunt) { var errors = [], failures = [], stack = []; - + //Eval each file so the tests are brought into this scope where CSSLint and YUITest are loaded already files.forEach(function(filepath) { eval(grunt.file.read(filepath)); }); - + // From YUITest Node CLI function filterStackTrace(stackTrace){ if (stackTrace){ @@ -276,7 +276,7 @@ module.exports = function(grunt) { return "Unavailable."; } } - + // From YUITest Node CLI with minor colourization changes function handleEvent(event){ @@ -387,8 +387,8 @@ module.exports = function(grunt) { var done = this.async(); var lastTag; var files = this.filesSrc; - - + + grunt.util.spawn({ cmd: 'git', args: ['tag'] @@ -399,26 +399,26 @@ module.exports = function(grunt) { major = parseInt(semver[0], 10), minor = parseInt(semver[1], 10), patch = parseInt(semver[2], 10); - - //A simple array sort can't be used because of the comparison of + + //A simple array sort can't be used because of the comparison of //the strings '0.9.9' > '0.9.10' for (var i = 1, len = tags.length; i < len; i++) { semver = tags[i].replace('v','').split('.'); - + var currentMajor = parseInt(semver[0], 10); if (currentMajor < major) { continue; } else if (currentMajor > major) { major = currentMajor; } - + var currentMinor = parseInt(semver[1], 10); if (currentMinor < minor) { continue; } else if (currentMinor > minor) { minor = currentMinor; } - + var currentPatch = parseInt(semver[2], 10); if (currentPatch < patch) { continue; @@ -428,9 +428,9 @@ module.exports = function(grunt) { } lastTag = 'v' + major + '.' + minor + '.' + patch; - + grunt.verbose.write('Last tag: ' + lastTag).writeln(); - + // grunt.util.spawn({ cmd: 'git', @@ -445,9 +445,9 @@ module.exports = function(grunt) { grunt.file.read(files[0]); grunt.file.write(files[0], grunt.template.process(template)); - + done(); - }); + }); }); }); @@ -457,13 +457,13 @@ module.exports = function(grunt) { var done = this.async(); var files = this.filesSrc; var progress = files.length; - + files.forEach(function(filepath) { grunt.util.spawn({ cmd: 'java', args: ['-jar', 'lib/js.jar', 'lib/yuitest-rhino-cli.js', 'build/csslint.js', filepath], opts: {stdio: 'inherit'} - }, function(error, result, code) { + }, function(error, result, code) { progress--; if (progress === 0) { done(); diff --git a/demos/demo.css b/demos/demo.css index b2409725..f0226e81 100644 --- a/demos/demo.css +++ b/demos/demo.css @@ -28,7 +28,7 @@ li.last.first { } -@charset "UTF-8"; +@charset "UTF-8"; @page { margin: 10%; diff --git a/release/csslint-node.js b/release/csslint-node.js index 0bb1ff31..f800f974 100644 --- a/release/csslint-node.js +++ b/release/csslint-node.js @@ -294,7 +294,7 @@ function Reporter(lines, ruleset){ * @type String[] */ this.lines = lines; - + /** * Information about the rules. Used to determine whether an issue is an * error or warning. @@ -532,7 +532,7 @@ CSSLint.addRule({ /*global CSSLint*/ /* - * Rule: Don't use width or height when using padding or border. + * Rule: Don't use width or height when using padding or border. */ CSSLint.addRule({ @@ -571,7 +571,7 @@ CSSLint.addRule({ function endRule(){ var prop, value; - + if (!boxSizing) { if (properties.height){ for (prop in heightProperties){ @@ -589,25 +589,25 @@ CSSLint.addRule({ for (prop in widthProperties){ if (widthProperties.hasOwnProperty(prop) && properties[prop]){ value = properties[prop].value; - + if (!(prop == "padding" && value.parts.length === 2 && value.parts[1].value === 0)){ reporter.report("Using width with " + prop + " can sometimes make elements larger than you expect.", properties[prop].line, properties[prop].col, rule); } } } - } - } + } + } } parser.addListener("startrule", startRule); parser.addListener("startfontface", startRule); parser.addListener("startpage", startRule); parser.addListener("startpagemargin", startRule); - parser.addListener("startkeyframerule", startRule); + parser.addListener("startkeyframerule", startRule); parser.addListener("property", function(event){ var name = event.property.text.toLowerCase(); - + if (heightProperties[name] || widthProperties[name]){ if (!/^0\S*$/.test(event.value) && !(name == "border" && event.value == "none")){ properties[name] = { line: event.property.line, col: event.property.col, value: event.value }; @@ -619,14 +619,14 @@ CSSLint.addRule({ boxSizing = true; } } - + }); parser.addListener("endrule", endRule); parser.addListener("endfontface", endRule); parser.addListener("endpage", endRule); parser.addListener("endpagemargin", endRule); - parser.addListener("endkeyframerule", endRule); + parser.addListener("endkeyframerule", endRule); } }); @@ -650,11 +650,11 @@ CSSLint.addRule({ parser.addListener("property", function(event){ var name = event.property.text.toLowerCase(); - + if (name == "box-sizing"){ reporter.report("The box-sizing property isn't supported in IE6 and IE7.", event.line, event.col, rule); } - }); + }); } }); @@ -728,7 +728,7 @@ CSSLint.addRule({ * Rule: Include all compatible vendor prefixes to reach a wider * range of users. */ -/*global CSSLint*/ +/*global CSSLint*/ CSSLint.addRule({ //rule information @@ -824,7 +824,7 @@ CSSLint.addRule({ arrayPush.apply(applyTo, variations); } } - + parser.addListener("startrule", function () { properties = []; }); @@ -840,9 +840,9 @@ CSSLint.addRule({ parser.addListener("property", function (event) { var name = event.property; if (CSSLint.Util.indexOf(applyTo, name.text) > -1) { - + // e.g., -moz-transform is okay to be alone in @-moz-keyframes - if (!inKeyFrame || typeof inKeyFrame != "string" || + if (!inKeyFrame || typeof inKeyFrame != "string" || name.text.indexOf("-" + inKeyFrame + "-") !== 0) { properties.push(name); } @@ -900,7 +900,7 @@ CSSLint.addRule({ item = full[i]; if (CSSLint.Util.indexOf(actual, item) === -1) { propertiesSpecified = (actual.length === 1) ? actual[0] : (actual.length == 2) ? actual.join(" and ") : actual.join(", "); - reporter.report("The property " + item + " is compatible with " + propertiesSpecified + " and should be included as well.", value.actualNodes[0].line, value.actualNodes[0].col, rule); + reporter.report("The property " + item + " is compatible with " + propertiesSpecified + " and should be included as well.", value.actualNodes[0].line, value.actualNodes[0].col, rule); } } @@ -911,7 +911,7 @@ CSSLint.addRule({ } }); /* - * Rule: Certain properties don't play well with certain display values. + * Rule: Certain properties don't play well with certain display values. * - float should not be used with inline-block * - height, width, margin-top, margin-bottom, float should not be used with inline * - vertical-align should not be used with block @@ -956,7 +956,7 @@ CSSLint.addRule({ } } } - + function startRule(){ properties = {}; } @@ -973,7 +973,7 @@ CSSLint.addRule({ reportProperty("width", display); reportProperty("margin", display); reportProperty("margin-top", display); - reportProperty("margin-bottom", display); + reportProperty("margin-bottom", display); reportProperty("float", display, "display:inline has no effect on floated elements (but may be used to fix the IE6 double-margin bug)."); break; @@ -1001,7 +1001,7 @@ CSSLint.addRule({ //otherwise do nothing } } - + } parser.addListener("startrule", startRule); @@ -1014,7 +1014,7 @@ CSSLint.addRule({ var name = event.property.text.toLowerCase(); if (propertiesToCheck[name]){ - properties[name] = { value: event.value.text, line: event.property.line, col: event.property.col }; + properties[name] = { value: event.value.text, line: event.property.line, col: event.property.col }; } }); @@ -1081,32 +1081,32 @@ CSSLint.addRule({ init: function(parser, reporter){ var rule = this, properties, - lastProperty; - + lastProperty; + function startRule(event){ - properties = {}; + properties = {}; } - + parser.addListener("startrule", startRule); parser.addListener("startfontface", startRule); parser.addListener("startpage", startRule); parser.addListener("startpagemargin", startRule); - parser.addListener("startkeyframerule", startRule); - + parser.addListener("startkeyframerule", startRule); + parser.addListener("property", function(event){ var property = event.property, name = property.text.toLowerCase(); - + if (properties[name] && (lastProperty != name || properties[name] == event.value.text)){ reporter.report("Duplicate property '" + event.property + "' found.", event.line, event.col, rule); } - + properties[name] = event.value.text; lastProperty = name; - + }); - - + + } }); @@ -1197,35 +1197,35 @@ CSSLint.addRule({ "background-color": 1 }, properties; - + function startRule(event){ - properties = {}; - lastProperty = null; + properties = {}; + lastProperty = null; } - + parser.addListener("startrule", startRule); parser.addListener("startfontface", startRule); parser.addListener("startpage", startRule); parser.addListener("startpagemargin", startRule); - parser.addListener("startkeyframerule", startRule); - + parser.addListener("startkeyframerule", startRule); + parser.addListener("property", function(event){ var property = event.property, name = property.text.toLowerCase(), parts = event.value.parts, - i = 0, + i = 0, colorType = "", - len = parts.length; - + len = parts.length; + if(propertiesToCheck[name]){ while(i < len){ if (parts[i].type == "color"){ if ("alpha" in parts[i] || "hue" in parts[i]){ - + if (/([^\)]+)\(/.test(parts[i])){ colorType = RegExp.$1.toUpperCase(); } - + if (!lastProperty || (lastProperty.property.text.toLowerCase() != name || lastProperty.colorType != "compat")){ reporter.report("Fallback " + name + " (hex or RGB) should precede " + colorType + " " + name + ".", event.line, event.col, rule); } @@ -1233,14 +1233,14 @@ CSSLint.addRule({ event.colorType = "compat"; } } - + i++; } } lastProperty = event; - }); - + }); + } }); @@ -1391,7 +1391,7 @@ CSSLint.addRule({ if (!gradients.webkit){ missing.push("Webkit (Safari 5+, Chrome)"); } - + if (!gradients.oldWebkit){ missing.push("Old Webkit (Safari 4+, Chrome)"); } @@ -1400,8 +1400,8 @@ CSSLint.addRule({ missing.push("Opera 11.1+"); } - if (missing.length && missing.length < 4){ - reporter.report("Missing vendor-prefixed CSS gradients for " + missing.join(", ") + ".", event.selectors[0].line, event.selectors[0].col, rule); + if (missing.length && missing.length < 4){ + reporter.report("Missing vendor-prefixed CSS gradients for " + missing.join(", ") + ".", event.selectors[0].line, event.selectors[0].col, rule); } }); @@ -1475,8 +1475,8 @@ CSSLint.addRule({ //initialization init: function(parser, reporter){ var rule = this; - - parser.addListener("import", function(event){ + + parser.addListener("import", function(event){ reporter.report("@import prevents parallel downloads, use instead.", event.line, event.col, rule); }); @@ -1581,14 +1581,14 @@ CSSLint.addRule({ lastRule = null; } } - + function endRule(event){ if (lastRule){ if (lastRule.outline){ if (lastRule.selectors.toString().toLowerCase().indexOf(":focus") == -1){ reporter.report("Outlines should only be modified using :focus.", lastRule.line, lastRule.col, rule); } else if (lastRule.propCount == 1) { - reporter.report("Outlines shouldn't be hidden unless other visual changes are made.", lastRule.line, lastRule.col, rule); + reporter.report("Outlines shouldn't be hidden unless other visual changes are made.", lastRule.line, lastRule.col, rule); } } } @@ -1598,26 +1598,26 @@ CSSLint.addRule({ parser.addListener("startfontface", startRule); parser.addListener("startpage", startRule); parser.addListener("startpagemargin", startRule); - parser.addListener("startkeyframerule", startRule); + parser.addListener("startkeyframerule", startRule); parser.addListener("property", function(event){ var name = event.property.text.toLowerCase(), - value = event.value; - + value = event.value; + if (lastRule){ lastRule.propCount++; if (name == "outline" && (value == "none" || value == "0")){ lastRule.outline = true; - } + } } - + }); - + parser.addListener("endrule", endRule); parser.addListener("endfontface", endRule); parser.addListener("endpage", endRule); parser.addListener("endpagemargin", endRule); - parser.addListener("endkeyframerule", endRule); + parser.addListener("endkeyframerule", endRule); } @@ -1638,7 +1638,7 @@ CSSLint.addRule({ init: function(parser, reporter){ var rule = this, classes = {}; - + parser.addListener("startrule", function(event){ var selectors = event.selectors, selector, @@ -1657,7 +1657,7 @@ CSSLint.addRule({ if (part.elementName && modifier.type == "id"){ reporter.report("Element (" + part + ") is overqualified, just use " + modifier + " without element name.", part.line, part.col, rule); } else if (modifier.type == "class"){ - + if (!classes[modifier]){ classes[modifier] = []; } @@ -1668,19 +1668,19 @@ CSSLint.addRule({ } } }); - + parser.addListener("endstylesheet", function(){ - + var prop; for (prop in classes){ if (classes.hasOwnProperty(prop)){ - + //one use means that this is overqualified if (classes[prop].length == 1 && classes[prop][0].part.elementName){ 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); } } - } + } }); } @@ -1796,7 +1796,7 @@ CSSLint.addRule({ }); /* - * Rule: Warn people with approaching the IE 4095 limit + * Rule: Warn people with approaching the IE 4095 limit */ /*global CSSLint*/ CSSLint.addRule({ @@ -1817,7 +1817,7 @@ CSSLint.addRule({ parser.addListener("endstylesheet", function() { if (count >= 3800) { - reporter.report("You have " + count + " selectors. Internet Explorer supports a maximum of 4095 selectors per stylesheet. Consider refactoring.",0,0,rule); + reporter.report("You have " + count + " selectors. Internet Explorer supports a maximum of 4095 selectors per stylesheet. Consider refactoring.",0,0,rule); } }); } @@ -1825,7 +1825,7 @@ CSSLint.addRule({ }); /* - * Rule: Warn people past the IE 4095 limit + * Rule: Warn people past the IE 4095 limit */ /*global CSSLint*/ CSSLint.addRule({ @@ -1846,7 +1846,7 @@ CSSLint.addRule({ parser.addListener("endstylesheet", function() { if (count > 4095) { - reporter.report("You have " + count + " selectors. Internet Explorer supports a maximum of 4095 selectors per stylesheet. Consider refactoring.",0,0,rule); + reporter.report("You have " + count + " selectors. Internet Explorer supports a maximum of 4095 selectors per stylesheet. Consider refactoring.",0,0,rule); } }); } @@ -1854,7 +1854,7 @@ CSSLint.addRule({ }); /* * Rule: Use shorthand properties where possible. - * + * */ /*global CSSLint*/ CSSLint.addRule({ @@ -1864,7 +1864,7 @@ CSSLint.addRule({ name: "Require shorthand properties", desc: "Use shorthand properties where possible.", browsers: "All", - + //initialization init: function(parser, reporter){ var rule = this, @@ -1883,10 +1883,10 @@ CSSLint.addRule({ "padding-bottom", "padding-left", "padding-right" - ] + ] }; - - //initialize propertiesToCheck + + //initialize propertiesToCheck for (prop in mapping){ if (mapping.hasOwnProperty(prop)){ for (i=0, len=mapping[prop].length; i < len; i++){ @@ -1894,35 +1894,35 @@ CSSLint.addRule({ } } } - + function startRule(event){ properties = {}; } - + //event handler for end of rules function endRule(event){ - + var prop, i, len, total; - + //check which properties this rule has for (prop in mapping){ if (mapping.hasOwnProperty(prop)){ total=0; - + for (i=0, len=mapping[prop].length; i < len; i++){ total += properties[mapping[prop][i]] ? 1 : 0; } - + if (total == mapping[prop].length){ reporter.report("The properties " + mapping[prop].join(", ") + " can be replaced by " + prop + ".", event.line, event.col, rule); } } } - } - + } + parser.addListener("startrule", startRule); parser.addListener("startfontface", startRule); - + //check for use of "font-size" parser.addListener("property", function(event){ var name = event.property.toString().toLowerCase(), @@ -1934,7 +1934,7 @@ CSSLint.addRule({ }); parser.addListener("endrule", endRule); - parser.addListener("endfontface", endRule); + parser.addListener("endfontface", endRule); } @@ -2083,14 +2083,14 @@ CSSLint.addRule({ part = selector.parts[selector.parts.length-1]; if (part.elementName && /(h[1-6])/i.test(part.elementName.toString())){ - + for (j=0; j < part.modifiers.length; j++){ if (part.modifiers[j].type == "pseudo"){ pseudo = true; break; } } - + if (!pseudo){ headings[RegExp.$1]++; if (headings[RegExp.$1] > 1) { @@ -2100,11 +2100,11 @@ CSSLint.addRule({ } } }); - + parser.addListener("endstylesheet", function(event){ var prop, messages = []; - + for (prop in headings){ if (headings.hasOwnProperty(prop)){ if (headings[prop] > 1){ @@ -2112,11 +2112,11 @@ CSSLint.addRule({ } } } - + if (messages.length){ reporter.rollupWarn("You have " + messages.join(", ") + " defined in this stylesheet.", rule); } - }); + }); } }); @@ -2145,7 +2145,7 @@ CSSLint.addRule({ for (i=0; i < selectors.length; i++){ selector = selectors[i]; - + part = selector.parts[selector.parts.length-1]; if (part.elementName == "*"){ reporter.report(rule.desc, part.line, part.col, rule); @@ -2172,7 +2172,7 @@ CSSLint.addRule({ var rule = this; parser.addListener("startrule", function(event){ - + var selectors = event.selectors, selector, part, @@ -2181,18 +2181,18 @@ CSSLint.addRule({ for (i=0; i < selectors.length; i++){ selector = selectors[i]; - + part = selector.parts[selector.parts.length-1]; if (part.type == parser.SELECTOR_PART_TYPE){ for (k=0; k < part.modifiers.length; k++){ modifier = part.modifiers[k]; if (modifier.type == "attribute" && (!part.elementName || part.elementName == "*")){ - reporter.report(rule.desc, part.line, part.col, rule); + reporter.report(rule.desc, part.line, part.col, rule); } } } - - } + + } }); } @@ -2221,70 +2221,70 @@ CSSLint.addRule({ "-webkit-border-top-right-radius": "border-top-right-radius", "-webkit-border-bottom-left-radius": "border-bottom-left-radius", "-webkit-border-bottom-right-radius": "border-bottom-right-radius", - + "-o-border-radius": "border-radius", "-o-border-top-left-radius": "border-top-left-radius", "-o-border-top-right-radius": "border-top-right-radius", "-o-border-bottom-left-radius": "border-bottom-left-radius", "-o-border-bottom-right-radius": "border-bottom-right-radius", - + "-moz-border-radius": "border-radius", "-moz-border-radius-topleft": "border-top-left-radius", "-moz-border-radius-topright": "border-top-right-radius", "-moz-border-radius-bottomleft": "border-bottom-left-radius", - "-moz-border-radius-bottomright": "border-bottom-right-radius", - + "-moz-border-radius-bottomright": "border-bottom-right-radius", + "-moz-column-count": "column-count", "-webkit-column-count": "column-count", - + "-moz-column-gap": "column-gap", "-webkit-column-gap": "column-gap", - + "-moz-column-rule": "column-rule", "-webkit-column-rule": "column-rule", - + "-moz-column-rule-style": "column-rule-style", "-webkit-column-rule-style": "column-rule-style", - + "-moz-column-rule-color": "column-rule-color", "-webkit-column-rule-color": "column-rule-color", - + "-moz-column-rule-width": "column-rule-width", "-webkit-column-rule-width": "column-rule-width", - + "-moz-column-width": "column-width", "-webkit-column-width": "column-width", - + "-webkit-column-span": "column-span", "-webkit-columns": "columns", - + "-moz-box-shadow": "box-shadow", "-webkit-box-shadow": "box-shadow", - + "-moz-transform" : "transform", "-webkit-transform" : "transform", "-o-transform" : "transform", "-ms-transform" : "transform", - + "-moz-transform-origin" : "transform-origin", "-webkit-transform-origin" : "transform-origin", "-o-transform-origin" : "transform-origin", "-ms-transform-origin" : "transform-origin", - + "-moz-box-sizing" : "box-sizing", "-webkit-box-sizing" : "box-sizing", - + "-moz-user-select" : "user-select", "-khtml-user-select" : "user-select", - "-webkit-user-select" : "user-select" + "-webkit-user-select" : "user-select" }; //event handler for beginning of rules function startRule(){ properties = {}; - num=1; + num=1; } - + //event handler for end of rules function endRule(event){ var prop, @@ -2304,7 +2304,7 @@ CSSLint.addRule({ needed = needsStandard[i].needed; actual = needsStandard[i].actual; - if (!properties[needed]){ + if (!properties[needed]){ reporter.report("Missing standard property '" + needed + "' to go along with '" + actual + "'.", properties[actual][0].name.line, properties[actual][0].name.col, rule); } else { //make sure standard property is last @@ -2314,13 +2314,13 @@ CSSLint.addRule({ } } - } - + } + parser.addListener("startrule", startRule); parser.addListener("startfontface", startRule); parser.addListener("startpage", startRule); parser.addListener("startpagemargin", startRule); - parser.addListener("startkeyframerule", startRule); + parser.addListener("startkeyframerule", startRule); parser.addListener("property", function(event){ var name = event.property.text.toLowerCase(); @@ -2336,7 +2336,7 @@ CSSLint.addRule({ parser.addListener("endfontface", endRule); parser.addListener("endpage", endRule); parser.addListener("endpagemargin", endRule); - parser.addListener("endkeyframerule", endRule); + parser.addListener("endkeyframerule", endRule); } }); @@ -2359,7 +2359,7 @@ CSSLint.addRule({ //count how many times "float" is used parser.addListener("property", function(event){ var parts = event.value.parts, - i = 0, + i = 0, len = parts.length; while(i < len){ @@ -2393,7 +2393,7 @@ CSSLint.addRule({ if (!str || str.constructor !== String) { return ""; } - + return str.replace(/[\"&><]/g, function(match) { switch (match) { case "\"": @@ -2403,7 +2403,7 @@ CSSLint.addRule({ case "<": return "<"; case ">": - return ">"; + return ">"; } }); }; @@ -2428,7 +2428,7 @@ CSSLint.addRule({ endFormat: function(){ return ""; }, - + /** * Returns message when there is a file read error. * @param {String} filename The name of the file that caused the error. @@ -2534,11 +2534,11 @@ CSSLint.addFormatter({ if (message.rollup) { output += filename + ": " + capitalize(message.type) + " - " + message.message + "\n"; } else { - output += filename + ": " + "line " + message.line + + output += filename + ": " + "line " + message.line + ", col " + message.col + ", " + capitalize(message.type) + " - " + message.message + "\n"; } }); - + return output; } }); @@ -2583,7 +2583,7 @@ CSSLint.addFormatter({ * - & is the escape sequence for & * - < is the escape sequence for < * - > is the escape sequence for > - * + * * @param {String} message to escape * @return escaped message as {String} */ @@ -2756,7 +2756,7 @@ CSSLint.addFormatter({ * - & is the escape sequence for & * - < is the escape sequence for < * - > is the escape sequence for > - * + * * @param {String} message to escape * @return escaped message as {String} */ @@ -2768,7 +2768,7 @@ CSSLint.addFormatter({ }; if (messages.length > 0) { - + output.push(""); CSSLint.Util.forEach(messages, function (message, i) { if (message.rollup) { @@ -2827,7 +2827,7 @@ CSSLint.addFormatter({ shortFilename = filename; if (pos === -1){ - pos = filename.lastIndexOf("\\"); + pos = filename.lastIndexOf("\\"); } if (pos > -1){ shortFilename = filename.substring(pos+1); @@ -2844,7 +2844,7 @@ CSSLint.addFormatter({ output += "\n" + message.evidence; } }); - + return output; } }); diff --git a/release/csslint-rhino.js b/release/csslint-rhino.js index 082a2765..587d438b 100644 --- a/release/csslint-rhino.js +++ b/release/csslint-rhino.js @@ -66,7 +66,7 @@ function EventTarget(){ * @property _listeners * @private */ - this._listeners = {}; + this._listeners = {}; } EventTarget.prototype = { @@ -88,14 +88,14 @@ EventTarget.prototype = { this._listeners[type].push(listener); }, - + /** * Fires an event based on the passed-in object. * @param {Object|String} event An object with at least a 'type' attribute * or a string indicating the event name. * @return {void} * @method fire - */ + */ fire: function(event){ if (typeof event == "string"){ event = { type: event }; @@ -103,19 +103,19 @@ EventTarget.prototype = { if (typeof event.target != "undefined"){ event.target = this; } - + if (typeof event.type == "undefined"){ throw new Error("Event object missing 'type' property."); } - + if (this._listeners[event.type]){ - + //create a copy of the array and use that so listeners can't chane var listeners = this._listeners[event.type].concat(); for (var i=0, len=listeners.length; i < len; i++){ listeners[i].call(this, event); } - } + } }, /** @@ -134,9 +134,9 @@ EventTarget.prototype = { break; } } - - - } + + + } } }; /** @@ -500,7 +500,7 @@ SyntaxUnit.prototype = { //restore constructor constructor: SyntaxUnit, - + /** * Returns the text representation of the unit. * @return {String} The text representation of the unit. @@ -509,7 +509,7 @@ SyntaxUnit.prototype = { valueOf: function(){ return this.toString(); }, - + /** * Returns the text representation of the unit. * @return {String} The text representation of the unit. @@ -527,7 +527,7 @@ SyntaxUnit.prototype = { * @class TokenStreamBase * @namespace parserlib.util * @constructor - * @param {String|StringReader} input The text to tokenize or a reader from + * @param {String|StringReader} input The text to tokenize or a reader from * which to read the input. */ function TokenStreamBase(input, tokenData){ @@ -539,15 +539,15 @@ function TokenStreamBase(input, tokenData){ * @private */ this._reader = input ? new StringReader(input.toString()) : null; - + /** * Token object for the last consumed token. * @type Token * @property _token * @private */ - this._token = null; - + this._token = null; + /** * The array of token information. * @type Array @@ -555,7 +555,7 @@ function TokenStreamBase(input, tokenData){ * @private */ this._tokenData = tokenData; - + /** * Lookahead token buffer. * @type Array @@ -563,7 +563,7 @@ function TokenStreamBase(input, tokenData){ * @private */ this._lt = []; - + /** * Lookahead token buffer index. * @type int @@ -571,7 +571,7 @@ function TokenStreamBase(input, tokenData){ * @private */ this._ltIndex = 0; - + this._ltIndexCache = []; } @@ -591,7 +591,7 @@ TokenStreamBase.createTokenData = function(tokens){ tokenData = tokens.concat([]), i = 0, len = tokenData.length+1; - + tokenData.UNKNOWN = -1; tokenData.unshift({name:"EOF"}); @@ -602,27 +602,27 @@ TokenStreamBase.createTokenData = function(tokens){ typeMap[tokenData[i].text] = i; } } - + tokenData.name = function(tt){ return nameMap[tt]; }; - + tokenData.type = function(c){ return typeMap[c]; }; - + return tokenData; }; TokenStreamBase.prototype = { //restore constructor - constructor: TokenStreamBase, - + constructor: TokenStreamBase, + //------------------------------------------------------------------------- // Matching methods //------------------------------------------------------------------------- - + /** * Determines if the next token matches the given token type. * If so, that token is consumed; if not, the token is placed @@ -638,27 +638,27 @@ TokenStreamBase.prototype = { * @method match */ match: function(tokenTypes, channel){ - + //always convert to an array, makes things easier if (!(tokenTypes instanceof Array)){ tokenTypes = [tokenTypes]; } - + var tt = this.get(channel), i = 0, len = tokenTypes.length; - + while(i < len){ if (tt == tokenTypes[i++]){ return true; } } - + //no match found, put the token back this.unget(); return false; - }, - + }, + /** * Determines if the next token matches the given token type. * If so, that token is consumed; if not, an error is thrown. @@ -669,7 +669,7 @@ TokenStreamBase.prototype = { * provided, reads from the default (unnamed) channel. * @return {void} * @method mustMatch - */ + */ mustMatch: function(tokenTypes, channel){ var token; @@ -679,17 +679,17 @@ TokenStreamBase.prototype = { tokenTypes = [tokenTypes]; } - if (!this.match.apply(this, arguments)){ + if (!this.match.apply(this, arguments)){ token = this.LT(1); - throw new SyntaxError("Expected " + this._tokenData[tokenTypes[0]].name + + throw new SyntaxError("Expected " + this._tokenData[tokenTypes[0]].name + " at line " + token.startLine + ", col " + token.startCol + ".", token.startLine, token.startCol); } }, - + //------------------------------------------------------------------------- // Consuming methods //------------------------------------------------------------------------- - + /** * Keeps reading from the token stream until either one of the specified * token types is found or until the end of the input is reached. @@ -702,21 +702,21 @@ TokenStreamBase.prototype = { * @method advance */ advance: function(tokenTypes, channel){ - + while(this.LA(0) !== 0 && !this.match(tokenTypes, channel)){ this.get(); } - return this.LA(0); + return this.LA(0); }, - + /** - * Consumes the next token from the token stream. + * Consumes the next token from the token stream. * @return {int} The token type of the token that was just consumed. * @method get - */ + */ get: function(channel){ - + var tokenInfo = this._tokenData, reader = this._reader, value, @@ -725,14 +725,14 @@ TokenStreamBase.prototype = { found = false, token, info; - + //check the lookahead buffer first - if (this._lt.length && this._ltIndex >= 0 && this._ltIndex < this._lt.length){ - + if (this._lt.length && this._ltIndex >= 0 && this._ltIndex < this._lt.length){ + i++; this._token = this._lt[this._ltIndex++]; info = tokenInfo[this._token.type]; - + //obey channels logic while((info.channel !== undefined && channel !== info.channel) && this._ltIndex < this._lt.length){ @@ -740,7 +740,7 @@ TokenStreamBase.prototype = { info = tokenInfo[this._token.type]; i++; } - + //here be dragons if ((info.channel === undefined || channel === info.channel) && this._ltIndex <= this._lt.length){ @@ -748,45 +748,45 @@ TokenStreamBase.prototype = { return this._token.type; } } - + //call token retriever method token = this._getToken(); //if it should be hidden, don't save a token if (token.type > -1 && !tokenInfo[token.type].hide){ - + //apply token channel token.channel = tokenInfo[token.type].channel; - + //save for later this._token = token; this._lt.push(token); //save space that will be moved (must be done before array is truncated) - this._ltIndexCache.push(this._lt.length - this._ltIndex + i); - + this._ltIndexCache.push(this._lt.length - this._ltIndex + i); + //keep the buffer under 5 items if (this._lt.length > 5){ - this._lt.shift(); + this._lt.shift(); } - + //also keep the shift buffer under 5 items if (this._ltIndexCache.length > 5){ this._ltIndexCache.shift(); } - + //update lookahead index this._ltIndex = this._lt.length; } - + /* * Skip to the next token if: * 1. The token type is marked as hidden. * 2. The token type has a channel specified and it isn't the current channel. */ info = tokenInfo[token.type]; - if (info && - (info.hide || + if (info && + (info.hide || (info.channel !== undefined && channel !== info.channel))){ return this.get(channel); } else { @@ -794,7 +794,7 @@ TokenStreamBase.prototype = { return token.type; } }, - + /** * Looks ahead a certain number of tokens and returns the token type at * that position. This will throw an error if you lookahead past the @@ -813,34 +813,34 @@ TokenStreamBase.prototype = { if (index > 5){ throw new Error("Too much lookahead."); } - + //get all those tokens while(total){ - tt = this.get(); - total--; + tt = this.get(); + total--; } - + //unget all those tokens while(total < index){ this.unget(); total++; } } else if (index < 0){ - + if(this._lt[this._ltIndex+index]){ tt = this._lt[this._ltIndex+index].type; } else { throw new Error("Too much lookbehind."); } - + } else { tt = this._token.type; } - + return tt; - + }, - + /** * Looks ahead a certain number of tokens and returns the token at * that position. This will throw an error if you lookahead past the @@ -850,18 +850,18 @@ TokenStreamBase.prototype = { * current token, 1 for the next, -1 for the previous, etc. * @return {Object} The token of the token in the given position. * @method LA - */ + */ LT: function(index){ - + //lookahead first to prime the token buffer this.LA(index); - + //now find the token, subtract one because _ltIndex is already at the next index - return this._lt[this._ltIndex+index-1]; + return this._lt[this._ltIndex+index-1]; }, - + /** - * Returns the token type for the next token in the stream without + * Returns the token type for the next token in the stream without * consuming it. * @return {int} The token type of the next token in the stream. * @method peek @@ -869,7 +869,7 @@ TokenStreamBase.prototype = { peek: function(){ return this.LA(1); }, - + /** * Returns the actual token object for the last consumed token. * @return {Token} The token object for the last consumed token. @@ -878,7 +878,7 @@ TokenStreamBase.prototype = { token: function(){ return this._token; }, - + /** * Returns the name of the token for the given token type. * @param {int} tokenType The type of token to get the name of. @@ -893,22 +893,22 @@ TokenStreamBase.prototype = { return this._tokenData[tokenType].name; } }, - + /** * Returns the token type value for the given token name. * @param {String} tokenName The name of the token whose value should be returned. * @return {int} The token type value for the given token name or -1 * for an unknown token. * @method tokenName - */ + */ tokenType: function(tokenName){ return this._tokenData[tokenName] || -1; }, - + /** * Returns the last consumed token to the token stream. * @method unget - */ + */ unget: function(){ //if (this._ltIndex > -1){ if (this._ltIndexCache.length){ @@ -1144,12 +1144,12 @@ var Colors = { * @class Combinator * @extends parserlib.util.SyntaxUnit * @constructor - * @param {String} text The text representation of the unit. + * @param {String} text The text representation of the unit. * @param {int} line The line of text on which the unit resides. * @param {int} col The column of text on which the unit resides. */ function Combinator(text, line, col){ - + SyntaxUnit.call(this, text, line, col, Parser.COMBINATOR_TYPE); /** @@ -1158,7 +1158,7 @@ function Combinator(text, line, col){ * @property type */ this.type = "unknown"; - + //pretty simple if (/^\s+$/.test(text)){ this.type = "descendant"; @@ -1187,7 +1187,7 @@ Combinator.prototype.constructor = Combinator; * @param {SyntaxUnit} value The value of the feature or null if none. */ function MediaFeature(name, value){ - + SyntaxUnit.call(this, "(" + name + (value !== null ? ":" + value : "") + ")", name.startLine, name.startCol, Parser.MEDIA_FEATURE_TYPE); /** @@ -1223,8 +1223,8 @@ MediaFeature.prototype.constructor = MediaFeature; * @param {int} col The column of text on which the unit resides. */ function MediaQuery(modifier, mediaType, features, line, col){ - - SyntaxUnit.call(this, (modifier ? modifier + " ": "") + (mediaType ? mediaType : "") + (mediaType && features.length > 0 ? " and " : "") + features.join(" and "), line, col, Parser.MEDIA_QUERY_TYPE); + + SyntaxUnit.call(this, (modifier ? modifier + " ": "") + (mediaType ? mediaType : "") + (mediaType && features.length > 0 ? " and " : "") + features.join(" and "), line, col, Parser.MEDIA_QUERY_TYPE); /** * The media modifier ("not" or "only") @@ -1238,8 +1238,8 @@ function MediaQuery(modifier, mediaType, features, line, col){ * @type String * @property mediaType */ - this.mediaType = mediaType; - + this.mediaType = mediaType; + /** * The parts that make up the selector. * @type Array @@ -2812,7 +2812,7 @@ Parser.prototype = function(){ var tokenStream = this._tokenStream, values = [], - //valueParts = [], + //valueParts = [], value = null, operator = null; @@ -2829,9 +2829,9 @@ Parser.prototype = function(){ values.push(operator); } /*else { //if there's not an operator, you have a full value - values.push(new PropertyValue(valueParts, valueParts[0].line, valueParts[0].col)); - valueParts = []; - }*/ + values.push(new PropertyValue(valueParts, valueParts[0].line, valueParts[0].col)); + valueParts = []; + }*/ value = this._term(); @@ -2843,7 +2843,7 @@ Parser.prototype = function(){ } while(true); } - //cleanup + //cleanup /*if (valueParts.length){ values.push(new PropertyValue(valueParts, valueParts[0].line, valueParts[0].col)); }*/ @@ -3544,7 +3544,7 @@ var Properties = { "animation-name" : { multi: "none | ", comma: true }, "animation-play-state" : { multi: "running | paused", comma: true }, "animation-timing-function" : 1, - + //vendor prefixed "-moz-animation-delay" : { multi: "