зеркало из https://github.com/mozilla/gecko-dev.git
Bug 574312 - make accessible tree creation from parent to child always, r=marcoz, davidb, sr=neil
This commit is contained in:
Родитель
7be35161f4
Коммит
a233b0fd40
|
@ -56,7 +56,7 @@ interface nsIDOMDOMStringList;
|
|||
*
|
||||
* @status UNDER_REVIEW
|
||||
*/
|
||||
[scriptable, uuid(420f0f49-27c1-4ac1-b509-5aba4353909b)]
|
||||
[scriptable, uuid(310ce77d-c92b-4761-82e8-77e1a728e8d4)]
|
||||
interface nsIAccessibleRetrieval : nsISupports
|
||||
{
|
||||
/**
|
||||
|
@ -73,30 +73,6 @@ interface nsIAccessibleRetrieval : nsISupports
|
|||
*/
|
||||
nsIAccessible getAccessibleFor(in nsIDOMNode aNode);
|
||||
|
||||
/**
|
||||
* The same like getAccessibleFor method except it returns accessible only if
|
||||
* it is attached, i.e. accessible is certified to be a descendent of the root
|
||||
* accessible.
|
||||
*
|
||||
* @param aNode - the DOM node to get an accessible for.
|
||||
*
|
||||
* @return - the accessible for the given DOM node.
|
||||
*/
|
||||
nsIAccessible getAttachedAccessibleFor(in nsIDOMNode aNode);
|
||||
|
||||
/**
|
||||
* Return an DOM node that is relevant to attached accesible check. This
|
||||
* node is either from bindings chain if given node is anonymous and owner
|
||||
* binding denies accessible in anonymous content or given node (it's not
|
||||
* important whether it is accessible or not). This method doesn't create
|
||||
* accessible object for returned node.
|
||||
*
|
||||
* @param aNode - the DOM node to get relevant content node.
|
||||
*
|
||||
* @return - the DOM node for parent attached accessible
|
||||
*/
|
||||
nsIDOMNode getRelevantContentNodeFor(in nsIDOMNode aNode);
|
||||
|
||||
/**
|
||||
* Returns accessible role as a string.
|
||||
*
|
||||
|
|
|
@ -113,8 +113,8 @@ nsAccTreeWalker::GetNextChildInternal(PRBool aNoWalkUp)
|
|||
|
||||
PRBool isHidden = PR_FALSE;
|
||||
nsRefPtr<nsAccessible> accessible =
|
||||
GetAccService()->GetAccessible(childNode, presShell, mWeakShell,
|
||||
&isHidden);
|
||||
GetAccService()->GetOrCreateAccessible(childNode, presShell, mWeakShell,
|
||||
&isHidden);
|
||||
|
||||
if (accessible)
|
||||
return accessible.forget();
|
||||
|
|
|
@ -527,31 +527,28 @@ nsAccUtils::GetTextAccessibleFromSelection(nsISelection *aSelection,
|
|||
nsCOMPtr<nsINode> focusNode(do_QueryInterface(focusDOMNode));
|
||||
nsCOMPtr<nsINode> resultNode =
|
||||
nsCoreUtils::GetDOMNodeFromDOMPoint(focusNode, focusOffset);
|
||||
nsCOMPtr<nsIWeakReference> weakShell(nsCoreUtils::GetWeakShellFor(resultNode));
|
||||
|
||||
// Get text accessible containing the result node.
|
||||
while (resultNode) {
|
||||
// Make sure to get the correct starting node for selection events inside
|
||||
// XBL content trees.
|
||||
resultNode = GetAccService()->GetRelevantContentNodeFor(resultNode);
|
||||
if (!resultNode->IsNodeOfType(nsINode::eTEXT)) {
|
||||
nsAccessible *accessible = GetAccService()->GetAccessible(resultNode);
|
||||
if (accessible) {
|
||||
nsHyperTextAccessible *textAcc = nsnull;
|
||||
CallQueryInterface(accessible, &textAcc);
|
||||
if (textAcc) {
|
||||
if (aNode)
|
||||
NS_ADDREF(*aNode = resultNode);
|
||||
|
||||
return textAcc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resultNode = resultNode->GetNodeParent();
|
||||
nsAccessible* accessible =
|
||||
GetAccService()->GetAccessibleOrContainer(resultNode, weakShell);
|
||||
if (!accessible) {
|
||||
NS_NOTREACHED("No nsIAccessibleText for selection change event!");
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
NS_NOTREACHED("No nsIAccessibleText for selection change event!");
|
||||
do {
|
||||
nsHyperTextAccessible* textAcc = nsnull;
|
||||
CallQueryInterface(accessible, &textAcc);
|
||||
if (textAcc) {
|
||||
if (aNode)
|
||||
NS_ADDREF(*aNode = accessible->GetNode());
|
||||
|
||||
return textAcc;
|
||||
}
|
||||
} while (accessible = accessible->GetParent());
|
||||
|
||||
NS_NOTREACHED("We must reach document accessible implementing nsIAccessibleText!");
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
|
@ -634,7 +631,8 @@ nsIntPoint
|
|||
nsAccUtils::GetScreenCoordsForParent(nsAccessNode *aAccessNode)
|
||||
{
|
||||
nsAccessible *parent =
|
||||
GetAccService()->GetContainerAccessible(aAccessNode->GetNode(), PR_TRUE);
|
||||
GetAccService()->GetContainerAccessible(aAccessNode->GetNode(),
|
||||
aAccessNode->GetWeakShell());
|
||||
if (!parent)
|
||||
return nsIntPoint(0, 0);
|
||||
|
||||
|
@ -815,12 +813,6 @@ nsAccUtils::MustPrune(nsIAccessible *aAccessible)
|
|||
role == nsIAccessibleRole::ROLE_SEPARATOR;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsAccUtils::IsNodeRelevant(nsINode *aNode)
|
||||
{
|
||||
return aNode == GetAccService()->GetRelevantContentNodeFor(aNode);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAccUtils::GetHeaderCellsFor(nsIAccessibleTable *aTable,
|
||||
nsIAccessibleTableCell *aCell,
|
||||
|
|
|
@ -410,12 +410,6 @@ public:
|
|||
*/
|
||||
static PRBool MustPrune(nsIAccessible *aAccessible);
|
||||
|
||||
/**
|
||||
* Return true if the given node can be accessible and attached to
|
||||
* the document's accessible tree.
|
||||
*/
|
||||
static PRBool IsNodeRelevant(nsINode *aNode);
|
||||
|
||||
/**
|
||||
* Search hint enum constants. Used by GetHeaderCellsFor() method.
|
||||
*/
|
||||
|
|
|
@ -176,6 +176,11 @@ public:
|
|||
*/
|
||||
already_AddRefed<nsIPresShell> GetPresShell();
|
||||
|
||||
/**
|
||||
* Return presentation shell for the accessible.
|
||||
*/
|
||||
nsIWeakReference* GetWeakShell() const { return mWeakShell; }
|
||||
|
||||
protected:
|
||||
nsPresContext* GetPresContext();
|
||||
|
||||
|
|
|
@ -148,30 +148,18 @@ nsAccessibilityService::NotifyOfAnchorJumpTo(nsIContent *aTarget)
|
|||
if (!document)
|
||||
return;
|
||||
|
||||
nsINode *targetNode = aTarget;
|
||||
nsAccessible *targetAcc = GetAccessible(targetNode);
|
||||
|
||||
// Getting the targetAcc above will have ensured accessible doc creation.
|
||||
// XXX Bug 561683
|
||||
nsDocAccessible *docAccessible = GetDocAccessible(document);
|
||||
if (!docAccessible)
|
||||
return;
|
||||
|
||||
// If the jump target is not accessible then fire an event for nearest
|
||||
// accessible in parent chain.
|
||||
if (!targetAcc) {
|
||||
targetAcc = GetContainerAccessible(targetNode, PR_TRUE);
|
||||
targetNode = targetAcc->GetNode();
|
||||
}
|
||||
|
||||
NS_ASSERTION(targetNode,
|
||||
"No accessible in parent chain!? Expect at least a document accessible.");
|
||||
if (!targetNode)
|
||||
nsCOMPtr<nsIWeakReference> weakShell(nsCoreUtils::GetWeakShellFor(aTarget));
|
||||
nsAccessible* targetAcc = GetAccessibleOrContainer(aTarget, weakShell);
|
||||
if (!targetAcc)
|
||||
return;
|
||||
|
||||
nsINode* targetNode = targetAcc->GetNode();
|
||||
|
||||
// XXX note in rare cases the node could go away before we flush the queue,
|
||||
// for example if the node becomes inaccessible, or is removed from the DOM.
|
||||
docAccessible->
|
||||
GetDocAccessible(document)->
|
||||
FireDelayedAccessibleEvent(nsIAccessibleEvent::EVENT_SCROLLING_START,
|
||||
targetNode);
|
||||
}
|
||||
|
@ -513,31 +501,6 @@ nsAccessibilityService::GetAccessibleFor(nsIDOMNode *aNode,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAccessibilityService::GetAttachedAccessibleFor(nsIDOMNode *aDOMNode,
|
||||
nsIAccessible **aAccessible)
|
||||
{
|
||||
NS_ENSURE_ARG(aDOMNode);
|
||||
NS_ENSURE_ARG_POINTER(aAccessible);
|
||||
|
||||
nsCOMPtr<nsINode> node(do_QueryInterface(aDOMNode));
|
||||
NS_IF_ADDREF(*aAccessible = GetAttachedAccessibleFor(node));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAccessibilityService::GetRelevantContentNodeFor(nsIDOMNode *aNode,
|
||||
nsIDOMNode **aRelevantNode)
|
||||
{
|
||||
NS_ENSURE_ARG(aNode);
|
||||
NS_ENSURE_ARG_POINTER(aRelevantNode);
|
||||
|
||||
nsCOMPtr<nsINode> node(do_QueryInterface(aNode));
|
||||
nsINode *relevantNode = GetRelevantContentNodeFor(node);
|
||||
CallQueryInterface(relevantNode, aRelevantNode);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAccessibilityService::GetStringRole(PRUint32 aRole, nsAString& aString)
|
||||
{
|
||||
|
@ -730,46 +693,25 @@ nsAccessibilityService::GetAccessibleInShell(nsINode* aNode,
|
|||
return nsnull;
|
||||
|
||||
nsCOMPtr<nsIWeakReference> weakShell(do_GetWeakReference(aPresShell));
|
||||
nsRefPtr<nsAccessible> accessible =
|
||||
GetAccessible(aNode, aPresShell, weakShell);
|
||||
return accessible;
|
||||
return GetAccessibleByRule(aNode, weakShell, eGetAccForNode);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsAccessibilityService public
|
||||
|
||||
nsAccessible *
|
||||
nsAccessibilityService::GetAccessible(nsINode *aNode)
|
||||
nsAccessible*
|
||||
nsAccessibilityService::GetAccessible(nsINode* aNode)
|
||||
{
|
||||
if (!aNode)
|
||||
return nsnull;
|
||||
|
||||
nsIPresShell *presShell = nsCoreUtils::GetPresShellFor(aNode);
|
||||
if (!presShell)
|
||||
return nsnull;
|
||||
|
||||
nsCOMPtr<nsIWeakReference> weakShell(do_GetWeakReference(presShell));
|
||||
nsRefPtr<nsAccessible> accessible = GetAccessible(aNode, presShell,
|
||||
weakShell);
|
||||
return accessible;
|
||||
if (aNode) {
|
||||
nsCOMPtr<nsIWeakReference> weakShell(nsCoreUtils::GetWeakShellFor(aNode));
|
||||
if (weakShell)
|
||||
return GetAccessibleByRule(aNode, weakShell, eGetAccForNode);
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsAccessible *
|
||||
nsAccessibilityService::GetAccessibleInWeakShell(nsINode *aNode,
|
||||
nsIWeakReference *aWeakShell)
|
||||
{
|
||||
if (!aNode || !aWeakShell)
|
||||
return nsnull;
|
||||
|
||||
nsCOMPtr<nsIPresShell> presShell(do_QueryReferent(aWeakShell));
|
||||
nsRefPtr<nsAccessible> accessible = GetAccessible(aNode, presShell,
|
||||
aWeakShell);
|
||||
return accessible;
|
||||
}
|
||||
|
||||
nsAccessible *
|
||||
nsAccessibilityService::GetContainerAccessible(nsINode *aNode,
|
||||
PRBool aCanCreate)
|
||||
nsAccessible*
|
||||
nsAccessibilityService::GetCachedContainerAccessible(nsINode* aNode)
|
||||
{
|
||||
if (!aNode)
|
||||
return nsnull;
|
||||
|
@ -786,32 +728,12 @@ nsAccessibilityService::GetContainerAccessible(nsINode *aNode,
|
|||
nsCOMPtr<nsIWeakReference> weakShell(do_GetWeakReference(presShell));
|
||||
|
||||
nsAccessible *accessible = nsnull;
|
||||
while (!accessible && (currNode = currNode->GetNodeParent())) {
|
||||
currNode = GetAccService()->GetRelevantContentNodeFor(currNode);
|
||||
|
||||
if (aCanCreate) {
|
||||
accessible = GetAccService()->GetAccessibleInWeakShell(currNode,
|
||||
weakShell);
|
||||
|
||||
} else {
|
||||
// Only return cached accessible, don't create anything.
|
||||
accessible = GetCachedAccessible(currNode, weakShell);
|
||||
}
|
||||
}
|
||||
while ((currNode = currNode->GetNodeParent()) &&
|
||||
!(accessible = GetCachedAccessible(currNode, weakShell)));
|
||||
|
||||
return accessible;
|
||||
}
|
||||
|
||||
nsAccessible *
|
||||
nsAccessibilityService::GetAttachedAccessibleFor(nsINode *aNode)
|
||||
{
|
||||
nsINode *relevantNode = GetRelevantContentNodeFor(aNode);
|
||||
if (relevantNode != aNode)
|
||||
return nsnull;
|
||||
|
||||
return GetAccessible(relevantNode);
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsAccessibilityService::InitAccessible(nsAccessible *aAccessible,
|
||||
nsRoleMapEntry *aRoleMapEntry)
|
||||
|
@ -863,10 +785,10 @@ static PRBool HasRelatedContent(nsIContent *aContent)
|
|||
}
|
||||
|
||||
already_AddRefed<nsAccessible>
|
||||
nsAccessibilityService::GetAccessible(nsINode *aNode,
|
||||
nsIPresShell *aPresShell,
|
||||
nsIWeakReference *aWeakShell,
|
||||
PRBool *aIsHidden)
|
||||
nsAccessibilityService::GetOrCreateAccessible(nsINode* aNode,
|
||||
nsIPresShell* aPresShell,
|
||||
nsIWeakReference* aWeakShell,
|
||||
PRBool* aIsHidden)
|
||||
{
|
||||
if (!aPresShell || !aWeakShell || !aNode || gIsShutdown)
|
||||
return nsnull;
|
||||
|
@ -1244,71 +1166,73 @@ nsAccessibilityService::HasUniversalAriaProperty(nsIContent *aContent)
|
|||
nsAccUtils::HasDefinedARIAToken(aContent, nsAccessibilityAtoms::aria_relevant);
|
||||
}
|
||||
|
||||
nsINode *
|
||||
nsAccessibilityService::GetRelevantContentNodeFor(nsINode *aNode)
|
||||
nsAccessible*
|
||||
nsAccessibilityService::GetAccessibleByRule(nsINode* aNode,
|
||||
nsIWeakReference* aWeakShell,
|
||||
EWhatAccToGet aWhatToGet)
|
||||
{
|
||||
// The method returns node that is relevant for attached accessible check.
|
||||
// Sometimes element that is XBL widget hasn't accessible children in
|
||||
// anonymous content. This method check whether given node can be accessible
|
||||
// by looking through all nested bindings that given node is anonymous for. If
|
||||
// there is XBL widget that deniedes to be accessible for given node then the
|
||||
// method returns that XBL widget otherwise it returns given node.
|
||||
|
||||
// For example, the algorithm allows us to handle following cases:
|
||||
// 1. xul:dialog element has buttons (like 'ok' and 'cancel') in anonymous
|
||||
// content. When node is dialog's button then we dialog's button since button
|
||||
// of xul:dialog is accessible anonymous node.
|
||||
// 2. xul:texbox has html:input in anonymous content. When given node is
|
||||
// html:input elmement then we return xul:textbox since xul:textbox doesn't
|
||||
// allow accessible nodes in anonymous content.
|
||||
// 3. xforms:input that is hosted in xul document contains xul:textbox
|
||||
// element. When given node is html:input or xul:textbox then we return
|
||||
// xforms:input element since xforms:input hasn't accessible anonymous
|
||||
// children.
|
||||
|
||||
if (!aNode)
|
||||
if (!aNode || !aWeakShell)
|
||||
return nsnull;
|
||||
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(aNode));
|
||||
if (content) {
|
||||
// Build stack of binding parents so we can walk it in reverse.
|
||||
nsIContent *bindingParent;
|
||||
nsCOMArray<nsIContent> bindingsStack;
|
||||
nsAccessible* cachedAcc = GetCachedAccessible(aNode, aWeakShell);
|
||||
if (cachedAcc) {
|
||||
if (aWhatToGet & eGetAccForNode)
|
||||
return cachedAcc;
|
||||
|
||||
for (bindingParent = content->GetBindingParent(); bindingParent != nsnull &&
|
||||
bindingParent != bindingParent->GetBindingParent();
|
||||
bindingParent = bindingParent->GetBindingParent()) {
|
||||
bindingsStack.AppendObject(bindingParent);
|
||||
}
|
||||
// XXX: while nsAccessible::GetParent() tries to repair broken tree and
|
||||
// may not return cached parent then we use GetAccessibleOrContainer().
|
||||
return GetAccessibleByRule(aNode->GetNodeParent(), aWeakShell,
|
||||
eGetAccForNodeOrContainer);
|
||||
}
|
||||
|
||||
PRInt32 bindingsCount = bindingsStack.Count();
|
||||
for (PRInt32 index = bindingsCount - 1; index >= 0 ; index--) {
|
||||
bindingParent = bindingsStack[index];
|
||||
// Go up looking for the nearest accessible container stored in cache.
|
||||
nsTArray<nsINode*> nodes;
|
||||
nsINode* node = aNode;
|
||||
while ((node = node->GetNodeParent()) &&
|
||||
!(cachedAcc = GetCachedAccessible(node, aWeakShell)))
|
||||
nodes.AppendElement(node);
|
||||
|
||||
// Try to get an accessible by type since XBL widget can be accessible
|
||||
// only if it implements nsIAccessibleProvider interface.
|
||||
nsCOMPtr<nsIWeakReference> weakShell =
|
||||
nsCoreUtils::GetWeakShellFor(bindingParent);
|
||||
// Node is not in accessible document.
|
||||
if (!cachedAcc)
|
||||
return nsnull;
|
||||
|
||||
// XXX: it's a hack we should try the cache before, otherwise to cache
|
||||
// the accessible.
|
||||
nsRefPtr<nsAccessible> accessible =
|
||||
CreateAccessibleByType(bindingParent, weakShell);
|
||||
|
||||
if (accessible) {
|
||||
if (!accessible->GetAllowsAnonChildAccessibles())
|
||||
return bindingParent;
|
||||
// If children of the cached accessible weren't initialized then go down to
|
||||
// the given node and create accessible tree.
|
||||
nsAccessible* containerAcc = cachedAcc;
|
||||
if (!cachedAcc->AreChildrenCached()) {
|
||||
cachedAcc->EnsureChildren();
|
||||
for (PRInt32 idx = nodes.Length() - 1; idx >= 0; idx--) {
|
||||
cachedAcc = GetCachedAccessible(nodes[idx], aWeakShell);
|
||||
if (cachedAcc) {
|
||||
cachedAcc->EnsureChildren();
|
||||
containerAcc = cachedAcc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return aNode;
|
||||
// If the given node is accessible then it should be cached at this point.
|
||||
// Exception is an area element because area and imagemap nodes aren't in
|
||||
// the same parent chain.
|
||||
cachedAcc = GetCachedAccessible(aNode, aWeakShell);
|
||||
if (!cachedAcc && aNode->IsElement()) {
|
||||
nsIFrame* frame = aNode->AsElement()->GetPrimaryFrame();
|
||||
if (frame && frame->GetContent() != aNode)
|
||||
cachedAcc = GetAreaAccessible(frame, aNode, aWeakShell, &containerAcc);
|
||||
}
|
||||
|
||||
if ((aWhatToGet & eGetAccForNode) && cachedAcc)
|
||||
return cachedAcc;
|
||||
else if (aWhatToGet & eGetAccForContainer)
|
||||
return containerAcc;
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsAccessible*
|
||||
nsAccessibilityService::GetAreaAccessible(nsIFrame *aImageFrame,
|
||||
nsINode *aAreaNode,
|
||||
nsIWeakReference *aWeakShell)
|
||||
nsAccessibilityService::GetAreaAccessible(nsIFrame* aImageFrame,
|
||||
nsINode* aAreaNode,
|
||||
nsIWeakReference* aWeakShell,
|
||||
nsAccessible** aImageAccessible)
|
||||
{
|
||||
// Check if frame is an image frame, and content is <area>.
|
||||
nsIImageFrame *imageFrame = do_QueryFrame(aImageFrame);
|
||||
|
@ -1331,6 +1255,9 @@ nsAccessibilityService::GetAreaAccessible(nsIFrame *aImageFrame,
|
|||
return nsnull;
|
||||
}
|
||||
|
||||
if (aImageAccessible)
|
||||
*aImageAccessible = imageAcc;
|
||||
|
||||
// Make sure <area> accessible children of the image map are cached so
|
||||
// that they should be available in global cache.
|
||||
imageAcc->EnsureChildren();
|
||||
|
|
|
@ -127,7 +127,8 @@ public:
|
|||
static PRBool IsShutdown() { return gIsShutdown; }
|
||||
|
||||
/**
|
||||
* Return an accessible for the given DOM node.
|
||||
* Return an accessible for the given DOM node from the cache or create new
|
||||
* one.
|
||||
*
|
||||
* @param aNode [in] the given node
|
||||
* @param aPresShell [in] the pres shell of the node
|
||||
|
@ -136,57 +137,52 @@ public:
|
|||
* hidden
|
||||
*/
|
||||
already_AddRefed<nsAccessible>
|
||||
GetAccessible(nsINode *aNode, nsIPresShell *aPresShell,
|
||||
nsIWeakReference *aWeakShell, PRBool *aIsHidden = nsnull);
|
||||
GetOrCreateAccessible(nsINode* aNode, nsIPresShell* aPresShell,
|
||||
nsIWeakReference* aWeakShell,
|
||||
PRBool* aIsHidden = nsnull);
|
||||
|
||||
/**
|
||||
* Return an accessible for the given DOM node.
|
||||
*/
|
||||
nsAccessible *GetAccessible(nsINode *aNode);
|
||||
nsAccessible* GetAccessible(nsINode* aNode);
|
||||
|
||||
/**
|
||||
* Return an accessible for a DOM node in the given pres shell.
|
||||
*
|
||||
* @param aNode [in] the given node.
|
||||
* @param aPresShell [in] the presentation shell of the given node.
|
||||
* Return an accessible for a DOM node in the given presshell.
|
||||
*
|
||||
* @param aNode [in] the given node
|
||||
* @param aWeakShell [in] the presentation shell for the given node
|
||||
*/
|
||||
nsAccessible *GetAccessibleInWeakShell(nsINode *aNode,
|
||||
nsIWeakReference *aPresShell);
|
||||
inline nsAccessible* GetAccessibleInWeakShell(nsINode* aNode,
|
||||
nsIWeakReference* aWeakShell)
|
||||
{
|
||||
return GetAccessibleByRule(aNode, aWeakShell, eGetAccForNode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the first accessible parent of a DOM node.
|
||||
* Return an accessible for the given DOM node or container accessible if
|
||||
* the node is not accessible.
|
||||
*/
|
||||
inline nsAccessible* GetAccessibleOrContainer(nsINode* aNode,
|
||||
nsIWeakReference* aWeakShell)
|
||||
{
|
||||
return GetAccessibleByRule(aNode, aWeakShell, eGetAccForNodeOrContainer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a container accessible for the given DOM node.
|
||||
*/
|
||||
inline nsAccessible* GetContainerAccessible(nsINode* aNode,
|
||||
nsIWeakReference* aWeakShell)
|
||||
{
|
||||
return GetAccessibleByRule(aNode, aWeakShell, eGetAccForContainer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the first cached accessible parent of a DOM node.
|
||||
*
|
||||
* @param aDOMNode [in] the DOM node to get an accessible for
|
||||
* @param aCanCreate [in] specifies if accessible can be created if it didn't
|
||||
* exist
|
||||
*/
|
||||
nsAccessible *GetContainerAccessible(nsINode *aNode, PRBool aCanCreate);
|
||||
|
||||
/**
|
||||
* The same as getAccessibleFor method except it returns accessible only if
|
||||
* it is attached, i.e. accessible is certified to be a descendant of the root
|
||||
* accessible.
|
||||
*
|
||||
* XXX: this method must go away once we'll implement correct accessible tree.
|
||||
*
|
||||
* @param aNode [in] the DOM node to get an accessible for
|
||||
* @return the accessible for the given DOM node
|
||||
*/
|
||||
nsAccessible *GetAttachedAccessibleFor(nsINode *aNode);
|
||||
|
||||
/**
|
||||
* Return an DOM node that is relevant to attached accessible check. This
|
||||
* node is either from bindings chain if given node is anonymous and owner
|
||||
* binding denies accessible in anonymous content or given node (it's not
|
||||
* important whether it is accessible or not). This method doesn't create
|
||||
* accessible object for returned node.
|
||||
*
|
||||
* XXX: this method must go away once we'll implement correct accessible tree.
|
||||
*
|
||||
* @param aNode [in] the DOM node to get relevant content node
|
||||
* @return the DOM node for parent attached accessible
|
||||
*/
|
||||
nsINode *GetRelevantContentNodeFor(nsINode *aNode);
|
||||
nsAccessible* GetCachedContainerAccessible(nsINode *aNode);
|
||||
|
||||
/**
|
||||
* Initialize an accessible and cache it. The method should be called for
|
||||
|
@ -231,11 +227,30 @@ private:
|
|||
*/
|
||||
void Shutdown();
|
||||
|
||||
enum EWhatAccToGet {
|
||||
eGetAccForNode = 0x1,
|
||||
eGetAccForContainer = 0x2,
|
||||
eGetAccForNodeOrContainer = eGetAccForNode | eGetAccForContainer
|
||||
};
|
||||
|
||||
/**
|
||||
* Return accessible or accessible container for the given node in presshell.
|
||||
*/
|
||||
nsAccessible* GetAccessibleByRule(nsINode* aNode,
|
||||
nsIWeakReference* aWeakShell,
|
||||
EWhatAccToGet aWhatToGet);
|
||||
|
||||
/**
|
||||
* Return accessible for HTML area element associated with an image map.
|
||||
*
|
||||
* @param aImageFrame [in] image frame
|
||||
* @param aAreaNode [in] area node
|
||||
* @param aWeakShell [in] presshell of image frame
|
||||
* @param aImageAccessible [out, optional] image accessible, isn't addrefed
|
||||
*/
|
||||
nsAccessible* GetAreaAccessible(nsIFrame* aImageFrame, nsINode* aAreaNode,
|
||||
nsIWeakReference* aWeakShell);
|
||||
nsIWeakReference* aWeakShell,
|
||||
nsAccessible** aImageAccessible = nsnull);
|
||||
|
||||
/**
|
||||
* Create accessible for the element implementing nsIAccessibleProvider
|
||||
|
|
|
@ -813,16 +813,13 @@ nsAccessible::GetChildAtPoint(PRInt32 aX, PRInt32 aY, PRBool aDeepestChild,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsINode *relevantNode = GetAccService()->GetRelevantContentNodeFor(content);
|
||||
nsAccessible *accessible = GetAccService()->GetAccessible(relevantNode);
|
||||
// Get accessible for the node with the point or the first accessible in
|
||||
// the DOM parent chain.
|
||||
nsAccessible* accessible =
|
||||
GetAccService()->GetAccessibleOrContainer(content, mWeakShell);
|
||||
if (!accessible) {
|
||||
// No accessible for the node with the point, so find the first
|
||||
// accessible in the DOM parent chain
|
||||
accessible = GetAccService()->GetContainerAccessible(relevantNode, PR_TRUE);
|
||||
if (!accessible) {
|
||||
NS_IF_ADDREF(*aChild = fallbackAnswer);
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IF_ADDREF(*aChild = fallbackAnswer);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (accessible == this) {
|
||||
|
@ -1242,8 +1239,6 @@ nsresult
|
|||
nsAccessible::HandleAccEvent(nsAccEvent *aEvent)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aEvent);
|
||||
NS_ENSURE_TRUE(nsAccUtils::IsNodeRelevant(aEvent->GetNode()),
|
||||
NS_ERROR_FAILURE);
|
||||
|
||||
nsCOMPtr<nsIObserverService> obsService =
|
||||
mozilla::services::GetObserverService();
|
||||
|
@ -2675,22 +2670,7 @@ nsAccessible::Init()
|
|||
void *uniqueID = nsnull;
|
||||
GetUniqueID(&uniqueID);
|
||||
|
||||
if (!docAcc->CacheAccessible(uniqueID, this))
|
||||
return PR_FALSE;
|
||||
|
||||
// Make sure an ancestor in real content is cached so that
|
||||
// nsDocAccessible::RefreshNodes() can find the anonymous subtree to release
|
||||
// when the root node goes away. /Specific examples of where this is used:
|
||||
// <input type="file"> and <xul:findbar>.
|
||||
// XXX: remove this once we create correct accessible tree.
|
||||
if (mContent && mContent->IsInAnonymousSubtree()) {
|
||||
nsAccessible *parent = GetAccService()->GetContainerAccessible(mContent,
|
||||
PR_TRUE);
|
||||
if (parent)
|
||||
parent->EnsureChildren();
|
||||
}
|
||||
|
||||
return PR_TRUE;
|
||||
return docAcc->CacheAccessible(uniqueID, this);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -2779,31 +2759,33 @@ nsAccessible::InvalidateChildren()
|
|||
nsAccessible*
|
||||
nsAccessible::GetParent()
|
||||
{
|
||||
if (mParent)
|
||||
return mParent;
|
||||
|
||||
if (IsDefunct())
|
||||
return nsnull;
|
||||
|
||||
if (mParent)
|
||||
return mParent;
|
||||
// XXX: mParent can be null randomly because supposedly we get layout
|
||||
// notification and invalidate parent-child relations, this accessible stays
|
||||
// unattached. This should gone after bug 572951. Other reason is bug 574588
|
||||
// since CacheChildren() implementation calls nsAccessible::GetRole() what
|
||||
// can need to get a parent and we are here as result.
|
||||
NS_WARNING("Bad accessible tree!");
|
||||
|
||||
#ifdef DEBUG
|
||||
nsDocAccessible *docAccessible = GetDocAccessible();
|
||||
NS_ASSERTION(docAccessible, "No document accessible for valid accessible!");
|
||||
#endif
|
||||
|
||||
nsAccessible *parent = GetAccService()->GetContainerAccessible(mContent,
|
||||
PR_TRUE);
|
||||
nsAccessible* parent = GetAccService()->GetContainerAccessible(mContent,
|
||||
mWeakShell);
|
||||
NS_ASSERTION(parent, "No accessible parent for valid accessible!");
|
||||
if (!parent)
|
||||
return nsnull;
|
||||
|
||||
#ifdef DEBUG
|
||||
NS_ASSERTION(!parent->IsDefunct(), "Defunct parent!");
|
||||
|
||||
// Repair parent-child relations.
|
||||
parent->EnsureChildren();
|
||||
if (parent != mParent)
|
||||
NS_WARNING("Bad accessible tree!");
|
||||
#endif
|
||||
|
||||
NS_ASSERTION(parent == mParent, "Wrong children repair!");
|
||||
return parent;
|
||||
}
|
||||
|
||||
|
@ -2845,25 +2827,6 @@ nsAccessible::GetIndexInParent()
|
|||
return parent ? parent->GetIndexOf(this) : -1;
|
||||
}
|
||||
|
||||
nsAccessible*
|
||||
nsAccessible::GetCachedParent()
|
||||
{
|
||||
if (IsDefunct())
|
||||
return nsnull;
|
||||
|
||||
return mParent;
|
||||
}
|
||||
|
||||
nsAccessible*
|
||||
nsAccessible::GetCachedFirstChild()
|
||||
{
|
||||
if (IsDefunct())
|
||||
return nsnull;
|
||||
|
||||
return mChildren.SafeElementAt(0, nsnull);
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
PRBool
|
||||
nsAccessible::IsInCache()
|
||||
|
|
|
@ -235,7 +235,7 @@ public:
|
|||
/**
|
||||
* Return parent accessible.
|
||||
*/
|
||||
virtual nsAccessible* GetParent();
|
||||
nsAccessible* GetParent();
|
||||
|
||||
/**
|
||||
* Return child accessible at the given index.
|
||||
|
@ -263,14 +263,13 @@ public:
|
|||
PRBool HasChildren() { return !!GetChildAt(0); }
|
||||
|
||||
/**
|
||||
* Return parent accessible only if cached.
|
||||
* Return cached accessible of parent-child relatives.
|
||||
*/
|
||||
nsAccessible* GetCachedParent();
|
||||
nsAccessible* GetCachedParent() const { return mParent; }
|
||||
nsAccessible* GetCachedFirstChild() const
|
||||
{ return mChildren.SafeElementAt(0, nsnull); }
|
||||
|
||||
/**
|
||||
* Return first child accessible only if cached.
|
||||
*/
|
||||
nsAccessible* GetCachedFirstChild();
|
||||
PRBool AreChildrenCached() const { return mAreChildrenInitialized; }
|
||||
|
||||
#ifdef DEBUG
|
||||
/**
|
||||
|
|
|
@ -405,12 +405,6 @@ nsApplicationAccessible::GetStateInternal(PRUint32 *aState,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsAccessible*
|
||||
nsApplicationAccessible::GetParent()
|
||||
{
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
void
|
||||
nsApplicationAccessible::InvalidateChildren()
|
||||
{
|
||||
|
|
|
@ -113,7 +113,6 @@ public:
|
|||
virtual nsresult GetARIAState(PRUint32 *aState, PRUint32 *aExtraState);
|
||||
virtual nsresult GetRoleInternal(PRUint32 *aRole);
|
||||
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
|
||||
virtual nsAccessible* GetParent();
|
||||
|
||||
virtual void InvalidateChildren();
|
||||
virtual PRBool AppendChild(nsAccessible* aChild);
|
||||
|
|
|
@ -955,8 +955,6 @@ nsDocAccessible::AttributeChangedImpl(nsIContent* aContent, PRInt32 aNameSpaceID
|
|||
}
|
||||
|
||||
NS_ASSERTION(aContent, "No node for attr modified");
|
||||
if (!aContent || !nsAccUtils::IsNodeRelevant(aContent))
|
||||
return;
|
||||
|
||||
// Universal boolean properties that don't require a role. Fire the state
|
||||
// change when disabled or aria-disabled attribute is set.
|
||||
|
@ -1272,12 +1270,6 @@ nsDocAccessible::ParentChainChanged(nsIContent *aContent)
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsAccessible
|
||||
|
||||
nsAccessible*
|
||||
nsDocAccessible::GetParent()
|
||||
{
|
||||
return IsDefunct() ? nsnull : mParent.get();
|
||||
}
|
||||
|
||||
#ifdef DEBUG_ACCDOCMGR
|
||||
nsresult
|
||||
nsDocAccessible::HandleAccEvent(nsAccEvent *aAccEvent)
|
||||
|
@ -1513,17 +1505,18 @@ nsDocAccessible::ProcessPendingEvent(nsAccEvent *aEvent)
|
|||
|
||||
if (eventType == nsIAccessibleEvent::EVENT_SHOW) {
|
||||
|
||||
nsAccessible *containerAccessible = nsnull;
|
||||
if (accessible)
|
||||
nsAccessible* containerAccessible = nsnull;
|
||||
if (accessible) {
|
||||
containerAccessible = accessible->GetParent();
|
||||
|
||||
if (!containerAccessible) {
|
||||
} else {
|
||||
nsCOMPtr<nsIWeakReference> weakShell(nsCoreUtils::GetWeakShellFor(node));
|
||||
containerAccessible = GetAccService()->GetContainerAccessible(node,
|
||||
PR_TRUE);
|
||||
if (!containerAccessible)
|
||||
containerAccessible = this;
|
||||
weakShell);
|
||||
}
|
||||
|
||||
if (!containerAccessible)
|
||||
containerAccessible = this;
|
||||
|
||||
if (isAsync) {
|
||||
// For asynch show, delayed invalidatation of parent's children
|
||||
containerAccessible->InvalidateChildren();
|
||||
|
@ -1769,7 +1762,7 @@ nsDocAccessible::InvalidateCacheSubtree(nsIContent *aChild,
|
|||
// Just invalidate accessible hierarchy and return,
|
||||
// otherwise the page load time slows down way too much
|
||||
nsAccessible *containerAccessible =
|
||||
GetAccService()->GetContainerAccessible(childNode, PR_FALSE);
|
||||
GetAccService()->GetCachedContainerAccessible(childNode);
|
||||
if (!containerAccessible) {
|
||||
containerAccessible = this;
|
||||
}
|
||||
|
@ -1805,7 +1798,7 @@ nsDocAccessible::InvalidateCacheSubtree(nsIContent *aChild,
|
|||
#endif
|
||||
|
||||
nsAccessible *containerAccessible =
|
||||
GetAccService()->GetContainerAccessible(childNode, PR_TRUE);
|
||||
GetAccService()->GetCachedContainerAccessible(childNode);
|
||||
if (!containerAccessible) {
|
||||
containerAccessible = this;
|
||||
}
|
||||
|
@ -1950,7 +1943,7 @@ nsDocAccessible::FireShowHideEvents(nsINode *aNode,
|
|||
accessible = GetCachedAccessible(aNode);
|
||||
} else {
|
||||
// Allow creation of new accessibles for show events
|
||||
accessible = GetAccService()->GetAttachedAccessibleFor(aNode);
|
||||
accessible = GetAccService()->GetAccessible(aNode);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -113,7 +113,6 @@ public:
|
|||
virtual nsresult GetARIAState(PRUint32 *aState, PRUint32 *aExtraState);
|
||||
|
||||
virtual void SetRoleMapEntry(nsRoleMapEntry* aRoleMapEntry);
|
||||
virtual nsAccessible* GetParent();
|
||||
|
||||
#ifdef DEBUG_ACCDOCMGR
|
||||
virtual nsresult HandleAccEvent(nsAccEvent *aAccEvent);
|
||||
|
|
|
@ -458,37 +458,24 @@ nsRootAccessible::FireCurrentFocusEvent()
|
|||
if (IsDefunct())
|
||||
return;
|
||||
|
||||
// Simulate a focus event so that we can reuse code that fires focus for
|
||||
// container children like treeitems.
|
||||
nsCOMPtr<nsINode> focusedNode = GetCurrentFocus();
|
||||
if (!focusedNode) {
|
||||
return; // No current focus
|
||||
}
|
||||
|
||||
// Simulate a focus event so that we can reuse code that fires focus for container children like treeitems
|
||||
nsCOMPtr<nsIDOMDocumentEvent> docEvent = do_QueryInterface(mDocument);
|
||||
if (docEvent) {
|
||||
nsCOMPtr<nsIDOMEvent> event;
|
||||
if (NS_SUCCEEDED(docEvent->CreateEvent(NS_LITERAL_STRING("Events"),
|
||||
getter_AddRefs(event))) &&
|
||||
NS_SUCCEEDED(event->InitEvent(NS_LITERAL_STRING("focus"), PR_TRUE, PR_TRUE))) {
|
||||
// Get the target node we really want for the event.
|
||||
|
||||
nsINode *targetNode =
|
||||
GetAccService()->GetRelevantContentNodeFor(focusedNode);
|
||||
if (targetNode) {
|
||||
// If the focused element is document element or HTML body element
|
||||
// then simulate the focus event for the document.
|
||||
nsINode *document = targetNode->GetOwnerDoc();
|
||||
if (targetNode == nsCoreUtils::GetRoleContent(document)) {
|
||||
HandleEventWithTarget(event, document);
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise simulate the focus event for currently focused node.
|
||||
nsCOMPtr<nsIPrivateDOMEvent> privateEvent(do_QueryInterface(event));
|
||||
nsCOMPtr<nsIDOMEventTarget> target(do_QueryInterface(focusedNode));
|
||||
privateEvent->SetTarget(target);
|
||||
HandleEventWithTarget(event, targetNode);
|
||||
}
|
||||
nsCOMPtr<nsIPrivateDOMEvent> privateEvent(do_QueryInterface(event));
|
||||
nsCOMPtr<nsIDOMEventTarget> target(do_QueryInterface(focusedNode));
|
||||
privateEvent->SetTarget(target);
|
||||
HandleEvent(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -496,61 +483,42 @@ nsRootAccessible::FireCurrentFocusEvent()
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsIDOMEventListener
|
||||
|
||||
NS_IMETHODIMP nsRootAccessible::HandleEvent(nsIDOMEvent* aEvent)
|
||||
NS_IMETHODIMP
|
||||
nsRootAccessible::HandleEvent(nsIDOMEvent* aEvent)
|
||||
{
|
||||
// Turn DOM events in accessibility events
|
||||
// Get info about event and target
|
||||
nsCOMPtr<nsIDOMNode> targetNode;
|
||||
GetTargetNode(aEvent, getter_AddRefs(targetNode));
|
||||
if (!targetNode)
|
||||
return NS_ERROR_FAILURE;
|
||||
nsCOMPtr<nsIDOMNSEvent> nsevent(do_QueryInterface(aEvent));
|
||||
NS_ENSURE_STATE(nsevent);
|
||||
|
||||
nsCOMPtr<nsINode> node(do_QueryInterface(targetNode));
|
||||
return HandleEventWithTarget(aEvent, node);
|
||||
}
|
||||
nsCOMPtr<nsIDOMEventTarget> domEventTarget;
|
||||
nsevent->GetOriginalTarget(getter_AddRefs(domEventTarget));
|
||||
nsCOMPtr<nsINode> origTarget(do_QueryInterface(domEventTarget));
|
||||
NS_ENSURE_STATE(origTarget);
|
||||
|
||||
|
||||
// nsRootAccessible protected member
|
||||
nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent,
|
||||
nsINode* aTargetNode)
|
||||
{
|
||||
nsAutoString eventType;
|
||||
aEvent->GetType(eventType);
|
||||
nsAutoString localName;
|
||||
nsCOMPtr<nsIContent> targetContent(do_QueryInterface(aTargetNode));
|
||||
if (targetContent)
|
||||
targetContent->NodeInfo()->GetName(localName);
|
||||
#ifdef MOZ_XUL
|
||||
PRBool isTree = localName.EqualsLiteral("tree");
|
||||
#endif
|
||||
#ifdef DEBUG_A11Y
|
||||
// Very useful for debugging, please leave this here.
|
||||
if (eventType.EqualsLiteral("AlertActive")) {
|
||||
printf("\ndebugging %s events for %s", NS_ConvertUTF16toUTF8(eventType).get(), NS_ConvertUTF16toUTF8(localName).get());
|
||||
}
|
||||
if (localName.LowerCaseEqualsLiteral("textbox")) {
|
||||
printf("\ndebugging %s events for %s", NS_ConvertUTF16toUTF8(eventType).get(), NS_ConvertUTF16toUTF8(localName).get());
|
||||
}
|
||||
#endif
|
||||
|
||||
nsAccessibilityService *accService = GetAccService();
|
||||
NS_ENSURE_TRUE(accService, NS_ERROR_FAILURE);
|
||||
|
||||
nsCOMPtr<nsIWeakReference> weakShell =
|
||||
nsCoreUtils::GetWeakShellFor(aTargetNode);
|
||||
nsCoreUtils::GetWeakShellFor(origTarget);
|
||||
if (!weakShell)
|
||||
return NS_OK;
|
||||
|
||||
nsAccessible *accessible =
|
||||
accService->GetAccessibleInWeakShell(aTargetNode, weakShell);
|
||||
nsAccessible* accessible =
|
||||
GetAccService()->GetAccessibleOrContainer(origTarget, weakShell);
|
||||
|
||||
if (eventType.EqualsLiteral("popuphiding"))
|
||||
return HandlePopupHidingEvent(aTargetNode, accessible);
|
||||
return HandlePopupHidingEvent(origTarget, accessible);
|
||||
|
||||
if (!accessible)
|
||||
return NS_OK;
|
||||
|
||||
nsINode* targetNode = accessible->GetNode();
|
||||
nsIContent* targetContent = targetNode->IsElement() ?
|
||||
targetNode->AsElement() : nsnull;
|
||||
#ifdef MOZ_XUL
|
||||
PRBool isTree = targetContent ?
|
||||
targetContent->NodeInfo()->Equals(nsAccessibilityAtoms::tree,
|
||||
kNameSpaceID_XUL) : PR_FALSE;
|
||||
|
||||
if (isTree) {
|
||||
nsRefPtr<nsXULTreeAccessible> treeAcc = do_QueryObject(accessible);
|
||||
NS_ASSERTION(treeAcc,
|
||||
|
@ -587,7 +555,7 @@ nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent,
|
|||
nsEventShell::FireEvent(accEvent);
|
||||
|
||||
if (isEnabled)
|
||||
FireAccessibleFocusEvent(accessible, aTargetNode, aEvent);
|
||||
FireAccessibleFocusEvent(accessible, targetNode, aEvent);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -611,7 +579,7 @@ nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent,
|
|||
// If it's a tree element, need the currently selected item
|
||||
if (isTree) {
|
||||
nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelect =
|
||||
do_QueryInterface(aTargetNode);
|
||||
do_QueryInterface(targetNode);
|
||||
if (multiSelect) {
|
||||
PRInt32 treeIndex = -1;
|
||||
multiSelect->GetCurrentIndex(&treeIndex);
|
||||
|
@ -641,9 +609,9 @@ nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent,
|
|||
|
||||
if (treeItemAccessible && eventType.EqualsLiteral("select")) {
|
||||
// If multiselect tree, we should fire selectionadd or selection removed
|
||||
if (gLastFocusedNode == aTargetNode) {
|
||||
if (gLastFocusedNode == targetNode) {
|
||||
nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSel =
|
||||
do_QueryInterface(aTargetNode);
|
||||
do_QueryInterface(targetNode);
|
||||
nsAutoString selType;
|
||||
multiSel->GetSelType(selType);
|
||||
if (selType.IsEmpty() || !selType.EqualsLiteral("single")) {
|
||||
|
@ -664,7 +632,7 @@ nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent,
|
|||
else
|
||||
#endif
|
||||
if (eventType.EqualsLiteral("focus")) {
|
||||
if (aTargetNode == mDocument && mDocument != gLastFocusedNode) {
|
||||
if (targetNode == mDocument && mDocument != gLastFocusedNode) {
|
||||
// Got focus event for the window, we will make sure that an accessible
|
||||
// focus event for initial focus is fired. We do this on a short timer
|
||||
// because the initial focus may not have been set yet.
|
||||
|
@ -674,14 +642,13 @@ nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent,
|
|||
// Keep a reference to the target node. We might want to change
|
||||
// it to the individual radio button or selected item, and send
|
||||
// the focus event to that.
|
||||
nsCOMPtr<nsINode> focusedItem(aTargetNode);
|
||||
|
||||
nsCOMPtr<nsINode> focusedItem = targetNode;
|
||||
if (!treeItemAccessible) {
|
||||
nsCOMPtr<nsIDOMXULSelectControlElement> selectControl =
|
||||
do_QueryInterface(aTargetNode);
|
||||
do_QueryInterface(targetNode);
|
||||
if (selectControl) {
|
||||
nsCOMPtr<nsIDOMXULMenuListElement> menuList =
|
||||
do_QueryInterface(aTargetNode);
|
||||
do_QueryInterface(targetNode);
|
||||
if (!menuList) {
|
||||
// Don't do this for menu lists, the items only get focused
|
||||
// when the list is open, based on DOMMenuitemActive events
|
||||
|
@ -693,8 +660,8 @@ nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent,
|
|||
if (!focusedItem)
|
||||
return NS_OK;
|
||||
|
||||
accessible = accService->GetAccessibleInWeakShell(focusedItem,
|
||||
weakShell);
|
||||
accessible = GetAccService()->GetAccessibleInWeakShell(focusedItem,
|
||||
weakShell);
|
||||
if (!accessible)
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -756,9 +723,8 @@ nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent,
|
|||
}
|
||||
if (!fireFocus) {
|
||||
nsCOMPtr<nsINode> realFocusedNode = GetCurrentFocus();
|
||||
nsCOMPtr<nsIContent> realFocusedContent = do_QueryInterface(realFocusedNode);
|
||||
nsCOMPtr<nsIContent> targetContent = do_QueryInterface(aTargetNode);
|
||||
nsIContent *containerContent = targetContent;
|
||||
nsIContent* realFocusedContent = realFocusedNode->AsElement();
|
||||
nsIContent* containerContent = targetContent;
|
||||
while (containerContent) {
|
||||
nsCOMPtr<nsIDOMXULPopupElement> popup = do_QueryInterface(containerContent);
|
||||
if (popup || containerContent == realFocusedContent) {
|
||||
|
@ -772,7 +738,7 @@ nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent,
|
|||
}
|
||||
if (fireFocus) {
|
||||
// Always asynch, always from user input.
|
||||
FireAccessibleFocusEvent(accessible, aTargetNode, aEvent, PR_TRUE,
|
||||
FireAccessibleFocusEvent(accessible, targetNode, aEvent, PR_TRUE,
|
||||
PR_TRUE, eFromUserInput);
|
||||
}
|
||||
}
|
||||
|
@ -787,7 +753,7 @@ nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent,
|
|||
}
|
||||
else if (eventType.EqualsLiteral("ValueChange")) {
|
||||
FireDelayedAccessibleEvent(nsIAccessibleEvent::EVENT_VALUE_CHANGE,
|
||||
aTargetNode, nsAccEvent::eRemoveDupes);
|
||||
targetNode, nsAccEvent::eRemoveDupes);
|
||||
}
|
||||
#ifdef DEBUG
|
||||
else if (eventType.EqualsLiteral("mouseover")) {
|
||||
|
@ -798,31 +764,6 @@ nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
void nsRootAccessible::GetTargetNode(nsIDOMEvent *aEvent, nsIDOMNode **aTargetNode)
|
||||
{
|
||||
*aTargetNode = nsnull;
|
||||
|
||||
nsCOMPtr<nsIDOMNSEvent> nsevent(do_QueryInterface(aEvent));
|
||||
|
||||
if (!nsevent)
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIDOMEventTarget> domEventTarget;
|
||||
nsevent->GetOriginalTarget(getter_AddRefs(domEventTarget));
|
||||
nsCOMPtr<nsIDOMNode> eventTarget(do_QueryInterface(domEventTarget));
|
||||
if (!eventTarget)
|
||||
return;
|
||||
|
||||
nsIAccessibilityService* accService = GetAccService();
|
||||
if (accService) {
|
||||
nsresult rv = accService->GetRelevantContentNodeFor(eventTarget,
|
||||
aTargetNode);
|
||||
if (NS_SUCCEEDED(rv) && *aTargetNode)
|
||||
return;
|
||||
}
|
||||
|
||||
NS_ADDREF(*aTargetNode = eventTarget);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsAccessNode
|
||||
|
@ -932,17 +873,6 @@ nsRootAccessible::GetRelationByType(PRUint32 aRelationType,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsAccessible
|
||||
|
||||
nsAccessible*
|
||||
nsRootAccessible::GetParent()
|
||||
{
|
||||
// Parent has been set in nsApplicationAccesible::AppendChild() when root
|
||||
// accessible was initialized.
|
||||
return mParent;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Protected members
|
||||
|
||||
|
|
|
@ -87,7 +87,6 @@ public:
|
|||
// nsAccessible
|
||||
virtual nsresult GetRoleInternal(PRUint32 *aRole);
|
||||
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
|
||||
virtual nsAccessible* GetParent();
|
||||
|
||||
// nsRootAccessible
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ROOTACCESSIBLE_IMPL_CID)
|
||||
|
@ -126,19 +125,12 @@ protected:
|
|||
nsresult RemoveEventListeners();
|
||||
|
||||
/**
|
||||
* Process DOM events.
|
||||
*/
|
||||
nsresult HandleEventWithTarget(nsIDOMEvent* aEvent, nsINode* aTargetNode);
|
||||
|
||||
static void GetTargetNode(nsIDOMEvent *aEvent, nsIDOMNode **aTargetNode);
|
||||
|
||||
/**
|
||||
* Process "popupshown" event. Used by HandleEventWithTarget().
|
||||
* Process "popupshown" event. Used by HandleEvent().
|
||||
*/
|
||||
|
||||
nsresult HandlePopupShownEvent(nsAccessible *aAccessible);
|
||||
/*
|
||||
* Process "popuphiding" event. Used by HandleEventWithTarget().
|
||||
* Process "popuphiding" event. Used by HandleEvent().
|
||||
*/
|
||||
nsresult HandlePopupHidingEvent(nsINode *aNode, nsAccessible *aAccessible);
|
||||
|
||||
|
|
|
@ -371,6 +371,7 @@ nsHTMLSelectListAccessible::CacheChildren()
|
|||
void
|
||||
nsHTMLSelectListAccessible::CacheOptSiblings(nsIContent *aParentContent)
|
||||
{
|
||||
nsCOMPtr<nsIPresShell> presShell(do_QueryReferent(mWeakShell));
|
||||
PRUint32 numChildren = aParentContent->GetChildCount();
|
||||
for (PRUint32 count = 0; count < numChildren; count ++) {
|
||||
nsIContent *childContent = aParentContent->GetChildAt(count);
|
||||
|
@ -383,8 +384,9 @@ nsHTMLSelectListAccessible::CacheOptSiblings(nsIContent *aParentContent)
|
|||
tag == nsAccessibilityAtoms::optgroup) {
|
||||
|
||||
// Get an accessible for option or optgroup and cache it.
|
||||
nsAccessible *accessible =
|
||||
GetAccService()->GetAccessibleInWeakShell(childContent, mWeakShell);
|
||||
nsRefPtr<nsAccessible> accessible =
|
||||
GetAccService()->GetOrCreateAccessible(childContent, presShell,
|
||||
mWeakShell);
|
||||
if (accessible) {
|
||||
mChildren.AppendElement(accessible);
|
||||
accessible->SetParent(this);
|
||||
|
@ -932,11 +934,19 @@ nsHTMLComboboxAccessible::CacheChildren()
|
|||
if (!mListAccessible)
|
||||
return;
|
||||
|
||||
mListAccessible->Init();
|
||||
// Initialize and put into cache.
|
||||
if (!mListAccessible->Init()) {
|
||||
mListAccessible->Shutdown();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
mChildren.AppendElement(mListAccessible);
|
||||
mListAccessible->SetParent(this);
|
||||
|
||||
// Cache combobox option accessibles so that we build complete accessible tree
|
||||
// for combobox.
|
||||
mListAccessible->EnsureChildren();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1171,10 +1181,3 @@ void nsHTMLComboboxListAccessible::GetBoundsRect(nsRect& aBounds, nsIFrame** aBo
|
|||
*aBoundingFrame = frame->GetParent();
|
||||
aBounds = (*aBoundingFrame)->GetRect();
|
||||
}
|
||||
|
||||
// nsHTMLComboboxListAccessible. nsAccessible public mehtod
|
||||
nsAccessible*
|
||||
nsHTMLComboboxListAccessible::GetParent()
|
||||
{
|
||||
return mParent;
|
||||
}
|
||||
|
|
|
@ -276,7 +276,6 @@ public:
|
|||
// nsAccessible
|
||||
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
|
||||
virtual void GetBoundsRect(nsRect& aBounds, nsIFrame** aBoundingFrame);
|
||||
virtual nsAccessible* GetParent();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -347,12 +347,6 @@ nsHTMLListBulletAccessible::AppendTextTo(nsAString& aText, PRUint32 aStartOffset
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsAccessible*
|
||||
nsHTMLListBulletAccessible::GetParent()
|
||||
{
|
||||
return mParent;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsHTMLListAccessible
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -129,8 +129,6 @@ public:
|
|||
virtual nsresult AppendTextTo(nsAString& aText, PRUint32 aStartOffset,
|
||||
PRUint32 aLength);
|
||||
|
||||
virtual nsAccessible* GetParent();
|
||||
|
||||
protected:
|
||||
// XXX: Ideally we'd get the bullet text directly from the bullet frame via
|
||||
// nsBulletFrame::GetListItemText(), but we'd need an interface for getting
|
||||
|
|
|
@ -1681,7 +1681,7 @@ nsAccessibleWrap::FirePlatformEvent(nsAccEvent *aEvent)
|
|||
if (eventType == nsIAccessibleEvent::EVENT_HIDE) {
|
||||
// Don't use frame from current accessible when we're hiding that
|
||||
// accessible.
|
||||
newAccessible = accessible->GetParent();
|
||||
newAccessible = accessible->GetCachedParent();
|
||||
} else {
|
||||
newAccessible = accessible;
|
||||
}
|
||||
|
|
|
@ -118,6 +118,8 @@ nsXFormsAccessible::CacheSelectChildren(nsIDOMNode *aContainerNode)
|
|||
if (!children)
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIPresShell> presShell(do_QueryReferent(mWeakShell));
|
||||
|
||||
PRUint32 length = 0;
|
||||
children->GetLength(&length);
|
||||
|
||||
|
@ -128,7 +130,8 @@ nsXFormsAccessible::CacheSelectChildren(nsIDOMNode *aContainerNode)
|
|||
continue;
|
||||
|
||||
nsCOMPtr<nsIContent> child(do_QueryInterface(DOMChild));
|
||||
nsAccessible *accessible = GetAccService()->GetAttachedAccessibleFor(child);
|
||||
nsRefPtr<nsAccessible> accessible =
|
||||
GetAccService()->GetOrCreateAccessible(child, presShell, mWeakShell);
|
||||
if (!accessible)
|
||||
continue;
|
||||
|
||||
|
|
|
@ -166,6 +166,8 @@ nsXULColorPickerAccessible::CacheChildren()
|
|||
|
||||
nsRefPtr<nsAccessible> child;
|
||||
while ((child = walker.GetNextChild())) {
|
||||
// XXX: do not call nsAccessible::GetRole() while accessible not in tree
|
||||
// (bug 574588).
|
||||
PRUint32 role = nsAccUtils::Role(child);
|
||||
|
||||
// Get an accessbile for menupopup or panel elements.
|
||||
|
|
|
@ -212,6 +212,8 @@ nsXULButtonAccessible::CacheChildren()
|
|||
|
||||
nsRefPtr<nsAccessible> child;
|
||||
while ((child = walker.GetNextChild())) {
|
||||
// XXX: do not call nsAccessible::GetRole() while accessible not in tree
|
||||
// (bug 574588).
|
||||
PRUint32 role = nsAccUtils::Role(child);
|
||||
|
||||
if (role == nsIAccessibleRole::ROLE_MENUPOPUP) {
|
||||
|
|
|
@ -1040,12 +1040,6 @@ nsXULTreeItemAccessibleBase::GetStateInternal(PRUint32 *aState,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsAccessible*
|
||||
nsXULTreeItemAccessibleBase::GetParent()
|
||||
{
|
||||
return IsDefunct() ? nsnull : mParent.get();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsXULTreeItemAccessibleBase: nsAccessible protected methods
|
||||
|
||||
|
|
|
@ -199,7 +199,6 @@ public:
|
|||
|
||||
// nsAccessible
|
||||
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
|
||||
virtual nsAccessible* GetParent();
|
||||
|
||||
// nsXULTreeItemAccessibleBase
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_XULTREEITEMBASEACCESSIBLE_IMPL_CID)
|
||||
|
|
|
@ -1202,12 +1202,6 @@ nsXULTreeGridCellAccessible::GetStateInternal(PRUint32 *aStates,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsAccessible*
|
||||
nsXULTreeGridCellAccessible::GetParent()
|
||||
{
|
||||
return IsDefunct() ? nsnull : mParent.get();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsXULTreeGridCellAccessible: public implementation
|
||||
|
||||
|
|
|
@ -162,8 +162,6 @@ public:
|
|||
virtual nsresult GetRoleInternal(PRUint32 *aRole);
|
||||
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
|
||||
|
||||
virtual nsAccessible* GetParent();
|
||||
|
||||
// nsXULTreeGridCellAccessible
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_XULTREEGRIDCELLACCESSIBLE_IMPL_CID)
|
||||
|
||||
|
|
|
@ -127,6 +127,11 @@
|
|||
try {
|
||||
docAcc = docAcc.parent;
|
||||
} catch (e) {
|
||||
// XXX: it may randomaly fail on propertypage accessible of browser's
|
||||
// tabbbrowser if nsIAccessible::parent returns cached parent only.
|
||||
// This should gone after bug 572951.
|
||||
// Error: failed | Can't get parent for [ 'panel1277435313424' ,
|
||||
// role: propertypage]
|
||||
ok(false, "Can't get parent for " + prettyName(docAcc));
|
||||
throw e;
|
||||
}
|
||||
|
|
|
@ -61,6 +61,7 @@
|
|||
this.invoke = function removeChildSpan_invoke()
|
||||
{
|
||||
// remove HTML span, a first child of the node
|
||||
ensureAccessibleTree(this.DOMNode);
|
||||
this.DOMNode.removeChild(this.DOMNode.firstChild);
|
||||
}
|
||||
|
||||
|
|
|
@ -384,8 +384,7 @@ inDOMView::GetCellProperties(PRInt32 row, nsITreeColumn* col, nsISupportsArray *
|
|||
|
||||
nsCOMPtr<nsIAccessible> accessible;
|
||||
nsresult rv =
|
||||
accService->GetAttachedAccessibleFor(node->node,
|
||||
getter_AddRefs(accessible));
|
||||
accService->GetAccessibleFor(node->node, getter_AddRefs(accessible));
|
||||
if (NS_SUCCEEDED(rv) && accessible)
|
||||
properties->AppendElement(kAccessibleNodeAtom);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче