diff --git a/mozilla/content/base/src/nsHTMLContentSerializer.cpp b/mozilla/content/base/src/nsHTMLContentSerializer.cpp index 297026d5af2..80871d441e2 100644 --- a/mozilla/content/base/src/nsHTMLContentSerializer.cpp +++ b/mozilla/content/base/src/nsHTMLContentSerializer.cpp @@ -112,19 +112,15 @@ nsHTMLContentSerializer::Init(PRUint32 aFlags, PRUint32 aWrapColumn) if ((mFlags & nsIDocumentEncoder::OutputCRLineBreak) && (mFlags & nsIDocumentEncoder::OutputLFLineBreak)) { // Windows/mail mLineBreak.AssignWithConversion("\r\n"); - mLineBreakLen = 2; } else if (mFlags & nsIDocumentEncoder::OutputCRLineBreak) { // Mac mLineBreak.AssignWithConversion("\r"); - mLineBreakLen = 1; } else if (mFlags & nsIDocumentEncoder::OutputLFLineBreak) { // Unix/DOM mLineBreak.AssignWithConversion("\n"); - mLineBreakLen = 1; } else { mLineBreak.AssignWithConversion(NS_LINEBREAK); // Platform/default - mLineBreakLen = NS_LINEBREAK_LEN; } mPreLevel = 0; @@ -144,20 +140,14 @@ nsHTMLContentSerializer::AppendText(nsIDOMText* aText, nsresult rv; rv = AppendTextData((nsIDOMNode*)aText, aStartOffset, - aEndOffset, data); + aEndOffset, data, PR_TRUE); if (NS_FAILED(rv)) return NS_ERROR_FAILURE; if (mPreLevel || (!mDoFormat && !HasLongLines(data))) { - AppendToString(data, - data.Length(), - aStr, - PR_TRUE); + AppendToString(data, aStr); } else { - AppendToStringWrapped(data, - data.Length(), - aStr, - PR_TRUE); + AppendToStringWrapped(data, aStr, PR_FALSE); } return NS_OK; @@ -254,7 +244,7 @@ nsHTMLContentSerializer::AppendElementStart(nsIDOMElement *aElement, } if (LineBreakBeforeOpen(name, hasDirtyAttr)) { - AppendToString(mLineBreak, mLineBreakLen, aStr); + AppendToString(mLineBreak, aStr); mColPos = 0; } @@ -264,18 +254,18 @@ nsHTMLContentSerializer::AppendElementStart(nsIDOMElement *aElement, StartIndentation(name, hasDirtyAttr, aStr); - AppendToString(NS_LITERAL_STRING(kLessThan), -1, aStr); + AppendToString(NS_LITERAL_STRING(kLessThan), aStr); nsXPIDLString sharedName; name->GetUnicode(getter_Shares(sharedName)); - AppendToString(sharedName, nsCRT::strlen(sharedName), aStr); + AppendToString(sharedName, -1, aStr); SerializeAttributes(content, name, aStr); - AppendToString(NS_LITERAL_STRING(kGreaterThan), -1, aStr); + AppendToString(NS_LITERAL_STRING(kGreaterThan), aStr); if (LineBreakAfterOpen(name, hasDirtyAttr)) { - AppendToString(mLineBreak, mLineBreakLen, aStr); + AppendToString(mLineBreak, aStr); mColPos = 0; } @@ -314,18 +304,18 @@ nsHTMLContentSerializer::AppendElementEnd(nsIDOMElement *aElement, } if (LineBreakBeforeClose(name, hasDirtyAttr)) { - AppendToString(mLineBreak, mLineBreakLen, aStr); + AppendToString(mLineBreak, aStr); mColPos = 0; } EndIndentation(name, hasDirtyAttr, aStr); - AppendToString(NS_LITERAL_STRING(kEndTag), -1, aStr); + AppendToString(NS_LITERAL_STRING(kEndTag), aStr); AppendToString(sharedName, -1, aStr); - AppendToString(NS_LITERAL_STRING(kGreaterThan), -1, aStr); + AppendToString(NS_LITERAL_STRING(kGreaterThan), aStr); if (LineBreakAfterClose(name, hasDirtyAttr)) { - AppendToString(mLineBreak, mLineBreakLen, aStr); + AppendToString(mLineBreak, aStr); mColPos = 0; } @@ -345,19 +335,31 @@ nsHTMLContentSerializer::AppendToString(const PRUnichar* aStr, mColPos += length; - aOutputStr.Append(aStr); + aOutputStr.Append(aStr, length); +} + +void +nsHTMLContentSerializer::AppendToString(const PRUnichar aChar, + nsAWritableString& aOutputStr) +{ + if (mBodyOnly && !mInBody) { + return; + } + + mColPos += 1; + + aOutputStr.Append(aChar); } void nsHTMLContentSerializer::AppendToStringWrapped(const nsAReadableString& aStr, - PRInt32 aLength, nsAWritableString& aOutputStr, PRBool aTranslateEntities) { - PRInt32 length = (aLength == -1) ? aStr.Length() : aLength; + PRInt32 length = aStr.Length(); if ((mColPos + length) < mMaxColumn) { - AppendToString(aStr, length, aOutputStr, aTranslateEntities); + AppendToString(aStr, aOutputStr, aTranslateEntities); } else { nsAutoString line; @@ -377,22 +379,20 @@ nsHTMLContentSerializer::AppendToStringWrapped(const nsAReadableString& aStr, if (indx == kNotFound) { if (strOffset == 0) { - AppendToString(aStr, length, aOutputStr, aTranslateEntities); + AppendToString(aStr, aOutputStr, aTranslateEntities); } else { lineLength = length - strOffset; aStr.Right(line, lineLength); - AppendToString(line, lineLength, - aOutputStr, aTranslateEntities); + AppendToString(line, aOutputStr, aTranslateEntities); } done = PR_TRUE; } else { lineLength = indx - strOffset; aStr.Mid(line, strOffset, lineLength); - AppendToString(line, lineLength, - aOutputStr, aTranslateEntities); - AppendToString(mLineBreak, mLineBreakLen, aOutputStr); + AppendToString(line, aOutputStr, aTranslateEntities); + AppendToString(mLineBreak, aOutputStr); strOffset = indx+1; mColPos = 0; } @@ -402,7 +402,6 @@ nsHTMLContentSerializer::AppendToStringWrapped(const nsAReadableString& aStr, void nsHTMLContentSerializer::AppendToString(const nsAReadableString& aStr, - PRInt32 aLength, nsAWritableString& aOutputStr, PRBool aTranslateEntities) { @@ -411,9 +410,8 @@ nsHTMLContentSerializer::AppendToString(const nsAReadableString& aStr, } nsresult rv; - PRInt32 length = (aLength == -1) ? aStr.Length() : aLength; - mColPos += length; + mColPos += aStr.Length(); if (aTranslateEntities) { nsCOMPtr converter; diff --git a/mozilla/content/base/src/nsHTMLContentSerializer.h b/mozilla/content/base/src/nsHTMLContentSerializer.h index d6fa630095c..f1921e7db55 100644 --- a/mozilla/content/base/src/nsHTMLContentSerializer.h +++ b/mozilla/content/base/src/nsHTMLContentSerializer.h @@ -63,17 +63,17 @@ class nsHTMLContentSerializer : public nsXMLContentSerializer { void SerializeAttributes(nsIContent* aContent, nsIAtom* aTagName, nsAWritableString& aStr); - void AppendToString(const PRUnichar* aStr, - PRInt32 aLength, - nsAWritableString& aOutputStr); - void AppendToString(const nsAReadableString& aStr, - PRInt32 aLength, - nsAWritableString& aOutputStr, - PRBool aTranslateEntities = PR_FALSE); - void AppendToStringWrapped(const nsAReadableString& aStr, - PRInt32 aLength, - nsAWritableString& aOutputStr, - PRBool aTranslateEntities); + virtual void AppendToString(const PRUnichar* aStr, + PRInt32 aLength, + nsAWritableString& aOutputStr); + virtual void AppendToString(const PRUnichar aChar, + nsAWritableString& aOutputStr); + virtual void AppendToString(const nsAReadableString& aStr, + nsAWritableString& aOutputStr, + PRBool aTranslateEntities = PR_FALSE); + virtual void AppendToStringWrapped(const nsAReadableString& aStr, + nsAWritableString& aOutputStr, + PRBool aTranslateEntities); PRBool HasLongLines(const nsString& text); nsCOMPtr mParserService; @@ -92,7 +92,6 @@ class nsHTMLContentSerializer : public nsXMLContentSerializer { PRInt32 mMaxColumn; nsString mLineBreak; - PRInt32 mLineBreakLen; }; extern nsresult NS_NewHTMLContentSerializer(nsIContentSerializer** aSerializer); diff --git a/mozilla/content/base/src/nsXMLContentSerializer.cpp b/mozilla/content/base/src/nsXMLContentSerializer.cpp index 1c3dfabc67d..20feae6bfb1 100644 --- a/mozilla/content/base/src/nsXMLContentSerializer.cpp +++ b/mozilla/content/base/src/nsXMLContentSerializer.cpp @@ -70,75 +70,33 @@ nsXMLContentSerializer::Init(PRUint32 flags, PRUint32 aWrapColumn) return NS_OK; } -static PRUint16 kGTVal = 62; -static const char* kEntities[] = { - "", "", "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", "", "", - "", "", "", "", """, "", "", "", "&", "'", - "", "", "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", "", "", - "<", "", ">" -}; - -void -nsXMLContentSerializer::ReplaceCharacterEntities(nsAWritableString& aStr, - PRUint32 aOffset) -{ - nsReadingIterator done_reading; - aStr.EndReading(done_reading); - - // for each chunk of |aString|... - PRUint32 fragmentLength = 0; - PRUint32 offset = aOffset; - nsReadingIterator iter; - aStr.BeginReading(iter); - - for (iter.advance(PRInt32(offset)); - iter != done_reading; - iter.advance(PRInt32(fragmentLength))) { - fragmentLength = iter.size_forward(); - const PRUnichar* c = iter.get(); - const PRUnichar* fragmentEnd = c + fragmentLength; - - // for each character in this chunk... - for (; c < fragmentEnd; c++, offset++) { - PRUnichar val = *c; - if ((val <= kGTVal) && (kEntities[val][0] != 0)) { - aStr.Cut(offset, 1); - aStr.Insert(NS_LITERAL_STRING(kEntities[val]), offset); - aStr.EndReading(done_reading); - aStr.BeginReading(iter); - fragmentLength = offset+nsCRT::strlen(kEntities[val]); - break; - } - } - } -} - nsresult nsXMLContentSerializer::AppendTextData(nsIDOMNode* aNode, PRInt32 aStartOffset, PRInt32 aEndOffset, - nsAWritableString& aStr) + nsAWritableString& aStr, + PRBool aTranslateEntities) { nsCOMPtr content = do_QueryInterface(aNode); if (!content) return NS_ERROR_FAILURE; const nsTextFragment* frag; content->GetText(&frag); - + if (frag) { - PRInt32 length = (aEndOffset == -1) ? frag->GetLength() : aEndOffset; - length -= aStartOffset; + PRInt32 length = ((aEndOffset == -1) ? frag->GetLength() : aEndOffset) - aStartOffset; if (frag->Is2b()) { - aStr.Append(frag->Get2b()+aStartOffset, length); + AppendToString(nsLiteralString(frag->Get2b()+aStartOffset, length), + aStr, + aTranslateEntities); } else { - aStr.Append(NS_ConvertASCIItoUCS2(frag->Get1b()+aStartOffset, length)); + AppendToString(NS_ConvertASCIItoUCS2(frag->Get1b()+aStartOffset, length), + aStr, + aTranslateEntities); } } - + return NS_OK; } @@ -150,15 +108,8 @@ nsXMLContentSerializer::AppendText(nsIDOMText* aText, { NS_ENSURE_ARG(aText); - PRUint32 length = aStr.Length(); - nsresult rv; - rv = AppendTextData(aText, aStartOffset, aEndOffset, aStr); - if (NS_FAILED(rv)) return NS_ERROR_FAILURE; - - ReplaceCharacterEntities(aStr, length); - - return NS_OK; + return AppendTextData(aText, aStartOffset, aEndOffset, aStr, PR_TRUE); } NS_IMETHODIMP @@ -170,10 +121,10 @@ nsXMLContentSerializer::AppendCDATASection(nsIDOMCDATASection* aCDATASection, NS_ENSURE_ARG(aCDATASection); nsresult rv; - aStr.Append(NS_LITERAL_STRING("")); + AppendToString(NS_LITERAL_STRING("]]>"), aStr); return NS_OK; } @@ -194,13 +145,13 @@ nsXMLContentSerializer::AppendProcessingInstruction(nsIDOMProcessingInstruction* rv = aPI->GetData(data); if (NS_FAILED(rv)) return NS_ERROR_FAILURE; - aStr.Append(NS_LITERAL_STRING(" 0) { - aStr.Append(NS_LITERAL_STRING(" ")); - aStr.Append(data); + AppendToString(NS_LITERAL_STRING(" "), aStr); + AppendToString(data, aStr); } - aStr.Append(NS_LITERAL_STRING(">")); + AppendToString(NS_LITERAL_STRING(">"), aStr); return NS_OK; } @@ -218,19 +169,19 @@ nsXMLContentSerializer::AppendComment(nsIDOMComment* aComment, rv = aComment->GetData(data); if (NS_FAILED(rv)) return NS_ERROR_FAILURE; - aStr.Append(NS_LITERAL_STRING("")); + AppendToString(NS_LITERAL_STRING("-->"), aStr); return NS_OK; } @@ -252,30 +203,30 @@ nsXMLContentSerializer::AppendDoctype(nsIDOMDocumentType *aDoctype, rv = aDoctype->GetInternalSubset(publicId); if (NS_FAILED(rv)) return NS_ERROR_FAILURE; - aStr.Append(NS_LITERAL_STRING(" 0) { - aStr.Append(NS_LITERAL_STRING(" PUBLIC ")); + AppendToString(NS_LITERAL_STRING(" PUBLIC "), aStr); if (publicId.FindChar(PRUnichar('"')) == -1) { quote = PRUnichar('"'); } else { quote = PRUnichar('\''); } - aStr.Append(quote); - aStr.Append(publicId); - aStr.Append(quote); - aStr.Append(PRUnichar(' ')); + AppendToString(quote, aStr); + AppendToString(publicId, aStr); + AppendToString(quote, aStr); + AppendToString(PRUnichar(' '), aStr); if (systemId.FindChar(PRUnichar('"')) == -1) { quote = PRUnichar('"'); } else { quote = PRUnichar('\''); } - aStr.Append(quote); - aStr.Append(systemId); - aStr.Append(quote); + AppendToString(quote, aStr); + AppendToString(systemId, aStr); + AppendToString(quote, aStr); } else if (systemId.Length() > 0) { if (systemId.FindChar(PRUnichar('"')) == -1) { @@ -284,18 +235,18 @@ nsXMLContentSerializer::AppendDoctype(nsIDOMDocumentType *aDoctype, else { quote = PRUnichar('\''); } - aStr.Append(NS_LITERAL_STRING(" SYSTEM ")); - aStr.Append(quote); - aStr.Append(systemId); - aStr.Append(quote); + AppendToString(NS_LITERAL_STRING(" SYSTEM "), aStr); + AppendToString(quote, aStr); + AppendToString(systemId, aStr); + AppendToString(quote, aStr); } if (internalSubset.Length() > 0) { - aStr.Append(PRUnichar(' ')); - aStr.Append(internalSubset); + AppendToString(PRUnichar(' '), aStr); + AppendToString(internalSubset, aStr); } - aStr.Append(NS_LITERAL_STRING(">")); + AppendToString(NS_LITERAL_STRING(">"), aStr); return NS_OK; } @@ -402,16 +353,16 @@ nsXMLContentSerializer::SerializeAttr(const nsAReadableString& aPrefix, const nsAReadableString& aValue, nsAWritableString& aStr) { - aStr.Append(NS_LITERAL_STRING(" ")); + AppendToString(PRUnichar(' '), aStr); if (aPrefix.Length() > 0) { - aStr.Append(aPrefix); - aStr.Append(NS_LITERAL_STRING(":")); + AppendToString(aPrefix, aStr); + AppendToString(NS_LITERAL_STRING(":"), aStr); } - aStr.Append(aName); + AppendToString(aName, aStr); - aStr.Append(NS_LITERAL_STRING("=\"")); - aStr.Append(aValue); - aStr.Append(NS_LITERAL_STRING("\"")); + AppendToString(NS_LITERAL_STRING("=\""), aStr); + AppendToString(aValue, aStr, PR_TRUE); + AppendToString(NS_LITERAL_STRING("\""), aStr); } NS_IMETHODIMP @@ -469,12 +420,12 @@ nsXMLContentSerializer::AppendElementStart(nsIDOMElement *aElement, // Serialize the qualified name of the element addNSAttr = ConfirmPrefix(tagPrefix, tagNamespaceURI); - aStr.Append(NS_LITERAL_STRING("<")); + AppendToString(NS_LITERAL_STRING("<"), aStr); if (tagPrefix.Length() > 0) { - aStr.Append(tagPrefix); - aStr.Append(NS_LITERAL_STRING(":")); + AppendToString(tagPrefix, aStr); + AppendToString(NS_LITERAL_STRING(":"), aStr); } - aStr.Append(tagLocalName); + AppendToString(tagLocalName, aStr); // If we had to add a new namespace declaration, serialize // and push it on the namespace stack @@ -517,7 +468,6 @@ nsXMLContentSerializer::AppendElementStart(nsIDOMElement *aElement, content->GetAttribute(namespaceID, attrName, valueStr); attrName->ToString(nameStr); - ReplaceCharacterEntities(valueStr, 0); SerializeAttr(prefixStr, nameStr, valueStr, aStr); if (addNSAttr) { @@ -526,7 +476,7 @@ nsXMLContentSerializer::AppendElementStart(nsIDOMElement *aElement, } } - aStr.Append(NS_LITERAL_STRING(">")); + AppendToString(NS_LITERAL_STRING(">"), aStr); return NS_OK; } @@ -544,15 +494,86 @@ nsXMLContentSerializer::AppendElementEnd(nsIDOMElement *aElement, aElement->GetNamespaceURI(tagNamespaceURI); ConfirmPrefix(tagPrefix, tagNamespaceURI); - aStr.Append(NS_LITERAL_STRING(" 0) { - aStr.Append(tagPrefix); - aStr.Append(NS_LITERAL_STRING(":")); + AppendToString(tagPrefix, aStr); + AppendToString(NS_LITERAL_STRING(":"), aStr); } - aStr.Append(tagLocalName); - aStr.Append(NS_LITERAL_STRING(">")); + AppendToString(tagLocalName, aStr); + AppendToString(NS_LITERAL_STRING(">"), aStr); PopNameSpaceDeclsFor(aElement); return NS_OK; } + +void +nsXMLContentSerializer::AppendToString(const PRUnichar* aStr, + PRInt32 aLength, + nsAWritableString& aOutputStr) +{ + PRInt32 length = (aLength == -1) ? nsCRT::strlen(aStr) : aLength; + + aOutputStr.Append(aStr, length); +} + +void +nsXMLContentSerializer::AppendToString(const PRUnichar aChar, + nsAWritableString& aOutputStr) +{ + aOutputStr.Append(aChar); +} + +static PRUint16 kGTVal = 62; +static const char* kEntities[] = { + "", "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", "", + "", "", "", "", """, "", "", "", "&", "'", + "", "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", "", + "<", "", ">" +}; + +void +nsXMLContentSerializer::AppendToString(const nsAReadableString& aStr, + nsAWritableString& aOutputStr, + PRBool aTranslateEntities) +{ + if (aTranslateEntities) { + nsReadingIterator done_reading; + aStr.EndReading(done_reading); + + // for each chunk of |aString|... + PRUint32 advanceLength = 0; + nsReadingIterator iter; + + for (aStr.BeginReading(iter); + iter != done_reading; + iter.advance(PRInt32(advanceLength))) { + PRUint32 fragmentLength = iter.size_forward(); + const PRUnichar* c = iter.get(); + const PRUnichar* fragmentStart = c; + const PRUnichar* fragmentEnd = c + fragmentLength; + const char* entityText = nsnull; + + // for each character in this chunk, check if it + // needs to be replaced + for (; c < fragmentEnd; c++, advanceLength++) { + PRUnichar val = *c; + if ((val <= kGTVal) && (kEntities[val][0] != 0)) { + entityText = kEntities[val]; + break; + } + } + + aOutputStr.Append(fragmentStart, advanceLength); + if (entityText) { + aOutputStr.Append(NS_ConvertASCIItoUCS2(entityText)); + advanceLength++; + } + } + } + + aOutputStr.Append(aStr); +} diff --git a/mozilla/content/base/src/nsXMLContentSerializer.h b/mozilla/content/base/src/nsXMLContentSerializer.h index 3d18e33cf57..c71b762247b 100644 --- a/mozilla/content/base/src/nsXMLContentSerializer.h +++ b/mozilla/content/base/src/nsXMLContentSerializer.h @@ -64,12 +64,19 @@ class nsXMLContentSerializer : public nsIContentSerializer { nsAWritableString& aStr); protected: - virtual void ReplaceCharacterEntities(nsAWritableString& aStr, - PRUint32 aOffset); + virtual void AppendToString(const PRUnichar* aStr, + PRInt32 aLength, + nsAWritableString& aOutputStr); + virtual void AppendToString(const PRUnichar aChar, + nsAWritableString& aOutputStr); + virtual void AppendToString(const nsAReadableString& aStr, + nsAWritableString& aOutputStr, + PRBool aTranslateEntities = PR_FALSE); nsresult AppendTextData(nsIDOMNode* aNode, PRInt32 aStartOffset, PRInt32 aEndOffset, - nsAWritableString& aStr); + nsAWritableString& aStr, + PRBool aTranslateEntities); virtual nsresult PushNameSpaceDecl(const nsAReadableString& aPrefix, const nsAReadableString& aURI, nsIDOMElement* aOwner); diff --git a/mozilla/layout/base/src/nsHTMLContentSerializer.cpp b/mozilla/layout/base/src/nsHTMLContentSerializer.cpp index 297026d5af2..80871d441e2 100644 --- a/mozilla/layout/base/src/nsHTMLContentSerializer.cpp +++ b/mozilla/layout/base/src/nsHTMLContentSerializer.cpp @@ -112,19 +112,15 @@ nsHTMLContentSerializer::Init(PRUint32 aFlags, PRUint32 aWrapColumn) if ((mFlags & nsIDocumentEncoder::OutputCRLineBreak) && (mFlags & nsIDocumentEncoder::OutputLFLineBreak)) { // Windows/mail mLineBreak.AssignWithConversion("\r\n"); - mLineBreakLen = 2; } else if (mFlags & nsIDocumentEncoder::OutputCRLineBreak) { // Mac mLineBreak.AssignWithConversion("\r"); - mLineBreakLen = 1; } else if (mFlags & nsIDocumentEncoder::OutputLFLineBreak) { // Unix/DOM mLineBreak.AssignWithConversion("\n"); - mLineBreakLen = 1; } else { mLineBreak.AssignWithConversion(NS_LINEBREAK); // Platform/default - mLineBreakLen = NS_LINEBREAK_LEN; } mPreLevel = 0; @@ -144,20 +140,14 @@ nsHTMLContentSerializer::AppendText(nsIDOMText* aText, nsresult rv; rv = AppendTextData((nsIDOMNode*)aText, aStartOffset, - aEndOffset, data); + aEndOffset, data, PR_TRUE); if (NS_FAILED(rv)) return NS_ERROR_FAILURE; if (mPreLevel || (!mDoFormat && !HasLongLines(data))) { - AppendToString(data, - data.Length(), - aStr, - PR_TRUE); + AppendToString(data, aStr); } else { - AppendToStringWrapped(data, - data.Length(), - aStr, - PR_TRUE); + AppendToStringWrapped(data, aStr, PR_FALSE); } return NS_OK; @@ -254,7 +244,7 @@ nsHTMLContentSerializer::AppendElementStart(nsIDOMElement *aElement, } if (LineBreakBeforeOpen(name, hasDirtyAttr)) { - AppendToString(mLineBreak, mLineBreakLen, aStr); + AppendToString(mLineBreak, aStr); mColPos = 0; } @@ -264,18 +254,18 @@ nsHTMLContentSerializer::AppendElementStart(nsIDOMElement *aElement, StartIndentation(name, hasDirtyAttr, aStr); - AppendToString(NS_LITERAL_STRING(kLessThan), -1, aStr); + AppendToString(NS_LITERAL_STRING(kLessThan), aStr); nsXPIDLString sharedName; name->GetUnicode(getter_Shares(sharedName)); - AppendToString(sharedName, nsCRT::strlen(sharedName), aStr); + AppendToString(sharedName, -1, aStr); SerializeAttributes(content, name, aStr); - AppendToString(NS_LITERAL_STRING(kGreaterThan), -1, aStr); + AppendToString(NS_LITERAL_STRING(kGreaterThan), aStr); if (LineBreakAfterOpen(name, hasDirtyAttr)) { - AppendToString(mLineBreak, mLineBreakLen, aStr); + AppendToString(mLineBreak, aStr); mColPos = 0; } @@ -314,18 +304,18 @@ nsHTMLContentSerializer::AppendElementEnd(nsIDOMElement *aElement, } if (LineBreakBeforeClose(name, hasDirtyAttr)) { - AppendToString(mLineBreak, mLineBreakLen, aStr); + AppendToString(mLineBreak, aStr); mColPos = 0; } EndIndentation(name, hasDirtyAttr, aStr); - AppendToString(NS_LITERAL_STRING(kEndTag), -1, aStr); + AppendToString(NS_LITERAL_STRING(kEndTag), aStr); AppendToString(sharedName, -1, aStr); - AppendToString(NS_LITERAL_STRING(kGreaterThan), -1, aStr); + AppendToString(NS_LITERAL_STRING(kGreaterThan), aStr); if (LineBreakAfterClose(name, hasDirtyAttr)) { - AppendToString(mLineBreak, mLineBreakLen, aStr); + AppendToString(mLineBreak, aStr); mColPos = 0; } @@ -345,19 +335,31 @@ nsHTMLContentSerializer::AppendToString(const PRUnichar* aStr, mColPos += length; - aOutputStr.Append(aStr); + aOutputStr.Append(aStr, length); +} + +void +nsHTMLContentSerializer::AppendToString(const PRUnichar aChar, + nsAWritableString& aOutputStr) +{ + if (mBodyOnly && !mInBody) { + return; + } + + mColPos += 1; + + aOutputStr.Append(aChar); } void nsHTMLContentSerializer::AppendToStringWrapped(const nsAReadableString& aStr, - PRInt32 aLength, nsAWritableString& aOutputStr, PRBool aTranslateEntities) { - PRInt32 length = (aLength == -1) ? aStr.Length() : aLength; + PRInt32 length = aStr.Length(); if ((mColPos + length) < mMaxColumn) { - AppendToString(aStr, length, aOutputStr, aTranslateEntities); + AppendToString(aStr, aOutputStr, aTranslateEntities); } else { nsAutoString line; @@ -377,22 +379,20 @@ nsHTMLContentSerializer::AppendToStringWrapped(const nsAReadableString& aStr, if (indx == kNotFound) { if (strOffset == 0) { - AppendToString(aStr, length, aOutputStr, aTranslateEntities); + AppendToString(aStr, aOutputStr, aTranslateEntities); } else { lineLength = length - strOffset; aStr.Right(line, lineLength); - AppendToString(line, lineLength, - aOutputStr, aTranslateEntities); + AppendToString(line, aOutputStr, aTranslateEntities); } done = PR_TRUE; } else { lineLength = indx - strOffset; aStr.Mid(line, strOffset, lineLength); - AppendToString(line, lineLength, - aOutputStr, aTranslateEntities); - AppendToString(mLineBreak, mLineBreakLen, aOutputStr); + AppendToString(line, aOutputStr, aTranslateEntities); + AppendToString(mLineBreak, aOutputStr); strOffset = indx+1; mColPos = 0; } @@ -402,7 +402,6 @@ nsHTMLContentSerializer::AppendToStringWrapped(const nsAReadableString& aStr, void nsHTMLContentSerializer::AppendToString(const nsAReadableString& aStr, - PRInt32 aLength, nsAWritableString& aOutputStr, PRBool aTranslateEntities) { @@ -411,9 +410,8 @@ nsHTMLContentSerializer::AppendToString(const nsAReadableString& aStr, } nsresult rv; - PRInt32 length = (aLength == -1) ? aStr.Length() : aLength; - mColPos += length; + mColPos += aStr.Length(); if (aTranslateEntities) { nsCOMPtr converter; diff --git a/mozilla/layout/base/src/nsHTMLContentSerializer.h b/mozilla/layout/base/src/nsHTMLContentSerializer.h index d6fa630095c..f1921e7db55 100644 --- a/mozilla/layout/base/src/nsHTMLContentSerializer.h +++ b/mozilla/layout/base/src/nsHTMLContentSerializer.h @@ -63,17 +63,17 @@ class nsHTMLContentSerializer : public nsXMLContentSerializer { void SerializeAttributes(nsIContent* aContent, nsIAtom* aTagName, nsAWritableString& aStr); - void AppendToString(const PRUnichar* aStr, - PRInt32 aLength, - nsAWritableString& aOutputStr); - void AppendToString(const nsAReadableString& aStr, - PRInt32 aLength, - nsAWritableString& aOutputStr, - PRBool aTranslateEntities = PR_FALSE); - void AppendToStringWrapped(const nsAReadableString& aStr, - PRInt32 aLength, - nsAWritableString& aOutputStr, - PRBool aTranslateEntities); + virtual void AppendToString(const PRUnichar* aStr, + PRInt32 aLength, + nsAWritableString& aOutputStr); + virtual void AppendToString(const PRUnichar aChar, + nsAWritableString& aOutputStr); + virtual void AppendToString(const nsAReadableString& aStr, + nsAWritableString& aOutputStr, + PRBool aTranslateEntities = PR_FALSE); + virtual void AppendToStringWrapped(const nsAReadableString& aStr, + nsAWritableString& aOutputStr, + PRBool aTranslateEntities); PRBool HasLongLines(const nsString& text); nsCOMPtr mParserService; @@ -92,7 +92,6 @@ class nsHTMLContentSerializer : public nsXMLContentSerializer { PRInt32 mMaxColumn; nsString mLineBreak; - PRInt32 mLineBreakLen; }; extern nsresult NS_NewHTMLContentSerializer(nsIContentSerializer** aSerializer); diff --git a/mozilla/layout/base/src/nsXMLContentSerializer.cpp b/mozilla/layout/base/src/nsXMLContentSerializer.cpp index 1c3dfabc67d..20feae6bfb1 100644 --- a/mozilla/layout/base/src/nsXMLContentSerializer.cpp +++ b/mozilla/layout/base/src/nsXMLContentSerializer.cpp @@ -70,75 +70,33 @@ nsXMLContentSerializer::Init(PRUint32 flags, PRUint32 aWrapColumn) return NS_OK; } -static PRUint16 kGTVal = 62; -static const char* kEntities[] = { - "", "", "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", "", "", - "", "", "", "", """, "", "", "", "&", "'", - "", "", "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", "", "", - "<", "", ">" -}; - -void -nsXMLContentSerializer::ReplaceCharacterEntities(nsAWritableString& aStr, - PRUint32 aOffset) -{ - nsReadingIterator done_reading; - aStr.EndReading(done_reading); - - // for each chunk of |aString|... - PRUint32 fragmentLength = 0; - PRUint32 offset = aOffset; - nsReadingIterator iter; - aStr.BeginReading(iter); - - for (iter.advance(PRInt32(offset)); - iter != done_reading; - iter.advance(PRInt32(fragmentLength))) { - fragmentLength = iter.size_forward(); - const PRUnichar* c = iter.get(); - const PRUnichar* fragmentEnd = c + fragmentLength; - - // for each character in this chunk... - for (; c < fragmentEnd; c++, offset++) { - PRUnichar val = *c; - if ((val <= kGTVal) && (kEntities[val][0] != 0)) { - aStr.Cut(offset, 1); - aStr.Insert(NS_LITERAL_STRING(kEntities[val]), offset); - aStr.EndReading(done_reading); - aStr.BeginReading(iter); - fragmentLength = offset+nsCRT::strlen(kEntities[val]); - break; - } - } - } -} - nsresult nsXMLContentSerializer::AppendTextData(nsIDOMNode* aNode, PRInt32 aStartOffset, PRInt32 aEndOffset, - nsAWritableString& aStr) + nsAWritableString& aStr, + PRBool aTranslateEntities) { nsCOMPtr content = do_QueryInterface(aNode); if (!content) return NS_ERROR_FAILURE; const nsTextFragment* frag; content->GetText(&frag); - + if (frag) { - PRInt32 length = (aEndOffset == -1) ? frag->GetLength() : aEndOffset; - length -= aStartOffset; + PRInt32 length = ((aEndOffset == -1) ? frag->GetLength() : aEndOffset) - aStartOffset; if (frag->Is2b()) { - aStr.Append(frag->Get2b()+aStartOffset, length); + AppendToString(nsLiteralString(frag->Get2b()+aStartOffset, length), + aStr, + aTranslateEntities); } else { - aStr.Append(NS_ConvertASCIItoUCS2(frag->Get1b()+aStartOffset, length)); + AppendToString(NS_ConvertASCIItoUCS2(frag->Get1b()+aStartOffset, length), + aStr, + aTranslateEntities); } } - + return NS_OK; } @@ -150,15 +108,8 @@ nsXMLContentSerializer::AppendText(nsIDOMText* aText, { NS_ENSURE_ARG(aText); - PRUint32 length = aStr.Length(); - nsresult rv; - rv = AppendTextData(aText, aStartOffset, aEndOffset, aStr); - if (NS_FAILED(rv)) return NS_ERROR_FAILURE; - - ReplaceCharacterEntities(aStr, length); - - return NS_OK; + return AppendTextData(aText, aStartOffset, aEndOffset, aStr, PR_TRUE); } NS_IMETHODIMP @@ -170,10 +121,10 @@ nsXMLContentSerializer::AppendCDATASection(nsIDOMCDATASection* aCDATASection, NS_ENSURE_ARG(aCDATASection); nsresult rv; - aStr.Append(NS_LITERAL_STRING("")); + AppendToString(NS_LITERAL_STRING("]]>"), aStr); return NS_OK; } @@ -194,13 +145,13 @@ nsXMLContentSerializer::AppendProcessingInstruction(nsIDOMProcessingInstruction* rv = aPI->GetData(data); if (NS_FAILED(rv)) return NS_ERROR_FAILURE; - aStr.Append(NS_LITERAL_STRING(" 0) { - aStr.Append(NS_LITERAL_STRING(" ")); - aStr.Append(data); + AppendToString(NS_LITERAL_STRING(" "), aStr); + AppendToString(data, aStr); } - aStr.Append(NS_LITERAL_STRING(">")); + AppendToString(NS_LITERAL_STRING(">"), aStr); return NS_OK; } @@ -218,19 +169,19 @@ nsXMLContentSerializer::AppendComment(nsIDOMComment* aComment, rv = aComment->GetData(data); if (NS_FAILED(rv)) return NS_ERROR_FAILURE; - aStr.Append(NS_LITERAL_STRING("")); + AppendToString(NS_LITERAL_STRING("-->"), aStr); return NS_OK; } @@ -252,30 +203,30 @@ nsXMLContentSerializer::AppendDoctype(nsIDOMDocumentType *aDoctype, rv = aDoctype->GetInternalSubset(publicId); if (NS_FAILED(rv)) return NS_ERROR_FAILURE; - aStr.Append(NS_LITERAL_STRING(" 0) { - aStr.Append(NS_LITERAL_STRING(" PUBLIC ")); + AppendToString(NS_LITERAL_STRING(" PUBLIC "), aStr); if (publicId.FindChar(PRUnichar('"')) == -1) { quote = PRUnichar('"'); } else { quote = PRUnichar('\''); } - aStr.Append(quote); - aStr.Append(publicId); - aStr.Append(quote); - aStr.Append(PRUnichar(' ')); + AppendToString(quote, aStr); + AppendToString(publicId, aStr); + AppendToString(quote, aStr); + AppendToString(PRUnichar(' '), aStr); if (systemId.FindChar(PRUnichar('"')) == -1) { quote = PRUnichar('"'); } else { quote = PRUnichar('\''); } - aStr.Append(quote); - aStr.Append(systemId); - aStr.Append(quote); + AppendToString(quote, aStr); + AppendToString(systemId, aStr); + AppendToString(quote, aStr); } else if (systemId.Length() > 0) { if (systemId.FindChar(PRUnichar('"')) == -1) { @@ -284,18 +235,18 @@ nsXMLContentSerializer::AppendDoctype(nsIDOMDocumentType *aDoctype, else { quote = PRUnichar('\''); } - aStr.Append(NS_LITERAL_STRING(" SYSTEM ")); - aStr.Append(quote); - aStr.Append(systemId); - aStr.Append(quote); + AppendToString(NS_LITERAL_STRING(" SYSTEM "), aStr); + AppendToString(quote, aStr); + AppendToString(systemId, aStr); + AppendToString(quote, aStr); } if (internalSubset.Length() > 0) { - aStr.Append(PRUnichar(' ')); - aStr.Append(internalSubset); + AppendToString(PRUnichar(' '), aStr); + AppendToString(internalSubset, aStr); } - aStr.Append(NS_LITERAL_STRING(">")); + AppendToString(NS_LITERAL_STRING(">"), aStr); return NS_OK; } @@ -402,16 +353,16 @@ nsXMLContentSerializer::SerializeAttr(const nsAReadableString& aPrefix, const nsAReadableString& aValue, nsAWritableString& aStr) { - aStr.Append(NS_LITERAL_STRING(" ")); + AppendToString(PRUnichar(' '), aStr); if (aPrefix.Length() > 0) { - aStr.Append(aPrefix); - aStr.Append(NS_LITERAL_STRING(":")); + AppendToString(aPrefix, aStr); + AppendToString(NS_LITERAL_STRING(":"), aStr); } - aStr.Append(aName); + AppendToString(aName, aStr); - aStr.Append(NS_LITERAL_STRING("=\"")); - aStr.Append(aValue); - aStr.Append(NS_LITERAL_STRING("\"")); + AppendToString(NS_LITERAL_STRING("=\""), aStr); + AppendToString(aValue, aStr, PR_TRUE); + AppendToString(NS_LITERAL_STRING("\""), aStr); } NS_IMETHODIMP @@ -469,12 +420,12 @@ nsXMLContentSerializer::AppendElementStart(nsIDOMElement *aElement, // Serialize the qualified name of the element addNSAttr = ConfirmPrefix(tagPrefix, tagNamespaceURI); - aStr.Append(NS_LITERAL_STRING("<")); + AppendToString(NS_LITERAL_STRING("<"), aStr); if (tagPrefix.Length() > 0) { - aStr.Append(tagPrefix); - aStr.Append(NS_LITERAL_STRING(":")); + AppendToString(tagPrefix, aStr); + AppendToString(NS_LITERAL_STRING(":"), aStr); } - aStr.Append(tagLocalName); + AppendToString(tagLocalName, aStr); // If we had to add a new namespace declaration, serialize // and push it on the namespace stack @@ -517,7 +468,6 @@ nsXMLContentSerializer::AppendElementStart(nsIDOMElement *aElement, content->GetAttribute(namespaceID, attrName, valueStr); attrName->ToString(nameStr); - ReplaceCharacterEntities(valueStr, 0); SerializeAttr(prefixStr, nameStr, valueStr, aStr); if (addNSAttr) { @@ -526,7 +476,7 @@ nsXMLContentSerializer::AppendElementStart(nsIDOMElement *aElement, } } - aStr.Append(NS_LITERAL_STRING(">")); + AppendToString(NS_LITERAL_STRING(">"), aStr); return NS_OK; } @@ -544,15 +494,86 @@ nsXMLContentSerializer::AppendElementEnd(nsIDOMElement *aElement, aElement->GetNamespaceURI(tagNamespaceURI); ConfirmPrefix(tagPrefix, tagNamespaceURI); - aStr.Append(NS_LITERAL_STRING(" 0) { - aStr.Append(tagPrefix); - aStr.Append(NS_LITERAL_STRING(":")); + AppendToString(tagPrefix, aStr); + AppendToString(NS_LITERAL_STRING(":"), aStr); } - aStr.Append(tagLocalName); - aStr.Append(NS_LITERAL_STRING(">")); + AppendToString(tagLocalName, aStr); + AppendToString(NS_LITERAL_STRING(">"), aStr); PopNameSpaceDeclsFor(aElement); return NS_OK; } + +void +nsXMLContentSerializer::AppendToString(const PRUnichar* aStr, + PRInt32 aLength, + nsAWritableString& aOutputStr) +{ + PRInt32 length = (aLength == -1) ? nsCRT::strlen(aStr) : aLength; + + aOutputStr.Append(aStr, length); +} + +void +nsXMLContentSerializer::AppendToString(const PRUnichar aChar, + nsAWritableString& aOutputStr) +{ + aOutputStr.Append(aChar); +} + +static PRUint16 kGTVal = 62; +static const char* kEntities[] = { + "", "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", "", + "", "", "", "", """, "", "", "", "&", "'", + "", "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", "", + "<", "", ">" +}; + +void +nsXMLContentSerializer::AppendToString(const nsAReadableString& aStr, + nsAWritableString& aOutputStr, + PRBool aTranslateEntities) +{ + if (aTranslateEntities) { + nsReadingIterator done_reading; + aStr.EndReading(done_reading); + + // for each chunk of |aString|... + PRUint32 advanceLength = 0; + nsReadingIterator iter; + + for (aStr.BeginReading(iter); + iter != done_reading; + iter.advance(PRInt32(advanceLength))) { + PRUint32 fragmentLength = iter.size_forward(); + const PRUnichar* c = iter.get(); + const PRUnichar* fragmentStart = c; + const PRUnichar* fragmentEnd = c + fragmentLength; + const char* entityText = nsnull; + + // for each character in this chunk, check if it + // needs to be replaced + for (; c < fragmentEnd; c++, advanceLength++) { + PRUnichar val = *c; + if ((val <= kGTVal) && (kEntities[val][0] != 0)) { + entityText = kEntities[val]; + break; + } + } + + aOutputStr.Append(fragmentStart, advanceLength); + if (entityText) { + aOutputStr.Append(NS_ConvertASCIItoUCS2(entityText)); + advanceLength++; + } + } + } + + aOutputStr.Append(aStr); +} diff --git a/mozilla/layout/base/src/nsXMLContentSerializer.h b/mozilla/layout/base/src/nsXMLContentSerializer.h index 3d18e33cf57..c71b762247b 100644 --- a/mozilla/layout/base/src/nsXMLContentSerializer.h +++ b/mozilla/layout/base/src/nsXMLContentSerializer.h @@ -64,12 +64,19 @@ class nsXMLContentSerializer : public nsIContentSerializer { nsAWritableString& aStr); protected: - virtual void ReplaceCharacterEntities(nsAWritableString& aStr, - PRUint32 aOffset); + virtual void AppendToString(const PRUnichar* aStr, + PRInt32 aLength, + nsAWritableString& aOutputStr); + virtual void AppendToString(const PRUnichar aChar, + nsAWritableString& aOutputStr); + virtual void AppendToString(const nsAReadableString& aStr, + nsAWritableString& aOutputStr, + PRBool aTranslateEntities = PR_FALSE); nsresult AppendTextData(nsIDOMNode* aNode, PRInt32 aStartOffset, PRInt32 aEndOffset, - nsAWritableString& aStr); + nsAWritableString& aStr, + PRBool aTranslateEntities); virtual nsresult PushNameSpaceDecl(const nsAReadableString& aPrefix, const nsAReadableString& aURI, nsIDOMElement* aOwner);