Bug 1294299 part 4 - Implement length and item getter. r=SimonSapin,heycam draft
authorXidorn Quan <me@upsuper.org>
Wed, 26 Oct 2016 10:03:00 +1100
changeset 432585 4b82b5d16d5df5dcaa84ff777938a6dfb29d5a5c
parent 432584 aa420e1e97a41e6957be96dd2018e7b30de8a8f0
child 432586 e732da1d70785893be451ed7196d84e357f0b54e
push id34373
push userxquan@mozilla.com
push dateWed, 02 Nov 2016 11:29:39 +0000
reviewersSimonSapin, heycam
bugs1294299
milestone52.0a1
Bug 1294299 part 4 - Implement length and item getter. r=SimonSapin,heycam MozReview-Commit-ID: IQs8Wjdsi1r
layout/style/DeclarationBlock.h
layout/style/DeclarationBlockInlines.h
layout/style/ServoBindingList.h
layout/style/ServoDeclarationBlock.h
layout/style/nsDOMCSSDeclaration.cpp
servo/components/style/binding_tools/regen.py
servo/components/style/gecko_bindings/bindings.rs
servo/ports/geckolib/glue.rs
--- a/layout/style/DeclarationBlock.h
+++ b/layout/style/DeclarationBlock.h
@@ -87,16 +87,19 @@ public:
     if (!(mContainer.mRaw & 0x1)) {
       return nullptr;
     }
     auto c = mContainer;
     c.mRaw &= ~uintptr_t(1);
     return c.mHTMLCSSStyleSheet;
   }
 
+  inline uint32_t Count() const;
+  inline bool GetNthProperty(uint32_t aIndex, nsAString& aReturn) const;
+
 private:
   union {
     // We only ever have one of these since we have an
     // nsHTMLCSSStyleSheet only for style attributes, and style
     // attributes never have an owning rule.
 
     // It's an nsHTMLCSSStyleSheet if the low bit is set.
 
--- a/layout/style/DeclarationBlockInlines.h
+++ b/layout/style/DeclarationBlockInlines.h
@@ -21,11 +21,23 @@ DeclarationBlock::AddRef()
 }
 
 MozExternalRefCountType
 DeclarationBlock::Release()
 {
   MOZ_STYLO_FORWARD(Release, ())
 }
 
+uint32_t
+DeclarationBlock::Count() const
+{
+  MOZ_STYLO_FORWARD(Count, ())
+}
+
+bool
+DeclarationBlock::GetNthProperty(uint32_t aIndex, nsAString& aReturn) const
+{
+  MOZ_STYLO_FORWARD(GetNthProperty, (aIndex, aReturn))
+}
+
 } // namespace mozilla
 
 #endif // mozilla_DeclarationBlockInlines_h
