Changeset 105590 in webkit


Ignore:
Timestamp:
Jan 22, 2012 11:29:04 AM (12 years ago)
Author:
mario@webkit.org
Message:

[GTK] ATK text-caret-moved and text-selection-changed events not being emitted
https://bugs.webkit.org/show_bug.cgi?id=76069

Reviewed by Martin Robinson.

Source/WebCore:

Fix bug introduced with patch for Bug 72830.

  • accessibility/AccessibilityObject.cpp:

(WebCore::AccessibilityObject::isDescendantOfObject): New function,
to check if an accessibility object is a descendant of other object.
(WebCore::AccessibilityObject::isAncestorOfObject): New function,
to check if an accessibility object is an ancestor of other object.

  • accessibility/AccessibilityObject.h:
  • accessibility/gtk/AccessibilityObjectWrapperAtk.cpp:

(webkit_accessible_text_get_caret_offset): Make sure to pass the
right reference object to objectFocusedAndCaretOffsetUnignored.
(objectFocusedAndCaretOffsetUnignored): Use positionBeforeNode
instead of firstPositionInNode for calculating the begining of the
range used to calculate the offsets. Ensure that the reference
object is never a descendant of the actual object being returned.

  • editing/gtk/FrameSelectionGtk.cpp:

(WebCore::FrameSelection::notifyAccessibilityForSelectionChange):
Pass the right accessibility object associated with the current
selection to objectFocusedAndCaretOffsetUnignored.

Source/WebKit/gtk:

Update caret browsing related unit tests to check emissions of
'text-caret-moved' and 'text-selection-changed' signals.

  • tests/testatk.c:

(textCaretMovedCallback): New callback for 'text-caret-moved'.
(testWebkitAtkCaretOffsets): Check emissions of 'text-caret-moved'.
(textSelectionChangedCallback): New callback for 'text-selection-changed'.
(testWebkitAtkTextSelections): Check emissions of 'text-selection-changed'.

