Issue #1258 - Part 1: Import mailnews, ldap, and mork from comm-esr52.9.1

This commit is contained in:
Matt A. Tobin 2019-11-03 00:17:46 -04:00 • committed by Roy Tam
commit e400f4130a
1564 changed files with 510348 additions and 0 deletions

View file

@ -0,0 +1,285 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80 filetype=javascript: */
/* 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/. */
/**
* This file implements helper methods to make the transition of base mailnews
* objects from JS to C++ easier, and also to allow creating specialized
* versions of those accounts using only JS XPCOM implementations.
*
* In C++ land, the XPCOM component is a generic C++ class that does nothing
* but delegate any calls to interfaces known in C++ to either the generic
* C++ implementation (such as nsMsgIncomingServer.cpp) or a JavaScript
* implementation of those methods. Those delegations could be used for either
* method-by-method replacement of the generic C++ methods with JavaScript
* versions, or for specialization of the generic class using JavaScript to
* implement a particular class type. We use a C++ class as the main XPCOM
* version for two related reasons: First, we do not want to go through a
* C++->js->C++ XPCOM transition just to execute a C++ method. Second, C++
* inheritance is different from JS inheritance, and sometimes the C++ code
* will ignore the XPCOM parts of the JS, and just execute using C++
* inheritance.
*
* In JavaScript land, the implementation currently uses the XPCOM object for
* JavaScript calls, with the last object in the prototype chain defaulting
* to calling using the CPP object, specified in an instance-specific
* this.cppBase object.
*
* Examples of use can be found in the test files for jsaccount stuff.
*/
const EXPORTED_SYMBOLS = ["JSAccountUtils"];
var JSAccountUtils = {};
var Cc = Components.classes;
var Ci = Components.interfaces;
var Cu = Components.utils;
var Cr = Components.results;
Cu.import("resource://gre/modules/Log.jsm");
Cu.import("resource://gre/modules/Preferences.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
// Logger definitions.
const LOGGER_NAME = "JsAccount";
const PREF_BRANCH_LOG = "mailnews.jsaccount.log.";
const PREF_LOG_LEVEL = PREF_BRANCH_LOG + "level";
const PREF_LOG_DUMP = PREF_BRANCH_LOG + "dump";
// Set default logging levels.
const LOG_LEVEL_DEFAULT = "Info"
const LOG_DUMP_DEFAULT = true;
// Logging usage: set mailnews.jsaccount.log.level to the word "Debug" to
// increase logging level.
var log = configureLogging();
/**
*
* Generic factory to create XPCOM components under JsAccount.
*
* @param aProperties This a a const JS object that describes the specific
* details of a particular JsAccount XPCOM object:
* {
* baseContractID: string contractID used to create the base generic C++
* object. This object must implement the interfaces in
* baseInterfaces, plus msgIOverride.
*
* baseInterfaces: JS array of interfaces implemented by the base, generic
* C++ object.
*
* extraInterfaces: JS array of additional interfaces implemented by the
* component (accessed using getInterface())
*
* contractID: string contract ID for the JS object that will be
* created by the factory.
*
* classID: Components.ID(CID) for the JS object that will be
* created by the factory, where CID is a string uuid.
* }
*
* @param aJsDelegateConstructor: a JS contructor class, called using new,
* that will create the JS object to which
* XPCOM methods calls will be delegated.
*/
JSAccountUtils.jaFactory = function (aProperties, aJsDelegateConstructor)
{
let factory = {};
factory.QueryInterface = XPCOMUtils.generateQI([Ci.nsIFactory]);
factory.lockFactory = function() {};
factory.createInstance = function(outer, iid)
{
if (outer != null)
throw Cr.NS_ERROR_NO_AGGREGATION;
// C++ delegator class.
let delegator = Cc[aProperties.baseContractID]
.createInstance(Ci.msgIOverride);
// Make sure the delegator JS wrapper knows its interfaces.
aProperties.baseInterfaces.forEach(iface => delegator instanceof iface);
// JavaScript overrides of base class functions.
let jsDelegate = new aJsDelegateConstructor(delegator, aProperties.baseInterfaces);
delegator.jsDelegate = jsDelegate;
// Get the delegate list for this current class. Use OwnProperty in case it
// inherits from another JsAccount class.
let delegateList = null;
if (Object.getPrototypeOf(jsDelegate).hasOwnProperty("delegateList")) {
delegateList = Object.getPrototypeOf(jsDelegate).delegateList;
}
if (delegateList instanceof Ci.msgIDelegateList) {
delegator.methodsToDelegate = delegateList;
} else {
// Lazily create and populate the list of methods to delegate.
log.info("creating delegate list for contractID " + aProperties.contractID);
let delegateList = delegator.methodsToDelegate;
Object.keys(delegator).forEach(name => {log.debug("delegator has key " + name);});
// jsMethods contains the methods that may be targets of the C++ delegation to JS.
let jsMethods = Object.getPrototypeOf(delegator.jsDelegate.wrappedJSObject);
for (let name in jsMethods)
{
log.debug("processing jsDelegate method: " + name);
if (name[0] == '_') { // don't bother with methods explicitly marked as internal.
log.debug("skipping " + name);
continue;
}
// Other methods to skip.
if (["QueryInterface", // nsISupports
"methodsToDelegate", "jsDelegate", "cppBase", // msgIOverride
"delegateList", "wrappedJSObject", // non-XPCOM methods to skip
].includes(name)) {
log.debug("skipping " + name);
continue;
}
let jsDescriptor = getPropertyDescriptor(jsMethods, name);
if (!jsDescriptor) {
log.debug("no jsDescriptor for " + name);
continue;
}
let cppDescriptor = Object.getOwnPropertyDescriptor(delegator, name);
if (!cppDescriptor) {
log.debug("no cppDescriptor found for " + name);
// It is OK for jsMethods to have methods that are not used in override of C++.
continue;
}
let upperCaseName = name[0].toUpperCase() + name.substr(1);
if ('value' in jsDescriptor) {
log.info("delegating " + upperCaseName);
delegateList.add(upperCaseName);
}
else {
if (jsDescriptor.set) {
log.info("delegating Set" + upperCaseName);
delegateList.add("Set" + upperCaseName);
}
if (jsDescriptor.get) {
log.info("delegating Get" + upperCaseName);
delegateList.add("Get" + upperCaseName);
}
}
}
// Save the delegate list for reuse, statically for all instances.
Object.getPrototypeOf(jsDelegate).delegateList = delegateList;
}
for (let iface of aProperties.baseInterfaces)
if (iid.equals(iface)) {
log.debug("Successfully returning delegator " + delegator);
return delegator;
}
throw Cr.NS_ERROR_NO_INTERFACE;
};
return factory;
}
/**
* Create a JS object that contains calls to each of the methods in a CPP
* base class, that will reference the cpp object defined on a particular
* instance of the object. This is intended to be the last item in the
* prototype chain for a JsAccount implementation.
*
* @param aProperties see definition in jsFactory above
*
* @returns a JS object suitable as the prototype of a JsAccount implementation.
*/
JSAccountUtils.makeCppDelegator = function(aProperties)
{
log.info("Making cppDelegator for contractID " + aProperties.contractID);
let cppDelegator = {};
let cppDummy = Cc[aProperties.baseContractID].createInstance(Ci.nsISupports);
// Add methods from all interfaces.
for (let iface of aProperties.baseInterfaces)
cppDummy instanceof Ci[iface];
for (let method in cppDummy) {
// skip nsISupports and msgIOverride methods
if (["QueryInterface", "methodsToDelegate", "jsDelegate", "cppBase", "getInterface"].includes(method)) {
log.config("Skipping " + method + "\n");
continue;
}
log.config("processing " + method + "\n");
let descriptor = Object.getOwnPropertyDescriptor(cppDummy, method);
let property = { enumerable: true };
// We must use Immediately Invoked Function Expressions to pass method, otherwise it is
// a closure containing just the last value it was set to.
if ('value' in descriptor) {
log.debug("Adding value for " + method);
property.value = function(aMethod) {
return function(...args) {
return Reflect.apply(this.cppBase[aMethod], undefined, args);
};
}(method);
}
if (descriptor.set) {
log.debug("Adding setter for " + method);
property.set = function(aMethod) {
return function(aVal) {
this.cppBase[aMethod] = aVal;
};
}(method);
}
if (descriptor.get) {
log.debug("Adding getter for " + method);
property.get = function(aMethod) {
return function() {
return this.cppBase[aMethod];
};
}(method);
}
Object.defineProperty(cppDelegator, method, property);
}
return cppDelegator;
}
// Utility functions.
// Iterate over an object and its prototypes to get a property descriptor.
function getPropertyDescriptor(obj, name)
{
let descriptor = null;
// Eventually we will hit an object that will delegate JS calls to a CPP
// object, which are not JS overrides of CPP methods. Locate this item, and
// skip, because it will not have _JsPrototypeToDelegate defined.
while (obj && ("_JsPrototypeToDelegate" in obj)) {
descriptor = Object.getOwnPropertyDescriptor(obj, name);
if (descriptor)
break;
obj = Object.getPrototypeOf(obj);
}
return descriptor;
}
// Configure the logger based on the preferences.
function configureLogging()
{
let log = Log.repository.getLogger(LOGGER_NAME);
// Log messages need to go to the browser console.
let consoleAppender = new Log.ConsoleAppender(new Log.BasicFormatter());
log.addAppender(consoleAppender);
// Make sure the logger keeps up with the logging level preference.
log.level = Log.Level[Preferences.get(PREF_LOG_LEVEL, LOG_LEVEL_DEFAULT)];
// If enabled in the preferences, add a dump appender.
let logDumping = Preferences.get(PREF_LOG_DUMP, LOG_DUMP_DEFAULT);
if (logDumping) {
let dumpAppender = new Log.DumpAppender(new Log.BasicFormatter());
log.addAppender(dumpAppender);
}
return log;
}

View file

@ -0,0 +1,81 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80 filetype=javascript: */
/* 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/. */
const EXPORTED_SYMBOLS = ["JaBaseUrlProperties", "JaBaseUrl"];
var Cc = Components.classes;
var Ci = Components.interfaces;
var Cr = Components.results;
var Cu = Components.utils;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/jsaccount/JSAccountUtils.jsm");
// A partial JavaScript implementation of the base server methods.
const JaBaseUrlProperties = {
// The CPP object that delgates to CPP or JS.
baseContractID: "@mozilla.org/jacppurldelegator;1",
// Interfaces implemented by the base CPP version of this object.
baseInterfaces: [ Ci.nsIURI,
Ci.nsIURL,
Ci.nsIMsgMailNewsUrl,
Ci.nsIMsgMessageUrl,
Ci.msgIOverride,
Ci.nsISupports,
Ci.nsIInterfaceRequestor,
],
// We don't typically define this as a creatable component, but if we do use
// these. Subclasses for particular account types require these defined for
// that type.
contractID: "@mozilla.org/jsaccount/jaurl;1",
classID: Components.ID("{1E7B42CA-E6D9-408F-A4E4-8D2F82AECBBD}"),
};
function JaBaseUrl(aDelegator, aBaseInterfaces) {
// Typical boilerplate to include in all implementations.
// Object delegating method calls to the appropriate XPCOM object.
// Weak because it owns us.
this._delegatorWeak = Cu.getWeakReference(aDelegator);
// Base implementation of methods with no overrides.
this.cppBase = aDelegator.cppBase;
// cppBase class sees all interfaces
aBaseInterfaces.forEach(iface => this.cppBase instanceof iface);
}
JaBaseUrl.prototype = {
// Typical boilerplate to include in all implementations.
__proto__: JSAccountUtils.makeCppDelegator(JaBaseUrlProperties),
// Flag this item as CPP needs to delegate to JS.
_JsPrototypeToDelegate: true,
// QI to the interfaces.
QueryInterface: XPCOMUtils.generateQI(JaBaseUrlProperties.baseInterfaces),
// Used to access an instance as JS, bypassing XPCOM.
get wrappedJSObject() {
return this;
},
// Accessor to the weak cpp delegator.
get delegator() {
return this._delegatorWeak.get();
},
// Dynamically-generated list of delegate methods.
delegateList: null,
// Implementation in JS (if any) of methods in XPCOM interfaces.
};

View file

@ -0,0 +1,15 @@
# -*- Mode: python; c-basic-offset: 4; 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/.
DIRS += [
'public',
'src'
]
EXTRA_JS_MODULES.jsaccount += [
'modules/JaBaseUrl.jsm',
'modules/JSAccountUtils.jsm',
]

View file

@ -0,0 +1,17 @@
# -*- Mode: python; c-basic-offset: 4; 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 += [
'msgIDelegateList.idl',
'msgIOverride.idl',
]
EXPORTS += [
'msgJsAccountCID.h',
]
XPIDL_MODULE = 'msgjsaccount'

