Bug 236876

Summary: REGRESSION (r273129): Text contents in <span> with opacity not repainting/updating when sibling element has "will-change: transform"
Product: WebKit Reporter: Long Zheng <long.zheng>
Component: CompositingAssignee: Simon Fraser (smfr) <simon.fraser>
Status: RESOLVED FIXED    
Severity: Major CC: bfulgham, changseok, esprehn+autocc, ews-watchlist, glenn, kondapallykalyan, mmaxfield, pdr, simon.fraser, webkit-bug-importer, zalan
Priority: P2 Keywords: InRadar
Version: Safari Technology Preview   
Hardware: All   
OS: All   
See Also: https://bugs.webkit.org/show_bug.cgi?id=222136
Attachments:
Description Flags
Demo of the repro
none
Non-reproducing reduction
none
Small testcase
none
Testcase without slider
none
Patch
none
Patch
none
Patch none

Description Long Zheng 2022-02-18 19:22:05 PST
Created attachment 452615 [details]
Demo of the repro

When working on a React application, I noticed that in Safari one of my <span> elements with some text content was not updating even though the underlying value in the DOM has changed. Upon extensive debugging and testing, I have deduced the problem occurs when
- the text <span> element has a CSS opacity value applied
- the sibling element has a CSS "will-change: transform" applied

Repro: 
- https://codesandbox.io/s/broken-feather-rl7u6b?file=/src/App.tsx
- Drag the input slider along the track
- The "Progress: 0" text should update/repaint as you drag the slider
- If you inspect the DOM, you can see the value and the node value does update
(See video attachment)

Actual behaviour:
- The text does not update/repaint
- The text updates/repaints if you mouse select the element

Expected behaviour:
- The text updates as you drag the slider

I have reproed this on
- Safari Version 15.3 (17612.4.9.1.8) on macOS 12.2.1
- Safari Technology Preview Release 140 (Safari 15.4, WebKit 17614.1.1.5) on macOS 12.2.1
- Safari on iOS 15.3.1

I cannot repro this issue on
- Chrome 98.0.4758.102 (Official Build) (arm64)
- Firefox 97.0 (64-bit)
Comment 1 zalan 2022-02-18 21:40:27 PST
Thank you for filing the bug.
This looks to be regressed at r273129.
Comment 2 zalan 2022-02-18 21:41:21 PST
> Thank you for filing the bug.
..report. :)
Comment 3 Radar WebKit Bug Importer 2022-02-18 21:42:01 PST
<rdar://problem/89180092>
Comment 4 Simon Fraser (smfr) 2022-02-25 12:46:59 PST Comment hidden (obsolete)
Comment 5 Simon Fraser (smfr) 2022-02-25 13:12:15 PST
This bug occurs with:
            let valueElement = document.getElementById('value');
            valueElement.firstChild.nodeValue = `Progress: ${value}`;

but not with:
            let valueElement = document.getElementById('value');
            valueElement.textContent = `Progress: ${value}`;
Comment 6 Simon Fraser (smfr) 2022-02-25 13:12:56 PST
Created attachment 453250 [details]
Small testcase
Comment 7 Simon Fraser (smfr) 2022-02-25 13:20:48 PST
Created attachment 453251 [details]
Testcase without slider
Comment 8 Simon Fraser (smfr) 2022-02-25 13:26:47 PST
Render tree looks like:

(B)lock/(I)nline/I(N)line-block, (A)bsolute/Fi(X)ed/(R)elative/Stic(K)y, (F)loating, (O)verflow clip, Anon(Y)mous, (G)enerated, has(L)ayer, hasLayer(S)crollableArea, (C)omposited, (+)Dirty style, (+)Dirty layout
B---YGLSC -+* RenderView at (0,0) size 506x0 renderer->(0x4ff0007d0) layout->[normal child]
B-----LS- -+    HTML RenderBlock at (0,0) size 506x0 renderer->(0x4ff001680) node->(0x4ff015770) layout->[normal child]
B-------- -+      BODY RenderBody at (8,8) size 490x30 renderer->(0x4ff0017a0) node->(0x4ff0156e0) (layout overflow 0,0 490x63) (visual overflow 0,0 490x63) layout->[normal child]
B-----L-C --        DIV RenderBlock at (0,0) size 490x30 renderer->(0x4ff004700) node->(0x4fd3588e0) (layout overflow 0,0 490x30) (visual overflow 0,-3 490x36)
-------- --          line at (0.00,0.00) size (490.00x30.00) baseline (25.00) enclosing top (-3.00) bottom (33.00)
-------- --            Inline level boxes:
-------- --              Inline box at (0.00,-3.00) size (469.89x36.00)
-------- --            Runs:
-------- --              box box at (0.00,-3.00) size 469.89x36.00
-------- --              text box at (0.00,-3.00) size 469.89x36.00 box(9, 48)
I-------- --          #text RenderText renderer->(0x4ff005090) node->(0x4fd342610) length->(53) "\n        Progress value should update after 0.5s\n    "
B-------- -+        DIV RenderBlock at (0,30) size 490x30 renderer->(0x4ff004820) node->(0x4fd358970) (layout overflow 0,-3 490x36) (visual overflow 0,-3 490x36) layout->[normal child]
-------- --          Line: (top: -3 bottom: 33) with leading (top: 0 bottom: 30)
-------- --          RootInlineBox at (0,-3) size 149.17x36 (0x4ff006140) renderer->(0x4ff004820)
-------- --            InlineFlowBox at (0,-3) size 149.17x36 (0x4ff006360) renderer->(0x4ff004fc0)
-------- --              InlineTextBox at (0,-3) size 149.17x36 (0x4ff006210) renderer->(0x4ff005100) run(0, 12) "Progress: 20"
IR----L-C --          SPAN RenderInline  (0.00, 0.00) renderer->(0x4ff004fc0) node->(0x4ff015aa0)
I-------- --            #text RenderText renderer->(0x4ff005100) node->(0x4fd342760) length->(12) "Progress: 20"
I-------- --          #text RenderText renderer->(0x4ff005170) node->(0x4fd3427d0) length->(5) "\n    "

and we do a repaint out of RenderBlockFlow::layoutBlock() that targets RenderBlock 0x4ff004820, thus failing to repaint inside the span's layer.

In the working textContent= case, we manage to repaint the span via RenderTreeBuilder::detachFromRenderElement() as the #text is destroyed.
Comment 9 zalan 2022-02-26 20:58:21 PST
Created attachment 453322 [details]
Patch
Comment 10 zalan 2022-02-27 10:19:55 PST
Created attachment 453348 [details]
Patch
Comment 11 zalan 2022-02-28 15:46:37 PST
Created attachment 453444 [details]
Patch
Comment 12 EWS 2022-03-01 07:11:03 PST
Committed r290645 (247918@main): <https://commits.webkit.org/247918@main>

All reviewed patches have been landed. Closing bug and clearing flags on attachment 453444 [details].
Comment 13 Sam Sneddon [:gsnedders] 2022-05-16 15:38:09 PDT
Just to let everyone know, for those who care about Safari, the fix for this has shipped in Safari 15.5.