From fc8d0eeae0b1e6bcaef59a63c62c2dcaf36b1f2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Jim=C3=A9nez=20Moreno?= Date: Tue, 4 Jul 2017 13:13:48 +0200 Subject: [PATCH] stylo: Implement ServoStyleRule::SelectorMatchesElement --- components/style/gecko/generated/bindings.rs | 10 +++++ components/style/gecko/wrapper.rs | 5 +++ ports/geckolib/glue.rs | 42 ++++++++++++++++++++ 3 files changed, 57 insertions(+) diff --git a/components/style/gecko/generated/bindings.rs b/components/style/gecko/generated/bindings.rs index 96d9b3f9dd3..84e4c69cba6 100644 --- a/components/style/gecko/generated/bindings.rs +++ b/components/style/gecko/generated/bindings.rs @@ -2144,6 +2144,16 @@ extern "C" { pub fn Servo_StyleRule_GetSelectorCount(rule: RawServoStyleRuleBorrowed, count: *mut u32); } +extern "C" { + pub fn Servo_StyleRule_SelectorMatchesElement(arg1: + RawServoStyleRuleBorrowed, + arg2: + RawGeckoElementBorrowed, + index: u32, + pseudo_type: + CSSPseudoElementType) + -> bool; +} extern "C" { pub fn Servo_ImportRule_GetHref(rule: RawServoImportRuleBorrowed, result: *mut nsAString); diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs index a7aff7f3a73..3af035cd208 100644 --- a/components/style/gecko/wrapper.rs +++ b/components/style/gecko/wrapper.rs @@ -694,6 +694,11 @@ impl<'le> GeckoElement<'le> { let node = self.as_node(); unsafe { Gecko_GetDocumentLWTheme(node.owner_doc()) } } + + /// Owner document quirks mode getter. + pub fn owner_document_quirks_mode(&self) -> QuirksMode { + self.as_node().owner_doc().mCompatMode.into() + } } /// Converts flags from the layout used by rust-selectors to the layout used diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index 4f47df2ebc0..2b023147b02 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -7,6 +7,7 @@ use cssparser::{Parser, ParserInput}; use cssparser::ToCss as ParserToCss; use env_logger::LogBuilder; use selectors::Element; +use selectors::matching::{MatchingContext, MatchingMode, matches_selector}; use std::env; use std::fmt::Write; use std::ptr; @@ -1255,6 +1256,47 @@ pub extern "C" fn Servo_StyleRule_GetSpecificityAtIndex( }) } +#[no_mangle] +pub extern "C" fn Servo_StyleRule_SelectorMatchesElement(rule: RawServoStyleRuleBorrowed, + element: RawGeckoElementBorrowed, + index: u32, + pseudo_type: CSSPseudoElementType) -> bool { + read_locked_arc(rule, |rule: &StyleRule| { + let index = index as usize; + if index >= rule.selectors.0.len() { + return false; + } + + let selector_and_hashes = &rule.selectors.0[index]; + let mut matching_mode = MatchingMode::Normal; + + match PseudoElement::from_pseudo_type(pseudo_type) { + Some(pseudo) => { + // We need to make sure that the requested pseudo element type + // matches the selector pseudo element type before proceeding. + match selector_and_hashes.selector.pseudo_element() { + Some(selector_pseudo) if *selector_pseudo == pseudo => { + matching_mode = MatchingMode::ForStatelessPseudoElement + }, + _ => return false, + }; + }, + None => { + // Do not attempt to match if a pseudo element is requested and + // this is not a pseudo element selector, or vice versa. + if selector_and_hashes.selector.has_pseudo_element() { + return false; + } + }, + }; + + let element = GeckoElement(element); + let mut ctx = MatchingContext::new(matching_mode, None, element.owner_document_quirks_mode()); + matches_selector(&selector_and_hashes.selector, 0, &selector_and_hashes.hashes, + &element, &mut ctx, &mut |_, _| {}) + }) +} + #[no_mangle] pub extern "C" fn Servo_ImportRule_GetHref(rule: RawServoImportRuleBorrowed, result: *mut nsAString) { read_locked_arc(rule, |rule: &ImportRule| {