* @param results {Object} with error and warning messages
* @param filename {String} relative file path
* @param options {Object} (UNUSED for now) specifies special handling of output
* @return {String} output for results
formatResults: function(results, filename/*, options*/) {
var messages = results.messages,
* Replace special characters before write to output.
* - single quotes is the escape sequence for double-quotes
* - & 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}
var escapeSpecialCharacters = function(str) {
if (!str || str.constructor !== String) {
return str.replace(/"/g, "'").replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
if (messages.length > 0) {
output.push("<file name=\""+filename+"\">");
CSSLint.Util.forEach(messages, function (message) {
output.push("<issue severity=\"" + message.type + "\" reason=\"" + escapeSpecialCharacters(message.message) + "\" evidence=\"" + escapeSpecialCharacters(message.evidence) + "\"/>");
output.push("<issue line=\"" + message.line + "\" char=\"" + message.col + "\" severity=\"" + message.type + "\"" +
" reason=\"" + escapeSpecialCharacters(message.message) + "\" evidence=\"" + escapeSpecialCharacters(message.evidence) + "\"/>");
* Return content to be printed before all file results.
* @return {String} to prepend before all results
startFormat: function() {
* Return content to be printed after all file results.
* @return {String} to append after all results
if (this.json.length > 0) {
if (this.json.length === 1) {
ret = JSON.stringify(this.json[0]);
ret = JSON.stringify(this.json);
* Given CSS Lint results for a file, return output for this format.
* @param results {Object} with error and warning messages
* @param filename {String} relative file path (Unused)
* @return {String} output for results
formatResults: function(results, filename, options) {
if (results.messages.length > 0 || !options.quiet) {
messages: results.messages,
name: "JUNIT XML format",
* Return opening root XML tag.
* @return {String} to prepend before all results
startFormat: function() {
return "<?xml version=\"1.0\" encoding=\"utf-8\"?><testsuites>";
* Return closing root XML tag.
* @return {String} to append after all results
* Given CSS Lint results for a file, return output for this format.
* @param results {Object} with error and warning messages
* @param filename {String} relative file path
* @param options {Object} (UNUSED for now) specifies special handling of output
* @return {String} output for results
formatResults: function(results, filename/*, options*/) {
var messages = results.messages,
* Generate a source string for a rule.
* JUNIT source strings usually resemble Java class names e.g
* net.csslint.SomeRuleName
* @return rule source as {String}
var generateSource = function(rule) {
if (!rule || !("name" in rule)) {
return "net.csslint." + rule.name.replace(/\s/g, "");
* Replace special characters before write to output.
* - single quotes is the escape sequence for double-quotes
* - < is the escape sequence for <
* - > is the escape sequence for >
* @param {String} message to escape
* @return escaped message as {String}
var escapeSpecialCharacters = function(str) {
if (!str || str.constructor !== String) {
return str.replace(/"/g, "'").replace(/</g, "<").replace(/>/g, ">");
if (messages.length > 0) {
messages.forEach(function (message) {
// since junit has no warning class
var type = message.type === "warning" ? "error" : message.type;
// ignore rollups for now
// build the test case separately, once joined
// we'll add it to a custom array filtered by type
output.push("<testcase time=\"0\" name=\"" + generateSource(message.rule) + "\">");
output.push("<" + type + " message=\"" + escapeSpecialCharacters(message.message) + "\"><![CDATA[" + message.line + ":" + message.col + ":" + escapeSpecialCharacters(message.evidence) + "]]></" + type + ">");
output.push("</testcase>");
output.unshift("<testsuite time=\"0\" tests=\"" + messages.length + "\" skipped=\"0\" errors=\"" + tests.error + "\" failures=\"" + tests.failure + "\" package=\"net.csslint\" name=\"" + filename + "\">");
output.push("</testsuite>");
* Return opening root XML tag.
* @return {String} to prepend before all results
startFormat: function() {
return "<?xml version=\"1.0\" encoding=\"utf-8\"?><lint>";
* Return closing root XML tag.
* @return {String} to append after all results
* Given CSS Lint results for a file, return output for this format.
* @param results {Object} with error and warning messages
* @param filename {String} relative file path
* @param options {Object} (UNUSED for now) specifies special handling of output
* @return {String} output for results
formatResults: function(results, filename/*, options*/) {
var messages = results.messages,
* Replace special characters before write to output.
* - single quotes is the escape sequence for double-quotes
* - & 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}
var escapeSpecialCharacters = function(str) {
if (!str || str.constructor !== String) {
return str.replace(/"/g, "'").replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
if (messages.length > 0) {
output.push("<file name=\""+filename+"\">");
CSSLint.Util.forEach(messages, function (message) {
output.push("<issue severity=\"" + message.type + "\" reason=\"" + escapeSpecialCharacters(message.message) + "\" evidence=\"" + escapeSpecialCharacters(message.evidence) + "\"/>");
if (message.rule && message.rule.id) {
rule = "rule=\"" + escapeSpecialCharacters(message.rule.id) + "\" ";
output.push("<issue " + rule + "line=\"" + message.line + "\" char=\"" + message.col + "\" severity=\"" + message.type + "\"" +
" reason=\"" + escapeSpecialCharacters(message.message) + "\" evidence=\"" + escapeSpecialCharacters(message.evidence) + "\"/>");
* Return content to be printed before all file results.
* @return {String} to prepend before all results
startFormat: function() {
* Return content to be printed after all file results.
* @return {String} to append after all results
* Given CSS Lint results for a file, return output for this format.
* @param results {Object} with error and warning messages
* @param filename {String} relative file path
* @param options {Object} (Optional) specifies special handling of output
* @return {String} output for results
formatResults: function(results, filename, options) {
var messages = results.messages,
if (messages.length === 0) {
return options.quiet ? "" : "\n\ncsslint: No errors in " + filename + ".";
output = "\n\ncsslint: There ";
if (messages.length === 1) {
output += "is 1 problem";
output += "are " + messages.length + " problems";
output += " in " + filename + ".";
var pos = filename.lastIndexOf("/"),
shortFilename = filename;
pos = filename.lastIndexOf("\\");
shortFilename = filename.substring(pos+1);
CSSLint.Util.forEach(messages, function (message, i) {
output = output + "\n\n" + shortFilename;
output += "\n" + (i+1) + ": " + message.type;
output += "\n" + message.message;
output += "\n" + (i+1) + ": " + message.type + " at line " + message.line + ", col " + message.col;
output += "\n" + message.message;
output += "\n" + message.evidence;