diff --git a/dom/base/nsFocusManager.cpp b/dom/base/nsFocusManager.cpp index 7a76d50c0f66..5643fd4b68a5 100644 --- a/dom/base/nsFocusManager.cpp +++ b/dom/base/nsFocusManager.cpp @@ -1939,14 +1939,6 @@ Element* nsFocusManager::FlushAndCheckIfFocusable(Element* aElement, return aElement; } - // cannot focus content in print preview mode. Only the root can be focused. - nsPresContext* presContext = presShell->GetPresContext(); - if (presContext && - presContext->Type() == nsPresContext::eContext_PrintPreview) { - LOGCONTENT("Cannot focus %s while in print preview", aElement) - return nullptr; - } - nsIFrame* frame = aElement->GetPrimaryFrame(); if (!frame) { LOGCONTENT("Cannot focus %s as it has no frame", aElement) diff --git a/layout/generic/nsIFrame.cpp b/layout/generic/nsIFrame.cpp index 261b69724b0d..68eb0f670200 100644 --- a/layout/generic/nsIFrame.cpp +++ b/layout/generic/nsIFrame.cpp @@ -9871,6 +9871,12 @@ bool nsIFrame::IsFocusable(int32_t* aTabIndex, bool aWithMouse) { } bool isFocusable = false; + // cannot focus content in print preview mode. Only the root can be focused, + // but that's handled elsewhere. + if (PresContext()->Type() == nsPresContext::eContext_PrintPreview) { + return false; + } + if (mContent && mContent->IsElement() && IsVisibleConsideringAncestors() && Style()->GetPseudoType() != PseudoStyleType::anonymousFlexItem && Style()->GetPseudoType() != PseudoStyleType::anonymousGridItem && diff --git a/toolkit/components/printing/tests/browser_modal_print.js b/toolkit/components/printing/tests/browser_modal_print.js index 342043b2fc51..f54820816630 100644 --- a/toolkit/components/printing/tests/browser_modal_print.js +++ b/toolkit/components/printing/tests/browser_modal_print.js @@ -70,3 +70,66 @@ add_task(async function testCancelButton() { helper.assertDialogHidden(); }); }); + +add_task(async function testTabOrder() { + await PrintHelper.withTestPage(async helper => { + helper.assertDialogHidden(); + await helper.startPrint(); + helper.assertDialogVisible(); + + const printerPicker = helper.doc.getElementById("printer-picker"); + is( + helper.doc.activeElement, + printerPicker, + "Initial focus on printer picker" + ); + + // Due to bug 1327274, if we shift+tab before print preview is initialized, + // focus will get trapped. Therefore, wait for initialization first. + await helper.win.PrintEventHandler._previewUpdatingPromise; + const previewBrowser = document.querySelector(".printPreviewBrowser"); + ok(previewBrowser, "Got the print preview browser"); + let focused = BrowserTestUtils.waitForEvent(previewBrowser, "focus"); + EventUtils.synthesizeKey("KEY_Tab", { shiftKey: true }); + await focused; + ok(true, "Print preview focused after shift+tab"); + + focused = BrowserTestUtils.waitForEvent(gNavToolbox, "focus", true); + EventUtils.synthesizeKey("KEY_Tab", { shiftKey: true }); + await focused; + ok(true, "Toolbox focused after shift+tab"); + + focused = BrowserTestUtils.waitForEvent(previewBrowser, "focus"); + EventUtils.synthesizeKey("KEY_Tab"); + await focused; + ok(true, "Print preview focused after tab"); + + focused = BrowserTestUtils.waitForEvent(printerPicker, "focus"); + EventUtils.synthesizeKey("KEY_Tab"); + await focused; + ok(true, "Printer picker focused after tab"); + + const cancelButton = helper.doc.querySelector("button[name=cancel]"); + ok(cancelButton, "Got the cancel button"); + focused = BrowserTestUtils.waitForEvent(cancelButton, "focus"); + cancelButton.focus(); + await focused; + ok(true, "Cancel button focused"); + + focused = BrowserTestUtils.waitForEvent(gNavToolbox, "focus", true); + EventUtils.synthesizeKey("KEY_Tab"); + await focused; + ok(true, "Toolbox focused after tab"); + + focused = BrowserTestUtils.waitForEvent(cancelButton, "focus"); + EventUtils.synthesizeKey("KEY_Tab", { shiftKey: true }); + await focused; + ok(true, "Cancel button focused after shift+tab"); + + await helper.withClosingFn(() => { + EventUtils.synthesizeKey("VK_ESCAPE", {}); + }); + + helper.assertDialogHidden(); + }); +});