aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom
diff options
context:
space:
mode:
authorbors-servo <lbergstrom+bors@mozilla.com>2017-05-18 18:45:20 -0500
committerGitHub <noreply@github.com>2017-05-18 18:45:20 -0500
commit640b16634f2828bad46ab6d78e785dfc2025ab46 (patch)
tree39ceb66e43604f1dcf2846b3d56b0726b4750451 /components/script/dom
parent0b3fd8de767c6ad6ea2fd983c396f5c0a20becfc (diff)
parentb359e3fcb40c03b1cb801caa7943eb72881509cf (diff)
downloadservo-640b16634f2828bad46ab6d78e785dfc2025ab46.tar.gz
servo-640b16634f2828bad46ab6d78e785dfc2025ab46.zip
Auto merge of #16915 - servo:attr-selectors, r=nox,emilio
Shrink selectors::Component, implement attr selector (in)case-sensitivity * https://bugzilla.mozilla.org/show_bug.cgi?id=1364148 * https://bugzilla.mozilla.org/show_bug.cgi?id=1364162 * https://bugzilla.mozilla.org/show_bug.cgi?id=1363531 * Fixes #3322 <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/16915) <!-- Reviewable:end -->
Diffstat (limited to 'components/script/dom')
-rw-r--r--components/script/dom/element.rs75
1 files changed, 30 insertions, 45 deletions
diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs
index 6b844dd83a2..55175fd45c6 100644
--- a/components/script/dom/element.rs
+++ b/components/script/dom/element.rs
@@ -86,9 +86,9 @@ use net_traits::request::CorsSettings;
use ref_filter_map::ref_filter_map;
use script_layout_interface::message::ReflowQueryType;
use script_thread::Runnable;
+use selectors::attr::{AttrSelectorOperation, NamespaceConstraint};
use selectors::matching::{ElementSelectorFlags, MatchingContext, MatchingMode, matches_selector_list};
use selectors::matching::{HAS_EDGE_CHILD_SELECTOR, HAS_SLOW_SELECTOR, HAS_SLOW_SELECTOR_LATER_SIBLINGS};
-use selectors::parser::{AttrSelector, NamespaceConstraint};
use servo_atoms::Atom;
use std::ascii::AsciiExt;
use std::borrow::Cow;
@@ -288,7 +288,7 @@ pub trait RawLayoutElementHelpers {
-> Option<&'a AttrValue>;
unsafe fn get_attr_val_for_layout<'a>(&'a self, namespace: &Namespace, name: &LocalName)
-> Option<&'a str>;
- unsafe fn get_attr_vals_for_layout<'a>(&'a self, name: &LocalName) -> Vec<&'a str>;
+ unsafe fn get_attr_vals_for_layout<'a>(&'a self, name: &LocalName) -> Vec<&'a AttrValue>;
}
#[inline]
@@ -314,6 +314,7 @@ impl RawLayoutElementHelpers for Element {
})
}
+ #[inline]
unsafe fn get_attr_val_for_layout<'a>(&'a self, namespace: &Namespace, name: &LocalName)
-> Option<&'a str> {
get_attr_for_layout(self, namespace, name).map(|attr| {
@@ -322,12 +323,12 @@ impl RawLayoutElementHelpers for Element {
}
#[inline]
- unsafe fn get_attr_vals_for_layout<'a>(&'a self, name: &LocalName) -> Vec<&'a str> {
+ unsafe fn get_attr_vals_for_layout<'a>(&'a self, name: &LocalName) -> Vec<&'a AttrValue> {
let attrs = self.attrs.borrow_for_layout();
attrs.iter().filter_map(|attr| {
let attr = attr.to_layout();
if *name == attr.local_name_atom_forever() {
- Some(attr.value_ref_forever())
+ Some(attr.value_forever())
} else {
None
}
@@ -2352,37 +2353,9 @@ impl VirtualMethods for Element {
}
}
-impl<'a> ::selectors::MatchAttrGeneric for Root<Element> {
+impl<'a> ::selectors::Element for Root<Element> {
type Impl = SelectorImpl;
- fn match_attr<F>(&self, attr: &AttrSelector<SelectorImpl>, test: F) -> bool
- where F: Fn(&str) -> bool
- {
- use ::selectors::Element;
- let local_name = {
- if self.is_html_element_in_html_document() {
- &attr.lower_name
- } else {
- &attr.name
- }
- };
- match attr.namespace {
- NamespaceConstraint::Specific(ref ns) => {
- self.get_attribute(&ns.url, local_name)
- .map_or(false, |attr| {
- test(&attr.value())
- })
- },
- NamespaceConstraint::Any => {
- self.attrs.borrow().iter().any(|attr| {
- attr.local_name() == local_name && test(&attr.value())
- })
- }
- }
- }
-}
-
-impl<'a> ::selectors::Element for Root<Element> {
fn parent_element(&self) -> Option<Root<Element>> {
self.upcast::<Node>().GetParentElement()
}
@@ -2412,6 +2385,25 @@ impl<'a> ::selectors::Element for Root<Element> {
self.node.following_siblings().filter_map(Root::downcast).next()
}
+ fn attr_matches(&self,
+ ns: &NamespaceConstraint<&Namespace>,
+ local_name: &LocalName,
+ operation: &AttrSelectorOperation<&String>)
+ -> bool {
+ match *ns {
+ NamespaceConstraint::Specific(ref ns) => {
+ self.get_attribute(ns, local_name)
+ .map_or(false, |attr| attr.value().eval_selector(operation))
+ }
+ NamespaceConstraint::Any => {
+ self.attrs.borrow().iter().any(|attr| {
+ attr.local_name() == local_name &&
+ attr.value().eval_selector(operation)
+ })
+ }
+ }
+ }
+
fn is_root(&self) -> bool {
match self.node.GetParentNode() {
None => false,
@@ -2459,6 +2451,11 @@ impl<'a> ::selectors::Element for Root<Element> {
}
},
+ NonTSPseudoClass::ServoCaseSensitiveTypeAttr(ref expected_value) => {
+ self.get_attribute(&ns!(), &local_name!("type"))
+ .map_or(false, |attr| attr.value().eq(expected_value))
+ }
+
// FIXME(#15746): This is wrong, we need to instead use extended filtering as per RFC4647
// https://tools.ietf.org/html/rfc4647#section-3.3.2
NonTSPseudoClass::Lang(ref lang) => extended_filtering(&*self.get_lang(), &*lang),
@@ -2489,18 +2486,6 @@ impl<'a> ::selectors::Element for Root<Element> {
Element::has_class(&**self, name)
}
- fn each_class<F>(&self, mut callback: F)
- where F: FnMut(&Atom)
- {
- if let Some(ref attr) = self.get_attribute(&ns!(), &local_name!("class")) {
- let tokens = attr.value();
- let tokens = tokens.as_tokens();
- for token in tokens {
- callback(token);
- }
- }
- }
-
fn is_html_element_in_html_document(&self) -> bool {
self.html_element_in_html_document()
}