servo: Merge #18862 - stylo: Use stylo for Element::Closest (from emilio:stylo-element-closest); r=heycam
authorEmilio Cobos Álvarez <emilio@crisal.io>
Fri, 13 Oct 2017 07:22:43 -0500
changeset 386089 39d219f0a5224a9bcf351143b3068f3ea8c50ccc
parent 386088 3cf260e1fb9ce549b29f9200b68e0e85f5e5ae0b
child 386090 388a4fce5b4eb8ae950c02d489bb59599c8f3a10
push id32675
push userarchaeopteryx@coole-files.de
push dateFri, 13 Oct 2017 21:36:21 +0000
treeherdermozilla-central@684b9ee0468e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersheycam
milestone58.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
servo: Merge #18862 - stylo: Use stylo for Element::Closest (from emilio:stylo-element-closest); r=heycam Bug: 1407952 Reviewed-by: heycam MozReview-Commit-ID: 3H2piFT2CfF Source-Repo: https://github.com/servo/servo Source-Revision: 20855c23043802e37c619127ba972948130fc58f
servo/ports/geckolib/glue.rs
--- a/servo/ports/geckolib/glue.rs
+++ b/servo/ports/geckolib/glue.rs
@@ -1,17 +1,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 use cssparser::{Parser, ParserInput};
 use cssparser::ToCss as ParserToCss;
 use env_logger::LogBuilder;
 use malloc_size_of::MallocSizeOfOps;
-use selectors::{self, Element};
+use selectors::{self, Element, NthIndexCache};
 use selectors::matching::{MatchingContext, MatchingMode, matches_selector};
 use servo_arc::{Arc, ArcBorrow, RawOffsetArc};
 use std::cell::RefCell;
 use std::env;
 use std::fmt::Write;
 use std::iter;
 use std::mem;
 use std::ptr;
@@ -1516,16 +1516,46 @@ pub extern "C" fn Servo_StyleRule_Select
 
         let element = GeckoElement(element);
         let mut ctx = MatchingContext::new(matching_mode, None, None, element.owner_document_quirks_mode());
         matches_selector(selector, 0, None, &element, &mut ctx, &mut |_, _| {})
     })
 }
 
 #[no_mangle]
+pub unsafe extern "C" fn Servo_SelectorList_Closest<'a>(
+    element: RawGeckoElementBorrowed<'a>,
+    selectors: RawServoSelectorListBorrowed,
+) -> RawGeckoElementBorrowedOrNull<'a> {
+    use std::borrow::Borrow;
+
+    let mut nth_index_cache = NthIndexCache::default();
+
+    let element = GeckoElement(element);
+    let mut context = MatchingContext::new(
+        MatchingMode::Normal,
+        None,
+        Some(&mut nth_index_cache),
+        element.owner_document_quirks_mode(),
+    );
+    context.scope_element = Some(element.opaque());
+
+    let selectors = ::selectors::SelectorList::from_ffi(selectors).borrow();
+    let mut current = Some(element);
+    while let Some(element) = current.take() {
+        if selectors::matching::matches_selector_list(&selectors, &element, &mut context) {
+            return Some(element.0);
+        }
+        current = element.parent_element();
+    }
+
+    return None;
+}
+
+#[no_mangle]
 pub unsafe extern "C" fn Servo_SelectorList_Matches(
     element: RawGeckoElementBorrowed,
     selectors: RawServoSelectorListBorrowed,
 ) -> bool {
     use std::borrow::Borrow;
 
     let element = GeckoElement(element);
     let mut context = MatchingContext::new(