mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-22 04:25:13 +00:00
LibWeb: Implement CSS 'contain' property
This commit is contained in:
parent
c53c781745
commit
67ed676831
Notes:
github-actions[bot]
2025-01-28 11:25:39 +00:00
Author: https://github.com/Psychpsyo Commit: https://github.com/LadybirdBrowser/ladybird/commit/67ed6768313 Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/3296 Reviewed-by: https://github.com/AtkinsSJ ✅
154 changed files with 4200 additions and 117 deletions
|
@ -1360,6 +1360,74 @@ Optional<CSS::Isolation> ComputedProperties::isolation() const
|
|||
return keyword_to_isolation(value.to_keyword());
|
||||
}
|
||||
|
||||
CSS::Containment ComputedProperties::contain() const
|
||||
{
|
||||
CSS::Containment containment = {};
|
||||
auto const& value = property(CSS::PropertyID::Contain);
|
||||
|
||||
switch (value.to_keyword()) {
|
||||
case Keyword::None:
|
||||
// This value indicates that the property has no effect. The element renders as normal, with no containment effects applied.
|
||||
return {};
|
||||
case Keyword::Strict:
|
||||
// This value computes to 'size layout paint style', and thus turns on all forms of containment for the element.
|
||||
containment.size_containment = true;
|
||||
containment.layout_containment = true;
|
||||
containment.paint_containment = true;
|
||||
containment.style_containment = true;
|
||||
break;
|
||||
case Keyword::Content:
|
||||
// This value computes to 'layout paint style', and thus turns on all forms of containment except size containment for the element.
|
||||
containment.layout_containment = true;
|
||||
containment.paint_containment = true;
|
||||
containment.style_containment = true;
|
||||
break;
|
||||
case Keyword::Size:
|
||||
containment.size_containment = true;
|
||||
break;
|
||||
case Keyword::InlineSize:
|
||||
containment.inline_size_containment = true;
|
||||
break;
|
||||
case Keyword::Layout:
|
||||
containment.layout_containment = true;
|
||||
break;
|
||||
case Keyword::Style:
|
||||
containment.style_containment = true;
|
||||
break;
|
||||
case Keyword::Paint:
|
||||
containment.paint_containment = true;
|
||||
break;
|
||||
default:
|
||||
if (value.is_value_list()) {
|
||||
auto& values = value.as_value_list().values();
|
||||
for (auto const& item : values) {
|
||||
switch (item->to_keyword()) {
|
||||
case Keyword::Size:
|
||||
containment.size_containment = true;
|
||||
break;
|
||||
case Keyword::InlineSize:
|
||||
containment.inline_size_containment = true;
|
||||
break;
|
||||
case Keyword::Layout:
|
||||
containment.layout_containment = true;
|
||||
break;
|
||||
case Keyword::Style:
|
||||
containment.style_containment = true;
|
||||
break;
|
||||
case Keyword::Paint:
|
||||
containment.paint_containment = true;
|
||||
break;
|
||||
default:
|
||||
dbgln("`{}` is not supported in `contain` (yet?)", item->to_string(CSSStyleValue::SerializationMode::Normal));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return containment;
|
||||
}
|
||||
|
||||
Optional<CSS::MaskType> ComputedProperties::mask_type() const
|
||||
{
|
||||
auto const& value = property(CSS::PropertyID::MaskType);
|
||||
|
|
|
@ -161,6 +161,7 @@ public:
|
|||
Optional<CSS::WritingMode> writing_mode() const;
|
||||
Optional<CSS::UserSelect> user_select() const;
|
||||
Optional<CSS::Isolation> isolation() const;
|
||||
CSS::Containment contain() const;
|
||||
|
||||
static Vector<CSS::Transformation> transformations_for_style_value(CSSStyleValue const& value);
|
||||
Vector<CSS::Transformation> transformations() const;
|
||||
|
|
|
@ -66,6 +66,18 @@ struct ObjectPosition {
|
|||
CSS::LengthPercentage offset_y { Percentage(50) };
|
||||
};
|
||||
|
||||
// https://drafts.csswg.org/css-contain-2/#containment-types
|
||||
struct Containment {
|
||||
// FIXME: It'd be nice if this was a single-byte bitfield instead of some bools.
|
||||
bool size_containment = false;
|
||||
bool inline_size_containment = false;
|
||||
bool layout_containment = false;
|
||||
bool style_containment = false;
|
||||
bool paint_containment = false;
|
||||
|
||||
bool is_empty() const { return !(size_containment || inline_size_containment || layout_containment || style_containment || paint_containment); }
|
||||
};
|
||||
|
||||
class InitialValues {
|
||||
public:
|
||||
static AspectRatio aspect_ratio() { return AspectRatio { true, {} }; }
|
||||
|
@ -172,6 +184,7 @@ public:
|
|||
static CSS::WritingMode writing_mode() { return CSS::WritingMode::HorizontalTb; }
|
||||
static CSS::UserSelect user_select() { return CSS::UserSelect::Auto; }
|
||||
static CSS::Isolation isolation() { return CSS::Isolation::Auto; }
|
||||
static CSS::Containment contain() { return {}; }
|
||||
|
||||
// https://www.w3.org/TR/SVG/geometry.html
|
||||
static LengthPercentage cx() { return CSS::Length::make_px(0); }
|
||||
|
@ -428,6 +441,7 @@ public:
|
|||
CSS::WritingMode writing_mode() const { return m_inherited.writing_mode; }
|
||||
CSS::UserSelect user_select() const { return m_noninherited.user_select; }
|
||||
CSS::Isolation isolation() const { return m_noninherited.isolation; }
|
||||
CSS::Containment const& contain() const { return m_noninherited.contain; }
|
||||
|
||||
CSS::LengthBox const& inset() const { return m_noninherited.inset; }
|
||||
const CSS::LengthBox& margin() const { return m_noninherited.margin; }
|
||||
|
@ -681,6 +695,7 @@ protected:
|
|||
CSS::UnicodeBidi unicode_bidi { InitialValues::unicode_bidi() };
|
||||
CSS::UserSelect user_select { InitialValues::user_select() };
|
||||
CSS::Isolation isolation { InitialValues::isolation() };
|
||||
CSS::Containment contain { InitialValues::contain() };
|
||||
|
||||
Optional<CSS::Transformation> rotate;
|
||||
Optional<CSS::Transformation> translate;
|
||||
|
@ -855,6 +870,7 @@ public:
|
|||
void set_writing_mode(CSS::WritingMode value) { m_inherited.writing_mode = value; }
|
||||
void set_user_select(CSS::UserSelect value) { m_noninherited.user_select = value; }
|
||||
void set_isolation(CSS::Isolation value) { m_noninherited.isolation = value; }
|
||||
void set_contain(CSS::Containment value) { m_noninherited.contain = move(value); }
|
||||
|
||||
void set_fill(SVGPaint value) { m_inherited.fill = move(value); }
|
||||
void set_stroke(SVGPaint value) { m_inherited.stroke = move(value); }
|
||||
|
|
|
@ -62,6 +62,11 @@ public:
|
|||
bool is_table_cell() const { return is_internal() && internal() == DisplayInternal::TableCell; }
|
||||
bool is_table_column_group() const { return is_internal() && internal() == DisplayInternal::TableColumnGroup; }
|
||||
bool is_table_caption() const { return is_internal() && internal() == DisplayInternal::TableCaption; }
|
||||
// https://drafts.csswg.org/css-display-3/#internal-table-element
|
||||
bool is_internal_table() const
|
||||
{
|
||||
return is_internal() && (internal() == DisplayInternal::TableRowGroup || internal() == DisplayInternal::TableHeaderGroup || internal() == DisplayInternal::TableFooterGroup || internal() == DisplayInternal::TableRow || internal() == DisplayInternal::TableCell || internal() == DisplayInternal::TableColumnGroup || internal() == DisplayInternal::TableColumn);
|
||||
}
|
||||
|
||||
bool is_none() const { return m_type == Type::Box && m_value.box == DisplayBox::None; }
|
||||
bool is_contents() const { return m_type == Type::Box && m_value.box == DisplayBox::Contents; }
|
||||
|
|
|
@ -107,6 +107,16 @@
|
|||
"none",
|
||||
"all"
|
||||
],
|
||||
"contain": [
|
||||
"none",
|
||||
"strict",
|
||||
"content",
|
||||
"size",
|
||||
"inline-size",
|
||||
"layout",
|
||||
"style",
|
||||
"paint"
|
||||
],
|
||||
"content-visibility": [
|
||||
"visible",
|
||||
"auto",
|
||||
|
|
|
@ -210,6 +210,7 @@
|
|||
"inline-end",
|
||||
"inline-flex",
|
||||
"inline-grid",
|
||||
"inline-size",
|
||||
"inline-start",
|
||||
"inline-table",
|
||||
"inset",
|
||||
|
@ -235,6 +236,7 @@
|
|||
"landscape",
|
||||
"large",
|
||||
"larger",
|
||||
"layout",
|
||||
"left",
|
||||
"legacy",
|
||||
"less",
|
||||
|
@ -308,6 +310,7 @@
|
|||
"p3",
|
||||
"padding-box",
|
||||
"paged",
|
||||
"paint",
|
||||
"paused",
|
||||
"petite-caps",
|
||||
"pixelated",
|
||||
|
@ -366,6 +369,7 @@
|
|||
"sideways-lr",
|
||||
"sideways-rl",
|
||||
"simplified",
|
||||
"size",
|
||||
"slashed-zero",
|
||||
"slider-horizontal",
|
||||
"slow",
|
||||
|
@ -389,7 +393,9 @@
|
|||
"static",
|
||||
"sticky",
|
||||
"stretch",
|
||||
"strict",
|
||||
"stroke-box",
|
||||
"style",
|
||||
"sub",
|
||||
"subtractive",
|
||||
"super",
|
||||
|
|
|
@ -923,6 +923,16 @@
|
|||
"column-count"
|
||||
]
|
||||
},
|
||||
"contain": {
|
||||
"__comment": "FIXME: Some values of contain need to be mutually exclusive. The grammar this should adhere to is 'none | strict | content | [ [size | inline-size] || layout || style || paint ]'.",
|
||||
"affects-stacking-context": true,
|
||||
"animation-type": "none",
|
||||
"inherited": false,
|
||||
"initial": "none",
|
||||
"valid-types": [
|
||||
"contain"
|
||||
]
|
||||
},
|
||||
"content": {
|
||||
"animation-type": "discrete",
|
||||
"inherited": false,
|
||||
|
|
|
@ -1190,9 +1190,21 @@ static void propagate_scrollbar_width_to_viewport(Element& root_element, Layout:
|
|||
viewport_computed_values.set_scrollbar_width(root_element_computed_values.scrollbar_width());
|
||||
}
|
||||
|
||||
// https://drafts.csswg.org/css-overflow-3/#overflow-propagation
|
||||
static void propagate_overflow_to_viewport(Element& root_element, Layout::Viewport& viewport)
|
||||
{
|
||||
// https://drafts.csswg.org/css-overflow-3/#overflow-propagation
|
||||
// https://drafts.csswg.org/css-contain-2/#contain-property
|
||||
// Additionally, when any containments are active on either the HTML <html> or <body> elements, propagation of
|
||||
// properties from the <body> element to the initial containing block, the viewport, or the canvas background, is
|
||||
// disabled. Notably, this affects:
|
||||
// - 'overflow' and its longhands (see CSS Overflow 3 § 3.3 Overflow Viewport Propagation)
|
||||
if (root_element.is_html_html_element() && !root_element.computed_properties()->contain().is_empty())
|
||||
return;
|
||||
|
||||
auto* body_element = root_element.first_child_of_type<HTML::HTMLBodyElement>();
|
||||
if (body_element && !body_element->computed_properties()->contain().is_empty())
|
||||
return;
|
||||
|
||||
// UAs must apply the overflow-* values set on the root element to the viewport
|
||||
// when the root element’s display value is not none.
|
||||
auto overflow_origin_node = root_element.layout_node();
|
||||
|
|
|
@ -2741,6 +2741,148 @@ bool Element::is_relevant_to_the_user()
|
|||
return false;
|
||||
}
|
||||
|
||||
// https://drafts.csswg.org/css-contain-2/#skips-its-contents
|
||||
bool Element::skips_its_contents()
|
||||
{
|
||||
// https://drafts.csswg.org/css-contain-2/#valdef-content-visibility-hidden
|
||||
// The element skips its contents.
|
||||
if (computed_properties()->content_visibility() == CSS::ContentVisibility::Hidden)
|
||||
return true;
|
||||
|
||||
// https://drafts.csswg.org/css-contain-2/#valdef-content-visibility-auto
|
||||
// If the element is not relevant to the user, it also skips its contents.
|
||||
if (computed_properties()->content_visibility() == CSS::ContentVisibility::Auto && !this->is_relevant_to_the_user()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// https://drafts.csswg.org/css-contain-2/#containment-size
|
||||
bool Element::has_size_containment() const
|
||||
{
|
||||
// However, giving an element size containment has no effect if any of the following are true:
|
||||
|
||||
// - if the element does not generate a principal box (as is the case with 'display: contents' or 'display: none')
|
||||
if (!layout_node())
|
||||
return false;
|
||||
|
||||
// - if its inner display type is 'table'
|
||||
if (layout_node()->display().is_table_inside())
|
||||
return false;
|
||||
|
||||
// - if its principal box is an internal table box
|
||||
if (layout_node()->display().is_internal_table())
|
||||
return false;
|
||||
|
||||
// - if its principal box is an internal ruby box or a non-atomic inline-level box
|
||||
// FIXME: Implement this.
|
||||
|
||||
if (computed_properties()->contain().size_containment)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
// https://drafts.csswg.org/css-contain-2/#containment-inline-size
|
||||
bool Element::has_inline_size_containment() const
|
||||
{
|
||||
// Giving an element inline-size containment has no effect if any of the following are true:
|
||||
|
||||
// - if the element does not generate a principal box (as is the case with 'display: contents' or 'display: none')
|
||||
if (!layout_node())
|
||||
return false;
|
||||
|
||||
// - if its inner display type is 'table'
|
||||
if (layout_node()->display().is_table_inside())
|
||||
return false;
|
||||
|
||||
// - if its principal box is an internal table box
|
||||
if (layout_node()->display().is_internal_table())
|
||||
return false;
|
||||
|
||||
// - if its principal box is an internal ruby box or a non-atomic inline-level box
|
||||
// FIXME: Implement this.
|
||||
|
||||
if (computed_properties()->contain().inline_size_containment)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
// https://drafts.csswg.org/css-contain-2/#containment-layout
|
||||
bool Element::has_layout_containment() const
|
||||
{
|
||||
// However, giving an element layout containment has no effect if any of the following are true:
|
||||
|
||||
// - if the element does not generate a principal box (as is the case with 'display: contents' or 'display: none')
|
||||
if (!layout_node())
|
||||
return false;
|
||||
|
||||
// - if its principal box is an internal table box other than 'table-cell'
|
||||
if (layout_node()->display().is_internal_table() && !layout_node()->display().is_table_cell())
|
||||
return false;
|
||||
|
||||
// - if its principal box is an internal ruby box or a non-atomic inline-level box
|
||||
// FIXME: Implement this.
|
||||
|
||||
if (computed_properties()->contain().layout_containment)
|
||||
return true;
|
||||
|
||||
// https://drafts.csswg.org/css-contain-2/#valdef-content-visibility-auto
|
||||
// Changes the used value of the 'contain' property so as to turn on layout containment, style containment, and
|
||||
// paint containment for the element.
|
||||
if (computed_properties()->content_visibility() == CSS::ContentVisibility::Auto)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
// https://drafts.csswg.org/css-contain-2/#containment-style
|
||||
bool Element::has_style_containment() const
|
||||
{
|
||||
// However, giving an element style containment has no effect if any of the following are true:
|
||||
|
||||
// - if the element does not generate a principal box (as is the case with 'display: contents' or 'display: none')
|
||||
if (!layout_node())
|
||||
return false;
|
||||
|
||||
if (computed_properties()->contain().style_containment)
|
||||
return true;
|
||||
|
||||
// https://drafts.csswg.org/css-contain-2/#valdef-content-visibility-auto
|
||||
// Changes the used value of the 'contain' property so as to turn on layout containment, style containment, and
|
||||
// paint containment for the element.
|
||||
if (computed_properties()->content_visibility() == CSS::ContentVisibility::Auto)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
// https://drafts.csswg.org/css-contain-2/#containment-paint
|
||||
bool Element::has_paint_containment() const
|
||||
{
|
||||
// However, giving an element paint containment has no effect if any of the following are true:
|
||||
|
||||
// - if the element does not generate a principal box (as is the case with 'display: contents' or 'display: none')
|
||||
if (!layout_node())
|
||||
return false;
|
||||
|
||||
// - if its principal box is an internal table box other than 'table-cell'
|
||||
if (layout_node()->display().is_internal_table() && !layout_node()->display().is_table_cell())
|
||||
return false;
|
||||
|
||||
// - if its principal box is an internal ruby box or a non-atomic inline-level box
|
||||
// FIXME: Implement this
|
||||
|
||||
if (computed_properties()->contain().paint_containment)
|
||||
return true;
|
||||
|
||||
// https://drafts.csswg.org/css-contain-2/#valdef-content-visibility-auto
|
||||
// Changes the used value of the 'contain' property so as to turn on layout containment, style containment, and
|
||||
// paint containment for the element.
|
||||
if (computed_properties()->content_visibility() == CSS::ContentVisibility::Auto)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Element::id_reference_exists(String const& id_reference) const
|
||||
{
|
||||
return document().get_element_by_id(id_reference);
|
||||
|
@ -3154,6 +3296,12 @@ void Element::resolve_counters(CSS::ComputedProperties& style)
|
|||
for (auto const& counter : counter_reset)
|
||||
ensure_counters_set().instantiate_a_counter(counter.name, unique_id(), counter.is_reversed, counter.value);
|
||||
|
||||
// FIXME: Take style containment into account
|
||||
// https://drafts.csswg.org/css-contain-2/#containment-style
|
||||
// Giving an element style containment has the following effects:
|
||||
// 1. The 'counter-increment' and 'counter-set' properties must be scoped to the element’s sub-tree and create a
|
||||
// new counter.
|
||||
|
||||
// 3. Counter values are incremented (counter-increment).
|
||||
auto counter_increment = style.counter_data(CSS::PropertyID::CounterIncrement);
|
||||
for (auto const& counter : counter_increment)
|
||||
|
|
|
@ -398,6 +398,16 @@ public:
|
|||
void determine_proximity_to_the_viewport();
|
||||
bool is_relevant_to_the_user();
|
||||
|
||||
// https://drafts.csswg.org/css-contain-2/#skips-its-contents
|
||||
bool skips_its_contents();
|
||||
|
||||
// https://drafts.csswg.org/css-contain-2/#containment-types
|
||||
bool has_size_containment() const;
|
||||
bool has_inline_size_containment() const;
|
||||
bool has_layout_containment() const;
|
||||
bool has_style_containment() const;
|
||||
bool has_paint_containment() const;
|
||||
|
||||
protected:
|
||||
Element(Document&, DOM::QualifiedName);
|
||||
virtual void initialize(JS::Realm&) override;
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include <LibWeb/Bindings/HTMLHtmlElementPrototype.h>
|
||||
#include <LibWeb/Bindings/Intrinsics.h>
|
||||
#include <LibWeb/HTML/HTMLBodyElement.h>
|
||||
#include <LibWeb/HTML/HTMLHtmlElement.h>
|
||||
#include <LibWeb/Layout/Node.h>
|
||||
|
||||
|
@ -28,6 +29,18 @@ void HTMLHtmlElement::initialize(JS::Realm& realm)
|
|||
|
||||
bool HTMLHtmlElement::should_use_body_background_properties() const
|
||||
{
|
||||
// https://drafts.csswg.org/css-contain-2/#contain-property
|
||||
// Additionally, when any containments are active on either the HTML <html> or <body> elements, propagation of
|
||||
// properties from the <body> element to the initial containing block, the viewport, or the canvas background, is
|
||||
// disabled. Notably, this affects:
|
||||
// - 'background' and its longhands (see CSS Backgrounds 3 § 2.11.2 The Canvas Background and the HTML <body> Element)
|
||||
if (!computed_properties()->contain().is_empty())
|
||||
return false;
|
||||
|
||||
auto* body_element = first_child_of_type<HTML::HTMLBodyElement>();
|
||||
if (body_element && !body_element->computed_properties()->contain().is_empty())
|
||||
return false;
|
||||
|
||||
auto background_color = layout_node()->computed_values().background_color();
|
||||
auto const& background_layers = layout_node()->background_layers();
|
||||
|
||||
|
|
|
@ -28,6 +28,37 @@ Box::~Box()
|
|||
{
|
||||
}
|
||||
|
||||
Optional<CSSPixels> Box::natural_width() const
|
||||
{
|
||||
// https://drafts.csswg.org/css-contain-2/#containment-size
|
||||
// Replaced elements must be treated as having a natural width and height of 0 and no natural aspect
|
||||
// ratio.
|
||||
if (dom_node() && dom_node()->is_element() && as<DOM::Element>(dom_node())->has_size_containment())
|
||||
return 0;
|
||||
|
||||
return m_natural_width;
|
||||
}
|
||||
Optional<CSSPixels> Box::natural_height() const
|
||||
{
|
||||
// https://drafts.csswg.org/css-contain-2/#containment-size
|
||||
// Replaced elements must be treated as having a natural width and height of 0 and no natural aspect
|
||||
// ratio.
|
||||
if (dom_node() && dom_node()->is_element() && as<DOM::Element>(dom_node())->has_size_containment())
|
||||
return 0;
|
||||
|
||||
return m_natural_height;
|
||||
}
|
||||
Optional<CSSPixelFraction> Box::natural_aspect_ratio() const
|
||||
{
|
||||
// https://drafts.csswg.org/css-contain-2/#containment-size
|
||||
// Replaced elements must be treated as having a natural width and height of 0 and no natural aspect
|
||||
// ratio.
|
||||
if (dom_node() && dom_node()->is_element() && as<DOM::Element>(dom_node())->has_size_containment())
|
||||
return {};
|
||||
|
||||
return m_natural_aspect_ratio;
|
||||
}
|
||||
|
||||
void Box::visit_edges(Cell::Visitor& visitor)
|
||||
{
|
||||
Base::visit_edges(visitor);
|
||||
|
|
|
@ -25,9 +25,9 @@ public:
|
|||
Painting::PaintableBox* paintable_box();
|
||||
|
||||
// https://www.w3.org/TR/css-images-3/#natural-dimensions
|
||||
Optional<CSSPixels> natural_width() const { return m_natural_width; }
|
||||
Optional<CSSPixels> natural_height() const { return m_natural_height; }
|
||||
Optional<CSSPixelFraction> natural_aspect_ratio() const { return m_natural_aspect_ratio; }
|
||||
Optional<CSSPixels> natural_width() const;
|
||||
Optional<CSSPixels> natural_height() const;
|
||||
Optional<CSSPixelFraction> natural_aspect_ratio() const;
|
||||
|
||||
bool has_natural_width() const { return natural_width().has_value(); }
|
||||
bool has_natural_height() const { return natural_height().has_value(); }
|
||||
|
|
|
@ -94,7 +94,14 @@ bool FormattingContext::creates_block_formatting_context(Box const& box)
|
|||
if (box.display().is_flow_root_inside())
|
||||
return true;
|
||||
|
||||
// FIXME: Elements with contain: layout, content, or paint.
|
||||
// https://drafts.csswg.org/css-contain-2/#containment-types
|
||||
// 1. The layout containment box establishes an independent formatting context.
|
||||
// 4. The paint containment box establishes an independent formatting context.
|
||||
if (box.dom_node() && box.dom_node()->is_element()) {
|
||||
auto element = as<DOM::Element>(box.dom_node());
|
||||
if (element->has_layout_containment() || element->has_paint_containment())
|
||||
return true;
|
||||
}
|
||||
|
||||
if (box.parent()) {
|
||||
auto parent_display = box.parent()->display();
|
||||
|
|
|
@ -89,6 +89,17 @@ bool Node::can_contain_boxes_with_position_absolute() const
|
|||
if (computed_values().scale().has_value())
|
||||
return true;
|
||||
|
||||
// https://drafts.csswg.org/css-contain-2/#containment-types
|
||||
// 4. The layout containment box establishes an absolute positioning containing block and a fixed positioning
|
||||
// containing block.
|
||||
// 4. The paint containment box establishes an absolute positioning containing block and a fixed positioning
|
||||
// containing block.
|
||||
if (dom_node() && dom_node()->is_element()) {
|
||||
auto element = as<DOM::Element>(dom_node());
|
||||
if (element->has_layout_containment() || element->has_paint_containment())
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -220,6 +231,15 @@ bool Node::establishes_stacking_context() const
|
|||
if (computed_values().isolation() == CSS::Isolation::Isolate)
|
||||
return true;
|
||||
|
||||
// https://drafts.csswg.org/css-contain-2/#containment-types
|
||||
// 5. The layout containment box creates a stacking context.
|
||||
// 3. The paint containment box creates a stacking context.
|
||||
if (dom_node() && dom_node()->is_element()) {
|
||||
auto element = as<DOM::Element>(dom_node());
|
||||
if (element->has_layout_containment() || element->has_paint_containment())
|
||||
return true;
|
||||
}
|
||||
|
||||
return computed_values().opacity() < 1.0f;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
<!DOCTYPE html>
|
||||
<link rel="help" href="https://crbug.com/1129563">
|
||||
<body style="contain: size layout;">
|
||||
<div id="target" style="contain: size layout;"></div>
|
||||
<div id="child"></div>
|
||||
</body>
|
||||
<script>
|
||||
document.body.offsetTop;
|
||||
const target = document.getElementById('target');
|
||||
const child = document.getElementById('child');
|
||||
target.appendChild(child);
|
||||
</script>
|
|
@ -0,0 +1,26 @@
|
|||
<style>
|
||||
* {
|
||||
counter-reset: reversed(counter_3) reversed(counter_4) 64 reversed(counter_5) -8772;
|
||||
contain: layout paint style inline-size !important;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
window.addEventListener("load", () => {
|
||||
let a = document.documentElement
|
||||
let b = document.getElementById("o1")
|
||||
let c = document.getElementById("o3")
|
||||
let d = new Range()
|
||||
document.documentElement.style.display = "none"
|
||||
document.documentElement.getBoundingClientRect()
|
||||
document.documentElement.style.display = ""
|
||||
d.setStartAfter(document.getElementById("o2"))
|
||||
try { document.prepend("", document.documentElement) } catch (e) {}
|
||||
d.surroundContents(b)
|
||||
try { b.prepend(a, c) } catch (e) {}
|
||||
b.scrollIntoView({ })
|
||||
a.style.display = "none"
|
||||
})
|
||||
</script>
|
||||
<br id="o1">
|
||||
<li id="o2">
|
||||
<input id="o3">
|
|
@ -0,0 +1,25 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1928724">
|
||||
|
||||
<style>
|
||||
*:only-child {
|
||||
contain: size layout paint;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
a.getBoundingClientRect();
|
||||
a.appendChild(c);
|
||||
b.scrollBy();
|
||||
})
|
||||
</script>
|
||||
|
||||
<body>
|
||||
<svg>
|
||||
<animateMotion id="b">
|
||||
</animateMotion>
|
||||
<foreignObject id="a">
|
||||
<article>
|
||||
<data id="c">
|
|
@ -0,0 +1,24 @@
|
|||
<!DOCTYPE html>
|
||||
<link rel="help" href="https://drafts.csswg.org/css-contain/#contain-property">
|
||||
<link rel="help" href="https://crbug.com/1214198">
|
||||
<link rel="author" title="Koji Ishii" href="mailto:kojii@chromium.org">
|
||||
<style>
|
||||
.contain {
|
||||
contain: strict;
|
||||
display: block;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
</style>
|
||||
<body>
|
||||
<div id="outer" class="contain">
|
||||
<div>
|
||||
<div id="inner" class="contain"></div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
document.body.offsetTop;
|
||||
inner.appendChild(document.createTextNode('inner-child'));
|
||||
outer.appendChild(document.createTextNode('outer-child'));
|
||||
</script>
|
||||
</body>
|
|
@ -0,0 +1,15 @@
|
|||
<!DOCTYPE html>
|
||||
<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
|
||||
<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1340168">
|
||||
<div style="contain:size layout;">
|
||||
<div id="klabb" style="display:inline-block; contain:size layout;">t</div>
|
||||
<br>
|
||||
<div id="babb" style="display:inline-block; width:10px; height:10px;"></div>
|
||||
</div>
|
||||
<script>
|
||||
document.body.offsetTop;
|
||||
klabb.innerHTML = ":-)";
|
||||
klabb.style.height = "100px";
|
||||
document.body.offsetTop;
|
||||
babb.style.width = "20px";
|
||||
</script>
|
|
@ -0,0 +1,18 @@
|
|||
<!DOCTYPE html>
|
||||
<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
|
||||
<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1386673">
|
||||
<div style="contain:layout size;">
|
||||
<div style="display:inline-block;">
|
||||
<div style="contain:layout size;">
|
||||
<div id="firstVictim"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="position:absolute;">
|
||||
<div id="secondVictim"></div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
document.body.offsetTop;
|
||||
firstVictim.style.display = "none";
|
||||
secondVictim.style.display = "none";
|
||||
</script>
|
|
@ -0,0 +1,12 @@
|
|||
<!DOCTYPE html>
|
||||
<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1439692">
|
||||
<style>
|
||||
body, fieldset { contain: strict; }
|
||||
</style>
|
||||
<script>
|
||||
function crash() {
|
||||
document.body.offsetTop;
|
||||
document.body.appendChild(document.createElement("fieldset"));
|
||||
}
|
||||
</script>
|
||||
<body onload="crash()">
|
|
@ -0,0 +1,11 @@
|
|||
<!DOCTYPE html>
|
||||
<div style="position: relative; width: 100px; height: 100px; overflow: hidden;">
|
||||
<div id="target" style="contain: size layout;">
|
||||
<canvas id="inner" width="0"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
document.body.offsetTop;
|
||||
document.getElementById('inner').width = '100';
|
||||
document.getElementById('target').style.contain = 'initial';
|
||||
</script>
|
39
Tests/LibWeb/Ref/expected/wpt-import/common/reftest-wait.js
Normal file
39
Tests/LibWeb/Ref/expected/wpt-import/common/reftest-wait.js
Normal file
|
@ -0,0 +1,39 @@
|
|||
/**
|
||||
* Remove the `reftest-wait` class on the document element.
|
||||
* The reftest runner will wait with taking a screenshot while
|
||||
* this class is present.
|
||||
*
|
||||
* See https://web-platform-tests.org/writing-tests/reftests.html#controlling-when-comparison-occurs
|
||||
*/
|
||||
function takeScreenshot() {
|
||||
document.documentElement.classList.remove("reftest-wait");
|
||||
}
|
||||
|
||||
/**
|
||||
* Call `takeScreenshot()` after a delay of at least |timeout| milliseconds.
|
||||
* @param {number} timeout - milliseconds
|
||||
*/
|
||||
function takeScreenshotDelayed(timeout) {
|
||||
setTimeout(function () {
|
||||
takeScreenshot();
|
||||
}, timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that a precondition is met before waiting for a screenshot.
|
||||
* @param {bool} condition - Fail the test if this evaluates to false
|
||||
* @param {string} msg - Error message to write to the screenshot
|
||||
*/
|
||||
function failIfNot(condition, msg) {
|
||||
const fail = () => {
|
||||
(document.body || document.documentElement).textContent = `Precondition Failed: ${msg}`;
|
||||
takeScreenshot();
|
||||
};
|
||||
if (!condition) {
|
||||
if (document.readyState == "interactive") {
|
||||
fail();
|
||||
} else {
|
||||
document.addEventListener("DOMContentLoaded", fail, false);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
"use strict";
|
||||
|
||||
/**
|
||||
* Waits until we have at least one frame rendered, regardless of the engine.
|
||||
*
|
||||
* @returns {Promise}
|
||||
*/
|
||||
function waitForAtLeastOneFrame() {
|
||||
return new Promise(resolve => {
|
||||
// Different web engines work slightly different on this area but waiting
|
||||
// for two requestAnimationFrames() to happen, one after another, should be
|
||||
// sufficient to ensure at least one frame has been generated anywhere.
|
||||
window.requestAnimationFrame(() => {
|
||||
window.requestAnimationFrame(() => {
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
<!doctype html>
|
||||
<title>CSS Test Reference</title>
|
||||
<p>You should see a wide orange rectangle to the left of the third float, overlapping the float.</p>
|
||||
<div style="width:400px;position:relative">
|
||||
<div style="float:right;width:200px;height:100px;background:blue"></div>
|
||||
<div style="float:left;width:250px;height:100px;background:blue"></div>
|
||||
<div style="float:right;width:300px;height:100px;background:blue"></div>
|
||||
<div style="position:absolute;left:0;top:200px;width:200px;height:20px;background-color:orange"></div>
|
||||
</div>
|
|
@ -0,0 +1,9 @@
|
|||
<!doctype html>
|
||||
<title>CSS Test Reference</title>
|
||||
<p>You should see a wide orange rectangle to the left of the first float, overlapping the float.</p>
|
||||
<div style="width:400px;position:relative">
|
||||
<div style="float:right;width:200px;height:100px;background:blue"></div>
|
||||
<div style="float:left;width:250px;height:100px;background:blue"></div>
|
||||
<div style="float:right;width:300px;height:100px;background:blue"></div>
|
||||
<div style="position:absolute;left:0;top:0;width:300px;height:20px;background-color:orange"></div>
|
||||
</div>
|
|
@ -0,0 +1,37 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Reftest Test</title>
|
||||
<link rel="author" title="Kyle Zentner" href="mailto:zentner.kyle@gmail.com">
|
||||
<link rel="author" title="Morgan Rae Reschenberg" href="mailto:mreschenberg@berkeley.edu">
|
||||
<style>
|
||||
#a {
|
||||
background: blue;
|
||||
margin: 10px;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
}
|
||||
#b {
|
||||
width: 50px;
|
||||
height: 40px;
|
||||
background: green;
|
||||
}
|
||||
#b-padding {
|
||||
height: 10px;
|
||||
}
|
||||
#c {
|
||||
width: 50px;
|
||||
height: 10px;
|
||||
background: lightblue;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="a">
|
||||
<div id="b-padding"></div>
|
||||
<div id="b"></div>
|
||||
<div id="c"></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,76 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Reftest Reference</title>
|
||||
<link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
|
||||
<style>
|
||||
.abspos-box {
|
||||
position: absolute;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
}
|
||||
|
||||
/* The boxes should stack in the order that I've listed their CSS classes
|
||||
here. The class names' first word (outside/before/inside/after) refers
|
||||
to the boxes' DOM position, and "background"/"midground"/"foreground"
|
||||
refers to their z-index values. */
|
||||
|
||||
.before-IB-background {
|
||||
background: darkmagenta;
|
||||
z-index: -1;
|
||||
top: 50px;
|
||||
left: 50px;
|
||||
}
|
||||
.after-IB-background {
|
||||
background: magenta;
|
||||
z-index: -1;
|
||||
top: 70px;
|
||||
left: 70px;
|
||||
}
|
||||
.outside-span-midground {
|
||||
background: darkkhaki;
|
||||
top: 90px;
|
||||
left: 90px;
|
||||
}
|
||||
.inside-IB-midground {
|
||||
background: khaki;
|
||||
top: 110px;
|
||||
left: 110px;
|
||||
}
|
||||
.before-IB-foreground {
|
||||
background: darkcyan;
|
||||
z-index: 1;
|
||||
top: 130px;
|
||||
left: 130px;
|
||||
}
|
||||
.after-IB-foreground {
|
||||
background: cyan;
|
||||
z-index: 1;
|
||||
top: 150px;
|
||||
left: 150px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- The expectation here is that 'abspos-box' elements will all interact in
|
||||
the same top-level stacking context. That means the box ordering should
|
||||
be (back to front): darkmagenta/magenta/darkkhaki/khaki/darkcyan/cyan,
|
||||
with the boxes stacked (visually) from top-left to bottom-right. -->
|
||||
|
||||
<div class="abspos-box outside-span-midground"></div>
|
||||
|
||||
<!-- Note: this file is identical to the testcase,
|
||||
except for the lack of "contain: layout" on this span. -->
|
||||
<span>
|
||||
<div class="abspos-box before-IB-background"></div>
|
||||
<div class="abspos-box before-IB-foreground"></div>
|
||||
<!-- This unstyled div crates the IB split: -->
|
||||
<div>
|
||||
<div class="abspos-box inside-IB-midground"></div>
|
||||
</div>
|
||||
<div class="abspos-box after-IB-background"></div>
|
||||
<div class="abspos-box after-IB-foreground"></div>
|
||||
</span>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,33 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Reftest Reference</title>
|
||||
<link rel="author" title="Kyle Zentner" href="mailto:zentner.kyle@gmail.com">
|
||||
<link rel="author" title="Morgan Rae Reschenberg" href="mailto:mreschenberg@berkeley.edu">
|
||||
<style>
|
||||
#a {
|
||||
display: contents;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background: green;
|
||||
margin: 50px;
|
||||
}
|
||||
#b {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background: green;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="a">
|
||||
<div>
|
||||
<div id="b"></div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,33 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Reftest Reference</title>
|
||||
<link rel="author" title="Kyle Zentner" href="mailto:zentner.kyle@gmail.com">
|
||||
<link rel="author" title="Morgan Rae Reschenberg" href="mailto:mreschenberg@berkeley.edu">
|
||||
<style>
|
||||
#a {
|
||||
display: contents;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background: red;
|
||||
margin: 50px;
|
||||
}
|
||||
#b {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background: green;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="a">
|
||||
<div>
|
||||
<div id="b"></div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,28 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<title>CSS Containment Test: Scrolling overflow works when paint is contained"</title>
|
||||
<link rel="help" href="https://drafts.csswg.org/css-contain-1/#containment-paint">
|
||||
<meta name="assert" content="Scrolling overflow works when paint is contained.">
|
||||
|
||||
<script src="../../common/reftest-wait.js"></script>
|
||||
<script src="../../common/rendering-utils.js"></script>
|
||||
|
||||
<style>
|
||||
.content {
|
||||
height: 100vh;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
<body>
|
||||
<div class="content"></div>
|
||||
|
||||
<script>
|
||||
waitForAtLeastOneFrame().then(() => {
|
||||
document.body.scrollTop = 100;
|
||||
takeScreenshot();
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,19 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Reftest Reference</title>
|
||||
<link rel="author" title="Kyle Zentner" href="mailto:zentner.kyle@gmail.com">
|
||||
<style>
|
||||
#a {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background: green;
|
||||
margin: 50px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="a"></div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,76 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Reftest Reference</title>
|
||||
<link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
|
||||
<style>
|
||||
.abspos-box {
|
||||
position: absolute;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
}
|
||||
|
||||
/* The boxes should stack in the order that I've listed their CSS classes
|
||||
here. The class names' first word (outside/before/inside/after) refers
|
||||
to the boxes' DOM position, and "background"/"midground"/"foreground"
|
||||
refers to their z-index values. */
|
||||
|
||||
.before-IB-background {
|
||||
background: darkmagenta;
|
||||
z-index: -1;
|
||||
top: 50px;
|
||||
left: 50px;
|
||||
}
|
||||
.after-IB-background {
|
||||
background: magenta;
|
||||
z-index: -1;
|
||||
top: 70px;
|
||||
left: 70px;
|
||||
}
|
||||
.outside-span-midground {
|
||||
background: darkkhaki;
|
||||
top: 90px;
|
||||
left: 90px;
|
||||
}
|
||||
.inside-IB-midground {
|
||||
background: khaki;
|
||||
top: 110px;
|
||||
left: 110px;
|
||||
}
|
||||
.before-IB-foreground {
|
||||
background: darkcyan;
|
||||
z-index: 1;
|
||||
top: 130px;
|
||||
left: 130px;
|
||||
}
|
||||
.after-IB-foreground {
|
||||
background: cyan;
|
||||
z-index: 1;
|
||||
top: 150px;
|
||||
left: 150px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- The expectation here is that 'abspos-box' elements will all interact in
|
||||
the same top-level stacking context. That means the box ordering should
|
||||
be (back to front): darkmagenta/magenta/darkkhaki/khaki/darkcyan/cyan,
|
||||
with the boxes stacked (visually) from top-left to bottom-right. -->
|
||||
|
||||
<div class="abspos-box outside-span-midground"></div>
|
||||
|
||||
<!-- Note: this file is identical to the testcase,
|
||||
except for the lack of "contain: paint" on this span. -->
|
||||
<span>
|
||||
<div class="abspos-box before-IB-background"></div>
|
||||
<div class="abspos-box before-IB-foreground"></div>
|
||||
<!-- This unstyled div crates the IB split: -->
|
||||
<div>
|
||||
<div class="abspos-box inside-IB-midground"></div>
|
||||
</div>
|
||||
<div class="abspos-box after-IB-background"></div>
|
||||
<div class="abspos-box after-IB-foreground"></div>
|
||||
</span>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,57 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Reftest Reference</title>
|
||||
<link rel="author" title="Yusuf Sermet" href="mailto:ysermet@mozilla.com">
|
||||
<style>
|
||||
div {
|
||||
position: relative;
|
||||
width: 100px;
|
||||
}
|
||||
#div1,
|
||||
#div3 {
|
||||
background-color: #cfc;
|
||||
height: 100px;
|
||||
}
|
||||
#div1 {
|
||||
z-index: 5;
|
||||
}
|
||||
#div2 {
|
||||
display: contents;
|
||||
background-color: #fdd;
|
||||
height: 100px;
|
||||
top: -20px;
|
||||
}
|
||||
#div2_1 {
|
||||
background-color: #ffc;
|
||||
z-index: 6;
|
||||
top: -10px;
|
||||
height: 100px;
|
||||
}
|
||||
#div2_2 {
|
||||
z-index: 3;
|
||||
position: absolute;
|
||||
top: -15px;
|
||||
width: 40px;
|
||||
height: 300px;
|
||||
background-color: #ddf;
|
||||
}
|
||||
#div3 {
|
||||
z-index: 2;
|
||||
top: -50px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="div1"></div>
|
||||
|
||||
<div id="div2">
|
||||
<div id="div2_1"></div>
|
||||
|
||||
<div id="div2_2"></div>
|
||||
</div>
|
||||
|
||||
<div id="div3"></div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,62 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Reftest Reference</title>
|
||||
<link rel="author" title="Yusuf Sermet" href="mailto:ysermet@mozilla.com">
|
||||
<style>
|
||||
div {
|
||||
position: relative;
|
||||
width: 100px;
|
||||
}
|
||||
#div1,
|
||||
#div3 {
|
||||
background-color: #cfc;
|
||||
}
|
||||
#div1 {
|
||||
z-index: 5;
|
||||
}
|
||||
#div2 {
|
||||
z-index: 1;
|
||||
background-color: #fdd;
|
||||
height: 100px;
|
||||
top: -20px;
|
||||
}
|
||||
#div2_1 {
|
||||
background-color: #ffc;
|
||||
z-index: 6;
|
||||
top: -10px;
|
||||
}
|
||||
#div2_2 {
|
||||
z-index: 3;
|
||||
position: absolute;
|
||||
top: -15px;
|
||||
width: 40px;
|
||||
height: 100px;
|
||||
background-color: #ddf;
|
||||
}
|
||||
#div3 {
|
||||
z-index: 2;
|
||||
top: -50px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="div1">
|
||||
<br/><br/>
|
||||
</div>
|
||||
|
||||
<div id="div2">
|
||||
<div id="div2_1">
|
||||
<br/><br/>
|
||||
</div>
|
||||
|
||||
<div id="div2_2">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="div3">
|
||||
<br/><br/>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,25 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Containment Reference: Size containment replaced elements intrinsic size</title>
|
||||
<style>
|
||||
body > div, video, audio, img, canvas, svg, iframe {
|
||||
border: 3px solid orange;
|
||||
contain: size;
|
||||
margin-bottom: 15px;
|
||||
width: 0px;
|
||||
height: 0px;
|
||||
float: left;
|
||||
clear: both;
|
||||
}
|
||||
</style>
|
||||
<div>abc</div>
|
||||
<video></video><br>
|
||||
<video controls></video><br>
|
||||
<img src="support/60x60-green.png"><br>
|
||||
<picture>
|
||||
<source srcset="support/60x60-green.png">
|
||||
<img>
|
||||
</picture><br>
|
||||
<canvas></canvas><br>
|
||||
<svg></svg><br>
|
||||
<iframe></iframe>
|
|
@ -0,0 +1,26 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Containment Reference: Size containment replaced elements intrinsic size</title>
|
||||
<style>
|
||||
body > div, video, audio, img, canvas, svg, iframe {
|
||||
position: absolute;
|
||||
border: 3px solid orange;
|
||||
contain: size;
|
||||
margin-bottom: 15px;
|
||||
width: 0px;
|
||||
height: 0px;
|
||||
float: left;
|
||||
clear: both;
|
||||
}
|
||||
</style>
|
||||
<div>abc</div>
|
||||
<video></video><br>
|
||||
<video controls></video><br>
|
||||
<img src="support/60x60-green.png"><br>
|
||||
<picture>
|
||||
<source srcset="support/60x60-green.png">
|
||||
<img>
|
||||
</picture><br>
|
||||
<canvas></canvas><br>
|
||||
<svg></svg><br>
|
||||
<iframe></iframe>
|
|
@ -0,0 +1,24 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Containment Reference: Size containment replaced elements intrinsic size</title>
|
||||
<style>
|
||||
div, video, audio, img, canvas, svg, iframe {
|
||||
border: 3px solid orange;
|
||||
margin-bottom: 15px;
|
||||
width: 25px;
|
||||
height: 35px;
|
||||
float: left;
|
||||
clear: both;
|
||||
}
|
||||
</style>
|
||||
<div>abc</div>
|
||||
<video></video><br>
|
||||
<video controls></video><br>
|
||||
<img src="support/60x60-green.png"><br>
|
||||
<picture>
|
||||
<source srcset="support/60x60-green.png">
|
||||
<img>
|
||||
</picture><br>
|
||||
<canvas></canvas><br>
|
||||
<svg></svg><br>
|
||||
<iframe></iframe>
|
|
@ -0,0 +1,35 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Reftest Reference</title>
|
||||
<link rel="author" title="Morgan Rae Reschenberg" href="mailto:mreschenberg@berkeley.edu">
|
||||
<style>
|
||||
select {
|
||||
color: transparent;
|
||||
}
|
||||
.minWidth {
|
||||
min-width: 100px;
|
||||
}
|
||||
.width {
|
||||
width: 100px;
|
||||
}
|
||||
.floatLWidth {
|
||||
float: left;
|
||||
width: 100px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<select multiple class="floatLWidth">
|
||||
</select>
|
||||
<br style="clear:both;">
|
||||
|
||||
<select multiple class="minWidth">
|
||||
</select>
|
||||
<br>
|
||||
|
||||
<select multiple class="width">
|
||||
</select>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,18 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Reftest Reference</title>
|
||||
<link rel="author" title="Morgan Rae Reschenberg" href="mailto:mreschenberg@berkeley.edu">
|
||||
<style>
|
||||
caption {
|
||||
border: 1em solid green;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<table>
|
||||
<caption></caption>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,15 @@
|
|||
<!doctype html>
|
||||
<html lang=en>
|
||||
<meta charset=utf-8>
|
||||
<title>CSS-contain test referemce</title>
|
||||
<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net">
|
||||
|
||||
<style>
|
||||
html, body, p, div {
|
||||
margin: 0;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<p>Test passes if there is no red.
|
|
@ -0,0 +1,27 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<meta charset="UTF-8">
|
||||
|
||||
<title>CSS Reference Test</title>
|
||||
|
||||
<link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
|
||||
|
||||
<style>
|
||||
div#green-square
|
||||
{
|
||||
background-color: green;
|
||||
height: 100px;
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
div#result
|
||||
{
|
||||
font-size: 3em;
|
||||
}
|
||||
</style>
|
||||
|
||||
<p>Test passes if there is a filled green square, no red and the number 17.
|
||||
|
||||
<div id="green-square"></div>
|
||||
|
||||
<div id="result">17</div>
|
|
@ -0,0 +1,30 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset=utf-8>
|
||||
<title>CSS Containment Test: Removing layout containment and contained positioned elements</title>
|
||||
|
||||
<style>
|
||||
.container {
|
||||
width: 300px;
|
||||
height: 300px;
|
||||
}
|
||||
.box {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background-color: green;
|
||||
}
|
||||
.fixed {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
.abspos {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="container">
|
||||
<div class="fixed box"></div>
|
||||
<div class="abspos box"></div>
|
||||
</div>
|
|
@ -0,0 +1,27 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Containment Test: Layout containment fixed positioned descendants</title>
|
||||
<style>
|
||||
#green {
|
||||
background: green;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
body {
|
||||
height: 3000px;
|
||||
margin: 0px;
|
||||
}
|
||||
#spacer {
|
||||
height: 200px;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
function runTest() {
|
||||
document.documentElement.scrollTop += 200;
|
||||
}
|
||||
</script>
|
||||
<body onload="runTest()">
|
||||
<div id="spacer"></div>
|
||||
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
|
||||
<div id="green"></div>
|
||||
</body>
|
|
@ -0,0 +1,43 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<meta charset="UTF-8">
|
||||
|
||||
<title>CSS Reference Test</title>
|
||||
|
||||
<link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
|
||||
|
||||
<style>
|
||||
table
|
||||
{
|
||||
background-color: blue;
|
||||
border-spacing: 2px;
|
||||
height: 206px;
|
||||
table-layout: fixed;
|
||||
width: 206px;
|
||||
}
|
||||
|
||||
td
|
||||
{
|
||||
background-color: white;
|
||||
padding: 0px;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
span
|
||||
{
|
||||
background-color: green;
|
||||
color: white;
|
||||
font-family: monospace;
|
||||
vertical-align: top;
|
||||
}
|
||||
</style>
|
||||
|
||||
<p>Test passes if there is the word PASS and if there is <strong>no red</strong>.
|
||||
|
||||
<table>
|
||||
|
||||
<tr><td> <td>
|
||||
|
||||
<tr><td> <td><span>PASS</span>
|
||||
|
||||
</table>
|
|
@ -0,0 +1,36 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<meta charset="UTF-8">
|
||||
|
||||
<title>CSS Reference Test</title>
|
||||
|
||||
<link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
|
||||
|
||||
<style>
|
||||
div
|
||||
{
|
||||
color: transparent;
|
||||
float: left;
|
||||
font-size: 16px;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
div#blue-rectangle
|
||||
{
|
||||
background-color: blue;
|
||||
margin: 8px;
|
||||
width: 6em;
|
||||
}
|
||||
|
||||
div#orange-rectangle
|
||||
{
|
||||
background-color: orange;
|
||||
width: 12em;
|
||||
}
|
||||
</style>
|
||||
|
||||
<p>Test passes if the orange rectangle and blue rectangle do not overlap.
|
||||
|
||||
<div id="blue-rectangle">Some text in a blue rectangle.</div>
|
||||
|
||||
<div id="orange-rectangle">Some text in an orange rectangle. Some text in an orange rectangle. Some text in an orange rectangle.</div>
|
|
@ -0,0 +1,24 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<meta charset="UTF-8">
|
||||
|
||||
<title>CSS Reference Test</title>
|
||||
|
||||
<link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
|
||||
|
||||
<style>
|
||||
div
|
||||
{
|
||||
font-family: monospace;
|
||||
font-size: 100px;
|
||||
height: 3em;
|
||||
overflow: scroll;
|
||||
width: 4ch;
|
||||
}
|
||||
</style>
|
||||
|
||||
<body>
|
||||
|
||||
<p>Test passes if there is no red.
|
||||
|
||||
<div></div>
|
|
@ -0,0 +1,24 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<meta charset="UTF-8">
|
||||
|
||||
<title>CSS Reference Test</title>
|
||||
|
||||
<link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
|
||||
|
||||
<style>
|
||||
div
|
||||
{
|
||||
font-family: monospace;
|
||||
font-size: 100px;
|
||||
height: 2.8ch;
|
||||
overflow: scroll;
|
||||
width: 4ch;
|
||||
}
|
||||
</style>
|
||||
|
||||
<body>
|
||||
|
||||
<p>Test passes if there is no red.
|
||||
|
||||
<div></div>
|
|
@ -0,0 +1,11 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<meta charset="UTF-8">
|
||||
|
||||
<title>CSS Reference Test</title>
|
||||
|
||||
<link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
|
||||
|
||||
<body>
|
||||
|
||||
<p>Test passes if there is no red.
|
|
@ -0,0 +1,37 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<meta charset="UTF-8">
|
||||
|
||||
<title>CSS Reference Test</title>
|
||||
|
||||
<link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
|
||||
|
||||
<style>
|
||||
div
|
||||
{
|
||||
color: transparent;
|
||||
float: left;
|
||||
font-size: 16px;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
div#blue-rectangle
|
||||
{
|
||||
background-color: blue;
|
||||
margin: 8px;
|
||||
width: 6em;
|
||||
}
|
||||
|
||||
div#orange-rectangle
|
||||
{
|
||||
background-color: orange;
|
||||
height: 0px;
|
||||
width: 12em;
|
||||
}
|
||||
</style>
|
||||
|
||||
<p>Test passes if the orange rectangle and blue rectangle do not overlap.
|
||||
|
||||
<div id="blue-rectangle">Some text in a blue rectangle.</div>
|
||||
|
||||
<div id="orange-rectangle">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore.</div>
|
|
@ -0,0 +1,24 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<meta charset="UTF-8">
|
||||
|
||||
<title>CSS Reference Test</title>
|
||||
|
||||
<link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
|
||||
|
||||
<style>
|
||||
div
|
||||
{
|
||||
background-color: green;
|
||||
height: 100px;
|
||||
left: 100px;
|
||||
position: relative;
|
||||
top: 100px;
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<p>Test passes if there is a filled green square and <strong>no red</strong>.
|
||||
|
||||
<div></div>
|
|
@ -0,0 +1,46 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<meta charset="UTF-8">
|
||||
|
||||
<title>CSS Reference Test</title>
|
||||
|
||||
<link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
|
||||
|
||||
<style>
|
||||
p
|
||||
{
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
div
|
||||
{
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
div.orange
|
||||
{
|
||||
background-color: orange;
|
||||
}
|
||||
|
||||
div.blue
|
||||
{
|
||||
background-color: blue;
|
||||
}
|
||||
|
||||
div#lime
|
||||
{
|
||||
background-color: lime;
|
||||
}
|
||||
</style>
|
||||
|
||||
<p>Test passes if there are 5 horizontal stripes across the page in this order (from top to bottom): an orange stripe, a blue stripe, a bright green stripe, a blue stripe and then an orange stripe.
|
||||
|
||||
<div class="orange"></div>
|
||||
|
||||
<div class="blue"></div>
|
||||
|
||||
<div id="lime"></div>
|
||||
|
||||
<div class="blue"></div>
|
||||
|
||||
<div class="orange"></div>
|
|
@ -0,0 +1,14 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Containment Test: Reference file</title>
|
||||
<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
|
||||
<style>
|
||||
.wrapper {
|
||||
border: solid thick;
|
||||
margin: 1em;
|
||||
}
|
||||
</style>
|
||||
<p>Test passes if it has the same output than the reference.</p>
|
||||
<div class="wrapper">
|
||||
<div style="margin: 2em 0;">This text should have 2em top and bottom margins (margins do not collapse).</div>
|
||||
</div>
|
|
@ -0,0 +1,14 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Containment Test: Reference file</title>
|
||||
<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
|
||||
<style>
|
||||
.wrapper {
|
||||
border: solid thick;
|
||||
margin: 1em;
|
||||
}
|
||||
</style>
|
||||
<p>Test passes if it has the same output than the reference.</p>
|
||||
<div class="wrapper">
|
||||
<div style="margin: 1em 0;">This text should have 1em top and bottom margins.</div>
|
||||
</div>
|
|
@ -0,0 +1,11 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<meta charset="UTF-8">
|
||||
|
||||
<title>CSS Reference Test</title>
|
||||
|
||||
<link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
|
||||
|
||||
<p>This test passes if the painted blue area is <strong>exactly as tall as</strong> the orange square.
|
||||
|
||||
<div><img src="../support/swatch-blue.png" width="100" height="100" alt="Image download support must be enabled"> <img src="../support/swatch-orange.png" width="100" height="100" alt="Image download support must be enabled"></div>
|
|
@ -0,0 +1,25 @@
|
|||
<!doctype html>
|
||||
<html lang=en>
|
||||
<meta charset=utf-8>
|
||||
<title>test reference</title>
|
||||
<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net">
|
||||
<style>
|
||||
div { font-size: 50px; }
|
||||
.green { background: green; }
|
||||
.grid {
|
||||
display: grid;
|
||||
grid-template-columns: min-content max-content;
|
||||
}
|
||||
</style>
|
||||
|
||||
<p>This test passes if there are two green rectangles and no red.
|
||||
|
||||
<div class=grid>
|
||||
<div style="grid-area: 1/1"> </div>
|
||||
<div style="grid-area: 2/2"id=test class="grid">
|
||||
<div> </div>
|
||||
<div class=green></div>
|
||||
<div class=green></div>
|
||||
<div> </div>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,18 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<meta charset="UTF-8">
|
||||
|
||||
<title>CSS Reference Test</title>
|
||||
|
||||
<link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
|
||||
|
||||
<style>
|
||||
div
|
||||
{
|
||||
font-size: 3em;
|
||||
}
|
||||
</style>
|
||||
|
||||
<p>Test passes if there is the number 14.
|
||||
|
||||
<div>14</div>
|
|
@ -0,0 +1,18 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<meta charset="UTF-8">
|
||||
|
||||
<title>CSS Reference Test</title>
|
||||
|
||||
<link rel="author" title="Vladimir Levin" href="mailto:vmpstr@chromium.org">
|
||||
|
||||
<style>
|
||||
div
|
||||
{
|
||||
font-size: 3em;
|
||||
}
|
||||
</style>
|
||||
|
||||
<p>Test passes if there is the number 13.
|
||||
|
||||
<div>13</div>
|
|
@ -0,0 +1,8 @@
|
|||
<!doctype html>
|
||||
<html lang=en>
|
||||
<meta charset=utf-8>
|
||||
<title>CSS-contain test reference</title>
|
||||
<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net">
|
||||
|
||||
<p>Test passes if the text below is "1 1.2" (not including the quotation marks).<p>
|
||||
<div>1 1.2</div>
|
|
@ -0,0 +1,8 @@
|
|||
<!doctype html>
|
||||
<html lang=en>
|
||||
<meta charset=utf-8>
|
||||
<title>CSS-contain test reference</title>
|
||||
<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net">
|
||||
|
||||
<p>Test passes if the text below is "1 2" (not including the quotation marks).<p>
|
||||
<div>1 2</div>
|
|
@ -0,0 +1,15 @@
|
|||
<!doctype html>
|
||||
<meta charset="UTF-8">
|
||||
<title>CSS Test Reference</title>
|
||||
<style>
|
||||
.list-item {
|
||||
margin-left: 40px;
|
||||
}
|
||||
</style>
|
||||
<div class="list-item">
|
||||
[1] A1
|
||||
<div class="list-item">[1] B1</div>
|
||||
<div class="list-item">[2] B2</div>
|
||||
</div>
|
||||
<div class="list-item">[2] A2</div>
|
||||
<div class="list-item">[3] A3</div>
|
|
@ -0,0 +1,13 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Reference rendering - passes if there is the word "PASS" below</title>
|
||||
<style>
|
||||
div { overflow: hidden; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<p>Test passes if there is the word "PASS" below.</p>
|
||||
<div>PASS</div>
|
||||
</body>
|
||||
</html>
|
Binary file not shown.
After Width: | Height: | Size: 86 B |
|
@ -0,0 +1,4 @@
|
|||
<!DOCTYPE html>
|
||||
<title>CSS Reftest Reference</title>
|
||||
<link rel="author" title="Morten Stenshorne" href="mstensho@chromium.org">
|
||||
<p>There should be nothing below.</p>
|
|
@ -0,0 +1,11 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Reference rendering - passes if there is the word "PASS" below</title>
|
||||
<link rel="author" title="Opera" href="https://www.opera.com/">
|
||||
</head>
|
||||
<body>
|
||||
<p>Test passes if there is the word "PASS" below.</p>
|
||||
<div>PASS</div>
|
||||
</body>
|
||||
</html>
|
BIN
Tests/LibWeb/Ref/expected/wpt-import/css/support/swatch-blue.png
Normal file
BIN
Tests/LibWeb/Ref/expected/wpt-import/css/support/swatch-blue.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 83 B |
Binary file not shown.
After Width: | Height: | Size: 83 B |
39
Tests/LibWeb/Ref/input/wpt-import/common/reftest-wait.js
Normal file
39
Tests/LibWeb/Ref/input/wpt-import/common/reftest-wait.js
Normal file
|
@ -0,0 +1,39 @@
|
|||
/**
|
||||
* Remove the `reftest-wait` class on the document element.
|
||||
* The reftest runner will wait with taking a screenshot while
|
||||
* this class is present.
|
||||
*
|
||||
* See https://web-platform-tests.org/writing-tests/reftests.html#controlling-when-comparison-occurs
|
||||
*/
|
||||
function takeScreenshot() {
|
||||
document.documentElement.classList.remove("reftest-wait");
|
||||
}
|
||||
|
||||
/**
|
||||
* Call `takeScreenshot()` after a delay of at least |timeout| milliseconds.
|
||||
* @param {number} timeout - milliseconds
|
||||
*/
|
||||
function takeScreenshotDelayed(timeout) {
|
||||
setTimeout(function() {
|
||||
takeScreenshot();
|
||||
}, timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that a precondition is met before waiting for a screenshot.
|
||||
* @param {bool} condition - Fail the test if this evaluates to false
|
||||
* @param {string} msg - Error message to write to the screenshot
|
||||
*/
|
||||
function failIfNot(condition, msg) {
|
||||
const fail = () => {
|
||||
(document.body || document.documentElement).textContent = `Precondition Failed: ${msg}`;
|
||||
takeScreenshot();
|
||||
};
|
||||
if (!condition) {
|
||||
if (document.readyState == "interactive") {
|
||||
fail();
|
||||
} else {
|
||||
document.addEventListener("DOMContentLoaded", fail, false);
|
||||
}
|
||||
}
|
||||
}
|
19
Tests/LibWeb/Ref/input/wpt-import/common/rendering-utils.js
Normal file
19
Tests/LibWeb/Ref/input/wpt-import/common/rendering-utils.js
Normal file
|
@ -0,0 +1,19 @@
|
|||
"use strict";
|
||||
|
||||
/**
|
||||
* Waits until we have at least one frame rendered, regardless of the engine.
|
||||
*
|
||||
* @returns {Promise}
|
||||
*/
|
||||
function waitForAtLeastOneFrame() {
|
||||
return new Promise(resolve => {
|
||||
// Different web engines work slightly different on this area but waiting
|
||||
// for two requestAnimationFrames() to happen, one after another, should be
|
||||
// sufficient to ensure at least one frame has been generated anywhere.
|
||||
window.requestAnimationFrame(() => {
|
||||
window.requestAnimationFrame(() => {
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
<!doctype html>
|
||||
<html lang=en>
|
||||
<meta charset=utf-8>
|
||||
<title>CSS-contain test: layout containment on body prevents overflow propagation</title>
|
||||
<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net">
|
||||
<meta name=flags content="">
|
||||
<meta name=assert content="layout containment on body prevents overflow propagation">
|
||||
<link rel="match" href="../../../../expected/wpt-import/css/css-contain/reference/contain-body-overflow-001-ref.html">
|
||||
<link rel=help href="https://drafts.csswg.org/css-contain-1/#contain-property">
|
||||
|
||||
<style>
|
||||
html, body, p, div {
|
||||
margin: 0;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
}
|
||||
div { background: red; }
|
||||
body {
|
||||
overflow: hidden;
|
||||
contain: layout;
|
||||
}
|
||||
</style>
|
||||
|
||||
<p>Test passes if there is no red.
|
||||
|
||||
<div></div>
|
|
@ -0,0 +1,26 @@
|
|||
<!doctype html>
|
||||
<html lang=en>
|
||||
<meta charset=utf-8>
|
||||
<title>CSS-contain test: size containment on body prevents overflow propagation</title>
|
||||
<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net">
|
||||
<meta name=flags content="">
|
||||
<meta name=assert content="size containment on body prevents overflow propagation">
|
||||
<link rel="match" href="../../../../expected/wpt-import/css/css-contain/reference/contain-body-overflow-001-ref.html">
|
||||
<link rel=help href="https://drafts.csswg.org/css-contain-1/#contain-property">
|
||||
|
||||
<style>
|
||||
html, body, p, div {
|
||||
margin: 0;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
}
|
||||
div { background: red; }
|
||||
body {
|
||||
overflow: hidden;
|
||||
contain: size;
|
||||
}
|
||||
</style>
|
||||
|
||||
<p>Test passes if there is no red.
|
||||
|
||||
<div></div>
|
|
@ -0,0 +1,26 @@
|
|||
<!doctype html>
|
||||
<html lang=en>
|
||||
<meta charset=utf-8>
|
||||
<title>CSS-contain test: style containment on body prevents overflow propagation</title>
|
||||
<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net">
|
||||
<meta name=flags content="">
|
||||
<meta name=assert content="style containment on body prevents overflow propagation">
|
||||
<link rel="match" href="../../../../expected/wpt-import/css/css-contain/reference/contain-body-overflow-001-ref.html">
|
||||
<link rel=help href="https://drafts.csswg.org/css-contain-2/#contain-property">
|
||||
|
||||
<style>
|
||||
html, body, p, div {
|
||||
margin: 0;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
}
|
||||
div { background: red; }
|
||||
body {
|
||||
overflow: hidden;
|
||||
contain: style;
|
||||
}
|
||||
</style>
|
||||
|
||||
<p>Test passes if there is no red.
|
||||
|
||||
<div></div>
|
|
@ -0,0 +1,42 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<meta charset="UTF-8">
|
||||
|
||||
<title>CSS Containment Test: a block with 'contain: content' alongside a float</title>
|
||||
|
||||
<link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
|
||||
<link rel="help" href="https://www.w3.org/TR/css-contain-1/#contain-property">
|
||||
<link rel="match" href="../../../../expected/wpt-import/css/css-contain/reference/contain-layout-ifc-022-ref.html">
|
||||
|
||||
|
||||
<style>
|
||||
div
|
||||
{
|
||||
color: transparent;
|
||||
font-size: 16px;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
div#floated-left
|
||||
{
|
||||
background-color: blue;
|
||||
float: left;
|
||||
margin: 8px;
|
||||
width: 6em;
|
||||
}
|
||||
|
||||
div#with-contain-content
|
||||
{
|
||||
background-color: orange;
|
||||
width: 12em;
|
||||
|
||||
contain: content;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
<p>Test passes if the orange rectangle and blue rectangle do not overlap.
|
||||
|
||||
<div id="floated-left">Some text in a blue rectangle.</div>
|
||||
|
||||
<div id="with-contain-content">Some text in an orange rectangle. Some text in an orange rectangle. Some text in an orange rectangle.</div>
|
|
@ -0,0 +1,52 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<meta charset="UTF-8">
|
||||
|
||||
<title>CSS Containment Test: element with 'contain: content' and absolutely positioned descendants</title>
|
||||
|
||||
<link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-contain/#contain-property">
|
||||
<link rel="match" href="../../../../expected/wpt-import/css/reference/ref-filled-green-100px-square.xht">
|
||||
|
||||
<meta name="assert" content="This test checks that an element with 'contain: content' acts as containing block for its absolutely positioned descendants.">
|
||||
|
||||
<style>
|
||||
div
|
||||
{
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
div#contain-content
|
||||
{
|
||||
background-color: red;
|
||||
contain: content;
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
div.abspos
|
||||
{
|
||||
background-color: green;
|
||||
height: 50px;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
div#first-abspos
|
||||
{
|
||||
top: 0px;
|
||||
}
|
||||
|
||||
div#second-abspos
|
||||
{
|
||||
bottom: 0px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<body>
|
||||
|
||||
<p>Test passes if there is a filled green square and <strong>no red</strong>.
|
||||
|
||||
<div id="contain-content">
|
||||
<div id="first-abspos" class="abspos"></div>
|
||||
<div id="second-abspos" class="abspos"></div>
|
||||
</div>
|
|
@ -0,0 +1,62 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<meta charset="UTF-8">
|
||||
|
||||
<title>CSS Containment Test: 'contain: content' applies to 'table-cell' elements</title>
|
||||
|
||||
<link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
|
||||
<link rel="help" href="https://www.w3.org/TR/css-contain-1/#containment-layout">
|
||||
<link rel="match" href="../../../../expected/wpt-import/css/css-contain/reference/contain-layout-cell-001-ref.html">
|
||||
|
||||
<meta content="In this test, the td#contain should act as the containing block for div#abs-pos ." name="assert">
|
||||
|
||||
<style>
|
||||
table
|
||||
{
|
||||
background-color: blue;
|
||||
border-spacing: 2px;
|
||||
height: 206px;
|
||||
table-layout: fixed;
|
||||
width: 206px;
|
||||
}
|
||||
|
||||
td
|
||||
{
|
||||
background-color: white;
|
||||
padding: 0px;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
td#contain
|
||||
{
|
||||
contain: content;
|
||||
}
|
||||
|
||||
span
|
||||
{
|
||||
background-color: red;
|
||||
color: yellow;
|
||||
font-family: monospace;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
div#abs-pos
|
||||
{
|
||||
background-color: green;
|
||||
color: white;
|
||||
font-family: monospace;
|
||||
left: 0px;
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<p>Test passes if there is the word PASS and if there is <strong>no red</strong>.
|
||||
|
||||
<table>
|
||||
|
||||
<tr><td> <td>
|
||||
|
||||
<tr><td> <td id="contain"><span>FAIL</span><div id="abs-pos">PASS</div>
|
||||
|
||||
</table>
|
|
@ -0,0 +1,28 @@
|
|||
<!doctype html>
|
||||
<html lang=en>
|
||||
<meta charset=utf-8>
|
||||
<title>CSS-contain test: layout containment on html prevents overflow propagation</title>
|
||||
<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net">
|
||||
<meta name=flags content="">
|
||||
<meta name=assert content="layout containment on html prevents overflow propagation">
|
||||
<link rel="match" href="../../../../expected/wpt-import/css/css-contain/reference/contain-body-overflow-001-ref.html">
|
||||
<link rel=help href="https://drafts.csswg.org/css-contain-1/#contain-property">
|
||||
|
||||
<style>
|
||||
html, body, p, div {
|
||||
margin: 0;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
}
|
||||
div { background: red; }
|
||||
body {
|
||||
overflow: hidden;
|
||||
}
|
||||
html {
|
||||
contain: layout;
|
||||
}
|
||||
</style>
|
||||
|
||||
<p>Test passes if there is no red.
|
||||
|
||||
<div></div>
|
|
@ -0,0 +1,29 @@
|
|||
<!doctype html>
|
||||
<html lang=en>
|
||||
<meta charset=utf-8>
|
||||
<title>CSS-contain test: paint containment on html prevents overflow propagation</title>
|
||||
<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net">
|
||||
<meta name=flags content="">
|
||||
<meta name=assert content="paint containment on html prevents overflow propagation">
|
||||
<link rel="match" href="../../../../expected/wpt-import/css/css-contain/reference/contain-body-overflow-001-ref.html">
|
||||
<link rel=help href="https://drafts.csswg.org/css-contain-1/#contain-property">
|
||||
|
||||
<style>
|
||||
html, body, p, div {
|
||||
margin: 0;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
}
|
||||
div { background: red; }
|
||||
body {
|
||||
overflow: hidden;
|
||||
}
|
||||
html {
|
||||
height: 400px;
|
||||
contain: paint;
|
||||
}
|
||||
</style>
|
||||
|
||||
<p>Test passes if there is no red.
|
||||
|
||||
<div></div>
|
|
@ -0,0 +1,28 @@
|
|||
<!doctype html>
|
||||
<html lang=en>
|
||||
<meta charset=utf-8>
|
||||
<title>CSS-contain test: size containment on html prevents overflow propagation</title>
|
||||
<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net">
|
||||
<meta name=flags content="">
|
||||
<meta name=assert content="size containment on html prevents overflow propagation">
|
||||
<link rel="match" href="../../../../expected/wpt-import/css/css-contain/reference/contain-body-overflow-001-ref.html">
|
||||
<link rel=help href="https://drafts.csswg.org/css-contain-1/#contain-property">
|
||||
|
||||
<style>
|
||||
html, body, p, div {
|
||||
margin: 0;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
}
|
||||
div { background: red; }
|
||||
body {
|
||||
overflow: hidden;
|
||||
}
|
||||
html {
|
||||
contain: size;
|
||||
}
|
||||
</style>
|
||||
|
||||
<p>Test passes if there is no red.
|
||||
|
||||
<div></div>
|
|
@ -0,0 +1,28 @@
|
|||
<!doctype html>
|
||||
<html lang=en>
|
||||
<meta charset=utf-8>
|
||||
<title>CSS-contain test: style containment on html prevents overflow propagation</title>
|
||||
<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net">
|
||||
<meta name=flags content="">
|
||||
<meta name=assert content="style containment on html prevents overflow propagation">
|
||||
<link rel="match" href="../../../../expected/wpt-import/css/css-contain/reference/contain-body-overflow-001-ref.html">
|
||||
<link rel=help href="https://drafts.csswg.org/css-contain-2/#contain-property">
|
||||
|
||||
<style>
|
||||
html, body, p, div {
|
||||
margin: 0;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
}
|
||||
div { background: red; }
|
||||
body {
|
||||
overflow: hidden;
|
||||
}
|
||||
html {
|
||||
contain: style;
|
||||
}
|
||||
</style>
|
||||
|
||||
<p>Test passes if there is no red.
|
||||
|
||||
<div></div>
|
|
@ -0,0 +1,35 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<link rel="author" title="Sammy Gill" href="mailto:sammy.gill@apple.com">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-grid-2/#algo-stretch">
|
||||
<link rel="match" href="../../../../expected/wpt-import//css/reference/ref-filled-green-100px-square-only.html">
|
||||
<meta name="assert" content="grid with inline-size containment, and min-height will still distribute extra space to auto rows">
|
||||
<style>
|
||||
grid {
|
||||
display: grid;
|
||||
min-height: 100px;
|
||||
grid-template-rows: auto;
|
||||
contain: inline-size;
|
||||
}
|
||||
.absolute {
|
||||
position: absolute;
|
||||
}
|
||||
.align-end {
|
||||
align-self: end;
|
||||
}
|
||||
.item {
|
||||
width: 100px;
|
||||
height: 50px;
|
||||
background-color: green;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<p>Test passes if there is a filled green square.</p>
|
||||
<grid>
|
||||
<div class="absolute item"></div>
|
||||
<div class="item align-end"></div>
|
||||
</grid>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,14 @@
|
|||
<!DOCTYPE html>
|
||||
<title>contain:inline-size on table</title>
|
||||
<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-contain/#contain-property">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-contain-3/#containment-inline-size">
|
||||
<link rel="match" href="../../../../expected/wpt-import/css/reference/ref-filled-green-100px-square.xht">
|
||||
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
|
||||
<!-- Note that size containment doesn't apply to tables:
|
||||
https://www.w3.org/TR/css-contain-1/#containment-size -->
|
||||
<div style="width:100px; height:100px; background:red;">
|
||||
<div style="display:table; contain:inline-size; width:fit-content; background:green;">
|
||||
<div style="width:100px; height:100px;"></div>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,23 @@
|
|||
<!doctype html>
|
||||
<html lang=en>
|
||||
<meta charset=utf-8>
|
||||
<title>CSS-contain test: layout containment on non-atomic inlines</title>
|
||||
<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net">
|
||||
<meta name=flags content="">
|
||||
<meta name=assert content="layout containment does not apply to non atomic inlines">
|
||||
<link rel="match" href="../../../../expected/wpt-import/css/reference/pass_if_pass_below.html">
|
||||
<link rel=help href="https://drafts.csswg.org/css-contain-1/#containment-layout">
|
||||
|
||||
<style>
|
||||
#pa {
|
||||
contain: layout;
|
||||
height: 100vh; /*If layout containment applies, the span becomes a BFC, height applies, and knocks SS off the page */
|
||||
}
|
||||
|
||||
#ss {
|
||||
vertical-align: bottom;
|
||||
}
|
||||
</style>
|
||||
|
||||
<p>Test passes if there is the word "PASS" below.</p>
|
||||
<div><span id="pa">PA</span><span id="ss">SS</span></div>
|
|
@ -0,0 +1,28 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Containment Test: Layout containment absolutely positioned descendants</title>
|
||||
<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-contain-1/#containment-layout">
|
||||
<link rel="match" href="../../../../expected/wpt-import/css/reference/ref-filled-green-100px-square.xht">
|
||||
<meta name=assert content="Layout containment makes an element to act as containing block for absolutely positioned descendants.">
|
||||
<style>
|
||||
#contain-layout {
|
||||
contain: layout;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background: red;
|
||||
}
|
||||
|
||||
#abspos {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
background: green;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
</style>
|
||||
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
|
||||
<div id="contain-layout">
|
||||
<div id="abspos"></div>
|
||||
</div>
|
|
@ -0,0 +1,30 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset=utf-8>
|
||||
<title>CSS Containment Test: Layout containment on table-caption</title>
|
||||
<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-contain-1/#containment-layout">
|
||||
<link rel="match" href="../../../../expected/wpt-import/css/reference/ref-filled-green-100px-square.xht">
|
||||
<meta name=assert content="Layout containment does apply to table-caption elements.">
|
||||
|
||||
<style>
|
||||
#table-caption {
|
||||
display: table-caption;
|
||||
contain: layout;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background: red;
|
||||
}
|
||||
#abspos {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
background: green;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
|
||||
<div id="table-caption">
|
||||
<div id="abspos"></div>
|
||||
</div>
|
|
@ -0,0 +1,20 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Containment Test: Layout containment stacking context</title>
|
||||
<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-contain-1/#containment-layout">
|
||||
<link rel="match" href="../../../../expected/wpt-import/css/reference/pass_if_pass_below.html">
|
||||
<meta name=assert content="Layout containment elements create a stacking context.">
|
||||
<style>
|
||||
div {
|
||||
contain: layout;
|
||||
background: white;
|
||||
}
|
||||
span {
|
||||
position: relative;
|
||||
z-index: -1;
|
||||
}
|
||||
</style>
|
||||
|
||||
<p>Test passes if there is the word "PASS" below.</p>
|
||||
<div><span>PASS</span></div>
|
|
@ -0,0 +1,22 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Containment Test: Layout containment stacking context</title>
|
||||
<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-contain-1/#containment-layout">
|
||||
<link rel="match" href="../../../../expected/wpt-import/css/reference/nothing.html">
|
||||
<meta name=assert content="Elements in which layout containment doesn't apply, do not create a stacking context.">
|
||||
<style>
|
||||
rt {
|
||||
display: ruby-text;
|
||||
contain: layout;
|
||||
background: white;
|
||||
overflow: hidden;
|
||||
}
|
||||
span {
|
||||
position: relative;
|
||||
z-index: -1;
|
||||
}
|
||||
</style>
|
||||
|
||||
<p>There should be nothing below.</p>
|
||||
<ruby><rt><span>FAIL</span></rt></ruby>
|
|
@ -0,0 +1,37 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Containment Test: Layout containment inside a fit-content element</title>
|
||||
<link rel="help" href="https://crbug.com/1268449">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-contain-1/#containment-layout">
|
||||
<link rel="match" href="../../../../expected/wpt-import/css/reference/ref-filled-green-100px-square.xht">
|
||||
<meta name=assert
|
||||
content="Layout containment inside a fit-content element should update size when the content is changed">
|
||||
<style>
|
||||
#contain-parent {
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
#contain-layout {
|
||||
contain: layout;
|
||||
background: green;
|
||||
}
|
||||
|
||||
#content {
|
||||
width: 50px;
|
||||
height: 100px;
|
||||
}
|
||||
</style>
|
||||
<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
|
||||
<div id="contain-parent">
|
||||
<div id="contain-layout">
|
||||
<div id="content"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
window.requestAnimationFrame(() => {
|
||||
document.body.offsetTop;
|
||||
document.getElementById('content').style.width = '100px';
|
||||
document.body.offsetTop;
|
||||
});
|
||||
</script>
|
|
@ -0,0 +1,42 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<meta charset=utf-8>
|
||||
<title>CSS Containment Test: Removing layout containment and contained positioned elements</title>
|
||||
<link rel="help" href="https://drafts.csswg.org/css-contain-1/#containment-layout">
|
||||
<link rel="match" href="../../../../expected/wpt-import/css/css-contain/reference/contain-layout-020-ref.html">
|
||||
<meta name=assert content="Removing layout containment relayouts contained positioned elements correctly.">
|
||||
|
||||
<style>
|
||||
#container {
|
||||
width: 300px;
|
||||
height: 300px;
|
||||
contain: layout;
|
||||
}
|
||||
.box {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background-color: green;
|
||||
}
|
||||
.fixed {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
.abspos {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="container">
|
||||
<div class="fixed box"></div>
|
||||
<div class="abspos box"></div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
requestAnimationFrame(() => {
|
||||
container.style.contain = "none";
|
||||
document.documentElement.removeAttribute("class");
|
||||
});
|
||||
</script>
|
|
@ -0,0 +1,68 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<meta charset="UTF-8">
|
||||
|
||||
<title>CSS Containment Test: 'contain: layout' applies to 'table-cell' elements</title>
|
||||
|
||||
<link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
|
||||
<link rel="help" href="https://www.w3.org/TR/css-contain-1/#containment-layout">
|
||||
<link rel="match" href="../../../../expected/wpt-import/css/css-contain/reference/contain-layout-cell-001-ref.html">
|
||||
|
||||
<meta content="In this test, the div#contain should act as the containing block for div#abs-pos ." name="assert">
|
||||
|
||||
<style>
|
||||
div#table
|
||||
{
|
||||
background-color: blue;
|
||||
border-spacing: 2px;
|
||||
display: table;
|
||||
height: 206px;
|
||||
table-layout: fixed;
|
||||
width: 206px;
|
||||
}
|
||||
|
||||
div.row
|
||||
{
|
||||
display: table-row;
|
||||
}
|
||||
|
||||
div.cell
|
||||
{
|
||||
background-color: white;
|
||||
display: table-cell;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
div#contain
|
||||
{
|
||||
contain: layout;
|
||||
}
|
||||
|
||||
span
|
||||
{
|
||||
background-color: red;
|
||||
color: yellow;
|
||||
font-family: monospace;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
div#abs-pos
|
||||
{
|
||||
background-color: green;
|
||||
color: white;
|
||||
font-family: monospace;
|
||||
left: 0px;
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<p>Test passes if there is the word PASS and if there is <strong>no red</strong>.
|
||||
|
||||
<div id="table">
|
||||
|
||||
<div class="row"><div class="cell"> </div><div class="cell"> </div></div>
|
||||
|
||||
<div class="row"><div class="cell"> </div><div class="cell" id="contain"><span>FAIL</span><div id="abs-pos">PASS</div></div></div>
|
||||
|
||||
</div>
|
|
@ -0,0 +1,62 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<meta charset="UTF-8">
|
||||
|
||||
<title>CSS Containment Test: 'contain: layout' applies to 'table-cell' elements</title>
|
||||
|
||||
<link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
|
||||
<link rel="help" href="https://www.w3.org/TR/css-contain-1/#containment-layout">
|
||||
<link rel="match" href="../../../../expected/wpt-import/css/css-contain/reference/contain-layout-cell-001-ref.html">
|
||||
|
||||
<meta content="In this test, the td#contain should act as the containing block for div#abs-pos ." name="assert">
|
||||
|
||||
<style>
|
||||
table
|
||||
{
|
||||
background-color: blue;
|
||||
border-spacing: 2px;
|
||||
height: 206px;
|
||||
table-layout: fixed;
|
||||
width: 206px;
|
||||
}
|
||||
|
||||
td
|
||||
{
|
||||
background-color: white;
|
||||
padding: 0px;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
td#contain
|
||||
{
|
||||
contain: layout;
|
||||
}
|
||||
|
||||
span
|
||||
{
|
||||
background-color: red;
|
||||
color: yellow;
|
||||
font-family: monospace;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
div#abs-pos
|
||||
{
|
||||
background-color: green;
|
||||
color: white;
|
||||
font-family: monospace;
|
||||
left: 0px;
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<p>Test passes if there is the word PASS and if there is <strong>no red</strong>.
|
||||
|
||||
<table>
|
||||
|
||||
<tr><td> <td>
|
||||
|
||||
<tr><td> <td id="contain"><span>FAIL</span><div id="abs-pos">PASS</div>
|
||||
|
||||
</table>
|
|
@ -0,0 +1,35 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Test: 'contain: layout' element should contain absolute position elements.</title>
|
||||
<link rel="author" title="Kyle Zentner" href="mailto:zentner.kyle@gmail.com">
|
||||
<link rel="author" title="Morgan Rae Reschenberg" href="mailto:mreschenberg@berkeley.edu">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-contain-1/#containment-layout">
|
||||
<link rel="match" href="../../../../expected/wpt-import/css/css-contain/contain-paint-containing-block-absolute-001-ref.html">
|
||||
<style>
|
||||
#a {
|
||||
contain: layout;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background: red;
|
||||
margin: 50px;
|
||||
}
|
||||
#b {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background: green;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="a">
|
||||
<div>
|
||||
<div id="b"></div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,37 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Test: 'contain: layout' with a vertical margin child. Margin collapse should not occur, and neither should overflow clipping.</title>
|
||||
<link rel="author" title="Kyle Zentner" href="mailto:zentner.kyle@gmail.com">
|
||||
<link rel="author" title="Morgan Rae Reschenberg" href="mailto:mreschenberg@berkeley.edu">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-contain/#containment-layout">
|
||||
<link rel="match" href="../../../../expected/wpt-import/css/css-contain/contain-layout-formatting-context-margin-001-ref.html">
|
||||
<style>
|
||||
#a {
|
||||
contain:layout;
|
||||
background: blue;
|
||||
margin: 10px;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
}
|
||||
#b {
|
||||
width: 50px;
|
||||
height: 40px;
|
||||
background: green;
|
||||
margin-top: 10px;
|
||||
}
|
||||
#c {
|
||||
background: lightblue;
|
||||
width: 50px;
|
||||
height: 10px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="a">
|
||||
<div id="b"></div>
|
||||
<div id="c"></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,53 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<meta charset="UTF-8">
|
||||
|
||||
<title>CSS Containment Test: 'contain: layout' and creation of an independent formating context: text no longer flowing around a float</title>
|
||||
|
||||
<link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
|
||||
<link rel="help" href="https://www.w3.org/TR/css-contain-1/#containment-layout">
|
||||
<link rel="match" href="../../../../expected/wpt-import/css/css-contain/reference/contain-layout-ifc-022-ref.html">
|
||||
|
||||
<meta content="This test checks that an element with 'contain: layout' will make such element create its own formatting context. In this test, the element with 'contain: layout' acts as if it has its own formatting context independent from div#floated-left element. In other words, the div#with-contain-layout is no longer required to flow its content around the div#floated-left element and current line boxes next to the float are no longer shortened to make room for the margin box of the float." name="assert">
|
||||
|
||||
<style>
|
||||
div
|
||||
{
|
||||
color: transparent;
|
||||
font-size: 16px;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
div#floated-left
|
||||
{
|
||||
background-color: blue;
|
||||
float: left;
|
||||
margin: 8px;
|
||||
width: 6em;
|
||||
}
|
||||
|
||||
div#with-contain-layout
|
||||
{
|
||||
background-color: orange;
|
||||
contain: layout;
|
||||
width: 12em;
|
||||
}
|
||||
</style>
|
||||
|
||||
<p>Test passes if the orange rectangle and blue rectangle do not overlap.
|
||||
|
||||
<!--
|
||||
|
||||
or
|
||||
|
||||
<p>Test passes if the orange rectangle and blue rectangle are side by side.
|
||||
|
||||
or
|
||||
|
||||
<p>Test passes if the orange rectangle and blue rectangle are apart from each other.
|
||||
|
||||
-->
|
||||
|
||||
<div id="floated-left">Some text in a blue rectangle.</div>
|
||||
|
||||
<div id="with-contain-layout">Some text in an orange rectangle. Some text in an orange rectangle. Some text in an orange rectangle.</div>
|
|
@ -0,0 +1,77 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Test: 'contain: layout' should have no effect on non-atomic inline
|
||||
(including its block part, if there's a block-in-inline split)</title>
|
||||
<link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-contain/#containment-layout">
|
||||
<link rel="match" href="../../../../expected/wpt-import/css/css-contain/contain-layout-ignored-cases-ib-split-001-ref.html">
|
||||
<style>
|
||||
.abspos-box {
|
||||
position: absolute;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
}
|
||||
|
||||
/* The boxes should stack in the order that I've listed their CSS classes
|
||||
here. The class names' first word (outside/before/inside/after) refers
|
||||
to the boxes' DOM position, and "background"/"midground"/"foreground"
|
||||
refers to their z-index values. */
|
||||
|
||||
.before-IB-background {
|
||||
background: darkmagenta;
|
||||
z-index: -1;
|
||||
top: 50px;
|
||||
left: 50px;
|
||||
}
|
||||
.after-IB-background {
|
||||
background: magenta;
|
||||
z-index: -1;
|
||||
top: 70px;
|
||||
left: 70px;
|
||||
}
|
||||
.outside-span-midground {
|
||||
background: darkkhaki;
|
||||
top: 90px;
|
||||
left: 90px;
|
||||
}
|
||||
.inside-IB-midground {
|
||||
background: khaki;
|
||||
top: 110px;
|
||||
left: 110px;
|
||||
}
|
||||
.before-IB-foreground {
|
||||
background: darkcyan;
|
||||
z-index: 1;
|
||||
top: 130px;
|
||||
left: 130px;
|
||||
}
|
||||
.after-IB-foreground {
|
||||
background: cyan;
|
||||
z-index: 1;
|
||||
top: 150px;
|
||||
left: 150px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- The expectation here is that 'abspos-box' elements will all interact in
|
||||
the same top-level stacking context. That means the box ordering should
|
||||
be (back to front): darkmagenta/magenta/darkkhaki/khaki/darkcyan/cyan,
|
||||
with the boxes stacked (visually) from top-left to bottom-right. -->
|
||||
|
||||
<div class="abspos-box outside-span-midground"></div>
|
||||
|
||||
<span style="contain: layout">
|
||||
<div class="abspos-box before-IB-background"></div>
|
||||
<div class="abspos-box before-IB-foreground"></div>
|
||||
<!-- This unstyled div crates the IB split: -->
|
||||
<div>
|
||||
<div class="abspos-box inside-IB-midground"></div>
|
||||
</div>
|
||||
<div class="abspos-box after-IB-background"></div>
|
||||
<div class="abspos-box after-IB-foreground"></div>
|
||||
</span>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,36 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Test: 'contain: layout' element should not contain absolute/fixed position elements when no principal box is generated.</title>
|
||||
<link rel="author" title="Yusuf Sermet" href="mailto:ysermet@mozilla.com">
|
||||
<link rel="author" title="Morgan Rae Reschenberg" href="mailto:mreschenberg@berkeley.edu">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-contain-1/#containment-layout">
|
||||
<link rel="match" href="../../../../expected/wpt-import/css/css-contain/contain-layout-ignored-cases-no-principal-box-002-ref.html">
|
||||
<style>
|
||||
#a {
|
||||
contain: layout;
|
||||
display: contents;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background: red;
|
||||
margin: 50px;
|
||||
}
|
||||
#b {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background: green;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="a">
|
||||
<div>
|
||||
<div id="b"></div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,36 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Test: 'contain: layout' element should not contain absolute/fixed position elements when no principal box is generated.</title>
|
||||
<link rel="author" title="Yusuf Sermet" href="mailto:ysermet@mozilla.com">
|
||||
<link rel="author" title="Morgan Rae Reschenberg" href="mailto:mreschenberg@berkeley.edu">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-contain-1/#containment-layout">
|
||||
<link rel="match" href="../../../../expected/wpt-import/css/css-contain/contain-layout-ignored-cases-no-principal-box-003-ref.html">
|
||||
<style>
|
||||
#a {
|
||||
contain: layout;
|
||||
display: contents;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background: red;
|
||||
margin: 50px;
|
||||
}
|
||||
#b {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background: green;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="a">
|
||||
<div>
|
||||
<div id="b"></div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,19 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Containment Test: Layout containment independent formatting context</title>
|
||||
<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-contain-1/#containment-layout">
|
||||
<link rel="match" href="../../../../expected/wpt-import/css/css-contain/reference/contain-paint-independent-formatting-context-001-ref.html">
|
||||
<meta name=assert content="Layout containment elements establish an independent formatting context. The test checks that this feature of layout containment applies to blocks.">
|
||||
<style>
|
||||
.wrapper {
|
||||
border: solid thick;
|
||||
margin: 1em;
|
||||
}
|
||||
</style>
|
||||
<p>Test passes if it has the same output than the reference.</p>
|
||||
<div class="wrapper">
|
||||
<div style="margin: 1em 0; contain: layout;">
|
||||
<div style="margin: 1em 0;">This text should have 2em top and bottom margins (margins do not collapse).</div>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,19 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Containment Test: Layout containment independent formatting context</title>
|
||||
<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-contain-1/#containment-layout">
|
||||
<link rel="match" href="../../../../expected/wpt-import/css/css-contain/reference/contain-paint-independent-formatting-context-001-ref.html">
|
||||
<meta name=assert content="Layout containment elements establish an independent formatting context. The test checks that this feature of layout containment applies to inline blocks.">
|
||||
<style>
|
||||
.wrapper {
|
||||
border: solid thick;
|
||||
margin: 1em;
|
||||
}
|
||||
</style>
|
||||
<p>Test passes if it has the same output than the reference.</p>
|
||||
<div class="wrapper">
|
||||
<span style="display: inline-block; margin: 1em 0; vertical-align: top; contain: layout;">
|
||||
<div style="margin: 1em 0;">This text should have 2em top and bottom margins (margins do not collapse).</div>
|
||||
</span>
|
||||
</div>
|
|
@ -0,0 +1,46 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<meta charset="UTF-8">
|
||||
|
||||
<title>CSS Containment Test: 'contain: layout' and ink overflow</title>
|
||||
|
||||
<link rel="author" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/">
|
||||
<link rel="help" href="https://www.w3.org/TR/css-overflow-3/#ink-overflow">
|
||||
<link rel="help" href="https://www.w3.org/TR/css-contain-1/#containment-layout">
|
||||
<link rel="match" href="../../../../expected/wpt-import/css/css-contain/reference/contain-layout-ink-overflow-014-ref.html">
|
||||
|
||||
<meta content="This test checks that when the contents of an element with 'contain: layout' overflows, its contents must be treated as ink overflow. In this test, the content overflows the div#inner. If such content was treated as 'overflow: visible', then the div#outer would 'pick up' such content and would make it reachable and accessible via its own generated scrollbar. But the overflowed content must be treated as ink overflow and is therefore treated as a graphical effect that is beyond the scrolling mechanism and outside the scrolling mechanism." name="assert">
|
||||
|
||||
<style>
|
||||
div#outer
|
||||
{
|
||||
font-family: monospace;
|
||||
font-size: 100px;
|
||||
height: 2.8ch;
|
||||
line-height: 1.5; /* computes to 150px */
|
||||
width: 4ch;
|
||||
|
||||
overflow: scroll;
|
||||
}
|
||||
|
||||
div#inner
|
||||
{
|
||||
color: red;
|
||||
contain: layout;
|
||||
height: 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
<!--
|
||||
|
||||
150px : height of 1 line box
|
||||
|
||||
-->
|
||||
|
||||
<body onload="document.getElementById('outer').scrollLeft = 250; document.getElementById('outer').scrollTop = 150;">
|
||||
|
||||
<p>Test passes if there is no red.
|
||||
|
||||
<div id="outer">
|
||||
<div id="inner"> <br>FAIL</div>
|
||||
</div>
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue