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