void EventTree::Process() { while (mFirst) { // Skip a node and its subtree if its container is not in the document. if (mFirst->mContainer->IsInDocument()) { mFirst->Process(); } mFirst = mFirst->mNext.forget(); } MOZ_ASSERT(mContainer || mDependentEvents.IsEmpty(), "No container, no events"); MOZ_ASSERT(!mContainer || !mContainer->IsDefunct(), "Processing events for defunct container"); // Fire mutation events. uint32_t eventsCount = mDependentEvents.Length(); for (uint32_t jdx = 0; jdx < eventsCount; jdx++) { AccMutationEvent* mtEvent = mDependentEvents[jdx]; MOZ_ASSERT(mtEvent->mEventRule != AccEvent::eDoNotEmit, "The event shouldn't be presented in the tree"); nsEventShell::FireEvent(mtEvent); if (mtEvent->mTextChangeEvent) { nsEventShell::FireEvent(mtEvent->mTextChangeEvent); } if (mtEvent->IsHide()) { // Fire menupopup end event before a hide event if a menu goes away. // XXX: We don't look into children of hidden subtree to find hiding // menupopup (as we did prior bug 570275) because we don't do that when // menu is showing (and that's impossible until bug 606924 is fixed). // Nevertheless we should do this at least because layout coalesces // the changes before our processing and we may miss some menupopup // events. Now we just want to be consistent in content insertion/removal // handling. if (mtEvent->mAccessible->ARIARole() == roles::MENUPOPUP) { nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_MENUPOPUP_END, mtEvent->mAccessible); } AccHideEvent* hideEvent = downcast_accEvent(mtEvent); if (hideEvent->NeedsShutdown()) { mtEvent->GetDocAccessible()->ShutdownChildrenInSubtree(mtEvent->mAccessible); } } } // Fire reorder event at last. if (mFireReorder) { MOZ_ASSERT(mContainer); nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_REORDER, mContainer); mContainer->Document()->MaybeNotifyOfValueChange(mContainer); } mDependentEvents.Clear(); }
void EventTree::Clear() { mFirst = nullptr; mNext = nullptr; mContainer = nullptr; uint32_t eventsCount = mDependentEvents.Length(); for (uint32_t jdx = 0; jdx < eventsCount; jdx++) { AccHideEvent* ev = downcast_accEvent(mDependentEvents[jdx]); if (ev && ev->NeedsShutdown()) { ev->Document()->ShutdownChildrenInSubtree(ev->mAccessible); } } mDependentEvents.Clear(); }
void EventQueue::ProcessEventQueue() { // Process only currently queued events. nsTArray<RefPtr<AccEvent> > events; events.SwapElements(mEvents); uint32_t eventCount = events.Length(); #ifdef A11Y_LOG if (eventCount > 0 && logging::IsEnabled(logging::eEvents)) { logging::MsgBegin("EVENTS", "events processing"); logging::Address("document", mDocument); logging::MsgEnd(); } #endif for (uint32_t idx = 0; idx < eventCount; idx++) { AccEvent* event = events[idx]; if (event->mEventRule != AccEvent::eDoNotEmit) { Accessible* target = event->GetAccessible(); if (!target || target->IsDefunct()) continue; // Dispatch the focus event if target is still focused. if (event->mEventType == nsIAccessibleEvent::EVENT_FOCUS) { FocusMgr()->ProcessFocusEvent(event); continue; } // Dispatch caret moved and text selection change events. if (event->mEventType == nsIAccessibleEvent::EVENT_TEXT_SELECTION_CHANGED) { SelectionMgr()->ProcessTextSelChangeEvent(event); continue; } // Fire selected state change events in support to selection events. if (event->mEventType == nsIAccessibleEvent::EVENT_SELECTION_ADD) { nsEventShell::FireEvent(event->mAccessible, states::SELECTED, true, event->mIsFromUserInput); } else if (event->mEventType == nsIAccessibleEvent::EVENT_SELECTION_REMOVE) { nsEventShell::FireEvent(event->mAccessible, states::SELECTED, false, event->mIsFromUserInput); } else if (event->mEventType == nsIAccessibleEvent::EVENT_SELECTION) { AccSelChangeEvent* selChangeEvent = downcast_accEvent(event); nsEventShell::FireEvent(event->mAccessible, states::SELECTED, (selChangeEvent->mSelChangeType == AccSelChangeEvent::eSelectionAdd), event->mIsFromUserInput); if (selChangeEvent->mPackedEvent) { nsEventShell::FireEvent(selChangeEvent->mPackedEvent->mAccessible, states::SELECTED, (selChangeEvent->mPackedEvent->mSelChangeType == AccSelChangeEvent::eSelectionAdd), selChangeEvent->mPackedEvent->mIsFromUserInput); } } nsEventShell::FireEvent(event); // Fire text change events. AccMutationEvent* mutationEvent = downcast_accEvent(event); if (mutationEvent) { if (mutationEvent->mTextChangeEvent) nsEventShell::FireEvent(mutationEvent->mTextChangeEvent); } } AccHideEvent* hideEvent = downcast_accEvent(event); if (hideEvent && hideEvent->NeedsShutdown()) { mDocument->ShutdownChildrenInSubtree(event->mAccessible); } if (!mDocument) return; } }