mirror of
https://github.com/servo/servo.git
synced 2025-07-23 07:13:52 +01:00
Simplify rust-selectors API for attribute selectors
This commit is contained in:
parent
2ca2c2d2be
commit
83c7824fda
15 changed files with 447 additions and 480 deletions
|
@ -50,8 +50,9 @@ use script_layout_interface::{HTMLCanvasData, LayoutNodeType, SVGSVGData, Truste
|
|||
use script_layout_interface::{OpaqueStyleAndLayoutData, PartialPersistentLayoutData};
|
||||
use script_layout_interface::wrapper_traits::{DangerousThreadSafeLayoutNode, GetLayoutData, LayoutNode};
|
||||
use script_layout_interface::wrapper_traits::{PseudoElementType, ThreadSafeLayoutElement, ThreadSafeLayoutNode};
|
||||
use selectors::attr::AttrSelectorOperation;
|
||||
use selectors::matching::{ElementSelectorFlags, MatchingContext};
|
||||
use selectors::parser::{AttrSelector, NamespaceConstraint};
|
||||
use selectors::parser::NamespaceConstraint;
|
||||
use servo_atoms::Atom;
|
||||
use servo_url::ServoUrl;
|
||||
use std::fmt;
|
||||
|
@ -509,6 +510,13 @@ impl<'le> ServoLayoutElement<'le> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn get_attr_enum(&self, namespace: &Namespace, name: &LocalName) -> Option<&AttrValue> {
|
||||
unsafe {
|
||||
(*self.element.unsafe_get()).get_attr_for_layout(namespace, name)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn get_attr(&self, namespace: &Namespace, name: &LocalName) -> Option<&str> {
|
||||
unsafe {
|
||||
|
@ -558,32 +566,9 @@ fn as_element<'le>(node: LayoutJS<Node>) -> Option<ServoLayoutElement<'le>> {
|
|||
node.downcast().map(ServoLayoutElement::from_layout_js)
|
||||
}
|
||||
|
||||
impl<'le> ::selectors::MatchAttrGeneric for ServoLayoutElement<'le> {
|
||||
impl<'le> ::selectors::Element for ServoLayoutElement<'le> {
|
||||
type Impl = SelectorImpl;
|
||||
|
||||
fn match_attr<F>(&self, attr: &AttrSelector<SelectorImpl>, test: F) -> bool
|
||||
where F: Fn(&str) -> bool {
|
||||
use ::selectors::Element;
|
||||
let name = if self.is_html_element_in_html_document() {
|
||||
&attr.lower_name
|
||||
} else {
|
||||
&attr.name
|
||||
};
|
||||
match attr.namespace {
|
||||
NamespaceConstraint::Specific(ref ns) => {
|
||||
self.get_attr(&ns.url, name).map_or(false, |attr| test(attr))
|
||||
},
|
||||
NamespaceConstraint::Any => {
|
||||
let attrs = unsafe {
|
||||
(*self.element.unsafe_get()).get_attr_vals_for_layout(name)
|
||||
};
|
||||
attrs.iter().any(|attr| test(*attr))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'le> ::selectors::Element for ServoLayoutElement<'le> {
|
||||
fn parent_element(&self) -> Option<ServoLayoutElement<'le>> {
|
||||
unsafe {
|
||||
self.element.upcast().parent_node_ref().and_then(as_element)
|
||||
|
@ -620,6 +605,25 @@ impl<'le> ::selectors::Element for ServoLayoutElement<'le> {
|
|||
None
|
||||
}
|
||||
|
||||
fn attr_matches(&self,
|
||||
ns: &NamespaceConstraint<SelectorImpl>,
|
||||
local_name: &LocalName,
|
||||
operation: &AttrSelectorOperation<SelectorImpl>)
|
||||
-> bool {
|
||||
match *ns {
|
||||
NamespaceConstraint::Specific(ref ns) => {
|
||||
self.get_attr_enum(&ns.url, local_name)
|
||||
.map_or(false, |value| value.eval_selector(operation))
|
||||
}
|
||||
NamespaceConstraint::Any => {
|
||||
let values = unsafe {
|
||||
(*self.element.unsafe_get()).get_attr_vals_for_layout(local_name)
|
||||
};
|
||||
values.iter().any(|value| value.eval_selector(operation))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn is_root(&self) -> bool {
|
||||
match self.as_node().parent_node() {
|
||||
None => false,
|
||||
|
@ -1075,6 +1079,10 @@ impl<'le> ThreadSafeLayoutElement for ServoThreadSafeLayoutElement<'le> {
|
|||
self.element
|
||||
}
|
||||
|
||||
fn get_attr_enum(&self, namespace: &Namespace, name: &LocalName) -> Option<&AttrValue> {
|
||||
self.element.get_attr_enum(namespace, name)
|
||||
}
|
||||
|
||||
fn get_attr<'a>(&'a self, namespace: &Namespace, name: &LocalName) -> Option<&'a str> {
|
||||
self.element.get_attr(namespace, name)
|
||||
}
|
||||
|
@ -1096,25 +1104,9 @@ impl<'le> ThreadSafeLayoutElement for ServoThreadSafeLayoutElement<'le> {
|
|||
///
|
||||
/// Note that the element implementation is needed only for selector matching,
|
||||
/// not for inheritance (styles are inherited appropiately).
|
||||
impl<'le> ::selectors::MatchAttrGeneric for ServoThreadSafeLayoutElement<'le> {
|
||||
impl<'le> ::selectors::Element for ServoThreadSafeLayoutElement<'le> {
|
||||
type Impl = SelectorImpl;
|
||||
|
||||
fn match_attr<F>(&self, attr: &AttrSelector<SelectorImpl>, test: F) -> bool
|
||||
where F: Fn(&str) -> bool {
|
||||
match attr.namespace {
|
||||
NamespaceConstraint::Specific(ref ns) => {
|
||||
self.get_attr(&ns.url, &attr.name).map_or(false, |attr| test(attr))
|
||||
},
|
||||
NamespaceConstraint::Any => {
|
||||
unsafe {
|
||||
(*self.element.element.unsafe_get()).get_attr_vals_for_layout(&attr.name).iter()
|
||||
.any(|attr| test(*attr))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<'le> ::selectors::Element for ServoThreadSafeLayoutElement<'le> {
|
||||
fn parent_element(&self) -> Option<Self> {
|
||||
warn!("ServoThreadSafeLayoutElement::parent_element called");
|
||||
None
|
||||
|
@ -1166,6 +1158,25 @@ impl<'le> ::selectors::Element for ServoThreadSafeLayoutElement<'le> {
|
|||
false
|
||||
}
|
||||
|
||||
fn attr_matches(&self,
|
||||
ns: &NamespaceConstraint<SelectorImpl>,
|
||||
local_name: &LocalName,
|
||||
operation: &AttrSelectorOperation<SelectorImpl>)
|
||||
-> bool {
|
||||
match *ns {
|
||||
NamespaceConstraint::Specific(ref ns) => {
|
||||
self.get_attr_enum(&ns.url, local_name)
|
||||
.map_or(false, |value| value.eval_selector(operation))
|
||||
}
|
||||
NamespaceConstraint::Any => {
|
||||
let values = unsafe {
|
||||
(*self.element.element.unsafe_get()).get_attr_vals_for_layout(local_name)
|
||||
};
|
||||
values.iter().any(|v| v.eval_selector(operation))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn match_non_ts_pseudo_class<F>(&self,
|
||||
_: &NonTSPseudoClass,
|
||||
_: &mut MatchingContext,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue