Bug 461922 - remove nsPIAccessibleDocument, r=marcoz, davidb, sr=neil

This commit is contained in:
Alexander Surkov 2009-06-25 10:08:53 +08:00
Родитель a9bdf35f91
Коммит e270dfb411
13 изменённых файлов: 267 добавлений и 228 удалений

Просмотреть файл

@ -59,7 +59,6 @@ XPIDLSRCS = \
nsIAccessibleRole.idl \ nsIAccessibleRole.idl \
nsIAccessibleStates.idl \ nsIAccessibleStates.idl \
nsIAccessibleDocument.idl \ nsIAccessibleDocument.idl \
nsPIAccessibleDocument.idl \
nsIAccessibleProvider.idl \ nsIAccessibleProvider.idl \
nsIAccessibleSelectable.idl \ nsIAccessibleSelectable.idl \
nsIAccessNode.idl \ nsIAccessNode.idl \

Просмотреть файл

@ -1,67 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 2003
* the Initial Developer. All Rights Reserved.
*
* Original Author: Aaron Leventhal (aaronl@netscape.com)
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
interface nsIAccessNode;
interface nsIContent;
[uuid(fa9cafac-9562-49ad-afcf-911ab1e4e4fb)]
interface nsPIAccessibleDocument : nsISupports
{
/**
* Find the accessible object in the accessibility cache that
* corresponds to aStartNode or the first ancestor of aStartNode
* that has an accessible object associated with it.
* Clear that accessible object's parent's cache of accessible children and
* and remove the accessible object and any decendents from the accessible cache.
* New accessible objects will be created and cached again on demand.
* @param aChangeContent The child that is changing
* @param aEvent The event from nsIAccessibleEvent that caused the change:
* Must be one of: EVENT_REORDER (change),
* EVENT_SHOW (make visible or create) or
* EVENT_HIDE (destroy or hide)
*/
void invalidateCacheSubtree(in nsIContent aChangeContent,
in PRUint32 aChangeEvent);
void cacheAccessNode(in voidPtr aUniqueID, in nsIAccessNode aAccessNode);
void flushPendingEvents();
void fireDocLoadEvents(in PRUint32 aEventType);
void fireAnchorJumpEvent();
};

Просмотреть файл

@ -45,6 +45,7 @@
#include "nsAccessibleEventData.h" #include "nsAccessibleEventData.h"
#include "nsHyperTextAccessible.h" #include "nsHyperTextAccessible.h"
#include "nsHTMLTableAccessible.h" #include "nsHTMLTableAccessible.h"
#include "nsDocAccessible.h"
#include "nsAccessibilityAtoms.h" #include "nsAccessibilityAtoms.h"
#include "nsAccessibleTreeWalker.h" #include "nsAccessibleTreeWalker.h"
#include "nsAccessible.h" #include "nsAccessible.h"
@ -747,6 +748,26 @@ nsAccUtils::QueryAccessibleTable(nsIAccessibleTable *aAccessibleTable)
return accessible; return accessible;
} }
already_AddRefed<nsDocAccessible>
nsAccUtils::QueryAccessibleDocument(nsIAccessible *aAccessible)
{
nsDocAccessible* accessible = nsnull;
if (aAccessible)
CallQueryInterface(aAccessible, &accessible);
return accessible;
}
already_AddRefed<nsDocAccessible>
nsAccUtils::QueryAccessibleDocument(nsIAccessibleDocument *aAccessibleDocument)
{
nsDocAccessible* accessible = nsnull;
if (aAccessibleDocument)
CallQueryInterface(aAccessibleDocument, &accessible);
return accessible;
}
#ifdef DEBUG_A11Y #ifdef DEBUG_A11Y
PRBool PRBool

Просмотреть файл

