Move 'contain: size' handling for replaced content

For Legacy layout, hoist the check for size containment out to
ComputeIntrinsicSizingInfoForReplacedContent, since this is the "real"
entrypoint.
For NG, put the check in NGLayoutInputNode::IntrinsicSize.

This also makes ComputeIntrinsicSizingInfo slightly more focused on
computing the intrinsic dimensions, and avoids calling it at all if
the box is subject to size containment.

Bug: 917018
Change-Id: I0e3fdc48e9c5a104cadaa253cb7cef23fdc42ece
Reviewed-on: https://chromium-review.googlesource.com/c/1386849
Commit-Queue: Fredrik Söderquist <fs@opera.com>
Reviewed-by: Morten Stenshorne <mstensho@chromium.org>
Reviewed-by: Aleks Totic <atotic@chromium.org>
Reviewed-by: Manuel Rego <rego@igalia.com>
Cr-Commit-Position: refs/heads/master@{#618496}
diff --git a/third_party/blink/renderer/core/layout/layout_embedded_object.cc b/third_party/blink/renderer/core/layout/layout_embedded_object.cc
index 6a7b279..a6aef27e 100644
--- a/third_party/blink/renderer/core/layout/layout_embedded_object.cc
+++ b/third_party/blink/renderer/core/layout/layout_embedded_object.cc
@@ -111,6 +111,7 @@
 
 void LayoutEmbeddedObject::ComputeIntrinsicSizingInfo(
     IntrinsicSizingInfo& intrinsic_sizing_info) const {
+  DCHECK(!ShouldApplySizeContainment());
   FrameView* frame_view = ChildFrameView();
   if (frame_view && frame_view->GetIntrinsicSizingInfo(intrinsic_sizing_info)) {
     // Handle zoom & vertical writing modes here, as the embedded document
diff --git a/third_party/blink/renderer/core/layout/layout_image.cc b/third_party/blink/renderer/core/layout/layout_image.cc
index a948c5f..44923da 100644
--- a/third_party/blink/renderer/core/layout/layout_image.cc
+++ b/third_party/blink/renderer/core/layout/layout_image.cc
@@ -413,6 +413,7 @@
 
 void LayoutImage::ComputeIntrinsicSizingInfo(
     IntrinsicSizingInfo& intrinsic_sizing_info) const {
+  DCHECK(!ShouldApplySizeContainment());
   if (!OverrideIntrinsicSizingInfo(intrinsic_sizing_info)) {
     if (SVGImage* svg_image = EmbeddedSVGImage()) {
       svg_image->GetIntrinsicSizingInfo(intrinsic_sizing_info);
diff --git a/third_party/blink/renderer/core/layout/layout_replaced.cc b/third_party/blink/renderer/core/layout/layout_replaced.cc
index 2c8bb3a..c8767ffe 100644
--- a/third_party/blink/renderer/core/layout/layout_replaced.cc
+++ b/third_party/blink/renderer/core/layout/layout_replaced.cc
@@ -155,6 +155,11 @@
 
 void LayoutReplaced::ComputeIntrinsicSizingInfoForReplacedContent(
     IntrinsicSizingInfo& intrinsic_sizing_info) const {
+  if (ShouldApplySizeContainment()) {
+    intrinsic_sizing_info.size = FloatSize();
+    return;
+  }
+
   ComputeIntrinsicSizingInfo(intrinsic_sizing_info);
 
   // Update our intrinsic size to match what was computed, so that
@@ -648,11 +653,7 @@
 
 void LayoutReplaced::ComputeIntrinsicSizingInfo(
     IntrinsicSizingInfo& intrinsic_sizing_info) const {
-  if (ShouldApplySizeContainment()) {
-    intrinsic_sizing_info.size = FloatSize();
-    return;
-  }
-
+  DCHECK(!ShouldApplySizeContainment());
   intrinsic_sizing_info.size = FloatSize(IntrinsicLogicalWidth().ToFloat(),
                                          IntrinsicLogicalHeight().ToFloat());
 
diff --git a/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.cc b/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.cc
index a52471a..a007811 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_layout_input_node.cc
@@ -93,6 +93,13 @@
   *default_intrinsic_size =
       NGLogicalSize(box_intrinsic_size.Width(), box_intrinsic_size.Height());
 
+  if (ShouldApplySizeContainment()) {
+    *computed_inline_size = LayoutUnit();
+    *computed_block_size = LayoutUnit();
+    *aspect_ratio = NGLogicalSize(LayoutUnit(), LayoutUnit());
+    return;
+  }
+
   IntrinsicSizingInfo legacy_sizing_info;
 
   ToLayoutReplaced(box_)->ComputeIntrinsicSizingInfo(legacy_sizing_info);
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_root.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_root.cc
index b1f6d6e..20f09c4 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_root.cc
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_root.cc
@@ -95,6 +95,7 @@
 
 void LayoutSVGRoot::ComputeIntrinsicSizingInfo(
     IntrinsicSizingInfo& intrinsic_sizing_info) const {
+  DCHECK(!ShouldApplySizeContainment());
   UnscaledIntrinsicSizingInfo(intrinsic_sizing_info);
 
   intrinsic_sizing_info.size.Scale(StyleRef().EffectiveZoom());
diff --git a/third_party/blink/web_tests/external/wpt/css/css-contain/contain-size-replaced-001.html b/third_party/blink/web_tests/external/wpt/css/css-contain/contain-size-replaced-001.html
new file mode 100644
index 0000000..b0dba02
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-contain/contain-size-replaced-001.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Containment Test: Size containment replaced elements intrinsic size</title>
+<link rel="help" href="https://drafts.csswg.org/css-contain-1/#containment-size">
+<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+<meta name=assert content="This test checks that intrinsic size of replaced elements with 'contain: size' is zero.">
+<style>
+object {
+  background: green;
+  padding: 50px;
+  contain: size;
+}
+</style>
+
+<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+<object data="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='100' height='100'><rect fill='red' width='100' height='100'/></svg>">
+</object>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-contain/contain-size-replaced-002.html b/third_party/blink/web_tests/external/wpt/css/css-contain/contain-size-replaced-002.html
new file mode 100644
index 0000000..20e4c8a1
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-contain/contain-size-replaced-002.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Containment Test: Size containment replaced elements intrinsic size</title>
+<link rel="help" href="https://drafts.csswg.org/css-contain-1/#containment-size">
+<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+<meta name=assert content="This test checks that intrinsic size of replaced elements with 'contain: size' is zero.">
+<style>
+svg {
+  background: green;
+  padding: 50px 0;
+  contain: size;
+}
+</style>
+
+<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+<svg width="100" viewBox="0 0 50 50">
+  <rect fill="red" width="50" height="50"/>
+</svg>