layout: Introduce support for legacy presentational attributes to selector

matching, and use it for `<input size>` and `<td width>`.

This implements a general framework for legacy presentational attributes
to the DOM and style calculation, so that adding more of them later will
be straightforward.
This commit is contained in:
Patrick Walton 2014-10-14 11:25:29 -07:00
parent 8077edc062
commit 5f8d3f72d8
31 changed files with 570 additions and 214 deletions

View file

@ -138,7 +138,7 @@ pub enum SpecificFragmentInfo {
InlineAbsoluteHypotheticalFragment(InlineAbsoluteHypotheticalFragmentInfo),
InlineBlockFragment(InlineBlockFragmentInfo),
InputFragment(InputFragmentInfo),
InputFragment,
ScannedTextFragment(ScannedTextFragmentInfo),
TableFragment,
TableCellFragment,
@ -183,22 +183,6 @@ impl InlineBlockFragmentInfo {
}
}
/// A fragment that represents a displayable form element
#[deriving(Clone)]
pub struct InputFragmentInfo {
pub size: u32,
}
impl InputFragmentInfo {
/// Returns the original inline-size of the input.
fn input_inline_size(&self, font_style: &FontStyle, layout_context: &LayoutContext) -> Au {
let metrics = text::font_metrics_for_style(layout_context.font_context(), font_style);
// https://html.spec.whatwg.org/#converting-a-character-width-to-pixels
metrics.average_advance * (self.size as i32 - 1) + metrics.max_advance
}
}
/// A fragment that represents a replaced content image and its accompanying borders, shadows, etc.
#[deriving(Clone)]
pub struct ImageFragmentInfo {
@ -550,7 +534,7 @@ impl Fragment {
fn style_specified_intrinsic_inline_size(&self) -> IntrinsicISizes {
let (use_margins, use_padding) = match self.specific {
GenericFragment | IframeFragment(_) | ImageFragment(_) | InlineBlockFragment(_) |
InputFragment(_) => (true, true),
InputFragment => (true, true),
TableFragment | TableCellFragment => (false, true),
TableWrapperFragment => (true, false),
TableRowFragment => (false, false),
@ -1195,7 +1179,7 @@ impl Fragment {
clip_rect))
}
GenericFragment | IframeFragment(..) | TableFragment | TableCellFragment |
TableRowFragment | TableWrapperFragment | InlineBlockFragment(_) | InputFragment(_) |
TableRowFragment | TableWrapperFragment | InlineBlockFragment(_) | InputFragment |
InlineAbsoluteHypotheticalFragment(_) => {
// FIXME(pcwalton): This is a bit of an abuse of the logging infrastructure. We
// should have a real `SERVO_DEBUG` system.
@ -1258,13 +1242,13 @@ impl Fragment {
}
/// Returns the intrinsic inline-sizes of this fragment.
pub fn intrinsic_inline_sizes(&mut self, layout_context: &LayoutContext) -> IntrinsicISizes {
pub fn intrinsic_inline_sizes(&mut self) -> IntrinsicISizes {
let mut result = self.style_specified_intrinsic_inline_size();
match self.specific {
GenericFragment | IframeFragment(_) | TableFragment | TableCellFragment |
TableColumnFragment(_) | TableRowFragment | TableWrapperFragment |
InlineAbsoluteHypotheticalFragment(_) => {}
InlineAbsoluteHypotheticalFragment(_) | InputFragment => {}
InlineBlockFragment(ref mut info) => {
let block_flow = info.flow_ref.get_mut().as_block();
result.minimum_inline_size = max(result.minimum_inline_size,
@ -1280,12 +1264,6 @@ impl Fragment {
result.preferred_inline_size = max(result.preferred_inline_size,
image_inline_size);
}
InputFragment(ref input_fragment_info) => {
let font_style = text::computed_style_to_font_style(&*self.style);
let input_inline_size = input_fragment_info.input_inline_size(&font_style, layout_context);
result.minimum_inline_size = input_inline_size;
result.preferred_inline_size = input_inline_size;
}
ScannedTextFragment(ref text_fragment_info) => {
let range = &text_fragment_info.range;
let min_line_inline_size = text_fragment_info.run.min_width_for_range(range);
@ -1333,7 +1311,7 @@ impl Fragment {
match self.specific {
GenericFragment | IframeFragment(_) | TableFragment | TableCellFragment |
TableRowFragment | TableWrapperFragment | InlineBlockFragment(_) |
InputFragment(_) | InlineAbsoluteHypotheticalFragment(_) => Au(0),
InputFragment | InlineAbsoluteHypotheticalFragment(_) => Au(0),
ImageFragment(ref image_fragment_info) => {
image_fragment_info.computed_inline_size()
}
@ -1352,7 +1330,7 @@ impl Fragment {
match self.specific {
GenericFragment | IframeFragment(_) | TableFragment | TableCellFragment |
TableRowFragment | TableWrapperFragment | InlineBlockFragment(_) |
InputFragment(_) | InlineAbsoluteHypotheticalFragment(_) => Au(0),
InputFragment | InlineAbsoluteHypotheticalFragment(_) => Au(0),
ImageFragment(ref image_fragment_info) => {
image_fragment_info.computed_block_size()
}
@ -1386,7 +1364,7 @@ impl Fragment {
-> Option<(SplitInfo, Option<SplitInfo>, Arc<Box<TextRun>> /* TODO(bjz): remove */)> {
match self.specific {
GenericFragment | IframeFragment(_) | ImageFragment(_) | TableFragment | TableCellFragment |
TableRowFragment | TableWrapperFragment | InputFragment(_) => None,
TableRowFragment | TableWrapperFragment | InputFragment => None,
TableColumnFragment(_) => fail!("Table column fragments do not need to split"),
UnscannedTextFragment(_) => fail!("Unscanned text fragments should have been scanned by now!"),
InlineBlockFragment(_) | InlineAbsoluteHypotheticalFragment(_) => {
@ -1429,7 +1407,7 @@ impl Fragment {
-> Option<(Option<SplitInfo>, Option<SplitInfo>, Arc<Box<TextRun>> /* TODO(bjz): remove */)> {
match self.specific {
GenericFragment | IframeFragment(_) | ImageFragment(_) | TableFragment | TableCellFragment |
TableRowFragment | TableWrapperFragment | InlineBlockFragment(_) | InputFragment(_) |
TableRowFragment | TableWrapperFragment | InlineBlockFragment(_) | InputFragment |
InlineAbsoluteHypotheticalFragment(_) => None,
TableColumnFragment(_) => fail!("Table column fragments do not have inline_size"),
UnscannedTextFragment(_) => fail!("Unscanned text fragments should have been scanned by now!"),
@ -1528,7 +1506,7 @@ impl Fragment {
container_inline_size: Au) {
match self.specific {
GenericFragment | IframeFragment(_) | TableFragment | TableCellFragment |
TableRowFragment | TableWrapperFragment | InputFragment(_) => return,
TableRowFragment | TableWrapperFragment | InputFragment => return,
TableColumnFragment(_) => fail!("Table column fragments do not have inline_size"),
UnscannedTextFragment(_) => {
fail!("Unscanned text fragments should have been scanned by now!")
@ -1624,7 +1602,7 @@ impl Fragment {
pub fn assign_replaced_block_size_if_necessary(&mut self, containing_block_block_size: Au) {
match self.specific {
GenericFragment | IframeFragment(_) | TableFragment | TableCellFragment |
TableRowFragment | TableWrapperFragment | InputFragment(_) => return,
TableRowFragment | TableWrapperFragment | InputFragment => return,
TableColumnFragment(_) => fail!("Table column fragments do not have block_size"),
UnscannedTextFragment(_) => {
fail!("Unscanned text fragments should have been scanned by now!")
@ -1787,7 +1765,7 @@ impl Fragment {
TableWrapperFragment => false,
GenericFragment | IframeFragment(_) | ImageFragment(_) | ScannedTextFragment(_) |
TableFragment | TableCellFragment | TableColumnFragment(_) | TableRowFragment |
UnscannedTextFragment(_) | InputFragment(_) => true,
UnscannedTextFragment(_) | InputFragment => true,
}
}
@ -1844,7 +1822,7 @@ impl fmt::Show for Fragment {
ImageFragment(_) => "ImageFragment",
InlineAbsoluteHypotheticalFragment(_) => "InlineAbsoluteHypotheticalFragment",
InlineBlockFragment(_) => "InlineBlockFragment",
InputFragment(_) => "InputFragment",
InputFragment => "InputFragment",
ScannedTextFragment(_) => "ScannedTextFragment",
TableFragment => "TableFragment",
TableCellFragment => "TableCellFragment",