From 42556b2a8dd57c0bb804ecf68a1cee1425fae929 Mon Sep 17 00:00:00 2001 From: Mert Akinc <7282195+m-akinc@users.noreply.github.com> Date: Tue, 7 May 2024 18:20:45 -0500 Subject: [PATCH] Avoid invalid CSS generation for styles using vendor pseudo-elements --- src/constants.ts | 2 +- src/preview/rewriteStyleSheet.test.ts | 28 ++++++++++++++++++++------- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/src/constants.ts b/src/constants.ts index fd441d7..fa2d241 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -4,7 +4,7 @@ export const PARAM_KEY = "pseudo" // Regex patterns for pseudo-elements which are not allowed to have classes applied on them // E.g. ::-webkit-scrollbar-thumb.pseudo-hover is not a valid selector -export const EXCLUDED_PSEUDO_ELEMENT_PATTERNS = ["::-webkit-scrollbar-thumb", "::-webkit-slider-thumb", "::part\\([^)]+\\)"] +export const EXCLUDED_PSEUDO_ELEMENT_PATTERNS = ["::-(webkit|moz|ms)-[a-z-]+", "::part\\([^)]+\\)"] // Dynamic pseudo-classes // @see https://www.w3.org/TR/2018/REC-selectors-3-20181106/#dynamic-pseudos diff --git a/src/preview/rewriteStyleSheet.test.ts b/src/preview/rewriteStyleSheet.test.ts index cb234ec..150aec9 100644 --- a/src/preview/rewriteStyleSheet.test.ts +++ b/src/preview/rewriteStyleSheet.test.ts @@ -137,27 +137,41 @@ describe("rewriteStyleSheet", () => { ].includes(x))).toEqual([]) }) - it("does not add .pseudo- to pseudo-class/element which does not support classes", () => { - const sheet = new Sheet("::-webkit-scrollbar-thumb:hover { border-color: transparent; }") + it("does not add invalid selector where .pseudo- would be appended to ::-webkit-* pseudo-element", () => { + const sheet = new Sheet("::-webkit-foo-bar:hover { border-color: transparent; }") rewriteStyleSheet(sheet as any) - expect(sheet.cssRules[0].getSelectors()).not.toContain("::-webkit-scrollbar-thumb.pseudo-hover") - expect(sheet.cssRules[0].getSelectors()).toContain(".pseudo-hover-all ::-webkit-scrollbar-thumb") + expect(sheet.cssRules[0].getSelectors()).not.toContain("::-webkit-foo-bar.pseudo-hover") + expect(sheet.cssRules[0].getSelectors()).toContain(".pseudo-hover-all ::-webkit-foo-bar") }) - it("adds alternative selector when ::-webkit-scrollbar-thumb follows :hover", () => { + it("does not add invalid selector where .pseudo- would be appended to ::-moz-* pseudo-element", () => { + const sheet = new Sheet("::-moz-foo-bar-baz:hover { border-color: transparent; }") + rewriteStyleSheet(sheet as any) + expect(sheet.cssRules[0].getSelectors()).not.toContain("::-moz-foo-bar-baz.pseudo-hover") + expect(sheet.cssRules[0].getSelectors()).toContain(".pseudo-hover-all ::-moz-foo-bar-baz") + }) + + it("does not add invalid selector where .pseudo- would be appended to ::-ms-* pseudo-element", () => { + const sheet = new Sheet("::-ms-foo:hover { border-color: transparent; }") + rewriteStyleSheet(sheet as any) + expect(sheet.cssRules[0].getSelectors()).not.toContain("::-ms-foo.pseudo-hover") + expect(sheet.cssRules[0].getSelectors()).toContain(".pseudo-hover-all ::-ms-foo") + }) + + it("adds alternative selector when .pseudo- would not be appended to pseudo-element", () => { const sheet = new Sheet("div:hover::-webkit-scrollbar-thumb { border-color: transparent; }") rewriteStyleSheet(sheet as any) expect(sheet.cssRules[0].getSelectors()).toContain("div.pseudo-hover::-webkit-scrollbar-thumb") }) - it("does not add .pseudo- to pseudo-class/element (with arguments) which does not support classes", () => { + it("does not add invalid selector where .pseudo- would be appended to ::part()", () => { const sheet = new Sheet("::part(foo bar):hover { border-color: transparent; }") rewriteStyleSheet(sheet as any) expect(sheet.cssRules[0].getSelectors()).not.toContain("::part(foo bar).pseudo-hover") expect(sheet.cssRules[0].getSelectors()).toContain(".pseudo-hover-all ::part(foo bar)") }) - it("adds alternative selector when ::part() follows :hover", () => { + it("adds alternative selector when .pseudo- would not be appended to ::part()", () => { const sheet = new Sheet("custom-elt:hover::part(foo bar) { border-color: transparent; }") rewriteStyleSheet(sheet as any) expect(sheet.cssRules[0].getSelectors()).toContain("custom-elt.pseudo-hover::part(foo bar)")