mirror of
https://github.com/thangisme/notes.git
synced 2024-11-01 08:37:16 -04:00
98 lines
2.9 KiB
JavaScript
98 lines
2.9 KiB
JavaScript
"use strict"
|
|
|
|
const hasBlock = require("../../utils/hasBlock")
|
|
const optionsMatches = require("../../utils/optionsMatches")
|
|
const report = require("../../utils/report")
|
|
const ruleMessages = require("../../utils/ruleMessages")
|
|
const validateOptions = require("../../utils/validateOptions")
|
|
const _ = require("lodash")
|
|
|
|
const ruleName = "max-nesting-depth"
|
|
|
|
const messages = ruleMessages(ruleName, {
|
|
expected: depth => `Expected nesting depth to be no more than ${depth}`,
|
|
})
|
|
|
|
const rule = function (max, options) {
|
|
const ignoreAtRulesWithoutDeclarationBlocks = optionsMatches(options, "ignore", "at-rules-without-declaration-blocks") || optionsMatches(options, "ignore", "blockless-at-rules")
|
|
const isIgnoreAtRule = node => node.type === "atrule" && optionsMatches(options, "ignoreAtRules", node.name)
|
|
|
|
return (root, result) => {
|
|
validateOptions(result, ruleName, {
|
|
actual: max,
|
|
possible: [_.isNumber],
|
|
}, {
|
|
optional: true,
|
|
actual: options,
|
|
possible: {
|
|
ignore: [
|
|
"at-rules-without-declaration-blocks",
|
|
"blockless-at-rules",
|
|
],
|
|
ignoreAtRules: [_.isString],
|
|
},
|
|
})
|
|
|
|
if (optionsMatches(options, "ignore", "at-rules-without-declaration-blocks")) {
|
|
result.warn((
|
|
"'max-nesting-depth\'s' \"at-rules-without-declaration-blocks\" option has been deprecated and in 8.0 will be removed. Instead use the \"blockless-at-rules\" option."
|
|
), {
|
|
stylelintType: "deprecation",
|
|
stylelintReference: "https://stylelint.io/user-guide/rules/max-nesting-depth/",
|
|
})
|
|
}
|
|
|
|
root.walkRules(checkStatement)
|
|
root.walkAtRules(checkStatement)
|
|
|
|
function checkStatement(statement) {
|
|
if (isIgnoreAtRule(statement)) {
|
|
return
|
|
}
|
|
if (!hasBlock(statement)) {
|
|
return
|
|
}
|
|
const depth = nestingDepth(statement)
|
|
if (depth > max) {
|
|
report({
|
|
ruleName,
|
|
result,
|
|
node: statement,
|
|
message: messages.expected(max),
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
function nestingDepth(node, level) {
|
|
level = level || 0
|
|
const parent = node.parent
|
|
|
|
if (isIgnoreAtRule(parent)) {
|
|
return 0
|
|
}
|
|
|
|
// The nesting depth level's computation has finished
|
|
// when this function, recursively called, receives
|
|
// a node that is not nested -- a direct child of the
|
|
// root node
|
|
if (parent.type === "root" || parent.type === "atrule" && parent.parent.type === "root") {
|
|
return level
|
|
}
|
|
|
|
if (ignoreAtRulesWithoutDeclarationBlocks && node.type === "atrule" && node.every(child => child.type !== "decl")) {
|
|
return nestingDepth(parent, level)
|
|
}
|
|
|
|
// Unless any of the conditions above apply, we want to
|
|
// add 1 to the nesting depth level and then check the parent,
|
|
// continuing to add and move up the hierarchy
|
|
// until we hit the root node
|
|
return nestingDepth(parent, level + 1)
|
|
}
|
|
}
|
|
|
|
rule.ruleName = ruleName
|
|
rule.messages = messages
|
|
module.exports = rule
|