From 4b9cd4e65dfe74c99fb04126dc6a48bfddabb935 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Thu, 7 May 2015 18:09:57 -0700 Subject: [PATCH] layout: Implement `` and `
`. Improves Hacker News. --- components/layout/block.rs | 34 +++++++---- components/layout/inline.rs | 2 +- components/style/legacy.rs | 56 ++++++++++++++----- components/style/properties.mako.rs | 17 +++--- resources/presentational-hints.css | 1 - resources/quirks-mode.css | 11 ++++ resources/servo.css | 2 + tests/ref/basic.list | 2 + tests/ref/servo_center_a.html | 20 +++++++ tests/ref/servo_center_ref.html | 18 ++++++ tests/ref/table_width_attribute_a.html | 15 +++++ tests/ref/table_width_attribute_ref.html | 16 ++++++ .../tables/table-width-150percent.html.ini | 2 +- 13 files changed, 160 insertions(+), 36 deletions(-) create mode 100644 tests/ref/servo_center_a.html create mode 100644 tests/ref/servo_center_ref.html create mode 100644 tests/ref/table_width_attribute_a.html create mode 100644 tests/ref/table_width_attribute_ref.html diff --git a/components/layout/block.rs b/components/layout/block.rs index 0df2bbe3f3a..78ed9d581c5 100644 --- a/components/layout/block.rs +++ b/components/layout/block.rs @@ -55,7 +55,7 @@ use std::cmp::{max, min}; use std::fmt; use std::sync::Arc; use style::computed_values::{border_collapse, box_sizing, display, float, overflow_x, overflow_y}; -use style::computed_values::{position}; +use style::computed_values::{position, text_align}; use style::properties::ComputedValues; use style::values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto}; use style::values::computed::{LengthOrPercentageOrNone}; @@ -1954,6 +1954,7 @@ pub struct ISizeConstraintInput { pub inline_end_margin: MaybeAuto, pub inline_start: MaybeAuto, pub inline_end: MaybeAuto, + pub text_align: text_align::T, pub available_inline_size: Au, } @@ -1963,6 +1964,7 @@ impl ISizeConstraintInput { inline_end_margin: MaybeAuto, inline_start: MaybeAuto, inline_end: MaybeAuto, + text_align: text_align::T, available_inline_size: Au) -> ISizeConstraintInput { ISizeConstraintInput { @@ -1971,6 +1973,7 @@ impl ISizeConstraintInput { inline_end_margin: inline_end_margin, inline_start: inline_start, inline_end: inline_end, + text_align: text_align, available_inline_size: available_inline_size, } } @@ -2066,6 +2069,7 @@ pub trait ISizeAndMarginsComputer { containing_block_inline_size), MaybeAuto::from_style(position.inline_end, containing_block_inline_size), + style.get_inheritedtext().text_align, available_inline_size) } @@ -2241,18 +2245,28 @@ pub trait ISizeAndMarginsComputer { // available_inline-size let (inline_start_margin, mut inline_size, inline_end_margin) = 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. + // If all have a computed value other than 'auto', the system is over-constrained. (MaybeAuto::Specified(margin_start), MaybeAuto::Specified(inline_size), MaybeAuto::Specified(margin_end)) => { - if parent_has_same_direction { - (margin_start, inline_size, available_inline_size - - (margin_start + inline_size)) - } else { - (available_inline_size - (margin_end + inline_size), - inline_size, - margin_end) + match (input.text_align, parent_has_same_direction) { + (text_align::T::servo_center, _) => { + // This is used for `
` and friends per HTML5 § 14.3.3. Make the + // inline-start and inline-end margins equal per HTML5 § 14.2. + let margin = (available_inline_size - inline_size).scale_by(0.5); + (margin, inline_size, margin) + } + (_, true) => { + // Ignore the end margin. + (margin_start, inline_size, available_inline_size - + (margin_start + inline_size)) + } + (_, false) => { + // Ignore the start margin. + (available_inline_size - (margin_end + inline_size), + inline_size, + margin_end) + } } } // If exactly one value is 'auto', solve for it diff --git a/components/layout/inline.rs b/components/layout/inline.rs index 03548ce8483..bb4a4354b1a 100644 --- a/components/layout/inline.rs +++ b/components/layout/inline.rs @@ -917,7 +917,7 @@ impl InlineFlow { InlineFlow::justify_inline_fragments(fragments, line, slack_inline_size) } text_align::T::justify | text_align::T::start => {} - text_align::T::center => { + text_align::T::center | text_align::T::servo_center => { inline_start_position_for_fragment = inline_start_position_for_fragment + slack_inline_size.scale_by(0.5) } diff --git a/components/style/legacy.rs b/components/style/legacy.rs index 2c7caa16998..b10376981a8 100644 --- a/components/style/legacy.rs +++ b/components/style/legacy.rs @@ -75,6 +75,14 @@ pub trait PresentationalHintSynthesis { E: TElement<'a> + TElementAttributes<'a>, V: VecLike>>; + /// Synthesizes rules for the legacy `width` attribute. + fn synthesize_presentational_hint_for_legacy_width_attribute<'a,E,V>( + &self, + element: E, + matching_rules_list: &mut V, + shareable: &mut bool) + where E: TElement<'a> + TElementAttributes<'a>, + V: VecLike>>; } impl PresentationalHintSynthesis for Stylist { @@ -97,27 +105,20 @@ impl PresentationalHintSynthesis for Stylist { match element.get_local_name() { name if *name == atom!("td") => { - match element.get_length_attribute(LengthAttribute::Width) { - LengthOrPercentageOrAuto::Auto => {} - LengthOrPercentageOrAuto::Percentage(percentage) => { - let width_value = specified::LengthOrPercentageOrAuto::Percentage(percentage); - matching_rules_list.push(from_declaration( - PropertyDeclaration::Width(SpecifiedValue(width_value)))); - *shareable = false - } - LengthOrPercentageOrAuto::Length(length) => { - let width_value = specified::LengthOrPercentageOrAuto::Length(specified::Length::Absolute(length)); - matching_rules_list.push(from_declaration( - PropertyDeclaration::Width(SpecifiedValue(width_value)))); - *shareable = false - } - } + self.synthesize_presentational_hint_for_legacy_width_attribute( + element, + matching_rules_list, + shareable); self.synthesize_presentational_hint_for_legacy_border_attribute( element, matching_rules_list, shareable); } name if *name == atom!("table") => { + self.synthesize_presentational_hint_for_legacy_width_attribute( + element, + matching_rules_list, + shareable); self.synthesize_presentational_hint_for_legacy_border_attribute( element, matching_rules_list, @@ -221,6 +222,31 @@ impl PresentationalHintSynthesis for Stylist { } } } + + fn synthesize_presentational_hint_for_legacy_width_attribute<'a,E,V>( + &self, + element: E, + matching_rules_list: &mut V, + shareable: &mut bool) + where E: TElement<'a> + TElementAttributes<'a>, + V: VecLike>> { + match element.get_length_attribute(LengthAttribute::Width) { + LengthOrPercentageOrAuto::Auto => {} + LengthOrPercentageOrAuto::Percentage(percentage) => { + let width_value = specified::LengthOrPercentageOrAuto::Percentage(percentage); + matching_rules_list.push(from_declaration( + PropertyDeclaration::Width(SpecifiedValue(width_value)))); + *shareable = false + } + LengthOrPercentageOrAuto::Length(length) => { + let width_value = specified::LengthOrPercentageOrAuto::Length( + specified::Length::Absolute(length)); + matching_rules_list.push(from_declaration( + PropertyDeclaration::Width(SpecifiedValue(width_value)))); + *shareable = false + } + } + } } diff --git a/components/style/properties.mako.rs b/components/style/properties.mako.rs index d5130bf0f98..fdcbb8b9a59 100644 --- a/components/style/properties.mako.rs +++ b/components/style/properties.mako.rs @@ -1735,10 +1735,10 @@ pub mod longhands { impl ComputedValueAsSpecified for SpecifiedValue {} pub mod computed_value { macro_rules! define_text_align { - ( $( $name: ident => $discriminant: expr, )+ ) => { + ( $( $name: ident ( $string: expr ) => $discriminant: expr, )+ ) => { define_css_keyword_enum! { T: $( - stringify!($name) => $name, + $string => $name, )+ } impl T { @@ -1761,12 +1761,13 @@ pub mod longhands { } } define_text_align! { - start => 0, - end => 1, - left => 2, - right => 3, - center => 4, - justify => 5, + start("start") => 0, + end("end") => 1, + left("left") => 2, + right("right") => 3, + center("center") => 4, + justify("justify") => 5, + servo_center("-servo-center") => 6, } } #[inline] pub fn get_initial_value() -> computed_value::T { diff --git a/resources/presentational-hints.css b/resources/presentational-hints.css index 47404a5db0b..a22560b9e32 100644 --- a/resources/presentational-hints.css +++ b/resources/presentational-hints.css @@ -11,7 +11,6 @@ pre[wrap] { white-space: pre-wrap; } FIXME: also "align descendants" https://html.spec.whatwg.org/multipage/#align-descendants */ -center, div[align=center i], div[align=middle i] { text-align: center; } div[align=left i] { text-align: left; } div[align=right i] { text-align: right; } div[align=justify i] { text-align: justify; } diff --git a/resources/quirks-mode.css b/resources/quirks-mode.css index 284c877358a..78a3c2d8a9b 100644 --- a/resources/quirks-mode.css +++ b/resources/quirks-mode.css @@ -19,6 +19,17 @@ table { font-size: initial; line-height: initial; white-space: initial; + /* text-align: initial; -- see FIXME below */ +} + +/* + * FIXME(pcwalton): Actually saying `text-align: initial` above breaks `
` inside `
` + * in quirks mode. This is because we (following Gecko, WebKit, and Blink) implement the HTML5 + * align-descendants rules with a special `text-align: -servo-center`. `text-align: initial`, if + * placed on the `
` element per the spec, would break this behavior. So we place it on + * `` instead. + */ +tbody { text-align: initial; } diff --git a/resources/servo.css b/resources/servo.css index 6008dafc2db..143dad0bbbe 100644 --- a/resources/servo.css +++ b/resources/servo.css @@ -19,3 +19,5 @@ td[align="left"] { text-align: left; } td[align="center"] { text-align: center; } td[align="right"] { text-align: right; } +center, div[align=center i], div[align=middle i] { text-align: -servo-center; } + diff --git a/tests/ref/basic.list b/tests/ref/basic.list index b1c87ce6ea7..e747d7113db 100644 --- a/tests/ref/basic.list +++ b/tests/ref/basic.list @@ -261,6 +261,7 @@ experimental != overconstrained_block.html overconstrained_block_ref.html == root_pseudo_a.html root_pseudo_b.html experimental == rtl_body.html rtl_body_ref.html experimental == rtl_simple.html rtl_simple_ref.html +== servo_center_a.html servo_center_ref.html == setattribute_id_restyle_a.html setattribute_id_restyle_b.html == stacking_context_overflow_a.html stacking_context_overflow_ref.html == stacking_context_overflow_relative_outline_a.html stacking_context_overflow_relative_outline_ref.html @@ -279,6 +280,7 @@ experimental == rtl_simple.html rtl_simple_ref.html == table_percentage_capping_a.html table_percentage_capping_ref.html == table_percentage_width_a.html table_percentage_width_ref.html experimental == table_row_direction_a.html table_row_direction_ref.html +== table_width_attribute_a.html table_width_attribute_ref.html == text_align_complex_a.html text_align_complex_ref.html == text_align_justify_a.html text_align_justify_ref.html experimental == text_align_rtl.html text_align_rtl_ref.html diff --git a/tests/ref/servo_center_a.html b/tests/ref/servo_center_a.html new file mode 100644 index 00000000000..b43bf1830b0 --- /dev/null +++ b/tests/ref/servo_center_a.html @@ -0,0 +1,20 @@ + + + + + + +
+
a
+ + + + diff --git a/tests/ref/servo_center_ref.html b/tests/ref/servo_center_ref.html new file mode 100644 index 00000000000..3d72f794091 --- /dev/null +++ b/tests/ref/servo_center_ref.html @@ -0,0 +1,18 @@ + + + + + + +
a
+ + + + diff --git a/tests/ref/table_width_attribute_a.html b/tests/ref/table_width_attribute_a.html new file mode 100644 index 00000000000..463deb178de --- /dev/null +++ b/tests/ref/table_width_attribute_a.html @@ -0,0 +1,15 @@ + + + + + + +
a
+ + + + diff --git a/tests/ref/table_width_attribute_ref.html b/tests/ref/table_width_attribute_ref.html new file mode 100644 index 00000000000..7ccf3ea21a9 --- /dev/null +++ b/tests/ref/table_width_attribute_ref.html @@ -0,0 +1,16 @@ + + + + + + +
a
+ + + + diff --git a/tests/wpt/metadata/html/rendering/non-replaced-elements/tables/table-width-150percent.html.ini b/tests/wpt/metadata/html/rendering/non-replaced-elements/tables/table-width-150percent.html.ini index 02e6e907813..76a75c6f128 100644 --- a/tests/wpt/metadata/html/rendering/non-replaced-elements/tables/table-width-150percent.html.ini +++ b/tests/wpt/metadata/html/rendering/non-replaced-elements/tables/table-width-150percent.html.ini @@ -2,4 +2,4 @@ type: reftest reftype: == refurl: /html/rendering/non-replaced-elements/tables/table-width-150percent-ref.html - expected: FAIL + expected: PASS