Bug 1353094 - simplify the logic of accessible subtrees removal, r=davidb
This commit is contained in:
@@ -676,7 +676,7 @@ NotificationController::WillRefresh(mozilla::TimeStamp aTime)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mDocument->ContentRemoved(containerElm, textNode);
|
mDocument->ContentRemoved(textAcc);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -52,6 +52,18 @@ TreeWalker::
|
|||||||
MOZ_COUNT_CTOR(TreeWalker);
|
MOZ_COUNT_CTOR(TreeWalker);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TreeWalker::
|
||||||
|
TreeWalker(DocAccessible* aDocument, nsIContent* aAnchorNode) :
|
||||||
|
mDoc(aDocument), mContext(nullptr), mAnchorNode(aAnchorNode),
|
||||||
|
mARIAOwnsIdx(0),
|
||||||
|
mChildFilter(nsIContent::eSkipPlaceholderContent | nsIContent::eAllChildren),
|
||||||
|
mFlags(eWalkCache),
|
||||||
|
mPhase(eAtStart)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(aAnchorNode, "No anchor node for the accessible tree walker");
|
||||||
|
MOZ_COUNT_CTOR(TreeWalker);
|
||||||
|
}
|
||||||
|
|
||||||
TreeWalker::~TreeWalker()
|
TreeWalker::~TreeWalker()
|
||||||
{
|
{
|
||||||
MOZ_COUNT_DTOR(TreeWalker);
|
MOZ_COUNT_DTOR(TreeWalker);
|
||||||
|
|||||||
@@ -47,6 +47,11 @@ public:
|
|||||||
*/
|
*/
|
||||||
TreeWalker(Accessible* aContext, nsIContent* aAnchorNode, uint32_t aFlags = eWalkCache);
|
TreeWalker(Accessible* aContext, nsIContent* aAnchorNode, uint32_t aFlags = eWalkCache);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Navigates the accessible children within the anchor node subtree.
|
||||||
|
*/
|
||||||
|
TreeWalker(DocAccessible* aDocument, nsIContent* aAnchorNode);
|
||||||
|
|
||||||
~TreeWalker();
|
~TreeWalker();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -524,7 +524,7 @@ nsAccessibilityService::DeckPanelSwitched(nsIPresShell* aPresShell,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
document->ContentRemoved(aDeckNode, panelNode);
|
document->ContentRemoved(panelNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aCurrentBoxFrame) {
|
if (aCurrentBoxFrame) {
|
||||||
@@ -582,26 +582,7 @@ nsAccessibilityService::ContentRemoved(nsIPresShell* aPresShell,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (document) {
|
if (document) {
|
||||||
// Flatten hierarchy may be broken at this point so we cannot get a true
|
document->ContentRemoved(aChildNode);
|
||||||
// container by traversing up the DOM tree. Find a parent of first accessible
|
|
||||||
// from the subtree of the given DOM node, that'll be a container. If no
|
|
||||||
// accessibles in subtree then we don't care about the change.
|
|
||||||
Accessible* child = document->GetAccessible(aChildNode);
|
|
||||||
if (!child) {
|
|
||||||
Accessible* container = document->GetContainerAccessible(aChildNode);
|
|
||||||
a11y::TreeWalker walker(container ? container : document, aChildNode,
|
|
||||||
a11y::TreeWalker::eWalkCache);
|
|
||||||
child = walker.Next();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (child) {
|
|
||||||
MOZ_DIAGNOSTIC_ASSERT(child->Parent(), "Unattached accessible from tree");
|
|
||||||
document->ContentRemoved(child->Parent(), aChildNode);
|
|
||||||
#ifdef A11Y_LOG
|
|
||||||
if (logging::IsEnabled(logging::eTree))
|
|
||||||
logging::AccessibleNNode("real container", child->Parent());
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef A11Y_LOG
|
#ifdef A11Y_LOG
|
||||||
|
|||||||
@@ -1170,10 +1170,7 @@ DocAccessible::ContentRemoved(nsIDocument* aDocument,
|
|||||||
// This one and content removal notification from layout may result in
|
// This one and content removal notification from layout may result in
|
||||||
// double processing of same subtrees. If it pops up in profiling, then
|
// double processing of same subtrees. If it pops up in profiling, then
|
||||||
// consider reusing a document node cache to reject these notifications early.
|
// consider reusing a document node cache to reject these notifications early.
|
||||||
Accessible* container = GetAccessibleOrContainer(aContainerNode);
|
ContentRemoved(aChildNode);
|
||||||
if (container) {
|
|
||||||
UpdateTreeOnRemoval(container, aChildNode);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -1382,7 +1379,7 @@ DocAccessible::RecreateAccessible(nsIContent* aContent)
|
|||||||
// should be coalesced with normal show/hide events.
|
// should be coalesced with normal show/hide events.
|
||||||
|
|
||||||
nsIContent* parent = aContent->GetFlattenedTreeParent();
|
nsIContent* parent = aContent->GetFlattenedTreeParent();
|
||||||
ContentRemoved(parent, aContent);
|
ContentRemoved(aContent);
|
||||||
ContentInserted(parent, aContent, aContent->GetNextSibling());
|
ContentInserted(parent, aContent, aContent->GetNextSibling());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1972,33 +1969,36 @@ DocAccessible::FireEventsOnInsertion(Accessible* aContainer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
DocAccessible::UpdateTreeOnRemoval(Accessible* aContainer, nsIContent* aChildNode)
|
DocAccessible::ContentRemoved(Accessible* aContent)
|
||||||
{
|
{
|
||||||
// If child node is not accessible then look for its accessible children.
|
MOZ_DIAGNOSTIC_ASSERT(aContent->Parent(), "Unattached accessible from tree");
|
||||||
Accessible* child = GetAccessible(aChildNode);
|
|
||||||
#ifdef A11Y_LOG
|
#ifdef A11Y_LOG
|
||||||
logging::TreeInfo("process content removal", 0,
|
logging::TreeInfo("process content removal", 0,
|
||||||
"container", aContainer, "child", aChildNode);
|
"container", aContent->Parent(), "child", aContent, nullptr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TreeMutation mt(aContainer);
|
TreeMutation mt(aContent->Parent());
|
||||||
if (child) {
|
mt.BeforeRemoval(aContent);
|
||||||
mt.BeforeRemoval(child);
|
aContent->Parent()->RemoveChild(aContent);
|
||||||
MOZ_ASSERT(aContainer == child->Parent(), "Wrong parent");
|
UncacheChildrenInSubtree(aContent);
|
||||||
aContainer->RemoveChild(child);
|
|
||||||
UncacheChildrenInSubtree(child);
|
|
||||||
mt.Done();
|
mt.Done();
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TreeWalker walker(aContainer, aChildNode, TreeWalker::eWalkCache);
|
void
|
||||||
while (Accessible* child = walker.Next()) {
|
DocAccessible::ContentRemoved(nsIContent* aContentNode)
|
||||||
mt.BeforeRemoval(child);
|
{
|
||||||
MOZ_ASSERT(aContainer == child->Parent(), "Wrong parent");
|
// If child node is not accessible then look for its accessible children.
|
||||||
aContainer->RemoveChild(child);
|
Accessible* acc = GetAccessible(aContentNode);
|
||||||
UncacheChildrenInSubtree(child);
|
if (acc) {
|
||||||
|
ContentRemoved(acc);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
TreeWalker walker(this, aContentNode);
|
||||||
|
while (Accessible* acc = walker.Next()) {
|
||||||
|
ContentRemoved(acc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
mt.Done();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@@ -2051,7 +2051,7 @@ DocAccessible::ValidateARIAOwned()
|
|||||||
|
|
||||||
// If DOM node doesn't have a frame anymore then shutdown its accessible.
|
// If DOM node doesn't have a frame anymore then shutdown its accessible.
|
||||||
if (child->Parent() && !child->GetFrame()) {
|
if (child->Parent() && !child->GetFrame()) {
|
||||||
UpdateTreeOnRemoval(child->Parent(), child->GetContent());
|
ContentRemoved(child);
|
||||||
children->RemoveElementAt(idx);
|
children->RemoveElementAt(idx);
|
||||||
idx--;
|
idx--;
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -342,18 +342,10 @@ public:
|
|||||||
nsIContent* aEndChildNode);
|
nsIContent* aEndChildNode);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notify the document accessible that content was removed.
|
* Update the tree on content removal.
|
||||||
*/
|
*/
|
||||||
void ContentRemoved(Accessible* aContainer, nsIContent* aChildNode)
|
void ContentRemoved(Accessible* aContent);
|
||||||
{
|
void ContentRemoved(nsIContent* aContentNode);
|
||||||
// Update the whole tree of this document accessible when the container is
|
|
||||||
// null (document element is removed).
|
|
||||||
UpdateTreeOnRemoval((aContainer ? aContainer : this), aChildNode);
|
|
||||||
}
|
|
||||||
void ContentRemoved(nsIContent* aContainerNode, nsIContent* aChildNode)
|
|
||||||
{
|
|
||||||
ContentRemoved(AccessibleOrTrueContainer(aContainerNode), aChildNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates accessible tree when rendered text is changed.
|
* Updates accessible tree when rendered text is changed.
|
||||||
@@ -512,11 +504,6 @@ protected:
|
|||||||
*/
|
*/
|
||||||
void ProcessInvalidationList();
|
void ProcessInvalidationList();
|
||||||
|
|
||||||
/**
|
|
||||||
* Update the accessible tree for content removal.
|
|
||||||
*/
|
|
||||||
void UpdateTreeOnRemoval(Accessible* aContainer, nsIContent* aChildNode);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validates all aria-owns connections and updates the tree accordingly.
|
* Validates all aria-owns connections and updates the tree accordingly.
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user