Skip to content

Commit

Permalink
feat: add the @global {} rule support
Browse files Browse the repository at this point in the history
  • Loading branch information
illright authored and kaisermann committed Jun 5, 2020
1 parent e9d7c61 commit 46722ba
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 1 deletion.
11 changes: 11 additions & 0 deletions src/autoProcess.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ interface Transformers {
coffeescript?: TransformerOptions<Options.Coffeescript>;
pug?: TransformerOptions<Options.Pug>;
globalStyle?: TransformerOptions<Options.Typescript>;
globalRule?: TransformerOptions<Options.Typescript>;
replace?: Options.Replace;
[languageName: string]: TransformerOptions<any>;
}
Expand Down Expand Up @@ -55,6 +56,7 @@ type AutoPreprocessOptions = {
coffeescript?: TransformerOptions<Options.Coffeescript>;
pug?: TransformerOptions<Options.Pug>;
globalStyle?: TransformerOptions<Options.Typescript>;
globalRule?: TransformerOptions<Options.Typescript>;
// workaround while we don't have this
// https://github.com/microsoft/TypeScript/issues/17867
[languageName: string]:
Expand Down Expand Up @@ -270,6 +272,15 @@ export function autoPreprocess(
map = transformed.map;
}

const transformed = await runTransformer('globalRule', null, {
content: code,
map,
filename,
});

code = transformed.code;
map = transformed.map;

return { code, map, dependencies };
},
};
Expand Down
13 changes: 13 additions & 0 deletions src/processors/globalRule.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { PreprocessorGroup } from '../types';

export default (): PreprocessorGroup => {
return {
async style({ content, filename }) {
const { default: transformer } = await import(
'../transformers/globalRule'
);

return transformer({ content, filename });
},
};
};
28 changes: 28 additions & 0 deletions src/transformers/globalRule.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import postcss from 'postcss';

import { Transformer } from '../types';
import { globalifyPlugin } from './globalStyle';

const globalifyRulePlugin = (root: any) => {
root.walkAtRules(/^global$/, (atrule: any) => {
globalifyPlugin(atrule);
let after = atrule;

atrule.each(function (child: any) {
after.after(child);
after = child;
});

atrule.remove();
});
};

const transformer: Transformer<never> = async ({ content, filename }) => {
const { css, map: newMap } = await postcss()
.use(globalifyRulePlugin)
.process(content, { from: filename, map: true });

return { code: css, map: newMap };
};

export default transformer;
2 changes: 1 addition & 1 deletion src/transformers/globalStyle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import postcss from 'postcss';

import { Transformer } from '../types';

const globalifyPlugin = (root: any) => {
export const globalifyPlugin = (root: any) => {
root.walkAtRules(/keyframes$/, (atrule: any) => {
if (!atrule.params.startsWith('-global-')) {
atrule.params = '-global-' + atrule.params;
Expand Down
42 changes: 42 additions & 0 deletions test/transformers/globalRule.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import autoProcess from '../../src';
import { preprocess } from '../utils';

describe('transformer - globalRule', () => {
it('wraps selector in :global(...) modifier', async () => {
const template = `<style>@global{div{color:red}.test{}}</style>`;
const opts = autoProcess();
const preprocessed = await preprocess(template, opts);
expect(preprocessed.toString()).toContain(
`:global(div){color:red}:global(.test){}`,
);
});

it('wraps selector in :global(...) modifier only inside the rule', async () => {
const template = `<style>@global{div{color:red}}.test{}</style>`;
const opts = autoProcess();
const preprocessed = await preprocess(template, opts);
expect(preprocessed.toString()).toContain(
`:global(div){color:red}.test{}`,
);
});

it('wraps selector in :global(...) only if needed', async () => {
const template = `<style>@global{.test{}:global(.foo){}}</style>`;
const opts = autoProcess();
const preprocessed = await preprocess(template, opts);
expect(preprocessed.toString()).toContain(
`:global(.test){}:global(.foo){}`,
);
});

it("prefixes @keyframes names with '-global-' only if needed", async () => {
const template = `<style>
@global{@keyframes a {from{} to{}}@keyframes -global-b {from{} to{}}}
</style>`;
const opts = autoProcess();
const preprocessed = await preprocess(template, opts);
expect(preprocessed.toString()).toContain(
`@keyframes -global-a {from{} to{}}@keyframes -global-b {from{} to{}}`,
);
});
});

0 comments on commit 46722ba

Please sign in to comment.