AXObject* AXObjectCacheImpl::getOrCreate(LayoutObject* layoutObject)
{
    if (!layoutObject)
        return 0;

    if (AXObject* obj = get(layoutObject))
        return obj;

    AXObject* newObj = createFromRenderer(layoutObject);

    // Will crash later if we have two objects for the same layoutObject.
    ASSERT(!get(layoutObject));

    getAXID(newObj);

    m_layoutObjectMapping.set(layoutObject, newObj->axObjectID());
    m_objects.set(newObj->axObjectID(), newObj);
    newObj->init();
    newObj->setLastKnownIsIgnoredValue(newObj->accessibilityIsIgnored());

    return newObj;
}
AXObject* AXObjectCacheImpl::getOrCreate(AbstractInlineTextBox* inlineTextBox)
{
    if (!inlineTextBox)
        return 0;

    if (AXObject* obj = get(inlineTextBox))
        return obj;

    AXObject* newObj = createFromInlineTextBox(inlineTextBox);

    // Will crash later if we have two objects for the same inlineTextBox.
    ASSERT(!get(inlineTextBox));

    getAXID(newObj);

    m_inlineTextBoxObjectMapping.set(inlineTextBox, newObj->axObjectID());
    m_objects.set(newObj->axObjectID(), newObj);
    newObj->init();
    newObj->setLastKnownIsIgnoredValue(newObj->accessibilityIsIgnored());

    return newObj;
}
AXObject* AXObjectCacheImpl::getOrCreate(AccessibilityRole role)
{
    AXObject* obj = nullptr;

    // will be filled in...
    switch (role) {
    case ColumnRole:
        obj = AXTableColumn::create(*this);
        break;
    case TableHeaderContainerRole:
        obj = AXTableHeaderContainer::create(*this);
        break;
    case SliderThumbRole:
        obj = AXSliderThumb::create(*this);
        break;
    case MenuListPopupRole:
        obj = AXMenuListPopup::create(*this);
        break;
    case SpinButtonRole:
        obj = AXSpinButton::create(*this);
        break;
    case SpinButtonPartRole:
        obj = AXSpinButtonPart::create(*this);
        break;
    default:
        obj = nullptr;
    }

    if (obj)
        getAXID(obj);
    else
        return 0;

    m_objects.set(obj->axObjectID(), obj);
    obj->init();
    return obj;
}
AXObject* AXObjectCacheImpl::getOrCreate(Node* node)
{
    if (!node)
        return 0;

    if (AXObject* obj = get(node))
        return obj;

    // If the node has a layout object, prefer using that as the primary key for the AXObject,
    // with the exception of an HTMLAreaElement, which is created based on its node.
    if (node->layoutObject() && !isHTMLAreaElement(node))
        return getOrCreate(node->layoutObject());

    if (!node->parentElement())
        return 0;

    if (isHTMLHeadElement(node))
        return 0;

    AXObject* newObj = createFromNode(node);

    // Will crash later if we have two objects for the same node.
    ASSERT(!get(node));

    getAXID(newObj);

    m_nodeObjectMapping.set(node, newObj->axObjectID());
    m_objects.set(newObj->axObjectID(), newObj);
    newObj->init();
    newObj->setLastKnownIsIgnoredValue(newObj->accessibilityIsIgnored());

    if (node->isElementNode())
        updateTreeIfElementIdIsAriaOwned(toElement(node));

    return newObj;
}