Source/WebCore: Add support for fixed and percent min-width on the table element...
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 1 Feb 2012 19:38:23 +0000 (19:38 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 1 Feb 2012 19:38:23 +0000 (19:38 +0000)
match Firefox and Opera's behavior.

In FixedTableLayout.cpp, the computePreferredLogicalWidths method looks like it has
issues based on the comment: "FIXME: This entire calculation is incorrect for both
minwidth and maxwidth." (minwidth and maxwidth refer to the preferred widths, not the
min-width and max-width styles). I have not implemented min-width for FixedTableLayout
in this patch since it requires some more research around that comment.

min-width and max-width on the table element was discussed on the www-style list:
http://lists.w3.org/Archives/Public/www-style/2012Jan/0684.html

min-width is not implemented on <table> for table-layout: auto
https://bugs.webkit.org/show_bug.cgi?id=76553

Patch by Max Vujovic <mvujovic@adobe.com> on 2012-02-01
Reviewed by Julien Chaffraix.

Test: fast/table/min-width.html

* rendering/AutoTableLayout.cpp:
(WebCore::AutoTableLayout::computePreferredLogicalWidths):

    If the min or max preferred logical width is less than a fixed min width style, it is
    set to the fixed min width style. Like a percent width style, a percent min-width style
    does not affect the min or max preferred logical widths computed by the table layout
    algorithm. RenderTable's computeLogicalWidth method handles percent min-width styles.

    min-width for the table-layout: fixed case has been split out into this bug:
    https://bugs.webkit.org/show_bug.cgi?id=76948

* rendering/RenderTable.cpp:
(WebCore::RenderTable::computeLogicalWidth):

    If the RenderStyle's logical min width is defined and greater than the logical width
    calculation, this method sets the logical width to the logical min width.

(WebCore::RenderTable::convertStyleWidthToComputedWidth):

    This new method generalizes and factors out logic from RenderTable::computeLogicalWidth
    that converted the width style to a computed value in the fixed and percent case.
    RenderTable::computeLogicalWidth now calls this method to determine the computed values
    for both the width style and the min-width style. In the future, it can also be used for
    the max-width style.

    Note that this method handles the special CSS table case, which requires borders and
    paddings to be included in the computed width calculation. This applies to all width
    styles, including width, min-width, and max-width. Before, this special case was handled
    in RenderTable::computeLogicalWidth.

* rendering/RenderTable.h:

LayoutTests: Add support for min-width on the table element.

min-width is not implemented on <table> for table-layout: auto
https://bugs.webkit.org/show_bug.cgi?id=76553

Patch by Max Vujovic <mvujovic@adobe.com> on 2012-02-01
Reviewed by Julien Chaffraix.

* fast/table/min-width-css-block-table.html: Added.
* fast/table/min-width-css-block-table-expected.txt: Added.
* fast/table/min-width-css-inline-table.html: Added.
* fast/table/min-width-css-inline-table-expected.txt: Added.
* fast/table/min-width-html-block-table.html: Added.
* fast/table/min-width-html-block-table-expected.txt: Added.
* fast/table/min-width-html-inline-table.html: Added.
* fast/table/min-width-html-inline-table-expected.txt: Added.
* fast/table/script-tests/min-width-css-block-table.js: Added.
(computeLogicalWidth):
* fast/table/script-tests/min-width-css-inline-table.js: Added.
(computeLogicalWidth):
* fast/table/script-tests/min-width-helpers.js: Added.
(runTests):
(createTableStyle):
(computeLogicalWidthHelper):
(createSpan):
* fast/table/script-tests/min-width-html-block-table.js: Added.
(computeLogicalWidth):
* fast/table/script-tests/min-width-html-inline-table.js: Added.
(computeLogicalWidth):

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

