Bug 1352882 - Part 1. Add releasing nsIDcoument option to recycle nsIDocumentEncoder. r?smaug
Editor uses weak reference for nsIDocument. But nsDocumentEncoder uses strong reference for it. So to recycle it, editor wants the option that it release nsIDocument into nsDocumentEncoder after EncodeTo* is called.
MozReview-Commit-ID: K3E9XhgD8FY
--- a/dom/base/nsDocumentEncoder.cpp
+++ b/dom/base/nsDocumentEncoder.cpp
@@ -41,16 +41,17 @@
#include "nsITransferable.h" // for kUnicodeMime
#include "nsContentUtils.h"
#include "nsNodeUtils.h"
#include "nsUnicharUtils.h"
#include "nsReadableUtils.h"
#include "nsTArray.h"
#include "nsIFrame.h"
#include "nsStringBuffer.h"
+#include "mozilla/AutoRestore.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/ShadowRoot.h"
#include "mozilla/dom/EncodingUtils.h"
#include "nsLayoutUtils.h"
using namespace mozilla;
using namespace mozilla::dom;
@@ -137,16 +138,35 @@ protected:
return false;
}
}
return true;
}
virtual bool IncludeInContext(nsINode *aNode);
+ class MOZ_STACK_CLASS AutoReleaseDocumentIfNeeded final
+ {
+ public:
+ AutoReleaseDocumentIfNeeded(nsDocumentEncoder* aEncoder)
+ : mEncoder(aEncoder)
+ {
+ }
+
+ ~AutoReleaseDocumentIfNeeded()
+ {
+ if (mEncoder->mFlags & ReleaseDocumentAfterOutput) {
+ mEncoder->mDocument = nullptr;
+ }
+ }
+
+ private:
+ nsDocumentEncoder* mEncoder;
+ };
+
nsCOMPtr<nsIDocument> mDocument;
nsCOMPtr<nsISelection> mSelection;
RefPtr<nsRange> mRange;
nsCOMPtr<nsINode> mNode;
nsCOMPtr<nsIOutputStream> mStream;
nsCOMPtr<nsIContentSerializer> mSerializer;
nsCOMPtr<nsIUnicodeEncoder> mUnicodeEncoder;
nsCOMPtr<nsINode> mCommonParent;
@@ -1004,16 +1024,18 @@ nsDocumentEncoder::EncodeToString(nsAStr
NS_IMETHODIMP
nsDocumentEncoder::EncodeToStringWithMaxLength(uint32_t aMaxLength,
nsAString& aOutputString)
{
if (!mDocument)
return NS_ERROR_NOT_INITIALIZED;
+ AutoReleaseDocumentIfNeeded autoReleaseDocument(this);
+
aOutputString.Truncate();
nsString output;
static const size_t bufferSize = 2048;
if (!mCachedBuffer) {
mCachedBuffer = nsStringBuffer::Alloc(bufferSize).take();
if (NS_WARN_IF(!mCachedBuffer)) {
return NS_ERROR_OUT_OF_MEMORY;
--- a/dom/base/nsIDocumentEncoder.idl
+++ b/dom/base/nsIDocumentEncoder.idl
@@ -243,16 +243,23 @@ interface nsIDocumentEncoder : nsISuppor
/**
* Disallow breaking of long character strings. This is important
* for serializing e-mail which contains CJK strings. These must
* not be broken just as "normal" longs strings aren't broken.
*/
const unsigned long OutputDisallowLineBreaking = (1 << 27);
/**
+ * Release reference of nsIDocument after using encodeTo* method to recycle
+ * this encoder without holding nsIDocument. To use this encoder again,
+ * we have to call init again.
+ */
+ const unsigned long ReleaseDocumentAfterOutput = (1 << 28);
+
+ /**
* 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.
* @param aFlags Flags to use while encoding. May also be set by SetFlags.
*/
void init(in nsIDOMDocument aDocument,
in AString aMimeType,
in unsigned long aFlags);