Diff
Modified: trunk/LayoutTests/ChangeLog (294290 => 294291)
--- trunk/LayoutTests/ChangeLog 2022-05-17 05:52:04 UTC (rev 294290)
+++ trunk/LayoutTests/ChangeLog 2022-05-17 05:59:55 UTC (rev 294291)
@@ -1,3 +1,30 @@
+2022-05-16 Antti Koivisto <an...@apple.com>
+
+ Resolve ::first-letter eagerly
+ https://bugs.webkit.org/show_bug.cgi?id=239844
+
+ Reviewed by Alan Bujtas.
+
+ * fast/css-generated-content/first-letter-in-nested-before-expected.html: Added.
+ * fast/css-generated-content/first-letter-in-nested-before-expected.png: Removed.
+ * fast/css-generated-content/first-letter-in-nested-before-expected.txt: Removed.
+ * fast/css-generated-content/first-letter-in-nested-before-table-expected.html: Copied from LayoutTests/fast/css-generated-content/first-letter-in-nested-before-table.html.
+ * fast/css-generated-content/first-letter-in-nested-before-table-expected.png: Removed.
+ * fast/css-generated-content/first-letter-in-nested-before-table-expected.txt: Removed.
+ * fast/css-generated-content/first-letter-in-nested-before-table.html:
+ * fast/css-generated-content/first-letter-in-nested-before.html:
+
+ Make reftest and update the behavior. ::first-letter won't affect ::before/after with display:table,
+ matching Firefox behavior (and spec logic).
+
+ * platform/glib/fast/css-generated-content/first-letter-in-nested-before-table-expected.txt: Removed.
+ * platform/gtk/fast/css-generated-content/first-letter-in-nested-before-expected.png: Removed.
+ * platform/gtk/fast/css-generated-content/first-letter-in-nested-before-table-expected.png: Removed.
+ * platform/ios/fast/css-generated-content/first-letter-in-nested-before-table-expected.txt: Removed.
+ * platform/mac/fast/css-generated-content/first-letter-in-nested-before-table-expected.txt: Removed.
+ * platform/win/fast/css-generated-content/first-letter-in-nested-before-table-expected.txt: Removed.
+ * platform/wincairo/fast/css-generated-content/first-letter-in-nested-before-table-expected.txt: Removed.
+
2022-05-16 Karl Rackler <rack...@apple.com>
REGRESSION (r294215): [ iOS ] Nine fast tests are a consistent image failure
Added: trunk/LayoutTests/fast/css-generated-content/first-letter-in-nested-before-expected.html (0 => 294291)
--- trunk/LayoutTests/fast/css-generated-content/first-letter-in-nested-before-expected.html (rev 0)
+++ trunk/LayoutTests/fast/css-generated-content/first-letter-in-nested-before-expected.html 2022-05-17 05:59:55 UTC (rev 294291)
@@ -0,0 +1,3 @@
+<body style="font-family: ahem; -webkit-font-smoothing: none;">
+ <div style="font-size: 100px; color: green;">A</div>
+</body>
Deleted: trunk/LayoutTests/fast/css-generated-content/first-letter-in-nested-before-expected.png
(Binary files differ)
Deleted: trunk/LayoutTests/fast/css-generated-content/first-letter-in-nested-before-expected.txt (294290 => 294291)
--- trunk/LayoutTests/fast/css-generated-content/first-letter-in-nested-before-expected.txt 2022-05-17 05:52:04 UTC (rev 294290)
+++ trunk/LayoutTests/fast/css-generated-content/first-letter-in-nested-before-expected.txt 2022-05-17 05:59:55 UTC (rev 294291)
@@ -1,17 +0,0 @@
-layer at (0,0) size 800x600
- RenderView at (0,0) size 800x600
-layer at (0,0) size 800x600
- RenderBlock {HTML} at (0,0) size 800x600
- RenderBody {BODY} at (8,8) size 784x584
- RenderBlock {DIV} at (0,0) size 784x100 [color=#FF0000]
- RenderText {#text} at (0,0) size 100x100
- text run at (0,0) width 100: "A"
- RenderBlock {DIV} at (0,0) size 784x100 [color=#008000]
- RenderTable at (0,0) size 100x100
- RenderTableSection (anonymous) at (0,0) size 100x100
- RenderTableRow (anonymous) at (0,0) size 100x100
- RenderTableCell (anonymous) at (0,0) size 100x100 [r=0 c=0 rs=1 cs=1]
- RenderInline (generated) at (0,0) size 100x100
- RenderText at (0,0) size 100x100
- text run at (0,0) width 100: "A"
- RenderText at (0,0) size 0x0
Copied: trunk/LayoutTests/fast/css-generated-content/first-letter-in-nested-before-table-expected.html (from rev 294290, trunk/LayoutTests/fast/css-generated-content/first-letter-in-nested-before-table.html) (0 => 294291)
--- trunk/LayoutTests/fast/css-generated-content/first-letter-in-nested-before-table-expected.html (rev 0)
+++ trunk/LayoutTests/fast/css-generated-content/first-letter-in-nested-before-table-expected.html 2022-05-17 05:59:55 UTC (rev 294291)
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html>
+<body style="font-family: ahem; font-size: 50px; -webkit-font-smoothing: none;">
+<style>
+.test1:before {
+ display: table;
+ content: "AB";
+}
+.test2:after {
+ display: table;
+ content: "EF";
+}
+</style>
+<div class="test1">C</div>
+<div class="test2"><span style="color:green">D</span></div>
+<div class="test2"></div>
+<script>
+document.body.offsetTop;
+document.body.style.color = "blue";
+</script>
+</html>
Deleted: trunk/LayoutTests/fast/css-generated-content/first-letter-in-nested-before-table-expected.png
(Binary files differ)
Deleted: trunk/LayoutTests/fast/css-generated-content/first-letter-in-nested-before-table-expected.txt (294290 => 294291)
--- trunk/LayoutTests/fast/css-generated-content/first-letter-in-nested-before-table-expected.txt 2022-05-17 05:52:04 UTC (rev 294290)
+++ trunk/LayoutTests/fast/css-generated-content/first-letter-in-nested-before-table-expected.txt 2022-05-17 05:59:55 UTC (rev 294291)
@@ -1,40 +0,0 @@
-layer at (0,0) size 800x600
- RenderView at (0,0) size 800x600
-layer at (0,0) size 800x266
- RenderBlock {HTML} at (0,0) size 800x266
- RenderBody {BODY} at (8,8) size 784x250 [color=#0000FF]
- RenderBlock {DIV} at (0,0) size 784x100
- RenderTable at (0,0) size 100x50
- RenderTableSection (anonymous) at (0,0) size 100x50
- RenderTableRow (anonymous) at (0,0) size 100x50
- RenderTableCell (anonymous) at (0,0) size 100x50 [r=0 c=0 rs=1 cs=1]
- RenderInline (generated) at (0,0) size 50x50 [color=#008000]
- RenderText at (0,0) size 50x50
- text run at (0,0) width 50: "A"
- RenderText at (50,0) size 50x50
- text run at (50,0) width 50: "B"
- RenderBlock (anonymous) at (0,50) size 784x50
- RenderText {#text} at (0,0) size 50x50
- text run at (0,0) width 50: "C"
- RenderBlock {DIV} at (0,100) size 784x100
- RenderBlock (anonymous) at (0,0) size 784x50
- RenderInline (generated) at (0,0) size 50x50 [color=#008000]
- RenderText {#text} at (0,0) size 50x50
- text run at (0,0) width 50: "D"
- RenderText {#text} at (0,0) size 0x0
- RenderTable at (0,50) size 100x50
- RenderTableSection (anonymous) at (0,0) size 100x50
- RenderTableRow (anonymous) at (0,0) size 100x50
- RenderTableCell (anonymous) at (0,0) size 100x50 [r=0 c=0 rs=1 cs=1]
- RenderText at (0,0) size 100x50
- text run at (0,0) width 100: "EF"
- RenderBlock {DIV} at (0,200) size 784x50
- RenderTable at (0,0) size 100x50
- RenderTableSection (anonymous) at (0,0) size 100x50
- RenderTableRow (anonymous) at (0,0) size 100x50
- RenderTableCell (anonymous) at (0,0) size 100x50 [r=0 c=0 rs=1 cs=1]
- RenderInline (generated) at (0,0) size 50x50 [color=#008000]
- RenderText at (0,0) size 50x50
- text run at (0,0) width 50: "E"
- RenderText at (50,0) size 50x50
- text run at (50,0) width 50: "F"
Modified: trunk/LayoutTests/fast/css-generated-content/first-letter-in-nested-before-table.html (294290 => 294291)
--- trunk/LayoutTests/fast/css-generated-content/first-letter-in-nested-before-table.html 2022-05-17 05:52:04 UTC (rev 294290)
+++ trunk/LayoutTests/fast/css-generated-content/first-letter-in-nested-before-table.html 2022-05-17 05:59:55 UTC (rev 294291)
@@ -1,5 +1,4 @@
<!DOCTYPE html>
-<!-- No text in black, B and F should be blue. -->
<html>
<body style="font-family: ahem; font-size: 50px; -webkit-font-smoothing: none;">
<style>
@@ -21,4 +20,4 @@
document.body.offsetTop;
document.body.style.color = "blue";
</script>
-</html>
\ No newline at end of file
+</html>
Modified: trunk/LayoutTests/fast/css-generated-content/first-letter-in-nested-before.html (294290 => 294291)
--- trunk/LayoutTests/fast/css-generated-content/first-letter-in-nested-before.html 2022-05-17 05:52:04 UTC (rev 294290)
+++ trunk/LayoutTests/fast/css-generated-content/first-letter-in-nested-before.html 2022-05-17 05:59:55 UTC (rev 294291)
@@ -1,6 +1,6 @@
<style>
#target { color: green; margin-top: -100px; }
- #target:before { display: table; content: "A"; }
+ #target:before { display: block; content: "A"; }
#target:first-letter { font-size: 200%; }
</style>
<body style="font-family: ahem; -webkit-font-smoothing: none;">
Deleted: trunk/LayoutTests/platform/glib/fast/css-generated-content/first-letter-in-nested-before-table-expected.txt (294290 => 294291)
--- trunk/LayoutTests/platform/glib/fast/css-generated-content/first-letter-in-nested-before-table-expected.txt 2022-05-17 05:52:04 UTC (rev 294290)
+++ trunk/LayoutTests/platform/glib/fast/css-generated-content/first-letter-in-nested-before-table-expected.txt 2022-05-17 05:59:55 UTC (rev 294291)
@@ -1,40 +0,0 @@
-layer at (0,0) size 800x600
- RenderView at (0,0) size 800x600
-layer at (0,0) size 800x266
- RenderBlock {HTML} at (0,0) size 800x266
- RenderBody {BODY} at (8,8) size 784x250 [color=#0000FF]
- RenderBlock {DIV} at (0,0) size 784x100
- RenderTable at (0,0) size 100x50
- RenderTableSection (anonymous) at (0,0) size 100x50
- RenderTableRow (anonymous) at (0,0) size 100x50
- RenderTableCell (anonymous) at (0,0) size 100x50 [r=0 c=0 rs=1 cs=1]
- RenderInline (generated) at (0,0) size 50x50 [color=#008000]
- RenderText at (0,0) size 50x50
- text run at (0,0) width 50: "A"
- RenderText at (50,0) size 50x50
- text run at (50,0) width 50: "B"
- RenderBlock (anonymous) at (0,50) size 784x50
- RenderText {#text} at (0,0) size 50x50
- text run at (0,0) width 50: "C"
- RenderBlock {DIV} at (0,100) size 784x100
- RenderBlock (anonymous) at (0,0) size 784x50
- RenderInline (generated) at (0,0) size 50x50 [color=#008000]
- RenderText at (0,0) size 50x50
- text run at (0,0) width 50: "D"
- RenderText {#text} at (0,0) size 0x0
- RenderTable at (0,50) size 100x50
- RenderTableSection (anonymous) at (0,0) size 100x50
- RenderTableRow (anonymous) at (0,0) size 100x50
- RenderTableCell (anonymous) at (0,0) size 100x50 [r=0 c=0 rs=1 cs=1]
- RenderText at (0,0) size 100x50
- text run at (0,0) width 100: "EF"
- RenderBlock {DIV} at (0,200) size 784x50
- RenderTable at (0,0) size 100x50
- RenderTableSection (anonymous) at (0,0) size 100x50
- RenderTableRow (anonymous) at (0,0) size 100x50
- RenderTableCell (anonymous) at (0,0) size 100x50 [r=0 c=0 rs=1 cs=1]
- RenderInline (generated) at (0,0) size 50x50 [color=#008000]
- RenderText at (0,0) size 50x50
- text run at (0,0) width 50: "E"
- RenderText at (50,0) size 50x50
- text run at (50,0) width 50: "F"
Deleted: trunk/LayoutTests/platform/gtk/fast/css-generated-content/first-letter-in-nested-before-expected.png
(Binary files differ)
Deleted: trunk/LayoutTests/platform/gtk/fast/css-generated-content/first-letter-in-nested-before-table-expected.png
(Binary files differ)
Deleted: trunk/LayoutTests/platform/ios/fast/css-generated-content/first-letter-in-nested-before-table-expected.txt (294290 => 294291)
--- trunk/LayoutTests/platform/ios/fast/css-generated-content/first-letter-in-nested-before-table-expected.txt 2022-05-17 05:52:04 UTC (rev 294290)
+++ trunk/LayoutTests/platform/ios/fast/css-generated-content/first-letter-in-nested-before-table-expected.txt 2022-05-17 05:59:55 UTC (rev 294291)
@@ -1,40 +0,0 @@
-layer at (0,0) size 800x600
- RenderView at (0,0) size 800x600
-layer at (0,0) size 800x266
- RenderBlock {HTML} at (0,0) size 800x266
- RenderBody {BODY} at (8,8) size 784x250 [color=#0000FF]
- RenderBlock {DIV} at (0,0) size 784x100
- RenderTable at (0,0) size 100x50
- RenderTableSection (anonymous) at (0,0) size 100x50
- RenderTableRow (anonymous) at (0,0) size 100x50
- RenderTableCell (anonymous) at (0,0) size 100x50 [r=0 c=0 rs=1 cs=1]
- RenderInline (generated) at (0,0) size 50x50 [color=#008000]
- RenderText at (0,0) size 50x50
- text run at (0,0) width 50: "A"
- RenderText at (50,0) size 50x50
- text run at (50,0) width 50: "B"
- RenderBlock (anonymous) at (0,50) size 784x50
- RenderText {#text} at (0,0) size 50x50
- text run at (0,0) width 50: "C"
- RenderBlock {DIV} at (0,100) size 784x100
- RenderBlock (anonymous) at (0,0) size 784x50
- RenderInline (generated) at (0,0) size 50x50 [color=#008000]
- RenderText at (0,0) size 50x50
- text run at (0,0) width 50: "D"
- RenderText {#text} at (0,0) size 0x0
- RenderTable at (0,50) size 100x50
- RenderTableSection (anonymous) at (0,0) size 100x50
- RenderTableRow (anonymous) at (0,0) size 100x50
- RenderTableCell (anonymous) at (0,0) size 100x50 [r=0 c=0 rs=1 cs=1]
- RenderText at (0,0) size 100x50
- text run at (0,0) width 100: "EF"
- RenderBlock {DIV} at (0,200) size 784x50
- RenderTable at (0,0) size 100x50
- RenderTableSection (anonymous) at (0,0) size 100x50
- RenderTableRow (anonymous) at (0,0) size 100x50
- RenderTableCell (anonymous) at (0,0) size 100x50 [r=0 c=0 rs=1 cs=1]
- RenderInline (generated) at (0,0) size 50x50 [color=#008000]
- RenderText at (0,0) size 50x50
- text run at (0,0) width 50: "E"
- RenderText at (50,0) size 50x50
- text run at (50,0) width 50: "F"
Deleted: trunk/LayoutTests/platform/mac/fast/css-generated-content/first-letter-in-nested-before-table-expected.txt (294290 => 294291)
--- trunk/LayoutTests/platform/mac/fast/css-generated-content/first-letter-in-nested-before-table-expected.txt 2022-05-17 05:52:04 UTC (rev 294290)
+++ trunk/LayoutTests/platform/mac/fast/css-generated-content/first-letter-in-nested-before-table-expected.txt 2022-05-17 05:59:55 UTC (rev 294291)
@@ -1,40 +0,0 @@
-layer at (0,0) size 800x600
- RenderView at (0,0) size 800x600
-layer at (0,0) size 800x266
- RenderBlock {HTML} at (0,0) size 800x266
- RenderBody {BODY} at (8,8) size 784x250 [color=#0000FF]
- RenderBlock {DIV} at (0,0) size 784x100
- RenderTable at (0,0) size 100x50
- RenderTableSection (anonymous) at (0,0) size 100x50
- RenderTableRow (anonymous) at (0,0) size 100x50
- RenderTableCell (anonymous) at (0,0) size 100x50 [r=0 c=0 rs=1 cs=1]
- RenderInline (generated) at (0,0) size 50x50 [color=#008000]
- RenderText at (0,0) size 50x50
- text run at (0,0) width 50: "A"
- RenderText at (50,0) size 50x50
- text run at (50,0) width 50: "B"
- RenderBlock (anonymous) at (0,50) size 784x50
- RenderText {#text} at (0,0) size 50x50
- text run at (0,0) width 50: "C"
- RenderBlock {DIV} at (0,100) size 784x100
- RenderBlock (anonymous) at (0,0) size 784x50
- RenderInline (generated) at (0,0) size 50x50 [color=#008000]
- RenderText at (0,0) size 50x50
- text run at (0,0) width 50: "D"
- RenderText {#text} at (0,0) size 0x0
- RenderTable at (0,50) size 100x50
- RenderTableSection (anonymous) at (0,0) size 100x50
- RenderTableRow (anonymous) at (0,0) size 100x50
- RenderTableCell (anonymous) at (0,0) size 100x50 [r=0 c=0 rs=1 cs=1]
- RenderText at (0,0) size 100x50
- text run at (0,0) width 100: "EF"
- RenderBlock {DIV} at (0,200) size 784x50
- RenderTable at (0,0) size 100x50
- RenderTableSection (anonymous) at (0,0) size 100x50
- RenderTableRow (anonymous) at (0,0) size 100x50
- RenderTableCell (anonymous) at (0,0) size 100x50 [r=0 c=0 rs=1 cs=1]
- RenderInline (generated) at (0,0) size 50x50 [color=#008000]
- RenderText at (0,0) size 50x50
- text run at (0,0) width 50: "E"
- RenderText at (50,0) size 50x50
- text run at (50,0) width 50: "F"
Deleted: trunk/LayoutTests/platform/win/fast/css-generated-content/first-letter-in-nested-before-table-expected.txt (294290 => 294291)
--- trunk/LayoutTests/platform/win/fast/css-generated-content/first-letter-in-nested-before-table-expected.txt 2022-05-17 05:52:04 UTC (rev 294290)
+++ trunk/LayoutTests/platform/win/fast/css-generated-content/first-letter-in-nested-before-table-expected.txt 2022-05-17 05:59:55 UTC (rev 294291)
@@ -1,40 +0,0 @@
-layer at (0,0) size 800x600
- RenderView at (0,0) size 800x600
-layer at (0,0) size 800x266
- RenderBlock {HTML} at (0,0) size 800x266
- RenderBody {BODY} at (8,8) size 784x250 [color=#0000FF]
- RenderBlock {DIV} at (0,0) size 784x100
- RenderTable at (0,0) size 100x50
- RenderTableSection (anonymous) at (0,0) size 100x50
- RenderTableRow (anonymous) at (0,0) size 100x50
- RenderTableCell (anonymous) at (0,0) size 100x50 [r=0 c=0 rs=1 cs=1]
- RenderInline (generated) at (0,0) size 50x50 [color=#008000]
- RenderText at (0,0) size 50x50
- text run at (0,0) width 50: "A"
- RenderText at (50,0) size 50x50
- text run at (50,0) width 50: "B"
- RenderBlock (anonymous) at (0,50) size 784x50
- RenderText {#text} at (0,0) size 50x50
- text run at (0,0) width 50: "C"
- RenderBlock {DIV} at (0,100) size 784x100
- RenderBlock (anonymous) at (0,0) size 784x50
- RenderInline (generated) at (0,0) size 50x50 [color=#008000]
- RenderText at (0,0) size 50x50
- text run at (0,0) width 50: "D"
- RenderText {#text} at (0,0) size 0x0
- RenderTable at (0,50) size 100x50
- RenderTableSection (anonymous) at (0,0) size 100x50
- RenderTableRow (anonymous) at (0,0) size 100x50
- RenderTableCell (anonymous) at (0,0) size 100x50 [r=0 c=0 rs=1 cs=1]
- RenderText at (0,0) size 100x50
- text run at (0,0) width 100: "EF"
- RenderBlock {DIV} at (0,200) size 784x50
- RenderTable at (0,0) size 100x50
- RenderTableSection (anonymous) at (0,0) size 100x50
- RenderTableRow (anonymous) at (0,0) size 100x50
- RenderTableCell (anonymous) at (0,0) size 100x50 [r=0 c=0 rs=1 cs=1]
- RenderInline (generated) at (0,0) size 50x50 [color=#008000]
- RenderText at (0,0) size 50x50
- text run at (0,0) width 50: "E"
- RenderText at (50,0) size 50x50
- text run at (50,0) width 50: "F"
Deleted: trunk/LayoutTests/platform/wincairo/fast/css-generated-content/first-letter-in-nested-before-table-expected.txt (294290 => 294291)
--- trunk/LayoutTests/platform/wincairo/fast/css-generated-content/first-letter-in-nested-before-table-expected.txt 2022-05-17 05:52:04 UTC (rev 294290)
+++ trunk/LayoutTests/platform/wincairo/fast/css-generated-content/first-letter-in-nested-before-table-expected.txt 2022-05-17 05:59:55 UTC (rev 294291)
@@ -1,40 +0,0 @@
-layer at (0,0) size 800x600
- RenderView at (0,0) size 800x600
-layer at (0,0) size 800x266
- RenderBlock {HTML} at (0,0) size 800x266
- RenderBody {BODY} at (8,8) size 784x250 [color=#0000FF]
- RenderBlock {DIV} at (0,0) size 784x100
- RenderTable at (0,0) size 100x50
- RenderTableSection (anonymous) at (0,0) size 100x50
- RenderTableRow (anonymous) at (0,0) size 100x50
- RenderTableCell (anonymous) at (0,0) size 100x50 [r=0 c=0 rs=1 cs=1]
- RenderInline (generated) at (0,0) size 50x50 [color=#008000]
- RenderText at (0,0) size 50x50
- text run at (0,0) width 50: "A"
- RenderText at (50,0) size 50x50
- text run at (50,0) width 50: "B"
- RenderBlock (anonymous) at (0,50) size 784x50
- RenderText {#text} at (0,0) size 50x50
- text run at (0,0) width 50: "C"
- RenderBlock {DIV} at (0,100) size 784x100
- RenderBlock (anonymous) at (0,0) size 784x50
- RenderInline (generated) at (0,0) size 50x50 [color=#008000]
- RenderText at (0,0) size 50x50
- text run at (0,0) width 50: "D"
- RenderText {#text} at (0,0) size 0x0
- RenderTable at (0,50) size 100x50
- RenderTableSection (anonymous) at (0,0) size 100x50
- RenderTableRow (anonymous) at (0,0) size 100x50
- RenderTableCell (anonymous) at (0,0) size 100x50 [r=0 c=0 rs=1 cs=1]
- RenderText at (0,0) size 100x50
- text run at (0,0) width 100: "EF"
- RenderBlock {DIV} at (0,200) size 784x50
- RenderTable at (0,0) size 100x50
- RenderTableSection (anonymous) at (0,0) size 100x50
- RenderTableRow (anonymous) at (0,0) size 100x50
- RenderTableCell (anonymous) at (0,0) size 100x50 [r=0 c=0 rs=1 cs=1]
- RenderInline (generated) at (0,0) size 50x50 [color=#008000]
- RenderText at (0,0) size 50x50
- text run at (0,0) width 50: "E"
- RenderText at (50,0) size 50x50
- text run at (50,0) width 50: "F"
Modified: trunk/Source/WebCore/ChangeLog (294290 => 294291)
--- trunk/Source/WebCore/ChangeLog 2022-05-17 05:52:04 UTC (rev 294290)
+++ trunk/Source/WebCore/ChangeLog 2022-05-17 05:59:55 UTC (rev 294291)
@@ -1,3 +1,54 @@
+2022-05-16 Antti Koivisto <an...@apple.com>
+
+ Resolve ::first-letter eagerly
+ https://bugs.webkit.org/show_bug.cgi?id=239844
+
+ Reviewed by Alan Bujtas.
+
+ ::first-letter pseudo-element should be resolved eagerly during style resolution, similar to ::first-line.
+ This will clean up the architecture. It also makes ::first-letter animatable.
+
+ * rendering/RenderTextFragment.cpp:
+ (WebCore::RenderTextFragment::styleDidChange): Deleted.
+ * rendering/RenderTextFragment.h:
+ * rendering/style/RenderStyle.cpp:
+ (WebCore::RenderStyle::removeCachedPseudoStyle): Deleted.
+
+ We always create a new style. There is no need to removed pseudo element styles.
+
+ * rendering/style/RenderStyle.h:
+ * rendering/updating/RenderTreeBuilderFirstLetter.cpp:
+ (WebCore::styleForFirstLetter):
+
+ Pull first-letter style from the parent style instead of resolving it in the middle of render tree building.
+
+ (WebCore::RenderTreeBuilder::FirstLetter::updateAfterDescendants):
+ (WebCore::RenderTreeBuilder::FirstLetter::updateStyle):
+
+ Delete the renderer if we no longer have a style.
+
+ (WebCore::RenderTreeBuilder::FirstLetter::createRenderers):
+ * rendering/updating/RenderTreeBuilderFirstLetter.h:
+ * style/StyleTreeResolver.cpp:
+ (WebCore::Style::TreeResolver::resolveElement):
+
+ Resove first-letter.
+
+ (WebCore::Style::TreeResolver::resolvePseudoElement):
+ (WebCore::Style::TreeResolver::resolveInheritedPseudoElement):
+
+ Factor into a function.
+
+ (WebCore::Style::isChildInBlockFormattingContext):
+ (WebCore::Style::TreeResolver::resolveAncestorFirstLinePseudoElement):
+ (WebCore::Style::TreeResolver::resolveAncestorFirstLetterPseudoElement):
+
+ Resolving first-letter is similar to first-line except it is always a leaf and so won't be inherited from.
+
+ (WebCore::Style::TreeResolver::makeResolutionContextForPseudoElement):
+ (WebCore::Style::TreeResolver::makeResolutionContextForInheritedFirstLine):
+ * style/StyleTreeResolver.h:
+
2022-05-16 Zan Dobersek <zdober...@igalia.com>
[GTK][WPE] Current-context enforcement in ANGLE is expensive
Modified: trunk/Source/WebCore/rendering/RenderTextFragment.cpp (294290 => 294291)
--- trunk/Source/WebCore/rendering/RenderTextFragment.cpp 2022-05-17 05:52:04 UTC (rev 294290)
+++ trunk/Source/WebCore/rendering/RenderTextFragment.cpp 2022-05-17 05:59:55 UTC (rev 294291)
@@ -69,14 +69,6 @@
return textNode() && textNode()->hasEditableStyle();
}
-void RenderTextFragment::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
-{
- RenderText::styleDidChange(diff, oldStyle);
-
- if (RenderBlock* block = blockForAccompanyingFirstLetter())
- block->mutableStyle().removeCachedPseudoStyle(PseudoId::FirstLetter);
-}
-
void RenderTextFragment::setText(const String& newText, bool force)
{
RenderText::setText(newText, force);
Modified: trunk/Source/WebCore/rendering/RenderTextFragment.h (294290 => 294291)
--- trunk/Source/WebCore/rendering/RenderTextFragment.h 2022-05-17 05:52:04 UTC (rev 294290)
+++ trunk/Source/WebCore/rendering/RenderTextFragment.h 2022-05-17 05:59:55 UTC (rev 294291)
@@ -60,7 +60,6 @@
private:
bool isTextFragment() const override { return true; }
- void styleDidChange(StyleDifference, const RenderStyle* oldStyle) override;
UChar previousCharacter() const override;
Modified: trunk/Source/WebCore/rendering/TextAutoSizing.cpp (294290 => 294291)
--- trunk/Source/WebCore/rendering/TextAutoSizing.cpp 2022-05-17 05:52:04 UTC (rev 294290)
+++ trunk/Source/WebCore/rendering/TextAutoSizing.cpp 2022-05-17 05:59:55 UTC (rev 294291)
@@ -45,6 +45,11 @@
static RenderStyle cloneRenderStyleWithState(const RenderStyle& currentStyle)
{
auto newStyle = RenderStyle::clone(currentStyle);
+
+ // FIXME: This should probably handle at least ::first-line too.
+ if (auto* firstLetterStyle = currentStyle.getCachedPseudoStyle(PseudoId::FirstLetter))
+ newStyle.addCachedPseudoStyle(makeUnique<RenderStyle>(RenderStyle::clone(*firstLetterStyle)));
+
if (currentStyle.lastChildState())
newStyle.setLastChildState();
if (currentStyle.firstChildState())
@@ -170,6 +175,21 @@
auto* block = downcast<RenderTextFragment>(textRenderer).blockForAccompanyingFirstLetter();
if (!block)
continue;
+
+ RenderObject* firstLetterRenderer;
+ RenderElement* dummy;
+ block->getFirstLetter(firstLetterRenderer, dummy);
+ if (firstLetterRenderer && firstLetterRenderer->parent() && firstLetterRenderer->parent()->parent()) {
+ auto& parentStyle = firstLetterRenderer->parent()->parent()->style();
+ auto* firstLetterStyle = parentStyle.getCachedPseudoStyle(PseudoId::FirstLetter);
+ if (!firstLetterStyle)
+ continue;
+ auto fontDescription = firstLetterStyle->fontDescription();
+ fontDescription.setComputedSize(averageSize * fontDescription.specifiedSize() / parentStyle.fontDescription().specifiedSize());
+ firstLetterStyle->setFontDescription(FontCascadeDescription { fontDescription });
+ firstLetterStyle->fontCascade().update(&node->document().fontSelector());
+ }
+
builder.updateAfterDescendants(*block);
}
Modified: trunk/Source/WebCore/rendering/style/RenderStyle.cpp (294290 => 294291)
--- trunk/Source/WebCore/rendering/style/RenderStyle.cpp 2022-05-17 05:52:04 UTC (rev 294290)
+++ trunk/Source/WebCore/rendering/style/RenderStyle.cpp 2022-05-17 05:59:55 UTC (rev 294291)
@@ -115,14 +115,7 @@
RenderStyle RenderStyle::cloneIncludingPseudoElements(const RenderStyle& style)
{
auto newStyle = RenderStyle(style, Clone);
-
- if (!style.m_cachedPseudoStyles)
- return newStyle;
-
- for (auto& pseudoElementStyle : *style.m_cachedPseudoStyles) {
- auto clone = makeUnique<RenderStyle>(cloneIncludingPseudoElements(*pseudoElementStyle));
- newStyle.addCachedPseudoStyle(WTFMove(clone));
- }
+ newStyle.copyPseudoElementsFrom(style);
return newStyle;
}
@@ -392,6 +385,15 @@
m_rareNonInheritedData.access().content = other.m_rareNonInheritedData->content->clone();
}
+void RenderStyle::copyPseudoElementsFrom(const RenderStyle& other)
+{
+ if (!other.m_cachedPseudoStyles)
+ return;
+
+ for (auto& pseudoElementStyle : *other.m_cachedPseudoStyles)
+ addCachedPseudoStyle(makeUnique<RenderStyle>(cloneIncludingPseudoElements(*pseudoElementStyle)));
+}
+
bool RenderStyle::operator==(const RenderStyle& other) const
{
// compare everything except the pseudoStyle pointer
@@ -450,19 +452,6 @@
return result;
}
-void RenderStyle::removeCachedPseudoStyle(PseudoId pid)
-{
- if (!m_cachedPseudoStyles)
- return;
- for (size_t i = 0; i < m_cachedPseudoStyles->size(); ++i) {
- RenderStyle* pseudoStyle = m_cachedPseudoStyles->at(i).get();
- if (pseudoStyle->styleType() == pid) {
- m_cachedPseudoStyles->remove(i);
- return;
- }
- }
-}
-
bool RenderStyle::inheritedEqual(const RenderStyle& other) const
{
return m_inheritedFlags == other.m_inheritedFlags
Modified: trunk/Source/WebCore/rendering/style/RenderStyle.h (294290 => 294291)
--- trunk/Source/WebCore/rendering/style/RenderStyle.h 2022-05-17 05:52:04 UTC (rev 294290)
+++ trunk/Source/WebCore/rendering/style/RenderStyle.h 2022-05-17 05:59:55 UTC (rev 294291)
@@ -169,6 +169,7 @@
void fastPathInheritFrom(const RenderStyle&);
void copyNonInheritedFrom(const RenderStyle&);
void copyContentFrom(const RenderStyle&);
+ void copyPseudoElementsFrom(const RenderStyle&);
ContentPosition resolvedJustifyContentPosition(const StyleContentAlignmentData& normalValueBehavior) const;
ContentDistribution resolvedJustifyContentDistribution(const StyleContentAlignmentData& normalValueBehavior) const;
@@ -186,7 +187,6 @@
RenderStyle* getCachedPseudoStyle(PseudoId) const;
RenderStyle* addCachedPseudoStyle(std::unique_ptr<RenderStyle>);
- void removeCachedPseudoStyle(PseudoId);
const PseudoStyleCache* cachedPseudoStyles() const { return m_cachedPseudoStyles.get(); }
Modified: trunk/Source/WebCore/rendering/updating/RenderTreeBuilderFirstLetter.cpp (294290 => 294291)
--- trunk/Source/WebCore/rendering/updating/RenderTreeBuilderFirstLetter.cpp 2022-05-17 05:52:04 UTC (rev 294290)
+++ trunk/Source/WebCore/rendering/updating/RenderTreeBuilderFirstLetter.cpp 2022-05-17 05:59:55 UTC (rev 294291)
@@ -38,12 +38,15 @@
namespace WebCore {
-static RenderStyle styleForFirstLetter(const RenderBlock& firstLetterBlock, const RenderObject& firstLetterContainer)
+static std::optional<RenderStyle> styleForFirstLetter(const RenderElement& firstLetterContainer)
{
- auto* containerFirstLetterStyle = firstLetterBlock.getCachedPseudoStyle(PseudoId::FirstLetter, &firstLetterContainer.firstLineStyle());
- // FIXME: first-letter style needs to be computed eagerly.
- auto firstLetterStyle = RenderStyle::clone(containerFirstLetterStyle ? *containerFirstLetterStyle : firstLetterContainer.firstLineStyle());
+ auto& styleContainer = firstLetterContainer.isAnonymous() && firstLetterContainer.parent() ? *firstLetterContainer.parent() : firstLetterContainer;
+ auto style = styleContainer.style().getCachedPseudoStyle(PseudoId::FirstLetter);
+ if (!style)
+ return { };
+ auto firstLetterStyle = RenderStyle::clone(*style);
+
// If we have an initial letter drop that is >= 1, then we need to force floating to be on.
if (firstLetterStyle.initialLetterDrop() >= 1 && !firstLetterStyle.isFloating())
firstLetterStyle.setFloating(firstLetterStyle.isLeftToRightDirection() ? Float::Left : Float::Right);
@@ -150,7 +153,7 @@
if (!is<RenderText>(firstLetterRenderer))
return;
- createRenderers(block, downcast<RenderText>(*firstLetterRenderer));
+ createRenderers(downcast<RenderText>(*firstLetterRenderer));
}
void RenderTreeBuilder::FirstLetter::cleanupOnDestroy(RenderTextFragment& textFragment)
@@ -164,18 +167,26 @@
{
RenderElement* firstLetter = currentChild.parent();
ASSERT(firstLetter->isFirstLetter());
+ if (!firstLetter || !firstLetter->parent())
+ return;
- RenderElement* firstLetterContainer = firstLetter->parent();
- auto pseudoStyle = styleForFirstLetter(firstLetterBlock, *firstLetterContainer);
+ auto& firstLetterContainer = *firstLetter->parent();
+
+ auto pseudoStyle = styleForFirstLetter(firstLetterContainer);
+ if (!pseudoStyle) {
+ m_builder.destroy(*firstLetter, CanCollapseAnonymousBlock::No);
+ return;
+ }
+
ASSERT(firstLetter->isFloating() || firstLetter->isInline());
- if (Style::determineChange(firstLetter->style(), pseudoStyle) == Style::Change::Renderer) {
+ if (Style::determineChange(firstLetter->style(), *pseudoStyle) == Style::Change::Renderer) {
// The first-letter renderer needs to be replaced. Create a new renderer of the right type.
RenderPtr<RenderBoxModelObject> newFirstLetter;
- if (pseudoStyle.display() == DisplayType::Inline)
- newFirstLetter = createRenderer<RenderInline>(firstLetterBlock.document(), WTFMove(pseudoStyle));
+ if (pseudoStyle->display() == DisplayType::Inline)
+ newFirstLetter = createRenderer<RenderInline>(firstLetterBlock.document(), WTFMove(*pseudoStyle));
else
- newFirstLetter = createRenderer<RenderBlockFlow>(firstLetterBlock.document(), WTFMove(pseudoStyle));
+ newFirstLetter = createRenderer<RenderBlockFlow>(firstLetterBlock.document(), WTFMove(*pseudoStyle));
newFirstLetter->initializeStyle();
newFirstLetter->setIsFirstLetter();
@@ -195,14 +206,14 @@
}
WeakPtr nextSibling = firstLetter->nextSibling();
m_builder.destroy(*firstLetter);
- m_builder.attach(*firstLetterContainer, WTFMove(newFirstLetter), nextSibling.get());
+ m_builder.attach(firstLetterContainer, WTFMove(newFirstLetter), nextSibling.get());
return;
}
- firstLetter->setStyle(WTFMove(pseudoStyle));
+ firstLetter->setStyle(WTFMove(*pseudoStyle));
}
-void RenderTreeBuilder::FirstLetter::createRenderers(RenderBlock& firstLetterBlock, RenderText& currentTextChild)
+void RenderTreeBuilder::FirstLetter::createRenderers(RenderText& currentTextChild)
{
RenderElement* textContentParent = currentTextChild.parent();
RenderElement* firstLetterContainer = nullptr;
@@ -210,12 +221,18 @@
firstLetterContainer = wrapperInlineForDisplayContents->parent();
else
firstLetterContainer = textContentParent;
- auto pseudoStyle = styleForFirstLetter(firstLetterBlock, *firstLetterContainer);
+ if (!firstLetterContainer)
+ return;
+
+ auto pseudoStyle = styleForFirstLetter(*firstLetterContainer);
+ if (!pseudoStyle)
+ return;
+
RenderPtr<RenderBoxModelObject> newFirstLetter;
- if (pseudoStyle.display() == DisplayType::Inline)
- newFirstLetter = createRenderer<RenderInline>(firstLetterBlock.document(), WTFMove(pseudoStyle));
+ if (pseudoStyle->display() == DisplayType::Inline)
+ newFirstLetter = createRenderer<RenderInline>(currentTextChild.document(), WTFMove(*pseudoStyle));
else
- newFirstLetter = createRenderer<RenderBlockFlow>(firstLetterBlock.document(), WTFMove(pseudoStyle));
+ newFirstLetter = createRenderer<RenderBlockFlow>(currentTextChild.document(), WTFMove(*pseudoStyle));
newFirstLetter->initializeStyle();
newFirstLetter->setIsFirstLetter();
@@ -263,7 +280,7 @@
newRemainingText = createRenderer<RenderTextFragment>(*textNode, oldText, length, oldText.length() - length);
textNode->setRenderer(newRemainingText.get());
} else
- newRemainingText = createRenderer<RenderTextFragment>(firstLetterBlock.document(), oldText, length, oldText.length() - length);
+ newRemainingText = createRenderer<RenderTextFragment>(m_builder.m_view.document(), oldText, length, oldText.length() - length);
RenderTextFragment& remainingText = *newRemainingText;
ASSERT_UNUSED(hasInlineWrapperForDisplayContents, hasInlineWrapperForDisplayContents == inlineWrapperForDisplayContents.get());
@@ -277,7 +294,7 @@
m_builder.attach(*firstLetterContainer, WTFMove(newFirstLetter), &remainingText);
// Construct text fragment for the first letter.
- auto letter = createRenderer<RenderTextFragment>(firstLetterBlock.document(), oldText, 0, length);
+ auto letter = createRenderer<RenderTextFragment>(m_builder.m_view.document(), oldText, 0, length);
m_builder.attach(firstLetter, WTFMove(letter));
}
}
Modified: trunk/Source/WebCore/rendering/updating/RenderTreeBuilderFirstLetter.h (294290 => 294291)
--- trunk/Source/WebCore/rendering/updating/RenderTreeBuilderFirstLetter.h 2022-05-17 05:52:04 UTC (rev 294290)
+++ trunk/Source/WebCore/rendering/updating/RenderTreeBuilderFirstLetter.h 2022-05-17 05:59:55 UTC (rev 294291)
@@ -42,7 +42,7 @@
private:
void updateStyle(RenderBlock& firstLetterBlock, RenderObject& currentChild);
- void createRenderers(RenderBlock& firstLetterBlock, RenderText& currentTextChild);
+ void createRenderers(RenderText& currentTextChild);
RenderTreeBuilder& m_builder;
};
Modified: trunk/Source/WebCore/rendering/updating/RenderTreeUpdaterGeneratedContent.cpp (294290 => 294291)
--- trunk/Source/WebCore/rendering/updating/RenderTreeUpdaterGeneratedContent.cpp 2022-05-17 05:52:04 UTC (rev 294290)
+++ trunk/Source/WebCore/rendering/updating/RenderTreeUpdaterGeneratedContent.cpp 2022-05-17 05:59:55 UTC (rev 294291)
@@ -144,6 +144,7 @@
contentsStyle->setStyleType(pseudoId);
contentsStyle->inheritFrom(*updateStyle);
contentsStyle->copyContentFrom(*updateStyle);
+ contentsStyle->copyPseudoElementsFrom(*updateStyle);
Style::ElementUpdate contentsUpdate { WTFMove(contentsStyle), styleChange, elementUpdate.recompositeLayer };
m_updater.updateElementRenderer(*pseudoElement, WTFMove(contentsUpdate));
Modified: trunk/Source/WebCore/style/StyleTreeResolver.cpp (294290 => 294291)
--- trunk/Source/WebCore/style/StyleTreeResolver.cpp 2022-05-17 05:52:04 UTC (rev 294290)
+++ trunk/Source/WebCore/style/StyleTreeResolver.cpp 2022-05-17 05:59:55 UTC (rev 294291)
@@ -273,6 +273,8 @@
if (resolveAndAddPseudoElementStyle(PseudoId::FirstLine) != Change::None)
descendantsToResolve = DescendantsToResolve::All;
+ if (resolveAndAddPseudoElementStyle(PseudoId::FirstLetter) != Change::None)
+ descendantsToResolve = DescendantsToResolve::All;
resolveAndAddPseudoElementStyle(PseudoId::Marker);
resolveAndAddPseudoElementStyle(PseudoId::Before);
@@ -292,7 +294,7 @@
return { WTFMove(update), descendantsToResolve };
}
-inline bool supportsFirstLinePseudoElement(const RenderStyle& style)
+inline bool supportsFirstLineAndLetterPseudoElement(const RenderStyle& style)
{
auto display = style.display();
return display == DisplayType::Block
@@ -311,53 +313,93 @@
return { };
if (pseudoId == PseudoId::FirstLine && !scope().resolver->usesFirstLineRules())
return { };
+ if (pseudoId == PseudoId::FirstLetter && !scope().resolver->usesFirstLetterRules())
+ return { };
if (elementUpdate.style->display() == DisplayType::None)
return { };
- if (!elementUpdate.style->hasPseudoStyle(pseudoId)) {
- if (pseudoId == PseudoId::FirstLine) {
- auto firstLineStyle = resolveInheritedFirstLinePseudoElement(element, elementUpdate);
- if (!firstLineStyle)
- return { };
+ if (!elementUpdate.style->hasPseudoStyle(pseudoId))
+ return resolveAncestorPseudoElement(element, pseudoId, elementUpdate);
- auto* oldStyle = element.renderOrDisplayContentsStyle(PseudoId::FirstLine);
- auto change = oldStyle ? determineChange(*oldStyle, *firstLineStyle) : Change::Renderer;
- return ElementUpdate { WTFMove(firstLineStyle), change };
- }
+ if ((pseudoId == PseudoId::FirstLine || pseudoId == PseudoId::FirstLetter) && !supportsFirstLineAndLetterPseudoElement(*elementUpdate.style))
return { };
- }
- if (pseudoId == PseudoId::FirstLine && !supportsFirstLinePseudoElement(*elementUpdate.style))
- return { };
+ auto resolutionContext = makeResolutionContextForPseudoElement(elementUpdate, pseudoId);
- auto resolutionContext = makeResolutionContextForPseudoElement(elementUpdate);
-
auto pseudoStyle = scope().resolver->pseudoStyleForElement(element, { pseudoId }, resolutionContext);
if (!pseudoStyle)
return { };
// FIXME: This test shouldn't be needed.
- bool hasAnimations = pseudoStyle->hasAnimationsOrTransitions() || element.hasKeyframeEffects(pseudoId);
- if (pseudoId != PseudoId::FirstLine && !pseudoElementRendererIsNeeded(pseudoStyle.get()) && !hasAnimations)
+ bool alwaysNeedsPseudoElement = pseudoStyle->hasAnimationsOrTransitions()
+ || element.hasKeyframeEffects(pseudoId)
+ || pseudoId == PseudoId::FirstLine
+ || pseudoId == PseudoId::FirstLetter;
+ if (!alwaysNeedsPseudoElement && !pseudoElementRendererIsNeeded(pseudoStyle.get()))
return { };
auto animatedUpdate = createAnimatedElementUpdate(WTFMove(pseudoStyle), { element, pseudoId }, elementUpdate.change, resolutionContext);
if (pseudoId == PseudoId::Before || pseudoId == PseudoId::After) {
- // ::first-line can inherit to ::before/::after
- auto firstLineContext = makeResolutionContextForInheritedFirstLine(elementUpdate, *elementUpdate.style);
- if (firstLineContext) {
- auto firstLineStyle = scope().resolver->pseudoStyleForElement(element, { pseudoId }, *firstLineContext);
- firstLineStyle->setStyleType(PseudoId::FirstLine);
- animatedUpdate.style->addCachedPseudoStyle(WTFMove(firstLineStyle));
+ if (scope().resolver->usesFirstLineRules()) {
+ // ::first-line can inherit to ::before/::after
+ if (auto firstLineContext = makeResolutionContextForInheritedFirstLine(elementUpdate, *elementUpdate.style)) {
+ auto firstLineStyle = scope().resolver->pseudoStyleForElement(element, { pseudoId }, *firstLineContext);
+ firstLineStyle->setStyleType(PseudoId::FirstLine);
+ animatedUpdate.style->addCachedPseudoStyle(WTFMove(firstLineStyle));
+ }
}
+ if (scope().resolver->usesFirstLetterRules()) {
+ auto beforeAfterContext = makeResolutionContextForPseudoElement(animatedUpdate, PseudoId::FirstLetter);
+ if (auto firstLetterStyle = resolveAncestorFirstLetterPseudoElement(element, elementUpdate, beforeAfterContext))
+ animatedUpdate.style->addCachedPseudoStyle(WTFMove(firstLetterStyle));
+ }
}
return animatedUpdate;
}
-std::unique_ptr<RenderStyle> TreeResolver::resolveInheritedFirstLinePseudoElement(Element& element, const ElementUpdate& elementUpdate)
+std::optional<ElementUpdate> TreeResolver::resolveAncestorPseudoElement(Element& element, PseudoId pseudoId, const ElementUpdate& elementUpdate)
{
+ ASSERT(!elementUpdate.style->hasPseudoStyle(pseudoId));
+
+ auto pseudoElementStyle = [&]() -> std::unique_ptr<RenderStyle> {
+ // ::first-line and ::first-letter defined on an ancestor element may need to be resolved for the current element.
+ if (pseudoId == PseudoId::FirstLine)
+ return resolveAncestorFirstLinePseudoElement(element, elementUpdate);
+ if (pseudoId == PseudoId::FirstLetter) {
+ auto resolutionContext = makeResolutionContextForPseudoElement(elementUpdate, PseudoId::FirstLetter);
+ return resolveAncestorFirstLetterPseudoElement(element, elementUpdate, resolutionContext);
+ }
+ return nullptr;
+ }();
+
+ if (!pseudoElementStyle)
+ return { };
+
+ auto* oldStyle = element.renderOrDisplayContentsStyle(pseudoId);
+ auto change = oldStyle ? determineChange(*oldStyle, *pseudoElementStyle) : Change::Renderer;
+ auto resolutionContext = makeResolutionContextForPseudoElement(elementUpdate, pseudoId);
+
+ return createAnimatedElementUpdate(WTFMove(pseudoElementStyle), { element, pseudoId }, change, resolutionContext);
+}
+
+static bool isChildInBlockFormattingContext(const RenderStyle& style)
+{
+ // FIXME: Incomplete. There should be shared code with layout for this.
+ if (style.display() != DisplayType::Block && style.display() != DisplayType::ListItem)
+ return false;
+ if (style.hasOutOfFlowPosition())
+ return false;
+ if (style.floating() != Float::None)
+ return false;
+ if (style.overflowX() != Overflow::Visible || style.overflowY() != Overflow::Visible)
+ return false;
+ return true;
+};
+
+std::unique_ptr<RenderStyle> TreeResolver::resolveAncestorFirstLinePseudoElement(Element& element, const ElementUpdate& elementUpdate)
+{
if (elementUpdate.style->display() == DisplayType::Inline) {
auto* parent = boxGeneratingParent();
if (!parent)
@@ -374,31 +416,18 @@
return firstLineStyle;
}
- auto isChildInBlockFormattingContext = [](const RenderStyle& style) {
- // FIXME: Incomplete. There should be shared code with layout for this.
- if (style.display() != DisplayType::Block)
- return false;
- if (style.hasOutOfFlowPosition())
- return false;
- if (style.floating() != Float::None)
- return false;
- if (style.overflowX() != Overflow::Visible || style.overflowY() != Overflow::Visible)
- return false;
- return true;
- };
-
- auto firstLineElementForBlock = [&]() -> Element* {
+ auto findFirstLineElementForBlock = [&]() -> Element* {
if (!isChildInBlockFormattingContext(*elementUpdate.style))
return nullptr;
// ::first-line is only propagated to the first block.
- if (parent().resolvedFirstBoxGeneratingChild)
+ if (parent().resolvedFirstLineAndLetterChild)
return nullptr;
for (auto& parent : makeReversedRange(m_parentStack)) {
if (parent.style.display() == DisplayType::Contents)
continue;
- if (!supportsFirstLinePseudoElement(parent.style))
+ if (!supportsFirstLineAndLetterPseudoElement(parent.style))
return nullptr;
if (parent.style.hasPseudoStyle(PseudoId::FirstLine))
return parent.element;
@@ -408,11 +437,11 @@
return nullptr;
};
- auto firstLineElement = firstLineElementForBlock();
+ auto firstLineElement = findFirstLineElementForBlock();
if (!firstLineElement)
return { };
- auto resolutionContext = makeResolutionContextForPseudoElement(elementUpdate);
+ auto resolutionContext = makeResolutionContextForPseudoElement(elementUpdate, PseudoId::FirstLine);
// Can't use the cached state since the element being resolved is not the current one.
resolutionContext.selectorMatchingState = nullptr;
@@ -419,6 +448,47 @@
return scope().resolver->pseudoStyleForElement(*firstLineElement, { PseudoId::FirstLine }, resolutionContext);
}
+std::unique_ptr<RenderStyle> TreeResolver::resolveAncestorFirstLetterPseudoElement(Element& element, const ElementUpdate& elementUpdate, ResolutionContext& resolutionContext)
+{
+ auto findFirstLetterElement = [&]() -> Element* {
+ if (elementUpdate.style->hasPseudoStyle(PseudoId::FirstLetter) && supportsFirstLineAndLetterPseudoElement(*elementUpdate.style))
+ return &element;
+
+ // ::first-letter is only propagated to the first box.
+ if (parent().resolvedFirstLineAndLetterChild)
+ return nullptr;
+
+ bool skipInlines = elementUpdate.style->display() == DisplayType::Inline;
+ if (!skipInlines && !isChildInBlockFormattingContext(*elementUpdate.style))
+ return nullptr;
+
+ for (auto& parent : makeReversedRange(m_parentStack)) {
+ if (parent.style.display() == DisplayType::Contents)
+ continue;
+ if (skipInlines && parent.style.display() == DisplayType::Inline)
+ continue;
+ skipInlines = false;
+
+ if (!supportsFirstLineAndLetterPseudoElement(parent.style))
+ return nullptr;
+ if (parent.style.hasPseudoStyle(PseudoId::FirstLetter))
+ return parent.element;
+ if (!isChildInBlockFormattingContext(parent.style))
+ return nullptr;
+ }
+ return nullptr;
+ };
+
+ auto firstLetterElement = findFirstLetterElement();
+ if (!firstLetterElement)
+ return { };
+
+ // Can't use the cached state since the element being resolved is not the current one.
+ resolutionContext.selectorMatchingState = nullptr;
+
+ return scope().resolver->pseudoStyleForElement(*firstLetterElement, { PseudoId::FirstLetter }, resolutionContext);
+}
+
ResolutionContext TreeResolver::makeResolutionContext()
{
return {
@@ -429,10 +499,18 @@
};
}
-ResolutionContext TreeResolver::makeResolutionContextForPseudoElement(const ElementUpdate& elementUpdate)
+ResolutionContext TreeResolver::makeResolutionContextForPseudoElement(const ElementUpdate& elementUpdate, PseudoId pseudoId)
{
+ auto parentStyle = [&] {
+ if (pseudoId == PseudoId::FirstLetter) {
+ if (auto* firstLineStyle = elementUpdate.style->getCachedPseudoStyle(PseudoId::FirstLine))
+ return firstLineStyle;
+ }
+ return elementUpdate.style.get();
+ };
+
return {
- elementUpdate.style.get(),
+ parentStyle(),
parentBoxStyleForPseudoElement(elementUpdate),
m_documentElementStyle.get(),
&scope().selectorMatchingState
@@ -441,9 +519,6 @@
std::optional<ResolutionContext> TreeResolver::makeResolutionContextForInheritedFirstLine(const ElementUpdate& elementUpdate, const RenderStyle& inheritStyle)
{
- if (!scope().resolver->usesFirstLineRules())
- return { };
-
auto parentFirstLineStyle = inheritStyle.getCachedPseudoStyle(PseudoId::FirstLine);
if (!parentFirstLineStyle)
return { };
@@ -705,7 +780,7 @@
}
if (!text.data().isAllSpecialCharacters<isHTMLSpace>())
- parent.resolvedFirstBoxGeneratingChild = true;
+ parent.resolvedFirstLineAndLetterChild = true;
text.setHasValidStyle();
it.traverseNextSkippingChildren();
@@ -762,8 +837,8 @@
if (!m_didSeePendingStylesheet)
m_didSeePendingStylesheet = hasLoadingStylesheet(m_document.styleScope(), element, !shouldIterateChildren);
- if (style && generatesBox(*style))
- parent.resolvedFirstBoxGeneratingChild = true;
+ if (!parent.resolvedFirstLineAndLetterChild && style && generatesBox(*style) && supportsFirstLineAndLetterPseudoElement(*style))
+ parent.resolvedFirstLineAndLetterChild = true;
if (!shouldIterateChildren) {
it.traverseNextSkippingChildren();
Modified: trunk/Source/WebCore/style/StyleTreeResolver.h (294290 => 294291)
--- trunk/Source/WebCore/style/StyleTreeResolver.h 2022-05-17 05:52:04 UTC (rev 294290)
+++ trunk/Source/WebCore/style/StyleTreeResolver.h 2022-05-17 05:59:55 UTC (rev 294291)
@@ -71,7 +71,9 @@
static ElementUpdate createAnimatedElementUpdate(std::unique_ptr<RenderStyle>, const Styleable&, Change, const ResolutionContext&);
std::optional<ElementUpdate> resolvePseudoElement(Element&, PseudoId, const ElementUpdate&);
- std::unique_ptr<RenderStyle> resolveInheritedFirstLinePseudoElement(Element&, const ElementUpdate&);
+ std::optional<ElementUpdate> resolveAncestorPseudoElement(Element&, PseudoId, const ElementUpdate&);
+ std::unique_ptr<RenderStyle> resolveAncestorFirstLinePseudoElement(Element&, const ElementUpdate&);
+ std::unique_ptr<RenderStyle> resolveAncestorFirstLetterPseudoElement(Element&, const ElementUpdate&, ResolutionContext&);
struct Scope : RefCounted<Scope> {
WTF_MAKE_STRUCT_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(TreeResolverScope);
@@ -92,7 +94,7 @@
Change change { Change::None };
DescendantsToResolve descendantsToResolve { DescendantsToResolve::None };
bool didPushScope { false };
- bool resolvedFirstBoxGeneratingChild { false };
+ bool resolvedFirstLineAndLetterChild { false };
Parent(Document&);
Parent(Element&, const RenderStyle&, Change, DescendantsToResolve);
@@ -114,7 +116,7 @@
static void resetDescendantStyleRelations(Element&, DescendantsToResolve);
ResolutionContext makeResolutionContext();
- ResolutionContext makeResolutionContextForPseudoElement(const ElementUpdate&);
+ ResolutionContext makeResolutionContextForPseudoElement(const ElementUpdate&, PseudoId);
std::optional<ResolutionContext> makeResolutionContextForInheritedFirstLine(const ElementUpdate&, const RenderStyle& inheritStyle);
const Parent* boxGeneratingParent() const;
const RenderStyle* parentBoxStyle() const;