diff --git a/parser/html/nsHtml5TreeOperation.cpp b/parser/html/nsHtml5TreeOperation.cpp index 892b93af06b..0bb0661f9c7 100644 --- a/parser/html/nsHtml5TreeOperation.cpp +++ b/parser/html/nsHtml5TreeOperation.cpp @@ -39,9 +39,14 @@ * ***** END LICENSE BLOCK ***** */ #include "nsHtml5TreeOperation.h" +#include "nsContentUtils.h" #include "nsNodeUtils.h" #include "nsAttrName.h" #include "nsHtml5TreeBuilder.h" +#include "nsIDOMMutationEvent.h" +#include "mozAutoDocUpdate.h" +#include "nsBindingManager.h" +#include "nsXBLBinding.h" nsHtml5TreeOperation::nsHtml5TreeOperation() : mOpCode(eTreeOpAppend) @@ -117,6 +122,8 @@ nsHtml5TreeOperation::Perform(nsHtml5TreeBuilder* aBuilder) } case eTreeOpAddAttributes: { // mNode holds the new attributes and mParent is the target + nsIDocument* document = mParent->GetCurrentDoc(); + PRUint32 len = mNode->GetAttrCount(); for (PRUint32 i = 0; i < len; ++i) { const nsAttrName* attrName = mNode->GetAttrNameAt(i); @@ -125,8 +132,38 @@ nsHtml5TreeOperation::Perform(nsHtml5TreeBuilder* aBuilder) if (!mParent->HasAttr(nsuri, localName)) { nsAutoString value; mNode->GetAttr(nsuri, localName, value); - mParent->SetAttr(nsuri, localName, attrName->GetPrefix(), value, PR_TRUE); - // XXX should not fire mutation event here + + // the manual notification code is based on nsGenericElement + + PRUint32 stateMask = PRUint32(mParent->IntrinsicState()); + nsNodeUtils::AttributeWillChange(mParent, + nsuri, + localName, + static_cast(nsIDOMMutationEvent::ADDITION)); + + mParent->SetAttr(nsuri, localName, attrName->GetPrefix(), value, PR_FALSE); + + if (document || mParent->HasFlag(NODE_FORCE_XBL_BINDINGS)) { + nsIDocument* ownerDoc = mParent->GetOwnerDoc(); + if (ownerDoc) { + nsRefPtr binding = + ownerDoc->BindingManager()->GetBinding(mParent); + if (binding) { + binding->AttributeChanged(localName, nsuri, PR_FALSE, PR_FALSE); + } + } + } + + stateMask = stateMask ^ PRUint32(mParent->IntrinsicState()); + if (stateMask && document) { + MOZ_AUTO_DOC_UPDATE(document, UPDATE_CONTENT_STATE, PR_TRUE); + document->ContentStatesChanged(mParent, nsnull, stateMask); + } + nsNodeUtils::AttributeChanged(mParent, + nsuri, + localName, + static_cast(nsIDOMMutationEvent::ADDITION), + stateMask); } } return rv;