intrinsic size keywords don't work for heights
authorsvillar@igalia.com <svillar@igalia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 24 Jun 2015 13:36:00 +0000 (13:36 +0000)
committersvillar@igalia.com <svillar@igalia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 24 Jun 2015 13:36:00 +0000 (13:36 +0000)
https://bugs.webkit.org/show_bug.cgi?id=113610

Reviewed by Darin Adler.

Source/WebCore:

Based on Blink's r148314 & r150355 by <cbiesinger@chromium.org>.

Adds intrinsic values support to heigh & min/max-height. This involves the
following changes:
- RenderBox needs to pass the content height through to computeLogicalHeight and
related functions, which needs it to resolve max-content, et. al.
- Make the callers pass the content height to this function. Some callers pass
logicalHeight() (adjusted for border/padding) which works because if
logicalHeight is not the content height, then it is the height we ended up using,
so the constrain* functions will just constrain to that value again.
- Parsing code needs to be adjusted to support intrinsic values for heights.

Tests: fast/css-intrinsic-dimensions/height-css-tables-collapsed.html
       fast/css-intrinsic-dimensions/height-css-tables.html
       fast/css-intrinsic-dimensions/height-flexbox.html
       fast/css-intrinsic-dimensions/height-positioned-replaced.html
       fast/css-intrinsic-dimensions/height-positioned.html
       fast/css-intrinsic-dimensions/height-replaced.html
       fast/css-intrinsic-dimensions/height-tables-collapsed.html
       fast/css-intrinsic-dimensions/height-tables.html
       fast/css-intrinsic-dimensions/height.html

* css/CSSParser.cpp:
(WebCore::CSSParser::isValidSize): Refactored from validateWidth and
validateHeight.
(WebCore::CSSParser::parseValue):
(WebCore::CSSParser::validateWidth): Deleted.
(WebCore::CSSParser::validateHeight): Deleted.
* css/CSSParser.h:
* platform/Length.h:
(WebCore::Length::isFillAvailable):
(WebCore::Length::isFitContent):
* rendering/RenderBox.cpp:
(WebCore::RenderBox::constrainLogicalHeightByMinMax):
(WebCore::RenderBox::constrainContentBoxLogicalHeightByMinMax):
(WebCore::RenderBox::computeLogicalHeight):
(WebCore::RenderBox::computeLogicalHeightUsing):
(WebCore::RenderBox::computeContentLogicalHeight):
(WebCore::RenderBox::computeIntrinsicLogicalContentHeightUsing):
(WebCore::RenderBox::computeContentAndScrollbarLogicalHeightUsing):
(WebCore::RenderBox::computePercentageLogicalHeight):
(WebCore::RenderBox::computeReplacedLogicalHeightUsing):
(WebCore::RenderBox::availableLogicalHeight):
(WebCore::RenderBox::availableLogicalHeightUsing):
(WebCore::RenderBox::computePositionedLogicalHeight):
(WebCore::RenderBox::computePositionedLogicalHeightUsing):
* rendering/RenderBox.h:
* rendering/RenderFlexibleBox.cpp:
(WebCore::RenderFlexibleBox::computeMainAxisExtentForChild):
(WebCore::RenderFlexibleBox::applyStretchAlignmentToChild):
* rendering/RenderFlowThread.cpp:
(WebCore::RenderFlowThread::addForcedRegionBreak):
* rendering/RenderGrid.cpp:
(WebCore::RenderGrid::computeUsedBreadthOfSpecifiedLength):
(WebCore::RenderGrid::applyStretchAlignmentToChildIfNeeded):
* rendering/RenderMultiColumnSet.cpp:
(WebCore::RenderMultiColumnSet::calculateMaxColumnHeight):
* rendering/RenderReplaced.cpp:
(WebCore::RenderReplaced::hasReplacedLogicalHeight):
* rendering/RenderTable.cpp:
(WebCore::RenderTable::convertStyleLogicalHeightToComputedHeight):
(WebCore::RenderTable::layout):

LayoutTests:

Based on Blink's r148314 by <cbiesinger@chromium.org>.

* fast/css-intrinsic-dimensions/height-css-tables-collapsed-expected.html: Added.
* fast/css-intrinsic-dimensions/height-css-tables-collapsed.html: Added.
* fast/css-intrinsic-dimensions/height-css-tables-expected.html: Added.
* fast/css-intrinsic-dimensions/height-css-tables.html: Added.
* fast/css-intrinsic-dimensions/height-expected.html: Added.
* fast/css-intrinsic-dimensions/height-flexbox-expected.html: Added.
* fast/css-intrinsic-dimensions/height-flexbox.html: Added.
* fast/css-intrinsic-dimensions/height-positioned-expected.html: Added.
* fast/css-intrinsic-dimensions/height-positioned-replaced-expected.html: Added.
* fast/css-intrinsic-dimensions/height-positioned-replaced.html: Added.
* fast/css-intrinsic-dimensions/height-positioned.html: Added.
* fast/css-intrinsic-dimensions/height-property-value-expected.txt:
* fast/css-intrinsic-dimensions/height-property-value.html:
* fast/css-intrinsic-dimensions/height-property-value.html.orig: Copied from LayoutTests/fast/css-intrinsic-dimensions/height-property-value.html.
* fast/css-intrinsic-dimensions/height-replaced-expected.html: Added.
* fast/css-intrinsic-dimensions/height-replaced.html: Added.
* fast/css-intrinsic-dimensions/height-tables-collapsed-expected.html: Added.
* fast/css-intrinsic-dimensions/height-tables-collapsed.html: Added.
* fast/css-intrinsic-dimensions/height-tables-expected.html: Added.
* fast/css-intrinsic-dimensions/height-tables.html: Added.
* fast/css-intrinsic-dimensions/height.html: Added.
* fast/css-intrinsic-dimensions/resources/height-keyword-classes.css: Added.
(.min-content):
(.max-content):
(.fill-available):
(.fit-content):
(.max-height-min-content):
(.max-height-max-content):
(.max-height-fill-available):
(.max-height-fit-content):
(.min-height-min-content):
(.min-height-max-content):
(.min-height-fill-available):
(.min-height-fit-content):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@185908 268f45cc-cd09-0410-ab3c-d52691b4dbfc

35 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/css-intrinsic-dimensions/height-css-tables-collapsed-expected.html [new file with mode: 0644]
LayoutTests/fast/css-intrinsic-dimensions/height-css-tables-collapsed.html [new file with mode: 0644]
LayoutTests/fast/css-intrinsic-dimensions/height-css-tables-expected.html [new file with mode: 0644]
LayoutTests/fast/css-intrinsic-dimensions/height-css-tables.html [new file with mode: 0644]
LayoutTests/fast/css-intrinsic-dimensions/height-expected.html [new file with mode: 0644]
LayoutTests/fast/css-intrinsic-dimensions/height-flexbox-expected.html [new file with mode: 0644]
LayoutTests/fast/css-intrinsic-dimensions/height-flexbox.html [new file with mode: 0644]
LayoutTests/fast/css-intrinsic-dimensions/height-positioned-expected.html [new file with mode: 0644]
LayoutTests/fast/css-intrinsic-dimensions/height-positioned-replaced-expected.html [new file with mode: 0644]
LayoutTests/fast/css-intrinsic-dimensions/height-positioned-replaced.html [new file with mode: 0644]
LayoutTests/fast/css-intrinsic-dimensions/height-positioned.html [new file with mode: 0644]
LayoutTests/fast/css-intrinsic-dimensions/height-property-value-expected.txt
LayoutTests/fast/css-intrinsic-dimensions/height-property-value.html
LayoutTests/fast/css-intrinsic-dimensions/height-property-value.html.orig [new file with mode: 0644]
LayoutTests/fast/css-intrinsic-dimensions/height-replaced-expected.html [new file with mode: 0644]
LayoutTests/fast/css-intrinsic-dimensions/height-replaced.html [new file with mode: 0644]
LayoutTests/fast/css-intrinsic-dimensions/height-tables-collapsed-expected.html [new file with mode: 0644]
LayoutTests/fast/css-intrinsic-dimensions/height-tables-collapsed.html [new file with mode: 0644]
LayoutTests/fast/css-intrinsic-dimensions/height-tables-expected.html [new file with mode: 0644]
LayoutTests/fast/css-intrinsic-dimensions/height-tables.html [new file with mode: 0644]
LayoutTests/fast/css-intrinsic-dimensions/height.html [new file with mode: 0644]
LayoutTests/fast/css-intrinsic-dimensions/resources/height-keyword-classes.css [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/css/CSSParser.cpp
Source/WebCore/css/CSSParser.h
Source/WebCore/platform/Length.h
Source/WebCore/rendering/RenderBox.cpp
Source/WebCore/rendering/RenderBox.h
Source/WebCore/rendering/RenderFlexibleBox.cpp
Source/WebCore/rendering/RenderFlowThread.cpp
Source/WebCore/rendering/RenderGrid.cpp
Source/WebCore/rendering/RenderMultiColumnSet.cpp
Source/WebCore/rendering/RenderReplaced.cpp
Source/WebCore/rendering/RenderTable.cpp

index 9b7a03f..095a1a4 100644 (file)
@@ -1,3 +1,47 @@
+2015-06-11  Sergio Villar Senin  <svillar@igalia.com>
+
+        intrinsic size keywords don't work for heights
+        https://bugs.webkit.org/show_bug.cgi?id=113610
+
+        Reviewed by Darin Adler.
+
+        Based on Blink's r148314 by <cbiesinger@chromium.org>.
+
+        * fast/css-intrinsic-dimensions/height-css-tables-collapsed-expected.html: Added.
+        * fast/css-intrinsic-dimensions/height-css-tables-collapsed.html: Added.
+        * fast/css-intrinsic-dimensions/height-css-tables-expected.html: Added.
+        * fast/css-intrinsic-dimensions/height-css-tables.html: Added.
+        * fast/css-intrinsic-dimensions/height-expected.html: Added.
+        * fast/css-intrinsic-dimensions/height-flexbox-expected.html: Added.
+        * fast/css-intrinsic-dimensions/height-flexbox.html: Added.
+        * fast/css-intrinsic-dimensions/height-positioned-expected.html: Added.
+        * fast/css-intrinsic-dimensions/height-positioned-replaced-expected.html: Added.
+        * fast/css-intrinsic-dimensions/height-positioned-replaced.html: Added.
+        * fast/css-intrinsic-dimensions/height-positioned.html: Added.
+        * fast/css-intrinsic-dimensions/height-property-value-expected.txt:
+        * fast/css-intrinsic-dimensions/height-property-value.html:
+        * fast/css-intrinsic-dimensions/height-property-value.html.orig: Copied from LayoutTests/fast/css-intrinsic-dimensions/height-property-value.html.
+        * fast/css-intrinsic-dimensions/height-replaced-expected.html: Added.
+        * fast/css-intrinsic-dimensions/height-replaced.html: Added.
+        * fast/css-intrinsic-dimensions/height-tables-collapsed-expected.html: Added.
+        * fast/css-intrinsic-dimensions/height-tables-collapsed.html: Added.
+        * fast/css-intrinsic-dimensions/height-tables-expected.html: Added.
+        * fast/css-intrinsic-dimensions/height-tables.html: Added.
+        * fast/css-intrinsic-dimensions/height.html: Added.
+        * fast/css-intrinsic-dimensions/resources/height-keyword-classes.css: Added.
+        (.min-content):
+        (.max-content):
+        (.fill-available):
+        (.fit-content):
+        (.max-height-min-content):
+        (.max-height-max-content):
+        (.max-height-fill-available):
+        (.max-height-fit-content):
+        (.min-height-min-content):
+        (.min-height-max-content):
+        (.min-height-fill-available):
+        (.min-height-fit-content):
+
 2015-06-23  Myles C. Maxfield  <mmaxfield@apple.com>
 
         [OS X] Rebaseline fast/text/font-weight{,-zh}.html for El Capitan
diff --git a/LayoutTests/fast/css-intrinsic-dimensions/height-css-tables-collapsed-expected.html b/LayoutTests/fast/css-intrinsic-dimensions/height-css-tables-collapsed-expected.html
new file mode 100644 (file)
index 0000000..d584a60
--- /dev/null
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+
+<style>
+  .item { height: 50px; width: 50px; border: 1px solid blue; }
+
+  .container { height: 100px; border: 5px solid pink; }
+  .table { border: 2px solid red; display: table; border-collapse: collapse; border-spacing: 2px; }
+  .td { border: 2px solid green; display: table-cell; }
+</style>
+
+<div class="table">
+  <div class="td">
+    <div class="item"></div>
+  </div>
+</div>
+
+<table>
+  <div class="td">
+    <div class="item"></div>
+  </div>
+</div>
+
+<div class="container">
+  <div class="table" style="height: 100%; box-sizing: border-box;">
+    <div class="td">
+      <div class="item"></div>
+    </div>
+  </div>
+</div>
+
+
+<div class="table container" style="display: block; float: left; height: 98px; border: 2px solid green;">
+  <div class="item"></div>
+</div>
diff --git a/LayoutTests/fast/css-intrinsic-dimensions/height-css-tables-collapsed.html b/LayoutTests/fast/css-intrinsic-dimensions/height-css-tables-collapsed.html
new file mode 100644 (file)
index 0000000..72ab8f2
--- /dev/null
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+
+<style>
+  @import "resources/height-keyword-classes.css";
+
+  .small { height: 1px; }
+  .big { height: 300px; }
+  .item { height: 50px; width: 50px; border: 1px solid blue; }
+
+  .container { height: 100px; border: 5px solid pink; }
+  .table { border: 2px solid red; display: table; border-collapse: collapse; border-spacing: 2px; }
+  .td { border: 2px solid green; display: table-cell; }
+</style>
+
+<div class="table big max-height-min-content">
+  <div class="td">
+    <div class="item"></div>
+  </div>
+</div>
+
+<table>
+  <div class="td small min-height-min-content">
+    <div class="item"></div>
+  </div>
+</div>
+
+<div class="container">
+  <div class="table small min-height-fill-available">
+    <div class="td">
+      <div class="item"></div>
+    </div>
+  </div>
+</div>
+
+
+<div class="table container">
+  <div class="td small min-height-fill-available">
+    <div class="item"></div>
+  </div>
+</div>
diff --git a/LayoutTests/fast/css-intrinsic-dimensions/height-css-tables-expected.html b/LayoutTests/fast/css-intrinsic-dimensions/height-css-tables-expected.html
new file mode 100644 (file)
index 0000000..5f4d437
--- /dev/null
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+
+<style>
+  .item { height: 50px; width: 50px; border: 1px solid blue; }
+
+  .container { height: 100px; border: 5px solid pink; }
+  .table { border: 2px solid red; display: table; border-spacing: 2px; }
+  .td { border: 2px solid green; display: table-cell; }
+</style>
+
+<div class="table">
+  <div class="td">
+    <div class="item"></div>
+  </div>
+</div>
+
+<table>
+  <div class="td">
+    <div class="item"></div>
+  </div>
+</div>
+
+<div class="container">
+  <div class="table" style="height: 100%; box-sizing: border-box;">
+    <div class="td">
+      <div class="item"></div>
+    </div>
+  </div>
+</div>
+
+
+<div class="table container" style="display: block; float: left; height: 98px;">
+  <div class="td" style="height: 90px;" style="display: block;">
+    <div class="item"></div>
+  </div>
+</div>
diff --git a/LayoutTests/fast/css-intrinsic-dimensions/height-css-tables.html b/LayoutTests/fast/css-intrinsic-dimensions/height-css-tables.html
new file mode 100644 (file)
index 0000000..a37d074
--- /dev/null
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+
+<style>
+  @import "resources/height-keyword-classes.css";
+
+  .small { height: 1px; }
+  .big { height: 300px; }
+  .item { height: 50px; width: 50px; border: 1px solid blue; }
+
+  .container { height: 100px; border: 5px solid pink; }
+  .table { border: 2px solid red; display: table; border-spacing: 2px; }
+  .td { border: 2px solid green; display: table-cell; }
+</style>
+
+<div class="table big max-height-min-content">
+  <div class="td">
+    <div class="item"></div>
+  </div>
+</div>
+
+<table>
+  <div class="td small min-height-min-content">
+    <div class="item"></div>
+  </div>
+</div>
+
+<div class="container">
+  <div class="table small min-height-fill-available">
+    <div class="td">
+      <div class="item"></div>
+    </div>
+  </div>
+</div>
+
+
+<div class="table container">
+  <div class="td small min-height-fill-available">
+    <div class="item"></div>
+  </div>
+</div>
diff --git a/LayoutTests/fast/css-intrinsic-dimensions/height-expected.html b/LayoutTests/fast/css-intrinsic-dimensions/height-expected.html
new file mode 100644 (file)
index 0000000..ad7a977
--- /dev/null
@@ -0,0 +1,80 @@
+<!DOCTYPE html>
+<style>
+    body * {
+        border: 2px solid red;
+        padding: 5px;
+        clear: both;
+    }
+
+    .container {
+        height: 300px;
+        border-color: blue;
+
+        display: inline-block;
+        width: 100px;
+    }
+
+    .fill-available {
+      height: 100%;
+      box-sizing: border-box;
+    }
+</style>
+<div class="container">
+  <div>
+    height: min-content<br>on this box.
+  </div>
+
+  <div>
+    height: max-content<br>on this box.
+  </div>
+
+  <div>
+    height: fit-content<br>on this box.
+  </div>
+</div>
+
+<div class="container">
+  <div class="fill-available">
+    height: fill-available<br> on this box.
+  </div>
+</div>
+
+<div class="container">
+  <div>
+    min-height: min-content<br>on this box.
+  </div>
+
+  <div>
+    min-height: max-content<br>on this box.
+  </div>
+
+  <div>
+    min-height: fit-content<br>on this box.
+  </div>
+</div>
+
+<div class="container">
+  <div class="fill-available">
+    min-height: fill-available<br> on this box.
+  </div>
+</div>
+
+<div class="container">
+  <div>
+    max-height: min-content<br>on this box.
+  </div>
+
+  <div>
+    max-height: max-content<br>on this box.
+  </div>
+
+  <div>
+    max-height: fit-content<br>on this box.
+  </div>
+</div>
+
+<div class="container">
+  <div class="fill-available">
+    max-height: fill-available<br> on this box.
+  </div>
+</div>
diff --git a/LayoutTests/fast/css-intrinsic-dimensions/height-flexbox-expected.html b/LayoutTests/fast/css-intrinsic-dimensions/height-flexbox-expected.html
new file mode 100644 (file)
index 0000000..384e1a1
--- /dev/null
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<style>
+  .container {
+    border: 2px solid blue;
+  }
+
+  .item {
+    border: 2px solid red;
+  }
+</style>
+
+<div class="container">
+  <div class="item">
+    Line 1<br>
+    Line 2
+  </div>
+</div>
+
+<div class="container">
+  <div class="item">
+    Line 1
+  </div>
+  <div class="item">
+    Line 1<br>
+    Line 2
+  </div>
+</div>
diff --git a/LayoutTests/fast/css-intrinsic-dimensions/height-flexbox.html b/LayoutTests/fast/css-intrinsic-dimensions/height-flexbox.html
new file mode 100644 (file)
index 0000000..2d4675c
--- /dev/null
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<style>
+  @import "resources/height-keyword-classes.css";
+
+  .container {
+    display: -webkit-flex;
+    display: flex;
+    -webkit-flex-direction: column;
+    flex-direction: column;
+
+    border: 2px solid blue;
+  }
+
+  .item {
+    height: 1px;
+    border: 2px solid red;
+    -webkit-flex: 1;
+    flex: 1;
+  }
+</style>
+
+<div class="container">
+  <div class="item min-height-min-content">
+    Line 1<br>
+    Line 2
+  </div>
+</div>
+
+<div class="container">
+  <div class="item min-height-min-content">
+    Line 1
+  </div>
+  <div class="item min-height-min-content">
+    Line 1<br>
+    Line 2
+  </div>
+</div>
diff --git a/LayoutTests/fast/css-intrinsic-dimensions/height-positioned-expected.html b/LayoutTests/fast/css-intrinsic-dimensions/height-positioned-expected.html
new file mode 100644 (file)
index 0000000..cb861f5
--- /dev/null
@@ -0,0 +1,120 @@
+<!DOCTYPE html>
+<!--
+All divs here should shrinkwrap to fit their content, except for fill-available
+-->
+<style>
+    body * {
+      border: 2px solid red;
+      padding: 5px;
+      clear: both;
+    }
+
+    .container {
+      height: 400px;
+      border-color: blue;
+
+      display: inline-block;
+      width: 100px;
+    }
+
+    .position-container {
+      border-color: green;
+      position: relative;
+      height: 100px;
+    }
+
+    .position-container > * {
+      position: absolute;
+    }
+
+    .f-a-container {
+      height: 100%;
+      box-sizing: border-box;
+    }
+
+    .fill-available {
+      height: 386px;
+      box-sizing: border-box;
+    }
+</style>
+<div class="container">
+  <div class="position-container">
+    <div>
+      height: min-content<br>on this box.
+    </div>
+  </div>
+  <div class="position-container">
+    <div>
+      height: max-content<br>on this box.
+    </div>
+  </div>
+  <div class="position-container">
+    <div>
+      height: fit-content<br>on this box.
+    </div>
+  </div>
+</div>
+
+<div class="container">
+  <div class="position-container f-a-container">
+    <div class="fill-available">
+      height: fill-available<br> on this box.
+    </div>
+  </div>
+</div>
+
+<div class="container">
+  <div class="position-container">
+    <div>
+      min-height: min-content<br>on this box.
+    </div>
+
+  </div>
+  <div class="position-container">
+    <div>
+      min-height: max-content<br>on this box.
+    </div>
+
+  </div>
+  <div class="position-container">
+    <div>
+      min-height: fit-content<br>on this box.
+    </div>
+  </div>
+</div>
+
+<div class="container">
+  <div class="position-container f-a-container">
+    <div class="fill-available">
+      min-height: fill-available<br> on this box.
+    </div>
+  </div>
+</div>
+
+<div class="container">
+  <div class="position-container">
+    <div>
+      max-height: min-content<br>on this box.
+    </div>
+
+  </div>
+  <div class="position-container">
+    <div>
+      max-height: max-content<br>on this box.
+    </div>
+
+  </div>
+  <div class="position-container">
+    <div>
+      max-height: fit-content<br>on this box.
+    </div>
+  </div>
+</div>
+
+<div class="container">
+  <div class="position-container f-a-container">
+    <div class="fill-available">
+      max-height: fill-available<br> on this box.
+    </div>
+  </div>
+</div>
diff --git a/LayoutTests/fast/css-intrinsic-dimensions/height-positioned-replaced-expected.html b/LayoutTests/fast/css-intrinsic-dimensions/height-positioned-replaced-expected.html
new file mode 100644 (file)
index 0000000..b348180
--- /dev/null
@@ -0,0 +1,111 @@
+<!DOCTYPE html>
+<!--
+iframes have an intrinsic size of 300x150
+-->
+<style>
+    body * {
+      border: 2px solid red;
+      padding: 5px;
+      clear: both;
+    }
+
+    .container {
+      height: 600px;
+      border-color: blue;
+
+      display: inline-block;
+      width: 100px;
+    }
+
+    .position-container {
+      border-color: green;
+      position: relative;
+      height: 180px;
+    }
+
+    .position-container > * {
+      position: absolute;
+      border: 5px solid pink;
+      width: 50px;
+    }
+
+    .f-a-container {
+      height: 100%;
+      box-sizing: border-box;
+    }
+
+    .fill-available {
+      height: 586px;
+      width: 70px;
+      box-sizing: border-box;
+    }
+</style>
+<div class="container">
+  <div class="position-container">
+    <iframe>
+    </iframe>
+  </div>
+  <div class="position-container">
+    <iframe>
+    </iframe>
+  </div>
+  <div class="position-container">
+    <iframe>
+    </iframe>
+  </div>
+</div>
+
+<div class="container">
+  <div class="position-container f-a-container">
+    <iframe class="fill-available">
+    </iframe>
+  </div>
+</div>
+
+<div class="container">
+  <div class="position-container">
+    <iframe>
+    </iframe>
+
+  </div>
+  <div class="position-container">
+    <iframe>
+    </iframe>
+
+  </div>
+  <div class="position-container">
+    <iframe>
+    </iframe>
+  </div>
+</div>
+
+<div class="container">
+  <div class="position-container f-a-container">
+    <iframe class="fill-available">
+    </iframe>
+  </div>
+</div>
+
+<div class="container">
+  <div class="position-container">
+    <iframe>
+    </iframe>
+
+  </div>
+  <div class="position-container">
+    <iframe>
+    </iframe>
+
+  </div>
+  <div class="position-container">
+    <iframe>
+    </iframe>
+  </div>
+</div>
+
+<div class="container">
+  <div class="position-container f-a-container">
+    <iframe class="fill-available">
+    </iframe>
+  </div>
+</div>
diff --git a/LayoutTests/fast/css-intrinsic-dimensions/height-positioned-replaced.html b/LayoutTests/fast/css-intrinsic-dimensions/height-positioned-replaced.html
new file mode 100644 (file)
index 0000000..e4bca13
--- /dev/null
@@ -0,0 +1,119 @@
+<!DOCTYPE html>
+<!--
+iframes have an intrinsic size of 300x150
+-->
+<style>
+    @import "resources/height-keyword-classes.css";
+
+    body * {
+      border: 2px solid red;
+      padding: 5px;
+      clear: both;
+    }
+
+    .container {
+      height: 600px;
+      border-color: blue;
+
+      display: inline-block;
+      width: 100px;
+    }
+
+    .position-container {
+      border-color: green;
+      position: relative;
+      height: 180px;
+    }
+
+    .position-container > * {
+      position: absolute;
+      border: 5px solid pink;
+      width: 50px;
+    }
+
+    .f-a-container {
+      height: 100%;
+      box-sizing: border-box;
+    }
+
+    .small {
+      height: 1px;
+    }
+
+    .big {
+      height: 300px;
+    }
+
+    .really-big {
+      height: 1000px;
+    }
+</style>
+<div class="container">
+  <div class="position-container">
+    <iframe class="min-content">
+    </iframe>
+  </div>
+  <div class="position-container">
+    <iframe class="max-content">
+    </iframe>
+  </div>
+  <div class="position-container">
+    <iframe class="fit-content">
+    </iframe>
+  </div>
+</div>
+
+<div class="container">
+  <div class="position-container f-a-container">
+    <iframe class="fill-available">
+    </iframe>
+  </div>
+</div>
+
+<div class="container">
+  <div class="position-container">
+    <iframe class="small min-height-min-content">
+    </iframe>
+
+  </div>
+  <div class="position-container">
+    <iframe class="small min-height-max-content">
+    </iframe>
+
+  </div>
+  <div class="position-container">
+    <iframe class="small min-height-fit-content">
+    </iframe>
+  </div>
+</div>
+
+<div class="container">
+  <div class="position-container f-a-container">
+    <iframe class="small min-height-fill-available">
+    </iframe>
+  </div>
+</div>
+
+<div class="container">
+  <div class="position-container">
+    <iframe class="big max-height-min-content">
+    </iframe>
+
+  </div>
+  <div class="position-container">
+    <iframe class="big max-height-max-content">
+    </iframe>
+
+  </div>
+  <div class="position-container">
+    <iframe class="big max-height-fit-content">
+    </iframe>
+  </div>
+</div>
+
+<div class="container">
+  <div class="position-container f-a-container">
+    <iframe class="really-big max-height-fill-available">
+    </iframe>
+  </div>
+</div>
diff --git a/LayoutTests/fast/css-intrinsic-dimensions/height-positioned.html b/LayoutTests/fast/css-intrinsic-dimensions/height-positioned.html
new file mode 100644 (file)
index 0000000..a749df6
--- /dev/null
@@ -0,0 +1,129 @@
+<!DOCTYPE html>
+<!--
+All divs here should shrinkwrap to fit their content, except for fill-available
+-->
+<style>
+    @import "resources/height-keyword-classes.css";
+
+    body * {
+      border: 2px solid red;
+      padding: 5px;
+      clear: both;
+    }
+
+    .container {
+      height: 400px;
+      border-color: blue;
+
+      display: inline-block;
+      width: 100px;
+    }
+
+    .position-container {
+      border-color: green;
+      position: relative;
+      height: 100px;
+    }
+
+    .position-container > * {
+      position: absolute;
+    }
+
+    .f-a-container {
+      height: 100%;
+      box-sizing: border-box;
+    }
+
+    .small {
+      height: 1px;
+    }
+
+    .big {
+      height: 200px;
+    }
+
+    .really-big {
+      height: 1000px;
+    }
+</style>
+<div class="container">
+  <div class="position-container">
+    <div class="min-content">
+      height: min-content<br>on this box.
+    </div>
+  </div>
+  <div class="position-container">
+    <div class="max-content">
+      height: max-content<br>on this box.
+    </div>
+  </div>
+  <div class="position-container">
+    <div class="fit-content">
+      height: fit-content<br>on this box.
+    </div>
+  </div>
+</div>
+
+<div class="container">
+  <div class="position-container f-a-container">
+    <div class="fill-available">
+      height: fill-available<br> on this box.
+    </div>
+  </div>
+</div>
+
+<div class="container">
+  <div class="position-container">
+    <div class="small min-height-min-content">
+      min-height: min-content<br>on this box.
+    </div>
+
+  </div>
+  <div class="position-container">
+    <div class="small min-height-max-content">
+      min-height: max-content<br>on this box.
+    </div>
+
+  </div>
+  <div class="position-container">
+    <div class="small min-height-fit-content">
+      min-height: fit-content<br>on this box.
+    </div>
+  </div>
+</div>
+
+<div class="container">
+  <div class="position-container f-a-container">
+    <div class="small min-height-fill-available">
+      min-height: fill-available<br> on this box.
+    </div>
+  </div>
+</div>
+
+<div class="container">
+  <div class="position-container">
+    <div class="big max-height-min-content">
+      max-height: min-content<br>on this box.
+    </div>
+
+  </div>
+  <div class="position-container">
+    <div class="big max-height-max-content">
+      max-height: max-content<br>on this box.
+    </div>
+
+  </div>
+  <div class="position-container">
+    <div class="big max-height-fit-content">
+      max-height: fit-content<br>on this box.
+    </div>
+  </div>
+</div>
+
+<div class="container">
+  <div class="position-container f-a-container">
+    <div class="really-big max-height-fill-available">
+      max-height: fill-available<br> on this box.
+    </div>
+  </div>
+</div>
index 107443f..2f99cec 100644 (file)
@@ -1,35 +1,20 @@
-Tests that the height keywords are not exposed yet.
+Tests that the height keywords are parsed.
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
-PASS divs[i].style.height is ""
-PASS divs[i].style.minHeight is ""
-PASS divs[i].style.maxHeight is ""
-PASS divs[i].style.height is ""
-PASS divs[i].style.minHeight is ""
-PASS divs[i].style.maxHeight is ""
-PASS divs[i].style.height is ""
-PASS divs[i].style.minHeight is ""
-PASS divs[i].style.maxHeight is ""
-PASS divs[i].style.height is ""
-PASS divs[i].style.minHeight is ""
-PASS divs[i].style.maxHeight is ""
-PASS divs[i].style.height is ""
-PASS divs[i].style.minHeight is ""
-PASS divs[i].style.maxHeight is ""
-PASS div.style.height is ""
-PASS div.style.minHeight is ""
-PASS div.style.maxHeight is ""
-PASS div.style.height is ""
-PASS div.style.minHeight is ""
-PASS div.style.maxHeight is ""
-PASS div.style.height is ""
-PASS div.style.minHeight is ""
-PASS div.style.maxHeight is ""
-PASS div.style.height is ""
-PASS div.style.minHeight is ""
-PASS div.style.maxHeight is ""
+PASS div.style.height is "-webkit-min-content"
+PASS div.style.minHeight is "-webkit-min-content"
+PASS div.style.maxHeight is "-webkit-min-content"
+PASS div.style.height is "-webkit-max-content"
+PASS div.style.minHeight is "-webkit-max-content"
+PASS div.style.maxHeight is "-webkit-max-content"
+PASS div.style.height is "-webkit-fill-available"
+PASS div.style.minHeight is "-webkit-fill-available"
+PASS div.style.maxHeight is "-webkit-fill-available"
+PASS div.style.height is "-webkit-fit-content"
+PASS div.style.minHeight is "-webkit-fit-content"
+PASS div.style.maxHeight is "-webkit-fit-content"
 PASS successfullyParsed is true
 
 TEST COMPLETE
index 145cd21..9fa7ff0 100644 (file)
@@ -4,22 +4,22 @@
 -->
 <script src="../../resources/js-test-pre.js"></script>
 
-<div style="height: -webkit-min-content; min-height: -webkit-min-content; max-height: -webkit-min-content;"></div>
-<div style="height: -webkit-max-content; min-height: -webkit-max-content; max-height: -webkit-max-content;"></div>
-<div style="height: -webkit-fill-available; min-height: -webkit-fill-available; max-height: -webkit-fill-available;"></div>
-<div style="height: -webkit-fit-content; min-height: -webkit-fit-content; max-height: -webkit-fit-content;"></div>
+<div style="height: -webkit-min-content; min-height: -webkit-min-content; max-height: -webkit-min-content;" expected-data="min-content"></div>
+<div style="height: -webkit-max-content; min-height: -webkit-max-content; max-height: -webkit-max-content;" expected-data="max-content"></div>
+<div style="height: -webkit-fill-available; min-height: -webkit-fill-available; max-height: -webkit-fill-available;" expected-data="fill-available"></div>
+<div style="height: -webkit-fit-content; min-height: -webkit-fit-content; max-height: -webkit-fit-content;" expected-data="fit-content"></div>
 
 <script>
-    description('Tests that the height keywords are not exposed yet.');
+    description('Tests that the height keywords are parsed.');
+    var PREFIX = '-webkit-';
 
-    var divs = document.querySelectorAll('div');
+    var divs = document.querySelectorAll('div.expected-data');
     for (var i = 0; i < divs.length; ++i) {
-        shouldBeEmptyString('divs[i].style.height');
-        shouldBeEmptyString('divs[i].style.minHeight');
-        shouldBeEmptyString('divs[i].style.maxHeight');
+        shouldBe('divs[i].style.height', 'PREFIX + divs[i].getAttribute("expected-data")');
+        shouldBe('divs[i].style.minHeight', 'PREFIX + divs[i].getAttribute("expected-data")');
+        shouldBe('divs[i].style.maxHeight', 'PREFIX + divs[i].getAttribute("expected-data")');
     }
 
-    var PREFIX = '-webkit-';
     var KEYWORDS = ['min-content', 'max-content', 'fill-available',  'fit-content'];
     var div;
 
@@ -28,9 +28,9 @@
         div.style.height = PREFIX + keyword;
         div.style.minHeight = PREFIX + keyword;
         div.style.maxHeight = PREFIX + keyword;
-        shouldBeEmptyString('div.style.height');
-        shouldBeEmptyString('div.style.minHeight');
-        shouldBeEmptyString('div.style.maxHeight');
+        shouldBe('div.style.height', '"' + PREFIX + keyword + '"');
+        shouldBe('div.style.minHeight', '"' + PREFIX + keyword + '"');
+        shouldBe('div.style.maxHeight', '"' + PREFIX + keyword + '"');
     });
 </script>
 
