mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 890284. Stop splitting textnodes in the XML content sink. r=peterv
This commit is contained in:
parent
628f8c6a07
commit
e8803f0d42
@ -96,16 +96,12 @@ NS_NewXMLContentSink(nsIXMLContentSink** aResult,
|
||||
}
|
||||
|
||||
nsXMLContentSink::nsXMLContentSink()
|
||||
: mConstrainSize(true),
|
||||
mPrettyPrintXML(true)
|
||||
: mPrettyPrintXML(true)
|
||||
{
|
||||
}
|
||||
|
||||
nsXMLContentSink::~nsXMLContentSink()
|
||||
{
|
||||
if (mText) {
|
||||
PR_Free(mText); // Doesn't null out, unlike PR_FREEIF
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -475,7 +471,6 @@ nsXMLContentSink::CreateElement(const char16_t** aAtts, uint32_t aAttsCount,
|
||||
nsCOMPtr<nsIScriptElement> sele = do_QueryInterface(content);
|
||||
sele->SetScriptLineNumber(aLineNumber);
|
||||
sele->SetCreatorParser(GetParser());
|
||||
mConstrainSize = false;
|
||||
}
|
||||
|
||||
// XHTML needs some special attention
|
||||
@ -552,7 +547,6 @@ nsXMLContentSink::CloseElement(nsIContent* aContent)
|
||||
if (nodeInfo->Equals(nsGkAtoms::script, kNameSpaceID_XHTML)
|
||||
|| nodeInfo->Equals(nsGkAtoms::script, kNameSpaceID_SVG)
|
||||
) {
|
||||
mConstrainSize = true;
|
||||
nsCOMPtr<nsIScriptElement> sele = do_QueryInterface(aContent);
|
||||
|
||||
if (mPreventScriptExecution) {
|
||||
@ -778,26 +772,19 @@ nsXMLContentSink::FlushText(bool aReleaseTextNode)
|
||||
|
||||
if (mTextLength != 0) {
|
||||
if (mLastTextNode) {
|
||||
if ((mLastTextNodeSize + mTextLength) > mTextSize && !mXSLTProcessor) {
|
||||
mLastTextNodeSize = 0;
|
||||
mLastTextNode = nullptr;
|
||||
FlushText(aReleaseTextNode);
|
||||
} else {
|
||||
bool notify = HaveNotifiedForCurrentContent();
|
||||
// We could probably always increase mInNotification here since
|
||||
// if AppendText doesn't notify it shouldn't trigger evil code.
|
||||
// But just in case it does, we don't want to mask any notifications.
|
||||
if (notify) {
|
||||
++mInNotification;
|
||||
}
|
||||
rv = mLastTextNode->AppendText(mText, mTextLength, notify);
|
||||
if (notify) {
|
||||
--mInNotification;
|
||||
}
|
||||
|
||||
mLastTextNodeSize += mTextLength;
|
||||
mTextLength = 0;
|
||||
bool notify = HaveNotifiedForCurrentContent();
|
||||
// We could probably always increase mInNotification here since
|
||||
// if AppendText doesn't notify it shouldn't trigger evil code.
|
||||
// But just in case it does, we don't want to mask any notifications.
|
||||
if (notify) {
|
||||
++mInNotification;
|
||||
}
|
||||
rv = mLastTextNode->AppendText(mText, mTextLength, notify);
|
||||
if (notify) {
|
||||
--mInNotification;
|
||||
}
|
||||
|
||||
mTextLength = 0;
|
||||
} else {
|
||||
nsRefPtr<nsTextNode> textContent = new nsTextNode(mNodeInfoManager);
|
||||
|
||||
@ -805,7 +792,6 @@ nsXMLContentSink::FlushText(bool aReleaseTextNode)
|
||||
|
||||
// Set the text in the text node
|
||||
textContent->SetText(mText, mTextLength, false);
|
||||
mLastTextNodeSize += mTextLength;
|
||||
mTextLength = 0;
|
||||
|
||||
// Add text to its parent
|
||||
@ -814,7 +800,6 @@ nsXMLContentSink::FlushText(bool aReleaseTextNode)
|
||||
}
|
||||
|
||||
if (aReleaseTextNode) {
|
||||
mLastTextNodeSize = 0;
|
||||
mLastTextNode = nullptr;
|
||||
}
|
||||
|
||||
@ -1437,41 +1422,19 @@ nsresult
|
||||
nsXMLContentSink::AddText(const char16_t* aText,
|
||||
int32_t aLength)
|
||||
{
|
||||
// Create buffer when we first need it
|
||||
if (0 == mTextSize) {
|
||||
mText = (char16_t *) PR_MALLOC(sizeof(char16_t) * NS_ACCUMULATION_BUFFER_SIZE);
|
||||
if (nullptr == mText) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
mTextSize = NS_ACCUMULATION_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
// Copy data from string into our buffer; flush buffer when it fills up
|
||||
// Copy data from string into our buffer; flush buffer when it fills up.
|
||||
int32_t offset = 0;
|
||||
while (0 != aLength) {
|
||||
int32_t amount = mTextSize - mTextLength;
|
||||
int32_t amount = NS_ACCUMULATION_BUFFER_SIZE - mTextLength;
|
||||
if (0 == amount) {
|
||||
// XSLT wants adjacent textnodes merged.
|
||||
if (mConstrainSize && !mXSLTProcessor) {
|
||||
nsresult rv = FlushText();
|
||||
if (NS_OK != rv) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
amount = mTextSize - mTextLength;
|
||||
}
|
||||
else {
|
||||
mTextSize += aLength;
|
||||
mText = (char16_t *) PR_REALLOC(mText, sizeof(char16_t) * mTextSize);
|
||||
if (nullptr == mText) {
|
||||
mTextSize = 0;
|
||||
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
amount = aLength;
|
||||
nsresult rv = FlushText(false);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
MOZ_ASSERT(mTextLength == 0);
|
||||
amount = NS_ACCUMULATION_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
if (amount > aLength) {
|
||||
amount = aLength;
|
||||
}
|
||||
|
@ -171,18 +171,15 @@ protected:
|
||||
|
||||
nsCOMPtr<nsIContent> mDocElement;
|
||||
nsCOMPtr<nsIContent> mCurrentHead; // When set, we're in an XHTML <haed>
|
||||
char16_t* mText;
|
||||
|
||||
XMLContentSinkState mState;
|
||||
|
||||
// The length of the valid data in mText.
|
||||
int32_t mTextLength;
|
||||
int32_t mTextSize;
|
||||
|
||||
int32_t mNotifyLevel;
|
||||
nsCOMPtr<nsIContent> mLastTextNode;
|
||||
int32_t mLastTextNodeSize;
|
||||
|
||||
uint8_t mConstrainSize : 1;
|
||||
uint8_t mPrettyPrintXML : 1;
|
||||
uint8_t mPrettyPrintHasSpecialRoot : 1;
|
||||
uint8_t mPrettyPrintHasFactoredElements : 1;
|
||||
@ -194,6 +191,10 @@ protected:
|
||||
nsTArray<StackNode> mContentStack;
|
||||
|
||||
nsCOMPtr<nsIDocumentTransformer> mXSLTProcessor;
|
||||
|
||||
static const int NS_ACCUMULATION_BUFFER_SIZE = 4096;
|
||||
// Our currently accumulated text that we have not flushed to a textnode yet.
|
||||
char16_t mText[NS_ACCUMULATION_BUFFER_SIZE];
|
||||
};
|
||||
|
||||
#endif // nsXMLContentSink_h__
|
||||
|
Loading…
Reference in New Issue
Block a user