View file

@ -0,0 +1,19 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* 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"
/**
* This interface provides a list of methods that should be delegated to
* a JsObject rather than a C++ XPCOM base object in JsAccount classes.
*/
[scriptable, builtinclass, uuid(627D3A34-F8A3-40eb-91FE-E413D6638D27)]
interface msgIDelegateList : nsISupports
{
/// Method name to delegate to JavaScript.
void add(in string aMethod);
};

View file

@ -0,0 +1,42 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* 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 "msgIDelegateList.idl"
/**
* Mailnews code typically has a C++ base class for objects, which is then
* specialized for each account type with a C++ subclass of the base class.
*
* This interface provides the ability of JavaScript-based account
* implementations to use the same C++ base classes as core objects, but
* use JavaScript to override methods instead of C++.
*/
[scriptable, uuid(68075269-8BBD-4a09-AC04-3241BF44F633)]
interface msgIOverride : nsISupports
{
/**
*
* A list of methods in the C++ base class that will be delegated to the JS
* delegate. This is calculated once, and then a fixed value is set to
* all subsequent instances so that it does not need to be recalculated each
* time. If the value has not yet been set, this will return a new instance.
*/
attribute msgIDelegateList methodsToDelegate;
/**
* JavaScript-based xpcom object that overrides C++ methods.
*/
attribute nsISupports jsDelegate;
/**
* C++ class used to implement default functionality. This is used when
* JavaScript methods want to call the base class default action, bypassing a
* possible JS override.
*/
readonly attribute nsISupports cppBase;
};

View file

@ -0,0 +1,35 @@
/* -*- 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/. */
// Contains the definitions of contract IDs for modules in JsAccounts.
#ifndef _msgJsAccountCID_H_
#define _msgJsAccountCID_H_
#define JACPPURLDELEGATOR_CID \
{ 0x1a0b778c, 0x2fe6, 0x4012, { 0xb4, 0xf3, 0xe8, 0x1c, 0xc, 0x11, 0x64, 0x9 } }
#define JACPPURLDELEGATOR_CONTRACTID "@mozilla.org/jacppurldelegator;1"
#define JACPPABDIRECTORYDELEGATOR_CID \
{ 0x77b5592c, 0x5018, 0x436d, { 0xa4, 0x66, 0xc4, 0xe5, 0x44, 0x3a, 0x16, 0x69 } }
#define JACPPABDIRECTORYDELEGATOR_CONTRACTID "@mozilla.org/jacppabdirectorydelegator;1"
#define JACPPINCOMINGSERVERDELEGATOR_CID \
{ 0x7aa11dd3, 0x5590, 0x4e01, { 0xbd, 0x87, 0x91, 0xf6, 0x02, 0x72, 0xd0, 0x1a } }
#define JACPPINCOMINGSERVERDELEGATOR_CONTRACTID "@mozilla.org/jacppincomingserverdelegator;1"
#define JACPPCOMPOSEDELEGATOR_CID \
{ 0xcfcd1caa, 0x00d9, 0x40d0, { 0x83, 0x1e, 0x67, 0x38, 0x20, 0xe0, 0x4f, 0xc6 } }
#define JACPPCOMPOSEDELEGATOR_CONTRACTID "@mozilla.org/jacppcomposedelegator;1"
#define JACPPMSGFOLDERDELEGATOR_CID \
{ 0xd6bd81fa, 0xb1d4, 0x424a, { 0x88, 0xea, 0xbb, 0x3e, 0xa8, 0x38, 0x1d, 0x50 } }
#define JACPPMSGFOLDERDELEGATOR_CONTRACTID "@mozilla.org/jacppmsgfolderdelegator;1"
#define JACPPSENDDELEGATOR_CID \
{ 0x36fcb887, 0x2b04, 0x42d4, { 0x92, 0xc9, 0xae, 0xd2, 0xac, 0xa1, 0xd4, 0x5b } }
#define JACPPSENDDELEGATOR_CONTRACTID "@mozilla.org/jacppsenddelegator;1"
#endif

View file

@ -0,0 +1,56 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>JsAccount Usage and Architecture</title>
</head>
<body>
<h1>Overview</h1>
<p>JsAccount is a technology that allows message account types to be created
in Mozilla Mailnews code using JavaScript. Although this is primarily
targeted at allowing extensions to create new accounts, it might also be
useful as a bridge to convert existing account types from being C++ based
to JavaScript based.</p>
<h2>Existing C++-based architecture of mailnews accounts</h2>
<p>In mailnews code, an account type is a set of classes that allow
implementation of a messaging particular protocol. The account type is
given a short string identifier ("imap", "news", "pop3") and is then used
to create objects of the appropriate type by appending that string to the
end of a base XPCOM contractID. So, for example, to create an imap server,
you generate a contractID using a base ID,
NS_MSGINCOMINGSERVER_CONTRACTID_PREFIX
"@mozilla.org/messenger/server;1?type=", then append "imap" to get:</p>
<p>@mozilla.org/messenger/server;1?type=imap</p>
<p>In the C++ code, there is a base object implementing shared
functionality. An account-specific class inherits that base functionality,
then extends it to represent the account-specific behavior that is needed.
This same basic concept is used to represent a whole series of classes
that are necessary to implement a specific mailnews account type.</p>
<p>For the server example, there is a base class named
nsMsgIncomingServer.cpp that implements that base interface
nsIMsgIncomingServer.idl. For imap, there is a specific class
nsImapIncomingServer.cpp that inherits from nsMsgIncomingServer.cpp,
overrides some of the methods in nsIMsgIncomingServer.idl, and also
implements an imap-specific interface nsIImapIncomingServer.idl. All of
this works fine using C++ inheritance and polymorphism.</p>
<p>Although JsAccount is intended mostly for mailnews accounts, the same
basic method of using a base class extended for specific types is also used
in other ways in mailnews code, including for addressbook types and views.
The technology may also be applied to those other object types as well.</p>
<h2>Role of JsAccount</h2>
<p>The JavaScript class system works very differently than the C++ system,
and you cannot use normal language constructs to override a C++ class with
a JavaScript class. What JsAccount allows you to do is to create XPCOM
objects in JavaScript, and use those objects to override or extend the
methods from the C++ base class in a way that will function correctly
whether those objects are executed from within C++ code or JavaScript
code. This allows you to create a new account using JavaScript code, while
using the same base class functionality that is used by the core C++
account types. Thus a new account type may be created in JavaScript-based
extension. The technology may also be used to create JavaScript
versions of existing account types in an incremental manner, slowly
converting methods from C++ to JavaScript.</p>
<p><br>
</p>
</body>
</html>

View file

@ -0,0 +1,33 @@
/* -*- 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 "DelegateList.h"
// This class is used within JsAccount to allow static storage of a list
// of methods to be overridden by JS implementations, in a way that can
// be stored and manipulated in JS, but used efficiently in C++.
namespace mozilla {
namespace mailnews {
NS_IMPL_ISUPPORTS(DelegateList, msgIDelegateList)
NS_IMETHODIMP DelegateList::Add(const char *aMethodName)
{
// __FUNCTION__ is the undecorated function name in gcc, but decorated in
// Windows. __func__ will resolve this when supported in VS 2015.
nsCString prettyFunction;
#if defined (_MSC_VER)
prettyFunction.Append(mPrefix);
#endif
prettyFunction.Append(nsDependentCString(aMethodName));
mMethods.Put(prettyFunction, true);
return NS_OK;
}
} // namespace mailnews
} // namespace mozilla

View file

@ -0,0 +1,52 @@
/* -*- 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 _DelegateList_H_
#define _DelegateList_H_
#include "nsISupports.h"
#include "msgIDelegateList.h"
#include "nsDataHashtable.h"
namespace mozilla {
namespace mailnews {
// This class provides a list of method names to delegate to another object.
class DelegateList : public msgIDelegateList
{
public:
NS_DECL_ISUPPORTS
NS_DECL_MSGIDELEGATELIST
DelegateList(const char *aWindowsPrefix) :
mPrefix(aWindowsPrefix)
{ }
nsDataHashtable<nsCStringHashKey, bool> mMethods;
protected:
virtual ~DelegateList() { }
nsCString mPrefix; // Windows decorated method prefix.
};
} // namespace mailnews
} // namespace mozilla
/*
* This macro is used in forwarding functions.
* _interface: the interface being forwarded.
* _jsdelegate: the name of the JS pointer that implements a particular
* interface.
*
* You must follow the naming convention:
* 1) use mCppBase as the name of the C++ base class instance.
* 2) use mMethod as the name of the DelegateList object.
**/
#define DELEGATE_JS(_interface, _jsdelegate) (\
_jsdelegate && mMethods && \
mMethods->Contains(nsLiteralCString(__FUNCTION__)) ? \
_jsdelegate : nsCOMPtr<_interface>(do_QueryInterface(mCppBase)))
#endif

View file

@ -0,0 +1,98 @@
/* -*- 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 "JaAbDirectory.h"
#include "nsISupportsUtils.h"
#include "nsIFile.h"
#include "nsIMsgHdr.h"
#include "nsIMessenger.h"
#include "nsMsgBaseCID.h"
#include "nsComponentManagerUtils.h"
namespace mozilla {
namespace mailnews {
NS_IMPL_ISUPPORTS_INHERITED(JaBaseCppAbDirectory, nsAbDirProperty,
nsIInterfaceRequestor)
// nsIInterfaceRequestor implementation
NS_IMETHODIMP JaBaseCppAbDirectory::GetInterface(const nsIID & aIID, void **aSink)
{
return QueryInterface(aIID, aSink);
}
// Delegator
NS_IMPL_ISUPPORTS_INHERITED(JaCppAbDirectoryDelegator,
JaBaseCppAbDirectory,
msgIOverride)
// Delegator object to bypass JS method override.
NS_IMPL_ISUPPORTS(JaCppAbDirectoryDelegator::Super,
nsIAbDirectory,
nsIAbCollection,
nsIAbItem,
nsIInterfaceRequestor)
JaCppAbDirectoryDelegator::JaCppAbDirectoryDelegator() :
mCppBase(new Super(this)),
mMethods(nullptr)
{ }
NS_IMETHODIMP JaCppAbDirectoryDelegator::SetMethodsToDelegate(msgIDelegateList* aDelegateList)
{
if (!aDelegateList)
{
NS_WARNING("Null delegate list");
return NS_ERROR_NULL_POINTER;
}
// We static_cast since we want to use the hash object directly.
mDelegateList = static_cast<DelegateList*> (aDelegateList);
mMethods = &(mDelegateList->mMethods);
return NS_OK;
}
NS_IMETHODIMP JaCppAbDirectoryDelegator::GetMethodsToDelegate(msgIDelegateList** aDelegateList)
{
if (!mDelegateList)
mDelegateList = new DelegateList("mozilla::mailnews::JaCppAbDirectoryDelegator::");
mMethods = &(mDelegateList->mMethods);
NS_ADDREF(*aDelegateList = mDelegateList);
return NS_OK;
}
NS_IMETHODIMP JaCppAbDirectoryDelegator::SetJsDelegate(nsISupports* aJsDelegate)
{
// If these QIs fail, then overrides are not provided for methods in that
// interface, which is OK.
mJsISupports = aJsDelegate;
mJsIAbDirectory = do_QueryInterface(aJsDelegate);
mJsIAbCollection = do_QueryInterface(aJsDelegate);
mJsIAbItem = do_QueryInterface(aJsDelegate);
mJsIInterfaceRequestor = do_QueryInterface(aJsDelegate);
return NS_OK;
}
NS_IMETHODIMP JaCppAbDirectoryDelegator::GetJsDelegate(nsISupports **aJsDelegate)
{
NS_ENSURE_ARG_POINTER(aJsDelegate);
if (mJsISupports)
{
NS_ADDREF(*aJsDelegate = mJsISupports);
return NS_OK;
}
return NS_ERROR_NOT_INITIALIZED;
}
NS_IMETHODIMP JaCppAbDirectoryDelegator::GetCppBase(nsISupports** aCppBase)
{
nsCOMPtr<nsISupports> cppBaseSupports;
cppBaseSupports = NS_ISUPPORTS_CAST(nsIAbDirectory*, mCppBase);
NS_ENSURE_STATE(cppBaseSupports);
cppBaseSupports.forget(aCppBase);
return NS_OK;
}
} // namespace mailnews
} // namespace mozilla

View file

@ -0,0 +1,89 @@
/* -*- 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 _JaAbDirectory_H_
#define _JaAbDirectory_H_
#include "DelegateList.h"
#include "msgIOverride.h"
#include "nsAbDirProperty.h"
#include "nsAutoPtr.h"
#include "nsDataHashtable.h"
#include "nsIInterfaceRequestor.h"
namespace mozilla {
namespace mailnews {
/* Header file */
// This class is an XPCOM component, usable in JS, that calls the methods
// in the C++ base class (bypassing any JS override).
class JaBaseCppAbDirectory : public nsAbDirProperty,
public nsIInterfaceRequestor
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIINTERFACEREQUESTOR
JaBaseCppAbDirectory() { }
protected:
virtual ~JaBaseCppAbDirectory() { }
};
class JaCppAbDirectoryDelegator : public JaBaseCppAbDirectory,
public msgIOverride
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_MSGIOVERRIDE
NS_FORWARD_NSIABDIRECTORY(DELEGATE_JS(nsIAbDirectory, mJsIAbDirectory)->)
NS_FORWARD_NSIABCOLLECTION(DELEGATE_JS(nsIAbCollection, mJsIAbCollection)->)
NS_FORWARD_NSIABITEM(DELEGATE_JS(nsIAbItem, mJsIAbItem)->)
NS_FORWARD_NSIINTERFACEREQUESTOR(DELEGATE_JS(nsIInterfaceRequestor, mJsIInterfaceRequestor)->)
JaCppAbDirectoryDelegator();
private:
virtual ~JaCppAbDirectoryDelegator() {
}
class Super : public nsIAbDirectory,
public nsIInterfaceRequestor
{
public:
Super(JaCppAbDirectoryDelegator* aFakeThis) {mFakeThis = aFakeThis;}
NS_DECL_ISUPPORTS
NS_FORWARD_NSIABDIRECTORY(mFakeThis->JaBaseCppAbDirectory::)
NS_FORWARD_NSIABCOLLECTION(mFakeThis->JaBaseCppAbDirectory::)
NS_FORWARD_NSIABITEM(mFakeThis->JaBaseCppAbDirectory::)
NS_FORWARD_NSIINTERFACEREQUESTOR(mFakeThis->JaBaseCppAbDirectory::)
private:
virtual ~Super() {}
JaCppAbDirectoryDelegator* mFakeThis;
};
// Interfaces that may be overridden by JS.
nsCOMPtr<nsIAbDirectory> mJsIAbDirectory;
nsCOMPtr<nsIAbCollection> mJsIAbCollection;
nsCOMPtr<nsIAbItem> mJsIAbItem;
nsCOMPtr<nsIInterfaceRequestor> mJsIInterfaceRequestor;
nsCOMPtr<nsISupports> mJsISupports;
// Class to bypass JS delegates. nsCOMPtr for when we do cycle collection.
nsCOMPtr<nsIAbDirectory> mCppBase;
RefPtr<DelegateList> mDelegateList;
nsDataHashtable<nsCStringHashKey, bool>* mMethods;
};
} // namespace mailnews
} // namespace mozilla
#endif

