michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include // for nullptr michael@0: michael@0: #include "mozilla/Module.h" // for Module, Module::CIDEntry, etc michael@0: #include "mozilla/ModuleUtils.h" michael@0: #include "mozilla/mozalloc.h" // for operator new michael@0: #include "nsCOMPtr.h" // for nsCOMPtr, getter_AddRefs, etc michael@0: #include "nsComponentManagerUtils.h" // for do_CreateInstance michael@0: #include "nsComposeTxtSrvFilter.h" // for nsComposeTxtSrvFilter, etc michael@0: #include "nsComposerController.h" // for nsComposerController, etc michael@0: #include "nsDebug.h" // for NS_ENSURE_SUCCESS michael@0: #include "nsEditingSession.h" // for NS_EDITINGSESSION_CID, etc michael@0: #include "nsEditorSpellCheck.h" // for NS_EDITORSPELLCHECK_CID, etc michael@0: #include "nsError.h" // for NS_ERROR_NO_AGGREGATION, etc michael@0: #include "nsIController.h" // for nsIController michael@0: #include "nsIControllerCommandTable.h" // for nsIControllerCommandTable, etc michael@0: #include "nsIControllerContext.h" // for nsIControllerContext michael@0: #include "nsID.h" // for NS_DEFINE_NAMED_CID, etc michael@0: #include "nsISupportsImpl.h" michael@0: #include "nsISupportsUtils.h" // for NS_ADDREF, NS_RELEASE michael@0: #include "nsServiceManagerUtils.h" // for do_GetService michael@0: #include "nscore.h" // for nsresult michael@0: michael@0: class nsISupports; michael@0: michael@0: #define NS_HTMLEDITOR_COMMANDTABLE_CID \ michael@0: { 0x13e50d8d, 0x9cee, 0x4ad1, { 0xa3, 0xa2, 0x4a, 0x44, 0x2f, 0xdf, 0x7d, 0xfa } } michael@0: michael@0: #define NS_HTMLEDITOR_DOCSTATE_COMMANDTABLE_CID \ michael@0: { 0xa33982d3, 0x1adf, 0x4162, { 0x99, 0x41, 0xf7, 0x34, 0xbc, 0x45, 0xe4, 0xed } } michael@0: michael@0: michael@0: static NS_DEFINE_CID(kHTMLEditorCommandTableCID, NS_HTMLEDITOR_COMMANDTABLE_CID); michael@0: static NS_DEFINE_CID(kHTMLEditorDocStateCommandTableCID, NS_HTMLEDITOR_DOCSTATE_COMMANDTABLE_CID); michael@0: michael@0: michael@0: //////////////////////////////////////////////////////////////////////// michael@0: // Define the contructor function for the objects michael@0: // michael@0: // NOTE: This creates an instance of objects by using the default constructor michael@0: // michael@0: michael@0: NS_GENERIC_FACTORY_CONSTRUCTOR(nsEditingSession) michael@0: NS_GENERIC_FACTORY_CONSTRUCTOR(nsEditorSpellCheck) michael@0: michael@0: // There are no macros that enable us to have 2 constructors michael@0: // for the same object michael@0: // michael@0: // Here we are creating the same object with two different contract IDs michael@0: // and then initializing it different. michael@0: // Basically, we need to tell the filter whether it is doing mail or not michael@0: static nsresult michael@0: nsComposeTxtSrvFilterConstructor(nsISupports *aOuter, REFNSIID aIID, michael@0: void **aResult, bool aIsForMail) michael@0: { michael@0: *aResult = nullptr; michael@0: if (nullptr != aOuter) michael@0: { michael@0: return NS_ERROR_NO_AGGREGATION; michael@0: } michael@0: nsComposeTxtSrvFilter * inst = new nsComposeTxtSrvFilter(); michael@0: if (nullptr == inst) michael@0: { michael@0: return NS_ERROR_OUT_OF_MEMORY; michael@0: } michael@0: NS_ADDREF(inst); michael@0: inst->Init(aIsForMail); michael@0: nsresult rv = inst->QueryInterface(aIID, aResult); michael@0: NS_RELEASE(inst); michael@0: return rv; michael@0: } michael@0: michael@0: static nsresult michael@0: nsComposeTxtSrvFilterConstructorForComposer(nsISupports *aOuter, michael@0: REFNSIID aIID, michael@0: void **aResult) michael@0: { michael@0: return nsComposeTxtSrvFilterConstructor(aOuter, aIID, aResult, false); michael@0: } michael@0: michael@0: static nsresult michael@0: nsComposeTxtSrvFilterConstructorForMail(nsISupports *aOuter, michael@0: REFNSIID aIID, michael@0: void **aResult) michael@0: { michael@0: return nsComposeTxtSrvFilterConstructor(aOuter, aIID, aResult, true); michael@0: } michael@0: michael@0: michael@0: // Constructor for a controller set up with a command table specified michael@0: // by the CID passed in. This function uses do_GetService to get the michael@0: // command table, so that every controller shares a single command michael@0: // table, for space-efficiency. michael@0: // michael@0: // The only reason to go via the service manager for the command table michael@0: // is that it holds onto the singleton for us, avoiding static variables here. michael@0: static nsresult michael@0: CreateControllerWithSingletonCommandTable(const nsCID& inCommandTableCID, nsIController **aResult) michael@0: { michael@0: nsresult rv; michael@0: nsCOMPtr controller = do_CreateInstance("@mozilla.org/embedcomp/base-command-controller;1", &rv); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: nsCOMPtr composerCommandTable = do_GetService(inCommandTableCID, &rv); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: // this guy is a singleton, so make it immutable michael@0: composerCommandTable->MakeImmutable(); michael@0: michael@0: nsCOMPtr controllerContext = do_QueryInterface(controller, &rv); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: rv = controllerContext->Init(composerCommandTable); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: *aResult = controller; michael@0: NS_ADDREF(*aResult); michael@0: return NS_OK; michael@0: } michael@0: michael@0: michael@0: // Here we make an instance of the controller that holds doc state commands. michael@0: // We set it up with a singleton command table. michael@0: static nsresult michael@0: nsHTMLEditorDocStateControllerConstructor(nsISupports *aOuter, REFNSIID aIID, michael@0: void **aResult) michael@0: { michael@0: nsCOMPtr controller; michael@0: nsresult rv = CreateControllerWithSingletonCommandTable(kHTMLEditorDocStateCommandTableCID, getter_AddRefs(controller)); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: return controller->QueryInterface(aIID, aResult); michael@0: } michael@0: michael@0: // Tere we make an instance of the controller that holds composer commands. michael@0: // We set it up with a singleton command table. michael@0: static nsresult michael@0: nsHTMLEditorControllerConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult) michael@0: { michael@0: nsCOMPtr controller; michael@0: nsresult rv = CreateControllerWithSingletonCommandTable(kHTMLEditorCommandTableCID, getter_AddRefs(controller)); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: return controller->QueryInterface(aIID, aResult); michael@0: } michael@0: michael@0: // Constructor for a command table that is pref-filled with HTML editor commands michael@0: static nsresult michael@0: nsHTMLEditorCommandTableConstructor(nsISupports *aOuter, REFNSIID aIID, michael@0: void **aResult) michael@0: { michael@0: nsresult rv; michael@0: nsCOMPtr commandTable = michael@0: do_CreateInstance(NS_CONTROLLERCOMMANDTABLE_CONTRACTID, &rv); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: rv = nsComposerController::RegisterHTMLEditorCommands(commandTable); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: // we don't know here whether we're being created as an instance, michael@0: // or a service, so we can't become immutable michael@0: michael@0: return commandTable->QueryInterface(aIID, aResult); michael@0: } michael@0: michael@0: michael@0: // Constructor for a command table that is pref-filled with HTML editor doc state commands michael@0: static nsresult michael@0: nsHTMLEditorDocStateCommandTableConstructor(nsISupports *aOuter, REFNSIID aIID, michael@0: void **aResult) michael@0: { michael@0: nsresult rv; michael@0: nsCOMPtr commandTable = michael@0: do_CreateInstance(NS_CONTROLLERCOMMANDTABLE_CONTRACTID, &rv); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: rv = nsComposerController::RegisterEditorDocStateCommands(commandTable); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: // we don't know here whether we're being created as an instance, michael@0: // or a service, so we can't become immutable michael@0: michael@0: return commandTable->QueryInterface(aIID, aResult); michael@0: } michael@0: michael@0: NS_DEFINE_NAMED_CID(NS_HTMLEDITORCONTROLLER_CID); michael@0: NS_DEFINE_NAMED_CID(NS_EDITORDOCSTATECONTROLLER_CID); michael@0: NS_DEFINE_NAMED_CID(NS_HTMLEDITOR_COMMANDTABLE_CID); michael@0: NS_DEFINE_NAMED_CID(NS_HTMLEDITOR_DOCSTATE_COMMANDTABLE_CID); michael@0: NS_DEFINE_NAMED_CID(NS_EDITINGSESSION_CID); michael@0: NS_DEFINE_NAMED_CID(NS_EDITORSPELLCHECK_CID); michael@0: NS_DEFINE_NAMED_CID(NS_COMPOSERTXTSRVFILTER_CID); michael@0: NS_DEFINE_NAMED_CID(NS_COMPOSERTXTSRVFILTERMAIL_CID); michael@0: michael@0: michael@0: static const mozilla::Module::CIDEntry kComposerCIDs[] = { michael@0: { &kNS_HTMLEDITORCONTROLLER_CID, false, nullptr, nsHTMLEditorControllerConstructor }, michael@0: { &kNS_EDITORDOCSTATECONTROLLER_CID, false, nullptr, nsHTMLEditorDocStateControllerConstructor }, michael@0: { &kNS_HTMLEDITOR_COMMANDTABLE_CID, false, nullptr, nsHTMLEditorCommandTableConstructor }, michael@0: { &kNS_HTMLEDITOR_DOCSTATE_COMMANDTABLE_CID, false, nullptr, nsHTMLEditorDocStateCommandTableConstructor }, michael@0: { &kNS_EDITINGSESSION_CID, false, nullptr, nsEditingSessionConstructor }, michael@0: { &kNS_EDITORSPELLCHECK_CID, false, nullptr, nsEditorSpellCheckConstructor }, michael@0: { &kNS_COMPOSERTXTSRVFILTER_CID, false, nullptr, nsComposeTxtSrvFilterConstructorForComposer }, michael@0: { &kNS_COMPOSERTXTSRVFILTERMAIL_CID, false, nullptr, nsComposeTxtSrvFilterConstructorForMail }, michael@0: { nullptr } michael@0: }; michael@0: michael@0: static const mozilla::Module::ContractIDEntry kComposerContracts[] = { michael@0: { "@mozilla.org/editor/htmleditorcontroller;1", &kNS_HTMLEDITORCONTROLLER_CID }, michael@0: { "@mozilla.org/editor/editordocstatecontroller;1", &kNS_EDITORDOCSTATECONTROLLER_CID }, michael@0: { "@mozilla.org/editor/editingsession;1", &kNS_EDITINGSESSION_CID }, michael@0: { "@mozilla.org/editor/editorspellchecker;1", &kNS_EDITORSPELLCHECK_CID }, michael@0: { COMPOSER_TXTSRVFILTER_CONTRACTID, &kNS_COMPOSERTXTSRVFILTER_CID }, michael@0: { COMPOSER_TXTSRVFILTERMAIL_CONTRACTID, &kNS_COMPOSERTXTSRVFILTERMAIL_CID }, michael@0: { nullptr } michael@0: }; michael@0: michael@0: static const mozilla::Module kComposerModule = { michael@0: mozilla::Module::kVersion, michael@0: kComposerCIDs, michael@0: kComposerContracts michael@0: }; michael@0: michael@0: NSMODULE_DEFN(nsComposerModule) = &kComposerModule;