1
0
mirror of https://github.com/thangisme/notes.git synced 2024-11-01 08:37:16 -04:00
notes/node_modules/stylelint/lib/rules/max-line-length/index.js
Patrick Marsceill b7b0d0d7bf
Initial commit
2017-03-09 13:16:08 -05:00

137 lines
4.0 KiB
JavaScript

"use strict"
const execall = require("execall")
const optionsMatches = require("../../utils/optionsMatches")
const report = require("../../utils/report")
const ruleMessages = require("../../utils/ruleMessages")
const validateOptions = require("../../utils/validateOptions")
const _ = require("lodash")
const styleSearch = require("style-search")
const ruleName = "max-line-length"
const messages = ruleMessages(ruleName, {
expected: l => `Expected line length to be no more than ${l} characters`,
})
const rule = function (maxLength, options) {
return (root, result) => {
const validOptions = validateOptions(result, ruleName, {
actual: maxLength,
possible: _.isNumber,
}, {
actual: options,
possible: {
ignore: [
"non-comments",
"comments",
],
ignorePattern: [_.isString],
},
optional: true,
})
if (!validOptions) {
return
}
const rootString = root.source.input.css
const ignoreNonComments = optionsMatches(options, "ignore", "non-comments")
const ignoreComments = optionsMatches(options, "ignore", "comments")
// Check first line
checkNewline({ endIndex: 0 })
// Check subsequent lines
styleSearch({ source: rootString, target: ["\n"], comments: "check" }, checkNewline)
function complain(index) {
report({
index,
result,
ruleName,
message: messages.expected(maxLength),
node: root,
})
}
function checkNewline(match) {
let nextNewlineIndex = rootString.indexOf("\n", match.endIndex)
if (rootString[nextNewlineIndex - 1] === "\r") {
nextNewlineIndex -= 1
}
// Accommodate last line
if (nextNewlineIndex === -1) {
nextNewlineIndex = rootString.length
}
const rawLineLength = nextNewlineIndex - match.endIndex
const lineText = rootString.slice(match.endIndex, nextNewlineIndex)
if (optionsMatches(options, "ignorePattern", lineText)) {
return
}
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.
// **Note that the length of any url arguments or import urls
// are excluded from the calculation.**
if (rawLineLength - urlArgumentsLength - importUrlsLength <= maxLength) {
return
}
const complaintIndex = nextNewlineIndex - 1
if (ignoreComments) {
if (match.insideComment) {
return
}
// This trimming business is to notice when the line starts a
// comment but that comment is indented, e.g.
// /* something here */
const nextTwoChars = rootString.slice(match.endIndex).trim().slice(0, 2)
if (nextTwoChars === "/*" || nextTwoChars === "//") {
return
}
}
if (ignoreNonComments) {
if (match.insideComment) {
return complain(complaintIndex)
}
// This trimming business is to notice when the line starts a
// comment but that comment is indented, e.g.
// /* something here */
const nextTwoChars = rootString.slice(match.endIndex).trim().slice(0, 2)
if (nextTwoChars !== "/*" && nextTwoChars !== "//") {
return
}
return complain(complaintIndex)
}
// If there are no spaces besides initial (indent) spaces, ignore it
const lineString = rootString.slice(match.endIndex, nextNewlineIndex)
if (lineString.replace(/^\s+/, "").indexOf(" ") === -1) {
return
}
return complain(complaintIndex)
}
}
}
rule.ruleName = ruleName
rule.messages = messages
module.exports = rule