AccessibilityMenuListOption* AccessibilityMenuListPopup::menuListOptionAccessibilityObject(HTMLElement* element) const
{
    if (!element || !isHTMLOptionElement(element) || !element->inRenderedDocument())
        return 0;

    AccessibilityObject* object = document()->axObjectCache()->getOrCreate(MenuListOptionRole);
    ASSERT_WITH_SECURITY_IMPLICATION(object->isMenuListOption());

    AccessibilityMenuListOption* option = toAccessibilityMenuListOption(object);
    option->setElement(element);

    return option;
}
AccessibilityMenuListOption* AccessibilityMenuListPopup::menuListOptionAccessibilityObject(HTMLElement* element) const
{
    if (!element || !element->hasTagName(optionTag))
        return 0;

    AccessibilityObject* object = m_menuList->renderer()->document()->axObjectCache()->getOrCreate(MenuListOptionRole);
    ASSERT(object->isMenuListOption());

    AccessibilityMenuListOption* option = static_cast<AccessibilityMenuListOption*>(object);
    option->setElement(element);

    return option;
}
AccessibilityMenuListOption* AccessibilityMenuListPopup::menuListOptionAccessibilityObject(HTMLElement* element) const
{
    if (!element || !element->hasTagName(optionTag) || !element->attached())
        return 0;

    AccessibilityObject* object = document()->axObjectCache()->getOrCreate(MenuListOptionRole);
    ASSERT_WITH_SECURITY_IMPLICATION(object->isMenuListOption());

    AccessibilityMenuListOption* option = static_cast<AccessibilityMenuListOption*>(object);
    option->setElement(element);

    return option;
}
void AccessibilityMenuListPopup::addChildren()
{
    if (!m_parent)
        return;
    
    Node* selectNode = m_parent->node();
    if (!selectNode)
        return;

    m_haveChildren = true;

    for (const auto& listItem : toHTMLSelectElement(selectNode)->listItems()) {
        AccessibilityMenuListOption* option = menuListOptionAccessibilityObject(listItem);
        if (option) {
            option->setParent(this);
            m_children.append(option);
        }
    }
}
void AccessibilityMenuListPopup::addChildren()
{
    Node* selectNode = m_menuList->renderer()->node();
    if (!selectNode)
        return;

    m_haveChildren = true;

    ASSERT(selectNode->hasTagName(selectTag));

    const Vector<Element*>& listItems = static_cast<HTMLSelectElement*>(selectNode)->listItems();
    unsigned length = listItems.size();
    for (unsigned i = 0; i < length; i++) {
        AccessibilityMenuListOption* option = menuListOptionAccessibilityObject(toHTMLElement(listItems[i]));
        if (option) {
            option->setParent(this);
            m_children.append(option);
        }
    }
}
void AccessibilityMenuListPopup::addChildren()
{
    if (!m_parent)
        return;
    
    Node* selectNode = m_parent->node();
    if (!selectNode)
        return;

    m_haveChildren = true;

    const Vector<HTMLElement*>& listItems = toHTMLSelectElement(selectNode)->listItems();
    unsigned length = listItems.size();
    for (unsigned i = 0; i < length; i++) {
        AccessibilityMenuListOption* option = menuListOptionAccessibilityObject(listItems[i]);
        if (option) {
            option->setParent(this);
            m_children.append(option);
        }
    }
}
void AccessibilityMenuListPopup::addChildren()
{
    Node* selectNode = m_menuList->renderer()->node();
    if (!selectNode)
        return;

    m_haveChildren = true;

    ASSERT(selectNode->hasTagName(selectTag));

    const Vector<Element*>& listItems = static_cast<HTMLSelectElement*>(selectNode)->listItems();
    unsigned length = listItems.size();
    for (unsigned i = 0; i < length; i++) {
        // The cast to HTMLElement below is safe because the only other possible listItem type
        // would be a WMLElement, but WML builds don't use accessbility features at all.
        AccessibilityMenuListOption* option = menuListOptionAccessibilityObject(static_cast<HTMLElement*>(listItems[i]));
        if (option) {
            option->setParent(this);
            m_children.append(option);
        }
    }
}