diff --git a/mozilla/content/base/public/nsIDocumentEncoder.h b/mozilla/content/base/public/nsIDocumentEncoder.h index d9c841fa18e..e3dda078344 100644 --- a/mozilla/content/base/public/nsIDocumentEncoder.h +++ b/mozilla/content/base/public/nsIDocumentEncoder.h @@ -110,6 +110,7 @@ public: NS_IMETHOD SubstituteURL(const nsString& aOriginal, const nsString& aReplacement) = 0; NS_IMETHOD PrettyPrint(PRBool aYes) = 0; + NS_IMETHOD SetWrapColumn(PRUint32 aWC) = 0; }; @@ -123,6 +124,7 @@ public: // Get embedded objects -- images, links, etc. // NOTE: we may want to use an enumerator NS_IMETHOD PrettyPrint(PRBool aYes) = 0; + NS_IMETHOD SetWrapColumn(PRUint32 aWC) = 0; }; diff --git a/mozilla/content/base/src/nsDocumentEncoder.cpp b/mozilla/content/base/src/nsDocumentEncoder.cpp index 351931eb281..4804728f91f 100644 --- a/mozilla/content/base/src/nsDocumentEncoder.cpp +++ b/mozilla/content/base/src/nsDocumentEncoder.cpp @@ -64,6 +64,7 @@ public: NS_IMETHOD SubstituteURL(const nsString& aOriginal, const nsString& aReplacement); NS_IMETHOD PrettyPrint(PRBool aYesNO); + NS_IMETHOD SetWrapColumn(PRUint32 aWC); private: nsIDocument* mDocument; @@ -283,7 +284,13 @@ nsHTMLEncoder::SubstituteURL(const nsString& aOriginal, const nsString& aReplace } NS_IMETHODIMP -nsHTMLEncoder::PrettyPrint(PRBool aYes) +nsHTMLEncoder::PrettyPrint(PRBool) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsHTMLEncoder::SetWrapColumn(PRUint32) { return NS_ERROR_NOT_IMPLEMENTED; } @@ -319,6 +326,7 @@ public: NS_IMETHOD EncodeToString(nsString& aOutputString); NS_IMETHOD PrettyPrint(PRBool aYesNO); + NS_IMETHOD SetWrapColumn(PRUint32 aWC); private: nsIDocument* mDocument; @@ -327,6 +335,7 @@ private: nsString mMimeType; nsString mCharset; PRBool mPrettyPrint; + PRUint32 mWrapColumn; }; @@ -393,6 +402,13 @@ nsTextEncoder::PrettyPrint(PRBool aYes) return NS_OK; } +NS_IMETHODIMP +nsTextEncoder::SetWrapColumn(PRUint32 aWC) +{ + mWrapColumn = aWC; + return NS_OK; +} + NS_IMETHODIMP nsTextEncoder::SetSelection(nsIDOMSelection* aSelection) { @@ -451,7 +467,7 @@ nsTextEncoder::EncodeToString(nsString& aOutputString) if (NS_SUCCEEDED(rv)) { parser->RegisterDTD(dtd); - parser->Parse(buffer, 0, "text/xif",PR_FALSE,PR_TRUE); + parser->Parse(buffer, 0, "text/xif", PR_FALSE,PR_TRUE); } NS_IF_RELEASE(dtd); NS_IF_RELEASE(sink); @@ -499,7 +515,8 @@ nsTextEncoder::EncodeToStream(nsIOutputStream* aStream) if (NS_OK == rv) { nsIHTMLContentSink* sink = nsnull; - rv = NS_New_HTMLToTXT_SinkStream(&sink,aStream,charset,mPrettyPrint); + rv = NS_New_HTMLToTXT_SinkStream(&sink, aStream, charset, + mWrapColumn, mPrettyPrint); if (sink && NS_SUCCEEDED(rv)) { diff --git a/mozilla/editor/base/nsEditorEventListeners.cpp b/mozilla/editor/base/nsEditorEventListeners.cpp index c8fa6f85173..d606b7db660 100644 --- a/mozilla/editor/base/nsEditorEventListeners.cpp +++ b/mozilla/editor/base/nsEditorEventListeners.cpp @@ -413,7 +413,7 @@ nsTextEditorKeyListener::ProcessShortCutKeys(nsIDOMEvent* aKeyEvent, PRBool& aPr { printf("Getting number of columns\n"); aProcessed=PR_TRUE; - PRInt32 wrap; + PRUint32 wrap; if (NS_SUCCEEDED(mEditor->GetBodyWrapWidth(&wrap))) printf("Currently wrapping to %d\n", wrap); else @@ -426,7 +426,7 @@ nsTextEditorKeyListener::ProcessShortCutKeys(nsIDOMEvent* aKeyEvent, PRBool& aPr if (PR_TRUE==altKey) { aProcessed=PR_TRUE; - PRInt32 wrap; + PRUint32 wrap; if (!NS_SUCCEEDED(mEditor->GetBodyWrapWidth(&wrap))) { printf("GetBodyWrapWidth returned an error\n"); @@ -447,7 +447,7 @@ nsTextEditorKeyListener::ProcessShortCutKeys(nsIDOMEvent* aKeyEvent, PRBool& aPr if (PR_TRUE==altKey) { aProcessed=PR_TRUE; - PRInt32 wrap; + PRUint32 wrap; if (!NS_SUCCEEDED(mEditor->GetBodyWrapWidth(&wrap))) { printf("GetBodyWrapWidth returned an error\n"); diff --git a/mozilla/editor/base/nsEditorShell.cpp b/mozilla/editor/base/nsEditorShell.cpp index 2e448e05e25..529c535ea30 100644 --- a/mozilla/editor/base/nsEditorShell.cpp +++ b/mozilla/editor/base/nsEditorShell.cpp @@ -1382,6 +1382,36 @@ nsEditorShell::InsertText(const PRUnichar *textToInsert) return err; } +NS_IMETHODIMP +nsEditorShell::InsertSource(const PRUnichar *aSourceToInsert) +{ + nsresult err = NS_NOINTERFACE; + + nsAutoString sourceToInsert(aSourceToInsert); + + switch (mEditorType) + { + case ePlainTextEditorType: + { + nsCOMPtr textEditor = do_QueryInterface(mEditor); + if (textEditor) + err = textEditor->InsertText(sourceToInsert); + } + break; + case eHTMLTextEditorType: + { + nsCOMPtr htmlEditor = do_QueryInterface(mEditor); + if (htmlEditor) + err = htmlEditor->InsertHTML(sourceToInsert); + } + break; + default: + err = NS_NOINTERFACE; + } + + return err; +} + NS_IMETHODIMP nsEditorShell::InsertBreak() { @@ -1592,7 +1622,12 @@ nsEditorShell::GetWrapColumn(PRInt32* aWrapColumn) { nsCOMPtr textEditor = do_QueryInterface(mEditor); if (textEditor) - err = textEditor->GetBodyWrapWidth(aWrapColumn); + { + PRUint32 wc; + err = textEditor->GetBodyWrapWidth(&wc); + if (NS_SUCCEEDED(err)) + *aWrapColumn = (PRInt32)wc; + } } break; default: diff --git a/mozilla/editor/base/nsEditorShell.h b/mozilla/editor/base/nsEditorShell.h index b728d51ac97..9401c904d22 100644 --- a/mozilla/editor/base/nsEditorShell.h +++ b/mozilla/editor/base/nsEditorShell.h @@ -128,6 +128,7 @@ class nsEditorShell : public nsIEditorShell, /* void InsertText (in wstring textToInsert); */ NS_IMETHOD InsertText(const PRUnichar *textToInsert); + NS_IMETHOD InsertSource(const PRUnichar *sourceToInsert); NS_IMETHOD InsertBreak(); NS_IMETHOD InsertLink(); NS_IMETHOD InsertImage(); diff --git a/mozilla/editor/base/nsTextEditor.cpp b/mozilla/editor/base/nsTextEditor.cpp index 8664a056880..303f85fdaac 100644 --- a/mozilla/editor/base/nsTextEditor.cpp +++ b/mozilla/editor/base/nsTextEditor.cpp @@ -1440,7 +1440,7 @@ findPreElement(nsIDOMDocument* domdoc) // Get the wrap width for the first PRE tag in the document. // If no PRE tag, throw an error. // -NS_IMETHODIMP nsTextEditor::GetBodyWrapWidth(PRInt32 *aWrapColumn) +NS_IMETHODIMP nsTextEditor::GetBodyWrapWidth(PRUint32 *aWrapColumn) { nsresult res; @@ -1500,12 +1500,11 @@ NS_IMETHODIMP nsTextEditor::GetBodyWrapWidth(PRInt32 *aWrapColumn) // (Eventually want to search for more than one in case there are // interspersed quoted text blocks.) // -NS_IMETHODIMP nsTextEditor::SetBodyWrapWidth(PRInt32 aWrapColumn) +NS_IMETHODIMP nsTextEditor::SetBodyWrapWidth(PRUint32 aWrapColumn) { nsresult res; - if (! aWrapColumn) - return NS_ERROR_NULL_POINTER; + mWrapColumn = aWrapColumn; nsCOMPtr domdoc; nsEditor::GetDocument(getter_AddRefs(domdoc)); @@ -1591,6 +1590,7 @@ NS_IMETHODIMP nsTextEditor::OutputTextToString(nsString& aOutputString, PRBool a // Try to turn on pretty printing, but don't panic if it doesn't work: (void)encoder->PrettyPrint(PR_TRUE); + (void)encoder->SetWrapColumn(mWrapColumn); rv = encoder->EncodeToString(aOutputString); } @@ -1689,6 +1689,7 @@ NS_IMETHODIMP nsTextEditor::OutputTextToStream(nsIOutputStream* aOutputStream, n // Try to turn on pretty printing, but don't panic if it doesn't work: (void)encoder->PrettyPrint(PR_TRUE); + (void)encoder->SetWrapColumn(mWrapColumn); return encoder->EncodeToStream(aOutputStream); } diff --git a/mozilla/editor/base/nsTextEditor.h b/mozilla/editor/base/nsTextEditor.h index 44c6b5846cc..37246216945 100644 --- a/mozilla/editor/base/nsTextEditor.h +++ b/mozilla/editor/base/nsTextEditor.h @@ -118,8 +118,8 @@ public: NS_IMETHOD OutputHTMLToStream(nsIOutputStream* aOutputStream, nsString* aCharsetOverride, PRBool aSelectionOnly); // Plain text wrapping control - NS_IMETHOD GetBodyWrapWidth(PRInt32 *aWrapColumn); - NS_IMETHOD SetBodyWrapWidth(PRInt32 aWrapColumn); + NS_IMETHOD GetBodyWrapWidth(PRUint32 *aWrapColumn); + NS_IMETHOD SetBodyWrapWidth(PRUint32 aWrapColumn); // Logging methods @@ -304,6 +304,7 @@ protected: nsCOMPtr mFocusListenerP; PRBool mIsComposing; PRInt32 mMaxTextLength; + PRUint32 mWrapColumn; // friends friend class nsTextEditRules; diff --git a/mozilla/editor/composer/src/nsEditorShell.cpp b/mozilla/editor/composer/src/nsEditorShell.cpp index 2e448e05e25..529c535ea30 100644 --- a/mozilla/editor/composer/src/nsEditorShell.cpp +++ b/mozilla/editor/composer/src/nsEditorShell.cpp @@ -1382,6 +1382,36 @@ nsEditorShell::InsertText(const PRUnichar *textToInsert) return err; } +NS_IMETHODIMP +nsEditorShell::InsertSource(const PRUnichar *aSourceToInsert) +{ + nsresult err = NS_NOINTERFACE; + + nsAutoString sourceToInsert(aSourceToInsert); + + switch (mEditorType) + { + case ePlainTextEditorType: + { + nsCOMPtr textEditor = do_QueryInterface(mEditor); + if (textEditor) + err = textEditor->InsertText(sourceToInsert); + } + break; + case eHTMLTextEditorType: + { + nsCOMPtr htmlEditor = do_QueryInterface(mEditor); + if (htmlEditor) + err = htmlEditor->InsertHTML(sourceToInsert); + } + break; + default: + err = NS_NOINTERFACE; + } + + return err; +} + NS_IMETHODIMP nsEditorShell::InsertBreak() { @@ -1592,7 +1622,12 @@ nsEditorShell::GetWrapColumn(PRInt32* aWrapColumn) { nsCOMPtr textEditor = do_QueryInterface(mEditor); if (textEditor) - err = textEditor->GetBodyWrapWidth(aWrapColumn); + { + PRUint32 wc; + err = textEditor->GetBodyWrapWidth(&wc); + if (NS_SUCCEEDED(err)) + *aWrapColumn = (PRInt32)wc; + } } break; default: diff --git a/mozilla/editor/composer/src/nsEditorShell.h b/mozilla/editor/composer/src/nsEditorShell.h index b728d51ac97..9401c904d22 100644 --- a/mozilla/editor/composer/src/nsEditorShell.h +++ b/mozilla/editor/composer/src/nsEditorShell.h @@ -128,6 +128,7 @@ class nsEditorShell : public nsIEditorShell, /* void InsertText (in wstring textToInsert); */ NS_IMETHOD InsertText(const PRUnichar *textToInsert); + NS_IMETHOD InsertSource(const PRUnichar *sourceToInsert); NS_IMETHOD InsertBreak(); NS_IMETHOD InsertLink(); NS_IMETHOD InsertImage(); diff --git a/mozilla/editor/idl/nsIEditorShell.idl b/mozilla/editor/idl/nsIEditorShell.idl index a6e86bbba92..fc038d10ccf 100644 --- a/mozilla/editor/idl/nsIEditorShell.idl +++ b/mozilla/editor/idl/nsIEditorShell.idl @@ -84,6 +84,7 @@ interface nsIEditorShell : nsISupports /* Structure change */ void InsertText(in wstring textToInsert); + void InsertSource(in wstring textToInsert); void InsertBreak(); void InsertLink(); diff --git a/mozilla/editor/libeditor/text/nsEditorEventListeners.cpp b/mozilla/editor/libeditor/text/nsEditorEventListeners.cpp index c8fa6f85173..d606b7db660 100644 --- a/mozilla/editor/libeditor/text/nsEditorEventListeners.cpp +++ b/mozilla/editor/libeditor/text/nsEditorEventListeners.cpp @@ -413,7 +413,7 @@ nsTextEditorKeyListener::ProcessShortCutKeys(nsIDOMEvent* aKeyEvent, PRBool& aPr { printf("Getting number of columns\n"); aProcessed=PR_TRUE; - PRInt32 wrap; + PRUint32 wrap; if (NS_SUCCEEDED(mEditor->GetBodyWrapWidth(&wrap))) printf("Currently wrapping to %d\n", wrap); else @@ -426,7 +426,7 @@ nsTextEditorKeyListener::ProcessShortCutKeys(nsIDOMEvent* aKeyEvent, PRBool& aPr if (PR_TRUE==altKey) { aProcessed=PR_TRUE; - PRInt32 wrap; + PRUint32 wrap; if (!NS_SUCCEEDED(mEditor->GetBodyWrapWidth(&wrap))) { printf("GetBodyWrapWidth returned an error\n"); @@ -447,7 +447,7 @@ nsTextEditorKeyListener::ProcessShortCutKeys(nsIDOMEvent* aKeyEvent, PRBool& aPr if (PR_TRUE==altKey) { aProcessed=PR_TRUE; - PRInt32 wrap; + PRUint32 wrap; if (!NS_SUCCEEDED(mEditor->GetBodyWrapWidth(&wrap))) { printf("GetBodyWrapWidth returned an error\n"); diff --git a/mozilla/editor/public/nsITextEditor.h b/mozilla/editor/public/nsITextEditor.h index b1a01892abe..3cda7ccecd1 100644 --- a/mozilla/editor/public/nsITextEditor.h +++ b/mozilla/editor/public/nsITextEditor.h @@ -348,8 +348,8 @@ public: * -1 = no wrap at all * */ - NS_IMETHOD GetBodyWrapWidth(PRInt32 *aWrapColumn)=0; - NS_IMETHOD SetBodyWrapWidth(PRInt32 aWrapColumn)=0; + NS_IMETHOD GetBodyWrapWidth(PRUint32 *aWrapColumn)=0; + NS_IMETHOD SetBodyWrapWidth(PRUint32 aWrapColumn)=0; // Miscellaneous Methods /* diff --git a/mozilla/editor/ui/composer/content/EditorAppShell.xul b/mozilla/editor/ui/composer/content/EditorAppShell.xul index 492d1c2fda4..9675d2fa4a1 100644 --- a/mozilla/editor/ui/composer/content/EditorAppShell.xul +++ b/mozilla/editor/ui/composer/content/EditorAppShell.xul @@ -194,7 +194,7 @@ - + diff --git a/mozilla/editor/ui/composer/content/EditorCommands.js b/mozilla/editor/ui/composer/content/EditorCommands.js index eb258dcf33b..2b64fab25ef 100644 --- a/mozilla/editor/ui/composer/content/EditorCommands.js +++ b/mozilla/editor/ui/composer/content/EditorCommands.js @@ -317,11 +317,18 @@ function EditorGetHTML() function EditorInsertText() { if (window.editorShell) { - dump("Inserting text\n"); window.editorShell.InsertText("Once more into the breach, dear friends.\n"); } } +function EditorInsertHTML() +{ + if (window.editorShell) { + window.openDialog("chrome://editordlgs/content/EdInsSrc.xul", + "InsSrcDlg", "chrome", ""); + } +} + function EditorInsertLink() { if (window.editorShell) { diff --git a/mozilla/editor/ui/dialogs/content/EdInsSrc.js b/mozilla/editor/ui/dialogs/content/EdInsSrc.js new file mode 100644 index 00000000000..170228f2e03 --- /dev/null +++ b/mozilla/editor/ui/dialogs/content/EdInsSrc.js @@ -0,0 +1,64 @@ +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +/* Insert Source HTML dialog */ + +var editorShell; +var dialog; + +// dialog initialization code +function Startup() +{ + // get the editor shell from the parent window + editorShell = window.opener.editorShell; + editorShell = editorShell.QueryInterface(Components.interfaces.nsIEditorShell); + + if (!editorShell) { + dump("editorShell not found!!!\n"); + window.close(); + return; + } + + // Create dialog object to store controls for easy access + dialog = new Object; + dialog.srcInput = document.getElementById("srcInput"); + + // Kinda clunky: Message was wrapped in a

