Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 38 additions & 4 deletions src/rules/box-model.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,31 @@ CSSLint.addRule({
"padding-top": 1
},
properties,
boxSizing = false;
boxSizing = false,
selectors,
universalBoxSizing = false,
warnings = [];

// the universal selector (*) applies to all elements,
// so a box-sizing declared there makes the warnings unnecessary
function hasUniversalSelector() {
var i, part;

for (i = 0; i < selectors.length; i++) {
if (selectors[i].parts.length === 1) {
part = selectors[i].parts[0];
if (part.elementName === "*" && part.modifiers.length === 0) {
return true;
}
}
}
return false;
}

function startRule() {
function startRule(event) {
properties = {};
boxSizing = false;
selectors = event.selectors;
}

function endRule() {
Expand All @@ -48,7 +68,7 @@ CSSLint.addRule({
value = properties[prop].value;
// special case for padding
if (!(prop === "padding" && value.parts.length === 2 && value.parts[0].value === 0)) {
reporter.report("Using height with " + prop + " can sometimes make elements larger than you expect.", properties[prop].line, properties[prop].col, rule);
warnings.push({ message: "Using height with " + prop + " can sometimes make elements larger than you expect.", line: properties[prop].line, col: properties[prop].col });
}
}
}
Expand All @@ -60,7 +80,7 @@ CSSLint.addRule({
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);
warnings.push({ message: "Using width with " + prop + " can sometimes make elements larger than you expect.", line: properties[prop].line, col: properties[prop].col });
}
}
}
Expand Down Expand Up @@ -91,6 +111,9 @@ CSSLint.addRule({
properties[name] = 1;
} else if (name === "box-sizing") {
boxSizing = true;
if (selectors && hasUniversalSelector()) {
universalBoxSizing = true;
}
}
}

Expand All @@ -102,6 +125,17 @@ CSSLint.addRule({
parser.addListener("endpagemargin", endRule);
parser.addListener("endkeyframerule", endRule);
parser.addListener("endviewport", endRule);

parser.addListener("endstylesheet", function() {
var i;

if (universalBoxSizing) {
return;
}
for (i = 0; i < warnings.length; i++) {
reporter.report(warnings[i].message, warnings[i].line, warnings[i].col, rule);
}
});
}

});
36 changes: 36 additions & 0 deletions tests/rules/box-model.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,42 @@
Assert.areEqual("Using width with padding can sometimes make elements larger than you expect.", result.messages[0].message);
},

"Using width and padding when the universal selector declares box-sizing should not result in a warning": function() {
var result = CSSLint.verify("* { box-sizing: border-box; } .foo { width: 100px; padding: 10px; }", { "box-model": 1 });
Assert.areEqual(0, result.messages.length);
},

"Using width and padding when a universal selector group declares box-sizing should not result in a warning": function() {
var result = CSSLint.verify("*, *:before, *:after { box-sizing: border-box; } .foo { width: 100px; padding: 10px; }", { "box-model": 1 });
Assert.areEqual(0, result.messages.length);
},

"Using width and padding before the universal selector declares box-sizing should not result in a warning": function() {
var result = CSSLint.verify(".foo { width: 100px; padding: 10px; } * { box-sizing: border-box; }", { "box-model": 1 });
Assert.areEqual(0, result.messages.length);
},

"Using width and padding when another selector declares box-sizing should result in a warning": function() {
var result = CSSLint.verify(".bar { box-sizing: border-box; } .foo { width: 100px; padding: 10px; }", { "box-model": 1 });
Assert.areEqual(1, result.messages.length);
Assert.areEqual("warning", result.messages[0].type);
Assert.areEqual("Using width with padding can sometimes make elements larger than you expect.", result.messages[0].message);
},

"Using width and padding when a qualified universal selector declares box-sizing should result in a warning": function() {
var result = CSSLint.verify("*.bar { box-sizing: border-box; } .foo { width: 100px; padding: 10px; }", { "box-model": 1 });
Assert.areEqual(1, result.messages.length);
Assert.areEqual("warning", result.messages[0].type);
Assert.areEqual("Using width with padding can sometimes make elements larger than you expect.", result.messages[0].message);
},

"Using width and padding when a descendant universal selector declares box-sizing should result in a warning": function() {
var result = CSSLint.verify("div * { box-sizing: border-box; } .foo { width: 100px; padding: 10px; }", { "box-model": 1 });
Assert.areEqual(1, result.messages.length);
Assert.areEqual("warning", result.messages[0].type);
Assert.areEqual("Using width with padding can sometimes make elements larger than you expect.", result.messages[0].message);
},

"Using width when padding is zero should not result in a warning": function() {
var result = CSSLint.verify(".foo { width: 100px; padding: 0; }", { "box-model": 1 });
Assert.areEqual(0, result.messages.length);
Expand Down