uint64_t HTMLSelectOptionAccessible::NativeState() const { // As a HTMLSelectOptionAccessible we can have the following states: // SELECTABLE, SELECTED, FOCUSED, FOCUSABLE, OFFSCREEN // Upcall to Accessible, but skip HyperTextAccessible impl // because we don't want EDITABLE or SELECTABLE_TEXT uint64_t state = Accessible::NativeState(); Accessible* select = GetSelect(); if (!select) return state; uint64_t selectState = select->State(); if (selectState & states::INVISIBLE) return state; // Are we selected? HTMLOptionElement* option = HTMLOptionElement::FromNode(mContent); bool selected = option && option->Selected(); if (selected) state |= states::SELECTED; if (selectState & states::OFFSCREEN) { state |= states::OFFSCREEN; } else if (selectState & states::COLLAPSED) { // <select> is COLLAPSED: add OFFSCREEN, if not the currently // visible option if (!selected) { state |= states::OFFSCREEN; // Ensure the invisible state is removed. Otherwise, group info will skip // this option. Furthermore, this gets cached and this doesn't get // invalidated even once the select is expanded. state &= ~states::INVISIBLE; } else { // Clear offscreen and invisible for currently showing option state &= ~(states::OFFSCREEN | states::INVISIBLE); state |= selectState & states::OPAQUE1; } } else { // XXX list frames are weird, don't rely on Accessible's general // visibility implementation unless they get reimplemented in layout state &= ~states::OFFSCREEN; // <select> is not collapsed: compare bounds to calculate OFFSCREEN Accessible* listAcc = Parent(); if (listAcc) { nsIntRect optionRect = Bounds(); nsIntRect listRect = listAcc->Bounds(); if (optionRect.Y() < listRect.Y() || optionRect.YMost() > listRect.YMost()) { state |= states::OFFSCREEN; } } } return state; }
uint64_t HTMLSelectOptionAccessible::NativeState() { // As a HTMLSelectOptionAccessible we can have the following states: // SELECTABLE, SELECTED, FOCUSED, FOCUSABLE, OFFSCREEN // Upcall to Accessible, but skip HyperTextAccessible impl // because we don't want EDITABLE or SELECTABLE_TEXT uint64_t state = Accessible::NativeState(); Accessible* select = GetSelect(); if (!select) return state; uint64_t selectState = select->State(); if (selectState & states::INVISIBLE) return state; // Are we selected? HTMLOptionElement* option = HTMLOptionElement::FromContent(mContent); bool selected = option && option->Selected(); if (selected) state |= states::SELECTED; if (selectState & states::OFFSCREEN) { state |= states::OFFSCREEN; } else if (selectState & states::COLLAPSED) { // <select> is COLLAPSED: add OFFSCREEN, if not the currently // visible option if (!selected) { state |= states::OFFSCREEN; state ^= states::INVISIBLE; } else { // Clear offscreen and invisible for currently showing option state &= ~(states::OFFSCREEN | states::INVISIBLE); state |= selectState & states::OPAQUE1; } } else { // XXX list frames are weird, don't rely on Accessible's general // visibility implementation unless they get reimplemented in layout state &= ~states::OFFSCREEN; // <select> is not collapsed: compare bounds to calculate OFFSCREEN Accessible* listAcc = Parent(); if (listAcc) { nsIntRect optionRect = Bounds(); nsIntRect listRect = listAcc->Bounds(); if (optionRect.y < listRect.y || optionRect.y + optionRect.height > listRect.y + listRect.height) { state |= states::OFFSCREEN; } } } return state; }