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/. */
6 #include "mozilla/EditorCommands.h"
8 #include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
9 #include "mozilla/EditorBase.h" // for EditorBase
10 #include "mozilla/ErrorResult.h"
11 #include "mozilla/HTMLEditor.h" // for HTMLEditor
12 #include "mozilla/dom/Element.h"
13 #include "nsAString.h"
14 #include "nsAtom.h" // for nsAtom, nsStaticAtom, etc
15 #include "nsCommandParams.h" // for nsCommandParams, etc
16 #include "nsComponentManagerUtils.h" // for do_CreateInstance
17 #include "nsGkAtoms.h" // for nsGkAtoms, nsGkAtoms::font, etc
18 #include "nsIClipboard.h" // for nsIClipboard, etc
19 #include "nsIEditingSession.h"
20 #include "nsIPrincipal.h" // for nsIPrincipal
21 #include "nsLiteralString.h" // for NS_LITERAL_STRING
22 #include "nsReadableUtils.h" // for EmptyString
23 #include "nsString.h" // for nsAutoString, nsString, etc
24 #include "nsStringFwd.h" // for nsString
32 static nsresult
GetListState(HTMLEditor
* aHTMLEditor
, bool* aMixed
,
33 nsAString
& aLocalName
);
36 #define STATE_ENABLED "state_enabled"
37 #define STATE_ALL "state_all"
38 #define STATE_ANY "state_any"
39 #define STATE_MIXED "state_mixed"
40 #define STATE_BEGIN "state_begin"
41 #define STATE_END "state_end"
42 #define STATE_ATTRIBUTE "state_attribute"
43 #define STATE_DATA "state_data"
45 /*****************************************************************************
46 * mozilla::StateUpdatingCommandBase
47 *****************************************************************************/
49 bool StateUpdatingCommandBase::IsCommandEnabled(Command aCommand
,
50 EditorBase
* aEditorBase
) const {
51 HTMLEditor
* htmlEditor
= HTMLEditor::GetFrom(aEditorBase
);
55 if (!htmlEditor
->IsModifiable() || !htmlEditor
->IsSelectionEditable()) {
58 if (aCommand
== Command::FormatAbsolutePosition
) {
59 return htmlEditor
->IsAbsolutePositionEditorEnabled();
64 nsresult
StateUpdatingCommandBase::DoCommand(Command aCommand
,
65 EditorBase
& aEditorBase
,
66 nsIPrincipal
* aPrincipal
) const {
67 HTMLEditor
* htmlEditor
= aEditorBase
.GetAsHTMLEditor();
68 if (NS_WARN_IF(!htmlEditor
)) {
69 return NS_ERROR_FAILURE
;
71 nsStaticAtom
* tagName
= GetTagName(aCommand
);
72 if (NS_WARN_IF(!tagName
)) {
73 return NS_ERROR_UNEXPECTED
;
75 nsresult rv
= ToggleState(MOZ_KnownLive(*tagName
), MOZ_KnownLive(*htmlEditor
),
77 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv
),
78 "StateUpdatingCommandBase::ToggleState() failed");
82 nsresult
StateUpdatingCommandBase::GetCommandStateParams(
83 Command aCommand
, nsCommandParams
& aParams
, EditorBase
* aEditorBase
,
84 nsIEditingSession
* aEditingSession
) const {
88 HTMLEditor
* htmlEditor
= aEditorBase
->GetAsHTMLEditor();
89 if (NS_WARN_IF(!htmlEditor
)) {
90 return NS_ERROR_FAILURE
;
92 nsStaticAtom
* tagName
= GetTagName(aCommand
);
93 if (NS_WARN_IF(!tagName
)) {
94 return NS_ERROR_UNEXPECTED
;
96 // MOZ_KnownLive(htmlEditor) because the lifetime of aEditorBase is guaranteed
98 // MOZ_KnownLive(tagName) because nsStaticAtom instances are alive until
100 nsresult rv
= GetCurrentState(MOZ_KnownLive(*tagName
),
101 MOZ_KnownLive(*htmlEditor
), aParams
);
102 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv
),
103 "StateUpdatingCommandBase::GetCurrentState() failed");
107 /*****************************************************************************
108 * mozilla::PasteNoFormattingCommand
109 *****************************************************************************/
111 StaticRefPtr
<PasteNoFormattingCommand
> PasteNoFormattingCommand::sInstance
;
113 bool PasteNoFormattingCommand::IsCommandEnabled(Command aCommand
,
114 EditorBase
* aEditorBase
) const {
115 HTMLEditor
* htmlEditor
= HTMLEditor::GetFrom(aEditorBase
);
119 return htmlEditor
->CanPaste(nsIClipboard::kGlobalClipboard
);
122 nsresult
PasteNoFormattingCommand::DoCommand(Command aCommand
,
123 EditorBase
& aEditorBase
,
124 nsIPrincipal
* aPrincipal
) const {
125 HTMLEditor
* htmlEditor
= aEditorBase
.GetAsHTMLEditor();
126 if (NS_WARN_IF(!htmlEditor
)) {
127 return NS_ERROR_FAILURE
;
129 // Known live because we hold a ref above in "editor"
130 nsresult rv
= MOZ_KnownLive(htmlEditor
)
131 ->PasteNoFormattingAsAction(
132 nsIClipboard::kGlobalClipboard
,
133 EditorBase::DispatchPasteEvent::Yes
, aPrincipal
);
134 NS_WARNING_ASSERTION(
136 "HTMLEditor::PasteNoFormattingAsAction(DispatchPasteEvent::Yes) failed");
140 nsresult
PasteNoFormattingCommand::GetCommandStateParams(
141 Command aCommand
, nsCommandParams
& aParams
, EditorBase
* aEditorBase
,
142 nsIEditingSession
* aEditingSession
) const {
143 return aParams
.SetBool(STATE_ENABLED
,
144 IsCommandEnabled(aCommand
, aEditorBase
));
147 /*****************************************************************************
148 * mozilla::StyleUpdatingCommand
149 *****************************************************************************/
151 StaticRefPtr
<StyleUpdatingCommand
> StyleUpdatingCommand::sInstance
;
153 nsresult
StyleUpdatingCommand::GetCurrentState(nsStaticAtom
& aTagName
,
154 HTMLEditor
& aHTMLEditor
,
155 nsCommandParams
& aParams
) const {
156 bool firstOfSelectionHasProp
= false;
157 bool anyOfSelectionHasProp
= false;
158 bool allOfSelectionHasProp
= false;
160 nsresult rv
= aHTMLEditor
.GetInlineProperty(
161 aTagName
, nullptr, u
""_ns
, &firstOfSelectionHasProp
,
162 &anyOfSelectionHasProp
, &allOfSelectionHasProp
);
163 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv
),
164 "HTMLEditor::GetInlineProperty() failed");
166 aParams
.SetBool(STATE_ENABLED
, NS_SUCCEEDED(rv
));
167 aParams
.SetBool(STATE_ALL
, allOfSelectionHasProp
);
168 aParams
.SetBool(STATE_ANY
, anyOfSelectionHasProp
);
169 aParams
.SetBool(STATE_MIXED
, anyOfSelectionHasProp
&& !allOfSelectionHasProp
);
170 aParams
.SetBool(STATE_BEGIN
, firstOfSelectionHasProp
);
171 aParams
.SetBool(STATE_END
, allOfSelectionHasProp
); // not completely accurate
175 nsresult
StyleUpdatingCommand::ToggleState(nsStaticAtom
& aTagName
,
176 HTMLEditor
& aHTMLEditor
,
177 nsIPrincipal
* aPrincipal
) const {
178 RefPtr
<nsCommandParams
> params
= new nsCommandParams();
180 // tags "href" and "name" are special cases in the core editor
181 // they are used to remove named anchor/link and shouldn't be used for
184 if (&aTagName
== nsGkAtoms::href
|| &aTagName
== nsGkAtoms::name
) {
187 // check current selection; set doTagRemoval if formatting should be removed
188 nsresult rv
= GetCurrentState(aTagName
, aHTMLEditor
, *params
);
190 NS_WARNING("StyleUpdatingCommand::GetCurrentState() failed");
194 doTagRemoval
= params
->GetBool(STATE_ALL
, error
);
195 if (NS_WARN_IF(error
.Failed())) {
196 return error
.StealNSResult();
202 aHTMLEditor
.RemoveInlinePropertyAsAction(aTagName
, nullptr, aPrincipal
);
203 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv
),
204 "HTMLEditor::RemoveInlinePropertyAsAction() failed");
208 nsresult rv
= aHTMLEditor
.SetInlinePropertyAsAction(aTagName
, nullptr, u
""_ns
,
210 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv
),
211 "HTMLEditor::SetInlinePropertyAsAction() failed");
215 /*****************************************************************************
216 * mozilla::ListCommand
217 *****************************************************************************/
219 StaticRefPtr
<ListCommand
> ListCommand::sInstance
;
221 nsresult
ListCommand::GetCurrentState(nsStaticAtom
& aTagName
,
222 HTMLEditor
& aHTMLEditor
,
223 nsCommandParams
& aParams
) const {
225 nsAutoString localName
;
226 nsresult rv
= GetListState(&aHTMLEditor
, &bMixed
, localName
);
228 NS_WARNING("GetListState() failed");
232 bool inList
= aTagName
.Equals(localName
);
233 aParams
.SetBool(STATE_ALL
, !bMixed
&& inList
);
234 aParams
.SetBool(STATE_MIXED
, bMixed
);
235 aParams
.SetBool(STATE_ENABLED
, true);
239 nsresult
ListCommand::ToggleState(nsStaticAtom
& aTagName
,
240 HTMLEditor
& aHTMLEditor
,
241 nsIPrincipal
* aPrincipal
) const {
242 RefPtr
<nsCommandParams
> params
= new nsCommandParams();
243 nsresult rv
= GetCurrentState(aTagName
, aHTMLEditor
, *params
);
245 NS_WARNING("ListCommand::GetCurrentState() failed");
250 bool inList
= params
->GetBool(STATE_ALL
, error
);
251 if (NS_WARN_IF(error
.Failed())) {
252 return error
.StealNSResult();
255 nsDependentAtomString
listType(&aTagName
);
257 nsresult rv
= aHTMLEditor
.RemoveListAsAction(listType
, aPrincipal
);
258 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv
),
259 "HTMLEditor::RemoveListAsAction() failed");
263 rv
= aHTMLEditor
.MakeOrChangeListAsAction(
264 aTagName
, u
""_ns
, HTMLEditor::SelectAllOfCurrentList::No
, aPrincipal
);
265 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv
),
266 "HTMLEditor::MakeOrChangeListAsAction() failed");
270 /*****************************************************************************
271 * mozilla::ListItemCommand
272 *****************************************************************************/
274 StaticRefPtr
<ListItemCommand
> ListItemCommand::sInstance
;
276 nsresult
ListItemCommand::GetCurrentState(nsStaticAtom
& aTagName
,
277 HTMLEditor
& aHTMLEditor
,
278 nsCommandParams
& aParams
) const {
280 ListItemElementSelectionState
state(aHTMLEditor
, error
);
281 if (error
.Failed()) {
282 NS_WARNING("ListItemElementSelectionState failed");
283 return error
.StealNSResult();
286 if (state
.IsNotOneTypeDefinitionListItemElementSelected()) {
287 aParams
.SetBool(STATE_ALL
, false);
288 aParams
.SetBool(STATE_MIXED
, true);
292 nsStaticAtom
* selectedListItemTagName
= nullptr;
293 if (state
.IsLIElementSelected()) {
294 selectedListItemTagName
= nsGkAtoms::li
;
295 } else if (state
.IsDTElementSelected()) {
296 selectedListItemTagName
= nsGkAtoms::dt
;
297 } else if (state
.IsDDElementSelected()) {
298 selectedListItemTagName
= nsGkAtoms::dd
;
300 aParams
.SetBool(STATE_ALL
, &aTagName
== selectedListItemTagName
);
301 aParams
.SetBool(STATE_MIXED
, false);
305 nsresult
ListItemCommand::ToggleState(nsStaticAtom
& aTagName
,
306 HTMLEditor
& aHTMLEditor
,
307 nsIPrincipal
* aPrincipal
) const {
308 // Need to use aTagName????
309 RefPtr
<nsCommandParams
> params
= new nsCommandParams();
310 GetCurrentState(aTagName
, aHTMLEditor
, *params
);
312 bool inList
= params
->GetBool(STATE_ALL
, error
);
313 if (NS_WARN_IF(error
.Failed())) {
314 return error
.StealNSResult();
318 // To remove a list, first get what kind of list we're in
320 nsAutoString localName
;
321 nsresult rv
= GetListState(&aHTMLEditor
, &bMixed
, localName
);
323 NS_WARNING("GetListState() failed");
326 if (localName
.IsEmpty() || bMixed
) {
329 rv
= aHTMLEditor
.RemoveListAsAction(localName
, aPrincipal
);
330 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv
),
331 "HTMLEditor::RemoveListAsAction() failed");
335 // Set to the requested paragraph type
336 // XXX Note: This actually doesn't work for "LI",
337 // but we currently don't use this for non DL lists anyway.
338 // Problem: won't this replace any current block paragraph style?
339 nsresult rv
= aHTMLEditor
.SetParagraphStateAsAction(
340 nsDependentAtomString(&aTagName
), aPrincipal
);
341 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv
),
342 "HTMLEditor::SetParagraphFormatAsAction() failed");
346 /*****************************************************************************
347 * mozilla::RemoveListCommand
348 *****************************************************************************/
350 StaticRefPtr
<RemoveListCommand
> RemoveListCommand::sInstance
;
352 bool RemoveListCommand::IsCommandEnabled(Command aCommand
,
353 EditorBase
* aEditorBase
) const {
354 HTMLEditor
* htmlEditor
= HTMLEditor::GetFrom(aEditorBase
);
358 if (!htmlEditor
->IsModifiable() || !htmlEditor
->IsSelectionEditable()) {
362 // It is enabled if we are in any list type
364 nsAutoString localName
;
365 nsresult rv
= GetListState(MOZ_KnownLive(htmlEditor
), &bMixed
, localName
);
366 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv
), "GetListState() failed");
367 return NS_SUCCEEDED(rv
) && (bMixed
|| !localName
.IsEmpty());
370 nsresult
RemoveListCommand::DoCommand(Command aCommand
, EditorBase
& aEditorBase
,
371 nsIPrincipal
* aPrincipal
) const {
372 HTMLEditor
* htmlEditor
= aEditorBase
.GetAsHTMLEditor();
373 if (NS_WARN_IF(!htmlEditor
)) {
376 // This removes any list type
378 MOZ_KnownLive(htmlEditor
)->RemoveListAsAction(u
""_ns
, aPrincipal
);
379 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv
),
380 "HTMLEditor::RemoveListAsAction() failed");
384 nsresult
RemoveListCommand::GetCommandStateParams(
385 Command aCommand
, nsCommandParams
& aParams
, EditorBase
* aEditorBase
,
386 nsIEditingSession
* aEditingSession
) const {
387 return aParams
.SetBool(STATE_ENABLED
,
388 IsCommandEnabled(aCommand
, aEditorBase
));
391 /*****************************************************************************
392 * mozilla::IndentCommand
393 *****************************************************************************/
395 StaticRefPtr
<IndentCommand
> IndentCommand::sInstance
;
397 bool IndentCommand::IsCommandEnabled(Command aCommand
,
398 EditorBase
* aEditorBase
) const {
399 HTMLEditor
* htmlEditor
= HTMLEditor::GetFrom(aEditorBase
);
403 return htmlEditor
->IsModifiable() && htmlEditor
->IsSelectionEditable();
406 nsresult
IndentCommand::DoCommand(Command aCommand
, EditorBase
& aEditorBase
,
407 nsIPrincipal
* aPrincipal
) const {
408 HTMLEditor
* htmlEditor
= aEditorBase
.GetAsHTMLEditor();
409 if (NS_WARN_IF(!htmlEditor
)) {
412 nsresult rv
= MOZ_KnownLive(htmlEditor
)->IndentAsAction(aPrincipal
);
413 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv
), "HTMLEditor::IndentAsAction() failed");
417 nsresult
IndentCommand::GetCommandStateParams(
418 Command aCommand
, nsCommandParams
& aParams
, EditorBase
* aEditorBase
,
419 nsIEditingSession
* aEditingSession
) const {
420 return aParams
.SetBool(STATE_ENABLED
,
421 IsCommandEnabled(aCommand
, aEditorBase
));
424 /*****************************************************************************
425 * mozilla::OutdentCommand
426 *****************************************************************************/
428 StaticRefPtr
<OutdentCommand
> OutdentCommand::sInstance
;
430 bool OutdentCommand::IsCommandEnabled(Command aCommand
,
431 EditorBase
* aEditorBase
) const {
432 HTMLEditor
* htmlEditor
= HTMLEditor::GetFrom(aEditorBase
);
436 return htmlEditor
->IsModifiable() && htmlEditor
->IsSelectionEditable();
439 nsresult
OutdentCommand::DoCommand(Command aCommand
, EditorBase
& aEditorBase
,
440 nsIPrincipal
* aPrincipal
) const {
441 HTMLEditor
* htmlEditor
= aEditorBase
.GetAsHTMLEditor();
442 if (NS_WARN_IF(!htmlEditor
)) {
445 nsresult rv
= MOZ_KnownLive(htmlEditor
)->OutdentAsAction(aPrincipal
);
446 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv
),
447 "HTMLEditor::OutdentAsAction() failed");
451 nsresult
OutdentCommand::GetCommandStateParams(
452 Command aCommand
, nsCommandParams
& aParams
, EditorBase
* aEditorBase
,
453 nsIEditingSession
* aEditingSession
) const {
454 return aParams
.SetBool(STATE_ENABLED
,
455 IsCommandEnabled(aCommand
, aEditorBase
));
458 /*****************************************************************************
459 * mozilla::MultiStateCommandBase
460 *****************************************************************************/
462 bool MultiStateCommandBase::IsCommandEnabled(Command aCommand
,
463 EditorBase
* aEditorBase
) const {
464 HTMLEditor
* htmlEditor
= HTMLEditor::GetFrom(aEditorBase
);
468 // should be disabled sometimes, like if the current selection is an image
469 return htmlEditor
->IsModifiable() && htmlEditor
->IsSelectionEditable();
472 nsresult
MultiStateCommandBase::DoCommand(Command aCommand
,
473 EditorBase
& aEditorBase
,
474 nsIPrincipal
* aPrincipal
) const {
476 "who is calling MultiStateCommandBase::DoCommand (no implementation)?");
480 nsresult
MultiStateCommandBase::DoCommandParam(Command aCommand
,
481 const nsAString
& aStringParam
,
482 EditorBase
& aEditorBase
,
483 nsIPrincipal
* aPrincipal
) const {
484 NS_WARNING_ASSERTION(aCommand
!= Command::FormatJustify
,
485 "Command::FormatJustify should be used only for "
486 "IsCommandEnabled() and GetCommandStateParams()");
487 HTMLEditor
* htmlEditor
= aEditorBase
.GetAsHTMLEditor();
488 if (NS_WARN_IF(!htmlEditor
)) {
489 return NS_ERROR_FAILURE
;
491 nsresult rv
= SetState(MOZ_KnownLive(htmlEditor
), aStringParam
, aPrincipal
);
492 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv
),
493 "MultiStateCommandBase::SetState() failed");
497 nsresult
MultiStateCommandBase::GetCommandStateParams(
498 Command aCommand
, nsCommandParams
& aParams
, EditorBase
* aEditorBase
,
499 nsIEditingSession
* aEditingSession
) const {
503 HTMLEditor
* htmlEditor
= aEditorBase
->GetAsHTMLEditor();
504 if (NS_WARN_IF(!htmlEditor
)) {
505 return NS_ERROR_FAILURE
;
507 nsresult rv
= GetCurrentState(MOZ_KnownLive(htmlEditor
), aParams
);
508 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv
),
509 "MultiStateCommandBase::GetCurrentState() failed");
513 /*****************************************************************************
514 * mozilla::FormatBlockStateCommand
515 *****************************************************************************/
517 StaticRefPtr
<FormatBlockStateCommand
> FormatBlockStateCommand::sInstance
;
519 nsresult
FormatBlockStateCommand::GetCurrentState(
520 HTMLEditor
* aHTMLEditor
, nsCommandParams
& aParams
) const {
521 if (NS_WARN_IF(!aHTMLEditor
)) {
522 return NS_ERROR_INVALID_ARG
;
526 ParagraphStateAtSelection
state(
528 ParagraphStateAtSelection::FormatBlockMode::HTMLFormatBlockCommand
,
530 if (error
.Failed()) {
531 NS_WARNING("ParagraphStateAtSelection failed");
532 return error
.StealNSResult();
534 aParams
.SetBool(STATE_MIXED
, state
.IsMixed());
535 if (NS_WARN_IF(!state
.GetFirstParagraphStateAtSelection())) {
536 aParams
.SetCString(STATE_ATTRIBUTE
, ""_ns
);
538 nsCString paragraphState
; // Don't use `nsAutoCString` for avoiding copy.
539 state
.GetFirstParagraphStateAtSelection()->ToUTF8String(paragraphState
);
540 aParams
.SetCString(STATE_ATTRIBUTE
, paragraphState
);
545 nsresult
FormatBlockStateCommand::SetState(HTMLEditor
* aHTMLEditor
,
546 const nsAString
& aNewState
,
547 nsIPrincipal
* aPrincipal
) const {
548 if (NS_WARN_IF(!aHTMLEditor
) || NS_WARN_IF(aNewState
.IsEmpty())) {
549 return NS_ERROR_INVALID_ARG
;
551 nsresult rv
= aHTMLEditor
->FormatBlockAsAction(aNewState
, aPrincipal
);
552 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv
),
553 "HTMLEditor::FormatBlockAsAction() failed");
557 /*****************************************************************************
558 * mozilla::ParagraphStateCommand
559 *****************************************************************************/
561 StaticRefPtr
<ParagraphStateCommand
> ParagraphStateCommand::sInstance
;
563 nsresult
ParagraphStateCommand::GetCurrentState(
564 HTMLEditor
* aHTMLEditor
, nsCommandParams
& aParams
) const {
565 if (NS_WARN_IF(!aHTMLEditor
)) {
566 return NS_ERROR_INVALID_ARG
;
570 ParagraphStateAtSelection
state(
572 ParagraphStateAtSelection::FormatBlockMode::XULParagraphStateCommand
,
574 if (error
.Failed()) {
575 NS_WARNING("ParagraphStateAtSelection failed");
576 return error
.StealNSResult();
578 aParams
.SetBool(STATE_MIXED
, state
.IsMixed());
579 if (NS_WARN_IF(!state
.GetFirstParagraphStateAtSelection())) {
580 // XXX This is odd behavior, we should fix this later.
581 aParams
.SetCString(STATE_ATTRIBUTE
, "x"_ns
);
583 nsCString paragraphState
; // Don't use `nsAutoCString` for avoiding copy.
584 state
.GetFirstParagraphStateAtSelection()->ToUTF8String(paragraphState
);
585 aParams
.SetCString(STATE_ATTRIBUTE
, paragraphState
);
590 nsresult
ParagraphStateCommand::SetState(HTMLEditor
* aHTMLEditor
,
591 const nsAString
& aNewState
,
592 nsIPrincipal
* aPrincipal
) const {
593 if (NS_WARN_IF(!aHTMLEditor
)) {
594 return NS_ERROR_INVALID_ARG
;
596 nsresult rv
= aHTMLEditor
->SetParagraphStateAsAction(aNewState
, aPrincipal
);
597 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv
),
598 "HTMLEditor::SetParagraphStateAsAction() failed");
602 /*****************************************************************************
603 * mozilla::FontFaceStateCommand
604 *****************************************************************************/
606 StaticRefPtr
<FontFaceStateCommand
> FontFaceStateCommand::sInstance
;
608 nsresult
FontFaceStateCommand::GetCurrentState(HTMLEditor
* aHTMLEditor
,
609 nsCommandParams
& aParams
) const {
610 if (NS_WARN_IF(!aHTMLEditor
)) {
611 return NS_ERROR_INVALID_ARG
;
614 nsAutoString outStateString
;
616 nsresult rv
= aHTMLEditor
->GetFontFaceState(&outMixed
, outStateString
);
618 NS_WARNING("HTMLEditor::GetFontFaceState() failed");
621 aParams
.SetBool(STATE_MIXED
, outMixed
);
622 aParams
.SetCString(STATE_ATTRIBUTE
, NS_ConvertUTF16toUTF8(outStateString
));
626 nsresult
FontFaceStateCommand::SetState(HTMLEditor
* aHTMLEditor
,
627 const nsAString
& aNewState
,
628 nsIPrincipal
* aPrincipal
) const {
629 if (NS_WARN_IF(!aHTMLEditor
)) {
630 return NS_ERROR_INVALID_ARG
;
633 if (aNewState
.IsEmpty() || aNewState
.EqualsLiteral("normal")) {
634 nsresult rv
= aHTMLEditor
->RemoveInlinePropertyAsAction(
635 *nsGkAtoms::font
, nsGkAtoms::face
, aPrincipal
);
636 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv
),
637 "HTMLEditor::RemoveInlinePropertyAsAction(nsGkAtoms::"
638 "font, nsGkAtoms::face) failed");
642 nsresult rv
= aHTMLEditor
->SetInlinePropertyAsAction(
643 *nsGkAtoms::font
, nsGkAtoms::face
, aNewState
, aPrincipal
);
644 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv
),
645 "HTMLEditor::SetInlinePropertyAsAction(nsGkAtoms::font, "
646 "nsGkAtoms::face) failed");
650 /*****************************************************************************
651 * mozilla::FontSizeStateCommand
652 *****************************************************************************/
654 StaticRefPtr
<FontSizeStateCommand
> FontSizeStateCommand::sInstance
;
656 nsresult
FontSizeStateCommand::GetCurrentState(HTMLEditor
* aHTMLEditor
,
657 nsCommandParams
& aParams
) const {
658 if (NS_WARN_IF(!aHTMLEditor
)) {
659 return NS_ERROR_INVALID_ARG
;
662 nsAutoString outStateString
;
663 bool firstHas
, anyHas
, allHas
;
664 nsresult rv
= aHTMLEditor
->GetInlinePropertyWithAttrValue(
665 *nsGkAtoms::font
, nsGkAtoms::size
, u
""_ns
, &firstHas
, &anyHas
, &allHas
,
669 "HTMLEditor::GetInlinePropertyWithAttrValue(nsGkAtoms::font, "
670 "nsGkAtoms::size) failed");
674 nsAutoCString tOutStateString
;
675 LossyCopyUTF16toASCII(outStateString
, tOutStateString
);
676 aParams
.SetBool(STATE_MIXED
, anyHas
&& !allHas
);
677 aParams
.SetCString(STATE_ATTRIBUTE
, tOutStateString
);
678 aParams
.SetBool(STATE_ENABLED
, true);
683 // acceptable values for "aNewState" are:
692 nsresult
FontSizeStateCommand::SetState(HTMLEditor
* aHTMLEditor
,
693 const nsAString
& aNewState
,
694 nsIPrincipal
* aPrincipal
) const {
695 if (NS_WARN_IF(!aHTMLEditor
)) {
696 return NS_ERROR_INVALID_ARG
;
699 if (!aNewState
.IsEmpty() && !aNewState
.EqualsLiteral("normal") &&
700 !aNewState
.EqualsLiteral("medium")) {
701 nsresult rv
= aHTMLEditor
->SetInlinePropertyAsAction(
702 *nsGkAtoms::font
, nsGkAtoms::size
, aNewState
, aPrincipal
);
703 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv
),
704 "HTMLEditor::SetInlinePropertyAsAction(nsGkAtoms::"
705 "font, nsGkAtoms::size) failed");
709 // remove any existing font size, big or small
710 nsresult rv
= aHTMLEditor
->RemoveInlinePropertyAsAction(
711 *nsGkAtoms::font
, nsGkAtoms::size
, aPrincipal
);
712 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv
),
713 "HTMLEditor::RemoveInlinePropertyAsAction(nsGkAtoms::"
714 "font, nsGkAtoms::size) failed");
718 /*****************************************************************************
719 * mozilla::FontColorStateCommand
720 *****************************************************************************/
722 StaticRefPtr
<FontColorStateCommand
> FontColorStateCommand::sInstance
;
724 nsresult
FontColorStateCommand::GetCurrentState(
725 HTMLEditor
* aHTMLEditor
, nsCommandParams
& aParams
) const {
726 if (NS_WARN_IF(!aHTMLEditor
)) {
727 return NS_ERROR_INVALID_ARG
;
731 nsAutoString outStateString
;
732 nsresult rv
= aHTMLEditor
->GetFontColorState(&outMixed
, outStateString
);
734 NS_WARNING("HTMLEditor::GetFontColorState() failed");
738 nsAutoCString tOutStateString
;
739 LossyCopyUTF16toASCII(outStateString
, tOutStateString
);
740 aParams
.SetBool(STATE_MIXED
, outMixed
);
741 aParams
.SetCString(STATE_ATTRIBUTE
, tOutStateString
);
745 nsresult
FontColorStateCommand::SetState(HTMLEditor
* aHTMLEditor
,
746 const nsAString
& aNewState
,
747 nsIPrincipal
* aPrincipal
) const {
748 if (NS_WARN_IF(!aHTMLEditor
)) {
749 return NS_ERROR_INVALID_ARG
;
752 if (aNewState
.IsEmpty() || aNewState
.EqualsLiteral("normal")) {
753 nsresult rv
= aHTMLEditor
->RemoveInlinePropertyAsAction(
754 *nsGkAtoms::font
, nsGkAtoms::color
, aPrincipal
);
755 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv
),
756 "HTMLEditor::RemoveInlinePropertyAsAction(nsGkAtoms::"
757 "font, nsGkAtoms::color) failed");
761 nsresult rv
= aHTMLEditor
->SetInlinePropertyAsAction(
762 *nsGkAtoms::font
, nsGkAtoms::color
, aNewState
, aPrincipal
);
763 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv
),
764 "HTMLEditor::SetInlinePropertyAsAction(nsGkAtoms::font, "
765 "nsGkAtoms::color) failed");
769 /*****************************************************************************
770 * mozilla::HighlightColorStateCommand
771 *****************************************************************************/
773 StaticRefPtr
<HighlightColorStateCommand
> HighlightColorStateCommand::sInstance
;
775 nsresult
HighlightColorStateCommand::GetCurrentState(
776 HTMLEditor
* aHTMLEditor
, nsCommandParams
& aParams
) const {
777 if (NS_WARN_IF(!aHTMLEditor
)) {
778 return NS_ERROR_INVALID_ARG
;
782 nsAutoString outStateString
;
783 nsresult rv
= aHTMLEditor
->GetHighlightColorState(&outMixed
, outStateString
);
785 NS_WARNING("HTMLEditor::GetHighlightColorState() failed");
789 nsAutoCString tOutStateString
;
790 LossyCopyUTF16toASCII(outStateString
, tOutStateString
);
791 aParams
.SetBool(STATE_MIXED
, outMixed
);
792 aParams
.SetCString(STATE_ATTRIBUTE
, tOutStateString
);
796 nsresult
HighlightColorStateCommand::SetState(HTMLEditor
* aHTMLEditor
,
797 const nsAString
& aNewState
,
798 nsIPrincipal
* aPrincipal
) const {
799 if (NS_WARN_IF(!aHTMLEditor
)) {
800 return NS_ERROR_INVALID_ARG
;
803 if (aNewState
.IsEmpty() || aNewState
.EqualsLiteral("normal")) {
804 nsresult rv
= aHTMLEditor
->RemoveInlinePropertyAsAction(
805 *nsGkAtoms::font
, nsGkAtoms::bgcolor
, aPrincipal
);
806 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv
),
807 "HTMLEditor::RemoveInlinePropertyAsAction(nsGkAtoms::"
808 "font, nsGkAtoms::bgcolor) failed");
812 nsresult rv
= aHTMLEditor
->SetInlinePropertyAsAction(
813 *nsGkAtoms::font
, nsGkAtoms::bgcolor
, aNewState
, aPrincipal
);
814 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv
),
815 "HTMLEditor::SetInlinePropertyAsAction(nsGkAtoms::font, "
816 "nsGkAtoms::bgcolor) failed");
820 /*****************************************************************************
821 * mozilla::BackgroundColorStateCommand
822 *****************************************************************************/
824 StaticRefPtr
<BackgroundColorStateCommand
>
825 BackgroundColorStateCommand::sInstance
;
827 nsresult
BackgroundColorStateCommand::GetCurrentState(
828 HTMLEditor
* aHTMLEditor
, nsCommandParams
& aParams
) const {
829 if (NS_WARN_IF(!aHTMLEditor
)) {
830 return NS_ERROR_INVALID_ARG
;
834 nsAutoString outStateString
;
835 nsresult rv
= aHTMLEditor
->GetBackgroundColorState(&outMixed
, outStateString
);
837 NS_WARNING("HTMLEditor::GetBackgroundColorState() failed");
841 nsAutoCString tOutStateString
;
842 LossyCopyUTF16toASCII(outStateString
, tOutStateString
);
843 aParams
.SetBool(STATE_MIXED
, outMixed
);
844 aParams
.SetCString(STATE_ATTRIBUTE
, tOutStateString
);
848 nsresult
BackgroundColorStateCommand::SetState(HTMLEditor
* aHTMLEditor
,
849 const nsAString
& aNewState
,
850 nsIPrincipal
* aPrincipal
) const {
851 if (NS_WARN_IF(!aHTMLEditor
)) {
852 return NS_ERROR_INVALID_ARG
;
854 nsresult rv
= aHTMLEditor
->SetBackgroundColorAsAction(aNewState
, aPrincipal
);
855 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv
),
856 "HTMLEditor::SetBackgroundColorAsAction() failed");
860 /*****************************************************************************
861 * mozilla::AlignCommand
862 *****************************************************************************/
864 StaticRefPtr
<AlignCommand
> AlignCommand::sInstance
;
866 nsresult
AlignCommand::GetCurrentState(HTMLEditor
* aHTMLEditor
,
867 nsCommandParams
& aParams
) const {
868 if (NS_WARN_IF(!aHTMLEditor
)) {
869 return NS_ERROR_INVALID_ARG
;
873 AlignStateAtSelection
state(*aHTMLEditor
, error
);
874 if (error
.Failed()) {
875 if (!state
.IsSelectionRangesFound()) {
876 // If there was no selection ranges, we shouldn't throw exception for
877 // compatibility with the other browsers, but I have no better idea
878 // than returning empty string in this case. Oddly, Blink/WebKit returns
879 // "true" or "false", but it's different from us and the value does not
880 // make sense. Additionally, WPT loves our behavior.
881 error
.SuppressException();
882 aParams
.SetBool(STATE_MIXED
, false);
883 aParams
.SetCString(STATE_ATTRIBUTE
, ""_ns
);
886 NS_WARNING("AlignStateAtSelection failed");
887 return error
.StealNSResult();
889 nsCString alignment
; // Don't use `nsAutoCString` to avoid copying string.
890 switch (state
.AlignmentAtSelectionStart()) {
892 case nsIHTMLEditor::eLeft
:
893 alignment
.AssignLiteral("left");
895 case nsIHTMLEditor::eCenter
:
896 alignment
.AssignLiteral("center");
898 case nsIHTMLEditor::eRight
:
899 alignment
.AssignLiteral("right");
901 case nsIHTMLEditor::eJustify
:
902 alignment
.AssignLiteral("justify");
905 aParams
.SetBool(STATE_MIXED
, false);
906 aParams
.SetCString(STATE_ATTRIBUTE
, alignment
);
910 nsresult
AlignCommand::SetState(HTMLEditor
* aHTMLEditor
,
911 const nsAString
& aNewState
,
912 nsIPrincipal
* aPrincipal
) const {
913 if (NS_WARN_IF(!aHTMLEditor
)) {
914 return NS_ERROR_INVALID_ARG
;
916 nsresult rv
= aHTMLEditor
->AlignAsAction(aNewState
, aPrincipal
);
917 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv
), "HTMLEditor::AlignAsAction() failed");
921 /*****************************************************************************
922 * mozilla::AbsolutePositioningCommand
923 *****************************************************************************/
925 StaticRefPtr
<AbsolutePositioningCommand
> AbsolutePositioningCommand::sInstance
;
927 nsresult
AbsolutePositioningCommand::GetCurrentState(
928 nsStaticAtom
& aTagName
, HTMLEditor
& aHTMLEditor
,
929 nsCommandParams
& aParams
) const {
930 if (!aHTMLEditor
.IsAbsolutePositionEditorEnabled()) {
931 aParams
.SetBool(STATE_MIXED
, false);
932 aParams
.SetCString(STATE_ATTRIBUTE
, ""_ns
);
936 RefPtr
<Element
> container
=
937 aHTMLEditor
.GetAbsolutelyPositionedSelectionContainer();
938 aParams
.SetBool(STATE_MIXED
, false);
939 aParams
.SetCString(STATE_ATTRIBUTE
, container
? "absolute"_ns
: ""_ns
);
943 nsresult
AbsolutePositioningCommand::ToggleState(
944 nsStaticAtom
& aTagName
, HTMLEditor
& aHTMLEditor
,
945 nsIPrincipal
* aPrincipal
) const {
946 RefPtr
<Element
> container
=
947 aHTMLEditor
.GetAbsolutelyPositionedSelectionContainer();
948 nsresult rv
= aHTMLEditor
.SetSelectionToAbsoluteOrStaticAsAction(!container
,
950 NS_WARNING_ASSERTION(
952 "HTMLEditor::SetSelectionToAbsoluteOrStaticAsAction() failed");
956 /*****************************************************************************
957 * mozilla::DecreaseZIndexCommand
958 *****************************************************************************/
960 StaticRefPtr
<DecreaseZIndexCommand
> DecreaseZIndexCommand::sInstance
;
962 bool DecreaseZIndexCommand::IsCommandEnabled(Command aCommand
,
963 EditorBase
* aEditorBase
) const {
964 RefPtr
<HTMLEditor
> htmlEditor
= HTMLEditor::GetFrom(aEditorBase
);
968 if (!htmlEditor
->IsAbsolutePositionEditorEnabled()) {
971 RefPtr
<Element
> positionedElement
= htmlEditor
->GetPositionedElement();
972 if (!positionedElement
) {
975 return htmlEditor
->GetZIndex(*positionedElement
) > 0;
978 nsresult
DecreaseZIndexCommand::DoCommand(Command aCommand
,
979 EditorBase
& aEditorBase
,
980 nsIPrincipal
* aPrincipal
) const {
981 HTMLEditor
* htmlEditor
= aEditorBase
.GetAsHTMLEditor();
982 if (NS_WARN_IF(!htmlEditor
)) {
983 return NS_ERROR_FAILURE
;
985 nsresult rv
= MOZ_KnownLive(htmlEditor
)->AddZIndexAsAction(-1, aPrincipal
);
986 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv
),
987 "HTMLEditor::AddZIndexAsAction(-1) failed");
991 nsresult
DecreaseZIndexCommand::GetCommandStateParams(
992 Command aCommand
, nsCommandParams
& aParams
, EditorBase
* aEditorBase
,
993 nsIEditingSession
* aEditingSession
) const {
994 return aParams
.SetBool(STATE_ENABLED
,
995 IsCommandEnabled(aCommand
, aEditorBase
));
998 /*****************************************************************************
999 * mozilla::IncreaseZIndexCommand
1000 *****************************************************************************/
1002 StaticRefPtr
<IncreaseZIndexCommand
> IncreaseZIndexCommand::sInstance
;
1004 bool IncreaseZIndexCommand::IsCommandEnabled(Command aCommand
,
1005 EditorBase
* aEditorBase
) const {
1006 HTMLEditor
* htmlEditor
= HTMLEditor::GetFrom(aEditorBase
);
1010 if (!htmlEditor
->IsAbsolutePositionEditorEnabled()) {
1013 return !!htmlEditor
->GetPositionedElement();
1016 nsresult
IncreaseZIndexCommand::DoCommand(Command aCommand
,
1017 EditorBase
& aEditorBase
,
1018 nsIPrincipal
* aPrincipal
) const {
1019 HTMLEditor
* htmlEditor
= aEditorBase
.GetAsHTMLEditor();
1020 if (NS_WARN_IF(!htmlEditor
)) {
1021 return NS_ERROR_FAILURE
;
1023 nsresult rv
= MOZ_KnownLive(htmlEditor
)->AddZIndexAsAction(1, aPrincipal
);
1024 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv
),
1025 "HTMLEditor::AddZIndexAsAction(1) failed");
1029 nsresult
IncreaseZIndexCommand::GetCommandStateParams(
1030 Command aCommand
, nsCommandParams
& aParams
, EditorBase
* aEditorBase
,
1031 nsIEditingSession
* aEditingSession
) const {
1032 return aParams
.SetBool(STATE_ENABLED
,
1033 IsCommandEnabled(aCommand
, aEditorBase
));
1036 /*****************************************************************************
1037 * mozilla::RemoveStylesCommand
1038 *****************************************************************************/
1040 StaticRefPtr
<RemoveStylesCommand
> RemoveStylesCommand::sInstance
;
1042 bool RemoveStylesCommand::IsCommandEnabled(Command aCommand
,
1043 EditorBase
* aEditorBase
) const {
1044 HTMLEditor
* htmlEditor
= HTMLEditor::GetFrom(aEditorBase
);
1048 // test if we have any styles?
1049 return htmlEditor
->IsModifiable() && htmlEditor
->IsSelectionEditable();
1052 nsresult
RemoveStylesCommand::DoCommand(Command aCommand
,
1053 EditorBase
& aEditorBase
,
1054 nsIPrincipal
* aPrincipal
) const {
1055 HTMLEditor
* htmlEditor
= aEditorBase
.GetAsHTMLEditor();
1056 if (NS_WARN_IF(!htmlEditor
)) {
1060 MOZ_KnownLive(htmlEditor
)->RemoveAllInlinePropertiesAsAction(aPrincipal
);
1061 NS_WARNING_ASSERTION(
1063 "HTMLEditor::RemoveAllInlinePropertiesAsAction() failed");
1067 nsresult
RemoveStylesCommand::GetCommandStateParams(
1068 Command aCommand
, nsCommandParams
& aParams
, EditorBase
* aEditorBase
,
1069 nsIEditingSession
* aEditingSession
) const {
1070 return aParams
.SetBool(STATE_ENABLED
,
1071 IsCommandEnabled(aCommand
, aEditorBase
));
1074 /*****************************************************************************
1075 * mozilla::IncreaseFontSizeCommand
1076 *****************************************************************************/
1078 StaticRefPtr
<IncreaseFontSizeCommand
> IncreaseFontSizeCommand::sInstance
;
1080 bool IncreaseFontSizeCommand::IsCommandEnabled(Command aCommand
,
1081 EditorBase
* aEditorBase
) const {
1082 HTMLEditor
* htmlEditor
= HTMLEditor::GetFrom(aEditorBase
);
1086 // test if we are at max size?
1087 return htmlEditor
->IsModifiable() && htmlEditor
->IsSelectionEditable();
1090 nsresult
IncreaseFontSizeCommand::DoCommand(Command aCommand
,
1091 EditorBase
& aEditorBase
,
1092 nsIPrincipal
* aPrincipal
) const {
1093 HTMLEditor
* htmlEditor
= aEditorBase
.GetAsHTMLEditor();
1094 if (NS_WARN_IF(!htmlEditor
)) {
1097 nsresult rv
= MOZ_KnownLive(htmlEditor
)->IncreaseFontSizeAsAction(aPrincipal
);
1098 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv
),
1099 "HTMLEditor::IncreaseFontSizeAsAction() failed");
1103 nsresult
IncreaseFontSizeCommand::GetCommandStateParams(
1104 Command aCommand
, nsCommandParams
& aParams
, EditorBase
* aEditorBase
,
1105 nsIEditingSession
* aEditingSession
) const {
1106 return aParams
.SetBool(STATE_ENABLED
,
1107 IsCommandEnabled(aCommand
, aEditorBase
));
1110 /*****************************************************************************
1111 * mozilla::DecreaseFontSizeCommand
1112 *****************************************************************************/
1114 StaticRefPtr
<DecreaseFontSizeCommand
> DecreaseFontSizeCommand::sInstance
;
1116 bool DecreaseFontSizeCommand::IsCommandEnabled(Command aCommand
,
1117 EditorBase
* aEditorBase
) const {
1118 HTMLEditor
* htmlEditor
= HTMLEditor::GetFrom(aEditorBase
);
1122 // test if we are at min size?
1123 return htmlEditor
->IsModifiable() && htmlEditor
->IsSelectionEditable();
1126 nsresult
DecreaseFontSizeCommand::DoCommand(Command aCommand
,
1127 EditorBase
& aEditorBase
,
1128 nsIPrincipal
* aPrincipal
) const {
1129 HTMLEditor
* htmlEditor
= aEditorBase
.GetAsHTMLEditor();
1130 if (NS_WARN_IF(!htmlEditor
)) {
1133 nsresult rv
= MOZ_KnownLive(htmlEditor
)->DecreaseFontSizeAsAction(aPrincipal
);
1134 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv
),
1135 "HTMLEditor::DecreaseFontSizeAsAction() failed");
1139 nsresult
DecreaseFontSizeCommand::GetCommandStateParams(
1140 Command aCommand
, nsCommandParams
& aParams
, EditorBase
* aEditorBase
,
1141 nsIEditingSession
* aEditingSession
) const {
1142 return aParams
.SetBool(STATE_ENABLED
,
1143 IsCommandEnabled(aCommand
, aEditorBase
));
1146 /*****************************************************************************
1147 * mozilla::InsertHTMLCommand
1148 *****************************************************************************/
1150 StaticRefPtr
<InsertHTMLCommand
> InsertHTMLCommand::sInstance
;
1152 bool InsertHTMLCommand::IsCommandEnabled(Command aCommand
,
1153 EditorBase
* aEditorBase
) const {
1154 HTMLEditor
* htmlEditor
= HTMLEditor::GetFrom(aEditorBase
);
1158 return htmlEditor
->IsModifiable() && htmlEditor
->IsSelectionEditable();
1161 nsresult
InsertHTMLCommand::DoCommand(Command aCommand
, EditorBase
& aEditorBase
,
1162 nsIPrincipal
* aPrincipal
) const {
1163 // If InsertHTMLCommand is called with no parameters, it was probably called
1164 // with an empty string parameter ''. In this case, it should act the same as
1165 // the delete command
1166 HTMLEditor
* htmlEditor
= aEditorBase
.GetAsHTMLEditor();
1167 if (NS_WARN_IF(!htmlEditor
)) {
1168 return NS_ERROR_FAILURE
;
1171 MOZ_KnownLive(htmlEditor
)->InsertHTMLAsAction(u
""_ns
, aPrincipal
);
1172 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv
),
1173 "HTMLEditor::InsertHTMLAsAction() failed");
1177 nsresult
InsertHTMLCommand::DoCommandParam(Command aCommand
,
1178 const nsAString
& aStringParam
,
1179 EditorBase
& aEditorBase
,
1180 nsIPrincipal
* aPrincipal
) const {
1181 if (NS_WARN_IF(aStringParam
.IsVoid())) {
1182 return NS_ERROR_INVALID_ARG
;
1185 HTMLEditor
* htmlEditor
= aEditorBase
.GetAsHTMLEditor();
1186 if (NS_WARN_IF(!htmlEditor
)) {
1187 return NS_ERROR_FAILURE
;
1190 MOZ_KnownLive(htmlEditor
)->InsertHTMLAsAction(aStringParam
, aPrincipal
);
1191 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv
),
1192 "HTMLEditor::InsertHTMLAsAction() failed");
1196 nsresult
InsertHTMLCommand::GetCommandStateParams(
1197 Command aCommand
, nsCommandParams
& aParams
, EditorBase
* aEditorBase
,
1198 nsIEditingSession
* aEditingSession
) const {
1199 return aParams
.SetBool(STATE_ENABLED
,
1200 IsCommandEnabled(aCommand
, aEditorBase
));
1203 /*****************************************************************************
1204 * mozilla::InsertTagCommand
1205 *****************************************************************************/
1207 StaticRefPtr
<InsertTagCommand
> InsertTagCommand::sInstance
;
1209 bool InsertTagCommand::IsCommandEnabled(Command aCommand
,
1210 EditorBase
* aEditorBase
) const {
1211 HTMLEditor
* htmlEditor
= HTMLEditor::GetFrom(aEditorBase
);
1215 return htmlEditor
->IsModifiable() && htmlEditor
->IsSelectionEditable();
1218 // corresponding STATE_ATTRIBUTE is: src (img) and href (a)
1219 nsresult
InsertTagCommand::DoCommand(Command aCommand
, EditorBase
& aEditorBase
,
1220 nsIPrincipal
* aPrincipal
) const {
1221 nsAtom
* tagName
= GetTagName(aCommand
);
1222 if (NS_WARN_IF(tagName
!= nsGkAtoms::hr
)) {
1223 return NS_ERROR_NOT_IMPLEMENTED
;
1226 HTMLEditor
* htmlEditor
= aEditorBase
.GetAsHTMLEditor();
1227 if (NS_WARN_IF(!htmlEditor
)) {
1228 return NS_ERROR_FAILURE
;
1231 RefPtr
<Element
> newElement
=
1232 MOZ_KnownLive(htmlEditor
)
1233 ->CreateElementWithDefaults(MOZ_KnownLive(*tagName
));
1234 if (NS_WARN_IF(!newElement
)) {
1235 return NS_ERROR_FAILURE
;
1238 MOZ_KnownLive(htmlEditor
)
1239 ->InsertElementAtSelectionAsAction(newElement
, true, aPrincipal
);
1240 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv
),
1241 "HTMLEditor::InsertElementAtSelectionAsAction() failed");
1245 nsresult
InsertTagCommand::DoCommandParam(Command aCommand
,
1246 const nsAString
& aStringParam
,
1247 EditorBase
& aEditorBase
,
1248 nsIPrincipal
* aPrincipal
) const {
1249 MOZ_ASSERT(aCommand
!= Command::InsertHorizontalRule
);
1251 if (NS_WARN_IF(aStringParam
.IsEmpty())) {
1252 return NS_ERROR_INVALID_ARG
;
1254 nsAtom
* tagName
= GetTagName(aCommand
);
1255 if (NS_WARN_IF(!tagName
)) {
1256 return NS_ERROR_UNEXPECTED
;
1259 HTMLEditor
* htmlEditor
= aEditorBase
.GetAsHTMLEditor();
1260 if (NS_WARN_IF(!htmlEditor
)) {
1261 return NS_ERROR_FAILURE
;
1264 // filter out tags we don't know how to insert
1265 nsAtom
* attribute
= nullptr;
1266 if (tagName
== nsGkAtoms::a
) {
1267 attribute
= nsGkAtoms::href
;
1268 } else if (tagName
== nsGkAtoms::img
) {
1269 attribute
= nsGkAtoms::src
;
1271 return NS_ERROR_NOT_IMPLEMENTED
;
1274 RefPtr
<Element
> newElement
=
1275 MOZ_KnownLive(htmlEditor
)
1276 ->CreateElementWithDefaults(MOZ_KnownLive(*tagName
));
1278 NS_WARNING("HTMLEditor::CreateElementWithDefaults() failed");
1279 return NS_ERROR_FAILURE
;
1283 newElement
->SetAttr(attribute
, aStringParam
, error
);
1284 if (error
.Failed()) {
1285 NS_WARNING("Element::SetAttr() failed");
1286 return error
.StealNSResult();
1289 // do actual insertion
1290 if (tagName
== nsGkAtoms::a
) {
1292 MOZ_KnownLive(htmlEditor
)
1293 ->InsertLinkAroundSelectionAsAction(newElement
, aPrincipal
);
1294 NS_WARNING_ASSERTION(
1296 "HTMLEditor::InsertLinkAroundSelectionAsAction() failed");
1301 MOZ_KnownLive(htmlEditor
)
1302 ->InsertElementAtSelectionAsAction(newElement
, true, aPrincipal
);
1303 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv
),
1304 "HTMLEditor::InsertElementAtSelectionAsAction() failed");
1308 nsresult
InsertTagCommand::GetCommandStateParams(
1309 Command aCommand
, nsCommandParams
& aParams
, EditorBase
* aEditorBase
,
1310 nsIEditingSession
* aEditingSession
) const {
1311 return aParams
.SetBool(STATE_ENABLED
,
1312 IsCommandEnabled(aCommand
, aEditorBase
));
1315 /*****************************************************************************
1317 *****************************************************************************/
1319 static nsresult
GetListState(HTMLEditor
* aHTMLEditor
, bool* aMixed
,
1320 nsAString
& aLocalName
) {
1321 MOZ_ASSERT(aHTMLEditor
);
1325 aLocalName
.Truncate();
1328 ListElementSelectionState
state(*aHTMLEditor
, error
);
1329 if (error
.Failed()) {
1330 NS_WARNING("ListElementSelectionState failed");
1331 return error
.StealNSResult();
1333 if (state
.IsNotOneTypeListElementSelected()) {
1338 if (state
.IsOLElementSelected()) {
1339 aLocalName
.AssignLiteral("ol");
1340 } else if (state
.IsULElementSelected()) {
1341 aLocalName
.AssignLiteral("ul");
1342 } else if (state
.IsDLElementSelected()) {
1343 aLocalName
.AssignLiteral("dl");
1348 } // namespace mozilla