From 3d6ee44234aaefa3b2c12751a2c5441383d4130f Mon Sep 17 00:00:00 2001 From: Alexander Surkov Date: Thu, 30 Jul 2009 15:55:51 +0800 Subject: [PATCH] Bug 452564 - can't create accessibles for table children when visibility style of table is changed, r=ginn.chen, sr=roc --- layout/base/nsFrameManager.cpp | 65 ++++++++++++++++++++-------------- layout/base/nsFrameManager.h | 3 +- 2 files changed, 41 insertions(+), 27 deletions(-) diff --git a/layout/base/nsFrameManager.cpp b/layout/base/nsFrameManager.cpp index ac4a6ebb7979..8572d1057eb4 100644 --- a/layout/base/nsFrameManager.cpp +++ b/layout/base/nsFrameManager.cpp @@ -1082,7 +1082,8 @@ nsFrameManager::ReResolveStyleContext(nsPresContext *aPresContext, nsIFrame *aFrame, nsIContent *aParentContent, nsStyleChangeList *aChangeList, - nsChangeHint aMinChange) + nsChangeHint aMinChange, + PRBool aFireAccessibilityEvents) { // It would be nice if we could make stronger assertions here; they // would let us simplify the ?: expressions below setting |content| @@ -1146,9 +1147,12 @@ nsFrameManager::ReResolveStyleContext(nsPresContext *aPresContext, // can't be trusted because it assumes any changes to the parent // style context provider will be automatically propagated to // the frame(s) with child style contexts. + + // Accessibility: we don't need to fire a11y events for child provider + // frame because it is visible or hidden withitn this frame. assumeDifferenceHint = ReResolveStyleContext(aPresContext, providerFrame, aParentContent, aChangeList, - aMinChange); + aMinChange, PR_FALSE); // The provider's new context becomes the parent context of // aFrame's context. @@ -1368,7 +1372,32 @@ nsFrameManager::ReResolveStyleContext(nsPresContext *aPresContext, } } } - + + PRBool fireAccessibilityEvents = aFireAccessibilityEvents; +#ifdef ACCESSIBILITY + if (fireAccessibilityEvents && mPresShell->IsAccessibilityActive() && + aFrame->GetStyleVisibility()->IsVisible() != isVisible && + !aFrame->GetPrevContinuation()) { + // A significant enough change occured that this part + // of the accessible tree is no longer valid. Fire event for primary + // frames only and if it wasn't fired for parent frame already. + + // XXX: bug 355521. Visibility does not affect descendents with + // visibility set. Work on a separate, accurate mechanism for dealing with + // visibility changes. + nsCOMPtr accService = + do_GetService("@mozilla.org/accessibilityService;1"); + if (accService) { + PRUint32 event = isVisible ? + nsIAccessibleEvent::EVENT_ASYNCH_HIDE : + nsIAccessibleEvent::EVENT_ASYNCH_SHOW; + accService->InvalidateSubtreeFor(mPresShell, aFrame->GetContent(), + event); + fireAccessibilityEvents = PR_FALSE; + } + } +#endif + if (!(aMinChange & nsChangeHint_ReconstructFrame)) { // There is no need to waste time crawling into a frame's children on a frame change. @@ -1410,17 +1439,20 @@ nsFrameManager::ReResolveStyleContext(nsPresContext *aPresContext, ReResolveStyleContext(aPresContext, outOfFlowFrame, content, aChangeList, NS_SubtractHint(aMinChange, - nsChangeHint_ReflowFrame)); + nsChangeHint_ReflowFrame), + fireAccessibilityEvents); // reresolve placeholder's context under the same parent // as the out-of-flow frame ReResolveStyleContext(aPresContext, child, content, - aChangeList, aMinChange); + aChangeList, aMinChange, + fireAccessibilityEvents); } else { // regular child frame if (child != resolvedChild) { ReResolveStyleContext(aPresContext, child, content, - aChangeList, aMinChange); + aChangeList, aMinChange, + fireAccessibilityEvents); } else { NOISY_TRACE_FRAME("child frame already resolved as descendant, skipping",aFrame); } @@ -1437,25 +1469,6 @@ nsFrameManager::ReResolveStyleContext(nsPresContext *aPresContext, newContext->Release(); } -#ifdef ACCESSIBILITY - if (mPresShell->IsAccessibilityActive() && - aFrame->GetStyleVisibility()->IsVisible() != isVisible && - !aFrame->GetPrevContinuation()) { // Primary frames only - // XXX Visibility does not affect descendents with visibility set - // Work on a separate, accurate mechanism for dealing with visibility changes. - // A significant enough change occured that this part - // of the accessible tree is no longer valid. - nsCOMPtr accService = - do_GetService("@mozilla.org/accessibilityService;1"); - if (accService) { - PRUint32 event = isVisible ? - PRUint32(nsIAccessibleEvent::EVENT_ASYNCH_HIDE) : - PRUint32(nsIAccessibleEvent::EVENT_ASYNCH_SHOW); - accService->InvalidateSubtreeFor(mPresShell, aFrame->GetContent(), event); - } - } -#endif - return aMinChange; } @@ -1487,7 +1500,7 @@ nsFrameManager::ComputeStyleChangeFor(nsIFrame *aFrame, // Inner loop over next-in-flows of the current frame nsChangeHint frameChange = ReResolveStyleContext(GetPresContext(), frame, nsnull, - aChangeList, topLevelChange); + aChangeList, topLevelChange, PR_TRUE); NS_UpdateHint(topLevelChange, frameChange); if (topLevelChange & nsChangeHint_ReconstructFrame) { diff --git a/layout/base/nsFrameManager.h b/layout/base/nsFrameManager.h index 1fa82778b5ea..f706bdd378df 100644 --- a/layout/base/nsFrameManager.h +++ b/layout/base/nsFrameManager.h @@ -240,7 +240,8 @@ private: nsIFrame *aFrame, nsIContent *aParentContent, nsStyleChangeList *aChangeList, - nsChangeHint aMinChange); + nsChangeHint aMinChange, + PRBool aFireAccessibilityEvents); }; #endif