mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-28 03:17:31 +09:00
Issue #1258 - Part 1: Import mailnews, ldap, and mork from comm-esr52.9.1
This commit is contained in:
parent
23e0d82436
commit
e400f4130a
1564 changed files with 510348 additions and 0 deletions
285
mailnews/jsaccount/modules/JSAccountUtils.jsm
Normal file
285
mailnews/jsaccount/modules/JSAccountUtils.jsm
Normal 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;
|
||||
}
|
||||
81
mailnews/jsaccount/modules/JaBaseUrl.jsm
Normal file
81
mailnews/jsaccount/modules/JaBaseUrl.jsm
Normal 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.
|
||||
|
||||
};
|
||||
15
mailnews/jsaccount/moz.build
Normal file
15
mailnews/jsaccount/moz.build
Normal 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',
|
||||
]
|
||||
17
mailnews/jsaccount/public/moz.build
Normal file
17
mailnews/jsaccount/public/moz.build
Normal 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'
|
||||
|
||||
19
mailnews/jsaccount/public/msgIDelegateList.idl
Normal file
19
mailnews/jsaccount/public/msgIDelegateList.idl
Normal 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);
|
||||
};
|
||||
42
mailnews/jsaccount/public/msgIOverride.idl
Normal file
42
mailnews/jsaccount/public/msgIOverride.idl
Normal 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;
|
||||
};
|
||||
35
mailnews/jsaccount/public/msgJsAccountCID.h
Normal file
35
mailnews/jsaccount/public/msgJsAccountCID.h
Normal 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
|
||||
56
mailnews/jsaccount/readme.html
Normal file
56
mailnews/jsaccount/readme.html
Normal 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>
|
||||
33
mailnews/jsaccount/src/DelegateList.cpp
Normal file
33
mailnews/jsaccount/src/DelegateList.cpp
Normal 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
|
||||
52
mailnews/jsaccount/src/DelegateList.h
Normal file
52
mailnews/jsaccount/src/DelegateList.h
Normal 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
|
||||
98
mailnews/jsaccount/src/JaAbDirectory.cpp
Normal file
98
mailnews/jsaccount/src/JaAbDirectory.cpp
Normal 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
|
||||
89
mailnews/jsaccount/src/JaAbDirectory.h
Normal file
89
mailnews/jsaccount/src/JaAbDirectory.h
Normal 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
|
||||
103
mailnews/jsaccount/src/JaCompose.cpp
Normal file
103
mailnews/jsaccount/src/JaCompose.cpp
Normal 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
|
||||
92
mailnews/jsaccount/src/JaCompose.h
Normal file
92
mailnews/jsaccount/src/JaCompose.h
Normal 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
|
||||
109
mailnews/jsaccount/src/JaIncomingServer.cpp
Normal file
109
mailnews/jsaccount/src/JaIncomingServer.cpp
Normal 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
|
||||
94
mailnews/jsaccount/src/JaIncomingServer.h
Normal file
94
mailnews/jsaccount/src/JaIncomingServer.h
Normal 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
|
||||
207
mailnews/jsaccount/src/JaMsgFolder.cpp
Normal file
207
mailnews/jsaccount/src/JaMsgFolder.cpp
Normal 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
|
||||
126
mailnews/jsaccount/src/JaMsgFolder.h
Normal file
126
mailnews/jsaccount/src/JaMsgFolder.h
Normal 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
|
||||
102
mailnews/jsaccount/src/JaSend.cpp
Normal file
102
mailnews/jsaccount/src/JaSend.cpp
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "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
|
||||
96
mailnews/jsaccount/src/JaSend.h
Normal file
96
mailnews/jsaccount/src/JaSend.h
Normal 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
|
||||
230
mailnews/jsaccount/src/JaUrl.cpp
Normal file
230
mailnews/jsaccount/src/JaUrl.cpp
Normal 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
|
||||
121
mailnews/jsaccount/src/JaUrl.h
Normal file
121
mailnews/jsaccount/src/JaUrl.h
Normal 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
|
||||
28
mailnews/jsaccount/src/moz.build
Normal file
28
mailnews/jsaccount/src/moz.build
Normal 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'
|
||||
Loading…
Add table
Add a link
Reference in a new issue