Changeset 83493 in webkit


Ignore:
Timestamp:
Apr 11, 2011 2:02:23 PM (13 years ago)
Author:
mario@webkit.org
Message:

2011-04-11 Mario Sanchez Prada <msanchez@igalia.com>

Reviewed by Chris Fleizach.

[Gtk] Implement support for Embedded Objects
https://bugs.webkit.org/show_bug.cgi?id=52148

Expose special OBJECT character for replaced elements, implementing
AtkText and AtkHyperlink when required.

  • accessibility/AccessibilityRenderObject.cpp: (WebCore::textIteratorBehaviorForTextRange): New helper function, to return the right behavior, depending on the platform, so it ensures that object replacement characters get emitted for GTK. (WebCore::AccessibilityRenderObject::textUnderElement): Use the new helper function textIteratorBehaviorForTextRange. (WebCore::AccessibilityRenderObject::stringValue): Ditto. (WebCore::AccessibilityRenderObject::indexForVisiblePosition): Consider replaced elements when calculating range length in GTK.
  • accessibility/gtk/AccessibilityObjectWrapperAtk.cpp: (textForRenderer): Ouput the 'object replacement character' for replaced objects. (getSelectionOffsetsForObject): Consider replaced elements when calculating range length in GTK. (webkitAccessibleHypertextGetLink): Remove wrong extra check that were causing only links to be considered. (webkitAccessibleHypertextGetNLinks): Replace wrong 'isLink()' check with the right one, by checking that the right ATK interface is being implemented by the AtkObject. (getInterfaceMaskFromObject): Implement the Hyperlink interface both for links and replaced objects. (objectAndOffsetUnignored): Consider replaced elements when calculating range length in GTK.
  • accessibility/gtk/WebKitAccessibleHyperlink.cpp: (getRangeLengthForObject): Ensure spaces are used for replaced elements when calling to TextIterator::rangeLength().
  • editing/TextIterator.h: New value in the TextIteratorBehavior enumeration (TextIteratorEmitsObjectReplacementCharacters) and new private variable to consider that new option internally.
  • editing/TextIterator.cpp: (WebCore::TextIterator::TextIterator): Initialize the new private attribute m_emitsObjectReplacementCharacters in constructors. (WebCore::TextIterator::handleReplacedElement): Emit the 'object replacement character' when m_emitsObjectReplacementCharacters.

2011-04-11 Mario Sanchez Prada <msanchez@igalia.com>

Reviewed by Chris Fleizach.

[Gtk] Implement support for Embedded Objects
https://bugs.webkit.org/show_bug.cgi?id=52148

New accessibility unit test for embedded objects.

  • tests/testatk.c: (testWebkitAtkEmbeddedObjects): New unit test. (main): Added the new unit test.
Location:
trunk/Source
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r83492 r83493  
     12011-04-11  Mario Sanchez Prada  <msanchez@igalia.com>
     2
     3        Reviewed by Chris Fleizach.
     4
     5        [Gtk] Implement support for Embedded Objects
     6        https://bugs.webkit.org/show_bug.cgi?id=52148
     7
     8        Expose special OBJECT character for replaced elements, implementing
     9        AtkText and AtkHyperlink when required.
     10
     11        * accessibility/AccessibilityRenderObject.cpp:
     12        (WebCore::textIteratorBehaviorForTextRange): New helper function,
     13        to return the right behavior, depending on the platform, so it
     14        ensures that object replacement characters get emitted for GTK.
     15        (WebCore::AccessibilityRenderObject::textUnderElement): Use the
     16        new helper function textIteratorBehaviorForTextRange.
     17        (WebCore::AccessibilityRenderObject::stringValue): Ditto.
     18        (WebCore::AccessibilityRenderObject::indexForVisiblePosition):
     19        Consider replaced elements when calculating range length in GTK.
     20
     21        * accessibility/gtk/AccessibilityObjectWrapperAtk.cpp:
     22        (textForRenderer): Ouput the 'object replacement character' for
     23        replaced objects.
     24        (getSelectionOffsetsForObject): Consider replaced elements when
     25        calculating range length in GTK.
     26        (webkitAccessibleHypertextGetLink): Remove wrong extra check that
     27        were causing only links to be considered.
     28        (webkitAccessibleHypertextGetNLinks): Replace wrong 'isLink()'
     29        check with the right one, by checking that the right ATK interface
     30        is being implemented by the AtkObject.
     31        (getInterfaceMaskFromObject): Implement the Hyperlink interface
     32        both for links and replaced objects.
     33        (objectAndOffsetUnignored): Consider replaced elements when
     34        calculating range length in GTK.
     35
     36        * accessibility/gtk/WebKitAccessibleHyperlink.cpp:
     37        (getRangeLengthForObject): Ensure spaces are used for replaced
     38        elements when calling to TextIterator::rangeLength().
     39
     40        * editing/TextIterator.h: New value in the TextIteratorBehavior
     41        enumeration (TextIteratorEmitsObjectReplacementCharacters) and new
     42        private variable to consider that new option internally.
     43        * editing/TextIterator.cpp:
     44        (WebCore::TextIterator::TextIterator): Initialize the new private
     45        attribute m_emitsObjectReplacementCharacters in constructors.
     46        (WebCore::TextIterator::handleReplacedElement): Emit the 'object
     47        replacement character' when m_emitsObjectReplacementCharacters.
     48
    1492011-04-11  Jia Pu  <jpu@apple.com>
    250
  • trunk/Source/WebCore/accessibility/AccessibilityRenderObject.cpp

    r82934 r83493  
    10121012}
    10131013
     1014static TextIteratorBehavior textIteratorBehaviorForTextRange()
     1015{
     1016    TextIteratorBehavior behavior = TextIteratorIgnoresStyleVisibility;
     1017
     1018#if PLATFORM(GTK)
     1019    // We need to emit replaced elements for GTK, and present
     1020    // them with the 'object replacement character' (0xFFFC).
     1021    behavior = static_cast<TextIteratorBehavior>(behavior | TextIteratorEmitsObjectReplacementCharacters);
     1022#endif
     1023
     1024    return behavior;
     1025}
     1026
    10141027String AccessibilityRenderObject::textUnderElement() const
    10151028{
     
    10261039            if (frame->document() != node->document())
    10271040                return String();
    1028             return plainText(rangeOfContents(node).get(), TextIteratorIgnoresStyleVisibility);
     1041
     1042            return plainText(rangeOfContents(node).get(), textIteratorBehaviorForTextRange());
    10291043        }
    10301044    }
     
    11401154        if (startVisiblePosition.isNull() || endVisiblePosition.isNull())
    11411155            return String();
    1142        
    1143         return plainText(makeRange(startVisiblePosition, endVisiblePosition).get(), TextIteratorIgnoresStyleVisibility);
     1156
     1157        return plainText(makeRange(startVisiblePosition, endVisiblePosition).get(),
     1158                         textIteratorBehaviorForTextRange());
    11441159    }
    11451160   
     
    24932508    range->setStart(node, 0, ec);
    24942509    range->setEnd(indexPosition.anchorNode(), indexPosition.deprecatedEditingOffset(), ec);
     2510
     2511#if PLATFORM(GTK)
     2512    // We need to consider replaced elements for GTK, as they will be
     2513    // presented with the 'object replacement character' (0xFFFC).
     2514    return TextIterator::rangeLength(range.get(), true);
     2515#else
    24952516    return TextIterator::rangeLength(range.get());
     2517#endif
    24962518}
    24972519
  • trunk/Source/WebCore/accessibility/gtk/AccessibilityObjectWrapperAtk.cpp

    r83450 r83493  
    4242#include "AccessibilityTableColumn.h"
    4343#include "AccessibilityTableRow.h"
     44#include "CharacterNames.h"
    4445#include "Document.h"
    4546#include "DocumentType.h"
     
    10541055            renderText = toRenderText(object);
    10551056        else {
     1057            if (object->isReplaced())
     1058                g_string_append_unichar(resultText, objectReplacementCharacter);
     1059
    10561060            // We need to check children, if any, to consider when
    10571061            // current object is not a text object but some of its
     
    10641068        }
    10651069
    1066         InlineTextBox* box = renderText->firstTextBox();
     1070        InlineTextBox* box = renderText ? renderText->firstTextBox() : 0;
    10671071        while (box) {
    10681072            gchar* text = convertUniCharToUTF8(renderText->characters(), renderText->textLength(), box->start(), box->end());
     
    16231627
    16241628    // Set values for start and end offsets.
    1625     startOffset = TextIterator::rangeLength(rangeInParent.get());
     1629    startOffset = TextIterator::rangeLength(rangeInParent.get(), true);
    16261630
    16271631    // We need to adjust the offsets for the list item marker.
     
    16331637
    16341638    RefPtr<Range> nodeRange = Range::create(node->document(), nodeRangeStart, nodeRangeEnd);
    1635     endOffset = startOffset + TextIterator::rangeLength(nodeRange.get());
     1639    endOffset = startOffset + TextIterator::rangeLength(nodeRange.get(), true);
    16361640}
    16371641
     
    21672171    for (unsigned i = 0; i < children.size(); i++) {
    21682172        AccessibilityObject* coreChild = children.at(i).get();
    2169         if (!coreChild->accessibilityIsIgnored() && coreChild->isLink()) {
     2173        if (!coreChild->accessibilityIsIgnored()) {
     2174            AtkObject* axObject = coreChild->wrapper();
     2175            if (!axObject || !ATK_IS_HYPERLINK_IMPL(axObject))
     2176                continue;
     2177
    21702178            currentLink++;
    21712179            if (index != currentLink)
    21722180                continue;
    21732181
    2174             AtkObject* axObject = coreChild->wrapper();
    2175             if (!axObject || !ATK_IS_HYPERLINK_IMPL(axObject))
    2176                 return 0;
    2177 
    21782182            return atk_hyperlink_impl_get_hyperlink(ATK_HYPERLINK_IMPL(axObject));
    21792183        }
     
    21922196    for (size_t i = 0; i < children.size(); i++) {
    21932197        AccessibilityObject* coreChild = children.at(i).get();
    2194         if (!coreChild->accessibilityIsIgnored() && coreChild->isLink())
    2195             linksFound++;
     2198        if (!coreChild->accessibilityIsIgnored()) {
     2199            AtkObject* axObject = coreChild->wrapper();
     2200            if (axObject && ATK_IS_HYPERLINK_IMPL(axObject))
     2201                linksFound++;
     2202        }
    21962203    }
    21972204
     
    24402447    interfaceMask |= 1 << WAI_ACTION;
    24412448
    2442     // Hyperlink
    2443     if (coreObject->isLink())
    2444         interfaceMask |= 1 << WAI_HYPERLINK;
    2445 
    24462449    // Selection
    24472450    if (coreObject->isListBox() || coreObject->isMenuList())
    24482451        interfaceMask |= 1 << WAI_SELECTION;
    24492452
     2453    // Get renderer if available.
     2454    RenderObject* renderer = 0;
     2455    if (coreObject->isAccessibilityRenderObject())
     2456        renderer = coreObject->renderer();
     2457
     2458    // Hyperlink (links and embedded objects).
     2459    if (coreObject->isLink() || (renderer && renderer->isReplaced()))
     2460        interfaceMask |= 1 << WAI_HYPERLINK;
     2461
    24502462    // Text & Editable Text
    24512463    if (role == StaticTextRole || coreObject->isMenuListOption())
    24522464        interfaceMask |= 1 << WAI_TEXT;
    2453     else if (coreObject->isAccessibilityRenderObject()) {
     2465    else {
    24542466        if (coreObject->isTextControl()) {
    24552467            interfaceMask |= 1 << WAI_TEXT;
     
    24572469                interfaceMask |= 1 << WAI_EDITABLE_TEXT;
    24582470        } else {
    2459             AccessibilityRenderObject* axRenderObject = static_cast<AccessibilityRenderObject*>(coreObject);
    2460             RenderObject* renderer = axRenderObject->renderer();
    24612471            if (role != TableRole) {
    24622472                interfaceMask |= 1 << WAI_HYPERTEXT;
     
    26062616        else if (!isStartOfLine(endPosition)) {
    26072617            RefPtr<Range> range = makeRange(startPosition, endPosition.previous());
    2608             offset = TextIterator::rangeLength(range.get()) + 1;
     2618            offset = TextIterator::rangeLength(range.get(), true) + 1;
    26092619        } else {
    26102620            RefPtr<Range> range = makeRange(startPosition, endPosition);
    2611             offset = TextIterator::rangeLength(range.get());
     2621            offset = TextIterator::rangeLength(range.get(), true);
    26122622        }
    26132623
  • trunk/Source/WebCore/accessibility/gtk/WebKitAccessibleHyperlink.cpp

    r83064 r83493  
    199199{
    200200    // This is going to be the actual length in most of the cases
    201     int baseLength = TextIterator::rangeLength(range);
     201    int baseLength = TextIterator::rangeLength(range, true);
    202202
    203203    // Check whether the current hyperlink belongs to a list item.
  • trunk/Source/WebCore/editing/TextIterator.cpp

    r83081 r83493  
    258258    , m_handledFirstLetter(false)
    259259    , m_ignoresStyleVisibility(false)
     260    , m_emitsObjectReplacementCharacters(false)
    260261{
    261262}
     
    276277    , m_handledFirstLetter(false)
    277278    , m_ignoresStyleVisibility(behavior & TextIteratorIgnoresStyleVisibility)
     279    , m_emitsObjectReplacementCharacters(behavior & TextIteratorEmitsObjectReplacementCharacters)
    278280{
    279281    if (!r)
     
    639641
    640642    m_hasEmitted = true;
     643
     644    if (m_emitsObjectReplacementCharacters && renderer && renderer->isReplaced()) {
     645        emitCharacter(objectReplacementCharacter, m_node->parentNode(), m_node, 0, 1);
     646        return true;
     647    }
    641648
    642649    if (m_emitsCharactersBetweenAllVisiblePositions) {
  • trunk/Source/WebCore/editing/TextIterator.h

    r83081 r83493  
    4242    TextIteratorEntersTextControls = 1 << 1,
    4343    TextIteratorEmitsTextsWithoutTranscoding = 1 << 2,
    44     TextIteratorIgnoresStyleVisibility = 1 << 3
     44    TextIteratorIgnoresStyleVisibility = 1 << 3,
     45    TextIteratorEmitsObjectReplacementCharacters = 1 << 4
    4546};
    4647   
     
    180181    // Used when the visibility of the style should not affect text gathering.
    181182    bool m_ignoresStyleVisibility;
     183    // Used when emitting the special 0xFFFC character is required.
     184    bool m_emitsObjectReplacementCharacters;
    182185};
    183186
  • trunk/Source/WebKit/gtk/ChangeLog

    r83333 r83493  
     12011-04-11  Mario Sanchez Prada  <msanchez@igalia.com>
     2
     3        Reviewed by Chris Fleizach.
     4
     5        [Gtk] Implement support for Embedded Objects
     6        https://bugs.webkit.org/show_bug.cgi?id=52148
     7
     8        New accessibility unit test for embedded objects.
     9
     10        * tests/testatk.c:
     11        (testWebkitAtkEmbeddedObjects): New unit test.
     12        (main): Added the new unit test.
     13
    1142011-04-08  Dominic Cooney  <dominicc@google.com>
    215
  • trunk/Source/WebKit/gtk/tests/testatk.c

    r81587 r83493  
    5151static const char* comboBoxSelector = "<html><body><select><option selected value='foo'>foo</option><option value='bar'>bar</option></select></body></html>";
    5252
     53static const char* embeddedObjects = "<html><body><p>Choose: <input value='foo' type='checkbox'/>foo <input value='bar' type='checkbox'/>bar (pick one)</p><p>Choose: <select name='foo'><option>bar</option><option>baz</option></select> (pick one)</p><p><input name='foobarbutton' value='foobar' type='button'/></p></body></html>";
     54
    5355static const char* formWithTextInputs = "<html><body><form><input type='text' name='entry' /></form></body></html>";
    5456
     
    478480    g_object_unref(item1);
    479481    g_object_unref(item2);
     482    g_object_unref(webView);
     483}
     484
     485static void testWebkitAtkEmbeddedObjects()
     486{
     487    WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
     488    g_object_ref_sink(webView);
     489    GtkAllocation allocation = { 0, 0, 800, 600 };
     490    gtk_widget_size_allocate(GTK_WIDGET(webView), &allocation);
     491    webkit_web_view_load_string(webView, embeddedObjects, 0, 0, 0);
     492
     493    /* Wait for the accessible objects to be created. */
     494    waitForAccessibleObjects();
     495
     496    AtkObject* object = gtk_widget_get_accessible(GTK_WIDGET(webView));
     497    g_assert(object);
     498
     499    AtkText* paragraph1 = ATK_TEXT(atk_object_ref_accessible_child(object, 0));
     500    g_assert(ATK_IS_TEXT(paragraph1));
     501    g_assert(ATK_IS_HYPERTEXT(paragraph1));
     502
     503    const gchar* expectedText = "Choose: \357\277\274foo \357\277\274bar (pick one)";
     504    char* text = atk_text_get_text(paragraph1, 0, -1);
     505    g_assert_cmpstr(text, ==, expectedText);
     506    g_free(text);
     507
     508    gint nLinks = atk_hypertext_get_n_links(ATK_HYPERTEXT(paragraph1));
     509    g_assert_cmpint(nLinks, ==, 2);
     510
     511    AtkHyperlink* hLink = atk_hypertext_get_link(ATK_HYPERTEXT(paragraph1), 0);
     512    g_assert(ATK_HYPERLINK(hLink));
     513    AtkObject* hLinkObject = atk_hyperlink_get_object(hLink, 0);
     514    g_assert(ATK_OBJECT(hLinkObject));
     515    g_assert(atk_object_get_role(hLinkObject) == ATK_ROLE_CHECK_BOX);
     516    g_assert_cmpint(atk_hyperlink_get_start_index(hLink), ==, 8);
     517    g_assert_cmpint(atk_hyperlink_get_end_index(hLink), ==, 9);
     518    g_assert_cmpint(atk_hyperlink_get_n_anchors(hLink), ==, 1);
     519    g_assert_cmpstr(atk_hyperlink_get_uri(hLink, 0), ==, 0);
     520
     521    AtkText* paragraph2 = ATK_TEXT(atk_object_ref_accessible_child(object, 1));
     522    g_assert(ATK_IS_TEXT(paragraph2));
     523    g_assert(ATK_IS_HYPERTEXT(paragraph2));
     524
     525    expectedText = "Choose: \357\277\274 (pick one)";
     526    text = atk_text_get_text(paragraph2, 0, -1);
     527    g_assert_cmpstr(text, ==, expectedText);
     528    g_free(text);
     529
     530    nLinks = atk_hypertext_get_n_links(ATK_HYPERTEXT(paragraph2));
     531    g_assert_cmpint(nLinks, ==, 1);
     532
     533    hLink = atk_hypertext_get_link(ATK_HYPERTEXT(paragraph2), 0);
     534    g_assert(ATK_HYPERLINK(hLink));
     535    hLinkObject = atk_hyperlink_get_object(hLink, 0);
     536    g_assert(ATK_OBJECT(hLinkObject));
     537    g_assert(atk_object_get_role(hLinkObject) == ATK_ROLE_COMBO_BOX);
     538    g_assert_cmpint(atk_hyperlink_get_start_index(hLink), ==, 8);
     539    g_assert_cmpint(atk_hyperlink_get_end_index(hLink), ==, 9);
     540    g_assert_cmpint(atk_hyperlink_get_n_anchors(hLink), ==, 1);
     541    g_assert_cmpstr(atk_hyperlink_get_uri(hLink, 0), ==, 0);
     542
     543    AtkText* paragraph3 = ATK_TEXT(atk_object_ref_accessible_child(object, 2));
     544    g_assert(ATK_IS_TEXT(paragraph3));
     545    g_assert(ATK_IS_HYPERTEXT(paragraph3));
     546
     547    expectedText = "\357\277\274";
     548    text = atk_text_get_text(paragraph3, 0, -1);
     549    g_assert_cmpstr(text, ==, expectedText);
     550    g_free(text);
     551
     552    nLinks = atk_hypertext_get_n_links(ATK_HYPERTEXT(paragraph3));
     553    g_assert_cmpint(nLinks, ==, 1);
     554
     555    hLink = atk_hypertext_get_link(ATK_HYPERTEXT(paragraph3), 0);
     556    g_assert(ATK_HYPERLINK(hLink));
     557    hLinkObject = atk_hyperlink_get_object(hLink, 0);
     558    g_assert(ATK_OBJECT(hLinkObject));
     559    g_assert(atk_object_get_role(hLinkObject) == ATK_ROLE_PUSH_BUTTON);
     560    g_assert_cmpint(atk_hyperlink_get_start_index(hLink), ==, 0);
     561    g_assert_cmpint(atk_hyperlink_get_end_index(hLink), ==, 1);
     562    g_assert_cmpint(atk_hyperlink_get_n_anchors(hLink), ==, 1);
     563    g_assert_cmpstr(atk_hyperlink_get_uri(hLink, 0), ==, 0);
     564
     565    g_object_unref(paragraph1);
     566    g_object_unref(paragraph2);
     567    g_object_unref(paragraph3);
    480568    g_object_unref(webView);
    481569}
     
    15801668    g_test_add_func("/webkit/atk/caretOffsetsAndExtranousWhiteSpaces", testWebkitAtkCaretOffsetsAndExtranousWhiteSpaces);
    15811669    g_test_add_func("/webkit/atk/comboBox", testWebkitAtkComboBox);
     1670    g_test_add_func("/webkit/atk/embeddedObjects", testWebkitAtkEmbeddedObjects);
    15821671    g_test_add_func("/webkit/atk/getTextAtOffset", testWebkitAtkGetTextAtOffset);
    15831672    g_test_add_func("/webkit/atk/getTextAtOffsetForms", testWebkitAtkGetTextAtOffsetForms);
Note: See TracChangeset for help on using the changeset viewer.