Bug 707654 - embeds relation on root accessible can return not content document, r=davidb

This commit is contained in:
Alexander Surkov 2012-01-31 15:40:06 +09:00
parent 6278f45019
commit 5659a8e340
6 changed files with 172 additions and 88 deletions

View File

@ -574,59 +574,6 @@ nsRootAccessible::Shutdown()
nsDocAccessibleWrap::Shutdown();
}
// nsRootAccessible protected member
already_AddRefed<nsIDocShellTreeItem>
nsRootAccessible::GetContentDocShell(nsIDocShellTreeItem *aStart)
{
if (!aStart) {
return nsnull;
}
PRInt32 itemType;
aStart->GetItemType(&itemType);
if (itemType == nsIDocShellTreeItem::typeContent) {
nsDocAccessible *accDoc = nsAccUtils::GetDocAccessibleFor(aStart);
// Hidden documents don't have accessibles (like SeaMonkey's sidebar),
// they are of no interest for a11y.
if (!accDoc)
return nsnull;
// If ancestor chain of accessibles is not completely visible,
// don't use this one. This happens for example if it's inside
// a background tab (tabbed browsing)
nsAccessible* parent = accDoc->Parent();
while (parent) {
if (parent->State() & states::INVISIBLE)
return nsnull;
if (parent == this)
break; // Don't check past original root accessible we started with
parent = parent->Parent();
}
NS_ADDREF(aStart);
return aStart;
}
nsCOMPtr<nsIDocShellTreeNode> treeNode(do_QueryInterface(aStart));
if (treeNode) {
PRInt32 subDocuments;
treeNode->GetChildCount(&subDocuments);
for (PRInt32 count = 0; count < subDocuments; count ++) {
nsCOMPtr<nsIDocShellTreeItem> treeItemChild, contentTreeItem;
treeNode->GetChildAt(count, getter_AddRefs(treeItemChild));
NS_ENSURE_TRUE(treeItemChild, nsnull);
contentTreeItem = GetContentDocShell(treeItemChild);
if (contentTreeItem) {
NS_ADDREF(aStart = contentTreeItem);
return aStart;
}
}
}
return nsnull;
}
// nsIAccessible method
Relation
nsRootAccessible::RelationByType(PRUint32 aType)
@ -634,14 +581,25 @@ nsRootAccessible::RelationByType(PRUint32 aType)
if (!mDocument || aType != nsIAccessibleRelation::RELATION_EMBEDS)
return nsDocAccessibleWrap::RelationByType(aType);
nsCOMPtr<nsIDocShellTreeItem> treeItem =
nsCoreUtils::GetDocShellTreeItemFor(mDocument);
nsCOMPtr<nsIDocShellTreeItem> contentTreeItem = GetContentDocShell(treeItem);
// there may be no content area, so we need a null check
if (!contentTreeItem)
return Relation();
nsIDOMWindow* rootWindow = mDocument->GetWindow();
if (rootWindow) {
nsCOMPtr<nsIDOMWindow> contentWindow;
rootWindow->GetContent(getter_AddRefs(contentWindow));
if (contentWindow) {
nsCOMPtr<nsIDOMDocument> contentDOMDocument;
contentWindow->GetDocument(getter_AddRefs(contentDOMDocument));
nsCOMPtr<nsIDocument> contentDocumentNode =
do_QueryInterface(contentDOMDocument);
if (contentDocumentNode) {
nsDocAccessible* contentDocument =
GetAccService()->GetDocAccessible(contentDocumentNode);
if (contentDocument)
return Relation(contentDocument);
}
}
}
return Relation(nsAccUtils::GetDocAccessibleFor(contentTreeItem));
return Relation();
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -127,8 +127,7 @@ protected:
PRUint32 GetChromeFlags();
#endif
already_AddRefed<nsIDocShellTreeItem>
GetContentDocShell(nsIDocShellTreeItem *aStart);
nsRefPtr<nsCaretAccessible> mCaretAccessible;
};

View File

@ -48,6 +48,7 @@ include $(topsrcdir)/config/rules.mk
# test_tabbrowser.xul disabled for misusing <tabbrowser> (bug 715857)
_TEST_FILES =\
test_embeds.xul \
test_general.html \
test_general.xul \
test_tree.xul \

View File

