зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1409951 - Use a stack to end serializer contexts instead of recomputing them. r=smaug
MozReview-Commit-ID: FOd8AUmtYyA
This commit is contained in:
Родитель
7b51513583
Коммит
009840a99b
|
@ -49,6 +49,7 @@
|
|||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/dom/ShadowRoot.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
#include "mozilla/ScopeExit.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
@ -92,8 +93,8 @@ protected:
|
|||
int32_t aDepth);
|
||||
nsresult SerializeRangeContextStart(const nsTArray<nsINode*>& aAncestorArray,
|
||||
nsAString& aString);
|
||||
nsresult SerializeRangeContextEnd(const nsTArray<nsINode*>& aAncestorArray,
|
||||
nsAString& aString);
|
||||
nsresult SerializeRangeContextEnd(nsAString& aString);
|
||||
|
||||
virtual int32_t
|
||||
GetImmediateContextCount(const nsTArray<nsINode*>& aAncestorArray)
|
||||
{
|
||||
|
@ -185,6 +186,7 @@ protected:
|
|||
AutoTArray<int32_t, 8> mStartOffsets;
|
||||
AutoTArray<nsIContent*, 8> mEndNodes;
|
||||
AutoTArray<int32_t, 8> mEndOffsets;
|
||||
AutoTArray<AutoTArray<nsINode*, 8>, 8> mRangeContexts;
|
||||
// Whether the serializer cares about being notified to scan elements to
|
||||
// keep track of whether they are preformatted. This stores the out
|
||||
// argument of nsIContentSerializer::Init().
|
||||
|
@ -874,6 +876,9 @@ nsDocumentEncoder::SerializeRangeContextStart(const nsTArray<nsINode*>& aAncesto
|
|||
if (mDisableContextSerialize) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
AutoTArray<nsINode*, 8>* serializedContext = mRangeContexts.AppendElement();
|
||||
|
||||
int32_t i = aAncestorArray.Length(), j;
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
|
@ -889,7 +894,7 @@ nsDocumentEncoder::SerializeRangeContextStart(const nsTArray<nsINode*>& aAncesto
|
|||
// Either a general inclusion or as immediate context
|
||||
if (IncludeInContext(node) || i < j) {
|
||||
rv = SerializeNodeStart(node, 0, -1, aString);
|
||||
|
||||
serializedContext->AppendElement(node);
|
||||
if (NS_FAILED(rv))
|
||||
break;
|
||||
}
|
||||
|
@ -899,34 +904,24 @@ nsDocumentEncoder::SerializeRangeContextStart(const nsTArray<nsINode*>& aAncesto
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsDocumentEncoder::SerializeRangeContextEnd(const nsTArray<nsINode*>& aAncestorArray,
|
||||
nsAString& aString)
|
||||
nsDocumentEncoder::SerializeRangeContextEnd(nsAString& aString)
|
||||
{
|
||||
if (mDisableContextSerialize) {
|
||||
return NS_OK;
|
||||
}
|
||||
int32_t i = 0, j;
|
||||
int32_t count = aAncestorArray.Length();
|
||||
|
||||
MOZ_RELEASE_ASSERT(!mRangeContexts.IsEmpty(), "Tried to end context without starting one.");
|
||||
AutoTArray<nsINode*, 8>& serializedContext = mRangeContexts.LastElement();
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
for (nsINode* node : Reversed(serializedContext)) {
|
||||
rv = SerializeNodeEnd(node, aString);
|
||||
|
||||
// currently only for table-related elements
|
||||
j = GetImmediateContextCount(aAncestorArray);
|
||||
|
||||
while (i < count) {
|
||||
nsINode *node = aAncestorArray.ElementAt(i++);
|
||||
|
||||
if (!node)
|
||||
if (NS_FAILED(rv))
|
||||
break;
|
||||
|
||||
// Either a general inclusion or as immediate context
|
||||
if (IncludeInContext(node) || i - 1 < j) {
|
||||
rv = SerializeNodeEnd(node, aString);
|
||||
|
||||
if (NS_FAILED(rv))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mRangeContexts.RemoveElementAt(mRangeContexts.Length() - 1);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -992,7 +987,7 @@ nsDocumentEncoder::SerializeRangeToString(nsRange *aRange,
|
|||
rv = SerializeRangeNodes(aRange, mCommonParent, aOutputString, 0);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
rv = SerializeRangeContextEnd(mCommonAncestors, aOutputString);
|
||||
rv = SerializeRangeContextEnd(aOutputString);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return rv;
|
||||
|
@ -1029,6 +1024,11 @@ NS_IMETHODIMP
|
|||
nsDocumentEncoder::EncodeToStringWithMaxLength(uint32_t aMaxLength,
|
||||
nsAString& aOutputString)
|
||||
{
|
||||
MOZ_ASSERT(mRangeContexts.IsEmpty(), "Re-entrant call to nsDocumentEncoder.");
|
||||
auto rangeContextGuard = MakeScopeExit([&] {
|
||||
mRangeContexts.Clear();
|
||||
});
|
||||
|
||||
if (!mDocument)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
|
@ -1112,10 +1112,8 @@ nsDocumentEncoder::EncodeToStringWithMaxLength(uint32_t aMaxLength,
|
|||
prevNode = node;
|
||||
} else if (prevNode) {
|
||||
// Went from a <tr> to a non-<tr>
|
||||
mCommonAncestors.Clear();
|
||||
nsContentUtils::GetAncestors(p->GetParentNode(), mCommonAncestors);
|
||||
mDisableContextSerialize = false;
|
||||
rv = SerializeRangeContextEnd(mCommonAncestors, output);
|
||||
rv = SerializeRangeContextEnd(output);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
prevNode = nullptr;
|
||||
}
|
||||
|
@ -1134,10 +1132,8 @@ nsDocumentEncoder::EncodeToStringWithMaxLength(uint32_t aMaxLength,
|
|||
nsCOMPtr<nsINode> p = do_QueryInterface(prevNode);
|
||||
rv = SerializeNodeEnd(p, output);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
mCommonAncestors.Clear();
|
||||
nsContentUtils::GetAncestors(p->GetParentNode(), mCommonAncestors);
|
||||
mDisableContextSerialize = false;
|
||||
rv = SerializeRangeContextEnd(mCommonAncestors, output);
|
||||
rv = SerializeRangeContextEnd(output);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
|
@ -1196,6 +1192,10 @@ nsDocumentEncoder::EncodeToStringWithMaxLength(uint32_t aMaxLength,
|
|||
NS_IMETHODIMP
|
||||
nsDocumentEncoder::EncodeToStream(nsIOutputStream* aStream)
|
||||
{
|
||||
MOZ_ASSERT(mRangeContexts.IsEmpty(), "Re-entrant call to nsDocumentEncoder.");
|
||||
auto rangeContextGuard = MakeScopeExit([&] {
|
||||
mRangeContexts.Clear();
|
||||
});
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
if (!mDocument)
|
||||
|
|
|
@ -388,6 +388,7 @@ nsPlainTextSerializer::ScanElementForPreformat(Element* aElement)
|
|||
NS_IMETHODIMP
|
||||
nsPlainTextSerializer::ForgetElementForPreformat(Element* aElement)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(!mPreformatStack.empty(), "Tried to pop without previous push.");
|
||||
mPreformatStack.pop();
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче