Skip to content

Commit

Permalink
Fix max-line-length column incorrect column (stylelint#2287)
Browse files Browse the repository at this point in the history
* Add a failing test for issue stylelint#2286

* Fix max-line-length column number for lines with urls

Closes stylelint#2286
  • Loading branch information
m-allanson authored and sergesemashko committed Mar 3, 2017
1 parent 11f0f47 commit 366e985
Show file tree
Hide file tree
Showing 4 changed files with 164 additions and 151 deletions.
4 changes: 2 additions & 2 deletions lib/rules/max-line-length/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ a { color: red }

Lines that exceed the maximum length but contain no whitespace (other than at the beginning of the line) are ignored.

When evaluating the line length, `url(...)` functions are collapsed into just `url()`, because typically you have no control over the length of its argument. This means that long `url()` functions should not contribute to warnings.
When evaluating the line length, the arguments of any `url(...)` functions are excluded from the calculation, because typically you have no control over the length of these arguments. This means that long `url()` functions should not contribute to warnings.

## Options

Expand Down Expand Up @@ -103,7 +103,7 @@ a { color: pink; }
```css
/*
* comment that is too long the max length
* comment that is too long the max length
* comment that is too long the max length
*
*/
a { color: pink; }
Expand Down
15 changes: 10 additions & 5 deletions lib/rules/max-line-length/__tests__/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,17 +81,22 @@ testRule(rule, {
code: "@import url(\"somethingsomethingsomethingsomething.css\") projection, tv;",
message: messages.expected(20),
line: 1,
column: 29,
column: 71,
}, {
code: "@import 'somethingsomethingsomethingsomething.css' projection, tv;",
message: messages.expected(20),
line: 1,
column: 24,
column: 66,
}, {
code: "@import 'svg-something<id=\"horse\">' screens, tv;",
message: messages.expected(20),
line: 1,
column: 21,
column: 48,
}, {
code: "a { background-image: url('some ignored url'); }",
message: messages.expected(20),
line: 1,
column: 48,
} ],
})

Expand Down Expand Up @@ -120,12 +125,12 @@ testRule(rule, {
code: "@import url(\"somethingsomethingsomethingsomething.css\") projection, screen;",
message: messages.expected(30),
line: 1,
column: 33,
column: 75,
}, {
code: "@import \"somethingsomethingsomethingsomething.css\" screen, projection, tv;",
message: messages.expected(30),
line: 1,
column: 32,
column: 74,
} ],
})

Expand Down
24 changes: 16 additions & 8 deletions lib/rules/max-line-length/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"use strict"

const execall = require("execall")
const optionsMatches = require("../../utils/optionsMatches")
const report = require("../../utils/report")
const ruleMessages = require("../../utils/ruleMessages")
Expand Down Expand Up @@ -32,13 +33,7 @@ const rule = function (maxLength, options) {
return
}

// Collapse all urls into something nice and short,
// so they do not throw the game
const rootString = root.toString()
// Replace `url(something)` with `url()`
.replace(/url\(.*\)/ig, "url()")
// Replace `@import "something"` with `@import ""`
.replace(/\@import\s+['"].*['"]/ig, "@import ")

const ignoreNonComments = optionsMatches(options, "ignore", "non-comments")
const ignoreComments = optionsMatches(options, "ignore", "comments")
Expand Down Expand Up @@ -70,9 +65,22 @@ const rule = function (maxLength, options) {
nextNewlineIndex = rootString.length
}

const rawLineLength = nextNewlineIndex - match.endIndex
const lineText = rootString.slice(match.endIndex, nextNewlineIndex)

const urlArgumentsLength = execall(/url\((.*)\)/ig, lineText).reduce((result, match) => {
return result + _.get(match, "sub[0].length", 0)
}, 0)

const importUrlsLength = execall(/\@import\s+(['"].*['"])/ig, lineText).reduce((result, match) => {
return result + _.get(match, "sub[0].length", 0)
}, 0)

// If the line's length is less than or equal to the specified
// max, ignore it ... So anything below is liable to be complained about
if (nextNewlineIndex - match.endIndex <= maxLength) {
// max, ignore it ... So anything below is liable to be complained about.
// **Note that the length of any url arguments or import urls
// are excluded from the calculation.**
if (rawLineLength - urlArgumentsLength - importUrlsLength <= maxLength) {
return
}

Expand Down
Loading

0 comments on commit 366e985

Please sign in to comment.