Skip to content

Commit

Permalink
Add isStandardSelector and reduce scope of isStandardRule
Browse files Browse the repository at this point in the history
  • Loading branch information
jeddy3 committed Apr 25, 2016
1 parent 7d6b327 commit aaa9a0f
Show file tree
Hide file tree
Showing 15 changed files with 79 additions and 32 deletions.
10 changes: 7 additions & 3 deletions src/rules/selector-class-pattern/index.js
Expand Up @@ -3,6 +3,7 @@ import selectorParser from "postcss-selector-parser"
import _ from "lodash"
import {
isStandardRule,
isStandardSelector,
report,
ruleMessages,
validateOptions,
Expand Down Expand Up @@ -36,13 +37,16 @@ export default function (pattern, options) {
root.walkRules(rule => {
if (!isStandardRule(rule)) { return }

const { selector } = rule
if (!isStandardSelector(selector)) { return }

// Only bother resolving selectors that have an interpolating &
if (shouldResolveNestedSelectors && hasInterpolatingAmpersand(rule.selector)) {
resolveNestedSelector(rule.selector, rule).forEach(selector => {
if (shouldResolveNestedSelectors && hasInterpolatingAmpersand(selector)) {
resolveNestedSelector(selector, rule).forEach(selector => {
selectorParser(s => checkSelector(s, rule)).process(selector)
})
} else {
selectorParser(s => checkSelector(s, rule)).process(rule.selector)
selectorParser(s => checkSelector(s, rule)).process(selector)
}
})

Expand Down
10 changes: 7 additions & 3 deletions src/rules/selector-id-pattern/index.js
Expand Up @@ -2,6 +2,7 @@ import selectorParser from "postcss-selector-parser"
import { isRegExp, isString } from "lodash"
import {
isStandardRule,
isStandardSelector,
report,
ruleMessages,
validateOptions,
Expand All @@ -25,16 +26,19 @@ export default function (pattern) {

root.walkRules(rule => {
if (!isStandardRule(rule)) { return }

selectorParser(checkSelector).process(rule.selector)

const { selector } = rule
if (!isStandardSelector(selector)) { return }

selectorParser(checkSelector).process(selector)

function checkSelector(fullSelector) {
fullSelector.eachInside(selectorNode => {
if (selectorNode.type !== "id") { return }
const { value, sourceIndex } = selectorNode

if (normalizedPattern.test(value)) { return }

report({
result,
ruleName,
Expand Down
2 changes: 2 additions & 0 deletions src/rules/selector-max-specificity/index.js
Expand Up @@ -3,6 +3,7 @@ import resolvedNestedSelector from "postcss-resolve-nested-selector"

import {
isStandardRule,
isStandardSelector,
report,
ruleMessages,
validateOptions,
Expand All @@ -28,6 +29,7 @@ export default function (max) {

root.walkRules(rule => {
if (!isStandardRule(rule)) { return }
if (!isStandardSelector(rule.selector)) { return }
// Using rule.selectors gets us each selector in the eventuality we have a comma separated set
rule.selectors.forEach(selector => {
resolvedNestedSelector(selector, rule).forEach(resolvedSelector => {
Expand Down
5 changes: 4 additions & 1 deletion src/rules/selector-no-attribute/index.js
@@ -1,6 +1,7 @@
import selectorParser from "postcss-selector-parser"
import {
isStandardRule,
isStandardSelector,
report,
ruleMessages,
validateOptions,
Expand All @@ -19,6 +20,8 @@ export default function (actual) {

root.walkRules(rule => {
if (!isStandardRule(rule)) { return }
const { selector } = rule
if (!isStandardSelector(selector)) { return }
selectorParser(selectorAST => {
selectorAST.eachAttribute(attribute => {
report({
Expand All @@ -30,7 +33,7 @@ export default function (actual) {
})
})
})
.process(rule.selector)
.process(selector)
})
}
}
5 changes: 4 additions & 1 deletion src/rules/selector-no-combinator/index.js
@@ -1,6 +1,7 @@
import selectorParser from "postcss-selector-parser"
import {
isStandardRule,
isStandardSelector,
report,
ruleMessages,
validateOptions,
Expand All @@ -19,6 +20,8 @@ export default function (actual) {

root.walkRules(rule => {
if (!isStandardRule(rule)) { return }
const { selector } = rule
if (!isStandardSelector(selector)) { return }
selectorParser(selectorAST => {
selectorAST.eachCombinator(combinator => {
report({
Expand All @@ -30,7 +33,7 @@ export default function (actual) {
})
})
})
.process(rule.selector)
.process(selector)
})
}
}
7 changes: 5 additions & 2 deletions src/rules/selector-no-id/index.js
@@ -1,7 +1,8 @@
import selectorParser from "postcss-selector-parser"
import {
isStandardRule,
isKeyframeRule,
isStandardRule,
isStandardSelector,
report,
ruleMessages,
validateOptions,
Expand All @@ -21,6 +22,8 @@ export default function (actual) {
root.walkRules(rule => {
if (!isStandardRule(rule)) { return }
if (isKeyframeRule(rule)) { return }
const { selector } = rule
if (!isStandardSelector(selector)) { return }
selectorParser(selectorAST => {
selectorAST.eachId(idNode => {

Expand All @@ -35,7 +38,7 @@ export default function (actual) {
})
})
})
.process(rule.selector)
.process(selector)
})
}
}
5 changes: 4 additions & 1 deletion src/rules/selector-no-type/index.js
Expand Up @@ -3,6 +3,7 @@ import { get } from "lodash"
import {
isKeyframeRule,
isStandardRule,
isStandardSelector,
isStandardTypeSelector,
optionsHaveIgnored,
report,
Expand Down Expand Up @@ -31,8 +32,10 @@ export default function (on, options) {

if (!isStandardRule(rule)) { return }
if (isKeyframeRule(rule)) { return }
const { selector } = rule
if (!isStandardSelector(selector)) { return }

selectorParser(checkSelector).process(rule.selector)
selectorParser(checkSelector).process(selector)

function checkSelector(selectorAST) {
selectorAST.eachTag(tag => {
Expand Down
5 changes: 4 additions & 1 deletion src/rules/selector-no-universal/index.js
@@ -1,6 +1,7 @@
import selectorParser from "postcss-selector-parser"
import {
isStandardRule,
isStandardSelector,
report,
ruleMessages,
validateOptions,
Expand All @@ -19,6 +20,8 @@ export default function (actual) {

root.walkRules(rule => {
if (!isStandardRule(rule)) { return }
const { selector } = rule
if (!isStandardSelector(selector)) { return }
selectorParser(selectorAST => {
selectorAST.eachUniversal(universal => {
report({
Expand All @@ -30,7 +33,7 @@ export default function (actual) {
})
})
})
.process(rule.selector)
.process(selector)
})
}
}
5 changes: 4 additions & 1 deletion src/rules/selector-no-vendor-prefix/index.js
@@ -1,6 +1,7 @@
import selectorParser from "postcss-selector-parser"
import {
isStandardRule,
isStandardSelector,
report,
ruleMessages,
isAutoprefixable,
Expand All @@ -20,6 +21,8 @@ export default function (actual) {

root.walkRules(rule => {
if (!isStandardRule(rule)) { return }
const { selector } = rule
if (!isStandardSelector(selector)) { return }
selectorParser(selectorTree => {
selectorTree.eachPseudo(pseudoNode => {
if (isAutoprefixable.selector(pseudoNode.value)) {
Expand All @@ -32,7 +35,7 @@ export default function (actual) {
})
}
})
}).process(rule.selector)
}).process(selector)
})
}
}
5 changes: 4 additions & 1 deletion src/rules/selector-type-case/index.js
Expand Up @@ -2,6 +2,7 @@ import selectorParser from "postcss-selector-parser"
import {
isKeyframeRule,
isStandardRule,
isStandardSelector,
isStandardTypeSelector,
report,
ruleMessages,
Expand Down Expand Up @@ -29,6 +30,8 @@ export default function (expectation) {

if (!isStandardRule(rule)) { return }
if (isKeyframeRule(rule)) { return }
const { selector } = rule
if (!isStandardSelector(selector)) { return }

function checkSelector(selectorAST) {
selectorAST.eachTag(tag => {
Expand All @@ -50,7 +53,7 @@ export default function (expectation) {
})
}

selectorParser(checkSelector).process(rule.selector)
selectorParser(checkSelector).process(selector)
})
}
}
16 changes: 1 addition & 15 deletions src/utils/__tests__/isStandardRule-test.js
@@ -1,11 +1,10 @@
import isStandardRule from "../isStandardRule"
import less from "postcss-less"
import scss from "postcss-scss"
import postcss from "postcss"
import test from "tape"

test("isStandardRule", t => {
t.plan(16)
t.plan(15)

rules("a {}", rule => {
t.ok(isStandardRule(rule), "type")
Expand All @@ -30,10 +29,6 @@ test("isStandardRule", t => {
t.notOk(isStandardRule(rule), "custom-property-set")
})

scssRules(".n-#{$n}", rule => {
t.notOk(isStandardRule(rule), "scss interpolation")
})

lessRules(".mixin-name(@var);", rule => {
t.notOk(isStandardRule(rule), "called Less class parametric mixin")
})
Expand All @@ -58,9 +53,6 @@ test("isStandardRule", t => {
lessRules("#namespace.mixin-name;", rule => {
t.notOk(isStandardRule(rule), "called namespaced Less mixin (compound)")
})
lessRules(".n-@{n}", rule => {
t.notOk(isStandardRule(rule), "Less interpolation")
})
})

function rules(css, cb) {
Expand All @@ -74,9 +66,3 @@ function lessRules(css, cb) {
result.root.walkRules(cb)
})
}

function scssRules(css, cb) {
postcss().process(css, { syntax: scss }).then(result => {
result.root.walkRules(cb)
})
}
19 changes: 19 additions & 0 deletions src/utils/__tests__/isStandardSelector-test.js
@@ -0,0 +1,19 @@
import test from "tape"
import isStandardSelector from "../isStandardSelector"

test("isStandardSelector", t => {
t.ok(isStandardSelector("a"), "type")
t.ok(isStandardSelector(".a"), "class")
t.ok(isStandardSelector("[a=a]"), "attribute")
t.ok(isStandardSelector("*"), "universal")
t.ok(isStandardSelector("a:last-child"), "pseudo-class")
t.ok(isStandardSelector("a:not(.b)"), "pseudo-class with function")
t.ok(isStandardSelector("a::after"), "pseudo-element")
t.ok(isStandardSelector("a.b"), "compound")
t.ok(isStandardSelector("a > b"), "complex")
t.ok(isStandardSelector("a, b"), "list")
t.notOk(isStandardSelector("#{50% - $n}"), "SCSS interpolation (id)")
t.notOk(isStandardSelector(".n-#{$n}"), "SCSS interpolation (class)")
t.notOk(isStandardSelector(".n-@{n}"), "Less interpolation")
t.end()
})
1 change: 1 addition & 0 deletions src/utils/index.js
Expand Up @@ -18,6 +18,7 @@ export { default as isSingleLineString } from "./isSingleLineString"
export { default as isStandardDeclaration } from "./isStandardDeclaration"
export { default as isStandardFunction } from "./isStandardFunction"
export { default as isStandardRule } from "./isStandardRule"
export { default as isStandardSelector } from "./isStandardSelector"
export { default as isStandardTypeSelector } from "./isStandardTypeSelector"
export { default as isStandardValue } from "./isStandardValue"
export { default as isValidHex } from "./isValidHex"
Expand Down
3 changes: 0 additions & 3 deletions src/utils/isStandardRule.js
Expand Up @@ -14,9 +14,6 @@ export default function (rule) {
// Custom property set (e.g. --custom-property-set: {})
if (_.endsWith(selector, ":")) { return false }

// SCSS or Less interpolation
if (/#{.+?}|@{.+?}|\$\(.+?\)/.test(selector)) { return false }

// Called Less mixin (e.g. a { .mixin() })
if (rule.ruleWithoutBody) { return false }

Expand Down
13 changes: 13 additions & 0 deletions src/utils/isStandardSelector.js
@@ -0,0 +1,13 @@
/**
* Check whether a selector is standard
*
* @param {string} selector
* @return {boolean} If `true`, the selector is standard
*/
export default function (selector) {

// SCSS or Less interpolation
if (/#{.+?}|@{.+?}|\$\(.+?\)/.test(selector)) { return false }

return true
}

0 comments on commit aaa9a0f

Please sign in to comment.