Changeset 244983 in webkit


Ignore:
Timestamp:
May 6, 2019 3:33:52 PM (5 years ago)
Author:
commit-queue@webkit.org
Message:

Hitpoint for link which spans two lines in web content is incorrect
https://bugs.webkit.org/show_bug.cgi?id=197511
<rdar://problem/49971483>

Patch by Andres Gonzalez <Andres Gonzalez> on 2019-05-06
Reviewed by Chris Fleizach.

Source/WebCore:

  • Special case for links to return first char location as clickPoint instead of middle point of bounding rect.
  • Modified iOS ActivationPoint to use clickPoint. This way all code paths go through the same function.
  • Made boundsForRects to return content coordinates in all platforms. Adjusted all callers, directly or indirectly, appropriately.

Tests: accessibility/ios-simulator/links-activation.html

accessibility/links-activation.html

  • accessibility/AccessibilityRenderObject.cpp:

(WebCore::AccessibilityRenderObject::clickPoint):
(WebCore::AccessibilityRenderObject::boundsForRects):
(WebCore::AccessibilityRenderObject::boundsForRects const): Deleted.

  • accessibility/AccessibilityRenderObject.h:
  • accessibility/ios/WebAccessibilityObjectWrapperIOS.mm:

(-[WebAccessibilityObjectWrapper accessibilityActivationPoint]):

  • accessibility/mac/WebAccessibilityObjectWrapperMac.mm:

(-[WebAccessibilityObjectWrapper accessibilityAttributeValue:forParameter:]):

LayoutTests:

  • Added LayoutTest.
  • accessibility/ios-simulator/links-activation-expected.txt: Added.
  • accessibility/ios-simulator/links-activation.html: Added.
  • accessibility/links-activation-expected.txt: Added.
  • accessibility/links-activation.html: Added.
