Bug 366340 List items should not have SHOWING state when they are scrolled offpatch by Nian.Liu r=surkov.alexander
authorginn.chen@sun.com
Tue, 10 Apr 2007 00:55:51 -0700
changeset 432 1835d4ff82328f455ac147debde73c57c5db89e5
parent 431 abfb638fdf255026bb2b24aaba5cee418f8a7b34
child 433 f0d1e32bdee5d7b5cae7ee658f4edaec66fe4aa8
push idunknown
push userunknown
push dateunknown
reviewerssurkov.alexander
bugs366340
milestone1.9a4pre
Bug 366340 List items should not have SHOWING state when they are scrolled offpatch by Nian.Liu r=surkov.alexander
accessible/src/html/nsHTMLSelectAccessible.cpp
accessible/src/html/nsHTMLSelectAccessible.h
--- a/accessible/src/html/nsHTMLSelectAccessible.cpp
+++ b/accessible/src/html/nsHTMLSelectAccessible.cpp
@@ -546,37 +546,24 @@ nsHTMLSelectOptionAccessible::GetAttribu
 
   nsAccessibilityUtils::
     SetAccGroupAttrs(aAttributes, level, indexOf + 1, childCount);
   return  NS_OK;
 }
 
 nsIFrame* nsHTMLSelectOptionAccessible::GetBoundsFrame()
 {
-  nsCOMPtr<nsIContent> selectContent(do_QueryInterface(mDOMNode));
-
-  while (selectContent && selectContent->Tag() != nsAccessibilityAtoms::select) {
-    selectContent = selectContent->GetParent();
-  }
-
-  nsCOMPtr<nsIDOMNode> selectNode(do_QueryInterface(selectContent));
-  if (selectNode) {
-    nsCOMPtr<nsIAccessibilityService> accService(do_GetService("@mozilla.org/accessibilityService;1"));
-    nsCOMPtr<nsIAccessible> selAcc;
-    accService->GetAccessibleFor(selectNode, getter_AddRefs(selAcc));
-    if (selAcc) {
-      PRUint32 state = State(selAcc);
-      if (state & nsIAccessibleStates::STATE_COLLAPSED) {
-        nsCOMPtr<nsIPresShell> presShell(GetPresShell());
-        if (!presShell) {
-          return nsnull;
-        }
-        return presShell->GetPrimaryFrameFor(selectContent);
-      }
+  PRUint32 state;
+  nsCOMPtr<nsIContent> content = GetSelectState(&state);
+  if (state & nsIAccessibleStates::STATE_COLLAPSED) {
+    nsCOMPtr<nsIPresShell> presShell(GetPresShell());
+    if (!presShell) {
+      return nsnull;
     }
+    return presShell->GetPrimaryFrameFor(content);
   }
 
   return nsAccessible::GetBoundsFrame();
 }
 
 /**
   * As a nsHTMLSelectOptionAccessible we can have the following states:
   *     STATE_SELECTABLE
@@ -616,16 +603,23 @@ nsHTMLSelectOptionAccessible::GetState(P
     option->GetSelected(&isSelected);
     if ( isSelected ) 
       *aState |= nsIAccessibleStates::STATE_SELECTED;
   }
 
   *aState |= nsIAccessibleStates::STATE_SELECTABLE |
              nsIAccessibleStates::STATE_FOCUSABLE;
 
+  // remove STATE_SHOWING if parent is STATE_COLLAPSED
+  PRUint32 state;
+  GetSelectState(&state);
+  if (state & nsIAccessibleStates::STATE_COLLAPSED) {
+    *aState |= nsIAccessibleStates::STATE_OFFSCREEN;
+  }
+
   return NS_OK;
 }
 
 /** select us! close combo box if necessary*/
 NS_IMETHODIMP nsHTMLSelectOptionAccessible::GetActionName(PRUint8 aIndex, nsAString& aName)
 {
   if (aIndex == eAction_Select) {
     aName.AssignLiteral("select"); 
@@ -782,16 +776,39 @@ void nsHTMLSelectOptionAccessible::Selec
                       multiSelect, nsnull);
   PRUint32 state = State(optionAccessible);
   PRUint32 eventType = (state & nsIAccessibleStates::STATE_SELECTED) ?
                        nsIAccessibleEvent::EVENT_SELECTION_ADD :
                        nsIAccessibleEvent::EVENT_SELECTION_REMOVE; 
   privateMultiSelect->FireToolkitEvent(eventType, optionAccessible, nsnull);
 }
 
+nsIContent* nsHTMLSelectOptionAccessible::GetSelectState(PRUint32* aState)
+{
+  nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
+  while (content && content->Tag() != nsAccessibilityAtoms::select) {
+    content = content->GetParent();
+  }
+
+  nsCOMPtr<nsIDOMNode> selectNode(do_QueryInterface(content));
+  if (selectNode) {
+    nsCOMPtr<nsIAccessibilityService> accService = GetAccService();
+    if (accService) {
+      nsCOMPtr<nsIAccessible> selAcc;
+      accService->GetAccessibleFor(selectNode, getter_AddRefs(selAcc));
+      if (selAcc) {
+        PRUint32 dummy;
+        selAcc->GetFinalState(aState, &dummy);
+        return content;
+      }
+    }
+  }
+  return nsnull; 
+}
+
 /** ----- nsHTMLSelectOptGroupAccessible ----- */
 
 /** Default Constructor */
 nsHTMLSelectOptGroupAccessible::nsHTMLSelectOptGroupAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell):
 nsHTMLSelectOptionAccessible(aDOMNode, aShell)
 {
 }
 
--- a/accessible/src/html/nsHTMLSelectAccessible.h
+++ b/accessible/src/html/nsHTMLSelectAccessible.h
@@ -164,16 +164,25 @@ public:
   NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
   NS_IMETHOD GetRole(PRUint32 *aRole);
   NS_IMETHOD GetName(nsAString& aName);
   virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
 
   nsIFrame*  GetBoundsFrame();
   static nsresult GetFocusedOptionNode(nsIDOMNode *aListNode, nsIDOMNode **aFocusedOptionNode);
   static void SelectionChangedIfOption(nsIContent *aPossibleOption);
+
+private:
+  
+  /**
+   * Get Select element's accessible state
+   * @param aState, Select element state
+   * @return Select element content, returns null if not avaliable
+   */ 
+  nsIContent* GetSelectState(PRUint32* aState);
 };
 
 /*
  * Opt Groups inside the select, contained within the list
  */
 class nsHTMLSelectOptGroupAccessible : public nsHTMLSelectOptionAccessible
 {
 public: