Source code
Revision control
Copy as Markdown
Other Tools
Test Info:
- Manifest: dom/events/test/mochitest.toml
<!DOCTYPE HTML>
<html>
<!--
-->
<head>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=687787">Mozilla Bug 687787</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
var eventStack = [];
function _callback(e){
var event = {'type' : e.type, 'target' : e.target, 'relatedTarget' : e.relatedTarget }
eventStack.push(event);
}
function clearEventStack(){
eventStack = [];
}
window.addEventListener("focus", _callback, true);
window.addEventListener("focusin", _callback, true);
window.addEventListener("focusout", _callback, true);
window.addEventListener("blur", _callback, true);
function CompareEventToExpected(e, expected) {
if (expected == null || e == null)
return false;
if (e.type == expected.type && e.target == expected.target && e.relatedTarget == expected.relatedTarget)
return true;
return false;
}
function TestEventOrderNormal() {
var input1 = document.createElement('input');
var input2 = document.createElement('input');
var input3 = document.createElement('input');
var content = document.getElementById('content');
input1.setAttribute('id', 'input1');
input2.setAttribute('id', 'input2');
input3.setAttribute('id', 'input3');
input1.setAttribute('type', 'text');
input2.setAttribute('type', 'text');
input3.setAttribute('type', 'text');
input1.setAttribute('inputmode', 'none');
input2.setAttribute('inputmode', 'none');
input3.setAttribute('inputmode', 'none');
content.appendChild(input1);
content.appendChild(input2);
content.appendChild(input3);
content.style.display = 'block'
let expectedEventOrder = [
{'type' : 'blur',
'target' : input1,
'relatedTarget' : input2},
{'type' : 'focusout',
'target' : input1,
'relatedTarget' : input2},
{'type' : 'focus',
'target' : input2,
'relatedTarget' : input1},
{'type' : 'focusin',
'target' : input2,
'relatedTarget' : input1},
{'type' : 'blur',
'target' : input2,
'relatedTarget' : input3},
{'type' : 'focusout',
'target' : input2,
'relatedTarget' : input3},
{'type' : 'focus',
'target' : input3,
'relatedTarget' : input2},
{'type' : 'focusin',
'target' : input3,
'relatedTarget' : input2},
]
input1.focus();
clearEventStack();
input2.focus();
input3.focus();
for (var i = 0; i < expectedEventOrder.length || i < eventStack.length ; i++) {
ok(CompareEventToExpected(expectedEventOrder[i], eventStack[i]), 'Normal event order is correct: Event ' + i + ': '
+ 'Expected ('
+ expectedEventOrder[i].type + ','
+ (expectedEventOrder[i].target ? expectedEventOrder[i].target.id : null) + ','
+ (expectedEventOrder[i].relatedTarget ? expectedEventOrder[i].relatedTarget.id : null) + '), '
+ 'Actual ('
+ eventStack[i].type + ','
+ (eventStack[i].target ? eventStack[i].target.id : null) + ','
+ (eventStack[i].relatedTarget ? eventStack[i].relatedTarget.id : null) + ')');
}
content.innerHTML = '';
}
function TestEventOrderNormalFiresAtRightTime() {
var input1 = document.createElement('input');
var input2 = document.createElement('input');
var input3 = document.createElement('input');
var content = document.getElementById('content');
input1.setAttribute('id', 'input1');
input2.setAttribute('id', 'input2');
input3.setAttribute('id', 'input3');
input1.setAttribute('type', 'text');
input2.setAttribute('type', 'text');
input3.setAttribute('type', 'text');
input1.onblur = function(e)
{
ok(document.activeElement == document.body, 'input1: not focused when blur fires')
}
input1.addEventListener('focusout', function(e)
{
ok(document.activeElement == document.body, 'input1: not focused when focusout fires')
});
input2.onfocus = function(e)
{
ok(document.activeElement == input2, 'input2: focused when focus fires')
}
input2.addEventListener('focusin', function(e)
{
ok(document.activeElement == input2, 'input2: focused when focusin fires')
});
content.appendChild(input1);
content.appendChild(input2);
content.style.display = 'block'
let expectedEventOrder = [
{'type' : 'blur',
'target' : input1,
'relatedTarget' : input2},
{'type' : 'focusout',
'target' : input1,
'relatedTarget' : input2},
{'type' : 'focus',
'target' : input2,
'relatedTarget' : input1},
{'type' : 'focusin',
'target' : input2,
'relatedTarget' : input1},
]
input1.focus();
clearEventStack();
input2.focus();
for (var i = 0; i < expectedEventOrder.length || i < eventStack.length ; i++) {
ok(CompareEventToExpected(expectedEventOrder[i], eventStack[i]), 'Normal event order is correct: Event ' + i + ': '
+ 'Expected ('
+ expectedEventOrder[i].type + ','
+ (expectedEventOrder[i].target ? expectedEventOrder[i].target.id : null) + ','
+ (expectedEventOrder[i].relatedTarget ? expectedEventOrder[i].relatedTarget.id : null) + '), '
+ 'Actual ('
+ eventStack[i].type + ','
+ (eventStack[i].target ? eventStack[i].target.id : null) + ','
+ (eventStack[i].relatedTarget ? eventStack[i].relatedTarget.id : null) + ')');
}
content.innerHTML = '';
}
function TestFocusOutRedirectsFocus() {
var input1 = document.createElement('input');
var input2 = document.createElement('input');
var input3 = document.createElement('input');
var content = document.getElementById('content');
input1.setAttribute('id', 'input1');
input2.setAttribute('id', 'input2');
input3.setAttribute('id', 'input3');
input1.setAttribute('type', 'text');
input2.setAttribute('type', 'text');
input3.setAttribute('type', 'text');
input1.addEventListener('focusout', function () {
input3.focus();
});
content.appendChild(input1);
content.appendChild(input2);
content.appendChild(input3);
content.style.display = 'block'
let expectedEventOrder = [
{'type' : 'blur',
'target' : input1,
'relatedTarget' : input2},
{'type' : 'focusout',
'target' : input1,
'relatedTarget' : input2},
{'type' : 'focus',
'target' : input3,
'relatedTarget' : null},
{'type' : 'focusin',
'target' : input3,
'relatedTarget' : null},
]
input1.focus();
clearEventStack();
input2.focus();
for (var i = 0; i < expectedEventOrder.length || i < eventStack.length; i++) {
ok(CompareEventToExpected(expectedEventOrder[i], eventStack[i]), 'Normal event order is correct: Event ' + i + ': '
+ 'Expected ('
+ expectedEventOrder[i].type + ','
+ (expectedEventOrder[i].target ? expectedEventOrder[i].target.id : null) + ','
+ (expectedEventOrder[i].relatedTarget ? expectedEventOrder[i].relatedTarget.id : null) + '), '
+ 'Actual ('
+ eventStack[i].type + ','
+ (eventStack[i].target ? eventStack[i].target.id : null) + ','
+ (eventStack[i].relatedTarget ? eventStack[i].relatedTarget.id : null) + ')');
}
content.innerHTML = '';
}
function TestFocusInRedirectsFocus() {
var input1 = document.createElement('input');
var input2 = document.createElement('input');
var input3 = document.createElement('input');
var content = document.getElementById('content');
input1.setAttribute('id', 'input1');
input2.setAttribute('id', 'input2');
input3.setAttribute('id', 'input3');
input1.setAttribute('type', 'text');
input2.setAttribute('type', 'text');
input3.setAttribute('type', 'text');
input2.addEventListener('focusin', function () {
input3.focus();
});
content.appendChild(input1);
content.appendChild(input2);
content.appendChild(input3);
content.style.display = 'block'
let expectedEventOrder = [
{'type' : 'blur',
'target' : input1,
'relatedTarget' : input2},
{'type' : 'focusout',
'target' : input1,
'relatedTarget' : input2},
{'type' : 'focus',
'target' : input2,
'relatedTarget' : input1},
{'type' : 'focusin',
'target' : input2,
'relatedTarget' : input1},
{'type' : 'blur',
'target' : input2,
'relatedTarget' : input3},
{'type' : 'focusout',
'target' : input2,
'relatedTarget' : input3},
{'type' : 'focus',
'target' : input3,
'relatedTarget' : input2},
{'type' : 'focusin',
'target' : input3,
'relatedTarget' : input2},
]
input1.focus();
clearEventStack();
input2.focus();
for (var i = 0; i < expectedEventOrder.length || i < eventStack.length; i++) {
ok(CompareEventToExpected(expectedEventOrder[i], eventStack[i]), 'Normal event order is correct: Event ' + i + ': '
+ 'Expected ('
+ expectedEventOrder[i].type + ','
+ (expectedEventOrder[i].target ? expectedEventOrder[i].target.id : null) + ','
+ (expectedEventOrder[i].relatedTarget ? expectedEventOrder[i].relatedTarget.id : null) + '), '
+ 'Actual ('
+ eventStack[i].type + ','
+ (eventStack[i].target ? eventStack[i].target.id : null) + ','
+ (eventStack[i].relatedTarget ? eventStack[i].relatedTarget.id : null) + ')');
}
content.innerHTML = '';
}
function TestBlurRedirectsFocus() {
var input1 = document.createElement('input');
var input2 = document.createElement('input');
var input3 = document.createElement('input');
var content = document.getElementById('content');
input1.setAttribute('id', 'input1');
input2.setAttribute('id', 'input2');
input3.setAttribute('id', 'input3');
input1.setAttribute('type', 'text');
input2.setAttribute('type', 'text');
input3.setAttribute('type', 'text');
input1.onblur = function () {
input3.focus();
}
content.appendChild(input1);
content.appendChild(input2);
content.appendChild(input3);
content.style.display = 'block'
let expectedEventOrder = [
{'type' : 'blur',
'target' : input1,
'relatedTarget' : input2},
{'type' : 'focus',
'target' : input3,
'relatedTarget' : null},
{'type' : 'focusin',
'target' : input3,
'relatedTarget' : null},
{'type' : 'focusout',
'target' : input1,
'relatedTarget' : input2},
]
input1.focus();
clearEventStack();
input2.focus();
for (var i = 0; i < expectedEventOrder.length || i < eventStack.length; i++) {
ok(CompareEventToExpected(expectedEventOrder[i], eventStack[i]), 'Normal event order is correct: Event ' + i + ': '
+ 'Expected ('
+ expectedEventOrder[i].type + ','
+ (expectedEventOrder[i].target ? expectedEventOrder[i].target.id : null) + ','
+ (expectedEventOrder[i].relatedTarget ? expectedEventOrder[i].relatedTarget.id : null) + '), '
+ 'Actual ('
+ eventStack[i].type + ','
+ (eventStack[i].target ? eventStack[i].target.id : null) + ','
+ (eventStack[i].relatedTarget ? eventStack[i].relatedTarget.id : null) + ')');
}
content.innerHTML = '';
}
function TestFocusRedirectsFocus() {
var input1 = document.createElement('input');
var input2 = document.createElement('input');
var input3 = document.createElement('input');
var content = document.getElementById('content');
input1.setAttribute('id', 'input1');
input2.setAttribute('id', 'input2');
input3.setAttribute('id', 'input3');
input1.setAttribute('type', 'text');
input2.setAttribute('type', 'text');
input3.setAttribute('type', 'text');
input2.onfocus = function () {
input3.focus();
}
content.appendChild(input1);
content.appendChild(input2);
content.appendChild(input3);
content.style.display = 'block'
let expectedEventOrder = [
{'type' : 'blur',
'target' : input1,
'relatedTarget' : input2},
{'type' : 'focusout',
'target' : input1,
'relatedTarget' : input2},
{'type' : 'focus',
'target' : input2,
'relatedTarget' : input1},
{'type' : 'blur',
'target' : input2,
'relatedTarget' : input3},
{'type' : 'focusout',
'target' : input2,
'relatedTarget' : input3},
{'type' : 'focus',
'target' : input3,
'relatedTarget' : input2},
{'type' : 'focusin',
'target' : input3,
'relatedTarget' : input2},
]
input1.focus();
clearEventStack();
input2.focus();
for (var i = 0; i < expectedEventOrder.length || i < eventStack.length; i++) {
ok(CompareEventToExpected(expectedEventOrder[i], eventStack[i]), 'Normal event order is correct: Event ' + i + ': '
+ 'Expected ('
+ expectedEventOrder[i].type + ','
+ (expectedEventOrder[i].target ? expectedEventOrder[i].target.id : null) + ','
+ (expectedEventOrder[i].relatedTarget ? expectedEventOrder[i].relatedTarget.id : null) + '), '
+ 'Actual ('
+ eventStack[i].type + ','
+ (eventStack[i].target ? eventStack[i].target.id : null) + ','
+ (eventStack[i].relatedTarget ? eventStack[i].relatedTarget.id : null) + ')');
}
content.innerHTML = '';
}
function TestEventOrderDifferentDocument() {
var input1 = document.createElement('input');
var input2 = document.createElement('input');
var iframe1 = document.createElement('iframe');
var content = document.getElementById('content');
input1.setAttribute('id', 'input1');
input2.setAttribute('id', 'input2');
iframe1.setAttribute('id', 'iframe1');
input1.setAttribute('type', 'text');
input2.setAttribute('type', 'text');
content.appendChild(input1);
content.appendChild(iframe1);
iframe1.contentDocument.body.appendChild(input2);
content.style.display = 'block'
iframe1.contentDocument.addEventListener("focus", _callback, true);
iframe1.contentDocument.addEventListener("focusin", _callback, true);
iframe1.contentDocument.addEventListener("focusout", _callback, true);
iframe1.contentDocument.addEventListener("blur", _callback, true);
let expectedEventOrder = [
{'type' : 'blur',
'target' : input1,
'relatedTarget' : null},
{'type' : 'focusout',
'target' : input1,
'relatedTarget' : null},
{'type' : 'blur',
'target' : document,
'relatedTarget' : null},
{'type' : 'blur',
'target' : window,
'relatedTarget' : null},
{'type' : 'focus',
'target' : iframe1.contentDocument,
'relatedTarget' : null},
{'type' : 'focus',
'target' : input2,
'relatedTarget' : null},
{'type' : 'focusin',
'target' : input2,
'relatedTarget' : null},
]
input1.focus();
clearEventStack();
input2.focus();
for (var i = 0; i < expectedEventOrder.length || i < eventStack.length; i++) {
ok(CompareEventToExpected(expectedEventOrder[i], eventStack[i]), 'Normal event order is correct: Event ' + i + ': '
+ 'Expected ('
+ expectedEventOrder[i].type + ','
+ (expectedEventOrder[i].target ? expectedEventOrder[i].target.id : null) + ','
+ (expectedEventOrder[i].relatedTarget ? expectedEventOrder[i].relatedTarget.id : null) + '), '
+ 'Actual ('
+ eventStack[i].type + ','
+ (eventStack[i].target ? eventStack[i].target.id : null) + ','
+ (eventStack[i].relatedTarget ? eventStack[i].relatedTarget.id : null) + ')');
}
content.innerHTML = '';
}
function TestFocusOutMovesTarget() {
var input1 = document.createElement('input');
var input2 = document.createElement('input');
var iframe1 = document.createElement('iframe');
var content = document.getElementById('content');
input1.setAttribute('id', 'input1');
input2.setAttribute('id', 'input2');
iframe1.setAttribute('id', 'iframe1');
input1.setAttribute('type', 'text');
input2.setAttribute('type', 'text');
input1.addEventListener('focusout', function () {
iframe1.contentDocument.body.appendChild(input2);
});
content.appendChild(input1);
content.appendChild(input2);
content.appendChild(iframe1);
content.style.display = 'block'
iframe1.contentDocument.addEventListener("focus", _callback, true);
iframe1.contentDocument.addEventListener("focusin", _callback, true);
iframe1.contentDocument.addEventListener("focusout", _callback, true);
iframe1.contentDocument.addEventListener("blur", _callback, true);
let expectedEventOrder = [
{'type' : 'blur',
'target' : input1,
'relatedTarget' : input2},
{'type' : 'focusout',
'target' : input1,
'relatedTarget' : input2},
]
input1.focus();
clearEventStack();
input2.focus();
for (var i = 0; i < expectedEventOrder.length || i < eventStack.length; i++) {
ok(CompareEventToExpected(expectedEventOrder[i], eventStack[i]), 'Normal event order is correct: Event ' + i + ': '
+ 'Expected ('
+ expectedEventOrder[i].type + ','
+ (expectedEventOrder[i].target ? expectedEventOrder[i].target.id : null) + ','
+ (expectedEventOrder[i].relatedTarget ? expectedEventOrder[i].relatedTarget.id : null) + '), '
+ 'Actual ('
+ eventStack[i].type + ','
+ (eventStack[i].target ? eventStack[i].target.id : null) + ','
+ (eventStack[i].relatedTarget ? eventStack[i].relatedTarget.id : null) + ')');
}
content.innerHTML = '';
}
function TestBlurWindowAndRefocusInputOnlyFiresFocusInOnInput() {
var input1 = document.createElement('input');
var content = document.getElementById('content');
input1.setAttribute('id', 'input1');
input1.setAttribute('type', 'text');
content.appendChild(input1);
let expectedEventOrder = [
{'type' : 'focus',
'target' : document,
'relatedTarget' : null},
{'type' : 'focus',
'target' : window,
'relatedTarget' : null},
{'type' : 'focus',
'target' : input1,
'relatedTarget' : null},
{'type' : 'focusin',
'target' : input1,
'relatedTarget' : null},
]
window.blur();
clearEventStack();
input1.focus();
for (var i = 0; i < expectedEventOrder.length || i < eventStack.length; i++) {
ok(CompareEventToExpected(expectedEventOrder[i], eventStack[i]), 'Normal event order is correct: Event ' + i + ': '
+ 'Expected ('
+ expectedEventOrder[i].type + ','
+ (expectedEventOrder[i].target ? expectedEventOrder[i].target.id : null) + ','
+ (expectedEventOrder[i].relatedTarget ? expectedEventOrder[i].relatedTarget.id : null) + '), '
+ 'Actual ('
+ eventStack[i].type + ','
+ (eventStack[i].target ? eventStack[i].target.id : null) + ','
+ (eventStack[i].relatedTarget ? eventStack[i].relatedTarget.id : null) + ')');
}
content.innerHTML = '';
}
TestEventOrderNormal();
TestEventOrderNormalFiresAtRightTime();
TestFocusOutRedirectsFocus();
TestFocusInRedirectsFocus();
TestBlurRedirectsFocus();
TestFocusRedirectsFocus();
TestFocusOutMovesTarget();
TestEventOrderDifferentDocument();
TestBlurWindowAndRefocusInputOnlyFiresFocusInOnInput();
</script>
</pre>
</body>
</html>