diff -r 000000000000 -r 6474c204b198 dom/tests/mochitest/chrome/window_focus.xul --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dom/tests/mochitest/chrome/window_focus.xul Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,1718 @@ + + + + + + + + + + + "); + + 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); + +]]> + + + + + + + +