mDocument->AttributeChanged(NS_STATIC_CAST(nsIStyledContent*, this), aName, NS_STYLE_HINT_UNKNOWN);
mDocument->AttributeChanged(NS_STATIC_CAST(nsIStyledContent*, this), aNameSpaceID, aName, NS_STYLE_HINT_UNKNOWN);
RDFElementImpl::SetAttribute(PRInt32 aNameSpaceID,                             nsIAtom* aName,                              const nsString& aValue,                             PRBool aNotify){    NS_ASSERTION(kNameSpaceID_Unknown != aNameSpaceID, "must have name space ID");    if (kNameSpaceID_Unknown == aNameSpaceID)        return NS_ERROR_ILLEGAL_VALUE;    NS_ASSERTION(nsnull != aName, "must have attribute name");    if (nsnull == aName)        return NS_ERROR_NULL_POINTER;    nsresult rv = NS_OK;    if (! mAttributes) {        rv = NS_NewXULAttributes(&mAttributes, NS_STATIC_CAST(nsIStyledContent*, this));        if (NS_FAILED(rv))            return rv;    }    // XXX Class and Style attribute setting should be checking for the XUL namespace!    // Check to see if the CLASS attribute is being set.  If so, we need to rebuild our    // class list.    if (mDocument && (aNameSpaceID == kNameSpaceID_None) && aName == kClassAtom) {      mAttributes->UpdateClassList(aValue);    }    // Check to see if the STYLE attribute is being set.  If so, we need to create a new    // style rule based off the value of this attribute, and we need to let the document    // know about the StyleRule change.    if (mDocument && (aNameSpaceID == kNameSpaceID_None) && aName == kStyleAtom) {        nsCOMPtr <nsIURI> docURL;        if (nsnull != mDocument) {            mDocument->GetBaseURL(*getter_AddRefs(docURL));        }        mAttributes->UpdateStyleRule(docURL, aValue);        // XXX Some kind of special document update might need to happen here.    }    // Check to see if the OBSERVES attribute is being set.  If so, we need to attach    // to the observed broadcaster.    if (mDocument && (aNameSpaceID == kNameSpaceID_None) &&         (aName == kObservesAtom))    {      // Do a getElementById to retrieve the broadcaster.      nsCOMPtr<nsIDOMElement> broadcaster;      nsCOMPtr<nsIDOMXULDocument> domDoc = do_QueryInterface(mDocument);      domDoc->GetElementById(aValue, getter_AddRefs(broadcaster));      if (broadcaster) {        nsCOMPtr<nsIDOMXULElement> xulBroadcaster = do_QueryInterface(broadcaster);        if (xulBroadcaster) {          xulBroadcaster->AddBroadcastListener("*", this);        }      }      else {        nsCOMPtr<nsIXULDocument> rdfdoc = do_QueryInterface(mDocument);        if (! rdfdoc)          return NS_ERROR_UNEXPECTED;        ObserverForwardReference* fwdref =            new ObserverForwardReference(this, aValue, nsAutoString("*"));        if (! fwdref)            return NS_ERROR_OUT_OF_MEMORY;        rdfdoc->AddForwardReference(fwdref);      }    }    // Need to check for the SELECTED attribute    // being set.  If we're a <treeitem>, <treerow>, or <treecell>, the act of    // setting these attributes forces us to update our selected arrays.    nsCOMPtr<nsIAtom> tag;    GetTag(*getter_AddRefs(tag));    if (mDocument && (aNameSpaceID == kNameSpaceID_None)) {      // See if we're a treeitem atom.      nsCOMPtr<nsIRDFNodeList> nodeList;      if (tag && (tag.get() == kTreeItemAtom) && (aName == kSelectedAtom)) {        nsCOMPtr<nsIDOMXULTreeElement> treeElement;        GetParentTree(getter_AddRefs(treeElement));        if (treeElement) {          nsCOMPtr<nsIDOMNodeList> nodes;          treeElement->GetSelectedItems(getter_AddRefs(nodes));          nodeList = do_QueryInterface(nodes);        }      }      else if (tag && (tag.get() == kTreeCellAtom) && (aName == kSelectedAtom)) {        nsCOMPtr<nsIDOMXULTreeElement> treeElement;        GetParentTree(getter_AddRefs(treeElement));        if (treeElement) {          nsCOMPtr<nsIDOMNodeList> nodes;          treeElement->GetSelectedCells(getter_AddRefs(nodes));          nodeList = do_QueryInterface(nodes);        }      }      if (nodeList) {        // Append this node to the list.        nodeList->AppendNode(this);      }    }       // Check to see if the POPUP attribute is being set.  If so, we need to attach    // a new instance of our popup handler to the node.    if (mDocument && (aNameSpaceID == kNameSpaceID_None) &&         (aName == kPopupAtom || aName == kTooltipAtom || aName == kContextAtom))    {        // Do a create instance of our popup listener.        nsIXULPopupListener* popupListener;        rv = nsComponentManager::CreateInstance(kXULPopupListenerCID,                                                nsnull,                                                kIXULPopupListenerIID,                                                (void**) &popupListener);        if (NS_FAILED(rv))        {          NS_ERROR("Unable to create an instance of the popup listener object.");          return rv;        }        XULPopupType popupType = eXULPopupType_popup;        if (aName == kTooltipAtom)          popupType = eXULPopupType_tooltip;        else if (aName == kContextAtom)          popupType = eXULPopupType_context;        // Add a weak reference to the node.        popupListener->Init(this, popupType);        // Add the popup as a listener on this element.        nsCOMPtr<nsIDOMEventListener> eventListener = do_QueryInterface(popupListener);        if (popupType == eXULPopupType_tooltip) {          AddEventListener("mouseout", eventListener, PR_FALSE);          AddEventListener("mousemove", eventListener, PR_FALSE);        }        else AddEventListener("mousedown", eventListener, PR_FALSE);                  NS_IF_RELEASE(popupListener);    }    // XXX need to check if they're changing an event handler: if so, then we need    // to unhook the old one.        nsXULAttribute* attr;    PRInt32 i = 0;    PRInt32 count = mAttributes->Count();    while (i < count) {        attr = mAttributes->ElementAt(i);        if ((aNameSpaceID == attr->mNameSpaceID) && (aName == attr->mName))            break;        i++;    }    if (i < count) {        attr->mValue = aValue;    }    else { // didn't find it        rv = NS_NewXULAttribute(&attr, NS_STATIC_CAST(nsIStyledContent*, this), aNameSpaceID, aName, aValue);        if (NS_FAILED(rv))            return rv;        mAttributes->AppendElement(attr);    }    // Check for event handlers and add a script listener if necessary.    EventHandlerMapEntry* entry = kEventHandlerMap;    while (entry->mAttributeAtom) {        if (entry->mAttributeAtom == aName) {            AddScriptEventListener(aName, aValue, *entry->mHandlerIID);            break;        }        ++entry;    }    // Notify any broadcasters that are listening to this node.    if (mBroadcastListeners != nsnull)    {        nsAutoString attribute;        aName->ToString(attribute);        count = mBroadcastListeners->Count();        for (i = 0; i < count; i++) {            XULBroadcastListener* xulListener = (XULBroadcastListener*)mBroadcastListeners->ElementAt(i);            if (xulListener->ObservingAttribute(attribute) &&                (aName != kIdAtom)) {                // XXX Should have a function that knows which attributes are special.                // First we set the attribute in the observer.                xulListener->mListener->SetAttribute(attribute, aValue);                ExecuteOnBroadcastHandler(xulListener->mListener, attribute);            }        }    }    if (NS_SUCCEEDED(rv) && aNotify && ElementIsInDocument()) {        mDocument->AttributeChanged(NS_STATIC_CAST(nsIStyledContent*, this), aName, NS_STYLE_HINT_UNKNOWN);    }    return rv;}