View file

@ -0,0 +1,103 @@
/* -*- 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 "JaCompose.h"
#include "nsISupportsUtils.h"
#include "nsComponentManagerUtils.h"
// This file specifies the implementation of nsIMsgCompose.idl objects
// in the JsAccount system.
namespace mozilla {
namespace mailnews {
NS_IMPL_ISUPPORTS_INHERITED(JaBaseCppCompose,
nsMsgCompose,
nsIInterfaceRequestor)
// nsIInterfaceRequestor implementation
NS_IMETHODIMP
JaBaseCppCompose::GetInterface(const nsIID & aIID, void **aSink)
{
return QueryInterface(aIID, aSink);
}
// Delegator object to bypass JS method override.
JaCppComposeDelegator::JaCppComposeDelegator() {
mCppBase = do_QueryInterface(
NS_ISUPPORTS_CAST(nsIMsgCompose*, new Super(this)));
mMethods = nullptr;
}
NS_IMPL_ISUPPORTS_INHERITED(JaCppComposeDelegator,
JaBaseCppCompose,
msgIOverride)
NS_IMPL_ISUPPORTS(JaCppComposeDelegator::Super,
nsIMsgCompose,
nsIMsgSendListener,
nsIInterfaceRequestor)
NS_IMETHODIMP
JaCppComposeDelegator::SetMethodsToDelegate(msgIDelegateList* aDelegateList)
{
if (!aDelegateList)
{
NS_WARNING("Null delegate list");
return NS_ERROR_NULL_POINTER;
}
// We static_cast since we want to use the hash object directly.
mDelegateList = static_cast<DelegateList*> (aDelegateList);
mMethods = &(mDelegateList->mMethods);
return NS_OK;
}
NS_IMETHODIMP
JaCppComposeDelegator::GetMethodsToDelegate(msgIDelegateList** aDelegateList)
{
if (!mDelegateList)
mDelegateList = new DelegateList("mozilla::mailnews::JaCppComposeDelegator::");
mMethods = &(mDelegateList->mMethods);
NS_ADDREF(*aDelegateList = mDelegateList);
return NS_OK;
}
NS_IMETHODIMP
JaCppComposeDelegator::SetJsDelegate(nsISupports* aJsDelegate)
{
// If these QIs fail, then overrides are not provided for methods in that
// interface, which is OK.
mJsISupports = aJsDelegate;
mJsIMsgCompose = do_QueryInterface(aJsDelegate);
mJsIMsgSendListener = do_QueryInterface(aJsDelegate);
mJsIInterfaceRequestor = do_QueryInterface(aJsDelegate);
return NS_OK;
}
NS_IMETHODIMP
JaCppComposeDelegator::GetJsDelegate(nsISupports **aJsDelegate)
{
NS_ENSURE_ARG_POINTER(aJsDelegate);
if (mJsISupports)
{
NS_ADDREF(*aJsDelegate = mJsISupports);
return NS_OK;
}
return NS_ERROR_NOT_INITIALIZED;
}
NS_IMETHODIMP
JaCppComposeDelegator::GetCppBase(nsISupports** aCppBase)
{
nsCOMPtr<nsISupports> cppBaseSupports;
cppBaseSupports = NS_ISUPPORTS_CAST(nsIMsgCompose*, mCppBase);
NS_ENSURE_STATE(cppBaseSupports);
cppBaseSupports.forget(aCppBase);
return NS_OK;
}
} // namespace mailnews
} // namespace mozilla

View file

@ -0,0 +1,92 @@
/* -*- 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 _JaCompose_H_
#define _JaCompose_H_
#include "DelegateList.h"
#include "msgIOverride.h"
#include "nsMsgCompose.h"
#include "nsAutoPtr.h"
#include "nsDataHashtable.h"
#include "nsIInterfaceRequestor.h"
// This file specifies the definition of nsIMsgCompose.idl objects
// in the JsAccount system.
namespace mozilla {
namespace mailnews {
/* Header file */
// This class is an XPCOM component, usable in JS, that calls the methods
// in the C++ base class (bypassing any JS override).
class JaBaseCppCompose : public nsMsgCompose,
public nsIInterfaceRequestor
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIINTERFACEREQUESTOR
JaBaseCppCompose() { }
protected:
virtual ~JaBaseCppCompose() { }
};
class JaCppComposeDelegator : public JaBaseCppCompose,
public msgIOverride
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_MSGIOVERRIDE
NS_FORWARD_NSIMSGCOMPOSE(DELEGATE_JS(nsIMsgCompose, mJsIMsgCompose)->)
NS_FORWARD_NSIMSGSENDLISTENER(DELEGATE_JS(nsIMsgSendListener, mJsIMsgSendListener)->)
NS_FORWARD_NSIINTERFACEREQUESTOR(DELEGATE_JS(nsIInterfaceRequestor, mJsIInterfaceRequestor)->)
JaCppComposeDelegator();
private:
virtual ~JaCppComposeDelegator() {
}
// This class will call a method on the delegator, but force the use of the
// C++ cppBase class, bypassing any JS Delegate.
class Super : public nsIMsgCompose,
public nsIInterfaceRequestor
{
public:
Super(JaCppComposeDelegator* aFakeThis) {mFakeThis = aFakeThis;}
NS_DECL_ISUPPORTS
// Forward all overridable methods, bypassing JS override.
NS_FORWARD_NSIMSGCOMPOSE(mFakeThis->JaBaseCppCompose::)
NS_FORWARD_NSIMSGSENDLISTENER(mFakeThis->JaBaseCppCompose::)
NS_FORWARD_NSIINTERFACEREQUESTOR(mFakeThis->JaBaseCppCompose::)
private:
virtual ~Super() {};
JaCppComposeDelegator* mFakeThis;
};
// Interfaces that may be overridden by JS.
nsCOMPtr<nsIMsgCompose> mJsIMsgCompose;
nsCOMPtr<nsIMsgSendListener> mJsIMsgSendListener;
nsCOMPtr<nsIInterfaceRequestor> mJsIInterfaceRequestor;
nsCOMPtr<nsISupports> mJsISupports;
// Class to bypass JS delegates.
nsCOMPtr<nsIMsgCompose> mCppBase;
RefPtr<DelegateList> mDelegateList;
nsDataHashtable<nsCStringHashKey, bool>* mMethods;
};
} // namespace mailnews
} // namespace mozilla
#endif

View file

