aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/layout_wrapper.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/layout_wrapper.rs')
-rw-r--r--components/script/layout_wrapper.rs162
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> {