, + // so actual message is a child text node + dialog.srcMessage = (document.getElementById("srcMessage")).firstChild; + + if (null == dialog.srcInput || + null == dialog.srcMessage ) + { + dump("Not all dialog controls were found!!!\n"); + } + + // Set initial focus + + dialog.srcInput.focus(); +} + +function onOK() +{ + if (dialog.srcInput.value != "") + editorShell.InsertSource(dialog.srcInput.value); + else dump("Null value -- not inserting\n"); + + window.close(); +} + diff --git a/mozilla/editor/ui/dialogs/content/EdInsSrc.xul b/mozilla/editor/ui/dialogs/content/EdInsSrc.xul new file mode 100644 index 00000000000..3d793102ca7 --- /dev/null +++ b/mozilla/editor/ui/dialogs/content/EdInsSrc.xul @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + +
+
HTML Source +

Enter HTML source to insert:

+ + +
+
+ + +
+
diff --git a/mozilla/editor/ui/dialogs/content/Makefile.in b/mozilla/editor/ui/dialogs/content/Makefile.in index 649b69fc24e..3acebc351fd 100644 --- a/mozilla/editor/ui/dialogs/content/Makefile.in +++ b/mozilla/editor/ui/dialogs/content/Makefile.in @@ -32,6 +32,8 @@ EXPORT_RESOURCE_CONTENT = \ $(srcdir)/EdLinkProps.js \ $(srcdir)/EdImageProps.xul \ $(srcdir)/EdImageProps.js \ + $(srcdir)/EdInsSrc.xul \ + $(srcdir)/EdInsSrc.js \ $(srcdir)/EdHLineProps.xul \ $(srcdir)/EdHLineProps.js \ $(srcdir)/EdSpellCheck.xul \ diff --git a/mozilla/htmlparser/src/nsHTMLToTXTSinkStream.cpp b/mozilla/htmlparser/src/nsHTMLToTXTSinkStream.cpp index e719032ca09..9d6c95957d5 100644 --- a/mozilla/htmlparser/src/nsHTMLToTXTSinkStream.cpp +++ b/mozilla/htmlparser/src/nsHTMLToTXTSinkStream.cpp @@ -34,6 +34,7 @@ #include "nsIParser.h" #include "nsHTMLEntities.h" #include "nsXIFDTD.h" +#include "prprf.h" // For PR_snprintf() #include "nsIUnicodeEncoder.h" #include "nsICharsetAlias.h" @@ -158,6 +159,7 @@ NS_HTMLPARS nsresult NS_New_HTMLToTXT_SinkStream(nsIHTMLContentSink** aInstancePtrResult, nsIOutputStream* aStream, const nsString* aCharsetOverride, + PRUint32 aWrapColumn, PRBool aPrettyPrint) { NS_ASSERTION(aStream != nsnull, "a valid stream is required"); @@ -165,6 +167,7 @@ NS_New_HTMLToTXT_SinkStream(nsIHTMLContentSink** aInstancePtrResult, if (nsnull == it) { return NS_ERROR_OUT_OF_MEMORY; } + it->SetWrapColumn(aWrapColumn); it->DoPrettyPrint(aPrettyPrint); if (aCharsetOverride != nsnull) it->SetCharsetOverride(aCharsetOverride); @@ -180,19 +183,25 @@ NS_New_HTMLToTXT_SinkStream(nsIHTMLContentSink** aInstancePtrResult, */ NS_HTMLPARS nsresult NS_New_HTMLToTXT_SinkStream(nsIHTMLContentSink** aInstancePtrResult, - nsString* aString, PRBool aPrettyPrint) + nsString* aString, + PRUint32 aWrapColumn, + PRBool aPrettyPrint) { NS_ASSERTION(aString != nsnull, "a valid stream is required"); nsHTMLToTXTSinkStream* it = new nsHTMLToTXTSinkStream(nsnull, aString); if (nsnull == it) { return NS_ERROR_OUT_OF_MEMORY; } + it->SetWrapColumn(aWrapColumn); it->DoPrettyPrint(aPrettyPrint); nsString ucs2("ucs2"); it->SetCharsetOverride(&ucs2); return it->QueryInterface(kIHTMLContentSinkIID, (void **)aInstancePtrResult); } +// Someday may want to make this non-const: +static const PRUint32 TagStackSize = 500; +static const PRUint32 OLStackSize = 100; /** * Construct a content sink stream. @@ -217,6 +226,14 @@ nsHTMLToTXTSinkStream::nsHTMLToTXTSinkStream(nsIOutputStream* aStream, mPrettyPrint = PR_FALSE; mPreformatted = PR_FALSE; mWrapColumn = 72; // XXX magic number, obviously needs to be settable + + // initialize the tag stack to zero: + mTagStack = new nsHTMLTag[TagStackSize]; + mTagStackIndex = 0; + + // initialize the OL stack, where numbers for ordered lists are kept: + mOLStack = new PRInt32[OLStackSize]; + mOLStackIndex = 0; } @@ -229,16 +246,11 @@ nsHTMLToTXTSinkStream::nsHTMLToTXTSinkStream(nsIOutputStream* aStream, nsHTMLToTXTSinkStream::~nsHTMLToTXTSinkStream() { delete [] mBuffer; + delete[] mTagStack; + delete[] mOLStack; NS_IF_RELEASE(mUnicodeEncoder); } -NS_IMETHODIMP -nsHTMLToTXTSinkStream::DoPrettyPrint(PRBool aDoPrettyPrint) -{ - mPrettyPrint = aDoPrettyPrint; - return NS_OK; -} - /** * * @update gpk04/30/99 @@ -627,14 +639,42 @@ nsHTMLToTXTSinkStream::OpenContainer(const nsIParserNode& aNode) } if (type == eHTMLTag_body) + { mDoOutput = PR_TRUE; + return NS_OK; + } + if (!mDoOutput) + return NS_OK; - else if (mDoOutput && type == eHTMLTag_li) + if (mTagStackIndex < TagStackSize) + mTagStack[mTagStackIndex++] = type; + + if (type == eHTMLTag_ol) + { + if (mOLStackIndex < OLStackSize) + mOLStack[mOLStackIndex++] = 1; // XXX should get it from the node! + } + + if (type == eHTMLTag_li) { nsString temp("*"); + if (mTagStackIndex > 1 && mTagStack[mTagStackIndex-2] == eHTMLTag_ol) + { + if (mOLStackIndex > 0) + { + // This is what nsBulletFrame does for OLs: + char cbuf[40]; + PR_snprintf(cbuf, sizeof(cbuf), "%ld.", (mOLStack[mOLStackIndex-1])++); + temp = cbuf; + } + else + temp = "#"; + } Write(temp); mColPos++; } + else if (type == eHTMLTag_blockquote) + mIndent += gTabSize; else if (type == eHTMLTag_pre) { mPreformatted = PR_TRUE; @@ -642,8 +682,23 @@ nsHTMLToTXTSinkStream::OpenContainer(const nsIParserNode& aNode) Write(temp); mColPos = 0; } - else if (type == eHTMLTag_blockquote) - mIndent += gTabSize; + + // Finally, the list of tags before which we want some vertical space: + switch (type) + { + case eHTMLTag_table: + case eHTMLTag_ul: + case eHTMLTag_ol: + case eHTMLTag_p: + { + nsString temp(NS_LINEBREAK); + Write(temp); + mColPos = 0; + break; + } + default: + break; + } return NS_OK; } @@ -662,20 +717,32 @@ nsHTMLToTXTSinkStream::CloseContainer(const nsIParserNode& aNode) eHTMLTags type = (eHTMLTags)aNode.GetNodeType(); if (type == eHTMLTag_body) + { mDoOutput = PR_FALSE; + return NS_OK; + } else if (type == eHTMLTag_comment) { mDoOutput = PR_TRUE; return NS_OK; } + if (!mDoOutput) + return NS_OK; - else if (type == eHTMLTag_pre) + if (mTagStackIndex > 0) + --mTagStackIndex; + + if (type == eHTMLTag_pre) mPreformatted = PR_FALSE; + else if (type == eHTMLTag_ol) + --mOLStackIndex; + else if (type == eHTMLTag_blockquote) mIndent -= gTabSize; + // End current line if we're ending a block level tag if (IsBlockLevel(type)) { if (mColPos != 0) diff --git a/mozilla/htmlparser/src/nsHTMLToTXTSinkStream.h b/mozilla/htmlparser/src/nsHTMLToTXTSinkStream.h index fd6205ef12c..f6140a4e2ba 100644 --- a/mozilla/htmlparser/src/nsHTMLToTXTSinkStream.h +++ b/mozilla/htmlparser/src/nsHTMLToTXTSinkStream.h @@ -39,6 +39,7 @@ #include "nsIHTMLContentSink.h" +#include "nsHTMLTags.h" #define NS_HTMLTOTEXTSINK_STREAM_CID \ {0xa39c6bff, 0x15f0, 0x11d2, \ @@ -107,7 +108,11 @@ class nsHTMLToTXTSinkStream : public nsIHTMLContentSink NS_IMETHOD BeginContext(PRInt32 aPosition); NS_IMETHOD EndContext(PRInt32 aPosition); - NS_IMETHOD DoPrettyPrint(PRBool aDoPrettyPrint); + /******************************************************************* + * The following methods are specific to this class. + *******************************************************************/ + NS_IMETHOD SetWrapColumn(PRUint32 aWrapCol) { mWrapColumn = aWrapCol; return NS_OK; }; + NS_IMETHOD DoPrettyPrint(PRBool aPP) { mPrettyPrint = aPP; return NS_OK; }; protected: void EnsureBufferSize(PRInt32 aNewSize); @@ -127,7 +132,15 @@ protected: PRBool mDoOutput; PRBool mPreformatted; PRBool mPrettyPrint; - PRInt32 mWrapColumn; + PRUint32 mWrapColumn; + + // The tag stack: the stack of tags we're operating on, so we can nest: + nsHTMLTag *mTagStack; + PRUint32 mTagStackIndex; + + // The stack for ordered lists: + PRInt32 *mOLStack; + PRUint32 mOLStackIndex; char* mBuffer; PRInt32 mBufferLength; // The length of the data in the buffer @@ -141,11 +154,13 @@ extern NS_HTMLPARS nsresult NS_New_HTMLToTXT_SinkStream(nsIHTMLContentSink** aInstancePtrResult, nsIOutputStream* aOutStream, const nsString* aCharsetOverride=nsnull, + PRUint32 aWrapColumn=0, PRBool aPrettyPrint=PR_FALSE); extern NS_HTMLPARS nsresult NS_New_HTMLToTXT_SinkStream(nsIHTMLContentSink** aInstancePtrResult, nsString* aOutString, + PRUint32 aWrapColumn=0, PRBool aPrettyPrint=PR_FALSE); #endif diff --git a/mozilla/layout/base/public/nsIDocumentEncoder.h b/mozilla/layout/base/public/nsIDocumentEncoder.h index d9c841fa18e..e3dda078344 100644 --- a/mozilla/layout/base/public/nsIDocumentEncoder.h +++ b/mozilla/layout/base/public/nsIDocumentEncoder.h @@ -110,6 +110,7 @@ public: NS_IMETHOD SubstituteURL(const nsString& aOriginal, const nsString& aReplacement) = 0; NS_IMETHOD PrettyPrint(PRBool aYes) = 0; + NS_IMETHOD SetWrapColumn(PRUint32 aWC) = 0; }; @@ -123,6 +124,7 @@ public: // Get embedded objects -- images, links, etc. // NOTE: we may want to use an enumerator NS_IMETHOD PrettyPrint(PRBool aYes) = 0; + NS_IMETHOD SetWrapColumn(PRUint32 aWC) = 0; }; diff --git a/mozilla/layout/base/src/nsDocumentEncoder.cpp b/mozilla/layout/base/src/nsDocumentEncoder.cpp index 351931eb281..4804728f91f 100644 --- a/mozilla/layout/base/src/nsDocumentEncoder.cpp +++ b/mozilla/layout/base/src/nsDocumentEncoder.cpp @@ -64,6 +64,7 @@ public: NS_IMETHOD SubstituteURL(const nsString& aOriginal, const nsString& aReplacement); NS_IMETHOD PrettyPrint(PRBool aYesNO); + NS_IMETHOD SetWrapColumn(PRUint32 aWC); private: nsIDocument* mDocument; @@ -283,7 +284,13 @@ nsHTMLEncoder::SubstituteURL(const nsString& aOriginal, const nsString& aReplace } NS_IMETHODIMP -nsHTMLEncoder::PrettyPrint(PRBool aYes) +nsHTMLEncoder::PrettyPrint(PRBool) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsHTMLEncoder::SetWrapColumn(PRUint32) { return NS_ERROR_NOT_IMPLEMENTED; } @@ -319,6 +326,7 @@ public: NS_IMETHOD EncodeToString(nsString& aOutputString); NS_IMETHOD PrettyPrint(PRBool aYesNO); + NS_IMETHOD SetWrapColumn(PRUint32 aWC); private: nsIDocument* mDocument; @@ -327,6 +335,7 @@ private: nsString mMimeType; nsString mCharset; PRBool mPrettyPrint; + PRUint32 mWrapColumn; }; @@ -393,6 +402,13 @@ nsTextEncoder::PrettyPrint(PRBool aYes) return NS_OK; } +NS_IMETHODIMP +nsTextEncoder::SetWrapColumn(PRUint32 aWC) +{ + mWrapColumn = aWC; + return NS_OK; +} + NS_IMETHODIMP nsTextEncoder::SetSelection(nsIDOMSelection* aSelection) { @@ -451,7 +467,7 @@ nsTextEncoder::EncodeToString(nsString& aOutputString) if (NS_SUCCEEDED(rv)) { parser->RegisterDTD(dtd); - parser->Parse(buffer, 0, "text/xif",PR_FALSE,PR_TRUE); + parser->Parse(buffer, 0, "text/xif", PR_FALSE,PR_TRUE); } NS_IF_RELEASE(dtd); NS_IF_RELEASE(sink); @@ -499,7 +515,8 @@ nsTextEncoder::EncodeToStream(nsIOutputStream* aStream) if (NS_OK == rv) { nsIHTMLContentSink* sink = nsnull; - rv = NS_New_HTMLToTXT_SinkStream(&sink,aStream,charset,mPrettyPrint); + rv = NS_New_HTMLToTXT_SinkStream(&sink, aStream, charset, + mWrapColumn, mPrettyPrint); if (sink && NS_SUCCEEDED(rv)) { diff --git a/mozilla/parser/htmlparser/src/nsHTMLToTXTSinkStream.cpp b/mozilla/parser/htmlparser/src/nsHTMLToTXTSinkStream.cpp index e719032ca09..9d6c95957d5 100644 --- a/mozilla/parser/htmlparser/src/nsHTMLToTXTSinkStream.cpp +++ b/mozilla/parser/htmlparser/src/nsHTMLToTXTSinkStream.cpp @@ -34,6 +34,7 @@ #include "nsIParser.h" #include "nsHTMLEntities.h" #include "nsXIFDTD.h" +#include "prprf.h" // For PR_snprintf() #include "nsIUnicodeEncoder.h" #include "nsICharsetAlias.h" @@ -158,6 +159,7 @@ NS_HTMLPARS nsresult NS_New_HTMLToTXT_SinkStream(nsIHTMLContentSink** aInstancePtrResult, nsIOutputStream* aStream, const nsString* aCharsetOverride, + PRUint32 aWrapColumn, PRBool aPrettyPrint) { NS_ASSERTION(aStream != nsnull, "a valid stream is required"); @@ -165,6 +167,7 @@ NS_New_HTMLToTXT_SinkStream(nsIHTMLContentSink** aInstancePtrResult, if (nsnull == it) { return NS_ERROR_OUT_OF_MEMORY; } + it->SetWrapColumn(aWrapColumn); it->DoPrettyPrint(aPrettyPrint); if (aCharsetOverride != nsnull) it->SetCharsetOverride(aCharsetOverride); @@ -180,19 +183,25 @@ NS_New_HTMLToTXT_SinkStream(nsIHTMLContentSink** aInstancePtrResult, */ NS_HTMLPARS nsresult NS_New_HTMLToTXT_SinkStream(nsIHTMLContentSink** aInstancePtrResult, - nsString* aString, PRBool aPrettyPrint) + nsString* aString, + PRUint32 aWrapColumn, + PRBool aPrettyPrint) { NS_ASSERTION(aString != nsnull, "a valid stream is required"); nsHTMLToTXTSinkStream* it = new nsHTMLToTXTSinkStream(nsnull, aString); if (nsnull == it) { return NS_ERROR_OUT_OF_MEMORY; } + it->SetWrapColumn(aWrapColumn); it->DoPrettyPrint(aPrettyPrint); nsString ucs2("ucs2"); it->SetCharsetOverride(&ucs2); return it->QueryInterface(kIHTMLContentSinkIID, (void **)aInstancePtrResult); } +// Someday may want to make this non-const: +static const PRUint32 TagStackSize = 500; +static const PRUint32 OLStackSize = 100; /** * Construct a content sink stream. @@ -217,6 +226,14 @@ nsHTMLToTXTSinkStream::nsHTMLToTXTSinkStream(nsIOutputStream* aStream, mPrettyPrint = PR_FALSE; mPreformatted = PR_FALSE; mWrapColumn = 72; // XXX magic number, obviously needs to be settable + + // initialize the tag stack to zero: + mTagStack = new nsHTMLTag[TagStackSize]; + mTagStackIndex = 0; + + // initialize the OL stack, where numbers for ordered lists are kept: + mOLStack = new PRInt32[OLStackSize]; + mOLStackIndex = 0; } @@ -229,16 +246,11 @@ nsHTMLToTXTSinkStream::nsHTMLToTXTSinkStream(nsIOutputStream* aStream, nsHTMLToTXTSinkStream::~nsHTMLToTXTSinkStream() { delete [] mBuffer; + delete[] mTagStack; + delete[] mOLStack; NS_IF_RELEASE(mUnicodeEncoder); } -NS_IMETHODIMP -nsHTMLToTXTSinkStream::DoPrettyPrint(PRBool aDoPrettyPrint) -{ - mPrettyPrint = aDoPrettyPrint; - return NS_OK; -} - /** * * @update gpk04/30/99 @@ -627,14 +639,42 @@ nsHTMLToTXTSinkStream::OpenContainer(const nsIParserNode& aNode) } if (type == eHTMLTag_body) + { mDoOutput = PR_TRUE; + return NS_OK; + } + if (!mDoOutput) + return NS_OK; - else if (mDoOutput && type == eHTMLTag_li) + if (mTagStackIndex < TagStackSize) + mTagStack[mTagStackIndex++] = type; + + if (type == eHTMLTag_ol) + { + if (mOLStackIndex < OLStackSize) + mOLStack[mOLStackIndex++] = 1; // XXX should get it from the node! + } + + if (type == eHTMLTag_li) { nsString temp("*"); + if (mTagStackIndex > 1 && mTagStack[mTagStackIndex-2] == eHTMLTag_ol) + { + if (mOLStackIndex > 0) + { + // This is what nsBulletFrame does for OLs: + char cbuf[40]; + PR_snprintf(cbuf, sizeof(cbuf), "%ld.", (mOLStack[mOLStackIndex-1])++); + temp = cbuf; + } + else + temp = "#"; + } Write(temp); mColPos++; } + else if (type == eHTMLTag_blockquote) + mIndent += gTabSize; else if (type == eHTMLTag_pre) { mPreformatted = PR_TRUE; @@ -642,8 +682,23 @@ nsHTMLToTXTSinkStream::OpenContainer(const nsIParserNode& aNode) Write(temp); mColPos = 0; } - else if (type == eHTMLTag_blockquote) - mIndent += gTabSize; + + // Finally, the list of tags before which we want some vertical space: + switch (type) + { + case eHTMLTag_table: + case eHTMLTag_ul: + case eHTMLTag_ol: + case eHTMLTag_p: + { + nsString temp(NS_LINEBREAK); + Write(temp); + mColPos = 0; + break; + } + default: + break; + } return NS_OK; } @@ -662,20 +717,32 @@ nsHTMLToTXTSinkStream::CloseContainer(const nsIParserNode& aNode) eHTMLTags type = (eHTMLTags)aNode.GetNodeType(); if (type == eHTMLTag_body) + { mDoOutput = PR_FALSE; + return NS_OK; + } else if (type == eHTMLTag_comment) { mDoOutput = PR_TRUE; return NS_OK; } + if (!mDoOutput) + return NS_OK; - else if (type == eHTMLTag_pre) + if (mTagStackIndex > 0) + --mTagStackIndex; + + if (type == eHTMLTag_pre) mPreformatted = PR_FALSE; + else if (type == eHTMLTag_ol) + --mOLStackIndex; + else if (type == eHTMLTag_blockquote) mIndent -= gTabSize; + // End current line if we're ending a block level tag if (IsBlockLevel(type)) { if (mColPos != 0) diff --git a/mozilla/parser/htmlparser/src/nsHTMLToTXTSinkStream.h b/mozilla/parser/htmlparser/src/nsHTMLToTXTSinkStream.h index fd6205ef12c..f6140a4e2ba 100644 --- a/mozilla/parser/htmlparser/src/nsHTMLToTXTSinkStream.h +++ b/mozilla/parser/htmlparser/src/nsHTMLToTXTSinkStream.h @@ -39,6 +39,7 @@ #include "nsIHTMLContentSink.h" +#include "nsHTMLTags.h" #define NS_HTMLTOTEXTSINK_STREAM_CID \ {0xa39c6bff, 0x15f0, 0x11d2, \ @@ -107,7 +108,11 @@ class nsHTMLToTXTSinkStream : public nsIHTMLContentSink NS_IMETHOD BeginContext(PRInt32 aPosition); NS_IMETHOD EndContext(PRInt32 aPosition); - NS_IMETHOD DoPrettyPrint(PRBool aDoPrettyPrint); + /******************************************************************* + * The following methods are specific to this class. + *******************************************************************/ + NS_IMETHOD SetWrapColumn(PRUint32 aWrapCol) { mWrapColumn = aWrapCol; return NS_OK; }; + NS_IMETHOD DoPrettyPrint(PRBool aPP) { mPrettyPrint = aPP; return NS_OK; }; protected: void EnsureBufferSize(PRInt32 aNewSize); @@ -127,7 +132,15 @@ protected: PRBool mDoOutput; PRBool mPreformatted; PRBool mPrettyPrint; - PRInt32 mWrapColumn; + PRUint32 mWrapColumn; + + // The tag stack: the stack of tags we're operating on, so we can nest: + nsHTMLTag *mTagStack; + PRUint32 mTagStackIndex; + + // The stack for ordered lists: + PRInt32 *mOLStack; + PRUint32 mOLStackIndex; char* mBuffer; PRInt32 mBufferLength; // The length of the data in the buffer @@ -141,11 +154,13 @@ extern NS_HTMLPARS nsresult NS_New_HTMLToTXT_SinkStream(nsIHTMLContentSink** aInstancePtrResult, nsIOutputStream* aOutStream, const nsString* aCharsetOverride=nsnull, + PRUint32 aWrapColumn=0, PRBool aPrettyPrint=PR_FALSE); extern NS_HTMLPARS nsresult NS_New_HTMLToTXT_SinkStream(nsIHTMLContentSink** aInstancePtrResult, nsString* aOutString, + PRUint32 aWrapColumn=0, PRBool aPrettyPrint=PR_FALSE); #endif