Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
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)
1000 {
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;
1012 }
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;
1025 }
1027 nsresult
1028 nsAbsolutePositioningCommand::ToggleState(nsIEditor *aEditor)
1029 {
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);
1040 }
1043 NS_IMETHODIMP
1044 nsDecreaseZIndexCommand::IsCommandEnabled(const char * aCommandName,
1045 nsISupports *refCon,
1046 bool *outCmdEnabled)
1047 {
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);
1063 }
1065 return NS_OK;
1066 }
1068 NS_IMETHODIMP
1069 nsDecreaseZIndexCommand::DoCommand(const char *aCommandName,
1070 nsISupports *refCon)
1071 {
1072 nsCOMPtr<nsIHTMLAbsPosEditor> htmlEditor = do_QueryInterface(refCon);
1073 NS_ENSURE_TRUE(htmlEditor, NS_ERROR_NOT_IMPLEMENTED);
1075 return htmlEditor->RelativeChangeZIndex(-1);
1076 }
1078 NS_IMETHODIMP
1079 nsDecreaseZIndexCommand::DoCommandParams(const char *aCommandName,
1080 nsICommandParams *aParams,
1081 nsISupports *refCon)
1082 {
1083 return DoCommand(aCommandName, refCon);
1084 }
1086 NS_IMETHODIMP
1087 nsDecreaseZIndexCommand::GetCommandStateParams(const char *aCommandName,
1088 nsICommandParams *aParams,
1089 nsISupports *refCon)
1090 {
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);
1098 }
1100 NS_IMETHODIMP
1101 nsIncreaseZIndexCommand::IsCommandEnabled(const char * aCommandName,
1102 nsISupports *refCon,
1103 bool *outCmdEnabled)
1104 {
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;
1116 }
1118 NS_IMETHODIMP
1119 nsIncreaseZIndexCommand::DoCommand(const char *aCommandName,
1120 nsISupports *refCon)
1121 {
1122 nsCOMPtr<nsIHTMLAbsPosEditor> htmlEditor = do_QueryInterface(refCon);
1123 NS_ENSURE_TRUE(htmlEditor, NS_ERROR_NOT_IMPLEMENTED);
1125 return htmlEditor->RelativeChangeZIndex(1);
1126 }
1128 NS_IMETHODIMP
1129 nsIncreaseZIndexCommand::DoCommandParams(const char *aCommandName,
1130 nsICommandParams *aParams,
1131 nsISupports *refCon)
1132 {
1133 return DoCommand(aCommandName, refCon);
1134 }
1136 NS_IMETHODIMP
1137 nsIncreaseZIndexCommand::GetCommandStateParams(const char *aCommandName,
1138 nsICommandParams *aParams,
1139 nsISupports *refCon)
1140 {
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);
1148 }
1151 NS_IMETHODIMP
1152 nsRemoveStylesCommand::IsCommandEnabled(const char * aCommandName,
1153 nsISupports *refCon,
1154 bool *outCmdEnabled)
1155 {
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;
1163 }
1167 NS_IMETHODIMP
1168 nsRemoveStylesCommand::DoCommand(const char *aCommandName,
1169 nsISupports *refCon)
1170 {
1171 nsCOMPtr<nsIHTMLEditor> editor = do_QueryInterface(refCon);
1173 nsresult rv = NS_OK;
1174 if (editor)
1175 {
1176 rv = editor->RemoveAllInlineProperties();
1177 }
1179 return rv;
1180 }
1182 NS_IMETHODIMP
1183 nsRemoveStylesCommand::DoCommandParams(const char *aCommandName,
1184 nsICommandParams *aParams,
1185 nsISupports *refCon)
1186 {
1187 return DoCommand(aCommandName, refCon);
1188 }
1190 NS_IMETHODIMP
1191 nsRemoveStylesCommand::GetCommandStateParams(const char *aCommandName,
1192 nsICommandParams *aParams,
1193 nsISupports *refCon)
1194 {
1195 bool outCmdEnabled = false;
1196 IsCommandEnabled(aCommandName, refCon, &outCmdEnabled);
1197 return aParams->SetBooleanValue(STATE_ENABLED,outCmdEnabled);
1198 }
1200 NS_IMETHODIMP
1201 nsIncreaseFontSizeCommand::IsCommandEnabled(const char * aCommandName,
1202 nsISupports *refCon,
1203 bool *outCmdEnabled)
1204 {
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;
1212 }
1215 NS_IMETHODIMP
1216 nsIncreaseFontSizeCommand::DoCommand(const char *aCommandName,
1217 nsISupports *refCon)
1218 {
1219 nsCOMPtr<nsIHTMLEditor> editor = do_QueryInterface(refCon);
1221 nsresult rv = NS_OK;
1222 if (editor)
1223 {
1224 rv = editor->IncreaseFontSize();
1225 }
1227 return rv;
1228 }
1230 NS_IMETHODIMP
1231 nsIncreaseFontSizeCommand::DoCommandParams(const char *aCommandName,
1232 nsICommandParams *aParams,
1233 nsISupports *refCon)
1234 {
1235 return DoCommand(aCommandName, refCon);
1236 }
1238 NS_IMETHODIMP
1239 nsIncreaseFontSizeCommand::GetCommandStateParams(const char *aCommandName,
1240 nsICommandParams *aParams,
1241 nsISupports *refCon)
1242 {
1243 bool outCmdEnabled = false;
1244 IsCommandEnabled(aCommandName, refCon, &outCmdEnabled);
1245 return aParams->SetBooleanValue(STATE_ENABLED,outCmdEnabled);
1246 }
1248 NS_IMETHODIMP
1249 nsDecreaseFontSizeCommand::IsCommandEnabled(const char * aCommandName,
1250 nsISupports *refCon,
1251 bool *outCmdEnabled)
1252 {
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;
1260 }
1263 NS_IMETHODIMP
1264 nsDecreaseFontSizeCommand::DoCommand(const char *aCommandName,
1265 nsISupports *refCon)
1266 {
1267 nsCOMPtr<nsIHTMLEditor> editor = do_QueryInterface(refCon);
1269 nsresult rv = NS_OK;
1270 if (editor)
1271 {
1272 rv = editor->DecreaseFontSize();
1273 }
1275 return rv;
1276 }
1278 NS_IMETHODIMP
1279 nsDecreaseFontSizeCommand::DoCommandParams(const char *aCommandName,
1280 nsICommandParams *aParams,
1281 nsISupports *refCon)
1282 {
1283 return DoCommand(aCommandName, refCon);
1284 }
1286 NS_IMETHODIMP
1287 nsDecreaseFontSizeCommand::GetCommandStateParams(const char *aCommandName,
1288 nsICommandParams *aParams,
1289 nsISupports *refCon)
1290 {
1291 bool outCmdEnabled = false;
1292 IsCommandEnabled(aCommandName, refCon, &outCmdEnabled);
1293 return aParams->SetBooleanValue(STATE_ENABLED,outCmdEnabled);
1294 }
1296 NS_IMETHODIMP
1297 nsInsertHTMLCommand::IsCommandEnabled(const char * aCommandName,
1298 nsISupports *refCon,
1299 bool *outCmdEnabled)
1300 {
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;
1308 }
1311 NS_IMETHODIMP
1312 nsInsertHTMLCommand::DoCommand(const char *aCommandName, nsISupports *refCon)
1313 {
1314 return NS_ERROR_NOT_IMPLEMENTED;
1315 }
1317 NS_IMETHODIMP
1318 nsInsertHTMLCommand::DoCommandParams(const char *aCommandName,
1319 nsICommandParams *aParams,
1320 nsISupports *refCon)
1321 {
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;
1337 }
1339 NS_IMETHODIMP
1340 nsInsertHTMLCommand::GetCommandStateParams(const char *aCommandName,
1341 nsICommandParams *aParams,
1342 nsISupports *refCon)
1343 {
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);
1350 }
1352 NS_IMPL_ISUPPORTS_INHERITED0(nsInsertTagCommand, nsBaseComposerCommand)
1354 nsInsertTagCommand::nsInsertTagCommand(nsIAtom* aTagName)
1355 : nsBaseComposerCommand()
1356 , mTagName(aTagName)
1357 {
1358 MOZ_ASSERT(mTagName);
1359 }
1361 nsInsertTagCommand::~nsInsertTagCommand()
1362 {
1363 }
1365 NS_IMETHODIMP
1366 nsInsertTagCommand::IsCommandEnabled(const char * aCommandName,
1367 nsISupports *refCon,
1368 bool *outCmdEnabled)
1369 {
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;
1377 }
1380 // corresponding STATE_ATTRIBUTE is: src (img) and href (a)
1381 NS_IMETHODIMP
1382 nsInsertTagCommand::DoCommand(const char *aCmdName, nsISupports *refCon)
1383 {
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);
1395 }
1397 NS_IMETHODIMP
1398 nsInsertTagCommand::DoCommandParams(const char *aCommandName,
1399 nsICommandParams *aParams,
1400 nsISupports *refCon)
1401 {
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);
1407 }
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;
1431 }
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);
1446 }
1448 NS_IMETHODIMP
1449 nsInsertTagCommand::GetCommandStateParams(const char *aCommandName,
1450 nsICommandParams *aParams,
1451 nsISupports *refCon)
1452 {
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);
1459 }
1462 /****************************/
1463 //HELPER METHODS
1464 /****************************/
1466 nsresult
1467 GetListState(nsIHTMLEditor* aEditor, bool* aMixed, nsAString& aLocalName)
1468 {
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;
1481 }
1483 if (bOL) {
1484 aLocalName.AssignLiteral("ol");
1485 } else if (bUL) {
1486 aLocalName.AssignLiteral("ul");
1487 } else if (bDL) {
1488 aLocalName.AssignLiteral("dl");
1489 }
1490 return NS_OK;
1491 }
1493 nsresult
1494 RemoveOneProperty(nsIHTMLEditor* aEditor, const nsAString& aProp)
1495 {
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());
1503 }
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)
1510 {
1511 MOZ_ASSERT(aEditor);
1513 if (aProp.LowerCaseEqualsLiteral("all")) {
1514 return aEditor->RemoveAllInlineProperties();
1515 }
1517 return RemoveOneProperty(aEditor, aProp);
1518 }
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)
1524 {
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());
1532 }