diff options
-rw-r--r-- | components/style/gecko/generated/bindings.rs | 10 | ||||
-rw-r--r-- | components/style/gecko/wrapper.rs | 5 | ||||
-rw-r--r-- | ports/geckolib/glue.rs | 42 |
3 files changed, 57 insertions, 0 deletions
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 @@ -2145,6 +2145,16 @@ extern "C" { 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; @@ -1256,6 +1257,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| { write!(unsafe { &mut *result }, "{}", rule.url.as_str()).unwrap(); |