19 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/table/min-width-css-block-table-expected.txt [new file with mode: 0644]
LayoutTests/fast/table/min-width-css-block-table.html [new file with mode: 0644]
LayoutTests/fast/table/min-width-css-inline-table-expected.txt [new file with mode: 0644]
LayoutTests/fast/table/min-width-css-inline-table.html [new file with mode: 0644]
LayoutTests/fast/table/min-width-html-block-table-expected.txt [new file with mode: 0644]
LayoutTests/fast/table/min-width-html-block-table.html [new file with mode: 0644]
LayoutTests/fast/table/min-width-html-inline-table-expected.txt [new file with mode: 0644]
LayoutTests/fast/table/min-width-html-inline-table.html [new file with mode: 0644]
LayoutTests/fast/table/resources/min-width.css [new file with mode: 0644]
LayoutTests/fast/table/script-tests/min-width-css-block-table.js [new file with mode: 0644]
LayoutTests/fast/table/script-tests/min-width-css-inline-table.js [new file with mode: 0644]
LayoutTests/fast/table/script-tests/min-width-helpers.js [new file with mode: 0644]
LayoutTests/fast/table/script-tests/min-width-html-block-table.js [new file with mode: 0644]
LayoutTests/fast/table/script-tests/min-width-html-inline-table.js [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/rendering/AutoTableLayout.cpp
Source/WebCore/rendering/RenderTable.cpp
Source/WebCore/rendering/RenderTable.h

index dab31eb..e5ccb64 100644 (file)
@@ -1,3 +1,34 @@
+2012-02-01  Max Vujovic  <mvujovic@adobe.com>
+
+        Add support for min-width on the table element.
+
+        min-width is not implemented on <table> for table-layout: auto
+        https://bugs.webkit.org/show_bug.cgi?id=76553
+
+        Reviewed by Julien Chaffraix.
+
+        * fast/table/min-width-css-block-table.html: Added.
+        * fast/table/min-width-css-block-table-expected.txt: Added.
+        * fast/table/min-width-css-inline-table.html: Added.
+        * fast/table/min-width-css-inline-table-expected.txt: Added.
+        * fast/table/min-width-html-block-table.html: Added.
+        * fast/table/min-width-html-block-table-expected.txt: Added.
+        * fast/table/min-width-html-inline-table.html: Added.
+        * fast/table/min-width-html-inline-table-expected.txt: Added.
+        * fast/table/script-tests/min-width-css-block-table.js: Added.
+        (computeLogicalWidth):
+        * fast/table/script-tests/min-width-css-inline-table.js: Added.
+        (computeLogicalWidth):
+        * fast/table/script-tests/min-width-helpers.js: Added.
+        (runTests):
+        (createTableStyle):
+        (computeLogicalWidthHelper):
+        (createSpan):
+        * fast/table/script-tests/min-width-html-block-table.js: Added.
+        (computeLogicalWidth):
+        * fast/table/script-tests/min-width-html-inline-table.js: Added.
+        (computeLogicalWidth):
+
 2012-02-01  Brian Salomon  <bsalomon@google.com>
 
         [SKIA/CHROMIUM] Perform getImageData format conversions using Skia
diff --git a/LayoutTests/fast/table/min-width-css-block-table-expected.txt b/LayoutTests/fast/table/min-width-css-block-table-expected.txt
new file mode 100644 (file)
index 0000000..6f35b83
--- /dev/null
@@ -0,0 +1,98 @@
+This test checks that the min-width style is applied to block CSS tables.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+======== General notes ========
+
+The stylesheet used to style the table in each test is available at: LayoutTests/fast/table/resources/min-width.css
+
+Most importantly, note that each table has:
+- minimum intrinsic width and height both equal to 100px based on the table content
+- maximum intrinsic width and height both equal to 250px based on the table content
+- borders and paddings that add up to 30px in both the horizontal and vertical directions
+- a parent whose dimensions are 1000px by 1000px
+
+The function signature of computeLogicalWidth is:
+function computeLogicalWidth(writingMode, direction, tableStyle)
+
+======== Test horizontal writing mode ========
+
+==== Test ltr direction ====
+
+PASS computeLogicalWidth('horizontal', 'ltr', 'min-width: 500px;') is '500px'
+PASS computeLogicalWidth('horizontal', 'ltr', 'min-width: 150px;') is '250px'
+PASS computeLogicalWidth('horizontal', 'ltr', 'min-width: 50px;') is '250px'
+PASS computeLogicalWidth('horizontal', 'ltr', 'width: 600px; min-width: 500px;') is '600px'
+PASS computeLogicalWidth('horizontal', 'ltr', 'width: 400px; min-width: 500px;') is '500px'
+PASS computeLogicalWidth('horizontal', 'ltr', 'width: 60%; min-width: 500px;') is '570px'
+PASS computeLogicalWidth('horizontal', 'ltr', 'width: 40%; min-width: 500px;') is '500px'
+PASS computeLogicalWidth('horizontal', 'ltr', 'min-width: 50%;') is '470px'
+PASS computeLogicalWidth('horizontal', 'ltr', 'min-width: 15%;') is '250px'
+PASS computeLogicalWidth('horizontal', 'ltr', 'min-width: 5%;') is '250px'
+PASS computeLogicalWidth('horizontal', 'ltr', 'width: 600px; min-width: 50%;') is '600px'
+PASS computeLogicalWidth('horizontal', 'ltr', 'width: 400px; min-width: 50%;') is '470px'
+PASS computeLogicalWidth('horizontal', 'ltr', 'width: 60%; min-width: 50%;') is '570px'
+PASS computeLogicalWidth('horizontal', 'ltr', 'width: 40%; min-width: 50%;') is '470px'
+PASS computeLogicalWidth('horizontal', 'ltr', 'min-width: auto;') is '250px'
+
+==== Test rtl direction ====
+
+PASS computeLogicalWidth('horizontal', 'rtl', 'min-width: 500px;') is '500px'
+PASS computeLogicalWidth('horizontal', 'rtl', 'min-width: 150px;') is '250px'
+PASS computeLogicalWidth('horizontal', 'rtl', 'min-width: 50px;') is '250px'
+PASS computeLogicalWidth('horizontal', 'rtl', 'width: 600px; min-width: 500px;') is '600px'
+PASS computeLogicalWidth('horizontal', 'rtl', 'width: 400px; min-width: 500px;') is '500px'
+PASS computeLogicalWidth('horizontal', 'rtl', 'width: 60%; min-width: 500px;') is '570px'
+PASS computeLogicalWidth('horizontal', 'rtl', 'width: 40%; min-width: 500px;') is '500px'
+PASS computeLogicalWidth('horizontal', 'rtl', 'min-width: 50%;') is '470px'
+PASS computeLogicalWidth('horizontal', 'rtl', 'min-width: 15%;') is '250px'
+PASS computeLogicalWidth('horizontal', 'rtl', 'min-width: 5%;') is '250px'
+PASS computeLogicalWidth('horizontal', 'rtl', 'width: 600px; min-width: 50%;') is '600px'
+PASS computeLogicalWidth('horizontal', 'rtl', 'width: 400px; min-width: 50%;') is '470px'
+PASS computeLogicalWidth('horizontal', 'rtl', 'width: 60%; min-width: 50%;') is '570px'
+PASS computeLogicalWidth('horizontal', 'rtl', 'width: 40%; min-width: 50%;') is '470px'
+PASS computeLogicalWidth('horizontal', 'rtl', 'min-width: auto;') is '250px'
+
+======== Test vertical writing mode ========
+
+==== Test ltr direction ====
+
+PASS computeLogicalWidth('vertical', 'ltr', 'min-height: 500px;') is '500px'
+PASS computeLogicalWidth('vertical', 'ltr', 'min-height: 150px;') is '250px'
+PASS computeLogicalWidth('vertical', 'ltr', 'min-height: 50px;') is '250px'
+PASS computeLogicalWidth('vertical', 'ltr', 'height: 600px; min-height: 500px;') is '600px'
+PASS computeLogicalWidth('vertical', 'ltr', 'height: 400px; min-height: 500px;') is '500px'
+PASS computeLogicalWidth('vertical', 'ltr', 'height: 60%; min-height: 500px;') is '570px'
+PASS computeLogicalWidth('vertical', 'ltr', 'height: 40%; min-height: 500px;') is '500px'
+PASS computeLogicalWidth('vertical', 'ltr', 'min-height: 50%;') is '470px'
+PASS computeLogicalWidth('vertical', 'ltr', 'min-height: 15%;') is '250px'
+PASS computeLogicalWidth('vertical', 'ltr', 'min-height: 5%;') is '250px'
+PASS computeLogicalWidth('vertical', 'ltr', 'height: 600px; min-height: 50%;') is '600px'
+PASS computeLogicalWidth('vertical', 'ltr', 'height: 400px; min-height: 50%;') is '470px'
+PASS computeLogicalWidth('vertical', 'ltr', 'height: 60%; min-height: 50%;') is '570px'
+PASS computeLogicalWidth('vertical', 'ltr', 'height: 40%; min-height: 50%;') is '470px'
+PASS computeLogicalWidth('vertical', 'ltr', 'min-height: auto;') is '250px'
+
+==== Test rtl direction ====
+
+PASS computeLogicalWidth('vertical', 'rtl', 'min-height: 500px;') is '500px'
+PASS computeLogicalWidth('vertical', 'rtl', 'min-height: 150px;') is '250px'
+PASS computeLogicalWidth('vertical', 'rtl', 'min-height: 50px;') is '250px'
+PASS computeLogicalWidth('vertical', 'rtl', 'height: 600px; min-height: 500px;') is '600px'
+PASS computeLogicalWidth('vertical', 'rtl', 'height: 400px; min-height: 500px;') is '500px'
+PASS computeLogicalWidth('vertical', 'rtl', 'height: 60%; min-height: 500px;') is '570px'
+PASS computeLogicalWidth('vertical', 'rtl', 'height: 40%; min-height: 500px;') is '500px'
+PASS computeLogicalWidth('vertical', 'rtl', 'min-height: 50%;') is '470px'
+PASS computeLogicalWidth('vertical', 'rtl', 'min-height: 15%;') is '250px'
+PASS computeLogicalWidth('vertical', 'rtl', 'min-height: 5%;') is '250px'
+PASS computeLogicalWidth('vertical', 'rtl', 'height: 600px; min-height: 50%;') is '600px'
+PASS computeLogicalWidth('vertical', 'rtl', 'height: 400px; min-height: 50%;') is '470px'
+PASS computeLogicalWidth('vertical', 'rtl', 'height: 60%; min-height: 50%;') is '570px'
+PASS computeLogicalWidth('vertical', 'rtl', 'height: 40%; min-height: 50%;') is '470px'
+PASS computeLogicalWidth('vertical', 'rtl', 'min-height: auto;') is '250px'
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/table/min-width-css-block-table.html b/LayoutTests/fast/table/min-width-css-block-table.html
new file mode 100644 (file)
index 0000000..4f7d1c4
--- /dev/null
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <link href="resources/min-width.css" rel="stylesheet" type="text/css">
+        <script src="../js/resources/js-test-pre.js"></script>
+        <script src="script-tests/min-width-helpers.js"></script>
+    </head>
+    <body>
+        <script src="script-tests/min-width-css-block-table.js"></script>
+        <script src="../js/resources/js-test-post.js"></script>
+    </body>
+</html>
diff --git a/LayoutTests/fast/table/min-width-css-inline-table-expected.txt b/LayoutTests/fast/table/min-width-css-inline-table-expected.txt
new file mode 100644 (file)
index 0000000..60d345a
--- /dev/null
@@ -0,0 +1,98 @@
+This test checks that the min-width style is applied to inline CSS tables.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+======== General notes ========
+
+The stylesheet used to style the table in each test is available at: LayoutTests/fast/table/resources/min-width.css
+
+Most importantly, note that each table has:
+- minimum intrinsic width and height both equal to 100px based on the table content
+- maximum intrinsic width and height both equal to 250px based on the table content
+- borders and paddings that add up to 30px in both the horizontal and vertical directions
+- a parent whose dimensions are 1000px by 1000px
+
+The function signature of computeLogicalWidth is:
+function computeLogicalWidth(writingMode, direction, tableStyle)
+
+======== Test horizontal writing mode ========
+
+==== Test ltr direction ====
+
+PASS computeLogicalWidth('horizontal', 'ltr', 'min-width: 500px;') is '500px'
+PASS computeLogicalWidth('horizontal', 'ltr', 'min-width: 150px;') is '250px'
+PASS computeLogicalWidth('horizontal', 'ltr', 'min-width: 50px;') is '250px'
+PASS computeLogicalWidth('horizontal', 'ltr', 'width: 600px; min-width: 500px;') is '600px'
+PASS computeLogicalWidth('horizontal', 'ltr', 'width: 400px; min-width: 500px;') is '500px'
+PASS computeLogicalWidth('horizontal', 'ltr', 'width: 60%; min-width: 500px;') is '570px'
+PASS computeLogicalWidth('horizontal', 'ltr', 'width: 40%; min-width: 500px;') is '500px'
+PASS computeLogicalWidth('horizontal', 'ltr', 'min-width: 50%;') is '470px'
+PASS computeLogicalWidth('horizontal', 'ltr', 'min-width: 15%;') is '250px'
+PASS computeLogicalWidth('horizontal', 'ltr', 'min-width: 5%;') is '250px'
+PASS computeLogicalWidth('horizontal', 'ltr', 'width: 600px; min-width: 50%;') is '600px'
+PASS computeLogicalWidth('horizontal', 'ltr', 'width: 400px; min-width: 50%;') is '470px'
+PASS computeLogicalWidth('horizontal', 'ltr', 'width: 60%; min-width: 50%;') is '570px'
+PASS computeLogicalWidth('horizontal', 'ltr', 'width: 40%; min-width: 50%;') is '470px'
+PASS computeLogicalWidth('horizontal', 'ltr', 'min-width: auto;') is '250px'
+
+==== Test rtl direction ====
+
+PASS computeLogicalWidth('horizontal', 'rtl', 'min-width: 500px;') is '500px'
+PASS computeLogicalWidth('horizontal', 'rtl', 'min-width: 150px;') is '250px'
+PASS computeLogicalWidth('horizontal', 'rtl', 'min-width: 50px;') is '250px'
+PASS computeLogicalWidth('horizontal', 'rtl', 'width: 600px; min-width: 500px;') is '600px'
+PASS computeLogicalWidth('horizontal', 'rtl', 'width: 400px; min-width: 500px;') is '500px'
+PASS computeLogicalWidth('horizontal', 'rtl', 'width: 60%; min-width: 500px;') is '570px'
+PASS computeLogicalWidth('horizontal', 'rtl', 'width: 40%; min-width: 500px;') is '500px'
+PASS computeLogicalWidth('horizontal', 'rtl', 'min-width: 50%;') is '470px'
+PASS computeLogicalWidth('horizontal', 'rtl', 'min-width: 15%;') is '250px'
+PASS computeLogicalWidth('horizontal', 'rtl', 'min-width: 5%;') is '250px'
+PASS computeLogicalWidth('horizontal', 'rtl', 'width: 600px; min-width: 50%;') is '600px'
+PASS computeLogicalWidth('horizontal', 'rtl', 'width: 400px; min-width: 50%;') is '470px'
+PASS computeLogicalWidth('horizontal', 'rtl', 'width: 60%; min-width: 50%;') is '570px'
+PASS computeLogicalWidth('horizontal', 'rtl', 'width: 40%; min-width: 50%;') is '470px'
+PASS computeLogicalWidth('horizontal', 'rtl', 'min-width: auto;') is '250px'
+
+======== Test vertical writing mode ========
+
+==== Test ltr direction ====
+
+PASS computeLogicalWidth('vertical', 'ltr', 'min-height: 500px;') is '500px'
+PASS computeLogicalWidth('vertical', 'ltr', 'min-height: 150px;') is '250px'
+PASS computeLogicalWidth('vertical', 'ltr', 'min-height: 50px;') is '250px'
+PASS computeLogicalWidth('vertical', 'ltr', 'height: 600px; min-height: 500px;') is '600px'
+PASS computeLogicalWidth('vertical', 'ltr', 'height: 400px; min-height: 500px;') is '500px'
+PASS computeLogicalWidth('vertical', 'ltr', 'height: 60%; min-height: 500px;') is '570px'
+PASS computeLogicalWidth('vertical', 'ltr', 'height: 40%; min-height: 500px;') is '500px'
+PASS computeLogicalWidth('vertical', 'ltr', 'min-height: 50%;') is '470px'
+PASS computeLogicalWidth('vertical', 'ltr', 'min-height: 15%;') is '250px'
+PASS computeLogicalWidth('vertical', 'ltr', 'min-height: 5%;') is '250px'
+PASS computeLogicalWidth('vertical', 'ltr', 'height: 600px; min-height: 50%;') is '600px'
+PASS computeLogicalWidth('vertical', 'ltr', 'height: 400px; min-height: 50%;') is '470px'
+PASS computeLogicalWidth('vertical', 'ltr', 'height: 60%; min-height: 50%;') is '570px'
+PASS computeLogicalWidth('vertical', 'ltr', 'height: 40%; min-height: 50%;') is '470px'
+PASS computeLogicalWidth('vertical', 'ltr', 'min-height: auto;') is '250px'
+
+==== Test rtl direction ====
+
+PASS computeLogicalWidth('vertical', 'rtl', 'min-height: 500px;') is '500px'
+PASS computeLogicalWidth('vertical', 'rtl', 'min-height: 150px;') is '250px'
+PASS computeLogicalWidth('vertical', 'rtl', 'min-height: 50px;') is '250px'
+PASS computeLogicalWidth('vertical', 'rtl', 'height: 600px; min-height: 500px;') is '600px'
+PASS computeLogicalWidth('vertical', 'rtl', 'height: 400px; min-height: 500px;') is '500px'
+PASS computeLogicalWidth('vertical', 'rtl', 'height: 60%; min-height: 500px;') is '570px'
+PASS computeLogicalWidth('vertical', 'rtl', 'height: 40%; min-height: 500px;') is '500px'
+PASS computeLogicalWidth('vertical', 'rtl', 'min-height: 50%;') is '470px'
+PASS computeLogicalWidth('vertical', 'rtl', 'min-height: 15%;') is '250px'
+PASS computeLogicalWidth('vertical', 'rtl', 'min-height: 5%;') is '250px'
+PASS computeLogicalWidth('vertical', 'rtl', 'height: 600px; min-height: 50%;') is '600px'
+PASS computeLogicalWidth('vertical', 'rtl', 'height: 400px; min-height: 50%;') is '470px'
+PASS computeLogicalWidth('vertical', 'rtl', 'height: 60%; min-height: 50%;') is '570px'
+PASS computeLogicalWidth('vertical', 'rtl', 'height: 40%; min-height: 50%;') is '470px'
+PASS computeLogicalWidth('vertical', 'rtl', 'min-height: auto;') is '250px'
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/table/min-width-css-inline-table.html b/LayoutTests/fast/table/min-width-css-inline-table.html
new file mode 100644 (file)
index 0000000..8ca9d70
--- /dev/null
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <link href="resources/min-width.css" rel="stylesheet" type="text/css">
+        <script src="../js/resources/js-test-pre.js"></script>
+        <script src="script-tests/min-width-helpers.js"></script>
+    </head>
+    <body>
+        <script src="script-tests/min-width-css-inline-table.js"></script>
+        <script src="../js/resources/js-test-post.js"></script>
+    </body>
+</html>
diff --git a/LayoutTests/fast/table/min-width-html-block-table-expected.txt b/LayoutTests/fast/table/min-width-html-block-table-expected.txt
new file mode 100644 (file)
index 0000000..47b1ec0
--- /dev/null
@@ -0,0 +1,98 @@
+This test checks that the min-width style is applied to block HTML tables.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+======== General notes ========
+
+The stylesheet used to style the table in each test is available at: LayoutTests/fast/table/resources/min-width.css
+
+Most importantly, note that each table has:
+- minimum intrinsic width and height both equal to 100px based on the table content
+- maximum intrinsic width and height both equal to 250px based on the table content
+- borders and paddings that add up to 30px in both the horizontal and vertical directions
+- a parent whose dimensions are 1000px by 1000px
+
+The function signature of computeLogicalWidth is:
+function computeLogicalWidth(writingMode, direction, tableStyle)
+
+======== Test horizontal writing mode ========
+
+==== Test ltr direction ====
+
+PASS computeLogicalWidth('horizontal', 'ltr', 'min-width: 500px;') is '470px'
+PASS computeLogicalWidth('horizontal', 'ltr', 'min-width: 150px;') is '250px'
+PASS computeLogicalWidth('horizontal', 'ltr', 'min-width: 50px;') is '250px'
+PASS computeLogicalWidth('horizontal', 'ltr', 'width: 600px; min-width: 500px;') is '570px'
+PASS computeLogicalWidth('horizontal', 'ltr', 'width: 400px; min-width: 500px;') is '470px'
+PASS computeLogicalWidth('horizontal', 'ltr', 'width: 60%; min-width: 500px;') is '570px'
+PASS computeLogicalWidth('horizontal', 'ltr', 'width: 40%; min-width: 500px;') is '470px'
+PASS computeLogicalWidth('horizontal', 'ltr', 'min-width: 50%;') is '470px'
+PASS computeLogicalWidth('horizontal', 'ltr', 'min-width: 15%;') is '250px'
+PASS computeLogicalWidth('horizontal', 'ltr', 'min-width: 5%;') is '250px'
+PASS computeLogicalWidth('horizontal', 'ltr', 'width: 600px; min-width: 50%;') is '570px'
+PASS computeLogicalWidth('horizontal', 'ltr', 'width: 400px; min-width: 50%;') is '470px'
+PASS computeLogicalWidth('horizontal', 'ltr', 'width: 60%; min-width: 50%;') is '570px'
+PASS computeLogicalWidth('horizontal', 'ltr', 'width: 40%; min-width: 50%;') is '470px'
+PASS computeLogicalWidth('horizontal', 'ltr', 'min-width: auto;') is '250px'
+
+==== Test rtl direction ====
+
+PASS computeLogicalWidth('horizontal', 'rtl', 'min-width: 500px;') is '470px'
+PASS computeLogicalWidth('horizontal', 'rtl', 'min-width: 150px;') is '250px'
+PASS computeLogicalWidth('horizontal', 'rtl', 'min-width: 50px;') is '250px'
+PASS computeLogicalWidth('horizontal', 'rtl', 'width: 600px; min-width: 500px;') is '570px'
+PASS computeLogicalWidth('horizontal', 'rtl', 'width: 400px; min-width: 500px;') is '470px'
+PASS computeLogicalWidth('horizontal', 'rtl', 'width: 60%; min-width: 500px;') is '570px'
+PASS computeLogicalWidth('horizontal', 'rtl', 'width: 40%; min-width: 500px;') is '470px'
+PASS computeLogicalWidth('horizontal', 'rtl', 'min-width: 50%;') is '470px'
+PASS computeLogicalWidth('horizontal', 'rtl', 'min-width: 15%;') is '250px'
+PASS computeLogicalWidth('horizontal', 'rtl', 'min-width: 5%;') is '250px'
+PASS computeLogicalWidth('horizontal', 'rtl', 'width: 600px; min-width: 50%;') is '570px'
+PASS computeLogicalWidth('horizontal', 'rtl', 'width: 400px; min-width: 50%;') is '470px'
+PASS computeLogicalWidth('horizontal', 'rtl', 'width: 60%; min-width: 50%;') is '570px'
+PASS computeLogicalWidth('horizontal', 'rtl', 'width: 40%; min-width: 50%;') is '470px'
+PASS computeLogicalWidth('horizontal', 'rtl', 'min-width: auto;') is '250px'
+
+======== Test vertical writing mode ========
+
+==== Test ltr direction ====
+
+PASS computeLogicalWidth('vertical', 'ltr', 'min-height: 500px;') is '470px'
+PASS computeLogicalWidth('vertical', 'ltr', 'min-height: 150px;') is '250px'
+PASS computeLogicalWidth('vertical', 'ltr', 'min-height: 50px;') is '250px'
+PASS computeLogicalWidth('vertical', 'ltr', 'height: 600px; min-height: 500px;') is '570px'
+PASS computeLogicalWidth('vertical', 'ltr', 'height: 400px; min-height: 500px;') is '470px'
+PASS computeLogicalWidth('vertical', 'ltr', 'height: 60%; min-height: 500px;') is '570px'
+PASS computeLogicalWidth('vertical', 'ltr', 'height: 40%; min-height: 500px;') is '470px'
+PASS computeLogicalWidth('vertical', 'ltr', 'min-height: 50%;') is '470px'
+PASS computeLogicalWidth('vertical', 'ltr', 'min-height: 15%;') is '250px'
+PASS computeLogicalWidth('vertical', 'ltr', 'min-height: 5%;') is '250px'
+PASS computeLogicalWidth('vertical', 'ltr', 'height: 600px; min-height: 50%;') is '570px'
+PASS computeLogicalWidth('vertical', 'ltr', 'height: 400px; min-height: 50%;') is '470px'
+PASS computeLogicalWidth('vertical', 'ltr', 'height: 60%; min-height: 50%;') is '570px'
+PASS computeLogicalWidth('vertical', 'ltr', 'height: 40%; min-height: 50%;') is '470px'
+PASS computeLogicalWidth('vertical', 'ltr', 'min-height: auto;') is '250px'
+
+==== Test rtl direction ====
+
+PASS computeLogicalWidth('vertical', 'rtl', 'min-height: 500px;') is '470px'
+PASS computeLogicalWidth('vertical', 'rtl', 'min-height: 150px;') is '250px'
+PASS computeLogicalWidth('vertical', 'rtl', 'min-height: 50px;') is '250px'
+PASS computeLogicalWidth('vertical', 'rtl', 'height: 600px; min-height: 500px;') is '570px'
+PASS computeLogicalWidth('vertical', 'rtl', 'height: 400px; min-height: 500px;') is '470px'
+PASS computeLogicalWidth('vertical', 'rtl', 'height: 60%; min-height: 500px;') is '570px'
+PASS computeLogicalWidth('vertical', 'rtl', 'height: 40%; min-height: 500px;') is '470px'
+PASS computeLogicalWidth('vertical', 'rtl', 'min-height: 50%;') is '470px'
+PASS computeLogicalWidth('vertical', 'rtl', 'min-height: 15%;') is '250px'
+PASS computeLogicalWidth('vertical', 'rtl', 'min-height: 5%;') is '250px'
+PASS computeLogicalWidth('vertical', 'rtl', 'height: 600px; min-height: 50%;') is '570px'
+PASS computeLogicalWidth('vertical', 'rtl', 'height: 400px; min-height: 50%;') is '470px'
+PASS computeLogicalWidth('vertical', 'rtl', 'height: 60%; min-height: 50%;') is '570px'
+PASS computeLogicalWidth('vertical', 'rtl', 'height: 40%; min-height: 50%;') is '470px'
+PASS computeLogicalWidth('vertical', 'rtl', 'min-height: auto;') is '250px'
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/table/min-width-html-block-table.html b/LayoutTests/fast/table/min-width-html-block-table.html
new file mode 100644 (file)
index 0000000..c4a1c15
--- /dev/null
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <link href="resources/min-width.css" rel="stylesheet" type="text/css">
+        <script src="../js/resources/js-test-pre.js"></script>
+        <script src="script-tests/min-width-helpers.js"></script>
+    </head>
+    <body>
+        <script src="script-tests/min-width-html-block-table.js"></script>
+        <script src="../js/resources/js-test-post.js"></script>
+    </body>
+</html>
diff --git a/LayoutTests/fast/table/min-width-html-inline-table-expected.txt b/LayoutTests/fast/table/min-width-html-inline-table-expected.txt
new file mode 100644 (file)
index 0000000..4161c6b
--- /dev/null
@@ -0,0 +1,98 @@
+This test checks that the min-width style is applied to inline HTML tables.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+======== General notes ========
+
+The stylesheet used to style the table in each test is available at: LayoutTests/fast/table/resources/min-width.css
+
+Most importantly, note that each table has:
+- minimum intrinsic width and height both equal to 100px based on the table content
+- maximum intrinsic width and height both equal to 250px based on the table content
+- borders and paddings that add up to 30px in both the horizontal and vertical directions
+- a parent whose dimensions are 1000px by 1000px
+
+The function signature of computeLogicalWidth is:
+function computeLogicalWidth(writingMode, direction, tableStyle)
+
+======== Test horizontal writing mode ========
+
+==== Test ltr direction ====
+
+PASS computeLogicalWidth('horizontal', 'ltr', 'min-width: 500px;') is '470px'
+PASS computeLogicalWidth('horizontal', 'ltr', 'min-width: 150px;') is '250px'
+PASS computeLogicalWidth('horizontal', 'ltr', 'min-width: 50px;') is '250px'
+PASS computeLogicalWidth('horizontal', 'ltr', 'width: 600px; min-width: 500px;') is '570px'
+PASS computeLogicalWidth('horizontal', 'ltr', 'width: 400px; min-width: 500px;') is '470px'
+PASS computeLogicalWidth('horizontal', 'ltr', 'width: 60%; min-width: 500px;') is '570px'
+PASS computeLogicalWidth('horizontal', 'ltr', 'width: 40%; min-width: 500px;') is '470px'
+PASS computeLogicalWidth('horizontal', 'ltr', 'min-width: 50%;') is '470px'
+PASS computeLogicalWidth('horizontal', 'ltr', 'min-width: 15%;') is '250px'
+PASS computeLogicalWidth('horizontal', 'ltr', 'min-width: 5%;') is '250px'
+PASS computeLogicalWidth('horizontal', 'ltr', 'width: 600px; min-width: 50%;') is '570px'
+PASS computeLogicalWidth('horizontal', 'ltr', 'width: 400px; min-width: 50%;') is '470px'
+PASS computeLogicalWidth('horizontal', 'ltr', 'width: 60%; min-width: 50%;') is '570px'
+PASS computeLogicalWidth('horizontal', 'ltr', 'width: 40%; min-width: 50%;') is '470px'
+PASS computeLogicalWidth('horizontal', 'ltr', 'min-width: auto;') is '250px'
+
+==== Test rtl direction ====
+
+PASS computeLogicalWidth('horizontal', 'rtl', 'min-width: 500px;') is '470px'
+PASS computeLogicalWidth('horizontal', 'rtl', 'min-width: 150px;') is '250px'
+PASS computeLogicalWidth('horizontal', 'rtl', 'min-width: 50px;') is '250px'
+PASS computeLogicalWidth('horizontal', 'rtl', 'width: 600px; min-width: 500px;') is '570px'
+PASS computeLogicalWidth('horizontal', 'rtl', 'width: 400px; min-width: 500px;') is '470px'
+PASS computeLogicalWidth('horizontal', 'rtl', 'width: 60%; min-width: 500px;') is '570px'
+PASS computeLogicalWidth('horizontal', 'rtl', 'width: 40%; min-width: 500px;') is '470px'
+PASS computeLogicalWidth('horizontal', 'rtl', 'min-width: 50%;') is '470px'
+PASS computeLogicalWidth('horizontal', 'rtl', 'min-width: 15%;') is '250px'
+PASS computeLogicalWidth('horizontal', 'rtl', 'min-width: 5%;') is '250px'
+PASS computeLogicalWidth('horizontal', 'rtl', 'width: 600px; min-width: 50%;') is '570px'
+PASS computeLogicalWidth('horizontal', 'rtl', 'width: 400px; min-width: 50%;') is '470px'
+PASS computeLogicalWidth('horizontal', 'rtl', 'width: 60%; min-width: 50%;') is '570px'
+PASS computeLogicalWidth('horizontal', 'rtl', 'width: 40%; min-width: 50%;') is '470px'
+PASS computeLogicalWidth('horizontal', 'rtl', 'min-width: auto;') is '250px'
+
+======== Test vertical writing mode ========
+
+==== Test ltr direction ====
+
+PASS computeLogicalWidth('vertical', 'ltr', 'min-height: 500px;') is '470px'
+PASS computeLogicalWidth('vertical', 'ltr', 'min-height: 150px;') is '250px'
+PASS computeLogicalWidth('vertical', 'ltr', 'min-height: 50px;') is '250px'
+PASS computeLogicalWidth('vertical', 'ltr', 'height: 600px; min-height: 500px;') is '570px'
+PASS computeLogicalWidth('vertical', 'ltr', 'height: 400px; min-height: 500px;') is '470px'
+PASS computeLogicalWidth('vertical', 'ltr', 'height: 60%; min-height: 500px;') is '570px'
+PASS computeLogicalWidth('vertical', 'ltr', 'height: 40%; min-height: 500px;') is '470px'
+PASS computeLogicalWidth('vertical', 'ltr', 'min-height: 50%;') is '470px'
+PASS computeLogicalWidth('vertical', 'ltr', 'min-height: 15%;') is '250px'
+PASS computeLogicalWidth('vertical', 'ltr', 'min-height: 5%;') is '250px'
+PASS computeLogicalWidth('vertical', 'ltr', 'height: 600px; min-height: 50%;') is '570px'
+PASS computeLogicalWidth('vertical', 'ltr', 'height: 400px; min-height: 50%;') is '470px'
+PASS computeLogicalWidth('vertical', 'ltr', 'height: 60%; min-height: 50%;') is '570px'
+PASS computeLogicalWidth('vertical', 'ltr', 'height: 40%; min-height: 50%;') is '470px'
+PASS computeLogicalWidth('vertical', 'ltr', 'min-height: auto;') is '250px'
+
+==== Test rtl direction ====
+
+PASS computeLogicalWidth('vertical', 'rtl', 'min-height: 500px;') is '470px'
+PASS computeLogicalWidth('vertical', 'rtl', 'min-height: 150px;') is '250px'
+PASS computeLogicalWidth('vertical', 'rtl', 'min-height: 50px;') is '250px'
+PASS computeLogicalWidth('vertical', 'rtl', 'height: 600px; min-height: 500px;') is '570px'
+PASS computeLogicalWidth('vertical', 'rtl', 'height: 400px; min-height: 500px;') is '470px'
+PASS computeLogicalWidth('vertical', 'rtl', 'height: 60%; min-height: 500px;') is '570px'
+PASS computeLogicalWidth('vertical', 'rtl', 'height: 40%; min-height: 500px;') is '470px'
+PASS computeLogicalWidth('vertical', 'rtl', 'min-height: 50%;') is '470px'
+PASS computeLogicalWidth('vertical', 'rtl', 'min-height: 15%;') is '250px'
+PASS computeLogicalWidth('vertical', 'rtl', 'min-height: 5%;') is '250px'
+PASS computeLogicalWidth('vertical', 'rtl', 'height: 600px; min-height: 50%;') is '570px'
+PASS computeLogicalWidth('vertical', 'rtl', 'height: 400px; min-height: 50%;') is '470px'
+PASS computeLogicalWidth('vertical', 'rtl', 'height: 60%; min-height: 50%;') is '570px'
+PASS computeLogicalWidth('vertical', 'rtl', 'height: 40%; min-height: 50%;') is '470px'
+PASS computeLogicalWidth('vertical', 'rtl', 'min-height: auto;') is '250px'
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/table/min-width-html-inline-table.html b/LayoutTests/fast/table/min-width-html-inline-table.html
new file mode 100644 (file)
index 0000000..138a554
--- /dev/null
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <link href="resources/min-width.css" rel="stylesheet" type="text/css">
+        <script src="../js/resources/js-test-pre.js"></script>
+        <script src="script-tests/min-width-helpers.js"></script>
+    </head>
+    <body>
+        <script src="script-tests/min-width-html-inline-table.js"></script>
+        <script src="../js/resources/js-test-post.js"></script>
+    </body>
+</html>
diff --git a/LayoutTests/fast/table/resources/min-width.css b/LayoutTests/fast/table/resources/min-width.css
new file mode 100644 (file)
index 0000000..07755d5
--- /dev/null
@@ -0,0 +1,47 @@
+.table-parent {
+    width: 1000px; 
+    height: 1000px;
+    background-color: #ccc;
+}
+
+.block {
+    display: table;
+}
+
+.inline {
+    display: inline-table;
+}
+
+.block,
+.inline {
+    border-spacing: 0;
+    padding: 10px 10px 10px 10px;
+    border: solid 5px #00f;
+    background-color: #0f0;
+}
+
+.row-group {
+    display: table-row-group;
+}
+
+.row {
+    display: table-row;
+}
+
+.cell {
+    display: table-cell;
+    padding: 0 0 0 0;
+}
+
+.horizontal {}
+
+.vertical {
+    -webkit-writing-mode: vertical-rl;
+    writing-mode: vertical-rl; 
+}
+
+.ltr {}
+
+.rtl {
+    direction: rtl;
+}
diff --git a/LayoutTests/fast/table/script-tests/min-width-css-block-table.js b/LayoutTests/fast/table/script-tests/min-width-css-block-table.js
new file mode 100644 (file)
index 0000000..d522e46
--- /dev/null
@@ -0,0 +1,10 @@
+description("This test checks that the min-width style is applied to block CSS tables.");
+
+// Requires min-width-helpers.js.
+
+function computeLogicalWidth(writingMode, direction, tableStyle)
+{
+    return computeLogicalWidthHelper("css", "block", writingMode, direction, tableStyle);
+}
+
+runTests("css");
diff --git a/LayoutTests/fast/table/script-tests/min-width-css-inline-table.js b/LayoutTests/fast/table/script-tests/min-width-css-inline-table.js
new file mode 100644 (file)
index 0000000..f3c3cf2
--- /dev/null
@@ -0,0 +1,10 @@
+description("This test checks that the min-width style is applied to inline CSS tables.");
+
+// Requires min-width-helpers.js.
+
+function computeLogicalWidth(writingMode, direction, tableStyle)
+{
+    return computeLogicalWidthHelper("css", "inline", writingMode, direction, tableStyle);
+}
+
+runTests("css");
\ No newline at end of file
diff --git a/LayoutTests/fast/table/script-tests/min-width-helpers.js b/LayoutTests/fast/table/script-tests/min-width-helpers.js
new file mode 100644 (file)
index 0000000..c441b72
--- /dev/null
@@ -0,0 +1,135 @@
+var testNotes = "======== General notes ========\n\
+\n\
+The stylesheet used to style the table in each test is available at: <a href=\"resources/min-width.css\">LayoutTests/fast/table/resources/min-width.css</a>\n\
+\n\
+Most importantly, note that each table has:\n\
+- minimum intrinsic width and height both equal to 100px based on the table content\n\
+- maximum intrinsic width and height both equal to 250px based on the table content\n\
+- borders and paddings that add up to 30px in both the horizontal and vertical directions\n\
+- a parent whose dimensions are 1000px by 1000px\n\
+\n\
+The function signature of computeLogicalWidth is:\n\
+function computeLogicalWidth(writingMode, direction, tableStyle)\n";
+
+/* All tables will be generated to have the following intrinsic widths. */
+var minIntrinsicLogicalWidth = 100;
+var maxIntrinsicLogicalWidth = 250;
+
+/* Tests will cover all permutations of the follow properties and settings. */
+var tableTypes = ["html", "css"];
+var displays = ["block", "inline"]
+var writingModes = ["horizontal", "vertical"];
+var directions = ["ltr", "rtl"];
+var logicalWidthsCombinations = [
+    /* fixed min-width, auto width */
+    {"min-width": "500px", "width": null, "computed-width": {"css": "500px", "html": "470px"}},
+    {"min-width": "150px", "width": null, "computed-width": {"css": "250px", "html": "250px"}},
+    {"min-width": "50px", "width": null, "computed-width": {"css": "250px", "html": "250px"}},
+    /* fixed min-width, fixed width */
+    {"min-width": "500px", "width": "600px", "computed-width": {"css": "600px", "html": "570px"}},
+    {"min-width": "500px", "width": "400px", "computed-width": {"css": "500px", "html": "470px"}},
+    /* fixed min-width, percent width */
+    {"min-width": "500px", "width": "60%", "computed-width": {"css": "570px", "html": "570px"}},
+    {"min-width": "500px", "width": "40%", "computed-width": {"css": "500px", "html": "470px"}},
+    /* percent min-width, auto width */
+    {"min-width": "50%", "width": null, "computed-width": {"css": "470px", "html": "470px"}},
+    {"min-width": "15%", "width": null, "computed-width": {"css": "250px", "html": "250px"}},
+    {"min-width": "5%", "width": null, "computed-width": {"css": "250px", "html": "250px"}},
+    /* percent min-width, fixed width */
+    {"min-width": "50%", "width": "600px", "computed-width": {"css": "600px", "html": "570px"}},
+    {"min-width": "50%", "width": "400px", "computed-width": {"css": "470px", "html": "470px"}},
+     /* percent min-width, percent width */
+    {"min-width": "50%", "width": "60%", "computed-width": {"css": "570px", "html": "570px"}},
+    {"min-width": "50%", "width": "40%", "computed-width": {"css": "470px", "html": "470px"}},
+     /* auto min-width (shouldn't affect anything), auto width */
+    {"min-width": "auto", "width": null, "computed-width": {"css": "250px", "html": "250px"}},
+];
+
+function runTests(tableType)
+{
+    debug(testNotes);
+
+    writingModes.forEach(function(writingMode) {
+        debug("======== Test " + writingMode + " writing mode ========\n");
+
+        directions.forEach(function(direction) {
+            debug("==== Test " + direction + " direction ====\n");
+
+            logicalWidthsCombinations.forEach(function(logicalWidthsCombination) {
+                var tableStyle = createTableStyle(writingMode, logicalWidthsCombination);
+                shouldEvaluateTo("computeLogicalWidth('" + writingMode + "', '" + direction + "', '" + tableStyle + "')", "'" + logicalWidthsCombination["computed-width"][tableType] + "'");
+            });
+
+            debug("");
+        });
+    });
+}
+
+function createTableStyle(writingMode, logicalWidthsCombination)
+{
+    var widthStyle = "";
+
+    var logicalWidthName = (writingMode == "vertical" ? "height" : "width");
+
+    if (logicalWidthsCombination["width"] != null)
+        widthStyle += logicalWidthName + ": " + logicalWidthsCombination["width"] + "; ";
+
+    if (logicalWidthsCombination["min-width"] != null)
+        widthStyle += "min-" + logicalWidthName + ": " + logicalWidthsCombination["min-width"] + ";";
+
+    return widthStyle;
+}
+
+function computeLogicalWidthHelper(tableType, display, writingMode, direction, tableStyle)
+{
+    var isCSSTable = (tableType == "css");
+    var tableClass = display + " " + writingMode + " " + direction;
+
+    var tableParent = document.createElement("div");
+    tableParent.setAttribute("class", "table-parent");
+    document.body.appendChild(tableParent);
+
+    var table = document.createElement(isCSSTable ? "div" : "table");
+    table.setAttribute("class", tableClass);
+    table.setAttribute("style", tableStyle);
+    tableParent.appendChild(table);
+
+    var rowGroup = document.createElement(isCSSTable ? "div" : "tbody");
+    rowGroup.setAttribute("class", "row-group");
+    table.appendChild(rowGroup);
+
+    var row = document.createElement(isCSSTable ? "div" : "tr");
+    row.setAttribute("class", "row");
+    rowGroup.appendChild(row);
+
+    var cell = document.createElement(isCSSTable ? "div" : "td");
+    cell.setAttribute("class", "cell");
+    row.appendChild(cell);
+
+    // Create as many spans of width equal to minIntrinsicLogicalWidth without exceeding maxIntrinsicLogicalWidth.
+    var remainingLogicalWidth;
+    for (remainingLogicalWidth = maxIntrinsicLogicalWidth; remainingLogicalWidth >= minIntrinsicLogicalWidth; remainingLogicalWidth -= minIntrinsicLogicalWidth) {
+        span = createSpan(minIntrinsicLogicalWidth);
+        cell.appendChild(span);
+    }
+
+    // Create a span of width < minIntrinsicLogicalWidth for any remaining width.
+    if (remainingLogicalWidth > 0) {
+        span = createSpan(remainingLogicalWidth);
+        cell.appendChild(span);
+    }
+
+    var logicalWidthPropertyName = (writingMode == "vertical" ? "height" : "width");
+    var computedLogicalWidth = window.getComputedStyle(table, null).getPropertyValue(logicalWidthPropertyName);
+
+    document.body.removeChild(tableParent);
+
+    return computedLogicalWidth;
+}
+
+function createSpan(logicalWidth)
+{
+    var span = document.createElement("span");
+    span.setAttribute("style", "display: inline-block; width: " + logicalWidth + "px; height: " + logicalWidth + "px; background-color: #f00;");
+    return span;
+}
diff --git a/LayoutTests/fast/table/script-tests/min-width-html-block-table.js b/LayoutTests/fast/table/script-tests/min-width-html-block-table.js
new file mode 100644 (file)
index 0000000..7da2f40
--- /dev/null
@@ -0,0 +1,10 @@
+description("This test checks that the min-width style is applied to block HTML tables.");
+
+// Requires min-width-helpers.js.
+
+function computeLogicalWidth(writingMode, direction, tableStyle)
+{
+    return computeLogicalWidthHelper("html", "block", writingMode, direction, tableStyle);
+}
+
+runTests("html");
diff --git a/LayoutTests/fast/table/script-tests/min-width-html-inline-table.js b/LayoutTests/fast/table/script-tests/min-width-html-inline-table.js
new file mode 100644 (file)
index 0000000..e2ac24e
--- /dev/null
@@ -0,0 +1,10 @@
+description("This test checks that the min-width style is applied to inline HTML tables.");
+
+// Requires min-width-helpers.js.
+
+function computeLogicalWidth(writingMode, direction, tableStyle)
+{
+    return computeLogicalWidthHelper("html", "inline", writingMode, direction, tableStyle);
+}
+
+runTests("html");
index 73d789c..df71f3d 100644 (file)
@@ -1,3 +1,56 @@
+2012-02-01  Max Vujovic  <mvujovic@adobe.com>
+
+        Add support for fixed and percent min-width on the table element for table-layout: auto to
+        match Firefox and Opera's behavior.
+
+        In FixedTableLayout.cpp, the computePreferredLogicalWidths method looks like it has
+        issues based on the comment: "FIXME: This entire calculation is incorrect for both
+        minwidth and maxwidth." (minwidth and maxwidth refer to the preferred widths, not the
+        min-width and max-width styles). I have not implemented min-width for FixedTableLayout
+        in this patch since it requires some more research around that comment.
+
+        min-width and max-width on the table element was discussed on the www-style list:
+        http://lists.w3.org/Archives/Public/www-style/2012Jan/0684.html
+
+        min-width is not implemented on <table> for table-layout: auto
+        https://bugs.webkit.org/show_bug.cgi?id=76553
+
+        Reviewed by Julien Chaffraix.
+
+        Test: fast/table/min-width.html
+
+        * rendering/AutoTableLayout.cpp:
+        (WebCore::AutoTableLayout::computePreferredLogicalWidths):
+
+            If the min or max preferred logical width is less than a fixed min width style, it is
+            set to the fixed min width style. Like a percent width style, a percent min-width style
+            does not affect the min or max preferred logical widths computed by the table layout
+            algorithm. RenderTable's computeLogicalWidth method handles percent min-width styles.
+
+            min-width for the table-layout: fixed case has been split out into this bug:
+            https://bugs.webkit.org/show_bug.cgi?id=76948
+
+        * rendering/RenderTable.cpp:
+        (WebCore::RenderTable::computeLogicalWidth):
+
+            If the RenderStyle's logical min width is defined and greater than the logical width
+            calculation, this method sets the logical width to the logical min width.
+
+        (WebCore::RenderTable::convertStyleWidthToComputedWidth):
+
+            This new method generalizes and factors out logic from RenderTable::computeLogicalWidth
+            that converted the width style to a computed value in the fixed and percent case.
+            RenderTable::computeLogicalWidth now calls this method to determine the computed values
+            for both the width style and the min-width style. In the future, it can also be used for
+            the max-width style.
+
+            Note that this method handles the special CSS table case, which requires borders and
+            paddings to be included in the computed width calculation. This applies to all width
+            styles, including width, min-width, and max-width. Before, this special case was handled
+            in RenderTable::computeLogicalWidth.
+
+        * rendering/RenderTable.h:
+
 2012-02-01  Brian Salomon  <bsalomon@google.com>
 
         [SKIA/CHROMIUM] Perform getImageData format conversions using Skia
