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 "nsEditorCommands.h"
8 #include "mozFlushType.h"
9 #include "mozilla/ArrayUtils.h"
10 #include "mozilla/Assertions.h"
15 #include "nsIClipboard.h"
16 #include "nsICommandParams.h"
18 #include "nsIDOMDocument.h"
19 #include "nsIDocument.h"
20 #include "nsIEditor.h"
21 #include "nsIEditorMailSupport.h"
22 #include "nsIPlaintextEditor.h"
23 #include "nsISelection.h"
24 #include "nsISelectionController.h"
25 #include "nsITransferable.h"
27 #include "nsAString.h"
31 #define STATE_ENABLED "state_enabled"
32 #define STATE_DATA "state_data"
34 nsBaseEditorCommand::nsBaseEditorCommand() {}
36 NS_IMPL_ISUPPORTS(nsBaseEditorCommand
, nsIControllerCommand
)
39 nsUndoCommand::IsCommandEnabled(const char *aCommandName
,
40 nsISupports
*aCommandRefCon
,
43 NS_ENSURE_ARG_POINTER(outCmdEnabled
);
44 nsCOMPtr
<nsIEditor
> editor
= do_QueryInterface(aCommandRefCon
);
46 bool isEnabled
, isEditable
= false;
47 nsresult rv
= editor
->GetIsSelectionEditable(&isEditable
);
48 NS_ENSURE_SUCCESS(rv
, rv
);
50 return editor
->CanUndo(&isEnabled
, outCmdEnabled
);
53 *outCmdEnabled
= false;
58 nsUndoCommand::DoCommand(const char *aCommandName
, nsISupports
*aCommandRefCon
)
60 nsCOMPtr
<nsIEditor
> editor
= do_QueryInterface(aCommandRefCon
);
62 return editor
->Undo(1);
64 return NS_ERROR_FAILURE
;
68 nsUndoCommand::DoCommandParams(const char *aCommandName
,
69 nsICommandParams
*aParams
,
70 nsISupports
*aCommandRefCon
)
72 return DoCommand(aCommandName
, aCommandRefCon
);
76 nsUndoCommand::GetCommandStateParams(const char *aCommandName
,
77 nsICommandParams
*aParams
,
78 nsISupports
*aCommandRefCon
)
81 IsCommandEnabled(aCommandName
, aCommandRefCon
, &canUndo
);
82 return aParams
->SetBooleanValue(STATE_ENABLED
, canUndo
);
86 nsRedoCommand::IsCommandEnabled(const char *aCommandName
,
87 nsISupports
*aCommandRefCon
,
90 NS_ENSURE_ARG_POINTER(outCmdEnabled
);
91 nsCOMPtr
<nsIEditor
> editor
= do_QueryInterface(aCommandRefCon
);
93 bool isEnabled
, isEditable
= false;
94 nsresult rv
= editor
->GetIsSelectionEditable(&isEditable
);
95 NS_ENSURE_SUCCESS(rv
, rv
);
97 return editor
->CanRedo(&isEnabled
, outCmdEnabled
);
100 *outCmdEnabled
= false;
105 nsRedoCommand::DoCommand(const char *aCommandName
, nsISupports
*aCommandRefCon
)
107 nsCOMPtr
<nsIEditor
> editor
= do_QueryInterface(aCommandRefCon
);
109 return editor
->Redo(1);
111 return NS_ERROR_FAILURE
;
115 nsRedoCommand::DoCommandParams(const char *aCommandName
,
116 nsICommandParams
*aParams
,
117 nsISupports
*aCommandRefCon
)
119 return DoCommand(aCommandName
, aCommandRefCon
);
123 nsRedoCommand::GetCommandStateParams(const char *aCommandName
,
124 nsICommandParams
*aParams
,
125 nsISupports
*aCommandRefCon
)
128 IsCommandEnabled(aCommandName
, aCommandRefCon
, &canUndo
);
129 return aParams
->SetBooleanValue(STATE_ENABLED
, canUndo
);
133 nsClearUndoCommand::IsCommandEnabled(const char *aCommandName
,
134 nsISupports
*refCon
, bool *outCmdEnabled
)
136 NS_ENSURE_ARG_POINTER(outCmdEnabled
);
137 nsCOMPtr
<nsIEditor
> editor
= do_QueryInterface(refCon
);
139 return editor
->GetIsSelectionEditable(outCmdEnabled
);
141 *outCmdEnabled
= false;
146 nsClearUndoCommand::DoCommand(const char *aCommandName
, nsISupports
*refCon
)
148 nsCOMPtr
<nsIEditor
> editor
= do_QueryInterface(refCon
);
149 NS_ENSURE_TRUE(editor
, NS_ERROR_NOT_IMPLEMENTED
);
151 editor
->EnableUndo(false); // Turning off undo clears undo/redo stacks.
152 editor
->EnableUndo(true); // This re-enables undo/redo.
158 nsClearUndoCommand::DoCommandParams(const char *aCommandName
,
159 nsICommandParams
*aParams
,
162 return DoCommand(aCommandName
, refCon
);
166 nsClearUndoCommand::GetCommandStateParams(const char *aCommandName
,
167 nsICommandParams
*aParams
,
170 NS_ENSURE_ARG_POINTER(aParams
);
173 nsresult rv
= IsCommandEnabled(aCommandName
, refCon
, &enabled
);
174 NS_ENSURE_SUCCESS(rv
, rv
);
176 return aParams
->SetBooleanValue(STATE_ENABLED
, enabled
);
180 nsCutCommand::IsCommandEnabled(const char *aCommandName
,
181 nsISupports
*aCommandRefCon
, bool *outCmdEnabled
)
183 NS_ENSURE_ARG_POINTER(outCmdEnabled
);
184 nsCOMPtr
<nsIEditor
> editor
= do_QueryInterface(aCommandRefCon
);
186 bool isEditable
= false;
187 nsresult rv
= editor
->GetIsSelectionEditable(&isEditable
);
188 NS_ENSURE_SUCCESS(rv
, rv
);
190 return editor
->CanCut(outCmdEnabled
);
193 *outCmdEnabled
= false;
198 nsCutCommand::DoCommand(const char *aCommandName
, nsISupports
*aCommandRefCon
)
200 nsCOMPtr
<nsIEditor
> editor
= do_QueryInterface(aCommandRefCon
);
202 return editor
->Cut();
204 return NS_ERROR_FAILURE
;
208 nsCutCommand::DoCommandParams(const char *aCommandName
,
209 nsICommandParams
*aParams
,
210 nsISupports
*aCommandRefCon
)
212 return DoCommand(aCommandName
, aCommandRefCon
);
216 nsCutCommand::GetCommandStateParams(const char *aCommandName
,
217 nsICommandParams
*aParams
,
218 nsISupports
*aCommandRefCon
)
221 IsCommandEnabled(aCommandName
, aCommandRefCon
, &canUndo
);
222 return aParams
->SetBooleanValue(STATE_ENABLED
, canUndo
);
226 nsCutOrDeleteCommand::IsCommandEnabled(const char *aCommandName
,
227 nsISupports
*aCommandRefCon
,
230 NS_ENSURE_ARG_POINTER(outCmdEnabled
);
231 nsCOMPtr
<nsIEditor
> editor
= do_QueryInterface(aCommandRefCon
);
233 return editor
->GetIsSelectionEditable(outCmdEnabled
);
235 *outCmdEnabled
= false;
240 nsCutOrDeleteCommand::DoCommand(const char *aCommandName
,
241 nsISupports
*aCommandRefCon
)
243 nsCOMPtr
<nsIEditor
> editor
= do_QueryInterface(aCommandRefCon
);
245 nsCOMPtr
<nsISelection
> selection
;
246 nsresult rv
= editor
->GetSelection(getter_AddRefs(selection
));
247 if (NS_SUCCEEDED(rv
) && selection
&& selection
->Collapsed()) {
248 return editor
->DeleteSelection(nsIEditor::eNext
, nsIEditor::eStrip
);
250 return editor
->Cut();
253 return NS_ERROR_FAILURE
;
257 nsCutOrDeleteCommand::DoCommandParams(const char *aCommandName
,
258 nsICommandParams
*aParams
,
259 nsISupports
*aCommandRefCon
)
261 return DoCommand(aCommandName
, aCommandRefCon
);
265 nsCutOrDeleteCommand::GetCommandStateParams(const char *aCommandName
,
266 nsICommandParams
*aParams
,
267 nsISupports
*aCommandRefCon
)
270 IsCommandEnabled(aCommandName
, aCommandRefCon
, &canUndo
);
271 return aParams
->SetBooleanValue(STATE_ENABLED
, canUndo
);
275 nsCopyCommand::IsCommandEnabled(const char *aCommandName
,
276 nsISupports
*aCommandRefCon
,
279 NS_ENSURE_ARG_POINTER(outCmdEnabled
);
280 nsCOMPtr
<nsIEditor
> editor
= do_QueryInterface(aCommandRefCon
);
282 return editor
->CanCopy(outCmdEnabled
);
284 *outCmdEnabled
= false;
289 nsCopyCommand::DoCommand(const char *aCommandName
, nsISupports
*aCommandRefCon
)
291 nsCOMPtr
<nsIEditor
> editor
= do_QueryInterface(aCommandRefCon
);
293 return editor
->Copy();
295 return NS_ERROR_FAILURE
;
299 nsCopyCommand::DoCommandParams(const char *aCommandName
,
300 nsICommandParams
*aParams
,
301 nsISupports
*aCommandRefCon
)
303 return DoCommand(aCommandName
, aCommandRefCon
);
307 nsCopyCommand::GetCommandStateParams(const char *aCommandName
,
308 nsICommandParams
*aParams
,
309 nsISupports
*aCommandRefCon
)
312 IsCommandEnabled(aCommandName
, aCommandRefCon
, &canUndo
);
313 return aParams
->SetBooleanValue(STATE_ENABLED
, canUndo
);
317 nsCopyOrDeleteCommand::IsCommandEnabled(const char *aCommandName
,
318 nsISupports
*aCommandRefCon
,
321 NS_ENSURE_ARG_POINTER(outCmdEnabled
);
322 nsCOMPtr
<nsIEditor
> editor
= do_QueryInterface(aCommandRefCon
);
324 return editor
->GetIsSelectionEditable(outCmdEnabled
);
326 *outCmdEnabled
= false;
331 nsCopyOrDeleteCommand::DoCommand(const char *aCommandName
,
332 nsISupports
*aCommandRefCon
)
334 nsCOMPtr
<nsIEditor
> editor
= do_QueryInterface(aCommandRefCon
);
336 nsCOMPtr
<nsISelection
> selection
;
337 nsresult rv
= editor
->GetSelection(getter_AddRefs(selection
));
338 if (NS_SUCCEEDED(rv
) && selection
&& selection
->Collapsed()) {
339 return editor
->DeleteSelection(nsIEditor::eNextWord
, nsIEditor::eStrip
);
341 return editor
->Copy();
344 return NS_ERROR_FAILURE
;
348 nsCopyOrDeleteCommand::DoCommandParams(const char *aCommandName
,
349 nsICommandParams
*aParams
,
350 nsISupports
*aCommandRefCon
)
352 return DoCommand(aCommandName
, aCommandRefCon
);
356 nsCopyOrDeleteCommand::GetCommandStateParams(const char *aCommandName
,
357 nsICommandParams
*aParams
,
358 nsISupports
*aCommandRefCon
)
361 IsCommandEnabled(aCommandName
, aCommandRefCon
, &canUndo
);
362 return aParams
->SetBooleanValue(STATE_ENABLED
, canUndo
);
366 nsCopyAndCollapseToEndCommand::IsCommandEnabled(const char *aCommandName
,
367 nsISupports
*aCommandRefCon
,
370 NS_ENSURE_ARG_POINTER(outCmdEnabled
);
371 nsCOMPtr
<nsIEditor
> editor
= do_QueryInterface(aCommandRefCon
);
373 return editor
->CanCopy(outCmdEnabled
);
375 *outCmdEnabled
= false;
380 nsCopyAndCollapseToEndCommand::DoCommand(const char *aCommandName
,
381 nsISupports
*aCommandRefCon
)
383 nsCOMPtr
<nsIEditor
> editor
= do_QueryInterface(aCommandRefCon
);
385 nsresult rv
= editor
->Copy();
390 nsCOMPtr
<nsISelection
> selection
;
391 rv
= editor
->GetSelection(getter_AddRefs(selection
));
392 if (NS_SUCCEEDED(rv
) && selection
) {
393 selection
->CollapseToEnd();
398 return NS_ERROR_FAILURE
;
402 nsCopyAndCollapseToEndCommand::DoCommandParams(const char *aCommandName
,
403 nsICommandParams
*aParams
,
404 nsISupports
*aCommandRefCon
)
406 return DoCommand(aCommandName
, aCommandRefCon
);
410 nsCopyAndCollapseToEndCommand::GetCommandStateParams(
411 const char *aCommandName
, nsICommandParams
*aParams
,
412 nsISupports
*aCommandRefCon
)
415 IsCommandEnabled(aCommandName
, aCommandRefCon
, &canUndo
);
416 return aParams
->SetBooleanValue(STATE_ENABLED
, canUndo
);
420 nsPasteCommand::IsCommandEnabled(const char *aCommandName
,
421 nsISupports
*aCommandRefCon
,
424 NS_ENSURE_ARG_POINTER(outCmdEnabled
);
425 nsCOMPtr
<nsIEditor
> editor
= do_QueryInterface(aCommandRefCon
);
427 bool isEditable
= false;
428 nsresult rv
= editor
->GetIsSelectionEditable(&isEditable
);
429 NS_ENSURE_SUCCESS(rv
, rv
);
431 return editor
->CanPaste(nsIClipboard::kGlobalClipboard
, outCmdEnabled
);
434 *outCmdEnabled
= false;
439 nsPasteCommand::DoCommand(const char *aCommandName
, nsISupports
*aCommandRefCon
)
441 nsCOMPtr
<nsIEditor
> editor
= do_QueryInterface(aCommandRefCon
);
442 NS_ENSURE_TRUE(editor
, NS_ERROR_FAILURE
);
444 return editor
->Paste(nsIClipboard::kGlobalClipboard
);
448 nsPasteCommand::DoCommandParams(const char *aCommandName
,
449 nsICommandParams
*aParams
,
450 nsISupports
*aCommandRefCon
)
452 return DoCommand(aCommandName
, aCommandRefCon
);
456 nsPasteCommand::GetCommandStateParams(const char *aCommandName
,
457 nsICommandParams
*aParams
,
458 nsISupports
*aCommandRefCon
)
461 IsCommandEnabled(aCommandName
, aCommandRefCon
, &canUndo
);
462 return aParams
->SetBooleanValue(STATE_ENABLED
, canUndo
);
466 nsPasteTransferableCommand::IsCommandEnabled(const char *aCommandName
,
467 nsISupports
*aCommandRefCon
,
470 NS_ENSURE_ARG_POINTER(outCmdEnabled
);
471 nsCOMPtr
<nsIEditor
> editor
= do_QueryInterface(aCommandRefCon
);
473 bool isEditable
= false;
474 nsresult rv
= editor
->GetIsSelectionEditable(&isEditable
);
475 NS_ENSURE_SUCCESS(rv
, rv
);
477 return editor
->CanPasteTransferable(nullptr, outCmdEnabled
);
480 *outCmdEnabled
= false;
485 nsPasteTransferableCommand::DoCommand(const char *aCommandName
,
486 nsISupports
*aCommandRefCon
)
488 return NS_ERROR_FAILURE
;
492 nsPasteTransferableCommand::DoCommandParams(const char *aCommandName
,
493 nsICommandParams
*aParams
,
494 nsISupports
*aCommandRefCon
)
496 nsCOMPtr
<nsIEditor
> editor
= do_QueryInterface(aCommandRefCon
);
497 NS_ENSURE_TRUE(editor
, NS_ERROR_FAILURE
);
499 nsCOMPtr
<nsISupports
> supports
;
500 aParams
->GetISupportsValue("transferable", getter_AddRefs(supports
));
501 NS_ENSURE_TRUE(supports
, NS_ERROR_FAILURE
);
503 nsCOMPtr
<nsITransferable
> trans
= do_QueryInterface(supports
);
504 NS_ENSURE_TRUE(trans
, NS_ERROR_FAILURE
);
506 return editor
->PasteTransferable(trans
);
510 nsPasteTransferableCommand::GetCommandStateParams(const char *aCommandName
,
511 nsICommandParams
*aParams
,
512 nsISupports
*aCommandRefCon
)
514 nsCOMPtr
<nsIEditor
> editor
= do_QueryInterface(aCommandRefCon
);
515 NS_ENSURE_TRUE(editor
, NS_ERROR_FAILURE
);
517 nsCOMPtr
<nsITransferable
> trans
;
519 nsCOMPtr
<nsISupports
> supports
;
520 aParams
->GetISupportsValue("transferable", getter_AddRefs(supports
));
522 trans
= do_QueryInterface(supports
);
523 NS_ENSURE_TRUE(trans
, NS_ERROR_FAILURE
);
527 nsresult rv
= editor
->CanPasteTransferable(trans
, &canPaste
);
528 NS_ENSURE_SUCCESS(rv
, rv
);
530 return aParams
->SetBooleanValue(STATE_ENABLED
, canPaste
);
534 nsSwitchTextDirectionCommand::IsCommandEnabled(const char *aCommandName
,
535 nsISupports
*aCommandRefCon
,
538 NS_ENSURE_ARG_POINTER(outCmdEnabled
);
539 nsCOMPtr
<nsIEditor
> editor
= do_QueryInterface(aCommandRefCon
);
541 return editor
->GetIsSelectionEditable(outCmdEnabled
);
543 *outCmdEnabled
= false;
548 nsSwitchTextDirectionCommand::DoCommand(const char *aCommandName
,
549 nsISupports
*aCommandRefCon
)
551 nsCOMPtr
<nsIEditor
> editor
= do_QueryInterface(aCommandRefCon
);
552 NS_ENSURE_TRUE(editor
, NS_ERROR_FAILURE
);
554 return editor
->SwitchTextDirection();
558 nsSwitchTextDirectionCommand::DoCommandParams(const char *aCommandName
,
559 nsICommandParams
*aParams
,
560 nsISupports
*aCommandRefCon
)
562 return DoCommand(aCommandName
, aCommandRefCon
);
566 nsSwitchTextDirectionCommand::GetCommandStateParams(const char *aCommandName
,
567 nsICommandParams
*aParams
,
568 nsISupports
*aCommandRefCon
)
570 bool canSwitchTextDirection
= true;
571 IsCommandEnabled(aCommandName
, aCommandRefCon
, &canSwitchTextDirection
);
572 return aParams
->SetBooleanValue(STATE_ENABLED
, canSwitchTextDirection
);
576 nsDeleteCommand::IsCommandEnabled(const char *aCommandName
,
577 nsISupports
*aCommandRefCon
,
580 NS_ENSURE_ARG_POINTER(outCmdEnabled
);
581 nsCOMPtr
<nsIEditor
> editor
= do_QueryInterface(aCommandRefCon
);
582 *outCmdEnabled
= false;
584 NS_ENSURE_TRUE(editor
, NS_OK
);
586 // We can generally delete whenever the selection is editable. However,
587 // cmd_delete doesn't make sense if the selection is collapsed because it's
588 // directionless, which is the same condition under which we can't cut.
589 nsresult rv
= editor
->GetIsSelectionEditable(outCmdEnabled
);
590 NS_ENSURE_SUCCESS(rv
, rv
);
592 if (!nsCRT::strcmp("cmd_delete", aCommandName
) && *outCmdEnabled
) {
593 rv
= editor
->CanDelete(outCmdEnabled
);
594 NS_ENSURE_SUCCESS(rv
, rv
);
601 nsDeleteCommand::DoCommand(const char *aCommandName
,
602 nsISupports
*aCommandRefCon
)
604 nsCOMPtr
<nsIEditor
> editor
= do_QueryInterface(aCommandRefCon
);
605 NS_ENSURE_TRUE(editor
, NS_ERROR_FAILURE
);
607 nsIEditor::EDirection deleteDir
= nsIEditor::eNone
;
609 if (!nsCRT::strcmp("cmd_delete", aCommandName
)) {
610 // Really this should probably be eNone, but it only makes a difference if
611 // the selection is collapsed, and then this command is disabled. So let's
612 // keep it as it always was to avoid breaking things.
613 deleteDir
= nsIEditor::ePrevious
;
614 } else if (!nsCRT::strcmp("cmd_deleteCharForward", aCommandName
)) {
615 deleteDir
= nsIEditor::eNext
;
616 } else if (!nsCRT::strcmp("cmd_deleteCharBackward", aCommandName
)) {
617 deleteDir
= nsIEditor::ePrevious
;
618 } else if (!nsCRT::strcmp("cmd_deleteWordBackward", aCommandName
)) {
619 deleteDir
= nsIEditor::ePreviousWord
;
620 } else if (!nsCRT::strcmp("cmd_deleteWordForward", aCommandName
)) {
621 deleteDir
= nsIEditor::eNextWord
;
622 } else if (!nsCRT::strcmp("cmd_deleteToBeginningOfLine", aCommandName
)) {
623 deleteDir
= nsIEditor::eToBeginningOfLine
;
624 } else if (!nsCRT::strcmp("cmd_deleteToEndOfLine", aCommandName
)) {
625 deleteDir
= nsIEditor::eToEndOfLine
;
627 MOZ_CRASH("Unrecognized nsDeleteCommand");
630 return editor
->DeleteSelection(deleteDir
, nsIEditor::eStrip
);
634 nsDeleteCommand::DoCommandParams(const char *aCommandName
,
635 nsICommandParams
*aParams
,
636 nsISupports
*aCommandRefCon
)
638 return DoCommand(aCommandName
, aCommandRefCon
);
642 nsDeleteCommand::GetCommandStateParams(const char *aCommandName
,
643 nsICommandParams
*aParams
,
644 nsISupports
*aCommandRefCon
)
647 IsCommandEnabled(aCommandName
, aCommandRefCon
, &canUndo
);
648 return aParams
->SetBooleanValue(STATE_ENABLED
, canUndo
);
652 nsSelectAllCommand::IsCommandEnabled(const char *aCommandName
,
653 nsISupports
*aCommandRefCon
,
656 NS_ENSURE_ARG_POINTER(outCmdEnabled
);
659 // You can always select all, unless the selection is editable,
660 // and the editable region is empty!
661 *outCmdEnabled
= true;
664 // you can select all if there is an editor which is non-empty
665 nsCOMPtr
<nsIEditor
> editor
= do_QueryInterface(aCommandRefCon
);
667 rv
= editor
->GetDocumentIsEmpty(&docIsEmpty
);
668 NS_ENSURE_SUCCESS(rv
, rv
);
669 *outCmdEnabled
= !docIsEmpty
;
676 nsSelectAllCommand::DoCommand(const char *aCommandName
,
677 nsISupports
*aCommandRefCon
)
679 nsCOMPtr
<nsIEditor
> editor
= do_QueryInterface(aCommandRefCon
);
681 return editor
->SelectAll();
683 return NS_ERROR_FAILURE
;
687 nsSelectAllCommand::DoCommandParams(const char *aCommandName
,
688 nsICommandParams
*aParams
,
689 nsISupports
*aCommandRefCon
)
691 return DoCommand(aCommandName
, aCommandRefCon
);
695 nsSelectAllCommand::GetCommandStateParams(const char *aCommandName
,
696 nsICommandParams
*aParams
,
697 nsISupports
*aCommandRefCon
)
700 IsCommandEnabled(aCommandName
, aCommandRefCon
, &canUndo
);
701 return aParams
->SetBooleanValue(STATE_ENABLED
, canUndo
);
705 nsSelectionMoveCommands::IsCommandEnabled(const char *aCommandName
,
706 nsISupports
*aCommandRefCon
,
709 NS_ENSURE_ARG_POINTER(outCmdEnabled
);
710 nsCOMPtr
<nsIEditor
> editor
= do_QueryInterface(aCommandRefCon
);
712 return editor
->GetIsSelectionEditable(outCmdEnabled
);
714 *outCmdEnabled
= false;
718 static const struct ScrollCommand
{
719 const char *reverseScroll
;
720 const char *forwardScroll
;
721 nsresult (NS_STDCALL
nsISelectionController::*scroll
)(bool);
722 } scrollCommands
[] = {
723 { "cmd_scrollTop", "cmd_scrollBottom",
724 &nsISelectionController::CompleteScroll
},
725 { "cmd_scrollPageUp", "cmd_scrollPageDown",
726 &nsISelectionController::ScrollPage
},
727 { "cmd_scrollLineUp", "cmd_scrollLineDown",
728 &nsISelectionController::ScrollLine
}
731 static const struct MoveCommand
{
732 const char *reverseMove
;
733 const char *forwardMove
;
734 const char *reverseSelect
;
735 const char *forwardSelect
;
736 nsresult (NS_STDCALL
nsISelectionController::*move
)(bool, bool);
738 { "cmd_charPrevious", "cmd_charNext",
739 "cmd_selectCharPrevious", "cmd_selectCharNext",
740 &nsISelectionController::CharacterMove
},
741 { "cmd_linePrevious", "cmd_lineNext",
742 "cmd_selectLinePrevious", "cmd_selectLineNext",
743 &nsISelectionController::LineMove
},
744 { "cmd_wordPrevious", "cmd_wordNext",
745 "cmd_selectWordPrevious", "cmd_selectWordNext",
746 &nsISelectionController::WordMove
},
747 { "cmd_beginLine", "cmd_endLine",
748 "cmd_selectBeginLine", "cmd_selectEndLine",
749 &nsISelectionController::IntraLineMove
},
750 { "cmd_movePageUp", "cmd_movePageDown",
751 "cmd_selectPageUp", "cmd_selectPageDown",
752 &nsISelectionController::PageMove
},
753 { "cmd_moveTop", "cmd_moveBottom",
754 "cmd_selectTop", "cmd_selectBottom",
755 &nsISelectionController::CompleteMove
}
758 static const struct PhysicalCommand
{
763 } physicalCommands
[] = {
764 { "cmd_moveLeft", "cmd_selectLeft",
765 nsISelectionController::MOVE_LEFT
, 0 },
766 { "cmd_moveRight", "cmd_selectRight",
767 nsISelectionController::MOVE_RIGHT
, 0 },
768 { "cmd_moveUp", "cmd_selectUp",
769 nsISelectionController::MOVE_UP
, 0 },
770 { "cmd_moveDown", "cmd_selectDown",
771 nsISelectionController::MOVE_DOWN
, 0 },
772 { "cmd_moveLeft2", "cmd_selectLeft2",
773 nsISelectionController::MOVE_LEFT
, 1 },
774 { "cmd_moveRight2", "cmd_selectRight2",
775 nsISelectionController::MOVE_RIGHT
, 1 },
776 { "cmd_moveUp2", "cmd_selectUp2",
777 nsISelectionController::MOVE_UP
, 1 },
778 { "cmd_moveDown2", "cmd_selectDown2",
779 nsISelectionController::MOVE_DOWN
, 1 }
783 nsSelectionMoveCommands::DoCommand(const char *aCommandName
,
784 nsISupports
*aCommandRefCon
)
786 nsCOMPtr
<nsIEditor
> editor
= do_QueryInterface(aCommandRefCon
);
787 NS_ENSURE_TRUE(editor
, NS_ERROR_FAILURE
);
789 nsCOMPtr
<nsIDOMDocument
> domDoc
;
790 editor
->GetDocument(getter_AddRefs(domDoc
));
791 nsCOMPtr
<nsIDocument
> doc
= do_QueryInterface(domDoc
);
793 // Most of the commands below (possibly all of them) need layout to
795 doc
->FlushPendingNotifications(Flush_Layout
);
798 nsCOMPtr
<nsISelectionController
> selCont
;
799 nsresult rv
= editor
->GetSelectionController(getter_AddRefs(selCont
));
800 NS_ENSURE_SUCCESS(rv
, rv
);
801 NS_ENSURE_TRUE(selCont
, NS_ERROR_FAILURE
);
804 for (size_t i
= 0; i
< mozilla::ArrayLength(scrollCommands
); i
++) {
805 const ScrollCommand
&cmd
= scrollCommands
[i
];
806 if (!nsCRT::strcmp(aCommandName
, cmd
.reverseScroll
)) {
807 return (selCont
->*(cmd
.scroll
))(false);
808 } else if (!nsCRT::strcmp(aCommandName
, cmd
.forwardScroll
)) {
809 return (selCont
->*(cmd
.scroll
))(true);
813 // caret movement/selection commands
814 for (size_t i
= 0; i
< mozilla::ArrayLength(moveCommands
); i
++) {
815 const MoveCommand
&cmd
= moveCommands
[i
];
816 if (!nsCRT::strcmp(aCommandName
, cmd
.reverseMove
)) {
817 return (selCont
->*(cmd
.move
))(false, false);
818 } else if (!nsCRT::strcmp(aCommandName
, cmd
.forwardMove
)) {
819 return (selCont
->*(cmd
.move
))(true, false);
820 } else if (!nsCRT::strcmp(aCommandName
, cmd
.reverseSelect
)) {
821 return (selCont
->*(cmd
.move
))(false, true);
822 } else if (!nsCRT::strcmp(aCommandName
, cmd
.forwardSelect
)) {
823 return (selCont
->*(cmd
.move
))(true, true);
827 // physical-direction movement/selection
828 for (size_t i
= 0; i
< mozilla::ArrayLength(physicalCommands
); i
++) {
829 const PhysicalCommand
&cmd
= physicalCommands
[i
];
830 if (!nsCRT::strcmp(aCommandName
, cmd
.move
)) {
831 return selCont
->PhysicalMove(cmd
.direction
, cmd
.amount
, false);
832 } else if (!nsCRT::strcmp(aCommandName
, cmd
.select
)) {
833 return selCont
->PhysicalMove(cmd
.direction
, cmd
.amount
, true);
837 return NS_ERROR_FAILURE
;
841 nsSelectionMoveCommands::DoCommandParams(const char *aCommandName
,
842 nsICommandParams
*aParams
,
843 nsISupports
*aCommandRefCon
)
845 return DoCommand(aCommandName
, aCommandRefCon
);
849 nsSelectionMoveCommands::GetCommandStateParams(const char *aCommandName
,
850 nsICommandParams
*aParams
,
851 nsISupports
*aCommandRefCon
)
854 IsCommandEnabled(aCommandName
, aCommandRefCon
, &canUndo
);
855 return aParams
->SetBooleanValue(STATE_ENABLED
, canUndo
);
859 nsInsertPlaintextCommand::IsCommandEnabled(const char *aCommandName
,
863 NS_ENSURE_ARG_POINTER(outCmdEnabled
);
864 nsCOMPtr
<nsIEditor
> editor
= do_QueryInterface(refCon
);
866 return editor
->GetIsSelectionEditable(outCmdEnabled
);
868 *outCmdEnabled
= false;
869 return NS_ERROR_NOT_IMPLEMENTED
;
873 nsInsertPlaintextCommand::DoCommand(const char *aCommandName
,
876 return NS_ERROR_NOT_IMPLEMENTED
;
880 nsInsertPlaintextCommand::DoCommandParams(const char *aCommandName
,
881 nsICommandParams
*aParams
,
884 NS_ENSURE_ARG_POINTER(aParams
);
886 nsCOMPtr
<nsIPlaintextEditor
> editor
= do_QueryInterface(refCon
);
887 NS_ENSURE_TRUE(editor
, NS_ERROR_NOT_IMPLEMENTED
);
889 // Get text to insert from command params
891 nsresult rv
= aParams
->GetStringValue(STATE_DATA
, text
);
892 NS_ENSURE_SUCCESS(rv
, rv
);
895 return editor
->InsertText(text
);
901 nsInsertPlaintextCommand::GetCommandStateParams(const char *aCommandName
,
902 nsICommandParams
*aParams
,
905 NS_ENSURE_ARG_POINTER(aParams
);
907 bool outCmdEnabled
= false;
908 IsCommandEnabled(aCommandName
, refCon
, &outCmdEnabled
);
909 return aParams
->SetBooleanValue(STATE_ENABLED
, outCmdEnabled
);
913 nsPasteQuotationCommand::IsCommandEnabled(const char *aCommandName
,
917 NS_ENSURE_ARG_POINTER(outCmdEnabled
);
919 nsCOMPtr
<nsIEditor
> editor
= do_QueryInterface(refCon
);
920 nsCOMPtr
<nsIEditorMailSupport
> mailEditor
= do_QueryInterface(refCon
);
921 if (editor
&& mailEditor
) {
923 editor
->GetFlags(&flags
);
924 if (!(flags
& nsIPlaintextEditor::eEditorSingleLineMask
))
925 return editor
->CanPaste(nsIClipboard::kGlobalClipboard
, outCmdEnabled
);
928 *outCmdEnabled
= false;
933 nsPasteQuotationCommand::DoCommand(const char *aCommandName
,
936 nsCOMPtr
<nsIEditorMailSupport
> mailEditor
= do_QueryInterface(refCon
);
938 return mailEditor
->PasteAsQuotation(nsIClipboard::kGlobalClipboard
);
940 return NS_ERROR_NOT_IMPLEMENTED
;
944 nsPasteQuotationCommand::DoCommandParams(const char *aCommandName
,
945 nsICommandParams
*aParams
,
948 nsCOMPtr
<nsIEditorMailSupport
> mailEditor
= do_QueryInterface(refCon
);
950 return mailEditor
->PasteAsQuotation(nsIClipboard::kGlobalClipboard
);
952 return NS_ERROR_NOT_IMPLEMENTED
;
956 nsPasteQuotationCommand::GetCommandStateParams(const char *aCommandName
,
957 nsICommandParams
*aParams
,
960 nsCOMPtr
<nsIEditor
> editor
= do_QueryInterface(refCon
);
962 bool enabled
= false;
963 editor
->CanPaste(nsIClipboard::kGlobalClipboard
, &enabled
);
964 aParams
->SetBooleanValue(STATE_ENABLED
, enabled
);