Add test for MouseEvent.toElement & MouseEvent.fromElement
diff --git a/uievents/order-of-events/mouse-events/defacto-fromelement-toelement-manual.html b/uievents/order-of-events/mouse-events/defacto-fromelement-toelement-manual.html
new file mode 100644
index 0000000..1302190
--- /dev/null
+++ b/uievents/order-of-events/mouse-events/defacto-fromelement-toelement-manual.html
@@ -0,0 +1,159 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>MouseEvent.fromElement and MouseEvent.toElement</title>
+ <meta name="flags" content="interact dom">
+ <link rel="author" title="Chris Rebert" href="http://chrisrebert.com">
+ <!-- If these do get spec'd, they would presumably belong in: -->
+ <link rel="help" href="https://w3c.github.io/uievents/#events-mouseevents">
+ <!-- Documentation (since there's not yet a spec): -->
+ <link rel="help" href="https://msdn.microsoft.com/en-us/library/ms533773(v=vs.85).aspx">
+ <link rel="help" href="https://msdn.microsoft.com/en-us/library/ms534684(v=vs.85).aspx">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <style>
+#outer {
+ width: 200px;
+ height: 200px;
+ background-color: fuchsia;
+}
+#inner {
+ position: relative;
+ top: 50px;
+ left: 50px;
+ width: 100px;
+ height: 100px;
+ background-color: teal;
+}
+ </style>
+</head>
+<body>
+ <div id="outer">
+ <div id="inner"></div>
+ </div>
+ <button type="button" onclick="done()">Done</button>
+ <ol>
+ <li>If the User-Agent lacks a pointing mechanism or the pointing mechanism does not support hovering, then <strong>skip</strong> this test.</li>
+ <li>Move the pointer into the fuchsia area.</li>
+ <li>Move the pointer into the teal area.</li>
+ <li>Move the pointer into the fuchsia area.</li>
+ <li>Move the pointer outside of both the fuchsia area and the teal area, without moving the pointer through the teal area.</li>
+ <li>Click the "Done" button.</li>
+ <li>If a "PASS" result has appeared, then the test passes; otherwise, it fails.</li>
+ </ol>
+ <script>
+setup({explicit_timeout: true});
+
+function one(type, listener) {
+ var wrapper = function (e) {
+ try {
+ listener(e);
+ } catch (err) {
+ document.removeEventListener(type, wrapper);
+ throw err;
+ }
+ document.removeEventListener(type, wrapper);
+ };
+
+ document.addEventListener(type, wrapper);
+}
+
+function assertEnterOver(e, type) {
+ assert_equals(e.fromElement, e.relatedTarget, 'For '+ type + ', .fromElement should equal .relatedTarget');
+ assert_equals(e.toElement, e.target, 'For ' + type + ', .toElement should equal .target');
+}
+
+function assertLeaveOut(e, type) {
+ assert_equals(e.fromElement, e.target, 'For '+ type + ', .fromElement should equal .target');
+ assert_equals(e.toElement, e.relatedTarget, 'For ' + type + ', .toElement should equal .relatedTarget');
+}
+
+window.addEventListener('load', function () {
+ var outer = document.getElementById('outer');
+ var inner = document.getElementById('inner');
+
+ var one = function (type, listener) {
+ var wrapper = function (e) {
+ try {
+ listener(e);
+ } catch (err) {
+ outer.removeEventListener(type, wrapper);
+ throw err;
+ }
+ outer.removeEventListener(type, wrapper);
+ };
+
+ outer.addEventListener(type, wrapper);
+ };
+
+ // These do bubble
+ async_test(function (t) {
+ // Pointer moves onto #outer
+ one('mouseover', t.step_func(function (firstOver) {
+ assertEnterOver(firstOver, 'mouseover');
+ assert_equals(firstOver.target, outer, 'First mouseover should be targeted at #outer');
+ assert_equals(firstOver.relatedTarget, document.body, 'First mouseover should have <body> as .relatedTarget');
+
+ // Pointer moves onto #inner
+ one('mouseout', t.step_func(function (firstOut) {
+ assertLeaveOut(firstOut, 'mouseout');
+ assert_equals(firstOut.target, outer, 'First mouseout should be targeted at #outer');
+ assert_equals(firstOut.relatedTarget, inner, 'First mouseout should have #inner as .relatedTarget');
+
+ one('mouseover', t.step_func(function (secondOver) {
+ assertEnterOver(secondOver, 'mouseover');
+ assert_equals(secondOver.target, inner, 'Second mouseover should be targeted at #inner');
+ assert_equals(secondOver.relatedTarget, outer, 'Second mouseover should have #outer as .relatedTarget');
+
+ // Pointer moves back onto #outer
+ one('mouseout', t.step_func(function (secondOut) {
+ assertLeaveOut(secondOut, 'mouseout');
+ assert_equals(secondOut.target, inner, 'Second mouseout should be targeted at #inner');
+ assert_equals(secondOut.relatedTarget, outer, 'Second mouseout should have #outer as .relatedTarget');
+
+ one('mouseover', t.step_func(function (thirdOver) {
+ assertEnterOver(thirdOver, 'mouseover');
+ assert_equals(thirdOver.target, outer, 'Third mouseover should be targeted at #outer');
+ assert_equals(thirdOver.relatedTarget, inner, 'Third mouseover should have #inner as .relatedTarget');
+
+ // Pointer moves off of #outer
+ one('mouseout', t.step_func(function (thirdOut) {
+ assertLeaveOut(thirdOut, 'mouseout');
+ assert_equals(thirdOut.target, outer, 'Third mouseout should be targeted at #outer');
+ assert_equals(thirdOut.relatedTarget, document.body, 'Third mouseout should have <body> as .relatedTarget');
+
+ t.done();
+ }));
+ }));
+ }));
+ }));
+ }));
+ }));
+ }, 'mouseover and mouseout');
+
+ // These don't bubble
+ async_test(function (t) {
+ outer.addEventListener('mouseenter', t.step_func_done(function (e) {
+ assertEnterOver(e, 'mouseenter');
+ }));
+ }, 'mouseenter #outer');
+ async_test(function (t) {
+ outer.addEventListener('mouseleave', t.step_func_done(function (e) {
+ assertLeaveOut(e, 'mouseleave');
+ }));
+ }, 'mouseleave #outer');
+ async_test(function (t) {
+ inner.addEventListener('mouseenter', t.step_func_done(function (e) {
+ assertEnterOver(e, 'mouseenter');
+ }));
+ }, 'mouseenter #inner');
+ async_test(function (t) {
+ inner.addEventListener('mouseleave', t.step_func_done(function (e) {
+ assertLeaveOut(e, 'mouseleave');
+ }));
+ }, 'mouseleave #inner');
+});
+ </script>
+</body>
+</html>