diff --git a/components/style/build_gecko.rs b/components/style/build_gecko.rs index b4c26cb4f6d..d32b3a9f62f 100644 --- a/components/style/build_gecko.rs +++ b/components/style/build_gecko.rs @@ -319,6 +319,7 @@ mod bindings { .include(add_include("mozilla/dom/NameSpaceConstants.h")) .include(add_include("mozilla/LookAndFeel.h")) .include(add_include("mozilla/ServoBindings.h")) + .include(add_include("nsCSSCounterStyleRule.h")) .include(add_include("nsCSSFontFaceRule.h")) .include(add_include("nsMediaFeatures.h")) .include(add_include("nsMediaList.h")) @@ -402,6 +403,7 @@ mod bindings { "nsBorderColors", "nscolor", "nsChangeHint", + "nsCSSCounterStyleRule", "nsCSSFontFaceRule", "nsCSSKeyword", "nsCSSPropertyID", @@ -691,6 +693,7 @@ mod bindings { "StyleBasicShapeType", "StyleShapeSource", "StyleTransition", + "nsCSSCounterStyleRule", "nsCSSFontFaceRule", "nsCSSKeyword", "nsCSSPropertyID", diff --git a/components/style/counter_style/mod.rs b/components/style/counter_style/mod.rs index ca27a650334..adf212e09b6 100644 --- a/components/style/counter_style/mod.rs +++ b/components/style/counter_style/mod.rs @@ -49,9 +49,9 @@ pub fn parse_counter_style_name(input: &mut Parser) -> Result { /// Parse the body (inside `{}`) of an @counter-style rule pub fn parse_counter_style_body(name: CustomIdent, context: &ParserContext, input: &mut Parser) - -> Result { + -> Result { let start = input.position(); - let mut rule = CounterStyleRule::empty(name); + let mut rule = CounterStyleRuleData::empty(name); { let parser = CounterStyleRuleParser { context: context, @@ -108,7 +108,7 @@ pub fn parse_counter_style_body(name: CustomIdent, context: &ParserContext, inpu struct CounterStyleRuleParser<'a, 'b: 'a> { context: &'a ParserContext<'b>, - rule: &'a mut CounterStyleRule, + rule: &'a mut CounterStyleRuleData, } /// Default methods reject all at rules. @@ -143,7 +143,7 @@ macro_rules! counter_style_descriptors { ) => { /// An @counter-style rule #[derive(Debug)] - pub struct CounterStyleRule { + pub struct CounterStyleRuleData { name: CustomIdent, $( #[$doc] @@ -151,9 +151,9 @@ macro_rules! counter_style_descriptors { )+ } - impl CounterStyleRule { + impl CounterStyleRuleData { fn empty(name: CustomIdent) -> Self { - CounterStyleRule { + CounterStyleRuleData { name: name, $( $ident: None, @@ -161,6 +161,11 @@ macro_rules! counter_style_descriptors { } } + /// Get the name of the counter style rule. + pub fn name(&self) -> &CustomIdent { + &self.name + } + $( accessor!(#[$doc] $name $ident: $ty = $initial); )+ @@ -197,7 +202,7 @@ macro_rules! counter_style_descriptors { } } - impl ToCssWithGuard for CounterStyleRule { + impl ToCssWithGuard for CounterStyleRuleData { fn to_css(&self, _guard: &SharedRwLockReadGuard, dest: &mut W) -> fmt::Result where W: fmt::Write { dest.write_str("@counter-style ")?; diff --git a/components/style/gecko/rules.rs b/components/style/gecko/rules.rs index 7af5fc599b7..49e33ab16cc 100644 --- a/components/style/gecko/rules.rs +++ b/components/style/gecko/rules.rs @@ -10,7 +10,8 @@ use counter_style; use cssparser::UnicodeRange; use font_face::{FontFaceRuleData, Source}; use gecko_bindings::bindings; -use gecko_bindings::structs::{self, nsCSSFontFaceRule, nsCSSValue, nsCSSCounterDesc}; +use gecko_bindings::structs::{self, nsCSSFontFaceRule, nsCSSValue}; +use gecko_bindings::structs::{nsCSSCounterDesc, nsCSSCounterStyleRule}; use gecko_bindings::sugar::ns_css_value::ToNsCssValue; use gecko_bindings::sugar::refptr::{RefPtr, UniqueRefPtr}; use shared_lock::{ToCssWithGuard, SharedRwLockReadGuard}; @@ -137,6 +138,31 @@ impl ToCssWithGuard for FontFaceRule { } } +/// A @counter-style rule +pub type CounterStyleRule = RefPtr; + +impl From for CounterStyleRule { + fn from(data: counter_style::CounterStyleRuleData) -> CounterStyleRule { + let mut result = unsafe { + UniqueRefPtr::from_addrefed( + bindings::Gecko_CSSCounterStyle_Create(data.name().0.as_ptr())) + }; + data.set_descriptors(&mut result.mValues); + result.get() + } +} + +impl ToCssWithGuard for CounterStyleRule { + fn to_css(&self, _guard: &SharedRwLockReadGuard, dest: &mut W) -> fmt::Result + where W: fmt::Write { + ns_auto_string!(css_text); + unsafe { + bindings::Gecko_CSSCounterStyle_GetCssText(self.get(), &mut *css_text); + } + write!(dest, "{}", css_text) + } +} + /// The type of nsCSSCounterStyleRule::mValues pub type CounterStyleDescriptors = [nsCSSValue; nsCSSCounterDesc::eCSSCounterDesc_COUNT as usize]; diff --git a/components/style/gecko_bindings/sugar/refptr.rs b/components/style/gecko_bindings/sugar/refptr.rs index b90477e13a4..77c6ca4f3c3 100644 --- a/components/style/gecko_bindings/sugar/refptr.rs +++ b/components/style/gecko_bindings/sugar/refptr.rs @@ -255,6 +255,8 @@ macro_rules! impl_refcount { impl_refcount!(::gecko_bindings::structs::nsCSSFontFaceRule, Gecko_CSSFontFaceRule_AddRef, Gecko_CSSFontFaceRule_Release); +impl_refcount!(::gecko_bindings::structs::nsCSSCounterStyleRule, + Gecko_CSSCounterStyleRule_AddRef, Gecko_CSSCounterStyleRule_Release); // Companion of NS_DECL_THREADSAFE_FFI_REFCOUNTING. // diff --git a/components/style/stylesheets.rs b/components/style/stylesheets.rs index 98c13948121..97907d7082b 100644 --- a/components/style/stylesheets.rs +++ b/components/style/stylesheets.rs @@ -8,7 +8,9 @@ use {Atom, Prefix, Namespace}; use context::QuirksMode; -use counter_style::{CounterStyleRule, parse_counter_style_name, parse_counter_style_body}; +use counter_style::{parse_counter_style_name, parse_counter_style_body}; +#[cfg(feature = "servo")] +use counter_style::CounterStyleRuleData; use cssparser::{AtRuleParser, Parser, QualifiedRuleParser}; use cssparser::{AtRuleType, RuleListParser, parse_one_rule, SourceLocation}; use cssparser::ToCss as ParserToCss; @@ -18,7 +20,7 @@ use error_reporting::{ParseErrorReporter, NullReporter}; use font_face::FontFaceRuleData; use font_face::parse_font_face_block; #[cfg(feature = "gecko")] -pub use gecko::rules::FontFaceRule; +pub use gecko::rules::{CounterStyleRule, FontFaceRule}; #[cfg(feature = "gecko")] use gecko_bindings::structs::URLExtraData; #[cfg(feature = "gecko")] @@ -697,6 +699,10 @@ impl ToCssWithGuard for StyleRule { #[cfg(feature = "servo")] pub type FontFaceRule = FontFaceRuleData; +/// A @counter-style rule +#[cfg(feature = "servo")] +pub type CounterStyleRule = CounterStyleRuleData; + #[derive(Debug)] /// A @-moz-document rule pub struct DocumentRule { @@ -1282,7 +1288,7 @@ impl<'a, 'b> AtRuleParser for NestedRuleParser<'a, 'b> { AtRulePrelude::CounterStyle(name) => { let context = ParserContext::new_with_rule_type(self.context, Some(CssRuleType::CounterStyle)); Ok(CssRule::CounterStyle(Arc::new(self.shared_lock.wrap( - parse_counter_style_body(name, &context, input)?)))) + parse_counter_style_body(name, &context, input)?.into())))) } AtRulePrelude::Media(media_queries, location) => { Ok(CssRule::Media(Arc::new(self.shared_lock.wrap(MediaRule { diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index 1a673afc790..2d40842b0bb 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -61,7 +61,8 @@ use style::gecko_bindings::structs; use style::gecko_bindings::structs::{CSSPseudoElementType, CompositeOperation}; use style::gecko_bindings::structs::{RawServoStyleRule, ServoStyleSheet}; use style::gecko_bindings::structs::{SheetParsingMode, nsIAtom, nsCSSPropertyID}; -use style::gecko_bindings::structs::{nsRestyleHint, nsChangeHint, nsCSSFontFaceRule}; +use style::gecko_bindings::structs::{nsCSSFontFaceRule, nsCSSCounterStyleRule}; +use style::gecko_bindings::structs::{nsRestyleHint, nsChangeHint}; use style::gecko_bindings::structs::Loader; use style::gecko_bindings::structs::RawGeckoPresContextOwned; use style::gecko_bindings::structs::ServoElementSnapshotTable; @@ -871,19 +872,28 @@ impl_group_rule_funcs! { (Document, DocumentRule, RawServoDocumentRule), to_css: Servo_DocumentRule_GetCssText, } -#[no_mangle] -pub extern "C" fn Servo_CssRules_GetFontFaceRuleAt(rules: ServoCssRulesBorrowed, index: u32) - -> *mut nsCSSFontFaceRule -{ - let global_style_data = &*GLOBAL_STYLE_DATA; - let guard = global_style_data.shared_lock.read(); - let rules = Locked::::as_arc(&rules).read_with(&guard); - match rules.0[index as usize] { - CssRule::FontFace(ref rule) => rule.read_with(&guard).get(), - _ => unreachable!("Servo_CssRules_GetFontFaceRuleAt should only be called on a FontFace rule"), +macro_rules! impl_getter_for_embedded_rule { + ($getter:ident: $name:ident -> $ty:ty) => { + #[no_mangle] + pub extern "C" fn $getter(rules: ServoCssRulesBorrowed, index: u32) -> *mut $ty + { + let global_style_data = &*GLOBAL_STYLE_DATA; + let guard = global_style_data.shared_lock.read(); + let rules = Locked::::as_arc(&rules).read_with(&guard); + match rules.0[index as usize] { + CssRule::$name(ref rule) => rule.read_with(&guard).get(), + _ => unreachable!(concat!(stringify!($getter), " should only be called on a ", + stringify!($name), " rule")), + } + } } } +impl_getter_for_embedded_rule!(Servo_CssRules_GetFontFaceRuleAt: + FontFace -> nsCSSFontFaceRule); +impl_getter_for_embedded_rule!(Servo_CssRules_GetCounterStyleRuleAt: + CounterStyle -> nsCSSCounterStyleRule); + #[no_mangle] pub extern "C" fn Servo_StyleRule_GetStyle(rule: RawServoStyleRuleBorrowed) -> RawServoDeclarationBlockStrong { read_locked_arc(rule, |rule: &StyleRule| {