@ -0,0 +1,152 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
type="text/css"?>
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
title="Embeds relation tests">
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
<script type="application/javascript"
src="../common.js"></script>
<script type="application/javascript"
src="../role.js"></script>
<script type="application/javascript"
src="../states.js"></script>
<script type="application/javascript"
src="../events.js"></script>
<script type="application/javascript"
src="../relations.js"></script>
<script type="application/javascript">
<![CDATA[
////////////////////////////////////////////////////////////////////////////
// Helpers
function tabBrowser()
{
return gBrowserWnd.gBrowser;
}
function currentBrowser()
{
return tabBrowser().selectedBrowser;
}
function currentTabDocument()
{
return currentBrowser().contentDocument;
}
////////////////////////////////////////////////////////////////////////////
// Invokers
function loadURI(aURI)
{
this.invoke = function loadURI_invoke()
{
tabBrowser().loadURI(aURI);
}
this.eventSeq = [
new invokerChecker(EVENT_REORDER, currentBrowser)
];
this.finalCheck = function loadURI_finalCheck()
{
testRelation(gBrowserWnd.document, RELATION_EMBEDS,
getAccessible(currentTabDocument()));
}
this.getID = function loadURI_getID()
{
return "load uri " + aURI;
}
}
function loadOneTab(aURI)
{
this.invoke = function loadOneTab_invoke()
{
tabBrowser().loadOneTab(aURI, null, null, null, false);
}
this.eventSeq = [
new invokerChecker(EVENT_REORDER, currentBrowser)
];
this.finalCheck = function loadURI_finalCheck()
{
testRelation(gBrowserWnd.document, RELATION_EMBEDS,
getAccessible(currentTabDocument()));
}
this.getID = function loadOneTab_getID()
{
return "load uri '" + aURI + "' in new tab";
}
}
////////////////////////////////////////////////////////////////////////////
// Testing
var gBrowserWnd = null;
function loadBrowser()
{
gBrowserWnd = window.openDialog("chrome://browser/content/", "_blank",
"chrome,all,dialog=no", "about:");
addA11yLoadEvent(startTests, gBrowserWnd);
}
function startTests()
{
// Wait for tab load.
var browser = currentBrowser();
addA11yLoadEvent(doTests, browser.contentWindow);
}
//gA11yEventDumpToConsole = true; // debug
var gQueue = null;
function doTests()
{
testRelation(gBrowserWnd.document, RELATION_EMBEDS,
getAccessible(currentTabDocument()));
gQueue = new eventQueue();
gQueue.push(new loadURI("about:about"));
gQueue.push(new loadOneTab("about:mozilla"));
gQueue.onFinish = function()
{
gBrowserWnd.close();
}
gQueue.invoke();
}
SimpleTest.waitForExplicitFinish();
addLoadEvent(loadBrowser);
]]>
</script>
<vbox flex="1" style="overflow: auto;">
<body xmlns="http://www.w3.org/1999/xhtml">
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=707654"
title="Embeds relation on root accessible can return not content document">
Mozilla Bug 707654
</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
</pre>
</body>
</vbox>
</window>

View File

@ -126,19 +126,6 @@
testRelation("legend", RELATION_LABEL_FOR, "fieldset");
testRelation("fieldset", RELATION_LABELLED_BY, "legend");
// 'embeds' relation for root accessible
var docAcc = null;
var parentOfDocAcc = null;
var parentDocAcc = getAccessible(document);
do {
docAcc = parentDocAcc;
parentOfDocAcc = getAccessible(docAcc.parent, [nsIAccessNode]);
parentDocAcc = getAccessible(parentOfDocAcc.document,
[nsIAccessible]);
} while (getRole(parentDocAcc) != ROLE_CHROME_WINDOW)
testRelation(parentDocAcc, RELATION_EMBEDS, docAcc);
// finish test
SimpleTest.finish();
}

View File

@ -103,19 +103,6 @@
// 'default button' relation
testRelation("textbox", RELATION_DEFAULT_BUTTON, "submit");
// 'embeds' relation for root accessible
var docAcc = null;
var parentOfDocAcc = null;
var parentDocAcc = getAccessible(document);
do {
docAcc = parentDocAcc;
parentOfDocAcc = getAccessible(docAcc.parent, [nsIAccessNode]);
parentDocAcc = getAccessible(parentOfDocAcc.document,
[nsIAccessible]);
} while (getRole(parentDocAcc) != ROLE_CHROME_WINDOW)
testRelation(parentDocAcc, RELATION_EMBEDS, docAcc);
// 'labelled by'/'label for' relation for xul:goupbox and xul:label of
// xul:caption
var groupboxAcc = getAccessible("groupbox");