editor/composer/src/nsComposerCommands.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 #include <stdio.h>                      // for printf
     9 #include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
    10 #include "nsAString.h"
    11 #include "nsCOMPtr.h"                   // for nsCOMPtr, do_QueryInterface, etc
    12 #include "nsComponentManagerUtils.h"    // for do_CreateInstance
    13 #include "nsComposerCommands.h"
    14 #include "nsDebug.h"                    // for NS_ENSURE_TRUE, etc
    15 #include "nsError.h"                    // for NS_OK, NS_ERROR_FAILURE, etc
    16 #include "nsGkAtoms.h"                  // for nsGkAtoms, nsGkAtoms::font, etc
    17 #include "nsIAtom.h"                    // for nsIAtom, etc
    18 #include "nsIClipboard.h"               // for nsIClipboard, etc
    19 #include "nsICommandParams.h"           // for nsICommandParams, etc
    20 #include "nsID.h"
    21 #include "nsIDOMElement.h"              // for nsIDOMElement
    22 #include "nsIEditor.h"                  // for nsIEditor
    23 #include "nsIHTMLAbsPosEditor.h"        // for nsIHTMLAbsPosEditor
    24 #include "nsIHTMLEditor.h"              // for nsIHTMLEditor, etc
    25 #include "nsLiteralString.h"            // for NS_LITERAL_STRING
    26 #include "nsReadableUtils.h"            // for EmptyString
    27 #include "nsString.h"                   // for nsAutoString, nsString, etc
    28 #include "nsStringFwd.h"                // for nsAFlatString
    30 class nsISupports;
    32 //prototype
    33 nsresult GetListState(nsIHTMLEditor* aEditor, bool* aMixed,
    34                       nsAString& aLocalName);
    35 nsresult RemoveOneProperty(nsIHTMLEditor* aEditor, const nsAString& aProp);
    36 nsresult RemoveTextProperty(nsIHTMLEditor* aEditor, const nsAString& aProp);
    37 nsresult SetTextProperty(nsIHTMLEditor *aEditor, const nsAString& aProp);
    40 //defines
    41 #define STATE_ENABLED  "state_enabled"
    42 #define STATE_ALL "state_all"
    43 #define STATE_ANY "state_any"
    44 #define STATE_MIXED "state_mixed"
    45 #define STATE_BEGIN "state_begin"
    46 #define STATE_END "state_end"
    47 #define STATE_ATTRIBUTE "state_attribute"
    48 #define STATE_DATA "state_data"
    51 nsBaseComposerCommand::nsBaseComposerCommand()
    52 {
    53 }
    55 NS_IMPL_ISUPPORTS(nsBaseComposerCommand, nsIControllerCommand)
    58 nsBaseStateUpdatingCommand::nsBaseStateUpdatingCommand(nsIAtom* aTagName)
    59 : nsBaseComposerCommand()
    60 , mTagName(aTagName)
    61 {
    62   MOZ_ASSERT(mTagName);
    63 }
    65 nsBaseStateUpdatingCommand::~nsBaseStateUpdatingCommand()
    66 {
    67 }
    69 NS_IMPL_ISUPPORTS_INHERITED0(nsBaseStateUpdatingCommand, nsBaseComposerCommand)
    71 NS_IMETHODIMP
    72 nsBaseStateUpdatingCommand::IsCommandEnabled(const char *aCommandName,
    73                                              nsISupports *refCon,
    74                                              bool *outCmdEnabled)
    75 {
    76   nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon);
    77   if (editor)
    78     return editor->GetIsSelectionEditable(outCmdEnabled);
    80   *outCmdEnabled = false;
    81   return NS_OK;
    82 }
    85 NS_IMETHODIMP
    86 nsBaseStateUpdatingCommand::DoCommand(const char *aCommandName,
    87                                       nsISupports *refCon)
    88 {
    89   nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon);
    90   NS_ENSURE_TRUE(editor, NS_ERROR_NOT_INITIALIZED);
    92   return ToggleState(editor);
    93 }
    95 NS_IMETHODIMP
    96 nsBaseStateUpdatingCommand::DoCommandParams(const char *aCommandName,
    97                                             nsICommandParams *aParams,
    98                                             nsISupports *refCon)
    99 {
   100   return DoCommand(aCommandName, refCon);
   101 }
   103 NS_IMETHODIMP
   104 nsBaseStateUpdatingCommand::GetCommandStateParams(const char *aCommandName, 
   105                                                   nsICommandParams *aParams,
   106                                                   nsISupports *refCon)
   107 {
   108   nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon);
   109   if (editor)
   110     return GetCurrentState(editor, aParams);
   112   return NS_OK;
   113 }
   115 NS_IMETHODIMP
   116 nsPasteNoFormattingCommand::IsCommandEnabled(const char * aCommandName, 
   117                                              nsISupports *refCon, 
   118                                              bool *outCmdEnabled)
   119 {
   120   NS_ENSURE_ARG_POINTER(outCmdEnabled);
   121   *outCmdEnabled = false;
   123   // This command is only implemented by nsIHTMLEditor, since
   124   //  pasting in a plaintext editor automatically only supplies 
   125   //  "unformatted" text
   126   nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(refCon);
   127   NS_ENSURE_TRUE(htmlEditor, NS_ERROR_NOT_IMPLEMENTED);
   129   nsCOMPtr<nsIEditor> editor = do_QueryInterface(htmlEditor);
   130   NS_ENSURE_TRUE(editor, NS_ERROR_INVALID_ARG);
   132   return editor->CanPaste(nsIClipboard::kGlobalClipboard, outCmdEnabled);
   133 }
   136 NS_IMETHODIMP
   137 nsPasteNoFormattingCommand::DoCommand(const char *aCommandName,
   138                                       nsISupports *refCon)
   139 {
   140   nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(refCon);
   141   NS_ENSURE_TRUE(htmlEditor, NS_ERROR_NOT_IMPLEMENTED);
   143   return htmlEditor->PasteNoFormatting(nsIClipboard::kGlobalClipboard);
   144 }
   146 NS_IMETHODIMP
   147 nsPasteNoFormattingCommand::DoCommandParams(const char *aCommandName,
   148                                             nsICommandParams *aParams, 
   149                                             nsISupports *refCon)
   150 {
   151   return DoCommand(aCommandName, refCon);
   152 }
   154 NS_IMETHODIMP
   155 nsPasteNoFormattingCommand::GetCommandStateParams(const char *aCommandName,
   156                                                   nsICommandParams *aParams,
   157                                                   nsISupports *refCon)
   158 {
   159   NS_ENSURE_ARG_POINTER(aParams);
   161   bool enabled = false;
   162   nsresult rv = IsCommandEnabled(aCommandName, refCon, &enabled);
   163   NS_ENSURE_SUCCESS(rv, rv);
   165   return aParams->SetBooleanValue(STATE_ENABLED, enabled);
   166 }
   168 nsStyleUpdatingCommand::nsStyleUpdatingCommand(nsIAtom* aTagName)
   169 : nsBaseStateUpdatingCommand(aTagName)
   170 {
   171 }
   173 nsresult
   174 nsStyleUpdatingCommand::GetCurrentState(nsIEditor *aEditor, 
   175                                         nsICommandParams *aParams)
   176 {
   177   NS_ASSERTION(aEditor, "Need editor here");
   178   nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(aEditor);
   179   NS_ENSURE_TRUE(htmlEditor, NS_ERROR_NOT_INITIALIZED);
   181   bool firstOfSelectionHasProp = false;
   182   bool anyOfSelectionHasProp = false;
   183   bool allOfSelectionHasProp = false;
   185   nsresult rv = htmlEditor->GetInlineProperty(mTagName, EmptyString(),
   186                                               EmptyString(),
   187                                               &firstOfSelectionHasProp,
   188                                               &anyOfSelectionHasProp,
   189                                               &allOfSelectionHasProp);
   191   aParams->SetBooleanValue(STATE_ENABLED, NS_SUCCEEDED(rv));
   192   aParams->SetBooleanValue(STATE_ALL, allOfSelectionHasProp);
   193   aParams->SetBooleanValue(STATE_ANY, anyOfSelectionHasProp);
   194   aParams->SetBooleanValue(STATE_MIXED, anyOfSelectionHasProp
   195            && !allOfSelectionHasProp);
   196   aParams->SetBooleanValue(STATE_BEGIN, firstOfSelectionHasProp);
   197   aParams->SetBooleanValue(STATE_END, allOfSelectionHasProp);//not completely accurate
   198   return NS_OK;
   199 }
   201 nsresult
   202 nsStyleUpdatingCommand::ToggleState(nsIEditor *aEditor)
   203 {
   204   nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(aEditor);
   205   NS_ENSURE_TRUE(htmlEditor, NS_ERROR_NO_INTERFACE);
   207   //create some params now...
   208   nsresult rv;
   209   nsCOMPtr<nsICommandParams> params =
   210       do_CreateInstance(NS_COMMAND_PARAMS_CONTRACTID,&rv);
   211   if (NS_FAILED(rv) || !params)
   212     return rv;
   214   // tags "href" and "name" are special cases in the core editor 
   215   // they are used to remove named anchor/link and shouldn't be used for insertion
   216   bool doTagRemoval;
   217   if (mTagName == nsGkAtoms::href || mTagName == nsGkAtoms::name) {
   218     doTagRemoval = true;
   219   } else {
   220     // check current selection; set doTagRemoval if formatting should be removed
   221     rv = GetCurrentState(aEditor, params);
   222     NS_ENSURE_SUCCESS(rv, rv);
   223     rv = params->GetBooleanValue(STATE_ALL, &doTagRemoval);
   224     NS_ENSURE_SUCCESS(rv, rv);
   225   }
   227   if (doTagRemoval) {
   228     // Also remove equivalent properties (bug 317093)
   229     if (mTagName == nsGkAtoms::b) {
   230       rv = RemoveTextProperty(htmlEditor, NS_LITERAL_STRING("strong"));
   231       NS_ENSURE_SUCCESS(rv, rv);
   232     } else if (mTagName == nsGkAtoms::i) {
   233       rv = RemoveTextProperty(htmlEditor, NS_LITERAL_STRING("em"));
   234       NS_ENSURE_SUCCESS(rv, rv);
   235     } else if (mTagName == nsGkAtoms::strike) {
   236       rv = RemoveTextProperty(htmlEditor, NS_LITERAL_STRING("s"));
   237       NS_ENSURE_SUCCESS(rv, rv);
   238     }
   240     rv = RemoveTextProperty(htmlEditor, nsDependentAtomString(mTagName));
   241   } else {
   242     // Superscript and Subscript styles are mutually exclusive
   243     aEditor->BeginTransaction();
   245     nsDependentAtomString tagName(mTagName);
   246     if (mTagName == nsGkAtoms::sub || mTagName == nsGkAtoms::sup) {
   247       rv = RemoveTextProperty(htmlEditor, tagName);
   248     }
   249     if (NS_SUCCEEDED(rv))
   250       rv = SetTextProperty(htmlEditor, tagName);
   252     aEditor->EndTransaction();
   253   }
   255   return rv;
   256 }
   258 nsListCommand::nsListCommand(nsIAtom* aTagName)
   259 : nsBaseStateUpdatingCommand(aTagName)
   260 {
   261 }
   263 nsresult
   264 nsListCommand::GetCurrentState(nsIEditor* aEditor, nsICommandParams* aParams)
   265 {
   266   NS_ASSERTION(aEditor, "Need editor here");
   267   nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(aEditor);
   268   NS_ENSURE_TRUE(htmlEditor, NS_ERROR_NO_INTERFACE);
   270   bool bMixed;
   271   nsAutoString localName;
   272   nsresult rv = GetListState(htmlEditor, &bMixed, localName);
   273   NS_ENSURE_SUCCESS(rv, rv);
   275   bool inList = mTagName->Equals(localName);
   276   aParams->SetBooleanValue(STATE_ALL, !bMixed && inList);
   277   aParams->SetBooleanValue(STATE_MIXED, bMixed);
   278   aParams->SetBooleanValue(STATE_ENABLED, true);
   279   return NS_OK;
   280 }
   282 nsresult
   283 nsListCommand::ToggleState(nsIEditor *aEditor)
   284 {
   285   nsCOMPtr<nsIHTMLEditor> editor = do_QueryInterface(aEditor);
   286   NS_ENSURE_TRUE(editor, NS_NOINTERFACE);
   288   nsresult rv;
   289   nsCOMPtr<nsICommandParams> params =
   290       do_CreateInstance(NS_COMMAND_PARAMS_CONTRACTID,&rv);
   291   if (NS_FAILED(rv) || !params)
   292     return rv;
   294   rv = GetCurrentState(aEditor, params);
   295   NS_ENSURE_SUCCESS(rv, rv);
   297   bool inList;
   298   rv = params->GetBooleanValue(STATE_ALL,&inList);
   299   NS_ENSURE_SUCCESS(rv, rv);
   301   nsDependentAtomString listType(mTagName);
   302   if (inList) {
   303     rv = editor->RemoveList(listType);    
   304   } else {
   305     rv = editor->MakeOrChangeList(listType, false, EmptyString());
   306   }
   308   return rv;
   309 }
   311 nsListItemCommand::nsListItemCommand(nsIAtom* aTagName)
   312 : nsBaseStateUpdatingCommand(aTagName)
   313 {
   314 }
   316 nsresult
   317 nsListItemCommand::GetCurrentState(nsIEditor* aEditor,
   318                                    nsICommandParams *aParams)
   319 {
   320   NS_ASSERTION(aEditor, "Need editor here");
   321   // 39584
   322   nsCOMPtr<nsIHTMLEditor>  htmlEditor = do_QueryInterface(aEditor);
   323   NS_ENSURE_TRUE(htmlEditor, NS_NOINTERFACE);
   325   bool bMixed, bLI, bDT, bDD;
   326   nsresult rv = htmlEditor->GetListItemState(&bMixed, &bLI, &bDT, &bDD);
   327   NS_ENSURE_SUCCESS(rv, rv);
   329   bool inList = false;
   330   if (!bMixed)
   331   {
   332     if (bLI) {
   333       inList = mTagName == nsGkAtoms::li;
   334     } else if (bDT) {
   335       inList = mTagName == nsGkAtoms::dt;
   336     } else if (bDD) {
   337       inList = mTagName == nsGkAtoms::dd;
   338     }
   339   }
   341   aParams->SetBooleanValue(STATE_ALL, !bMixed && inList);
   342   aParams->SetBooleanValue(STATE_MIXED, bMixed);
   344   return NS_OK;
   345 }
   347 nsresult
   348 nsListItemCommand::ToggleState(nsIEditor *aEditor)
   349 {
   350   NS_ASSERTION(aEditor, "Need editor here");
   351   nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(aEditor);
   352   NS_ENSURE_TRUE(htmlEditor, NS_ERROR_NOT_INITIALIZED);
   354   bool inList;
   355   // Need to use mTagName????
   356   nsresult rv;
   357   nsCOMPtr<nsICommandParams> params =
   358       do_CreateInstance(NS_COMMAND_PARAMS_CONTRACTID,&rv);
   359   if (NS_FAILED(rv) || !params)
   360     return rv;
   361   rv = GetCurrentState(aEditor, params);
   362   rv = params->GetBooleanValue(STATE_ALL,&inList);
   363   NS_ENSURE_SUCCESS(rv, rv);
   364   NS_ENSURE_SUCCESS(rv, rv);
   366   if (inList) {
   367     // To remove a list, first get what kind of list we're in
   368     bool bMixed;
   369     nsAutoString localName;
   370     rv = GetListState(htmlEditor, &bMixed, localName);
   371     NS_ENSURE_SUCCESS(rv, rv); 
   372     if (localName.IsEmpty() || bMixed) {
   373       return rv;
   374     }
   375     return htmlEditor->RemoveList(localName);
   376   }
   378   // Set to the requested paragraph type
   379   //XXX Note: This actually doesn't work for "LI",
   380   //    but we currently don't use this for non DL lists anyway.
   381   // Problem: won't this replace any current block paragraph style?
   382   return htmlEditor->SetParagraphFormat(nsDependentAtomString(mTagName));
   383 }
   385 NS_IMETHODIMP
   386 nsRemoveListCommand::IsCommandEnabled(const char * aCommandName,
   387                                       nsISupports *refCon,
   388                                       bool *outCmdEnabled)
   389 {
   390   *outCmdEnabled = false;
   391   nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon);
   392   NS_ENSURE_TRUE(editor, NS_OK);
   394   bool isEditable = false;
   395   nsresult rv = editor->GetIsSelectionEditable(&isEditable);
   396   NS_ENSURE_SUCCESS(rv, rv);
   397   if (!isEditable) {
   398     return NS_OK;
   399   }
   401   // It is enabled if we are in any list type
   402   nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(refCon);
   403   NS_ENSURE_TRUE(htmlEditor, NS_ERROR_NO_INTERFACE);
   405   bool bMixed;
   406   nsAutoString localName;
   407   rv = GetListState(htmlEditor, &bMixed, localName);
   408   NS_ENSURE_SUCCESS(rv, rv);
   410   *outCmdEnabled = bMixed || !localName.IsEmpty();
   411   return NS_OK;
   412 }
   415 NS_IMETHODIMP
   416 nsRemoveListCommand::DoCommand(const char *aCommandName, nsISupports *refCon)
   417 {
   418   nsCOMPtr<nsIHTMLEditor> editor = do_QueryInterface(refCon);
   420   nsresult rv = NS_OK;
   421   if (editor)
   422   {
   423     // This removes any list type
   424     rv = editor->RemoveList(EmptyString());
   425   }
   427   return rv;  
   428 }
   430 NS_IMETHODIMP
   431 nsRemoveListCommand::DoCommandParams(const char *aCommandName, 
   432                                      nsICommandParams *aParams,
   433                                      nsISupports *refCon)
   434 {
   435   return DoCommand(aCommandName, refCon);
   436 }
   438 NS_IMETHODIMP
   439 nsRemoveListCommand::GetCommandStateParams(const char *aCommandName,
   440                                            nsICommandParams *aParams, 
   441                                            nsISupports *refCon)
   442 {
   443   bool outCmdEnabled = false;
   444   IsCommandEnabled(aCommandName, refCon, &outCmdEnabled);
   445   return aParams->SetBooleanValue(STATE_ENABLED,outCmdEnabled);
   446 }
   448 NS_IMETHODIMP
   449 nsIndentCommand::IsCommandEnabled(const char * aCommandName,
   450                                   nsISupports *refCon, bool *outCmdEnabled)
   451 {
   452   nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon);
   453   if (editor)
   454     return editor->GetIsSelectionEditable(outCmdEnabled);
   456   *outCmdEnabled = false;
   457   return NS_OK;
   458 }
   461 NS_IMETHODIMP
   462 nsIndentCommand::DoCommand(const char *aCommandName, nsISupports *refCon)
   463 {
   464   nsCOMPtr<nsIHTMLEditor> editor = do_QueryInterface(refCon);
   466   nsresult rv = NS_OK;
   467   if (editor)
   468   {
   469     rv = editor->Indent(NS_LITERAL_STRING("indent"));
   470   }
   472   return rv;  
   473 }
   475 NS_IMETHODIMP
   476 nsIndentCommand::DoCommandParams(const char *aCommandName,
   477                                  nsICommandParams *aParams,
   478                                  nsISupports *refCon)
   479 {
   480   return DoCommand(aCommandName, refCon);  
   481 }
   483 NS_IMETHODIMP
   484 nsIndentCommand::GetCommandStateParams(const char *aCommandName,
   485                                        nsICommandParams *aParams,
   486                                        nsISupports *refCon)
   487 {
   488   bool outCmdEnabled = false;
   489   IsCommandEnabled(aCommandName, refCon, &outCmdEnabled);
   490   return aParams->SetBooleanValue(STATE_ENABLED,outCmdEnabled);
   491 }
   494 //OUTDENT
   496 NS_IMETHODIMP
   497 nsOutdentCommand::IsCommandEnabled(const char * aCommandName,
   498                                    nsISupports *refCon,
   499                                    bool *outCmdEnabled)
   500 {
   501   *outCmdEnabled = false;
   503   nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon);
   504   if (editor) {
   505     nsresult rv = editor->GetIsSelectionEditable(outCmdEnabled);
   506     NS_ENSURE_SUCCESS(rv, rv);
   507   }
   509   return NS_OK;
   510 }
   513 NS_IMETHODIMP
   514 nsOutdentCommand::DoCommand(const char *aCommandName, nsISupports *refCon)
   515 {
   516   nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(refCon);
   517   if (htmlEditor)
   518     return htmlEditor->Indent(NS_LITERAL_STRING("outdent"));
   520   return NS_OK;  
   521 }
   523 NS_IMETHODIMP
   524 nsOutdentCommand::DoCommandParams(const char *aCommandName,
   525                                   nsICommandParams *aParams, 
   526                                   nsISupports *refCon)
   527 {
   528   return DoCommand(aCommandName, refCon);  
   529 }
   531 NS_IMETHODIMP
   532 nsOutdentCommand::GetCommandStateParams(const char *aCommandName,
   533                                         nsICommandParams *aParams,
   534                                         nsISupports *refCon)
   535 {
   536   bool outCmdEnabled = false;
   537   IsCommandEnabled(aCommandName, refCon, &outCmdEnabled);
   538   return aParams->SetBooleanValue(STATE_ENABLED,outCmdEnabled);
   539 }
   541 nsMultiStateCommand::nsMultiStateCommand()
   542 : nsBaseComposerCommand()
   543 {
   544 }
   546 nsMultiStateCommand::~nsMultiStateCommand()
   547 {
   548 }
   550 NS_IMPL_ISUPPORTS_INHERITED0(nsMultiStateCommand, nsBaseComposerCommand)
   552 NS_IMETHODIMP
   553 nsMultiStateCommand::IsCommandEnabled(const char * aCommandName,
   554                                       nsISupports *refCon,
   555                                       bool *outCmdEnabled)
   556 {
   557   nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon);
   558   // should be disabled sometimes, like if the current selection is an image
   559   if (editor)
   560     return editor->GetIsSelectionEditable(outCmdEnabled);
   562   *outCmdEnabled = false;
   563   return NS_OK; 
   564 }
   567 NS_IMETHODIMP
   568 nsMultiStateCommand::DoCommand(const char *aCommandName, nsISupports *refCon)
   569 {
   570 #ifdef DEBUG
   571   printf("who is calling nsMultiStateCommand::DoCommand \
   572           (no implementation)? %s\n", aCommandName);
   573 #endif
   575   return NS_OK;  
   576 }
   578 NS_IMETHODIMP
   579 nsMultiStateCommand::DoCommandParams(const char *aCommandName,
   580                                      nsICommandParams *aParams,
   581                                      nsISupports *refCon)
   582 {
   583   nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon);
   585   nsresult rv = NS_OK;
   586   if (editor)
   587   {
   588       nsAutoString tString;
   590       if (aParams) {
   591         nsXPIDLCString s;
   592         rv = aParams->GetCStringValue(STATE_ATTRIBUTE, getter_Copies(s));
   593         if (NS_SUCCEEDED(rv))
   594           tString.AssignWithConversion(s);
   595         else
   596           rv = aParams->GetStringValue(STATE_ATTRIBUTE, tString);
   597       }
   599       rv = SetState(editor, tString);
   600   }
   602   return rv;  
   603 }
   605 NS_IMETHODIMP
   606 nsMultiStateCommand::GetCommandStateParams(const char *aCommandName,
   607                                            nsICommandParams *aParams,
   608                                            nsISupports *refCon)
   609 {
   610   nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon);
   611   nsresult rv = NS_OK;
   612   if (editor)
   613   {
   614       rv = GetCurrentState(editor, aParams);
   615   }
   616   return rv;
   617 }
   619 nsParagraphStateCommand::nsParagraphStateCommand()
   620 : nsMultiStateCommand()
   621 {
   622 }
   624 nsresult
   625 nsParagraphStateCommand::GetCurrentState(nsIEditor *aEditor,
   626                                          nsICommandParams *aParams)
   627 {
   628   NS_ASSERTION(aEditor, "Need an editor here");
   630   nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(aEditor);
   631   NS_ENSURE_TRUE(htmlEditor, NS_ERROR_FAILURE);
   633   bool outMixed;
   634   nsAutoString outStateString;
   635   nsresult rv = htmlEditor->GetParagraphState(&outMixed, outStateString);
   636   if (NS_SUCCEEDED(rv))
   637   {
   638     nsAutoCString tOutStateString;
   639     tOutStateString.AssignWithConversion(outStateString);
   640     aParams->SetBooleanValue(STATE_MIXED,outMixed);
   641     aParams->SetCStringValue(STATE_ATTRIBUTE, tOutStateString.get());
   642   }
   643   return rv;
   644 }
   647 nsresult
   648 nsParagraphStateCommand::SetState(nsIEditor *aEditor, nsString& newState)
   649 {
   650   NS_ASSERTION(aEditor, "Need an editor here");
   651   nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(aEditor);
   652   NS_ENSURE_TRUE(htmlEditor, NS_ERROR_FAILURE);
   654   return htmlEditor->SetParagraphFormat(newState);
   655 }
   657 nsFontFaceStateCommand::nsFontFaceStateCommand()
   658 : nsMultiStateCommand()
   659 {
   660 }
   662 nsresult
   663 nsFontFaceStateCommand::GetCurrentState(nsIEditor *aEditor,
   664                                         nsICommandParams *aParams)
   665 {
   666   NS_ASSERTION(aEditor, "Need an editor here");
   667   nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(aEditor);
   668   NS_ENSURE_TRUE(htmlEditor, NS_ERROR_FAILURE);
   670   nsAutoString outStateString;
   671   bool outMixed;
   672   nsresult rv = htmlEditor->GetFontFaceState(&outMixed, outStateString);
   673   if (NS_SUCCEEDED(rv))
   674   {
   675     aParams->SetBooleanValue(STATE_MIXED,outMixed);
   676     aParams->SetCStringValue(STATE_ATTRIBUTE, NS_ConvertUTF16toUTF8(outStateString).get());
   677   }
   678   return rv;
   679 }
   682 nsresult
   683 nsFontFaceStateCommand::SetState(nsIEditor *aEditor, nsString& newState)
   684 {
   685   NS_ASSERTION(aEditor, "Need an editor here");
   686   nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(aEditor);
   687   NS_ENSURE_TRUE(htmlEditor, NS_ERROR_FAILURE);
   689   if (newState.EqualsLiteral("tt")) {
   690     // The old "teletype" attribute
   691     nsresult rv = htmlEditor->SetInlineProperty(nsGkAtoms::tt, EmptyString(),
   692                                                 EmptyString());
   693     NS_ENSURE_SUCCESS(rv, rv);
   694     // Clear existing font face
   695     return htmlEditor->RemoveInlineProperty(nsGkAtoms::font,
   696                                             NS_LITERAL_STRING("face"));
   697   }
   699   // Remove any existing TT nodes
   700   nsresult rv = htmlEditor->RemoveInlineProperty(nsGkAtoms::tt, EmptyString());
   701   NS_ENSURE_SUCCESS(rv, rv);
   703   if (newState.IsEmpty() || newState.EqualsLiteral("normal")) {
   704     return htmlEditor->RemoveInlineProperty(nsGkAtoms::font,
   705                                             NS_LITERAL_STRING("face"));
   706   }
   708   return htmlEditor->SetInlineProperty(nsGkAtoms::font,
   709                                        NS_LITERAL_STRING("face"), newState);
   710 }
   712 nsFontSizeStateCommand::nsFontSizeStateCommand()
   713   : nsMultiStateCommand()
   714 {
   715 }
   717 //  nsAutoCString tOutStateString;
   718 //  tOutStateString.AssignWithConversion(outStateString);
   719 nsresult
   720 nsFontSizeStateCommand::GetCurrentState(nsIEditor *aEditor,
   721                                         nsICommandParams *aParams)
   722 {
   723   NS_ASSERTION(aEditor, "Need an editor here");
   724   nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(aEditor);
   725   NS_ENSURE_TRUE(htmlEditor, NS_ERROR_INVALID_ARG);
   727   nsAutoString outStateString;
   728   nsCOMPtr<nsIAtom> fontAtom = do_GetAtom("font");
   729   bool firstHas, anyHas, allHas;
   730   nsresult rv = htmlEditor->GetInlinePropertyWithAttrValue(fontAtom,
   731                                          NS_LITERAL_STRING("size"),
   732                                          EmptyString(),
   733                                          &firstHas, &anyHas, &allHas,
   734                                          outStateString);
   735   NS_ENSURE_SUCCESS(rv, rv);
   737   nsAutoCString tOutStateString;
   738   tOutStateString.AssignWithConversion(outStateString);
   739   aParams->SetBooleanValue(STATE_MIXED, anyHas && !allHas);
   740   aParams->SetCStringValue(STATE_ATTRIBUTE, tOutStateString.get());
   741   aParams->SetBooleanValue(STATE_ENABLED, true);
   743   return rv;
   744 }
   747 // acceptable values for "newState" are:
   748 //   -2
   749 //   -1
   750 //    0
   751 //   +1
   752 //   +2
   753 //   +3
   754 //   medium
   755 //   normal
   756 nsresult
   757 nsFontSizeStateCommand::SetState(nsIEditor *aEditor, nsString& newState)
   758 {
   759   NS_ASSERTION(aEditor, "Need an editor here");
   760   nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(aEditor);
   761   NS_ENSURE_TRUE(htmlEditor, NS_ERROR_INVALID_ARG);
   763   if (!newState.IsEmpty() &&
   764       !newState.EqualsLiteral("normal") &&
   765       !newState.EqualsLiteral("medium")) {
   766     return htmlEditor->SetInlineProperty(nsGkAtoms::font,
   767                                          NS_LITERAL_STRING("size"), newState);
   768   }
   770   // remove any existing font size, big or small
   771   nsresult rv = htmlEditor->RemoveInlineProperty(nsGkAtoms::font,
   772                                                  NS_LITERAL_STRING("size"));
   773   NS_ENSURE_SUCCESS(rv, rv);
   775   rv = htmlEditor->RemoveInlineProperty(nsGkAtoms::big, EmptyString());
   776   NS_ENSURE_SUCCESS(rv, rv);
   778   return htmlEditor->RemoveInlineProperty(nsGkAtoms::small, EmptyString());
   779 }
   781 nsFontColorStateCommand::nsFontColorStateCommand()
   782 : nsMultiStateCommand()
   783 {
   784 }
   786 nsresult
   787 nsFontColorStateCommand::GetCurrentState(nsIEditor *aEditor,
   788                                          nsICommandParams *aParams)
   789 {
   790   NS_ASSERTION(aEditor, "Need an editor here");
   792   nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(aEditor);
   793   NS_ENSURE_TRUE(htmlEditor, NS_ERROR_FAILURE);
   795   bool outMixed;
   796   nsAutoString outStateString;
   797   nsresult rv = htmlEditor->GetFontColorState(&outMixed, outStateString);
   798   NS_ENSURE_SUCCESS(rv, rv);
   800   nsAutoCString tOutStateString;
   801   tOutStateString.AssignWithConversion(outStateString);
   802   aParams->SetBooleanValue(STATE_MIXED, outMixed);
   803   aParams->SetCStringValue(STATE_ATTRIBUTE, tOutStateString.get());
   804   return NS_OK;
   805 }
   807 nsresult
   808 nsFontColorStateCommand::SetState(nsIEditor *aEditor, nsString& newState)
   809 {
   810   NS_ASSERTION(aEditor, "Need an editor here");
   811   nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(aEditor);
   812   NS_ENSURE_TRUE(htmlEditor, NS_ERROR_FAILURE);
   814   if (newState.IsEmpty() || newState.EqualsLiteral("normal")) {
   815     return htmlEditor->RemoveInlineProperty(nsGkAtoms::font,
   816                                             NS_LITERAL_STRING("color"));
   817   }
   819   return htmlEditor->SetInlineProperty(nsGkAtoms::font,
   820                                        NS_LITERAL_STRING("color"), newState);
   821 }
   823 nsHighlightColorStateCommand::nsHighlightColorStateCommand()
   824 : nsMultiStateCommand()
   825 {
   826 }
   828 nsresult
   829 nsHighlightColorStateCommand::GetCurrentState(nsIEditor *aEditor,
   830                                               nsICommandParams *aParams)
   831 {
   832   NS_ASSERTION(aEditor, "Need an editor here");
   833   nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(aEditor);
   834   NS_ENSURE_TRUE(htmlEditor, NS_ERROR_FAILURE);
   836   bool outMixed;
   837   nsAutoString outStateString;
   838   nsresult rv = htmlEditor->GetHighlightColorState(&outMixed, outStateString);
   839   NS_ENSURE_SUCCESS(rv, rv);
   841   nsAutoCString tOutStateString;
   842   tOutStateString.AssignWithConversion(outStateString);
   843   aParams->SetBooleanValue(STATE_MIXED, outMixed);
   844   aParams->SetCStringValue(STATE_ATTRIBUTE, tOutStateString.get());
   845   return NS_OK;
   846 }
   848 nsresult
   849 nsHighlightColorStateCommand::SetState(nsIEditor *aEditor, nsString& newState)
   850 {
   851   NS_ASSERTION(aEditor, "Need an editor here");
   852   nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(aEditor);
   853   NS_ENSURE_TRUE(htmlEditor, NS_ERROR_FAILURE);
   855   if (newState.IsEmpty() || newState.EqualsLiteral("normal")) {
   856     return htmlEditor->RemoveInlineProperty(nsGkAtoms::font,
   857                                             NS_LITERAL_STRING("bgcolor"));
   858   }
   860   return htmlEditor->SetInlineProperty(nsGkAtoms::font,
   861                                        NS_LITERAL_STRING("bgcolor"),
   862                                        newState);
   863 }
   865 NS_IMETHODIMP
   866 nsHighlightColorStateCommand::IsCommandEnabled(const char * aCommandName,
   867                                                nsISupports *refCon,
   868                                                bool *outCmdEnabled)
   869 {
   870   nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon);
   871   if (editor)
   872     return editor->GetIsSelectionEditable(outCmdEnabled);
   874   *outCmdEnabled = false;
   875   return NS_OK;
   876 }
   879 nsBackgroundColorStateCommand::nsBackgroundColorStateCommand()
   880 : nsMultiStateCommand()
   881 {
   882 }
   884 nsresult
   885 nsBackgroundColorStateCommand::GetCurrentState(nsIEditor *aEditor,
   886                                                nsICommandParams *aParams)
   887 {
   888   NS_ASSERTION(aEditor, "Need an editor here");
   890   nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(aEditor);
   891   NS_ENSURE_TRUE(htmlEditor, NS_ERROR_FAILURE);
   893   bool outMixed;
   894   nsAutoString outStateString;
   895   nsresult rv =  htmlEditor->GetBackgroundColorState(&outMixed, outStateString);
   896   NS_ENSURE_SUCCESS(rv, rv);
   898   nsAutoCString tOutStateString;
   899   tOutStateString.AssignWithConversion(outStateString);
   900   aParams->SetBooleanValue(STATE_MIXED, outMixed);
   901   aParams->SetCStringValue(STATE_ATTRIBUTE, tOutStateString.get());
   902   return NS_OK;
   903 }
   905 nsresult
   906 nsBackgroundColorStateCommand::SetState(nsIEditor *aEditor, nsString& newState)
   907 {
   908   NS_ASSERTION(aEditor, "Need an editor here");
   910   nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(aEditor);
   911   NS_ENSURE_TRUE(htmlEditor, NS_ERROR_FAILURE);
   913   return htmlEditor->SetBackgroundColor(newState);
   914 }
   916 nsAlignCommand::nsAlignCommand()
   917 : nsMultiStateCommand()
   918 {
   919 }
   921 nsresult
   922 nsAlignCommand::GetCurrentState(nsIEditor *aEditor, nsICommandParams *aParams)
   923 {
   924   NS_ASSERTION(aEditor, "Need an editor here");
   926   nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(aEditor);
   927   NS_ENSURE_TRUE(htmlEditor, NS_ERROR_FAILURE);
   929   nsIHTMLEditor::EAlignment firstAlign;
   930   bool outMixed;
   931   nsresult rv = htmlEditor->GetAlignment(&outMixed, &firstAlign);
   933   NS_ENSURE_SUCCESS(rv, rv);
   935   nsAutoString outStateString;
   936   switch (firstAlign)
   937   {
   938     default:
   939     case nsIHTMLEditor::eLeft:
   940       outStateString.AssignLiteral("left");
   941       break;
   943     case nsIHTMLEditor::eCenter:
   944       outStateString.AssignLiteral("center");
   945       break;
   947     case nsIHTMLEditor::eRight:
   948       outStateString.AssignLiteral("right");
   949       break;
   951     case nsIHTMLEditor::eJustify:
   952       outStateString.AssignLiteral("justify");
   953       break;
   954   }
   955   nsAutoCString tOutStateString;
   956   tOutStateString.AssignWithConversion(outStateString);
   957   aParams->SetBooleanValue(STATE_MIXED,outMixed);
   958   aParams->SetCStringValue(STATE_ATTRIBUTE, tOutStateString.get());
   959   return NS_OK;
   960 }
   962 nsresult
   963 nsAlignCommand::SetState(nsIEditor *aEditor, nsString& newState)
   964 {
   965   NS_ASSERTION(aEditor, "Need an editor here");
   967   nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(aEditor);
   968   NS_ENSURE_TRUE(htmlEditor, NS_ERROR_FAILURE);
   970   return htmlEditor->Align(newState);
   971 }
   973 nsAbsolutePositioningCommand::nsAbsolutePositioningCommand()
   974 : nsBaseStateUpdatingCommand(nsGkAtoms::_empty)
   975 {
   976 }
   978 NS_IMETHODIMP
   979 nsAbsolutePositioningCommand::IsCommandEnabled(const char * aCommandName,
   980                                                nsISupports *aCommandRefCon,
   981                                                bool *outCmdEnabled)
   982 {
   983   nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
   984   nsCOMPtr<nsIHTMLAbsPosEditor> htmlEditor = do_QueryInterface(aCommandRefCon);
   985   if (htmlEditor)
   986   {
   987     bool isEditable = false;
   988     nsresult rv = editor->GetIsSelectionEditable(&isEditable);
   989     NS_ENSURE_SUCCESS(rv, rv);
   990     if (isEditable)
   991       return htmlEditor->GetAbsolutePositioningEnabled(outCmdEnabled);
   992   }
   994   *outCmdEnabled = false;
   995   return NS_OK;
   996 }
   998 nsresult
   999 nsAbsolutePositioningCommand::GetCurrentState(nsIEditor *aEditor, nsICommandParams *aParams)
  1001   NS_ASSERTION(aEditor, "Need an editor here");
  1003   nsCOMPtr<nsIHTMLAbsPosEditor> htmlEditor = do_QueryInterface(aEditor);
  1004   NS_ENSURE_TRUE(htmlEditor, NS_ERROR_FAILURE);
  1006   bool isEnabled;
  1007   htmlEditor->GetAbsolutePositioningEnabled(&isEnabled);
  1008   if (!isEnabled) {
  1009     aParams->SetBooleanValue(STATE_MIXED,false);
  1010     aParams->SetCStringValue(STATE_ATTRIBUTE, "");
  1011     return NS_OK;
  1014   nsCOMPtr<nsIDOMElement>  elt;
  1015   nsresult rv = htmlEditor->GetAbsolutelyPositionedSelectionContainer(getter_AddRefs(elt));
  1016   NS_ENSURE_SUCCESS(rv, rv);
  1018   nsAutoString outStateString;
  1019   if (elt)
  1020     outStateString.AssignLiteral("absolute");
  1022   aParams->SetBooleanValue(STATE_MIXED,false);
  1023   aParams->SetCStringValue(STATE_ATTRIBUTE, NS_ConvertUTF16toUTF8(outStateString).get());
  1024   return NS_OK;
  1027 nsresult
  1028 nsAbsolutePositioningCommand::ToggleState(nsIEditor *aEditor)
  1030   NS_ASSERTION(aEditor, "Need an editor here");
  1032   nsCOMPtr<nsIHTMLAbsPosEditor> htmlEditor = do_QueryInterface(aEditor);
  1033   NS_ENSURE_TRUE(htmlEditor, NS_ERROR_FAILURE);
  1035   nsCOMPtr<nsIDOMElement> elt;
  1036   nsresult rv = htmlEditor->GetAbsolutelyPositionedSelectionContainer(getter_AddRefs(elt));
  1037   NS_ENSURE_SUCCESS(rv, rv);
  1039   return htmlEditor->AbsolutePositionSelection(!elt);
  1043 NS_IMETHODIMP
  1044 nsDecreaseZIndexCommand::IsCommandEnabled(const char * aCommandName,
  1045                                           nsISupports *refCon,
  1046                                           bool *outCmdEnabled)
  1048   nsCOMPtr<nsIHTMLAbsPosEditor> htmlEditor = do_QueryInterface(refCon);
  1049   NS_ENSURE_TRUE(htmlEditor, NS_ERROR_FAILURE);
  1051   htmlEditor->GetAbsolutePositioningEnabled(outCmdEnabled);
  1052   if (!(*outCmdEnabled))
  1053     return NS_OK;
  1055   nsCOMPtr<nsIDOMElement> positionedElement;
  1056   htmlEditor->GetPositionedElement(getter_AddRefs(positionedElement));
  1057   *outCmdEnabled = false;
  1058   if (positionedElement) {
  1059     int32_t z;
  1060     nsresult res = htmlEditor->GetElementZIndex(positionedElement, &z);
  1061     NS_ENSURE_SUCCESS(res, res);
  1062     *outCmdEnabled = (z > 0);
  1065   return NS_OK;
  1068 NS_IMETHODIMP
  1069 nsDecreaseZIndexCommand::DoCommand(const char *aCommandName,
  1070                                    nsISupports *refCon)
  1072   nsCOMPtr<nsIHTMLAbsPosEditor> htmlEditor = do_QueryInterface(refCon);
  1073   NS_ENSURE_TRUE(htmlEditor, NS_ERROR_NOT_IMPLEMENTED);
  1075   return htmlEditor->RelativeChangeZIndex(-1);
  1078 NS_IMETHODIMP
  1079 nsDecreaseZIndexCommand::DoCommandParams(const char *aCommandName,
  1080                                          nsICommandParams *aParams, 
  1081                                          nsISupports *refCon)
  1083   return DoCommand(aCommandName, refCon);
  1086 NS_IMETHODIMP
  1087 nsDecreaseZIndexCommand::GetCommandStateParams(const char *aCommandName,
  1088                                                nsICommandParams *aParams,
  1089                                                nsISupports *refCon)
  1091   NS_ENSURE_ARG_POINTER(aParams);
  1093   bool enabled = false;
  1094   nsresult rv = IsCommandEnabled(aCommandName, refCon, &enabled);
  1095   NS_ENSURE_SUCCESS(rv, rv);
  1097   return aParams->SetBooleanValue(STATE_ENABLED, enabled);
  1100 NS_IMETHODIMP
  1101 nsIncreaseZIndexCommand::IsCommandEnabled(const char * aCommandName,
  1102                                           nsISupports *refCon,
  1103                                           bool *outCmdEnabled)
  1105   nsCOMPtr<nsIHTMLAbsPosEditor> htmlEditor = do_QueryInterface(refCon);
  1106   NS_ENSURE_TRUE(htmlEditor, NS_ERROR_FAILURE);
  1108   htmlEditor->GetAbsolutePositioningEnabled(outCmdEnabled);
  1109   if (!(*outCmdEnabled))
  1110     return NS_OK;
  1112   nsCOMPtr<nsIDOMElement> positionedElement;
  1113   htmlEditor->GetPositionedElement(getter_AddRefs(positionedElement));
  1114   *outCmdEnabled = (nullptr != positionedElement);
  1115   return NS_OK;
  1118 NS_IMETHODIMP
  1119 nsIncreaseZIndexCommand::DoCommand(const char *aCommandName,
  1120                                    nsISupports *refCon)
  1122   nsCOMPtr<nsIHTMLAbsPosEditor> htmlEditor = do_QueryInterface(refCon);
  1123   NS_ENSURE_TRUE(htmlEditor, NS_ERROR_NOT_IMPLEMENTED);
  1125   return htmlEditor->RelativeChangeZIndex(1);
  1128 NS_IMETHODIMP
  1129 nsIncreaseZIndexCommand::DoCommandParams(const char *aCommandName,
  1130                                          nsICommandParams *aParams, 
  1131                                          nsISupports *refCon)
  1133   return DoCommand(aCommandName, refCon);
  1136 NS_IMETHODIMP
  1137 nsIncreaseZIndexCommand::GetCommandStateParams(const char *aCommandName,
  1138                                                nsICommandParams *aParams,
  1139                                                nsISupports *refCon)
  1141   NS_ENSURE_ARG_POINTER(aParams);
  1143   bool enabled = false;
  1144   nsresult rv = IsCommandEnabled(aCommandName, refCon, &enabled);
  1145   NS_ENSURE_SUCCESS(rv, rv);
  1147   return aParams->SetBooleanValue(STATE_ENABLED, enabled);
  1151 NS_IMETHODIMP
  1152 nsRemoveStylesCommand::IsCommandEnabled(const char * aCommandName,
  1153                                         nsISupports *refCon,
  1154                                         bool *outCmdEnabled)
  1156   nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon);
  1157   // test if we have any styles?
  1158   if (editor)
  1159     return editor->GetIsSelectionEditable(outCmdEnabled);
  1161   *outCmdEnabled = false;
  1162   return NS_OK;
  1167 NS_IMETHODIMP
  1168 nsRemoveStylesCommand::DoCommand(const char *aCommandName,
  1169                                  nsISupports *refCon)
  1171   nsCOMPtr<nsIHTMLEditor> editor = do_QueryInterface(refCon);
  1173   nsresult rv = NS_OK;
  1174   if (editor)
  1176     rv = editor->RemoveAllInlineProperties();
  1179   return rv;  
  1182 NS_IMETHODIMP
  1183 nsRemoveStylesCommand::DoCommandParams(const char *aCommandName,
  1184                                        nsICommandParams *aParams,
  1185                                        nsISupports *refCon)
  1187   return DoCommand(aCommandName, refCon);
  1190 NS_IMETHODIMP
  1191 nsRemoveStylesCommand::GetCommandStateParams(const char *aCommandName,
  1192                                              nsICommandParams *aParams,
  1193                                              nsISupports *refCon)
  1195   bool outCmdEnabled = false;
  1196   IsCommandEnabled(aCommandName, refCon, &outCmdEnabled);
  1197   return aParams->SetBooleanValue(STATE_ENABLED,outCmdEnabled);
  1200 NS_IMETHODIMP
  1201 nsIncreaseFontSizeCommand::IsCommandEnabled(const char * aCommandName,
  1202                                             nsISupports *refCon,
  1203                                             bool *outCmdEnabled)
  1205   nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon);
  1206   // test if we are at max size?
  1207   if (editor)
  1208     return editor->GetIsSelectionEditable(outCmdEnabled);
  1210   *outCmdEnabled = false;
  1211   return NS_OK;
  1215 NS_IMETHODIMP
  1216 nsIncreaseFontSizeCommand::DoCommand(const char *aCommandName,
  1217                                      nsISupports *refCon)
  1219   nsCOMPtr<nsIHTMLEditor> editor = do_QueryInterface(refCon);
  1221   nsresult rv = NS_OK;
  1222   if (editor)
  1224     rv = editor->IncreaseFontSize();
  1227   return rv;  
  1230 NS_IMETHODIMP
  1231 nsIncreaseFontSizeCommand::DoCommandParams(const char *aCommandName,
  1232                                            nsICommandParams *aParams,
  1233                                            nsISupports *refCon)
  1235   return DoCommand(aCommandName, refCon);
  1238 NS_IMETHODIMP
  1239 nsIncreaseFontSizeCommand::GetCommandStateParams(const char *aCommandName,
  1240                                                  nsICommandParams *aParams,
  1241                                                  nsISupports *refCon)
  1243   bool outCmdEnabled = false;
  1244   IsCommandEnabled(aCommandName, refCon, &outCmdEnabled);
  1245   return aParams->SetBooleanValue(STATE_ENABLED,outCmdEnabled);
  1248 NS_IMETHODIMP
  1249 nsDecreaseFontSizeCommand::IsCommandEnabled(const char * aCommandName,
  1250                                             nsISupports *refCon,
  1251                                             bool *outCmdEnabled)
  1253   nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon);
  1254   // test if we are at min size?
  1255   if (editor)
  1256     return editor->GetIsSelectionEditable(outCmdEnabled);
  1258   *outCmdEnabled = false;
  1259   return NS_OK;
  1263 NS_IMETHODIMP
  1264 nsDecreaseFontSizeCommand::DoCommand(const char *aCommandName,
  1265                                      nsISupports *refCon)
  1267   nsCOMPtr<nsIHTMLEditor> editor = do_QueryInterface(refCon);
  1269   nsresult rv = NS_OK;
  1270   if (editor)
  1272     rv = editor->DecreaseFontSize();
  1275   return rv;  
  1278 NS_IMETHODIMP
  1279 nsDecreaseFontSizeCommand::DoCommandParams(const char *aCommandName,
  1280                                            nsICommandParams *aParams,
  1281                                            nsISupports *refCon)
  1283   return DoCommand(aCommandName, refCon);
  1286 NS_IMETHODIMP
  1287 nsDecreaseFontSizeCommand::GetCommandStateParams(const char *aCommandName,
  1288                                                  nsICommandParams *aParams,
  1289                                                  nsISupports *refCon)
  1291   bool outCmdEnabled = false;
  1292   IsCommandEnabled(aCommandName, refCon, &outCmdEnabled);
  1293   return aParams->SetBooleanValue(STATE_ENABLED,outCmdEnabled);
  1296 NS_IMETHODIMP
  1297 nsInsertHTMLCommand::IsCommandEnabled(const char * aCommandName,
  1298                                       nsISupports *refCon,
  1299                                       bool *outCmdEnabled)
  1301   NS_ENSURE_ARG_POINTER(outCmdEnabled);
  1302   nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon);
  1303   if (editor)
  1304     return editor->GetIsSelectionEditable(outCmdEnabled);
  1306   *outCmdEnabled = false;
  1307   return NS_OK;
  1311 NS_IMETHODIMP
  1312 nsInsertHTMLCommand::DoCommand(const char *aCommandName, nsISupports *refCon)
  1314   return NS_ERROR_NOT_IMPLEMENTED;
  1317 NS_IMETHODIMP
  1318 nsInsertHTMLCommand::DoCommandParams(const char *aCommandName,
  1319                                      nsICommandParams *aParams,
  1320                                      nsISupports *refCon)
  1322   NS_ENSURE_ARG_POINTER(aParams);
  1323   NS_ENSURE_ARG_POINTER(refCon);
  1325   nsCOMPtr<nsIHTMLEditor> editor = do_QueryInterface(refCon);
  1326   NS_ENSURE_TRUE(editor, NS_ERROR_NOT_IMPLEMENTED);
  1328   // Get HTML source string to insert from command params
  1329   nsAutoString html;
  1330   nsresult rv = aParams->GetStringValue(STATE_DATA, html);
  1331   NS_ENSURE_SUCCESS(rv, rv);
  1333   if (!html.IsEmpty())
  1334     return editor->InsertHTML(html);
  1336   return NS_OK;
  1339 NS_IMETHODIMP
  1340 nsInsertHTMLCommand::GetCommandStateParams(const char *aCommandName,
  1341                                            nsICommandParams *aParams,
  1342                                            nsISupports *refCon)
  1344   NS_ENSURE_ARG_POINTER(aParams);
  1345   NS_ENSURE_ARG_POINTER(refCon);
  1347   bool outCmdEnabled = false;
  1348   IsCommandEnabled(aCommandName, refCon, &outCmdEnabled);
  1349   return aParams->SetBooleanValue(STATE_ENABLED, outCmdEnabled);
  1352 NS_IMPL_ISUPPORTS_INHERITED0(nsInsertTagCommand, nsBaseComposerCommand)
  1354 nsInsertTagCommand::nsInsertTagCommand(nsIAtom* aTagName)
  1355 : nsBaseComposerCommand()
  1356 , mTagName(aTagName)
  1358   MOZ_ASSERT(mTagName);
  1361 nsInsertTagCommand::~nsInsertTagCommand()
  1365 NS_IMETHODIMP
  1366 nsInsertTagCommand::IsCommandEnabled(const char * aCommandName,
  1367                                      nsISupports *refCon,
  1368                                      bool *outCmdEnabled)
  1370   NS_ENSURE_ARG_POINTER(outCmdEnabled);
  1371   nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon);
  1372   if (editor)
  1373     return editor->GetIsSelectionEditable(outCmdEnabled);
  1375   *outCmdEnabled = false;
  1376   return NS_OK;
  1380 // corresponding STATE_ATTRIBUTE is: src (img) and href (a) 
  1381 NS_IMETHODIMP
  1382 nsInsertTagCommand::DoCommand(const char *aCmdName, nsISupports *refCon)
  1384   NS_ENSURE_TRUE(mTagName == nsGkAtoms::hr, NS_ERROR_NOT_IMPLEMENTED);
  1386   nsCOMPtr<nsIHTMLEditor> editor = do_QueryInterface(refCon);
  1387   NS_ENSURE_TRUE(editor, NS_ERROR_NOT_IMPLEMENTED);
  1389   nsCOMPtr<nsIDOMElement> domElem;
  1390   nsresult rv = editor->CreateElementWithDefaults(
  1391     nsDependentAtomString(mTagName), getter_AddRefs(domElem));
  1392   NS_ENSURE_SUCCESS(rv, rv);
  1394   return editor->InsertElementAtSelection(domElem, true);
  1397 NS_IMETHODIMP
  1398 nsInsertTagCommand::DoCommandParams(const char *aCommandName,
  1399                                     nsICommandParams *aParams,
  1400                                     nsISupports *refCon)
  1402   NS_ENSURE_ARG_POINTER(refCon);
  1404   // inserting an hr shouldn't have an parameters, just call DoCommand for that
  1405   if (mTagName == nsGkAtoms::hr) {
  1406     return DoCommand(aCommandName, refCon);
  1409   NS_ENSURE_ARG_POINTER(aParams);
  1411   nsCOMPtr<nsIHTMLEditor> editor = do_QueryInterface(refCon);
  1412   NS_ENSURE_TRUE(editor, NS_ERROR_NOT_IMPLEMENTED);
  1414   // do we have an href to use for creating link?
  1415   nsXPIDLCString s;
  1416   nsresult rv = aParams->GetCStringValue(STATE_ATTRIBUTE, getter_Copies(s));
  1417   NS_ENSURE_SUCCESS(rv, rv);
  1418   nsAutoString attrib; attrib.AssignWithConversion(s);
  1420   if (attrib.IsEmpty())
  1421     return NS_ERROR_INVALID_ARG;
  1423   // filter out tags we don't know how to insert
  1424   nsAutoString attributeType;
  1425   if (mTagName == nsGkAtoms::a) {
  1426     attributeType.AssignLiteral("href");
  1427   } else if (mTagName == nsGkAtoms::img) {
  1428     attributeType.AssignLiteral("src");
  1429   } else {
  1430     return NS_ERROR_NOT_IMPLEMENTED;
  1433   nsCOMPtr<nsIDOMElement> domElem;
  1434   rv = editor->CreateElementWithDefaults(nsDependentAtomString(mTagName),
  1435                                          getter_AddRefs(domElem));
  1436   NS_ENSURE_SUCCESS(rv, rv);
  1438   rv = domElem->SetAttribute(attributeType, attrib);
  1439   NS_ENSURE_SUCCESS(rv, rv);
  1441   // do actual insertion
  1442   if (mTagName == nsGkAtoms::a)
  1443     return editor->InsertLinkAroundSelection(domElem);
  1445   return editor->InsertElementAtSelection(domElem, true);
  1448 NS_IMETHODIMP
  1449 nsInsertTagCommand::GetCommandStateParams(const char *aCommandName,
  1450                                           nsICommandParams *aParams,
  1451                                           nsISupports *refCon)
  1453   NS_ENSURE_ARG_POINTER(aParams);
  1454   NS_ENSURE_ARG_POINTER(refCon);
  1456   bool outCmdEnabled = false;
  1457   IsCommandEnabled(aCommandName, refCon, &outCmdEnabled);
  1458   return aParams->SetBooleanValue(STATE_ENABLED, outCmdEnabled);
  1462 /****************************/
  1463 //HELPER METHODS
  1464 /****************************/
  1466 nsresult
  1467 GetListState(nsIHTMLEditor* aEditor, bool* aMixed, nsAString& aLocalName)
  1469   MOZ_ASSERT(aEditor);
  1470   MOZ_ASSERT(aMixed);
  1472   *aMixed = false;
  1473   aLocalName.Truncate();
  1475   bool bOL, bUL, bDL;
  1476   nsresult rv = aEditor->GetListState(aMixed, &bOL, &bUL, &bDL);
  1477   NS_ENSURE_SUCCESS(rv, rv);
  1479   if (*aMixed) {
  1480     return NS_OK;
  1483   if (bOL) {
  1484     aLocalName.AssignLiteral("ol");
  1485   } else if (bUL) {
  1486     aLocalName.AssignLiteral("ul");
  1487   } else if (bDL) {
  1488     aLocalName.AssignLiteral("dl");
  1490   return NS_OK;
  1493 nsresult
  1494 RemoveOneProperty(nsIHTMLEditor* aEditor, const nsAString& aProp)
  1496   MOZ_ASSERT(aEditor);
  1498   /// XXX Hack alert! Look in nsIEditProperty.h for this
  1499   nsCOMPtr<nsIAtom> styleAtom = do_GetAtom(aProp);
  1500   NS_ENSURE_TRUE(styleAtom, NS_ERROR_OUT_OF_MEMORY);
  1502   return aEditor->RemoveInlineProperty(styleAtom, EmptyString());
  1506 // the name of the attribute here should be the contents of the appropriate
  1507 // tag, e.g. 'b' for bold, 'i' for italics.
  1508 nsresult
  1509 RemoveTextProperty(nsIHTMLEditor* aEditor, const nsAString& aProp)
  1511   MOZ_ASSERT(aEditor);
  1513   if (aProp.LowerCaseEqualsLiteral("all")) {
  1514     return aEditor->RemoveAllInlineProperties();
  1517   return RemoveOneProperty(aEditor, aProp);
  1520 // the name of the attribute here should be the contents of the appropriate
  1521 // tag, e.g. 'b' for bold, 'i' for italics.
  1522 nsresult
  1523 SetTextProperty(nsIHTMLEditor* aEditor, const nsAString& aProp)
  1525   MOZ_ASSERT(aEditor);
  1527   /// XXX Hack alert! Look in nsIEditProperty.h for this
  1528   nsCOMPtr<nsIAtom> styleAtom = do_GetAtom(aProp);
  1529   NS_ENSURE_TRUE(styleAtom, NS_ERROR_OUT_OF_MEMORY);
  1531   return aEditor->SetInlineProperty(styleAtom, EmptyString(), EmptyString());

mercurial