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/. */
5
6 #include "EditorCommands.h"
7
8 #include "mozilla/ArrayUtils.h"
9 #include "mozilla/Assertions.h"
10 #include "mozilla/FlushType.h"
11 #include "mozilla/TextEditor.h"
12 #include "mozilla/dom/Selection.h"
13 #include "nsCOMPtr.h"
14 #include "nsCRT.h"
15 #include "nsDebug.h"
16 #include "nsError.h"
17 #include "nsIClipboard.h"
18 #include "nsICommandParams.h"
19 #include "nsID.h"
20 #include "nsIDOMDocument.h"
21 #include "nsIDocument.h"
22 #include "nsIEditor.h"
23 #include "nsIEditorMailSupport.h"
24 #include "nsIPlaintextEditor.h"
25 #include "nsISelectionController.h"
26 #include "nsITransferable.h"
27 #include "nsString.h"
28 #include "nsAString.h"
29
30 class nsISupports;
31
32 #define STATE_ENABLED "state_enabled"
33 #define STATE_DATA "state_data"
34
35 namespace mozilla {
36
37 /******************************************************************************
38 * mozilla::EditorCommandBase
39 ******************************************************************************/
40
EditorCommandBase()41 EditorCommandBase::EditorCommandBase() {}
42
NS_IMPL_ISUPPORTS(EditorCommandBase,nsIControllerCommand)43 NS_IMPL_ISUPPORTS(EditorCommandBase, nsIControllerCommand)
44
45 /******************************************************************************
46 * mozilla::UndoCommand
47 ******************************************************************************/
48
49 NS_IMETHODIMP
50 UndoCommand::IsCommandEnabled(const char* aCommandName,
51 nsISupports* aCommandRefCon, bool* aIsEnabled) {
52 if (NS_WARN_IF(!aIsEnabled)) {
53 return NS_ERROR_INVALID_ARG;
54 }
55
56 *aIsEnabled = false;
57
58 nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
59 if (!editor) {
60 return NS_OK;
61 }
62 TextEditor* textEditor = editor->AsTextEditor();
63 MOZ_ASSERT(textEditor);
64 if (!textEditor->IsSelectionEditable()) {
65 return NS_OK;
66 }
67 bool isEnabled = false;
68 return editor->CanUndo(&isEnabled, aIsEnabled);
69 }
70
71 NS_IMETHODIMP
DoCommand(const char * aCommandName,nsISupports * aCommandRefCon)72 UndoCommand::DoCommand(const char* aCommandName, nsISupports* aCommandRefCon) {
73 nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
74 if (!editor) {
75 return NS_ERROR_FAILURE;
76 }
77 TextEditor* textEditor = editor->AsTextEditor();
78 MOZ_ASSERT(textEditor);
79 return textEditor->Undo(1);
80 }
81
82 NS_IMETHODIMP
DoCommandParams(const char * aCommandName,nsICommandParams * aParams,nsISupports * aCommandRefCon)83 UndoCommand::DoCommandParams(const char* aCommandName,
84 nsICommandParams* aParams,
85 nsISupports* aCommandRefCon) {
86 return DoCommand(aCommandName, aCommandRefCon);
87 }
88
89 NS_IMETHODIMP
GetCommandStateParams(const char * aCommandName,nsICommandParams * aParams,nsISupports * aCommandRefCon)90 UndoCommand::GetCommandStateParams(const char* aCommandName,
91 nsICommandParams* aParams,
92 nsISupports* aCommandRefCon) {
93 bool canUndo;
94 IsCommandEnabled(aCommandName, aCommandRefCon, &canUndo);
95 return aParams->SetBooleanValue(STATE_ENABLED, canUndo);
96 }
97
98 /******************************************************************************
99 * mozilla::RedoCommand
100 ******************************************************************************/
101
102 NS_IMETHODIMP
IsCommandEnabled(const char * aCommandName,nsISupports * aCommandRefCon,bool * aIsEnabled)103 RedoCommand::IsCommandEnabled(const char* aCommandName,
104 nsISupports* aCommandRefCon, bool* aIsEnabled) {
105 if (NS_WARN_IF(!aIsEnabled)) {
106 return NS_ERROR_INVALID_ARG;
107 }
108
109 *aIsEnabled = false;
110
111 nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
112 if (!editor) {
113 return NS_OK;
114 }
115 TextEditor* textEditor = editor->AsTextEditor();
116 MOZ_ASSERT(textEditor);
117 if (!textEditor->IsSelectionEditable()) {
118 return NS_OK;
119 }
120 bool isEnabled = false;
121 return editor->CanRedo(&isEnabled, aIsEnabled);
122 }
123
124 NS_IMETHODIMP
DoCommand(const char * aCommandName,nsISupports * aCommandRefCon)125 RedoCommand::DoCommand(const char* aCommandName, nsISupports* aCommandRefCon) {
126 nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
127 if (!editor) {
128 return NS_ERROR_FAILURE;
129 }
130 TextEditor* textEditor = editor->AsTextEditor();
131 MOZ_ASSERT(textEditor);
132 return textEditor->Redo(1);
133 }
134
135 NS_IMETHODIMP
DoCommandParams(const char * aCommandName,nsICommandParams * aParams,nsISupports * aCommandRefCon)136 RedoCommand::DoCommandParams(const char* aCommandName,
137 nsICommandParams* aParams,
138 nsISupports* aCommandRefCon) {
139 return DoCommand(aCommandName, aCommandRefCon);
140 }
141
142 NS_IMETHODIMP
GetCommandStateParams(const char * aCommandName,nsICommandParams * aParams,nsISupports * aCommandRefCon)143 RedoCommand::GetCommandStateParams(const char* aCommandName,
144 nsICommandParams* aParams,
145 nsISupports* aCommandRefCon) {
146 bool canUndo;
147 IsCommandEnabled(aCommandName, aCommandRefCon, &canUndo);
148 return aParams->SetBooleanValue(STATE_ENABLED, canUndo);
149 }
150
151 /******************************************************************************
152 * mozilla::ClearUndoCommand
153 ******************************************************************************/
154
155 NS_IMETHODIMP
IsCommandEnabled(const char * aCommandName,nsISupports * aCommandRefCon,bool * aIsEnabled)156 ClearUndoCommand::IsCommandEnabled(const char* aCommandName,
157 nsISupports* aCommandRefCon,
158 bool* aIsEnabled) {
159 if (NS_WARN_IF(!aIsEnabled)) {
160 return NS_ERROR_INVALID_ARG;
161 }
162 nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
163 if (!editor) {
164 *aIsEnabled = false;
165 return NS_OK;
166 }
167 TextEditor* textEditor = editor->AsTextEditor();
168 MOZ_ASSERT(textEditor);
169 *aIsEnabled = textEditor->IsSelectionEditable();
170 return NS_OK;
171 }
172
173 NS_IMETHODIMP
DoCommand(const char * aCommandName,nsISupports * aCommandRefCon)174 ClearUndoCommand::DoCommand(const char* aCommandName,
175 nsISupports* aCommandRefCon) {
176 nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
177 if (!editor) {
178 return NS_ERROR_FAILURE;
179 }
180 TextEditor* textEditor = editor->AsTextEditor();
181 MOZ_ASSERT(textEditor);
182 textEditor->EnableUndo(false); // Turning off undo clears undo/redo stacks.
183 textEditor->EnableUndo(true); // This re-enables undo/redo.
184 return NS_OK;
185 }
186
187 NS_IMETHODIMP
DoCommandParams(const char * aCommandName,nsICommandParams * aParams,nsISupports * aCommandRefCon)188 ClearUndoCommand::DoCommandParams(const char* aCommandName,
189 nsICommandParams* aParams,
190 nsISupports* aCommandRefCon) {
191 return DoCommand(aCommandName, aCommandRefCon);
192 }
193
194 NS_IMETHODIMP
GetCommandStateParams(const char * aCommandName,nsICommandParams * aParams,nsISupports * aCommandRefCon)195 ClearUndoCommand::GetCommandStateParams(const char* aCommandName,
196 nsICommandParams* aParams,
197 nsISupports* aCommandRefCon) {
198 NS_ENSURE_ARG_POINTER(aParams);
199
200 bool enabled;
201 nsresult rv = IsCommandEnabled(aCommandName, aCommandRefCon, &enabled);
202 NS_ENSURE_SUCCESS(rv, rv);
203
204 return aParams->SetBooleanValue(STATE_ENABLED, enabled);
205 }
206
207 /******************************************************************************
208 * mozilla::CutCommand
209 ******************************************************************************/
210
211 NS_IMETHODIMP
IsCommandEnabled(const char * aCommandName,nsISupports * aCommandRefCon,bool * aIsEnabled)212 CutCommand::IsCommandEnabled(const char* aCommandName,
213 nsISupports* aCommandRefCon, bool* aIsEnabled) {
214 if (NS_WARN_IF(!aIsEnabled)) {
215 return NS_ERROR_INVALID_ARG;
216 }
217
218 *aIsEnabled = false;
219
220 nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
221 if (!editor) {
222 return NS_OK;
223 }
224 TextEditor* textEditor = editor->AsTextEditor();
225 MOZ_ASSERT(textEditor);
226 if (!textEditor->IsSelectionEditable()) {
227 return NS_OK;
228 }
229 return editor->CanCut(aIsEnabled);
230 }
231
232 NS_IMETHODIMP
DoCommand(const char * aCommandName,nsISupports * aCommandRefCon)233 CutCommand::DoCommand(const char* aCommandName, nsISupports* aCommandRefCon) {
234 nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
235 if (!editor) {
236 return NS_ERROR_FAILURE;
237 }
238 TextEditor* textEditor = editor->AsTextEditor();
239 MOZ_ASSERT(textEditor);
240 return textEditor->Cut();
241 }
242
243 NS_IMETHODIMP
DoCommandParams(const char * aCommandName,nsICommandParams * aParams,nsISupports * aCommandRefCon)244 CutCommand::DoCommandParams(const char* aCommandName, nsICommandParams* aParams,
245 nsISupports* aCommandRefCon) {
246 return DoCommand(aCommandName, aCommandRefCon);
247 }
248
249 NS_IMETHODIMP
GetCommandStateParams(const char * aCommandName,nsICommandParams * aParams,nsISupports * aCommandRefCon)250 CutCommand::GetCommandStateParams(const char* aCommandName,
251 nsICommandParams* aParams,
252 nsISupports* aCommandRefCon) {
253 bool canUndo;
254 IsCommandEnabled(aCommandName, aCommandRefCon, &canUndo);
255 return aParams->SetBooleanValue(STATE_ENABLED, canUndo);
256 }
257
258 /******************************************************************************
259 * mozilla::CutOrDeleteCommand
260 ******************************************************************************/
261
262 NS_IMETHODIMP
IsCommandEnabled(const char * aCommandName,nsISupports * aCommandRefCon,bool * aIsEnabled)263 CutOrDeleteCommand::IsCommandEnabled(const char* aCommandName,
264 nsISupports* aCommandRefCon,
265 bool* aIsEnabled) {
266 if (NS_WARN_IF(!aIsEnabled)) {
267 return NS_ERROR_INVALID_ARG;
268 }
269 nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
270 if (!editor) {
271 *aIsEnabled = false;
272 return NS_OK;
273 }
274 TextEditor* textEditor = editor->AsTextEditor();
275 MOZ_ASSERT(textEditor);
276 *aIsEnabled = textEditor->IsSelectionEditable();
277 return NS_OK;
278 }
279
280 NS_IMETHODIMP
DoCommand(const char * aCommandName,nsISupports * aCommandRefCon)281 CutOrDeleteCommand::DoCommand(const char* aCommandName,
282 nsISupports* aCommandRefCon) {
283 nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
284 if (!editor) {
285 return NS_ERROR_FAILURE;
286 }
287 TextEditor* textEditor = editor->AsTextEditor();
288 MOZ_ASSERT(textEditor);
289 dom::Selection* selection = textEditor->GetSelection();
290 if (selection && selection->Collapsed()) {
291 return textEditor->DeleteSelection(nsIEditor::eNext, nsIEditor::eStrip);
292 }
293 return textEditor->Cut();
294 }
295
296 NS_IMETHODIMP
DoCommandParams(const char * aCommandName,nsICommandParams * aParams,nsISupports * aCommandRefCon)297 CutOrDeleteCommand::DoCommandParams(const char* aCommandName,
298 nsICommandParams* aParams,
299 nsISupports* aCommandRefCon) {
300 return DoCommand(aCommandName, aCommandRefCon);
301 }
302
303 NS_IMETHODIMP
GetCommandStateParams(const char * aCommandName,nsICommandParams * aParams,nsISupports * aCommandRefCon)304 CutOrDeleteCommand::GetCommandStateParams(const char* aCommandName,
305 nsICommandParams* aParams,
306 nsISupports* aCommandRefCon) {
307 bool canUndo;
308 IsCommandEnabled(aCommandName, aCommandRefCon, &canUndo);
309 return aParams->SetBooleanValue(STATE_ENABLED, canUndo);
310 }
311
312 /******************************************************************************
313 * mozilla::CopyCommand
314 ******************************************************************************/
315
316 NS_IMETHODIMP
IsCommandEnabled(const char * aCommandName,nsISupports * aCommandRefCon,bool * aIsEnabled)317 CopyCommand::IsCommandEnabled(const char* aCommandName,
318 nsISupports* aCommandRefCon, bool* aIsEnabled) {
319 if (NS_WARN_IF(!aIsEnabled)) {
320 return NS_ERROR_INVALID_ARG;
321 }
322 nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
323 if (!editor) {
324 *aIsEnabled = false;
325 return NS_OK;
326 }
327 TextEditor* textEditor = editor->AsTextEditor();
328 MOZ_ASSERT(textEditor);
329 return textEditor->CanCopy(aIsEnabled);
330 }
331
332 NS_IMETHODIMP
DoCommand(const char * aCommandName,nsISupports * aCommandRefCon)333 CopyCommand::DoCommand(const char* aCommandName, nsISupports* aCommandRefCon) {
334 nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
335 if (!editor) {
336 return NS_ERROR_FAILURE;
337 }
338 TextEditor* textEditor = editor->AsTextEditor();
339 MOZ_ASSERT(textEditor);
340 return textEditor->Copy();
341 }
342
343 NS_IMETHODIMP
DoCommandParams(const char * aCommandName,nsICommandParams * aParams,nsISupports * aCommandRefCon)344 CopyCommand::DoCommandParams(const char* aCommandName,
345 nsICommandParams* aParams,
346 nsISupports* aCommandRefCon) {
347 return DoCommand(aCommandName, aCommandRefCon);
348 }
349
350 NS_IMETHODIMP
GetCommandStateParams(const char * aCommandName,nsICommandParams * aParams,nsISupports * aCommandRefCon)351 CopyCommand::GetCommandStateParams(const char* aCommandName,
352 nsICommandParams* aParams,
353 nsISupports* aCommandRefCon) {
354 bool canUndo;
355 IsCommandEnabled(aCommandName, aCommandRefCon, &canUndo);
356 return aParams->SetBooleanValue(STATE_ENABLED, canUndo);
357 }
358
359 /******************************************************************************
360 * mozilla::CopyOrDeleteCommand
361 ******************************************************************************/
362
363 NS_IMETHODIMP
IsCommandEnabled(const char * aCommandName,nsISupports * aCommandRefCon,bool * aIsEnabled)364 CopyOrDeleteCommand::IsCommandEnabled(const char* aCommandName,
365 nsISupports* aCommandRefCon,
366 bool* aIsEnabled) {
367 if (NS_WARN_IF(!aIsEnabled)) {
368 return NS_ERROR_INVALID_ARG;
369 }
370
371 nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
372 if (!editor) {
373 *aIsEnabled = false;
374 return NS_OK;
375 }
376 TextEditor* textEditor = editor->AsTextEditor();
377 MOZ_ASSERT(textEditor);
378 *aIsEnabled = textEditor->IsSelectionEditable();
379 return NS_OK;
380 }
381
382 NS_IMETHODIMP
DoCommand(const char * aCommandName,nsISupports * aCommandRefCon)383 CopyOrDeleteCommand::DoCommand(const char* aCommandName,
384 nsISupports* aCommandRefCon) {
385 nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
386 if (!editor) {
387 return NS_ERROR_FAILURE;
388 }
389 TextEditor* textEditor = editor->AsTextEditor();
390 MOZ_ASSERT(textEditor);
391 dom::Selection* selection = textEditor->GetSelection();
392 if (selection && selection->Collapsed()) {
393 return textEditor->DeleteSelection(nsIEditor::eNextWord, nsIEditor::eStrip);
394 }
395 return textEditor->Copy();
396 }
397
398 NS_IMETHODIMP
DoCommandParams(const char * aCommandName,nsICommandParams * aParams,nsISupports * aCommandRefCon)399 CopyOrDeleteCommand::DoCommandParams(const char* aCommandName,
400 nsICommandParams* aParams,
401 nsISupports* aCommandRefCon) {
402 return DoCommand(aCommandName, aCommandRefCon);
403 }
404
405 NS_IMETHODIMP
GetCommandStateParams(const char * aCommandName,nsICommandParams * aParams,nsISupports * aCommandRefCon)406 CopyOrDeleteCommand::GetCommandStateParams(const char* aCommandName,
407 nsICommandParams* aParams,
408 nsISupports* aCommandRefCon) {
409 bool canUndo;
410 IsCommandEnabled(aCommandName, aCommandRefCon, &canUndo);
411 return aParams->SetBooleanValue(STATE_ENABLED, canUndo);
412 }
413
414 /******************************************************************************
415 * mozilla::CopyAndCollapseToEndCommand
416 ******************************************************************************/
417
418 NS_IMETHODIMP
IsCommandEnabled(const char * aCommandName,nsISupports * aCommandRefCon,bool * aIsEnabled)419 CopyAndCollapseToEndCommand::IsCommandEnabled(const char* aCommandName,
420 nsISupports* aCommandRefCon,
421 bool* aIsEnabled) {
422 if (NS_WARN_IF(!aIsEnabled)) {
423 return NS_ERROR_INVALID_ARG;
424 }
425 nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
426 if (!editor) {
427 *aIsEnabled = false;
428 return NS_OK;
429 }
430 TextEditor* textEditor = editor->AsTextEditor();
431 MOZ_ASSERT(textEditor);
432 return textEditor->CanCopy(aIsEnabled);
433 }
434
435 NS_IMETHODIMP
DoCommand(const char * aCommandName,nsISupports * aCommandRefCon)436 CopyAndCollapseToEndCommand::DoCommand(const char* aCommandName,
437 nsISupports* aCommandRefCon) {
438 nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
439 if (!editor) {
440 return NS_ERROR_FAILURE;
441 }
442 TextEditor* textEditor = editor->AsTextEditor();
443 MOZ_ASSERT(textEditor);
444 nsresult rv = textEditor->Copy();
445 if (NS_FAILED(rv)) {
446 return rv;
447 }
448 RefPtr<dom::Selection> selection = textEditor->GetSelection();
449 if (selection) {
450 selection->CollapseToEnd();
451 }
452 return NS_OK;
453 }
454
455 NS_IMETHODIMP
DoCommandParams(const char * aCommandName,nsICommandParams * aParams,nsISupports * aCommandRefCon)456 CopyAndCollapseToEndCommand::DoCommandParams(const char* aCommandName,
457 nsICommandParams* aParams,
458 nsISupports* aCommandRefCon) {
459 return DoCommand(aCommandName, aCommandRefCon);
460 }
461
462 NS_IMETHODIMP
GetCommandStateParams(const char * aCommandName,nsICommandParams * aParams,nsISupports * aCommandRefCon)463 CopyAndCollapseToEndCommand::GetCommandStateParams(
464 const char* aCommandName, nsICommandParams* aParams,
465 nsISupports* aCommandRefCon) {
466 bool canUndo;
467 IsCommandEnabled(aCommandName, aCommandRefCon, &canUndo);
468 return aParams->SetBooleanValue(STATE_ENABLED, canUndo);
469 }
470
471 /******************************************************************************
472 * mozilla::PasteCommand
473 ******************************************************************************/
474
475 NS_IMETHODIMP
IsCommandEnabled(const char * aCommandName,nsISupports * aCommandRefCon,bool * aIsEnabled)476 PasteCommand::IsCommandEnabled(const char* aCommandName,
477 nsISupports* aCommandRefCon, bool* aIsEnabled) {
478 if (NS_WARN_IF(!aIsEnabled)) {
479 return NS_ERROR_INVALID_ARG;
480 }
481
482 *aIsEnabled = false;
483
484 nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
485 if (!editor) {
486 return NS_OK;
487 }
488 TextEditor* textEditor = editor->AsTextEditor();
489 MOZ_ASSERT(textEditor);
490 if (!textEditor->IsSelectionEditable()) {
491 return NS_OK;
492 }
493 return textEditor->CanPaste(nsIClipboard::kGlobalClipboard, aIsEnabled);
494 }
495
496 NS_IMETHODIMP
DoCommand(const char * aCommandName,nsISupports * aCommandRefCon)497 PasteCommand::DoCommand(const char* aCommandName, nsISupports* aCommandRefCon) {
498 nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
499 if (NS_WARN_IF(!editor)) {
500 return NS_ERROR_FAILURE;
501 }
502 TextEditor* textEditor = editor->AsTextEditor();
503 MOZ_ASSERT(textEditor);
504 return textEditor->Paste(nsIClipboard::kGlobalClipboard);
505 }
506
507 NS_IMETHODIMP
DoCommandParams(const char * aCommandName,nsICommandParams * aParams,nsISupports * aCommandRefCon)508 PasteCommand::DoCommandParams(const char* aCommandName,
509 nsICommandParams* aParams,
510 nsISupports* aCommandRefCon) {
511 return DoCommand(aCommandName, aCommandRefCon);
512 }
513
514 NS_IMETHODIMP
GetCommandStateParams(const char * aCommandName,nsICommandParams * aParams,nsISupports * aCommandRefCon)515 PasteCommand::GetCommandStateParams(const char* aCommandName,
516 nsICommandParams* aParams,
517 nsISupports* aCommandRefCon) {
518 bool canUndo;
519 IsCommandEnabled(aCommandName, aCommandRefCon, &canUndo);
520 return aParams->SetBooleanValue(STATE_ENABLED, canUndo);
521 }
522
523 /******************************************************************************
524 * mozilla::PasteTransferableCommand
525 ******************************************************************************/
526
527 NS_IMETHODIMP
IsCommandEnabled(const char * aCommandName,nsISupports * aCommandRefCon,bool * aIsEnabled)528 PasteTransferableCommand::IsCommandEnabled(const char* aCommandName,
529 nsISupports* aCommandRefCon,
530 bool* aIsEnabled) {
531 if (NS_WARN_IF(!aIsEnabled)) {
532 return NS_ERROR_INVALID_ARG;
533 }
534
535 *aIsEnabled = false;
536
537 nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
538 if (!editor) {
539 return NS_OK;
540 }
541 TextEditor* textEditor = editor->AsTextEditor();
542 MOZ_ASSERT(textEditor);
543 if (!textEditor->IsSelectionEditable()) {
544 return NS_OK;
545 }
546 return textEditor->CanPasteTransferable(nullptr, aIsEnabled);
547 }
548
549 NS_IMETHODIMP
DoCommand(const char * aCommandName,nsISupports * aCommandRefCon)550 PasteTransferableCommand::DoCommand(const char* aCommandName,
551 nsISupports* aCommandRefCon) {
552 return NS_ERROR_FAILURE;
553 }
554
555 NS_IMETHODIMP
DoCommandParams(const char * aCommandName,nsICommandParams * aParams,nsISupports * aCommandRefCon)556 PasteTransferableCommand::DoCommandParams(const char* aCommandName,
557 nsICommandParams* aParams,
558 nsISupports* aCommandRefCon) {
559 nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
560 if (NS_WARN_IF(!editor)) {
561 return NS_ERROR_FAILURE;
562 }
563
564 nsCOMPtr<nsISupports> supports;
565 aParams->GetISupportsValue("transferable", getter_AddRefs(supports));
566 if (NS_WARN_IF(!supports)) {
567 return NS_ERROR_FAILURE;
568 }
569
570 nsCOMPtr<nsITransferable> trans = do_QueryInterface(supports);
571 if (NS_WARN_IF(!trans)) {
572 return NS_ERROR_FAILURE;
573 }
574
575 TextEditor* textEditor = editor->AsTextEditor();
576 MOZ_ASSERT(textEditor);
577 return textEditor->PasteTransferable(trans);
578 }
579
580 NS_IMETHODIMP
GetCommandStateParams(const char * aCommandName,nsICommandParams * aParams,nsISupports * aCommandRefCon)581 PasteTransferableCommand::GetCommandStateParams(const char* aCommandName,
582 nsICommandParams* aParams,
583 nsISupports* aCommandRefCon) {
584 nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
585 if (NS_WARN_IF(!editor)) {
586 return NS_ERROR_FAILURE;
587 }
588
589 nsCOMPtr<nsISupports> supports;
590 aParams->GetISupportsValue("transferable", getter_AddRefs(supports));
591 if (NS_WARN_IF(!supports)) {
592 return NS_ERROR_FAILURE;
593 }
594
595 nsCOMPtr<nsITransferable> trans;
596 trans = do_QueryInterface(supports);
597 if (NS_WARN_IF(!trans)) {
598 return NS_ERROR_FAILURE;
599 }
600
601 TextEditor* textEditor = editor->AsTextEditor();
602 MOZ_ASSERT(textEditor);
603
604 bool canPaste;
605 nsresult rv = textEditor->CanPasteTransferable(trans, &canPaste);
606 if (NS_WARN_IF(NS_FAILED(rv))) {
607 return rv;
608 }
609
610 return aParams->SetBooleanValue(STATE_ENABLED, canPaste);
611 }
612
613 /******************************************************************************
614 * mozilla::SwitchTextDirectionCommand
615 ******************************************************************************/
616
617 NS_IMETHODIMP
IsCommandEnabled(const char * aCommandName,nsISupports * aCommandRefCon,bool * aIsEnabled)618 SwitchTextDirectionCommand::IsCommandEnabled(const char* aCommandName,
619 nsISupports* aCommandRefCon,
620 bool* aIsEnabled) {
621 if (NS_WARN_IF(!aIsEnabled)) {
622 return NS_ERROR_INVALID_ARG;
623 }
624 nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
625 if (!editor) {
626 *aIsEnabled = false;
627 return NS_OK;
628 }
629 TextEditor* textEditor = editor->AsTextEditor();
630 MOZ_ASSERT(textEditor);
631 *aIsEnabled = textEditor->IsSelectionEditable();
632 return NS_OK;
633 }
634
635 NS_IMETHODIMP
DoCommand(const char * aCommandName,nsISupports * aCommandRefCon)636 SwitchTextDirectionCommand::DoCommand(const char* aCommandName,
637 nsISupports* aCommandRefCon) {
638 nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
639 if (NS_WARN_IF(!editor)) {
640 return NS_ERROR_FAILURE;
641 }
642 TextEditor* textEditor = editor->AsTextEditor();
643 MOZ_ASSERT(textEditor);
644 return textEditor->SwitchTextDirection();
645 }
646
647 NS_IMETHODIMP
DoCommandParams(const char * aCommandName,nsICommandParams * aParams,nsISupports * aCommandRefCon)648 SwitchTextDirectionCommand::DoCommandParams(const char* aCommandName,
649 nsICommandParams* aParams,
650 nsISupports* aCommandRefCon) {
651 return DoCommand(aCommandName, aCommandRefCon);
652 }
653
654 NS_IMETHODIMP
GetCommandStateParams(const char * aCommandName,nsICommandParams * aParams,nsISupports * aCommandRefCon)655 SwitchTextDirectionCommand::GetCommandStateParams(const char* aCommandName,
656 nsICommandParams* aParams,
657 nsISupports* aCommandRefCon) {
658 bool canSwitchTextDirection = true;
659 IsCommandEnabled(aCommandName, aCommandRefCon, &canSwitchTextDirection);
660 return aParams->SetBooleanValue(STATE_ENABLED, canSwitchTextDirection);
661 }
662
663 /******************************************************************************
664 * mozilla::DeleteCommand
665 ******************************************************************************/
666
667 NS_IMETHODIMP
IsCommandEnabled(const char * aCommandName,nsISupports * aCommandRefCon,bool * aIsEnabled)668 DeleteCommand::IsCommandEnabled(const char* aCommandName,
669 nsISupports* aCommandRefCon, bool* aIsEnabled) {
670 if (NS_WARN_IF(!aIsEnabled)) {
671 return NS_ERROR_INVALID_ARG;
672 }
673
674 *aIsEnabled = false;
675
676 nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
677 if (!editor) {
678 return NS_OK;
679 }
680
681 TextEditor* textEditor = editor->AsTextEditor();
682 MOZ_ASSERT(textEditor);
683
684 // We can generally delete whenever the selection is editable. However,
685 // cmd_delete doesn't make sense if the selection is collapsed because it's
686 // directionless, which is the same condition under which we can't cut.
687 *aIsEnabled = textEditor->IsSelectionEditable();
688
689 if (!nsCRT::strcmp("cmd_delete", aCommandName) && *aIsEnabled) {
690 nsresult rv = textEditor->CanDelete(aIsEnabled);
691 if (NS_WARN_IF(NS_FAILED(rv))) {
692 return rv;
693 }
694 }
695 return NS_OK;
696 }
697
698 NS_IMETHODIMP
DoCommand(const char * aCommandName,nsISupports * aCommandRefCon)699 DeleteCommand::DoCommand(const char* aCommandName,
700 nsISupports* aCommandRefCon) {
701 nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
702 if (NS_WARN_IF(!editor)) {
703 return NS_ERROR_FAILURE;
704 }
705
706 nsIEditor::EDirection deleteDir = nsIEditor::eNone;
707
708 if (!nsCRT::strcmp("cmd_delete", aCommandName)) {
709 // Really this should probably be eNone, but it only makes a difference if
710 // the selection is collapsed, and then this command is disabled. So let's
711 // keep it as it always was to avoid breaking things.
712 deleteDir = nsIEditor::ePrevious;
713 } else if (!nsCRT::strcmp("cmd_deleteCharForward", aCommandName)) {
714 deleteDir = nsIEditor::eNext;
715 } else if (!nsCRT::strcmp("cmd_deleteCharBackward", aCommandName)) {
716 deleteDir = nsIEditor::ePrevious;
717 } else if (!nsCRT::strcmp("cmd_deleteWordBackward", aCommandName)) {
718 deleteDir = nsIEditor::ePreviousWord;
719 } else if (!nsCRT::strcmp("cmd_deleteWordForward", aCommandName)) {
720 deleteDir = nsIEditor::eNextWord;
721 } else if (!nsCRT::strcmp("cmd_deleteToBeginningOfLine", aCommandName)) {
722 deleteDir = nsIEditor::eToBeginningOfLine;
723 } else if (!nsCRT::strcmp("cmd_deleteToEndOfLine", aCommandName)) {
724 deleteDir = nsIEditor::eToEndOfLine;
725 } else {
726 MOZ_CRASH("Unrecognized nsDeleteCommand");
727 }
728
729 TextEditor* textEditor = editor->AsTextEditor();
730 MOZ_ASSERT(textEditor);
731 return textEditor->DeleteSelection(deleteDir, nsIEditor::eStrip);
732 }
733
734 NS_IMETHODIMP
DoCommandParams(const char * aCommandName,nsICommandParams * aParams,nsISupports * aCommandRefCon)735 DeleteCommand::DoCommandParams(const char* aCommandName,
736 nsICommandParams* aParams,
737 nsISupports* aCommandRefCon) {
738 return DoCommand(aCommandName, aCommandRefCon);
739 }
740
741 NS_IMETHODIMP
GetCommandStateParams(const char * aCommandName,nsICommandParams * aParams,nsISupports * aCommandRefCon)742 DeleteCommand::GetCommandStateParams(const char* aCommandName,
743 nsICommandParams* aParams,
744 nsISupports* aCommandRefCon) {
745 bool canUndo;
746 IsCommandEnabled(aCommandName, aCommandRefCon, &canUndo);
747 return aParams->SetBooleanValue(STATE_ENABLED, canUndo);
748 }
749
750 /******************************************************************************
751 * mozilla::SelectAllCommand
752 ******************************************************************************/
753
754 NS_IMETHODIMP
IsCommandEnabled(const char * aCommandName,nsISupports * aCommandRefCon,bool * aIsEnabled)755 SelectAllCommand::IsCommandEnabled(const char* aCommandName,
756 nsISupports* aCommandRefCon,
757 bool* aIsEnabled) {
758 NS_ENSURE_ARG_POINTER(aIsEnabled);
759
760 nsresult rv = NS_OK;
761 // You can always select all, unless the selection is editable,
762 // and the editable region is empty!
763 *aIsEnabled = true;
764 bool docIsEmpty;
765
766 nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
767 if (!editor) {
768 return NS_OK;
769 }
770
771 // You can select all if there is an editor which is non-empty
772 TextEditor* textEditor = editor->AsTextEditor();
773 MOZ_ASSERT(textEditor);
774 rv = textEditor->GetDocumentIsEmpty(&docIsEmpty);
775 if (NS_WARN_IF(NS_FAILED(rv))) {
776 return rv;
777 }
778 *aIsEnabled = !docIsEmpty;
779 return NS_OK;
780 }
781
782 NS_IMETHODIMP
DoCommand(const char * aCommandName,nsISupports * aCommandRefCon)783 SelectAllCommand::DoCommand(const char* aCommandName,
784 nsISupports* aCommandRefCon) {
785 nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
786 if (!editor) {
787 return NS_ERROR_FAILURE;
788 }
789 TextEditor* textEditor = editor->AsTextEditor();
790 MOZ_ASSERT(textEditor);
791 return textEditor->SelectAll();
792 }
793
794 NS_IMETHODIMP
DoCommandParams(const char * aCommandName,nsICommandParams * aParams,nsISupports * aCommandRefCon)795 SelectAllCommand::DoCommandParams(const char* aCommandName,
796 nsICommandParams* aParams,
797 nsISupports* aCommandRefCon) {
798 return DoCommand(aCommandName, aCommandRefCon);
799 }
800
801 NS_IMETHODIMP
GetCommandStateParams(const char * aCommandName,nsICommandParams * aParams,nsISupports * aCommandRefCon)802 SelectAllCommand::GetCommandStateParams(const char* aCommandName,
803 nsICommandParams* aParams,
804 nsISupports* aCommandRefCon) {
805 bool canUndo;
806 IsCommandEnabled(aCommandName, aCommandRefCon, &canUndo);
807 return aParams->SetBooleanValue(STATE_ENABLED, canUndo);
808 }
809
810 /******************************************************************************
811 * mozilla::SelectionMoveCommands
812 ******************************************************************************/
813
814 NS_IMETHODIMP
IsCommandEnabled(const char * aCommandName,nsISupports * aCommandRefCon,bool * aIsEnabled)815 SelectionMoveCommands::IsCommandEnabled(const char* aCommandName,
816 nsISupports* aCommandRefCon,
817 bool* aIsEnabled) {
818 NS_ENSURE_ARG_POINTER(aIsEnabled);
819 nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
820 if (!editor) {
821 *aIsEnabled = false;
822 return NS_OK;
823 }
824 TextEditor* textEditor = editor->AsTextEditor();
825 MOZ_ASSERT(textEditor);
826 *aIsEnabled = textEditor->IsSelectionEditable();
827 return NS_OK;
828 }
829
830 static const struct ScrollCommand {
831 const char* reverseScroll;
832 const char* forwardScroll;
833 nsresult (NS_STDCALL nsISelectionController::*scroll)(bool);
834 } scrollCommands[] = {{"cmd_scrollTop", "cmd_scrollBottom",
835 &nsISelectionController::CompleteScroll},
836 {"cmd_scrollPageUp", "cmd_scrollPageDown",
837 &nsISelectionController::ScrollPage},
838 {"cmd_scrollLineUp", "cmd_scrollLineDown",
839 &nsISelectionController::ScrollLine}};
840
841 static const struct MoveCommand {
842 const char* reverseMove;
843 const char* forwardMove;
844 const char* reverseSelect;
845 const char* forwardSelect;
846 nsresult (NS_STDCALL nsISelectionController::*move)(bool, bool);
847 } moveCommands[] = {
848 {"cmd_charPrevious", "cmd_charNext", "cmd_selectCharPrevious",
849 "cmd_selectCharNext", &nsISelectionController::CharacterMove},
850 {"cmd_linePrevious", "cmd_lineNext", "cmd_selectLinePrevious",
851 "cmd_selectLineNext", &nsISelectionController::LineMove},
852 {"cmd_wordPrevious", "cmd_wordNext", "cmd_selectWordPrevious",
853 "cmd_selectWordNext", &nsISelectionController::WordMove},
854 {"cmd_beginLine", "cmd_endLine", "cmd_selectBeginLine", "cmd_selectEndLine",
855 &nsISelectionController::IntraLineMove},
856 {"cmd_movePageUp", "cmd_movePageDown", "cmd_selectPageUp",
857 "cmd_selectPageDown", &nsISelectionController::PageMove},
858 {"cmd_moveTop", "cmd_moveBottom", "cmd_selectTop", "cmd_selectBottom",
859 &nsISelectionController::CompleteMove}};
860
861 static const struct PhysicalCommand {
862 const char* move;
863 const char* select;
864 int16_t direction;
865 int16_t amount;
866 } physicalCommands[] = {
867 {"cmd_moveLeft", "cmd_selectLeft", nsISelectionController::MOVE_LEFT, 0},
868 {"cmd_moveRight", "cmd_selectRight", nsISelectionController::MOVE_RIGHT, 0},
869 {"cmd_moveUp", "cmd_selectUp", nsISelectionController::MOVE_UP, 0},
870 {"cmd_moveDown", "cmd_selectDown", nsISelectionController::MOVE_DOWN, 0},
871 {"cmd_moveLeft2", "cmd_selectLeft2", nsISelectionController::MOVE_LEFT, 1},
872 {"cmd_moveRight2", "cmd_selectRight2", nsISelectionController::MOVE_RIGHT,
873 1},
874 {"cmd_moveUp2", "cmd_selectUp2", nsISelectionController::MOVE_UP, 1},
875 {"cmd_moveDown2", "cmd_selectDown2", nsISelectionController::MOVE_DOWN, 1}};
876
877 NS_IMETHODIMP
DoCommand(const char * aCommandName,nsISupports * aCommandRefCon)878 SelectionMoveCommands::DoCommand(const char* aCommandName,
879 nsISupports* aCommandRefCon) {
880 nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
881 if (NS_WARN_IF(!editor)) {
882 return NS_ERROR_FAILURE;
883 }
884
885 TextEditor* textEditor = editor->AsTextEditor();
886 MOZ_ASSERT(textEditor);
887 nsCOMPtr<nsIDocument> doc = textEditor->GetDocument();
888 if (doc) {
889 // Most of the commands below (possibly all of them) need layout to
890 // be up to date.
891 doc->FlushPendingNotifications(FlushType::Layout);
892 }
893
894 nsCOMPtr<nsISelectionController> selectionController =
895 textEditor->GetSelectionController();
896 if (NS_WARN_IF(!selectionController)) {
897 return NS_ERROR_FAILURE;
898 }
899
900 // scroll commands
901 for (size_t i = 0; i < mozilla::ArrayLength(scrollCommands); i++) {
902 const ScrollCommand& cmd = scrollCommands[i];
903 if (!nsCRT::strcmp(aCommandName, cmd.reverseScroll)) {
904 return (selectionController->*(cmd.scroll))(false);
905 } else if (!nsCRT::strcmp(aCommandName, cmd.forwardScroll)) {
906 return (selectionController->*(cmd.scroll))(true);
907 }
908 }
909
910 // caret movement/selection commands
911 for (size_t i = 0; i < mozilla::ArrayLength(moveCommands); i++) {
912 const MoveCommand& cmd = moveCommands[i];
913 if (!nsCRT::strcmp(aCommandName, cmd.reverseMove)) {
914 return (selectionController->*(cmd.move))(false, false);
915 } else if (!nsCRT::strcmp(aCommandName, cmd.forwardMove)) {
916 return (selectionController->*(cmd.move))(true, false);
917 } else if (!nsCRT::strcmp(aCommandName, cmd.reverseSelect)) {
918 return (selectionController->*(cmd.move))(false, true);
919 } else if (!nsCRT::strcmp(aCommandName, cmd.forwardSelect)) {
920 return (selectionController->*(cmd.move))(true, true);
921 }
922 }
923
924 // physical-direction movement/selection
925 for (size_t i = 0; i < mozilla::ArrayLength(physicalCommands); i++) {
926 const PhysicalCommand& cmd = physicalCommands[i];
927 if (!nsCRT::strcmp(aCommandName, cmd.move)) {
928 return selectionController->PhysicalMove(cmd.direction, cmd.amount,
929 false);
930 } else if (!nsCRT::strcmp(aCommandName, cmd.select)) {
931 return selectionController->PhysicalMove(cmd.direction, cmd.amount, true);
932 }
933 }
934
935 return NS_ERROR_FAILURE;
936 }
937
938 NS_IMETHODIMP
DoCommandParams(const char * aCommandName,nsICommandParams * aParams,nsISupports * aCommandRefCon)939 SelectionMoveCommands::DoCommandParams(const char* aCommandName,
940 nsICommandParams* aParams,
941 nsISupports* aCommandRefCon) {
942 return DoCommand(aCommandName, aCommandRefCon);
943 }
944
945 NS_IMETHODIMP
GetCommandStateParams(const char * aCommandName,nsICommandParams * aParams,nsISupports * aCommandRefCon)946 SelectionMoveCommands::GetCommandStateParams(const char* aCommandName,
947 nsICommandParams* aParams,
948 nsISupports* aCommandRefCon) {
949 bool canUndo;
950 IsCommandEnabled(aCommandName, aCommandRefCon, &canUndo);
951 return aParams->SetBooleanValue(STATE_ENABLED, canUndo);
952 }
953
954 /******************************************************************************
955 * mozilla::InsertPlaintextCommand
956 ******************************************************************************/
957
958 NS_IMETHODIMP
IsCommandEnabled(const char * aCommandName,nsISupports * aCommandRefCon,bool * aIsEnabled)959 InsertPlaintextCommand::IsCommandEnabled(const char* aCommandName,
960 nsISupports* aCommandRefCon,
961 bool* aIsEnabled) {
962 if (NS_WARN_IF(!aIsEnabled)) {
963 return NS_ERROR_INVALID_ARG;
964 }
965 nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
966 if (NS_WARN_IF(!editor)) {
967 *aIsEnabled = false;
968 return NS_ERROR_FAILURE;
969 }
970 TextEditor* textEditor = editor->AsTextEditor();
971 MOZ_ASSERT(textEditor);
972 *aIsEnabled = textEditor->IsSelectionEditable();
973 return NS_OK;
974 }
975
976 NS_IMETHODIMP
DoCommand(const char * aCommandName,nsISupports * aCommandRefCon)977 InsertPlaintextCommand::DoCommand(const char* aCommandName,
978 nsISupports* aCommandRefCon) {
979 // No value is equivalent to empty string
980 nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
981 if (NS_WARN_IF(!editor)) {
982 return NS_ERROR_FAILURE;
983 }
984 TextEditor* textEditor = editor->AsTextEditor();
985 MOZ_ASSERT(textEditor);
986 return textEditor->InsertText(EmptyString());
987 }
988
989 NS_IMETHODIMP
DoCommandParams(const char * aCommandName,nsICommandParams * aParams,nsISupports * aCommandRefCon)990 InsertPlaintextCommand::DoCommandParams(const char* aCommandName,
991 nsICommandParams* aParams,
992 nsISupports* aCommandRefCon) {
993 if (NS_WARN_IF(!aParams)) {
994 return NS_ERROR_INVALID_ARG;
995 }
996
997 nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
998 if (NS_WARN_IF(!editor)) {
999 return NS_ERROR_FAILURE;
1000 }
1001
1002 // Get text to insert from command params
1003 nsAutoString text;
1004 nsresult rv = aParams->GetStringValue(STATE_DATA, text);
1005 if (NS_WARN_IF(NS_FAILED(rv))) {
1006 return rv;
1007 }
1008
1009 TextEditor* textEditor = editor->AsTextEditor();
1010 MOZ_ASSERT(textEditor);
1011 return textEditor->InsertText(text);
1012 }
1013
1014 NS_IMETHODIMP
GetCommandStateParams(const char * aCommandName,nsICommandParams * aParams,nsISupports * aCommandRefCon)1015 InsertPlaintextCommand::GetCommandStateParams(const char* aCommandName,
1016 nsICommandParams* aParams,
1017 nsISupports* aCommandRefCon) {
1018 if (NS_WARN_IF(!aParams)) {
1019 return NS_ERROR_INVALID_ARG;
1020 }
1021
1022 bool aIsEnabled = false;
1023 IsCommandEnabled(aCommandName, aCommandRefCon, &aIsEnabled);
1024 return aParams->SetBooleanValue(STATE_ENABLED, aIsEnabled);
1025 }
1026
1027 /******************************************************************************
1028 * mozilla::InsertParagraphCommand
1029 ******************************************************************************/
1030
1031 NS_IMETHODIMP
IsCommandEnabled(const char * aCommandName,nsISupports * aCommandRefCon,bool * aIsEnabled)1032 InsertParagraphCommand::IsCommandEnabled(const char* aCommandName,
1033 nsISupports* aCommandRefCon,
1034 bool* aIsEnabled) {
1035 if (NS_WARN_IF(!aIsEnabled)) {
1036 return NS_ERROR_INVALID_ARG;
1037 }
1038 nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
1039 if (NS_WARN_IF(!editor)) {
1040 *aIsEnabled = false;
1041 return NS_ERROR_FAILURE;
1042 }
1043
1044 TextEditor* textEditor = editor->AsTextEditor();
1045 MOZ_ASSERT(textEditor);
1046 *aIsEnabled = textEditor->IsSelectionEditable();
1047 return NS_OK;
1048 }
1049
1050 NS_IMETHODIMP
DoCommand(const char * aCommandName,nsISupports * aCommandRefCon)1051 InsertParagraphCommand::DoCommand(const char* aCommandName,
1052 nsISupports* aCommandRefCon) {
1053 nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
1054 if (NS_WARN_IF(!editor)) {
1055 return NS_ERROR_FAILURE;
1056 }
1057
1058 TextEditor* textEditor = editor->AsTextEditor();
1059 MOZ_ASSERT(textEditor);
1060 return textEditor->TypedText(EmptyString(), TextEditor::eTypedBreak);
1061 }
1062
1063 NS_IMETHODIMP
DoCommandParams(const char * aCommandName,nsICommandParams * aParams,nsISupports * aCommandRefCon)1064 InsertParagraphCommand::DoCommandParams(const char* aCommandName,
1065 nsICommandParams* aParams,
1066 nsISupports* aCommandRefCon) {
1067 return DoCommand(aCommandName, aCommandRefCon);
1068 }
1069
1070 NS_IMETHODIMP
GetCommandStateParams(const char * aCommandName,nsICommandParams * aParams,nsISupports * aCommandRefCon)1071 InsertParagraphCommand::GetCommandStateParams(const char* aCommandName,
1072 nsICommandParams* aParams,
1073 nsISupports* aCommandRefCon) {
1074 if (NS_WARN_IF(!aParams)) {
1075 return NS_ERROR_INVALID_ARG;
1076 }
1077
1078 bool aIsEnabled = false;
1079 IsCommandEnabled(aCommandName, aCommandRefCon, &aIsEnabled);
1080 return aParams->SetBooleanValue(STATE_ENABLED, aIsEnabled);
1081 }
1082
1083 /******************************************************************************
1084 * mozilla::InsertLineBreakCommand
1085 ******************************************************************************/
1086
1087 NS_IMETHODIMP
IsCommandEnabled(const char * aCommandName,nsISupports * aCommandRefCon,bool * aIsEnabled)1088 InsertLineBreakCommand::IsCommandEnabled(const char* aCommandName,
1089 nsISupports* aCommandRefCon,
1090 bool* aIsEnabled) {
1091 if (NS_WARN_IF(!aIsEnabled)) {
1092 return NS_ERROR_INVALID_ARG;
1093 }
1094 nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
1095 if (NS_WARN_IF(!editor)) {
1096 *aIsEnabled = false;
1097 return NS_ERROR_FAILURE;
1098 }
1099
1100 TextEditor* textEditor = editor->AsTextEditor();
1101 MOZ_ASSERT(textEditor);
1102 *aIsEnabled = textEditor->IsSelectionEditable();
1103 return NS_OK;
1104 }
1105
1106 NS_IMETHODIMP
DoCommand(const char * aCommandName,nsISupports * aCommandRefCon)1107 InsertLineBreakCommand::DoCommand(const char* aCommandName,
1108 nsISupports* aCommandRefCon) {
1109 nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
1110 if (NS_WARN_IF(!editor)) {
1111 return NS_ERROR_FAILURE;
1112 }
1113
1114 TextEditor* textEditor = editor->AsTextEditor();
1115 MOZ_ASSERT(textEditor);
1116 return textEditor->TypedText(EmptyString(), TextEditor::eTypedBR);
1117 }
1118
1119 NS_IMETHODIMP
DoCommandParams(const char * aCommandName,nsICommandParams * aParams,nsISupports * aCommandRefCon)1120 InsertLineBreakCommand::DoCommandParams(const char* aCommandName,
1121 nsICommandParams* aParams,
1122 nsISupports* aCommandRefCon) {
1123 return DoCommand(aCommandName, aCommandRefCon);
1124 }
1125
1126 NS_IMETHODIMP
GetCommandStateParams(const char * aCommandName,nsICommandParams * aParams,nsISupports * aCommandRefCon)1127 InsertLineBreakCommand::GetCommandStateParams(const char* aCommandName,
1128 nsICommandParams* aParams,
1129 nsISupports* aCommandRefCon) {
1130 if (NS_WARN_IF(!aParams)) {
1131 return NS_ERROR_INVALID_ARG;
1132 }
1133
1134 bool aIsEnabled = false;
1135 IsCommandEnabled(aCommandName, aCommandRefCon, &aIsEnabled);
1136 return aParams->SetBooleanValue(STATE_ENABLED, aIsEnabled);
1137 }
1138
1139 /******************************************************************************
1140 * mozilla::PasteQuotationCommand
1141 ******************************************************************************/
1142
1143 NS_IMETHODIMP
IsCommandEnabled(const char * aCommandName,nsISupports * aCommandRefCon,bool * aIsEnabled)1144 PasteQuotationCommand::IsCommandEnabled(const char* aCommandName,
1145 nsISupports* aCommandRefCon,
1146 bool* aIsEnabled) {
1147 if (NS_WARN_IF(!aIsEnabled)) {
1148 return NS_ERROR_INVALID_ARG;
1149 }
1150
1151 *aIsEnabled = false;
1152
1153 nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
1154 if (!editor) {
1155 return NS_OK;
1156 }
1157 TextEditor* textEditor = editor->AsTextEditor();
1158 MOZ_ASSERT(textEditor);
1159 if (textEditor->IsSingleLineEditor()) {
1160 return NS_OK;
1161 }
1162 return textEditor->CanPaste(nsIClipboard::kGlobalClipboard, aIsEnabled);
1163 }
1164
1165 NS_IMETHODIMP
DoCommand(const char * aCommandName,nsISupports * aCommandRefCon)1166 PasteQuotationCommand::DoCommand(const char* aCommandName,
1167 nsISupports* aCommandRefCon) {
1168 nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
1169 if (NS_WARN_IF(!editor)) {
1170 return NS_ERROR_FAILURE;
1171 }
1172 TextEditor* textEditor = editor->AsTextEditor();
1173 MOZ_ASSERT(textEditor);
1174 return textEditor->PasteAsQuotation(nsIClipboard::kGlobalClipboard);
1175 }
1176
1177 NS_IMETHODIMP
DoCommandParams(const char * aCommandName,nsICommandParams * aParams,nsISupports * aCommandRefCon)1178 PasteQuotationCommand::DoCommandParams(const char* aCommandName,
1179 nsICommandParams* aParams,
1180 nsISupports* aCommandRefCon) {
1181 nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
1182 if (!editor) {
1183 return NS_ERROR_FAILURE;
1184 }
1185 TextEditor* textEditor = editor->AsTextEditor();
1186 MOZ_ASSERT(textEditor);
1187 return textEditor->PasteAsQuotation(nsIClipboard::kGlobalClipboard);
1188 }
1189
1190 NS_IMETHODIMP
GetCommandStateParams(const char * aCommandName,nsICommandParams * aParams,nsISupports * aCommandRefCon)1191 PasteQuotationCommand::GetCommandStateParams(const char* aCommandName,
1192 nsICommandParams* aParams,
1193 nsISupports* aCommandRefCon) {
1194 nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
1195 if (!editor) {
1196 return NS_OK;
1197 }
1198 TextEditor* textEditor = editor->AsTextEditor();
1199 MOZ_ASSERT(textEditor);
1200 bool enabled = false;
1201 textEditor->CanPaste(nsIClipboard::kGlobalClipboard, &enabled);
1202 aParams->SetBooleanValue(STATE_ENABLED, enabled);
1203 return NS_OK;
1204 }
1205
1206 } // namespace mozilla
1207