Commit e1cf9db2 authored by myid.o.shin@gmail.com's avatar myid.o.shin@gmail.com

We need to account for culled inline parents of the hit-tested nodes.

The problem is that the mouse events aren't fired when there is the element culled inline
like label element that doesn't has any background color or border or self-layer.
We already handle area-based hit-tests for culled inline.
This patch makes hit-test include not only area-based hit-tests but also point-based ones at the place handling culled inline.

BUG=312199
R=rbyers@chromium.org, pdr@chromium.org, leviw@chromium.org
TEST=LayoutTests/fast/events/hit-test-culled_inline.html

Review URL: https://codereview.chromium.org/685963002

git-svn-id: svn://svn.chromium.org/blink/trunk@185417 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent b279cb32
Click the empty area on the left
Click the empty areain middle
Click event should be fired when it occurs within culled inline.
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
PASS document.elementFromPoint(x, y).id is "clickme1"
LABEL that is a parent of INPUT is clicked.
LABEL that is a parent of INPUT is clicked.
PASS gotClick is true
PASS document.elementFromPoint(x, y).id is "clickme2"
SPAN that is a parent of EM is clicked.
PASS gotClick is true
PASS document.getElementById("checkbox").checked is true
PASS successfullyParsed is true
TEST COMPLETE
<!DOCTYPE html>
<style type="text/css">
input, em { cursor: pointer; margin-right: 100px; }
label, span { cursor: pointer; background: transparent; }
</style>
<script src="../../resources/js-test.js"></script>
<div><label id="clickme1" for="checkbox"><input id="checkbox" type="checkbox">Click the empty area on the left</input></label></div>
<div><span id="clickme2"><em id="em">Click the empty area</em><em>in middle</em></span></div>
<p id="description"></p>
<div id="console"></div>
<script>
description('Click event should be fired when it occurs within culled inline.');
var parent;
var gotClick;
function hitTest(id) {
var element = document.getElementById(id);
parent = element.parentElement;
// the x, y coordinates on margin of element
x = element.offsetLeft + element.offsetWidth + 10;
y = element.offsetTop + element.offsetHeight / 2;
shouldBeEqualToString('document.elementFromPoint(x, y).id', parent.id);
if (window.eventSender) {
gotClick = false;
parent.addEventListener('click', function(e) {
debug(parent.nodeName + ' that is a parent of ' + element.nodeName + ' is clicked.');
gotClick = true;
});
eventSender.mouseMoveTo(x, y);
eventSender.mouseDown();
eventSender.mouseUp();
shouldBeTrue('gotClick');
}
debug('');
}
hitTest('checkbox');
hitTest('em');
if (window.eventSender)
shouldBeTrue('document.getElementById("checkbox").checked');
</script>
...@@ -1029,17 +1029,14 @@ bool InlineFlowBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& re ...@@ -1029,17 +1029,14 @@ bool InlineFlowBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& re
return false; return false;
// Check children first. // Check children first.
// We need to account for culled inline parents of the hit-tested nodes, so that they may also get included in area-based hit-tests. // We need to account for culled inline parents of the hit-tested nodes, so that they may also get included in not only area-based hit-tests but also point-based ones.
RenderObject* culledParent = 0; RenderObject* culledParent = 0;
for (InlineBox* curr = lastChild(); curr; curr = curr->prevOnLine()) { for (InlineBox* curr = lastChild(); curr; curr = curr->prevOnLine()) {
if (curr->renderer().isText() || !curr->boxModelObject()->hasSelfPaintingLayer()) { if (curr->renderer().isText() || !curr->boxModelObject()->hasSelfPaintingLayer()) {
RenderObject* newParent = 0; RenderObject* newParent = 0;
// Culled parents are only relevant for area-based hit-tests, so ignore it in point-based ones. newParent = curr->renderer().parent();
if (locationInContainer.isRectBasedTest()) { if (newParent == renderer())
newParent = curr->renderer().parent(); newParent = 0;
if (newParent == renderer())
newParent = 0;
}
// Check the culled parent after all its children have been checked, to do this we wait until // Check the culled parent after all its children have been checked, to do this we wait until
// we are about to test an element with a different parent. // we are about to test an element with a different parent.
if (newParent != culledParent) { if (newParent != culledParent) {
......
...@@ -802,7 +802,7 @@ private: ...@@ -802,7 +802,7 @@ private:
bool RenderInline::hitTestCulledInline(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset) bool RenderInline::hitTestCulledInline(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset)
{ {
ASSERT(result.isRectBasedTest() && !alwaysCreateLineBoxes()); ASSERT(!alwaysCreateLineBoxes());
if (!visibleToHitTestRequest(request)) if (!visibleToHitTestRequest(request))
return false; return false;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment