Bug 470687, try to prevent broadcaster loops, r=enndeakin, sr=neil

This commit is contained in:
Olli Pettay 2009-01-07 15:25:29 +02:00
parent 23446e97e2
commit 123c00756f
2 changed files with 44 additions and 31 deletions

View File

@ -1021,6 +1021,18 @@ nsXULDocument::AttributeChanged(nsIDocument* aDocument,
= do_QueryReferent(bl->mListener);
nsCOMPtr<nsIContent> l = do_QueryInterface(listenerEl);
if (l) {
PRBool possibleCycle = PR_FALSE;
for (PRUint32 j = 0; j < mDelayedAttrChangeBroadcasts.Length(); ++j) {
if (mDelayedAttrChangeBroadcasts[j].mListener == listenerEl &&
mDelayedAttrChangeBroadcasts[j].mAttrName == aAttribute) {
possibleCycle = PR_TRUE;
break;
}
}
if (possibleCycle) {
NS_WARNING("Broadcasting loop!");
} else {
nsAutoString currentValue;
PRBool hasAttr = l->GetAttr(kNameSpaceID_None,
aAttribute,
@ -1043,6 +1055,7 @@ nsXULDocument::AttributeChanged(nsIDocument* aDocument,
}
}
}
}
// checks for modifications in broadcasters
PRBool listener, resolved;
@ -3289,18 +3302,15 @@ nsXULDocument::EndUpdate(nsUpdateType aUpdateType)
{
nsXMLDocument::EndUpdate(aUpdateType);
if (mUpdateNestLevel == 0) {
PRUint32 length = mDelayedAttrChangeBroadcasts.Length();
if (length) {
nsTArray<nsDelayedBroadcastUpdate> delayedAttrChangeBroadcasts;
mDelayedAttrChangeBroadcasts.SwapElements(
delayedAttrChangeBroadcasts);
for (PRUint32 i = 0; i < length; ++i) {
nsIAtom* attrName = delayedAttrChangeBroadcasts[i].mAttrName;
if (delayedAttrChangeBroadcasts[i].mNeedsAttrChange) {
if (!mHandlingDelayedAttrChange) {
mHandlingDelayedAttrChange = PR_TRUE;
for (PRUint32 i = 0; i < mDelayedAttrChangeBroadcasts.Length(); ++i) {
nsIAtom* attrName = mDelayedAttrChangeBroadcasts[i].mAttrName;
if (mDelayedAttrChangeBroadcasts[i].mNeedsAttrChange) {
nsCOMPtr<nsIContent> listener =
do_QueryInterface(delayedAttrChangeBroadcasts[i].mListener);
nsString value = delayedAttrChangeBroadcasts[i].mAttr;
if (delayedAttrChangeBroadcasts[i].mSetAttr) {
do_QueryInterface(mDelayedAttrChangeBroadcasts[i].mListener);
nsString value = mDelayedAttrChangeBroadcasts[i].mAttr;
if (mDelayedAttrChangeBroadcasts[i].mSetAttr) {
listener->SetAttr(kNameSpaceID_None, attrName, value,
PR_TRUE);
} else {
@ -3309,14 +3319,16 @@ nsXULDocument::EndUpdate(nsUpdateType aUpdateType)
}
}
nsCOMPtr<nsIContent> broadcaster =
do_QueryInterface(delayedAttrChangeBroadcasts[i].mBroadcaster);
do_QueryInterface(mDelayedAttrChangeBroadcasts[i].mBroadcaster);
ExecuteOnBroadcastHandlerFor(broadcaster,
delayedAttrChangeBroadcasts[i].mListener,
mDelayedAttrChangeBroadcasts[i].mListener,
attrName);
}
mDelayedAttrChangeBroadcasts.Clear();
mHandlingDelayedAttrChange = PR_FALSE;
}
length = mDelayedBroadcasters.Length();
PRUint32 length = mDelayedBroadcasters.Length();
if (length) {
nsTArray<nsDelayedBroadcastUpdate> delayedBroadcasters;
mDelayedBroadcasters.SwapElements(delayedBroadcasters);

View File

@ -734,6 +734,7 @@ protected:
nsTArray<nsDelayedBroadcastUpdate> mDelayedBroadcasters;
nsTArray<nsDelayedBroadcastUpdate> mDelayedAttrChangeBroadcasts;
PRBool mHandlingDelayedAttrChange;
private:
// helpers