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 109355 75f3cd90e74364a16d8d3f5674a81974274e946e
parent 109354 67ff83142ba5058e9370fb6e1289c929739cdd5b
child 109356 c526d9dfb684d8d7c053157861b9c147e8c5b0cb
push id214
push userakeybl@mozilla.com
push dateWed, 14 Nov 2012 20:38:59 +0000
treeherdermozilla-release@c8b08ec8e1aa [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdbaron, peterv
bugs753517
milestone17.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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,    \