Bug 452564 - can't create accessibles for table children when visibility style of table is changed, r=ginn.chen, sr=roc

This commit is contained in:
Alexander Surkov
2009-07-30 15:55:51 +08:00
parent e64e15befa
commit f2faf2a6b8
2 changed files with 41 additions and 27 deletions

View File

@@ -1082,7 +1082,8 @@ nsFrameManager::ReResolveStyleContext(nsPresContext *aPresContext,
nsIFrame *aFrame, nsIFrame *aFrame,
nsIContent *aParentContent, nsIContent *aParentContent,
nsStyleChangeList *aChangeList, nsStyleChangeList *aChangeList,
nsChangeHint aMinChange) nsChangeHint aMinChange,
PRBool aFireAccessibilityEvents)
{ {
// It would be nice if we could make stronger assertions here; they // It would be nice if we could make stronger assertions here; they
// would let us simplify the ?: expressions below setting |content| // 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 // can't be trusted because it assumes any changes to the parent
// style context provider will be automatically propagated to // style context provider will be automatically propagated to
// the frame(s) with child style contexts. // 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, assumeDifferenceHint = ReResolveStyleContext(aPresContext, providerFrame,
aParentContent, aChangeList, aParentContent, aChangeList,
aMinChange); aMinChange, PR_FALSE);
// The provider's new context becomes the parent context of // The provider's new context becomes the parent context of
// aFrame's context. // aFrame's context.
@@ -1369,6 +1373,31 @@ 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<nsIAccessibilityService> 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)) { if (!(aMinChange & nsChangeHint_ReconstructFrame)) {
// There is no need to waste time crawling into a frame's children on a frame change. // 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, ReResolveStyleContext(aPresContext, outOfFlowFrame,
content, aChangeList, content, aChangeList,
NS_SubtractHint(aMinChange, NS_SubtractHint(aMinChange,
nsChangeHint_ReflowFrame)); nsChangeHint_ReflowFrame),
fireAccessibilityEvents);
// reresolve placeholder's context under the same parent // reresolve placeholder's context under the same parent
// as the out-of-flow frame // as the out-of-flow frame
ReResolveStyleContext(aPresContext, child, content, ReResolveStyleContext(aPresContext, child, content,
aChangeList, aMinChange); aChangeList, aMinChange,
fireAccessibilityEvents);
} }
else { // regular child frame else { // regular child frame
if (child != resolvedChild) { if (child != resolvedChild) {
ReResolveStyleContext(aPresContext, child, content, ReResolveStyleContext(aPresContext, child, content,
aChangeList, aMinChange); aChangeList, aMinChange,
fireAccessibilityEvents);
} else { } else {
NOISY_TRACE_FRAME("child frame already resolved as descendant, skipping",aFrame); NOISY_TRACE_FRAME("child frame already resolved as descendant, skipping",aFrame);
} }
@@ -1437,25 +1469,6 @@ nsFrameManager::ReResolveStyleContext(nsPresContext *aPresContext,
newContext->Release(); 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<nsIAccessibilityService> 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; return aMinChange;
} }
@@ -1487,7 +1500,7 @@ nsFrameManager::ComputeStyleChangeFor(nsIFrame *aFrame,
// Inner loop over next-in-flows of the current frame // Inner loop over next-in-flows of the current frame
nsChangeHint frameChange = nsChangeHint frameChange =
ReResolveStyleContext(GetPresContext(), frame, nsnull, ReResolveStyleContext(GetPresContext(), frame, nsnull,
aChangeList, topLevelChange); aChangeList, topLevelChange, PR_TRUE);
NS_UpdateHint(topLevelChange, frameChange); NS_UpdateHint(topLevelChange, frameChange);
if (topLevelChange & nsChangeHint_ReconstructFrame) { if (topLevelChange & nsChangeHint_ReconstructFrame) {

View File

@@ -240,7 +240,8 @@ private:
nsIFrame *aFrame, nsIFrame *aFrame,
nsIContent *aParentContent, nsIContent *aParentContent,
nsStyleChangeList *aChangeList, nsStyleChangeList *aChangeList,
nsChangeHint aMinChange); nsChangeHint aMinChange,
PRBool aFireAccessibilityEvents);
}; };
#endif #endif