Skip to content

Commit

Permalink
Check for rewritten pseudo states at rule-level rather than sheet-level
Browse files Browse the repository at this point in the history
  • Loading branch information
ghengeveld committed Sep 1, 2023
1 parent 4b7f441 commit d86bb22
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 29 deletions.
51 changes: 29 additions & 22 deletions src/preview/rewriteStyleSheet.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import { rewriteStyleSheet } from "./rewriteStyleSheet"

class Rule {
__pseudoStatesRewritten: boolean
cssText: string
selectorText?: string

constructor(cssText: string) {
this.__pseudoStatesRewritten = false
if (cssText.trim().startsWith("@")) {
this.cssText = cssText
return
Expand All @@ -16,19 +19,21 @@ class Rule {
}
}

class Sheet {
type CSSRule = CSSStyleRule & {
__pseudoStatesRewritten: boolean
cssRules: CSSStyleRule[]
}

class Sheet {
cssRules: CSSRule[]

constructor(...rules: string[]) {
this.__pseudoStatesRewritten = false
this.cssRules = rules.map((cssText) => new Rule(cssText) as CSSStyleRule)
this.cssRules = rules.map((cssText) => new Rule(cssText) as CSSRule)
}
deleteRule(index: number) {
this.cssRules.splice(index, 1)
}
insertRule(cssText: string, index: number) {
this.cssRules.splice(index, 0, new Rule(cssText) as CSSStyleRule)
this.cssRules.splice(index, 0, new Rule(cssText) as CSSRule)
}
}

Expand Down Expand Up @@ -85,7 +90,9 @@ describe("rewriteStyleSheet", () => {
it('supports ":host"', () => {
const sheet = new Sheet(":host(:hover) { color: red }")
rewriteStyleSheet(sheet as any)
expect(sheet.cssRules[0].cssText).toEqual(":host(:hover), :host(.pseudo-hover), :host(.pseudo-hover-all) { color: red }")
expect(sheet.cssRules[0].cssText).toEqual(
":host(:hover), :host(.pseudo-hover), :host(.pseudo-hover-all) { color: red }"
)
})

it('supports ":not"', () => {
Expand All @@ -96,21 +103,22 @@ describe("rewriteStyleSheet", () => {

it("override correct rules with media query present", () => {
const sheet = new Sheet(
`@media (max-width: 790px) {
.test {
background-color: green;
}
}`,
`.test {
background-color: blue;
}`,
`.test:hover {
background-color: red;
}`,
`.test2:hover {
background-color: white;
}`)
rewriteStyleSheet(sheet)
`@media (max-width: 790px) {
.test {
background-color: green;
}
}`,
`.test {
background-color: blue;
}`,
`.test:hover {
background-color: red;
}`,
`.test2:hover {
background-color: white;
}`
)
rewriteStyleSheet(sheet as any)
expect(sheet.cssRules[0].cssText).toContain("@media (max-width: 790px)")
expect(sheet.cssRules[1].selectorText).toContain(".test")
expect(sheet.cssRules[2].selectorText).toContain(".test:hover")
Expand All @@ -119,6 +127,5 @@ describe("rewriteStyleSheet", () => {
expect(sheet.cssRules[3].selectorText).toContain(".test2:hover")
expect(sheet.cssRules[3].selectorText).toContain(".test2.pseudo-hover")
expect(sheet.cssRules[3].selectorText).toContain(".pseudo-hover-all .test2")

})
})
15 changes: 8 additions & 7 deletions src/preview/rewriteStyleSheet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ const rewriteRule = ({ cssText, selectorText }: CSSStyleRule, shadowRoot?: Shado
return acc.replace(new RegExp(`:${state}`, "g"), `.pseudo-${state}-all`)
}, selector)


if (selector.startsWith(":host(") || selector.startsWith("::slotted(")) {
return [selector, classSelector, classAllSelector].filter(Boolean)
}
Expand All @@ -67,23 +66,25 @@ export const rewriteStyleSheet = (
shadowRoot?: ShadowRoot,
shadowHosts?: Set<Element>
) => {
// @ts-expect-error
if (sheet.__pseudoStatesRewritten) return
// @ts-expect-error
sheet.__pseudoStatesRewritten = true

try {
let index = -1
for (const cssRule of sheet.cssRules) {
index++
if (!("selectorText" in cssRule)) continue

// @ts-expect-error
if (cssRule.__pseudoStatesRewritten || !("selectorText" in cssRule)) continue

const styleRule = cssRule as CSSStyleRule
if (matchOne.test(styleRule.selectorText)) {
const newRule = rewriteRule(styleRule, shadowRoot)
sheet.deleteRule(index)
sheet.insertRule(newRule, index)
if (shadowRoot && shadowHosts) shadowHosts.add(shadowRoot.host)
}

// @ts-expect-error
cssRule.__pseudoStatesRewritten = true

if (index > 1000) {
warnOnce("Reached maximum of 1000 pseudo selectors per sheet, skipping the rest.")
break
Expand Down

0 comments on commit d86bb22

Please sign in to comment.