Title: [164504] trunk
Revision
164504
Author
[email protected]
Date
2014-02-21 14:38:12 -0800 (Fri, 21 Feb 2014)

Log Message

COL element in table has 0 for offsetWidth
https://bugs.webkit.org/show_bug.cgi?id=15277

Reviewed by David Hyatt.

Source/WebCore:

Implements offset{Left, Top, Width, Height} for table columns and column groups
per section Extensions to the HTMLElement Interface of the CSSOM View spec,
<http://www.w3.org/TR/cssom-view/#extensions-to-the-htmlelement-interface> (Draft 17 December 2013).

For now, we fail almost all of the offset{Height, Top} sub-tests in the included test
for the separate border model as we need to fix <https://bugs.webkit.org/show_bug.cgi?id=128988>.

Test: fast/table/col-and-colgroup-offsets.html

* rendering/RenderTable.cpp:
(WebCore::RenderTable::RenderTable): Initialize cached column offset top and offset height.
We cache these offsets since they are the same for all columns in the table.
(WebCore::RenderTable::invalidateCachedColumns): Clear cached effective column index map.
(WebCore::RenderTable::invalidateCachedColumnOffsets): Added.
(WebCore::RenderTable::layout): Invalidate cached column offsets as the location or height
of one or more sections may have changed.
(WebCore::RenderTable::updateColumnCache): Modified to build effective column index map.
(WebCore::RenderTable::effectiveIndexOfColumn): Added.
(WebCore::RenderTable::offsetTopForColumn): Added.
(WebCore::RenderTable::offsetLeftForColumn): Added.
(WebCore::RenderTable::offsetWidthForColumn): Added.
(WebCore::RenderTable::offsetHeightForColumn): Added.
* rendering/RenderTable.h: Make isTableColumnGroupWithColumnChildren() const.
* rendering/RenderTableCol.cpp:
(WebCore::RenderTableCol::offsetLeft): Added; turns around and calls RenderTable::offsetLeftForColumn().
(WebCore::RenderTableCol::offsetTop): Added; turns around and calls RenderTable::offsetTopForColumn().
(WebCore::RenderTableCol::offsetWidth): Added; turns around and calls RenderTable::offsetWidthForColumn().
(WebCore::RenderTableCol::offsetHeight): Added; turns around and calls RenderTable::offsetHeightForColumn().
* rendering/RenderTableCol.h:

LayoutTests:

Added test to ensure that offset{Left, Top, Width, Height} return correct results
for table columns and column groups.

For now, we fail almost all of the offset{Height, Top} sub-tests for the separate
border model as we need to fix <https://bugs.webkit.org/show_bug.cgi?id=128988>.

* fast/table/col-and-colgroup-offsets-expected.txt: Added.
* fast/table/col-and-colgroup-offsets.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (164503 => 164504)


--- trunk/LayoutTests/ChangeLog	2014-02-21 22:37:29 UTC (rev 164503)
+++ trunk/LayoutTests/ChangeLog	2014-02-21 22:38:12 UTC (rev 164504)
@@ -1,3 +1,19 @@
+2014-02-21  Daniel Bates  <[email protected]>
+
+        COL element in table has 0 for offsetWidth
+        https://bugs.webkit.org/show_bug.cgi?id=15277
+
+        Reviewed by David Hyatt.
+
+        Added test to ensure that offset{Left, Top, Width, Height} return correct results
+        for table columns and column groups.
+
+        For now, we fail almost all of the offset{Height, Top} sub-tests for the separate
+        border model as we need to fix <https://bugs.webkit.org/show_bug.cgi?id=128988>.
+
+        * fast/table/col-and-colgroup-offsets-expected.txt: Added.
+        * fast/table/col-and-colgroup-offsets.html: Added.
+
 2014-02-21  Benjamin Poulain  <[email protected]>
 
         'mouseenter' mouse compat event not fired when listeners for touch events

Added: trunk/LayoutTests/fast/table/col-and-colgroup-offsets-expected.txt (0 => 164504)


--- trunk/LayoutTests/fast/table/col-and-colgroup-offsets-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/table/col-and-colgroup-offsets-expected.txt	2014-02-21 22:38:12 UTC (rev 164504)
@@ -0,0 +1,93 @@
+This test checks that offset{Left, Top, Width, Height} work for table columns and column groups.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+
+When borderCollapse == "separate"
+
+Tests for offsetLeft:
+PASS document.getElementById("productNo").parentNode.offsetLeft is document.getElementById("row1Cell1").offsetLeft
+PASS document.getElementById("productNo").offsetLeft is document.getElementById("row1Cell1").offsetLeft
+PASS document.getElementById("productName").offsetLeft is document.getElementById("row1Cell2").offsetLeft
+PASS document.getElementById("hasMAndHasNAndHasO").offsetLeft is document.getElementById("row1Cell3").offsetLeft
+PASS document.getElementById("hasMAndHasN").offsetLeft is document.getElementById("row1Cell3").offsetLeft
+PASS document.getElementById("hasO").offsetLeft is document.getElementById("row1Cell5").offsetLeft
+PASS document.getElementById("hasP").offsetLeft is document.getElementById("row1Cell6").offsetLeft
+PASS document.getElementById("columnThatShouldNotBeRendered").offsetLeft is 0
+
+Tests for offsetTop:
+FAIL document.getElementById("productNo").parentNode.offsetTop should be 24. Was 20.
+FAIL document.getElementById("productNo").offsetTop should be 24. Was 20.
+FAIL document.getElementById("productName").offsetTop should be 24. Was 20.
+FAIL document.getElementById("hasMAndHasNAndHasO").offsetTop should be 24. Was 20.
+FAIL document.getElementById("hasMAndHasN").offsetTop should be 24. Was 20.
+FAIL document.getElementById("hasO").offsetTop should be 24. Was 20.
+FAIL document.getElementById("hasP").offsetTop should be 24. Was 20.
+PASS document.getElementById("columnThatShouldNotBeRendered").offsetTop is 0
+
+Tests for offsetWidth:
+PASS document.getElementById("productNo").parentNode.offsetWidth is 184
+PASS document.getElementById("productNo").offsetWidth is 89
+PASS document.getElementById("productName").offsetWidth is 91
+PASS document.getElementById("hasMAndHasNAndHasO").offsetWidth is 155
+PASS document.getElementById("hasMAndHasN").offsetWidth is 103
+PASS document.getElementById("hasO").offsetWidth is 48
+PASS document.getElementById("hasP").offsetWidth is 46
+PASS document.getElementById("columnThatShouldNotBeRendered").offsetWidth is 0
+
+Tests for offsetHeight:
+FAIL document.getElementById("productNo").parentNode.offsetHeight should be 111. Was 119.
+FAIL document.getElementById("productNo").offsetHeight should be 111. Was 119.
+FAIL document.getElementById("productName").offsetHeight should be 111. Was 119.
+FAIL document.getElementById("hasMAndHasNAndHasO").offsetHeight should be 111. Was 119.
+FAIL document.getElementById("hasMAndHasN").offsetHeight should be 111. Was 119.
+FAIL document.getElementById("hasO").offsetHeight should be 111. Was 119.
+FAIL document.getElementById("hasP").offsetHeight should be 111. Was 119.
+PASS document.getElementById("columnThatShouldNotBeRendered").offsetHeight is 0
+
+When borderCollapse == "collapse"
+
+Tests for offsetLeft:
+PASS document.getElementById("productNo").parentNode.offsetLeft is document.getElementById("row1Cell1").offsetLeft
+PASS document.getElementById("productNo").offsetLeft is document.getElementById("row1Cell1").offsetLeft
+PASS document.getElementById("productName").offsetLeft is document.getElementById("row1Cell2").offsetLeft
+PASS document.getElementById("hasMAndHasNAndHasO").offsetLeft is document.getElementById("row1Cell3").offsetLeft
+PASS document.getElementById("hasMAndHasN").offsetLeft is document.getElementById("row1Cell3").offsetLeft
+PASS document.getElementById("hasO").offsetLeft is document.getElementById("row1Cell5").offsetLeft
+PASS document.getElementById("hasP").offsetLeft is document.getElementById("row1Cell6").offsetLeft
+PASS document.getElementById("columnThatShouldNotBeRendered").offsetLeft is 0
+
+Tests for offsetTop:
+PASS document.getElementById("productNo").parentNode.offsetTop is 19
+PASS document.getElementById("productNo").offsetTop is 19
+PASS document.getElementById("productName").offsetTop is 19
+PASS document.getElementById("hasMAndHasNAndHasO").offsetTop is 19
+PASS document.getElementById("hasMAndHasN").offsetTop is 19
+PASS document.getElementById("hasO").offsetTop is 19
+PASS document.getElementById("hasP").offsetTop is 19
+PASS document.getElementById("columnThatShouldNotBeRendered").offsetTop is 0
+
+Tests for offsetWidth:
+PASS document.getElementById("productNo").parentNode.offsetWidth is 176
+PASS document.getElementById("productNo").offsetWidth is 87
+PASS document.getElementById("productName").offsetWidth is 89
+PASS document.getElementById("hasMAndHasNAndHasO").offsetWidth is 141
+PASS document.getElementById("hasMAndHasN").offsetWidth is 95
+PASS document.getElementById("hasO").offsetWidth is 46
+PASS document.getElementById("hasP").offsetWidth is 44
+PASS document.getElementById("columnThatShouldNotBeRendered").offsetWidth is 0
+
+Tests for offsetHeight:
+PASS document.getElementById("productNo").parentNode.offsetHeight is 91
+PASS document.getElementById("productNo").offsetHeight is 91
+PASS document.getElementById("productName").offsetHeight is 91
+PASS document.getElementById("hasMAndHasNAndHasO").offsetHeight is 91
+PASS document.getElementById("hasMAndHasN").offsetHeight is 91
+PASS document.getElementById("hasO").offsetHeight is 91
+PASS document.getElementById("hasP").offsetHeight is 91
+PASS document.getElementById("columnThatShouldNotBeRendered").offsetHeight is 0
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/table/col-and-colgroup-offsets.html (0 => 164504)


--- trunk/LayoutTests/fast/table/col-and-colgroup-offsets.html	                        (rev 0)
+++ trunk/LayoutTests/fast/table/col-and-colgroup-offsets.html	2014-02-21 22:38:12 UTC (rev 164504)
@@ -0,0 +1,162 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+<style>
+table, td, th { border: 2px solid blue; } /* To make it easier to visually inspect the test case. */
+</style>
+<script>
+window.jsTestIsAsync = true;
+
+var table;
+var tableHorizontalBorderSpacing;
+var tableVerticalBorderSpacing;
+var borderCollapseMenu;
+
+window._onload_ = function() {
+    description("This test checks that offset{Left, Top, Width, Height} work for table columns and column groups.");
+
+    table = document.querySelector("table");
+    borderCollapseMenu = document.getElementById("borderCollapseMenu");
+    borderCollapseMenu._onchange_ = didChangeBorderCollapse;
+
+    runTests();
+}
+
+function didChangeBorderCollapse()
+{
+    var newBorderCollapse = borderCollapseMenu.options[borderCollapseMenu.selectedIndex].value;
+    table.style.borderCollapse = borderCollapseMenu.options[borderCollapseMenu.selectedIndex].value;
+    tableHorizontalBorderSpacing = newBorderCollapse === "collapse" ? 0 : parseInt(table.getAttribute("cellspacing"), 10);
+    tableVerticalBorderSpacing = tableHorizontalBorderSpacing;
+}
+
+function runTests()
+{
+    var savedSelectedIndex;
+    if (!window.testRunner)
+        savedSelectedIndex = borderCollapseMenu.selectedIndex;
+
+    for (var i = 0; i < borderCollapseMenu.options.length; ++i) {
+        borderCollapseMenu.options[i].selected = true;
+        didChangeBorderCollapse();
+
+        debug('<br>When borderCollapse == "' + borderCollapseMenu.options[i].value + '"');
+
+        debug("<br>Tests for offsetLeft:");
+        testOffsetLeft();
+
+        debug("<br>Tests for offsetTop:");
+        testOffsetTop();
+
+        debug("<br>Tests for offsetWidth:");
+        testOffsetWidth();
+
+        debug("<br>Tests for offsetHeight:");
+        testOffsetHeight();
+    }
+
+    if (window.testRunner)
+        document.body.removeChild(document.getElementById("test-container"));
+    else {
+        borderCollapseMenu.options[savedSelectedIndex].selected = true;
+        didChangeBorderCollapse();
+    }
+    finishJSTest();
+}
+
+function testOffsetLeft()
+{
+    shouldEvaluateTo('document.getElementById("productNo").parentNode.offsetLeft', 'document.getElementById("row1Cell1").offsetLeft');
+    shouldBe('document.getElementById("productNo").offsetLeft', 'document.getElementById("row1Cell1").offsetLeft');
+    shouldBe('document.getElementById("productName").offsetLeft', 'document.getElementById("row1Cell2").offsetLeft');
+    shouldBe('document.getElementById("hasMAndHasNAndHasO").offsetLeft', 'document.getElementById("row1Cell3").offsetLeft');
+    shouldBe('document.getElementById("hasMAndHasN").offsetLeft', 'document.getElementById("row1Cell3").offsetLeft');
+    shouldBe('document.getElementById("hasO").offsetLeft', 'document.getElementById("row1Cell5").offsetLeft');
+    shouldBe('document.getElementById("hasP").offsetLeft', 'document.getElementById("row1Cell6").offsetLeft');
+    shouldEvaluateTo('document.getElementById("columnThatShouldNotBeRendered").offsetLeft', 0);
+}
+
+function testOffsetTop()
+{
+    var top = document.getElementById("productNoHeading").offsetTop;
+    shouldEvaluateTo('document.getElementById("productNo").parentNode.offsetTop', top);
+    shouldEvaluateTo('document.getElementById("productNo").offsetTop', top);
+    shouldEvaluateTo('document.getElementById("productName").offsetTop', top);
+    shouldEvaluateTo('document.getElementById("hasMAndHasNAndHasO").offsetTop', top);
+    shouldEvaluateTo('document.getElementById("hasMAndHasN").offsetTop', top);
+    shouldEvaluateTo('document.getElementById("hasO").offsetTop', top);
+    shouldEvaluateTo('document.getElementById("hasP").offsetTop', top);
+    shouldEvaluateTo('document.getElementById("columnThatShouldNotBeRendered").offsetTop', 0);
+}
+
+function testOffsetWidth()
+{
+    shouldEvaluateTo('document.getElementById("productNo").parentNode.offsetWidth', document.getElementById("row1Cell1").offsetWidth + tableHorizontalBorderSpacing + document.getElementById("row1Cell2").offsetWidth);
+    shouldEvaluateTo('document.getElementById("productNo").offsetWidth', document.getElementById("row1Cell1").offsetWidth);
+    shouldEvaluateTo('document.getElementById("productName").offsetWidth', document.getElementById("row1Cell2").offsetWidth);
+    shouldEvaluateTo('document.getElementById("hasMAndHasNAndHasO").offsetWidth', document.getElementById("row1Cell3").offsetWidth + tableHorizontalBorderSpacing + document.getElementById("row1Cell4").offsetWidth + tableHorizontalBorderSpacing + document.getElementById("row1Cell5").offsetWidth);
+    shouldEvaluateTo('document.getElementById("hasMAndHasN").offsetWidth', document.getElementById("row1Cell3").offsetWidth + tableHorizontalBorderSpacing + document.getElementById("row1Cell4").offsetWidth);
+    shouldEvaluateTo('document.getElementById("hasO").offsetWidth', document.getElementById("row1Cell5").offsetWidth);
+    shouldEvaluateTo('document.getElementById("hasP").offsetWidth', document.getElementById("row1Cell6").offsetWidth);
+    shouldEvaluateTo('document.getElementById("columnThatShouldNotBeRendered").offsetWidth', 0);
+}
+
+function testOffsetHeight()
+{
+    var height = tableContentHeight();
+    shouldEvaluateTo('document.getElementById("productNo").parentNode.offsetHeight', height);
+    shouldEvaluateTo('document.getElementById("productNo").offsetHeight', height);
+    shouldEvaluateTo('document.getElementById("productName").offsetHeight', height);
+    shouldEvaluateTo('document.getElementById("hasMAndHasNAndHasO").offsetHeight', height);
+    shouldEvaluateTo('document.getElementById("hasMAndHasN").offsetHeight', height);
+    shouldEvaluateTo('document.getElementById("hasO").offsetHeight', height);
+    shouldEvaluateTo('document.getElementById("hasP").offsetHeight', height);
+    shouldEvaluateTo('document.getElementById("columnThatShouldNotBeRendered").offsetHeight', 0);
+}
+
+function tableContentHeight()
+{
+    var result = 0;
+    var rows = document.getElementsByTagName("tr");
+    var numberOfRows = rows.length;
+    if (numberOfRows)
+        result += rows[0].offsetHeight;
+    for (var i = 1; i < numberOfRows; ++i)
+        result += tableVerticalBorderSpacing + rows[i].offsetHeight;
+    return result;
+}
+</script>
+</head>
+<body>
+<p id="description"></p>
+<div id="test-container">
+    <label for=""
+    <select id="borderCollapseMenu">
+        <option value="separate">separate</option>
+        <option value="collapse">collapse</option>
+    </select>
+    <table cellspacing="4">
+        <caption>Product Table</caption>
+        <col id="productNo" style="background-color: lightblue">
+        <col id="productName" style="background-color: lightgreen">
+        <colgroup id="hasMAndHasNAndHasO" style="background-color: lightgray">
+            <col id="hasMAndHasN" span="2">
+            <col id="hasO">
+        </colgroup>
+        <colgroup id="hasP" style="background-color: gray">
+        <colgroup id="columnThatShouldNotBeRendered" style="background-color: red" span="2">
+        <thead>
+            <tr><th id="productNoHeading">Product No.</th><th>Name</th><th>Has M</th><th>Has N</th><th>Has O</th><th>Has P</th></tr>
+        </thead>
+        <tbody>
+            <tr><td id="row1Cell1">1</td><td id="row1Cell2">Gizmo A</td><td id="row1Cell3">&#x2713;</td><td id="row1Cell4"></td><td id="row1Cell5">&#x2713;</td><td id="row1Cell6">&#x2713;</td></tr>
+            <tr><td>2</td><td>Gizmo A Pro</td><td>&#x2713;</td><td>&#x2713;</td><td>&#x2713;</td><td>&#x2713;</td></tr>
+            <tr><td>3</td><td>Gizmo B</td><td><td><td colspan="2" style="text-align: center">&#x2713;</td></tr>
+        </tbody>
+    </table>
+</div>
+<div id="console"></div>
+<script src=""
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (164503 => 164504)


--- trunk/Source/WebCore/ChangeLog	2014-02-21 22:37:29 UTC (rev 164503)
+++ trunk/Source/WebCore/ChangeLog	2014-02-21 22:38:12 UTC (rev 164504)
@@ -1,3 +1,40 @@
+2014-02-21  Daniel Bates  <[email protected]>
+
+        COL element in table has 0 for offsetWidth
+        https://bugs.webkit.org/show_bug.cgi?id=15277
+
+        Reviewed by David Hyatt.
+
+        Implements offset{Left, Top, Width, Height} for table columns and column groups
+        per section Extensions to the HTMLElement Interface of the CSSOM View spec,
+        <http://www.w3.org/TR/cssom-view/#extensions-to-the-htmlelement-interface> (Draft 17 December 2013).
+
+        For now, we fail almost all of the offset{Height, Top} sub-tests in the included test
+        for the separate border model as we need to fix <https://bugs.webkit.org/show_bug.cgi?id=128988>.
+
+        Test: fast/table/col-and-colgroup-offsets.html
+
+        * rendering/RenderTable.cpp:
+        (WebCore::RenderTable::RenderTable): Initialize cached column offset top and offset height.
+        We cache these offsets since they are the same for all columns in the table.
+        (WebCore::RenderTable::invalidateCachedColumns): Clear cached effective column index map.
+        (WebCore::RenderTable::invalidateCachedColumnOffsets): Added.
+        (WebCore::RenderTable::layout): Invalidate cached column offsets as the location or height
+        of one or more sections may have changed.
+        (WebCore::RenderTable::updateColumnCache): Modified to build effective column index map.
+        (WebCore::RenderTable::effectiveIndexOfColumn): Added.
+        (WebCore::RenderTable::offsetTopForColumn): Added.
+        (WebCore::RenderTable::offsetLeftForColumn): Added.
+        (WebCore::RenderTable::offsetWidthForColumn): Added.
+        (WebCore::RenderTable::offsetHeightForColumn): Added.
+        * rendering/RenderTable.h: Make isTableColumnGroupWithColumnChildren() const.
+        * rendering/RenderTableCol.cpp:
+        (WebCore::RenderTableCol::offsetLeft): Added; turns around and calls RenderTable::offsetLeftForColumn().
+        (WebCore::RenderTableCol::offsetTop): Added; turns around and calls RenderTable::offsetTopForColumn().
+        (WebCore::RenderTableCol::offsetWidth): Added; turns around and calls RenderTable::offsetWidthForColumn().
+        (WebCore::RenderTableCol::offsetHeight): Added; turns around and calls RenderTable::offsetHeightForColumn().
+        * rendering/RenderTableCol.h:
+
 2014-02-21  Enrica Casucci  <[email protected]>
 
         Build fix for iOS after r164498.

Modified: trunk/Source/WebCore/rendering/RenderTable.cpp (164503 => 164504)


--- trunk/Source/WebCore/rendering/RenderTable.cpp	2014-02-21 22:37:29 UTC (rev 164503)
+++ trunk/Source/WebCore/rendering/RenderTable.cpp	2014-02-21 22:38:12 UTC (rev 164504)
@@ -4,7 +4,7 @@
  *           (C) 1998 Waldo Bastian ([email protected])
  *           (C) 1999 Lars Knoll ([email protected])
  *           (C) 1999 Antti Koivisto ([email protected])
- * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2014 Apple Inc. All rights reserved.
  * Copyright (C) 2006 Alexey Proskuryakov ([email protected])
  *
  * This library is free software; you can redistribute it and/or
@@ -64,6 +64,8 @@
     , m_vSpacing(0)
     , m_borderStart(0)
     , m_borderEnd(0)
+    , m_columnOffsetTop(-1)
+    , m_columnOffsetHeight(-1)
 {
     setChildrenInline(false);
     m_columnPos.fill(0, 1);
@@ -237,8 +239,15 @@
 {
     m_columnRenderersValid = false;
     m_columnRenderers.resize(0);
+    m_effectiveColumnIndexMap.clear();
 }
 
+void RenderTable::invalidateCachedColumnOffsets()
+{
+    m_columnOffsetTop = -1;
+    m_columnOffsetHeight = -1;
+}
+
 void RenderTable::addColumn(const RenderTableCol*)
 {
     invalidateCachedColumns();
@@ -557,6 +566,9 @@
     // Layout was changed, so probably borders too.
     invalidateCollapsedBorders();
 
+    // The location or height of one or more sections may have changed.
+    invalidateCachedColumnOffsets();
+
     computeOverflow(clientLogicalBottom());
 
     statePusher.pop();
@@ -849,16 +861,100 @@
 {
     ASSERT(m_hasColElements);
     ASSERT(m_columnRenderers.isEmpty());
+    ASSERT(m_effectiveColumnIndexMap.isEmpty());
     ASSERT(!m_columnRenderersValid);
 
+    unsigned columnIndex = 0;
     for (RenderTableCol* columnRenderer = firstColumn(); columnRenderer; columnRenderer = columnRenderer->nextColumn()) {
         if (columnRenderer->isTableColumnGroupWithColumnChildren())
             continue;
         m_columnRenderers.append(columnRenderer);
+        // FIXME: We should look to compute the effective column index successively from previous values instead of
+        // calling colToEffCol(), which is in O(numEffCols()). Although it's unlikely that this is a hot function.
+        m_effectiveColumnIndexMap.add(columnRenderer, colToEffCol(columnIndex));
+        columnIndex += columnRenderer->span();
     }
     m_columnRenderersValid = true;
 }
 
+unsigned RenderTable::effectiveIndexOfColumn(const RenderTableCol& column) const
+{
+    if (!m_columnRenderersValid)
+        updateColumnCache();
+    const RenderTableCol* columnToUse = &column;
+    if (columnToUse->isTableColumnGroupWithColumnChildren())
+        columnToUse = columnToUse->nextColumn(); // First column in column-group
+    auto it = m_effectiveColumnIndexMap.find(columnToUse);
+    ASSERT(it != m_effectiveColumnIndexMap.end());
+    if (it == m_effectiveColumnIndexMap.end())
+        return std::numeric_limits<unsigned>::max();
+    return it->value;
+}
+
+LayoutUnit RenderTable::offsetTopForColumn(const RenderTableCol& column) const
+{
+    if (effectiveIndexOfColumn(column) >= numEffCols())
+        return 0;
+    if (m_columnOffsetTop >= 0) {
+        ASSERT(!needsLayout());
+        return m_columnOffsetTop;
+    }
+    RenderTableSection* section = topNonEmptySection();
+    return m_columnOffsetTop = section ? section->offsetTop() : LayoutUnit(0);
+}
+
+LayoutUnit RenderTable::offsetLeftForColumn(const RenderTableCol& column) const
+{
+    unsigned columnIndex = effectiveIndexOfColumn(column);
+    if (columnIndex >= numEffCols())
+        return 0;
+    return m_columnPos[columnIndex] + m_hSpacing + borderLeft();
+}
+
+LayoutUnit RenderTable::offsetWidthForColumn(const RenderTableCol& column) const
+{
+    const RenderTableCol* currentColumn = &column;
+    bool hasColumnChildren;
+    if ((hasColumnChildren = currentColumn->isTableColumnGroupWithColumnChildren()))
+        currentColumn = currentColumn->nextColumn(); // First column in column-group
+    unsigned numberOfEffectiveColumns = numEffCols();
+    ASSERT_WITH_SECURITY_IMPLICATION(m_columnPos.size() >= numberOfEffectiveColumns + 1);
+    unsigned width = 0;
+    while (currentColumn) {
+        unsigned columnIndex = effectiveIndexOfColumn(*currentColumn);
+        unsigned span = currentColumn->span();
+        while (span && columnIndex < numberOfEffectiveColumns) {
+            width += m_columnPos[columnIndex + 1] - m_columnPos[columnIndex] - m_hSpacing;
+            span -= m_columns[columnIndex].span;
+            ++columnIndex;
+            if (span)
+                width += m_hSpacing;
+        }
+        if (!hasColumnChildren)
+            break;
+        currentColumn = currentColumn->nextColumn();
+        if (!currentColumn || currentColumn->isTableColumnGroup())
+            break;
+        width += m_hSpacing;
+    }
+    return width;
+}
+
+LayoutUnit RenderTable::offsetHeightForColumn(const RenderTableCol& column) const
+{
+    if (effectiveIndexOfColumn(column) >= numEffCols())
+        return 0;
+    if (m_columnOffsetHeight >= 0) {
+        ASSERT(!needsLayout());
+        return m_columnOffsetHeight;
+    }
+    LayoutUnit height = 0;
+    for (RenderTableSection* section = topSection(); section; section = sectionBelow(section))
+        height += section->offsetHeight();
+    m_columnOffsetHeight = height;
+    return m_columnOffsetHeight;
+}
+
 RenderTableCol* RenderTable::slowColElement(unsigned col, bool* startEdge, bool* endEdge) const
 {
     ASSERT(m_hasColElements);

Modified: trunk/Source/WebCore/rendering/RenderTable.h (164503 => 164504)


--- trunk/Source/WebCore/rendering/RenderTable.h	2014-02-21 22:37:29 UTC (rev 164503)
+++ trunk/Source/WebCore/rendering/RenderTable.h	2014-02-21 22:38:12 UTC (rev 164504)
@@ -4,7 +4,7 @@
  *           (C) 1998 Waldo Bastian ([email protected])
  *           (C) 1999 Lars Knoll ([email protected])
  *           (C) 1999 Antti Koivisto ([email protected])
- * Copyright (C) 2003, 2004, 2005, 2006, 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2003, 2004, 2005, 2006, 2009, 2010, 2014 Apple Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -28,6 +28,7 @@
 #include "CSSPropertyNames.h"
 #include "CollapsedBorderValue.h"
 #include "RenderBlock.h"
+#include <wtf/HashMap.h>
 #include <wtf/Vector.h>
 
 namespace WebCore {
@@ -263,6 +264,11 @@
     void addColumn(const RenderTableCol*);
     void removeColumn(const RenderTableCol*);
 
+    LayoutUnit offsetTopForColumn(const RenderTableCol&) const;
+    LayoutUnit offsetLeftForColumn(const RenderTableCol&) const;
+    LayoutUnit offsetWidthForColumn(const RenderTableCol&) const;
+    LayoutUnit offsetHeightForColumn(const RenderTableCol&) const;
+
 protected:
     virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) override final;
     virtual void simplifiedNormalFlowLayout() override final;
@@ -292,6 +298,8 @@
     void updateColumnCache() const;
     void invalidateCachedColumns();
 
+    void invalidateCachedColumnOffsets();
+
     virtual RenderBlock* firstLineBlock() const override final;
     virtual void updateFirstLetter() override final;
     
@@ -318,6 +326,10 @@
     mutable Vector<RenderTableCaption*> m_captions;
     mutable Vector<RenderTableCol*> m_columnRenderers;
 
+    unsigned effectiveIndexOfColumn(const RenderTableCol&) const;
+    typedef HashMap<const RenderTableCol*, unsigned> EffectiveColumnIndexMap;
+    mutable EffectiveColumnIndexMap m_effectiveColumnIndexMap;
+
     mutable RenderTableSection* m_head;
     mutable RenderTableSection* m_foot;
     mutable RenderTableSection* m_firstBody;
@@ -338,6 +350,8 @@
     short m_vSpacing;
     int m_borderStart;
     int m_borderEnd;
+    mutable LayoutUnit m_columnOffsetTop;
+    mutable LayoutUnit m_columnOffsetHeight;
 };
 
 inline RenderTableSection* RenderTable::topSection() const

Modified: trunk/Source/WebCore/rendering/RenderTableCol.cpp (164503 => 164504)


--- trunk/Source/WebCore/rendering/RenderTableCol.cpp	2014-02-21 22:37:29 UTC (rev 164503)
+++ trunk/Source/WebCore/rendering/RenderTableCol.cpp	2014-02-21 22:38:12 UTC (rev 164504)
@@ -200,4 +200,24 @@
     return style().borderEnd();
 }
 
+LayoutUnit RenderTableCol::offsetLeft() const
+{
+    return table()->offsetLeftForColumn(*this);
 }
+
+LayoutUnit RenderTableCol::offsetTop() const
+{
+    return table()->offsetTopForColumn(*this);
+}
+
+LayoutUnit RenderTableCol::offsetWidth() const
+{
+    return table()->offsetWidthForColumn(*this);
+}
+
+LayoutUnit RenderTableCol::offsetHeight() const
+{
+    return table()->offsetHeightForColumn(*this);
+}
+
+}

Modified: trunk/Source/WebCore/rendering/RenderTableCol.h (164503 => 164504)


--- trunk/Source/WebCore/rendering/RenderTableCol.h	2014-02-21 22:37:29 UTC (rev 164503)
+++ trunk/Source/WebCore/rendering/RenderTableCol.h	2014-02-21 22:38:12 UTC (rev 164504)
@@ -43,7 +43,7 @@
     unsigned span() const { return m_span; }
     void setSpan(unsigned span) { m_span = span; }
 
-    bool isTableColumnGroupWithColumnChildren() { return firstChild(); }
+    bool isTableColumnGroupWithColumnChildren() const { return firstChild(); }
     bool isTableColumn() const { return style().display() == TABLE_COLUMN; }
     bool isTableColumnGroup() const { return style().display() == TABLE_COLUMN_GROUP; }
 
@@ -71,6 +71,11 @@
     const BorderValue& borderAdjoiningCellBefore(const RenderTableCell*) const;
     const BorderValue& borderAdjoiningCellAfter(const RenderTableCell*) const;
 
+    virtual LayoutUnit offsetLeft() const override;
+    virtual LayoutUnit offsetTop() const override;
+    virtual LayoutUnit offsetWidth() const override;
+    virtual LayoutUnit offsetHeight() const override;
+
 private:
     virtual const char* renderName() const override { return "RenderTableCol"; }
     virtual bool isRenderTableCol() const override { return true; }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to