Performance fix for message display - Bug #: 21203 - r: xxxxx

This commit is contained in:
rhp%netscape.com 1999-12-15 03:35:34 +00:00
Родитель 2ce647f94a
Коммит 972a33874a
20 изменённых файлов: 908 добавлений и 870 удалений

Просмотреть файл

@ -21,8 +21,5 @@
#
mailheader.css
mailheader-micro.css
mailheader-normal.css
mailheader-all.css
addcard.gif
attach.gif

Просмотреть файл

@ -28,9 +28,6 @@ include $(DEPTH)/config/autoconf.mk
EXPORT_RESOURCES = \
$(srcdir)/mailheader.css \
$(srcdir)/mailheader-micro.css \
$(srcdir)/mailheader-normal.css \
$(srcdir)/mailheader-all.css \
$(srcdir)/addcard.gif \
$(srcdir)/attach.gif \
$(NULL)

Просмотреть файл

@ -1,16 +0,0 @@
/*
* Window behavior for scrolling and general header color
* attributes
*/
window { overflow: auto; }
mailheader { display: block; }
mailattachcount { display: none; }
box[name=header-attachment] { background-color: #EFEFEF; border: 0px solid #EFEFEF; border-left-width: 4px; }
box[name=header-part1] { background-color: #EFEFEF; border: 0px solid #EFEFEF; border-left-width: 4px; }
box[name=header-part2] { background-color: #DEDEDE; border: 0px solid #DEDEDE; border-left-width: 4px; }
box[name=header-part3] { background-color: #DEDEDE; border: 0px solid #DEDEDE; border-left-width: 4px; }
box[name=header-seamonkey] { background-color: #DEDEDE; border: 0px solid #DEDEDE; border-left-width: 4px; }
menubar[name=attachment-menubar] { background-color: #EFEFEF; border: 0px solid #EFEFEF; }
menu[name=attachment-menu] { background-color: #EFEFEF; border: 0px solid #EFEFEF; }

Просмотреть файл

@ -26,16 +26,10 @@ include <$(DEPTH)\config\rules.mak>
install::
$(MAKE_INSTALL) mailheader.css $(DIST)\bin\chrome\messenger\skin\default
$(MAKE_INSTALL) mailheader-micro.css $(DIST)\bin\chrome\messenger\skin\default
$(MAKE_INSTALL) mailheader-normal.css $(DIST)\bin\chrome\messenger\skin\default
$(MAKE_INSTALL) mailheader-all.css $(DIST)\bin\chrome\messenger\skin\default
$(MAKE_INSTALL) addcard.gif $(DIST)\bin\chrome\messenger\skin\default
$(MAKE_INSTALL) attach.gif $(DIST)\bin\chrome\messenger\skin\default
clobber::
rm -f $(DIST)\bin\chrome\messenger\skin\default\mailheader.css
rm -f $(DIST)\bin\chrome\messenger\skin\default\mailheader-micro.css
rm -f $(DIST)\bin\chrome\messenger\skin\default\mailheader-normal.css
rm -f $(DIST)\bin\chrome\messenger\skin\default\mailheader-all.css
rm -f $(DIST)\bin\chrome\messenger\skin\default\addcard.gif
rm -f $(DIST)\bin\chrome\messenger\skin\default\attach.gif

Просмотреть файл

@ -134,16 +134,3 @@ nsMsgCreateTempFileName(char *tFileName)
else
return tString;
}
char *
nsMimePlatformFileToURL (nsFileSpec aFileSpec)
{
nsFileURL tURL(aFileSpec);
const char *tPtr = nsnull;
tPtr = tURL.GetURLString();
if (tPtr)
return nsCRT::strdup(tPtr);
else
return nsnull;
}

Просмотреть файл

@ -34,7 +34,5 @@ extern "C" PRBool EmitThisHeaderForPrefSetting(PRInt32 dispType, const char *h
nsFileSpec *nsMsgCreateTempFileSpec(char *tFileName);
char *nsMsgCreateTempFileName(char *tFileName);
char *nsMimePlatformFileToURL (nsFileSpec aFileSpec);
#endif // _nsEmitterUtils_h_

Просмотреть файл

@ -39,7 +39,9 @@
#include "nsFileSpec.h"
#include "nsIRegistry.h"
static NS_DEFINE_CID(kPrefCID, NS_PREF_CID);
#define MIME_URL "chrome://messenger/locale/mimeheader.properties"
static NS_DEFINE_CID(kPrefCID, NS_PREF_CID);
static NS_DEFINE_CID(kStringBundleServiceCID, NS_STRINGBUNDLESERVICE_CID);
NS_IMPL_ISUPPORTS2(nsMimeBaseEmitter, nsIMimeEmitter, nsIPipeObserver)
@ -47,18 +49,39 @@ nsMimeBaseEmitter::nsMimeBaseEmitter()
{
NS_INIT_REFCNT();
// Initialize data output vars...
mBufferMgr = NULL;
mTotalWritten = 0;
mTotalRead = 0;
mDocHeader = PR_FALSE;
m_stringBundle = nsnull;
mInputStream = nsnull;
mOutStream = nsnull;
mOutListener = nsnull;
// Display output control vars...
mDocHeader = PR_FALSE;
m_stringBundle = nsnull;
mURL = nsnull;
mHeaderDisplayType = nsMimeHeaderDisplayTypes::NormalHeaders;
// Setup array for attachments
mAttachCount = 0;
mAttachArray = new nsVoidArray();
mCurrentAttachment = nsnull;
// Header cache...
mHeaderArray = new nsVoidArray();
// Embedded Header Cache...
mEmbeddedHeaderArray = nsnull;
// HTML Header Data...
mHTMLHeaders = "";
// Init the body...
mBodyStarted = PR_FALSE;
mBody = "";
// Do prefs last since we can live without this if it fails...
nsresult rv = nsServiceManager::GetService(kPrefCID, nsIPref::GetIID(), (nsISupports**)&(mPrefs));
if (! (mPrefs && NS_SUCCEEDED(rv)))
return;
@ -69,249 +92,62 @@ nsMimeBaseEmitter::nsMimeBaseEmitter()
nsMimeBaseEmitter::~nsMimeBaseEmitter(void)
{
PRInt32 i;
// Delete the buffer manager...
if (mBufferMgr)
delete mBufferMgr;
// Release the prefs service
// Release the prefs service...
if (mPrefs)
nsServiceManager::ReleaseService(kPrefCID, mPrefs);
}
NS_IMETHODIMP
nsMimeBaseEmitter::SetPipe(nsIInputStream * aInputStream, nsIOutputStream *outStream)
{
mInputStream = aInputStream;
mOutStream = outStream;
return NS_OK;
}
// Note - these is setup only...you should not write
// anything to the stream since these may be image data
// output streams, etc...
NS_IMETHODIMP
nsMimeBaseEmitter::Initialize(nsIURI *url, nsIChannel * aChannel)
{
// set the url
mURL = url;
mChannel = aChannel;
// Create rebuffering object
mBufferMgr = new MimeRebuffer();
// Counters for output stream
mTotalWritten = 0;
mTotalRead = 0;
return NS_OK;
}
NS_IMETHODIMP
nsMimeBaseEmitter::SetOutputListener(nsIStreamListener *listener)
{
mOutListener = listener;
return NS_OK;
}
// Note - this is teardown only...you should not write
// anything to the stream since these may be image data
// output streams, etc...
NS_IMETHODIMP
nsMimeBaseEmitter::Complete()
{
// If we are here and still have data to write, we should try
// to flush it...if we try and fail, we should probably return
// an error!
PRUint32 written;
while ( (mBufferMgr) && (mBufferMgr->GetSize() > 0))
Write("", 0, &written);
if (mOutListener)
// Clean up the attachment array structures...
if (mAttachArray)
{
PRUint32 bytesInStream;
mInputStream->Available(&bytesInStream);
mOutListener->OnDataAvailable(mChannel, mURL, mInputStream, 0, bytesInStream);
}
return NS_OK;
}
// Header handling routines.
NS_IMETHODIMP
nsMimeBaseEmitter::StartHeader(PRBool rootMailHeader, PRBool headerOnly, const char *msgID,
const char *outCharset)
{
return NS_OK;
}
NS_IMETHODIMP
nsMimeBaseEmitter::AddHeaderField(const char *field, const char *value)
{
return NS_OK;
}
NS_IMETHODIMP
nsMimeBaseEmitter::EndHeader()
{
return NS_OK;
}
// Attachment handling routines
NS_IMETHODIMP
nsMimeBaseEmitter::StartAttachment(const char *name, const char *contentType, const char *url)
{
return NS_OK;
}
NS_IMETHODIMP
nsMimeBaseEmitter::AddAttachmentField(const char *field, const char *value)
{
return NS_OK;
}
NS_IMETHODIMP
nsMimeBaseEmitter::EndAttachment()
{
return NS_OK;
}
// body handling routines
NS_IMETHODIMP
nsMimeBaseEmitter::StartBody(PRBool bodyOnly, const char *msgID, const char *outCharset)
{
return NS_OK;
}
NS_IMETHODIMP
nsMimeBaseEmitter::WriteBody(const char *buf, PRUint32 size, PRUint32 *amountWritten)
{
return NS_OK;
}
NS_IMETHODIMP
nsMimeBaseEmitter::EndBody()
{
return NS_OK;
}
NS_IMETHODIMP
nsMimeBaseEmitter::UtilityWrite(const char *buf)
{
PRInt32 tmpLen = nsCRT::strlen(buf);
PRUint32 written;
Write(buf, tmpLen, &written);
return NS_OK;
}
NS_IMETHODIMP
nsMimeBaseEmitter::UtilityWriteCRLF(const char *buf)
{
PRInt32 tmpLen = nsCRT::strlen(buf);
PRUint32 written;
Write(buf, tmpLen, &written);
Write(CRLF, 2, &written);
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// These are routines necessary for the C based routines in libmime
// to access the new world streams.
////////////////////////////////////////////////////////////////////////////////
NS_IMETHODIMP
nsMimeBaseEmitter::Write(const char *buf, PRUint32 size, PRUint32 *amountWritten)
{
unsigned int written = 0;
PRUint32 rc = 0;
PRUint32 needToWrite;
//
// Make sure that the buffer we are "pushing" into has enough room
// for the write operation. If not, we have to buffer, return, and get
// it on the next time through
//
*amountWritten = 0;
needToWrite = mBufferMgr->GetSize();
// First, handle any old buffer data...
if (needToWrite > 0)
{
rc += mOutStream->Write(mBufferMgr->GetBuffer(),
needToWrite, &written);
mTotalWritten += written;
mBufferMgr->ReduceBuffer(written);
*amountWritten = written;
// if we couldn't write all the old data, buffer the new data
// and return
if (mBufferMgr->GetSize() > 0)
for (i=0; i<mAttachArray->Count(); i++)
{
mBufferMgr->IncreaseBuffer(buf, size);
return NS_OK;
attachmentInfoType *attachInfo = (attachmentInfoType *)mAttachArray->ElementAt(i);
if (!attachInfo)
continue;
PR_FREEIF(attachInfo->contentType);
PR_FREEIF(attachInfo->displayName);
PR_FREEIF(attachInfo->urlSpec);
delete attachInfo;
}
delete mAttachArray;
}
// Cleanup allocated header arrays...
CleanupHeaderArray(mHeaderArray);
mHeaderArray = nsnull;
// if we get here, we are dealing with new data...try to write
// and then do the right thing...
rc = mOutStream->Write(buf, size, &written);
*amountWritten = written;
mTotalWritten += written;
if (written < size)
mBufferMgr->IncreaseBuffer(buf+written, (size-written));
return rc;
CleanupHeaderArray(mEmbeddedHeaderArray);
mEmbeddedHeaderArray = nsnull;
}
NS_IMETHODIMP nsMimeBaseEmitter::OnWrite(nsIPipe* aPipe, PRUint32 aCount)
void
nsMimeBaseEmitter::CleanupHeaderArray(nsVoidArray *aArray)
{
return NS_OK;
}
if (!aArray)
return;
NS_IMETHODIMP nsMimeBaseEmitter::OnEmpty(nsIPipe* aPipe)
{
return NS_OK;
}
NS_IMETHODIMP nsMimeBaseEmitter::OnFull(nsIPipe* /* aPipe */)
{
// the pipe is full so we should flush our data to the converter's listener
// in order to make more room.
// since we only have one pipe per mime emitter, i can ignore the pipe param and use
// my outStream object directly (it will be the same thing as what we'd get from aPipe.
nsresult rv = NS_OK;
if (mOutListener && mInputStream)
for (PRInt32 i=0; i<aArray->Count(); i++)
{
PRUint32 bytesAvailable = 0;
mInputStream->Available(&bytesAvailable);
rv = mOutListener->OnDataAvailable(mChannel, mURL, mInputStream, 0, bytesAvailable);
headerInfoType *headerInfo = (headerInfoType *)aArray->ElementAt(i);
if (!headerInfo)
continue;
PR_FREEIF(headerInfo->name);
PR_FREEIF(headerInfo->value);
delete headerInfo;
}
else
rv = NS_ERROR_NULL_POINTER;
return rv;
}
//
// This should be part of the base class to optimize the performance of the
// calls to get localized strings.
// This is the next generation string retrieval call
//
/* This is the next generation string retrieval call */
static NS_DEFINE_CID(kStringBundleServiceCID, NS_STRINGBUNDLESERVICE_CID);
#define MIME_URL "chrome://messenger/locale/mimeheader.properties"
char *
nsMimeBaseEmitter::MimeGetStringByName(const char *aHeaderName)
{
@ -372,3 +208,520 @@ nsMimeBaseEmitter::LocalizeHeaderName(const char *aHeaderName, const char *aDefa
else
return nsCRT::strdup(aDefaultName);
}
///////////////////////////////////////////////////////////////////////////
// nsIPipeObserver Interface
///////////////////////////////////////////////////////////////////////////
NS_IMETHODIMP nsMimeBaseEmitter::OnWrite(nsIPipe* aPipe, PRUint32 aCount)
{
return NS_OK;
}
NS_IMETHODIMP nsMimeBaseEmitter::OnEmpty(nsIPipe* aPipe)
{
return NS_OK;
}
NS_IMETHODIMP nsMimeBaseEmitter::OnFull(nsIPipe* /* aPipe */)
{
// the pipe is full so we should flush our data to the converter's listener
// in order to make more room.
// since we only have one pipe per mime emitter, i can ignore the pipe param and use
// my outStream object directly (it will be the same thing as what we'd get from aPipe.
nsresult rv = NS_OK;
if (mOutListener && mInputStream)
{
PRUint32 bytesAvailable = 0;
mInputStream->Available(&bytesAvailable);
rv = mOutListener->OnDataAvailable(mChannel, mURL, mInputStream, 0, bytesAvailable);
}
else
rv = NS_ERROR_NULL_POINTER;
return rv;
}
///////////////////////////////////////////////////////////////////////////
// nsMimeBaseEmitter Interface
///////////////////////////////////////////////////////////////////////////
NS_IMETHODIMP
nsMimeBaseEmitter::SetPipe(nsIInputStream * aInputStream, nsIOutputStream *outStream)
{
mInputStream = aInputStream;
mOutStream = outStream;
return NS_OK;
}
// Note - these is setup only...you should not write
// anything to the stream since these may be image data
// output streams, etc...
NS_IMETHODIMP
nsMimeBaseEmitter::Initialize(nsIURI *url, nsIChannel * aChannel)
{
// set the url
mURL = url;
mChannel = aChannel;
// Create rebuffering object
mBufferMgr = new MimeRebuffer();
// Counters for output stream
mTotalWritten = 0;
mTotalRead = 0;
return NS_OK;
}
NS_IMETHODIMP
nsMimeBaseEmitter::SetOutputListener(nsIStreamListener *listener)
{
mOutListener = listener;
return NS_OK;
}
// Attachment handling routines
nsresult
nsMimeBaseEmitter::StartAttachment(const char *name, const char *contentType, const char *url)
{
// Ok, now we will setup the attachment info
mCurrentAttachment = (attachmentInfoType *) PR_NEWZAP(attachmentInfoType);
if ( (mCurrentAttachment) && mAttachArray)
{
++mAttachCount;
mCurrentAttachment->displayName = nsCRT::strdup(name);
mCurrentAttachment->urlSpec = nsCRT::strdup(url);
mCurrentAttachment->contentType = nsCRT::strdup(contentType);
}
return NS_OK;
}
nsresult
nsMimeBaseEmitter::EndAttachment()
{
// Ok, add the attachment info to the attachment array...
if ( (mCurrentAttachment) && (mAttachArray) )
{
mAttachArray->AppendElement(mCurrentAttachment);
mCurrentAttachment = nsnull;
}
return NS_OK;
}
NS_IMETHODIMP
nsMimeBaseEmitter::AddAttachmentField(const char *field, const char *value)
{
return NS_OK;
}
NS_IMETHODIMP
nsMimeBaseEmitter::UtilityWrite(const char *buf)
{
PRInt32 tmpLen = nsCRT::strlen(buf);
PRUint32 written;
Write(buf, tmpLen, &written);
return NS_OK;
}
NS_IMETHODIMP
nsMimeBaseEmitter::UtilityWriteCRLF(const char *buf)
{
PRInt32 tmpLen = nsCRT::strlen(buf);
PRUint32 written;
Write(buf, tmpLen, &written);
Write(CRLF, 2, &written);
return NS_OK;
}
NS_IMETHODIMP
nsMimeBaseEmitter::Write(const char *buf, PRUint32 size, PRUint32 *amountWritten)
{
unsigned int written = 0;
PRUint32 rc = 0;
PRUint32 needToWrite;
//
// Make sure that the buffer we are "pushing" into has enough room
// for the write operation. If not, we have to buffer, return, and get
// it on the next time through
//
*amountWritten = 0;
needToWrite = mBufferMgr->GetSize();
// First, handle any old buffer data...
if (needToWrite > 0)
{
rc += mOutStream->Write(mBufferMgr->GetBuffer(),
needToWrite, &written);
mTotalWritten += written;
mBufferMgr->ReduceBuffer(written);
*amountWritten = written;
// if we couldn't write all the old data, buffer the new data
// and return
if (mBufferMgr->GetSize() > 0)
{
mBufferMgr->IncreaseBuffer(buf, size);
return NS_OK;
}
}
// if we get here, we are dealing with new data...try to write
// and then do the right thing...
rc = mOutStream->Write(buf, size, &written);
*amountWritten = written;
mTotalWritten += written;
if (written < size)
mBufferMgr->IncreaseBuffer(buf+written, (size-written));
return rc;
}
//
// Find a cached header! Note: Do NOT free this value!
//
char *
nsMimeBaseEmitter::GetHeaderValue(const char *aHeaderName,
nsVoidArray *aArray)
{
PRInt32 i;
char *retVal = nsnull;
if (!aArray)
return nsnull;
for (i=0; i<aArray->Count(); i++)
{
headerInfoType *headerInfo = (headerInfoType *)aArray->ElementAt(i);
if ( (!headerInfo) || (!headerInfo->name) || (!(*headerInfo->name)) )
continue;
if (!nsCRT::strcasecmp(aHeaderName, headerInfo->name))
{
retVal = headerInfo->value;
break;
}
}
return retVal;
}
//
// This is called at the start of the header block for all header information in ANY
// AND ALL MESSAGES (yes, quoted, attached, etc...)
//
NS_IMETHODIMP
nsMimeBaseEmitter::StartHeader(PRBool rootMailHeader, PRBool headerOnly, const char *msgID,
const char *outCharset)
{
mDocHeader = rootMailHeader;
// If this is not the mail messages header, then we need to create
// the mEmbeddedHeaderArray structure for use with this internal header
// structure.
if (!mDocHeader)
{
if (mEmbeddedHeaderArray)
CleanupHeaderArray(mEmbeddedHeaderArray);
mEmbeddedHeaderArray = new nsVoidArray();
if (!mEmbeddedHeaderArray)
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;
}
//
// This will be called for every header field regardless if it is in an
// internal body or the outer message.
//
NS_IMETHODIMP
nsMimeBaseEmitter::AddHeaderField(const char *field, const char *value)
{
if ( (!field) || (!value) )
return NS_OK;
nsVoidArray *tPtr;
if (mDocHeader)
tPtr = mHeaderArray;
else
tPtr = mEmbeddedHeaderArray;
// This is a header so we need to cache and output later.
// Ok, now we will setup the header info for the header array!
headerInfoType *ptr = (headerInfoType *) PR_NEWZAP(headerInfoType);
if ( (ptr) && tPtr)
{
ptr->name = nsCRT::strdup(field);
ptr->value = nsCRT::strdup(value);
tPtr->AppendElement(ptr);
}
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// The following code is responsible for formatting headers in a manner that is
// identical to the normal XUL output.
////////////////////////////////////////////////////////////////////////////////
nsresult
nsMimeBaseEmitter::WriteHeaderFieldHTML(const char *field, const char *value)
{
if ( (!field) || (!value) )
return NS_OK;
//
// This is a check to see what the pref is for header display. If
// We should only output stuff that corresponds with that setting.
//
if (!EmitThisHeaderForPrefSetting(mHeaderDisplayType, field))
return NS_OK;
char *newValue = nsEscapeHTML(value);
if (!newValue)
return NS_OK;
mHTMLHeaders.Append("<TR>");
mHTMLHeaders.Append("<TD>");
mHTMLHeaders.Append("<DIV CLASS=\"headerdisplayname\">");
// Here is where we are going to try to L10N the tagName so we will always
// get a field name next to an emitted header value. Note: Default will always
// be the name of the header itself.
//
nsCAutoString newTagName(field);
newTagName.CompressWhitespace(PR_TRUE, PR_TRUE);
newTagName.ToUpperCase();
char *l10nTagName = LocalizeHeaderName((const char *) newTagName, field);
if ( (!l10nTagName) || (!*l10nTagName) )
mHTMLHeaders.Append(field);
else
{
mHTMLHeaders.Append(l10nTagName);
PR_FREEIF(l10nTagName);
}
mHTMLHeaders.Append(": ");
mHTMLHeaders.Append("</DIV>");
// Now write out the actual value itself and move on!
//
mHTMLHeaders.Append(newValue);
mHTMLHeaders.Append("</TD>");
mHTMLHeaders.Append("</TR>");
PR_FREEIF(newValue);
return NS_OK;
}
nsresult
nsMimeBaseEmitter::WriteHeaderFieldHTMLPrefix()
{
mHTMLHeaders.Append("<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 WIDTH=\"100%\">");
return NS_OK;
}
nsresult
nsMimeBaseEmitter::WriteHeaderFieldHTMLPostfix()
{
mHTMLHeaders.Append("</TABLE><BR>");
return NS_OK;
}
nsresult
nsMimeBaseEmitter::WriteHTMLHeaders()
{
WriteHeaderFieldHTMLPrefix();
// Start with the subject, from date info!
DumpSubjectFromDate();
// Continue with the to and cc headers
DumpToCC();
// Do the rest of the headers, but these will only be written if
// the user has the "show all headers" pref set
DumpRestOfHeaders();
WriteHeaderFieldHTMLPostfix();
// Now, we need to either append the headers we built up to the
// overall body or output to the stream.
if (mDocHeader)
UtilityWriteCRLF(mHTMLHeaders);
else
mBody.Append(mHTMLHeaders);
return NS_OK;
}
nsresult
nsMimeBaseEmitter::DumpSubjectFromDate()
{
mHTMLHeaders.Append("<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 WIDTH=\"100%\" NAME=\"header-part1\" >");
// This is the envelope information
OutputGenericHeader(HEADER_SUBJECT);
OutputGenericHeader(HEADER_FROM);
OutputGenericHeader(HEADER_DATE);
mHTMLHeaders.Append("</TABLE>");
return NS_OK;
}
nsresult
nsMimeBaseEmitter::DumpToCC()
{
char * toField = GetHeaderValue(HEADER_TO, mHeaderArray);
char * ccField = GetHeaderValue(HEADER_CC, mHeaderArray);
char * bccField = GetHeaderValue(HEADER_BCC, mHeaderArray);
char * newsgroupField = GetHeaderValue(HEADER_NEWSGROUPS, mHeaderArray);
// only dump these fields if we have at least one of them! When displaying news
// messages that didn't have a to or cc field, we'd always get an empty box
// which looked weird.
if (toField || ccField || bccField || newsgroupField)
{
mHTMLHeaders.Append("<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 WIDTH=\"100%\" NAME=\"header-part2\" >");
OutputGenericHeader(HEADER_TO);
OutputGenericHeader(HEADER_CC);
OutputGenericHeader(HEADER_BCC);
OutputGenericHeader(HEADER_NEWSGROUPS);
mHTMLHeaders.Append("</TABLE>");
}
return NS_OK;
}
nsresult
nsMimeBaseEmitter::DumpRestOfHeaders()
{
PRInt32 i;
if (mHeaderDisplayType != nsMimeHeaderDisplayTypes::AllHeaders)
return NS_OK;
mHTMLHeaders.Append("<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0 WIDTH=\"100%\" NAME=\"header-part3\" >");
for (i=0; i<mHeaderArray->Count(); i++)
{
headerInfoType *headerInfo = (headerInfoType *)mHeaderArray->ElementAt(i);
if ( (!headerInfo) || (!headerInfo->name) || (!(*headerInfo->name)) ||
(!headerInfo->value) || (!(*headerInfo->value)))
continue;
if ( (!nsCRT::strcasecmp(HEADER_SUBJECT, headerInfo->name)) ||
(!nsCRT::strcasecmp(HEADER_DATE, headerInfo->name)) ||
(!nsCRT::strcasecmp(HEADER_FROM, headerInfo->name)) ||
(!nsCRT::strcasecmp(HEADER_TO, headerInfo->name)) ||
(!nsCRT::strcasecmp(HEADER_CC, headerInfo->name)) )
continue;
WriteHeaderFieldHTML(headerInfo->name, headerInfo->value);
}
mHTMLHeaders.Append("</TABLE>");
return NS_OK;
}
nsresult
nsMimeBaseEmitter::OutputGenericHeader(const char *aHeaderVal)
{
char *val = nsnull;
nsresult rv;
if (mDocHeader)
val = GetHeaderValue(aHeaderVal, mHeaderArray);
else
val = GetHeaderValue(aHeaderVal, mEmbeddedHeaderArray);
if (val)
{
rv = WriteHeaderFieldHTML(aHeaderVal, val);
return rv;
}
else
return NS_ERROR_FAILURE;
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// These are the methods that should be implemented by the child class!
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//
// This should be implemented by the child class if special processing
// needs to be done when the entire message is read.
//
NS_IMETHODIMP
nsMimeBaseEmitter::Complete()
{
// If we are here and still have data to write, we should try
// to flush it...if we try and fail, we should probably return
// an error!
PRUint32 written;
while ( (mBufferMgr) && (mBufferMgr->GetSize() > 0))
Write("", 0, &written);
if (mOutListener)
{
PRUint32 bytesInStream;
mInputStream->Available(&bytesInStream);
mOutListener->OnDataAvailable(mChannel, mURL, mInputStream, 0, bytesInStream);
}
return NS_OK;
}
//
// This needs to do the right thing with the stored information. It only
// has to do the output functions, this base class will take care of the
// memory cleanup
//
NS_IMETHODIMP
nsMimeBaseEmitter::EndHeader()
{
return NS_OK;
}
// body handling routines
NS_IMETHODIMP
nsMimeBaseEmitter::StartBody(PRBool bodyOnly, const char *msgID, const char *outCharset)
{
return NS_OK;
}
NS_IMETHODIMP
nsMimeBaseEmitter::WriteBody(const char *buf, PRUint32 size, PRUint32 *amountWritten)
{
return NS_OK;
}
NS_IMETHODIMP
nsMimeBaseEmitter::EndBody()
{
return NS_OK;
}

Просмотреть файл

@ -38,50 +38,109 @@
#include "nsIPipe.h"
#include "nsIStringBundle.h"
#include "nsCOMPtr.h"
#include "nsVoidArray.h"
//
// The base emitter will serve as the place to do all of the caching,
// sorting, etc... of mail headers and bodies for this internally developed
// emitter library. The other emitter classes in this file (nsMimeHTMLEmitter, etc.)
// will only be concerned with doing output processing ONLY.
//
//
// Used for keeping track of the attachment information...
//
typedef struct {
char *displayName;
char *urlSpec;
char *contentType;
} attachmentInfoType;
//
// For header info...
//
typedef struct {
char *name;
char *value;
} headerInfoType;
class nsMimeBaseEmitter : public nsIMimeEmitter, nsIPipeObserver {
public:
nsMimeBaseEmitter ();
virtual ~nsMimeBaseEmitter (void);
nsMimeBaseEmitter ();
virtual ~nsMimeBaseEmitter (void);
// nsISupports interface
NS_DECL_ISUPPORTS
// nsISupports interface
NS_DECL_ISUPPORTS
NS_DECL_NSIMIMEEMITTER
NS_DECL_NSIPIPEOBSERVER
NS_DECL_NSIMIMEEMITTER
NS_DECL_NSIPIPEOBSERVER
NS_IMETHOD UtilityWriteCRLF(const char *buf);
// Utility output functions...
NS_IMETHOD UtilityWriteCRLF(const char *buf);
// For cacheing string bundles...
char *MimeGetStringByName(const char *aHeaderName);
char *LocalizeHeaderName(const char *aHeaderName, const char *aDefaultName);
// For string bundle usage...
char *MimeGetStringByName(const char *aHeaderName);
char *LocalizeHeaderName(const char *aHeaderName, const char *aDefaultName);
// For header processing...
char *GetHeaderValue(const char *aHeaderName,
nsVoidArray *aArray);
// To write out a stored header array as HTML
nsresult WriteHeaderFieldHTMLPrefix();
nsresult WriteHeaderFieldHTML(const char *field, const char *value);
nsresult WriteHeaderFieldHTMLPostfix();
nsresult WriteHTMLHeaders();
protected:
// For buffer management on output
MimeRebuffer *mBufferMgr;
// Internal methods...
void CleanupHeaderArray(nsVoidArray *aArray);
nsCOMPtr<nsIStringBundle> m_stringBundle; // For string bundle usage...
// For header output...
nsresult DumpSubjectFromDate();
nsresult DumpToCC();
nsresult DumpRestOfHeaders();
nsresult OutputGenericHeader(const char *aHeaderVal);
// For string bundle usage...
nsCOMPtr<nsIStringBundle> m_stringBundle; // For string bundle usage...
// mscott - dont ref count the streams....the emitter is owned by the converter
// For buffer management on output
MimeRebuffer *mBufferMgr;
// mscott
// dont ref count the streams....the emitter is owned by the converter
// which owns these streams...
//
nsIOutputStream *mOutStream;
nsIInputStream *mInputStream;
nsIStreamListener *mOutListener;
nsIChannel *mChannel;
// For gathering statistics on processing...
PRUint32 mTotalWritten;
PRUint32 mTotalRead;
// For header determination...
PRBool mDocHeader;
// Output control and info...
nsIPref *mPrefs; // Connnection to prefs service manager
PRBool mDocHeader; // For header determination...
nsIURI *mURL; // the url for the data being processed...
PRInt32 mHeaderDisplayType; // The setting for header output...
nsCString mHTMLHeaders; // HTML Header Data...
// the url for the data being processed...
nsIURI *mURL;
// For attachment processing...
PRInt32 mAttachCount;
nsVoidArray *mAttachArray;
attachmentInfoType *mCurrentAttachment;
// The setting for header output...
nsIPref *mPrefs; /* Connnection to prefs service manager */
PRInt32 mHeaderDisplayType;
// For header caching...
nsVoidArray *mHeaderArray;
nsVoidArray *mEmbeddedHeaderArray;
nsCOMPtr<nsIMsgHeaderParser> mHeaderParser;
// For body caching...
PRBool mBodyStarted;
nsCString mBody;
};
#endif /* _nsMimeBaseEmitter_h_ */

Просмотреть файл

@ -43,91 +43,26 @@ nsresult NS_NewMimeHtmlEmitter(const nsIID& iid, void **result)
*/
nsMimeHtmlEmitter::nsMimeHtmlEmitter()
{
mFirst = PR_TRUE;
}
nsMimeHtmlEmitter::~nsMimeHtmlEmitter(void)
{
}
// Header handling routines.
nsresult
nsMimeHtmlEmitter::StartHeader(PRBool rootMailHeader, PRBool headerOnly, const char *msgID,
const char *outCharset)
{
mDocHeader = rootMailHeader;
if (mDocHeader)
{
UtilityWrite("<TABLE BORDER=0>");
}
else
UtilityWrite("<TABLE BORDER=0>");
return NS_OK;
}
nsresult
nsMimeHtmlEmitter::AddHeaderField(const char *field, const char *value)
{
if ( (!field) || (!value) )
return NS_OK;
//
// This is a check to see what the pref is for header display. If
// We should only output stuff that corresponds with that setting.
//
if (!EmitThisHeaderForPrefSetting(mHeaderDisplayType, field))
return NS_OK;
char *newValue = nsEscapeHTML(value);
if (!newValue)
return NS_OK;
UtilityWrite("<TR>");
UtilityWrite("<TD>");
UtilityWrite("<DIV align=right>");
UtilityWrite("<B>");
// Here is where we are going to try to L10N the tagName so we will always
// get a field name next to an emitted header value. Note: Default will always
// be the name of the header itself.
//
nsString newTagName(field);
newTagName.CompressWhitespace(PR_TRUE, PR_TRUE);
newTagName.ToUpperCase();
char *upCaseField = newTagName.ToNewCString();
char *l10nTagName = LocalizeHeaderName(upCaseField, field);
if ( (!l10nTagName) || (!*l10nTagName) )
UtilityWrite(field);
else
{
UtilityWrite(l10nTagName);
PR_FREEIF(l10nTagName);
}
// Now write out the actual value itself and move on!
//
UtilityWrite(":");
UtilityWrite("</B>");
UtilityWrite("</DIV>");
UtilityWrite("</TD>");
UtilityWrite("<TD>");
UtilityWrite(newValue);
UtilityWrite("</TD>");
UtilityWrite("</TR>");
PR_FREEIF(newValue);
nsCRT::free(upCaseField);
return NS_OK;
}
nsresult
nsMimeHtmlEmitter::EndHeader()
{
UtilityWrite("</TABLE></BLOCKQUOTE>");
if (mDocHeader)
{
// Stylesheet info!
UtilityWriteCRLF("<LINK REL=\"STYLESHEET\" HREF=\"chrome://messenger/skin/mailheader.css\">");
// Make it look consistent...
UtilityWriteCRLF("<LINK REL=\"STYLESHEET\" HREF=\"chrome://global/skin\">");
}
WriteHTMLHeaders();
return NS_OK;
}
@ -139,14 +74,22 @@ nsMimeHtmlEmitter::EndHeader()
nsresult
nsMimeHtmlEmitter::StartAttachment(const char *name, const char *contentType, const char *url)
{
if (mFirst)
UtilityWrite("<HR WIDTH=\"90%\" SIZE=4>");
mFirst = PR_FALSE;
UtilityWrite("<CENTER>");
UtilityWrite("<TABLE BORDER CELLSPACING=0>");
UtilityWrite("<TABLE BORDER>");
UtilityWrite("<tr>");
UtilityWrite("<TD>");
UtilityWrite("<CENTER>");
UtilityWrite("<B>Attachment: </B>");
UtilityWrite("<DIV align=right CLASS=\"headerdisplayname\">");
UtilityWrite(name);
UtilityWrite("</DIV>");
UtilityWrite("</CENTER>");
UtilityWrite("</TD>");
@ -162,16 +105,19 @@ nsMimeHtmlEmitter::AddAttachmentField(const char *field, const char *value)
if ( (!value) || (!*value) )
return NS_OK;
// Don't output this ugly header...
if (!nsCRT::strcmp(field, HEADER_X_MOZILLA_PART_URL))
return NS_OK;
char *newValue = nsEscapeHTML(value);
UtilityWrite("<TR>");
UtilityWrite("<TD>");
UtilityWrite("<DIV align=right>");
UtilityWrite("<B>");
UtilityWrite("<DIV align=right CLASS=\"headerdisplayname\">");
UtilityWrite(field);
UtilityWrite(":");
UtilityWrite("</B>");
UtilityWrite("</DIV>");
UtilityWrite("</TD>");
UtilityWrite("<TD>");
@ -198,13 +144,6 @@ nsMimeHtmlEmitter::EndAttachment()
return NS_OK;
}
// Attachment handling routines
nsresult
nsMimeHtmlEmitter::StartBody(PRBool bodyOnly, const char *msgID, const char *outCharset)
{
return NS_OK;
}
nsresult
nsMimeHtmlEmitter::WriteBody(const char *buf, PRUint32 size, PRUint32 *amountWritten)
{

Просмотреть файл

@ -39,9 +39,6 @@ public:
virtual ~nsMimeHtmlEmitter (void);
// Header handling routines.
NS_IMETHOD StartHeader(PRBool rootMailHeader, PRBool headerOnly, const char *msgID,
const char *outCharset);
NS_IMETHOD AddHeaderField(const char *field, const char *value);
NS_IMETHOD EndHeader();
// Attachment handling routines
@ -50,10 +47,10 @@ public:
NS_IMETHOD EndAttachment();
// Body handling routines
NS_IMETHOD StartBody(PRBool bodyOnly, const char *msgID, const char *outCharset);
NS_IMETHOD WriteBody(const char *buf, PRUint32 size, PRUint32 *amountWritten);
protected:
PRBool mFirst; // Attachment flag...
};
/* this function will be used by the factory to generate an class access object....*/

Просмотреть файл

@ -65,14 +65,6 @@ nsMimeXULEmitter::nsMimeXULEmitter()
{
mCutoffValue = 3;
// Header cache...
mHeaderArray = new nsVoidArray();
// Setup array for attachments
mAttachCount = 0;
mAttachArray = new nsVoidArray();
mCurrentAttachment = nsnull;
// Vars to handle the body...
mBody = "";
mBodyStarted = PR_FALSE;
@ -92,38 +84,7 @@ nsMimeXULEmitter::nsMimeXULEmitter()
nsMimeXULEmitter::~nsMimeXULEmitter(void)
{
PRInt32 i;
if (mAttachArray)
{
for (i=0; i<mAttachArray->Count(); i++)
{
attachmentInfoType *attachInfo = (attachmentInfoType *)mAttachArray->ElementAt(i);
if (!attachInfo)
continue;
PR_FREEIF(attachInfo->contentType);
PR_FREEIF(attachInfo->displayName);
PR_FREEIF(attachInfo->urlSpec);
delete attachInfo;
}
delete mAttachArray;
}
if (mHeaderArray)
{
for (i=0; i<mHeaderArray->Count(); i++)
{
headerInfoType *headerInfo = (headerInfoType *)mHeaderArray->ElementAt(i);
if (!headerInfo)
continue;
PR_FREEIF(headerInfo->name);
PR_FREEIF(headerInfo->value);
delete headerInfo;
}
delete mHeaderArray;
}
PRInt32 i;
if (mMiscStatusArray)
{
@ -134,54 +95,27 @@ nsMimeXULEmitter::~nsMimeXULEmitter(void)
continue;
NS_IF_RELEASE(statusInfo->obj);
delete statusInfo;
delete statusInfo;
}
delete mMiscStatusArray;
}
}
// Attachment handling routines
nsresult
nsMimeXULEmitter::StartAttachment(const char *name, const char *contentType, const char *url)
{
// Ok, now we will setup the attachment info
mCurrentAttachment = (attachmentInfoType *) PR_NEWZAP(attachmentInfoType);
if ( (mCurrentAttachment) && mAttachArray)
{
++mAttachCount;
mCurrentAttachment->displayName = nsCRT::strdup(name);
mCurrentAttachment->urlSpec = nsCRT::strdup(url);
mCurrentAttachment->contentType = nsCRT::strdup(contentType);
}
return NS_OK;
}
nsresult
nsMimeXULEmitter::EndAttachment()
{
// Ok, add the attachment info to the attachment array...
if ( (mCurrentAttachment) && (mAttachArray) )
{
mAttachArray->AppendElement(mCurrentAttachment);
mCurrentAttachment = nsnull;
}
return NS_OK;
}
// Attachment handling routines
nsresult
nsMimeXULEmitter::StartBody(PRBool bodyOnly, const char *msgID, const char *outCharset)
{
// Setup everything for META tags and stylesheet info!
mBody.Append("<HTML>");
mBody.Append("<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=");
mBody.Append(outCharset);
mBody.Append("\">");
// Now for some style...
mBody.Append("<LINK REL=\"STYLESHEET\" HREF=\"chrome://messenger/skin/mailheader.css\">");
mBody.Append("<LINK REL=\"STYLESHEET\" HREF=\"chrome://global/skin\">");
mBodyStarted = PR_TRUE;
return NS_OK;
}
@ -201,9 +135,6 @@ nsMimeXULEmitter::WriteBody(const char *buf, PRUint32 size, PRUint32 *amountWrit
return NS_OK;
}
#define TEMP_FILE_PREFIX "nsMimeBody"
nsresult
nsMimeXULEmitter::EndBody()
{
@ -213,88 +144,95 @@ nsMimeXULEmitter::EndBody()
}
nsresult
nsMimeXULEmitter::AddHeaderFieldHTML(const char *field, const char *value)
nsMimeXULEmitter::BuildListOfStatusProviders()
{
if ( (!field) || (!value) )
return NS_OK;
nsresult rv;
//
// This is a check to see what the pref is for header display. If
// We should only output stuff that corresponds with that setting.
//
if (!EmitThisHeaderForPrefSetting(mHeaderDisplayType, field))
return NS_OK;
// enumerate the registry subkeys
nsRegistryKey key;
nsCOMPtr<nsIEnumerator> components;
miscStatusType *newInfo = nsnull;
char *newValue = nsEscapeHTML(value);
if (!newValue)
return NS_OK;
UtilityWrite("<TR>");
UtilityWrite("<td>");
UtilityWrite("<div align=right>");
UtilityWrite("<B>");
// Here is where we are going to try to L10N the tagName so we will always
// get a field name next to an emitted header value. Note: Default will always
// be the name of the header itself.
//
nsCAutoString newTagName(field);
newTagName.CompressWhitespace(PR_TRUE, PR_TRUE);
newTagName.ToUpperCase();
char *l10nTagName = LocalizeHeaderName((const char *) newTagName, field);
if ( (!l10nTagName) || (!*l10nTagName) )
UtilityWrite(field);
else
NS_WITH_SERVICE(nsIRegistry, registry, NS_REGISTRY_PROGID, &rv);
if (NS_FAILED(rv))
return rv;
rv = registry->OpenWellKnownRegistry(nsIRegistry::ApplicationComponentRegistry);
if (NS_FAILED(rv))
return rv;
rv = registry->GetSubtree(nsIRegistry::Common, NS_IMIME_MISC_STATUS_KEY, &key);
if (NS_FAILED(rv))
return rv;
rv = registry->EnumerateSubtrees(key, getter_AddRefs(components));
if (NS_FAILED(rv))
return rv;
// go ahead and enumerate through.
nsCAutoString actualProgID;
rv = components->First();
while (NS_SUCCEEDED(rv) && (NS_OK != components->IsDone()))
{
UtilityWrite(l10nTagName);
PR_FREEIF(l10nTagName);
nsCOMPtr<nsISupports> base;
rv = components->CurrentItem(getter_AddRefs(base));
if (NS_FAILED(rv))
return rv;
nsCOMPtr<nsIRegistryNode> node;
node = do_QueryInterface(base, &rv);
if (NS_FAILED(rv))
return rv;
nsXPIDLCString name;
rv = node->GetName(getter_Copies(name));
if (NS_FAILED(rv))
return rv;
actualProgID = NS_IMIME_MISC_STATUS_KEY;
actualProgID.Append(name);
// now we've got the PROGID, let's add it to the list...
newInfo = (miscStatusType *)PR_NEWZAP(miscStatusType);
if (newInfo)
{
newInfo->obj = GetStatusObjForProgID(actualProgID);
if (newInfo->obj)
{
newInfo->progID = actualProgID;
mMiscStatusArray->AppendElement(newInfo);
}
}
rv = components->Next();
}
// Now write out the actual value itself and move on!
//
UtilityWrite(":");
UtilityWrite("</B>");
UtilityWrite("</div>");
UtilityWrite("</td>");
UtilityWrite("<td>");
UtilityWrite(newValue);
UtilityWrite("</td>");
UtilityWrite("</TR>");
PR_FREEIF(newValue);
registry->Close();
return NS_OK;
}
//
// Find a cached header! Note: Do NOT free this value!
//
char *
nsMimeXULEmitter::GetHeaderValue(const char *aHeaderName)
nsIMimeMiscStatus *
nsMimeXULEmitter::GetStatusObjForProgID(nsCString aProgID)
{
PRInt32 i;
char *retVal = nsnull;
nsresult rv = NS_OK;
nsISupports *obj = nsnull;
if (!mHeaderArray)
NS_WITH_SERVICE(nsIComponentManager, comMgr, kComponentManagerCID, &rv);
if (NS_FAILED(rv))
return nsnull;
nsCID cid;
rv = comMgr->ProgIDToCLSID(aProgID, &cid);
if (NS_FAILED(rv))
return nsnull;
for (i=0; i<mHeaderArray->Count(); i++)
{
headerInfoType *headerInfo = (headerInfoType *)mHeaderArray->ElementAt(i);
if ( (!headerInfo) || (!headerInfo->name) || (!(*headerInfo->name)) )
continue;
if (!nsCRT::strcasecmp(aHeaderName, headerInfo->name))
{
retVal = headerInfo->value;
break;
}
}
return retVal;
rv = comMgr->CreateInstance(cid, nsnull, NS_GET_IID(nsIMimeMiscStatus), (void**)&obj);
if (NS_FAILED(rv))
return nsnull;
else
return (nsIMimeMiscStatus *)obj;
}
//////////////////////////////////////////////////////////////////////////////
@ -310,24 +248,11 @@ nsMimeXULEmitter::GetHeaderValue(const char *aHeaderName)
// display. This will include style sheet information, etc...
//
nsresult
nsMimeXULEmitter::WriteXULHeader(const char *msgID)
nsMimeXULEmitter::WriteXULHeader()
{
if ( (!msgID) || (!*msgID) )
msgID = "none";
char *newValue = nsEscapeHTML(msgID);
if (!newValue)
return NS_ERROR_OUT_OF_MEMORY;
UtilityWriteCRLF("<?xml version=\"1.0\"?>");
UtilityWriteCRLF("<?xml-stylesheet href=\"chrome://messenger/skin/mailheader.css\" type=\"text/css\"?>");
if (mHeaderDisplayType == nsMimeHeaderDisplayTypes::MicroHeaders)
UtilityWriteCRLF("<?xml-stylesheet href=\"chrome://messenger/skin/mailheader-micro.css\" type=\"text/css\"?>");
else if (mHeaderDisplayType == nsMimeHeaderDisplayTypes::NormalHeaders)
UtilityWriteCRLF("<?xml-stylesheet href=\"chrome://messenger/skin/mailheader-normal.css\" type=\"text/css\"?>");
else /* AllHeaders */
UtilityWriteCRLF("<?xml-stylesheet href=\"chrome://messenger/skin/mailheader-all.css\" type=\"text/css\"?>");
// Make it look consistent...
UtilityWriteCRLF("<?xml-stylesheet href=\"chrome://global/skin/\" type=\"text/css\"?>");
@ -341,12 +266,6 @@ nsMimeXULEmitter::WriteXULHeader(const char *msgID)
DoWindowStatusProcessing();
UtilityWriteCRLF("align=\"vertical\" flex=\"1\"> ");
// Output the message ID to make it query-able via the DOM
UtilityWrite("<message id=\"");
UtilityWrite(newValue);
PR_FREEIF(newValue);
UtilityWriteCRLF("\"/>");
// Now, the JavaScript...
UtilityWriteCRLF("<html:script language=\"javascript\" src=\"chrome://messenger/content/attach.js\"/>");
UtilityWriteCRLF("<html:script language=\"javascript\" src=\"chrome://messenger/content/mime.js\"/>");
@ -355,30 +274,6 @@ nsMimeXULEmitter::WriteXULHeader(const char *msgID)
return NS_OK;
}
//
// This is called at the start of the header block for all header information in ANY
// AND ALL MESSAGES (yes, quoted, attached, etc...) So, we need to handle these differently
// if they are the rood message as opposed to quoted message. If rootMailHeader is set to
// PR_TRUE, this is the root document, else it is a header in the body somewhere
//
nsresult
nsMimeXULEmitter::StartHeader(PRBool rootMailHeader, PRBool headerOnly, const char *msgID,
const char *outCharset)
{
mDocHeader = rootMailHeader;
if (!mDocHeader)
{
UtilityWriteCRLF("<BLOCKQUOTE><table BORDER=0 BGCOLOR=\"#CCCCCC\" >");
}
else
{
WriteXULHeader(msgID);
}
return NS_OK;
}
nsresult
nsMimeXULEmitter::DoSpecialSenderProcessing(const char *field, const char *value)
{
@ -393,46 +288,22 @@ nsMimeXULEmitter::DoSpecialSenderProcessing(const char *field, const char *value
return rv;
}
//
// This will be called for every header field...for now, we are calling the WriteXULTag for
// each of these calls.
//
nsresult
nsMimeXULEmitter::AddHeaderField(const char *field, const char *value)
{
if ( (!field) || (!value) )
return NS_OK;
if ( (mDocHeader) && (!nsCRT::strcmp(field, HEADER_FROM)) )
DoSpecialSenderProcessing(field, value);
if (!mDocHeader)
return AddHeaderFieldHTML(field, value);
else
{
// This is the main header so we do caching for XUL later!
// Ok, now we will setup the header info for the header array!
headerInfoType *ptr = (headerInfoType *) PR_NEWZAP(headerInfoType);
if ( (ptr) && mHeaderArray)
{
ptr->name = nsCRT::strdup(field);
ptr->value = nsCRT::strdup(value);
mHeaderArray->AppendElement(ptr);
}
return NS_OK;
}
}
//
// This finalizes the header field being parsed.
//
nsresult
nsMimeXULEmitter::EndHeader()
{
//
// If this is NOT the mail messages's header, then we need to write
// out the contents of the headers in HTML form.
//
if (!mDocHeader)
UtilityWriteCRLF("</TABLE></BLOCKQUOTE>");
{
WriteHTMLHeaders();
return NS_OK;
}
// Nothing to do in the case of the actual Envelope. This will be done
// on Complete().
@ -449,6 +320,9 @@ nsMimeXULEmitter::EndHeader()
nsresult
nsMimeXULEmitter::Complete()
{
// First the top of the document...
WriteXULHeader();
// Start off the header as a toolbox!
UtilityWriteCRLF("<toolbox>");
@ -474,6 +348,18 @@ nsMimeXULEmitter::Complete()
return nsMimeBaseEmitter::Complete();
}
//
// This will be called for every header field regardless if it is in an
// internal body or the outer message. If it is the
//
NS_IMETHODIMP
nsMimeXULEmitter::AddHeaderField(const char *field, const char *value)
{
if (mDocHeader)
DoSpecialSenderProcessing(field, value);
return nsMimeBaseEmitter::AddHeaderField(field, value);
}
nsresult
nsMimeXULEmitter::DumpAttachmentMenu()
@ -628,12 +514,12 @@ nsMimeXULEmitter::DumpBody()
{
// Now we will write out the XUL/IFRAME line for the mBody
//
// remove nsMimePlatformFileToURL?
UtilityWrite("<html:iframe id=\"mail-body-frame\" type=\"content-primary\" src=\"");
UtilityWrite("data:text/html;base64,");
char *encoded = PL_Base64Encode(mBody, 0, nsnull);
if (!encoded)
return NS_ERROR_OUT_OF_MEMORY;
UtilityWrite(encoded);
PR_Free(encoded);
UtilityWriteCRLF("\" border=\"0\" scrolling=\"auto\" resize=\"yes\" width=\"100%\" flex=\"1\"/>");
@ -643,7 +529,7 @@ nsMimeXULEmitter::DumpBody()
nsresult
nsMimeXULEmitter::OutputGenericHeader(const char *aHeaderVal)
{
char *val = GetHeaderValue(aHeaderVal);
char *val = GetHeaderValue(aHeaderVal, mHeaderArray);
nsresult rv;
if (val)
@ -679,7 +565,7 @@ nsMimeXULEmitter::DumpSubjectFromDate()
UtilityWriteCRLF("<spring flex=\"1\"/>");
// Now the addbook and attachment icons need to be displayed
DumpAddBookIcon(GetHeaderValue(HEADER_FROM));
DumpAddBookIcon(GetHeaderValue(HEADER_FROM, mHeaderArray));
DumpAttachmentMenu();
UtilityWriteCRLF("<spring flex=\"1\"/>");
@ -694,10 +580,10 @@ nsMimeXULEmitter::DumpSubjectFromDate()
nsresult
nsMimeXULEmitter::DumpToCC()
{
char * toField = GetHeaderValue(HEADER_TO);
char * ccField = GetHeaderValue(HEADER_CC);
char * bccField = GetHeaderValue(HEADER_BCC);
char * newsgroupField = GetHeaderValue(HEADER_NEWSGROUPS);
char * toField = GetHeaderValue(HEADER_TO, mHeaderArray);
char * ccField = GetHeaderValue(HEADER_CC, mHeaderArray);
char * bccField = GetHeaderValue(HEADER_BCC, mHeaderArray);
char * newsgroupField = GetHeaderValue(HEADER_NEWSGROUPS, mHeaderArray);
// only dump these fields if we have at least one of them! When displaying news
// messages that didn't have a to or cc field, we'd always get an empty box
@ -723,12 +609,12 @@ nsresult
nsMimeXULEmitter::DumpRestOfHeaders()
{
PRInt32 i;
if (mHeaderDisplayType != nsMimeHeaderDisplayTypes::AllHeaders)
{
// For now, lets advertise the fact that 5.0 sent this message.
char *userAgent = nsMimeXULEmitter::GetHeaderValue(HEADER_USER_AGENT);
char *userAgent = nsMimeXULEmitter::GetHeaderValue(HEADER_USER_AGENT, mHeaderArray);
if (userAgent)
{
char *compVal = "Mozilla 5.0";
@ -743,36 +629,34 @@ nsMimeXULEmitter::DumpRestOfHeaders()
UtilityWriteCRLF("</toolbar>");
}
}
return NS_OK;
}
UtilityWriteCRLF("<toolbar>");
UtilityWriteCRLF("<box name=\"header-part3\" align=\"vertical\" flex=\"1\">");
for (i=0; i<mHeaderArray->Count(); i++)
{
headerInfoType *headerInfo = (headerInfoType *)mHeaderArray->ElementAt(i);
if ( (!headerInfo) || (!headerInfo->name) || (!(*headerInfo->name)) ||
(!headerInfo->value) || (!(*headerInfo->value)))
continue;
UtilityWriteCRLF("<toolbar>");
UtilityWriteCRLF("<box name=\"header-part3\" align=\"vertical\" flex=\"1\">");
for (i=0; i<mHeaderArray->Count(); i++)
{
headerInfoType *headerInfo = (headerInfoType *)mHeaderArray->ElementAt(i);
if ( (!headerInfo) || (!headerInfo->name) || (!(*headerInfo->name)) ||
(!headerInfo->value) || (!(*headerInfo->value)))
continue;
if ( (!nsCRT::strcasecmp(HEADER_SUBJECT, headerInfo->name)) ||
(!nsCRT::strcasecmp(HEADER_DATE, headerInfo->name)) ||
(!nsCRT::strcasecmp(HEADER_FROM, headerInfo->name)) ||
(!nsCRT::strcasecmp(HEADER_TO, headerInfo->name)) ||
(!nsCRT::strcasecmp(HEADER_CC, headerInfo->name)) )
continue;
UtilityWriteCRLF("<box>");
WriteXULTag(headerInfo->name, headerInfo->value);
UtilityWriteCRLF("</box>");
}
if ( (!nsCRT::strcasecmp(HEADER_SUBJECT, headerInfo->name)) ||
(!nsCRT::strcasecmp(HEADER_DATE, headerInfo->name)) ||
(!nsCRT::strcasecmp(HEADER_FROM, headerInfo->name)) ||
(!nsCRT::strcasecmp(HEADER_TO, headerInfo->name)) ||
(!nsCRT::strcasecmp(HEADER_CC, headerInfo->name)) )
continue;
UtilityWriteCRLF("<box>");
WriteXULTag(headerInfo->name, headerInfo->value);
UtilityWriteCRLF("</box>");
}
UtilityWriteCRLF("</box>");
UtilityWriteCRLF("</toolbar>");
return NS_OK;
}
@ -895,7 +779,6 @@ nsMimeXULEmitter::WriteMiscXULTag(const char *tagName, const char *value)
{
UtilityWrite(value);
}
////
UtilityWriteCRLF("</html:td>");
@ -1119,153 +1002,3 @@ nsMimeXULEmitter::ProcessSingleEmailEntry(const char *curHeader, char *curName,
return NS_OK;
}
nsresult
nsMimeXULEmitter::BuildListOfStatusProviders()
{
nsresult rv;
// enumerate the registry subkeys
nsRegistryKey key;
nsCOMPtr<nsIEnumerator> components;
miscStatusType *newInfo = nsnull;
NS_WITH_SERVICE(nsIRegistry, registry, NS_REGISTRY_PROGID, &rv);
if (NS_FAILED(rv))
return rv;
rv = registry->OpenWellKnownRegistry(nsIRegistry::ApplicationComponentRegistry);
if (NS_FAILED(rv))
return rv;
rv = registry->GetSubtree(nsIRegistry::Common, NS_IMIME_MISC_STATUS_KEY, &key);
if (NS_FAILED(rv))
return rv;
rv = registry->EnumerateSubtrees(key, getter_AddRefs(components));
if (NS_FAILED(rv))
return rv;
// go ahead and enumerate through.
nsCAutoString actualProgID;
rv = components->First();
while (NS_SUCCEEDED(rv) && (NS_OK != components->IsDone()))
{
nsCOMPtr<nsISupports> base;
rv = components->CurrentItem(getter_AddRefs(base));
if (NS_FAILED(rv))
return rv;
nsCOMPtr<nsIRegistryNode> node;
node = do_QueryInterface(base, &rv);
if (NS_FAILED(rv))
return rv;
nsXPIDLCString name;
rv = node->GetName(getter_Copies(name));
if (NS_FAILED(rv))
return rv;
actualProgID = NS_IMIME_MISC_STATUS_KEY;
actualProgID.Append(name);
// now we've got the PROGID, let's add it to the list...
newInfo = (miscStatusType *)PR_NEWZAP(miscStatusType);
if (newInfo)
{
newInfo->obj = GetStatusObjForProgID(actualProgID);
if (newInfo->obj)
{
newInfo->progID = actualProgID;
mMiscStatusArray->AppendElement(newInfo);
}
}
rv = components->Next();
}
registry->Close();
return NS_OK;
}
nsIMimeMiscStatus *
nsMimeXULEmitter::GetStatusObjForProgID(nsCString aProgID)
{
nsresult rv = NS_OK;
nsISupports *obj = nsnull;
NS_WITH_SERVICE(nsIComponentManager, comMgr, kComponentManagerCID, &rv);
if (NS_FAILED(rv))
return nsnull;
nsCID cid;
rv = comMgr->ProgIDToCLSID(aProgID, &cid);
if (NS_FAILED(rv))
return nsnull;
rv = comMgr->CreateInstance(cid, nsnull, NS_GET_IID(nsIMimeMiscStatus), (void**)&obj);
if (NS_FAILED(rv))
return nsnull;
else
return (nsIMimeMiscStatus *)obj;
}
NS_IMETHODIMP
nsMimeXULEmitter::Write(const char *buf, PRUint32 size, PRUint32 *amountWritten)
{
unsigned int written = 0;
PRUint32 rc = 0;
PRUint32 needToWrite;
//
// Make sure that the buffer we are "pushing" into has enough room
// for the write operation. If not, we have to buffer, return, and get
// it on the next time through
//
*amountWritten = 0;
needToWrite = mBufferMgr->GetSize();
// First, handle any old buffer data...
if (needToWrite > 0)
{
rc += mOutStream->Write(mBufferMgr->GetBuffer(),
needToWrite, &written);
mTotalWritten += written;
mBufferMgr->ReduceBuffer(written);
*amountWritten = written;
// if we couldn't write all the old data, buffer the new data
// and return
if (mBufferMgr->GetSize() > 0)
{
mBufferMgr->IncreaseBuffer(buf, size);
return NS_OK;
}
}
// if we get here, we are dealing with new data...try to write
// and then do the right thing...
//
// Note: if the body has been started, we shouldn't write to the
// output stream, but rather, just append to the body buffer.
//
if (mBodyStarted)
{
mBody.Append(buf, size);
rc = size;
written = size;
}
else
rc = mOutStream->Write(buf, size, &written);
*amountWritten = written;
mTotalWritten += written;
if (written < size)
mBufferMgr->IncreaseBuffer(buf+written, (size-written));
return rc;
}

Просмотреть файл

@ -37,19 +37,6 @@
#include "nsIMsgHeaderParser.h"
#include "nsCOMPtr.h"
//
// Used for keeping track of the attachment information...
//
typedef struct {
char *displayName;
char *urlSpec;
char *contentType;
} attachmentInfoType;
typedef struct {
char *name;
char *value;
} headerInfoType;
typedef struct {
nsString progID;
@ -61,30 +48,22 @@ public:
nsMimeXULEmitter ();
virtual ~nsMimeXULEmitter (void);
NS_IMETHOD Complete();
// Header handling routines.
NS_IMETHOD StartHeader(PRBool rootMailHeader, PRBool headerOnly, const char *msgID,
const char *outCharset);
// Header handling output routines.
NS_IMETHOD AddHeaderField(const char *field, const char *value);
NS_IMETHOD EndHeader();
NS_IMETHOD AddHeaderFieldHTML(const char *field, const char *value);
// Attachment handling routines
NS_IMETHOD StartAttachment(const char *name, const char *contentType, const char *url);
NS_IMETHOD EndAttachment();
// Body handling routines
NS_IMETHOD StartBody(PRBool bodyOnly, const char *msgID, const char *outCharset);
NS_IMETHOD WriteBody(const char *buf, PRUint32 size, PRUint32 *amountWritten);
NS_IMETHOD EndBody();
// Generic write routine. This is necessary for output that
// libmime needs to pass through without any particular parsing
// involved (i.e. decoded images, HTML Body Text, etc...
NS_IMETHOD Write(const char *buf, PRUint32 size, PRUint32 *amountWritten);
// Complete() the emitter operation.
NS_IMETHOD Complete();
NS_IMETHOD WriteXULHeader(const char *msgID);
//
// XUL Specific Output methods
//
NS_IMETHOD WriteXULHeader();
NS_IMETHOD WriteXULTag(const char *tagName, const char *value);
NS_IMETHOD WriteMiscXULTag(const char *tagName, const char *value);
NS_IMETHOD WriteEmailAddrXULTag(const char *tagName, const char *value);
@ -92,7 +71,6 @@ public:
nsresult ProcessSingleEmailEntry(const char *curHeader, char *curName, char *curAddress);
nsresult WriteXULTagPrefix(const char *tagName, const char *value);
nsresult WriteXULTagPostfix(const char *tagName, const char *value);
nsresult OhTheHumanityCleanupTempFileHack();
// For Interesting XUL output!
nsresult DumpAttachmentMenu();
@ -105,29 +83,18 @@ public:
// For storing recipient info in the history database...
nsresult DoSpecialSenderProcessing(const char *field, const char *value);
// For per-email address status processing...
nsresult DoGlobalStatusProcessing();
nsresult DoWindowStatusProcessing();
nsresult BuildListOfStatusProviders();
nsIMimeMiscStatus *GetStatusObjForProgID(nsCString aProgID);
char *GetHeaderValue(const char *aHeaderName);
protected:
PRInt32 mCutoffValue;
// For attachment processing...
PRInt32 mAttachCount;
nsVoidArray *mAttachArray;
attachmentInfoType *mCurrentAttachment;
// For body caching...
PRBool mBodyStarted;
nsCString mBody;
// For header caching...
nsVoidArray *mHeaderArray;
// For fancy per-email status!
nsVoidArray *mMiscStatusArray;
nsCOMPtr<nsIMsgHeaderParser> mHeaderParser;
};

Просмотреть файл

@ -86,12 +86,6 @@ nsMimeXmlEmitter::WriteXMLHeader(const char *msgID)
UtilityWrite("<?xml version=\"1.0\"?>");
UtilityWriteCRLF("<?xml-stylesheet href=\"chrome://messenger/skin/mailheader.css\" type=\"text/css\"?>");
if (mHeaderDisplayType == nsMimeHeaderDisplayTypes::MicroHeaders)
UtilityWrite("<?xml-stylesheet href=\"chrome://messenger/skin/mailheader-micro.css\" type=\"text/css\"?>");
else if (mHeaderDisplayType == nsMimeHeaderDisplayTypes::NormalHeaders)
UtilityWrite("<?xml-stylesheet href=\"chrome://messenger/skin/mailheader-normal.css\" type=\"text/css\"?>");
else /* AllHeaders */
UtilityWrite("<?xml-stylesheet href=\"chrome://messenger/skin/mailheader-all.css\" type=\"text/css\"?>");
UtilityWrite("<message id=\"");
UtilityWrite(newValue);

Просмотреть файл

@ -77,6 +77,9 @@ static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
static NS_DEFINE_IID(kIPrefIID, NS_IPREF_IID);
static NS_DEFINE_CID(kPrefCID, NS_PREF_CID);
// Text Scanning...
static NS_DEFINE_CID(kTXTToHTMLConvCID, MOZITXTTOHTMLCONV_CID);
extern "C" char *MIME_DecodeMimePartIIStr(const char *header, char *charset);
static MimeHeadersState MIME_HeaderType;
@ -367,7 +370,8 @@ NotifyEmittersOfAttachmentList(MimeDisplayOptions *opt,
if (spec)
nsAllocator::Free(spec);
if (opt->format_out == nsMimeOutput::nsMimeMessageQuoting)
if ( (opt->format_out == nsMimeOutput::nsMimeMessageQuoting) ||
(opt->format_out == nsMimeOutput::nsMimeMessagePrintOutput) )
{
mimeEmitterAddAttachmentField(opt, HEADER_CONTENT_DESCRIPTION, tmp->description);
mimeEmitterAddAttachmentField(opt, HEADER_CONTENT_TYPE, tmp->real_type);
@ -625,6 +629,14 @@ mime_display_stream_complete (nsMIMESession *stream)
int status;
PRBool abortNow = PR_FALSE;
// Release the prefs service
if ( (obj->options) && (obj->options->prefs) )
nsServiceManager::ReleaseService(kPrefCID, obj->options->prefs);
// Release the conversion object
if ( (obj->options) && (obj->options->conv) )
NS_RELEASE(obj->options->conv);
if ((obj->options) && (obj->options->headers == MimeHeadersOnly))
abortNow = PR_TRUE;
@ -661,11 +673,7 @@ mime_display_stream_complete (nsMIMESession *stream)
msd->options = 0;
}
}
// Release the prefs service
if ( (obj) && (obj->options) && (obj->options->prefs) )
nsServiceManager::ReleaseService(kPrefCID, obj->options->prefs);
if (msd->headers)
MimeHeaders_free (msd->headers);
@ -1047,6 +1055,16 @@ GetPrefServiceManager(MimeDisplayOptions *opt)
return opt->prefs;
}
// Get the text converter...
mozITXTToHTMLConv *
GetTextConverter(MimeDisplayOptions *opt)
{
if (!opt)
return nsnull;
return opt->conv;
}
////////////////////////////////////////////////////////////////
// Bridge routines for new stream converter XP-COM interface
////////////////////////////////////////////////////////////////
@ -1111,6 +1129,17 @@ mime_bridge_create_display_stream(
return nsnull;
}
// Need the text converter...
rv = nsComponentManager::CreateInstance(kTXTToHTMLConvCID,
NULL, nsCOMTypeInfo<mozITXTToHTMLConv>::GetIID(),
(void **)&(msd->options->conv));
if (NS_FAILED(rv))
{
nsServiceManager::ReleaseService(kPrefCID, msd->options->prefs);
PR_FREEIF(msd);
return nsnull;
}
//
// Set the defaults, based on the context, and the output-type.
//
@ -1126,7 +1155,8 @@ mime_bridge_create_display_stream(
msd->options->fancy_links_p = PR_TRUE;
break;
case nsMimeOutput::nsMimeMessageQuoting: // all HTML quoted output
case nsMimeOutput::nsMimeMessageQuoting: // all HTML quoted/printed output
case nsMimeOutput::nsMimeMessagePrintOutput:
msd->options->fancy_headers_p = PR_TRUE;
msd->options->fancy_links_p = PR_TRUE;
break;
@ -1193,7 +1223,8 @@ mime_bridge_create_display_stream(
//
// For quoting, don't mess with citatation...
if (format_out == nsMimeOutput::nsMimeMessageQuoting || format_out == nsMimeOutput::nsMimeMessageBodyQuoting)
if ( format_out == nsMimeOutput::nsMimeMessageQuoting || format_out == nsMimeOutput::nsMimeMessageBodyQuoting ||
format_out == nsMimeOutput::nsMimeMessagePrintOutput )
{
msd->options->charset_conversion_fn = mime_insert_html_convert_charset;
msd->options->dont_touch_citations_p = PR_TRUE;

Просмотреть файл

@ -147,6 +147,9 @@ extern "C" nsresult mimeEmitterStartHeader(MimeDisplayOptions *opt, PRBool r
/* To Get the connnection to prefs service manager */
extern "C" nsIPref *GetPrefServiceManager(MimeDisplayOptions *opt);
// Get the text converter...
mozITXTToHTMLConv *GetTextConverter(MimeDisplayOptions *opt);
/* This is the next generation string retrieval call */
extern "C" char *MimeGetStringByID(PRInt32 stringID);

Просмотреть файл

@ -30,9 +30,9 @@
#include "nsMimeStringResources.h"
#include "nsIPref.h"
#include "nsIServiceManager.h"
#include "mimemoz2.h"
static NS_DEFINE_CID(kPrefCID, NS_PREF_CID);
static NS_DEFINE_CID(kTXTToHTMLConvCID, MOZITXTTOHTMLCONV_CID);
#define MIME_SUPERCLASS mimeInlineTextClass
MimeDefClass(MimeInlineTextPlainFlowed, MimeInlineTextPlainFlowedClass,
@ -275,26 +275,23 @@ MimeInlineTextPlainFlowed_parse_line (char *line, PRInt32 length, MimeObject *ob
linep++;
}
}
// If we have been told not to mess with this text, then don't do this search!
PRBool skipScanning = (obj->options && obj->options->force_user_charset) ||
mozITXTToHTMLConv *conv = GetTextConverter(obj->options);
// If we have been told not to mess with this text, then don't do this search..or if the converter
// is null for some reason
PRBool skipScanning = (!conv) ||
(obj->options && obj->options->force_user_charset) ||
(obj->options && (obj->options->format_out == nsMimeOutput::nsMimeMessageQuoting)) ||
(obj->options && (obj->options->format_out == nsMimeOutput::nsMimeMessageBodyQuoting));
if (!skipScanning)
{
nsCOMPtr<mozITXTToHTMLConv> conv;
nsresult rv = nsComponentManager::CreateInstance(kTXTToHTMLConvCID,
NULL, nsCOMTypeInfo<mozITXTToHTMLConv>::GetIID(),
(void **) getter_AddRefs(conv));
if (NS_FAILED(rv))
return -1;
//XXX I18N Converting char* to PRUnichar*
nsString strline(linep, (length - (linep - line)) );
PRUnichar* wresult;
rv = conv->ScanTXT(strline.GetUnicode(),
nsresult rv = conv->ScanTXT(strline.GetUnicode(),
obj->options->dont_touch_citations_p /*XXX This is pref abuse.
ScanTXT does nothing with citations. Add prefs.*/
? conv->kURLs : ~PRUint32(0),

Просмотреть файл

@ -30,6 +30,7 @@
#include "nsIComponentManager.h"
#include "nsString.h"
#include "nsMimeStringResources.h"
#include "mimemoz2.h"
static NS_DEFINE_CID(kTXTToHTMLConvCID, MOZITXTTOHTMLCONV_CID);
@ -150,24 +151,20 @@ MimeInlineTextPlain_parse_line (char *line, PRInt32 length, MimeObject *obj)
*/
*obj->obuffer = 0;
mozITXTToHTMLConv *conv = GetTextConverter(obj->options);
// If we have been told not to mess with this text, then don't do this search!
PRBool skipScanning = (obj->options && obj->options->force_user_charset) ||
PRBool skipScanning = (!conv) ||
(obj->options && obj->options->force_user_charset) ||
(obj->options && (obj->options->format_out == nsMimeOutput::nsMimeMessageQuoting)) ||
(obj->options && (obj->options->format_out == nsMimeOutput::nsMimeMessageBodyQuoting));
if (!skipScanning)
{
nsCOMPtr<mozITXTToHTMLConv> conv;
nsresult rv = nsComponentManager::CreateInstance(kTXTToHTMLConvCID,
NULL, nsCOMTypeInfo<mozITXTToHTMLConv>::GetIID(),
(void **) getter_AddRefs(conv));
if (NS_FAILED(rv))
return -1;
nsString strline(line, length);
PRUnichar* wresult;
rv = conv->ScanTXT(strline.GetUnicode(),
nsresult rv = conv->ScanTXT(strline.GetUnicode(),
obj->options->dont_touch_citations_p /*XXX This is pref abuse.
ScanTXT does nothing with citations. Add prefs.*/
? conv->kURLs : ~PRUint32(0),

Просмотреть файл

@ -31,6 +31,7 @@
#include "nsMailHeaders.h"
#include "nsIMimeStreamConverter.h"
#include "nsIPref.h"
#include "mozITXTToHTMLConv.h"
#define MIME_DRAFTS
@ -140,6 +141,7 @@ typedef char *(*MimeHTMLGeneratorFunction) (const char *data, void *closure,
struct MimeDisplayOptions
{
mozITXTToHTMLConv *conv; // For text conversion...
nsIPref *prefs; /* Connnection to prefs service manager */
nsMimeOutputType format_out; // The format out type

Просмотреть файл

@ -245,6 +245,7 @@ nsStreamConverter::DetermineOutputFormat(const char *url, nsMimeOutputType *aNe
char *ptr3 = PL_strcasestr ("quote", (header+lenOfHeader));
char *ptr4 = PL_strcasestr ("quotebody", (header+lenOfHeader));
char *ptr5 = PL_strcasestr ("none", (header+lenOfHeader));
char *ptr6 = PL_strcasestr ("print", (header+lenOfHeader));
if (ptr5)
{
PR_FREEIF(mOutputFormat);
@ -269,6 +270,12 @@ nsStreamConverter::DetermineOutputFormat(const char *url, nsMimeOutputType *aNe
mOutputFormat = nsCRT::strdup("text/html");
*aNewType = nsMimeOutput::nsMimeMessageBodyQuoting;
}
else if (ptr6)
{
PR_FREEIF(mOutputFormat);
mOutputFormat = nsCRT::strdup("text/html");
*aNewType = nsMimeOutput::nsMimeMessagePrintOutput;
}
}
else
{
@ -397,6 +404,7 @@ NS_IMETHODIMP nsStreamConverter::Init(nsIURI *aURI, nsIStreamListener * aOutList
case nsMimeOutput::nsMimeMessageQuoting: // all HTML quoted output
case nsMimeOutput::nsMimeMessageBodyQuoting: // only HTML body quoted output
case nsMimeOutput::nsMimeMessagePrintOutput: // all Printing output
PR_FREEIF(mOutputFormat);
mOutputFormat = nsCRT::strdup("text/html");
break;

Просмотреть файл

@ -192,6 +192,7 @@ public:
{
if ((mOutFormat == nsMimeOutput::nsMimeMessageSplitDisplay) ||
(mOutFormat == nsMimeOutput::nsMimeMessageBodyDisplay) ||
(mOutFormat == nsMimeOutput::nsMimeMessagePrintOutput) ||
(mOutFormat == nsMimeOutput::nsMimeMessageQuoting))
{
char *note = "\n<center><hr WIDTH=\"90%\"><br><b>Anything after the above horizontal line is diagnostic output<br>and is not part of the HTML stream!</b></center><pre>\n";
@ -498,7 +499,7 @@ DoRFC822toHTMLConversion(char *filename, int numArgs)
if (numArgs >= 3)
outFormat = nsMimeOutput::nsMimeMessageXULDisplay;
else
outFormat = nsMimeOutput::nsMimeMessageQuoting;
outFormat = nsMimeOutput::nsMimeMessagePrintOutput;
char *opts = PL_strchr(filename, '?');
char save;
@ -621,7 +622,7 @@ DoFormattingOnly(char *filename)
nsMimeOutputType outFormat;
char *contentType = nsnull;
outFormat = nsMimeOutput::nsMimeMessageQuoting;
outFormat = nsMimeOutput::nsMimeMessagePrintOutput;
char *opts = PL_strchr(filename, '?');
char save;