- Revision
- 214561
- Author
- cdu...@apple.com
- Date
- 2017-03-29 13:54:21 -0700 (Wed, 29 Mar 2017)
Log Message
Animated SVG images are not paused in pages loaded in the background
https://bugs.webkit.org/show_bug.cgi?id=170043
<rdar://problem/31234412>
Reviewed by Simon Fraser.
Source/WebCore:
Animated SVG images are not paused in pages loaded in the background. We rely
on FrameView::isOffscreen() to stop images animations in background tab (See
logic in RenderElement's shouldRepaintForImageAnimation()). This works fine
if a tab is visble and then becomes hidden (i.e. by switching to another
tab). However, in the case where the tab gets loaded while in the background
(e.g. opening link in new background tab, or session restore), then the
animations would not be paused, due to FrameView::isOffscreen() erroneously
returning false in this case.
Normally, the following chain of events happens:
- Page is visible, we construct a main frame and its FrameView for loading
the page. When a FrameView is constructed, we call FrameView::show() to
make it visible. Then, if the page becomes non-visible, we call
Page::setIsVisibleInternal(false) which calls FrameView::hide(). After
that, FrameView::isOffscreen() correctly returns true because we properly
called FrameView::hide().
However, when doing a load while the Page is hidden, the following was
happening:
- Page is not visible, we call Page::setIsVisibleInternal(false) which tries
to call FrameView::hide() for the main frame but it does not have a FrameView
yet (because the load has not started). We start the load and end up creating
a FrameView. The FrameView constructor was calling FrameView::show()
unconditionally, thus making the FrameView think is visible, even though its
page isn't. At this point, FrameView::isOffscreen() was returning false
and animations would keep running, even though the page is not visible.
To address the issue, we now call FrameView::show() in FrameView::create() only
if the Page is actually visible, instead of calling it unconditionally. If the
page ever becomes visible, Page::setIsVisibleInternal(true) will be called and
it will take care of calling FrameView::show() then.
Tests: svg/animations/animations-paused-in-background-page-iframe.html
svg/animations/animations-paused-in-background-page.html
* page/FrameView.cpp:
(WebCore::FrameView::create):
LayoutTests:
Extend layout test coverage.
* svg/animations/animations-paused-in-background-page-expected.txt: Added.
* svg/animations/animations-paused-in-background-page-iframe-expected.txt: Added.
* svg/animations/animations-paused-in-background-page-iframe.html: Added.
* svg/animations/animations-paused-in-background-page.html: Added.
* svg/animations/resources/iframe-with-animated-svg-image.html: Added.
Modified Paths
Added Paths
Diff
Modified: trunk/LayoutTests/ChangeLog (214560 => 214561)
--- trunk/LayoutTests/ChangeLog 2017-03-29 20:38:54 UTC (rev 214560)
+++ trunk/LayoutTests/ChangeLog 2017-03-29 20:54:21 UTC (rev 214561)
@@ -1,3 +1,19 @@
+2017-03-29 Chris Dumez <cdu...@apple.com>
+
+ Animated SVG images are not paused in pages loaded in the background
+ https://bugs.webkit.org/show_bug.cgi?id=170043
+ <rdar://problem/31234412>
+
+ Reviewed by Simon Fraser.
+
+ Extend layout test coverage.
+
+ * svg/animations/animations-paused-in-background-page-expected.txt: Added.
+ * svg/animations/animations-paused-in-background-page-iframe-expected.txt: Added.
+ * svg/animations/animations-paused-in-background-page-iframe.html: Added.
+ * svg/animations/animations-paused-in-background-page.html: Added.
+ * svg/animations/resources/iframe-with-animated-svg-image.html: Added.
+
2017-03-29 Myles C. Maxfield <mmaxfi...@apple.com>
Post-commit test gardening after r214546
Modified: trunk/LayoutTests/platform/ios/TestExpectations (214560 => 214561)
--- trunk/LayoutTests/platform/ios/TestExpectations 2017-03-29 20:38:54 UTC (rev 214560)
+++ trunk/LayoutTests/platform/ios/TestExpectations 2017-03-29 20:54:21 UTC (rev 214561)
@@ -309,6 +309,8 @@
webkit.org/b/165799 fast/events/page-visibility-onvisibilitychange.html [ Skip ]
webkit.org/b/165799 media/media-playback-page-visibility.html [ Skip ]
webkit.org/b/165799 svg/animations/animations-paused-page-non-visible.html [ Skip ]
+webkit.org/b/165799 svg/animations/animations-paused-in-background-page-iframe.html [ Skip ]
+webkit.org/b/165799 svg/animations/animations-paused-in-background-page.html [ Skip ]
# AutoFill button is not supported
fast/forms/auto-fill-button/mouse-down-input-mouse-release-auto-fill-button.html
Modified: trunk/LayoutTests/platform/mac-wk1/TestExpectations (214560 => 214561)
--- trunk/LayoutTests/platform/mac-wk1/TestExpectations 2017-03-29 20:38:54 UTC (rev 214560)
+++ trunk/LayoutTests/platform/mac-wk1/TestExpectations 2017-03-29 20:54:21 UTC (rev 214561)
@@ -125,6 +125,8 @@
fast/images/animated-gif-zooming.html [ Skip ]
svg/animations/animated-svg-image-outside-viewport-paused.html [ Skip ]
svg/animations/animated-svg-image-removed-from-document-paused.html [ Skip ]
+svg/animations/animations-paused-in-background-page-iframe.html [ Skip ]
+svg/animations/animations-paused-in-background-page.html [ Skip ]
# WK1 uses the native scrollview for scrolling by page.
scrollbars/scrolling-backward-by-page-accounting-bottom-fixed-elements-on-keyboard-spacebar.html
Added: trunk/LayoutTests/svg/animations/animations-paused-in-background-page-expected.txt (0 => 214561)
--- trunk/LayoutTests/svg/animations/animations-paused-in-background-page-expected.txt (rev 0)
+++ trunk/LayoutTests/svg/animations/animations-paused-in-background-page-expected.txt 2017-03-29 20:54:21 UTC (rev 214561)
@@ -0,0 +1,14 @@
+Tests that animated SVG images are properly paused when the page is no longer visible
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS internals.isImageAnimating(testImage) is true
+Setting page visibility to hidden
+PASS internals.isImageAnimating(testImage) became false
+Setting page visibility to visible
+PASS internals.isImageAnimating(testImage) became false
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/svg/animations/animations-paused-in-background-page-iframe-expected.txt (0 => 214561)
--- trunk/LayoutTests/svg/animations/animations-paused-in-background-page-iframe-expected.txt (rev 0)
+++ trunk/LayoutTests/svg/animations/animations-paused-in-background-page-iframe-expected.txt 2017-03-29 20:54:21 UTC (rev 214561)
@@ -0,0 +1,14 @@
+Tests that animated SVG images are properly paused when loaded in a new iframe inside a hidden page
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Setting page visibility to hidden
+PASS document.hidden is true
+PASS internals.isImageAnimating(testImage) is false
+Setting page visibility to visible
+PASS internals.isImageAnimating(testImage) became true
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/svg/animations/animations-paused-in-background-page-iframe.html (0 => 214561)
--- trunk/LayoutTests/svg/animations/animations-paused-in-background-page-iframe.html (rev 0)
+++ trunk/LayoutTests/svg/animations/animations-paused-in-background-page-iframe.html 2017-03-29 20:54:21 UTC (rev 214561)
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src=""
+<script>
+description("Tests that animated SVG images are properly paused when loaded in a new iframe inside a hidden page");
+jsTestIsAsync = true;
+
+function frameLoadedInBackground()
+{
+ setTimeout(function() {
+ testImage = frame.contentDocument.getElementById("testImage");
+ shouldBeFalse("internals.isImageAnimating(testImage)");
+
+ document._onvisibilitychange_ = null;
+ debug("Setting page visibility to visible");
+ if (window.testRunner)
+ testRunner.setPageVisibility('visible');
+
+ shouldBecomeEqual("internals.isImageAnimating(testImage)", "true", finishJSTest);
+ }, 30);
+}
+
+window._onload_ = function() {
+ document._onvisibilitychange_ = function() {
+ setTimeout(function() {
+ shouldBeTrue("document.hidden");
+ frame = document.createElement("iframe");
+ frame.src = ""
+ frame._onload_ = frameLoadedInBackground;
+ document.body.appendChild(frame);
+ }, 30);
+ };
+
+ debug("Setting page visibility to hidden");
+ if (window.testRunner)
+ testRunner.setPageVisibility('hidden');
+}
+</script>
+<script src=""
+</body>
+</html>
Added: trunk/LayoutTests/svg/animations/animations-paused-in-background-page.html (0 => 214561)
--- trunk/LayoutTests/svg/animations/animations-paused-in-background-page.html (rev 0)
+++ trunk/LayoutTests/svg/animations/animations-paused-in-background-page.html 2017-03-29 20:54:21 UTC (rev 214561)
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src=""
+<script>
+description("Tests that animated SVG images are properly paused when the page is no longer visible");
+jsTestIsAsync = true;
+
+function makePageVisible()
+{
+ debug("Setting page visibility to visible");
+ if (window.testRunner)
+ testRunner.setPageVisibility('visible');
+ shouldBecomeEqual("internals.isImageAnimating(testImage)", "false", finishJSTest);
+}
+
+window._onload_ = function() {
+ testImage = document.getElementById("testImage");
+ shouldBeTrue("internals.isImageAnimating(testImage)");
+
+ debug("Setting page visibility to hidden");
+ if (window.testRunner)
+ testRunner.setPageVisibility('hidden');
+
+ shouldBecomeEqual("internals.isImageAnimating(testImage)", "false", makePageVisible);
+}
+</script>
+<img id="testImage" src=""
+<script src=""
+</body>
+</html>
Added: trunk/LayoutTests/svg/animations/resources/iframe-with-animated-svg-image.html (0 => 214561)
--- trunk/LayoutTests/svg/animations/resources/iframe-with-animated-svg-image.html (rev 0)
+++ trunk/LayoutTests/svg/animations/resources/iframe-with-animated-svg-image.html 2017-03-29 20:54:21 UTC (rev 214561)
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<html>
+<body>
+<img id="testImage" src=""
+</body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (214560 => 214561)
--- trunk/Source/WebCore/ChangeLog 2017-03-29 20:38:54 UTC (rev 214560)
+++ trunk/Source/WebCore/ChangeLog 2017-03-29 20:54:21 UTC (rev 214561)
@@ -1,3 +1,49 @@
+2017-03-29 Chris Dumez <cdu...@apple.com>
+
+ Animated SVG images are not paused in pages loaded in the background
+ https://bugs.webkit.org/show_bug.cgi?id=170043
+ <rdar://problem/31234412>
+
+ Reviewed by Simon Fraser.
+
+ Animated SVG images are not paused in pages loaded in the background. We rely
+ on FrameView::isOffscreen() to stop images animations in background tab (See
+ logic in RenderElement's shouldRepaintForImageAnimation()). This works fine
+ if a tab is visble and then becomes hidden (i.e. by switching to another
+ tab). However, in the case where the tab gets loaded while in the background
+ (e.g. opening link in new background tab, or session restore), then the
+ animations would not be paused, due to FrameView::isOffscreen() erroneously
+ returning false in this case.
+
+ Normally, the following chain of events happens:
+ - Page is visible, we construct a main frame and its FrameView for loading
+ the page. When a FrameView is constructed, we call FrameView::show() to
+ make it visible. Then, if the page becomes non-visible, we call
+ Page::setIsVisibleInternal(false) which calls FrameView::hide(). After
+ that, FrameView::isOffscreen() correctly returns true because we properly
+ called FrameView::hide().
+
+ However, when doing a load while the Page is hidden, the following was
+ happening:
+ - Page is not visible, we call Page::setIsVisibleInternal(false) which tries
+ to call FrameView::hide() for the main frame but it does not have a FrameView
+ yet (because the load has not started). We start the load and end up creating
+ a FrameView. The FrameView constructor was calling FrameView::show()
+ unconditionally, thus making the FrameView think is visible, even though its
+ page isn't. At this point, FrameView::isOffscreen() was returning false
+ and animations would keep running, even though the page is not visible.
+
+ To address the issue, we now call FrameView::show() in FrameView::create() only
+ if the Page is actually visible, instead of calling it unconditionally. If the
+ page ever becomes visible, Page::setIsVisibleInternal(true) will be called and
+ it will take care of calling FrameView::show() then.
+
+ Tests: svg/animations/animations-paused-in-background-page-iframe.html
+ svg/animations/animations-paused-in-background-page.html
+
+ * page/FrameView.cpp:
+ (WebCore::FrameView::create):
+
2017-03-29 Wenson Hsieh <wenson_hs...@apple.com>
Links with empty hrefs should not be drag sources
Modified: trunk/Source/WebCore/page/FrameView.cpp (214560 => 214561)
--- trunk/Source/WebCore/page/FrameView.cpp 2017-03-29 20:38:54 UTC (rev 214560)
+++ trunk/Source/WebCore/page/FrameView.cpp 2017-03-29 20:54:21 UTC (rev 214561)
@@ -296,7 +296,8 @@
Ref<FrameView> FrameView::create(Frame& frame)
{
Ref<FrameView> view = adoptRef(*new FrameView(frame));
- view->show();
+ if (frame.page() && frame.page()->isVisible())
+ view->show();
return view;
}
@@ -304,7 +305,8 @@
{
Ref<FrameView> view = adoptRef(*new FrameView(frame));
view->Widget::setFrameRect(IntRect(view->location(), initialSize));
- view->show();
+ if (frame.page() && frame.page()->isVisible())
+ view->show();
return view;
}