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
7 #include <stdio.h> // for printf
8
9 #include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
10 #include "nsAString.h"
11 #include "nsCOMPtr.h" // for nsCOMPtr, do_QueryInterface, etc
12 #include "nsComponentManagerUtils.h" // for do_CreateInstance
13 #include "nsComposerCommands.h"
14 #include "nsDebug.h" // for NS_ENSURE_TRUE, etc
15 #include "nsError.h" // for NS_OK, NS_ERROR_FAILURE, etc
16 #include "nsGkAtoms.h" // for nsGkAtoms, nsGkAtoms::font, etc
17 #include "nsIAtom.h" // for nsIAtom, etc
18 #include "nsIClipboard.h" // for nsIClipboard, etc
19 #include "nsICommandParams.h" // for nsICommandParams, etc
20 #include "nsID.h"
21 #include "nsIDOMElement.h" // for nsIDOMElement
22 #include "nsIEditor.h" // for nsIEditor
23 #include "nsIHTMLAbsPosEditor.h" // for nsIHTMLAbsPosEditor
24 #include "nsIHTMLEditor.h" // for nsIHTMLEditor, etc
25 #include "nsLiteralString.h" // for NS_LITERAL_STRING
26 #include "nsReadableUtils.h" // for EmptyString
27 #include "nsString.h" // for nsAutoString, nsString, etc
28 #include "nsStringFwd.h" // for nsAFlatString
29
30 class nsISupports;
31
32 //prototype
33 nsresult GetListState(nsIHTMLEditor* aEditor, bool* aMixed,
34 nsAString& aLocalName);
35 nsresult RemoveOneProperty(nsIHTMLEditor* aEditor, const nsAString& aProp);
36 nsresult RemoveTextProperty(nsIHTMLEditor* aEditor, const nsAString& aProp);
37 nsresult SetTextProperty(nsIHTMLEditor *aEditor, const nsAString& aProp);
38
39
40 //defines
41 #define STATE_ENABLED "state_enabled"
42 #define STATE_ALL "state_all"
43 #define STATE_ANY "state_any"
44 #define STATE_MIXED "state_mixed"
45 #define STATE_BEGIN "state_begin"
46 #define STATE_END "state_end"
47 #define STATE_ATTRIBUTE "state_attribute"
48 #define STATE_DATA "state_data"
49
50
nsBaseComposerCommand()51 nsBaseComposerCommand::nsBaseComposerCommand()
52 {
53 }
54
NS_IMPL_ISUPPORTS(nsBaseComposerCommand,nsIControllerCommand)55 NS_IMPL_ISUPPORTS(nsBaseComposerCommand, nsIControllerCommand)
56
57
58 nsBaseStateUpdatingCommand::nsBaseStateUpdatingCommand(nsIAtom* aTagName)
59 : nsBaseComposerCommand()
60 , mTagName(aTagName)
61 {
62 MOZ_ASSERT(mTagName);
63 }
64
~nsBaseStateUpdatingCommand()65 nsBaseStateUpdatingCommand::~nsBaseStateUpdatingCommand()
66 {
67 }
68
NS_IMPL_ISUPPORTS_INHERITED0(nsBaseStateUpdatingCommand,nsBaseComposerCommand)69 NS_IMPL_ISUPPORTS_INHERITED0(nsBaseStateUpdatingCommand, nsBaseComposerCommand)
70
71 NS_IMETHODIMP
72 nsBaseStateUpdatingCommand::IsCommandEnabled(const char *aCommandName,
73 nsISupports *refCon,
74 bool *outCmdEnabled)
75 {
76 nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon);
77 if (editor)
78 return editor->GetIsSelectionEditable(outCmdEnabled);
79
80 *outCmdEnabled = false;
81 return NS_OK;
82 }
83
84
85 NS_IMETHODIMP
DoCommand(const char * aCommandName,nsISupports * refCon)86 nsBaseStateUpdatingCommand::DoCommand(const char *aCommandName,
87 nsISupports *refCon)
88 {
89 nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon);
90 NS_ENSURE_TRUE(editor, NS_ERROR_NOT_INITIALIZED);
91
92 return ToggleState(editor);
93 }
94
95 NS_IMETHODIMP
DoCommandParams(const char * aCommandName,nsICommandParams * aParams,nsISupports * refCon)96 nsBaseStateUpdatingCommand::DoCommandParams(const char *aCommandName,
97 nsICommandParams *aParams,
98 nsISupports *refCon)
99 {
100 return DoCommand(aCommandName, refCon);
101 }
102
103 NS_IMETHODIMP
GetCommandStateParams(const char * aCommandName,nsICommandParams * aParams,nsISupports * refCon)104 nsBaseStateUpdatingCommand::GetCommandStateParams(const char *aCommandName,
105 nsICommandParams *aParams,
106 nsISupports *refCon)
107 {
108 nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon);
109 if (editor)
110 return GetCurrentState(editor, aParams);
111
112 return NS_OK;
113 }
114
115 NS_IMETHODIMP
IsCommandEnabled(const char * aCommandName,nsISupports * refCon,bool * outCmdEnabled)116 nsPasteNoFormattingCommand::IsCommandEnabled(const char * aCommandName,
117 nsISupports *refCon,
118 bool *outCmdEnabled)
119 {
120 NS_ENSURE_ARG_POINTER(outCmdEnabled);
121 *outCmdEnabled = false;
122
123 // This command is only implemented by nsIHTMLEditor, since
124 // pasting in a plaintext editor automatically only supplies
125 // "unformatted" text
126 nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(refCon);
127 NS_ENSURE_TRUE(htmlEditor, NS_ERROR_NOT_IMPLEMENTED);
128
129 nsCOMPtr<nsIEditor> editor = do_QueryInterface(htmlEditor);
130 NS_ENSURE_TRUE(editor, NS_ERROR_INVALID_ARG);
131
132 return editor->CanPaste(nsIClipboard::kGlobalClipboard, outCmdEnabled);
133 }
134
135
136 NS_IMETHODIMP
DoCommand(const char * aCommandName,nsISupports * refCon)137 nsPasteNoFormattingCommand::DoCommand(const char *aCommandName,
138 nsISupports *refCon)
139 {
140 nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(refCon);
141 NS_ENSURE_TRUE(htmlEditor, NS_ERROR_NOT_IMPLEMENTED);
142
143 return htmlEditor->PasteNoFormatting(nsIClipboard::kGlobalClipboard);
144 }
145
146 NS_IMETHODIMP
DoCommandParams(const char * aCommandName,nsICommandParams * aParams,nsISupports * refCon)147 nsPasteNoFormattingCommand::DoCommandParams(const char *aCommandName,
148 nsICommandParams *aParams,
149 nsISupports *refCon)
150 {
151 return DoCommand(aCommandName, refCon);
152 }
153
154 NS_IMETHODIMP
GetCommandStateParams(const char * aCommandName,nsICommandParams * aParams,nsISupports * refCon)155 nsPasteNoFormattingCommand::GetCommandStateParams(const char *aCommandName,
156 nsICommandParams *aParams,
157 nsISupports *refCon)
158 {
159 NS_ENSURE_ARG_POINTER(aParams);
160
161 bool enabled = false;
162 nsresult rv = IsCommandEnabled(aCommandName, refCon, &enabled);
163 NS_ENSURE_SUCCESS(rv, rv);
164
165 return aParams->SetBooleanValue(STATE_ENABLED, enabled);
166 }
167
nsStyleUpdatingCommand(nsIAtom * aTagName)168 nsStyleUpdatingCommand::nsStyleUpdatingCommand(nsIAtom* aTagName)
169 : nsBaseStateUpdatingCommand(aTagName)
170 {
171 }
172
173 nsresult
GetCurrentState(nsIEditor * aEditor,nsICommandParams * aParams)174 nsStyleUpdatingCommand::GetCurrentState(nsIEditor *aEditor,
175 nsICommandParams *aParams)
176 {
177 NS_ASSERTION(aEditor, "Need editor here");
178 nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(aEditor);
179 NS_ENSURE_TRUE(htmlEditor, NS_ERROR_NOT_INITIALIZED);
180
181 bool firstOfSelectionHasProp = false;
182 bool anyOfSelectionHasProp = false;
183 bool allOfSelectionHasProp = false;
184
185 nsresult rv = htmlEditor->GetInlineProperty(mTagName, EmptyString(),
186 EmptyString(),
187 &firstOfSelectionHasProp,
188 &anyOfSelectionHasProp,
189 &allOfSelectionHasProp);
190
191 aParams->SetBooleanValue(STATE_ENABLED, NS_SUCCEEDED(rv));
192 aParams->SetBooleanValue(STATE_ALL, allOfSelectionHasProp);
193 aParams->SetBooleanValue(STATE_ANY, anyOfSelectionHasProp);
194 aParams->SetBooleanValue(STATE_MIXED, anyOfSelectionHasProp
195 && !allOfSelectionHasProp);
196 aParams->SetBooleanValue(STATE_BEGIN, firstOfSelectionHasProp);
197 aParams->SetBooleanValue(STATE_END, allOfSelectionHasProp);//not completely accurate
198 return NS_OK;
199 }
200
201 nsresult
ToggleState(nsIEditor * aEditor)202 nsStyleUpdatingCommand::ToggleState(nsIEditor *aEditor)
203 {
204 nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(aEditor);
205 NS_ENSURE_TRUE(htmlEditor, NS_ERROR_NO_INTERFACE);
206
207 //create some params now...
208 nsresult rv;
209 nsCOMPtr<nsICommandParams> params =
210 do_CreateInstance(NS_COMMAND_PARAMS_CONTRACTID,&rv);
211 if (NS_FAILED(rv) || !params)
212 return rv;
213
214 // tags "href" and "name" are special cases in the core editor
215 // they are used to remove named anchor/link and shouldn't be used for insertion
216 bool doTagRemoval;
217 if (mTagName == nsGkAtoms::href || mTagName == nsGkAtoms::name) {
218 doTagRemoval = true;
219 } else {
220 // check current selection; set doTagRemoval if formatting should be removed
221 rv = GetCurrentState(aEditor, params);
222 NS_ENSURE_SUCCESS(rv, rv);
223 rv = params->GetBooleanValue(STATE_ALL, &doTagRemoval);
224 NS_ENSURE_SUCCESS(rv, rv);
225 }
226
227 if (doTagRemoval) {
228 // Also remove equivalent properties (bug 317093)
229 if (mTagName == nsGkAtoms::b) {
230 rv = RemoveTextProperty(htmlEditor, NS_LITERAL_STRING("strong"));
231 NS_ENSURE_SUCCESS(rv, rv);
232 } else if (mTagName == nsGkAtoms::i) {
233 rv = RemoveTextProperty(htmlEditor, NS_LITERAL_STRING("em"));
234 NS_ENSURE_SUCCESS(rv, rv);
235 } else if (mTagName == nsGkAtoms::strike) {
236 rv = RemoveTextProperty(htmlEditor, NS_LITERAL_STRING("s"));
237 NS_ENSURE_SUCCESS(rv, rv);
238 }
239
240 rv = RemoveTextProperty(htmlEditor, nsDependentAtomString(mTagName));
241 } else {
242 // Superscript and Subscript styles are mutually exclusive
243 aEditor->BeginTransaction();
244
245 nsDependentAtomString tagName(mTagName);
246 if (mTagName == nsGkAtoms::sub || mTagName == nsGkAtoms::sup) {
247 rv = RemoveTextProperty(htmlEditor, tagName);
248 }
249 if (NS_SUCCEEDED(rv))
250 rv = SetTextProperty(htmlEditor, tagName);
251
252 aEditor->EndTransaction();
253 }
254
255 return rv;
256 }
257
nsListCommand(nsIAtom * aTagName)258 nsListCommand::nsListCommand(nsIAtom* aTagName)
259 : nsBaseStateUpdatingCommand(aTagName)
260 {
261 }
262
263 nsresult
GetCurrentState(nsIEditor * aEditor,nsICommandParams * aParams)264 nsListCommand::GetCurrentState(nsIEditor* aEditor, nsICommandParams* aParams)
265 {
266 NS_ASSERTION(aEditor, "Need editor here");
267 nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(aEditor);
268 NS_ENSURE_TRUE(htmlEditor, NS_ERROR_NO_INTERFACE);
269
270 bool bMixed;
271 nsAutoString localName;
272 nsresult rv = GetListState(htmlEditor, &bMixed, localName);
273 NS_ENSURE_SUCCESS(rv, rv);
274
275 bool inList = mTagName->Equals(localName);
276 aParams->SetBooleanValue(STATE_ALL, !bMixed && inList);
277 aParams->SetBooleanValue(STATE_MIXED, bMixed);
278 aParams->SetBooleanValue(STATE_ENABLED, true);
279 return NS_OK;
280 }
281
282 nsresult
ToggleState(nsIEditor * aEditor)283 nsListCommand::ToggleState(nsIEditor *aEditor)
284 {
285 nsCOMPtr<nsIHTMLEditor> editor = do_QueryInterface(aEditor);
286 NS_ENSURE_TRUE(editor, NS_NOINTERFACE);
287
288 nsresult rv;
289 nsCOMPtr<nsICommandParams> params =
290 do_CreateInstance(NS_COMMAND_PARAMS_CONTRACTID,&rv);
291 if (NS_FAILED(rv) || !params)
292 return rv;
293
294 rv = GetCurrentState(aEditor, params);
295 NS_ENSURE_SUCCESS(rv, rv);
296
297 bool inList;
298 rv = params->GetBooleanValue(STATE_ALL,&inList);
299 NS_ENSURE_SUCCESS(rv, rv);
300
301 nsDependentAtomString listType(mTagName);
302 if (inList) {
303 rv = editor->RemoveList(listType);
304 } else {
305 rv = editor->MakeOrChangeList(listType, false, EmptyString());
306 }
307
308 return rv;
309 }
310
nsListItemCommand(nsIAtom * aTagName)311 nsListItemCommand::nsListItemCommand(nsIAtom* aTagName)
312 : nsBaseStateUpdatingCommand(aTagName)
313 {
314 }
315
316 nsresult
GetCurrentState(nsIEditor * aEditor,nsICommandParams * aParams)317 nsListItemCommand::GetCurrentState(nsIEditor* aEditor,
318 nsICommandParams *aParams)
319 {
320 NS_ASSERTION(aEditor, "Need editor here");
321 // 39584
322 nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(aEditor);
323 NS_ENSURE_TRUE(htmlEditor, NS_NOINTERFACE);
324
325 bool bMixed, bLI, bDT, bDD;
326 nsresult rv = htmlEditor->GetListItemState(&bMixed, &bLI, &bDT, &bDD);
327 NS_ENSURE_SUCCESS(rv, rv);
328
329 bool inList = false;
330 if (!bMixed) {
331 if (bLI) {
332 inList = mTagName == nsGkAtoms::li;
333 } else if (bDT) {
334 inList = mTagName == nsGkAtoms::dt;
335 } else if (bDD) {
336 inList = mTagName == nsGkAtoms::dd;
337 }
338 }
339
340 aParams->SetBooleanValue(STATE_ALL, !bMixed && inList);
341 aParams->SetBooleanValue(STATE_MIXED, bMixed);
342
343 return NS_OK;
344 }
345
346 nsresult
ToggleState(nsIEditor * aEditor)347 nsListItemCommand::ToggleState(nsIEditor *aEditor)
348 {
349 NS_ASSERTION(aEditor, "Need editor here");
350 nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(aEditor);
351 NS_ENSURE_TRUE(htmlEditor, NS_ERROR_NOT_INITIALIZED);
352
353 bool inList;
354 // Need to use mTagName????
355 nsresult rv;
356 nsCOMPtr<nsICommandParams> params =
357 do_CreateInstance(NS_COMMAND_PARAMS_CONTRACTID,&rv);
358 if (NS_FAILED(rv) || !params)
359 return rv;
360 rv = GetCurrentState(aEditor, params);
361 rv = params->GetBooleanValue(STATE_ALL,&inList);
362 NS_ENSURE_SUCCESS(rv, rv);
363 NS_ENSURE_SUCCESS(rv, rv);
364
365 if (inList) {
366 // To remove a list, first get what kind of list we're in
367 bool bMixed;
368 nsAutoString localName;
369 rv = GetListState(htmlEditor, &bMixed, localName);
370 NS_ENSURE_SUCCESS(rv, rv);
371 if (localName.IsEmpty() || bMixed) {
372 return rv;
373 }
374 return htmlEditor->RemoveList(localName);
375 }
376
377 // Set to the requested paragraph type
378 //XXX Note: This actually doesn't work for "LI",
379 // but we currently don't use this for non DL lists anyway.
380 // Problem: won't this replace any current block paragraph style?
381 return htmlEditor->SetParagraphFormat(nsDependentAtomString(mTagName));
382 }
383
384 NS_IMETHODIMP
IsCommandEnabled(const char * aCommandName,nsISupports * refCon,bool * outCmdEnabled)385 nsRemoveListCommand::IsCommandEnabled(const char * aCommandName,
386 nsISupports *refCon,
387 bool *outCmdEnabled)
388 {
389 *outCmdEnabled = false;
390 nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon);
391 NS_ENSURE_TRUE(editor, NS_OK);
392
393 bool isEditable = false;
394 nsresult rv = editor->GetIsSelectionEditable(&isEditable);
395 NS_ENSURE_SUCCESS(rv, rv);
396 if (!isEditable) {
397 return NS_OK;
398 }
399
400 // It is enabled if we are in any list type
401 nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(refCon);
402 NS_ENSURE_TRUE(htmlEditor, NS_ERROR_NO_INTERFACE);
403
404 bool bMixed;
405 nsAutoString localName;
406 rv = GetListState(htmlEditor, &bMixed, localName);
407 NS_ENSURE_SUCCESS(rv, rv);
408
409 *outCmdEnabled = bMixed || !localName.IsEmpty();
410 return NS_OK;
411 }
412
413
414 NS_IMETHODIMP
DoCommand(const char * aCommandName,nsISupports * refCon)415 nsRemoveListCommand::DoCommand(const char *aCommandName, nsISupports *refCon)
416 {
417 nsCOMPtr<nsIHTMLEditor> editor = do_QueryInterface(refCon);
418
419 nsresult rv = NS_OK;
420 if (editor) {
421 // This removes any list type
422 rv = editor->RemoveList(EmptyString());
423 }
424
425 return rv;
426 }
427
428 NS_IMETHODIMP
DoCommandParams(const char * aCommandName,nsICommandParams * aParams,nsISupports * refCon)429 nsRemoveListCommand::DoCommandParams(const char *aCommandName,
430 nsICommandParams *aParams,
431 nsISupports *refCon)
432 {
433 return DoCommand(aCommandName, refCon);
434 }
435
436 NS_IMETHODIMP
GetCommandStateParams(const char * aCommandName,nsICommandParams * aParams,nsISupports * refCon)437 nsRemoveListCommand::GetCommandStateParams(const char *aCommandName,
438 nsICommandParams *aParams,
439 nsISupports *refCon)
440 {
441 bool outCmdEnabled = false;
442 IsCommandEnabled(aCommandName, refCon, &outCmdEnabled);
443 return aParams->SetBooleanValue(STATE_ENABLED,outCmdEnabled);
444 }
445
446 NS_IMETHODIMP
IsCommandEnabled(const char * aCommandName,nsISupports * refCon,bool * outCmdEnabled)447 nsIndentCommand::IsCommandEnabled(const char * aCommandName,
448 nsISupports *refCon, bool *outCmdEnabled)
449 {
450 nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon);
451 if (editor)
452 return editor->GetIsSelectionEditable(outCmdEnabled);
453
454 *outCmdEnabled = false;
455 return NS_OK;
456 }
457
458
459 NS_IMETHODIMP
DoCommand(const char * aCommandName,nsISupports * refCon)460 nsIndentCommand::DoCommand(const char *aCommandName, nsISupports *refCon)
461 {
462 nsCOMPtr<nsIHTMLEditor> editor = do_QueryInterface(refCon);
463
464 nsresult rv = NS_OK;
465 if (editor) {
466 rv = editor->Indent(NS_LITERAL_STRING("indent"));
467 }
468
469 return rv;
470 }
471
472 NS_IMETHODIMP
DoCommandParams(const char * aCommandName,nsICommandParams * aParams,nsISupports * refCon)473 nsIndentCommand::DoCommandParams(const char *aCommandName,
474 nsICommandParams *aParams,
475 nsISupports *refCon)
476 {
477 return DoCommand(aCommandName, refCon);
478 }
479
480 NS_IMETHODIMP
GetCommandStateParams(const char * aCommandName,nsICommandParams * aParams,nsISupports * refCon)481 nsIndentCommand::GetCommandStateParams(const char *aCommandName,
482 nsICommandParams *aParams,
483 nsISupports *refCon)
484 {
485 bool outCmdEnabled = false;
486 IsCommandEnabled(aCommandName, refCon, &outCmdEnabled);
487 return aParams->SetBooleanValue(STATE_ENABLED,outCmdEnabled);
488 }
489
490
491 //OUTDENT
492
493 NS_IMETHODIMP
IsCommandEnabled(const char * aCommandName,nsISupports * refCon,bool * outCmdEnabled)494 nsOutdentCommand::IsCommandEnabled(const char * aCommandName,
495 nsISupports *refCon,
496 bool *outCmdEnabled)
497 {
498 *outCmdEnabled = false;
499
500 nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon);
501 if (editor) {
502 nsresult rv = editor->GetIsSelectionEditable(outCmdEnabled);
503 NS_ENSURE_SUCCESS(rv, rv);
504 }
505
506 return NS_OK;
507 }
508
509
510 NS_IMETHODIMP
DoCommand(const char * aCommandName,nsISupports * refCon)511 nsOutdentCommand::DoCommand(const char *aCommandName, nsISupports *refCon)
512 {
513 nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(refCon);
514 if (htmlEditor)
515 return htmlEditor->Indent(NS_LITERAL_STRING("outdent"));
516
517 return NS_OK;
518 }
519
520 NS_IMETHODIMP
DoCommandParams(const char * aCommandName,nsICommandParams * aParams,nsISupports * refCon)521 nsOutdentCommand::DoCommandParams(const char *aCommandName,
522 nsICommandParams *aParams,
523 nsISupports *refCon)
524 {
525 return DoCommand(aCommandName, refCon);
526 }
527
528 NS_IMETHODIMP
GetCommandStateParams(const char * aCommandName,nsICommandParams * aParams,nsISupports * refCon)529 nsOutdentCommand::GetCommandStateParams(const char *aCommandName,
530 nsICommandParams *aParams,
531 nsISupports *refCon)
532 {
533 bool outCmdEnabled = false;
534 IsCommandEnabled(aCommandName, refCon, &outCmdEnabled);
535 return aParams->SetBooleanValue(STATE_ENABLED,outCmdEnabled);
536 }
537
nsMultiStateCommand()538 nsMultiStateCommand::nsMultiStateCommand()
539 : nsBaseComposerCommand()
540 {
541 }
542
~nsMultiStateCommand()543 nsMultiStateCommand::~nsMultiStateCommand()
544 {
545 }
546
NS_IMPL_ISUPPORTS_INHERITED0(nsMultiStateCommand,nsBaseComposerCommand)547 NS_IMPL_ISUPPORTS_INHERITED0(nsMultiStateCommand, nsBaseComposerCommand)
548
549 NS_IMETHODIMP
550 nsMultiStateCommand::IsCommandEnabled(const char * aCommandName,
551 nsISupports *refCon,
552 bool *outCmdEnabled)
553 {
554 nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon);
555 // should be disabled sometimes, like if the current selection is an image
556 if (editor)
557 return editor->GetIsSelectionEditable(outCmdEnabled);
558
559 *outCmdEnabled = false;
560 return NS_OK;
561 }
562
563
564 NS_IMETHODIMP
DoCommand(const char * aCommandName,nsISupports * refCon)565 nsMultiStateCommand::DoCommand(const char *aCommandName, nsISupports *refCon)
566 {
567 #ifdef DEBUG
568 printf("who is calling nsMultiStateCommand::DoCommand \
569 (no implementation)? %s\n", aCommandName);
570 #endif
571
572 return NS_OK;
573 }
574
575 NS_IMETHODIMP
DoCommandParams(const char * aCommandName,nsICommandParams * aParams,nsISupports * refCon)576 nsMultiStateCommand::DoCommandParams(const char *aCommandName,
577 nsICommandParams *aParams,
578 nsISupports *refCon)
579 {
580 nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon);
581
582 nsresult rv = NS_OK;
583 if (editor) {
584 nsAutoString tString;
585
586 if (aParams) {
587 nsXPIDLCString s;
588 rv = aParams->GetCStringValue(STATE_ATTRIBUTE, getter_Copies(s));
589 if (NS_SUCCEEDED(rv))
590 tString.AssignWithConversion(s);
591 else
592 rv = aParams->GetStringValue(STATE_ATTRIBUTE, tString);
593 }
594
595 rv = SetState(editor, tString);
596 }
597
598 return rv;
599 }
600
601 NS_IMETHODIMP
GetCommandStateParams(const char * aCommandName,nsICommandParams * aParams,nsISupports * refCon)602 nsMultiStateCommand::GetCommandStateParams(const char *aCommandName,
603 nsICommandParams *aParams,
604 nsISupports *refCon)
605 {
606 nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon);
607 nsresult rv = NS_OK;
608 if (editor) {
609 rv = GetCurrentState(editor, aParams);
610 }
611 return rv;
612 }
613
nsParagraphStateCommand()614 nsParagraphStateCommand::nsParagraphStateCommand()
615 : nsMultiStateCommand()
616 {
617 }
618
619 nsresult
GetCurrentState(nsIEditor * aEditor,nsICommandParams * aParams)620 nsParagraphStateCommand::GetCurrentState(nsIEditor *aEditor,
621 nsICommandParams *aParams)
622 {
623 NS_ASSERTION(aEditor, "Need an editor here");
624
625 nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(aEditor);
626 NS_ENSURE_TRUE(htmlEditor, NS_ERROR_FAILURE);
627
628 bool outMixed;
629 nsAutoString outStateString;
630 nsresult rv = htmlEditor->GetParagraphState(&outMixed, outStateString);
631 if (NS_SUCCEEDED(rv)) {
632 nsAutoCString tOutStateString;
633 tOutStateString.AssignWithConversion(outStateString);
634 aParams->SetBooleanValue(STATE_MIXED,outMixed);
635 aParams->SetCStringValue(STATE_ATTRIBUTE, tOutStateString.get());
636 }
637 return rv;
638 }
639
640
641 nsresult
SetState(nsIEditor * aEditor,nsString & newState)642 nsParagraphStateCommand::SetState(nsIEditor *aEditor, nsString& newState)
643 {
644 NS_ASSERTION(aEditor, "Need an editor here");
645 nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(aEditor);
646 NS_ENSURE_TRUE(htmlEditor, NS_ERROR_FAILURE);
647
648 return htmlEditor->SetParagraphFormat(newState);
649 }
650
nsFontFaceStateCommand()651 nsFontFaceStateCommand::nsFontFaceStateCommand()
652 : nsMultiStateCommand()
653 {
654 }
655
656 nsresult
GetCurrentState(nsIEditor * aEditor,nsICommandParams * aParams)657 nsFontFaceStateCommand::GetCurrentState(nsIEditor *aEditor,
658 nsICommandParams *aParams)
659 {
660 NS_ASSERTION(aEditor, "Need an editor here");
661 nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(aEditor);
662 NS_ENSURE_TRUE(htmlEditor, NS_ERROR_FAILURE);
663
664 nsAutoString outStateString;
665 bool outMixed;
666 nsresult rv = htmlEditor->GetFontFaceState(&outMixed, outStateString);
667 if (NS_SUCCEEDED(rv)) {
668 aParams->SetBooleanValue(STATE_MIXED,outMixed);
669 aParams->SetCStringValue(STATE_ATTRIBUTE, NS_ConvertUTF16toUTF8(outStateString).get());
670 }
671 return rv;
672 }
673
674
675 nsresult
SetState(nsIEditor * aEditor,nsString & newState)676 nsFontFaceStateCommand::SetState(nsIEditor *aEditor, nsString& newState)
677 {
678 NS_ASSERTION(aEditor, "Need an editor here");
679 nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(aEditor);
680 NS_ENSURE_TRUE(htmlEditor, NS_ERROR_FAILURE);
681
682 if (newState.EqualsLiteral("tt")) {
683 // The old "teletype" attribute
684 nsresult rv = htmlEditor->SetInlineProperty(nsGkAtoms::tt, EmptyString(),
685 EmptyString());
686 NS_ENSURE_SUCCESS(rv, rv);
687 // Clear existing font face
688 return htmlEditor->RemoveInlineProperty(nsGkAtoms::font,
689 NS_LITERAL_STRING("face"));
690 }
691
692 // Remove any existing TT nodes
693 nsresult rv = htmlEditor->RemoveInlineProperty(nsGkAtoms::tt, EmptyString());
694 NS_ENSURE_SUCCESS(rv, rv);
695
696 if (newState.IsEmpty() || newState.EqualsLiteral("normal")) {
697 return htmlEditor->RemoveInlineProperty(nsGkAtoms::font,
698 NS_LITERAL_STRING("face"));
699 }
700
701 return htmlEditor->SetInlineProperty(nsGkAtoms::font,
702 NS_LITERAL_STRING("face"), newState);
703 }
704
nsFontSizeStateCommand()705 nsFontSizeStateCommand::nsFontSizeStateCommand()
706 : nsMultiStateCommand()
707 {
708 }
709
710 // nsAutoCString tOutStateString;
711 // tOutStateString.AssignWithConversion(outStateString);
712 nsresult
GetCurrentState(nsIEditor * aEditor,nsICommandParams * aParams)713 nsFontSizeStateCommand::GetCurrentState(nsIEditor *aEditor,
714 nsICommandParams *aParams)
715 {
716 NS_ASSERTION(aEditor, "Need an editor here");
717 nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(aEditor);
718 NS_ENSURE_TRUE(htmlEditor, NS_ERROR_INVALID_ARG);
719
720 nsAutoString outStateString;
721 nsCOMPtr<nsIAtom> fontAtom = NS_Atomize("font");
722 bool firstHas, anyHas, allHas;
723 nsresult rv = htmlEditor->GetInlinePropertyWithAttrValue(fontAtom,
724 NS_LITERAL_STRING("size"),
725 EmptyString(),
726 &firstHas, &anyHas, &allHas,
727 outStateString);
728 NS_ENSURE_SUCCESS(rv, rv);
729
730 nsAutoCString tOutStateString;
731 tOutStateString.AssignWithConversion(outStateString);
732 aParams->SetBooleanValue(STATE_MIXED, anyHas && !allHas);
733 aParams->SetCStringValue(STATE_ATTRIBUTE, tOutStateString.get());
734 aParams->SetBooleanValue(STATE_ENABLED, true);
735
736 return rv;
737 }
738
739
740 // acceptable values for "newState" are:
741 // -2
742 // -1
743 // 0
744 // +1
745 // +2
746 // +3
747 // medium
748 // normal
749 nsresult
SetState(nsIEditor * aEditor,nsString & newState)750 nsFontSizeStateCommand::SetState(nsIEditor *aEditor, nsString& newState)
751 {
752 NS_ASSERTION(aEditor, "Need an editor here");
753 nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(aEditor);
754 NS_ENSURE_TRUE(htmlEditor, NS_ERROR_INVALID_ARG);
755
756 if (!newState.IsEmpty() &&
757 !newState.EqualsLiteral("normal") &&
758 !newState.EqualsLiteral("medium")) {
759 return htmlEditor->SetInlineProperty(nsGkAtoms::font,
760 NS_LITERAL_STRING("size"), newState);
761 }
762
763 // remove any existing font size, big or small
764 nsresult rv = htmlEditor->RemoveInlineProperty(nsGkAtoms::font,
765 NS_LITERAL_STRING("size"));
766 NS_ENSURE_SUCCESS(rv, rv);
767
768 rv = htmlEditor->RemoveInlineProperty(nsGkAtoms::big, EmptyString());
769 NS_ENSURE_SUCCESS(rv, rv);
770
771 return htmlEditor->RemoveInlineProperty(nsGkAtoms::small, EmptyString());
772 }
773
nsFontColorStateCommand()774 nsFontColorStateCommand::nsFontColorStateCommand()
775 : nsMultiStateCommand()
776 {
777 }
778
779 nsresult
GetCurrentState(nsIEditor * aEditor,nsICommandParams * aParams)780 nsFontColorStateCommand::GetCurrentState(nsIEditor *aEditor,
781 nsICommandParams *aParams)
782 {
783 NS_ASSERTION(aEditor, "Need an editor here");
784
785 nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(aEditor);
786 NS_ENSURE_TRUE(htmlEditor, NS_ERROR_FAILURE);
787
788 bool outMixed;
789 nsAutoString outStateString;
790 nsresult rv = htmlEditor->GetFontColorState(&outMixed, outStateString);
791 NS_ENSURE_SUCCESS(rv, rv);
792
793 nsAutoCString tOutStateString;
794 tOutStateString.AssignWithConversion(outStateString);
795 aParams->SetBooleanValue(STATE_MIXED, outMixed);
796 aParams->SetCStringValue(STATE_ATTRIBUTE, tOutStateString.get());
797 return NS_OK;
798 }
799
800 nsresult
SetState(nsIEditor * aEditor,nsString & newState)801 nsFontColorStateCommand::SetState(nsIEditor *aEditor, nsString& newState)
802 {
803 NS_ASSERTION(aEditor, "Need an editor here");
804 nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(aEditor);
805 NS_ENSURE_TRUE(htmlEditor, NS_ERROR_FAILURE);
806
807 if (newState.IsEmpty() || newState.EqualsLiteral("normal")) {
808 return htmlEditor->RemoveInlineProperty(nsGkAtoms::font,
809 NS_LITERAL_STRING("color"));
810 }
811
812 return htmlEditor->SetInlineProperty(nsGkAtoms::font,
813 NS_LITERAL_STRING("color"), newState);
814 }
815
nsHighlightColorStateCommand()816 nsHighlightColorStateCommand::nsHighlightColorStateCommand()
817 : nsMultiStateCommand()
818 {
819 }
820
821 nsresult
GetCurrentState(nsIEditor * aEditor,nsICommandParams * aParams)822 nsHighlightColorStateCommand::GetCurrentState(nsIEditor *aEditor,
823 nsICommandParams *aParams)
824 {
825 NS_ASSERTION(aEditor, "Need an editor here");
826 nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(aEditor);
827 NS_ENSURE_TRUE(htmlEditor, NS_ERROR_FAILURE);
828
829 bool outMixed;
830 nsAutoString outStateString;
831 nsresult rv = htmlEditor->GetHighlightColorState(&outMixed, outStateString);
832 NS_ENSURE_SUCCESS(rv, rv);
833
834 nsAutoCString tOutStateString;
835 tOutStateString.AssignWithConversion(outStateString);
836 aParams->SetBooleanValue(STATE_MIXED, outMixed);
837 aParams->SetCStringValue(STATE_ATTRIBUTE, tOutStateString.get());
838 return NS_OK;
839 }
840
841 nsresult
SetState(nsIEditor * aEditor,nsString & newState)842 nsHighlightColorStateCommand::SetState(nsIEditor *aEditor, nsString& newState)
843 {
844 NS_ASSERTION(aEditor, "Need an editor here");
845 nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(aEditor);
846 NS_ENSURE_TRUE(htmlEditor, NS_ERROR_FAILURE);
847
848 if (newState.IsEmpty() || newState.EqualsLiteral("normal")) {
849 return htmlEditor->RemoveInlineProperty(nsGkAtoms::font,
850 NS_LITERAL_STRING("bgcolor"));
851 }
852
853 return htmlEditor->SetInlineProperty(nsGkAtoms::font,
854 NS_LITERAL_STRING("bgcolor"),
855 newState);
856 }
857
858 NS_IMETHODIMP
IsCommandEnabled(const char * aCommandName,nsISupports * refCon,bool * outCmdEnabled)859 nsHighlightColorStateCommand::IsCommandEnabled(const char * aCommandName,
860 nsISupports *refCon,
861 bool *outCmdEnabled)
862 {
863 nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon);
864 if (editor)
865 return editor->GetIsSelectionEditable(outCmdEnabled);
866
867 *outCmdEnabled = false;
868 return NS_OK;
869 }
870
871
nsBackgroundColorStateCommand()872 nsBackgroundColorStateCommand::nsBackgroundColorStateCommand()
873 : nsMultiStateCommand()
874 {
875 }
876
877 nsresult
GetCurrentState(nsIEditor * aEditor,nsICommandParams * aParams)878 nsBackgroundColorStateCommand::GetCurrentState(nsIEditor *aEditor,
879 nsICommandParams *aParams)
880 {
881 NS_ASSERTION(aEditor, "Need an editor here");
882
883 nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(aEditor);
884 NS_ENSURE_TRUE(htmlEditor, NS_ERROR_FAILURE);
885
886 bool outMixed;
887 nsAutoString outStateString;
888 nsresult rv = htmlEditor->GetBackgroundColorState(&outMixed, outStateString);
889 NS_ENSURE_SUCCESS(rv, rv);
890
891 nsAutoCString tOutStateString;
892 tOutStateString.AssignWithConversion(outStateString);
893 aParams->SetBooleanValue(STATE_MIXED, outMixed);
894 aParams->SetCStringValue(STATE_ATTRIBUTE, tOutStateString.get());
895 return NS_OK;
896 }
897
898 nsresult
SetState(nsIEditor * aEditor,nsString & newState)899 nsBackgroundColorStateCommand::SetState(nsIEditor *aEditor, nsString& newState)
900 {
901 NS_ASSERTION(aEditor, "Need an editor here");
902
903 nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(aEditor);
904 NS_ENSURE_TRUE(htmlEditor, NS_ERROR_FAILURE);
905
906 return htmlEditor->SetBackgroundColor(newState);
907 }
908
nsAlignCommand()909 nsAlignCommand::nsAlignCommand()
910 : nsMultiStateCommand()
911 {
912 }
913
914 nsresult
GetCurrentState(nsIEditor * aEditor,nsICommandParams * aParams)915 nsAlignCommand::GetCurrentState(nsIEditor *aEditor, nsICommandParams *aParams)
916 {
917 NS_ASSERTION(aEditor, "Need an editor here");
918
919 nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(aEditor);
920 NS_ENSURE_TRUE(htmlEditor, NS_ERROR_FAILURE);
921
922 nsIHTMLEditor::EAlignment firstAlign;
923 bool outMixed;
924 nsresult rv = htmlEditor->GetAlignment(&outMixed, &firstAlign);
925
926 NS_ENSURE_SUCCESS(rv, rv);
927
928 nsAutoString outStateString;
929 switch (firstAlign) {
930 default:
931 case nsIHTMLEditor::eLeft:
932 outStateString.AssignLiteral("left");
933 break;
934
935 case nsIHTMLEditor::eCenter:
936 outStateString.AssignLiteral("center");
937 break;
938
939 case nsIHTMLEditor::eRight:
940 outStateString.AssignLiteral("right");
941 break;
942
943 case nsIHTMLEditor::eJustify:
944 outStateString.AssignLiteral("justify");
945 break;
946 }
947 nsAutoCString tOutStateString;
948 tOutStateString.AssignWithConversion(outStateString);
949 aParams->SetBooleanValue(STATE_MIXED,outMixed);
950 aParams->SetCStringValue(STATE_ATTRIBUTE, tOutStateString.get());
951 return NS_OK;
952 }
953
954 nsresult
SetState(nsIEditor * aEditor,nsString & newState)955 nsAlignCommand::SetState(nsIEditor *aEditor, nsString& newState)
956 {
957 NS_ASSERTION(aEditor, "Need an editor here");
958
959 nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(aEditor);
960 NS_ENSURE_TRUE(htmlEditor, NS_ERROR_FAILURE);
961
962 return htmlEditor->Align(newState);
963 }
964
nsAbsolutePositioningCommand()965 nsAbsolutePositioningCommand::nsAbsolutePositioningCommand()
966 : nsBaseStateUpdatingCommand(nsGkAtoms::_empty)
967 {
968 }
969
970 NS_IMETHODIMP
IsCommandEnabled(const char * aCommandName,nsISupports * aCommandRefCon,bool * outCmdEnabled)971 nsAbsolutePositioningCommand::IsCommandEnabled(const char * aCommandName,
972 nsISupports *aCommandRefCon,
973 bool *outCmdEnabled)
974 {
975 nsCOMPtr<nsIEditor> editor = do_QueryInterface(aCommandRefCon);
976 nsCOMPtr<nsIHTMLAbsPosEditor> htmlEditor = do_QueryInterface(aCommandRefCon);
977 if (htmlEditor) {
978 bool isEditable = false;
979 nsresult rv = editor->GetIsSelectionEditable(&isEditable);
980 NS_ENSURE_SUCCESS(rv, rv);
981 if (isEditable)
982 return htmlEditor->GetAbsolutePositioningEnabled(outCmdEnabled);
983 }
984
985 *outCmdEnabled = false;
986 return NS_OK;
987 }
988
989 nsresult
GetCurrentState(nsIEditor * aEditor,nsICommandParams * aParams)990 nsAbsolutePositioningCommand::GetCurrentState(nsIEditor *aEditor, nsICommandParams *aParams)
991 {
992 NS_ASSERTION(aEditor, "Need an editor here");
993
994 nsCOMPtr<nsIHTMLAbsPosEditor> htmlEditor = do_QueryInterface(aEditor);
995 NS_ENSURE_TRUE(htmlEditor, NS_ERROR_FAILURE);
996
997 bool isEnabled;
998 htmlEditor->GetAbsolutePositioningEnabled(&isEnabled);
999 if (!isEnabled) {
1000 aParams->SetBooleanValue(STATE_MIXED,false);
1001 aParams->SetCStringValue(STATE_ATTRIBUTE, "");
1002 return NS_OK;
1003 }
1004
1005 nsCOMPtr<nsIDOMElement> elt;
1006 nsresult rv = htmlEditor->GetAbsolutelyPositionedSelectionContainer(getter_AddRefs(elt));
1007 NS_ENSURE_SUCCESS(rv, rv);
1008
1009 nsAutoString outStateString;
1010 if (elt)
1011 outStateString.AssignLiteral("absolute");
1012
1013 aParams->SetBooleanValue(STATE_MIXED,false);
1014 aParams->SetCStringValue(STATE_ATTRIBUTE, NS_ConvertUTF16toUTF8(outStateString).get());
1015 return NS_OK;
1016 }
1017
1018 nsresult
ToggleState(nsIEditor * aEditor)1019 nsAbsolutePositioningCommand::ToggleState(nsIEditor *aEditor)
1020 {
1021 NS_ASSERTION(aEditor, "Need an editor here");
1022
1023 nsCOMPtr<nsIHTMLAbsPosEditor> htmlEditor = do_QueryInterface(aEditor);
1024 NS_ENSURE_TRUE(htmlEditor, NS_ERROR_FAILURE);
1025
1026 nsCOMPtr<nsIDOMElement> elt;
1027 nsresult rv = htmlEditor->GetAbsolutelyPositionedSelectionContainer(getter_AddRefs(elt));
1028 NS_ENSURE_SUCCESS(rv, rv);
1029
1030 return htmlEditor->AbsolutePositionSelection(!elt);
1031 }
1032
1033
1034 NS_IMETHODIMP
IsCommandEnabled(const char * aCommandName,nsISupports * refCon,bool * outCmdEnabled)1035 nsDecreaseZIndexCommand::IsCommandEnabled(const char * aCommandName,
1036 nsISupports *refCon,
1037 bool *outCmdEnabled)
1038 {
1039 nsCOMPtr<nsIHTMLAbsPosEditor> htmlEditor = do_QueryInterface(refCon);
1040 NS_ENSURE_TRUE(htmlEditor, NS_ERROR_FAILURE);
1041
1042 htmlEditor->GetAbsolutePositioningEnabled(outCmdEnabled);
1043 if (!(*outCmdEnabled))
1044 return NS_OK;
1045
1046 nsCOMPtr<nsIDOMElement> positionedElement;
1047 htmlEditor->GetPositionedElement(getter_AddRefs(positionedElement));
1048 *outCmdEnabled = false;
1049 if (positionedElement) {
1050 int32_t z;
1051 nsresult rv = htmlEditor->GetElementZIndex(positionedElement, &z);
1052 NS_ENSURE_SUCCESS(rv, rv);
1053 *outCmdEnabled = (z > 0);
1054 }
1055
1056 return NS_OK;
1057 }
1058
1059 NS_IMETHODIMP
DoCommand(const char * aCommandName,nsISupports * refCon)1060 nsDecreaseZIndexCommand::DoCommand(const char *aCommandName,
1061 nsISupports *refCon)
1062 {
1063 nsCOMPtr<nsIHTMLAbsPosEditor> htmlEditor = do_QueryInterface(refCon);
1064 NS_ENSURE_TRUE(htmlEditor, NS_ERROR_NOT_IMPLEMENTED);
1065
1066 return htmlEditor->RelativeChangeZIndex(-1);
1067 }
1068
1069 NS_IMETHODIMP
DoCommandParams(const char * aCommandName,nsICommandParams * aParams,nsISupports * refCon)1070 nsDecreaseZIndexCommand::DoCommandParams(const char *aCommandName,
1071 nsICommandParams *aParams,
1072 nsISupports *refCon)
1073 {
1074 return DoCommand(aCommandName, refCon);
1075 }
1076
1077 NS_IMETHODIMP
GetCommandStateParams(const char * aCommandName,nsICommandParams * aParams,nsISupports * refCon)1078 nsDecreaseZIndexCommand::GetCommandStateParams(const char *aCommandName,
1079 nsICommandParams *aParams,
1080 nsISupports *refCon)
1081 {
1082 NS_ENSURE_ARG_POINTER(aParams);
1083
1084 bool enabled = false;
1085 nsresult rv = IsCommandEnabled(aCommandName, refCon, &enabled);
1086 NS_ENSURE_SUCCESS(rv, rv);
1087
1088 return aParams->SetBooleanValue(STATE_ENABLED, enabled);
1089 }
1090
1091 NS_IMETHODIMP
IsCommandEnabled(const char * aCommandName,nsISupports * refCon,bool * outCmdEnabled)1092 nsIncreaseZIndexCommand::IsCommandEnabled(const char * aCommandName,
1093 nsISupports *refCon,
1094 bool *outCmdEnabled)
1095 {
1096 nsCOMPtr<nsIHTMLAbsPosEditor> htmlEditor = do_QueryInterface(refCon);
1097 NS_ENSURE_TRUE(htmlEditor, NS_ERROR_FAILURE);
1098
1099 htmlEditor->GetAbsolutePositioningEnabled(outCmdEnabled);
1100 if (!(*outCmdEnabled))
1101 return NS_OK;
1102
1103 nsCOMPtr<nsIDOMElement> positionedElement;
1104 htmlEditor->GetPositionedElement(getter_AddRefs(positionedElement));
1105 *outCmdEnabled = (nullptr != positionedElement);
1106 return NS_OK;
1107 }
1108
1109 NS_IMETHODIMP
DoCommand(const char * aCommandName,nsISupports * refCon)1110 nsIncreaseZIndexCommand::DoCommand(const char *aCommandName,
1111 nsISupports *refCon)
1112 {
1113 nsCOMPtr<nsIHTMLAbsPosEditor> htmlEditor = do_QueryInterface(refCon);
1114 NS_ENSURE_TRUE(htmlEditor, NS_ERROR_NOT_IMPLEMENTED);
1115
1116 return htmlEditor->RelativeChangeZIndex(1);
1117 }
1118
1119 NS_IMETHODIMP
DoCommandParams(const char * aCommandName,nsICommandParams * aParams,nsISupports * refCon)1120 nsIncreaseZIndexCommand::DoCommandParams(const char *aCommandName,
1121 nsICommandParams *aParams,
1122 nsISupports *refCon)
1123 {
1124 return DoCommand(aCommandName, refCon);
1125 }
1126
1127 NS_IMETHODIMP
GetCommandStateParams(const char * aCommandName,nsICommandParams * aParams,nsISupports * refCon)1128 nsIncreaseZIndexCommand::GetCommandStateParams(const char *aCommandName,
1129 nsICommandParams *aParams,
1130 nsISupports *refCon)
1131 {
1132 NS_ENSURE_ARG_POINTER(aParams);
1133
1134 bool enabled = false;
1135 nsresult rv = IsCommandEnabled(aCommandName, refCon, &enabled);
1136 NS_ENSURE_SUCCESS(rv, rv);
1137
1138 return aParams->SetBooleanValue(STATE_ENABLED, enabled);
1139 }
1140
1141
1142 NS_IMETHODIMP
IsCommandEnabled(const char * aCommandName,nsISupports * refCon,bool * outCmdEnabled)1143 nsRemoveStylesCommand::IsCommandEnabled(const char * aCommandName,
1144 nsISupports *refCon,
1145 bool *outCmdEnabled)
1146 {
1147 nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon);
1148 // test if we have any styles?
1149 if (editor)
1150 return editor->GetIsSelectionEditable(outCmdEnabled);
1151
1152 *outCmdEnabled = false;
1153 return NS_OK;
1154 }
1155
1156
1157
1158 NS_IMETHODIMP
DoCommand(const char * aCommandName,nsISupports * refCon)1159 nsRemoveStylesCommand::DoCommand(const char *aCommandName,
1160 nsISupports *refCon)
1161 {
1162 nsCOMPtr<nsIHTMLEditor> editor = do_QueryInterface(refCon);
1163
1164 nsresult rv = NS_OK;
1165 if (editor) {
1166 rv = editor->RemoveAllInlineProperties();
1167 }
1168
1169 return rv;
1170 }
1171
1172 NS_IMETHODIMP
DoCommandParams(const char * aCommandName,nsICommandParams * aParams,nsISupports * refCon)1173 nsRemoveStylesCommand::DoCommandParams(const char *aCommandName,
1174 nsICommandParams *aParams,
1175 nsISupports *refCon)
1176 {
1177 return DoCommand(aCommandName, refCon);
1178 }
1179
1180 NS_IMETHODIMP
GetCommandStateParams(const char * aCommandName,nsICommandParams * aParams,nsISupports * refCon)1181 nsRemoveStylesCommand::GetCommandStateParams(const char *aCommandName,
1182 nsICommandParams *aParams,
1183 nsISupports *refCon)
1184 {
1185 bool outCmdEnabled = false;
1186 IsCommandEnabled(aCommandName, refCon, &outCmdEnabled);
1187 return aParams->SetBooleanValue(STATE_ENABLED,outCmdEnabled);
1188 }
1189
1190 NS_IMETHODIMP
IsCommandEnabled(const char * aCommandName,nsISupports * refCon,bool * outCmdEnabled)1191 nsIncreaseFontSizeCommand::IsCommandEnabled(const char * aCommandName,
1192 nsISupports *refCon,
1193 bool *outCmdEnabled)
1194 {
1195 nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon);
1196 // test if we are at max size?
1197 if (editor)
1198 return editor->GetIsSelectionEditable(outCmdEnabled);
1199
1200 *outCmdEnabled = false;
1201 return NS_OK;
1202 }
1203
1204
1205 NS_IMETHODIMP
DoCommand(const char * aCommandName,nsISupports * refCon)1206 nsIncreaseFontSizeCommand::DoCommand(const char *aCommandName,
1207 nsISupports *refCon)
1208 {
1209 nsCOMPtr<nsIHTMLEditor> editor = do_QueryInterface(refCon);
1210
1211 nsresult rv = NS_OK;
1212 if (editor) {
1213 rv = editor->IncreaseFontSize();
1214 }
1215
1216 return rv;
1217 }
1218
1219 NS_IMETHODIMP
DoCommandParams(const char * aCommandName,nsICommandParams * aParams,nsISupports * refCon)1220 nsIncreaseFontSizeCommand::DoCommandParams(const char *aCommandName,
1221 nsICommandParams *aParams,
1222 nsISupports *refCon)
1223 {
1224 return DoCommand(aCommandName, refCon);
1225 }
1226
1227 NS_IMETHODIMP
GetCommandStateParams(const char * aCommandName,nsICommandParams * aParams,nsISupports * refCon)1228 nsIncreaseFontSizeCommand::GetCommandStateParams(const char *aCommandName,
1229 nsICommandParams *aParams,
1230 nsISupports *refCon)
1231 {
1232 bool outCmdEnabled = false;
1233 IsCommandEnabled(aCommandName, refCon, &outCmdEnabled);
1234 return aParams->SetBooleanValue(STATE_ENABLED,outCmdEnabled);
1235 }
1236
1237 NS_IMETHODIMP
IsCommandEnabled(const char * aCommandName,nsISupports * refCon,bool * outCmdEnabled)1238 nsDecreaseFontSizeCommand::IsCommandEnabled(const char * aCommandName,
1239 nsISupports *refCon,
1240 bool *outCmdEnabled)
1241 {
1242 nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon);
1243 // test if we are at min size?
1244 if (editor)
1245 return editor->GetIsSelectionEditable(outCmdEnabled);
1246
1247 *outCmdEnabled = false;
1248 return NS_OK;
1249 }
1250
1251
1252 NS_IMETHODIMP
DoCommand(const char * aCommandName,nsISupports * refCon)1253 nsDecreaseFontSizeCommand::DoCommand(const char *aCommandName,
1254 nsISupports *refCon)
1255 {
1256 nsCOMPtr<nsIHTMLEditor> editor = do_QueryInterface(refCon);
1257
1258 nsresult rv = NS_OK;
1259 if (editor) {
1260 rv = editor->DecreaseFontSize();
1261 }
1262
1263 return rv;
1264 }
1265
1266 NS_IMETHODIMP
DoCommandParams(const char * aCommandName,nsICommandParams * aParams,nsISupports * refCon)1267 nsDecreaseFontSizeCommand::DoCommandParams(const char *aCommandName,
1268 nsICommandParams *aParams,
1269 nsISupports *refCon)
1270 {
1271 return DoCommand(aCommandName, refCon);
1272 }
1273
1274 NS_IMETHODIMP
GetCommandStateParams(const char * aCommandName,nsICommandParams * aParams,nsISupports * refCon)1275 nsDecreaseFontSizeCommand::GetCommandStateParams(const char *aCommandName,
1276 nsICommandParams *aParams,
1277 nsISupports *refCon)
1278 {
1279 bool outCmdEnabled = false;
1280 IsCommandEnabled(aCommandName, refCon, &outCmdEnabled);
1281 return aParams->SetBooleanValue(STATE_ENABLED,outCmdEnabled);
1282 }
1283
1284 NS_IMETHODIMP
IsCommandEnabled(const char * aCommandName,nsISupports * refCon,bool * outCmdEnabled)1285 nsInsertHTMLCommand::IsCommandEnabled(const char * aCommandName,
1286 nsISupports *refCon,
1287 bool *outCmdEnabled)
1288 {
1289 NS_ENSURE_ARG_POINTER(outCmdEnabled);
1290 nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon);
1291 if (editor)
1292 return editor->GetIsSelectionEditable(outCmdEnabled);
1293
1294 *outCmdEnabled = false;
1295 return NS_OK;
1296 }
1297
1298
1299 NS_IMETHODIMP
DoCommand(const char * aCommandName,nsISupports * refCon)1300 nsInsertHTMLCommand::DoCommand(const char *aCommandName, nsISupports *refCon)
1301 {
1302 // If nsInsertHTMLCommand is called with no parameters, it was probably called with
1303 // an empty string parameter ''. In this case, it should act the same as the delete command
1304 NS_ENSURE_ARG_POINTER(refCon);
1305
1306 nsCOMPtr<nsIHTMLEditor> editor = do_QueryInterface(refCon);
1307 NS_ENSURE_TRUE(editor, NS_ERROR_NOT_IMPLEMENTED);
1308
1309 nsString html = EmptyString();
1310 return editor->InsertHTML(html);
1311 }
1312
1313 NS_IMETHODIMP
DoCommandParams(const char * aCommandName,nsICommandParams * aParams,nsISupports * refCon)1314 nsInsertHTMLCommand::DoCommandParams(const char *aCommandName,
1315 nsICommandParams *aParams,
1316 nsISupports *refCon)
1317 {
1318 NS_ENSURE_ARG_POINTER(aParams);
1319 NS_ENSURE_ARG_POINTER(refCon);
1320
1321 nsCOMPtr<nsIHTMLEditor> editor = do_QueryInterface(refCon);
1322 NS_ENSURE_TRUE(editor, NS_ERROR_NOT_IMPLEMENTED);
1323
1324 // Get HTML source string to insert from command params
1325 nsAutoString html;
1326 nsresult rv = aParams->GetStringValue(STATE_DATA, html);
1327 NS_ENSURE_SUCCESS(rv, rv);
1328
1329 return editor->InsertHTML(html);
1330 }
1331
1332 NS_IMETHODIMP
GetCommandStateParams(const char * aCommandName,nsICommandParams * aParams,nsISupports * refCon)1333 nsInsertHTMLCommand::GetCommandStateParams(const char *aCommandName,
1334 nsICommandParams *aParams,
1335 nsISupports *refCon)
1336 {
1337 NS_ENSURE_ARG_POINTER(aParams);
1338 NS_ENSURE_ARG_POINTER(refCon);
1339
1340 bool outCmdEnabled = false;
1341 IsCommandEnabled(aCommandName, refCon, &outCmdEnabled);
1342 return aParams->SetBooleanValue(STATE_ENABLED, outCmdEnabled);
1343 }
1344
NS_IMPL_ISUPPORTS_INHERITED0(nsInsertTagCommand,nsBaseComposerCommand)1345 NS_IMPL_ISUPPORTS_INHERITED0(nsInsertTagCommand, nsBaseComposerCommand)
1346
1347 nsInsertTagCommand::nsInsertTagCommand(nsIAtom* aTagName)
1348 : nsBaseComposerCommand()
1349 , mTagName(aTagName)
1350 {
1351 MOZ_ASSERT(mTagName);
1352 }
1353
~nsInsertTagCommand()1354 nsInsertTagCommand::~nsInsertTagCommand()
1355 {
1356 }
1357
1358 NS_IMETHODIMP
IsCommandEnabled(const char * aCommandName,nsISupports * refCon,bool * outCmdEnabled)1359 nsInsertTagCommand::IsCommandEnabled(const char * aCommandName,
1360 nsISupports *refCon,
1361 bool *outCmdEnabled)
1362 {
1363 NS_ENSURE_ARG_POINTER(outCmdEnabled);
1364 nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon);
1365 if (editor)
1366 return editor->GetIsSelectionEditable(outCmdEnabled);
1367
1368 *outCmdEnabled = false;
1369 return NS_OK;
1370 }
1371
1372
1373 // corresponding STATE_ATTRIBUTE is: src (img) and href (a)
1374 NS_IMETHODIMP
DoCommand(const char * aCmdName,nsISupports * refCon)1375 nsInsertTagCommand::DoCommand(const char *aCmdName, nsISupports *refCon)
1376 {
1377 NS_ENSURE_TRUE(mTagName == nsGkAtoms::hr, NS_ERROR_NOT_IMPLEMENTED);
1378
1379 nsCOMPtr<nsIHTMLEditor> editor = do_QueryInterface(refCon);
1380 NS_ENSURE_TRUE(editor, NS_ERROR_NOT_IMPLEMENTED);
1381
1382 nsCOMPtr<nsIDOMElement> domElem;
1383 nsresult rv = editor->CreateElementWithDefaults(
1384 nsDependentAtomString(mTagName), getter_AddRefs(domElem));
1385 NS_ENSURE_SUCCESS(rv, rv);
1386
1387 return editor->InsertElementAtSelection(domElem, true);
1388 }
1389
1390 NS_IMETHODIMP
DoCommandParams(const char * aCommandName,nsICommandParams * aParams,nsISupports * refCon)1391 nsInsertTagCommand::DoCommandParams(const char *aCommandName,
1392 nsICommandParams *aParams,
1393 nsISupports *refCon)
1394 {
1395 NS_ENSURE_ARG_POINTER(refCon);
1396
1397 // inserting an hr shouldn't have an parameters, just call DoCommand for that
1398 if (mTagName == nsGkAtoms::hr) {
1399 return DoCommand(aCommandName, refCon);
1400 }
1401
1402 NS_ENSURE_ARG_POINTER(aParams);
1403
1404 nsCOMPtr<nsIHTMLEditor> editor = do_QueryInterface(refCon);
1405 NS_ENSURE_TRUE(editor, NS_ERROR_NOT_IMPLEMENTED);
1406
1407 // do we have an href to use for creating link?
1408 nsXPIDLCString s;
1409 nsresult rv = aParams->GetCStringValue(STATE_ATTRIBUTE, getter_Copies(s));
1410 NS_ENSURE_SUCCESS(rv, rv);
1411 nsAutoString attrib; attrib.AssignWithConversion(s);
1412
1413 if (attrib.IsEmpty())
1414 return NS_ERROR_INVALID_ARG;
1415
1416 // filter out tags we don't know how to insert
1417 nsAutoString attributeType;
1418 if (mTagName == nsGkAtoms::a) {
1419 attributeType.AssignLiteral("href");
1420 } else if (mTagName == nsGkAtoms::img) {
1421 attributeType.AssignLiteral("src");
1422 } else {
1423 return NS_ERROR_NOT_IMPLEMENTED;
1424 }
1425
1426 nsCOMPtr<nsIDOMElement> domElem;
1427 rv = editor->CreateElementWithDefaults(nsDependentAtomString(mTagName),
1428 getter_AddRefs(domElem));
1429 NS_ENSURE_SUCCESS(rv, rv);
1430
1431 rv = domElem->SetAttribute(attributeType, attrib);
1432 NS_ENSURE_SUCCESS(rv, rv);
1433
1434 // do actual insertion
1435 if (mTagName == nsGkAtoms::a)
1436 return editor->InsertLinkAroundSelection(domElem);
1437
1438 return editor->InsertElementAtSelection(domElem, true);
1439 }
1440
1441 NS_IMETHODIMP
GetCommandStateParams(const char * aCommandName,nsICommandParams * aParams,nsISupports * refCon)1442 nsInsertTagCommand::GetCommandStateParams(const char *aCommandName,
1443 nsICommandParams *aParams,
1444 nsISupports *refCon)
1445 {
1446 NS_ENSURE_ARG_POINTER(aParams);
1447 NS_ENSURE_ARG_POINTER(refCon);
1448
1449 bool outCmdEnabled = false;
1450 IsCommandEnabled(aCommandName, refCon, &outCmdEnabled);
1451 return aParams->SetBooleanValue(STATE_ENABLED, outCmdEnabled);
1452 }
1453
1454
1455 /****************************/
1456 //HELPER METHODS
1457 /****************************/
1458
1459 nsresult
GetListState(nsIHTMLEditor * aEditor,bool * aMixed,nsAString & aLocalName)1460 GetListState(nsIHTMLEditor* aEditor, bool* aMixed, nsAString& aLocalName)
1461 {
1462 MOZ_ASSERT(aEditor);
1463 MOZ_ASSERT(aMixed);
1464
1465 *aMixed = false;
1466 aLocalName.Truncate();
1467
1468 bool bOL, bUL, bDL;
1469 nsresult rv = aEditor->GetListState(aMixed, &bOL, &bUL, &bDL);
1470 NS_ENSURE_SUCCESS(rv, rv);
1471
1472 if (*aMixed) {
1473 return NS_OK;
1474 }
1475
1476 if (bOL) {
1477 aLocalName.AssignLiteral("ol");
1478 } else if (bUL) {
1479 aLocalName.AssignLiteral("ul");
1480 } else if (bDL) {
1481 aLocalName.AssignLiteral("dl");
1482 }
1483 return NS_OK;
1484 }
1485
1486 nsresult
RemoveOneProperty(nsIHTMLEditor * aEditor,const nsAString & aProp)1487 RemoveOneProperty(nsIHTMLEditor* aEditor, const nsAString& aProp)
1488 {
1489 MOZ_ASSERT(aEditor);
1490
1491 /// XXX Hack alert! Look in nsIEditProperty.h for this
1492 nsCOMPtr<nsIAtom> styleAtom = NS_Atomize(aProp);
1493 NS_ENSURE_TRUE(styleAtom, NS_ERROR_OUT_OF_MEMORY);
1494
1495 return aEditor->RemoveInlineProperty(styleAtom, EmptyString());
1496 }
1497
1498
1499 // the name of the attribute here should be the contents of the appropriate
1500 // tag, e.g. 'b' for bold, 'i' for italics.
1501 nsresult
RemoveTextProperty(nsIHTMLEditor * aEditor,const nsAString & aProp)1502 RemoveTextProperty(nsIHTMLEditor* aEditor, const nsAString& aProp)
1503 {
1504 MOZ_ASSERT(aEditor);
1505
1506 if (aProp.LowerCaseEqualsLiteral("all")) {
1507 return aEditor->RemoveAllInlineProperties();
1508 }
1509
1510 return RemoveOneProperty(aEditor, aProp);
1511 }
1512
1513 // the name of the attribute here should be the contents of the appropriate
1514 // tag, e.g. 'b' for bold, 'i' for italics.
1515 nsresult
SetTextProperty(nsIHTMLEditor * aEditor,const nsAString & aProp)1516 SetTextProperty(nsIHTMLEditor* aEditor, const nsAString& aProp)
1517 {
1518 MOZ_ASSERT(aEditor);
1519
1520 /// XXX Hack alert! Look in nsIEditProperty.h for this
1521 nsCOMPtr<nsIAtom> styleAtom = NS_Atomize(aProp);
1522 NS_ENSURE_TRUE(styleAtom, NS_ERROR_OUT_OF_MEMORY);
1523
1524 return aEditor->SetInlineProperty(styleAtom, EmptyString(), EmptyString());
1525 }
1526