mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-14 02:31:59 +00:00
Bug 13378. Make sure that we hook up any broadcasters that arrive in overlay subtrees. r=hyatt
This commit is contained in:
parent
6ca0248d35
commit
b20b076a88
@ -2699,29 +2699,25 @@ nsXULElement::AddBroadcastListener(const nsString& attr, nsIDOMElement* anElemen
|
||||
listener->SetAttribute(attr->GetNameSpaceID(), attr->GetName(), value, PR_TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
else {
|
||||
// Find out if the attribute is even present at all.
|
||||
nsCOMPtr<nsIAtom> kAtom = dont_AddRef(NS_NewAtom(attr));
|
||||
|
||||
// Find out if the attribute is even present at all.
|
||||
nsAutoString attrValue;
|
||||
nsIAtom* kAtom = NS_NewAtom(attr);
|
||||
nsresult result = GetAttribute(kNameSpaceID_None, kAtom, attrValue);
|
||||
PRBool attrPresent = (result == NS_CONTENT_ATTR_NO_VALUE ||
|
||||
result == NS_CONTENT_ATTR_HAS_VALUE);
|
||||
nsAutoString attrValue;
|
||||
nsresult result = GetAttribute(kNameSpaceID_None, kAtom, attrValue);
|
||||
PRBool attrPresent = (result == NS_CONTENT_ATTR_NO_VALUE ||
|
||||
result == NS_CONTENT_ATTR_HAS_VALUE);
|
||||
|
||||
if (attrPresent)
|
||||
{
|
||||
if (attrPresent) {
|
||||
// Set the attribute
|
||||
anElement->SetAttribute(attr, attrValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
// Unset the attribute
|
||||
anElement->RemoveAttribute(attr);
|
||||
}
|
||||
|
||||
NS_RELEASE(kAtom);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -34,35 +34,38 @@ public:
|
||||
/**
|
||||
* Priority codes returned from GetPriority()
|
||||
*/
|
||||
enum Priority {
|
||||
enum State {
|
||||
/** A dummy marker, used to indicate unstarted resolution */
|
||||
eStart,
|
||||
|
||||
/** The initial pass, after which the content model will be
|
||||
fully built */
|
||||
ePriority_Construction,
|
||||
eConstruction,
|
||||
|
||||
/** A second pass, after which all 'magic attribute' hookup
|
||||
will have been performed */
|
||||
ePriority_Hookup,
|
||||
eHookup,
|
||||
|
||||
/** A dummy marker, used in kPasses to indicate termination */
|
||||
ePriority_Done
|
||||
eDone
|
||||
};
|
||||
|
||||
/**
|
||||
* Forward references are categorized by 'priority', and all
|
||||
* forward references in a higher priority are resolved before any
|
||||
* reference in a lower priority. This variable specifies this
|
||||
* ordering. The last Priority is guaranteed to be ePriority_Done.
|
||||
* ordering. The last Priority is guaranteed to be eDone.
|
||||
*/
|
||||
static const Priority kPasses[];
|
||||
static const State kPasses[];
|
||||
|
||||
/**
|
||||
* Get the priority of the forward reference. 'ePriority_Construction'
|
||||
* references are all resolved before 'ePriority_Hookup' references
|
||||
* Get the state in which the forward reference should be resolved.
|
||||
* 'eConstruction' references are all resolved before 'eHookup' references
|
||||
* are resolved.
|
||||
*
|
||||
* @return the Priority of the reference
|
||||
* @return the State in which the reference needs to be resolved
|
||||
*/
|
||||
virtual Priority GetPriority() = 0;
|
||||
virtual State GetState() = 0;
|
||||
|
||||
/**
|
||||
* Result codes returned from Resolve()
|
||||
|
@ -159,10 +159,10 @@ static NS_DEFINE_IID(kIParserIID, NS_IPARSER_IID);
|
||||
|
||||
#define XUL_NAMESPACE_URI "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
|
||||
const nsForwardReference::Priority nsForwardReference::kPasses[] = {
|
||||
nsForwardReference::ePriority_Construction,
|
||||
nsForwardReference::ePriority_Hookup,
|
||||
nsForwardReference::ePriority_Done
|
||||
const nsForwardReference::State nsForwardReference::kPasses[] = {
|
||||
nsForwardReference::State::eConstruction,
|
||||
nsForwardReference::State::eHookup,
|
||||
nsForwardReference::State::eDone
|
||||
};
|
||||
|
||||
|
||||
@ -217,7 +217,7 @@ nsXULDocument::nsXULDocument(void)
|
||||
mCharSetID("UTF-8"),
|
||||
mDisplaySelection(PR_FALSE),
|
||||
mIsPopup(PR_FALSE),
|
||||
mForwardReferencesResolved(PR_FALSE),
|
||||
mResolutionPhase(nsForwardReference::State::eStart),
|
||||
mState(eState_Master)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
@ -1814,7 +1814,7 @@ nsXULDocument::SetForm(nsIDOMHTMLFormElement* aForm)
|
||||
NS_IMETHODIMP
|
||||
nsXULDocument::AddForwardReference(nsForwardReference* aRef)
|
||||
{
|
||||
if (! mForwardReferencesResolved) {
|
||||
if (mResolutionPhase < aRef->GetState()) {
|
||||
mForwardReferences.AppendElement(aRef);
|
||||
}
|
||||
else {
|
||||
@ -1829,23 +1829,17 @@ nsXULDocument::AddForwardReference(nsForwardReference* aRef)
|
||||
NS_IMETHODIMP
|
||||
nsXULDocument::ResolveForwardReferences()
|
||||
{
|
||||
if (mForwardReferencesResolved)
|
||||
if (mResolutionPhase == nsForwardReference::State::eDone)
|
||||
return NS_OK;
|
||||
|
||||
// So we're monotonic. This prevents a forward reference from
|
||||
// adding _yet another_ forward reference, which could cause the
|
||||
// 'annealing' process to diverge.
|
||||
mForwardReferencesResolved = PR_TRUE;
|
||||
|
||||
// Resolve each outstanding 'forward' reference. We iterate
|
||||
// through the list of forward references until no more forward
|
||||
// references can be resolved. This annealing process is
|
||||
// guaranteed to converge because we've "closed the gate" to new
|
||||
// forward references.
|
||||
|
||||
for (const nsForwardReference::Priority* pass = nsForwardReference::kPasses;
|
||||
*pass != nsForwardReference::ePriority_Done;
|
||||
++pass) {
|
||||
const nsForwardReference::State* pass = nsForwardReference::kPasses;
|
||||
while ((mResolutionPhase = *pass) != nsForwardReference::eDone) {
|
||||
PRInt32 previous = 0;
|
||||
while (mForwardReferences.Count() && mForwardReferences.Count() != previous) {
|
||||
previous = mForwardReferences.Count();
|
||||
@ -1853,27 +1847,28 @@ nsXULDocument::ResolveForwardReferences()
|
||||
for (PRInt32 i = 0; i < mForwardReferences.Count(); ++i) {
|
||||
nsForwardReference* fwdref = NS_REINTERPRET_CAST(nsForwardReference*, mForwardReferences[i]);
|
||||
|
||||
if (fwdref->GetPriority() != *pass)
|
||||
continue;
|
||||
if (fwdref->GetState() == *pass) {
|
||||
nsForwardReference::Result result = fwdref->Resolve();
|
||||
|
||||
nsForwardReference::Result result = fwdref->Resolve();
|
||||
switch (result) {
|
||||
case nsForwardReference::eResolve_Succeeded:
|
||||
case nsForwardReference::eResolve_Error:
|
||||
mForwardReferences.RemoveElementAt(i);
|
||||
delete fwdref;
|
||||
|
||||
switch (result) {
|
||||
case nsForwardReference::eResolve_Succeeded:
|
||||
case nsForwardReference::eResolve_Error:
|
||||
mForwardReferences.RemoveElementAt(i);
|
||||
delete fwdref;
|
||||
// fixup because we removed from list
|
||||
--i;
|
||||
break;
|
||||
|
||||
// fixup because we removed from list
|
||||
--i;
|
||||
break;
|
||||
|
||||
case nsForwardReference::eResolve_Later:
|
||||
// do nothing. we'll try again later
|
||||
;
|
||||
case nsForwardReference::eResolve_Later:
|
||||
// do nothing. we'll try again later
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
++pass;
|
||||
}
|
||||
|
||||
DestroyForwardReferences();
|
||||
@ -2445,13 +2440,13 @@ nsXULDocument::AddSubtreeToDocument(nsIContent* aElement)
|
||||
|
||||
// 3. Check for a broadcaster hookup attribute, in which case
|
||||
// we'll hook the node up as a listener on a broadcaster.
|
||||
PRBool resolved;
|
||||
rv = CheckBroadcasterHookup(this, aElement, &resolved);
|
||||
PRBool listener, resolved;
|
||||
rv = CheckBroadcasterHookup(this, aElement, &listener, &resolved);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// If it's not there yet, we may be able to defer hookup until
|
||||
// later.
|
||||
if (!resolved && !mForwardReferencesResolved) {
|
||||
if (listener && !resolved && (mResolutionPhase != nsForwardReference::State::eDone)) {
|
||||
BroadcasterHookup* hookup = new BroadcasterHookup(this, aElement);
|
||||
if (! hookup)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
@ -5141,7 +5136,9 @@ nsForwardReference::Result
|
||||
nsXULDocument::BroadcasterHookup::Resolve()
|
||||
{
|
||||
nsresult rv;
|
||||
rv = CheckBroadcasterHookup(mDocument, mObservesElement, &mResolved);
|
||||
|
||||
PRBool listener;
|
||||
rv = CheckBroadcasterHookup(mDocument, mObservesElement, &listener, &mResolved);
|
||||
if (NS_FAILED(rv)) return eResolve_Error;
|
||||
|
||||
return mResolved ? eResolve_Succeeded : eResolve_Later;
|
||||
@ -5196,6 +5193,7 @@ nsXULDocument::BroadcasterHookup::~BroadcasterHookup()
|
||||
nsresult
|
||||
nsXULDocument::CheckBroadcasterHookup(nsXULDocument* aDocument,
|
||||
nsIContent* aElement,
|
||||
PRBool* aNeedsHookup,
|
||||
PRBool* aDidResolve)
|
||||
{
|
||||
// Resolve a broadcaster hookup. Look at the element that we're
|
||||
@ -5233,8 +5231,10 @@ nsXULDocument::CheckBroadcasterHookup(nsXULDocument* aDocument,
|
||||
|
||||
// If we're still parented by an 'overlay' tag, then we haven't
|
||||
// made it into the real document yet. Defer hookup.
|
||||
if (parentTag.get() == kOverlayAtom)
|
||||
if (parentTag.get() == kOverlayAtom) {
|
||||
*aNeedsHookup = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
listener = do_QueryInterface(parent);
|
||||
|
||||
@ -5253,8 +5253,10 @@ nsXULDocument::CheckBroadcasterHookup(nsXULDocument* aDocument,
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// Bail if there's no broadcasterID
|
||||
if ((rv != NS_CONTENT_ATTR_HAS_VALUE) || (broadcasterID.Length() == 0))
|
||||
if ((rv != NS_CONTENT_ATTR_HAS_VALUE) || (broadcasterID.Length() == 0)) {
|
||||
*aNeedsHookup = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
listener = do_QueryInterface(aElement);
|
||||
|
||||
@ -5274,12 +5276,16 @@ nsXULDocument::CheckBroadcasterHookup(nsXULDocument* aDocument,
|
||||
// If we can't find the broadcaster, then we'll need to defer the
|
||||
// hookup. We may need to resolve some of the other overlays
|
||||
// first.
|
||||
if (! target)
|
||||
if (! target) {
|
||||
*aNeedsHookup = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMXULElement> broadcaster = do_QueryInterface(target);
|
||||
if (! broadcaster)
|
||||
if (! broadcaster) {
|
||||
*aNeedsHookup = PR_FALSE;
|
||||
return NS_OK; // not a XUL element, so we can't subscribe
|
||||
}
|
||||
|
||||
rv = broadcaster->AddBroadcastListener(attribute, listener);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
@ -5310,6 +5316,7 @@ nsXULDocument::CheckBroadcasterHookup(nsXULDocument* aDocument,
|
||||
}
|
||||
#endif
|
||||
|
||||
*aNeedsHookup = PR_FALSE;
|
||||
*aDidResolve = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -519,7 +519,7 @@ protected:
|
||||
nsCOMPtr<nsIDOMXULCommandDispatcher> mCommandDispatcher; // [OWNER] of the focus tracker
|
||||
|
||||
nsVoidArray mForwardReferences;
|
||||
PRBool mForwardReferencesResolved;
|
||||
nsForwardReference::State mResolutionPhase;
|
||||
|
||||
// The following are pointers into the content model which provide access to
|
||||
// the objects triggering either a popup or a tooltip. These are marked as
|
||||
@ -651,7 +651,7 @@ protected:
|
||||
|
||||
virtual ~BroadcasterHookup();
|
||||
|
||||
virtual Priority GetPriority() { return ePriority_Hookup; }
|
||||
virtual State GetState() { return eHookup; }
|
||||
virtual Result Resolve();
|
||||
};
|
||||
|
||||
@ -676,7 +676,7 @@ protected:
|
||||
|
||||
virtual ~OverlayForwardReference();
|
||||
|
||||
virtual Priority GetPriority() { return ePriority_Construction; }
|
||||
virtual State GetState() { return eConstruction; }
|
||||
virtual Result Resolve();
|
||||
};
|
||||
|
||||
@ -687,6 +687,7 @@ protected:
|
||||
nsresult
|
||||
CheckBroadcasterHookup(nsXULDocument* aDocument,
|
||||
nsIContent* aElement,
|
||||
PRBool* aNeedsHookup,
|
||||
PRBool* aDidResolve);
|
||||
|
||||
static
|
||||
|
@ -34,35 +34,38 @@ public:
|
||||
/**
|
||||
* Priority codes returned from GetPriority()
|
||||
*/
|
||||
enum Priority {
|
||||
enum State {
|
||||
/** A dummy marker, used to indicate unstarted resolution */
|
||||
eStart,
|
||||
|
||||
/** The initial pass, after which the content model will be
|
||||
fully built */
|
||||
ePriority_Construction,
|
||||
eConstruction,
|
||||
|
||||
/** A second pass, after which all 'magic attribute' hookup
|
||||
will have been performed */
|
||||
ePriority_Hookup,
|
||||
eHookup,
|
||||
|
||||
/** A dummy marker, used in kPasses to indicate termination */
|
||||
ePriority_Done
|
||||
eDone
|
||||
};
|
||||
|
||||
/**
|
||||
* Forward references are categorized by 'priority', and all
|
||||
* forward references in a higher priority are resolved before any
|
||||
* reference in a lower priority. This variable specifies this
|
||||
* ordering. The last Priority is guaranteed to be ePriority_Done.
|
||||
* ordering. The last Priority is guaranteed to be eDone.
|
||||
*/
|
||||
static const Priority kPasses[];
|
||||
static const State kPasses[];
|
||||
|
||||
/**
|
||||
* Get the priority of the forward reference. 'ePriority_Construction'
|
||||
* references are all resolved before 'ePriority_Hookup' references
|
||||
* Get the state in which the forward reference should be resolved.
|
||||
* 'eConstruction' references are all resolved before 'eHookup' references
|
||||
* are resolved.
|
||||
*
|
||||
* @return the Priority of the reference
|
||||
* @return the State in which the reference needs to be resolved
|
||||
*/
|
||||
virtual Priority GetPriority() = 0;
|
||||
virtual State GetState() = 0;
|
||||
|
||||
/**
|
||||
* Result codes returned from Resolve()
|
||||
|
@ -159,10 +159,10 @@ static NS_DEFINE_IID(kIParserIID, NS_IPARSER_IID);
|
||||
|
||||
#define XUL_NAMESPACE_URI "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
|
||||
const nsForwardReference::Priority nsForwardReference::kPasses[] = {
|
||||
nsForwardReference::ePriority_Construction,
|
||||
nsForwardReference::ePriority_Hookup,
|
||||
nsForwardReference::ePriority_Done
|
||||
const nsForwardReference::State nsForwardReference::kPasses[] = {
|
||||
nsForwardReference::State::eConstruction,
|
||||
nsForwardReference::State::eHookup,
|
||||
nsForwardReference::State::eDone
|
||||
};
|
||||
|
||||
|
||||
@ -217,7 +217,7 @@ nsXULDocument::nsXULDocument(void)
|
||||
mCharSetID("UTF-8"),
|
||||
mDisplaySelection(PR_FALSE),
|
||||
mIsPopup(PR_FALSE),
|
||||
mForwardReferencesResolved(PR_FALSE),
|
||||
mResolutionPhase(nsForwardReference::State::eStart),
|
||||
mState(eState_Master)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
@ -1814,7 +1814,7 @@ nsXULDocument::SetForm(nsIDOMHTMLFormElement* aForm)
|
||||
NS_IMETHODIMP
|
||||
nsXULDocument::AddForwardReference(nsForwardReference* aRef)
|
||||
{
|
||||
if (! mForwardReferencesResolved) {
|
||||
if (mResolutionPhase < aRef->GetState()) {
|
||||
mForwardReferences.AppendElement(aRef);
|
||||
}
|
||||
else {
|
||||
@ -1829,23 +1829,17 @@ nsXULDocument::AddForwardReference(nsForwardReference* aRef)
|
||||
NS_IMETHODIMP
|
||||
nsXULDocument::ResolveForwardReferences()
|
||||
{
|
||||
if (mForwardReferencesResolved)
|
||||
if (mResolutionPhase == nsForwardReference::State::eDone)
|
||||
return NS_OK;
|
||||
|
||||
// So we're monotonic. This prevents a forward reference from
|
||||
// adding _yet another_ forward reference, which could cause the
|
||||
// 'annealing' process to diverge.
|
||||
mForwardReferencesResolved = PR_TRUE;
|
||||
|
||||
// Resolve each outstanding 'forward' reference. We iterate
|
||||
// through the list of forward references until no more forward
|
||||
// references can be resolved. This annealing process is
|
||||
// guaranteed to converge because we've "closed the gate" to new
|
||||
// forward references.
|
||||
|
||||
for (const nsForwardReference::Priority* pass = nsForwardReference::kPasses;
|
||||
*pass != nsForwardReference::ePriority_Done;
|
||||
++pass) {
|
||||
const nsForwardReference::State* pass = nsForwardReference::kPasses;
|
||||
while ((mResolutionPhase = *pass) != nsForwardReference::eDone) {
|
||||
PRInt32 previous = 0;
|
||||
while (mForwardReferences.Count() && mForwardReferences.Count() != previous) {
|
||||
previous = mForwardReferences.Count();
|
||||
@ -1853,27 +1847,28 @@ nsXULDocument::ResolveForwardReferences()
|
||||
for (PRInt32 i = 0; i < mForwardReferences.Count(); ++i) {
|
||||
nsForwardReference* fwdref = NS_REINTERPRET_CAST(nsForwardReference*, mForwardReferences[i]);
|
||||
|
||||
if (fwdref->GetPriority() != *pass)
|
||||
continue;
|
||||
if (fwdref->GetState() == *pass) {
|
||||
nsForwardReference::Result result = fwdref->Resolve();
|
||||
|
||||
nsForwardReference::Result result = fwdref->Resolve();
|
||||
switch (result) {
|
||||
case nsForwardReference::eResolve_Succeeded:
|
||||
case nsForwardReference::eResolve_Error:
|
||||
mForwardReferences.RemoveElementAt(i);
|
||||
delete fwdref;
|
||||
|
||||
switch (result) {
|
||||
case nsForwardReference::eResolve_Succeeded:
|
||||
case nsForwardReference::eResolve_Error:
|
||||
mForwardReferences.RemoveElementAt(i);
|
||||
delete fwdref;
|
||||
// fixup because we removed from list
|
||||
--i;
|
||||
break;
|
||||
|
||||
// fixup because we removed from list
|
||||
--i;
|
||||
break;
|
||||
|
||||
case nsForwardReference::eResolve_Later:
|
||||
// do nothing. we'll try again later
|
||||
;
|
||||
case nsForwardReference::eResolve_Later:
|
||||
// do nothing. we'll try again later
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
++pass;
|
||||
}
|
||||
|
||||
DestroyForwardReferences();
|
||||
@ -2445,13 +2440,13 @@ nsXULDocument::AddSubtreeToDocument(nsIContent* aElement)
|
||||
|
||||
// 3. Check for a broadcaster hookup attribute, in which case
|
||||
// we'll hook the node up as a listener on a broadcaster.
|
||||
PRBool resolved;
|
||||
rv = CheckBroadcasterHookup(this, aElement, &resolved);
|
||||
PRBool listener, resolved;
|
||||
rv = CheckBroadcasterHookup(this, aElement, &listener, &resolved);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// If it's not there yet, we may be able to defer hookup until
|
||||
// later.
|
||||
if (!resolved && !mForwardReferencesResolved) {
|
||||
if (listener && !resolved && (mResolutionPhase != nsForwardReference::State::eDone)) {
|
||||
BroadcasterHookup* hookup = new BroadcasterHookup(this, aElement);
|
||||
if (! hookup)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
@ -5141,7 +5136,9 @@ nsForwardReference::Result
|
||||
nsXULDocument::BroadcasterHookup::Resolve()
|
||||
{
|
||||
nsresult rv;
|
||||
rv = CheckBroadcasterHookup(mDocument, mObservesElement, &mResolved);
|
||||
|
||||
PRBool listener;
|
||||
rv = CheckBroadcasterHookup(mDocument, mObservesElement, &listener, &mResolved);
|
||||
if (NS_FAILED(rv)) return eResolve_Error;
|
||||
|
||||
return mResolved ? eResolve_Succeeded : eResolve_Later;
|
||||
@ -5196,6 +5193,7 @@ nsXULDocument::BroadcasterHookup::~BroadcasterHookup()
|
||||
nsresult
|
||||
nsXULDocument::CheckBroadcasterHookup(nsXULDocument* aDocument,
|
||||
nsIContent* aElement,
|
||||
PRBool* aNeedsHookup,
|
||||
PRBool* aDidResolve)
|
||||
{
|
||||
// Resolve a broadcaster hookup. Look at the element that we're
|
||||
@ -5233,8 +5231,10 @@ nsXULDocument::CheckBroadcasterHookup(nsXULDocument* aDocument,
|
||||
|
||||
// If we're still parented by an 'overlay' tag, then we haven't
|
||||
// made it into the real document yet. Defer hookup.
|
||||
if (parentTag.get() == kOverlayAtom)
|
||||
if (parentTag.get() == kOverlayAtom) {
|
||||
*aNeedsHookup = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
listener = do_QueryInterface(parent);
|
||||
|
||||
@ -5253,8 +5253,10 @@ nsXULDocument::CheckBroadcasterHookup(nsXULDocument* aDocument,
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// Bail if there's no broadcasterID
|
||||
if ((rv != NS_CONTENT_ATTR_HAS_VALUE) || (broadcasterID.Length() == 0))
|
||||
if ((rv != NS_CONTENT_ATTR_HAS_VALUE) || (broadcasterID.Length() == 0)) {
|
||||
*aNeedsHookup = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
listener = do_QueryInterface(aElement);
|
||||
|
||||
@ -5274,12 +5276,16 @@ nsXULDocument::CheckBroadcasterHookup(nsXULDocument* aDocument,
|
||||
// If we can't find the broadcaster, then we'll need to defer the
|
||||
// hookup. We may need to resolve some of the other overlays
|
||||
// first.
|
||||
if (! target)
|
||||
if (! target) {
|
||||
*aNeedsHookup = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMXULElement> broadcaster = do_QueryInterface(target);
|
||||
if (! broadcaster)
|
||||
if (! broadcaster) {
|
||||
*aNeedsHookup = PR_FALSE;
|
||||
return NS_OK; // not a XUL element, so we can't subscribe
|
||||
}
|
||||
|
||||
rv = broadcaster->AddBroadcastListener(attribute, listener);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
@ -5310,6 +5316,7 @@ nsXULDocument::CheckBroadcasterHookup(nsXULDocument* aDocument,
|
||||
}
|
||||
#endif
|
||||
|
||||
*aNeedsHookup = PR_FALSE;
|
||||
*aDidResolve = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -519,7 +519,7 @@ protected:
|
||||
nsCOMPtr<nsIDOMXULCommandDispatcher> mCommandDispatcher; // [OWNER] of the focus tracker
|
||||
|
||||
nsVoidArray mForwardReferences;
|
||||
PRBool mForwardReferencesResolved;
|
||||
nsForwardReference::State mResolutionPhase;
|
||||
|
||||
// The following are pointers into the content model which provide access to
|
||||
// the objects triggering either a popup or a tooltip. These are marked as
|
||||
@ -651,7 +651,7 @@ protected:
|
||||
|
||||
virtual ~BroadcasterHookup();
|
||||
|
||||
virtual Priority GetPriority() { return ePriority_Hookup; }
|
||||
virtual State GetState() { return eHookup; }
|
||||
virtual Result Resolve();
|
||||
};
|
||||
|
||||
@ -676,7 +676,7 @@ protected:
|
||||
|
||||
virtual ~OverlayForwardReference();
|
||||
|
||||
virtual Priority GetPriority() { return ePriority_Construction; }
|
||||
virtual State GetState() { return eConstruction; }
|
||||
virtual Result Resolve();
|
||||
};
|
||||
|
||||
@ -687,6 +687,7 @@ protected:
|
||||
nsresult
|
||||
CheckBroadcasterHookup(nsXULDocument* aDocument,
|
||||
nsIContent* aElement,
|
||||
PRBool* aNeedsHookup,
|
||||
PRBool* aDidResolve);
|
||||
|
||||
static
|
||||
|
@ -2699,29 +2699,25 @@ nsXULElement::AddBroadcastListener(const nsString& attr, nsIDOMElement* anElemen
|
||||
listener->SetAttribute(attr->GetNameSpaceID(), attr->GetName(), value, PR_TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
else {
|
||||
// Find out if the attribute is even present at all.
|
||||
nsCOMPtr<nsIAtom> kAtom = dont_AddRef(NS_NewAtom(attr));
|
||||
|
||||
// Find out if the attribute is even present at all.
|
||||
nsAutoString attrValue;
|
||||
nsIAtom* kAtom = NS_NewAtom(attr);
|
||||
nsresult result = GetAttribute(kNameSpaceID_None, kAtom, attrValue);
|
||||
PRBool attrPresent = (result == NS_CONTENT_ATTR_NO_VALUE ||
|
||||
result == NS_CONTENT_ATTR_HAS_VALUE);
|
||||
nsAutoString attrValue;
|
||||
nsresult result = GetAttribute(kNameSpaceID_None, kAtom, attrValue);
|
||||
PRBool attrPresent = (result == NS_CONTENT_ATTR_NO_VALUE ||
|
||||
result == NS_CONTENT_ATTR_HAS_VALUE);
|
||||
|
||||
if (attrPresent)
|
||||
{
|
||||
if (attrPresent) {
|
||||
// Set the attribute
|
||||
anElement->SetAttribute(attr, attrValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
// Unset the attribute
|
||||
anElement->RemoveAttribute(attr);
|
||||
}
|
||||
|
||||
NS_RELEASE(kAtom);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user