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: michael@0: #include // for printf michael@0: michael@0: #include "mozilla/Assertions.h" // for MOZ_ASSERT, etc michael@0: #include "nsAString.h" michael@0: #include "nsCOMPtr.h" // for nsCOMPtr, do_QueryInterface, etc michael@0: #include "nsComponentManagerUtils.h" // for do_CreateInstance michael@0: #include "nsComposerCommands.h" michael@0: #include "nsDebug.h" // for NS_ENSURE_TRUE, etc michael@0: #include "nsError.h" // for NS_OK, NS_ERROR_FAILURE, etc michael@0: #include "nsGkAtoms.h" // for nsGkAtoms, nsGkAtoms::font, etc michael@0: #include "nsIAtom.h" // for nsIAtom, etc michael@0: #include "nsIClipboard.h" // for nsIClipboard, etc michael@0: #include "nsICommandParams.h" // for nsICommandParams, etc michael@0: #include "nsID.h" michael@0: #include "nsIDOMElement.h" // for nsIDOMElement michael@0: #include "nsIEditor.h" // for nsIEditor michael@0: #include "nsIHTMLAbsPosEditor.h" // for nsIHTMLAbsPosEditor michael@0: #include "nsIHTMLEditor.h" // for nsIHTMLEditor, etc michael@0: #include "nsLiteralString.h" // for NS_LITERAL_STRING michael@0: #include "nsReadableUtils.h" // for EmptyString michael@0: #include "nsString.h" // for nsAutoString, nsString, etc michael@0: #include "nsStringFwd.h" // for nsAFlatString michael@0: michael@0: class nsISupports; michael@0: michael@0: //prototype michael@0: nsresult GetListState(nsIHTMLEditor* aEditor, bool* aMixed, michael@0: nsAString& aLocalName); michael@0: nsresult RemoveOneProperty(nsIHTMLEditor* aEditor, const nsAString& aProp); michael@0: nsresult RemoveTextProperty(nsIHTMLEditor* aEditor, const nsAString& aProp); michael@0: nsresult SetTextProperty(nsIHTMLEditor *aEditor, const nsAString& aProp); michael@0: michael@0: michael@0: //defines michael@0: #define STATE_ENABLED "state_enabled" michael@0: #define STATE_ALL "state_all" michael@0: #define STATE_ANY "state_any" michael@0: #define STATE_MIXED "state_mixed" michael@0: #define STATE_BEGIN "state_begin" michael@0: #define STATE_END "state_end" michael@0: #define STATE_ATTRIBUTE "state_attribute" michael@0: #define STATE_DATA "state_data" michael@0: michael@0: michael@0: nsBaseComposerCommand::nsBaseComposerCommand() michael@0: { michael@0: } michael@0: michael@0: NS_IMPL_ISUPPORTS(nsBaseComposerCommand, nsIControllerCommand) michael@0: michael@0: michael@0: nsBaseStateUpdatingCommand::nsBaseStateUpdatingCommand(nsIAtom* aTagName) michael@0: : nsBaseComposerCommand() michael@0: , mTagName(aTagName) michael@0: { michael@0: MOZ_ASSERT(mTagName); michael@0: } michael@0: michael@0: nsBaseStateUpdatingCommand::~nsBaseStateUpdatingCommand() michael@0: { michael@0: } michael@0: michael@0: NS_IMPL_ISUPPORTS_INHERITED0(nsBaseStateUpdatingCommand, nsBaseComposerCommand) michael@0: michael@0: NS_IMETHODIMP michael@0: nsBaseStateUpdatingCommand::IsCommandEnabled(const char *aCommandName, michael@0: nsISupports *refCon, michael@0: bool *outCmdEnabled) michael@0: { michael@0: nsCOMPtr editor = do_QueryInterface(refCon); michael@0: if (editor) michael@0: return editor->GetIsSelectionEditable(outCmdEnabled); michael@0: michael@0: *outCmdEnabled = false; michael@0: return NS_OK; michael@0: } michael@0: michael@0: michael@0: NS_IMETHODIMP michael@0: nsBaseStateUpdatingCommand::DoCommand(const char *aCommandName, michael@0: nsISupports *refCon) michael@0: { michael@0: nsCOMPtr editor = do_QueryInterface(refCon); michael@0: NS_ENSURE_TRUE(editor, NS_ERROR_NOT_INITIALIZED); michael@0: michael@0: return ToggleState(editor); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsBaseStateUpdatingCommand::DoCommandParams(const char *aCommandName, michael@0: nsICommandParams *aParams, michael@0: nsISupports *refCon) michael@0: { michael@0: return DoCommand(aCommandName, refCon); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsBaseStateUpdatingCommand::GetCommandStateParams(const char *aCommandName, michael@0: nsICommandParams *aParams, michael@0: nsISupports *refCon) michael@0: { michael@0: nsCOMPtr editor = do_QueryInterface(refCon); michael@0: if (editor) michael@0: return GetCurrentState(editor, aParams); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsPasteNoFormattingCommand::IsCommandEnabled(const char * aCommandName, michael@0: nsISupports *refCon, michael@0: bool *outCmdEnabled) michael@0: { michael@0: NS_ENSURE_ARG_POINTER(outCmdEnabled); michael@0: *outCmdEnabled = false; michael@0: michael@0: // This command is only implemented by nsIHTMLEditor, since michael@0: // pasting in a plaintext editor automatically only supplies michael@0: // "unformatted" text michael@0: nsCOMPtr htmlEditor = do_QueryInterface(refCon); michael@0: NS_ENSURE_TRUE(htmlEditor, NS_ERROR_NOT_IMPLEMENTED); michael@0: michael@0: nsCOMPtr editor = do_QueryInterface(htmlEditor); michael@0: NS_ENSURE_TRUE(editor, NS_ERROR_INVALID_ARG); michael@0: michael@0: return editor->CanPaste(nsIClipboard::kGlobalClipboard, outCmdEnabled); michael@0: } michael@0: michael@0: michael@0: NS_IMETHODIMP michael@0: nsPasteNoFormattingCommand::DoCommand(const char *aCommandName, michael@0: nsISupports *refCon) michael@0: { michael@0: nsCOMPtr htmlEditor = do_QueryInterface(refCon); michael@0: NS_ENSURE_TRUE(htmlEditor, NS_ERROR_NOT_IMPLEMENTED); michael@0: michael@0: return htmlEditor->PasteNoFormatting(nsIClipboard::kGlobalClipboard); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsPasteNoFormattingCommand::DoCommandParams(const char *aCommandName, michael@0: nsICommandParams *aParams, michael@0: nsISupports *refCon) michael@0: { michael@0: return DoCommand(aCommandName, refCon); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsPasteNoFormattingCommand::GetCommandStateParams(const char *aCommandName, michael@0: nsICommandParams *aParams, michael@0: nsISupports *refCon) michael@0: { michael@0: NS_ENSURE_ARG_POINTER(aParams); michael@0: michael@0: bool enabled = false; michael@0: nsresult rv = IsCommandEnabled(aCommandName, refCon, &enabled); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: return aParams->SetBooleanValue(STATE_ENABLED, enabled); michael@0: } michael@0: michael@0: nsStyleUpdatingCommand::nsStyleUpdatingCommand(nsIAtom* aTagName) michael@0: : nsBaseStateUpdatingCommand(aTagName) michael@0: { michael@0: } michael@0: michael@0: nsresult michael@0: nsStyleUpdatingCommand::GetCurrentState(nsIEditor *aEditor, michael@0: nsICommandParams *aParams) michael@0: { michael@0: NS_ASSERTION(aEditor, "Need editor here"); michael@0: nsCOMPtr htmlEditor = do_QueryInterface(aEditor); michael@0: NS_ENSURE_TRUE(htmlEditor, NS_ERROR_NOT_INITIALIZED); michael@0: michael@0: bool firstOfSelectionHasProp = false; michael@0: bool anyOfSelectionHasProp = false; michael@0: bool allOfSelectionHasProp = false; michael@0: michael@0: nsresult rv = htmlEditor->GetInlineProperty(mTagName, EmptyString(), michael@0: EmptyString(), michael@0: &firstOfSelectionHasProp, michael@0: &anyOfSelectionHasProp, michael@0: &allOfSelectionHasProp); michael@0: michael@0: aParams->SetBooleanValue(STATE_ENABLED, NS_SUCCEEDED(rv)); michael@0: aParams->SetBooleanValue(STATE_ALL, allOfSelectionHasProp); michael@0: aParams->SetBooleanValue(STATE_ANY, anyOfSelectionHasProp); michael@0: aParams->SetBooleanValue(STATE_MIXED, anyOfSelectionHasProp michael@0: && !allOfSelectionHasProp); michael@0: aParams->SetBooleanValue(STATE_BEGIN, firstOfSelectionHasProp); michael@0: aParams->SetBooleanValue(STATE_END, allOfSelectionHasProp);//not completely accurate michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsresult michael@0: nsStyleUpdatingCommand::ToggleState(nsIEditor *aEditor) michael@0: { michael@0: nsCOMPtr htmlEditor = do_QueryInterface(aEditor); michael@0: NS_ENSURE_TRUE(htmlEditor, NS_ERROR_NO_INTERFACE); michael@0: michael@0: //create some params now... michael@0: nsresult rv; michael@0: nsCOMPtr params = michael@0: do_CreateInstance(NS_COMMAND_PARAMS_CONTRACTID,&rv); michael@0: if (NS_FAILED(rv) || !params) michael@0: return rv; michael@0: michael@0: // tags "href" and "name" are special cases in the core editor michael@0: // they are used to remove named anchor/link and shouldn't be used for insertion michael@0: bool doTagRemoval; michael@0: if (mTagName == nsGkAtoms::href || mTagName == nsGkAtoms::name) { michael@0: doTagRemoval = true; michael@0: } else { michael@0: // check current selection; set doTagRemoval if formatting should be removed michael@0: rv = GetCurrentState(aEditor, params); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: rv = params->GetBooleanValue(STATE_ALL, &doTagRemoval); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: } michael@0: michael@0: if (doTagRemoval) { michael@0: // Also remove equivalent properties (bug 317093) michael@0: if (mTagName == nsGkAtoms::b) { michael@0: rv = RemoveTextProperty(htmlEditor, NS_LITERAL_STRING("strong")); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: } else if (mTagName == nsGkAtoms::i) { michael@0: rv = RemoveTextProperty(htmlEditor, NS_LITERAL_STRING("em")); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: } else if (mTagName == nsGkAtoms::strike) { michael@0: rv = RemoveTextProperty(htmlEditor, NS_LITERAL_STRING("s")); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: } michael@0: michael@0: rv = RemoveTextProperty(htmlEditor, nsDependentAtomString(mTagName)); michael@0: } else { michael@0: // Superscript and Subscript styles are mutually exclusive michael@0: aEditor->BeginTransaction(); michael@0: michael@0: nsDependentAtomString tagName(mTagName); michael@0: if (mTagName == nsGkAtoms::sub || mTagName == nsGkAtoms::sup) { michael@0: rv = RemoveTextProperty(htmlEditor, tagName); michael@0: } michael@0: if (NS_SUCCEEDED(rv)) michael@0: rv = SetTextProperty(htmlEditor, tagName); michael@0: michael@0: aEditor->EndTransaction(); michael@0: } michael@0: michael@0: return rv; michael@0: } michael@0: michael@0: nsListCommand::nsListCommand(nsIAtom* aTagName) michael@0: : nsBaseStateUpdatingCommand(aTagName) michael@0: { michael@0: } michael@0: michael@0: nsresult michael@0: nsListCommand::GetCurrentState(nsIEditor* aEditor, nsICommandParams* aParams) michael@0: { michael@0: NS_ASSERTION(aEditor, "Need editor here"); michael@0: nsCOMPtr htmlEditor = do_QueryInterface(aEditor); michael@0: NS_ENSURE_TRUE(htmlEditor, NS_ERROR_NO_INTERFACE); michael@0: michael@0: bool bMixed; michael@0: nsAutoString localName; michael@0: nsresult rv = GetListState(htmlEditor, &bMixed, localName); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: bool inList = mTagName->Equals(localName); michael@0: aParams->SetBooleanValue(STATE_ALL, !bMixed && inList); michael@0: aParams->SetBooleanValue(STATE_MIXED, bMixed); michael@0: aParams->SetBooleanValue(STATE_ENABLED, true); michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsresult michael@0: nsListCommand::ToggleState(nsIEditor *aEditor) michael@0: { michael@0: nsCOMPtr editor = do_QueryInterface(aEditor); michael@0: NS_ENSURE_TRUE(editor, NS_NOINTERFACE); michael@0: michael@0: nsresult rv; michael@0: nsCOMPtr params = michael@0: do_CreateInstance(NS_COMMAND_PARAMS_CONTRACTID,&rv); michael@0: if (NS_FAILED(rv) || !params) michael@0: return rv; michael@0: michael@0: rv = GetCurrentState(aEditor, params); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: bool inList; michael@0: rv = params->GetBooleanValue(STATE_ALL,&inList); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: nsDependentAtomString listType(mTagName); michael@0: if (inList) { michael@0: rv = editor->RemoveList(listType); michael@0: } else { michael@0: rv = editor->MakeOrChangeList(listType, false, EmptyString()); michael@0: } michael@0: michael@0: return rv; michael@0: } michael@0: michael@0: nsListItemCommand::nsListItemCommand(nsIAtom* aTagName) michael@0: : nsBaseStateUpdatingCommand(aTagName) michael@0: { michael@0: } michael@0: michael@0: nsresult michael@0: nsListItemCommand::GetCurrentState(nsIEditor* aEditor, michael@0: nsICommandParams *aParams) michael@0: { michael@0: NS_ASSERTION(aEditor, "Need editor here"); michael@0: // 39584 michael@0: nsCOMPtr htmlEditor = do_QueryInterface(aEditor); michael@0: NS_ENSURE_TRUE(htmlEditor, NS_NOINTERFACE); michael@0: michael@0: bool bMixed, bLI, bDT, bDD; michael@0: nsresult rv = htmlEditor->GetListItemState(&bMixed, &bLI, &bDT, &bDD); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: bool inList = false; michael@0: if (!bMixed) michael@0: { michael@0: if (bLI) { michael@0: inList = mTagName == nsGkAtoms::li; michael@0: } else if (bDT) { michael@0: inList = mTagName == nsGkAtoms::dt; michael@0: } else if (bDD) { michael@0: inList = mTagName == nsGkAtoms::dd; michael@0: } michael@0: } michael@0: michael@0: aParams->SetBooleanValue(STATE_ALL, !bMixed && inList); michael@0: aParams->SetBooleanValue(STATE_MIXED, bMixed); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsresult michael@0: nsListItemCommand::ToggleState(nsIEditor *aEditor) michael@0: { michael@0: NS_ASSERTION(aEditor, "Need editor here"); michael@0: nsCOMPtr htmlEditor = do_QueryInterface(aEditor); michael@0: NS_ENSURE_TRUE(htmlEditor, NS_ERROR_NOT_INITIALIZED); michael@0: michael@0: bool inList; michael@0: // Need to use mTagName???? michael@0: nsresult rv; michael@0: nsCOMPtr params = michael@0: do_CreateInstance(NS_COMMAND_PARAMS_CONTRACTID,&rv); michael@0: if (NS_FAILED(rv) || !params) michael@0: return rv; michael@0: rv = GetCurrentState(aEditor, params); michael@0: rv = params->GetBooleanValue(STATE_ALL,&inList); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: if (inList) { michael@0: // To remove a list, first get what kind of list we're in michael@0: bool bMixed; michael@0: nsAutoString localName; michael@0: rv = GetListState(htmlEditor, &bMixed, localName); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: if (localName.IsEmpty() || bMixed) { michael@0: return rv; michael@0: } michael@0: return htmlEditor->RemoveList(localName); michael@0: } michael@0: michael@0: // Set to the requested paragraph type michael@0: //XXX Note: This actually doesn't work for "LI", michael@0: // but we currently don't use this for non DL lists anyway. michael@0: // Problem: won't this replace any current block paragraph style? michael@0: return htmlEditor->SetParagraphFormat(nsDependentAtomString(mTagName)); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsRemoveListCommand::IsCommandEnabled(const char * aCommandName, michael@0: nsISupports *refCon, michael@0: bool *outCmdEnabled) michael@0: { michael@0: *outCmdEnabled = false; michael@0: nsCOMPtr editor = do_QueryInterface(refCon); michael@0: NS_ENSURE_TRUE(editor, NS_OK); michael@0: michael@0: bool isEditable = false; michael@0: nsresult rv = editor->GetIsSelectionEditable(&isEditable); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: if (!isEditable) { michael@0: return NS_OK; michael@0: } michael@0: michael@0: // It is enabled if we are in any list type michael@0: nsCOMPtr htmlEditor = do_QueryInterface(refCon); michael@0: NS_ENSURE_TRUE(htmlEditor, NS_ERROR_NO_INTERFACE); michael@0: michael@0: bool bMixed; michael@0: nsAutoString localName; michael@0: rv = GetListState(htmlEditor, &bMixed, localName); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: *outCmdEnabled = bMixed || !localName.IsEmpty(); michael@0: return NS_OK; michael@0: } michael@0: michael@0: michael@0: NS_IMETHODIMP michael@0: nsRemoveListCommand::DoCommand(const char *aCommandName, nsISupports *refCon) michael@0: { michael@0: nsCOMPtr editor = do_QueryInterface(refCon); michael@0: michael@0: nsresult rv = NS_OK; michael@0: if (editor) michael@0: { michael@0: // This removes any list type michael@0: rv = editor->RemoveList(EmptyString()); michael@0: } michael@0: michael@0: return rv; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsRemoveListCommand::DoCommandParams(const char *aCommandName, michael@0: nsICommandParams *aParams, michael@0: nsISupports *refCon) michael@0: { michael@0: return DoCommand(aCommandName, refCon); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsRemoveListCommand::GetCommandStateParams(const char *aCommandName, michael@0: nsICommandParams *aParams, michael@0: nsISupports *refCon) michael@0: { michael@0: bool outCmdEnabled = false; michael@0: IsCommandEnabled(aCommandName, refCon, &outCmdEnabled); michael@0: return aParams->SetBooleanValue(STATE_ENABLED,outCmdEnabled); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsIndentCommand::IsCommandEnabled(const char * aCommandName, michael@0: nsISupports *refCon, bool *outCmdEnabled) michael@0: { michael@0: nsCOMPtr editor = do_QueryInterface(refCon); michael@0: if (editor) michael@0: return editor->GetIsSelectionEditable(outCmdEnabled); michael@0: michael@0: *outCmdEnabled = false; michael@0: return NS_OK; michael@0: } michael@0: michael@0: michael@0: NS_IMETHODIMP michael@0: nsIndentCommand::DoCommand(const char *aCommandName, nsISupports *refCon) michael@0: { michael@0: nsCOMPtr editor = do_QueryInterface(refCon); michael@0: michael@0: nsresult rv = NS_OK; michael@0: if (editor) michael@0: { michael@0: rv = editor->Indent(NS_LITERAL_STRING("indent")); michael@0: } michael@0: michael@0: return rv; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsIndentCommand::DoCommandParams(const char *aCommandName, michael@0: nsICommandParams *aParams, michael@0: nsISupports *refCon) michael@0: { michael@0: return DoCommand(aCommandName, refCon); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsIndentCommand::GetCommandStateParams(const char *aCommandName, michael@0: nsICommandParams *aParams, michael@0: nsISupports *refCon) michael@0: { michael@0: bool outCmdEnabled = false; michael@0: IsCommandEnabled(aCommandName, refCon, &outCmdEnabled); michael@0: return aParams->SetBooleanValue(STATE_ENABLED,outCmdEnabled); michael@0: } michael@0: michael@0: michael@0: //OUTDENT michael@0: michael@0: NS_IMETHODIMP michael@0: nsOutdentCommand::IsCommandEnabled(const char * aCommandName, michael@0: nsISupports *refCon, michael@0: bool *outCmdEnabled) michael@0: { michael@0: *outCmdEnabled = false; michael@0: michael@0: nsCOMPtr editor = do_QueryInterface(refCon); michael@0: if (editor) { michael@0: nsresult rv = editor->GetIsSelectionEditable(outCmdEnabled); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: } michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: michael@0: NS_IMETHODIMP michael@0: nsOutdentCommand::DoCommand(const char *aCommandName, nsISupports *refCon) michael@0: { michael@0: nsCOMPtr htmlEditor = do_QueryInterface(refCon); michael@0: if (htmlEditor) michael@0: return htmlEditor->Indent(NS_LITERAL_STRING("outdent")); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsOutdentCommand::DoCommandParams(const char *aCommandName, michael@0: nsICommandParams *aParams, michael@0: nsISupports *refCon) michael@0: { michael@0: return DoCommand(aCommandName, refCon); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsOutdentCommand::GetCommandStateParams(const char *aCommandName, michael@0: nsICommandParams *aParams, michael@0: nsISupports *refCon) michael@0: { michael@0: bool outCmdEnabled = false; michael@0: IsCommandEnabled(aCommandName, refCon, &outCmdEnabled); michael@0: return aParams->SetBooleanValue(STATE_ENABLED,outCmdEnabled); michael@0: } michael@0: michael@0: nsMultiStateCommand::nsMultiStateCommand() michael@0: : nsBaseComposerCommand() michael@0: { michael@0: } michael@0: michael@0: nsMultiStateCommand::~nsMultiStateCommand() michael@0: { michael@0: } michael@0: michael@0: NS_IMPL_ISUPPORTS_INHERITED0(nsMultiStateCommand, nsBaseComposerCommand) michael@0: michael@0: NS_IMETHODIMP michael@0: nsMultiStateCommand::IsCommandEnabled(const char * aCommandName, michael@0: nsISupports *refCon, michael@0: bool *outCmdEnabled) michael@0: { michael@0: nsCOMPtr editor = do_QueryInterface(refCon); michael@0: // should be disabled sometimes, like if the current selection is an image michael@0: if (editor) michael@0: return editor->GetIsSelectionEditable(outCmdEnabled); michael@0: michael@0: *outCmdEnabled = false; michael@0: return NS_OK; michael@0: } michael@0: michael@0: michael@0: NS_IMETHODIMP michael@0: nsMultiStateCommand::DoCommand(const char *aCommandName, nsISupports *refCon) michael@0: { michael@0: #ifdef DEBUG michael@0: printf("who is calling nsMultiStateCommand::DoCommand \ michael@0: (no implementation)? %s\n", aCommandName); michael@0: #endif michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsMultiStateCommand::DoCommandParams(const char *aCommandName, michael@0: nsICommandParams *aParams, michael@0: nsISupports *refCon) michael@0: { michael@0: nsCOMPtr editor = do_QueryInterface(refCon); michael@0: michael@0: nsresult rv = NS_OK; michael@0: if (editor) michael@0: { michael@0: nsAutoString tString; michael@0: michael@0: if (aParams) { michael@0: nsXPIDLCString s; michael@0: rv = aParams->GetCStringValue(STATE_ATTRIBUTE, getter_Copies(s)); michael@0: if (NS_SUCCEEDED(rv)) michael@0: tString.AssignWithConversion(s); michael@0: else michael@0: rv = aParams->GetStringValue(STATE_ATTRIBUTE, tString); michael@0: } michael@0: michael@0: rv = SetState(editor, tString); michael@0: } michael@0: michael@0: return rv; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsMultiStateCommand::GetCommandStateParams(const char *aCommandName, michael@0: nsICommandParams *aParams, michael@0: nsISupports *refCon) michael@0: { michael@0: nsCOMPtr editor = do_QueryInterface(refCon); michael@0: nsresult rv = NS_OK; michael@0: if (editor) michael@0: { michael@0: rv = GetCurrentState(editor, aParams); michael@0: } michael@0: return rv; michael@0: } michael@0: michael@0: nsParagraphStateCommand::nsParagraphStateCommand() michael@0: : nsMultiStateCommand() michael@0: { michael@0: } michael@0: michael@0: nsresult michael@0: nsParagraphStateCommand::GetCurrentState(nsIEditor *aEditor, michael@0: nsICommandParams *aParams) michael@0: { michael@0: NS_ASSERTION(aEditor, "Need an editor here"); michael@0: michael@0: nsCOMPtr htmlEditor = do_QueryInterface(aEditor); michael@0: NS_ENSURE_TRUE(htmlEditor, NS_ERROR_FAILURE); michael@0: michael@0: bool outMixed; michael@0: nsAutoString outStateString; michael@0: nsresult rv = htmlEditor->GetParagraphState(&outMixed, outStateString); michael@0: if (NS_SUCCEEDED(rv)) michael@0: { michael@0: nsAutoCString tOutStateString; michael@0: tOutStateString.AssignWithConversion(outStateString); michael@0: aParams->SetBooleanValue(STATE_MIXED,outMixed); michael@0: aParams->SetCStringValue(STATE_ATTRIBUTE, tOutStateString.get()); michael@0: } michael@0: return rv; michael@0: } michael@0: michael@0: michael@0: nsresult michael@0: nsParagraphStateCommand::SetState(nsIEditor *aEditor, nsString& newState) michael@0: { michael@0: NS_ASSERTION(aEditor, "Need an editor here"); michael@0: nsCOMPtr htmlEditor = do_QueryInterface(aEditor); michael@0: NS_ENSURE_TRUE(htmlEditor, NS_ERROR_FAILURE); michael@0: michael@0: return htmlEditor->SetParagraphFormat(newState); michael@0: } michael@0: michael@0: nsFontFaceStateCommand::nsFontFaceStateCommand() michael@0: : nsMultiStateCommand() michael@0: { michael@0: } michael@0: michael@0: nsresult michael@0: nsFontFaceStateCommand::GetCurrentState(nsIEditor *aEditor, michael@0: nsICommandParams *aParams) michael@0: { michael@0: NS_ASSERTION(aEditor, "Need an editor here"); michael@0: nsCOMPtr htmlEditor = do_QueryInterface(aEditor); michael@0: NS_ENSURE_TRUE(htmlEditor, NS_ERROR_FAILURE); michael@0: michael@0: nsAutoString outStateString; michael@0: bool outMixed; michael@0: nsresult rv = htmlEditor->GetFontFaceState(&outMixed, outStateString); michael@0: if (NS_SUCCEEDED(rv)) michael@0: { michael@0: aParams->SetBooleanValue(STATE_MIXED,outMixed); michael@0: aParams->SetCStringValue(STATE_ATTRIBUTE, NS_ConvertUTF16toUTF8(outStateString).get()); michael@0: } michael@0: return rv; michael@0: } michael@0: michael@0: michael@0: nsresult michael@0: nsFontFaceStateCommand::SetState(nsIEditor *aEditor, nsString& newState) michael@0: { michael@0: NS_ASSERTION(aEditor, "Need an editor here"); michael@0: nsCOMPtr htmlEditor = do_QueryInterface(aEditor); michael@0: NS_ENSURE_TRUE(htmlEditor, NS_ERROR_FAILURE); michael@0: michael@0: if (newState.EqualsLiteral("tt")) { michael@0: // The old "teletype" attribute michael@0: nsresult rv = htmlEditor->SetInlineProperty(nsGkAtoms::tt, EmptyString(), michael@0: EmptyString()); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: // Clear existing font face michael@0: return htmlEditor->RemoveInlineProperty(nsGkAtoms::font, michael@0: NS_LITERAL_STRING("face")); michael@0: } michael@0: michael@0: // Remove any existing TT nodes michael@0: nsresult rv = htmlEditor->RemoveInlineProperty(nsGkAtoms::tt, EmptyString()); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: if (newState.IsEmpty() || newState.EqualsLiteral("normal")) { michael@0: return htmlEditor->RemoveInlineProperty(nsGkAtoms::font, michael@0: NS_LITERAL_STRING("face")); michael@0: } michael@0: michael@0: return htmlEditor->SetInlineProperty(nsGkAtoms::font, michael@0: NS_LITERAL_STRING("face"), newState); michael@0: } michael@0: michael@0: nsFontSizeStateCommand::nsFontSizeStateCommand() michael@0: : nsMultiStateCommand() michael@0: { michael@0: } michael@0: michael@0: // nsAutoCString tOutStateString; michael@0: // tOutStateString.AssignWithConversion(outStateString); michael@0: nsresult michael@0: nsFontSizeStateCommand::GetCurrentState(nsIEditor *aEditor, michael@0: nsICommandParams *aParams) michael@0: { michael@0: NS_ASSERTION(aEditor, "Need an editor here"); michael@0: nsCOMPtr htmlEditor = do_QueryInterface(aEditor); michael@0: NS_ENSURE_TRUE(htmlEditor, NS_ERROR_INVALID_ARG); michael@0: michael@0: nsAutoString outStateString; michael@0: nsCOMPtr fontAtom = do_GetAtom("font"); michael@0: bool firstHas, anyHas, allHas; michael@0: nsresult rv = htmlEditor->GetInlinePropertyWithAttrValue(fontAtom, michael@0: NS_LITERAL_STRING("size"), michael@0: EmptyString(), michael@0: &firstHas, &anyHas, &allHas, michael@0: outStateString); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: nsAutoCString tOutStateString; michael@0: tOutStateString.AssignWithConversion(outStateString); michael@0: aParams->SetBooleanValue(STATE_MIXED, anyHas && !allHas); michael@0: aParams->SetCStringValue(STATE_ATTRIBUTE, tOutStateString.get()); michael@0: aParams->SetBooleanValue(STATE_ENABLED, true); michael@0: michael@0: return rv; michael@0: } michael@0: michael@0: michael@0: // acceptable values for "newState" are: michael@0: // -2 michael@0: // -1 michael@0: // 0 michael@0: // +1 michael@0: // +2 michael@0: // +3 michael@0: // medium michael@0: // normal michael@0: nsresult michael@0: nsFontSizeStateCommand::SetState(nsIEditor *aEditor, nsString& newState) michael@0: { michael@0: NS_ASSERTION(aEditor, "Need an editor here"); michael@0: nsCOMPtr htmlEditor = do_QueryInterface(aEditor); michael@0: NS_ENSURE_TRUE(htmlEditor, NS_ERROR_INVALID_ARG); michael@0: michael@0: if (!newState.IsEmpty() && michael@0: !newState.EqualsLiteral("normal") && michael@0: !newState.EqualsLiteral("medium")) { michael@0: return htmlEditor->SetInlineProperty(nsGkAtoms::font, michael@0: NS_LITERAL_STRING("size"), newState); michael@0: } michael@0: michael@0: // remove any existing font size, big or small michael@0: nsresult rv = htmlEditor->RemoveInlineProperty(nsGkAtoms::font, michael@0: NS_LITERAL_STRING("size")); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: rv = htmlEditor->RemoveInlineProperty(nsGkAtoms::big, EmptyString()); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: return htmlEditor->RemoveInlineProperty(nsGkAtoms::small, EmptyString()); michael@0: } michael@0: michael@0: nsFontColorStateCommand::nsFontColorStateCommand() michael@0: : nsMultiStateCommand() michael@0: { michael@0: } michael@0: michael@0: nsresult michael@0: nsFontColorStateCommand::GetCurrentState(nsIEditor *aEditor, michael@0: nsICommandParams *aParams) michael@0: { michael@0: NS_ASSERTION(aEditor, "Need an editor here"); michael@0: michael@0: nsCOMPtr htmlEditor = do_QueryInterface(aEditor); michael@0: NS_ENSURE_TRUE(htmlEditor, NS_ERROR_FAILURE); michael@0: michael@0: bool outMixed; michael@0: nsAutoString outStateString; michael@0: nsresult rv = htmlEditor->GetFontColorState(&outMixed, outStateString); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: nsAutoCString tOutStateString; michael@0: tOutStateString.AssignWithConversion(outStateString); michael@0: aParams->SetBooleanValue(STATE_MIXED, outMixed); michael@0: aParams->SetCStringValue(STATE_ATTRIBUTE, tOutStateString.get()); michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsresult michael@0: nsFontColorStateCommand::SetState(nsIEditor *aEditor, nsString& newState) michael@0: { michael@0: NS_ASSERTION(aEditor, "Need an editor here"); michael@0: nsCOMPtr htmlEditor = do_QueryInterface(aEditor); michael@0: NS_ENSURE_TRUE(htmlEditor, NS_ERROR_FAILURE); michael@0: michael@0: if (newState.IsEmpty() || newState.EqualsLiteral("normal")) { michael@0: return htmlEditor->RemoveInlineProperty(nsGkAtoms::font, michael@0: NS_LITERAL_STRING("color")); michael@0: } michael@0: michael@0: return htmlEditor->SetInlineProperty(nsGkAtoms::font, michael@0: NS_LITERAL_STRING("color"), newState); michael@0: } michael@0: michael@0: nsHighlightColorStateCommand::nsHighlightColorStateCommand() michael@0: : nsMultiStateCommand() michael@0: { michael@0: } michael@0: michael@0: nsresult michael@0: nsHighlightColorStateCommand::GetCurrentState(nsIEditor *aEditor, michael@0: nsICommandParams *aParams) michael@0: { michael@0: NS_ASSERTION(aEditor, "Need an editor here"); michael@0: nsCOMPtr htmlEditor = do_QueryInterface(aEditor); michael@0: NS_ENSURE_TRUE(htmlEditor, NS_ERROR_FAILURE); michael@0: michael@0: bool outMixed; michael@0: nsAutoString outStateString; michael@0: nsresult rv = htmlEditor->GetHighlightColorState(&outMixed, outStateString); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: nsAutoCString tOutStateString; michael@0: tOutStateString.AssignWithConversion(outStateString); michael@0: aParams->SetBooleanValue(STATE_MIXED, outMixed); michael@0: aParams->SetCStringValue(STATE_ATTRIBUTE, tOutStateString.get()); michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsresult michael@0: nsHighlightColorStateCommand::SetState(nsIEditor *aEditor, nsString& newState) michael@0: { michael@0: NS_ASSERTION(aEditor, "Need an editor here"); michael@0: nsCOMPtr htmlEditor = do_QueryInterface(aEditor); michael@0: NS_ENSURE_TRUE(htmlEditor, NS_ERROR_FAILURE); michael@0: michael@0: if (newState.IsEmpty() || newState.EqualsLiteral("normal")) { michael@0: return htmlEditor->RemoveInlineProperty(nsGkAtoms::font, michael@0: NS_LITERAL_STRING("bgcolor")); michael@0: } michael@0: michael@0: return htmlEditor->SetInlineProperty(nsGkAtoms::font, michael@0: NS_LITERAL_STRING("bgcolor"), michael@0: newState); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsHighlightColorStateCommand::IsCommandEnabled(const char * aCommandName, michael@0: nsISupports *refCon, michael@0: bool *outCmdEnabled) michael@0: { michael@0: nsCOMPtr editor = do_QueryInterface(refCon); michael@0: if (editor) michael@0: return editor->GetIsSelectionEditable(outCmdEnabled); michael@0: michael@0: *outCmdEnabled = false; michael@0: return NS_OK; michael@0: } michael@0: michael@0: michael@0: nsBackgroundColorStateCommand::nsBackgroundColorStateCommand() michael@0: : nsMultiStateCommand() michael@0: { michael@0: } michael@0: michael@0: nsresult michael@0: nsBackgroundColorStateCommand::GetCurrentState(nsIEditor *aEditor, michael@0: nsICommandParams *aParams) michael@0: { michael@0: NS_ASSERTION(aEditor, "Need an editor here"); michael@0: michael@0: nsCOMPtr htmlEditor = do_QueryInterface(aEditor); michael@0: NS_ENSURE_TRUE(htmlEditor, NS_ERROR_FAILURE); michael@0: michael@0: bool outMixed; michael@0: nsAutoString outStateString; michael@0: nsresult rv = htmlEditor->GetBackgroundColorState(&outMixed, outStateString); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: nsAutoCString tOutStateString; michael@0: tOutStateString.AssignWithConversion(outStateString); michael@0: aParams->SetBooleanValue(STATE_MIXED, outMixed); michael@0: aParams->SetCStringValue(STATE_ATTRIBUTE, tOutStateString.get()); michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsresult michael@0: nsBackgroundColorStateCommand::SetState(nsIEditor *aEditor, nsString& newState) michael@0: { michael@0: NS_ASSERTION(aEditor, "Need an editor here"); michael@0: michael@0: nsCOMPtr htmlEditor = do_QueryInterface(aEditor); michael@0: NS_ENSURE_TRUE(htmlEditor, NS_ERROR_FAILURE); michael@0: michael@0: return htmlEditor->SetBackgroundColor(newState); michael@0: } michael@0: michael@0: nsAlignCommand::nsAlignCommand() michael@0: : nsMultiStateCommand() michael@0: { michael@0: } michael@0: michael@0: nsresult michael@0: nsAlignCommand::GetCurrentState(nsIEditor *aEditor, nsICommandParams *aParams) michael@0: { michael@0: NS_ASSERTION(aEditor, "Need an editor here"); michael@0: michael@0: nsCOMPtr htmlEditor = do_QueryInterface(aEditor); michael@0: NS_ENSURE_TRUE(htmlEditor, NS_ERROR_FAILURE); michael@0: michael@0: nsIHTMLEditor::EAlignment firstAlign; michael@0: bool outMixed; michael@0: nsresult rv = htmlEditor->GetAlignment(&outMixed, &firstAlign); michael@0: michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: nsAutoString outStateString; michael@0: switch (firstAlign) michael@0: { michael@0: default: michael@0: case nsIHTMLEditor::eLeft: michael@0: outStateString.AssignLiteral("left"); michael@0: break; michael@0: michael@0: case nsIHTMLEditor::eCenter: michael@0: outStateString.AssignLiteral("center"); michael@0: break; michael@0: michael@0: case nsIHTMLEditor::eRight: michael@0: outStateString.AssignLiteral("right"); michael@0: break; michael@0: michael@0: case nsIHTMLEditor::eJustify: michael@0: outStateString.AssignLiteral("justify"); michael@0: break; michael@0: } michael@0: nsAutoCString tOutStateString; michael@0: tOutStateString.AssignWithConversion(outStateString); michael@0: aParams->SetBooleanValue(STATE_MIXED,outMixed); michael@0: aParams->SetCStringValue(STATE_ATTRIBUTE, tOutStateString.get()); michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsresult michael@0: nsAlignCommand::SetState(nsIEditor *aEditor, nsString& newState) michael@0: { michael@0: NS_ASSERTION(aEditor, "Need an editor here"); michael@0: michael@0: nsCOMPtr htmlEditor = do_QueryInterface(aEditor); michael@0: NS_ENSURE_TRUE(htmlEditor, NS_ERROR_FAILURE); michael@0: michael@0: return htmlEditor->Align(newState); michael@0: } michael@0: michael@0: nsAbsolutePositioningCommand::nsAbsolutePositioningCommand() michael@0: : nsBaseStateUpdatingCommand(nsGkAtoms::_empty) michael@0: { michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsAbsolutePositioningCommand::IsCommandEnabled(const char * aCommandName, michael@0: nsISupports *aCommandRefCon, michael@0: bool *outCmdEnabled) michael@0: { michael@0: nsCOMPtr editor = do_QueryInterface(aCommandRefCon); michael@0: nsCOMPtr htmlEditor = do_QueryInterface(aCommandRefCon); michael@0: if (htmlEditor) michael@0: { michael@0: bool isEditable = false; michael@0: nsresult rv = editor->GetIsSelectionEditable(&isEditable); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: if (isEditable) michael@0: return htmlEditor->GetAbsolutePositioningEnabled(outCmdEnabled); michael@0: } michael@0: michael@0: *outCmdEnabled = false; michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsresult michael@0: nsAbsolutePositioningCommand::GetCurrentState(nsIEditor *aEditor, nsICommandParams *aParams) michael@0: { michael@0: NS_ASSERTION(aEditor, "Need an editor here"); michael@0: michael@0: nsCOMPtr htmlEditor = do_QueryInterface(aEditor); michael@0: NS_ENSURE_TRUE(htmlEditor, NS_ERROR_FAILURE); michael@0: michael@0: bool isEnabled; michael@0: htmlEditor->GetAbsolutePositioningEnabled(&isEnabled); michael@0: if (!isEnabled) { michael@0: aParams->SetBooleanValue(STATE_MIXED,false); michael@0: aParams->SetCStringValue(STATE_ATTRIBUTE, ""); michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsCOMPtr elt; michael@0: nsresult rv = htmlEditor->GetAbsolutelyPositionedSelectionContainer(getter_AddRefs(elt)); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: nsAutoString outStateString; michael@0: if (elt) michael@0: outStateString.AssignLiteral("absolute"); michael@0: michael@0: aParams->SetBooleanValue(STATE_MIXED,false); michael@0: aParams->SetCStringValue(STATE_ATTRIBUTE, NS_ConvertUTF16toUTF8(outStateString).get()); michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsresult michael@0: nsAbsolutePositioningCommand::ToggleState(nsIEditor *aEditor) michael@0: { michael@0: NS_ASSERTION(aEditor, "Need an editor here"); michael@0: michael@0: nsCOMPtr htmlEditor = do_QueryInterface(aEditor); michael@0: NS_ENSURE_TRUE(htmlEditor, NS_ERROR_FAILURE); michael@0: michael@0: nsCOMPtr elt; michael@0: nsresult rv = htmlEditor->GetAbsolutelyPositionedSelectionContainer(getter_AddRefs(elt)); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: return htmlEditor->AbsolutePositionSelection(!elt); michael@0: } michael@0: michael@0: michael@0: NS_IMETHODIMP michael@0: nsDecreaseZIndexCommand::IsCommandEnabled(const char * aCommandName, michael@0: nsISupports *refCon, michael@0: bool *outCmdEnabled) michael@0: { michael@0: nsCOMPtr htmlEditor = do_QueryInterface(refCon); michael@0: NS_ENSURE_TRUE(htmlEditor, NS_ERROR_FAILURE); michael@0: michael@0: htmlEditor->GetAbsolutePositioningEnabled(outCmdEnabled); michael@0: if (!(*outCmdEnabled)) michael@0: return NS_OK; michael@0: michael@0: nsCOMPtr positionedElement; michael@0: htmlEditor->GetPositionedElement(getter_AddRefs(positionedElement)); michael@0: *outCmdEnabled = false; michael@0: if (positionedElement) { michael@0: int32_t z; michael@0: nsresult res = htmlEditor->GetElementZIndex(positionedElement, &z); michael@0: NS_ENSURE_SUCCESS(res, res); michael@0: *outCmdEnabled = (z > 0); michael@0: } michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDecreaseZIndexCommand::DoCommand(const char *aCommandName, michael@0: nsISupports *refCon) michael@0: { michael@0: nsCOMPtr htmlEditor = do_QueryInterface(refCon); michael@0: NS_ENSURE_TRUE(htmlEditor, NS_ERROR_NOT_IMPLEMENTED); michael@0: michael@0: return htmlEditor->RelativeChangeZIndex(-1); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDecreaseZIndexCommand::DoCommandParams(const char *aCommandName, michael@0: nsICommandParams *aParams, michael@0: nsISupports *refCon) michael@0: { michael@0: return DoCommand(aCommandName, refCon); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDecreaseZIndexCommand::GetCommandStateParams(const char *aCommandName, michael@0: nsICommandParams *aParams, michael@0: nsISupports *refCon) michael@0: { michael@0: NS_ENSURE_ARG_POINTER(aParams); michael@0: michael@0: bool enabled = false; michael@0: nsresult rv = IsCommandEnabled(aCommandName, refCon, &enabled); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: return aParams->SetBooleanValue(STATE_ENABLED, enabled); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsIncreaseZIndexCommand::IsCommandEnabled(const char * aCommandName, michael@0: nsISupports *refCon, michael@0: bool *outCmdEnabled) michael@0: { michael@0: nsCOMPtr htmlEditor = do_QueryInterface(refCon); michael@0: NS_ENSURE_TRUE(htmlEditor, NS_ERROR_FAILURE); michael@0: michael@0: htmlEditor->GetAbsolutePositioningEnabled(outCmdEnabled); michael@0: if (!(*outCmdEnabled)) michael@0: return NS_OK; michael@0: michael@0: nsCOMPtr positionedElement; michael@0: htmlEditor->GetPositionedElement(getter_AddRefs(positionedElement)); michael@0: *outCmdEnabled = (nullptr != positionedElement); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsIncreaseZIndexCommand::DoCommand(const char *aCommandName, michael@0: nsISupports *refCon) michael@0: { michael@0: nsCOMPtr htmlEditor = do_QueryInterface(refCon); michael@0: NS_ENSURE_TRUE(htmlEditor, NS_ERROR_NOT_IMPLEMENTED); michael@0: michael@0: return htmlEditor->RelativeChangeZIndex(1); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsIncreaseZIndexCommand::DoCommandParams(const char *aCommandName, michael@0: nsICommandParams *aParams, michael@0: nsISupports *refCon) michael@0: { michael@0: return DoCommand(aCommandName, refCon); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsIncreaseZIndexCommand::GetCommandStateParams(const char *aCommandName, michael@0: nsICommandParams *aParams, michael@0: nsISupports *refCon) michael@0: { michael@0: NS_ENSURE_ARG_POINTER(aParams); michael@0: michael@0: bool enabled = false; michael@0: nsresult rv = IsCommandEnabled(aCommandName, refCon, &enabled); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: return aParams->SetBooleanValue(STATE_ENABLED, enabled); michael@0: } michael@0: michael@0: michael@0: NS_IMETHODIMP michael@0: nsRemoveStylesCommand::IsCommandEnabled(const char * aCommandName, michael@0: nsISupports *refCon, michael@0: bool *outCmdEnabled) michael@0: { michael@0: nsCOMPtr editor = do_QueryInterface(refCon); michael@0: // test if we have any styles? michael@0: if (editor) michael@0: return editor->GetIsSelectionEditable(outCmdEnabled); michael@0: michael@0: *outCmdEnabled = false; michael@0: return NS_OK; michael@0: } michael@0: michael@0: michael@0: michael@0: NS_IMETHODIMP michael@0: nsRemoveStylesCommand::DoCommand(const char *aCommandName, michael@0: nsISupports *refCon) michael@0: { michael@0: nsCOMPtr editor = do_QueryInterface(refCon); michael@0: michael@0: nsresult rv = NS_OK; michael@0: if (editor) michael@0: { michael@0: rv = editor->RemoveAllInlineProperties(); michael@0: } michael@0: michael@0: return rv; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsRemoveStylesCommand::DoCommandParams(const char *aCommandName, michael@0: nsICommandParams *aParams, michael@0: nsISupports *refCon) michael@0: { michael@0: return DoCommand(aCommandName, refCon); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsRemoveStylesCommand::GetCommandStateParams(const char *aCommandName, michael@0: nsICommandParams *aParams, michael@0: nsISupports *refCon) michael@0: { michael@0: bool outCmdEnabled = false; michael@0: IsCommandEnabled(aCommandName, refCon, &outCmdEnabled); michael@0: return aParams->SetBooleanValue(STATE_ENABLED,outCmdEnabled); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsIncreaseFontSizeCommand::IsCommandEnabled(const char * aCommandName, michael@0: nsISupports *refCon, michael@0: bool *outCmdEnabled) michael@0: { michael@0: nsCOMPtr editor = do_QueryInterface(refCon); michael@0: // test if we are at max size? michael@0: if (editor) michael@0: return editor->GetIsSelectionEditable(outCmdEnabled); michael@0: michael@0: *outCmdEnabled = false; michael@0: return NS_OK; michael@0: } michael@0: michael@0: michael@0: NS_IMETHODIMP michael@0: nsIncreaseFontSizeCommand::DoCommand(const char *aCommandName, michael@0: nsISupports *refCon) michael@0: { michael@0: nsCOMPtr editor = do_QueryInterface(refCon); michael@0: michael@0: nsresult rv = NS_OK; michael@0: if (editor) michael@0: { michael@0: rv = editor->IncreaseFontSize(); michael@0: } michael@0: michael@0: return rv; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsIncreaseFontSizeCommand::DoCommandParams(const char *aCommandName, michael@0: nsICommandParams *aParams, michael@0: nsISupports *refCon) michael@0: { michael@0: return DoCommand(aCommandName, refCon); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsIncreaseFontSizeCommand::GetCommandStateParams(const char *aCommandName, michael@0: nsICommandParams *aParams, michael@0: nsISupports *refCon) michael@0: { michael@0: bool outCmdEnabled = false; michael@0: IsCommandEnabled(aCommandName, refCon, &outCmdEnabled); michael@0: return aParams->SetBooleanValue(STATE_ENABLED,outCmdEnabled); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDecreaseFontSizeCommand::IsCommandEnabled(const char * aCommandName, michael@0: nsISupports *refCon, michael@0: bool *outCmdEnabled) michael@0: { michael@0: nsCOMPtr editor = do_QueryInterface(refCon); michael@0: // test if we are at min size? michael@0: if (editor) michael@0: return editor->GetIsSelectionEditable(outCmdEnabled); michael@0: michael@0: *outCmdEnabled = false; michael@0: return NS_OK; michael@0: } michael@0: michael@0: michael@0: NS_IMETHODIMP michael@0: nsDecreaseFontSizeCommand::DoCommand(const char *aCommandName, michael@0: nsISupports *refCon) michael@0: { michael@0: nsCOMPtr editor = do_QueryInterface(refCon); michael@0: michael@0: nsresult rv = NS_OK; michael@0: if (editor) michael@0: { michael@0: rv = editor->DecreaseFontSize(); michael@0: } michael@0: michael@0: return rv; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDecreaseFontSizeCommand::DoCommandParams(const char *aCommandName, michael@0: nsICommandParams *aParams, michael@0: nsISupports *refCon) michael@0: { michael@0: return DoCommand(aCommandName, refCon); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsDecreaseFontSizeCommand::GetCommandStateParams(const char *aCommandName, michael@0: nsICommandParams *aParams, michael@0: nsISupports *refCon) michael@0: { michael@0: bool outCmdEnabled = false; michael@0: IsCommandEnabled(aCommandName, refCon, &outCmdEnabled); michael@0: return aParams->SetBooleanValue(STATE_ENABLED,outCmdEnabled); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsInsertHTMLCommand::IsCommandEnabled(const char * aCommandName, michael@0: nsISupports *refCon, michael@0: bool *outCmdEnabled) michael@0: { michael@0: NS_ENSURE_ARG_POINTER(outCmdEnabled); michael@0: nsCOMPtr editor = do_QueryInterface(refCon); michael@0: if (editor) michael@0: return editor->GetIsSelectionEditable(outCmdEnabled); michael@0: michael@0: *outCmdEnabled = false; michael@0: return NS_OK; michael@0: } michael@0: michael@0: michael@0: NS_IMETHODIMP michael@0: nsInsertHTMLCommand::DoCommand(const char *aCommandName, nsISupports *refCon) michael@0: { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsInsertHTMLCommand::DoCommandParams(const char *aCommandName, michael@0: nsICommandParams *aParams, michael@0: nsISupports *refCon) michael@0: { michael@0: NS_ENSURE_ARG_POINTER(aParams); michael@0: NS_ENSURE_ARG_POINTER(refCon); michael@0: michael@0: nsCOMPtr editor = do_QueryInterface(refCon); michael@0: NS_ENSURE_TRUE(editor, NS_ERROR_NOT_IMPLEMENTED); michael@0: michael@0: // Get HTML source string to insert from command params michael@0: nsAutoString html; michael@0: nsresult rv = aParams->GetStringValue(STATE_DATA, html); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: if (!html.IsEmpty()) michael@0: return editor->InsertHTML(html); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsInsertHTMLCommand::GetCommandStateParams(const char *aCommandName, michael@0: nsICommandParams *aParams, michael@0: nsISupports *refCon) michael@0: { michael@0: NS_ENSURE_ARG_POINTER(aParams); michael@0: NS_ENSURE_ARG_POINTER(refCon); michael@0: michael@0: bool outCmdEnabled = false; michael@0: IsCommandEnabled(aCommandName, refCon, &outCmdEnabled); michael@0: return aParams->SetBooleanValue(STATE_ENABLED, outCmdEnabled); michael@0: } michael@0: michael@0: NS_IMPL_ISUPPORTS_INHERITED0(nsInsertTagCommand, nsBaseComposerCommand) michael@0: michael@0: nsInsertTagCommand::nsInsertTagCommand(nsIAtom* aTagName) michael@0: : nsBaseComposerCommand() michael@0: , mTagName(aTagName) michael@0: { michael@0: MOZ_ASSERT(mTagName); michael@0: } michael@0: michael@0: nsInsertTagCommand::~nsInsertTagCommand() michael@0: { michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsInsertTagCommand::IsCommandEnabled(const char * aCommandName, michael@0: nsISupports *refCon, michael@0: bool *outCmdEnabled) michael@0: { michael@0: NS_ENSURE_ARG_POINTER(outCmdEnabled); michael@0: nsCOMPtr editor = do_QueryInterface(refCon); michael@0: if (editor) michael@0: return editor->GetIsSelectionEditable(outCmdEnabled); michael@0: michael@0: *outCmdEnabled = false; michael@0: return NS_OK; michael@0: } michael@0: michael@0: michael@0: // corresponding STATE_ATTRIBUTE is: src (img) and href (a) michael@0: NS_IMETHODIMP michael@0: nsInsertTagCommand::DoCommand(const char *aCmdName, nsISupports *refCon) michael@0: { michael@0: NS_ENSURE_TRUE(mTagName == nsGkAtoms::hr, NS_ERROR_NOT_IMPLEMENTED); michael@0: michael@0: nsCOMPtr editor = do_QueryInterface(refCon); michael@0: NS_ENSURE_TRUE(editor, NS_ERROR_NOT_IMPLEMENTED); michael@0: michael@0: nsCOMPtr domElem; michael@0: nsresult rv = editor->CreateElementWithDefaults( michael@0: nsDependentAtomString(mTagName), getter_AddRefs(domElem)); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: return editor->InsertElementAtSelection(domElem, true); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsInsertTagCommand::DoCommandParams(const char *aCommandName, michael@0: nsICommandParams *aParams, michael@0: nsISupports *refCon) michael@0: { michael@0: NS_ENSURE_ARG_POINTER(refCon); michael@0: michael@0: // inserting an hr shouldn't have an parameters, just call DoCommand for that michael@0: if (mTagName == nsGkAtoms::hr) { michael@0: return DoCommand(aCommandName, refCon); michael@0: } michael@0: michael@0: NS_ENSURE_ARG_POINTER(aParams); michael@0: michael@0: nsCOMPtr editor = do_QueryInterface(refCon); michael@0: NS_ENSURE_TRUE(editor, NS_ERROR_NOT_IMPLEMENTED); michael@0: michael@0: // do we have an href to use for creating link? michael@0: nsXPIDLCString s; michael@0: nsresult rv = aParams->GetCStringValue(STATE_ATTRIBUTE, getter_Copies(s)); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: nsAutoString attrib; attrib.AssignWithConversion(s); michael@0: michael@0: if (attrib.IsEmpty()) michael@0: return NS_ERROR_INVALID_ARG; michael@0: michael@0: // filter out tags we don't know how to insert michael@0: nsAutoString attributeType; michael@0: if (mTagName == nsGkAtoms::a) { michael@0: attributeType.AssignLiteral("href"); michael@0: } else if (mTagName == nsGkAtoms::img) { michael@0: attributeType.AssignLiteral("src"); michael@0: } else { michael@0: return NS_ERROR_NOT_IMPLEMENTED; michael@0: } michael@0: michael@0: nsCOMPtr domElem; michael@0: rv = editor->CreateElementWithDefaults(nsDependentAtomString(mTagName), michael@0: getter_AddRefs(domElem)); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: rv = domElem->SetAttribute(attributeType, attrib); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: // do actual insertion michael@0: if (mTagName == nsGkAtoms::a) michael@0: return editor->InsertLinkAroundSelection(domElem); michael@0: michael@0: return editor->InsertElementAtSelection(domElem, true); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsInsertTagCommand::GetCommandStateParams(const char *aCommandName, michael@0: nsICommandParams *aParams, michael@0: nsISupports *refCon) michael@0: { michael@0: NS_ENSURE_ARG_POINTER(aParams); michael@0: NS_ENSURE_ARG_POINTER(refCon); michael@0: michael@0: bool outCmdEnabled = false; michael@0: IsCommandEnabled(aCommandName, refCon, &outCmdEnabled); michael@0: return aParams->SetBooleanValue(STATE_ENABLED, outCmdEnabled); michael@0: } michael@0: michael@0: michael@0: /****************************/ michael@0: //HELPER METHODS michael@0: /****************************/ michael@0: michael@0: nsresult michael@0: GetListState(nsIHTMLEditor* aEditor, bool* aMixed, nsAString& aLocalName) michael@0: { michael@0: MOZ_ASSERT(aEditor); michael@0: MOZ_ASSERT(aMixed); michael@0: michael@0: *aMixed = false; michael@0: aLocalName.Truncate(); michael@0: michael@0: bool bOL, bUL, bDL; michael@0: nsresult rv = aEditor->GetListState(aMixed, &bOL, &bUL, &bDL); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: if (*aMixed) { michael@0: return NS_OK; michael@0: } michael@0: michael@0: if (bOL) { michael@0: aLocalName.AssignLiteral("ol"); michael@0: } else if (bUL) { michael@0: aLocalName.AssignLiteral("ul"); michael@0: } else if (bDL) { michael@0: aLocalName.AssignLiteral("dl"); michael@0: } michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsresult michael@0: RemoveOneProperty(nsIHTMLEditor* aEditor, const nsAString& aProp) michael@0: { michael@0: MOZ_ASSERT(aEditor); michael@0: michael@0: /// XXX Hack alert! Look in nsIEditProperty.h for this michael@0: nsCOMPtr styleAtom = do_GetAtom(aProp); michael@0: NS_ENSURE_TRUE(styleAtom, NS_ERROR_OUT_OF_MEMORY); michael@0: michael@0: return aEditor->RemoveInlineProperty(styleAtom, EmptyString()); michael@0: } michael@0: michael@0: michael@0: // the name of the attribute here should be the contents of the appropriate michael@0: // tag, e.g. 'b' for bold, 'i' for italics. michael@0: nsresult michael@0: RemoveTextProperty(nsIHTMLEditor* aEditor, const nsAString& aProp) michael@0: { michael@0: MOZ_ASSERT(aEditor); michael@0: michael@0: if (aProp.LowerCaseEqualsLiteral("all")) { michael@0: return aEditor->RemoveAllInlineProperties(); michael@0: } michael@0: michael@0: return RemoveOneProperty(aEditor, aProp); michael@0: } michael@0: michael@0: // the name of the attribute here should be the contents of the appropriate michael@0: // tag, e.g. 'b' for bold, 'i' for italics. michael@0: nsresult michael@0: SetTextProperty(nsIHTMLEditor* aEditor, const nsAString& aProp) michael@0: { michael@0: MOZ_ASSERT(aEditor); michael@0: michael@0: /// XXX Hack alert! Look in nsIEditProperty.h for this michael@0: nsCOMPtr styleAtom = do_GetAtom(aProp); michael@0: NS_ENSURE_TRUE(styleAtom, NS_ERROR_OUT_OF_MEMORY); michael@0: michael@0: return aEditor->SetInlineProperty(styleAtom, EmptyString(), EmptyString()); michael@0: }