@ -0,0 +1,109 @@
/* -*- 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 "JaIncomingServer.h"
#include "nsISupportsUtils.h"
#include "nsComponentManagerUtils.h"
// This file specifies the implementation of nsIMsgIncomingServer.idl objects
// in the JsAccount system.
namespace mozilla {
namespace mailnews {
NS_IMPL_ISUPPORTS_INHERITED(JaBaseCppIncomingServer,
nsMsgIncomingServer,
nsIInterfaceRequestor)
// nsMsgIncomingServer overrides
nsresult
JaBaseCppIncomingServer::CreateRootFolderFromUri(const nsCString &serverUri,
nsIMsgFolder **rootFolder)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
// nsIInterfaceRequestor implementation
NS_IMETHODIMP
JaBaseCppIncomingServer::GetInterface(const nsIID & aIID, void **aSink)
{
return QueryInterface(aIID, aSink);
}
// Delegator object to bypass JS method override.
JaCppIncomingServerDelegator::JaCppIncomingServerDelegator() {
mCppBase = do_QueryInterface(
NS_ISUPPORTS_CAST(nsIMsgIncomingServer*, new Super(this)));
mMethods = nullptr;
}
NS_IMPL_ISUPPORTS_INHERITED(JaCppIncomingServerDelegator,
JaBaseCppIncomingServer,
msgIOverride)
NS_IMPL_ISUPPORTS(JaCppIncomingServerDelegator::Super,
nsIMsgIncomingServer,
nsIInterfaceRequestor)
NS_IMETHODIMP
JaCppIncomingServerDelegator::SetMethodsToDelegate(msgIDelegateList* aDelegateList)
{
if (!aDelegateList)
{
NS_WARNING("Null delegate list");
return NS_ERROR_NULL_POINTER;
}
// We static_cast since we want to use the hash object directly.
mDelegateList = static_cast<DelegateList*> (aDelegateList);
mMethods = &(mDelegateList->mMethods);
return NS_OK;
}
NS_IMETHODIMP
JaCppIncomingServerDelegator::GetMethodsToDelegate(msgIDelegateList** aDelegateList)
{
if (!mDelegateList)
mDelegateList = new DelegateList("mozilla::mailnews::JaCppIncomingServerDelegator::");
mMethods = &(mDelegateList->mMethods);
NS_ADDREF(*aDelegateList = mDelegateList);
return NS_OK;
}
NS_IMETHODIMP
JaCppIncomingServerDelegator::SetJsDelegate(nsISupports* aJsDelegate)
{
// If these QIs fail, then overrides are not provided for methods in that
// interface, which is OK.
mJsISupports = aJsDelegate;
mJsIMsgIncomingServer = do_QueryInterface(aJsDelegate);
mJsIInterfaceRequestor = do_QueryInterface(aJsDelegate);
return NS_OK;
}
NS_IMETHODIMP
JaCppIncomingServerDelegator::GetJsDelegate(nsISupports **aJsDelegate)
{
NS_ENSURE_ARG_POINTER(aJsDelegate);
if (mJsISupports)
{
NS_ADDREF(*aJsDelegate = mJsISupports);
return NS_OK;
}
return NS_ERROR_NOT_INITIALIZED;
}
NS_IMETHODIMP
JaCppIncomingServerDelegator::GetCppBase(nsISupports** aCppBase)
{
nsCOMPtr<nsISupports> cppBaseSupports;
cppBaseSupports = NS_ISUPPORTS_CAST(nsIMsgIncomingServer*, mCppBase);
NS_ENSURE_STATE(cppBaseSupports);
cppBaseSupports.forget(aCppBase);
return NS_OK;
}
} // namespace mailnews
} // namespace mozilla

View file

@ -0,0 +1,94 @@
/* -*- 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 _JaIncomingServer_H_
#define _JaIncomingServer_H_
#include "DelegateList.h"
#include "msgIOverride.h"
#include "nsMsgIncomingServer.h"
#include "nsAutoPtr.h"
#include "nsDataHashtable.h"
#include "nsIInterfaceRequestor.h"
// This file specifies the definition of nsIMsgIncomingServer.idl objects
// in the JsAccount system.
namespace mozilla {
namespace mailnews {
/* Header file */
// This class is an XPCOM component, usable in JS, that calls the methods
// in the C++ base class (bypassing any JS override).
class JaBaseCppIncomingServer : public nsMsgIncomingServer,
public nsIInterfaceRequestor
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIINTERFACEREQUESTOR
JaBaseCppIncomingServer() { }
// nsMsgIncomingServer overrides
nsresult CreateRootFolderFromUri(const nsCString &serverUri,
nsIMsgFolder **rootFolder) override;
protected:
virtual ~JaBaseCppIncomingServer() { }
};
class JaCppIncomingServerDelegator : public JaBaseCppIncomingServer,
public msgIOverride
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_MSGIOVERRIDE
NS_FORWARD_NSIMSGINCOMINGSERVER(DELEGATE_JS(nsIMsgIncomingServer, mJsIMsgIncomingServer)->)
NS_FORWARD_NSIINTERFACEREQUESTOR(DELEGATE_JS(nsIInterfaceRequestor, mJsIInterfaceRequestor)->)
JaCppIncomingServerDelegator();
private:
virtual ~JaCppIncomingServerDelegator() {
}
// This class will call a method on the delegator, but force the use of the
// C++ parent class, bypassing any JS Delegate.
class Super : public nsIMsgIncomingServer,
public nsIInterfaceRequestor
{
public:
Super(JaCppIncomingServerDelegator* aFakeThis) {mFakeThis = aFakeThis;}
NS_DECL_ISUPPORTS
// Forward all overridable methods, bypassing JS override.
NS_FORWARD_NSIMSGINCOMINGSERVER(mFakeThis->JaBaseCppIncomingServer::)
NS_FORWARD_NSIINTERFACEREQUESTOR(mFakeThis->JaBaseCppIncomingServer::)
private:
virtual ~Super() {};
JaCppIncomingServerDelegator* mFakeThis;
};
// Interfaces that may be overridden by JS.
nsCOMPtr<nsIMsgIncomingServer> mJsIMsgIncomingServer;
nsCOMPtr<nsIInterfaceRequestor> mJsIInterfaceRequestor;
nsCOMPtr<nsISupports> mJsISupports;
// Class to bypass JS delegates.
nsCOMPtr<nsIMsgIncomingServer> mCppBase;
RefPtr<DelegateList> mDelegateList;
nsDataHashtable<nsCStringHashKey, bool>* mMethods;
};
} // namespace mailnews
} // namespace mozilla
#endif

View file

@ -0,0 +1,207 @@
/* -*- 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 "JaMsgFolder.h"
#include "nsISupportsUtils.h"
#include "nsMsgBaseCID.h"
#include "nsComponentManagerUtils.h"
#include "nsIUUIDGenerator.h"
#include "nsIComponentRegistrar.h"
#include "nsMsgDBCID.h"
#define MAILDATABASE_CONTRACTID_BASE "@mozilla.org/nsMsgDatabase/msgDB-"
namespace mozilla {
namespace mailnews {
NS_IMPL_ISUPPORTS_INHERITED(JaBaseCppMsgFolder, nsMsgDBFolder,
nsIInterfaceRequestor)
// nsIInterfaceRequestor implementation
NS_IMETHODIMP
JaBaseCppMsgFolder::GetInterface(const nsIID & aIID, void **aSink)
{
return QueryInterface(aIID, aSink);
}
// Definition of abstract nsMsgDBFolder methods.
nsresult
JaBaseCppMsgFolder::GetDatabase()
{
nsresult rv = NS_OK;
if (!mDatabase)
{
nsCOMPtr<nsIMsgDBService> msgDBService = do_GetService(NS_MSGDB_SERVICE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
// Create the database, keeping it if it is "out of date"
rv = msgDBService->OpenFolderDB(this, true, getter_AddRefs(mDatabase));
if (rv == NS_MSG_ERROR_FOLDER_SUMMARY_MISSING)
{
rv = msgDBService->CreateNewDB(this, getter_AddRefs(mDatabase));
NS_ENSURE_STATE(mDatabase);
// not sure about this ... the issue is that if the summary is not valid, then
// the db does not get added to the cache in the future, and reindexes
// do not show all of the messages.
//mDatabase->SetSummaryValid(true);
mDatabase->SetSummaryValid(false);
CreateDummyFile(this);
}
if (rv != NS_MSG_ERROR_FOLDER_SUMMARY_OUT_OF_DATE)
NS_ENSURE_SUCCESS(rv, rv);
else if (mDatabase)
{
// Not going to warn here, because on initialization we set all
// databases as invalid.
//NS_WARNING("Mail Summary database is out of date");
// Grrr, the only way to get this into the cache is to set the db as valid,
// close, reopen, then set as invalid.
mDatabase->SetSummaryValid(true);
msgDBService->ForceFolderDBClosed(this);
rv = msgDBService->OpenFolderDB(this, true, getter_AddRefs(mDatabase));
if (mDatabase)
mDatabase->SetSummaryValid(false);
}
if (mDatabase)
{
//
// When I inadvertently deleted the out-of-date database, I hit this code with
// the db's m_dbFolderInfo as null from the delete, yet the local mDatabase
// reference kept the database alive. So I hit an assert when I tried to open
// the database. Be careful if you try to fix the out-of-date issues!
//
//UpdateNewMessages();
if(mAddListener)
mDatabase->AddListener(this);
// UpdateSummaryTotals can null mDatabase during initialization, so we save a local copy
nsCOMPtr<nsIMsgDatabase> database(mDatabase);
UpdateSummaryTotals(true);
mDatabase = database;
}
}
return rv;
}
/*
* The utility function GetSummaryFileLocation takes a folder file,
* then appends .msf to come up with the name of the database file. So
* we need a placeholder file with simply the folder name. This method
* creates an appropriate file as a placeholder, or you may use the file if
* appropriate.
*/
nsresult
JaBaseCppMsgFolder::CreateDummyFile(nsIMsgFolder* aMailFolder)
{
nsresult rv;
if (!aMailFolder)
return NS_OK;
nsCOMPtr <nsIFile> path;
// need to make sure folder exists...
aMailFolder->GetFilePath(getter_AddRefs(path));
if (path)
{
bool exists;
rv = path->Exists(&exists);
if (!exists)
{
rv = path->Create(nsIFile::NORMAL_FILE_TYPE, 0644);
NS_ENSURE_SUCCESS(rv, rv);
}
}
return NS_OK;
}
// AFAICT this is unused in mailnews code.
nsresult
JaBaseCppMsgFolder::CreateChildFromURI(const nsCString &uri, nsIMsgFolder **folder)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
// Delegator object to bypass JS method override.
JaCppMsgFolderDelegator::JaCppMsgFolderDelegator() :
mCppBase(new Super(this)),
mMethods(nullptr)
{ }
NS_IMPL_ISUPPORTS_INHERITED(JaCppMsgFolderDelegator, JaBaseCppMsgFolder,
msgIOverride)
NS_IMPL_ISUPPORTS(JaCppMsgFolderDelegator::Super,
nsIMsgFolder,
nsIRDFResource,
nsIRDFNode,
nsIDBChangeListener,
nsIUrlListener,
nsIJunkMailClassificationListener,
nsIMsgTraitClassificationListener,
nsIInterfaceRequestor)
NS_IMETHODIMP
JaCppMsgFolderDelegator::SetMethodsToDelegate(msgIDelegateList* aDelegateList)
{
if (!aDelegateList)
{
NS_WARNING("Null delegate list");
return NS_ERROR_NULL_POINTER;
}
// We static_cast since we want to use the hash object directly.
mDelegateList = static_cast<DelegateList*> (aDelegateList);
mMethods = &(mDelegateList->mMethods);
return NS_OK;
}
NS_IMETHODIMP
JaCppMsgFolderDelegator::GetMethodsToDelegate(msgIDelegateList** aDelegateList)
{
if (!mDelegateList)
mDelegateList = new DelegateList("mozilla::mailnews::JaCppMsgFolderDelegator::");
mMethods = &(mDelegateList->mMethods);
NS_ADDREF(*aDelegateList = mDelegateList);
return NS_OK;
}
NS_IMETHODIMP JaCppMsgFolderDelegator::SetJsDelegate(nsISupports* aJsDelegate)
{
// If these QIs fail, then overrides are not provided for methods in that
// interface, which is OK.
mJsISupports = aJsDelegate;
mJsIMsgFolder = do_QueryInterface(aJsDelegate);
mJsIDBChangeListener = do_QueryInterface(aJsDelegate);
mJsIUrlListener = do_QueryInterface(aJsDelegate);
mJsIJunkMailClassificationListener = do_QueryInterface(aJsDelegate);
mJsIMsgTraitClassificationListener = do_QueryInterface(aJsDelegate);
mJsIInterfaceRequestor = do_QueryInterface(aJsDelegate);
return NS_OK;
}
NS_IMETHODIMP JaCppMsgFolderDelegator::GetJsDelegate(nsISupports **aJsDelegate)
{
NS_ENSURE_ARG_POINTER(aJsDelegate);
if (mJsISupports)
{
NS_ADDREF(*aJsDelegate = mJsISupports);
return NS_OK;
}
return NS_ERROR_NOT_INITIALIZED;
}
NS_IMETHODIMP JaCppMsgFolderDelegator::GetCppBase(nsISupports** aCppBase)
{
nsCOMPtr<nsISupports> cppBaseSupports;
cppBaseSupports = NS_ISUPPORTS_CAST(nsIMsgFolder*, mCppBase);
NS_ENSURE_STATE(cppBaseSupports);
cppBaseSupports.forget(aCppBase);
return NS_OK;
}
} // namespace mailnews
} // namespace mozilla

