mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 902618 - Parser notifies about subtree roots, but not their descendants, r=hsivonen,bz
This commit is contained in:
parent
fc9d66f955
commit
837c622779
@ -1350,6 +1350,8 @@ private:
|
||||
// Set if the element has a parser insertion mode other than "in body",
|
||||
// per the HTML5 "Parse state" section.
|
||||
ElementHasWeirdParserInsertionMode,
|
||||
// Parser sets this flag if it has notified about the node.
|
||||
ParserHasNotified,
|
||||
// Guard value
|
||||
BooleanFlagCount
|
||||
};
|
||||
@ -1490,6 +1492,8 @@ public:
|
||||
bool IsScopedStyleRoot() { return GetBoolFlag(ElementIsScopedStyleRoot); }
|
||||
bool HasRelevantHoverRules() const { return GetBoolFlag(NodeHasRelevantHoverRules); }
|
||||
void SetHasRelevantHoverRules() { SetBoolFlag(NodeHasRelevantHoverRules); }
|
||||
void SetParserHasNotified() { SetBoolFlag(ParserHasNotified); };
|
||||
bool HasParserNotified() { return GetBoolFlag(ParserHasNotified); }
|
||||
protected:
|
||||
void SetParentIsContent(bool aValue) { SetBoolFlag(ParentIsContent, aValue); }
|
||||
void SetInDocument() { SetBoolFlag(IsInDocument); }
|
||||
|
@ -13,14 +13,16 @@
|
||||
#include "nsDOMSettableTokenList.h"
|
||||
#include "nsFormSubmission.h"
|
||||
|
||||
NS_IMPL_NS_NEW_HTML_ELEMENT(Output)
|
||||
NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(Output)
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
HTMLOutputElement::HTMLOutputElement(already_AddRefed<nsINodeInfo>& aNodeInfo)
|
||||
HTMLOutputElement::HTMLOutputElement(already_AddRefed<nsINodeInfo>& aNodeInfo,
|
||||
FromParser aFromParser)
|
||||
: nsGenericHTMLFormElement(aNodeInfo)
|
||||
, mValueModeFlag(eModeDefault)
|
||||
, mIsDoneAddingChildren(!aFromParser)
|
||||
{
|
||||
AddMutationObserver(this);
|
||||
|
||||
@ -93,6 +95,12 @@ HTMLOutputElement::ParseAttribute(int32_t aNamespaceID, nsIAtom* aAttribute,
|
||||
aValue, aResult);
|
||||
}
|
||||
|
||||
void
|
||||
HTMLOutputElement::DoneAddingChildren(bool aHaveNotified)
|
||||
{
|
||||
mIsDoneAddingChildren = true;
|
||||
}
|
||||
|
||||
EventStates
|
||||
HTMLOutputElement::IntrinsicState() const
|
||||
{
|
||||
@ -170,7 +178,7 @@ HTMLOutputElement::HtmlFor()
|
||||
|
||||
void HTMLOutputElement::DescendantsChanged()
|
||||
{
|
||||
if (mValueModeFlag == eModeDefault) {
|
||||
if (mIsDoneAddingChildren && mValueModeFlag == eModeDefault) {
|
||||
if (!nsContentUtils::GetNodeTextContent(this, true, mDefaultValue)) {
|
||||
NS_RUNTIMEABORT("OOM");
|
||||
}
|
||||
|
@ -21,7 +21,8 @@ class HTMLOutputElement MOZ_FINAL : public nsGenericHTMLFormElement,
|
||||
public:
|
||||
using nsIConstraintValidation::GetValidationMessage;
|
||||
|
||||
HTMLOutputElement(already_AddRefed<nsINodeInfo>& aNodeInfo);
|
||||
HTMLOutputElement(already_AddRefed<nsINodeInfo>& aNodeInfo,
|
||||
FromParser aFromParser = NOT_FROM_PARSER);
|
||||
virtual ~HTMLOutputElement();
|
||||
|
||||
// nsISupports
|
||||
@ -39,6 +40,8 @@ public:
|
||||
bool ParseAttribute(int32_t aNamespaceID, nsIAtom* aAttribute,
|
||||
const nsAString& aValue, nsAttrValue& aResult) MOZ_OVERRIDE;
|
||||
|
||||
virtual void DoneAddingChildren(bool aHaveNotified) MOZ_OVERRIDE;
|
||||
|
||||
EventStates IntrinsicState() const MOZ_OVERRIDE;
|
||||
|
||||
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
@ -101,6 +104,7 @@ protected:
|
||||
};
|
||||
|
||||
ValueModeFlag mValueModeFlag;
|
||||
bool mIsDoneAddingChildren;
|
||||
nsString mDefaultValue;
|
||||
nsRefPtr<nsDOMSettableTokenList> mTokenList;
|
||||
};
|
||||
|
@ -33,7 +33,6 @@ EXPORTS += [
|
||||
'nsHtml5OplessBuilder.h',
|
||||
'nsHtml5OwningUTF16Buffer.h',
|
||||
'nsHtml5Parser.h',
|
||||
'nsHtml5PendingNotification.h',
|
||||
'nsHtml5PlainTextUtils.h',
|
||||
'nsHtml5RefPtr.h',
|
||||
'nsHtml5Speculation.h',
|
||||
|
@ -7,10 +7,10 @@
|
||||
#ifndef nsHtml5DocumentBuilder_h
|
||||
#define nsHtml5DocumentBuilder_h
|
||||
|
||||
#include "nsHtml5PendingNotification.h"
|
||||
#include "nsContentSink.h"
|
||||
#include "nsHtml5DocumentMode.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIContent.h"
|
||||
|
||||
typedef nsIContent* nsIContentPtr;
|
||||
|
||||
@ -29,74 +29,9 @@ public:
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
inline void HoldElement(nsIContent* aContent)
|
||||
inline void HoldElement(already_AddRefed<nsIContent> aContent)
|
||||
{
|
||||
mOwnedElements.AppendElement(aContent);
|
||||
}
|
||||
|
||||
inline bool HaveNotified(nsIContent* aNode)
|
||||
{
|
||||
NS_PRECONDITION(aNode, "HaveNotified called with null argument.");
|
||||
const nsHtml5PendingNotification* start = mPendingNotifications.Elements();
|
||||
const nsHtml5PendingNotification* end = start + mPendingNotifications.Length();
|
||||
for (;;) {
|
||||
nsIContent* parent = aNode->GetParent();
|
||||
if (!parent) {
|
||||
return true;
|
||||
}
|
||||
for (nsHtml5PendingNotification* iter = (nsHtml5PendingNotification*)start; iter < end; ++iter) {
|
||||
if (iter->Contains(parent)) {
|
||||
return iter->HaveNotifiedIndex(parent->IndexOf(aNode));
|
||||
}
|
||||
}
|
||||
aNode = parent;
|
||||
}
|
||||
}
|
||||
|
||||
void PostPendingAppendNotification(nsIContent* aParent, nsIContent* aChild)
|
||||
{
|
||||
bool newParent = true;
|
||||
const nsIContentPtr* first = mElementsSeenInThisAppendBatch.Elements();
|
||||
const nsIContentPtr* last = first + mElementsSeenInThisAppendBatch.Length() - 1;
|
||||
for (const nsIContentPtr* iter = last; iter >= first; --iter) {
|
||||
#ifdef DEBUG_NS_HTML5_TREE_OP_EXECUTOR_FLUSH
|
||||
sAppendBatchSlotsExamined++;
|
||||
#endif
|
||||
if (*iter == aParent) {
|
||||
newParent = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (aChild->IsElement()) {
|
||||
mElementsSeenInThisAppendBatch.AppendElement(aChild);
|
||||
}
|
||||
mElementsSeenInThisAppendBatch.AppendElement(aParent);
|
||||
if (newParent) {
|
||||
mPendingNotifications.AppendElement(aParent);
|
||||
}
|
||||
#ifdef DEBUG_NS_HTML5_TREE_OP_EXECUTOR_FLUSH
|
||||
sAppendBatchExaminations++;
|
||||
#endif
|
||||
}
|
||||
|
||||
void FlushPendingAppendNotifications()
|
||||
{
|
||||
NS_PRECONDITION(mFlushState == eInDocUpdate, "Notifications flushed outside update");
|
||||
mFlushState = eNotifying;
|
||||
const nsHtml5PendingNotification* start = mPendingNotifications.Elements();
|
||||
const nsHtml5PendingNotification* end = start + mPendingNotifications.Length();
|
||||
for (nsHtml5PendingNotification* iter = (nsHtml5PendingNotification*)start; iter < end; ++iter) {
|
||||
iter->Fire();
|
||||
}
|
||||
mPendingNotifications.Clear();
|
||||
#ifdef DEBUG_NS_HTML5_TREE_OP_EXECUTOR_FLUSH
|
||||
if (mElementsSeenInThisAppendBatch.Length() > sAppendBatchMaxSize) {
|
||||
sAppendBatchMaxSize = mElementsSeenInThisAppendBatch.Length();
|
||||
}
|
||||
#endif
|
||||
mElementsSeenInThisAppendBatch.Clear();
|
||||
NS_ASSERTION(mFlushState == eNotifying, "mFlushState out of sync");
|
||||
mFlushState = eInDocUpdate;
|
||||
*(mOwnedElements.AppendElement()) = aContent;
|
||||
}
|
||||
|
||||
nsresult Init(nsIDocument* aDoc, nsIURI* aURI,
|
||||
@ -142,12 +77,16 @@ public:
|
||||
{
|
||||
NS_PRECONDITION(mFlushState != eNotifying, "mFlushState out of sync");
|
||||
if (mFlushState == eInDocUpdate) {
|
||||
FlushPendingAppendNotifications();
|
||||
mFlushState = eInFlush;
|
||||
mDocument->EndUpdate(UPDATE_CONTENT_MODEL);
|
||||
}
|
||||
}
|
||||
|
||||
bool IsInDocUpdate()
|
||||
{
|
||||
return mFlushState == eInDocUpdate;
|
||||
}
|
||||
|
||||
void SetDocumentCharsetAndSource(nsACString& aCharset, int32_t aCharsetSource);
|
||||
|
||||
/**
|
||||
@ -167,19 +106,12 @@ public:
|
||||
virtual nsresult FlushTags();
|
||||
|
||||
protected:
|
||||
inline void SetAppendBatchCapacity(uint32_t aCapacity)
|
||||
{
|
||||
mElementsSeenInThisAppendBatch.SetCapacity(aCapacity);
|
||||
}
|
||||
|
||||
nsHtml5DocumentBuilder(bool aRunsToCompletion);
|
||||
virtual ~nsHtml5DocumentBuilder();
|
||||
|
||||
private:
|
||||
nsTArray<nsHtml5PendingNotification> mPendingNotifications;
|
||||
nsTArray<nsIContentPtr> mElementsSeenInThisAppendBatch;
|
||||
protected:
|
||||
nsTArray<nsCOMPtr<nsIContent> > mOwnedElements;
|
||||
nsAutoTArray<nsCOMPtr<nsIContent>, 32> mOwnedElements;
|
||||
/**
|
||||
* Non-NS_OK if this parser should refuse to process any more input.
|
||||
* For example, the parser needs to be marked as broken if it drops some
|
||||
|
@ -1,55 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef nsHtml5PendingNotification_h
|
||||
#define nsHtml5PendingNotification_h
|
||||
|
||||
#include "nsNodeUtils.h"
|
||||
|
||||
class nsHtml5TreeBuilder;
|
||||
|
||||
class nsHtml5PendingNotification {
|
||||
public:
|
||||
|
||||
nsHtml5PendingNotification(nsIContent* aParent)
|
||||
: mParent(aParent),
|
||||
mChildCount(aParent->GetChildCount() - 1)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsHtml5PendingNotification);
|
||||
}
|
||||
|
||||
~nsHtml5PendingNotification()
|
||||
{
|
||||
MOZ_COUNT_DTOR(nsHtml5PendingNotification);
|
||||
}
|
||||
|
||||
inline void Fire()
|
||||
{
|
||||
nsNodeUtils::ContentAppended(mParent, mParent->GetChildAt(mChildCount),
|
||||
mChildCount);
|
||||
}
|
||||
|
||||
inline bool Contains(nsIContent* aNode)
|
||||
{
|
||||
return !!(mParent == aNode);
|
||||
}
|
||||
|
||||
inline bool HaveNotifiedIndex(uint32_t index)
|
||||
{
|
||||
return index < mChildCount;
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
* An element
|
||||
*/
|
||||
nsIContent* mParent;
|
||||
|
||||
/**
|
||||
* Child count at start of notification deferring
|
||||
*/
|
||||
uint32_t mChildCount;
|
||||
};
|
||||
|
||||
#endif // nsHtml5PendingNotification_h
|
@ -44,7 +44,6 @@
|
||||
#include "nsHtml5Parser.h"
|
||||
#include "nsHtml5Atoms.h"
|
||||
#include "nsHtml5TreeOperation.h"
|
||||
#include "nsHtml5PendingNotification.h"
|
||||
#include "nsHtml5StateSnapshot.h"
|
||||
#include "nsHtml5StackNode.h"
|
||||
#include "nsHtml5TreeOpExecutor.h"
|
||||
|
@ -45,7 +45,6 @@
|
||||
#include "nsHtml5Parser.h"
|
||||
#include "nsHtml5Atoms.h"
|
||||
#include "nsHtml5TreeOperation.h"
|
||||
#include "nsHtml5PendingNotification.h"
|
||||
#include "nsHtml5StateSnapshot.h"
|
||||
#include "nsHtml5StackNode.h"
|
||||
#include "nsHtml5TreeOpExecutor.h"
|
||||
|
@ -639,16 +639,6 @@ nsHtml5TreeBuilder::elementPushed(int32_t aNamespace, nsIAtom* aName, nsIContent
|
||||
}
|
||||
if (aName == nsHtml5Atoms::input ||
|
||||
aName == nsHtml5Atoms::button) {
|
||||
if (!formPointer) {
|
||||
// If form inputs don't belong to a form, their state preservation
|
||||
// won't work right without an append notification flush at this
|
||||
// point. See bug 497861.
|
||||
if (mBuilder) {
|
||||
mBuilder->FlushPendingAppendNotifications();
|
||||
} else {
|
||||
mOpQueue.AppendElement()->Init(eTreeOpFlushPendingAppendNotifications);
|
||||
}
|
||||
}
|
||||
if (mBuilder) {
|
||||
nsHtml5TreeOperation::DoneCreatingElement(static_cast<nsIContent*>(aElement));
|
||||
} else {
|
||||
@ -710,7 +700,7 @@ nsHtml5TreeBuilder::elementPopped(int32_t aNamespace, nsIAtom* aName, nsIContent
|
||||
}
|
||||
if (aName == nsHtml5Atoms::title) {
|
||||
if (mBuilder) {
|
||||
nsHtml5TreeOperation::DoneAddingChildren(static_cast<nsIContent*>(aElement), mBuilder);
|
||||
nsHtml5TreeOperation::DoneAddingChildren(static_cast<nsIContent*>(aElement));
|
||||
return;
|
||||
}
|
||||
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
|
||||
@ -722,7 +712,6 @@ nsHtml5TreeBuilder::elementPopped(int32_t aNamespace, nsIAtom* aName, nsIContent
|
||||
if (mBuilder) {
|
||||
MOZ_ASSERT(!nsContentUtils::IsSafeToRunScript(),
|
||||
"Scripts must be blocked.");
|
||||
mBuilder->FlushPendingAppendNotifications();
|
||||
mBuilder->UpdateStyleSheet(static_cast<nsIContent*>(aElement));
|
||||
return;
|
||||
}
|
||||
@ -748,32 +737,12 @@ nsHtml5TreeBuilder::elementPopped(int32_t aNamespace, nsIAtom* aName, nsIContent
|
||||
// properly (e.g. form state restoration).
|
||||
// XXX expose ElementName group here and do switch
|
||||
if (aName == nsHtml5Atoms::object ||
|
||||
aName == nsHtml5Atoms::applet) {
|
||||
aName == nsHtml5Atoms::applet ||
|
||||
aName == nsHtml5Atoms::select ||
|
||||
aName == nsHtml5Atoms::textarea ||
|
||||
aName == nsHtml5Atoms::output) {
|
||||
if (mBuilder) {
|
||||
nsHtml5TreeOperation::DoneAddingChildren(static_cast<nsIContent*>(aElement), mBuilder);
|
||||
return;
|
||||
}
|
||||
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
|
||||
NS_ASSERTION(treeOp, "Tree op allocation failed.");
|
||||
treeOp->Init(eTreeOpDoneAddingChildren, aElement);
|
||||
return;
|
||||
}
|
||||
if (aName == nsHtml5Atoms::select ||
|
||||
aName == nsHtml5Atoms::textarea) {
|
||||
if (!formPointer) {
|
||||
// If form inputs don't belong to a form, their state preservation
|
||||
// won't work right without an append notification flush at this
|
||||
// point. See bug 497861 and bug 539895.
|
||||
if (mBuilder) {
|
||||
mBuilder->FlushPendingAppendNotifications();
|
||||
} else {
|
||||
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
|
||||
NS_ASSERTION(treeOp, "Tree op allocation failed.");
|
||||
treeOp->Init(eTreeOpFlushPendingAppendNotifications);
|
||||
}
|
||||
}
|
||||
if (mBuilder) {
|
||||
nsHtml5TreeOperation::DoneAddingChildren(static_cast<nsIContent*>(aElement), mBuilder);
|
||||
nsHtml5TreeOperation::DoneAddingChildren(static_cast<nsIContent*>(aElement));
|
||||
return;
|
||||
}
|
||||
nsHtml5TreeOperation* treeOp = mOpQueue.AppendElement();
|
||||
|
@ -430,8 +430,6 @@ nsHtml5TreeOpExecutor::RunFlushLoop()
|
||||
|
||||
uint32_t numberOfOpsToFlush = mOpQueue.Length();
|
||||
|
||||
SetAppendBatchCapacity(numberOfOpsToFlush * 2);
|
||||
|
||||
const nsHtml5TreeOperation* first = mOpQueue.Elements();
|
||||
const nsHtml5TreeOperation* last = first + numberOfOpsToFlush - 1;
|
||||
for (nsHtml5TreeOperation* iter = const_cast<nsHtml5TreeOperation*>(first);;) {
|
||||
@ -534,8 +532,6 @@ nsHtml5TreeOpExecutor::FlushDocumentWrite()
|
||||
|
||||
uint32_t numberOfOpsToFlush = mOpQueue.Length();
|
||||
|
||||
SetAppendBatchCapacity(numberOfOpsToFlush * 2);
|
||||
|
||||
const nsHtml5TreeOperation* start = mOpQueue.Elements();
|
||||
const nsHtml5TreeOperation* end = start + numberOfOpsToFlush;
|
||||
for (nsHtml5TreeOperation* iter = const_cast<nsHtml5TreeOperation*>(start);
|
||||
|
@ -71,7 +71,7 @@ class MOZ_STACK_CLASS nsHtml5OtherDocUpdate {
|
||||
}
|
||||
}
|
||||
private:
|
||||
nsIDocument* mDocument;
|
||||
nsCOMPtr<nsIDocument> mDocument;
|
||||
};
|
||||
|
||||
nsHtml5TreeOperation::nsHtml5TreeOperation()
|
||||
@ -123,28 +123,23 @@ nsHtml5TreeOperation::AppendTextToTextNode(const char16_t* aBuffer,
|
||||
nsHtml5DocumentBuilder* aBuilder)
|
||||
{
|
||||
NS_PRECONDITION(aTextNode, "Got null text node.");
|
||||
MOZ_ASSERT(aBuilder);
|
||||
MOZ_ASSERT(aBuilder->GetDocument() == aTextNode->OwnerDoc());
|
||||
MOZ_ASSERT(aBuilder->IsInDocUpdate());
|
||||
uint32_t oldLength = aTextNode->TextLength();
|
||||
CharacterDataChangeInfo info = {
|
||||
true,
|
||||
oldLength,
|
||||
oldLength,
|
||||
aLength
|
||||
};
|
||||
nsNodeUtils::CharacterDataWillChange(aTextNode, &info);
|
||||
|
||||
if (aBuilder->HaveNotified(aTextNode)) {
|
||||
// This text node has already been notified on, so it's necessary to
|
||||
// notify on the append
|
||||
nsresult rv = NS_OK;
|
||||
uint32_t oldLength = aTextNode->TextLength();
|
||||
CharacterDataChangeInfo info = {
|
||||
true,
|
||||
oldLength,
|
||||
oldLength,
|
||||
aLength
|
||||
};
|
||||
nsNodeUtils::CharacterDataWillChange(aTextNode, &info);
|
||||
nsresult rv = aTextNode->AppendText(aBuffer, aLength, false);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aTextNode->AppendText(aBuffer, aLength, false);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsNodeUtils::CharacterDataChanged(aTextNode, &info);
|
||||
return rv;
|
||||
}
|
||||
|
||||
return aTextNode->AppendText(aBuffer, aLength, false);
|
||||
nsNodeUtils::CharacterDataChanged(aTextNode, &info);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
@ -178,30 +173,17 @@ nsHtml5TreeOperation::Append(nsIContent* aNode,
|
||||
nsIContent* aParent,
|
||||
nsHtml5DocumentBuilder* aBuilder)
|
||||
{
|
||||
MOZ_ASSERT(aBuilder);
|
||||
MOZ_ASSERT(aBuilder->IsInDocUpdate());
|
||||
nsresult rv = NS_OK;
|
||||
nsIDocument* executorDoc = aBuilder->GetDocument();
|
||||
NS_ASSERTION(executorDoc, "Null doc on executor");
|
||||
nsIDocument* parentDoc = aParent->OwnerDoc();
|
||||
NS_ASSERTION(parentDoc, "Null owner doc on old node.");
|
||||
|
||||
if (MOZ_LIKELY(executorDoc == parentDoc)) {
|
||||
// the usual case. the parent is in the parser's doc
|
||||
rv = aParent->AppendChildTo(aNode, false);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
aBuilder->PostPendingAppendNotification(aParent, aNode);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
// The parent has been moved to another doc
|
||||
parentDoc->BeginUpdate(UPDATE_CONTENT_MODEL);
|
||||
|
||||
nsHtml5OtherDocUpdate update(aParent->OwnerDoc(),
|
||||
aBuilder->GetDocument());
|
||||
uint32_t childCount = aParent->GetChildCount();
|
||||
rv = aParent->AppendChildTo(aNode, false);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
aNode->SetParserHasNotified();
|
||||
nsNodeUtils::ContentAppended(aParent, aNode, childCount);
|
||||
}
|
||||
parentDoc->EndUpdate(UPDATE_CONTENT_MODEL);
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -209,12 +191,16 @@ nsresult
|
||||
nsHtml5TreeOperation::AppendToDocument(nsIContent* aNode,
|
||||
nsHtml5DocumentBuilder* aBuilder)
|
||||
{
|
||||
MOZ_ASSERT(aBuilder);
|
||||
MOZ_ASSERT(aBuilder->GetDocument() == aNode->OwnerDoc());
|
||||
MOZ_ASSERT(aBuilder->IsInDocUpdate());
|
||||
nsresult rv = NS_OK;
|
||||
aBuilder->FlushPendingAppendNotifications();
|
||||
|
||||
nsIDocument* doc = aBuilder->GetDocument();
|
||||
uint32_t childCount = doc->GetChildCount();
|
||||
rv = doc->AppendChildTo(aNode, false);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
aNode->SetParserHasNotified();
|
||||
nsNodeUtils::ContentInserted(doc, aNode, childCount);
|
||||
|
||||
NS_ASSERTION(!nsContentUtils::IsSafeToRunScript(),
|
||||
@ -247,7 +233,8 @@ IsElementOrTemplateContent(nsINode* aNode) {
|
||||
void
|
||||
nsHtml5TreeOperation::Detach(nsIContent* aNode, nsHtml5DocumentBuilder* aBuilder)
|
||||
{
|
||||
aBuilder->FlushPendingAppendNotifications();
|
||||
MOZ_ASSERT(aBuilder);
|
||||
MOZ_ASSERT(aBuilder->IsInDocUpdate());
|
||||
nsCOMPtr<nsINode> parent = aNode->GetParentNode();
|
||||
if (parent) {
|
||||
nsHtml5OtherDocUpdate update(parent->OwnerDoc(),
|
||||
@ -263,8 +250,8 @@ nsHtml5TreeOperation::AppendChildrenToNewParent(nsIContent* aNode,
|
||||
nsIContent* aParent,
|
||||
nsHtml5DocumentBuilder* aBuilder)
|
||||
{
|
||||
aBuilder->FlushPendingAppendNotifications();
|
||||
|
||||
MOZ_ASSERT(aBuilder);
|
||||
MOZ_ASSERT(aBuilder->IsInDocUpdate());
|
||||
nsHtml5OtherDocUpdate update(aParent->OwnerDoc(),
|
||||
aBuilder->GetDocument());
|
||||
|
||||
@ -290,10 +277,11 @@ nsHtml5TreeOperation::FosterParent(nsIContent* aNode,
|
||||
nsIContent* aTable,
|
||||
nsHtml5DocumentBuilder* aBuilder)
|
||||
{
|
||||
MOZ_ASSERT(aBuilder);
|
||||
MOZ_ASSERT(aBuilder->IsInDocUpdate());
|
||||
nsIContent* foster = aTable->GetParent();
|
||||
|
||||
if (IsElementOrTemplateContent(foster)) {
|
||||
aBuilder->FlushPendingAppendNotifications();
|
||||
|
||||
nsHtml5OtherDocUpdate update(foster->OwnerDoc(),
|
||||
aBuilder->GetDocument());
|
||||
@ -352,16 +340,17 @@ nsHtml5TreeOperation::CreateElement(int32_t aNs,
|
||||
aName = nsHtml5Atoms::select;
|
||||
}
|
||||
|
||||
nsCOMPtr<dom::Element> newContent;
|
||||
nsCOMPtr<dom::Element> newElement;
|
||||
nsCOMPtr<nsINodeInfo> nodeInfo = aBuilder->GetNodeInfoManager()->
|
||||
GetNodeInfo(aName, nullptr, aNs, nsIDOMNode::ELEMENT_NODE);
|
||||
NS_ASSERTION(nodeInfo, "Got null nodeinfo.");
|
||||
NS_NewElement(getter_AddRefs(newContent),
|
||||
NS_NewElement(getter_AddRefs(newElement),
|
||||
nodeInfo.forget(),
|
||||
aFromParser);
|
||||
NS_ASSERTION(newContent, "Element creation created null pointer.");
|
||||
NS_ASSERTION(newElement, "Element creation created null pointer.");
|
||||
|
||||
aBuilder->HoldElement(newContent);
|
||||
dom::Element* newContent = newElement;
|
||||
aBuilder->HoldElement(newElement.forget());
|
||||
|
||||
if (MOZ_UNLIKELY(aName == nsHtml5Atoms::style || aName == nsHtml5Atoms::link)) {
|
||||
nsCOMPtr<nsIStyleSheetLinkingElement> ssle(do_QueryInterface(newContent));
|
||||
@ -408,6 +397,7 @@ nsHtml5TreeOperation::CreateElement(int32_t aNs,
|
||||
(void) optionText->SetText(theContent[i], false);
|
||||
optionElt->AppendChildTo(optionText, false);
|
||||
newContent->AppendChildTo(optionElt, false);
|
||||
// XXXsmaug Shouldn't we call this after adding all the child nodes.
|
||||
newContent->DoneAddingChildren(false);
|
||||
}
|
||||
}
|
||||
@ -506,12 +496,12 @@ nsHtml5TreeOperation::FosterParentText(nsIContent* aStackParent,
|
||||
nsIContent* aTable,
|
||||
nsHtml5DocumentBuilder* aBuilder)
|
||||
{
|
||||
MOZ_ASSERT(aBuilder);
|
||||
MOZ_ASSERT(aBuilder->IsInDocUpdate());
|
||||
nsresult rv = NS_OK;
|
||||
nsIContent* foster = aTable->GetParent();
|
||||
|
||||
if (IsElementOrTemplateContent(foster)) {
|
||||
aBuilder->FlushPendingAppendNotifications();
|
||||
|
||||
nsHtml5OtherDocUpdate update(foster->OwnerDoc(),
|
||||
aBuilder->GetDocument());
|
||||
|
||||
@ -609,10 +599,9 @@ nsHtml5TreeOperation::PreventScriptExecution(nsIContent* aNode)
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5TreeOperation::DoneAddingChildren(nsIContent* aNode,
|
||||
nsHtml5DocumentBuilder* aBuilder)
|
||||
nsHtml5TreeOperation::DoneAddingChildren(nsIContent* aNode)
|
||||
{
|
||||
aNode->DoneAddingChildren(aBuilder->HaveNotified(aNode));
|
||||
aNode->DoneAddingChildren(aNode->HasParserNotified());
|
||||
}
|
||||
|
||||
void
|
||||
@ -763,7 +752,7 @@ nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder,
|
||||
}
|
||||
case eTreeOpDoneAddingChildren: {
|
||||
nsIContent* node = *(mOne.node);
|
||||
node->DoneAddingChildren(aBuilder->HaveNotified(node));
|
||||
node->DoneAddingChildren(node->HasParserNotified());
|
||||
return NS_OK;
|
||||
}
|
||||
case eTreeOpDoneCreatingElement: {
|
||||
@ -771,10 +760,6 @@ nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder,
|
||||
DoneCreatingElement(node);
|
||||
return NS_OK;
|
||||
}
|
||||
case eTreeOpFlushPendingAppendNotifications: {
|
||||
aBuilder->FlushPendingAppendNotifications();
|
||||
return NS_OK;
|
||||
}
|
||||
case eTreeOpSetDocumentCharset: {
|
||||
char* str = mOne.charPtr;
|
||||
int32_t charsetSource = mFour.integer;
|
||||
@ -791,7 +776,6 @@ nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder,
|
||||
}
|
||||
case eTreeOpUpdateStyleSheet: {
|
||||
nsIContent* node = *(mOne.node);
|
||||
aBuilder->FlushPendingAppendNotifications();
|
||||
aBuilder->UpdateStyleSheet(node);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -44,7 +44,6 @@ enum eHtml5TreeOperation {
|
||||
eTreeOpPreventScriptExecution,
|
||||
eTreeOpDoneAddingChildren,
|
||||
eTreeOpDoneCreatingElement,
|
||||
eTreeOpFlushPendingAppendNotifications,
|
||||
eTreeOpSetDocumentCharset,
|
||||
eTreeOpNeedsCharsetSwitchTo,
|
||||
eTreeOpUpdateStyleSheet,
|
||||
@ -182,8 +181,7 @@ class nsHtml5TreeOperation {
|
||||
|
||||
static void PreventScriptExecution(nsIContent* aNode);
|
||||
|
||||
static void DoneAddingChildren(nsIContent* aNode,
|
||||
nsHtml5DocumentBuilder* aBuilder);
|
||||
static void DoneAddingChildren(nsIContent* aNode);
|
||||
|
||||
static void DoneCreatingElement(nsIContent* aNode);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user