Back to index

lightning-sunbird  0.9+nobinonly
nsHTMLEditorLog.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Pierre Phaneuf <pp@ludusdesign.com>
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either of the GNU General Public License Version 2 or later (the "GPL"),
00027  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 
00039 #include <stdio.h>
00040 #include "nsIDOMElement.h"
00041 #include "nsIDOMAttr.h"
00042 #include "nsIDOMNode.h"
00043 #include "nsIDOMNodeList.h"
00044 #include "nsIDOMCharacterData.h"
00045 #include "nsIDOMNamedNodeMap.h"
00046 #include "nsISelection.h"
00047 #include "nsIDOMRange.h"
00048 #include "nsHTMLEditorLog.h"
00049 #include "nsNetUtil.h"
00050 #include "nsCOMPtr.h"
00051 #include "nsCRT.h"
00052 #include "prprf.h"
00053 
00054 #include "nsEditorTxnLog.h"
00055 
00056 #define LOCK_LOG(doc)
00057 #define UNLOCK_LOG(doc)
00058 
00059 nsHTMLEditorLog::nsHTMLEditorLog()
00060 {
00061   mLocked   = -1;
00062   mEditorTxnLog = 0;
00063 }
00064 
00065 nsHTMLEditorLog::~nsHTMLEditorLog()
00066 {
00067   StopLogging();
00068 }
00069 
00070 NS_IMPL_ISUPPORTS_INHERITED1(nsHTMLEditorLog, nsHTMLEditor, nsIEditorLogging)
00071 
00072 NS_IMETHODIMP
00073 nsHTMLEditorLog::SetInlineProperty(nsIAtom *aProperty, const nsAString &aAttribute, const nsAString &aValue)
00074 {
00075   nsAutoHTMLEditorLogLock logLock(this);
00076 
00077   if (!mLocked && mFileStream)
00078   {
00079     nsAutoString propStr;
00080 
00081     aProperty->ToString(propStr);
00082 
00083     PrintSelection();
00084     Write("atomService = Components.classes[\"@mozilla.org/atom-service;1\"].getService(Components.interfaces.nsIAtomService);\n");
00085     Write("propAtom = atomService.getAtom(\"");
00086     PrintUnicode(propStr);
00087     Write("\");\n");
00088     Write("GetCurrentEditor().setInlineProperty(propAtom, \"");
00089     if (aAttribute.Length())
00090       PrintUnicode(aAttribute);
00091     Write("\", \"");
00092     if (aValue.Length())
00093       PrintUnicode(aValue);
00094     Write("\");\n");
00095 
00096     Flush();
00097   }
00098 
00099   return nsHTMLEditor::SetInlineProperty(aProperty, aAttribute, aValue);
00100 }
00101 
00102 NS_IMETHODIMP
00103 nsHTMLEditorLog::SetParagraphFormat(const nsAString& aParagraphFormat)
00104 {
00105   nsAutoHTMLEditorLogLock logLock(this);
00106 
00107   if (!mLocked && mFileStream)
00108   {
00109     PrintSelection();
00110     Write("GetCurrentEditor().setParagraphFormat(\"");
00111     PrintUnicode(aParagraphFormat);
00112     Write("\");\n");
00113 
00114     Flush();
00115   }
00116 
00117   return nsHTMLEditor::SetParagraphFormat(aParagraphFormat);
00118 }
00119 
00120 NS_IMETHODIMP
00121 nsHTMLEditorLog::RemoveInlineProperty(nsIAtom *aProperty, const nsAString &aAttribute)
00122 {
00123   nsAutoHTMLEditorLogLock logLock(this);
00124 
00125   if (!mLocked && mFileStream)
00126   {
00127     nsAutoString propStr;
00128 
00129     aProperty->ToString(propStr);
00130 
00131     PrintSelection();
00132     Write("atomService = Components.classes[\"@mozilla.org/atom-service;1\"].getService(Components.interfaces.nsIAtomService);\n");
00133     Write("propAtom = atomService.getAtom(\"");
00134     PrintUnicode(propStr);
00135     Write("\");\n");
00136     Write("GetCurrentEditor().removeInlineProperty(propAtom, \"");
00137     if (aAttribute.Length())
00138       PrintUnicode(aAttribute);
00139     Write("\");\n");
00140 
00141     Flush();
00142   }
00143 
00144   return nsHTMLEditor::RemoveInlineProperty(aProperty, aAttribute);
00145 }
00146 
00147 NS_IMETHODIMP
00148 nsHTMLEditorLog::DeleteSelection(nsIEditor::EDirection aAction)
00149 {
00150   nsAutoHTMLEditorLogLock logLock(this);
00151 
00152   if (!mLocked && mFileStream)
00153   {
00154     PrintSelection();
00155     Write("GetCurrentEditor().deleteSelection(");
00156     WriteInt(aAction);
00157     Write(");\n");
00158 
00159     Flush();
00160   }
00161 
00162   return nsHTMLEditor::DeleteSelection(aAction);
00163 }
00164 
00165 NS_IMETHODIMP
00166 nsHTMLEditorLog::InsertText(const nsAString& aStringToInsert)
00167 {
00168   nsAutoHTMLEditorLogLock logLock(this);
00169 
00170   if (!mLocked && mFileStream)
00171   {
00172     PrintSelection();
00173 
00174     Write("GetCurrentEditor().insertText(\"");
00175     nsAutoString str(aStringToInsert);
00176     PrintUnicode(str);
00177     Write("\");\n");
00178 
00179     Flush();
00180   }
00181 
00182   return nsHTMLEditor::InsertText(aStringToInsert);
00183 }
00184 
00185 NS_IMETHODIMP
00186 nsHTMLEditorLog::InsertLineBreak()
00187 {
00188   nsAutoHTMLEditorLogLock logLock(this);
00189 
00190   if (!mLocked && mFileStream)
00191   {
00192     PrintSelection();
00193     Write("GetCurrentEditor().insertLineBreak();\n");
00194     Flush();
00195   }
00196 
00197   return nsHTMLEditor::InsertLineBreak();
00198 }
00199 
00200 NS_IMETHODIMP
00201 nsHTMLEditorLog::Undo(PRUint32 aCount)
00202 {
00203   nsAutoHTMLEditorLogLock logLock(this);
00204 
00205   if (!mLocked && mFileStream)
00206   {
00207     Write("GetCurrentEditor().undo(");
00208     WriteInt(aCount);
00209     Write(");\n");
00210     Flush();
00211   }
00212 
00213   return nsHTMLEditor::Undo(aCount);
00214 }
00215 
00216 NS_IMETHODIMP
00217 nsHTMLEditorLog::Redo(PRUint32 aCount)
00218 {
00219   nsAutoHTMLEditorLogLock logLock(this);
00220 
00221   if (!mLocked && mFileStream)
00222   {
00223     Write("GetCurrentEditor().redo(");
00224     WriteInt(aCount);
00225     Write(");\n");
00226     Flush();
00227   }
00228 
00229   return nsHTMLEditor::Redo(aCount);
00230 }
00231 
00232 NS_IMETHODIMP
00233 nsHTMLEditorLog::BeginTransaction()
00234 {
00235   nsAutoHTMLEditorLogLock logLock(this);
00236 
00237   if (!mLocked && mFileStream)
00238   {
00239     Write("GetCurrentEditor().beginTransaction();\n");
00240     Flush();
00241   }
00242 
00243   return nsHTMLEditor::BeginTransaction();
00244 }
00245 
00246 NS_IMETHODIMP
00247 nsHTMLEditorLog::EndTransaction()
00248 {
00249   nsAutoHTMLEditorLogLock logLock(this);
00250 
00251   if (!mLocked && mFileStream)
00252   {
00253     Write("GetCurrentEditor().endTransaction();\n");
00254     Flush();
00255   }
00256 
00257   return nsHTMLEditor::EndTransaction();
00258 }
00259 
00260 NS_IMETHODIMP
00261 nsHTMLEditorLog::SelectAll()
00262 {
00263   nsAutoHTMLEditorLogLock logLock(this);
00264 
00265   if (!mLocked && mFileStream)
00266   {
00267     Write("GetCurrentEditor().selectAll();\n");
00268     Flush();
00269   }
00270 
00271   return nsHTMLEditor::SelectAll();
00272 }
00273 
00274 NS_IMETHODIMP
00275 nsHTMLEditorLog::BeginningOfDocument()
00276 {
00277   nsAutoHTMLEditorLogLock logLock(this);
00278 
00279   if (!mLocked && mFileStream)
00280   {
00281     Write("GetCurrentEditor().beginningOfDocument();\n");
00282     Flush();
00283   }
00284 
00285   return nsHTMLEditor::BeginningOfDocument();
00286 }
00287 
00288 NS_IMETHODIMP
00289 nsHTMLEditorLog::EndOfDocument()
00290 {
00291   nsAutoHTMLEditorLogLock logLock(this);
00292 
00293   if (!mLocked && mFileStream)
00294   {
00295     Write("GetCurrentEditor().endOfDocument();\n");
00296     Flush();
00297   }
00298 
00299   return nsHTMLEditor::EndOfDocument();
00300 }
00301 
00302 NS_IMETHODIMP
00303 nsHTMLEditorLog::Cut()
00304 {
00305   nsAutoHTMLEditorLogLock logLock(this);
00306 
00307   if (!mLocked && mFileStream)
00308   {
00309     PrintSelection();
00310     Write("GetCurrentEditor().cut();\n");
00311     Flush();
00312   }
00313 
00314   return nsHTMLEditor::Cut();
00315 }
00316 
00317 NS_IMETHODIMP
00318 nsHTMLEditorLog::Copy()
00319 {
00320   nsAutoHTMLEditorLogLock logLock(this);
00321 
00322   if (!mLocked && mFileStream)
00323   {
00324     PrintSelection();
00325     Write("GetCurrentEditor().copy();\n");
00326     Flush();
00327   }
00328 
00329   return nsHTMLEditor::Copy();
00330 }
00331 
00332 NS_IMETHODIMP
00333 nsHTMLEditorLog::Paste(PRInt32 aClipboardType)
00334 {
00335   nsAutoHTMLEditorLogLock logLock(this);
00336 
00337   if (!mLocked && mFileStream)
00338   {
00339     PrintSelection();
00340     Write("GetCurrentEditor().paste(");
00341     WriteInt(aClipboardType);
00342     Write(");\n");
00343     Flush();
00344   }
00345 
00346   return nsHTMLEditor::Paste(aClipboardType);
00347 }
00348 
00349 NS_IMETHODIMP
00350 nsHTMLEditorLog::PasteAsQuotation(PRInt32 aClipboardType)
00351 {
00352   nsAutoHTMLEditorLogLock logLock(this);
00353 
00354   if (!mLocked && mFileStream)
00355   {
00356     PrintSelection();
00357     Write("GetCurrentEditor().pasteAsQuotation(");
00358     WriteInt(aClipboardType);
00359     Write(");\n");
00360     Flush();
00361   }
00362 
00363   return nsHTMLEditor::PasteAsQuotation(aClipboardType);
00364 }
00365 
00366 NS_IMETHODIMP
00367 nsHTMLEditorLog::PasteAsPlaintextQuotation(PRInt32 aClipboardType)
00368 {
00369   nsAutoHTMLEditorLogLock logLock(this);
00370 
00371   if (!mLocked && mFileStream)
00372   {
00373     PrintSelection();
00374     Write("GetCurrentEditor().pasteAsQuotation(");
00375     WriteInt(aClipboardType);
00376     Write(");\n");
00377     Flush();
00378   }
00379 
00380   return nsHTMLEditor::PasteAsPlaintextQuotation(aClipboardType);
00381 }
00382 
00383 NS_IMETHODIMP
00384 nsHTMLEditorLog::PasteAsCitedQuotation(const nsAString& aCitation,
00385                                        PRInt32 aClipboardType)
00386 {
00387   nsAutoHTMLEditorLogLock logLock(this);
00388 
00389   if (!mLocked && mFileStream)
00390   {
00391     PrintSelection();
00392     Write("GetCurrentEditor().pasteAsCitedQuotation(\"");
00393     PrintUnicode(aCitation);
00394     Write("\", ");
00395     WriteInt(aClipboardType);
00396     Write(");\n");
00397     Flush();
00398   }
00399 
00400   return nsHTMLEditor::PasteAsCitedQuotation(aCitation, aClipboardType);
00401 }
00402 
00403 NS_IMETHODIMP
00404 nsHTMLEditorLog::InsertAsQuotation(const nsAString& aQuotedText,
00405                                    nsIDOMNode **aNodeInserted)
00406 {
00407   nsAutoHTMLEditorLogLock logLock(this);
00408 
00409   if (!mLocked && mFileStream)
00410   {
00411     PrintSelection();
00412     Write("GetCurrentEditor().insertAsQuotation(\"");
00413     PrintUnicode(aQuotedText);
00414     Write("\");\n");
00415     Flush();
00416   }
00417 
00418   return nsHTMLEditor::InsertAsQuotation(aQuotedText, aNodeInserted);
00419 }
00420 
00421 NS_IMETHODIMP
00422 nsHTMLEditorLog::InsertAsPlaintextQuotation(const nsAString& aQuotedText,
00423                                             PRBool aAddCites,
00424                                             nsIDOMNode **aNodeInserted)
00425 {
00426   nsAutoHTMLEditorLogLock logLock(this);
00427 
00428   if (!mLocked && mFileStream)
00429   {
00430     PrintSelection();
00431     Write("GetCurrentEditor().insertAsQuotation(\"");
00432     PrintUnicode(aQuotedText);
00433     Write("\");\n");
00434     Flush();
00435   }
00436 
00437   return nsHTMLEditor::InsertAsPlaintextQuotation(aQuotedText,
00438                                                   aAddCites,
00439                                                   aNodeInserted);
00440 }
00441 
00442 NS_IMETHODIMP
00443 nsHTMLEditorLog::InsertAsCitedQuotation(const nsAString& aQuotedText,
00444                                         const nsAString& aCitation,
00445                                         PRBool aInsertHTML,
00446                                         nsIDOMNode **aNodeInserted)
00447 {
00448   nsAutoHTMLEditorLogLock logLock(this);
00449 
00450   if (!mLocked && mFileStream)
00451   {
00452     PrintSelection();
00453     Write("GetCurrentEditor().insertAsCitedQuotation(\"");
00454     PrintUnicode(aQuotedText);
00455     Write("\", \"");
00456     PrintUnicode(aCitation);
00457     Write("\", ");
00458     Write(aInsertHTML ? "true" : "false");
00459     Write("\");\n");
00460     Flush();
00461   }
00462 
00463   return nsHTMLEditor::InsertAsCitedQuotation(aQuotedText, aCitation, aInsertHTML,
00464                                               aNodeInserted);
00465 }
00466 
00467 NS_IMETHODIMP
00468 nsHTMLEditorLog::SetBackgroundColor(const nsAString& aColor)
00469 {
00470   nsAutoHTMLEditorLogLock logLock(this);
00471 
00472   if (!mLocked && mFileStream)
00473   {
00474     Write("GetCurrentEditor().setBackgroundColor(\"");
00475     PrintUnicode(aColor);
00476     Write("\");\n");
00477     Flush();
00478   }
00479 
00480   return nsHTMLEditor::SetBackgroundColor(aColor);
00481 }
00482 
00483 NS_IMETHODIMP
00484 nsHTMLEditorLog::SetBodyAttribute(const nsAString& aAttr, const nsAString& aValue)
00485 {
00486   nsAutoHTMLEditorLogLock logLock(this);
00487 
00488   if (!mLocked && mFileStream)
00489   {
00490     Write("GetCurrentEditor().setBodyAttribute(\"");
00491     PrintUnicode(aAttr);
00492     Write("\", \"");
00493     PrintUnicode(aValue);
00494     Write("\");\n");
00495     Flush();
00496   }
00497 
00498   return nsHTMLEditor::SetBodyAttribute(aAttr, aValue);
00499 }
00500 
00501 NS_IMETHODIMP
00502 nsHTMLEditorLog:: InsertTableCell(PRInt32 aNumber, PRBool aAfter)
00503 {
00504   nsAutoHTMLEditorLogLock logLock(this);
00505 
00506   if (!mLocked && mFileStream)
00507   {
00508     Write("GetCurrentEditor().insertTableCell(");
00509     WriteInt(aNumber);
00510     Write(", ");
00511     Write(aAfter ? "true" : "false");
00512     Write(");\n");
00513     Flush();
00514   }
00515 
00516   return nsHTMLEditor::InsertTableCell(aNumber, aAfter);
00517 }
00518 
00519 
00520 NS_IMETHODIMP
00521 nsHTMLEditorLog:: InsertTableColumn(PRInt32 aNumber, PRBool aAfter)
00522 {
00523   nsAutoHTMLEditorLogLock logLock(this);
00524 
00525   if (!mLocked && mFileStream)
00526   {
00527     Write("GetCurrentEditor().insertTableColumn(");
00528     WriteInt(aNumber);
00529     Write(", ");
00530     Write(aAfter ? "true" : "false");
00531     Write(");\n");
00532     Flush();
00533   }
00534 
00535   return nsHTMLEditor::InsertTableColumn(aNumber, aAfter);
00536 }
00537 
00538 
00539 NS_IMETHODIMP
00540 nsHTMLEditorLog:: InsertTableRow(PRInt32 aNumber, PRBool aAfter)
00541 {
00542   nsAutoHTMLEditorLogLock logLock(this);
00543 
00544   if (!mLocked && mFileStream)
00545   {
00546     Write("GetCurrentEditor().insertTableRow(");
00547     WriteInt(aNumber);
00548     Write(", ");
00549     Write(aAfter ? "true" : "false");
00550     Write(");\n");
00551     Flush();
00552   }
00553 
00554   return nsHTMLEditor::InsertTableRow(aNumber, aAfter);
00555 }
00556 
00557 NS_IMETHODIMP
00558 nsHTMLEditorLog:: DeleteTable()
00559 {
00560   nsAutoHTMLEditorLogLock logLock(this);
00561 
00562   if (!mLocked && mFileStream)
00563   {
00564     Write("GetCurrentEditor().deleteTable();\n");
00565     Flush();
00566   }
00567 
00568   return nsHTMLEditor::DeleteTable();
00569 }
00570 
00571 NS_IMETHODIMP
00572 nsHTMLEditorLog:: DeleteTableCell(PRInt32 aNumber)
00573 {
00574   nsAutoHTMLEditorLogLock logLock(this);
00575 
00576   if (!mLocked && mFileStream)
00577   {
00578     Write("GetCurrentEditor().deleteTableCell(");
00579     WriteInt(aNumber);
00580     Write(");\n");
00581     Flush();
00582   }
00583 
00584   return nsHTMLEditor::DeleteTableCell(aNumber);
00585 }
00586 
00587 NS_IMETHODIMP
00588 nsHTMLEditorLog:: DeleteTableCellContents()
00589 {
00590   nsAutoHTMLEditorLogLock logLock(this);
00591 
00592   if (!mLocked && mFileStream)
00593   {
00594     Write("GetCurrentEditor().deleteTableCellContents();\n");
00595     Flush();
00596   }
00597 
00598   return nsHTMLEditor::DeleteTableCellContents();
00599 }
00600 
00601 
00602 NS_IMETHODIMP
00603 nsHTMLEditorLog:: DeleteTableColumn(PRInt32 aNumber)
00604 {
00605   nsAutoHTMLEditorLogLock logLock(this);
00606 
00607   if (!mLocked && mFileStream)
00608   {
00609     Write("GetCurrentEditor().deleteTableColumn(");
00610     WriteInt(aNumber);
00611     Write(");\n");
00612     Flush();
00613   }
00614 
00615   return nsHTMLEditor::DeleteTableColumn(aNumber);
00616 }
00617 
00618 
00619 NS_IMETHODIMP
00620 nsHTMLEditorLog:: DeleteTableRow(PRInt32 aNumber)
00621 {
00622   nsAutoHTMLEditorLogLock logLock(this);
00623 
00624   if (!mLocked && mFileStream)
00625   {
00626     Write("GetCurrentEditor().deleteTableRow(");
00627     WriteInt(aNumber);
00628     Write(");\n");
00629     Flush();
00630   }
00631 
00632   return nsHTMLEditor::DeleteTableRow(aNumber);
00633 }
00634 
00635 NS_IMETHODIMP
00636 nsHTMLEditorLog:: JoinTableCells(PRBool aMergeNonContiguousContents)
00637 {
00638   nsAutoHTMLEditorLogLock logLock(this);
00639 
00640   if (!mLocked && mFileStream)
00641   {
00642     Write("GetCurrentEditor().joinTableCells(");
00643     Write(aMergeNonContiguousContents ? "true" : "false");
00644     Write(");\n");
00645     Flush();
00646   }
00647 
00648   return nsHTMLEditor::JoinTableCells(aMergeNonContiguousContents);
00649 }
00650 
00651 NS_IMETHODIMP
00652 nsHTMLEditorLog:: SplitTableCell()
00653 {
00654   nsAutoHTMLEditorLogLock logLock(this);
00655 
00656   if (!mLocked && mFileStream)
00657   {
00658     Write("GetCurrentEditor().splitTableCell();\n");
00659     Flush();
00660   }
00661 
00662   return nsHTMLEditor::SplitTableCell();
00663 }
00664 
00665 
00666 NS_IMETHODIMP
00667 nsHTMLEditorLog:: NormalizeTable(nsIDOMElement *aTable)
00668 {
00669   nsAutoHTMLEditorLogLock logLock(this);
00670 
00671   if (!mLocked && mFileStream)
00672   {
00673     nsCOMPtr<nsIDOMNode> node = do_QueryInterface(aTable);
00674     if (!node)
00675       return NS_ERROR_NULL_POINTER;
00676 
00677     PrintNode(node, 0);
00678     Write("GetCurrentEditor().normalizeTable(n0);\n");
00679     Flush();
00680   }
00681 
00682   return nsHTMLEditor::NormalizeTable(aTable);
00683 }
00684 
00685 NS_IMETHODIMP
00686 nsHTMLEditorLog::SwitchTableCellHeaderType(nsIDOMElement *aSourceCell, nsIDOMElement **aNewCell)
00687 {
00688   nsAutoHTMLEditorLogLock logLock(this);
00689 
00690   if (!mLocked && mFileStream)
00691   {
00692     nsCOMPtr<nsIDOMNode> node = do_QueryInterface(aSourceCell);
00693     if (!node)
00694       return NS_ERROR_NULL_POINTER;
00695 
00696     PrintNode(node, 0);
00697     Write("GetCurrentEditor().switchTableCellHeaderType(n0);\n");
00698     Flush();
00699   }
00700 
00701   return nsHTMLEditor::SwitchTableCellHeaderType(aSourceCell, aNewCell);
00702 }
00703 
00704 NS_IMETHODIMP
00705 nsHTMLEditorLog::MakeOrChangeList(const nsAString& aListType, PRBool entireList, const nsAString& aBulletType)
00706 {
00707   nsAutoHTMLEditorLogLock logLock(this);
00708 
00709   if (!mLocked && mFileStream)
00710   {
00711     PrintSelection();
00712 
00713     Write("GetCurrentEditor().makeOrChangeList(\"");
00714     PrintUnicode(aListType);
00715     Write("\", ");
00716     Write(entireList ? "true" : "false");
00717     Write(", \"");
00718     PrintUnicode(aBulletType);
00719     Write("\");\n");
00720     Flush();
00721   }
00722 
00723   return nsHTMLEditor::MakeOrChangeList(aListType, entireList, aBulletType);
00724 }
00725 
00726 NS_IMETHODIMP
00727 nsHTMLEditorLog::Indent(const nsAString& aIndent)
00728 {
00729   nsAutoHTMLEditorLogLock logLock(this);
00730 
00731   if (!mLocked && mFileStream)
00732   {
00733     PrintSelection();
00734 
00735     Write("GetCurrentEditor().indent(\"");
00736     PrintUnicode(aIndent);
00737     Write("\");\n");
00738     Flush();
00739   }
00740 
00741   return nsHTMLEditor::Indent(aIndent);
00742 }
00743 
00744 NS_IMETHODIMP
00745 nsHTMLEditorLog::Align(const nsAString& aAlign)
00746 {
00747   nsAutoHTMLEditorLogLock logLock(this);
00748 
00749   if (!mLocked && mFileStream)
00750   {
00751     PrintSelection();
00752 
00753     Write("GetCurrentEditor().align(\"");
00754     PrintUnicode(aAlign);
00755     Write("\");\n");
00756     Flush();
00757   }
00758 
00759   return nsHTMLEditor::Align(aAlign);
00760 }
00761 
00762 NS_IMETHODIMP
00763 nsHTMLEditorLog::InsertElementAtSelection(nsIDOMElement* aElement, PRBool aDeleteSelection)
00764 {
00765   nsAutoHTMLEditorLogLock logLock(this);
00766 
00767   if (!mLocked && mFileStream)
00768   {
00769     if (!aElement)
00770       return NS_ERROR_NULL_POINTER;
00771 
00772     nsCOMPtr<nsIDOMNode> node = do_QueryInterface(aElement);
00773 
00774     if (!node)
00775       return NS_ERROR_NULL_POINTER;
00776 
00777     PrintSelection();
00778     PrintNode(node, 0);
00779     Write("GetCurrentEditor().insertElementAtSelection(n0, ");
00780     Write(aDeleteSelection ? "true" : "false");
00781     Write(");\n");
00782     Flush();
00783   }
00784 
00785   return nsHTMLEditor::InsertElementAtSelection(aElement, aDeleteSelection);
00786 }
00787 
00788 NS_IMETHODIMP
00789 nsHTMLEditorLog::InsertLinkAroundSelection(nsIDOMElement* aAnchorElement)
00790 {
00791   nsAutoHTMLEditorLogLock logLock(this);
00792 
00793   if (!mLocked && mFileStream)
00794   {
00795     if (!aAnchorElement)
00796       return NS_ERROR_NULL_POINTER;
00797 
00798     nsCOMPtr<nsIDOMNode> node = do_QueryInterface(aAnchorElement);
00799 
00800     if (!node)
00801       return NS_ERROR_NULL_POINTER;
00802 
00803     PrintSelection();
00804     PrintNode(node, 0);
00805     Write("GetCurrentEditor().insertLinkAroundSelection(n0);\n");
00806     Flush();
00807   }
00808 
00809   return nsHTMLEditor::InsertLinkAroundSelection(aAnchorElement);
00810 }
00811 
00812 NS_IMETHODIMP
00813 nsHTMLEditorLog::SetDocumentTitle(const nsAString& aTitle)
00814 {
00815   nsAutoHTMLEditorLogLock logLock(this);
00816 
00817   if (!mLocked && mFileStream)
00818   {
00819     PrintSelection();
00820 
00821     Write("GetCurrentEditor().setDocumentTitle(\"");
00822     nsAutoString str(aTitle);
00823     PrintUnicode(str);
00824     Write("\");\n");
00825     Flush();
00826   }
00827 
00828   return nsHTMLEditor::SetDocumentTitle(aTitle);
00829 }
00830 
00831 NS_IMETHODIMP
00832 nsHTMLEditorLog::StartLogging(nsIFile *aLogFile)
00833 {
00834   nsresult result = NS_ERROR_FAILURE;
00835 
00836   if (!aLogFile)
00837     return NS_ERROR_NULL_POINTER;
00838 
00839   if (mFileStream)
00840   {
00841     result = StopLogging();
00842 
00843     if (NS_FAILED(result))
00844       return result;
00845   }
00846 
00847   result = NS_NewLocalFileOutputStream(getter_AddRefs(mFileStream), aLogFile);
00848   if (NS_FAILED(result)) return result;
00849 
00850   if (mTxnMgr)
00851   {
00852     mEditorTxnLog = new nsEditorTxnLog(this);
00853 
00854     if (mEditorTxnLog)
00855     {
00856       NS_ADDREF(mEditorTxnLog);
00857       mTxnMgr->AddListener(mEditorTxnLog);
00858     }
00859     else
00860       return NS_ERROR_OUT_OF_MEMORY;
00861   }
00862 
00863   return NS_OK;
00864 }
00865 
00866 NS_IMETHODIMP
00867 nsHTMLEditorLog::StopLogging()
00868 {
00869   if (mTxnMgr && mEditorTxnLog)
00870     mTxnMgr->RemoveListener(mEditorTxnLog);
00871 
00872   if (mEditorTxnLog)
00873   {
00874     NS_RELEASE(mEditorTxnLog);
00875     mEditorTxnLog = 0;
00876   }
00877 
00878   if (mFileStream)
00879   {
00880     mFileStream->Close();
00881     mFileStream = nsnull;
00882   }
00883 
00884   return NS_OK;
00885 }
00886 
00887 
00888 nsresult
00889 nsHTMLEditorLog::Write(const char *aBuffer)
00890 {
00891   nsresult result;
00892 
00893   if (!aBuffer)
00894     return NS_ERROR_NULL_POINTER;
00895 
00896   PRInt32 len = strlen(aBuffer);
00897 
00898   if (mFileStream)
00899   {
00900     PRUint32 retval;
00901 
00902     result = mFileStream->Write(aBuffer, len, &retval);
00903 
00904     if (NS_FAILED(result))
00905       return result;
00906 
00907 #ifdef VERY_SLOW
00908 
00909     result = mFileStream->Flush();
00910 
00911     if (NS_FAILED(result))
00912       return result;
00913 
00914 #endif // VERY_SLOW
00915   }
00916   else
00917     fwrite(aBuffer, 1, len, stdout);
00918 
00919   return NS_OK;
00920 }
00921 
00922 nsresult
00923 nsHTMLEditorLog::WriteInt(PRInt32 aInt)
00924 {
00925   char buf[256];
00926 
00927   PR_snprintf(buf, sizeof(buf), "%d", aInt);
00928 
00929   return Write(buf);
00930 }
00931 
00932 nsresult
00933 nsHTMLEditorLog::Flush()
00934 {
00935   nsresult result = NS_OK;
00936 
00937   if (mFileStream)
00938     result = mFileStream->Flush();
00939   else
00940     fflush(stdout);
00941 
00942   return result;
00943 }
00944 
00945 nsresult
00946 nsHTMLEditorLog::PrintUnicode(const nsAString &aString)
00947 {
00948   //const PRUnichar *uc = aString.get();
00949   char buf[10];
00950   nsReadingIterator <PRUnichar> beginIter,endIter;
00951   aString.BeginReading(beginIter);
00952   aString.EndReading(endIter);
00953   while(beginIter != endIter)
00954   {
00955     if (nsCRT::IsAsciiAlpha(*beginIter) || nsCRT::IsAsciiDigit(*beginIter) || *beginIter == ' ')
00956       PR_snprintf(buf, sizeof(buf), "%c", *beginIter);
00957     else
00958       PR_snprintf(buf, sizeof(buf), "\\u%.4x", *beginIter);
00959 
00960     nsresult result = Write(buf);
00961 
00962     if (NS_FAILED(result))
00963       return result;
00964     ++beginIter;
00965   }
00966 
00967   return NS_OK;
00968 }
00969 
00970 nsresult
00971 nsHTMLEditorLog::PrintSelection()
00972 {
00973   nsCOMPtr<nsISelection> selection;
00974   nsresult result;
00975   PRInt32 rangeCount;
00976 
00977   result = GetSelection(getter_AddRefs(selection));
00978 
00979   if (NS_FAILED(result))
00980     return result;
00981 
00982   result = selection->GetRangeCount(&rangeCount);
00983 
00984   if (NS_FAILED(result))
00985     return result;
00986 
00987   Write("selRanges = [ ");
00988 
00989   PRInt32 i, j;
00990   nsCOMPtr<nsIDOMRange> range;
00991   nsCOMPtr<nsIDOMNode> startNode;
00992   nsCOMPtr<nsIDOMNode> endNode;
00993   PRInt32 startOffset, endOffset;
00994 
00995   for (i = 0; i < rangeCount; i++)
00996   {
00997     result = selection->GetRangeAt(i, getter_AddRefs(range));
00998 
00999     if (NS_FAILED(result))
01000       return result;
01001     
01002     result = range->GetStartContainer(getter_AddRefs(startNode));
01003 
01004     if (NS_FAILED(result))
01005       return result;
01006 
01007     if (!startNode)
01008       return NS_ERROR_NULL_POINTER;
01009 
01010     result = range->GetStartOffset(&startOffset);
01011 
01012     if (NS_FAILED(result))
01013       return result;
01014 
01015     result = range->GetEndContainer(getter_AddRefs(endNode));
01016 
01017     if (NS_FAILED(result))
01018       return result;
01019 
01020     if (!endNode)
01021       return NS_ERROR_NULL_POINTER;
01022 
01023     result = range->GetEndOffset(&endOffset);
01024 
01025     if (NS_FAILED(result))
01026       return result;
01027 
01028     PRInt32 *offsetArray = 0;
01029     PRInt32 arrayLength = 0;
01030 
01031     result = GetNodeTreeOffsets(startNode, &offsetArray, &arrayLength);
01032 
01033     if (NS_FAILED(result))
01034       return result;
01035 
01036     if (i != 0)
01037       Write(",\n              ");
01038 
01039     Write("[ [[");
01040 
01041     for (j = 0; j < arrayLength; j++)
01042     {
01043       if (j != 0)
01044         Write(", ");
01045       WriteInt(offsetArray[j]);
01046     }
01047 
01048     Write("], ");
01049     WriteInt(startOffset);
01050     Write("], ");
01051 
01052     if (startNode != endNode)
01053     {
01054       delete []offsetArray;
01055       offsetArray = 0;
01056       arrayLength = 0;
01057 
01058       result = GetNodeTreeOffsets(endNode, &offsetArray, &arrayLength);
01059 
01060       if (NS_FAILED(result))
01061         return result;
01062     }
01063 
01064     Write("[[");
01065 
01066     for (j = 0; j < arrayLength; j++)
01067     {
01068       if (j != 0)
01069         Write(", ");
01070       WriteInt(offsetArray[j]);
01071     }
01072 
01073     delete []offsetArray;
01074 
01075     Write("], ");
01076     WriteInt(endOffset);
01077     Write("] ]");
01078   }
01079 
01080   Write(" ];\nEditorSetSelectionFromOffsets(selRanges);\n");
01081 
01082   Flush();
01083 
01084   return NS_OK;
01085 }
01086 
01087 nsresult
01088 nsHTMLEditorLog::PrintElementNode(nsIDOMNode *aNode, PRInt32 aDepth)
01089 {
01090   nsresult result;
01091   nsAutoString tag, name, value;
01092   nsCOMPtr<nsIDOMElement> ele = do_QueryInterface(aNode);
01093   nsCOMPtr<nsIDOMNamedNodeMap> map;
01094 
01095   if (!ele)
01096     return NS_ERROR_NULL_POINTER;
01097 
01098   result = ele->GetTagName(tag);
01099 
01100   if (NS_FAILED(result))
01101     return result;
01102 
01103   Write("n");
01104   WriteInt(aDepth);
01105   Write(" = GetCurrentEditor().editorDocument.createElement(\"");
01106   PrintUnicode(tag);
01107   Write("\");\n");
01108 
01109   result = aNode->GetAttributes(getter_AddRefs(map));
01110 
01111   if (NS_FAILED(result))
01112     return result;
01113 
01114   if (!map)
01115     return NS_ERROR_NULL_POINTER;
01116 
01117   PRUint32 i, len;
01118   nsCOMPtr<nsIDOMNode> attr;
01119 
01120   result = map->GetLength(&len);
01121 
01122   if (NS_FAILED(result))
01123     return result;
01124 
01125   for (i = 0; i < len; i++)
01126   {
01127     result = map->Item(i, getter_AddRefs(attr));
01128 
01129     if (NS_FAILED(result))
01130       return result;
01131 
01132     if (!attr)
01133       return NS_ERROR_NULL_POINTER;
01134 
01135     result = PrintAttributeNode(attr, aDepth);
01136 
01137     if (NS_FAILED(result))
01138       return result;
01139   }
01140 
01141   result = PrintNodeChildren(aNode, aDepth);
01142 
01143   return result;
01144 }
01145 
01146 nsresult
01147 nsHTMLEditorLog::PrintAttributeNode(nsIDOMNode *aNode, PRInt32 aDepth)
01148 {
01149   nsresult result;
01150   nsCOMPtr<nsIDOMAttr> attr = do_QueryInterface(aNode);
01151 
01152   if (!attr)
01153     return NS_ERROR_NULL_POINTER;
01154 
01155   nsAutoString str;
01156 
01157   result = attr->GetName(str);
01158 
01159   if (NS_FAILED(result))
01160     return result;
01161 
01162   Write("a");
01163   WriteInt(aDepth);
01164   Write(" = GetCurrentEditor().editorDocument.createAttribute(\"");
01165   PrintUnicode(str);
01166   Write("\");\n");
01167 
01168   result = attr->GetValue(str);
01169 
01170   if (NS_FAILED(result))
01171     return result;
01172 
01173   Write("a");
01174   WriteInt(aDepth);
01175   Write(".value = \"");
01176   PrintUnicode(str);
01177   Write("\";\n");
01178   
01179   Write("n");
01180   WriteInt(aDepth);
01181   Write(".setAttributeNode(a");
01182   WriteInt(aDepth);
01183   Write(");\n");
01184 
01185   return NS_OK;
01186 }
01187 
01188 nsresult
01189 nsHTMLEditorLog::PrintNodeChildren(nsIDOMNode *aNode, PRInt32 aDepth)
01190 {
01191   nsresult result;
01192 
01193   if (!aNode)
01194     return NS_ERROR_NULL_POINTER;
01195 
01196   nsCOMPtr<nsIDOMNodeList> list;
01197 
01198   result = aNode->GetChildNodes(getter_AddRefs(list));
01199   
01200   if (NS_FAILED(result))
01201     return result;
01202 
01203   if (!list)
01204   {
01205     // Must not have any children!
01206     return NS_OK;
01207   }
01208 
01209   PRUint32 i, len;
01210   nsCOMPtr<nsIDOMNode> node;
01211 
01212   result = list->GetLength(&len);
01213 
01214   if (NS_FAILED(result))
01215     return result;
01216 
01217   for (i = 0; i < len; i++)
01218   {
01219     result = list->Item(i, getter_AddRefs(node));
01220 
01221     if (NS_FAILED(result))
01222       return result;
01223 
01224     result = PrintNode(node, aDepth + 1);
01225 
01226     if (NS_FAILED(result))
01227       return result;
01228 
01229     Write("n");
01230     WriteInt(aDepth);
01231     Write(".appendChild(n");
01232     WriteInt(aDepth+1);
01233     Write(");\n");
01234   }
01235 
01236   return NS_OK;
01237 }
01238 
01239 nsresult
01240 nsHTMLEditorLog::PrintTextNode(nsIDOMNode *aNode, PRInt32 aDepth)
01241 {
01242   nsresult result;
01243 
01244   nsCOMPtr<nsIDOMCharacterData> cd = do_QueryInterface(aNode);
01245 
01246   if (!cd)
01247     return NS_ERROR_NULL_POINTER;
01248 
01249   nsAutoString str;
01250 
01251   result = cd->GetData(str);
01252 
01253   if (NS_FAILED(result))
01254     return result;
01255 
01256   Write("n");
01257   WriteInt(aDepth);
01258   Write(" = GetCurrentEditor().editorDocument.createTextNode(\"");
01259   PrintUnicode(str);
01260   Write("\");\n");
01261 
01262   return NS_OK;
01263 }
01264 
01265 nsresult
01266 nsHTMLEditorLog::PrintNode(nsIDOMNode *aNode, PRInt32 aDepth)
01267 {
01268   nsresult result = NS_OK;
01269 
01270   if (!aNode)
01271     return NS_ERROR_NULL_POINTER;
01272 
01273   PRUint16 nodeType;
01274   
01275   result = aNode->GetNodeType(&nodeType);
01276 
01277   switch (nodeType)
01278   {
01279     case nsIDOMNode::ELEMENT_NODE:
01280       result = PrintElementNode(aNode, aDepth);
01281       break;
01282     case nsIDOMNode::TEXT_NODE:
01283       result = PrintTextNode(aNode, aDepth);
01284       break;
01285     case nsIDOMNode::ATTRIBUTE_NODE:
01286       result = PrintAttributeNode(aNode, aDepth);
01287       break;
01288     case nsIDOMNode::CDATA_SECTION_NODE:
01289     case nsIDOMNode::ENTITY_REFERENCE_NODE:
01290     case nsIDOMNode::ENTITY_NODE:
01291     case nsIDOMNode::PROCESSING_INSTRUCTION_NODE:
01292     case nsIDOMNode::COMMENT_NODE:
01293     case nsIDOMNode::DOCUMENT_NODE:
01294     case nsIDOMNode::DOCUMENT_TYPE_NODE:
01295     case nsIDOMNode::DOCUMENT_FRAGMENT_NODE:
01296     case nsIDOMNode::NOTATION_NODE:
01297     default:
01298       break;
01299   }
01300 
01301   Flush();
01302 
01303   return result;
01304 }
01305 
01306 nsresult
01307 nsHTMLEditorLog::GetNodeTreeOffsets(nsIDOMNode *aNode, PRInt32 **aResult, PRInt32 *aLength)
01308 {
01309   nsresult result;
01310 
01311   if (!aNode || !aResult || !aLength)
01312     return NS_ERROR_NULL_POINTER;
01313 
01314   *aResult = 0;
01315   *aLength = 0;
01316 
01317   nsIDOMNode *parent = aNode;
01318   PRInt32 i = 0;
01319 
01320   // Count the number of parent nodes above aNode.
01321 
01322   while (parent)
01323   {
01324     result = parent->GetParentNode(&parent);
01325 
01326     if (NS_FAILED(result))
01327       return result;
01328 
01329     if (parent)
01330       ++i;
01331   }
01332 
01333   // Allocate an array big enough to hold all the offsets.
01334 
01335   *aResult = new PRInt32[i];
01336 
01337   if (!aResult)
01338     return NS_ERROR_OUT_OF_MEMORY;
01339 
01340   *aLength = i;
01341 
01342   while (aNode && i > 0)
01343   {
01344     PRInt32 offset = 0;
01345 
01346     result = aNode->GetParentNode(&parent);
01347 
01348     if (NS_FAILED(result))
01349     {
01350       delete [](*aResult);
01351       *aResult = 0;
01352       *aLength = 0;
01353       return result;
01354     }
01355 
01356     while (aNode)
01357     {
01358       result = aNode->GetPreviousSibling(&aNode);
01359 
01360       if (NS_FAILED(result))
01361       {
01362         delete [](*aResult);
01363         *aResult = 0;
01364         *aLength = 0;
01365         return result;
01366       }
01367 
01368       if (aNode)
01369         ++offset;
01370     }
01371 
01372     (*aResult)[--i] = offset;
01373     aNode = parent;
01374   }
01375 
01376   return NS_OK;
01377 }
01378 
01379 nsresult
01380 nsHTMLEditorLog::Lock()
01381 {
01382   mLocked++;
01383   return NS_OK;
01384 }
01385 
01386 nsresult
01387 nsHTMLEditorLog::Unlock()
01388 {
01389   --mLocked;
01390   return NS_OK;
01391 }
01392 
01393 #ifdef NEVER_ENABLE_THIS_JAVASCRIPT
01394 
01395 function EditorGetNodeAtOffsets(offsets)
01396 {
01397   var node = null;
01398   var i;
01399 
01400   node = GetCurrentEditor().editorDocument;
01401 
01402   for (i = 0; i < offsets.length; i++)
01403   {
01404     node = node.childNodes[offsets[i]];
01405   }
01406 
01407   return node;
01408 }
01409 
01410 function EditorSetSelectionFromOffsets(selRanges)
01411 {
01412   var rangeArr, start, end, i, node, offset;
01413   var selection = GetCurrentEditor().editorSelection;
01414 
01415   selection.clearSelection();
01416 
01417   for (i = 0; i < selRanges.length; i++)
01418   {
01419     rangeArr = selRanges[i];
01420     start    = rangeArr[0];
01421     end      = rangeArr[1];
01422 
01423     var range = GetCurrentEditor().editorDocument.createRange();
01424 
01425     node   = EditorGetNodeAtOffsets(start[0]);
01426     offset = start[1];
01427 
01428     range.setStart(node, offset);
01429 
01430     node   = EditorGetNodeAtOffsets(end[0]);
01431     offset = end[1];
01432 
01433     range.setEnd(node, offset);
01434 
01435     selection.addRange(range);
01436   }
01437 }
01438 
01439 #endif