index 863e4c8..2fa064f 100644 (file)
@@ -262,13 +262,19 @@ void AutoTableLayout::computePreferredLogicalWidths(LayoutUnit& minWidth, Layout
     maxWidth += bordersPaddingAndSpacing;
 
     Length tableLogicalWidth = m_table->style()->logicalWidth();
-    if (tableLogicalWidth.isFixed() && tableLogicalWidth.value() > 0) {
+    if (tableLogicalWidth.isFixed() && tableLogicalWidth.isPositive()) {
         minWidth = max<int>(minWidth, tableLogicalWidth.value());
         maxWidth = minWidth;
     } else if (!remainingPercent && maxNonPercent) {
         // if there was no remaining percent, maxWidth is invalid.
         maxWidth = intMaxForLength;        
     }
+
+    Length tableLogicalMinWidth = m_table->style()->logicalMinWidth();
+    if (tableLogicalMinWidth.isFixed() && tableLogicalMinWidth.isPositive()) {
+        minWidth = max<int>(minWidth, tableLogicalMinWidth.value());
+        maxWidth = max<int>(minWidth, maxWidth);
+    }
 }
 
 /*
index 144601d..5de2ddb 100644 (file)
@@ -227,34 +227,32 @@ void RenderTable::computeLogicalWidth()
     bool hasPerpendicularContainingBlock = cb->style()->isHorizontalWritingMode() != style()->isHorizontalWritingMode();
     LayoutUnit containerWidthInInlineDirection = hasPerpendicularContainingBlock ? perpendicularContainingBlockLogicalHeight() : availableLogicalWidth;
 
-    LengthType logicalWidthType = style()->logicalWidth().type();
-    if (logicalWidthType > Relative && style()->logicalWidth().isPositive()) {
-        // Percent or fixed table
-        // HTML tables size as though CSS width includes border/padding, CSS tables do not.
-        LayoutUnit borders = 0;
-        if (logicalWidthType != Percent && (!node() || !node()->hasTagName(tableTag))) {
-            recalcBordersInRowDirection();
-            borders = borderStart() + borderEnd() + (collapseBorders() ? 0 : paddingStart() + paddingEnd());
-         }
-        setLogicalWidth(style()->logicalWidth().calcMinValue(containerWidthInInlineDirection) + borders);
-        setLogicalWidth(max(minPreferredLogicalWidth(), logicalWidth()));
-    } else {
+    Length styleLogicalWidth = style()->logicalWidth();
+    if (styleLogicalWidth.isSpecified() && styleLogicalWidth.isPositive())
+        setLogicalWidth(convertStyleLogicalWidthToComputedWidth(styleLogicalWidth, containerWidthInInlineDirection));
+    else {
         // Subtract out any fixed margins from our available width for auto width tables.
         LayoutUnit marginTotal = 0;
         if (!style()->marginStart().isAuto())
             marginTotal += style()->marginStart().calcValue(availableLogicalWidth);
         if (!style()->marginEnd().isAuto())
             marginTotal += style()->marginEnd().calcValue(availableLogicalWidth);
-            
+
         // Subtract out our margins to get the available content width.
         LayoutUnit availableContentLogicalWidth = max<LayoutUnit>(0, containerWidthInInlineDirection - marginTotal);
-        
-        // Ensure we aren't bigger than our max width or smaller than our min width.
+
+        // Ensure we aren't bigger than our available width.
         setLogicalWidth(min(availableContentLogicalWidth, maxPreferredLogicalWidth()));
     }
 
+    // Ensure we aren't smaller than our min preferred width.
     setLogicalWidth(max(logicalWidth(), minPreferredLogicalWidth()));
 
+    // Ensure we aren't smaller than our min-width style.
+    Length styleMinLogicalWidth = style()->logicalMinWidth();
+    if (styleMinLogicalWidth.isSpecified() && styleMinLogicalWidth.isPositive())
+        setLogicalWidth(max(logicalWidth(), convertStyleLogicalWidthToComputedWidth(styleMinLogicalWidth, availableLogicalWidth)));
+
     // Finally, with our true width determined, compute our margins for real.
     setMarginStart(0);
     setMarginEnd(0);
@@ -266,6 +264,19 @@ void RenderTable::computeLogicalWidth()
     }
 }
 
+// This method takes a RenderStyle's logical width, min-width, or max-width length and computes its actual value.
+LayoutUnit RenderTable::convertStyleLogicalWidthToComputedWidth(const Length& styleLogicalWidth, LayoutUnit availableWidth)
+{
+    // HTML tables' width styles already include borders and paddings, but CSS tables' width styles do not.
+    LayoutUnit borders = 0;
+    bool isCSSTable = !node() || !node()->hasTagName(tableTag);
+    if (isCSSTable && styleLogicalWidth.isFixed() && styleLogicalWidth.isPositive()) {
+        recalcBordersInRowDirection();
+        borders = borderStart() + borderEnd() + (collapseBorders() ? 0 : paddingStart() + paddingEnd());
+    }
+    return styleLogicalWidth.calcMinValue(availableWidth) + borders;
+}
+
 void RenderTable::layoutCaption(RenderTableCaption* caption)
 {
     IntRect captionRect(caption->x(), caption->y(), caption->width(), caption->height());
index ed83bf3..ba9fd39 100644 (file)
@@ -240,6 +240,8 @@ private:
 
     virtual void computeLogicalWidth();
 
+    LayoutUnit convertStyleLogicalWidthToComputedWidth(const Length& styleLogicalWidth, LayoutUnit availableWidth);
+
     virtual LayoutRect overflowClipRect(const LayoutPoint& location, RenderRegion*, OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize);
 
     virtual void addOverflowFromChildren();