@ -55,6 +55,7 @@
class nsAccessNode; class nsAccessNode;
class nsAccessible; class nsAccessible;
class nsHTMLTableAccessible; class nsHTMLTableAccessible;
class nsDocAccessible;
class nsAccUtils class nsAccUtils
{ {
@ -340,7 +341,19 @@ public:
*/ */
static already_AddRefed<nsHTMLTableAccessible> static already_AddRefed<nsHTMLTableAccessible>
QueryAccessibleTable(nsIAccessibleTable *aAccessibleTable); QueryAccessibleTable(nsIAccessibleTable *aAccessibleTable);
/**
* Query nsDocAccessible from the given nsIAccessible.
*/
static already_AddRefed<nsDocAccessible>
QueryAccessibleDocument(nsIAccessible *aAccessible);
/**
* Query nsDocAccessible from the given nsIAccessibleDocument.
*/
static already_AddRefed<nsDocAccessible>
QueryAccessibleDocument(nsIAccessibleDocument *aAccessibleDocument);
#ifdef DEBUG_A11Y #ifdef DEBUG_A11Y
/** /**
* Detect whether the given accessible object implements nsIAccessibleText, * Detect whether the given accessible object implements nsIAccessibleText,

Просмотреть файл

@ -42,7 +42,6 @@
#include "nsHashtable.h" #include "nsHashtable.h"
#include "nsIAccessibilityService.h" #include "nsIAccessibilityService.h"
#include "nsIAccessibleDocument.h" #include "nsIAccessibleDocument.h"
#include "nsPIAccessibleDocument.h"
#include "nsIDocShell.h" #include "nsIDocShell.h"
#include "nsIDocShellTreeItem.h" #include "nsIDocShellTreeItem.h"
#include "nsIDocument.h" #include "nsIDocument.h"
@ -192,10 +191,10 @@ nsAccessNode::Init()
void* uniqueID; void* uniqueID;
GetUniqueID(&uniqueID); GetUniqueID(&uniqueID);
nsCOMPtr<nsPIAccessibleDocument> privateDocAccessible = nsRefPtr<nsDocAccessible> docAcc =
do_QueryInterface(docAccessible); nsAccUtils::QueryAccessibleDocument(docAccessible);
NS_ASSERTION(privateDocAccessible, "No private docaccessible for docaccessible"); NS_ASSERTION(docAcc, "No nsDocAccessible for document accessible!");
privateDocAccessible->CacheAccessNode(uniqueID, this); docAcc->CacheAccessNode(uniqueID, this);
// Make sure an ancestor in real content is cached // Make sure an ancestor in real content is cached
// so that nsDocAccessible::RefreshNodes() can find the anonymous subtree to release when // so that nsDocAccessible::RefreshNodes() can find the anonymous subtree to release when

Просмотреть файл

@ -43,8 +43,7 @@
* This class wraps up the creation (and destruction) of the standard * This class wraps up the creation (and destruction) of the standard
* set of atoms used in the accessibility module. These objects * set of atoms used in the accessibility module. These objects
* are created when the are needed by accessibility is being used and they * are created when the are needed by accessibility is being used and they
* are destroyed when the last nsRootAccessible is destroyed via * are destroyed when the last nsRootAccessible is destroyed.
* nsRootAccessible::ShutdownAll()
*/ */
class nsAccessibilityAtoms { class nsAccessibilityAtoms {

Просмотреть файл

@ -242,9 +242,11 @@ NS_IMETHODIMP nsAccessibilityService::ProcessDocLoadEvent(nsITimer *aTimer, void
nsCOMPtr<nsIAccessible> accessible; nsCOMPtr<nsIAccessible> accessible;
GetAccessibleFor(docNode, getter_AddRefs(accessible)); GetAccessibleFor(docNode, getter_AddRefs(accessible));
nsCOMPtr<nsPIAccessibleDocument> privDocAccessible = do_QueryInterface(accessible); nsRefPtr<nsDocAccessible> docAcc =
NS_ENSURE_STATE(privDocAccessible); nsAccUtils::QueryAccessibleDocument(accessible);
privDocAccessible->FireDocLoadEvents(aEventType); NS_ENSURE_STATE(docAcc);
docAcc->FireDocLoadEvents(aEventType);
return NS_OK; return NS_OK;
} }
@ -307,12 +309,12 @@ NS_IMETHODIMP nsAccessibilityService::OnLocationChange(nsIWebProgress *aWebProgr
nsCOMPtr<nsIAccessibleDocument> accessibleDoc = nsCOMPtr<nsIAccessibleDocument> accessibleDoc =
nsAccessNode::GetDocAccessibleFor(domDocRootNode); nsAccessNode::GetDocAccessibleFor(domDocRootNode);
nsCOMPtr<nsPIAccessibleDocument> privateAccessibleDoc = nsRefPtr<nsDocAccessible> docAcc =
do_QueryInterface(accessibleDoc); nsAccUtils::QueryAccessibleDocument(accessibleDoc);
if (!privateAccessibleDoc) { if (docAcc)
return NS_OK; docAcc->FireAnchorJumpEvent();
}
return privateAccessibleDoc->FireAnchorJumpEvent(); return NS_OK;
} }
/* void onStatusChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsresult aStatus, in wstring aMessage); */ /* void onStatusChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsresult aStatus, in wstring aMessage); */
@ -2040,12 +2042,12 @@ NS_IMETHODIMP nsAccessibilityService::InvalidateSubtreeFor(nsIPresShell *aShell,
NS_ENSURE_ARG_POINTER(aShell); NS_ENSURE_ARG_POINTER(aShell);
nsCOMPtr<nsIAccessibleDocument> accessibleDoc = nsCOMPtr<nsIAccessibleDocument> accessibleDoc =
nsAccessNode::GetDocAccessibleFor(aShell->GetDocument()); nsAccessNode::GetDocAccessibleFor(aShell->GetDocument());
nsCOMPtr<nsPIAccessibleDocument> privateAccessibleDoc = nsRefPtr<nsDocAccessible> docAcc =
do_QueryInterface(accessibleDoc); nsAccUtils::QueryAccessibleDocument(accessibleDoc);
if (!privateAccessibleDoc) { if (docAcc)
return NS_OK; docAcc->InvalidateCacheSubtree(aChangeContent, aEvent);
}
return privateAccessibleDoc->InvalidateCacheSubtree(aChangeContent, aEvent); return NS_OK;
} }
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////

Просмотреть файл

@ -150,6 +150,18 @@ ElementTraverser(const void *aKey, nsIAccessNode *aAccessNode,
return PL_DHASH_NEXT; return PL_DHASH_NEXT;
} }
// What we want is: NS_INTERFACE_MAP_ENTRY(self) for static IID accessors,
// but some of our classes have an ambiguous base class of nsISupports which
// prevents this from working (the default macro converts it to nsISupports,
// then addrefs it, then returns it). Therefore, we expand the macro here and
// change it so that it works. Yuck.
#define NS_INTERFACE_MAP_STATIC_AMBIGUOUS(_class) \
if (aIID.Equals(NS_GET_IID(_class))) { \
NS_ADDREF(this); \
*aInstancePtr = this; \
return NS_OK; \
} else
NS_IMPL_CYCLE_COLLECTION_CLASS(nsDocAccessible) NS_IMPL_CYCLE_COLLECTION_CLASS(nsDocAccessible)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsDocAccessible, nsAccessible) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsDocAccessible, nsAccessible)
@ -163,14 +175,14 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsDocAccessible, nsAccessible)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsDocAccessible) NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsDocAccessible)
NS_INTERFACE_MAP_STATIC_AMBIGUOUS(nsDocAccessible)
NS_INTERFACE_MAP_ENTRY(nsIAccessibleDocument) NS_INTERFACE_MAP_ENTRY(nsIAccessibleDocument)
NS_INTERFACE_MAP_ENTRY(nsPIAccessibleDocument)
NS_INTERFACE_MAP_ENTRY(nsIDocumentObserver) NS_INTERFACE_MAP_ENTRY(nsIDocumentObserver)
NS_INTERFACE_MAP_ENTRY(nsIMutationObserver) NS_INTERFACE_MAP_ENTRY(nsIMutationObserver)
NS_INTERFACE_MAP_ENTRY(nsIScrollPositionListener) NS_INTERFACE_MAP_ENTRY(nsIScrollPositionListener)
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIAccessibleDocument)
NS_INTERFACE_MAP_ENTRY(nsIObserver) NS_INTERFACE_MAP_ENTRY(nsIObserver)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIAccessibleDocument)
NS_INTERFACE_MAP_END_INHERITING(nsHyperTextAccessible) NS_INTERFACE_MAP_END_INHERITING(nsHyperTextAccessible)
NS_IMPL_ADDREF_INHERITED(nsDocAccessible, nsHyperTextAccessible) NS_IMPL_ADDREF_INHERITED(nsDocAccessible, nsHyperTextAccessible)
@ -553,7 +565,7 @@ NS_IMETHODIMP nsDocAccessible::GetCachedAccessNode(void *aUniqueID, nsIAccessNod
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP void
nsDocAccessible::CacheAccessNode(void *aUniqueID, nsIAccessNode *aAccessNode) nsDocAccessible::CacheAccessNode(void *aUniqueID, nsIAccessNode *aAccessNode)
{ {
// If there is an access node for the given unique ID then let's shutdown it. // If there is an access node for the given unique ID then let's shutdown it.
@ -568,7 +580,6 @@ nsDocAccessible::CacheAccessNode(void *aUniqueID, nsIAccessNode *aAccessNode)
} }
PutCacheEntry(mAccessNodeCache, aUniqueID, aAccessNode); PutCacheEntry(mAccessNodeCache, aUniqueID, aAccessNode);
return NS_OK;
} }
NS_IMETHODIMP nsDocAccessible::GetParent(nsIAccessible **aParent) NS_IMETHODIMP nsDocAccessible::GetParent(nsIAccessible **aParent)
@ -692,6 +703,15 @@ nsDocAccessible::GetFrame()
return root; return root;
} }
PRBool
nsDocAccessible::IsDefunct()
{
if (nsHyperTextAccessibleWrap::IsDefunct())
return PR_TRUE;
return !mDocument;
}
void nsDocAccessible::GetBoundsRect(nsRect& aBounds, nsIFrame** aRelativeFrame) void nsDocAccessible::GetBoundsRect(nsRect& aBounds, nsIFrame** aRelativeFrame)
{ {
*aRelativeFrame = GetFrame(); *aRelativeFrame = GetFrame();
@ -822,11 +842,12 @@ nsresult nsDocAccessible::RemoveEventListeners()
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP nsDocAccessible::FireAnchorJumpEvent() void
nsDocAccessible::FireAnchorJumpEvent()
{ {
if (!mIsContentLoaded || !mDocument) { if (!mIsContentLoaded || !mDocument)
return NS_OK; return;
}
nsCOMPtr<nsISupports> container = mDocument->GetContainer(); nsCOMPtr<nsISupports> container = mDocument->GetContainer();
nsCOMPtr<nsIWebNavigation> webNav(do_GetInterface(container)); nsCOMPtr<nsIWebNavigation> webNav(do_GetInterface(container));
nsCAutoString theURL; nsCAutoString theURL;
@ -854,15 +875,13 @@ NS_IMETHODIMP nsDocAccessible::FireAnchorJumpEvent()
mIsAnchorJumped = PR_TRUE; mIsAnchorJumped = PR_TRUE;
lastAnchor.Assign(currentAnchor); lastAnchor.Assign(currentAnchor);
} }
return NS_OK;
} }
NS_IMETHODIMP nsDocAccessible::FireDocLoadEvents(PRUint32 aEventType) void
nsDocAccessible::FireDocLoadEvents(PRUint32 aEventType)
{ {
if (!mDocument || !mWeakShell) { if (IsDefunct())
return NS_OK; // Document has been shut down return;
}
PRBool isFinished = PRBool isFinished =
(aEventType == nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE || (aEventType == nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE ||
@ -871,15 +890,16 @@ NS_IMETHODIMP nsDocAccessible::FireDocLoadEvents(PRUint32 aEventType)
mIsContentLoaded = isFinished; mIsContentLoaded = isFinished;
if (isFinished) { if (isFinished) {
if (mIsLoadCompleteFired) if (mIsLoadCompleteFired)
return NS_OK; return;
mIsLoadCompleteFired = PR_TRUE; mIsLoadCompleteFired = PR_TRUE;
} }
nsCOMPtr<nsIDocShellTreeItem> treeItem = nsCOMPtr<nsIDocShellTreeItem> treeItem =
nsCoreUtils::GetDocShellTreeItemFor(mDOMNode); nsCoreUtils::GetDocShellTreeItemFor(mDOMNode);
if (!treeItem) { if (!treeItem)
return NS_OK; return;
}
nsCOMPtr<nsIDocShellTreeItem> sameTypeRoot; nsCOMPtr<nsIDocShellTreeItem> sameTypeRoot;
treeItem->GetSameTypeRootTreeItem(getter_AddRefs(sameTypeRoot)); treeItem->GetSameTypeRootTreeItem(getter_AddRefs(sameTypeRoot));
@ -928,7 +948,6 @@ NS_IMETHODIMP nsDocAccessible::FireDocLoadEvents(PRUint32 aEventType)
nsAccUtils::FireAccEvent(aEventType, this); nsAccUtils::FireAccEvent(aEventType, this);
} }
return NS_OK;
} }
void nsDocAccessible::ScrollTimerCallback(nsITimer *aTimer, void *aClosure) void nsDocAccessible::ScrollTimerCallback(nsITimer *aTimer, void *aClosure)
@ -1569,14 +1588,14 @@ nsDocAccessible::FireDelayedAccessibleEvent(nsIAccessibleEvent *aEvent)
// so that event gets fired via FlushEventsCallback // so that event gets fired via FlushEventsCallback
NS_ADDREF_THIS(); // Kung fu death grip to prevent crash in callback NS_ADDREF_THIS(); // Kung fu death grip to prevent crash in callback
mFireEventTimer->InitWithFuncCallback(FlushEventsCallback, mFireEventTimer->InitWithFuncCallback(FlushEventsCallback,
static_cast<nsPIAccessibleDocument*>(this), this, 0, nsITimer::TYPE_ONE_SHOT);
0, nsITimer::TYPE_ONE_SHOT);
} }
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP nsDocAccessible::FlushPendingEvents() void
nsDocAccessible::FlushPendingEvents()
{ {
mInFlushPendingEvents = PR_TRUE; mInFlushPendingEvents = PR_TRUE;
PRUint32 length = mEventsToFire.Count(); PRUint32 length = mEventsToFire.Count();
@ -1685,12 +1704,12 @@ NS_IMETHODIMP nsDocAccessible::FlushPendingEvents()
if (accessible) { if (accessible) {
if (eventType == nsIAccessibleEvent::EVENT_INTERNAL_LOAD) { if (eventType == nsIAccessibleEvent::EVENT_INTERNAL_LOAD) {
nsCOMPtr<nsPIAccessibleDocument> docAccessible = nsRefPtr<nsDocAccessible> docAcc =
do_QueryInterface(accessible); nsAccUtils::QueryAccessibleDocument(accessible);
NS_ASSERTION(docAccessible, "No doc accessible for doc load event"); NS_ASSERTION(docAcc, "No doc accessible for doc load event");
if (docAccessible) {
docAccessible->FireDocLoadEvents(nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE); if (docAcc)
} docAcc->FireDocLoadEvents(nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE);
} }
else if (eventType == nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED) { else if (eventType == nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED) {
nsCOMPtr<nsIAccessibleText> accessibleText = do_QueryInterface(accessible); nsCOMPtr<nsIAccessibleText> accessibleText = do_QueryInterface(accessible);
@ -1759,12 +1778,11 @@ NS_IMETHODIMP nsDocAccessible::FlushPendingEvents()
nsAccEvent::ResetLastInputState(); nsAccEvent::ResetLastInputState();
mInFlushPendingEvents = PR_FALSE; mInFlushPendingEvents = PR_FALSE;
return NS_OK;
} }
void nsDocAccessible::FlushEventsCallback(nsITimer *aTimer, void *aClosure) void nsDocAccessible::FlushEventsCallback(nsITimer *aTimer, void *aClosure)
{ {
nsPIAccessibleDocument *accessibleDoc = static_cast<nsPIAccessibleDocument*>(aClosure); nsDocAccessible *accessibleDoc = static_cast<nsDocAccessible*>(aClosure);
NS_ASSERTION(accessibleDoc, "How did we get here without an accessible document?"); NS_ASSERTION(accessibleDoc, "How did we get here without an accessible document?");
if (accessibleDoc) { if (accessibleDoc) {
// A lot of crashes were happening here, so now we're reffing the doc // A lot of crashes were happening here, so now we're reffing the doc
@ -1880,8 +1898,9 @@ void nsDocAccessible::RefreshNodes(nsIDOMNode *aStartNode)
mAccessNodeCache.Remove(uniqueID); mAccessNodeCache.Remove(uniqueID);
} }
NS_IMETHODIMP nsDocAccessible::InvalidateCacheSubtree(nsIContent *aChild, void
PRUint32 aChangeEventType) nsDocAccessible::InvalidateCacheSubtree(nsIContent *aChild,
PRUint32 aChangeEventType)
{ {
PRBool isHiding = PRBool isHiding =
aChangeEventType == nsIAccessibleEvent::EVENT_ASYNCH_HIDE || aChangeEventType == nsIAccessibleEvent::EVENT_ASYNCH_HIDE ||
@ -1908,11 +1927,12 @@ NS_IMETHODIMP nsDocAccessible::InvalidateCacheSubtree(nsIContent *aChild,
// instead of just the accessible tree, although that would be faster // instead of just the accessible tree, although that would be faster
// Otherwise we might miss the nsAccessNode's that are not nsAccessible's. // Otherwise we might miss the nsAccessNode's that are not nsAccessible's.
NS_ENSURE_TRUE(mDOMNode, NS_ERROR_FAILURE); NS_ENSURE_TRUE(mDOMNode,);
nsCOMPtr<nsIDOMNode> childNode = aChild ? do_QueryInterface(aChild) : mDOMNode; nsCOMPtr<nsIDOMNode> childNode = aChild ? do_QueryInterface(aChild) : mDOMNode;
nsCOMPtr<nsIPresShell> presShell = GetPresShell(); nsCOMPtr<nsIPresShell> presShell = GetPresShell();
NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE); NS_ENSURE_TRUE(presShell,);
if (!mIsContentLoaded) { if (!mIsContentLoaded) {
// Still loading document // Still loading document
@ -1925,10 +1945,12 @@ NS_IMETHODIMP nsDocAccessible::InvalidateCacheSubtree(nsIContent *aChild,
// Leave early, and ensure mAccChildCount stays uninitialized instead of 0, // Leave early, and ensure mAccChildCount stays uninitialized instead of 0,
// which it is if anyone asks for its children right now. // which it is if anyone asks for its children right now.
InvalidateChildren(); InvalidateChildren();
return NS_OK; return;
} }
nsIEventStateManager *esm = presShell->GetPresContext()->EventStateManager(); nsIEventStateManager *esm = presShell->GetPresContext()->EventStateManager();
NS_ENSURE_TRUE(esm, NS_ERROR_FAILURE); NS_ENSURE_TRUE(esm,);
if (!esm->IsHandlingUserInputExternal()) { if (!esm->IsHandlingUserInputExternal()) {
// Changes during page load, but not caused by user input // Changes during page load, but not caused by user input
// Just invalidate accessible hierarchy and return, // Just invalidate accessible hierarchy and return,
@ -1942,7 +1964,7 @@ NS_IMETHODIMP nsDocAccessible::InvalidateCacheSubtree(nsIContent *aChild,
nsRefPtr<nsAccessible> containerAcc = nsRefPtr<nsAccessible> containerAcc =
nsAccUtils::QueryAccessible(containerAccessible); nsAccUtils::QueryAccessible(containerAccessible);
containerAcc->InvalidateChildren(); containerAcc->InvalidateChildren();
return NS_OK; return;
} }
// else: user input, so we must fall through and for full handling, // else: user input, so we must fall through and for full handling,
// e.g. fire the mutation events. Note: user input could cause DOM_CREATE // e.g. fire the mutation events. Note: user input could cause DOM_CREATE
@ -1998,7 +2020,7 @@ NS_IMETHODIMP nsDocAccessible::InvalidateCacheSubtree(nsIContent *aChild,
// This often happens when visibility is cleared for node, // This often happens when visibility is cleared for node,
// which hides an entire subtree -- we get notified for each // which hides an entire subtree -- we get notified for each
// node in the subtree and need to collate the hide events ourselves. // node in the subtree and need to collate the hide events ourselves.
return NS_OK; return;
} }
} }
} }
@ -2010,7 +2032,8 @@ NS_IMETHODIMP nsDocAccessible::InvalidateCacheSubtree(nsIContent *aChild,
// Fire an event if the accessible existed for node being hidden, otherwise // Fire an event if the accessible existed for node being hidden, otherwise
// for the first line accessible descendants. Fire before the accessible(s) away. // for the first line accessible descendants. Fire before the accessible(s) away.
nsresult rv = FireShowHideEvents(childNode, PR_FALSE, removalEventType, PR_TRUE, PR_FALSE); nsresult rv = FireShowHideEvents(childNode, PR_FALSE, removalEventType, PR_TRUE, PR_FALSE);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv,);
if (childNode != mDOMNode) { // Fire text change unless the node being removed is for this doc if (childNode != mDOMNode) { // Fire text change unless the node being removed is for this doc
// When a node is hidden or removed, the text in an ancestor hyper text will lose characters // When a node is hidden or removed, the text in an ancestor hyper text will lose characters
// At this point we still have the frame and accessible for this node if there was one // At this point we still have the frame and accessible for this node if there was one
@ -2102,11 +2125,9 @@ NS_IMETHODIMP nsDocAccessible::InvalidateCacheSubtree(nsIContent *aChild,
new nsAccReorderEvent(containerAccessible, isAsynch, new nsAccReorderEvent(containerAccessible, isAsynch,
isUnconditionalEvent, isUnconditionalEvent,
aChild ? childNode.get() : nsnull); aChild ? childNode.get() : nsnull);
NS_ENSURE_TRUE(reorderEvent, NS_ERROR_OUT_OF_MEMORY); NS_ENSURE_TRUE(reorderEvent,);
FireDelayedAccessibleEvent(reorderEvent); FireDelayedAccessibleEvent(reorderEvent);
return NS_OK;
} }
NS_IMETHODIMP NS_IMETHODIMP

Просмотреть файл

@ -41,7 +41,6 @@
#include "nsHyperTextAccessibleWrap.h" #include "nsHyperTextAccessibleWrap.h"
#include "nsIAccessibleDocument.h" #include "nsIAccessibleDocument.h"
#include "nsPIAccessibleDocument.h"
#include "nsIDocument.h" #include "nsIDocument.h"
#include "nsIDocumentObserver.h" #include "nsIDocumentObserver.h"
#include "nsIEditor.h" #include "nsIEditor.h"
@ -56,9 +55,16 @@ class nsIScrollableView;
const PRUint32 kDefaultCacheSize = 256; const PRUint32 kDefaultCacheSize = 256;
#define NS_DOCACCESSIBLE_IMPL_CID \
{ /* 0ed1be1d-52a7-4bfd-b4f5-0de7caed4617 */ \
0x0ed1be1d, \
0x52a7, \
0x4bfd, \
{ 0xb4, 0xf5, 0x0d, 0xe7, 0xca, 0xed, 0x46, 0x17 } \
}
class nsDocAccessible : public nsHyperTextAccessibleWrap, class nsDocAccessible : public nsHyperTextAccessibleWrap,
public nsIAccessibleDocument, public nsIAccessibleDocument,
public nsPIAccessibleDocument,
public nsIDocumentObserver, public nsIDocumentObserver,
public nsIObserver, public nsIObserver,
public nsIScrollPositionListener, public nsIScrollPositionListener,
@ -68,73 +74,119 @@ class nsDocAccessible : public nsHyperTextAccessibleWrap,
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsDocAccessible, nsAccessible) NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsDocAccessible, nsAccessible)
NS_DECL_NSIACCESSIBLEDOCUMENT NS_DECL_NSIACCESSIBLEDOCUMENT
NS_DECL_NSPIACCESSIBLEDOCUMENT NS_DECLARE_STATIC_IID_ACCESSOR(NS_DOCACCESSIBLE_IMPL_CID)
NS_DECL_NSIOBSERVER NS_DECL_NSIOBSERVER
public: public:
nsDocAccessible(nsIDOMNode *aNode, nsIWeakReference* aShell); nsDocAccessible(nsIDOMNode *aNode, nsIWeakReference* aShell);
virtual ~nsDocAccessible(); virtual ~nsDocAccessible();
// nsIAccessible // nsIAccessible
NS_IMETHOD GetName(nsAString& aName); NS_IMETHOD GetName(nsAString& aName);
NS_IMETHOD GetDescription(nsAString& aDescription); NS_IMETHOD GetDescription(nsAString& aDescription);
NS_IMETHOD GetAttributes(nsIPersistentProperties **aAttributes); NS_IMETHOD GetAttributes(nsIPersistentProperties **aAttributes);
NS_IMETHOD GetFocusedChild(nsIAccessible **aFocusedChild); NS_IMETHOD GetFocusedChild(nsIAccessible **aFocusedChild);
NS_IMETHOD GetParent(nsIAccessible **aParent); NS_IMETHOD GetParent(nsIAccessible **aParent);
NS_IMETHOD TakeFocus(void); NS_IMETHOD TakeFocus(void);
// ----- nsIScrollPositionListener --------------------------- // nsIScrollPositionListener
NS_IMETHOD ScrollPositionWillChange(nsIScrollableView *aView, nscoord aX, nscoord aY); NS_IMETHOD ScrollPositionWillChange(nsIScrollableView *aView,
virtual void ViewPositionDidChange(nsIScrollableView* aScrollable) {} nscoord aX, nscoord aY);
NS_IMETHOD ScrollPositionDidChange(nsIScrollableView *aView, nscoord aX, nscoord aY); virtual void ViewPositionDidChange(nsIScrollableView* aScrollable) {}
NS_IMETHOD ScrollPositionDidChange(nsIScrollableView *aView,
nscoord aX, nscoord aY);
// nsIDocumentObserver // nsIDocumentObserver
NS_DECL_NSIDOCUMENTOBSERVER NS_DECL_NSIDOCUMENTOBSERVER
static void FlushEventsCallback(nsITimer *aTimer, void *aClosure); // nsAccessNode
virtual nsresult Init();
virtual nsresult Shutdown();
virtual nsIFrame* GetFrame();
virtual PRBool IsDefunct();
// nsAccessNode // nsAccessible
virtual nsresult Init();
virtual nsresult Shutdown();
virtual nsIFrame* GetFrame();
// nsAccessible
virtual nsresult GetRoleInternal(PRUint32 *aRole); virtual nsresult GetRoleInternal(PRUint32 *aRole);
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState); virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
virtual nsresult GetARIAState(PRUint32 *aState); virtual nsresult GetARIAState(PRUint32 *aState);
virtual void SetRoleMapEntry(nsRoleMapEntry* aRoleMapEntry); virtual void SetRoleMapEntry(nsRoleMapEntry* aRoleMapEntry);
// nsIAccessibleText // nsIAccessibleText
NS_IMETHOD GetAssociatedEditor(nsIEditor **aEditor); NS_IMETHOD GetAssociatedEditor(nsIEditor **aEditor);
/** // nsDocAccessible
* Non-virtual method to fire a delayed event after a 0 length timeout
*
* @param aEvent - the nsIAccessibleEvent event type
* @param aDOMNode - DOM node the accesible event should be fired for
* @param aAllowDupes - eAllowDupes: more than one event of the same type is allowed.
* eCoalesceFromSameSubtree: if two events are in the same subtree,
* only the event on ancestor is used
* eRemoveDupes (default): events of the same type are discarded
* (the last one is used)
*
* @param aIsAsynch - set to PR_TRUE if this is not being called from code
* synchronous with a DOM event
*/
nsresult FireDelayedToolkitEvent(PRUint32 aEvent, nsIDOMNode *aDOMNode,
nsAccEvent::EEventRule aAllowDupes = nsAccEvent::eRemoveDupes,
PRBool aIsAsynch = PR_FALSE);
/** /**
* Fire accessible event in timeout. * Non-virtual method to fire a delayed event after a 0 length timeout.
* *
* @param aEvent - the event to fire * @param aEvent [in] the nsIAccessibleEvent event type
*/ * @param aDOMNode [in] DOM node the accesible event should be fired for
nsresult FireDelayedAccessibleEvent(nsIAccessibleEvent *aEvent); * @param aAllowDupes [in] rule to process an event (see EEventRule constants)
* @param aIsAsynch [in] set to PR_TRUE if this is not being called from
* code synchronous with a DOM event
*/
nsresult FireDelayedToolkitEvent(PRUint32 aEvent, nsIDOMNode *aDOMNode,
nsAccEvent::EEventRule aAllowDupes = nsAccEvent::eRemoveDupes,
PRBool aIsAsynch = PR_FALSE);
void ShutdownChildDocuments(nsIDocShellTreeItem *aStart); /**
* Fire accessible event after timeout.
*
* @param aEvent [in] the event to fire
*/
nsresult FireDelayedAccessibleEvent(nsIAccessibleEvent *aEvent);
/**
* Find the accessible object in the accessibility cache that corresponds to
* the given node or the first ancestor of it that has an accessible object
* associated with it. Clear that accessible object's parent's cache of
* accessible children and remove the accessible object and any descendants
* from the accessible cache. Fires proper events. New accessible objects will
* be created and cached again on demand.
*
* @param aContent [in] the child that is changing
* @param aEvent [in] the event from nsIAccessibleEvent that caused
* the change.
*/
void InvalidateCacheSubtree(nsIContent *aContent, PRUint32 aEvent);
/**
* Cache access node.
*
* @param aUniquID [in] the unique identifier of accessible
* @param aAccessNode [in] accessible to cache
*/
void CacheAccessNode(void *aUniqueID, nsIAccessNode *aAccessNode);
/**
* Fires pending events.
*/
void FlushPendingEvents();
/**
* Fire document load events.
*
* @param aEventType [in] nsIAccessibleEvent constant
*/
virtual void FireDocLoadEvents(PRUint32 aEventType);
/**
* Process the case when anchor was clicked.
*/
virtual void FireAnchorJumpEvent();
/**
* Used to flush pending events, called after timeout. See FlushPendingEvents.
*/
static void FlushEventsCallback(nsITimer *aTimer, void *aClosure);
protected:
/**
* Iterates through sub documents and shut them down.
*/
void ShutdownChildDocuments(nsIDocShellTreeItem *aStart);
protected:
virtual void GetBoundsRect(nsRect& aRect, nsIFrame** aRelativeFrame); virtual void GetBoundsRect(nsRect& aRect, nsIFrame** aRelativeFrame);
virtual nsresult AddEventListeners(); virtual nsresult AddEventListeners();
virtual nsresult RemoveEventListeners(); virtual nsresult RemoveEventListeners();
@ -230,4 +282,7 @@ protected:
static nsIAtom *gLastFocusedFrameType; static nsIAtom *gLastFocusedFrameType;
}; };
NS_DEFINE_STATIC_IID_ACCESSOR(nsDocAccessible,
NS_DOCACCESSIBLE_IMPL_CID)
#endif #endif

Просмотреть файл

@ -1070,27 +1070,26 @@ nsRootAccessible::GetRelationByType(PRUint32 aRelationType,
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP nsRootAccessible::FireDocLoadEvents(PRUint32 aEventType) void
nsRootAccessible::FireDocLoadEvents(PRUint32 aEventType)
{ {
if (!mDocument || !mWeakShell) { if (IsDefunct())
return NS_OK; // Document has been shut down return;
}
nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem = nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem =
nsCoreUtils::GetDocShellTreeItemFor(mDOMNode); nsCoreUtils::GetDocShellTreeItemFor(mDOMNode);
NS_ASSERTION(docShellTreeItem, "No doc shell tree item for document"); NS_ASSERTION(docShellTreeItem, "No doc shell tree item for document");
NS_ENSURE_TRUE(docShellTreeItem, NS_ERROR_FAILURE); if (!docShellTreeItem)
return;
PRInt32 contentType; PRInt32 contentType;
docShellTreeItem->GetItemType(&contentType); docShellTreeItem->GetItemType(&contentType);
if (contentType == nsIDocShellTreeItem::typeContent) { if (contentType == nsIDocShellTreeItem::typeContent)
return nsDocAccessibleWrap::FireDocLoadEvents(aEventType); // Content might need to fire event nsDocAccessibleWrap::FireDocLoadEvents(aEventType); // Content might need to fire event
}
// Root chrome: don't fire event // Root chrome: don't fire event
mIsContentLoaded = (aEventType == nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE || mIsContentLoaded = (aEventType == nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE ||
aEventType == nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_STOPPED); aEventType == nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_STOPPED);
return NS_OK;
} }
nsresult nsresult

Просмотреть файл

@ -69,33 +69,32 @@ class nsRootAccessible : public nsDocAccessibleWrap,
{ {
NS_DECL_ISUPPORTS_INHERITED NS_DECL_ISUPPORTS_INHERITED
public: public:
nsRootAccessible(nsIDOMNode *aDOMNode, nsIWeakReference* aShell); nsRootAccessible(nsIDOMNode *aDOMNode, nsIWeakReference* aShell);
virtual ~nsRootAccessible(); virtual ~nsRootAccessible();
// nsIAccessible // nsIAccessible
NS_IMETHOD GetName(nsAString& aName); NS_IMETHOD GetName(nsAString& aName);
NS_IMETHOD GetParent(nsIAccessible * *aParent); NS_IMETHOD GetParent(nsIAccessible * *aParent);
NS_IMETHOD GetRelationByType(PRUint32 aRelationType, NS_IMETHOD GetRelationByType(PRUint32 aRelationType,
nsIAccessibleRelation **aRelation); nsIAccessibleRelation **aRelation);
// ----- nsPIAccessibleDocument ----------------------- // nsIDOMEventListener
NS_IMETHOD FireDocLoadEvents(PRUint32 aEventType); NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent);
// ----- nsIDOMEventListener -------------------------- // nsAccessNode
NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent); virtual nsresult Init();
virtual nsresult Shutdown();
// nsAccessNode // nsAccessible
virtual nsresult Init(); virtual nsresult GetRoleInternal(PRUint32 *aRole);
virtual nsresult Shutdown(); virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
// nsAccessible // nsDocAccessible
virtual nsresult GetRoleInternal(PRUint32 *aRole); virtual void FireDocLoadEvents(PRUint32 aEventType);
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
void ShutdownAll(); // nsRootAccessible
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ROOTACCESSIBLE_IMPL_CID)
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ROOTACCESSIBLE_IMPL_CID)
/** /**
* Fire an accessible focus event for the current focusAccssible * Fire an accessible focus event for the current focusAccssible

Просмотреть файл

@ -161,7 +161,8 @@ __try {
return E_FAIL; return E_FAIL;
} }
NS_IMETHODIMP nsDocAccessibleWrap::FireAnchorJumpEvent() void
nsDocAccessibleWrap::FireAnchorJumpEvent()
{ {
// Staying on the same page, jumping to a named anchor // Staying on the same page, jumping to a named anchor
// Fire EVENT_SCROLLING_START on first leaf accessible -- because some // Fire EVENT_SCROLLING_START on first leaf accessible -- because some
@ -171,19 +172,19 @@ NS_IMETHODIMP nsDocAccessibleWrap::FireAnchorJumpEvent()
// we have to move forward in the document to get one // we have to move forward in the document to get one
nsDocAccessible::FireAnchorJumpEvent(); nsDocAccessible::FireAnchorJumpEvent();
if (!mIsAnchorJumped) if (!mIsAnchorJumped)
return NS_OK; return;
nsCOMPtr<nsIDOMNode> focusNode; nsCOMPtr<nsIDOMNode> focusNode;
if (mIsAnchor) { if (mIsAnchor) {
nsCOMPtr<nsISelectionController> selCon(do_QueryReferent(mWeakShell)); nsCOMPtr<nsISelectionController> selCon(do_QueryReferent(mWeakShell));
if (!selCon) { if (!selCon)
return NS_OK; return;
}
nsCOMPtr<nsISelection> domSel; nsCOMPtr<nsISelection> domSel;
selCon->GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(domSel)); selCon->GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(domSel));
if (!domSel) { if (!domSel)
return NS_OK; return;
}
domSel->GetFocusNode(getter_AddRefs(focusNode)); domSel->GetFocusNode(getter_AddRefs(focusNode));
} }
else { else {
@ -193,8 +194,6 @@ NS_IMETHODIMP nsDocAccessibleWrap::FireAnchorJumpEvent()
nsCOMPtr<nsIAccessible> accessible = GetFirstAvailableAccessible(focusNode, PR_TRUE); nsCOMPtr<nsIAccessible> accessible = GetFirstAvailableAccessible(focusNode, PR_TRUE);
nsAccUtils::FireAccEvent(nsIAccessibleEvent::EVENT_SCROLLING_START, nsAccUtils::FireAccEvent(nsIAccessibleEvent::EVENT_SCROLLING_START,
accessible); accessible);
return NS_OK;
} }
STDMETHODIMP nsDocAccessibleWrap::get_URL(/* [out] */ BSTR __RPC_FAR *aURL) STDMETHODIMP nsDocAccessibleWrap::get_URL(/* [out] */ BSTR __RPC_FAR *aURL)

Просмотреть файл

@ -92,7 +92,7 @@ public:
/* [optional][in] */ VARIANT varChild, /* [optional][in] */ VARIANT varChild,
/* [retval][out] */ BSTR __RPC_FAR *pszValue); /* [retval][out] */ BSTR __RPC_FAR *pszValue);
NS_IMETHOD FireAnchorJumpEvent(); virtual void FireAnchorJumpEvent();
}; };
#endif #endif