1 if (window
.testRunner
) {
2 testRunner
.waitUntilDone();
3 testRunner
.dumpAsText();
6 var consoleOutput
= null;
10 var focusedElem
= null;
11 var failedTestCount
= 0;
13 var tagNamesAlwaysFocused
= ["A",
23 var tagNamesTransferFocused
= ["LABEL"]; // labels always transfer focus to the labeled element
25 var noDisplayTagNamesWithFocus
= ["AREA"]; // AREA elements can get focus, but are not displayed.
27 function printToConsole(str
)
30 consoleOutput
= window
.frames
[2].document
.getElementById("theConsole");
32 consoleOutput
.appendChild(window
.frames
[2].document
.createTextNode(str
));
33 consoleOutput
.appendChild(window
.frames
[2].document
.createElement("br"));
36 function doFocus(elem
)
49 for (var i
= 0; i
< 2; ++i
)
50 focusEachChild(window
.frames
[i
].document
.body
);
52 // focus an untested element so that blur can be dispatched on the last iframe tested
53 var homeBase
= window
.frames
[1].document
.getElementsByClassName('homebase');
56 var resultSummary
= focusCount
+" focus / "+blurCount
+" blur events dispatched, and should be 333 / 333 ";
57 resultSummary
+= (focusCount
==blurCount
) ? "<span style='color:green'>PASSED</span><br>" : "<span style='color:red'>FAILED</span><br>";
58 resultSummary
+= "Total of "+failedTestCount
+" focus test(s) failed.";
60 resultSummary
+= "<br>Details:<br>"+consoleOutput
.innerHTML
;
62 resultSummary
+= " <span style='color:green'>PASSED</span>";
64 document
.write(resultSummary
);
67 if (window
.testRunner
)
68 testRunner
.notifyDone();
71 function focusEachChild(elem
) {
72 var childNodes
= elem
.childNodes
;
73 for (var i
= 0; i
< childNodes
.length
; i
++) {
74 if (childNodes
[i
].nodeType
== Node
.ELEMENT_NODE
&& childNodes
[i
].id
) {
75 childNodes
[i
].addEventListener('focus',function () { doFocus(this) }, false);
76 childNodes
[i
].addEventListener('blur',function () { doBlur(this) }, false);
77 testProgrammaticFocus(childNodes
[i
]);
79 if (childNodes
[i
].childNodes
.length
)
80 focusEachChild(childNodes
[i
]);
81 if (childNodes
[i
].tagName
=="IFRAME") {
82 if (childNodes
[i
].id
== "iframe1b") {
83 window
.frames
[0].document
.body
.focus();
85 focusEachChild(childNodes
[i
].contentDocument
.body
);
90 Array
.prototype.find = function(element
) {
91 for (var i
= 0; i
< this.length
; i
++) {
92 if(this[i
] == element
) {
99 function testProgrammaticFocus(elem
)
101 var elemThatShouldFocus
= null;
102 var OKtoFocusOtherElement
= false;
105 if (elem
.tabIndex
== elem
.getAttribute("tabindex")) // this means tabindex was explicitly set
106 elemThatShouldFocus
= elem
;
107 else if (tagNamesAlwaysFocused
.find(elem
.tagName
)) // special case form elements and other controls that are always focusable
108 elemThatShouldFocus
= elem
;
110 // Hidden elements should not be focusable. https://bugs.webkit.org/show_bug.cgi?id=27099
111 if (document
.defaultView
.getComputedStyle(elem
).display
== "none" && !noDisplayTagNamesWithFocus
.find(elem
.tagName
))
112 elemThatShouldFocus
= null;
114 // AREA elements with tabindex = -1 should not be focusable.
115 if (elem
.tabIndex
== -1 && elem
.tagName
== "AREA")
116 elemThatShouldFocus
= null;
118 if (tagNamesTransferFocused
.find(elem
.tagName
)) {
119 elemThatShouldFocus
= null;
120 OKtoFocusOtherElement
= true;
124 if (elemThatShouldFocus
== focusedElem
|| (!elemThatShouldFocus
&& OKtoFocusOtherElement
))
125 printToConsole("<"+elem
.tagName
+"> "+elem
.id
+" PASSED focus test");
128 printToConsole(elem
.id
+" FAILED - was " + (focusedElem
? "" : " not ") + " focused but focus " + (elemThatShouldFocus
? " was " : " wasn\'t") + " expected");
129 if (elemThatShouldFocus
&& focusedElem
)
130 printToConsole("elemThatShouldFocus is <"+elemThatShouldFocus
.tagName
+"> "+elemThatShouldFocus
.id
+", focusedElem is <"+focusedElem
.tagName
+"> "+focusedElem
.id
);
131 if (!elemThatShouldFocus
)
132 printToConsole("elemThatShouldFocus is null, focusedElem is <"+focusedElem
.tagName
+"> "+focusedElem
.id
);
134 printToConsole("elemThatShouldFocus is <"+elemThatShouldFocus
.tagName
+"> "+elemThatShouldFocus
.id
+", focusedElem is null");