diff options
Diffstat (limited to 'components/script/layout_wrapper.rs')
-rw-r--r-- | components/script/layout_wrapper.rs | 162 |
1 files changed, 93 insertions, 69 deletions
diff --git a/components/script/layout_wrapper.rs b/components/script/layout_wrapper.rs index 3d4b90eaeab..62e5158f321 100644 --- a/components/script/layout_wrapper.rs +++ b/components/script/layout_wrapper.rs @@ -44,14 +44,14 @@ use dom::node::{LayoutNodeHelpers, Node}; use dom::text::Text; use gfx_traits::ByteIndex; use html5ever::{LocalName, Namespace}; -use msg::constellation_msg::{FrameId, PipelineId}; +use msg::constellation_msg::{BrowsingContextId, PipelineId}; use range::Range; use script_layout_interface::{HTMLCanvasData, LayoutNodeType, SVGSVGData, TrustedNodeAddress}; 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::matching::{ElementSelectorFlags, StyleRelations}; -use selectors::parser::{AttrSelector, NamespaceConstraint}; +use selectors::attr::{AttrSelectorOperation, NamespaceConstraint}; +use selectors::matching::{ElementSelectorFlags, MatchingContext}; use servo_atoms::Atom; use servo_url::ServoUrl; use std::fmt; @@ -402,11 +402,22 @@ 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 Arc<ComputedValues>, + current_cv: &'a ComputedValues, _pseudo_element: Option<&PseudoElement>) - -> Option<&'a Arc<ComputedValues>> { + -> Option<&'a ComputedValues> { Some(current_cv) } @@ -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, @@ -652,9 +666,17 @@ impl<'le> ::selectors::Element for ServoLayoutElement<'le> { self.element.namespace() } + fn match_pseudo_element(&self, + _pseudo: &PseudoElement, + _context: &mut MatchingContext) + -> bool + { + false + } + fn match_non_ts_pseudo_class<F>(&self, pseudo_class: &NonTSPseudoClass, - _: &mut StyleRelations, + _: &mut MatchingContext, _: &mut F) -> bool where F: FnMut(&Self, ElementSelectorFlags), @@ -684,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()), @@ -717,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() @@ -908,9 +922,9 @@ impl<'ln> ThreadSafeLayoutNode for ServoThreadSafeLayoutNode<'ln> { this.svg_data() } - fn iframe_frame_id(&self) -> FrameId { + fn iframe_browsing_context_id(&self) -> BrowsingContextId { let this = unsafe { self.get_jsmanaged() }; - this.iframe_frame_id() + this.iframe_browsing_context_id() } fn iframe_pipeline_id(&self) -> PipelineId { @@ -1067,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) } @@ -1083,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 @@ -1150,9 +1152,36 @@ impl<'le> ::selectors::Element for ServoThreadSafeLayoutElement<'le> { self.element.get_namespace() } + fn match_pseudo_element(&self, + _pseudo: &PseudoElement, + _context: &mut MatchingContext) + -> bool + { + 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 StyleRelations, + _: &mut MatchingContext, _: &mut F) -> bool where F: FnMut(&Self, ElementSelectorFlags), @@ -1181,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> { |