layout/printing/nsPrintPreviewListener.cpp

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

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

mercurial