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);
+
+]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+