Title: [132612] trunk
Revision
132612
Author
[email protected]
Date
2012-10-26 04:13:46 -0700 (Fri, 26 Oct 2012)

Log Message

RenderTableCol::computePreferredLogicalWidths and RenderTableCol::layout should never be called
https://bugs.webkit.org/show_bug.cgi?id=99861

Reviewed by Ojan Vafai.

Source/WebCore:

RenderTableCol's computePreferredLogicalWidths and layout's only purpose were to clear the preferred logical
widths dirty / layout flag so that we would properly propagate the information to our containing table. This
led to clunky code where the table layout code had to forcefully call RenderTableCol::computePreferredLogicalWidths
or else we would ignore the next layout hint on the <col> or <colgroup>.

Tests: fast/table/col-span-change-relayout.html
       fast/table/simplified-layout-table.html

* rendering/AutoTableLayout.cpp:
(WebCore::AutoTableLayout::recalcColumn):
* rendering/RenderTable.cpp:
(WebCore::RenderTable::layout):
Simplified the code now that we only need to iterate over the sections.

* rendering/FixedTableLayout.cpp:
(WebCore::FixedTableLayout::calcWidthArray):
Removed call to computePreferredLogicalWidths.

* rendering/RenderTableCol.cpp:
(WebCore::RenderTableCol::styleDidChange):
(WebCore::RenderTableCol::updateFromElement):
Forward a layout hint to the table so that we properly recompute the cell's logical withs.

(WebCore::RenderTableCol::computePreferredLogicalWidths):
(WebCore::RenderTableCol::layout):
Change our implementations of those 2 methods to be no-ops, while enforcing that they are
never called when it was possible.

(WebCore::RenderTableCol::propagateLayoutCueToTable):
New helper function that forward any layout cue to the containing table, this works around
us not clearing the flags which confuses RenderObject markContainingBlocksForLayout and
invalidateContainerPreferredLogicalWidths.

* rendering/RenderTableCol.h:
Made the function that we are not expected to be called private.

LayoutTests:

Added 2 tests:
- 1 to cover the code in RenderTableCol::updateFromElement.
- 1 to cover simplified layout on a table.

* fast/table/col-span-change-relayout-expected.txt: Added.
* fast/table/col-span-change-relayout.html: Added.
* fast/table/simplified-layout-table-expected.html: Added.
* fast/table/simplified-layout-table.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (132611 => 132612)


--- trunk/LayoutTests/ChangeLog	2012-10-26 11:08:26 UTC (rev 132611)
+++ trunk/LayoutTests/ChangeLog	2012-10-26 11:13:46 UTC (rev 132612)
@@ -1,3 +1,19 @@
+2012-10-26  Julien Chaffraix  <[email protected]>
+
+        RenderTableCol::computePreferredLogicalWidths and RenderTableCol::layout should never be called
+        https://bugs.webkit.org/show_bug.cgi?id=99861
+
+        Reviewed by Ojan Vafai.
+
+        Added 2 tests:
+        - 1 to cover the code in RenderTableCol::updateFromElement.
+        - 1 to cover simplified layout on a table.
+
+        * fast/table/col-span-change-relayout-expected.txt: Added.
+        * fast/table/col-span-change-relayout.html: Added.
+        * fast/table/simplified-layout-table-expected.html: Added.
+        * fast/table/simplified-layout-table.html: Added.
+
 2012-10-26  Balazs Kelemen  <[email protected]>
 
         [Qt] Pixel tests need rebaseline

Added: trunk/LayoutTests/fast/table/col-span-change-relayout-expected.txt (0 => 132612)


--- trunk/LayoutTests/fast/table/col-span-change-relayout-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/table/col-span-change-relayout-expected.txt	2012-10-26 11:13:46 UTC (rev 132612)
@@ -0,0 +1,7 @@
+This test checks that dynamically changing a column's 'span' properly recompute the cell's widths.
+
+The table below shrink to 200px after changing the column's span.
+
+PASS
+PASS
+

Added: trunk/LayoutTests/fast/table/col-span-change-relayout.html (0 => 132612)