diff --git a/LayoutTests/fast/css-intrinsic-dimensions/height-property-value.html.orig b/LayoutTests/fast/css-intrinsic-dimensions/height-property-value.html.orig
new file mode 100644 (file)
index 0000000..145cd21
--- /dev/null
@@ -0,0 +1,37 @@
+<!doctype html>
+<!--
+    Tests that the height keywords are not respected by the parser yet.
+-->
+<script src="../../resources/js-test-pre.js"></script>
+
+<div style="height: -webkit-min-content; min-height: -webkit-min-content; max-height: -webkit-min-content;"></div>
+<div style="height: -webkit-max-content; min-height: -webkit-max-content; max-height: -webkit-max-content;"></div>
+<div style="height: -webkit-fill-available; min-height: -webkit-fill-available; max-height: -webkit-fill-available;"></div>
+<div style="height: -webkit-fit-content; min-height: -webkit-fit-content; max-height: -webkit-fit-content;"></div>
+
+<script>
+    description('Tests that the height keywords are not exposed yet.');
+
+    var divs = document.querySelectorAll('div');
+    for (var i = 0; i < divs.length; ++i) {
+        shouldBeEmptyString('divs[i].style.height');
+        shouldBeEmptyString('divs[i].style.minHeight');
+        shouldBeEmptyString('divs[i].style.maxHeight');
+    }
+
+    var PREFIX = '-webkit-';
+    var KEYWORDS = ['min-content', 'max-content', 'fill-available',  'fit-content'];
+    var div;
+
+    KEYWORDS.forEach(function(keyword) {
+        div = document.createElement('div');
+        div.style.height = PREFIX + keyword;
+        div.style.minHeight = PREFIX + keyword;
+        div.style.maxHeight = PREFIX + keyword;
+        shouldBeEmptyString('div.style.height');
+        shouldBeEmptyString('div.style.minHeight');
+        shouldBeEmptyString('div.style.maxHeight');
+    });
+</script>
+
+<script src="../../resources/js-test-post.js"></script>
diff --git a/LayoutTests/fast/css-intrinsic-dimensions/height-replaced-expected.html b/LayoutTests/fast/css-intrinsic-dimensions/height-replaced-expected.html
new file mode 100644 (file)
index 0000000..ea6fb39
--- /dev/null
@@ -0,0 +1,85 @@
+<!DOCTYPE html>
+<style>
+    body * {
+        border: 2px solid red;
+        padding: 5px;
+        clear: both;
+    }
+
+    .container {
+        height: 500px;
+        border-color: blue;
+
+        display: inline-block;
+        width: 100px;
+    }
+
+    iframe {
+      width: 50px;
+    }
+
+    .fill-available {
+      height: 100%;
+      width: 64px;
+      box-sizing: border-box;
+    }
+</style>
+<div class="container">
+  <iframe>
+    height: min-content<br>on this box.
+  </iframe>
+
+  <iframe>
+    height: max-content<br>on this box.
+  </iframe>
+
+  <iframe>
+    height: fit-content<br>on this box.
+  </iframe>
+</div>
+
+<div class="container">
+  <iframe class="fill-available">
+    height: fill-available<br> on this box.
+  </iframe>
+</div>
+
+<div class="container">
+  <iframe>
+    min-height: min-content<br>on this box.
+  </iframe>
+
+  <iframe>
+    min-height: max-content<br>on this box.
+  </iframe>
+
+  <iframe>
+    min-height: fit-content<br>on this box.
+  </iframe>
+</div>
+
+<div class="container">
+  <iframe class="fill-available">
+    min-height: fill-available<br> on this box.
+  </iframe>
+</div>
+
+<div class="container">
+  <iframe>
+    max-height: min-content<br>on this box.
+  </iframe>
+
+  <iframe>
+    max-height: max-content<br>on this box.
+  </iframe>
+
+  <iframe>
+    max-height: fit-content<br>on this box.
+  </iframe>
+</div>
+
+<div class="container">
+  <iframe class="fill-available">
+    max-height: fill-available<br> on this box.
+  </iframe>
+</div>
diff --git a/LayoutTests/fast/css-intrinsic-dimensions/height-replaced.html b/LayoutTests/fast/css-intrinsic-dimensions/height-replaced.html
new file mode 100644 (file)
index 0000000..596407a
--- /dev/null
@@ -0,0 +1,84 @@
+<!DOCTYPE html>
+<!--
+All divs here should shrinkwrap to fit their content, except for fill-available
+-->
+<style>
+    @import "resources/height-keyword-classes.css";
+
+    body * {
+        border: 2px solid red;
+        padding: 5px;
+        clear: both;
+    }
+
+    .container {
+        height: 500px;
+        border-color: blue;
+
+        display: inline-block;
+        width: 100px;
+    }
+
+    iframe {
+      width: 50px;
+    }
+
+    .small {
+      height: 1px;
+    }
+
+    .big {
+      height: 300px;
+    }
+
+    .really-big {
+      height: 1000px;
+    }
+</style>
+<div class="container">
+  <iframe class="min-content">
+  </iframe>
+
+  <iframe class="max-content">
+  </iframe>
+
+  <iframe class="fit-content">
+  </iframe>
+</div>
+
+<div class="container">
+  <iframe class="fill-available">
+  </iframe>
+</div>
+
+<div class="container">
+  <iframe class="small min-height-min-content">
+  </iframe>
+
+  <iframe class="small min-height-max-content">
+  </iframe>
+
+  <iframe class="small min-height-fit-content">
+  </iframe>
+</div>
+
+<div class="container">
+  <iframe class="small min-height-fill-available">
+  </iframe>
+</div>
+
+<div class="container">
+  <iframe class="big max-height-min-content">
+  </iframe>
+
+  <iframe class="big max-height-max-content">
+  </iframe>
+
+  <iframe class="big max-height-fit-content">
+  </iframe>
+</div>
+
+<div class="container">
+  <iframe class="really-big max-height-fill-available">
+  </iframe>
+</div>
diff --git a/LayoutTests/fast/css-intrinsic-dimensions/height-tables-collapsed-expected.html b/LayoutTests/fast/css-intrinsic-dimensions/height-tables-collapsed-expected.html
new file mode 100644 (file)
index 0000000..5ebfbc5
--- /dev/null
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+
+<style>
+  .item { height: 50px; width: 50px; border: 1px solid blue; }
+
+  .container { height: 100px; border: 5px solid pink; }
+  table { border: 2px solid red; border-collapse: collapse; }
+  td { border: 2px solid green; }
+</style>
+
+<table>
+  <td>
+    <div class="item"></div>
+  </td>
+</table>
+
+<table>
+  <td>
+    <div class="item"></div>
+  </td>
+</table>
+
+<div class="container">
+  <table style="height: 100%; box-sizing: border-box;">
+    <td>
+      <div class="item"></div>
+    </td>
+  </table>
+</div>
+
+
+<table class="container">
+  <td style="height: 79px;">
+    <div class="item"></div>
+  </td>
+</table>
diff --git a/LayoutTests/fast/css-intrinsic-dimensions/height-tables-collapsed.html b/LayoutTests/fast/css-intrinsic-dimensions/height-tables-collapsed.html
new file mode 100644 (file)
index 0000000..596a5d3
--- /dev/null
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+
+<style>
+  @import "resources/height-keyword-classes.css";
+
+  .small { height: 1px; }
+  .big { height: 300px; }
+  .item { height: 50px; width: 50px; border: 1px solid blue; }
+
+  .container { height: 100px; border: 5px solid pink; }
+  table { border: 2px solid red; border-collapse: collapse; }
+  td { border: 2px solid green; }
+</style>
+
+<table class="big max-height-min-content">
+  <td>
+    <div class="item"></div>
+  </td>
+</table>
+
+<table>
+  <td class="small min-height-min-content">
+    <div class="item"></div>
+  </td>
+</table>
+
+<div class="container">
+  <table class="small min-height-fill-available">
+    <td>
+      <div class="item"></div>
+    </td>
+  </table>
+</div>
+
+
+<table class="container">
+  <td class="small min-height-fill-available">
+    <div class="item"></div>
+  </td>
+</table>
diff --git a/LayoutTests/fast/css-intrinsic-dimensions/height-tables-expected.html b/LayoutTests/fast/css-intrinsic-dimensions/height-tables-expected.html
new file mode 100644 (file)
index 0000000..fa27589
--- /dev/null
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+
+<style>
+  .item { height: 50px; width: 50px; border: 1px solid blue; }
+
+  .container { height: 100px; border: 5px solid pink; }
+  table { border: 2px solid red; }
+  td { border: 2px solid green; }
+</style>
+
+<table>
+  <td>
+    <div class="item"></div>
+  </td>
+</table>
+
+<table>
+  <td>
+    <div class="item"></div>
+  </td>
+</table>
+
+<div class="container">
+  <table style="height: 100%; box-sizing: border-box;">
+    <td>
+      <div class="item"></div>
+    </td>
+  </table>
+</div>
+
+
+<table class="container">
+  <td style="height: 79px;">
+    <div class="item"></div>
+  </td>
+</table>
diff --git a/LayoutTests/fast/css-intrinsic-dimensions/height-tables.html b/LayoutTests/fast/css-intrinsic-dimensions/height-tables.html
new file mode 100644 (file)
index 0000000..99c922e
--- /dev/null
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+
+<style>
+  @import "resources/height-keyword-classes.css";
+
+  .small { height: 1px; }
+  .big { height: 300px; }
+  .item { height: 50px; width: 50px; border: 1px solid blue; }
+
+  .container { height: 100px; border: 5px solid pink; }
+  table { border: 2px solid red; }
+  td { border: 2px solid green; }
+</style>
+
+<table class="big max-height-min-content">
+  <td>
+    <div class="item"></div>
+  </td>
+</table>
+
+<table>
+  <td class="small min-height-min-content">
+    <div class="item"></div>
+  </td>
+</table>
+
+<div class="container">
+  <table class="small min-height-fill-available">
+    <td>
+      <div class="item"></div>
+    </td>
+  </table>
+</div>
+
+
+<table class="container">
+  <td class="small min-height-fill-available">
+    <div class="item"></div>
+  </td>
+</table>
diff --git a/LayoutTests/fast/css-intrinsic-dimensions/height.html b/LayoutTests/fast/css-intrinsic-dimensions/height.html
new file mode 100644 (file)
index 0000000..35ff3b6
--- /dev/null
@@ -0,0 +1,92 @@
+<!DOCTYPE html>
+<!--
+All divs here should shrinkwrap to fit their content, except for fill-available
+-->
+<style>
+    @import "resources/height-keyword-classes.css";
+
+    body * {
+        border: 2px solid red;
+        padding: 5px;
+        clear: both;
+    }
+
+    .container {
+        height: 300px;
+        border-color: blue;
+
+        display: inline-block;
+        width: 100px;
+    }
+
+    .small {
+      height: 1px;
+    }
+
+    .big {
+      height: 100px;
+    }
+
+    .really-big {
+      height: 1000px;
+    }
+</style>
+<div class="container">
+  <div class="min-content">
+    height: min-content<br>on this box.
+  </div>
+
+  <div class="max-content">
+    height: max-content<br>on this box.
+  </div>
+
+  <div class="fit-content">
+    height: fit-content<br>on this box.
+  </div>
+</div>
+
+<div class="container">
+  <div class="fill-available">
+    height: fill-available<br> on this box.
+  </div>
+</div>
+
+<div class="container">
+  <div class="small min-height-min-content">
+    min-height: min-content<br>on this box.
+  </div>
+
+  <div class="small min-height-max-content">
+    min-height: max-content<br>on this box.
+  </div>
+
+  <div class="small min-height-fit-content">
+    min-height: fit-content<br>on this box.
+  </div>
+</div>
+
+<div class="container">
+  <div class="small min-height-fill-available">
+    min-height: fill-available<br> on this box.
+  </div>
+</div>
+
+<div class="container">
+  <div class="big max-height-min-content">
+    max-height: min-content<br>on this box.
+  </div>
+
+  <div class="big max-height-max-content">
+    max-height: max-content<br>on this box.
+  </div>
+
+  <div class="big max-height-fit-content">
+    max-height: fit-content<br>on this box.
+  </div>
+</div>
+
+<div class="container">
+  <div class="really-big max-height-fill-available">
+    max-height: fill-available<br> on this box.
+  </div>
+</div>
diff --git a/LayoutTests/fast/css-intrinsic-dimensions/resources/height-keyword-classes.css b/LayoutTests/fast/css-intrinsic-dimensions/resources/height-keyword-classes.css
new file mode 100644 (file)
index 0000000..9cbfaa1
--- /dev/null
@@ -0,0 +1,77 @@
+/* In the current spec for heights, min-content, max-content and fit-content are
+ * equivalent.
+ * fill-available is different and similar to widths.
+ */
+
+.min-content {
+    height: -webkit-min-content;
+    height: -moz-min-content;
+    height: min-content;
+}
+
+.max-content {
+    height: -webkit-max-content;
+    height: -moz-max-content;
+    height: max-content;
+}
+
+.fill-available {
+    height: -webkit-fill-available;
+    /* Firefox is missing the fill- prefix because they followed an older spec */
+    height: -moz-available;
+    height: fill-available;
+}
+
+.fit-content {
+    height: -webkit-fit-content;
+    height: -moz-fit-content;
+    height: fit-content;
+}
+
+.max-height-min-content {
+    max-height: -webkit-min-content;
+    max-height: -moz-min-content;
+    max-height: min-content;
+}
+
+.max-height-max-content {
+    max-height: -webkit-max-content;
+    max-height: -moz-max-content;
+    max-height: max-content;
+}
+
+.max-height-fill-available {
+    max-height: -webkit-fill-available;
+    max-height: -moz-available;
+    max-height: fill-available;
+}
+
+.max-height-fit-content {
+    max-height: -webkit-fit-content;
+    max-height: -moz-fit-content;
+    max-height: fit-content;
+}
+
+.min-height-min-content {
+    min-height: -webkit-min-content;
+    min-height: -moz-min-content;
+    min-height: min-content;
+}
+
+.min-height-max-content {
+    min-height: -webkit-max-content;
+    min-height: -moz-max-content;
+    min-height: max-content;
+}
+
+.min-height-fill-available {
+    min-height: -webkit-fill-available;
+    min-height: -moz-available;
+    min-height: fill-available;
+}
+
+.min-height-fit-content {
+    min-height: -webkit-fit-content;
+    min-height: -moz-fit-content;
+    min-height: fit-content;
+}
index b613542..f08c6ec 100644 (file)
@@ -1,3 +1,73 @@
+2015-06-11  Sergio Villar Senin  <svillar@igalia.com>
+
+        intrinsic size keywords don't work for heights
+        https://bugs.webkit.org/show_bug.cgi?id=113610
+
+        Reviewed by Darin Adler.
+
+        Based on Blink's r148314 & r150355 by <cbiesinger@chromium.org>.
+
+        Adds intrinsic values support to heigh & min/max-height. This involves the
+        following changes:
+        - RenderBox needs to pass the content height through to computeLogicalHeight and
+        related functions, which needs it to resolve max-content, et. al.
+        - Make the callers pass the content height to this function. Some callers pass
+        logicalHeight() (adjusted for border/padding) which works because if
+        logicalHeight is not the content height, then it is the height we ended up using,
+        so the constrain* functions will just constrain to that value again.
+        - Parsing code needs to be adjusted to support intrinsic values for heights.
+
+        Tests: fast/css-intrinsic-dimensions/height-css-tables-collapsed.html
+               fast/css-intrinsic-dimensions/height-css-tables.html
+               fast/css-intrinsic-dimensions/height-flexbox.html
+               fast/css-intrinsic-dimensions/height-positioned-replaced.html
+               fast/css-intrinsic-dimensions/height-positioned.html
+               fast/css-intrinsic-dimensions/height-replaced.html
+               fast/css-intrinsic-dimensions/height-tables-collapsed.html
+               fast/css-intrinsic-dimensions/height-tables.html
+               fast/css-intrinsic-dimensions/height.html
+
+        * css/CSSParser.cpp:
+        (WebCore::CSSParser::isValidSize): Refactored from validateWidth and
+        validateHeight.
+        (WebCore::CSSParser::parseValue):
+        (WebCore::CSSParser::validateWidth): Deleted.
+        (WebCore::CSSParser::validateHeight): Deleted.
+        * css/CSSParser.h:
+        * platform/Length.h:
+        (WebCore::Length::isFillAvailable):
+        (WebCore::Length::isFitContent):
+        * rendering/RenderBox.cpp:
+        (WebCore::RenderBox::constrainLogicalHeightByMinMax):
+        (WebCore::RenderBox::constrainContentBoxLogicalHeightByMinMax):
+        (WebCore::RenderBox::computeLogicalHeight):
+        (WebCore::RenderBox::computeLogicalHeightUsing):
+        (WebCore::RenderBox::computeContentLogicalHeight):
+        (WebCore::RenderBox::computeIntrinsicLogicalContentHeightUsing):
+        (WebCore::RenderBox::computeContentAndScrollbarLogicalHeightUsing):
+        (WebCore::RenderBox::computePercentageLogicalHeight):
+        (WebCore::RenderBox::computeReplacedLogicalHeightUsing):
+        (WebCore::RenderBox::availableLogicalHeight):
+        (WebCore::RenderBox::availableLogicalHeightUsing):
+        (WebCore::RenderBox::computePositionedLogicalHeight):
+        (WebCore::RenderBox::computePositionedLogicalHeightUsing):
+        * rendering/RenderBox.h:
+        * rendering/RenderFlexibleBox.cpp:
+        (WebCore::RenderFlexibleBox::computeMainAxisExtentForChild):
+        (WebCore::RenderFlexibleBox::applyStretchAlignmentToChild):
+        * rendering/RenderFlowThread.cpp:
+        (WebCore::RenderFlowThread::addForcedRegionBreak):
+        * rendering/RenderGrid.cpp:
+        (WebCore::RenderGrid::computeUsedBreadthOfSpecifiedLength):
+        (WebCore::RenderGrid::applyStretchAlignmentToChildIfNeeded):
+        * rendering/RenderMultiColumnSet.cpp:
+        (WebCore::RenderMultiColumnSet::calculateMaxColumnHeight):
+        * rendering/RenderReplaced.cpp:
+        (WebCore::RenderReplaced::hasReplacedLogicalHeight):
+        * rendering/RenderTable.cpp:
+        (WebCore::RenderTable::convertStyleLogicalHeightToComputedHeight):
+        (WebCore::RenderTable::layout):
+
 2015-06-24  Commit Queue  <commit-queue@webkit.org>
 
         Unreviewed, rolling out r185906.
