Index: third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp |
diff --git a/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp b/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp |
index 28a3b54094c5904559a0f948fec8beae6e543dcc..47d9a9f2d3d2262fce813c27787f43095ec6436f 100644 |
--- a/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp |
+++ b/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp |
@@ -47,6 +47,7 @@ |
#include "core/svg/graphics/SVGImageChromeClient.h" |
#include "platform/EventDispatchForbiddenScope.h" |
#include "platform/LengthFunctions.h" |
+#include "platform/ScriptForbiddenScope.h" |
#include "platform/TraceEvent.h" |
#include "platform/geometry/IntRect.h" |
#include "platform/graphics/GraphicsContext.h" |
@@ -337,7 +338,8 @@ void SVGImage::draw(SkCanvas* canvas, const SkPaint& paint, const FloatRect& dst |
void SVGImage::drawInternal(SkCanvas* canvas, const SkPaint& paint, const FloatRect& dstRect, const FloatRect& srcRect, |
RespectImageOrientationEnum, ImageClampingMode, const KURL& url) |
{ |
- FrameView* view = frameView(); |
+ DCHECK(m_page); |
+ FrameView* view = toLocalFrame(m_page->mainFrame())->view(); |
view->resize(containerSize()); |
// Always call processUrlFragment, even if the url is empty, because |
@@ -389,21 +391,24 @@ LayoutReplaced* SVGImage::embeddedReplacedContent() const |
return toLayoutSVGRoot(rootElement->layoutObject()); |
} |
-FrameView* SVGImage::frameView() const |
+// FIXME: support CatchUpAnimation = CatchUp. |
+void SVGImage::startAnimation(CatchUpAnimation) |
{ |
- if (!m_page) |
- return nullptr; |
- |
- return toLocalFrame(m_page->mainFrame())->view(); |
+ SVGSVGElement* rootElement = svgRootElement(m_page.get()); |
+ if (!rootElement) |
+ return; |
+ m_chromeClient->resumeAnimation(); |
+ if (rootElement->animationsPaused()) |
+ rootElement->unpauseAnimations(); |
} |
-// FIXME: support CatchUpAnimation = CatchUp. |
-void SVGImage::startAnimation(CatchUpAnimation) |
+void SVGImage::stopAnimation() |
{ |
SVGSVGElement* rootElement = svgRootElement(m_page.get()); |
- if (!rootElement || !rootElement->animationsPaused()) |
+ if (!rootElement) |
return; |
- rootElement->unpauseAnimations(); |
+ m_chromeClient->suspendAnimation(); |
+ rootElement->pauseAnimations(); |
} |
void SVGImage::resetAnimation() |
@@ -411,6 +416,7 @@ void SVGImage::resetAnimation() |
SVGSVGElement* rootElement = svgRootElement(m_page.get()); |
if (!rootElement) |
return; |
+ m_chromeClient->suspendAnimation(); |
rootElement->pauseAnimations(); |
rootElement->setCurrentTime(0); |
} |
@@ -420,7 +426,30 @@ bool SVGImage::hasAnimations() const |
SVGSVGElement* rootElement = svgRootElement(m_page.get()); |
if (!rootElement) |
return false; |
- return rootElement->timeContainer()->hasAnimations() || toLocalFrame(m_page->mainFrame())->document()->timeline().hasPendingUpdates(); |
+ return rootElement->timeContainer()->hasAnimations() |
+ || toLocalFrame(m_page->mainFrame())->document()->timeline().hasPendingUpdates(); |
+} |
+ |
+void SVGImage::serviceAnimations(double monotonicAnimationStartTime) |
+{ |
+ // If none of our observers (sic!) are visible, or for some other reason |
+ // does not want us to keep running animations, stop them until further |
+ // notice (next paint.) |
+ if (getImageObserver()->shouldPauseAnimation(this)) { |
+ stopAnimation(); |
+ return; |
+ } |
+ |
+ // serviceScriptedAnimations runs requestAnimationFrame callbacks, but SVG |
+ // images can't have any so we assert there's no script. |
+ ScriptForbiddenScope forbidScript; |
+ |
+ // The calls below may trigger GCs, so set up the required persistent |
+ // reference on the ImageResource which owns this SVGImage. By transitivity, |
+ // that will keep the associated SVGImageChromeClient object alive. |
+ Persistent<ImageObserver> protect(getImageObserver()); |
+ m_page->animator().serviceScriptedAnimations(monotonicAnimationStartTime); |
+ m_page->animator().updateAllLifecyclePhases(*toLocalFrame(m_page->mainFrame())); |
} |
void SVGImage::advanceAnimationForTesting() |
@@ -432,11 +461,16 @@ void SVGImage::advanceAnimationForTesting() |
// but will not permanently change the animation timeline. |
// TODO(pdr): Actually advance the document timeline so CSS animations |
// can be properly tested. |
- rootElement->document().page()->animator().serviceScriptedAnimations(rootElement->getCurrentTime()); |
+ m_page->animator().serviceScriptedAnimations(rootElement->getCurrentTime()); |
getImageObserver()->animationAdvanced(this); |
} |
} |
+SVGImageChromeClient& SVGImage::chromeClientForTesting() |
+{ |
+ return *m_chromeClient; |
+} |
+ |
void SVGImage::updateUseCounters(Document& document) const |
{ |
if (SVGSVGElement* rootElement = svgRootElement(m_page.get())) { |