From be4f98c3bcb4e6069defbb2f2ba2dab65d8ea549 Mon Sep 17 00:00:00 2001 From: "waterson%netscape.com" Date: Thu, 15 Nov 2001 02:46:29 +0000 Subject: [PATCH] Bug 101982. Fix onbroadcast handler. r=cmanske, sr=hyatt git-svn-id: svn://10.0.0.236/trunk@108138 18797224-902f-48f8-a5cc-f745e15eee43 --- .../xul/document/src/nsXULDocument.cpp | 106 ++++++++++-------- .../content/xul/document/src/nsXULDocument.h | 7 +- 2 files changed, 68 insertions(+), 45 deletions(-) diff --git a/mozilla/content/xul/document/src/nsXULDocument.cpp b/mozilla/content/xul/document/src/nsXULDocument.cpp index 184d5283d77..d1380a76442 100644 --- a/mozilla/content/xul/document/src/nsXULDocument.cpp +++ b/mozilla/content/xul/document/src/nsXULDocument.cpp @@ -441,7 +441,7 @@ nsXULDocument::nsXULDocument(void) mDisplaySelection(PR_FALSE), mIsPopup(PR_FALSE), mIsFastLoad(PR_FALSE), - mApplyingPersitedAttrs(PR_FALSE), + mApplyingPersistedAttrs(PR_FALSE), mNextFastLoad(nsnull), mBoxObjectTable(nsnull), mTemplateBuilderTable(nsnull), @@ -1728,10 +1728,10 @@ CanBroadcast(PRInt32 aNameSpaceID, nsIAtom* aAttribute) return PR_TRUE; } -static void -SynchronizeBroadcastListener(nsIDOMElement* aBroadcaster, - nsIDOMElement* aListener, - const nsAString& aAttr) +void +nsXULDocument::SynchronizeBroadcastListener(nsIDOMElement *aBroadcaster, + nsIDOMElement *aListener, + const nsAString &aAttr) { nsCOMPtr broadcaster = do_QueryInterface(aBroadcaster); nsCOMPtr listener = do_QueryInterface(aListener); @@ -1754,6 +1754,15 @@ SynchronizeBroadcastListener(nsIDOMElement* aBroadcaster, nsAutoString value; broadcaster->GetAttr(nameSpaceID, name, value); listener->SetAttr(nameSpaceID, name, value, PR_TRUE); + +#if 0 + // XXX we don't fire the |onbroadcast| handler during + // initial hookup: doing so would potentially run the + // |onbroadcast| handler before the |onload| handler, + // which could define JS properties that mask XBL + // properties, etc. + ExecuteOnBroadcastHandlerFor(broadcaster, aListener, name); +#endif } } else { @@ -1770,6 +1779,14 @@ SynchronizeBroadcastListener(nsIDOMElement* aBroadcaster, else { listener->UnsetAttr(kNameSpaceID_None, name, PR_TRUE); } + +#if 0 + // XXX we don't fire the |onbroadcast| handler during initial + // hookup: doing so would potentially run the |onbroadcast| + // handler before the |onload| handler, which could define JS + // properties that mask XBL properties, etc. + ExecuteOnBroadcastHandlerFor(broadcaster, aListener, name); +#endif } } @@ -1918,6 +1935,10 @@ nsXULDocument::ExecuteOnBroadcastHandlerFor(nsIContent* aBroadcaster, PRInt32 count; listener->ChildCount(count); for (PRInt32 i = 0; i < count; ++i) { + // Look for an element beneath the listener. This + // ought to have an |element| attribute that refers to + // aBroadcaster, and an |attribute| element that tells us what + // attriubtes we're listening for. nsCOMPtr child; listener->ChildAt(i, *getter_AddRefs(child)); @@ -1928,7 +1949,7 @@ nsXULDocument::ExecuteOnBroadcastHandlerFor(nsIContent* aBroadcaster, // Is this the element that was listening to us? nsAutoString listeningToID; - aBroadcaster->GetAttr(kNameSpaceID_None, nsXULAtoms::element, listeningToID); + child->GetAttr(kNameSpaceID_None, nsXULAtoms::element, listeningToID); nsAutoString broadcasterID; aBroadcaster->GetAttr(kNameSpaceID_None, nsXULAtoms::id, broadcasterID); @@ -1939,15 +1960,16 @@ nsXULDocument::ExecuteOnBroadcastHandlerFor(nsIContent* aBroadcaster, // We are observing the broadcaster, but is this the right // attribute? nsAutoString listeningToAttribute; - listener->GetAttr(kNameSpaceID_None, nsXULAtoms::attribute, listeningToAttribute); + child->GetAttr(kNameSpaceID_None, nsXULAtoms::attribute, + listeningToAttribute); - if (!listeningToAttribute.Equals(attrName) && - !listeningToAttribute.Equals(NS_LITERAL_STRING("*"))) { + if (listeningToAttribute != attrName && + listeningToAttribute != NS_LITERAL_STRING("*")) { continue; } - // This is the right observes node. Execute the onchange - // event handler + // This is the right element. Execute the + // |onbroadcast| event handler nsEvent event; event.eventStructType = NS_EVENT; event.message = NS_XUL_BROADCAST; @@ -1961,7 +1983,7 @@ nsXULDocument::ExecuteOnBroadcastHandlerFor(nsIContent* aBroadcaster, // Handle the DOM event nsEventStatus status = nsEventStatus_eIgnore; - listener->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status); + child->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status); } } @@ -1976,10 +1998,6 @@ nsXULDocument::AttributeChanged(nsIContent* aElement, { nsresult rv; - PRInt32 nameSpaceID; - rv = aElement->GetNameSpaceID(nameSpaceID); - if (NS_FAILED(rv)) return rv; - // First see if we need to update our element map. if ((aAttribute == nsXULAtoms::id) || (aAttribute == nsXULAtoms::ref)) { @@ -1992,30 +2010,6 @@ nsXULDocument::AttributeChanged(nsIContent* aElement, if (NS_FAILED(rv)) return rv; } - // Now notify external observers - for (PRInt32 i = mObservers.Count() - 1; i >= 0; --i) { - nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i]; - observer->AttributeChanged(this, aElement, aNameSpaceID, aAttribute, aModType, aHint); - } - - // See if there is anything we need to persist in the localstore. - // - // XXX Namespace handling broken :-( - nsAutoString persist; - rv = aElement->GetAttr(kNameSpaceID_None, nsXULAtoms::persist, persist); - if (NS_FAILED(rv)) return rv; - - if (rv == NS_CONTENT_ATTR_HAS_VALUE) { - nsAutoString attr; - rv = aAttribute->ToString(attr); - if (NS_FAILED(rv)) return rv; - - if (persist.Find(attr) >= 0) { - rv = Persist(aElement, kNameSpaceID_None, aAttribute); - if (NS_FAILED(rv)) return rv; - } - } - // Synchronize broadcast listeners if (mBroadcasterMap && CanBroadcast(aNameSpaceID, aAttribute)) { nsCOMPtr domele = do_QueryInterface(aElement); @@ -2056,6 +2050,30 @@ nsXULDocument::AttributeChanged(nsIContent* aElement, } } + // Now notify external observers + for (PRInt32 i = mObservers.Count() - 1; i >= 0; --i) { + nsIDocumentObserver* observer = (nsIDocumentObserver*)mObservers[i]; + observer->AttributeChanged(this, aElement, aNameSpaceID, aAttribute, aModType, aHint); + } + + // See if there is anything we need to persist in the localstore. + // + // XXX Namespace handling broken :-( + nsAutoString persist; + rv = aElement->GetAttr(kNameSpaceID_None, nsXULAtoms::persist, persist); + if (NS_FAILED(rv)) return rv; + + if (rv == NS_CONTENT_ATTR_HAS_VALUE) { + nsAutoString attr; + rv = aAttribute->ToString(attr); + if (NS_FAILED(rv)) return rv; + + if (persist.Find(attr) >= 0) { + rv = Persist(aElement, kNameSpaceID_None, aAttribute); + if (NS_FAILED(rv)) return rv; + } + } + return NS_OK; } @@ -2849,7 +2867,7 @@ nsXULDocument::Persist(const nsAReadableString& aID, { // If we're currently reading persisted attributes out of the // localstore, _don't_ re-enter and try to set them again! - if (mApplyingPersitedAttrs) + if (mApplyingPersistedAttrs) return NS_OK; nsresult rv; @@ -2886,7 +2904,7 @@ nsresult nsXULDocument::Persist(nsIContent* aElement, PRInt32 aNameSpaceID, nsIAtom* aAttribute) { - // First make sure we _have_ a local store to stuff the persited + // First make sure we _have_ a local store to stuff the persisted // information into. (We might not have one if profile information // hasn't been loaded yet...) if (! mLocalStore) @@ -5224,7 +5242,7 @@ nsXULDocument::ApplyPersistentAttributes() if (! mLocalStore) return NS_OK; - mApplyingPersitedAttrs = PR_TRUE; + mApplyingPersistedAttrs = PR_TRUE; nsSupportsArray elements; @@ -5271,7 +5289,7 @@ nsXULDocument::ApplyPersistentAttributes() ApplyPersistentAttributesToElements(resource, &elements); } - mApplyingPersitedAttrs = PR_FALSE; + mApplyingPersistedAttrs = PR_FALSE; return NS_OK; } diff --git a/mozilla/content/xul/document/src/nsXULDocument.h b/mozilla/content/xul/document/src/nsXULDocument.h index 872ea283b5d..f904c98330d 100644 --- a/mozilla/content/xul/document/src/nsXULDocument.h +++ b/mozilla/content/xul/document/src/nsXULDocument.h @@ -584,7 +584,7 @@ protected: nsVoidArray mSubDocuments; // [OWNER] of subelements PRPackedBool mIsPopup; PRPackedBool mIsFastLoad; - PRPackedBool mApplyingPersitedAttrs; + PRPackedBool mApplyingPersistedAttrs; nsXULDocument* mNextFastLoad; nsCOMPtr mCommandDispatcher; // [OWNER] of the focus tracker @@ -788,6 +788,11 @@ protected: PRBool* aNeedsHookup, PRBool* aDidResolve); + void + SynchronizeBroadcastListener(nsIDOMElement *aBroadcaster, + nsIDOMElement *aListener, + const nsAString &aAttr); + static nsresult InsertElement(nsIContent* aParent, nsIContent* aChild);