View file

@ -0,0 +1,126 @@
/* -*- 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 _JaMsgFolder_H_
#define _JaMsgFolder_H_
#include "DelegateList.h"
#include "msgIOverride.h"
#include "nsMsgDBFolder.h"
#include "nsAutoPtr.h"
#include "nsCycleCollectionParticipant.h"
#include "nsDataHashtable.h"
#include "nsIInterfaceRequestor.h"
#include "nsWeakReference.h"
#include "nsNetUtil.h"
namespace mozilla {
namespace mailnews {
/* Header file */
// This class is an XPCOM component, usable in JS, that calls the methods
// in the C++ base class (bypassing any JS override).
class JaBaseCppMsgFolder : public nsMsgDBFolder,
public nsIInterfaceRequestor
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIINTERFACEREQUESTOR
JaBaseCppMsgFolder() { }
// nsMsgDBFolder overrides
nsresult CreateChildFromURI(const nsCString &uri, nsIMsgFolder **folder) override;
nsresult GetDatabase() override;
// Local Utility Functions
// Create a placeholder file to represent a folder.
nsresult CreateDummyFile(nsIMsgFolder* aMailFolder);
protected:
virtual ~JaBaseCppMsgFolder() { }
};
class JaCppMsgFolderDelegator : public JaBaseCppMsgFolder,
public msgIOverride
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_MSGIOVERRIDE
// Note that we do not support override of RDF methods.
NS_FORWARD_NSIRDFRESOURCE(JaBaseCppMsgFolder::)
NS_FORWARD_NSIRDFNODE(JaBaseCppMsgFolder::)
NS_FORWARD_NSIMSGFOLDER(DELEGATE_JS(nsIMsgFolder, mJsIMsgFolder)->)
NS_FORWARD_NSIDBCHANGELISTENER(
DELEGATE_JS(nsIDBChangeListener, mJsIDBChangeListener)->)
NS_FORWARD_NSIURLLISTENER(DELEGATE_JS(nsIUrlListener, mJsIUrlListener)->)
NS_FORWARD_NSIJUNKMAILCLASSIFICATIONLISTENER(
DELEGATE_JS(nsIJunkMailClassificationListener,
mJsIJunkMailClassificationListener)->)
NS_FORWARD_NSIMSGTRAITCLASSIFICATIONLISTENER(
DELEGATE_JS(nsIMsgTraitClassificationListener,
mJsIMsgTraitClassificationListener)->)
NS_FORWARD_NSIINTERFACEREQUESTOR(
DELEGATE_JS(nsIInterfaceRequestor, mJsIInterfaceRequestor)->)
JaCppMsgFolderDelegator();
private:
virtual ~JaCppMsgFolderDelegator() {
}
class Super : public nsIMsgFolder,
public nsIRDFResource,
public nsIDBChangeListener,
public nsIUrlListener,
public nsIJunkMailClassificationListener,
public nsIMsgTraitClassificationListener,
public nsIInterfaceRequestor
{
public:
// Why fake this? Because this method is fully owned by
// JaCppMsgFolderDelegator, and this reference is to the "this" of the
// main method. But it is not really the local "this".
Super(JaCppMsgFolderDelegator* aFakeThis) {mFakeThis = aFakeThis;}
NS_DECL_ISUPPORTS
NS_FORWARD_NSIMSGFOLDER(mFakeThis->JaBaseCppMsgFolder::)
NS_FORWARD_NSIRDFRESOURCE(mFakeThis->JaBaseCppMsgFolder::)
NS_FORWARD_NSIRDFNODE(mFakeThis->JaBaseCppMsgFolder::)
NS_FORWARD_NSIDBCHANGELISTENER(mFakeThis->JaBaseCppMsgFolder::)
NS_FORWARD_NSIURLLISTENER(mFakeThis->JaBaseCppMsgFolder::)
NS_FORWARD_NSIJUNKMAILCLASSIFICATIONLISTENER(mFakeThis->JaBaseCppMsgFolder::)
NS_FORWARD_NSIMSGTRAITCLASSIFICATIONLISTENER(mFakeThis->JaBaseCppMsgFolder::)
NS_FORWARD_NSIINTERFACEREQUESTOR(mFakeThis->JaBaseCppMsgFolder::)
private:
virtual ~Super() {}
JaCppMsgFolderDelegator* mFakeThis;
};
// Interfaces that may be overridden by JS.
nsCOMPtr<nsIMsgFolder> mJsIMsgFolder;
nsCOMPtr<nsIDBChangeListener> mJsIDBChangeListener;
nsCOMPtr<nsIUrlListener> mJsIUrlListener;
nsCOMPtr<nsIJunkMailClassificationListener> mJsIJunkMailClassificationListener;
nsCOMPtr<nsIMsgTraitClassificationListener> mJsIMsgTraitClassificationListener;
nsCOMPtr<nsIInterfaceRequestor> mJsIInterfaceRequestor;
nsCOMPtr<nsISupports> mJsISupports;
nsCOMPtr<nsIMsgFolder> mCppBase;
RefPtr<DelegateList> mDelegateList;
nsDataHashtable<nsCStringHashKey, bool>* mMethods;
};
} // namespace mailnews
} // namespace mozilla
#endif

View file