--- a/layout/style/ServoBindingList.h
+++ b/layout/style/ServoBindingList.h
@@ -69,16 +69,21 @@ SERVO_BINDING_FUNC(Servo_DeclarationBloc
 SERVO_BINDING_FUNC(Servo_DeclarationBlock_Release, void,
                    RawServoDeclarationBlockBorrowed declarations)
 SERVO_BINDING_FUNC(Servo_DeclarationBlock_Equals, bool,
                    RawServoDeclarationBlockBorrowed a,
                    RawServoDeclarationBlockBorrowed b)
 SERVO_BINDING_FUNC(Servo_DeclarationBlock_SerializeOneValue, void,
                    RawServoDeclarationBlockBorrowed declarations,
                    nsString* buffer)
+SERVO_BINDING_FUNC(Servo_DeclarationBlock_Count, uint32_t,
+                   RawServoDeclarationBlockBorrowed declarations)
+SERVO_BINDING_FUNC(Servo_DeclarationBlock_GetNthProperty, bool,
+                   RawServoDeclarationBlockBorrowed declarations,
+                   uint32_t index, nsAString* result)
 
 // CSS supports()
 SERVO_BINDING_FUNC(Servo_CSSSupports, bool,
                    const nsACString* name, const nsACString* value)
 
 // Computed style data
 SERVO_BINDING_FUNC(Servo_ComputedValues_Get, ServoComputedValuesStrong,
                    RawGeckoNodeBorrowed node)
--- a/layout/style/ServoDeclarationBlock.h
+++ b/layout/style/ServoDeclarationBlock.h
@@ -24,16 +24,24 @@ public:
 
   RawServoDeclarationBlock* const* RefRaw() const {
     static_assert(sizeof(RefPtr<RawServoDeclarationBlock>) ==
                   sizeof(RawServoDeclarationBlock*),
                   "RefPtr should just be a pointer");
     return reinterpret_cast<RawServoDeclarationBlock* const*>(&mRaw);
   }
 
+  uint32_t Count() const {
+    return Servo_DeclarationBlock_Count(mRaw);
+  }
+  bool GetNthProperty(uint32_t aIndex, nsAString& aReturn) const {
+    aReturn.Truncate();
+    return Servo_DeclarationBlock_GetNthProperty(mRaw, aIndex, &aReturn);
+  }
+
 protected:
   explicit ServoDeclarationBlock(
     already_AddRefed<RawServoDeclarationBlock> aRaw)
     : DeclarationBlock(StyleBackendType::Servo), mRaw(aRaw) {}
 
 private:
   ~ServoDeclarationBlock() {}
 
--- a/layout/style/nsDOMCSSDeclaration.cpp
+++ b/layout/style/nsDOMCSSDeclaration.cpp
@@ -161,17 +161,17 @@ nsDOMCSSDeclaration::SetCssText(const ns
   }
 
   return SetCSSDeclaration(decl);
 }
 
 NS_IMETHODIMP
 nsDOMCSSDeclaration::GetLength(uint32_t* aLength)
 {
-  css::Declaration* decl = GetCSSDeclaration(eOperation_Read)->AsGecko();
+  DeclarationBlock* decl = GetCSSDeclaration(eOperation_Read);
 
   if (decl) {
     *aLength = decl->Count();
   } else {
     *aLength = 0;
   }
 
   return NS_OK;
@@ -183,17 +183,17 @@ nsDOMCSSDeclaration::GetPropertyCSSValue
   // We don't support CSSValue yet so we'll just return null...
 
   return nullptr;
 }
 
 void
 nsDOMCSSDeclaration::IndexedGetter(uint32_t aIndex, bool& aFound, nsAString& aPropName)
 {
-  css::Declaration* decl = GetCSSDeclaration(eOperation_Read)->AsGecko();
+  DeclarationBlock* decl = GetCSSDeclaration(eOperation_Read);
   aFound = decl && decl->GetNthProperty(aIndex, aPropName);
 }
 
 NS_IMETHODIMP
 nsDOMCSSDeclaration::GetPropertyValue(const nsAString& aPropertyName,
                                       nsAString& aReturn)
 {
   const nsCSSPropertyID propID =
--- a/servo/components/style/binding_tools/regen.py
+++ b/servo/components/style/binding_tools/regen.py
@@ -231,20 +231,22 @@ COMPILATION_TARGETS = {
             }
         ],
     },
     # Generation of the ffi bindings.
     "bindings": {
         "target_dir": "../gecko_bindings",
         "blacklist_types": [
             "nsACString_internal",
+            "nsAString_internal",
         ],
         "raw_lines": [
-            "pub use nsstring::nsACString;",
+            "pub use nsstring::{nsACString, nsAString};",
             "type nsACString_internal = nsACString;",
+            "type nsAString_internal = nsAString;"
         ],
         "flags": [
             "--ignore-methods",
         ],
         "match_headers": [
             "ServoBindingList.h",
             "ServoBindings.h",
             "nsStyleStructList.h",
--- a/servo/components/style/gecko_bindings/bindings.rs
+++ b/servo/components/style/gecko_bindings/bindings.rs
@@ -1,12 +1,13 @@
 /* automatically generated by rust-bindgen */
 
-pub use nsstring::nsACString;
+pub use nsstring::{nsACString, nsAString};
 type nsACString_internal = nsACString;
+type nsAString_internal = nsAString;
 pub type ServoComputedValuesStrong = ::gecko_bindings::sugar::ownership::Strong<ServoComputedValues>;
 pub type ServoComputedValuesBorrowedOrNull<'a> = Option<&'a ServoComputedValues>;
 pub type ServoComputedValuesBorrowed<'a> = &'a ServoComputedValues;
 enum ServoComputedValuesVoid{ }
 pub struct ServoComputedValues(ServoComputedValuesVoid);
 pub type RawServoStyleSheetStrong = ::gecko_bindings::sugar::ownership::Strong<RawServoStyleSheet>;
 pub type RawServoStyleSheetBorrowedOrNull<'a> = Option<&'a RawServoStyleSheet>;
 pub type RawServoStyleSheetBorrowed<'a> = &'a RawServoStyleSheet;
@@ -932,16 +933,29 @@ extern "C" {
      -> bool;
 }
 extern "C" {
     pub fn Servo_DeclarationBlock_SerializeOneValue(declarations:
                                                         RawServoDeclarationBlockBorrowed,
                                                     buffer: *mut nsString);
 }
 extern "C" {
+    pub fn Servo_DeclarationBlock_Count(declarations:
+                                            RawServoDeclarationBlockBorrowed)
+     -> u32;
+}
+extern "C" {
+    pub fn Servo_DeclarationBlock_GetNthProperty(declarations:
+                                                     RawServoDeclarationBlockBorrowed,
+                                                 index: u32,
+                                                 result:
+                                                     *mut nsAString_internal)
+     -> bool;
+}
+extern "C" {
     pub fn Servo_CSSSupports(name: *const nsACString_internal,
                              value: *const nsACString_internal) -> bool;
 }
 extern "C" {
     pub fn Servo_ComputedValues_Get(node: RawGeckoNodeBorrowed)
      -> ServoComputedValuesStrong;
 }
 extern "C" {
--- a/servo/ports/geckolib/glue.rs
+++ b/servo/ports/geckolib/glue.rs
@@ -2,16 +2,17 @@
  * 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/. */
 
 use app_units::Au;
 use cssparser::{Parser, ToCss};
 use env_logger;
 use euclid::Size2D;
 use parking_lot::RwLock;
+use std::fmt::Write;
 use std::mem::transmute;
 use std::sync::{Arc, Mutex};
 use style::arc_ptr_eq;
 use style::context::{LocalStyleContextCreationInfo, ReflowGoal, SharedStyleContext};
 use style::dom::{NodeInfo, StylingMode, TElement, TNode};
 use style::error_reporting::StdoutErrorReporter;
 use style::gecko::data::{NUM_THREADS, PerDocumentStyleData};
 use style::gecko::selector_impl::{GeckoSelectorImpl, PseudoElement};
@@ -470,16 +471,35 @@ pub extern "C" fn Servo_DeclarationBlock
     // FIXME: Once we have nsString bindings for Servo (bug 1294742), we should be able to drop
     // this and fill in |buffer| directly.
     unsafe {
         Gecko_Utf8SliceToString(buffer, value.as_ptr(), length);
     }
 }
 
 #[no_mangle]
+pub extern "C" fn Servo_DeclarationBlock_Count(declarations: RawServoDeclarationBlockBorrowed) -> u32 {
+     let declarations = RwLock::<PropertyDeclarationBlock>::as_arc(&declarations);
+     declarations.read().declarations.len() as u32
+}
+
+#[no_mangle]
+pub extern "C" fn Servo_DeclarationBlock_GetNthProperty(declarations: RawServoDeclarationBlockBorrowed,
+                                                        index: u32, result: *mut nsAString) -> bool {
+    let declarations = RwLock::<PropertyDeclarationBlock>::as_arc(&declarations);
+    if let Some(&(ref decl, _)) = declarations.read().declarations.get(index as usize) {
+        let result = unsafe { result.as_mut().unwrap() };
+        write!(result, "{}", decl.name()).unwrap();
+        true
+    } else {
+        false
+    }
+}
+
+#[no_mangle]
 pub extern "C" fn Servo_CSSSupports(property: *const nsACString, value: *const nsACString) -> bool {
     let property = unsafe { property.as_ref().unwrap().as_str_unchecked() };
     let value = unsafe { value.as_ref().unwrap().as_str_unchecked() };
 
     let base_url = &*DUMMY_BASE_URL;
     let extra_data = ParserContextExtraData::default();
 
     match parse_one_declaration(&property, &value, &base_url, Box::new(StdoutErrorReporter), extra_data) {