Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,13 @@ module: {
postcssOptions: {
plugins: {
"postcss-prefix-selector": {
prefix: '.my-prefix'
prefix: '.my-prefix',
transform(prefix, selector, prefixedSelector) {
if (selector.match(/^(html|body)/)) {
return selector.replace(/^([^\s]*)/, `$1 ${prefix}`);
}
return prefixedSelector;
},
},
autoprefixer: {
browsers: ['last 4 versions']
Expand All @@ -118,6 +124,7 @@ module: {
- `exclude` - It's possible to avoid prefixing some selectors by passing an array of selectors (strings or regular expressions).
- `transform` - In cases where you may want to use the prefix differently for different selectors, it is possible to pass in a custom transform method.
- `ignoreFiles` - List of ignored files for processing.
- `includeFiles` - List of included files for processing.

## Maintainer

Expand Down
9 changes: 9 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ module.exports = function postcssPrefixSelector(options) {
const prefix = options.prefix;
const prefixWithSpace = /\s+$/.test(prefix) ? prefix : `${prefix} `;
const ignoreFiles = options.ignoreFiles ? [].concat(options.ignoreFiles) : [];
const includeFiles = options.includeFiles
? [].concat(options.includeFiles)
: [];

return function (root) {
if (
Expand All @@ -10,6 +13,12 @@ module.exports = function postcssPrefixSelector(options) {
) {
return;
}
if (
root.source.input.file &&
includeFiles.some((file) => !root.source.input.file.includes(file))
) {
return;
}

root.walkRules((rule) => {
const keyframeRules = [
Expand Down
7 changes: 7 additions & 0 deletions test/fixtures/between-symbol-plus-selector.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.a {
color: coral;
}

.b {
color: deepskyblue;
}
7 changes: 7 additions & 0 deletions test/fixtures/between-symbol-plus-selector.expected.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.hello+ .a {
color: coral;
}

.hello+ .b {
color: deepskyblue;
}
7 changes: 7 additions & 0 deletions test/fixtures/between-symbol-selector.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.a {
color: coral;
}

.b {
color: deepskyblue;
}
7 changes: 7 additions & 0 deletions test/fixtures/between-symbol-selector.expected.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.hello.a {
color: coral;
}

.hello.b {
color: deepskyblue;
}
7 changes: 7 additions & 0 deletions test/fixtures/include-files.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.a {
color: coral;
}

.b {
color: deepskyblue;
}
7 changes: 7 additions & 0 deletions test/fixtures/include-files.expected.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.hello .a {
color: coral;
}

.hello .b {
color: deepskyblue;
}
7 changes: 7 additions & 0 deletions test/fixtures/single-long-selector.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.a {
color: coral;
}

.b {
color: deepskyblue;
}
7 changes: 7 additions & 0 deletions test/fixtures/single-long-selector.expected.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.hello .world .a {
color: coral;
}

.hello .world .b {
color: deepskyblue;
}
81 changes: 81 additions & 0 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,87 @@ it('should prefix selectors in unignored files', () => {
assert.equal(out, expected);
});

it('should prefix selectors in included file', () => {
const out = postcss()
.use(
prefixer({
prefix: '.hello ',
includeFiles: ['include-files.css'],
})
)
.process(getFixtureContents('include-files.css'), {
from: 'include-files.css',
}).css;

const expected = getFixtureContents('include-files.expected.css');

assert.equal(out, expected);
});

it('should not prefix selectors in unincluded files', () => {
const out = postcss()
.use(
prefixer({
prefix: '.hello ',
includeFiles: ['include-files.css'],
})
)
.process(getFixtureContents('single-selector.css'), {
from: 'single-selector.css',
}).css;

const expected = getFixtureContents('single-selector.css');

assert.equal(out, expected);
});

it('should use custom symbol between prefix and selector. Use empty to glue', () => {
const out = postcss()
.use(
prefixer({
prefix: '.hello',
transform(prefix, selector) {
return prefix + selector;
},
})
)
.process(getFixtureContents('between-symbol-selector.css')).css;

const expected = getFixtureContents('between-symbol-selector.expected.css');

assert.equal(out, expected);
});

it('should use custom symbol between prefix and selector. Use "+"', () => {
const out = postcss()
.use(
prefixer({
prefix: '.hello+',
})
)
.process(getFixtureContents('between-symbol-plus-selector.css')).css;

const expected = getFixtureContents(
'between-symbol-plus-selector.expected.css'
);

assert.equal(out, expected);
});

it('should prefix a selector. Use ".hello .world"', () => {
const out = postcss()
.use(
prefixer({
prefix: '.hello .world',
})
)
.process(getFixtureContents('single-long-selector.css')).css;

const expected = getFixtureContents('single-long-selector.expected.css');

assert.equal(out, expected);
});

function getFixtureContents(name) {
return fs.readFileSync(`test/fixtures/${name}`, 'utf8').trim();
}