diff options
Diffstat (limited to '')
-rw-r--r-- | comm/mailnews/jsaccount/src/DelegateList.cpp | 24 | ||||
-rw-r--r-- | comm/mailnews/jsaccount/src/DelegateList.h | 48 | ||||
-rw-r--r-- | comm/mailnews/jsaccount/src/JaAbDirectory.cpp | 81 | ||||
-rw-r--r-- | comm/mailnews/jsaccount/src/JaAbDirectory.h | 84 | ||||
-rw-r--r-- | comm/mailnews/jsaccount/src/JaCompose.cpp | 89 | ||||
-rw-r--r-- | comm/mailnews/jsaccount/src/JaCompose.h | 89 | ||||
-rw-r--r-- | comm/mailnews/jsaccount/src/JaIncomingServer.cpp | 96 | ||||
-rw-r--r-- | comm/mailnews/jsaccount/src/JaIncomingServer.h | 95 | ||||
-rw-r--r-- | comm/mailnews/jsaccount/src/JaMsgFolder.cpp | 176 | ||||
-rw-r--r-- | comm/mailnews/jsaccount/src/JaMsgFolder.h | 137 | ||||
-rw-r--r-- | comm/mailnews/jsaccount/src/JaUrl.cpp | 205 | ||||
-rw-r--r-- | comm/mailnews/jsaccount/src/JaUrl.h | 138 | ||||
-rw-r--r-- | comm/mailnews/jsaccount/src/components.conf | 37 | ||||
-rw-r--r-- | comm/mailnews/jsaccount/src/moz.build | 30 |
14 files changed, 1329 insertions, 0 deletions
diff --git a/comm/mailnews/jsaccount/src/DelegateList.cpp b/comm/mailnews/jsaccount/src/DelegateList.cpp new file mode 100644 index 0000000000..cd146fe3dc --- /dev/null +++ b/comm/mailnews/jsaccount/src/DelegateList.cpp @@ -0,0 +1,24 @@ +/* -*- Mode: C++; tab-width: 2; 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 nsACString& aMethodName) { + mMethods.InsertOrUpdate(aMethodName, true); + return NS_OK; +} + +} // namespace mailnews +} // namespace mozilla diff --git a/comm/mailnews/jsaccount/src/DelegateList.h b/comm/mailnews/jsaccount/src/DelegateList.h new file mode 100644 index 0000000000..f59e178f0c --- /dev/null +++ b/comm/mailnews/jsaccount/src/DelegateList.h @@ -0,0 +1,48 @@ +/* -*- 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 "nsTHashMap.h" +#include "nsString.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() {} + nsTHashMap<nsCStringHashKey, bool> mMethods; + + protected: + virtual ~DelegateList() {} +}; + +} // namespace mailnews +} // namespace mozilla + +/* + * This macro is used in forwarding functions. + * _jsdelegate: the name of the JS pointer that implements a particular + * interface. + * _jsmethods: the DelegateList object + * _cppbase: the C++ base instance (used when call not delegated to js) + * + **/ + +#define DELEGATE_JS(_jsdelegate, _jsmethods, _cppbase) \ + (_jsdelegate && _jsmethods && \ + _jsmethods->Contains(nsLiteralCString(__func__)) \ + ? _jsdelegate \ + : (_cppbase)) + +#endif diff --git a/comm/mailnews/jsaccount/src/JaAbDirectory.cpp b/comm/mailnews/jsaccount/src/JaAbDirectory.cpp new file mode 100644 index 0000000000..11b29e99ab --- /dev/null +++ b/comm/mailnews/jsaccount/src/JaAbDirectory.cpp @@ -0,0 +1,81 @@ +/* -*- Mode: C++; tab-width: 2; 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 "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, + 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(); + 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); + 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 diff --git a/comm/mailnews/jsaccount/src/JaAbDirectory.h b/comm/mailnews/jsaccount/src/JaAbDirectory.h new file mode 100644 index 0000000000..7a2903d3d4 --- /dev/null +++ b/comm/mailnews/jsaccount/src/JaAbDirectory.h @@ -0,0 +1,84 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef _JaAbDirectory_H_ +#define _JaAbDirectory_H_ + +#include "nsISupports.h" +#include "DelegateList.h" +#include "msgIOverride.h" +#include "nsIAbDirectory.h" +#include "nsAbDirProperty.h" +#include "nsTHashMap.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 + + // use mCppBase as a raw pointer where possible + NS_FORWARD_NSIABDIRECTORY(DELEGATE_JS(mJsIAbDirectory, mMethods, mCppBase)->) + NS_FORWARD_NSIINTERFACEREQUESTOR( + DELEGATE_JS( + mJsIInterfaceRequestor, mMethods, + (nsCOMPtr<nsIInterfaceRequestor>(do_QueryInterface(mCppBase)))) + ->) + + JaCppAbDirectoryDelegator(); + + private: + virtual ~JaCppAbDirectoryDelegator() {} + + class Super : public nsIAbDirectory, public nsIInterfaceRequestor { + public: + explicit Super(JaCppAbDirectoryDelegator* aFakeThis) { + mFakeThis = aFakeThis; + } + NS_DECL_ISUPPORTS + NS_FORWARD_NSIABDIRECTORY(mFakeThis->JaBaseCppAbDirectory::) + NS_FORWARD_NSIINTERFACEREQUESTOR(mFakeThis->JaBaseCppAbDirectory::) + private: + virtual ~Super() {} + JaCppAbDirectoryDelegator* mFakeThis; + }; + + // Interfaces that may be overridden by JS. + nsCOMPtr<nsIAbDirectory> mJsIAbDirectory; + nsCOMPtr<nsIInterfaceRequestor> mJsIInterfaceRequestor; + + nsCOMPtr<nsISupports> mJsISupports; + + // Class to bypass JS delegates. nsCOMPtr for when we do cycle collection. + nsCOMPtr<nsIAbDirectory> mCppBase; + + RefPtr<DelegateList> mDelegateList; + nsTHashMap<nsCStringHashKey, bool>* mMethods; +}; + +} // namespace mailnews +} // namespace mozilla + +#endif diff --git a/comm/mailnews/jsaccount/src/JaCompose.cpp b/comm/mailnews/jsaccount/src/JaCompose.cpp new file mode 100644 index 0000000000..a44dac2c01 --- /dev/null +++ b/comm/mailnews/jsaccount/src/JaCompose.cpp @@ -0,0 +1,89 @@ +/* -*- Mode: C++; tab-width: 2; 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 "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(); + 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 diff --git a/comm/mailnews/jsaccount/src/JaCompose.h b/comm/mailnews/jsaccount/src/JaCompose.h new file mode 100644 index 0000000000..587e91738a --- /dev/null +++ b/comm/mailnews/jsaccount/src/JaCompose.h @@ -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 _JaCompose_H_ +#define _JaCompose_H_ + +#include "nsISupports.h" +#include "DelegateList.h" +#include "msgIOverride.h" +#include "nsMsgCompose.h" +#include "nsIMsgCompose.h" +#include "nsTHashMap.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(mJsIMsgCompose, mMethods, mCppBase)->) + NS_FORWARD_NSIMSGSENDLISTENER( + DELEGATE_JS(mJsIMsgSendListener, mMethods, mCppBase.get())->) + NS_FORWARD_NSIINTERFACEREQUESTOR( + DELEGATE_JS( + mJsIInterfaceRequestor, mMethods, + (nsCOMPtr<nsIInterfaceRequestor>(do_QueryInterface(mCppBase)))) + ->) + + 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: + explicit 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; + nsTHashMap<nsCStringHashKey, bool>* mMethods; +}; + +} // namespace mailnews +} // namespace mozilla + +#endif diff --git a/comm/mailnews/jsaccount/src/JaIncomingServer.cpp b/comm/mailnews/jsaccount/src/JaIncomingServer.cpp new file mode 100644 index 0000000000..8acdf9c655 --- /dev/null +++ b/comm/mailnews/jsaccount/src/JaIncomingServer.cpp @@ -0,0 +1,96 @@ +/* -*- Mode: C++; tab-width: 2; 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 "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 nsACString& 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(); + 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 diff --git a/comm/mailnews/jsaccount/src/JaIncomingServer.h b/comm/mailnews/jsaccount/src/JaIncomingServer.h new file mode 100644 index 0000000000..67c7fd48f6 --- /dev/null +++ b/comm/mailnews/jsaccount/src/JaIncomingServer.h @@ -0,0 +1,95 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef _JaIncomingServer_H_ +#define _JaIncomingServer_H_ + +#include "nsISupports.h" +#include "DelegateList.h" +#include "msgIOverride.h" +#include "nsIMsgIncomingServer.h" +#include "nsMsgIncomingServer.h" +#include "nsTHashMap.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 nsACString& serverUri, + nsIMsgFolder** rootFolder) override; + + protected: + virtual ~JaBaseCppIncomingServer() {} +}; + +class JaCppIncomingServerDelegator : public JaBaseCppIncomingServer, + public msgIOverride { + public: + NS_DECL_ISUPPORTS_INHERITED + NS_DECL_MSGIOVERRIDE + + // use mCppBase as a raw pointer where possible + NS_FORWARD_NSIMSGINCOMINGSERVER( + DELEGATE_JS(mJsIMsgIncomingServer, mMethods, mCppBase)->) + NS_FORWARD_NSIINTERFACEREQUESTOR( + DELEGATE_JS( + mJsIInterfaceRequestor, mMethods, + (nsCOMPtr<nsIInterfaceRequestor>(do_QueryInterface(mCppBase)))) + ->) + + 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: + explicit 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; + nsTHashMap<nsCStringHashKey, bool>* mMethods; +}; + +} // namespace mailnews +} // namespace mozilla + +#endif diff --git a/comm/mailnews/jsaccount/src/JaMsgFolder.cpp b/comm/mailnews/jsaccount/src/JaMsgFolder.cpp new file mode 100644 index 0000000000..e10f9f1704 --- /dev/null +++ b/comm/mailnews/jsaccount/src/JaMsgFolder.cpp @@ -0,0 +1,176 @@ +/* -*- Mode: C++; tab-width: 2; 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 "nsComponentManagerUtils.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("@mozilla.org/msgDatabase/msgDBService;1", &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 nsACString& 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, + 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(); + 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 diff --git a/comm/mailnews/jsaccount/src/JaMsgFolder.h b/comm/mailnews/jsaccount/src/JaMsgFolder.h new file mode 100644 index 0000000000..97cdfce5e6 --- /dev/null +++ b/comm/mailnews/jsaccount/src/JaMsgFolder.h @@ -0,0 +1,137 @@ +/* -*- 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 "nsISupports.h" +#include "DelegateList.h" +#include "msgIOverride.h" +#include "nsIMsgFolder.h" +#include "nsMsgDBFolder.h" +#include "nsCycleCollectionParticipant.h" +#include "nsTHashMap.h" +#include "nsIInterfaceRequestor.h" +#include "nsNetUtil.h" +#include "nsIDBChangeListener.h" +#include "nsIUrlListener.h" +#include "nsIMsgFilterPlugin.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 JaBaseCppMsgFolder : public nsMsgDBFolder, + public nsIInterfaceRequestor + +{ + public: + NS_DECL_ISUPPORTS_INHERITED + NS_DECL_NSIINTERFACEREQUESTOR + JaBaseCppMsgFolder() {} + + // nsMsgDBFolder overrides + + nsresult CreateChildFromURI(const nsACString& 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 + + NS_FORWARD_NSIMSGFOLDER(DELEGATE_JS(mJsIMsgFolder, mMethods, mCppBase)->) + NS_FORWARD_NSIDBCHANGELISTENER( + DELEGATE_JS(mJsIDBChangeListener, mMethods, + (nsCOMPtr<nsIDBChangeListener>(do_QueryInterface(mCppBase)))) + ->) + NS_FORWARD_NSIURLLISTENER( + DELEGATE_JS(mJsIUrlListener, mMethods, + (nsCOMPtr<nsIUrlListener>(do_QueryInterface(mCppBase)))) + ->) + NS_FORWARD_NSIJUNKMAILCLASSIFICATIONLISTENER( + DELEGATE_JS(mJsIJunkMailClassificationListener, mMethods, + (nsCOMPtr<nsIJunkMailClassificationListener>( + do_QueryInterface(mCppBase)))) + ->) + NS_FORWARD_NSIMSGTRAITCLASSIFICATIONLISTENER( + DELEGATE_JS(mJsIMsgTraitClassificationListener, mMethods, + (nsCOMPtr<nsIMsgTraitClassificationListener>( + do_QueryInterface(mCppBase)))) + ->) + NS_FORWARD_NSIINTERFACEREQUESTOR( + DELEGATE_JS( + mJsIInterfaceRequestor, mMethods, + (nsCOMPtr<nsIInterfaceRequestor>(do_QueryInterface(mCppBase)))) + ->) + + JaCppMsgFolderDelegator(); + + private: + virtual ~JaCppMsgFolderDelegator() {} + + class Super : public nsIMsgFolder, + 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". + explicit Super(JaCppMsgFolderDelegator* aFakeThis) { + mFakeThis = aFakeThis; + } + NS_DECL_ISUPPORTS + NS_FORWARD_NSIMSGFOLDER(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; + nsTHashMap<nsCStringHashKey, bool>* mMethods; +}; + +} // namespace mailnews +} // namespace mozilla + +#endif diff --git a/comm/mailnews/jsaccount/src/JaUrl.cpp b/comm/mailnews/jsaccount/src/JaUrl.cpp new file mode 100644 index 0000000000..249c45c9df --- /dev/null +++ b/comm/mailnews/jsaccount/src/JaUrl.cpp @@ -0,0 +1,205 @@ +/* -*- Mode: C++; tab-width: 2; 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 "nsMsgUtils.h" + +// This file contains an implementation of mailnews URLs in JsAccount. + +namespace mozilla { +namespace mailnews { + +NS_IMPL_ISUPPORTS_INHERITED(JaBaseCppUrl, nsMsgMailNewsUrl, nsIMsgMessageUrl, + msgIJaUrl, 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; +} + +NS_IMETHODIMP JaBaseCppUrl::GetServer(nsIMsgIncomingServer** aIncomingServer) { + if (mFolder) { + return mFolder->GetServer(aIncomingServer); + } + return NS_ERROR_NOT_INITIALIZED; +} + +NS_IMETHODIMP JaBaseCppUrl::IsUrlType(uint32_t type, bool* isType) { + NS_ENSURE_ARG(isType); + *isType = (m_urlType == type); + return NS_OK; +} + +// nsIMsgMessageUrl implementation +NS_IMETHODIMP JaBaseCppUrl::GetUri(nsACString& aUri) { + if (!mUri.IsEmpty()) + aUri = mUri; + else + return NS_ERROR_NOT_INITIALIZED; + return NS_OK; +} +NS_IMETHODIMP JaBaseCppUrl::SetUri(const nsACString& 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(nsACString& aOriginalSpec) { + if (mOriginalSpec.IsEmpty()) return NS_ERROR_NULL_POINTER; + aOriginalSpec = mOriginalSpec; + return NS_OK; +} +NS_IMETHODIMP JaBaseCppUrl::SetOriginalSpec(const nsACString& aOriginalSpec) { + mOriginalSpec = aOriginalSpec; + return NS_OK; +} + +NS_IMETHODIMP JaBaseCppUrl::GetNormalizedSpec(nsACString& aPrincipalSpec) { + // URLs contain a lot of query parts. We want need a normalized form: + // scheme://server/folder?number=123 + nsCOMPtr<nsIMsgMailNewsUrl> mailnewsURL; + QueryInterface(NS_GET_IID(nsIMsgMailNewsUrl), getter_AddRefs(mailnewsURL)); + + nsAutoCString spec; + mailnewsURL->GetSpecIgnoringRef(spec); + + nsCString queryPart = MsgExtractQueryPart(spec, "number="); + + // Strip any query part beginning with ? or /; + MsgRemoveQueryPart(spec); + + if (!queryPart.IsEmpty()) spec += "?"_ns + queryPart; + + aPrincipalSpec.Assign(spec); + return NS_OK; +} + +NS_IMETHODIMP JaBaseCppUrl::GetMessageHeader(nsIMsgDBHdr** aMessageHeader) { + // This routine does a lookup using messenger, assuming 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("@mozilla.org/messenger;1", &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; +} + +// msgIJaUrl implementation +NS_IMETHODIMP JaBaseCppUrl::SetUrlType(unsigned int type) { + m_urlType = type; + return NS_OK; +} + +NS_IMETHODIMP JaBaseCppUrl::SetSpec(const nsACString& aSpec) { + return SetSpecInternal(aSpec); +} + +// 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, nsIMsgMessageUrl, nsIURI, nsIURL, + nsIURIWithSpecialOrigin, nsIMsgMailNewsUrl, msgIJaUrl, + nsIInterfaceRequestor, nsISupportsWeakReference) + +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(); + 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; + 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 diff --git a/comm/mailnews/jsaccount/src/JaUrl.h b/comm/mailnews/jsaccount/src/JaUrl.h new file mode 100644 index 0000000000..6de4feba60 --- /dev/null +++ b/comm/mailnews/jsaccount/src/JaUrl.h @@ -0,0 +1,138 @@ +/* -*- 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 "nsCycleCollectionParticipant.h" +#include "nsTHashMap.h" +#include "nsIFile.h" +#include "nsIInterfaceRequestor.h" +#include "nsIMsgFolder.h" +#include "nsISupports.h" +#include "nsIURI.h" +#include "nsIURL.h" +#include "nsMsgMailNewsUrl.h" +#include "nsWeakReference.h" +#include "msgIJaUrl.h" +#include "nsProxyRelease.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 msgIJaUrl, + public nsIInterfaceRequestor, + public nsSupportsWeakReference { + public: + NS_DECL_ISUPPORTS_INHERITED + NS_DECL_NSIMSGMESSAGEURL + NS_DECL_MSGIJAURL + NS_DECL_NSIINTERFACEREQUESTOR + JaBaseCppUrl() {} + + // nsIMsgMailNewsUrl overrides + NS_IMETHOD GetFolder(nsIMsgFolder** aFolder) override; + NS_IMETHOD SetFolder(nsIMsgFolder* aFolder) override; + NS_IMETHOD IsUrlType(uint32_t type, bool* isType) override; + NS_IMETHOD GetServer(nsIMsgIncomingServer** aIncomingServer) 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 = false; + nsCString mOriginalSpec; + + // msgIJaUrl variables + unsigned int m_urlType{0}; +}; + +class JaCppUrlDelegator : public JaBaseCppUrl, public msgIOverride { + public: + NS_DECL_ISUPPORTS_INHERITED + NS_DECL_MSGIOVERRIDE + + NS_FORWARD_NSIMSGMESSAGEURL( + DELEGATE_JS(mJsIMsgMessageUrl, mMethods, + (nsCOMPtr<nsIMsgMessageUrl>(do_QueryInterface(mCppBase)))) + ->) + NS_FORWARD_NSIINTERFACEREQUESTOR( + DELEGATE_JS( + mJsIInterfaceRequestor, mMethods, + (nsCOMPtr<nsIInterfaceRequestor>(do_QueryInterface(mCppBase)))) + ->) + + JaCppUrlDelegator(); + + class Super : public nsIMsgMailNewsUrl, + public nsIURIWithSpecialOrigin, + public nsIMsgMessageUrl, + public msgIJaUrl, + public nsIInterfaceRequestor, + public nsISupportsWeakReference { + public: + explicit Super(JaCppUrlDelegator* aFakeThis) { mFakeThis = aFakeThis; } + NS_DECL_ISUPPORTS + NS_FORWARD_NSIMSGMAILNEWSURL(mFakeThis->JaBaseCppUrl::) + NS_FORWARD_NSIURI(mFakeThis->JaBaseCppUrl::) + NS_FORWARD_NSIURL(mFakeThis->JaBaseCppUrl::) + NS_FORWARD_NSIURIWITHSPECIALORIGIN(mFakeThis->JaBaseCppUrl::) + NS_FORWARD_NSIMSGMESSAGEURL(mFakeThis->JaBaseCppUrl::) + NS_FORWARD_MSGIJAURL(mFakeThis->JaBaseCppUrl::) + NS_FORWARD_NSIINTERFACEREQUESTOR(mFakeThis->JaBaseCppUrl::) + NS_FORWARD_NSISUPPORTSWEAKREFERENCE(mFakeThis->JaBaseCppUrl::) + private: + virtual ~Super() {} + JaCppUrlDelegator* mFakeThis; + }; + + private: + virtual ~JaCppUrlDelegator() { + NS_ReleaseOnMainThread("JaCppUrlDelegator::mJsIMsgMessageUrl", + mJsIMsgMessageUrl.forget()); + NS_ReleaseOnMainThread("JaCppUrlDelegator::mJsIInterfaceRequestor", + mJsIInterfaceRequestor.forget()); + NS_ReleaseOnMainThread("JaCppUrlDelegator::mJsISupports", + mJsISupports.forget()); + NS_ReleaseOnMainThread("JaCppUrlDelegator::mDelegateList", + mDelegateList.forget()); + } + + // Interfaces that may be overridden by JS. + 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; + nsTHashMap<nsCStringHashKey, bool>* mMethods; +}; + +} // namespace mailnews +} // namespace mozilla + +#endif diff --git a/comm/mailnews/jsaccount/src/components.conf b/comm/mailnews/jsaccount/src/components.conf new file mode 100644 index 0000000000..89b4543316 --- /dev/null +++ b/comm/mailnews/jsaccount/src/components.conf @@ -0,0 +1,37 @@ +# 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/. + +Classes = [ + { + "cid": "{77b5592c-5018-436d-a466-c4e5443a1669}", + "contract_ids": ["@mozilla.org/jacppabdirectorydelegator;1"], + "type": "mailnews::JaCppAbDirectoryDelegator", + "headers": ["/comm/mailnews/jsaccount/src/JaAbDirectory.h"], + }, + { + "cid": "{cfcd1caa-00d9-40d0-831e-673820e04fc6}", + "contract_ids": ["@mozilla.org/jacppcomposedelegator;1"], + "type": "mailnews::JaCppComposeDelegator", + "headers": ["/comm/mailnews/jsaccount/src/JaCompose.h"], + }, + { + "cid": "{7aa11dd3-5590-4e01-bd87-91f60272d01a}", + "contract_ids": ["@mozilla.org/jacppincomingserverdelegator;1"], + "type": "mailnews::JaCppIncomingServerDelegator", + "init_method": "Init", + "headers": ["/comm/mailnews/jsaccount/src/JaIncomingServer.h"], + }, + { + "cid": "{d6bd81fa-b1d4-424a-88ea-bb3ea8381d50}", + "contract_ids": ["@mozilla.org/jacppmsgfolderdelegator;1"], + "type": "mailnews::JaCppMsgFolderDelegator", + "headers": ["/comm/mailnews/jsaccount/src/JaMsgFolder.h"], + }, + { + "cid": "{1a0b778c-2fe6-4012-b4f3-e81c0c116409}", + "contract_ids": ["@mozilla.org/jacppurldelegator;1"], + "type": "mailnews::JaCppUrlDelegator", + "headers": ["/comm/mailnews/jsaccount/src/JaUrl.h"], + }, +] diff --git a/comm/mailnews/jsaccount/src/moz.build b/comm/mailnews/jsaccount/src/moz.build new file mode 100644 index 0000000000..a78cb5c1f7 --- /dev/null +++ b/comm/mailnews/jsaccount/src/moz.build @@ -0,0 +1,30 @@ +# -*- 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", + "JaUrl.cpp", +] + +EXPORTS += [ + "DelegateList.h", + "JaAbDirectory.h", + "JaCompose.h", + "JaIncomingServer.h", + "JaMsgFolder.h", + "JaUrl.h", +] + +Library("JsAccount") +FINAL_LIBRARY = "mail" + +XPCOM_MANIFESTS += [ + "components.conf", +] |