Bug 753517 part 3. Expose the API needed for Paris bindings on nsDOMCSSDeclaration and nsICSSDeclaration. r=dbaron,peterv
authorBoris Zbarsky <bzbarsky@mit.edu>
Thu, 23 Aug 2012 21:08:08 -0700
changeset 105394 75f3cd90e74364a16d8d3f5674a81974274e946e
parent 105393 67ff83142ba5058e9370fb6e1289c929739cdd5b
child 105395 c526d9dfb684d8d7c053157861b9c147e8c5b0cb
push id55
push usershu@rfrn.org
push dateThu, 30 Aug 2012 01:33:09 +0000
reviewersdbaron, peterv
bugs753517
milestone17.0a1
Bug 753517 part 3. Expose the API needed for Paris bindings on nsDOMCSSDeclaration and nsICSSDeclaration. r=dbaron,peterv
dom/bindings/ErrorResult.h
layout/style/Declaration.cpp
layout/style/Declaration.h
layout/style/nsCSSRules.cpp
layout/style/nsCSSRules.h
layout/style/nsComputedDOMStyle.cpp
layout/style/nsComputedDOMStyle.h
layout/style/nsDOMCSSAttrDeclaration.h
layout/style/nsDOMCSSDeclaration.cpp
layout/style/nsDOMCSSDeclaration.h
layout/style/nsICSSDeclaration.h
--- a/dom/bindings/ErrorResult.h
+++ b/dom/bindings/ErrorResult.h
@@ -7,16 +7,17 @@
 /**
  * A struct for tracking exceptions that need to be thrown to JS.
  */
 
 #ifndef mozilla_ErrorResult_h
 #define mozilla_ErrorResult_h
 
 #include "nscore.h"
+#include "mozilla/Assertions.h"
 
 namespace mozilla {
 
 class ErrorResult {
 public:
   ErrorResult() {
     mResult = NS_OK;
   }
--- a/layout/style/Declaration.cpp
+++ b/layout/style/Declaration.cpp
@@ -982,26 +982,28 @@ Declaration::List(FILE* out, int32_t aIn
   fputs("{ ", out);
   nsAutoString s;
   ToString(s);
   fputs(NS_ConvertUTF16toUTF8(s).get(), out);
   fputs("}", out);
 }
 #endif
 
-void
+bool
 Declaration::GetNthProperty(uint32_t aIndex, nsAString& aReturn) const
 {
   aReturn.Truncate();
   if (aIndex < mOrder.Length()) {
     nsCSSProperty property = OrderValueAt(aIndex);
     if (0 <= property) {
       AppendASCIItoUTF16(nsCSSProps::GetStringValue(property), aReturn);
+      return true;
     }
   }
+  return false;
 }
 
 void
 Declaration::InitializeEmpty()
 {
   NS_ABORT_IF_FALSE(!mData && !mImportantData, "already initialized");
   mData = nsCSSCompressedDataBlock::CreateEmptyBlock();
 }
--- a/layout/style/Declaration.h
+++ b/layout/style/Declaration.h
@@ -65,17 +65,19 @@ public:
 
   bool HasImportantData() const { return mImportantData != nullptr; }
   bool GetValueIsImportant(nsCSSProperty aProperty) const;
   bool GetValueIsImportant(const nsAString& aProperty) const;
 
   uint32_t Count() const {
     return mOrder.Length();
   }
-  void GetNthProperty(uint32_t aIndex, nsAString& aReturn) const;
+
+  // Returns whether we actually had a property at aIndex
+  bool GetNthProperty(uint32_t aIndex, nsAString& aReturn) const;
 
   void ToString(nsAString& aString) const;
 
   nsCSSCompressedDataBlock* GetNormalBlock() const { return mData; }
   nsCSSCompressedDataBlock* GetImportantBlock() const { return mImportantData; }
 
   /**
    * Initialize this declaration as holding no data.  Cannot fail.
--- a/layout/style/nsCSSRules.cpp
+++ b/layout/style/nsCSSRules.cpp
@@ -1553,33 +1553,44 @@ nsCSSFontFaceStyleDecl::GetLength(uint32
       len++;
 
   *aLength = len;
   return NS_OK;
 }
 
 // DOMString item (in unsigned long index);
 NS_IMETHODIMP
-nsCSSFontFaceStyleDecl::Item(uint32_t index, nsAString & aResult)
- {
+nsCSSFontFaceStyleDecl::Item(uint32_t aIndex, nsAString& aReturn)
+{
+  bool found;
+  IndexedGetter(aIndex, found, aReturn);
+  if (!found) {
+    aReturn.Truncate();
+  }
+  return NS_OK;
+}
+
+void
+nsCSSFontFaceStyleDecl::IndexedGetter(uint32_t index, bool& aFound, nsAString & aResult)
+{
   int32_t nset = -1;
   for (nsCSSFontDesc id = nsCSSFontDesc(eCSSFontDesc_UNKNOWN + 1);
        id < eCSSFontDesc_COUNT;
        id = nsCSSFontDesc(id + 1)) {
     if ((this->*nsCSSFontFaceStyleDecl::Fields[id]).GetUnit()
         != eCSSUnit_Null) {
       nset++;
       if (nset == int32_t(index)) {
+        aFound = true;
         aResult.AssignASCII(nsCSSProps::GetStringValue(id).get());
-        return NS_OK;
+        return;
       }
     }
   }
-  aResult.Truncate();
-  return NS_OK;
+  aFound = false;
 }
 
 // readonly attribute nsIDOMCSSRule parentRule;
 NS_IMETHODIMP
 nsCSSFontFaceStyleDecl::GetParentRule(nsIDOMCSSRule** aParentRule)
 {
   NS_IF_ADDREF(*aParentRule = ContainingRule()->GetDOMRule());
   return NS_OK;
--- a/layout/style/nsCSSRules.h
+++ b/layout/style/nsCSSRules.h
@@ -160,16 +160,17 @@ class nsCSSFontFaceRule;
 class nsCSSFontFaceStyleDecl : public nsICSSDeclaration
 {
 public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMCSSSTYLEDECLARATION
   NS_DECL_NSICSSDECLARATION
 
   virtual nsINode *GetParentObject();
+  virtual void IndexedGetter(uint32_t aIndex, bool& aFound, nsAString& aPropName);
 
   nsresult GetPropertyValue(nsCSSFontDesc aFontDescID,
                             nsAString & aResult) const;
 
 protected:
   friend class nsCSSFontFaceRule;
 #define CSS_FONT_DESC(name_, method_) nsCSSValue m##method_;
 #include "nsCSSFontDescList.h"
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -540,28 +540,31 @@ nsComputedDOMStyle::SetProperty(const ns
 {
   return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
 }
 
 
 NS_IMETHODIMP
 nsComputedDOMStyle::Item(uint32_t aIndex, nsAString& aReturn)
 {
-  aReturn.Truncate();
-
+  return nsDOMCSSDeclaration::Item(aIndex, aReturn);
+}
+
+void
+nsComputedDOMStyle::IndexedGetter(uint32_t aIndex, bool& aFound,
+                                  nsAString& aPropName)
+{
   uint32_t length = 0;
   const ComputedStyleMapEntry* propMap = GetQueryablePropertyMap(&length);
-  if (aIndex < length) {
+  aFound = aIndex < length;
+  if (aFound) {
     CopyASCIItoUTF16(nsCSSProps::GetStringValue(propMap[aIndex].mProperty),
-                    aReturn);
+                     aPropName);
   }
-
-  return NS_OK;
-}
-
+}
 
 // Property getters...
 
 nsIDOMCSSValue*
 nsComputedDOMStyle::DoGetBinding()
 {
   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
 
--- a/layout/style/nsComputedDOMStyle.h
+++ b/layout/style/nsComputedDOMStyle.h
@@ -20,26 +20,27 @@
 #include "nsWeakReference.h"
 #include "nsAutoPtr.h"
 #include "nsStyleStruct.h"
 #include "nsStyleContext.h"
 
 class nsIFrame;
 class nsIPresShell;
 
-class nsComputedDOMStyle : public nsDOMCSSDeclaration
+class nsComputedDOMStyle MOZ_FINAL : public nsDOMCSSDeclaration
 {
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsComputedDOMStyle,
                                                                    nsICSSDeclaration)
 
   NS_DECL_NSICSSDECLARATION
 
   NS_DECL_NSIDOMCSSSTYLEDECLARATION
+  virtual void IndexedGetter(uint32_t aIndex, bool& aFound, nsAString& aPropName);
 
   nsComputedDOMStyle(mozilla::dom::Element* aElement,
                      const nsAString& aPseudoElt,
                      nsIPresShell* aPresShell);
   virtual ~nsComputedDOMStyle();
 
   static void Shutdown();
 
--- a/layout/style/nsDOMCSSAttrDeclaration.h
+++ b/layout/style/nsDOMCSSAttrDeclaration.h
@@ -18,17 +18,17 @@ namespace css {
 class Loader;
 }
 
 namespace dom {
 class Element;
 }
 }
 
-class nsDOMCSSAttributeDeclaration : public nsDOMCSSDeclaration
+class nsDOMCSSAttributeDeclaration MOZ_FINAL : public nsDOMCSSDeclaration
 {
 public:
   typedef mozilla::dom::Element Element;
   nsDOMCSSAttributeDeclaration(Element* aContent, bool aIsSMILOverride);
   ~nsDOMCSSAttributeDeclaration();
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsDOMCSSAttributeDeclaration,
--- a/layout/style/nsDOMCSSDeclaration.cpp
+++ b/layout/style/nsDOMCSSDeclaration.cpp
@@ -139,27 +139,21 @@ nsDOMCSSDeclaration::GetPropertyCSSValue
   NS_ENSURE_ARG_POINTER(aReturn);
 
   // We don't support CSSValue yet so we'll just return null...
   *aReturn = nullptr;
 
   return NS_OK;
 }
 
-NS_IMETHODIMP
-nsDOMCSSDeclaration::Item(uint32_t aIndex, nsAString& aReturn)
+void
+nsDOMCSSDeclaration::IndexedGetter(uint32_t aIndex, bool& aFound, nsAString& aPropName)
 {
   css::Declaration* decl = GetCSSDeclaration(false);
-
-  aReturn.SetLength(0);
-  if (decl) {
-    decl->GetNthProperty(aIndex, aReturn);
-  }
-
-  return NS_OK;
+  aFound = decl && decl->GetNthProperty(aIndex, aPropName);
 }
 
 NS_IMETHODIMP
 nsDOMCSSDeclaration::GetPropertyValue(const nsAString& aPropertyName,
                                       nsAString& aReturn)
 {
   const nsCSSProperty propID = nsCSSProps::LookupProperty(aPropertyName,
                                                           nsCSSProps::eEnabled);
--- a/layout/style/nsDOMCSSDeclaration.h
+++ b/layout/style/nsDOMCSSDeclaration.h
@@ -28,40 +28,79 @@ class Rule;
 class nsDOMCSSDeclaration : public nsICSSDeclaration,
                             public nsIDOMCSS2Properties
 {
 public:
   // Only implement QueryInterface; subclasses have the responsibility
   // of implementing AddRef/Release.
   NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr);
 
+  // Declare addref and release so they can be called on us, but don't
+  // implement them.  Our subclasses must handle their own
+  // refcounting.
+  NS_IMETHOD_(nsrefcnt) AddRef() = 0;
+  NS_IMETHOD_(nsrefcnt) Release() = 0;
+
   NS_DECL_NSICSSDECLARATION
+  using nsICSSDeclaration::GetLength;
 
   // Require subclasses to implement |GetParentRule|.
   //NS_DECL_NSIDOMCSSSTYLEDECLARATION
   NS_IMETHOD GetCssText(nsAString & aCssText);
   NS_IMETHOD SetCssText(const nsAString & aCssText);
   NS_IMETHOD GetPropertyValue(const nsAString & propertyName,
                               nsAString & _retval);
   NS_IMETHOD GetPropertyCSSValue(const nsAString & propertyName,
                                  nsIDOMCSSValue **_retval);
   NS_IMETHOD RemoveProperty(const nsAString & propertyName,
                             nsAString & _retval);
   NS_IMETHOD GetPropertyPriority(const nsAString & propertyName,
                                  nsAString & _retval);
   NS_IMETHOD SetProperty(const nsAString & propertyName,
                          const nsAString & value, const nsAString & priority);
   NS_IMETHOD GetLength(uint32_t *aLength);
-  NS_IMETHOD Item(uint32_t index, nsAString & _retval);
   NS_IMETHOD GetParentRule(nsIDOMCSSRule * *aParentRule) = 0;
 
   // We implement this as a shim which forwards to GetPropertyValue
   // and SetPropertyValue; subclasses need not.
   NS_DECL_NSIDOMCSS2PROPERTIES
 
+  // WebIDL interface for CSS2Properties
+#define CSS_PROP_DOMPROP_PREFIXED(prop_) Moz ## prop_
+#define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_,          \
+                 kwtable_, stylestruct_, stylestructoffset_, animtype_)      \
+  void                                                                       \
+  Get##method_(nsAString& aValue, mozilla::ErrorResult& rv)                  \
+  {                                                                          \
+    rv = GetPropertyValue(eCSSProperty_##id_, aValue);                       \
+  }                                                                          \
+                                                                             \
+  void                                                                       \
+  Set##method_(const nsAString& aValue, mozilla::ErrorResult& rv)            \
+  {                                                                          \
+    rv = SetPropertyValue(eCSSProperty_##id_, aValue);                       \
+  }
+
+#define CSS_PROP_LIST_EXCLUDE_INTERNAL
+#define CSS_PROP_SHORTHAND(name_, id_, method_, flags_, pref_)  \
+  CSS_PROP(name_, id_, method_, flags_, pref_, X, X, X, X, X)
+#include "nsCSSPropList.h"
+
+#define CSS_PROP_ALIAS(aliasname_, propid_, aliasmethod_, pref_)  \
+  CSS_PROP(X, propid_, aliasmethod_, X, pref_, X, X, X, X, X)
+#include "nsCSSPropAliasList.h"
+#undef CSS_PROP_ALIAS
+
+#undef CSS_PROP_SHORTHAND
+#undef CSS_PROP_LIST_EXCLUDE_INTERNAL
+#undef CSS_PROP
+#undef CSS_PROP_DOMPROP_PREFIXED
+
+  virtual void IndexedGetter(uint32_t aIndex, bool& aFound, nsAString& aPropName);
+
 protected:
   // This method can return null regardless of the value of aAllocate;
   // however, a null return should only be considered a failure
   // if aAllocate is true.
   virtual mozilla::css::Declaration* GetCSSDeclaration(bool aAllocate) = 0;
   virtual nsresult SetCSSDeclaration(mozilla::css::Declaration* aDecl) = 0;
   // Document that we must call BeginUpdate/EndUpdate on around the
   // calls to SetCSSDeclaration and the style rule mutation that leads
--- a/layout/style/nsICSSDeclaration.h
+++ b/layout/style/nsICSSDeclaration.h
@@ -17,51 +17,132 @@
  * nsCSSProperty enums for the prop names instead of using strings.
  * This is meant for use in performance-sensitive code only!  Most
  * consumers should continue to use nsIDOMCSSStyleDeclaration.
  */
 
 #include "nsIDOMCSSStyleDeclaration.h"
 #include "nsCSSProperty.h"
 #include "nsWrapperCache.h"
+#include "mozilla/dom/BindingUtils.h"
+#include "nsString.h"
+#include "nsIDOMCSSRule.h"
+#include "nsIDOMCSSValue.h"
+#include "mozilla/ErrorResult.h"
 
-// 57eb81d1-a607-4429-926b-802519d43aad
+// dbeabbfa-6cb3-4f5c-aec2-dd558d9d681f
 #define NS_ICSSDECLARATION_IID \
- { 0x57eb81d1, 0xa607, 0x4429, \
-    {0x92, 0x6b, 0x80, 0x25, 0x19, 0xd4, 0x3a, 0xad } }
+{ 0xdbeabbfa, 0x6cb3, 0x4f5c, \
+ { 0xae, 0xc2, 0xdd, 0x55, 0x8d, 0x9d, 0x68, 0x1f } }
 
 class nsINode;
 
 class nsICSSDeclaration : public nsIDOMCSSStyleDeclaration,
                           public nsWrapperCache
 {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_ICSSDECLARATION_IID)
 
   /**
    * Method analogous to nsIDOMCSSStyleDeclaration::GetPropertyValue,
    * which obeys all the same restrictions.
    */
   NS_IMETHOD GetPropertyValue(const nsCSSProperty aPropID,
                               nsAString& aValue) = 0;
 
-  // Also have to declare the nsIDOMCSSStyleDeclaration method, so we
-  // don't hide it... very sad, but it stole the good method name
-  NS_IMETHOD GetPropertyValue(const nsAString& aPropName,
-                              nsAString& aValue) = 0;
-  
   /**
    * Method analogous to nsIDOMCSSStyleDeclaration::SetProperty.  This
    * method does NOT allow setting a priority (the priority will
    * always be set to default priority).
    */
   NS_IMETHOD SetPropertyValue(const nsCSSProperty aPropID,
                               const nsAString& aValue) = 0;
 
   virtual nsINode *GetParentObject() = 0;
+
+  // Also have to declare all the nsIDOMCSSStyleDeclaration methods,
+  // since we want to be able to call them from the WebIDL versions.
+  NS_IMETHOD GetCssText(nsAString& aCssText) = 0;
+  NS_IMETHOD SetCssText(const nsAString& aCssText) = 0;
+  NS_IMETHOD GetPropertyValue(const nsAString& aPropName,
+                              nsAString& aValue) = 0;
+  NS_IMETHOD GetPropertyCSSValue(const nsAString& aPropertyName,
+                                 nsIDOMCSSValue** aReturn) = 0;
+  NS_IMETHOD RemoveProperty(const nsAString& aPropertyName,
+                            nsAString& aReturn) = 0;
+  NS_IMETHOD GetPropertyPriority(const nsAString& aPropertyName,
+                                 nsAString& aReturn) = 0;
+  NS_IMETHOD SetProperty(const nsAString& aPropertyName,
+                         const nsAString& aValue,
+                         const nsAString& aPriority) = 0;
+  NS_IMETHOD GetLength(uint32_t* aLength) = 0;
+  NS_IMETHOD Item(uint32_t aIndex, nsAString& aReturn)
+  {
+    bool found;
+    IndexedGetter(aIndex, found, aReturn);
+    if (!found) {
+      aReturn.Truncate();
+    }
+    return NS_OK;
+  }
+  NS_IMETHOD GetParentRule(nsIDOMCSSRule * *aParentRule) = 0;
+
+  // WebIDL interface for CSSStyleDeclaration
+  void SetCssText(const nsAString& aString, mozilla::ErrorResult& rv) {
+    rv = SetCssText(aString);
+  }
+  void GetCssText(nsString& aString) {
+    // Cast to nsAString& so we end up calling our virtual
+    // |GetCssText(nsAString& aCssText)| overload, which does the real work.
+    GetCssText(static_cast<nsAString&>(aString));
+  }
+  uint32_t GetLength() {
+    uint32_t length;
+    GetLength(&length);
+    return length;
+  }
+  void Item(uint32_t aIndex, nsString& aPropName) {
+    Item(aIndex, static_cast<nsAString&>(aPropName));
+  }
+
+  // The actual implementation of the Item method and the WebIDL indexed getter
+  virtual void IndexedGetter(uint32_t aIndex, bool& aFound, nsAString& aPropName) = 0;
+
+  void GetPropertyValue(const nsAString& aPropName, nsString& aValue,
+                        mozilla::ErrorResult& rv) {
+    rv = GetPropertyValue(aPropName, aValue);
+  }
+  already_AddRefed<nsIDOMCSSValue>
+    GetPropertyCSSValue(const nsAString& aPropName, mozilla::ErrorResult& rv) {
+    nsCOMPtr<nsIDOMCSSValue> val;
+    rv = GetPropertyCSSValue(aPropName, getter_AddRefs(val));
+    return val.forget();
+  }
+  void GetPropertyPriority(const nsAString& aPropName, nsString& aPriority) {
+    GetPropertyPriority(aPropName, static_cast<nsAString&>(aPriority));
+  }
+  // XXXbz we should nix the Optional thing once bug 759622 is fixed.
+  void SetProperty(const nsAString& aPropName, const nsAString& aValue,
+                   const mozilla::dom::Optional<nsAString>& aPriority,
+                   mozilla::ErrorResult& rv) {
+    if (aPriority.WasPassed()) {
+      rv = SetProperty(aPropName, aValue, aPriority.Value());
+    } else {
+      rv = SetProperty(aPropName, aValue, EmptyString());
+    }
+  }
+  void RemoveProperty(const nsAString& aPropName, nsString& aRetval,
+                      mozilla::ErrorResult& rv) {
+    rv = RemoveProperty(aPropName, aRetval);
+  }
+  already_AddRefed<nsIDOMCSSRule> GetParentRule() {
+    nsCOMPtr<nsIDOMCSSRule> rule;
+    GetParentRule(getter_AddRefs(rule));
+    return rule.forget();
+  }
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsICSSDeclaration, NS_ICSSDECLARATION_IID)
 
 #define NS_DECL_NSICSSDECLARATION                               \
   NS_IMETHOD GetPropertyValue(const nsCSSProperty aPropID,    \
                               nsAString& aValue);               \
   NS_IMETHOD SetPropertyValue(const nsCSSProperty aPropID,    \