Bug 1062832 - Remove frame handling from nsSVGIDRenderingObserver and put it into nsSVGRenderingObserverProperty. r=roc

This commit is contained in:
Markus Stange 2014-09-09 17:14:45 +02:00
Родитель f0ce0d3170
Коммит 5ca816d536
2 изменённых файлов: 106 добавлений и 47 удалений

Просмотреть файл

@ -177,14 +177,13 @@ nsSVGRenderingObserver::ContentRemoved(nsIDocument *aDocument,
* benefits/necessity of maintaining a second observer list.
*/
nsSVGIDRenderingObserver::nsSVGIDRenderingObserver(nsIURI *aURI,
nsIFrame *aFrame,
nsSVGIDRenderingObserver::nsSVGIDRenderingObserver(nsIURI* aURI,
nsIContent* aObservingContent,
bool aReferenceImage)
: mElement(MOZ_THIS_IN_INITIALIZER_LIST()), mFrame(aFrame),
mFramePresShell(aFrame->PresContext()->PresShell())
: mElement(MOZ_THIS_IN_INITIALIZER_LIST())
{
// Start watching the target element
mElement.Reset(aFrame->GetContent(), aURI, true, aReferenceImage);
mElement.Reset(aObservingContent, aURI, true, aReferenceImage);
StartListening();
}
@ -196,19 +195,39 @@ nsSVGIDRenderingObserver::~nsSVGIDRenderingObserver()
void
nsSVGIDRenderingObserver::DoUpdate()
{
if (mFramePresShell->IsDestroying()) {
// mFrame is no longer valid. Bail out.
mFrame = nullptr;
return;
}
if (mElement.get() && mInObserverList) {
nsSVGEffects::RemoveRenderingObserver(mElement.get(), this);
mInObserverList = false;
}
if (mFrame && mFrame->IsFrameOfType(nsIFrame::eSVG)) {
}
void
nsSVGFrameReferenceFromProperty::Detach()
{
mFrame = nullptr;
mFramePresShell = nullptr;
}
nsIFrame*
nsSVGFrameReferenceFromProperty::Get()
{
if (mFramePresShell && mFramePresShell->IsDestroying()) {
// mFrame is no longer valid.
Detach();
}
return mFrame;
}
void
nsSVGRenderingObserverProperty::DoUpdate()
{
nsSVGIDRenderingObserver::DoUpdate();
nsIFrame* frame = mFrameReference.Get();
if (frame && frame->IsFrameOfType(nsIFrame::eSVG)) {
// Changes should propagate out to things that might be observing
// the referencing frame or its ancestors.
nsSVGEffects::InvalidateRenderingObservers(mFrame);
nsSVGEffects::InvalidateRenderingObservers(frame);
}
}
@ -226,8 +245,10 @@ nsSVGFilterReference::GetFilterFrame()
void
nsSVGFilterReference::DoUpdate()
{
nsSVGIDRenderingObserver::DoUpdate();
if (!mFrame)
nsSVGRenderingObserverProperty::DoUpdate();
nsIFrame* frame = mFrameReference.Get();
if (!frame)
return;
// Repaint asynchronously in case the filter frame is being torn down
@ -235,11 +256,11 @@ nsSVGFilterReference::DoUpdate()
nsChangeHint(nsChangeHint_RepaintFrame);
// Don't need to request UpdateOverflow if we're being reflowed.
if (!(mFrame->GetStateBits() & NS_FRAME_IN_REFLOW)) {
if (!(frame->GetStateBits() & NS_FRAME_IN_REFLOW)) {
NS_UpdateHint(changeHint, nsChangeHint_UpdateOverflow);
}
mFramePresShell->GetPresContext()->RestyleManager()->PostRestyleEvent(
mFrame->GetContent()->AsElement(), nsRestyleHint(0), changeHint);
frame->PresContext()->RestyleManager()->PostRestyleEvent(
frame->GetContent()->AsElement(), nsRestyleHint(0), changeHint);
}
NS_IMPL_ISUPPORTS(nsSVGFilterProperty, nsISupports)
@ -288,26 +309,28 @@ nsSVGFilterProperty::Invalidate()
void
nsSVGMarkerProperty::DoUpdate()
{
nsSVGIDRenderingObserver::DoUpdate();
if (!mFrame)
nsSVGRenderingObserverProperty::DoUpdate();
nsIFrame* frame = mFrameReference.Get();
if (!frame)
return;
NS_ASSERTION(mFrame->IsFrameOfType(nsIFrame::eSVG), "SVG frame expected");
NS_ASSERTION(frame->IsFrameOfType(nsIFrame::eSVG), "SVG frame expected");
// Repaint asynchronously in case the marker frame is being torn down
nsChangeHint changeHint =
nsChangeHint(nsChangeHint_RepaintFrame);
// Don't need to request ReflowFrame if we're being reflowed.
if (!(mFrame->GetStateBits() & NS_FRAME_IN_REFLOW)) {
if (!(frame->GetStateBits() & NS_FRAME_IN_REFLOW)) {
// XXXjwatt: We need to unify SVG into standard reflow so we can just use
// nsChangeHint_NeedReflow | nsChangeHint_NeedDirtyReflow here.
nsSVGEffects::InvalidateRenderingObservers(mFrame);
nsSVGEffects::InvalidateRenderingObservers(frame);
// XXXSDL KILL THIS!!!
nsSVGUtils::ScheduleReflowSVG(mFrame);
nsSVGUtils::ScheduleReflowSVG(frame);
}
mFramePresShell->GetPresContext()->RestyleManager()->PostRestyleEvent(
mFrame->GetContent()->AsElement(), nsRestyleHint(0), changeHint);
frame->PresContext()->RestyleManager()->PostRestyleEvent(
frame->GetContent()->AsElement(), nsRestyleHint(0), changeHint);
}
bool
@ -320,11 +343,13 @@ nsSVGTextPathProperty::TargetIsValid()
void
nsSVGTextPathProperty::DoUpdate()
{
nsSVGIDRenderingObserver::DoUpdate();
if (!mFrame)
nsSVGRenderingObserverProperty::DoUpdate();
nsIFrame* frame = mFrameReference.Get();
if (!frame)
return;
NS_ASSERTION(mFrame->IsFrameOfType(nsIFrame::eSVG) || mFrame->IsSVGText(),
NS_ASSERTION(frame->IsFrameOfType(nsIFrame::eSVG) || frame->IsSVGText(),
"SVG frame expected");
// Avoid getting into an infinite loop of reflows if the <textPath> is
@ -347,8 +372,8 @@ nsSVGTextPathProperty::DoUpdate()
// Repaint asynchronously in case the path frame is being torn down
nsChangeHint changeHint =
nsChangeHint(nsChangeHint_RepaintFrame | nsChangeHint_UpdateTextPath);
mFramePresShell->GetPresContext()->RestyleManager()->PostRestyleEvent(
mFrame->GetContent()->AsElement(), nsRestyleHint(0), changeHint);
frame->PresContext()->RestyleManager()->PostRestyleEvent(
frame->GetContent()->AsElement(), nsRestyleHint(0), changeHint);
}
static void
@ -363,15 +388,17 @@ InvalidateAllContinuations(nsIFrame* aFrame)
void
nsSVGPaintingProperty::DoUpdate()
{
nsSVGIDRenderingObserver::DoUpdate();
if (!mFrame)
nsSVGRenderingObserverProperty::DoUpdate();
nsIFrame* frame = mFrameReference.Get();
if (!frame)
return;
if (mFrame->GetStateBits() & NS_FRAME_SVG_LAYOUT) {
nsSVGEffects::InvalidateRenderingObservers(mFrame);
mFrame->InvalidateFrameSubtree();
if (frame->GetStateBits() & NS_FRAME_SVG_LAYOUT) {
nsSVGEffects::InvalidateRenderingObservers(frame);
frame->InvalidateFrameSubtree();
} else {
InvalidateAllContinuations(mFrame);
InvalidateAllContinuations(frame);
}
}

Просмотреть файл

@ -112,7 +112,7 @@ protected:
class nsSVGIDRenderingObserver : public nsSVGRenderingObserver {
public:
typedef mozilla::dom::Element Element;
nsSVGIDRenderingObserver(nsIURI* aURI, nsIFrame *aFrame,
nsSVGIDRenderingObserver(nsIURI* aURI, nsIContent* aObservingContent,
bool aReferenceImage);
virtual ~nsSVGIDRenderingObserver();
@ -142,16 +142,48 @@ protected:
};
SourceReference mElement;
// The frame that this property is attached to
};
struct nsSVGFrameReferenceFromProperty
{
nsSVGFrameReferenceFromProperty(nsIFrame* aFrame)
: mFrame(aFrame)
, mFramePresShell(aFrame->PresContext()->PresShell())
{}
// Clear our reference to the frame.
void Detach();
// null if the frame has become invalid
nsIFrame* Get();
private:
// The frame that this property is attached to, may be null
nsIFrame *mFrame;
// When a presshell is torn down, we don't delete the properties for
// each frame until after the frames are destroyed. So here we remember
// the presshell for the frames we care about and, before we use the frame,
// we test the presshell to see if it's destroying itself. If it is,
// then the frame pointer is not valid and we know the frame has gone away.
// mFramePresShell may be null, but when mFrame is non-null, mFramePresShell
// is guaranteed to be non-null, too.
nsIPresShell *mFramePresShell;
};
class nsSVGRenderingObserverProperty : public nsSVGIDRenderingObserver {
public:
nsSVGRenderingObserverProperty(nsIURI* aURI, nsIFrame *aFrame,
bool aReferenceImage)
: nsSVGIDRenderingObserver(aURI, aFrame->GetContent(), aReferenceImage)
, mFrameReference(aFrame)
{}
protected:
virtual void DoUpdate() MOZ_OVERRIDE;
nsSVGFrameReferenceFromProperty mFrameReference;
};
/**
* In a filter chain, there can be multiple SVG reference filters.
* e.g. filter: url(#svg-filter-1) blur(10px) url(#svg-filter-2);
@ -165,10 +197,10 @@ protected:
* The nsSVGFilterProperty class manages a list of nsSVGFilterReferences.
*/
class nsSVGFilterReference MOZ_FINAL :
public nsSVGIDRenderingObserver, public nsISVGFilterReference {
public nsSVGRenderingObserverProperty, public nsISVGFilterReference {
public:
nsSVGFilterReference(nsIURI *aURI, nsIFrame *aFilteredFrame)
: nsSVGIDRenderingObserver(aURI, aFilteredFrame, false) {}
: nsSVGRenderingObserverProperty(aURI, aFilteredFrame, false) {}
bool ReferencesValidResource() { return GetFilterFrame(); }
@ -187,7 +219,7 @@ protected:
virtual ~nsSVGFilterReference() {}
private:
// nsSVGIDRenderingObserver
// nsSVGRenderingObserverProperty
virtual void DoUpdate() MOZ_OVERRIDE;
};
@ -220,19 +252,19 @@ private:
nsTArray<nsRefPtr<nsSVGFilterReference>> mReferences;
};
class nsSVGMarkerProperty : public nsSVGIDRenderingObserver {
class nsSVGMarkerProperty : public nsSVGRenderingObserverProperty {
public:
nsSVGMarkerProperty(nsIURI *aURI, nsIFrame *aFrame, bool aReferenceImage)
: nsSVGIDRenderingObserver(aURI, aFrame, aReferenceImage) {}
: nsSVGRenderingObserverProperty(aURI, aFrame, aReferenceImage) {}
protected:
virtual void DoUpdate() MOZ_OVERRIDE;
};
class nsSVGTextPathProperty : public nsSVGIDRenderingObserver {
class nsSVGTextPathProperty : public nsSVGRenderingObserverProperty {
public:
nsSVGTextPathProperty(nsIURI *aURI, nsIFrame *aFrame, bool aReferenceImage)
: nsSVGIDRenderingObserver(aURI, aFrame, aReferenceImage)
: nsSVGRenderingObserverProperty(aURI, aFrame, aReferenceImage)
, mValid(true) {}
virtual bool ObservesReflow() MOZ_OVERRIDE { return false; }
@ -249,10 +281,10 @@ private:
bool mValid;
};
class nsSVGPaintingProperty : public nsSVGIDRenderingObserver {
class nsSVGPaintingProperty : public nsSVGRenderingObserverProperty {
public:
nsSVGPaintingProperty(nsIURI *aURI, nsIFrame *aFrame, bool aReferenceImage)
: nsSVGIDRenderingObserver(aURI, aFrame, aReferenceImage) {}
: nsSVGRenderingObserverProperty(aURI, aFrame, aReferenceImage) {}
protected:
virtual void DoUpdate() MOZ_OVERRIDE;