2011-01-18 11:03:38 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
2012-05-21 15:12:37 +04:00
|
|
|
/* 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/. */
|
2011-01-18 11:03:38 +03:00
|
|
|
|
2013-01-29 14:00:58 +04:00
|
|
|
#ifndef mozilla_a11y_NotificationController_h_
|
|
|
|
#define mozilla_a11y_NotificationController_h_
|
|
|
|
|
|
|
|
#include "EventQueue.h"
|
2016-04-07 16:30:22 +03:00
|
|
|
#include "EventTree.h"
|
2011-01-18 11:03:38 +03:00
|
|
|
|
2015-09-15 19:01:51 +03:00
|
|
|
#include "mozilla/Tuple.h"
|
2011-01-18 11:03:38 +03:00
|
|
|
#include "nsCycleCollectionParticipant.h"
|
2011-09-14 01:32:07 +04:00
|
|
|
#include "nsRefreshDriver.h"
|
2011-01-18 11:03:38 +03:00
|
|
|
|
2018-04-09 14:12:13 +03:00
|
|
|
#include <utility>
|
|
|
|
|
2012-10-04 13:57:09 +04:00
|
|
|
#ifdef A11Y_LOG
|
2012-06-02 05:58:44 +04:00
|
|
|
# include "Logging.h"
|
|
|
|
#endif
|
|
|
|
|
2012-11-18 06:01:44 +04:00
|
|
|
namespace mozilla {
|
2019-04-13 15:13:15 +03:00
|
|
|
|
|
|
|
class PresShell;
|
|
|
|
|
2012-11-18 06:01:44 +04:00
|
|
|
namespace a11y {
|
|
|
|
|
2012-05-27 13:01:40 +04:00
|
|
|
class DocAccessible;
|
2011-01-18 11:03:38 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Notification interface.
|
|
|
|
*/
|
|
|
|
class Notification {
|
|
|
|
public:
|
2014-08-29 05:03:41 +04:00
|
|
|
NS_INLINE_DECL_REFCOUNTING(mozilla::a11y::Notification)
|
2011-01-18 11:03:38 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Process notification.
|
|
|
|
*/
|
|
|
|
virtual void Process() = 0;
|
|
|
|
|
|
|
|
protected:
|
|
|
|
Notification() {}
|
|
|
|
|
2014-04-02 04:21:24 +04:00
|
|
|
/**
|
|
|
|
* Protected destructor, to discourage deletion outside of Release():
|
|
|
|
*/
|
|
|
|
virtual ~Notification() {}
|
|
|
|
|
2011-01-18 11:03:38 +03:00
|
|
|
private:
|
|
|
|
Notification(const Notification&);
|
|
|
|
Notification& operator=(const Notification&);
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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.
|
|
|
|
*/
|
2015-09-15 19:01:51 +03:00
|
|
|
template <class Class, class... Args>
|
2011-01-18 11:03:38 +03:00
|
|
|
class TNotification : public Notification {
|
|
|
|
public:
|
2015-09-15 19:01:51 +03:00
|
|
|
typedef void (Class::*Callback)(Args*...);
|
2018-11-30 13:46:48 +03:00
|
|
|
|
2015-09-15 19:01:51 +03:00
|
|
|
TNotification(Class* aInstance, Callback aCallback, Args*... aArgs)
|
|
|
|
: mInstance(aInstance), mCallback(aCallback), mArgs(aArgs...) {}
|
2012-07-30 18:20:58 +04:00
|
|
|
virtual ~TNotification() { mInstance = nullptr; }
|
2011-01-18 11:03:38 +03:00
|
|
|
|
2015-03-21 19:28:04 +03:00
|
|
|
virtual void Process() override {
|
2018-04-09 14:12:13 +03:00
|
|
|
ProcessHelper(std::index_sequence_for<Args...>{});
|
|
|
|
}
|
2011-01-18 11:03:38 +03:00
|
|
|
|
|
|
|
private:
|
|
|
|
TNotification(const TNotification&);
|
|
|
|
TNotification& operator=(const TNotification&);
|
|
|
|
|
2015-09-15 19:01:51 +03:00
|
|
|
template <size_t... Indices>
|
2018-04-09 14:12:13 +03:00
|
|
|
void ProcessHelper(std::index_sequence<Indices...>) {
|
2015-09-15 19:01:51 +03:00
|
|
|
(mInstance->*mCallback)(Get<Indices>(mArgs)...);
|
|
|
|
}
|
|
|
|
|
2011-01-18 11:03:38 +03:00
|
|
|
Class* mInstance;
|
|
|
|
Callback mCallback;
|
2015-10-18 08:24:48 +03:00
|
|
|
Tuple<RefPtr<Args>...> mArgs;
|
2011-01-18 11:03:38 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Used to process notifications from core for the document accessible.
|
|
|
|
*/
|
2015-03-21 19:28:04 +03:00
|
|
|
class NotificationController final : public EventQueue,
|
2015-03-27 21:52:19 +03:00
|
|
|
public nsARefreshObserver {
|
2011-01-18 11:03:38 +03:00
|
|
|
public:
|
2019-04-13 15:13:15 +03:00
|
|
|
NotificationController(DocAccessible* aDocument, PresShell* aPresShell);
|
2011-01-18 11:03:38 +03:00
|
|
|
|
2015-03-21 19:28:04 +03:00
|
|
|
NS_IMETHOD_(MozExternalRefCountType) AddRef(void) override;
|
|
|
|
NS_IMETHOD_(MozExternalRefCountType) Release(void) override;
|
2011-01-18 11:03:38 +03:00
|
|
|
|
|
|
|
NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(NotificationController)
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Shutdown the notification controller.
|
|
|
|
*/
|
|
|
|
void Shutdown();
|
|
|
|
|
|
|
|
/**
|
2016-04-07 16:30:22 +03:00
|
|
|
* Add an accessible event into the queue to process it later.
|
2011-01-18 11:03:38 +03:00
|
|
|
*/
|
2013-01-29 14:00:58 +04:00
|
|
|
void QueueEvent(AccEvent* aEvent) {
|
2016-04-07 16:30:22 +03:00
|
|
|
if (PushEvent(aEvent)) {
|
2013-01-29 14:00:58 +04:00
|
|
|
ScheduleProcessing();
|
2016-04-07 16:30:22 +03:00
|
|
|
}
|
2013-01-29 14:00:58 +04:00
|
|
|
}
|
2011-01-18 11:03:38 +03:00
|
|
|
|
2016-04-07 16:30:22 +03:00
|
|
|
/**
|
|
|
|
* Creates and adds a name change event into the queue for a container of
|
|
|
|
* the given accessible, if the accessible is a part of name computation of
|
|
|
|
* the container.
|
|
|
|
*/
|
|
|
|
void QueueNameChange(Accessible* aChangeTarget) {
|
|
|
|
if (PushNameChange(aChangeTarget)) {
|
|
|
|
ScheduleProcessing();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns existing event tree for the given the accessible or creates one if
|
|
|
|
* it doesn't exists yet.
|
|
|
|
*/
|
|
|
|
EventTree* QueueMutation(Accessible* aContainer);
|
|
|
|
|
2016-09-29 22:44:18 +03:00
|
|
|
class MoveGuard final {
|
|
|
|
public:
|
|
|
|
explicit MoveGuard(NotificationController* aController)
|
|
|
|
: mController(aController) {
|
|
|
|
#ifdef DEBUG
|
|
|
|
MOZ_ASSERT(!mController->mMoveGuardOnStack,
|
|
|
|
"Move guard is on stack already!");
|
|
|
|
mController->mMoveGuardOnStack = true;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
~MoveGuard() {
|
|
|
|
#ifdef DEBUG
|
|
|
|
MOZ_ASSERT(mController->mMoveGuardOnStack, "No move guard on stack!");
|
|
|
|
mController->mMoveGuardOnStack = false;
|
|
|
|
#endif
|
|
|
|
mController->mPrecedingEvents.Clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
NotificationController* mController;
|
|
|
|
};
|
|
|
|
|
2016-04-07 16:30:22 +03:00
|
|
|
#ifdef A11Y_LOG
|
|
|
|
const EventTree& RootEventTree() const { return mEventTree; };
|
|
|
|
#endif
|
|
|
|
|
2016-11-11 06:12:32 +03:00
|
|
|
/**
|
|
|
|
* 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();
|
|
|
|
|
2011-01-26 09:35:51 +03:00
|
|
|
/**
|
|
|
|
* Schedule binding the child document to the tree of this document.
|
|
|
|
*/
|
2012-05-27 13:01:40 +04:00
|
|
|
void ScheduleChildDocBinding(DocAccessible* aDocument);
|
2011-01-26 09:35:51 +03:00
|
|
|
|
2011-01-28 11:42:22 +03:00
|
|
|
/**
|
|
|
|
* Schedule the accessible tree update because of rendered text changes.
|
|
|
|
*/
|
|
|
|
inline void ScheduleTextUpdate(nsIContent* aTextNode) {
|
2016-02-02 01:05:45 +03:00
|
|
|
// 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");
|
|
|
|
|
|
|
|
mTextHash.PutEntry(aTextNode);
|
|
|
|
ScheduleProcessing();
|
2011-01-28 11:42:22 +03:00
|
|
|
}
|
|
|
|
|
2011-01-18 11:03:38 +03:00
|
|
|
/**
|
|
|
|
* Pend accessible tree update for content insertion.
|
|
|
|
*/
|
2018-10-18 11:02:51 +03:00
|
|
|
void ScheduleContentInsertion(nsIContent* aStartChildNode,
|
2011-01-18 11:03:38 +03:00
|
|
|
nsIContent* aEndChildNode);
|
|
|
|
|
2015-10-30 01:08:48 +03:00
|
|
|
/**
|
|
|
|
* Pend an accessible subtree relocation.
|
|
|
|
*/
|
|
|
|
void ScheduleRelocation(Accessible* aOwner) {
|
|
|
|
if (!mRelocations.Contains(aOwner) && mRelocations.AppendElement(aOwner)) {
|
|
|
|
ScheduleProcessing();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-09-15 19:01:51 +03:00
|
|
|
/**
|
|
|
|
* Start to observe refresh to make notifications and events processing after
|
|
|
|
* layout.
|
|
|
|
*/
|
|
|
|
void ScheduleProcessing();
|
|
|
|
|
2011-01-18 11:03:38 +03:00
|
|
|
/**
|
|
|
|
* 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.
|
|
|
|
*/
|
2019-03-25 08:04:36 +03:00
|
|
|
template <class Class, class... Args>
|
2011-01-18 11:03:38 +03:00
|
|
|
inline void HandleNotification(
|
2019-03-25 08:04:36 +03:00
|
|
|
Class* aInstance,
|
|
|
|
typename TNotification<Class, Args...>::Callback aMethod,
|
|
|
|
Args*... aArgs) {
|
2011-01-18 11:03:38 +03:00
|
|
|
if (!IsUpdatePending()) {
|
2012-10-04 13:57:09 +04:00
|
|
|
#ifdef A11Y_LOG
|
2012-06-02 05:58:44 +04:00
|
|
|
if (mozilla::a11y::logging::IsEnabled(
|
|
|
|
mozilla::a11y::logging::eNotifications))
|
|
|
|
mozilla::a11y::logging::Text("sync notification processing");
|
2011-01-18 11:03:38 +03:00
|
|
|
#endif
|
2019-03-25 08:04:36 +03:00
|
|
|
(aInstance->*aMethod)(aArgs...);
|
2011-01-18 11:03:38 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<Notification> notification =
|
2019-03-25 08:04:36 +03:00
|
|
|
new TNotification<Class, Args...>(aInstance, aMethod, aArgs...);
|
2011-01-18 11:03:38 +03:00
|
|
|
if (notification && mNotifications.AppendElement(notification))
|
|
|
|
ScheduleProcessing();
|
|
|
|
}
|
|
|
|
|
2011-02-01 06:00:06 +03:00
|
|
|
/**
|
|
|
|
* Schedule the generic notification to process asynchronously.
|
|
|
|
*
|
|
|
|
* @note The caller must guarantee that the given instance still exists when
|
|
|
|
* the notification is processed.
|
|
|
|
*/
|
2015-09-15 19:01:51 +03:00
|
|
|
template <class Class>
|
2011-02-01 06:00:06 +03:00
|
|
|
inline void ScheduleNotification(
|
2015-09-15 19:01:51 +03:00
|
|
|
Class* aInstance, typename TNotification<Class>::Callback aMethod) {
|
2015-10-18 08:24:48 +03:00
|
|
|
RefPtr<Notification> notification =
|
2015-09-15 19:01:51 +03:00
|
|
|
new TNotification<Class>(aInstance, aMethod);
|
2011-02-01 06:00:06 +03:00
|
|
|
if (notification && mNotifications.AppendElement(notification))
|
|
|
|
ScheduleProcessing();
|
|
|
|
}
|
|
|
|
|
2018-06-08 17:55:08 +03:00
|
|
|
template <class Class, class Arg>
|
|
|
|
inline void ScheduleNotification(
|
|
|
|
Class* aInstance, typename TNotification<Class, Arg>::Callback aMethod,
|
|
|
|
Arg* aArg) {
|
|
|
|
RefPtr<Notification> notification =
|
|
|
|
new TNotification<Class, Arg>(aInstance, aMethod, aArg);
|
|
|
|
if (notification && mNotifications.AppendElement(notification)) {
|
|
|
|
ScheduleProcessing();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-10-06 06:10:30 +04:00
|
|
|
#ifdef DEBUG
|
|
|
|
bool IsUpdating() const {
|
|
|
|
return mObservingState == eRefreshProcessingForUpdate;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2011-01-18 11:03:38 +03:00
|
|
|
protected:
|
2014-06-23 23:56:09 +04:00
|
|
|
virtual ~NotificationController();
|
|
|
|
|
2012-08-24 20:50:06 +04:00
|
|
|
nsCycleCollectingAutoRefCnt mRefCnt;
|
2011-01-18 11:03:38 +03:00
|
|
|
NS_DECL_OWNINGTHREAD
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return true if the accessible tree state update is pending.
|
|
|
|
*/
|
|
|
|
bool IsUpdatePending();
|
|
|
|
|
2017-12-14 12:07:00 +03:00
|
|
|
/**
|
|
|
|
* Return true if we should wait for processing from the parent before we can
|
|
|
|
* process our own queue.
|
|
|
|
*/
|
|
|
|
bool WaitingForParent();
|
|
|
|
|
2011-01-18 11:03:38 +03:00
|
|
|
private:
|
|
|
|
NotificationController(const NotificationController&);
|
|
|
|
NotificationController& operator=(const NotificationController&);
|
|
|
|
|
|
|
|
// nsARefreshObserver
|
2015-03-21 19:28:04 +03:00
|
|
|
virtual void WillRefresh(mozilla::TimeStamp aTime) override;
|
2011-01-18 11:03:38 +03:00
|
|
|
|
2016-09-29 22:44:18 +03:00
|
|
|
/**
|
|
|
|
* Set and returns a hide event, paired with a show event, for the move.
|
|
|
|
*/
|
|
|
|
void WithdrawPrecedingEvents(nsTArray<RefPtr<AccHideEvent>>* aEvs) {
|
|
|
|
if (mPrecedingEvents.Length() > 0) {
|
2018-05-30 22:15:35 +03:00
|
|
|
aEvs->AppendElements(std::move(mPrecedingEvents));
|
2016-09-29 22:44:18 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
void StorePrecedingEvent(AccHideEvent* aEv) {
|
|
|
|
MOZ_ASSERT(mMoveGuardOnStack, "No move guard on stack!");
|
|
|
|
mPrecedingEvents.AppendElement(aEv);
|
|
|
|
}
|
|
|
|
void StorePrecedingEvents(nsTArray<RefPtr<AccHideEvent>>&& aEvs) {
|
|
|
|
MOZ_ASSERT(mMoveGuardOnStack, "No move guard on stack!");
|
|
|
|
mPrecedingEvents.InsertElementsAt(0, aEvs);
|
|
|
|
}
|
|
|
|
|
2011-01-18 11:03:38 +03:00
|
|
|
private:
|
2016-11-11 06:12:32 +03:00
|
|
|
/**
|
|
|
|
* get rid of a mutation event that is no longer necessary.
|
|
|
|
*/
|
|
|
|
void DropMutationEvent(AccTreeMutationEvent* aEvent);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Fire all necessary mutation events.
|
|
|
|
*/
|
|
|
|
void ProcessMutationEvents();
|
|
|
|
|
2011-01-18 11:03:38 +03:00
|
|
|
/**
|
|
|
|
* Indicates whether we're waiting on an event queue processing from our
|
|
|
|
* notification controller to flush events.
|
|
|
|
*/
|
|
|
|
enum eObservingState {
|
|
|
|
eNotObservingRefresh,
|
|
|
|
eRefreshObserving,
|
2013-05-24 22:24:19 +04:00
|
|
|
eRefreshProcessing,
|
2011-01-18 11:03:38 +03:00
|
|
|
eRefreshProcessingForUpdate
|
|
|
|
};
|
|
|
|
eObservingState mObservingState;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The presshell of the document accessible.
|
|
|
|
*/
|
2019-04-13 15:13:15 +03:00
|
|
|
PresShell* mPresShell;
|
2011-01-18 11:03:38 +03:00
|
|
|
|
2011-01-26 09:35:51 +03:00
|
|
|
/**
|
|
|
|
* Child documents that needs to be bound to the tree.
|
|
|
|
*/
|
2015-10-18 08:24:48 +03:00
|
|
|
nsTArray<RefPtr<DocAccessible>> mHangingChildDocuments;
|
2011-01-26 09:35:51 +03:00
|
|
|
|
2011-01-18 11:03:38 +03:00
|
|
|
/**
|
2016-02-18 17:31:42 +03:00
|
|
|
* Pending accessible tree update notifications for content insertions.
|
2011-01-18 11:03:38 +03:00
|
|
|
*/
|
2016-02-18 17:31:42 +03:00
|
|
|
nsClassHashtable<nsRefPtrHashKey<Accessible>, nsTArray<nsCOMPtr<nsIContent>>>
|
|
|
|
mContentInsertions;
|
2011-01-18 11:03:38 +03:00
|
|
|
|
2011-01-31 14:45:33 +03:00
|
|
|
template <class T>
|
|
|
|
class nsCOMPtrHashKey : public PLDHashEntryHdr {
|
|
|
|
public:
|
|
|
|
typedef T* KeyType;
|
|
|
|
typedef const T* KeyTypePointer;
|
|
|
|
|
2014-09-02 20:19:58 +04:00
|
|
|
explicit nsCOMPtrHashKey(const T* aKey) : mKey(const_cast<T*>(aKey)) {}
|
Bug 1415980 - make hash keys movable and not copyable; r=erahm
Everything that goes in a PLDHashtable (and its derivatives, like
nsTHashtable) needs to inherit from PLDHashEntryHdr. But through a lack
of enforcement, copy constructors for these derived classes didn't
explicitly invoke the copy constructor for PLDHashEntryHdr (and the
compiler didn't invoke the copy constructor for us). Instead,
PLDHashTable explicitly copied around the bits that the copy constructor
would have.
The current setup has two problems:
1) Derived classes should be using move construction, not copy
construction, since anything that's shuffling hash table keys/entries
around will be using move construction.
2) Derived classes should take responsibility for transferring bits of
superclass state around, and not rely on something else to handle that.
The second point is not a huge problem for PLDHashTable (PLDHashTable
only has to copy PLDHashEntryHdr's bits in a single place), but future
hash table implementations that might move entries around more
aggressively would have to insert compensation code all over the
place. Additionally, if moving entries is implemented via memcpy (which
is quite common), PLDHashTable copying around bits *again* is
inefficient.
Let's fix all these problems in one go, by:
1) Explicitly declaring the set of constructors that PLDHashEntryHdr
implements (and does not implement). In particular, the copy
constructor is deleted, so any derived classes that attempt to make
themselves copyable will be detected at compile time: the compiler
will complain that the superclass type is not copyable.
This change on its own will result in many compiler errors, so...
2) Change any derived classes to implement move constructors instead of
copy constructors. Note that some of these move constructors are,
strictly speaking, unnecessary, since the relevant classes are moved
via memcpy in nsTHashtable and its derivatives.
2018-09-20 18:20:36 +03:00
|
|
|
nsCOMPtrHashKey(nsCOMPtrHashKey<T>&& aOther)
|
|
|
|
: PLDHashEntryHdr(std::move(aOther)), mKey(std::move(aOther.mKey)) {}
|
2011-01-31 14:45:33 +03:00
|
|
|
~nsCOMPtrHashKey() {}
|
|
|
|
|
|
|
|
KeyType GetKey() const { return mKey; }
|
2011-09-29 10:19:26 +04:00
|
|
|
bool KeyEquals(KeyTypePointer aKey) const { return aKey == mKey; }
|
2011-01-31 14:45:33 +03:00
|
|
|
|
|
|
|
static KeyTypePointer KeyToPointer(KeyType aKey) { return aKey; }
|
|
|
|
static PLDHashNumber HashKey(KeyTypePointer aKey) {
|
|
|
|
return NS_PTR_TO_INT32(aKey) >> 2;
|
|
|
|
}
|
|
|
|
|
2011-10-17 18:59:28 +04:00
|
|
|
enum { ALLOW_MEMMOVE = true };
|
2011-01-31 14:45:33 +03:00
|
|
|
|
|
|
|
protected:
|
|
|
|
nsCOMPtr<T> mKey;
|
|
|
|
};
|
|
|
|
|
2011-01-28 11:42:22 +03:00
|
|
|
/**
|
2016-02-18 17:31:42 +03:00
|
|
|
* Pending accessible tree update notifications for rendered text changes.
|
2011-01-28 11:42:22 +03:00
|
|
|
*/
|
2011-01-31 14:45:33 +03:00
|
|
|
nsTHashtable<nsCOMPtrHashKey<nsIContent>> mTextHash;
|
2011-01-28 11:42:22 +03:00
|
|
|
|
2011-01-18 11:03:38 +03:00
|
|
|
/**
|
2016-02-02 18:36:30 +03:00
|
|
|
* Other notifications like DOM events. Don't make this an AutoTArray; we
|
2011-01-18 11:03:38 +03:00
|
|
|
* use SwapElements() on it.
|
|
|
|
*/
|
2015-10-18 08:24:48 +03:00
|
|
|
nsTArray<RefPtr<Notification>> mNotifications;
|
2015-10-30 01:08:48 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Holds all scheduled relocations.
|
|
|
|
*/
|
|
|
|
nsTArray<RefPtr<Accessible>> mRelocations;
|
2016-04-07 16:30:22 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Holds all mutation events.
|
|
|
|
*/
|
|
|
|
EventTree mEventTree;
|
2016-09-29 22:44:18 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* A temporary collection of hide events that should be fired before related
|
|
|
|
* show event. Used by EventTree.
|
|
|
|
*/
|
|
|
|
nsTArray<RefPtr<AccHideEvent>> mPrecedingEvents;
|
|
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
bool mMoveGuardOnStack;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
friend class MoveGuard;
|
|
|
|
friend class EventTree;
|
2016-11-11 01:05:02 +03:00
|
|
|
|
2016-11-11 06:12:32 +03:00
|
|
|
/**
|
|
|
|
* 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;
|
|
|
|
|
2016-11-11 01:05:02 +03:00
|
|
|
/**
|
|
|
|
* A class to map an accessible and event type to an event.
|
|
|
|
*/
|
|
|
|
class EventMap {
|
|
|
|
public:
|
|
|
|
enum EventType {
|
|
|
|
ShowEvent = 0x0,
|
|
|
|
HideEvent = 0x1,
|
|
|
|
ReorderEvent = 0x2,
|
|
|
|
};
|
|
|
|
|
|
|
|
void PutEvent(AccTreeMutationEvent* aEvent);
|
|
|
|
AccTreeMutationEvent* GetEvent(Accessible* aTarget, EventType aType);
|
|
|
|
void RemoveEvent(AccTreeMutationEvent* aEvent);
|
|
|
|
void Clear() { mTable.Clear(); }
|
|
|
|
|
|
|
|
private:
|
|
|
|
EventType GetEventType(AccTreeMutationEvent* aEvent);
|
|
|
|
|
|
|
|
nsRefPtrHashtable<nsUint64HashKey, AccTreeMutationEvent> mTable;
|
|
|
|
};
|
|
|
|
|
|
|
|
EventMap mMutationMap;
|
2016-11-11 06:12:32 +03:00
|
|
|
uint32_t mEventGeneration;
|
2011-01-18 11:03:38 +03:00
|
|
|
};
|
|
|
|
|
2012-11-18 06:01:44 +04:00
|
|
|
} // namespace a11y
|
|
|
|
} // namespace mozilla
|
|
|
|
|
2013-01-29 14:00:58 +04:00
|
|
|
#endif // mozilla_a11y_NotificationController_h_
|