{
// VT_EMPTY: None. This object does not have the keyboard focus itself// and does not contain a child that has the keyboard focus.// VT_I4: lVal is CHILDID_SELF. The object itself has the keyboard focus.// VT_I4: lVal contains the child ID of the child element with the keyboard focus.// VT_DISPATCH: pdispVal member is the address of the IDispatch interface// for the child object with the keyboard focus.if (!mDOMNode) {
return E_FAIL; // This node is shut down
}
VariantInit(pvarChild);
// Return the current IAccessible child that has focusnsCOMPtr<nsIAccessible> focusedAccessible;
GetFocusedChild(getter_AddRefs(focusedAccessible));
if (focusedAccessible == this) {
pvarChild->vt = VT_I4;
pvarChild->lVal = CHILDID_SELF;
}
elseif (focusedAccessible) {
pvarChild->vt = VT_DISPATCH;
pvarChild->pdispVal = NativeAccessible(focusedAccessible);
}
else {
pvarChild->vt = VT_EMPTY; // No focus or focus is not a child
}
return S_OK;
}

The VARIANT return value arguement is expected to either contain a single IAccessible or an IEnumVARIANT of IAccessibles. We return the IEnumVARIANT regardless of the number of options selected, unless there are none selected in which case we return an empty VARIANT.

The typedefs at the beginning set up the structure that will contain an array of the IAccessibles. It implements the IEnumVARIANT interface, allowing us to use it to return the IAccessibles in the VARIANT.

We get the selected options from the select's accessible object and then put create IAccessible objects for them and put those in the CComObject<EnumeratorType> object. Then we put the CComObject<EnumeratorType> object in the VARIANT and return.

{
/* * This method is used to determine the bounds of a content node. * Because HTML wraps and links are not always rectangular, this * method uses the following algorithm: * * 1) Start with an empty rectangle * 2) Add the rect for the primary frame from for the DOM node. * 3) For each next frame at the same depth with the same DOM node, add that rect to total * 4) If that frame is an inline frame, search deeper at that point in the tree, adding all rects */// Initialization area
*aBoundingFrame = nsnull;
nsIFrame *firstFrame = GetBoundsFrame();
if (!firstFrame)
return;
// Find common relative parent// This is an ancestor frame that will incompass all frames for this content node.// We need the relative parent so we can get absolute screen coordinatesnsIFrame *ancestorFrame = firstFrame;
while (ancestorFrame) {
*aBoundingFrame = ancestorFrame;
// If any other frame type, we only need to deal with the primary frame// Otherwise, there may be more frames attached to the same content nodeif (!IsCorrectFrameType(ancestorFrame, nsAccessibilityAtoms::inlineFrame) &&
!IsCorrectFrameType(ancestorFrame, nsAccessibilityAtoms::textFrame))
break;
ancestorFrame = ancestorFrame->GetParent();
}
nsIFrame *iterFrame = firstFrame;
nsCOMPtr<nsIContent> firstContent(do_QueryInterface(mDOMNode));
nsIContent* iterContent = firstContent;
PRInt32 depth = 0;
// Look only at frames below this depth, or at this depth (if we're still on the content node we started with)while (iterContent == firstContent || depth > 0) {
// Coordinates will come back relative to parent framensRect currFrameBounds = iterFrame->GetRect();
// Make this frame's bounds relative to common parent frame
currFrameBounds +=
iterFrame->GetParent()->GetOffsetToExternal(*aBoundingFrame);
// Add this frame's bounds to total
aTotalBounds.UnionRect(aTotalBounds, currFrameBounds);
nsIFrame *iterNextFrame = nsnull;
if (IsCorrectFrameType(iterFrame, nsAccessibilityAtoms::inlineFrame)) {
// Only do deeper bounds search if we're on an inline frame// Inline frames can contain larger frames inside of them
iterNextFrame = iterFrame->GetFirstChild(nsnull);
}
if (iterNextFrame)
++depth; // Child was found in code above this: We are going deeper in this iteration of the loopelse {
// Use next sibling if it exists, or go back up the tree to get the first next-in-flow or next-sibling // within our searchwhile (iterFrame) {
iterNextFrame = iterFrame->GetNextInFlow();
if (!iterNextFrame)
iterNextFrame = iterFrame->GetNextSibling();
if (iterNextFrame || --depth < 0)
break;
iterFrame = iterFrame->GetParent();
}
}
// Get ready for the next round of our loop
iterFrame = iterNextFrame;
if (iterFrame == nsnull)
break;
iterContent = nsnull;
if (depth == 0)
iterContent = iterFrame->GetContent();
}
}

