зеркало из https://github.com/mozilla/pjs.git
Prevent having kbd focus inside the content document in Print Preview. b=244128 r=bryner sr=bzbarsky a=asa
This commit is contained in:
Родитель
5a9bcfc92c
Коммит
900fbeaa4b
|
@ -5128,12 +5128,20 @@ nsEventStateManager::TabIntoDocument(nsIDocShell* aDocShell,
|
|||
nsCOMPtr<nsIDocShellTreeItem> treeItem = do_QueryInterface(aDocShell);
|
||||
treeItem->GetItemType(&itemType);
|
||||
|
||||
nsCOMPtr<nsPresContext> presContext;
|
||||
aDocShell->GetPresContext(getter_AddRefs(presContext));
|
||||
PRBool focusDocument;
|
||||
if (!aForward || (itemType == nsIDocShellTreeItem::typeChrome))
|
||||
focusDocument = PR_FALSE;
|
||||
else {
|
||||
// Check for a frameset document
|
||||
focusDocument = !(IsFrameSetDoc(aDocShell));
|
||||
if (presContext &&
|
||||
presContext->Type() == nsPresContext::eContext_PrintPreview) {
|
||||
// Don't focus any content in print preview mode, bug 244128.
|
||||
focusDocument = PR_TRUE;
|
||||
} else {
|
||||
if (!aForward || (itemType == nsIDocShellTreeItem::typeChrome))
|
||||
focusDocument = PR_FALSE;
|
||||
else {
|
||||
// Check for a frameset document
|
||||
focusDocument = !(IsFrameSetDoc(aDocShell));
|
||||
}
|
||||
}
|
||||
|
||||
if (focusDocument) {
|
||||
|
@ -5143,10 +5151,8 @@ nsEventStateManager::TabIntoDocument(nsIDocShell* aDocShell,
|
|||
else {
|
||||
aDocShell->SetHasFocus(PR_FALSE);
|
||||
|
||||
nsCOMPtr<nsPresContext> pc;
|
||||
aDocShell->GetPresContext(getter_AddRefs(pc));
|
||||
if (pc) {
|
||||
nsIEventStateManager *docESM = pc->EventStateManager();
|
||||
if (presContext) {
|
||||
nsIEventStateManager *docESM = presContext->EventStateManager();
|
||||
|
||||
// we are about to shift focus to aDocShell
|
||||
// keep track of the document, so we don't try to go back into it.
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
#include "nsIDocument.h"
|
||||
#include "nsPresContext.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsIEventStateManager.h"
|
||||
#include "nsStyleSet.h"
|
||||
#include "nsIStyleSheet.h"
|
||||
#include "nsICSSStyleSheet.h"
|
||||
|
@ -3948,6 +3949,37 @@ DocumentViewerImpl::ReturnToGalleyPresentation()
|
|||
#endif // NS_PRINTING && NS_PRINT_PREVIEW
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
// Reset ESM focus for all descendent doc shells.
|
||||
static void
|
||||
ResetFocusState(nsIDocShell* aDocShell)
|
||||
{
|
||||
nsCOMPtr<nsISimpleEnumerator> docShellEnumerator;
|
||||
aDocShell->GetDocShellEnumerator(nsIDocShellTreeItem::typeContent,
|
||||
nsIDocShell::ENUMERATE_FORWARDS,
|
||||
getter_AddRefs(docShellEnumerator));
|
||||
|
||||
nsCOMPtr<nsIDocShell> currentDocShell;
|
||||
nsCOMPtr<nsISupports> currentContainer;
|
||||
PRBool hasMoreDocShells;
|
||||
while (NS_SUCCEEDED(docShellEnumerator->HasMoreElements(&hasMoreDocShells))
|
||||
&& hasMoreDocShells) {
|
||||
docShellEnumerator->GetNext(getter_AddRefs(currentContainer));
|
||||
currentDocShell = do_QueryInterface(currentContainer);
|
||||
if (!currentDocShell) {
|
||||
break;
|
||||
}
|
||||
nsCOMPtr<nsPresContext> presContext;
|
||||
currentDocShell->GetPresContext(getter_AddRefs(presContext));
|
||||
nsIEventStateManager* esm =
|
||||
presContext ? presContext->EventStateManager() : nsnull;
|
||||
if (esm) {
|
||||
esm->SetContentState(nsnull, NS_EVENT_STATE_FOCUS);
|
||||
esm->SetFocusedContent(nsnull);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
void
|
||||
DocumentViewerImpl::InstallNewPresentation()
|
||||
|
@ -3966,6 +3998,7 @@ DocumentViewerImpl::InstallNewPresentation()
|
|||
nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(dstParentItem));
|
||||
if (docShell) {
|
||||
docShell->SetHasFocus(PR_TRUE);
|
||||
::ResetFocusState(docShell);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Mats Palmgren <mats.palmgren@bredband.net>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
|
@ -40,6 +41,11 @@
|
|||
#include "nsIContent.h"
|
||||
#include "nsIDOMKeyEvent.h"
|
||||
#include "nsIDOMNSEvent.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsPresContext.h"
|
||||
#include "nsIEventStateManager.h"
|
||||
#include "nsLiteralString.h"
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsPrintPreviewListener, nsIDOMEventListener)
|
||||
|
@ -108,50 +114,93 @@ nsPrintPreviewListener::RemoveListeners()
|
|||
|
||||
//-------------------------------------------------------
|
||||
//
|
||||
// IsKeyOK
|
||||
// GetActionForEvent
|
||||
//
|
||||
// Helper function to let certain key events thru
|
||||
//
|
||||
static PRBool IsKeyOK(nsIDOMEvent* aEvent)
|
||||
enum eEventAction {
|
||||
eEventAction_Tab, eEventAction_ShiftTab,
|
||||
eEventAction_Propagate, eEventAction_Suppress
|
||||
};
|
||||
|
||||
static eEventAction
|
||||
GetActionForEvent(nsIDOMEvent* aEvent)
|
||||
{
|
||||
const PRUint32 kOKKeyCodes[] = {nsIDOMKeyEvent::DOM_VK_PAGE_UP, nsIDOMKeyEvent::DOM_VK_PAGE_DOWN,
|
||||
nsIDOMKeyEvent::DOM_VK_UP, nsIDOMKeyEvent::DOM_VK_DOWN,
|
||||
nsIDOMKeyEvent::DOM_VK_HOME, nsIDOMKeyEvent::DOM_VK_END,
|
||||
nsIDOMKeyEvent::DOM_VK_TAB, 0};
|
||||
static const PRUint32 kOKKeyCodes[] = {
|
||||
nsIDOMKeyEvent::DOM_VK_PAGE_UP, nsIDOMKeyEvent::DOM_VK_PAGE_DOWN,
|
||||
nsIDOMKeyEvent::DOM_VK_UP, nsIDOMKeyEvent::DOM_VK_DOWN,
|
||||
nsIDOMKeyEvent::DOM_VK_HOME, nsIDOMKeyEvent::DOM_VK_END
|
||||
};
|
||||
|
||||
nsCOMPtr<nsIDOMKeyEvent> keyEvent(do_QueryInterface(aEvent));
|
||||
if (keyEvent) {
|
||||
PRBool b;
|
||||
keyEvent->GetAltKey(&b);
|
||||
if (b) return PR_FALSE;
|
||||
if (b) return eEventAction_Suppress;
|
||||
keyEvent->GetCtrlKey(&b);
|
||||
if (b) return PR_FALSE;
|
||||
if (b) return eEventAction_Suppress;
|
||||
|
||||
keyEvent->GetShiftKey(&b);
|
||||
if (b) return PR_FALSE;
|
||||
|
||||
PRUint32 keyCode;
|
||||
keyEvent->GetKeyCode(&keyCode);
|
||||
PRInt32 i = 0;
|
||||
while (kOKKeyCodes[i] != 0) {
|
||||
if (keyCode == nsIDOMKeyEvent::DOM_VK_TAB)
|
||||
return b ? eEventAction_ShiftTab : eEventAction_Tab;
|
||||
|
||||
if (b) return eEventAction_Suppress;
|
||||
|
||||
for (PRUint32 i = 0; i < sizeof(kOKKeyCodes)/sizeof(kOKKeyCodes[0]); ++i) {
|
||||
if (keyCode == kOKKeyCodes[i]) {
|
||||
return PR_TRUE;
|
||||
return eEventAction_Propagate;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return PR_FALSE;
|
||||
return eEventAction_Suppress;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintPreviewListener::HandleEvent(nsIDOMEvent* aKeyEvent)
|
||||
{
|
||||
NS_IMETHODIMP
|
||||
nsPrintPreviewListener::HandleEvent(nsIDOMEvent* aEvent)
|
||||
{
|
||||
nsCOMPtr<nsIDOMEventTarget> target;
|
||||
nsCOMPtr<nsIDOMNSEvent> nsEvent = do_QueryInterface(aKeyEvent);
|
||||
nsCOMPtr<nsIDOMNSEvent> nsEvent = do_QueryInterface(aEvent);
|
||||
if (nsEvent)
|
||||
nsEvent->GetOriginalTarget(getter_AddRefs(target));
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(target));
|
||||
if (content && !content->IsContentOfType(nsIContent::eXUL) && !IsKeyOK(aKeyEvent)) {
|
||||
aKeyEvent->StopPropagation();
|
||||
aKeyEvent->PreventDefault();
|
||||
if (content && !content->IsContentOfType(nsIContent::eXUL)) {
|
||||
eEventAction action = ::GetActionForEvent(aEvent);
|
||||
switch (action) {
|
||||
case eEventAction_Tab:
|
||||
case eEventAction_ShiftTab:
|
||||
{
|
||||
nsAutoString eventString;
|
||||
aEvent->GetType(eventString);
|
||||
if (eventString == NS_LITERAL_STRING("keydown")) {
|
||||
// Handle tabbing explicitly here since we don't want focus ending up
|
||||
// inside the content document, bug 244128.
|
||||
nsIDocument* doc = content->GetCurrentDoc();
|
||||
NS_ASSERTION(doc, "no document");
|
||||
|
||||
nsIDocument* parentDoc = doc->GetParentDocument();
|
||||
NS_ASSERTION(parentDoc, "no parent document");
|
||||
nsIEventStateManager* esm =
|
||||
parentDoc->GetShellAt(0)->GetPresContext()->EventStateManager();
|
||||
if (esm) {
|
||||
esm->SetContentState(nsnull, NS_EVENT_STATE_FOCUS);
|
||||
PRBool forward = (action == eEventAction_Tab);
|
||||
esm->ShiftFocus(forward,
|
||||
forward ? nsnull : parentDoc->FindContentForSubDocument(doc));
|
||||
}
|
||||
}
|
||||
}
|
||||
// fall-through
|
||||
case eEventAction_Suppress:
|
||||
aEvent->StopPropagation();
|
||||
aEvent->PreventDefault();
|
||||
break;
|
||||
case eEventAction_Propagate:
|
||||
// intentionally empty
|
||||
break;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче