mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 11:25:00 +00:00
Bug 574089 - Optimize ::GetInnerHTML, r=jst
--HG-- extra : rebase_source : 3ed1549eaa96d3ff3fe6bf2bb2562dd9e68fcc17
This commit is contained in:
parent
9a0c6c33bd
commit
4a3cfaa4e8
@ -63,6 +63,7 @@
|
||||
#include "nsSMILAnimationController.h"
|
||||
#endif // MOZ_SMIL
|
||||
#include "nsIScriptGlobalObject.h"
|
||||
#include "nsIDocumentEncoder.h"
|
||||
|
||||
class nsIContent;
|
||||
class nsPresContext;
|
||||
@ -116,10 +117,9 @@ class Element;
|
||||
} // namespace mozilla
|
||||
|
||||
|
||||
// fbcd570b-dbfa-479b-9bd0-02312129c044
|
||||
#define NS_IDOCUMENT_IID \
|
||||
{ 0xfbcd570b, 0xdbfa, 0x479b, \
|
||||
{ 0x9b, 0xd0, 0x02, 0x31, 0x21, 0x29, 0xc0, 0x44 } }
|
||||
{ 0x1d8bd3d4, 0x6f6d, 0x49fe, \
|
||||
{ 0xaf, 0xda, 0xc9, 0x4a, 0xef, 0x8f, 0xcf, 0x1f } }
|
||||
|
||||
// Flag for AddStyleSheet().
|
||||
#define NS_STYLESHEET_FROM_CATALOG (1 << 0)
|
||||
@ -1115,6 +1115,16 @@ public:
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
already_AddRefed<nsIDocumentEncoder> GetCachedEncoder()
|
||||
{
|
||||
return mCachedEncoder.forget();
|
||||
}
|
||||
|
||||
void SetCachedEncoder(nsIDocumentEncoder* aEncoder)
|
||||
{
|
||||
mCachedEncoder = aEncoder;
|
||||
}
|
||||
|
||||
// In case of failure, the document really can't initialize the frame loader.
|
||||
virtual nsresult InitializeFrameLoader(nsFrameLoader* aLoader) = 0;
|
||||
// In case of failure, the caller must handle the error, for example by
|
||||
@ -1422,6 +1432,17 @@ protected:
|
||||
return GetRootElement();
|
||||
}
|
||||
|
||||
void SetContentTypeInternal(const nsACString& aType)
|
||||
{
|
||||
mCachedEncoder = nsnull;
|
||||
mContentType = aType;
|
||||
}
|
||||
|
||||
nsCString GetContentTypeInternal() const
|
||||
{
|
||||
return mContentType;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> mDocumentURI;
|
||||
nsCOMPtr<nsIURI> mDocumentBaseURI;
|
||||
|
||||
@ -1530,7 +1551,9 @@ protected:
|
||||
PRUint32 mBidiOptions;
|
||||
|
||||
nsCString mContentLanguage;
|
||||
private:
|
||||
nsCString mContentType;
|
||||
protected:
|
||||
|
||||
// The document's security info
|
||||
nsCOMPtr<nsISupports> mSecurityInfo;
|
||||
@ -1560,6 +1583,8 @@ protected:
|
||||
// Weak reference to mScriptGlobalObject QI:d to nsPIDOMWindow,
|
||||
// updated on every set of mSecriptGlobalObject.
|
||||
nsPIDOMWindow *mWindow;
|
||||
|
||||
nsCOMPtr<nsIDocumentEncoder> mCachedEncoder;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsIDocument, NS_IDOCUMENT_IID)
|
||||
|
@ -44,6 +44,13 @@ interface nsISelection;
|
||||
interface nsIDOMNode;
|
||||
interface nsIOutputStream;
|
||||
|
||||
%{ C++
|
||||
class nsINode;
|
||||
class nsIDocument;
|
||||
%}
|
||||
[ptr] native nsINodePtr(nsINode);
|
||||
[ptr] native nsIDocumentPtr(nsIDocument);
|
||||
|
||||
[scriptable, uuid(c0da5b87-0ba7-4d7c-8cb3-fcb02af4253d)]
|
||||
interface nsIDocumentEncoderNodeFixup : nsISupports
|
||||
{
|
||||
@ -61,7 +68,7 @@ interface nsIDocumentEncoderNodeFixup : nsISupports
|
||||
nsIDOMNode fixupNode(in nsIDOMNode aNode, out boolean aSerializeCloneKids);
|
||||
};
|
||||
|
||||
[scriptable, uuid(794a81f6-bde6-4f76-9f5e-0ea0911a2d9f)]
|
||||
[scriptable, uuid(7222bdf1-c2b9-41f1-a40a-a3d65283a95b)]
|
||||
interface nsIDocumentEncoder : nsISupports
|
||||
{
|
||||
// Output methods flag bits. There are a frightening number of these,
|
||||
@ -238,6 +245,9 @@ interface nsIDocumentEncoder : nsISupports
|
||||
void init(in nsIDOMDocument aDocument,
|
||||
in AString aMimeType,
|
||||
in unsigned long aFlags);
|
||||
[noscript] void nativeInit(in nsIDocumentPtr aDocument,
|
||||
in AString aMimeType,
|
||||
in unsigned long aFlags);
|
||||
|
||||
/**
|
||||
* If the selection is set to a non-null value, then the
|
||||
@ -270,6 +280,7 @@ interface nsIDocumentEncoder : nsISupports
|
||||
* @param aContainer The node which child nodes will be encoded.
|
||||
*/
|
||||
void setContainerNode(in nsIDOMNode aContainer);
|
||||
[noscript] void setNativeContainerNode(in nsINodePtr aContainer);
|
||||
|
||||
/**
|
||||
* Documents typically have an intrinsic character set,
|
||||
|
@ -1393,7 +1393,7 @@ nsDOMImplementation::Init(nsIURI* aDocumentURI, nsIURI* aBaseURI,
|
||||
nsDocument::nsDocument(const char* aContentType)
|
||||
: nsIDocument()
|
||||
{
|
||||
mContentType = aContentType;
|
||||
SetContentTypeInternal(nsDependentCString(aContentType));
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
if (!gDocumentLeakPRLog)
|
||||
@ -1688,6 +1688,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDocument)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mFirstBaseNodeWithHref)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mDOMImplementation)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOriginalDocument)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mCachedEncoder)
|
||||
|
||||
// Traverse all our nsCOMArrays.
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mStyleSheets)
|
||||
@ -1731,6 +1732,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDocument)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mFirstBaseNodeWithHref)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mDOMImplementation)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOriginalDocument)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mCachedEncoder)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_USERDATA
|
||||
|
||||
@ -1947,7 +1949,7 @@ nsDocument::ResetToURI(nsIURI *aURI, nsILoadGroup *aLoadGroup,
|
||||
mLastModified.Truncate();
|
||||
// XXXbz I guess we're assuming that the caller will either pass in
|
||||
// a channel with a useful type or call SetContentType?
|
||||
mContentType.Truncate();
|
||||
SetContentTypeInternal(EmptyCString());
|
||||
mContentLanguage.Truncate();
|
||||
mBaseTarget.Truncate();
|
||||
mReferrer.Truncate();
|
||||
@ -2155,7 +2157,7 @@ nsDocument::StartDocumentLoad(const char* aCommand, nsIChannel* aChannel,
|
||||
contentType.EndReading(end);
|
||||
semicolon = start;
|
||||
FindCharInReadable(';', semicolon, end);
|
||||
mContentType = Substring(start, semicolon);
|
||||
SetContentTypeInternal(Substring(start, semicolon));
|
||||
}
|
||||
|
||||
RetrieveRelevantHeaders(aChannel);
|
||||
@ -2436,7 +2438,7 @@ nsDocument::SetApplicationCache(nsIApplicationCache *aApplicationCache)
|
||||
NS_IMETHODIMP
|
||||
nsDocument::GetContentType(nsAString& aContentType)
|
||||
{
|
||||
CopyUTF8toUTF16(mContentType, aContentType);
|
||||
CopyUTF8toUTF16(GetContentTypeInternal(), aContentType);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -2444,11 +2446,11 @@ nsDocument::GetContentType(nsAString& aContentType)
|
||||
void
|
||||
nsDocument::SetContentType(const nsAString& aContentType)
|
||||
{
|
||||
NS_ASSERTION(mContentType.IsEmpty() ||
|
||||
mContentType.Equals(NS_ConvertUTF16toUTF8(aContentType)),
|
||||
NS_ASSERTION(GetContentTypeInternal().IsEmpty() ||
|
||||
GetContentTypeInternal().Equals(NS_ConvertUTF16toUTF8(aContentType)),
|
||||
"Do you really want to change the content-type?");
|
||||
|
||||
CopyUTF16toUTF8(aContentType, mContentType);
|
||||
SetContentTypeInternal(NS_ConvertUTF16toUTF8(aContentType));
|
||||
}
|
||||
|
||||
/* Return true if the document is in the focused top-level window, and is an
|
||||
@ -7305,7 +7307,7 @@ nsDocument::CloneDocHelper(nsDocument* clone) const
|
||||
clone->mCompatMode = mCompatMode;
|
||||
clone->mBidiOptions = mBidiOptions;
|
||||
clone->mContentLanguage = mContentLanguage;
|
||||
clone->mContentType = mContentType;
|
||||
clone->SetContentTypeInternal(GetContentTypeInternal());
|
||||
clone->mSecurityInfo = mSecurityInfo;
|
||||
|
||||
// State from nsDocument
|
||||
|
@ -81,6 +81,7 @@
|
||||
#include "nsReadableUtils.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsStringBuffer.h"
|
||||
|
||||
nsresult NS_NewDomSelection(nsISelection **aDomSelection);
|
||||
|
||||
@ -95,8 +96,8 @@ public:
|
||||
nsDocumentEncoder();
|
||||
virtual ~nsDocumentEncoder();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS(nsDocumentEncoder)
|
||||
NS_DECL_NSIDOCUMENTENCODER
|
||||
|
||||
protected:
|
||||
@ -175,17 +176,36 @@ protected:
|
||||
PRPackedBool mHaltRangeHint;
|
||||
PRPackedBool mIsCopying; // Set to PR_TRUE only while copying
|
||||
PRPackedBool mNodeIsContainer;
|
||||
nsStringBuffer* mCachedBuffer;
|
||||
};
|
||||
|
||||
NS_IMPL_ADDREF(nsDocumentEncoder)
|
||||
NS_IMPL_RELEASE(nsDocumentEncoder)
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsDocumentEncoder)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(nsDocumentEncoder)
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDocumentEncoder)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsDocumentEncoder)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDocumentEncoder)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDocumentEncoder)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
nsDocumentEncoder::nsDocumentEncoder()
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDocumentEncoder)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mDocument)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mSelection)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mRange)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mNode)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mCommonParent)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDocumentEncoder)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mDocument)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mSelection)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mRange)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mNode)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mCommonParent)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
nsDocumentEncoder::nsDocumentEncoder() : mCachedBuffer(nsnull)
|
||||
{
|
||||
Initialize();
|
||||
mMimeType.AssignLiteral("text/plain");
|
||||
@ -202,10 +222,14 @@ void nsDocumentEncoder::Initialize()
|
||||
mEndRootIndex = 0;
|
||||
mHaltRangeHint = PR_FALSE;
|
||||
mNodeIsContainer = PR_FALSE;
|
||||
mSerializer = nsnull;
|
||||
}
|
||||
|
||||
nsDocumentEncoder::~nsDocumentEncoder()
|
||||
{
|
||||
if (mCachedBuffer) {
|
||||
mCachedBuffer->Release();
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -216,10 +240,23 @@ nsDocumentEncoder::Init(nsIDOMDocument* aDocument,
|
||||
if (!aDocument)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
nsCOMPtr<nsIDocument> doc = do_QueryInterface(aDocument);
|
||||
NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
|
||||
|
||||
return NativeInit(doc, aMimeType, aFlags);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocumentEncoder::NativeInit(nsIDocument* aDocument,
|
||||
const nsAString& aMimeType,
|
||||
PRUint32 aFlags)
|
||||
{
|
||||
if (!aDocument)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
Initialize();
|
||||
|
||||
mDocument = do_QueryInterface(aDocument);
|
||||
NS_ENSURE_TRUE(mDocument, NS_ERROR_FAILURE);
|
||||
mDocument = aDocument;
|
||||
|
||||
mMimeType = aMimeType;
|
||||
|
||||
@ -266,6 +303,14 @@ nsDocumentEncoder::SetContainerNode(nsIDOMNode *aContainer)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocumentEncoder::SetNativeContainerNode(nsINode* aContainer)
|
||||
{
|
||||
mNodeIsContainer = PR_TRUE;
|
||||
mNode = aContainer;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocumentEncoder::SetCharset(const nsACString& aCharset)
|
||||
{
|
||||
@ -928,11 +973,26 @@ nsDocumentEncoder::EncodeToString(nsAString& aOutputString)
|
||||
|
||||
aOutputString.Truncate();
|
||||
|
||||
nsCAutoString progId(NS_CONTENTSERIALIZER_CONTRACTID_PREFIX);
|
||||
AppendUTF16toUTF8(mMimeType, progId);
|
||||
nsString output;
|
||||
static const size_t bufferSize = 2048;
|
||||
if (!mCachedBuffer) {
|
||||
mCachedBuffer = nsStringBuffer::Alloc(bufferSize);
|
||||
}
|
||||
NS_ASSERTION(!mCachedBuffer->IsReadonly(),
|
||||
"DocumentEncoder shouldn't keep reference to non-readonly buffer!");
|
||||
static_cast<PRUnichar*>(mCachedBuffer->Data())[0] = PRUnichar(0);
|
||||
mCachedBuffer->ToString(0, output, PR_TRUE);
|
||||
// output owns the buffer now!
|
||||
mCachedBuffer = nsnull;
|
||||
|
||||
|
||||
mSerializer = do_CreateInstance(progId.get());
|
||||
NS_ENSURE_TRUE(mSerializer, NS_ERROR_NOT_IMPLEMENTED);
|
||||
if (!mSerializer) {
|
||||
nsCAutoString progId(NS_CONTENTSERIALIZER_CONTRACTID_PREFIX);
|
||||
AppendUTF16toUTF8(mMimeType, progId);
|
||||
|
||||
mSerializer = do_CreateInstance(progId.get());
|
||||
NS_ENSURE_TRUE(mSerializer, NS_ERROR_NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
@ -966,47 +1026,59 @@ nsDocumentEncoder::EncodeToString(nsAString& aOutputString)
|
||||
if (node != prevNode) {
|
||||
if (prevNode) {
|
||||
nsCOMPtr<nsINode> p = do_QueryInterface(prevNode);
|
||||
rv = SerializeNodeEnd(p, aOutputString);
|
||||
rv = SerializeNodeEnd(p, output);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
prevNode = nsnull;
|
||||
}
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(node);
|
||||
if (content && content->Tag() == nsGkAtoms::tr) {
|
||||
nsCOMPtr<nsINode> n = do_QueryInterface(node);
|
||||
rv = SerializeNodeStart(n, 0, -1, aOutputString);
|
||||
rv = SerializeNodeStart(n, 0, -1, output);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
prevNode = node;
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIRange> r = do_QueryInterface(range);
|
||||
rv = SerializeRangeToString(r, aOutputString);
|
||||
rv = SerializeRangeToString(r, output);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
if (prevNode) {
|
||||
nsCOMPtr<nsINode> p = do_QueryInterface(prevNode);
|
||||
rv = SerializeNodeEnd(p, aOutputString);
|
||||
rv = SerializeNodeEnd(p, output);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
mSelection = nsnull;
|
||||
} else if (mRange) {
|
||||
rv = SerializeRangeToString(mRange, aOutputString);
|
||||
rv = SerializeRangeToString(mRange, output);
|
||||
|
||||
mRange = nsnull;
|
||||
} else if (mNode) {
|
||||
rv = SerializeToStringRecursive(mNode, aOutputString, mNodeIsContainer);
|
||||
rv = SerializeToStringRecursive(mNode, output, mNodeIsContainer);
|
||||
mNode = nsnull;
|
||||
} else {
|
||||
rv = mSerializer->AppendDocumentStart(mDocument, aOutputString);
|
||||
rv = mSerializer->AppendDocumentStart(mDocument, output);
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = SerializeToStringRecursive(mDocument, aOutputString, PR_FALSE);
|
||||
rv = SerializeToStringRecursive(mDocument, output, PR_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = mSerializer->Flush(aOutputString);
|
||||
rv = mSerializer->Flush(output);
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
aOutputString.Append(output.get(), output.Length());
|
||||
}
|
||||
mCachedBuffer = nsStringBuffer::FromString(output);
|
||||
// Try to cache the buffer.
|
||||
if (mCachedBuffer && mCachedBuffer->StorageSize() == bufferSize &&
|
||||
!mCachedBuffer->IsReadonly()) {
|
||||
mCachedBuffer->AddRef();
|
||||
} else {
|
||||
mCachedBuffer = nsnull;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
@ -101,6 +101,8 @@ nsXHTMLContentSerializer::Init(PRUint32 aFlags, PRUint32 aWrapColumn,
|
||||
const char* aCharSet, PRBool aIsCopying,
|
||||
PRBool aRewriteEncodingDeclaration)
|
||||
{
|
||||
mInBody = 0;
|
||||
|
||||
// The previous version of the HTML serializer did implicit wrapping
|
||||
// when there is no flags, so we keep wrapping in order to keep
|
||||
// compatibility with the existing calling code
|
||||
|
@ -111,6 +111,15 @@ nsXMLContentSerializer::Init(PRUint32 aFlags, PRUint32 aWrapColumn,
|
||||
const char* aCharSet, PRBool aIsCopying,
|
||||
PRBool aRewriteEncodingDeclaration)
|
||||
{
|
||||
mPrefixIndex = 0;
|
||||
mColPos = 0;
|
||||
mIndentOverflow = 0;
|
||||
mIsIndentationAddedOnCurrentLine = PR_FALSE;
|
||||
mInAttribute = PR_FALSE;
|
||||
mAddNewlineForRootNode = PR_FALSE;
|
||||
mAddSpace = PR_FALSE;
|
||||
mMayIgnoreLineBreakSequence = PR_FALSE;
|
||||
|
||||
mCharset = aCharSet;
|
||||
mFlags = aFlags;
|
||||
|
||||
|
@ -655,13 +655,11 @@ nsGenericHTMLElement::GetInnerHTML(nsAString& aInnerHTML)
|
||||
{
|
||||
aInnerHTML.Truncate();
|
||||
|
||||
nsCOMPtr<nsIDocument> doc = GetOwnerDoc();
|
||||
nsIDocument* doc = GetOwnerDoc();
|
||||
if (!doc) {
|
||||
return NS_OK; // We rely on the document for doing HTML conversion
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMNode> thisNode(do_QueryInterface(static_cast<nsIContent *>
|
||||
(this)));
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
nsAutoString contentType;
|
||||
@ -670,13 +668,15 @@ nsGenericHTMLElement::GetInnerHTML(nsAString& aInnerHTML)
|
||||
} else {
|
||||
doc->GetContentType(contentType);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocumentEncoder> docEncoder;
|
||||
docEncoder =
|
||||
do_CreateInstance(PromiseFlatCString(
|
||||
|
||||
nsCOMPtr<nsIDocumentEncoder> docEncoder = doc->GetCachedEncoder();
|
||||
if (!docEncoder) {
|
||||
docEncoder =
|
||||
do_CreateInstance(PromiseFlatCString(
|
||||
nsDependentCString(NS_DOC_ENCODER_CONTRACTID_BASE) +
|
||||
NS_ConvertUTF16toUTF8(contentType)
|
||||
).get());
|
||||
}
|
||||
if (!(docEncoder || doc->IsHTML())) {
|
||||
// This could be some type for which we create a synthetic document. Try
|
||||
// again as XML
|
||||
@ -686,17 +686,19 @@ nsGenericHTMLElement::GetInnerHTML(nsAString& aInnerHTML)
|
||||
|
||||
NS_ENSURE_TRUE(docEncoder, NS_ERROR_FAILURE);
|
||||
|
||||
nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(doc);
|
||||
rv = docEncoder->Init(domDoc, contentType,
|
||||
nsIDocumentEncoder::OutputEncodeBasicEntities |
|
||||
// Output DOM-standard newlines
|
||||
nsIDocumentEncoder::OutputLFLineBreak |
|
||||
// Don't do linebreaking that's not present in the source
|
||||
nsIDocumentEncoder::OutputRaw);
|
||||
rv = docEncoder->NativeInit(doc, contentType,
|
||||
nsIDocumentEncoder::OutputEncodeBasicEntities |
|
||||
// Output DOM-standard newlines
|
||||
nsIDocumentEncoder::OutputLFLineBreak |
|
||||
// Don't do linebreaking that's not present in
|
||||
// the source
|
||||
nsIDocumentEncoder::OutputRaw);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
docEncoder->SetContainerNode(thisNode);
|
||||
return docEncoder->EncodeToString(aInnerHTML);
|
||||
docEncoder->SetNativeContainerNode(this);
|
||||
rv = docEncoder->EncodeToString(aInnerHTML);
|
||||
doc->SetCachedEncoder(docEncoder);
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -342,7 +342,7 @@ nsHTMLDocument::ResetToURI(nsIURI *aURI, nsILoadGroup *aLoadGroup,
|
||||
// Make the content type default to "text/html", we are a HTML
|
||||
// document, after all. Once we start getting data, this may be
|
||||
// changed.
|
||||
mContentType = "text/html";
|
||||
SetContentTypeInternal(nsDependentCString("text/html"));
|
||||
}
|
||||
|
||||
nsStyleSet::sheetType
|
||||
@ -2035,7 +2035,7 @@ nsHTMLDocument::OpenCommon(const nsACString& aContentType, PRBool aReplace)
|
||||
}
|
||||
|
||||
// This will be propagated to the parser when someone actually calls write()
|
||||
mContentType = aContentType;
|
||||
SetContentTypeInternal(aContentType);
|
||||
|
||||
mWriteState = eDocumentOpened;
|
||||
|
||||
@ -2134,7 +2134,7 @@ nsHTMLDocument::Close()
|
||||
|
||||
++mWriteLevel;
|
||||
rv = mParser->Parse(EmptyString(), mParser->GetRootContextKey(),
|
||||
mContentType, PR_TRUE);
|
||||
GetContentTypeInternal(), PR_TRUE);
|
||||
--mWriteLevel;
|
||||
|
||||
// XXX Make sure that all the document.written content is
|
||||
@ -2234,11 +2234,11 @@ nsHTMLDocument::WriteCommon(const nsAString& aText,
|
||||
// why pay that price when we don't need to?
|
||||
if (aNewlineTerminate) {
|
||||
rv = mParser->Parse(aText + new_line,
|
||||
key, mContentType,
|
||||
key, GetContentTypeInternal(),
|
||||
(mWriteState == eNotWriting || (mWriteLevel > 1)));
|
||||
} else {
|
||||
rv = mParser->Parse(aText,
|
||||
key, mContentType,
|
||||
key, GetContentTypeInternal(),
|
||||
(mWriteState == eNotWriting || (mWriteLevel > 1)));
|
||||
}
|
||||
|
||||
|
@ -165,8 +165,10 @@ class nsStringBuffer
|
||||
* however, string length is always measured in storage units
|
||||
* (2-byte units for wide strings).
|
||||
*/
|
||||
NS_COM void ToString(PRUint32 len, nsAString &str);
|
||||
NS_COM void ToString(PRUint32 len, nsACString &str);
|
||||
NS_COM void ToString(PRUint32 len, nsAString &str,
|
||||
PRBool aMoveOwnership = PR_FALSE);
|
||||
NS_COM void ToString(PRUint32 len, nsACString &str,
|
||||
PRBool aMoveOwnership = PR_FALSE);
|
||||
};
|
||||
|
||||
#endif /* !defined(nsStringBuffer_h__ */
|
||||
|
@ -264,7 +264,8 @@ nsStringBuffer::FromString(const nsACString& str)
|
||||
}
|
||||
|
||||
void
|
||||
nsStringBuffer::ToString(PRUint32 len, nsAString &str)
|
||||
nsStringBuffer::ToString(PRUint32 len, nsAString &str,
|
||||
PRBool aMoveOwnership)
|
||||
{
|
||||
PRUnichar* data = static_cast<PRUnichar*>(Data());
|
||||
|
||||
@ -275,12 +276,15 @@ nsStringBuffer::ToString(PRUint32 len, nsAString &str)
|
||||
PRUint32 flags = accessor->flags();
|
||||
flags = (flags & 0xFFFF0000) | nsSubstring::F_SHARED | nsSubstring::F_TERMINATED;
|
||||
|
||||
AddRef();
|
||||
if (!aMoveOwnership) {
|
||||
AddRef();
|
||||
}
|
||||
accessor->set(data, len, flags);
|
||||
}
|
||||
|
||||
void
|
||||
nsStringBuffer::ToString(PRUint32 len, nsACString &str)
|
||||
nsStringBuffer::ToString(PRUint32 len, nsACString &str,
|
||||
PRBool aMoveOwnership)
|
||||
{
|
||||
char* data = static_cast<char*>(Data());
|
||||
|
||||
@ -291,7 +295,9 @@ nsStringBuffer::ToString(PRUint32 len, nsACString &str)
|
||||
PRUint32 flags = accessor->flags();
|
||||
flags = (flags & 0xFFFF0000) | nsCSubstring::F_SHARED | nsCSubstring::F_TERMINATED;
|
||||
|
||||
AddRef();
|
||||
if (!aMoveOwnership) {
|
||||
AddRef();
|
||||
}
|
||||
accessor->set(data, len, flags);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user