зеркало из https://github.com/mozilla/gecko-dev.git
Bug 401463 and others. Make us call InstallImplementation in more places in order to behave more like we did when InstallImplementation was called during LoadBindings. r/sr=jst
This commit is contained in:
Родитель
07f4756c14
Коммит
7fd1b7262b
|
@ -404,7 +404,7 @@ NS_IMPL_CYCLE_COLLECTING_RELEASE(nsBindingManager)
|
|||
// Constructors/Destructors
|
||||
nsBindingManager::nsBindingManager(nsIDocument* aDocument)
|
||||
: mProcessingAttachedStack(PR_FALSE),
|
||||
mProcessOnEndUpdate(PR_FALSE),
|
||||
mAttachedStackSizeOnOutermost(0),
|
||||
mDocument(aDocument)
|
||||
{
|
||||
mContentListTable.ops = nsnull;
|
||||
|
@ -510,7 +510,12 @@ nsBindingManager::SetBinding(nsIContent* aContent, nsXBLBinding* aBinding)
|
|||
aContent->UnsetFlags(NODE_IS_INSERTION_PARENT);
|
||||
}
|
||||
}
|
||||
mAttachedStack.RemoveElement(oldBinding);
|
||||
// Don't remove items here as that could mess up an executing
|
||||
// ProcessAttachedQueue
|
||||
PRUint32 index = mAttachedStack.IndexOf(oldBinding);
|
||||
if (index != mAttachedStack.NoIndex) {
|
||||
mAttachedStack[index] = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
PRBool result = PR_TRUE;
|
||||
|
@ -923,30 +928,46 @@ nsBindingManager::DoProcessAttachedQueue()
|
|||
}
|
||||
|
||||
void
|
||||
nsBindingManager::ProcessAttachedQueue()
|
||||
nsBindingManager::ProcessAttachedQueue(PRUint32 aSkipSize)
|
||||
{
|
||||
if (mProcessingAttachedStack || mAttachedStack.Length() == 0)
|
||||
if (mProcessingAttachedStack || mAttachedStack.Length() <= aSkipSize)
|
||||
return;
|
||||
|
||||
mProcessingAttachedStack = PR_TRUE;
|
||||
|
||||
PRInt32 lastItem;
|
||||
while ((lastItem = mAttachedStack.Length() - 1) >= 0) {
|
||||
nsRefPtr<nsXBLBinding> binding = mAttachedStack.ElementAt(lastItem);
|
||||
mAttachedStack.RemoveElementAt(lastItem);
|
||||
|
||||
NS_ASSERTION(binding, "null item in attached stack?");
|
||||
nsresult rv = binding->EnsureScriptAPI();
|
||||
if (NS_FAILED(rv)) {
|
||||
return;
|
||||
PRUint32 currentIndex = aSkipSize;
|
||||
while (mAttachedStack.Length() > aSkipSize) {
|
||||
// First install all implementations. Do this from low index to high
|
||||
// since that way we'll automatically get any new bindings added in the
|
||||
// process.
|
||||
for (; currentIndex < mAttachedStack.Length(); ++currentIndex) {
|
||||
nsRefPtr<nsXBLBinding> binding = mAttachedStack.ElementAt(currentIndex);
|
||||
if (binding) {
|
||||
nsresult rv = binding->EnsureScriptAPI();
|
||||
if (NS_FAILED(rv)) {
|
||||
mAttachedStack[currentIndex] = nsnull;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
binding->ExecuteAttachedHandler();
|
||||
// Then excute constructors. Do this from high index to low
|
||||
while (currentIndex > aSkipSize && currentIndex == mAttachedStack.Length()) {
|
||||
--currentIndex;
|
||||
nsRefPtr<nsXBLBinding> binding = mAttachedStack.ElementAt(currentIndex);
|
||||
mAttachedStack.RemoveElementAt(currentIndex);
|
||||
if (binding) {
|
||||
binding->ExecuteAttachedHandler();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mProcessingAttachedStack = PR_FALSE;
|
||||
// If NodeWillBeDestroyed has run we don't want to clobber
|
||||
// mProcessingAttachedStack set there.
|
||||
if (mDocument) {
|
||||
mProcessingAttachedStack = PR_FALSE;
|
||||
}
|
||||
|
||||
NS_ASSERTION(mAttachedStack.Length() == 0, "How did we get here?");
|
||||
NS_ASSERTION(mAttachedStack.Length() == aSkipSize, "How did we get here?");
|
||||
|
||||
mAttachedStack.Compact();
|
||||
}
|
||||
|
@ -1534,14 +1555,24 @@ nsBindingManager::Traverse(nsIContent *aContent,
|
|||
void
|
||||
nsBindingManager::BeginOutermostUpdate()
|
||||
{
|
||||
mProcessOnEndUpdate = (mAttachedStack.Length() == 0);
|
||||
mAttachedStackSizeOnOutermost = mAttachedStack.Length();
|
||||
}
|
||||
|
||||
void
|
||||
nsBindingManager::EndOutermostUpdate()
|
||||
{
|
||||
if (mProcessOnEndUpdate) {
|
||||
mProcessOnEndUpdate = PR_FALSE;
|
||||
ProcessAttachedQueue();
|
||||
if (!mProcessingAttachedStack) {
|
||||
ProcessAttachedQueue(mAttachedStackSizeOnOutermost);
|
||||
mAttachedStackSizeOnOutermost = 0;
|
||||
}
|
||||
else {
|
||||
PRUint32 i = mAttachedStackSizeOnOutermost;
|
||||
for (; i < mAttachedStack.Length(); ++i) {
|
||||
nsRefPtr<nsXBLBinding> binding = mAttachedStack[i];
|
||||
nsresult rv = binding->EnsureScriptAPI();
|
||||
if (NS_FAILED(rv)) {
|
||||
mAttachedStack[i] = nsnull;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -162,7 +162,7 @@ public:
|
|||
nsIPrincipal* aOriginPrincipal);
|
||||
|
||||
nsresult AddToAttachedQueue(nsXBLBinding* aBinding);
|
||||
void ProcessAttachedQueue();
|
||||
void ProcessAttachedQueue(PRUint32 aSkipSize = 0);
|
||||
|
||||
void ExecuteDetachedHandlers();
|
||||
|
||||
|
@ -287,7 +287,7 @@ protected:
|
|||
// A queue of binding attached event handlers that are awaiting execution.
|
||||
nsBindingList mAttachedStack;
|
||||
PRPackedBool mProcessingAttachedStack;
|
||||
PRPackedBool mProcessOnEndUpdate;
|
||||
PRUint32 mAttachedStackSizeOnOutermost;
|
||||
|
||||
// Our posted event to process the attached queue, if any
|
||||
friend class nsRunnableMethod<nsBindingManager>;
|
||||
|
|
Загрузка…
Ссылка в новой задаче