void nsHTMLSelectListAccessible::CacheOptSiblings(nsIContent *aParentContent) { nsCOMPtr<nsIPresShell> presShell(do_QueryReferent(mWeakShell)); PRUint32 numChildren = aParentContent->GetChildCount(); for (PRUint32 count = 0; count < numChildren; count ++) { nsIContent *childContent = aParentContent->GetChildAt(count); if (!childContent->IsHTML()) { continue; } nsCOMPtr<nsIAtom> tag = childContent->Tag(); if (tag == nsAccessibilityAtoms::option || tag == nsAccessibilityAtoms::optgroup) { // Get an accessible for option or optgroup and cache it. nsRefPtr<nsAccessible> accessible = GetAccService()->GetOrCreateAccessible(childContent, presShell, mWeakShell); if (accessible) AppendChild(accessible); // Deep down into optgroup element. if (tag == nsAccessibilityAtoms::optgroup) CacheOptSiblings(childContent); } } }
void nsHTMLSelectListAccessible::CacheChildren() { // Cache accessibles for <optgroup> and <option> DOM decendents as children, // as well as the accessibles for them. Avoid whitespace text nodes. We want // to count all the <optgroup>s and <option>s as children because we want // a flat tree under the Select List. CacheOptSiblings(mContent); }
already_AddRefed<nsIAccessible> nsHTMLSelectListAccessible::CacheOptSiblings(nsIAccessibilityService *aAccService, nsIContent *aParentContent, nsIAccessible *aLastGoodAccessible, PRInt32 *aChildCount) { // Recursive helper for CacheChildren() PRUint32 numChildren = aParentContent->GetChildCount(); nsCOMPtr<nsIAccessible> lastGoodAccessible(aLastGoodAccessible); nsCOMPtr<nsIAccessible> newAccessible; for (PRUint32 count = 0; count < numChildren; count ++) { nsIContent *childContent = aParentContent->GetChildAt(count); if (!childContent->IsNodeOfType(nsINode::eHTML)) { continue; } nsCOMPtr<nsIAtom> tag = childContent->Tag(); if (tag == nsAccessibilityAtoms::option || tag == nsAccessibilityAtoms::optgroup) { newAccessible = AccessibleForOption(aAccService, childContent, lastGoodAccessible, aChildCount); if (newAccessible) { lastGoodAccessible = newAccessible; } if (tag == nsAccessibilityAtoms::optgroup) { newAccessible = CacheOptSiblings(aAccService, childContent, lastGoodAccessible, aChildCount); if (newAccessible) { lastGoodAccessible = newAccessible; } } } } if (lastGoodAccessible) { nsRefPtr<nsAccessible> lastAcc = nsAccUtils::QueryAccessible(lastGoodAccessible); lastAcc->SetNextSibling(nsnull); } return lastGoodAccessible.forget(); }
void nsHTMLSelectListAccessible::CacheChildren() { // Cache the number of <optgroup> and <option> DOM decendents, // as well as the accessibles for them. Avoid whitespace text nodes. nsCOMPtr<nsIContent> selectContent(do_QueryInterface(mDOMNode)); nsCOMPtr<nsIAccessibilityService> accService(do_GetService("@mozilla.org/accessibilityService;1")); if (!selectContent || !accService) { mAccChildCount = eChildCountUninitialized; return; } if (mAccChildCount != eChildCountUninitialized) { return; } mAccChildCount = 0; // Avoid reentry PRInt32 childCount = 0; nsCOMPtr<nsIAccessible> lastGoodAccessible = CacheOptSiblings(accService, selectContent, nsnull, &childCount); mAccChildCount = childCount; }