Auto merge of #9715 - ecoal95:mousemove, r=mbrubeck

script: Fix MouseOver handling

Now we only query for the topmost node, and apply the hover state to all
of the parent elements.

This fixes things like #9705, where the hover state was applied only to
the children.

This also makes us more conformant with other browsers in the case of
taking in account margins and paddings.

For example, prior to this PR, when your mouse was over the inner
element, in the bottom part, `hover` styles didn't apply to the parent.

```html
<style>
div {
  padding: 10px;
  margin: 10px;
  height: 15px;
  background: blue;
}

div:hover {
  background: red;
}
</style>

<div>
  <div></div>
</div>
```

Fixes #9705

<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.svg" height="40" alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/9715)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2016-03-03 22:55:35 +05:30
commit 056a7cf1a2
7 changed files with 271 additions and 141 deletions

View file

@ -34513,6 +34513,14 @@
"local_changes": {
"deleted": [],
"items": {
"manual": {
"uievents/order-of-events/mouse-events/mouseover-out-manual.html": [
{
"path": "uievents/order-of-events/mouse-events/mouseover-out-manual.html",
"url": "/uievents/order-of-events/mouse-events/mouseover-out-manual.html"
}
]
},
"testharness": {
"dom/lists/DOMTokenList-value.html": [
{

View file

@ -0,0 +1,125 @@
<!doctype html>
<meta charset="utf-8">
<title>Mouseover/mouseout handling</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<style>
#outer,
#inner,
#released {
padding: 10px;
margin: 10px;
height: 15px;
}
#outer:hover,
#inner:hover,
#released:hover {
background: red;
}
#outer {
background: blue;
}
#inner {
background: green;
}
#released {
background: yellow;
}
</style>
<p>
Steps:
<ol>
<li>Move your mouse over the blue <code>&lt;div&gt;</code> element, later
over the green one, later over the yellow one.
<li>Move the mouse from the yellow element to the green one, later to the
blue one, and later over this paragraph.
</ol>
</p>
<div id="outer">
<div id="inner"></div>
</div>
<div id="released"></div>
<div id="log"></div>
<script>
var t = async_test("Mouseover/out events");
var outer = document.getElementById("outer");
var inner = document.getElementById("inner");
var inner_over = 0;
var inner_out = 0;
var outer_own_over = 0;
var outer_own_out = 0;
var outer_over = 0;
var outer_out = 0;
inner.addEventListener("mouseover", t.step_func(function(e) {
assert_true(inner_over == inner_out, "mouseover is received before mouseout");
switch (inner_over) {
case 0:
assert_true(outer_own_over == 1, "should have triggered a mouseover in the outer before");
break;
case 1:
assert_true(outer_own_over == 1, "should have not triggered a mouseover in the outer before");
break;
default:
assert_true(false, "should not get more than two mouseovers");
}
inner_over++;
}), false);
inner.addEventListener("mouseout", t.step_func(function(e) {
assert_true(inner_over == inner_out + 1, "mouseout is received after mouseover");
switch (inner_out) {
case 0:
assert_true(outer_own_out == 1, "mouseout should have been received in the parent when hovering over this element");
break;
case 1:
break;
default:
assert_true(false, "should not get more than two mouseouts");
}
inner_out++;
}), false);
outer.addEventListener("mouseover", t.step_func(function(e) {
if (e.target == outer) {
assert_true(outer_own_over == outer_own_out, "outer: mouseover is received before mouseout");
outer_own_over++;
} else {
assert_true(outer_over - outer_own_over == inner_over - 1, "mouseover: should only receive this via bubbling");
}
outer_over++;
}), false);
outer.addEventListener('mouseout', t.step_func(function(e) {
if (e.target == outer) {
assert_true(outer_own_over == outer_own_out + 1, "outer: mouseout is received after mouseover");
if (outer_own_out == 1) {
assert_true(inner_out == 2, "inner should be done now");
t.done();
}
outer_own_out++;
} else {
assert_true(outer_out - outer_own_out == inner_out - 1, "mouseout: should only receive this via bubbling");
}
outer_out++;
}), false);
</script>