mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-22 09:45:41 +00:00
![Nicholas Nethercote](/assets/img/avatar_default.png)
(Path is actually r=froydnj.) Bug 1400459 devirtualized nsIAtom so that it is no longer a subclass of nsISupports. This means that nsAtom is now a better name for it than nsIAtom. MozReview-Commit-ID: 91U22X2NydP --HG-- rename : xpcom/ds/nsIAtom.h => xpcom/ds/nsAtom.h extra : rebase_source : ac3e904a21b8b48e74534fff964f1623ee937c67
718 lines
22 KiB
C++
718 lines
22 KiB
C++
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#ifndef NSSVGEFFECTS_H_
|
|
#define NSSVGEFFECTS_H_
|
|
|
|
#include "mozilla/Attributes.h"
|
|
#include "mozilla/dom/IDTracker.h"
|
|
#include "FrameProperties.h"
|
|
#include "mozilla/dom/Element.h"
|
|
#include "nsHashKeys.h"
|
|
#include "nsID.h"
|
|
#include "nsIFrame.h"
|
|
#include "nsIMutationObserver.h"
|
|
#include "nsInterfaceHashtable.h"
|
|
#include "nsISupportsBase.h"
|
|
#include "nsISupportsImpl.h"
|
|
#include "nsStubMutationObserver.h"
|
|
#include "nsSVGUtils.h"
|
|
#include "nsTHashtable.h"
|
|
#include "nsURIHashKey.h"
|
|
#include "nsCycleCollectionParticipant.h"
|
|
|
|
class nsAtom;
|
|
class nsIPresShell;
|
|
class nsIURI;
|
|
class nsSVGClipPathFrame;
|
|
class nsSVGPaintServerFrame;
|
|
class nsSVGFilterFrame;
|
|
class nsSVGMaskFrame;
|
|
class nsSVGFilterChainObserver;
|
|
|
|
/*
|
|
* This interface allows us to be notified when a piece of SVG content is
|
|
* re-rendered.
|
|
*
|
|
* Concrete implementations of this interface need to implement
|
|
* "GetTarget()" to specify the piece of SVG content that they'd like to
|
|
* monitor, and they need to implement "OnRenderingChange" to specify how
|
|
* we'll react when that content gets re-rendered. They also need to implement
|
|
* a constructor and destructor, which should call StartObserving and
|
|
* StopObserving, respectively.
|
|
*/
|
|
class nsSVGRenderingObserver : public nsStubMutationObserver
|
|
{
|
|
|
|
protected:
|
|
virtual ~nsSVGRenderingObserver()
|
|
{}
|
|
|
|
public:
|
|
typedef mozilla::dom::Element Element;
|
|
nsSVGRenderingObserver()
|
|
: mInObserverList(false)
|
|
{}
|
|
|
|
// nsIMutationObserver
|
|
NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
|
|
NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
|
|
NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
|
|
NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
|
|
|
|
/**
|
|
* Called when non-DOM-mutation changes to the observed element should likely
|
|
* cause the rendering of our observer to change. This includes changes to
|
|
* CSS computed values, but also changes to rendering observers that the
|
|
* observed element itself may have (for example, when we're being used to
|
|
* observe an SVG pattern, and an element in that pattern references and
|
|
* observes a gradient that has changed).
|
|
*/
|
|
void OnNonDOMMutationRenderingChange();
|
|
|
|
// When a nsSVGRenderingObserver list gets forcibly cleared, it uses this
|
|
// callback to notify every observer that's cleared from it, so they can
|
|
// react.
|
|
void NotifyEvictedFromRenderingObserverList();
|
|
|
|
bool IsInObserverList() const { return mInObserverList; }
|
|
|
|
nsIFrame* GetReferencedFrame();
|
|
/**
|
|
* @param aOK this is only for the convenience of callers. We set *aOK to false
|
|
* if the frame is the wrong type
|
|
*/
|
|
nsIFrame* GetReferencedFrame(mozilla::LayoutFrameType aFrameType, bool* aOK);
|
|
|
|
Element* GetReferencedElement();
|
|
|
|
virtual bool ObservesReflow() { return true; }
|
|
|
|
protected:
|
|
void StartObserving();
|
|
void StopObserving();
|
|
|
|
/**
|
|
* Called whenever the rendering of the observed element may have changed.
|
|
*
|
|
* More specifically, this method is called whenever DOM mutation occurs in
|
|
* the observed element's subtree, or whenever
|
|
* SVGObserverUtils::InvalidateRenderingObservers or
|
|
* SVGObserverUtils::InvalidateDirectRenderingObservers is called for the
|
|
* observed element's frame.
|
|
*
|
|
* Subclasses should override this method to handle rendering changes
|
|
* appropriately.
|
|
*/
|
|
virtual void OnRenderingChange() = 0;
|
|
|
|
// This is an internally-used version of GetReferencedElement that doesn't
|
|
// forcibly add us as an observer. (whereas GetReferencedElement does)
|
|
virtual Element* GetTarget() = 0;
|
|
|
|
// Whether we're in our referenced element's observer list at this time.
|
|
bool mInObserverList;
|
|
};
|
|
|
|
|
|
/*
|
|
* SVG elements reference supporting resources by element ID. We need to
|
|
* track when those resources change and when the DOM changes in ways
|
|
* that affect which element is referenced by a given ID (e.g., when
|
|
* element IDs change). The code here is responsible for that.
|
|
*
|
|
* When a frame references a supporting resource, we create a property
|
|
* object derived from nsSVGIDRenderingObserver to manage the relationship. The
|
|
* property object is attached to the referencing frame.
|
|
*/
|
|
class nsSVGIDRenderingObserver : public nsSVGRenderingObserver
|
|
{
|
|
public:
|
|
typedef mozilla::dom::Element Element;
|
|
typedef mozilla::dom::IDTracker IDTracker;
|
|
|
|
nsSVGIDRenderingObserver(nsIURI* aURI, nsIContent* aObservingContent,
|
|
bool aReferenceImage);
|
|
virtual ~nsSVGIDRenderingObserver();
|
|
|
|
protected:
|
|
Element* GetTarget() override { return mObservedElementTracker.get(); }
|
|
|
|
void OnRenderingChange() override;
|
|
|
|
/**
|
|
* Helper that provides a reference to the element with the ID that our
|
|
* observer wants to observe, and that will invalidate our observer if the
|
|
* element that that ID identifies changes to a different element (or none).
|
|
*/
|
|
class ElementTracker final : public IDTracker
|
|
{
|
|
public:
|
|
explicit ElementTracker(nsSVGIDRenderingObserver* aOwningObserver)
|
|
: mOwningObserver(aOwningObserver)
|
|
{}
|
|
protected:
|
|
virtual void ElementChanged(Element* aFrom, Element* aTo) override {
|
|
mOwningObserver->StopObserving(); // stop observing the old element
|
|
IDTracker::ElementChanged(aFrom, aTo);
|
|
mOwningObserver->StartObserving(); // start observing the new element
|
|
mOwningObserver->OnRenderingChange();
|
|
}
|
|
/**
|
|
* Override IsPersistent because we want to keep tracking the element
|
|
* for the ID even when it changes.
|
|
*/
|
|
virtual bool IsPersistent() override { return true; }
|
|
private:
|
|
nsSVGIDRenderingObserver* mOwningObserver;
|
|
};
|
|
|
|
ElementTracker mObservedElementTracker;
|
|
};
|
|
|
|
struct nsSVGFrameReferenceFromProperty
|
|
{
|
|
explicit 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:
|
|
NS_DECL_ISUPPORTS
|
|
|
|
nsSVGRenderingObserverProperty(nsIURI* aURI, nsIFrame *aFrame,
|
|
bool aReferenceImage)
|
|
: nsSVGIDRenderingObserver(aURI, aFrame->GetContent(), aReferenceImage)
|
|
, mFrameReference(aFrame)
|
|
{}
|
|
|
|
protected:
|
|
virtual ~nsSVGRenderingObserverProperty() {}
|
|
|
|
virtual void OnRenderingChange() 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);
|
|
*
|
|
* This class keeps track of one SVG reference filter in a filter chain.
|
|
* e.g. url(#svg-filter-1)
|
|
*
|
|
* It fires invalidations when the SVG filter element's id changes or when
|
|
* the SVG filter element's content changes.
|
|
*
|
|
* The nsSVGFilterChainObserver class manages a list of nsSVGFilterReferences.
|
|
*/
|
|
class nsSVGFilterReference final : public nsSVGIDRenderingObserver
|
|
, public nsISVGFilterReference
|
|
{
|
|
public:
|
|
nsSVGFilterReference(nsIURI* aURI,
|
|
nsIContent* aObservingContent,
|
|
nsSVGFilterChainObserver* aFilterChainObserver)
|
|
: nsSVGIDRenderingObserver(aURI, aObservingContent, false)
|
|
, mFilterChainObserver(aFilterChainObserver)
|
|
{
|
|
}
|
|
|
|
bool ReferencesValidResource() { return GetFilterFrame(); }
|
|
|
|
void DetachFromChainObserver() { mFilterChainObserver = nullptr; }
|
|
|
|
/**
|
|
* @return the filter frame, or null if there is no filter frame
|
|
*/
|
|
nsSVGFilterFrame *GetFilterFrame();
|
|
|
|
// nsISupports
|
|
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
|
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsSVGFilterReference, nsSVGIDRenderingObserver)
|
|
|
|
// nsISVGFilterReference
|
|
virtual void Invalidate() override { OnRenderingChange(); };
|
|
|
|
protected:
|
|
virtual ~nsSVGFilterReference() {}
|
|
|
|
// nsSVGIDRenderingObserver
|
|
virtual void OnRenderingChange() override;
|
|
|
|
private:
|
|
nsSVGFilterChainObserver* mFilterChainObserver;
|
|
};
|
|
|
|
/**
|
|
* This class manages a list of nsSVGFilterReferences, which represent SVG
|
|
* reference filters in a filter chain.
|
|
* e.g. filter: url(#svg-filter-1) blur(10px) url(#svg-filter-2);
|
|
*
|
|
* In the above example, the nsSVGFilterChainObserver will manage two
|
|
* nsSVGFilterReferences, one for each SVG reference filter. CSS filters like
|
|
* "blur(10px)" don't reference filter elements, so they don't need an
|
|
* nsSVGFilterReference. The style system invalidates changes to CSS filters.
|
|
*/
|
|
class nsSVGFilterChainObserver : public nsISupports
|
|
{
|
|
public:
|
|
nsSVGFilterChainObserver(const nsTArray<nsStyleFilter>& aFilters,
|
|
nsIContent* aFilteredElement,
|
|
nsIFrame* aFiltedFrame = nullptr);
|
|
|
|
bool ReferencesValidResources();
|
|
bool IsInObserverLists() const;
|
|
void Invalidate() { OnRenderingChange(); }
|
|
|
|
// nsISupports
|
|
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
|
NS_DECL_CYCLE_COLLECTION_CLASS(nsSVGFilterChainObserver)
|
|
|
|
protected:
|
|
virtual ~nsSVGFilterChainObserver();
|
|
|
|
virtual void OnRenderingChange() = 0;
|
|
|
|
private:
|
|
|
|
void DetachReferences()
|
|
{
|
|
for (uint32_t i = 0; i < mReferences.Length(); i++) {
|
|
mReferences[i]->DetachFromChainObserver();
|
|
}
|
|
}
|
|
|
|
nsTArray<RefPtr<nsSVGFilterReference>> mReferences;
|
|
};
|
|
|
|
class nsSVGFilterProperty : public nsSVGFilterChainObserver
|
|
{
|
|
public:
|
|
nsSVGFilterProperty(const nsTArray<nsStyleFilter>& aFilters,
|
|
nsIFrame* aFilteredFrame)
|
|
: nsSVGFilterChainObserver(aFilters, aFilteredFrame->GetContent(),
|
|
aFilteredFrame)
|
|
, mFrameReference(aFilteredFrame)
|
|
{}
|
|
|
|
void DetachFromFrame() { mFrameReference.Detach(); }
|
|
|
|
protected:
|
|
virtual void OnRenderingChange() override;
|
|
|
|
nsSVGFrameReferenceFromProperty mFrameReference;
|
|
};
|
|
|
|
class nsSVGMarkerProperty final: public nsSVGRenderingObserverProperty
|
|
{
|
|
public:
|
|
nsSVGMarkerProperty(nsIURI* aURI, nsIFrame* aFrame, bool aReferenceImage)
|
|
: nsSVGRenderingObserverProperty(aURI, aFrame, aReferenceImage) {}
|
|
|
|
protected:
|
|
virtual void OnRenderingChange() override;
|
|
};
|
|
|
|
class nsSVGTextPathProperty final : public nsSVGRenderingObserverProperty
|
|
{
|
|
public:
|
|
nsSVGTextPathProperty(nsIURI* aURI, nsIFrame* aFrame, bool aReferenceImage)
|
|
: nsSVGRenderingObserverProperty(aURI, aFrame, aReferenceImage)
|
|
, mValid(true) {}
|
|
|
|
virtual bool ObservesReflow() override { return false; }
|
|
|
|
protected:
|
|
virtual void OnRenderingChange() override;
|
|
|
|
private:
|
|
/**
|
|
* Returns true if the target of the textPath is the frame of a 'path' element.
|
|
*/
|
|
bool TargetIsValid();
|
|
|
|
bool mValid;
|
|
};
|
|
|
|
class nsSVGPaintingProperty final : public nsSVGRenderingObserverProperty
|
|
{
|
|
public:
|
|
nsSVGPaintingProperty(nsIURI* aURI, nsIFrame* aFrame, bool aReferenceImage)
|
|
: nsSVGRenderingObserverProperty(aURI, aFrame, aReferenceImage) {}
|
|
|
|
protected:
|
|
virtual void OnRenderingChange() override;
|
|
};
|
|
|
|
class nsSVGMaskProperty final : public nsISupports
|
|
{
|
|
public:
|
|
explicit nsSVGMaskProperty(nsIFrame* aFrame);
|
|
|
|
// nsISupports
|
|
NS_DECL_ISUPPORTS
|
|
|
|
const nsTArray<RefPtr<nsSVGPaintingProperty>>& GetProps() const
|
|
{
|
|
return mProperties;
|
|
}
|
|
|
|
void ResolveImage(uint32_t aIndex);
|
|
|
|
private:
|
|
virtual ~nsSVGMaskProperty() {}
|
|
nsTArray<RefPtr<nsSVGPaintingProperty>> mProperties;
|
|
nsIFrame* mFrame;
|
|
};
|
|
|
|
/**
|
|
* A manager for one-shot nsSVGRenderingObserver tracking.
|
|
* nsSVGRenderingObservers can be added or removed. They are not strongly
|
|
* referenced so an observer must be removed before it dies.
|
|
* When InvalidateAll is called, all outstanding references get
|
|
* OnNonDOMMutationRenderingChange()
|
|
* called on them and the list is cleared. The intent is that
|
|
* the observer will force repainting of whatever part of the document
|
|
* is needed, and then at paint time the observer will do a clean lookup
|
|
* of the referenced element and [re-]add itself to the element's observer list.
|
|
*
|
|
* InvalidateAll must be called before this object is destroyed, i.e.
|
|
* before the referenced frame is destroyed. This should normally happen
|
|
* via nsSVGContainerFrame::RemoveFrame, since only frames in the frame
|
|
* tree should be referenced.
|
|
*/
|
|
class nsSVGRenderingObserverList
|
|
{
|
|
public:
|
|
nsSVGRenderingObserverList()
|
|
: mObservers(4)
|
|
{
|
|
MOZ_COUNT_CTOR(nsSVGRenderingObserverList);
|
|
}
|
|
|
|
~nsSVGRenderingObserverList() {
|
|
InvalidateAll();
|
|
MOZ_COUNT_DTOR(nsSVGRenderingObserverList);
|
|
}
|
|
|
|
void Add(nsSVGRenderingObserver* aObserver)
|
|
{ mObservers.PutEntry(aObserver); }
|
|
void Remove(nsSVGRenderingObserver* aObserver)
|
|
{ mObservers.RemoveEntry(aObserver); }
|
|
#ifdef DEBUG
|
|
bool Contains(nsSVGRenderingObserver* aObserver)
|
|
{ return (mObservers.GetEntry(aObserver) != nullptr); }
|
|
#endif
|
|
bool IsEmpty()
|
|
{ return mObservers.Count() == 0; }
|
|
|
|
/**
|
|
* Drop all our observers, and notify them that we have changed and dropped
|
|
* our reference to them.
|
|
*/
|
|
void InvalidateAll();
|
|
|
|
/**
|
|
* Drop all observers that observe reflow, and notify them that we have changed and dropped
|
|
* our reference to them.
|
|
*/
|
|
void InvalidateAllForReflow();
|
|
|
|
/**
|
|
* Drop all our observers, and notify them that we have dropped our reference
|
|
* to them.
|
|
*/
|
|
void RemoveAll();
|
|
|
|
private:
|
|
nsTHashtable<nsPtrHashKey<nsSVGRenderingObserver> > mObservers;
|
|
};
|
|
|
|
class SVGObserverUtils
|
|
{
|
|
public:
|
|
typedef mozilla::dom::Element Element;
|
|
typedef nsInterfaceHashtable<nsURIHashKey, nsIMutationObserver>
|
|
URIObserverHashtable;
|
|
|
|
using PaintingPropertyDescriptor =
|
|
const mozilla::FramePropertyDescriptor<nsSVGPaintingProperty>*;
|
|
using URIObserverHashtablePropertyDescriptor =
|
|
const mozilla::FramePropertyDescriptor<URIObserverHashtable>*;
|
|
|
|
static void DestroyFilterProperty(nsSVGFilterProperty* aProp)
|
|
{
|
|
// nsSVGFilterProperty is cycle-collected, so dropping the last reference
|
|
// doesn't necessarily destroy it. We need to tell it that the frame
|
|
// has now become invalid.
|
|
aProp->DetachFromFrame();
|
|
|
|
aProp->Release();
|
|
}
|
|
|
|
NS_DECLARE_FRAME_PROPERTY_WITH_DTOR(FilterProperty, nsSVGFilterProperty,
|
|
DestroyFilterProperty)
|
|
NS_DECLARE_FRAME_PROPERTY_RELEASABLE(MaskProperty, nsSVGMaskProperty)
|
|
NS_DECLARE_FRAME_PROPERTY_RELEASABLE(ClipPathProperty, nsSVGPaintingProperty)
|
|
NS_DECLARE_FRAME_PROPERTY_RELEASABLE(MarkerBeginProperty, nsSVGMarkerProperty)
|
|
NS_DECLARE_FRAME_PROPERTY_RELEASABLE(MarkerMiddleProperty, nsSVGMarkerProperty)
|
|
NS_DECLARE_FRAME_PROPERTY_RELEASABLE(MarkerEndProperty, nsSVGMarkerProperty)
|
|
NS_DECLARE_FRAME_PROPERTY_RELEASABLE(FillProperty, nsSVGPaintingProperty)
|
|
NS_DECLARE_FRAME_PROPERTY_RELEASABLE(StrokeProperty, nsSVGPaintingProperty)
|
|
NS_DECLARE_FRAME_PROPERTY_RELEASABLE(HrefAsTextPathProperty,
|
|
nsSVGTextPathProperty)
|
|
NS_DECLARE_FRAME_PROPERTY_RELEASABLE(HrefAsPaintingProperty,
|
|
nsSVGPaintingProperty)
|
|
NS_DECLARE_FRAME_PROPERTY_DELETABLE(BackgroundImageProperty,
|
|
URIObserverHashtable)
|
|
|
|
/**
|
|
* Get the paint server for a aTargetFrame.
|
|
*/
|
|
static nsSVGPaintServerFrame *GetPaintServer(nsIFrame* aTargetFrame,
|
|
nsStyleSVGPaint nsStyleSVG::* aPaint,
|
|
PaintingPropertyDescriptor aProperty);
|
|
|
|
struct EffectProperties {
|
|
nsSVGFilterProperty* mFilter;
|
|
nsSVGMaskProperty* mMask;
|
|
nsSVGPaintingProperty* mClipPath;
|
|
|
|
/**
|
|
* @return the clip-path frame, or null if there is no clip-path frame
|
|
*/
|
|
nsSVGClipPathFrame* GetClipPathFrame();
|
|
|
|
/**
|
|
* @return an array which contains all SVG mask frames.
|
|
*/
|
|
nsTArray<nsSVGMaskFrame*> GetMaskFrames();
|
|
|
|
/*
|
|
* @return true if all effects we have are valid or we have no effect
|
|
* at all.
|
|
*/
|
|
bool HasNoOrValidEffects();
|
|
|
|
/*
|
|
* @return true if we have any invalid effect.
|
|
*/
|
|
bool HasInvalidEffects() {
|
|
return !HasNoOrValidEffects();
|
|
}
|
|
|
|
/*
|
|
* @return true if we either do not have clip-path or have a valid
|
|
* clip-path.
|
|
*/
|
|
bool HasNoOrValidClipPath();
|
|
|
|
/*
|
|
* @return true if we have an invalid clip-path.
|
|
*/
|
|
bool HasInvalidClipPath() {
|
|
return !HasNoOrValidClipPath();
|
|
}
|
|
|
|
/*
|
|
* @return true if we either do not have mask or all masks we have
|
|
* are valid.
|
|
*/
|
|
bool HasNoOrValidMask();
|
|
|
|
/*
|
|
* @return true if we have an invalid mask.
|
|
*/
|
|
bool HasInvalidMask() {
|
|
return !HasNoOrValidMask();
|
|
}
|
|
|
|
bool HasValidFilter() {
|
|
return mFilter && mFilter->ReferencesValidResources();
|
|
}
|
|
|
|
/*
|
|
* @return true if we either do not have filter or all filters we have
|
|
* are valid.
|
|
*/
|
|
bool HasNoOrValidFilter() {
|
|
return !mFilter || mFilter->ReferencesValidResources();
|
|
}
|
|
|
|
/*
|
|
* @return true if we have an invalid filter.
|
|
*/
|
|
bool HasInvalidFilter() {
|
|
return !HasNoOrValidFilter();
|
|
}
|
|
};
|
|
|
|
/**
|
|
* @param aFrame should be the first continuation
|
|
*/
|
|
static EffectProperties GetEffectProperties(nsIFrame* aFrame);
|
|
|
|
/**
|
|
* Called when changes to an element (e.g. CSS property changes) cause its
|
|
* frame to start/stop referencing (or reference different) SVG resource
|
|
* elements. (_Not_ called for changes to referenced resource elements.)
|
|
*
|
|
* This function handles such changes by discarding _all_ the frame's SVG
|
|
* effects frame properties (causing those properties to stop watching their
|
|
* target element). It also synchronously (re)creates the filter and marker
|
|
* frame properties (XXX why not the other properties?), which makes it
|
|
* useful for initializing those properties during first reflow.
|
|
*
|
|
* XXX rename to something more meaningful like RefreshResourceReferences?
|
|
*/
|
|
static void UpdateEffects(nsIFrame* aFrame);
|
|
|
|
/**
|
|
* @param aFrame should be the first continuation
|
|
*/
|
|
static nsSVGFilterProperty *GetFilterProperty(nsIFrame* aFrame);
|
|
|
|
/**
|
|
* @param aFrame must be a first-continuation.
|
|
*/
|
|
static void AddRenderingObserver(Element* aElement, nsSVGRenderingObserver *aObserver);
|
|
/**
|
|
* @param aFrame must be a first-continuation.
|
|
*/
|
|
static void RemoveRenderingObserver(Element* aElement, nsSVGRenderingObserver *aObserver);
|
|
|
|
/**
|
|
* Removes all rendering observers from aElement.
|
|
*/
|
|
static void RemoveAllRenderingObservers(Element* aElement);
|
|
|
|
/**
|
|
* This can be called on any frame. We invalidate the observers of aFrame's
|
|
* element, if any, or else walk up to the nearest observable SVG parent
|
|
* frame with observers and invalidate them instead.
|
|
*
|
|
* Note that this method is very different to e.g.
|
|
* nsNodeUtils::AttributeChanged which walks up the content node tree all the
|
|
* way to the root node (not stopping if it encounters a non-container SVG
|
|
* node) invalidating all mutation observers (not just
|
|
* nsSVGRenderingObservers) on all nodes along the way (not just the first
|
|
* node it finds with observers). In other words, by doing all the
|
|
* things in parentheses in the preceding sentence, this method uses
|
|
* knowledge about our implementation and what can be affected by SVG effects
|
|
* to make invalidation relatively lightweight when an SVG effect changes.
|
|
*/
|
|
static void InvalidateRenderingObservers(nsIFrame* aFrame);
|
|
|
|
enum {
|
|
INVALIDATE_REFLOW = 1
|
|
};
|
|
|
|
/**
|
|
* This can be called on any element or frame. Only direct observers of this
|
|
* (frame's) element, if any, are invalidated.
|
|
*/
|
|
static void InvalidateDirectRenderingObservers(Element* aElement, uint32_t aFlags = 0);
|
|
static void InvalidateDirectRenderingObservers(nsIFrame* aFrame, uint32_t aFlags = 0);
|
|
|
|
/**
|
|
* Get an nsSVGMarkerProperty for the frame, creating a fresh one if necessary
|
|
*/
|
|
static nsSVGMarkerProperty *
|
|
GetMarkerProperty(nsIURI* aURI, nsIFrame* aFrame,
|
|
const mozilla::FramePropertyDescriptor<nsSVGMarkerProperty>* aProperty);
|
|
/**
|
|
* Get an nsSVGTextPathProperty for the frame, creating a fresh one if necessary
|
|
*/
|
|
static nsSVGTextPathProperty *
|
|
GetTextPathProperty(nsIURI* aURI, nsIFrame* aFrame,
|
|
const mozilla::FramePropertyDescriptor<nsSVGTextPathProperty>* aProperty);
|
|
/**
|
|
* Get an nsSVGPaintingProperty for the frame, creating a fresh one if necessary
|
|
*/
|
|
static nsSVGPaintingProperty*
|
|
GetPaintingProperty(nsIURI* aURI, nsIFrame* aFrame,
|
|
const mozilla::FramePropertyDescriptor<nsSVGPaintingProperty>* aProperty);
|
|
/**
|
|
* Get an nsSVGPaintingProperty for the frame for that URI, creating a fresh
|
|
* one if necessary
|
|
*/
|
|
static nsSVGPaintingProperty*
|
|
GetPaintingPropertyForURI(nsIURI* aURI, nsIFrame* aFrame,
|
|
URIObserverHashtablePropertyDescriptor aProp);
|
|
|
|
/**
|
|
* A helper function to resolve marker's URL.
|
|
*/
|
|
static already_AddRefed<nsIURI>
|
|
GetMarkerURI(nsIFrame* aFrame,
|
|
RefPtr<mozilla::css::URLValue> nsStyleSVG::* aMarker);
|
|
|
|
/**
|
|
* A helper function to resolve clip-path URL.
|
|
*/
|
|
static already_AddRefed<nsIURI>
|
|
GetClipPathURI(nsIFrame* aFrame);
|
|
|
|
/**
|
|
* A helper function to resolve filter URL.
|
|
*/
|
|
static already_AddRefed<nsIURI>
|
|
GetFilterURI(nsIFrame* aFrame, uint32_t aIndex);
|
|
|
|
/**
|
|
* A helper function to resolve filter URL.
|
|
*/
|
|
static already_AddRefed<nsIURI>
|
|
GetFilterURI(nsIFrame* aFrame, const nsStyleFilter& aFilter);
|
|
|
|
/**
|
|
* A helper function to resolve paint-server URL.
|
|
*/
|
|
static already_AddRefed<nsIURI>
|
|
GetPaintURI(nsIFrame* aFrame, nsStyleSVGPaint nsStyleSVG::* aPaint);
|
|
|
|
/**
|
|
* A helper function to resolve SVG mask URL.
|
|
*/
|
|
static already_AddRefed<nsIURI>
|
|
GetMaskURI(nsIFrame* aFrame, uint32_t aIndex);
|
|
|
|
/**
|
|
* Return a baseURL for resolving a local-ref URL.
|
|
*
|
|
* @param aContent an element which uses a local-ref property. Here are some
|
|
* examples:
|
|
* <rect fill=url(#foo)>
|
|
* <circle clip-path=url(#foo)>
|
|
* <use xlink:href="#foo">
|
|
*/
|
|
static already_AddRefed<nsIURI>
|
|
GetBaseURLForLocalRef(nsIContent* aContent, nsIURI* aDocURI);
|
|
};
|
|
|
|
#endif /*NSSVGEFFECTS_H_*/
|