Bug 572689 - Add an SVG property for -moz-element called BackgroundImageProperty and make it able to handle multiple observers with different observer URLs. r=roc
authorMarkus Stange <mstange@themasta.com>
Fri, 13 Aug 2010 15:30:45 +0200
changeset 50421 77d39c005c6fd1e068feb192e6edf93c4c60c7ca
parent 50420 91f0d2cd19e832ba9b65631d2ce301c9aca0761a
child 50422 5d5752f83c6110ce178f60f139aca5bf7bad2132
push idunknown
push userunknown
push dateunknown
reviewersroc
bugs572689
milestone2.0b4pre
Bug 572689 - Add an SVG property for -moz-element called BackgroundImageProperty and make it able to handle multiple observers with different observer URLs. r=roc
layout/svg/base/src/nsSVGEffects.cpp
layout/svg/base/src/nsSVGEffects.h
--- a/layout/svg/base/src/nsSVGEffects.cpp
+++ b/layout/svg/base/src/nsSVGEffects.cpp
@@ -361,16 +361,46 @@ nsSVGEffects::GetTextPathProperty(nsIURI
 nsSVGPaintingProperty *
 nsSVGEffects::GetPaintingProperty(nsIURI *aURI, nsIFrame *aFrame,
                                   const FramePropertyDescriptor *aProp)
 {
   return static_cast<nsSVGPaintingProperty*>(
           GetEffectProperty(aURI, aFrame, aProp, CreatePaintingProperty));
 }
 
+static nsSVGRenderingObserver *
+GetEffectPropertyForURI(nsIURI *aURI, nsIFrame *aFrame,
+                        const FramePropertyDescriptor *aProperty,
+                        nsSVGRenderingObserver * (* aCreate)(nsIURI *, nsIFrame *))
+{
+  FrameProperties props = aFrame->Properties();
+  nsSVGEffects::URIObserverHashtable *hashtable =
+    static_cast<nsSVGEffects::URIObserverHashtable*>(props.Get(aProperty));
+  if (!hashtable) {
+    hashtable = new nsSVGEffects::URIObserverHashtable();
+    hashtable->Init();
+    props.Set(aProperty, hashtable);
+  }
+  nsSVGRenderingObserver* prop =
+    static_cast<nsSVGRenderingObserver*>(hashtable->GetWeak(aURI));
+  if (!prop) {
+    prop = aCreate(aURI, aFrame);
+    hashtable->Put(aURI, prop);
+  }
+  return prop;
+}
+
+nsSVGPaintingProperty *
+nsSVGEffects::GetPaintingPropertyForURI(nsIURI *aURI, nsIFrame *aFrame,
+                                        const FramePropertyDescriptor *aProp)
+{
+  return static_cast<nsSVGPaintingProperty*>(
+          GetEffectPropertyForURI(aURI, aFrame, aProp, CreatePaintingProperty));
+}
+
 nsSVGEffects::EffectProperties
 nsSVGEffects::GetEffectProperties(nsIFrame *aFrame)
 {
   NS_ASSERTION(!aFrame->GetPrevContinuation(), "aFrame should be first continuation");
 
   EffectProperties result;
   const nsStyleSVGReset *style = aFrame->GetStyleSVGReset();
   result.mFilter = static_cast<nsSVGFilterProperty*>
@@ -415,16 +445,17 @@ nsSVGEffects::UpdateEffects(nsIFrame *aF
   props.Delete(FilterProperty());
   props.Delete(MaskProperty());
   props.Delete(ClipPathProperty());
   props.Delete(MarkerBeginProperty());
   props.Delete(MarkerMiddleProperty());
   props.Delete(MarkerEndProperty());
   props.Delete(FillProperty());
   props.Delete(StrokeProperty());
+  props.Delete(BackgroundImageProperty());
 
   // Ensure that the filter is repainted correctly
   // We can't do that in DoUpdate as the referenced frame may not be valid
   GetEffectProperty(aFrame->GetStyleSVGReset()->mFilter,
                     aFrame, FilterProperty(), CreateFilterProperty);
 
   if (aFrame->IsFrameOfType(nsIFrame::eSVG)) {
     // Set marker properties here to avoid reference loops
--- a/layout/svg/base/src/nsSVGEffects.h
+++ b/layout/svg/base/src/nsSVGEffects.h
@@ -38,17 +38,18 @@
 #ifndef NSSVGEFFECTS_H_
 #define NSSVGEFFECTS_H_
 
 #include "nsIContent.h"
 #include "nsIFrame.h"
 #include "nsReferencedElement.h"
 #include "nsStubMutationObserver.h"
 #include "nsSVGUtils.h"
-#include "nsTHashtable.h"
+#include "nsInterfaceHashtable.h"
+#include "nsURIHashKey.h"
 
 class nsSVGClipPathFrame;
 class nsSVGFilterFrame;
 class nsSVGMaskFrame;
 
 /*
  * SVG elements reference supporting resources by element ID. We need to
  * track when those resources change and when the DOM changes in ways
@@ -212,31 +213,39 @@ public:
 
 private:
   nsTHashtable<nsVoidPtrHashKey> mObservers;
 };
 
 class nsSVGEffects {
 public:
   typedef mozilla::FramePropertyDescriptor FramePropertyDescriptor;
+  typedef nsInterfaceHashtable<nsURIHashKey, nsIMutationObserver>
+    URIObserverHashtable;
 
   static void DestroySupports(void* aPropertyValue)
   {
     (static_cast<nsISupports*>(aPropertyValue))->Release();
   }
 
+  static void DestroyHashtable(void* aPropertyValue)
+  {
+    delete static_cast<URIObserverHashtable*> (aPropertyValue);
+  }
+
   NS_DECLARE_FRAME_PROPERTY(FilterProperty, DestroySupports)
   NS_DECLARE_FRAME_PROPERTY(MaskProperty, DestroySupports)
   NS_DECLARE_FRAME_PROPERTY(ClipPathProperty, DestroySupports)
   NS_DECLARE_FRAME_PROPERTY(MarkerBeginProperty, DestroySupports)
   NS_DECLARE_FRAME_PROPERTY(MarkerMiddleProperty, DestroySupports)
   NS_DECLARE_FRAME_PROPERTY(MarkerEndProperty, DestroySupports)
   NS_DECLARE_FRAME_PROPERTY(FillProperty, DestroySupports)
   NS_DECLARE_FRAME_PROPERTY(StrokeProperty, DestroySupports)
   NS_DECLARE_FRAME_PROPERTY(HrefProperty, DestroySupports)
+  NS_DECLARE_FRAME_PROPERTY(BackgroundImageProperty, DestroyHashtable)
 
   struct EffectProperties {
     nsSVGFilterProperty*   mFilter;
     nsSVGPaintingProperty* mMask;
     nsSVGPaintingProperty* mClipPath;
 
     /**
      * @return the clip-path frame, or null if there is no clip-path frame
@@ -330,11 +339,18 @@ public:
   GetTextPathProperty(nsIURI *aURI, nsIFrame *aFrame,
                       const FramePropertyDescriptor *aProperty);
   /**
    * Get an nsSVGPaintingProperty for the frame, creating a fresh one if necessary
    */
   static nsSVGPaintingProperty *
   GetPaintingProperty(nsIURI *aURI, nsIFrame *aFrame,
                       const FramePropertyDescriptor *aProperty);
+  /**
+   * Get an nsSVGPaintingProperty for the frame for that URI, creating a fresh
+   * one if necessary
+   */
+  static nsSVGPaintingProperty *
+  GetPaintingPropertyForURI(nsIURI *aURI, nsIFrame *aFrame,
+                            const FramePropertyDescriptor *aProp);
 };
 
 #endif /*NSSVGEFFECTS_H_*/