mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-08 08:17:31 +09:00
import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo
This commit is contained in:
commit
dcd9973243
150858 changed files with 23884658 additions and 0 deletions
102
layout/printing/PrintTranslator.cpp
Normal file
102
layout/printing/PrintTranslator.cpp
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
/* -*- 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/. */
|
||||
|
||||
#include "PrintTranslator.h"
|
||||
|
||||
#include "gfxContext.h"
|
||||
#include "nsDeviceContext.h"
|
||||
#include "mozilla/gfx/RecordedEvent.h"
|
||||
#include "mozilla/gfx/RecordingTypes.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
namespace mozilla {
|
||||
namespace layout {
|
||||
|
||||
PrintTranslator::PrintTranslator(nsDeviceContext* aDeviceContext)
|
||||
: mDeviceContext(aDeviceContext)
|
||||
{
|
||||
RefPtr<gfxContext> context = mDeviceContext->CreateReferenceRenderingContext();
|
||||
mBaseDT = context->GetDrawTarget();
|
||||
}
|
||||
|
||||
bool
|
||||
PrintTranslator::TranslateRecording(std::istream& aRecording)
|
||||
{
|
||||
uint32_t magicInt;
|
||||
ReadElement(aRecording, magicInt);
|
||||
if (magicInt != mozilla::gfx::kMagicInt) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint16_t majorRevision;
|
||||
ReadElement(aRecording, majorRevision);
|
||||
if (majorRevision != kMajorRevision) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint16_t minorRevision;
|
||||
ReadElement(aRecording, minorRevision);
|
||||
if (minorRevision > kMinorRevision) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int32_t eventType;
|
||||
ReadElement(aRecording, eventType);
|
||||
while (aRecording.good()) {
|
||||
UniquePtr<RecordedEvent> recordedEvent(
|
||||
RecordedEvent::LoadEventFromStream(aRecording,
|
||||
static_cast<RecordedEvent::EventType>(eventType)));
|
||||
|
||||
// Make sure that the whole event was read from the stream successfully.
|
||||
if (!aRecording.good() || !recordedEvent) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!recordedEvent->PlayEvent(this)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ReadElement(aRecording, eventType);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
already_AddRefed<DrawTarget>
|
||||
PrintTranslator::CreateDrawTarget(ReferencePtr aRefPtr,
|
||||
const gfx::IntSize &aSize,
|
||||
gfx::SurfaceFormat aFormat)
|
||||
{
|
||||
RefPtr<gfxContext> context = mDeviceContext->CreateRenderingContext();
|
||||
if (!context) {
|
||||
NS_WARNING("Failed to create rendering context for print.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<DrawTarget> drawTarget = context->GetDrawTarget();
|
||||
AddDrawTarget(aRefPtr, drawTarget);
|
||||
return drawTarget.forget();
|
||||
}
|
||||
|
||||
FontType
|
||||
PrintTranslator::GetDesiredFontType()
|
||||
{
|
||||
switch (mBaseDT->GetBackendType()) {
|
||||
case BackendType::DIRECT2D:
|
||||
return FontType::DWRITE;
|
||||
case BackendType::CAIRO:
|
||||
return FontType::CAIRO;
|
||||
case BackendType::SKIA:
|
||||
return FontType::SKIA;
|
||||
default:
|
||||
return FontType::CAIRO;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace layout
|
||||
} // namespace mozilla
|
||||
178
layout/printing/PrintTranslator.h
Normal file
178
layout/printing/PrintTranslator.h
Normal file
|
|
@ -0,0 +1,178 @@
|
|||
/* -*- 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_layout_PrintTranslator_h
|
||||
#define mozilla_layout_PrintTranslator_h
|
||||
|
||||
#include <istream>
|
||||
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "mozilla/gfx/Filters.h"
|
||||
#include "mozilla/gfx/RecordedEvent.h"
|
||||
#include "nsRefPtrHashtable.h"
|
||||
|
||||
class nsDeviceContext;
|
||||
|
||||
namespace mozilla {
|
||||
namespace layout {
|
||||
|
||||
using gfx::Translator;
|
||||
using gfx::ReferencePtr;
|
||||
using gfx::DrawTarget;
|
||||
using gfx::Path;
|
||||
using gfx::SourceSurface;
|
||||
using gfx::FilterNode;
|
||||
using gfx::GradientStops;
|
||||
using gfx::ScaledFont;
|
||||
using gfx::NativeFontResource;
|
||||
|
||||
class PrintTranslator final : public Translator
|
||||
{
|
||||
public:
|
||||
explicit PrintTranslator(nsDeviceContext* aDeviceContext);
|
||||
|
||||
bool TranslateRecording(std::istream& aRecording);
|
||||
|
||||
DrawTarget* LookupDrawTarget(ReferencePtr aRefPtr) final
|
||||
{
|
||||
DrawTarget* result = mDrawTargets.GetWeak(aRefPtr);
|
||||
MOZ_ASSERT(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
Path* LookupPath(ReferencePtr aRefPtr) final
|
||||
{
|
||||
Path* result = mPaths.GetWeak(aRefPtr);
|
||||
MOZ_ASSERT(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
SourceSurface* LookupSourceSurface(ReferencePtr aRefPtr) final
|
||||
{
|
||||
SourceSurface* result = mSourceSurfaces.GetWeak(aRefPtr);
|
||||
MOZ_ASSERT(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
FilterNode* LookupFilterNode(ReferencePtr aRefPtr) final
|
||||
{
|
||||
FilterNode* result = mFilterNodes.GetWeak(aRefPtr);
|
||||
MOZ_ASSERT(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
GradientStops* LookupGradientStops(ReferencePtr aRefPtr) final
|
||||
{
|
||||
GradientStops* result = mGradientStops.GetWeak(aRefPtr);
|
||||
MOZ_ASSERT(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
ScaledFont* LookupScaledFont(ReferencePtr aRefPtr) final
|
||||
{
|
||||
ScaledFont* result = mScaledFonts.GetWeak(aRefPtr);
|
||||
MOZ_ASSERT(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
NativeFontResource* LookupNativeFontResource(uint64_t aKey) final
|
||||
{
|
||||
NativeFontResource* result = mNativeFontResources.GetWeak(aKey);
|
||||
MOZ_ASSERT(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
void AddDrawTarget(ReferencePtr aRefPtr, DrawTarget *aDT) final
|
||||
{
|
||||
mDrawTargets.Put(aRefPtr, aDT);
|
||||
}
|
||||
|
||||
void AddPath(ReferencePtr aRefPtr, Path *aPath) final
|
||||
{
|
||||
mPaths.Put(aRefPtr, aPath);
|
||||
}
|
||||
|
||||
void AddSourceSurface(ReferencePtr aRefPtr, SourceSurface *aSurface) final
|
||||
{
|
||||
mSourceSurfaces.Put(aRefPtr, aSurface);
|
||||
}
|
||||
|
||||
void AddFilterNode(ReferencePtr aRefPtr, FilterNode *aFilter) final
|
||||
{
|
||||
mFilterNodes.Put(aRefPtr, aFilter);
|
||||
}
|
||||
|
||||
void AddGradientStops(ReferencePtr aRefPtr, GradientStops *aStops) final
|
||||
{
|
||||
mGradientStops.Put(aRefPtr, aStops);
|
||||
}
|
||||
|
||||
void AddScaledFont(ReferencePtr aRefPtr, ScaledFont *aScaledFont) final
|
||||
{
|
||||
mScaledFonts.Put(aRefPtr, aScaledFont);
|
||||
}
|
||||
|
||||
void AddNativeFontResource(uint64_t aKey,
|
||||
NativeFontResource *aScaledFontResouce) final
|
||||
{
|
||||
mNativeFontResources.Put(aKey, aScaledFontResouce);
|
||||
}
|
||||
|
||||
void RemoveDrawTarget(ReferencePtr aRefPtr) final
|
||||
{
|
||||
mDrawTargets.Remove(aRefPtr);
|
||||
}
|
||||
|
||||
void RemovePath(ReferencePtr aRefPtr) final
|
||||
{
|
||||
mPaths.Remove(aRefPtr);
|
||||
}
|
||||
|
||||
void RemoveSourceSurface(ReferencePtr aRefPtr) final
|
||||
{
|
||||
mSourceSurfaces.Remove(aRefPtr);
|
||||
}
|
||||
|
||||
void RemoveFilterNode(ReferencePtr aRefPtr) final
|
||||
{
|
||||
mFilterNodes.Remove(aRefPtr);
|
||||
}
|
||||
|
||||
void RemoveGradientStops(ReferencePtr aRefPtr) final
|
||||
{
|
||||
mGradientStops.Remove(aRefPtr);
|
||||
}
|
||||
|
||||
void RemoveScaledFont(ReferencePtr aRefPtr) final
|
||||
{
|
||||
mScaledFonts.Remove(aRefPtr);
|
||||
}
|
||||
|
||||
already_AddRefed<DrawTarget> CreateDrawTarget(ReferencePtr aRefPtr,
|
||||
const gfx::IntSize &aSize,
|
||||
gfx::SurfaceFormat aFormat) final;
|
||||
|
||||
mozilla::gfx::DrawTarget* GetReferenceDrawTarget() final { return mBaseDT; }
|
||||
|
||||
mozilla::gfx::FontType GetDesiredFontType() final;
|
||||
|
||||
private:
|
||||
RefPtr<nsDeviceContext> mDeviceContext;
|
||||
RefPtr<DrawTarget> mBaseDT;
|
||||
|
||||
nsRefPtrHashtable<nsPtrHashKey<void>, DrawTarget> mDrawTargets;
|
||||
nsRefPtrHashtable<nsPtrHashKey<void>, Path> mPaths;
|
||||
nsRefPtrHashtable<nsPtrHashKey<void>, SourceSurface> mSourceSurfaces;
|
||||
nsRefPtrHashtable<nsPtrHashKey<void>, FilterNode> mFilterNodes;
|
||||
nsRefPtrHashtable<nsPtrHashKey<void>, GradientStops> mGradientStops;
|
||||
nsRefPtrHashtable<nsPtrHashKey<void>, ScaledFont> mScaledFonts;
|
||||
nsRefPtrHashtable<nsUint64HashKey, NativeFontResource> mNativeFontResources;
|
||||
};
|
||||
|
||||
} // namespace layout
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_layout_PrintTranslator_h
|
||||
10
layout/printing/crashtests/509839-1.html
Normal file
10
layout/printing/crashtests/509839-1.html
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<html class="reftest-print"><head>
|
||||
<title>Crash [@ nsViewManager::CreateView][@ nsCSSFrameConstructor::AddFrameConstructionItemsInternal] on closing print preview with -moz-transform, position: fixed table displays</title>
|
||||
</head><body>
|
||||
<div style="position: fixed;">
|
||||
<div style="display: table-header-group; -moz-transform: rotate(1deg);">
|
||||
<div style="position: relative;"></div>
|
||||
<div style="display: table-row;page-break-before: always;"></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
8
layout/printing/crashtests/509839-2.html
Normal file
8
layout/printing/crashtests/509839-2.html
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
<html style="position: fixed; -moz-transform: scale(0.000001);" class="reftest-print">
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<div style="display: table-row;"></div>
|
||||
<div style="display: table-row; page-break-before: right;"></div>
|
||||
</body>
|
||||
</html>
|
||||
9
layout/printing/crashtests/576878.xhtml
Normal file
9
layout/printing/crashtests/576878.xhtml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:mathml="http://www.w3.org/1998/Math/MathML" class="reftest-print">
|
||||
|
||||
<mathml:mfenced style="position: fixed;">
|
||||
<span style="position: inherit; float: right;"><span style="position:fixed;">b</span></span>
|
||||
</mathml:mfenced>
|
||||
<div style="page-break-before: always; "/>
|
||||
|
||||
m
|
||||
</html>
|
||||
10
layout/printing/crashtests/793844.html
Normal file
10
layout/printing/crashtests/793844.html
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<html class="reftest-print">
|
||||
<head>
|
||||
<title>crash in nsContentList::nsContentList on print preview</title>
|
||||
</head><body>
|
||||
|
||||
<iframe onload="window.location.reload()" src="data:text/html,">
|
||||
</iframe>
|
||||
|
||||
|
||||
</body></html>
|
||||
4
layout/printing/crashtests/crashtests.list
Normal file
4
layout/printing/crashtests/crashtests.list
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
load 509839-1.html
|
||||
load 509839-2.html
|
||||
asserts-if(browserIsRemote,4) load 576878.xhtml
|
||||
load 793844.html
|
||||
58
layout/printing/ipc/PRemotePrintJob.ipdl
Normal file
58
layout/printing/ipc/PRemotePrintJob.ipdl
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
/* -*- 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/. */
|
||||
|
||||
include protocol PPrinting;
|
||||
|
||||
namespace mozilla {
|
||||
namespace layout {
|
||||
|
||||
async protocol PRemotePrintJob
|
||||
{
|
||||
manager PPrinting;
|
||||
|
||||
both:
|
||||
// Tell either side to abort printing and clean up.
|
||||
async AbortPrint(nsresult aRv);
|
||||
|
||||
parent:
|
||||
// Initialize the real print device with the given information.
|
||||
async InitializePrint(nsString aDocumentTitle, nsString aPrintToFile,
|
||||
int32_t aStartPage, int32_t aEndPage);
|
||||
|
||||
// Translate the stored page recording and play back the events to the real
|
||||
// print device.
|
||||
async ProcessPage(nsCString aPageFileName);
|
||||
|
||||
// This informs the real print device that we've finished, so it can trigger
|
||||
// the actual print.
|
||||
async FinalizePrint();
|
||||
|
||||
// Report a state change to listeners in the parent process.
|
||||
async StateChange(long aStateFlags,
|
||||
nsresult aStatus);
|
||||
|
||||
// Report a progress change to listeners in the parent process.
|
||||
async ProgressChange(long aCurSelfProgress,
|
||||
long aMaxSelfProgress,
|
||||
long aCurTotalProgress,
|
||||
long aMaxTotalProgress);
|
||||
|
||||
// Report a status change to listeners in the parent process.
|
||||
async StatusChange(nsresult aStatus);
|
||||
|
||||
child:
|
||||
// Inform the child that the print has been initialized in the parent or has
|
||||
// failed with result aRv.
|
||||
async PrintInitializationResult(nsresult aRv);
|
||||
|
||||
// Inform the child that the latest page has been processed remotely.
|
||||
async PageProcessed();
|
||||
|
||||
async __delete__();
|
||||
};
|
||||
|
||||
} // namespace layout
|
||||
} // namespace mozilla
|
||||
155
layout/printing/ipc/RemotePrintJobChild.cpp
Normal file
155
layout/printing/ipc/RemotePrintJobChild.cpp
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
/* -*- 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/. */
|
||||
|
||||
#include "RemotePrintJobChild.h"
|
||||
|
||||
#include "mozilla/Unused.h"
|
||||
#include "nsPagePrintTimer.h"
|
||||
#include "nsPrintEngine.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layout {
|
||||
|
||||
NS_IMPL_ISUPPORTS(RemotePrintJobChild,
|
||||
nsIWebProgressListener)
|
||||
|
||||
RemotePrintJobChild::RemotePrintJobChild()
|
||||
{
|
||||
MOZ_COUNT_CTOR(RemotePrintJobChild);
|
||||
}
|
||||
|
||||
nsresult
|
||||
RemotePrintJobChild::InitializePrint(const nsString& aDocumentTitle,
|
||||
const nsString& aPrintToFile,
|
||||
const int32_t& aStartPage,
|
||||
const int32_t& aEndPage)
|
||||
{
|
||||
// Print initialization can sometimes display a dialog in the parent, so we
|
||||
// need to spin a nested event loop until initialization completes.
|
||||
Unused << SendInitializePrint(aDocumentTitle, aPrintToFile, aStartPage,
|
||||
aEndPage);
|
||||
while (!mPrintInitialized) {
|
||||
Unused << NS_ProcessNextEvent();
|
||||
}
|
||||
|
||||
return mInitializationResult;
|
||||
}
|
||||
|
||||
bool
|
||||
RemotePrintJobChild::RecvPrintInitializationResult(const nsresult& aRv)
|
||||
{
|
||||
mPrintInitialized = true;
|
||||
mInitializationResult = aRv;
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
RemotePrintJobChild::ProcessPage(const nsCString& aPageFileName)
|
||||
{
|
||||
MOZ_ASSERT(mPagePrintTimer);
|
||||
|
||||
mPagePrintTimer->WaitForRemotePrint();
|
||||
Unused << SendProcessPage(aPageFileName);
|
||||
}
|
||||
|
||||
bool
|
||||
RemotePrintJobChild::RecvPageProcessed()
|
||||
{
|
||||
MOZ_ASSERT(mPagePrintTimer);
|
||||
|
||||
mPagePrintTimer->RemotePrintFinished();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
RemotePrintJobChild::RecvAbortPrint(const nsresult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(mPrintEngine);
|
||||
|
||||
mPrintEngine->CleanupOnFailure(aRv, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
RemotePrintJobChild::SetPagePrintTimer(nsPagePrintTimer* aPagePrintTimer)
|
||||
{
|
||||
MOZ_ASSERT(aPagePrintTimer);
|
||||
|
||||
mPagePrintTimer = aPagePrintTimer;
|
||||
}
|
||||
|
||||
void
|
||||
RemotePrintJobChild::SetPrintEngine(nsPrintEngine* aPrintEngine)
|
||||
{
|
||||
MOZ_ASSERT(aPrintEngine);
|
||||
|
||||
mPrintEngine = aPrintEngine;
|
||||
}
|
||||
|
||||
// nsIWebProgressListener
|
||||
|
||||
NS_IMETHODIMP
|
||||
RemotePrintJobChild::OnStateChange(nsIWebProgress* aProgress,
|
||||
nsIRequest* aRequest, uint32_t aStateFlags,
|
||||
nsresult aStatus)
|
||||
{
|
||||
Unused << SendStateChange(aStateFlags, aStatus);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
RemotePrintJobChild::OnProgressChange(nsIWebProgress * aProgress,
|
||||
nsIRequest * aRequest,
|
||||
int32_t aCurSelfProgress,
|
||||
int32_t aMaxSelfProgress,
|
||||
int32_t aCurTotalProgress,
|
||||
int32_t aMaxTotalProgress)
|
||||
{
|
||||
Unused << SendProgressChange(aCurSelfProgress, aMaxSelfProgress,
|
||||
aCurTotalProgress, aMaxTotalProgress);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
RemotePrintJobChild::OnLocationChange(nsIWebProgress* aProgress,
|
||||
nsIRequest* aRequest, nsIURI* aURI,
|
||||
uint32_t aFlags)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
RemotePrintJobChild::OnStatusChange(nsIWebProgress* aProgress,
|
||||
nsIRequest* aRequest, nsresult aStatus,
|
||||
const char16_t* aMessage)
|
||||
{
|
||||
Unused << SendStatusChange(aStatus);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
RemotePrintJobChild::OnSecurityChange(nsIWebProgress* aProgress,
|
||||
nsIRequest* aRequest, uint32_t aState)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// End of nsIWebProgressListener
|
||||
|
||||
RemotePrintJobChild::~RemotePrintJobChild()
|
||||
{
|
||||
MOZ_COUNT_DTOR(RemotePrintJobChild);
|
||||
}
|
||||
|
||||
void
|
||||
RemotePrintJobChild::ActorDestroy(ActorDestroyReason aWhy)
|
||||
{
|
||||
mPagePrintTimer = nullptr;
|
||||
mPrintEngine = nullptr;
|
||||
}
|
||||
|
||||
} // namespace layout
|
||||
} // namespace mozilla
|
||||
61
layout/printing/ipc/RemotePrintJobChild.h
Normal file
61
layout/printing/ipc/RemotePrintJobChild.h
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
/* -*- 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_layout_RemotePrintJobChild_h
|
||||
#define mozilla_layout_RemotePrintJobChild_h
|
||||
|
||||
#include "mozilla/layout/PRemotePrintJobChild.h"
|
||||
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "nsIWebProgressListener.h"
|
||||
|
||||
class nsPagePrintTimer;
|
||||
class nsPrintEngine;
|
||||
|
||||
namespace mozilla {
|
||||
namespace layout {
|
||||
|
||||
class RemotePrintJobChild final : public PRemotePrintJobChild
|
||||
, public nsIWebProgressListener
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIWEBPROGRESSLISTENER
|
||||
|
||||
RemotePrintJobChild();
|
||||
|
||||
void ActorDestroy(ActorDestroyReason aWhy) final;
|
||||
|
||||
nsresult InitializePrint(const nsString& aDocumentTitle,
|
||||
const nsString& aPrintToFile,
|
||||
const int32_t& aStartPage,
|
||||
const int32_t& aEndPage);
|
||||
|
||||
bool RecvPrintInitializationResult(const nsresult& aRv) final;
|
||||
|
||||
void ProcessPage(const nsCString& aPageFileName);
|
||||
|
||||
bool RecvPageProcessed() final;
|
||||
|
||||
bool RecvAbortPrint(const nsresult& aRv) final;
|
||||
|
||||
void SetPagePrintTimer(nsPagePrintTimer* aPagePrintTimer);
|
||||
|
||||
void SetPrintEngine(nsPrintEngine* aPrintEngine);
|
||||
|
||||
private:
|
||||
~RemotePrintJobChild() final;
|
||||
|
||||
bool mPrintInitialized = false;
|
||||
nsresult mInitializationResult = NS_OK;
|
||||
RefPtr<nsPagePrintTimer> mPagePrintTimer;
|
||||
RefPtr<nsPrintEngine> mPrintEngine;
|
||||
};
|
||||
|
||||
} // namespace layout
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_layout_RemotePrintJobChild_h
|
||||
244
layout/printing/ipc/RemotePrintJobParent.cpp
Normal file
244
layout/printing/ipc/RemotePrintJobParent.cpp
Normal file
|
|
@ -0,0 +1,244 @@
|
|||
/* -*- 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/. */
|
||||
|
||||
#include "RemotePrintJobParent.h"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include "gfxContext.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/Unused.h"
|
||||
#include "nsAppDirectoryServiceDefs.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsDirectoryServiceUtils.h"
|
||||
#include "nsDeviceContext.h"
|
||||
#include "nsIDeviceContextSpec.h"
|
||||
#include "nsIPrintSettings.h"
|
||||
#include "nsIWebProgressListener.h"
|
||||
#include "PrintTranslator.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layout {
|
||||
|
||||
RemotePrintJobParent::RemotePrintJobParent(nsIPrintSettings* aPrintSettings)
|
||||
: mPrintSettings(aPrintSettings)
|
||||
{
|
||||
MOZ_COUNT_CTOR(RemotePrintJobParent);
|
||||
}
|
||||
|
||||
bool
|
||||
RemotePrintJobParent::RecvInitializePrint(const nsString& aDocumentTitle,
|
||||
const nsString& aPrintToFile,
|
||||
const int32_t& aStartPage,
|
||||
const int32_t& aEndPage)
|
||||
{
|
||||
nsresult rv = InitializePrintDevice(aDocumentTitle, aPrintToFile, aStartPage,
|
||||
aEndPage);
|
||||
if (NS_FAILED(rv)) {
|
||||
Unused << SendPrintInitializationResult(rv);
|
||||
Unused << Send__delete__(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
mPrintTranslator.reset(new PrintTranslator(mPrintDeviceContext));
|
||||
Unused << SendPrintInitializationResult(NS_OK);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
nsresult
|
||||
RemotePrintJobParent::InitializePrintDevice(const nsString& aDocumentTitle,
|
||||
const nsString& aPrintToFile,
|
||||
const int32_t& aStartPage,
|
||||
const int32_t& aEndPage)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIDeviceContextSpec> deviceContextSpec =
|
||||
do_CreateInstance("@mozilla.org/gfx/devicecontextspec;1", &rv);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = deviceContextSpec->Init(nullptr, mPrintSettings, false);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
mPrintDeviceContext = new nsDeviceContext();
|
||||
rv = mPrintDeviceContext->InitForPrinting(deviceContextSpec);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = mPrintDeviceContext->BeginDocument(aDocumentTitle, aPrintToFile,
|
||||
aStartPage, aEndPage);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
RemotePrintJobParent::RecvProcessPage(const nsCString& aPageFileName)
|
||||
{
|
||||
nsresult rv = PrintPage(aPageFileName);
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
Unused << SendAbortPrint(rv);
|
||||
} else {
|
||||
Unused << SendPageProcessed();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
nsresult
|
||||
RemotePrintJobParent::PrintPage(const nsCString& aPageFileName)
|
||||
{
|
||||
MOZ_ASSERT(mPrintDeviceContext);
|
||||
|
||||
nsresult rv = mPrintDeviceContext->BeginPage();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIFile> recordingFile;
|
||||
rv = NS_GetSpecialDirectory(NS_APP_CONTENT_PROCESS_TEMP_DIR,
|
||||
getter_AddRefs(recordingFile));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = recordingFile->AppendNative(aPageFileName);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsAutoCString recordingPath;
|
||||
rv = recordingFile->GetNativePath(recordingPath);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
std::ifstream recording(recordingPath.get(), std::ifstream::binary);
|
||||
if (!mPrintTranslator->TranslateRecording(recording)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
rv = mPrintDeviceContext->EndPage();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
recording.close();
|
||||
rv = recordingFile->Remove(/* recursive= */ false);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
RemotePrintJobParent::RecvFinalizePrint()
|
||||
{
|
||||
// EndDocument is sometimes called in the child even when BeginDocument has
|
||||
// not been called. See bug 1223332.
|
||||
if (mPrintDeviceContext) {
|
||||
DebugOnly<nsresult> rv = mPrintDeviceContext->EndDocument();
|
||||
|
||||
// Too late to abort the child just log.
|
||||
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "EndDocument failed");
|
||||
}
|
||||
|
||||
|
||||
Unused << Send__delete__(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
RemotePrintJobParent::RecvAbortPrint(const nsresult& aRv)
|
||||
{
|
||||
if (mPrintDeviceContext) {
|
||||
Unused << mPrintDeviceContext->AbortDocument();
|
||||
}
|
||||
|
||||
Unused << Send__delete__(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
RemotePrintJobParent::RecvStateChange(const long& aStateFlags,
|
||||
const nsresult& aStatus)
|
||||
{
|
||||
uint32_t numberOfListeners = mPrintProgressListeners.Length();
|
||||
for (uint32_t i = 0; i < numberOfListeners; ++i) {
|
||||
nsIWebProgressListener* listener = mPrintProgressListeners.SafeElementAt(i);
|
||||
listener->OnStateChange(nullptr, nullptr, aStateFlags, aStatus);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
RemotePrintJobParent::RecvProgressChange(const long& aCurSelfProgress,
|
||||
const long& aMaxSelfProgress,
|
||||
const long& aCurTotalProgress,
|
||||
const long& aMaxTotalProgress)
|
||||
{
|
||||
uint32_t numberOfListeners = mPrintProgressListeners.Length();
|
||||
for (uint32_t i = 0; i < numberOfListeners; ++i) {
|
||||
nsIWebProgressListener* listener = mPrintProgressListeners.SafeElementAt(i);
|
||||
listener->OnProgressChange(nullptr, nullptr,
|
||||
aCurSelfProgress, aMaxSelfProgress,
|
||||
aCurTotalProgress, aMaxTotalProgress);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
RemotePrintJobParent::RecvStatusChange(const nsresult& aStatus)
|
||||
{
|
||||
uint32_t numberOfListeners = mPrintProgressListeners.Length();
|
||||
for (uint32_t i = 0; i < numberOfListeners; ++i) {
|
||||
nsIWebProgressListener* listener = mPrintProgressListeners.SafeElementAt(i);
|
||||
listener->OnStatusChange(nullptr, nullptr, aStatus, nullptr);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
RemotePrintJobParent::RegisterListener(nsIWebProgressListener* aListener)
|
||||
{
|
||||
MOZ_ASSERT(aListener);
|
||||
|
||||
mPrintProgressListeners.AppendElement(aListener);
|
||||
}
|
||||
|
||||
already_AddRefed<nsIPrintSettings>
|
||||
RemotePrintJobParent::GetPrintSettings()
|
||||
{
|
||||
nsCOMPtr<nsIPrintSettings> printSettings = mPrintSettings;
|
||||
return printSettings.forget();
|
||||
}
|
||||
|
||||
RemotePrintJobParent::~RemotePrintJobParent()
|
||||
{
|
||||
MOZ_COUNT_DTOR(RemotePrintJobParent);
|
||||
}
|
||||
|
||||
void
|
||||
RemotePrintJobParent::ActorDestroy(ActorDestroyReason aWhy)
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace layout
|
||||
} // namespace mozilla
|
||||
|
||||
|
||||
84
layout/printing/ipc/RemotePrintJobParent.h
Normal file
84
layout/printing/ipc/RemotePrintJobParent.h
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
/* -*- 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_layout_RemotePrintJobParent_h
|
||||
#define mozilla_layout_RemotePrintJobParent_h
|
||||
|
||||
#include "mozilla/layout/PRemotePrintJobParent.h"
|
||||
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
|
||||
class nsDeviceContext;
|
||||
class nsIPrintSettings;
|
||||
class nsIWebProgressListener;
|
||||
class PrintTranslator;
|
||||
|
||||
namespace mozilla {
|
||||
namespace layout {
|
||||
|
||||
class RemotePrintJobParent final : public PRemotePrintJobParent
|
||||
{
|
||||
public:
|
||||
explicit RemotePrintJobParent(nsIPrintSettings* aPrintSettings);
|
||||
|
||||
void ActorDestroy(ActorDestroyReason aWhy) final;
|
||||
|
||||
bool RecvInitializePrint(const nsString& aDocumentTitle,
|
||||
const nsString& aPrintToFile,
|
||||
const int32_t& aStartPage,
|
||||
const int32_t& aEndPage) final;
|
||||
|
||||
bool RecvProcessPage(const nsCString& aPageFileName) final;
|
||||
|
||||
bool RecvFinalizePrint() final;
|
||||
|
||||
bool RecvAbortPrint(const nsresult& aRv) final;
|
||||
|
||||
bool RecvStateChange(const long& aStateFlags,
|
||||
const nsresult& aStatus) final;
|
||||
|
||||
bool RecvProgressChange(const long& aCurSelfProgress,
|
||||
const long& aMaxSelfProgress,
|
||||
const long& aCurTotalProgress,
|
||||
const long& aMaxTotalProgress) final;
|
||||
|
||||
bool RecvStatusChange(const nsresult& aStatus) final;
|
||||
|
||||
/**
|
||||
* Register a progress listener to receive print progress updates.
|
||||
*
|
||||
* @param aListener the progress listener to register. Must not be null.
|
||||
*/
|
||||
void RegisterListener(nsIWebProgressListener* aListener);
|
||||
|
||||
/**
|
||||
* @return the print settings for this remote print job.
|
||||
*/
|
||||
already_AddRefed<nsIPrintSettings> GetPrintSettings();
|
||||
|
||||
private:
|
||||
~RemotePrintJobParent() final;
|
||||
|
||||
nsresult InitializePrintDevice(const nsString& aDocumentTitle,
|
||||
const nsString& aPrintToFile,
|
||||
const int32_t& aStartPage,
|
||||
const int32_t& aEndPage);
|
||||
|
||||
nsresult PrintPage(const nsCString& aPageFileName);
|
||||
|
||||
nsCOMPtr<nsIPrintSettings> mPrintSettings;
|
||||
RefPtr<nsDeviceContext> mPrintDeviceContext;
|
||||
UniquePtr<PrintTranslator> mPrintTranslator;
|
||||
nsCOMArray<nsIWebProgressListener> mPrintProgressListeners;
|
||||
};
|
||||
|
||||
} // namespace layout
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_layout_RemotePrintJobParent_h
|
||||
37
layout/printing/moz.build
Normal file
37
layout/printing/moz.build
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# 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/.
|
||||
|
||||
XPIDL_SOURCES += [
|
||||
'nsIPrintProgress.idl',
|
||||
'nsIPrintProgressParams.idl',
|
||||
'nsIPrintStatusFeedback.idl',
|
||||
]
|
||||
|
||||
EXPORTS.mozilla.layout += [
|
||||
'ipc/RemotePrintJobChild.h',
|
||||
'ipc/RemotePrintJobParent.h',
|
||||
]
|
||||
|
||||
XPIDL_MODULE = 'layout_printing'
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'ipc/RemotePrintJobChild.cpp',
|
||||
'ipc/RemotePrintJobParent.cpp',
|
||||
'nsPagePrintTimer.cpp',
|
||||
'nsPrintData.cpp',
|
||||
'nsPrintEngine.cpp',
|
||||
'nsPrintObject.cpp',
|
||||
'nsPrintPreviewListener.cpp',
|
||||
'PrintTranslator.cpp',
|
||||
]
|
||||
|
||||
include('/ipc/chromium/chromium-config.mozbuild')
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
LOCAL_INCLUDES += [
|
||||
'../base',
|
||||
'/dom/base',
|
||||
]
|
||||
43
layout/printing/nsIPrintProgress.idl
Normal file
43
layout/printing/nsIPrintProgress.idl
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
/* -*- 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 "nsIWebProgressListener.idl"
|
||||
|
||||
interface mozIDOMWindowProxy;
|
||||
interface nsIObserver;
|
||||
interface nsIPrompt;
|
||||
|
||||
[scriptable, uuid(05f4fb88-e568-4d35-b394-ce0aa3eea6fc)]
|
||||
interface nsIPrintProgress: nsIWebProgressListener {
|
||||
|
||||
/* Open the progress dialog
|
||||
you can specify parameters through an xpcom object
|
||||
*/
|
||||
void openProgressDialog(in mozIDOMWindowProxy parent,
|
||||
in string dialogURL,
|
||||
in nsISupports parameters,
|
||||
in nsIObserver openDialogObserver,
|
||||
out boolean notifyOnOpen);
|
||||
|
||||
/* Close the progress dialog */
|
||||
void closeProgressDialog(in boolean forceClose);
|
||||
|
||||
/* Register a Web Progress Listener */
|
||||
void registerListener(in nsIWebProgressListener listener);
|
||||
|
||||
/* Unregister a Web Progress Listener */
|
||||
void unregisterListener(in nsIWebProgressListener listener);
|
||||
|
||||
/* This method is called after the dialog that shows the progress has been shown
|
||||
*/
|
||||
void doneIniting();
|
||||
|
||||
/* Retrieve the prompter, needed to display modal dialog on top of progress dialog */
|
||||
nsIPrompt getPrompter();
|
||||
|
||||
/* Indicated if the user asked to cancel the current process */
|
||||
attribute boolean processCanceledByUser;
|
||||
};
|
||||
|
||||
|
||||
14
layout/printing/nsIPrintProgressParams.idl
Normal file
14
layout/printing/nsIPrintProgressParams.idl
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
/* -*- 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 "nsISupports.idl"
|
||||
|
||||
[scriptable, uuid(CA89B55B-6FAF-4051-9645-1C03EF5108F8)]
|
||||
interface nsIPrintProgressParams: nsISupports {
|
||||
|
||||
/* message subject */
|
||||
attribute wstring docTitle;
|
||||
attribute wstring docURL;
|
||||
|
||||
};
|
||||
23
layout/printing/nsIPrintStatusFeedback.idl
Normal file
23
layout/printing/nsIPrintStatusFeedback.idl
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/* -*- Mode: C++; tab-width: 2; 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 "nsISupports.idl"
|
||||
|
||||
interface nsIDocShell;
|
||||
interface mozIDOMWindowProxy;
|
||||
|
||||
/**
|
||||
* XXX This interface seems to be unimplemented and unused.
|
||||
*/
|
||||
[scriptable, uuid(8eb6ffc9-715c-487e-927c-c56139229548)]
|
||||
interface nsIPrintStatusFeedback : nsISupports {
|
||||
void showStatusString(in wstring status);
|
||||
void startMeteors();
|
||||
void stopMeteors();
|
||||
void showProgress(in long percent);
|
||||
[noscript] void setDocShell(in nsIDocShell shell, in mozIDOMWindowProxy window);
|
||||
void closeWindow();
|
||||
};
|
||||
|
||||
224
layout/printing/nsPagePrintTimer.cpp
Normal file
224
layout/printing/nsPagePrintTimer.cpp
Normal file
|
|
@ -0,0 +1,224 @@
|
|||
/* -*- Mode: C++; tab-width: 2; 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 "nsPagePrintTimer.h"
|
||||
|
||||
#include "mozilla/Unused.h"
|
||||
#include "nsIContentViewer.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsPrintEngine.h"
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED(nsPagePrintTimer, mozilla::Runnable, nsITimerCallback)
|
||||
|
||||
nsPagePrintTimer::~nsPagePrintTimer()
|
||||
{
|
||||
// "Destroy" the document viewer; this normally doesn't actually
|
||||
// destroy it because of the IncrementDestroyRefCount call below
|
||||
// XXX This is messy; the document viewer should use a single approach
|
||||
// to keep itself alive during printing
|
||||
nsCOMPtr<nsIContentViewer> cv(do_QueryInterface(mDocViewerPrint));
|
||||
if (cv) {
|
||||
cv->Destroy();
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsPagePrintTimer::StartTimer(bool aUseDelay)
|
||||
{
|
||||
nsresult result;
|
||||
mTimer = do_CreateInstance("@mozilla.org/timer;1", &result);
|
||||
if (NS_FAILED(result)) {
|
||||
NS_WARNING("unable to start the timer");
|
||||
} else {
|
||||
uint32_t delay = 0;
|
||||
if (aUseDelay) {
|
||||
if (mFiringCount < 10) {
|
||||
// Longer delay for the few first pages.
|
||||
delay = mDelay + ((10 - mFiringCount) * 100);
|
||||
} else {
|
||||
delay = mDelay;
|
||||
}
|
||||
}
|
||||
mTimer->InitWithCallback(this, delay, nsITimer::TYPE_ONE_SHOT);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsPagePrintTimer::StartWatchDogTimer()
|
||||
{
|
||||
nsresult result;
|
||||
if (mWatchDogTimer) {
|
||||
mWatchDogTimer->Cancel();
|
||||
}
|
||||
mWatchDogTimer = do_CreateInstance("@mozilla.org/timer;1", &result);
|
||||
if (NS_FAILED(result)) {
|
||||
NS_WARNING("unable to start the timer");
|
||||
} else {
|
||||
// Instead of just doing one timer for a long period do multiple so we
|
||||
// can check if the user cancelled the printing.
|
||||
mWatchDogTimer->InitWithCallback(this, WATCH_DOG_INTERVAL,
|
||||
nsITimer::TYPE_ONE_SHOT);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
nsPagePrintTimer::StopWatchDogTimer()
|
||||
{
|
||||
if (mWatchDogTimer) {
|
||||
mWatchDogTimer->Cancel();
|
||||
mWatchDogTimer = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
//nsRunnable
|
||||
NS_IMETHODIMP
|
||||
nsPagePrintTimer::Run()
|
||||
{
|
||||
bool initNewTimer = true;
|
||||
// Check to see if we are done
|
||||
// inRange will be true if a page is actually printed
|
||||
bool inRange;
|
||||
bool donePrinting;
|
||||
|
||||
// donePrinting will be true if it completed successfully or
|
||||
// if the printing was cancelled
|
||||
donePrinting = !mPrintEngine || mPrintEngine->PrintPage(mPrintObj, inRange);
|
||||
if (donePrinting) {
|
||||
// now clean up print or print the next webshell
|
||||
if (!mPrintEngine || mPrintEngine->DonePrintingPages(mPrintObj, NS_OK)) {
|
||||
initNewTimer = false;
|
||||
mDone = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Note that the Stop() destroys this after the print job finishes
|
||||
// (The PrintEngine stops holding a reference when DonePrintingPages
|
||||
// returns true.)
|
||||
Stop();
|
||||
if (initNewTimer) {
|
||||
++mFiringCount;
|
||||
nsresult result = StartTimer(inRange);
|
||||
if (NS_FAILED(result)) {
|
||||
mDone = true; // had a failure.. we are finished..
|
||||
if (mPrintEngine) {
|
||||
mPrintEngine->SetIsPrinting(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsITimerCallback
|
||||
NS_IMETHODIMP
|
||||
nsPagePrintTimer::Notify(nsITimer *timer)
|
||||
{
|
||||
// When finished there may be still pending notifications, which we can just
|
||||
// ignore.
|
||||
if (mDone) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// There are four things that call Notify with different values for timer:
|
||||
// 1) the delay between pages (timer == mTimer)
|
||||
// 2) canvasPrintState done (timer == null)
|
||||
// 3) the watch dog timer (timer == mWatchDogTimer)
|
||||
// 4) the waiting for remote print "timer" (timer == mWaitingForRemotePrint)
|
||||
if (!timer) {
|
||||
// Reset the counter since a mozPrintCallback has finished.
|
||||
mWatchDogCount = 0;
|
||||
} else if (timer == mTimer) {
|
||||
// Reset the watchdog timer before the start of every page.
|
||||
mWatchDogCount = 0;
|
||||
mTimer = nullptr;
|
||||
} else if (timer == mWaitingForRemotePrint) {
|
||||
mWaitingForRemotePrint = nullptr;
|
||||
|
||||
// If we are still waiting for the page delay timer, don't let the
|
||||
// notification from the remote print job trigger the next page.
|
||||
if (mTimer) {
|
||||
return NS_OK;
|
||||
}
|
||||
} else if (timer == mWatchDogTimer) {
|
||||
mWatchDogCount++;
|
||||
if (mWatchDogCount > WATCH_DOG_MAX_COUNT) {
|
||||
Fail();
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
if (mDocViewerPrint) {
|
||||
bool donePrePrint = true;
|
||||
if (mPrintEngine) {
|
||||
donePrePrint = mPrintEngine->PrePrintPage();
|
||||
}
|
||||
|
||||
if (donePrePrint && !mWaitingForRemotePrint) {
|
||||
StopWatchDogTimer();
|
||||
NS_DispatchToMainThread(this);
|
||||
} else {
|
||||
// Start the watch dog if we're waiting for preprint to ensure that if any
|
||||
// mozPrintCallbacks take to long we error out.
|
||||
StartWatchDogTimer();
|
||||
}
|
||||
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
nsPagePrintTimer::WaitForRemotePrint()
|
||||
{
|
||||
nsresult result;
|
||||
mWaitingForRemotePrint = do_CreateInstance("@mozilla.org/timer;1", &result);
|
||||
if (NS_FAILED(result)) {
|
||||
NS_WARNING("Failed to wait for remote print, we might time-out.");
|
||||
mWaitingForRemotePrint = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsPagePrintTimer::RemotePrintFinished()
|
||||
{
|
||||
if (!mWaitingForRemotePrint) {
|
||||
return;
|
||||
}
|
||||
|
||||
mozilla::Unused <<
|
||||
mWaitingForRemotePrint->InitWithCallback(this, 0, nsITimer::TYPE_ONE_SHOT);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsPagePrintTimer::Start(nsPrintObject* aPO)
|
||||
{
|
||||
mPrintObj = aPO;
|
||||
mDone = false;
|
||||
return StartTimer(false);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
nsPagePrintTimer::Stop()
|
||||
{
|
||||
if (mTimer) {
|
||||
mTimer->Cancel();
|
||||
mTimer = nullptr;
|
||||
}
|
||||
StopWatchDogTimer();
|
||||
}
|
||||
|
||||
void
|
||||
nsPagePrintTimer::Fail()
|
||||
{
|
||||
NS_WARNING("nsPagePrintTimer::Fail called");
|
||||
|
||||
mDone = true;
|
||||
Stop();
|
||||
if (mPrintEngine) {
|
||||
mPrintEngine->CleanupOnFailure(NS_OK, false);
|
||||
}
|
||||
}
|
||||
93
layout/printing/nsPagePrintTimer.h
Normal file
93
layout/printing/nsPagePrintTimer.h
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
/* -*- Mode: C++; tab-width: 2; 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/. */
|
||||
#ifndef nsPagePrintTimer_h___
|
||||
#define nsPagePrintTimer_h___
|
||||
|
||||
// Timer Includes
|
||||
#include "nsITimer.h"
|
||||
|
||||
#include "nsIDocumentViewerPrint.h"
|
||||
#include "nsPrintObject.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
class nsPrintEngine;
|
||||
|
||||
//---------------------------------------------------
|
||||
//-- Page Timer Class
|
||||
//---------------------------------------------------
|
||||
class nsPagePrintTimer final : public mozilla::Runnable,
|
||||
public nsITimerCallback
|
||||
{
|
||||
public:
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
nsPagePrintTimer(nsPrintEngine* aPrintEngine,
|
||||
nsIDocumentViewerPrint* aDocViewerPrint,
|
||||
uint32_t aDelay)
|
||||
: mPrintEngine(aPrintEngine)
|
||||
, mDocViewerPrint(aDocViewerPrint)
|
||||
, mDelay(aDelay)
|
||||
, mFiringCount(0)
|
||||
, mPrintObj(nullptr)
|
||||
, mWatchDogCount(0)
|
||||
, mDone(false)
|
||||
{
|
||||
mDocViewerPrint->IncrementDestroyRefCount();
|
||||
}
|
||||
|
||||
NS_DECL_NSITIMERCALLBACK
|
||||
|
||||
nsresult Start(nsPrintObject* aPO);
|
||||
|
||||
NS_IMETHOD Run() override;
|
||||
|
||||
void Stop();
|
||||
|
||||
void WaitForRemotePrint();
|
||||
void RemotePrintFinished();
|
||||
|
||||
void Disconnect()
|
||||
{
|
||||
mPrintEngine = nullptr;
|
||||
mPrintObj = nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
~nsPagePrintTimer();
|
||||
|
||||
nsresult StartTimer(bool aUseDelay);
|
||||
nsresult StartWatchDogTimer();
|
||||
void StopWatchDogTimer();
|
||||
void Fail();
|
||||
|
||||
nsPrintEngine* mPrintEngine;
|
||||
nsCOMPtr<nsIDocumentViewerPrint> mDocViewerPrint;
|
||||
nsCOMPtr<nsITimer> mTimer;
|
||||
nsCOMPtr<nsITimer> mWatchDogTimer;
|
||||
nsCOMPtr<nsITimer> mWaitingForRemotePrint;
|
||||
uint32_t mDelay;
|
||||
uint32_t mFiringCount;
|
||||
nsPrintObject * mPrintObj;
|
||||
uint32_t mWatchDogCount;
|
||||
bool mDone;
|
||||
|
||||
static const uint32_t WATCH_DOG_INTERVAL = 1000;
|
||||
static const uint32_t WATCH_DOG_MAX_COUNT =
|
||||
#ifdef DEBUG
|
||||
// Debug builds are very slow (on Mac at least) and can need extra time
|
||||
30
|
||||
#else
|
||||
10
|
||||
#endif
|
||||
;
|
||||
};
|
||||
|
||||
|
||||
nsresult
|
||||
NS_NewPagePrintTimer(nsPagePrintTimer **aResult);
|
||||
|
||||
#endif /* nsPagePrintTimer_h___ */
|
||||
140
layout/printing/nsPrintData.cpp
Normal file
140
layout/printing/nsPrintData.cpp
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
/* -*- Mode: C++; tab-width: 2; 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 "nsPrintData.h"
|
||||
|
||||
#include "nsIStringBundle.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsPrintObject.h"
|
||||
#include "nsPrintPreviewListener.h"
|
||||
#include "nsIWebProgressListener.h"
|
||||
#include "mozilla/Services.h"
|
||||
|
||||
//-----------------------------------------------------
|
||||
// PR LOGGING
|
||||
#include "mozilla/Logging.h"
|
||||
|
||||
#define DUMP_LAYOUT_LEVEL 9 // this turns on the dumping of each doucment's layout info
|
||||
static mozilla::LazyLogModule gPrintingLog("printing");
|
||||
|
||||
#define PR_PL(_p1) MOZ_LOG(gPrintingLog, mozilla::LogLevel::Debug, _p1);
|
||||
|
||||
//---------------------------------------------------
|
||||
//-- nsPrintData Class Impl
|
||||
//---------------------------------------------------
|
||||
nsPrintData::nsPrintData(ePrintDataType aType) :
|
||||
mType(aType), mDebugFilePtr(nullptr), mPrintObject(nullptr), mSelectedPO(nullptr),
|
||||
mPrintDocList(0), mIsIFrameSelected(false),
|
||||
mIsParentAFrameSet(false), mOnStartSent(false),
|
||||
mIsAborted(false), mPreparingForPrint(false), mDocWasToBeDestroyed(false),
|
||||
mShrinkToFit(false), mPrintFrameType(nsIPrintSettings::kFramesAsIs),
|
||||
mNumPrintablePages(0), mNumPagesPrinted(0),
|
||||
mShrinkRatio(1.0), mOrigDCScale(1.0), mPPEventListeners(nullptr),
|
||||
mBrandName(nullptr)
|
||||
{
|
||||
nsCOMPtr<nsIStringBundle> brandBundle;
|
||||
nsCOMPtr<nsIStringBundleService> svc =
|
||||
mozilla::services::GetStringBundleService();
|
||||
if (svc) {
|
||||
svc->CreateBundle( "chrome://branding/locale/brand.properties", getter_AddRefs( brandBundle ) );
|
||||
if (brandBundle) {
|
||||
brandBundle->GetStringFromName(u"brandShortName", &mBrandName );
|
||||
}
|
||||
}
|
||||
|
||||
if (!mBrandName) {
|
||||
mBrandName = ToNewUnicode(NS_LITERAL_STRING("Mozilla Document"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
nsPrintData::~nsPrintData()
|
||||
{
|
||||
// remove the event listeners
|
||||
if (mPPEventListeners) {
|
||||
mPPEventListeners->RemoveListeners();
|
||||
NS_RELEASE(mPPEventListeners);
|
||||
}
|
||||
|
||||
// Only Send an OnEndPrinting if we have started printing
|
||||
if (mOnStartSent && mType != eIsPrintPreview) {
|
||||
OnEndPrinting();
|
||||
}
|
||||
|
||||
if (mPrintDC && !mDebugFilePtr) {
|
||||
PR_PL(("****************** End Document ************************\n"));
|
||||
PR_PL(("\n"));
|
||||
bool isCancelled = false;
|
||||
mPrintSettings->GetIsCancelled(&isCancelled);
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
if (mType == eIsPrinting) {
|
||||
if (!isCancelled && !mIsAborted) {
|
||||
rv = mPrintDC->EndDocument();
|
||||
} else {
|
||||
rv = mPrintDC->AbortDocument();
|
||||
}
|
||||
if (NS_FAILED(rv)) {
|
||||
// XXX nsPrintData::ShowPrintErrorDialog(rv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete mPrintObject;
|
||||
|
||||
if (mBrandName) {
|
||||
free(mBrandName);
|
||||
}
|
||||
}
|
||||
|
||||
void nsPrintData::OnStartPrinting()
|
||||
{
|
||||
if (!mOnStartSent) {
|
||||
DoOnProgressChange(0, 0, true, nsIWebProgressListener::STATE_START|nsIWebProgressListener::STATE_IS_DOCUMENT|nsIWebProgressListener::STATE_IS_NETWORK);
|
||||
mOnStartSent = true;
|
||||
}
|
||||
}
|
||||
|
||||
void nsPrintData::OnEndPrinting()
|
||||
{
|
||||
DoOnProgressChange(100, 100, true, nsIWebProgressListener::STATE_STOP|nsIWebProgressListener::STATE_IS_DOCUMENT);
|
||||
DoOnProgressChange(100, 100, true, nsIWebProgressListener::STATE_STOP|nsIWebProgressListener::STATE_IS_NETWORK);
|
||||
}
|
||||
|
||||
void
|
||||
nsPrintData::DoOnProgressChange(int32_t aProgress,
|
||||
int32_t aMaxProgress,
|
||||
bool aDoStartStop,
|
||||
int32_t aFlag)
|
||||
{
|
||||
size_t numberOfListeners = mPrintProgressListeners.Length();
|
||||
for (size_t i = 0; i < numberOfListeners; ++i) {
|
||||
nsCOMPtr<nsIWebProgressListener> listener =
|
||||
mPrintProgressListeners.SafeElementAt(i);
|
||||
if (NS_WARN_IF(!listener)) {
|
||||
continue;
|
||||
}
|
||||
listener->OnProgressChange(nullptr, nullptr, aProgress, aMaxProgress,
|
||||
aProgress, aMaxProgress);
|
||||
if (aDoStartStop) {
|
||||
listener->OnStateChange(nullptr, nullptr, aFlag, NS_OK);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsPrintData::DoOnStatusChange(nsresult aStatus)
|
||||
{
|
||||
size_t numberOfListeners = mPrintProgressListeners.Length();
|
||||
for (size_t i = 0; i < numberOfListeners; ++i) {
|
||||
nsCOMPtr<nsIWebProgressListener> listener =
|
||||
mPrintProgressListeners.SafeElementAt(i);
|
||||
if (NS_WARN_IF(!listener)) {
|
||||
continue;
|
||||
}
|
||||
listener->OnStatusChange(nullptr, nullptr, aStatus, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
96
layout/printing/nsPrintData.h
Normal file
96
layout/printing/nsPrintData.h
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
/* -*- Mode: C++; tab-width: 2; 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/. */
|
||||
|
||||
#ifndef nsPrintData_h___
|
||||
#define nsPrintData_h___
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
|
||||
// Interfaces
|
||||
#include "nsDeviceContext.h"
|
||||
#include "nsIPrintProgressParams.h"
|
||||
#include "nsIPrintSettings.h"
|
||||
#include "nsISupportsImpl.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsCOMArray.h"
|
||||
|
||||
// Classes
|
||||
class nsPrintObject;
|
||||
class nsPrintPreviewListener;
|
||||
class nsIWebProgressListener;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// nsPrintData Class
|
||||
//
|
||||
// mPreparingForPrint - indicates that we have started Printing but
|
||||
// have not gone to the timer to start printing the pages. It gets turned
|
||||
// off right before we go to the timer.
|
||||
//
|
||||
// mDocWasToBeDestroyed - Gets set when "someone" tries to unload the document
|
||||
// while we were prparing to Print. This typically happens if a user starts
|
||||
// to print while a page is still loading. If they start printing and pause
|
||||
// at the print dialog and then the page comes in, we then abort printing
|
||||
// because the document is no longer stable.
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
class nsPrintData {
|
||||
public:
|
||||
typedef enum {eIsPrinting, eIsPrintPreview } ePrintDataType;
|
||||
|
||||
explicit nsPrintData(ePrintDataType aType);
|
||||
|
||||
NS_INLINE_DECL_REFCOUNTING(nsPrintData)
|
||||
|
||||
// Listener Helper Methods
|
||||
void OnEndPrinting();
|
||||
void OnStartPrinting();
|
||||
void DoOnProgressChange(int32_t aProgress,
|
||||
int32_t aMaxProgress,
|
||||
bool aDoStartStop,
|
||||
int32_t aFlag);
|
||||
|
||||
void DoOnStatusChange(nsresult aStatus);
|
||||
|
||||
|
||||
ePrintDataType mType; // the type of data this is (Printing or Print Preview)
|
||||
RefPtr<nsDeviceContext> mPrintDC;
|
||||
FILE *mDebugFilePtr; // a file where information can go to when printing
|
||||
|
||||
nsPrintObject * mPrintObject;
|
||||
nsPrintObject * mSelectedPO;
|
||||
|
||||
nsCOMArray<nsIWebProgressListener> mPrintProgressListeners;
|
||||
nsCOMPtr<nsIPrintProgressParams> mPrintProgressParams;
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowOuter> mCurrentFocusWin; // cache a pointer to the currently focused window
|
||||
|
||||
nsTArray<nsPrintObject*> mPrintDocList;
|
||||
bool mIsIFrameSelected;
|
||||
bool mIsParentAFrameSet;
|
||||
bool mOnStartSent;
|
||||
bool mIsAborted; // tells us the document is being aborted
|
||||
bool mPreparingForPrint; // see comments above
|
||||
bool mDocWasToBeDestroyed; // see comments above
|
||||
bool mShrinkToFit;
|
||||
int16_t mPrintFrameType;
|
||||
int32_t mNumPrintablePages;
|
||||
int32_t mNumPagesPrinted;
|
||||
float mShrinkRatio;
|
||||
float mOrigDCScale;
|
||||
|
||||
nsCOMPtr<nsIPrintSettings> mPrintSettings;
|
||||
nsPrintPreviewListener* mPPEventListeners;
|
||||
|
||||
char16_t* mBrandName; // needed as a substitute name for a document
|
||||
|
||||
private:
|
||||
nsPrintData() = delete;
|
||||
nsPrintData& operator=(const nsPrintData& aOther) = delete;
|
||||
|
||||
~nsPrintData(); // non-virtual
|
||||
};
|
||||
|
||||
#endif /* nsPrintData_h___ */
|
||||
|
||||
4071
layout/printing/nsPrintEngine.cpp
Normal file
4071
layout/printing/nsPrintEngine.cpp
Normal file
File diff suppressed because it is too large
Load diff
305
layout/printing/nsPrintEngine.h
Normal file
305
layout/printing/nsPrintEngine.h
Normal file
|
|
@ -0,0 +1,305 @@
|
|||
/* -*- Mode: C++; tab-width: 2; 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/. */
|
||||
#ifndef nsPrintEngine_h___
|
||||
#define nsPrintEngine_h___
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
#include "nsPrintObject.h"
|
||||
#include "nsPrintData.h"
|
||||
#include "nsFrameList.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsIWebProgress.h"
|
||||
#include "mozilla/dom/HTMLCanvasElement.h"
|
||||
#include "nsIWebProgressListener.h"
|
||||
#include "nsWeakReference.h"
|
||||
|
||||
// Interfaces
|
||||
#include "nsIObserver.h"
|
||||
|
||||
// Classes
|
||||
class nsPagePrintTimer;
|
||||
class nsIDocShell;
|
||||
class nsIDocument;
|
||||
class nsIDocumentViewerPrint;
|
||||
class nsPrintObject;
|
||||
class nsIDocShell;
|
||||
class nsIPageSequenceFrame;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// nsPrintEngine Class
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
class nsPrintEngine final : public nsIObserver,
|
||||
public nsIWebProgressListener,
|
||||
public nsSupportsWeakReference
|
||||
{
|
||||
public:
|
||||
// nsISupports interface...
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// nsIObserver
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
NS_DECL_NSIWEBPROGRESSLISTENER
|
||||
|
||||
// Old nsIWebBrowserPrint methods; not cleaned up yet
|
||||
NS_IMETHOD Print(nsIPrintSettings* aPrintSettings,
|
||||
nsIWebProgressListener* aWebProgressListener);
|
||||
NS_IMETHOD PrintPreview(nsIPrintSettings* aPrintSettings,
|
||||
mozIDOMWindowProxy* aChildDOMWin,
|
||||
nsIWebProgressListener* aWebProgressListener);
|
||||
NS_IMETHOD GetIsFramesetDocument(bool *aIsFramesetDocument);
|
||||
NS_IMETHOD GetIsIFrameSelected(bool *aIsIFrameSelected);
|
||||
NS_IMETHOD GetIsRangeSelection(bool *aIsRangeSelection);
|
||||
NS_IMETHOD GetIsFramesetFrameSelected(bool *aIsFramesetFrameSelected);
|
||||
NS_IMETHOD GetPrintPreviewNumPages(int32_t *aPrintPreviewNumPages);
|
||||
NS_IMETHOD EnumerateDocumentNames(uint32_t* aCount, char16_t*** aResult);
|
||||
static nsresult GetGlobalPrintSettings(nsIPrintSettings** aPrintSettings);
|
||||
NS_IMETHOD GetDoingPrint(bool *aDoingPrint);
|
||||
NS_IMETHOD GetDoingPrintPreview(bool *aDoingPrintPreview);
|
||||
NS_IMETHOD GetCurrentPrintSettings(nsIPrintSettings **aCurrentPrintSettings);
|
||||
|
||||
|
||||
// This enum tells indicates what the default should be for the title
|
||||
// if the title from the document is null
|
||||
enum eDocTitleDefault {
|
||||
eDocTitleDefBlank,
|
||||
eDocTitleDefURLDoc
|
||||
};
|
||||
|
||||
nsPrintEngine();
|
||||
|
||||
void Destroy();
|
||||
void DestroyPrintingData();
|
||||
|
||||
nsresult Initialize(nsIDocumentViewerPrint* aDocViewerPrint,
|
||||
nsIDocShell* aContainer,
|
||||
nsIDocument* aDocument,
|
||||
float aScreenDPI,
|
||||
FILE* aDebugFile);
|
||||
|
||||
nsresult GetSeqFrameAndCountPages(nsIFrame*& aSeqFrame, int32_t& aCount);
|
||||
|
||||
//
|
||||
// The following three methods are used for printing...
|
||||
//
|
||||
nsresult DocumentReadyForPrinting();
|
||||
nsresult GetSelectionDocument(nsIDeviceContextSpec * aDevSpec,
|
||||
nsIDocument ** aNewDoc);
|
||||
|
||||
nsresult SetupToPrintContent();
|
||||
nsresult EnablePOsForPrinting();
|
||||
nsPrintObject* FindSmallestSTF();
|
||||
|
||||
bool PrintDocContent(nsPrintObject* aPO, nsresult& aStatus);
|
||||
nsresult DoPrint(nsPrintObject * aPO);
|
||||
|
||||
void SetPrintPO(nsPrintObject* aPO, bool aPrint);
|
||||
|
||||
void TurnScriptingOn(bool aDoTurnOn);
|
||||
bool CheckDocumentForPPCaching();
|
||||
void InstallPrintPreviewListener();
|
||||
|
||||
// nsIDocumentViewerPrint Printing Methods
|
||||
bool HasPrintCallbackCanvas();
|
||||
bool PrePrintPage();
|
||||
bool PrintPage(nsPrintObject* aPOect, bool& aInRange);
|
||||
bool DonePrintingPages(nsPrintObject* aPO, nsresult aResult);
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
void BuildDocTree(nsIDocShell * aParentNode,
|
||||
nsTArray<nsPrintObject*> * aDocList,
|
||||
nsPrintObject * aPO);
|
||||
nsresult ReflowDocList(nsPrintObject * aPO, bool aSetPixelScale);
|
||||
|
||||
nsresult ReflowPrintObject(nsPrintObject * aPO);
|
||||
|
||||
void CheckForChildFrameSets(nsPrintObject* aPO);
|
||||
|
||||
void CalcNumPrintablePages(int32_t& aNumPages);
|
||||
void ShowPrintProgress(bool aIsForPrinting, bool& aDoNotify);
|
||||
nsresult CleanupOnFailure(nsresult aResult, bool aIsPrinting);
|
||||
// If FinishPrintPreview() fails, caller may need to reset the state of the
|
||||
// object, for example by calling CleanupOnFailure().
|
||||
nsresult FinishPrintPreview();
|
||||
static void CloseProgressDialog(nsIWebProgressListener* aWebProgressListener);
|
||||
void SetDocAndURLIntoProgress(nsPrintObject* aPO,
|
||||
nsIPrintProgressParams* aParams);
|
||||
void EllipseLongString(nsAString& aStr, const uint32_t aLen, bool aDoFront);
|
||||
nsresult CheckForPrinters(nsIPrintSettings* aPrintSettings);
|
||||
void CleanupDocTitleArray(char16_t**& aArray, int32_t& aCount);
|
||||
|
||||
bool IsThereARangeSelection(nsPIDOMWindowOuter* aDOMWin);
|
||||
|
||||
void FirePrintingErrorEvent(nsresult aPrintError);
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
|
||||
// Timer Methods
|
||||
nsresult StartPagePrintTimer(nsPrintObject* aPO);
|
||||
|
||||
bool IsWindowsInOurSubTree(nsPIDOMWindowOuter* aDOMWindow);
|
||||
static bool IsParentAFrameSet(nsIDocShell * aParent);
|
||||
bool IsThereAnIFrameSelected(nsIDocShell* aDocShell,
|
||||
nsPIDOMWindowOuter* aDOMWin,
|
||||
bool& aIsParentFrameSet);
|
||||
|
||||
static nsPrintObject* FindPrintObjectByDOMWin(nsPrintObject* aParentObject,
|
||||
nsPIDOMWindowOuter* aDOMWin);
|
||||
|
||||
// get the currently infocus frame for the document viewer
|
||||
already_AddRefed<nsPIDOMWindowOuter> FindFocusedDOMWindow();
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// Static Methods
|
||||
//---------------------------------------------------------------------
|
||||
static void GetDocumentTitleAndURL(nsIDocument* aDoc,
|
||||
nsAString& aTitle,
|
||||
nsAString& aURLStr);
|
||||
void GetDisplayTitleAndURL(nsPrintObject* aPO,
|
||||
nsAString& aTitle,
|
||||
nsAString& aURLStr,
|
||||
eDocTitleDefault aDefType);
|
||||
|
||||
static bool HasFramesetChild(nsIContent* aContent);
|
||||
|
||||
bool CheckBeforeDestroy();
|
||||
nsresult Cancelled();
|
||||
|
||||
nsIPresShell* GetPrintPreviewPresShell() {return mPrtPreview->mPrintObject->mPresShell;}
|
||||
|
||||
float GetPrintPreviewScale() { return mPrtPreview->mPrintObject->
|
||||
mPresContext->GetPrintPreviewScale(); }
|
||||
|
||||
static nsIPresShell* GetPresShellFor(nsIDocShell* aDocShell);
|
||||
|
||||
// These calls also update the DocViewer
|
||||
void SetIsPrinting(bool aIsPrinting);
|
||||
bool GetIsPrinting()
|
||||
{
|
||||
return mIsDoingPrinting;
|
||||
}
|
||||
void SetIsPrintPreview(bool aIsPrintPreview);
|
||||
bool GetIsPrintPreview()
|
||||
{
|
||||
return mIsDoingPrintPreview;
|
||||
}
|
||||
void SetIsCreatingPrintPreview(bool aIsCreatingPrintPreview)
|
||||
{
|
||||
mIsCreatingPrintPreview = aIsCreatingPrintPreview;
|
||||
}
|
||||
bool GetIsCreatingPrintPreview()
|
||||
{
|
||||
return mIsCreatingPrintPreview;
|
||||
}
|
||||
|
||||
void SetDisallowSelectionPrint(bool aDisallowSelectionPrint)
|
||||
{
|
||||
mDisallowSelectionPrint = aDisallowSelectionPrint;
|
||||
}
|
||||
|
||||
protected:
|
||||
~nsPrintEngine();
|
||||
|
||||
nsresult CommonPrint(bool aIsPrintPreview, nsIPrintSettings* aPrintSettings,
|
||||
nsIWebProgressListener* aWebProgressListener,
|
||||
nsIDOMDocument* aDoc);
|
||||
|
||||
nsresult DoCommonPrint(bool aIsPrintPreview, nsIPrintSettings* aPrintSettings,
|
||||
nsIWebProgressListener* aWebProgressListener,
|
||||
nsIDOMDocument* aDoc);
|
||||
|
||||
void FirePrintCompletionEvent();
|
||||
static nsresult GetSeqFrameAndCountPagesInternal(nsPrintObject* aPO,
|
||||
nsIFrame*& aSeqFrame,
|
||||
int32_t& aCount);
|
||||
|
||||
static nsresult FindSelectionBoundsWithList(nsFrameList::Enumerator& aChildFrames,
|
||||
nsIFrame * aParentFrame,
|
||||
nsRect& aRect,
|
||||
nsIFrame *& aStartFrame,
|
||||
nsRect& aStartRect,
|
||||
nsIFrame *& aEndFrame,
|
||||
nsRect& aEndRect);
|
||||
|
||||
static nsresult FindSelectionBounds(nsIFrame * aParentFrame,
|
||||
nsRect& aRect,
|
||||
nsIFrame *& aStartFrame,
|
||||
nsRect& aStartRect,
|
||||
nsIFrame *& aEndFrame,
|
||||
nsRect& aEndRect);
|
||||
|
||||
static nsresult GetPageRangeForSelection(nsIPageSequenceFrame* aPageSeqFrame,
|
||||
nsIFrame** aStartFrame,
|
||||
int32_t& aStartPageNum,
|
||||
nsRect& aStartRect,
|
||||
nsIFrame** aEndFrame,
|
||||
int32_t& aEndPageNum,
|
||||
nsRect& aEndRect);
|
||||
|
||||
static void MapContentForPO(nsPrintObject* aPO, nsIContent* aContent);
|
||||
|
||||
static void MapContentToWebShells(nsPrintObject* aRootPO, nsPrintObject* aPO);
|
||||
|
||||
static void SetPrintAsIs(nsPrintObject* aPO, bool aAsIs = true);
|
||||
|
||||
void DisconnectPagePrintTimer();
|
||||
|
||||
// Static member variables
|
||||
bool mIsCreatingPrintPreview;
|
||||
bool mIsDoingPrinting;
|
||||
bool mIsDoingPrintPreview; // per DocumentViewer
|
||||
bool mProgressDialogIsShown;
|
||||
|
||||
nsCOMPtr<nsIDocumentViewerPrint> mDocViewerPrint;
|
||||
nsWeakPtr mContainer;
|
||||
float mScreenDPI;
|
||||
|
||||
// We are the primary owner of our nsPrintData member vars. These vars
|
||||
// are refcounted so that functions (e.g. nsPrintData methods) can create
|
||||
// temporary owning references when they need to fire a callback that
|
||||
// could conceivably destroy this nsPrintEngine owner object and all its
|
||||
// member-data.
|
||||
RefPtr<nsPrintData> mPrt;
|
||||
|
||||
nsPagePrintTimer* mPagePrintTimer;
|
||||
nsWeakFrame mPageSeqFrame;
|
||||
|
||||
// Print Preview
|
||||
RefPtr<nsPrintData> mPrtPreview;
|
||||
RefPtr<nsPrintData> mOldPrtPreview;
|
||||
|
||||
nsCOMPtr<nsIDocument> mDocument;
|
||||
|
||||
FILE* mDebugFile;
|
||||
|
||||
int32_t mLoadCounter;
|
||||
bool mDidLoadDataForPrinting;
|
||||
bool mIsDestroying;
|
||||
bool mDisallowSelectionPrint;
|
||||
|
||||
nsresult AfterNetworkPrint(bool aHandleError);
|
||||
|
||||
nsresult SetRootView(nsPrintObject* aPO,
|
||||
bool& aDoReturn,
|
||||
bool& aDocumentIsTopLevel,
|
||||
nsSize& aAdjSize);
|
||||
nsView* GetParentViewForRoot();
|
||||
bool DoSetPixelScale();
|
||||
void UpdateZoomRatio(nsPrintObject* aPO, bool aSetPixelScale);
|
||||
nsresult ReconstructAndReflow(bool aDoSetPixelScale);
|
||||
nsresult UpdateSelectionAndShrinkPrintObject(nsPrintObject* aPO,
|
||||
bool aDocumentIsTopLevel);
|
||||
nsresult InitPrintDocConstruction(bool aHandleError);
|
||||
void FirePrintPreviewUpdateEvent();
|
||||
private:
|
||||
nsPrintEngine& operator=(const nsPrintEngine& aOther) = delete;
|
||||
};
|
||||
|
||||
#endif /* nsPrintEngine_h___ */
|
||||
113
layout/printing/nsPrintObject.cpp
Normal file
113
layout/printing/nsPrintObject.cpp
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
/* -*- Mode: C++; tab-width: 2; 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 "nsPrintObject.h"
|
||||
#include "nsIContentViewer.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsContentUtils.h" // for nsAutoScriptBlocker
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsIDocShellTreeItem.h"
|
||||
#include "nsIBaseWindow.h"
|
||||
#include "nsIDocument.h"
|
||||
|
||||
//---------------------------------------------------
|
||||
//-- nsPrintObject Class Impl
|
||||
//---------------------------------------------------
|
||||
nsPrintObject::nsPrintObject() :
|
||||
mContent(nullptr), mFrameType(eFrame), mParent(nullptr),
|
||||
mHasBeenPrinted(false), mDontPrint(true), mPrintAsIs(false),
|
||||
mInvisible(false), mDidCreateDocShell(false),
|
||||
mShrinkRatio(1.0), mZoomRatio(1.0)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsPrintObject);
|
||||
}
|
||||
|
||||
|
||||
nsPrintObject::~nsPrintObject()
|
||||
{
|
||||
MOZ_COUNT_DTOR(nsPrintObject);
|
||||
for (uint32_t i=0;i<mKids.Length();i++) {
|
||||
nsPrintObject* po = mKids[i];
|
||||
delete po;
|
||||
}
|
||||
|
||||
DestroyPresentation();
|
||||
if (mDidCreateDocShell && mDocShell) {
|
||||
nsCOMPtr<nsIBaseWindow> baseWin(do_QueryInterface(mDocShell));
|
||||
if (baseWin) {
|
||||
baseWin->Destroy();
|
||||
}
|
||||
}
|
||||
mDocShell = nullptr;
|
||||
mTreeOwner = nullptr; // mTreeOwner must be released after mDocShell;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
nsresult
|
||||
nsPrintObject::Init(nsIDocShell* aDocShell, nsIDOMDocument* aDoc,
|
||||
bool aPrintPreview)
|
||||
{
|
||||
mPrintPreview = aPrintPreview;
|
||||
|
||||
if (mPrintPreview || mParent) {
|
||||
mDocShell = aDocShell;
|
||||
} else {
|
||||
mTreeOwner = do_GetInterface(aDocShell);
|
||||
// Create a container docshell for printing.
|
||||
mDocShell = do_CreateInstance("@mozilla.org/docshell;1");
|
||||
NS_ENSURE_TRUE(mDocShell, NS_ERROR_OUT_OF_MEMORY);
|
||||
mDidCreateDocShell = true;
|
||||
mDocShell->SetItemType(aDocShell->ItemType());
|
||||
mDocShell->SetTreeOwner(mTreeOwner);
|
||||
}
|
||||
NS_ENSURE_TRUE(mDocShell, NS_ERROR_FAILURE);
|
||||
|
||||
// Keep the document related to this docshell alive
|
||||
nsCOMPtr<nsIDOMDocument> dummy = do_GetInterface(mDocShell);
|
||||
mozilla::Unused << dummy;
|
||||
|
||||
nsCOMPtr<nsIContentViewer> viewer;
|
||||
mDocShell->GetContentViewer(getter_AddRefs(viewer));
|
||||
NS_ENSURE_STATE(viewer);
|
||||
|
||||
nsCOMPtr<nsIDocument> doc = do_QueryInterface(aDoc);
|
||||
NS_ENSURE_STATE(doc);
|
||||
|
||||
if (mParent) {
|
||||
nsCOMPtr<nsPIDOMWindowOuter> window = doc->GetWindow();
|
||||
if (window) {
|
||||
mContent = window->GetFrameElementInternal();
|
||||
}
|
||||
mDocument = doc;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
mDocument = doc->CreateStaticClone(mDocShell);
|
||||
nsCOMPtr<nsIDOMDocument> clonedDOMDoc = do_QueryInterface(mDocument);
|
||||
NS_ENSURE_STATE(clonedDOMDoc);
|
||||
|
||||
viewer->SetDOMDocument(clonedDOMDoc);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Resets PO by destroying the presentation
|
||||
void
|
||||
nsPrintObject::DestroyPresentation()
|
||||
{
|
||||
if (mPresShell) {
|
||||
mPresShell->EndObservingDocument();
|
||||
nsAutoScriptBlocker scriptBlocker;
|
||||
nsCOMPtr<nsIPresShell> shell = mPresShell;
|
||||
mPresShell = nullptr;
|
||||
shell->Destroy();
|
||||
}
|
||||
mPresContext = nullptr;
|
||||
mViewManager = nullptr;
|
||||
}
|
||||
|
||||
71
layout/printing/nsPrintObject.h
Normal file
71
layout/printing/nsPrintObject.h
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
/* -*- Mode: C++; tab-width: 2; 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/. */
|
||||
#ifndef nsPrintObject_h___
|
||||
#define nsPrintObject_h___
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
|
||||
// Interfaces
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsViewManager.h"
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsIDocShellTreeOwner.h"
|
||||
|
||||
class nsIContent;
|
||||
class nsIDocument;
|
||||
class nsPresContext;
|
||||
|
||||
// nsPrintObject Document Type
|
||||
enum PrintObjectType {eDoc = 0, eFrame = 1, eIFrame = 2, eFrameSet = 3};
|
||||
|
||||
//---------------------------------------------------
|
||||
//-- nsPrintObject Class
|
||||
//---------------------------------------------------
|
||||
class nsPrintObject
|
||||
{
|
||||
|
||||
public:
|
||||
nsPrintObject();
|
||||
~nsPrintObject(); // non-virtual
|
||||
|
||||
// Methods
|
||||
nsresult Init(nsIDocShell* aDocShell, nsIDOMDocument* aDoc,
|
||||
bool aPrintPreview);
|
||||
|
||||
bool IsPrintable() { return !mDontPrint; }
|
||||
void DestroyPresentation();
|
||||
|
||||
// Data Members
|
||||
nsCOMPtr<nsIDocShell> mDocShell;
|
||||
nsCOMPtr<nsIDocShellTreeOwner> mTreeOwner;
|
||||
nsCOMPtr<nsIDocument> mDocument;
|
||||
|
||||
RefPtr<nsPresContext> mPresContext;
|
||||
nsCOMPtr<nsIPresShell> mPresShell;
|
||||
RefPtr<nsViewManager> mViewManager;
|
||||
|
||||
nsCOMPtr<nsIContent> mContent;
|
||||
PrintObjectType mFrameType;
|
||||
|
||||
nsTArray<nsPrintObject*> mKids;
|
||||
nsPrintObject* mParent;
|
||||
bool mHasBeenPrinted;
|
||||
bool mDontPrint;
|
||||
bool mPrintAsIs;
|
||||
bool mInvisible; // Indicates PO is set to not visible by CSS
|
||||
bool mPrintPreview;
|
||||
bool mDidCreateDocShell;
|
||||
float mShrinkRatio;
|
||||
float mZoomRatio;
|
||||
|
||||
private:
|
||||
nsPrintObject& operator=(const nsPrintObject& aOther) = delete;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* nsPrintObject_h___ */
|
||||
|
||||
212
layout/printing/nsPrintPreviewListener.cpp
Normal file
212
layout/printing/nsPrintPreviewListener.cpp
Normal file
|
|
@ -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;
|
||||
}
|
||||
53
layout/printing/nsPrintPreviewListener.h
Normal file
53
layout/printing/nsPrintPreviewListener.h
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
/* -*- 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/. */
|
||||
|
||||
#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__ */
|
||||
Loading…
Add table
Add a link
Reference in a new issue