зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1794319: Remove a11y::EventTree, as it has been dead code for 6 years. r=eeejay
Differential Revision: https://phabricator.services.mozilla.com/D158918
This commit is contained in:
Родитель
1ae5e445bd
Коммит
45537045d3
|
@ -114,13 +114,6 @@ AccHideEvent::AccHideEvent(LocalAccessible* aTarget, bool aNeedsShutdown)
|
|||
// AccShowEvent
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AccShowEvent::AccShowEvent(LocalAccessible* aTarget)
|
||||
: AccMutationEvent(::nsIAccessibleEvent::EVENT_SHOW, aTarget) {
|
||||
int32_t idx = aTarget->IndexInParent();
|
||||
MOZ_ASSERT(idx >= 0);
|
||||
mInsertionIndex = idx;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// AccTextSelChangeEvent
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -301,21 +301,14 @@ class AccHideEvent : public AccMutationEvent {
|
|||
*/
|
||||
class AccShowEvent : public AccMutationEvent {
|
||||
public:
|
||||
explicit AccShowEvent(LocalAccessible* aTarget);
|
||||
explicit AccShowEvent(LocalAccessible* aTarget)
|
||||
: AccMutationEvent(::nsIAccessibleEvent::EVENT_SHOW, aTarget) {}
|
||||
|
||||
// Event
|
||||
static const EventGroup kEventGroup = eShowEvent;
|
||||
virtual unsigned int GetEventGroups() const override {
|
||||
return AccMutationEvent::GetEventGroups() | (1U << eShowEvent);
|
||||
}
|
||||
|
||||
uint32_t InsertionIndex() const { return mInsertionIndex; }
|
||||
|
||||
private:
|
||||
nsTArray<RefPtr<AccHideEvent>> mPrecedingEvents;
|
||||
uint32_t mInsertionIndex;
|
||||
|
||||
friend class EventTree;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -23,8 +23,6 @@ using namespace mozilla::a11y;
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// TreeMutation class
|
||||
|
||||
EventTree* const TreeMutation::kNoEventTree = reinterpret_cast<EventTree*>(-1);
|
||||
|
||||
TreeMutation::TreeMutation(LocalAccessible* aParent, bool aNoEvents)
|
||||
: mParent(aParent),
|
||||
mStartIdx(UINT32_MAX),
|
||||
|
@ -34,20 +32,6 @@ TreeMutation::TreeMutation(LocalAccessible* aParent, bool aNoEvents)
|
|||
mIsDone = false;
|
||||
#endif
|
||||
|
||||
#ifdef A11Y_LOG
|
||||
if (mQueueEvents && logging::IsEnabled(logging::eEventTree)) {
|
||||
logging::MsgBegin("EVENTS_TREE", "reordering tree before");
|
||||
logging::AccessibleInfo("reordering for", mParent);
|
||||
Controller()->RootEventTree().Log();
|
||||
logging::MsgEnd();
|
||||
|
||||
if (logging::IsEnabled(logging::eVerbose)) {
|
||||
logging::Tree("EVENTS_TREE", "Container tree", mParent->Document(),
|
||||
PrefixLog, static_cast<void*>(this));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
mParent->mStateFlags |= LocalAccessible::eKidsMutating;
|
||||
}
|
||||
|
||||
|
@ -116,487 +100,4 @@ void TreeMutation::Done() {
|
|||
#ifdef DEBUG
|
||||
mIsDone = true;
|
||||
#endif
|
||||
|
||||
#ifdef A11Y_LOG
|
||||
if (mQueueEvents && logging::IsEnabled(logging::eEventTree)) {
|
||||
logging::MsgBegin("EVENTS_TREE", "reordering tree after");
|
||||
logging::AccessibleInfo("reordering for", mParent);
|
||||
Controller()->RootEventTree().Log();
|
||||
logging::MsgEnd();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef A11Y_LOG
|
||||
const char* TreeMutation::PrefixLog(void* aData, LocalAccessible* aAcc) {
|
||||
TreeMutation* thisObj = reinterpret_cast<TreeMutation*>(aData);
|
||||
if (thisObj->mParent == aAcc) {
|
||||
return "_X_";
|
||||
}
|
||||
const EventTree& ret = thisObj->Controller()->RootEventTree();
|
||||
if (ret.Find(aAcc)) {
|
||||
return "_с_";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// EventTree
|
||||
|
||||
void EventTree::Shown(LocalAccessible* aChild) {
|
||||
RefPtr<AccShowEvent> ev = new AccShowEvent(aChild);
|
||||
Controller(aChild)->WithdrawPrecedingEvents(&ev->mPrecedingEvents);
|
||||
Mutated(ev);
|
||||
}
|
||||
|
||||
void EventTree::Hidden(LocalAccessible* aChild, bool aNeedsShutdown) {
|
||||
RefPtr<AccHideEvent> ev = new AccHideEvent(aChild, aNeedsShutdown);
|
||||
if (!aNeedsShutdown) {
|
||||
Controller(aChild)->StorePrecedingEvent(ev);
|
||||
}
|
||||
Mutated(ev);
|
||||
}
|
||||
|
||||
void EventTree::Process(const RefPtr<DocAccessible>& aDeathGrip) {
|
||||
while (mFirst) {
|
||||
// Skip a node and its subtree if its container is not in the document.
|
||||
if (mFirst->mContainer->IsInDocument()) {
|
||||
mFirst->Process(aDeathGrip);
|
||||
if (aDeathGrip->IsDefunct()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
mFirst = std::move(mFirst->mNext);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mContainer || mDependentEvents.IsEmpty(),
|
||||
"No container, no events");
|
||||
MOZ_ASSERT(!mContainer || !mContainer->IsDefunct(),
|
||||
"Processing events for defunct container");
|
||||
MOZ_ASSERT(!mFireReorder || mContainer, "No target for reorder event");
|
||||
|
||||
// Fire mutation events.
|
||||
uint32_t eventsCount = mDependentEvents.Length();
|
||||
for (uint32_t jdx = 0; jdx < eventsCount; jdx++) {
|
||||
AccMutationEvent* mtEvent = mDependentEvents[jdx];
|
||||
MOZ_ASSERT(mtEvent->Document(), "No document for event target");
|
||||
|
||||
// Fire all hide events that has to be fired before this show event.
|
||||
if (mtEvent->IsShow()) {
|
||||
AccShowEvent* showEv = downcast_accEvent(mtEvent);
|
||||
for (uint32_t i = 0; i < showEv->mPrecedingEvents.Length(); i++) {
|
||||
nsEventShell::FireEvent(showEv->mPrecedingEvents[i]);
|
||||
if (aDeathGrip->IsDefunct()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsEventShell::FireEvent(mtEvent);
|
||||
if (aDeathGrip->IsDefunct()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mtEvent->mTextChangeEvent) {
|
||||
nsEventShell::FireEvent(mtEvent->mTextChangeEvent);
|
||||
if (aDeathGrip->IsDefunct()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
if (aDeathGrip->IsDefunct()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
AccHideEvent* hideEvent = downcast_accEvent(mtEvent);
|
||||
if (hideEvent->NeedsShutdown()) {
|
||||
aDeathGrip->ShutdownChildrenInSubtree(mtEvent->mAccessible);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fire reorder event at last.
|
||||
if (mFireReorder) {
|
||||
nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_REORDER, mContainer);
|
||||
mContainer->Document()->MaybeNotifyOfValueChange(mContainer);
|
||||
}
|
||||
|
||||
mDependentEvents.Clear();
|
||||
}
|
||||
|
||||
EventTree* EventTree::FindOrInsert(LocalAccessible* aContainer) {
|
||||
if (!mFirst) {
|
||||
mFirst.reset(new EventTree(aContainer, mDependentEvents.IsEmpty()));
|
||||
return mFirst.get();
|
||||
}
|
||||
|
||||
EventTree* prevNode = nullptr;
|
||||
EventTree* node = mFirst.get();
|
||||
do {
|
||||
MOZ_ASSERT(!node->mContainer->IsApplication(),
|
||||
"No event for application accessible is expected here");
|
||||
MOZ_ASSERT(!node->mContainer->IsDefunct(),
|
||||
"An event target has to be alive");
|
||||
|
||||
// Case of same target.
|
||||
if (node->mContainer == aContainer) {
|
||||
return node;
|
||||
}
|
||||
|
||||
// Check if the given container is contained by a current node
|
||||
LocalAccessible* top = mContainer ? mContainer : aContainer->Document();
|
||||
LocalAccessible* parent = aContainer;
|
||||
while (parent) {
|
||||
// Reached a top, no match for a current event.
|
||||
if (parent == top) {
|
||||
break;
|
||||
}
|
||||
|
||||
// We got a match.
|
||||
if (parent->LocalParent() == node->mContainer) {
|
||||
// Reject the node if it's contained by a show/hide event target
|
||||
uint32_t evCount = node->mDependentEvents.Length();
|
||||
for (uint32_t idx = 0; idx < evCount; idx++) {
|
||||
AccMutationEvent* ev = node->mDependentEvents[idx];
|
||||
if (ev->GetAccessible() == parent) {
|
||||
#ifdef A11Y_LOG
|
||||
if (logging::IsEnabled(logging::eEventTree)) {
|
||||
logging::MsgBegin("EVENTS_TREE",
|
||||
"Rejecting node contained by show/hide");
|
||||
logging::AccessibleInfo("Node", aContainer);
|
||||
logging::MsgEnd();
|
||||
}
|
||||
#endif
|
||||
// If the node is rejected, then check if it has related hide event
|
||||
// on stack, and if so, then connect it to the parent show event.
|
||||
if (ev->IsShow()) {
|
||||
AccShowEvent* showEv = downcast_accEvent(ev);
|
||||
Controller(aContainer)
|
||||
->WithdrawPrecedingEvents(&showEv->mPrecedingEvents);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return node->FindOrInsert(aContainer);
|
||||
}
|
||||
|
||||
parent = parent->LocalParent();
|
||||
MOZ_ASSERT(parent, "Wrong tree");
|
||||
}
|
||||
|
||||
// If the given container contains a current node
|
||||
// then
|
||||
// if show or hide of the given node contains a grand parent of the
|
||||
// current node then ignore the current node and its show and hide events
|
||||
// otherwise ignore the current node, but not its show and hide events
|
||||
LocalAccessible* curParent = node->mContainer;
|
||||
while (curParent && !curParent->IsDoc()) {
|
||||
if (curParent->LocalParent() != aContainer) {
|
||||
curParent = curParent->LocalParent();
|
||||
continue;
|
||||
}
|
||||
|
||||
// Insert the tail node into the hierarchy between the current node and
|
||||
// its parent.
|
||||
node->mFireReorder = false;
|
||||
UniquePtr<EventTree>& nodeOwnerRef = prevNode ? prevNode->mNext : mFirst;
|
||||
UniquePtr<EventTree> newNode(
|
||||
new EventTree(aContainer, mDependentEvents.IsEmpty()));
|
||||
newNode->mFirst = std::move(nodeOwnerRef);
|
||||
nodeOwnerRef = std::move(newNode);
|
||||
nodeOwnerRef->mNext = std::move(node->mNext);
|
||||
|
||||
// Check if a next node is contained by the given node too, and move them
|
||||
// under the given node if so.
|
||||
prevNode = nodeOwnerRef.get();
|
||||
node = nodeOwnerRef->mNext.get();
|
||||
UniquePtr<EventTree>* nodeRef = &nodeOwnerRef->mNext;
|
||||
EventTree* insNode = nodeOwnerRef->mFirst.get();
|
||||
while (node) {
|
||||
LocalAccessible* curParent = node->mContainer;
|
||||
while (curParent && !curParent->IsDoc()) {
|
||||
if (curParent->LocalParent() != aContainer) {
|
||||
curParent = curParent->LocalParent();
|
||||
continue;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!insNode->mNext);
|
||||
|
||||
node->mFireReorder = false;
|
||||
insNode->mNext = std::move(*nodeRef);
|
||||
insNode = insNode->mNext.get();
|
||||
|
||||
prevNode->mNext = std::move(node->mNext);
|
||||
node = prevNode;
|
||||
break;
|
||||
}
|
||||
|
||||
prevNode = node;
|
||||
nodeRef = &node->mNext;
|
||||
node = node->mNext.get();
|
||||
}
|
||||
|
||||
return nodeOwnerRef.get();
|
||||
}
|
||||
|
||||
prevNode = node;
|
||||
} while ((node = node->mNext.get()));
|
||||
|
||||
MOZ_ASSERT(prevNode, "Nowhere to insert");
|
||||
MOZ_ASSERT(!prevNode->mNext, "Taken by another node");
|
||||
|
||||
// If 'this' node contains the given container accessible, then
|
||||
// do not emit a reorder event for the container
|
||||
// if a dependent show event target contains the given container then do not
|
||||
// emit show / hide events (see Process() method)
|
||||
|
||||
prevNode->mNext.reset(new EventTree(aContainer, mDependentEvents.IsEmpty()));
|
||||
return prevNode->mNext.get();
|
||||
}
|
||||
|
||||
void EventTree::Clear() {
|
||||
mFirst = nullptr;
|
||||
mNext = nullptr;
|
||||
mContainer = nullptr;
|
||||
|
||||
uint32_t eventsCount = mDependentEvents.Length();
|
||||
for (uint32_t jdx = 0; jdx < eventsCount; jdx++) {
|
||||
mDependentEvents[jdx]->mEventType = AccEvent::eDoNotEmit;
|
||||
AccHideEvent* ev = downcast_accEvent(mDependentEvents[jdx]);
|
||||
if (ev && ev->NeedsShutdown()) {
|
||||
ev->Document()->ShutdownChildrenInSubtree(ev->mAccessible);
|
||||
}
|
||||
}
|
||||
mDependentEvents.Clear();
|
||||
}
|
||||
|
||||
const EventTree* EventTree::Find(const LocalAccessible* aContainer) const {
|
||||
const EventTree* et = this;
|
||||
while (et) {
|
||||
if (et->mContainer == aContainer) {
|
||||
return et;
|
||||
}
|
||||
|
||||
if (et->mFirst) {
|
||||
et = et->mFirst.get();
|
||||
const EventTree* cet = et->Find(aContainer);
|
||||
if (cet) {
|
||||
return cet;
|
||||
}
|
||||
}
|
||||
|
||||
et = et->mNext.get();
|
||||
const EventTree* cet = et->Find(aContainer);
|
||||
if (cet) {
|
||||
return cet;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#ifdef A11Y_LOG
|
||||
void EventTree::Log(uint32_t aLevel) const {
|
||||
if (aLevel == UINT32_MAX) {
|
||||
if (mFirst) {
|
||||
mFirst->Log(0);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < aLevel; i++) {
|
||||
printf(" ");
|
||||
}
|
||||
logging::AccessibleInfo("container", mContainer);
|
||||
|
||||
for (uint32_t i = 0; i < mDependentEvents.Length(); i++) {
|
||||
AccMutationEvent* ev = mDependentEvents[i];
|
||||
if (ev->IsShow()) {
|
||||
for (uint32_t i = 0; i < aLevel + 1; i++) {
|
||||
printf(" ");
|
||||
}
|
||||
logging::AccessibleInfo("shown", ev->mAccessible);
|
||||
|
||||
AccShowEvent* showEv = downcast_accEvent(ev);
|
||||
for (uint32_t i = 0; i < showEv->mPrecedingEvents.Length(); i++) {
|
||||
for (uint32_t j = 0; j < aLevel + 1; j++) {
|
||||
printf(" ");
|
||||
}
|
||||
logging::AccessibleInfo("preceding",
|
||||
showEv->mPrecedingEvents[i]->mAccessible);
|
||||
}
|
||||
} else {
|
||||
for (uint32_t i = 0; i < aLevel + 1; i++) {
|
||||
printf(" ");
|
||||
}
|
||||
logging::AccessibleInfo("hidden", ev->mAccessible);
|
||||
}
|
||||
}
|
||||
|
||||
if (mFirst) {
|
||||
mFirst->Log(aLevel + 1);
|
||||
}
|
||||
|
||||
if (mNext) {
|
||||
mNext->Log(aLevel);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void EventTree::Mutated(AccMutationEvent* aEv) {
|
||||
// If shown or hidden node is a root of previously mutated subtree, then
|
||||
// discard those subtree mutations as we are no longer interested in them.
|
||||
UniquePtr<EventTree>* node = &mFirst;
|
||||
while (*node) {
|
||||
LocalAccessible* cntr = (*node)->mContainer;
|
||||
while (cntr != mContainer) {
|
||||
if (cntr == aEv->mAccessible) {
|
||||
#ifdef A11Y_LOG
|
||||
if (logging::IsEnabled(logging::eEventTree)) {
|
||||
logging::MsgBegin("EVENTS_TREE", "Trim subtree");
|
||||
logging::AccessibleInfo("Show/hide container", aEv->mAccessible);
|
||||
logging::AccessibleInfo("Trimmed subtree root", (*node)->mContainer);
|
||||
logging::MsgEnd();
|
||||
}
|
||||
#endif
|
||||
|
||||
// If the new hide is part of a move and it contains existing child
|
||||
// shows, then move preceding events from the child shows to the buffer,
|
||||
// so the ongoing show event will pick them up.
|
||||
if (aEv->IsHide()) {
|
||||
AccHideEvent* hideEv = downcast_accEvent(aEv);
|
||||
if (!hideEv->mNeedsShutdown) {
|
||||
for (uint32_t i = 0; i < (*node)->mDependentEvents.Length(); i++) {
|
||||
AccMutationEvent* childEv = (*node)->mDependentEvents[i];
|
||||
if (childEv->IsShow()) {
|
||||
AccShowEvent* childShowEv = downcast_accEvent(childEv);
|
||||
if (childShowEv->mPrecedingEvents.Length() > 0) {
|
||||
Controller(mContainer)
|
||||
->StorePrecedingEvents(
|
||||
std::move(childShowEv->mPrecedingEvents));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// If the new show contains existing child shows, then move preceding
|
||||
// events from the child shows to the new show.
|
||||
else if (aEv->IsShow()) {
|
||||
AccShowEvent* showEv = downcast_accEvent(aEv);
|
||||
for (uint32_t i = 0; (*node)->mDependentEvents.Length(); i++) {
|
||||
AccMutationEvent* childEv = (*node)->mDependentEvents[i];
|
||||
if (childEv->IsShow()) {
|
||||
AccShowEvent* showChildEv = downcast_accEvent(childEv);
|
||||
if (showChildEv->mPrecedingEvents.Length() > 0) {
|
||||
#ifdef A11Y_LOG
|
||||
if (logging::IsEnabled(logging::eEventTree)) {
|
||||
logging::MsgBegin("EVENTS_TREE", "Adopt preceding events");
|
||||
logging::AccessibleInfo("Parent", aEv->mAccessible);
|
||||
for (uint32_t j = 0;
|
||||
j < showChildEv->mPrecedingEvents.Length(); j++) {
|
||||
logging::AccessibleInfo(
|
||||
"Adoptee",
|
||||
showChildEv->mPrecedingEvents[i]->mAccessible);
|
||||
}
|
||||
logging::MsgEnd();
|
||||
}
|
||||
#endif
|
||||
showEv->mPrecedingEvents.AppendElements(
|
||||
showChildEv->mPrecedingEvents);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*node = std::move((*node)->mNext);
|
||||
break;
|
||||
}
|
||||
cntr = cntr->LocalParent();
|
||||
}
|
||||
if (cntr == aEv->mAccessible) {
|
||||
continue;
|
||||
}
|
||||
node = &(*node)->mNext;
|
||||
}
|
||||
|
||||
AccMutationEvent* prevEvent = mDependentEvents.SafeLastElement(nullptr);
|
||||
mDependentEvents.AppendElement(aEv);
|
||||
|
||||
// Coalesce text change events from this hide/show event and the previous one.
|
||||
if (prevEvent && aEv->mEventType == prevEvent->mEventType) {
|
||||
if (aEv->IsHide()) {
|
||||
// XXX: we need a way to ignore SplitNode and JoinNode() when they do not
|
||||
// affect the text within the hypertext.
|
||||
AccTextChangeEvent* prevTextEvent = prevEvent->mTextChangeEvent;
|
||||
if (prevTextEvent) {
|
||||
AccHideEvent* hideEvent = downcast_accEvent(aEv);
|
||||
AccHideEvent* prevHideEvent = downcast_accEvent(prevEvent);
|
||||
|
||||
if (prevHideEvent->mNextSibling == hideEvent->mAccessible) {
|
||||
hideEvent->mAccessible->AppendTextTo(prevTextEvent->mModifiedText);
|
||||
} else if (prevHideEvent->mPrevSibling == hideEvent->mAccessible) {
|
||||
uint32_t oldLen = prevTextEvent->GetLength();
|
||||
hideEvent->mAccessible->AppendTextTo(prevTextEvent->mModifiedText);
|
||||
prevTextEvent->mStart -= prevTextEvent->GetLength() - oldLen;
|
||||
}
|
||||
|
||||
hideEvent->mTextChangeEvent.swap(prevEvent->mTextChangeEvent);
|
||||
}
|
||||
} else {
|
||||
AccTextChangeEvent* prevTextEvent = prevEvent->mTextChangeEvent;
|
||||
if (prevTextEvent) {
|
||||
if (aEv->mAccessible->IndexInParent() ==
|
||||
prevEvent->mAccessible->IndexInParent() + 1) {
|
||||
// If tail target was inserted after this target, i.e. tail target is
|
||||
// next sibling of this target.
|
||||
aEv->mAccessible->AppendTextTo(prevTextEvent->mModifiedText);
|
||||
} else if (aEv->mAccessible->IndexInParent() ==
|
||||
prevEvent->mAccessible->IndexInParent() - 1) {
|
||||
// If tail target was inserted before this target, i.e. tail target is
|
||||
// previous sibling of this target.
|
||||
nsAutoString startText;
|
||||
aEv->mAccessible->AppendTextTo(startText);
|
||||
prevTextEvent->mModifiedText =
|
||||
startText + prevTextEvent->mModifiedText;
|
||||
prevTextEvent->mStart -= startText.Length();
|
||||
}
|
||||
|
||||
aEv->mTextChangeEvent.swap(prevEvent->mTextChangeEvent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create a text change event caused by this hide/show event. When a node is
|
||||
// hidden/removed or shown/appended, the text in an ancestor hyper text will
|
||||
// lose or get new characters.
|
||||
if (aEv->mTextChangeEvent || !mContainer->IsHyperText()) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsAutoString text;
|
||||
aEv->mAccessible->AppendTextTo(text);
|
||||
if (text.IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t offset = mContainer->AsHyperText()->GetChildOffset(aEv->mAccessible);
|
||||
aEv->mTextChangeEvent = new AccTextChangeEvent(
|
||||
mContainer, offset, text, aEv->IsShow(),
|
||||
aEv->mIsFromUserInput ? eFromUserInput : eNoUserInput);
|
||||
}
|
||||
|
|
|
@ -41,12 +41,6 @@ class TreeMutation final {
|
|||
return mParent->Document()->Controller();
|
||||
}
|
||||
|
||||
static EventTree* const kNoEventTree;
|
||||
|
||||
#ifdef A11Y_LOG
|
||||
static const char* PrefixLog(void* aData, LocalAccessible*);
|
||||
#endif
|
||||
|
||||
LocalAccessible* mParent;
|
||||
uint32_t mStartIdx;
|
||||
uint32_t mStateFlagsCopy;
|
||||
|
@ -61,67 +55,6 @@ class TreeMutation final {
|
|||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* A mutation events coalescence structure.
|
||||
*/
|
||||
class EventTree final {
|
||||
public:
|
||||
EventTree()
|
||||
: mFirst(nullptr),
|
||||
mNext(nullptr),
|
||||
mContainer(nullptr),
|
||||
mFireReorder(false) {}
|
||||
explicit EventTree(LocalAccessible* aContainer, bool aFireReorder)
|
||||
: mFirst(nullptr),
|
||||
mNext(nullptr),
|
||||
mContainer(aContainer),
|
||||
mFireReorder(aFireReorder) {}
|
||||
~EventTree() { Clear(); }
|
||||
|
||||
void Shown(LocalAccessible* aTarget);
|
||||
void Hidden(LocalAccessible*, bool);
|
||||
|
||||
/**
|
||||
* Return an event tree node for the given accessible.
|
||||
*/
|
||||
const EventTree* Find(const LocalAccessible* aContainer) const;
|
||||
|
||||
/**
|
||||
* Add a mutation event to this event tree.
|
||||
*/
|
||||
void Mutated(AccMutationEvent* aEv);
|
||||
|
||||
#ifdef A11Y_LOG
|
||||
void Log(uint32_t aLevel = UINT32_MAX) const;
|
||||
#endif
|
||||
|
||||
private:
|
||||
/**
|
||||
* Processes the event queue and fires events.
|
||||
*/
|
||||
void Process(const RefPtr<DocAccessible>& aDeathGrip);
|
||||
|
||||
/**
|
||||
* Return an event subtree for the given accessible.
|
||||
*/
|
||||
EventTree* FindOrInsert(LocalAccessible* aContainer);
|
||||
|
||||
void Clear();
|
||||
|
||||
UniquePtr<EventTree> mFirst;
|
||||
UniquePtr<EventTree> mNext;
|
||||
|
||||
LocalAccessible* mContainer;
|
||||
nsTArray<RefPtr<AccMutationEvent>> mDependentEvents;
|
||||
bool mFireReorder;
|
||||
|
||||
static NotificationController* Controller(LocalAccessible* aAcc) {
|
||||
return aAcc->Document()->Controller();
|
||||
}
|
||||
|
||||
friend class NotificationController;
|
||||
};
|
||||
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
|
|
|
@ -53,7 +53,6 @@ static ModuleRep sModuleMap[] = {{"docload", logging::eDocLoad},
|
|||
{"doclifecycle", logging::eDocLifeCycle},
|
||||
|
||||
{"events", logging::eEvents},
|
||||
{"eventTree", logging::eEventTree},
|
||||
{"platforms", logging::ePlatforms},
|
||||
{"text", logging::eText},
|
||||
{"tree", logging::eTree},
|
||||
|
|
|
@ -39,21 +39,20 @@ enum EModules {
|
|||
eDocLifeCycle = eDocLoad | eDocCreate | eDocDestroy,
|
||||
|
||||
eEvents = 1 << 3,
|
||||
eEventTree = 1 << 4,
|
||||
ePlatforms = 1 << 5,
|
||||
eText = 1 << 6,
|
||||
eTree = 1 << 7,
|
||||
eTreeSize = 1 << 8,
|
||||
ePlatforms = 1 << 4,
|
||||
eText = 1 << 5,
|
||||
eTree = 1 << 6,
|
||||
eTreeSize = 1 << 7,
|
||||
|
||||
eDOMEvents = 1 << 9,
|
||||
eFocus = 1 << 10,
|
||||
eSelection = 1 << 11,
|
||||
eDOMEvents = 1 << 8,
|
||||
eFocus = 1 << 9,
|
||||
eSelection = 1 << 10,
|
||||
eNotifications = eDOMEvents | eSelection | eFocus,
|
||||
|
||||
// extras
|
||||
eStack = 1 << 12,
|
||||
eVerbose = 1 << 13,
|
||||
eCache = 1 << 14,
|
||||
eStack = 1 << 11,
|
||||
eVerbose = 1 << 12,
|
||||
eCache = 1 << 13,
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -35,10 +35,6 @@ NotificationController::NotificationController(DocAccessible* aDocument,
|
|||
mObservingState(eNotObservingRefresh),
|
||||
mPresShell(aPresShell),
|
||||
mEventGeneration(0) {
|
||||
#ifdef DEBUG
|
||||
mMoveGuardOnStack = false;
|
||||
#endif
|
||||
|
||||
// Schedule initial accessible tree construction.
|
||||
ScheduleProcessing();
|
||||
}
|
||||
|
@ -107,15 +103,6 @@ void NotificationController::Shutdown() {
|
|||
mFocusEvent = nullptr;
|
||||
mEvents.Clear();
|
||||
mRelocations.Clear();
|
||||
mEventTree.Clear();
|
||||
}
|
||||
|
||||
EventTree* NotificationController::QueueMutation(LocalAccessible* aContainer) {
|
||||
EventTree* tree = mEventTree.FindOrInsert(aContainer);
|
||||
if (tree) {
|
||||
ScheduleProcessing();
|
||||
}
|
||||
return tree;
|
||||
}
|
||||
|
||||
void NotificationController::CoalesceHideEvent(AccHideEvent* aHideEvent) {
|
||||
|
|
|
@ -7,10 +7,11 @@
|
|||
#define mozilla_a11y_NotificationController_h_
|
||||
|
||||
#include "EventQueue.h"
|
||||
#include "EventTree.h"
|
||||
|
||||
#include "mozilla/Tuple.h"
|
||||
#include "nsClassHashtable.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsRefreshObservers.h"
|
||||
#include "nsTHashSet.h"
|
||||
|
||||
|
@ -114,38 +115,6 @@ class NotificationController final : public EventQueue,
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns existing event tree for the given the accessible or creates one if
|
||||
* it doesn't exists yet.
|
||||
*/
|
||||
EventTree* QueueMutation(LocalAccessible* aContainer);
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
#ifdef A11Y_LOG
|
||||
const EventTree& RootEventTree() const { return mEventTree; };
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Queue a mutation event to emit if not coalesced away. Returns true if the
|
||||
* event was queued and has not yet been coalesced.
|
||||
|
@ -300,23 +269,6 @@ class NotificationController final : public EventQueue,
|
|||
// nsARefreshObserver
|
||||
virtual void WillRefresh(mozilla::TimeStamp aTime) override;
|
||||
|
||||
/**
|
||||
* Set and returns a hide event, paired with a show event, for the move.
|
||||
*/
|
||||
void WithdrawPrecedingEvents(nsTArray<RefPtr<AccHideEvent>>* aEvs) {
|
||||
if (mPrecedingEvents.Length() > 0) {
|
||||
aEvs->AppendElements(std::move(mPrecedingEvents));
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
* Remove a specific hide event if it should not be propagated.
|
||||
|
@ -403,24 +355,6 @@ class NotificationController final : public EventQueue,
|
|||
*/
|
||||
nsTArray<RefPtr<LocalAccessible>> mRelocations;
|
||||
|
||||
/**
|
||||
* Holds all mutation events.
|
||||
*/
|
||||
EventTree mEventTree;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "CachedTableAccessible.h"
|
||||
#include "DocAccessible-inl.h"
|
||||
#include "DocAccessibleChild.h"
|
||||
#include "EventTree.h"
|
||||
#include "HTMLImageMapAccessible.h"
|
||||
#include "nsAccCache.h"
|
||||
#include "nsAccessiblePivot.h"
|
||||
|
@ -2410,8 +2411,6 @@ bool DocAccessible::MoveChild(LocalAccessible* aChild,
|
|||
}
|
||||
}
|
||||
|
||||
NotificationController::MoveGuard mguard(mNotificationController);
|
||||
|
||||
if (curParent == aNewParent) {
|
||||
MOZ_ASSERT(aChild->IndexInParent() != aIdxInParent, "No move case");
|
||||
curParent->RelocateChild(aIdxInParent, aChild);
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "ARIAMap.h"
|
||||
#include "nsAccUtils.h"
|
||||
#include "DocAccessible-inl.h"
|
||||
#include "EventTree.h"
|
||||
#include "Role.h"
|
||||
|
||||
#include "nsIFrame.h"
|
||||
|
|
Загрузка…
Ссылка в новой задаче