layout/printing/nsPrintPreviewListener.cpp

Wed, 31 Dec 2014 13:27:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 13:27:57 +0100
branch
TOR_BUG_3246
changeset 6
8bccb770b82d
permissions
-rw-r--r--

Ignore runtime configuration files generated during quality assurance.

     1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
     2  *
     3  * This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 #include "nsPrintPreviewListener.h"
     9 #include "mozilla/TextEvents.h"
    10 #include "mozilla/dom/Element.h"
    11 #include "mozilla/dom/Event.h" // for nsIDOMEvent::InternalDOMEvent()
    12 #include "nsIDOMWindow.h"
    13 #include "nsPIDOMWindow.h"
    14 #include "nsIDOMElement.h"
    15 #include "nsIDOMKeyEvent.h"
    16 #include "nsIDOMEvent.h"
    17 #include "nsIDocument.h"
    18 #include "nsIDocShell.h"
    19 #include "nsPresContext.h"
    20 #include "nsFocusManager.h"
    21 #include "nsLiteralString.h"
    23 using namespace mozilla;
    24 using namespace mozilla::dom;
    26 NS_IMPL_ISUPPORTS(nsPrintPreviewListener, nsIDOMEventListener)
    29 //
    30 // nsPrintPreviewListener ctor
    31 //
    32 nsPrintPreviewListener::nsPrintPreviewListener(EventTarget* aTarget)
    33   : mEventTarget(aTarget)
    34 {
    35   NS_ADDREF_THIS();
    36 } // ctor
    38 nsPrintPreviewListener::~nsPrintPreviewListener()
    39 {
    40 }
    42 //-------------------------------------------------------
    43 //
    44 // AddListeners
    45 //
    46 // Subscribe to the events that will allow us to track various events. 
    47 //
    48 nsresult
    49 nsPrintPreviewListener::AddListeners()
    50 {
    51   if (mEventTarget) {
    52     mEventTarget->AddEventListener(NS_LITERAL_STRING("click"), this, true);
    53     mEventTarget->AddEventListener(NS_LITERAL_STRING("contextmenu"), this, true);
    54     mEventTarget->AddEventListener(NS_LITERAL_STRING("keydown"), this, true);
    55     mEventTarget->AddEventListener(NS_LITERAL_STRING("keypress"), this, true);
    56     mEventTarget->AddEventListener(NS_LITERAL_STRING("keyup"), this, true);
    57     mEventTarget->AddEventListener(NS_LITERAL_STRING("mousedown"), this, true);
    58     mEventTarget->AddEventListener(NS_LITERAL_STRING("mousemove"), this, true);
    59     mEventTarget->AddEventListener(NS_LITERAL_STRING("mouseout"), this, true);
    60     mEventTarget->AddEventListener(NS_LITERAL_STRING("mouseover"), this, true);
    61     mEventTarget->AddEventListener(NS_LITERAL_STRING("mouseup"), this, true);
    63     mEventTarget->AddSystemEventListener(NS_LITERAL_STRING("keydown"),
    64                                          this, true);
    65   }
    67   return NS_OK;
    68 }
    71 //-------------------------------------------------------
    72 //
    73 // RemoveListeners
    74 //
    75 // Unsubscribe from all the various events that we were listening to. 
    76 //
    77 nsresult 
    78 nsPrintPreviewListener::RemoveListeners()
    79 {
    80   if (mEventTarget) {
    81     mEventTarget->RemoveEventListener(NS_LITERAL_STRING("click"), this, true);
    82     mEventTarget->RemoveEventListener(NS_LITERAL_STRING("contextmenu"), this, true);
    83     mEventTarget->RemoveEventListener(NS_LITERAL_STRING("keydown"), this, true);
    84     mEventTarget->RemoveEventListener(NS_LITERAL_STRING("keypress"), this, true);
    85     mEventTarget->RemoveEventListener(NS_LITERAL_STRING("keyup"), this, true);
    86     mEventTarget->RemoveEventListener(NS_LITERAL_STRING("mousedown"), this, true);
    87     mEventTarget->RemoveEventListener(NS_LITERAL_STRING("mousemove"), this, true);
    88     mEventTarget->RemoveEventListener(NS_LITERAL_STRING("mouseout"), this, true);
    89     mEventTarget->RemoveEventListener(NS_LITERAL_STRING("mouseover"), this, true);
    90     mEventTarget->RemoveEventListener(NS_LITERAL_STRING("mouseup"), this, true);
    92     mEventTarget->RemoveSystemEventListener(NS_LITERAL_STRING("keydown"),
    93                                             this, true);
    94   }
    96   return NS_OK;
    97 }
    99 //-------------------------------------------------------
   100 //
   101 // GetActionForEvent
   102 //
   103 // Helper function to let certain key events through
   104 //
   105 enum eEventAction {
   106   eEventAction_Tab,       eEventAction_ShiftTab,
   107   eEventAction_Propagate, eEventAction_Suppress,
   108   eEventAction_StopPropagation
   109 };
   111 static eEventAction
   112 GetActionForEvent(nsIDOMEvent* aEvent)
   113 {
   114   WidgetKeyboardEvent* keyEvent =
   115     aEvent->GetInternalNSEvent()->AsKeyboardEvent();
   116   if (!keyEvent) {
   117     return eEventAction_Suppress;
   118   }
   120   if (keyEvent->mFlags.mInSystemGroup) {
   121     NS_ASSERTION(keyEvent->message == NS_KEY_DOWN,
   122       "Assuming we're listening only keydown event in system group");
   123     return eEventAction_StopPropagation;
   124   }
   126   if (keyEvent->IsAlt() || keyEvent->IsControl() || keyEvent->IsMeta()) {
   127     // Don't consume keydown event because following keypress event may be
   128     // handled as access key or shortcut key.
   129     return (keyEvent->message == NS_KEY_DOWN) ? eEventAction_StopPropagation :
   130                                                 eEventAction_Suppress;
   131   }
   133   static const uint32_t kOKKeyCodes[] = {
   134     nsIDOMKeyEvent::DOM_VK_PAGE_UP, nsIDOMKeyEvent::DOM_VK_PAGE_DOWN,
   135     nsIDOMKeyEvent::DOM_VK_UP,      nsIDOMKeyEvent::DOM_VK_DOWN, 
   136     nsIDOMKeyEvent::DOM_VK_HOME,    nsIDOMKeyEvent::DOM_VK_END 
   137   };
   139   if (keyEvent->keyCode == nsIDOMKeyEvent::DOM_VK_TAB) {
   140     return keyEvent->IsShift() ? eEventAction_ShiftTab : eEventAction_Tab;
   141   }
   143   if (keyEvent->charCode == ' ' || keyEvent->keyCode == NS_VK_SPACE) {
   144     return eEventAction_Propagate;
   145   }
   147   if (keyEvent->IsShift()) {
   148     return eEventAction_Suppress;
   149   }
   151   for (uint32_t i = 0; i < ArrayLength(kOKKeyCodes); ++i) {
   152     if (keyEvent->keyCode == kOKKeyCodes[i]) {
   153       return eEventAction_Propagate;
   154     }
   155   }
   157   return eEventAction_Suppress;
   158 }
   160 NS_IMETHODIMP
   161 nsPrintPreviewListener::HandleEvent(nsIDOMEvent* aEvent)
   162 {
   163   nsCOMPtr<nsIContent> content = do_QueryInterface(
   164     aEvent ? aEvent->InternalDOMEvent()->GetOriginalTarget() : nullptr);
   165   if (content && !content->IsXUL()) {
   166     eEventAction action = ::GetActionForEvent(aEvent);
   167     switch (action) {
   168       case eEventAction_Tab:
   169       case eEventAction_ShiftTab:
   170       {
   171         nsAutoString eventString;
   172         aEvent->GetType(eventString);
   173         if (eventString == NS_LITERAL_STRING("keydown")) {
   174           // Handle tabbing explicitly here since we don't want focus ending up
   175           // inside the content document, bug 244128.
   176           nsIDocument* doc = content->GetCurrentDoc();
   177           NS_ASSERTION(doc, "no document");
   179           nsIDocument* parentDoc = doc->GetParentDocument();
   180           NS_ASSERTION(parentDoc, "no parent document");
   182           nsCOMPtr<nsIDOMWindow> win = do_QueryInterface(parentDoc->GetWindow());
   184           nsIFocusManager* fm = nsFocusManager::GetFocusManager();
   185           if (fm && win) {
   186             dom::Element* fromElement = parentDoc->FindContentForSubDocument(doc);
   187             nsCOMPtr<nsIDOMElement> from = do_QueryInterface(fromElement);
   189             bool forward = (action == eEventAction_Tab);
   190             nsCOMPtr<nsIDOMElement> result;
   191             fm->MoveFocus(win, from,
   192                           forward ? nsIFocusManager::MOVEFOCUS_FORWARD :
   193                                     nsIFocusManager::MOVEFOCUS_BACKWARD,
   194                           nsIFocusManager::FLAG_BYKEY, getter_AddRefs(result));
   195           }
   196         }
   197       }
   198       // fall-through
   199       case eEventAction_Suppress:
   200         aEvent->StopPropagation();
   201         aEvent->PreventDefault();
   202         break;
   203       case eEventAction_StopPropagation:
   204         aEvent->StopPropagation();
   205         break;
   206       case eEventAction_Propagate:
   207         // intentionally empty
   208         break;
   209     }
   210   }
   211   return NS_OK;
   212 }

mercurial