Bug 676213 - document load and busy events may be fired before subdocuments are ready, r=tbsaunde

This commit is contained in:
Alexander Surkov
2011-08-08 16:55:36 +09:00
parent ecf3a7a354
commit ee15517707
8 changed files with 209 additions and 150 deletions

View File

@@ -55,7 +55,7 @@
NotificationController::NotificationController(nsDocAccessible* aDocument,
nsIPresShell* aPresShell) :
mObservingState(eNotObservingRefresh), mDocument(aDocument),
mPresShell(aPresShell), mTreeConstructedState(eTreeConstructionPending)
mPresShell(aPresShell)
{
mTextHash.Init();
@@ -154,10 +154,6 @@ NotificationController::ScheduleContentInsertion(nsAccessible* aContainer,
nsIContent* aStartChildNode,
nsIContent* aEndChildNode)
{
// Ignore content insertions until we constructed accessible tree.
if (mTreeConstructedState == eTreeConstructionPending)
return;
nsRefPtr<ContentInsertion> insertion = new ContentInsertion(mDocument,
aContainer);
if (insertion && insertion->InitChildList(aStartChildNode, aEndChildNode) &&
@@ -207,7 +203,7 @@ NotificationController::WillRefresh(mozilla::TimeStamp aTime)
mObservingState = eRefreshProcessingForUpdate;
// Initial accessible tree construction.
if (mTreeConstructedState == eTreeConstructionPending) {
if (!mDocument->HasLoadState(nsDocAccessible::eTreeConstructed)) {
// If document is not bound to parent at this point then the document is not
// ready yet (process notifications later).
if (!mDocument->IsBoundToParent())
@@ -218,8 +214,7 @@ NotificationController::WillRefresh(mozilla::TimeStamp aTime)
mDocument.get(), mDocument->GetDocumentNode());
#endif
mTreeConstructedState = eTreeConstructed;
mDocument->NotifyOfInitialUpdate();
mDocument->DoInitialUpdate();
NS_ASSERTION(mContentInsertions.Length() == 0,
"Pending content insertions while initial accessible tree isn't created!");
@@ -250,8 +245,8 @@ NotificationController::WillRefresh(mozilla::TimeStamp aTime)
mTextHash.Clear();
// Bind hanging child documents.
PRUint32 childDocCount = mHangingChildDocuments.Length();
for (PRUint32 idx = 0; idx < childDocCount; idx++) {
PRUint32 hangingDocCnt = mHangingChildDocuments.Length();
for (PRUint32 idx = 0; idx < hangingDocCnt; idx++) {
nsDocAccessible* childDoc = mHangingChildDocuments[idx];
nsIContent* ownerContent = mDocument->GetDocumentNode()->
@@ -271,6 +266,25 @@ NotificationController::WillRefresh(mozilla::TimeStamp aTime)
}
mHangingChildDocuments.Clear();
// If the document is ready and all its subdocuments are completely loaded
// then process the document load.
if (mDocument->HasLoadState(nsDocAccessible::eReady) &&
!mDocument->HasLoadState(nsDocAccessible::eCompletelyLoaded) &&
hangingDocCnt == 0) {
PRUint32 childDocCnt = mDocument->ChildDocumentCount(), childDocIdx = 0;
for (; childDocIdx < childDocCnt; childDocIdx++) {
nsDocAccessible* childDoc = mDocument->GetChildDocumentAt(childDocIdx);
if (!childDoc->HasLoadState(nsDocAccessible::eCompletelyLoaded))
break;
}
if (childDocIdx == childDocCnt) {
mDocument->ProcessLoad();
if (!mDocument)
return;
}
}
// Process only currently queued generic notifications.
nsTArray < nsRefPtr<Notification> > notifications;
notifications.SwapElements(mNotifications);
@@ -310,10 +324,12 @@ NotificationController::WillRefresh(mozilla::TimeStamp aTime)
return;
}
// Stop further processing if there are no newly queued insertions,
// notifications or events.
// Stop further processing if there are no new notifications of any kind or
// events and document load is processed.
if (mContentInsertions.Length() == 0 && mNotifications.Length() == 0 &&
mEvents.Length() == 0 &&
mEvents.Length() == 0 && mTextHash.Count() == 0 &&
mHangingChildDocuments.Length() == 0 &&
mDocument->HasLoadState(nsDocAccessible::eCompletelyLoaded) &&
mPresShell->RemoveRefreshObserver(this, Flush_Display)) {
mObservingState = eNotObservingRefresh;
}