There is additional space not belonged to a table between the table cells
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 15 Aug 2012 18:01:05 +0000 (18:01 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 15 Aug 2012 18:01:05 +0000 (18:01 +0000)
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: https://svn.webkit.org/repository/webkit/trunk@125684 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/fast/table/hittest-tablecell-bottom-edge-expected.txt [new file with mode: 0644]
LayoutTests/fast/table/hittest-tablecell-bottom-edge.html [new file with mode: 0644]
LayoutTests/fast/table/hittest-tablecell-right-edge-expected.txt [new file with mode: 0644]
LayoutTests/fast/table/hittest-tablecell-right-edge.html [new file with mode: 0644]
LayoutTests/fast/table/hittest-tablecell-with-borders-bottom-edge-expected.txt [new file with mode: 0644]
LayoutTests/fast/table/hittest-tablecell-with-borders-bottom-edge.html [new file with mode: 0644]
LayoutTests/fast/table/hittest-tablecell-with-borders-right-edge-expected.txt [new file with mode: 0644]
LayoutTests/fast/table/hittest-tablecell-with-borders-right-edge.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/rendering/RenderTableSection.cpp

index c5a6edd..4e1a303 100644 (file)
@@ -1,3 +1,24 @@
+2012-08-15  Arpita Bahuguna  <arpitabahuguna@gmail.com>
+
+        There is additional space not belonged to a table between the table cells
+        https://bugs.webkit.org/show_bug.cgi?id=74864
+
+        Reviewed by Julien Chaffraix.
+
+        * 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.
+
 2012-08-15  Anna Cavender  <annacc@chromium.org>
 
         Add the timestampOffset attribute to SourceBuffer.
diff --git a/LayoutTests/fast/table/hittest-tablecell-bottom-edge-expected.txt b/LayoutTests/fast/table/hittest-tablecell-bottom-edge-expected.txt
new file mode 100644 (file)
index 0000000..609790e
--- /dev/null
@@ -0,0 +1,75 @@
+Test for Bugzilla Bug 74864: There is additional space not belonged to a table between the table cells.
+
+An event generated on the edge of a table cell is not being consumed by the appropriate underlying element. This test verifies that the hittest result on the bottom edge of a table cell returns the proper underlying element.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Executing for element tr1-td1 on the bottom edge of the table cell:
+PASS document.elementFromPoint(middleX, edge - 1).id is 'tr1-td1'
+PASS document.elementFromPoint(middleX, edge).id is 'tr2-td1'
+PASS document.elementFromPoint(middleX, edge + 1).id is 'tr2-td1'
+Executing for element tr1-td2 on the bottom edge of the table cell:
+PASS document.elementFromPoint(middleX, edge - 1).id is 'tr1-td1'
+PASS document.elementFromPoint(middleX, edge).id is 'tr2-td1'
+PASS document.elementFromPoint(middleX, edge + 1).id is 'tr2-td1'
+Executing for element tr1-td3 on the bottom edge of the table cell:
+PASS document.elementFromPoint(middleX, edge - 1).id is 'tr1-td1'
+PASS document.elementFromPoint(middleX, edge).id is 'tr2-td1'
+PASS document.elementFromPoint(middleX, edge + 1).id is 'tr2-td1'
+Executing for element tr1-td4 on the bottom edge of the table cell:
+PASS document.elementFromPoint(middleX, edge - 1).id is 'tr1-td2'
+PASS document.elementFromPoint(middleX, edge).id is 'tr2-td2'
+PASS document.elementFromPoint(middleX, edge + 1).id is 'tr2-td2'
+Executing for element tr2-td1 on the bottom edge of the table cell:
+PASS document.elementFromPoint(middleX, edge - 1).id is 'tr2-td1'
+PASS document.elementFromPoint(middleX, edge).id is 'tr4-td1'
+PASS document.elementFromPoint(middleX, edge + 1).id is 'tr4-td1'
+Executing for element tr2-td2 on the bottom edge of the table cell:
+PASS document.elementFromPoint(middleX, edge - 1).id is 'tr2-td1'
+PASS document.elementFromPoint(middleX, edge).id is 'tr4-td1'
+PASS document.elementFromPoint(middleX, edge + 1).id is 'tr4-td1'
+Executing for element tr2-td3 on the bottom edge of the table cell:
+PASS document.elementFromPoint(middleX, edge - 1).id is 'tr2-td1'
+PASS document.elementFromPoint(middleX, edge).id is 'tr4-td1'
+PASS document.elementFromPoint(middleX, edge + 1).id is 'tr4-td1'
+Executing for element tr2-td4 on the bottom edge of the table cell:
+PASS document.elementFromPoint(middleX, edge - 1).id is 'tr2-td2'
+PASS document.elementFromPoint(middleX, edge).id is 'tr4-td2'
+PASS document.elementFromPoint(middleX, edge + 1).id is 'tr4-td2'
+Executing for element tr3-td1 on the bottom edge of the table cell:
+PASS document.elementFromPoint(middleX, edge - 1).id is ''
+PASS document.elementFromPoint(middleX, edge).id is 'tr4-td1'
+PASS document.elementFromPoint(middleX, edge + 1).id is 'tr4-td1'
+Executing for element tr3-td2 on the bottom edge of the table cell:
+PASS document.elementFromPoint(middleX, edge - 1).id is ''
+PASS document.elementFromPoint(middleX, edge).id is 'tr4-td1'
+PASS document.elementFromPoint(middleX, edge + 1).id is 'tr4-td1'
+Executing for element tr3-td3 on the bottom edge of the table cell:
+PASS document.elementFromPoint(middleX, edge - 1).id is ''
+PASS document.elementFromPoint(middleX, edge).id is 'tr4-td1'
+PASS document.elementFromPoint(middleX, edge + 1).id is 'tr4-td1'
+Executing for element tr3-td4 on the bottom edge of the table cell:
+PASS document.elementFromPoint(middleX, edge - 1).id is ''
+PASS document.elementFromPoint(middleX, edge).id is 'tr4-td2'
+PASS document.elementFromPoint(middleX, edge + 1).id is 'tr4-td2'
+Executing for element tr4-td1 on the bottom edge of the table cell:
+PASS document.elementFromPoint(middleX, edge - 1).id is 'tr4-td1'
+PASS document.elementFromPoint(middleX, edge).id is ''
+PASS document.elementFromPoint(middleX, edge + 1).id is ''
+Executing for element tr4-td2 on the bottom edge of the table cell:
+PASS document.elementFromPoint(middleX, edge - 1).id is 'tr4-td2'
+PASS document.elementFromPoint(middleX, edge).id is ''
+PASS document.elementFromPoint(middleX, edge + 1).id is ''
+Executing for element tr4-td3 on the bottom edge of the table cell:
+PASS document.elementFromPoint(middleX, edge - 1).id is ''
+PASS document.elementFromPoint(middleX, edge).id is ''
+PASS document.elementFromPoint(middleX, edge + 1).id is ''
+Executing for element tr4-td4 on the bottom edge of the table cell:
+PASS document.elementFromPoint(middleX, edge - 1).id is 'tr4-td4'
+PASS document.elementFromPoint(middleX, edge).id is ''
+PASS document.elementFromPoint(middleX, edge + 1).id is ''
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/table/hittest-tablecell-bottom-edge.html b/LayoutTests/fast/table/hittest-tablecell-bottom-edge.html
new file mode 100644 (file)
index 0000000..9718a0e
--- /dev/null
@@ -0,0 +1,134 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../js/resources/js-test-pre.js"></script>
+<script>
+function test()
+{
+    description("An event generated on the edge of a table cell is not being consumed by the appropriate underlying element. This test verifies that the hittest result on the bottom edge of a table cell returns the proper underlying element.");
+               
+    var ele = {};      
+    ['tr1-td1', 'tr1-td2', 'tr1-td3', 'tr1-td4',
+     'tr2-td1', 'tr2-td2', 'tr2-td3', 'tr2-td4',
+     'tr3-td1', 'tr3-td2', 'tr3-td3', 'tr3-td4',
+     'tr4-td1', 'tr4-td2', 'tr4-td3', 'tr4-td4'].forEach(function(a) {
+        ele[a] = document.getElementById(a);
+        hittest(ele[a], a);
+        ele[a].innerHTML = '';
+    });
+
+    isSuccessfullyParsed();
+}
+function hittest(ele, orgElement, expected1, expected2)
+{      
+    middleX = ele.getBoundingClientRect().right / 2;
+    edge = ele.getBoundingClientRect().bottom;
+    debug('Executing for element '+orgElement+' on the bottom edge of the table cell:');
+    
+    switch (orgElement) {
+    case ('tr1-td1'):
+        shouldBe("document.elementFromPoint(middleX, edge - 1).id", "'tr1-td1'");
+               shouldBe("document.elementFromPoint(middleX, edge).id", "'tr2-td1'");
+               shouldBe("document.elementFromPoint(middleX, edge + 1).id", "'tr2-td1'");
+               break;
+       case ('tr1-td2'):
+       case ('tr1-td3'):
+               shouldBe("document.elementFromPoint(middleX, edge - 1).id", "'tr1-td1'");
+               shouldBe("document.elementFromPoint(middleX, edge).id", "'tr2-td1'");
+               shouldBe("document.elementFromPoint(middleX, edge + 1).id", "'tr2-td1'");
+               break;
+       case ('tr1-td4'):
+               shouldBe("document.elementFromPoint(middleX, edge - 1).id", "'tr1-td2'");
+               shouldBe("document.elementFromPoint(middleX, edge).id", "'tr2-td2'");
+               shouldBe("document.elementFromPoint(middleX, edge + 1).id", "'tr2-td2'");
+               break;
+       case ('tr2-td1'):
+       case ('tr2-td2'): 
+       case ('tr2-td3'):                
+               shouldBe("document.elementFromPoint(middleX, edge - 1).id", "'tr2-td1'");
+               shouldBe("document.elementFromPoint(middleX, edge).id", "'tr4-td1'");
+               shouldBe("document.elementFromPoint(middleX, edge + 1).id", "'tr4-td1'");
+               break;
+       case ('tr2-td4'):
+               shouldBe("document.elementFromPoint(middleX, edge - 1).id", "'tr2-td2'");
+               shouldBe("document.elementFromPoint(middleX, edge).id", "'tr4-td2'");
+               shouldBe("document.elementFromPoint(middleX, edge + 1).id", "'tr4-td2'");
+               break;
+   case ('tr3-td1'):
+   case ('tr3-td2'):
+   case ('tr3-td3'):              
+               shouldBe("document.elementFromPoint(middleX, edge - 1).id", "''");
+               shouldBe("document.elementFromPoint(middleX, edge).id", "'tr4-td1'");
+               shouldBe("document.elementFromPoint(middleX, edge + 1).id", "'tr4-td1'");
+               break;
+       case ('tr3-td4'):
+               shouldBe("document.elementFromPoint(middleX, edge - 1).id", "''");
+               shouldBe("document.elementFromPoint(middleX, edge).id", "'tr4-td2'");
+               shouldBe("document.elementFromPoint(middleX, edge + 1).id", "'tr4-td2'");
+               break;
+       case ('tr4-td1'):
+               shouldBe("document.elementFromPoint(middleX, edge - 1).id", "'tr4-td1'");
+               shouldBe("document.elementFromPoint(middleX, edge).id", "''");
+               shouldBe("document.elementFromPoint(middleX, edge + 1).id", "''");
+               break;
+       case ('tr4-td2'):
+               shouldBe("document.elementFromPoint(middleX, edge - 1).id", "'tr4-td2'");
+               shouldBe("document.elementFromPoint(middleX, edge).id", "''");
+               shouldBe("document.elementFromPoint(middleX, edge + 1).id", "''");
+               break;        
+       case ('tr4-td3'):        
+               shouldBe("document.elementFromPoint(middleX, edge - 1).id", "''");
+               shouldBe("document.elementFromPoint(middleX, edge).id", "''");
+               shouldBe("document.elementFromPoint(middleX, edge + 1).id", "''");
+               break;
+       case ('tr4-td4'):
+               shouldBe("document.elementFromPoint(middleX, edge - 1).id", "'tr4-td4'");
+               shouldBe("document.elementFromPoint(middleX, edge).id", "''");
+               shouldBe("document.elementFromPoint(middleX, edge + 1).id", "''");
+               break;
+       default:
+               break;
+    }
+}
+</script>
+<style>
+    table
+    {
+        border-spacing: 0px;
+        font-size: 1000%;
+    }
+    td { padding: 0px; }
+</style>
+</head>
+<body onload="test()">
+    <p>Test for Bugzilla <a href="https://bugs.webkit.org/show_bug.cgi?id=74864">Bug 74864</a>: There is additional space not belonged to a table between the table cells.</p>
+    <table cellspacing=0>
+        <tr id="tr1">
+            <td id="tr1-td1">1</td>
+            <td id="tr1-td2">1</td>
+            <td id="tr1-td3"></td>
+            <td id="tr1-td4">1</td>
+        </tr>
+        <tr id="tr2">
+            <td id="tr2-td1">1</td>
+            <td id="tr2-td2">1</td>
+            <td id="tr2-td3"></td>
+            <td id="tr2-td4">1</td>
+        </tr>
+        <tr id="tr3">
+            <td id="tr3-td1"></td>
+            <td id="tr3-td2"></td>
+            <td id="tr3-td3"></td>
+            <td id="tr3-td4"></td>
+        </tr>  
+        <tr id="tr4">
+            <td id="tr4-td1">1</td>
+            <td id="tr4-td2">1</td>
+            <td id="tr4-td3"></td>            
+            <td id="tr4-td4">1</td>
+        </tr>              
+    </table>
+    <p id="description"></p>
+    <div id="console"></div>
+</body>
+</html>
diff --git a/LayoutTests/fast/table/hittest-tablecell-right-edge-expected.txt b/LayoutTests/fast/table/hittest-tablecell-right-edge-expected.txt
new file mode 100644 (file)
index 0000000..6dc62f5
--- /dev/null
@@ -0,0 +1,75 @@
+Test for Bugzilla Bug 74864: There is additional space not belonged to a table between the table cells.
+
+An event generated on the edge of a table cell is not being consumed by the appropriate underlying element. This test verifies that the hittest result on the right edge of a table cell returns the proper underlying element.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Executing for element tr1-td1 on the right edge of the table cell:
+PASS document.elementFromPoint(edge - 1, middleY).id is 'tr1-td1'
+PASS document.elementFromPoint(edge, middleY).id is 'tr1-td2'
+PASS document.elementFromPoint(edge + 1, middleY).id is 'tr1-td2'
+Executing for element tr1-td2 on the right edge of the table cell:
+PASS document.elementFromPoint(edge - 1, middleY).id is 'tr1-td2'
+PASS document.elementFromPoint(edge, middleY).id is 'tr1-td4'
+PASS document.elementFromPoint(edge + 1, middleY).id is 'tr1-td4'
+Executing for element tr1-td3 on the right edge of the table cell:
+PASS document.elementFromPoint(edge - 1, middleY).id is 'tr1-td2'
+PASS document.elementFromPoint(edge, middleY).id is 'tr1-td4'
+PASS document.elementFromPoint(edge + 1, middleY).id is 'tr1-td4'
+Executing for element tr1-td4 on the right edge of the table cell:
+PASS document.elementFromPoint(edge - 1, middleY).id is 'tr1-td4'
+PASS document.elementFromPoint(edge, middleY).id is ''
+PASS document.elementFromPoint(edge + 1, middleY).id is ''
+Executing for element tr2-td1 on the right edge of the table cell:
+PASS document.elementFromPoint(edge - 1, middleY).id is 'tr2-td1'
+PASS document.elementFromPoint(edge, middleY).id is 'tr2-td2'
+PASS document.elementFromPoint(edge + 1, middleY).id is 'tr2-td2'
+Executing for element tr2-td2 on the right edge of the table cell:
+PASS document.elementFromPoint(edge - 1, middleY).id is 'tr2-td2'
+PASS document.elementFromPoint(edge, middleY).id is 'tr2-td4'
+PASS document.elementFromPoint(edge + 1, middleY).id is 'tr2-td4'
+Executing for element tr2-td3 on the right edge of the table cell:
+PASS document.elementFromPoint(edge - 1, middleY).id is 'tr2-td2'
+PASS document.elementFromPoint(edge, middleY).id is 'tr2-td4'
+PASS document.elementFromPoint(edge + 1, middleY).id is 'tr2-td4'
+Executing for element tr2-td4 on the right edge of the table cell:
+PASS document.elementFromPoint(edge - 1, middleY).id is 'tr2-td4'
+PASS document.elementFromPoint(edge, middleY).id is ''
+PASS document.elementFromPoint(edge + 1, middleY).id is ''
+Executing for element tr3-td1 on the right edge of the table cell:
+PASS document.elementFromPoint(edge - 1, middleY).id is ''
+PASS document.elementFromPoint(edge, middleY).id is ''
+PASS document.elementFromPoint(edge + 1, middleY).id is ''
+Executing for element tr3-td2 on the right edge of the table cell:
+PASS document.elementFromPoint(edge - 1, middleY).id is ''
+PASS document.elementFromPoint(edge, middleY).id is ''
+PASS document.elementFromPoint(edge + 1, middleY).id is ''
+Executing for element tr3-td3 on the right edge of the table cell:
+PASS document.elementFromPoint(edge - 1, middleY).id is ''
+PASS document.elementFromPoint(edge, middleY).id is ''
+PASS document.elementFromPoint(edge + 1, middleY).id is ''
+Executing for element tr3-td4 on the right edge of the table cell:
+PASS document.elementFromPoint(edge - 1, middleY).id is ''
+PASS document.elementFromPoint(edge, middleY).id is ''
+PASS document.elementFromPoint(edge + 1, middleY).id is ''
+Executing for element tr4-td1 on the right edge of the table cell:
+PASS document.elementFromPoint(edge - 1, middleY).id is 'tr4-td1'
+PASS document.elementFromPoint(edge, middleY).id is 'tr4-td2'
+PASS document.elementFromPoint(edge + 1, middleY).id is 'tr4-td2'
+Executing for element tr4-td2 on the right edge of the table cell:
+PASS document.elementFromPoint(edge - 1, middleY).id is 'tr4-td2'
+PASS document.elementFromPoint(edge, middleY).id is 'tr4-td4'
+PASS document.elementFromPoint(edge + 1, middleY).id is 'tr4-td4'
+Executing for element tr4-td3 on the right edge of the table cell:
+PASS document.elementFromPoint(edge - 1, middleY).id is ''
+PASS document.elementFromPoint(edge, middleY).id is 'tr4-td4'
+PASS document.elementFromPoint(edge + 1, middleY).id is 'tr4-td4'
+Executing for element tr4-td4 on the right edge of the table cell:
+PASS document.elementFromPoint(edge - 1, middleY).id is 'tr4-td4'
+PASS document.elementFromPoint(edge, middleY).id is ''
+PASS document.elementFromPoint(edge + 1, middleY).id is ''
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/table/hittest-tablecell-right-edge.html b/LayoutTests/fast/table/hittest-tablecell-right-edge.html
new file mode 100644 (file)
index 0000000..53b1c07
--- /dev/null
@@ -0,0 +1,138 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../js/resources/js-test-pre.js"></script>
+<script>
+function test()
+{
+    description("An event generated on the edge of a table cell is not being consumed by the appropriate underlying element. This test verifies that the hittest result on the right edge of a table cell returns the proper underlying element.");
+               
+    var ele = {};      
+    ['tr1-td1', 'tr1-td2', 'tr1-td3', 'tr1-td4',
+     'tr2-td1', 'tr2-td2', 'tr2-td3', 'tr2-td4',
+     'tr3-td1', 'tr3-td2', 'tr3-td3', 'tr3-td4',
+     'tr4-td1', 'tr4-td2', 'tr4-td3', 'tr4-td4'].forEach(function(a) {
+        ele[a] = document.getElementById(a);
+        hittest(ele[a], a);
+        ele[a].innerHTML = '';
+    });
+
+    isSuccessfullyParsed();
+}
+function hittest(ele, orgElement, expected1, expected2)
+{      
+    edge = ele.getBoundingClientRect().right;
+    middleY = ele.getBoundingClientRect().bottom / 2;
+    debug('Executing for element '+orgElement+' on the right edge of the table cell:');
+    
+    switch (orgElement) {
+       case ('tr1-td1'):
+               shouldBe("document.elementFromPoint(edge - 1, middleY).id", "'tr1-td1'");
+               shouldBe("document.elementFromPoint(edge, middleY).id", "'tr1-td2'");
+               shouldBe("document.elementFromPoint(edge + 1, middleY).id", "'tr1-td2'");
+               break;
+       case ('tr1-td2'):
+               shouldBe("document.elementFromPoint(edge - 1, middleY).id", "'tr1-td2'");
+               shouldBe("document.elementFromPoint(edge, middleY).id", "'tr1-td4'");
+               shouldBe("document.elementFromPoint(edge + 1, middleY).id", "'tr1-td4'");
+               break;        
+       case ('tr1-td3'):
+               shouldBe("document.elementFromPoint(edge - 1, middleY).id", "'tr1-td2'");
+               shouldBe("document.elementFromPoint(edge, middleY).id", "'tr1-td4'");
+               shouldBe("document.elementFromPoint(edge + 1, middleY).id", "'tr1-td4'");
+               break;
+       case ('tr1-td4'):
+               shouldBe("document.elementFromPoint(edge - 1, middleY).id", "'tr1-td4'");
+               shouldBe("document.elementFromPoint(edge, middleY).id", "''");
+               shouldBe("document.elementFromPoint(edge + 1, middleY).id", "''");
+               break;
+       case ('tr2-td1'):
+               shouldBe("document.elementFromPoint(edge - 1, middleY).id", "'tr2-td1'");
+               shouldBe("document.elementFromPoint(edge, middleY).id", "'tr2-td2'");
+               shouldBe("document.elementFromPoint(edge + 1, middleY).id", "'tr2-td2'");
+               break;
+       case ('tr2-td2'):
+       case ('tr2-td3'):        
+               shouldBe("document.elementFromPoint(edge - 1, middleY).id", "'tr2-td2'");
+               shouldBe("document.elementFromPoint(edge, middleY).id", "'tr2-td4'");
+               shouldBe("document.elementFromPoint(edge + 1, middleY).id", "'tr2-td4'");
+               break; 
+       case ('tr2-td4'):
+               shouldBe("document.elementFromPoint(edge - 1, middleY).id", "'tr2-td4'");
+               shouldBe("document.elementFromPoint(edge, middleY).id", "''");
+               shouldBe("document.elementFromPoint(edge + 1, middleY).id", "''");
+               break;
+       case ('tr3-td1'):
+       case ('tr3-td2'):
+       case ('tr3-td3'):
+       case ('tr3-td4'):
+               shouldBe("document.elementFromPoint(edge - 1, middleY).id", "''");
+               shouldBe("document.elementFromPoint(edge, middleY).id", "''");
+               shouldBe("document.elementFromPoint(edge + 1, middleY).id", "''");
+               break;
+       case ('tr4-td1'):
+               shouldBe("document.elementFromPoint(edge - 1, middleY).id", "'tr4-td1'");
+               shouldBe("document.elementFromPoint(edge, middleY).id", "'tr4-td2'");
+               shouldBe("document.elementFromPoint(edge + 1, middleY).id", "'tr4-td2'");
+               break;
+       case ('tr4-td2'):
+               shouldBe("document.elementFromPoint(edge - 1, middleY).id", "'tr4-td2'");
+               shouldBe("document.elementFromPoint(edge, middleY).id", "'tr4-td4'");
+               shouldBe("document.elementFromPoint(edge + 1, middleY).id", "'tr4-td4'");
+               break;        
+       case ('tr4-td3'):        
+               shouldBe("document.elementFromPoint(edge - 1, middleY).id", "''");
+               shouldBe("document.elementFromPoint(edge, middleY).id", "'tr4-td4'");
+               shouldBe("document.elementFromPoint(edge + 1, middleY).id", "'tr4-td4'");
+               break;
+       case ('tr4-td4'):
+               shouldBe("document.elementFromPoint(edge - 1, middleY).id", "'tr4-td4'");
+               shouldBe("document.elementFromPoint(edge, middleY).id", "''");
+               shouldBe("document.elementFromPoint(edge + 1, middleY).id", "''");
+               break;
+       default:
+               break;
+    }
+}
+</script>
+<style>
+    table
+    {
+        border-spacing: 0px;
+        font-size: 1000%;
+    }
+    td { padding: 0px; }
+</style>
+</head>
+<body onload="test()">
+    <p>Test for Bugzilla <a href="https://bugs.webkit.org/show_bug.cgi?id=74864">Bug 74864</a>: There is additional space not belonged to a table between the table cells.</p>
+    <table cellspacing=0>
+        <tr id="tr1">
+            <td id="tr1-td1">1</td>
+            <td id="tr1-td2">1</td>
+            <td id="tr1-td3"></td>
+            <td id="tr1-td4">1</td>
+        </tr>
+        <tr id="tr2">
+            <td id="tr2-td1">1</td>
+            <td id="tr2-td2">1</td>
+            <td id="tr2-td3"></td>
+            <td id="tr2-td4">1</td>
+        </tr>
+        <tr id="tr3">
+            <td id="tr3-td1"></td>
+            <td id="tr3-td2"></td>
+            <td id="tr3-td3"></td>
+            <td id="tr3-td4"></td>
+        </tr>  
+        <tr id="tr4">
+            <td id="tr4-td1">1</td>
+            <td id="tr4-td2">1</td>
+            <td id="tr4-td3"></td>            
+            <td id="tr4-td4">1</td>
+        </tr>              
+    </table>
+    <p id="description"></p>
+    <div id="console"></div>
+</body>
+</html>
diff --git a/LayoutTests/fast/table/hittest-tablecell-with-borders-bottom-edge-expected.txt b/LayoutTests/fast/table/hittest-tablecell-with-borders-bottom-edge-expected.txt
new file mode 100644 (file)
index 0000000..401789b
--- /dev/null
@@ -0,0 +1,75 @@
+Test for Bugzilla Bug 74864: There is additional space not belonged to a table between the table cells.
+
+An event generated on the edge of a table cell is not being consumed by the appropriate underlying element. This test verifies that the hittest result on the bottom edge of a table cell (with borders) returns the proper underlying element.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Executing for element tr1-td1 on the bottom edge of the table cell:
+PASS document.elementFromPoint(middleX, edge - 1).id is 'tr1-td1'
+PASS document.elementFromPoint(middleX, edge).id is 'tr2-td1'
+PASS document.elementFromPoint(middleX, edge + 1).id is 'tr2-td1'
+Executing for element tr1-td2 on the bottom edge of the table cell:
+PASS document.elementFromPoint(middleX, edge - 1).id is 'tr1-td1'
+PASS document.elementFromPoint(middleX, edge).id is 'tr2-td1'
+PASS document.elementFromPoint(middleX, edge + 1).id is 'tr2-td1'
+Executing for element tr1-td3 on the bottom edge of the table cell:
+PASS document.elementFromPoint(middleX, edge - 1).id is 'tr1-td1'
+PASS document.elementFromPoint(middleX, edge).id is 'tr2-td1'
+PASS document.elementFromPoint(middleX, edge + 1).id is 'tr2-td1'
+Executing for element tr1-td4 on the bottom edge of the table cell:
+PASS document.elementFromPoint(middleX, edge - 1).id is 'tr1-td2'
+PASS document.elementFromPoint(middleX, edge).id is 'tr2-td2'
+PASS document.elementFromPoint(middleX, edge + 1).id is 'tr2-td2'
+Executing for element tr2-td1 on the bottom edge of the table cell:
+PASS document.elementFromPoint(middleX, edge - 1).id is 'tr2-td1'
+PASS document.elementFromPoint(middleX, edge).id is 'tr3-td1'
+PASS document.elementFromPoint(middleX, edge + 1).id is 'tr3-td1'
+Executing for element tr2-td2 on the bottom edge of the table cell:
+PASS document.elementFromPoint(middleX, edge - 1).id is 'tr2-td1'
+PASS document.elementFromPoint(middleX, edge).id is 'tr3-td1'
+PASS document.elementFromPoint(middleX, edge + 1).id is 'tr3-td1'
+Executing for element tr2-td3 on the bottom edge of the table cell:
+PASS document.elementFromPoint(middleX, edge - 1).id is 'tr2-td1'
+PASS document.elementFromPoint(middleX, edge).id is 'tr3-td1'
+PASS document.elementFromPoint(middleX, edge + 1).id is 'tr3-td1'
+Executing for element tr2-td4 on the bottom edge of the table cell:
+PASS document.elementFromPoint(middleX, edge - 1).id is 'tr2-td2'
+PASS document.elementFromPoint(middleX, edge).id is 'tr3-td2'
+PASS document.elementFromPoint(middleX, edge + 1).id is 'tr3-td2'
+Executing for element tr3-td1 on the bottom edge of the table cell:
+PASS document.elementFromPoint(middleX, edge - 1).id is 'tr3-td1'
+PASS document.elementFromPoint(middleX, edge).id is 'tr4-td1'
+PASS document.elementFromPoint(middleX, edge + 1).id is 'tr4-td1'
+Executing for element tr3-td2 on the bottom edge of the table cell:
+PASS document.elementFromPoint(middleX, edge - 1).id is 'tr3-td1'
+PASS document.elementFromPoint(middleX, edge).id is 'tr4-td1'
+PASS document.elementFromPoint(middleX, edge + 1).id is 'tr4-td1'
+Executing for element tr3-td3 on the bottom edge of the table cell:
+PASS document.elementFromPoint(middleX, edge - 1).id is 'tr3-td1'
+PASS document.elementFromPoint(middleX, edge).id is 'tr4-td1'
+PASS document.elementFromPoint(middleX, edge + 1).id is 'tr4-td1'
+Executing for element tr3-td4 on the bottom edge of the table cell:
+PASS document.elementFromPoint(middleX, edge - 1).id is 'tr3-td2'
+PASS document.elementFromPoint(middleX, edge).id is 'tr4-td2'
+PASS document.elementFromPoint(middleX, edge + 1).id is 'tr4-td2'
+Executing for element tr4-td1 on the bottom edge of the table cell:
+PASS document.elementFromPoint(middleX, edge - 1).id is 'tr4-td1'
+PASS document.elementFromPoint(middleX, edge).id is ''
+PASS document.elementFromPoint(middleX, edge + 1).id is ''
+Executing for element tr4-td2 on the bottom edge of the table cell:
+PASS document.elementFromPoint(middleX, edge - 1).id is 'tr4-td2'
+PASS document.elementFromPoint(middleX, edge).id is ''
+PASS document.elementFromPoint(middleX, edge + 1).id is ''
+Executing for element tr4-td3 on the bottom edge of the table cell:
+PASS document.elementFromPoint(middleX, edge - 1).id is ''
+PASS document.elementFromPoint(middleX, edge).id is ''
+PASS document.elementFromPoint(middleX, edge + 1).id is ''
+Executing for element tr4-td4 on the bottom edge of the table cell:
+PASS document.elementFromPoint(middleX, edge - 1).id is 'tr4-td4'
+PASS document.elementFromPoint(middleX, edge).id is ''
+PASS document.elementFromPoint(middleX, edge + 1).id is ''
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/table/hittest-tablecell-with-borders-bottom-edge.html b/LayoutTests/fast/table/hittest-tablecell-with-borders-bottom-edge.html
new file mode 100644 (file)
index 0000000..e342b6e
--- /dev/null
@@ -0,0 +1,142 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../js/resources/js-test-pre.js"></script>
+<script>
+function test()
+{
+    description("An event generated on the edge of a table cell is not being consumed by the appropriate underlying element. This test verifies that the hittest result on the bottom edge of a table cell (with borders) returns the proper underlying element.");
+               
+    var ele = {};      
+    ['tr1-td1', 'tr1-td2', 'tr1-td3', 'tr1-td4',
+     'tr2-td1', 'tr2-td2', 'tr2-td3', 'tr2-td4',
+     'tr3-td1', 'tr3-td2', 'tr3-td3', 'tr3-td4',
+     'tr4-td1', 'tr4-td2', 'tr4-td3', 'tr4-td4'].forEach(function(a) {
+        ele[a] = document.getElementById(a);
+        hittest(ele[a], a);
+        ele[a].innerHTML = '';
+    });
+
+    isSuccessfullyParsed();
+}
+function hittest(ele, orgElement, expected1, expected2)
+{      
+    middleX = ele.getBoundingClientRect().right / 2;
+    edge = ele.getBoundingClientRect().bottom;
+    debug('Executing for element '+orgElement+' on the bottom edge of the table cell:');
+    
+    switch(orgElement) {
+       case ('tr1-td1'):
+               shouldBe("document.elementFromPoint(middleX, edge - 1).id", "'tr1-td1'");
+               shouldBe("document.elementFromPoint(middleX, edge).id", "'tr2-td1'");
+               shouldBe("document.elementFromPoint(middleX, edge + 1).id", "'tr2-td1'");
+               break;
+       case ('tr1-td2'):
+       case ('tr1-td3'):
+               shouldBe("document.elementFromPoint(middleX, edge - 1).id", "'tr1-td1'");
+               shouldBe("document.elementFromPoint(middleX, edge).id", "'tr2-td1'");
+               shouldBe("document.elementFromPoint(middleX, edge + 1).id", "'tr2-td1'");
+               break;
+       case ('tr1-td4'):
+               shouldBe("document.elementFromPoint(middleX, edge - 1).id", "'tr1-td2'");
+               shouldBe("document.elementFromPoint(middleX, edge).id", "'tr2-td2'");
+               shouldBe("document.elementFromPoint(middleX, edge + 1).id", "'tr2-td2'");
+               break;
+       case ('tr2-td1'):
+               shouldBe("document.elementFromPoint(middleX, edge - 1).id", "'tr2-td1'");
+               shouldBe("document.elementFromPoint(middleX, edge).id", "'tr3-td1'");
+               shouldBe("document.elementFromPoint(middleX, edge + 1).id", "'tr3-td1'");
+               break;
+       case ('tr2-td2'):
+       case ('tr2-td3'):        
+               shouldBe("document.elementFromPoint(middleX, edge - 1).id", "'tr2-td1'");
+               shouldBe("document.elementFromPoint(middleX, edge).id", "'tr3-td1'");
+               shouldBe("document.elementFromPoint(middleX, edge + 1).id", "'tr3-td1'");
+               break;
+       case ('tr2-td4'):
+               shouldBe("document.elementFromPoint(middleX, edge - 1).id", "'tr2-td2'");
+               shouldBe("document.elementFromPoint(middleX, edge).id", "'tr3-td2'");
+               shouldBe("document.elementFromPoint(middleX, edge + 1).id", "'tr3-td2'");
+               break;
+   case ('tr3-td1'):
+   case ('tr3-td2'):
+   case ('tr3-td3'):       
+               shouldBe("document.elementFromPoint(middleX, edge - 1).id", "'tr3-td1'");
+               shouldBe("document.elementFromPoint(middleX, edge).id", "'tr4-td1'");
+               shouldBe("document.elementFromPoint(middleX, edge + 1).id", "'tr4-td1'");
+               break;
+       case ('tr3-td4'):
+               shouldBe("document.elementFromPoint(middleX, edge - 1).id", "'tr3-td2'");
+               shouldBe("document.elementFromPoint(middleX, edge).id", "'tr4-td2'");
+               shouldBe("document.elementFromPoint(middleX, edge + 1).id", "'tr4-td2'");
+               break;
+       case ('tr4-td1'):
+               shouldBe("document.elementFromPoint(middleX, edge - 1).id", "'tr4-td1'");
+               shouldBe("document.elementFromPoint(middleX, edge).id", "''");
+               shouldBe("document.elementFromPoint(middleX, edge + 1).id", "''");
+               break;
+       case ('tr4-td2'):
+               shouldBe("document.elementFromPoint(middleX, edge - 1).id", "'tr4-td2'");
+               shouldBe("document.elementFromPoint(middleX, edge).id", "''");
+               shouldBe("document.elementFromPoint(middleX, edge + 1).id", "''");
+               break;        
+       case ('tr4-td3'):
+               shouldBe("document.elementFromPoint(middleX, edge - 1).id", "''");
+               shouldBe("document.elementFromPoint(middleX, edge).id", "''");
+               shouldBe("document.elementFromPoint(middleX, edge + 1).id", "''");
+               break;
+       case ('tr4-td4'):
+               shouldBe("document.elementFromPoint(middleX, edge - 1).id", "'tr4-td4'");
+               shouldBe("document.elementFromPoint(middleX, edge).id", "''");
+               shouldBe("document.elementFromPoint(middleX, edge + 1).id", "''");
+               break;
+       default:
+               break;
+    }
+}
+</script>
+<style>
+    table
+    {
+        border-spacing: 0px;
+        font-size: 1000%;
+    }
+    td
+       { 
+        padding: 0px;
+        border: 1px solid black;
+    }
+</style>
+</head>
+<body onload="test()">
+    <p>Test for Bugzilla <a href="https://bugs.webkit.org/show_bug.cgi?id=74864">Bug 74864</a>: There is additional space not belonged to a table between the table cells.</p>
+    <table cellspacing=0>
+        <tr id="tr1">
+            <td id="tr1-td1">1</td>
+            <td id="tr1-td2">1</td>
+            <td id="tr1-td3"></td>
+            <td id="tr1-td4">1</td>
+        </tr>
+        <tr id="tr2">
+            <td id="tr2-td1">1</td>
+            <td id="tr2-td2">1</td>
+            <td id="tr2-td3"></td>
+            <td id="tr2-td4">1</td>
+        </tr>
+        <tr id="tr3">
+            <td id="tr3-td1"></td>
+            <td id="tr3-td2"></td>
+            <td id="tr3-td3"></td>
+            <td id="tr3-td4"></td>
+        </tr>  
+        <tr id="tr4">
+            <td id="tr4-td1">1</td>
+            <td id="tr4-td2">1</td>
+            <td id="tr4-td3"></td>            
+            <td id="tr4-td4">1</td>
+        </tr>              
+    </table>
+    <p id="description"></p>
+    <div id="console"></div>
+</body>
+</html>
diff --git a/LayoutTests/fast/table/hittest-tablecell-with-borders-right-edge-expected.txt b/LayoutTests/fast/table/hittest-tablecell-with-borders-right-edge-expected.txt
new file mode 100644 (file)
index 0000000..813ec58
--- /dev/null
@@ -0,0 +1,75 @@
+Test for Bugzilla Bug 74864: There is additional space not belonged to a table between the table cells.
+
+An event generated on the edge of a table cell is not being consumed by the appropriate underlying element. This test verifies that the hittest result on the right edge of a table cell (with borders) returns the proper underlying element.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Executing for element tr1-td1 on the right edge of the table cell:
+PASS document.elementFromPoint(edge - 1, middleY).id is 'tr1-td1'
+PASS document.elementFromPoint(edge, middleY).id is 'tr1-td2'
+PASS document.elementFromPoint(edge + 1, middleY).id is 'tr1-td2'
+Executing for element tr1-td2 on the right edge of the table cell:
+PASS document.elementFromPoint(edge - 1, middleY).id is 'tr1-td2'
+PASS document.elementFromPoint(edge, middleY).id is 'tr1-td3'
+PASS document.elementFromPoint(edge + 1, middleY).id is 'tr1-td3'
+Executing for element tr1-td3 on the right edge of the table cell:
+PASS document.elementFromPoint(edge - 1, middleY).id is 'tr1-td3'
+PASS document.elementFromPoint(edge, middleY).id is 'tr1-td4'
+PASS document.elementFromPoint(edge + 1, middleY).id is 'tr1-td4'
+Executing for element tr1-td4 on the right edge of the table cell:
+PASS document.elementFromPoint(edge - 1, middleY).id is 'tr1-td4'
+PASS document.elementFromPoint(edge, middleY).id is ''
+PASS document.elementFromPoint(edge + 1, middleY).id is ''
+Executing for element tr2-td1 on the right edge of the table cell:
+PASS document.elementFromPoint(edge - 1, middleY).id is 'tr2-td1'
+PASS document.elementFromPoint(edge, middleY).id is 'tr2-td2'
+PASS document.elementFromPoint(edge + 1, middleY).id is 'tr2-td2'
+Executing for element tr2-td2 on the right edge of the table cell:
+PASS document.elementFromPoint(edge - 1, middleY).id is 'tr2-td2'
+PASS document.elementFromPoint(edge, middleY).id is 'tr2-td3'
+PASS document.elementFromPoint(edge + 1, middleY).id is 'tr2-td3'
+Executing for element tr2-td3 on the right edge of the table cell:
+PASS document.elementFromPoint(edge - 1, middleY).id is 'tr2-td3'
+PASS document.elementFromPoint(edge, middleY).id is 'tr2-td4'
+PASS document.elementFromPoint(edge + 1, middleY).id is 'tr2-td4'
+Executing for element tr2-td4 on the right edge of the table cell:
+PASS document.elementFromPoint(edge - 1, middleY).id is 'tr2-td4'
+PASS document.elementFromPoint(edge, middleY).id is ''
+PASS document.elementFromPoint(edge + 1, middleY).id is ''
+Executing for element tr3-td1 on the right edge of the table cell:
+PASS document.elementFromPoint(edge - 1, middleY).id is ''
+PASS document.elementFromPoint(edge, middleY).id is ''
+PASS document.elementFromPoint(edge + 1, middleY).id is ''
+Executing for element tr3-td2 on the right edge of the table cell:
+PASS document.elementFromPoint(edge - 1, middleY).id is ''
+PASS document.elementFromPoint(edge, middleY).id is ''
+PASS document.elementFromPoint(edge + 1, middleY).id is ''
+Executing for element tr3-td3 on the right edge of the table cell:
+PASS document.elementFromPoint(edge - 1, middleY).id is ''
+PASS document.elementFromPoint(edge, middleY).id is ''
+PASS document.elementFromPoint(edge + 1, middleY).id is ''
+Executing for element tr3-td4 on the right edge of the table cell:
+PASS document.elementFromPoint(edge - 1, middleY).id is ''
+PASS document.elementFromPoint(edge, middleY).id is ''
+PASS document.elementFromPoint(edge + 1, middleY).id is ''
+Executing for element tr4-td1 on the right edge of the table cell:
+PASS document.elementFromPoint(edge - 1, middleY).id is 'tr4-td1'
+PASS document.elementFromPoint(edge, middleY).id is 'tr4-td2'
+PASS document.elementFromPoint(edge + 1, middleY).id is 'tr4-td2'
+Executing for element tr4-td2 on the right edge of the table cell:
+PASS document.elementFromPoint(edge - 1, middleY).id is 'tr4-td2'
+PASS document.elementFromPoint(edge, middleY).id is 'tr4-td3'
+PASS document.elementFromPoint(edge + 1, middleY).id is 'tr4-td3'
+Executing for element tr4-td3 on the right edge of the table cell:
+PASS document.elementFromPoint(edge - 1, middleY).id is 'tr4-td3'
+PASS document.elementFromPoint(edge, middleY).id is 'tr4-td4'
+PASS document.elementFromPoint(edge + 1, middleY).id is 'tr4-td4'
+Executing for element tr4-td4 on the right edge of the table cell:
+PASS document.elementFromPoint(edge - 1, middleY).id is 'tr4-td4'
+PASS document.elementFromPoint(edge, middleY).id is ''
+PASS document.elementFromPoint(edge + 1, middleY).id is ''
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/table/hittest-tablecell-with-borders-right-edge.html b/LayoutTests/fast/table/hittest-tablecell-with-borders-right-edge.html
new file mode 100644 (file)
index 0000000..4e6e387
--- /dev/null
@@ -0,0 +1,154 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../js/resources/js-test-pre.js"></script>
+<script>
+function test()
+{
+    description("An event generated on the edge of a table cell is not being consumed by the appropriate underlying element. This test verifies that the hittest result on the right edge of a table cell (with borders) returns the proper underlying element.");
+               
+    var ele = {};      
+    ['tr1-td1', 'tr1-td2', 'tr1-td3', 'tr1-td4',
+     'tr2-td1', 'tr2-td2', 'tr2-td3', 'tr2-td4',
+     'tr3-td1', 'tr3-td2', 'tr3-td3', 'tr3-td4',
+     'tr4-td1', 'tr4-td2', 'tr4-td3', 'tr4-td4'].forEach(function(a) {
+        ele[a] = document.getElementById(a);
+        hittest(ele[a], a); 
+        ele[a].innerHTML = '';
+    });
+
+    isSuccessfullyParsed();
+}
+function hittest(ele, orgElement, expected1, expected2)
+{      
+    edge = ele.getBoundingClientRect().right;
+    middleY = ele.getBoundingClientRect().bottom / 2;
+    debug('Executing for element '+orgElement+' on the right edge of the table cell:');
+    
+    switch (orgElement) {
+       case ('tr1-td1'):
+               shouldBe("document.elementFromPoint(edge - 1, middleY).id", "'tr1-td1'");
+               shouldBe("document.elementFromPoint(edge, middleY).id", "'tr1-td2'");
+               shouldBe("document.elementFromPoint(edge + 1, middleY).id", "'tr1-td2'");
+               break;
+       case ('tr1-td2'):
+               shouldBe("document.elementFromPoint(edge - 1, middleY).id", "'tr1-td2'");
+               shouldBe("document.elementFromPoint(edge, middleY).id", "'tr1-td3'");
+               shouldBe("document.elementFromPoint(edge + 1, middleY).id", "'tr1-td3'");
+               break;        
+       case ('tr1-td3'):
+               shouldBe("document.elementFromPoint(edge - 1, middleY).id", "'tr1-td3'");
+               shouldBe("document.elementFromPoint(edge, middleY).id", "'tr1-td4'");
+               shouldBe("document.elementFromPoint(edge + 1, middleY).id", "'tr1-td4'");
+               break;
+       case ('tr1-td4'):
+               shouldBe("document.elementFromPoint(edge - 1, middleY).id", "'tr1-td4'");
+               shouldBe("document.elementFromPoint(edge, middleY).id", "''");
+               shouldBe("document.elementFromPoint(edge + 1, middleY).id", "''");
+               break;
+       case ('tr2-td1'):
+               shouldBe("document.elementFromPoint(edge - 1, middleY).id", "'tr2-td1'");
+               shouldBe("document.elementFromPoint(edge, middleY).id", "'tr2-td2'");
+               shouldBe("document.elementFromPoint(edge + 1, middleY).id", "'tr2-td2'");
+               break;
+       case ('tr2-td2'):
+               shouldBe("document.elementFromPoint(edge - 1, middleY).id", "'tr2-td2'");
+               shouldBe("document.elementFromPoint(edge, middleY).id", "'tr2-td3'");
+               shouldBe("document.elementFromPoint(edge + 1, middleY).id", "'tr2-td3'");
+               break;        
+       case ('tr2-td3'):
+               shouldBe("document.elementFromPoint(edge - 1, middleY).id", "'tr2-td3'");
+               shouldBe("document.elementFromPoint(edge, middleY).id", "'tr2-td4'");
+               shouldBe("document.elementFromPoint(edge + 1, middleY).id", "'tr2-td4'");
+               break;
+       case ('tr2-td4'):
+               shouldBe("document.elementFromPoint(edge - 1, middleY).id", "'tr2-td4'");
+               shouldBe("document.elementFromPoint(edge, middleY).id", "''");
+               shouldBe("document.elementFromPoint(edge + 1, middleY).id", "''");
+               break;
+       case ('tr3-td1'):
+               shouldBe("document.elementFromPoint(edge - 1, middleY).id", "''");
+               shouldBe("document.elementFromPoint(edge, middleY).id", "''");
+               shouldBe("document.elementFromPoint(edge + 1, middleY).id", "''");
+               break;
+       case ('tr3-td2'):
+       case ('tr3-td3'):
+               shouldBe("document.elementFromPoint(edge - 1, middleY).id", "''");
+               shouldBe("document.elementFromPoint(edge, middleY).id", "''");
+               shouldBe("document.elementFromPoint(edge + 1, middleY).id", "''");
+               break;
+       case ('tr3-td4'):
+               shouldBe("document.elementFromPoint(edge - 1, middleY).id", "''");
+               shouldBe("document.elementFromPoint(edge, middleY).id", "''");
+               shouldBe("document.elementFromPoint(edge + 1, middleY).id", "''");
+               break;
+       case ('tr4-td1'):
+               shouldBe("document.elementFromPoint(edge - 1, middleY).id", "'tr4-td1'");
+               shouldBe("document.elementFromPoint(edge, middleY).id", "'tr4-td2'");
+               shouldBe("document.elementFromPoint(edge + 1, middleY).id", "'tr4-td2'");
+               break;
+       case ('tr4-td2'):
+               shouldBe("document.elementFromPoint(edge - 1, middleY).id", "'tr4-td2'");
+               shouldBe("document.elementFromPoint(edge, middleY).id", "'tr4-td3'");
+               shouldBe("document.elementFromPoint(edge + 1, middleY).id", "'tr4-td3'");
+               break;        
+       case ('tr4-td3'):
+               shouldBe("document.elementFromPoint(edge - 1, middleY).id", "'tr4-td3'");
+               shouldBe("document.elementFromPoint(edge, middleY).id", "'tr4-td4'");
+               shouldBe("document.elementFromPoint(edge + 1, middleY).id", "'tr4-td4'");
+               break;
+       case ('tr4-td4'):
+               shouldBe("document.elementFromPoint(edge - 1, middleY).id", "'tr4-td4'");
+               shouldBe("document.elementFromPoint(edge, middleY).id", "''");
+               shouldBe("document.elementFromPoint(edge + 1, middleY).id", "''");
+               break;
+       default:
+               break;
+    }
+}
+</script>
+<style>
+    table
+    {
+        border-spacing: 0px;
+        font-size: 1000%;
+    }
+    td
+       {
+        padding: 0px;
+        border: 1px solid black;
+    }
+</style>
+</head>
+<body onload="test()">
+    <p>Test for Bugzilla <a href="https://bugs.webkit.org/show_bug.cgi?id=74864">Bug 74864</a>: There is additional space not belonged to a table between the table cells.</p>
+    <table cellspacing=0>
+        <tr id="tr1">
+            <td id="tr1-td1">1</td>
+            <td id="tr1-td2">1</td>
+            <td id="tr1-td3"></td>
+            <td id="tr1-td4">1</td>
+        </tr>
+        <tr id="tr2">
+            <td id="tr2-td1">1</td>
+            <td id="tr2-td2">1</td>
+            <td id="tr2-td3"></td>
+            <td id="tr2-td4">1</td>
+        </tr>
+        <tr id="tr3">
+            <td id="tr3-td1"></td>
+            <td id="tr3-td2"></td>
+            <td id="tr3-td3"></td>
+            <td id="tr3-td4"></td>
+        </tr>  
+        <tr id="tr4">
+            <td id="tr4-td1">1</td>
+            <td id="tr4-td2">1</td>
+            <td id="tr4-td3"></td>            
+            <td id="tr4-td4">1</td>
+        </tr>              
+    </table>
+    <p id="description"></p>
+    <div id="console"></div>
+</body>
+</html>
index 65649c7..5e75756 100644 (file)
@@ -1,3 +1,32 @@
+2012-08-15  Arpita Bahuguna  <arpitabahuguna@gmail.com>
+
+        There is additional space not belonged to a table between the table cells
+        https://bugs.webkit.org/show_bug.cgi?id=74864
+
+        Reviewed by Julien Chaffraix.
+
+        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().
+
 2012-08-15  Anna Cavender  <annacc@chromium.org>
 
         Add the timestampOffset attribute to SourceBuffer.
index 80e6465..d34070c 100644 (file)
@@ -1092,8 +1092,6 @@ CellSpan RenderTableSection::dirtiedColumns(const LayoutRect& damageRect) const
 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 @@ CellSpan RenderTableSection::spannedColumns(const LayoutRect& flippedRect) const
 {
     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;
     }