mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
Implement keyword sizes for replaced elements (#34091)
Signed-off-by: Oriol Brufau <obrufau@igalia.com>
This commit is contained in:
parent
3289e7d84d
commit
ee7b207f96
18 changed files with 342 additions and 106 deletions
|
@ -18,7 +18,7 @@ use style::properties::longhands::box_sizing::computed_value::T as BoxSizing;
|
|||
use style::properties::longhands::flex_direction::computed_value::T as FlexDirection;
|
||||
use style::properties::longhands::flex_wrap::computed_value::T as FlexWrap;
|
||||
use style::properties::ComputedValues;
|
||||
use style::values::computed::length::Size;
|
||||
use style::values::computed::length::Size as StyleSize;
|
||||
use style::values::generics::flex::GenericFlexBasis as FlexBasis;
|
||||
use style::values::generics::length::{GenericLengthPercentageOrAuto, LengthPercentageOrNormal};
|
||||
use style::values::specified::align::AlignFlags;
|
||||
|
@ -32,7 +32,7 @@ use crate::cell::ArcRefCell;
|
|||
use crate::context::LayoutContext;
|
||||
use crate::formatting_contexts::{Baselines, IndependentFormattingContext, IndependentLayout};
|
||||
use crate::fragment_tree::{BoxFragment, CollapsedBlockMargins, Fragment, FragmentFlags};
|
||||
use crate::geom::{AuOrAuto, LogicalRect, LogicalSides, LogicalVec2};
|
||||
use crate::geom::{AuOrAuto, LogicalRect, LogicalSides, LogicalVec2, Size};
|
||||
use crate::positioned::{
|
||||
relative_adjustement, AbsolutelyPositionedBox, PositioningContext, PositioningContextLength,
|
||||
};
|
||||
|
@ -1873,11 +1873,16 @@ impl FlexItem<'_> {
|
|||
containing_block,
|
||||
&replaced.style,
|
||||
LogicalVec2 {
|
||||
inline: AuOrAuto::LengthPercentage(inline_size),
|
||||
block: block_size,
|
||||
inline: Size::Numeric(inline_size),
|
||||
block: block_size.non_auto().map_or(Size::Initial, Size::Numeric),
|
||||
},
|
||||
flex_axis.vec2_to_flow_relative(self.content_min_size),
|
||||
flex_axis.vec2_to_flow_relative(self.content_max_size),
|
||||
flex_axis
|
||||
.vec2_to_flow_relative(self.content_min_size)
|
||||
.map(|size| Size::Numeric(*size)),
|
||||
flex_axis
|
||||
.vec2_to_flow_relative(self.content_max_size)
|
||||
.map(|size| size.map_or(Size::Initial, Size::Numeric)),
|
||||
flex_axis.vec2_to_flow_relative(self.pbm_auto_is_zero),
|
||||
);
|
||||
let hypothetical_cross_size = flex_axis.vec2_to_flex_relative(size).cross;
|
||||
|
||||
|
@ -2505,7 +2510,7 @@ impl FlexItemBox {
|
|||
|
||||
let used_flex_basis = match &style.get_position().flex_basis {
|
||||
FlexBasis::Content => FlexBasis::Content,
|
||||
FlexBasis::Size(Size::LengthPercentage(length_percentage)) => {
|
||||
FlexBasis::Size(StyleSize::LengthPercentage(length_percentage)) => {
|
||||
let apply_box_sizing = |length: Au| {
|
||||
match style.get_position().box_sizing {
|
||||
BoxSizing::ContentBox => length,
|
||||
|
@ -2678,9 +2683,12 @@ impl FlexItemBox {
|
|||
.used_size_as_if_inline_element_from_content_box_sizes(
|
||||
flex_context.containing_block,
|
||||
&replaced.style,
|
||||
content_box_size,
|
||||
min_size,
|
||||
max_size,
|
||||
content_box_size
|
||||
.map(|size| size.non_auto().map_or(Size::Initial, Size::Numeric)),
|
||||
min_size.map(|size| Size::Numeric(*size)),
|
||||
max_size.map(|size| size.map_or(Size::Initial, Size::Numeric)),
|
||||
padding_border_margin.padding_border_sums +
|
||||
padding_border_margin.margin.auto_is(Au::zero).sum(),
|
||||
)
|
||||
.block
|
||||
},
|
||||
|
|
|
@ -1359,9 +1359,8 @@ fn layout_in_flow_replaced_block_level(
|
|||
replaced: &ReplacedContent,
|
||||
mut sequential_layout_state: Option<&mut SequentialLayoutState>,
|
||||
) -> BoxFragment {
|
||||
let content_box_sizes_and_pbm: ContentBoxSizesAndPBMDeprecated = style
|
||||
.content_box_sizes_and_padding_border_margin(&containing_block.into())
|
||||
.into();
|
||||
let content_box_sizes_and_pbm =
|
||||
style.content_box_sizes_and_padding_border_margin(&containing_block.into());
|
||||
let pbm = &content_box_sizes_and_pbm.pbm;
|
||||
let content_size = replaced.used_size_as_if_inline_element(
|
||||
containing_block,
|
||||
|
@ -2018,7 +2017,7 @@ impl IndependentFormattingContext {
|
|||
.used_size_as_if_inline_element(
|
||||
containing_block,
|
||||
&replaced.style,
|
||||
&content_box_sizes_and_pbm.clone().into(),
|
||||
&content_box_sizes_and_pbm,
|
||||
)
|
||||
.to_physical_size(container_writing_mode);
|
||||
let fragments = replaced.contents.make_fragments(
|
||||
|
|
|
@ -466,7 +466,7 @@ impl HoistedAbsolutelyPositionedBox {
|
|||
.used_size_as_if_inline_element(
|
||||
containing_block,
|
||||
&style,
|
||||
&content_box_sizes_and_pbm.into(),
|
||||
&content_box_sizes_and_pbm,
|
||||
)
|
||||
.map(|size| Size::Numeric(*size));
|
||||
(used_size, Default::default(), Default::default())
|
||||
|
|
|
@ -6,7 +6,7 @@ use std::cell::LazyCell;
|
|||
use std::fmt;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use app_units::{Au, MAX_AU};
|
||||
use app_units::Au;
|
||||
use base::id::{BrowsingContextId, PipelineId};
|
||||
use canvas_traits::canvas::{CanvasId, CanvasMsg, FromLayoutMsg};
|
||||
use data_url::DataUrl;
|
||||
|
@ -28,9 +28,9 @@ use webrender_api::ImageKey;
|
|||
use crate::context::LayoutContext;
|
||||
use crate::dom::NodeExt;
|
||||
use crate::fragment_tree::{BaseFragmentInfo, Fragment, IFrameFragment, ImageFragment};
|
||||
use crate::geom::{LogicalVec2, PhysicalPoint, PhysicalRect, PhysicalSize};
|
||||
use crate::geom::{LogicalVec2, PhysicalPoint, PhysicalRect, PhysicalSize, Size};
|
||||
use crate::sizing::InlineContentSizesResult;
|
||||
use crate::style_ext::{AspectRatio, Clamp, ComputedValuesExt, ContentBoxSizesAndPBMDeprecated};
|
||||
use crate::style_ext::{AspectRatio, Clamp, ComputedValuesExt, ContentBoxSizesAndPBM};
|
||||
use crate::{AuOrAuto, ContainingBlock, IndefiniteContainingBlock};
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
|
@ -444,16 +444,16 @@ impl ReplacedContent {
|
|||
&self,
|
||||
containing_block: &ContainingBlock,
|
||||
style: &ComputedValues,
|
||||
content_box_sizes_and_pbm: &ContentBoxSizesAndPBMDeprecated,
|
||||
content_box_sizes_and_pbm: &ContentBoxSizesAndPBM,
|
||||
) -> LogicalVec2<Au> {
|
||||
let pbm = &content_box_sizes_and_pbm.pbm;
|
||||
self.used_size_as_if_inline_element_from_content_box_sizes(
|
||||
containing_block,
|
||||
style,
|
||||
content_box_sizes_and_pbm.content_box_size,
|
||||
content_box_sizes_and_pbm
|
||||
.content_min_box_size
|
||||
.auto_is(Au::zero),
|
||||
content_box_sizes_and_pbm.content_min_box_size,
|
||||
content_box_sizes_and_pbm.content_max_box_size,
|
||||
pbm.padding_border_sums + pbm.margin.auto_is(Au::zero).sum(),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -476,76 +476,138 @@ impl ReplacedContent {
|
|||
///
|
||||
/// Also used in other cases, for example
|
||||
/// <https://drafts.csswg.org/css2/visudet.html#block-replaced-width>
|
||||
///
|
||||
/// The logic differs from CSS2 in order to properly handle `aspect-ratio` and keyword sizes.
|
||||
/// Each axis can have preferred, min and max sizing constraints, plus constraints transferred
|
||||
/// from the other axis if there is an aspect ratio, plus a natural and default size.
|
||||
/// In case of conflict, the order of precedence (from highest to lowest) is:
|
||||
/// 1. Non-transferred min constraint
|
||||
/// 2. Non-transferred max constraint
|
||||
/// 3. Non-transferred preferred constraint
|
||||
/// 4. Transferred min constraint
|
||||
/// 5. Transferred max constraint
|
||||
/// 6. Transferred preferred constraint
|
||||
/// 7. Natural size
|
||||
/// 8. Default object size
|
||||
///
|
||||
/// <https://drafts.csswg.org/css-sizing-4/#aspect-ratio-size-transfers>
|
||||
/// <https://github.com/w3c/csswg-drafts/issues/6071#issuecomment-2243986313>
|
||||
pub(crate) fn used_size_as_if_inline_element_from_content_box_sizes(
|
||||
&self,
|
||||
containing_block: &ContainingBlock,
|
||||
style: &ComputedValues,
|
||||
box_size: LogicalVec2<AuOrAuto>,
|
||||
min_box_size: LogicalVec2<Au>,
|
||||
max_box_size: LogicalVec2<Option<Au>>,
|
||||
box_size: LogicalVec2<Size<Au>>,
|
||||
min_box_size: LogicalVec2<Size<Au>>,
|
||||
max_box_size: LogicalVec2<Size<Au>>,
|
||||
pbm_sums: LogicalVec2<Au>,
|
||||
) -> LogicalVec2<Au> {
|
||||
let box_size = box_size.map(|size| size.non_auto());
|
||||
let max_box_size = max_box_size.map(|max_size| max_size.unwrap_or(MAX_AU));
|
||||
// <https://drafts.csswg.org/css-sizing-4/#preferred-aspect-ratio>
|
||||
let ratio = self.preferred_aspect_ratio(&containing_block.into(), style);
|
||||
|
||||
// <https://drafts.csswg.org/css-images-3/#natural-dimensions>
|
||||
// <https://drafts.csswg.org/css-images-3/#default-object-size>
|
||||
let writing_mode = style.writing_mode;
|
||||
let natural_size = LazyCell::new(|| self.flow_relative_natural_size(writing_mode));
|
||||
let default_object_size =
|
||||
LazyCell::new(|| Self::flow_relative_default_object_size(writing_mode));
|
||||
let ratio = self.preferred_aspect_ratio(&containing_block.into(), style);
|
||||
let get_inline_fallback_size = || {
|
||||
natural_size
|
||||
.inline
|
||||
.unwrap_or_else(|| default_object_size.inline)
|
||||
};
|
||||
let get_block_fallback_size = || {
|
||||
natural_size
|
||||
.block
|
||||
.unwrap_or_else(|| default_object_size.block)
|
||||
};
|
||||
|
||||
// This is a simplification of the CSS2 algorithm in a way that properly handles `aspect-ratio`.
|
||||
// Each axis can have preferred, min and max sizing constraints, plus constraints transferred
|
||||
// from the other axis if there is an aspect ratio, plus a natural and default size.
|
||||
// In case of conflict, the order of precedence (from highest to lowest) is:
|
||||
// 1. Non-transferred min constraint
|
||||
// 2. Non-transferred max constraint
|
||||
// 3. Non-transferred preferred constraint
|
||||
// 4. Transferred min constraint
|
||||
// 5. Transferred max constraint
|
||||
// 6. Transferred preferred constraint
|
||||
// 7. Natural size
|
||||
// 8. Default object size
|
||||
// <https://drafts.csswg.org/css-sizing-4/#aspect-ratio-size-transfers>
|
||||
// <https://github.com/w3c/csswg-drafts/issues/6071#issuecomment-2243986313>
|
||||
box_size.map_inline_and_block_axes(
|
||||
|inline_size| {
|
||||
let mut min = min_box_size.inline;
|
||||
let mut max = max_box_size.inline;
|
||||
if let Some(ratio) = ratio.filter(|_| inline_size.is_none()) {
|
||||
min = ratio
|
||||
.compute_dependent_size(Direction::Inline, min_box_size.block)
|
||||
.clamp_between_extremums(min, Some(max));
|
||||
max.min_assign(
|
||||
ratio.compute_dependent_size(Direction::Inline, max_box_size.block),
|
||||
);
|
||||
}
|
||||
inline_size
|
||||
.or_else(|| {
|
||||
Some(ratio?.compute_dependent_size(Direction::Inline, box_size.block?))
|
||||
})
|
||||
.or_else(|| natural_size.inline)
|
||||
.unwrap_or_else(|| default_object_size.inline)
|
||||
.clamp_between_extremums(min, Some(max))
|
||||
},
|
||||
|block_size| {
|
||||
let mut min = min_box_size.block;
|
||||
let mut max = max_box_size.block;
|
||||
if let Some(ratio) = ratio.filter(|_| block_size.is_none()) {
|
||||
min = ratio
|
||||
.compute_dependent_size(Direction::Block, min_box_size.inline)
|
||||
.clamp_between_extremums(min, Some(max));
|
||||
max.min_assign(
|
||||
ratio.compute_dependent_size(Direction::Block, max_box_size.inline),
|
||||
);
|
||||
}
|
||||
block_size
|
||||
.or_else(|| {
|
||||
Some(ratio?.compute_dependent_size(Direction::Block, box_size.inline?))
|
||||
})
|
||||
.or_else(|| natural_size.block)
|
||||
.unwrap_or_else(|| default_object_size.block)
|
||||
.clamp_between_extremums(min, Some(max))
|
||||
},
|
||||
)
|
||||
// <https://drafts.csswg.org/css-sizing-4/#stretch-fit-sizing>
|
||||
let inline_stretch_size = Au::zero().max(containing_block.inline_size - pbm_sums.inline);
|
||||
let block_stretch_size = containing_block
|
||||
.block_size
|
||||
.non_auto()
|
||||
.map(|block_size| Au::zero().max(block_size - pbm_sums.block));
|
||||
|
||||
// <https://drafts.csswg.org/css-sizing-3/#intrinsic-sizes>
|
||||
// FIXME: Use ReplacedContent::inline_content_sizes() once it's fixed to correctly handle
|
||||
// min and max constraints.
|
||||
let inline_content_size = LazyCell::new(|| {
|
||||
let Some(ratio) = ratio else {
|
||||
return get_inline_fallback_size();
|
||||
};
|
||||
let block_stretch_size = block_stretch_size.unwrap_or_else(get_block_fallback_size);
|
||||
let transfer = |size| ratio.compute_dependent_size(Direction::Inline, size);
|
||||
let min = transfer(
|
||||
min_box_size
|
||||
.block
|
||||
.maybe_resolve_extrinsic(Some(block_stretch_size))
|
||||
.unwrap_or_default(),
|
||||
);
|
||||
let max = max_box_size
|
||||
.block
|
||||
.maybe_resolve_extrinsic(Some(block_stretch_size))
|
||||
.map(transfer);
|
||||
box_size
|
||||
.block
|
||||
.maybe_resolve_extrinsic(Some(block_stretch_size))
|
||||
.map_or_else(get_inline_fallback_size, transfer)
|
||||
.clamp_between_extremums(min, max)
|
||||
});
|
||||
let block_content_size = LazyCell::new(|| {
|
||||
let Some(ratio) = ratio else {
|
||||
return get_block_fallback_size();
|
||||
};
|
||||
let mut get_inline_content_size = || (*inline_content_size).into();
|
||||
let transfer = |size| ratio.compute_dependent_size(Direction::Block, size);
|
||||
let min = transfer(
|
||||
min_box_size
|
||||
.inline
|
||||
.resolve_non_initial(inline_stretch_size, &mut get_inline_content_size)
|
||||
.unwrap_or_default(),
|
||||
);
|
||||
let max = max_box_size
|
||||
.inline
|
||||
.resolve_non_initial(inline_stretch_size, &mut get_inline_content_size)
|
||||
.map(transfer);
|
||||
box_size
|
||||
.inline
|
||||
.maybe_resolve_extrinsic(Some(inline_stretch_size))
|
||||
.map_or_else(get_block_fallback_size, transfer)
|
||||
.clamp_between_extremums(min, max)
|
||||
});
|
||||
let mut get_inline_content_size = || (*inline_content_size).into();
|
||||
let mut get_block_content_size = || (*block_content_size).into();
|
||||
let block_stretch_size = block_stretch_size.unwrap_or_else(|| *block_content_size);
|
||||
|
||||
// <https://drafts.csswg.org/css-sizing-3/#sizing-properties>
|
||||
let preferred_inline = box_size.inline.resolve(
|
||||
Size::FitContent,
|
||||
inline_stretch_size,
|
||||
&mut get_inline_content_size,
|
||||
);
|
||||
let preferred_block = box_size.block.resolve(
|
||||
Size::FitContent,
|
||||
block_stretch_size,
|
||||
&mut get_block_content_size,
|
||||
);
|
||||
let min_inline = min_box_size
|
||||
.inline
|
||||
.resolve_non_initial(inline_stretch_size, &mut get_inline_content_size)
|
||||
.unwrap_or_default();
|
||||
let min_block = min_box_size
|
||||
.block
|
||||
.resolve_non_initial(block_stretch_size, &mut get_block_content_size)
|
||||
.unwrap_or_default();
|
||||
let max_inline = max_box_size
|
||||
.inline
|
||||
.resolve_non_initial(inline_stretch_size, &mut get_inline_content_size);
|
||||
let max_block = max_box_size
|
||||
.block
|
||||
.resolve_non_initial(block_stretch_size, &mut get_block_content_size);
|
||||
LogicalVec2 {
|
||||
inline: preferred_inline.clamp_between_extremums(min_inline, max_inline),
|
||||
block: preferred_block.clamp_between_extremums(min_block, max_block),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
7
tests/wpt/meta/MANIFEST.json
vendored
7
tests/wpt/meta/MANIFEST.json
vendored
|
@ -570980,6 +570980,13 @@
|
|||
{}
|
||||
]
|
||||
],
|
||||
"keyword-sizes-on-replaced-element.html": [
|
||||
"e26c1b7d6ac38858fd7a941a690ea01e6005c38c",
|
||||
[
|
||||
null,
|
||||
{}
|
||||
]
|
||||
],
|
||||
"min-max-content-orthogonal-flow-crash-001.html": [
|
||||
"d2617f8aa2d1c966e394abb1d1617c012ea4648e",
|
||||
[
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
[image-min-max-content-intrinsic-size-change-001.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[image-min-max-content-intrinsic-size-change-002.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[image-min-max-content-intrinsic-size-change-003.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[image-min-max-content-intrinsic-size-change-004.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[image-min-max-content-intrinsic-size-change-005.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[image-min-max-content-intrinsic-size-change-006.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[image-min-max-content-intrinsic-size-change-007.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[image-min-max-content-intrinsic-size-change-008.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[replaced-max-height-min-content.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[replaced-max-width-min-content.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[replaced-min-height-min-content.html]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[replaced-min-width-min-content.html]
|
||||
expected: FAIL
|
184
tests/wpt/tests/css/css-sizing/keyword-sizes-on-replaced-element.html
vendored
Normal file
184
tests/wpt/tests/css/css-sizing/keyword-sizes-on-replaced-element.html
vendored
Normal file
|
@ -0,0 +1,184 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Keyword sizes on replaced element</title>
|
||||
<link rel="author" title="Oriol Brufau" href="obrufau@igalia.com">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-sizing-3/#sizing-values">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-sizing-4/#sizing-values">
|
||||
<link rel="help" href="https://drafts.csswg.org/css2/#replaced-element">
|
||||
<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/11006">
|
||||
<meta assert="The various keyword sizes work as expected on replaced elements.">
|
||||
|
||||
<style>
|
||||
.test {
|
||||
margin: 5px;
|
||||
border: 3px solid;
|
||||
padding: 2px;
|
||||
width: auto;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
/* Set the preferred size to small amount, to test that the min size works */
|
||||
.test.min-width { width: 0px }
|
||||
.test.min-height { height: 0px }
|
||||
|
||||
/* Set the preferred size to big amount, to test that the max size works */
|
||||
.test.max-width { width: 500px }
|
||||
.test.max-height { height: 500px }
|
||||
|
||||
/* stretch isn't widely supported, fall back to vendor-prefixed alternatives */
|
||||
.width.stretch { width: -moz-available; width: -webkit-fill-available; width: stretch }
|
||||
.min-width.stretch { min-width: -moz-available; min-width: -webkit-fill-available; min-width: stretch }
|
||||
.max-width.stretch { max-width: -moz-available; max-width: -webkit-fill-available; max-width: stretch }
|
||||
.height.stretch { height: -moz-available; height: -webkit-fill-available; height: stretch }
|
||||
.min-height.stretch { min-height: -moz-available; min-height: -webkit-fill-available; min-height: stretch }
|
||||
.max-height.stretch { max-height: -moz-available; max-height: -webkit-fill-available; max-height: stretch }
|
||||
</style>
|
||||
<div id="log"></div>
|
||||
|
||||
<!-- Intrinsic keywords -->
|
||||
<div style="width: 200px; height: 100px">
|
||||
<canvas width="100" height="100" class="test width height" style="width: 50px; height: 50px"
|
||||
data-expected-width="60" data-expected-height="60"></canvas>
|
||||
<canvas width="100" height="100" class="test width height" style="width: 50px; height: min-content"
|
||||
data-expected-width="60" data-expected-height="60"></canvas>
|
||||
<canvas width="100" height="100" class="test width height" style="width: 50px; height: fit-content"
|
||||
data-expected-width="60" data-expected-height="60"></canvas>
|
||||
<canvas width="100" height="100" class="test width height" style="width: 50px; height: max-content"
|
||||
data-expected-width="60" data-expected-height="60"></canvas>
|
||||
<canvas width="100" height="100" class="test width height" style="width: min-content; height: 50px"
|
||||
data-expected-width="60" data-expected-height="60"></canvas>
|
||||
<canvas width="100" height="100" class="test width height" style="width: min-content; height: min-content"
|
||||
data-expected-width="110" data-expected-height="110"></canvas>
|
||||
<canvas width="100" height="100" class="test width height" style="width: min-content; height: fit-content"
|
||||
data-expected-width="110" data-expected-height="110"></canvas>
|
||||
<canvas width="100" height="100" class="test width height" style="width: min-content; height: max-content"
|
||||
data-expected-width="110" data-expected-height="110"></canvas>
|
||||
<canvas width="100" height="100" class="test width height" style="width: fit-content; height: 50px"
|
||||
data-expected-width="60" data-expected-height="60"></canvas>
|
||||
<canvas width="100" height="100" class="test width height" style="width: fit-content; height: min-content"
|
||||
data-expected-width="110" data-expected-height="110"></canvas>
|
||||
<canvas width="100" height="100" class="test width height" style="width: fit-content; height: fit-content"
|
||||
data-expected-width="110" data-expected-height="110"></canvas>
|
||||
<canvas width="100" height="100" class="test width height" style="width: fit-content; height: max-content"
|
||||
data-expected-width="110" data-expected-height="110"></canvas>
|
||||
<canvas width="100" height="100" class="test width height" style="width: max-content; height: 50px"
|
||||
data-expected-width="60" data-expected-height="60"></canvas>
|
||||
<canvas width="100" height="100" class="test width height" style="width: max-content; height: min-content"
|
||||
data-expected-width="110" data-expected-height="110"></canvas>
|
||||
<canvas width="100" height="100" class="test width height" style="width: max-content; height: fit-content"
|
||||
data-expected-width="110" data-expected-height="110"></canvas>
|
||||
<canvas width="100" height="100" class="test width height" style="width: max-content; height: max-content"
|
||||
data-expected-width="110" data-expected-height="110"></canvas>
|
||||
|
||||
<br>
|
||||
|
||||
<canvas width="100" height="100" class="test min-width height" style="min-width: 50px; height: 50px"
|
||||
data-expected-width="60" data-expected-height="60"></canvas>
|
||||
<canvas width="100" height="100" class="test min-width height" style="min-width: 50px; height: min-content"
|
||||
data-expected-width="60" data-expected-height="60"></canvas>
|
||||
<canvas width="100" height="100" class="test min-width height" style="min-width: 50px; height: fit-content"
|
||||
data-expected-width="60" data-expected-height="60"></canvas>
|
||||
<canvas width="100" height="100" class="test min-width height" style="min-width: 50px; height: max-content"
|
||||
data-expected-width="60" data-expected-height="60"></canvas>
|
||||
<canvas width="100" height="100" class="test min-width height" style="min-width: min-content; height: 50px"
|
||||
data-expected-width="60" data-expected-height="60"></canvas>
|
||||
<canvas width="100" height="100" class="test min-width height" style="min-width: min-content; height: min-content"
|
||||
data-expected-width="110" data-expected-height="110"></canvas>
|
||||
<canvas width="100" height="100" class="test min-width height" style="min-width: min-content; height: fit-content"
|
||||
data-expected-width="110" data-expected-height="110"></canvas>
|
||||
<canvas width="100" height="100" class="test min-width height" style="min-width: min-content; height: max-content"
|
||||
data-expected-width="110" data-expected-height="110"></canvas>
|
||||
<canvas width="100" height="100" class="test min-width height" style="min-width: fit-content; height: 50px"
|
||||
data-expected-width="60" data-expected-height="60"></canvas>
|
||||
<canvas width="100" height="100" class="test min-width height" style="min-width: fit-content; height: min-content"
|
||||
data-expected-width="110" data-expected-height="110"></canvas>
|
||||
<canvas width="100" height="100" class="test min-width height" style="min-width: fit-content; height: fit-content"
|
||||
data-expected-width="110" data-expected-height="110"></canvas>
|
||||
<canvas width="100" height="100" class="test min-width height" style="min-width: fit-content; height: max-content"
|
||||
data-expected-width="110" data-expected-height="110"></canvas>
|
||||
<canvas width="100" height="100" class="test min-width height" style="min-width: max-content; height: 50px"
|
||||
data-expected-width="60" data-expected-height="60"></canvas>
|
||||
<canvas width="100" height="100" class="test min-width height" style="min-width: max-content; height: min-content"
|
||||
data-expected-width="110" data-expected-height="110"></canvas>
|
||||
<canvas width="100" height="100" class="test min-width height" style="min-width: max-content; height: fit-content"
|
||||
data-expected-width="110" data-expected-height="110"></canvas>
|
||||
<canvas width="100" height="100" class="test min-width height" style="min-width: max-content; height: max-content"
|
||||
data-expected-width="110" data-expected-height="110"></canvas>
|
||||
|
||||
<br>
|
||||
|
||||
<canvas width="100" height="100" class="test max-width height" style="max-width: 50px; height: 50px"
|
||||
data-expected-width="60" data-expected-height="60"></canvas>
|
||||
<canvas width="100" height="100" class="test max-width height" style="max-width: 50px; height: min-content"
|
||||
data-expected-width="60" data-expected-height="60"></canvas>
|
||||
<canvas width="100" height="100" class="test max-width height" style="max-width: 50px; height: fit-content"
|
||||
data-expected-width="60" data-expected-height="60"></canvas>
|
||||
<canvas width="100" height="100" class="test max-width height" style="max-width: 50px; height: max-content"
|
||||
data-expected-width="60" data-expected-height="60"></canvas>
|
||||
<canvas width="100" height="100" class="test max-width height" style="max-width: min-content; height: 50px"
|
||||
data-expected-width="60" data-expected-height="60"></canvas>
|
||||
<canvas width="100" height="100" class="test max-width height" style="max-width: min-content; height: min-content"
|
||||
data-expected-width="110" data-expected-height="110"></canvas>
|
||||
<canvas width="100" height="100" class="test max-width height" style="max-width: min-content; height: fit-content"
|
||||
data-expected-width="110" data-expected-height="110"></canvas>
|
||||
<canvas width="100" height="100" class="test max-width height" style="max-width: min-content; height: max-content"
|
||||
data-expected-width="110" data-expected-height="110"></canvas>
|
||||
<canvas width="100" height="100" class="test max-width height" style="max-width: fit-content; height: 50px"
|
||||
data-expected-width="60" data-expected-height="60"></canvas>
|
||||
<canvas width="100" height="100" class="test max-width height" style="max-width: fit-content; height: min-content"
|
||||
data-expected-width="110" data-expected-height="110"></canvas>
|
||||
<canvas width="100" height="100" class="test max-width height" style="max-width: fit-content; height: fit-content"
|
||||
data-expected-width="110" data-expected-height="110"></canvas>
|
||||
<canvas width="100" height="100" class="test max-width height" style="max-width: fit-content; height: max-content"
|
||||
data-expected-width="110" data-expected-height="110"></canvas>
|
||||
<canvas width="100" height="100" class="test max-width height" style="max-width: max-content; height: 50px"
|
||||
data-expected-width="60" data-expected-height="60"></canvas>
|
||||
<canvas width="100" height="100" class="test max-width height" style="max-width: max-content; height: min-content"
|
||||
data-expected-width="110" data-expected-height="110"></canvas>
|
||||
<canvas width="100" height="100" class="test max-width height" style="max-width: max-content; height: fit-content"
|
||||
data-expected-width="110" data-expected-height="110"></canvas>
|
||||
<canvas width="100" height="100" class="test max-width height" style="max-width: max-content; height: max-content"
|
||||
data-expected-width="110" data-expected-height="110"></canvas>
|
||||
</div>
|
||||
|
||||
<!-- Definite stretch -->
|
||||
<div style="width: 200px; height: 100px">
|
||||
<canvas width="100" height="100" class="test width stretch"
|
||||
data-expected-width="190" data-expected-height="190">X X</canvas>
|
||||
<canvas width="100" height="100" class="test min-width stretch"
|
||||
data-expected-width="190" data-expected-height="190">X X</canvas>
|
||||
<canvas width="100" height="100" class="test max-width stretch"
|
||||
data-expected-width="190" data-expected-height="190">X X</canvas>
|
||||
<canvas width="100" height="100" class="test height stretch"
|
||||
data-expected-width="90" data-expected-height="90">X X</canvas>
|
||||
<canvas width="100" height="100" class="test min-height stretch"
|
||||
data-expected-width="90" data-expected-height="90">X X</canvas>
|
||||
<canvas width="100" height="100" class="test max-height stretch"
|
||||
data-expected-width="90" data-expected-height="90">X X</canvas>
|
||||
</div>
|
||||
|
||||
<!-- Stretch sizes can't result in a negative content size -->
|
||||
<div class="wrapper" style="width: 0px; height: 0px">
|
||||
<canvas width="100" height="100" class="test width min-width max-width stretch"
|
||||
data-expected-width="10" data-expected-height="10"></canvas>
|
||||
<canvas width="100" height="100" class="test height min-height max-height stretch"
|
||||
data-expected-width="10" data-expected-height="10"></canvas>
|
||||
<canvas width="100" height="100" class="test width min-width max-width height min-height max-height stretch"
|
||||
data-expected-width="10" data-expected-height="10"></canvas>
|
||||
</div>
|
||||
|
||||
<!-- Indefinite stretch -->
|
||||
<div style="width: 200px; max-height: 100px">
|
||||
<canvas width="100" height="100" class="test height stretch indefinite"
|
||||
data-expected-width="110" data-expected-height="110"></canvas>
|
||||
<canvas width="100" height="100" class="test min-height stretch indefinite"
|
||||
data-expected-width="110" data-expected-height="110"></canvas>
|
||||
<canvas width="100" height="100" class="test max-height stretch indefinite"
|
||||
data-expected-width="110" data-expected-height="110"></canvas>
|
||||
</div>
|
||||
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/check-layout-th.js"></script>
|
||||
<script>
|
||||
checkLayout(".test");
|
||||
</script>
|
Loading…
Add table
Add a link
Reference in a new issue