aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/layout/css/matching.rs74
-rw-r--r--components/layout/wrapper.rs104
2 files changed, 88 insertions, 90 deletions
diff --git a/components/layout/css/matching.rs b/components/layout/css/matching.rs
index 7036038369c..ae136aea5ff 100644
--- a/components/layout/css/matching.rs
+++ b/components/layout/css/matching.rs
@@ -11,7 +11,6 @@ use context::SharedLayoutContext;
use data::LayoutDataWrapper;
use incremental::{self, RestyleDamage};
use msg::ParseErrorReporter;
-use script::dom::bindings::inheritance::{CharacterDataTypeId, NodeTypeId};
use script::layout_interface::Animation;
use selectors::bloom::BloomFilter;
use selectors::matching::{CommonStyleAffectingAttributeMode, CommonStyleAffectingAttributes};
@@ -724,49 +723,46 @@ impl<'ln, ConcreteLayoutNode> MatchMethods<'ln, ConcreteLayoutNode>
match *layout_data_ref {
None => panic!("no layout data"),
Some(ref mut layout_data) => {
- match self.type_id() {
- NodeTypeId::CharacterData(CharacterDataTypeId::Text) => {
- // Text nodes get a copy of the parent style. This ensures
- // that during fragment construction any non-inherited
- // CSS properties (such as vertical-align) are correctly
- // set on the fragment(s).
- let cloned_parent_style = parent_style.unwrap().clone();
- layout_data.shared_data.style = Some(cloned_parent_style);
+ if self.is_text_node() {
+ // Text nodes get a copy of the parent style. This ensures
+ // that during fragment construction any non-inherited
+ // CSS properties (such as vertical-align) are correctly
+ // set on the fragment(s).
+ let cloned_parent_style = parent_style.unwrap().clone();
+ layout_data.shared_data.style = Some(cloned_parent_style);
+ } else {
+ let mut damage = self.cascade_node_pseudo_element(
+ layout_context,
+ parent_style,
+ &applicable_declarations.normal,
+ &mut layout_data.shared_data.style,
+ applicable_declarations_cache,
+ new_animations_sender,
+ applicable_declarations.normal_shareable,
+ true);
+ if !applicable_declarations.before.is_empty() {
+ damage = damage | self.cascade_node_pseudo_element(
+ layout_context,
+ Some(layout_data.shared_data.style.as_ref().unwrap()),
+ &*applicable_declarations.before,
+ &mut layout_data.data.before_style,
+ applicable_declarations_cache,
+ new_animations_sender,
+ false,
+ false);
}
- _ => {
- let mut damage = self.cascade_node_pseudo_element(
+ if !applicable_declarations.after.is_empty() {
+ damage = damage | self.cascade_node_pseudo_element(
layout_context,
- parent_style,
- &applicable_declarations.normal,
- &mut layout_data.shared_data.style,
+ Some(layout_data.shared_data.style.as_ref().unwrap()),
+ &*applicable_declarations.after,
+ &mut layout_data.data.after_style,
applicable_declarations_cache,
new_animations_sender,
- applicable_declarations.normal_shareable,
- true);
- if applicable_declarations.before.len() > 0 {
- damage = damage | self.cascade_node_pseudo_element(
- layout_context,
- Some(layout_data.shared_data.style.as_ref().unwrap()),
- &*applicable_declarations.before,
- &mut layout_data.data.before_style,
- applicable_declarations_cache,
- new_animations_sender,
- false,
- false);
- }
- if applicable_declarations.after.len() > 0 {
- damage = damage | self.cascade_node_pseudo_element(
- layout_context,
- Some(layout_data.shared_data.style.as_ref().unwrap()),
- &*applicable_declarations.after,
- &mut layout_data.data.after_style,
- applicable_declarations_cache,
- new_animations_sender,
- false,
- false);
- }
- layout_data.data.restyle_damage = damage;
+ false,
+ false);
}
+ layout_data.data.restyle_damage = damage;
}
}
}
diff --git a/components/layout/wrapper.rs b/components/layout/wrapper.rs
index 5ad91dbcbc0..ddb899b9db5 100644
--- a/components/layout/wrapper.rs
+++ b/components/layout/wrapper.rs
@@ -93,16 +93,33 @@ pub trait LayoutNode<'ln> : Sized + Copy + Clone {
/// Returns the type ID of this node.
fn type_id(&self) -> NodeTypeId;
+ /// Returns whether this is a text node. It turns out that this is all the style system cares
+ /// about, and thus obviates the need to compute the full type id, which would be expensive in
+ /// Gecko.
+ fn is_text_node(&self) -> bool;
+
fn is_element(&self) -> bool;
fn dump(self);
- fn traverse_preorder(self) -> LayoutTreeIterator<'ln, Self>;
+ fn traverse_preorder(self) -> LayoutTreeIterator<'ln, Self> {
+ LayoutTreeIterator::new(self)
+ }
/// Returns an iterator over this node's children.
- fn children(self) -> LayoutNodeChildrenIterator<'ln, Self>;
+ fn children(self) -> LayoutNodeChildrenIterator<'ln, Self> {
+ LayoutNodeChildrenIterator {
+ current: self.first_child(),
+ phantom: PhantomData,
+ }
+ }
- fn rev_children(self) -> LayoutNodeReverseChildrenIterator<'ln, Self>;
+ fn rev_children(self) -> LayoutNodeReverseChildrenIterator<'ln, Self> {
+ LayoutNodeReverseChildrenIterator {
+ current: self.last_child(),
+ phantom: PhantomData,
+ }
+ }
/// Converts self into an `OpaqueNode`.
fn opaque(&self) -> OpaqueNode;
@@ -304,6 +321,10 @@ impl<'ln> LayoutNode<'ln> for ServoLayoutNode<'ln> {
}
}
+ fn is_text_node(&self) -> bool {
+ self.type_id() == NodeTypeId::CharacterData(CharacterDataTypeId::Text)
+ }
+
fn is_element(&self) -> bool {
unsafe {
self.node.is_element_for_layout()
@@ -314,24 +335,6 @@ impl<'ln> LayoutNode<'ln> for ServoLayoutNode<'ln> {
self.dump_indent(0);
}
- fn traverse_preorder(self) -> LayoutTreeIterator<'ln, Self> {
- LayoutTreeIterator::new(self)
- }
-
- fn children(self) -> LayoutNodeChildrenIterator<'ln, Self> {
- LayoutNodeChildrenIterator {
- current: self.first_child(),
- phantom: PhantomData,
- }
- }
-
- fn rev_children(self) -> LayoutNodeReverseChildrenIterator<'ln, Self> {
- LayoutNodeReverseChildrenIterator {
- current: self.last_child(),
- phantom: PhantomData,
- }
- }
-
fn opaque(&self) -> OpaqueNode {
OpaqueNodeMethods::from_jsmanaged(unsafe { self.get_jsmanaged() })
}
@@ -835,6 +838,10 @@ pub trait ThreadSafeLayoutNode<'ln> : Clone + Copy + Sized {
type ConcreteThreadSafeLayoutElement: ThreadSafeLayoutElement<'ln, ConcreteThreadSafeLayoutNode = Self>;
type ChildrenIterator: Iterator<Item = Self> + Sized;
+ /// Creates a new `ThreadSafeLayoutNode` for the same `LayoutNode`
+ /// with a different pseudo-element type.
+ fn with_pseudo(&self, pseudo: PseudoElementType<display::T>) -> Self;
+
/// Converts self into an `OpaqueNode`.
fn opaque(&self) -> OpaqueNode;
@@ -857,10 +864,22 @@ pub trait ThreadSafeLayoutNode<'ln> : Clone + Copy + Sized {
fn get_pseudo_element_type(&self) -> PseudoElementType<display::T>;
#[inline]
- fn get_before_pseudo(&self) -> Option<Self>;
+ fn get_before_pseudo(&self) -> Option<Self> {
+ let layout_data_ref = self.borrow_layout_data();
+ let node_layout_data_wrapper = layout_data_ref.as_ref().unwrap();
+ node_layout_data_wrapper.data.before_style.as_ref().map(|style| {
+ self.with_pseudo(PseudoElementType::Before(style.get_box().display))
+ })
+ }
#[inline]
- fn get_after_pseudo(&self) -> Option<Self>;
+ fn get_after_pseudo(&self) -> Option<Self> {
+ let layout_data_ref = self.borrow_layout_data();
+ let node_layout_data_wrapper = layout_data_ref.as_ref().unwrap();
+ node_layout_data_wrapper.data.after_style.as_ref().map(|style| {
+ self.with_pseudo(PseudoElementType::After(style.get_box().display))
+ })
+ }
/// Borrows the layout data immutably. Fails on a conflicting borrow.
///
@@ -975,8 +994,9 @@ pub trait ThreadSafeLayoutNode<'ln> : Clone + Copy + Sized {
fn get_colspan(&self) -> u32;
}
-// These can violate the thread-safety and therefore are not public.
-trait DangerousThreadSafeLayoutNode<'ln> : ThreadSafeLayoutNode<'ln> {
+// This trait is only public so that it can be implemented by the gecko wrapper.
+// It can be used to violate thread-safety, so don't use it elsewhere in layout!
+pub trait DangerousThreadSafeLayoutNode<'ln> : ThreadSafeLayoutNode<'ln> {
unsafe fn dangerous_first_child(&self) -> Option<Self>;
unsafe fn dangerous_next_sibling(&self) -> Option<Self>;
}
@@ -1024,15 +1044,6 @@ impl<'ln> ServoThreadSafeLayoutNode<'ln> {
}
}
- /// Creates a new `ServoThreadSafeLayoutNode` for the same `LayoutNode`
- /// with a different pseudo-element type.
- fn with_pseudo(&self, pseudo: PseudoElementType<display::T>) -> ServoThreadSafeLayoutNode<'ln> {
- ServoThreadSafeLayoutNode {
- node: self.node.clone(),
- pseudo: pseudo,
- }
- }
-
/// Returns the interior of this node as a `LayoutJS`. This is highly unsafe for layout to
/// call and as such is marked `unsafe`.
unsafe fn get_jsmanaged(&self) -> &LayoutJS<Node> {
@@ -1052,6 +1063,13 @@ impl<'ln> ThreadSafeLayoutNode<'ln> for ServoThreadSafeLayoutNode<'ln> {
type ConcreteThreadSafeLayoutElement = ServoThreadSafeLayoutElement<'ln>;
type ChildrenIterator = ThreadSafeLayoutNodeChildrenIterator<'ln, Self>;
+ fn with_pseudo(&self, pseudo: PseudoElementType<display::T>) -> ServoThreadSafeLayoutNode<'ln> {
+ ServoThreadSafeLayoutNode {
+ node: self.node.clone(),
+ pseudo: pseudo,
+ }
+ }
+
fn opaque(&self) -> OpaqueNode {
OpaqueNodeMethods::from_jsmanaged(unsafe { self.get_jsmanaged() })
}
@@ -1094,22 +1112,6 @@ impl<'ln> ThreadSafeLayoutNode<'ln> for ServoThreadSafeLayoutNode<'ln> {
self.pseudo
}
- fn get_before_pseudo(&self) -> Option<ServoThreadSafeLayoutNode<'ln>> {
- let layout_data_ref = self.borrow_layout_data();
- let node_layout_data_wrapper = layout_data_ref.as_ref().unwrap();
- node_layout_data_wrapper.data.before_style.as_ref().map(|style| {
- self.with_pseudo(PseudoElementType::Before(style.get_box().display))
- })
- }
-
- fn get_after_pseudo(&self) -> Option<ServoThreadSafeLayoutNode<'ln>> {
- let layout_data_ref = self.borrow_layout_data();
- let node_layout_data_wrapper = layout_data_ref.as_ref().unwrap();
- node_layout_data_wrapper.data.after_style.as_ref().map(|style| {
- self.with_pseudo(PseudoElementType::After(style.get_box().display))
- })
- }
-
fn borrow_layout_data(&self) -> Ref<Option<LayoutDataWrapper>> {
self.node.borrow_layout_data()
}
@@ -1244,7 +1246,7 @@ pub struct ThreadSafeLayoutNodeChildrenIterator<'ln, ConcreteNode: ThreadSafeLay
impl<'ln, ConcreteNode> ThreadSafeLayoutNodeChildrenIterator<'ln, ConcreteNode>
where ConcreteNode: DangerousThreadSafeLayoutNode<'ln> {
- fn new(parent: ConcreteNode) -> Self {
+ pub fn new(parent: ConcreteNode) -> Self {
let first_child: Option<ConcreteNode> = match parent.get_pseudo_element_type() {
PseudoElementType::Normal => {
parent.get_before_pseudo().or_else(|| {