/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/** * Template class for generic notification. * * @note Instance is kept as a weak ref, the caller must guarantee it exists * longer than the document accessible owning the notification controller * that this notification is processed by.
*/ template <classClass, class... Args> class TNotification : public Notification { public: typedefvoid (Class::*Callback)(Args*...);
/** * Used to process notifications from core for the document accessible.
*/ class NotificationController final : public EventQueue, public nsARefreshObserver { public:
NotificationController(DocAccessible* aDocument, PresShell* aPresShell);
/** * Shutdown the notification controller.
*/ void Shutdown();
/** * Add an accessible event into the queue to process it later.
*/ void QueueEvent(AccEvent* aEvent) { if (PushEvent(aEvent)) {
ScheduleProcessing();
}
}
/** * Queue a mutation event to emit if not coalesced away. Returns true if the * event was queued and has not yet been coalesced.
*/ bool QueueMutationEvent(AccTreeMutationEvent* aEvent);
/** * Coalesce all queued mutation events.
*/ void CoalesceMutationEvents();
/** * Schedule binding the child document to the tree of this document.
*/ void ScheduleChildDocBinding(DocAccessible* aDocument);
/** * Schedule the accessible tree update because of rendered text changes.
*/ inlinevoid ScheduleTextUpdate(nsIContent* aTextNode) { // Make sure we are not called with a node that is not in the DOM tree or // not visible.
MOZ_ASSERT(aTextNode->GetParentNode(), "A text node is not in DOM");
MOZ_ASSERT(aTextNode->GetPrimaryFrame(), "A text node doesn't have a frame");
MOZ_ASSERT(aTextNode->GetPrimaryFrame()->StyleVisibility()->IsVisible(), "A text node is not visible");
mTextArray.AppendElement(aTextNode);
ScheduleProcessing();
}
/** * Pend accessible tree update for content insertion.
*/ void ScheduleContentInsertion(LocalAccessible* aContainer,
nsTArray<nsCOMPtr<nsIContent>>& aInsertions);
/** * Pend an accessible subtree relocation.
*/ void ScheduleRelocation(LocalAccessible* aOwner) { if (!mRelocations.Contains(aOwner)) { // XXX(Bug 1631371) Check if this should use a fallible operation as it // pretended earlier, or change the return type to void.
mRelocations.AppendElement(aOwner);
ScheduleProcessing();
}
}
/** * Start to observe refresh to make notifications and events processing after * layout.
*/ void ScheduleProcessing();
/** * Process the generic notification synchronously if there are no pending * layout changes and no notifications are pending or being processed right * now. Otherwise, queue it up to process asynchronously. * * @note The caller must guarantee that the given instance still exists when * the notification is processed.
*/ template <classClass, class... Args> inlinevoid HandleNotification( Class* aInstance, typename TNotification<Class, Args...>::Callback aMethod,
Args*... aArgs) { if (!IsUpdatePending()) { #ifdef A11Y_LOG if (mozilla::a11y::logging::IsEnabled(
mozilla::a11y::logging::eNotifications)) {
mozilla::a11y::logging::Text("sync notification processing");
} #endif
(aInstance->*aMethod)(aArgs...); return;
}
RefPtr<Notification> notification = new TNotification<Class, Args...>(aInstance, aMethod, aArgs...); if (notification) { // XXX(Bug 1631371) Check if this should use a fallible operation as it // pretended earlier.
mNotifications.AppendElement(notification);
ScheduleProcessing();
}
}
/** * Schedule the generic notification to process asynchronously. * * @note The caller must guarantee that the given instance still exists when * the notification is processed.
*/ template <classClass> inlinevoid ScheduleNotification( Class* aInstance, typename TNotification<Class>::Callback aMethod) {
RefPtr<Notification> notification = new TNotification<Class>(aInstance, aMethod); if (notification) { // XXX(Bug 1631371) Check if this should use a fallible operation as it // pretended earlier.
mNotifications.AppendElement(notification);
ScheduleProcessing();
}
}
template <classClass, class Arg> inlinevoid ScheduleNotification( Class* aInstance, typename TNotification<Class, Arg>::Callback aMethod,
Arg* aArg) {
RefPtr<Notification> notification = new TNotification<Class, Arg>(aInstance, aMethod, aArg); if (notification) { // XXX(Bug 1631371) Check if this should use a fallible operation as it // pretended earlier.
mNotifications.AppendElement(notification);
ScheduleProcessing();
}
}
private: /** * Remove a specific hide event if it should not be propagated.
*/ void CoalesceHideEvent(AccHideEvent* aHideEvent);
/** * get rid of a mutation event that is no longer necessary.
*/ void DropMutationEvent(AccTreeMutationEvent* aEvent);
/** * For content process documents: * Assess and queue all necessary mutation events. This function queues the * events on DocAccessibleChild. To fire the queued events, call * DocAccessibleChild::SendQueuedMutationEvents. This function may fire * events that must occur before mutation events. * For parent process documents: * Fire all necessary mutation events immediately.
*/ void ProcessMutationEvents();
/** * Indicates whether we're waiting on an event queue processing from our * notification controller to flush events.
*/ enum eObservingState {
eNotObservingRefresh,
eRefreshObserving,
eRefreshProcessing,
eRefreshProcessingForUpdate
};
eObservingState mObservingState;
/** * The presshell of the document accessible.
*/
PresShell* mPresShell;
/** * Child documents that needs to be bound to the tree.
*/
nsTArray<RefPtr<DocAccessible>> mHangingChildDocuments;
/** * Pending accessible tree update notifications for content insertions.
*/
nsClassHashtable<nsRefPtrHashKey<LocalAccessible>,
nsTArray<nsCOMPtr<nsIContent>>>
mContentInsertions;
template <class T> class nsCOMPtrHashKey : public PLDHashEntryHdr { public: typedef T* KeyType; typedefconst T* KeyTypePointer;
/** * Pending accessible tree update notifications for rendered text changes. * When there are a lot of nearby text insertions (e.g. during a reflow), it * is much more performant to process them in order because we then benefit * from the layout line cursor. Therefore, we use an array here.
*/
nsTArray<nsCOMPtr<nsIContent>> mTextArray;
/** * Other notifications like DOM events. Don't make this an AutoTArray; we * use SwapElements() on it.
*/
nsTArray<RefPtr<Notification>> mNotifications;
/** * Holds all scheduled relocations.
*/
nsTArray<RefPtr<LocalAccessible>> mRelocations;
/** * A list of all mutation events we may want to emit. Ordered from the first * event that should be emitted to the last one to emit.
*/
RefPtr<AccTreeMutationEvent> mFirstMutationEvent;
RefPtr<AccTreeMutationEvent> mLastMutationEvent;
/** * A class to map an accessible and event type to an event.
*/ class EventMap { public: enum EventType {
ShowEvent = 0x0,
HideEvent = 0x1,
ReorderEvent = 0x2,
};
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.