diff options
Diffstat (limited to 'components')
-rw-r--r-- | components/layout/css/matching.rs | 2 | ||||
-rw-r--r-- | components/layout/layout_task.rs | 2 | ||||
-rw-r--r-- | components/layout/parallel.rs | 2 | ||||
-rw-r--r-- | components/layout/sequential.rs | 2 | ||||
-rw-r--r-- | components/layout/traversal.rs | 2 | ||||
-rw-r--r-- | components/layout/wrapper.rs | 471 |
6 files changed, 290 insertions, 191 deletions
diff --git a/components/layout/css/matching.rs b/components/layout/css/matching.rs index 4afd9a77815..c088452021d 100644 --- a/components/layout/css/matching.rs +++ b/components/layout/css/matching.rs @@ -31,7 +31,7 @@ use util::arc_ptr_eq; use util::cache::{LRUCache, SimpleHashCache}; use util::opts; use util::vec::ForgetfulSink; -use wrapper::{LayoutElement, LayoutNode}; +use wrapper::{LayoutElement, LayoutElementTrait, LayoutNode, LayoutNodeTrait}; pub struct ApplicableDeclarations { pub normal: SmallVec<[DeclarationBlock; 16]>, diff --git a/components/layout/layout_task.rs b/components/layout/layout_task.rs index 0aed4e6c9c0..87decbff3e0 100644 --- a/components/layout/layout_task.rs +++ b/components/layout/layout_task.rs @@ -82,7 +82,7 @@ use util::opts; use util::task::spawn_named_with_send_on_failure; use util::task_state; use util::workqueue::WorkQueue; -use wrapper::{LayoutNode, ThreadSafeLayoutNode}; +use wrapper::{LayoutDocumentTrait, LayoutElementTrait, LayoutNode, LayoutNodeTrait, ThreadSafeLayoutNode}; /// The number of screens of data we're allowed to generate display lists for in each direction. pub const DISPLAY_PORT_SIZE_FACTOR: i32 = 8; diff --git a/components/layout/parallel.rs b/components/layout/parallel.rs index 1b1f4056706..6e7a04c1cba 100644 --- a/components/layout/parallel.rs +++ b/components/layout/parallel.rs @@ -23,7 +23,7 @@ use traversal::{PostorderDomTraversal, PreorderDomTraversal}; use util::opts; use util::workqueue::{WorkQueue, WorkUnit, WorkerProxy}; use wrapper::UnsafeLayoutNode; -use wrapper::{LayoutNode, layout_node_from_unsafe_layout_node, layout_node_to_unsafe_layout_node}; +use wrapper::{LayoutNode, LayoutNodeTrait, layout_node_from_unsafe_layout_node, layout_node_to_unsafe_layout_node}; const CHUNK_SIZE: usize = 64; diff --git a/components/layout/sequential.rs b/components/layout/sequential.rs index 9202ef2ea8a..87d9096402d 100644 --- a/components/layout/sequential.rs +++ b/components/layout/sequential.rs @@ -19,7 +19,7 @@ use traversal::{BuildDisplayList, ComputeAbsolutePositions}; use traversal::{PostorderDomTraversal, PreorderDomTraversal}; use util::geometry::ZERO_POINT; use util::opts; -use wrapper::LayoutNode; +use wrapper::{LayoutNode, LayoutNodeTrait}; pub fn traverse_dom_preorder(root: LayoutNode, shared_layout_context: &SharedLayoutContext) { diff --git a/components/layout/traversal.rs b/components/layout/traversal.rs index 3a1fcf38bc6..605a239e9be 100644 --- a/components/layout/traversal.rs +++ b/components/layout/traversal.rs @@ -17,7 +17,7 @@ use std::cell::RefCell; use std::mem; use util::opts; use util::tid::tid; -use wrapper::{LayoutNode, layout_node_to_unsafe_layout_node}; +use wrapper::{LayoutNode, LayoutNodeTrait, layout_node_to_unsafe_layout_node}; use wrapper::{ThreadSafeLayoutNode, UnsafeLayoutNode}; /// Every time we do another layout, the old bloom filters are invalid. This is diff --git a/components/layout/wrapper.rs b/components/layout/wrapper.rs index 11a4a0e514e..634aeca28de 100644 --- a/components/layout/wrapper.rs +++ b/components/layout/wrapper.rs @@ -73,6 +73,168 @@ use util::str::{is_whitespace, search_index}; /// A wrapper so that layout can access only the methods that it should have access to. Layout must /// only ever see these and must never see instances of `LayoutJS`. + +pub trait WrapperTypes<'a> : Sized { + type Node: LayoutNodeTrait<'a, Self>; + type Document: LayoutDocumentTrait<'a, Self>; + type Element: LayoutElementTrait<'a, Self>; +} + +pub trait LayoutNodeTrait<'ln, Wrappers> : Sized + Copy + Clone + where Wrappers: WrapperTypes<'ln> { + /// Returns the type ID of this node. + fn type_id(&self) -> NodeTypeId; + + fn is_element(&self) -> bool; + + fn dump(self); + + fn traverse_preorder(self) -> LayoutTreeIterator<'ln, Wrappers>; + + /// Returns an iterator over this node's children. + fn children(self) -> LayoutNodeChildrenIterator<'ln, Wrappers>; + + fn rev_children(self) -> LayoutNodeReverseChildrenIterator<'ln, Wrappers>; + + /// Converts self into an `OpaqueNode`. + fn opaque(&self) -> OpaqueNode; + + /// Resets layout data and styles for the node. + /// + /// FIXME(pcwalton): Do this as part of fragment building instead of in a traversal. + fn initialize_layout_data(self); + + /// While doing a reflow, the node at the root has no parent, as far as we're + /// concerned. This method returns `None` at the reflow root. + fn layout_parent_node(self, reflow_root: OpaqueNode) -> Option<Self>; + + fn debug_id(self) -> usize; + + fn as_element(&self) -> Option<Wrappers::Element>; + + fn as_document(&self) -> Option<Wrappers::Document>; + + fn children_count(&self) -> u32; + + fn has_changed(&self) -> bool; + + unsafe fn set_changed(&self, value: bool); + + fn is_dirty(&self) -> bool; + + unsafe fn set_dirty(&self, value: bool); + + fn has_dirty_descendants(&self) -> bool; + + unsafe fn set_dirty_descendants(&self, value: bool); + + fn dirty_self(&self) { + unsafe { + self.set_dirty(true); + self.set_dirty_descendants(true); + } + } + + fn dirty_descendants(&self) { + for ref child in self.children() { + child.dirty_self(); + child.dirty_descendants(); + } + } + + /// Borrows the layout data without checks. + #[inline(always)] + unsafe fn borrow_layout_data_unchecked(&self) -> *const Option<LayoutDataWrapper>; + + /// Borrows the layout data immutably. Fails on a conflicting borrow. + #[inline(always)] + fn borrow_layout_data(&self) -> Ref<Option<LayoutDataWrapper>>; + + /// Borrows the layout data mutably. Fails on a conflicting borrow. + #[inline(always)] + fn mutate_layout_data(&self) -> RefMut<Option<LayoutDataWrapper>>; + + fn parent_node(&self) -> Option<Wrappers::Node>; + + fn first_child(&self) -> Option<Wrappers::Node>; + + fn last_child(&self) -> Option<Wrappers::Node>; + + fn prev_sibling(&self) -> Option<Wrappers::Node>; + + fn next_sibling(&self) -> Option<Wrappers::Node>; +} + +pub trait LayoutDocumentTrait<'ld, Wrappers> : Sized + Copy + Clone + where Wrappers: WrapperTypes<'ld> { + fn as_node(&self) -> Wrappers::Node; + + fn root_node(&self) -> Option<Wrappers::Node>; + + fn drain_modified_elements(&self) -> Vec<(Wrappers::Element, ElementSnapshot)>; +} + +pub trait LayoutElementTrait<'le, Wrappers> : Sized + Copy + Clone + ::selectors::Element + where Wrappers: WrapperTypes<'le> { + fn as_node(&self) -> Wrappers::Node; + + fn style_attribute(&self) -> &'le Option<PropertyDeclarationBlock>; + + fn get_state(&self) -> ElementState; + + /// Properly marks nodes as dirty in response to restyle hints. + fn note_restyle_hint(&self, mut hint: RestyleHint) { + // Bail early if there's no restyling to do. + if hint.is_empty() { + return; + } + + // If the restyle hint is non-empty, we need to restyle either this element + // or one of its siblings. Mark our ancestor chain as having dirty descendants. + let node = self.as_node(); + let mut curr = node; + while let Some(parent) = curr.parent_node() { + if parent.has_dirty_descendants() { break } + unsafe { parent.set_dirty_descendants(true); } + curr = parent; + } + + // Process hints. + if hint.contains(RESTYLE_SELF) { + node.dirty_self(); + + // FIXME(bholley, #8438): We currently need to RESTYLE_DESCENDANTS in the + // RESTYLE_SELF case in order to make sure "inherit" style structs propagate + // properly. See the explanation in the github issue. + hint.insert(RESTYLE_DESCENDANTS); + } + if hint.contains(RESTYLE_DESCENDANTS) { + unsafe { node.set_dirty_descendants(true); } + node.dirty_descendants(); + } + if hint.contains(RESTYLE_LATER_SIBLINGS) { + let mut next = ::selectors::Element::next_sibling_element(self); + while let Some(sib) = next { + let sib_node = sib.as_node(); + sib_node.dirty_self(); + sib_node.dirty_descendants(); + next = ::selectors::Element::next_sibling_element(&sib); + } + } + } +} + +pub struct ServoWrapperTypes<'a> { + // Satisfy the compiler about the unused lifetime. + phantom: PhantomData<&'a ()>, +} + +impl<'a> WrapperTypes<'a> for ServoWrapperTypes<'a> { + type Node = LayoutNode<'a>; + type Element = LayoutElement<'a>; + type Document = LayoutDocument<'a>; +} + #[derive(Copy, Clone)] pub struct LayoutNode<'a> { /// The wrapped node. @@ -108,84 +270,46 @@ impl<'ln> LayoutNode<'ln> { chain: self.chain, } } +} - /// Returns the type ID of this node. - pub fn type_id(&self) -> NodeTypeId { +impl<'ln> LayoutNodeTrait<'ln, ServoWrapperTypes<'ln>> for LayoutNode<'ln> { + fn type_id(&self) -> NodeTypeId { unsafe { self.node.type_id_for_layout() } } - pub fn is_element(&self) -> bool { + fn is_element(&self) -> bool { unsafe { self.node.is_element_for_layout() } } - pub fn dump(self) { + fn dump(self) { self.dump_indent(0); } - fn dump_indent(self, indent: u32) { - let mut s = String::new(); - for _ in 0..indent { - s.push_str(" "); - } - - s.push_str(&self.debug_str()); - println!("{}", s); - - for kid in self.children() { - kid.dump_indent(indent + 1); - } - } - - fn debug_str(self) -> String { - format!("{:?}: changed={} dirty={} dirty_descendants={}", - self.type_id(), self.has_changed(), self.is_dirty(), self.has_dirty_descendants()) - } - - pub fn flow_debug_id(self) -> usize { - let layout_data_ref = self.borrow_layout_data(); - match *layout_data_ref { - None => 0, - Some(ref layout_data) => layout_data.data.flow_construction_result.debug_id() - } - } - - pub fn traverse_preorder(self) -> LayoutTreeIterator<'ln> { + fn traverse_preorder(self) -> LayoutTreeIterator<'ln, ServoWrapperTypes<'ln>> { LayoutTreeIterator::new(self) } - /// Returns an iterator over this node's children. - pub fn children(self) -> LayoutNodeChildrenIterator<'ln> { + fn children(self) -> LayoutNodeChildrenIterator<'ln, ServoWrapperTypes<'ln>> { LayoutNodeChildrenIterator { current: self.first_child(), } } - pub fn rev_children(self) -> LayoutNodeReverseChildrenIterator<'ln> { + fn rev_children(self) -> LayoutNodeReverseChildrenIterator<'ln, ServoWrapperTypes<'ln>> { LayoutNodeReverseChildrenIterator { current: self.last_child() } - } - /// 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> { - &self.node - } - - /// Converts self into an `OpaqueNode`. - pub fn opaque(&self) -> OpaqueNode { + fn opaque(&self) -> OpaqueNode { OpaqueNodeMethods::from_jsmanaged(unsafe { self.get_jsmanaged() }) } - /// Resets layout data and styles for the node. - /// - /// FIXME(pcwalton): Do this as part of fragment building instead of in a traversal. - pub fn initialize_layout_data(self) { + fn initialize_layout_data(self) { let mut layout_data_ref = self.mutate_layout_data(); match *layout_data_ref { None => { @@ -198,9 +322,7 @@ impl<'ln> LayoutNode<'ln> { } } - /// While doing a reflow, the node at the root has no parent, as far as we're - /// concerned. This method returns `None` at the reflow root. - pub fn layout_parent_node(self, reflow_root: OpaqueNode) -> Option<LayoutNode<'ln>> { + fn layout_parent_node(self, reflow_root: OpaqueNode) -> Option<LayoutNode<'ln>> { if self.opaque() == reflow_root { None } else { @@ -208,18 +330,62 @@ impl<'ln> LayoutNode<'ln> { } } - pub fn debug_id(self) -> usize { + fn debug_id(self) -> usize { self.opaque().to_untrusted_node_address().0 as usize } - pub fn as_element(&self) -> Option<LayoutElement<'ln>> { + fn children_count(&self) -> u32 { + unsafe { self.node.children_count() } + } + + fn as_element(&self) -> Option<LayoutElement<'ln>> { as_element(self.node) } - pub fn as_document(&self) -> Option<LayoutDocument<'ln>> { + fn as_document(&self) -> Option<LayoutDocument<'ln>> { self.node.downcast().map(|document| LayoutDocument::from_layout_js(document)) } + fn has_changed(&self) -> bool { + unsafe { self.node.get_flag(HAS_CHANGED) } + } + + unsafe fn set_changed(&self, value: bool) { + self.node.set_flag(HAS_CHANGED, value) + } + + fn is_dirty(&self) -> bool { + unsafe { self.node.get_flag(IS_DIRTY) } + } + + unsafe fn set_dirty(&self, value: bool) { + self.node.set_flag(IS_DIRTY, value) + } + + fn has_dirty_descendants(&self) -> bool { + unsafe { self.node.get_flag(HAS_DIRTY_DESCENDANTS) } + } + + unsafe fn set_dirty_descendants(&self, value: bool) { + self.node.set_flag(HAS_DIRTY_DESCENDANTS, value) + } + + unsafe fn borrow_layout_data_unchecked(&self) -> *const Option<LayoutDataWrapper> { + mem::transmute(self.get_jsmanaged().layout_data_unchecked()) + } + + fn borrow_layout_data(&self) -> Ref<Option<LayoutDataWrapper>> { + unsafe { + mem::transmute(self.get_jsmanaged().layout_data()) + } + } + + fn mutate_layout_data(&self) -> RefMut<Option<LayoutDataWrapper>> { + unsafe { + mem::transmute(self.get_jsmanaged().layout_data_mut()) + } + } + fn parent_node(&self) -> Option<LayoutNode<'ln>> { unsafe { self.node.parent_node_ref().map(|node| self.new_with_this_lifetime(&node)) @@ -249,92 +415,75 @@ impl<'ln> LayoutNode<'ln> { self.node.next_sibling_ref().map(|node| self.new_with_this_lifetime(&node)) } } - - pub fn children_count(&self) -> u32 { - unsafe { self.node.children_count() } - } } impl<'ln> LayoutNode<'ln> { - pub fn has_changed(&self) -> bool { - unsafe { self.node.get_flag(HAS_CHANGED) } - } - - pub unsafe fn set_changed(&self, value: bool) { - self.node.set_flag(HAS_CHANGED, value) - } - - pub fn is_dirty(&self) -> bool { - unsafe { self.node.get_flag(IS_DIRTY) } - } - - pub unsafe fn set_dirty(&self, value: bool) { - self.node.set_flag(IS_DIRTY, value) - } + fn dump_indent(self, indent: u32) { + let mut s = String::new(); + for _ in 0..indent { + s.push_str(" "); + } - pub fn has_dirty_descendants(&self) -> bool { - unsafe { self.node.get_flag(HAS_DIRTY_DESCENDANTS) } - } + s.push_str(&self.debug_str()); + println!("{}", s); - pub unsafe fn set_dirty_descendants(&self, value: bool) { - self.node.set_flag(HAS_DIRTY_DESCENDANTS, value) + for kid in self.children() { + kid.dump_indent(indent + 1); + } } - /// Borrows the layout data without checks. - #[inline(always)] - pub unsafe fn borrow_layout_data_unchecked(&self) -> *const Option<LayoutDataWrapper> { - mem::transmute(self.get_jsmanaged().layout_data_unchecked()) + fn debug_str(self) -> String { + format!("{:?}: changed={} dirty={} dirty_descendants={}", + self.type_id(), self.has_changed(), self.is_dirty(), self.has_dirty_descendants()) } - /// Borrows the layout data immutably. Fails on a conflicting borrow. - #[inline(always)] - pub fn borrow_layout_data(&self) -> Ref<Option<LayoutDataWrapper>> { - unsafe { - mem::transmute(self.get_jsmanaged().layout_data()) + pub fn flow_debug_id(self) -> usize { + let layout_data_ref = self.borrow_layout_data(); + match *layout_data_ref { + None => 0, + Some(ref layout_data) => layout_data.data.flow_construction_result.debug_id() } } - /// Borrows the layout data mutably. Fails on a conflicting borrow. - #[inline(always)] - pub fn mutate_layout_data(&self) -> RefMut<Option<LayoutDataWrapper>> { - unsafe { - mem::transmute(self.get_jsmanaged().layout_data_mut()) - } + /// 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> { + &self.node } } -pub struct LayoutNodeChildrenIterator<'a> { - current: Option<LayoutNode<'a>>, +pub struct LayoutNodeChildrenIterator<'a, Wrappers: WrapperTypes<'a>> { + current: Option<Wrappers::Node>, } -impl<'a> Iterator for LayoutNodeChildrenIterator<'a> { - type Item = LayoutNode<'a>; - fn next(&mut self) -> Option<LayoutNode<'a>> { +impl<'a, Wrappers: WrapperTypes<'a>> Iterator for LayoutNodeChildrenIterator<'a, Wrappers> { + type Item = Wrappers::Node; + fn next(&mut self) -> Option<Wrappers::Node> { let node = self.current; self.current = node.and_then(|node| node.next_sibling()); node } } -pub struct LayoutNodeReverseChildrenIterator<'a> { - current: Option<LayoutNode<'a>>, +pub struct LayoutNodeReverseChildrenIterator<'a, Wrappers: WrapperTypes<'a>> { + current: Option<Wrappers::Node>, } -impl<'a> Iterator for LayoutNodeReverseChildrenIterator<'a> { - type Item = LayoutNode<'a>; - fn next(&mut self) -> Option<LayoutNode<'a>> { +impl<'a, Wrappers: WrapperTypes<'a>> Iterator for LayoutNodeReverseChildrenIterator<'a, Wrappers> { + type Item = Wrappers::Node; + fn next(&mut self) -> Option<Wrappers::Node> { let node = self.current; self.current = node.and_then(|node| node.prev_sibling()); node } } -pub struct LayoutTreeIterator<'a> { - stack: Vec<LayoutNode<'a>>, +pub struct LayoutTreeIterator<'a, Wrappers: WrapperTypes<'a>> { + stack: Vec<Wrappers::Node>, } -impl<'a> LayoutTreeIterator<'a> { - fn new(root: LayoutNode<'a>) -> LayoutTreeIterator<'a> { +impl<'a, Wrappers> LayoutTreeIterator<'a, Wrappers> where Wrappers: WrapperTypes<'a> { + fn new(root: Wrappers::Node) -> LayoutTreeIterator<'a, Wrappers> { let mut stack = vec!(); stack.push(root); LayoutTreeIterator { @@ -343,9 +492,9 @@ impl<'a> LayoutTreeIterator<'a> { } } -impl<'a> Iterator for LayoutTreeIterator<'a> { - type Item = LayoutNode<'a>; - fn next(&mut self) -> Option<LayoutNode<'a>> { +impl<'a, Wrappers> Iterator for LayoutTreeIterator<'a, Wrappers> where Wrappers: WrapperTypes<'a> { + type Item = Wrappers::Node; + fn next(&mut self) -> Option<Wrappers::Node> { let ret = self.stack.pop(); ret.map(|node| self.stack.extend(node.rev_children())); ret @@ -354,33 +503,35 @@ impl<'a> Iterator for LayoutTreeIterator<'a> { // A wrapper around documents that ensures ayout can only ever access safe properties. #[derive(Copy, Clone)] -pub struct LayoutDocument<'le> { +pub struct LayoutDocument<'ld> { document: LayoutJS<Document>, - chain: PhantomData<&'le ()>, + chain: PhantomData<&'ld ()>, } -impl<'le> LayoutDocument<'le> { - fn from_layout_js(doc: LayoutJS<Document>) -> LayoutDocument<'le> { - LayoutDocument { - document: doc, - chain: PhantomData, - } - } - - pub fn as_node(&self) -> LayoutNode<'le> { +impl<'ld> LayoutDocumentTrait<'ld, ServoWrapperTypes<'ld>> for LayoutDocument<'ld> { + fn as_node(&self) -> LayoutNode<'ld> { LayoutNode::from_layout_js(self.document.upcast()) } - pub fn root_node(&self) -> Option<LayoutNode<'le>> { + fn root_node(&self) -> Option<LayoutNode<'ld>> { self.as_node().children().find(LayoutNode::is_element) } - pub fn drain_modified_elements(&self) -> Vec<(LayoutElement, ElementSnapshot)> { + fn drain_modified_elements(&self) -> Vec<(LayoutElement<'ld>, ElementSnapshot)> { let elements = unsafe { self.document.drain_modified_elements() }; elements.into_iter().map(|(el, snapshot)| (LayoutElement::from_layout_js(el), snapshot)).collect() } } +impl<'ld> LayoutDocument<'ld> { + fn from_layout_js(doc: LayoutJS<Document>) -> LayoutDocument<'ld> { + LayoutDocument { + document: doc, + chain: PhantomData, + } + } +} + /// A wrapper around elements that ensures layout can only ever access safe properties. #[derive(Copy, Clone)] pub struct LayoutElement<'le> { @@ -388,80 +539,28 @@ pub struct LayoutElement<'le> { chain: PhantomData<&'le ()>, } -impl<'le> LayoutElement<'le> { - fn from_layout_js(el: LayoutJS<Element>) -> LayoutElement<'le> { - LayoutElement { - element: el, - chain: PhantomData, - } +impl<'le> LayoutElementTrait<'le, ServoWrapperTypes<'le>> for LayoutElement<'le> { + fn as_node(&self) -> LayoutNode<'le> { + LayoutNode::from_layout_js(self.element.upcast()) } - pub fn style_attribute(&self) -> &'le Option<PropertyDeclarationBlock> { + fn style_attribute(&self) -> &'le Option<PropertyDeclarationBlock> { unsafe { &*self.element.style_attribute() } } - pub fn as_node(&self) -> LayoutNode<'le> { - LayoutNode::from_layout_js(self.element.upcast()) - } - - pub fn get_state(&self) -> ElementState { + fn get_state(&self) -> ElementState { self.element.get_state_for_layout() } +} - /// Properly marks nodes as dirty in response to restyle hints. - pub fn note_restyle_hint(&self, mut hint: RestyleHint) { - // Bail early if there's no restyling to do. - if hint.is_empty() { - return; - } - - // If the restyle hint is non-empty, we need to restyle either this element - // or one of its siblings. Mark our ancestor chain as having dirty descendants. - let node = self.as_node(); - let mut curr = node; - while let Some(parent) = curr.parent_node() { - if parent.has_dirty_descendants() { break } - unsafe { parent.set_dirty_descendants(true); } - curr = parent; - } - - // Set up our helpers. - fn dirty_node(node: &LayoutNode) { - unsafe { - node.set_dirty(true); - node.set_dirty_descendants(true); - } - } - fn dirty_descendants(node: &LayoutNode) { - for ref child in node.children() { - dirty_node(child); - dirty_descendants(child); - } - } - - // Process hints. - if hint.contains(RESTYLE_SELF) { - dirty_node(&node); - // FIXME(bholley, #8438): We currently need to RESTYLE_DESCENDANTS in the - // RESTYLE_SELF case in order to make sure "inherit" style structs propagate - // properly. See the explanation in the github issue. - hint.insert(RESTYLE_DESCENDANTS); - } - if hint.contains(RESTYLE_DESCENDANTS) { - unsafe { node.set_dirty_descendants(true); } - dirty_descendants(&node); - } - if hint.contains(RESTYLE_LATER_SIBLINGS) { - let mut next = ::selectors::Element::next_sibling_element(self); - while let Some(sib) = next { - let sib_node = sib.as_node(); - dirty_node(&sib_node); - dirty_descendants(&sib_node); - next = ::selectors::Element::next_sibling_element(&sib); - } +impl<'le> LayoutElement<'le> { + fn from_layout_js(el: LayoutJS<Element>) -> LayoutElement<'le> { + LayoutElement { + element: el, + chain: PhantomData, } } } |