Skip to content

Commit 36a25f7

Browse files
committed
Added: plugin now expose replaceRuleSelector to make it easy to reuse in some others plugins (like postcss-custom-selectors) (1.2.0)
- Fixed: indentation adjustment doesn't contain useless new lines - Fixed: transformation doesn't add some useless whitespace
1 parent 3883f71 commit 36a25f7

4 files changed

Lines changed: 75 additions & 24 deletions

File tree

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
# 1.2.0 - 2015-07-14
2+
3+
- Fixed: indentation adjustment doesn't contain useless new lines
4+
- Fixed: transformation doesn't add some useless whitespace
5+
- Added: plugin now expose `replaceRuleSelector` to make it easy to reuse in
6+
some others plugins (like `postcss-custom-selectors`).
7+
18
# 1.1.2 - 2015-06-29
29

310
- Fixed: support pseudo-element that might be collapsed to :matches()

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "postcss-selector-matches",
3-
"version": "1.1.2",
3+
"version": "1.2.0",
44
"description": "PostCSS plugin to transform :matches() W3C CSS pseudo class to more compatible CSS selectors",
55
"keywords": [
66
"postcss",

src/index.js

Lines changed: 39 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,15 @@ import list from "postcss/lib/list"
33

44
import balancedMatch from "balanced-match"
55

6-
function explodeSelector(pseudoClass, selector, options) {
6+
const pseudoClass = ":matches"
7+
8+
function explodeSelector(selector, options) {
79
if (selector && selector.indexOf(pseudoClass) > -1) {
810
let newSelectors = []
11+
const preWhitespaceMatches = selector.match(/^\s+/)
12+
const preWhitespace = preWhitespaceMatches
13+
? preWhitespaceMatches[0]
14+
: ""
915
const selectorPart = list.comma(selector)
1016
selectorPart.forEach(part => {
1117
const position = part.indexOf(pseudoClass)
@@ -18,27 +24,23 @@ function explodeSelector(pseudoClass, selector, options) {
1824
.comma(matches.body)
1925
.reduce((acc, s) => [
2026
...acc,
21-
...explodeSelector(pseudoClass, s, options),
27+
...explodeSelector(s, options),
2228
], [])
2329
: [body]
2430

2531
const postSelectors = matches && matches.post
26-
? explodeSelector(pseudoClass, matches.post, options)
32+
? explodeSelector(matches.post, options)
2733
: []
2834

2935
let newParts
3036
if (postSelectors.length === 0) {
31-
newParts = bodySelectors.map((s) => pre + s)
37+
newParts = bodySelectors.map((s) => preWhitespace + pre + s)
3238
}
3339
else {
34-
const postWhitespaceMatches = matches.post.match(/^\s+/)
35-
const postWhitespace = postWhitespaceMatches
36-
? postWhitespaceMatches[0]
37-
: ""
3840
newParts = []
3941
postSelectors.forEach(postS => {
4042
bodySelectors.forEach(s => {
41-
newParts.push(pre + s + postWhitespace + postS)
43+
newParts.push(pre + s + postS)
4244
})
4345
})
4446
}
@@ -53,20 +55,36 @@ function explodeSelector(pseudoClass, selector, options) {
5355
return [selector]
5456
}
5557

56-
function explodeSelectors(pseudoClass) {
57-
return (options = {}) => {
58-
return (css) => {
59-
css.eachRule(rule => {
60-
if (rule.selector && rule.selector.indexOf(pseudoClass) > -1) {
61-
rule.selector = explodeSelector(pseudoClass, rule.selector, options)
62-
.join("," + (options.lineBreak ? "\n" + rule.before : " "))
63-
}
64-
})
65-
}
58+
function replaceRuleSelector(rule, options) {
59+
const indentation = rule.before
60+
? rule.before.split("\n").pop()
61+
: ""
62+
return (
63+
explodeSelector(rule.selector, options)
64+
.join("," + (options.lineBreak ? "\n" + indentation : " "))
65+
)
66+
67+
}
68+
69+
function explodeSelectors(options = {}) {
70+
return (css) => {
71+
css.eachRule(rule => {
72+
if (rule.selector && rule.selector.indexOf(pseudoClass) > -1) {
73+
rule.selector = replaceRuleSelector(rule, options)
74+
}
75+
})
6676
}
77+
6778
}
6879

69-
export default postcss.plugin(
80+
const plugin = postcss.plugin(
7081
"postcss-selector-matches",
71-
explodeSelectors(":matches")
82+
explodeSelectors
7283
)
84+
85+
// expose for postcss-custom-selectors
86+
export {replaceRuleSelector}
87+
// old school fallback
88+
plugin.replaceRuleSelector = replaceRuleSelector
89+
90+
export default plugin

test/index.js

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
11
import tape from "tape"
22

33
import postcss from "postcss"
4-
import selectorMatches from "../src/index.js"
4+
import plugin, {replaceRuleSelector} from "../src"
55

66
function transform(css, options = {}) {
7-
return postcss(selectorMatches(options)).process(css).css
7+
return postcss(plugin(options)).process(css).css
88
}
99

1010
tape("postcss-selector-matches", t => {
11+
t.ok(
12+
typeof replaceRuleSelector === "function" &&
13+
typeof plugin.replaceRuleSelector === "function",
14+
"expose 'replaceRuleSelector' function (for postcss-custom-selectors)"
15+
)
16+
1117
t.equal(
1218
transform("body {}"),
1319
"body {}",
@@ -89,6 +95,12 @@ tape("postcss-selector-matches", t => {
8995
"should add line break if asked too, and respect indentation"
9096
)
9197

98+
t.equal(
99+
transform("\n .foo:matches(:nth-child(-n+2), .bar) {}", {lineBreak: true}),
100+
"\n .foo:nth-child(-n+2),\n .foo.bar {}",
101+
"should add line break if asked too, and respect indentation even with \n"
102+
)
103+
92104
t.equal(
93105
transform(`
94106
button:matches(:hover, :active),
@@ -104,5 +116,19 @@ button:hover, button:active, .button:hover, .button:active {}`,
104116
"should work with something after :matches()"
105117
)
106118

119+
t.equal(
120+
transform(`article :matches(h1, h2, h3) + p {}`),
121+
`article h1 + p, article h2 + p, article h3 + p {}`,
122+
"should works correctly with adjacent selectors"
123+
)
124+
125+
t.equal(
126+
transform(`article :matches(h1, h2, h3) + p {}`, {lineBreak: true}),
127+
`article h1 + p,
128+
article h2 + p,
129+
article h3 + p {}`,
130+
"should works correctly with adjacent selectors and line break"
131+
)
132+
107133
t.end()
108134
})

0 commit comments

Comments
 (0)