diff -r 55f344578932 content/base/public/nsIDocumentEncoder.idl --- a/content/base/public/nsIDocumentEncoder.idl Fri Mar 18 11:43:21 2011 +0000 +++ b/content/base/public/nsIDocumentEncoder.idl Tue Apr 26 18:33:30 2011 +0200 @@ -237,6 +237,11 @@ const unsigned long OutputFormatDelSp = (1 << 20); /** + * Output all non-ascii characters as numeric entities + */ + const unsigned long OutputEncodeCharacterEntities = (1 << 21); + + /** * Initialize with a pointer to the document and the mime type. * @param aDocument Document to encode. * @param aMimeType MimeType to use. May also be set by SetMimeType. diff -r 55f344578932 content/base/src/nsCopySupport.cpp --- a/content/base/src/nsCopySupport.cpp Fri Mar 18 11:43:21 2011 +0000 +++ b/content/base/src/nsCopySupport.cpp Tue Apr 26 18:33:30 2011 +0200 @@ -436,7 +436,7 @@ // copy it properly (all the copy code for non-plaintext assumes using HTML // serializers and parsers is OK, and those mess up XHTML). nsCOMPtr htmlDoc = do_QueryInterface(aDoc); - if (!(htmlDoc && aDoc->IsHTML())) + if (!htmlDoc) *aIsPlainTextContext = PR_TRUE; return NS_OK; diff -r 55f344578932 content/base/src/nsDocumentEncoder.cpp --- a/content/base/src/nsDocumentEncoder.cpp Fri Mar 18 11:43:21 2011 +0000 +++ b/content/base/src/nsDocumentEncoder.cpp Tue Apr 26 18:33:30 2011 +0200 @@ -1333,7 +1333,7 @@ // also consider ourselves in a text widget if we can't find an html document nsCOMPtr htmlDoc = do_QueryInterface(mDocument); - if (!(htmlDoc && mDocument->IsHTML())) + if (!htmlDoc) mIsTextWidget = PR_TRUE; // normalize selection if we are not in a widget diff -r 55f344578932 content/base/src/nsHTMLContentSerializer.cpp --- a/content/base/src/nsHTMLContentSerializer.cpp Fri Mar 18 11:43:21 2011 +0000 +++ b/content/base/src/nsHTMLContentSerializer.cpp Tue Apr 26 18:33:30 2011 +0200 @@ -250,14 +250,15 @@ PRBool lineBreakBeforeOpen = LineBreakBeforeOpen(content->GetNameSpaceID(), name); - if ((mDoFormat || forceFormat) && !mPreLevel && !mDoRaw) { + if (((mDoFormat || forceFormat) && !mPreLevel) || mDoRaw) { if (mColPos && lineBreakBeforeOpen) { AppendNewLineToString(aStr); + mMayIgnoreLineBreakSequence = PR_FALSE; } else { MaybeAddNewlineForRootNode(aStr); } - if (!mColPos) { + if (!mColPos && !mDoRaw) { AppendIndentation(aStr); } else if (mAddSpace) { @@ -513,7 +514,8 @@ PRBool nonBasicEntities = !!(mFlags & (nsIDocumentEncoder::OutputEncodeLatin1Entities | nsIDocumentEncoder::OutputEncodeHTMLEntities | - nsIDocumentEncoder::OutputEncodeW3CEntities)); + nsIDocumentEncoder::OutputEncodeW3CEntities | + nsIDocumentEncoder::OutputEncodeCharacterEntities)); if (!nonBasicEntities && (mFlags & (nsIDocumentEncoder::OutputEncodeBasicEntities))) { @@ -569,7 +571,13 @@ // needs to be replaced for (; c < fragmentEnd; c++, advanceLength++) { PRUnichar val = *c; - if (val <= kValNBSP && entityTable[val]) { + if ((val == kValNBSP || val > 127) && + (mFlags & nsIDocumentEncoder::OutputEncodeCharacterEntities)) { + nsAutoString entityValue(PRUnichar('#')); + entityValue.AppendInt(val); + entityText = ToNewCString(entityValue); + break; + } else if (val <= kValNBSP && entityTable[val]) { fullConstEntityText = entityTable[val]; break; } else if (val > 127 && diff -r 55f344578932 content/base/src/nsXHTMLContentSerializer.cpp --- a/content/base/src/nsXHTMLContentSerializer.cpp Fri Mar 18 11:43:21 2011 +0000 +++ b/content/base/src/nsXHTMLContentSerializer.cpp Tue Apr 26 18:33:30 2011 +0200 @@ -761,14 +761,23 @@ return mAddSpace; } - if (aName == nsGkAtoms::title || - aName == nsGkAtoms::meta || - aName == nsGkAtoms::link || - aName == nsGkAtoms::style || + if (// aName == nsGkAtoms::title || + // aName == nsGkAtoms::meta || + //aName == nsGkAtoms::link || + //aName == nsGkAtoms::style || aName == nsGkAtoms::select || aName == nsGkAtoms::option || aName == nsGkAtoms::script || - aName == nsGkAtoms::html) { + aName == nsGkAtoms::html || + aName == nsGkAtoms::head || + //aName == nsGkAtoms::body || + aName == nsGkAtoms::table || + aName == nsGkAtoms::caption || + aName == nsGkAtoms::tbody || + aName == nsGkAtoms::thead || + aName == nsGkAtoms::tfoot || + aName == nsGkAtoms::tr || + aName == nsGkAtoms::td) { return PR_TRUE; } else { @@ -795,7 +804,7 @@ if ((aName == nsGkAtoms::html) || (aName == nsGkAtoms::head) || - (aName == nsGkAtoms::body) || + //(aName == nsGkAtoms::body) || (aName == nsGkAtoms::ul) || (aName == nsGkAtoms::ol) || (aName == nsGkAtoms::dl) || @@ -803,7 +812,7 @@ (aName == nsGkAtoms::tbody) || (aName == nsGkAtoms::tr) || (aName == nsGkAtoms::br) || - (aName == nsGkAtoms::meta) || + //(aName == nsGkAtoms::meta) || (aName == nsGkAtoms::link) || (aName == nsGkAtoms::script) || (aName == nsGkAtoms::select) || @@ -832,7 +841,10 @@ (aName == nsGkAtoms::dl) || (aName == nsGkAtoms::select) || (aName == nsGkAtoms::table) || - (aName == nsGkAtoms::tbody)) { + (aName == nsGkAtoms::tbody) || + (aName == nsGkAtoms::thead) || + (aName == nsGkAtoms::tfoot) || + (aName == nsGkAtoms::tr)) { return PR_TRUE; } return PR_FALSE; @@ -897,6 +909,8 @@ name == nsGkAtoms::noframes ) { mPreLevel++; + if (name != nsGkAtoms::pre) + ++mDisableEntityEncoding; } } @@ -915,6 +929,8 @@ name == nsGkAtoms::noframes ) { --mPreLevel; + if (name != nsGkAtoms::pre) + --mDisableEntityEncoding; } } @@ -1034,3 +1050,4 @@ return PR_TRUE; } + diff -r 55f344578932 content/base/src/nsXMLContentSerializer.cpp --- a/content/base/src/nsXMLContentSerializer.cpp Fri Mar 18 11:43:21 2011 +0000 +++ b/content/base/src/nsXMLContentSerializer.cpp Tue Apr 26 18:33:30 2011 +0200 @@ -64,6 +64,7 @@ #include "nsContentUtils.h" #include "nsAttrName.h" #include "nsILineBreaker.h" +#include "nsIParserService.h" static const char kMozStr[] = "moz"; @@ -939,7 +940,7 @@ nsIAtom *name = content->Tag(); PRBool lineBreakBeforeOpen = LineBreakBeforeOpen(content->GetNameSpaceID(), name); - if ((mDoFormat || forceFormat) && !mPreLevel && !mDoRaw) { + if (((mDoFormat || forceFormat) && !mPreLevel) || mDoRaw) { if (mColPos && lineBreakBeforeOpen) { AppendNewLineToString(aStr); } @@ -1186,6 +1187,21 @@ return; } mColPos += aStr.Length(); + nsASingleFragmentString::const_char_iterator pos, end, sequenceStart; + + aStr.BeginReading(pos); + aStr.EndReading(end); + PRBool foundOtherThanCR = PR_FALSE; + while (!foundOtherThanCR && pos < end) { + if (*pos != '\n' && *pos != '\r') { + foundOtherThanCR = PR_TRUE; + } + pos++; + } + + if (!foundOtherThanCR) { + mMayIgnoreLineBreakSequence = PR_TRUE; + } aOutputStr.Append(aStr); } @@ -1296,6 +1312,10 @@ void nsXMLContentSerializer::AppendNewLineToString(nsAString& aStr) { + if (mMayIgnoreLineBreakSequence) { + mMayIgnoreLineBreakSequence = PR_FALSE; + return; + } AppendToString(mLineBreak, aStr); mMayIgnoreLineBreakSequence = PR_TRUE; mColPos = 0; @@ -1336,7 +1356,39 @@ PRBool nsXMLContentSerializer::LineBreakBeforeOpen(PRInt32 aNamespaceID, nsIAtom* aName) { - return mAddSpace; + if (aNamespaceID != kNameSpaceID_XHTML) { + return mAddSpace; + } + + if (aName == nsGkAtoms::title || + aName == nsGkAtoms::meta || + aName == nsGkAtoms::link || + aName == nsGkAtoms::style || + aName == nsGkAtoms::select || + aName == nsGkAtoms::option || + aName == nsGkAtoms::script || + aName == nsGkAtoms::html || + aName == nsGkAtoms::table || + aName == nsGkAtoms::caption || + aName == nsGkAtoms::tbody || + aName == nsGkAtoms::thead || + aName == nsGkAtoms::tfoot || + aName == nsGkAtoms::tr || + aName == nsGkAtoms::td) { + return PR_TRUE; + } + else { + nsIParserService* parserService = nsContentUtils::GetParserService(); + + if (parserService) { + PRBool res; + parserService-> + IsBlock(parserService->HTMLCaseSensitiveAtomTagToId(aName), res); + return res; + } + } + + return mAddSpace; } PRBool @@ -1464,6 +1516,7 @@ // Since we only saw linebreaks, but no spaces or tabs, // let's write a linebreak now. AppendNewLineToString(aOutputStr); + mMayIgnoreLineBreakSequence = PR_TRUE; } } } diff -r 55f344578932 editor/libeditor/html/nsHTMLDataTransfer.cpp --- a/editor/libeditor/html/nsHTMLDataTransfer.cpp Fri Mar 18 11:43:21 2011 +0000 +++ b/editor/libeditor/html/nsHTMLDataTransfer.cpp Tue Apr 26 18:33:30 2011 +0200 @@ -1386,7 +1386,8 @@ aSourceDoc, aDestinationNode, aDestOffset, aDoDeleteSelection, - isSafe); + //isSafe); + true); } } else if (0 == nsCRT::strcmp(bestFlavor, kUnicodeMime) || diff -r 55f344578932 editor/libeditor/html/nsHTMLEditRules.cpp --- a/editor/libeditor/html/nsHTMLEditRules.cpp Fri Mar 18 11:43:21 2011 +0000 +++ b/editor/libeditor/html/nsHTMLEditRules.cpp Tue Apr 26 18:33:30 2011 +0200 @@ -1450,39 +1450,8 @@ // it is to search for both tabs and newlines. if (isPRE || IsPlaintextEditor()) { - while (unicodeBuf && (pos != -1) && (pos < (PRInt32)(*inString).Length())) - { - PRInt32 oldPos = pos; - PRInt32 subStrLen; - pos = tString.FindChar(nsCRT::LF, oldPos); - - if (pos != -1) - { - subStrLen = pos - oldPos; - // if first char is newline, then use just it - if (subStrLen == 0) - subStrLen = 1; - } - else - { - subStrLen = tString.Length() - oldPos; - pos = tString.Length(); - } - - nsDependentSubstring subStr(tString, oldPos, subStrLen); - - // is it a return? - if (subStr.Equals(newlineStr)) - { - res = mHTMLEditor->CreateBRImpl(address_of(curNode), &curOffset, address_of(unused), nsIEditor::eNone); - pos++; - } - else - { - res = mHTMLEditor->InsertTextImpl(subStr, address_of(curNode), &curOffset, doc); - } - NS_ENSURE_SUCCESS(res, res); - } + res = mHTMLEditor->InsertTextImpl(tString, address_of(curNode), &curOffset, doc); + NS_ENSURE_SUCCESS(res, res); } else {