Diff
Modified: trunk/LayoutTests/ChangeLog (214321 => 214322)
--- trunk/LayoutTests/ChangeLog 2017-03-23 22:39:57 UTC (rev 214321)
+++ trunk/LayoutTests/ChangeLog 2017-03-23 22:40:50 UTC (rev 214322)
@@ -1 +1,16 @@
+2017-03-23 Chris Dumez <cdu...@apple.com>
+
+ SVG animations are not paused when inserted into a hidden page
+ https://bugs.webkit.org/show_bug.cgi?id=170026
+ <rdar://problem/31228704>
+
+ Reviewed by Andreas Kling.
+
+ Add layout test coverage.
+
+ * svg/animations/animations-paused-when-inserted-in-hidden-document-expected.txt: Added.
+ * svg/animations/animations-paused-when-inserted-in-hidden-document.html: Added.
+ * svg/animations/animations-paused-when-inserted-in-hidden-document2-expected.txt: Added.
+ * svg/animations/animations-paused-when-inserted-in-hidden-document2.html: Added.
+
== Rolled over to ChangeLog-2017-03-23 ==
Added: trunk/LayoutTests/svg/animations/animations-paused-when-inserted-in-hidden-document-expected.txt (0 => 214322)
--- trunk/LayoutTests/svg/animations/animations-paused-when-inserted-in-hidden-document-expected.txt (rev 0)
+++ trunk/LayoutTests/svg/animations/animations-paused-when-inserted-in-hidden-document-expected.txt 2017-03-23 22:40:50 UTC (rev 214322)
@@ -0,0 +1,20 @@
+Tests that SVG animations are properly paused in iframes that are inserted into hidden pages.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Setting page visibility to hidden
+Inserting frame in document
+PASS frame.contentWindow.internals.areSVGAnimationsPaused is true
+PASS frame.contentDocument.getElementsByTagName('svg')[0].animationsPaused() is true
+PASS grandChildFrame.contentWindow.internals.areSVGAnimationsPaused is true
+PASS grandChildFrame.contentDocument.getElementsByTagName('svg')[0].animationsPaused() is true
+Setting page visibility to visible
+PASS frame.contentWindow.internals.areSVGAnimationsPaused is false
+PASS frame.contentDocument.getElementsByTagName('svg')[0].animationsPaused() is false
+PASS grandChildFrame.contentWindow.internals.areSVGAnimationsPaused is false
+PASS grandChildFrame.contentDocument.getElementsByTagName('svg')[0].animationsPaused() is false
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/svg/animations/animations-paused-when-inserted-in-hidden-document.html (0 => 214322)
--- trunk/LayoutTests/svg/animations/animations-paused-when-inserted-in-hidden-document.html (rev 0)
+++ trunk/LayoutTests/svg/animations/animations-paused-when-inserted-in-hidden-document.html 2017-03-23 22:40:50 UTC (rev 214322)
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src=""
+<script>
+description("Tests that SVG animations are properly paused in iframes that are inserted into hidden pages.");
+jsTestIsAsync = true;
+
+document.addEventListener("visibilitychange", function() {
+ if (document.hidden) {
+ frame = document.createElement("iframe");
+ frame._onload_ = function() {
+ setTimeout(function() {
+ shouldBeTrue("frame.contentWindow.internals.areSVGAnimationsPaused");
+ shouldBeTrue("frame.contentDocument.getElementsByTagName('svg')[0].animationsPaused()");
+ grandChildFrame = frame.contentDocument.getElementById('grandChildFrame');
+ shouldBeTrue("grandChildFrame.contentWindow.internals.areSVGAnimationsPaused");
+ shouldBeTrue("grandChildFrame.contentDocument.getElementsByTagName('svg')[0].animationsPaused()");
+
+ debug("Setting page visibility to visible");
+ if (window.testRunner)
+ testRunner.setPageVisibility("visible");
+ }, 0);
+ }
+ frame.src = ""
+ debug("Inserting frame in document");
+ document.body.appendChild(frame);
+ } else {
+ shouldBeFalse("frame.contentWindow.internals.areSVGAnimationsPaused");
+ shouldBeFalse("frame.contentDocument.getElementsByTagName('svg')[0].animationsPaused()");
+ grandChildFrame = frame.contentDocument.getElementById('grandChildFrame');
+ shouldBeFalse("grandChildFrame.contentWindow.internals.areSVGAnimationsPaused");
+ shouldBeFalse("grandChildFrame.contentDocument.getElementsByTagName('svg')[0].animationsPaused()");
+ finishJSTest();
+ }
+});
+
+window._onload_ = function() {
+ debug("Setting page visibility to hidden");
+ if (window.testRunner)
+ testRunner.setPageVisibility("hidden");
+}
+</script>
+<script src=""
+</body>
+</html>
Added: trunk/LayoutTests/svg/animations/animations-paused-when-inserted-in-hidden-document2-expected.txt (0 => 214322)
--- trunk/LayoutTests/svg/animations/animations-paused-when-inserted-in-hidden-document2-expected.txt (rev 0)
+++ trunk/LayoutTests/svg/animations/animations-paused-when-inserted-in-hidden-document2-expected.txt 2017-03-23 22:40:50 UTC (rev 214322)
@@ -0,0 +1,16 @@
+Tests that SVG animations are properly paused in iframes that are inserted into hidden pages.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Setting page visibility to hidden
+Inserting SVG animation in the document
+PASS internals.areSVGAnimationsPaused is true
+PASS svgElement.animationsPaused() is true
+Setting page visibility to visible
+PASS internals.areSVGAnimationsPaused is false
+PASS svgElement.animationsPaused() is false
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/svg/animations/animations-paused-when-inserted-in-hidden-document2.html (0 => 214322)
--- trunk/LayoutTests/svg/animations/animations-paused-when-inserted-in-hidden-document2.html (rev 0)
+++ trunk/LayoutTests/svg/animations/animations-paused-when-inserted-in-hidden-document2.html 2017-03-23 22:40:50 UTC (rev 214322)
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src=""
+<script>
+description("Tests that SVG animations are properly paused in iframes that are inserted into hidden pages.");
+jsTestIsAsync = true;
+
+var animationAsText = '<svg width="300px" height="100px"><rect x="0" y="0" width="300" height="100" stroke="black" stroke-width="1" /><circle cx="0" cy="50" r="15" fill="blue" stroke="black" stroke-width="1"><animate attributeName="cx" from="0" to="100" dur="5s" repeatCount="indefinite" /></circle></svg>';
+
+document.addEventListener("visibilitychange", function() {
+ if (document.hidden) {
+ debug("Inserting SVG animation in the document");
+ testDiv.innerHTML = animationAsText;
+ svgElement = document.getElementsByTagName("svg")[0];
+
+ setTimeout(function() {
+ shouldBeTrue("internals.areSVGAnimationsPaused");
+ shouldBeTrue("svgElement.animationsPaused()");
+
+ debug("Setting page visibility to visible");
+ if (window.testRunner)
+ testRunner.setPageVisibility("visible");
+ }, 0);
+ } else {
+ shouldBeFalse("internals.areSVGAnimationsPaused");
+ shouldBeFalse("svgElement.animationsPaused()");
+ finishJSTest();
+ }
+});
+
+window._onload_ = function() {
+ debug("Setting page visibility to hidden");
+ if (window.testRunner)
+ testRunner.setPageVisibility("hidden");
+}
+</script>
+<div id="testDiv"></div>
+<script src=""
+</body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (214321 => 214322)
--- trunk/Source/WebCore/ChangeLog 2017-03-23 22:39:57 UTC (rev 214321)
+++ trunk/Source/WebCore/ChangeLog 2017-03-23 22:40:50 UTC (rev 214322)
@@ -1 +1,30 @@
+2017-03-23 Chris Dumez <cdu...@apple.com>
+
+ SVG animations are not paused when inserted into a hidden page
+ https://bugs.webkit.org/show_bug.cgi?id=170026
+ <rdar://problem/31228704>
+
+ Reviewed by Andreas Kling.
+
+ SVG animations were not paused when inserted into a hidden page. We would pause
+ animations in a page when the page becomes hidden. However, new animations
+ inserted in the page after this point would start, despite the page being
+ hidden.
+
+ Tests:
+ - svg/animations/animations-paused-when-inserted-in-hidden-document.html
+ - svg/animations/animations-paused-when-inserted-in-hidden-document2.html
+
+ * dom/Document.cpp:
+ (WebCore::Document::accessSVGExtensions):
+ * svg/SVGDocumentExtensions.cpp:
+ (WebCore::SVGDocumentExtensions::SVGDocumentExtensions):
+ (WebCore::SVGDocumentExtensions::addTimeContainer):
+ (WebCore::reportMessage):
+ * svg/SVGDocumentExtensions.h:
+ * testing/Internals.cpp:
+ (WebCore::Internals::areSVGAnimationsPaused):
+ * testing/Internals.h:
+ * testing/Internals.idl:
+
== Rolled over to ChangeLog-2017-03-23 ==
Modified: trunk/Source/WebCore/dom/Document.cpp (214321 => 214322)
--- trunk/Source/WebCore/dom/Document.cpp 2017-03-23 22:39:57 UTC (rev 214321)
+++ trunk/Source/WebCore/dom/Document.cpp 2017-03-23 22:40:50 UTC (rev 214322)
@@ -4873,7 +4873,7 @@
SVGDocumentExtensions& Document::accessSVGExtensions()
{
if (!m_svgExtensions)
- m_svgExtensions = std::make_unique<SVGDocumentExtensions>(this);
+ m_svgExtensions = std::make_unique<SVGDocumentExtensions>(*this);
return *m_svgExtensions;
}
Modified: trunk/Source/WebCore/svg/SVGDocumentExtensions.cpp (214321 => 214322)
--- trunk/Source/WebCore/svg/SVGDocumentExtensions.cpp 2017-03-23 22:39:57 UTC (rev 214321)
+++ trunk/Source/WebCore/svg/SVGDocumentExtensions.cpp 2017-03-23 22:40:50 UTC (rev 214322)
@@ -27,6 +27,7 @@
#include "EventListener.h"
#include "Frame.h"
#include "FrameLoader.h"
+#include "Page.h"
#include "SMILTimeContainer.h"
#include "SVGElement.h"
#include "SVGResourcesCache.h"
@@ -39,9 +40,10 @@
namespace WebCore {
-SVGDocumentExtensions::SVGDocumentExtensions(Document* document)
+SVGDocumentExtensions::SVGDocumentExtensions(Document& document)
: m_document(document)
, m_resourcesCache(std::make_unique<SVGResourcesCache>())
+ , m_areAnimationsPaused(!document.page() || !document.page()->isVisible())
{
}
@@ -52,6 +54,8 @@
void SVGDocumentExtensions::addTimeContainer(SVGSVGElement* element)
{
m_timeContainers.add(element);
+ if (m_areAnimationsPaused)
+ element->pauseAnimations();
}
void SVGDocumentExtensions::removeTimeContainer(SVGSVGElement* element)
@@ -124,10 +128,10 @@
}
}
-static void reportMessage(Document* document, MessageLevel level, const String& message)
+static void reportMessage(Document& document, MessageLevel level, const String& message)
{
- if (document->frame())
- document->addConsoleMessage(MessageSource::Rendering, level, message);
+ if (document.frame())
+ document.addConsoleMessage(MessageSource::Rendering, level, message);
}
void SVGDocumentExtensions::reportWarning(const String& message)
Modified: trunk/Source/WebCore/svg/SVGDocumentExtensions.h (214321 => 214322)
--- trunk/Source/WebCore/svg/SVGDocumentExtensions.h 2017-03-23 22:39:57 UTC (rev 214321)
+++ trunk/Source/WebCore/svg/SVGDocumentExtensions.h 2017-03-23 22:40:50 UTC (rev 214322)
@@ -40,7 +40,7 @@
WTF_MAKE_NONCOPYABLE(SVGDocumentExtensions); WTF_MAKE_FAST_ALLOCATED;
public:
typedef HashSet<Element*> PendingElements;
- explicit SVGDocumentExtensions(Document*);
+ explicit SVGDocumentExtensions(Document&);
~SVGDocumentExtensions();
void addTimeContainer(SVGSVGElement*);
@@ -77,7 +77,7 @@
#endif
private:
- Document* m_document; // weak reference
+ Document& m_document;
HashSet<SVGSVGElement*> m_timeContainers; // For SVG 1.2 support this will need to be made more general.
#if ENABLE(SVG_FONTS)
HashSet<SVGFontFaceElement*> m_svgFontFaceElements;
@@ -89,7 +89,7 @@
std::unique_ptr<SVGResourcesCache> m_resourcesCache;
Vector<SVGElement*> m_rebuildElements;
- bool m_areAnimationsPaused { false }; // For testing.
+ bool m_areAnimationsPaused;
public:
// This HashMap contains a list of pending resources. Pending resources, are such
Modified: trunk/Source/WebCore/testing/Internals.cpp (214321 => 214322)
--- trunk/Source/WebCore/testing/Internals.cpp 2017-03-23 22:39:57 UTC (rev 214321)
+++ trunk/Source/WebCore/testing/Internals.cpp 2017-03-23 22:40:50 UTC (rev 214322)
@@ -517,14 +517,14 @@
return WorkerThread::workerThreadCount();
}
-bool Internals::areSVGAnimationsPaused() const
+ExceptionOr<bool> Internals::areSVGAnimationsPaused() const
{
auto* document = contextDocument();
if (!document)
- return false;
+ return Exception { INVALID_ACCESS_ERR, ASCIILiteral("No context document") };
if (!document->svgExtensions())
- return false;
+ return Exception { NOT_FOUND_ERR, ASCIILiteral("No SVG animations") };
return document->accessSVGExtensions().areAnimationsPaused();
}
Modified: trunk/Source/WebCore/testing/Internals.h (214321 => 214322)
--- trunk/Source/WebCore/testing/Internals.h 2017-03-23 22:39:57 UTC (rev 214321)
+++ trunk/Source/WebCore/testing/Internals.h 2017-03-23 22:40:50 UTC (rev 214322)
@@ -266,7 +266,7 @@
InternalSettings* settings() const;
unsigned workerThreadCount() const;
- bool areSVGAnimationsPaused() const;
+ ExceptionOr<bool> areSVGAnimationsPaused() const;
ExceptionOr<double> svgAnimationsInterval(SVGSVGElement&) const;
ExceptionOr<void> setDeviceProximity(const String& eventType, double value, double min, double max);
Modified: trunk/Source/WebCore/testing/Internals.idl (214321 => 214322)
--- trunk/Source/WebCore/testing/Internals.idl 2017-03-23 22:39:57 UTC (rev 214321)
+++ trunk/Source/WebCore/testing/Internals.idl 2017-03-23 22:40:50 UTC (rev 214322)
@@ -249,7 +249,7 @@
readonly attribute InternalSettings settings;
readonly attribute unsigned long workerThreadCount;
- readonly attribute boolean areSVGAnimationsPaused;
+ [MayThrowException] readonly attribute boolean areSVGAnimationsPaused;
[MayThrowException] double svgAnimationsInterval(SVGSVGElement element);
// Flags for layerTreeAsText.