Bug 1243583 - ensure transition events are dispatched to all the relevant subdocuments, r=dholbert
--- a/layout/base/nsRefreshDriver.cpp
+++ b/layout/base/nsRefreshDriver.cpp
@@ -1474,56 +1474,56 @@ nsRefreshDriver::DispatchPendingEvents()
nsTArray<PendingEvent> pendingEvents(Move(mPendingEvents));
for (PendingEvent& event : pendingEvents) {
bool dummy;
event.mTarget->DispatchEvent(event.mEvent, &dummy);
}
}
static bool
-DispatchAnimationEventsOnSubDocuments(nsIDocument* aDocument,
- void* aRefreshDriver)
+CollectDocuments(nsIDocument* aDocument, void* aDocArray)
{
- nsIPresShell* shell = aDocument->GetShell();
- if (!shell) {
- return true;
- }
-
- RefPtr<nsPresContext> context = shell->GetPresContext();
- if (!context || context->RefreshDriver() != aRefreshDriver) {
- return true;
- }
-
- nsCOMPtr<nsIDocument> kungFuDeathGrip(aDocument);
-
- context->TransitionManager()->SortEvents();
- context->AnimationManager()->SortEvents();
-
- // Dispatch transition events first since transitions conceptually sit
- // below animations in terms of compositing order.
- context->TransitionManager()->DispatchEvents();
- // Check that the presshell has not been destroyed
- if (context->GetPresShell()) {
- context->AnimationManager()->DispatchEvents();
- }
-
- aDocument->EnumerateSubDocuments(DispatchAnimationEventsOnSubDocuments,
- aRefreshDriver);
-
+ static_cast<nsCOMArray<nsIDocument>*>(aDocArray)->AppendObject(aDocument);
+ aDocument->EnumerateSubDocuments(CollectDocuments, aDocArray);
return true;
}
void
nsRefreshDriver::DispatchAnimationEvents()
{
if (!mPresContext) {
return;
}
- DispatchAnimationEventsOnSubDocuments(mPresContext->Document(), this);
+ nsCOMArray<nsIDocument> documents;
+ CollectDocuments(mPresContext->Document(), &documents);
+
+ for (int32_t i = 0; i < documents.Count(); ++i) {
+ nsIDocument* doc = documents[i];
+ nsIPresShell* shell = doc->GetShell();
+ if (!shell) {
+ continue;
+ }
+
+ RefPtr<nsPresContext> context = shell->GetPresContext();
+ if (!context || context->RefreshDriver() != this) {
+ continue;
+ }
+
+ context->TransitionManager()->SortEvents();
+ context->AnimationManager()->SortEvents();
+
+ // Dispatch transition events first since transitions conceptually sit
+ // below animations in terms of compositing order.
+ context->TransitionManager()->DispatchEvents();
+ // Check that the presshell has not been destroyed
+ if (context->GetPresShell()) {
+ context->AnimationManager()->DispatchEvents();
+ }
+ }
}
void
nsRefreshDriver::RunFrameRequestCallbacks(TimeStamp aNowTime)
{
// Grab all of our frame request callbacks up front.
nsTArray<DocumentFrameCallbacks>
frameRequestCallbacks(mFrameRequestCallbackDocs.Length() +