Skip to content

Commit

Permalink
Bugfix/separate selectors (#1253)
Browse files Browse the repository at this point in the history
* Fix #1196

* Add tests for grouping rules

* Use instance data instead of global const

* Make solution more proper and easier to reason about
  • Loading branch information
fanich37 authored and ai committed Oct 14, 2019
1 parent 3795794 commit f626441
Show file tree
Hide file tree
Showing 5 changed files with 147 additions and 13 deletions.
31 changes: 24 additions & 7 deletions lib/selector.js
@@ -1,3 +1,5 @@
let { list } = require('postcss')

let OldSelector = require('./old-selector')
let Prefixer = require('./prefixer')
let Browsers = require('./browsers')
Expand Down Expand Up @@ -53,15 +55,30 @@ class Selector extends Prefixer {
*/
prefixeds (rule) {
if (rule._autoprefixerPrefixeds) {
return rule._autoprefixerPrefixeds
if (rule._autoprefixerPrefixeds[this.name]) {
return rule._autoprefixerPrefixeds
}
} else {
rule._autoprefixerPrefixeds = {}
}

let prefixeds = {}
for (let prefix of this.possible()) {
prefixeds[prefix] = this.replace(rule.selector, prefix)
if (rule.selector.includes(',')) {
let ruleParts = list.comma(rule.selector)
let toProcess = ruleParts.filter(el => el.includes(this.name))

for (let prefix of this.possible()) {
prefixeds[prefix] = toProcess
.map(el => this.replace(el, prefix))
.join(', ')
}
} else {
for (let prefix of this.possible()) {
prefixeds[prefix] = this.replace(rule.selector, prefix)
}
}

rule._autoprefixerPrefixeds = prefixeds
rule._autoprefixerPrefixeds[this.name] = prefixeds
return rule._autoprefixerPrefixeds
}

Expand All @@ -79,8 +96,8 @@ class Selector extends Prefixer {
}

let some = false
for (let key in prefixeds) {
let prefixed = prefixeds[key]
for (let key in prefixeds[this.name]) {
let prefixed = prefixeds[this.name][key]
if (before.selector === prefixed) {
if (prefix === key) {
return true
Expand Down Expand Up @@ -117,7 +134,7 @@ class Selector extends Prefixer {
return
}

let cloned = this.clone(rule, { selector: prefixeds[prefix] })
let cloned = this.clone(rule, { selector: prefixeds[this.name][prefix] })
rule.parent.insertBefore(rule, cloned)
}

Expand Down
7 changes: 7 additions & 0 deletions test/autoprefixer.test.js
Expand Up @@ -44,6 +44,10 @@ let uncascader = autoprefixer({
let gradienter = autoprefixer({
overrideBrowserslist: ['Chrome 25', 'Opera 12', 'Android 2.3']
})
let grouping = autoprefixer({
overrideBrowserslist: ['Chrome 25', 'Firefox > 17', 'IE 10', 'Edge 12'],
grid: 'autoplace'
})
let ffgradienter = autoprefixer({
overrideBrowserslist: ['Chrome 25', 'Opera 12', 'Firefox 6']
})
Expand Down Expand Up @@ -90,6 +94,8 @@ function prefixer (name) {
return gradienter
} else if (name === 'gradient-fix') {
return ffgradienter
} else if (name === 'grouping-rule') {
return grouping
} else if (name === 'flexbox' || name === 'flex-rewrite') {
return flexboxer
} else if (name === 'double') {
Expand Down Expand Up @@ -244,6 +250,7 @@ it('saves declaration style', () => check('style'))
it('uses ignore next control comments', () => check('ignore-next'))
it('uses block control comments', () => check('disabled'))
it('has actual example in docs', () => check('example'))
it('process grouping rules correctly', () => check('grouping-rule'))

it('uses control comments to whole scope', () => {
let input = read('scope')
Expand Down
23 changes: 23 additions & 0 deletions test/cases/grouping-rule.css
@@ -0,0 +1,23 @@
.grid {
display: grid;
}

.a,
.b,
.c::selection,
.d:read-only,
.e::placeholder {
color: yellow;
}

::selection {
color: red;
}

:read-only {
color: black;
}

.f:read-write, .g:read-write {
background: #fff;
}
64 changes: 64 additions & 0 deletions test/cases/grouping-rule.out.css
@@ -0,0 +1,64 @@
.grid {
display: -ms-grid;
display: grid;
}

.c::-moz-selection {
color: yellow;
}

.e::-webkit-input-placeholder {
color: yellow;
}

.e:-moz-placeholder {
color: yellow;
}

.e::-moz-placeholder {
color: yellow;
}

.e:-ms-input-placeholder {
color: yellow;
}

.e::-ms-input-placeholder {
color: yellow;
}

.d:-moz-read-only {
color: yellow;
}

.a,
.b,
.c::selection,
.d:read-only,
.e::placeholder {
color: yellow;
}

::-moz-selection {
color: red;
}

::selection {
color: red;
}

:-moz-read-only {
color: black;
}

:read-only {
color: black;
}

.f:-moz-read-write, .g:-moz-read-write {
background: #fff;
}

.f:read-write, .g:read-write {
background: #fff;
}
35 changes: 29 additions & 6 deletions test/selector.test.js
Expand Up @@ -28,7 +28,7 @@ describe('regexp()', () => {
})

describe('check()', () => {
it('shecks rule selectors', () => {
it('checks rule selectors', () => {
let css = parse('body .selection {}, ' +
':::selection {}, body ::selection {}')
expect(selector.check(css.nodes[0])).toBeFalsy()
Expand All @@ -38,13 +38,36 @@ describe('check()', () => {
})

describe('prefixeds()', () => {
it('returns all avaiable prefixed selectors', () => {
it('grouping rule gets correct _autoprefixerPrefixeds property', () => {
let css = parse('.c::selection, .d:read-only {}')
let rSel = new Selector(':read-only', ['-moz-'])
selector.prefixeds(css.first)
rSel.prefixeds(css.first)
expect(css.first._autoprefixerPrefixeds).toEqual({
'::selection': {
'-webkit-': '.c::-webkit-selection',
'-moz-': '.c::-moz-selection',
'-ms-': '.c::-ms-selection',
'-o-': '.c::-o-selection'
},
':read-only': {
'-webkit-': '.d:-webkit-read-only',
'-moz-': '.d:-moz-read-only',
'-ms-': '.d:-ms-read-only',
'-o-': '.d:-o-read-only'
}
})
})

it('returns all available prefixed selectors', () => {
let css = parse('::selection {}')
expect(selector.prefixeds(css.first)).toEqual({
'-webkit-': '::-webkit-selection',
'-moz-': '::-moz-selection',
'-ms-': '::-ms-selection',
'-o-': '::-o-selection'
'::selection': {
'-webkit-': '::-webkit-selection',
'-moz-': '::-moz-selection',
'-ms-': '::-ms-selection',
'-o-': '::-o-selection'
}
})
})
})
Expand Down

0 comments on commit f626441

Please sign in to comment.