Location:
trunk
Files:
4 added
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r244977 r244983  
     12019-05-06  Andres Gonzalez  <andresg_22@apple.com>
     2
     3        Hitpoint for link which spans two lines in web content is incorrect
     4        https://bugs.webkit.org/show_bug.cgi?id=197511
     5        <rdar://problem/49971483>
     6
     7        Reviewed by Chris Fleizach.
     8
     9        - Added LayoutTest.
     10
     11        * accessibility/ios-simulator/links-activation-expected.txt: Added.
     12        * accessibility/ios-simulator/links-activation.html: Added.
     13        * accessibility/links-activation-expected.txt: Added.
     14        * accessibility/links-activation.html: Added.
     15
    1162019-05-06  Youenn Fablet  <youenn@apple.com>
    217
  • trunk/Source/WebCore/ChangeLog

    r244980 r244983  
     12019-05-06  Andres Gonzalez  <andresg_22@apple.com>
     2
     3        Hitpoint for link which spans two lines in web content is incorrect
     4        https://bugs.webkit.org/show_bug.cgi?id=197511
     5        <rdar://problem/49971483>
     6
     7        Reviewed by Chris Fleizach.
     8
     9        - Special case for links to return first char location as clickPoint instead of middle point of bounding rect.
     10        - Modified iOS ActivationPoint to use clickPoint. This way all code paths go through the same function.
     11        - Made boundsForRects to return content coordinates in all platforms. Adjusted all callers, directly or indirectly, appropriately.
     12
     13        Tests: accessibility/ios-simulator/links-activation.html
     14               accessibility/links-activation.html
     15
     16        * accessibility/AccessibilityRenderObject.cpp:
     17        (WebCore::AccessibilityRenderObject::clickPoint):
     18        (WebCore::AccessibilityRenderObject::boundsForRects):
     19        (WebCore::AccessibilityRenderObject::boundsForRects const): Deleted.
     20        * accessibility/AccessibilityRenderObject.h:
     21        * accessibility/ios/WebAccessibilityObjectWrapperIOS.mm:
     22        (-[WebAccessibilityObjectWrapper accessibilityActivationPoint]):
     23        * accessibility/mac/WebAccessibilityObjectWrapperMac.mm:
     24        (-[WebAccessibilityObjectWrapper accessibilityAttributeValue:forParameter:]):
     25
    1262019-05-06  Jer Noble  <jer.noble@apple.com>
    227
  • trunk/Source/WebCore/accessibility/AccessibilityRenderObject.cpp

    r244582 r244983  
    900900}
    901901
     902IntPoint AccessibilityRenderObject::linkClickPoint()
     903{
     904    ASSERT(isLink());
     905    /* A link bounding rect can contain points that are not part of the link.
     906     For instance, a link that starts at the end of a line and finishes at the
     907     beginning of the next line will have a bounding rect that includes the
     908     entire two lines. In such a case, the middle point of the bounding rect
     909     may not belong to the link element and thus may not activate the link.
     910     Hence, return the middle point of the first character in the link if exists.
     911     */
     912    if (RefPtr<Range> range = elementRange()) {
     913        VisiblePosition start = range->startPosition();
     914        VisiblePosition end = nextVisiblePosition(start);
     915        if (start.isNull() || !range->contains(end))
     916            return AccessibilityObject::clickPoint();
     917
     918        RefPtr<Range> charRange = makeRange(start, end);
     919        IntRect rect = boundsForRange(charRange);
     920        return { rect.x() + rect.width() / 2, rect.y() + rect.height() / 2 };
     921    }
     922    return AccessibilityObject::clickPoint();
     923}
     924
    902925IntPoint AccessibilityRenderObject::clickPoint()
    903926{
    904927    // Headings are usually much wider than their textual content. If the mid point is used, often it can be wrong.
    905     if (isHeading() && children().size() == 1)
    906         return children()[0]->clickPoint();
     928    AccessibilityChildrenVector children = this->children();
     929    if (isHeading() && children.size() == 1)
     930        return children[0]->clickPoint();
     931
     932    if (isLink())
     933        return linkClickPoint();
    907934
    908935    // use the default position unless this is an editable web area, in which case we use the selection bounds.
     
    913940    VisiblePositionRange range = VisiblePositionRange(visSelection.visibleStart(), visSelection.visibleEnd());
    914941    IntRect bounds = boundsForVisiblePositionRange(range);
    915 #if PLATFORM(COCOA)
    916     bounds.setLocation(m_renderer->view().frameView().screenToContents(bounds.location()));
    917 #endif       
    918     return IntPoint(bounds.x() + (bounds.width() / 2), bounds.y() - (bounds.height() / 2));
     942    return { bounds.x() + (bounds.width() / 2), bounds.y() + (bounds.height() / 2) };
    919943}
    920944   
     
    20432067}
    20442068
    2045 IntRect AccessibilityRenderObject::boundsForRects(LayoutRect& rect1, LayoutRect& rect2, RefPtr<Range> dataRange) const
     2069IntRect AccessibilityRenderObject::boundsForRects(LayoutRect const& rect1, LayoutRect const& rect2, RefPtr<Range> const& dataRange)
    20462070{
    20472071    LayoutRect ourRect = rect1;
     
    20552079            ourRect = boundingBox;
    20562080    }
    2057    
    2058 #if PLATFORM(MAC)
    2059     return m_renderer->view().frameView().contentsToScreen(snappedIntRect(ourRect));
    2060 #else
     2081
    20612082    return snappedIntRect(ourRect);
    2062 #endif
    20632083}
    20642084
  • trunk/Source/WebCore/accessibility/AccessibilityRenderObject.h

    r244061 r244983  
    169169    IntRect boundsForVisiblePositionRange(const VisiblePositionRange&) const override;
    170170    IntRect boundsForRange(const RefPtr<Range>) const override;
    171     IntRect boundsForRects(LayoutRect&, LayoutRect&, RefPtr<Range>) const;
    172171    void setSelectedVisiblePositionRange(const VisiblePositionRange&) const override;
    173172    bool isVisiblePositionRangeInDifferentDocument(const VisiblePositionRange&) const;
     
    293292    RenderObject* targetElementForActiveDescendant(const QualifiedName&, AccessibilityObject*) const;
    294293    bool canHavePlainText() const;
     294    // Special handling of click point for links.
     295    IntPoint linkClickPoint();
     296    // Rects utilities.
     297    static IntRect boundsForRects(LayoutRect const&, LayoutRect const&, RefPtr<Range> const&);
    295298};
    296299
  • trunk/Source/WebCore/accessibility/ios/WebAccessibilityObjectWrapperIOS.mm

    r244691 r244983  
    16001600    if (![self _prepareAccessibilityCall])
    16011601        return CGPointZero;
    1602    
    1603     auto rect = FloatRect(snappedIntRect(m_object->boundingBoxRect()));
    1604     CGRect cgRect = [self convertRectToSpace:rect space:AccessibilityConversionSpace::Screen];
    1605     return CGPointMake(CGRectGetMidX(cgRect), CGRectGetMidY(cgRect));
     1602
     1603    IntPoint point = m_object->clickPoint();
     1604    return [self _accessibilityConvertPointToViewSpace:point];
    16061605}
    16071606
  • trunk/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm

    r244691 r244983  
    42604260    if ([attribute isEqualToString:@"AXBoundsForTextMarkerRange"]) {
    42614261        RefPtr<Range> range = [self rangeForTextMarkerRange:textMarkerRange];
    4262         NSRect rect = m_object->boundsForRange(range);
     4262        auto bounds = FloatRect(m_object->boundsForRange(range));
     4263        NSRect rect = [self convertRectToSpace:bounds space:AccessibilityConversionSpace::Screen];
    42634264        return [NSValue valueWithRect:rect];
    42644265    }
     
    42704271            return nil;
    42714272        RefPtr<Range> range = cache->rangeForUnorderedCharacterOffsets(start, end);
    4272         NSRect rect = m_object->boundsForRange(range);
     4273        auto bounds = FloatRect(m_object->boundsForRange(range));
     4274        NSRect rect = [self convertRectToSpace:bounds space:AccessibilityConversionSpace::Screen];
    42734275        return [NSValue valueWithRect:rect];
    42744276    }
     
    45054507                return nil;
    45064508            PlainTextRange plainTextRange = PlainTextRange(range.location, range.length);
    4507             NSRect rect = m_object->doAXBoundsForRangeUsingCharacterOffset(plainTextRange);
     4509            auto bounds = FloatRect(m_object->doAXBoundsForRangeUsingCharacterOffset(plainTextRange));
     4510            NSRect rect = [self convertRectToSpace:bounds space:AccessibilityConversionSpace::Screen];
    45084511            return [NSValue valueWithRect:rect];
    45094512        }
Note: See TracChangeset for help on using the changeset viewer.