зеркало из https://github.com/mozilla/pjs.git
Bug 397112. Crash [@ nsAccessible::GetFirstChild] moving text out of an option. Patch by Alexander Surkov and Mats Palmgren. r=aaronlev
This commit is contained in:
Родитель
04762f216f
Коммит
0872c250cc
|
@ -41,7 +41,7 @@
|
|||
interface nsIAccessible;
|
||||
interface nsIAccessibleEvent;
|
||||
|
||||
[uuid(03932812-53d1-4dc7-965d-6b6ad8a872b1)]
|
||||
[uuid(af05f83c-6fd2-48c1-b1c3-811857472421)]
|
||||
interface nsPIAccessible : nsISupports
|
||||
{
|
||||
/**
|
||||
|
@ -64,6 +64,11 @@ interface nsPIAccessible : nsISupports
|
|||
*/
|
||||
void getCachedParent(out nsIAccessible aAccParent);
|
||||
|
||||
/**
|
||||
* Return first child accessible only if cached.
|
||||
*/
|
||||
void getCachedFirstChild(out nsIAccessible aAccFirstChild);
|
||||
|
||||
/**
|
||||
* Set the child count to -1 (unknown) and null out cached child pointers
|
||||
*/
|
||||
|
|
|
@ -444,6 +444,16 @@ nsAccessible::GetKeyboardShortcut(nsAString& aAccessKey)
|
|||
|
||||
NS_IMETHODIMP nsAccessible::SetParent(nsIAccessible *aParent)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
if (aParent && aParent != mParent) {
|
||||
nsCOMPtr<nsPIAccessible> privParent = do_QueryInterface(mParent);
|
||||
if (privParent) {
|
||||
nsCOMPtr<nsIAccessible> firstChild;
|
||||
privParent->GetCachedFirstChild(getter_AddRefs(firstChild));
|
||||
NS_ASSERTION(firstChild != this, "Reparenting other node's first child!");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
mParent = aParent;
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -588,6 +598,17 @@ NS_IMETHODIMP nsAccessible::GetCachedParent(nsIAccessible ** aParent)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsAccessible::GetCachedFirstChild(nsIAccessible ** aFirstChild)
|
||||
{
|
||||
*aFirstChild = nsnull;
|
||||
if (!mWeakShell) {
|
||||
// This node has been shut down
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
NS_IF_ADDREF(*aFirstChild = mFirstChild);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute nsIAccessible nextSibling; */
|
||||
NS_IMETHODIMP nsAccessible::GetNextSibling(nsIAccessible * *aNextSibling)
|
||||
{
|
||||
|
@ -655,6 +676,16 @@ NS_IMETHODIMP nsAccessible::GetFirstChild(nsIAccessible * *aFirstChild)
|
|||
PRInt32 numChildren;
|
||||
GetChildCount(&numChildren); // Make sure we cache all of the children
|
||||
|
||||
#ifdef DEBUG
|
||||
nsCOMPtr<nsPIAccessible> firstChild(do_QueryInterface(mFirstChild));
|
||||
if (firstChild) {
|
||||
nsCOMPtr<nsIAccessible> realParent;
|
||||
firstChild->GetCachedParent(getter_AddRefs(realParent));
|
||||
NS_ASSERTION(!realParent || realParent == this,
|
||||
"Two accessibles have the same first child accessible.");
|
||||
}
|
||||
#endif
|
||||
|
||||
NS_IF_ADDREF(*aFirstChild = mFirstChild);
|
||||
|
||||
return NS_OK;
|
||||
|
|
|
@ -1549,6 +1549,15 @@ NS_IMETHODIMP nsDocAccessible::FlushPendingEvents()
|
|||
accessibleEvent->GetEventType(&eventType);
|
||||
if (eventType == nsIAccessibleEvent::EVENT_DOM_CREATE ||
|
||||
eventType == nsIAccessibleEvent::EVENT_ASYNCH_SHOW) {
|
||||
nsCOMPtr<nsIAccessible> containerAccessible;
|
||||
if (accessible) {
|
||||
accessible->GetParent(getter_AddRefs(containerAccessible));
|
||||
nsCOMPtr<nsPIAccessible> privateContainerAccessible =
|
||||
do_QueryInterface(containerAccessible);
|
||||
if (privateContainerAccessible)
|
||||
privateContainerAccessible->InvalidateChildren();
|
||||
}
|
||||
|
||||
// Also fire text changes if the node being created could affect the text in an nsIAccessibleText parent.
|
||||
// When a node is being made visible or is inserted, the text in an ancestor hyper text will gain characters
|
||||
// At this point we now have the frame and accessible for this node if there is one. That is why we
|
||||
|
@ -1557,8 +1566,10 @@ NS_IMETHODIMP nsDocAccessible::FlushPendingEvents()
|
|||
nsCOMPtr<nsIDOMNode> domNode;
|
||||
accessibleEvent->GetDOMNode(getter_AddRefs(domNode));
|
||||
if (domNode && domNode != mDOMNode) {
|
||||
nsCOMPtr<nsIAccessible> containerAccessible;
|
||||
GetAccessibleInParentChain(domNode, getter_AddRefs(containerAccessible));
|
||||
if (!containerAccessible)
|
||||
GetAccessibleInParentChain(domNode,
|
||||
getter_AddRefs(containerAccessible));
|
||||
|
||||
nsCOMPtr<nsIAccessibleTextChangeEvent> textChangeEvent =
|
||||
CreateTextChangeEventForNode(containerAccessible, domNode, accessible, PR_TRUE, PR_TRUE);
|
||||
if (textChangeEvent) {
|
||||
|
@ -1831,11 +1842,6 @@ NS_IMETHODIMP nsDocAccessible::InvalidateCacheSubtree(nsIContent *aChild,
|
|||
// and there is always one of those.
|
||||
|
||||
if (aChild && !isHiding) {
|
||||
nsCOMPtr<nsPIAccessible> privateContainerAccessible =
|
||||
do_QueryInterface(containerAccessible);
|
||||
if (privateContainerAccessible) {
|
||||
privateContainerAccessible->InvalidateChildren();
|
||||
}
|
||||
// Fire EVENT_SHOW, EVENT_MENUPOPUP_START for newly visible content.
|
||||
// Fire after a short timer, because we want to make sure the view has been
|
||||
// updated to make this accessible content visible. If we don't wait,
|
||||
|
|
Загрузка…
Ссылка в новой задаче