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