"); addEventListener("focus", doFrameSwitchingTests, true); noRootWindow = window.open(data, "_blank", "chrome,width=100,height=100"); } // these tests check when focus is moved between a tree of frames to ensure // that the focus is in the right place at each event step. function doFrameSwitchingTests() { removeEventListener("focus", doFrameSwitchingTests, true); noRootWindow.close(); var framea = document.getElementById("ifa"); var frameb = document.getElementById("ifb"); framea.style.MozUserFocus = ""; frameb.style.MozUserFocus = ""; window.removeEventListener("focus", eventOccured, true); window.removeEventListener("blur", eventOccured, true); var inputa = framea.contentDocument.body.firstChild; inputa.focus(); addFrameSwitchingListeners(framea); addFrameSwitchingListeners(frameb); var framec = framea.contentDocument.body.lastChild; addFrameSwitchingListeners(framec); var framed = framec.contentDocument.body.lastChild; addFrameSwitchingListeners(framed); var inputc = framec.contentDocument.body.firstChild; var expectedMainWindowFocus = framea; // An element in the immediate parent frame is focused. Focus an element in // the child. The child should be focused and the parent's current focus should // be the child iframe. gEventMatched = true; is(fm.getFocusedElementForWindow(window, false, {}), expectedMainWindowFocus, "parent of framea has iframe focused"); gExpectedEvents = [[inputa, "blur", null, framea.contentWindow, window, framea], [framea.contentDocument, "blur", null, null, window, framea], [framea.contentWindow, "blur", null, null, window, framea], [framec.contentDocument, "focus", null, framec.contentWindow, window, framea], [framec.contentWindow, "focus", null, framec.contentWindow, window, framea], [inputc, "focus", inputc, framec.contentWindow, window, framea]]; inputc.focus(); ok(gEventMatched && gExpectedEvents.length == 0, "frame switch from parent input to child input" + gExpectedEvents); // An element in a child is focused. Focus an element in the immediate // parent. gEventMatched = true; gExpectedEvents = [[inputc, "blur", null, framec.contentWindow, window, framea], [framec.contentDocument, "blur", null, null, window, framea], [framec.contentWindow, "blur", null, null, window, framea], [framea.contentDocument, "focus", null, framea.contentWindow, window, framea], [framea.contentWindow, "focus", null, framea.contentWindow, window, framea], [inputa, "focus", inputa, framea.contentWindow, window, framea]]; inputa.focus(); ok(gEventMatched && gExpectedEvents.length == 0, "frame switch from child input to parent input"); // An element in a frame is focused. Focus an element in a sibling frame. // The common ancestor of the two frames should have its focused node // cleared after the element is blurred. var inputb = frameb.contentDocument.body.firstChild; gEventMatched = true; gExpectedEvents = [[inputa, "blur", null, framea.contentWindow, window, framea], [framea.contentDocument, "blur", null, null, window, null], [framea.contentWindow, "blur", null, null, window, null], [frameb.contentDocument, "focus", null, frameb.contentWindow, window, frameb], [frameb.contentWindow, "focus", null, frameb.contentWindow, window, frameb], [inputb, "focus", inputb, frameb.contentWindow, window, frameb]]; inputb.focus(); ok(gEventMatched && gExpectedEvents.length == 0, "frame switch from input to sibling frame"); is(fm.getFocusedElementForWindow(framea.contentWindow, false, {}), inputa, "blurred frame still has input as focus"); // focus a descendant in a sibling var inputd = framed.contentDocument.body.firstChild; gEventMatched = true; gExpectedEvents = [[inputb, "blur", null, frameb.contentWindow, window, frameb], [frameb.contentDocument, "blur", null, null, window, null], [frameb.contentWindow, "blur", null, null, window, null], [framed.contentDocument, "focus", null, framed.contentWindow, window, framea], [framed.contentWindow, "focus", null, framed.contentWindow, window, framea], [inputd, "focus", inputd, framed.contentWindow, window, framea]]; inputd.focus(); ok(gEventMatched && gExpectedEvents.length == 0, "frame switch from input to sibling descendant"); is(fm.getFocusedElementForWindow(framea.contentWindow, false, {}), framec, "sibling parent focus has shifted to frame"); // focus an ancestor gEventMatched = true; gExpectedEvents = [[inputd, "blur", null, framed.contentWindow, window, framea], [framed.contentDocument, "blur", null, null, window, framea], [framed.contentWindow, "blur", null, null, window, framea], [framea.contentDocument, "focus", null, framea.contentWindow, window, framea], [framea.contentWindow, "focus", null, framea.contentWindow, window, framea], [inputa, "focus", inputa, framea.contentWindow, window, framea]]; inputa.focus(); ok(gEventMatched && gExpectedEvents.length == 0, "frame switch from child input to ancestor"); // focus a descendant gEventMatched = true; gExpectedEvents = [[inputa, "blur", null, framea.contentWindow, window, framea], [framea.contentDocument, "blur", null, null, window, framea], [framea.contentWindow, "blur", null, null, window, framea], [framed.contentDocument, "focus", null, framed.contentWindow, window, framea], [framed.contentWindow, "focus", null, framed.contentWindow, window, framea], [inputd, "focus", inputd, framed.contentWindow, window, framea]]; inputd.focus(); ok(gEventMatched && gExpectedEvents.length == 0, "frame switch from child input to ancestor"); is(fm.getFocusedElementForWindow(framea.contentWindow, false, {}), framec, "parent focus has shifted to frame"); // focus a sibling frame by setting focusedWindow gEventMatched = true; gExpectedEvents = [[inputd, "blur", null, framed.contentWindow, window, framea], [framed.contentDocument, "blur", null, null, window, null], [framed.contentWindow, "blur", null, null, window, null], [frameb.contentDocument, "focus", null, frameb.contentWindow, window, frameb], [frameb.contentWindow, "focus", null, frameb.contentWindow, window, frameb], [inputb, "focus", inputb, frameb.contentWindow, window, frameb]]; fm.focusedWindow = frameb.contentWindow; ok(gEventMatched && gExpectedEvents.length == 0, "frame switch using focusedWindow"); // clear the focus in an unfocused frame gEventMatched = true; gExpectedEvents = []; fm.clearFocus(framec.contentWindow); ok(gEventMatched && gExpectedEvents.length == 0, "clearFocus in unfocused frame"); // focus a sibling frame by setting focusedWindow when no element is focused in that frame gEventMatched = true; gExpectedEvents = [[inputb, "blur", null, frameb.contentWindow, window, frameb], [frameb.contentDocument, "blur", null, null, window, null], [frameb.contentWindow, "blur", null, null, window, null], [framec.contentDocument, "focus", null, framec.contentWindow, window, framea], [framec.contentWindow, "focus", null, framec.contentWindow, window, framea]]; fm.focusedWindow = framec.contentWindow; ok(gEventMatched && gExpectedEvents.length == 0, "frame switch using focusedWindow with no element focused"); is(fm.getFocusedElementForWindow(framea.contentWindow, false, {}), framec, "parent focus has shifted to frame using focusedWindow"); // focus the parent frame by setting focusedWindow. This should have no effect. gEventMatched = true; gExpectedEvents = []; fm.focusedWindow = framea.contentWindow; ok(gEventMatched && gExpectedEvents.length == 0, "frame switch to parent using focusedWindow"); // clear the focus in the parent frame gEventMatched = true; gExpectedEvents = [[framec.contentDocument, "blur", null, null, window, framea], [framec.contentWindow, "blur", null, null, window, framea], [framea.contentDocument, "focus", null, framea.contentWindow, window, framea], [framea.contentWindow, "focus", null, framea.contentWindow, window, framea]]; fm.clearFocus(framea.contentWindow); ok(gEventMatched && gExpectedEvents.length == 0, "clearFocus in parent frame"); // clear the focus in an unfocused child frame gEventMatched = true; gExpectedEvents = []; fm.clearFocus(framed.contentWindow); ok(gEventMatched && gExpectedEvents.length == 0, "clearFocus in unfocused child frame"); var exh = false; try { fm.focusedWindow = null; } catch (ex) { exh = true; } is(exh, true, "focusedWindow set to null"); is(fm.focusedWindow, framea.contentWindow, "window not changed when focusedWindow set to null"); doFrameHistoryTests() } function doFrameHistoryTests() { var t20 = getById("t20"); t20.focus(); gChildWindow.addEventListener("focus", function(event) { if (event.target == t20) { is(fm.focusedElement, t20, "focus restored after history back"); done(); } }, true); // make sure that loading a new page and then going back maintains the focus gChildWindow.location = "data:text/html,"; } function addFrameSwitchingListeners(frame) { frame.contentWindow.addEventListener("focus", frameSwitchingEventOccured, false); frame.contentWindow.addEventListener("blur", frameSwitchingEventOccured, false); frame.contentDocument.addEventListener("focus", frameSwitchingEventOccured, false); frame.contentDocument.addEventListener("blur", frameSwitchingEventOccured, false); var node = frame.contentDocument.body.firstChild; node.addEventListener("focus", frameSwitchingEventOccured, false); node.addEventListener("blur", frameSwitchingEventOccured, false); } function frameSwitchingEventOccured(event) { if (!gExpectedEvents.length) { gEventMatched = false; return; } try { var events = gExpectedEvents.shift(); is(event.target, events[0], "event target"); is(event.type, events[1], "event type"); is(fm.focusedElement, events[2], "focused element"); is(fm.focusedWindow, events[3], "focused frame"); if (events[4]) is(fm.getFocusedElementForWindow(events[4], false, {}), events[5], "focused element in frame"); if (gEventMatched && event.target == events[0] && event.type == events[1] && fm.focusedElement == events[2] && fm.focusedWindow == events[3]) { if (!events[4] || fm.getFocusedElementForWindow(events[4], false, {}) == events[5]) return; } } catch (ex) { ok(ex, "exception"); } gEventMatched = false; } SimpleTest.waitForExplicitFinish(); SimpleTest.waitForFocus(startTest); ]]>