--- trunk/LayoutTests/fast/table/col-span-change-relayout.html	                        (rev 0)
+++ trunk/LayoutTests/fast/table/col-span-change-relayout.html	2012-10-26 11:13:46 UTC (rev 132612)
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <script src=""
+        <style>
+            table
+            {
+                border-collapse: collapse;
+                table-layout: fixed;
+                width: 200px;
+            }
+            td
+            {
+                background: green;
+                height: 1em;
+            }
+        </style>
+        <script>
+            if (window.testRunner)
+                testRunner.dumpAsText();
+
+            function log(msg)
+            {
+                var console = document.getElementById('console');
+                console.appendChild(document.createTextNode(msg));
+                console.appendChild(document.createElement('br'));
+            }
+
+            function changeColSpan()
+            {
+                document.getElementById('table').setAttribute('data-expected-width', 300);
+                checkLayout('table');
+
+                var col = document.getElementById('column');
+                col.setAttribute("span", "1");
+                document.getElementById('table').setAttribute('data-expected-width', 200);
+                checkLayout('table');
+            }
+        </script>
+    </head>
+    <body _onload_="changeColSpan();">
+        <p>This test checks that dynamically changing a column's 'span' properly recompute the cell's widths.</p>
+        <p>The table below shrink to 200px after changing the column's span.</p>
+        <table id="table">
+            <colgroup>
+                <col span="2" id="column" style="width: 100px"></col>
+                <col style="width: 100px;"></col>
+            </colgroup>
+            <tr>
+                <td id="cell"></td>
+                <td></td>
+                <td></td>
+           </tr>
+        </table>
+        <p id="console"></p>
+    </body>
+</html>
+

Added: trunk/LayoutTests/fast/table/simplified-layout-table-expected.html (0 => 132612)


--- trunk/LayoutTests/fast/table/simplified-layout-table-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/table/simplified-layout-table-expected.html	2012-10-26 11:13:46 UTC (rev 132612)
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+div {
+    height: 100px;
+    width: 100px;
+    background-color: green;
+    opacity: 0.8;
+    padding: 0px;
+    -webkit-transform: translate(50px, 50px);
+}
+</style>
+</head>
+<p>Test for <a href="" and RenderTableCol::layout should never be called.</p>
+<p>This test checks that simplified layout works on a table with a &lt;col&gt;.</p>
+<div></div>
+</html>
Property changes on: trunk/LayoutTests/fast/table/simplified-layout-table-expected.html
___________________________________________________________________

Added: svn:executable

Added: trunk/LayoutTests/fast/table/simplified-layout-table.html (0 => 132612)


--- trunk/LayoutTests/fast/table/simplified-layout-table.html	                        (rev 0)
+++ trunk/LayoutTests/fast/table/simplified-layout-table.html	2012-10-26 11:13:46 UTC (rev 132612)
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+table {
+    border-spacing: 0px;
+}
+col {
+    width: 100px;
+}
+td {
+    height: 100px;
+    background-color: green;
+    opacity: 0.8;
+    padding: 0px;
+}
+td.transformed {
+    -webkit-transform: translate(50px, 50px);
+}
+</style>
+<script>
+function simplifiedLayout()
+{
+    var cell = document.getElementsByTagName("td")[0];
+    // Force layout.
+    cell.offsetTop;
+    cell.classList.add("transformed");
+}
+window.addEventListener("load", simplifiedLayout);
+</script>
+</head>
+<p>Test for <a href="" and RenderTableCol::layout should never be called.</p>
+<p>This test checks that simplified layout works on a table with a &lt;col&gt;.</p>
+<table>
+    <col></col>
+    <tbody>
+        <tr><td></td></tr>
+    </tbody>
+</table>
+</html>
Property changes on: trunk/LayoutTests/fast/table/simplified-layout-table.html
___________________________________________________________________

Added: svn:executable

Modified: trunk/Source/WebCore/ChangeLog (132611 => 132612)


--- trunk/Source/WebCore/ChangeLog	2012-10-26 11:08:26 UTC (rev 132611)
+++ trunk/Source/WebCore/ChangeLog	2012-10-26 11:13:46 UTC (rev 132612)
@@ -1,3 +1,46 @@
+2012-10-26  Julien Chaffraix  <[email protected]>
+
+        RenderTableCol::computePreferredLogicalWidths and RenderTableCol::layout should never be called
+        https://bugs.webkit.org/show_bug.cgi?id=99861
+
+        Reviewed by Ojan Vafai.
+
+        RenderTableCol's computePreferredLogicalWidths and layout's only purpose were to clear the preferred logical
+        widths dirty / layout flag so that we would properly propagate the information to our containing table. This
+        led to clunky code where the table layout code had to forcefully call RenderTableCol::computePreferredLogicalWidths
+        or else we would ignore the next layout hint on the <col> or <colgroup>.
+
+        Tests: fast/table/col-span-change-relayout.html
+               fast/table/simplified-layout-table.html
+
+        * rendering/AutoTableLayout.cpp:
+        (WebCore::AutoTableLayout::recalcColumn):
+        * rendering/RenderTable.cpp:
+        (WebCore::RenderTable::layout):
+        Simplified the code now that we only need to iterate over the sections.
+
+        * rendering/FixedTableLayout.cpp:
+        (WebCore::FixedTableLayout::calcWidthArray):
+        Removed call to computePreferredLogicalWidths.
+
+        * rendering/RenderTableCol.cpp:
+        (WebCore::RenderTableCol::styleDidChange):
+        (WebCore::RenderTableCol::updateFromElement):
+        Forward a layout hint to the table so that we properly recompute the cell's logical withs.
+
+        (WebCore::RenderTableCol::computePreferredLogicalWidths):
+        (WebCore::RenderTableCol::layout):
+        Change our implementations of those 2 methods to be no-ops, while enforcing that they are
+        never called when it was possible.
+
+        (WebCore::RenderTableCol::propagateLayoutCueToTable):
+        New helper function that forward any layout cue to the containing table, this works around
+        us not clearing the flags which confuses RenderObject markContainingBlocksForLayout and
+        invalidateContainerPreferredLogicalWidths.
+
+        * rendering/RenderTableCol.h:
+        Made the function that we are not expected to be called private.
+
 2012-10-26  Sheriff Bot  <[email protected]>
 
         Unreviewed, rolling out r132601.

Modified: trunk/Source/WebCore/rendering/AutoTableLayout.cpp (132611 => 132612)


--- trunk/Source/WebCore/rendering/AutoTableLayout.cpp	2012-10-26 11:08:26 UTC (rev 132611)
+++ trunk/Source/WebCore/rendering/AutoTableLayout.cpp	2012-10-26 11:13:46 UTC (rev 132612)
@@ -49,81 +49,77 @@
     RenderTableCell* fixedContributor = 0;
     RenderTableCell* maxContributor = 0;
 
-    for (RenderObject* child = m_table->children()->firstChild(); child; child = child->nextSibling()) {
-        if (child->isRenderTableCol())
-            toRenderTableCol(child)->computePreferredLogicalWidths();
-        else if (child->isTableSection()) {
-            RenderTableSection* section = toRenderTableSection(child);
-            unsigned numRows = section->numRows();
-            for (unsigned i = 0; i < numRows; i++) {
-                RenderTableSection::CellStruct current = section->cellAt(i, effCol);
-                RenderTableCell* cell = current.primaryCell();
-                
-                if (current.inColSpan || !cell)
-                    continue;
+    for (RenderTableSection* section = m_table->topNonEmptySection(); section; section = m_table->sectionBelow(section, SkipEmptySections)) {
+        unsigned numRows = section->numRows();
+        ASSERT(numRows);
+        for (unsigned i = 0; i < numRows; i++) {
+            RenderTableSection::CellStruct current = section->cellAt(i, effCol);
+            RenderTableCell* cell = current.primaryCell();
 
-                bool cellHasContent = cell->children()->firstChild() || cell->style()->hasBorder() || cell->style()->hasPadding();
-                if (cellHasContent)
-                    columnLayout.emptyCellsOnly = false;
+            if (current.inColSpan || !cell)
+                continue;
 
-                // A cell originates in this column. Ensure we have
-                // a min/max width of at least 1px for this column now.
-                columnLayout.minLogicalWidth = max<int>(columnLayout.minLogicalWidth, cellHasContent ? 1 : 0);
-                columnLayout.maxLogicalWidth = max<int>(columnLayout.maxLogicalWidth, 1);
+            bool cellHasContent = cell->children()->firstChild() || cell->style()->hasBorder() || cell->style()->hasPadding();
+            if (cellHasContent)
+                columnLayout.emptyCellsOnly = false;
 
-                if (cell->colSpan() == 1) {
-                    if (cell->preferredLogicalWidthsDirty())
-                        cell->computePreferredLogicalWidths();
-                    columnLayout.minLogicalWidth = max<int>(cell->minPreferredLogicalWidth(), columnLayout.minLogicalWidth);
-                    if (cell->maxPreferredLogicalWidth() > columnLayout.maxLogicalWidth) {
-                        columnLayout.maxLogicalWidth = cell->maxPreferredLogicalWidth();
-                        maxContributor = cell;
-                    }
+            // A cell originates in this column. Ensure we have
+            // a min/max width of at least 1px for this column now.
+            columnLayout.minLogicalWidth = max<int>(columnLayout.minLogicalWidth, cellHasContent ? 1 : 0);
+            columnLayout.maxLogicalWidth = max<int>(columnLayout.maxLogicalWidth, 1);
 
-                    // All browsers implement a size limit on the cell's max width. 
-                    // Our limit is based on KHTML's representation that used 16 bits widths.
-                    // FIXME: Other browsers have a lower limit for the cell's max width. 
-                    const int cCellMaxWidth = 32760;
-                    Length cellLogicalWidth = cell->styleOrColLogicalWidth();
-                    if (cellLogicalWidth.value() > cCellMaxWidth)
-                        cellLogicalWidth.setValue(cCellMaxWidth);
-                    if (cellLogicalWidth.isNegative())
-                        cellLogicalWidth.setValue(0);
-                    switch (cellLogicalWidth.type()) {
-                    case Fixed:
-                        // ignore width=0
-                        if (cellLogicalWidth.isPositive() && !columnLayout.logicalWidth.isPercent()) {
-                            LayoutUnit logicalWidth = cell->adjustBorderBoxLogicalWidthForBoxSizing(cellLogicalWidth.value());
-                            if (columnLayout.logicalWidth.isFixed()) {
-                                // Nav/IE weirdness
-                                if ((logicalWidth > columnLayout.logicalWidth.value()) 
-                                    || ((columnLayout.logicalWidth.value() == logicalWidth) && (maxContributor == cell))) {
-                                    columnLayout.logicalWidth.setValue(Fixed, logicalWidth);
-                                    fixedContributor = cell;
-                                }
-                            } else {
+            if (cell->colSpan() == 1) {
+                if (cell->preferredLogicalWidthsDirty())
+                    cell->computePreferredLogicalWidths();
+                columnLayout.minLogicalWidth = max<int>(cell->minPreferredLogicalWidth(), columnLayout.minLogicalWidth);
+                if (cell->maxPreferredLogicalWidth() > columnLayout.maxLogicalWidth) {
+                    columnLayout.maxLogicalWidth = cell->maxPreferredLogicalWidth();
+                    maxContributor = cell;
+                }
+
+                // All browsers implement a size limit on the cell's max width.
+                // Our limit is based on KHTML's representation that used 16 bits widths.
+                // FIXME: Other browsers have a lower limit for the cell's max width.
+                const int cCellMaxWidth = 32760;
+                Length cellLogicalWidth = cell->styleOrColLogicalWidth();
+                if (cellLogicalWidth.value() > cCellMaxWidth)
+                    cellLogicalWidth.setValue(cCellMaxWidth);
+                if (cellLogicalWidth.isNegative())
+                    cellLogicalWidth.setValue(0);
+                switch (cellLogicalWidth.type()) {
+                case Fixed:
+                    // ignore width=0
+                    if (cellLogicalWidth.isPositive() && !columnLayout.logicalWidth.isPercent()) {
+                        LayoutUnit logicalWidth = cell->adjustBorderBoxLogicalWidthForBoxSizing(cellLogicalWidth.value());
+                        if (columnLayout.logicalWidth.isFixed()) {
+                            // Nav/IE weirdness
+                            if ((logicalWidth > columnLayout.logicalWidth.value())
+                                || ((columnLayout.logicalWidth.value() == logicalWidth) && (maxContributor == cell))) {
                                 columnLayout.logicalWidth.setValue(Fixed, logicalWidth);
                                 fixedContributor = cell;
                             }
+                        } else {
+                            columnLayout.logicalWidth.setValue(Fixed, logicalWidth);
+                            fixedContributor = cell;
                         }
-                        break;
-                    case Percent:
-                        m_hasPercent = true;
-                        if (cellLogicalWidth.isPositive() && (!columnLayout.logicalWidth.isPercent() || cellLogicalWidth.value() > columnLayout.logicalWidth.value()))
-                            columnLayout.logicalWidth = cellLogicalWidth;
-                        break;
-                    case Relative:
-                        // FIXME: Need to understand this case and whether it makes sense to compare values
-                        // which are not necessarily of the same type.
-                        if (cellLogicalWidth.value() > columnLayout.logicalWidth.value())
-                            columnLayout.logicalWidth = cellLogicalWidth;
-                    default:
-                        break;
                     }
-                } else if (!effCol || section->primaryCellAt(i, effCol - 1) != cell) {
-                    // This spanning cell originates in this column. Insert the cell into spanning cells list.
-                    insertSpanCell(cell);
+                    break;
+                case Percent:
+                    m_hasPercent = true;
+                    if (cellLogicalWidth.isPositive() && (!columnLayout.logicalWidth.isPercent() || cellLogicalWidth.value() > columnLayout.logicalWidth.value()))
+                        columnLayout.logicalWidth = cellLogicalWidth;
+                    break;
+                case Relative:
+                    // FIXME: Need to understand this case and whether it makes sense to compare values
+                    // which are not necessarily of the same type.
+                    if (cellLogicalWidth.value() > columnLayout.logicalWidth.value())
+                        columnLayout.logicalWidth = cellLogicalWidth;
+                default:
+                    break;
                 }
+            } else if (!effCol || section->primaryCellAt(i, effCol - 1) != cell) {
+                // This spanning cell originates in this column. Insert the cell into spanning cells list.
+                insertSpanCell(cell);
             }
         }
     }

Modified: trunk/Source/WebCore/rendering/FixedTableLayout.cpp (132611 => 132612)


--- trunk/Source/WebCore/rendering/FixedTableLayout.cpp	2012-10-26 11:08:26 UTC (rev 132611)
+++ trunk/Source/WebCore/rendering/FixedTableLayout.cpp	2012-10-26 11:13:46 UTC (rev 132612)
@@ -88,8 +88,6 @@
 
     unsigned currentEffectiveColumn = 0;
     for (RenderTableCol* col = m_table->firstColumn(); col; col = col->nextColumn()) {
-        col->computePreferredLogicalWidths();
-
         // Width specified by column-groups that have column child does not affect column width in fixed layout tables
         if (col->isTableColumnGroupWithColumnChildren())
             continue;

Modified: trunk/Source/WebCore/rendering/RenderTable.cpp (132611 => 132612)


--- trunk/Source/WebCore/rendering/RenderTable.cpp	2012-10-26 11:08:26 UTC (rev 132611)
+++ trunk/Source/WebCore/rendering/RenderTable.cpp	2012-10-26 11:13:46 UTC (rev 132612)
@@ -378,20 +378,15 @@
 
     bool collapsing = collapseBorders();
 
-    for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
-        if (child->isTableSection()) {
-            RenderTableSection* section = toRenderTableSection(child);
-            if (m_columnLogicalWidthChanged)
-                section->setChildNeedsLayout(true, MarkOnlyThis);
-            section->layoutIfNeeded();
-            totalSectionLogicalHeight += section->calcRowLogicalHeight();
-            if (collapsing)
-                section->recalcOuterBorder();
-            ASSERT(!section->needsLayout());
-        } else if (child->isRenderTableCol()) {
-            child->layoutIfNeeded();
-            ASSERT(!child->needsLayout());
-        }
+    // We ignore table col / colgroup in this iteration as they are only used to size the cell's widths during auto / fixed table layout.
+    for (RenderTableSection* section = topSection(); section; section = sectionBelow(section)) {
+        if (m_columnLogicalWidthChanged)
+            section->setChildNeedsLayout(true, MarkOnlyThis);
+        section->layoutIfNeeded();
+        totalSectionLogicalHeight += section->calcRowLogicalHeight();
+        if (collapsing)
+            section->recalcOuterBorder();
+        ASSERT(!section->needsLayout());
     }
 
     // If any table section moved vertically, we will just repaint everything from that

Modified: trunk/Source/WebCore/rendering/RenderTableCol.cpp (132611 => 132612)


--- trunk/Source/WebCore/rendering/RenderTableCol.cpp	2012-10-26 11:08:26 UTC (rev 132611)
+++ trunk/Source/WebCore/rendering/RenderTableCol.cpp	2012-10-26 11:13:46 UTC (rev 132612)
@@ -49,6 +49,9 @@
 {
     RenderBox::styleDidChange(diff, oldStyle);
 
+    if (diff == StyleDifferenceLayout)
+        propagateLayoutCueToTable();
+
     // If border was changed, notify table.
     if (parent()) {
         RenderTable* table = this->table();
@@ -66,8 +69,9 @@
         m_span = tc->span();
     } else
         m_span = !(style() && style()->display() == TABLE_COLUMN_GROUP);
-    if (m_span != oldSpan && style() && parent())
-        setNeedsLayoutAndPrefWidthsRecalc();
+
+    if (m_span != oldSpan && style())
+        propagateLayoutCueToTable();
 }
 
 void RenderTableCol::willBeRemovedFromTree()
@@ -114,12 +118,28 @@
 
 void RenderTableCol::computePreferredLogicalWidths()
 {
-    setPreferredLogicalWidthsDirty(false);
+    // <col> and <colgroup> don't have preferred logical widths as they have
+    // no content so computing our preferred logical widths is wasteful.
+    ASSERT_NOT_REACHED();
+}
 
-    for (RenderObject* child = firstChild(); child; child = child->nextSibling())
-        child->setPreferredLogicalWidthsDirty(false);
+void RenderTableCol::layout()
+{
+    // There is no need to layout table <col> or <colgroup> as they have no content.
+    // We cannot ASSERT_NOT_REACHED here as simplified normal flow layout forces
+    // layout on any renderer.
 }
 
+void RenderTableCol::propagateLayoutCueToTable() const
+{
+    // Forward any layout hint to the table: this is required as the table is
+    // the one to layout / compute preferred logical widths on all the cells.
+    if (RenderTable* table = this->table()) {
+        table->setChildNeedsLayout(true);
+        table->setPreferredLogicalWidthsDirty(true);
+    }
+}
+
 RenderTable* RenderTableCol::table() const
 {
     RenderObject* table = parent();

Modified: trunk/Source/WebCore/rendering/RenderTableCol.h (132611 => 132612)


--- trunk/Source/WebCore/rendering/RenderTableCol.h	2012-10-26 11:08:26 UTC (rev 132611)
+++ trunk/Source/WebCore/rendering/RenderTableCol.h	2012-10-26 11:13:46 UTC (rev 132612)
@@ -40,8 +40,6 @@
     const RenderObjectChildList* children() const { return &m_children; }
     RenderObjectChildList* children() { return &m_children; }
 
-    virtual void computePreferredLogicalWidths();
-
     unsigned span() const { return m_span; }
     void setSpan(unsigned span) { m_span = span; }
 
@@ -77,6 +75,9 @@
     virtual RenderObjectChildList* virtualChildren() { return children(); }
     virtual const RenderObjectChildList* virtualChildren() const { return children(); }
 
+    virtual void computePreferredLogicalWidths() OVERRIDE;
+    virtual void layout() OVERRIDE;
+
     virtual const char* renderName() const { return "RenderTableCol"; }
     virtual bool isRenderTableCol() const OVERRIDE { return true; }
     virtual void updateFromElement();
@@ -92,6 +93,8 @@
 
     virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
 
+    void propagateLayoutCueToTable() const;
+
     RenderTable* table() const;
 
     RenderObjectChildList m_children;
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to