Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.
Sign upFirst pass at implementing the Flex Layout Algorithm #27044
Conversation
highfive
commented
Jun 22, 2020
|
Heads up! This PR modifies the following files:
|
|
r? @nox |
|
@bors-servo try=wpt-2020 |
First pass at implementing the Flex Layout Algorithm
|
|
The "expected" crashes are panics in I suspect that any test with both flexbox and abspos is potentially impacted, so marking a couple file names as knows intermittent is not gonna help much. I’m looking into this to hopefully fix it before landing. More generally though, @nox do you have thoughts on:
|
…x item
|
Figured it out. This issue is when implementing this bit of spec:
“Do layout” has the side effect of collecting absolutely-positioned descendants into @bors-servo try=wpt-2020 |
First pass at implementing the Flex Layout Algorithm
|
|
|
I'm a bit confused why some iterators need to be collected when they are used a single time any way, but otherwise, LGTM. |
|
For example the module-level |
|
@bors-servo r=nox |
|
|
|
|
|
@bors-servo retry |
|
|
|
@bors-servo retry |
|
|
| }, | ||
| }; | ||
| let fragments = flex_lines | ||
| .into_iter() |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Manishearth
Jul 13, 2020
Member
I guess we're typically iterating over a small number of items so it won't matter much
This comment has been minimized.
This comment has been minimized.
SimonSapin
Jul 13, 2020
Author
Member
This PR was getting big, so at some point I stopped refactoring and focused on getting it landed. I’m sure it can be improved still.
There’s a limitation though where the returned impl Iterator needs to take ownership of every closure captures, it cannot borrow stuff on the stack. Some .collect() calls help with that.
| // “When specified on a flex item, the `auto` keyword retrieves | ||
| // the value of the main size property as the used `flex-basis`.” | ||
| match content_box_size.main { | ||
| LengthOrAuto::LengthPercentage(length) => FlexBasis::Size(length), |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
SimonSapin
Jul 13, 2020
Author
Member
content_box_size here originally comes from the ComputedValuesExt method of the same name, which already takes care of resolving percentages (but not auto)
|
|
||
| let mut content_block_size_option_dance = None; | ||
| let fragments = | ||
| positioning_context.adjust_static_positions(tree_rank, |positioning_context| { |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
SimonSapin
Jul 21, 2020
Author
Member
The BoxFragment::content_rect::start_corner position of a fragment is a point in a coordinate space whose origin is the start corner of the parent in the in the fragment tree. Using relative coordinates like this allows translating an entire sub-tree by modifying the coordinates of its root fragment.
When hoisting an absolutely-positioned box "up" the tree, we’re effectively moving to another coordinate space. HoistedAbsolutelyPositionedBox::box_offsets may contain coordinates that will contribute to the position of the eventual fragment. adjust_static_positions effectively converts them to another coordinate space.
| let pbm = replaced | ||
| .style | ||
| .padding_border_margin(flex_context.containing_block); | ||
| let size = replaced.contents.used_size_as_if_inline_element( |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
SimonSapin
Jul 21, 2020
Author
Member
This code path is for replaced elements. I think auto and fit-content resolve to the same thing for those, though I might be wrong for some cases and it’s possible that we don’t implement everything in https://drafts.csswg.org/css-sizing/#intrinsic accurately.
| } | ||
| flex_context | ||
| .positioning_context | ||
| .append(item_result.positioning_context); |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
SimonSapin
Jul 21, 2020
Author
Member
IndependentFormattingContext::layout takes a &mut PositioningContext parameter, and has the side effect of (possibly) appending to it. To isolate this side-effect, we construct a new PositioningContext for each flex item, and keep it with the "result of layout". If we end up doing layout for a flex item again because of align-self: stretch, we throw away that PositioningContext and make a new one. This was added in 22b60d8. At some point though we want a single PositioningContext for the entire flex container, so we append the item-specific ones together.
I am working on a branch that removes &mut PositioningContext parameters everywhere and keeps hoisted boxes in respective "result of layout" types instead.
SimonSapin commentedJun 22, 2020
•
edited
CC #26639