Update rustc to revision 3dcd2157403163789aaf21a9ab3c4d30a7c6494d.

This commit is contained in:
Ms2ger 2014-12-17 10:42:52 +01:00 committed by Josh Matthews
parent b8900782b0
commit 466faac2a5
223 changed files with 4414 additions and 4105 deletions

View file

@ -31,9 +31,9 @@ use construct::FlowConstructor;
use context::LayoutContext;
use css::node_style::StyledNode;
use display_list_builder::{BlockFlowDisplayListBuilding, FragmentDisplayListBuilding};
use floats::{ClearBoth, ClearLeft, ClearRight, FloatKind, FloatLeft, Floats, PlacementInfo};
use flow::{AbsolutePositionInfo, BaseFlow, BlockFlowClass, FloatIfNecessary, FlowClass, Flow};
use flow::{ForceNonfloated, ImmutableFlowUtils, MutableFlowUtils, PreorderFlowTraversal};
use floats::{ClearType, FloatKind, Floats, PlacementInfo};
use flow::{AbsolutePositionInfo, BaseFlow, ForceNonfloatedFlag, FlowClass, Flow};
use flow::{ImmutableFlowUtils, MutableFlowUtils, PreorderFlowTraversal};
use flow::{PostorderFlowTraversal, mut_base};
use flow::{HAS_LEFT_FLOATED_DESCENDANTS, HAS_RIGHT_FLOATED_DESCENDANTS};
use flow::{IMPACTED_BY_LEFT_FLOATS, IMPACTED_BY_RIGHT_FLOATS};
@ -41,12 +41,11 @@ use flow::{LAYERS_NEEDED_FOR_DESCENDANTS, NEEDS_LAYER};
use flow::{IS_ABSOLUTELY_POSITIONED};
use flow::{CLEARS_LEFT, CLEARS_RIGHT};
use flow;
use fragment::{Fragment, ImageFragment, InlineBlockFragment, FragmentBoundsIterator};
use fragment::ScannedTextFragment;
use fragment::{Fragment, FragmentBoundsIterator, SpecificFragmentInfo};
use incremental::{REFLOW, REFLOW_OUT_OF_FLOW};
use layout_debug;
use model::{Auto, IntrinsicISizes, MarginCollapseInfo, MarginsCollapse, MarginsCollapseThrough};
use model::{MaybeAuto, NoCollapsibleMargins, Specified, specified, specified_or_none};
use model::{IntrinsicISizes, MarginCollapseInfo};
use model::{MaybeAuto, CollapsibleMargins, specified, specified_or_none};
use table::ColumnComputedInlineSize;
use wrapper::ThreadSafeLayoutNode;
@ -60,8 +59,8 @@ use servo_util::opts;
use std::cmp::{max, min};
use std::fmt;
use style::ComputedValues;
use style::computed_values::{LPA_Auto, LPA_Length, LPA_Percentage, LPN_Length, LPN_None};
use style::computed_values::{LPN_Percentage, LP_Length, LP_Percentage, box_sizing, display, float};
use style::computed_values::{LengthOrPercentageOrAuto, LengthOrPercentageOrNone};
use style::computed_values::{LengthOrPercentage, box_sizing, display, float};
use style::computed_values::{overflow, position};
use sync::Arc;
@ -138,7 +137,7 @@ impl BSizeConstraintSolution {
let static_position_block_start = static_b_offset;
let (block_start, block_end, block_size, margin_block_start, margin_block_end) = match (block_start, block_end, block_size) {
(Auto, Auto, Auto) => {
(MaybeAuto::Auto, MaybeAuto::Auto, MaybeAuto::Auto) => {
let margin_block_start = block_start_margin.specified_or_zero();
let margin_block_end = block_end_margin.specified_or_zero();
let block_start = static_position_block_start;
@ -149,23 +148,23 @@ impl BSizeConstraintSolution {
let sum = block_start + block_size + margin_block_start + margin_block_end;
(block_start, available_block_size - sum, block_size, margin_block_start, margin_block_end)
}
(Specified(block_start), Specified(block_end), Specified(block_size)) => {
(MaybeAuto::Specified(block_start), MaybeAuto::Specified(block_end), MaybeAuto::Specified(block_size)) => {
match (block_start_margin, block_end_margin) {
(Auto, Auto) => {
(MaybeAuto::Auto, MaybeAuto::Auto) => {
let total_margin_val = available_block_size - block_start - block_end - block_size;
(block_start, block_end, block_size,
total_margin_val.scale_by(0.5),
total_margin_val.scale_by(0.5))
}
(Specified(margin_block_start), Auto) => {
(MaybeAuto::Specified(margin_block_start), MaybeAuto::Auto) => {
let sum = block_start + block_end + block_size + margin_block_start;
(block_start, block_end, block_size, margin_block_start, available_block_size - sum)
}
(Auto, Specified(margin_block_end)) => {
(MaybeAuto::Auto, MaybeAuto::Specified(margin_block_end)) => {
let sum = block_start + block_end + block_size + margin_block_end;
(block_start, block_end, block_size, available_block_size - sum, margin_block_end)
}
(Specified(margin_block_start), Specified(margin_block_end)) => {
(MaybeAuto::Specified(margin_block_start), MaybeAuto::Specified(margin_block_end)) => {
// Values are over-constrained. Ignore value for 'block-end'.
let sum = block_start + block_size + margin_block_start + margin_block_end;
(block_start, available_block_size - sum, block_size, margin_block_start, margin_block_end)
@ -176,19 +175,19 @@ impl BSizeConstraintSolution {
// For the rest of the cases, auto values for margin are set to 0
// If only one is Auto, solve for it
(Auto, Specified(block_end), Specified(block_size)) => {
(MaybeAuto::Auto, MaybeAuto::Specified(block_end), MaybeAuto::Specified(block_size)) => {
let margin_block_start = block_start_margin.specified_or_zero();
let margin_block_end = block_end_margin.specified_or_zero();
let sum = block_end + block_size + margin_block_start + margin_block_end;
(available_block_size - sum, block_end, block_size, margin_block_start, margin_block_end)
}
(Specified(block_start), Auto, Specified(block_size)) => {
(MaybeAuto::Specified(block_start), MaybeAuto::Auto, MaybeAuto::Specified(block_size)) => {
let margin_block_start = block_start_margin.specified_or_zero();
let margin_block_end = block_end_margin.specified_or_zero();
let sum = block_start + block_size + margin_block_start + margin_block_end;
(block_start, available_block_size - sum, block_size, margin_block_start, margin_block_end)
}
(Specified(block_start), Specified(block_end), Auto) => {
(MaybeAuto::Specified(block_start), MaybeAuto::Specified(block_end), MaybeAuto::Auto) => {
let margin_block_start = block_start_margin.specified_or_zero();
let margin_block_end = block_end_margin.specified_or_zero();
let sum = block_start + block_end + margin_block_start + margin_block_end;
@ -197,14 +196,14 @@ impl BSizeConstraintSolution {
// If block-size is auto, then block-size is content block-size. Solve for the
// non-auto value.
(Specified(block_start), Auto, Auto) => {
(MaybeAuto::Specified(block_start), MaybeAuto::Auto, MaybeAuto::Auto) => {
let margin_block_start = block_start_margin.specified_or_zero();
let margin_block_end = block_end_margin.specified_or_zero();
let block_size = content_block_size;
let sum = block_start + block_size + margin_block_start + margin_block_end;
(block_start, available_block_size - sum, block_size, margin_block_start, margin_block_end)
}
(Auto, Specified(block_end), Auto) => {
(MaybeAuto::Auto, MaybeAuto::Specified(block_end), MaybeAuto::Auto) => {
let margin_block_start = block_start_margin.specified_or_zero();
let margin_block_end = block_end_margin.specified_or_zero();
let block_size = content_block_size;
@ -212,7 +211,7 @@ impl BSizeConstraintSolution {
(available_block_size - sum, block_end, block_size, margin_block_start, margin_block_end)
}
(Auto, Auto, Specified(block_size)) => {
(MaybeAuto::Auto, MaybeAuto::Auto, MaybeAuto::Specified(block_size)) => {
let margin_block_start = block_start_margin.specified_or_zero();
let margin_block_end = block_end_margin.specified_or_zero();
let block_start = static_position_block_start;
@ -249,30 +248,30 @@ impl BSizeConstraintSolution {
let static_position_block_start = static_b_offset;
let (block_start, block_end, block_size, margin_block_start, margin_block_end) = match (block_start, block_end) {
(Auto, Auto) => {
(MaybeAuto::Auto, MaybeAuto::Auto) => {
let margin_block_start = block_start_margin.specified_or_zero();
let margin_block_end = block_end_margin.specified_or_zero();
let block_start = static_position_block_start;
let sum = block_start + block_size + margin_block_start + margin_block_end;
(block_start, available_block_size - sum, block_size, margin_block_start, margin_block_end)
}
(Specified(block_start), Specified(block_end)) => {
(MaybeAuto::Specified(block_start), MaybeAuto::Specified(block_end)) => {
match (block_start_margin, block_end_margin) {
(Auto, Auto) => {
(MaybeAuto::Auto, MaybeAuto::Auto) => {
let total_margin_val = available_block_size - block_start - block_end - block_size;
(block_start, block_end, block_size,
total_margin_val.scale_by(0.5),
total_margin_val.scale_by(0.5))
}
(Specified(margin_block_start), Auto) => {
(MaybeAuto::Specified(margin_block_start), MaybeAuto::Auto) => {
let sum = block_start + block_end + block_size + margin_block_start;
(block_start, block_end, block_size, margin_block_start, available_block_size - sum)
}
(Auto, Specified(margin_block_end)) => {
(MaybeAuto::Auto, MaybeAuto::Specified(margin_block_end)) => {
let sum = block_start + block_end + block_size + margin_block_end;
(block_start, block_end, block_size, available_block_size - sum, margin_block_end)
}
(Specified(margin_block_start), Specified(margin_block_end)) => {
(MaybeAuto::Specified(margin_block_start), MaybeAuto::Specified(margin_block_end)) => {
// Values are over-constrained. Ignore value for 'block-end'.
let sum = block_start + block_size + margin_block_start + margin_block_end;
(block_start, available_block_size - sum, block_size, margin_block_start, margin_block_end)
@ -281,13 +280,13 @@ impl BSizeConstraintSolution {
}
// If only one is Auto, solve for it
(Auto, Specified(block_end)) => {
(MaybeAuto::Auto, MaybeAuto::Specified(block_end)) => {
let margin_block_start = block_start_margin.specified_or_zero();
let margin_block_end = block_end_margin.specified_or_zero();
let sum = block_end + block_size + margin_block_start + margin_block_end;
(available_block_size - sum, block_end, block_size, margin_block_start, margin_block_end)
}
(Specified(block_start), Auto) => {
(MaybeAuto::Specified(block_start), MaybeAuto::Auto) => {
let margin_block_start = block_start_margin.specified_or_zero();
let margin_block_end = block_end_margin.specified_or_zero();
let sum = block_start + block_size + margin_block_start + margin_block_end;
@ -325,25 +324,26 @@ impl CandidateBSizeIterator {
// `min-height` and `max-height`, percentage values are ignored.
let block_size = match (fragment.style.content_block_size(), block_container_block_size) {
(LPA_Percentage(percent), Some(block_container_block_size)) => {
Specified(block_container_block_size.scale_by(percent))
(LengthOrPercentageOrAuto::Percentage(percent), Some(block_container_block_size)) => {
MaybeAuto::Specified(block_container_block_size.scale_by(percent))
}
(LPA_Percentage(_), None) | (LPA_Auto, _) => Auto,
(LPA_Length(length), _) => Specified(length),
(LengthOrPercentageOrAuto::Percentage(_), None) | (LengthOrPercentageOrAuto::Auto, _) => MaybeAuto::Auto,
(LengthOrPercentageOrAuto::Length(length), _) => MaybeAuto::Specified(length),
};
let max_block_size = match (fragment.style.max_block_size(), block_container_block_size) {
(LPN_Percentage(percent), Some(block_container_block_size)) => {
(LengthOrPercentageOrNone::Percentage(percent), Some(block_container_block_size)) => {
Some(block_container_block_size.scale_by(percent))
}
(LPN_Percentage(_), None) | (LPN_None, _) => None,
(LPN_Length(length), _) => Some(length),
(LengthOrPercentageOrNone::Percentage(_), None) |
(LengthOrPercentageOrNone::None, _) => None,
(LengthOrPercentageOrNone::Length(length), _) => Some(length),
};
let min_block_size = match (fragment.style.min_block_size(), block_container_block_size) {
(LP_Percentage(percent), Some(block_container_block_size)) => {
(LengthOrPercentage::Percentage(percent), Some(block_container_block_size)) => {
block_container_block_size.scale_by(percent)
}
(LP_Percentage(_), None) => Au(0),
(LP_Length(length), _) => length,
(LengthOrPercentage::Percentage(_), None) => Au(0),
(LengthOrPercentage::Length(length), _) => length,
};
// If the style includes `box-sizing: border-box`, subtract the border and padding.
@ -357,7 +357,7 @@ impl CandidateBSizeIterator {
max_block_size: max_block_size.map(|size| adjust(size, adjustment_for_box_sizing)),
min_block_size: adjust(min_block_size, adjustment_for_box_sizing),
candidate_value: Au(0),
status: InitialCandidateBSizeStatus,
status: CandidateBSizeIteratorStatus::Initial,
};
fn adjust(size: Au, delta: Au) -> Au {
@ -369,48 +369,48 @@ impl CandidateBSizeIterator {
impl Iterator<MaybeAuto> for CandidateBSizeIterator {
fn next(&mut self) -> Option<MaybeAuto> {
self.status = match self.status {
InitialCandidateBSizeStatus => TryingBSizeCandidateBSizeStatus,
TryingBSizeCandidateBSizeStatus => {
CandidateBSizeIteratorStatus::Initial => CandidateBSizeIteratorStatus::Trying,
CandidateBSizeIteratorStatus::Trying => {
match self.max_block_size {
Some(max_block_size) if self.candidate_value > max_block_size => {
TryingMaxCandidateBSizeStatus
CandidateBSizeIteratorStatus::TryingMax
}
_ if self.candidate_value < self.min_block_size => TryingMinCandidateBSizeStatus,
_ => FoundCandidateBSizeStatus,
_ if self.candidate_value < self.min_block_size => CandidateBSizeIteratorStatus::TryingMin,
_ => CandidateBSizeIteratorStatus::Found,
}
}
TryingMaxCandidateBSizeStatus => {
CandidateBSizeIteratorStatus::TryingMax => {
if self.candidate_value < self.min_block_size {
TryingMinCandidateBSizeStatus
CandidateBSizeIteratorStatus::TryingMin
} else {
FoundCandidateBSizeStatus
CandidateBSizeIteratorStatus::Found
}
}
TryingMinCandidateBSizeStatus | FoundCandidateBSizeStatus => {
FoundCandidateBSizeStatus
CandidateBSizeIteratorStatus::TryingMin | CandidateBSizeIteratorStatus::Found => {
CandidateBSizeIteratorStatus::Found
}
};
match self.status {
TryingBSizeCandidateBSizeStatus => Some(self.block_size),
TryingMaxCandidateBSizeStatus => {
Some(Specified(self.max_block_size.unwrap()))
CandidateBSizeIteratorStatus::Trying => Some(self.block_size),
CandidateBSizeIteratorStatus::TryingMax => {
Some(MaybeAuto::Specified(self.max_block_size.unwrap()))
}
TryingMinCandidateBSizeStatus => {
Some(Specified(self.min_block_size))
CandidateBSizeIteratorStatus::TryingMin => {
Some(MaybeAuto::Specified(self.min_block_size))
}
FoundCandidateBSizeStatus => None,
InitialCandidateBSizeStatus => panic!(),
CandidateBSizeIteratorStatus::Found => None,
CandidateBSizeIteratorStatus::Initial => panic!(),
}
}
}
enum CandidateBSizeIteratorStatus {
InitialCandidateBSizeStatus,
TryingBSizeCandidateBSizeStatus,
TryingMaxCandidateBSizeStatus,
TryingMinCandidateBSizeStatus,
FoundCandidateBSizeStatus,
Initial,
Trying,
TryingMax,
TryingMin,
Found,
}
// A helper function used in block-size calculation.
@ -479,12 +479,12 @@ impl<'a> PostorderFlowTraversal for AbsoluteStoreOverflowTraversal<'a> {
}
pub enum BlockType {
BlockReplacedType,
BlockNonReplacedType,
AbsoluteReplacedType,
AbsoluteNonReplacedType,
FloatReplacedType,
FloatNonReplacedType,
Replaced,
NonReplaced,
AbsoluteReplaced,
AbsoluteNonReplaced,
FloatReplaced,
FloatNonReplaced,
}
#[deriving(Clone, PartialEq)]
@ -495,9 +495,9 @@ pub enum MarginsMayCollapseFlag {
#[deriving(PartialEq)]
enum FormattingContextType {
NonformattingContext,
BlockFormattingContext,
OtherFormattingContext,
None,
Block,
Other,
}
// Propagates the `layers_needed_for_descendants` flag appropriately from a child. This is called
@ -571,7 +571,7 @@ 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, ForceNonfloated),
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),
@ -585,7 +585,7 @@ impl BlockFlow {
pub fn from_node_and_fragment(node: &ThreadSafeLayoutNode, fragment: Fragment) -> BlockFlow {
let writing_mode = node.style().writing_mode;
BlockFlow {
base: BaseFlow::new(Some((*node).clone()), writing_mode, ForceNonfloated),
base: BaseFlow::new(Some((*node).clone()), writing_mode, ForceNonfloatedFlag::ForceNonfloated),
fragment: fragment,
static_b_offset: Au::new(0),
inline_size_of_preceding_left_floats: Au(0),
@ -602,7 +602,7 @@ impl BlockFlow {
-> BlockFlow {
let writing_mode = node.style().writing_mode;
BlockFlow {
base: BaseFlow::new(Some((*node).clone()), writing_mode, FloatIfNecessary),
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),
@ -619,7 +619,7 @@ impl BlockFlow {
-> BlockFlow {
let writing_mode = node.style().writing_mode;
BlockFlow {
base: BaseFlow::new(Some((*node).clone()), writing_mode, FloatIfNecessary),
base: BaseFlow::new(Some((*node).clone()), writing_mode, ForceNonfloatedFlag::FloatIfNecessary),
fragment: fragment,
static_b_offset: Au::new(0),
inline_size_of_preceding_left_floats: Au(0),
@ -637,21 +637,21 @@ impl BlockFlow {
pub fn block_type(&self) -> BlockType {
if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
if self.is_replaced_content() {
AbsoluteReplacedType
BlockType::AbsoluteReplaced
} else {
AbsoluteNonReplacedType
BlockType::AbsoluteNonReplaced
}
} else if self.base.flags.is_float() {
if self.is_replaced_content() {
FloatReplacedType
BlockType::FloatReplaced
} else {
FloatNonReplacedType
BlockType::FloatNonReplaced
}
} else {
if self.is_replaced_content() {
BlockReplacedType
BlockType::Replaced
} else {
BlockNonReplacedType
BlockType::NonReplaced
}
}
}
@ -662,27 +662,27 @@ impl BlockFlow {
containing_block_inline_size: Au) {
let block_type = self.block_type();
match block_type {
AbsoluteReplacedType => {
BlockType::AbsoluteReplaced => {
let inline_size_computer = AbsoluteReplaced;
inline_size_computer.compute_used_inline_size(self, ctx, containing_block_inline_size);
}
AbsoluteNonReplacedType => {
BlockType::AbsoluteNonReplaced => {
let inline_size_computer = AbsoluteNonReplaced;
inline_size_computer.compute_used_inline_size(self, ctx, containing_block_inline_size);
}
FloatReplacedType => {
BlockType::FloatReplaced => {
let inline_size_computer = FloatReplaced;
inline_size_computer.compute_used_inline_size(self, ctx, containing_block_inline_size);
}
FloatNonReplacedType => {
BlockType::FloatNonReplaced => {
let inline_size_computer = FloatNonReplaced;
inline_size_computer.compute_used_inline_size(self, ctx, containing_block_inline_size);
}
BlockReplacedType => {
BlockType::Replaced => {
let inline_size_computer = BlockReplaced;
inline_size_computer.compute_used_inline_size(self, ctx, containing_block_inline_size);
}
BlockNonReplacedType => {
BlockType::NonReplaced => {
let inline_size_computer = BlockNonReplaced;
inline_size_computer.compute_used_inline_size(self, ctx, containing_block_inline_size);
}
@ -767,7 +767,7 @@ impl BlockFlow {
/// and image fragments.
fn is_replaced_content(&self) -> bool {
match self.fragment.specific {
ScannedTextFragment(_) | ImageFragment(_) | InlineBlockFragment(_) => true,
SpecificFragmentInfo::ScannedText(_) | SpecificFragmentInfo::Image(_) | SpecificFragmentInfo::InlineBlock(_) => true,
_ => false,
}
}
@ -793,11 +793,11 @@ impl BlockFlow {
}
let (block_start_margin_value, block_end_margin_value) = match self.base.collapsible_margins {
MarginsCollapseThrough(_) => panic!("Margins unexpectedly collapsed through root flow."),
MarginsCollapse(block_start_margin, block_end_margin) => {
CollapsibleMargins::CollapseThrough(_) => panic!("Margins unexpectedly collapsed through root flow."),
CollapsibleMargins::Collapse(block_start_margin, block_end_margin) => {
(block_start_margin.collapse(), block_end_margin.collapse())
}
NoCollapsibleMargins(block_start, block_end) => (block_start, block_end),
CollapsibleMargins::None(block_start, block_end) => (block_start, block_end),
};
// Shift all kids down (or up, if margins are negative) if necessary.
@ -840,7 +840,7 @@ impl BlockFlow {
// Absolute positioning establishes a block formatting context. Don't propagate floats
// in or out. (But do propagate them between kids.)
if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) ||
margins_may_collapse != MarginsMayCollapse {
margins_may_collapse != MarginsMayCollapseFlag::MarginsMayCollapse {
self.base.floats = Floats::new(self.fragment.style.writing_mode);
}
@ -853,7 +853,7 @@ impl BlockFlow {
translate_including_floats(&mut cur_b, block_start_offset, &mut self.base.floats);
let can_collapse_block_start_margin_with_kids =
margins_may_collapse == MarginsMayCollapse &&
margins_may_collapse == MarginsMayCollapseFlag::MarginsMayCollapse &&
!self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) &&
self.fragment.border_padding.block_start == Au(0);
margin_collapse_info.initialize_block_start_margin(
@ -924,9 +924,9 @@ impl BlockFlow {
let clearance = match (flow::base(kid).flags.contains(CLEARS_LEFT),
flow::base(kid).flags.contains(CLEARS_RIGHT)) {
(false, false) => Au(0),
(true, false) => floats.clearance(ClearLeft),
(false, true) => floats.clearance(ClearRight),
(true, true) => floats.clearance(ClearBoth),
(true, false) => floats.clearance(ClearType::Left),
(false, true) => floats.clearance(ClearType::Right),
(true, true) => floats.clearance(ClearType::Both),
};
translate_including_floats(&mut cur_b, clearance, &mut floats);
@ -961,7 +961,7 @@ impl BlockFlow {
// Add in our block-end margin and compute our collapsible margins.
let can_collapse_block_end_margin_with_kids =
margins_may_collapse == MarginsMayCollapse &&
margins_may_collapse == MarginsMayCollapseFlag::MarginsMayCollapse &&
!self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) &&
self.fragment.border_padding.block_end == Au(0);
let (collapsible_margins, delta) =
@ -983,11 +983,11 @@ impl BlockFlow {
block_size = Au::max(screen_size.block, block_size)
}
if is_root || self.formatting_context_type() != NonformattingContext ||
if is_root || self.formatting_context_type() != FormattingContextType::None ||
self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
// The content block-size includes all the floats per CSS 2.1 § 10.6.7. The easiest
// way to handle this is to just treat it as clearance.
block_size = block_size + floats.clearance(ClearBoth);
block_size = block_size + floats.clearance(ClearType::Both);
}
if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
@ -1014,8 +1014,8 @@ impl BlockFlow {
Some(candidate_block_size) => {
candidate_block_size_iterator.candidate_value =
match candidate_block_size {
Auto => block_size,
Specified(value) => value
MaybeAuto::Auto => block_size,
MaybeAuto::Specified(value) => value
}
}
None => break,
@ -1069,7 +1069,7 @@ impl BlockFlow {
// Also don't remove the dirty bits if we're a block formatting context since our inline
// size has not yet been computed. (See `assign_inline_position_for_formatting_context()`.)
if (self.base.flags.is_float() ||
self.formatting_context_type() == NonformattingContext) &&
self.formatting_context_type() == FormattingContextType::None) &&
!self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
self.base.restyle_damage.remove(REFLOW_OUT_OF_FLOW | REFLOW);
}
@ -1147,12 +1147,12 @@ impl BlockFlow {
// calculated during assign-inline-size.
let margin = self.fragment.style().logical_margin();
let margin_block_start = match margin.block_start {
LPA_Auto => Auto,
_ => Specified(self.fragment.margin.block_start)
LengthOrPercentageOrAuto::Auto => MaybeAuto::Auto,
_ => MaybeAuto::Specified(self.fragment.margin.block_start)
};
let margin_block_end = match margin.block_end {
LPA_Auto => Auto,
_ => Specified(self.fragment.margin.block_end)
LengthOrPercentageOrAuto::Auto => MaybeAuto::Auto,
_ => MaybeAuto::Specified(self.fragment.margin.block_end)
};
let block_start;
@ -1292,7 +1292,7 @@ impl BlockFlow {
// direction.)
let mut inline_size_of_preceding_left_floats = Au(0);
let mut inline_size_of_preceding_right_floats = Au(0);
if self.formatting_context_type() == NonformattingContext {
if self.formatting_context_type() == FormattingContextType::None {
inline_size_of_preceding_left_floats = self.inline_size_of_preceding_left_floats;
inline_size_of_preceding_right_floats = self.inline_size_of_preceding_right_floats;
}
@ -1301,11 +1301,11 @@ impl BlockFlow {
let content_block_size = self.fragment.style().content_block_size();
let explicit_content_size = match (content_block_size,
self.base.block_container_explicit_block_size) {
(LPA_Percentage(percent), Some(container_size)) => {
(LengthOrPercentageOrAuto::Percentage(percent), Some(container_size)) => {
Some(container_size.scale_by(percent))
}
(LPA_Percentage(_), None) | (LPA_Auto, _) => None,
(LPA_Length(length), _) => Some(length),
(LengthOrPercentageOrAuto::Percentage(_), None) | (LengthOrPercentageOrAuto::Auto, _) => None,
(LengthOrPercentageOrAuto::Length(length), _) => Some(length),
};
// Calculate containing block inline size.
@ -1410,14 +1410,14 @@ impl BlockFlow {
fn formatting_context_type(&self) -> FormattingContextType {
let style = self.fragment.style();
if style.get_box().float != float::none {
return OtherFormattingContext
return FormattingContextType::Other
}
match style.get_box().display {
display::table_cell | display::table_caption | display::inline_block => {
OtherFormattingContext
FormattingContextType::Other
}
_ if style.get_box().overflow != overflow::visible => BlockFormattingContext,
_ => NonformattingContext,
_ if style.get_box().overflow != overflow::visible => FormattingContextType::Block,
_ => FormattingContextType::None,
}
}
@ -1435,7 +1435,7 @@ impl BlockFlow {
///
/// FIXME(pcwalton): This code is not incremental-reflow-safe (i.e. not idempotent).
fn assign_inline_position_for_formatting_context(&mut self) {
debug_assert!(self.formatting_context_type() != NonformattingContext);
debug_assert!(self.formatting_context_type() != FormattingContextType::None);
if !self.base.restyle_damage.intersects(REFLOW_OUT_OF_FLOW | REFLOW) {
return
@ -1449,7 +1449,7 @@ impl BlockFlow {
self.fragment.border_box.size.block),
ceiling: self.base.position.start.b,
max_inline_size: MAX_AU,
kind: FloatLeft,
kind: FloatKind::Left,
};
// Offset our position by whatever displacement is needed to not impact the floats.
@ -1482,7 +1482,7 @@ impl BlockFlow {
impl Flow for BlockFlow {
fn class(&self) -> FlowClass {
BlockFlowClass
FlowClass::Block
}
fn as_block<'a>(&'a mut self) -> &'a mut BlockFlow {
@ -1510,7 +1510,7 @@ impl Flow for BlockFlow {
// and preferred width, rather than bubbling up children inline
// width.
let fixed_width = match self.fragment.style().get_box().width {
LPA_Length(_) => true,
LengthOrPercentageOrAuto::Length(_) => true,
_ => false,
};
@ -1602,8 +1602,8 @@ impl Flow for BlockFlow {
// Formatting contexts are never impacted by floats.
match self.formatting_context_type() {
NonformattingContext => {}
BlockFormattingContext => {
FormattingContextType::None => {}
FormattingContextType::Block => {
self.base.flags.remove(IMPACTED_BY_LEFT_FLOATS);
self.base.flags.remove(IMPACTED_BY_RIGHT_FLOATS);
@ -1615,7 +1615,7 @@ impl Flow for BlockFlow {
self.inline_size_of_preceding_left_floats -
self.inline_size_of_preceding_right_floats;
}
OtherFormattingContext => {
FormattingContextType::Other => {
self.base.flags.remove(IMPACTED_BY_LEFT_FLOATS);
self.base.flags.remove(IMPACTED_BY_RIGHT_FLOATS);
}
@ -1646,7 +1646,7 @@ impl Flow for BlockFlow {
return false
}
let is_formatting_context = self.formatting_context_type() != NonformattingContext;
let is_formatting_context = self.formatting_context_type() != FormattingContextType::None;
if !self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) && is_formatting_context {
self.assign_inline_position_for_formatting_context();
}
@ -1687,10 +1687,10 @@ impl Flow for BlockFlow {
} else if self.is_root() || self.base.flags.is_float() || self.is_inline_block() {
// Root element margins should never be collapsed according to CSS § 8.3.1.
debug!("assign_block_size: assigning block_size for root flow");
self.assign_block_size_block_base(ctx, MarginsMayNotCollapse);
self.assign_block_size_block_base(ctx, MarginsMayCollapseFlag::MarginsMayNotCollapse);
} else {
debug!("assign_block_size: assigning block_size for block");
self.assign_block_size_block_base(ctx, MarginsMayCollapse);
self.assign_block_size_block_base(ctx, MarginsMayCollapseFlag::MarginsMayCollapse);
}
}
@ -1839,16 +1839,16 @@ impl Flow for BlockFlow {
fn update_late_computed_inline_position_if_necessary(&mut self, inline_position: Au) {
if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) &&
self.fragment.style().logical_position().inline_start == LPA_Auto &&
self.fragment.style().logical_position().inline_end == LPA_Auto {
self.fragment.style().logical_position().inline_start == LengthOrPercentageOrAuto::Auto &&
self.fragment.style().logical_position().inline_end == LengthOrPercentageOrAuto::Auto {
self.base.position.start.i = inline_position
}
}
fn update_late_computed_block_position_if_necessary(&mut self, block_position: Au) {
if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) &&
self.fragment.style().logical_position().block_start == LPA_Auto &&
self.fragment.style().logical_position().block_end == LPA_Auto {
self.fragment.style().logical_position().block_start == LengthOrPercentageOrAuto::Auto &&
self.fragment.style().logical_position().block_end == LengthOrPercentageOrAuto::Auto {
self.base.position.start.b = block_position
}
}
@ -1976,11 +1976,11 @@ pub trait ISizeAndMarginsComputer {
let style = block.fragment.style();
match (computed_inline_size, style.get_box().box_sizing) {
(Specified(size), box_sizing::border_box) => {
(MaybeAuto::Specified(size), box_sizing::border_box) => {
computed_inline_size =
Specified(size - block.fragment.border_padding.inline_start_end())
MaybeAuto::Specified(size - block.fragment.border_padding.inline_start_end())
}
(Auto, box_sizing::border_box) | (_, box_sizing::content_box) => {}
(MaybeAuto::Auto, box_sizing::border_box) | (_, box_sizing::content_box) => {}
}
// The text alignment of a block flow is the text alignment of its box's style.
@ -2090,7 +2090,7 @@ pub trait ISizeAndMarginsComputer {
match specified_or_none(block.fragment().style().max_inline_size(),
containing_block_inline_size) {
Some(max_inline_size) if max_inline_size < solution.inline_size => {
input.computed_inline_size = Specified(max_inline_size);
input.computed_inline_size = MaybeAuto::Specified(max_inline_size);
solution = self.solve_inline_size_constraints(block, &input);
}
_ => {}
@ -2102,7 +2102,7 @@ pub trait ISizeAndMarginsComputer {
let computed_min_inline_size = specified(block.fragment().style().min_inline_size(),
containing_block_inline_size);
if computed_min_inline_size > solution.inline_size {
input.computed_inline_size = Specified(computed_min_inline_size);
input.computed_inline_size = MaybeAuto::Specified(computed_min_inline_size);
solution = self.solve_inline_size_constraints(block, &input);
}
@ -2131,13 +2131,13 @@ pub trait ISizeAndMarginsComputer {
// If inline-size is not 'auto', and inline-size + margins > available_inline-size, all
// 'auto' margins are treated as 0.
let (inline_start_margin, inline_end_margin) = match computed_inline_size {
Auto => (inline_start_margin, inline_end_margin),
Specified(inline_size) => {
MaybeAuto::Auto => (inline_start_margin, inline_end_margin),
MaybeAuto::Specified(inline_size) => {
let inline_start = inline_start_margin.specified_or_zero();
let inline_end = inline_end_margin.specified_or_zero();
if (inline_start + inline_end + inline_size) > available_inline_size {
(Specified(inline_start), Specified(inline_end))
(MaybeAuto::Specified(inline_start), MaybeAuto::Specified(inline_end))
} else {
(inline_start_margin, inline_end_margin)
}
@ -2150,31 +2150,31 @@ pub trait ISizeAndMarginsComputer {
match (inline_start_margin, computed_inline_size, inline_end_margin) {
// If all have a computed value other than 'auto', the system is
// over-constrained so we discard the end margin.
(Specified(margin_start), Specified(inline_size), Specified(_margin_end)) =>
(MaybeAuto::Specified(margin_start), MaybeAuto::Specified(inline_size), MaybeAuto::Specified(_margin_end)) =>
(margin_start, inline_size, available_inline_size -
(margin_start + inline_size)),
// If exactly one value is 'auto', solve for it
(Auto, Specified(inline_size), Specified(margin_end)) =>
(MaybeAuto::Auto, MaybeAuto::Specified(inline_size), MaybeAuto::Specified(margin_end)) =>
(available_inline_size - (inline_size + margin_end), inline_size, margin_end),
(Specified(margin_start), Auto, Specified(margin_end)) =>
(MaybeAuto::Specified(margin_start), MaybeAuto::Auto, MaybeAuto::Specified(margin_end)) =>
(margin_start, available_inline_size - (margin_start + margin_end),
margin_end),
(Specified(margin_start), Specified(inline_size), Auto) =>
(MaybeAuto::Specified(margin_start), MaybeAuto::Specified(inline_size), MaybeAuto::Auto) =>
(margin_start, inline_size, available_inline_size -
(margin_start + inline_size)),
// If inline-size is set to 'auto', any other 'auto' value becomes '0',
// and inline-size is solved for
(Auto, Auto, Specified(margin_end)) =>
(MaybeAuto::Auto, MaybeAuto::Auto, MaybeAuto::Specified(margin_end)) =>
(Au::new(0), available_inline_size - margin_end, margin_end),
(Specified(margin_start), Auto, Auto) =>
(MaybeAuto::Specified(margin_start), MaybeAuto::Auto, MaybeAuto::Auto) =>
(margin_start, available_inline_size - margin_start, Au::new(0)),
(Auto, Auto, Auto) =>
(MaybeAuto::Auto, MaybeAuto::Auto, MaybeAuto::Auto) =>
(Au::new(0), available_inline_size, Au::new(0)),
// If inline-start and inline-end margins are auto, they become equal
(Auto, Specified(inline_size), Auto) => {
(MaybeAuto::Auto, MaybeAuto::Specified(inline_size), MaybeAuto::Auto) => {
let margin = (available_inline_size - inline_size).scale_by(0.5);
(margin, inline_size, margin)
}
@ -2229,7 +2229,7 @@ impl ISizeAndMarginsComputer for AbsoluteNonReplaced {
let static_position_inline_start = static_i_offset;
let (inline_start, inline_end, inline_size, margin_inline_start, margin_inline_end) = match (inline_start, inline_end, computed_inline_size) {
(Auto, Auto, Auto) => {
(MaybeAuto::Auto, MaybeAuto::Auto, MaybeAuto::Auto) => {
let margin_start = inline_start_margin.specified_or_zero();
let margin_end = inline_end_margin.specified_or_zero();
let inline_start = static_position_inline_start;
@ -2242,9 +2242,9 @@ impl ISizeAndMarginsComputer for AbsoluteNonReplaced {
let sum = inline_start + inline_size + margin_start + margin_end;
(inline_start, available_inline_size - sum, inline_size, margin_start, margin_end)
}
(Specified(inline_start), Specified(inline_end), Specified(inline_size)) => {
(MaybeAuto::Specified(inline_start), MaybeAuto::Specified(inline_end), MaybeAuto::Specified(inline_size)) => {
match (inline_start_margin, inline_end_margin) {
(Auto, Auto) => {
(MaybeAuto::Auto, MaybeAuto::Auto) => {
let total_margin_val = available_inline_size - inline_start - inline_end - inline_size;
if total_margin_val < Au(0) {
// margin-inline-start becomes 0 because direction is 'ltr'.
@ -2257,15 +2257,15 @@ impl ISizeAndMarginsComputer for AbsoluteNonReplaced {
total_margin_val.scale_by(0.5))
}
}
(Specified(margin_start), Auto) => {
(MaybeAuto::Specified(margin_start), MaybeAuto::Auto) => {
let sum = inline_start + inline_end + inline_size + margin_start;
(inline_start, inline_end, inline_size, margin_start, available_inline_size - sum)
}
(Auto, Specified(margin_end)) => {
(MaybeAuto::Auto, MaybeAuto::Specified(margin_end)) => {
let sum = inline_start + inline_end + inline_size + margin_end;
(inline_start, inline_end, inline_size, available_inline_size - sum, margin_end)
}
(Specified(margin_start), Specified(margin_end)) => {
(MaybeAuto::Specified(margin_start), MaybeAuto::Specified(margin_end)) => {
// Values are over-constrained.
// Ignore value for 'inline-end' cos direction is 'ltr'.
// TODO: Handle 'rtl' when it is implemented.
@ -2277,19 +2277,19 @@ impl ISizeAndMarginsComputer for AbsoluteNonReplaced {
// For the rest of the cases, auto values for margin are set to 0
// If only one is Auto, solve for it
(Auto, Specified(inline_end), Specified(inline_size)) => {
(MaybeAuto::Auto, MaybeAuto::Specified(inline_end), MaybeAuto::Specified(inline_size)) => {
let margin_start = inline_start_margin.specified_or_zero();
let margin_end = inline_end_margin.specified_or_zero();
let sum = inline_end + inline_size + margin_start + margin_end;
(available_inline_size - sum, inline_end, inline_size, margin_start, margin_end)
}
(Specified(inline_start), Auto, Specified(inline_size)) => {
(MaybeAuto::Specified(inline_start), MaybeAuto::Auto, MaybeAuto::Specified(inline_size)) => {
let margin_start = inline_start_margin.specified_or_zero();
let margin_end = inline_end_margin.specified_or_zero();
let sum = inline_start + inline_size + margin_start + margin_end;
(inline_start, available_inline_size - sum, inline_size, margin_start, margin_end)
}
(Specified(inline_start), Specified(inline_end), Auto) => {
(MaybeAuto::Specified(inline_start), MaybeAuto::Specified(inline_end), MaybeAuto::Auto) => {
let margin_start = inline_start_margin.specified_or_zero();
let margin_end = inline_end_margin.specified_or_zero();
let sum = inline_start + inline_end + margin_start + margin_end;
@ -2298,7 +2298,7 @@ impl ISizeAndMarginsComputer for AbsoluteNonReplaced {
// If inline-size is auto, then inline-size is shrink-to-fit. Solve for the
// non-auto value.
(Specified(inline_start), Auto, Auto) => {
(MaybeAuto::Specified(inline_start), MaybeAuto::Auto, MaybeAuto::Auto) => {
let margin_start = inline_start_margin.specified_or_zero();
let margin_end = inline_end_margin.specified_or_zero();
// Set inline-end to zero to calculate inline-size
@ -2307,7 +2307,7 @@ impl ISizeAndMarginsComputer for AbsoluteNonReplaced {
let sum = inline_start + inline_size + margin_start + margin_end;
(inline_start, available_inline_size - sum, inline_size, margin_start, margin_end)
}
(Auto, Specified(inline_end), Auto) => {
(MaybeAuto::Auto, MaybeAuto::Specified(inline_end), MaybeAuto::Auto) => {
let margin_start = inline_start_margin.specified_or_zero();
let margin_end = inline_end_margin.specified_or_zero();
// Set inline-start to zero to calculate inline-size
@ -2317,7 +2317,7 @@ impl ISizeAndMarginsComputer for AbsoluteNonReplaced {
(available_inline_size - sum, inline_end, inline_size, margin_start, margin_end)
}
(Auto, Auto, Specified(inline_size)) => {
(MaybeAuto::Auto, MaybeAuto::Auto, MaybeAuto::Specified(inline_size)) => {
let margin_start = inline_start_margin.specified_or_zero();
let margin_end = inline_end_margin.specified_or_zero();
// Setting 'inline-start' to static position because direction is 'ltr'.
@ -2374,7 +2374,7 @@ impl ISizeAndMarginsComputer for AbsoluteReplaced {
// TODO: Handle all the cases for 'rtl' direction.
let inline_size = match computed_inline_size {
Specified(w) => w,
MaybeAuto::Specified(w) => w,
_ => panic!("{} {}",
"The used value for inline_size for absolute replaced flow",
"should have already been calculated by now.")
@ -2386,7 +2386,7 @@ impl ISizeAndMarginsComputer for AbsoluteReplaced {
let static_position_inline_start = static_i_offset;
let (inline_start, inline_end, inline_size, margin_inline_start, margin_inline_end) = match (inline_start, inline_end) {
(Auto, Auto) => {
(MaybeAuto::Auto, MaybeAuto::Auto) => {
let inline_start = static_position_inline_start;
let margin_start = inline_start_margin.specified_or_zero();
let margin_end = inline_end_margin.specified_or_zero();
@ -2394,21 +2394,21 @@ impl ISizeAndMarginsComputer for AbsoluteReplaced {
(inline_start, available_inline_size - sum, inline_size, margin_start, margin_end)
}
// If only one is Auto, solve for it
(Auto, Specified(inline_end)) => {
(MaybeAuto::Auto, MaybeAuto::Specified(inline_end)) => {
let margin_start = inline_start_margin.specified_or_zero();
let margin_end = inline_end_margin.specified_or_zero();
let sum = inline_end + inline_size + margin_start + margin_end;
(available_inline_size - sum, inline_end, inline_size, margin_start, margin_end)
}
(Specified(inline_start), Auto) => {
(MaybeAuto::Specified(inline_start), MaybeAuto::Auto) => {
let margin_start = inline_start_margin.specified_or_zero();
let margin_end = inline_end_margin.specified_or_zero();
let sum = inline_start + inline_size + margin_start + margin_end;
(inline_start, available_inline_size - sum, inline_size, margin_start, margin_end)
}
(Specified(inline_start), Specified(inline_end)) => {
(MaybeAuto::Specified(inline_start), MaybeAuto::Specified(inline_end)) => {
match (inline_start_margin, inline_end_margin) {
(Auto, Auto) => {
(MaybeAuto::Auto, MaybeAuto::Auto) => {
let total_margin_val = available_inline_size - inline_start - inline_end - inline_size;
if total_margin_val < Au(0) {
// margin-inline-start becomes 0 because direction is 'ltr'.
@ -2420,15 +2420,15 @@ impl ISizeAndMarginsComputer for AbsoluteReplaced {
total_margin_val.scale_by(0.5))
}
}
(Specified(margin_start), Auto) => {
(MaybeAuto::Specified(margin_start), MaybeAuto::Auto) => {
let sum = inline_start + inline_end + inline_size + margin_start;
(inline_start, inline_end, inline_size, margin_start, available_inline_size - sum)
}
(Auto, Specified(margin_end)) => {
(MaybeAuto::Auto, MaybeAuto::Specified(margin_end)) => {
let sum = inline_start + inline_end + inline_size + margin_end;
(inline_start, inline_end, inline_size, available_inline_size - sum, margin_end)
}
(Specified(margin_start), Specified(margin_end)) => {
(MaybeAuto::Specified(margin_start), MaybeAuto::Specified(margin_end)) => {
// Values are over-constrained.
// Ignore value for 'inline-end' cos direction is 'ltr'.
let sum = inline_start + inline_size + margin_start + margin_end;
@ -2452,7 +2452,7 @@ impl ISizeAndMarginsComputer for AbsoluteReplaced {
fragment.assign_replaced_inline_size_if_necessary(containing_block_inline_size);
// For replaced absolute flow, the rest of the constraint solving will
// take inline-size to be specified as the value computed here.
Specified(fragment.content_inline_size())
MaybeAuto::Specified(fragment.content_inline_size())
}
fn containing_block_inline_size(&self, block: &mut BlockFlow, _: Au, ctx: &LayoutContext) -> Au {
@ -2485,8 +2485,8 @@ impl ISizeAndMarginsComputer for BlockReplaced {
input: &ISizeConstraintInput)
-> ISizeConstraintSolution {
match input.computed_inline_size {
Specified(_) => {},
Auto => panic!("BlockReplaced: inline_size should have been computed by now")
MaybeAuto::Specified(_) => {},
MaybeAuto::Auto => panic!("BlockReplaced: inline_size should have been computed by now")
};
self.solve_block_inline_size_constraints(block, input)
}
@ -2501,7 +2501,7 @@ impl ISizeAndMarginsComputer for BlockReplaced {
fragment.assign_replaced_inline_size_if_necessary(parent_flow_inline_size);
// For replaced block flow, the rest of the constraint solving will
// take inline-size to be specified as the value computed here.
Specified(fragment.content_inline_size())
MaybeAuto::Specified(fragment.content_inline_size())
}
}
@ -2540,8 +2540,8 @@ impl ISizeAndMarginsComputer for FloatReplaced {
let margin_inline_start = inline_start_margin.specified_or_zero();
let margin_inline_end = inline_end_margin.specified_or_zero();
let inline_size = match computed_inline_size {
Specified(w) => w,
Auto => panic!("FloatReplaced: inline_size should have been computed by now")
MaybeAuto::Specified(w) => w,
MaybeAuto::Auto => panic!("FloatReplaced: inline_size should have been computed by now")
};
debug!("assign_inline_sizes_float -- inline_size: {}", inline_size);
ISizeConstraintSolution::new(inline_size, margin_inline_start, margin_inline_end)
@ -2557,7 +2557,7 @@ impl ISizeAndMarginsComputer for FloatReplaced {
fragment.assign_replaced_inline_size_if_necessary(parent_flow_inline_size);
// For replaced block flow, the rest of the constraint solving will
// take inline-size to be specified as the value computed here.
Specified(fragment.content_inline_size())
MaybeAuto::Specified(fragment.content_inline_size())
}
}

View file

@ -22,12 +22,12 @@ use flow::{Descendants, AbsDescendants};
use flow::{IS_ABSOLUTELY_POSITIONED};
use flow;
use flow_ref::FlowRef;
use fragment::{Fragment, GenericFragment, IframeFragment, IframeFragmentInfo, ImageFragment};
use fragment::{ImageFragmentInfo, InlineAbsoluteHypotheticalFragment};
use fragment::{InlineAbsoluteHypotheticalFragmentInfo, InlineBlockFragment};
use fragment::{InlineBlockFragmentInfo, SpecificFragmentInfo, TableCellFragment};
use fragment::{TableColumnFragment, TableColumnFragmentInfo, TableFragment, TableRowFragment};
use fragment::{TableWrapperFragment, UnscannedTextFragment, UnscannedTextFragmentInfo};
use fragment::{Fragment, IframeFragmentInfo};
use fragment::ImageFragmentInfo;
use fragment::InlineAbsoluteHypotheticalFragmentInfo;
use fragment::{InlineBlockFragmentInfo, SpecificFragmentInfo};
use fragment::TableColumnFragmentInfo;
use fragment::UnscannedTextFragmentInfo;
use incremental::{RECONSTRUCT_FLOW, RestyleDamage};
use inline::InlineFlow;
use list_item::{mod, ListItemFlow};
@ -41,19 +41,11 @@ use table_row::TableRowFlow;
use table_cell::TableCellFlow;
use text::TextRunScanner;
use util::{HAS_NEWLY_CONSTRUCTED_FLOW, LayoutDataAccess, OpaqueNodeMethods, LayoutDataWrapper};
use wrapper::{PostorderNodeMutTraversal, TLayoutNode, ThreadSafeLayoutNode};
use wrapper::{Before, After, Normal};
use wrapper::{PostorderNodeMutTraversal, PseudoElementType, TLayoutNode, ThreadSafeLayoutNode};
use gfx::display_list::OpaqueNode;
use script::dom::element::{HTMLIFrameElementTypeId, HTMLImageElementTypeId};
use script::dom::element::{HTMLObjectElementTypeId, HTMLInputElementTypeId};
use script::dom::element::{HTMLTableColElementTypeId, HTMLTableDataCellElementTypeId};
use script::dom::element::{HTMLTableElementTypeId, HTMLTableHeaderCellElementTypeId};
use script::dom::element::{HTMLTableRowElementTypeId, HTMLTableSectionElementTypeId};
use script::dom::element::HTMLTextAreaElementTypeId;
use script::dom::node::{CommentNodeTypeId, DoctypeNodeTypeId, DocumentFragmentNodeTypeId};
use script::dom::node::{DocumentNodeTypeId, ElementNodeTypeId, ProcessingInstructionNodeTypeId};
use script::dom::node::{TextNodeTypeId};
use script::dom::element::ElementTypeId;
use script::dom::node::NodeTypeId;
use script::dom::htmlobjectelement::is_image_data;
use servo_util::opts;
use std::collections::DList;
@ -69,22 +61,22 @@ use url::Url;
pub enum ConstructionResult {
/// This node contributes nothing at all (`display: none`). Alternately, this is what newly
/// created nodes have their `ConstructionResult` set to.
NoConstructionResult,
None,
/// This node contributed a flow at the proper position in the tree.
/// Nothing more needs to be done for this node. It has bubbled up fixed
/// and absolute descendant flows that have a containing block above it.
FlowConstructionResult(FlowRef, AbsDescendants),
Flow(FlowRef, AbsDescendants),
/// This node contributed some object or objects that will be needed to construct a proper flow
/// later up the tree, but these objects have not yet found their home.
ConstructionItemConstructionResult(ConstructionItem),
ConstructionItem(ConstructionItem),
}
impl ConstructionResult {
pub fn swap_out(&mut self) -> ConstructionResult {
if opts::get().nonincremental_layout {
return mem::replace(self, NoConstructionResult)
return mem::replace(self, ConstructionResult::None)
}
(*self).clone()
@ -92,9 +84,9 @@ impl ConstructionResult {
pub fn debug_id(&self) -> uint {
match self {
&NoConstructionResult => 0u,
&ConstructionItemConstructionResult(_) => 0u,
&FlowConstructionResult(ref flow_ref, _) => flow::base(flow_ref.deref()).debug_id(),
&ConstructionResult::None => 0u,
&ConstructionResult::ConstructionItem(_) => 0u,
&ConstructionResult::Flow(ref flow_ref, _) => flow::base(flow_ref.deref()).debug_id(),
}
}
}
@ -105,11 +97,11 @@ impl ConstructionResult {
#[deriving(Clone)]
pub enum ConstructionItem {
/// Inline fragments and associated {ib} splits that have not yet found flows.
InlineFragmentsConstructionItem(InlineFragmentsConstructionResult),
InlineFragments(InlineFragmentsConstructionResult),
/// Potentially ignorable whitespace.
WhitespaceConstructionItem(OpaqueNode, Arc<ComputedValues>, RestyleDamage),
Whitespace(OpaqueNode, Arc<ComputedValues>, RestyleDamage),
/// TableColumn Fragment
TableColumnFragmentConstructionItem(Fragment),
TableColumnFragment(Fragment),
}
/// Represents inline fragments and {ib} splits that are bubbling up from an inline.
@ -139,7 +131,7 @@ pub struct InlineFragmentsConstructionResult {
/// The resulting `ConstructionItem` for the outer `span` will be:
///
/// ```ignore
/// InlineFragmentsConstructionItem(Some(~[
/// ConstructionItem::InlineFragments(Some(~[
/// InlineBlockSplit {
/// predecessor_fragments: ~[
/// A
@ -213,9 +205,9 @@ impl InlineFragmentsAccumulator {
}
enum WhitespaceStrippingMode {
NoWhitespaceStripping,
StripWhitespaceFromStart,
StripWhitespaceFromEnd,
None,
FromStart,
FromEnd,
}
/// An object that knows how to create flows.
@ -237,11 +229,11 @@ impl<'a> FlowConstructor<'a> {
fn build_fragment_info_for_image(&mut self, node: &ThreadSafeLayoutNode, url: Option<Url>)
-> SpecificFragmentInfo {
match url {
None => GenericFragment,
None => SpecificFragmentInfo::Generic,
Some(url) => {
// FIXME(pcwalton): The fact that image fragments store the cache within them makes
// little sense to me.
ImageFragment(box ImageFragmentInfo::new(node,
SpecificFragmentInfo::Image(box ImageFragmentInfo::new(node,
url,
self.layout_context
.shared
@ -260,28 +252,28 @@ impl<'a> FlowConstructor<'a> {
pub fn build_specific_fragment_info_for_node(&mut self, node: &ThreadSafeLayoutNode)
-> SpecificFragmentInfo {
match node.type_id() {
Some(ElementNodeTypeId(HTMLIFrameElementTypeId)) => {
IframeFragment(box IframeFragmentInfo::new(node))
Some(NodeTypeId::Element(ElementTypeId::HTMLIFrameElement)) => {
SpecificFragmentInfo::Iframe(box IframeFragmentInfo::new(node))
}
Some(ElementNodeTypeId(HTMLImageElementTypeId)) => {
Some(NodeTypeId::Element(ElementTypeId::HTMLImageElement)) => {
self.build_fragment_info_for_image(node, node.image_url())
}
Some(ElementNodeTypeId(HTMLObjectElementTypeId)) => {
Some(NodeTypeId::Element(ElementTypeId::HTMLObjectElement)) => {
let data = node.get_object_data();
self.build_fragment_info_for_image(node, data)
}
Some(ElementNodeTypeId(HTMLTableElementTypeId)) => TableWrapperFragment,
Some(ElementNodeTypeId(HTMLTableColElementTypeId)) => {
TableColumnFragment(TableColumnFragmentInfo::new(node))
Some(NodeTypeId::Element(ElementTypeId::HTMLTableElement)) => SpecificFragmentInfo::TableWrapper,
Some(NodeTypeId::Element(ElementTypeId::HTMLTableColElement)) => {
SpecificFragmentInfo::TableColumn(TableColumnFragmentInfo::new(node))
}
Some(ElementNodeTypeId(HTMLTableDataCellElementTypeId)) |
Some(ElementNodeTypeId(HTMLTableHeaderCellElementTypeId)) => TableCellFragment,
Some(ElementNodeTypeId(HTMLTableRowElementTypeId)) |
Some(ElementNodeTypeId(HTMLTableSectionElementTypeId)) => TableRowFragment,
Some(TextNodeTypeId) => UnscannedTextFragment(UnscannedTextFragmentInfo::new(node)),
Some(NodeTypeId::Element(ElementTypeId::HTMLTableDataCellElement)) |
Some(NodeTypeId::Element(ElementTypeId::HTMLTableHeaderCellElement)) => SpecificFragmentInfo::TableCell,
Some(NodeTypeId::Element(ElementTypeId::HTMLTableRowElement)) |
Some(NodeTypeId::Element(ElementTypeId::HTMLTableSectionElement)) => SpecificFragmentInfo::TableRow,
Some(NodeTypeId::Text) => SpecificFragmentInfo::UnscannedText(UnscannedTextFragmentInfo::new(node)),
_ => {
// This includes pseudo-elements.
GenericFragment
SpecificFragmentInfo::Generic
}
}
}
@ -304,14 +296,14 @@ impl<'a> FlowConstructor<'a> {
};
match whitespace_stripping {
NoWhitespaceStripping => {}
StripWhitespaceFromStart => {
WhitespaceStrippingMode::None => {}
WhitespaceStrippingMode::FromStart => {
strip_ignorable_whitespace_from_start(&mut fragments);
if fragments.is_empty() {
return
};
}
StripWhitespaceFromEnd => {
WhitespaceStrippingMode::FromEnd => {
strip_ignorable_whitespace_from_end(&mut fragments);
if fragments.is_empty() {
return
@ -323,8 +315,8 @@ impl<'a> FlowConstructor<'a> {
let mut inline_block_flows = vec!();
for f in fragments.iter() {
match f.specific {
InlineBlockFragment(ref info) => inline_block_flows.push(info.flow_ref.clone()),
InlineAbsoluteHypotheticalFragment(ref info) => {
SpecificFragmentInfo::InlineBlock(ref info) => inline_block_flows.push(info.flow_ref.clone()),
SpecificFragmentInfo::InlineAbsoluteHypothetical(ref info) => {
inline_block_flows.push(info.flow_ref.clone())
}
_ => {}
@ -374,12 +366,12 @@ impl<'a> FlowConstructor<'a> {
abs_descendants: &mut Descendants,
first_fragment: &mut bool) {
match kid.swap_out_construction_result() {
NoConstructionResult => {}
FlowConstructionResult(kid_flow, kid_abs_descendants) => {
ConstructionResult::None => {}
ConstructionResult::Flow(kid_flow, kid_abs_descendants) => {
// If kid_flow is TableCaptionFlow, kid_flow should be added under
// TableWrapperFlow.
if flow.is_table() && kid_flow.deref().is_table_caption() {
kid.set_flow_construction_result(FlowConstructionResult(kid_flow,
kid.set_flow_construction_result(ConstructionResult::Flow(kid_flow,
Descendants::new()))
} else if flow.need_anonymous_flow(&*kid_flow) {
consecutive_siblings.push(kid_flow)
@ -393,7 +385,7 @@ impl<'a> FlowConstructor<'a> {
InlineFragmentsAccumulator::new()),
flow,
consecutive_siblings,
StripWhitespaceFromStart,
WhitespaceStrippingMode::FromStart,
node);
if !consecutive_siblings.is_empty() {
let consecutive_siblings = mem::replace(consecutive_siblings, vec!());
@ -403,7 +395,7 @@ impl<'a> FlowConstructor<'a> {
}
abs_descendants.push_descendants(kid_abs_descendants);
}
ConstructionItemConstructionResult(InlineFragmentsConstructionItem(
ConstructionResult::ConstructionItem(ConstructionItem::InlineFragments(
InlineFragmentsConstructionResult {
splits,
fragments: successor_fragments,
@ -423,9 +415,9 @@ impl<'a> FlowConstructor<'a> {
// whitespace per CSS 2.1 § 9.2.1.1.
let whitespace_stripping = if *first_fragment {
*first_fragment = false;
StripWhitespaceFromStart
WhitespaceStrippingMode::FromStart
} else {
NoWhitespaceStripping
WhitespaceStrippingMode::None
};
// Flush any inline fragments that we were gathering up.
@ -452,20 +444,20 @@ impl<'a> FlowConstructor<'a> {
inline_fragment_accumulator.push_all(successor_fragments);
abs_descendants.push_descendants(kid_abs_descendants);
}
ConstructionItemConstructionResult(WhitespaceConstructionItem(whitespace_node,
ConstructionResult::ConstructionItem(ConstructionItem::Whitespace(whitespace_node,
whitespace_style,
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 =
UnscannedTextFragment(UnscannedTextFragmentInfo::from_text(" ".to_string()));
SpecificFragmentInfo::UnscannedText(UnscannedTextFragmentInfo::from_text(" ".to_string()));
let fragment = Fragment::from_opaque_node_and_style(whitespace_node,
whitespace_style,
whitespace_damage,
fragment_info);
inline_fragment_accumulator.fragments.push_back(fragment);
}
ConstructionItemConstructionResult(TableColumnFragmentConstructionItem(_)) => {
ConstructionResult::ConstructionItem(ConstructionItem::TableColumnFragment(_)) => {
// TODO: Implement anonymous table objects for missing parents
// CSS 2.1 § 17.2.1, step 3-2
}
@ -495,7 +487,7 @@ impl<'a> FlowConstructor<'a> {
// List of absolute descendants, in tree order.
let mut abs_descendants = Descendants::new();
for kid in node.children() {
if kid.get_pseudo_element_type() != Normal {
if kid.get_pseudo_element_type() != PseudoElementType::Normal {
self.process(&kid);
}
@ -514,7 +506,7 @@ impl<'a> FlowConstructor<'a> {
self.flush_inline_fragments_to_flow_or_list(inline_fragment_accumulator,
&mut flow,
&mut consecutive_siblings,
StripWhitespaceFromEnd,
WhitespaceStrippingMode::FromEnd,
node);
if !consecutive_siblings.is_empty() {
self.generate_anonymous_missing_child(consecutive_siblings, &mut flow, node);
@ -537,7 +529,7 @@ impl<'a> FlowConstructor<'a> {
abs_descendants.push(flow.clone());
}
}
FlowConstructionResult(flow, abs_descendants)
ConstructionResult::Flow(flow, abs_descendants)
}
/// Constructs a flow for the given block node and its children. This method creates an
@ -553,19 +545,19 @@ impl<'a> FlowConstructor<'a> {
/// `<textarea>`.
fn build_flow_for_block(&mut self, flow: FlowRef, node: &ThreadSafeLayoutNode)
-> ConstructionResult {
let initial_fragment = if node.get_pseudo_element_type() != Normal ||
node.type_id() == Some(ElementNodeTypeId(HTMLInputElementTypeId)) ||
node.type_id() == Some(ElementNodeTypeId(HTMLTextAreaElementTypeId)) {
let initial_fragment = if node.get_pseudo_element_type() != PseudoElementType::Normal ||
node.type_id() == Some(NodeTypeId::Element(ElementTypeId::HTMLInputElement)) ||
node.type_id() == Some(NodeTypeId::Element(ElementTypeId::HTMLTextAreaElement)) {
// A TextArea's text contents are displayed through the input text
// box, so don't construct them.
if node.type_id() == Some(ElementNodeTypeId(HTMLTextAreaElementTypeId)) {
if node.type_id() == Some(NodeTypeId::Element(ElementTypeId::HTMLTextAreaElement)) {
for kid in node.children() {
kid.set_flow_construction_result(NoConstructionResult)
kid.set_flow_construction_result(ConstructionResult::None)
}
}
Some(Fragment::new_from_specific_info(
node,
UnscannedTextFragment(UnscannedTextFragmentInfo::new(node))))
SpecificFragmentInfo::UnscannedText(UnscannedTextFragmentInfo::new(node))))
} else {
None
};
@ -602,12 +594,12 @@ impl<'a> FlowConstructor<'a> {
// Concatenate all the fragments of our kids, creating {ib} splits as necessary.
for kid in node.children() {
if kid.get_pseudo_element_type() != Normal {
if kid.get_pseudo_element_type() != PseudoElementType::Normal {
self.process(&kid);
}
match kid.swap_out_construction_result() {
NoConstructionResult => {}
FlowConstructionResult(flow, kid_abs_descendants) => {
ConstructionResult::None => {}
ConstructionResult::Flow(flow, kid_abs_descendants) => {
// {ib} split. Flush the accumulator to our new split and make a new
// accumulator to hold any subsequent fragments we come across.
let split = InlineBlockSplit {
@ -620,7 +612,7 @@ impl<'a> FlowConstructor<'a> {
opt_inline_block_splits.push_back(split);
abs_descendants.push_descendants(kid_abs_descendants);
}
ConstructionItemConstructionResult(InlineFragmentsConstructionItem(
ConstructionResult::ConstructionItem(ConstructionItem::InlineFragments(
InlineFragmentsConstructionResult {
splits,
fragments: successors,
@ -649,12 +641,12 @@ impl<'a> FlowConstructor<'a> {
fragment_accumulator.push_all(successors);
abs_descendants.push_descendants(kid_abs_descendants);
}
ConstructionItemConstructionResult(WhitespaceConstructionItem(
ConstructionResult::ConstructionItem(ConstructionItem::Whitespace(
whitespace_node,
whitespace_style,
whitespace_damage)) => {
// Instantiate the whitespace fragment.
let fragment_info = UnscannedTextFragment(UnscannedTextFragmentInfo::from_text(
let fragment_info = SpecificFragmentInfo::UnscannedText(UnscannedTextFragmentInfo::from_text(
" ".to_string()));
let fragment = Fragment::from_opaque_node_and_style(whitespace_node,
whitespace_style,
@ -662,7 +654,7 @@ impl<'a> FlowConstructor<'a> {
fragment_info);
fragment_accumulator.fragments.push_back(fragment)
}
ConstructionItemConstructionResult(TableColumnFragmentConstructionItem(_)) => {
ConstructionResult::ConstructionItem(ConstructionItem::TableColumnFragment(_)) => {
// TODO: Implement anonymous table objects for missing parents
// CSS 2.1 § 17.2.1, step 3-2
}
@ -672,15 +664,15 @@ impl<'a> FlowConstructor<'a> {
// Finally, make a new construction result.
if opt_inline_block_splits.len() > 0 || fragment_accumulator.fragments.len() > 0
|| abs_descendants.len() > 0 {
let construction_item = InlineFragmentsConstructionItem(
let construction_item = ConstructionItem::InlineFragments(
InlineFragmentsConstructionResult {
splits: opt_inline_block_splits,
fragments: fragment_accumulator.to_dlist(),
abs_descendants: abs_descendants,
});
ConstructionItemConstructionResult(construction_item)
ConstructionResult::ConstructionItem(construction_item)
} else {
NoConstructionResult
ConstructionResult::None
}
}
@ -690,7 +682,7 @@ impl<'a> FlowConstructor<'a> {
fn build_fragments_for_replaced_inline_content(&mut self, node: &ThreadSafeLayoutNode)
-> ConstructionResult {
for kid in node.children() {
kid.set_flow_construction_result(NoConstructionResult)
kid.set_flow_construction_result(ConstructionResult::None)
}
// If this node is ignorable whitespace, bail out now.
@ -698,7 +690,7 @@ impl<'a> FlowConstructor<'a> {
// FIXME(#2001, pcwalton): Don't do this if there's padding or borders.
if node.is_ignorable_whitespace() {
let opaque_node = OpaqueNodeMethods::from_thread_safe_layout_node(node);
return ConstructionItemConstructionResult(WhitespaceConstructionItem(
return ConstructionResult::ConstructionItem(ConstructionItem::Whitespace(
opaque_node,
node.style().clone(),
node.restyle_damage()))
@ -707,8 +699,8 @@ impl<'a> FlowConstructor<'a> {
// 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() != Normal {
let fragment_info = UnscannedTextFragment(UnscannedTextFragmentInfo::new(node));
let fragment = if node.get_pseudo_element_type() != PseudoElementType::Normal {
let fragment_info = SpecificFragmentInfo::UnscannedText(UnscannedTextFragmentInfo::new(node));
Fragment::new_from_specific_info(node, fragment_info)
} else {
Fragment::new(self, node)
@ -717,34 +709,34 @@ impl<'a> FlowConstructor<'a> {
let mut fragments = DList::new();
fragments.push_back(fragment);
let construction_item = InlineFragmentsConstructionItem(InlineFragmentsConstructionResult {
let construction_item = ConstructionItem::InlineFragments(InlineFragmentsConstructionResult {
splits: DList::new(),
fragments: fragments,
abs_descendants: Descendants::new(),
});
ConstructionItemConstructionResult(construction_item)
ConstructionResult::ConstructionItem(construction_item)
}
fn build_fragment_for_inline_block(&mut self, node: &ThreadSafeLayoutNode)
-> ConstructionResult {
let block_flow_result = self.build_flow_for_nonfloated_block(node);
let (block_flow, abs_descendants) = match block_flow_result {
FlowConstructionResult(block_flow, abs_descendants) => (block_flow, abs_descendants),
ConstructionResult::Flow(block_flow, abs_descendants) => (block_flow, abs_descendants),
_ => unreachable!()
};
let fragment_info = InlineBlockFragment(InlineBlockFragmentInfo::new(block_flow));
let fragment_info = SpecificFragmentInfo::InlineBlock(InlineBlockFragmentInfo::new(block_flow));
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);
let construction_item = InlineFragmentsConstructionItem(InlineFragmentsConstructionResult {
let construction_item = ConstructionItem::InlineFragments(InlineFragmentsConstructionResult {
splits: DList::new(),
fragments: fragment_accumulator.to_dlist(),
abs_descendants: abs_descendants,
});
ConstructionItemConstructionResult(construction_item)
ConstructionResult::ConstructionItem(construction_item)
}
/// This is an annoying case, because the computed `display` value is `block`, but the
@ -753,23 +745,23 @@ impl<'a> FlowConstructor<'a> {
-> ConstructionResult {
let block_flow_result = self.build_flow_for_nonfloated_block(node);
let (block_flow, abs_descendants) = match block_flow_result {
FlowConstructionResult(block_flow, abs_descendants) => (block_flow, abs_descendants),
ConstructionResult::Flow(block_flow, abs_descendants) => (block_flow, abs_descendants),
_ => unreachable!()
};
let fragment_info = InlineAbsoluteHypotheticalFragment(
let fragment_info = SpecificFragmentInfo::InlineAbsoluteHypothetical(
InlineAbsoluteHypotheticalFragmentInfo::new(block_flow));
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);
let construction_item = InlineFragmentsConstructionItem(InlineFragmentsConstructionResult {
let construction_item = ConstructionItem::InlineFragments(InlineFragmentsConstructionResult {
splits: DList::new(),
fragments: fragment_accumulator.to_dlist(),
abs_descendants: abs_descendants,
});
ConstructionItemConstructionResult(construction_item)
ConstructionResult::ConstructionItem(construction_item)
}
/// Builds one or more fragments for a node with `display: inline`. This yields an
@ -792,8 +784,8 @@ impl<'a> FlowConstructor<'a> {
node: &ThreadSafeLayoutNode) {
for kid in node.children() {
match kid.swap_out_construction_result() {
NoConstructionResult | ConstructionItemConstructionResult(_) => {}
FlowConstructionResult(kid_flow, _) => {
ConstructionResult::None | ConstructionResult::ConstructionItem(_) => {}
ConstructionResult::Flow(kid_flow, _) => {
// Only kid flows with table-caption are matched here.
if kid_flow.deref().is_table_caption() {
table_wrapper_flow.add_new_child(kid_flow);
@ -836,7 +828,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_from_specific_info(node, TableWrapperFragment);
let fragment = Fragment::new_from_specific_info(node, SpecificFragmentInfo::TableWrapper);
let wrapper_flow = match float_value {
float::none => box TableWrapperFlow::from_node_and_fragment(node, fragment),
_ => {
@ -846,7 +838,7 @@ impl<'a> FlowConstructor<'a> {
};
let mut wrapper_flow = FlowRef::new(wrapper_flow as Box<Flow>);
let table_fragment = Fragment::new_from_specific_info(node, TableFragment);
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>);
@ -862,7 +854,7 @@ impl<'a> FlowConstructor<'a> {
// NOTE: The order of captions and table are not the same order as in the DOM tree.
// All caption blocks are placed before the table flow
match construction_result {
FlowConstructionResult(table_flow, table_abs_descendants) => {
ConstructionResult::Flow(table_flow, table_abs_descendants) => {
wrapper_flow.add_new_child(table_flow);
abs_descendants.push_descendants(table_abs_descendants);
}
@ -890,7 +882,7 @@ impl<'a> FlowConstructor<'a> {
}
}
FlowConstructionResult(wrapper_flow, abs_descendants)
ConstructionResult::Flow(wrapper_flow, abs_descendants)
}
/// Builds a flow for a node with `display: table-caption`. This yields a `TableCaptionFlow`
@ -904,7 +896,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_from_specific_info(node, TableRowFragment);
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)
@ -913,7 +905,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_from_specific_info(node, TableRowFragment);
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)
}
@ -921,7 +913,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_from_specific_info(node, TableCellFragment);
let fragment = Fragment::new_from_specific_info(node, SpecificFragmentInfo::TableCell);
let flow = box TableCellFlow::from_node_and_fragment(node, fragment) as Box<Flow>;
self.build_flow_for_block(FlowRef::new(flow), node)
}
@ -945,7 +937,7 @@ impl<'a> FlowConstructor<'a> {
let mut unscanned_marker_fragments = DList::new();
unscanned_marker_fragments.push_back(Fragment::new_from_specific_info(
node,
UnscannedTextFragment(UnscannedTextFragmentInfo::from_text(text))));
SpecificFragmentInfo::UnscannedText(UnscannedTextFragmentInfo::from_text(text))));
let marker_fragments = TextRunScanner::new().scan_for_runs(
self.layout_context.font_context(),
unscanned_marker_fragments);
@ -984,14 +976,14 @@ impl<'a> FlowConstructor<'a> {
-> ConstructionResult {
// CSS 2.1 § 17.2.1. Treat all child fragments of a `table-column` as `display: none`.
for kid in node.children() {
kid.set_flow_construction_result(NoConstructionResult)
kid.set_flow_construction_result(ConstructionResult::None)
}
let specific = TableColumnFragment(TableColumnFragmentInfo::new(node));
let construction_item = TableColumnFragmentConstructionItem(
let specific = SpecificFragmentInfo::TableColumn(TableColumnFragmentInfo::new(node));
let construction_item = ConstructionItem::TableColumnFragment(
Fragment::new_from_specific_info(node, specific)
);
ConstructionItemConstructionResult(construction_item)
ConstructionResult::ConstructionItem(construction_item)
}
/// Builds a flow for a node with `display: table-column-group`.
@ -1000,13 +992,13 @@ impl<'a> FlowConstructor<'a> {
-> ConstructionResult {
let fragment = Fragment::new_from_specific_info(
node,
TableColumnFragment(TableColumnFragmentInfo::new(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`
// as `display: none`.
match kid.swap_out_construction_result() {
ConstructionItemConstructionResult(TableColumnFragmentConstructionItem(
ConstructionResult::ConstructionItem(ConstructionItem::TableColumnFragment(
fragment)) => {
col_fragments.push(fragment);
}
@ -1014,15 +1006,15 @@ impl<'a> FlowConstructor<'a> {
}
}
if col_fragments.is_empty() {
debug!("add TableColumnFragment for empty colgroup");
let specific = TableColumnFragment(TableColumnFragmentInfo::new(node));
debug!("add SpecificFragmentInfo::TableColumn for empty colgroup");
let specific = SpecificFragmentInfo::TableColumn(TableColumnFragmentInfo::new(node));
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>);
flow.finish();
FlowConstructionResult(flow, Descendants::new())
ConstructionResult::Flow(flow, Descendants::new())
}
/// Attempts to perform incremental repair to account for recent changes to this node. This
@ -1049,15 +1041,15 @@ impl<'a> FlowConstructor<'a> {
}
match node.swap_out_construction_result() {
NoConstructionResult => true,
FlowConstructionResult(mut flow, _) => {
ConstructionResult::None => true,
ConstructionResult::Flow(mut flow, _) => {
// The node's flow is of the same type and has the same set of children and can
// therefore be repaired by simply propagating damage and style to the flow.
flow::mut_base(&mut *flow).restyle_damage.insert(node.restyle_damage());
flow.repair_style(node.style());
true
}
ConstructionItemConstructionResult(_) => {
ConstructionResult::ConstructionItem(_) => {
false
}
}
@ -1078,13 +1070,13 @@ impl<'a> PostorderNodeMutTraversal for FlowConstructor<'a> {
// Pseudo-element.
let style = node.style();
let display = match node.get_pseudo_element_type() {
Normal => display::inline,
Before(display) => display,
After(display) => display,
PseudoElementType::Normal => display::inline,
PseudoElementType::Before(display) => display,
PseudoElementType::After(display) => display,
};
(display, style.get_box().float, style.get_box().position)
}
Some(ElementNodeTypeId(_)) => {
Some(NodeTypeId::Element(_)) => {
let style = node.style();
let munged_display = if style.get_box()._servo_display_for_hypothetical_box ==
display::inline {
@ -1094,12 +1086,12 @@ impl<'a> PostorderNodeMutTraversal for FlowConstructor<'a> {
};
(munged_display, style.get_box().float, style.get_box().position)
}
Some(TextNodeTypeId) => (display::inline, float::none, position::static_),
Some(CommentNodeTypeId) |
Some(DoctypeNodeTypeId) |
Some(DocumentFragmentNodeTypeId) |
Some(DocumentNodeTypeId) |
Some(ProcessingInstructionNodeTypeId) => {
Some(NodeTypeId::Text) => (display::inline, float::none, position::static_),
Some(NodeTypeId::Comment) |
Some(NodeTypeId::DocumentType) |
Some(NodeTypeId::DocumentFragment) |
Some(NodeTypeId::Document) |
Some(NodeTypeId::ProcessingInstruction) => {
(display::none, float::none, position::static_)
}
};
@ -1228,7 +1220,7 @@ 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 `NoConstructionResult` and returns the
/// Replaces the flow construction result in a node with `ConstructionResult::None` and returns the
/// old value.
fn swap_out_construction_result(self) -> ConstructionResult;
}
@ -1236,24 +1228,24 @@ trait NodeUtils {
impl<'ln> NodeUtils for ThreadSafeLayoutNode<'ln> {
fn is_replaced_content(&self) -> bool {
match self.type_id() {
Some(TextNodeTypeId) |
Some(ProcessingInstructionNodeTypeId) |
Some(CommentNodeTypeId) |
Some(DoctypeNodeTypeId) |
Some(DocumentFragmentNodeTypeId) |
Some(DocumentNodeTypeId) |
Some(NodeTypeId::Text) |
Some(NodeTypeId::ProcessingInstruction) |
Some(NodeTypeId::Comment) |
Some(NodeTypeId::DocumentType) |
Some(NodeTypeId::DocumentFragment) |
Some(NodeTypeId::Document) |
None |
Some(ElementNodeTypeId(HTMLImageElementTypeId)) => true,
Some(ElementNodeTypeId(HTMLObjectElementTypeId)) => self.has_object_data(),
Some(ElementNodeTypeId(_)) => false,
Some(NodeTypeId::Element(ElementTypeId::HTMLImageElement)) => true,
Some(NodeTypeId::Element(ElementTypeId::HTMLObjectElement)) => self.has_object_data(),
Some(NodeTypeId::Element(_)) => false,
}
}
fn get_construction_result<'a>(self, layout_data: &'a mut LayoutDataWrapper) -> &'a mut ConstructionResult {
match self.get_pseudo_element_type() {
Before(_) => &mut layout_data.data.before_flow_construction_result,
After (_) => &mut layout_data.data.after_flow_construction_result,
Normal => &mut layout_data.data.flow_construction_result,
PseudoElementType::Before(_) => &mut layout_data.data.before_flow_construction_result,
PseudoElementType::After (_) => &mut layout_data.data.after_flow_construction_result,
PseudoElementType::Normal => &mut layout_data.data.flow_construction_result,
}
}

View file

@ -9,7 +9,7 @@ use incremental::{mod, RestyleDamage};
use util::{LayoutDataAccess, LayoutDataWrapper};
use wrapper::{LayoutElement, LayoutNode, TLayoutNode};
use script::dom::node::{TextNodeTypeId};
use script::dom::node::NodeTypeId;
use servo_util::bloom::BloomFilter;
use servo_util::cache::{Cache, LRUCache, SimpleHashCache};
use servo_util::smallvec::{SmallVec, SmallVec16};
@ -18,8 +18,8 @@ use std::mem;
use std::hash::{Hash, sip};
use std::slice::Items;
use string_cache::{Atom, Namespace};
use style::{mod, After, Before, ComputedValues, DeclarationBlock, Stylist, TElement, TNode};
use style::{AttrIsEqualMode, AttrIsPresentMode, CommonStyleAffectingAttributes, cascade};
use style::{mod, PseudoElement, ComputedValues, DeclarationBlock, Stylist, TElement, TNode};
use style::{CommonStyleAffectingAttributeMode, CommonStyleAffectingAttributes, cascade};
use sync::Arc;
pub struct ApplicableDeclarations {
@ -153,12 +153,12 @@ fn create_common_style_affecting_attributes_from_element(element: &LayoutElement
let mut flags = CommonStyleAffectingAttributes::empty();
for attribute_info in style::common_style_affecting_attributes().iter() {
match attribute_info.mode {
AttrIsPresentMode(flag) => {
CommonStyleAffectingAttributeMode::IsPresent(flag) => {
if element.get_attr(&ns!(""), &attribute_info.atom).is_some() {
flags.insert(flag)
}
}
AttrIsEqualMode(target_value, flag) => {
CommonStyleAffectingAttributeMode::IsEqual(target_value, flag) => {
match element.get_attr(&ns!(""), &attribute_info.atom) {
Some(element_value) if element_value == target_value => {
flags.insert(flag)
@ -273,13 +273,13 @@ impl StyleSharingCandidate {
for attribute_info in style::common_style_affecting_attributes().iter() {
match attribute_info.mode {
AttrIsPresentMode(flag) => {
CommonStyleAffectingAttributeMode::IsPresent(flag) => {
if self.common_style_affecting_attributes.contains(flag) !=
element.get_attr(&ns!(""), &attribute_info.atom).is_some() {
return false
}
}
AttrIsEqualMode(target_value, flag) => {
CommonStyleAffectingAttributeMode::IsEqual(target_value, flag) => {
match element.get_attr(&ns!(""), &attribute_info.atom) {
Some(ref element_value) if self.common_style_affecting_attributes
.contains(flag) &&
@ -501,12 +501,12 @@ impl<'ln> MatchMethods for LayoutNode<'ln> {
stylist.push_applicable_declarations(self,
parent_bf,
None,
Some(Before),
Some(PseudoElement::Before),
&mut applicable_declarations.before);
stylist.push_applicable_declarations(self,
parent_bf,
None,
Some(After),
Some(PseudoElement::After),
&mut applicable_declarations.after);
*shareable = applicable_declarations.normal_shareable &&
@ -520,7 +520,7 @@ impl<'ln> MatchMethods for LayoutNode<'ln> {
parent: Option<LayoutNode>)
-> StyleSharingResult {
if !self.is_element() {
return CannotShare(false)
return StyleSharingResult::CannotShare(false)
}
let ok = {
let element = self.as_element();
@ -528,7 +528,7 @@ impl<'ln> MatchMethods for LayoutNode<'ln> {
element.get_attr(&ns!(""), &atom!("id")).is_none()
};
if !ok {
return CannotShare(false)
return StyleSharingResult::CannotShare(false)
}
for (i, &(ref candidate, ())) in style_sharing_candidate_cache.iter().enumerate() {
@ -540,13 +540,13 @@ impl<'ln> MatchMethods for LayoutNode<'ln> {
let style = &mut shared_data.style;
let damage = incremental::compute_damage(style, &*shared_style);
*style = Some(shared_style);
return StyleWasShared(i, damage)
return StyleSharingResult::StyleWasShared(i, damage)
}
None => {}
}
}
CannotShare(true)
StyleSharingResult::CannotShare(true)
}
// The below two functions are copy+paste because I can't figure out how to
@ -614,7 +614,7 @@ impl<'ln> MatchMethods for LayoutNode<'ln> {
&None => panic!("no layout data"),
&Some(ref mut layout_data) => {
match self.type_id() {
Some(TextNodeTypeId) => {
Some(NodeTypeId::Text) => {
// Text nodes get a copy of the parent style. This ensures
// that during fragment construction any non-inherited
// CSS properties (such as vertical-align) are correctly

View file

@ -4,7 +4,7 @@
//! Style retrieval from DOM elements.
use wrapper::{After, Before, Normal, ThreadSafeLayoutNode};
use wrapper::{PseudoElementType, ThreadSafeLayoutNode};
use std::mem;
use style::ComputedValues;
@ -27,7 +27,7 @@ impl<'ln> StyledNode for ThreadSafeLayoutNode<'ln> {
unsafe {
let layout_data_ref = self.borrow_layout_data();
match self.get_pseudo_element_type() {
Before(_) => {
PseudoElementType::Before(_) => {
mem::transmute(layout_data_ref.as_ref()
.unwrap()
.data
@ -35,7 +35,7 @@ impl<'ln> StyledNode for ThreadSafeLayoutNode<'ln> {
.as_ref()
.unwrap())
}
After(_) => {
PseudoElementType::After(_) => {
mem::transmute(layout_data_ref.as_ref()
.unwrap()
.data
@ -43,7 +43,7 @@ impl<'ln> StyledNode for ThreadSafeLayoutNode<'ln> {
.as_ref()
.unwrap())
}
Normal => {
PseudoElementType::Normal => {
mem::transmute(layout_data_ref.as_ref()
.unwrap()
.shared_data
@ -66,9 +66,9 @@ impl<'ln> StyledNode for ThreadSafeLayoutNode<'ln> {
let style =
match self.get_pseudo_element_type() {
Before(_) => &mut layout_data.data.before_style,
After (_) => &mut layout_data.data.after_style,
Normal => &mut layout_data.shared_data.style,
PseudoElementType::Before(_) => &mut layout_data.data.before_style,
PseudoElementType::After (_) => &mut layout_data.data.after_style,
PseudoElementType::Normal => &mut layout_data.shared_data.style,
};
*style = None;

View file

@ -13,11 +13,8 @@
use block::BlockFlow;
use context::LayoutContext;
use flow::{mod, Flow, IS_ABSOLUTELY_POSITIONED, NEEDS_LAYER};
use fragment::{Fragment, GenericFragment, IframeFragment, IframeFragmentInfo, ImageFragment};
use fragment::{ImageFragmentInfo, InlineAbsoluteHypotheticalFragment, InlineBlockFragment};
use fragment::{ScannedTextFragment, ScannedTextFragmentInfo, TableFragment};
use fragment::{TableCellFragment, TableColumnFragment, TableRowFragment, TableWrapperFragment};
use fragment::{UnscannedTextFragment};
use fragment::{Fragment, SpecificFragmentInfo, IframeFragmentInfo, ImageFragmentInfo};
use fragment::ScannedTextFragmentInfo;
use list_item::ListItemFlow;
use model;
use util::{OpaqueNodeMethods, ToGfxColor};
@ -41,20 +38,21 @@ use servo_util::geometry::{mod, Au, ZERO_POINT, ZERO_RECT};
use servo_util::logical_geometry::{LogicalRect, WritingMode};
use servo_util::opts;
use std::default::Default;
use style::computed::{AngleAoc, CornerAoc, LP_Length, LP_Percentage, LengthOrPercentage};
use style::computed::{LinearGradient, LinearGradientImage, UrlImage};
use std::num::FloatMath;
use style::computed::{AngleOrCorner, LengthOrPercentage, HorizontalDirection, VerticalDirection};
use style::computed::{Image, LinearGradient};
use style::computed_values::{background_attachment, background_repeat, border_style, overflow};
use style::computed_values::{visibility};
use style::{ComputedValues, Bottom, Left, RGBA, Right, Top};
use style::{ComputedValues, RGBA};
use style::style_structs::Border;
use sync::Arc;
use url::Url;
/// The results of display list building for a single flow.
pub enum DisplayListBuildingResult {
NoDisplayListBuildingResult,
StackingContextResult(Arc<StackingContext>),
DisplayListResult(Box<DisplayList>),
None,
StackingContext(Arc<StackingContext>),
Normal(Box<DisplayList>),
}
impl DisplayListBuildingResult {
@ -63,11 +61,11 @@ impl DisplayListBuildingResult {
/// consist of an entire stacking context, it will be emptied.
pub fn add_to(&mut self, display_list: &mut DisplayList) {
match *self {
NoDisplayListBuildingResult => return,
StackingContextResult(ref mut stacking_context) => {
DisplayListBuildingResult::None => return,
DisplayListBuildingResult::StackingContext(ref mut stacking_context) => {
display_list.children.push_back((*stacking_context).clone())
}
DisplayListResult(ref mut source_display_list) => {
DisplayListBuildingResult::Normal(ref mut source_display_list) => {
display_list.append_from(&mut **source_display_list)
}
}
@ -210,7 +208,7 @@ impl FragmentDisplayListBuilding for Fragment {
let background = style.get_background();
match background.background_image {
None => {}
Some(LinearGradientImage(ref gradient)) => {
Some(Image::LinearGradient(ref gradient)) => {
self.build_display_list_for_background_linear_gradient(display_list,
level,
absolute_bounds,
@ -218,7 +216,7 @@ impl FragmentDisplayListBuilding for Fragment {
gradient,
style)
}
Some(UrlImage(ref image_url)) => {
Some(Image::Url(ref image_url)) => {
self.build_display_list_for_background_image(style,
display_list,
layout_context,
@ -330,20 +328,20 @@ impl FragmentDisplayListBuilding for Fragment {
// This is the distance between the center and the ending point; i.e. half of the distance
// between the starting point and the ending point.
let delta = match gradient.angle_or_corner {
AngleAoc(angle) => {
AngleOrCorner::Angle(angle) => {
Point2D(Au((angle.radians().sin() *
absolute_bounds.size.width.to_f64().unwrap() / 2.0) as i32),
Au((-angle.radians().cos() *
absolute_bounds.size.height.to_f64().unwrap() / 2.0) as i32))
}
CornerAoc(horizontal, vertical) => {
AngleOrCorner::Corner(horizontal, vertical) => {
let x_factor = match horizontal {
Left => -1,
Right => 1,
HorizontalDirection::Left => -1,
HorizontalDirection::Right => 1,
};
let y_factor = match vertical {
Top => -1,
Bottom => 1,
VerticalDirection::Top => -1,
VerticalDirection::Bottom => 1,
};
Point2D(Au(x_factor * absolute_bounds.size.width.to_i32().unwrap() / 2),
Au(y_factor * absolute_bounds.size.height.to_i32().unwrap() / 2))
@ -647,7 +645,7 @@ impl FragmentDisplayListBuilding for Fragment {
None => {}
}
match self.specific {
ScannedTextFragment(_) => {},
SpecificFragmentInfo::ScannedText(_) => {},
_ => {
self.build_display_list_for_box_shadow_if_applicable(
&*self.style,
@ -675,7 +673,7 @@ impl FragmentDisplayListBuilding for Fragment {
None => {}
}
match self.specific {
ScannedTextFragment(_) => {},
SpecificFragmentInfo::ScannedText(_) => {},
_ => {
self.build_display_list_for_background_if_applicable(
&*self.style,
@ -707,7 +705,7 @@ impl FragmentDisplayListBuilding for Fragment {
None => {}
}
match self.specific {
ScannedTextFragment(_) => {},
SpecificFragmentInfo::ScannedText(_) => {},
_ => {
self.build_display_list_for_borders_if_applicable(
&*self.style,
@ -729,9 +727,9 @@ impl FragmentDisplayListBuilding for Fragment {
// Create special per-fragment-type display items.
match self.specific {
UnscannedTextFragment(_) => panic!("Shouldn't see unscanned fragments here."),
TableColumnFragment(_) => panic!("Shouldn't see table column fragments here."),
ScannedTextFragment(ref text_fragment) => {
SpecificFragmentInfo::UnscannedText(_) => panic!("Shouldn't see unscanned fragments here."),
SpecificFragmentInfo::TableColumn(_) => panic!("Shouldn't see table column fragments here."),
SpecificFragmentInfo::ScannedText(ref text_fragment) => {
// Create the text display item.
let orientation = if self.style.writing_mode.is_vertical() {
if self.style.writing_mode.is_sideways_left() {
@ -806,16 +804,16 @@ impl FragmentDisplayListBuilding for Fragment {
clip_rect);
}
}
GenericFragment | IframeFragment(..) | TableFragment | TableCellFragment |
TableRowFragment | TableWrapperFragment | InlineBlockFragment(_) |
InlineAbsoluteHypotheticalFragment(_) => {
SpecificFragmentInfo::Generic | SpecificFragmentInfo::Iframe(..) | SpecificFragmentInfo::Table | SpecificFragmentInfo::TableCell |
SpecificFragmentInfo::TableRow | SpecificFragmentInfo::TableWrapper | SpecificFragmentInfo::InlineBlock(_) |
SpecificFragmentInfo::InlineAbsoluteHypothetical(_) => {
if opts::get().show_debug_fragment_borders {
self.build_debug_borders_around_fragment(display_list,
flow_origin,
clip_rect);
}
}
ImageFragment(ref mut image_fragment) => {
SpecificFragmentInfo::Image(ref mut image_fragment) => {
let image_ref = &mut image_fragment.image;
match image_ref.get_image(self.node.to_untrusted_node_address()) {
Some(image) => {
@ -857,7 +855,7 @@ impl FragmentDisplayListBuilding for Fragment {
// because layout for the iframe only needs to know size, and origin is only relevant if
// the iframe is actually going to be displayed.
match self.specific {
IframeFragment(ref iframe_fragment) => {
SpecificFragmentInfo::Iframe(ref iframe_fragment) => {
self.finalize_position_and_size_of_iframe(&**iframe_fragment,
absolute_fragment_bounds.origin,
layout_context)
@ -891,7 +889,7 @@ impl FragmentDisplayListBuilding for Fragment {
-> Rect<Au> {
// Don't clip if we're text.
match self.specific {
ScannedTextFragment(_) => return current_clip_rect,
SpecificFragmentInfo::ScannedText(_) => return current_clip_rect,
_ => {}
}
@ -962,9 +960,9 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
background_border_level);
self.base.display_list_building_result = if self.fragment.establishes_stacking_context() {
StackingContextResult(self.create_stacking_context(display_list, None))
DisplayListBuildingResult::StackingContext(self.create_stacking_context(display_list, None))
} else {
DisplayListResult(display_list)
DisplayListBuildingResult::Normal(display_list)
}
}
@ -973,13 +971,13 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
layout_context: &LayoutContext) {
self.build_display_list_for_block_base(&mut *display_list,
layout_context,
RootOfStackingContextLevel);
BackgroundAndBorderLevel::RootOfStackingContext);
if !self.base.absolute_position_info.layers_needed_for_positioned_flows &&
!self.base.flags.contains(NEEDS_LAYER) {
// We didn't need a layer.
self.base.display_list_building_result =
StackingContextResult(self.create_stacking_context(display_list, None));
DisplayListBuildingResult::StackingContext(self.create_stacking_context(display_list, None));
return
}
@ -996,7 +994,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
Some(Arc::new(PaintLayer::new(self.layer_id(0),
transparent,
scroll_policy))));
self.base.display_list_building_result = StackingContextResult(stacking_context)
self.base.display_list_building_result = DisplayListBuildingResult::StackingContext(stacking_context)
}
fn build_display_list_for_floating_block(&mut self,
@ -1004,13 +1002,13 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
layout_context: &LayoutContext) {
self.build_display_list_for_block_base(&mut *display_list,
layout_context,
RootOfStackingContextLevel);
BackgroundAndBorderLevel::RootOfStackingContext);
display_list.form_float_pseudo_stacking_context();
self.base.display_list_building_result = if self.fragment.establishes_stacking_context() {
StackingContextResult(self.create_stacking_context(display_list, None))
DisplayListBuildingResult::StackingContext(self.create_stacking_context(display_list, None))
} else {
DisplayListResult(display_list)
DisplayListBuildingResult::Normal(display_list)
}
}
@ -1024,7 +1022,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
} else if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
self.build_display_list_for_absolutely_positioned_block(display_list, layout_context)
} else {
self.build_display_list_for_static_block(display_list, layout_context, BlockLevel)
self.build_display_list_for_static_block(display_list, layout_context, BackgroundAndBorderLevel::Block)
}
}
@ -1059,7 +1057,7 @@ impl ListItemFlowDisplayListBuilding for ListItemFlow {
marker.build_display_list(&mut *display_list,
layout_context,
stacking_relative_fragment_origin,
ContentLevel,
BackgroundAndBorderLevel::Content,
&self.block_flow.base.clip_rect);
}
}
@ -1087,8 +1085,8 @@ fn fmin(a: f32, b: f32) -> f32 {
fn position_to_offset(position: LengthOrPercentage, Au(total_length): Au) -> f32 {
match position {
LP_Length(Au(length)) => fmin(1.0, (length as f32) / (total_length as f32)),
LP_Percentage(percentage) => percentage as f32,
LengthOrPercentage::Length(Au(length)) => fmin(1.0, (length as f32) / (total_length as f32)),
LengthOrPercentage::Percentage(percentage) => percentage as f32,
}
}
@ -1096,29 +1094,29 @@ fn position_to_offset(position: LengthOrPercentage, Au(total_length): Au) -> f32
#[deriving(Clone, PartialEq, Show)]
pub enum StackingLevel {
/// The border and backgrounds for the root of this stacking context: steps 1 and 2.
BackgroundAndBordersStackingLevel,
BackgroundAndBorders,
/// Borders and backgrounds for block-level descendants: step 4.
BlockBackgroundsAndBordersStackingLevel,
BlockBackgroundsAndBorders,
/// All other content.
ContentStackingLevel,
Content,
}
impl StackingLevel {
#[inline]
pub fn from_background_and_border_level(level: BackgroundAndBorderLevel) -> StackingLevel {
match level {
RootOfStackingContextLevel => BackgroundAndBordersStackingLevel,
BlockLevel => BlockBackgroundsAndBordersStackingLevel,
ContentLevel => ContentStackingLevel,
BackgroundAndBorderLevel::RootOfStackingContext => StackingLevel::BackgroundAndBorders,
BackgroundAndBorderLevel::Block => StackingLevel::BlockBackgroundsAndBorders,
BackgroundAndBorderLevel::Content => StackingLevel::Content,
}
}
}
/// Which level to place backgrounds and borders in.
pub enum BackgroundAndBorderLevel {
RootOfStackingContextLevel,
BlockLevel,
ContentLevel,
RootOfStackingContext,
Block,
Content,
}
trait StackingContextConstruction {
@ -1129,13 +1127,13 @@ trait StackingContextConstruction {
impl StackingContextConstruction for DisplayList {
fn push(&mut self, display_item: DisplayItem, level: StackingLevel) {
match level {
BackgroundAndBordersStackingLevel => {
StackingLevel::BackgroundAndBorders => {
self.background_and_borders.push_back(display_item)
}
BlockBackgroundsAndBordersStackingLevel => {
StackingLevel::BlockBackgroundsAndBorders => {
self.block_backgrounds_and_borders.push_back(display_item)
}
ContentStackingLevel => self.content.push_back(display_item),
StackingLevel::Content => self.content.push_back(display_item),
}
}
}

View file

@ -14,25 +14,25 @@ use style::computed_values::float;
/// The kind of float: left or right.
#[deriving(Clone, Encodable, Show)]
pub enum FloatKind {
FloatLeft,
FloatRight
Left,
Right
}
impl FloatKind {
pub fn from_property(property: float::T) -> FloatKind {
match property {
float::none => panic!("can't create a float type from an unfloated property"),
float::left => FloatLeft,
float::right => FloatRight,
float::left => FloatKind::Left,
float::right => FloatKind::Right,
}
}
}
/// The kind of clearance: left, right, or both.
pub enum ClearType {
ClearLeft,
ClearRight,
ClearBoth,
Left,
Right,
Both,
}
/// Information about a single float.
@ -184,7 +184,7 @@ impl Floats {
debug!("float_pos: {}, float_size: {}", float_pos, float_size);
match float.kind {
FloatLeft if float_pos.i + float_size.inline > max_inline_start &&
FloatKind::Left if float_pos.i + float_size.inline > max_inline_start &&
float_pos.b + float_size.block > block_start &&
float_pos.b < block_start + block_size => {
max_inline_start = float_pos.i + float_size.inline;
@ -196,7 +196,7 @@ impl Floats {
max_inline_start is {}",
max_inline_start);
}
FloatRight if float_pos.i < min_inline_end &&
FloatKind::Right if float_pos.i < min_inline_end &&
float_pos.b + float_size.block > block_start &&
float_pos.b < block_start + block_size => {
min_inline_end = float_pos.i;
@ -207,7 +207,7 @@ impl Floats {
is {}",
min_inline_end);
}
FloatLeft | FloatRight => {}
FloatKind::Left | FloatKind::Right => {}
}
}
@ -307,7 +307,7 @@ impl Floats {
// If no floats, use this fast path.
if !self.list.is_present() {
match info.kind {
FloatLeft => {
FloatKind::Left => {
return LogicalRect::new(
self.writing_mode,
Au(0),
@ -315,7 +315,7 @@ impl Floats {
info.max_inline_size,
Au(i32::MAX))
}
FloatRight => {
FloatKind::Right => {
return LogicalRect::new(
self.writing_mode,
info.max_inline_size - info.size.inline,
@ -338,7 +338,7 @@ impl Floats {
// TODO(eatkinson): integrate with overflow
None => {
return match info.kind {
FloatLeft => {
FloatKind::Left => {
LogicalRect::new(
self.writing_mode,
Au(0),
@ -346,7 +346,7 @@ impl Floats {
info.max_inline_size,
Au(i32::MAX))
}
FloatRight => {
FloatKind::Right => {
LogicalRect::new(
self.writing_mode,
info.max_inline_size - info.size.inline,
@ -367,7 +367,7 @@ impl Floats {
rect.size.inline);
let block_size = block_size.unwrap_or(Au(i32::MAX));
return match info.kind {
FloatLeft => {
FloatKind::Left => {
LogicalRect::new(
self.writing_mode,
rect.start.i,
@ -375,7 +375,7 @@ impl Floats {
rect.size.inline,
block_size)
}
FloatRight => {
FloatKind::Right => {
LogicalRect::new(
self.writing_mode,
rect.start.i + rect.size.inline - info.size.inline,
@ -399,9 +399,9 @@ impl Floats {
let mut clearance = Au(0);
for float in list.floats.iter() {
match (clear, float.kind) {
(ClearLeft, FloatLeft) |
(ClearRight, FloatRight) |
(ClearBoth, _) => {
(ClearType::Left, FloatKind::Left) |
(ClearType::Right, FloatKind::Right) |
(ClearType::Both, _) => {
let b = self.offset.block + float.bounds.start.b + float.bounds.size.block;
clearance = max(clearance, b);
}

View file

@ -28,12 +28,11 @@
use css::node_style::StyledNode;
use block::BlockFlow;
use context::LayoutContext;
use display_list_builder::{DisplayListBuildingResult, DisplayListResult};
use display_list_builder::{NoDisplayListBuildingResult, StackingContextResult};
use display_list_builder::DisplayListBuildingResult;
use floats::Floats;
use flow_list::{FlowList, FlowListIterator, MutFlowListIterator};
use flow_ref::FlowRef;
use fragment::{Fragment, FragmentBoundsIterator, TableRowFragment, TableCellFragment};
use fragment::{Fragment, FragmentBoundsIterator, SpecificFragmentInfo};
use incremental::{RECONSTRUCT_FLOW, REFLOW, REFLOW_OUT_OF_FLOW, RestyleDamage};
use inline::InlineFlow;
use model::{CollapsibleMargins, IntrinsicISizes, MarginCollapseInfo};
@ -428,16 +427,16 @@ pub trait MutableOwnedFlowUtils {
#[deriving(Encodable, PartialEq, Show)]
pub enum FlowClass {
BlockFlowClass,
InlineFlowClass,
ListItemFlowClass,
TableWrapperFlowClass,
TableFlowClass,
TableColGroupFlowClass,
TableRowGroupFlowClass,
TableRowFlowClass,
TableCaptionFlowClass,
TableCellFlowClass,
Block,
Inline,
ListItem,
TableWrapper,
Table,
TableColGroup,
TableRowGroup,
TableRow,
TableCaption,
TableCell,
}
/// A top-down traversal.
@ -810,13 +809,13 @@ impl<E, S: Encoder<E>> Encodable<S, E> for BaseFlow {
try!(e.emit_struct_field("class", 0, |e| c.class().encode(e)))
e.emit_struct_field("data", 1, |e| {
match c.class() {
BlockFlowClass => c.as_immutable_block().encode(e),
InlineFlowClass => c.as_immutable_inline().encode(e),
TableFlowClass => c.as_immutable_table().encode(e),
TableWrapperFlowClass => c.as_immutable_table_wrapper().encode(e),
TableRowGroupFlowClass => c.as_immutable_table_rowgroup().encode(e),
TableRowFlowClass => c.as_immutable_table_row().encode(e),
TableCellFlowClass => c.as_immutable_table_cell().encode(e),
FlowClass::Block => c.as_immutable_block().encode(e),
FlowClass::Inline => c.as_immutable_inline().encode(e),
FlowClass::Table => c.as_immutable_table().encode(e),
FlowClass::TableWrapper => c.as_immutable_table_wrapper().encode(e),
FlowClass::TableRowGroup => c.as_immutable_table_rowgroup().encode(e),
FlowClass::TableRow => c.as_immutable_table_row().encode(e),
FlowClass::TableCell => c.as_immutable_table_cell().encode(e),
_ => { Ok(()) } // TODO: Support captions
}
})
@ -869,7 +868,7 @@ impl BaseFlow {
_ => {}
}
if force_nonfloated == FloatIfNecessary {
if force_nonfloated == ForceNonfloatedFlag::FloatIfNecessary {
match node_style.get_box().float {
float::none => {}
float::left => flags.insert(FLOATS_LEFT),
@ -910,7 +909,7 @@ impl BaseFlow {
block_container_inline_size: Au(0),
block_container_explicit_block_size: None,
absolute_cb: ContainingBlockLink::new(),
display_list_building_result: NoDisplayListBuildingResult,
display_list_building_result: DisplayListBuildingResult::None,
absolute_position_info: AbsolutePositionInfo::new(writing_mode),
clip_rect: Rect(Zero::zero(), Size2D(Au(0), Au(0))),
flags: flags,
@ -940,11 +939,11 @@ impl BaseFlow {
position_with_overflow.size.block));
let all_items = match self.display_list_building_result {
NoDisplayListBuildingResult => Vec::new(),
StackingContextResult(ref stacking_context) => {
DisplayListBuildingResult::None => Vec::new(),
DisplayListBuildingResult::StackingContext(ref stacking_context) => {
stacking_context.display_list.all_display_items()
}
DisplayListResult(ref display_list) => display_list.all_display_items(),
DisplayListBuildingResult::Normal(ref display_list) => display_list.all_display_items(),
};
for item in all_items.iter() {
@ -979,7 +978,7 @@ impl<'a> ImmutableFlowUtils for &'a Flow + 'a {
/// Returns true if this flow is a block flow.
fn is_block_like(self) -> bool {
match self.class() {
BlockFlowClass => true,
FlowClass::Block => true,
_ => false,
}
}
@ -989,8 +988,8 @@ impl<'a> ImmutableFlowUtils for &'a Flow + 'a {
/// table-column-group flow, or table-caption flow.
fn is_proper_table_child(self) -> bool {
match self.class() {
TableRowFlowClass | TableRowGroupFlowClass |
TableColGroupFlowClass | TableCaptionFlowClass => true,
FlowClass::TableRow | FlowClass::TableRowGroup |
FlowClass::TableColGroup | FlowClass::TableCaption => true,
_ => false,
}
}
@ -998,7 +997,7 @@ impl<'a> ImmutableFlowUtils for &'a Flow + 'a {
/// Returns true if this flow is a table row flow.
fn is_table_row(self) -> bool {
match self.class() {
TableRowFlowClass => true,
FlowClass::TableRow => true,
_ => false,
}
}
@ -1006,7 +1005,7 @@ impl<'a> ImmutableFlowUtils for &'a Flow + 'a {
/// Returns true if this flow is a table cell flow.
fn is_table_cell(self) -> bool {
match self.class() {
TableCellFlowClass => true,
FlowClass::TableCell => true,
_ => false,
}
}
@ -1014,7 +1013,7 @@ impl<'a> ImmutableFlowUtils for &'a Flow + 'a {
/// Returns true if this flow is a table colgroup flow.
fn is_table_colgroup(self) -> bool {
match self.class() {
TableColGroupFlowClass => true,
FlowClass::TableColGroup => true,
_ => false,
}
}
@ -1022,7 +1021,7 @@ impl<'a> ImmutableFlowUtils for &'a Flow + 'a {
/// Returns true if this flow is a table flow.
fn is_table(self) -> bool {
match self.class() {
TableFlowClass => true,
FlowClass::Table => true,
_ => false,
}
}
@ -1030,7 +1029,7 @@ impl<'a> ImmutableFlowUtils for &'a Flow + 'a {
/// Returns true if this flow is a table caption flow.
fn is_table_caption(self) -> bool {
match self.class() {
TableCaptionFlowClass => true,
FlowClass::TableCaption => true,
_ => false,
}
}
@ -1038,7 +1037,7 @@ impl<'a> ImmutableFlowUtils for &'a Flow + 'a {
/// Returns true if this flow is a table rowgroup flow.
fn is_table_rowgroup(self) -> bool {
match self.class() {
TableRowGroupFlowClass => true,
FlowClass::TableRowGroup => true,
_ => false,
}
}
@ -1046,9 +1045,9 @@ impl<'a> ImmutableFlowUtils for &'a Flow + 'a {
/// Returns true if this flow is one of table-related flows.
fn is_table_kind(self) -> bool {
match self.class() {
TableWrapperFlowClass | TableFlowClass |
TableColGroupFlowClass | TableRowGroupFlowClass |
TableRowFlowClass | TableCaptionFlowClass | TableCellFlowClass => true,
FlowClass::TableWrapper | FlowClass::Table |
FlowClass::TableColGroup | FlowClass::TableRowGroup |
FlowClass::TableRow | FlowClass::TableCaption | FlowClass::TableCell => true,
_ => false,
}
}
@ -1057,9 +1056,9 @@ impl<'a> ImmutableFlowUtils for &'a Flow + 'a {
/// Spec: http://www.w3.org/TR/CSS21/tables.html#anonymous-boxes
fn need_anonymous_flow(self, child: &Flow) -> bool {
match self.class() {
TableFlowClass => !child.is_proper_table_child(),
TableRowGroupFlowClass => !child.is_table_row(),
TableRowFlowClass => !child.is_table_cell(),
FlowClass::Table => !child.is_proper_table_child(),
FlowClass::TableRowGroup => !child.is_table_row(),
FlowClass::TableRow => !child.is_table_cell(),
_ => false
}
}
@ -1067,12 +1066,12 @@ impl<'a> ImmutableFlowUtils for &'a Flow + 'a {
/// Generates missing child flow of this flow.
fn generate_missing_child_flow(self, node: &ThreadSafeLayoutNode) -> FlowRef {
let flow = match self.class() {
TableFlowClass | TableRowGroupFlowClass => {
let fragment = Fragment::new_anonymous_table_fragment(node, TableRowFragment);
FlowClass::Table | FlowClass::TableRowGroup => {
let fragment = Fragment::new_anonymous_table_fragment(node, SpecificFragmentInfo::TableRow);
box TableRowFlow::from_node_and_fragment(node, fragment) as Box<Flow>
},
TableRowFlowClass => {
let fragment = Fragment::new_anonymous_table_fragment(node, TableCellFragment);
FlowClass::TableRow => {
let fragment = Fragment::new_anonymous_table_fragment(node, SpecificFragmentInfo::TableCell);
box TableCellFlow::from_node_and_fragment(node, fragment) as Box<Flow>
},
_ => {
@ -1101,7 +1100,7 @@ impl<'a> ImmutableFlowUtils for &'a Flow + 'a {
fn is_block_container(self) -> bool {
match self.class() {
// TODO: Change this when inline-blocks are supported.
BlockFlowClass | TableCaptionFlowClass | TableCellFlowClass => {
FlowClass::Block | FlowClass::TableCaption | FlowClass::TableCell => {
// FIXME: Actually check the type of the node
self.child_count() != 0
}
@ -1112,7 +1111,7 @@ impl<'a> ImmutableFlowUtils for &'a Flow + 'a {
/// Returns true if this flow is a block flow.
fn is_block_flow(self) -> bool {
match self.class() {
BlockFlowClass => true,
FlowClass::Block => true,
_ => false,
}
}
@ -1120,7 +1119,7 @@ impl<'a> ImmutableFlowUtils for &'a Flow + 'a {
/// Returns true if this flow is an inline flow.
fn is_inline_flow(self) -> bool {
match self.class() {
InlineFlowClass => true,
FlowClass::Inline => true,
_ => false,
}
}

View file

@ -9,14 +9,14 @@
use css::node_style::StyledNode;
use construct::FlowConstructor;
use context::LayoutContext;
use floats::{ClearBoth, ClearLeft, ClearRight, ClearType};
use floats::ClearType;
use flow;
use flow::Flow;
use flow_ref::FlowRef;
use incremental::RestyleDamage;
use inline::{InlineFragmentContext, InlineMetrics};
use layout_debug;
use model::{Auto, IntrinsicISizes, IntrinsicISizesContribution, MaybeAuto, Specified, specified};
use model::{IntrinsicISizes, IntrinsicISizesContribution, MaybeAuto, specified};
use model;
use text;
use util::OpaqueNodeMethods;
@ -39,12 +39,12 @@ use servo_util::smallvec::SmallVec;
use servo_util::str::is_whitespace;
use std::cmp::{max, min};
use std::fmt;
use std::from_str::FromStr;
use std::str::FromStr;
use string_cache::Atom;
use style::{ComputedValues, TElement, TNode, cascade_anonymous};
use style::computed_values::{LengthOrPercentage, LengthOrPercentageOrAuto};
use style::computed_values::{LengthOrPercentageOrNone};
use style::computed_values::{LPA_Auto, clear, overflow_wrap, position, text_align};
use style::computed_values::{clear, overflow_wrap, position, text_align};
use style::computed_values::{text_decoration, vertical_align, white_space};
use sync::{Arc, Mutex};
use url::Url;
@ -62,7 +62,7 @@ use url::Url;
/// positioned as if it were a block fragment, but its children are positioned according to
/// inline flow.
///
/// A `GenericFragment` is an empty fragment that contributes only borders, margins, padding, and
/// A `SpecificFragmentInfo::Generic` is an empty fragment that contributes only borders, margins, padding, and
/// backgrounds. It is analogous to a CSS nonreplaced content box.
///
/// A fragment's type influences how its styles are interpreted during layout. For example,
@ -124,40 +124,40 @@ impl<E, S: Encoder<E>> Encodable<S, E> for Fragment {
/// Keep this enum small. As in, no more than one word. Or pcwalton will yell at you.
#[deriving(Clone)]
pub enum SpecificFragmentInfo {
GenericFragment,
IframeFragment(Box<IframeFragmentInfo>),
ImageFragment(Box<ImageFragmentInfo>),
Generic,
Iframe(Box<IframeFragmentInfo>),
Image(Box<ImageFragmentInfo>),
/// A hypothetical box (see CSS 2.1 § 10.3.7) for an absolutely-positioned block that was
/// declared with `display: inline;`.
InlineAbsoluteHypotheticalFragment(InlineAbsoluteHypotheticalFragmentInfo),
InlineAbsoluteHypothetical(InlineAbsoluteHypotheticalFragmentInfo),
InlineBlockFragment(InlineBlockFragmentInfo),
ScannedTextFragment(Box<ScannedTextFragmentInfo>),
TableFragment,
TableCellFragment,
TableColumnFragment(TableColumnFragmentInfo),
TableRowFragment,
TableWrapperFragment,
UnscannedTextFragment(UnscannedTextFragmentInfo),
InlineBlock(InlineBlockFragmentInfo),
ScannedText(Box<ScannedTextFragmentInfo>),
Table,
TableCell,
TableColumn(TableColumnFragmentInfo),
TableRow,
TableWrapper,
UnscannedText(UnscannedTextFragmentInfo),
}
impl SpecificFragmentInfo {
fn restyle_damage(&self) -> RestyleDamage {
let flow =
match *self {
IframeFragment(_)
| ImageFragment(_)
| ScannedTextFragment(_)
| TableFragment
| TableCellFragment
| TableColumnFragment(_)
| TableRowFragment
| TableWrapperFragment
| UnscannedTextFragment(_)
| GenericFragment => return RestyleDamage::empty(),
InlineAbsoluteHypotheticalFragment(ref info) => &info.flow_ref,
InlineBlockFragment(ref info) => &info.flow_ref,
SpecificFragmentInfo::Iframe(_)
| SpecificFragmentInfo::Image(_)
| SpecificFragmentInfo::ScannedText(_)
| SpecificFragmentInfo::Table
| SpecificFragmentInfo::TableCell
| SpecificFragmentInfo::TableColumn(_)
| SpecificFragmentInfo::TableRow
| SpecificFragmentInfo::TableWrapper
| SpecificFragmentInfo::UnscannedText(_)
| SpecificFragmentInfo::Generic => return RestyleDamage::empty(),
SpecificFragmentInfo::InlineAbsoluteHypothetical(ref info) => &info.flow_ref,
SpecificFragmentInfo::InlineBlock(ref info) => &info.flow_ref,
};
flow::base(flow.deref()).restyle_damage
@ -165,18 +165,18 @@ impl SpecificFragmentInfo {
pub fn get_type(&self) -> &'static str {
match *self {
GenericFragment => "GenericFragment",
IframeFragment(_) => "IframeFragment",
ImageFragment(_) => "ImageFragment",
InlineAbsoluteHypotheticalFragment(_) => "InlineAbsoluteHypotheticalFragment",
InlineBlockFragment(_) => "InlineBlockFragment",
ScannedTextFragment(_) => "ScannedTextFragment",
TableFragment => "TableFragment",
TableCellFragment => "TableCellFragment",
TableColumnFragment(_) => "TableColumnFragment",
TableRowFragment => "TableRowFragment",
TableWrapperFragment => "TableWrapperFragment",
UnscannedTextFragment(_) => "UnscannedTextFragment",
SpecificFragmentInfo::Generic => "SpecificFragmentInfo::Generic",
SpecificFragmentInfo::Iframe(_) => "SpecificFragmentInfo::Iframe",
SpecificFragmentInfo::Image(_) => "SpecificFragmentInfo::Image",
SpecificFragmentInfo::InlineAbsoluteHypothetical(_) => "SpecificFragmentInfo::InlineAbsoluteHypothetical",
SpecificFragmentInfo::InlineBlock(_) => "SpecificFragmentInfo::InlineBlock",
SpecificFragmentInfo::ScannedText(_) => "SpecificFragmentInfo::ScannedText",
SpecificFragmentInfo::Table => "SpecificFragmentInfo::Table",
SpecificFragmentInfo::TableCell => "SpecificFragmentInfo::TableCell",
SpecificFragmentInfo::TableColumn(_) => "SpecificFragmentInfo::TableColumn",
SpecificFragmentInfo::TableRow => "SpecificFragmentInfo::TableRow",
SpecificFragmentInfo::TableWrapper => "SpecificFragmentInfo::TableWrapper",
SpecificFragmentInfo::UnscannedText(_) => "SpecificFragmentInfo::UnscannedText",
}
}
}
@ -294,14 +294,14 @@ impl ImageFragmentInfo {
dom_length: Option<Au>,
container_inline_size: Au) -> MaybeAuto {
match (MaybeAuto::from_style(style_length,container_inline_size),dom_length) {
(Specified(length),_) => {
Specified(length)
(MaybeAuto::Specified(length),_) => {
MaybeAuto::Specified(length)
},
(Auto,Some(length)) => {
Specified(length)
(MaybeAuto::Auto,Some(length)) => {
MaybeAuto::Specified(length)
},
(Auto,None) => {
Auto
(MaybeAuto::Auto,None) => {
MaybeAuto::Auto
}
}
}
@ -531,7 +531,7 @@ impl Fragment {
// Foo
// </div>
//
// Anonymous table fragments, TableRowFragment and TableCellFragment, are generated around
// Anonymous table fragments, SpecificFragmentInfo::TableRow and SpecificFragmentInfo::TableCell, are generated around
// `Foo`, but they shouldn't inherit the border.
let node_style = cascade_anonymous(&**node.style());
@ -574,11 +574,11 @@ impl Fragment {
self.margin = LogicalMargin::zero(self.style.writing_mode);
}
/// Saves the new_line_pos vector into a `ScannedTextFragment`. This will fail
/// Saves the new_line_pos vector into a `SpecificFragmentInfo::ScannedText`. This will fail
/// if called on any other type of fragment.
pub fn save_new_line_pos(&mut self) {
match &mut self.specific {
&ScannedTextFragment(ref mut info) => {
&SpecificFragmentInfo::ScannedText(ref mut info) => {
if !info.new_line_pos.is_empty() {
info.original_new_line_pos = Some(info.new_line_pos.clone());
}
@ -589,7 +589,7 @@ impl Fragment {
pub fn restore_new_line_pos(&mut self) {
match &mut self.specific {
&ScannedTextFragment(ref mut info) => {
&SpecificFragmentInfo::ScannedText(ref mut info) => {
match info.original_new_line_pos.take() {
None => {}
Some(new_line_pos) => info.new_line_pos = new_line_pos,
@ -623,7 +623,7 @@ impl Fragment {
border_box: new_border_box,
border_padding: self.border_padding,
margin: self.margin,
specific: ScannedTextFragment(info),
specific: SpecificFragmentInfo::ScannedText(info),
inline_context: self.inline_context.clone(),
debug_id: self.debug_id,
}
@ -647,25 +647,25 @@ impl Fragment {
fn quantities_included_in_intrinsic_inline_size(&self)
-> QuantitiesIncludedInIntrinsicInlineSizes {
match self.specific {
GenericFragment | IframeFragment(_) | ImageFragment(_) | InlineBlockFragment(_) => {
SpecificFragmentInfo::Generic | SpecificFragmentInfo::Iframe(_) | SpecificFragmentInfo::Image(_) | SpecificFragmentInfo::InlineBlock(_) => {
QuantitiesIncludedInIntrinsicInlineSizes::all()
}
TableFragment | TableCellFragment => {
SpecificFragmentInfo::Table | SpecificFragmentInfo::TableCell => {
INTRINSIC_INLINE_SIZE_INCLUDES_PADDING |
INTRINSIC_INLINE_SIZE_INCLUDES_BORDER |
INTRINSIC_INLINE_SIZE_INCLUDES_SPECIFIED
}
TableWrapperFragment => {
SpecificFragmentInfo::TableWrapper => {
INTRINSIC_INLINE_SIZE_INCLUDES_MARGINS |
INTRINSIC_INLINE_SIZE_INCLUDES_BORDER |
INTRINSIC_INLINE_SIZE_INCLUDES_SPECIFIED
}
TableRowFragment => {
SpecificFragmentInfo::TableRow => {
INTRINSIC_INLINE_SIZE_INCLUDES_BORDER |
INTRINSIC_INLINE_SIZE_INCLUDES_SPECIFIED
}
ScannedTextFragment(_) | TableColumnFragment(_) | UnscannedTextFragment(_) |
InlineAbsoluteHypotheticalFragment(_) => {
SpecificFragmentInfo::ScannedText(_) | SpecificFragmentInfo::TableColumn(_) | SpecificFragmentInfo::UnscannedText(_) |
SpecificFragmentInfo::InlineAbsoluteHypothetical(_) => {
QuantitiesIncludedInIntrinsicInlineSizes::empty()
}
}
@ -744,7 +744,7 @@ impl Fragment {
#[inline]
pub fn border_width(&self) -> LogicalMargin<Au> {
let style_border_width = match self.specific {
ScannedTextFragment(_) => LogicalMargin::zero(self.style.writing_mode),
SpecificFragmentInfo::ScannedText(_) => LogicalMargin::zero(self.style.writing_mode),
_ => self.style().logical_border_width(),
};
@ -764,7 +764,7 @@ impl Fragment {
/// (for example, via constraint solving for blocks).
pub fn compute_inline_direction_margins(&mut self, containing_block_inline_size: Au) {
match self.specific {
TableFragment | TableCellFragment | TableRowFragment | TableColumnFragment(_) => {
SpecificFragmentInfo::Table | SpecificFragmentInfo::TableCell | SpecificFragmentInfo::TableRow | SpecificFragmentInfo::TableColumn(_) => {
self.margin.inline_start = Au(0);
self.margin.inline_end = Au(0)
}
@ -787,7 +787,7 @@ impl Fragment {
/// (for example, via constraint solving for absolutely-positioned flows).
pub fn compute_block_direction_margins(&mut self, containing_block_inline_size: Au) {
match self.specific {
TableFragment | TableCellFragment | TableRowFragment | TableColumnFragment(_) => {
SpecificFragmentInfo::Table | SpecificFragmentInfo::TableCell | SpecificFragmentInfo::TableRow | SpecificFragmentInfo::TableColumn(_) => {
self.margin.block_start = Au(0);
self.margin.block_end = Au(0)
}
@ -814,11 +814,11 @@ impl Fragment {
// Compute padding.
let padding = match self.specific {
TableColumnFragment(_) | TableRowFragment |
TableWrapperFragment => LogicalMargin::zero(self.style.writing_mode),
SpecificFragmentInfo::TableColumn(_) | SpecificFragmentInfo::TableRow |
SpecificFragmentInfo::TableWrapper => LogicalMargin::zero(self.style.writing_mode),
_ => {
let style_padding = match self.specific {
ScannedTextFragment(_) => LogicalMargin::zero(self.style.writing_mode),
SpecificFragmentInfo::ScannedText(_) => LogicalMargin::zero(self.style.writing_mode),
_ => model::padding_from_style(self.style(), containing_block_inline_size),
};
@ -842,12 +842,12 @@ impl Fragment {
fn from_style(style: &ComputedValues, container_size: &LogicalSize<Au>)
-> LogicalSize<Au> {
let offsets = style.logical_position();
let offset_i = if offsets.inline_start != LPA_Auto {
let offset_i = if offsets.inline_start != LengthOrPercentageOrAuto::Auto {
MaybeAuto::from_style(offsets.inline_start, container_size.inline).specified_or_zero()
} else {
-MaybeAuto::from_style(offsets.inline_end, container_size.inline).specified_or_zero()
};
let offset_b = if offsets.block_start != LPA_Auto {
let offset_b = if offsets.block_start != LengthOrPercentageOrAuto::Auto {
MaybeAuto::from_style(offsets.block_start, container_size.inline).specified_or_zero()
} else {
-MaybeAuto::from_style(offsets.block_end, container_size.inline).specified_or_zero()
@ -883,9 +883,9 @@ impl Fragment {
let style = self.style();
match style.get_box().clear {
clear::none => None,
clear::left => Some(ClearLeft),
clear::right => Some(ClearRight),
clear::both => Some(ClearBoth),
clear::left => Some(ClearType::Left),
clear::right => Some(ClearType::Right),
clear::both => Some(ClearType::Both),
}
}
@ -925,9 +925,9 @@ impl Fragment {
/// inlines.
pub fn inline_start_offset(&self) -> Au {
match self.specific {
TableWrapperFragment => self.margin.inline_start,
TableFragment | TableCellFragment | TableRowFragment => self.border_padding.inline_start,
TableColumnFragment(_) => Au(0),
SpecificFragmentInfo::TableWrapper => self.margin.inline_start,
SpecificFragmentInfo::Table | SpecificFragmentInfo::TableCell | SpecificFragmentInfo::TableRow => self.border_padding.inline_start,
SpecificFragmentInfo::TableColumn(_) => Au(0),
_ => self.margin.inline_start + self.border_padding.inline_start,
}
}
@ -940,7 +940,7 @@ impl Fragment {
/// Returns the newline positions of this fragment, if it's a scanned text fragment.
pub fn newline_positions(&self) -> Option<&Vec<CharIndex>> {
match self.specific {
ScannedTextFragment(ref info) => Some(&info.new_line_pos),
SpecificFragmentInfo::ScannedText(ref info) => Some(&info.new_line_pos),
_ => None,
}
}
@ -948,7 +948,7 @@ impl Fragment {
/// Returns the newline positions of this fragment, if it's a scanned text fragment.
pub fn newline_positions_mut(&mut self) -> Option<&mut Vec<CharIndex>> {
match self.specific {
ScannedTextFragment(ref mut info) => Some(&mut info.new_line_pos),
SpecificFragmentInfo::ScannedText(ref mut info) => Some(&mut info.new_line_pos),
_ => None,
}
}
@ -956,7 +956,7 @@ impl Fragment {
/// Returns true if and only if this is a scanned text fragment.
fn is_scanned_text_fragment(&self) -> bool {
match self.specific {
ScannedTextFragment(..) => true,
SpecificFragmentInfo::ScannedText(..) => true,
_ => false,
}
}
@ -965,21 +965,21 @@ impl Fragment {
pub fn compute_intrinsic_inline_sizes(&mut self) -> IntrinsicISizesContribution {
let mut result = self.style_specified_intrinsic_inline_size();
match self.specific {
GenericFragment | IframeFragment(_) | TableFragment | TableCellFragment |
TableColumnFragment(_) | TableRowFragment | TableWrapperFragment |
InlineAbsoluteHypotheticalFragment(_) => {}
InlineBlockFragment(ref mut info) => {
SpecificFragmentInfo::Generic | SpecificFragmentInfo::Iframe(_) | SpecificFragmentInfo::Table | SpecificFragmentInfo::TableCell |
SpecificFragmentInfo::TableColumn(_) | SpecificFragmentInfo::TableRow | SpecificFragmentInfo::TableWrapper |
SpecificFragmentInfo::InlineAbsoluteHypothetical(_) => {}
SpecificFragmentInfo::InlineBlock(ref mut info) => {
let block_flow = info.flow_ref.as_block();
result.union_block(&block_flow.base.intrinsic_inline_sizes)
}
ImageFragment(ref mut image_fragment_info) => {
SpecificFragmentInfo::Image(ref mut image_fragment_info) => {
let image_inline_size = image_fragment_info.image_inline_size();
result.union_block(&IntrinsicISizes {
minimum_inline_size: image_inline_size,
preferred_inline_size: image_inline_size,
})
}
ScannedTextFragment(ref text_fragment_info) => {
SpecificFragmentInfo::ScannedText(ref text_fragment_info) => {
let range = &text_fragment_info.range;
let min_line_inline_size = text_fragment_info.run.min_width_for_range(range);
@ -994,7 +994,7 @@ impl Fragment {
preferred_inline_size: max_line_inline_size,
})
}
UnscannedTextFragment(..) => {
SpecificFragmentInfo::UnscannedText(..) => {
panic!("Unscanned text fragments should have been scanned by now!")
}
};
@ -1019,40 +1019,40 @@ impl Fragment {
}
/// TODO: What exactly does this function return? Why is it Au(0) for GenericFragment?
/// TODO: What exactly does this function return? Why is it Au(0) for SpecificFragmentInfo::Generic?
pub fn content_inline_size(&self) -> Au {
match self.specific {
GenericFragment | IframeFragment(_) | TableFragment | TableCellFragment |
TableRowFragment | TableWrapperFragment | InlineBlockFragment(_) |
InlineAbsoluteHypotheticalFragment(_) => Au(0),
ImageFragment(ref image_fragment_info) => {
SpecificFragmentInfo::Generic | SpecificFragmentInfo::Iframe(_) | SpecificFragmentInfo::Table | SpecificFragmentInfo::TableCell |
SpecificFragmentInfo::TableRow | SpecificFragmentInfo::TableWrapper | SpecificFragmentInfo::InlineBlock(_) |
SpecificFragmentInfo::InlineAbsoluteHypothetical(_) => Au(0),
SpecificFragmentInfo::Image(ref image_fragment_info) => {
image_fragment_info.computed_inline_size()
}
ScannedTextFragment(ref text_fragment_info) => {
SpecificFragmentInfo::ScannedText(ref text_fragment_info) => {
let (range, run) = (&text_fragment_info.range, &text_fragment_info.run);
let text_bounds = run.metrics_for_range(range).bounding_box;
text_bounds.size.width
}
TableColumnFragment(_) => panic!("Table column fragments do not have inline_size"),
UnscannedTextFragment(_) => panic!("Unscanned text fragments should have been scanned by now!"),
SpecificFragmentInfo::TableColumn(_) => panic!("Table column fragments do not have inline_size"),
SpecificFragmentInfo::UnscannedText(_) => panic!("Unscanned text fragments should have been scanned by now!"),
}
}
/// Returns, and computes, the block-size of this fragment.
pub fn content_block_size(&self, layout_context: &LayoutContext) -> Au {
match self.specific {
GenericFragment | IframeFragment(_) | TableFragment | TableCellFragment |
TableRowFragment | TableWrapperFragment | InlineBlockFragment(_) |
InlineAbsoluteHypotheticalFragment(_) => Au(0),
ImageFragment(ref image_fragment_info) => {
SpecificFragmentInfo::Generic | SpecificFragmentInfo::Iframe(_) | SpecificFragmentInfo::Table | SpecificFragmentInfo::TableCell |
SpecificFragmentInfo::TableRow | SpecificFragmentInfo::TableWrapper | SpecificFragmentInfo::InlineBlock(_) |
SpecificFragmentInfo::InlineAbsoluteHypothetical(_) => Au(0),
SpecificFragmentInfo::Image(ref image_fragment_info) => {
image_fragment_info.computed_block_size()
}
ScannedTextFragment(_) => {
SpecificFragmentInfo::ScannedText(_) => {
// Compute the block-size based on the line-block-size and font size.
self.calculate_line_height(layout_context)
}
TableColumnFragment(_) => panic!("Table column fragments do not have block_size"),
UnscannedTextFragment(_) => panic!("Unscanned text fragments should have been scanned by now!"),
SpecificFragmentInfo::TableColumn(_) => panic!("Table column fragments do not have block_size"),
SpecificFragmentInfo::UnscannedText(_) => panic!("Unscanned text fragments should have been scanned by now!"),
}
}
@ -1076,14 +1076,14 @@ impl Fragment {
pub fn find_split_info_by_new_line(&self)
-> Option<(SplitInfo, Option<SplitInfo>, Arc<Box<TextRun>> /* TODO(bjz): remove */)> {
match self.specific {
GenericFragment | IframeFragment(_) | ImageFragment(_) | TableFragment | TableCellFragment |
TableRowFragment | TableWrapperFragment => None,
TableColumnFragment(_) => panic!("Table column fragments do not need to split"),
UnscannedTextFragment(_) => panic!("Unscanned text fragments should have been scanned by now!"),
InlineBlockFragment(_) | InlineAbsoluteHypotheticalFragment(_) => {
SpecificFragmentInfo::Generic | SpecificFragmentInfo::Iframe(_) | SpecificFragmentInfo::Image(_) | SpecificFragmentInfo::Table | SpecificFragmentInfo::TableCell |
SpecificFragmentInfo::TableRow | SpecificFragmentInfo::TableWrapper => None,
SpecificFragmentInfo::TableColumn(_) => panic!("Table column fragments do not need to split"),
SpecificFragmentInfo::UnscannedText(_) => panic!("Unscanned text fragments should have been scanned by now!"),
SpecificFragmentInfo::InlineBlock(_) | SpecificFragmentInfo::InlineAbsoluteHypothetical(_) => {
panic!("Inline blocks or inline absolute hypothetical fragments do not get split")
}
ScannedTextFragment(ref text_fragment_info) => {
SpecificFragmentInfo::ScannedText(ref text_fragment_info) => {
let mut new_line_pos = text_fragment_info.new_line_pos.clone();
let cur_new_line_pos = new_line_pos.remove(0).unwrap();
@ -1118,14 +1118,14 @@ impl Fragment {
pub fn calculate_split_position(&self, max_inline_size: Au, starts_line: bool)
-> Option<SplitResult> {
let text_fragment_info = match self.specific {
GenericFragment | IframeFragment(_) | ImageFragment(_) | TableFragment |
TableCellFragment | TableRowFragment | TableWrapperFragment | InlineBlockFragment(_) |
InlineAbsoluteHypotheticalFragment(_) => return None,
TableColumnFragment(_) => panic!("Table column fragments do not have inline_size"),
UnscannedTextFragment(_) => {
SpecificFragmentInfo::Generic | SpecificFragmentInfo::Iframe(_) | SpecificFragmentInfo::Image(_) | SpecificFragmentInfo::Table |
SpecificFragmentInfo::TableCell | SpecificFragmentInfo::TableRow | SpecificFragmentInfo::TableWrapper | SpecificFragmentInfo::InlineBlock(_) |
SpecificFragmentInfo::InlineAbsoluteHypothetical(_) => return None,
SpecificFragmentInfo::TableColumn(_) => panic!("Table column fragments do not have inline_size"),
SpecificFragmentInfo::UnscannedText(_) => {
panic!("Unscanned text fragments should have been scanned by now!")
}
ScannedTextFragment(ref text_fragment_info) => text_fragment_info,
SpecificFragmentInfo::ScannedText(ref text_fragment_info) => text_fragment_info,
};
let mut flags = SplitOptions::empty();
@ -1152,14 +1152,14 @@ impl Fragment {
-> Option<SplitResult>
where I: Iterator<TextRunSlice<'a>> {
let text_fragment_info = match self.specific {
GenericFragment | IframeFragment(_) | ImageFragment(_) | TableFragment |
TableCellFragment | TableRowFragment | TableWrapperFragment | InlineBlockFragment(_) |
InlineAbsoluteHypotheticalFragment(_) => return None,
TableColumnFragment(_) => panic!("Table column fragments do not have inline_size"),
UnscannedTextFragment(_) => {
SpecificFragmentInfo::Generic | SpecificFragmentInfo::Iframe(_) | SpecificFragmentInfo::Image(_) | SpecificFragmentInfo::Table |
SpecificFragmentInfo::TableCell | SpecificFragmentInfo::TableRow | SpecificFragmentInfo::TableWrapper | SpecificFragmentInfo::InlineBlock(_) |
SpecificFragmentInfo::InlineAbsoluteHypothetical(_) => return None,
SpecificFragmentInfo::TableColumn(_) => panic!("Table column fragments do not have inline_size"),
SpecificFragmentInfo::UnscannedText(_) => {
panic!("Unscanned text fragments should have been scanned by now!")
}
ScannedTextFragment(ref text_fragment_info) => text_fragment_info,
SpecificFragmentInfo::ScannedText(ref text_fragment_info) => text_fragment_info,
};
let mut pieces_processed_count: uint = 0;
@ -1262,7 +1262,7 @@ impl Fragment {
white_space::normal | white_space::nowrap => {}
}
match self.specific {
UnscannedTextFragment(ref text_fragment_info) => {
SpecificFragmentInfo::UnscannedText(ref text_fragment_info) => {
is_whitespace(text_fragment_info.text.as_slice())
}
_ => false,
@ -1273,14 +1273,14 @@ impl Fragment {
/// content per CSS 2.1 § 10.3.2.
pub fn assign_replaced_inline_size_if_necessary(&mut self, container_inline_size: Au) {
match self.specific {
GenericFragment | IframeFragment(_) | TableFragment | TableCellFragment |
TableRowFragment | TableWrapperFragment => return,
TableColumnFragment(_) => panic!("Table column fragments do not have inline_size"),
UnscannedTextFragment(_) => {
SpecificFragmentInfo::Generic | SpecificFragmentInfo::Iframe(_) | SpecificFragmentInfo::Table | SpecificFragmentInfo::TableCell |
SpecificFragmentInfo::TableRow | SpecificFragmentInfo::TableWrapper => return,
SpecificFragmentInfo::TableColumn(_) => panic!("Table column fragments do not have inline_size"),
SpecificFragmentInfo::UnscannedText(_) => {
panic!("Unscanned text fragments should have been scanned by now!")
}
ImageFragment(_) | ScannedTextFragment(_) | InlineBlockFragment(_) |
InlineAbsoluteHypotheticalFragment(_) => {}
SpecificFragmentInfo::Image(_) | SpecificFragmentInfo::ScannedText(_) | SpecificFragmentInfo::InlineBlock(_) |
SpecificFragmentInfo::InlineAbsoluteHypothetical(_) => {}
};
let style_inline_size = self.style().content_inline_size();
@ -1292,7 +1292,7 @@ impl Fragment {
let noncontent_inline_size = self.border_padding.inline_start_end();
match self.specific {
InlineAbsoluteHypotheticalFragment(ref mut info) => {
SpecificFragmentInfo::InlineAbsoluteHypothetical(ref mut info) => {
let block_flow = info.flow_ref.as_block();
block_flow.base.position.size.inline =
block_flow.base.intrinsic_inline_sizes.preferred_inline_size;
@ -1300,18 +1300,18 @@ impl Fragment {
// This is a hypothetical box, so it takes up no space.
self.border_box.size.inline = Au(0);
}
InlineBlockFragment(ref mut info) => {
SpecificFragmentInfo::InlineBlock(ref mut info) => {
let block_flow = info.flow_ref.as_block();
self.border_box.size.inline =
block_flow.base.intrinsic_inline_sizes.preferred_inline_size;
block_flow.base.block_container_inline_size = self.border_box.size.inline;
}
ScannedTextFragment(ref info) => {
SpecificFragmentInfo::ScannedText(ref info) => {
// Scanned text fragments will have already had their content inline-sizes assigned
// by this point.
self.border_box.size.inline = info.content_size.inline + noncontent_inline_size
}
ImageFragment(ref mut image_fragment_info) => {
SpecificFragmentInfo::Image(ref mut image_fragment_info) => {
// TODO(ksh8281): compute border,margin
let inline_size = ImageFragmentInfo::style_length(
style_inline_size,
@ -1319,7 +1319,7 @@ impl Fragment {
container_inline_size);
let inline_size = match inline_size {
Auto => {
MaybeAuto::Auto => {
let intrinsic_width = image_fragment_info.image_inline_size();
let intrinsic_height = image_fragment_info.image_block_size();
@ -1334,8 +1334,8 @@ impl Fragment {
image_fragment_info.dom_block_size,
Au(0));
let specified_height = match specified_height {
Auto => intrinsic_height,
Specified(h) => h,
MaybeAuto::Auto => intrinsic_height,
MaybeAuto::Specified(h) => h,
};
let specified_height = ImageFragmentInfo::clamp_size(
specified_height,
@ -1345,7 +1345,7 @@ impl Fragment {
Au((specified_height.to_f32().unwrap() * ratio) as i32)
}
},
Specified(w) => w,
MaybeAuto::Specified(w) => w,
};
let inline_size = ImageFragmentInfo::clamp_size(inline_size,
@ -1366,14 +1366,14 @@ impl Fragment {
/// Ideally, this should follow CSS 2.1 § 10.6.2.
pub fn assign_replaced_block_size_if_necessary(&mut self, containing_block_block_size: Au) {
match self.specific {
GenericFragment | IframeFragment(_) | TableFragment | TableCellFragment |
TableRowFragment | TableWrapperFragment => return,
TableColumnFragment(_) => panic!("Table column fragments do not have block_size"),
UnscannedTextFragment(_) => {
SpecificFragmentInfo::Generic | SpecificFragmentInfo::Iframe(_) | SpecificFragmentInfo::Table | SpecificFragmentInfo::TableCell |
SpecificFragmentInfo::TableRow | SpecificFragmentInfo::TableWrapper => return,
SpecificFragmentInfo::TableColumn(_) => panic!("Table column fragments do not have block_size"),
SpecificFragmentInfo::UnscannedText(_) => {
panic!("Unscanned text fragments should have been scanned by now!")
}
ImageFragment(_) | ScannedTextFragment(_) | InlineBlockFragment(_) |
InlineAbsoluteHypotheticalFragment(_) => {}
SpecificFragmentInfo::Image(_) | SpecificFragmentInfo::ScannedText(_) | SpecificFragmentInfo::InlineBlock(_) |
SpecificFragmentInfo::InlineAbsoluteHypothetical(_) => {}
}
let style_block_size = self.style().content_block_size();
@ -1382,7 +1382,7 @@ impl Fragment {
let noncontent_block_size = self.border_padding.block_start_end();
match self.specific {
ImageFragment(ref mut image_fragment_info) => {
SpecificFragmentInfo::Image(ref mut image_fragment_info) => {
// TODO(ksh8281): compute border,margin,padding
let inline_size = image_fragment_info.computed_inline_size();
let block_size = ImageFragmentInfo::style_length(
@ -1391,13 +1391,13 @@ impl Fragment {
containing_block_block_size);
let block_size = match block_size {
Auto => {
MaybeAuto::Auto => {
let scale = image_fragment_info.image_inline_size().to_f32().unwrap()
/ inline_size.to_f32().unwrap();
Au((image_fragment_info.image_block_size().to_f32().unwrap() / scale)
as i32)
},
Specified(h) => {
MaybeAuto::Specified(h) => {
h
}
};
@ -1409,18 +1409,18 @@ impl Fragment {
image_fragment_info.computed_block_size = Some(block_size);
self.border_box.size.block = block_size + noncontent_block_size
}
ScannedTextFragment(ref info) => {
SpecificFragmentInfo::ScannedText(ref info) => {
// Scanned text fragments' content block-sizes are calculated by the text run
// scanner during flow construction.
self.border_box.size.block = info.content_size.block + noncontent_block_size
}
InlineBlockFragment(ref mut info) => {
SpecificFragmentInfo::InlineBlock(ref mut info) => {
// Not the primary fragment, so we do not take the noncontent size into account.
let block_flow = info.flow_ref.as_block();
self.border_box.size.block = block_flow.base.position.size.block +
block_flow.fragment.margin.block_start_end()
}
InlineAbsoluteHypotheticalFragment(ref mut info) => {
SpecificFragmentInfo::InlineAbsoluteHypothetical(ref mut info) => {
// Not the primary fragment, so we do not take the noncontent size into account.
let block_flow = info.flow_ref.as_block();
self.border_box.size.block = block_flow.base.position.size.block;
@ -1433,7 +1433,7 @@ impl Fragment {
/// used in an inline formatting context. See CSS 2.1 § 10.8.1.
pub fn inline_metrics(&self, layout_context: &LayoutContext) -> InlineMetrics {
match self.specific {
ImageFragment(ref image_fragment_info) => {
SpecificFragmentInfo::Image(ref image_fragment_info) => {
let computed_block_size = image_fragment_info.computed_block_size();
InlineMetrics {
block_size_above_baseline: computed_block_size + self.border_padding.block_start_end(),
@ -1441,12 +1441,12 @@ impl Fragment {
ascent: computed_block_size + self.border_padding.block_end,
}
}
ScannedTextFragment(ref text_fragment) => {
SpecificFragmentInfo::ScannedText(ref text_fragment) => {
// See CSS 2.1 § 10.8.1.
let line_height = self.calculate_line_height(layout_context);
InlineMetrics::from_font_metrics(&text_fragment.run.font_metrics, line_height)
}
InlineBlockFragment(ref info) => {
SpecificFragmentInfo::InlineBlock(ref info) => {
// See CSS 2.1 § 10.8.1.
let block_flow = info.flow_ref.deref().as_immutable_block();
let font_style = self.style.get_font_arc();
@ -1456,7 +1456,7 @@ impl Fragment {
block_flow.base.position.size.block +
block_flow.fragment.margin.block_start_end())
}
InlineAbsoluteHypotheticalFragment(_) => {
SpecificFragmentInfo::InlineAbsoluteHypothetical(_) => {
// Hypothetical boxes take up no space.
InlineMetrics {
block_size_above_baseline: Au(0),
@ -1477,7 +1477,7 @@ impl Fragment {
/// Returns true if this fragment is a hypothetical box. See CSS 2.1 § 10.3.7.
pub fn is_hypothetical(&self) -> bool {
match self.specific {
InlineAbsoluteHypotheticalFragment(_) => true,
SpecificFragmentInfo::InlineAbsoluteHypothetical(_) => true,
_ => false,
}
}
@ -1485,7 +1485,7 @@ impl Fragment {
/// Returns true if this fragment can merge with another adjacent fragment or false otherwise.
pub fn can_merge_with_fragment(&self, other: &Fragment) -> bool {
match (&self.specific, &other.specific) {
(&UnscannedTextFragment(_), &UnscannedTextFragment(_)) => {
(&SpecificFragmentInfo::UnscannedText(_), &SpecificFragmentInfo::UnscannedText(_)) => {
// FIXME: Should probably use a whitelist of styles that can safely differ (#3165)
self.style().get_font() == other.style().get_font() &&
self.text_decoration() == other.text_decoration() &&
@ -1506,17 +1506,17 @@ impl Fragment {
/// because the corresponding table flow is the primary fragment.
pub fn is_primary_fragment(&self) -> bool {
match self.specific {
InlineBlockFragment(_) | InlineAbsoluteHypotheticalFragment(_) |
TableWrapperFragment => false,
GenericFragment | IframeFragment(_) | ImageFragment(_) | ScannedTextFragment(_) |
TableFragment | TableCellFragment | TableColumnFragment(_) | TableRowFragment |
UnscannedTextFragment(_) => true,
SpecificFragmentInfo::InlineBlock(_) | SpecificFragmentInfo::InlineAbsoluteHypothetical(_) |
SpecificFragmentInfo::TableWrapper => false,
SpecificFragmentInfo::Generic | SpecificFragmentInfo::Iframe(_) | SpecificFragmentInfo::Image(_) | SpecificFragmentInfo::ScannedText(_) |
SpecificFragmentInfo::Table | SpecificFragmentInfo::TableCell | SpecificFragmentInfo::TableColumn(_) | SpecificFragmentInfo::TableRow |
SpecificFragmentInfo::UnscannedText(_) => true,
}
}
pub fn update_late_computed_inline_position_if_necessary(&mut self) {
match self.specific {
InlineAbsoluteHypotheticalFragment(ref mut info) => {
SpecificFragmentInfo::InlineAbsoluteHypothetical(ref mut info) => {
let position = self.border_box.start.i;
info.flow_ref.update_late_computed_inline_position_if_necessary(position)
}
@ -1526,7 +1526,7 @@ impl Fragment {
pub fn update_late_computed_block_position_if_necessary(&mut self) {
match self.specific {
InlineAbsoluteHypotheticalFragment(ref mut info) => {
SpecificFragmentInfo::InlineAbsoluteHypothetical(ref mut info) => {
let position = self.border_box.start.b;
info.flow_ref.update_late_computed_block_position_if_necessary(position)
}

View file

@ -6,13 +6,13 @@
use css::node_style::StyledNode;
use context::LayoutContext;
use display_list_builder::{ContentLevel, DisplayListResult, FragmentDisplayListBuilding};
use floats::{FloatLeft, Floats, PlacementInfo};
use flow::{BaseFlow, FlowClass, Flow, ForceNonfloated, InlineFlowClass, MutableFlowUtils};
use display_list_builder::{BackgroundAndBorderLevel, DisplayListBuildingResult, FragmentDisplayListBuilding};
use floats::{FloatKind, Floats, PlacementInfo};
use flow::{BaseFlow, FlowClass, Flow, MutableFlowUtils, ForceNonfloatedFlag};
use flow::{IS_ABSOLUTELY_POSITIONED};
use flow;
use fragment::{Fragment, InlineAbsoluteHypotheticalFragment, InlineBlockFragment};
use fragment::{FragmentBoundsIterator, ScannedTextFragment, ScannedTextFragmentInfo};
use fragment::{Fragment, SpecificFragmentInfo};
use fragment::{FragmentBoundsIterator, ScannedTextFragmentInfo};
use fragment::SplitInfo;
use incremental::{REFLOW, REFLOW_OUT_OF_FLOW};
use layout_debug;
@ -345,8 +345,8 @@ impl LineBreaker {
};
let need_to_merge = match (&mut result.specific, &candidate.specific) {
(&ScannedTextFragment(ref mut result_info),
&ScannedTextFragment(ref candidate_info))
(&SpecificFragmentInfo::ScannedText(ref mut result_info),
&SpecificFragmentInfo::ScannedText(ref candidate_info))
if arc_ptr_eq(&result_info.run, &candidate_info.run) &&
result_info.range.end() + CharIndex(1) == candidate_info.range.begin() => {
// We found a previously-broken fragment. Merge it up.
@ -412,7 +412,7 @@ impl LineBreaker {
first_fragment.border_box.size.block),
ceiling: ceiling,
max_inline_size: flow.base.position.size.inline,
kind: FloatLeft,
kind: FloatKind::Left,
});
// Simple case: if the fragment fits, then we can stop here.
@ -744,7 +744,7 @@ pub struct InlineFlow {
impl InlineFlow {
pub fn from_fragments(fragments: InlineFragments, writing_mode: WritingMode) -> InlineFlow {
InlineFlow {
base: BaseFlow::new(None, writing_mode, ForceNonfloated),
base: BaseFlow::new(None, writing_mode, ForceNonfloatedFlag::ForceNonfloated),
fragments: fragments,
lines: Vec::new(),
minimum_block_size_above_baseline: Au(0),
@ -946,7 +946,7 @@ impl InlineFlow {
impl Flow for InlineFlow {
fn class(&self) -> FlowClass {
InlineFlowClass
FlowClass::Inline
}
fn as_immutable_inline<'a>(&'a self) -> &'a InlineFlow {
@ -1188,7 +1188,7 @@ impl Flow for InlineFlow {
fn compute_absolute_position(&mut self) {
for fragment in self.fragments.fragments.iter_mut() {
let stacking_relative_position = match fragment.specific {
InlineBlockFragment(ref mut info) => {
SpecificFragmentInfo::InlineBlock(ref mut info) => {
let block_flow = info.flow_ref.as_block();
block_flow.base.absolute_position_info = self.base.absolute_position_info;
@ -1200,7 +1200,7 @@ impl Flow for InlineFlow {
container_size);
block_flow.base.stacking_relative_position
}
InlineAbsoluteHypotheticalFragment(ref mut info) => {
SpecificFragmentInfo::InlineAbsoluteHypothetical(ref mut info) => {
let block_flow = info.flow_ref.as_block();
block_flow.base.absolute_position_info = self.base.absolute_position_info;
@ -1220,10 +1220,10 @@ impl Flow for InlineFlow {
stacking_relative_position);
match fragment.specific {
InlineBlockFragment(ref mut info) => {
SpecificFragmentInfo::InlineBlock(ref mut info) => {
flow::mut_base(info.flow_ref.deref_mut()).clip_rect = clip_rect
}
InlineAbsoluteHypotheticalFragment(ref mut info) => {
SpecificFragmentInfo::InlineAbsoluteHypothetical(ref mut info) => {
flow::mut_base(info.flow_ref.deref_mut()).clip_rect = clip_rect
}
_ => {}
@ -1246,15 +1246,15 @@ impl Flow for InlineFlow {
fragment.build_display_list(&mut *display_list,
layout_context,
fragment_origin,
ContentLevel,
BackgroundAndBorderLevel::Content,
&self.base.clip_rect);
match fragment.specific {
InlineBlockFragment(ref mut block_flow) => {
SpecificFragmentInfo::InlineBlock(ref mut block_flow) => {
let block_flow = block_flow.flow_ref.deref_mut();
flow::mut_base(block_flow).display_list_building_result
.add_to(&mut *display_list)
}
InlineAbsoluteHypotheticalFragment(ref mut block_flow) => {
SpecificFragmentInfo::InlineAbsoluteHypothetical(ref mut block_flow) => {
let block_flow = block_flow.flow_ref.deref_mut();
flow::mut_base(block_flow).display_list_building_result
.add_to(&mut *display_list)
@ -1263,7 +1263,7 @@ impl Flow for InlineFlow {
}
}
self.base.display_list_building_result = DisplayListResult(display_list);
self.base.display_list_building_result = DisplayListBuildingResult::Normal(display_list);
if opts::get().validate_display_list_geometry {
self.base.validate_display_list_geometry();

View file

@ -6,7 +6,7 @@
//! painted.
use css::node_style::StyledNode;
use construct::FlowConstructionResult;
use construct::ConstructionResult;
use context::SharedLayoutContext;
use flow::{mod, Flow, ImmutableFlowUtils, MutableFlowUtils, MutableOwnedFlowUtils};
use flow_ref::FlowRef;
@ -33,8 +33,8 @@ use layout_traits;
use layout_traits::{LayoutControlMsg, LayoutTaskFactory};
use log;
use script::dom::bindings::js::JS;
use script::dom::node::{ElementNodeTypeId, LayoutDataRef, Node};
use script::dom::element::{HTMLBodyElementTypeId, HTMLHtmlElementTypeId};
use script::dom::node::{LayoutDataRef, Node, NodeTypeId};
use script::dom::element::ElementTypeId;
use script::layout_interface::{AddStylesheetMsg, ContentBoxResponse, ContentBoxesResponse};
use script::layout_interface::{ContentBoxesQuery, ContentBoxQuery, ExitNowMsg, GetRPCMsg};
use script::layout_interface::{HitTestResponse, LayoutChan, LayoutRPC, LoadStylesheetMsg};
@ -54,15 +54,15 @@ use servo_util::opts;
use servo_util::smallvec::{SmallVec, SmallVec1, VecLike};
use servo_util::task::spawn_named_with_send_on_failure;
use servo_util::task_state;
use servo_util::time::{TimeProfilerChan, profile, TimeRootWindow, TimeIFrame, TimeIncremental, TimeFirstReflow};
use servo_util::time::{TimeProfilerChan, profile, TimerMetadataFrameType, TimerMetadataReflowType};
use servo_util::time;
use servo_util::workqueue::WorkQueue;
use std::cell::Cell;
use std::comm::{channel, Sender, Receiver, Select};
use std::mem;
use std::ptr;
use style::{AuthorOrigin, Stylesheet, Stylist, TNode, iter_font_face_rules};
use style::{Device, Screen};
use style::{StylesheetOrigin, Stylesheet, Stylist, TNode, iter_font_face_rules};
use style::{MediaType, Device};
use sync::{Arc, Mutex, MutexGuard};
use url::Url;
@ -217,8 +217,8 @@ enum RWGuard<'a> {
impl<'a> Deref<LayoutTaskData> for RWGuard<'a> {
fn deref(&self) -> &LayoutTaskData {
match *self {
Held(ref x) => x.deref(),
Used(ref x) => x.deref(),
RWGuard::Held(ref x) => x.deref(),
RWGuard::Used(ref x) => x.deref(),
}
}
}
@ -226,8 +226,8 @@ impl<'a> Deref<LayoutTaskData> for RWGuard<'a> {
impl<'a> DerefMut<LayoutTaskData> for RWGuard<'a> {
fn deref_mut(&mut self) -> &mut LayoutTaskData {
match *self {
Held(ref mut x) => x.deref_mut(),
Used(ref mut x) => x.deref_mut(),
RWGuard::Held(ref mut x) => x.deref_mut(),
RWGuard::Used(ref mut x) => x.deref_mut(),
}
}
}
@ -249,7 +249,7 @@ impl LayoutTask {
let local_image_cache =
Arc::new(Mutex::new(LocalImageCache::new(image_cache_task.clone())));
let screen_size = Size2D(Au(0), Au(0));
let device = Device::new(Screen, opts::get().initial_window_size.as_f32() * ScaleFactor(1.0));
let device = Device::new(MediaType::Screen, opts::get().initial_window_size.as_f32() * ScaleFactor(1.0));
let parallel_traversal = if opts::get().layout_threads != 1 {
Some(WorkQueue::new("LayoutWorker", task_state::LAYOUT,
opts::get().layout_threads, ptr::null()))
@ -332,23 +332,23 @@ impl LayoutTask {
}
let ret = sel.wait();
if ret == port1.id() {
Script
PortToRead::Script
} else if ret == port2.id() {
Pipeline
PortToRead::Pipeline
} else {
panic!("invalid select result");
}
};
match port_to_read {
Pipeline => {
PortToRead::Pipeline => {
match self.pipeline_port.recv() {
layout_traits::ExitNowMsg => {
self.handle_script_request(ExitNowMsg, possibly_locked_rw_data)
}
}
},
Script => {
PortToRead::Script => {
let msg = self.port.recv();
self.handle_script_request(msg, possibly_locked_rw_data)
}
@ -365,8 +365,8 @@ impl LayoutTask {
possibly_locked_rw_data: &mut Option<MutexGuard<'a, LayoutTaskData>>)
-> RWGuard<'a> {
match possibly_locked_rw_data.take() {
None => Used(self.rw_data.lock()),
Some(x) => Held(x),
None => RWGuard::Used(self.rw_data.lock()),
Some(x) => RWGuard::Held(x),
}
}
@ -376,8 +376,8 @@ impl LayoutTask {
fn return_rw_data<'a>(possibly_locked_rw_data: &mut Option<MutexGuard<'a, LayoutTaskData>>,
rw_data: RWGuard<'a>) {
match rw_data {
Used(x) => drop(x),
Held(x) => *possibly_locked_rw_data = Some(x),
RWGuard::Used(x) => drop(x),
RWGuard::Held(x) => *possibly_locked_rw_data = Some(x),
}
}
@ -398,8 +398,8 @@ impl LayoutTask {
ReflowMsg(data) => {
profile(time::LayoutPerformCategory,
Some((&data.url,
if data.iframe { TimeIFrame } else { TimeRootWindow },
if self.first_reflow.get() { TimeFirstReflow } else { TimeIncremental })),
if data.iframe { TimerMetadataFrameType::IFrame } else { TimerMetadataFrameType::RootWindow },
if self.first_reflow.get() { TimerMetadataReflowType::FirstReflow } else { TimerMetadataReflowType::Incremental })),
self.time_profiler_chan.clone(),
|| self.handle_reflow(&*data, possibly_locked_rw_data));
},
@ -483,7 +483,7 @@ impl LayoutTask {
final_url,
protocol_encoding_label,
Some(environment_encoding),
AuthorOrigin);
StylesheetOrigin::Author);
self.handle_add_stylesheet(sheet, possibly_locked_rw_data);
}
@ -522,7 +522,7 @@ impl LayoutTask {
let result = layout_data.data.flow_construction_result.swap_out();
let mut flow = match result {
FlowConstructionResult(mut flow, abs_descendants) => {
ConstructionResult::Flow(mut flow, abs_descendants) => {
// Note: Assuming that the root has display 'static' (as per
// CSS Section 9.3.1). Otherwise, if it were absolutely
// positioned, it would return a reference to itself in
@ -574,8 +574,8 @@ impl LayoutTask {
// operation out.
parallel::traverse_flow_tree_preorder(layout_root,
&data.url,
if data.iframe { TimeIFrame } else { TimeRootWindow },
if self.first_reflow.get() { TimeFirstReflow } else { TimeIncremental },
if data.iframe { TimerMetadataFrameType::IFrame } else { TimerMetadataFrameType::RootWindow },
if self.first_reflow.get() { TimerMetadataReflowType::FirstReflow } else { TimerMetadataReflowType::Incremental },
self.time_profiler_chan.clone(),
shared_layout_context,
traversal);
@ -629,8 +629,8 @@ impl LayoutTask {
let writing_mode = flow::base(&**layout_root).writing_mode;
profile(time::LayoutDispListBuildCategory,
Some((&data.url,
if data.iframe { TimeIFrame } else { TimeRootWindow },
if self.first_reflow.get() { TimeFirstReflow } else { TimeIncremental })),
if data.iframe { TimerMetadataFrameType::IFrame } else { TimerMetadataFrameType::RootWindow },
if self.first_reflow.get() { TimerMetadataReflowType::FirstReflow } else { TimerMetadataReflowType::Incremental })),
self.time_profiler_chan.clone(),
|| {
shared_layout_ctx.dirty =
@ -650,8 +650,8 @@ impl LayoutTask {
Some(ref mut traversal) => {
parallel::build_display_list_for_subtree(layout_root,
&data.url,
if data.iframe { TimeIFrame } else { TimeRootWindow },
if self.first_reflow.get() { TimeFirstReflow } else { TimeIncremental },
if data.iframe { TimerMetadataFrameType::IFrame } else { TimerMetadataFrameType::RootWindow },
if self.first_reflow.get() { TimerMetadataReflowType::FirstReflow } else { TimerMetadataReflowType::Incremental },
self.time_profiler_chan.clone(),
shared_layout_ctx,
traversal);
@ -664,8 +664,8 @@ impl LayoutTask {
// it with extreme prejudice.
let mut color = color::rgba(1.0, 1.0, 1.0, 1.0);
for child in node.traverse_preorder() {
if child.type_id() == Some(ElementNodeTypeId(HTMLHtmlElementTypeId)) ||
child.type_id() == Some(ElementNodeTypeId(HTMLBodyElementTypeId)) {
if child.type_id() == Some(NodeTypeId::Element(ElementTypeId::HTMLHtmlElement)) ||
child.type_id() == Some(NodeTypeId::Element(ElementTypeId::HTMLBodyElement)) {
let element_bg_color = {
let thread_safe_child = ThreadSafeLayoutNode::new(&child);
thread_safe_child.style()
@ -754,7 +754,7 @@ impl LayoutTask {
let screen_size_changed = current_screen_size != old_screen_size;
if screen_size_changed {
let device = Device::new(Screen, data.window_size.initial_viewport);
let device = Device::new(MediaType::Screen, data.window_size.initial_viewport);
rw_data.stylist.set_device(device);
}
@ -776,8 +776,8 @@ impl LayoutTask {
let mut layout_root = profile(time::LayoutStyleRecalcCategory,
Some((&data.url,
if data.iframe { TimeIFrame } else { TimeRootWindow },
if self.first_reflow.get() { TimeFirstReflow } else { TimeIncremental })),
if data.iframe { TimerMetadataFrameType::IFrame } else { TimerMetadataFrameType::RootWindow },
if self.first_reflow.get() { TimerMetadataReflowType::FirstReflow } else { TimerMetadataReflowType::Incremental })),
self.time_profiler_chan.clone(),
|| {
// Perform CSS selector matching and flow construction.
@ -796,8 +796,8 @@ impl LayoutTask {
profile(time::LayoutRestyleDamagePropagation,
Some((&data.url,
if data.iframe { TimeIFrame } else { TimeRootWindow },
if self.first_reflow.get() { TimeFirstReflow } else { TimeIncremental })),
if data.iframe { TimerMetadataFrameType::IFrame } else { TimerMetadataFrameType::RootWindow },
if self.first_reflow.get() { TimerMetadataReflowType::FirstReflow } else { TimerMetadataReflowType::Incremental })),
self.time_profiler_chan.clone(),
|| {
if opts::get().nonincremental_layout ||
@ -819,8 +819,8 @@ impl LayoutTask {
// the boxes.
profile(time::LayoutMainCategory,
Some((&data.url,
if data.iframe { TimeIFrame } else { TimeRootWindow },
if self.first_reflow.get() { TimeFirstReflow } else { TimeIncremental })),
if data.iframe { TimerMetadataFrameType::IFrame } else { TimerMetadataFrameType::RootWindow },
if self.first_reflow.get() { TimerMetadataReflowType::FirstReflow } else { TimerMetadataReflowType::Incremental })),
self.time_profiler_chan.clone(),
|| {
let rw_data = rw_data.deref_mut();

View file

@ -11,7 +11,7 @@ use block::BlockFlow;
use construct::FlowConstructor;
use context::LayoutContext;
use display_list_builder::ListItemFlowDisplayListBuilding;
use flow::{Flow, FlowClass, ListItemFlowClass};
use flow::{Flow, FlowClass};
use fragment::{Fragment, FragmentBoundsIterator};
use wrapper::ThreadSafeLayoutNode;
@ -46,7 +46,7 @@ impl ListItemFlow {
impl Flow for ListItemFlow {
fn class(&self) -> FlowClass {
ListItemFlowClass
FlowClass::ListItem
}
fn as_block<'a>(&'a mut self) -> &'a mut BlockFlow {

View file

@ -10,7 +10,7 @@ use fragment::Fragment;
use style::computed_values as computed;
use geom::SideOffsets2D;
use style::computed_values::{LPA_Auto, LPA_Length, LPA_Percentage, LP_Length, LP_Percentage};
use style::computed_values::{LengthOrPercentageOrAuto, LengthOrPercentage};
use style::ComputedValues;
use servo_util::geometry::Au;
use servo_util::logical_geometry::LogicalMargin;
@ -62,26 +62,26 @@ impl AdjoiningMargins {
/// Represents the block-start and block-end margins of a flow with collapsible margins. See CSS 2.1 § 8.3.1.
pub enum CollapsibleMargins {
/// Margins may not collapse with this flow.
NoCollapsibleMargins(Au, Au),
None(Au, Au),
/// Both the block-start and block-end margins (specified here in that order) may collapse, but the
/// margins do not collapse through this flow.
MarginsCollapse(AdjoiningMargins, AdjoiningMargins),
Collapse(AdjoiningMargins, AdjoiningMargins),
/// Margins collapse *through* this flow. This means, essentially, that the flow doesnt
/// have any border, padding, or out-of-flow (floating or positioned) content
MarginsCollapseThrough(AdjoiningMargins),
CollapseThrough(AdjoiningMargins),
}
impl CollapsibleMargins {
pub fn new() -> CollapsibleMargins {
NoCollapsibleMargins(Au(0), Au(0))
CollapsibleMargins::None(Au(0), Au(0))
}
}
enum FinalMarginState {
MarginsCollapseThroughFinalMarginState,
BottomMarginCollapsesFinalMarginState,
MarginsCollapseThrough,
BottomMarginCollapses,
}
pub struct MarginCollapseInfo {
@ -94,7 +94,7 @@ impl MarginCollapseInfo {
/// TODO(#2012, pcwalton): Remove this method once `fragment` is not an `Option`.
pub fn new() -> MarginCollapseInfo {
MarginCollapseInfo {
state: AccumulatingCollapsibleTopMargin,
state: MarginCollapseState::AccumulatingCollapsibleTopMargin,
block_start_margin: AdjoiningMargins::new(),
margin_in: AdjoiningMargins::new(),
}
@ -104,7 +104,7 @@ impl MarginCollapseInfo {
fragment: &Fragment,
can_collapse_block_start_margin_with_kids: bool) {
if !can_collapse_block_start_margin_with_kids {
self.state = AccumulatingMarginIn
self.state = MarginCollapseState::AccumulatingMarginIn
}
self.block_start_margin = AdjoiningMargins::from_margin(fragment.margin.block_start)
@ -115,28 +115,28 @@ impl MarginCollapseInfo {
can_collapse_block_end_margin_with_kids: bool)
-> (CollapsibleMargins, Au) {
let state = match self.state {
AccumulatingCollapsibleTopMargin => {
MarginCollapseState::AccumulatingCollapsibleTopMargin => {
match fragment.style().content_block_size() {
LPA_Auto | LPA_Length(Au(0)) | LPA_Percentage(0.) => {
LengthOrPercentageOrAuto::Auto | LengthOrPercentageOrAuto::Length(Au(0)) | LengthOrPercentageOrAuto::Percentage(0.) => {
match fragment.style().min_block_size() {
LP_Length(Au(0)) | LP_Percentage(0.) => {
MarginsCollapseThroughFinalMarginState
LengthOrPercentage::Length(Au(0)) | LengthOrPercentage::Percentage(0.) => {
FinalMarginState::MarginsCollapseThrough
},
_ => {
// If the fragment has non-zero min-block-size, margins may not
// collapse through it.
BottomMarginCollapsesFinalMarginState
FinalMarginState::BottomMarginCollapses
}
}
},
_ => {
// If the fragment has an explicitly specified block-size, margins may not
// collapse through it.
BottomMarginCollapsesFinalMarginState
FinalMarginState::BottomMarginCollapses
}
}
}
AccumulatingMarginIn => BottomMarginCollapsesFinalMarginState,
MarginCollapseState::AccumulatingMarginIn => FinalMarginState::BottomMarginCollapses,
};
// Different logic is needed here depending on whether this flow can collapse its block-end
@ -144,26 +144,26 @@ impl MarginCollapseInfo {
let block_end_margin = fragment.margin.block_end;
if !can_collapse_block_end_margin_with_kids {
match state {
MarginsCollapseThroughFinalMarginState => {
FinalMarginState::MarginsCollapseThrough => {
let advance = self.block_start_margin.collapse();
self.margin_in.union(AdjoiningMargins::from_margin(block_end_margin));
(MarginsCollapse(self.block_start_margin, self.margin_in), advance)
(CollapsibleMargins::Collapse(self.block_start_margin, self.margin_in), advance)
}
BottomMarginCollapsesFinalMarginState => {
FinalMarginState::BottomMarginCollapses => {
let advance = self.margin_in.collapse();
self.margin_in.union(AdjoiningMargins::from_margin(block_end_margin));
(MarginsCollapse(self.block_start_margin, self.margin_in), advance)
(CollapsibleMargins::Collapse(self.block_start_margin, self.margin_in), advance)
}
}
} else {
match state {
MarginsCollapseThroughFinalMarginState => {
FinalMarginState::MarginsCollapseThrough => {
self.block_start_margin.union(AdjoiningMargins::from_margin(block_end_margin));
(MarginsCollapseThrough(self.block_start_margin), Au(0))
(CollapsibleMargins::CollapseThrough(self.block_start_margin), Au(0))
}
BottomMarginCollapsesFinalMarginState => {
FinalMarginState::BottomMarginCollapses => {
self.margin_in.union(AdjoiningMargins::from_margin(block_end_margin));
(MarginsCollapse(self.block_start_margin, self.margin_in), Au(0))
(CollapsibleMargins::Collapse(self.block_start_margin, self.margin_in), Au(0))
}
}
}
@ -171,8 +171,8 @@ impl MarginCollapseInfo {
pub fn current_float_ceiling(&mut self) -> Au {
match self.state {
AccumulatingCollapsibleTopMargin => self.block_start_margin.collapse(),
AccumulatingMarginIn => self.margin_in.collapse(),
MarginCollapseState::AccumulatingCollapsibleTopMargin => self.block_start_margin.collapse(),
MarginCollapseState::AccumulatingMarginIn => self.margin_in.collapse(),
}
}
@ -181,27 +181,27 @@ impl MarginCollapseInfo {
/// that should be added to the Y offset during block layout.
pub fn advance_block_start_margin(&mut self, child_collapsible_margins: &CollapsibleMargins) -> Au {
match (self.state, *child_collapsible_margins) {
(AccumulatingCollapsibleTopMargin, NoCollapsibleMargins(block_start, _)) => {
self.state = AccumulatingMarginIn;
(MarginCollapseState::AccumulatingCollapsibleTopMargin, CollapsibleMargins::None(block_start, _)) => {
self.state = MarginCollapseState::AccumulatingMarginIn;
block_start
}
(AccumulatingCollapsibleTopMargin, MarginsCollapse(block_start, _)) => {
(MarginCollapseState::AccumulatingCollapsibleTopMargin, CollapsibleMargins::Collapse(block_start, _)) => {
self.block_start_margin.union(block_start);
self.state = AccumulatingMarginIn;
self.state = MarginCollapseState::AccumulatingMarginIn;
Au(0)
}
(AccumulatingMarginIn, NoCollapsibleMargins(block_start, _)) => {
(MarginCollapseState::AccumulatingMarginIn, CollapsibleMargins::None(block_start, _)) => {
let previous_margin_value = self.margin_in.collapse();
self.margin_in = AdjoiningMargins::new();
previous_margin_value + block_start
}
(AccumulatingMarginIn, MarginsCollapse(block_start, _)) => {
(MarginCollapseState::AccumulatingMarginIn, CollapsibleMargins::Collapse(block_start, _)) => {
self.margin_in.union(block_start);
let margin_value = self.margin_in.collapse();
self.margin_in = AdjoiningMargins::new();
margin_value
}
(_, MarginsCollapseThrough(_)) => {
(_, CollapsibleMargins::CollapseThrough(_)) => {
// For now, we ignore this; this will be handled by `advance_block-end_margin` below.
Au(0)
}
@ -213,23 +213,23 @@ impl MarginCollapseInfo {
/// that should be added to the Y offset during block layout.
pub fn advance_block_end_margin(&mut self, child_collapsible_margins: &CollapsibleMargins) -> Au {
match (self.state, *child_collapsible_margins) {
(AccumulatingCollapsibleTopMargin, NoCollapsibleMargins(..)) |
(AccumulatingCollapsibleTopMargin, MarginsCollapse(..)) => {
(MarginCollapseState::AccumulatingCollapsibleTopMargin, CollapsibleMargins::None(..)) |
(MarginCollapseState::AccumulatingCollapsibleTopMargin, CollapsibleMargins::Collapse(..)) => {
// Can't happen because the state will have been replaced with
// `AccumulatingMarginIn` above.
// `MarginCollapseState::AccumulatingMarginIn` above.
panic!("should not be accumulating collapsible block_start margins anymore!")
}
(AccumulatingCollapsibleTopMargin, MarginsCollapseThrough(margin)) => {
(MarginCollapseState::AccumulatingCollapsibleTopMargin, CollapsibleMargins::CollapseThrough(margin)) => {
self.block_start_margin.union(margin);
Au(0)
}
(AccumulatingMarginIn, NoCollapsibleMargins(_, block_end)) => {
(MarginCollapseState::AccumulatingMarginIn, CollapsibleMargins::None(_, block_end)) => {
assert_eq!(self.margin_in.most_positive, Au(0));
assert_eq!(self.margin_in.most_negative, Au(0));
block_end
}
(AccumulatingMarginIn, MarginsCollapse(_, block_end)) |
(AccumulatingMarginIn, MarginsCollapseThrough(block_end)) => {
(MarginCollapseState::AccumulatingMarginIn, CollapsibleMargins::Collapse(_, block_end)) |
(MarginCollapseState::AccumulatingMarginIn, CollapsibleMargins::CollapseThrough(block_end)) => {
self.margin_in.union(block_end);
Au(0)
}
@ -333,19 +333,19 @@ impl MaybeAuto {
pub fn from_style(length: computed::LengthOrPercentageOrAuto, containing_length: Au)
-> MaybeAuto {
match length {
computed::LPA_Auto => Auto,
computed::LPA_Percentage(percent) => {
Specified(containing_length.scale_by(percent))
computed::LengthOrPercentageOrAuto::Auto => MaybeAuto::Auto,
computed::LengthOrPercentageOrAuto::Percentage(percent) => {
MaybeAuto::Specified(containing_length.scale_by(percent))
}
computed::LPA_Length(length) => Specified(length)
computed::LengthOrPercentageOrAuto::Length(length) => MaybeAuto::Specified(length)
}
}
#[inline]
pub fn specified_or_default(&self, default: Au) -> Au {
match *self {
Auto => default,
Specified(value) => value,
MaybeAuto::Auto => default,
MaybeAuto::Specified(value) => value,
}
}
@ -357,24 +357,24 @@ impl MaybeAuto {
#[inline]
pub fn map(&self, mapper: |Au| -> Au) -> MaybeAuto {
match *self {
Auto => Auto,
Specified(value) => Specified(mapper(value)),
MaybeAuto::Auto => MaybeAuto::Auto,
MaybeAuto::Specified(value) => MaybeAuto::Specified(mapper(value)),
}
}
}
pub fn specified_or_none(length: computed::LengthOrPercentageOrNone, containing_length: Au) -> Option<Au> {
match length {
computed::LPN_None => None,
computed::LPN_Percentage(percent) => Some(containing_length.scale_by(percent)),
computed::LPN_Length(length) => Some(length),
computed::LengthOrPercentageOrNone::None => None,
computed::LengthOrPercentageOrNone::Percentage(percent) => Some(containing_length.scale_by(percent)),
computed::LengthOrPercentageOrNone::Length(length) => Some(length),
}
}
pub fn specified(length: computed::LengthOrPercentage, containing_length: Au) -> Au {
match length {
computed::LP_Length(length) => length,
computed::LP_Percentage(p) => containing_length.scale_by(p)
computed::LengthOrPercentage::Length(length) => length,
computed::LengthOrPercentage::Percentage(p) => containing_length.scale_by(p)
}
}

View file

@ -6,18 +6,18 @@
#![deny(unsafe_blocks)]
use block::{BlockFlow, MarginsMayNotCollapse, ISizeAndMarginsComputer};
use block::{BlockFlow, ISizeAndMarginsComputer, MarginsMayCollapseFlag};
use block::{ISizeConstraintInput, ISizeConstraintSolution};
use construct::FlowConstructor;
use context::LayoutContext;
use floats::FloatKind;
use flow::{mod, Flow, FlowClass, IMPACTED_BY_LEFT_FLOATS, IMPACTED_BY_RIGHT_FLOATS};
use flow::{ImmutableFlowUtils, TableFlowClass};
use flow::ImmutableFlowUtils;
use fragment::{Fragment, FragmentBoundsIterator};
use layout_debug;
use model::{IntrinsicISizes, IntrinsicISizesContribution};
use table_row::CellIntrinsicInlineSize;
use table_wrapper::{TableLayout, FixedLayout, AutoLayout};
use table_wrapper::TableLayout;
use wrapper::ThreadSafeLayoutNode;
use servo_util::geometry::Au;
@ -25,7 +25,7 @@ use servo_util::logical_geometry::LogicalRect;
use std::cmp::max;
use std::fmt;
use style::{ComputedValues, CSSFloat};
use style::computed_values::{LPA_Auto, LPA_Length, LPA_Percentage, table_layout};
use style::computed_values::{LengthOrPercentageOrAuto, table_layout};
use sync::Arc;
/// A table flow corresponded to the table's internal table fragment under a table wrapper flow.
@ -54,9 +54,9 @@ impl 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::fixed {
FixedLayout
TableLayout::Fixed
} else {
AutoLayout
TableLayout::Auto
};
TableFlow {
block_flow: block_flow,
@ -72,9 +72,9 @@ impl TableFlow {
let mut block_flow = BlockFlow::from_node(constructor, node);
let table_layout = if block_flow.fragment().style().get_table().table_layout ==
table_layout::fixed {
FixedLayout
TableLayout::Fixed
} else {
AutoLayout
TableLayout::Auto
};
TableFlow {
block_flow: block_flow,
@ -91,9 +91,9 @@ impl 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::fixed {
FixedLayout
TableLayout::Fixed
} else {
AutoLayout
TableLayout::Auto
};
TableFlow {
block_flow: block_flow,
@ -164,7 +164,7 @@ impl TableFlow {
/// methods
#[inline(always)]
fn assign_block_size_table_base<'a>(&mut self, layout_context: &'a LayoutContext<'a>) {
self.block_flow.assign_block_size_block_base(layout_context, MarginsMayNotCollapse);
self.block_flow.assign_block_size_block_base(layout_context, MarginsMayCollapseFlag::MarginsMayNotCollapse);
}
/// Updates the minimum and preferred inline-size calculation for a single row. This is
@ -181,7 +181,7 @@ impl TableFlow {
debug_assert!(child.is_table_row());
let row = child.as_table_row();
match table_layout {
FixedLayout => {
TableLayout::Fixed => {
// Fixed table layout only looks at the first row.
//
// FIXME(pcwalton): This is really inefficient. We should stop after the first row!
@ -192,7 +192,7 @@ impl TableFlow {
}
}
}
AutoLayout => {
TableLayout::Auto => {
computation.union_block(&TableFlow::update_automatic_column_inline_sizes(
column_inline_sizes,
row.cell_intrinsic_inline_sizes.as_slice()))
@ -203,7 +203,7 @@ impl TableFlow {
impl Flow for TableFlow {
fn class(&self) -> FlowClass {
TableFlowClass
FlowClass::Table
}
fn as_table<'a>(&'a mut self) -> &'a mut TableFlow {
@ -242,12 +242,12 @@ impl Flow for TableFlow {
for specified_inline_size in kid.as_table_colgroup().inline_sizes.iter() {
self.column_intrinsic_inline_sizes.push(ColumnIntrinsicInlineSize {
minimum_length: match *specified_inline_size {
LPA_Auto | LPA_Percentage(_) => Au(0),
LPA_Length(length) => length,
LengthOrPercentageOrAuto::Auto | LengthOrPercentageOrAuto::Percentage(_) => Au(0),
LengthOrPercentageOrAuto::Length(length) => length,
},
percentage: match *specified_inline_size {
LPA_Auto | LPA_Length(_) => 0.0,
LPA_Percentage(percentage) => percentage,
LengthOrPercentageOrAuto::Auto | LengthOrPercentageOrAuto::Length(_) => 0.0,
LengthOrPercentageOrAuto::Percentage(percentage) => percentage,
},
preferred: Au(0),
constrained: false,
@ -308,7 +308,7 @@ impl Flow for TableFlow {
self.block_flow.fragment.border_box.size.inline - padding_and_borders;
match self.table_layout {
FixedLayout => {
TableLayout::Fixed => {
// In fixed table layout, we distribute extra space among the unspecified columns
// if there are any, or among all the columns if all are specified.
self.column_computed_inline_sizes.clear();

View file

@ -9,7 +9,7 @@
use block::BlockFlow;
use construct::FlowConstructor;
use context::LayoutContext;
use flow::{TableCaptionFlowClass, FlowClass, Flow};
use flow::{FlowClass, Flow};
use fragment::FragmentBoundsIterator;
use wrapper::ThreadSafeLayoutNode;
@ -35,7 +35,7 @@ impl TableCaptionFlow {
impl Flow for TableCaptionFlow {
fn class(&self) -> FlowClass {
TableCaptionFlowClass
FlowClass::TableCaption
}
fn as_table_caption<'a>(&'a mut self) -> &'a mut TableCaptionFlow {

View file

@ -6,9 +6,9 @@
#![deny(unsafe_blocks)]
use block::{BlockFlow, MarginsMayNotCollapse, ISizeAndMarginsComputer};
use block::{BlockFlow, ISizeAndMarginsComputer, MarginsMayCollapseFlag};
use context::LayoutContext;
use flow::{TableCellFlowClass, FlowClass, Flow};
use flow::{FlowClass, Flow};
use fragment::{Fragment, FragmentBoundsIterator};
use model::{MaybeAuto};
use layout_debug;
@ -17,7 +17,7 @@ use wrapper::ThreadSafeLayoutNode;
use servo_util::geometry::Au;
use std::fmt;
use style::{ColSpanUnsignedIntegerAttribute, ComputedValues};
use style::{UnsignedIntegerAttribute, ComputedValues};
use sync::Arc;
/// A table formatting context.
@ -34,7 +34,7 @@ impl TableCellFlow {
-> TableCellFlow {
TableCellFlow {
block_flow: BlockFlow::from_node_and_fragment(node, fragment),
column_span: node.get_unsigned_integer_attribute(ColSpanUnsignedIntegerAttribute)
column_span: node.get_unsigned_integer_attribute(UnsignedIntegerAttribute::ColSpanUnsignedIntegerAttribute)
.unwrap_or(1),
}
}
@ -53,13 +53,13 @@ impl TableCellFlow {
/// methods.
#[inline(always)]
fn assign_block_size_table_cell_base<'a>(&mut self, layout_context: &'a LayoutContext<'a>) {
self.block_flow.assign_block_size_block_base(layout_context, MarginsMayNotCollapse)
self.block_flow.assign_block_size_block_base(layout_context, MarginsMayCollapseFlag::MarginsMayNotCollapse)
}
}
impl Flow for TableCellFlow {
fn class(&self) -> FlowClass {
TableCellFlowClass
FlowClass::TableCell
}
fn as_table_cell<'a>(&'a mut self) -> &'a mut TableCellFlow {

View file

@ -8,8 +8,8 @@
use context::LayoutContext;
use css::node_style::StyledNode;
use flow::{BaseFlow, ForceNonfloated, TableColGroupFlowClass, FlowClass, Flow};
use fragment::{Fragment, FragmentBoundsIterator, TableColumnFragment};
use flow::{BaseFlow, FlowClass, Flow, ForceNonfloatedFlag};
use fragment::{Fragment, FragmentBoundsIterator, SpecificFragmentInfo};
use layout_debug;
use wrapper::ThreadSafeLayoutNode;
@ -44,7 +44,7 @@ impl TableColGroupFlow {
-> TableColGroupFlow {
let writing_mode = node.style().writing_mode;
TableColGroupFlow {
base: BaseFlow::new(Some((*node).clone()), writing_mode, ForceNonfloated),
base: BaseFlow::new(Some((*node).clone()), writing_mode, ForceNonfloatedFlag::ForceNonfloated),
fragment: Some(fragment),
cols: fragments,
inline_sizes: vec!(),
@ -54,7 +54,7 @@ impl TableColGroupFlow {
impl Flow for TableColGroupFlow {
fn class(&self) -> FlowClass {
TableColGroupFlowClass
FlowClass::TableColGroup
}
fn as_table_colgroup<'a>(&'a mut self) -> &'a mut TableColGroupFlow {
@ -69,7 +69,7 @@ impl Flow for TableColGroupFlow {
// Retrieve the specified value from the appropriate CSS property.
let inline_size = fragment.style().content_inline_size();
let span: int = match fragment.specific {
TableColumnFragment(col_fragment) => max(col_fragment.span, 1),
SpecificFragmentInfo::TableColumn(col_fragment) => max(col_fragment.span, 1),
_ => panic!("non-table-column fragment inside table column?!"),
};
for _ in range(0, span) {

View file

@ -10,19 +10,19 @@ use block::BlockFlow;
use block::ISizeAndMarginsComputer;
use construct::FlowConstructor;
use context::LayoutContext;
use flow::{TableRowFlowClass, FlowClass, Flow, ImmutableFlowUtils};
use flow::{FlowClass, Flow, ImmutableFlowUtils};
use flow;
use fragment::{Fragment, FragmentBoundsIterator};
use layout_debug;
use table::{ColumnComputedInlineSize, ColumnIntrinsicInlineSize, InternalTable};
use model::{MaybeAuto, Specified, Auto};
use model::MaybeAuto;
use wrapper::ThreadSafeLayoutNode;
use servo_util::geometry::Au;
use std::cmp::max;
use std::fmt;
use style::ComputedValues;
use style::computed_values::{LPA_Auto, LPA_Length, LPA_Percentage};
use style::computed_values::LengthOrPercentageOrAuto;
use sync::Arc;
/// A single row of a table.
@ -120,8 +120,8 @@ impl TableRowFlow {
.style()
.content_block_size(),
Au(0)) {
Auto => block_size,
Specified(value) => max(value, block_size)
MaybeAuto::Auto => block_size,
MaybeAuto::Specified(value) => max(value, block_size)
};
// cur_y = cur_y + block-size;
@ -149,7 +149,7 @@ impl TableRowFlow {
impl Flow for TableRowFlow {
fn class(&self) -> FlowClass {
TableRowFlowClass
FlowClass::TableRow
}
fn as_table_row<'a>(&'a mut self) -> &'a mut TableRowFlow {
@ -205,19 +205,19 @@ impl Flow for TableRowFlow {
let child_base = flow::mut_base(kid);
let child_column_inline_size = ColumnIntrinsicInlineSize {
minimum_length: match child_specified_inline_size {
LPA_Auto | LPA_Percentage(_) => {
LengthOrPercentageOrAuto::Auto | LengthOrPercentageOrAuto::Percentage(_) => {
child_base.intrinsic_inline_sizes.minimum_inline_size
}
LPA_Length(length) => length,
LengthOrPercentageOrAuto::Length(length) => length,
},
percentage: match child_specified_inline_size {
LPA_Auto | LPA_Length(_) => 0.0,
LPA_Percentage(percentage) => percentage,
LengthOrPercentageOrAuto::Auto | LengthOrPercentageOrAuto::Length(_) => 0.0,
LengthOrPercentageOrAuto::Percentage(percentage) => percentage,
},
preferred: child_base.intrinsic_inline_sizes.preferred_inline_size,
constrained: match child_specified_inline_size {
LPA_Length(_) => true,
LPA_Auto | LPA_Percentage(_) => false,
LengthOrPercentageOrAuto::Length(_) => true,
LengthOrPercentageOrAuto::Auto | LengthOrPercentageOrAuto::Percentage(_) => false,
},
};
min_inline_size = min_inline_size + child_column_inline_size.minimum_length;

View file

@ -6,10 +6,10 @@
#![deny(unsafe_blocks)]
use block::{BlockFlow, ISizeAndMarginsComputer, MarginsMayNotCollapse};
use block::{BlockFlow, ISizeAndMarginsComputer, MarginsMayCollapseFlag};
use construct::FlowConstructor;
use context::LayoutContext;
use flow::{Flow, FlowClass, TableRowGroupFlowClass};
use flow::{FlowClass, Flow};
use fragment::{Fragment, FragmentBoundsIterator};
use layout_debug;
use table::{ColumnComputedInlineSize, ColumnIntrinsicInlineSize, InternalTable};
@ -62,13 +62,13 @@ impl TableRowGroupFlow {
/// methods.
#[inline(always)]
fn assign_block_size_table_rowgroup_base<'a>(&mut self, layout_context: &'a LayoutContext<'a>) {
self.block_flow.assign_block_size_block_base(layout_context, MarginsMayNotCollapse)
self.block_flow.assign_block_size_block_base(layout_context, MarginsMayCollapseFlag::MarginsMayNotCollapse)
}
}
impl Flow for TableRowGroupFlow {
fn class(&self) -> FlowClass {
TableRowGroupFlowClass
FlowClass::TableRowGroup
}
fn as_table_rowgroup<'a>(&'a mut self) -> &'a mut TableRowGroupFlow {

View file

@ -13,12 +13,11 @@
#![deny(unsafe_blocks)]
use block::{BlockFlow, BlockNonReplaced, FloatNonReplaced, ISizeAndMarginsComputer};
use block::{MarginsMayNotCollapse};
use block::{BlockFlow, BlockNonReplaced, FloatNonReplaced, ISizeAndMarginsComputer, MarginsMayCollapseFlag};
use construct::FlowConstructor;
use context::LayoutContext;
use floats::FloatKind;
use flow::{TableWrapperFlowClass, FlowClass, Flow, ImmutableFlowUtils};
use flow::{FlowClass, Flow, ImmutableFlowUtils};
use flow::{IMPACTED_BY_LEFT_FLOATS, IMPACTED_BY_RIGHT_FLOATS};
use fragment::{Fragment, FragmentBoundsIterator};
use table::{ColumnComputedInlineSize, ColumnIntrinsicInlineSize};
@ -33,8 +32,8 @@ use sync::Arc;
#[deriving(Encodable, Show)]
pub enum TableLayout {
FixedLayout,
AutoLayout
Fixed,
Auto
}
/// A table wrapper flow based on a block formatting context.
@ -56,9 +55,9 @@ impl TableWrapperFlow {
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::fixed {
FixedLayout
TableLayout::Fixed
} else {
AutoLayout
TableLayout::Auto
};
TableWrapperFlow {
block_flow: block_flow,
@ -73,9 +72,9 @@ impl TableWrapperFlow {
let mut block_flow = BlockFlow::from_node(constructor, node);
let table_layout = if block_flow.fragment().style().get_table().table_layout ==
table_layout::fixed {
FixedLayout
TableLayout::Fixed
} else {
AutoLayout
TableLayout::Auto
};
TableWrapperFlow {
block_flow: block_flow,
@ -91,9 +90,9 @@ impl TableWrapperFlow {
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::fixed {
FixedLayout
TableLayout::Fixed
} else {
AutoLayout
TableLayout::Auto
};
TableWrapperFlow {
block_flow: block_flow,
@ -158,7 +157,7 @@ impl TableWrapperFlow {
// FIXME(pcwalton, spec): How do I deal with fractional excess?
let excess_inline_size = available_inline_size - total_used_inline_size;
if excess_inline_size > Au(0) &&
selection == UsePreferredGuessAndDistributeExcessInlineSize {
selection == SelectedAutoLayoutCandidateGuess::UsePreferredGuessAndDistributeExcessInlineSize {
let mut info = ExcessInlineSizeDistributionInfo::new();
for column_intrinsic_inline_size in self.column_intrinsic_inline_sizes.iter() {
info.update(column_intrinsic_inline_size)
@ -214,7 +213,7 @@ impl TableWrapperFlow {
impl Flow for TableWrapperFlow {
fn class(&self) -> FlowClass {
TableWrapperFlowClass
FlowClass::TableWrapper
}
fn as_table_wrapper<'a>(&'a mut self) -> &'a mut TableWrapperFlow {
@ -274,8 +273,8 @@ impl Flow for TableWrapperFlow {
self.compute_used_inline_size(layout_context, containing_block_inline_size);
match self.table_layout {
FixedLayout => {}
AutoLayout => {
TableLayout::Fixed => {}
TableLayout::Auto => {
self.calculate_table_column_sizes_for_automatic_layout(
intermediate_column_inline_sizes.as_mut_slice())
}
@ -286,8 +285,8 @@ impl Flow for TableWrapperFlow {
// In case of fixed layout, column inline-sizes are calculated in table flow.
let assigned_column_inline_sizes = match self.table_layout {
FixedLayout => None,
AutoLayout => {
TableLayout::Fixed => None,
TableLayout::Auto => {
Some(intermediate_column_inline_sizes.iter().map(|sizes| {
ColumnComputedInlineSize {
size: sizes.size,
@ -317,7 +316,7 @@ impl Flow for TableWrapperFlow {
fn assign_block_size<'a>(&mut self, ctx: &'a LayoutContext<'a>) {
debug!("assign_block_size: assigning block_size for table_wrapper");
self.block_flow.assign_block_size_block_base(ctx, MarginsMayNotCollapse);
self.block_flow.assign_block_size_block_base(ctx, MarginsMayCollapseFlag::MarginsMayNotCollapse);
}
fn compute_absolute_position(&mut self) {
@ -449,17 +448,17 @@ impl AutoLayoutCandidateGuess {
/// This does *not* distribute excess inline-size. That must be done later if necessary.
fn calculate(&self, selection: SelectedAutoLayoutCandidateGuess) -> Au {
match selection {
UseMinimumGuess => self.minimum_guess,
InterpolateBetweenMinimumGuessAndMinimumPercentageGuess(weight) => {
SelectedAutoLayoutCandidateGuess::UseMinimumGuess => self.minimum_guess,
SelectedAutoLayoutCandidateGuess::InterpolateBetweenMinimumGuessAndMinimumPercentageGuess(weight) => {
interp(self.minimum_guess, self.minimum_percentage_guess, weight)
}
InterpolateBetweenMinimumPercentageGuessAndMinimumSpecifiedGuess(weight) => {
SelectedAutoLayoutCandidateGuess::InterpolateBetweenMinimumPercentageGuessAndMinimumSpecifiedGuess(weight) => {
interp(self.minimum_percentage_guess, self.minimum_specified_guess, weight)
}
InterpolateBetweenMinimumSpecifiedGuessAndPreferredGuess(weight) => {
SelectedAutoLayoutCandidateGuess::InterpolateBetweenMinimumSpecifiedGuessAndPreferredGuess(weight) => {
interp(self.minimum_specified_guess, self.preferred_guess, weight)
}
UsePreferredGuessAndDistributeExcessInlineSize => {
SelectedAutoLayoutCandidateGuess::UsePreferredGuessAndDistributeExcessInlineSize => {
self.preferred_guess
}
}
@ -498,24 +497,24 @@ impl SelectedAutoLayoutCandidateGuess {
fn select(guess: &AutoLayoutCandidateGuess, assignable_inline_size: Au)
-> SelectedAutoLayoutCandidateGuess {
if assignable_inline_size < guess.minimum_guess {
UseMinimumGuess
SelectedAutoLayoutCandidateGuess::UseMinimumGuess
} else if assignable_inline_size < guess.minimum_percentage_guess {
let weight = weight(guess.minimum_guess,
assignable_inline_size,
guess.minimum_percentage_guess);
InterpolateBetweenMinimumGuessAndMinimumPercentageGuess(weight)
SelectedAutoLayoutCandidateGuess::InterpolateBetweenMinimumGuessAndMinimumPercentageGuess(weight)
} else if assignable_inline_size < guess.minimum_specified_guess {
let weight = weight(guess.minimum_percentage_guess,
assignable_inline_size,
guess.minimum_specified_guess);
InterpolateBetweenMinimumPercentageGuessAndMinimumSpecifiedGuess(weight)
SelectedAutoLayoutCandidateGuess::InterpolateBetweenMinimumPercentageGuessAndMinimumSpecifiedGuess(weight)
} else if assignable_inline_size < guess.preferred_guess {
let weight = weight(guess.minimum_specified_guess,
assignable_inline_size,
guess.preferred_guess);
InterpolateBetweenMinimumSpecifiedGuessAndPreferredGuess(weight)
SelectedAutoLayoutCandidateGuess::InterpolateBetweenMinimumSpecifiedGuessAndPreferredGuess(weight)
} else {
UsePreferredGuessAndDistributeExcessInlineSize
SelectedAutoLayoutCandidateGuess::UsePreferredGuessAndDistributeExcessInlineSize
}
}
}

View file

@ -6,7 +6,7 @@
#![deny(unsafe_blocks)]
use fragment::{Fragment, ScannedTextFragmentInfo, UnscannedTextFragment};
use fragment::{Fragment, SpecificFragmentInfo, ScannedTextFragmentInfo};
use inline::InlineFragments;
use gfx::font::{FontMetrics, IGNORE_LIGATURES_SHAPING_FLAG, RunMetrics, ShapingFlags};
@ -85,7 +85,7 @@ impl TextRunScanner {
debug_assert!(!self.clump.is_empty());
match self.clump.front().unwrap().specific {
UnscannedTextFragment(_) => {}
SpecificFragmentInfo::UnscannedText(_) => {}
_ => {
debug_assert!(self.clump.len() == 1,
"WAT: can't coalesce non-text nodes in flush_clump_to_list()!");
@ -126,7 +126,7 @@ impl TextRunScanner {
let mut run_text = String::new();
for in_fragment in self.clump.iter() {
let in_fragment = match in_fragment.specific {
UnscannedTextFragment(ref text_fragment_info) => &text_fragment_info.text,
SpecificFragmentInfo::UnscannedText(ref text_fragment_info) => &text_fragment_info.text,
_ => panic!("Expected an unscanned text fragment!"),
};
@ -181,7 +181,7 @@ impl TextRunScanner {
mem::replace(&mut self.clump, DList::new()).into_iter().enumerate() {
let range = *new_ranges.get(logical_offset);
if range.is_empty() {
debug!("Elided an `UnscannedTextFragment` because it was zero-length after \
debug!("Elided an `SpecificFragmentInfo::UnscannedText` because it was zero-length after \
compression; {}",
old_fragment);
continue

View file

@ -5,7 +5,7 @@
//! Traversals over the DOM and flow trees, running the layout computations.
use css::node_style::StyledNode;
use css::matching::{ApplicableDeclarations, CannotShare, MatchMethods, StyleWasShared};
use css::matching::{ApplicableDeclarations, MatchMethods, StyleSharingResult};
use construct::FlowConstructor;
use context::LayoutContext;
use flow::{Flow, MutableFlowUtils};
@ -152,7 +152,7 @@ impl<'a> PreorderDomTraversal for RecalcStyleForNode<'a> {
};
// Otherwise, match and cascade selectors.
match sharing_result {
CannotShare(mut shareable) => {
StyleSharingResult::CannotShare(mut shareable) => {
let mut applicable_declarations = ApplicableDeclarations::new();
if node.is_element() {
@ -178,7 +178,7 @@ impl<'a> PreorderDomTraversal for RecalcStyleForNode<'a> {
style_sharing_candidate_cache.insert_if_possible(&node);
}
}
StyleWasShared(index, damage) => {
StyleSharingResult::StyleWasShared(index, damage) => {
style_sharing_candidate_cache.touch(index);
ThreadSafeLayoutNode::new(&node).set_restyle_damage(damage);
}

View file

@ -2,7 +2,7 @@
* 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 construct::{ConstructionResult, NoConstructionResult};
use construct::ConstructionResult;
use incremental::RestyleDamage;
use parallel::DomParallelInfo;
use wrapper::{LayoutNode, TLayoutNode, ThreadSafeLayoutNode};
@ -54,9 +54,9 @@ impl PrivateLayoutData {
before_style: None,
after_style: None,
restyle_damage: RestyleDamage::empty(),
flow_construction_result: NoConstructionResult,
before_flow_construction_result: NoConstructionResult,
after_flow_construction_result: NoConstructionResult,
flow_construction_result: ConstructionResult::None,
before_flow_construction_result: ConstructionResult::None,
after_flow_construction_result: ConstructionResult::None,
parallel: DomParallelInfo::new(),
flags: LayoutDataFlags::empty(),
}

View file

@ -42,13 +42,13 @@ use script::dom::bindings::codegen::InheritTypes::{ElementCast, HTMLIFrameElemen
use script::dom::bindings::codegen::InheritTypes::{HTMLImageElementCast, HTMLInputElementCast};
use script::dom::bindings::codegen::InheritTypes::{HTMLTextAreaElementCast, NodeCast, TextCast};
use script::dom::bindings::js::JS;
use script::dom::element::{Element, HTMLAreaElementTypeId, HTMLAnchorElementTypeId};
use script::dom::element::{HTMLLinkElementTypeId, LayoutElementHelpers, RawLayoutElementHelpers};
use script::dom::element::{Element, ElementTypeId};
use script::dom::element::{LayoutElementHelpers, RawLayoutElementHelpers};
use script::dom::htmliframeelement::HTMLIFrameElement;
use script::dom::htmlimageelement::LayoutHTMLImageElementHelpers;
use script::dom::htmlinputelement::LayoutHTMLInputElementHelpers;
use script::dom::htmltextareaelement::LayoutHTMLTextAreaElementHelpers;
use script::dom::node::{DocumentNodeTypeId, ElementNodeTypeId, Node, NodeTypeId};
use script::dom::node::{Node, NodeTypeId};
use script::dom::node::{LayoutNodeHelpers, RawLayoutNodeHelpers, SharedLayoutData};
use script::dom::node::{HAS_CHANGED, IS_DIRTY, HAS_DIRTY_SIBLINGS, HAS_DIRTY_DESCENDANTS};
use script::dom::text::Text;
@ -59,8 +59,8 @@ use std::kinds::marker::ContravariantLifetime;
use std::mem;
use string_cache::{Atom, Namespace};
use style::computed_values::{content, display, white_space};
use style::{AnyNamespace, AttrSelector, BorderUnsignedIntegerAttribute, IntegerAttribute};
use style::{LengthAttribute, PropertyDeclarationBlock, SimpleColorAttribute, SpecificNamespace};
use style::{NamespaceConstraint, AttrSelector, IntegerAttribute};
use style::{LengthAttribute, PropertyDeclarationBlock, SimpleColorAttribute};
use style::{TElement, TElementAttributes, TNode, UnsignedIntegerAttribute};
use url::Url;
@ -87,14 +87,14 @@ pub trait TLayoutNode {
fn node_is_element(&self) -> bool {
match self.type_id() {
Some(ElementNodeTypeId(..)) => true,
Some(NodeTypeId::Element(..)) => true,
_ => false
}
}
fn node_is_document(&self) -> bool {
match self.type_id() {
Some(DocumentNodeTypeId(..)) => true,
Some(NodeTypeId::Document(..)) => true,
_ => false
}
}
@ -201,7 +201,7 @@ impl<'ln> TLayoutNode for LayoutNode<'ln> {
impl<'ln> LayoutNode<'ln> {
/// Creates a new layout node, scoped to the given closure.
pub unsafe fn with_layout_node<R>(node: JS<Node>, f: <'a> |LayoutNode<'a>| -> R) -> R {
pub unsafe fn with_layout_node<R>(node: JS<Node>, f: for <'a> |LayoutNode<'a>| -> R) -> R {
f(LayoutNode {
node: node,
chain: ContravariantLifetime,
@ -375,11 +375,11 @@ impl<'ln> TNode<'ln, LayoutElement<'ln>> for LayoutNode<'ln> {
&attr.name
};
match attr.namespace {
SpecificNamespace(ref ns) => {
NamespaceConstraint::Specific(ref ns) => {
let element = self.as_element();
element.get_attr(ns, name).map_or(false, |attr| test(attr))
},
AnyNamespace => {
NamespaceConstraint::Any => {
let element = self.as_element();
element.get_attrs(name).iter().any(|attr| test(*attr))
}
@ -516,9 +516,9 @@ impl<'le> TElement<'le> for LayoutElement<'le> {
match NodeCast::from_actual(self.element).type_id_for_layout() {
// http://www.whatwg.org/specs/web-apps/current-work/multipage/selectors.html#
// selector-link
ElementNodeTypeId(HTMLAnchorElementTypeId) |
ElementNodeTypeId(HTMLAreaElementTypeId) |
ElementNodeTypeId(HTMLLinkElementTypeId) => {
NodeTypeId::Element(ElementTypeId::HTMLAnchorElement) |
NodeTypeId::Element(ElementTypeId::HTMLAreaElement) |
NodeTypeId::Element(ElementTypeId::HTMLLinkElement) => {
unsafe {
self.element.get_attr_val_for_layout(&ns!(""), &atom!("href"))
}
@ -594,7 +594,7 @@ impl<'le> TElement<'le> for LayoutElement<'le> {
fn has_nonzero_border(self) -> bool {
unsafe {
match self.element
.get_unsigned_integer_attribute_for_layout(BorderUnsignedIntegerAttribute) {
.get_unsigned_integer_attribute_for_layout(UnsignedIntegerAttribute::BorderUnsignedIntegerAttribute) {
None | Some(0) => false,
_ => true,
}
@ -651,14 +651,14 @@ pub enum PseudoElementType {
impl PseudoElementType {
pub fn is_before(&self) -> bool {
match *self {
Before(_) => true,
PseudoElementType::Before(_) => true,
_ => false,
}
}
pub fn is_after(&self) -> bool {
match *self {
After(_) => true,
PseudoElementType::After(_) => true,
_ => false,
}
}
@ -682,13 +682,13 @@ impl<'ln> TLayoutNode for ThreadSafeLayoutNode<'ln> {
node: node.transmute_copy(),
chain: self.node.chain,
},
pseudo: Normal,
pseudo: PseudoElementType::Normal,
}
}
/// Returns `None` if this is a pseudo-element.
fn type_id(&self) -> Option<NodeTypeId> {
if self.pseudo != Normal {
if self.pseudo != PseudoElementType::Normal {
return None
}
@ -704,20 +704,20 @@ impl<'ln> TLayoutNode for ThreadSafeLayoutNode<'ln> {
}
fn first_child(&self) -> Option<ThreadSafeLayoutNode<'ln>> {
if self.pseudo != Normal {
if self.pseudo != PseudoElementType::Normal {
return None
}
if self.has_before_pseudo() {
// FIXME(pcwalton): This logic looks weird. Is it right?
match self.pseudo {
Normal => {
let pseudo_before_node = self.with_pseudo(Before(self.get_before_display()));
PseudoElementType::Normal => {
let pseudo_before_node = self.with_pseudo(PseudoElementType::Before(self.get_before_display()));
return Some(pseudo_before_node)
}
Before(display::inline) => {}
Before(_) => {
let pseudo_before_node = self.with_pseudo(Before(display::inline));
PseudoElementType::Before(display::inline) => {}
PseudoElementType::Before(_) => {
let pseudo_before_node = self.with_pseudo(PseudoElementType::Before(display::inline));
return Some(pseudo_before_node)
}
_ => {}
@ -730,7 +730,7 @@ impl<'ln> TLayoutNode for ThreadSafeLayoutNode<'ln> {
}
fn text(&self) -> String {
if self.pseudo != Normal {
if self.pseudo != PseudoElementType::Normal {
let layout_data_ref = self.borrow_layout_data();
let node_layout_data_wrapper = layout_data_ref.as_ref().unwrap();
@ -751,7 +751,7 @@ impl<'ln> ThreadSafeLayoutNode<'ln> {
pub fn new<'a>(node: &LayoutNode<'a>) -> ThreadSafeLayoutNode<'a> {
ThreadSafeLayoutNode {
node: node.clone(),
pseudo: Normal,
pseudo: PseudoElementType::Normal,
}
}
@ -1019,7 +1019,7 @@ impl<'a> Iterator<ThreadSafeLayoutNode<'a>> for ThreadSafeLayoutNodeChildrenIter
match self.parent_node {
Some(ref parent_node) => {
if parent_node.pseudo == Normal {
if parent_node.pseudo == PseudoElementType::Normal {
self.current_node = self.current_node.clone().and_then(|node| {
unsafe {
node.next_sibling()
@ -1036,8 +1036,8 @@ impl<'a> Iterator<ThreadSafeLayoutNode<'a>> for ThreadSafeLayoutNodeChildrenIter
match self.parent_node {
Some(ref parent_node) => {
if parent_node.has_after_pseudo() {
let pseudo_after_node = if parent_node.pseudo == Normal {
let pseudo = After(parent_node.get_after_display());
let pseudo_after_node = if parent_node.pseudo == PseudoElementType::Normal {
let pseudo = PseudoElementType::After(parent_node.get_after_display());
Some(parent_node.with_pseudo(pseudo))
} else {
None