@ -0,0 +1,102 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "JaSend.h"
#include "nsISupportsUtils.h"
#include "nsComponentManagerUtils.h"
// This file specifies the implementation of nsIMsgSend.idl objects
// in the JsAccount system.
namespace mozilla {
namespace mailnews {
NS_IMPL_ISUPPORTS_INHERITED(JaBaseCppSend,
nsMsgComposeAndSend,
nsIInterfaceRequestor)
// nsIInterfaceRequestor implementation
NS_IMETHODIMP
JaBaseCppSend::GetInterface(const nsIID & aIID, void **aSink)
{
return QueryInterface(aIID, aSink);
}
// Delegator object to bypass JS method override.
JaCppSendDelegator::JaCppSendDelegator() {
mCppBase = do_QueryInterface(
NS_ISUPPORTS_CAST(nsIMsgSend*, new Super(this)));
mMethods = nullptr;
}
NS_IMPL_ISUPPORTS_INHERITED(JaCppSendDelegator,
JaBaseCppSend,
msgIOverride)
NS_IMPL_ISUPPORTS(JaCppSendDelegator::Super,
nsIMsgSend,
nsIMsgOperationListener,
nsIInterfaceRequestor)
NS_IMETHODIMP
JaCppSendDelegator::SetMethodsToDelegate(msgIDelegateList* aDelegateList)
{
if (!aDelegateList)
{
NS_WARNING("Null delegate list");
return NS_ERROR_NULL_POINTER;
}
// We static_cast since we want to use the hash object directly.
mDelegateList = static_cast<DelegateList*> (aDelegateList);
mMethods = &(mDelegateList->mMethods);
return NS_OK;
}
NS_IMETHODIMP
JaCppSendDelegator::GetMethodsToDelegate(msgIDelegateList** aDelegateList)
{
if (!mDelegateList)
mDelegateList = new DelegateList("mozilla::mailnews::JaCppSendDelegator::");
mMethods = &(mDelegateList->mMethods);
NS_ADDREF(*aDelegateList = mDelegateList);
return NS_OK;
}
NS_IMETHODIMP
JaCppSendDelegator::SetJsDelegate(nsISupports* aJsDelegate)
{
// If these QIs fail, then overrides are not provided for methods in that
// interface, which is OK.
mJsISupports = aJsDelegate;
mJsIMsgSend = do_QueryInterface(aJsDelegate);
mJsIInterfaceRequestor = do_QueryInterface(aJsDelegate);
return NS_OK;
}
NS_IMETHODIMP
JaCppSendDelegator::GetJsDelegate(nsISupports **aJsDelegate)
{
NS_ENSURE_ARG_POINTER(aJsDelegate);
if (mJsISupports)
{
NS_ADDREF(*aJsDelegate = mJsISupports);
return NS_OK;
}
return NS_ERROR_NOT_INITIALIZED;
}
NS_IMETHODIMP
JaCppSendDelegator::GetCppBase(nsISupports** aCppBase)
{
nsCOMPtr<nsISupports> cppBaseSupports;
cppBaseSupports = NS_ISUPPORTS_CAST(nsIMsgSend*, mCppBase);
NS_ENSURE_STATE(cppBaseSupports);
cppBaseSupports.forget(aCppBase);
return NS_OK;
}
} // namespace mailnews
} // namespace mozilla

View file

@ -0,0 +1,96 @@
/* -*- 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 _JaSend_H_
#define _JaSend_H_
#include "DelegateList.h"
#include "msgIOverride.h"
#include "nsMsgSend.h"
#include "nsAutoPtr.h"
#include "nsDataHashtable.h"
#include "nsIInterfaceRequestor.h"
// This file specifies the definition of nsIMsgSend.idl objects
// in the JsAccount system.
namespace mozilla {
namespace mailnews {
/* Header file */
// This class is an XPCOM component, usable in JS, that calls the methods
// in the C++ base class (bypassing any JS override).
class JaBaseCppSend : public nsMsgComposeAndSend,
public nsIInterfaceRequestor
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIINTERFACEREQUESTOR
JaBaseCppSend() { }
protected:
virtual ~JaBaseCppSend() { }
};
class JaCppSendDelegator : public JaBaseCppSend,
public msgIOverride
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_MSGIOVERRIDE
NS_FORWARD_NSIMSGSEND(DELEGATE_JS(nsIMsgSend, mJsIMsgSend)->)
NS_FORWARD_NSIMSGOPERATIONLISTENER(
DELEGATE_JS(nsIMsgOperationListener, mJsIMsgOperationListener)->)
NS_FORWARD_NSIINTERFACEREQUESTOR(
DELEGATE_JS(nsIInterfaceRequestor, mJsIInterfaceRequestor)->)
JaCppSendDelegator();
private:
virtual ~JaCppSendDelegator() {
}
// This class will call a method on the delegator, but force the use of the
// C++ parent class, bypassing any JS Delegate.
class Super : public nsIMsgSend,
public nsIMsgOperationListener,
public nsIInterfaceRequestor
{
public:
Super(JaCppSendDelegator* aFakeThis) {mFakeThis = aFakeThis;}
NS_DECL_ISUPPORTS
// Forward all overridable methods, bypassing JS override.
NS_FORWARD_NSIMSGSEND(mFakeThis->JaBaseCppSend::)
NS_FORWARD_NSIMSGOPERATIONLISTENER(mFakeThis->JaBaseCppSend::)
NS_FORWARD_NSIINTERFACEREQUESTOR(mFakeThis->JaBaseCppSend::)
private:
virtual ~Super() {};
JaCppSendDelegator* mFakeThis;
};
// Interfaces that may be overridden by JS.
nsCOMPtr<nsIMsgSend> mJsIMsgSend;
nsCOMPtr<nsIMsgOperationListener> mJsIMsgOperationListener;
nsCOMPtr<nsIInterfaceRequestor> mJsIInterfaceRequestor;
nsCOMPtr<nsISupports> mJsISupports;
// Class to bypass JS delegates.
nsCOMPtr<nsIMsgSend> mCppBase;
RefPtr<DelegateList> mDelegateList;
nsDataHashtable<nsCStringHashKey, bool>* mMethods;
};
} // namespace mailnews
} // namespace mozilla
#endif

View file

