mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +01:00
Auto merge of #9004 - bholley:stylo_uplifts_1, r=pcwalton
Stylo uplifts Part 1 @pcwalton indicated his approval for landing stuff for the servo/gecko layout integration into the tree, which will improve maintainability for that effort. Here's an initial batch. <!-- Reviewable:start --> [<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/9004) <!-- Reviewable:end -->
This commit is contained in:
commit
9412e71460
2 changed files with 89 additions and 91 deletions
|
@ -11,7 +11,6 @@ use context::SharedLayoutContext;
|
||||||
use data::LayoutDataWrapper;
|
use data::LayoutDataWrapper;
|
||||||
use incremental::{self, RestyleDamage};
|
use incremental::{self, RestyleDamage};
|
||||||
use msg::ParseErrorReporter;
|
use msg::ParseErrorReporter;
|
||||||
use script::dom::bindings::inheritance::{CharacterDataTypeId, NodeTypeId};
|
|
||||||
use script::layout_interface::Animation;
|
use script::layout_interface::Animation;
|
||||||
use selectors::bloom::BloomFilter;
|
use selectors::bloom::BloomFilter;
|
||||||
use selectors::matching::{CommonStyleAffectingAttributeMode, CommonStyleAffectingAttributes};
|
use selectors::matching::{CommonStyleAffectingAttributeMode, CommonStyleAffectingAttributes};
|
||||||
|
@ -724,49 +723,46 @@ impl<'ln, ConcreteLayoutNode> MatchMethods<'ln, ConcreteLayoutNode>
|
||||||
match *layout_data_ref {
|
match *layout_data_ref {
|
||||||
None => panic!("no layout data"),
|
None => panic!("no layout data"),
|
||||||
Some(ref mut layout_data) => {
|
Some(ref mut layout_data) => {
|
||||||
match self.type_id() {
|
if self.is_text_node() {
|
||||||
NodeTypeId::CharacterData(CharacterDataTypeId::Text) => {
|
// Text nodes get a copy of the parent style. This ensures
|
||||||
// Text nodes get a copy of the parent style. This ensures
|
// that during fragment construction any non-inherited
|
||||||
// that during fragment construction any non-inherited
|
// CSS properties (such as vertical-align) are correctly
|
||||||
// CSS properties (such as vertical-align) are correctly
|
// set on the fragment(s).
|
||||||
// set on the fragment(s).
|
let cloned_parent_style = parent_style.unwrap().clone();
|
||||||
let cloned_parent_style = parent_style.unwrap().clone();
|
layout_data.shared_data.style = Some(cloned_parent_style);
|
||||||
layout_data.shared_data.style = Some(cloned_parent_style);
|
} else {
|
||||||
}
|
let mut damage = self.cascade_node_pseudo_element(
|
||||||
_ => {
|
layout_context,
|
||||||
let mut damage = self.cascade_node_pseudo_element(
|
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,
|
layout_context,
|
||||||
parent_style,
|
Some(layout_data.shared_data.style.as_ref().unwrap()),
|
||||||
&applicable_declarations.normal,
|
&*applicable_declarations.before,
|
||||||
&mut layout_data.shared_data.style,
|
&mut layout_data.data.before_style,
|
||||||
applicable_declarations_cache,
|
applicable_declarations_cache,
|
||||||
new_animations_sender,
|
new_animations_sender,
|
||||||
applicable_declarations.normal_shareable,
|
false,
|
||||||
true);
|
false);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
if !applicable_declarations.after.is_empty() {
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,16 +93,33 @@ pub trait LayoutNode<'ln> : Sized + Copy + Clone {
|
||||||
/// Returns the type ID of this node.
|
/// Returns the type ID of this node.
|
||||||
fn type_id(&self) -> NodeTypeId;
|
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 is_element(&self) -> bool;
|
||||||
|
|
||||||
fn dump(self);
|
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.
|
/// 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`.
|
/// Converts self into an `OpaqueNode`.
|
||||||
fn opaque(&self) -> 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 {
|
fn is_element(&self) -> bool {
|
||||||
unsafe {
|
unsafe {
|
||||||
self.node.is_element_for_layout()
|
self.node.is_element_for_layout()
|
||||||
|
@ -314,24 +335,6 @@ impl<'ln> LayoutNode<'ln> for ServoLayoutNode<'ln> {
|
||||||
self.dump_indent(0);
|
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 {
|
fn opaque(&self) -> OpaqueNode {
|
||||||
OpaqueNodeMethods::from_jsmanaged(unsafe { self.get_jsmanaged() })
|
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 ConcreteThreadSafeLayoutElement: ThreadSafeLayoutElement<'ln, ConcreteThreadSafeLayoutNode = Self>;
|
||||||
type ChildrenIterator: Iterator<Item = Self> + Sized;
|
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`.
|
/// Converts self into an `OpaqueNode`.
|
||||||
fn opaque(&self) -> 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>;
|
fn get_pseudo_element_type(&self) -> PseudoElementType<display::T>;
|
||||||
|
|
||||||
#[inline]
|
#[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]
|
#[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.
|
/// 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;
|
fn get_colspan(&self) -> u32;
|
||||||
}
|
}
|
||||||
|
|
||||||
// These can violate the thread-safety and therefore are not public.
|
// This trait is only public so that it can be implemented by the gecko wrapper.
|
||||||
trait DangerousThreadSafeLayoutNode<'ln> : ThreadSafeLayoutNode<'ln> {
|
// 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_first_child(&self) -> Option<Self>;
|
||||||
unsafe fn dangerous_next_sibling(&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
|
/// Returns the interior of this node as a `LayoutJS`. This is highly unsafe for layout to
|
||||||
/// call and as such is marked `unsafe`.
|
/// call and as such is marked `unsafe`.
|
||||||
unsafe fn get_jsmanaged(&self) -> &LayoutJS<Node> {
|
unsafe fn get_jsmanaged(&self) -> &LayoutJS<Node> {
|
||||||
|
@ -1052,6 +1063,13 @@ impl<'ln> ThreadSafeLayoutNode<'ln> for ServoThreadSafeLayoutNode<'ln> {
|
||||||
type ConcreteThreadSafeLayoutElement = ServoThreadSafeLayoutElement<'ln>;
|
type ConcreteThreadSafeLayoutElement = ServoThreadSafeLayoutElement<'ln>;
|
||||||
type ChildrenIterator = ThreadSafeLayoutNodeChildrenIterator<'ln, Self>;
|
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 {
|
fn opaque(&self) -> OpaqueNode {
|
||||||
OpaqueNodeMethods::from_jsmanaged(unsafe { self.get_jsmanaged() })
|
OpaqueNodeMethods::from_jsmanaged(unsafe { self.get_jsmanaged() })
|
||||||
}
|
}
|
||||||
|
@ -1094,22 +1112,6 @@ impl<'ln> ThreadSafeLayoutNode<'ln> for ServoThreadSafeLayoutNode<'ln> {
|
||||||
self.pseudo
|
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>> {
|
fn borrow_layout_data(&self) -> Ref<Option<LayoutDataWrapper>> {
|
||||||
self.node.borrow_layout_data()
|
self.node.borrow_layout_data()
|
||||||
}
|
}
|
||||||
|
@ -1244,7 +1246,7 @@ pub struct ThreadSafeLayoutNodeChildrenIterator<'ln, ConcreteNode: ThreadSafeLay
|
||||||
|
|
||||||
impl<'ln, ConcreteNode> ThreadSafeLayoutNodeChildrenIterator<'ln, ConcreteNode>
|
impl<'ln, ConcreteNode> ThreadSafeLayoutNodeChildrenIterator<'ln, ConcreteNode>
|
||||||
where ConcreteNode: DangerousThreadSafeLayoutNode<'ln> {
|
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() {
|
let first_child: Option<ConcreteNode> = match parent.get_pseudo_element_type() {
|
||||||
PseudoElementType::Normal => {
|
PseudoElementType::Normal => {
|
||||||
parent.get_before_pseudo().or_else(|| {
|
parent.get_before_pseudo().or_else(|| {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue