diff --git a/components/layout/construct.rs b/components/layout/construct.rs index 8c79618a6ed..c600b0ce8e6 100644 --- a/components/layout/construct.rs +++ b/components/layout/construct.rs @@ -34,9 +34,8 @@ use list_item::{ListItemFlow, ListStyleTypeContent}; use multicol::{MulticolFlow, MulticolColumnFlow}; use parallel; use script::layout_interface::is_image_data; -use script::layout_interface::{CharacterDataTypeId, ElementTypeId}; -use script::layout_interface::{HTMLElementTypeId, NodeTypeId}; use script_layout_interface::restyle_damage::{BUBBLE_ISIZES, RECONSTRUCT_FLOW, RestyleDamage}; +use script_layout_interface::{LayoutNodeType, LayoutElementType}; use std::borrow::ToOwned; use std::collections::LinkedList; use std::marker::PhantomData; @@ -304,44 +303,35 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode> /// Builds the fragment for the given block or subclass thereof. fn build_fragment_for_block(&mut self, node: &ConcreteThreadSafeLayoutNode) -> Fragment { let specific_fragment_info = match node.type_id() { - Some(NodeTypeId::Element(ElementTypeId::HTMLElement( - HTMLElementTypeId::HTMLIFrameElement))) => { + Some(LayoutNodeType::Element(LayoutElementType::HTMLIFrameElement)) => { SpecificFragmentInfo::Iframe(IframeFragmentInfo::new(node)) } - Some(NodeTypeId::Element(ElementTypeId::HTMLElement( - HTMLElementTypeId::HTMLImageElement))) => { + Some(LayoutNodeType::Element(LayoutElementType::HTMLImageElement)) => { let image_info = box ImageFragmentInfo::new(node, node.image_url(), &self.layout_context); SpecificFragmentInfo::Image(image_info) } - Some(NodeTypeId::Element(ElementTypeId::HTMLElement( - HTMLElementTypeId::HTMLObjectElement))) => { + Some(LayoutNodeType::Element(LayoutElementType::HTMLObjectElement)) => { let image_info = box ImageFragmentInfo::new(node, node.object_data(), &self.layout_context); SpecificFragmentInfo::Image(image_info) } - Some(NodeTypeId::Element(ElementTypeId::HTMLElement( - HTMLElementTypeId::HTMLTableElement))) => { + Some(LayoutNodeType::Element(LayoutElementType::HTMLTableElement)) => { SpecificFragmentInfo::TableWrapper } - Some(NodeTypeId::Element(ElementTypeId::HTMLElement( - HTMLElementTypeId::HTMLTableColElement))) => { + Some(LayoutNodeType::Element(LayoutElementType::HTMLTableColElement)) => { SpecificFragmentInfo::TableColumn(TableColumnFragmentInfo::new(node)) } - Some(NodeTypeId::Element(ElementTypeId::HTMLElement( - HTMLElementTypeId::HTMLTableCellElement(_)))) => { + Some(LayoutNodeType::Element(LayoutElementType::HTMLTableCellElement)) => { SpecificFragmentInfo::TableCell } - Some(NodeTypeId::Element(ElementTypeId::HTMLElement( - HTMLElementTypeId::HTMLTableRowElement))) | - Some(NodeTypeId::Element(ElementTypeId::HTMLElement( - HTMLElementTypeId::HTMLTableSectionElement))) => { + Some(LayoutNodeType::Element(LayoutElementType::HTMLTableRowElement)) | + Some(LayoutNodeType::Element(LayoutElementType::HTMLTableSectionElement)) => { SpecificFragmentInfo::TableRow } - Some(NodeTypeId::Element(ElementTypeId::HTMLElement( - HTMLElementTypeId::HTMLCanvasElement))) => { + Some(LayoutNodeType::Element(LayoutElementType::HTMLCanvasElement)) => { let data = node.canvas_data().unwrap(); SpecificFragmentInfo::Canvas(box CanvasFragmentInfo::new(node, data, self.layout_context)) } @@ -690,16 +680,13 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode> -> ConstructionResult { let mut initial_fragments = IntermediateInlineFragments::new(); let node_is_input_or_text_area = - node.type_id() == Some(NodeTypeId::Element(ElementTypeId::HTMLElement( - HTMLElementTypeId::HTMLInputElement))) || - node.type_id() == Some(NodeTypeId::Element(ElementTypeId::HTMLElement( - HTMLElementTypeId::HTMLTextAreaElement))); + node.type_id() == Some(LayoutNodeType::Element(LayoutElementType::HTMLInputElement)) || + node.type_id() == Some(LayoutNodeType::Element(LayoutElementType::HTMLTextAreaElement)); if node.get_pseudo_element_type().is_replaced_content() || node_is_input_or_text_area { // A TextArea's text contents are displayed through the input text // box, so don't construct them. - if node.type_id() == Some(NodeTypeId::Element(ElementTypeId::HTMLElement( - HTMLElementTypeId::HTMLTextAreaElement))) { + if node.type_id() == Some(LayoutNodeType::Element(LayoutElementType::HTMLTextAreaElement)) { for kid in node.children() { self.set_flow_construction_result(&kid, ConstructionResult::None) } @@ -971,7 +958,7 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode> // fragment that needs to be generated for this inline node. let mut fragments = IntermediateInlineFragments::new(); match (node.get_pseudo_element_type(), node.type_id()) { - (_, Some(NodeTypeId::CharacterData(CharacterDataTypeId::Text))) => { + (_, Some(LayoutNodeType::Text)) => { self.create_fragments_for_node_text_content(&mut fragments, node, &style) } (PseudoElementType::Normal, _) => { @@ -1525,7 +1512,7 @@ impl<'a, ConcreteThreadSafeLayoutNode> PostorderNodeMutTraversal { + Some(LayoutNodeType::Element(_)) => { let style = node.style(self.style_context()); let original_display = style.get_box()._servo_display_for_hypothetical_box; let munged_display = match original_display { @@ -1534,13 +1521,13 @@ impl<'a, ConcreteThreadSafeLayoutNode> PostorderNodeMutTraversal + Some(LayoutNodeType::Text) => (display::T::inline, float::T::none, position::T::static_), - Some(NodeTypeId::CharacterData(CharacterDataTypeId::Comment)) | - Some(NodeTypeId::CharacterData(CharacterDataTypeId::ProcessingInstruction)) | - Some(NodeTypeId::DocumentType) | - Some(NodeTypeId::DocumentFragment) | - Some(NodeTypeId::Document(_)) => { + Some(LayoutNodeType::Comment) | + Some(LayoutNodeType::ProcessingInstruction) | + Some(LayoutNodeType::DocumentType) | + Some(LayoutNodeType::DocumentFragment) | + Some(LayoutNodeType::Document) => { (display::T::none, float::T::none, position::T::static_) } }; @@ -1679,19 +1666,17 @@ impl NodeUtils for ConcreteThreadSafeLayoutNode where ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode { fn is_replaced_content(&self) -> bool { match self.type_id() { - Some(NodeTypeId::CharacterData(_)) | - Some(NodeTypeId::DocumentType) | - Some(NodeTypeId::DocumentFragment) | - Some(NodeTypeId::Document(_)) | - Some(NodeTypeId::Element(ElementTypeId::HTMLElement( - HTMLElementTypeId::HTMLImageElement))) | - Some(NodeTypeId::Element(ElementTypeId::HTMLElement( - HTMLElementTypeId::HTMLIFrameElement))) | - Some(NodeTypeId::Element(ElementTypeId::HTMLElement( - HTMLElementTypeId::HTMLCanvasElement))) => true, - Some(NodeTypeId::Element(ElementTypeId::HTMLElement( - HTMLElementTypeId::HTMLObjectElement))) => self.has_object_data(), - Some(NodeTypeId::Element(_)) => false, + Some(LayoutNodeType::Comment) | + Some(LayoutNodeType::ProcessingInstruction) | + Some(LayoutNodeType::Text) | + Some(LayoutNodeType::DocumentType) | + Some(LayoutNodeType::DocumentFragment) | + Some(LayoutNodeType::Document) | + Some(LayoutNodeType::Element(LayoutElementType::HTMLImageElement)) | + Some(LayoutNodeType::Element(LayoutElementType::HTMLIFrameElement)) | + Some(LayoutNodeType::Element(LayoutElementType::HTMLCanvasElement)) => true, + Some(LayoutNodeType::Element(LayoutElementType::HTMLObjectElement)) => self.has_object_data(), + Some(LayoutNodeType::Element(_)) => false, None => self.get_pseudo_element_type().is_replaced_content(), } } diff --git a/components/layout/wrapper.rs b/components/layout/wrapper.rs index ce4fe30c075..d8a61bb2a27 100644 --- a/components/layout/wrapper.rs +++ b/components/layout/wrapper.rs @@ -44,6 +44,7 @@ use script::layout_interface::{HTMLCanvasData, HTMLElementTypeId, LayoutCharacte use script::layout_interface::{LayoutDocumentHelpers, LayoutElementHelpers, LayoutJS}; use script::layout_interface::{LayoutNodeHelpers, Node, NodeTypeId}; use script::layout_interface::{RawLayoutElementHelpers, Text, TrustedNodeAddress}; +use script_layout_interface::LayoutNodeType; use script_layout_interface::restyle_damage::RestyleDamage; use script_layout_interface::{OpaqueStyleAndLayoutData, PartialStyleAndLayoutData}; use selectors::matching::{DeclarationBlock, ElementFlags}; @@ -77,7 +78,7 @@ pub trait LayoutNode: TNode { fn to_threadsafe(&self) -> Self::ConcreteThreadSafeLayoutNode; /// Returns the type ID of this node. - fn type_id(&self) -> NodeTypeId; + fn type_id(&self) -> LayoutNodeType; fn get_style_data(&self) -> Option<&RefCell>; @@ -130,6 +131,12 @@ impl<'ln> ServoLayoutNode<'ln> { chain: self.chain, } } + + fn script_type_id(&self) -> NodeTypeId { + unsafe { + self.node.type_id_for_layout() + } + } } impl<'ln> TNode for ServoLayoutNode<'ln> { @@ -151,7 +158,7 @@ impl<'ln> TNode for ServoLayoutNode<'ln> { } fn is_text_node(&self) -> bool { - self.type_id() == NodeTypeId::CharacterData(CharacterDataTypeId::Text) + self.script_type_id() == NodeTypeId::CharacterData(CharacterDataTypeId::Text) } fn is_element(&self) -> bool { @@ -288,10 +295,8 @@ impl<'ln> LayoutNode for ServoLayoutNode<'ln> { ServoThreadSafeLayoutNode::new(self) } - fn type_id(&self) -> NodeTypeId { - unsafe { - self.node.type_id_for_layout() - } + fn type_id(&self) -> LayoutNodeType { + self.script_type_id().into() } fn get_style_data(&self) -> Option<&RefCell> { @@ -375,7 +380,7 @@ impl<'ln> ServoLayoutNode<'ln> { fn debug_str(self) -> String { format!("{:?}: changed={} dirty={} dirty_descendants={}", - self.type_id(), self.has_changed(), self.is_dirty(), self.has_dirty_descendants()) + self.script_type_id(), self.has_changed(), self.is_dirty(), self.has_dirty_descendants()) } /// Returns the interior of this node as a `LayoutJS`. This is highly unsafe for layout to @@ -526,7 +531,7 @@ impl<'le> ::selectors::Element for ServoLayoutElement<'le> { match self.as_node().parent_node() { None => false, Some(node) => { - match node.type_id() { + match node.script_type_id() { NodeTypeId::Document(_) => true, _ => false } @@ -535,7 +540,7 @@ impl<'le> ::selectors::Element for ServoLayoutElement<'le> { } fn is_empty(&self) -> bool { - self.as_node().children().all(|node| match node.type_id() { + self.as_node().children().all(|node| match node.script_type_id() { NodeTypeId::Element(..) => false, NodeTypeId::CharacterData(CharacterDataTypeId::Text) => unsafe { node.node.downcast().unwrap().data_for_layout().is_empty() @@ -559,7 +564,7 @@ impl<'le> ::selectors::Element for ServoLayoutElement<'le> { // https://github.com/servo/servo/issues/8718 NonTSPseudoClass::Link | NonTSPseudoClass::AnyLink => unsafe { - match self.as_node().type_id() { + match self.as_node().script_type_id() { // https://html.spec.whatwg.org/multipage/#selector-link NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLAnchorElement)) | NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLAreaElement)) | @@ -708,16 +713,16 @@ pub trait ThreadSafeLayoutNode: Clone + Copy + Sized + PartialEq { /// Returns the type ID of this node. /// Returns `None` if this is a pseudo-element; otherwise, returns `Some`. - fn type_id(&self) -> Option; + fn type_id(&self) -> Option; /// Returns the type ID of this node, without discarding pseudo-elements as /// `type_id` does. - fn type_id_without_excluding_pseudo_elements(&self) -> NodeTypeId; + fn type_id_without_excluding_pseudo_elements(&self) -> LayoutNodeType; #[inline] fn is_element_or_elements_pseudo(&self) -> bool { match self.type_id_without_excluding_pseudo_elements() { - NodeTypeId::Element(..) => true, + LayoutNodeType::Element(..) => true, _ => false, } } @@ -728,7 +733,7 @@ pub trait ThreadSafeLayoutNode: Clone + Copy + Sized + PartialEq { fn children(&self) -> Self::ChildrenIterator; #[inline] - fn is_element(&self) -> bool { if let Some(NodeTypeId::Element(_)) = self.type_id() { true } else { false } } + fn is_element(&self) -> bool { if let Some(LayoutNodeType::Element(_)) = self.type_id() { true } else { false } } /// If this is an element, accesses the element data. Fails if this is not an element node. #[inline] @@ -909,7 +914,7 @@ pub trait ThreadSafeLayoutNode: Clone + Copy + Sized + PartialEq { /// `empty_cells` per CSS 2.1 ยง 17.6.1.1. fn is_content(&self) -> bool { match self.type_id() { - Some(NodeTypeId::Element(..)) | Some(NodeTypeId::CharacterData(CharacterDataTypeId::Text)) => true, + Some(LayoutNodeType::Element(..)) | Some(LayoutNodeType::Text) => true, _ => false } } @@ -1075,7 +1080,7 @@ impl<'ln> ThreadSafeLayoutNode for ServoThreadSafeLayoutNode<'ln> { OpaqueNodeMethods::from_jsmanaged(unsafe { self.get_jsmanaged() }) } - fn type_id(&self) -> Option { + fn type_id(&self) -> Option { if self.pseudo != PseudoElementType::Normal { return None } @@ -1084,7 +1089,7 @@ impl<'ln> ThreadSafeLayoutNode for ServoThreadSafeLayoutNode<'ln> { } #[inline] - fn type_id_without_excluding_pseudo_elements(&self) -> NodeTypeId { + fn type_id_without_excluding_pseudo_elements(&self) -> LayoutNodeType { self.node.type_id() } diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index a6834d487d4..b803f41766c 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -21,8 +21,8 @@ use dom::bindings::codegen::UnionTypes::NodeOrString; use dom::bindings::conversions::{self, DerivedFrom}; use dom::bindings::error::{Error, ErrorResult, Fallible}; use dom::bindings::global::GlobalRef; -use dom::bindings::inheritance::{Castable, CharacterDataTypeId}; -use dom::bindings::inheritance::{EventTargetTypeId, NodeTypeId}; +use dom::bindings::inheritance::{Castable, CharacterDataTypeId, ElementTypeId}; +use dom::bindings::inheritance::{EventTargetTypeId, HTMLElementTypeId, NodeTypeId}; use dom::bindings::js::Root; use dom::bindings::js::RootedReference; use dom::bindings::js::{JS, LayoutJS, MutNullableHeap}; @@ -62,6 +62,7 @@ use msg::constellation_msg::PipelineId; use parse::html::parse_html_fragment; use ref_slice::ref_slice; use script_layout_interface::OpaqueStyleAndLayoutData; +use script_layout_interface::{LayoutNodeType, LayoutElementType}; use script_traits::UntrustedNodeAddress; use selectors::matching::matches; use selectors::parser::Selector; @@ -2634,3 +2635,56 @@ impl UniqueId { } } } + +impl Into for NodeTypeId { + #[inline(always)] + fn into(self) -> LayoutNodeType { + match self { + NodeTypeId::CharacterData(CharacterDataTypeId::Comment) => + LayoutNodeType::Comment, + NodeTypeId::Document(..) => + LayoutNodeType::Document, + NodeTypeId::DocumentFragment => + LayoutNodeType::DocumentFragment, + NodeTypeId::DocumentType => + LayoutNodeType::DocumentType, + NodeTypeId::Element(e) => + LayoutNodeType::Element(e.into()), + NodeTypeId::CharacterData(CharacterDataTypeId::ProcessingInstruction) => + LayoutNodeType::ProcessingInstruction, + NodeTypeId::CharacterData(CharacterDataTypeId::Text) => + LayoutNodeType::Text, + } + } +} + +impl Into for ElementTypeId { + #[inline(always)] + fn into(self) -> LayoutElementType { + match self { + ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLCanvasElement) => + LayoutElementType::HTMLCanvasElement, + ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLIFrameElement) => + LayoutElementType::HTMLIFrameElement, + ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLImageElement) => + LayoutElementType::HTMLImageElement, + ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLInputElement) => + LayoutElementType::HTMLInputElement, + ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLObjectElement) => + LayoutElementType::HTMLObjectElement, + ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLTableCellElement(_)) => + LayoutElementType::HTMLTableCellElement, + ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLTableColElement) => + LayoutElementType::HTMLTableColElement, + ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLTableElement) => + LayoutElementType::HTMLTableElement, + ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLTableRowElement) => + LayoutElementType::HTMLTableRowElement, + ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLTableSectionElement) => + LayoutElementType::HTMLTableSectionElement, + ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLTextAreaElement) => + LayoutElementType::HTMLTextAreaElement, + _ => LayoutElementType::Element, + } + } +} diff --git a/components/script_layout_interface/lib.rs b/components/script_layout_interface/lib.rs index 7c1a4e28e29..0b3e1bce3e6 100644 --- a/components/script_layout_interface/lib.rs +++ b/components/script_layout_interface/lib.rs @@ -42,3 +42,30 @@ pub struct OpaqueStyleAndLayoutData { #[allow(unsafe_code)] unsafe impl Send for OpaqueStyleAndLayoutData {} + +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +pub enum LayoutNodeType { + Comment, + Document, + DocumentFragment, + DocumentType, + Element(LayoutElementType), + ProcessingInstruction, + Text, +} + +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +pub enum LayoutElementType { + Element, + HTMLCanvasElement, + HTMLIFrameElement, + HTMLImageElement, + HTMLInputElement, + HTMLObjectElement, + HTMLTableCellElement, + HTMLTableColElement, + HTMLTableElement, + HTMLTableRowElement, + HTMLTableSectionElement, + HTMLTextAreaElement, +}