Changeset 72958 in webkit


Ignore:
Timestamp:
Nov 30, 2010 1:16:14 PM (13 years ago)
Author:
mario@webkit.org
Message:

2010-11-30 Mario Sanchez Prada <msanchez@igalia.com>

Reviewed by Chris Fleizach.

[GTK] Implement ROLE_COMBO_BOX
https://bugs.webkit.org/show_bug.cgi?id=25678

Implement the remaining bits for combo boxes.

This patch finishes the implementation, from the point of view of
the Atk library, of those objects exposed to ATK as combo boxes,
and their related elements (menus and menu items). It therefore
implements the proper interfaces for each type of object related
to combo boxes (AtkSelection for the combo box, AtkText for every
menu item and AtkAction for the combo box, the menu and the menu
items), takes care of emitting the proper signals when focus or a
given a selection changes and adds a new unit test to check all
this new stuff.

Make possible to ask an AccessibleMenuListOption for a sensible
string representation, so far only available through the private
and MSAA related method nameForMSAA. Just moved the implementation
of that method to an overriden version of stringValue(), which is
platform independent, and called that from nameForMSAA().

  • accessibility/AccessibilityMenuListOption.h:
  • accessibility/AccessibilityMenuListOption.cpp: (WebCore::AccessibilityMenuListOption::nameForMSAA): Just call to stringValue(), which holds from now on that used to be here. (WebCore::AccessibilityMenuListOption::stringValue): New, override of AccessibilityObject::stringValue() to return a proper string.

Emit the missing signals when a selection is made.

  • accessibility/gtk/AXObjectCacheAtk.cpp: (WebCore::AXObjectCache::postPlatformNotification): Emit the usual 'focus' signals when a selection is made over the combo box.
  • accessibility/gtk/AccessibilityObjectWrapperAtk.cpp: (setAtkStateSetFromCoreObject): Ensure the EXPANDABLE and EXPANDED Atk states are added to the state set when needed. (listObjectForSelection): New, returns the proper list object (the one holding the list of available options as its children) for an specific AtkObject implementing AtkSelection. This is needed because sometimes the selectable options are not directly children of the AtkSelection object (i.e. a combo box has a 'menu' object as its only child of it, holding the list of options as children). (optionFromList): Use listObjectForSelection() to get the actual object holding the list of children as the available options. (optionFromSelection): Add support for combo boxes. (webkit_accessible_selection_add_selection): Ditto. (webkit_accessible_selection_clear_selection): Ditto. (webkit_accessible_selection_get_selection_count): Ditto. (webkit_accessible_selection_is_child_selected): Ditto. (webkit_accessible_selection_remove_selection): Ditto. (webkit_accessible_text_get_text): Makes sure stringValue() is considered to get the result substring when it was already considered when checking the maximum text length for the object. (getInterfaceMaskFromObject): Make sure the AtkSelection interface is implemented for the combo boxes, that the AtkText is implemented for the menu items and that the AtkAction interface is now implemented for every object (WebCore will decide what to do).

Avoid a segfault crash when using this from unit tests.

  • platform/gtk/PopupMenuGtk.cpp: (WebCore::PopupMenuGtk::show): Make sure we got a valid GdkWindow before calling gdk_window_get_origin() over it.

2010-11-30 Mario Sanchez Prada <msanchez@igalia.com>

Reviewed by Chris Fleizach.

[GTK] Implement ROLE_COMBO_BOX
https://bugs.webkit.org/show_bug.cgi?id=25678

New test to check the implementation of the combo boxes.

  • tests/testatk.c: (testWebkitAtkComboBox): New test, checking that the roles and the implemented interfaces for a combo box and its descendants work. (main): Added the new unit test.
