diff options
Diffstat (limited to 'components/script')
-rw-r--r-- | components/script/dom/element.rs | 75 | ||||
-rw-r--r-- | components/script/dom/mutationobserver.rs | 2 | ||||
-rw-r--r-- | components/script/layout_wrapper.rs | 130 |
3 files changed, 100 insertions, 107 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() } diff --git a/components/script/dom/mutationobserver.rs b/components/script/dom/mutationobserver.rs index b174ae4d11f..48c8fe24b87 100644 --- a/components/script/dom/mutationobserver.rs +++ b/components/script/dom/mutationobserver.rs @@ -9,7 +9,7 @@ use dom::bindings::codegen::Bindings::MutationObserverBinding::MutationCallback; use dom::bindings::codegen::Bindings::MutationObserverBinding::MutationObserverBinding::MutationObserverMethods; use dom::bindings::codegen::Bindings::MutationObserverBinding::MutationObserverInit; use dom::bindings::error::{Error, Fallible}; -use dom::bindings::js::{JS, Root}; +use dom::bindings::js::Root; use dom::bindings::reflector::{Reflector, reflect_dom_object}; use dom::bindings::str::DOMString; use dom::mutationrecord::MutationRecord; diff --git a/components/script/layout_wrapper.rs b/components/script/layout_wrapper.rs index 4d1810978d8..62e5158f321 100644 --- a/components/script/layout_wrapper.rs +++ b/components/script/layout_wrapper.rs @@ -50,8 +50,8 @@ 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, NamespaceConstraint}; use selectors::matching::{ElementSelectorFlags, MatchingContext}; -use selectors::parser::{AttrSelector, NamespaceConstraint}; use servo_atoms::Atom; use servo_url::ServoUrl; use std::fmt; @@ -402,6 +402,17 @@ impl<'le> TElement for ServoLayoutElement<'le> { self.get_attr(namespace, attr).map_or(false, |x| x == val) } + #[inline(always)] + fn each_class<F>(&self, mut callback: F) where F: FnMut(&Atom) { + unsafe { + if let Some(ref classes) = self.element.get_classes_for_layout() { + for class in *classes { + callback(class) + } + } + } + } + #[inline] fn existing_style_for_restyle_damage<'a>(&'a self, current_cv: &'a ComputedValues, @@ -510,6 +521,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 +576,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 +615,25 @@ impl<'le> ::selectors::Element for ServoLayoutElement<'le> { None } + fn attr_matches(&self, + ns: &NamespaceConstraint<&Namespace>, + local_name: &LocalName, + operation: &AttrSelectorOperation<&String>) + -> bool { + match *ns { + NamespaceConstraint::Specific(ref ns) => { + self.get_attr_enum(ns, 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, @@ -692,7 +706,10 @@ impl<'le> ::selectors::Element for ServoLayoutElement<'le> { _ => true, } }, - + NonTSPseudoClass::ServoCaseSensitiveTypeAttr(ref expected_value) => { + self.get_attr_enum(&ns!(), &local_name!("type")) + .map_or(false, |attr| attr == expected_value) + } NonTSPseudoClass::ReadOnly => !self.element.get_state_for_layout().contains(pseudo_class.state_flag()), @@ -725,17 +742,6 @@ impl<'le> ::selectors::Element for ServoLayoutElement<'le> { } } - #[inline(always)] - fn each_class<F>(&self, mut callback: F) where F: FnMut(&Atom) { - unsafe { - if let Some(ref classes) = self.element.get_classes_for_layout() { - for class in *classes { - callback(class) - } - } - } - } - fn is_html_element_in_html_document(&self) -> bool { unsafe { self.element.html_element_in_html_document_for_layout() @@ -1075,6 +1081,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) } @@ -1091,30 +1101,14 @@ impl<'le> ThreadSafeLayoutElement for ServoThreadSafeLayoutElement<'le> { /// i.e., local_name, attributes, so they can only be used for **private** /// pseudo-elements (like `::-servo-details-content`). /// -/// Probably a few more of this functions can be implemented (like `has_class`, -/// `each_class`, etc), but they have no use right now. +/// Probably a few more of this functions can be implemented (like `has_class`, etc.), +/// but they have no use right now. /// /// 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 +1160,25 @@ impl<'le> ::selectors::Element for ServoThreadSafeLayoutElement<'le> { false } + fn attr_matches(&self, + ns: &NamespaceConstraint<&Namespace>, + local_name: &LocalName, + operation: &AttrSelectorOperation<&String>) + -> bool { + match *ns { + NamespaceConstraint::Specific(ref ns) => { + self.get_attr_enum(ns, 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, @@ -1197,11 +1210,6 @@ impl<'le> ::selectors::Element for ServoThreadSafeLayoutElement<'le> { warn!("ServoThreadSafeLayoutElement::is_root called"); false } - - fn each_class<F>(&self, _callback: F) - where F: FnMut(&Atom) { - warn!("ServoThreadSafeLayoutElement::each_class called"); - } } impl<'le> PresentationalHintsSynthesizer for ServoThreadSafeLayoutElement<'le> { |