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 upmin/max-width/height, replaced elements #25207
Conversation
highfive
commented
Dec 8, 2019
|
Heads up! This PR modifies the following files:
|
|
Lots of nits but otherwise nothing to say. |
|
|
||
| /// Convert | ||
| #[cfg(not(feature = "gecko"))] | ||
| pub fn to_option(self) -> Option<LengthPercentage> { |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
SimonSapin
Dec 9, 2019
Author
Member
This is subtle but I mean this method not as "if this enum is the LengthPercentage variant, access its field" but rather "losslessly convert all the information in this enum". If/when we add support for e.g. min-width: min-content https://drafts.csswg.org/css-sizing/#min-size-properties this enum will have additional variants like it does today for Gecko, this method will need to be removed, and the callers should be modified to handle those variants separately.
| .to_option() | ||
| .and_then(|lp| lp.as_length()); | ||
| let clamp = |l: Length| l.clamp_between_extremums(min_inline_size, max_inline_size); | ||
|
|
||
| // Percentages for 'width' are treated as 'auto' | ||
| let inline_size = inline_size.map(|lp| lp.as_length()); | ||
| // The (inner) min/max-content are only used for 'auto' | ||
| let mut outer = match inline_size.non_auto().flatten() { |
This comment has been minimized.
This comment has been minimized.
nox
Dec 9, 2019
Member
Can't you use and_then to define inline_size and then remove the flatten call?
This comment has been minimized.
This comment has been minimized.
SimonSapin
Dec 9, 2019
Author
Member
The call two lines above is LengthPercentageOrAuto::map, not Option::map. Maybe we should have LengthPercentageOrAuto::and_then that return Auto when its closure returns Option::None?
| @@ -299,7 +298,7 @@ impl Drop for BoxSlot<'_> { | |||
| pub(crate) trait NodeExt<'dom>: 'dom + Copy + LayoutNode + Send + Sync { | |||
| fn is_element(self) -> bool; | |||
| fn as_text(self) -> Option<String>; | |||
| fn as_image(self) -> Option<(Option<Arc<NetImage>>, Vec2<Length>)>; | |||
| fn as_image(self) -> Option<(Option<Arc<NetImage>>, Vec2<f64>)>; | |||
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
SimonSapin
Dec 9, 2019
Author
Member
It’s not Length because it is measured in image pixels rather than CSS px.
I wanted to make it u32 but it’s already divided by script::dom::htmlimageelement::ImageRequest::current_pixel_density. I’m not sure what that density means exactly or if diving there is correct.
It could be CSSFloat. It probably wouldn’t affect much since it’s not kept in memory for a long time.
| let intrinsic_size = physical::Vec2 { | ||
| x: self.intrinsic_width, | ||
| y: self.intrinsic_height, | ||
| }; |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
SimonSapin
Dec 9, 2019
Author
Member
Could be either. An earlier version of the comment on the field declaration talked about "all three components"
| let clamp = |inline_size: Length, block_size: Length| Vec2 { | ||
| inline: inline_size.clamp_between_extremums(min_box_size.inline, max_box_size.inline), | ||
| block: block_size.clamp_between_extremums(min_box_size.block, max_box_size.block), |
This comment has been minimized.
This comment has been minimized.
nox
Dec 9, 2019
Member
Wondering if we should have a meethod for that, don't we do that for non-replaced things elsewhere in the code?
This comment has been minimized.
This comment has been minimized.
SimonSapin
Dec 9, 2019
Author
Member
I grepped through the code and didn’t find another instance of computing both at the same time.
In block layout for example, we compute the used width before recurring and the used height after.
| (LengthOrAuto::LengthPercentage(inline), LengthOrAuto::LengthPercentage(block)) => { | ||
| clamp(inline, block) | ||
| }, | ||
| (LengthOrAuto::LengthPercentage(inline), LengthOrAuto::Auto) => { | ||
| clamp(inline, inline / intrinsic_ratio) | ||
| let block = if let Some(i_over_b) = intrinsic_ratio { |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
SimonSapin
Dec 9, 2019
Author
Member
The problem these new names try to address is that when A divided by B is called a ratio, B divided by A is also called a ratio although they’re not interchangeable. Code that uses that ratio sometimes to multiple and sometimes to divide a length, having a variable name that indicates the “direction” of the ratio helps check if those are correct by doing pseudo-dimensional analysis.
We could declare that an aspect ratio is by convention always a width divided by a height. But this code work in flow-relative dimensions and accesses a ratio field in physical dimensions. I’ve added inline_size_over_block_size_intrinsic_ratio to make that conversion.
I’m open to other names, but I’d prefer if they indicate the “direction” of the ratio somehow. Or maybe we could provide that indication in doc-comments and code comments?
This comment has been minimized.
This comment has been minimized.
| &self, | ||
| style: &ComputedValues, | ||
| ) -> Option<CSSFloat> { | ||
| self.intrinsic_ratio.map(|width_over_height| { |
This comment has been minimized.
This comment has been minimized.
nox
Dec 9, 2019
Member
Sorry, but again, I find the code more readable when that is just named ratio.
| Ok(replaced) => { | ||
| // https://drafts.csswg.org/css2/visudet.html#abs-replaced-width | ||
| // https://drafts.csswg.org/css2/visudet.html#abs-replaced-height | ||
| let u = replaced.used_size_as_if_inline_element(&containing_block.into(), style); |
This comment has been minimized.
This comment has been minimized.
| let margin_end; | ||
| let used_size; | ||
| if let LengthOrAuto::LengthPercentage(s) = size { | ||
| used_size = s; |
This comment has been minimized.
This comment has been minimized.
| @@ -208,7 +208,7 @@ impl<'a> AbsolutelyPositionedFragment<'a> { | |||
| padding_border_sum: Length, | |||
| computed_margin_start: LengthOrAuto, | |||
| computed_margin_end: LengthOrAuto, | |||
| solve_margins: impl FnOnce(Length) -> (Length, Length), | |||
| avoid_negative_margin_start: bool, | |||
This comment has been minimized.
This comment has been minimized.
nox
Dec 9, 2019
Member
Please remove this change or introduce yet another new type for this boolean.
This comment has been minimized.
This comment has been minimized.
SimonSapin
Dec 9, 2019
Author
Member
Even with exactly two call sites, that both have a comment to repeat the name of the parameter?
This comment has been minimized.
This comment has been minimized.
nox
Dec 9, 2019
Member
IIRC the collapsing margin stuff doesn't have more callers than that, and the comment can go if you introduce a type, but as I said on IRC, all my nits are optional.
|
This conflicts with #25203, I’ll push a rebase + changes after that one lands. |
Percentage `width` are treated as `auto` for the purpose of min/max-content computation, so they also need to be considered when testing “wether width is auto”
|
@bors-servo r=nox |
|
|
min/max-width/height, replaced elements
|
|
SimonSapin commentedDec 8, 2019
No description provided.