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;