mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 509666 - Notify the right document in the HTML5 parser when nodes have been moved between documents during the parse. r=bnewman.
--HG-- extra : rebase_source : ecf04f12b213b6be84887b83c98e15817074d374
This commit is contained in:
parent
bcac5a67b9
commit
841cc3cb3e
@ -58,6 +58,34 @@
|
|||||||
#include "nsIStyleSheetLinkingElement.h"
|
#include "nsIStyleSheetLinkingElement.h"
|
||||||
#include "nsIDOMDocumentType.h"
|
#include "nsIDOMDocumentType.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper class that opens a notification batch if the current doc
|
||||||
|
* is different from the executor doc.
|
||||||
|
*/
|
||||||
|
class NS_STACK_CLASS nsHtml5OtherDocUpdate {
|
||||||
|
public:
|
||||||
|
nsHtml5OtherDocUpdate(nsIDocument* aCurrentDoc, nsIDocument* aExecutorDoc)
|
||||||
|
{
|
||||||
|
NS_PRECONDITION(aCurrentDoc, "Node has no doc?");
|
||||||
|
NS_PRECONDITION(aExecutorDoc, "Executor has no doc?");
|
||||||
|
if (NS_LIKELY(aCurrentDoc == aExecutorDoc)) {
|
||||||
|
mDocument = nsnull;
|
||||||
|
} else {
|
||||||
|
mDocument = aCurrentDoc;
|
||||||
|
aCurrentDoc->BeginUpdate(UPDATE_CONTENT_MODEL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~nsHtml5OtherDocUpdate()
|
||||||
|
{
|
||||||
|
if (NS_UNLIKELY(mDocument)) {
|
||||||
|
mDocument->EndUpdate(UPDATE_CONTENT_MODEL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
nsIDocument* mDocument;
|
||||||
|
};
|
||||||
|
|
||||||
nsHtml5TreeOperation::nsHtml5TreeOperation()
|
nsHtml5TreeOperation::nsHtml5TreeOperation()
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
: mOpCode(eTreeOpUninitialized)
|
: mOpCode(eTreeOpUninitialized)
|
||||||
@ -102,8 +130,27 @@ nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder,
|
|||||||
case eTreeOpAppend: {
|
case eTreeOpAppend: {
|
||||||
nsIContent* node = *(mOne.node);
|
nsIContent* node = *(mOne.node);
|
||||||
nsIContent* parent = *(mTwo.node);
|
nsIContent* parent = *(mTwo.node);
|
||||||
aBuilder->PostPendingAppendNotification(parent, node);
|
|
||||||
|
nsIDocument* executorDoc = aBuilder->GetDocument();
|
||||||
|
NS_ASSERTION(executorDoc, "Null doc on executor");
|
||||||
|
nsIDocument* parentDoc = parent->GetOwnerDoc();
|
||||||
|
NS_ASSERTION(parentDoc, "Null owner doc on old node.");
|
||||||
|
|
||||||
|
if (NS_LIKELY(executorDoc == parentDoc)) {
|
||||||
|
// the usual case. the parent is in the parser's doc
|
||||||
|
aBuilder->PostPendingAppendNotification(parent, node);
|
||||||
|
rv = parent->AppendChildTo(node, PR_FALSE);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The parent has been moved to another doc
|
||||||
|
parentDoc->BeginUpdate(UPDATE_CONTENT_MODEL);
|
||||||
|
|
||||||
|
PRUint32 childCount = parent->GetChildCount();
|
||||||
rv = parent->AppendChildTo(node, PR_FALSE);
|
rv = parent->AppendChildTo(node, PR_FALSE);
|
||||||
|
nsNodeUtils::ContentAppended(parent, childCount);
|
||||||
|
|
||||||
|
parentDoc->EndUpdate(UPDATE_CONTENT_MODEL);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
case eTreeOpDetach: {
|
case eTreeOpDetach: {
|
||||||
@ -111,6 +158,8 @@ nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder,
|
|||||||
aBuilder->FlushPendingAppendNotifications();
|
aBuilder->FlushPendingAppendNotifications();
|
||||||
nsIContent* parent = node->GetParent();
|
nsIContent* parent = node->GetParent();
|
||||||
if (parent) {
|
if (parent) {
|
||||||
|
nsHtml5OtherDocUpdate update(parent->GetOwnerDoc(),
|
||||||
|
aBuilder->GetDocument());
|
||||||
PRUint32 pos = parent->IndexOf(node);
|
PRUint32 pos = parent->IndexOf(node);
|
||||||
NS_ASSERTION((pos >= 0), "Element not found as child of its parent");
|
NS_ASSERTION((pos >= 0), "Element not found as child of its parent");
|
||||||
rv = parent->RemoveChildAt(pos, PR_TRUE, PR_FALSE);
|
rv = parent->RemoveChildAt(pos, PR_TRUE, PR_FALSE);
|
||||||
@ -122,6 +171,10 @@ nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder,
|
|||||||
nsIContent* node = *(mOne.node);
|
nsIContent* node = *(mOne.node);
|
||||||
nsIContent* parent = *(mTwo.node);
|
nsIContent* parent = *(mTwo.node);
|
||||||
aBuilder->FlushPendingAppendNotifications();
|
aBuilder->FlushPendingAppendNotifications();
|
||||||
|
|
||||||
|
nsHtml5OtherDocUpdate update(parent->GetOwnerDoc(),
|
||||||
|
aBuilder->GetDocument());
|
||||||
|
|
||||||
PRUint32 childCount = parent->GetChildCount();
|
PRUint32 childCount = parent->GetChildCount();
|
||||||
PRBool didAppend = PR_FALSE;
|
PRBool didAppend = PR_FALSE;
|
||||||
while (node->GetChildCount()) {
|
while (node->GetChildCount()) {
|
||||||
@ -142,16 +195,40 @@ nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder,
|
|||||||
nsIContent* parent = *(mTwo.node);
|
nsIContent* parent = *(mTwo.node);
|
||||||
nsIContent* table = *(mThree.node);
|
nsIContent* table = *(mThree.node);
|
||||||
nsIContent* foster = table->GetParent();
|
nsIContent* foster = table->GetParent();
|
||||||
|
|
||||||
if (foster && foster->IsNodeOfType(nsINode::eELEMENT)) {
|
if (foster && foster->IsNodeOfType(nsINode::eELEMENT)) {
|
||||||
aBuilder->FlushPendingAppendNotifications();
|
aBuilder->FlushPendingAppendNotifications();
|
||||||
|
|
||||||
|
nsHtml5OtherDocUpdate update(foster->GetOwnerDoc(),
|
||||||
|
aBuilder->GetDocument());
|
||||||
|
|
||||||
PRUint32 pos = foster->IndexOf(table);
|
PRUint32 pos = foster->IndexOf(table);
|
||||||
rv = foster->InsertChildAt(node, pos, PR_FALSE);
|
rv = foster->InsertChildAt(node, pos, PR_FALSE);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
nsNodeUtils::ContentInserted(foster, node, pos);
|
nsNodeUtils::ContentInserted(foster, node, pos);
|
||||||
} else {
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsIDocument* executorDoc = aBuilder->GetDocument();
|
||||||
|
NS_ASSERTION(executorDoc, "Null doc on executor");
|
||||||
|
nsIDocument* parentDoc = parent->GetOwnerDoc();
|
||||||
|
NS_ASSERTION(parentDoc, "Null owner doc on old node.");
|
||||||
|
|
||||||
|
if (NS_LIKELY(executorDoc == parentDoc)) {
|
||||||
|
// the usual case. the parent is in the parser's doc
|
||||||
aBuilder->PostPendingAppendNotification(parent, node);
|
aBuilder->PostPendingAppendNotification(parent, node);
|
||||||
rv = parent->AppendChildTo(node, PR_FALSE);
|
rv = parent->AppendChildTo(node, PR_FALSE);
|
||||||
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The parent has been moved to another doc
|
||||||
|
parentDoc->BeginUpdate(UPDATE_CONTENT_MODEL);
|
||||||
|
|
||||||
|
PRUint32 childCount = parent->GetChildCount();
|
||||||
|
rv = parent->AppendChildTo(node, PR_FALSE);
|
||||||
|
nsNodeUtils::ContentAppended(parent, childCount);
|
||||||
|
|
||||||
|
parentDoc->EndUpdate(UPDATE_CONTENT_MODEL);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
case eTreeOpAppendToDocument: {
|
case eTreeOpAppendToDocument: {
|
||||||
@ -168,6 +245,9 @@ nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder,
|
|||||||
nsIContent* node = *(mOne.node);
|
nsIContent* node = *(mOne.node);
|
||||||
nsHtml5HtmlAttributes* attributes = mTwo.attributes;
|
nsHtml5HtmlAttributes* attributes = mTwo.attributes;
|
||||||
|
|
||||||
|
nsHtml5OtherDocUpdate update(node->GetOwnerDoc(),
|
||||||
|
aBuilder->GetDocument());
|
||||||
|
|
||||||
nsIDocument* document = node->GetCurrentDoc();
|
nsIDocument* document = node->GetCurrentDoc();
|
||||||
|
|
||||||
PRInt32 len = attributes->getLength();
|
PRInt32 len = attributes->getLength();
|
||||||
|
Loading…
Reference in New Issue
Block a user