index 4b69c31..d8dbdff 100644 (file)
@@ -1815,7 +1815,7 @@ static inline bool isForwardSlashOperator(CSSParserValue& value)
     return value.unit == CSSParserValue::Operator && value.iValue == '/';
 }
 
-bool CSSParser::validateWidth(ValueWithCalculation& valueWithCalculation)
+bool CSSParser::isValidSize(ValueWithCalculation& valueWithCalculation)
 {
     int id = valueWithCalculation.value().id;
     if (id == CSSValueIntrinsic || id == CSSValueMinIntrinsic || id == CSSValueWebkitMinContent || id == CSSValueWebkitMaxContent || id == CSSValueWebkitFillAvailable || id == CSSValueWebkitFitContent)
@@ -1823,15 +1823,6 @@ bool CSSParser::validateWidth(ValueWithCalculation& valueWithCalculation)
     return !id && validateUnit(valueWithCalculation, FLength | FPercent | FNonNeg);
 }
 
-// FIXME: Combine this with validWidth when we support fit-content, et al, for heights.
-bool CSSParser::validateHeight(ValueWithCalculation& valueWithCalculation)
-{
-    int id = valueWithCalculation.value().id;
-    if (id == CSSValueIntrinsic || id == CSSValueMinIntrinsic)
-        return true;
-    return !id && validateUnit(valueWithCalculation, FLength | FPercent | FNonNeg);
-}
-
 inline PassRefPtr<CSSPrimitiveValue> CSSParser::parseValidPrimitive(CSSValueID identifier, ValueWithCalculation& valueWithCalculation)
 {
     if (identifier)
@@ -2256,32 +2247,23 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important)
 
     case CSSPropertyMaxWidth:
     case CSSPropertyWebkitMaxLogicalWidth:
-        validPrimitive = (id == CSSValueNone || validateWidth(valueWithCalculation));
-        break;
-
-    case CSSPropertyMinWidth:
-    case CSSPropertyWebkitMinLogicalWidth:
-        validPrimitive = validateWidth(valueWithCalculation);
-        break;
-
-    case CSSPropertyWidth:
-    case CSSPropertyWebkitLogicalWidth:
-        validPrimitive = (id == CSSValueAuto || validateWidth(valueWithCalculation));
-        break;
-
     case CSSPropertyMaxHeight:
     case CSSPropertyWebkitMaxLogicalHeight:
-        validPrimitive = (id == CSSValueNone || validateHeight(valueWithCalculation));
+        validPrimitive = (id == CSSValueNone || isValidSize(valueWithCalculation));
         break;
 
+    case CSSPropertyMinWidth:
+    case CSSPropertyWebkitMinLogicalWidth:
     case CSSPropertyMinHeight:
     case CSSPropertyWebkitMinLogicalHeight:
-        validPrimitive = validateHeight(valueWithCalculation);
+        validPrimitive = isValidSize(valueWithCalculation);
         break;
 
+    case CSSPropertyWidth:
+    case CSSPropertyWebkitLogicalWidth:
     case CSSPropertyHeight:
     case CSSPropertyWebkitLogicalHeight:
