style: Add FFI function to parse a @counter-style descriptor. draft
authorCameron McCormack <cam@mcc.id.au>
Fri, 24 Nov 2017 16:48:12 +0800
changeset 703087 1af913309806836ec8af53c91b247942ec979f28
parent 703086 6d821a5b42543fe700604fa255cf87e86e752193
child 703088 a7d1b67e4e5723ee21abf198555ee635e5a6b3e3
push id90704
push userbmo:cam@mcc.id.au
push dateFri, 24 Nov 2017 09:30:23 +0000
milestone59.0a1
style: Add FFI function to parse a @counter-style descriptor. MozReview-Commit-ID: CEYdvsfYx7l
servo/components/style/counter_style/mod.rs
servo/ports/geckolib/glue.rs
--- a/servo/components/style/counter_style/mod.rs
+++ b/servo/components/style/counter_style/mod.rs
@@ -6,17 +6,17 @@
 //!
 //! [counter-style]: https://drafts.csswg.org/css-counter-styles/
 
 use Atom;
 use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser};
 use cssparser::{Parser, Token, serialize_identifier, CowRcStr};
 use error_reporting::{ContextualParseError, ParseErrorReporter};
 #[cfg(feature = "gecko")] use gecko::rules::CounterStyleDescriptors;
-#[cfg(feature = "gecko")] use gecko_bindings::structs::nsCSSCounterDesc;
+#[cfg(feature = "gecko")] use gecko_bindings::structs::{nsCSSCounterDesc, nsCSSValue};
 use parser::{ParserContext, ParserErrorContext, Parse};
 use selectors::parser::SelectorParseErrorKind;
 use shared_lock::{SharedRwLockReadGuard, ToCssWithGuard};
 #[allow(unused_imports)] use std::ascii::AsciiExt;
 use std::borrow::Cow;
 use std::fmt;
 use std::ops::Range;
 use style_traits::{Comma, OneOrMoreSeparated, ParseError, StyleParseErrorKind, ToCss};
@@ -220,16 +220,40 @@ macro_rules! counter_style_descriptors {
                         dest.write_str(concat!("  ", $name, ": "))?;
                         ToCss::to_css(value, dest)?;
                         dest.write_str(";\n")?;
                     }
                 )+
                 dest.write_str("}")
             }
         }
+
+        /// Parse a descriptor into an `nsCSSValue`.
+        #[cfg(feature = "gecko")]
+        pub fn parse_counter_style_descriptor<'i, 't>(
+            context: &ParserContext,
+            input: &mut Parser<'i, 't>,
+            descriptor: nsCSSCounterDesc,
+            value: &mut nsCSSValue
+        ) -> Result<(), ParseError<'i>> {
+            match descriptor {
+                $(
+                    nsCSSCounterDesc::$gecko_ident => {
+                        let v: $ty =
+                            input.parse_entirely(|i| Parse::parse(context, i))?;
+                        value.set_from(v);
+                    }
+                )*
+                nsCSSCounterDesc::eCSSCounterDesc_COUNT |
+                nsCSSCounterDesc::eCSSCounterDesc_UNKNOWN => {
+                    panic!("invalid counter descriptor");
+                }
+            }
+            Ok(())
+        }
     }
 }
 
 counter_style_descriptors! {
     /// <https://drafts.csswg.org/css-counter-styles/#counter-style-system>
     "system" system / eCSSCounterDesc_System: System = {
         System::Symbolic
     }
--- a/servo/ports/geckolib/glue.rs
+++ b/servo/ports/geckolib/glue.rs
@@ -100,16 +100,18 @@ use style::gecko_bindings::structs::RawS
 use style::gecko_bindings::structs::RawServoSourceSizeList;
 use style::gecko_bindings::structs::SeenPtrs;
 use style::gecko_bindings::structs::ServoElementSnapshotTable;
 use style::gecko_bindings::structs::ServoStyleSetSizes;
 use style::gecko_bindings::structs::ServoTraversalFlags;
 use style::gecko_bindings::structs::StyleRuleInclusion;
 use style::gecko_bindings::structs::URLExtraData;
 use style::gecko_bindings::structs::gfxFontFeatureValueSet;
+use style::gecko_bindings::structs::nsCSSCounterDesc;
+use style::gecko_bindings::structs::nsCSSValue;
 use style::gecko_bindings::structs::nsCSSValueSharedList;
 use style::gecko_bindings::structs::nsCompatibility;
 use style::gecko_bindings::structs::nsIDocument;
 use style::gecko_bindings::structs::nsStyleTransformMatrix::MatrixTransformOperator;
 use style::gecko_bindings::structs::nsTArray;
 use style::gecko_bindings::structs::nsresult;
 use style::gecko_bindings::sugar::ownership::{FFIArcHelpers, HasFFI, HasArcFFI};
 use style::gecko_bindings::sugar::ownership::{HasSimpleFFI, Strong};
@@ -4698,8 +4700,41 @@ pub extern "C" fn Servo_ParseCounterStyl
 ) -> *mut nsAtom {
     let value = unsafe { value.as_ref().unwrap().as_str_unchecked() };
     let mut input = ParserInput::new(&value);
     match Parser::new(&mut input).parse_entirely(counter_style::parse_counter_style_name) {
         Ok(name) => name.0.into_addrefed(),
         Err(_) => ptr::null_mut(),
     }
 }
+
+#[no_mangle]
+pub extern "C" fn Servo_ParseCounterStyleDescriptor(
+    descriptor: nsCSSCounterDesc,
+    value: *const nsACString,
+    raw_extra_data: *mut URLExtraData,
+    result: *mut nsCSSValue,
+) -> bool {
+    let value = unsafe { value.as_ref().unwrap().as_str_unchecked() };
+    let url_data = unsafe {
+        if raw_extra_data.is_null() {
+            dummy_url_data()
+        } else {
+            RefPtr::from_ptr_ref(&raw_extra_data)
+        }
+    };
+    let result = unsafe { result.as_mut().unwrap() };
+    let mut input = ParserInput::new(&value);
+    let mut parser = Parser::new(&mut input);
+    let context = ParserContext::new(
+        Origin::Author,
+        url_data,
+        Some(CssRuleType::CounterStyle),
+        ParsingMode::DEFAULT,
+        QuirksMode::NoQuirks,
+    );
+    counter_style::parse_counter_style_descriptor(
+        &context,
+        &mut parser,
+        descriptor,
+        result,
+    ).is_ok()
+}