Created attachment 416919 [details] Screen capture of the reproduction of the CSS animation bug We have a couple iframe paint bugs in Safari we've finally been able to consistently reproduce on some systems. In Safari 13+ (and possibly earlier versions), a loaded iframe faded into view through a JavaScript based animation (e.g. `$.fadeIn()`) would sometimes paint blank. In those cases, no composite layer for the iframe would exist. Any reflow of the container would trigger the iframe paint. Applying a transform or other CSS style that would force a composite layer for the iframe would prevent the occurrence of this bug. To reproduce: - In Safari 13+ , open https://hofman-stripe-payments-demo.appspot.com/jq-repro/?stripeStaticLayer=false&stripeTransitionFix=false - Click CB (the frame is painted correctly) - Refresh - Click CB again (make sure network cache is not disabled if devtools are open) - Observe blank painted iframe where card input should be - The iframe is actually functional, can be filed through keyboard or autofill. - Any resize of the container (window) caused the iframe to be painted However, the workaround to force a composite layer through CSS style causes another blank paint bug in Safari 14+. If the loaded iframe is animated into view through a CSS transition on an ancestor, the iframe is painted blank. Without the forced promotion to its own composition layer, the iframe would render fine. A forced reflow of the parent doesn't help repaint the iframe since it has its own composite layer. We have implemented another workaround to listen for transition start events on any ancestor and force a reflow on the iframe itself, however it's very hacky, and we are worried of other undiscovered cases where this bug might trigger. To reproduce: - In Safari 14+, open https://hofman-stripe-payments-demo.appspot.com/?stripeStaticLayer=true&stripeTransitionFix=false - Observe the card iframe painted blank - The iframe is actually functional, can be filed through keyboard or autofill. We've had multiple bug reports from our users about these issues including: - https://github.com/stripe/react-stripe-js/issues/136 - https://github.com/stripe/stripe-js/issues/128 - https://github.com/stripe/stripe-js/issues/113 - https://github.com/stripe/react-stripe-elements/issues/35 While the above reproductions are for desktop Safari, we've had reports of these bugs also happening on iPhone and iPad. There are some triggers we still don't fully understand. For the first reproduction, we don't know why caching seem to have an impact. For the second reproduction, the issue only manifests if the iframe has loaded before the CSS transition starts (the reproduction delays CSS animation until load for consistency). We unfortunately haven't been able to create more minimal reproductions.
Created attachment 416920 [details] Screen capture of the reproduction of the Javascript animation bug
> - In Safari 13+ , open https://hofman-stripe-payments-demo.appspot.com/jq-repro/?stripeStaticLayer=false&stripeTransitionFix=false I can reproduce this issue with a recent WebKit build that I have on my machine. > - In Safari 14+, open https://hofman-stripe-payments-demo.appspot.com/?stripeStaticLayer=true&stripeTransitionFix=false But I cannot reproduces this one. Perhaps it's a Safari 14 regression that's been fixed already.
<rdar://problem/72793724>
> But I cannot reproduces this one. Perhaps it's a Safari 14 regression that's been fixed already. Apparently we still have inconsistent reproduction on this depending on the machine. We're trying to figure out if there is some other factor (e.g. dedicated graphics). Can you reproduce in Safari 14.0.2 (15610.3.7.1.10, 15610)? My machine is a MacBookPro15,2 i7 running macOS 10.15.7 (19H15)
Created attachment 416961 [details] iframe painted when window dragged to built-in display
Created attachment 416963 [details] iframe not painted when window dragged to other display
I believe we've isolated a necessary trigger for this bug: the window needs to be rendered on a secondary display (non-retina?), not the built-in display of the MacBook Pro. Then dragging that window to the built-in display will cause the iframe to be painted. The same is not true if dragging the window to another (non-retina?) display.
I've verified that rendering on a secondary retina monitor does not trigger this bug. It seems that the trigger for the CSS animation based bug is for the window to be rendered on a non-retina display.
I can reproduce the Safari 14 version on a non-retina display.
I can see that the GraphicsLayers are connected across frame boundaries, but the CALayers are not.
Doesn't happen if we don't call m_graphicsLayer->setContentsVisible(false) on the iframe's layer. Hardcoding the deviceScaleFactor() to 1 makes it happen on Retina screens.
Found it.
The "non-retina" part is related to m_compositedBoundsOffsetFromGraphicsLayer which affects whether the iframe's GraphicsLayer uses a m_contentsClippingLayer or not.
Created attachment 417044 [details] Patch
Committed r271191: <https://trac.webkit.org/changeset/271191> All reviewed patches have been landed. Closing bug and clearing flags on attachment 417044 [details].
Thanks for the quick turnaround. For clarification, does the patch also fix the JavaScript based animation bug present since at least Safari 13? Sorry for filing a combined bug on this one, they seemed related since our workaround for the first one triggered the second one.
The Safari 13+ bug does seem to still reproduce after this fix. I'll investigate.
Doing so in bug 220498.