{
nsIContent *walkUpContent = aForNode;
// go up tree get name of ancestor label if there is one. Don't go up farther than form elementwhile ((walkUpContent = walkUpContent->GetParent()) != nsnull) {
nsIAtom *tag = walkUpContent->Tag();
if (tag == nsAccessibilityAtoms::label) {
return walkUpContent;
}
if (tag == nsAccessibilityAtoms::form ||
tag == nsAccessibilityAtoms::body) {
// Reached top ancestor in form// There can be a label targeted at this control using the // for="control_id" attribute. To save computing time, only // look for those inside of a form elementnsAutoString forId;
aForNode->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::id, forId);
// Actually we'll be walking down the content this time, with a depth first searchif (forId.IsEmpty()) {
break;
}
returnGetContentPointingTo(&forId, walkUpContent, nsAccessibilityAtoms::_for);
}
}
returnnsnull;
}

{
// Return the next descendant that matches one of the states in matchState// Uses depth first searchNS_ASSERTION(matchState, "GetNextWithState() not called with a state to match");
NS_ASSERTION(aStart, "GetNextWithState() not called with an accessible to start with");
nsCOMPtr<nsIAccessible> look, current = aStart;
PRUint32state = 0;
while (0 == (state & matchState)) {
current->GetFirstChild(getter_AddRefs(look));
while (!look) {
if (current == this) {
returnnsnull; // At top of subtree
}
current->GetNextSibling(getter_AddRefs(look));
if (!look) {
current->GetParent(getter_AddRefs(look));
current.swap(look);
continue;
}
}
current.swap(look);
current->GetFinalState(&state);
}
nsIAccessible *returnAccessible = nsnull;
current.swap(returnAccessible);
return returnAccessible;
}

{
*aXPAccessible = nsnull;
if (!mWeakShell)
return; // Fail, we don't want to do anything after we've shut down// if its us real easy - this seems to always be the caseif (aVarChild.lVal == CHILDID_SELF) {
*aXPAccessible = NS_STATIC_CAST(nsIAccessible*, this);
}
else {
// XXX It is rare to use a VARIANT with a child num// so optimizing this is not a priority// We can come back it do it later, if there are perf problems// with a specific assistive technologynsCOMPtr<nsIAccessible> xpAccessible, nextAccessible;
GetFirstChild(getter_AddRefs(xpAccessible));
for (PRInt32index = 0; xpAccessible; index ++) {
if (!xpAccessible)
break; // Failedif (aVarChild.lVal == index) {
*aXPAccessible = xpAccessible;
break;
}
nextAccessible = xpAccessible;
nextAccessible->GetNextSibling(getter_AddRefs(xpAccessible));
}
}
NS_IF_ADDREF(*aXPAccessible);
}

3 main cases for XUL Controls to be labeled 1 - control contains label="foo" 2 - control has, as a child, a label element

- label has either value="foo" or children

3 - non-child label contains control="controlID"

label has either value="foo" or children Once a label is found, the search is discontinued, so a control that has a label child as well as having a label external to the control that uses the control="controlID" syntax will use the child label for its Name.

Focus this accessible node, The state STATE_FOCUSABLE indicates whether this node is normally focusable.

It is the callers responsibility to determine whether this node is focusable. accTakeFocus on a node that is not normally focusable (such as a table), will still set focus on that node, although normally that will not be visually indicated in most style sheets.