Bug 911889. Part 6: A scripted change to element.style.opacity or element.style.transform in a setTimeout or requestAnimationFrame callback should trigger our "style property is animated" heuristic. r=dbaron

--HG--
extra : rebase_source : ac1d4ccfa3c82132ff73aeb1d66a09765004be4a
This commit is contained in:
Robert O'Callahan 2013-09-04 23:47:23 +12:00
parent 8bb77601e1
commit 0b17009152
4 changed files with 62 additions and 5 deletions

View File

@ -7,6 +7,9 @@
#include "nsExpirationTracker.h"
#include "nsIFrame.h"
#include "nsIContent.h"
#include "nsRefreshDriver.h"
#include "nsPIDOMWindow.h"
#include "nsIDocument.h"
namespace mozilla {
@ -132,6 +135,28 @@ ActiveLayerTracker::NotifyAnimated(nsIFrame* aFrame, nsCSSProperty aProperty)
mutationCount = 0xFF;
}
static bool
IsPresContextInScriptAnimationCallback(nsPresContext* aPresContext)
{
if (aPresContext->RefreshDriver()->IsInRefresh()) {
return true;
}
// Treat timeouts/setintervals as scripted animation callbacks for our
// purposes.
nsPIDOMWindow* win = aPresContext->Document()->GetInnerWindow();
return win && win->IsRunningTimeout();
}
/* static */ void
ActiveLayerTracker::NotifyInlineStyleRuleModified(nsIFrame* aFrame,
nsCSSProperty aProperty)
{
if (!IsPresContextInScriptAnimationCallback(aFrame->PresContext())) {
return;
}
NotifyAnimated(aFrame, aProperty);
}
/* static */ bool
ActiveLayerTracker::IsStyleAnimated(nsIFrame* aFrame, nsCSSProperty aProperty)
{

View File

@ -19,6 +19,8 @@ namespace mozilla {
*/
class ActiveLayerTracker {
public:
static void Shutdown();
/*
* We track eCSSProperty_transform and eCSSProperty_opacity style changes
* and use that information to guess whether style changes are animated.
@ -36,23 +38,33 @@ public:
* Any such marking will time out after a short period.
*/
static void NotifyAnimated(nsIFrame* aFrame, nsCSSProperty aProperty);
/**
* Notify that a property in the inline style rule of aFrame's element
* has been modified.
* This notification is incomplete --- not all modifications to inline
* style will trigger this.
*/
static void NotifyInlineStyleRuleModified(nsIFrame* aFrame, nsCSSProperty aProperty);
/**
* Return true if aFrame's aProperty style should be considered as being animated
* for constructing active layers.
*/
static bool IsStyleAnimated(nsIFrame* aFrame, nsCSSProperty aProperty);
/*
* We track modifications to the content of certain frames (i.e. canvas frames)
* and use that to make layering decisions.
*/
/**
* Mark aFrame's content as being active. This marking will time out after
* a short period. This is useful for frames such as canvas frames.
* a short period.
*/
static void NotifyContentChange(nsIFrame* aFrame);
/**
* Return true if this frame's content is still marked as active.
*/
static bool IsContentActive(nsIFrame* aFrame);
static void Shutdown();
};
}

View File

@ -15,9 +15,10 @@
#include "nsIURI.h"
#include "nsNodeUtils.h"
#include "nsWrapperCacheInlines.h"
#include "nsIFrame.h"
#include "ActiveLayerTracker.h"
namespace css = mozilla::css;
namespace dom = mozilla::dom;
using namespace mozilla;
nsDOMCSSAttributeDeclaration::nsDOMCSSAttributeDeclaration(dom::Element* aElement,
bool aIsSMILOverride)
@ -169,3 +170,19 @@ nsDOMCSSAttributeDeclaration::GetParentObject()
{
return mElement;
}
NS_IMETHODIMP
nsDOMCSSAttributeDeclaration::SetPropertyValue(const nsCSSProperty aPropID,
const nsAString& aValue)
{
// Scripted modifications to style.opacity or style.transform
// could immediately force us into the animated state if heuristics suggest
// this is scripted animation.
if (aPropID == eCSSProperty_opacity || aPropID == eCSSProperty_transform) {
nsIFrame* frame = mElement->GetPrimaryFrame();
if (frame) {
ActiveLayerTracker::NotifyInlineStyleRuleModified(frame, aPropID);
}
}
return nsDOMCSSDeclaration::SetPropertyValue(aPropID, aValue);
}

View File

@ -38,6 +38,9 @@ public:
virtual nsINode* GetParentObject() MOZ_OVERRIDE;
NS_IMETHOD SetPropertyValue(const nsCSSProperty aPropID,
const nsAString& aValue);
protected:
virtual nsresult SetCSSDeclaration(mozilla::css::Declaration* aDecl) MOZ_OVERRIDE;
virtual nsIDocument* DocToUpdate() MOZ_OVERRIDE;