Auto merge of #13705 - pcwalton:incremental-float, r=notriddle

layout: Don't touch the inline positions of block children unless they are to be reflowed.

See the comment added to
`BlockFlow::propagate_assigned_inline_size_to_children()` for details.

Closes #13704.

r? @notriddle

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/13705)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2016-10-12 16:00:37 -05:00 committed by GitHub
commit 0ffbba94fa
2 changed files with 35 additions and 1 deletions

View file

@ -1390,8 +1390,22 @@ impl BlockFlow {
// and its inline-size is our content inline-size. // and its inline-size is our content inline-size.
let kid_mode = flow::base(kid).writing_mode; let kid_mode = flow::base(kid).writing_mode;
{ {
// Don't assign positions to children unless they're going to be reflowed.
// Otherwise, the position we assign might be incorrect and never fixed up. (Issue
// #13704.)
//
// For instance, floats have their true inline position calculated in
// `assign_block_size()`, which won't do anything unless `REFLOW` is set. So, if a
// float child does not have `REFLOW` set, we must be careful to avoid touching its
// inline position, as no logic will run afterward to set its true value.
let kid_base = flow::mut_base(kid); let kid_base = flow::mut_base(kid);
if kid_base.flags.contains(INLINE_POSITION_IS_STATIC) { let reflow_damage = if kid_base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
REFLOW_OUT_OF_FLOW
} else {
REFLOW
};
if kid_base.flags.contains(INLINE_POSITION_IS_STATIC) &&
kid_base.restyle_damage.contains(reflow_damage) {
kid_base.position.start.i = kid_base.position.start.i =
if kid_mode.is_bidi_ltr() == containing_block_mode.is_bidi_ltr() { if kid_mode.is_bidi_ltr() == containing_block_mode.is_bidi_ltr() {
inline_start_content_edge inline_start_content_edge

View file

@ -0,0 +1,20 @@
<!DOCTYPE html>
<style>
.float {
float: right;
}
.bad {
display: inline-block;
background-color: gray;
height: 30px;
width: 30px;
}
.bad:hover {
opacity: .85;
}
</style>
<div class=float>
<a class="bad"></a>
</div>
<p style="clear: both">Mouse over the preceding gray square. It should change color but remain in place.</p>