forked from mirrors/gecko-dev
Bug 1395181 part 2: Support click handlers added to the root element. r=eeejay
Normally, we treat the body as the DOM node for a DocAccessible. However, a click listener can be added to the root element; e.g. the html element. We now treat a click listener added to the root element the same as if one were added to the body. This required a change to nsAccessibilityService to use the DocAccessible when click listeners change for the root element so a cache update is pushed. This change was made for the body also, since we weren't pushing a cache update for click listener changes on the body either. Differential Revision: https://phabricator.services.mozilla.com/D144278
This commit is contained in:
parent
ddd6d00a57
commit
a3b482acc2
4 changed files with 56 additions and 4 deletions
|
|
@ -304,6 +304,10 @@ nsAccessibilityService::ListenersChanged(nsIArray* aEventChanges) {
|
|||
|
||||
if (document) {
|
||||
LocalAccessible* acc = document->GetAccessible(content);
|
||||
if (!acc && (content == document->GetContent() ||
|
||||
content == document->DocumentNode()->GetRootElement())) {
|
||||
acc = document;
|
||||
}
|
||||
if (!acc && nsCoreUtils::HasClickListener(content)) {
|
||||
// Create an accessible for a inaccessible element having click event
|
||||
// handler.
|
||||
|
|
|
|||
|
|
@ -2616,3 +2616,26 @@ LocalAccessible* DocAccessible::GetAccessible(nsINode* aNode) const {
|
|||
return aNode == mDocumentNode ? const_cast<DocAccessible*>(this)
|
||||
: mNodeToAccessibleMap.Get(aNode);
|
||||
}
|
||||
|
||||
bool DocAccessible::HasPrimaryAction() const {
|
||||
if (HyperTextAccessible::HasPrimaryAction()) {
|
||||
return true;
|
||||
}
|
||||
// mContent is normally the body, but there might be a click listener on the
|
||||
// root.
|
||||
dom::Element* root = mDocumentNode->GetRootElement();
|
||||
if (mContent != root) {
|
||||
return nsCoreUtils::HasClickListener(root);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void DocAccessible::ActionNameAt(uint8_t aIndex, nsAString& aName) {
|
||||
aName.Truncate();
|
||||
if (aIndex != 0) {
|
||||
return;
|
||||
}
|
||||
if (HasPrimaryAction()) {
|
||||
aName.AssignLiteral("click");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -84,6 +84,10 @@ class DocAccessible : public HyperTextAccessibleWrap,
|
|||
|
||||
virtual nsRect RelativeBounds(nsIFrame** aRelativeFrame) const override;
|
||||
|
||||
// ActionAccessible
|
||||
virtual bool HasPrimaryAction() const override;
|
||||
virtual void ActionNameAt(uint8_t aIndex, nsAString& aName) override;
|
||||
|
||||
// HyperTextAccessible
|
||||
virtual already_AddRefed<EditorBase> GetEditor() const override;
|
||||
|
||||
|
|
|
|||
|
|
@ -170,9 +170,9 @@ addAccessibleTask(
|
|||
await _testActions("onclick_img", ["showlongdesc"]);
|
||||
|
||||
// Remove 'href' from link and test linkable child
|
||||
acc = findAccessibleChildByID(docAcc, "link1");
|
||||
const link1Acc = findAccessibleChildByID(docAcc, "link1");
|
||||
is(
|
||||
acc.firstChild.getActionName(0),
|
||||
link1Acc.firstChild.getActionName(0),
|
||||
"click ancestor",
|
||||
"linkable child has click ancestor action"
|
||||
);
|
||||
|
|
@ -180,8 +180,29 @@ addAccessibleTask(
|
|||
let link1 = content.document.getElementById("link1");
|
||||
link1.removeAttribute("href");
|
||||
});
|
||||
await untilCacheIs(() => acc.actionCount, 0, "link has no actions");
|
||||
is(acc.firstChild.actionCount, 0, "linkable child's actions removed");
|
||||
await untilCacheIs(() => link1Acc.actionCount, 0, "link has no actions");
|
||||
is(link1Acc.firstChild.actionCount, 0, "linkable child's actions removed");
|
||||
|
||||
// Add a click handler to the body. Ensure it propagates to descendants.
|
||||
await invokeContentTask(browser, [], () => {
|
||||
content.document.body.onclick = () => {};
|
||||
});
|
||||
await untilCacheIs(() => docAcc.actionCount, 1, "Doc has 1 action");
|
||||
await _testActions("link1", ["click ancestor"]);
|
||||
|
||||
await invokeContentTask(browser, [], () => {
|
||||
content.document.body.onclick = null;
|
||||
});
|
||||
await untilCacheIs(() => docAcc.actionCount, 0, "Doc has no actions");
|
||||
is(link1Acc.actionCount, 0, "link has no actions");
|
||||
|
||||
// Add a click handler to the root element. Ensure it propagates to
|
||||
// descendants.
|
||||
await invokeContentTask(browser, [], () => {
|
||||
content.document.documentElement.onclick = () => {};
|
||||
});
|
||||
await untilCacheIs(() => docAcc.actionCount, 1, "Doc has 1 action");
|
||||
await _testActions("link1", ["click ancestor"]);
|
||||
},
|
||||
{
|
||||
chrome: true,
|
||||
|
|
|
|||
Loading…
Reference in a new issue