-        validPrimitive = (id == CSSValueAuto || validateHeight(valueWithCalculation));
+        validPrimitive = (id == CSSValueAuto || isValidSize(valueWithCalculation));
         break;
 
     case CSSPropertyFontSize:
index 398c2f4..f7923c5 100644 (file)
@@ -550,8 +550,7 @@ private:
     void setupParser(const char* prefix, unsigned prefixLength, StringView, const char* suffix, unsigned suffixLength);
     bool inShorthand() const { return m_inParseShorthand; }
 
-    bool validateWidth(ValueWithCalculation&);
-    bool validateHeight(ValueWithCalculation&);
+    bool isValidSize(ValueWithCalculation&);
 
     void deleteFontFaceOnlyValues();
 
index 9c8d08a..e4294e9 100644 (file)
@@ -87,6 +87,8 @@ public:
     bool isPercent() const;
     bool isRelative() const;
     bool isUndefined() const;
+    bool isFillAvailable() const;
+    bool isFitContent() const;
 
     bool hasQuirk() const;
 
@@ -400,6 +402,16 @@ inline bool Length::isSpecifiedOrIntrinsic() const
     return isSpecified() || isIntrinsic();
 }
 
+inline bool Length::isFillAvailable() const
+{
+    return type() == FillAvailable;
+}
+
+inline bool Length::isFitContent() const
+{
+    return type() == FitContent;
+}
+
 // FIXME: Does this need to be in the header? Is it valuable to inline? Does it get inlined?
 inline Length Length::blend(const Length& from, double progress) const
 {
index d018ed4..502df66 100644 (file)
@@ -656,26 +656,26 @@ LayoutUnit RenderBox::constrainLogicalWidthInRegionByMinMax(LayoutUnit logicalWi
     return std::max(logicalWidth, computeLogicalWidthInRegionUsing(MinSize, styleToUse.logicalMinWidth(), availableWidth, cb, region));
 }
 
-LayoutUnit RenderBox::constrainLogicalHeightByMinMax(LayoutUnit logicalHeight) const
+LayoutUnit RenderBox::constrainLogicalHeightByMinMax(LayoutUnit logicalHeight, LayoutUnit intrinsicContentHeight) const
 {
     const RenderStyle& styleToUse = style();
     if (!styleToUse.logicalMaxHeight().isUndefined()) {
-        LayoutUnit maxH = computeLogicalHeightUsing(styleToUse.logicalMaxHeight());
+        LayoutUnit maxH = computeLogicalHeightUsing(styleToUse.logicalMaxHeight(), intrinsicContentHeight);
         if (maxH != -1)
             logicalHeight = std::min(logicalHeight, maxH);
     }
-    return std::max(logicalHeight, computeLogicalHeightUsing(styleToUse.logicalMinHeight()));
+    return std::max(logicalHeight, computeLogicalHeightUsing(styleToUse.logicalMinHeight(), intrinsicContentHeight));
 }
 
-LayoutUnit RenderBox::constrainContentBoxLogicalHeightByMinMax(LayoutUnit logicalHeight) const
+LayoutUnit RenderBox::constrainContentBoxLogicalHeightByMinMax(LayoutUnit logicalHeight, LayoutUnit intrinsicContentHeight) const
 {
     const RenderStyle& styleToUse = style();
     if (!styleToUse.logicalMaxHeight().isUndefined()) {
-        LayoutUnit maxH = computeContentLogicalHeight(styleToUse.logicalMaxHeight());
+        LayoutUnit maxH = computeContentLogicalHeight(styleToUse.logicalMaxHeight(), intrinsicContentHeight);
         if (maxH != -1)
             logicalHeight = std::min(logicalHeight, maxH);
     }
-    return std::max(logicalHeight, computeContentLogicalHeight(styleToUse.logicalMinHeight()));
+    return std::max(logicalHeight, computeContentLogicalHeight(styleToUse.logicalMinHeight(), intrinsicContentHeight));
 }
 
 RoundedRect::Radii RenderBox::borderRadii() const
@@ -2756,19 +2756,21 @@ void RenderBox::computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logica
 
         LayoutUnit heightResult;
         if (checkMinMaxHeight) {
-            heightResult = computeLogicalHeightUsing(style().logicalHeight());
+            LayoutUnit intrinsicHeight = computedValues.m_extent - borderAndPaddingLogicalHeight();
+            heightResult = computeLogicalHeightUsing(style().logicalHeight(), intrinsicHeight);
             if (heightResult == -1)
                 heightResult = computedValues.m_extent;
-            heightResult = constrainLogicalHeightByMinMax(heightResult);
+            heightResult = constrainLogicalHeightByMinMax(heightResult, intrinsicHeight);
         } else {
             // The only times we don't check min/max height are when a fixed length has
             // been given as an override.  Just use that.  The value has already been adjusted
             // for box-sizing.
+            ASSERT(h.isFixed());
             heightResult = h.value() + borderAndPaddingLogicalHeight();
         }
 
         computedValues.m_extent = heightResult;
-        
+
         if (hasPerpendicularContainingBlock) {
             bool shouldFlipBeforeAfter = shouldFlipBeforeAfterMargins(cb->style(), &style());
             computeInlineDirectionMargins(cb, containingBlockLogicalWidthForContent(), heightResult,
@@ -2796,24 +2798,40 @@ void RenderBox::computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logica
     }
 }
 
-LayoutUnit RenderBox::computeLogicalHeightUsing(const Length& height) const
+LayoutUnit RenderBox::computeLogicalHeightUsing(const Length& height, LayoutUnit intrinsicContentHeight) const
 {
-    LayoutUnit logicalHeight = computeContentAndScrollbarLogicalHeightUsing(height);
+    LayoutUnit logicalHeight = computeContentAndScrollbarLogicalHeightUsing(height, intrinsicContentHeight);
     if (logicalHeight != -1)
         logicalHeight = adjustBorderBoxLogicalHeightForBoxSizing(logicalHeight);
     return logicalHeight;
 }
 
-LayoutUnit RenderBox::computeContentLogicalHeight(const Length& height) const
+LayoutUnit RenderBox::computeContentLogicalHeight(const Length& height, LayoutUnit intrinsicContentHeight) const
 {
-    LayoutUnit heightIncludingScrollbar = computeContentAndScrollbarLogicalHeightUsing(height);
+    LayoutUnit heightIncludingScrollbar = computeContentAndScrollbarLogicalHeightUsing(height, intrinsicContentHeight);
     if (heightIncludingScrollbar == -1)
         return -1;
     return std::max<LayoutUnit>(0, adjustContentBoxLogicalHeightForBoxSizing(heightIncludingScrollbar) - scrollbarLogicalHeight());
 }
 
-LayoutUnit RenderBox::computeContentAndScrollbarLogicalHeightUsing(const Length& height) const
+LayoutUnit RenderBox::computeIntrinsicLogicalContentHeightUsing(Length logicalHeightLength, LayoutUnit intrinsicContentHeight, LayoutUnit borderAndPadding) const
+{
+    // FIXME: The CSS sizing spec is considering changing what min-content/max-content should resolve to.
+    // If that happens, this code will have to change.
+    if (logicalHeightLength.isMinContent() || logicalHeightLength.isMaxContent() || logicalHeightLength.isFitContent())
+        return intrinsicContentHeight;
+    if (logicalHeightLength.isFillAvailable())
+        return containingBlock()->availableLogicalHeight(ExcludeMarginBorderPadding) - borderAndPadding;
+    ASSERT_NOT_REACHED();
+    return 0;
+}
+
+LayoutUnit RenderBox::computeContentAndScrollbarLogicalHeightUsing(const Length& height, LayoutUnit intrinsicContentHeight) const
 {
+    // FIXME: The CSS sizing spec is considering changing what min-content/max-content should resolve to.
+    // If that happens, this code will have to change.
+    if (height.isIntrinsic())
+        return computeIntrinsicLogicalContentHeightUsing(height, intrinsicContentHeight, borderAndPaddingLogicalHeight());
     if (height.isFixed())
         return height.value();
     if (height.isPercentOrCalculated())
@@ -2890,7 +2908,7 @@ LayoutUnit RenderBox::computePercentageLogicalHeight(const Length& height) const
         }
     } else if (cbstyle.logicalHeight().isFixed()) {
         LayoutUnit contentBoxHeight = cb->adjustContentBoxLogicalHeightForBoxSizing(cbstyle.logicalHeight().value());
-        availableHeight = std::max<LayoutUnit>(0, cb->constrainContentBoxLogicalHeightByMinMax(contentBoxHeight - cb->scrollbarLogicalHeight()));
+        availableHeight = std::max<LayoutUnit>(0, cb->constrainContentBoxLogicalHeightByMinMax(contentBoxHeight - cb->scrollbarLogicalHeight(), -1));
     } else if (cbstyle.logicalHeight().isPercentOrCalculated() && !isOutOfFlowPositionedWithSpecifiedHeight) {
         // We need to recur and compute the percentage height for our containing block.
         LayoutUnit heightWithScrollbar = cb->computePercentageLogicalHeight(cbstyle.logicalHeight());
@@ -2900,7 +2918,7 @@ LayoutUnit RenderBox::computePercentageLogicalHeight(const Length& height) const
             // handle the min/max of the current block, its caller does. So the
             // return value from the recursive call will not have been adjusted
             // yet.
-            LayoutUnit contentBoxHeight = cb->constrainContentBoxLogicalHeightByMinMax(contentBoxHeightWithScrollbar - cb->scrollbarLogicalHeight());
+            LayoutUnit contentBoxHeight = cb->constrainContentBoxLogicalHeightByMinMax(contentBoxHeightWithScrollbar - cb->scrollbarLogicalHeight(), -1);
             availableHeight = std::max<LayoutUnit>(0, contentBoxHeight);
         }
     } else if (isOutOfFlowPositionedWithSpecifiedHeight) {
@@ -3045,6 +3063,11 @@ LayoutUnit RenderBox::computeReplacedLogicalHeightUsing(Length logicalHeight) co
             }
             return adjustContentBoxLogicalHeightForBoxSizing(valueForLength(logicalHeight, availableHeight));
         }
