Auto merge of #16066 - Manishearth:stylo-nonts, r=emilio

stylo: Support all non-ts pseudos with an argument

r=emilio https://bugzilla.mozilla.org/show_bug.cgi?id=1341086#c34

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/16066)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2017-03-21 20:20:28 -07:00 committed by GitHub
commit 82b88aad45
4 changed files with 43 additions and 5 deletions

View file

@ -67,6 +67,11 @@ macro_rules! apply_non_ts_list {
], ],
string: [ string: [
("-moz-system-metric", MozSystemMetric, mozSystemMetric, _, PSEUDO_CLASS_INTERNAL), ("-moz-system-metric", MozSystemMetric, mozSystemMetric, _, PSEUDO_CLASS_INTERNAL),
("-moz-locale-dir", MozLocaleDir, mozLocaleDir, _, PSEUDO_CLASS_INTERNAL),
("-moz-empty-except-children-with-localname", MozEmptyExceptChildrenWithLocalname,
mozEmptyExceptChildrenWithLocalname, _, PSEUDO_CLASS_INTERNAL),
("dir", Dir, dir, _, _),
("lang", Lang, lang, _, _),
] ]
} }
} }

View file

@ -151,7 +151,7 @@ macro_rules! pseudo_class_name {
)* )*
$( $(
#[doc = $s_css] #[doc = $s_css]
$s_name(Box<str>), $s_name(Box<[u16]>),
)* )*
/// The non-standard `:-moz-any` pseudo-class. /// The non-standard `:-moz-any` pseudo-class.
MozAny(Vec<ComplexSelector<SelectorImpl>>), MozAny(Vec<ComplexSelector<SelectorImpl>>),
@ -162,13 +162,20 @@ apply_non_ts_list!(pseudo_class_name);
impl ToCss for NonTSPseudoClass { impl ToCss for NonTSPseudoClass {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
use cssparser::CssStringWriter;
use fmt::Write;
macro_rules! pseudo_class_serialize { macro_rules! pseudo_class_serialize {
(bare: [$(($css:expr, $name:ident, $gecko_type:tt, $state:tt, $flags:tt),)*], (bare: [$(($css:expr, $name:ident, $gecko_type:tt, $state:tt, $flags:tt),)*],
string: [$(($s_css:expr, $s_name:ident, $s_gecko_type:tt, $s_state:tt, $s_flags:tt),)*]) => { string: [$(($s_css:expr, $s_name:ident, $s_gecko_type:tt, $s_state:tt, $s_flags:tt),)*]) => {
match *self { match *self {
$(NonTSPseudoClass::$name => concat!(":", $css),)* $(NonTSPseudoClass::$name => concat!(":", $css),)*
$(NonTSPseudoClass::$s_name(ref s) => { $(NonTSPseudoClass::$s_name(ref s) => {
return dest.write_str(&format!(":{}({})", $s_css, s)) write!(dest, ":{}(", $s_css)?;
{
let mut css = CssStringWriter::new(dest);
css.write_str(&String::from_utf16(&s).unwrap())?;
}
return dest.write_str(")")
}, )* }, )*
NonTSPseudoClass::MozAny(ref selectors) => { NonTSPseudoClass::MozAny(ref selectors) => {
dest.write_str(":-moz-any(")?; dest.write_str(":-moz-any(")?;
@ -334,8 +341,11 @@ impl<'a> ::selectors::Parser for SelectorParser<'a> {
string: [$(($s_css:expr, $s_name:ident, $s_gecko_type:tt, $s_state:tt, $s_flags:tt),)*]) => { string: [$(($s_css:expr, $s_name:ident, $s_gecko_type:tt, $s_state:tt, $s_flags:tt),)*]) => {
match_ignore_ascii_case! { &name, match_ignore_ascii_case! { &name,
$($s_css => { $($s_css => {
let name = String::from(parser.expect_ident_or_string()?).into_boxed_str(); let name = parser.expect_ident_or_string()?;
NonTSPseudoClass::$s_name(name) // convert to null terminated utf16 string
// since that's what Gecko deals with
let utf16: Vec<u16> = name.encode_utf16().chain(Some(0u16)).collect();
NonTSPseudoClass::$s_name(utf16.into_boxed_slice())
}, )* }, )*
"-moz-any" => { "-moz-any" => {
let selectors = parser.parse_comma_separated(|input| { let selectors = parser.parse_comma_separated(|input| {

View file

@ -35,6 +35,7 @@ use gecko_bindings::bindings::Gecko_GetAnimationRule;
use gecko_bindings::bindings::Gecko_GetHTMLPresentationAttrDeclarationBlock; use gecko_bindings::bindings::Gecko_GetHTMLPresentationAttrDeclarationBlock;
use gecko_bindings::bindings::Gecko_GetStyleAttrDeclarationBlock; use gecko_bindings::bindings::Gecko_GetStyleAttrDeclarationBlock;
use gecko_bindings::bindings::Gecko_GetStyleContext; use gecko_bindings::bindings::Gecko_GetStyleContext;
use gecko_bindings::bindings::Gecko_MatchStringArgPseudo;
use gecko_bindings::bindings::Gecko_UpdateAnimations; use gecko_bindings::bindings::Gecko_UpdateAnimations;
use gecko_bindings::structs; use gecko_bindings::structs;
use gecko_bindings::structs::{RawGeckoElement, RawGeckoNode}; use gecko_bindings::structs::{RawGeckoElement, RawGeckoNode};
@ -702,10 +703,26 @@ impl<'le> ::selectors::Element for GeckoElement<'le> {
NonTSPseudoClass::MozBrowserFrame => unsafe { NonTSPseudoClass::MozBrowserFrame => unsafe {
Gecko_MatchesElement(pseudo_class.to_gecko_pseudoclasstype().unwrap(), self.0) Gecko_MatchesElement(pseudo_class.to_gecko_pseudoclasstype().unwrap(), self.0)
}, },
NonTSPseudoClass::MozSystemMetric(_) => false,
NonTSPseudoClass::MozAny(ref sels) => { NonTSPseudoClass::MozAny(ref sels) => {
sels.iter().any(|s| matches_complex_selector(s, self, None, relations, flags)) sels.iter().any(|s| matches_complex_selector(s, self, None, relations, flags))
} }
NonTSPseudoClass::MozSystemMetric(ref s) |
NonTSPseudoClass::MozLocaleDir(ref s) |
NonTSPseudoClass::MozEmptyExceptChildrenWithLocalname(ref s) |
NonTSPseudoClass::Dir(ref s) |
NonTSPseudoClass::Lang(ref s) => {
use selectors::matching::HAS_SLOW_SELECTOR;
unsafe {
let mut set_slow_selector = false;
let matches = Gecko_MatchStringArgPseudo(self.0,
pseudo_class.to_gecko_pseudoclasstype().unwrap(),
s.as_ptr(), &mut set_slow_selector);
if set_slow_selector {
*flags |= HAS_SLOW_SELECTOR;
}
matches
}
}
} }
} }

View file

@ -1003,6 +1003,12 @@ extern "C" {
RawGeckoPresContextBorrowed) RawGeckoPresContextBorrowed)
-> nscolor; -> nscolor;
} }
extern "C" {
pub fn Gecko_MatchStringArgPseudo(element: RawGeckoElementBorrowed,
type_: CSSPseudoClassType,
ident: *const u16,
set_slow_selector: *mut bool) -> bool;
}
extern "C" { extern "C" {
pub fn Gecko_Construct_Default_nsStyleFont(ptr: *mut nsStyleFont, pub fn Gecko_Construct_Default_nsStyleFont(ptr: *mut nsStyleFont,
pres_context: pres_context: