There is additional space not belonged to a table between the table cells
https://bugs.webkit.org/show_bug.cgi?id=74864

Patch by Arpita Bahuguna <arpitabahuguna@gmail.com> on 2012-08-15
Reviewed by Julien Chaffraix.

Source/WebCore:

Hittest for a point on the edge, i.e. between two table columns, currently
does not return any matching underlying element.

A hittest on such a point (on the edge of two table columns) should return
the column that lies either on the logical right/bottom of the said point.

Tests: fast/table/hittest-tablecell-bottom-edge.html
       fast/table/hittest-tablecell-right-edge.html
       fast/table/hittest-tablecell-with-borders-bottom-edge.html
       fast/table/hittest-tablecell-with-borders-right-edge.html

* rendering/RenderTableSection.cpp:
(WebCore::RenderTableSection::spannedRows):
Removed the FIXME regarding the correctness of the usage of the upper_bound algorithm
since that is now verified by the testcases in this patch. Also, the comment
regarding the inconsistency between the algorithms used in spannedRows and spannedColumns
is no longer valid.

(WebCore::RenderTableSection::spannedColumns):
Changed lower_bound() algorithm to upper_bound() for obtaining the next column.
This is now similar to what is used for obtaining the next row in spannedRows().

LayoutTests:

* fast/table/hittest-tablecell-bottom-edge-expected.txt: Added.
* fast/table/hittest-tablecell-bottom-edge.html: Added.
* fast/table/hittest-tablecell-right-edge-expected.txt: Added.
* fast/table/hittest-tablecell-right-edge.html: Added.
Testcases added for verifying that the proper node is returned upon hit test
carried out at a point lying on the edge of two table cells.

* fast/table/hittest-tablecell-with-borders-bottom-edge-expected.txt: Added.
* fast/table/hittest-tablecell-with-borders-bottom-edge.html: Added.
* fast/table/hittest-tablecell-with-borders-right-edge-expected.txt: Added.
* fast/table/hittest-tablecell-with-borders-right-edge.html: Added.
These testcases verify the aforementioned behavior when the table cells
also have border specified for them.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@125684 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/rendering/RenderTableSection.cpp b/Source/WebCore/rendering/RenderTableSection.cpp
index 80e6465..d34070c 100644
--- a/Source/WebCore/rendering/RenderTableSection.cpp
+++ b/Source/WebCore/rendering/RenderTableSection.cpp
@@ -1092,8 +1092,6 @@
 CellSpan RenderTableSection::spannedRows(const LayoutRect& flippedRect) const
 {
     // Find the first row that starts after rect top.
-    // FIXME: Upper_bound might not be the correct algorithm here since it might skip empty rows, but it is
-    // consistent with behavior in the former point based hit-testing (but inconsistent with spannedColumns).
     unsigned nextRow = std::upper_bound(m_rowPos.begin(), m_rowPos.end(), flippedRect.y()) - m_rowPos.begin();
 
     if (nextRow == m_rowPos.size())
@@ -1118,20 +1116,24 @@
 {
     const Vector<int>& columnPos = table()->columnPositions();
 
-    // Find the first columnt that starts after rect left.
-    unsigned nextColumn = std::lower_bound(columnPos.begin(), columnPos.end(), flippedRect.x()) - columnPos.begin();
+    // Find the first column that starts after rect left.
+    // lower_bound doesn't handle the edge between two cells properly as it would wrongly return the
+    // cell on the logical top/left.
+    // upper_bound on the other hand properly returns the cell on the logical bottom/right, which also
+    // matches the behavior of other browsers.
+    unsigned nextColumn = std::upper_bound(columnPos.begin(), columnPos.end(), flippedRect.x()) - columnPos.begin();
 
     if (nextColumn == columnPos.size())
         return CellSpan(columnPos.size() - 1, columnPos.size() - 1); // After all columns.
 
     unsigned startColumn = nextColumn > 0 ? nextColumn - 1 : 0;
 
-    // Find the first row that starts after rect right.
+    // Find the first column that starts after rect right.
     unsigned endColumn;
     if (columnPos[nextColumn] >= flippedRect.maxX())
         endColumn = nextColumn;
     else {
-        endColumn = std::lower_bound(columnPos.begin() + nextColumn, columnPos.end(), flippedRect.maxX()) - columnPos.begin();
+        endColumn = std::upper_bound(columnPos.begin() + nextColumn, columnPos.end(), flippedRect.maxX()) - columnPos.begin();
         if (endColumn == columnPos.size())
             endColumn = columnPos.size() - 1;
     }