mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-10 02:08:38 +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
15
embedding/components/appstartup/moz.build
Normal file
15
embedding/components/appstartup/moz.build
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
# -*- 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/.
|
||||
|
||||
EXPORTS += [
|
||||
'nsIAppStartupNotifier.h',
|
||||
]
|
||||
|
||||
SOURCES += [
|
||||
'nsAppStartupNotifier.cpp',
|
||||
]
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
90
embedding/components/appstartup/nsAppStartupNotifier.cpp
Normal file
90
embedding/components/appstartup/nsAppStartupNotifier.cpp
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* 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 "nsCOMPtr.h"
|
||||
#include "nsString.h"
|
||||
#include "nsXPIDLString.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsICategoryManager.h"
|
||||
#include "nsXPCOM.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "nsAppStartupNotifier.h"
|
||||
#include "nsISimpleEnumerator.h"
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsAppStartupNotifier, nsIObserver)
|
||||
|
||||
nsAppStartupNotifier::nsAppStartupNotifier()
|
||||
{
|
||||
}
|
||||
|
||||
nsAppStartupNotifier::~nsAppStartupNotifier()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsAppStartupNotifier::Observe(nsISupports *aSubject, const char *aTopic, const char16_t *someData)
|
||||
{
|
||||
NS_ENSURE_ARG(aTopic);
|
||||
nsresult rv;
|
||||
|
||||
// now initialize all startup listeners
|
||||
nsCOMPtr<nsICategoryManager> categoryManager =
|
||||
do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsISimpleEnumerator> enumerator;
|
||||
rv = categoryManager->EnumerateCategory(aTopic,
|
||||
getter_AddRefs(enumerator));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsCOMPtr<nsISupports> entry;
|
||||
while (NS_SUCCEEDED(enumerator->GetNext(getter_AddRefs(entry)))) {
|
||||
nsCOMPtr<nsISupportsCString> category = do_QueryInterface(entry, &rv);
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsAutoCString categoryEntry;
|
||||
rv = category->GetData(categoryEntry);
|
||||
|
||||
nsXPIDLCString contractId;
|
||||
categoryManager->GetCategoryEntry(aTopic,
|
||||
categoryEntry.get(),
|
||||
getter_Copies(contractId));
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
|
||||
// If we see the word "service," in the beginning
|
||||
// of the contractId then we create it as a service
|
||||
// if not we do a createInstance
|
||||
|
||||
nsCOMPtr<nsISupports> startupInstance;
|
||||
if (Substring(contractId, 0, 8).EqualsLiteral("service,"))
|
||||
startupInstance = do_GetService(contractId.get() + 8, &rv);
|
||||
else
|
||||
startupInstance = do_CreateInstance(contractId, &rv);
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// Try to QI to nsIObserver
|
||||
nsCOMPtr<nsIObserver> startupObserver =
|
||||
do_QueryInterface(startupInstance, &rv);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = startupObserver->Observe(nullptr, aTopic, nullptr);
|
||||
|
||||
// mainly for debugging if you want to know if your observer worked.
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "Startup Observer failed!\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
#ifdef DEBUG
|
||||
nsAutoCString warnStr("Cannot create startup observer : ");
|
||||
warnStr += contractId.get();
|
||||
NS_WARNING(warnStr.get());
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
30
embedding/components/appstartup/nsAppStartupNotifier.h
Normal file
30
embedding/components/appstartup/nsAppStartupNotifier.h
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
/* -*- 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 nsAppStartupNotifier_h___
|
||||
#define nsAppStartupNotifier_h___
|
||||
|
||||
#include "nsIAppStartupNotifier.h"
|
||||
|
||||
// {1F59B001-02C9-11d5-AE76-CC92F7DB9E03}
|
||||
#define NS_APPSTARTUPNOTIFIER_CID \
|
||||
{ 0x1f59b001, 0x2c9, 0x11d5, { 0xae, 0x76, 0xcc, 0x92, 0xf7, 0xdb, 0x9e, 0x3 } }
|
||||
|
||||
class nsAppStartupNotifier : public nsIObserver
|
||||
{
|
||||
public:
|
||||
NS_DEFINE_STATIC_CID_ACCESSOR( NS_APPSTARTUPNOTIFIER_CID )
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
nsAppStartupNotifier();
|
||||
|
||||
protected:
|
||||
virtual ~nsAppStartupNotifier();
|
||||
};
|
||||
|
||||
#endif /* nsAppStartupNotifier_h___ */
|
||||
|
||||
59
embedding/components/appstartup/nsIAppStartupNotifier.h
Normal file
59
embedding/components/appstartup/nsIAppStartupNotifier.h
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* 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 nsIAppStartupNotifier_h___
|
||||
#define nsIAppStartupNotifier_h___
|
||||
|
||||
#include "nsIObserver.h"
|
||||
|
||||
/*
|
||||
Some components need to be run at the startup of mozilla or embedding - to
|
||||
start new services etc.
|
||||
|
||||
This interface provides a generic way to start up arbitrary components
|
||||
without requiring them to hack into main1() (or into NS_InitEmbedding) as
|
||||
it's currently being done for services such as wallet, command line handlers
|
||||
etc.
|
||||
|
||||
We will have a category called "app-startup" which components register
|
||||
themselves in using the CategoryManager.
|
||||
|
||||
Components can also (optionally) add the word "service," as a prefix
|
||||
to the "value" they pass in during a call to AddCategoryEntry() as
|
||||
shown below:
|
||||
|
||||
categoryManager->AddCategoryEntry(APPSTARTUP_CATEGORY, "testcomp",
|
||||
"service," NS_WALLETSERVICE_CONTRACTID
|
||||
true, true,
|
||||
getter_Copies(previous));
|
||||
|
||||
Presence of the "service" keyword indicates the components desire to
|
||||
be started as a service. When the "service" keyword is not present
|
||||
we just do a do_CreateInstance.
|
||||
|
||||
When mozilla starts (and when NS_InitEmbedding()) is invoked
|
||||
we create an instance of the AppStartupNotifier component (which
|
||||
implements nsIObserver) and invoke its Observe() method.
|
||||
|
||||
Observe() will enumerate the components registered into the
|
||||
APPSTARTUP_CATEGORY and notify them that startup has begun
|
||||
and release them.
|
||||
*/
|
||||
|
||||
#define NS_APPSTARTUPNOTIFIER_CONTRACTID "@mozilla.org/embedcomp/appstartup-notifier;1"
|
||||
|
||||
#define APPSTARTUP_CATEGORY "app-startup"
|
||||
#define APPSTARTUP_TOPIC "app-startup"
|
||||
|
||||
|
||||
/*
|
||||
Please note that there's not a new interface in this file.
|
||||
We're just leveraging nsIObserver instead of creating a
|
||||
new one
|
||||
|
||||
This file exists solely to provide the defines above
|
||||
*/
|
||||
|
||||
#endif /* nsIAppStartupNotifier_h___ */
|
||||
38
embedding/components/build/moz.build
Normal file
38
embedding/components/build/moz.build
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
# -*- 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/.
|
||||
|
||||
SOURCES += [
|
||||
'nsEmbeddingModule.cpp',
|
||||
]
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
LOCAL_INCLUDES += [
|
||||
'../appstartup',
|
||||
'../commandhandler',
|
||||
'../find',
|
||||
'../printingui/ipc',
|
||||
'../webbrowserpersist',
|
||||
'../windowwatcher',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
|
||||
DEFINES['PROXY_PRINTING'] = 1
|
||||
LOCAL_INCLUDES += [
|
||||
'../printingui/win',
|
||||
]
|
||||
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
|
||||
DEFINES['PROXY_PRINTING'] = 1
|
||||
LOCAL_INCLUDES += [
|
||||
'../printingui/mac',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_PDF_PRINTING']:
|
||||
DEFINES['PROXY_PRINTING'] = 1
|
||||
LOCAL_INCLUDES += [
|
||||
'../printingui/unixshared',
|
||||
]
|
||||
|
||||
include('/ipc/chromium/chromium-config.mozbuild')
|
||||
120
embedding/components/build/nsEmbeddingModule.cpp
Normal file
120
embedding/components/build/nsEmbeddingModule.cpp
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* 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 "mozilla/ModuleUtils.h"
|
||||
#include "nsDialogParamBlock.h"
|
||||
#include "nsWindowWatcher.h"
|
||||
#include "nsAppStartupNotifier.h"
|
||||
#include "nsFind.h"
|
||||
#include "nsWebBrowserFind.h"
|
||||
#include "nsWebBrowserPersist.h"
|
||||
#include "nsCommandManager.h"
|
||||
#include "nsControllerCommandTable.h"
|
||||
#include "nsCommandParams.h"
|
||||
#include "nsCommandGroup.h"
|
||||
#include "nsBaseCommandController.h"
|
||||
#include "nsNetCID.h"
|
||||
#include "nsEmbedCID.h"
|
||||
|
||||
#ifdef NS_PRINTING
|
||||
#include "nsPrintingPromptService.h"
|
||||
#include "nsPrintingProxy.h"
|
||||
#endif
|
||||
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsWindowWatcher, Init)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsAppStartupNotifier)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsFind)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsWebBrowserFind)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsWebBrowserPersist)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsControllerCommandTable)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsCommandManager)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsCommandParams)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsControllerCommandGroup)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsBaseCommandController)
|
||||
|
||||
#ifdef MOZ_XUL
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsDialogParamBlock)
|
||||
#ifdef NS_PRINTING
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPrintingPromptService, Init)
|
||||
#ifdef PROXY_PRINTING
|
||||
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsPrintingProxy,
|
||||
nsPrintingProxy::GetInstance)
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_XUL
|
||||
NS_DEFINE_NAMED_CID(NS_DIALOGPARAMBLOCK_CID);
|
||||
#ifdef NS_PRINTING
|
||||
NS_DEFINE_NAMED_CID(NS_PRINTINGPROMPTSERVICE_CID);
|
||||
#endif
|
||||
#endif
|
||||
NS_DEFINE_NAMED_CID(NS_WINDOWWATCHER_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_FIND_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_WEB_BROWSER_FIND_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_APPSTARTUPNOTIFIER_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_WEBBROWSERPERSIST_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_CONTROLLERCOMMANDTABLE_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_COMMAND_MANAGER_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_COMMAND_PARAMS_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_CONTROLLER_COMMAND_GROUP_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_BASECOMMANDCONTROLLER_CID);
|
||||
|
||||
static const mozilla::Module::CIDEntry kEmbeddingCIDs[] = {
|
||||
#ifdef MOZ_XUL
|
||||
{ &kNS_DIALOGPARAMBLOCK_CID, false, nullptr, nsDialogParamBlockConstructor },
|
||||
#ifdef NS_PRINTING
|
||||
|
||||
#ifdef PROXY_PRINTING
|
||||
{ &kNS_PRINTINGPROMPTSERVICE_CID, false, nullptr, nsPrintingPromptServiceConstructor,
|
||||
mozilla::Module::MAIN_PROCESS_ONLY },
|
||||
{ &kNS_PRINTINGPROMPTSERVICE_CID, false, nullptr, nsPrintingProxyConstructor,
|
||||
mozilla::Module::CONTENT_PROCESS_ONLY },
|
||||
#else
|
||||
{ &kNS_PRINTINGPROMPTSERVICE_CID, false, nullptr, nsPrintingPromptServiceConstructor },
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
{ &kNS_WINDOWWATCHER_CID, false, nullptr, nsWindowWatcherConstructor },
|
||||
{ &kNS_FIND_CID, false, nullptr, nsFindConstructor },
|
||||
{ &kNS_WEB_BROWSER_FIND_CID, false, nullptr, nsWebBrowserFindConstructor },
|
||||
{ &kNS_APPSTARTUPNOTIFIER_CID, false, nullptr, nsAppStartupNotifierConstructor },
|
||||
{ &kNS_WEBBROWSERPERSIST_CID, false, nullptr, nsWebBrowserPersistConstructor },
|
||||
{ &kNS_CONTROLLERCOMMANDTABLE_CID, false, nullptr, nsControllerCommandTableConstructor },
|
||||
{ &kNS_COMMAND_MANAGER_CID, false, nullptr, nsCommandManagerConstructor },
|
||||
{ &kNS_COMMAND_PARAMS_CID, false, nullptr, nsCommandParamsConstructor },
|
||||
{ &kNS_CONTROLLER_COMMAND_GROUP_CID, false, nullptr, nsControllerCommandGroupConstructor },
|
||||
{ &kNS_BASECOMMANDCONTROLLER_CID, false, nullptr, nsBaseCommandControllerConstructor },
|
||||
{ nullptr }
|
||||
};
|
||||
|
||||
static const mozilla::Module::ContractIDEntry kEmbeddingContracts[] = {
|
||||
#ifdef MOZ_XUL
|
||||
{ NS_DIALOGPARAMBLOCK_CONTRACTID, &kNS_DIALOGPARAMBLOCK_CID },
|
||||
#ifdef NS_PRINTING
|
||||
{ NS_PRINTINGPROMPTSERVICE_CONTRACTID, &kNS_PRINTINGPROMPTSERVICE_CID },
|
||||
#endif
|
||||
#endif
|
||||
{ NS_WINDOWWATCHER_CONTRACTID, &kNS_WINDOWWATCHER_CID },
|
||||
{ NS_FIND_CONTRACTID, &kNS_FIND_CID },
|
||||
{ NS_WEB_BROWSER_FIND_CONTRACTID, &kNS_WEB_BROWSER_FIND_CID },
|
||||
{ NS_APPSTARTUPNOTIFIER_CONTRACTID, &kNS_APPSTARTUPNOTIFIER_CID },
|
||||
{ NS_WEBBROWSERPERSIST_CONTRACTID, &kNS_WEBBROWSERPERSIST_CID },
|
||||
{ NS_CONTROLLERCOMMANDTABLE_CONTRACTID, &kNS_CONTROLLERCOMMANDTABLE_CID },
|
||||
{ NS_COMMAND_MANAGER_CONTRACTID, &kNS_COMMAND_MANAGER_CID },
|
||||
{ NS_COMMAND_PARAMS_CONTRACTID, &kNS_COMMAND_PARAMS_CID },
|
||||
{ NS_CONTROLLER_COMMAND_GROUP_CONTRACTID, &kNS_CONTROLLER_COMMAND_GROUP_CID },
|
||||
{ NS_BASECOMMANDCONTROLLER_CONTRACTID, &kNS_BASECOMMANDCONTROLLER_CID },
|
||||
{ nullptr }
|
||||
};
|
||||
|
||||
static const mozilla::Module kEmbeddingModule = {
|
||||
mozilla::Module::kVersion,
|
||||
kEmbeddingCIDs,
|
||||
kEmbeddingContracts
|
||||
};
|
||||
|
||||
NSMODULE_DEFN(embedcomponents) = &kEmbeddingModule;
|
||||
26
embedding/components/commandhandler/moz.build
Normal file
26
embedding/components/commandhandler/moz.build
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
# -*- 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 += [
|
||||
'nsICommandManager.idl',
|
||||
'nsICommandParams.idl',
|
||||
'nsIControllerCommand.idl',
|
||||
'nsIControllerCommandTable.idl',
|
||||
'nsIControllerContext.idl',
|
||||
'nsPICommandUpdater.idl',
|
||||
]
|
||||
|
||||
XPIDL_MODULE = 'commandhandler'
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'nsBaseCommandController.cpp',
|
||||
'nsCommandGroup.cpp',
|
||||
'nsCommandManager.cpp',
|
||||
'nsCommandParams.cpp',
|
||||
'nsControllerCommandTable.cpp',
|
||||
]
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
184
embedding/components/commandhandler/nsBaseCommandController.cpp
Normal file
184
embedding/components/commandhandler/nsBaseCommandController.cpp
Normal file
|
|
@ -0,0 +1,184 @@
|
|||
/* -*- 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 "nsString.h"
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsBaseCommandController.h"
|
||||
|
||||
#include "nsString.h"
|
||||
#include "nsWeakPtr.h"
|
||||
|
||||
NS_IMPL_ADDREF(nsBaseCommandController)
|
||||
NS_IMPL_RELEASE(nsBaseCommandController)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(nsBaseCommandController)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIController)
|
||||
NS_INTERFACE_MAP_ENTRY(nsICommandController)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIControllerContext)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIControllerContext)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
nsBaseCommandController::nsBaseCommandController()
|
||||
: mCommandContextRawPtr(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
nsBaseCommandController::~nsBaseCommandController()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBaseCommandController::Init(nsIControllerCommandTable* aCommandTable)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
if (aCommandTable) {
|
||||
mCommandTable = aCommandTable;
|
||||
} else {
|
||||
mCommandTable =
|
||||
do_CreateInstance(NS_CONTROLLERCOMMANDTABLE_CONTRACTID, &rv);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBaseCommandController::SetCommandContext(nsISupports* aCommandContext)
|
||||
{
|
||||
mCommandContextWeakPtr = nullptr;
|
||||
mCommandContextRawPtr = nullptr;
|
||||
|
||||
if (aCommandContext) {
|
||||
nsCOMPtr<nsISupportsWeakReference> weak = do_QueryInterface(aCommandContext);
|
||||
if (weak) {
|
||||
nsresult rv =
|
||||
weak->GetWeakReference(getter_AddRefs(mCommandContextWeakPtr));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
} else {
|
||||
mCommandContextRawPtr = aCommandContext;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBaseCommandController::GetInterface(const nsIID& aIID, void** aResult)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
|
||||
if (NS_SUCCEEDED(QueryInterface(aIID, aResult))) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (aIID.Equals(NS_GET_IID(nsIControllerCommandTable))) {
|
||||
if (mCommandTable) {
|
||||
return mCommandTable->QueryInterface(aIID, aResult);
|
||||
}
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
return NS_NOINTERFACE;
|
||||
}
|
||||
|
||||
/* =======================================================================
|
||||
* nsIController
|
||||
* ======================================================================= */
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBaseCommandController::IsCommandEnabled(const char* aCommand, bool* aResult)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aCommand);
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
NS_ENSURE_STATE(mCommandTable);
|
||||
|
||||
nsISupports* context = mCommandContextRawPtr;
|
||||
nsCOMPtr<nsISupports> weak;
|
||||
if (!context) {
|
||||
weak = do_QueryReferent(mCommandContextWeakPtr);
|
||||
context = weak;
|
||||
}
|
||||
return mCommandTable->IsCommandEnabled(aCommand, context, aResult);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBaseCommandController::SupportsCommand(const char* aCommand, bool* aResult)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aCommand);
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
NS_ENSURE_STATE(mCommandTable);
|
||||
|
||||
nsISupports* context = mCommandContextRawPtr;
|
||||
nsCOMPtr<nsISupports> weak;
|
||||
if (!context) {
|
||||
weak = do_QueryReferent(mCommandContextWeakPtr);
|
||||
context = weak;
|
||||
}
|
||||
return mCommandTable->SupportsCommand(aCommand, context, aResult);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBaseCommandController::DoCommand(const char* aCommand)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aCommand);
|
||||
NS_ENSURE_STATE(mCommandTable);
|
||||
|
||||
nsISupports* context = mCommandContextRawPtr;
|
||||
nsCOMPtr<nsISupports> weak;
|
||||
if (!context) {
|
||||
weak = do_QueryReferent(mCommandContextWeakPtr);
|
||||
context = weak;
|
||||
}
|
||||
return mCommandTable->DoCommand(aCommand, context);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBaseCommandController::DoCommandWithParams(const char* aCommand,
|
||||
nsICommandParams* aParams)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aCommand);
|
||||
NS_ENSURE_STATE(mCommandTable);
|
||||
|
||||
nsISupports* context = mCommandContextRawPtr;
|
||||
nsCOMPtr<nsISupports> weak;
|
||||
if (!context) {
|
||||
weak = do_QueryReferent(mCommandContextWeakPtr);
|
||||
context = weak;
|
||||
}
|
||||
return mCommandTable->DoCommandParams(aCommand, aParams, context);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBaseCommandController::GetCommandStateWithParams(const char* aCommand,
|
||||
nsICommandParams* aParams)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aCommand);
|
||||
NS_ENSURE_STATE(mCommandTable);
|
||||
|
||||
nsISupports* context = mCommandContextRawPtr;
|
||||
nsCOMPtr<nsISupports> weak;
|
||||
if (!context) {
|
||||
weak = do_QueryReferent(mCommandContextWeakPtr);
|
||||
context = weak;
|
||||
}
|
||||
return mCommandTable->GetCommandState(aCommand, aParams, context);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBaseCommandController::OnEvent(const char* aEventName)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aEventName);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBaseCommandController::GetSupportedCommands(uint32_t* aCount,
|
||||
char*** aCommands)
|
||||
{
|
||||
NS_ENSURE_STATE(mCommandTable);
|
||||
return mCommandTable->GetSupportedCommands(aCount, aCommands);
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
/* -*- 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 nsBaseCommandController_h__
|
||||
#define nsBaseCommandController_h__
|
||||
|
||||
#define NS_BASECOMMANDCONTROLLER_CID \
|
||||
{ 0xbf88b48c, 0xfd8e, 0x40b4, { 0xba, 0x36, 0xc7, 0xc3, 0xad, 0x6d, 0x8a, 0xc9 } }
|
||||
#define NS_BASECOMMANDCONTROLLER_CONTRACTID \
|
||||
"@mozilla.org/embedcomp/base-command-controller;1"
|
||||
|
||||
#include "nsIController.h"
|
||||
#include "nsIControllerContext.h"
|
||||
#include "nsIControllerCommandTable.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsIWeakReferenceUtils.h"
|
||||
|
||||
// The base editor controller is used for both text widgets, and all other text
|
||||
// and html editing
|
||||
class nsBaseCommandController
|
||||
: public nsIController
|
||||
, public nsIControllerContext
|
||||
, public nsIInterfaceRequestor
|
||||
, public nsICommandController
|
||||
{
|
||||
public:
|
||||
nsBaseCommandController();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSICONTROLLER
|
||||
NS_DECL_NSICOMMANDCONTROLLER
|
||||
NS_DECL_NSICONTROLLERCONTEXT
|
||||
NS_DECL_NSIINTERFACEREQUESTOR
|
||||
|
||||
protected:
|
||||
virtual ~nsBaseCommandController();
|
||||
|
||||
private:
|
||||
nsWeakPtr mCommandContextWeakPtr;
|
||||
nsISupports* mCommandContextRawPtr;
|
||||
|
||||
// Our reference to the command manager
|
||||
nsCOMPtr<nsIControllerCommandTable> mCommandTable;
|
||||
};
|
||||
|
||||
#endif /* nsBaseCommandController_h_ */
|
||||
296
embedding/components/commandhandler/nsCommandGroup.cpp
Normal file
296
embedding/components/commandhandler/nsCommandGroup.cpp
Normal file
|
|
@ -0,0 +1,296 @@
|
|||
/* -*- 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 "nsString.h"
|
||||
#include "nsReadableUtils.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsISimpleEnumerator.h"
|
||||
#include "nsXPCOM.h"
|
||||
#include "nsSupportsPrimitives.h"
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsCommandGroup.h"
|
||||
#include "nsIControllerCommand.h"
|
||||
#include "nsCRT.h"
|
||||
|
||||
class nsGroupsEnumerator : public nsISimpleEnumerator
|
||||
{
|
||||
public:
|
||||
explicit nsGroupsEnumerator(
|
||||
nsControllerCommandGroup::GroupsHashtable& aInHashTable);
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSISIMPLEENUMERATOR
|
||||
|
||||
protected:
|
||||
virtual ~nsGroupsEnumerator();
|
||||
|
||||
nsresult Initialize();
|
||||
|
||||
protected:
|
||||
nsControllerCommandGroup::GroupsHashtable& mHashTable;
|
||||
int32_t mIndex;
|
||||
const char** mGroupNames; // array of pointers to char16_t* in the hash table
|
||||
bool mInitted;
|
||||
};
|
||||
|
||||
/* Implementation file */
|
||||
NS_IMPL_ISUPPORTS(nsGroupsEnumerator, nsISimpleEnumerator)
|
||||
|
||||
nsGroupsEnumerator::nsGroupsEnumerator(
|
||||
nsControllerCommandGroup::GroupsHashtable& aInHashTable)
|
||||
: mHashTable(aInHashTable)
|
||||
, mIndex(-1)
|
||||
, mGroupNames(nullptr)
|
||||
, mInitted(false)
|
||||
{
|
||||
}
|
||||
|
||||
nsGroupsEnumerator::~nsGroupsEnumerator()
|
||||
{
|
||||
delete[] mGroupNames;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGroupsEnumerator::HasMoreElements(bool* aResult)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
|
||||
if (!mInitted) {
|
||||
rv = Initialize();
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
*aResult = (mIndex < static_cast<int32_t>(mHashTable.Count()) - 1);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGroupsEnumerator::GetNext(nsISupports** aResult)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
|
||||
if (!mInitted) {
|
||||
rv = Initialize();
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
mIndex++;
|
||||
if (mIndex >= static_cast<int32_t>(mHashTable.Count())) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
const char* thisGroupName = mGroupNames[mIndex];
|
||||
|
||||
nsCOMPtr<nsISupportsCString> supportsString =
|
||||
do_CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
supportsString->SetData(nsDependentCString(thisGroupName));
|
||||
return CallQueryInterface(supportsString, aResult);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGroupsEnumerator::Initialize()
|
||||
{
|
||||
if (mInitted) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
mGroupNames = new const char*[mHashTable.Count()];
|
||||
if (!mGroupNames) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
mIndex = 0;
|
||||
for (auto iter = mHashTable.Iter(); !iter.Done(); iter.Next()) {
|
||||
mGroupNames[mIndex] = iter.Key().Data();
|
||||
mIndex++;
|
||||
}
|
||||
|
||||
mIndex = -1;
|
||||
mInitted = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
class nsNamedGroupEnumerator : public nsISimpleEnumerator
|
||||
{
|
||||
public:
|
||||
explicit nsNamedGroupEnumerator(nsTArray<nsCString>* aInArray);
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSISIMPLEENUMERATOR
|
||||
|
||||
protected:
|
||||
virtual ~nsNamedGroupEnumerator();
|
||||
|
||||
nsTArray<nsCString>* mGroupArray;
|
||||
int32_t mIndex;
|
||||
};
|
||||
|
||||
nsNamedGroupEnumerator::nsNamedGroupEnumerator(nsTArray<nsCString>* aInArray)
|
||||
: mGroupArray(aInArray)
|
||||
, mIndex(-1)
|
||||
{
|
||||
}
|
||||
|
||||
nsNamedGroupEnumerator::~nsNamedGroupEnumerator()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsNamedGroupEnumerator, nsISimpleEnumerator)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNamedGroupEnumerator::HasMoreElements(bool* aResult)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
|
||||
int32_t arrayLen = mGroupArray ? mGroupArray->Length() : 0;
|
||||
*aResult = (mIndex < arrayLen - 1);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNamedGroupEnumerator::GetNext(nsISupports** aResult)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
|
||||
if (!mGroupArray) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mIndex++;
|
||||
if (mIndex >= int32_t(mGroupArray->Length())) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
const nsCString& thisGroupName = mGroupArray->ElementAt(mIndex);
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsISupportsCString> supportsString =
|
||||
do_CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
supportsString->SetData(thisGroupName);
|
||||
return CallQueryInterface(supportsString, aResult);
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsControllerCommandGroup, nsIControllerCommandGroup)
|
||||
|
||||
nsControllerCommandGroup::nsControllerCommandGroup()
|
||||
{
|
||||
}
|
||||
|
||||
nsControllerCommandGroup::~nsControllerCommandGroup()
|
||||
{
|
||||
ClearGroupsHash();
|
||||
}
|
||||
|
||||
void
|
||||
nsControllerCommandGroup::ClearGroupsHash()
|
||||
{
|
||||
mGroupsHash.Clear();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsControllerCommandGroup::AddCommandToGroup(const char* aCommand,
|
||||
const char* aGroup)
|
||||
{
|
||||
nsDependentCString groupKey(aGroup);
|
||||
nsTArray<nsCString>* commandList = mGroupsHash.Get(groupKey);
|
||||
if (!commandList) {
|
||||
// make this list
|
||||
commandList = new AutoTArray<nsCString, 8>;
|
||||
mGroupsHash.Put(groupKey, commandList);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
nsCString* appended =
|
||||
#endif
|
||||
commandList->AppendElement(aCommand);
|
||||
NS_ASSERTION(appended, "Append failed");
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsControllerCommandGroup::RemoveCommandFromGroup(const char* aCommand,
|
||||
const char* aGroup)
|
||||
{
|
||||
nsDependentCString groupKey(aGroup);
|
||||
nsTArray<nsCString>* commandList = mGroupsHash.Get(groupKey);
|
||||
if (!commandList) {
|
||||
return NS_OK; // no group
|
||||
}
|
||||
|
||||
uint32_t numEntries = commandList->Length();
|
||||
for (uint32_t i = 0; i < numEntries; i++) {
|
||||
nsCString commandString = commandList->ElementAt(i);
|
||||
if (nsDependentCString(aCommand) != commandString) {
|
||||
commandList->RemoveElementAt(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsControllerCommandGroup::IsCommandInGroup(const char* aCommand,
|
||||
const char* aGroup, bool* aResult)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
*aResult = false;
|
||||
|
||||
nsDependentCString groupKey(aGroup);
|
||||
nsTArray<nsCString>* commandList = mGroupsHash.Get(groupKey);
|
||||
if (!commandList) {
|
||||
return NS_OK; // no group
|
||||
}
|
||||
|
||||
uint32_t numEntries = commandList->Length();
|
||||
for (uint32_t i = 0; i < numEntries; i++) {
|
||||
nsCString commandString = commandList->ElementAt(i);
|
||||
if (nsDependentCString(aCommand) != commandString) {
|
||||
*aResult = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsControllerCommandGroup::GetGroupsEnumerator(nsISimpleEnumerator** aResult)
|
||||
{
|
||||
RefPtr<nsGroupsEnumerator> groupsEnum = new nsGroupsEnumerator(mGroupsHash);
|
||||
|
||||
groupsEnum.forget(aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsControllerCommandGroup::GetEnumeratorForGroup(const char* aGroup,
|
||||
nsISimpleEnumerator** aResult)
|
||||
{
|
||||
nsDependentCString groupKey(aGroup);
|
||||
nsTArray<nsCString>* commandList = mGroupsHash.Get(groupKey); // may be null
|
||||
|
||||
RefPtr<nsNamedGroupEnumerator> theGroupEnum =
|
||||
new nsNamedGroupEnumerator(commandList);
|
||||
|
||||
theGroupEnum.forget(aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
44
embedding/components/commandhandler/nsCommandGroup.h
Normal file
44
embedding/components/commandhandler/nsCommandGroup.h
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
/* -*- 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 nsCommandGroup_h__
|
||||
#define nsCommandGroup_h__
|
||||
|
||||
#include "nsIController.h"
|
||||
#include "nsClassHashtable.h"
|
||||
#include "nsHashKeys.h"
|
||||
|
||||
// {ecd55a01-2780-11d5-a73c-ca641a6813bc}
|
||||
#define NS_CONTROLLER_COMMAND_GROUP_CID \
|
||||
{ 0xecd55a01, 0x2780, 0x11d5, { 0xa7, 0x3c, 0xca, 0x64, 0x1a, 0x68, 0x13, 0xbc } }
|
||||
|
||||
#define NS_CONTROLLER_COMMAND_GROUP_CONTRACTID \
|
||||
"@mozilla.org/embedcomp/controller-command-group;1"
|
||||
|
||||
class nsControllerCommandGroup : public nsIControllerCommandGroup
|
||||
{
|
||||
public:
|
||||
nsControllerCommandGroup();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSICONTROLLERCOMMANDGROUP
|
||||
|
||||
public:
|
||||
typedef nsClassHashtable<nsCStringHashKey, nsTArray<nsCString>>
|
||||
GroupsHashtable;
|
||||
|
||||
protected:
|
||||
virtual ~nsControllerCommandGroup();
|
||||
|
||||
void ClearGroupsHash();
|
||||
|
||||
protected:
|
||||
// Hash keyed on command group. This could be made more space-efficient,
|
||||
// maybe with atoms.
|
||||
GroupsHashtable mGroupsHash;
|
||||
};
|
||||
|
||||
#endif // nsCommandGroup_h__
|
||||
262
embedding/components/commandhandler/nsCommandManager.cpp
Normal file
262
embedding/components/commandhandler/nsCommandManager.cpp
Normal file
|
|
@ -0,0 +1,262 @@
|
|||
/* -*- 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 "nsString.h"
|
||||
|
||||
#include "nsIController.h"
|
||||
#include "nsIControllers.h"
|
||||
#include "nsIObserver.h"
|
||||
|
||||
#include "nsIComponentManager.h"
|
||||
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsPIWindowRoot.h"
|
||||
#include "nsIFocusManager.h"
|
||||
|
||||
#include "nsCOMArray.h"
|
||||
|
||||
#include "nsCommandManager.h"
|
||||
|
||||
nsCommandManager::nsCommandManager()
|
||||
: mWindow(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
nsCommandManager::~nsCommandManager()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsCommandManager)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsCommandManager)
|
||||
tmp->mObserversTable.Clear();
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsCommandManager)
|
||||
for (auto iter = tmp->mObserversTable.Iter(); !iter.Done(); iter.Next()) {
|
||||
nsCommandManager::ObserverList* observers = iter.UserData();
|
||||
int32_t numItems = observers->Length();
|
||||
for (int32_t i = 0; i < numItems; ++i) {
|
||||
cb.NoteXPCOMChild(observers->ElementAt(i));
|
||||
}
|
||||
}
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsCommandManager)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsCommandManager)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsCommandManager)
|
||||
NS_INTERFACE_MAP_ENTRY(nsICommandManager)
|
||||
NS_INTERFACE_MAP_ENTRY(nsPICommandUpdater)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsICommandManager)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCommandManager::Init(mozIDOMWindowProxy* aWindow)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aWindow);
|
||||
|
||||
mWindow = aWindow; // weak ptr
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCommandManager::CommandStatusChanged(const char* aCommandName)
|
||||
{
|
||||
ObserverList* commandObservers;
|
||||
mObserversTable.Get(aCommandName, &commandObservers);
|
||||
|
||||
if (commandObservers) {
|
||||
// XXX Should we worry about observers removing themselves from Observe()?
|
||||
int32_t i, numItems = commandObservers->Length();
|
||||
for (i = 0; i < numItems; ++i) {
|
||||
nsCOMPtr<nsIObserver> observer = commandObservers->ElementAt(i);
|
||||
// should we get the command state to pass here? This might be expensive.
|
||||
observer->Observe(NS_ISUPPORTS_CAST(nsICommandManager*, this),
|
||||
aCommandName,
|
||||
u"command_status_changed");
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#if 0
|
||||
#pragma mark -
|
||||
#endif
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCommandManager::AddCommandObserver(nsIObserver* aCommandObserver,
|
||||
const char* aCommandToObserve)
|
||||
{
|
||||
NS_ENSURE_ARG(aCommandObserver);
|
||||
|
||||
// XXX todo: handle special cases of aCommandToObserve being null, or empty
|
||||
|
||||
// for each command in the table, we make a list of observers for that command
|
||||
ObserverList* commandObservers;
|
||||
if (!mObserversTable.Get(aCommandToObserve, &commandObservers)) {
|
||||
commandObservers = new ObserverList;
|
||||
mObserversTable.Put(aCommandToObserve, commandObservers);
|
||||
}
|
||||
|
||||
// need to check that this command observer hasn't already been registered
|
||||
int32_t existingIndex = commandObservers->IndexOf(aCommandObserver);
|
||||
if (existingIndex == -1) {
|
||||
commandObservers->AppendElement(aCommandObserver);
|
||||
} else {
|
||||
NS_WARNING("Registering command observer twice on the same command");
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCommandManager::RemoveCommandObserver(nsIObserver* aCommandObserver,
|
||||
const char* aCommandObserved)
|
||||
{
|
||||
NS_ENSURE_ARG(aCommandObserver);
|
||||
|
||||
// XXX todo: handle special cases of aCommandToObserve being null, or empty
|
||||
|
||||
ObserverList* commandObservers;
|
||||
if (!mObserversTable.Get(aCommandObserved, &commandObservers)) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
commandObservers->RemoveElement(aCommandObserver);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCommandManager::IsCommandSupported(const char* aCommandName,
|
||||
mozIDOMWindowProxy* aTargetWindow,
|
||||
bool* aResult)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
|
||||
nsCOMPtr<nsIController> controller;
|
||||
GetControllerForCommand(aCommandName, aTargetWindow,
|
||||
getter_AddRefs(controller));
|
||||
*aResult = (controller.get() != nullptr);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCommandManager::IsCommandEnabled(const char* aCommandName,
|
||||
mozIDOMWindowProxy* aTargetWindow,
|
||||
bool* aResult)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
|
||||
bool commandEnabled = false;
|
||||
|
||||
nsCOMPtr<nsIController> controller;
|
||||
GetControllerForCommand(aCommandName, aTargetWindow,
|
||||
getter_AddRefs(controller));
|
||||
if (controller) {
|
||||
controller->IsCommandEnabled(aCommandName, &commandEnabled);
|
||||
}
|
||||
*aResult = commandEnabled;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCommandManager::GetCommandState(const char* aCommandName,
|
||||
mozIDOMWindowProxy* aTargetWindow,
|
||||
nsICommandParams* aCommandParams)
|
||||
{
|
||||
nsCOMPtr<nsIController> controller;
|
||||
nsAutoString tValue;
|
||||
nsresult rv = GetControllerForCommand(aCommandName, aTargetWindow,
|
||||
getter_AddRefs(controller));
|
||||
if (!controller) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsICommandController> commandController =
|
||||
do_QueryInterface(controller);
|
||||
if (commandController) {
|
||||
rv = commandController->GetCommandStateWithParams(aCommandName,
|
||||
aCommandParams);
|
||||
} else {
|
||||
rv = NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCommandManager::DoCommand(const char* aCommandName,
|
||||
nsICommandParams* aCommandParams,
|
||||
mozIDOMWindowProxy* aTargetWindow)
|
||||
{
|
||||
nsCOMPtr<nsIController> controller;
|
||||
nsresult rv = GetControllerForCommand(aCommandName, aTargetWindow,
|
||||
getter_AddRefs(controller));
|
||||
if (!controller) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsICommandController> commandController =
|
||||
do_QueryInterface(controller);
|
||||
if (commandController && aCommandParams) {
|
||||
rv = commandController->DoCommandWithParams(aCommandName, aCommandParams);
|
||||
} else {
|
||||
rv = controller->DoCommand(aCommandName);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsCommandManager::GetControllerForCommand(const char* aCommand,
|
||||
mozIDOMWindowProxy* aTargetWindow,
|
||||
nsIController** aResult)
|
||||
{
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
*aResult = nullptr;
|
||||
|
||||
// check if we're in content or chrome
|
||||
// if we're not chrome we must have a target window or we bail
|
||||
if (!nsContentUtils::LegacyIsCallerChromeOrNativeCode()) {
|
||||
if (!aTargetWindow) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// if a target window is specified, it must be the window we expect
|
||||
if (aTargetWindow != mWindow) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
if (auto* targetWindow = nsPIDOMWindowOuter::From(aTargetWindow)) {
|
||||
// get the controller for this particular window
|
||||
nsCOMPtr<nsIControllers> controllers;
|
||||
rv = targetWindow->GetControllers(getter_AddRefs(controllers));
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
if (!controllers) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// dispatch the command
|
||||
return controllers->GetControllerForCommand(aCommand, aResult);
|
||||
}
|
||||
|
||||
auto* window = nsPIDOMWindowOuter::From(mWindow);
|
||||
NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
|
||||
nsCOMPtr<nsPIWindowRoot> root = window->GetTopWindowRoot();
|
||||
NS_ENSURE_TRUE(root, NS_ERROR_FAILURE);
|
||||
|
||||
// no target window; send command to focus controller
|
||||
return root->GetControllerForCommand(aCommand, aResult);
|
||||
}
|
||||
50
embedding/components/commandhandler/nsCommandManager.h
Normal file
50
embedding/components/commandhandler/nsCommandManager.h
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/* -*- 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 nsCommandManager_h__
|
||||
#define nsCommandManager_h__
|
||||
|
||||
#include "nsString.h"
|
||||
#include "nsClassHashtable.h"
|
||||
#include "nsWeakReference.h"
|
||||
|
||||
#include "nsICommandManager.h"
|
||||
#include "nsPICommandUpdater.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
|
||||
class nsIController;
|
||||
template<class E> class nsCOMArray;
|
||||
|
||||
class nsCommandManager
|
||||
: public nsICommandManager
|
||||
, public nsPICommandUpdater
|
||||
, public nsSupportsWeakReference
|
||||
{
|
||||
public:
|
||||
typedef nsTArray<nsCOMPtr<nsIObserver> > ObserverList;
|
||||
|
||||
nsCommandManager();
|
||||
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsCommandManager, nsICommandManager)
|
||||
|
||||
NS_DECL_NSICOMMANDMANAGER
|
||||
NS_DECL_NSPICOMMANDUPDATER
|
||||
|
||||
protected:
|
||||
virtual ~nsCommandManager();
|
||||
|
||||
nsresult GetControllerForCommand(const char* aCommand,
|
||||
mozIDOMWindowProxy* aDirectedToThisWindow,
|
||||
nsIController** aResult);
|
||||
|
||||
protected:
|
||||
nsClassHashtable<nsCharPtrHashKey, ObserverList> mObserversTable;
|
||||
|
||||
mozIDOMWindowProxy* mWindow; // weak ptr. The window should always outlive us
|
||||
};
|
||||
|
||||
#endif // nsCommandManager_h__
|
||||
264
embedding/components/commandhandler/nsCommandParams.cpp
Normal file
264
embedding/components/commandhandler/nsCommandParams.cpp
Normal file
|
|
@ -0,0 +1,264 @@
|
|||
/* -*- 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 "xpcom-config.h"
|
||||
#include <new>
|
||||
#include "nscore.h"
|
||||
#include "nsCRT.h"
|
||||
|
||||
#include "nsCommandParams.h"
|
||||
#include "mozilla/HashFunctions.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
const PLDHashTableOps nsCommandParams::sHashOps =
|
||||
{
|
||||
HashKey,
|
||||
HashMatchEntry,
|
||||
HashMoveEntry,
|
||||
HashClearEntry
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsCommandParams, nsICommandParams)
|
||||
|
||||
nsCommandParams::nsCommandParams()
|
||||
: mValuesHash(&sHashOps, sizeof(HashEntry), 2)
|
||||
{
|
||||
}
|
||||
|
||||
nsCommandParams::~nsCommandParams()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCommandParams::GetValueType(const char* aName, int16_t* aRetVal)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aRetVal);
|
||||
|
||||
HashEntry* foundEntry = GetNamedEntry(aName);
|
||||
if (foundEntry) {
|
||||
*aRetVal = foundEntry->mEntryType;
|
||||
return NS_OK;
|
||||
}
|
||||
*aRetVal = eNoType;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCommandParams::GetBooleanValue(const char* aName, bool* aRetVal)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aRetVal);
|
||||
|
||||
HashEntry* foundEntry = GetNamedEntry(aName);
|
||||
if (foundEntry && foundEntry->mEntryType == eBooleanType) {
|
||||
*aRetVal = foundEntry->mData.mBoolean;
|
||||
return NS_OK;
|
||||
}
|
||||
*aRetVal = false;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCommandParams::GetLongValue(const char* aName, int32_t* aRetVal)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aRetVal);
|
||||
|
||||
HashEntry* foundEntry = GetNamedEntry(aName);
|
||||
if (foundEntry && foundEntry->mEntryType == eLongType) {
|
||||
*aRetVal = foundEntry->mData.mLong;
|
||||
return NS_OK;
|
||||
}
|
||||
*aRetVal = false;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCommandParams::GetDoubleValue(const char* aName, double* aRetVal)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aRetVal);
|
||||
|
||||
HashEntry* foundEntry = GetNamedEntry(aName);
|
||||
if (foundEntry && foundEntry->mEntryType == eDoubleType) {
|
||||
*aRetVal = foundEntry->mData.mDouble;
|
||||
return NS_OK;
|
||||
}
|
||||
*aRetVal = 0.0;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCommandParams::GetStringValue(const char* aName, nsAString& aRetVal)
|
||||
{
|
||||
HashEntry* foundEntry = GetNamedEntry(aName);
|
||||
if (foundEntry && foundEntry->mEntryType == eWStringType) {
|
||||
NS_ASSERTION(foundEntry->mData.mString, "Null string");
|
||||
aRetVal.Assign(*foundEntry->mData.mString);
|
||||
return NS_OK;
|
||||
}
|
||||
aRetVal.Truncate();
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCommandParams::GetCStringValue(const char* aName, char** aRetVal)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aRetVal);
|
||||
|
||||
HashEntry* foundEntry = GetNamedEntry(aName);
|
||||
if (foundEntry && foundEntry->mEntryType == eStringType) {
|
||||
NS_ASSERTION(foundEntry->mData.mCString, "Null string");
|
||||
*aRetVal = ToNewCString(*foundEntry->mData.mCString);
|
||||
return NS_OK;
|
||||
}
|
||||
*aRetVal = nullptr;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCommandParams::GetISupportsValue(const char* aName, nsISupports** aRetVal)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aRetVal);
|
||||
|
||||
HashEntry* foundEntry = GetNamedEntry(aName);
|
||||
if (foundEntry && foundEntry->mEntryType == eISupportsType) {
|
||||
NS_IF_ADDREF(*aRetVal = foundEntry->mISupports.get());
|
||||
return NS_OK;
|
||||
}
|
||||
*aRetVal = nullptr;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCommandParams::SetBooleanValue(const char* aName, bool aValue)
|
||||
{
|
||||
HashEntry* foundEntry = GetOrMakeEntry(aName, eBooleanType);
|
||||
if (!foundEntry) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
foundEntry->mData.mBoolean = aValue;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCommandParams::SetLongValue(const char* aName, int32_t aValue)
|
||||
{
|
||||
HashEntry* foundEntry = GetOrMakeEntry(aName, eLongType);
|
||||
if (!foundEntry) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
foundEntry->mData.mLong = aValue;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCommandParams::SetDoubleValue(const char* aName, double aValue)
|
||||
{
|
||||
HashEntry* foundEntry = GetOrMakeEntry(aName, eDoubleType);
|
||||
if (!foundEntry) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
foundEntry->mData.mDouble = aValue;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCommandParams::SetStringValue(const char* aName, const nsAString& aValue)
|
||||
{
|
||||
HashEntry* foundEntry = GetOrMakeEntry(aName, eWStringType);
|
||||
if (!foundEntry) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
foundEntry->mData.mString = new nsString(aValue);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCommandParams::SetCStringValue(const char* aName, const char* aValue)
|
||||
{
|
||||
HashEntry* foundEntry = GetOrMakeEntry(aName, eStringType);
|
||||
if (!foundEntry) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
foundEntry->mData.mCString = new nsCString(aValue);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCommandParams::SetISupportsValue(const char* aName, nsISupports* aValue)
|
||||
{
|
||||
HashEntry* foundEntry = GetOrMakeEntry(aName, eISupportsType);
|
||||
if (!foundEntry) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
foundEntry->mISupports = aValue; // addrefs
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCommandParams::RemoveValue(const char* aName)
|
||||
{
|
||||
mValuesHash.Remove((void*)aName);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCommandParams::HashEntry*
|
||||
nsCommandParams::GetNamedEntry(const char* aName)
|
||||
{
|
||||
return static_cast<HashEntry*>(mValuesHash.Search((void*)aName));
|
||||
}
|
||||
|
||||
nsCommandParams::HashEntry*
|
||||
nsCommandParams::GetOrMakeEntry(const char* aName, uint8_t aEntryType)
|
||||
{
|
||||
auto foundEntry = static_cast<HashEntry*>(mValuesHash.Search((void*)aName));
|
||||
if (foundEntry) { // reuse existing entry
|
||||
foundEntry->Reset(aEntryType);
|
||||
return foundEntry;
|
||||
}
|
||||
|
||||
foundEntry = static_cast<HashEntry*>(mValuesHash.Add((void*)aName, fallible));
|
||||
if (!foundEntry) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Use placement new. Our ctor does not clobber keyHash, which is important.
|
||||
new (foundEntry) HashEntry(aEntryType, aName);
|
||||
return foundEntry;
|
||||
}
|
||||
|
||||
PLDHashNumber
|
||||
nsCommandParams::HashKey(const void* aKey)
|
||||
{
|
||||
return HashString((const char*)aKey);
|
||||
}
|
||||
|
||||
bool
|
||||
nsCommandParams::HashMatchEntry(const PLDHashEntryHdr* aEntry, const void* aKey)
|
||||
{
|
||||
const char* keyString = (const char*)aKey;
|
||||
const HashEntry* thisEntry = static_cast<const HashEntry*>(aEntry);
|
||||
return thisEntry->mEntryName.Equals(keyString);
|
||||
}
|
||||
|
||||
void
|
||||
nsCommandParams::HashMoveEntry(PLDHashTable* aTable,
|
||||
const PLDHashEntryHdr* aFrom,
|
||||
PLDHashEntryHdr* aTo)
|
||||
{
|
||||
const HashEntry* fromEntry = static_cast<const HashEntry*>(aFrom);
|
||||
HashEntry* toEntry = static_cast<HashEntry*>(aTo);
|
||||
|
||||
new (toEntry) HashEntry(*fromEntry);
|
||||
|
||||
fromEntry->~HashEntry();
|
||||
}
|
||||
|
||||
void
|
||||
nsCommandParams::HashClearEntry(PLDHashTable* aTable, PLDHashEntryHdr* aEntry)
|
||||
{
|
||||
HashEntry* thisEntry = static_cast<HashEntry*>(aEntry);
|
||||
thisEntry->~HashEntry();
|
||||
}
|
||||
131
embedding/components/commandhandler/nsCommandParams.h
Normal file
131
embedding/components/commandhandler/nsCommandParams.h
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
/* -*- 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 nsCommandParams_h__
|
||||
#define nsCommandParams_h__
|
||||
|
||||
#include "nsString.h"
|
||||
#include "nsICommandParams.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "PLDHashTable.h"
|
||||
|
||||
class nsCommandParams : public nsICommandParams
|
||||
{
|
||||
public:
|
||||
nsCommandParams();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSICOMMANDPARAMS
|
||||
|
||||
protected:
|
||||
virtual ~nsCommandParams();
|
||||
|
||||
struct HashEntry : public PLDHashEntryHdr
|
||||
{
|
||||
nsCString mEntryName;
|
||||
|
||||
uint8_t mEntryType;
|
||||
union
|
||||
{
|
||||
bool mBoolean;
|
||||
int32_t mLong;
|
||||
double mDouble;
|
||||
nsString* mString;
|
||||
nsCString* mCString;
|
||||
} mData;
|
||||
|
||||
nsCOMPtr<nsISupports> mISupports;
|
||||
|
||||
HashEntry(uint8_t aType, const char* aEntryName)
|
||||
: mEntryName(aEntryName)
|
||||
, mEntryType(aType)
|
||||
{
|
||||
Reset(mEntryType);
|
||||
}
|
||||
|
||||
HashEntry(const HashEntry& aRHS)
|
||||
: mEntryType(aRHS.mEntryType)
|
||||
{
|
||||
Reset(mEntryType);
|
||||
switch (mEntryType) {
|
||||
case eBooleanType:
|
||||
mData.mBoolean = aRHS.mData.mBoolean;
|
||||
break;
|
||||
case eLongType:
|
||||
mData.mLong = aRHS.mData.mLong;
|
||||
break;
|
||||
case eDoubleType:
|
||||
mData.mDouble = aRHS.mData.mDouble;
|
||||
break;
|
||||
case eWStringType:
|
||||
NS_ASSERTION(aRHS.mData.mString, "Source entry has no string");
|
||||
mData.mString = new nsString(*aRHS.mData.mString);
|
||||
break;
|
||||
case eStringType:
|
||||
NS_ASSERTION(aRHS.mData.mCString, "Source entry has no string");
|
||||
mData.mCString = new nsCString(*aRHS.mData.mCString);
|
||||
break;
|
||||
case eISupportsType:
|
||||
mISupports = aRHS.mISupports.get();
|
||||
break;
|
||||
default:
|
||||
NS_ERROR("Unknown type");
|
||||
}
|
||||
}
|
||||
|
||||
~HashEntry() { Reset(eNoType); }
|
||||
|
||||
void Reset(uint8_t aNewType)
|
||||
{
|
||||
switch (mEntryType) {
|
||||
case eNoType:
|
||||
break;
|
||||
case eBooleanType:
|
||||
mData.mBoolean = false;
|
||||
break;
|
||||
case eLongType:
|
||||
mData.mLong = 0;
|
||||
break;
|
||||
case eDoubleType:
|
||||
mData.mDouble = 0.0;
|
||||
break;
|
||||
case eWStringType:
|
||||
delete mData.mString;
|
||||
mData.mString = nullptr;
|
||||
break;
|
||||
case eISupportsType:
|
||||
mISupports = nullptr;
|
||||
break;
|
||||
case eStringType:
|
||||
delete mData.mCString;
|
||||
mData.mCString = nullptr;
|
||||
break;
|
||||
default:
|
||||
NS_ERROR("Unknown type");
|
||||
}
|
||||
mEntryType = aNewType;
|
||||
}
|
||||
};
|
||||
|
||||
HashEntry* GetNamedEntry(const char* aName);
|
||||
HashEntry* GetOrMakeEntry(const char* aName, uint8_t aEntryType);
|
||||
|
||||
protected:
|
||||
static PLDHashNumber HashKey(const void* aKey);
|
||||
|
||||
static bool HashMatchEntry(const PLDHashEntryHdr* aEntry, const void* aKey);
|
||||
|
||||
static void HashMoveEntry(PLDHashTable* aTable, const PLDHashEntryHdr* aFrom,
|
||||
PLDHashEntryHdr* aTo);
|
||||
|
||||
static void HashClearEntry(PLDHashTable* aTable, PLDHashEntryHdr* aEntry);
|
||||
|
||||
PLDHashTable mValuesHash;
|
||||
|
||||
static const PLDHashTableOps sHashOps;
|
||||
};
|
||||
|
||||
#endif // nsCommandParams_h__
|
||||
209
embedding/components/commandhandler/nsControllerCommandTable.cpp
Normal file
209
embedding/components/commandhandler/nsControllerCommandTable.cpp
Normal file
|
|
@ -0,0 +1,209 @@
|
|||
/* -*- 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 "nsString.h"
|
||||
#include "nsIControllerCommand.h"
|
||||
#include "nsControllerCommandTable.h"
|
||||
|
||||
nsresult NS_NewControllerCommandTable(nsIControllerCommandTable** aResult);
|
||||
|
||||
// this value is used to size the hash table. Just a sensible upper bound
|
||||
#define NUM_COMMANDS_LENGTH 32
|
||||
|
||||
nsControllerCommandTable::nsControllerCommandTable()
|
||||
: mCommandsTable(NUM_COMMANDS_LENGTH)
|
||||
, mMutable(true)
|
||||
{
|
||||
}
|
||||
|
||||
nsControllerCommandTable::~nsControllerCommandTable()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsControllerCommandTable, nsIControllerCommandTable,
|
||||
nsISupportsWeakReference)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsControllerCommandTable::MakeImmutable(void)
|
||||
{
|
||||
mMutable = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsControllerCommandTable::RegisterCommand(const char* aCommandName,
|
||||
nsIControllerCommand* aCommand)
|
||||
{
|
||||
NS_ENSURE_TRUE(mMutable, NS_ERROR_FAILURE);
|
||||
|
||||
mCommandsTable.Put(nsDependentCString(aCommandName), aCommand);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsControllerCommandTable::UnregisterCommand(const char* aCommandName,
|
||||
nsIControllerCommand* aCommand)
|
||||
{
|
||||
NS_ENSURE_TRUE(mMutable, NS_ERROR_FAILURE);
|
||||
|
||||
nsDependentCString commandKey(aCommandName);
|
||||
if (!mCommandsTable.Get(commandKey, nullptr)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mCommandsTable.Remove(commandKey);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsControllerCommandTable::FindCommandHandler(const char* aCommandName,
|
||||
nsIControllerCommand** aResult)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
|
||||
*aResult = nullptr;
|
||||
|
||||
nsCOMPtr<nsIControllerCommand> foundCommand;
|
||||
mCommandsTable.Get(nsDependentCString(aCommandName),
|
||||
getter_AddRefs(foundCommand));
|
||||
if (!foundCommand) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
foundCommand.forget(aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsControllerCommandTable::IsCommandEnabled(const char* aCommandName,
|
||||
nsISupports* aCommandRefCon,
|
||||
bool* aResult)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
|
||||
*aResult = false;
|
||||
|
||||
nsCOMPtr<nsIControllerCommand> commandHandler;
|
||||
FindCommandHandler(aCommandName, getter_AddRefs(commandHandler));
|
||||
if (!commandHandler) {
|
||||
NS_WARNING("Controller command table asked about a command that it does "
|
||||
"not handle");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return commandHandler->IsCommandEnabled(aCommandName, aCommandRefCon,
|
||||
aResult);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsControllerCommandTable::UpdateCommandState(const char* aCommandName,
|
||||
nsISupports* aCommandRefCon)
|
||||
{
|
||||
nsCOMPtr<nsIControllerCommand> commandHandler;
|
||||
FindCommandHandler(aCommandName, getter_AddRefs(commandHandler));
|
||||
if (!commandHandler) {
|
||||
NS_WARNING("Controller command table asked to update the state of a "
|
||||
"command that it does not handle");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsControllerCommandTable::SupportsCommand(const char* aCommandName,
|
||||
nsISupports* aCommandRefCon,
|
||||
bool* aResult)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
|
||||
// XXX: need to check the readonly and disabled states
|
||||
|
||||
*aResult = false;
|
||||
|
||||
nsCOMPtr<nsIControllerCommand> commandHandler;
|
||||
FindCommandHandler(aCommandName, getter_AddRefs(commandHandler));
|
||||
|
||||
*aResult = (commandHandler.get() != nullptr);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsControllerCommandTable::DoCommand(const char* aCommandName,
|
||||
nsISupports* aCommandRefCon)
|
||||
{
|
||||
nsCOMPtr<nsIControllerCommand> commandHandler;
|
||||
FindCommandHandler(aCommandName, getter_AddRefs(commandHandler));
|
||||
if (!commandHandler) {
|
||||
NS_WARNING("Controller command table asked to do a command that it does "
|
||||
"not handle");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return commandHandler->DoCommand(aCommandName, aCommandRefCon);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsControllerCommandTable::DoCommandParams(const char* aCommandName,
|
||||
nsICommandParams* aParams,
|
||||
nsISupports* aCommandRefCon)
|
||||
{
|
||||
nsCOMPtr<nsIControllerCommand> commandHandler;
|
||||
FindCommandHandler(aCommandName, getter_AddRefs(commandHandler));
|
||||
if (!commandHandler) {
|
||||
NS_WARNING("Controller command table asked to do a command that it does "
|
||||
"not handle");
|
||||
return NS_OK;
|
||||
}
|
||||
return commandHandler->DoCommandParams(aCommandName, aParams, aCommandRefCon);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsControllerCommandTable::GetCommandState(const char* aCommandName,
|
||||
nsICommandParams* aParams,
|
||||
nsISupports* aCommandRefCon)
|
||||
{
|
||||
nsCOMPtr<nsIControllerCommand> commandHandler;
|
||||
FindCommandHandler(aCommandName, getter_AddRefs(commandHandler));
|
||||
if (!commandHandler) {
|
||||
NS_WARNING("Controller command table asked to do a command that it does "
|
||||
"not handle");
|
||||
return NS_OK;
|
||||
}
|
||||
return commandHandler->GetCommandStateParams(aCommandName, aParams,
|
||||
aCommandRefCon);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsControllerCommandTable::GetSupportedCommands(uint32_t* aCount,
|
||||
char*** aCommands)
|
||||
{
|
||||
char** commands =
|
||||
static_cast<char**>(moz_xmalloc(sizeof(char*) * mCommandsTable.Count()));
|
||||
*aCount = mCommandsTable.Count();
|
||||
*aCommands = commands;
|
||||
|
||||
for (auto iter = mCommandsTable.Iter(); !iter.Done(); iter.Next()) {
|
||||
*commands = ToNewCString(iter.Key());
|
||||
commands++;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
NS_NewControllerCommandTable(nsIControllerCommandTable** aResult)
|
||||
{
|
||||
NS_PRECONDITION(aResult != nullptr, "null ptr");
|
||||
if (!aResult) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
nsControllerCommandTable* newCommandTable = new nsControllerCommandTable();
|
||||
NS_ADDREF(newCommandTable);
|
||||
*aResult = newCommandTable;
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
/* -*- 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 nsControllerCommandTable_h_
|
||||
#define nsControllerCommandTable_h_
|
||||
|
||||
#include "nsIControllerCommandTable.h"
|
||||
#include "nsWeakReference.h"
|
||||
#include "nsInterfaceHashtable.h"
|
||||
|
||||
class nsIControllerCommand;
|
||||
|
||||
class nsControllerCommandTable final
|
||||
: public nsIControllerCommandTable
|
||||
, public nsSupportsWeakReference
|
||||
{
|
||||
public:
|
||||
nsControllerCommandTable();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSICONTROLLERCOMMANDTABLE
|
||||
|
||||
protected:
|
||||
virtual ~nsControllerCommandTable();
|
||||
|
||||
// Hash table of nsIControllerCommands, keyed by command name.
|
||||
nsInterfaceHashtable<nsCStringHashKey, nsIControllerCommand> mCommandsTable;
|
||||
|
||||
// Are we mutable?
|
||||
bool mMutable;
|
||||
};
|
||||
|
||||
#endif // nsControllerCommandTable_h_
|
||||
118
embedding/components/commandhandler/nsICommandManager.idl
Normal file
118
embedding/components/commandhandler/nsICommandManager.idl
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
/* -*- 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"
|
||||
#include "nsIObserver.idl"
|
||||
#include "nsICommandParams.idl"
|
||||
|
||||
interface mozIDOMWindowProxy;
|
||||
|
||||
/*
|
||||
* nsICommandManager is an interface used to executing user-level commands,
|
||||
* and getting the state of available commands.
|
||||
*
|
||||
* Commands are identified by strings, which are documented elsewhere.
|
||||
* In addition, the list of required and optional parameters for
|
||||
* each command, that are passed in via the nsICommandParams, are
|
||||
* also documented elsewhere. (Where? Need a good location for this).
|
||||
*/
|
||||
|
||||
|
||||
[scriptable, uuid(bb5a1730-d83b-4fa2-831b-35b9d5842e84)]
|
||||
interface nsICommandManager : nsISupports
|
||||
{
|
||||
/*
|
||||
* Register an observer on the specified command. The observer's Observe
|
||||
* method will get called when the state (enabled/disbaled, or toggled etc)
|
||||
* of the command changes.
|
||||
*
|
||||
* You can register the same observer on multiple commmands by calling this
|
||||
* multiple times.
|
||||
*/
|
||||
void addCommandObserver(in nsIObserver aCommandObserver,
|
||||
in string aCommandToObserve);
|
||||
|
||||
/*
|
||||
* Stop an observer from observering the specified command. If the observer
|
||||
* was also registered on ther commands, they will continue to be observed.
|
||||
*
|
||||
* Passing an empty string in 'aCommandObserved' will remove the observer
|
||||
* from all commands.
|
||||
*/
|
||||
void removeCommandObserver(in nsIObserver aCommandObserver,
|
||||
in string aCommandObserved);
|
||||
|
||||
/*
|
||||
* Ask the command manager if the specified command is supported.
|
||||
* If aTargetWindow is null, the focused window is used.
|
||||
*
|
||||
*/
|
||||
boolean isCommandSupported(in string aCommandName,
|
||||
in mozIDOMWindowProxy aTargetWindow);
|
||||
|
||||
/*
|
||||
* Ask the command manager if the specified command is currently.
|
||||
* enabled.
|
||||
* If aTargetWindow is null, the focused window is used.
|
||||
*/
|
||||
boolean isCommandEnabled(in string aCommandName,
|
||||
in mozIDOMWindowProxy aTargetWindow);
|
||||
|
||||
/*
|
||||
* Get the state of the specified commands.
|
||||
*
|
||||
* On input: aCommandParams filled in with values that the caller cares
|
||||
* about, most of which are command-specific (see the command documentation
|
||||
* for details). One boolean value, "enabled", applies to all commands,
|
||||
* and, in return will be set to indicate whether the command is enabled
|
||||
* (equivalent to calling isCommandEnabled).
|
||||
*
|
||||
* aCommandName is the name of the command that needs the state
|
||||
* aTargetWindow is the source of command controller
|
||||
* (null means use focus controller)
|
||||
* On output: aCommandParams: values set by the caller filled in with
|
||||
* state from the command.
|
||||
*/
|
||||
void getCommandState(in string aCommandName,
|
||||
in mozIDOMWindowProxy aTargetWindow,
|
||||
/* inout */ in nsICommandParams aCommandParams);
|
||||
|
||||
/*
|
||||
* Execute the specified command.
|
||||
* The command will be executed in aTargetWindow if it is specified.
|
||||
* If aTargetWindow is null, it will go to the focused window.
|
||||
*
|
||||
* param: aCommandParams, a list of name-value pairs of command parameters,
|
||||
* may be null for parameter-less commands.
|
||||
*
|
||||
*/
|
||||
void doCommand(in string aCommandName,
|
||||
in nsICommandParams aCommandParams,
|
||||
in mozIDOMWindowProxy aTargetWindow);
|
||||
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
|
||||
Arguments to observers "Observe" method are as follows:
|
||||
|
||||
void Observe( in nsISupports aSubject, // The nsICommandManager calling this Observer
|
||||
in string aTopic, // Name of the command
|
||||
in wstring aDummy ); // unused
|
||||
|
||||
*/
|
||||
|
||||
// {64edb481-0c04-11d5-a73c-e964b968b0bc}
|
||||
%{C++
|
||||
#define NS_COMMAND_MANAGER_CID \
|
||||
{ 0x64edb481, 0x0c04, 0x11d5, { 0xa7, 0x3c, 0xe9, 0x64, 0xb9, 0x68, 0xb0, 0xbc } }
|
||||
|
||||
#define NS_COMMAND_MANAGER_CONTRACTID \
|
||||
"@mozilla.org/embedcomp/command-manager;1"
|
||||
%}
|
||||
|
||||
|
||||
|
||||
85
embedding/components/commandhandler/nsICommandParams.idl
Normal file
85
embedding/components/commandhandler/nsICommandParams.idl
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
/* -*- 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"
|
||||
|
||||
/*
|
||||
* nsICommandParams is used to pass parameters to commands executed
|
||||
* via nsICommandManager, and to get command state.
|
||||
*
|
||||
*/
|
||||
|
||||
[scriptable, uuid(b1fdf3c4-74e3-4f7d-a14d-2b76bcf53482)]
|
||||
interface nsICommandParams : nsISupports
|
||||
{
|
||||
/*
|
||||
* List of primitive types for parameter values.
|
||||
*/
|
||||
const short eNoType = 0; /* Only used for sanity checking */
|
||||
const short eBooleanType = 1;
|
||||
const short eLongType = 2;
|
||||
const short eDoubleType = 3;
|
||||
const short eWStringType = 4;
|
||||
const short eISupportsType = 5;
|
||||
const short eStringType = 6;
|
||||
|
||||
/*
|
||||
* getValueType
|
||||
*
|
||||
* Get the type of a specified parameter
|
||||
*/
|
||||
short getValueType(in string name);
|
||||
|
||||
/*
|
||||
* get_Value
|
||||
*
|
||||
* Get the value of a specified parameter. Will return
|
||||
* an error if the parameter does not exist, or if the value
|
||||
* is of the wrong type (no coercion is performed for you).
|
||||
*
|
||||
* nsISupports values can contain any XPCOM interface,
|
||||
* as documented for the command. It is permissible
|
||||
* for it to contain nsICommandParams, but not *this*
|
||||
* one (i.e. self-containing is not allowed).
|
||||
*/
|
||||
boolean getBooleanValue(in string name);
|
||||
long getLongValue(in string name);
|
||||
double getDoubleValue(in string name);
|
||||
AString getStringValue(in string name);
|
||||
string getCStringValue(in string name);
|
||||
nsISupports getISupportsValue(in string name);
|
||||
|
||||
/*
|
||||
* set_Value
|
||||
*
|
||||
* Set the value of a specified parameter (thus creating
|
||||
* an entry for it).
|
||||
*
|
||||
* nsISupports values can contain any XPCOM interface,
|
||||
* as documented for the command. It is permissible
|
||||
* for it to contain nsICommandParams, but not *this*
|
||||
* one (i.e. self-containing is not allowed).
|
||||
*/
|
||||
void setBooleanValue(in string name, in boolean value);
|
||||
void setLongValue(in string name, in long value);
|
||||
void setDoubleValue(in string name, in double value);
|
||||
void setStringValue(in string name, in AString value);
|
||||
void setCStringValue(in string name, in string value);
|
||||
void setISupportsValue(in string name, in nsISupports value);
|
||||
|
||||
/*
|
||||
* removeValue
|
||||
*
|
||||
* Remove the specified parameter from the list.
|
||||
*/
|
||||
void removeValue(in string name);
|
||||
};
|
||||
|
||||
// {f7fa4581-238e-11d5-a73c-ab64fb68f2bc}
|
||||
%{C++
|
||||
#define NS_COMMAND_PARAMS_CID { 0xf7fa4581, 0x238e, 0x11d5, { 0xa7, 0x3c, 0xab, 0x64, 0xfb, 0x68, 0xf2, 0xbc } }
|
||||
#define NS_COMMAND_PARAMS_CONTRACTID "@mozilla.org/embedcomp/command-params;1"
|
||||
%}
|
||||
|
||||
51
embedding/components/commandhandler/nsIControllerCommand.idl
Normal file
51
embedding/components/commandhandler/nsIControllerCommand.idl
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
/* -*- 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"
|
||||
#include "nsICommandParams.idl"
|
||||
|
||||
/**
|
||||
* nsIControllerCommand
|
||||
*
|
||||
* A generic command interface. You can register an nsIControllerCommand
|
||||
* with the nsIControllerCommandTable.
|
||||
*/
|
||||
|
||||
[scriptable, uuid(0eae9a46-1dd2-11b2-aca0-9176f05fe9db)]
|
||||
interface nsIControllerCommand : nsISupports
|
||||
{
|
||||
|
||||
/**
|
||||
* Returns true if the command is currently enabled. An nsIControllerCommand
|
||||
* can implement more than one commands; say, a group of related commands
|
||||
* (e.g. delete left/delete right). Because of this, the command name is
|
||||
* passed to each method.
|
||||
*
|
||||
* @param aCommandName the name of the command for which we want the enabled
|
||||
* state.
|
||||
* @param aCommandContext a cookie held by the nsIControllerCommandTable,
|
||||
* allowing the command to get some context information.
|
||||
* The contents of this cookie are implementation-defined.
|
||||
*/
|
||||
boolean isCommandEnabled(in string aCommandName, in nsISupports aCommandContext);
|
||||
|
||||
void getCommandStateParams(in string aCommandName, in nsICommandParams aParams, in nsISupports aCommandContext);
|
||||
|
||||
/**
|
||||
* Execute the name command.
|
||||
*
|
||||
* @param aCommandName the name of the command to execute.
|
||||
*
|
||||
* @param aCommandContext a cookie held by the nsIControllerCommandTable,
|
||||
* allowing the command to get some context information.
|
||||
* The contents of this cookie are implementation-defined.
|
||||
*/
|
||||
void doCommand(in string aCommandName, in nsISupports aCommandContext);
|
||||
|
||||
void doCommandParams(in string aCommandName, in nsICommandParams aParams, in nsISupports aCommandContext);
|
||||
|
||||
};
|
||||
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
/* 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"
|
||||
#include "nsIControllerCommand.idl"
|
||||
#include "nsICommandParams.idl"
|
||||
|
||||
/**
|
||||
* nsIControllerCommandTable
|
||||
*
|
||||
* An interface via which a controller can maintain a series of commands,
|
||||
* and efficiently dispatch commands to their respective handlers.
|
||||
*
|
||||
* Controllers that use an nsIControllerCommandTable should support
|
||||
* nsIInterfaceRequestor, and be able to return an interface to their
|
||||
* controller command table via getInterface().
|
||||
*
|
||||
*/
|
||||
|
||||
[scriptable, uuid(c847f90e-b8f3-49db-a4df-8867831f2800)]
|
||||
interface nsIControllerCommandTable : nsISupports
|
||||
{
|
||||
/**
|
||||
* Make this command table immutable, so that commands cannot
|
||||
* be registered or unregistered. Some command tables are made
|
||||
* mutable after command registration so that they can be
|
||||
* used as singletons.
|
||||
*/
|
||||
void makeImmutable();
|
||||
|
||||
/**
|
||||
* Register and unregister commands with the command table.
|
||||
*
|
||||
* @param aCommandName the name of the command under which to register or
|
||||
* unregister the given command handler.
|
||||
*
|
||||
* @param aCommand the handler for this command.
|
||||
*/
|
||||
void registerCommand(in string aCommandName, in nsIControllerCommand aCommand);
|
||||
void unregisterCommand(in string aCommandName, in nsIControllerCommand aCommand);
|
||||
|
||||
/**
|
||||
* Find the command handler which has been registered to handle the named command.
|
||||
*
|
||||
* @param aCommandName the name of the command to find the handler for.
|
||||
*/
|
||||
nsIControllerCommand findCommandHandler(in string aCommandName);
|
||||
|
||||
/**
|
||||
* Get whether the named command is enabled.
|
||||
*
|
||||
* @param aCommandName the name of the command to test
|
||||
* @param aCommandRefCon the command context data
|
||||
*/
|
||||
boolean isCommandEnabled(in string aCommandName, in nsISupports aCommandRefCon);
|
||||
|
||||
/**
|
||||
* Tell the command to update its state (if it is a state updating command)
|
||||
*
|
||||
* @param aCommandName the name of the command to update
|
||||
* @param aCommandRefCon the command context data
|
||||
*/
|
||||
void updateCommandState(in string aCommandName, in nsISupports aCommandRefCon);
|
||||
|
||||
/**
|
||||
* Get whether the named command is supported.
|
||||
*
|
||||
* @param aCommandName the name of the command to test
|
||||
* @param aCommandRefCon the command context data
|
||||
*/
|
||||
boolean supportsCommand(in string aCommandName, in nsISupports aCommandRefCon);
|
||||
|
||||
/**
|
||||
* Execute the named command.
|
||||
*
|
||||
* @param aCommandName the name of the command to execute
|
||||
* @param aCommandRefCon the command context data
|
||||
*/
|
||||
void doCommand(in string aCommandName, in nsISupports aCommandRefCon);
|
||||
|
||||
void doCommandParams(in string aCommandName, in nsICommandParams aParam, in nsISupports aCommandRefCon);
|
||||
|
||||
void getCommandState(in string aCommandName, in nsICommandParams aParam, in nsISupports aCommandRefCon);
|
||||
|
||||
void getSupportedCommands(out unsigned long count,
|
||||
[array, size_is(count), retval] out string commands);
|
||||
};
|
||||
|
||||
|
||||
|
||||
%{C++
|
||||
// {670ee5da-6ad5-11d7-9950-000393636592}
|
||||
#define NS_CONTROLLERCOMMANDTABLE_CID \
|
||||
{0x670ee5da, 0x6ad5, 0x11d7, \
|
||||
{ 0x99, 0x50, 0x00, 0x03, 0x93, 0x63, 0x65, 0x92 }}
|
||||
|
||||
#define NS_CONTROLLERCOMMANDTABLE_CONTRACTID \
|
||||
"@mozilla.org/embedcomp/controller-command-table;1"
|
||||
%}
|
||||
35
embedding/components/commandhandler/nsIControllerContext.idl
Normal file
35
embedding/components/commandhandler/nsIControllerContext.idl
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
/* -*- 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"
|
||||
#include "nsIControllerCommandTable.idl"
|
||||
|
||||
[scriptable, uuid(47B82B60-A36F-4167-8072-6F421151ED50)]
|
||||
interface nsIControllerContext : nsISupports
|
||||
{
|
||||
|
||||
/**
|
||||
* Init the controller, optionally passing a controller
|
||||
* command table.
|
||||
*
|
||||
* @param aCommandTable a command table, used internally
|
||||
* by this controller. May be null, in
|
||||
* which case the controller will create
|
||||
* a new, empty table.
|
||||
*/
|
||||
void init(in nsIControllerCommandTable aCommandTable);
|
||||
|
||||
/**
|
||||
* Set a context on this controller, which is passed
|
||||
* to commands to give them some context when they execute.
|
||||
*
|
||||
* @param aCommandContext the context passed to commands.
|
||||
* Note that this is *not* addreffed by the
|
||||
* controller, and so needs to outlive it,
|
||||
* or be nulled out.
|
||||
*/
|
||||
void setCommandContext(in nsISupports aCommandContext);
|
||||
|
||||
};
|
||||
39
embedding/components/commandhandler/nsPICommandUpdater.idl
Normal file
39
embedding/components/commandhandler/nsPICommandUpdater.idl
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/* -*- 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 mozIDOMWindowProxy;
|
||||
|
||||
/*
|
||||
The nsPICommandUpdater interface is used by modules that implement
|
||||
commands, to tell the command manager that commands need updating.
|
||||
This is a private interface; embedders should not use it.
|
||||
|
||||
Command-implementing modules should get one of these by a QI
|
||||
from an nsICommandManager.
|
||||
*/
|
||||
|
||||
[scriptable, uuid(35e474ae-8016-4c34-9644-edc11f8b0ce1)]
|
||||
interface nsPICommandUpdater : nsISupports
|
||||
{
|
||||
|
||||
/*
|
||||
* Init the command updater, passing an nsIDOMWindow which
|
||||
* is the window that the command updater lives on.
|
||||
*
|
||||
*/
|
||||
void init(in mozIDOMWindowProxy aWindow);
|
||||
|
||||
/*
|
||||
* Notify the command manager that the status of a command
|
||||
* changed. It may have changed from enabled to disabled,
|
||||
* or vice versa, or become toggled etc.
|
||||
*/
|
||||
void commandStatusChanged(in string aCommandName);
|
||||
|
||||
};
|
||||
|
||||
|
||||
19
embedding/components/find/moz.build
Normal file
19
embedding/components/find/moz.build
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
# -*- 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 += [
|
||||
'nsIFind.idl',
|
||||
'nsIWebBrowserFind.idl',
|
||||
]
|
||||
|
||||
XPIDL_MODULE = 'find'
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'nsFind.cpp',
|
||||
'nsWebBrowserFind.cpp',
|
||||
]
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
1383
embedding/components/find/nsFind.cpp
Normal file
1383
embedding/components/find/nsFind.cpp
Normal file
File diff suppressed because it is too large
Load diff
83
embedding/components/find/nsFind.h
Normal file
83
embedding/components/find/nsFind.h
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
/* -*- 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 nsFind_h__
|
||||
#define nsFind_h__
|
||||
|
||||
#include "nsIFind.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsIDOMNode.h"
|
||||
#include "nsIDOMRange.h"
|
||||
#include "nsIContentIterator.h"
|
||||
#include "nsIWordBreaker.h"
|
||||
|
||||
class nsIContent;
|
||||
|
||||
#define NS_FIND_CONTRACTID "@mozilla.org/embedcomp/rangefind;1"
|
||||
|
||||
#define NS_FIND_CID \
|
||||
{0x471f4944, 0x1dd2, 0x11b2, {0x87, 0xac, 0x90, 0xbe, 0x0a, 0x51, 0xd6, 0x09}}
|
||||
|
||||
class nsFindContentIterator;
|
||||
|
||||
class nsFind : public nsIFind
|
||||
{
|
||||
public:
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_NSIFIND
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS(nsFind)
|
||||
|
||||
nsFind();
|
||||
|
||||
protected:
|
||||
virtual ~nsFind();
|
||||
|
||||
// Parameters set from the interface:
|
||||
//nsCOMPtr<nsIDOMRange> mRange; // search only in this range
|
||||
bool mFindBackward;
|
||||
bool mCaseSensitive;
|
||||
|
||||
// Use "find entire words" mode by setting to a word breaker or null, to
|
||||
// disable "entire words" mode.
|
||||
nsCOMPtr<nsIWordBreaker> mWordBreaker;
|
||||
|
||||
int32_t mIterOffset;
|
||||
nsCOMPtr<nsIDOMNode> mIterNode;
|
||||
|
||||
// Last block parent, so that we will notice crossing block boundaries:
|
||||
nsCOMPtr<nsIDOMNode> mLastBlockParent;
|
||||
nsresult GetBlockParent(nsIDOMNode* aNode, nsIDOMNode** aParent);
|
||||
|
||||
// Utility routines:
|
||||
bool IsTextNode(nsIDOMNode* aNode);
|
||||
bool IsBlockNode(nsIContent* aNode);
|
||||
bool SkipNode(nsIContent* aNode);
|
||||
bool IsVisibleNode(nsIDOMNode* aNode);
|
||||
|
||||
// Move in the right direction for our search:
|
||||
nsresult NextNode(nsIDOMRange* aSearchRange,
|
||||
nsIDOMRange* aStartPoint, nsIDOMRange* aEndPoint,
|
||||
bool aContinueOk);
|
||||
|
||||
// Get the first character from the next node (last if mFindBackward).
|
||||
char16_t PeekNextChar(nsIDOMRange* aSearchRange,
|
||||
nsIDOMRange* aStartPoint,
|
||||
nsIDOMRange* aEndPoint);
|
||||
|
||||
// Reset variables before returning -- don't hold any references.
|
||||
void ResetAll();
|
||||
|
||||
// The iterator we use to move through the document:
|
||||
nsresult InitIterator(nsIDOMNode* aStartNode, int32_t aStartOffset,
|
||||
nsIDOMNode* aEndNode, int32_t aEndOffset);
|
||||
RefPtr<nsFindContentIterator> mIterator;
|
||||
|
||||
friend class PeekNextCharRestoreState;
|
||||
};
|
||||
|
||||
#endif // nsFind_h__
|
||||
34
embedding/components/find/nsIFind.idl
Normal file
34
embedding/components/find/nsIFind.idl
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
/* -*- 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 nsIDOMRange;
|
||||
interface nsIWordBreaker;
|
||||
|
||||
[scriptable, uuid(40aba110-2a56-4678-be90-e2c17a9ae7d7)]
|
||||
interface nsIFind : nsISupports
|
||||
{
|
||||
attribute boolean findBackwards;
|
||||
attribute boolean caseSensitive;
|
||||
attribute boolean entireWord;
|
||||
|
||||
/**
|
||||
* Find some text in the current context. The implementation is
|
||||
* responsible for performing the find and highlighting the text.
|
||||
*
|
||||
* @param aPatText The text to search for.
|
||||
* @param aSearchRange A Range specifying domain of search.
|
||||
* @param aStartPoint A Range specifying search start point.
|
||||
* If not collapsed, we'll start from
|
||||
* end (forward) or start (backward).
|
||||
* @param aEndPoint A Range specifying search end point.
|
||||
* If not collapsed, we'll end at
|
||||
* end (forward) or start (backward).
|
||||
* @retval A range spanning the match that was found (or null).
|
||||
*/
|
||||
nsIDOMRange Find(in wstring aPatText, in nsIDOMRange aSearchRange,
|
||||
in nsIDOMRange aStartPoint, in nsIDOMRange aEndPoint);
|
||||
};
|
||||
145
embedding/components/find/nsIWebBrowserFind.idl
Normal file
145
embedding/components/find/nsIWebBrowserFind.idl
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
/* -*- Mode: IDL; 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"
|
||||
|
||||
#include "domstubs.idl"
|
||||
|
||||
interface mozIDOMWindowProxy;
|
||||
|
||||
/* THIS IS A PUBLIC EMBEDDING API */
|
||||
|
||||
|
||||
/**
|
||||
* nsIWebBrowserFind
|
||||
*
|
||||
* Searches for text in a web browser.
|
||||
*
|
||||
* Get one by doing a GetInterface on an nsIWebBrowser.
|
||||
*
|
||||
* By default, the implementation will search the focussed frame, or
|
||||
* if there is no focussed frame, the web browser content area. It
|
||||
* does not by default search subframes or iframes. To change this
|
||||
* behaviour, and to explicitly set the frame to search,
|
||||
* QueryInterface to nsIWebBrowserFindInFrames.
|
||||
*/
|
||||
|
||||
[scriptable, uuid(e4920136-b3e0-49e0-b1cd-6c783d2591a8)]
|
||||
interface nsIWebBrowserFind : nsISupports
|
||||
{
|
||||
/**
|
||||
* findNext
|
||||
*
|
||||
* Finds, highlights, and scrolls into view the next occurrence of the
|
||||
* search string, using the current search settings. Fails if the
|
||||
* search string is empty.
|
||||
*
|
||||
* @return Whether an occurrence was found
|
||||
*/
|
||||
boolean findNext();
|
||||
|
||||
/**
|
||||
* searchString
|
||||
*
|
||||
* The string to search for. This must be non-empty to search.
|
||||
*/
|
||||
attribute wstring searchString;
|
||||
|
||||
/**
|
||||
* findBackwards
|
||||
*
|
||||
* Whether to find backwards (towards the beginning of the document).
|
||||
* Default is false (search forward).
|
||||
*/
|
||||
attribute boolean findBackwards;
|
||||
|
||||
/**
|
||||
* wrapFind
|
||||
*
|
||||
* Whether the search wraps around to the start (or end) of the document
|
||||
* if no match was found between the current position and the end (or
|
||||
* beginning). Works correctly when searching backwards. Default is
|
||||
* false.
|
||||
*/
|
||||
attribute boolean wrapFind;
|
||||
|
||||
/**
|
||||
* entireWord
|
||||
*
|
||||
* Whether to match entire words only. Default is false.
|
||||
*/
|
||||
attribute boolean entireWord;
|
||||
|
||||
/**
|
||||
* matchCase
|
||||
*
|
||||
* Whether to match case (case sensitive) when searching. Default is false.
|
||||
*/
|
||||
attribute boolean matchCase;
|
||||
|
||||
/**
|
||||
* searchFrames
|
||||
*
|
||||
* Whether to search through all frames in the content area. Default is true.
|
||||
*
|
||||
* Note that you can control whether the search propagates into child or
|
||||
* parent frames explicitly using nsIWebBrowserFindInFrames, but if one,
|
||||
* but not both, of searchSubframes and searchParentFrames are set, this
|
||||
* returns false.
|
||||
*/
|
||||
attribute boolean searchFrames;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* nsIWebBrowserFindInFrames
|
||||
*
|
||||
* Controls how find behaves when multiple frames or iframes are present.
|
||||
*
|
||||
* Get by doing a QueryInterface from nsIWebBrowserFind.
|
||||
*/
|
||||
|
||||
[scriptable, uuid(e0f5d182-34bc-11d5-be5b-b760676c6ebc)]
|
||||
interface nsIWebBrowserFindInFrames : nsISupports
|
||||
{
|
||||
/**
|
||||
* currentSearchFrame
|
||||
*
|
||||
* Frame at which to start the search. Once the search is done, this will
|
||||
* be set to be the last frame searched, whether or not a result was found.
|
||||
* Has to be equal to or contained within the rootSearchFrame.
|
||||
*/
|
||||
attribute mozIDOMWindowProxy currentSearchFrame;
|
||||
|
||||
/**
|
||||
* rootSearchFrame
|
||||
*
|
||||
* Frame within which to confine the search (normally the content area frame).
|
||||
* Set this to only search a subtree of the frame hierarchy.
|
||||
*/
|
||||
attribute mozIDOMWindowProxy rootSearchFrame;
|
||||
|
||||
/**
|
||||
* searchSubframes
|
||||
*
|
||||
* Whether to recurse down into subframes while searching. Default is true.
|
||||
*
|
||||
* Setting nsIWebBrowserfind.searchFrames to true sets this to true.
|
||||
*/
|
||||
attribute boolean searchSubframes;
|
||||
|
||||
/**
|
||||
* searchParentFrames
|
||||
*
|
||||
* Whether to allow the search to propagate out of the currentSearchFrame into its
|
||||
* parent frame(s). Search is always confined within the rootSearchFrame. Default
|
||||
* is true.
|
||||
*
|
||||
* Setting nsIWebBrowserfind.searchFrames to true sets this to true.
|
||||
*/
|
||||
attribute boolean searchParentFrames;
|
||||
|
||||
};
|
||||
868
embedding/components/find/nsWebBrowserFind.cpp
Normal file
868
embedding/components/find/nsWebBrowserFind.cpp
Normal file
|
|
@ -0,0 +1,868 @@
|
|||
/* -*- 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 "nsWebBrowserFind.h"
|
||||
|
||||
// Only need this for NS_FIND_CONTRACTID,
|
||||
// else we could use nsIDOMRange.h and nsIFind.h.
|
||||
#include "nsFind.h"
|
||||
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsPresContext.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsISelectionController.h"
|
||||
#include "nsISelection.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsITextControlFrame.h"
|
||||
#include "nsReadableUtils.h"
|
||||
#include "nsIDOMHTMLElement.h"
|
||||
#include "nsIDOMHTMLDocument.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsContentCID.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "nsFind.h"
|
||||
#include "nsError.h"
|
||||
#include "nsFocusManager.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "nsISimpleEnumerator.h"
|
||||
#include "nsContentUtils.h"
|
||||
|
||||
#if DEBUG
|
||||
#include "nsIWebNavigation.h"
|
||||
#include "nsXPIDLString.h"
|
||||
#endif
|
||||
|
||||
nsWebBrowserFind::nsWebBrowserFind()
|
||||
: mFindBackwards(false)
|
||||
, mWrapFind(false)
|
||||
, mEntireWord(false)
|
||||
, mMatchCase(false)
|
||||
, mSearchSubFrames(true)
|
||||
, mSearchParentFrames(true)
|
||||
{
|
||||
}
|
||||
|
||||
nsWebBrowserFind::~nsWebBrowserFind()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsWebBrowserFind, nsIWebBrowserFind,
|
||||
nsIWebBrowserFindInFrames)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWebBrowserFind::FindNext(bool* aResult)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
*aResult = false;
|
||||
|
||||
NS_ENSURE_TRUE(CanFindNext(), NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
nsCOMPtr<nsPIDOMWindowOuter> searchFrame = do_QueryReferent(mCurrentSearchFrame);
|
||||
NS_ENSURE_TRUE(searchFrame, NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowOuter> rootFrame = do_QueryReferent(mRootSearchFrame);
|
||||
NS_ENSURE_TRUE(rootFrame, NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
// first, if there's a "cmd_findagain" observer around, check to see if it
|
||||
// wants to perform the find again command . If it performs the find again
|
||||
// it will return true, in which case we exit ::FindNext() early.
|
||||
// Otherwise, nsWebBrowserFind needs to perform the find again command itself
|
||||
// this is used by nsTypeAheadFind, which controls find again when it was
|
||||
// the last executed find in the current window.
|
||||
nsCOMPtr<nsIObserverService> observerSvc =
|
||||
mozilla::services::GetObserverService();
|
||||
if (observerSvc) {
|
||||
nsCOMPtr<nsISupportsInterfacePointer> windowSupportsData =
|
||||
do_CreateInstance(NS_SUPPORTS_INTERFACE_POINTER_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsCOMPtr<nsISupports> searchWindowSupports = do_QueryInterface(rootFrame);
|
||||
windowSupportsData->SetData(searchWindowSupports);
|
||||
NS_NAMED_LITERAL_STRING(dnStr, "down");
|
||||
NS_NAMED_LITERAL_STRING(upStr, "up");
|
||||
observerSvc->NotifyObservers(windowSupportsData,
|
||||
"nsWebBrowserFind_FindAgain",
|
||||
mFindBackwards ? upStr.get() : dnStr.get());
|
||||
windowSupportsData->GetData(getter_AddRefs(searchWindowSupports));
|
||||
// findnext performed if search window data cleared out
|
||||
*aResult = searchWindowSupports == nullptr;
|
||||
if (*aResult) {
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// next, look in the current frame. If found, return.
|
||||
|
||||
// Beware! This may flush notifications via synchronous
|
||||
// ScrollSelectionIntoView.
|
||||
rv = SearchInFrame(searchFrame, false, aResult);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
if (*aResult) {
|
||||
return OnFind(searchFrame); // we are done
|
||||
}
|
||||
|
||||
// if we are not searching other frames, return
|
||||
if (!mSearchSubFrames && !mSearchParentFrames) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsIDocShell* rootDocShell = rootFrame->GetDocShell();
|
||||
if (!rootDocShell) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
int32_t enumDirection = mFindBackwards ? nsIDocShell::ENUMERATE_BACKWARDS :
|
||||
nsIDocShell::ENUMERATE_FORWARDS;
|
||||
|
||||
nsCOMPtr<nsISimpleEnumerator> docShellEnumerator;
|
||||
rv = rootDocShell->GetDocShellEnumerator(nsIDocShellTreeItem::typeAll,
|
||||
enumDirection,
|
||||
getter_AddRefs(docShellEnumerator));
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// remember where we started
|
||||
nsCOMPtr<nsIDocShellTreeItem> startingItem =
|
||||
do_QueryInterface(searchFrame->GetDocShell(), &rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocShellTreeItem> curItem;
|
||||
|
||||
// XXX We should avoid searching in frameset documents here.
|
||||
// We also need to honour mSearchSubFrames and mSearchParentFrames.
|
||||
bool hasMore, doFind = false;
|
||||
while (NS_SUCCEEDED(docShellEnumerator->HasMoreElements(&hasMore)) &&
|
||||
hasMore) {
|
||||
nsCOMPtr<nsISupports> curSupports;
|
||||
rv = docShellEnumerator->GetNext(getter_AddRefs(curSupports));
|
||||
if (NS_FAILED(rv)) {
|
||||
break;
|
||||
}
|
||||
curItem = do_QueryInterface(curSupports, &rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (doFind) {
|
||||
searchFrame = curItem->GetWindow();
|
||||
if (!searchFrame) {
|
||||
break;
|
||||
}
|
||||
|
||||
OnStartSearchFrame(searchFrame);
|
||||
|
||||
// Beware! This may flush notifications via synchronous
|
||||
// ScrollSelectionIntoView.
|
||||
rv = SearchInFrame(searchFrame, false, aResult);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
if (*aResult) {
|
||||
return OnFind(searchFrame); // we are done
|
||||
}
|
||||
|
||||
OnEndSearchFrame(searchFrame);
|
||||
}
|
||||
|
||||
if (curItem.get() == startingItem.get()) {
|
||||
doFind = true; // start looking in frames after this one
|
||||
}
|
||||
}
|
||||
|
||||
if (!mWrapFind) {
|
||||
// remember where we left off
|
||||
SetCurrentSearchFrame(searchFrame);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// From here on, we're wrapping, first through the other frames, then finally
|
||||
// from the beginning of the starting frame back to the starting point.
|
||||
|
||||
// because nsISimpleEnumerator is totally lame and isn't resettable, I have to
|
||||
// make a new one
|
||||
docShellEnumerator = nullptr;
|
||||
rv = rootDocShell->GetDocShellEnumerator(nsIDocShellTreeItem::typeAll,
|
||||
enumDirection,
|
||||
getter_AddRefs(docShellEnumerator));
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
while (NS_SUCCEEDED(docShellEnumerator->HasMoreElements(&hasMore)) &&
|
||||
hasMore) {
|
||||
nsCOMPtr<nsISupports> curSupports;
|
||||
rv = docShellEnumerator->GetNext(getter_AddRefs(curSupports));
|
||||
if (NS_FAILED(rv)) {
|
||||
break;
|
||||
}
|
||||
curItem = do_QueryInterface(curSupports, &rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
break;
|
||||
}
|
||||
|
||||
searchFrame = curItem->GetWindow();
|
||||
if (!searchFrame) {
|
||||
rv = NS_ERROR_FAILURE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (curItem.get() == startingItem.get()) {
|
||||
// Beware! This may flush notifications via synchronous
|
||||
// ScrollSelectionIntoView.
|
||||
rv = SearchInFrame(searchFrame, true, aResult);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
if (*aResult) {
|
||||
return OnFind(searchFrame); // we are done
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
OnStartSearchFrame(searchFrame);
|
||||
|
||||
// Beware! This may flush notifications via synchronous
|
||||
// ScrollSelectionIntoView.
|
||||
rv = SearchInFrame(searchFrame, false, aResult);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
if (*aResult) {
|
||||
return OnFind(searchFrame); // we are done
|
||||
}
|
||||
|
||||
OnEndSearchFrame(searchFrame);
|
||||
}
|
||||
|
||||
// remember where we left off
|
||||
SetCurrentSearchFrame(searchFrame);
|
||||
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "Something failed");
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWebBrowserFind::GetSearchString(char16_t** aSearchString)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aSearchString);
|
||||
*aSearchString = ToNewUnicode(mSearchString);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWebBrowserFind::SetSearchString(const char16_t* aSearchString)
|
||||
{
|
||||
mSearchString.Assign(aSearchString);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWebBrowserFind::GetFindBackwards(bool* aFindBackwards)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aFindBackwards);
|
||||
*aFindBackwards = mFindBackwards;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWebBrowserFind::SetFindBackwards(bool aFindBackwards)
|
||||
{
|
||||
mFindBackwards = aFindBackwards;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWebBrowserFind::GetWrapFind(bool* aWrapFind)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aWrapFind);
|
||||
*aWrapFind = mWrapFind;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWebBrowserFind::SetWrapFind(bool aWrapFind)
|
||||
{
|
||||
mWrapFind = aWrapFind;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWebBrowserFind::GetEntireWord(bool* aEntireWord)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aEntireWord);
|
||||
*aEntireWord = mEntireWord;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWebBrowserFind::SetEntireWord(bool aEntireWord)
|
||||
{
|
||||
mEntireWord = aEntireWord;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWebBrowserFind::GetMatchCase(bool* aMatchCase)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aMatchCase);
|
||||
*aMatchCase = mMatchCase;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWebBrowserFind::SetMatchCase(bool aMatchCase)
|
||||
{
|
||||
mMatchCase = aMatchCase;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static bool
|
||||
IsInNativeAnonymousSubtree(nsIContent* aContent)
|
||||
{
|
||||
while (aContent) {
|
||||
nsIContent* bindingParent = aContent->GetBindingParent();
|
||||
if (bindingParent == aContent) {
|
||||
return true;
|
||||
}
|
||||
|
||||
aContent = bindingParent;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
nsWebBrowserFind::SetSelectionAndScroll(nsPIDOMWindowOuter* aWindow,
|
||||
nsIDOMRange* aRange)
|
||||
{
|
||||
nsCOMPtr<nsIDocument> doc = aWindow->GetDoc();
|
||||
if (!doc) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsIPresShell* presShell = doc->GetShell();
|
||||
if (!presShell) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMNode> node;
|
||||
aRange->GetStartContainer(getter_AddRefs(node));
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(node));
|
||||
nsIFrame* frame = content->GetPrimaryFrame();
|
||||
if (!frame) {
|
||||
return;
|
||||
}
|
||||
nsCOMPtr<nsISelectionController> selCon;
|
||||
frame->GetSelectionController(presShell->GetPresContext(),
|
||||
getter_AddRefs(selCon));
|
||||
|
||||
// since the match could be an anonymous textnode inside a
|
||||
// <textarea> or text <input>, we need to get the outer frame
|
||||
nsITextControlFrame* tcFrame = nullptr;
|
||||
for (; content; content = content->GetParent()) {
|
||||
if (!IsInNativeAnonymousSubtree(content)) {
|
||||
nsIFrame* f = content->GetPrimaryFrame();
|
||||
if (!f) {
|
||||
return;
|
||||
}
|
||||
tcFrame = do_QueryFrame(f);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISelection> selection;
|
||||
|
||||
selCon->SetDisplaySelection(nsISelectionController::SELECTION_ON);
|
||||
selCon->GetSelection(nsISelectionController::SELECTION_NORMAL,
|
||||
getter_AddRefs(selection));
|
||||
if (selection) {
|
||||
selection->RemoveAllRanges();
|
||||
selection->AddRange(aRange);
|
||||
|
||||
nsCOMPtr<nsIFocusManager> fm = do_GetService(FOCUSMANAGER_CONTRACTID);
|
||||
if (fm) {
|
||||
if (tcFrame) {
|
||||
nsCOMPtr<nsIDOMElement> newFocusedElement(do_QueryInterface(content));
|
||||
fm->SetFocus(newFocusedElement, nsIFocusManager::FLAG_NOSCROLL);
|
||||
} else {
|
||||
nsCOMPtr<nsIDOMElement> result;
|
||||
fm->MoveFocus(aWindow, nullptr, nsIFocusManager::MOVEFOCUS_CARET,
|
||||
nsIFocusManager::FLAG_NOSCROLL, getter_AddRefs(result));
|
||||
}
|
||||
}
|
||||
|
||||
// Scroll if necessary to make the selection visible:
|
||||
// Must be the last thing to do - bug 242056
|
||||
|
||||
// After ScrollSelectionIntoView(), the pending notifications might be
|
||||
// flushed and PresShell/PresContext/Frames may be dead. See bug 418470.
|
||||
selCon->ScrollSelectionIntoView(
|
||||
nsISelectionController::SELECTION_NORMAL,
|
||||
nsISelectionController::SELECTION_WHOLE_SELECTION,
|
||||
nsISelectionController::SCROLL_CENTER_VERTICALLY |
|
||||
nsISelectionController::SCROLL_SYNCHRONOUS);
|
||||
}
|
||||
}
|
||||
|
||||
// Adapted from nsTextServicesDocument::GetDocumentContentRootNode
|
||||
nsresult
|
||||
nsWebBrowserFind::GetRootNode(nsIDOMDocument* aDomDoc, nsIDOMNode** aNode)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
NS_ENSURE_ARG_POINTER(aNode);
|
||||
*aNode = 0;
|
||||
|
||||
nsCOMPtr<nsIDOMHTMLDocument> htmlDoc = do_QueryInterface(aDomDoc);
|
||||
if (htmlDoc) {
|
||||
// For HTML documents, the content root node is the body.
|
||||
nsCOMPtr<nsIDOMHTMLElement> bodyElement;
|
||||
rv = htmlDoc->GetBody(getter_AddRefs(bodyElement));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ENSURE_ARG_POINTER(bodyElement);
|
||||
bodyElement.forget(aNode);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// For non-HTML documents, the content root node will be the doc element.
|
||||
nsCOMPtr<nsIDOMElement> docElement;
|
||||
rv = aDomDoc->GetDocumentElement(getter_AddRefs(docElement));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ENSURE_ARG_POINTER(docElement);
|
||||
docElement.forget(aNode);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsWebBrowserFind::SetRangeAroundDocument(nsIDOMRange* aSearchRange,
|
||||
nsIDOMRange* aStartPt,
|
||||
nsIDOMRange* aEndPt,
|
||||
nsIDOMDocument* aDoc)
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> bodyNode;
|
||||
nsresult rv = GetRootNode(aDoc, getter_AddRefs(bodyNode));
|
||||
nsCOMPtr<nsIContent> bodyContent(do_QueryInterface(bodyNode));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ENSURE_ARG_POINTER(bodyContent);
|
||||
|
||||
uint32_t childCount = bodyContent->GetChildCount();
|
||||
|
||||
aSearchRange->SetStart(bodyNode, 0);
|
||||
aSearchRange->SetEnd(bodyNode, childCount);
|
||||
|
||||
if (mFindBackwards) {
|
||||
aStartPt->SetStart(bodyNode, childCount);
|
||||
aStartPt->SetEnd(bodyNode, childCount);
|
||||
aEndPt->SetStart(bodyNode, 0);
|
||||
aEndPt->SetEnd(bodyNode, 0);
|
||||
} else {
|
||||
aStartPt->SetStart(bodyNode, 0);
|
||||
aStartPt->SetEnd(bodyNode, 0);
|
||||
aEndPt->SetStart(bodyNode, childCount);
|
||||
aEndPt->SetEnd(bodyNode, childCount);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Set the range to go from the end of the current selection to the end of the
|
||||
// document (forward), or beginning to beginning (reverse). or around the whole
|
||||
// document if there's no selection.
|
||||
nsresult
|
||||
nsWebBrowserFind::GetSearchLimits(nsIDOMRange* aSearchRange,
|
||||
nsIDOMRange* aStartPt, nsIDOMRange* aEndPt,
|
||||
nsIDOMDocument* aDoc, nsISelection* aSel,
|
||||
bool aWrap)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aSel);
|
||||
|
||||
// There is a selection.
|
||||
int32_t count = -1;
|
||||
nsresult rv = aSel->GetRangeCount(&count);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (count < 1) {
|
||||
return SetRangeAroundDocument(aSearchRange, aStartPt, aEndPt, aDoc);
|
||||
}
|
||||
|
||||
// Need bodyNode, for the start/end of the document
|
||||
nsCOMPtr<nsIDOMNode> bodyNode;
|
||||
rv = GetRootNode(aDoc, getter_AddRefs(bodyNode));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIContent> bodyContent(do_QueryInterface(bodyNode));
|
||||
NS_ENSURE_ARG_POINTER(bodyContent);
|
||||
|
||||
uint32_t childCount = bodyContent->GetChildCount();
|
||||
|
||||
// There are four possible range endpoints we might use:
|
||||
// DocumentStart, SelectionStart, SelectionEnd, DocumentEnd.
|
||||
|
||||
nsCOMPtr<nsIDOMRange> range;
|
||||
nsCOMPtr<nsIDOMNode> node;
|
||||
int32_t offset;
|
||||
|
||||
// Forward, not wrapping: SelEnd to DocEnd
|
||||
if (!mFindBackwards && !aWrap) {
|
||||
// This isn't quite right, since the selection's ranges aren't
|
||||
// necessarily in order; but they usually will be.
|
||||
aSel->GetRangeAt(count - 1, getter_AddRefs(range));
|
||||
if (!range) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
range->GetEndContainer(getter_AddRefs(node));
|
||||
if (!node) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
range->GetEndOffset(&offset);
|
||||
|
||||
aSearchRange->SetStart(node, offset);
|
||||
aSearchRange->SetEnd(bodyNode, childCount);
|
||||
aStartPt->SetStart(node, offset);
|
||||
aStartPt->SetEnd(node, offset);
|
||||
aEndPt->SetStart(bodyNode, childCount);
|
||||
aEndPt->SetEnd(bodyNode, childCount);
|
||||
}
|
||||
// Backward, not wrapping: DocStart to SelStart
|
||||
else if (mFindBackwards && !aWrap) {
|
||||
aSel->GetRangeAt(0, getter_AddRefs(range));
|
||||
if (!range) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
range->GetStartContainer(getter_AddRefs(node));
|
||||
if (!node) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
range->GetStartOffset(&offset);
|
||||
|
||||
aSearchRange->SetStart(bodyNode, 0);
|
||||
aSearchRange->SetEnd(bodyNode, childCount);
|
||||
aStartPt->SetStart(node, offset);
|
||||
aStartPt->SetEnd(node, offset);
|
||||
aEndPt->SetStart(bodyNode, 0);
|
||||
aEndPt->SetEnd(bodyNode, 0);
|
||||
}
|
||||
// Forward, wrapping: DocStart to SelEnd
|
||||
else if (!mFindBackwards && aWrap) {
|
||||
aSel->GetRangeAt(count - 1, getter_AddRefs(range));
|
||||
if (!range) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
range->GetEndContainer(getter_AddRefs(node));
|
||||
if (!node) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
range->GetEndOffset(&offset);
|
||||
|
||||
aSearchRange->SetStart(bodyNode, 0);
|
||||
aSearchRange->SetEnd(bodyNode, childCount);
|
||||
aStartPt->SetStart(bodyNode, 0);
|
||||
aStartPt->SetEnd(bodyNode, 0);
|
||||
aEndPt->SetStart(node, offset);
|
||||
aEndPt->SetEnd(node, offset);
|
||||
}
|
||||
// Backward, wrapping: SelStart to DocEnd
|
||||
else if (mFindBackwards && aWrap) {
|
||||
aSel->GetRangeAt(0, getter_AddRefs(range));
|
||||
if (!range) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
range->GetStartContainer(getter_AddRefs(node));
|
||||
if (!node) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
range->GetStartOffset(&offset);
|
||||
|
||||
aSearchRange->SetStart(bodyNode, 0);
|
||||
aSearchRange->SetEnd(bodyNode, childCount);
|
||||
aStartPt->SetStart(bodyNode, childCount);
|
||||
aStartPt->SetEnd(bodyNode, childCount);
|
||||
aEndPt->SetStart(node, offset);
|
||||
aEndPt->SetEnd(node, offset);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWebBrowserFind::GetSearchFrames(bool* aSearchFrames)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aSearchFrames);
|
||||
// this only returns true if we are searching both sub and parent frames.
|
||||
// There is ambiguity if the caller has previously set one, but not both of
|
||||
// these.
|
||||
*aSearchFrames = mSearchSubFrames && mSearchParentFrames;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWebBrowserFind::SetSearchFrames(bool aSearchFrames)
|
||||
{
|
||||
mSearchSubFrames = aSearchFrames;
|
||||
mSearchParentFrames = aSearchFrames;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWebBrowserFind::GetCurrentSearchFrame(mozIDOMWindowProxy** aCurrentSearchFrame)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aCurrentSearchFrame);
|
||||
nsCOMPtr<mozIDOMWindowProxy> searchFrame = do_QueryReferent(mCurrentSearchFrame);
|
||||
searchFrame.forget(aCurrentSearchFrame);
|
||||
return (*aCurrentSearchFrame) ? NS_OK : NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWebBrowserFind::SetCurrentSearchFrame(mozIDOMWindowProxy* aCurrentSearchFrame)
|
||||
{
|
||||
// is it ever valid to set this to null?
|
||||
NS_ENSURE_ARG(aCurrentSearchFrame);
|
||||
mCurrentSearchFrame = do_GetWeakReference(aCurrentSearchFrame);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWebBrowserFind::GetRootSearchFrame(mozIDOMWindowProxy** aRootSearchFrame)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aRootSearchFrame);
|
||||
nsCOMPtr<mozIDOMWindowProxy> searchFrame = do_QueryReferent(mRootSearchFrame);
|
||||
searchFrame.forget(aRootSearchFrame);
|
||||
return (*aRootSearchFrame) ? NS_OK : NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWebBrowserFind::SetRootSearchFrame(mozIDOMWindowProxy* aRootSearchFrame)
|
||||
{
|
||||
// is it ever valid to set this to null?
|
||||
NS_ENSURE_ARG(aRootSearchFrame);
|
||||
mRootSearchFrame = do_GetWeakReference(aRootSearchFrame);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWebBrowserFind::GetSearchSubframes(bool* aSearchSubframes)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aSearchSubframes);
|
||||
*aSearchSubframes = mSearchSubFrames;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWebBrowserFind::SetSearchSubframes(bool aSearchSubframes)
|
||||
{
|
||||
mSearchSubFrames = aSearchSubframes;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWebBrowserFind::GetSearchParentFrames(bool* aSearchParentFrames)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aSearchParentFrames);
|
||||
*aSearchParentFrames = mSearchParentFrames;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWebBrowserFind::SetSearchParentFrames(bool aSearchParentFrames)
|
||||
{
|
||||
mSearchParentFrames = aSearchParentFrames;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
This method handles finding in a single window (aka frame).
|
||||
|
||||
*/
|
||||
nsresult
|
||||
nsWebBrowserFind::SearchInFrame(nsPIDOMWindowOuter* aWindow, bool aWrapping,
|
||||
bool* aDidFind)
|
||||
{
|
||||
NS_ENSURE_ARG(aWindow);
|
||||
NS_ENSURE_ARG_POINTER(aDidFind);
|
||||
|
||||
*aDidFind = false;
|
||||
|
||||
// Do security check, to ensure that the frame we're searching is
|
||||
// acccessible from the frame where the Find is being run.
|
||||
|
||||
// get a uri for the window
|
||||
nsCOMPtr<nsIDocument> theDoc = aWindow->GetDoc();
|
||||
if (!theDoc) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (!nsContentUtils::SubjectPrincipal()->Subsumes(theDoc->NodePrincipal())) {
|
||||
return NS_ERROR_DOM_PROP_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIFind> find = do_CreateInstance(NS_FIND_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
(void)find->SetCaseSensitive(mMatchCase);
|
||||
(void)find->SetFindBackwards(mFindBackwards);
|
||||
|
||||
(void)find->SetEntireWord(mEntireWord);
|
||||
|
||||
// Now make sure the content (for actual finding) and frame (for
|
||||
// selection) models are up to date.
|
||||
theDoc->FlushPendingNotifications(Flush_Frames);
|
||||
|
||||
nsCOMPtr<nsISelection> sel = GetFrameSelection(aWindow);
|
||||
NS_ENSURE_ARG_POINTER(sel);
|
||||
|
||||
nsCOMPtr<nsIDOMRange> searchRange = new nsRange(theDoc);
|
||||
NS_ENSURE_ARG_POINTER(searchRange);
|
||||
nsCOMPtr<nsIDOMRange> startPt = new nsRange(theDoc);
|
||||
NS_ENSURE_ARG_POINTER(startPt);
|
||||
nsCOMPtr<nsIDOMRange> endPt = new nsRange(theDoc);
|
||||
NS_ENSURE_ARG_POINTER(endPt);
|
||||
|
||||
nsCOMPtr<nsIDOMRange> foundRange;
|
||||
|
||||
nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(theDoc);
|
||||
MOZ_ASSERT(domDoc);
|
||||
|
||||
// If !aWrapping, search from selection to end
|
||||
if (!aWrapping)
|
||||
rv = GetSearchLimits(searchRange, startPt, endPt, domDoc, sel, false);
|
||||
|
||||
// If aWrapping, search the part of the starting frame
|
||||
// up to the point where we left off.
|
||||
else
|
||||
rv = GetSearchLimits(searchRange, startPt, endPt, domDoc, sel, true);
|
||||
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = find->Find(mSearchString.get(), searchRange, startPt, endPt,
|
||||
getter_AddRefs(foundRange));
|
||||
|
||||
if (NS_SUCCEEDED(rv) && foundRange) {
|
||||
*aDidFind = true;
|
||||
sel->RemoveAllRanges();
|
||||
// Beware! This may flush notifications via synchronous
|
||||
// ScrollSelectionIntoView.
|
||||
SetSelectionAndScroll(aWindow, foundRange);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
// called when we start searching a frame that is not the initial focussed
|
||||
// frame. Prepare the frame to be searched. we clear the selection, so that the
|
||||
// search starts from the top of the frame.
|
||||
nsresult
|
||||
nsWebBrowserFind::OnStartSearchFrame(nsPIDOMWindowOuter* aWindow)
|
||||
{
|
||||
return ClearFrameSelection(aWindow);
|
||||
}
|
||||
|
||||
// called when we are done searching a frame and didn't find anything, and about
|
||||
// about to start searching the next frame.
|
||||
nsresult
|
||||
nsWebBrowserFind::OnEndSearchFrame(nsPIDOMWindowOuter* aWindow)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
already_AddRefed<nsISelection>
|
||||
nsWebBrowserFind::GetFrameSelection(nsPIDOMWindowOuter* aWindow)
|
||||
{
|
||||
nsCOMPtr<nsIDocument> doc = aWindow->GetDoc();
|
||||
if (!doc) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsIPresShell* presShell = doc->GetShell();
|
||||
if (!presShell) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// text input controls have their independent selection controllers that we
|
||||
// must use when they have focus.
|
||||
nsPresContext* presContext = presShell->GetPresContext();
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowOuter> focusedWindow;
|
||||
nsCOMPtr<nsIContent> focusedContent = nsFocusManager::GetFocusedDescendant(
|
||||
aWindow, false, getter_AddRefs(focusedWindow));
|
||||
|
||||
nsIFrame* frame =
|
||||
focusedContent ? focusedContent->GetPrimaryFrame() : nullptr;
|
||||
|
||||
nsCOMPtr<nsISelectionController> selCon;
|
||||
nsCOMPtr<nsISelection> sel;
|
||||
if (frame) {
|
||||
frame->GetSelectionController(presContext, getter_AddRefs(selCon));
|
||||
selCon->GetSelection(nsISelectionController::SELECTION_NORMAL,
|
||||
getter_AddRefs(sel));
|
||||
if (sel) {
|
||||
int32_t count = -1;
|
||||
sel->GetRangeCount(&count);
|
||||
if (count > 0) {
|
||||
return sel.forget();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
selCon = do_QueryInterface(presShell);
|
||||
selCon->GetSelection(nsISelectionController::SELECTION_NORMAL,
|
||||
getter_AddRefs(sel));
|
||||
return sel.forget();
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsWebBrowserFind::ClearFrameSelection(nsPIDOMWindowOuter* aWindow)
|
||||
{
|
||||
NS_ENSURE_ARG(aWindow);
|
||||
nsCOMPtr<nsISelection> selection = GetFrameSelection(aWindow);
|
||||
if (selection) {
|
||||
selection->RemoveAllRanges();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsWebBrowserFind::OnFind(nsPIDOMWindowOuter* aFoundWindow)
|
||||
{
|
||||
SetCurrentSearchFrame(aFoundWindow);
|
||||
|
||||
// We don't want a selection to appear in two frames simultaneously
|
||||
nsCOMPtr<nsPIDOMWindowOuter> lastFocusedWindow =
|
||||
do_QueryReferent(mLastFocusedWindow);
|
||||
if (lastFocusedWindow && lastFocusedWindow != aFoundWindow) {
|
||||
ClearFrameSelection(lastFocusedWindow);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIFocusManager> fm = do_GetService(FOCUSMANAGER_CONTRACTID);
|
||||
if (fm) {
|
||||
// get the containing frame and focus it. For top-level windows, the right
|
||||
// window should already be focused.
|
||||
nsCOMPtr<nsIDOMElement> frameElement =
|
||||
do_QueryInterface(aFoundWindow->GetFrameElementInternal());
|
||||
if (frameElement) {
|
||||
fm->SetFocus(frameElement, 0);
|
||||
}
|
||||
|
||||
mLastFocusedWindow = do_GetWeakReference(aFoundWindow);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
95
embedding/components/find/nsWebBrowserFind.h
Normal file
95
embedding/components/find/nsWebBrowserFind.h
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
/* -*- 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 nsWebBrowserFindImpl_h__
|
||||
#define nsWebBrowserFindImpl_h__
|
||||
|
||||
#include "nsIWebBrowserFind.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsWeakReference.h"
|
||||
|
||||
#include "nsIFind.h"
|
||||
|
||||
#include "nsString.h"
|
||||
|
||||
#define NS_WEB_BROWSER_FIND_CONTRACTID "@mozilla.org/embedcomp/find;1"
|
||||
|
||||
#define NS_WEB_BROWSER_FIND_CID \
|
||||
{0x57cf9383, 0x3405, 0x11d5, {0xbe, 0x5b, 0xaa, 0x20, 0xfa, 0x2c, 0xf3, 0x7c}}
|
||||
|
||||
class nsISelection;
|
||||
class nsIDOMWindow;
|
||||
|
||||
class nsIDocShell;
|
||||
|
||||
//*****************************************************************************
|
||||
// class nsWebBrowserFind
|
||||
//*****************************************************************************
|
||||
|
||||
class nsWebBrowserFind
|
||||
: public nsIWebBrowserFind
|
||||
, public nsIWebBrowserFindInFrames
|
||||
{
|
||||
public:
|
||||
nsWebBrowserFind();
|
||||
|
||||
// nsISupports
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// nsIWebBrowserFind
|
||||
NS_DECL_NSIWEBBROWSERFIND
|
||||
|
||||
// nsIWebBrowserFindInFrames
|
||||
NS_DECL_NSIWEBBROWSERFINDINFRAMES
|
||||
|
||||
protected:
|
||||
virtual ~nsWebBrowserFind();
|
||||
|
||||
bool CanFindNext() { return mSearchString.Length() != 0; }
|
||||
|
||||
nsresult SearchInFrame(nsPIDOMWindowOuter* aWindow, bool aWrapping,
|
||||
bool* aDidFind);
|
||||
|
||||
nsresult OnStartSearchFrame(nsPIDOMWindowOuter* aWindow);
|
||||
nsresult OnEndSearchFrame(nsPIDOMWindowOuter* aWindow);
|
||||
|
||||
already_AddRefed<nsISelection> GetFrameSelection(nsPIDOMWindowOuter* aWindow);
|
||||
nsresult ClearFrameSelection(nsPIDOMWindowOuter* aWindow);
|
||||
|
||||
nsresult OnFind(nsPIDOMWindowOuter* aFoundWindow);
|
||||
|
||||
void SetSelectionAndScroll(nsPIDOMWindowOuter* aWindow, nsIDOMRange* aRange);
|
||||
|
||||
nsresult GetRootNode(nsIDOMDocument* aDomDoc, nsIDOMNode** aNode);
|
||||
nsresult GetSearchLimits(nsIDOMRange* aRange,
|
||||
nsIDOMRange* aStartPt, nsIDOMRange* aEndPt,
|
||||
nsIDOMDocument* aDoc, nsISelection* aSel,
|
||||
bool aWrap);
|
||||
nsresult SetRangeAroundDocument(nsIDOMRange* aSearchRange,
|
||||
nsIDOMRange* aStartPoint,
|
||||
nsIDOMRange* aEndPoint,
|
||||
nsIDOMDocument* aDoc);
|
||||
|
||||
protected:
|
||||
nsString mSearchString;
|
||||
|
||||
bool mFindBackwards;
|
||||
bool mWrapFind;
|
||||
bool mEntireWord;
|
||||
bool mMatchCase;
|
||||
|
||||
bool mSearchSubFrames;
|
||||
bool mSearchParentFrames;
|
||||
|
||||
// These are all weak because who knows if windows can go away during our
|
||||
// lifetime.
|
||||
nsWeakPtr mCurrentSearchFrame;
|
||||
nsWeakPtr mRootSearchFrame;
|
||||
nsWeakPtr mLastFocusedWindow;
|
||||
};
|
||||
|
||||
#endif
|
||||
20
embedding/components/moz.build
Normal file
20
embedding/components/moz.build
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
# -*- 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/.
|
||||
|
||||
# You'd think we could skip building ui if XUL is disabled,
|
||||
# but we need to export interface headers from those directories.
|
||||
DIRS += [
|
||||
'windowwatcher',
|
||||
'appstartup',
|
||||
'find',
|
||||
'webbrowserpersist',
|
||||
'commandhandler',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_XUL']:
|
||||
DIRS += ['printingui']
|
||||
|
||||
DIRS += ['build']
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
|
||||
/* 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 embedding {
|
||||
|
||||
protocol PPrintProgressDialog
|
||||
{
|
||||
manager PPrinting;
|
||||
|
||||
parent:
|
||||
async StateChange(long stateFlags,
|
||||
nsresult status);
|
||||
|
||||
async ProgressChange(long curSelfProgress,
|
||||
long maxSelfProgress,
|
||||
long curTotalProgress,
|
||||
long maxTotalProgress);
|
||||
|
||||
async DocTitleChange(nsString newTitle);
|
||||
|
||||
async DocURLChange(nsString newURL);
|
||||
|
||||
async __delete__();
|
||||
|
||||
child:
|
||||
async DialogOpened();
|
||||
};
|
||||
|
||||
} // namespace embedding
|
||||
} // namespace mozilla
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
|
||||
/* 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 PPrintingTypes;
|
||||
include protocol PPrinting;
|
||||
include protocol PRemotePrintJob;
|
||||
|
||||
namespace mozilla {
|
||||
namespace embedding {
|
||||
|
||||
// A PrintData for success, a failure nsresult for failure.
|
||||
union PrintDataOrNSResult
|
||||
{
|
||||
PrintData;
|
||||
nsresult;
|
||||
};
|
||||
|
||||
protocol PPrintSettingsDialog
|
||||
{
|
||||
manager PPrinting;
|
||||
|
||||
child:
|
||||
async __delete__(PrintDataOrNSResult result);
|
||||
};
|
||||
|
||||
} // namespace embedding
|
||||
} // namespace mozilla
|
||||
48
embedding/components/printingui/ipc/PPrinting.ipdl
Normal file
48
embedding/components/printingui/ipc/PPrinting.ipdl
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
|
||||
/* 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 PPrintingTypes;
|
||||
include protocol PContent;
|
||||
include protocol PBrowser;
|
||||
include protocol PPrintProgressDialog;
|
||||
include protocol PPrintSettingsDialog;
|
||||
include protocol PRemotePrintJob;
|
||||
|
||||
namespace mozilla {
|
||||
namespace embedding {
|
||||
|
||||
sync protocol PPrinting
|
||||
{
|
||||
manager PContent;
|
||||
manages PPrintProgressDialog;
|
||||
manages PPrintSettingsDialog;
|
||||
manages PRemotePrintJob;
|
||||
|
||||
parent:
|
||||
sync ShowProgress(PBrowser browser,
|
||||
PPrintProgressDialog printProgressDialog,
|
||||
nullable PRemotePrintJob remotePrintJob,
|
||||
bool isForPrinting)
|
||||
returns(bool notifyOnOpen,
|
||||
nsresult rv);
|
||||
|
||||
async ShowPrintDialog(PPrintSettingsDialog dialog,
|
||||
nullable PBrowser browser,
|
||||
PrintData settings);
|
||||
|
||||
async PPrintProgressDialog();
|
||||
async PPrintSettingsDialog();
|
||||
|
||||
sync SavePrintSettings(PrintData settings, bool usePrinterNamePrefix,
|
||||
uint32_t flags)
|
||||
returns(nsresult rv);
|
||||
|
||||
child:
|
||||
async PRemotePrintJob();
|
||||
async __delete__();
|
||||
};
|
||||
|
||||
} // namespace embedding
|
||||
} // namespace mozilla
|
||||
126
embedding/components/printingui/ipc/PPrintingTypes.ipdlh
Normal file
126
embedding/components/printingui/ipc/PPrintingTypes.ipdlh
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
|
||||
/* 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 PRemotePrintJob;
|
||||
|
||||
namespace mozilla {
|
||||
namespace embedding {
|
||||
|
||||
struct CStringKeyValue {
|
||||
nsCString key;
|
||||
nsCString value;
|
||||
};
|
||||
|
||||
struct PrintData {
|
||||
nullable PRemotePrintJob remotePrintJob;
|
||||
int32_t startPageRange;
|
||||
int32_t endPageRange;
|
||||
double edgeTop;
|
||||
double edgeLeft;
|
||||
double edgeBottom;
|
||||
double edgeRight;
|
||||
double marginTop;
|
||||
double marginLeft;
|
||||
double marginBottom;
|
||||
double marginRight;
|
||||
double unwriteableMarginTop;
|
||||
double unwriteableMarginLeft;
|
||||
double unwriteableMarginBottom;
|
||||
double unwriteableMarginRight;
|
||||
double scaling;
|
||||
bool printBGColors;
|
||||
bool printBGImages;
|
||||
short printRange;
|
||||
nsString title;
|
||||
nsString docURL;
|
||||
nsString headerStrLeft;
|
||||
nsString headerStrCenter;
|
||||
nsString headerStrRight;
|
||||
nsString footerStrLeft;
|
||||
nsString footerStrCenter;
|
||||
nsString footerStrRight;
|
||||
|
||||
short howToEnableFrameUI;
|
||||
bool isCancelled;
|
||||
short printFrameTypeUsage;
|
||||
short printFrameType;
|
||||
bool printSilent;
|
||||
bool shrinkToFit;
|
||||
bool showPrintProgress;
|
||||
|
||||
nsString paperName;
|
||||
short paperData;
|
||||
double paperWidth;
|
||||
double paperHeight;
|
||||
short paperSizeUnit;
|
||||
bool printReversed;
|
||||
bool printInColor;
|
||||
int32_t orientation;
|
||||
int32_t numCopies;
|
||||
nsString printerName;
|
||||
bool printToFile;
|
||||
nsString toFileName;
|
||||
short outputFormat;
|
||||
int32_t printPageDelay;
|
||||
int32_t resolution;
|
||||
int32_t duplex;
|
||||
bool isInitializedFromPrinter;
|
||||
bool isInitializedFromPrefs;
|
||||
int32_t optionFlags;
|
||||
|
||||
/* Windows-specific things */
|
||||
nsString driverName;
|
||||
nsString deviceName;
|
||||
double printableWidthInInches;
|
||||
double printableHeightInInches;
|
||||
bool isFramesetDocument;
|
||||
bool isFramesetFrameSelected;
|
||||
bool isIFrameSelected;
|
||||
bool isRangeSelection;
|
||||
uint8_t[] devModeData;
|
||||
|
||||
/**
|
||||
* GTK-specific things. Some of these might look like dupes of the
|
||||
* information we're already passing, but the generalized settings that
|
||||
* we hold in nsIPrintSettings don't map perfectly to GTK's GtkPrintSettings,
|
||||
* so there are some nuances. GtkPrintSettings, for example, stores both an
|
||||
* internal name for paper size, as well as the display name.
|
||||
*/
|
||||
CStringKeyValue[] GTKPrintSettings;
|
||||
|
||||
/**
|
||||
* OS X specific things.
|
||||
*/
|
||||
nsString printJobName;
|
||||
bool printAllPages;
|
||||
bool mustCollate;
|
||||
nsString disposition;
|
||||
/** TODO: Is there an "unsigned short" primitive? **/
|
||||
short pagesAcross;
|
||||
short pagesDown;
|
||||
double printTime;
|
||||
bool detailedErrorReporting;
|
||||
nsString faxNumber;
|
||||
bool addHeaderAndFooter;
|
||||
bool fileNameExtensionHidden;
|
||||
/*
|
||||
* Holds the scaling factor from the Print dialog when shrink
|
||||
* to fit is not used. This is needed by the child when it
|
||||
* isn't using remote printing. When shrink to fit is enabled
|
||||
* (default), print dialog code ensures this value is 1.0.
|
||||
*/
|
||||
float scalingFactor;
|
||||
/*
|
||||
* Scaling factor for converting from OS X native paper size
|
||||
* units to inches.
|
||||
*/
|
||||
float widthScale;
|
||||
float heightScale;
|
||||
double adjustedPaperWidth;
|
||||
double adjustedPaperHeight;
|
||||
};
|
||||
|
||||
} // namespace embedding
|
||||
} // namespace mozilla
|
||||
158
embedding/components/printingui/ipc/PrintDataUtils.cpp
Normal file
158
embedding/components/printingui/ipc/PrintDataUtils.cpp
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* vim: set sw=4 ts=8 et 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 "PrintDataUtils.h"
|
||||
#include "nsIPrintSettings.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIWebBrowserPrint.h"
|
||||
#include "nsXPIDLString.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace embedding {
|
||||
|
||||
/**
|
||||
* MockWebBrowserPrint is a mostly useless implementation of nsIWebBrowserPrint,
|
||||
* but wraps a PrintData so that it's able to return information to print
|
||||
* settings dialogs that need an nsIWebBrowserPrint to interrogate.
|
||||
*/
|
||||
|
||||
NS_IMPL_ISUPPORTS(MockWebBrowserPrint, nsIWebBrowserPrint);
|
||||
|
||||
MockWebBrowserPrint::MockWebBrowserPrint(const PrintData &aData)
|
||||
: mData(aData)
|
||||
{
|
||||
MOZ_COUNT_CTOR(MockWebBrowserPrint);
|
||||
}
|
||||
|
||||
MockWebBrowserPrint::~MockWebBrowserPrint()
|
||||
{
|
||||
MOZ_COUNT_DTOR(MockWebBrowserPrint);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MockWebBrowserPrint::GetGlobalPrintSettings(nsIPrintSettings **aGlobalPrintSettings)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MockWebBrowserPrint::GetCurrentPrintSettings(nsIPrintSettings **aCurrentPrintSettings)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MockWebBrowserPrint::GetCurrentChildDOMWindow(mozIDOMWindowProxy **aCurrentPrintSettings)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MockWebBrowserPrint::GetDoingPrint(bool *aDoingPrint)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MockWebBrowserPrint::GetDoingPrintPreview(bool *aDoingPrintPreview)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MockWebBrowserPrint::GetIsFramesetDocument(bool *aIsFramesetDocument)
|
||||
{
|
||||
*aIsFramesetDocument = mData.isFramesetDocument();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MockWebBrowserPrint::GetIsFramesetFrameSelected(bool *aIsFramesetFrameSelected)
|
||||
{
|
||||
*aIsFramesetFrameSelected = mData.isFramesetFrameSelected();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MockWebBrowserPrint::GetIsIFrameSelected(bool *aIsIFrameSelected)
|
||||
{
|
||||
*aIsIFrameSelected = mData.isIFrameSelected();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MockWebBrowserPrint::GetIsRangeSelection(bool *aIsRangeSelection)
|
||||
{
|
||||
*aIsRangeSelection = mData.isRangeSelection();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MockWebBrowserPrint::GetPrintPreviewNumPages(int32_t *aPrintPreviewNumPages)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MockWebBrowserPrint::Print(nsIPrintSettings* aThePrintSettings,
|
||||
nsIWebProgressListener* aWPListener)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MockWebBrowserPrint::PrintPreview(nsIPrintSettings* aThePrintSettings,
|
||||
mozIDOMWindowProxy* aChildDOMWin,
|
||||
nsIWebProgressListener* aWPListener)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MockWebBrowserPrint::PrintPreviewNavigate(int16_t aNavType,
|
||||
int32_t aPageNum)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MockWebBrowserPrint::Cancel()
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MockWebBrowserPrint::EnumerateDocumentNames(uint32_t* aCount,
|
||||
char16_t*** aResult)
|
||||
{
|
||||
*aCount = 0;
|
||||
*aResult = nullptr;
|
||||
|
||||
if (mData.printJobName().IsEmpty()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// The only consumer that cares about this is the OS X printing
|
||||
// dialog, and even then, it only cares about the first document
|
||||
// name. That's why we only send a single document name through
|
||||
// PrintData.
|
||||
char16_t** array = (char16_t**) moz_xmalloc(sizeof(char16_t*));
|
||||
array[0] = ToNewUnicode(mData.printJobName());
|
||||
|
||||
*aCount = 1;
|
||||
*aResult = array;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MockWebBrowserPrint::ExitPrintPreview()
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
} // namespace embedding
|
||||
} // namespace mozilla
|
||||
|
||||
39
embedding/components/printingui/ipc/PrintDataUtils.h
Normal file
39
embedding/components/printingui/ipc/PrintDataUtils.h
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* vim: set sw=4 ts=8 et 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_embedding_PrintDataUtils_h
|
||||
#define mozilla_embedding_PrintDataUtils_h
|
||||
|
||||
#include "mozilla/embedding/PPrinting.h"
|
||||
#include "nsIWebBrowserPrint.h"
|
||||
|
||||
/**
|
||||
* nsIPrintSettings and nsIWebBrowserPrint information is sent back and forth
|
||||
* across PPrinting via the PrintData struct. These are utilities for
|
||||
* manipulating PrintData that can be used on either side of the communications
|
||||
* channel.
|
||||
*/
|
||||
|
||||
namespace mozilla {
|
||||
namespace embedding {
|
||||
|
||||
class MockWebBrowserPrint final : public nsIWebBrowserPrint
|
||||
{
|
||||
public:
|
||||
explicit MockWebBrowserPrint(const PrintData &aData);
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIWEBBROWSERPRINT
|
||||
|
||||
private:
|
||||
~MockWebBrowserPrint();
|
||||
PrintData mData;
|
||||
};
|
||||
|
||||
} // namespace embedding
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
132
embedding/components/printingui/ipc/PrintProgressDialogChild.cpp
Normal file
132
embedding/components/printingui/ipc/PrintProgressDialogChild.cpp
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
/* 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 "mozilla/Unused.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "PrintProgressDialogChild.h"
|
||||
|
||||
class nsIWebProgress;
|
||||
class nsIRequest;
|
||||
|
||||
using mozilla::Unused;
|
||||
|
||||
namespace mozilla {
|
||||
namespace embedding {
|
||||
|
||||
NS_IMPL_ISUPPORTS(PrintProgressDialogChild,
|
||||
nsIWebProgressListener,
|
||||
nsIPrintProgressParams)
|
||||
|
||||
PrintProgressDialogChild::PrintProgressDialogChild(
|
||||
nsIObserver* aOpenObserver) :
|
||||
mOpenObserver(aOpenObserver)
|
||||
{
|
||||
MOZ_COUNT_CTOR(PrintProgressDialogChild);
|
||||
}
|
||||
|
||||
PrintProgressDialogChild::~PrintProgressDialogChild()
|
||||
{
|
||||
// When the printing engine stops supplying information about printing
|
||||
// progress, it'll drop references to us and destroy us. We need to signal
|
||||
// the parent to decrement its refcount, as well as prevent it from attempting
|
||||
// to contact us further.
|
||||
Unused << Send__delete__(this);
|
||||
MOZ_COUNT_DTOR(PrintProgressDialogChild);
|
||||
}
|
||||
|
||||
bool
|
||||
PrintProgressDialogChild::RecvDialogOpened()
|
||||
{
|
||||
// nsPrintEngine's observer, which we're reporting to here, doesn't care
|
||||
// what gets passed as the subject, topic or data, so we'll just send
|
||||
// nullptrs.
|
||||
mOpenObserver->Observe(nullptr, nullptr, nullptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
// nsIWebProgressListener
|
||||
|
||||
NS_IMETHODIMP
|
||||
PrintProgressDialogChild::OnStateChange(nsIWebProgress* aProgress,
|
||||
nsIRequest* aRequest,
|
||||
uint32_t aStateFlags,
|
||||
nsresult aStatus)
|
||||
{
|
||||
Unused << SendStateChange(aStateFlags, aStatus);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PrintProgressDialogChild::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
|
||||
PrintProgressDialogChild::OnLocationChange(nsIWebProgress* aProgress,
|
||||
nsIRequest* aRequest,
|
||||
nsIURI* aURI,
|
||||
uint32_t aFlags)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PrintProgressDialogChild::OnStatusChange(nsIWebProgress* aProgress,
|
||||
nsIRequest* aRequest,
|
||||
nsresult aStatus,
|
||||
const char16_t* aMessage)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PrintProgressDialogChild::OnSecurityChange(nsIWebProgress* aProgress,
|
||||
nsIRequest* aRequest,
|
||||
uint32_t aState)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsIPrintProgressParams
|
||||
|
||||
NS_IMETHODIMP PrintProgressDialogChild::GetDocTitle(char16_t* *aDocTitle)
|
||||
{
|
||||
NS_ENSURE_ARG(aDocTitle);
|
||||
|
||||
*aDocTitle = ToNewUnicode(mDocTitle);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP PrintProgressDialogChild::SetDocTitle(const char16_t* aDocTitle)
|
||||
{
|
||||
mDocTitle = aDocTitle;
|
||||
Unused << SendDocTitleChange(nsString(aDocTitle));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP PrintProgressDialogChild::GetDocURL(char16_t **aDocURL)
|
||||
{
|
||||
NS_ENSURE_ARG(aDocURL);
|
||||
|
||||
*aDocURL = ToNewUnicode(mDocURL);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP PrintProgressDialogChild::SetDocURL(const char16_t* aDocURL)
|
||||
{
|
||||
mDocURL = aDocURL;
|
||||
Unused << SendDocURLChange(nsString(aDocURL));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // namespace embedding
|
||||
} // namespace mozilla
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/* 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_embedding_PrintProgressDialogChild_h
|
||||
#define mozilla_embedding_PrintProgressDialogChild_h
|
||||
|
||||
#include "mozilla/embedding/PPrintProgressDialogChild.h"
|
||||
#include "nsIPrintProgressParams.h"
|
||||
#include "nsIWebProgressListener.h"
|
||||
|
||||
class nsIObserver;
|
||||
|
||||
namespace mozilla {
|
||||
namespace embedding {
|
||||
|
||||
class PrintProgressDialogChild final : public PPrintProgressDialogChild,
|
||||
public nsIWebProgressListener,
|
||||
public nsIPrintProgressParams
|
||||
{
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIWEBPROGRESSLISTENER
|
||||
NS_DECL_NSIPRINTPROGRESSPARAMS
|
||||
|
||||
public:
|
||||
MOZ_IMPLICIT PrintProgressDialogChild(nsIObserver* aOpenObserver);
|
||||
|
||||
virtual bool RecvDialogOpened() override;
|
||||
|
||||
private:
|
||||
virtual ~PrintProgressDialogChild();
|
||||
nsCOMPtr<nsIObserver> mOpenObserver;
|
||||
nsString mDocTitle;
|
||||
nsString mDocURL;
|
||||
};
|
||||
|
||||
} // namespace embedding
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,113 @@
|
|||
/* 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 "mozilla/Unused.h"
|
||||
#include "nsIPrintProgressParams.h"
|
||||
#include "nsIWebProgressListener.h"
|
||||
#include "PrintProgressDialogParent.h"
|
||||
|
||||
using mozilla::Unused;
|
||||
|
||||
namespace mozilla {
|
||||
namespace embedding {
|
||||
|
||||
NS_IMPL_ISUPPORTS(PrintProgressDialogParent, nsIObserver)
|
||||
|
||||
PrintProgressDialogParent::PrintProgressDialogParent() :
|
||||
mActive(true)
|
||||
{
|
||||
MOZ_COUNT_CTOR(PrintProgressDialogParent);
|
||||
}
|
||||
|
||||
PrintProgressDialogParent::~PrintProgressDialogParent()
|
||||
{
|
||||
MOZ_COUNT_DTOR(PrintProgressDialogParent);
|
||||
}
|
||||
|
||||
void
|
||||
PrintProgressDialogParent::SetWebProgressListener(nsIWebProgressListener* aListener)
|
||||
{
|
||||
mWebProgressListener = aListener;
|
||||
}
|
||||
|
||||
void
|
||||
PrintProgressDialogParent::SetPrintProgressParams(nsIPrintProgressParams* aParams)
|
||||
{
|
||||
mPrintProgressParams = aParams;
|
||||
}
|
||||
|
||||
bool
|
||||
PrintProgressDialogParent::RecvStateChange(const long& stateFlags,
|
||||
const nsresult& status)
|
||||
{
|
||||
if (mWebProgressListener) {
|
||||
mWebProgressListener->OnStateChange(nullptr, nullptr, stateFlags, status);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
PrintProgressDialogParent::RecvProgressChange(const long& curSelfProgress,
|
||||
const long& maxSelfProgress,
|
||||
const long& curTotalProgress,
|
||||
const long& maxTotalProgress)
|
||||
{
|
||||
if (mWebProgressListener) {
|
||||
mWebProgressListener->OnProgressChange(nullptr, nullptr, curSelfProgress,
|
||||
maxSelfProgress, curTotalProgress,
|
||||
maxTotalProgress);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
PrintProgressDialogParent::RecvDocTitleChange(const nsString& newTitle)
|
||||
{
|
||||
if (mPrintProgressParams) {
|
||||
mPrintProgressParams->SetDocTitle(newTitle.get());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
PrintProgressDialogParent::RecvDocURLChange(const nsString& newURL)
|
||||
{
|
||||
if (mPrintProgressParams) {
|
||||
mPrintProgressParams->SetDocURL(newURL.get());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
PrintProgressDialogParent::ActorDestroy(ActorDestroyReason aWhy)
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
PrintProgressDialogParent::Recv__delete__()
|
||||
{
|
||||
// The child has requested that we tear down the connection, so we set a
|
||||
// member to make sure we don't try to contact it after the fact.
|
||||
mActive = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// nsIObserver
|
||||
NS_IMETHODIMP
|
||||
PrintProgressDialogParent::Observe(nsISupports *aSubject, const char *aTopic,
|
||||
const char16_t *aData)
|
||||
{
|
||||
if (mActive) {
|
||||
Unused << SendDialogOpened();
|
||||
} else {
|
||||
NS_WARNING("The print progress dialog finished opening, but communications "
|
||||
"with the child have been closed.");
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
} // namespace embedding
|
||||
} // namespace mozilla
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
/* 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_embedding_PrintProgressDialogParent_h
|
||||
#define mozilla_embedding_PrintProgressDialogParent_h
|
||||
|
||||
#include "mozilla/embedding/PPrintProgressDialogParent.h"
|
||||
#include "nsIObserver.h"
|
||||
|
||||
class nsIPrintProgressParams;
|
||||
class nsIWebProgressListener;
|
||||
|
||||
namespace mozilla {
|
||||
namespace embedding {
|
||||
class PrintProgressDialogParent final : public PPrintProgressDialogParent,
|
||||
public nsIObserver
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
MOZ_IMPLICIT PrintProgressDialogParent();
|
||||
|
||||
void SetWebProgressListener(nsIWebProgressListener* aListener);
|
||||
|
||||
void SetPrintProgressParams(nsIPrintProgressParams* aParams);
|
||||
|
||||
virtual bool
|
||||
RecvStateChange(
|
||||
const long& stateFlags,
|
||||
const nsresult& status) override;
|
||||
|
||||
virtual bool
|
||||
RecvProgressChange(
|
||||
const long& curSelfProgress,
|
||||
const long& maxSelfProgress,
|
||||
const long& curTotalProgress,
|
||||
const long& maxTotalProgress) override;
|
||||
|
||||
virtual bool
|
||||
RecvDocTitleChange(const nsString& newTitle) override;
|
||||
|
||||
virtual bool
|
||||
RecvDocURLChange(const nsString& newURL) override;
|
||||
|
||||
virtual void
|
||||
ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
|
||||
virtual bool
|
||||
Recv__delete__() override;
|
||||
|
||||
private:
|
||||
virtual ~PrintProgressDialogParent();
|
||||
|
||||
nsCOMPtr<nsIWebProgressListener> mWebProgressListener;
|
||||
nsCOMPtr<nsIPrintProgressParams> mPrintProgressParams;
|
||||
bool mActive;
|
||||
};
|
||||
|
||||
} // namespace embedding
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
/* 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 "PrintSettingsDialogChild.h"
|
||||
|
||||
using mozilla::Unused;
|
||||
|
||||
namespace mozilla {
|
||||
namespace embedding {
|
||||
|
||||
PrintSettingsDialogChild::PrintSettingsDialogChild()
|
||||
: mReturned(false)
|
||||
{
|
||||
MOZ_COUNT_CTOR(PrintSettingsDialogChild);
|
||||
}
|
||||
|
||||
PrintSettingsDialogChild::~PrintSettingsDialogChild()
|
||||
{
|
||||
MOZ_COUNT_DTOR(PrintSettingsDialogChild);
|
||||
}
|
||||
|
||||
bool
|
||||
PrintSettingsDialogChild::Recv__delete__(const PrintDataOrNSResult& aData)
|
||||
{
|
||||
if (aData.type() == PrintDataOrNSResult::Tnsresult) {
|
||||
mResult = aData.get_nsresult();
|
||||
MOZ_ASSERT(NS_FAILED(mResult), "expected a failure result");
|
||||
} else {
|
||||
mResult = NS_OK;
|
||||
mData = aData.get_PrintData();
|
||||
}
|
||||
mReturned = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace embedding
|
||||
} // namespace mozilla
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
/* 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_embedding_PrintSettingsDialogChild_h
|
||||
#define mozilla_embedding_PrintSettingsDialogChild_h
|
||||
|
||||
#include "mozilla/embedding/PPrintSettingsDialogChild.h"
|
||||
namespace mozilla {
|
||||
namespace embedding {
|
||||
|
||||
class PrintSettingsDialogChild final : public PPrintSettingsDialogChild
|
||||
{
|
||||
NS_INLINE_DECL_REFCOUNTING(PrintSettingsDialogChild)
|
||||
|
||||
public:
|
||||
MOZ_IMPLICIT PrintSettingsDialogChild();
|
||||
|
||||
virtual bool Recv__delete__(const PrintDataOrNSResult& aData) override;
|
||||
|
||||
bool returned() { return mReturned; };
|
||||
nsresult result() { return mResult; };
|
||||
PrintData data() { return mData; };
|
||||
|
||||
private:
|
||||
virtual ~PrintSettingsDialogChild();
|
||||
bool mReturned;
|
||||
nsresult mResult;
|
||||
PrintData mData;
|
||||
};
|
||||
|
||||
} // namespace embedding
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
/* 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 "PrintSettingsDialogParent.h"
|
||||
|
||||
// C++ file contents
|
||||
namespace mozilla {
|
||||
namespace embedding {
|
||||
|
||||
PrintSettingsDialogParent::PrintSettingsDialogParent()
|
||||
{
|
||||
MOZ_COUNT_CTOR(PrintSettingsDialogParent);
|
||||
}
|
||||
|
||||
PrintSettingsDialogParent::~PrintSettingsDialogParent()
|
||||
{
|
||||
MOZ_COUNT_DTOR(PrintSettingsDialogParent);
|
||||
}
|
||||
|
||||
void
|
||||
PrintSettingsDialogParent::ActorDestroy(ActorDestroyReason aWhy)
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace embedding
|
||||
} // namespace mozilla
|
||||
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
/* 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_embedding_PrintSettingsDialogParent_h
|
||||
#define mozilla_embedding_PrintSettingsDialogParent_h
|
||||
|
||||
#include "mozilla/embedding/PPrintSettingsDialogParent.h"
|
||||
|
||||
// Header file contents
|
||||
namespace mozilla {
|
||||
namespace embedding {
|
||||
|
||||
class PrintSettingsDialogParent final : public PPrintSettingsDialogParent
|
||||
{
|
||||
public:
|
||||
virtual void
|
||||
ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
|
||||
MOZ_IMPLICIT PrintSettingsDialogParent();
|
||||
|
||||
private:
|
||||
virtual ~PrintSettingsDialogParent();
|
||||
};
|
||||
|
||||
} // namespace embedding
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
336
embedding/components/printingui/ipc/PrintingParent.cpp
Normal file
336
embedding/components/printingui/ipc/PrintingParent.cpp
Normal file
|
|
@ -0,0 +1,336 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* 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 "mozilla/dom/Element.h"
|
||||
#include "mozilla/dom/TabParent.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/Unused.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "nsIPrintingPromptService.h"
|
||||
#include "nsIPrintProgressParams.h"
|
||||
#include "nsIPrintSettingsService.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsIWebProgressListener.h"
|
||||
#include "PrintingParent.h"
|
||||
#include "PrintDataUtils.h"
|
||||
#include "PrintProgressDialogParent.h"
|
||||
#include "PrintSettingsDialogParent.h"
|
||||
#include "mozilla/layout/RemotePrintJobParent.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
using namespace mozilla::layout;
|
||||
|
||||
namespace mozilla {
|
||||
namespace embedding {
|
||||
bool
|
||||
PrintingParent::RecvShowProgress(PBrowserParent* parent,
|
||||
PPrintProgressDialogParent* printProgressDialog,
|
||||
PRemotePrintJobParent* remotePrintJob,
|
||||
const bool& isForPrinting,
|
||||
bool* notifyOnOpen,
|
||||
nsresult* result)
|
||||
{
|
||||
*result = NS_ERROR_FAILURE;
|
||||
*notifyOnOpen = false;
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowOuter> parentWin = DOMWindowFromBrowserParent(parent);
|
||||
if (!parentWin) {
|
||||
return true;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPrintingPromptService> pps(do_GetService("@mozilla.org/embedcomp/printingprompt-service;1"));
|
||||
|
||||
if (!pps) {
|
||||
return true;
|
||||
}
|
||||
|
||||
PrintProgressDialogParent* dialogParent =
|
||||
static_cast<PrintProgressDialogParent*>(printProgressDialog);
|
||||
nsCOMPtr<nsIObserver> observer = do_QueryInterface(dialogParent);
|
||||
|
||||
nsCOMPtr<nsIWebProgressListener> printProgressListener;
|
||||
nsCOMPtr<nsIPrintProgressParams> printProgressParams;
|
||||
|
||||
*result = pps->ShowProgress(parentWin, nullptr, nullptr, observer,
|
||||
isForPrinting,
|
||||
getter_AddRefs(printProgressListener),
|
||||
getter_AddRefs(printProgressParams),
|
||||
notifyOnOpen);
|
||||
NS_ENSURE_SUCCESS(*result, true);
|
||||
|
||||
if (remotePrintJob) {
|
||||
// If we have a RemotePrintJob use that as a more general forwarder for
|
||||
// print progress listeners.
|
||||
static_cast<RemotePrintJobParent*>(remotePrintJob)
|
||||
->RegisterListener(printProgressListener);
|
||||
} else {
|
||||
dialogParent->SetWebProgressListener(printProgressListener);
|
||||
}
|
||||
|
||||
dialogParent->SetPrintProgressParams(printProgressParams);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
nsresult
|
||||
PrintingParent::ShowPrintDialog(PBrowserParent* aParent,
|
||||
const PrintData& aData,
|
||||
PrintData* aResult)
|
||||
{
|
||||
// If aParent is null this call is just being used to get print settings from
|
||||
// the printer for print preview.
|
||||
bool isPrintPreview = !aParent;
|
||||
nsCOMPtr<nsPIDOMWindowOuter> parentWin;
|
||||
if (aParent) {
|
||||
parentWin = DOMWindowFromBrowserParent(aParent);
|
||||
if (!parentWin) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPrintingPromptService> pps(do_GetService("@mozilla.org/embedcomp/printingprompt-service;1"));
|
||||
if (!pps) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// The initSettings we got can be wrapped using
|
||||
// PrintDataUtils' MockWebBrowserPrint, which implements enough of
|
||||
// nsIWebBrowserPrint to keep the dialogs happy.
|
||||
nsCOMPtr<nsIWebBrowserPrint> wbp = new MockWebBrowserPrint(aData);
|
||||
|
||||
// Use the existing RemotePrintJob and its settings, if we have one, to make
|
||||
// sure they stay current.
|
||||
RemotePrintJobParent* remotePrintJob =
|
||||
static_cast<RemotePrintJobParent*>(aData.remotePrintJobParent());
|
||||
nsCOMPtr<nsIPrintSettings> settings;
|
||||
nsresult rv;
|
||||
if (remotePrintJob) {
|
||||
settings = remotePrintJob->GetPrintSettings();
|
||||
} else {
|
||||
rv = mPrintSettingsSvc->GetNewPrintSettings(getter_AddRefs(settings));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
// We only want to use the print silently setting from the parent.
|
||||
bool printSilently;
|
||||
rv = settings->GetPrintSilent(&printSilently);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = mPrintSettingsSvc->DeserializeToPrintSettings(aData, settings);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = settings->SetPrintSilent(printSilently);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// If this is for print preview or we are printing silently then we just need
|
||||
// to initialize the print settings with anything specific from the printer.
|
||||
if (isPrintPreview || printSilently ||
|
||||
Preferences::GetBool("print.always_print_silent", printSilently)) {
|
||||
nsXPIDLString printerName;
|
||||
rv = settings->GetPrinterName(getter_Copies(printerName));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
settings->SetIsInitializedFromPrinter(false);
|
||||
mPrintSettingsSvc->InitPrintSettingsFromPrinter(printerName, settings);
|
||||
} else {
|
||||
rv = pps->ShowPrintDialog(parentWin, wbp, settings);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
if (isPrintPreview) {
|
||||
// For print preview we don't want a RemotePrintJob just the settings.
|
||||
rv = mPrintSettingsSvc->SerializeToPrintData(settings, nullptr, aResult);
|
||||
} else {
|
||||
rv = SerializeAndEnsureRemotePrintJob(settings, nullptr, remotePrintJob,
|
||||
aResult);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
bool
|
||||
PrintingParent::RecvShowPrintDialog(PPrintSettingsDialogParent* aDialog,
|
||||
PBrowserParent* aParent,
|
||||
const PrintData& aData)
|
||||
{
|
||||
PrintData resultData;
|
||||
nsresult rv = ShowPrintDialog(aParent, aData, &resultData);
|
||||
|
||||
// The child has been spinning an event loop while waiting
|
||||
// to hear about the print settings. We return the results
|
||||
// with an async message which frees the child process from
|
||||
// its nested event loop.
|
||||
if (NS_FAILED(rv)) {
|
||||
mozilla::Unused << aDialog->Send__delete__(aDialog, rv);
|
||||
} else {
|
||||
mozilla::Unused << aDialog->Send__delete__(aDialog, resultData);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
PrintingParent::RecvSavePrintSettings(const PrintData& aData,
|
||||
const bool& aUsePrinterNamePrefix,
|
||||
const uint32_t& aFlags,
|
||||
nsresult* aResult)
|
||||
{
|
||||
nsCOMPtr<nsIPrintSettings> settings;
|
||||
*aResult = mPrintSettingsSvc->GetNewPrintSettings(getter_AddRefs(settings));
|
||||
NS_ENSURE_SUCCESS(*aResult, true);
|
||||
|
||||
*aResult = mPrintSettingsSvc->DeserializeToPrintSettings(aData, settings);
|
||||
NS_ENSURE_SUCCESS(*aResult, true);
|
||||
|
||||
*aResult = mPrintSettingsSvc->SavePrintSettingsToPrefs(settings,
|
||||
aUsePrinterNamePrefix,
|
||||
aFlags);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
PPrintProgressDialogParent*
|
||||
PrintingParent::AllocPPrintProgressDialogParent()
|
||||
{
|
||||
PrintProgressDialogParent* actor = new PrintProgressDialogParent();
|
||||
NS_ADDREF(actor); // De-ref'd in the __delete__ handler for
|
||||
// PrintProgressDialogParent.
|
||||
return actor;
|
||||
}
|
||||
|
||||
bool
|
||||
PrintingParent::DeallocPPrintProgressDialogParent(PPrintProgressDialogParent* doomed)
|
||||
{
|
||||
// We can't just delete the PrintProgressDialogParent since somebody might
|
||||
// still be holding a reference to it as nsIObserver, so just decrement the
|
||||
// refcount instead.
|
||||
PrintProgressDialogParent* actor = static_cast<PrintProgressDialogParent*>(doomed);
|
||||
NS_RELEASE(actor);
|
||||
return true;
|
||||
}
|
||||
|
||||
PPrintSettingsDialogParent*
|
||||
PrintingParent::AllocPPrintSettingsDialogParent()
|
||||
{
|
||||
return new PrintSettingsDialogParent();
|
||||
}
|
||||
|
||||
bool
|
||||
PrintingParent::DeallocPPrintSettingsDialogParent(PPrintSettingsDialogParent* aDoomed)
|
||||
{
|
||||
delete aDoomed;
|
||||
return true;
|
||||
}
|
||||
|
||||
PRemotePrintJobParent*
|
||||
PrintingParent::AllocPRemotePrintJobParent()
|
||||
{
|
||||
MOZ_ASSERT_UNREACHABLE("No default constructors for implementations.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
PrintingParent::DeallocPRemotePrintJobParent(PRemotePrintJobParent* aDoomed)
|
||||
{
|
||||
delete aDoomed;
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
PrintingParent::ActorDestroy(ActorDestroyReason aWhy)
|
||||
{
|
||||
}
|
||||
|
||||
nsPIDOMWindowOuter*
|
||||
PrintingParent::DOMWindowFromBrowserParent(PBrowserParent* parent)
|
||||
{
|
||||
if (!parent) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
TabParent* tabParent = TabParent::GetFrom(parent);
|
||||
if (!tabParent) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<Element> frameElement = tabParent->GetOwnerElement();
|
||||
if (!frameElement) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIContent> frame(do_QueryInterface(frameElement));
|
||||
if (!frame) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowOuter> parentWin = frame->OwnerDoc()->GetWindow();
|
||||
if (!parentWin) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return parentWin;
|
||||
}
|
||||
|
||||
nsresult
|
||||
PrintingParent::SerializeAndEnsureRemotePrintJob(
|
||||
nsIPrintSettings* aPrintSettings, nsIWebProgressListener* aListener,
|
||||
layout::RemotePrintJobParent* aRemotePrintJob, PrintData* aPrintData)
|
||||
{
|
||||
MOZ_ASSERT(aPrintData);
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIPrintSettings> printSettings;
|
||||
if (aPrintSettings) {
|
||||
printSettings = aPrintSettings;
|
||||
} else {
|
||||
rv = mPrintSettingsSvc->GetNewPrintSettings(getter_AddRefs(printSettings));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
rv = mPrintSettingsSvc->SerializeToPrintData(printSettings, nullptr,
|
||||
aPrintData);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
RemotePrintJobParent* remotePrintJob;
|
||||
if (aRemotePrintJob) {
|
||||
remotePrintJob = aRemotePrintJob;
|
||||
aPrintData->remotePrintJobParent() = remotePrintJob;
|
||||
} else {
|
||||
remotePrintJob = new RemotePrintJobParent(aPrintSettings);
|
||||
aPrintData->remotePrintJobParent() =
|
||||
SendPRemotePrintJobConstructor(remotePrintJob);
|
||||
}
|
||||
if (aListener) {
|
||||
remotePrintJob->RegisterListener(aListener);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PrintingParent::PrintingParent()
|
||||
{
|
||||
MOZ_COUNT_CTOR(PrintingParent);
|
||||
|
||||
mPrintSettingsSvc =
|
||||
do_GetService("@mozilla.org/gfx/printsettings-service;1");
|
||||
MOZ_ASSERT(mPrintSettingsSvc);
|
||||
}
|
||||
|
||||
PrintingParent::~PrintingParent()
|
||||
{
|
||||
MOZ_COUNT_DTOR(PrintingParent);
|
||||
}
|
||||
|
||||
} // namespace embedding
|
||||
} // namespace mozilla
|
||||
|
||||
109
embedding/components/printingui/ipc/PrintingParent.h
Normal file
109
embedding/components/printingui/ipc/PrintingParent.h
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* vim: set sw=4 ts=8 et 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_embedding_PrintingParent_h
|
||||
#define mozilla_embedding_PrintingParent_h
|
||||
|
||||
#include "mozilla/dom/PBrowserParent.h"
|
||||
#include "mozilla/embedding/PPrintingParent.h"
|
||||
|
||||
class nsIPrintSettingsService;
|
||||
class nsIWebProgressListener;
|
||||
class nsPIDOMWindowOuter;
|
||||
class PPrintProgressDialogParent;
|
||||
class PPrintSettingsDialogParent;
|
||||
|
||||
namespace mozilla {
|
||||
namespace layout {
|
||||
class PRemotePrintJobParent;
|
||||
class RemotePrintJobParent;
|
||||
}
|
||||
|
||||
namespace embedding {
|
||||
|
||||
class PrintingParent final : public PPrintingParent
|
||||
{
|
||||
public:
|
||||
NS_INLINE_DECL_REFCOUNTING(PrintingParent)
|
||||
|
||||
virtual bool
|
||||
RecvShowProgress(PBrowserParent* parent,
|
||||
PPrintProgressDialogParent* printProgressDialog,
|
||||
PRemotePrintJobParent* remotePrintJob,
|
||||
const bool& isForPrinting,
|
||||
bool* notifyOnOpen,
|
||||
nsresult* result);
|
||||
virtual bool
|
||||
RecvShowPrintDialog(PPrintSettingsDialogParent* aDialog,
|
||||
PBrowserParent* aParent,
|
||||
const PrintData& aData);
|
||||
|
||||
virtual bool
|
||||
RecvSavePrintSettings(const PrintData& data,
|
||||
const bool& usePrinterNamePrefix,
|
||||
const uint32_t& flags,
|
||||
nsresult* rv);
|
||||
|
||||
virtual PPrintProgressDialogParent*
|
||||
AllocPPrintProgressDialogParent();
|
||||
|
||||
virtual bool
|
||||
DeallocPPrintProgressDialogParent(PPrintProgressDialogParent* aActor);
|
||||
|
||||
virtual PPrintSettingsDialogParent*
|
||||
AllocPPrintSettingsDialogParent();
|
||||
|
||||
virtual bool
|
||||
DeallocPPrintSettingsDialogParent(PPrintSettingsDialogParent* aActor);
|
||||
|
||||
virtual PRemotePrintJobParent*
|
||||
AllocPRemotePrintJobParent();
|
||||
|
||||
virtual bool
|
||||
DeallocPRemotePrintJobParent(PRemotePrintJobParent* aActor);
|
||||
|
||||
virtual void
|
||||
ActorDestroy(ActorDestroyReason aWhy);
|
||||
|
||||
MOZ_IMPLICIT PrintingParent();
|
||||
|
||||
/**
|
||||
* Serialize nsIPrintSettings to PrintData ready for sending to a child
|
||||
* process. A RemotePrintJob will be created and added to the PrintData.
|
||||
* An optional progress listener can be given, which will be registered
|
||||
* with the RemotePrintJob, so that progress can be tracked in the parent.
|
||||
*
|
||||
* @param aPrintSettings optional print settings to serialize, otherwise a
|
||||
* default print settings will be used.
|
||||
* @param aProgressListener optional print progress listener.
|
||||
* @param aRemotePrintJob optional remote print job, so that an existing
|
||||
* one can be used.
|
||||
* @param aPrintData PrintData to populate.
|
||||
*/
|
||||
nsresult
|
||||
SerializeAndEnsureRemotePrintJob(nsIPrintSettings* aPrintSettings,
|
||||
nsIWebProgressListener* aListener,
|
||||
layout::RemotePrintJobParent* aRemotePrintJob,
|
||||
PrintData* aPrintData);
|
||||
|
||||
private:
|
||||
virtual ~PrintingParent();
|
||||
|
||||
nsPIDOMWindowOuter*
|
||||
DOMWindowFromBrowserParent(PBrowserParent* parent);
|
||||
|
||||
nsresult
|
||||
ShowPrintDialog(PBrowserParent* parent,
|
||||
const PrintData& data,
|
||||
PrintData* result);
|
||||
|
||||
nsCOMPtr<nsIPrintSettingsService> mPrintSettingsSvc;
|
||||
};
|
||||
|
||||
} // namespace embedding
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
35
embedding/components/printingui/ipc/moz.build
Normal file
35
embedding/components/printingui/ipc/moz.build
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
# -*- 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/.
|
||||
|
||||
EXPORTS += [
|
||||
'nsPrintingProxy.h',
|
||||
]
|
||||
|
||||
EXPORTS.mozilla.embedding.printingui += [
|
||||
'PrintingParent.h',
|
||||
]
|
||||
|
||||
if CONFIG['NS_PRINTING']:
|
||||
UNIFIED_SOURCES += [
|
||||
'nsPrintingProxy.cpp',
|
||||
'PrintDataUtils.cpp',
|
||||
'PrintingParent.cpp',
|
||||
'PrintProgressDialogChild.cpp',
|
||||
'PrintProgressDialogParent.cpp',
|
||||
'PrintSettingsDialogChild.cpp',
|
||||
'PrintSettingsDialogParent.cpp',
|
||||
]
|
||||
|
||||
IPDL_SOURCES += [
|
||||
'PPrinting.ipdl',
|
||||
'PPrintingTypes.ipdlh',
|
||||
'PPrintProgressDialog.ipdl',
|
||||
'PPrintSettingsDialog.ipdl',
|
||||
]
|
||||
|
||||
include('/ipc/chromium/chromium-config.mozbuild')
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
269
embedding/components/printingui/ipc/nsPrintingProxy.cpp
Normal file
269
embedding/components/printingui/ipc/nsPrintingProxy.cpp
Normal file
|
|
@ -0,0 +1,269 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* 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 "nsPrintingProxy.h"
|
||||
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
#include "mozilla/dom/TabChild.h"
|
||||
#include "mozilla/layout/RemotePrintJobChild.h"
|
||||
#include "mozilla/Unused.h"
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsIDocShellTreeOwner.h"
|
||||
#include "nsIPrintingPromptService.h"
|
||||
#include "nsIPrintSession.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsPrintOptionsImpl.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "PrintDataUtils.h"
|
||||
#include "PrintProgressDialogChild.h"
|
||||
#include "PrintSettingsDialogChild.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
using namespace mozilla::embedding;
|
||||
using namespace mozilla::layout;
|
||||
|
||||
static StaticRefPtr<nsPrintingProxy> sPrintingProxyInstance;
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsPrintingProxy, nsIPrintingPromptService)
|
||||
|
||||
nsPrintingProxy::nsPrintingProxy()
|
||||
{
|
||||
}
|
||||
|
||||
nsPrintingProxy::~nsPrintingProxy()
|
||||
{
|
||||
}
|
||||
|
||||
/* static */
|
||||
already_AddRefed<nsPrintingProxy>
|
||||
nsPrintingProxy::GetInstance()
|
||||
{
|
||||
if (!sPrintingProxyInstance) {
|
||||
sPrintingProxyInstance = new nsPrintingProxy();
|
||||
if (!sPrintingProxyInstance) {
|
||||
return nullptr;
|
||||
}
|
||||
nsresult rv = sPrintingProxyInstance->Init();
|
||||
if (NS_FAILED(rv)) {
|
||||
sPrintingProxyInstance = nullptr;
|
||||
return nullptr;
|
||||
}
|
||||
ClearOnShutdown(&sPrintingProxyInstance);
|
||||
}
|
||||
|
||||
RefPtr<nsPrintingProxy> inst = sPrintingProxyInstance.get();
|
||||
return inst.forget();
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsPrintingProxy::Init()
|
||||
{
|
||||
mozilla::Unused << ContentChild::GetSingleton()->SendPPrintingConstructor(this);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrintingProxy::ShowPrintDialog(mozIDOMWindowProxy *parent,
|
||||
nsIWebBrowserPrint *webBrowserPrint,
|
||||
nsIPrintSettings *printSettings)
|
||||
{
|
||||
NS_ENSURE_ARG(webBrowserPrint);
|
||||
NS_ENSURE_ARG(printSettings);
|
||||
|
||||
// If parent is null we are just being called to retrieve the print settings
|
||||
// from the printer in the parent for print preview.
|
||||
TabChild* pBrowser = nullptr;
|
||||
if (parent) {
|
||||
// Get the TabChild for this nsIDOMWindow, which we can then pass up to
|
||||
// the parent.
|
||||
nsCOMPtr<nsPIDOMWindowOuter> pwin = nsPIDOMWindowOuter::From(parent);
|
||||
NS_ENSURE_STATE(pwin);
|
||||
nsCOMPtr<nsIDocShell> docShell = pwin->GetDocShell();
|
||||
NS_ENSURE_STATE(docShell);
|
||||
|
||||
nsCOMPtr<nsITabChild> tabchild = docShell->GetTabChild();
|
||||
NS_ENSURE_STATE(tabchild);
|
||||
|
||||
pBrowser = static_cast<TabChild*>(tabchild.get());
|
||||
}
|
||||
|
||||
// Next, serialize the nsIWebBrowserPrint and nsIPrintSettings we were given.
|
||||
nsresult rv = NS_OK;
|
||||
nsCOMPtr<nsIPrintSettingsService> printSettingsSvc =
|
||||
do_GetService("@mozilla.org/gfx/printsettings-service;1", &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PrintData inSettings;
|
||||
rv = printSettingsSvc->SerializeToPrintData(printSettings, webBrowserPrint,
|
||||
&inSettings);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Now, the waiting game. The parent process should be showing
|
||||
// the printing dialog soon. In the meantime, we need to spin a
|
||||
// nested event loop while we wait for the results of the dialog
|
||||
// to be returned to us.
|
||||
|
||||
RefPtr<PrintSettingsDialogChild> dialog = new PrintSettingsDialogChild();
|
||||
SendPPrintSettingsDialogConstructor(dialog);
|
||||
|
||||
mozilla::Unused << SendShowPrintDialog(dialog, pBrowser, inSettings);
|
||||
|
||||
while(!dialog->returned()) {
|
||||
NS_ProcessNextEvent(nullptr, true);
|
||||
}
|
||||
|
||||
rv = dialog->result();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = printSettingsSvc->DeserializeToPrintSettings(dialog->data(),
|
||||
printSettings);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrintingProxy::ShowProgress(mozIDOMWindowProxy* parent,
|
||||
nsIWebBrowserPrint* webBrowserPrint, // ok to be null
|
||||
nsIPrintSettings* printSettings, // ok to be null
|
||||
nsIObserver* openDialogObserver, // ok to be null
|
||||
bool isForPrinting,
|
||||
nsIWebProgressListener** webProgressListener,
|
||||
nsIPrintProgressParams** printProgressParams,
|
||||
bool* notifyOnOpen)
|
||||
{
|
||||
NS_ENSURE_ARG(parent);
|
||||
NS_ENSURE_ARG(webProgressListener);
|
||||
NS_ENSURE_ARG(printProgressParams);
|
||||
NS_ENSURE_ARG(notifyOnOpen);
|
||||
|
||||
// Get the TabChild for this nsIDOMWindow, which we can then pass up to
|
||||
// the parent.
|
||||
nsCOMPtr<nsPIDOMWindowOuter> pwin = nsPIDOMWindowOuter::From(parent);
|
||||
NS_ENSURE_STATE(pwin);
|
||||
nsCOMPtr<nsIDocShell> docShell = pwin->GetDocShell();
|
||||
NS_ENSURE_STATE(docShell);
|
||||
nsCOMPtr<nsITabChild> tabchild = docShell->GetTabChild();
|
||||
TabChild* pBrowser = static_cast<TabChild*>(tabchild.get());
|
||||
|
||||
RefPtr<PrintProgressDialogChild> dialogChild =
|
||||
new PrintProgressDialogChild(openDialogObserver);
|
||||
|
||||
SendPPrintProgressDialogConstructor(dialogChild);
|
||||
|
||||
// Get the RemotePrintJob if we have one available.
|
||||
RefPtr<mozilla::layout::RemotePrintJobChild> remotePrintJob;
|
||||
if (printSettings) {
|
||||
nsCOMPtr<nsIPrintSession> printSession;
|
||||
nsresult rv = printSettings->GetPrintSession(getter_AddRefs(printSession));
|
||||
if (NS_SUCCEEDED(rv) && printSession) {
|
||||
printSession->GetRemotePrintJob(getter_AddRefs(remotePrintJob));
|
||||
}
|
||||
}
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
mozilla::Unused << SendShowProgress(pBrowser, dialogChild, remotePrintJob,
|
||||
isForPrinting, notifyOnOpen, &rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// If we have a RemotePrintJob that will be being used as a more general
|
||||
// forwarder for print progress listeners. Once we always have one we can
|
||||
// remove the interface from PrintProgressDialogChild.
|
||||
if (!remotePrintJob) {
|
||||
NS_ADDREF(*webProgressListener = dialogChild);
|
||||
}
|
||||
NS_ADDREF(*printProgressParams = dialogChild);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrintingProxy::ShowPageSetup(mozIDOMWindowProxy *parent,
|
||||
nsIPrintSettings *printSettings,
|
||||
nsIObserver *aObs)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrintingProxy::ShowPrinterProperties(mozIDOMWindowProxy *parent,
|
||||
const char16_t *printerName,
|
||||
nsIPrintSettings *printSettings)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsPrintingProxy::SavePrintSettings(nsIPrintSettings* aPS,
|
||||
bool aUsePrinterNamePrefix,
|
||||
uint32_t aFlags)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIPrintSettingsService> printSettingsSvc =
|
||||
do_GetService("@mozilla.org/gfx/printsettings-service;1", &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PrintData settings;
|
||||
rv = printSettingsSvc->SerializeToPrintData(aPS, nullptr, &settings);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
Unused << SendSavePrintSettings(settings, aUsePrinterNamePrefix, aFlags,
|
||||
&rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
PPrintProgressDialogChild*
|
||||
nsPrintingProxy::AllocPPrintProgressDialogChild()
|
||||
{
|
||||
// The parent process will never initiate the PPrintProgressDialog
|
||||
// protocol connection, so no need to provide an allocator here.
|
||||
NS_NOTREACHED("Allocator for PPrintProgressDialogChild should not be "
|
||||
"called on nsPrintingProxy.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
nsPrintingProxy::DeallocPPrintProgressDialogChild(PPrintProgressDialogChild* aActor)
|
||||
{
|
||||
// The PrintProgressDialogChild implements refcounting, and
|
||||
// will take itself out.
|
||||
return true;
|
||||
}
|
||||
|
||||
PPrintSettingsDialogChild*
|
||||
nsPrintingProxy::AllocPPrintSettingsDialogChild()
|
||||
{
|
||||
// The parent process will never initiate the PPrintSettingsDialog
|
||||
// protocol connection, so no need to provide an allocator here.
|
||||
NS_NOTREACHED("Allocator for PPrintSettingsDialogChild should not be "
|
||||
"called on nsPrintingProxy.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
nsPrintingProxy::DeallocPPrintSettingsDialogChild(PPrintSettingsDialogChild* aActor)
|
||||
{
|
||||
// The PrintSettingsDialogChild implements refcounting, and
|
||||
// will take itself out.
|
||||
return true;
|
||||
}
|
||||
|
||||
PRemotePrintJobChild*
|
||||
nsPrintingProxy::AllocPRemotePrintJobChild()
|
||||
{
|
||||
RefPtr<RemotePrintJobChild> remotePrintJob = new RemotePrintJobChild();
|
||||
return remotePrintJob.forget().take();
|
||||
}
|
||||
|
||||
bool
|
||||
nsPrintingProxy::DeallocPRemotePrintJobChild(PRemotePrintJobChild* aDoomed)
|
||||
{
|
||||
RemotePrintJobChild* remotePrintJob = static_cast<RemotePrintJobChild*>(aDoomed);
|
||||
NS_RELEASE(remotePrintJob);
|
||||
return true;
|
||||
}
|
||||
57
embedding/components/printingui/ipc/nsPrintingProxy.h
Normal file
57
embedding/components/printingui/ipc/nsPrintingProxy.h
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
/* -*- 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 __nsPrintingProxy_h
|
||||
#define __nsPrintingProxy_h
|
||||
|
||||
#include "nsIPrintingPromptService.h"
|
||||
#include "mozilla/embedding/PPrintingChild.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layout {
|
||||
class PRemotePrintJobChild;
|
||||
}
|
||||
}
|
||||
|
||||
class nsPrintingProxy: public nsIPrintingPromptService,
|
||||
public mozilla::embedding::PPrintingChild
|
||||
{
|
||||
virtual ~nsPrintingProxy();
|
||||
|
||||
public:
|
||||
nsPrintingProxy();
|
||||
|
||||
static already_AddRefed<nsPrintingProxy> GetInstance();
|
||||
|
||||
nsresult Init();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIPRINTINGPROMPTSERVICE
|
||||
|
||||
nsresult SavePrintSettings(nsIPrintSettings* aPS,
|
||||
bool aUsePrinterNamePrefix,
|
||||
uint32_t aFlags);
|
||||
|
||||
virtual PPrintProgressDialogChild*
|
||||
AllocPPrintProgressDialogChild() override;
|
||||
|
||||
virtual bool
|
||||
DeallocPPrintProgressDialogChild(PPrintProgressDialogChild* aActor) override;
|
||||
|
||||
virtual PPrintSettingsDialogChild*
|
||||
AllocPPrintSettingsDialogChild() override;
|
||||
|
||||
virtual bool
|
||||
DeallocPPrintSettingsDialogChild(PPrintSettingsDialogChild* aActor) override;
|
||||
|
||||
virtual PRemotePrintJobChild*
|
||||
AllocPRemotePrintJobChild() override;
|
||||
|
||||
virtual bool
|
||||
DeallocPRemotePrintJobChild(PRemotePrintJobChild* aActor) override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
16
embedding/components/printingui/mac/moz.build
Normal file
16
embedding/components/printingui/mac/moz.build
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
# -*- 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/.
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'nsPrintProgress.cpp',
|
||||
'nsPrintProgressParams.cpp',
|
||||
]
|
||||
|
||||
SOURCES += [
|
||||
'nsPrintingPromptServiceX.mm',
|
||||
]
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
213
embedding/components/printingui/mac/nsPrintProgress.cpp
Normal file
213
embedding/components/printingui/mac/nsPrintProgress.cpp
Normal file
|
|
@ -0,0 +1,213 @@
|
|||
/* -*- 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 "nsPrintProgress.h"
|
||||
|
||||
#include "nsIBaseWindow.h"
|
||||
#include "nsXPCOM.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
|
||||
NS_IMPL_ADDREF(nsPrintProgress)
|
||||
NS_IMPL_RELEASE(nsPrintProgress)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(nsPrintProgress)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIPrintStatusFeedback)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIPrintProgress)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIPrintStatusFeedback)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIWebProgressListener)
|
||||
NS_INTERFACE_MAP_END_THREADSAFE
|
||||
|
||||
|
||||
nsPrintProgress::nsPrintProgress()
|
||||
{
|
||||
m_closeProgress = false;
|
||||
m_processCanceled = false;
|
||||
m_pendingStateFlags = -1;
|
||||
m_pendingStateValue = NS_OK;
|
||||
}
|
||||
|
||||
nsPrintProgress::~nsPrintProgress()
|
||||
{
|
||||
(void)ReleaseListeners();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::OpenProgressDialog(mozIDOMWindowProxy *parent,
|
||||
const char *dialogURL,
|
||||
nsISupports *parameters,
|
||||
nsIObserver *openDialogObserver,
|
||||
bool *notifyOnOpen)
|
||||
{
|
||||
MOZ_ASSERT_UNREACHABLE("The nsPrintingPromptService::ShowProgress "
|
||||
"implementation for OS X returns "
|
||||
"NS_ERROR_NOT_IMPLEMENTED, so we should never get "
|
||||
"here.");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::CloseProgressDialog(bool forceClose)
|
||||
{
|
||||
MOZ_ASSERT_UNREACHABLE("The nsPrintingPromptService::ShowProgress "
|
||||
"implementation for OS X returns "
|
||||
"NS_ERROR_NOT_IMPLEMENTED, so we should never get "
|
||||
"here.");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::GetPrompter(nsIPrompt **_retval)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(_retval);
|
||||
*_retval = nullptr;
|
||||
|
||||
if (! m_closeProgress && m_dialog) {
|
||||
nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryInterface(m_dialog);
|
||||
MOZ_ASSERT(window);
|
||||
return window->GetPrompter(_retval);
|
||||
}
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::GetProcessCanceledByUser(bool *aProcessCanceledByUser)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aProcessCanceledByUser);
|
||||
*aProcessCanceledByUser = m_processCanceled;
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHODIMP nsPrintProgress::SetProcessCanceledByUser(bool aProcessCanceledByUser)
|
||||
{
|
||||
m_processCanceled = aProcessCanceledByUser;
|
||||
OnStateChange(nullptr, nullptr, nsIWebProgressListener::STATE_STOP, NS_OK);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::RegisterListener(nsIWebProgressListener * listener)
|
||||
{
|
||||
if (!listener) //Nothing to do with a null listener!
|
||||
return NS_OK;
|
||||
|
||||
m_listenerList.AppendObject(listener);
|
||||
if (m_closeProgress || m_processCanceled)
|
||||
listener->OnStateChange(nullptr, nullptr,
|
||||
nsIWebProgressListener::STATE_STOP, NS_OK);
|
||||
else
|
||||
{
|
||||
listener->OnStatusChange(nullptr, nullptr, NS_OK, m_pendingStatus.get());
|
||||
if (m_pendingStateFlags != -1)
|
||||
listener->OnStateChange(nullptr, nullptr, m_pendingStateFlags, m_pendingStateValue);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::UnregisterListener(nsIWebProgressListener *listener)
|
||||
{
|
||||
if (listener)
|
||||
m_listenerList.RemoveObject(listener);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::DoneIniting()
|
||||
{
|
||||
if (m_observer) {
|
||||
m_observer->Observe(nullptr, nullptr, nullptr);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::OnStateChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, uint32_t aStateFlags, nsresult aStatus)
|
||||
{
|
||||
m_pendingStateFlags = aStateFlags;
|
||||
m_pendingStateValue = aStatus;
|
||||
|
||||
uint32_t count = m_listenerList.Count();
|
||||
for (uint32_t i = count - 1; i < count; i --)
|
||||
{
|
||||
nsCOMPtr<nsIWebProgressListener> progressListener = m_listenerList.SafeObjectAt(i);
|
||||
if (progressListener)
|
||||
progressListener->OnStateChange(aWebProgress, aRequest, aStateFlags, aStatus);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::OnProgressChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, int32_t aCurSelfProgress, int32_t aMaxSelfProgress, int32_t aCurTotalProgress, int32_t aMaxTotalProgress)
|
||||
{
|
||||
uint32_t count = m_listenerList.Count();
|
||||
for (uint32_t i = count - 1; i < count; i --)
|
||||
{
|
||||
nsCOMPtr<nsIWebProgressListener> progressListener = m_listenerList.SafeObjectAt(i);
|
||||
if (progressListener)
|
||||
progressListener->OnProgressChange(aWebProgress, aRequest, aCurSelfProgress, aMaxSelfProgress, aCurTotalProgress, aMaxTotalProgress);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::OnLocationChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, nsIURI *location, uint32_t aFlags)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::OnStatusChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, nsresult aStatus, const char16_t *aMessage)
|
||||
{
|
||||
if (aMessage && *aMessage)
|
||||
m_pendingStatus = aMessage;
|
||||
|
||||
uint32_t count = m_listenerList.Count();
|
||||
for (uint32_t i = count - 1; i < count; i --)
|
||||
{
|
||||
nsCOMPtr<nsIWebProgressListener> progressListener = m_listenerList.SafeObjectAt(i);
|
||||
if (progressListener)
|
||||
progressListener->OnStatusChange(aWebProgress, aRequest, aStatus, aMessage);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::OnSecurityChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, uint32_t state)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsPrintProgress::ReleaseListeners()
|
||||
{
|
||||
m_listenerList.Clear();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::ShowStatusString(const char16_t *status)
|
||||
{
|
||||
return OnStatusChange(nullptr, nullptr, NS_OK, status);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::StartMeteors()
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::StopMeteors()
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::ShowProgress(int32_t percent)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::SetDocShell(nsIDocShell *shell,
|
||||
mozIDOMWindowProxy *window)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::CloseWindow()
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
44
embedding/components/printingui/mac/nsPrintProgress.h
Normal file
44
embedding/components/printingui/mac/nsPrintProgress.h
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
/* -*- 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 __nsPrintProgress_h
|
||||
#define __nsPrintProgress_h
|
||||
|
||||
#include "nsIPrintProgress.h"
|
||||
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIPrintStatusFeedback.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsString.h"
|
||||
|
||||
class nsPrintProgress : public nsIPrintProgress, public nsIPrintStatusFeedback
|
||||
{
|
||||
public:
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
NS_DECL_NSIPRINTPROGRESS
|
||||
NS_DECL_NSIWEBPROGRESSLISTENER
|
||||
NS_DECL_NSIPRINTSTATUSFEEDBACK
|
||||
|
||||
nsPrintProgress();
|
||||
|
||||
protected:
|
||||
virtual ~nsPrintProgress();
|
||||
|
||||
private:
|
||||
nsresult ReleaseListeners();
|
||||
|
||||
bool m_closeProgress;
|
||||
bool m_processCanceled;
|
||||
nsString m_pendingStatus;
|
||||
int32_t m_pendingStateFlags;
|
||||
nsresult m_pendingStateValue;
|
||||
// XXX This member is read-only.
|
||||
nsCOMPtr<mozIDOMWindowProxy> m_dialog;
|
||||
nsCOMArray<nsIWebProgressListener> m_listenerList;
|
||||
nsCOMPtr<nsIObserver> m_observer;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
/* -*- 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 "nsPrintProgressParams.h"
|
||||
#include "nsReadableUtils.h"
|
||||
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsPrintProgressParams, nsIPrintProgressParams)
|
||||
|
||||
nsPrintProgressParams::nsPrintProgressParams()
|
||||
{
|
||||
}
|
||||
|
||||
nsPrintProgressParams::~nsPrintProgressParams()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgressParams::GetDocTitle(char16_t * *aDocTitle)
|
||||
{
|
||||
NS_ENSURE_ARG(aDocTitle);
|
||||
|
||||
*aDocTitle = ToNewUnicode(mDocTitle);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgressParams::SetDocTitle(const char16_t * aDocTitle)
|
||||
{
|
||||
mDocTitle = aDocTitle;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgressParams::GetDocURL(char16_t * *aDocURL)
|
||||
{
|
||||
NS_ENSURE_ARG(aDocURL);
|
||||
|
||||
*aDocURL = ToNewUnicode(mDocURL);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgressParams::SetDocURL(const char16_t * aDocURL)
|
||||
{
|
||||
mDocURL = aDocURL;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
28
embedding/components/printingui/mac/nsPrintProgressParams.h
Normal file
28
embedding/components/printingui/mac/nsPrintProgressParams.h
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
/* -*- 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 __nsPrintProgressParams_h
|
||||
#define __nsPrintProgressParams_h
|
||||
|
||||
#include "nsIPrintProgressParams.h"
|
||||
#include "nsString.h"
|
||||
|
||||
class nsPrintProgressParams : public nsIPrintProgressParams
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIPRINTPROGRESSPARAMS
|
||||
|
||||
nsPrintProgressParams();
|
||||
|
||||
protected:
|
||||
virtual ~nsPrintProgressParams();
|
||||
|
||||
private:
|
||||
nsString mDocTitle;
|
||||
nsString mDocURL;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
/* -*- 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 __nsPrintingPromptService_h
|
||||
#define __nsPrintingPromptService_h
|
||||
|
||||
// {E042570C-62DE-4bb6-A6E0-798E3C07B4DF}
|
||||
#define NS_PRINTINGPROMPTSERVICE_CID \
|
||||
{0xe042570c, 0x62de, 0x4bb6, { 0xa6, 0xe0, 0x79, 0x8e, 0x3c, 0x7, 0xb4, 0xdf}}
|
||||
#define NS_PRINTINGPROMPTSERVICE_CONTRACTID \
|
||||
"@mozilla.org/embedcomp/printingprompt-service;1"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIPrintingPromptService.h"
|
||||
#include "nsPIPromptService.h"
|
||||
#include "nsIWindowWatcher.h"
|
||||
|
||||
// Printing Progress Includes
|
||||
#include "nsPrintProgress.h"
|
||||
#include "nsIWebProgressListener.h"
|
||||
|
||||
class nsPrintingPromptService: public nsIPrintingPromptService,
|
||||
public nsIWebProgressListener
|
||||
{
|
||||
public:
|
||||
nsPrintingPromptService();
|
||||
|
||||
nsresult Init();
|
||||
|
||||
NS_DECL_NSIPRINTINGPROMPTSERVICE
|
||||
NS_DECL_NSIWEBPROGRESSLISTENER
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
protected:
|
||||
virtual ~nsPrintingPromptService();
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsIPrintProgress> mPrintProgress;
|
||||
};
|
||||
|
||||
#endif
|
||||
128
embedding/components/printingui/mac/nsPrintingPromptServiceX.mm
Normal file
128
embedding/components/printingui/mac/nsPrintingPromptServiceX.mm
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
/* -*- 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 "nsPrintingPromptService.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsObjCExceptions.h"
|
||||
|
||||
#include "nsIPrintingPromptService.h"
|
||||
#include "nsIFactory.h"
|
||||
#include "nsIPrintDialogService.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
|
||||
//*****************************************************************************
|
||||
// nsPrintingPromptService
|
||||
//*****************************************************************************
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsPrintingPromptService, nsIPrintingPromptService, nsIWebProgressListener)
|
||||
|
||||
nsPrintingPromptService::nsPrintingPromptService()
|
||||
{
|
||||
}
|
||||
|
||||
nsPrintingPromptService::~nsPrintingPromptService()
|
||||
{
|
||||
}
|
||||
|
||||
nsresult nsPrintingPromptService::Init()
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
// nsPrintingPromptService::nsIPrintingPromptService
|
||||
//*****************************************************************************
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrintingPromptService::ShowPrintDialog(mozIDOMWindowProxy *parent, nsIWebBrowserPrint *webBrowserPrint, nsIPrintSettings *printSettings)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
||||
|
||||
nsCOMPtr<nsIPrintDialogService> dlgPrint(do_GetService(
|
||||
NS_PRINTDIALOGSERVICE_CONTRACTID));
|
||||
if (dlgPrint) {
|
||||
return dlgPrint->Show(nsPIDOMWindowOuter::From(parent), printSettings,
|
||||
webBrowserPrint);
|
||||
}
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrintingPromptService::ShowProgress(mozIDOMWindowProxy* parent,
|
||||
nsIWebBrowserPrint* webBrowserPrint, // ok to be null
|
||||
nsIPrintSettings* printSettings, // ok to be null
|
||||
nsIObserver* openDialogObserver, // ok to be null
|
||||
bool isForPrinting,
|
||||
nsIWebProgressListener** webProgressListener,
|
||||
nsIPrintProgressParams** printProgressParams,
|
||||
bool* notifyOnOpen)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrintingPromptService::ShowPageSetup(mozIDOMWindowProxy *parent, nsIPrintSettings *printSettings, nsIObserver *aObs)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
||||
nsCOMPtr<nsIPrintDialogService> dlgPrint(do_GetService(
|
||||
NS_PRINTDIALOGSERVICE_CONTRACTID));
|
||||
if (dlgPrint) {
|
||||
return dlgPrint->ShowPageSetup(nsPIDOMWindowOuter::From(parent), printSettings);
|
||||
}
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrintingPromptService::ShowPrinterProperties(mozIDOMWindowProxy *parent, const char16_t *printerName, nsIPrintSettings *printSettings)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
// nsPrintingPromptService::nsIWebProgressListener
|
||||
//*****************************************************************************
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrintingPromptService::OnStateChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, uint32_t aStateFlags, nsresult aStatus)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onProgressChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aCurSelfProgress, in long aMaxSelfProgress, in long aCurTotalProgress, in long aMaxTotalProgress); */
|
||||
NS_IMETHODIMP
|
||||
nsPrintingPromptService::OnProgressChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, int32_t aCurSelfProgress, int32_t aMaxSelfProgress, int32_t aCurTotalProgress, int32_t aMaxTotalProgress)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onLocationChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsIURI location, in unsigned long aFlags); */
|
||||
NS_IMETHODIMP
|
||||
nsPrintingPromptService::OnLocationChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, nsIURI *location, uint32_t aFlags)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onStatusChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsresult aStatus, in wstring aMessage); */
|
||||
NS_IMETHODIMP
|
||||
nsPrintingPromptService::OnStatusChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, nsresult aStatus, const char16_t *aMessage)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onSecurityChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in unsigned long state); */
|
||||
NS_IMETHODIMP
|
||||
nsPrintingPromptService::OnSecurityChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, uint32_t state)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
17
embedding/components/printingui/moz.build
Normal file
17
embedding/components/printingui/moz.build
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
# -*- 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/.
|
||||
|
||||
toolkit = CONFIG['MOZ_WIDGET_TOOLKIT']
|
||||
|
||||
DIRS += ['ipc']
|
||||
|
||||
if CONFIG['NS_PRINTING']:
|
||||
if toolkit == 'windows':
|
||||
DIRS += ['win']
|
||||
elif toolkit == 'cocoa':
|
||||
DIRS += ['mac']
|
||||
elif CONFIG['MOZ_PDF_PRINTING']:
|
||||
DIRS += ['unixshared']
|
||||
13
embedding/components/printingui/unixshared/moz.build
Normal file
13
embedding/components/printingui/unixshared/moz.build
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
# -*- 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/.
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'nsPrintingPromptService.cpp',
|
||||
'nsPrintProgress.cpp',
|
||||
'nsPrintProgressParams.cpp',
|
||||
]
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
267
embedding/components/printingui/unixshared/nsPrintProgress.cpp
Normal file
267
embedding/components/printingui/unixshared/nsPrintProgress.cpp
Normal file
|
|
@ -0,0 +1,267 @@
|
|||
/* -*- 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 "nsPrintProgress.h"
|
||||
|
||||
#include "nsArray.h"
|
||||
#include "nsIBaseWindow.h"
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsIDocShellTreeOwner.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
#include "nsIXULWindow.h"
|
||||
#include "nsXPCOM.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
|
||||
|
||||
NS_IMPL_ADDREF(nsPrintProgress)
|
||||
NS_IMPL_RELEASE(nsPrintProgress)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(nsPrintProgress)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIPrintStatusFeedback)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIPrintProgress)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIPrintStatusFeedback)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIWebProgressListener)
|
||||
NS_INTERFACE_MAP_END_THREADSAFE
|
||||
|
||||
|
||||
nsPrintProgress::nsPrintProgress(nsIPrintSettings* aPrintSettings)
|
||||
{
|
||||
m_closeProgress = false;
|
||||
m_processCanceled = false;
|
||||
m_pendingStateFlags = -1;
|
||||
m_pendingStateValue = NS_OK;
|
||||
m_PrintSetting = aPrintSettings;
|
||||
}
|
||||
|
||||
nsPrintProgress::~nsPrintProgress()
|
||||
{
|
||||
(void)ReleaseListeners();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::OpenProgressDialog(mozIDOMWindowProxy *parent,
|
||||
const char *dialogURL,
|
||||
nsISupports *parameters,
|
||||
nsIObserver *openDialogObserver,
|
||||
bool *notifyOnOpen)
|
||||
{
|
||||
*notifyOnOpen = true;
|
||||
m_observer = openDialogObserver;
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
|
||||
if (m_dialog)
|
||||
return NS_ERROR_ALREADY_INITIALIZED;
|
||||
|
||||
if (!dialogURL || !*dialogURL)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
if (parent)
|
||||
{
|
||||
// Set up window.arguments[0]...
|
||||
nsCOMPtr<nsIMutableArray> array = nsArray::Create();
|
||||
|
||||
nsCOMPtr<nsISupportsInterfacePointer> ifptr =
|
||||
do_CreateInstance(NS_SUPPORTS_INTERFACE_POINTER_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
ifptr->SetData(static_cast<nsIPrintProgress*>(this));
|
||||
ifptr->SetDataIID(&NS_GET_IID(nsIPrintProgress));
|
||||
|
||||
array->AppendElement(ifptr, /*weak =*/ false);
|
||||
|
||||
array->AppendElement(parameters, /*weak =*/ false);
|
||||
|
||||
// We will set the opener of the dialog to be the nsIDOMWindow for the
|
||||
// browser XUL window itself, as opposed to the content. That way, the
|
||||
// progress window has access to the opener.
|
||||
auto* pParentWindow = nsPIDOMWindowOuter::From(parent);
|
||||
nsCOMPtr<nsIDocShell> docShell = pParentWindow->GetDocShell();
|
||||
NS_ENSURE_STATE(docShell);
|
||||
|
||||
nsCOMPtr<nsIDocShellTreeOwner> owner;
|
||||
docShell->GetTreeOwner(getter_AddRefs(owner));
|
||||
|
||||
nsCOMPtr<nsIXULWindow> ownerXULWindow = do_GetInterface(owner);
|
||||
nsCOMPtr<mozIDOMWindowProxy> ownerWindow = do_GetInterface(ownerXULWindow);
|
||||
NS_ENSURE_STATE(ownerWindow);
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowOuter> piOwnerWindow = nsPIDOMWindowOuter::From(ownerWindow);
|
||||
|
||||
// Open the dialog.
|
||||
nsCOMPtr<nsPIDOMWindowOuter> newWindow;
|
||||
|
||||
rv = piOwnerWindow->OpenDialog(NS_ConvertASCIItoUTF16(dialogURL),
|
||||
NS_LITERAL_STRING("_blank"),
|
||||
NS_LITERAL_STRING("chrome,titlebar,dependent,centerscreen"),
|
||||
array, getter_AddRefs(newWindow));
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::CloseProgressDialog(bool forceClose)
|
||||
{
|
||||
m_closeProgress = true;
|
||||
// XXX Invalid cast of bool to nsresult (bug 778106)
|
||||
return OnStateChange(nullptr, nullptr, nsIWebProgressListener::STATE_STOP,
|
||||
(nsresult)forceClose);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::GetPrompter(nsIPrompt **_retval)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(_retval);
|
||||
*_retval = nullptr;
|
||||
|
||||
if (! m_closeProgress && m_dialog) {
|
||||
nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryInterface(m_dialog);
|
||||
MOZ_ASSERT(window);
|
||||
return window->GetPrompter(_retval);
|
||||
}
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::GetProcessCanceledByUser(bool *aProcessCanceledByUser)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aProcessCanceledByUser);
|
||||
*aProcessCanceledByUser = m_processCanceled;
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHODIMP nsPrintProgress::SetProcessCanceledByUser(bool aProcessCanceledByUser)
|
||||
{
|
||||
if(m_PrintSetting)
|
||||
m_PrintSetting->SetIsCancelled(true);
|
||||
m_processCanceled = aProcessCanceledByUser;
|
||||
OnStateChange(nullptr, nullptr, nsIWebProgressListener::STATE_STOP, NS_OK);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::RegisterListener(nsIWebProgressListener * listener)
|
||||
{
|
||||
if (!listener) //Nothing to do with a null listener!
|
||||
return NS_OK;
|
||||
|
||||
m_listenerList.AppendObject(listener);
|
||||
if (m_closeProgress || m_processCanceled)
|
||||
listener->OnStateChange(nullptr, nullptr, nsIWebProgressListener::STATE_STOP, NS_OK);
|
||||
else
|
||||
{
|
||||
listener->OnStatusChange(nullptr, nullptr, NS_OK, m_pendingStatus.get());
|
||||
if (m_pendingStateFlags != -1)
|
||||
listener->OnStateChange(nullptr, nullptr, m_pendingStateFlags, m_pendingStateValue);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::UnregisterListener(nsIWebProgressListener *listener)
|
||||
{
|
||||
if (listener)
|
||||
m_listenerList.RemoveObject(listener);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::DoneIniting()
|
||||
{
|
||||
if (m_observer) {
|
||||
m_observer->Observe(nullptr, nullptr, nullptr);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::OnStateChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, uint32_t aStateFlags, nsresult aStatus)
|
||||
{
|
||||
m_pendingStateFlags = aStateFlags;
|
||||
m_pendingStateValue = aStatus;
|
||||
|
||||
uint32_t count = m_listenerList.Count();
|
||||
for (uint32_t i = count - 1; i < count; i --)
|
||||
{
|
||||
nsCOMPtr<nsIWebProgressListener> progressListener = m_listenerList.SafeObjectAt(i);
|
||||
if (progressListener)
|
||||
progressListener->OnStateChange(aWebProgress, aRequest, aStateFlags, aStatus);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::OnProgressChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, int32_t aCurSelfProgress, int32_t aMaxSelfProgress, int32_t aCurTotalProgress, int32_t aMaxTotalProgress)
|
||||
{
|
||||
uint32_t count = m_listenerList.Count();
|
||||
for (uint32_t i = count - 1; i < count; i --)
|
||||
{
|
||||
nsCOMPtr<nsIWebProgressListener> progressListener = m_listenerList.SafeObjectAt(i);
|
||||
if (progressListener)
|
||||
progressListener->OnProgressChange(aWebProgress, aRequest, aCurSelfProgress, aMaxSelfProgress, aCurTotalProgress, aMaxTotalProgress);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::OnLocationChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, nsIURI *location, uint32_t aFlags)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::OnStatusChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, nsresult aStatus, const char16_t *aMessage)
|
||||
{
|
||||
if (aMessage && *aMessage)
|
||||
m_pendingStatus = aMessage;
|
||||
|
||||
uint32_t count = m_listenerList.Count();
|
||||
for (uint32_t i = count - 1; i < count; i --)
|
||||
{
|
||||
nsCOMPtr<nsIWebProgressListener> progressListener = m_listenerList.SafeObjectAt(i);
|
||||
if (progressListener)
|
||||
progressListener->OnStatusChange(aWebProgress, aRequest, aStatus, aMessage);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::OnSecurityChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, uint32_t state)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsPrintProgress::ReleaseListeners()
|
||||
{
|
||||
m_listenerList.Clear();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::ShowStatusString(const char16_t *status)
|
||||
{
|
||||
return OnStatusChange(nullptr, nullptr, NS_OK, status);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::StartMeteors()
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::StopMeteors()
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::ShowProgress(int32_t percent)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::SetDocShell(nsIDocShell *shell, mozIDOMWindowProxy *window)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::CloseWindow()
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
46
embedding/components/printingui/unixshared/nsPrintProgress.h
Normal file
46
embedding/components/printingui/unixshared/nsPrintProgress.h
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
/* -*- 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 __nsPrintProgress_h
|
||||
#define __nsPrintProgress_h
|
||||
|
||||
#include "nsIPrintProgress.h"
|
||||
#include "nsIPrintingPromptService.h"
|
||||
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "nsIPrintStatusFeedback.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsString.h"
|
||||
|
||||
class nsPrintProgress : public nsIPrintProgress, public nsIPrintStatusFeedback
|
||||
{
|
||||
public:
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
NS_DECL_NSIPRINTPROGRESS
|
||||
NS_DECL_NSIWEBPROGRESSLISTENER
|
||||
NS_DECL_NSIPRINTSTATUSFEEDBACK
|
||||
|
||||
explicit nsPrintProgress(nsIPrintSettings* aPrintSettings);
|
||||
|
||||
protected:
|
||||
virtual ~nsPrintProgress();
|
||||
|
||||
private:
|
||||
nsresult ReleaseListeners();
|
||||
|
||||
bool m_closeProgress;
|
||||
bool m_processCanceled;
|
||||
nsString m_pendingStatus;
|
||||
int32_t m_pendingStateFlags;
|
||||
nsresult m_pendingStateValue;
|
||||
nsCOMPtr<nsIDOMWindow> m_dialog;
|
||||
nsCOMArray<nsIWebProgressListener> m_listenerList;
|
||||
nsCOMPtr<nsIObserver> m_observer;
|
||||
nsCOMPtr<nsIPrintSettings> m_PrintSetting;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
/* -*- 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 "nsPrintProgressParams.h"
|
||||
#include "nsReadableUtils.h"
|
||||
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsPrintProgressParams, nsIPrintProgressParams)
|
||||
|
||||
nsPrintProgressParams::nsPrintProgressParams()
|
||||
{
|
||||
}
|
||||
|
||||
nsPrintProgressParams::~nsPrintProgressParams()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgressParams::GetDocTitle(char16_t * *aDocTitle)
|
||||
{
|
||||
NS_ENSURE_ARG(aDocTitle);
|
||||
|
||||
*aDocTitle = ToNewUnicode(mDocTitle);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgressParams::SetDocTitle(const char16_t * aDocTitle)
|
||||
{
|
||||
mDocTitle = aDocTitle;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgressParams::GetDocURL(char16_t * *aDocURL)
|
||||
{
|
||||
NS_ENSURE_ARG(aDocURL);
|
||||
|
||||
*aDocURL = ToNewUnicode(mDocURL);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgressParams::SetDocURL(const char16_t * aDocURL)
|
||||
{
|
||||
mDocURL = aDocURL;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
/* -*- 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 __nsPrintProgressParams_h
|
||||
#define __nsPrintProgressParams_h
|
||||
|
||||
#include "nsIPrintProgressParams.h"
|
||||
#include "nsString.h"
|
||||
|
||||
class nsPrintProgressParams : public nsIPrintProgressParams
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIPRINTPROGRESSPARAMS
|
||||
|
||||
nsPrintProgressParams();
|
||||
|
||||
protected:
|
||||
virtual ~nsPrintProgressParams();
|
||||
|
||||
private:
|
||||
nsString mDocTitle;
|
||||
nsString mDocURL;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,298 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* 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 "nsPrintingPromptService.h"
|
||||
|
||||
#include "nsArray.h"
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsIDialogParamBlock.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsISupportsUtils.h"
|
||||
#include "nsString.h"
|
||||
#include "nsIPrintDialogService.h"
|
||||
|
||||
// Printing Progress Includes
|
||||
#include "nsPrintProgress.h"
|
||||
#include "nsPrintProgressParams.h"
|
||||
|
||||
static const char *kPrintDialogURL = "chrome://global/content/printdialog.xul";
|
||||
static const char *kPrintProgressDialogURL = "chrome://global/content/printProgress.xul";
|
||||
static const char *kPrtPrvProgressDialogURL = "chrome://global/content/printPreviewProgress.xul";
|
||||
static const char *kPageSetupDialogURL = "chrome://global/content/printPageSetup.xul";
|
||||
static const char *kPrinterPropertiesURL = "chrome://global/content/printjoboptions.xul";
|
||||
|
||||
/****************************************************************
|
||||
************************* ParamBlock ***************************
|
||||
****************************************************************/
|
||||
|
||||
class ParamBlock {
|
||||
|
||||
public:
|
||||
ParamBlock()
|
||||
{
|
||||
mBlock = 0;
|
||||
}
|
||||
~ParamBlock()
|
||||
{
|
||||
NS_IF_RELEASE(mBlock);
|
||||
}
|
||||
nsresult Init() {
|
||||
return CallCreateInstance(NS_DIALOGPARAMBLOCK_CONTRACTID, &mBlock);
|
||||
}
|
||||
nsIDialogParamBlock * operator->() const MOZ_NO_ADDREF_RELEASE_ON_RETURN { return mBlock; }
|
||||
operator nsIDialogParamBlock * () const { return mBlock; }
|
||||
|
||||
private:
|
||||
nsIDialogParamBlock *mBlock;
|
||||
};
|
||||
|
||||
/****************************************************************
|
||||
***************** nsPrintingPromptService **********************
|
||||
****************************************************************/
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsPrintingPromptService, nsIPrintingPromptService, nsIWebProgressListener)
|
||||
|
||||
nsPrintingPromptService::nsPrintingPromptService()
|
||||
{
|
||||
}
|
||||
|
||||
nsPrintingPromptService::~nsPrintingPromptService()
|
||||
{
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsPrintingPromptService::Init()
|
||||
{
|
||||
nsresult rv;
|
||||
mWatcher = do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrintingPromptService::ShowPrintDialog(mozIDOMWindowProxy *parent,
|
||||
nsIWebBrowserPrint *webBrowserPrint,
|
||||
nsIPrintSettings *printSettings)
|
||||
{
|
||||
NS_ENSURE_ARG(webBrowserPrint);
|
||||
NS_ENSURE_ARG(printSettings);
|
||||
|
||||
// Try to access a component dialog
|
||||
nsCOMPtr<nsIPrintDialogService> dlgPrint(do_GetService(
|
||||
NS_PRINTDIALOGSERVICE_CONTRACTID));
|
||||
if (dlgPrint)
|
||||
return dlgPrint->Show(nsPIDOMWindowOuter::From(parent),
|
||||
printSettings, webBrowserPrint);
|
||||
|
||||
// Show the built-in dialog instead
|
||||
ParamBlock block;
|
||||
nsresult rv = block.Init();
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
block->SetInt(0, 0);
|
||||
return DoDialog(parent, block, webBrowserPrint, printSettings, kPrintDialogURL);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrintingPromptService::ShowProgress(mozIDOMWindowProxy* parent,
|
||||
nsIWebBrowserPrint* webBrowserPrint, // ok to be null
|
||||
nsIPrintSettings* printSettings, // ok to be null
|
||||
nsIObserver* openDialogObserver, // ok to be null
|
||||
bool isForPrinting,
|
||||
nsIWebProgressListener** webProgressListener,
|
||||
nsIPrintProgressParams** printProgressParams,
|
||||
bool* notifyOnOpen)
|
||||
{
|
||||
NS_ENSURE_ARG(webProgressListener);
|
||||
NS_ENSURE_ARG(printProgressParams);
|
||||
NS_ENSURE_ARG(notifyOnOpen);
|
||||
|
||||
*notifyOnOpen = false;
|
||||
|
||||
nsPrintProgress* prtProgress = new nsPrintProgress(printSettings);
|
||||
mPrintProgress = prtProgress;
|
||||
mWebProgressListener = prtProgress;
|
||||
|
||||
nsCOMPtr<nsIPrintProgressParams> prtProgressParams = new nsPrintProgressParams();
|
||||
|
||||
nsCOMPtr<mozIDOMWindowProxy> parentWindow = parent;
|
||||
|
||||
if (mWatcher && !parentWindow) {
|
||||
mWatcher->GetActiveWindow(getter_AddRefs(parentWindow));
|
||||
}
|
||||
|
||||
if (parentWindow) {
|
||||
mPrintProgress->OpenProgressDialog(parentWindow,
|
||||
isForPrinting ? kPrintProgressDialogURL : kPrtPrvProgressDialogURL,
|
||||
prtProgressParams, openDialogObserver, notifyOnOpen);
|
||||
}
|
||||
|
||||
prtProgressParams.forget(printProgressParams);
|
||||
NS_ADDREF(*webProgressListener = this);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrintingPromptService::ShowPageSetup(mozIDOMWindowProxy *parent,
|
||||
nsIPrintSettings *printSettings,
|
||||
nsIObserver *aObs)
|
||||
{
|
||||
NS_ENSURE_ARG(printSettings);
|
||||
|
||||
// Try to access a component dialog
|
||||
nsCOMPtr<nsIPrintDialogService> dlgPrint(do_GetService(
|
||||
NS_PRINTDIALOGSERVICE_CONTRACTID));
|
||||
if (dlgPrint)
|
||||
return dlgPrint->ShowPageSetup(nsPIDOMWindowOuter::From(parent),
|
||||
printSettings);
|
||||
|
||||
ParamBlock block;
|
||||
nsresult rv = block.Init();
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
block->SetInt(0, 0);
|
||||
return DoDialog(parent, block, nullptr, printSettings, kPageSetupDialogURL);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrintingPromptService::ShowPrinterProperties(mozIDOMWindowProxy *parent,
|
||||
const char16_t *printerName,
|
||||
nsIPrintSettings *printSettings)
|
||||
{
|
||||
/* fixme: We simply ignore the |aPrinter| argument here
|
||||
* We should get the supported printer attributes from the printer and
|
||||
* populate the print job options dialog with these data instead of using
|
||||
* the "default set" here.
|
||||
* However, this requires changes on all platforms and is another big chunk
|
||||
* of patches ... ;-(
|
||||
*/
|
||||
NS_ENSURE_ARG(printerName);
|
||||
NS_ENSURE_ARG(printSettings);
|
||||
|
||||
ParamBlock block;
|
||||
nsresult rv = block.Init();
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
block->SetInt(0, 0);
|
||||
return DoDialog(parent, block, nullptr, printSettings, kPrinterPropertiesURL);
|
||||
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsPrintingPromptService::DoDialog(mozIDOMWindowProxy *aParent,
|
||||
nsIDialogParamBlock *aParamBlock,
|
||||
nsIWebBrowserPrint *aWebBrowserPrint,
|
||||
nsIPrintSettings* aPS,
|
||||
const char *aChromeURL)
|
||||
{
|
||||
NS_ENSURE_ARG(aParamBlock);
|
||||
NS_ENSURE_ARG(aPS);
|
||||
NS_ENSURE_ARG(aChromeURL);
|
||||
|
||||
if (!mWatcher)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// get a parent, if at all possible
|
||||
// (though we'd rather this didn't fail, it's OK if it does. so there's
|
||||
// no failure or null check.)
|
||||
nsCOMPtr<mozIDOMWindowProxy> activeParent;
|
||||
if (!aParent)
|
||||
{
|
||||
mWatcher->GetActiveWindow(getter_AddRefs(activeParent));
|
||||
aParent = activeParent;
|
||||
}
|
||||
|
||||
// create a nsIMutableArray of the parameters
|
||||
// being passed to the window
|
||||
nsCOMPtr<nsIMutableArray> array = nsArray::Create();
|
||||
|
||||
nsCOMPtr<nsISupports> psSupports(do_QueryInterface(aPS));
|
||||
NS_ASSERTION(psSupports, "PrintSettings must be a supports");
|
||||
array->AppendElement(psSupports, /*weak =*/ false);
|
||||
|
||||
if (aWebBrowserPrint) {
|
||||
nsCOMPtr<nsISupports> wbpSupports(do_QueryInterface(aWebBrowserPrint));
|
||||
NS_ASSERTION(wbpSupports, "nsIWebBrowserPrint must be a supports");
|
||||
array->AppendElement(wbpSupports, /*weak =*/ false);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISupports> blkSupps(do_QueryInterface(aParamBlock));
|
||||
NS_ASSERTION(blkSupps, "IOBlk must be a supports");
|
||||
array->AppendElement(blkSupps, /*weak =*/ false);
|
||||
|
||||
nsCOMPtr<mozIDOMWindowProxy> dialog;
|
||||
nsresult rv = mWatcher->OpenWindow(aParent, aChromeURL, "_blank",
|
||||
"centerscreen,chrome,modal,titlebar", array,
|
||||
getter_AddRefs(dialog));
|
||||
|
||||
// if aWebBrowserPrint is not null then we are printing
|
||||
// so we want to pass back NS_ERROR_ABORT on cancel
|
||||
if (NS_SUCCEEDED(rv) && aWebBrowserPrint)
|
||||
{
|
||||
int32_t status;
|
||||
aParamBlock->GetInt(0, &status);
|
||||
return status == 0?NS_ERROR_ABORT:NS_OK;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// nsIWebProgressListener
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrintingPromptService::OnStateChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, uint32_t aStateFlags, nsresult aStatus)
|
||||
{
|
||||
if ((aStateFlags & STATE_STOP) && mWebProgressListener) {
|
||||
mWebProgressListener->OnStateChange(aWebProgress, aRequest, aStateFlags, aStatus);
|
||||
if (mPrintProgress) {
|
||||
mPrintProgress->CloseProgressDialog(true);
|
||||
}
|
||||
mPrintProgress = nullptr;
|
||||
mWebProgressListener = nullptr;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrintingPromptService::OnProgressChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, int32_t aCurSelfProgress, int32_t aMaxSelfProgress, int32_t aCurTotalProgress, int32_t aMaxTotalProgress)
|
||||
{
|
||||
if (mWebProgressListener) {
|
||||
return mWebProgressListener->OnProgressChange(aWebProgress, aRequest, aCurSelfProgress, aMaxSelfProgress, aCurTotalProgress, aMaxTotalProgress);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrintingPromptService::OnLocationChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, nsIURI *location, uint32_t aFlags)
|
||||
{
|
||||
if (mWebProgressListener) {
|
||||
return mWebProgressListener->OnLocationChange(aWebProgress, aRequest, location, aFlags);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrintingPromptService::OnStatusChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, nsresult aStatus, const char16_t *aMessage)
|
||||
{
|
||||
if (mWebProgressListener) {
|
||||
return mWebProgressListener->OnStatusChange(aWebProgress, aRequest, aStatus, aMessage);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrintingPromptService::OnSecurityChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, uint32_t state)
|
||||
{
|
||||
if (mWebProgressListener) {
|
||||
return mWebProgressListener->OnSecurityChange(aWebProgress, aRequest, state);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
/* -*- 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 __nsPrintingPromptService_h
|
||||
#define __nsPrintingPromptService_h
|
||||
|
||||
// {E042570C-62DE-4bb6-A6E0-798E3C07B4DF}
|
||||
#define NS_PRINTINGPROMPTSERVICE_CID \
|
||||
{0xe042570c, 0x62de, 0x4bb6, { 0xa6, 0xe0, 0x79, 0x8e, 0x3c, 0x7, 0xb4, 0xdf}}
|
||||
#define NS_PRINTINGPROMPTSERVICE_CONTRACTID \
|
||||
"@mozilla.org/embedcomp/printingprompt-service;1"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIPrintingPromptService.h"
|
||||
#include "nsPIPromptService.h"
|
||||
#include "nsIWindowWatcher.h"
|
||||
|
||||
// Printing Progress Includes
|
||||
#include "nsPrintProgress.h"
|
||||
#include "nsPrintProgressParams.h"
|
||||
#include "nsIWebProgressListener.h"
|
||||
|
||||
class nsIDOMWindow;
|
||||
class nsIDialogParamBlock;
|
||||
|
||||
class nsPrintingPromptService: public nsIPrintingPromptService,
|
||||
public nsIWebProgressListener
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
nsPrintingPromptService();
|
||||
|
||||
nsresult Init();
|
||||
|
||||
NS_DECL_NSIPRINTINGPROMPTSERVICE
|
||||
NS_DECL_NSIWEBPROGRESSLISTENER
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
protected:
|
||||
virtual ~nsPrintingPromptService();
|
||||
|
||||
private:
|
||||
nsresult DoDialog(mozIDOMWindowProxy *aParent,
|
||||
nsIDialogParamBlock *aParamBlock,
|
||||
nsIWebBrowserPrint *aWebBrowserPrint,
|
||||
nsIPrintSettings* aPS,
|
||||
const char *aChromeURL);
|
||||
|
||||
nsCOMPtr<nsIWindowWatcher> mWatcher;
|
||||
nsCOMPtr<nsIPrintProgress> mPrintProgress;
|
||||
nsCOMPtr<nsIWebProgressListener> mWebProgressListener;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
18
embedding/components/printingui/win/moz.build
Normal file
18
embedding/components/printingui/win/moz.build
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
# -*- 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/.
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'nsPrintDialogUtil.cpp',
|
||||
'nsPrintingPromptService.cpp',
|
||||
'nsPrintProgress.cpp',
|
||||
'nsPrintProgressParams.cpp',
|
||||
]
|
||||
|
||||
EXPORTS += [
|
||||
'nsPrintDialogUtil.h',
|
||||
]
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
854
embedding/components/printingui/win/nsPrintDialogUtil.cpp
Normal file
854
embedding/components/printingui/win/nsPrintDialogUtil.cpp
Normal file
|
|
@ -0,0 +1,854 @@
|
|||
/* -*- 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/. */
|
||||
|
||||
/* -------------------------------------------------------------------
|
||||
To Build This:
|
||||
|
||||
You need to add this to the the makefile.win in mozilla/dom/base:
|
||||
|
||||
.\$(OBJDIR)\nsFlyOwnPrintDialog.obj \
|
||||
|
||||
|
||||
And this to the makefile.win in mozilla/content/build:
|
||||
|
||||
WIN_LIBS= \
|
||||
winspool.lib \
|
||||
comctl32.lib \
|
||||
comdlg32.lib
|
||||
|
||||
---------------------------------------------------------------------- */
|
||||
|
||||
#include "plstr.h"
|
||||
#include <windows.h>
|
||||
#include <tchar.h>
|
||||
|
||||
#include <unknwn.h>
|
||||
#include <commdlg.h>
|
||||
|
||||
#include "nsIWebBrowserPrint.h"
|
||||
#include "nsString.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsReadableUtils.h"
|
||||
#include "nsIPrintSettings.h"
|
||||
#include "nsIPrintSettingsWin.h"
|
||||
#include "nsIPrinterEnumerator.h"
|
||||
|
||||
#include "nsRect.h"
|
||||
|
||||
#include "nsIPrefService.h"
|
||||
#include "nsIPrefBranch.h"
|
||||
|
||||
#include "nsCRT.h"
|
||||
#include "prenv.h" /* for PR_GetEnv */
|
||||
|
||||
#include <windows.h>
|
||||
#include <winspool.h>
|
||||
|
||||
// For Localization
|
||||
#include "nsIStringBundle.h"
|
||||
|
||||
// For NS_CopyUnicodeToNative
|
||||
#include "nsNativeCharsetUtils.h"
|
||||
|
||||
// This is for extending the dialog
|
||||
#include <dlgs.h>
|
||||
|
||||
#include "nsWindowsHelpers.h"
|
||||
#include "WinUtils.h"
|
||||
|
||||
// Default labels for the radio buttons
|
||||
static const char* kAsLaidOutOnScreenStr = "As &laid out on the screen";
|
||||
static const char* kTheSelectedFrameStr = "The selected &frame";
|
||||
static const char* kEachFrameSeparately = "&Each frame separately";
|
||||
|
||||
|
||||
//-----------------------------------------------
|
||||
// Global Data
|
||||
//-----------------------------------------------
|
||||
// Identifies which new radio btn was cliked on
|
||||
static UINT gFrameSelectedRadioBtn = 0;
|
||||
|
||||
// Indicates whether the native print dialog was successfully extended
|
||||
static bool gDialogWasExtended = false;
|
||||
|
||||
#define PRINTDLG_PROPERTIES "chrome://global/locale/printdialog.properties"
|
||||
|
||||
static HWND gParentWnd = nullptr;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Return localized bundle for resource strings
|
||||
static nsresult
|
||||
GetLocalizedBundle(const char * aPropFileName, nsIStringBundle** aStrBundle)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aPropFileName);
|
||||
NS_ENSURE_ARG_POINTER(aStrBundle);
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIStringBundle> bundle;
|
||||
|
||||
|
||||
// Create bundle
|
||||
nsCOMPtr<nsIStringBundleService> stringService =
|
||||
do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
|
||||
if (NS_SUCCEEDED(rv) && stringService) {
|
||||
rv = stringService->CreateBundle(aPropFileName, aStrBundle);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Return localized string
|
||||
static nsresult
|
||||
GetLocalizedString(nsIStringBundle* aStrBundle, const char* aKey, nsString& oVal)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aStrBundle);
|
||||
NS_ENSURE_ARG_POINTER(aKey);
|
||||
|
||||
// Determine default label from string bundle
|
||||
nsXPIDLString valUni;
|
||||
nsAutoString key;
|
||||
key.AssignWithConversion(aKey);
|
||||
nsresult rv = aStrBundle->GetStringFromName(key.get(), getter_Copies(valUni));
|
||||
if (NS_SUCCEEDED(rv) && valUni) {
|
||||
oVal.Assign(valUni);
|
||||
} else {
|
||||
oVal.Truncate();
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Set a multi-byte string in the control
|
||||
static void SetTextOnWnd(HWND aControl, const nsString& aStr)
|
||||
{
|
||||
nsAutoCString text;
|
||||
if (NS_SUCCEEDED(NS_CopyUnicodeToNative(aStr, text))) {
|
||||
::SetWindowText(aControl, text.get());
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Will get the control and localized string by "key"
|
||||
static void SetText(HWND aParent,
|
||||
UINT aId,
|
||||
nsIStringBundle* aStrBundle,
|
||||
const char* aKey)
|
||||
{
|
||||
HWND wnd = GetDlgItem (aParent, aId);
|
||||
if (!wnd) {
|
||||
return;
|
||||
}
|
||||
nsAutoString str;
|
||||
nsresult rv = GetLocalizedString(aStrBundle, aKey, str);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
SetTextOnWnd(wnd, str);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
static void SetRadio(HWND aParent,
|
||||
UINT aId,
|
||||
bool aIsSet,
|
||||
bool isEnabled = true)
|
||||
{
|
||||
HWND wnd = ::GetDlgItem (aParent, aId);
|
||||
if (!wnd) {
|
||||
return;
|
||||
}
|
||||
if (!isEnabled) {
|
||||
::EnableWindow(wnd, FALSE);
|
||||
return;
|
||||
}
|
||||
::EnableWindow(wnd, TRUE);
|
||||
::SendMessage(wnd, BM_SETCHECK, (WPARAM)aIsSet, (LPARAM)0);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
static void SetRadioOfGroup(HWND aDlg, int aRadId)
|
||||
{
|
||||
int radioIds[] = {rad4, rad5, rad6};
|
||||
int numRads = 3;
|
||||
|
||||
for (int i=0;i<numRads;i++) {
|
||||
HWND radWnd = ::GetDlgItem(aDlg, radioIds[i]);
|
||||
if (radWnd != nullptr) {
|
||||
::SendMessage(radWnd, BM_SETCHECK, (WPARAM)(radioIds[i] == aRadId), (LPARAM)0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
typedef struct {
|
||||
const char * mKeyStr;
|
||||
long mKeyId;
|
||||
} PropKeyInfo;
|
||||
|
||||
// These are the control ids used in the dialog and
|
||||
// defined by MS-Windows in commdlg.h
|
||||
static PropKeyInfo gAllPropKeys[] = {
|
||||
{"printFramesTitleWindows", grp3},
|
||||
{"asLaidOutWindows", rad4},
|
||||
{"selectedFrameWindows", rad5},
|
||||
{"separateFramesWindows", rad6},
|
||||
{nullptr, 0}};
|
||||
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
//--------------------------------------------------------
|
||||
// Get the absolute coords of the child windows relative
|
||||
// to its parent window
|
||||
static void GetLocalRect(HWND aWnd, RECT& aRect, HWND aParent)
|
||||
{
|
||||
::GetWindowRect(aWnd, &aRect);
|
||||
|
||||
// MapWindowPoints converts screen coordinates to client coordinates.
|
||||
// It works correctly in both left-to-right and right-to-left windows.
|
||||
::MapWindowPoints(nullptr, aParent, (LPPOINT)&aRect, 2);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Show or Hide the control
|
||||
static void Show(HWND aWnd, bool bState)
|
||||
{
|
||||
if (aWnd) {
|
||||
::ShowWindow(aWnd, bState?SW_SHOW:SW_HIDE);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Create a child window "control"
|
||||
static HWND CreateControl(LPCTSTR aType,
|
||||
DWORD aStyle,
|
||||
HINSTANCE aHInst,
|
||||
HWND aHdlg,
|
||||
int aId,
|
||||
const nsAString& aStr,
|
||||
const nsIntRect& aRect)
|
||||
{
|
||||
nsAutoCString str;
|
||||
if (NS_FAILED(NS_CopyUnicodeToNative(aStr, str)))
|
||||
return nullptr;
|
||||
|
||||
HWND hWnd = ::CreateWindow (aType, str.get(),
|
||||
WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | aStyle,
|
||||
aRect.x, aRect.y, aRect.width, aRect.height,
|
||||
(HWND)aHdlg, (HMENU)(intptr_t)aId,
|
||||
aHInst, nullptr);
|
||||
if (hWnd == nullptr) return nullptr;
|
||||
|
||||
// get the native font for the dialog and
|
||||
// set it into the new control
|
||||
HFONT hFont = (HFONT)::SendMessage(aHdlg, WM_GETFONT, (WPARAM)0, (LPARAM)0);
|
||||
if (hFont != nullptr) {
|
||||
::SendMessage(hWnd, WM_SETFONT, (WPARAM) hFont, (LPARAM)0);
|
||||
}
|
||||
return hWnd;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Create a Radio Button
|
||||
static HWND CreateRadioBtn(HINSTANCE aHInst,
|
||||
HWND aHdlg,
|
||||
int aId,
|
||||
const char* aStr,
|
||||
const nsIntRect& aRect)
|
||||
{
|
||||
nsString cStr;
|
||||
cStr.AssignWithConversion(aStr);
|
||||
return CreateControl("BUTTON", BS_RADIOBUTTON, aHInst, aHdlg, aId, cStr, aRect);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Create a Group Box
|
||||
static HWND CreateGroupBox(HINSTANCE aHInst,
|
||||
HWND aHdlg,
|
||||
int aId,
|
||||
const nsAString& aStr,
|
||||
const nsIntRect& aRect)
|
||||
{
|
||||
return CreateControl("BUTTON", BS_GROUPBOX, aHInst, aHdlg, aId, aStr, aRect);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Localizes and initializes the radio buttons and group
|
||||
static void InitializeExtendedDialog(HWND hdlg, int16_t aHowToEnableFrameUI)
|
||||
{
|
||||
MOZ_ASSERT(aHowToEnableFrameUI != nsIPrintSettings::kFrameEnableNone,
|
||||
"should not be called");
|
||||
|
||||
// Localize the new controls in the print dialog
|
||||
nsCOMPtr<nsIStringBundle> strBundle;
|
||||
if (NS_SUCCEEDED(GetLocalizedBundle(PRINTDLG_PROPERTIES, getter_AddRefs(strBundle)))) {
|
||||
int32_t i = 0;
|
||||
while (gAllPropKeys[i].mKeyStr != nullptr) {
|
||||
SetText(hdlg, gAllPropKeys[i].mKeyId, strBundle, gAllPropKeys[i].mKeyStr);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
// Set up radio buttons
|
||||
if (aHowToEnableFrameUI == nsIPrintSettings::kFrameEnableAll) {
|
||||
SetRadio(hdlg, rad4, false);
|
||||
SetRadio(hdlg, rad5, true);
|
||||
SetRadio(hdlg, rad6, false);
|
||||
// set default so user doesn't have to actually press on it
|
||||
gFrameSelectedRadioBtn = rad5;
|
||||
|
||||
} else { // nsIPrintSettings::kFrameEnableAsIsAndEach
|
||||
SetRadio(hdlg, rad4, false);
|
||||
SetRadio(hdlg, rad5, false, false);
|
||||
SetRadio(hdlg, rad6, true);
|
||||
// set default so user doesn't have to actually press on it
|
||||
gFrameSelectedRadioBtn = rad6;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Special Hook Procedure for handling the print dialog messages
|
||||
static UINT CALLBACK PrintHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
|
||||
if (uiMsg == WM_COMMAND) {
|
||||
UINT id = LOWORD(wParam);
|
||||
if (id == rad4 || id == rad5 || id == rad6) {
|
||||
gFrameSelectedRadioBtn = id;
|
||||
SetRadioOfGroup(hdlg, id);
|
||||
}
|
||||
|
||||
} else if (uiMsg == WM_INITDIALOG) {
|
||||
PRINTDLG * printDlg = (PRINTDLG *)lParam;
|
||||
if (printDlg == nullptr) return 0L;
|
||||
|
||||
int16_t howToEnableFrameUI = (int16_t)printDlg->lCustData;
|
||||
// don't add frame options if they would be disabled anyway
|
||||
// because there are no frames
|
||||
if (howToEnableFrameUI == nsIPrintSettings::kFrameEnableNone)
|
||||
return TRUE;
|
||||
|
||||
HINSTANCE hInst = (HINSTANCE)::GetWindowLongPtr(hdlg, GWLP_HINSTANCE);
|
||||
if (hInst == nullptr) return 0L;
|
||||
|
||||
// Start by getting the local rects of several of the controls
|
||||
// so we can calculate where the new controls are
|
||||
HWND wnd = ::GetDlgItem(hdlg, grp1);
|
||||
if (wnd == nullptr) return 0L;
|
||||
RECT dlgRect;
|
||||
GetLocalRect(wnd, dlgRect, hdlg);
|
||||
|
||||
wnd = ::GetDlgItem(hdlg, rad1); // this is the top control "All"
|
||||
if (wnd == nullptr) return 0L;
|
||||
RECT rad1Rect;
|
||||
GetLocalRect(wnd, rad1Rect, hdlg);
|
||||
|
||||
wnd = ::GetDlgItem(hdlg, rad2); // this is the bottom control "Selection"
|
||||
if (wnd == nullptr) return 0L;
|
||||
RECT rad2Rect;
|
||||
GetLocalRect(wnd, rad2Rect, hdlg);
|
||||
|
||||
wnd = ::GetDlgItem(hdlg, rad3); // this is the middle control "Pages"
|
||||
if (wnd == nullptr) return 0L;
|
||||
RECT rad3Rect;
|
||||
GetLocalRect(wnd, rad3Rect, hdlg);
|
||||
|
||||
HWND okWnd = ::GetDlgItem(hdlg, IDOK);
|
||||
if (okWnd == nullptr) return 0L;
|
||||
RECT okRect;
|
||||
GetLocalRect(okWnd, okRect, hdlg);
|
||||
|
||||
wnd = ::GetDlgItem(hdlg, grp4); // this is the "Print range" groupbox
|
||||
if (wnd == nullptr) return 0L;
|
||||
RECT prtRect;
|
||||
GetLocalRect(wnd, prtRect, hdlg);
|
||||
|
||||
|
||||
// calculate various different "gaps" for layout purposes
|
||||
|
||||
int rbGap = rad3Rect.top - rad1Rect.bottom; // gap between radiobtns
|
||||
int grpBotGap = dlgRect.bottom - rad2Rect.bottom; // gap from bottom rb to bottom of grpbox
|
||||
int grpGap = dlgRect.top - prtRect.bottom ; // gap between group boxes
|
||||
int top = dlgRect.bottom + grpGap;
|
||||
int radHgt = rad1Rect.bottom - rad1Rect.top + 1; // top of new group box
|
||||
int y = top+(rad1Rect.top-dlgRect.top); // starting pos of first radio
|
||||
int rbWidth = dlgRect.right - rad1Rect.left - 5; // measure from rb left to the edge of the groupbox
|
||||
// (5 is arbitrary)
|
||||
nsIntRect rect;
|
||||
|
||||
// Create and position the radio buttons
|
||||
//
|
||||
// If any one control cannot be created then
|
||||
// hide the others and bail out
|
||||
//
|
||||
rect.SetRect(rad1Rect.left, y, rbWidth,radHgt);
|
||||
HWND rad4Wnd = CreateRadioBtn(hInst, hdlg, rad4, kAsLaidOutOnScreenStr, rect);
|
||||
if (rad4Wnd == nullptr) return 0L;
|
||||
y += radHgt + rbGap;
|
||||
|
||||
rect.SetRect(rad1Rect.left, y, rbWidth, radHgt);
|
||||
HWND rad5Wnd = CreateRadioBtn(hInst, hdlg, rad5, kTheSelectedFrameStr, rect);
|
||||
if (rad5Wnd == nullptr) {
|
||||
Show(rad4Wnd, FALSE); // hide
|
||||
return 0L;
|
||||
}
|
||||
y += radHgt + rbGap;
|
||||
|
||||
rect.SetRect(rad1Rect.left, y, rbWidth, radHgt);
|
||||
HWND rad6Wnd = CreateRadioBtn(hInst, hdlg, rad6, kEachFrameSeparately, rect);
|
||||
if (rad6Wnd == nullptr) {
|
||||
Show(rad4Wnd, FALSE); // hide
|
||||
Show(rad5Wnd, FALSE); // hide
|
||||
return 0L;
|
||||
}
|
||||
y += radHgt + grpBotGap;
|
||||
|
||||
// Create and position the group box
|
||||
rect.SetRect (dlgRect.left, top, dlgRect.right-dlgRect.left+1, y-top+1);
|
||||
HWND grpBoxWnd = CreateGroupBox(hInst, hdlg, grp3, NS_LITERAL_STRING("Print Frame"), rect);
|
||||
if (grpBoxWnd == nullptr) {
|
||||
Show(rad4Wnd, FALSE); // hide
|
||||
Show(rad5Wnd, FALSE); // hide
|
||||
Show(rad6Wnd, FALSE); // hide
|
||||
return 0L;
|
||||
}
|
||||
|
||||
// Here we figure out the old height of the dlg
|
||||
// then figure its gap from the old grpbx to the bottom
|
||||
// then size the dlg
|
||||
RECT pr, cr;
|
||||
::GetWindowRect(hdlg, &pr);
|
||||
::GetClientRect(hdlg, &cr);
|
||||
|
||||
int dlgHgt = (cr.bottom - cr.top) + 1;
|
||||
int bottomGap = dlgHgt - okRect.bottom;
|
||||
pr.bottom += (dlgRect.bottom-dlgRect.top) + grpGap + 1 - (dlgHgt-dlgRect.bottom) + bottomGap;
|
||||
|
||||
::SetWindowPos(hdlg, nullptr, pr.left, pr.top, pr.right-pr.left+1, pr.bottom-pr.top+1,
|
||||
SWP_NOMOVE|SWP_NOREDRAW|SWP_NOZORDER);
|
||||
|
||||
// figure out the new height of the dialog
|
||||
::GetClientRect(hdlg, &cr);
|
||||
dlgHgt = (cr.bottom - cr.top) + 1;
|
||||
|
||||
// Reposition the OK and Cancel btns
|
||||
int okHgt = okRect.bottom - okRect.top + 1;
|
||||
::SetWindowPos(okWnd, nullptr, okRect.left, dlgHgt-bottomGap-okHgt, 0, 0,
|
||||
SWP_NOSIZE|SWP_NOREDRAW|SWP_NOZORDER);
|
||||
|
||||
HWND cancelWnd = ::GetDlgItem(hdlg, IDCANCEL);
|
||||
if (cancelWnd == nullptr) return 0L;
|
||||
|
||||
RECT cancelRect;
|
||||
GetLocalRect(cancelWnd, cancelRect, hdlg);
|
||||
int cancelHgt = cancelRect.bottom - cancelRect.top + 1;
|
||||
::SetWindowPos(cancelWnd, nullptr, cancelRect.left, dlgHgt-bottomGap-cancelHgt, 0, 0,
|
||||
SWP_NOSIZE|SWP_NOREDRAW|SWP_NOZORDER);
|
||||
|
||||
// localize and initialize the groupbox and radiobuttons
|
||||
InitializeExtendedDialog(hdlg, howToEnableFrameUI);
|
||||
|
||||
// Looks like we were able to extend the dialog
|
||||
gDialogWasExtended = true;
|
||||
return TRUE;
|
||||
}
|
||||
return 0L;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Returns a Global Moveable Memory Handle to a DevMode
|
||||
// from the Printer by the name of aPrintName
|
||||
//
|
||||
// NOTE:
|
||||
// This function assumes that aPrintName has already been converted from
|
||||
// unicode
|
||||
//
|
||||
static nsReturnRef<nsHGLOBAL>
|
||||
CreateGlobalDevModeAndInit(const nsXPIDLString& aPrintName,
|
||||
nsIPrintSettings* aPS)
|
||||
{
|
||||
nsHPRINTER hPrinter = nullptr;
|
||||
// const cast kludge for silly Win32 api's
|
||||
LPWSTR printName = const_cast<wchar_t*>(static_cast<const wchar_t*>(aPrintName.get()));
|
||||
BOOL status = ::OpenPrinterW(printName, &hPrinter, nullptr);
|
||||
if (!status) {
|
||||
return nsReturnRef<nsHGLOBAL>();
|
||||
}
|
||||
|
||||
// Make sure hPrinter is closed on all paths
|
||||
nsAutoPrinter autoPrinter(hPrinter);
|
||||
|
||||
// Get the buffer size
|
||||
LONG needed = ::DocumentPropertiesW(gParentWnd, hPrinter, printName, nullptr,
|
||||
nullptr, 0);
|
||||
if (needed < 0) {
|
||||
return nsReturnRef<nsHGLOBAL>();
|
||||
}
|
||||
|
||||
// Allocate a buffer of the correct size.
|
||||
nsAutoDevMode newDevMode((LPDEVMODEW)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||
needed));
|
||||
if (!newDevMode) {
|
||||
return nsReturnRef<nsHGLOBAL>();
|
||||
}
|
||||
|
||||
nsHGLOBAL hDevMode = ::GlobalAlloc(GHND, needed);
|
||||
nsAutoGlobalMem globalDevMode(hDevMode);
|
||||
if (!hDevMode) {
|
||||
return nsReturnRef<nsHGLOBAL>();
|
||||
}
|
||||
|
||||
LONG ret = ::DocumentPropertiesW(gParentWnd, hPrinter, printName, newDevMode,
|
||||
nullptr, DM_OUT_BUFFER);
|
||||
if (ret != IDOK) {
|
||||
return nsReturnRef<nsHGLOBAL>();
|
||||
}
|
||||
|
||||
// Lock memory and copy contents from DEVMODE (current printer)
|
||||
// to Global Memory DEVMODE
|
||||
LPDEVMODEW devMode = (DEVMODEW *)::GlobalLock(hDevMode);
|
||||
if (!devMode) {
|
||||
return nsReturnRef<nsHGLOBAL>();
|
||||
}
|
||||
|
||||
memcpy(devMode, newDevMode.get(), needed);
|
||||
// Initialize values from the PrintSettings
|
||||
nsCOMPtr<nsIPrintSettingsWin> psWin = do_QueryInterface(aPS);
|
||||
MOZ_ASSERT(psWin);
|
||||
psWin->CopyToNative(devMode);
|
||||
|
||||
// Sets back the changes we made to the DevMode into the Printer Driver
|
||||
ret = ::DocumentPropertiesW(gParentWnd, hPrinter, printName, devMode, devMode,
|
||||
DM_IN_BUFFER | DM_OUT_BUFFER);
|
||||
if (ret != IDOK) {
|
||||
::GlobalUnlock(hDevMode);
|
||||
return nsReturnRef<nsHGLOBAL>();
|
||||
}
|
||||
|
||||
::GlobalUnlock(hDevMode);
|
||||
|
||||
return globalDevMode.out();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// helper
|
||||
static void GetDefaultPrinterNameFromGlobalPrinters(nsXPIDLString &printerName)
|
||||
{
|
||||
nsCOMPtr<nsIPrinterEnumerator> prtEnum = do_GetService("@mozilla.org/gfx/printerenumerator;1");
|
||||
if (prtEnum) {
|
||||
prtEnum->GetDefaultPrinterName(getter_Copies(printerName));
|
||||
}
|
||||
}
|
||||
|
||||
// Determine whether we have a completely native dialog
|
||||
// or whether we cshould extend it
|
||||
static bool ShouldExtendPrintDialog()
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIPrefService> prefs =
|
||||
do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, true);
|
||||
nsCOMPtr<nsIPrefBranch> prefBranch;
|
||||
rv = prefs->GetBranch(nullptr, getter_AddRefs(prefBranch));
|
||||
NS_ENSURE_SUCCESS(rv, true);
|
||||
|
||||
bool result;
|
||||
rv = prefBranch->GetBoolPref("print.extend_native_print_dialog", &result);
|
||||
NS_ENSURE_SUCCESS(rv, true);
|
||||
return result;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Displays the native Print Dialog
|
||||
static nsresult
|
||||
ShowNativePrintDialog(HWND aHWnd,
|
||||
nsIPrintSettings* aPrintSettings)
|
||||
{
|
||||
//NS_ENSURE_ARG_POINTER(aHWnd);
|
||||
NS_ENSURE_ARG_POINTER(aPrintSettings);
|
||||
|
||||
gDialogWasExtended = false;
|
||||
|
||||
// Get the Print Name to be used
|
||||
nsXPIDLString printerName;
|
||||
aPrintSettings->GetPrinterName(getter_Copies(printerName));
|
||||
|
||||
// If there is no name then use the default printer
|
||||
if (printerName.IsEmpty()) {
|
||||
GetDefaultPrinterNameFromGlobalPrinters(printerName);
|
||||
} else {
|
||||
HANDLE hPrinter = nullptr;
|
||||
if(!::OpenPrinterW(const_cast<wchar_t*>(static_cast<const wchar_t*>(printerName.get())),
|
||||
&hPrinter, nullptr)) {
|
||||
// If the last used printer is not found, we should use default printer.
|
||||
GetDefaultPrinterNameFromGlobalPrinters(printerName);
|
||||
} else {
|
||||
::ClosePrinter(hPrinter);
|
||||
}
|
||||
}
|
||||
|
||||
// Now create a DEVNAMES struct so the the dialog is initialized correctly.
|
||||
|
||||
uint32_t len = printerName.Length();
|
||||
nsHGLOBAL hDevNames = ::GlobalAlloc(GHND, sizeof(wchar_t) * (len + 1)
|
||||
+ sizeof(DEVNAMES));
|
||||
nsAutoGlobalMem autoDevNames(hDevNames);
|
||||
if (!hDevNames) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
DEVNAMES* pDevNames = (DEVNAMES*)::GlobalLock(hDevNames);
|
||||
if (!pDevNames) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
pDevNames->wDriverOffset = sizeof(DEVNAMES)/sizeof(wchar_t);
|
||||
pDevNames->wDeviceOffset = sizeof(DEVNAMES)/sizeof(wchar_t);
|
||||
pDevNames->wOutputOffset = sizeof(DEVNAMES)/sizeof(wchar_t)+len;
|
||||
pDevNames->wDefault = 0;
|
||||
|
||||
memcpy(pDevNames+1, printerName, (len + 1) * sizeof(wchar_t));
|
||||
::GlobalUnlock(hDevNames);
|
||||
|
||||
// Create a Moveable Memory Object that holds a new DevMode
|
||||
// from the Printer Name
|
||||
// The PRINTDLG.hDevMode requires that it be a moveable memory object
|
||||
// NOTE: autoDevMode is automatically freed when any error occurred
|
||||
nsAutoGlobalMem autoDevMode(CreateGlobalDevModeAndInit(printerName, aPrintSettings));
|
||||
|
||||
// Prepare to Display the Print Dialog
|
||||
PRINTDLGW prntdlg;
|
||||
memset(&prntdlg, 0, sizeof(PRINTDLGW));
|
||||
|
||||
prntdlg.lStructSize = sizeof(prntdlg);
|
||||
prntdlg.hwndOwner = aHWnd;
|
||||
prntdlg.hDevMode = autoDevMode.get();
|
||||
prntdlg.hDevNames = hDevNames;
|
||||
prntdlg.hDC = nullptr;
|
||||
prntdlg.Flags = PD_ALLPAGES | PD_RETURNIC |
|
||||
PD_USEDEVMODECOPIESANDCOLLATE | PD_COLLATE;
|
||||
|
||||
// if there is a current selection then enable the "Selection" radio button
|
||||
int16_t howToEnableFrameUI = nsIPrintSettings::kFrameEnableNone;
|
||||
bool isOn;
|
||||
aPrintSettings->GetPrintOptions(nsIPrintSettings::kEnableSelectionRB, &isOn);
|
||||
if (!isOn) {
|
||||
prntdlg.Flags |= PD_NOSELECTION;
|
||||
}
|
||||
aPrintSettings->GetHowToEnableFrameUI(&howToEnableFrameUI);
|
||||
|
||||
int32_t pg = 1;
|
||||
aPrintSettings->GetStartPageRange(&pg);
|
||||
prntdlg.nFromPage = pg;
|
||||
|
||||
aPrintSettings->GetEndPageRange(&pg);
|
||||
prntdlg.nToPage = pg;
|
||||
|
||||
prntdlg.nMinPage = 1;
|
||||
prntdlg.nMaxPage = 0xFFFF;
|
||||
prntdlg.nCopies = 1;
|
||||
prntdlg.lpfnSetupHook = nullptr;
|
||||
prntdlg.lpSetupTemplateName = nullptr;
|
||||
prntdlg.hPrintTemplate = nullptr;
|
||||
prntdlg.hSetupTemplate = nullptr;
|
||||
|
||||
prntdlg.hInstance = nullptr;
|
||||
prntdlg.lpPrintTemplateName = nullptr;
|
||||
|
||||
if (!ShouldExtendPrintDialog()) {
|
||||
prntdlg.lCustData = 0;
|
||||
prntdlg.lpfnPrintHook = nullptr;
|
||||
} else {
|
||||
// Set up print dialog "hook" procedure for extending the dialog
|
||||
prntdlg.lCustData = (DWORD)howToEnableFrameUI;
|
||||
prntdlg.lpfnPrintHook = (LPPRINTHOOKPROC)PrintHookProc;
|
||||
prntdlg.Flags |= PD_ENABLEPRINTHOOK;
|
||||
}
|
||||
|
||||
BOOL result;
|
||||
{
|
||||
mozilla::widget::WinUtils::AutoSystemDpiAware dpiAwareness;
|
||||
result = ::PrintDlgW(&prntdlg);
|
||||
}
|
||||
|
||||
if (TRUE == result) {
|
||||
// check to make sure we don't have any nullptr pointers
|
||||
NS_ENSURE_TRUE(aPrintSettings && prntdlg.hDevMode, NS_ERROR_FAILURE);
|
||||
|
||||
if (prntdlg.hDevNames == nullptr) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
// Lock the deviceNames and check for nullptr
|
||||
DEVNAMES *devnames = (DEVNAMES *)::GlobalLock(prntdlg.hDevNames);
|
||||
if (devnames == nullptr) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
char16_t* device = &(((char16_t *)devnames)[devnames->wDeviceOffset]);
|
||||
char16_t* driver = &(((char16_t *)devnames)[devnames->wDriverOffset]);
|
||||
|
||||
// Check to see if the "Print To File" control is checked
|
||||
// then take the name from devNames and set it in the PrintSettings
|
||||
//
|
||||
// NOTE:
|
||||
// As per Microsoft SDK documentation the returned value offset from
|
||||
// devnames->wOutputOffset is either "FILE:" or nullptr
|
||||
// if the "Print To File" checkbox is checked it MUST be "FILE:"
|
||||
// We assert as an extra safety check.
|
||||
if (prntdlg.Flags & PD_PRINTTOFILE) {
|
||||
char16ptr_t fileName = &(((wchar_t *)devnames)[devnames->wOutputOffset]);
|
||||
NS_ASSERTION(wcscmp(fileName, L"FILE:") == 0, "FileName must be `FILE:`");
|
||||
aPrintSettings->SetToFileName(fileName);
|
||||
aPrintSettings->SetPrintToFile(true);
|
||||
} else {
|
||||
// clear "print to file" info
|
||||
aPrintSettings->SetPrintToFile(false);
|
||||
aPrintSettings->SetToFileName(nullptr);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPrintSettingsWin> psWin(do_QueryInterface(aPrintSettings));
|
||||
if (!psWin) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Setup local Data members
|
||||
psWin->SetDeviceName(device);
|
||||
psWin->SetDriverName(driver);
|
||||
|
||||
#if defined(DEBUG_rods) || defined(DEBUG_dcone)
|
||||
wprintf(L"printer: driver %s, device %s flags: %d\n", driver, device, prntdlg.Flags);
|
||||
#endif
|
||||
// fill the print options with the info from the dialog
|
||||
|
||||
aPrintSettings->SetPrinterName(device);
|
||||
|
||||
if (prntdlg.Flags & PD_SELECTION) {
|
||||
aPrintSettings->SetPrintRange(nsIPrintSettings::kRangeSelection);
|
||||
|
||||
} else if (prntdlg.Flags & PD_PAGENUMS) {
|
||||
aPrintSettings->SetPrintRange(nsIPrintSettings::kRangeSpecifiedPageRange);
|
||||
aPrintSettings->SetStartPageRange(prntdlg.nFromPage);
|
||||
aPrintSettings->SetEndPageRange(prntdlg.nToPage);
|
||||
|
||||
} else { // (prntdlg.Flags & PD_ALLPAGES)
|
||||
aPrintSettings->SetPrintRange(nsIPrintSettings::kRangeAllPages);
|
||||
}
|
||||
|
||||
if (howToEnableFrameUI != nsIPrintSettings::kFrameEnableNone) {
|
||||
// make sure the dialog got extended
|
||||
if (gDialogWasExtended) {
|
||||
// check to see about the frame radio buttons
|
||||
switch (gFrameSelectedRadioBtn) {
|
||||
case rad4:
|
||||
aPrintSettings->SetPrintFrameType(nsIPrintSettings::kFramesAsIs);
|
||||
break;
|
||||
case rad5:
|
||||
aPrintSettings->SetPrintFrameType(nsIPrintSettings::kSelectedFrame);
|
||||
break;
|
||||
case rad6:
|
||||
aPrintSettings->SetPrintFrameType(nsIPrintSettings::kEachFrameSep);
|
||||
break;
|
||||
} // switch
|
||||
} else {
|
||||
// if it didn't get extended then have it default to printing
|
||||
// each frame separately
|
||||
aPrintSettings->SetPrintFrameType(nsIPrintSettings::kEachFrameSep);
|
||||
}
|
||||
} else {
|
||||
aPrintSettings->SetPrintFrameType(nsIPrintSettings::kNoFrames);
|
||||
}
|
||||
// Unlock DeviceNames
|
||||
::GlobalUnlock(prntdlg.hDevNames);
|
||||
|
||||
// Transfer the settings from the native data to the PrintSettings
|
||||
LPDEVMODEW devMode = (LPDEVMODEW)::GlobalLock(prntdlg.hDevMode);
|
||||
if (!devMode || !prntdlg.hDC) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
psWin->SetDevMode(devMode); // copies DevMode
|
||||
psWin->CopyFromNative(prntdlg.hDC, devMode);
|
||||
::GlobalUnlock(prntdlg.hDevMode);
|
||||
::DeleteDC(prntdlg.hDC);
|
||||
|
||||
#if defined(DEBUG_rods) || defined(DEBUG_dcone)
|
||||
bool printSelection = prntdlg.Flags & PD_SELECTION;
|
||||
bool printAllPages = prntdlg.Flags & PD_ALLPAGES;
|
||||
bool printNumPages = prntdlg.Flags & PD_PAGENUMS;
|
||||
int32_t fromPageNum = 0;
|
||||
int32_t toPageNum = 0;
|
||||
|
||||
if (printNumPages) {
|
||||
fromPageNum = prntdlg.nFromPage;
|
||||
toPageNum = prntdlg.nToPage;
|
||||
}
|
||||
if (printSelection) {
|
||||
printf("Printing the selection\n");
|
||||
|
||||
} else if (printAllPages) {
|
||||
printf("Printing all the pages\n");
|
||||
|
||||
} else {
|
||||
printf("Printing from page no. %d to %d\n", fromPageNum, toPageNum);
|
||||
}
|
||||
#endif
|
||||
|
||||
} else {
|
||||
::SetFocus(aHWnd);
|
||||
aPrintSettings->SetIsCancelled(true);
|
||||
return NS_ERROR_ABORT;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
static void
|
||||
PrepareForPrintDialog(nsIWebBrowserPrint* aWebBrowserPrint, nsIPrintSettings* aPS)
|
||||
{
|
||||
NS_ASSERTION(aWebBrowserPrint, "Can't be null");
|
||||
NS_ASSERTION(aPS, "Can't be null");
|
||||
|
||||
bool isFramesetDocument;
|
||||
bool isFramesetFrameSelected;
|
||||
bool isIFrameSelected;
|
||||
bool isRangeSelection;
|
||||
|
||||
aWebBrowserPrint->GetIsFramesetDocument(&isFramesetDocument);
|
||||
aWebBrowserPrint->GetIsFramesetFrameSelected(&isFramesetFrameSelected);
|
||||
aWebBrowserPrint->GetIsIFrameSelected(&isIFrameSelected);
|
||||
aWebBrowserPrint->GetIsRangeSelection(&isRangeSelection);
|
||||
|
||||
// Setup print options for UI
|
||||
if (isFramesetDocument) {
|
||||
if (isFramesetFrameSelected) {
|
||||
aPS->SetHowToEnableFrameUI(nsIPrintSettings::kFrameEnableAll);
|
||||
} else {
|
||||
aPS->SetHowToEnableFrameUI(nsIPrintSettings::kFrameEnableAsIsAndEach);
|
||||
}
|
||||
} else {
|
||||
aPS->SetHowToEnableFrameUI(nsIPrintSettings::kFrameEnableNone);
|
||||
}
|
||||
|
||||
// Now determine how to set up the Frame print UI
|
||||
aPS->SetPrintOptions(nsIPrintSettings::kEnableSelectionRB, isRangeSelection || isIFrameSelected);
|
||||
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
//-- Show Print Dialog
|
||||
//----------------------------------------------------------------------------------
|
||||
nsresult NativeShowPrintDialog(HWND aHWnd,
|
||||
nsIWebBrowserPrint* aWebBrowserPrint,
|
||||
nsIPrintSettings* aPrintSettings)
|
||||
{
|
||||
PrepareForPrintDialog(aWebBrowserPrint, aPrintSettings);
|
||||
|
||||
nsresult rv = ShowNativePrintDialog(aHWnd, aPrintSettings);
|
||||
if (aHWnd) {
|
||||
::DestroyWindow(aHWnd);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
12
embedding/components/printingui/win/nsPrintDialogUtil.h
Normal file
12
embedding/components/printingui/win/nsPrintDialogUtil.h
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
/* -*- 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 nsFlyOwnDialog_h___
|
||||
#define nsFlyOwnDialog_h___
|
||||
|
||||
nsresult NativeShowPrintDialog(HWND aHWnd,
|
||||
nsIWebBrowserPrint* aWebBrowserPrint,
|
||||
nsIPrintSettings* aPrintSettings);
|
||||
|
||||
#endif /* nsFlyOwnDialog_h___ */
|
||||
293
embedding/components/printingui/win/nsPrintProgress.cpp
Normal file
293
embedding/components/printingui/win/nsPrintProgress.cpp
Normal file
|
|
@ -0,0 +1,293 @@
|
|||
/* -*- 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 "nsPrintProgress.h"
|
||||
|
||||
#include "nsArray.h"
|
||||
#include "nsIBaseWindow.h"
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsIDocShellTreeOwner.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
#include "nsIXULWindow.h"
|
||||
#include "nsXPCOM.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
|
||||
#if 0
|
||||
NS_IMPL_ADDREF(nsPrintProgress)
|
||||
NS_IMPL_RELEASE(nsPrintProgress)
|
||||
#else
|
||||
NS_IMETHODIMP_(MozExternalRefCountType) nsPrintProgress::AddRef(void)
|
||||
{
|
||||
NS_PRECONDITION(int32_t(mRefCnt) >= 0, "illegal refcnt");
|
||||
nsrefcnt count;
|
||||
count = ++mRefCnt;
|
||||
//NS_LOG_ADDREF(this, count, "nsPrintProgress", sizeof(*this));
|
||||
return count;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(MozExternalRefCountType) nsPrintProgress::Release(void)
|
||||
{
|
||||
nsrefcnt count;
|
||||
NS_PRECONDITION(0 != mRefCnt, "dup release");
|
||||
count = --mRefCnt;
|
||||
//NS_LOG_RELEASE(this, count, "nsPrintProgress");
|
||||
if (0 == count) {
|
||||
mRefCnt = 1; /* stabilize */
|
||||
/* enable this to find non-threadsafe destructors: */
|
||||
/* NS_ASSERT_OWNINGTHREAD(nsPrintProgress); */
|
||||
delete this;
|
||||
return 0;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(nsPrintProgress)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIPrintStatusFeedback)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIPrintProgress)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIPrintStatusFeedback)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIWebProgressListener)
|
||||
NS_INTERFACE_MAP_END_THREADSAFE
|
||||
|
||||
|
||||
nsPrintProgress::nsPrintProgress()
|
||||
{
|
||||
m_closeProgress = false;
|
||||
m_processCanceled = false;
|
||||
m_pendingStateFlags = -1;
|
||||
m_pendingStateValue = NS_OK;
|
||||
}
|
||||
|
||||
nsPrintProgress::~nsPrintProgress()
|
||||
{
|
||||
(void)ReleaseListeners();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::OpenProgressDialog(mozIDOMWindowProxy *parent,
|
||||
const char *dialogURL,
|
||||
nsISupports *parameters,
|
||||
nsIObserver *openDialogObserver,
|
||||
bool *notifyOnOpen)
|
||||
{
|
||||
*notifyOnOpen = true;
|
||||
m_observer = openDialogObserver;
|
||||
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
|
||||
if (m_dialog)
|
||||
return NS_ERROR_ALREADY_INITIALIZED;
|
||||
|
||||
if (!dialogURL || !*dialogURL)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
if (parent)
|
||||
{
|
||||
// Set up window.arguments[0]...
|
||||
nsCOMPtr<nsIMutableArray> array = nsArray::Create();
|
||||
|
||||
nsCOMPtr<nsISupportsInterfacePointer> ifptr =
|
||||
do_CreateInstance(NS_SUPPORTS_INTERFACE_POINTER_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
ifptr->SetData(static_cast<nsIPrintProgress*>(this));
|
||||
ifptr->SetDataIID(&NS_GET_IID(nsIPrintProgress));
|
||||
|
||||
array->AppendElement(ifptr, /*weak =*/ false);
|
||||
|
||||
array->AppendElement(parameters, /*weak = */ false);
|
||||
|
||||
// We will set the opener of the dialog to be the nsIDOMWindow for the
|
||||
// browser XUL window itself, as opposed to the content. That way, the
|
||||
// progress window has access to the opener.
|
||||
nsCOMPtr<nsPIDOMWindowOuter> pParentWindow = nsPIDOMWindowOuter::From(parent);
|
||||
NS_ENSURE_STATE(pParentWindow);
|
||||
|
||||
nsCOMPtr<nsIDocShell> docShell = pParentWindow->GetDocShell();
|
||||
NS_ENSURE_STATE(docShell);
|
||||
|
||||
nsCOMPtr<nsIDocShellTreeOwner> owner;
|
||||
docShell->GetTreeOwner(getter_AddRefs(owner));
|
||||
|
||||
nsCOMPtr<nsIXULWindow> ownerXULWindow = do_GetInterface(owner);
|
||||
nsCOMPtr<mozIDOMWindowProxy> ownerWindow = do_GetInterface(ownerXULWindow);
|
||||
NS_ENSURE_STATE(ownerWindow);
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowOuter> piOwnerWindow = nsPIDOMWindowOuter::From(ownerWindow);
|
||||
|
||||
// Open the dialog.
|
||||
nsCOMPtr<nsPIDOMWindowOuter> newWindow;
|
||||
rv = piOwnerWindow->OpenDialog(NS_ConvertASCIItoUTF16(dialogURL),
|
||||
NS_LITERAL_STRING("_blank"),
|
||||
NS_LITERAL_STRING("chrome,titlebar,dependent,centerscreen"),
|
||||
array, getter_AddRefs(newWindow));
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::CloseProgressDialog(bool forceClose)
|
||||
{
|
||||
m_closeProgress = true;
|
||||
// XXX Casting from bool to nsresult
|
||||
return OnStateChange(nullptr, nullptr, nsIWebProgressListener::STATE_STOP,
|
||||
static_cast<nsresult>(forceClose));
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::GetPrompter(nsIPrompt **_retval)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(_retval);
|
||||
*_retval = nullptr;
|
||||
|
||||
if (! m_closeProgress && m_dialog) {
|
||||
nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryInterface(m_dialog);
|
||||
MOZ_ASSERT(window);
|
||||
return window->GetPrompter(_retval);
|
||||
}
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::GetProcessCanceledByUser(bool *aProcessCanceledByUser)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aProcessCanceledByUser);
|
||||
*aProcessCanceledByUser = m_processCanceled;
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHODIMP nsPrintProgress::SetProcessCanceledByUser(bool aProcessCanceledByUser)
|
||||
{
|
||||
m_processCanceled = aProcessCanceledByUser;
|
||||
OnStateChange(nullptr, nullptr, nsIWebProgressListener::STATE_STOP, NS_OK);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::RegisterListener(nsIWebProgressListener * listener)
|
||||
{
|
||||
if (!listener) //Nothing to do with a null listener!
|
||||
return NS_OK;
|
||||
|
||||
m_listenerList.AppendObject(listener);
|
||||
if (m_closeProgress || m_processCanceled)
|
||||
listener->OnStateChange(nullptr, nullptr,
|
||||
nsIWebProgressListener::STATE_STOP, NS_OK);
|
||||
else
|
||||
{
|
||||
listener->OnStatusChange(nullptr, nullptr, NS_OK, m_pendingStatus.get());
|
||||
if (m_pendingStateFlags != -1)
|
||||
listener->OnStateChange(nullptr, nullptr, m_pendingStateFlags, m_pendingStateValue);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::UnregisterListener(nsIWebProgressListener *listener)
|
||||
{
|
||||
if (listener)
|
||||
m_listenerList.RemoveObject(listener);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::DoneIniting()
|
||||
{
|
||||
if (m_observer) {
|
||||
m_observer->Observe(nullptr, nullptr, nullptr);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::OnStateChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, uint32_t aStateFlags, nsresult aStatus)
|
||||
{
|
||||
m_pendingStateFlags = aStateFlags;
|
||||
m_pendingStateValue = aStatus;
|
||||
|
||||
uint32_t count = m_listenerList.Count();
|
||||
for (uint32_t i = count - 1; i < count; i --)
|
||||
{
|
||||
nsCOMPtr<nsIWebProgressListener> progressListener = m_listenerList.SafeObjectAt(i);
|
||||
if (progressListener)
|
||||
progressListener->OnStateChange(aWebProgress, aRequest, aStateFlags, aStatus);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::OnProgressChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, int32_t aCurSelfProgress, int32_t aMaxSelfProgress, int32_t aCurTotalProgress, int32_t aMaxTotalProgress)
|
||||
{
|
||||
uint32_t count = m_listenerList.Count();
|
||||
for (uint32_t i = count - 1; i < count; i --)
|
||||
{
|
||||
nsCOMPtr<nsIWebProgressListener> progressListener = m_listenerList.SafeObjectAt(i);
|
||||
if (progressListener)
|
||||
progressListener->OnProgressChange(aWebProgress, aRequest, aCurSelfProgress, aMaxSelfProgress, aCurTotalProgress, aMaxTotalProgress);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::OnLocationChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, nsIURI *location, uint32_t aFlags)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::OnStatusChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, nsresult aStatus, const char16_t *aMessage)
|
||||
{
|
||||
if (aMessage && *aMessage)
|
||||
m_pendingStatus = aMessage;
|
||||
|
||||
uint32_t count = m_listenerList.Count();
|
||||
for (uint32_t i = count - 1; i < count; i --)
|
||||
{
|
||||
nsCOMPtr<nsIWebProgressListener> progressListener = m_listenerList.SafeObjectAt(i);
|
||||
if (progressListener)
|
||||
progressListener->OnStatusChange(aWebProgress, aRequest, aStatus, aMessage);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::OnSecurityChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, uint32_t state)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsPrintProgress::ReleaseListeners()
|
||||
{
|
||||
m_listenerList.Clear();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::ShowStatusString(const char16_t *status)
|
||||
{
|
||||
return OnStatusChange(nullptr, nullptr, NS_OK, status);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::StartMeteors()
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::StopMeteors()
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::ShowProgress(int32_t percent)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::SetDocShell(nsIDocShell *shell, mozIDOMWindowProxy *window)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::CloseWindow()
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
43
embedding/components/printingui/win/nsPrintProgress.h
Normal file
43
embedding/components/printingui/win/nsPrintProgress.h
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
/* -*- 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 __nsPrintProgress_h
|
||||
#define __nsPrintProgress_h
|
||||
|
||||
#include "nsIPrintProgress.h"
|
||||
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "nsIPrintStatusFeedback.h"
|
||||
#include "nsString.h"
|
||||
#include "nsIWindowWatcher.h"
|
||||
#include "nsIObserver.h"
|
||||
|
||||
class nsPrintProgress : public nsIPrintProgress, public nsIPrintStatusFeedback
|
||||
{
|
||||
public:
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
NS_DECL_NSIPRINTPROGRESS
|
||||
NS_DECL_NSIWEBPROGRESSLISTENER
|
||||
NS_DECL_NSIPRINTSTATUSFEEDBACK
|
||||
|
||||
nsPrintProgress();
|
||||
virtual ~nsPrintProgress();
|
||||
|
||||
private:
|
||||
nsresult ReleaseListeners();
|
||||
|
||||
bool m_closeProgress;
|
||||
bool m_processCanceled;
|
||||
nsString m_pendingStatus;
|
||||
int32_t m_pendingStateFlags;
|
||||
nsresult m_pendingStateValue;
|
||||
nsCOMPtr<nsIDOMWindow> m_dialog;
|
||||
nsCOMArray<nsIWebProgressListener> m_listenerList;
|
||||
nsCOMPtr<nsIObserver> m_observer;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
/* -*- 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 "nsPrintProgressParams.h"
|
||||
#include "nsReadableUtils.h"
|
||||
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsPrintProgressParams, nsIPrintProgressParams)
|
||||
|
||||
nsPrintProgressParams::nsPrintProgressParams()
|
||||
{
|
||||
}
|
||||
|
||||
nsPrintProgressParams::~nsPrintProgressParams()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgressParams::GetDocTitle(char16_t * *aDocTitle)
|
||||
{
|
||||
NS_ENSURE_ARG(aDocTitle);
|
||||
|
||||
*aDocTitle = ToNewUnicode(mDocTitle);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgressParams::SetDocTitle(const char16_t * aDocTitle)
|
||||
{
|
||||
mDocTitle = aDocTitle;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgressParams::GetDocURL(char16_t * *aDocURL)
|
||||
{
|
||||
NS_ENSURE_ARG(aDocURL);
|
||||
|
||||
*aDocURL = ToNewUnicode(mDocURL);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgressParams::SetDocURL(const char16_t * aDocURL)
|
||||
{
|
||||
mDocURL = aDocURL;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
27
embedding/components/printingui/win/nsPrintProgressParams.h
Normal file
27
embedding/components/printingui/win/nsPrintProgressParams.h
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
/* -*- 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 __nsPrintProgressParams_h
|
||||
#define __nsPrintProgressParams_h
|
||||
|
||||
#include "nsIPrintProgressParams.h"
|
||||
#include "nsString.h"
|
||||
|
||||
class nsPrintProgressParams : public nsIPrintProgressParams
|
||||
{
|
||||
virtual ~nsPrintProgressParams();
|
||||
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIPRINTPROGRESSPARAMS
|
||||
|
||||
nsPrintProgressParams();
|
||||
|
||||
private:
|
||||
nsString mDocTitle;
|
||||
nsString mDocURL;
|
||||
};
|
||||
|
||||
#endif
|
||||
341
embedding/components/printingui/win/nsPrintingPromptService.cpp
Normal file
341
embedding/components/printingui/win/nsPrintingPromptService.cpp
Normal file
|
|
@ -0,0 +1,341 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* 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 "nsCOMPtr.h"
|
||||
|
||||
#include "nsPrintingPromptService.h"
|
||||
#include "nsIPrintingPromptService.h"
|
||||
#include "nsIFactory.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsReadableUtils.h"
|
||||
#include "nsIEmbeddingSiteWindow.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIWebBrowserChrome.h"
|
||||
#include "nsIWindowWatcher.h"
|
||||
#include "nsPrintDialogUtil.h"
|
||||
|
||||
// Printing Progress Includes
|
||||
#include "nsPrintProgress.h"
|
||||
#include "nsPrintProgressParams.h"
|
||||
#include "nsIWebProgressListener.h"
|
||||
|
||||
// XP Dialog includes
|
||||
#include "nsArray.h"
|
||||
#include "nsIDialogParamBlock.h"
|
||||
#include "nsISupportsUtils.h"
|
||||
|
||||
// Includes need to locate the native Window
|
||||
#include "nsIWidget.h"
|
||||
#include "nsIBaseWindow.h"
|
||||
#include "nsIWebBrowserChrome.h"
|
||||
#include "nsIDocShellTreeOwner.h"
|
||||
#include "nsIDocShellTreeItem.h"
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
|
||||
|
||||
static const char *kPrintProgressDialogURL = "chrome://global/content/printProgress.xul";
|
||||
static const char *kPrtPrvProgressDialogURL = "chrome://global/content/printPreviewProgress.xul";
|
||||
static const char *kPageSetupDialogURL = "chrome://global/content/printPageSetup.xul";
|
||||
|
||||
/****************************************************************
|
||||
************************* ParamBlock ***************************
|
||||
****************************************************************/
|
||||
|
||||
class ParamBlock {
|
||||
|
||||
public:
|
||||
ParamBlock()
|
||||
{
|
||||
mBlock = 0;
|
||||
}
|
||||
~ParamBlock()
|
||||
{
|
||||
NS_IF_RELEASE(mBlock);
|
||||
}
|
||||
nsresult Init() {
|
||||
return CallCreateInstance(NS_DIALOGPARAMBLOCK_CONTRACTID, &mBlock);
|
||||
}
|
||||
nsIDialogParamBlock * operator->() const MOZ_NO_ADDREF_RELEASE_ON_RETURN { return mBlock; }
|
||||
operator nsIDialogParamBlock * const () { return mBlock; }
|
||||
|
||||
private:
|
||||
nsIDialogParamBlock *mBlock;
|
||||
};
|
||||
|
||||
//*****************************************************************************
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsPrintingPromptService, nsIPrintingPromptService, nsIWebProgressListener)
|
||||
|
||||
nsPrintingPromptService::nsPrintingPromptService()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------
|
||||
nsPrintingPromptService::~nsPrintingPromptService()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------
|
||||
nsresult
|
||||
nsPrintingPromptService::Init()
|
||||
{
|
||||
nsresult rv;
|
||||
mWatcher = do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------
|
||||
HWND
|
||||
nsPrintingPromptService::GetHWNDForDOMWindow(mozIDOMWindowProxy *aWindow)
|
||||
{
|
||||
nsCOMPtr<nsIWebBrowserChrome> chrome;
|
||||
|
||||
// We might be embedded so check this path first
|
||||
if (mWatcher) {
|
||||
nsCOMPtr<mozIDOMWindowProxy> fosterParent;
|
||||
if (!aWindow)
|
||||
{ // it will be a dependent window. try to find a foster parent.
|
||||
mWatcher->GetActiveWindow(getter_AddRefs(fosterParent));
|
||||
aWindow = fosterParent;
|
||||
}
|
||||
mWatcher->GetChromeForWindow(aWindow, getter_AddRefs(chrome));
|
||||
}
|
||||
|
||||
if (chrome) {
|
||||
nsCOMPtr<nsIEmbeddingSiteWindow> site(do_QueryInterface(chrome));
|
||||
if (site)
|
||||
{
|
||||
HWND w;
|
||||
site->GetSiteWindow(reinterpret_cast<void **>(&w));
|
||||
return w;
|
||||
}
|
||||
}
|
||||
|
||||
// Now we might be the Browser so check this path
|
||||
nsCOMPtr<nsPIDOMWindowOuter> window = nsPIDOMWindowOuter::From(aWindow);
|
||||
|
||||
nsCOMPtr<nsIDocShellTreeItem> treeItem =
|
||||
do_QueryInterface(window->GetDocShell());
|
||||
if (!treeItem) return nullptr;
|
||||
|
||||
nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
|
||||
treeItem->GetTreeOwner(getter_AddRefs(treeOwner));
|
||||
if (!treeOwner) return nullptr;
|
||||
|
||||
nsCOMPtr<nsIWebBrowserChrome> webBrowserChrome(do_GetInterface(treeOwner));
|
||||
if (!webBrowserChrome) return nullptr;
|
||||
|
||||
nsCOMPtr<nsIBaseWindow> baseWin(do_QueryInterface(webBrowserChrome));
|
||||
if (!baseWin) return nullptr;
|
||||
|
||||
nsCOMPtr<nsIWidget> widget;
|
||||
baseWin->GetMainWidget(getter_AddRefs(widget));
|
||||
if (!widget) return nullptr;
|
||||
|
||||
return (HWND)widget->GetNativeData(NS_NATIVE_TMP_WINDOW);
|
||||
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// nsIPrintingPromptService
|
||||
|
||||
//-----------------------------------------------------------
|
||||
NS_IMETHODIMP
|
||||
nsPrintingPromptService::ShowPrintDialog(mozIDOMWindowProxy *parent, nsIWebBrowserPrint *webBrowserPrint, nsIPrintSettings *printSettings)
|
||||
{
|
||||
NS_ENSURE_ARG(parent);
|
||||
|
||||
HWND hWnd = GetHWNDForDOMWindow(parent);
|
||||
NS_ASSERTION(hWnd, "Couldn't get native window for PRint Dialog!");
|
||||
|
||||
return NativeShowPrintDialog(hWnd, webBrowserPrint, printSettings);
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrintingPromptService::ShowProgress(mozIDOMWindowProxy* parent,
|
||||
nsIWebBrowserPrint* webBrowserPrint, // ok to be null
|
||||
nsIPrintSettings* printSettings, // ok to be null
|
||||
nsIObserver* openDialogObserver, // ok to be null
|
||||
bool isForPrinting,
|
||||
nsIWebProgressListener** webProgressListener,
|
||||
nsIPrintProgressParams** printProgressParams,
|
||||
bool* notifyOnOpen)
|
||||
{
|
||||
NS_ENSURE_ARG(webProgressListener);
|
||||
NS_ENSURE_ARG(printProgressParams);
|
||||
NS_ENSURE_ARG(notifyOnOpen);
|
||||
|
||||
*notifyOnOpen = false;
|
||||
if (mPrintProgress) {
|
||||
*webProgressListener = nullptr;
|
||||
*printProgressParams = nullptr;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsPrintProgress* prtProgress = new nsPrintProgress();
|
||||
mPrintProgress = prtProgress;
|
||||
mWebProgressListener = prtProgress;
|
||||
|
||||
nsCOMPtr<nsIPrintProgressParams> prtProgressParams = new nsPrintProgressParams();
|
||||
|
||||
nsCOMPtr<mozIDOMWindowProxy> parentWindow = parent;
|
||||
|
||||
if (mWatcher && !parentWindow) {
|
||||
mWatcher->GetActiveWindow(getter_AddRefs(parentWindow));
|
||||
}
|
||||
|
||||
if (parentWindow) {
|
||||
mPrintProgress->OpenProgressDialog(parentWindow,
|
||||
isForPrinting ? kPrintProgressDialogURL : kPrtPrvProgressDialogURL,
|
||||
prtProgressParams, openDialogObserver, notifyOnOpen);
|
||||
}
|
||||
|
||||
prtProgressParams.forget(printProgressParams);
|
||||
NS_ADDREF(*webProgressListener = this);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrintingPromptService::ShowPageSetup(mozIDOMWindowProxy *parent, nsIPrintSettings *printSettings, nsIObserver *aObs)
|
||||
{
|
||||
NS_ENSURE_ARG(printSettings);
|
||||
|
||||
ParamBlock block;
|
||||
nsresult rv = block.Init();
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
block->SetInt(0, 0);
|
||||
rv = DoDialog(parent, block, printSettings, kPageSetupDialogURL);
|
||||
|
||||
// if aWebBrowserPrint is not null then we are printing
|
||||
// so we want to pass back NS_ERROR_ABORT on cancel
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
int32_t status;
|
||||
block->GetInt(0, &status);
|
||||
return status == 0?NS_ERROR_ABORT:NS_OK;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrintingPromptService::ShowPrinterProperties(mozIDOMWindowProxy *parent, const char16_t *printerName, nsIPrintSettings *printSettings)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------
|
||||
// Helper to Fly XP Dialog
|
||||
nsresult
|
||||
nsPrintingPromptService::DoDialog(mozIDOMWindowProxy *aParent,
|
||||
nsIDialogParamBlock *aParamBlock,
|
||||
nsIPrintSettings* aPS,
|
||||
const char *aChromeURL)
|
||||
{
|
||||
NS_ENSURE_ARG(aParamBlock);
|
||||
NS_ENSURE_ARG(aPS);
|
||||
NS_ENSURE_ARG(aChromeURL);
|
||||
|
||||
if (!mWatcher)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// get a parent, if at all possible
|
||||
// (though we'd rather this didn't fail, it's OK if it does. so there's
|
||||
// no failure or null check.)
|
||||
nsCOMPtr<mozIDOMWindowProxy> activeParent; // retain ownership for method lifetime
|
||||
if (!aParent)
|
||||
{
|
||||
mWatcher->GetActiveWindow(getter_AddRefs(activeParent));
|
||||
aParent = activeParent;
|
||||
}
|
||||
|
||||
// create a nsIMutableArray of the parameters
|
||||
// being passed to the window
|
||||
nsCOMPtr<nsIMutableArray> array = nsArray::Create();
|
||||
|
||||
nsCOMPtr<nsISupports> psSupports(do_QueryInterface(aPS));
|
||||
NS_ASSERTION(psSupports, "PrintSettings must be a supports");
|
||||
array->AppendElement(psSupports, /*weak =*/ false);
|
||||
|
||||
nsCOMPtr<nsISupports> blkSupps(do_QueryInterface(aParamBlock));
|
||||
NS_ASSERTION(blkSupps, "IOBlk must be a supports");
|
||||
array->AppendElement(blkSupps, /*weak =*/ false);
|
||||
|
||||
nsCOMPtr<mozIDOMWindowProxy> dialog;
|
||||
nsresult rv = mWatcher->OpenWindow(aParent, aChromeURL, "_blank",
|
||||
"centerscreen,chrome,modal,titlebar", array,
|
||||
getter_AddRefs(dialog));
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// nsIWebProgressListener
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrintingPromptService::OnStateChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, uint32_t aStateFlags, nsresult aStatus)
|
||||
{
|
||||
if ((aStateFlags & STATE_STOP) && mWebProgressListener)
|
||||
{
|
||||
mWebProgressListener->OnStateChange(aWebProgress, aRequest, aStateFlags, aStatus);
|
||||
if (mPrintProgress)
|
||||
{
|
||||
mPrintProgress->CloseProgressDialog(true);
|
||||
}
|
||||
mPrintProgress = nullptr;
|
||||
mWebProgressListener = nullptr;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrintingPromptService::OnProgressChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, int32_t aCurSelfProgress, int32_t aMaxSelfProgress, int32_t aCurTotalProgress, int32_t aMaxTotalProgress)
|
||||
{
|
||||
if (mWebProgressListener)
|
||||
{
|
||||
return mWebProgressListener->OnProgressChange(aWebProgress, aRequest, aCurSelfProgress, aMaxSelfProgress, aCurTotalProgress, aMaxTotalProgress);
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrintingPromptService::OnLocationChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, nsIURI *location, uint32_t aFlags)
|
||||
{
|
||||
if (mWebProgressListener)
|
||||
{
|
||||
return mWebProgressListener->OnLocationChange(aWebProgress, aRequest, location, aFlags);
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrintingPromptService::OnStatusChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, nsresult aStatus, const char16_t *aMessage)
|
||||
{
|
||||
if (mWebProgressListener)
|
||||
{
|
||||
return mWebProgressListener->OnStatusChange(aWebProgress, aRequest, aStatus, aMessage);
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrintingPromptService::OnSecurityChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, uint32_t state)
|
||||
{
|
||||
if (mWebProgressListener)
|
||||
{
|
||||
return mWebProgressListener->OnSecurityChange(aWebProgress, aRequest, state);
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
/* -*- 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 __nsPrintingPromptService_h
|
||||
#define __nsPrintingPromptService_h
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
// {E042570C-62DE-4bb6-A6E0-798E3C07B4DF}
|
||||
#define NS_PRINTINGPROMPTSERVICE_CID \
|
||||
{0xe042570c, 0x62de, 0x4bb6, { 0xa6, 0xe0, 0x79, 0x8e, 0x3c, 0x7, 0xb4, 0xdf}}
|
||||
#define NS_PRINTINGPROMPTSERVICE_CONTRACTID \
|
||||
"@mozilla.org/embedcomp/printingprompt-service;1"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIPrintingPromptService.h"
|
||||
#include "nsPIPromptService.h"
|
||||
#include "nsIWindowWatcher.h"
|
||||
|
||||
// Printing Progress Includes
|
||||
#include "nsPrintProgress.h"
|
||||
#include "nsPrintProgressParams.h"
|
||||
#include "nsIWebProgressListener.h"
|
||||
|
||||
class nsIDOMWindow;
|
||||
class nsIDialogParamBlock;
|
||||
|
||||
class nsPrintingPromptService: public nsIPrintingPromptService,
|
||||
public nsIWebProgressListener
|
||||
{
|
||||
virtual ~nsPrintingPromptService();
|
||||
|
||||
public:
|
||||
nsPrintingPromptService();
|
||||
|
||||
nsresult Init();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIPRINTINGPROMPTSERVICE
|
||||
NS_DECL_NSIWEBPROGRESSLISTENER
|
||||
|
||||
private:
|
||||
HWND GetHWNDForDOMWindow(mozIDOMWindowProxy *parent);
|
||||
nsresult DoDialog(mozIDOMWindowProxy *aParent,
|
||||
nsIDialogParamBlock *aParamBlock,
|
||||
nsIPrintSettings* aPS,
|
||||
const char *aChromeURL);
|
||||
|
||||
nsCOMPtr<nsIWindowWatcher> mWatcher;
|
||||
nsCOMPtr<nsIPrintProgress> mPrintProgress;
|
||||
nsCOMPtr<nsIWebProgressListener> mWebProgressListener;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
/* -*- Mode: IDL; tab-width: 8; 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 protocol PContent;
|
||||
include protocol PWebBrowserPersistResources;
|
||||
include protocol PWebBrowserPersistSerialize;
|
||||
|
||||
include InputStreamParams;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
// nsIWebBrowserPersistDocument has attributes which can be read
|
||||
// synchronously. To avoid using sync IPC for them, the actor sends
|
||||
// this structure from the child to the parent before the parent actor
|
||||
// is exposed to XPCOM.
|
||||
struct WebBrowserPersistDocumentAttrs {
|
||||
bool isPrivate;
|
||||
nsCString documentURI;
|
||||
nsCString baseURI;
|
||||
nsCString contentType;
|
||||
nsCString characterSet;
|
||||
nsString title;
|
||||
nsString referrer;
|
||||
nsString contentDisposition;
|
||||
uint32_t cacheKey;
|
||||
uint32_t persistFlags;
|
||||
};
|
||||
|
||||
// IPDL doesn't have tuples, so this gives the pair of strings from
|
||||
// nsIWebBrowserPersistURIMap::getURIMapping a name.
|
||||
struct WebBrowserPersistURIMapEntry {
|
||||
nsCString mapFrom;
|
||||
nsCString mapTo;
|
||||
};
|
||||
|
||||
// nsIWebBrowserPersistURIMap is just copied over IPC as one of these,
|
||||
// not proxied, to simplify the protocol.
|
||||
struct WebBrowserPersistURIMap {
|
||||
WebBrowserPersistURIMapEntry[] mapURIs;
|
||||
nsCString targetBaseURI;
|
||||
};
|
||||
|
||||
// This remotes nsIWebBrowserPersistDocument and its visitors. The
|
||||
// lifecycle is a little complicated: the initial document is
|
||||
// constructed parent->child, but subdocuments are constructed
|
||||
// child->parent and then passed back. Subdocuments aren't subactors,
|
||||
// because that would impose a lifetime relationship that doesn't
|
||||
// exist in the XPIDL; instead they're all managed by the enclosing
|
||||
// PContent.
|
||||
protocol PWebBrowserPersistDocument {
|
||||
manager PContent;
|
||||
manages PWebBrowserPersistResources;
|
||||
manages PWebBrowserPersistSerialize;
|
||||
|
||||
parent:
|
||||
// The actor isn't exposed to XPCOM until after it gets one of these
|
||||
// two messages; see also the state transition rules. The message
|
||||
// is either a response to the constructor (if it was parent->child)
|
||||
// or sent after it (if it was child->parent).
|
||||
async Attributes(WebBrowserPersistDocumentAttrs aAttrs,
|
||||
OptionalInputStreamParams postData,
|
||||
FileDescriptor[] postFiles);
|
||||
async InitFailure(nsresult aStatus);
|
||||
|
||||
child:
|
||||
async SetPersistFlags(uint32_t aNewFlags);
|
||||
async PWebBrowserPersistResources();
|
||||
async PWebBrowserPersistSerialize(WebBrowserPersistURIMap aMap,
|
||||
nsCString aRequestedContentType,
|
||||
uint32_t aEncoderFlags,
|
||||
uint32_t aWrapColumn);
|
||||
async __delete__();
|
||||
|
||||
state START:
|
||||
recv Attributes goto MAIN;
|
||||
recv InitFailure goto FAILED;
|
||||
|
||||
state MAIN:
|
||||
send SetPersistFlags goto MAIN;
|
||||
send PWebBrowserPersistResources goto MAIN;
|
||||
send PWebBrowserPersistSerialize goto MAIN;
|
||||
send __delete__;
|
||||
|
||||
state FAILED:
|
||||
send __delete__;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
/* -*- Mode: IDL; tab-width: 8; 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 protocol PWebBrowserPersistDocument;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
// == nsIWebBrowserPersistResourceVisitor
|
||||
protocol PWebBrowserPersistResources {
|
||||
manager PWebBrowserPersistDocument;
|
||||
|
||||
parent:
|
||||
async VisitResource(nsCString aURI);
|
||||
|
||||
// The actor sent here is in the START state; the parent-side
|
||||
// receiver will have to wait for it to enter the MAIN state
|
||||
// before exposing it with a visitDocument call.
|
||||
async VisitDocument(PWebBrowserPersistDocument aSubDocument);
|
||||
|
||||
// This reflects the endVisit method.
|
||||
async __delete__(nsresult aStatus);
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
/* -*- Mode: IDL; tab-width: 8; 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 protocol PWebBrowserPersistDocument;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
// This actor represents both an nsIWebBrowserPersistWriteCompletion
|
||||
// and the nsIOutputStream passed with it to the writeContent method.
|
||||
protocol PWebBrowserPersistSerialize {
|
||||
manager PWebBrowserPersistDocument;
|
||||
|
||||
parent:
|
||||
// This sends the data with no flow control, so the parent could
|
||||
// wind up buffering an arbitrarily large amount of data... but
|
||||
// it's a serialized DOM that's already in memory as DOM nodes, so
|
||||
// this is at worst just a constant-factor increase in memory usage.
|
||||
// Also, Chromium does the same thing; see
|
||||
// content::RenderViewImpl::didSerializeDataForFrame.
|
||||
async WriteData(uint8_t[] aData);
|
||||
|
||||
// This is the onFinish method.
|
||||
async __delete__(nsCString aContentType,
|
||||
nsresult aStatus);
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
@ -0,0 +1,159 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* 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 "WebBrowserPersistDocumentChild.h"
|
||||
|
||||
#include "mozilla/ipc/InputStreamUtils.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "WebBrowserPersistLocalDocument.h"
|
||||
#include "WebBrowserPersistResourcesChild.h"
|
||||
#include "WebBrowserPersistSerializeChild.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
WebBrowserPersistDocumentChild::WebBrowserPersistDocumentChild()
|
||||
{
|
||||
}
|
||||
|
||||
WebBrowserPersistDocumentChild::~WebBrowserPersistDocumentChild()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
WebBrowserPersistDocumentChild::Start(nsIDocument* aDocument)
|
||||
{
|
||||
RefPtr<WebBrowserPersistLocalDocument> doc;
|
||||
if (aDocument) {
|
||||
doc = new WebBrowserPersistLocalDocument(aDocument);
|
||||
}
|
||||
Start(doc);
|
||||
}
|
||||
|
||||
void
|
||||
WebBrowserPersistDocumentChild::Start(nsIWebBrowserPersistDocument* aDocument)
|
||||
{
|
||||
MOZ_ASSERT(!mDocument);
|
||||
if (!aDocument) {
|
||||
SendInitFailure(NS_ERROR_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
WebBrowserPersistDocumentAttrs attrs;
|
||||
nsCOMPtr<nsIInputStream> postDataStream;
|
||||
OptionalInputStreamParams postData;
|
||||
nsTArray<FileDescriptor> postFiles;
|
||||
#define ENSURE(e) do { \
|
||||
nsresult rv = (e); \
|
||||
if (NS_FAILED(rv)) { \
|
||||
SendInitFailure(rv); \
|
||||
return; \
|
||||
} \
|
||||
} while(0)
|
||||
ENSURE(aDocument->GetIsPrivate(&(attrs.isPrivate())));
|
||||
ENSURE(aDocument->GetDocumentURI(attrs.documentURI()));
|
||||
ENSURE(aDocument->GetBaseURI(attrs.baseURI()));
|
||||
ENSURE(aDocument->GetContentType(attrs.contentType()));
|
||||
ENSURE(aDocument->GetCharacterSet(attrs.characterSet()));
|
||||
ENSURE(aDocument->GetTitle(attrs.title()));
|
||||
ENSURE(aDocument->GetReferrer(attrs.referrer()));
|
||||
ENSURE(aDocument->GetContentDisposition(attrs.contentDisposition()));
|
||||
ENSURE(aDocument->GetCacheKey(&(attrs.cacheKey())));
|
||||
ENSURE(aDocument->GetPersistFlags(&(attrs.persistFlags())));
|
||||
ENSURE(aDocument->GetPostData(getter_AddRefs(postDataStream)));
|
||||
ipc::SerializeInputStream(postDataStream,
|
||||
postData,
|
||||
postFiles);
|
||||
#undef ENSURE
|
||||
mDocument = aDocument;
|
||||
SendAttributes(attrs, postData, postFiles);
|
||||
}
|
||||
|
||||
bool
|
||||
WebBrowserPersistDocumentChild::RecvSetPersistFlags(const uint32_t& aNewFlags)
|
||||
{
|
||||
mDocument->SetPersistFlags(aNewFlags);
|
||||
return true;
|
||||
}
|
||||
|
||||
PWebBrowserPersistResourcesChild*
|
||||
WebBrowserPersistDocumentChild::AllocPWebBrowserPersistResourcesChild()
|
||||
{
|
||||
auto* actor = new WebBrowserPersistResourcesChild();
|
||||
NS_ADDREF(actor);
|
||||
return actor;
|
||||
}
|
||||
|
||||
bool
|
||||
WebBrowserPersistDocumentChild::RecvPWebBrowserPersistResourcesConstructor(PWebBrowserPersistResourcesChild* aActor)
|
||||
{
|
||||
RefPtr<WebBrowserPersistResourcesChild> visitor =
|
||||
static_cast<WebBrowserPersistResourcesChild*>(aActor);
|
||||
nsresult rv = mDocument->ReadResources(visitor);
|
||||
if (NS_FAILED(rv)) {
|
||||
// This is a sync failure on the child side but an async
|
||||
// failure on the parent side -- it already got NS_OK from
|
||||
// ReadResources, so the error has to be reported via the
|
||||
// visitor instead.
|
||||
visitor->EndVisit(mDocument, rv);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
WebBrowserPersistDocumentChild::DeallocPWebBrowserPersistResourcesChild(PWebBrowserPersistResourcesChild* aActor)
|
||||
{
|
||||
auto* castActor =
|
||||
static_cast<WebBrowserPersistResourcesChild*>(aActor);
|
||||
NS_RELEASE(castActor);
|
||||
return true;
|
||||
}
|
||||
|
||||
PWebBrowserPersistSerializeChild*
|
||||
WebBrowserPersistDocumentChild::AllocPWebBrowserPersistSerializeChild(
|
||||
const WebBrowserPersistURIMap& aMap,
|
||||
const nsCString& aRequestedContentType,
|
||||
const uint32_t& aEncoderFlags,
|
||||
const uint32_t& aWrapColumn)
|
||||
{
|
||||
auto* actor = new WebBrowserPersistSerializeChild(aMap);
|
||||
NS_ADDREF(actor);
|
||||
return actor;
|
||||
}
|
||||
|
||||
bool
|
||||
WebBrowserPersistDocumentChild::RecvPWebBrowserPersistSerializeConstructor(
|
||||
PWebBrowserPersistSerializeChild* aActor,
|
||||
const WebBrowserPersistURIMap& aMap,
|
||||
const nsCString& aRequestedContentType,
|
||||
const uint32_t& aEncoderFlags,
|
||||
const uint32_t& aWrapColumn)
|
||||
{
|
||||
auto* castActor =
|
||||
static_cast<WebBrowserPersistSerializeChild*>(aActor);
|
||||
// This actor performs the roles of: completion, URI map, and output stream.
|
||||
nsresult rv = mDocument->WriteContent(castActor,
|
||||
castActor,
|
||||
aRequestedContentType,
|
||||
aEncoderFlags,
|
||||
aWrapColumn,
|
||||
castActor);
|
||||
if (NS_FAILED(rv)) {
|
||||
castActor->OnFinish(mDocument, castActor, aRequestedContentType, rv);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
WebBrowserPersistDocumentChild::DeallocPWebBrowserPersistSerializeChild(PWebBrowserPersistSerializeChild* aActor)
|
||||
{
|
||||
auto* castActor =
|
||||
static_cast<WebBrowserPersistSerializeChild*>(aActor);
|
||||
NS_RELEASE(castActor);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* 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 WebBrowserPersistDocumentChild_h__
|
||||
#define WebBrowserPersistDocumentChild_h__
|
||||
|
||||
#include "mozilla/PWebBrowserPersistDocumentChild.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIWebBrowserPersistDocument.h"
|
||||
|
||||
class nsIDocument;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class WebBrowserPersistDocumentChild final
|
||||
: public PWebBrowserPersistDocumentChild
|
||||
{
|
||||
public:
|
||||
WebBrowserPersistDocumentChild();
|
||||
~WebBrowserPersistDocumentChild();
|
||||
|
||||
// This sends either Attributes or InitFailure and thereby causes
|
||||
// the actor to leave the START state.
|
||||
void Start(nsIWebBrowserPersistDocument* aDocument);
|
||||
void Start(nsIDocument* aDocument);
|
||||
|
||||
virtual bool
|
||||
RecvSetPersistFlags(const uint32_t& aNewFlags) override;
|
||||
|
||||
virtual PWebBrowserPersistResourcesChild*
|
||||
AllocPWebBrowserPersistResourcesChild() override;
|
||||
virtual bool
|
||||
RecvPWebBrowserPersistResourcesConstructor(PWebBrowserPersistResourcesChild* aActor) override;
|
||||
virtual bool
|
||||
DeallocPWebBrowserPersistResourcesChild(PWebBrowserPersistResourcesChild* aActor) override;
|
||||
|
||||
virtual PWebBrowserPersistSerializeChild*
|
||||
AllocPWebBrowserPersistSerializeChild(
|
||||
const WebBrowserPersistURIMap& aMap,
|
||||
const nsCString& aRequestedContentType,
|
||||
const uint32_t& aEncoderFlags,
|
||||
const uint32_t& aWrapColumn) override;
|
||||
virtual bool
|
||||
RecvPWebBrowserPersistSerializeConstructor(
|
||||
PWebBrowserPersistSerializeChild* aActor,
|
||||
const WebBrowserPersistURIMap& aMap,
|
||||
const nsCString& aRequestedContentType,
|
||||
const uint32_t& aEncoderFlags,
|
||||
const uint32_t& aWrapColumn) override;
|
||||
virtual bool
|
||||
DeallocPWebBrowserPersistSerializeChild(PWebBrowserPersistSerializeChild* aActor) override;
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsIWebBrowserPersistDocument> mDocument;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // WebBrowserPersistDocumentChild_h__
|
||||
|
|
@ -0,0 +1,125 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* 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 "WebBrowserPersistDocumentParent.h"
|
||||
|
||||
#include "mozilla/ipc/InputStreamUtils.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "WebBrowserPersistResourcesParent.h"
|
||||
#include "WebBrowserPersistSerializeParent.h"
|
||||
#include "WebBrowserPersistRemoteDocument.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
WebBrowserPersistDocumentParent::WebBrowserPersistDocumentParent()
|
||||
: mReflection(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
WebBrowserPersistDocumentParent::SetOnReady(nsIWebBrowserPersistDocumentReceiver* aOnReady)
|
||||
{
|
||||
MOZ_ASSERT(aOnReady);
|
||||
MOZ_ASSERT(!mOnReady);
|
||||
MOZ_ASSERT(!mReflection);
|
||||
mOnReady = aOnReady;
|
||||
}
|
||||
|
||||
void
|
||||
WebBrowserPersistDocumentParent::ActorDestroy(ActorDestroyReason aWhy)
|
||||
{
|
||||
if (mReflection) {
|
||||
mReflection->ActorDestroy();
|
||||
mReflection = nullptr;
|
||||
}
|
||||
if (mOnReady) {
|
||||
// Bug 1202887: If this is part of a subtree destruction, then
|
||||
// anything which could cause another actor in that subtree to
|
||||
// be Send__delete__()ed will cause use-after-free -- such as
|
||||
// dropping the last reference to another document's
|
||||
// WebBrowserPersistRemoteDocument. To avoid that, defer the
|
||||
// callback until after the entire subtree is destroyed.
|
||||
nsCOMPtr<nsIRunnable> errorLater = NewRunnableMethod
|
||||
<nsresult>(mOnReady, &nsIWebBrowserPersistDocumentReceiver::OnError,
|
||||
NS_ERROR_FAILURE);
|
||||
NS_DispatchToCurrentThread(errorLater);
|
||||
mOnReady = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
WebBrowserPersistDocumentParent::~WebBrowserPersistDocumentParent()
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(!mReflection);
|
||||
MOZ_ASSERT(!mOnReady);
|
||||
}
|
||||
|
||||
bool
|
||||
WebBrowserPersistDocumentParent::RecvAttributes(const Attrs& aAttrs,
|
||||
const OptionalInputStreamParams& aPostData,
|
||||
nsTArray<FileDescriptor>&& aPostFiles)
|
||||
{
|
||||
// Deserialize the postData unconditionally so that fds aren't leaked.
|
||||
nsCOMPtr<nsIInputStream> postData =
|
||||
ipc::DeserializeInputStream(aPostData, aPostFiles);
|
||||
if (!mOnReady || mReflection) {
|
||||
return false;
|
||||
}
|
||||
mReflection = new WebBrowserPersistRemoteDocument(this, aAttrs, postData);
|
||||
RefPtr<WebBrowserPersistRemoteDocument> reflection = mReflection;
|
||||
mOnReady->OnDocumentReady(reflection);
|
||||
mOnReady = nullptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
WebBrowserPersistDocumentParent::RecvInitFailure(const nsresult& aFailure)
|
||||
{
|
||||
if (!mOnReady || mReflection) {
|
||||
return false;
|
||||
}
|
||||
mOnReady->OnError(aFailure);
|
||||
mOnReady = nullptr;
|
||||
// Warning: Send__delete__ deallocates this object.
|
||||
return Send__delete__(this);
|
||||
}
|
||||
|
||||
PWebBrowserPersistResourcesParent*
|
||||
WebBrowserPersistDocumentParent::AllocPWebBrowserPersistResourcesParent()
|
||||
{
|
||||
MOZ_CRASH("Don't use this; construct the actor directly and AddRef.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
WebBrowserPersistDocumentParent::DeallocPWebBrowserPersistResourcesParent(PWebBrowserPersistResourcesParent* aActor)
|
||||
{
|
||||
// Turn the ref held by IPC back into an nsRefPtr.
|
||||
RefPtr<WebBrowserPersistResourcesParent> actor =
|
||||
already_AddRefed<WebBrowserPersistResourcesParent>(
|
||||
static_cast<WebBrowserPersistResourcesParent*>(aActor));
|
||||
return true;
|
||||
}
|
||||
|
||||
PWebBrowserPersistSerializeParent*
|
||||
WebBrowserPersistDocumentParent::AllocPWebBrowserPersistSerializeParent(
|
||||
const WebBrowserPersistURIMap& aMap,
|
||||
const nsCString& aRequestedContentType,
|
||||
const uint32_t& aEncoderFlags,
|
||||
const uint32_t& aWrapColumn)
|
||||
{
|
||||
MOZ_CRASH("Don't use this; construct the actor directly.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
WebBrowserPersistDocumentParent::DeallocPWebBrowserPersistSerializeParent(PWebBrowserPersistSerializeParent* aActor)
|
||||
{
|
||||
delete aActor;
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* 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 WebBrowserPersistDocumentParent_h__
|
||||
#define WebBrowserPersistDocumentParent_h__
|
||||
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/PWebBrowserPersistDocumentParent.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIWebBrowserPersistDocument.h"
|
||||
|
||||
// This class is the IPC half of the glue between the
|
||||
// nsIWebBrowserPersistDocument interface and a remote document. When
|
||||
// (and if) it receives the Attributes message it constructs an
|
||||
// WebBrowserPersistRemoteDocument and releases it into the XPCOM
|
||||
// universe; otherwise, it invokes the document receiver's error
|
||||
// callback.
|
||||
//
|
||||
// This object's lifetime is the normal IPC lifetime; on destruction,
|
||||
// it calls its XPCOM reflection (if it exists yet) to remove that
|
||||
// reference. Normal deletion occurs when the XPCOM object is being
|
||||
// destroyed or after an InitFailure is received and handled.
|
||||
//
|
||||
// See also: TabParent::StartPersistence.
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class WebBrowserPersistRemoteDocument;
|
||||
|
||||
class WebBrowserPersistDocumentParent final
|
||||
: public PWebBrowserPersistDocumentParent
|
||||
{
|
||||
public:
|
||||
WebBrowserPersistDocumentParent();
|
||||
virtual ~WebBrowserPersistDocumentParent();
|
||||
|
||||
// Set a callback to be invoked when the actor leaves the START
|
||||
// state. This method must be called exactly once while the actor
|
||||
// is still in the START state (or is unconstructed).
|
||||
void SetOnReady(nsIWebBrowserPersistDocumentReceiver* aOnReady);
|
||||
|
||||
using Attrs = WebBrowserPersistDocumentAttrs;
|
||||
|
||||
// IPDL methods:
|
||||
virtual bool
|
||||
RecvAttributes(const Attrs& aAttrs,
|
||||
const OptionalInputStreamParams& aPostData,
|
||||
nsTArray<FileDescriptor>&& aPostFiles) override;
|
||||
virtual bool
|
||||
RecvInitFailure(const nsresult& aFailure) override;
|
||||
|
||||
virtual PWebBrowserPersistResourcesParent*
|
||||
AllocPWebBrowserPersistResourcesParent() override;
|
||||
virtual bool
|
||||
DeallocPWebBrowserPersistResourcesParent(PWebBrowserPersistResourcesParent* aActor) override;
|
||||
|
||||
virtual PWebBrowserPersistSerializeParent*
|
||||
AllocPWebBrowserPersistSerializeParent(
|
||||
const WebBrowserPersistURIMap& aMap,
|
||||
const nsCString& aRequestedContentType,
|
||||
const uint32_t& aEncoderFlags,
|
||||
const uint32_t& aWrapColumn) override;
|
||||
virtual bool
|
||||
DeallocPWebBrowserPersistSerializeParent(PWebBrowserPersistSerializeParent* aActor) override;
|
||||
|
||||
virtual void
|
||||
ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
private:
|
||||
// This is reset to nullptr when the callback is invoked.
|
||||
nsCOMPtr<nsIWebBrowserPersistDocumentReceiver> mOnReady;
|
||||
WebBrowserPersistRemoteDocument* mReflection;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // WebBrowserPersistDocumentParent_h__
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,51 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* 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 WebBrowserPersistLocalDocument_h__
|
||||
#define WebBrowserPersistLocalDocument_h__
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsIWebBrowserPersistDocument.h"
|
||||
|
||||
class nsIDocumentEncoder;
|
||||
class nsISHEntry;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class WebBrowserPersistLocalDocument final
|
||||
: public nsIWebBrowserPersistDocument
|
||||
{
|
||||
public:
|
||||
explicit WebBrowserPersistLocalDocument(nsIDocument* aDocument);
|
||||
|
||||
const nsCString& GetCharacterSet() const;
|
||||
uint32_t GetPersistFlags() const;
|
||||
already_AddRefed<nsIURI> GetBaseURI() const;
|
||||
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_NSIWEBBROWSERPERSISTDOCUMENT
|
||||
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS(WebBrowserPersistLocalDocument)
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsIDocument> mDocument;
|
||||
uint32_t mPersistFlags;
|
||||
|
||||
void DecideContentType(nsACString& aContentType);
|
||||
nsresult GetDocEncoder(const nsACString& aContentType,
|
||||
uint32_t aEncoderFlags,
|
||||
nsIDocumentEncoder** aEncoder);
|
||||
already_AddRefed<nsISHEntry> GetHistory();
|
||||
|
||||
virtual ~WebBrowserPersistLocalDocument();
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // WebBrowserPersistLocalDocument_h__
|
||||
|
|
@ -0,0 +1,186 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* 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 "WebBrowserPersistRemoteDocument.h"
|
||||
#include "WebBrowserPersistDocumentParent.h"
|
||||
#include "WebBrowserPersistResourcesParent.h"
|
||||
#include "WebBrowserPersistSerializeParent.h"
|
||||
#include "mozilla/Unused.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
NS_IMPL_ISUPPORTS(WebBrowserPersistRemoteDocument,
|
||||
nsIWebBrowserPersistDocument)
|
||||
|
||||
WebBrowserPersistRemoteDocument
|
||||
::WebBrowserPersistRemoteDocument(WebBrowserPersistDocumentParent* aActor,
|
||||
const Attrs& aAttrs,
|
||||
nsIInputStream* aPostData)
|
||||
: mActor(aActor)
|
||||
, mAttrs(aAttrs)
|
||||
, mPostData(aPostData)
|
||||
{
|
||||
}
|
||||
|
||||
WebBrowserPersistRemoteDocument::~WebBrowserPersistRemoteDocument()
|
||||
{
|
||||
if (mActor) {
|
||||
Unused << mActor->Send__delete__(mActor);
|
||||
// That will call mActor->ActorDestroy, which calls this->ActorDestroy
|
||||
// (whether or not the IPC send succeeds).
|
||||
}
|
||||
MOZ_ASSERT(!mActor);
|
||||
}
|
||||
|
||||
void
|
||||
WebBrowserPersistRemoteDocument::ActorDestroy(void)
|
||||
{
|
||||
mActor = nullptr;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WebBrowserPersistRemoteDocument::GetIsPrivate(bool* aIsPrivate)
|
||||
{
|
||||
*aIsPrivate = mAttrs.isPrivate();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WebBrowserPersistRemoteDocument::GetDocumentURI(nsACString& aURISpec)
|
||||
{
|
||||
aURISpec = mAttrs.documentURI();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WebBrowserPersistRemoteDocument::GetBaseURI(nsACString& aURISpec)
|
||||
{
|
||||
aURISpec = mAttrs.baseURI();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WebBrowserPersistRemoteDocument::GetContentType(nsACString& aContentType)
|
||||
{
|
||||
aContentType = mAttrs.contentType();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WebBrowserPersistRemoteDocument::GetCharacterSet(nsACString& aCharSet)
|
||||
{
|
||||
aCharSet = mAttrs.characterSet();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WebBrowserPersistRemoteDocument::GetTitle(nsAString& aTitle)
|
||||
{
|
||||
aTitle = mAttrs.title();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WebBrowserPersistRemoteDocument::GetReferrer(nsAString& aReferrer)
|
||||
{
|
||||
aReferrer = mAttrs.referrer();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WebBrowserPersistRemoteDocument::GetContentDisposition(nsAString& aDisp)
|
||||
{
|
||||
aDisp = mAttrs.contentDisposition();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WebBrowserPersistRemoteDocument::GetCacheKey(uint32_t* aCacheKey)
|
||||
{
|
||||
*aCacheKey = mAttrs.cacheKey();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WebBrowserPersistRemoteDocument::GetPersistFlags(uint32_t* aFlags)
|
||||
{
|
||||
*aFlags = mAttrs.persistFlags();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WebBrowserPersistRemoteDocument::SetPersistFlags(uint32_t aFlags)
|
||||
{
|
||||
if (!mActor) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
if (!mActor->SendSetPersistFlags(aFlags)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
mAttrs.persistFlags() = aFlags;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WebBrowserPersistRemoteDocument::GetPostData(nsIInputStream** aStream)
|
||||
{
|
||||
nsCOMPtr<nsIInputStream> stream = mPostData;
|
||||
stream.forget(aStream);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WebBrowserPersistRemoteDocument::ReadResources(nsIWebBrowserPersistResourceVisitor* aVisitor)
|
||||
{
|
||||
if (!mActor) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
RefPtr<WebBrowserPersistResourcesParent> subActor =
|
||||
new WebBrowserPersistResourcesParent(this, aVisitor);
|
||||
return mActor->SendPWebBrowserPersistResourcesConstructor(
|
||||
subActor.forget().take())
|
||||
? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WebBrowserPersistRemoteDocument::WriteContent(
|
||||
nsIOutputStream* aStream,
|
||||
nsIWebBrowserPersistURIMap* aMap,
|
||||
const nsACString& aRequestedContentType,
|
||||
uint32_t aEncoderFlags,
|
||||
uint32_t aWrapColumn,
|
||||
nsIWebBrowserPersistWriteCompletion* aCompletion)
|
||||
{
|
||||
if (!mActor) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
WebBrowserPersistURIMap map;
|
||||
uint32_t numMappedURIs;
|
||||
if (aMap) {
|
||||
rv = aMap->GetTargetBaseURI(map.targetBaseURI());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = aMap->GetNumMappedURIs(&numMappedURIs);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
for (uint32_t i = 0; i < numMappedURIs; ++i) {
|
||||
WebBrowserPersistURIMapEntry& nextEntry =
|
||||
*(map.mapURIs().AppendElement());
|
||||
rv = aMap->GetURIMapping(i, nextEntry.mapFrom(), nextEntry.mapTo());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
}
|
||||
|
||||
auto* subActor = new WebBrowserPersistSerializeParent(this,
|
||||
aStream,
|
||||
aCompletion);
|
||||
nsCString requestedContentType(aRequestedContentType); // Sigh.
|
||||
return mActor->SendPWebBrowserPersistSerializeConstructor(
|
||||
subActor, map, requestedContentType, aEncoderFlags, aWrapColumn)
|
||||
? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* 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 WebBrowserPersistRemoteDocument_h__
|
||||
#define WebBrowserPersistRemoteDocument_h__
|
||||
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/PWebBrowserPersistDocumentParent.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIWebBrowserPersistDocument.h"
|
||||
#include "nsIInputStream.h"
|
||||
|
||||
// This class is the XPCOM half of the glue between the
|
||||
// nsIWebBrowserPersistDocument interface and a remote document; it is
|
||||
// created by WebBrowserPersistDocumentParent when (and if) it
|
||||
// receives the information needed to populate the interface's
|
||||
// properties.
|
||||
//
|
||||
// This object has a normal refcounted lifetime. The corresponding
|
||||
// IPC actor holds a weak reference to this class; when the last
|
||||
// strong reference is released, it sends an IPC delete message and
|
||||
// thereby removes that reference.
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class WebBrowserPersistDocumentParent;
|
||||
|
||||
class WebBrowserPersistRemoteDocument final
|
||||
: public nsIWebBrowserPersistDocument
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIWEBBROWSERPERSISTDOCUMENT
|
||||
|
||||
private:
|
||||
using Attrs = WebBrowserPersistDocumentAttrs;
|
||||
WebBrowserPersistDocumentParent* mActor;
|
||||
Attrs mAttrs;
|
||||
nsCOMPtr<nsIInputStream> mPostData;
|
||||
|
||||
friend class WebBrowserPersistDocumentParent;
|
||||
WebBrowserPersistRemoteDocument(WebBrowserPersistDocumentParent* aActor,
|
||||
const Attrs& aAttrs,
|
||||
nsIInputStream* aPostData);
|
||||
~WebBrowserPersistRemoteDocument();
|
||||
|
||||
void ActorDestroy(void);
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // WebBrowserPersistRemoteDocument_h__
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* 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 "WebBrowserPersistResourcesChild.h"
|
||||
|
||||
#include "WebBrowserPersistDocumentChild.h"
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
NS_IMPL_ISUPPORTS(WebBrowserPersistResourcesChild,
|
||||
nsIWebBrowserPersistResourceVisitor)
|
||||
|
||||
WebBrowserPersistResourcesChild::WebBrowserPersistResourcesChild()
|
||||
{
|
||||
}
|
||||
|
||||
WebBrowserPersistResourcesChild::~WebBrowserPersistResourcesChild()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WebBrowserPersistResourcesChild::VisitResource(nsIWebBrowserPersistDocument *aDocument,
|
||||
const nsACString& aURI)
|
||||
{
|
||||
nsCString copiedURI(aURI); // Yay, XPIDL/IPDL mismatch.
|
||||
SendVisitResource(copiedURI);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WebBrowserPersistResourcesChild::VisitDocument(nsIWebBrowserPersistDocument* aDocument,
|
||||
nsIWebBrowserPersistDocument* aSubDocument)
|
||||
{
|
||||
auto* subActor = new WebBrowserPersistDocumentChild();
|
||||
// As a consequence of how PWebBrowserPersistDocumentConstructor
|
||||
// can be sent by both the parent and the child, we must pass the
|
||||
// aBrowser and outerWindowID arguments here, but the values are
|
||||
// ignored by the parent. In particular, the TabChild in which
|
||||
// persistence started does not necessarily exist at this point;
|
||||
// see bug 1203602.
|
||||
if (!Manager()->Manager()
|
||||
->SendPWebBrowserPersistDocumentConstructor(subActor, nullptr, 0)) {
|
||||
// NOTE: subActor is freed at this point.
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
// ...but here, IPC won't free subActor until after this returns
|
||||
// to the event loop.
|
||||
|
||||
// The order of these two messages will be preserved, because
|
||||
// they're the same toplevel protocol and priority.
|
||||
//
|
||||
// With this ordering, it's always the transition out of START
|
||||
// state that causes a document's parent actor to be exposed to
|
||||
// XPCOM (for both parent->child and child->parent construction),
|
||||
// which simplifies the lifetime management.
|
||||
SendVisitDocument(subActor);
|
||||
subActor->Start(aSubDocument);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WebBrowserPersistResourcesChild::EndVisit(nsIWebBrowserPersistDocument *aDocument,
|
||||
nsresult aStatus)
|
||||
{
|
||||
Send__delete__(this, aStatus);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* 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 WebBrowserPersistResourcesChild_h__
|
||||
#define WebBrowserPersistResourcesChild_h__
|
||||
|
||||
#include "mozilla/PWebBrowserPersistResourcesChild.h"
|
||||
|
||||
#include "nsIWebBrowserPersistDocument.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class WebBrowserPersistResourcesChild final
|
||||
: public PWebBrowserPersistResourcesChild
|
||||
, public nsIWebBrowserPersistResourceVisitor
|
||||
{
|
||||
public:
|
||||
WebBrowserPersistResourcesChild();
|
||||
|
||||
NS_DECL_NSIWEBBROWSERPERSISTRESOURCEVISITOR
|
||||
NS_DECL_ISUPPORTS
|
||||
private:
|
||||
virtual ~WebBrowserPersistResourcesChild();
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // WebBrowserPersistDocumentChild_h__
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* 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 "WebBrowserPersistResourcesParent.h"
|
||||
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
NS_IMPL_ISUPPORTS(WebBrowserPersistResourcesParent,
|
||||
nsIWebBrowserPersistDocumentReceiver)
|
||||
|
||||
WebBrowserPersistResourcesParent::WebBrowserPersistResourcesParent(
|
||||
nsIWebBrowserPersistDocument* aDocument,
|
||||
nsIWebBrowserPersistResourceVisitor* aVisitor)
|
||||
: mDocument(aDocument)
|
||||
, mVisitor(aVisitor)
|
||||
{
|
||||
MOZ_ASSERT(aDocument);
|
||||
MOZ_ASSERT(aVisitor);
|
||||
}
|
||||
|
||||
WebBrowserPersistResourcesParent::~WebBrowserPersistResourcesParent()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
WebBrowserPersistResourcesParent::ActorDestroy(ActorDestroyReason aWhy)
|
||||
{
|
||||
if (aWhy != Deletion && mVisitor) {
|
||||
// See comment in WebBrowserPersistDocumentParent::ActorDestroy
|
||||
// (or bug 1202887) for why this is deferred.
|
||||
nsCOMPtr<nsIRunnable> errorLater = NewRunnableMethod
|
||||
<nsCOMPtr<nsIWebBrowserPersistDocument>, nsresult>
|
||||
(mVisitor, &nsIWebBrowserPersistResourceVisitor::EndVisit,
|
||||
mDocument, NS_ERROR_FAILURE);
|
||||
NS_DispatchToCurrentThread(errorLater);
|
||||
}
|
||||
mVisitor = nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
WebBrowserPersistResourcesParent::Recv__delete__(const nsresult& aStatus)
|
||||
{
|
||||
mVisitor->EndVisit(mDocument, aStatus);
|
||||
mVisitor = nullptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
WebBrowserPersistResourcesParent::RecvVisitResource(const nsCString& aURI)
|
||||
{
|
||||
mVisitor->VisitResource(mDocument, aURI);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
WebBrowserPersistResourcesParent::RecvVisitDocument(PWebBrowserPersistDocumentParent* aSubDocument)
|
||||
{
|
||||
// Don't expose the subdocument to the visitor until it's ready
|
||||
// (until the actor isn't in START state).
|
||||
static_cast<WebBrowserPersistDocumentParent*>(aSubDocument)
|
||||
->SetOnReady(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WebBrowserPersistResourcesParent::OnDocumentReady(nsIWebBrowserPersistDocument* aSubDocument)
|
||||
{
|
||||
if (!mVisitor) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
mVisitor->VisitDocument(mDocument, aSubDocument);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WebBrowserPersistResourcesParent::OnError(nsresult aFailure)
|
||||
{
|
||||
// Nothing useful to do but ignore the failed document.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* 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 WebBrowserPersistResourcesParent_h__
|
||||
#define WebBrowserPersistResourcesParent_h__
|
||||
|
||||
#include "mozilla/PWebBrowserPersistResourcesParent.h"
|
||||
|
||||
#include "WebBrowserPersistDocumentParent.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIWebBrowserPersistDocument.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class WebBrowserPersistResourcesParent final
|
||||
: public PWebBrowserPersistResourcesParent
|
||||
, public nsIWebBrowserPersistDocumentReceiver
|
||||
{
|
||||
public:
|
||||
WebBrowserPersistResourcesParent(nsIWebBrowserPersistDocument* aDocument,
|
||||
nsIWebBrowserPersistResourceVisitor* aVisitor);
|
||||
|
||||
virtual bool
|
||||
RecvVisitResource(const nsCString& aURI) override;
|
||||
|
||||
virtual bool
|
||||
RecvVisitDocument(PWebBrowserPersistDocumentParent* aSubDocument) override;
|
||||
|
||||
virtual bool
|
||||
Recv__delete__(const nsresult& aStatus) override;
|
||||
|
||||
virtual void
|
||||
ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
|
||||
NS_DECL_NSIWEBBROWSERPERSISTDOCUMENTRECEIVER
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
private:
|
||||
// Note: even if the XPIDL didn't need mDocument for visitor
|
||||
// callbacks, this object still needs to hold a strong reference
|
||||
// to it to defer actor subtree deletion until after the
|
||||
// visitation is finished.
|
||||
nsCOMPtr<nsIWebBrowserPersistDocument> mDocument;
|
||||
nsCOMPtr<nsIWebBrowserPersistResourceVisitor> mVisitor;
|
||||
|
||||
virtual ~WebBrowserPersistResourcesParent();
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // WebBrowserPersistResourcesParent_h__
|
||||
|
|
@ -0,0 +1,143 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* 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 "WebBrowserPersistSerializeChild.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "nsThreadUtils.h"
|
||||
#include "ipc/IPCMessageUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
NS_IMPL_ISUPPORTS(WebBrowserPersistSerializeChild,
|
||||
nsIWebBrowserPersistWriteCompletion,
|
||||
nsIWebBrowserPersistURIMap,
|
||||
nsIOutputStream)
|
||||
|
||||
WebBrowserPersistSerializeChild::WebBrowserPersistSerializeChild(const WebBrowserPersistURIMap& aMap)
|
||||
: mMap(aMap)
|
||||
{
|
||||
}
|
||||
|
||||
WebBrowserPersistSerializeChild::~WebBrowserPersistSerializeChild()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WebBrowserPersistSerializeChild::OnFinish(nsIWebBrowserPersistDocument* aDocument,
|
||||
nsIOutputStream* aStream,
|
||||
const nsACString& aContentType,
|
||||
nsresult aStatus)
|
||||
{
|
||||
MOZ_ASSERT(aStream == this);
|
||||
nsCString contentType(aContentType);
|
||||
Send__delete__(this, contentType, aStatus);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WebBrowserPersistSerializeChild::GetNumMappedURIs(uint32_t* aNum)
|
||||
{
|
||||
*aNum = static_cast<uint32_t>(mMap.mapURIs().Length());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WebBrowserPersistSerializeChild::GetURIMapping(uint32_t aIndex,
|
||||
nsACString& aMapFrom,
|
||||
nsACString& aMapTo)
|
||||
{
|
||||
if (aIndex >= mMap.mapURIs().Length()) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
aMapFrom = mMap.mapURIs()[aIndex].mapFrom();
|
||||
aMapTo = mMap.mapURIs()[aIndex].mapTo();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WebBrowserPersistSerializeChild::GetTargetBaseURI(nsACString& aURI)
|
||||
{
|
||||
aURI = mMap.targetBaseURI();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WebBrowserPersistSerializeChild::Close()
|
||||
{
|
||||
NS_WARNING("WebBrowserPersistSerializeChild::Close()");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WebBrowserPersistSerializeChild::Flush()
|
||||
{
|
||||
NS_WARNING("WebBrowserPersistSerializeChild::Flush()");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WebBrowserPersistSerializeChild::Write(const char* aBuf, uint32_t aCount,
|
||||
uint32_t* aWritten)
|
||||
{
|
||||
// Normally an nsIOutputStream would have to be thread-safe, but
|
||||
// nsDocumentEncoder currently doesn't call this off the main
|
||||
// thread (which also means it's difficult to test the
|
||||
// thread-safety code this class doesn't yet have).
|
||||
//
|
||||
// This is *not* an NS_ERROR_NOT_IMPLEMENTED, because at this
|
||||
// point we've probably already misused the non-thread-safe
|
||||
// refcounting.
|
||||
MOZ_RELEASE_ASSERT(NS_IsMainThread(), "Fix this class to be thread-safe.");
|
||||
|
||||
// Work around bug 1181433 by sending multiple messages if
|
||||
// necessary to write the entire aCount bytes, even though
|
||||
// nsIOutputStream.idl says we're allowed to do a short write.
|
||||
const char* buf = aBuf;
|
||||
uint32_t count = aCount;
|
||||
*aWritten = 0;
|
||||
while (count > 0) {
|
||||
uint32_t toWrite = std::min(IPC::MAX_MESSAGE_SIZE, count);
|
||||
nsTArray<uint8_t> arrayBuf;
|
||||
// It would be nice if this extra copy could be avoided.
|
||||
arrayBuf.AppendElements(buf, toWrite);
|
||||
SendWriteData(Move(arrayBuf));
|
||||
*aWritten += toWrite;
|
||||
buf += toWrite;
|
||||
count -= toWrite;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WebBrowserPersistSerializeChild::WriteFrom(nsIInputStream* aFrom,
|
||||
uint32_t aCount,
|
||||
uint32_t* aWritten)
|
||||
{
|
||||
NS_WARNING("WebBrowserPersistSerializeChild::WriteFrom()");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WebBrowserPersistSerializeChild::WriteSegments(nsReadSegmentFun aFun,
|
||||
void* aCtx,
|
||||
uint32_t aCount,
|
||||
uint32_t* aWritten)
|
||||
{
|
||||
NS_WARNING("WebBrowserPersistSerializeChild::WriteSegments()");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WebBrowserPersistSerializeChild::IsNonBlocking(bool* aNonBlocking)
|
||||
{
|
||||
// Writes will never fail with NS_BASE_STREAM_WOULD_BLOCK, so:
|
||||
*aNonBlocking = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* 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 WebBrowserPersistSerializeChild_h__
|
||||
#define WebBrowserPersistSerializeChild_h__
|
||||
|
||||
#include "mozilla/PWebBrowserPersistSerializeChild.h"
|
||||
|
||||
#include "mozilla/PWebBrowserPersistDocument.h"
|
||||
#include "nsIWebBrowserPersistDocument.h"
|
||||
#include "nsIOutputStream.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class WebBrowserPersistSerializeChild final
|
||||
: public PWebBrowserPersistSerializeChild
|
||||
, public nsIWebBrowserPersistWriteCompletion
|
||||
, public nsIWebBrowserPersistURIMap
|
||||
, public nsIOutputStream
|
||||
{
|
||||
public:
|
||||
explicit WebBrowserPersistSerializeChild(const WebBrowserPersistURIMap& aMap);
|
||||
|
||||
NS_DECL_NSIWEBBROWSERPERSISTWRITECOMPLETION
|
||||
NS_DECL_NSIWEBBROWSERPERSISTURIMAP
|
||||
NS_DECL_NSIOUTPUTSTREAM
|
||||
NS_DECL_ISUPPORTS
|
||||
private:
|
||||
WebBrowserPersistURIMap mMap;
|
||||
|
||||
virtual ~WebBrowserPersistSerializeChild();
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // WebBrowserPersistSerializeChild_h__
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* 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 "WebBrowserPersistSerializeParent.h"
|
||||
|
||||
#include "nsReadableUtils.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
WebBrowserPersistSerializeParent::WebBrowserPersistSerializeParent(
|
||||
nsIWebBrowserPersistDocument* aDocument,
|
||||
nsIOutputStream* aStream,
|
||||
nsIWebBrowserPersistWriteCompletion* aFinish)
|
||||
: mDocument(aDocument)
|
||||
, mStream(aStream)
|
||||
, mFinish(aFinish)
|
||||
, mOutputError(NS_OK)
|
||||
{
|
||||
MOZ_ASSERT(aDocument);
|
||||
MOZ_ASSERT(aStream);
|
||||
MOZ_ASSERT(aFinish);
|
||||
}
|
||||
|
||||
WebBrowserPersistSerializeParent::~WebBrowserPersistSerializeParent()
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
WebBrowserPersistSerializeParent::RecvWriteData(nsTArray<uint8_t>&& aData)
|
||||
{
|
||||
if (NS_FAILED(mOutputError)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t written = 0;
|
||||
static_assert(sizeof(char) == sizeof(uint8_t),
|
||||
"char must be (at least?) 8 bits");
|
||||
const char* data = reinterpret_cast<const char*>(aData.Elements());
|
||||
// nsIOutputStream::Write is allowed to return short writes.
|
||||
while (written < aData.Length()) {
|
||||
uint32_t writeReturn;
|
||||
nsresult rv = mStream->Write(data + written,
|
||||
aData.Length() - written,
|
||||
&writeReturn);
|
||||
if (NS_FAILED(rv)) {
|
||||
mOutputError = rv;
|
||||
return true;
|
||||
}
|
||||
written += writeReturn;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
WebBrowserPersistSerializeParent::Recv__delete__(const nsCString& aContentType,
|
||||
const nsresult& aStatus)
|
||||
{
|
||||
if (NS_SUCCEEDED(mOutputError)) {
|
||||
mOutputError = aStatus;
|
||||
}
|
||||
mFinish->OnFinish(mDocument,
|
||||
mStream,
|
||||
aContentType,
|
||||
mOutputError);
|
||||
mFinish = nullptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
WebBrowserPersistSerializeParent::ActorDestroy(ActorDestroyReason aWhy)
|
||||
{
|
||||
if (mFinish) {
|
||||
MOZ_ASSERT(aWhy != Deletion);
|
||||
// See comment in WebBrowserPersistDocumentParent::ActorDestroy
|
||||
// (or bug 1202887) for why this is deferred.
|
||||
nsCOMPtr<nsIRunnable> errorLater = NewRunnableMethod
|
||||
<nsCOMPtr<nsIWebBrowserPersistDocument>, nsCOMPtr<nsIOutputStream>,
|
||||
nsCString, nsresult>
|
||||
(mFinish, &nsIWebBrowserPersistWriteCompletion::OnFinish,
|
||||
mDocument, mStream, EmptyCString(), NS_ERROR_FAILURE);
|
||||
NS_DispatchToCurrentThread(errorLater);
|
||||
mFinish = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* 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 WebBrowserPersistSerializeParent_h__
|
||||
#define WebBrowserPersistSerializeParent_h__
|
||||
|
||||
#include "mozilla/PWebBrowserPersistSerializeParent.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIOutputStream.h"
|
||||
#include "nsIWebBrowserPersistDocument.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class WebBrowserPersistSerializeParent
|
||||
: public PWebBrowserPersistSerializeParent
|
||||
{
|
||||
public:
|
||||
WebBrowserPersistSerializeParent(
|
||||
nsIWebBrowserPersistDocument* aDocument,
|
||||
nsIOutputStream* aStream,
|
||||
nsIWebBrowserPersistWriteCompletion* aFinish);
|
||||
virtual ~WebBrowserPersistSerializeParent();
|
||||
|
||||
virtual bool
|
||||
RecvWriteData(nsTArray<uint8_t>&& aData) override;
|
||||
|
||||
virtual bool
|
||||
Recv__delete__(const nsCString& aContentType,
|
||||
const nsresult& aStatus) override;
|
||||
|
||||
virtual void
|
||||
ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
|
||||
private:
|
||||
// See also ...ReadParent::mDocument for the other reason this
|
||||
// strong reference needs to be here.
|
||||
nsCOMPtr<nsIWebBrowserPersistDocument> mDocument;
|
||||
nsCOMPtr<nsIOutputStream> mStream;
|
||||
nsCOMPtr<nsIWebBrowserPersistWriteCompletion> mFinish;
|
||||
nsresult mOutputError;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // WebBrowserPersistSerializeParent_h__
|
||||
49
embedding/components/webbrowserpersist/moz.build
Normal file
49
embedding/components/webbrowserpersist/moz.build
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
# -*- 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 += [
|
||||
'nsCWebBrowserPersist.idl',
|
||||
'nsIWebBrowserPersist.idl',
|
||||
'nsIWebBrowserPersistable.idl',
|
||||
'nsIWebBrowserPersistDocument.idl',
|
||||
]
|
||||
|
||||
XPIDL_MODULE = 'webbrowserpersist'
|
||||
|
||||
IPDL_SOURCES += [
|
||||
'PWebBrowserPersistDocument.ipdl',
|
||||
'PWebBrowserPersistResources.ipdl',
|
||||
'PWebBrowserPersistSerialize.ipdl',
|
||||
]
|
||||
|
||||
SOURCES += [
|
||||
'nsWebBrowserPersist.cpp',
|
||||
'WebBrowserPersistDocumentChild.cpp',
|
||||
'WebBrowserPersistDocumentParent.cpp',
|
||||
'WebBrowserPersistLocalDocument.cpp',
|
||||
'WebBrowserPersistRemoteDocument.cpp',
|
||||
'WebBrowserPersistResourcesChild.cpp',
|
||||
'WebBrowserPersistResourcesParent.cpp',
|
||||
'WebBrowserPersistSerializeChild.cpp',
|
||||
'WebBrowserPersistSerializeParent.cpp',
|
||||
]
|
||||
|
||||
EXPORTS.mozilla += [
|
||||
'WebBrowserPersistDocumentChild.h',
|
||||
'WebBrowserPersistDocumentParent.h',
|
||||
'WebBrowserPersistLocalDocument.h',
|
||||
]
|
||||
|
||||
include('/ipc/chromium/chromium-config.mozbuild')
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
LOCAL_INCLUDES += [
|
||||
'/dom/base',
|
||||
'/dom/html',
|
||||
]
|
||||
|
||||
if CONFIG['GNU_CXX']:
|
||||
CXXFLAGS += ['-Wno-error=shadow']
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
/* -*- Mode: IDL; 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 "nsIWebBrowserPersist.idl"
|
||||
|
||||
%{ C++
|
||||
// {7E677795-C582-4cd1-9E8D-8271B3474D2A}
|
||||
#define NS_WEBBROWSERPERSIST_CID \
|
||||
{ 0x7e677795, 0xc582, 0x4cd1, { 0x9e, 0x8d, 0x82, 0x71, 0xb3, 0x47, 0x4d, 0x2a } }
|
||||
#define NS_WEBBROWSERPERSIST_CONTRACTID \
|
||||
"@mozilla.org/embedding/browser/nsWebBrowserPersist;1"
|
||||
%}
|
||||
286
embedding/components/webbrowserpersist/nsIWebBrowserPersist.idl
Normal file
286
embedding/components/webbrowserpersist/nsIWebBrowserPersist.idl
Normal file
|
|
@ -0,0 +1,286 @@
|
|||
/* -*- Mode: IDL; 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 "nsICancelable.idl"
|
||||
|
||||
interface nsIURI;
|
||||
interface nsIInputStream;
|
||||
interface nsIDOMDocument;
|
||||
interface nsIWebProgressListener;
|
||||
interface nsIFile;
|
||||
interface nsIChannel;
|
||||
interface nsILoadContext;
|
||||
|
||||
/**
|
||||
* Interface for persisting DOM documents and URIs to local or remote storage.
|
||||
*/
|
||||
[scriptable, uuid(8cd752a4-60b1-42c3-a819-65c7a1138a28)]
|
||||
interface nsIWebBrowserPersist : nsICancelable
|
||||
{
|
||||
/** No special persistence behaviour. */
|
||||
const unsigned long PERSIST_FLAGS_NONE = 0;
|
||||
/** Use cached data if present (skipping validation), else load from network */
|
||||
const unsigned long PERSIST_FLAGS_FROM_CACHE = 1;
|
||||
/** Bypass the cached data. */
|
||||
const unsigned long PERSIST_FLAGS_BYPASS_CACHE = 2;
|
||||
/** Ignore any redirected data (usually adverts). */
|
||||
const unsigned long PERSIST_FLAGS_IGNORE_REDIRECTED_DATA = 4;
|
||||
/** Ignore IFRAME content (usually adverts). */
|
||||
const unsigned long PERSIST_FLAGS_IGNORE_IFRAMES = 8;
|
||||
/** Do not run the incoming data through a content converter e.g. to decompress it */
|
||||
const unsigned long PERSIST_FLAGS_NO_CONVERSION = 16;
|
||||
/** Replace existing files on the disk (use with due diligence!) */
|
||||
const unsigned long PERSIST_FLAGS_REPLACE_EXISTING_FILES = 32;
|
||||
/** Don't modify or add base tags */
|
||||
const unsigned long PERSIST_FLAGS_NO_BASE_TAG_MODIFICATIONS = 64;
|
||||
/** Make changes to original dom rather than cloning nodes */
|
||||
const unsigned long PERSIST_FLAGS_FIXUP_ORIGINAL_DOM = 128;
|
||||
/** Fix links relative to destination location (not origin) */
|
||||
const unsigned long PERSIST_FLAGS_FIXUP_LINKS_TO_DESTINATION = 256;
|
||||
/** Don't make any adjustments to links */
|
||||
const unsigned long PERSIST_FLAGS_DONT_FIXUP_LINKS = 512;
|
||||
/** Force serialization of output (one file at a time; not concurrent) */
|
||||
const unsigned long PERSIST_FLAGS_SERIALIZE_OUTPUT = 1024;
|
||||
/** Don't make any adjustments to filenames */
|
||||
const unsigned long PERSIST_FLAGS_DONT_CHANGE_FILENAMES = 2048;
|
||||
/** Fail on broken inline links */
|
||||
const unsigned long PERSIST_FLAGS_FAIL_ON_BROKEN_LINKS = 4096;
|
||||
/**
|
||||
* Automatically cleanup after a failed or cancelled operation, deleting all
|
||||
* created files and directories. This flag does nothing for failed upload
|
||||
* operations to remote servers.
|
||||
*/
|
||||
const unsigned long PERSIST_FLAGS_CLEANUP_ON_FAILURE = 8192;
|
||||
/**
|
||||
* Let the WebBrowserPersist decide whether the incoming data is encoded
|
||||
* and whether it needs to go through a content converter e.g. to
|
||||
* decompress it.
|
||||
*/
|
||||
const unsigned long PERSIST_FLAGS_AUTODETECT_APPLY_CONVERSION = 16384;
|
||||
/**
|
||||
* Append the downloaded data to the target file.
|
||||
* This can only be used when persisting to a local file.
|
||||
*/
|
||||
const unsigned long PERSIST_FLAGS_APPEND_TO_FILE = 32768;
|
||||
|
||||
/**
|
||||
* Force relevant cookies to be sent with this load even if normally they
|
||||
* wouldn't be.
|
||||
*/
|
||||
const unsigned long PERSIST_FLAGS_FORCE_ALLOW_COOKIES = 65536;
|
||||
|
||||
/**
|
||||
* Flags governing how data is fetched and saved from the network.
|
||||
* It is best to set this value explicitly unless you are prepared
|
||||
* to accept the default values.
|
||||
*/
|
||||
attribute unsigned long persistFlags;
|
||||
|
||||
/** Persister is ready to save data */
|
||||
const unsigned long PERSIST_STATE_READY = 1;
|
||||
/** Persister is saving data */
|
||||
const unsigned long PERSIST_STATE_SAVING = 2;
|
||||
/** Persister has finished saving data */
|
||||
const unsigned long PERSIST_STATE_FINISHED = 3;
|
||||
|
||||
/**
|
||||
* Current state of the persister object.
|
||||
*/
|
||||
readonly attribute unsigned long currentState;
|
||||
|
||||
/**
|
||||
* Value indicating the success or failure of the persist
|
||||
* operation.
|
||||
*
|
||||
* @throws NS_BINDING_ABORTED Operation cancelled.
|
||||
* @throws NS_ERROR_FAILURE Non-specific failure.
|
||||
*/
|
||||
readonly attribute nsresult result;
|
||||
|
||||
/**
|
||||
* Callback listener for progress notifications. The object that the
|
||||
* embbedder supplies may also implement nsIInterfaceRequestor and be
|
||||
* prepared to return nsIAuthPrompt or other interfaces that may be required
|
||||
* to download data.
|
||||
*
|
||||
* @see nsIAuthPrompt
|
||||
* @see nsIInterfaceRequestor
|
||||
*/
|
||||
attribute nsIWebProgressListener progressListener;
|
||||
|
||||
/**
|
||||
* Save the specified URI to file.
|
||||
*
|
||||
* @param aURI URI to save to file. Some implementations of this interface
|
||||
* may also support <CODE>nullptr</CODE> to imply the currently
|
||||
* loaded URI.
|
||||
* @param aCacheKey An object representing the URI in the cache or
|
||||
* <CODE>nullptr</CODE>. This can be a necko cache key,
|
||||
* an nsIWebPageDescriptor, or the currentDescriptor of an
|
||||
* nsIWebPageDescriptor.
|
||||
* @param aReferrer The referrer URI to pass with an HTTP request or
|
||||
* <CODE>nullptr</CODE>.
|
||||
* @param aReferrerPolicy The referrer policy for when and what to send via
|
||||
* HTTP Referer header. Ignored if aReferrer is
|
||||
* <CODE>nullptr</CODE>. Taken from REFERRER_POLICY
|
||||
* constants in nsIHttpChannel.
|
||||
* @param aPostData Post data to pass with an HTTP request or
|
||||
* <CODE>nullptr</CODE>.
|
||||
* @param aExtraHeaders Additional headers to supply with an HTTP request
|
||||
* or <CODE>nullptr</CODE>.
|
||||
* @param aFile Target file. This may be a nsIFile object or an
|
||||
* nsIURI object with a file scheme or a scheme that
|
||||
* supports uploading (e.g. ftp).
|
||||
* @param aPrivacyContext A context from which the privacy status of this
|
||||
* save operation can be determined. Must only be null
|
||||
* in situations in which no such context is available
|
||||
* (eg. the operation has no logical association with any
|
||||
* window or document)
|
||||
*
|
||||
* @see nsIFile
|
||||
* @see nsIURI
|
||||
* @see nsIInputStream
|
||||
*
|
||||
* @throws NS_ERROR_INVALID_ARG One or more arguments was invalid.
|
||||
*/
|
||||
void saveURI(in nsIURI aURI, in nsISupports aCacheKey,
|
||||
in nsIURI aReferrer, in unsigned long aReferrerPolicy,
|
||||
in nsIInputStream aPostData,
|
||||
in string aExtraHeaders, in nsISupports aFile,
|
||||
in nsILoadContext aPrivacyContext);
|
||||
|
||||
/**
|
||||
* @param aIsPrivate Treat the save operation as private (ie. with
|
||||
* regards to networking operations and persistence
|
||||
* of intermediate data, etc.)
|
||||
* @see saveURI for all other parameter descriptions
|
||||
*/
|
||||
void savePrivacyAwareURI(in nsIURI aURI, in nsISupports aCacheKey,
|
||||
in nsIURI aReferrer, in unsigned long aReferrerPolicy,
|
||||
in nsIInputStream aPostData,
|
||||
in string aExtraHeaders, in nsISupports aFile,
|
||||
in boolean aIsPrivate);
|
||||
|
||||
/**
|
||||
* Save a channel to a file. It must not be opened yet.
|
||||
* @see saveURI
|
||||
*/
|
||||
void saveChannel(in nsIChannel aChannel, in nsISupports aFile);
|
||||
|
||||
/** Output only the current selection as opposed to the whole document. */
|
||||
const unsigned long ENCODE_FLAGS_SELECTION_ONLY = 1;
|
||||
/**
|
||||
* For plaintext output. Convert html to plaintext that looks like the html.
|
||||
* Implies wrap (except inside <pre>), since html wraps.
|
||||
* HTML output: always do prettyprinting, ignoring existing formatting.
|
||||
*/
|
||||
const unsigned long ENCODE_FLAGS_FORMATTED = 2;
|
||||
/**
|
||||
* Output without formatting or wrapping the content. This flag
|
||||
* may be used to preserve the original formatting as much as possible.
|
||||
*/
|
||||
const unsigned long ENCODE_FLAGS_RAW = 4;
|
||||
/** Output only the body section, no HTML tags. */
|
||||
const unsigned long ENCODE_FLAGS_BODY_ONLY = 8;
|
||||
/** Wrap even if when not doing formatted output (e.g. for text fields). */
|
||||
const unsigned long ENCODE_FLAGS_PREFORMATTED = 16;
|
||||
/** Wrap documents at the specified column. */
|
||||
const unsigned long ENCODE_FLAGS_WRAP = 32;
|
||||
/**
|
||||
* For plaintext output. Output for format flowed (RFC 2646). This is used
|
||||
* when converting to text for mail sending. This differs just slightly
|
||||
* but in an important way from normal formatted, and that is that
|
||||
* lines are space stuffed. This can't (correctly) be done later.
|
||||
*/
|
||||
const unsigned long ENCODE_FLAGS_FORMAT_FLOWED = 64;
|
||||
/** Convert links to absolute links where possible. */
|
||||
const unsigned long ENCODE_FLAGS_ABSOLUTE_LINKS = 128;
|
||||
|
||||
/**
|
||||
* Attempt to encode entities standardized at W3C (HTML, MathML, etc).
|
||||
* This is a catch-all flag for documents with mixed contents. Beware of
|
||||
* interoperability issues. See below for other flags which might likely
|
||||
* do what you want.
|
||||
*/
|
||||
const unsigned long ENCODE_FLAGS_ENCODE_W3C_ENTITIES = 256;
|
||||
|
||||
/**
|
||||
* Output with carriage return line breaks. May also be combined with
|
||||
* ENCODE_FLAGS_LF_LINEBREAKS and if neither is specified, the platform
|
||||
* default format is used.
|
||||
*/
|
||||
const unsigned long ENCODE_FLAGS_CR_LINEBREAKS = 512;
|
||||
/**
|
||||
* Output with linefeed line breaks. May also be combined with
|
||||
* ENCODE_FLAGS_CR_LINEBREAKS and if neither is specified, the platform
|
||||
* default format is used.
|
||||
*/
|
||||
const unsigned long ENCODE_FLAGS_LF_LINEBREAKS = 1024;
|
||||
/** For plaintext output. Output the content of noscript elements. */
|
||||
const unsigned long ENCODE_FLAGS_NOSCRIPT_CONTENT = 2048;
|
||||
/** For plaintext output. Output the content of noframes elements. */
|
||||
const unsigned long ENCODE_FLAGS_NOFRAMES_CONTENT = 4096;
|
||||
|
||||
/**
|
||||
* Encode basic entities, e.g. output instead of character code 0xa0.
|
||||
* The basic set is just & < > " for interoperability
|
||||
* with older products that don't support α and friends.
|
||||
*/
|
||||
const unsigned long ENCODE_FLAGS_ENCODE_BASIC_ENTITIES = 8192;
|
||||
/**
|
||||
* Encode Latin1 entities. This includes the basic set and
|
||||
* accented letters between 128 and 255.
|
||||
*/
|
||||
const unsigned long ENCODE_FLAGS_ENCODE_LATIN1_ENTITIES = 16384;
|
||||
/**
|
||||
* Encode HTML4 entities. This includes the basic set, accented
|
||||
* letters, greek letters and certain special markup symbols.
|
||||
*/
|
||||
const unsigned long ENCODE_FLAGS_ENCODE_HTML_ENTITIES = 32768;
|
||||
|
||||
/**
|
||||
* Save the specified DOM document to file and optionally all linked files
|
||||
* (e.g. images, CSS, JS & subframes). Do not call this method until the
|
||||
* document has finished loading!
|
||||
*
|
||||
* @param aDocument Document to save to file. Some implementations of
|
||||
* this interface may also support <CODE>nullptr</CODE>
|
||||
* to imply the currently loaded document. Can be an
|
||||
* nsIWebBrowserPersistDocument or nsIDOMDocument.
|
||||
* @param aFile Target local file. This may be a nsIFile object or an
|
||||
* nsIURI object with a file scheme or a scheme that
|
||||
* supports uploading (e.g. ftp).
|
||||
* @param aDataPath Path to directory where URIs linked to the document
|
||||
* are saved or nullptr if no linked URIs should be saved.
|
||||
* This may be a nsIFile object or an nsIURI object
|
||||
* with a file scheme.
|
||||
* @param aOutputContentType The desired MIME type format to save the
|
||||
* document and all subdocuments into or nullptr to use
|
||||
* the default behaviour.
|
||||
* @param aEncodingFlags Flags to pass to the encoder.
|
||||
* @param aWrapColumn For text documents, indicates the desired width to
|
||||
* wrap text at. Parameter is ignored if wrapping is not
|
||||
* specified by the encoding flags.
|
||||
*
|
||||
* @see nsIWebBrowserPersistDocument
|
||||
* @see nsIWebBrowserPersistable
|
||||
* @see nsIFile
|
||||
* @see nsIURI
|
||||
*
|
||||
* @throws NS_ERROR_INVALID_ARG One or more arguments was invalid.
|
||||
*/
|
||||
void saveDocument(in nsISupports aDocument,
|
||||
in nsISupports aFile, in nsISupports aDataPath,
|
||||
in string aOutputContentType, in unsigned long aEncodingFlags,
|
||||
in unsigned long aWrapColumn);
|
||||
|
||||
/**
|
||||
* Cancels the current operation. The caller is responsible for cleaning up
|
||||
* partially written files or directories. This has the same effect as calling
|
||||
* cancel with an argument of NS_BINDING_ABORTED.
|
||||
*/
|
||||
void cancelSave();
|
||||
};
|
||||
|
|
@ -0,0 +1,197 @@
|
|||
/* -*- Mode: IDL; 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 nsIDOMDocument;
|
||||
interface nsIInputStream;
|
||||
interface nsIOutputStream;
|
||||
interface nsITabParent;
|
||||
interface nsIWebBrowserPersistResourceVisitor;
|
||||
interface nsIWebBrowserPersistWriteCompletion;
|
||||
|
||||
/**
|
||||
* Interface for the URI-mapping information that can be supplied when
|
||||
* serializing the DOM of an nsIWebBrowserPersistDocument.
|
||||
*
|
||||
* @see nsIWebBrowserPersistDocument
|
||||
*/
|
||||
[scriptable, uuid(d52e8b93-2771-45e8-a5b0-6e12b667046b)]
|
||||
interface nsIWebBrowserPersistURIMap : nsISupports
|
||||
{
|
||||
/**
|
||||
* The number of URI mappings.
|
||||
*/
|
||||
readonly attribute unsigned long numMappedURIs;
|
||||
|
||||
/**
|
||||
* Obtain the URI mapping at the given index, which must be less than
|
||||
* numMappedURIs, as a pair of URI spec strings.
|
||||
*/
|
||||
void getURIMapping(in unsigned long aIndex,
|
||||
out AUTF8String aMapFrom,
|
||||
out AUTF8String aMapTo);
|
||||
|
||||
/**
|
||||
* The spec of the base URI that the document will have after it is
|
||||
* serialized.
|
||||
*/
|
||||
readonly attribute AUTF8String targetBaseURI;
|
||||
};
|
||||
|
||||
/**
|
||||
* Interface representing a document that can be serialized with
|
||||
* nsIWebBrowserPersist; it may or may not be in this process. Some
|
||||
* information is exposed as attributes, which may or may not reflect
|
||||
* changes made to the underlying document; most of these are
|
||||
* self-explanatory from their names and types.
|
||||
*/
|
||||
[scriptable, uuid(74aa4918-5d15-46b6-9ccf-74f9696d721d)]
|
||||
interface nsIWebBrowserPersistDocument : nsISupports
|
||||
{
|
||||
readonly attribute boolean isPrivate;
|
||||
readonly attribute AUTF8String documentURI;
|
||||
readonly attribute AUTF8String baseURI;
|
||||
readonly attribute ACString contentType;
|
||||
readonly attribute ACString characterSet;
|
||||
readonly attribute AString title;
|
||||
readonly attribute AString referrer;
|
||||
readonly attribute AString contentDisposition;
|
||||
readonly attribute nsIInputStream postData;
|
||||
|
||||
/**
|
||||
* The cache key. Unlike in nsISHEntry, where it's wrapped in an
|
||||
* nsISupportsPRUint32, this is just the integer.
|
||||
*/
|
||||
readonly attribute unsigned long cacheKey;
|
||||
|
||||
/**
|
||||
* This attribute is set by nsIWebBrowserPersist implementations to
|
||||
* propagate persist flags that apply to the DOM traversal and
|
||||
* serialization (rather than to managing file I/O).
|
||||
*/
|
||||
attribute unsigned long persistFlags;
|
||||
|
||||
/**
|
||||
* Walk the DOM searching for external resources needed to render it.
|
||||
* The visitor callbacks may be called either before or after
|
||||
* readResources returns.
|
||||
*
|
||||
* @see nsIWebBrowserPersistResourceVisitor
|
||||
*/
|
||||
void readResources(in nsIWebBrowserPersistResourceVisitor aVisitor);
|
||||
|
||||
/**
|
||||
* Serialize the document's DOM.
|
||||
*
|
||||
* @param aStream The output stream to write the document to.
|
||||
*
|
||||
* @param aURIMap Optional; specifies URI rewriting to perform on
|
||||
* external references (as read by readResources).
|
||||
* If given, also causes relative hyperlinks to be
|
||||
* converted to absolute in the written text.
|
||||
*
|
||||
* @param aRequestedContentType
|
||||
* The desired MIME type to save the document as;
|
||||
* optional and defaults to the document's type.
|
||||
* (If no encoder exists for that type, "text/html"
|
||||
* is used instead.)
|
||||
*
|
||||
* @param aEncoderFlags Flags to pass to the encoder.
|
||||
*
|
||||
* @param aWrapColumn Desired text width, ignored if wrapping is not
|
||||
* specified by the encoding flags, or if 0.
|
||||
*
|
||||
* @param aCompletion Callback invoked when writing is complete.
|
||||
* It may be called either before or after writeContent
|
||||
* returns.
|
||||
*
|
||||
* @see nsIDocumentEncoder
|
||||
*/
|
||||
void writeContent(in nsIOutputStream aStream,
|
||||
in nsIWebBrowserPersistURIMap aURIMap,
|
||||
in ACString aRequestedContentType,
|
||||
in unsigned long aEncoderFlags,
|
||||
in unsigned long aWrapColumn,
|
||||
in nsIWebBrowserPersistWriteCompletion aCompletion);
|
||||
};
|
||||
|
||||
/**
|
||||
* Asynchronous visitor that receives external resources linked by an
|
||||
* nsIWebBrowserPersistDocument and which are needed to render the
|
||||
* document.
|
||||
*/
|
||||
[scriptable, uuid(8ce37706-b7d3-481a-be68-54f174fc0d0a)]
|
||||
interface nsIWebBrowserPersistResourceVisitor : nsISupports
|
||||
{
|
||||
/**
|
||||
* Indicates a resource that is not a document; e.g., an image, script,
|
||||
* or stylesheet.
|
||||
*
|
||||
* @param aDocument The document containing the reference.
|
||||
* @param aURI The absolute URI spec for the referenced resource.
|
||||
*/
|
||||
void visitResource(in nsIWebBrowserPersistDocument aDocument,
|
||||
in AUTF8String aURI);
|
||||
/**
|
||||
* Indicates a subdocument resource; e.g., a frame or iframe.
|
||||
*
|
||||
* @param aDocument The document containing the reference.
|
||||
* @param aSubDocument The referenced document.
|
||||
*/
|
||||
void visitDocument(in nsIWebBrowserPersistDocument aDocument,
|
||||
in nsIWebBrowserPersistDocument aSubDocument);
|
||||
|
||||
/**
|
||||
* Indicates that the document traversal is complete.
|
||||
*
|
||||
* @param aDocument The document that was being traversed.
|
||||
* @param aStatus Indicates whether the traversal encountered an error.
|
||||
*/
|
||||
void endVisit(in nsIWebBrowserPersistDocument aDocument,
|
||||
in nsresult aStatus);
|
||||
};
|
||||
|
||||
/**
|
||||
* Asynchronous callback for when nsIWebBrowserPersistDocument is finished
|
||||
* serializing the document's DOM.
|
||||
*/
|
||||
[scriptable, function, uuid(a07e6892-38ae-4207-8340-7fa6ec446ed6)]
|
||||
interface nsIWebBrowserPersistWriteCompletion : nsISupports
|
||||
{
|
||||
/**
|
||||
* Indicates that serialization is finished.
|
||||
*
|
||||
* @param aDocument The document that was being serialized.
|
||||
*
|
||||
* @param aStream The stream that was being written to. If it
|
||||
* needs to be closed, the callback must do that;
|
||||
* the serialization process leaves it open.
|
||||
*
|
||||
* @param aContentType The content type with which the document was
|
||||
* actually serialized; this may be useful to set
|
||||
* metadata on the result, or if uploading it.
|
||||
*
|
||||
* @param aStatus Indicates whether serialization encountered an error.
|
||||
*/
|
||||
void onFinish(in nsIWebBrowserPersistDocument aDocument,
|
||||
in nsIOutputStream aStream,
|
||||
in ACString aContentType,
|
||||
in nsresult aStatus);
|
||||
};
|
||||
|
||||
/**
|
||||
* Asynchronous callback for creating a persistable document from some
|
||||
* other object.
|
||||
*
|
||||
* @see nsIWebBrowserPersistable.
|
||||
*/
|
||||
[scriptable, uuid(321e3174-594f-4036-b7be-791b821bd376)]
|
||||
interface nsIWebBrowserPersistDocumentReceiver : nsISupports
|
||||
{
|
||||
void onDocumentReady(in nsIWebBrowserPersistDocument aDocument);
|
||||
void onError(in nsresult aFailure);
|
||||
};
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
/* -*- Mode: IDL; 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 nsIWebBrowserPersistDocumentReceiver;
|
||||
|
||||
/**
|
||||
* Interface for objects which represent a document that can be
|
||||
* serialized with nsIWebBrowserPersist. This interface is
|
||||
* asynchronous because the actual document can be in another process
|
||||
* (e.g., if this object is an nsFrameLoader for an out-of-process
|
||||
* frame).
|
||||
*
|
||||
* Warning: this is currently implemented only by nsFrameLoader, and
|
||||
* may change in the future to become more frame-loader-specific or be
|
||||
* merged into nsIFrameLoader. See bug 1101100 comment #34.
|
||||
*
|
||||
* @see nsIWebBrowserPersistDocumentReceiver
|
||||
* @see nsIWebBrowserPersistDocument
|
||||
* @see nsIWebBrowserPersist
|
||||
*
|
||||
* @param aOuterWindowID
|
||||
* The outer window ID of the subframe we'd like to persist.
|
||||
* If set at 0, nsIWebBrowserPersistable will attempt to persist
|
||||
* the top-level document. If the outer window ID is for a subframe
|
||||
* that does not exist, or is not held beneath the nsIWebBrowserPersistable,
|
||||
* aRecv's onError method will be called with NS_ERROR_NO_CONTENT.
|
||||
* @param aRecv
|
||||
* The nsIWebBrowserPersistDocumentReceiver is a callback that
|
||||
* will be fired once the document is ready for persisting.
|
||||
*/
|
||||
[scriptable, uuid(f4c3fa8e-83e9-49f8-ac6f-951fc7541fe4)]
|
||||
interface nsIWebBrowserPersistable : nsISupports
|
||||
{
|
||||
void startPersistence(in unsigned long long aOuterWindowID,
|
||||
in nsIWebBrowserPersistDocumentReceiver aRecv);
|
||||
};
|
||||
2812
embedding/components/webbrowserpersist/nsWebBrowserPersist.cpp
Normal file
2812
embedding/components/webbrowserpersist/nsWebBrowserPersist.cpp
Normal file
File diff suppressed because it is too large
Load diff
181
embedding/components/webbrowserpersist/nsWebBrowserPersist.h
Normal file
181
embedding/components/webbrowserpersist/nsWebBrowserPersist.h
Normal file
|
|
@ -0,0 +1,181 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* 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 nsWebBrowserPersist_h__
|
||||
#define nsWebBrowserPersist_h__
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsWeakReference.h"
|
||||
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsIMIMEService.h"
|
||||
#include "nsIStreamListener.h"
|
||||
#include "nsIOutputStream.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsIChannel.h"
|
||||
#include "nsIDocumentEncoder.h"
|
||||
#include "nsITransport.h"
|
||||
#include "nsIProgressEventSink.h"
|
||||
#include "nsIFile.h"
|
||||
#include "nsIWebProgressListener2.h"
|
||||
#include "nsIWebBrowserPersistDocument.h"
|
||||
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "nsClassHashtable.h"
|
||||
#include "nsHashKeys.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
#include "nsCWebBrowserPersist.h"
|
||||
|
||||
class nsIStorageStream;
|
||||
class nsIWebBrowserPersistDocument;
|
||||
|
||||
class nsWebBrowserPersist final : public nsIInterfaceRequestor,
|
||||
public nsIWebBrowserPersist,
|
||||
public nsIStreamListener,
|
||||
public nsIProgressEventSink,
|
||||
public nsSupportsWeakReference
|
||||
{
|
||||
friend class nsEncoderNodeFixup;
|
||||
|
||||
// Public members
|
||||
public:
|
||||
nsWebBrowserPersist();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIINTERFACEREQUESTOR
|
||||
NS_DECL_NSICANCELABLE
|
||||
NS_DECL_NSIWEBBROWSERPERSIST
|
||||
NS_DECL_NSIREQUESTOBSERVER
|
||||
NS_DECL_NSISTREAMLISTENER
|
||||
NS_DECL_NSIPROGRESSEVENTSINK
|
||||
|
||||
// Private members
|
||||
private:
|
||||
virtual ~nsWebBrowserPersist();
|
||||
nsresult SaveURIInternal(
|
||||
nsIURI *aURI, nsISupports *aCacheKey, nsIURI *aReferrer,
|
||||
uint32_t aReferrerPolicy, nsIInputStream *aPostData,
|
||||
const char *aExtraHeaders, nsIURI *aFile,
|
||||
bool aCalcFileExt, bool aIsPrivate);
|
||||
nsresult SaveChannelInternal(
|
||||
nsIChannel *aChannel, nsIURI *aFile, bool aCalcFileExt);
|
||||
nsresult SaveDocumentInternal(
|
||||
nsIWebBrowserPersistDocument *aDocument,
|
||||
nsIURI *aFile,
|
||||
nsIURI *aDataPath);
|
||||
nsresult SaveDocuments();
|
||||
void FinishSaveDocumentInternal(nsIURI* aFile, nsIFile* aDataPath);
|
||||
nsresult GetExtensionForContentType(
|
||||
const char16_t *aContentType, char16_t **aExt);
|
||||
|
||||
struct CleanupData;
|
||||
struct DocData;
|
||||
struct OutputData;
|
||||
struct UploadData;
|
||||
struct URIData;
|
||||
struct WalkData;
|
||||
struct URIFixupData;
|
||||
|
||||
class OnWalk;
|
||||
class OnWrite;
|
||||
class FlatURIMap;
|
||||
friend class OnWalk;
|
||||
friend class OnWrite;
|
||||
|
||||
nsresult SaveDocumentDeferred(mozilla::UniquePtr<WalkData>&& aData);
|
||||
void Cleanup();
|
||||
void CleanupLocalFiles();
|
||||
nsresult GetValidURIFromObject(nsISupports *aObject, nsIURI **aURI) const;
|
||||
static nsresult GetLocalFileFromURI(nsIURI *aURI, nsIFile **aLocalFile);
|
||||
static nsresult AppendPathToURI(nsIURI *aURI, const nsAString & aPath);
|
||||
nsresult MakeAndStoreLocalFilenameInURIMap(
|
||||
nsIURI *aURI, bool aNeedsPersisting, URIData **aData);
|
||||
nsresult MakeOutputStream(
|
||||
nsIURI *aFile, nsIOutputStream **aOutputStream);
|
||||
nsresult MakeOutputStreamFromFile(
|
||||
nsIFile *aFile, nsIOutputStream **aOutputStream);
|
||||
nsresult MakeOutputStreamFromURI(nsIURI *aURI, nsIOutputStream **aOutStream);
|
||||
nsresult CreateChannelFromURI(nsIURI *aURI, nsIChannel **aChannel);
|
||||
nsresult StartUpload(nsIStorageStream *aOutStream, nsIURI *aDestinationURI,
|
||||
const nsACString &aContentType);
|
||||
nsresult StartUpload(nsIInputStream *aInputStream, nsIURI *aDestinationURI,
|
||||
const nsACString &aContentType);
|
||||
nsresult CalculateAndAppendFileExt(nsIURI *aURI, nsIChannel *aChannel,
|
||||
nsIURI *aOriginalURIWithExtension);
|
||||
nsresult CalculateUniqueFilename(nsIURI *aURI);
|
||||
nsresult MakeFilenameFromURI(
|
||||
nsIURI *aURI, nsString &aFilename);
|
||||
nsresult StoreURI(
|
||||
const char *aURI,
|
||||
bool aNeedsPersisting = true,
|
||||
URIData **aData = nullptr);
|
||||
nsresult StoreURI(
|
||||
nsIURI *aURI,
|
||||
bool aNeedsPersisting = true,
|
||||
URIData **aData = nullptr);
|
||||
bool DocumentEncoderExists(const char *aContentType);
|
||||
|
||||
nsresult SaveSubframeContent(
|
||||
nsIWebBrowserPersistDocument *aFrameContent,
|
||||
const nsCString& aURISpec,
|
||||
URIData *aData);
|
||||
nsresult SendErrorStatusChange(
|
||||
bool aIsReadError, nsresult aResult, nsIRequest *aRequest, nsIURI *aURI);
|
||||
|
||||
nsresult FixRedirectedChannelEntry(nsIChannel *aNewChannel);
|
||||
|
||||
void EndDownload(nsresult aResult);
|
||||
void FinishDownload();
|
||||
void SerializeNextFile();
|
||||
void CalcTotalProgress();
|
||||
|
||||
void SetApplyConversionIfNeeded(nsIChannel *aChannel);
|
||||
|
||||
nsCOMPtr<nsIURI> mCurrentDataPath;
|
||||
bool mCurrentDataPathIsRelative;
|
||||
nsCString mCurrentRelativePathToData;
|
||||
nsCOMPtr<nsIURI> mCurrentBaseURI;
|
||||
nsCString mCurrentCharset;
|
||||
nsCOMPtr<nsIURI> mTargetBaseURI;
|
||||
uint32_t mCurrentThingsToPersist;
|
||||
|
||||
nsCOMPtr<nsIMIMEService> mMIMEService;
|
||||
nsCOMPtr<nsIURI> mURI;
|
||||
nsCOMPtr<nsIWebProgressListener> mProgressListener;
|
||||
/**
|
||||
* Progress listener for 64-bit values; this is the same object as
|
||||
* mProgressListener, but is a member to avoid having to qi it for each
|
||||
* progress notification.
|
||||
*/
|
||||
nsCOMPtr<nsIWebProgressListener2> mProgressListener2;
|
||||
nsCOMPtr<nsIProgressEventSink> mEventSink;
|
||||
nsClassHashtable<nsISupportsHashKey, OutputData> mOutputMap;
|
||||
nsClassHashtable<nsISupportsHashKey, UploadData> mUploadList;
|
||||
nsClassHashtable<nsCStringHashKey, URIData> mURIMap;
|
||||
nsCOMPtr<nsIWebBrowserPersistURIMap> mFlatURIMap;
|
||||
nsTArray<mozilla::UniquePtr<WalkData>> mWalkStack;
|
||||
nsTArray<DocData*> mDocList;
|
||||
nsTArray<CleanupData*> mCleanupList;
|
||||
nsTArray<nsCString> mFilenameList;
|
||||
bool mFirstAndOnlyUse;
|
||||
bool mSavingDocument;
|
||||
bool mCancel;
|
||||
bool mCompleted;
|
||||
bool mStartSaving;
|
||||
bool mReplaceExisting;
|
||||
bool mSerializingOutput;
|
||||
bool mIsPrivate;
|
||||
uint32_t mPersistFlags;
|
||||
nsresult mPersistResult;
|
||||
int64_t mTotalCurrentProgress;
|
||||
int64_t mTotalMaxProgress;
|
||||
int16_t mWrapColumn;
|
||||
uint32_t mEncodingFlags;
|
||||
nsString mContentType;
|
||||
};
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue