⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 accessibilityrenderobject.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        if (isNativeTextControl())        return toRenderTextControl(m_renderer)->visiblePositionForIndex(index);        if (!isTextControl() && !m_renderer->isText())        return VisiblePosition();        Node* node = m_renderer->node();    if (!node)        return VisiblePosition();        if (index <= 0)        return VisiblePosition(node, 0, DOWNSTREAM);        ExceptionCode ec = 0;    RefPtr<Range> range = Range::create(m_renderer->document());    range->selectNodeContents(node, ec);    CharacterIterator it(range.get());    it.advance(index - 1);    return VisiblePosition(it.range()->endContainer(ec), it.range()->endOffset(ec), UPSTREAM);}    int AccessibilityRenderObject::indexForVisiblePosition(const VisiblePosition& pos) const{    if (isNativeTextControl())        return toRenderTextControl(m_renderer)->indexForVisiblePosition(pos);        if (!isTextControl())        return 0;        Node* node = m_renderer->node();    if (!node)        return 0;        Position indexPosition = pos.deepEquivalent();    if (!indexPosition.node() || indexPosition.node()->rootEditableElement() != node)        return 0;        ExceptionCode ec = 0;    RefPtr<Range> range = Range::create(m_renderer->document());    range->setStart(node, 0, ec);    range->setEnd(indexPosition.node(), indexPosition.offset(), ec);    return TextIterator::rangeLength(range.get());}IntRect AccessibilityRenderObject::boundsForVisiblePositionRange(const VisiblePositionRange& visiblePositionRange) const{    if (visiblePositionRange.isNull())        return IntRect();        // Create a mutable VisiblePositionRange.    VisiblePositionRange range(visiblePositionRange);    IntRect rect1 = range.start.absoluteCaretBounds();    IntRect rect2 = range.end.absoluteCaretBounds();        // readjust for position at the edge of a line.  This is to exclude line rect that doesn't need to be accounted in the range bounds    if (rect2.y() != rect1.y()) {        VisiblePosition endOfFirstLine = endOfLine(range.start);        if (range.start == endOfFirstLine) {            range.start.setAffinity(DOWNSTREAM);            rect1 = range.start.absoluteCaretBounds();        }        if (range.end == endOfFirstLine) {            range.end.setAffinity(UPSTREAM);            rect2 = range.end.absoluteCaretBounds();        }    }        IntRect ourrect = rect1;    ourrect.unite(rect2);        // if the rectangle spans lines and contains multiple text chars, use the range's bounding box intead    if (rect1.bottom() != rect2.bottom()) {        RefPtr<Range> dataRange = makeRange(range.start, range.end);        IntRect boundingBox = dataRange->boundingBox();        String rangeString = plainText(dataRange.get());        if (rangeString.length() > 1 && !boundingBox.isEmpty())            ourrect = boundingBox;    }    #if PLATFORM(MAC)    return m_renderer->document()->view()->contentsToScreen(ourrect);#else    return ourrect;#endif}    void AccessibilityRenderObject::setSelectedVisiblePositionRange(const VisiblePositionRange& range) const{    if (range.start.isNull() || range.end.isNull())        return;        // make selection and tell the document to use it. if it's zero length, then move to that position    if (range.start == range.end) {        m_renderer->document()->frame()->selection()->moveTo(range.start, true);    }    else {        VisibleSelection newSelection = VisibleSelection(range.start, range.end);        m_renderer->document()->frame()->selection()->setSelection(newSelection);    }    }VisiblePosition AccessibilityRenderObject::visiblePositionForPoint(const IntPoint& point) const{    // convert absolute point to view coordinates    FrameView* frameView = m_renderer->document()->topDocument()->renderer()->view()->frameView();    RenderView* renderView = topRenderer();    Node* innerNode = 0;        // locate the node containing the point    IntPoint pointResult;    while (1) {        IntPoint ourpoint;#if PLATFORM(MAC)        ourpoint = frameView->screenToContents(point);#else        ourpoint = point;#endif        HitTestRequest request(HitTestRequest::ReadOnly |                               HitTestRequest::Active);        HitTestResult result(ourpoint);        renderView->layer()->hitTest(request, result);        innerNode = result.innerNode();        if (!innerNode || !innerNode->renderer())            return VisiblePosition();                pointResult = result.localPoint();                // done if hit something other than a widget        RenderObject* renderer = innerNode->renderer();        if (!renderer->isWidget())            break;                // descend into widget (FRAME, IFRAME, OBJECT...)        Widget* widget = static_cast<RenderWidget*>(renderer)->widget();        if (!widget || !widget->isFrameView())            break;        Frame* frame = static_cast<FrameView*>(widget)->frame();        if (!frame)            break;        renderView = frame->document()->renderView();        frameView = static_cast<FrameView*>(widget);    }        return innerNode->renderer()->positionForPoint(pointResult);}// NOTE: Consider providing this utility method as AX APIVisiblePosition AccessibilityRenderObject::visiblePositionForIndex(unsigned indexValue, bool lastIndexOK) const{    if (!isTextControl())        return VisiblePosition();        // lastIndexOK specifies whether the position after the last character is acceptable    if (indexValue >= text().length()) {        if (!lastIndexOK || indexValue > text().length())            return VisiblePosition();    }    VisiblePosition position = visiblePositionForIndex(indexValue);    position.setAffinity(DOWNSTREAM);    return position;}// NOTE: Consider providing this utility method as AX APIint AccessibilityRenderObject::index(const VisiblePosition& position) const{    if (!isTextControl())        return -1;        Node* node = position.deepEquivalent().node();    if (!node)        return -1;        for (RenderObject* renderer = node->renderer(); renderer && renderer->node(); renderer = renderer->parent()) {        if (renderer == m_renderer)            return indexForVisiblePosition(position);    }        return -1;}// Given a line number, the range of characters of the text associated with this accessibility// object that contains the line number.PlainTextRange AccessibilityRenderObject::doAXRangeForLine(unsigned lineNumber) const{    if (!isTextControl())        return PlainTextRange();        // iterate to the specified line    VisiblePosition visiblePos = visiblePositionForIndex(0);    VisiblePosition savedVisiblePos;    for (unsigned lineCount = lineNumber; lineCount != 0; lineCount -= 1) {        savedVisiblePos = visiblePos;        visiblePos = nextLinePosition(visiblePos, 0);        if (visiblePos.isNull() || visiblePos == savedVisiblePos)            return PlainTextRange();    }        // make a caret selection for the marker position, then extend it to the line    // NOTE: ignores results of selection.modify because it returns false when    // starting at an empty line.  The resulting selection in that case    // will be a caret at visiblePos.    SelectionController selection;    selection.setSelection(VisibleSelection(visiblePos));    selection.modify(SelectionController::EXTEND, SelectionController::LEFT, LineBoundary);    selection.modify(SelectionController::EXTEND, SelectionController::RIGHT, LineBoundary);        // calculate the indices for the selection start and end    VisiblePosition startPosition = selection.selection().visibleStart();    VisiblePosition endPosition = selection.selection().visibleEnd();    int index1 = indexForVisiblePosition(startPosition);    int index2 = indexForVisiblePosition(endPosition);        // add one to the end index for a line break not caused by soft line wrap (to match AppKit)    if (endPosition.affinity() == DOWNSTREAM && endPosition.next().isNotNull())        index2 += 1;        // return nil rather than an zero-length range (to match AppKit)    if (index1 == index2)        return PlainTextRange();        return PlainTextRange(index1, index2 - index1);}// The composed character range in the text associated with this accessibility object that// is specified by the given index value. This parameterized attribute returns the complete// range of characters (including surrogate pairs of multi-byte glyphs) at the given index.PlainTextRange AccessibilityRenderObject::doAXRangeForIndex(unsigned index) const{    if (!isTextControl())        return PlainTextRange();        String elementText = text();    if (!elementText.length() || index > elementText.length() - 1)        return PlainTextRange();        return PlainTextRange(index, 1);}// A substring of the text associated with this accessibility object that is// specified by the given character range.String AccessibilityRenderObject::doAXStringForRange(const PlainTextRange& range) const{    if (isPasswordField())        return String();        if (range.length == 0)        return "";        if (!isTextControl())        return String();        String elementText = text();    if (range.start + range.length > elementText.length())        return String();        return elementText.substring(range.start, range.length);}// The bounding rectangle of the text associated with this accessibility object that is// specified by the given range. This is the bounding rectangle a sighted user would see// on the display screen, in pixels.IntRect AccessibilityRenderObject::doAXBoundsForRange(const PlainTextRange& range) const{    if (isTextControl())        return boundsForVisiblePositionRange(visiblePositionRangeForRange(range));    return IntRect();}AccessibilityObject* AccessibilityRenderObject::doAccessibilityHitTest(const IntPoint& point) const{    if (!m_renderer || !m_renderer->hasLayer())        return 0;        RenderLayer* layer = toRenderBox(m_renderer)->layer();         HitTestRequest request(HitTestRequest::ReadOnly |                           HitTestRequest::Active);    HitTestResult hitTestResult = HitTestResult(point);    layer->hitTest(request, hitTestResult);    if (!hitTestResult.innerNode())        return 0;    Node* node = hitTestResult.innerNode()->shadowAncestorNode();    RenderObject* obj = node->renderer();    if (!obj)        return 0;        AccessibilityObject *result = obj->document()->axObjectCache()->getOrCreate(obj);    if (obj->isListBox())        return static_cast<AccessibilityListBox*>(result)->doAccessibilityHitTest(point);            if (result->accessibilityIsIgnored())        result = result->parentObjectUnignored();    return result;}AccessibilityObject* AccessibilityRenderObject::focusedUIElement() const{    // get the focused node in the page    Page* page = m_renderer->document()->page();    if (!page)        return 0;        Document* focusedDocument = page->focusController()->focusedOrMainFrame()->document();    Node* focusedNode = focusedDocument->focusedNode();    if (!focusedNode)        focusedNode = focusedDocument;        RenderObject* focusedNodeRenderer = focusedNode->renderer();    if (!focusedNodeRenderer)        return 0;        AccessibilityObject* obj = focusedNodeRenderer->document()->axObjectCache()->getOrCreate(focusedNodeRenderer);        if (obj->shouldFocusActiveDescendant()) {        if (AccessibilityObject* 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;}bool AccessibilityRenderObject::shouldFocusActiveDescendant() const{    switch (ariaRoleAttribute()) {    case GroupRole:    case ComboBoxRole:    case ListBoxRole:    case MenuRole:    case MenuBarRole:    case RadioGroupRole:    case RowRole:    case PopUpButtonRole:    case ProgressIndicatorRole:    case ToolbarRole:    case OutlineRole:    /* FIXME: replace these with actual roles when they are added to AccessibilityRole    composite    alert    alertdialog    grid    status    timer    tree    */        return true;    default:        return false;    }}AccessibilityObject* AccessibilityRenderObject::activeDescendant() const{    if (renderer()->node() && !renderer()->node()->isElementNode())        return 0;    Element* element = static_cast<Element*>(renderer()->node());            String activeDescendantAttrStr = element->getAttribute(aria_activedescendantAttr).string();    if (activeDescendantAttrStr.isNull() || activeDescendantAttrStr.isEmpty())        return 0;        Element* target = renderer()->document()->getElementById(activeDescendantAttrStr);    if (!target)        return 0;        AccessibilityObject* obj = renderer()->document()->axObjectCache()->getOrCreate(target->renderer());    if (obj->isAccessibilityRenderObject())    // an activedescendant is only useful if it has a renderer, because that's what's needed to post the notification        return obj;    return 0;}void AccessibilityRenderObject::handleActiveDescendantChanged(){    Element* element = static_cast<Element*>(renderer()->node());    if (!element)        return;    Document* doc = renderer()->document();    if (!doc->frame()->selection()->isFocusedAndActive() || doc->focusedNode() != element)        return;     AccessibilityRenderObject* activedescendant = static_cast<AccessibilityRenderObject*>(activeDescendant());        if (activedescendant && shouldFocusActiveDescendant())        doc->axObjectCache()->postNotificationToElement(activedescendant->renderer(), "AXFocusedUIElementChanged");}AccessibilityObject* AccessibilityRenderObject::observableObject() const{    for (RenderObject* renderer = m_renderer; renderer && renderer->node(); renderer = renderer->parent()) {        if (renderer->isTextControl())            return renderer->document()->axObjectCache()->getOrCreate(renderer);    }        return 0;}    typedef HashMap<String, AccessibilityRole, CaseFoldingHash> ARIARoleMap;static const ARIARoleMap& createARIARoleMap(){    struct RoleEntry {        String 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -