From 84ea2d4b9290275ad8667c6a5f2cea8a92660084 Mon Sep 17 00:00:00 2001 From: krister Date: Fri, 1 Feb 2019 15:39:22 -0300 Subject: [PATCH 1/3] Handle interpolation in selector-nest-combinators --- .../__tests__/index.js | 40 ++++++++++++++++- src/rules/selector-nest-combinators/index.js | 45 +++++++++++++------ 2 files changed, 70 insertions(+), 15 deletions(-) diff --git a/src/rules/selector-nest-combinators/__tests__/index.js b/src/rules/selector-nest-combinators/__tests__/index.js index 46d25180..b92bd03b 100644 --- a/src/rules/selector-nest-combinators/__tests__/index.js +++ b/src/rules/selector-nest-combinators/__tests__/index.js @@ -1,4 +1,4 @@ -import rule, { ruleName, messages } from ".."; +import rule, { messages, ruleName } from ".."; testRule(rule, { ruleName, @@ -86,6 +86,16 @@ testRule(rule, { :not([class]:last-child) {} `, description: "when selectors are chained within a not selector" + }, + { + code: ` + .class-name { + #{if(&, "&", "")} { + + } + } + `, + description: "should support interpolation" } ], @@ -144,6 +154,15 @@ testRule(rule, { messages: messages.expected(":last-child", "pseudo"), line: 2, column: 25 + }, + { + code: ` + .class-name #{if(&, "&", "")} {} + `, + description: "when interpolation is used", + messages: messages.expectedInterpolation, + line: 2, + column: 18 } ] }); @@ -215,6 +234,12 @@ testRule(rule, { #foo:not([class]:last-child) {} `, description: "when using a not selector" + }, + { + code: ` + .class-name #{if(&, "&", "")} {} + `, + description: "should support interpolation" } ], @@ -288,6 +313,19 @@ testRule(rule, { messages: messages.rejected, line: 3, column: 9 + }, + { + code: ` + .class-name { + #{if(&, "&", "")} { + + } + } + `, + description: "when interpolation is used", + messages: messages.rejected, + line: 3, + column: 8 } ] }); diff --git a/src/rules/selector-nest-combinators/index.js b/src/rules/selector-nest-combinators/index.js index 65470817..4ff490a5 100644 --- a/src/rules/selector-nest-combinators/index.js +++ b/src/rules/selector-nest-combinators/index.js @@ -4,9 +4,10 @@ import { namespace, parseSelector } from "../../utils"; export const ruleName = namespace("selector-nest-combinators"); export const messages = utils.ruleMessages(ruleName, { + expectedInterpolation: `Expected interpolation to be in a nested form`, expected: (combinator, type) => `Expected combinator "${combinator}" of type "${type}" to be in a nested form`, - rejected: () => `Unexpected nesting found in selector` + rejected: `Unexpected nesting found in selector` }); export default function(expectation) { @@ -20,6 +21,18 @@ export default function(expectation) { return; } + function precedesParentSelector(current) { + do { + current = current.next(); + + if (current.type === "nesting") { + return true; + } + } while (current.next()); + + return false; + } + root.walkRules(rule => { parseSelector(rule.selector, result, rule, fullSelector => { // attribute, class, combinator, comment, id, nesting, pseudo, root, selector, string, tag, or universal @@ -32,9 +45,15 @@ export default function(expectation) { "universal" ]; + const interpolationRe = /#{.+}$/; + let message; fullSelector.walk(node => { + if (node.value === "}") { + return; + } + if (expectation === "always") { if (node.type === "selector") { return; @@ -81,7 +100,17 @@ export default function(expectation) { return; } - message = messages.expected(node.value, node.type); + const hasInterpolation = interpolationRe.test(rule.selector); + + if (node.type !== "combinator" && hasInterpolation) { + return; + } + + if (hasInterpolation) { + message = messages.expectedInterpolation; + } else { + message = messages.expected(node.value, node.type); + } } if (expectation === "never") { @@ -99,18 +128,6 @@ export default function(expectation) { message, index: node.sourceIndex }); - - function precedesParentSelector(current) { - do { - current = current.next(); - - if (current.type === "nesting") { - return true; - } - } while (current.next()); - - return false; - } }); }); }); From 20387a8eb475a9d40e2fad5cc1faaad99e381195 Mon Sep 17 00:00:00 2001 From: krister Date: Fri, 1 Feb 2019 15:43:09 -0300 Subject: [PATCH 2/3] move variables outside the loops --- src/rules/selector-nest-combinators/index.js | 24 ++++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/rules/selector-nest-combinators/index.js b/src/rules/selector-nest-combinators/index.js index 4ff490a5..79363985 100644 --- a/src/rules/selector-nest-combinators/index.js +++ b/src/rules/selector-nest-combinators/index.js @@ -33,20 +33,20 @@ export default function(expectation) { return false; } + // attribute, class, combinator, comment, id, nesting, pseudo, root, selector, string, tag, or universal + const chainingTypes = [ + "attribute", + "class", + "id", + "pseudo", + "tag", + "universal" + ]; + + const interpolationRe = /#{.+}$/; + root.walkRules(rule => { parseSelector(rule.selector, result, rule, fullSelector => { - // attribute, class, combinator, comment, id, nesting, pseudo, root, selector, string, tag, or universal - const chainingTypes = [ - "attribute", - "class", - "id", - "pseudo", - "tag", - "universal" - ]; - - const interpolationRe = /#{.+}$/; - let message; fullSelector.walk(node => { From 9ff71441dfb883c1a15c866a5fdbc91cc37bba2b Mon Sep 17 00:00:00 2001 From: krister Date: Fri, 1 Feb 2019 22:13:29 -0300 Subject: [PATCH 3/3] make matching non-greedy --- src/rules/selector-nest-combinators/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rules/selector-nest-combinators/index.js b/src/rules/selector-nest-combinators/index.js index 79363985..c3ac73d1 100644 --- a/src/rules/selector-nest-combinators/index.js +++ b/src/rules/selector-nest-combinators/index.js @@ -43,7 +43,7 @@ export default function(expectation) { "universal" ]; - const interpolationRe = /#{.+}$/; + const interpolationRe = /#{.+?}$/; root.walkRules(rule => { parseSelector(rule.selector, result, rule, fullSelector => {