function checkCommandState(testid, undoEnabled, copyEnabled, deleteEnabled) { is( !document.getElementById("cmd_undo").hasAttribute("disabled"), undoEnabled, testid + " undo" ); is( !document.getElementById("cmd_copy").hasAttribute("disabled"), copyEnabled, testid + " copy" ); is( !document.getElementById("cmd_delete").hasAttribute("disabled"), deleteEnabled, testid + " delete" ); } function keyAndUpdate(key, eventDetails, updateEventsCount) { let updatePromise = BrowserTestUtils.waitForEvent( window, "commandupdate", false, () => { return --updateEventsCount == 0; } ); EventUtils.synthesizeKey(key, eventDetails); return updatePromise; } add_task(async function test_controllers_subframes() { let tab = await BrowserTestUtils.openNewForegroundTab( gBrowser, OOP_BASE_PAGE_URI ); let browser = tab.linkedBrowser; let browsingContexts = await initChildFrames( browser, "

" ); gURLBar.focus(); let canTabMoveFocusToRootElement = !SpecialPowers.getBoolPref( "dom.disable_tab_focus_to_root_element" ); for (let stepNum = 0; stepNum < browsingContexts.length; stepNum++) { let useTab = stepNum > 0; // When canTabMoveFocusToRootElement is true, this kepress will move the // focus to a root element, which will trigger an extra "select" command // compare to the case when canTabMoveFocusToRootElement is false. await keyAndUpdate( useTab ? "VK_TAB" : "VK_F6", {}, canTabMoveFocusToRootElement ? 6 : 4 ); // Since focus may be switching into a separate process here, // need to wait for the focus to have been updated. await SpecialPowers.spawn(browsingContexts[stepNum], [], () => { return ContentTaskUtils.waitForCondition( () => content.browsingContext.isActive && content.document.hasFocus() ); }); // Force the UI to update on platforms that don't // normally do so until menus are opened. if (AppConstants.platform != "macosx") { goUpdateGlobalEditMenuItems(true); } await SpecialPowers.spawn( browsingContexts[stepNum], [{ canTabMoveFocusToRootElement, useTab }], args => { // Both the tab key and document navigation with F6 will focus // the root of the document within the frame. // When dom.disable_tab_focus_to_root_element is true, only F6 will do this. let document = content.document; let expectedElement = args.canTabMoveFocusToRootElement || !args.useTab ? document.documentElement : document.getElementById("input"); Assert.equal(document.activeElement, expectedElement, "root focused"); } ); if (canTabMoveFocusToRootElement || !useTab) { // XXX Currently, Copy is always enabled when the root (not an editor element) // is focused. Possibly that should only be true if a listener is present? checkCommandState( "step " + stepNum + " root focused", false, true, false ); // Tab to the textbox. await keyAndUpdate("VK_TAB", {}, 1); } if (AppConstants.platform != "macosx") { goUpdateGlobalEditMenuItems(true); } await SpecialPowers.spawn(browsingContexts[stepNum], [], () => { Assert.equal( content.document.activeElement, content.document.getElementById("input"), "input focused" ); }); checkCommandState( "step " + stepNum + " input focused", false, false, false ); // Type into the textbox. await keyAndUpdate("a", {}, 1); checkCommandState("step " + stepNum + " typed", true, false, false); await SpecialPowers.spawn(browsingContexts[stepNum], [], () => { Assert.equal( content.document.activeElement, content.document.getElementById("input"), "input focused" ); }); // Select all text; this causes the Copy and Delete commands to be enabled. await keyAndUpdate("a", { accelKey: true }, 1); if (AppConstants.platform != "macosx") { goUpdateGlobalEditMenuItems(true); } checkCommandState("step " + stepNum + " selected", true, true, true); // Now make sure that the text is selected. await SpecialPowers.spawn(browsingContexts[stepNum], [], () => { let input = content.document.getElementById("input"); Assert.equal(input.value, "a", "text matches"); Assert.equal(input.selectionStart, 0, "selectionStart matches"); Assert.equal(input.selectionEnd, 1, "selectionEnd matches"); }); } BrowserTestUtils.removeTab(tab); });