diff options
Diffstat (limited to 'components/script')
-rw-r--r-- | components/script/Cargo.toml | 2 | ||||
-rw-r--r-- | components/script/dom/element.rs | 53 | ||||
-rw-r--r-- | components/script/layout_wrapper.rs | 90 |
3 files changed, 79 insertions, 66 deletions
diff --git a/components/script/Cargo.toml b/components/script/Cargo.toml index d9bdeac843b..fa2d75c633d 100644 --- a/components/script/Cargo.toml +++ b/components/script/Cargo.toml @@ -57,7 +57,7 @@ regex = "0.1.43" rustc-serialize = "0.3" script_layout_interface = {path = "../script_layout_interface"} script_traits = {path = "../script_traits"} -selectors = {version = "0.6", features = ["heap_size"]} +selectors = {version = "0.7", features = ["heap_size"]} serde = "0.7.11" smallvec = "0.1" string_cache = {version = "0.2.20", features = ["heap_size", "unstable"]} diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index d9535663d46..e53f7dbb77b 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -2217,6 +2217,34 @@ impl VirtualMethods for Element { } } +impl<'a> ::selectors::MatchAttrGeneric for Root<Element> { + fn match_attr<F>(&self, attr: &AttrSelector, 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, 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> { type Impl = ServoSelectorImpl; @@ -2317,31 +2345,6 @@ impl<'a> ::selectors::Element for Root<Element> { } } - fn match_attr<F>(&self, attr: &AttrSelector, test: F) -> bool - where F: Fn(&str) -> bool - { - 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, 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()) - }) - } - } - } - fn is_html_element_in_html_document(&self) -> bool { self.html_element_in_html_document() } diff --git a/components/script/layout_wrapper.rs b/components/script/layout_wrapper.rs index 7085fcae002..ebc2da9c529 100644 --- a/components/script/layout_wrapper.rs +++ b/components/script/layout_wrapper.rs @@ -387,17 +387,13 @@ impl<'le> TElement for ServoLayoutElement<'le> { } #[inline] - fn get_attr(&self, namespace: &Namespace, name: &Atom) -> Option<&str> { - unsafe { - (*self.element.unsafe_get()).get_attr_val_for_layout(namespace, name) - } + fn has_attr(&self, namespace: &Namespace, attr: &Atom) -> bool { + self.get_attr(namespace, attr).is_some() } #[inline] - fn get_attrs(&self, name: &Atom) -> Vec<&str> { - unsafe { - (*self.element.unsafe_get()).get_attr_vals_for_layout(name) - } + fn attr_equals(&self, namespace: &Namespace, attr: &Atom, val: &Atom) -> bool { + self.get_attr(namespace, attr).map_or(false, |x| x == val) } } @@ -409,12 +405,41 @@ impl<'le> ServoLayoutElement<'le> { chain: PhantomData, } } + + #[inline] + fn get_attr(&self, namespace: &Namespace, name: &Atom) -> Option<&str> { + unsafe { + (*self.element.unsafe_get()).get_attr_val_for_layout(namespace, name) + } + } } fn as_element<'le>(node: LayoutJS<Node>) -> Option<ServoLayoutElement<'le>> { node.downcast().map(ServoLayoutElement::from_layout_js) } +impl<'le> ::selectors::MatchAttrGeneric for ServoLayoutElement<'le> { + fn match_attr<F>(&self, attr: &AttrSelector, 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, 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> { type Impl = ServoSelectorImpl; @@ -550,22 +575,6 @@ impl<'le> ::selectors::Element for ServoLayoutElement<'le> { } } - fn match_attr<F>(&self, attr: &AttrSelector, test: F) -> bool where F: Fn(&str) -> bool { - 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, name).map_or(false, |attr| test(attr)) - }, - NamespaceConstraint::Any => { - self.get_attrs(name).iter().any(|attr| test(*attr)) - } - } - } - fn is_html_element_in_html_document(&self) -> bool { unsafe { self.element.html_element_in_html_document_for_layout() @@ -900,7 +909,23 @@ 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::Element for ServoThreadSafeLayoutElement<'le> { +impl<'le> ::selectors::MatchAttrGeneric for ServoThreadSafeLayoutElement<'le> { + fn match_attr<F>(&self, attr: &AttrSelector, test: F) -> bool + where F: Fn(&str) -> bool { + match attr.namespace { + NamespaceConstraint::Specific(ref ns) => { + self.get_attr(ns, &attr.name).map_or(false, |attr| test(attr)) + }, + NamespaceConstraint::Any => { + unsafe { + self.element.get_attr_vals_for_layout(&attr.name).iter() + .any(|attr| test(*attr)) + } + } + } + } +} +impl<'le> ::selectors::Element for ServoThreadSafeLayoutElement<'le> { type Impl = ServoSelectorImpl; fn parent_element(&self) -> Option<Self> { @@ -962,21 +987,6 @@ impl <'le> ::selectors::Element for ServoThreadSafeLayoutElement<'le> { false } - fn match_attr<F>(&self, attr: &AttrSelector, test: F) -> bool - where F: Fn(&str) -> bool { - match attr.namespace { - NamespaceConstraint::Specific(ref ns) => { - self.get_attr(ns, &attr.name).map_or(false, |attr| test(attr)) - }, - NamespaceConstraint::Any => { - unsafe { - self.element.get_attr_vals_for_layout(&attr.name).iter() - .any(|attr| test(*attr)) - } - } - } - } - fn is_empty(&self) -> bool { warn!("ServoThreadSafeLayoutElement::is_empty called"); false |