diff options
author | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
---|---|---|
committer | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
commit | 5f8de423f190bbb79a62f804151bc24824fa32d8 (patch) | |
tree | 10027f336435511475e392454359edea8e25895d /layout/printing/nsPrintPreviewListener.cpp | |
parent | 49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff) | |
download | UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip |
Add m-esr52 at 52.6.0
Diffstat (limited to 'layout/printing/nsPrintPreviewListener.cpp')
-rw-r--r-- | layout/printing/nsPrintPreviewListener.cpp | 212 |
1 files changed, 212 insertions, 0 deletions
diff --git a/layout/printing/nsPrintPreviewListener.cpp b/layout/printing/nsPrintPreviewListener.cpp new file mode 100644 index 000000000..5edc0fb90 --- /dev/null +++ b/layout/printing/nsPrintPreviewListener.cpp @@ -0,0 +1,212 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsPrintPreviewListener.h" + +#include "mozilla/TextEvents.h" +#include "mozilla/dom/Element.h" +#include "mozilla/dom/Event.h" // for nsIDOMEvent::InternalDOMEvent() +#include "nsIDOMWindow.h" +#include "nsPIDOMWindow.h" +#include "nsIDOMElement.h" +#include "nsIDOMKeyEvent.h" +#include "nsIDOMEvent.h" +#include "nsIDocument.h" +#include "nsIDocShell.h" +#include "nsPresContext.h" +#include "nsFocusManager.h" +#include "nsLiteralString.h" + +using namespace mozilla; +using namespace mozilla::dom; + +NS_IMPL_ISUPPORTS(nsPrintPreviewListener, nsIDOMEventListener) + + +// +// nsPrintPreviewListener ctor +// +nsPrintPreviewListener::nsPrintPreviewListener(EventTarget* aTarget) + : mEventTarget(aTarget) +{ + NS_ADDREF_THIS(); +} // ctor + +nsPrintPreviewListener::~nsPrintPreviewListener() +{ +} + +//------------------------------------------------------- +// +// AddListeners +// +// Subscribe to the events that will allow us to track various events. +// +nsresult +nsPrintPreviewListener::AddListeners() +{ + if (mEventTarget) { + mEventTarget->AddEventListener(NS_LITERAL_STRING("click"), this, true); + mEventTarget->AddEventListener(NS_LITERAL_STRING("contextmenu"), this, true); + mEventTarget->AddEventListener(NS_LITERAL_STRING("keydown"), this, true); + mEventTarget->AddEventListener(NS_LITERAL_STRING("keypress"), this, true); + mEventTarget->AddEventListener(NS_LITERAL_STRING("keyup"), this, true); + mEventTarget->AddEventListener(NS_LITERAL_STRING("mousedown"), this, true); + mEventTarget->AddEventListener(NS_LITERAL_STRING("mousemove"), this, true); + mEventTarget->AddEventListener(NS_LITERAL_STRING("mouseout"), this, true); + mEventTarget->AddEventListener(NS_LITERAL_STRING("mouseover"), this, true); + mEventTarget->AddEventListener(NS_LITERAL_STRING("mouseup"), this, true); + + mEventTarget->AddSystemEventListener(NS_LITERAL_STRING("keydown"), + this, true); + } + + return NS_OK; +} + + +//------------------------------------------------------- +// +// RemoveListeners +// +// Unsubscribe from all the various events that we were listening to. +// +nsresult +nsPrintPreviewListener::RemoveListeners() +{ + if (mEventTarget) { + mEventTarget->RemoveEventListener(NS_LITERAL_STRING("click"), this, true); + mEventTarget->RemoveEventListener(NS_LITERAL_STRING("contextmenu"), this, true); + mEventTarget->RemoveEventListener(NS_LITERAL_STRING("keydown"), this, true); + mEventTarget->RemoveEventListener(NS_LITERAL_STRING("keypress"), this, true); + mEventTarget->RemoveEventListener(NS_LITERAL_STRING("keyup"), this, true); + mEventTarget->RemoveEventListener(NS_LITERAL_STRING("mousedown"), this, true); + mEventTarget->RemoveEventListener(NS_LITERAL_STRING("mousemove"), this, true); + mEventTarget->RemoveEventListener(NS_LITERAL_STRING("mouseout"), this, true); + mEventTarget->RemoveEventListener(NS_LITERAL_STRING("mouseover"), this, true); + mEventTarget->RemoveEventListener(NS_LITERAL_STRING("mouseup"), this, true); + + mEventTarget->RemoveSystemEventListener(NS_LITERAL_STRING("keydown"), + this, true); + } + + return NS_OK; +} + +//------------------------------------------------------- +// +// GetActionForEvent +// +// Helper function to let certain key events through +// +enum eEventAction { + eEventAction_Tab, eEventAction_ShiftTab, + eEventAction_Propagate, eEventAction_Suppress, + eEventAction_StopPropagation +}; + +static eEventAction +GetActionForEvent(nsIDOMEvent* aEvent) +{ + WidgetKeyboardEvent* keyEvent = + aEvent->WidgetEventPtr()->AsKeyboardEvent(); + if (!keyEvent) { + return eEventAction_Suppress; + } + + if (keyEvent->mFlags.mInSystemGroup) { + NS_ASSERTION(keyEvent->mMessage == eKeyDown, + "Assuming we're listening only keydown event in system group"); + return eEventAction_StopPropagation; + } + + if (keyEvent->IsAlt() || keyEvent->IsControl() || keyEvent->IsMeta()) { + // Don't consume keydown event because following keypress event may be + // handled as access key or shortcut key. + return (keyEvent->mMessage == eKeyDown) ? eEventAction_StopPropagation : + eEventAction_Suppress; + } + + static const uint32_t kOKKeyCodes[] = { + NS_VK_PAGE_UP, NS_VK_PAGE_DOWN, + NS_VK_UP, NS_VK_DOWN, + NS_VK_HOME, NS_VK_END + }; + + if (keyEvent->mKeyCode == NS_VK_TAB) { + return keyEvent->IsShift() ? eEventAction_ShiftTab : eEventAction_Tab; + } + + if (keyEvent->mCharCode == ' ' || keyEvent->mKeyCode == NS_VK_SPACE) { + return eEventAction_Propagate; + } + + if (keyEvent->IsShift()) { + return eEventAction_Suppress; + } + + for (uint32_t i = 0; i < ArrayLength(kOKKeyCodes); ++i) { + if (keyEvent->mKeyCode == kOKKeyCodes[i]) { + return eEventAction_Propagate; + } + } + + return eEventAction_Suppress; +} + +NS_IMETHODIMP +nsPrintPreviewListener::HandleEvent(nsIDOMEvent* aEvent) +{ + nsCOMPtr<nsIContent> content = do_QueryInterface( + aEvent ? aEvent->InternalDOMEvent()->GetOriginalTarget() : nullptr); + if (content && !content->IsXULElement()) { + eEventAction action = ::GetActionForEvent(aEvent); + switch (action) { + case eEventAction_Tab: + case eEventAction_ShiftTab: + { + nsAutoString eventString; + aEvent->GetType(eventString); + if (eventString.EqualsLiteral("keydown")) { + // Handle tabbing explicitly here since we don't want focus ending up + // inside the content document, bug 244128. + nsIDocument* doc = content->GetUncomposedDoc(); + NS_ASSERTION(doc, "no document"); + + nsIDocument* parentDoc = doc->GetParentDocument(); + NS_ASSERTION(parentDoc, "no parent document"); + + nsCOMPtr<nsPIDOMWindowOuter> win = parentDoc->GetWindow(); + + nsIFocusManager* fm = nsFocusManager::GetFocusManager(); + if (fm && win) { + dom::Element* fromElement = parentDoc->FindContentForSubDocument(doc); + nsCOMPtr<nsIDOMElement> from = do_QueryInterface(fromElement); + + bool forward = (action == eEventAction_Tab); + nsCOMPtr<nsIDOMElement> result; + fm->MoveFocus(win, from, + forward ? nsIFocusManager::MOVEFOCUS_FORWARD : + nsIFocusManager::MOVEFOCUS_BACKWARD, + nsIFocusManager::FLAG_BYKEY, getter_AddRefs(result)); + } + } + } + MOZ_FALLTHROUGH; + case eEventAction_Suppress: + aEvent->StopPropagation(); + aEvent->PreventDefault(); + break; + case eEventAction_StopPropagation: + aEvent->StopPropagation(); + break; + case eEventAction_Propagate: + // intentionally empty + break; + } + } + return NS_OK; +} |