aboutsummaryrefslogtreecommitdiffstats
path: root/components
diff options
context:
space:
mode:
authorSimon Sapin <simon.sapin@exyr.org>2015-03-03 21:16:24 +0100
committerSimon Sapin <simon.sapin@exyr.org>2015-03-03 21:16:24 +0100
commit4c1d778ced267eeef790d4166e361d9348b933d3 (patch)
treeccdd9544f8f4b7a2f6299244915584fcbf5cfc18 /components
parent7a218b3f08c95b5c1a14ef1bbf09658d61b8d342 (diff)
downloadservo-4c1d778ced267eeef790d4166e361d9348b933d3.tar.gz
servo-4c1d778ced267eeef790d4166e361d9348b933d3.zip
Revert "layout: Implement ordered lists, CSS counters, and `quotes` per CSS 2.1"
This reverts commit 30fd28d1077fbb3f47140f6ab1252c0d24f44d23.
Diffstat (limited to 'components')
-rw-r--r--components/layout/block.rs39
-rw-r--r--components/layout/construct.rs252
-rw-r--r--components/layout/display_list_builder.rs1
-rw-r--r--components/layout/flow.rs118
-rw-r--r--components/layout/fragment.rs162
-rw-r--r--components/layout/generated_content.rs573
-rw-r--r--components/layout/incremental.rs48
-rw-r--r--components/layout/inline.rs22
-rw-r--r--components/layout/layout_task.rs8
-rw-r--r--components/layout/lib.rs3
-rw-r--r--components/layout/list_item.rs97
-rw-r--r--components/layout/sequential.rs24
-rw-r--r--components/layout/table.rs61
-rw-r--r--components/layout/table_caption.rs14
-rw-r--r--components/layout/table_cell.rs6
-rw-r--r--components/layout/table_colgroup.rs4
-rw-r--r--components/layout/table_row.rs23
-rw-r--r--components/layout/table_rowgroup.rs16
-rw-r--r--components/layout/table_wrapper.rs27
-rw-r--r--components/layout/traversal.rs5
-rw-r--r--components/layout/wrapper.rs47
-rw-r--r--components/script/dom/webidls/CSSStyleDeclaration.webidl5
-rw-r--r--components/style/properties.mako.rs423
-rw-r--r--components/util/time.rs3
24 files changed, 494 insertions, 1487 deletions
diff --git a/components/layout/block.rs b/components/layout/block.rs
index a6a4a3c07a1..822ec6bfb82 100644
--- a/components/layout/block.rs
+++ b/components/layout/block.rs
@@ -27,6 +27,7 @@
#![deny(unsafe_blocks)]
+use construct::FlowConstructor;
use context::LayoutContext;
use css::node_style::StyledNode;
use display_list_builder::{BlockFlowDisplayListBuilding, FragmentDisplayListBuilding};
@@ -39,8 +40,7 @@ use flow::{IMPACTED_BY_LEFT_FLOATS, IMPACTED_BY_RIGHT_FLOATS};
use flow::{LAYERS_NEEDED_FOR_DESCENDANTS, NEEDS_LAYER};
use flow::{IS_ABSOLUTELY_POSITIONED};
use flow::{CLEARS_LEFT, CLEARS_RIGHT};
-use fragment::{CoordinateSystem, Fragment, FragmentBorderBoxIterator, FragmentMutator};
-use fragment::{SpecificFragmentInfo};
+use fragment::{CoordinateSystem, Fragment, FragmentBorderBoxIterator, SpecificFragmentInfo};
use incremental::{REFLOW, REFLOW_OUT_OF_FLOW};
use layout_debug;
use model::{IntrinsicISizes, MarginCollapseInfo};
@@ -569,6 +569,20 @@ impl Encodable for BlockFlowFlags {
}
impl BlockFlow {
+ pub fn from_node(constructor: &mut FlowConstructor, node: &ThreadSafeLayoutNode) -> BlockFlow {
+ let writing_mode = node.style().writing_mode;
+ BlockFlow {
+ base: BaseFlow::new(Some((*node).clone()), writing_mode, ForceNonfloatedFlag::ForceNonfloated),
+ fragment: Fragment::new(constructor, node),
+ static_b_offset: Au::new(0),
+ inline_size_of_preceding_left_floats: Au(0),
+ inline_size_of_preceding_right_floats: Au(0),
+ hypothetical_position: LogicalPoint::new(writing_mode, Au(0), Au(0)),
+ float: None,
+ flags: BlockFlowFlags::empty(),
+ }
+ }
+
pub fn from_node_and_fragment(node: &ThreadSafeLayoutNode, fragment: Fragment) -> BlockFlow {
let writing_mode = node.style().writing_mode;
BlockFlow {
@@ -583,6 +597,23 @@ impl BlockFlow {
}
}
+ pub fn float_from_node(constructor: &mut FlowConstructor,
+ node: &ThreadSafeLayoutNode,
+ float_kind: FloatKind)
+ -> BlockFlow {
+ let writing_mode = node.style().writing_mode;
+ BlockFlow {
+ base: BaseFlow::new(Some((*node).clone()), writing_mode, ForceNonfloatedFlag::FloatIfNecessary),
+ fragment: Fragment::new(constructor, node),
+ static_b_offset: Au::new(0),
+ inline_size_of_preceding_left_floats: Au(0),
+ inline_size_of_preceding_right_floats: Au(0),
+ hypothetical_position: LogicalPoint::new(writing_mode, Au(0), Au(0)),
+ float: Some(box FloatedBlockInfo::new(float_kind)),
+ flags: BlockFlowFlags::empty(),
+ }
+ }
+
pub fn float_from_node_and_fragment(node: &ThreadSafeLayoutNode,
fragment: Fragment,
float_kind: FloatKind)
@@ -1888,10 +1919,6 @@ impl Flow for BlockFlow {
CoordinateSystem::Parent)
.translate(stacking_context_position));
}
-
- fn mutate_fragments(&mut self, mutator: &mut FragmentMutator) {
- mutator.process(&mut self.fragment)
- }
}
impl fmt::Debug for BlockFlow {
diff --git a/components/layout/construct.rs b/components/layout/construct.rs
index 82c941b4d67..b2ea8090ea6 100644
--- a/components/layout/construct.rs
+++ b/components/layout/construct.rs
@@ -13,27 +13,33 @@
#![deny(unsafe_blocks)]
+use css::node_style::StyledNode;
use block::BlockFlow;
use context::LayoutContext;
-use css::node_style::StyledNode;
use floats::FloatKind;
-use flow::{self, AbsDescendants, Descendants, Flow, IS_ABSOLUTELY_POSITIONED, ImmutableFlowUtils};
-use flow::{MutableOwnedFlowUtils};
+use flow::{Flow, ImmutableFlowUtils, MutableOwnedFlowUtils};
+use flow::{Descendants, AbsDescendants};
+use flow::{IS_ABSOLUTELY_POSITIONED};
+use flow;
use flow_ref::FlowRef;
-use fragment::{CanvasFragmentInfo, Fragment, GeneratedContentInfo, IframeFragmentInfo};
-use fragment::{ImageFragmentInfo, InlineAbsoluteHypotheticalFragmentInfo, InlineBlockFragmentInfo};
-use fragment::{SpecificFragmentInfo, TableColumnFragmentInfo, UnscannedTextFragmentInfo};
+use fragment::{Fragment, IframeFragmentInfo};
+use fragment::ImageFragmentInfo;
+use fragment::CanvasFragmentInfo;
+use fragment::InlineAbsoluteHypotheticalFragmentInfo;
+use fragment::{InlineBlockFragmentInfo, SpecificFragmentInfo};
+use fragment::TableColumnFragmentInfo;
+use fragment::UnscannedTextFragmentInfo;
use incremental::{RECONSTRUCT_FLOW, RestyleDamage};
use inline::InlineFlow;
-use list_item::{ListItemFlow, ListStyleTypeContent};
+use list_item::{self, ListItemFlow};
use parallel;
+use table_wrapper::TableWrapperFlow;
use table::TableFlow;
use table_caption::TableCaptionFlow;
-use table_cell::TableCellFlow;
use table_colgroup::TableColGroupFlow;
-use table_row::TableRowFlow;
use table_rowgroup::TableRowGroupFlow;
-use table_wrapper::TableWrapperFlow;
+use table_row::TableRowFlow;
+use table_cell::TableCellFlow;
use text::TextRunScanner;
use util::{HAS_NEWLY_CONSTRUCTED_FLOW, LayoutDataAccess, OpaqueNodeMethods, LayoutDataWrapper};
use wrapper::{PostorderNodeMutTraversal, PseudoElementType, TLayoutNode, ThreadSafeLayoutNode};
@@ -48,10 +54,9 @@ use std::borrow::ToOwned;
use std::collections::DList;
use std::mem;
use std::sync::atomic::Ordering;
-use style::computed_values::content::ContentItem;
use style::computed_values::{caption_side, display, empty_cells, float, list_style_position};
use style::computed_values::{position};
-use style::properties::{self, ComputedValues};
+use style::properties::{ComputedValues, make_inline};
use std::sync::Arc;
use url::Url;
@@ -245,51 +250,41 @@ impl<'a> FlowConstructor<'a> {
}
}
- /// Builds the fragment for the given block or subclass thereof.
- fn build_fragment_for_block(&mut self, node: &ThreadSafeLayoutNode) -> Fragment {
- let specific_fragment_info = match node.type_id() {
- Some(NodeTypeId::Element(ElementTypeId::HTMLElement(
- HTMLElementTypeId::HTMLIFrameElement))) => {
+ /// Builds specific `Fragment` info for the given node.
+ ///
+ /// This does *not* construct the text for generated content (but, for generated content with
+ /// `display: block`, it does construct the generic fragment corresponding to the block).
+ /// Construction of the text fragment is done specially by `build_flow_using_children()` and
+ /// `build_fragments_for_replaced_inline_content()`.
+ pub fn build_specific_fragment_info_for_node(&mut self, node: &ThreadSafeLayoutNode)
+ -> SpecificFragmentInfo {
+ match node.type_id() {
+ Some(NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLIFrameElement))) => {
SpecificFragmentInfo::Iframe(box IframeFragmentInfo::new(node))
}
- Some(NodeTypeId::Element(ElementTypeId::HTMLElement(
- HTMLElementTypeId::HTMLImageElement))) => {
+ Some(NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLImageElement))) => {
self.build_fragment_info_for_image(node, node.image_url())
}
- Some(NodeTypeId::Element(ElementTypeId::HTMLElement(
- HTMLElementTypeId::HTMLObjectElement))) => {
+ Some(NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLObjectElement))) => {
let data = node.get_object_data();
self.build_fragment_info_for_image(node, data)
}
- Some(NodeTypeId::Element(ElementTypeId::HTMLElement(
- HTMLElementTypeId::HTMLTableElement))) => {
- SpecificFragmentInfo::TableWrapper
- }
- Some(NodeTypeId::Element(ElementTypeId::HTMLElement(
- HTMLElementTypeId::HTMLTableColElement))) => {
+ Some(NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLTableElement))) => SpecificFragmentInfo::TableWrapper,
+ Some(NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLTableColElement))) => {
SpecificFragmentInfo::TableColumn(TableColumnFragmentInfo::new(node))
}
- Some(NodeTypeId::Element(ElementTypeId::HTMLElement(
- HTMLElementTypeId::HTMLTableCellElement(_)))) => {
- SpecificFragmentInfo::TableCell
- }
- Some(NodeTypeId::Element(ElementTypeId::HTMLElement(
- HTMLElementTypeId::HTMLTableRowElement))) |
- Some(NodeTypeId::Element(ElementTypeId::HTMLElement(
- HTMLElementTypeId::HTMLTableSectionElement))) => {
- SpecificFragmentInfo::TableRow
- }
- Some(NodeTypeId::Element(ElementTypeId::HTMLElement(
- HTMLElementTypeId::HTMLCanvasElement))) => {
+ Some(NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLTableCellElement(_)))) => SpecificFragmentInfo::TableCell,
+ Some(NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLTableRowElement))) |
+ Some(NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLTableSectionElement))) => SpecificFragmentInfo::TableRow,
+ Some(NodeTypeId::Text) => SpecificFragmentInfo::UnscannedText(UnscannedTextFragmentInfo::new(node)),
+ Some(NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLCanvasElement))) => {
SpecificFragmentInfo::Canvas(box CanvasFragmentInfo::new(node))
}
_ => {
// This includes pseudo-elements.
SpecificFragmentInfo::Generic
}
- };
-
- Fragment::new(node, specific_fragment_info)
+ }
}
/// Creates an inline flow from a set of inline fragments, then adds it as a child of the given
@@ -329,9 +324,7 @@ impl<'a> FlowConstructor<'a> {
let mut inline_block_flows = vec!();
for f in fragments.iter() {
match f.specific {
- SpecificFragmentInfo::InlineBlock(ref info) => {
- inline_block_flows.push(info.flow_ref.clone())
- }
+ SpecificFragmentInfo::InlineBlock(ref info) => inline_block_flows.push(info.flow_ref.clone()),
SpecificFragmentInfo::InlineAbsoluteHypothetical(ref info) => {
inline_block_flows.push(info.flow_ref.clone())
}
@@ -465,8 +458,8 @@ impl<'a> FlowConstructor<'a> {
whitespace_damage)) => {
// Add whitespace results. They will be stripped out later on when
// between block elements, and retained when between inline elements.
- let fragment_info = SpecificFragmentInfo::UnscannedText(
- UnscannedTextFragmentInfo::from_text(" ".to_owned()));
+ let fragment_info =
+ SpecificFragmentInfo::UnscannedText(UnscannedTextFragmentInfo::from_text(" ".to_owned()));
let fragment = Fragment::from_opaque_node_and_style(whitespace_node,
whitespace_style,
whitespace_damage,
@@ -562,22 +555,18 @@ impl<'a> FlowConstructor<'a> {
fn build_flow_for_block(&mut self, flow: FlowRef, node: &ThreadSafeLayoutNode)
-> ConstructionResult {
let initial_fragment = if node.get_pseudo_element_type() != PseudoElementType::Normal ||
- node.type_id() == Some(NodeTypeId::Element(ElementTypeId::HTMLElement(
- HTMLElementTypeId::HTMLInputElement))) ||
- node.type_id() == Some(NodeTypeId::Element(ElementTypeId::HTMLElement(
- HTMLElementTypeId::HTMLTextAreaElement))) {
+ node.type_id() == Some(NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLInputElement))) ||
+ node.type_id() == Some(NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLTextAreaElement))) {
// 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(NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLTextAreaElement))) {
for kid in node.children() {
kid.set_flow_construction_result(ConstructionResult::None)
}
}
-
- let mut fragments = DList::new();
- self.create_fragments_for_node_text_content(&mut fragments, node, node.style());
- fragments.into_iter().next()
+ Some(Fragment::new_from_specific_info(
+ node,
+ SpecificFragmentInfo::UnscannedText(UnscannedTextFragmentInfo::new(node))))
} else {
None
};
@@ -585,39 +574,12 @@ impl<'a> FlowConstructor<'a> {
self.build_flow_for_block_starting_with_fragment(flow, node, initial_fragment)
}
- /// Pushes fragments appropriate for the content of the given node onto the given list.
- fn create_fragments_for_node_text_content(&self,
- fragments: &mut DList<Fragment>,
- node: &ThreadSafeLayoutNode,
- style: &Arc<ComputedValues>) {
- for content_item in node.text_content().into_iter() {
- let specific = match content_item {
- ContentItem::String(string) => {
- let info = UnscannedTextFragmentInfo::from_text(string);
- SpecificFragmentInfo::UnscannedText(info)
- }
- content_item => {
- let content_item = box GeneratedContentInfo::ContentItem(content_item);
- SpecificFragmentInfo::GeneratedContent(content_item)
- }
- };
-
- let opaque_node = OpaqueNodeMethods::from_thread_safe_layout_node(node);
- fragments.push_back(Fragment::from_opaque_node_and_style(opaque_node,
- style.clone(),
- node.restyle_damage(),
- specific))
- }
- }
-
-
/// Builds a flow for a node with `display: block`. This yields a `BlockFlow` with possibly
/// other `BlockFlow`s or `InlineFlow`s underneath it, depending on whether {ib} splits needed
/// to happen.
fn build_flow_for_nonfloated_block(&mut self, node: &ThreadSafeLayoutNode)
-> ConstructionResult {
- let flow = box BlockFlow::from_node_and_fragment(node, self.build_fragment_for_block(node))
- as Box<Flow>;
+ let flow = box BlockFlow::from_node(self, node) as Box<Flow>;
self.build_flow_for_block(FlowRef::new(flow), node)
}
@@ -625,9 +587,7 @@ impl<'a> FlowConstructor<'a> {
/// a `BlockFlow` underneath it.
fn build_flow_for_floated_block(&mut self, node: &ThreadSafeLayoutNode, float_kind: FloatKind)
-> ConstructionResult {
- let fragment = self.build_fragment_for_block(node);
- let flow = box BlockFlow::float_from_node_and_fragment(node, fragment, float_kind) as
- Box<Flow>;
+ let flow = box BlockFlow::float_from_node(self, node, float_kind) as Box<Flow>;
self.build_flow_for_block(FlowRef::new(flow), node)
}
@@ -695,8 +655,8 @@ impl<'a> FlowConstructor<'a> {
whitespace_style,
whitespace_damage)) => {
// Instantiate the whitespace fragment.
- let fragment_info = SpecificFragmentInfo::UnscannedText(
- UnscannedTextFragmentInfo::from_text(" ".to_owned()));
+ let fragment_info = SpecificFragmentInfo::UnscannedText(UnscannedTextFragmentInfo::from_text(
+ " ".to_owned()));
let fragment = Fragment::from_opaque_node_and_style(whitespace_node,
whitespace_style,
whitespace_damage,
@@ -750,22 +710,30 @@ impl<'a> FlowConstructor<'a> {
// `baz` had better not be absolutely positioned!
let mut style = (*node.style()).clone();
if style.get_box().display != display::T::inline {
- style = Arc::new(properties::make_inline(&*style))
+ style = Arc::new(make_inline(&*style))
}
// If this is generated content, then we need to initialize the accumulator with the
// fragment corresponding to that content. Otherwise, just initialize with the ordinary
// fragment that needs to be generated for this inline node.
+ let fragment = if node.get_pseudo_element_type() != PseudoElementType::Normal {
+ let fragment_info =
+ SpecificFragmentInfo::UnscannedText(UnscannedTextFragmentInfo::new(node));
+ Fragment::from_opaque_node_and_style(
+ OpaqueNodeMethods::from_thread_safe_layout_node(node),
+ style,
+ node.restyle_damage(),
+ fragment_info)
+ } else {
+ Fragment::from_opaque_node_and_style(
+ OpaqueNodeMethods::from_thread_safe_layout_node(node),
+ style,
+ node.restyle_damage(),
+ self.build_specific_fragment_info_for_node(node))
+ };
+
let mut fragments = DList::new();
- match (node.get_pseudo_element_type(), node.type_id()) {
- (_, Some(NodeTypeId::Text)) => {
- self.create_fragments_for_node_text_content(&mut fragments, node, &style)
- }
- (PseudoElementType::Normal, _) => {
- fragments.push_back(self.build_fragment_for_block(node));
- }
- (_, _) => self.create_fragments_for_node_text_content(&mut fragments, node, &style),
- }
+ fragments.push_back(fragment);
let construction_item =
ConstructionItem::InlineFragments(InlineFragmentsConstructionResult {
@@ -786,7 +754,7 @@ impl<'a> FlowConstructor<'a> {
let fragment_info = SpecificFragmentInfo::InlineBlock(InlineBlockFragmentInfo::new(
block_flow));
- let fragment = Fragment::new(node, fragment_info);
+ let fragment = Fragment::new_from_specific_info(node, fragment_info);
let mut fragment_accumulator = InlineFragmentsAccumulator::from_inline_node(node);
fragment_accumulator.fragments.push_back(fragment);
@@ -812,7 +780,7 @@ impl<'a> FlowConstructor<'a> {
let fragment_info = SpecificFragmentInfo::InlineAbsoluteHypothetical(
InlineAbsoluteHypotheticalFragmentInfo::new(block_flow));
- let fragment = Fragment::new(node, fragment_info);
+ let fragment = Fragment::new_from_specific_info(node, fragment_info);
let mut fragment_accumulator = InlineFragmentsAccumulator::from_inline_node(node);
fragment_accumulator.fragments.push_back(fragment);
@@ -897,7 +865,7 @@ impl<'a> FlowConstructor<'a> {
/// possibly other `TableCaptionFlow`s or `TableFlow`s underneath it.
fn build_flow_for_table_wrapper(&mut self, node: &ThreadSafeLayoutNode, float_value: float::T)
-> ConstructionResult {
- let fragment = Fragment::new(node, SpecificFragmentInfo::TableWrapper);
+ let fragment = Fragment::new_from_specific_info(node, SpecificFragmentInfo::TableWrapper);
let wrapper_flow = match float_value {
float::T::none => box TableWrapperFlow::from_node_and_fragment(node, fragment),
_ => {
@@ -907,7 +875,7 @@ impl<'a> FlowConstructor<'a> {
};
let mut wrapper_flow = FlowRef::new(wrapper_flow as Box<Flow>);
- let table_fragment = Fragment::new(node, SpecificFragmentInfo::Table);
+ let table_fragment = Fragment::new_from_specific_info(node, SpecificFragmentInfo::Table);
let table_flow = box TableFlow::from_node_and_fragment(node, table_fragment);
let table_flow = FlowRef::new(table_flow as Box<Flow>);
@@ -941,8 +909,7 @@ impl<'a> FlowConstructor<'a> {
wrapper_flow.finish();
let is_positioned = wrapper_flow.as_block().is_positioned();
let is_fixed_positioned = wrapper_flow.as_block().is_fixed();
- let is_absolutely_positioned =
- flow::base(&*wrapper_flow).flags.contains(IS_ABSOLUTELY_POSITIONED);
+ let is_absolutely_positioned = flow::base(&*wrapper_flow).flags.contains(IS_ABSOLUTELY_POSITIONED);
if is_positioned {
// This is the containing block for all the absolute descendants.
wrapper_flow.set_absolute_descendants(abs_descendants);
@@ -965,8 +932,7 @@ impl<'a> FlowConstructor<'a> {
/// Builds a flow for a node with `display: table-caption`. This yields a `TableCaptionFlow`
/// with possibly other `BlockFlow`s or `InlineFlow`s underneath it.
fn build_flow_for_table_caption(&mut self, node: &ThreadSafeLayoutNode) -> ConstructionResult {
- let fragment = self.build_fragment_for_block(node);
- let flow = box TableCaptionFlow::from_node_and_fragment(node, fragment) as Box<Flow>;
+ let flow = box TableCaptionFlow::from_node(self, node) as Box<Flow>;
self.build_flow_for_block(FlowRef::new(flow), node)
}
@@ -974,7 +940,7 @@ impl<'a> FlowConstructor<'a> {
/// with possibly other `TableRowFlow`s underneath it.
fn build_flow_for_table_rowgroup(&mut self, node: &ThreadSafeLayoutNode)
-> ConstructionResult {
- let fragment = Fragment::new(node, SpecificFragmentInfo::TableRow);
+ let fragment = Fragment::new_from_specific_info(node, SpecificFragmentInfo::TableRow);
let flow = box TableRowGroupFlow::from_node_and_fragment(node, fragment);
let flow = flow as Box<Flow>;
self.build_flow_for_block(FlowRef::new(flow), node)
@@ -983,7 +949,7 @@ impl<'a> FlowConstructor<'a> {
/// Builds a flow for a node with `display: table-row`. This yields a `TableRowFlow` with
/// possibly other `TableCellFlow`s underneath it.
fn build_flow_for_table_row(&mut self, node: &ThreadSafeLayoutNode) -> ConstructionResult {
- let fragment = Fragment::new(node, SpecificFragmentInfo::TableRow);
+ let fragment = Fragment::new_from_specific_info(node, SpecificFragmentInfo::TableRow);
let flow = box TableRowFlow::from_node_and_fragment(node, fragment) as Box<Flow>;
self.build_flow_for_block(FlowRef::new(flow), node)
}
@@ -991,7 +957,7 @@ impl<'a> FlowConstructor<'a> {
/// Builds a flow for a node with `display: table-cell`. This yields a `TableCellFlow` with
/// possibly other `BlockFlow`s or `InlineFlow`s underneath it.
fn build_flow_for_table_cell(&mut self, node: &ThreadSafeLayoutNode) -> ConstructionResult {
- let fragment = Fragment::new(node, SpecificFragmentInfo::TableCell);
+ let fragment = Fragment::new_from_specific_info(node, SpecificFragmentInfo::TableCell);
// Determine if the table cell should be hidden. Per CSS 2.1 § 17.6.1.1, this will be true
// if the cell has any in-flow elements (even empty ones!) and has `empty-cells` set to
@@ -1019,18 +985,19 @@ impl<'a> FlowConstructor<'a> {
};
let marker_fragment = match node.style().get_list().list_style_image {
Some(ref url) => {
- Some(Fragment::new(node,
- self.build_fragment_info_for_image(node, Some((*url).clone()))))
+ Some(Fragment::new_from_specific_info(
+ node,
+ self.build_fragment_info_for_image(node, Some((*url).clone()))))
}
None => {
- match ListStyleTypeContent::from_list_style_type(node.style()
+ match list_item::static_text_for_list_style_type(node.style()
.get_list()
.list_style_type) {
- ListStyleTypeContent::None => None,
- ListStyleTypeContent::StaticText(text) => {
+ None => None,
+ Some(text) => {
let text = text.to_owned();
let mut unscanned_marker_fragments = DList::new();
- unscanned_marker_fragments.push_back(Fragment::new(
+ unscanned_marker_fragments.push_back(Fragment::new_from_specific_info(
node,
SpecificFragmentInfo::UnscannedText(
UnscannedTextFragmentInfo::from_text(text))));
@@ -1040,9 +1007,6 @@ impl<'a> FlowConstructor<'a> {
debug_assert!(marker_fragments.len() == 1);
marker_fragments.fragments.into_iter().next()
}
- ListStyleTypeContent::GeneratedContent(info) => {
- Some(Fragment::new(node, SpecificFragmentInfo::GeneratedContent(info)))
- }
}
}
};
@@ -1054,20 +1018,19 @@ impl<'a> FlowConstructor<'a> {
// there.
let flow;
let initial_fragment;
- let main_fragment = self.build_fragment_for_block(node);
match node.style().get_list().list_style_position {
list_style_position::T::outside => {
- flow = box ListItemFlow::from_node_fragments_and_flotation(node,
- main_fragment,
- marker_fragment,
- flotation);
+ flow = box ListItemFlow::from_node_marker_and_flotation(self,
+ node,
+ marker_fragment,
+ flotation);
initial_fragment = None;
}
list_style_position::T::inside => {
- flow = box ListItemFlow::from_node_fragments_and_flotation(node,
- main_fragment,
- None,
- flotation);
+ flow = box ListItemFlow::from_node_marker_and_flotation(self,
+ node,
+ None,
+ flotation);
initial_fragment = marker_fragment;
}
}
@@ -1086,8 +1049,9 @@ impl<'a> FlowConstructor<'a> {
}
let specific = SpecificFragmentInfo::TableColumn(TableColumnFragmentInfo::new(node));
- let construction_item = ConstructionItem::TableColumnFragment(Fragment::new(node,
- specific));
+ let construction_item = ConstructionItem::TableColumnFragment(
+ Fragment::new_from_specific_info(node, specific)
+ );
ConstructionResult::ConstructionItem(construction_item)
}
@@ -1095,9 +1059,9 @@ impl<'a> FlowConstructor<'a> {
/// This yields a `TableColGroupFlow`.
fn build_flow_for_table_colgroup(&mut self, node: &ThreadSafeLayoutNode)
-> ConstructionResult {
- let fragment =
- Fragment::new(node,
- SpecificFragmentInfo::TableColumn(TableColumnFragmentInfo::new(node)));
+ let fragment = Fragment::new_from_specific_info(
+ node,
+ SpecificFragmentInfo::TableColumn(TableColumnFragmentInfo::new(node)));
let mut col_fragments = vec!();
for kid in node.children() {
// CSS 2.1 § 17.2.1. Treat all non-column child fragments of `table-column-group`
@@ -1113,7 +1077,7 @@ impl<'a> FlowConstructor<'a> {
if col_fragments.is_empty() {
debug!("add SpecificFragmentInfo::TableColumn for empty colgroup");
let specific = SpecificFragmentInfo::TableColumn(TableColumnFragmentInfo::new(node));
- col_fragments.push(Fragment::new(node, specific));
+ col_fragments.push(Fragment::new_from_specific_info(node, specific));
}
let flow = box TableColGroupFlow::from_node_and_fragments(node, fragment, col_fragments);
let mut flow = FlowRef::new(flow as Box<Flow>);
@@ -1329,29 +1293,25 @@ trait NodeUtils {
/// Sets the construction result of a flow.
fn set_flow_construction_result(self, result: ConstructionResult);
- /// Replaces the flow construction result in a node with `ConstructionResult::None` and returns
- /// the old value.
+ /// Replaces the flow construction result in a node with `ConstructionResult::None` and returns the
+ /// old value.
fn swap_out_construction_result(self) -> ConstructionResult;
}
impl<'ln> NodeUtils for ThreadSafeLayoutNode<'ln> {
fn is_replaced_content(&self) -> bool {
match self.type_id() {
- None |
Some(NodeTypeId::Text) |
Some(NodeTypeId::ProcessingInstruction) |
Some(NodeTypeId::Comment) |
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(),
+ None |
+ Some(NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLImageElement))) => true,
+ Some(NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLObjectElement))) => self.has_object_data(),
+ Some(NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLIFrameElement))) => true,
+ Some(NodeTypeId::Element(ElementTypeId::HTMLElement(HTMLElementTypeId::HTMLCanvasElement))) => true,
Some(NodeTypeId::Element(_)) => false,
}
}
diff --git a/components/layout/display_list_builder.rs b/components/layout/display_list_builder.rs
index 58eabd2580b..e61e8728eb6 100644
--- a/components/layout/display_list_builder.rs
+++ b/components/layout/display_list_builder.rs
@@ -953,7 +953,6 @@ impl FragmentDisplayListBuilding for Fragment {
}
}
SpecificFragmentInfo::Generic |
- SpecificFragmentInfo::GeneratedContent(..) |
SpecificFragmentInfo::Iframe(..) |
SpecificFragmentInfo::Table |
SpecificFragmentInfo::TableCell |
diff --git a/components/layout/flow.rs b/components/layout/flow.rs
index b9dacc872d1..19f1df86c3a 100644
--- a/components/layout/flow.rs
+++ b/components/layout/flow.rs
@@ -32,10 +32,10 @@ use display_list_builder::DisplayListBuildingResult;
use floats::Floats;
use flow_list::{FlowList, FlowListIterator, MutFlowListIterator};
use flow_ref::FlowRef;
-use fragment::{Fragment, FragmentBorderBoxIterator, FragmentMutator, SpecificFragmentInfo};
-use incremental::{self, RECONSTRUCT_FLOW, REFLOW, REFLOW_OUT_OF_FLOW, RestyleDamage};
+use fragment::{Fragment, FragmentBorderBoxIterator, SpecificFragmentInfo};
+use incremental::{RECONSTRUCT_FLOW, REFLOW, REFLOW_OUT_OF_FLOW, RestyleDamage};
use inline::InlineFlow;
-use model::{CollapsibleMargins, IntrinsicISizes, MarginCollapseInfo};
+use model::{CollapsibleMargins, IntrinsicISizes};
use parallel::FlowParallelInfo;
use table::{ColumnComputedInlineSize, ColumnIntrinsicInlineSize, TableFlow};
use table_caption::TableCaptionFlow;
@@ -235,15 +235,6 @@ pub trait Flow: fmt::Debug + Sync {
iterator: &mut FragmentBorderBoxIterator,
stacking_context_position: &Point2D<Au>);
- /// Mutably iterates through fragments in this flow.
- fn mutate_fragments(&mut self, mutator: &mut FragmentMutator);
-
- fn compute_collapsible_block_start_margin(&mut self,
- _layout_context: &mut LayoutContext,
- _margin_collapse_info: &mut MarginCollapseInfo) {
- // The default implementation is a no-op.
- }
-
/// Marks this flow as the root flow. The default implementation is a no-op.
fn mark_as_root(&mut self) {}
@@ -483,67 +474,51 @@ pub trait PostorderFlowTraversal {
}
}
-/// An in-order (sequential only) traversal.
-pub trait InorderFlowTraversal {
- /// The operation to perform. Returns the level of the tree we're at.
- fn process(&mut self, flow: &mut Flow, level: u32);
-
- /// Returns true if this node should be processed and false if neither this node nor its
- /// descendants should be processed.
- fn should_process(&mut self, flow: &mut Flow) -> bool;
-}
-
bitflags! {
#[doc = "Flags used in flows."]
- flags FlowFlags: u32 {
+ flags FlowFlags: u16 {
// floated descendants flags
#[doc = "Whether this flow has descendants that float left in the same block formatting"]
#[doc = "context."]
- const HAS_LEFT_FLOATED_DESCENDANTS = 0b0000_0000_0000_0000_0001,
+ const HAS_LEFT_FLOATED_DESCENDANTS = 0b0000_0000_0000_0001,
#[doc = "Whether this flow has descendants that float right in the same block formatting"]
#[doc = "context."]
- const HAS_RIGHT_FLOATED_DESCENDANTS = 0b0000_0000_0000_0000_0010,
+ const HAS_RIGHT_FLOATED_DESCENDANTS = 0b0000_0000_0000_0010,
#[doc = "Whether this flow is impacted by floats to the left in the same block formatting"]
#[doc = "context (i.e. its height depends on some prior flows with `float: left`)."]
- const IMPACTED_BY_LEFT_FLOATS = 0b0000_0000_0000_0000_0100,
+ const IMPACTED_BY_LEFT_FLOATS = 0b0000_0000_0000_0100,
#[doc = "Whether this flow is impacted by floats to the right in the same block"]
#[doc = "formatting context (i.e. its height depends on some prior flows with `float:"]
#[doc = "right`)."]
- const IMPACTED_BY_RIGHT_FLOATS = 0b0000_0000_0000_0000_1000,
+ const IMPACTED_BY_RIGHT_FLOATS = 0b0000_0000_0000_1000,
// text align flags
#[doc = "Whether this flow contains a flow that has its own layer within the same absolute"]
#[doc = "containing block."]
- const LAYERS_NEEDED_FOR_DESCENDANTS = 0b0000_0000_0000_0001_0000,
+ const LAYERS_NEEDED_FOR_DESCENDANTS = 0b0000_0000_0001_0000,
#[doc = "Whether this flow must have its own layer. Even if this flag is not set, it might"]
#[doc = "get its own layer if it's deemed to be likely to overlap flows with their own"]
#[doc = "layer."]
- const NEEDS_LAYER = 0b0000_0000_0000_0010_0000,
+ const NEEDS_LAYER = 0b0000_0000_0010_0000,
#[doc = "Whether this flow is absolutely positioned. This is checked all over layout, so a"]
#[doc = "virtual call is too expensive."]
- const IS_ABSOLUTELY_POSITIONED = 0b0000_0000_0000_0100_0000,
+ const IS_ABSOLUTELY_POSITIONED = 0b0000_0000_0100_0000,
#[doc = "Whether this flow clears to the left. This is checked all over layout, so a"]
#[doc = "virtual call is too expensive."]
- const CLEARS_LEFT = 0b0000_0000_0000_1000_0000,
+ const CLEARS_LEFT = 0b0000_0000_1000_0000,
#[doc = "Whether this flow clears to the right. This is checked all over layout, so a"]
#[doc = "virtual call is too expensive."]
- const CLEARS_RIGHT = 0b0000_0000_0001_0000_0000,
+ const CLEARS_RIGHT = 0b0000_0001_0000_0000,
#[doc = "Whether this flow is left-floated. This is checked all over layout, so a"]
#[doc = "virtual call is too expensive."]
- const FLOATS_LEFT = 0b0000_0000_0010_0000_0000,
+ const FLOATS_LEFT = 0b0000_0010_0000_0000,
#[doc = "Whether this flow is right-floated. This is checked all over layout, so a"]
#[doc = "virtual call is too expensive."]
- const FLOATS_RIGHT = 0b0000_0000_0100_0000_0000,
+ const FLOATS_RIGHT = 0b0000_0100_0000_0000,
#[doc = "Text alignment. \
NB: If you update this, update `TEXT_ALIGN_SHIFT` below."]
- const TEXT_ALIGN = 0b0000_0111_1000_0000_0000,
- #[doc = "Whether this flow has a fragment with `counter-reset` or `counter-increment` \
- styles."]
- const AFFECTS_COUNTERS = 0b0000_1000_0000_0000_0000,
- #[doc = "Whether this flow's descendants have fragments that affect `counter-reset` or \
- `counter-increment` styles."]
- const HAS_COUNTER_AFFECTING_CHILDREN = 0b0001_0000_0000_0000_0000
+ const TEXT_ALIGN = 0b0111_1000_0000_0000,
}
}
@@ -569,13 +544,13 @@ impl FlowFlags {
#[inline]
pub fn text_align(self) -> text_align::T {
- FromPrimitive::from_u32((self & TEXT_ALIGN).bits() >> TEXT_ALIGN_SHIFT).unwrap()
+ FromPrimitive::from_u16((self & TEXT_ALIGN).bits() >> TEXT_ALIGN_SHIFT).unwrap()
}
#[inline]
pub fn set_text_align(&mut self, value: text_align::T) {
*self = (*self & !TEXT_ALIGN) |
- FlowFlags::from_bits((value as u32) << TEXT_ALIGN_SHIFT).unwrap();
+ FlowFlags::from_bits((value as u16) << TEXT_ALIGN_SHIFT).unwrap();
}
#[inline]
@@ -895,41 +870,39 @@ impl BaseFlow {
force_nonfloated: ForceNonfloatedFlag)
-> BaseFlow {
let mut flags = FlowFlags::empty();
- if let Some(node) = node {
- let node_style = node.style();
- match node_style.get_box().position {
- position::T::absolute | position::T::fixed => {
- flags.insert(IS_ABSOLUTELY_POSITIONED)
+ match node {
+ None => {}
+ Some(node) => {
+ let node_style = node.style();
+ match node_style.get_box().position {
+ position::T::absolute | position::T::fixed => {
+ flags.insert(IS_ABSOLUTELY_POSITIONED)
+ }
+ _ => {}
}
- _ => {}
- }
- if force_nonfloated == ForceNonfloatedFlag::FloatIfNecessary {
- match node_style.get_box().float {
- float::T::none => {}
- float::T::left => flags.insert(FLOATS_LEFT),
- float::T::right => flags.insert(FLOATS_RIGHT),
+ if force_nonfloated == ForceNonfloatedFlag::FloatIfNecessary {
+ match node_style.get_box().float {
+ float::T::none => {}
+ float::T::left => flags.insert(FLOATS_LEFT),
+ float::T::right => flags.insert(FLOATS_RIGHT),
+ }
}
- }
- match node_style.get_box().clear {
- clear::T::none => {}
- clear::T::left => flags.insert(CLEARS_LEFT),
- clear::T::right => flags.insert(CLEARS_RIGHT),
- clear::T::both => {
- flags.insert(CLEARS_LEFT);
- flags.insert(CLEARS_RIGHT);
+ match node_style.get_box().clear {
+ clear::T::none => {}
+ clear::T::left => flags.insert(CLEARS_LEFT),
+ clear::T::right => flags.insert(CLEARS_RIGHT),
+ clear::T::both => {
+ flags.insert(CLEARS_LEFT);
+ flags.insert(CLEARS_RIGHT);
+ }
}
}
-
- if !node_style.get_counters().counter_reset.0.is_empty() ||
- !node_style.get_counters().counter_increment.0.is_empty() {
- flags.insert(AFFECTS_COUNTERS)
- }
}
// New flows start out as fully damaged.
- let mut damage = incremental::all();
+ let mut damage = RestyleDamage::all();
damage.remove(RECONSTRUCT_FLOW);
BaseFlow {
@@ -1003,12 +976,10 @@ impl BaseFlow {
}
impl<'a> ImmutableFlowUtils for &'a (Flow + 'a) {
- /// Returns true if this flow is a block flow or subclass thereof.
+ /// Returns true if this flow is a block flow.
fn is_block_like(self) -> bool {
match self.class() {
- FlowClass::Block | FlowClass::ListItem | FlowClass::Table | FlowClass::TableRowGroup |
- FlowClass::TableRow | FlowClass::TableCaption | FlowClass::TableCell |
- FlowClass::TableWrapper => true,
+ FlowClass::Block => true,
_ => false,
}
}
@@ -1343,4 +1314,3 @@ impl ContainingBlockLink {
}
}
}
-
diff --git a/components/layout/fragment.rs b/components/layout/fragment.rs
index 88204e5042c..26a91139b31 100644
--- a/components/layout/fragment.rs
+++ b/components/layout/fragment.rs
@@ -8,12 +8,13 @@
use canvas::canvas_paint_task::CanvasMsg;
use css::node_style::StyledNode;
+use construct::FlowConstructor;
use context::LayoutContext;
use floats::ClearType;
use flow;
use flow::Flow;
use flow_ref::FlowRef;
-use incremental::{self, RestyleDamage};
+use incremental::RestyleDamage;
use inline::{InlineFragmentContext, InlineMetrics};
use layout_debug;
use model::{IntrinsicISizes, IntrinsicISizesContribution, MaybeAuto, specified};
@@ -27,11 +28,11 @@ use geom::{Point2D, Rect, Size2D};
use gfx::display_list::{BLUR_INFLATION_FACTOR, OpaqueNode};
use gfx::text::glyph::CharIndex;
use gfx::text::text_run::{TextRun, TextRunSlice};
+use script_traits::UntrustedNodeAddress;
+use rustc_serialize::{Encodable, Encoder};
use msg::constellation_msg::{PipelineId, SubpageId};
use net::image::holder::ImageHolder;
use net::local_image_cache::LocalImageCache;
-use rustc_serialize::{Encodable, Encoder};
-use script_traits::UntrustedNodeAddress;
use servo_util::geometry::{self, Au, ZERO_POINT};
use servo_util::logical_geometry::{LogicalRect, LogicalSize, LogicalMargin};
use servo_util::range::*;
@@ -43,17 +44,15 @@ use std::collections::DList;
use std::fmt;
use std::num::ToPrimitive;
use std::str::FromStr;
-use std::sync::mpsc::Sender;
use std::sync::{Arc, Mutex};
+use std::sync::mpsc::Sender;
use string_cache::Atom;
-use style::computed_values::content::ContentItem;
+use style::properties::{ComputedValues, cascade_anonymous, make_border};
+use style::node::{TElement, TNode};
+use style::values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto, LengthOrPercentageOrNone};
use style::computed_values::{clear, mix_blend_mode, overflow_wrap};
use style::computed_values::{position, text_align, text_decoration, vertical_align, white_space};
use style::computed_values::{word_break};
-use style::node::{TElement, TNode};
-use style::properties::{ComputedValues, cascade_anonymous, make_border};
-use style::values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto};
-use style::values::computed::{LengthOrPercentageOrNone};
use text::TextRunScanner;
use url::Url;
@@ -137,11 +136,6 @@ impl Encodable for Fragment {
#[derive(Clone)]
pub enum SpecificFragmentInfo {
Generic,
-
- /// A piece of generated content that cannot be resolved into `ScannedText` until the generated
- /// content resolution phase (e.g. an ordered list item marker).
- GeneratedContent(Box<GeneratedContentInfo>),
-
Iframe(Box<IframeFragmentInfo>),
Image(Box<ImageFragmentInfo>),
Canvas(Box<CanvasFragmentInfo>),
@@ -164,18 +158,17 @@ impl SpecificFragmentInfo {
fn restyle_damage(&self) -> RestyleDamage {
let flow =
match *self {
- SpecificFragmentInfo::Canvas(_) |
- SpecificFragmentInfo::GeneratedContent(_) |
- SpecificFragmentInfo::Iframe(_) |
- SpecificFragmentInfo::Image(_) |
- SpecificFragmentInfo::ScannedText(_) |
- SpecificFragmentInfo::Table |
- SpecificFragmentInfo::TableCell |
- SpecificFragmentInfo::TableColumn(_) |
- SpecificFragmentInfo::TableRow |
- SpecificFragmentInfo::TableWrapper |
- SpecificFragmentInfo::UnscannedText(_) |
- SpecificFragmentInfo::Generic => return RestyleDamage::empty(),
+ SpecificFragmentInfo::Iframe(_)
+ | SpecificFragmentInfo::Image(_)
+ | SpecificFragmentInfo::ScannedText(_)
+ | SpecificFragmentInfo::Table
+ | SpecificFragmentInfo::TableCell
+ | SpecificFragmentInfo::TableColumn(_)
+ | SpecificFragmentInfo::TableRow
+ | SpecificFragmentInfo::TableWrapper
+ | SpecificFragmentInfo::UnscannedText(_)
+ | SpecificFragmentInfo::Canvas(_)
+ | SpecificFragmentInfo::Generic => return RestyleDamage::empty(),
SpecificFragmentInfo::InlineAbsoluteHypothetical(ref info) => &info.flow_ref,
SpecificFragmentInfo::InlineBlock(ref info) => &info.flow_ref,
};
@@ -187,12 +180,9 @@ impl SpecificFragmentInfo {
match *self {
SpecificFragmentInfo::Canvas(_) => "SpecificFragmentInfo::Canvas",
SpecificFragmentInfo::Generic => "SpecificFragmentInfo::Generic",
- SpecificFragmentInfo::GeneratedContent(_) => "SpecificFragmentInfo::GeneratedContent",
SpecificFragmentInfo::Iframe(_) => "SpecificFragmentInfo::Iframe",
SpecificFragmentInfo::Image(_) => "SpecificFragmentInfo::Image",
- SpecificFragmentInfo::InlineAbsoluteHypothetical(_) => {
- "SpecificFragmentInfo::InlineAbsoluteHypothetical"
- }
+ SpecificFragmentInfo::InlineAbsoluteHypothetical(_) => "SpecificFragmentInfo::InlineAbsoluteHypothetical",
SpecificFragmentInfo::InlineBlock(_) => "SpecificFragmentInfo::InlineBlock",
SpecificFragmentInfo::ScannedText(_) => "SpecificFragmentInfo::ScannedText",
SpecificFragmentInfo::Table => "SpecificFragmentInfo::Table",
@@ -206,11 +196,8 @@ impl SpecificFragmentInfo {
}
/// Clamp a value obtained from style_length, based on min / max lengths.
-fn clamp_size(size: Au,
- min_size: LengthOrPercentage,
- max_size: LengthOrPercentageOrNone,
- container_inline_size: Au)
- -> Au {
+fn clamp_size(size: Au, min_size: LengthOrPercentage, max_size: LengthOrPercentageOrNone,
+ container_inline_size: Au) -> Au {
let min_size = model::specified(min_size, container_inline_size);
let max_size = model::specified_or_none(max_size, container_inline_size);
@@ -220,13 +207,6 @@ fn clamp_size(size: Au,
})
}
-/// Information for generated content.
-#[derive(Clone)]
-pub enum GeneratedContentInfo {
- ListItem,
- ContentItem(ContentItem),
-}
-
/// A hypothetical box (see CSS 2.1 § 10.3.7) for an absolutely-positioned block that was declared
/// with `display: inline;`.
///
@@ -657,6 +637,14 @@ pub struct UnscannedTextFragmentInfo {
}
impl UnscannedTextFragmentInfo {
+ /// Creates a new instance of `UnscannedTextFragmentInfo` from the given DOM node.
+ pub fn new(node: &ThreadSafeLayoutNode) -> UnscannedTextFragmentInfo {
+ // FIXME(pcwalton): Don't copy text; atomically reference count it instead.
+ UnscannedTextFragmentInfo {
+ text: box node.text(),
+ }
+ }
+
/// Creates a new instance of `UnscannedTextFragmentInfo` from the given text.
#[inline]
pub fn from_text(text: String) -> UnscannedTextFragmentInfo {
@@ -690,8 +678,34 @@ impl TableColumnFragmentInfo {
}
impl Fragment {
- /// Constructs a new `Fragment` instance.
- pub fn new(node: &ThreadSafeLayoutNode, specific: SpecificFragmentInfo) -> Fragment {
+ /// Constructs a new `Fragment` instance for the given node.
+ ///
+ /// This does *not* construct the text for generated content. See comments in
+ /// `FlowConstructor::build_specific_fragment_info_for_node()` for more details.
+ ///
+ /// Arguments:
+ ///
+ /// * `constructor`: The flow constructor.
+ /// * `node`: The node to create a fragment for.
+ pub fn new(constructor: &mut FlowConstructor, node: &ThreadSafeLayoutNode) -> Fragment {
+ let style = node.style().clone();
+ let writing_mode = style.writing_mode;
+ Fragment {
+ node: OpaqueNodeMethods::from_thread_safe_layout_node(node),
+ style: style,
+ restyle_damage: node.restyle_damage(),
+ border_box: LogicalRect::zero(writing_mode),
+ border_padding: LogicalMargin::zero(writing_mode),
+ margin: LogicalMargin::zero(writing_mode),
+ specific: constructor.build_specific_fragment_info_for_node(node),
+ inline_context: None,
+ debug_id: layout_debug::generate_unique_debug_id(),
+ }
+ }
+
+ /// Constructs a new `Fragment` instance from a specific info.
+ pub fn new_from_specific_info(node: &ThreadSafeLayoutNode, specific: SpecificFragmentInfo)
+ -> Fragment {
let style = node.style().clone();
let writing_mode = style.writing_mode;
Fragment {
@@ -707,6 +721,24 @@ impl Fragment {
}
}
+ /// Constructs a new `Fragment` instance for an anonymous object.
+ pub fn new_anonymous(constructor: &mut FlowConstructor, node: &ThreadSafeLayoutNode)
+ -> Fragment {
+ let node_style = cascade_anonymous(&**node.style());
+ let writing_mode = node_style.writing_mode;
+ Fragment {
+ node: OpaqueNodeMethods::from_thread_safe_layout_node(node),
+ style: Arc::new(node_style),
+ restyle_damage: node.restyle_damage(),
+ border_box: LogicalRect::zero(writing_mode),
+ border_padding: LogicalMargin::zero(writing_mode),
+ margin: LogicalMargin::zero(writing_mode),
+ specific: constructor.build_specific_fragment_info_for_node(node),
+ inline_context: None,
+ debug_id: layout_debug::generate_unique_debug_id(),
+ }
+ }
+
/// Constructs a new `Fragment` instance for an anonymous table object.
pub fn new_anonymous_from_specific_info(node: &ThreadSafeLayoutNode,
specific: SpecificFragmentInfo)
@@ -805,7 +837,7 @@ impl Fragment {
Fragment {
node: self.node,
style: self.style.clone(),
- restyle_damage: incremental::all(),
+ restyle_damage: RestyleDamage::all(),
border_box: new_border_box,
border_padding: self.border_padding,
margin: self.margin,
@@ -880,7 +912,6 @@ impl Fragment {
match self.specific {
SpecificFragmentInfo::Canvas(_) |
SpecificFragmentInfo::Generic |
- SpecificFragmentInfo::GeneratedContent(_) |
SpecificFragmentInfo::Iframe(_) |
SpecificFragmentInfo::Image(_) |
SpecificFragmentInfo::InlineBlock(_) => {
@@ -900,9 +931,7 @@ impl Fragment {
INTRINSIC_INLINE_SIZE_INCLUDES_BORDER |
INTRINSIC_INLINE_SIZE_INCLUDES_SPECIFIED
}
- SpecificFragmentInfo::ScannedText(_) |
- SpecificFragmentInfo::TableColumn(_) |
- SpecificFragmentInfo::UnscannedText(_) |
+ SpecificFragmentInfo::ScannedText(_) | SpecificFragmentInfo::TableColumn(_) | SpecificFragmentInfo::UnscannedText(_) |
SpecificFragmentInfo::InlineAbsoluteHypothetical(_) => {
QuantitiesIncludedInIntrinsicInlineSizes::empty()
}
@@ -1191,14 +1220,6 @@ impl Fragment {
}
}
- /// Returns true if and only if this fragment is a generated content fragment.
- pub fn is_generated_content(&self) -> bool {
- match self.specific {
- SpecificFragmentInfo::GeneratedContent(..) => true,
- _ => false,
- }
- }
-
/// Returns true if and only if this is a scanned text fragment.
pub fn is_scanned_text_fragment(&self) -> bool {
match self.specific {
@@ -1212,7 +1233,6 @@ impl Fragment {
let mut result = self.style_specified_intrinsic_inline_size();
match self.specific {
SpecificFragmentInfo::Generic |
- SpecificFragmentInfo::GeneratedContent(_) |
SpecificFragmentInfo::Iframe(_) |
SpecificFragmentInfo::Table |
SpecificFragmentInfo::TableCell |
@@ -1282,7 +1302,6 @@ impl Fragment {
pub fn content_inline_size(&self) -> Au {
match self.specific {
SpecificFragmentInfo::Generic |
- SpecificFragmentInfo::GeneratedContent(_) |
SpecificFragmentInfo::Iframe(_) |
SpecificFragmentInfo::Table |
SpecificFragmentInfo::TableCell |
@@ -1314,7 +1333,6 @@ impl Fragment {
pub fn content_block_size(&self, layout_context: &LayoutContext) -> Au {
match self.specific {
SpecificFragmentInfo::Generic |
- SpecificFragmentInfo::GeneratedContent(_) |
SpecificFragmentInfo::Iframe(_) |
SpecificFragmentInfo::Table |
SpecificFragmentInfo::TableCell |
@@ -1333,7 +1351,7 @@ impl Fragment {
self.calculate_line_height(layout_context)
}
SpecificFragmentInfo::TableColumn(_) => {
- panic!("Table column fragments do not have block size")
+ panic!("Table column fragments do not have block_size")
}
SpecificFragmentInfo::UnscannedText(_) => {
panic!("Unscanned text fragments should have been scanned by now!")
@@ -1363,7 +1381,6 @@ impl Fragment {
match self.specific {
SpecificFragmentInfo::Canvas(_) |
SpecificFragmentInfo::Generic |
- SpecificFragmentInfo::GeneratedContent(_) |
SpecificFragmentInfo::Iframe(_) |
SpecificFragmentInfo::Image(_) |
SpecificFragmentInfo::Table |
@@ -1671,23 +1688,22 @@ impl Fragment {
pub fn assign_replaced_inline_size_if_necessary<'a>(&'a mut self, container_inline_size: Au) {
match self.specific {
SpecificFragmentInfo::Generic |
- SpecificFragmentInfo::GeneratedContent(_) |
SpecificFragmentInfo::Table |
SpecificFragmentInfo::TableCell |
SpecificFragmentInfo::TableRow |
SpecificFragmentInfo::TableWrapper => return,
SpecificFragmentInfo::TableColumn(_) => {
- panic!("Table column fragments do not have inline size")
+ panic!("Table column fragments do not have inline_size")
}
SpecificFragmentInfo::UnscannedText(_) => {
panic!("Unscanned text fragments should have been scanned by now!")
}
SpecificFragmentInfo::Canvas(_) |
SpecificFragmentInfo::Image(_) |
- SpecificFragmentInfo::Iframe(_) |
+ SpecificFragmentInfo::ScannedText(_) |
SpecificFragmentInfo::InlineBlock(_) |
SpecificFragmentInfo::InlineAbsoluteHypothetical(_) |
- SpecificFragmentInfo::ScannedText(_) => {}
+ SpecificFragmentInfo::Iframe(_) => {}
};
let style = self.style().clone();
@@ -1751,23 +1767,22 @@ impl Fragment {
pub fn assign_replaced_block_size_if_necessary(&mut self, containing_block_block_size: Au) {
match self.specific {
SpecificFragmentInfo::Generic |
- SpecificFragmentInfo::GeneratedContent(_) |
SpecificFragmentInfo::Table |
SpecificFragmentInfo::TableCell |
SpecificFragmentInfo::TableRow |
SpecificFragmentInfo::TableWrapper => return,
SpecificFragmentInfo::TableColumn(_) => {
- panic!("Table column fragments do not have block size")
+ panic!("Table column fragments do not have block_size")
}
SpecificFragmentInfo::UnscannedText(_) => {
panic!("Unscanned text fragments should have been scanned by now!")
}
SpecificFragmentInfo::Canvas(_) |
- SpecificFragmentInfo::Iframe(_) |
SpecificFragmentInfo::Image(_) |
+ SpecificFragmentInfo::ScannedText(_) |
SpecificFragmentInfo::InlineBlock(_) |
SpecificFragmentInfo::InlineAbsoluteHypothetical(_) |
- SpecificFragmentInfo::ScannedText(_) => {}
+ SpecificFragmentInfo::Iframe(_) => {}
}
let style = self.style().clone();
@@ -1905,7 +1920,6 @@ impl Fragment {
SpecificFragmentInfo::TableWrapper => false,
SpecificFragmentInfo::Canvas(_) |
SpecificFragmentInfo::Generic |
- SpecificFragmentInfo::GeneratedContent(_) |
SpecificFragmentInfo::Iframe(_) |
SpecificFragmentInfo::Image(_) |
SpecificFragmentInfo::ScannedText(_) |
@@ -2119,9 +2133,3 @@ fn strip_trailing_whitespace(text_run: &TextRun, range: &mut Range<CharIndex>) -
return true
}
-/// A mutable iterator over fragments.
-pub trait FragmentMutator {
- /// The operation to perform.
- fn process(&mut self, fragment: &mut Fragment);
-}
-
diff --git a/components/layout/generated_content.rs b/components/layout/generated_content.rs
deleted file mode 100644
index d4ec6e5a534..00000000000
--- a/components/layout/generated_content.rs
+++ /dev/null
@@ -1,573 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-//! The generated content assignment phase.
-//!
-//! This phase handles CSS counters, quotes, and ordered lists per CSS § 12.3-12.5. It cannot be
-//! done in parallel and is therefore a sequential pass that runs on as little of the flow tree
-//! as possible.
-
-use context::LayoutContext;
-use flow::{self, AFFECTS_COUNTERS, Flow, HAS_COUNTER_AFFECTING_CHILDREN, ImmutableFlowUtils};
-use flow::{InorderFlowTraversal};
-use fragment::{Fragment, FragmentMutator, GeneratedContentInfo, SpecificFragmentInfo};
-use fragment::{UnscannedTextFragmentInfo};
-use incremental::{self, RESOLVE_GENERATED_CONTENT};
-use text::TextRunScanner;
-
-use gfx::display_list::OpaqueNode;
-use servo_util::smallvec::{SmallVec, SmallVec8};
-use std::collections::{DList, HashMap};
-use std::sync::Arc;
-use style::computed_values::content::ContentItem;
-use style::computed_values::{display, list_style_type};
-use style::properties::ComputedValues;
-
-// Decimal styles per CSS-COUNTER-STYLES § 6.1:
-static DECIMAL: [char; 10] = [ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' ];
-// TODO(pcwalton): `decimal-leading-zero`
-static ARABIC_INDIC: [char; 10] = [ '٠', '١', '٢', '٣', '٤', '٥', '٦', '٧', '٨', '٩' ];
-// TODO(pcwalton): `armenian`, `upper-armenian`, `lower-armenian`
-static BENGALI: [char; 10] = [ '০', '১', '২', '৩', '৪', '৫', '৬', '৭', '৮', '৯' ];
-static CAMBODIAN: [char; 10] = [ '០', '១', '២', '៣', '៤', '៥', '៦', '៧', '៨', '៩' ];
-// TODO(pcwalton): Suffix for CJK decimal.
-static CJK_DECIMAL: [char; 10] = [ '〇', '一', '二', '三', '四', '五', '六', '七', '八', '九' ];
-static DEVANAGARI: [char; 10] = [ '०', '१', '२', '३', '४', '५', '६', '७', '८', '९' ];
-// TODO(pcwalton): `georgian`
-static GUJARATI: [char; 10] = ['૦', '૧', '૨', '૩', '૪', '૫', '૬', '૭', '૮', '૯'];
-static GURMUKHI: [char; 10] = ['੦', '੧', '੨', '੩', '੪', '੫', '੬', '੭', '੮', '੯'];
-// TODO(pcwalton): `hebrew`
-static KANNADA: [char; 10] = ['೦', '೧', '೨', '೩', '೪', '೫', '೬', '೭', '೮', '೯'];
-static LAO: [char; 10] = ['໐', '໑', '໒', '໓', '໔', '໕', '໖', '໗', '໘', '໙'];
-static MALAYALAM: [char; 10] = ['൦', '൧', '൨', '൩', '൪', '൫', '൬', '൭', '൮', '൯'];
-static MONGOLIAN: [char; 10] = ['᠐', '᠑', '᠒', '᠓', '᠔', '᠕', '᠖', '᠗', '᠘', '᠙'];
-static MYANMAR: [char; 10] = ['၀', '၁', '၂', '၃', '၄', '၅', '၆', '၇', '၈', '၉'];
-static ORIYA: [char; 10] = ['୦', '୧', '୨', '୩', '୪', '୫', '୬', '୭', '୮', '୯'];
-static PERSIAN: [char; 10] = ['۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹'];
-// TODO(pcwalton): `lower-roman`, `upper-roman`
-static TELUGU: [char; 10] = ['౦', '౧', '౨', '౩', '౪', '౫', '౬', '౭', '౮', '౯'];
-static THAI: [char; 10] = ['๐', '๑', '๒', '๓', '๔', '๕', '๖', '๗', '๘', '๙'];
-static TIBETAN: [char; 10] = ['༠', '༡', '༢', '༣', '༤', '༥', '༦', '༧', '༨', '༩'];
-
-// Alphabetic styles per CSS-COUNTER-STYLES § 6.2:
-static LOWER_ALPHA: [char; 26] = [
- 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
- 't', 'u', 'v', 'w', 'x', 'y', 'z'
-];
-static UPPER_ALPHA: [char; 26] = [
- 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
- 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
-];
-static CJK_EARTHLY_BRANCH: [char; 12] = [
- '子', '丑', '寅', '卯', '辰', '巳', '午', '未', '申', '酉', '戌', '亥'
-];
-static CJK_HEAVENLY_STEM: [char; 10] = [
- '甲', '乙', '丙', '丁', '戊', '己', '庚', '辛', '壬', '癸'
-];
-static LOWER_GREEK: [char; 24] = [
- 'α', 'β', 'γ', 'δ', 'ε', 'ζ', 'η', 'θ', 'ι', 'κ', 'λ', 'μ', 'ν', 'ξ', 'ο', 'π', 'ρ', 'σ', 'τ',
- 'υ', 'φ', 'χ', 'ψ', 'ω'
-];
-static HIRAGANA: [char; 48] = [
- 'あ', 'い', 'う', 'え', 'お', 'か', 'き', 'く', 'け', 'こ', 'さ', 'し', 'す', 'せ', 'そ',
- 'た', 'ち', 'つ', 'て', 'と', 'な', 'に', 'ぬ', 'ね', 'の', 'は', 'ひ', 'ふ', 'へ', 'ほ',
- 'ま', 'み', 'む', 'め', 'も', 'や', 'ゆ', 'よ', 'ら', 'り', 'る', 'れ', 'ろ',
- 'わ', 'ゐ', 'ゑ', 'を', 'ん'
-];
-static HIRAGANA_IROHA: [char; 47] = [
- 'い', 'ろ', 'は', 'に', 'ほ', 'へ', 'と', 'ち', 'り', 'ぬ', 'る', 'を', 'わ', 'か', 'よ',
- 'た', 'れ', 'そ', 'つ', 'ね', 'な', 'ら', 'む', 'う', 'ゐ', 'の', 'お', 'く', 'や', 'ま',
- 'け', 'ふ', 'こ', 'え', 'て', 'あ', 'さ', 'き', 'ゆ', 'め', 'み', 'し', 'ゑ',
- 'ひ', 'も', 'せ', 'す'
-];
-static KATAKANA: [char; 48] = [
- 'ア', 'イ', 'ウ', 'エ', 'オ', 'カ', 'キ', 'ク', 'ケ', 'コ', 'サ', 'シ', 'ス', 'セ', 'ソ',
- 'タ', 'チ', 'ツ', 'テ', 'ト', 'ナ', 'ニ', 'ヌ', 'ネ', 'ノ', 'ハ', 'ヒ', 'フ', 'ヘ', 'ホ',
- 'マ', 'ミ', 'ム', 'メ', 'モ', 'ヤ', 'ユ', 'ヨ', 'ラ', 'リ', 'ル', 'レ', 'ロ',
- 'ワ', 'ヰ', 'ヱ', 'ヲ', 'ン'
-];
-static KATAKANA_IROHA: [char; 47] = [
- 'イ', 'ロ', 'ハ', 'ニ', 'ホ', 'ヘ', 'ト', 'チ', 'リ', 'ヌ', 'ル', 'ヲ', 'ワ', 'カ', 'ヨ',
- 'タ', 'レ', 'ソ', 'ツ', 'ネ', 'ナ', 'ラ', 'ム', 'ウ', 'ヰ', 'ノ', 'オ', 'ク', 'ヤ', 'マ',
- 'ケ', 'フ', 'コ', 'エ', 'テ', 'ア', 'サ', 'キ', 'ユ', 'メ', 'ミ', 'シ', 'ヱ',
- 'ヒ', 'モ', 'セ', 'ス'
-];
-
-/// The generated content resolution traversal.
-pub struct ResolveGeneratedContent<'a> {
- /// The layout context.
- layout_context: &'a LayoutContext<'a>,
- /// The counter representing an ordered list item.
- list_item: Counter,
- /// Named CSS counters.
- counters: HashMap<String,Counter>,
- /// The level of quote nesting.
- quote: u32,
-}
-
-impl<'a> ResolveGeneratedContent<'a> {
- /// Creates a new generated content resolution traversal.
- pub fn new(layout_context: &'a LayoutContext<'a>) -> ResolveGeneratedContent<'a> {
- ResolveGeneratedContent {
- layout_context: layout_context,
- list_item: Counter::new(),
- counters: HashMap::new(),
- quote: 0,
- }
- }
-}
-
-impl<'a> InorderFlowTraversal for ResolveGeneratedContent<'a> {
- #[inline]
- fn process(&mut self, flow: &mut Flow, level: u32) {
- let mut mutator = ResolveGeneratedContentFragmentMutator {
- traversal: self,
- level: level,
- is_block: flow.is_block_like(),
- incremented: false,
- };
- flow.mutate_fragments(&mut mutator);
- }
-
- #[inline]
- fn should_process(&mut self, flow: &mut Flow) -> bool {
- flow::base(flow).restyle_damage.intersects(RESOLVE_GENERATED_CONTENT) ||
- flow::base(flow).flags.intersects(AFFECTS_COUNTERS | HAS_COUNTER_AFFECTING_CHILDREN)
- }
-}
-
-/// The object that mutates the generated content fragments.
-struct ResolveGeneratedContentFragmentMutator<'a,'b:'a> {
- /// The traversal.
- traversal: &'a mut ResolveGeneratedContent<'b>,
- /// The level we're at in the flow tree.
- level: u32,
- /// Whether this flow is a block flow.
- is_block: bool,
- /// Whether we've incremented the counter yet.
- incremented: bool,
-}
-
-impl<'a,'b> FragmentMutator for ResolveGeneratedContentFragmentMutator<'a,'b> {
- fn process(&mut self, fragment: &mut Fragment) {
- // We only reset and/or increment counters once per flow. This avoids double-incrementing
- // counters on list items (once for the main fragment and once for the marker).
- if !self.incremented {
- self.reset_and_increment_counters_as_necessary(fragment);
- }
-
- let mut list_style_type = fragment.style().get_list().list_style_type;
- if fragment.style().get_box().display != display::T::list_item {
- list_style_type = list_style_type::T::none
- }
-
- let mut new_info = None;
- {
- let info =
- if let SpecificFragmentInfo::GeneratedContent(ref mut info) = fragment.specific {
- info
- } else {
- return
- };
-
- match **info {
- GeneratedContentInfo::ListItem => {
- new_info = self.traversal.list_item.render(self.traversal.layout_context,
- fragment.node,
- fragment.style.clone(),
- list_style_type,
- RenderingMode::Suffix(".\u{00a0}"))
- }
- GeneratedContentInfo::ContentItem(ContentItem::String(_)) => {
- // Nothing to do here.
- }
- GeneratedContentInfo::ContentItem(ContentItem::Counter(ref counter_name,
- list_style_type)) => {
- let mut temporary_counter = Counter::new();
- let counter = self.traversal
- .counters
- .get(counter_name.as_slice())
- .unwrap_or(&mut temporary_counter);
- new_info = counter.render(self.traversal.layout_context,
- fragment.node,
- fragment.style.clone(),
- list_style_type,
- RenderingMode::Plain)
- }
- GeneratedContentInfo::ContentItem(ContentItem::Counters(ref counter_name,
- ref separator,
- list_style_type)) => {
- let mut temporary_counter = Counter::new();
- let counter = self.traversal
- .counters
- .get(counter_name.as_slice())
- .unwrap_or(&mut temporary_counter);
- new_info = counter.render(self.traversal.layout_context,
- fragment.node,
- fragment.style.clone(),
- list_style_type,
- RenderingMode::All(separator.as_slice()))
- }
- GeneratedContentInfo::ContentItem(ContentItem::OpenQuote) => {
- new_info = Some(render_text(self.traversal.layout_context,
- fragment.node,
- fragment.style.clone(),
- self.quote(&*fragment.style, false)));
- self.traversal.quote += 1
- }
- GeneratedContentInfo::ContentItem(ContentItem::CloseQuote) => {
- if self.traversal.quote >= 1 {
- self.traversal.quote -= 1
- }
-
- new_info = Some(render_text(self.traversal.layout_context,
- fragment.node,
- fragment.style.clone(),
- self.quote(&*fragment.style, true)));
- }
- GeneratedContentInfo::ContentItem(ContentItem::NoOpenQuote) => {
- self.traversal.quote += 1
- }
- GeneratedContentInfo::ContentItem(ContentItem::NoCloseQuote) => {
- if self.traversal.quote >= 1 {
- self.traversal.quote -= 1
- }
- }
- }
- };
-
- if let Some(new_info) = new_info {
- fragment.specific = new_info
- }
- }
-}
-
-impl<'a,'b> ResolveGeneratedContentFragmentMutator<'a,'b> {
- fn reset_and_increment_counters_as_necessary(&mut self, fragment: &mut Fragment) {
- let mut list_style_type = fragment.style().get_list().list_style_type;
- if !self.is_block || fragment.style().get_box().display != display::T::list_item {
- list_style_type = list_style_type::T::none
- }
-
- match list_style_type {
- list_style_type::T::disc | list_style_type::T::none | list_style_type::T::circle |
- list_style_type::T::square | list_style_type::T::disclosure_open |
- list_style_type::T::disclosure_closed => {}
- _ => self.traversal.list_item.increment(self.level, 1),
- }
-
- // Truncate down counters.
- for (_, counter) in self.traversal.counters.iter_mut() {
- counter.truncate_to_level(self.level);
- }
- self.traversal.list_item.truncate_to_level(self.level);
-
- for &(ref counter_name, value) in fragment.style().get_counters().counter_reset.0.iter() {
- if let Some(ref mut counter) = self.traversal.counters.get_mut(counter_name) {
- counter.reset(self.level, value);
- continue
- }
-
- let mut counter = Counter::new();
- counter.reset(self.level, value);
- self.traversal.counters.insert((*counter_name).clone(), counter);
- }
-
- for &(ref counter_name, value) in fragment.style()
- .get_counters()
- .counter_increment
- .0
- .iter() {
- if let Some(ref mut counter) = self.traversal.counters.get_mut(counter_name) {
- counter.increment(self.level, value);
- continue
- }
-
- let mut counter = Counter::new();
- counter.increment(self.level, value);
- self.traversal.counters.insert((*counter_name).clone(), counter);
- }
-
- self.incremented = true
- }
-
- fn quote(&self, style: &ComputedValues, close: bool) -> String {
- let quotes = &style.get_list().quotes;
- debug_assert!(!quotes.0.is_empty());
- let &(ref open_quote, ref close_quote) =
- if self.traversal.quote as uint >= quotes.0.len() {
- quotes.0.last().unwrap()
- } else {
- &quotes.0[self.traversal.quote as uint]
- };
- if close {
- close_quote.to_string()
- } else {
- open_quote.to_string()
- }
- }
-}
-
-/// A counter per CSS 2.1 § 12.4.
-struct Counter {
- /// The values at each level.
- values: Vec<CounterValue>,
-}
-
-impl Counter {
- fn new() -> Counter {
- Counter {
- values: Vec::new(),
- }
- }
-
- fn reset(&mut self, level: u32, value: i32) {
- // Do we have an instance of the counter at this level? If so, just mutate it.
- match self.values.last_mut() {
- Some(ref mut existing_value) if level == existing_value.level => {
- existing_value.value = value;
- return
- }
- _ => {}
- }
-
- // Otherwise, push a new instance of the counter.
- self.values.push(CounterValue {
- level: level,
- value: value,
- })
- }
-
- fn truncate_to_level(&mut self, level: u32) {
- let mut position = None;
- for (i, value) in self.values.iter().enumerate() {
- if value.level > level {
- position = Some(i);
- break
- }
- }
-
- if let Some(position) = position {
- self.values.truncate(position)
- }
- }
-
- fn increment(&mut self, level: u32, amount: i32) {
- if let Some(ref mut value) = self.values.last_mut() {
- value.value += amount;
- return
- }
-
- self.values.push(CounterValue {
- level: level,
- value: amount,
- })
- }
-
- fn render(&self,
- layout_context: &LayoutContext,
- node: OpaqueNode,
- style: Arc<ComputedValues>,
- list_style_type: list_style_type::T,
- mode: RenderingMode)
- -> Option<SpecificFragmentInfo> {
- let mut string = String::new();
- match mode {
- RenderingMode::Plain => {
- let value = match self.values.last() {
- Some(ref value) => value.value,
- None => 0,
- };
- push_representation(value, list_style_type, &mut string)
- }
- RenderingMode::Suffix(suffix) => {
- let value = match self.values.last() {
- Some(ref value) => value.value,
- None => 0,
- };
- push_representation(value, list_style_type, &mut string);
- string.push_str(suffix)
- }
- RenderingMode::All(separator) => {
- let mut first = true;
- for value in self.values.iter() {
- if !first {
- string.push_str(separator)
- }
- first = false;
- push_representation(value.value, list_style_type, &mut string)
- }
- }
- }
-
- if string.is_empty() {
- None
- } else {
- Some(render_text(layout_context, node, style, string))
- }
- }
-}
-
-/// How a counter value is to be rendered.
-enum RenderingMode<'a> {
- /// The innermost counter value is rendered with no extra decoration.
- Plain,
- /// The innermost counter value is rendered with the given string suffix.
- Suffix(&'a str),
- /// All values of the counter are rendered with the given separator string between them.
- All(&'a str),
-}
-
-/// The value of a counter at a given level.
-struct CounterValue {
- /// The level of the flow tree that this corresponds to.
- level: u32,
- /// The value of the counter at this level.
- value: i32,
-}
-
-/// Creates fragment info for a literal string.
-fn render_text(layout_context: &LayoutContext,
- node: OpaqueNode,
- style: Arc<ComputedValues>,
- string: String)
- -> SpecificFragmentInfo {
- let mut fragments = DList::new();
- let info = SpecificFragmentInfo::UnscannedText(UnscannedTextFragmentInfo::from_text(string));
- fragments.push_back(Fragment::from_opaque_node_and_style(node,
- style,
- incremental::all(),
- info));
- let fragments = TextRunScanner::new().scan_for_runs(layout_context.font_context(), fragments);
- debug_assert!(fragments.len() == 1);
- fragments.fragments.into_iter().next().unwrap().specific
-}
-
-/// Appends string that represents the value rendered using the system appropriate for the given
-/// `list-style-type` onto the given string.
-fn push_representation(value: i32, list_style_type: list_style_type::T, accumulator: &mut String) {
- match list_style_type {
- list_style_type::T::none => {}
- list_style_type::T::disc |
- list_style_type::T::circle |
- list_style_type::T::square |
- list_style_type::T::disclosure_open |
- list_style_type::T::disclosure_closed => {
- accumulator.push_str(static_representation(list_style_type).unwrap())
- }
- list_style_type::T::decimal => push_numeric_representation(value, &DECIMAL, accumulator),
- list_style_type::T::arabic_indic => {
- push_numeric_representation(value, &ARABIC_INDIC, accumulator)
- }
- list_style_type::T::bengali => push_numeric_representation(value, &BENGALI, accumulator),
- list_style_type::T::cambodian | list_style_type::T::khmer => {
- push_numeric_representation(value, &CAMBODIAN, accumulator)
- }
- list_style_type::T::cjk_decimal => {
- push_numeric_representation(value, &CJK_DECIMAL, accumulator)
- }
- list_style_type::T::devanagari => {
- push_numeric_representation(value, &DEVANAGARI, accumulator)
- }
- list_style_type::T::gujarati => push_numeric_representation(value, &GUJARATI, accumulator),
- list_style_type::T::gurmukhi => push_numeric_representation(value, &GURMUKHI, accumulator),
- list_style_type::T::kannada => push_numeric_representation(value, &KANNADA, accumulator),
- list_style_type::T::lao => push_numeric_representation(value, &LAO, accumulator),
- list_style_type::T::malayalam => {
- push_numeric_representation(value, &MALAYALAM, accumulator)
- }
- list_style_type::T::mongolian => {
- push_numeric_representation(value, &MONGOLIAN, accumulator)
- }
- list_style_type::T::myanmar => push_numeric_representation(value, &MYANMAR, accumulator),
- list_style_type::T::oriya => push_numeric_representation(value, &ORIYA, accumulator),
- list_style_type::T::persian => push_numeric_representation(value, &PERSIAN, accumulator),
- list_style_type::T::telugu => push_numeric_representation(value, &TELUGU, accumulator),
- list_style_type::T::thai => push_numeric_representation(value, &THAI, accumulator),
- list_style_type::T::tibetan => push_numeric_representation(value, &TIBETAN, accumulator),
- list_style_type::T::lower_alpha => {
- push_alphabetic_representation(value, &LOWER_ALPHA, accumulator)
- }
- list_style_type::T::upper_alpha => {
- push_alphabetic_representation(value, &UPPER_ALPHA, accumulator)
- }
- list_style_type::T::cjk_earthly_branch => {
- push_alphabetic_representation(value, &CJK_EARTHLY_BRANCH, accumulator)
- }
- list_style_type::T::cjk_heavenly_stem => {
- push_alphabetic_representation(value, &CJK_HEAVENLY_STEM, accumulator)
- }
- list_style_type::T::lower_greek => {
- push_alphabetic_representation(value, &LOWER_GREEK, accumulator)
- }
- list_style_type::T::hiragana => {
- push_alphabetic_representation(value, &HIRAGANA, accumulator)
- }
- list_style_type::T::hiragana_iroha => {
- push_alphabetic_representation(value, &HIRAGANA_IROHA, accumulator)
- }
- list_style_type::T::katakana => {
- push_alphabetic_representation(value, &KATAKANA, accumulator)
- }
- list_style_type::T::katakana_iroha => {
- push_alphabetic_representation(value, &KATAKANA_IROHA, accumulator)
- }
- }
-}
-
-/// Returns the static string that represents the value rendered using the given list-style, if
-/// possible.
-pub fn static_representation(list_style_type: list_style_type::T) -> Option<&'static str> {
- match list_style_type {
- list_style_type::T::disc => Some("•\u{00a0}"),
- list_style_type::T::circle => Some("◦\u{00a0}"),
- list_style_type::T::square => Some("▪\u{00a0}"),
- list_style_type::T::disclosure_open => Some("▾\u{00a0}"),
- list_style_type::T::disclosure_closed => Some("‣\u{00a0}"),
- _ => None,
- }
-}
-
-/// Pushes the string that represents the value rendered using the given *alphabetic system* onto
-/// the accumulator per CSS-COUNTER-STYLES § 3.1.4.
-fn push_alphabetic_representation(mut value: i32, system: &[char], accumulator: &mut String) {
- let mut string = SmallVec8::new();
- while value != 0 {
- // Step 1.
- value = value - 1;
- // Step 2.
- string.push(system[(value as uint) % system.len()]);
- // Step 3.
- value = ((value as uint) / system.len()) as i32;
- }
-
- for i in range(0, string.len()).rev() {
- accumulator.push(*string.get(i))
- }
-}
-
-/// Pushes the string that represents the value rendered using the given *numeric system* onto the
-/// accumulator per CSS-COUNTER-STYLES § 3.1.4.
-fn push_numeric_representation(mut value: i32, system: &[char], accumulator: &mut String) {
- // Step 1.
- if value == 0 {
- accumulator.push(system[0]);
- return
- }
-
- // Step 2.
- let mut string = SmallVec8::new();
- while value != 0 {
- // Step 2.1.
- string.push(system[(value as uint) % system.len()]);
- // Step 2.2.
- value = ((value as uint) / system.len()) as i32;
- }
-
- // Step 3.
- for i in range(0, string.len()).rev() {
- accumulator.push(*string.get(i))
- }
-}
-
diff --git a/components/layout/incremental.rs b/components/layout/incremental.rs
index 2bf7a67ee7a..b163a8fbf29 100644
--- a/components/layout/incremental.rs
+++ b/components/layout/incremental.rs
@@ -2,7 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-use flow::{self, AFFECTS_COUNTERS, Flow, HAS_COUNTER_AFFECTING_CHILDREN, IS_ABSOLUTELY_POSITIONED};
+use flow::{self, Flow};
+use flow::{IS_ABSOLUTELY_POSITIONED};
use std::fmt;
use std::sync::Arc;
@@ -31,12 +32,8 @@ bitflags! {
#[doc = "top-down."]
const REFLOW = 0x08,
- #[doc = "Re-resolve generated content. \
- Propagates up the flow tree because the computation is inorder."]
- const RESOLVE_GENERATED_CONTENT = 0x10,
-
#[doc = "The entire flow needs to be reconstructed."]
- const RECONSTRUCT_FLOW = 0x20
+ const RECONSTRUCT_FLOW = 0x10
}
}
@@ -53,9 +50,9 @@ impl RestyleDamage {
/// we should add to the *parent* of this flow.
pub fn damage_for_parent(self, child_is_absolutely_positioned: bool) -> RestyleDamage {
if child_is_absolutely_positioned {
- self & (REPAINT | REFLOW_OUT_OF_FLOW | RESOLVE_GENERATED_CONTENT)
+ self & (REPAINT | REFLOW_OUT_OF_FLOW)
} else {
- self & (REPAINT | REFLOW | REFLOW_OUT_OF_FLOW | RESOLVE_GENERATED_CONTENT)
+ self & (REPAINT | REFLOW | REFLOW_OUT_OF_FLOW)
}
}
@@ -94,11 +91,10 @@ impl fmt::Debug for RestyleDamage {
let mut first_elem = true;
let to_iter =
- [ (REPAINT, "Repaint")
- , (BUBBLE_ISIZES, "BubbleISizes")
+ [ (REPAINT, "Repaint")
+ , (BUBBLE_ISIZES, "BubbleISizes")
, (REFLOW_OUT_OF_FLOW, "ReflowOutOfFlow")
- , (REFLOW, "Reflow")
- , (RESOLVE_GENERATED_CONTENT, "ResolveGeneratedContent")
+ , (REFLOW, "Reflow")
, (RECONSTRUCT_FLOW, "ReconstructFlow")
];
@@ -130,18 +126,10 @@ macro_rules! add_if_not_equal(
})
);
-/// Returns a bitmask that represents a fully damaged flow.
-///
-/// Use this instead of `RestyleDamage::all()` because `RestyleDamage::all()` will result in
-/// unnecessary sequential resolution of generated content.
-pub fn all() -> RestyleDamage {
- REPAINT | BUBBLE_ISIZES | REFLOW_OUT_OF_FLOW | REFLOW | RECONSTRUCT_FLOW
-}
-
pub fn compute_damage(old: &Option<Arc<ComputedValues>>, new: &ComputedValues) -> RestyleDamage {
let old: &ComputedValues =
match old.as_ref() {
- None => return all(),
+ None => return RestyleDamage::all(),
Some(cv) => &**cv,
};
@@ -198,9 +186,6 @@ impl<'a> LayoutDamageComputation for &'a mut (Flow + 'a) {
let mut special_damage = SpecialRestyleDamage::empty();
let is_absolutely_positioned = flow::base(self).flags.contains(IS_ABSOLUTELY_POSITIONED);
- // In addition to damage, we use this phase to compute whether nodes affect CSS counters.
- let mut has_counter_affecting_children = false;
-
{
let self_base = flow::mut_base(self);
for kid in self_base.children.iter_mut() {
@@ -214,32 +199,21 @@ impl<'a> LayoutDamageComputation for &'a mut (Flow + 'a) {
self_base.restyle_damage
.insert(flow::base(kid).restyle_damage.damage_for_parent(
child_is_absolutely_positioned));
-
- has_counter_affecting_children = has_counter_affecting_children ||
- flow::base(kid).flags.intersects(AFFECTS_COUNTERS |
- HAS_COUNTER_AFFECTING_CHILDREN);
-
}
}
- let self_base = flow::mut_base(self);
+ let self_base = flow::base(self);
if self_base.flags.float_kind() != float::T::none &&
self_base.restyle_damage.intersects(REFLOW) {
special_damage.insert(REFLOW_ENTIRE_DOCUMENT);
}
- if has_counter_affecting_children {
- self_base.flags.insert(HAS_COUNTER_AFFECTING_CHILDREN)
- } else {
- self_base.flags.remove(HAS_COUNTER_AFFECTING_CHILDREN)
- }
-
special_damage
}
fn reflow_entire_document(self) {
let self_base = flow::mut_base(self);
- self_base.restyle_damage.insert(all());
+ self_base.restyle_damage.insert(RestyleDamage::all());
self_base.restyle_damage.remove(RECONSTRUCT_FLOW);
for kid in self_base.children.iter_mut() {
kid.reflow_entire_document();
diff --git a/components/layout/inline.rs b/components/layout/inline.rs
index 5c25d5ab00f..0a4b575c3c4 100644
--- a/components/layout/inline.rs
+++ b/components/layout/inline.rs
@@ -11,10 +11,10 @@ use floats::{FloatKind, Floats, PlacementInfo};
use flow::{BaseFlow, FlowClass, Flow, MutableFlowUtils, ForceNonfloatedFlag};
use flow::{IS_ABSOLUTELY_POSITIONED};
use flow;
-use fragment::{CoordinateSystem, Fragment, FragmentBorderBoxIterator, FragmentMutator};
-use fragment::{ScannedTextFragmentInfo, SpecificFragmentInfo};
+use fragment::{CoordinateSystem, Fragment, FragmentBorderBoxIterator, ScannedTextFragmentInfo};
+use fragment::{SpecificFragmentInfo};
use fragment::SplitInfo;
-use incremental::{REFLOW, REFLOW_OUT_OF_FLOW, RESOLVE_GENERATED_CONTENT};
+use incremental::{REFLOW, REFLOW_OUT_OF_FLOW};
use layout_debug;
use model::IntrinsicISizesContribution;
use text;
@@ -789,22 +789,14 @@ pub struct InlineFlow {
impl InlineFlow {
pub fn from_fragments(fragments: InlineFragments, writing_mode: WritingMode) -> InlineFlow {
- let mut flow = InlineFlow {
+ InlineFlow {
base: BaseFlow::new(None, writing_mode, ForceNonfloatedFlag::ForceNonfloated),
fragments: fragments,
lines: Vec::new(),
minimum_block_size_above_baseline: Au(0),
minimum_depth_below_baseline: Au(0),
first_line_indentation: Au(0),
- };
-
- for fragment in flow.fragments.fragments.iter() {
- if fragment.is_generated_content() {
- flow.base.restyle_damage.insert(RESOLVE_GENERATED_CONTENT)
- }
}
-
- flow
}
/// Returns the distance from the baseline for the logical block-start inline-start corner of
@@ -1399,12 +1391,6 @@ impl Flow for InlineFlow {
.translate(stacking_context_position))
}
}
-
- fn mutate_fragments(&mut self, mutator: &mut FragmentMutator) {
- for fragment in self.fragments.fragments.iter_mut() {
- mutator.process(fragment)
- }
- }
}
impl fmt::Debug for InlineFlow {
diff --git a/components/layout/layout_task.rs b/components/layout/layout_task.rs
index 3a0959d6b48..ca321f23526 100644
--- a/components/layout/layout_task.rs
+++ b/components/layout/layout_task.rs
@@ -834,14 +834,6 @@ impl LayoutTask {
layout_debug::begin_trace(layout_root.clone());
}
- // Resolve generated content.
- profile(TimeProfilerCategory::LayoutGeneratedContent,
- self.profiler_metadata(data),
- self.time_profiler_chan.clone(),
- || {
- sequential::resolve_generated_content(&mut layout_root, &shared_layout_context)
- });
-
// Perform the primary layout passes over the flow tree to compute the locations of all
// the boxes.
profile(TimeProfilerCategory::LayoutMain,
diff --git a/components/layout/lib.rs b/components/layout/lib.rs
index 0985a51997e..837945eff81 100644
--- a/components/layout/lib.rs
+++ b/components/layout/lib.rs
@@ -66,9 +66,7 @@ pub mod flow;
pub mod flow_list;
pub mod flow_ref;
pub mod fragment;
-pub mod generated_content;
pub mod layout_task;
-pub mod incremental;
pub mod inline;
pub mod list_item;
pub mod model;
@@ -84,6 +82,7 @@ pub mod table_cell;
pub mod text;
pub mod traversal;
pub mod util;
+pub mod incremental;
pub mod wrapper;
pub mod css {
diff --git a/components/layout/list_item.rs b/components/layout/list_item.rs
index 23748480cf1..eedb2d3b6b6 100644
--- a/components/layout/list_item.rs
+++ b/components/layout/list_item.rs
@@ -8,14 +8,12 @@
#![deny(unsafe_blocks)]
use block::BlockFlow;
+use construct::FlowConstructor;
use context::LayoutContext;
use display_list_builder::ListItemFlowDisplayListBuilding;
use floats::FloatKind;
use flow::{Flow, FlowClass};
-use fragment::{CoordinateSystem, Fragment, FragmentBorderBoxIterator, FragmentMutator};
-use fragment::{GeneratedContentInfo};
-use generated_content;
-use incremental::RESOLVE_GENERATED_CONTENT;
+use fragment::{Fragment, FragmentBorderBoxIterator};
use wrapper::ThreadSafeLayoutNode;
use geom::{Point2D, Rect};
@@ -38,33 +36,19 @@ pub struct ListItemFlow {
}
impl ListItemFlow {
- pub fn from_node_fragments_and_flotation(node: &ThreadSafeLayoutNode,
- main_fragment: Fragment,
- marker_fragment: Option<Fragment>,
- flotation: Option<FloatKind>)
- -> ListItemFlow {
- let mut this = ListItemFlow {
+ pub fn from_node_marker_and_flotation(constructor: &mut FlowConstructor,
+ node: &ThreadSafeLayoutNode,
+ marker_fragment: Option<Fragment>,
+ flotation: Option<FloatKind>)
+ -> ListItemFlow {
+ ListItemFlow {
block_flow: if let Some(flotation) = flotation {
- BlockFlow::float_from_node_and_fragment(node, main_fragment, flotation)
+ BlockFlow::float_from_node(constructor, node, flotation)
} else {
- BlockFlow::from_node_and_fragment(node, main_fragment)
+ BlockFlow::from_node(constructor, node)
},
marker: marker_fragment,
- };
-
- if let Some(ref marker) = this.marker {
- match marker.style().get_list().list_style_type {
- list_style_type::T::disc |
- list_style_type::T::none |
- list_style_type::T::circle |
- list_style_type::T::square |
- list_style_type::T::disclosure_open |
- list_style_type::T::disclosure_closed => {}
- _ => this.block_flow.base.restyle_damage.insert(RESOLVE_GENERATED_CONTENT),
- }
}
-
- this
}
}
@@ -150,55 +134,24 @@ impl Flow for ListItemFlow {
fn iterate_through_fragment_border_boxes(&self,
iterator: &mut FragmentBorderBoxIterator,
stacking_context_position: &Point2D<Au>) {
- self.block_flow.iterate_through_fragment_border_boxes(iterator, stacking_context_position);
-
- if let Some(ref marker) = self.marker {
- if iterator.should_process(marker) {
- iterator.process(
- marker,
- &marker.stacking_relative_border_box(&self.block_flow
- .base
- .stacking_relative_position,
- &self.block_flow
- .base
- .absolute_position_info
- .relative_containing_block_size,
- CoordinateSystem::Parent)
- .translate(stacking_context_position));
- }
- }
- }
-
- fn mutate_fragments(&mut self, mutator: &mut FragmentMutator) {
- self.block_flow.mutate_fragments(mutator);
-
- if let Some(ref mut marker) = self.marker {
- mutator.process(marker)
- }
+ self.block_flow.iterate_through_fragment_border_boxes(iterator, stacking_context_position)
}
}
-/// The kind of content that `list-style-type` results in.
-pub enum ListStyleTypeContent {
- None,
- StaticText(&'static str),
- GeneratedContent(Box<GeneratedContentInfo>),
-}
-
-impl ListStyleTypeContent {
- /// Returns the content to be used for the given value of the `list-style-type` property.
- pub fn from_list_style_type(list_style_type: list_style_type::T) -> ListStyleTypeContent {
- // Just to keep things simple, use a nonbreaking space (Unicode 0xa0) to provide the marker
- // separation.
- match list_style_type {
- list_style_type::T::none => ListStyleTypeContent::None,
- list_style_type::T::disc | list_style_type::T::circle | list_style_type::T::square |
- list_style_type::T::disclosure_open | list_style_type::T::disclosure_closed => {
- let text = generated_content::static_representation(list_style_type).unwrap();
- ListStyleTypeContent::StaticText(text)
- }
- _ => ListStyleTypeContent::GeneratedContent(box GeneratedContentInfo::ListItem),
- }
+/// Returns the static text to be used for the given value of the `list-style-type` property.
+///
+/// TODO(pcwalton): Return either a string or a counter descriptor, once we support counters.
+pub fn static_text_for_list_style_type(list_style_type: list_style_type::T)
+ -> Option<&'static str> {
+ // Just to keep things simple, use a nonbreaking space (Unicode 0xa0) to provide the marker
+ // separation.
+ match list_style_type {
+ list_style_type::T::none => None,
+ list_style_type::T::disc => Some("•\u{a0}"),
+ list_style_type::T::circle => Some("◦\u{a0}"),
+ list_style_type::T::square => Some("▪\u{a0}"),
+ list_style_type::T::disclosure_open => Some("▾\u{a0}"),
+ list_style_type::T::disclosure_closed => Some("‣\u{a0}"),
}
}
diff --git a/components/layout/sequential.rs b/components/layout/sequential.rs
index c33441b6faf..ff2bd948c51 100644
--- a/components/layout/sequential.rs
+++ b/components/layout/sequential.rs
@@ -5,11 +5,10 @@
//! Implements sequential traversals over the DOM and flow trees.
use context::{LayoutContext, SharedLayoutContext};
-use flow::{self, Flow, ImmutableFlowUtils, InorderFlowTraversal, MutableFlowUtils};
-use flow::{PostorderFlowTraversal, PreorderFlowTraversal};
+use flow::{self, Flow, ImmutableFlowUtils, MutableFlowUtils, PostorderFlowTraversal};
+use flow::{PreorderFlowTraversal};
use flow_ref::FlowRef;
use fragment::FragmentBorderBoxIterator;
-use generated_content::ResolveGeneratedContent;
use traversal::{BubbleISizes, RecalcStyleForNode, ConstructFlows};
use traversal::{AssignBSizesAndStoreOverflow, AssignISizes};
use traversal::{ComputeAbsolutePositions, BuildDisplayList};
@@ -40,24 +39,6 @@ pub fn traverse_dom_preorder(root: LayoutNode,
doit(root, recalc_style, construct_flows);
}
-pub fn resolve_generated_content(root: &mut FlowRef, shared_layout_context: &SharedLayoutContext) {
- fn doit(flow: &mut Flow, level: u32, traversal: &mut ResolveGeneratedContent) {
- if !traversal.should_process(flow) {
- return
- }
-
- traversal.process(flow, level);
-
- for kid in flow::mut_base(flow).children.iter_mut() {
- doit(kid, level + 1, traversal)
- }
- }
-
- let layout_context = LayoutContext::new(shared_layout_context);
- let mut traversal = ResolveGeneratedContent::new(&layout_context);
- doit(&mut **root, 0, &mut traversal)
-}
-
pub fn traverse_flow_tree_preorder(root: &mut FlowRef,
shared_layout_context: &SharedLayoutContext) {
fn doit(flow: &mut Flow,
@@ -138,4 +119,3 @@ pub fn iterate_through_flow_tree_fragment_border_boxes(root: &mut FlowRef,
doit(&mut **root, iterator, &ZERO_POINT);
}
-
diff --git a/components/layout/table.rs b/components/layout/table.rs
index 4a23db3f532..270143a21da 100644
--- a/components/layout/table.rs
+++ b/components/layout/table.rs
@@ -8,11 +8,12 @@
use block::{BlockFlow, ISizeAndMarginsComputer, MarginsMayCollapseFlag};
use block::{ISizeConstraintInput, ISizeConstraintSolution};
+use construct::FlowConstructor;
use context::LayoutContext;
use floats::FloatKind;
use flow::{self, Flow, FlowClass, IMPACTED_BY_LEFT_FLOATS, IMPACTED_BY_RIGHT_FLOATS};
-use flow::{ImmutableFlowUtils};
-use fragment::{Fragment, FragmentBorderBoxIterator, FragmentMutator};
+use flow::ImmutableFlowUtils;
+use fragment::{Fragment, FragmentBorderBoxIterator};
use layout_debug;
use model::{IntrinsicISizes, IntrinsicISizesContribution};
use table_row::CellIntrinsicInlineSize;
@@ -54,12 +55,12 @@ impl TableFlow {
fragment: Fragment)
-> TableFlow {
let mut block_flow = BlockFlow::from_node_and_fragment(node, fragment);
- let table_layout =
- if block_flow.fragment().style().get_table().table_layout == table_layout::T::fixed {
- TableLayout::Fixed
- } else {
- TableLayout::Auto
- };
+ let table_layout = if block_flow.fragment().style().get_table().table_layout ==
+ table_layout::T::fixed {
+ TableLayout::Fixed
+ } else {
+ TableLayout::Auto
+ };
TableFlow {
block_flow: block_flow,
column_intrinsic_inline_sizes: Vec::new(),
@@ -68,17 +69,35 @@ impl TableFlow {
}
}
- pub fn float_from_node_and_fragment(node: &ThreadSafeLayoutNode,
- fragment: Fragment,
- float_kind: FloatKind)
- -> TableFlow {
- let mut block_flow = BlockFlow::float_from_node_and_fragment(node, fragment, float_kind);
- let table_layout =
- if block_flow.fragment().style().get_table().table_layout == table_layout::T::fixed {
- TableLayout::Fixed
- } else {
- TableLayout::Auto
- };
+ pub fn from_node(constructor: &mut FlowConstructor,
+ node: &ThreadSafeLayoutNode)
+ -> TableFlow {
+ let mut block_flow = BlockFlow::from_node(constructor, node);
+ let table_layout = if block_flow.fragment().style().get_table().table_layout ==
+ table_layout::T::fixed {
+ TableLayout::Fixed
+ } else {
+ TableLayout::Auto
+ };
+ TableFlow {
+ block_flow: block_flow,
+ column_intrinsic_inline_sizes: Vec::new(),
+ column_computed_inline_sizes: Vec::new(),
+ table_layout: table_layout
+ }
+ }
+
+ pub fn float_from_node(constructor: &mut FlowConstructor,
+ node: &ThreadSafeLayoutNode,
+ float_kind: FloatKind)
+ -> TableFlow {
+ let mut block_flow = BlockFlow::float_from_node(constructor, node, float_kind);
+ let table_layout = if block_flow.fragment().style().get_table().table_layout ==
+ table_layout::T::fixed {
+ TableLayout::Fixed
+ } else {
+ TableLayout::Auto
+ };
TableFlow {
block_flow: block_flow,
column_intrinsic_inline_sizes: Vec::new(),
@@ -377,10 +396,6 @@ impl Flow for TableFlow {
stacking_context_position: &Point2D<Au>) {
self.block_flow.iterate_through_fragment_border_boxes(iterator, stacking_context_position)
}
-
- fn mutate_fragments(&mut self, mutator: &mut FragmentMutator) {
- self.block_flow.mutate_fragments(mutator)
- }
}
impl fmt::Debug for TableFlow {
diff --git a/components/layout/table_caption.rs b/components/layout/table_caption.rs
index f892929932b..43eaacf9384 100644
--- a/components/layout/table_caption.rs
+++ b/components/layout/table_caption.rs
@@ -7,9 +7,10 @@
#![deny(unsafe_blocks)]
use block::BlockFlow;
+use construct::FlowConstructor;
use context::LayoutContext;
use flow::{FlowClass, Flow};
-use fragment::{Fragment, FragmentBorderBoxIterator, FragmentMutator};
+use fragment::FragmentBorderBoxIterator;
use wrapper::ThreadSafeLayoutNode;
use geom::{Point2D, Rect};
@@ -25,10 +26,11 @@ pub struct TableCaptionFlow {
}
impl TableCaptionFlow {
- pub fn from_node_and_fragment(node: &ThreadSafeLayoutNode, fragment: Fragment)
- -> TableCaptionFlow {
+ pub fn from_node(constructor: &mut FlowConstructor,
+ node: &ThreadSafeLayoutNode)
+ -> TableCaptionFlow {
TableCaptionFlow {
- block_flow: BlockFlow::from_node_and_fragment(node, fragment)
+ block_flow: BlockFlow::from_node(constructor, node)
}
}
}
@@ -94,10 +96,6 @@ impl Flow for TableCaptionFlow {
stacking_context_position: &Point2D<Au>) {
self.block_flow.iterate_through_fragment_border_boxes(iterator, stacking_context_position)
}
-
- fn mutate_fragments(&mut self, mutator: &mut FragmentMutator) {
- self.block_flow.mutate_fragments(mutator)
- }
}
impl fmt::Debug for TableCaptionFlow {
diff --git a/components/layout/table_cell.rs b/components/layout/table_cell.rs
index 2735f5294df..670dcf7b344 100644
--- a/components/layout/table_cell.rs
+++ b/components/layout/table_cell.rs
@@ -9,7 +9,7 @@
use block::{BlockFlow, ISizeAndMarginsComputer, MarginsMayCollapseFlag};
use context::LayoutContext;
use flow::{Flow, FlowClass};
-use fragment::{Fragment, FragmentBorderBoxIterator, FragmentMutator};
+use fragment::{Fragment, FragmentBorderBoxIterator};
use model::{MaybeAuto};
use layout_debug;
use table::InternalTable;
@@ -178,10 +178,6 @@ impl Flow for TableCellFlow {
stacking_context_position: &Point2D<Au>) {
self.block_flow.iterate_through_fragment_border_boxes(iterator, stacking_context_position)
}
-
- fn mutate_fragments(&mut self, mutator: &mut FragmentMutator) {
- self.block_flow.mutate_fragments(mutator)
- }
}
impl fmt::Debug for TableCellFlow {
diff --git a/components/layout/table_colgroup.rs b/components/layout/table_colgroup.rs
index 2bf02db4428..6d19a0c5778 100644
--- a/components/layout/table_colgroup.rs
+++ b/components/layout/table_colgroup.rs
@@ -9,7 +9,7 @@
use context::LayoutContext;
use css::node_style::StyledNode;
use flow::{BaseFlow, FlowClass, Flow, ForceNonfloatedFlag};
-use fragment::{Fragment, FragmentBorderBoxIterator, FragmentMutator, SpecificFragmentInfo};
+use fragment::{Fragment, FragmentBorderBoxIterator, SpecificFragmentInfo};
use layout_debug;
use wrapper::ThreadSafeLayoutNode;
@@ -104,8 +104,6 @@ impl Flow for TableColGroupFlow {
fn iterate_through_fragment_border_boxes(&self,
_: &mut FragmentBorderBoxIterator,
_: &Point2D<Au>) {}
-
- fn mutate_fragments(&mut self, _: &mut FragmentMutator) {}
}
impl fmt::Debug for TableColGroupFlow {
diff --git a/components/layout/table_row.rs b/components/layout/table_row.rs
index 6425b63d1ea..d712d7e4945 100644
--- a/components/layout/table_row.rs
+++ b/components/layout/table_row.rs
@@ -8,9 +8,11 @@
use block::BlockFlow;
use block::ISizeAndMarginsComputer;
+use construct::FlowConstructor;
use context::LayoutContext;
-use flow::{self, FlowClass, Flow, ImmutableFlowUtils};
-use fragment::{Fragment, FragmentBorderBoxIterator, FragmentMutator};
+use flow::{FlowClass, Flow, ImmutableFlowUtils};
+use flow;
+use fragment::{Fragment, FragmentBorderBoxIterator};
use layout_debug;
use table::{ColumnComputedInlineSize, ColumnIntrinsicInlineSize, InternalTable};
use model::MaybeAuto;
@@ -47,7 +49,8 @@ pub struct CellIntrinsicInlineSize {
}
impl TableRowFlow {
- pub fn from_node_and_fragment(node: &ThreadSafeLayoutNode, fragment: Fragment)
+ pub fn from_node_and_fragment(node: &ThreadSafeLayoutNode,
+ fragment: Fragment)
-> TableRowFlow {
TableRowFlow {
block_flow: BlockFlow::from_node_and_fragment(node, fragment),
@@ -56,6 +59,16 @@ impl TableRowFlow {
}
}
+ pub fn from_node(constructor: &mut FlowConstructor,
+ node: &ThreadSafeLayoutNode)
+ -> TableRowFlow {
+ TableRowFlow {
+ block_flow: BlockFlow::from_node(constructor, node),
+ cell_intrinsic_inline_sizes: Vec::new(),
+ column_computed_inline_sizes: Vec::new()
+ }
+ }
+
pub fn fragment<'a>(&'a mut self) -> &'a Fragment {
&self.block_flow.fragment
}
@@ -318,10 +331,6 @@ impl Flow for TableRowFlow {
stacking_context_position: &Point2D<Au>) {
self.block_flow.iterate_through_fragment_border_boxes(iterator, stacking_context_position)
}
-
- fn mutate_fragments(&mut self, mutator: &mut FragmentMutator) {
- self.block_flow.mutate_fragments(mutator)
- }
}
impl fmt::Debug for TableRowFlow {
diff --git a/components/layout/table_rowgroup.rs b/components/layout/table_rowgroup.rs
index ac86cd8987e..9728fde36a8 100644
--- a/components/layout/table_rowgroup.rs
+++ b/components/layout/table_rowgroup.rs
@@ -7,9 +7,10 @@
#![deny(unsafe_blocks)]
use block::{BlockFlow, ISizeAndMarginsComputer, MarginsMayCollapseFlag};
+use construct::FlowConstructor;
use context::LayoutContext;
use flow::{FlowClass, Flow};
-use fragment::{Fragment, FragmentBorderBoxIterator, FragmentMutator};
+use fragment::{Fragment, FragmentBorderBoxIterator};
use layout_debug;
use table::{ColumnComputedInlineSize, ColumnIntrinsicInlineSize, InternalTable};
use wrapper::ThreadSafeLayoutNode;
@@ -44,6 +45,15 @@ impl TableRowGroupFlow {
}
}
+ pub fn from_node(constructor: &mut FlowConstructor, node: &ThreadSafeLayoutNode)
+ -> TableRowGroupFlow {
+ TableRowGroupFlow {
+ block_flow: BlockFlow::from_node(constructor, node),
+ column_intrinsic_inline_sizes: Vec::new(),
+ column_computed_inline_sizes: Vec::new(),
+ }
+ }
+
pub fn fragment<'a>(&'a mut self) -> &'a Fragment {
&self.block_flow.fragment
}
@@ -155,10 +165,6 @@ impl Flow for TableRowGroupFlow {
stacking_context_position: &Point2D<Au>) {
self.block_flow.iterate_through_fragment_border_boxes(iterator, stacking_context_position)
}
-
- fn mutate_fragments(&mut self, mutator: &mut FragmentMutator) {
- self.block_flow.mutate_fragments(mutator)
- }
}
impl fmt::Debug for TableRowGroupFlow {
diff --git a/components/layout/table_wrapper.rs b/components/layout/table_wrapper.rs
index fbe124af1bf..e849150bede 100644
--- a/components/layout/table_wrapper.rs
+++ b/components/layout/table_wrapper.rs
@@ -13,13 +13,13 @@
#![deny(unsafe_blocks)]
-use block::{BlockFlow, BlockNonReplaced, FloatNonReplaced, ISizeAndMarginsComputer};
-use block::{MarginsMayCollapseFlag};
+use block::{BlockFlow, BlockNonReplaced, FloatNonReplaced, ISizeAndMarginsComputer, MarginsMayCollapseFlag};
+use construct::FlowConstructor;
use context::LayoutContext;
use floats::FloatKind;
use flow::{FlowClass, Flow, ImmutableFlowUtils};
use flow::{IMPACTED_BY_LEFT_FLOATS, IMPACTED_BY_RIGHT_FLOATS};
-use fragment::{Fragment, FragmentBorderBoxIterator, FragmentMutator};
+use fragment::{Fragment, FragmentBorderBoxIterator};
use table::{ColumnComputedInlineSize, ColumnIntrinsicInlineSize};
use wrapper::ThreadSafeLayoutNode;
@@ -70,6 +70,23 @@ impl TableWrapperFlow {
}
}
+ pub fn from_node(constructor: &mut FlowConstructor,
+ node: &ThreadSafeLayoutNode)
+ -> TableWrapperFlow {
+ let mut block_flow = BlockFlow::from_node(constructor, node);
+ let table_layout = if block_flow.fragment().style().get_table().table_layout ==
+ table_layout::T::fixed {
+ TableLayout::Fixed
+ } else {
+ TableLayout::Auto
+ };
+ TableWrapperFlow {
+ block_flow: block_flow,
+ column_intrinsic_inline_sizes: vec!(),
+ table_layout: table_layout
+ }
+ }
+
pub fn float_from_node_and_fragment(node: &ThreadSafeLayoutNode,
fragment: Fragment,
float_kind: FloatKind)
@@ -366,10 +383,6 @@ impl Flow for TableWrapperFlow {
stacking_context_position: &Point2D<Au>) {
self.block_flow.iterate_through_fragment_border_boxes(iterator, stacking_context_position)
}
-
- fn mutate_fragments(&mut self, mutator: &mut FragmentMutator) {
- self.block_flow.mutate_fragments(mutator)
- }
}
impl fmt::Debug for TableWrapperFlow {
diff --git a/components/layout/traversal.rs b/components/layout/traversal.rs
index 04a99ee4b77..2211cf2fcce 100644
--- a/components/layout/traversal.rs
+++ b/components/layout/traversal.rs
@@ -13,7 +13,7 @@ use context::LayoutContext;
use flow::{Flow, MutableFlowUtils};
use flow::{PreorderFlowTraversal, PostorderFlowTraversal};
use flow;
-use incremental::{self, BUBBLE_ISIZES, REFLOW, REFLOW_OUT_OF_FLOW, RestyleDamage};
+use incremental::{RestyleDamage, BUBBLE_ISIZES, REFLOW, REFLOW_OUT_OF_FLOW};
use wrapper::{layout_node_to_unsafe_layout_node, LayoutNode};
use wrapper::{PostorderNodeMutTraversal, ThreadSafeLayoutNode, UnsafeLayoutNode};
use wrapper::{PreorderDomTraversal, PostorderDomTraversal};
@@ -171,7 +171,7 @@ impl<'a> PreorderDomTraversal for RecalcStyleForNode<'a> {
&mut applicable_declarations,
&mut shareable);
} else {
- ThreadSafeLayoutNode::new(&node).set_restyle_damage(incremental::all())
+ ThreadSafeLayoutNode::new(&node).set_restyle_damage(RestyleDamage::all())
}
// Perform the CSS cascade.
@@ -376,4 +376,3 @@ impl<'a> PostorderFlowTraversal for BuildDisplayList<'a> {
flow.build_display_list(self.layout_context);
}
}
-
diff --git a/components/layout/wrapper.rs b/components/layout/wrapper.rs
index e43603d0dc1..54f341d1d09 100644
--- a/components/layout/wrapper.rs
+++ b/components/layout/wrapper.rs
@@ -67,11 +67,9 @@ use std::marker::ContravariantLifetime;
use std::mem;
use std::sync::mpsc::Sender;
use string_cache::{Atom, Namespace};
-use selectors::parser::{NamespaceConstraint, AttrSelector};
-use style::computed_values::content::ContentItem;
use style::computed_values::{content, display, white_space};
-use style::legacy::{IntegerAttribute, LengthAttribute, SimpleColorAttribute};
-use style::legacy::{UnsignedIntegerAttribute};
+use selectors::parser::{NamespaceConstraint, AttrSelector};
+use style::legacy::{LengthAttribute, SimpleColorAttribute, UnsignedIntegerAttribute, IntegerAttribute};
use style::node::{TElement, TElementAttributes, TNode};
use style::properties::PropertyDeclarationBlock;
use url::Url;
@@ -156,11 +154,10 @@ pub trait TLayoutNode {
}
}
- /// If this is a text node or generated content, copies out its content. If this is not a text
- /// node, fails.
+ /// If this is a text node, copies out the text. If this is not a text node, fails.
///
- /// FIXME(pcwalton): This might have too much copying and/or allocation. Profile this.
- fn text_content(&self) -> Vec<ContentItem>;
+ /// FIXME(pcwalton): Don't copy text. Atomically reference count instead.
+ fn text(&self) -> String;
/// Returns the first child of this node.
fn first_child(&self) -> Option<Self>;
@@ -217,25 +214,19 @@ impl<'ln> TLayoutNode for LayoutNode<'ln> {
}
}
- fn text_content(&self) -> Vec<ContentItem> {
+ fn text(&self) -> String {
unsafe {
let text: Option<LayoutJS<Text>> = TextCast::to_layout_js(self.get_jsmanaged());
if let Some(text) = text {
- return vec![
- ContentItem::String((*text.unsafe_get()).characterdata()
- .data_for_layout()
- .to_owned())
- ];
+ return (*text.unsafe_get()).characterdata().data_for_layout().to_owned();
}
- let input: Option<LayoutJS<HTMLInputElement>> =
- HTMLInputElementCast::to_layout_js(self.get_jsmanaged());
+ let input: Option<LayoutJS<HTMLInputElement>> = HTMLInputElementCast::to_layout_js(self.get_jsmanaged());
if let Some(input) = input {
- return vec![ContentItem::String(input.get_value_for_layout())];
+ return input.get_value_for_layout();
}
- let area: Option<LayoutJS<HTMLTextAreaElement>> =
- HTMLTextAreaElementCast::to_layout_js(self.get_jsmanaged());
+ let area: Option<LayoutJS<HTMLTextAreaElement>> = HTMLTextAreaElementCast::to_layout_js(self.get_jsmanaged());
if let Some(area) = area {
- return vec![ContentItem::String(area.get_value_for_layout())];
+ return area.get_value_for_layout();
}
panic!("not text!")
@@ -670,10 +661,16 @@ impl<'le> TElementAttributes for LayoutElement<'le> {
}
}
-fn get_content(content_list: &content::T) -> Vec<ContentItem> {
+fn get_content(content_list: &content::T) -> String {
match *content_list {
- content::T::Content(ref value) if !value.is_empty() => (*value).clone(),
- _ => vec![ContentItem::String("".to_owned())],
+ content::T::Content(ref value) => {
+ let iter = &mut value.clone().into_iter().peekable();
+ match iter.next() {
+ Some(content::ContentItem::StringContent(content)) => content,
+ _ => "".to_owned(),
+ }
+ }
+ _ => "".to_owned(),
}
}
@@ -765,7 +762,7 @@ impl<'ln> TLayoutNode for ThreadSafeLayoutNode<'ln> {
}
}
- fn text_content(&self) -> Vec<ContentItem> {
+ fn text(&self) -> String {
if self.pseudo != PseudoElementType::Normal {
let layout_data_ref = self.borrow_layout_data();
let node_layout_data_wrapper = layout_data_ref.as_ref().unwrap();
@@ -778,7 +775,7 @@ impl<'ln> TLayoutNode for ThreadSafeLayoutNode<'ln> {
return get_content(&after_style.get_box().content)
}
}
- self.node.text_content()
+ self.node.text()
}
}
diff --git a/components/script/dom/webidls/CSSStyleDeclaration.webidl b/components/script/dom/webidls/CSSStyleDeclaration.webidl
index bde48aaaff3..46ca8424b70 100644
--- a/components/script/dom/webidls/CSSStyleDeclaration.webidl
+++ b/components/script/dom/webidls/CSSStyleDeclaration.webidl
@@ -103,11 +103,6 @@ partial interface CSSStyleDeclaration {
[TreatNullAs=EmptyString] attribute DOMString listStyleType;
[TreatNullAs=EmptyString] attribute DOMString listStyleImage;
- [TreatNullAs=EmptyString] attribute DOMString quotes;
-
- [TreatNullAs=EmptyString] attribute DOMString counterIncrement;
- [TreatNullAs=EmptyString] attribute DOMString counterReset;
-
[TreatNullAs=EmptyString] attribute DOMString overflow;
[TreatNullAs=EmptyString] attribute DOMString overflowX;
[TreatNullAs=EmptyString] attribute DOMString overflowY;
diff --git a/components/style/properties.mako.rs b/components/style/properties.mako.rs
index b3ccef6f95a..5330de59a93 100644
--- a/components/style/properties.mako.rs
+++ b/components/style/properties.mako.rs
@@ -758,241 +758,86 @@ pub mod longhands {
${switch_to_style_struct("Box")}
<%self:longhand name="content">
- use cssparser::{ToCss, Token};
- use std::ascii::AsciiExt;
- use std::borrow::ToOwned;
- use values::computed::ComputedValueAsSpecified;
-
- use super::list_style_type;
-
- pub use self::computed_value::T as SpecifiedValue;
- pub use self::computed_value::ContentItem;
-
- impl ComputedValueAsSpecified for SpecifiedValue {}
+ pub use self::computed_value::T as SpecifiedValue;
+ pub use self::computed_value::ContentItem;
+ use cssparser::Token;
+ use values::computed::ComputedValueAsSpecified;
- pub mod computed_value {
- use super::super::list_style_type;
+ impl ComputedValueAsSpecified for SpecifiedValue {}
- use cssparser::{ToCss, Token};
- use std::borrow::IntoCow;
- use text_writer::{self, TextWriter};
+ pub mod computed_value {
+ use std::borrow::IntoCow;
+ use cssparser::{ToCss, Token};
+ use text_writer::{self, TextWriter};
- #[derive(PartialEq, Eq, Clone)]
- pub enum ContentItem {
- /// Literal string content.
- String(String),
- /// `counter(name, style)`.
- Counter(String, list_style_type::computed_value::T),
- /// `counters(name, separator, style)`.
- Counters(String, String, list_style_type::computed_value::T),
- /// `open-quote`.
- OpenQuote,
- /// `close-quote`.
- CloseQuote,
- /// `no-open-quote`.
- NoOpenQuote,
- /// `no-close-quote`.
- NoCloseQuote,
- }
-
- impl ToCss for ContentItem {
- fn to_css<W>(&self, dest: &mut W) -> text_writer::Result where W: TextWriter {
- match self {
- &ContentItem::String(ref s) => {
- Token::QuotedString((&**s).into_cow()).to_css(dest)
- }
- &ContentItem::Counter(ref s, _) => {
- // FIXME(pcwalton)
- Token::QuotedString((&**s).into_cow()).to_css(dest)
- }
- &ContentItem::Counters(ref s, _, _) => {
- // FIXME(pcwalton)
- Token::QuotedString((&**s).into_cow()).to_css(dest)
- }
- &ContentItem::OpenQuote => dest.write_str("open-quote"),
- &ContentItem::CloseQuote => dest.write_str("close-quote"),
- &ContentItem::NoOpenQuote => dest.write_str("no-open-quote"),
- &ContentItem::NoCloseQuote => dest.write_str("no-close-quote"),
- }
+ #[derive(PartialEq, Eq, Clone)]
+ pub enum ContentItem {
+ StringContent(String),
}
- }
-
- #[allow(non_camel_case_types)]
- #[derive(PartialEq, Eq, Clone)]
- pub enum T {
- normal,
- none,
- Content(Vec<ContentItem>),
- }
- impl ToCss for T {
- fn to_css<W>(&self, dest: &mut W) -> text_writer::Result where W: TextWriter {
- match self {
- &T::normal => dest.write_str("normal"),
- &T::none => dest.write_str("none"),
- &T::Content(ref content) => {
- let mut iter = content.iter();
- try!(iter.next().unwrap().to_css(dest));
- for c in iter {
- try!(c.to_css(dest));
+ impl ToCss for ContentItem {
+ fn to_css<W>(&self, dest: &mut W) -> text_writer::Result where W: TextWriter {
+ match self {
+ &ContentItem::StringContent(ref s) => {
+ Token::QuotedString((&**s).into_cow()).to_css(dest)
}
- Ok(())
}
}
}
- }
- }
- #[inline]
- pub fn get_initial_value() -> computed_value::T {
- computed_value::T::normal
- }
-
- pub fn counter_name_is_illegal(name: &str) -> bool {
- name.eq_ignore_ascii_case("none") || name.eq_ignore_ascii_case("inherit") ||
- name.eq_ignore_ascii_case("initial")
- }
- // normal | none | [ <string> | <counter> | open-quote | close-quote | no-open-quote |
- // no-close-quote ]+
- // TODO: <uri>, attr(<identifier>)
- pub fn parse(context: &ParserContext, input: &mut Parser)
- -> Result<SpecifiedValue, ()> {
- if input.try(|input| input.expect_ident_matching("normal")).is_ok() {
- return Ok(SpecifiedValue::normal)
- }
- if input.try(|input| input.expect_ident_matching("none")).is_ok() {
- return Ok(SpecifiedValue::none)
- }
- let mut content = vec![];
- loop {
- match input.next() {
- Ok(Token::QuotedString(value)) => {
- content.push(ContentItem::String(value.into_owned()))
- }
- Ok(Token::Function(name)) => {
- if name.eq_ignore_ascii_case("counter") {
- let (mut counter_name, mut counter_style) = (None, None);
- match input.parse_nested_block(|input| {
- input.parse_comma_separated(|input| {
- if counter_name.is_none() {
- match input.next() {
- Ok(Token::Ident(value)) => {
- counter_name = Some((*value).to_owned());
- Ok(())
- }
- _ => Err(())
- }
- } else if counter_style.is_none() {
- match list_style_type::parse(context, input) {
- Ok(style) => {
- counter_style = Some(style);
- Ok(())
- }
- _ => Err(())
- }
- } else {
- Err(())
- }
- })
- }) {
- Ok(_) => {
- match (counter_name, counter_style) {
- (Some(name), Some(style)) => {
- content.push(ContentItem::Counter(name, style))
- }
- (Some(name), None) => {
- content.push(ContentItem::Counter(
- name,
- list_style_type::computed_value::T::decimal))
- }
- _ => return Err(()),
- }
- }
- Err(_) => return Err(()),
- }
- } else if name.eq_ignore_ascii_case("counters") {
- let mut counter_name = None;
- let mut counter_separator = None;
- let mut counter_style = None;
- match input.parse_nested_block(|input| {
- input.parse_comma_separated(|input| {
- if counter_name.is_none() {
- match input.next() {
- Ok(Token::Ident(value)) => {
- counter_name = Some((*value).to_owned());
- Ok(())
- }
- _ => Err(())
- }
- } else if counter_separator.is_none() {
- match input.next() {
- Ok(Token::QuotedString(value)) => {
- counter_separator = Some((*value).to_owned());
- Ok(())
- }
- _ => Err(())
- }
- } else if counter_style.is_none() {
- match input.try(|input| {
- list_style_type::parse(context, input)
- }) {
- Ok(style) => {
- counter_style = Some(style);
- Ok(())
- }
- _ => Err(()),
- }
- } else {
- Err(())
- }
- })
- }) {
- Ok(_) => {
- match (counter_name, counter_separator, counter_style) {
- (Some(name), Some(separator), Some(style)) => {
- content.push(ContentItem::Counters(name,
- separator,
- style))
- }
- (Some(name), Some(separator), None) => {
- content.push(ContentItem::Counters(
- name,
- separator,
- list_style_type::computed_value::T::decimal))
- }
- _ => return Err(()),
- }
+ #[allow(non_camel_case_types)]
+ #[derive(PartialEq, Eq, Clone)]
+ pub enum T {
+ normal,
+ none,
+ Content(Vec<ContentItem>),
+ }
+
+ impl ToCss for T {
+ fn to_css<W>(&self, dest: &mut W) -> text_writer::Result where W: TextWriter {
+ match self {
+ &T::normal => dest.write_str("normal"),
+ &T::none => dest.write_str("none"),
+ &T::Content(ref content) => {
+ let mut iter = content.iter();
+ try!(iter.next().unwrap().to_css(dest));
+ for c in iter {
+ try!(c.to_css(dest));
}
- Err(_) => return Err(()),
+ Ok(())
}
- } else {
- return Err(())
}
}
- Ok(Token::Ident(ident)) => {
- if ident.eq_ignore_ascii_case("open-quote") {
- content.push(ContentItem::OpenQuote)
- } else if ident.eq_ignore_ascii_case("close-quote") {
- content.push(ContentItem::CloseQuote)
- } else if ident.eq_ignore_ascii_case("no-open-quote") {
- content.push(ContentItem::NoOpenQuote)
- } else if ident.eq_ignore_ascii_case("no-close-quote") {
- content.push(ContentItem::NoCloseQuote)
- } else {
- return Err(())
+ }
+ }
+ #[inline]
+ pub fn get_initial_value() -> computed_value::T {
+ computed_value::T::normal
+ }
+
+ // normal | none | [ <string> ]+
+ // TODO: <uri>, <counter>, attr(<identifier>), open-quote, close-quote, no-open-quote, no-close-quote
+ pub fn parse(_context: &ParserContext, input: &mut Parser)
+ -> Result<SpecifiedValue, ()> {
+ if input.try(|input| input.expect_ident_matching("normal")).is_ok() {
+ return Ok(SpecifiedValue::normal)
+ }
+ if input.try(|input| input.expect_ident_matching("none")).is_ok() {
+ return Ok(SpecifiedValue::none)
+ }
+ let mut content = vec![];
+ loop {
+ match input.next() {
+ Ok(Token::QuotedString(value)) => {
+ content.push(ContentItem::StringContent(value.into_owned()))
}
- }
- Err(()) if !content.is_empty() => {
- let mut result = String::new();
- for content in content.iter() {
- content.to_css(&mut result).unwrap()
+ Err(()) if !content.is_empty() => {
+ return Ok(SpecifiedValue::Content(content))
}
- return Ok(SpecifiedValue::Content(content))
+ _ => return Err(())
}
- _ => return Err(())
}
}
- }
</%self:longhand>
${new_style_struct("List", is_inherited=True)}
@@ -1001,12 +846,14 @@ pub mod longhands {
// TODO(pcwalton): Implement the full set of counter styles per CSS-COUNTER-STYLES [1] 6.1:
//
- // decimal-leading-zero, armenian, upper-armenian, lower-armenian, georgian, lower-roman,
- // upper-roman
+ // decimal, decimal-leading-zero, arabic-indic, armenian, upper-armenian, lower-armenian,
+ // bengali, cambodian, khmer, cjk-decimal, devanagiri, georgian, gujarati, gurmukhi,
+ // hebrew, kannada, lao, malayalam, mongolian, myanmar, oriya, persian, lower-roman,
+ // upper-roman, telugu, thai, tibetan
//
// [1]: http://dev.w3.org/csswg/css-counter-styles/
${single_keyword("list-style-type",
- "disc none circle square decimal arabic-indic bengali cambodian cjk-decimal devanagari gujarati gurmukhi kannada khmer lao malayalam mongolian myanmar oriya persian telugu thai tibetan lower-alpha upper-alpha cjk-earthly-branch cjk-heavenly-stem lower-greek hiragana hiragana-iroha katakana katakana-iroha disclosure-open disclosure-closed")}
+ "disc none circle square disclosure-open disclosure-closed")}
<%self:longhand name="list-style-image">
use std::borrow::IntoCow;
@@ -1062,144 +909,6 @@ pub mod longhands {
}
</%self:longhand>
- <%self:longhand name="quotes">
- use cssparser::{ToCss, Token};
- use text_writer::{self, TextWriter};
- use values::computed::{ToComputedValue, Context};
-
- pub use self::computed_value::T as SpecifiedValue;
-
- pub mod computed_value {
- #[derive(Clone, PartialEq)]
- pub struct T(pub Vec<(String,String)>);
- }
-
- impl ToComputedValue for SpecifiedValue {
- type ComputedValue = computed_value::T;
-
- fn to_computed_value(&self, _: &Context) -> computed_value::T {
- (*self).clone()
- }
- }
-
- impl ToCss for SpecifiedValue {
- fn to_css<W>(&self, dest: &mut W) -> text_writer::Result where W: TextWriter {
- // TODO(pcwalton)
- dest.write_str("")
- }
- }
-
- #[inline]
- pub fn get_initial_value() -> computed_value::T {
- computed_value::T(vec![
- ("\u{201c}".to_string(), "\u{201d}".to_string()),
- ("\u{2018}".to_string(), "\u{2019}".to_string()),
- ])
- }
-
- pub fn parse(_: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue,()> {
- if input.try(|input| input.expect_ident_matching("none")).is_ok() {
- return Ok(SpecifiedValue(Vec::new()))
- }
-
- let mut quotes = Vec::new();
- loop {
- let first = match input.next() {
- Ok(Token::QuotedString(value)) => value.into_owned(),
- Ok(_) => return Err(()),
- Err(()) => break,
- };
- let second = match input.next() {
- Ok(Token::QuotedString(value)) => value.into_owned(),
- _ => return Err(()),
- };
- quotes.push((first, second))
- }
- if !quotes.is_empty() {
- Ok(SpecifiedValue(quotes))
- } else {
- Err(())
- }
- }
- </%self:longhand>
-
- ${new_style_struct("Counters", is_inherited=False)}
-
- <%self:longhand name="counter-increment">
- use cssparser::{NumericValue, ToCss, Token};
- use super::content;
- use text_writer::{self, TextWriter};
- use values::computed::{ToComputedValue, Context};
-
- use std::borrow::ToOwned;
-
- pub use self::computed_value::T as SpecifiedValue;
-
- pub mod computed_value {
- #[derive(Clone, PartialEq)]
- pub struct T(pub Vec<(String,i32)>);
- }
-
- #[inline]
- pub fn get_initial_value() -> computed_value::T {
- computed_value::T(Vec::new())
- }
-
- impl ToComputedValue for SpecifiedValue {
- type ComputedValue = computed_value::T;
-
- fn to_computed_value(&self, _: &Context) -> computed_value::T {
- (*self).clone()
- }
- }
-
- impl ToCss for SpecifiedValue {
- fn to_css<W>(&self, dest: &mut W) -> text_writer::Result where W: TextWriter {
- // TODO(pcwalton)
- dest.write_str("")
- }
- }
-
- pub fn parse(_: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue,()> {
- if input.try(|input| input.expect_ident_matching("none")).is_ok() {
- return Ok(SpecifiedValue(Vec::new()))
- }
-
- let mut counters = Vec::new();
- loop {
- let counter_name = match input.next() {
- Ok(Token::Ident(ident)) => (*ident).to_owned(),
- Ok(_) => return Err(()),
- Err(_) => break,
- };
- if content::counter_name_is_illegal(counter_name.as_slice()) {
- return Err(())
- }
- let counter_delta = input.try(|input| {
- match input.next() {
- Ok(Token::Number(NumericValue {
- int_value: Some(int_value),
- ..
- })) => Ok(int_value as i32),
- _ => Err(()),
- }
- }).unwrap_or(1);
- counters.push((counter_name, counter_delta))
- }
-
- if !counters.is_empty() {
- Ok(SpecifiedValue(counters))
- } else {
- Err(())
- }
- }
- </%self:longhand>
-
- <%self:longhand name="counter-reset">
- pub use super::counter_increment::{SpecifiedValue, computed_value, get_initial_value};
- pub use super::counter_increment::{parse};
- </%self:longhand>
-
// CSS 2.1, Section 13 - Paged media
// CSS 2.1, Section 14 - Colors and Backgrounds
diff --git a/components/util/time.rs b/components/util/time.rs
index c9cf32c0617..46de5abbceb 100644
--- a/components/util/time.rs
+++ b/components/util/time.rs
@@ -81,7 +81,6 @@ pub enum TimeProfilerCategory {
LayoutSelectorMatch,
LayoutTreeBuilder,
LayoutDamagePropagate,
- LayoutGeneratedContent,
LayoutMain,
LayoutParallelWarmup,
LayoutShaping,
@@ -100,7 +99,6 @@ impl Formatable for TimeProfilerCategory {
TimeProfilerCategory::LayoutStyleRecalc |
TimeProfilerCategory::LayoutRestyleDamagePropagation |
TimeProfilerCategory::LayoutNonIncrementalReset |
- TimeProfilerCategory::LayoutGeneratedContent |
TimeProfilerCategory::LayoutMain |
TimeProfilerCategory::LayoutDispListBuild |
TimeProfilerCategory::LayoutShaping |
@@ -121,7 +119,6 @@ impl Formatable for TimeProfilerCategory {
TimeProfilerCategory::LayoutSelectorMatch => "Selector Matching",
TimeProfilerCategory::LayoutTreeBuilder => "Tree Building",
TimeProfilerCategory::LayoutDamagePropagate => "Damage Propagation",
- TimeProfilerCategory::LayoutGeneratedContent => "Generated Content Resolution",
TimeProfilerCategory::LayoutMain => "Primary Layout Pass",
TimeProfilerCategory::LayoutParallelWarmup => "Parallel Warmup",
TimeProfilerCategory::LayoutShaping => "Shaping",