File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -291,7 +291,8 @@ test("includes pseudo elements", () => {
291291 background: green;
292292 }
293293
294- div ::before {
294+ .test ::before {
295+ content: "";
295296 display: block;
296297 }
297298 ` ;
@@ -307,6 +308,10 @@ test("includes pseudo elements", () => {
307308 }}</style>
308309 <span>
309310 <style>@scope{:scope{
311+ &::before {
312+ content: \\"\\";
313+ display: block
314+ }
310315 &::selection {background: blue}
311316 }}</style>
312317 Content
@@ -315,6 +320,42 @@ test("includes pseudo elements", () => {
315320 ` ) ;
316321} ) ;
317322
323+ test ( "pseudo elements only included when they render" , ( ) => {
324+ const html = `
325+ <div class="test"><div class="other">Content</div></div>
326+ ` ;
327+
328+ const styles = `
329+ .test::before { content: "prefix"; color: blue; }
330+ .test::after { content: ""; color: red; }
331+ .test::selection { background: yellow; }
332+ .test::first-line { font-weight: bold; }
333+
334+ .other::before { display: block; }
335+ .other::after { content: none; color: red; }
336+ ` ;
337+
338+ expect ( testHTML ( html , styles ) ) . toMatchInlineSnapshot ( `
339+ "<div>
340+ <style>@scope{:scope{
341+ &::after {
342+ color: red;
343+ content: \\"\\"
344+ }
345+ &::before {
346+ color: blue;
347+ content: \\"prefix\\"
348+ }
349+ &::first-line {font-weight: bold}
350+ &::selection {background: yellow}
351+ }}</style>
352+ <div>
353+ Content
354+ </div>
355+ </div>"
356+ ` ) ;
357+ } ) ;
358+
318359function testHTML ( html : string , styles : string = "" ) {
319360 const div = document . createElement ( "div" ) ;
320361 const style = document . createElement ( "style" ) ;
Original file line number Diff line number Diff line change @@ -94,7 +94,7 @@ export function getPseudoElementStyles(
9494 name ,
9595 stylesByPseudoElement [ name ]
9696 ) ;
97- if ( styles ) {
97+ if ( styles && shouldIncludePseudoElement ( name , styles ) ) {
9898 appliedPseudoElementStyles ||= { } ;
9999 appliedPseudoElementStyles [ name ] = styles ;
100100 }
@@ -103,6 +103,24 @@ export function getPseudoElementStyles(
103103 return appliedPseudoElementStyles ;
104104}
105105
106+ function shouldIncludePseudoElement (
107+ pseudoName : string ,
108+ styles : { [ property : string ] : string }
109+ ) : boolean {
110+ if ( pseudoName !== "::before" && pseudoName !== "::after" ) {
111+ // Other pseudo-elements (::selection, ::first-line, etc.) should always be included.
112+ return true ;
113+ }
114+
115+ const contentValue = styles . content ;
116+
117+ // Pseudo-element renders if:
118+ // - content property exists (not undefined).
119+ // - content: "" (empty string).
120+ // - content is not "none".
121+ return contentValue !== undefined && contentValue !== "none" ;
122+ }
123+
106124/**
107125 * Given a stylesheet returns all css rules including rules from
108126 * nested stylesheets such as media queries or supports.
You can’t perform that action at this time.
0 commit comments