Location:
trunk/Source
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r105583 r105590  
     12012-01-22  Mario Sanchez Prada  <msanchez@igalia.com>
     2
     3        [GTK] ATK text-caret-moved and text-selection-changed events not being emitted
     4        https://bugs.webkit.org/show_bug.cgi?id=76069
     5
     6        Reviewed by Martin Robinson.
     7
     8        Fix bug introduced with patch for Bug 72830.
     9
     10        * accessibility/AccessibilityObject.cpp:
     11        (WebCore::AccessibilityObject::isDescendantOfObject): New function,
     12        to check if an accessibility object is a descendant of other object.
     13        (WebCore::AccessibilityObject::isAncestorOfObject): New function,
     14        to check if an accessibility object is an ancestor of other object.
     15        * accessibility/AccessibilityObject.h:
     16
     17        * accessibility/gtk/AccessibilityObjectWrapperAtk.cpp:
     18        (webkit_accessible_text_get_caret_offset): Make sure to pass the
     19        right reference object to objectFocusedAndCaretOffsetUnignored.
     20        (objectFocusedAndCaretOffsetUnignored): Use positionBeforeNode
     21        instead of firstPositionInNode for calculating the begining of the
     22        range used to calculate the offsets. Ensure that the reference
     23        object is never a descendant of the actual object being returned.
     24
     25        * editing/gtk/FrameSelectionGtk.cpp:
     26        (WebCore::FrameSelection::notifyAccessibilityForSelectionChange):
     27        Pass the right accessibility object associated with the current
     28        selection to objectFocusedAndCaretOffsetUnignored.
     29
    1302012-01-21  David Reveman  <reveman@chromium.org>
    231
  • trunk/Source/WebCore/accessibility/AccessibilityObject.cpp

    r105295 r105590  
    12941294    return AccessibilityOrientationHorizontal;
    12951295}   
     1296
     1297bool AccessibilityObject::isDescendantOfObject(const AccessibilityObject* axObject) const
     1298{
     1299    if (!axObject || !axObject->hasChildren())
     1300        return false;
     1301
     1302    for (const AccessibilityObject* parent = parentObject(); parent; parent = parent->parentObject()) {
     1303        if (parent == axObject)
     1304            return true;
     1305    }
     1306    return false;
     1307}
     1308
     1309bool AccessibilityObject::isAncestorOfObject(const AccessibilityObject* axObject) const
     1310{
     1311    if (!axObject)
     1312        return false;
     1313
     1314    return this == axObject || axObject->isDescendantOfObject(this);
     1315}
    12961316
    12971317typedef HashMap<String, AccessibilityRole, CaseFoldingHash> ARIARoleMap;
  • trunk/Source/WebCore/accessibility/AccessibilityObject.h

    r105295 r105590  
    565565    virtual void handleActiveDescendantChanged() { }
    566566    virtual void handleAriaExpandedChanged() { }
     567    bool isDescendantOfObject(const AccessibilityObject*) const;
     568    bool isAncestorOfObject(const AccessibilityObject*) const;
    567569   
    568570    static AccessibilityRole ariaRoleToWebCoreRole(const String&);
  • trunk/Source/WebCore/accessibility/gtk/AccessibilityObjectWrapperAtk.cpp

    r104446 r105590  
    13461346        return 0;
    13471347
     1348    // We need to make sure we pass a valid object as reference.
     1349    if (coreObject->accessibilityIsIgnored())
     1350        coreObject = coreObject->parentObjectUnignored();
     1351    if (!coreObject)
     1352        return 0;
     1353
    13481354    int offset;
    13491355    if (!objectFocusedAndCaretOffsetUnignored(coreObject, offset))
     
    27372743
    27382744    // Look for the actual (not ignoring accessibility) selected object.
    2739     if (focusedObject->accessibilityIsIgnored())
    2740         focusedObject = focusedObject->parentObjectUnignored();
    2741     if (!focusedObject)
     2745    AccessibilityObject* firstUnignoredParent = focusedObject;
     2746    if (firstUnignoredParent->accessibilityIsIgnored())
     2747        firstUnignoredParent = firstUnignoredParent->parentObjectUnignored();
     2748    if (!firstUnignoredParent)
    27422749        return 0;
    27432750
    27442751    // Don't ignore links if the offset is being requested for a link.
    2745     if (!referenceObject->isLink() && focusedObject->isLink())
    2746         focusedObject = focusedObject->parentObjectUnignored();
    2747     if (!focusedObject)
    2748         return 0;
     2752    if (!referenceObject->isLink() && firstUnignoredParent->isLink())
     2753        firstUnignoredParent = firstUnignoredParent->parentObjectUnignored();
     2754    if (!firstUnignoredParent)
     2755        return 0;
     2756
     2757    // The reference object must either coincide with the focused
     2758    // object being considered, or be a descendant of it.
     2759    if (referenceObject->isDescendantOfObject(firstUnignoredParent))
     2760        referenceObject = firstUnignoredParent;
    27492761
    27502762    Node* startNode = 0;
    2751     if (focusedObject != referenceObject || focusedObject->isTextControl()) {
     2763    if (firstUnignoredParent != referenceObject || firstUnignoredParent->isTextControl()) {
    27522764        // We need to use the first child's node of the reference
    27532765        // object as the start point to calculate the caret offset
     
    27602772    }
    27612773    if (!startNode)
    2762         startNode = focusedObject->node();
    2763 
    2764     VisiblePosition startPosition = VisiblePosition(firstPositionInNode(startNode), DOWNSTREAM);
    2765     VisiblePosition endPosition = focusedObject->selection().visibleEnd();
     2774        startNode = firstUnignoredParent->node();
     2775
     2776    VisiblePosition startPosition = VisiblePosition(positionBeforeNode(startNode), DOWNSTREAM);
     2777    VisiblePosition endPosition = firstUnignoredParent->selection().visibleEnd();
    27662778
    27672779    if (startPosition == endPosition)
     
    27752787    }
    27762788
    2777     return focusedObject;
     2789    return firstUnignoredParent;
    27782790}
    27792791
  • trunk/Source/WebCore/editing/gtk/FrameSelectionGtk.cpp

    r104922 r105590  
    8585        return;
    8686
    87     // Look for the accessibility object for the Frame.
    88     AccessibilityObject* accessibilityObject = m_frame->document()->axObjectCache()->rootObjectForFrame(m_frame);
     87    RenderObject* focusedNode = m_selection.end().containerNode()->renderer();
     88    AccessibilityObject* accessibilityObject = m_frame->document()->axObjectCache()->getOrCreate(focusedNode);
     89
     90    // Need to check this as getOrCreate could return 0.
    8991    if (!accessibilityObject)
    9092        return;
  • trunk/Source/WebKit/gtk/ChangeLog

    r105326 r105590  
     12012-01-22  Mario Sanchez Prada  <msanchez@igalia.com>
     2
     3        [GTK] ATK text-caret-moved and text-selection-changed events not being emitted
     4        https://bugs.webkit.org/show_bug.cgi?id=76069
     5
     6        Reviewed by Martin Robinson.
     7
     8        Update caret browsing related unit tests to check emissions of
     9        'text-caret-moved' and 'text-selection-changed' signals.
     10
     11        * tests/testatk.c:
     12        (textCaretMovedCallback): New callback for 'text-caret-moved'.
     13        (testWebkitAtkCaretOffsets): Check emissions of 'text-caret-moved'.
     14        (textSelectionChangedCallback): New callback for 'text-selection-changed'.
     15        (testWebkitAtkTextSelections): Check emissions of 'text-selection-changed'.
     16
    1172012-01-18  Evan Nemerson  <evan@coeus-group.com>
    218
  • trunk/Source/WebKit/gtk/tests/testatk.c

    r104922 r105590  
    255255}
    256256
     257static gchar* textCaretMovedResult = 0;
     258
     259static void textCaretMovedCallback(AtkText* text, gint pos, gpointer data)
     260{
     261    g_assert(ATK_IS_TEXT(text));
     262
     263    g_free(textCaretMovedResult);
     264    AtkRole role = atk_object_get_role(ATK_OBJECT(text));
     265    textCaretMovedResult = g_strdup_printf("|%s|%d|", atk_role_get_name(role), pos);
     266}
     267
    257268static void testWebkitAtkCaretOffsets()
    258269{
     
    268279    AtkObject* header = atk_object_ref_accessible_child(object, 0);
    269280    g_assert(ATK_IS_TEXT(header));
     281    g_signal_connect(header, "text-caret-moved", G_CALLBACK(textCaretMovedCallback), 0);
     282
    270283    gchar* text = atk_text_get_text(ATK_TEXT(header), 0, -1);
    271284    g_assert_cmpstr(text, ==, "A text header");
     
    277290    gint offset = atk_text_get_caret_offset(ATK_TEXT(header));
    278291    g_assert_cmpint(offset, ==, 5);
     292    g_assert_cmpstr(textCaretMovedResult, ==, "|heading|5|");
    279293
    280294    AtkObject* paragraph = atk_object_ref_accessible_child(object, 1);
    281295    g_assert(ATK_IS_TEXT(paragraph));
     296    g_signal_connect(paragraph, "text-caret-moved", G_CALLBACK(textCaretMovedCallback), 0);
     297
    282298    text = atk_text_get_text(ATK_TEXT(paragraph), 0, -1);
    283299    g_assert_cmpstr(text, ==, "A paragraph with a link in the middle");
     
    289305    offset = atk_text_get_caret_offset(ATK_TEXT(paragraph));
    290306    g_assert_cmpint(offset, ==, 5);
     307    g_assert_cmpstr(textCaretMovedResult, ==, "|paragraph|5|");
    291308
    292309    result = atk_text_set_caret_offset(ATK_TEXT(paragraph), 20);
     
    294311    offset = atk_text_get_caret_offset(ATK_TEXT(paragraph));
    295312    g_assert_cmpint(offset, ==, 20);
     313    g_assert_cmpstr(textCaretMovedResult, ==, "|paragraph|20|");
    296314
    297315    result = atk_text_set_caret_offset(ATK_TEXT(paragraph), 30);
     
    299317    offset = atk_text_get_caret_offset(ATK_TEXT(paragraph));
    300318    g_assert_cmpint(offset, ==, 30);
     319    g_assert_cmpstr(textCaretMovedResult, ==, "|paragraph|30|");
     320
     321    AtkObject* link = atk_object_ref_accessible_child(paragraph, 0);
     322    g_assert(ATK_IS_TEXT(link));
     323    text = atk_text_get_text(ATK_TEXT(link), 0, -1);
     324    g_assert_cmpstr(text, ==, "with a link");
     325    g_free (text);
     326
     327    result = atk_text_set_caret_offset(ATK_TEXT(link), 5);
     328    g_assert_cmpint(result, ==, TRUE);
     329    offset = atk_text_get_caret_offset(ATK_TEXT(link));
     330    g_assert_cmpint(offset, ==, 5);
     331    /* Positions inside links are reported relative to the paragraph. */
     332    g_assert_cmpstr(textCaretMovedResult, ==, "|paragraph|17|");
    301333
    302334    AtkObject* list = atk_object_ref_accessible_child(object, 2);
     
    356388    g_assert_cmpint(offset, ==, 5);
    357389
     390    g_free(textCaretMovedResult);
     391
    358392    g_object_unref(header);
    359393    g_object_unref(paragraph);
     394    g_object_unref(link);
    360395    g_object_unref(list);
    361396    g_object_unref(listItem);
     
    10881123}
    10891124
     1125static gchar* textSelectionChangedResult = 0;
     1126
     1127static void textSelectionChangedCallback(AtkText* text, gpointer data)
     1128{
     1129    g_assert(ATK_IS_TEXT(text));
     1130
     1131    g_free(textSelectionChangedResult);
     1132    AtkRole role = atk_object_get_role(ATK_OBJECT(text));
     1133    int startOffset = 0;
     1134    int endOffset = 0;
     1135    atk_text_get_selection(ATK_TEXT(text), 0, &startOffset, &endOffset);
     1136    textSelectionChangedResult = g_strdup_printf("|%s|%d|%d|", atk_role_get_name(role), startOffset, endOffset);
     1137}
     1138
    10901139static void testWebkitAtkTextSelections()
    10911140{
     
    11011150    AtkText* paragraph1 = ATK_TEXT(atk_object_ref_accessible_child(object, 0));
    11021151    g_assert(ATK_IS_TEXT(paragraph1));
     1152    g_signal_connect(paragraph1, "text-selection-changed", G_CALLBACK(textSelectionChangedCallback), 0);
    11031153
    11041154    AtkText* paragraph2 = ATK_TEXT(atk_object_ref_accessible_child(object, 1));
    11051155    g_assert(ATK_IS_TEXT(paragraph2));
     1156    g_signal_connect(paragraph2, "text-selection-changed", G_CALLBACK(textSelectionChangedCallback), 0);
    11061157
    11071158    AtkText* link = ATK_TEXT(atk_object_ref_accessible_child(ATK_OBJECT(paragraph2), 0));
     
    11391190    g_assert(result);
    11401191    g_assert_cmpint(atk_text_get_n_selections(paragraph1), ==, 1);
     1192    g_assert_cmpstr(textSelectionChangedResult, ==, "|paragraph|5|25|");
    11411193    selectedText = atk_text_get_selection(paragraph1, 0, &startOffset, &endOffset);
    11421194    g_assert_cmpint(startOffset, ==, 5);
     
    11441196    g_assert_cmpstr(selectedText, ==, "agraph with plain te");
    11451197    g_free (selectedText);
     1198
    11461199    /* Try removing the selection from other AtkText object (should fail). */
    11471200    result = atk_text_remove_selection(paragraph2, 0);
     
    11861239    g_assert(result);
    11871240    g_assert_cmpint(atk_text_get_n_selections(paragraph2), ==, 1);
     1241    g_assert_cmpstr(textSelectionChangedResult, ==, "|paragraph|27|37|");
    11881242    selectedText = atk_text_get_selection(paragraph2, 0, &startOffset, &endOffset);
    11891243    g_assert_cmpint(startOffset, ==, 27);
     
    12341288    g_assert_cmpstr(selectedText, ==, "A list");
    12351289    g_free (selectedText);
     1290
     1291    g_free(textSelectionChangedResult);
    12361292
    12371293    g_object_unref(paragraph1);
Note: See TracChangeset for help on using the changeset viewer.