Bug 1307357 part 5 - Implement css text getters for ServoStyleRule. r?SimonSapin draft
authorXidorn Quan <me@upsuper.org>
Fri, 04 Nov 2016 11:43:31 +1100
changeset 434694 cd3433258cf44cc630520165647a2e495e36a6bd
parent 434693 68060b4d56daf3c12babb3b272ca3ef6d46cf0a6
child 434695 1dbd39a91066b49c83ca037af35ff6064c2c3e99
push id34791
push userxquan@mozilla.com
push dateMon, 07 Nov 2016 06:12:19 +0000
reviewersSimonSapin
bugs1307357
milestone52.0a1
Bug 1307357 part 5 - Implement css text getters for ServoStyleRule. r?SimonSapin MozReview-Commit-ID: 44bKwabU4eJ
layout/style/ServoBindingList.h
layout/style/ServoStyleRule.cpp
servo/components/style/stylesheets.rs
servo/ports/geckolib/glue.rs
--- a/layout/style/ServoBindingList.h
+++ b/layout/style/ServoBindingList.h
@@ -46,16 +46,22 @@ SERVO_BINDING_FUNC(Servo_StyleSet_Append
 SERVO_BINDING_FUNC(Servo_StyleSet_PrependStyleSheet, void,
                    RawServoStyleSetBorrowed set, RawServoStyleSheetBorrowed sheet)
 SERVO_BINDING_FUNC(Servo_StyleSet_RemoveStyleSheet, void,
                    RawServoStyleSetBorrowed set, RawServoStyleSheetBorrowed sheet)
 SERVO_BINDING_FUNC(Servo_StyleSet_InsertStyleSheetBefore, void,
                    RawServoStyleSetBorrowed set, RawServoStyleSheetBorrowed sheet,
                    RawServoStyleSheetBorrowed reference)
 
+// CSS Rules
+SERVO_BINDING_FUNC(Servo_StyleRule_GetCssText, void,
+                   RawServoStyleRuleBorrowed rule, nsAString* result)
+SERVO_BINDING_FUNC(Servo_StyleRule_GetSelectorText, void,
+                   RawServoStyleRuleBorrowed rule, nsAString* result)
+
 // Animations API
 SERVO_BINDING_FUNC(Servo_ParseProperty,
                    RawServoDeclarationBlockStrong,
                    const nsACString* property, const nsACString* value,
                    const nsACString* base_url, ThreadSafeURIHolder* base,
                    ThreadSafeURIHolder* referrer,
                    ThreadSafePrincipalHolder* principal)
 SERVO_BINDING_FUNC(Servo_RestyleWithAddedDeclaration,
--- a/layout/style/ServoStyleRule.cpp
+++ b/layout/style/ServoStyleRule.cpp
@@ -3,16 +3,18 @@
 /* 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/. */
 
 /* representation of CSSStyleRule for stylo */
 
 #include "mozilla/ServoStyleRule.h"
 
+#include "mozilla/ServoBindings.h"
+
 #include "nsDOMClassInfoID.h"
 
 namespace mozilla {
 
 // -- ServoStyleRule --------------------------------------------------
 
 // QueryInterface implementation for ServoStyleRule
 NS_INTERFACE_MAP_BEGIN(ServoStyleRule)
@@ -57,17 +59,18 @@ ServoStyleRule::GetType(uint16_t* aType)
 {
   *aType = nsIDOMCSSRule::STYLE_RULE;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 ServoStyleRule::GetCssText(nsAString& aCssText)
 {
-  return NS_ERROR_NOT_IMPLEMENTED;
+  Servo_StyleRule_GetCssText(mRawRule, &aCssText);
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 ServoStyleRule::SetCssText(const nsAString& aCssText)
 {
   return NS_OK;
 }
 
@@ -90,23 +93,27 @@ ServoStyleRule::GetCSSRule()
   return this;
 }
 
 /* CSSStyleRule implementation */
 
 NS_IMETHODIMP
 ServoStyleRule::GetSelectorText(nsAString& aSelectorText)
 {
-  return NS_ERROR_NOT_IMPLEMENTED;
+  Servo_StyleRule_GetSelectorText(mRawRule, &aSelectorText);
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 ServoStyleRule::SetSelectorText(const nsAString& aSelectorText)
 {
-  return NS_ERROR_NOT_IMPLEMENTED;
+  // XXX We need to implement this... But Gecko doesn't have this either
+  //     so it's probably okay to leave it unimplemented currently?
+  //     See bug 37468 and mozilla::css::StyleRule::SetSelectorText.
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 ServoStyleRule::GetStyle(nsIDOMCSSStyleDeclaration** aStyle)
 {
   *aStyle = nullptr;
   return NS_ERROR_NOT_IMPLEMENTED;
 }
--- a/servo/components/style/stylesheets.rs
+++ b/servo/components/style/stylesheets.rs
@@ -1,27 +1,28 @@
 /* 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/. */
 
 //! Style sheets and their CSS rules.
 
 use cssparser::{AtRuleParser, Parser, QualifiedRuleParser, decode_stylesheet_bytes};
-use cssparser::{AtRuleType, RuleListParser, Token};
+use cssparser::{AtRuleType, RuleListParser, ToCss, Token};
 use encoding::EncodingRef;
 use error_reporting::ParseErrorReporter;
 use font_face::{FontFaceRule, parse_font_face_block};
 use keyframes::{Keyframe, parse_keyframe_list};
 use media_queries::{Device, MediaQueryList, parse_media_query_list};
 use parking_lot::RwLock;
 use parser::{ParserContext, ParserContextExtraData, log_css_error};
 use properties::{PropertyDeclarationBlock, parse_property_declaration_list};
 use selector_impl::TheSelectorImpl;
 use selectors::parser::{Selector, parse_selector_list};
 use std::cell::Cell;
+use std::fmt;
 use std::sync::Arc;
 use string_cache::{Atom, Namespace};
 use url::Url;
 use viewport::ViewportRule;
 
 
 /// Each style rule has an origin, which determines where it enters the cascade.
 ///
@@ -127,16 +128,51 @@ pub struct MediaRule {
 }
 
 #[derive(Debug)]
 pub struct StyleRule {
     pub selectors: Vec<Selector<TheSelectorImpl>>,
     pub block: Arc<RwLock<PropertyDeclarationBlock>>,
 }
 
+impl StyleRule {
+    /// Serialize the group of selectors for this rule.
+    ///
+    /// https://drafts.csswg.org/cssom/#serialize-a-group-of-selectors
+    pub fn selectors_to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
+        let mut iter = self.selectors.iter();
+        try!(iter.next().unwrap().to_css(dest));
+        for selector in iter {
+            try!(write!(dest, ", "));
+            try!(selector.to_css(dest));
+        }
+        Ok(())
+    }
+}
+
+impl ToCss for StyleRule {
+    // https://drafts.csswg.org/cssom/#serialize-a-css-rule CSSStyleRule
+    fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
+        // Step 1
+        try!(self.selectors_to_css(dest));
+        // Step 2
+        try!(write!(dest, "{{ "));
+        // Step 3
+        let declaration_block = self.block.read();
+        try!(declaration_block.to_css(dest));
+        // Step 4
+        if declaration_block.declarations.len() > 0 {
+            try!(write!(dest, " "));
+        }
+        // Step 5
+        try!(write!(dest, "}}"));
+        Ok(())
+    }
+}
+
 
 impl Stylesheet {
     pub fn from_bytes_iter<I: Iterator<Item=Vec<u8>>>(
             input: I, base_url: Url, protocol_encoding_label: Option<&str>,
             environment_encoding: Option<EncodingRef>, origin: Origin,
             error_reporter: Box<ParseErrorReporter + Send>,
             extra_data: ParserContextExtraData) -> Stylesheet {
         let mut bytes = vec![];
--- a/servo/ports/geckolib/glue.rs
+++ b/servo/ports/geckolib/glue.rs
@@ -281,16 +281,28 @@ pub extern "C" fn Servo_StyleRule_AddRef
 }
 
 #[no_mangle]
 pub extern "C" fn Servo_StyleRule_Release(rule: RawServoStyleRuleBorrowed) -> () {
     unsafe { RwLock::<StyleRule>::release(rule) };
 }
 
 #[no_mangle]
+pub extern "C" fn Servo_StyleRule_GetCssText(rule: RawServoStyleRuleBorrowed, result: *mut nsAString) -> () {
+    let rule = RwLock::<StyleRule>::as_arc(&rule);
+    rule.read().to_css(unsafe { result.as_mut().unwrap() }).unwrap();
+}
+
+#[no_mangle]
+pub extern "C" fn Servo_StyleRule_GetSelectorText(rule: RawServoStyleRuleBorrowed, result: *mut nsAString) -> () {
+    let rule = RwLock::<StyleRule>::as_arc(&rule);
+    rule.read().selectors_to_css(unsafe { result.as_mut().unwrap() }).unwrap();
+}
+
+#[no_mangle]
 pub extern "C" fn Servo_ComputedValues_Get(node: RawGeckoNodeBorrowed)
      -> ServoComputedValuesStrong {
     let node = GeckoNode(node);
 
     // Gecko erroneously calls this function from ServoRestyleManager::RecreateStyleContexts.
     // We plan to fix that, but just support it for now until that code gets rewritten.
     if node.is_text_node() {
         error!("Don't call Servo_ComputedValue_Get() for text nodes");