mirror of
https://github.com/servo/servo.git
synced 2025-08-05 05:30:08 +01:00
Auto merge of #7825 - eefriedman:div-align, r=mbrubeck
Fully implement the "align descendants" rule for div. This adds -servo-left and -servo-right to complement -servo-center. ~~This intentionally doesn't try to address issue #7301.~~ Commit added to address #7301. <!-- Reviewable:start --> [<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/7825) <!-- Reviewable:end -->
This commit is contained in:
commit
ab42ca4296
9 changed files with 194 additions and 40 deletions
|
@ -1466,8 +1466,9 @@ impl BlockFlow {
|
||||||
|
|
||||||
// Per CSS 2.1 § 16.3.1, text alignment propagates to all children in flow.
|
// Per CSS 2.1 § 16.3.1, text alignment propagates to all children in flow.
|
||||||
//
|
//
|
||||||
// TODO(#2018, pcwalton): Do this in the cascade instead.
|
// TODO(#2265, pcwalton): Do this in the cascade instead.
|
||||||
flow::mut_base(kid).flags.propagate_text_alignment_from_parent(flags.clone());
|
let containing_block_text_align = self.fragment.style().get_inheritedtext().text_align;
|
||||||
|
flow::mut_base(kid).flags.set_text_align(containing_block_text_align);
|
||||||
|
|
||||||
// Handle `text-indent` on behalf of any inline children that we have. This is
|
// Handle `text-indent` on behalf of any inline children that we have. This is
|
||||||
// necessary because any percentages are relative to the containing block, which only
|
// necessary because any percentages are relative to the containing block, which only
|
||||||
|
@ -2272,9 +2273,6 @@ pub trait ISizeAndMarginsComputer {
|
||||||
(_, box_sizing::T::content_box) => {}
|
(_, box_sizing::T::content_box) => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The text alignment of a block flow is the text alignment of its box's style.
|
|
||||||
block.base.flags.set_text_align(style.get_inheritedtext().text_align);
|
|
||||||
|
|
||||||
let margin = style.logical_margin();
|
let margin = style.logical_margin();
|
||||||
let position = style.logical_position();
|
let position = style.logical_position();
|
||||||
|
|
||||||
|
@ -2438,6 +2436,7 @@ pub trait ISizeAndMarginsComputer {
|
||||||
// Check for direction of parent flow (NOT Containing Block)
|
// Check for direction of parent flow (NOT Containing Block)
|
||||||
let block_mode = block.base.writing_mode;
|
let block_mode = block.base.writing_mode;
|
||||||
let container_mode = block.base.block_container_writing_mode;
|
let container_mode = block.base.block_container_writing_mode;
|
||||||
|
let block_align = block.base.flags.text_align();
|
||||||
|
|
||||||
// FIXME (mbrubeck): Handle vertical writing modes.
|
// FIXME (mbrubeck): Handle vertical writing modes.
|
||||||
let parent_has_same_direction = container_mode.is_bidi_ltr() == block_mode.is_bidi_ltr();
|
let parent_has_same_direction = container_mode.is_bidi_ltr() == block_mode.is_bidi_ltr();
|
||||||
|
@ -2466,20 +2465,23 @@ pub trait ISizeAndMarginsComputer {
|
||||||
(MaybeAuto::Specified(margin_start),
|
(MaybeAuto::Specified(margin_start),
|
||||||
MaybeAuto::Specified(inline_size),
|
MaybeAuto::Specified(inline_size),
|
||||||
MaybeAuto::Specified(margin_end)) => {
|
MaybeAuto::Specified(margin_end)) => {
|
||||||
match (input.text_align, parent_has_same_direction) {
|
// servo_left, servo_right, and servo_center are used to implement
|
||||||
(text_align::T::servo_center, _) => {
|
// the "align descendants" rule in HTML5 § 14.2.
|
||||||
// This is used for `<center>` and friends per HTML5 § 14.3.3. Make the
|
if block_align == text_align::T::servo_center {
|
||||||
// inline-start and inline-end margins equal per HTML5 § 14.2.
|
// Ignore any existing margins, and make the inline-start and
|
||||||
let margin = (available_inline_size - inline_size).scale_by(0.5);
|
// inline-end margins equal.
|
||||||
(margin, inline_size, margin)
|
let margin = (available_inline_size - inline_size).scale_by(0.5);
|
||||||
}
|
(margin, inline_size, margin)
|
||||||
(_, true) => {
|
} else {
|
||||||
// Ignore the end margin.
|
let ignore_end_margin = match block_align {
|
||||||
|
text_align::T::servo_left => block_mode.is_bidi_ltr(),
|
||||||
|
text_align::T::servo_right => !block_mode.is_bidi_ltr(),
|
||||||
|
_ => parent_has_same_direction,
|
||||||
|
};
|
||||||
|
if ignore_end_margin {
|
||||||
(margin_start, inline_size, available_inline_size -
|
(margin_start, inline_size, available_inline_size -
|
||||||
(margin_start + inline_size))
|
(margin_start + inline_size))
|
||||||
}
|
} else {
|
||||||
(_, false) => {
|
|
||||||
// Ignore the start margin.
|
|
||||||
(available_inline_size - (margin_end + inline_size),
|
(available_inline_size - (margin_end + inline_size),
|
||||||
inline_size,
|
inline_size,
|
||||||
margin_end)
|
margin_end)
|
||||||
|
|
|
@ -656,14 +656,6 @@ static HAS_FLOATED_DESCENDANTS_BITMASK: FlowFlags = FlowFlags { bits: 0b0000_001
|
||||||
static TEXT_ALIGN_SHIFT: usize = 11;
|
static TEXT_ALIGN_SHIFT: usize = 11;
|
||||||
|
|
||||||
impl FlowFlags {
|
impl FlowFlags {
|
||||||
/// Propagates text alignment flags from an appropriate parent flow per CSS 2.1.
|
|
||||||
///
|
|
||||||
/// FIXME(#2265, pcwalton): It would be cleaner and faster to make this a derived CSS property
|
|
||||||
/// `-servo-text-align-in-effect`.
|
|
||||||
pub fn propagate_text_alignment_from_parent(&mut self, parent_flags: FlowFlags) {
|
|
||||||
self.set_text_align_override(parent_flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn text_align(self) -> text_align::T {
|
pub fn text_align(self) -> text_align::T {
|
||||||
text_align::T::from_u32((self & TEXT_ALIGN).bits() >> TEXT_ALIGN_SHIFT).unwrap()
|
text_align::T::from_u32((self & TEXT_ALIGN).bits() >> TEXT_ALIGN_SHIFT).unwrap()
|
||||||
|
@ -675,11 +667,6 @@ impl FlowFlags {
|
||||||
FlowFlags::from_bits(value.to_u32() << TEXT_ALIGN_SHIFT).unwrap();
|
FlowFlags::from_bits(value.to_u32() << TEXT_ALIGN_SHIFT).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn set_text_align_override(&mut self, parent: FlowFlags) {
|
|
||||||
self.insert(parent & TEXT_ALIGN);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn union_floated_descendants_flags(&mut self, other: FlowFlags) {
|
pub fn union_floated_descendants_flags(&mut self, other: FlowFlags) {
|
||||||
self.insert(other & HAS_FLOATED_DESCENDANTS_BITMASK);
|
self.insert(other & HAS_FLOATED_DESCENDANTS_BITMASK);
|
||||||
|
|
|
@ -1019,8 +1019,14 @@ impl InlineFlow {
|
||||||
// Translate `left` and `right` to logical directions.
|
// Translate `left` and `right` to logical directions.
|
||||||
let is_ltr = fragments.fragments[0].style().writing_mode.is_bidi_ltr();
|
let is_ltr = fragments.fragments[0].style().writing_mode.is_bidi_ltr();
|
||||||
let line_align = match (line_align, is_ltr) {
|
let line_align = match (line_align, is_ltr) {
|
||||||
(text_align::T::left, true) | (text_align::T::right, false) => text_align::T::start,
|
(text_align::T::left, true) |
|
||||||
(text_align::T::left, false) | (text_align::T::right, true) => text_align::T::end,
|
(text_align::T::servo_left, true) |
|
||||||
|
(text_align::T::right, false) |
|
||||||
|
(text_align::T::servo_right, false) => text_align::T::start,
|
||||||
|
(text_align::T::left, false) |
|
||||||
|
(text_align::T::servo_left, false) |
|
||||||
|
(text_align::T::right, true) |
|
||||||
|
(text_align::T::servo_right, true) => text_align::T::end,
|
||||||
_ => line_align
|
_ => line_align
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1040,7 +1046,10 @@ impl InlineFlow {
|
||||||
inline_start_position_for_fragment = inline_start_position_for_fragment +
|
inline_start_position_for_fragment = inline_start_position_for_fragment +
|
||||||
slack_inline_size
|
slack_inline_size
|
||||||
}
|
}
|
||||||
text_align::T::left | text_align::T::right => unreachable!()
|
text_align::T::left |
|
||||||
|
text_align::T::servo_left |
|
||||||
|
text_align::T::right |
|
||||||
|
text_align::T::servo_right => unreachable!()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lay out the fragments in visual order.
|
// Lay out the fragments in visual order.
|
||||||
|
|
|
@ -2012,6 +2012,8 @@ pub mod longhands {
|
||||||
center("center") => 4,
|
center("center") => 4,
|
||||||
justify("justify") => 5,
|
justify("justify") => 5,
|
||||||
servo_center("-servo-center") => 6,
|
servo_center("-servo-center") => 6,
|
||||||
|
servo_left("-servo-left") => 7,
|
||||||
|
servo_right("-servo-right") => 8,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[inline] pub fn get_initial_value() -> computed_value::T {
|
#[inline] pub fn get_initial_value() -> computed_value::T {
|
||||||
|
|
|
@ -7,12 +7,9 @@ https://html.spec.whatwg.org/multipage/#presentational-hints
|
||||||
|
|
||||||
pre[wrap] { white-space: pre-wrap; }
|
pre[wrap] { white-space: pre-wrap; }
|
||||||
|
|
||||||
/*
|
div[align=left i] { text-align: -servo-left; }
|
||||||
FIXME: also "align descendants"
|
div[align=right i] { text-align: -servo-right; }
|
||||||
https://html.spec.whatwg.org/multipage/#align-descendants
|
div[align=center i], div[align=middle i] { text-align: -servo-center; }
|
||||||
*/
|
|
||||||
div[align=left i] { text-align: left; }
|
|
||||||
div[align=right i] { text-align: right; }
|
|
||||||
div[align=justify i] { text-align: justify; }
|
div[align=justify i] { text-align: justify; }
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -29,5 +29,5 @@ td[align="left"] { text-align: left; }
|
||||||
td[align="center"] { text-align: center; }
|
td[align="center"] { text-align: center; }
|
||||||
td[align="right"] { text-align: right; }
|
td[align="right"] { text-align: right; }
|
||||||
|
|
||||||
center, div[align=center i], div[align=middle i] { text-align: -servo-center; }
|
center { text-align: -servo-center; }
|
||||||
|
|
||||||
|
|
|
@ -4285,6 +4285,16 @@
|
||||||
],
|
],
|
||||||
"url": "/html/rendering/non-replaced-elements/flow-content-0/figure.html"
|
"url": "/html/rendering/non-replaced-elements/flow-content-0/figure.html"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "html/rendering/non-replaced-elements/flow-content-0/div-align.html",
|
||||||
|
"references": [
|
||||||
|
[
|
||||||
|
"/html/rendering/non-replaced-elements/flow-content-0/div-align-ref.html",
|
||||||
|
"=="
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"url": "/html/rendering/non-replaced-elements/flow-content-0/div-align.html"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "html/rendering/non-replaced-elements/phrasing-content-0/font-element-text-decoration-color/001-a.html",
|
"path": "html/rendering/non-replaced-elements/phrasing-content-0/font-element-text-decoration-color/001-a.html",
|
||||||
"references": [
|
"references": [
|
||||||
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset=utf-8>
|
||||||
|
<link rel="match" href="div-align-ref.html">
|
||||||
|
<style>
|
||||||
|
.test { width: 50px; background-color: yellow; }
|
||||||
|
.center { text-align: center; }
|
||||||
|
.center .test { margin: 0 auto; }
|
||||||
|
.left { text-align: left; }
|
||||||
|
.left .test { margin-right: auto; }
|
||||||
|
.right { text-align: right; }
|
||||||
|
.right .test { margin-left: auto; }
|
||||||
|
.rtl { direction: rtl; }
|
||||||
|
.ltr { direction: ltr; }
|
||||||
|
.left .margin { margin-left: 1em; }
|
||||||
|
.right .margin { margin-right: 1em; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<!-- Centered tests -->
|
||||||
|
<div class=center>
|
||||||
|
<div class=test>t א</div>
|
||||||
|
<div class="test rtl">t א</div>
|
||||||
|
<div class="test margin">t א</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class=center>
|
||||||
|
<div class="test left">t א</div>
|
||||||
|
<div class="test right">t א</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class=left>
|
||||||
|
<div class=center>
|
||||||
|
<div class=test>t א</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Left-aligned tests -->
|
||||||
|
<div class=left>
|
||||||
|
<div class=test>t א</div>
|
||||||
|
<div class="test rtl">t א</div>
|
||||||
|
<div class="test margin">t א</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="left rtl">
|
||||||
|
<div class=test>t א</div>
|
||||||
|
<div class="test ltr">t א</div>
|
||||||
|
<div class="test margin">t א</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class=left>
|
||||||
|
<div class="test center">t א</div>
|
||||||
|
<div class="test right">t א</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Right-aligned tests -->
|
||||||
|
<div class=right>
|
||||||
|
<div class=test>t א</div>
|
||||||
|
<div class="test rtl">t א</div>
|
||||||
|
<div class="test margin">t א</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="right rtl">
|
||||||
|
<div class=test>t א</div>
|
||||||
|
<div class="test ltr">t א</div>
|
||||||
|
<div class="test margin">t א</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class=right>
|
||||||
|
<div class="test left">t א</div>
|
||||||
|
<div class="test center">t א</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset=utf-8>
|
||||||
|
<style>
|
||||||
|
.test { width: 50px; background-color: yellow; }
|
||||||
|
.rtl { direction: rtl; }
|
||||||
|
.ltr { direction: ltr; }
|
||||||
|
[align=left] .margin { margin-left: 1em }
|
||||||
|
[align=right] .margin { margin-right: 1em }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<!-- Centered tests -->
|
||||||
|
<div align=center>
|
||||||
|
<div class=test>t א</div>
|
||||||
|
<div class="test rtl">t א</div>
|
||||||
|
<div class="test margin">t א</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div align=center>
|
||||||
|
<div class=test align=left>t א</div>
|
||||||
|
<div class=test align=right>t א</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div align=left>
|
||||||
|
<div align=center>
|
||||||
|
<div class=test>t א</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Left-aligned tests -->
|
||||||
|
<div align=left>
|
||||||
|
<div class=test>t א</div>
|
||||||
|
<div class="test rtl">t א</div>
|
||||||
|
<div class="test margin">t א</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div align=left class=rtl>
|
||||||
|
<div class=test>t א</div>
|
||||||
|
<div class="test ltr">t א</div>
|
||||||
|
<div class="test margin">t א</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div align=left>
|
||||||
|
<div class=test align=center>t א</div>
|
||||||
|
<div class=test align=right>t א</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Right-aligned tests -->
|
||||||
|
<div align=right>
|
||||||
|
<div class=test>t א</div>
|
||||||
|
<div class="test rtl">t א</div>
|
||||||
|
<div class="test margin">t א</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div align=right class=rtl>
|
||||||
|
<div class=test>t א</div>
|
||||||
|
<div class="test ltr">t א</div>
|
||||||
|
<div class="test margin">t א</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div align=right>
|
||||||
|
<div class=test align=left>t א</div>
|
||||||
|
<div class=test align=center>t א</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue