Bug 1551882. Refactor the print preview listener code to make its purpose clear. r=bobowen

Differential Revision: https://phabricator.services.mozilla.com/D31252

--HG--
rename : layout/printing/nsPrintPreviewListener.cpp => layout/printing/PrintPreviewUserEventSuppressor.cpp
rename : layout/printing/nsPrintPreviewListener.h => layout/printing/PrintPreviewUserEventSuppressor.h
extra : rebase_source : a2bfc2635d8cb98ee7c93597c6f805122e99111f
extra : amend_source : 2d3c11cbc8e07fa90b1960c4e1a4422c12f2761b
This commit is contained in:
Jonathan Watt 2019-05-16 23:16:11 +01:00
parent f6c688146a
commit dbcde07e70
8 changed files with 95 additions and 109 deletions

View File

@ -4,7 +4,7 @@
* 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 "PrintPreviewUserEventSuppressor.h"
#include "mozilla/TextEvents.h"
#include "mozilla/dom/Element.h"
@ -17,28 +17,19 @@
#include "nsFocusManager.h"
#include "nsLiteralString.h"
using namespace mozilla;
using namespace mozilla::dom;
NS_IMPL_ISUPPORTS(nsPrintPreviewListener, nsIDOMEventListener)
namespace mozilla {
//
// nsPrintPreviewListener ctor
//
nsPrintPreviewListener::nsPrintPreviewListener(EventTarget* aTarget)
PrintPreviewUserEventSuppressor::PrintPreviewUserEventSuppressor(
EventTarget* aTarget)
: mEventTarget(aTarget) {
NS_ADDREF_THIS();
} // ctor
AddListeners();
}
nsPrintPreviewListener::~nsPrintPreviewListener() {}
NS_IMPL_ISUPPORTS(PrintPreviewUserEventSuppressor, nsIDOMEventListener)
//-------------------------------------------------------
//
// AddListeners
//
// Subscribe to the events that will allow us to track various events.
//
nsresult nsPrintPreviewListener::AddListeners() {
void PrintPreviewUserEventSuppressor::AddListeners() {
if (mEventTarget) {
mEventTarget->AddEventListener(NS_LITERAL_STRING("click"), this, true);
mEventTarget->AddEventListener(NS_LITERAL_STRING("contextmenu"), this,
@ -55,17 +46,9 @@ nsresult nsPrintPreviewListener::AddListeners() {
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() {
void PrintPreviewUserEventSuppressor::RemoveListeners() {
if (mEventTarget) {
mEventTarget->RemoveEventListener(NS_LITERAL_STRING("click"), this, true);
mEventTarget->RemoveEventListener(NS_LITERAL_STRING("contextmenu"), this,
@ -87,16 +70,8 @@ nsresult nsPrintPreviewListener::RemoveListeners() {
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,
@ -105,6 +80,7 @@ enum eEventAction {
eEventAction_StopPropagation
};
// Helper function to let certain key events through
static eEventAction GetActionForEvent(Event* aEvent) {
WidgetKeyboardEvent* keyEvent = aEvent->WidgetEventPtr()->AsKeyboardEvent();
if (!keyEvent) {
@ -150,11 +126,11 @@ static eEventAction GetActionForEvent(Event* aEvent) {
}
NS_IMETHODIMP
nsPrintPreviewListener::HandleEvent(Event* aEvent) {
PrintPreviewUserEventSuppressor::HandleEvent(Event* aEvent) {
nsCOMPtr<nsIContent> content =
do_QueryInterface(aEvent ? aEvent->GetOriginalTarget() : nullptr);
if (content && !content->IsXULElement()) {
eEventAction action = ::GetActionForEvent(aEvent);
eEventAction action = GetActionForEvent(aEvent);
switch (action) {
case eEventAction_Tab:
case eEventAction_ShiftTab: {
@ -173,10 +149,9 @@ nsPrintPreviewListener::HandleEvent(Event* aEvent) {
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
if (fm && win) {
dom::Element* fromElement =
parentDoc->FindContentForSubDocument(doc);
Element* fromElement = parentDoc->FindContentForSubDocument(doc);
bool forward = (action == eEventAction_Tab);
RefPtr<dom::Element> result;
RefPtr<Element> result;
fm->MoveFocus(win, fromElement,
forward ? nsIFocusManager::MOVEFOCUS_FORWARD
: nsIFocusManager::MOVEFOCUS_BACKWARD,
@ -199,3 +174,5 @@ nsPrintPreviewListener::HandleEvent(Event* aEvent) {
}
return NS_OK;
}
} // namespace mozilla

View File

@ -0,0 +1,53 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
#ifndef mozilla_PrintPreviewUserEventSuppressor_h
#define mozilla_PrintPreviewUserEventSuppressor_h
#include "nsCOMPtr.h"
#include "nsIDOMEventListener.h"
#include "mozilla/Attributes.h"
namespace mozilla {
namespace dom {
class EventTarget;
} // namespace dom
/**
* A class that filters out certain user events targeted at the given event
* target (a document). Intended for use with the Print Preview document to
* stop users from doing anything that would break printing invariants. (For
* example, blocks opening of the context menu, interaction with form controls,
* content selection, etc.)
*/
class PrintPreviewUserEventSuppressor final : public nsIDOMEventListener {
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIDOMEVENTLISTENER
explicit PrintPreviewUserEventSuppressor(dom::EventTarget* aTarget);
/**
* Must be called before releasing this object in order to break the strong
* reference cycle between ourselves and the document we're listening to,
* or else the objects in the cylce will be leaked (since this class does
* not participate in cycle collection).
*/
void StopSuppressing() { RemoveListeners(); }
private:
~PrintPreviewUserEventSuppressor() { RemoveListeners(); }
void AddListeners();
void RemoveListeners();
nsCOMPtr<mozilla::dom::EventTarget> mEventTarget;
};
} // namespace mozilla
#endif // mozilla_PrintPreviewUserEventSuppressor_h

View File

@ -28,7 +28,7 @@ UNIFIED_SOURCES += [
'nsPrintData.cpp',
'nsPrintJob.cpp',
'nsPrintObject.cpp',
'nsPrintPreviewListener.cpp',
'PrintPreviewUserEventSuppressor.cpp',
'PrintTranslator.cpp',
]

View File

@ -10,9 +10,9 @@
#include "nsIServiceManager.h"
#include "nsIWidget.h"
#include "nsPrintObject.h"
#include "nsPrintPreviewListener.h"
#include "nsIWebProgressListener.h"
#include "mozilla/Services.h"
#include "PrintPreviewUserEventSuppressor.h"
//-----------------------------------------------------
// PR LOGGING
@ -38,8 +38,7 @@ nsPrintData::nsPrintData(ePrintDataType aType)
mPrintFrameType(nsIPrintSettings::kFramesAsIs),
mNumPrintablePages(0),
mNumPagesPrinted(0),
mShrinkRatio(1.0),
mPPEventListeners(nullptr) {
mShrinkRatio(1.0) {
nsCOMPtr<nsIStringBundle> brandBundle;
nsCOMPtr<nsIStringBundleService> svc =
mozilla::services::GetStringBundleService();
@ -57,10 +56,9 @@ nsPrintData::nsPrintData(ePrintDataType aType)
}
nsPrintData::~nsPrintData() {
// remove the event listeners
if (mPPEventListeners) {
mPPEventListeners->RemoveListeners();
NS_RELEASE(mPPEventListeners);
if (mPPEventSuppressor) {
mPPEventSuppressor->StopSuppressing();
mPPEventSuppressor = nullptr;
}
// Only Send an OnEndPrinting if we have started printing

View File

@ -18,11 +18,13 @@
#include "nsTArray.h"
#include "nsCOMArray.h"
// Classes
class nsPrintObject;
class nsPrintPreviewListener;
class nsIWebProgressListener;
namespace mozilla {
class PrintPreviewUserEventSuppressor;
} // namespace mozilla
//------------------------------------------------------------------------
// nsPrintData Class
//
@ -38,6 +40,9 @@ class nsIWebProgressListener;
//
//------------------------------------------------------------------------
class nsPrintData {
typedef mozilla::PrintPreviewUserEventSuppressor
PrintPreviewUserEventSuppressor;
public:
typedef enum { eIsPrinting, eIsPrintPreview } ePrintDataType;
@ -82,7 +87,7 @@ class nsPrintData {
float mShrinkRatio;
nsCOMPtr<nsIPrintSettings> mPrintSettings;
nsPrintPreviewListener* mPPEventListeners;
RefPtr<PrintPreviewUserEventSuppressor> mPPEventSuppressor;
nsString mBrandName; // needed as a substitute name for a document

View File

@ -38,8 +38,6 @@
static const char sPrintSettingsServiceContractID[] =
"@mozilla.org/gfx/printsettings-service;1";
// Printing Events
#include "nsPrintPreviewListener.h"
#include "nsThreadUtils.h"
// Printing
@ -116,6 +114,7 @@ static const char kPrintingPromptService[] =
#include "mozilla/dom/HTMLFrameElement.h"
#include "nsContentList.h"
#include "nsIChannel.h"
#include "PrintPreviewUserEventSuppressor.h"
#include "xpcpublic.h"
#include "nsVariant.h"
#include "mozilla/ServoStyleSet.h"
@ -571,8 +570,8 @@ nsresult nsPrintJob::Cancelled() {
// some events from being processed while in PrintPreview
//
// No return code - if this fails, there isn't much we can do
void nsPrintJob::InstallPrintPreviewListener() {
if (!mPrt->mPPEventListeners) {
void nsPrintJob::SuppressPrintPreviewUserEvents() {
if (!mPrt->mPPEventSuppressor) {
nsCOMPtr<nsIDocShell> docShell = do_QueryReferent(mContainer);
if (!docShell) {
return;
@ -580,8 +579,7 @@ void nsPrintJob::InstallPrintPreviewListener() {
if (nsPIDOMWindowOuter* win = docShell->GetWindow()) {
nsCOMPtr<EventTarget> target = win->GetFrameElementInternal();
mPrt->mPPEventListeners = new nsPrintPreviewListener(target);
mPrt->mPPEventListeners->AddListeners();
mPrt->mPPEventSuppressor = new PrintPreviewUserEventSuppressor(target);
}
}
}
@ -1007,7 +1005,7 @@ nsresult nsPrintJob::DoCommonPrint(bool aIsPrintPreview,
TurnScriptingOn(false);
if (!notifyOnInit) {
InstallPrintPreviewListener();
SuppressPrintPreviewUserEvents();
rv = InitPrintDocConstruction(false);
} else {
rv = NS_OK;

View File

@ -109,7 +109,13 @@ class nsPrintJob final : public nsIObserver,
void TurnScriptingOn(bool aDoTurnOn);
bool CheckDocumentForPPCaching();
void InstallPrintPreviewListener();
/**
* Filters out certain user events while Print Preview is open to prevent
* the user from interacting with the Print Preview document and breaking
* printing invariants.
*/
void SuppressPrintPreviewUserEvents();
// nsIDocumentViewerPrint Printing Methods
bool HasPrintCallbackCanvas();

View File

@ -1,51 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
#ifndef nsPrintPreviewListener_h__
#define nsPrintPreviewListener_h__
// Interfaces needed to be included
#include "nsIDOMEventListener.h"
// Helper Classes
#include "nsCOMPtr.h"
#include "mozilla/Attributes.h"
namespace mozilla {
namespace dom {
class EventTarget;
} // namespace dom
} // namespace mozilla
//
// class nsPrintPreviewListener
//
// The class that listens to the chrome events and tells the embedding
// chrome to show context menus, as appropriate. Handles registering itself
// with the DOM with AddChromeListeners() and removing itself with
// RemoveChromeListeners().
//
class nsPrintPreviewListener final : public nsIDOMEventListener
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIDOMEVENTLISTENER
explicit nsPrintPreviewListener(mozilla::dom::EventTarget* aTarget);
// Add/remove the relevant listeners, based on what interfaces
// the embedding chrome implements.
nsresult AddListeners();
nsresult RemoveListeners();
private:
~nsPrintPreviewListener();
nsCOMPtr<mozilla::dom::EventTarget> mEventTarget;
}; // class nsPrintPreviewListener
#endif /* nsPrintPreviewListener_h__ */