diff --git a/packages/processor/plugins/scoping.js b/packages/processor/plugins/scoping.js index 4a9510182..5b9f52f69 100644 --- a/packages/processor/plugins/scoping.js +++ b/packages/processor/plugins/scoping.js @@ -95,10 +95,15 @@ module.exports = (css, { opts, messages }) => { // Walk all rules and save off rewritten selectors css.walkRules((rule) => { + // Don't process the children of @keyframes, they don't need scoping + if(rule.parent.type === "atrule" && rule.parent.name === "keyframes") { + return; + } + // Save closure ref to this rule current = rule; lookup = classes; - + rule.selector = parser.processSync(rule); }); diff --git a/packages/processor/test/__snapshots__/keyframes.test.js.snap b/packages/processor/test/__snapshots__/keyframes.test.js.snap index 2b5d1aaec..7f44d42bb 100644 --- a/packages/processor/test/__snapshots__/keyframes.test.js.snap +++ b/packages/processor/test/__snapshots__/keyframes.test.js.snap @@ -1,31 +1,42 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`/processor.js scoping should leave unknown animation names alone 1`] = ` +exports[`/processor.js @keyframes scoping should leave unknown animation names alone 1`] = ` "/* unknown-name.css */ .a { animation: a; } .b { animation-name: b; }" `; -exports[`/processor.js scoping should update multiple animations properly 1`] = ` +exports[`/processor.js @keyframes scoping should not scope rules within @keyframes 1`] = ` +"/* unknown-name.css */ +.a { animation: a; } + +@keyframes a { + from { color: white; } + 50.25% { color: red; } + to { color: black; } +}" +`; + +exports[`/processor.js @keyframes scoping should update multiple animations properly 1`] = ` "/* multiple-animations.css */ @keyframes a {} @keyframes b {} .c { animation: a 10s linear, b 0.2s infinite; }" `; -exports[`/processor.js scoping should update scoped animations from the scoping plugin's message 1`] = ` +exports[`/processor.js @keyframes scoping should update scoped animations from the scoping plugin's message 1`] = ` "/* animation.css */ @keyframes a {} .b { animation: a; }" `; -exports[`/processor.js scoping should update scoped prefixed animations from the scoping plugin's message 1`] = ` +exports[`/processor.js @keyframes scoping should update scoped prefixed animations from the scoping plugin's message 1`] = ` "/* prefixed-animations.css */ @-webkit-keyframes a {} .b { animation: a; }" `; -exports[`/processor.js scoping should update the animation-name property 1`] = ` +exports[`/processor.js @keyframes scoping should update the animation-name property 1`] = ` "/* animation-name.css */ @keyframes a {} .b { animation-name: a; }" diff --git a/packages/processor/test/keyframes.test.js b/packages/processor/test/keyframes.test.js index 7407cb1b6..1ee493509 100644 --- a/packages/processor/test/keyframes.test.js +++ b/packages/processor/test/keyframes.test.js @@ -5,7 +5,7 @@ const namer = require("@modular-css/test-utils/namer.js"); const Processor = require("../processor.js"); describe("/processor.js", () => { - describe("scoping", () => { + describe("@keyframes scoping", () => { let processor; beforeEach(() => { @@ -15,13 +15,26 @@ describe("/processor.js", () => { }); it("should leave unknown animation names alone", async () => { - await processor.string( - "./unknown-name.css", - dedent(` - .a { animation: a; } - .b { animation-name: b; } - `) - ); + await processor.string("./unknown-name.css", dedent(` + .a { animation: a; } + .b { animation-name: b; } + `)); + + const { css } = await processor.output(); + + expect(css).toMatchSnapshot(); + }); + + it("should not scope rules within @keyframes", async () => { + await processor.string("./unknown-name.css", dedent(` + .a { animation: a; } + + @keyframes a { + from { color: white; } + 50.25% { color: red; } + to { color: black; } + } + `)); const { css } = await processor.output(); @@ -29,13 +42,10 @@ describe("/processor.js", () => { }); it("should update scoped animations from the scoping plugin's message", async () => { - await processor.string( - "./animation.css", - dedent(` - @keyframes a {} - .b { animation: a; } - `) - ); + await processor.string("./animation.css", dedent(` + @keyframes a {} + .b { animation: a; } + `)); const { css } = await processor.output(); @@ -43,13 +53,10 @@ describe("/processor.js", () => { }); it("should update the animation-name property", async () => { - await processor.string( - "./animation-name.css", - dedent(` - @keyframes a {} - .b { animation-name: a; } - `) - ); + await processor.string("./animation-name.css", dedent(` + @keyframes a {} + .b { animation-name: a; } + `)); const { css } = await processor.output(); @@ -58,14 +65,11 @@ describe("/processor.js", () => { // Issue 208 it("should update multiple animations properly", async () => { - await processor.string( - "./multiple-animations.css", - dedent(` - @keyframes a {} - @keyframes b {} - .c { animation: a 10s linear, b 0.2s infinite; } - `) - ); + await processor.string("./multiple-animations.css", dedent(` + @keyframes a {} + @keyframes b {} + .c { animation: a 10s linear, b 0.2s infinite; } + `)); const { css } = await processor.output(); @@ -73,13 +77,10 @@ describe("/processor.js", () => { }); it("should update scoped prefixed animations from the scoping plugin's message", async () => { - await processor.string( - "./prefixed-animations.css", - dedent(` - @-webkit-keyframes a {} - .b { animation: a; } - `) - ); + await processor.string("./prefixed-animations.css", dedent(` + @-webkit-keyframes a {} + .b { animation: a; } + `)); const { css } = await processor.output();