зеркало из https://github.com/mozilla/gecko-dev.git
Bug 470687, try to prevent broadcaster loops, r=enndeakin, sr=neil
This commit is contained in:
Родитель
23446e97e2
Коммит
123c00756f
|
@ -1021,23 +1021,36 @@ nsXULDocument::AttributeChanged(nsIDocument* aDocument,
|
|||
= do_QueryReferent(bl->mListener);
|
||||
nsCOMPtr<nsIContent> l = do_QueryInterface(listenerEl);
|
||||
if (l) {
|
||||
nsAutoString currentValue;
|
||||
PRBool hasAttr = l->GetAttr(kNameSpaceID_None,
|
||||
aAttribute,
|
||||
currentValue);
|
||||
// We need to update listener only if we're
|
||||
// (1) removing an existing attribute,
|
||||
// (2) adding a new attribute or
|
||||
// (3) changing the value of an attribute.
|
||||
PRBool needsAttrChange =
|
||||
attrSet != hasAttr || !value.Equals(currentValue);
|
||||
nsDelayedBroadcastUpdate delayedUpdate(domele,
|
||||
listenerEl,
|
||||
aAttribute,
|
||||
value,
|
||||
attrSet,
|
||||
needsAttrChange);
|
||||
mDelayedAttrChangeBroadcasts.AppendElement(delayedUpdate);
|
||||
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,
|
||||
currentValue);
|
||||
// We need to update listener only if we're
|
||||
// (1) removing an existing attribute,
|
||||
// (2) adding a new attribute or
|
||||
// (3) changing the value of an attribute.
|
||||
PRBool needsAttrChange =
|
||||
attrSet != hasAttr || !value.Equals(currentValue);
|
||||
nsDelayedBroadcastUpdate delayedUpdate(domele,
|
||||
listenerEl,
|
||||
aAttribute,
|
||||
value,
|
||||
attrSet,
|
||||
needsAttrChange);
|
||||
mDelayedAttrChangeBroadcasts.AppendElement(delayedUpdate);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
|
|
@ -734,6 +734,7 @@ protected:
|
|||
|
||||
nsTArray<nsDelayedBroadcastUpdate> mDelayedBroadcasters;
|
||||
nsTArray<nsDelayedBroadcastUpdate> mDelayedAttrChangeBroadcasts;
|
||||
PRBool mHandlingDelayedAttrChange;
|
||||
private:
|
||||
// helpers
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче