Bug 553540 - need new flag to nsPlainTextSerializer to support delsp=yes (RFC 3676). r=laurent sr=jst

This commit is contained in:
Makoto Kato 2010-04-02 18:21:40 +09:00
Родитель d29a3fb127
Коммит 681aec8428
4 изменённых файлов: 105 добавлений и 9 удалений

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

@ -61,7 +61,7 @@ interface nsIDocumentEncoderNodeFixup : nsISupports
nsIDOMNode fixupNode(in nsIDOMNode aNode, out boolean aSerializeCloneKids);
};
[scriptable, uuid(196a3aee-006e-4f8f-a420-e1c1b0958a26)]
[scriptable, uuid(794a81f6-bde6-4f76-9f5e-0ea0911a2d9f)]
interface nsIDocumentEncoder : nsISupports
{
// Output methods flag bits. There are a frightening number of these,
@ -214,7 +214,14 @@ interface nsIDocumentEncoder : nsISupports
* This flag suppresses that behavior.
*/
const unsigned long OutputDontRewriteEncodingDeclaration = (1 << 18);
/**
* Output for delsp=yes (RFC 3676). This is used with OutputFormatFlowed
* when converting to text for mail sending.
* PlainText output only.
*/
const unsigned long OutputFormatDelSp = (1 << 19);
/**
* When using the HTML or XHTML serializer, skip elements that are not
* visible when this flag is set. Elements are not visible when they

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

@ -1411,8 +1411,10 @@ nsPlainTextSerializer::AddToLine(const PRUnichar * aLineFragment,
else {
mCurrentLine.Right(restOfLine, linelength-goodSpace);
}
// if breaker was U+0020, it has to consider for delsp=yes support
PRBool breakBySpace = mCurrentLine.CharAt(goodSpace) == ' ';
mCurrentLine.Truncate(goodSpace);
EndLine(PR_TRUE);
EndLine(PR_TRUE, breakBySpace);
mCurrentLine.Truncate();
// Space stuff new line?
if(mFlags & nsIDocumentEncoder::OutputFormatFlowed) {
@ -1450,7 +1452,7 @@ nsPlainTextSerializer::AddToLine(const PRUnichar * aLineFragment,
* preformatted.
*/
void
nsPlainTextSerializer::EndLine(PRBool aSoftlinebreak)
nsPlainTextSerializer::EndLine(PRBool aSoftlinebreak, PRBool aBreakBySpace)
{
PRUint32 currentlinelength = mCurrentLine.Length();
@ -1482,7 +1484,13 @@ nsPlainTextSerializer::EndLine(PRBool aSoftlinebreak)
// Add the soft part of the soft linebreak (RFC 2646 4.1)
// We only do this when there is no indentation since format=flowed
// lines and indentation doesn't work well together.
mCurrentLine.Append(PRUnichar(' '));
// If breaker character is ASCII space with RFC 3676 support (delsp=yes),
// add twice space.
if (mFlags & nsIDocumentEncoder::OutputFormatDelSp && aBreakBySpace)
mCurrentLine.Append(NS_LITERAL_STRING(" "));
else
mCurrentLine.Append(PRUnichar(' '));
}
if(aSoftlinebreak) {

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

@ -129,7 +129,7 @@ public:
protected:
nsresult GetAttributeValue(const nsIParserNode* node, nsIAtom* aName, nsString& aValueRet);
void AddToLine(const PRUnichar* aStringToAdd, PRInt32 aLength);
void EndLine(PRBool softlinebreak);
void EndLine(PRBool softlinebreak, PRBool aBreakBySpace = PR_FALSE);
void EnsureVerticalSpace(PRInt32 noOfRows);
void FlushLine();
void OutputQuotesAndIndent(PRBool stripTrailingSpaces=PR_FALSE);

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

@ -45,11 +45,12 @@
#include "nsServiceManagerUtils.h"
#include "nsStringGlue.h"
#include "nsParserCIID.h"
#include "nsIDocumentEncoder.h"
static NS_DEFINE_CID(kCParserCID, NS_PARSER_CID);
void
ConvertBufToPlainText(nsString &aConBuf)
ConvertBufToPlainText(nsString &aConBuf, int aFlag)
{
nsCOMPtr<nsIParser> parser = do_CreateInstance(kCParserCID);
if (parser) {
@ -59,7 +60,7 @@ ConvertBufToPlainText(nsString &aConBuf)
nsCOMPtr<nsIHTMLToTextSink> textSink(do_QueryInterface(sink));
if (textSink) {
nsAutoString convertedText;
textSink->Initialize(&convertedText, 0, 72);
textSink->Initialize(&convertedText, aFlag, 72);
parser->SetContentSink(sink);
parser->Parse(aConBuf, 0, NS_LITERAL_CSTRING("text/html"), PR_TRUE);
aConBuf = convertedText;
@ -68,13 +69,87 @@ ConvertBufToPlainText(nsString &aConBuf)
}
}
// Test for ASCII with format=flowed; delsp=yes
nsresult
TestASCIIWithFlowedDelSp()
{
nsString test;
nsString result;
test.AssignLiteral("<html><body>"
"Firefox Firefox Firefox Firefox "
"Firefox Firefox Firefox Firefox "
"Firefox Firefox Firefox Firefox"
"</body></html>");
ConvertBufToPlainText(test, nsIDocumentEncoder::OutputFormatted |
nsIDocumentEncoder::OutputCRLineBreak |
nsIDocumentEncoder::OutputLFLineBreak |
nsIDocumentEncoder::OutputFormatFlowed |
nsIDocumentEncoder::OutputFormatDelSp);
// create result case
result.AssignLiteral("Firefox Firefox Firefox Firefox "
"Firefox Firefox Firefox Firefox "
"Firefox \r\nFirefox Firefox Firefox\r\n");
if (!test.Equals(result)) {
fail("Wrong HTML to ASCII text serialization with format=flowed; delsp=yes");
return NS_ERROR_FAILURE;
}
passed("HTML to ASCII text serialization with format=flowed; delsp=yes");
return NS_OK;
}
// Test for CJK with format=flowed; delsp=yes
nsresult
TestCJKWithFlowedDelSp()
{
nsString test;
nsString result;
test.AssignLiteral("<html><body>");
for (PRUint32 i = 0; i < 40; i++) {
// Insert Kanji (U+5341)
test.Append(0x5341);
}
test.AppendLiteral("</body></html>");
ConvertBufToPlainText(test, nsIDocumentEncoder::OutputFormatted |
nsIDocumentEncoder::OutputCRLineBreak |
nsIDocumentEncoder::OutputLFLineBreak |
nsIDocumentEncoder::OutputFormatFlowed |
nsIDocumentEncoder::OutputFormatDelSp);
// create result case
for (PRUint32 i = 0; i < 36; i++) {
result.Append(0x5341);
}
result.Append(NS_LITERAL_STRING(" \r\n"));
for (PRUint32 i = 0; i < 4; i++) {
result.Append(0x5341);
}
result.Append(NS_LITERAL_STRING("\r\n"));
if (!test.Equals(result)) {
fail("Wrong HTML to CJK text serialization with format=flowed; delsp=yes");
return NS_ERROR_FAILURE;
}
passed("HTML to CJK text serialization with format=flowed; delsp=yes");
return NS_OK;
}
nsresult
TestPlainTextSerializer()
{
nsString test;
test.AppendLiteral("<html><base>base</base><head><span>span</span></head>"
"<body>body</body></html>");
ConvertBufToPlainText(test);
ConvertBufToPlainText(test, 0);
if (!test.EqualsLiteral("basespanbody")) {
fail("Wrong html to text serialization");
return NS_ERROR_FAILURE;
@ -82,6 +157,12 @@ TestPlainTextSerializer()
passed("HTML to text serialization test");
nsresult rv = TestASCIIWithFlowedDelSp();
NS_ENSURE_SUCCESS(rv, rv);
rv = TestCJKWithFlowedDelSp();
NS_ENSURE_SUCCESS(rv, rv);
// Add new tests here...
return NS_OK;
}