aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/layout_wrapper.rs
diff options
context:
space:
mode:
authorSimon Sapin <simon.sapin@exyr.org>2017-05-17 19:41:21 +0200
committerSimon Sapin <simon.sapin@exyr.org>2017-05-18 17:13:13 +0200
commit83c7824fda2377ea2b52414de35d146dd4f6e64d (patch)
tree9f74fea6c9712dd7816aeda7f200cf96167201b8 /components/script/layout_wrapper.rs
parent2ca2c2d2be88176897f7fc76c7b7112f14cb6c9a (diff)
downloadservo-83c7824fda2377ea2b52414de35d146dd4f6e64d.tar.gz
servo-83c7824fda2377ea2b52414de35d146dd4f6e64d.zip
Simplify rust-selectors API for attribute selectors
Diffstat (limited to 'components/script/layout_wrapper.rs')
-rw-r--r--components/script/layout_wrapper.rs95
1 files changed, 53 insertions, 42 deletions
diff --git a/components/script/layout_wrapper.rs b/components/script/layout_wrapper.rs
index 4d1810978d8..773937fce00 100644
--- a/components/script/layout_wrapper.rs
+++ b/components/script/layout_wrapper.rs
@@ -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;
@@ -510,6 +511,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 {
(*self.element.unsafe_get()).get_attr_val_for_layout(namespace, name)
@@ -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,