Пример #1
0
void AXListBox::setSelectedChildren(AccessibilityChildrenVector& children)
{
    if (!canSetSelectedChildrenAttribute())
        return;

    Node* selectNode = m_renderer->node();
    if (!selectNode)
        return;

    // disable any selected options
    unsigned length = m_children.size();
    for (unsigned i = 0; i < length; i++) {
        AXListBoxOption* listBoxOption = toAXListBoxOption(m_children[i].get());
        if (listBoxOption->isSelected())
            listBoxOption->setSelected(false);
    }

    length = children.size();
    for (unsigned i = 0; i < length; i++) {
        AXObject* obj = children[i].get();
        if (obj->roleValue() != ListBoxOptionRole)
            continue;

        toAXListBoxOption(obj)->setSelected(true);
    }
}
void InspectorAccessibilityAgent::getAXNode(ErrorString* errorString, int nodeId, RefPtr<AXNode>& accessibilityNode)
{
    Frame* mainFrame = m_page->mainFrame();
    if (!mainFrame->isLocalFrame()) {
        *errorString = "Can't inspect out of process frames yet";
        return;
    }

    InspectorDOMAgent* domAgent = toLocalFrame(mainFrame)->instrumentingAgents()->inspectorDOMAgent();
    if (!domAgent) {
        *errorString = "DOM agent must be enabled";
        return;
    }
    Node* node = domAgent->assertNode(errorString, nodeId);
    if (!node)
        return;

    Document& document = node->document();
    OwnPtr<ScopedAXObjectCache> cache = ScopedAXObjectCache::create(document);
    AXObjectCacheImpl* cacheImpl = toAXObjectCacheImpl(cache->get());
    AXObject* axObject = cacheImpl->getOrCreate(node);
    if (!axObject || axObject->accessibilityIsIgnored()) {
        accessibilityNode = buildObjectForIgnoredNode(node, axObject, cacheImpl);
        return;
    }

    RefPtr<TypeBuilder::Array<AXProperty>> properties = TypeBuilder::Array<AXProperty>::create();
    fillLiveRegionProperties(axObject, properties);
    fillGlobalStates(axObject, properties);
    fillWidgetProperties(axObject, properties);
    fillWidgetStates(axObject, properties);
    fillRelationships(axObject, properties);

    accessibilityNode = buildObjectForNode(node, axObject, cacheImpl, properties);
}
const AtomicString& AXObjectCacheImpl::computedRoleForNode(Node* node)
{
    AXObject* obj = getOrCreate(node);
    if (!obj)
        return AXObject::roleName(UnknownRole);
    return AXObject::roleName(obj->roleValue());
}
void AXObjectCacheImpl::handleEditableTextContentChanged(Node* node)
{
    AXObject* obj = get(node);
    while (obj && !obj->isNativeTextControl() && !obj->isNonNativeTextControl())
        obj = obj->parentObject();
    postNotification(obj, AXObjectCache::AXValueChanged);
}
Пример #5
0
bool AXTableCell::isTableCell() const {
  AXObject* parent = parentObjectUnignored();
  if (!parent || !parent->isTableRow())
    return false;

  return true;
}
Пример #6
0
AXObject* AXListBox::elementAccessibilityHitTest(const IntPoint& point) const
{
    // the internal HTMLSelectElement methods for returning a listbox option at a point
    // ignore optgroup elements.
    if (!m_renderer)
        return 0;

    Node* node = m_renderer->node();
    if (!node)
        return 0;

    LayoutRect parentRect = elementRect();

    AXObject* listBoxOption = 0;
    unsigned length = m_children.size();
    for (unsigned i = 0; i < length; i++) {
        LayoutRect rect = toRenderListBox(m_renderer)->itemBoundingBoxRect(parentRect.location(), 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 accessibility features at all.
        if (rect.contains(point)) {
            listBoxOption = m_children[i].get();
            break;
        }
    }

    if (listBoxOption && !listBoxOption->accessibilityIsIgnored())
        return listBoxOption;

    return axObjectCache()->getOrCreate(m_renderer);
}
Пример #7
0
AXObject* AXObjectCache::focusedImageMapUIElement(HTMLAreaElement* areaElement)
{
    // Find the corresponding accessibility object for the HTMLAreaElement. This should be
    // in the list of children for its corresponding image.
    if (!areaElement)
        return 0;

    HTMLImageElement* imageElement = areaElement->imageElement();
    if (!imageElement)
        return 0;

    AXObject* axRenderImage = areaElement->document().axObjectCache()->getOrCreate(imageElement);
    if (!axRenderImage)
        return 0;

    AXObject::AccessibilityChildrenVector imageChildren = axRenderImage->children();
    unsigned count = imageChildren.size();
    for (unsigned k = 0; k < count; ++k) {
        AXObject* child = imageChildren[k].get();
        if (!child->isImageMapLink())
            continue;

        if (toAXImageMapLink(child)->areaElement() == areaElement)
            return child;
    }

    return 0;
}
Пример #8
0
AXTableCell* AXTable::cellForColumnAndRow(unsigned column, unsigned row)
{
    updateChildrenIfNecessary();
    if (column >= columnCount() || row >= rowCount())
        return 0;

    // Iterate backwards through the rows in case the desired cell has a rowspan and exists in a previous row.
    for (unsigned rowIndexCounter = row + 1; rowIndexCounter > 0; --rowIndexCounter) {
        unsigned rowIndex = rowIndexCounter - 1;
        const auto& children = m_rows[rowIndex]->children();
        // Since some cells may have colspans, we have to check the actual range of each
        // cell to determine which is the right one.
        for (unsigned colIndexCounter = std::min(static_cast<unsigned>(children.size()), column + 1); colIndexCounter > 0; --colIndexCounter) {
            unsigned colIndex = colIndexCounter - 1;
            AXObject* child = children[colIndex].get();

            if (!child->isTableCell())
                continue;

            std::pair<unsigned, unsigned> columnRange;
            std::pair<unsigned, unsigned> rowRange;
            AXTableCell* tableCellChild = toAXTableCell(child);
            tableCellChild->columnIndexRange(columnRange);
            tableCellChild->rowIndexRange(rowRange);

            if ((column >= columnRange.first && column < (columnRange.first + columnRange.second))
                && (row >= rowRange.first && row < (rowRange.first + rowRange.second)))
                return tableCellChild;
        }
    }

    return 0;
}
Пример #9
0
Document* AXScrollbar::document() const
{
    AXObject* parent = parentObject();
    if (!parent)
        return 0;
    return parent->document();
}
Пример #10
0
void AXARIAGridCell::rowIndexRange(pair<unsigned, unsigned>& rowRange)
{
    AXObject* parent = parentObjectUnignored();
    if (!parent)
        return;

    if (parent->isTableRow()) {
        // We already got a table row, use its API.
        rowRange.first = toAXTableRow(parent)->rowIndex();
    } else if (parent->isAXTable()) {
        // We reached the parent table, so we need to inspect its
        // children to determine the row index for the cell in it.
        unsigned columnCount = toAXTable(parent)->columnCount();
        if (!columnCount)
            return;

        AccessibilityChildrenVector siblings = parent->children();
        unsigned childrenSize = siblings.size();
        for (unsigned k = 0; k < childrenSize; ++k) {
            if (siblings[k].get() == this) {
                rowRange.first = k / columnCount;
                break;
            }
        }
    }

    // as far as I can tell, grid cells cannot span rows
    rowRange.second = 1;
}
Пример #11
0
AXObject* AXObjectCacheImpl::focusedUIElementForPage(const Page* page)
{
    if (!page->settings().accessibilityEnabled())
        return 0;

    // Cross-process accessibility is not yet implemented.
    if (!page->focusController().focusedOrMainFrame()->isLocalFrame())
        return 0;

    // get the focused node in the page
    Document* focusedDocument = toLocalFrame(page->focusController().focusedOrMainFrame())->document();
    Node* focusedNode = focusedDocument->focusedElement();
    if (!focusedNode)
        focusedNode = focusedDocument;

    if (isHTMLAreaElement(*focusedNode))
        return focusedImageMapUIElement(toHTMLAreaElement(focusedNode));

    AXObject* obj = toAXObjectCacheImpl(focusedNode->document().axObjectCache())->getOrCreate(focusedNode);
    if (!obj)
        return 0;

    if (obj->shouldFocusActiveDescendant()) {
        if (AXObject* descendant = obj->activeDescendant())
            obj = descendant;
    }

    // the HTML element, for example, is focusable but has an AX object that is ignored
    if (obj->accessibilityIsIgnored())
        obj = obj->parentObjectUnignored();

    return obj;
}
Пример #12
0
AXObject* AXObjectCache::focusedUIElementForPage(const Page* page)
{
    if (!gAccessibilityEnabled)
        return 0;

    // get the focused node in the page
    Document* focusedDocument = page->focusController().focusedOrMainFrame()->document();
    Node* focusedNode = focusedDocument->focusedElement();
    if (!focusedNode)
        focusedNode = focusedDocument;

    if (focusedNode->hasTagName(areaTag))
        return focusedImageMapUIElement(toHTMLAreaElement(focusedNode));

    AXObject* obj = focusedNode->document().axObjectCache()->getOrCreate(focusedNode);
    if (!obj)
        return 0;

    if (obj->shouldFocusActiveDescendant()) {
        if (AXObject* descendant = obj->activeDescendant())
            obj = descendant;
    }

    // the HTML element, for example, is focusable but has an AX object that is ignored
    if (obj->accessibilityIsIgnored())
        obj = obj->parentObjectUnignored();

    return obj;
}
Пример #13
0
void AXObject::scrollToGlobalPoint(const IntPoint& globalPoint) const
{
    // Search up the parent chain and create a vector of all scrollable parent objects
    // and ending with this object itself.
    Vector<const AXObject*> objects;
    AXObject* parentObject;
    for (parentObject = this->parentObject(); parentObject; parentObject = parentObject->parentObject()) {
        if (parentObject->getScrollableAreaIfScrollable())
            objects.prepend(parentObject);
    }
    objects.append(this);

    // Start with the outermost scrollable (the main window) and try to scroll the
    // next innermost object to the given point.
    int offsetX = 0, offsetY = 0;
    IntPoint point = globalPoint;
    size_t levels = objects.size() - 1;
    for (size_t i = 0; i < levels; i++) {
        const AXObject* outer = objects[i];
        const AXObject* inner = objects[i + 1];

        ScrollableArea* scrollableArea = outer->getScrollableAreaIfScrollable();

        LayoutRect innerRect = inner->isAXScrollView() ? inner->parentObject()->elementRect() : inner->elementRect();
        LayoutRect objectRect = innerRect;
        IntPoint scrollPosition = scrollableArea->scrollPosition();

        // Convert the object rect into local coordinates.
        objectRect.move(offsetX, offsetY);
        if (!outer->isAXScrollView())
            objectRect.move(scrollPosition.x(), scrollPosition.y());

        int desiredX = computeBestScrollOffset(
            0,
            objectRect.x(), objectRect.maxX(),
            objectRect.x(), objectRect.maxX(),
            point.x(), point.x());
        int desiredY = computeBestScrollOffset(
            0,
            objectRect.y(), objectRect.maxY(),
            objectRect.y(), objectRect.maxY(),
            point.y(), point.y());
        outer->scrollTo(IntPoint(desiredX, desiredY));

        if (outer->isAXScrollView() && !inner->isAXScrollView()) {
            // If outer object we just scrolled is a scroll view (main window or iframe) but the
            // inner object is not, keep track of the coordinate transformation to apply to
            // future nested calculations.
            scrollPosition = scrollableArea->scrollPosition();
            offsetX -= (scrollPosition.x() + point.x());
            offsetY -= (scrollPosition.y() + point.y());
            point.move(scrollPosition.x() - innerRect.x(), scrollPosition.y() - innerRect.y());
        } else if (inner->isAXScrollView()) {
            // Otherwise, if the inner object is a scroll view, reset the coordinate transformation.
            offsetX = 0;
            offsetY = 0;
        }
    }
}
void AXObjectCacheImpl::listboxActiveIndexChanged(HTMLSelectElement* select)
{
    AXObject* obj = get(select);
    if (!obj || !obj->isAXListBox())
        return;

    toAXListBox(obj)->activeIndexChanged();
}
Пример #15
0
bool AXARIAGridRow::isARIATreeGridRow() const
{
    AXObject* parent = parentTable();
    if (!parent)
        return false;

    return parent->ariaRoleAttribute() == TreeGridRole;
}
Пример #16
0
void AXObjectCacheImpl::setCanvasObjectBounds(Element* element, const LayoutRect& rect)
{
    AXObject* obj = getOrCreate(element);
    if (!obj)
        return;

    obj->setElementRect(rect);
}
Пример #17
0
void AXObjectCacheImpl::handleScrollPositionChanged(FrameView* frameView)
{
    // Prefer to fire the scroll position changed event on the frame view's child web area, if possible.
    AXObject* targetAXObject = getOrCreate(frameView);
    if (targetAXObject && !targetAXObject->children().isEmpty())
        targetAXObject = targetAXObject->children()[0].get();
    postPlatformNotification(targetAXObject, AXScrollPositionChanged);
}
void AXObjectCacheImpl::didHideMenuListPopup(LayoutMenuList* menuList)
{
    AXObject* obj = get(menuList);
    if (!obj || !obj->isMenuList())
        return;

    toAXMenuList(obj)->didHidePopup();
}
void AXObjectCacheImpl::handleUpdateActiveMenuOption(LayoutMenuList* menuList, int optionIndex)
{
    AXObject* obj = get(menuList);
    if (!obj || !obj->isMenuList())
        return;

    toAXMenuList(obj)->didUpdateActiveOption(optionIndex);
}
Пример #20
0
AXObject* AXTableRow::parentTable() const
{
    AXObject* parent = parentObjectUnignored();
    if (!parent || !parent->isAXTable())
        return 0;

    return parent;
}
String AXObjectCacheImpl::computedNameForNode(Node* node)
{
    AXObject* obj = getOrCreate(node);
    if (!obj)
        return "";

    return obj->computedName();
}
Пример #22
0
AXObject* AXObject::parentObjectUnignored() const
{
    AXObject* parent;
    for (parent = parentObject(); parent && parent->accessibilityIsIgnored(); parent = parent->parentObject()) {
    }

    return parent;
}
Пример #23
0
bool AXTableRow::isTableRow() const
{
    AXObject* table = parentTable();
    if (!table || !table->isAXTable())
        return false;

    return true;
}
Пример #24
0
bool AXScrollView::computeAccessibilityIsIgnored() const
{
    AXObject* webArea = webAreaObject();
    if (!webArea)
        return true;

    return webArea->accessibilityIsIgnored();
}
Пример #25
0
int AXTable::tableLevel() const
{
    int level = 0;
    for (AXObject* obj = static_cast<AXObject*>(const_cast<AXTable*>(this)); obj; obj = obj->parentObject()) {
        if (obj->isAXTable())
            ++level;
    }

    return level;
}
Пример #26
0
void AXScrollView::addChildren()
{
    ASSERT(!m_haveChildren);
    m_haveChildren = true;

    AXObject* webArea = webAreaObject();
    if (webArea && !webArea->accessibilityIsIgnored())
        m_children.append(webArea);

    updateScrollbars();
}
void AXObjectCacheImpl::handleAriaSelectedChanged(Node* node)
{
    AXObject* obj = get(node);
    if (!obj)
        return;

    postNotification(obj, AXCheckedStateChanged);

    AXObject* listbox = obj->parentObjectUnignored();
    if (listbox && listbox->roleValue() == ListBoxRole)
        postNotification(listbox, AXSelectedChildrenChanged);
}
Пример #28
0
AXObject* AXARIAGridRow::headerObject()
{
    AccessibilityChildrenVector rowChildren = children();
    unsigned childrenCount = rowChildren.size();
    for (unsigned i = 0; i < childrenCount; ++i) {
        AXObject* cell = rowChildren[i].get();
        if (cell->ariaRoleAttribute() == RowHeaderRole)
            return cell;
    }

    return 0;
}
Пример #29
0
AXMenuListOption* AXMenuListPopup::menuListOptionAXObject(HTMLElement* element) const
{
    ASSERT(element);
    if (!isHTMLOptionElement(*element))
        return 0;

    AXObject* object = axObjectCache().getOrCreate(element);
    if (!object || !object->isMenuListOption())
        return 0;

    return toAXMenuListOption(object);
}
Пример #30
0
AXObjectCache::~AXObjectCache()
{
    m_notificationPostTimer.stop();

    HashMap<AXID, RefPtr<AXObject> >::iterator end = m_objects.end();
    for (HashMap<AXID, RefPtr<AXObject> >::iterator it = m_objects.begin(); it != end; ++it) {
        AXObject* obj = (*it).value.get();
        detachWrapper(obj);
        obj->detach();
        removeAXID(obj);
    }
}