Skip to content

Commit

Permalink
Fix regression in pseudo-element handling
Browse files Browse the repository at this point in the history
  • Loading branch information
m-akinc committed May 2, 2024
1 parent 64a04cb commit 563a384
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 9 deletions.
2 changes: 2 additions & 0 deletions src/preview/rewriteStyleSheet.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ describe("rewriteStyleSheet", () => {
const sheet = new Sheet("::-webkit-scrollbar-thumb: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")
})

it("adds alternative selector when ::-webkit-scrollbar-thumb follows :hover", () => {
Expand All @@ -153,6 +154,7 @@ describe("rewriteStyleSheet", () => {
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", () => {
Expand Down
26 changes: 17 additions & 9 deletions src/preview/rewriteStyleSheet.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import { PSEUDO_STATES, EXCLUDED_PSEUDO_ELEMENT_PATTERNS } from "../constants"
import { splitSelectors } from "./splitSelectors"

const pseudoStateRegExp = (global: boolean, pseudoStates: string[]) =>
new RegExp(`(?<!(?:${EXCLUDED_PSEUDO_ELEMENT_PATTERNS.join("|")})\\S*):(${pseudoStates.join("|")})`, global ? "g" : undefined)
const pseudoStates = Object.values(PSEUDO_STATES)
const matchOne = pseudoStateRegExp(false, pseudoStates)
const matchAll = pseudoStateRegExp(true, pseudoStates)
const replacementRegExp = (pseudoState: string) => pseudoStateRegExp(true, [pseudoState])

const pseudoStatesPattern = `:(${pseudoStates.join("|")})`
const matchOne = new RegExp(pseudoStatesPattern)
const matchAll = new RegExp(pseudoStatesPattern, "g")
const warnings = new Set()
const warnOnce = (message: string) => {
if (warnings.has(message)) return
Expand All @@ -17,7 +15,11 @@ const warnOnce = (message: string) => {
}

const replacePseudoStates = (selector: string, allClass?: boolean) => {
return pseudoStates.reduce((acc, state) => acc.replace(replacementRegExp(state), `.pseudo-${state}${allClass ? "-all" : ""}`), selector)
const negativeLookbehind = `(?<!(?:${EXCLUDED_PSEUDO_ELEMENT_PATTERNS.join("|")})\\S*)`
return pseudoStates.reduce((acc, state) => acc.replace(
new RegExp(`${negativeLookbehind}:${state}`, "g"),
`.pseudo-${state}${allClass ? "-all" : ""}`
), selector)
}

// Does not handle :host() or :not() containing pseudo-states. Need to call replaceNotSelectors on the input first.
Expand Down Expand Up @@ -77,11 +79,16 @@ const rewriteRule = ({ cssText, selectorText }: CSSStyleRule, forShadowDOM: bool
if (selector.includes(".pseudo-")) {
return []
}
const replacementSelectors = [selector]
if (!matchOne.test(selector)) {
return [selector]
return replacementSelectors
}

const classSelector = replacePseudoStates(selector)
if (classSelector !== selector) {
replacementSelectors.push(classSelector)
}

let ancestorSelector = ""

if (selector.startsWith(":host(")) {
Expand All @@ -108,8 +115,9 @@ const rewriteRule = ({ cssText, selectorText }: CSSStyleRule, forShadowDOM: bool
const withNotsReplaced = rewriteNotSelectors(selector, forShadowDOM)
ancestorSelector = replacePseudoStatesWithAncestorSelector(withNotsReplaced, forShadowDOM)
}
replacementSelectors.push(ancestorSelector)

return [selector, classSelector, ancestorSelector]
return replacementSelectors
})
.join(", ")
)
Expand Down

0 comments on commit 563a384

Please sign in to comment.