@ -0,0 +1,230 @@
/* -*- 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 "JaUrl.h"
#include "nsComponentManagerUtils.h"
#include "nsIFile.h"
#include "nsIMessenger.h"
#include "nsIMsgHdr.h"
#include "nsISupportsUtils.h"
#include "nsMsgBaseCID.h"
#include "nsMsgUtils.h"
// This file contains an implementation of mailnews URLs in JsAccount.
namespace mozilla {
namespace mailnews {
NS_IMPL_ISUPPORTS_INHERITED(JaBaseCppUrl, nsMsgMailNewsUrl,
nsIMsgMessageUrl,
nsIInterfaceRequestor,
nsISupportsWeakReference)
// nsIMsgMailNewsUrl overrides
NS_IMETHODIMP JaBaseCppUrl::GetFolder(nsIMsgFolder **aFolder)
{
NS_ENSURE_ARG_POINTER(aFolder);
NS_IF_ADDREF(*aFolder = mFolder);
return NS_OK;
}
NS_IMETHODIMP JaBaseCppUrl::SetFolder(nsIMsgFolder *aFolder)
{
mFolder = aFolder;
return NS_OK;
}
// nsIMsgMessageUrl implementation
NS_IMETHODIMP JaBaseCppUrl::GetUri(char **aUri)
{
if (!mUri.IsEmpty())
*aUri = ToNewCString(mUri);
else
return NS_ERROR_NOT_INITIALIZED;
return NS_OK;
}
NS_IMETHODIMP JaBaseCppUrl::SetUri(const char *aUri)
{
mUri = aUri;
return NS_OK;
}
NS_IMETHODIMP JaBaseCppUrl::GetMessageFile(nsIFile **aMessageFile)
{
NS_ENSURE_ARG_POINTER(aMessageFile);
NS_IF_ADDREF(*aMessageFile = mMessageFile);
return NS_OK;
}
NS_IMETHODIMP JaBaseCppUrl::SetMessageFile(nsIFile *aMessageFile)
{
mMessageFile = aMessageFile;
return NS_OK;
}
NS_IMETHODIMP JaBaseCppUrl::GetAddDummyEnvelope(bool *aAddDummyEnvelope)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP JaBaseCppUrl::SetAddDummyEnvelope(bool aAddDummyEnvelope)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP JaBaseCppUrl::GetCanonicalLineEnding(bool *aCanonicalLineEnding)
{
NS_ENSURE_ARG_POINTER(aCanonicalLineEnding);
*aCanonicalLineEnding = mCanonicalLineEnding;
return NS_OK;
}
NS_IMETHODIMP JaBaseCppUrl::SetCanonicalLineEnding(bool aCanonicalLineEnding)
{
mCanonicalLineEnding = aCanonicalLineEnding;
return NS_OK;
}
NS_IMETHODIMP JaBaseCppUrl::GetOriginalSpec(char **aOriginalSpec)
{
if (!aOriginalSpec || mOriginalSpec.IsEmpty())
return NS_ERROR_NULL_POINTER;
*aOriginalSpec = ToNewCString(mOriginalSpec);
return NS_OK;
}
NS_IMETHODIMP JaBaseCppUrl::SetOriginalSpec(const char *aOriginalSpec)
{
mOriginalSpec = aOriginalSpec;
return NS_OK;
}
NS_IMETHODIMP JaBaseCppUrl::GetPrincipalSpec(nsACString& aPrincipalSpec)
{
// URLs contain a lot of query parts. We want need a normalised form:
// scheme://server/folder?number=123
nsCOMPtr<nsIMsgMailNewsUrl> mailnewsURL;
QueryInterface(NS_GET_IID(nsIMsgMailNewsUrl), getter_AddRefs(mailnewsURL));
nsAutoCString spec;
mailnewsURL->GetSpecIgnoringRef(spec);
nsAutoCString queryPart = MsgExtractQueryPart(spec, "number=");
// Strip any query part beginning with ? or /;
int32_t ind = spec.Find("/;");
if (ind != kNotFound)
spec.SetLength(ind);
ind = spec.FindChar('?');
if (ind != kNotFound)
spec.SetLength(ind);
if (!queryPart.IsEmpty())
spec += NS_LITERAL_CSTRING("?") + queryPart;
aPrincipalSpec.Assign(spec);
return NS_OK;
}
NS_IMETHODIMP JaBaseCppUrl::GetMessageHeader(nsIMsgDBHdr **aMessageHeader)
{
// This routine does a lookup using messenger, assumming that the message URI
// has been set in mUri.
NS_ENSURE_TRUE(!mUri.IsEmpty(), NS_ERROR_NOT_INITIALIZED);
nsresult rv;
nsCOMPtr<nsIMessenger> messenger(do_CreateInstance(NS_MESSENGER_CONTRACTID, &rv));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIMsgDBHdr> msgHdr;
rv = messenger->MsgHdrFromURI(mUri, getter_AddRefs(msgHdr));
NS_ENSURE_SUCCESS(rv, rv);
msgHdr.forget(aMessageHeader);
return NS_OK;
}
NS_IMETHODIMP JaBaseCppUrl::SetMessageHeader(nsIMsgDBHdr *aMsgHdr)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
// nsIInterfaceRequestor implementation
NS_IMETHODIMP JaBaseCppUrl::GetInterface(const nsIID & aIID, void **aSink)
{
return QueryInterface(aIID, aSink);
}
// Delegator
NS_IMPL_ISUPPORTS_INHERITED(JaCppUrlDelegator,
JaBaseCppUrl,
msgIOverride)
// Delegator object to bypass JS method override.
NS_IMPL_ISUPPORTS(JaCppUrlDelegator::Super,
nsIMsgMailNewsUrl,
nsIMsgMessageUrl,
nsIURI,
nsIURIWithQuery,
nsIURL,
nsIInterfaceRequestor)
JaCppUrlDelegator::JaCppUrlDelegator() :
mCppBase(new Super(this)),
mMethods(nullptr)
{ }
NS_IMETHODIMP JaCppUrlDelegator::SetMethodsToDelegate(msgIDelegateList *aDelegateList)
{
if (!aDelegateList)
{
NS_WARNING("Null delegate list");
return NS_ERROR_NULL_POINTER;
}
// We static_cast since we want to use the hash object directly.
mDelegateList = static_cast<DelegateList*> (aDelegateList);
mMethods = &(mDelegateList->mMethods);
return NS_OK;
}
NS_IMETHODIMP JaCppUrlDelegator::GetMethodsToDelegate(msgIDelegateList **aDelegateList)
{
if (!mDelegateList)
mDelegateList = new DelegateList("mozilla::mailnews::JaCppUrlDelegator::");
mMethods = &(mDelegateList->mMethods);
NS_ADDREF(*aDelegateList = mDelegateList);
return NS_OK;
}
NS_IMETHODIMP JaCppUrlDelegator::SetJsDelegate(nsISupports *aJsDelegate)
{
// If these QIs fail, then overrides are not provided for methods in that
// interface, which is OK.
mJsISupports = aJsDelegate;
mJsIMsgMailNewsUrl = do_QueryInterface(aJsDelegate);
mJsIURI = do_QueryInterface(aJsDelegate);
mJsIURIWithQuery = do_QueryInterface(aJsDelegate);
mJsIURL = do_QueryInterface(aJsDelegate);
mJsIMsgMessageUrl = do_QueryInterface(aJsDelegate);
mJsIInterfaceRequestor = do_QueryInterface(aJsDelegate);
return NS_OK;
}
NS_IMETHODIMP JaCppUrlDelegator::GetJsDelegate(nsISupports **aJsDelegate)
{
NS_ENSURE_ARG_POINTER(aJsDelegate);
if (mJsISupports)
{
NS_ADDREF(*aJsDelegate = mJsISupports);
return NS_OK;
}
return NS_ERROR_NOT_INITIALIZED;
}
NS_IMETHODIMP JaCppUrlDelegator::GetCppBase(nsISupports **aCppBase)
{
nsCOMPtr<nsISupports> cppBaseSupports;
cppBaseSupports = NS_ISUPPORTS_CAST(nsIMsgMailNewsUrl*, mCppBase);
NS_ENSURE_STATE(cppBaseSupports);
cppBaseSupports.forget(aCppBase);
return NS_OK;
}
} // namespace mailnews
} // namespace mozilla

View file

@ -0,0 +1,121 @@
/* -*- 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 _JaUrl_H_
#define _JaUrl_H_
#include "DelegateList.h"
#include "msgCore.h"
#include "msgIOverride.h"
#include "nsAutoPtr.h"
#include "nsCycleCollectionParticipant.h"
#include "nsDataHashtable.h"
#include "nsIFile.h"
#include "nsIInterfaceRequestor.h"
#include "nsIMsgFolder.h"
#include "nsISupports.h"
#include "nsMsgMailNewsUrl.h"
#include "nsWeakReference.h"
namespace mozilla {
namespace mailnews {
/* Header file */
// This class is an XPCOM component, usable in JS, that calls the methods
// in the C++ base class (bypassing any JS override).
class JaBaseCppUrl : public nsMsgMailNewsUrl,
public nsIMsgMessageUrl,
public nsIInterfaceRequestor,
public nsSupportsWeakReference
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIMSGMESSAGEURL
NS_DECL_NSIINTERFACEREQUESTOR
JaBaseCppUrl() { }
// nsIMsgMailNewsUrl overrides
NS_IMETHOD GetFolder(nsIMsgFolder **aFolder) override;
NS_IMETHOD SetFolder(nsIMsgFolder *aFolder) override;
protected:
virtual ~JaBaseCppUrl() { }
// nsIMsgMailUrl variables.
nsCOMPtr<nsIMsgFolder> mFolder;
// nsIMsgMessageUrl variables.
// the uri for the original message, like ews-message://server/folder#123
nsCString mUri;
nsCOMPtr<nsIFile> mMessageFile;
bool mCanonicalLineEnding;
nsCString mOriginalSpec;
};
class JaCppUrlDelegator : public JaBaseCppUrl,
public msgIOverride
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_MSGIOVERRIDE
NS_FORWARD_NSIMSGMAILNEWSURL(DELEGATE_JS(nsIMsgMailNewsUrl, mJsIMsgMailNewsUrl)->)
NS_FORWARD_NSIURI(DELEGATE_JS(nsIURI, mJsIURI)->)
NS_FORWARD_NSIURIWITHQUERY(DELEGATE_JS(nsIURIWithQuery, mJsIURIWithQuery)->)
NS_FORWARD_NSIURL(DELEGATE_JS(nsIURL, mJsIURL)->)
NS_FORWARD_NSIMSGMESSAGEURL(DELEGATE_JS(nsIMsgMessageUrl, mJsIMsgMessageUrl)->)
NS_FORWARD_NSIINTERFACEREQUESTOR(DELEGATE_JS(nsIInterfaceRequestor, mJsIInterfaceRequestor)->)
JaCppUrlDelegator();
class Super : public nsIMsgMailNewsUrl,
public nsIMsgMessageUrl,
public nsIInterfaceRequestor
{
public:
Super(JaCppUrlDelegator *aFakeThis) {mFakeThis = aFakeThis;}
NS_DECL_ISUPPORTS
NS_FORWARD_NSIMSGMAILNEWSURL(mFakeThis->JaBaseCppUrl::)
NS_FORWARD_NSIURI(mFakeThis->JaBaseCppUrl::)
NS_FORWARD_NSIURIWITHQUERY(mFakeThis->JaBaseCppUrl::)
NS_FORWARD_NSIURL(mFakeThis->JaBaseCppUrl::)
NS_FORWARD_NSIMSGMESSAGEURL(mFakeThis->JaBaseCppUrl::)
NS_FORWARD_NSIINTERFACEREQUESTOR(mFakeThis->JaBaseCppUrl::)
private:
virtual ~Super() {}
JaCppUrlDelegator *mFakeThis;
};
private:
virtual ~JaCppUrlDelegator() {
}
// Interfaces that may be overridden by JS.
nsCOMPtr<nsIMsgMailNewsUrl> mJsIMsgMailNewsUrl;
nsCOMPtr<nsIURI> mJsIURI;
nsCOMPtr<nsIURIWithQuery> mJsIURIWithQuery;
nsCOMPtr<nsIURL> mJsIURL;
nsCOMPtr<nsIMsgMessageUrl> mJsIMsgMessageUrl;
nsCOMPtr<nsIInterfaceRequestor> mJsIInterfaceRequestor;
// Owning reference to the JS override.
nsCOMPtr<nsISupports> mJsISupports;
// Class to bypass JS delegates. nsCOMPtr for when we do cycle collection.
nsCOMPtr<nsIMsgMailNewsUrl> mCppBase;
RefPtr<DelegateList> mDelegateList;
nsDataHashtable<nsCStringHashKey, bool> *mMethods;
};
} // namespace mailnews
} // namespace mozilla
#endif

View file

@ -0,0 +1,28 @@
# -*- Mode: python; c-basic-offset: 4; 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 += [
'DelegateList.cpp',
'JaAbDirectory.cpp',
'JaCompose.cpp',
'JaIncomingServer.cpp',
'JaMsgFolder.cpp',
'JaSend.cpp',
'JaUrl.cpp',
]
EXPORTS += [
'DelegateList.h',
'JaAbDirectory.h',
'JaCompose.h',
'JaIncomingServer.h',
'JaMsgFolder.h',
'JaSend.h',
'JaUrl.h',
]
Library('JsAccount')
FINAL_LIBRARY = 'mail'