+        case MinContent:
+        case MaxContent:
+        case FitContent:
+        case FillAvailable:
+            return adjustContentBoxLogicalHeightForBoxSizing(computeIntrinsicLogicalContentHeightUsing(logicalHeight, intrinsicLogicalHeight(), borderAndPaddingLogicalHeight()));
         default:
             return intrinsicLogicalHeight();
     }
@@ -3052,7 +3075,7 @@ LayoutUnit RenderBox::computeReplacedLogicalHeightUsing(Length logicalHeight) co
 
 LayoutUnit RenderBox::availableLogicalHeight(AvailableLogicalHeightType heightType) const
 {
-    return constrainLogicalHeightByMinMax(availableLogicalHeightUsing(style().logicalHeight(), heightType));
+    return constrainLogicalHeightByMinMax(availableLogicalHeightUsing(style().logicalHeight(), heightType), -1);
 }
 
 LayoutUnit RenderBox::availableLogicalHeightUsing(const Length& h, AvailableLogicalHeightType heightType) const
@@ -3072,7 +3095,7 @@ LayoutUnit RenderBox::availableLogicalHeightUsing(const Length& h, AvailableLogi
         return adjustContentBoxLogicalHeightForBoxSizing(valueForLength(h, availableHeight));
     }
 
-    LayoutUnit heightIncludingScrollbar = computeContentAndScrollbarLogicalHeightUsing(h);
+    LayoutUnit heightIncludingScrollbar = computeContentAndScrollbarLogicalHeightUsing(h, -1);
     if (heightIncludingScrollbar != -1)
         return std::max<LayoutUnit>(0, adjustContentBoxLogicalHeightForBoxSizing(heightIncludingScrollbar) - scrollbarLogicalHeight());
 
@@ -3689,7 +3712,7 @@ void RenderBox::computePositionedLogicalHeight(LogicalExtentComputedValues& comp
     }
 
     // Calculate constraint equation values for 'min-height' case.
-    if (!styleToUse.logicalMinHeight().isZero()) {
+    if (!styleToUse.logicalMinHeight().isZero() || styleToUse.logicalMinHeight().isIntrinsic()) {
         LogicalExtentComputedValues minValues;
 
         computePositionedLogicalHeightUsing(styleToUse.logicalMinHeight(), containerBlock, containerLogicalHeight, bordersPlusPadding, logicalHeight,
@@ -3763,18 +3786,22 @@ void RenderBox::computePositionedLogicalHeightUsing(Length logicalHeightLength,
     const LayoutUnit containerRelativeLogicalWidth = containingBlockLogicalWidthForPositioned(containerBlock, nullptr, false);
 
     LayoutUnit logicalTopValue = 0;
-    LayoutUnit resolvedLogicalHeight = 0;
 
     bool logicalHeightIsAuto = logicalHeightLength.isAuto();
     bool logicalTopIsAuto = logicalTop.isAuto();
     bool logicalBottomIsAuto = logicalBottom.isAuto();
 
     // Height is never unsolved for tables.
+    LayoutUnit resolvedLogicalHeight;
     if (isTable()) {
         resolvedLogicalHeight = contentLogicalHeight;
         logicalHeightIsAuto = false;
-    } else
-        resolvedLogicalHeight = adjustContentBoxLogicalHeightForBoxSizing(valueForLength(logicalHeightLength, containerLogicalHeight));
+    } else {
+        if (logicalHeightLength.isIntrinsic())
+            resolvedLogicalHeight = computeIntrinsicLogicalContentHeightUsing(logicalHeightLength, contentLogicalHeight, bordersPlusPadding);
+        else
+            resolvedLogicalHeight = adjustContentBoxLogicalHeightForBoxSizing(valueForLength(logicalHeightLength, containerLogicalHeight));
+    }
 
     if (!logicalTopIsAuto && !logicalHeightIsAuto && !logicalBottomIsAuto) {
         /*-----------------------------------------------------------------------*\
index 2a8e992..e8f3e18 100644 (file)
@@ -87,8 +87,8 @@ public:
     LayoutUnit logicalHeight() const { return style().isHorizontalWritingMode() ? height() : width(); }
 
     LayoutUnit constrainLogicalWidthInRegionByMinMax(LayoutUnit, LayoutUnit, RenderBlock*, RenderRegion* = nullptr) const;
-    LayoutUnit constrainLogicalHeightByMinMax(LayoutUnit) const;
-    LayoutUnit constrainContentBoxLogicalHeightByMinMax(LayoutUnit) const;
+    LayoutUnit constrainLogicalHeightByMinMax(LayoutUnit logicalHeight, LayoutUnit intrinsicContentHeight) const;
+    LayoutUnit constrainContentBoxLogicalHeightByMinMax(LayoutUnit logicalHeight, LayoutUnit intrinsicContentHeight) const;
 
     int pixelSnappedLogicalHeight() const { return style().isHorizontalWritingMode() ? pixelSnappedSize().height() : pixelSnappedSize().width(); }
     int pixelSnappedLogicalWidth() const { return style().isHorizontalWritingMode() ? pixelSnappedSize().width() : pixelSnappedSize().height(); }
@@ -432,9 +432,9 @@ public:
     LayoutUnit shrinkLogicalWidthToAvoidFloats(LayoutUnit childMarginStart, LayoutUnit childMarginEnd, const RenderBlock* cb, RenderRegion*) const;
 
     LayoutUnit computeLogicalWidthInRegionUsing(SizeType, Length logicalWidth, LayoutUnit availableLogicalWidth, const RenderBlock* containingBlock, RenderRegion*) const;
-    LayoutUnit computeLogicalHeightUsing(const Length& height) const;
-    LayoutUnit computeContentLogicalHeight(const Length& height) const;
-    LayoutUnit computeContentAndScrollbarLogicalHeightUsing(const Length& height) const;
+    LayoutUnit computeLogicalHeightUsing(const Length& height, LayoutUnit intrinsicContentHeight) const;
+    LayoutUnit computeContentLogicalHeight(const Length& height, LayoutUnit intrinsicContentHeight) const;
+    LayoutUnit computeContentAndScrollbarLogicalHeightUsing(const Length& height, LayoutUnit intrinsicContentHeight) const;
     LayoutUnit computeReplacedLogicalWidthUsing(Length width) const;
     LayoutUnit computeReplacedLogicalWidthRespectingMinMaxWidth(LayoutUnit logicalWidth, ShouldComputePreferred  = ComputeActual) const;
     LayoutUnit computeReplacedLogicalHeightUsing(Length height) const;
@@ -655,6 +655,7 @@ protected:
     void computePositionedLogicalWidth(LogicalExtentComputedValues&, RenderRegion* = nullptr) const;
 
     LayoutUnit computeIntrinsicLogicalWidthUsing(Length logicalWidthLength, LayoutUnit availableLogicalWidth, LayoutUnit borderAndPadding) const;
+    LayoutUnit computeIntrinsicLogicalContentHeightUsing(Length logicalHeightLength, LayoutUnit intrinsicContentHeight, LayoutUnit borderAndPadding) const;
     
     virtual bool shouldComputeSizeAsReplaced() const { return isReplaced() && !isInlineBlockOrInlineTable(); }
 
index 0d5a036..183ccd7 100644 (file)
@@ -451,11 +451,12 @@ LayoutUnit RenderFlexibleBox::computeMainAxisExtentForChild(RenderBox& child, Si
 {
     // FIXME: This is wrong for orthogonal flows. It should use the flexbox's writing-mode, not the child's in order
     // to figure out the logical height/width.
-    // FIXME: This is wrong if the height is set to an intrinsic keyword value. computeContentLogicalHeight will return -1.
-    // Instead, we need to layout the child an get the appropriate height value.
-    // https://bugs.webkit.org/show_bug.cgi?id=113610
-    if (isColumnFlow())
-        return child.computeContentLogicalHeight(size);
+    if (isColumnFlow()) {
+        // We don't have to check for "auto" here - computeContentLogicalHeight will just return -1 for that case anyway.
+        if (size.isIntrinsic())
+            child.layoutIfNeeded();
+        return child.computeContentLogicalHeight(size, child.logicalHeight() - child.borderAndPaddingLogicalHeight());
+    }
     // FIXME: Figure out how this should work for regions and pass in the appropriate values.
     RenderRegion* region = nullptr;
     return child.computeLogicalWidthInRegionUsing(sizeType, size, contentLogicalWidth(), this, region) - child.borderAndPaddingLogicalWidth();
@@ -1336,7 +1337,8 @@ void RenderFlexibleBox::applyStretchAlignmentToChild(RenderBox& child, LayoutUni
         // FIXME: If the child has orthogonal flow, then it already has an override height set, so use it.
         if (!hasOrthogonalFlow(child)) {
             LayoutUnit stretchedLogicalHeight = child.logicalHeight() + availableAlignmentSpaceForChild(lineCrossAxisExtent, child);
-            LayoutUnit desiredLogicalHeight = child.constrainLogicalHeightByMinMax(stretchedLogicalHeight);
+            ASSERT(!child.needsLayout());
+            LayoutUnit desiredLogicalHeight = child.constrainLogicalHeightByMinMax(stretchedLogicalHeight, child.logicalHeight() - child.borderAndPaddingLogicalHeight());
 
             // FIXME: Can avoid laying out here in some cases. See https://webkit.org/b/87905.
             if (desiredLogicalHeight != child.logicalHeight()) {
index c2a3d78..ddbf3ac 100644 (file)
@@ -1094,7 +1094,7 @@ bool RenderFlowThread::addForcedRegionBreak(const RenderBlock* block, LayoutUnit
         hasComputedAutoHeight = true;
 
         // Compute the region height pretending that the offsetBreakInCurrentRegion is the logicalHeight for the auto-height region.
-        LayoutUnit regionComputedAutoHeight = namedFlowFragment.constrainContentBoxLogicalHeightByMinMax(offsetBreakInCurrentRegion);
+        LayoutUnit regionComputedAutoHeight = namedFlowFragment.constrainContentBoxLogicalHeightByMinMax(offsetBreakInCurrentRegion, -1);
 
         // The new height of this region needs to be smaller than the initial value, the max height. A forced break is the only way to change the initial
         // height of an auto-height region besides content ending.
index f2a8f2d..75e6615 100644 (file)
@@ -469,7 +469,7 @@ LayoutUnit RenderGrid::computeUsedBreadthOfMaxLength(GridTrackSizingDirection di
 LayoutUnit RenderGrid::computeUsedBreadthOfSpecifiedLength(GridTrackSizingDirection direction, const Length& trackLength) const
 {
     ASSERT(trackLength.isSpecified());
-    return valueForLength(trackLength, direction == ForColumns ? logicalWidth() : std::max(LayoutUnit(), computeContentLogicalHeight(style().logicalHeight())));
+    return valueForLength(trackLength, direction == ForColumns ? logicalWidth() : std::max(LayoutUnit(), computeContentLogicalHeight(style().logicalHeight(), -1)));
 }
 
 double RenderGrid::computeNormalizedFractionBreadth(Vector<GridTrack>& tracks, const GridSpan& tracksSpan, GridTrackSizingDirection direction, LayoutUnit spaceToFill) const
@@ -1306,7 +1306,7 @@ void RenderGrid::applyStretchAlignmentToChildIfNeeded(RenderBox& child, LayoutUn
     // FIXME: grid track sizing and positioning do not support orthogonal modes yet.
     if (!hasOrthogonalWritingMode) {
         LayoutUnit stretchedLogicalHeight = availableAlignmentSpaceForChildBeforeStretching(gridAreaBreadthForChild, child);
-        LayoutUnit desiredLogicalHeight = child.constrainLogicalHeightByMinMax(stretchedLogicalHeight);
+        LayoutUnit desiredLogicalHeight = child.constrainLogicalHeightByMinMax(stretchedLogicalHeight, -1);
 
         // FIXME: Can avoid laying out here in some cases. See https://webkit.org/b/87905.
         bool childNeedsRelayout = desiredLogicalHeight != child.logicalHeight();
index 821e4b9..2091b5b 100644 (file)
@@ -415,7 +415,7 @@ LayoutUnit RenderMultiColumnSet::calculateMaxColumnHeight() const
     LayoutUnit availableHeight = multiColumnFlowThread()->columnHeightAvailable();
     LayoutUnit maxColumnHeight = availableHeight ? availableHeight : RenderFlowThread::maxLogicalHeight();
     if (!multicolStyle.logicalMaxHeight().isUndefined()) {
-        LayoutUnit logicalMaxHeight = multicolBlock->computeContentLogicalHeight(multicolStyle.logicalMaxHeight());
+        LayoutUnit logicalMaxHeight = multicolBlock->computeContentLogicalHeight(multicolStyle.logicalMaxHeight(), -1);
         if (logicalMaxHeight != -1 && maxColumnHeight > logicalMaxHeight)
             maxColumnHeight = logicalMaxHeight;
     }
index fb16c0d..bdcd3d8 100644 (file)
@@ -282,6 +282,9 @@ bool RenderReplaced::hasReplacedLogicalHeight() const
         return true;
     }
 
+    if (style().logicalHeight().isIntrinsic())
+        return true;
+
     return false;
 }
 
index 08c0427..64e029a 100644 (file)
@@ -357,19 +357,22 @@ LayoutUnit RenderTable::convertStyleLogicalWidthToComputedWidth(const Length& st
 
 LayoutUnit RenderTable::convertStyleLogicalHeightToComputedHeight(const Length& styleLogicalHeight)
 {
+    LayoutUnit borderAndPaddingBefore = borderBefore() + (collapseBorders() ? LayoutUnit() : paddingBefore());
+    LayoutUnit borderAndPaddingAfter = borderAfter() + (collapseBorders() ? LayoutUnit() : paddingAfter());
+    LayoutUnit borderAndPadding = borderAndPaddingBefore + borderAndPaddingAfter;
     LayoutUnit computedLogicalHeight = 0;
     if (styleLogicalHeight.isFixed()) {
         // HTML tables size as though CSS height includes border/padding, CSS tables do not.
         LayoutUnit borders = LayoutUnit();
         // FIXME: We cannot apply box-sizing: content-box on <table> which other browsers allow.
         if (is<HTMLTableElement>(element()) || style().boxSizing() == BORDER_BOX) {
-            LayoutUnit borderAndPaddingBefore = borderBefore() + (collapseBorders() ? LayoutUnit() : paddingBefore());
-            LayoutUnit borderAndPaddingAfter = borderAfter() + (collapseBorders() ? LayoutUnit() : paddingAfter());
-            borders = borderAndPaddingBefore + borderAndPaddingAfter;
+            borders = borderAndPadding;
         }
         computedLogicalHeight = styleLogicalHeight.value() - borders;
     } else if (styleLogicalHeight.isPercentOrCalculated())
         computedLogicalHeight = computePercentageLogicalHeight(styleLogicalHeight);
+    else if (styleLogicalHeight.isIntrinsic())
+        computedLogicalHeight = computeIntrinsicLogicalContentHeightUsing(styleLogicalHeight, logicalHeight() - borderAndPadding, borderAndPadding);
     else
         ASSERT_NOT_REACHED();
     return std::max<LayoutUnit>(0, computedLogicalHeight);
@@ -502,17 +505,17 @@ void RenderTable::layout()
     LayoutUnit computedLogicalHeight = 0;
     
     Length logicalHeightLength = style().logicalHeight();
-    if (logicalHeightLength.isSpecified() && logicalHeightLength.isPositive())
+    if (logicalHeightLength.isIntrinsic() || (logicalHeightLength.isSpecified() && logicalHeightLength.isPositive()))
         computedLogicalHeight = convertStyleLogicalHeightToComputedHeight(logicalHeightLength);
     
     Length logicalMaxHeightLength = style().logicalMaxHeight();
-    if (logicalMaxHeightLength.isSpecified() && !logicalMaxHeightLength.isNegative()) {
+    if (logicalMaxHeightLength.isIntrinsic() || (logicalMaxHeightLength.isSpecified() && !logicalMaxHeightLength.isNegative())) {
         LayoutUnit computedMaxLogicalHeight = convertStyleLogicalHeightToComputedHeight(logicalMaxHeightLength);
         computedLogicalHeight = std::min(computedLogicalHeight, computedMaxLogicalHeight);
     }
 
     Length logicalMinHeightLength = style().logicalMinHeight();
-    if (logicalMinHeightLength.isSpecified() && !logicalMinHeightLength.isNegative()) {
+    if (logicalMinHeightLength.isIntrinsic() || (logicalMinHeightLength.isSpecified() && !logicalMinHeightLength.isNegative())) {
         LayoutUnit computedMinLogicalHeight = convertStyleLogicalHeightToComputedHeight(logicalMinHeightLength);
         computedLogicalHeight = std::max(computedLogicalHeight, computedMinLogicalHeight);
     }