Location:
trunk
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r72956 r72958  
     12010-11-30  Mario Sanchez Prada  <msanchez@igalia.com>
     2
     3        Reviewed by Chris Fleizach.
     4
     5        [GTK] Implement ROLE_COMBO_BOX
     6        https://bugs.webkit.org/show_bug.cgi?id=25678
     7
     8        Implement the remaining bits for combo boxes.
     9
     10        This patch finishes the implementation, from the point of view of
     11        the Atk library, of those objects exposed to ATK as combo boxes,
     12        and their related elements (menus and menu items). It therefore
     13        implements the proper interfaces for each type of object related
     14        to combo boxes (AtkSelection for the combo box, AtkText for every
     15        menu item and AtkAction for the combo box, the menu and the menu
     16        items), takes care of emitting the proper signals when focus or a
     17        given a selection changes and adds a new unit test to check all
     18        this new stuff.
     19
     20        Make possible to ask an AccessibleMenuListOption for a sensible
     21        string representation, so far only available through the private
     22        and MSAA related method nameForMSAA. Just moved the implementation
     23        of that method to an overriden version of stringValue(), which is
     24        platform independent, and called that from nameForMSAA().
     25
     26        * accessibility/AccessibilityMenuListOption.h:
     27        * accessibility/AccessibilityMenuListOption.cpp:
     28        (WebCore::AccessibilityMenuListOption::nameForMSAA): Just call to
     29        stringValue(), which holds from now on that used to be here.
     30        (WebCore::AccessibilityMenuListOption::stringValue): New, override
     31        of AccessibilityObject::stringValue() to return a proper string.
     32
     33        Emit the missing signals when a selection is made.
     34
     35        * accessibility/gtk/AXObjectCacheAtk.cpp:
     36        (WebCore::AXObjectCache::postPlatformNotification): Emit the usual
     37        'focus' signals when a selection is made over the combo box.
     38
     39        * accessibility/gtk/AccessibilityObjectWrapperAtk.cpp:
     40        (setAtkStateSetFromCoreObject): Ensure the EXPANDABLE and EXPANDED
     41        Atk states are added to the state set when needed.
     42        (listObjectForSelection): New, returns the proper list object (the
     43        one holding the list of available options as its children) for an
     44        specific AtkObject implementing AtkSelection. This is needed
     45        because sometimes the selectable options are not directly children
     46        of the AtkSelection object (i.e. a combo box has a 'menu' object
     47        as its only child of it, holding the list of options as children).
     48        (optionFromList): Use listObjectForSelection() to get the actual
     49        object holding the list of children as the available options.
     50        (optionFromSelection): Add support for combo boxes.
     51        (webkit_accessible_selection_add_selection): Ditto.
     52        (webkit_accessible_selection_clear_selection): Ditto.
     53        (webkit_accessible_selection_get_selection_count): Ditto.
     54        (webkit_accessible_selection_is_child_selected): Ditto.
     55        (webkit_accessible_selection_remove_selection): Ditto.
     56        (webkit_accessible_text_get_text): Makes sure stringValue() is
     57        considered to get the result substring when it was already
     58        considered when checking the maximum text length for the object.
     59        (getInterfaceMaskFromObject): Make sure the AtkSelection interface
     60        is implemented for the combo boxes, that the AtkText is
     61        implemented for the menu items and that the AtkAction interface is
     62        now implemented for every object (WebCore will decide what to do).
     63
     64        Avoid a segfault crash when using this from unit tests.
     65
     66        * platform/gtk/PopupMenuGtk.cpp:
     67        (WebCore::PopupMenuGtk::show): Make sure we got a valid GdkWindow
     68        before calling gdk_window_get_origin() over it.
     69
    1702010-11-30  Andreas Kling  <kling@webkit.org>
    271
  • trunk/WebCore/accessibility/AccessibilityMenuListOption.cpp

    r72673 r72958  
    9292String AccessibilityMenuListOption::nameForMSAA() const
    9393{
    94     return static_cast<HTMLOptionElement*>(m_element.get())->text();
     94    return stringValue();
    9595}
    9696
     
    111111}
    112112
     113String AccessibilityMenuListOption::stringValue() const
     114{
     115    return static_cast<HTMLOptionElement*>(m_element.get())->text();
     116}
     117
    113118} // namespace WebCore
  • trunk/WebCore/accessibility/AccessibilityMenuListOption.h

    r72673 r72958  
    6060    virtual bool canSetSelectedAttribute() const;
    6161    virtual IntRect elementRect() const;
     62    virtual String stringValue() const;
    6263
    6364    RefPtr<HTMLElement> m_element;
  • trunk/WebCore/accessibility/gtk/AXObjectCacheAtk.cpp

    r72673 r72958  
    9696void AXObjectCache::postPlatformNotification(AccessibilityObject* coreObject, AXNotification notification)
    9797{
     98    AtkObject* axObject = coreObject->wrapper();
     99    if (!axObject)
     100        return;
     101
    98102    if (notification == AXCheckedStateChanged) {
    99103        if (!coreObject->isCheckboxOrRadio())
    100104            return;
    101         g_signal_emit_by_name(coreObject->wrapper(), "state-change", "checked", coreObject->isChecked());
     105        g_signal_emit_by_name(axObject, "state-change", "checked", coreObject->isChecked());
     106    } else if (notification == AXMenuListValueChanged) {
     107        if (!coreObject->isMenuList())
     108            return;
     109        g_signal_emit_by_name(axObject, "focus-event", true);
     110        g_signal_emit_by_name(axObject, "state-change", "focused", true);
    102111    } else if (notification == AXSelectedChildrenChanged)
    103112        notifyChildrenSelectionChange(coreObject);
  • trunk/WebCore/accessibility/gtk/AccessibilityObjectWrapperAtk.cpp

    r72904 r72958  
    5959#include "RenderListMarker.h"
    6060#include "RenderText.h"
     61#include "SelectElement.h"
    6162#include "TextEncoding.h"
    6263#include "TextIterator.h"
     
    501502    }
    502503
     504    if (coreObject->canSetExpandedAttribute())
     505        atk_state_set_add_state(stateSet, ATK_STATE_EXPANDABLE);
     506
     507    if (coreObject->isExpanded())
     508        atk_state_set_add_state(stateSet, ATK_STATE_EXPANDED);
     509
    503510    if (coreObject->canSetFocusAttribute())
    504511        atk_state_set_add_state(stateSet, ATK_STATE_FOCUSABLE);
     
    695702// Selection (for controls)
    696703
     704static AccessibilityObject* listObjectForSelection(AtkSelection* selection)
     705{
     706    AccessibilityObject* coreSelection = core(selection);
     707
     708    // Only list boxes and menu lists supported so far.
     709    if (!coreSelection->isListBox() && !coreSelection->isMenuList())
     710        return 0;
     711
     712    // For list boxes the list object is just itself.
     713    if (coreSelection->isListBox())
     714        return coreSelection;
     715
     716    // For menu lists we need to return the first accessible child,
     717    // with role MenuListPopupRole, since that's the one holding the list
     718    // of items with role MenuListOptionRole.
     719    AccessibilityObject::AccessibilityChildrenVector children = coreSelection->children();
     720    if (!children.size())
     721        return 0;
     722
     723    AccessibilityObject* listObject = children.at(0).get();
     724    if (!listObject->isMenuListPopup())
     725        return 0;
     726
     727    return listObject;
     728}
     729
    697730static AccessibilityObject* optionFromList(AtkSelection* selection, gint i)
    698731{
     
    701734        return 0;
    702735
    703     AccessibilityRenderObject::AccessibilityChildrenVector options = core(selection)->children();
     736    // Need to select the proper list object depending on the type.
     737    AccessibilityObject* listObject = listObjectForSelection(selection);
     738    if (!listObject)
     739        return 0;
     740
     741    AccessibilityRenderObject::AccessibilityChildrenVector options = listObject->children();
    704742    if (i < static_cast<gint>(options.size()))
    705743        return options.at(i).get();
     
    713751
    714752    AccessibilityObject* coreSelection = core(selection);
    715     if (!coreSelection || i < 0)
     753    if (!coreSelection || !coreSelection->isAccessibilityRenderObject() || i < 0)
    716754        return 0;
    717755
    718756    AccessibilityRenderObject::AccessibilityChildrenVector selectedItems;
    719757    if (coreSelection->isListBox())
    720         static_cast<AccessibilityListBox*>(coreSelection)->selectedChildren(selectedItems);
    721 
    722     // TODO: Combo boxes
     758        coreSelection->selectedChildren(selectedItems);
     759    else if (coreSelection->isMenuList()) {
     760        RenderObject* renderer = toAccessibilityRenderObject(coreSelection)->renderer();
     761        if (!renderer)
     762            return 0;
     763
     764        SelectElement* selectNode = toSelectElement(static_cast<Element*>(renderer->node()));
     765        int selectedIndex = selectNode->selectedIndex();
     766        const Vector<Element*> listItems = selectNode->listItems();
     767
     768        if (selectedIndex < 0 || selectedIndex >= static_cast<int>(listItems.size()))
     769            return 0;
     770
     771        return optionFromList(selection, selectedIndex);
     772    }
    723773
    724774    if (i < static_cast<gint>(selectedItems.size()))
     
    729779
    730780static gboolean webkit_accessible_selection_add_selection(AtkSelection* selection, gint i)
    731 {
    732     AccessibilityObject* option = optionFromList(selection, i);
    733     if (option && core(selection)->isListBox()) {
    734         AccessibilityListBoxOption* listBoxOption = static_cast<AccessibilityListBoxOption*>(option);
    735         listBoxOption->setSelected(true);
    736         return listBoxOption->isSelected();
    737     }
    738 
    739     return false;
    740 }
    741 
    742 static gboolean webkit_accessible_selection_clear_selection(AtkSelection* selection)
    743781{
    744782    AccessibilityObject* coreSelection = core(selection);
     
    746784        return false;
    747785
     786    AccessibilityObject* option = optionFromList(selection, i);
     787    if (option && (coreSelection->isListBox() || coreSelection->isMenuList())) {
     788        option->setSelected(true);
     789        return option->isSelected();
     790    }
     791
     792    return false;
     793}
     794
     795static gboolean webkit_accessible_selection_clear_selection(AtkSelection* selection)
     796{
     797    AccessibilityObject* coreSelection = core(selection);
     798    if (!coreSelection)
     799        return false;
     800
    748801    AccessibilityRenderObject::AccessibilityChildrenVector selectedItems;
    749     if (coreSelection->isListBox()) {
     802    if (coreSelection->isListBox() || coreSelection->isMenuList()) {
    750803        // Set the list of selected items to an empty list; then verify that it worked.
    751804        AccessibilityListBox* listBox = static_cast<AccessibilityListBox*>(coreSelection);
     
    772825{
    773826    AccessibilityObject* coreSelection = core(selection);
    774     if (coreSelection && coreSelection->isListBox()) {
     827    if (!coreSelection || !coreSelection->isAccessibilityRenderObject())
     828        return 0;
     829
     830    if (coreSelection->isListBox()) {
    775831        AccessibilityRenderObject::AccessibilityChildrenVector selectedItems;
    776         static_cast<AccessibilityListBox*>(coreSelection)->selectedChildren(selectedItems);
     832        coreSelection->selectedChildren(selectedItems);
    777833        return static_cast<gint>(selectedItems.size());
    778834    }
    779835
     836    if (coreSelection->isMenuList()) {
     837        RenderObject* renderer = toAccessibilityRenderObject(coreSelection)->renderer();
     838        if (!renderer)
     839            return 0;
     840
     841        SelectElement* selectNode = toSelectElement(static_cast<Element*>(renderer->node()));
     842        int selectedIndex = selectNode->selectedIndex();
     843        const Vector<Element*> listItems = selectNode->listItems();
     844
     845        return selectedIndex >= 0 && selectedIndex < static_cast<int>(listItems.size());
     846    }
     847
    780848    return 0;
    781849}
     
    783851static gboolean webkit_accessible_selection_is_child_selected(AtkSelection* selection, gint i)
    784852{
     853    AccessibilityObject* coreSelection = core(selection);
     854    if (!coreSelection)
     855        return 0;
     856
    785857    AccessibilityObject* option = optionFromList(selection, i);
    786     if (option && core(selection)->isListBox())
    787         return static_cast<AccessibilityListBoxOption*>(option)->isSelected();
     858    if (option && (coreSelection->isListBox() || coreSelection->isMenuList()))
     859        return option->isSelected();
    788860
    789861    return false;
     
    792864static gboolean webkit_accessible_selection_remove_selection(AtkSelection* selection, gint i)
    793865{
     866    AccessibilityObject* coreSelection = core(selection);
     867    if (!coreSelection)
     868        return 0;
     869
    794870    // TODO: This is only getting called if i == 0. What is preventing the rest?
    795871    AccessibilityObject* option = optionFromSelection(selection, i);
    796     if (option && core(selection)->isListBox()) {
    797         AccessibilityListBoxOption* listBoxOption = static_cast<AccessibilityListBoxOption*>(option);
    798         listBoxOption->setSelected(false);
    799         return !listBoxOption->isSelected();
     872    if (option && (coreSelection->isListBox() || coreSelection->isMenuList())) {
     873        option->setSelected(false);
     874        return !option->isSelected();
    800875    }
    801876
     
    9701045    if (coreObject->isTextControl())
    9711046        ret = coreObject->doAXStringForRange(PlainTextRange(start, length));
    972     else
    973         ret = coreObject->textUnderElement().substring(start, length);
     1047    else {
     1048        ret = coreObject->stringValue().substring(start, length);
     1049        if (!ret)
     1050            ret = coreObject->textUnderElement().substring(start, length);
     1051    }
    9741052
    9751053    if (!ret.length()) {
     
    21782256
    21792257    // Action
    2180     if (!coreObject->actionVerb().isEmpty()) {
    2181         interfaceMask |= 1 << WAI_ACTION;
    2182 
    2183         if (!coreObject->accessibilityIsIgnored() && coreObject->isLink())
    2184             interfaceMask |= 1 << WAI_HYPERLINK;
    2185     }
     2258    // As the implementation of the AtkAction interface is a very
     2259    // basic one (just relays in executing the default action for each
     2260    // object, and only supports having one action per object), it is
     2261    // better just to implement this interface for every instance of
     2262    // the WebKitAccessible class and let WebCore decide what to do.
     2263    interfaceMask |= 1 << WAI_ACTION;
     2264
     2265    // Hyperlink
     2266    if (coreObject->isLink())
     2267        interfaceMask |= 1 << WAI_HYPERLINK;
    21862268
    21872269    // Selection
    2188     if (coreObject->isListBox())
     2270    if (coreObject->isListBox() || coreObject->isMenuList())
    21892271        interfaceMask |= 1 << WAI_SELECTION;
    21902272
    21912273    // Text & Editable Text
    2192     if (role == StaticTextRole)
     2274    if (role == StaticTextRole || coreObject->isMenuListOption())
    21932275        interfaceMask |= 1 << WAI_TEXT;
    21942276    else if (coreObject->isAccessibilityRenderObject()) {
  • trunk/WebCore/platform/gtk/PopupMenuGtk.cpp

    r72673 r72958  
    5959        gtk_container_foreach(GTK_CONTAINER(m_popup.get()), reinterpret_cast<GtkCallback>(menuRemoveItem), this);
    6060
    61     int x, y;
    62     gdk_window_get_origin(gtk_widget_get_window(GTK_WIDGET(view->hostWindow()->platformPageClient())), &x, &y);
     61    int x = 0;
     62    int y = 0;
     63    GdkWindow* window = gtk_widget_get_window(GTK_WIDGET(view->hostWindow()->platformPageClient()));
     64    if (window)
     65        gdk_window_get_origin(window, &x, &y);
    6366    m_menuPosition = view->contentsToWindow(rect.location());
    6467    m_menuPosition = IntPoint(m_menuPosition.x() + x, m_menuPosition.y() + y + rect.height());
  • trunk/WebKit/gtk/ChangeLog

    r72909 r72958  
     12010-11-30  Mario Sanchez Prada  <msanchez@igalia.com>
     2
     3        Reviewed by Chris Fleizach.
     4
     5        [GTK] Implement ROLE_COMBO_BOX
     6        https://bugs.webkit.org/show_bug.cgi?id=25678
     7
     8        New test to check the implementation of the combo boxes.
     9
     10        * tests/testatk.c:
     11        (testWebkitAtkComboBox): New test, checking that the roles and the
     12        implemented interfaces for a combo box and its descendants work.
     13        (main): Added the new unit test.
     14
    1152010-11-30  Carlos Garcia Campos  <cgarcia@igalia.com>
    216
  • trunk/WebKit/gtk/tests/testatk.c

    r72904 r72958  
    4545static const char* contentsInTableWithHeaders = "<html><body><table><tr><th>foo</th><th>bar</th><th colspan='2'>baz</th></tr><tr><th>qux</th><td>1</td><td>2</td><td>3</td></tr><tr><th rowspan='2'>quux</th><td>4</td><td>5</td><td>6</td></tr><tr><td>6</td><td>7</td><td>8</td></tr><tr><th>corge</th><td>9</td><td>10</td><td>11</td></tr></table><table><tr><td>1</td><td>2</td></tr><tr><td>3</td><td>4</td></tr></table></body></html>";
    4646
     47static const char* comboBoxSelector = "<html><body><select><option selected value='foo'>foo</option><option value='bar'>bar</option></select></body></html>";
     48
    4749static const char* formWithTextInputs = "<html><body><form><input type='text' name='entry' /></form></body></html>";
    4850
     
    220222    testGetTextFunction(textObject, atk_text_get_text_at_offset, ATK_TEXT_BOUNDARY_LINE_END,
    221223                        0, "This is a test. This is the second sentence. And this the third.", 0, 64);
     224}
     225
     226static void testWebkitAtkComboBox()
     227{
     228    WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
     229    g_object_ref_sink(webView);
     230    GtkAllocation allocation = { 0, 0, 800, 600 };
     231    gtk_widget_size_allocate(GTK_WIDGET(webView), &allocation);
     232    webkit_web_view_load_string(webView, comboBoxSelector, 0, 0, 0);
     233
     234    /* Wait for the accessible objects to be created. */
     235    waitForAccessibleObjects();
     236
     237    AtkObject* object = gtk_widget_get_accessible(GTK_WIDGET(webView));
     238    g_assert(object);
     239
     240    AtkObject* formObject = atk_object_ref_accessible_child(object, 0);
     241    g_assert(formObject);
     242
     243    AtkObject* comboBox = atk_object_ref_accessible_child(formObject, 0);
     244    g_assert(ATK_IS_OBJECT(comboBox));
     245
     246    AtkObject* menuPopup = atk_object_ref_accessible_child(comboBox, 0);
     247    g_assert(ATK_IS_OBJECT(menuPopup));
     248
     249    AtkObject* item1 = atk_object_ref_accessible_child(menuPopup, 0);
     250    g_assert(ATK_IS_OBJECT(item1));
     251
     252    AtkObject* item2 = atk_object_ref_accessible_child(menuPopup, 1);
     253    g_assert(ATK_IS_OBJECT(item2));
     254
     255    /* Check roles. */
     256    g_assert(atk_object_get_role(comboBox) == ATK_ROLE_COMBO_BOX);
     257    g_assert(atk_object_get_role(menuPopup) == ATK_ROLE_MENU);
     258    g_assert(atk_object_get_role(item1) == ATK_ROLE_MENU_ITEM);
     259    g_assert(atk_object_get_role(item2) == ATK_ROLE_MENU_ITEM);
     260
     261    /* Check the implementation of the AtkSelection interface. */
     262    g_assert(ATK_IS_SELECTION(comboBox));
     263    AtkSelection* atkSelection = ATK_SELECTION(comboBox);
     264    g_assert_cmpint(atk_selection_get_selection_count(atkSelection), ==, 1);
     265    g_assert(atk_selection_is_child_selected(atkSelection, 0));
     266    g_assert(!atk_selection_is_child_selected(atkSelection, 1));
     267    AtkObject* selectedItem = atk_selection_ref_selection(atkSelection, 0);
     268    g_assert(selectedItem == item1);
     269    g_object_unref(selectedItem);
     270
     271    /* Check the implementations of the AtkAction interface. */
     272    g_assert(ATK_IS_ACTION(comboBox));
     273    AtkAction* atkAction = ATK_ACTION(comboBox);
     274    g_assert_cmpint(atk_action_get_n_actions(atkAction), ==, 1);
     275    g_assert(atk_action_do_action(atkAction, 0));
     276
     277    g_assert(ATK_IS_ACTION(menuPopup));
     278    atkAction = ATK_ACTION(menuPopup);
     279    g_assert_cmpint(atk_action_get_n_actions(atkAction), ==, 1);
     280    g_assert(atk_action_do_action(atkAction, 0));
     281
     282    g_assert(ATK_IS_ACTION(item1));
     283    atkAction = ATK_ACTION(item1);
     284    g_assert_cmpint(atk_action_get_n_actions(atkAction), ==, 1);
     285    g_assert(atk_action_do_action(atkAction, 0));
     286
     287    g_assert(ATK_IS_ACTION(item2));
     288    atkAction = ATK_ACTION(item2);
     289    g_assert_cmpint(atk_action_get_n_actions(atkAction), ==, 1);
     290    g_assert(atk_action_do_action(atkAction, 0));
     291
     292    /* After selecting the second item, selection should have changed. */
     293    g_assert_cmpint(atk_selection_get_selection_count(atkSelection), ==, 1);
     294    g_assert(!atk_selection_is_child_selected(atkSelection, 0));
     295    g_assert(atk_selection_is_child_selected(atkSelection, 1));
     296    selectedItem = atk_selection_ref_selection(atkSelection, 0);
     297    g_assert(selectedItem == item2);
     298    g_object_unref(selectedItem);
     299
     300    /* Check the implementation of the AtkText interface. */
     301    g_assert(ATK_IS_TEXT(item1));
     302    AtkText* atkText = ATK_TEXT(item1);
     303    char *text = atk_text_get_text(atkText, 0, -1);
     304    g_assert_cmpstr(text, ==, "foo");
     305    g_free(text);
     306    text = atk_text_get_text(atkText, 0, 2);
     307    g_assert_cmpstr(text, ==, "fo");
     308    g_free(text);
     309
     310    g_assert(ATK_IS_TEXT(item2));
     311    atkText = ATK_TEXT(item2);
     312    text = atk_text_get_text(atkText, 0, -1);
     313    g_assert_cmpstr(text, ==, "bar");
     314    g_free(text);
     315    text = atk_text_get_text(atkText, 1, 3);
     316    g_assert_cmpstr(text, ==, "ar");
     317    g_free(text);
     318
     319    g_object_unref(formObject);
     320    g_object_unref(comboBox);
     321    g_object_unref(menuPopup);
     322    g_object_unref(item1);
     323    g_object_unref(item2);
     324    g_object_unref(webView);
    222325}
    223326
     
    12121315
    12131316    g_test_bug_base("https://bugs.webkit.org/");
     1317    g_test_add_func("/webkit/atk/comboBox", testWebkitAtkComboBox);
    12141318    g_test_add_func("/webkit/atk/getTextAtOffset", testWebkitAtkGetTextAtOffset);
    12151319    g_test_add_func("/webkit/atk/getTextAtOffsetForms", testWebkitAtkGetTextAtOffsetForms);
Note: See TracChangeset for help on using the changeset viewer.