Changeset 67383 in webkit
- Timestamp:
- Sep 13, 2010 5:29:26 AM (14 years ago)
- Location:
- trunk
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r67376 r67383 1 2010-09-13 Mario Sanchez Prada <msanchez@igalia.com> 2 3 Reviewed by Martin Robinson. 4 5 [GTK] ATs should be able to select/unselect text 6 https://bugs.webkit.org/show_bug.cgi?id=25673 7 8 Implement AtkText's setSelection and removeSelection functions 9 10 * accessibility/AccessibilityObject.cpp: 11 (WebCore::AccessibilityObject::visiblePositionRangeForRange): 12 Moved some GTK specific code from a ifdef-endif region to 13 AccessibilityObjectAtk.cpp 14 * accessibility/AccessibilityObject.h: 15 * accessibility/gtk/AccessibilityObjectAtk.cpp: 16 (WebCore::AccessibilityObject::getLengthForTextRange): New. 17 * accessibility/gtk/AccessibilityObjectWrapperAtk.cpp: 18 (webkit_accessible_text_remove_selection): Implemented following 19 the lead of GAIL's implementation of the AtkText interface. 20 (webkit_accessible_text_set_selection): Implemented following 21 the lead of GAIL's implementation of the AtkText interface. 22 (webkit_accessible_text_set_caret_offset): Changed to directly use 23 visiblePositionRangeForRange now that there's no longer a problem 24 with that, as it was in the past (only worked for text controls). 25 1 26 2010-08-27 Kenneth Rohde Christiansen <kenneth@webkit.org> 2 27 -
trunk/WebCore/accessibility/AccessibilityObject.cpp
r65016 r67383 374 374 VisiblePositionRange AccessibilityObject::visiblePositionRangeForRange(const PlainTextRange& range) const 375 375 { 376 unsigned textLength = text().length(); 377 #if PLATFORM(GTK) 378 // Gtk ATs need this for all text objects; not just text controls. 379 if (!textLength) { 380 Node* node = this->node(); 381 RenderObject* renderer = node ? node->renderer() : 0; 382 if (renderer && renderer->isText()) { 383 RenderText* renderText = toRenderText(renderer); 384 textLength = renderText ? renderText->textLength() : 0; 385 } 386 // Get the text length from the elements under the 387 // accessibility object if the value is still zero. 388 if (!textLength && allowsTextRanges()) 389 textLength = textUnderElement().length(); 390 } 391 #endif 376 unsigned textLength = getLengthForTextRange(); 392 377 if (range.start + range.length > textLength) 393 378 return VisiblePositionRange(); -
trunk/WebCore/accessibility/AccessibilityObject.h
r65021 r67383 575 575 #if PLATFORM(GTK) 576 576 bool allowsTextRanges() const; 577 unsigned getLengthForTextRange() const; 577 578 #else 578 579 bool allowsTextRanges() const { return isTextControl(); } 580 unsigned getLengthForTextRange() const { return text().length(); } 579 581 #endif 580 582 -
trunk/WebCore/accessibility/gtk/AccessibilityObjectAtk.cpp
r66964 r67383 21 21 #include "config.h" 22 22 #include "AccessibilityObject.h" 23 #include "RenderObject.h" 24 #include "RenderText.h" 23 25 24 26 #include <glib-object.h> … … 103 105 } 104 106 107 unsigned AccessibilityObject::getLengthForTextRange() const 108 { 109 unsigned textLength = text().length(); 110 111 if (textLength) 112 return textLength; 113 114 // Gtk ATs need this for all text objects; not just text controls. 115 Node* node = this->node(); 116 RenderObject* renderer = node ? node->renderer() : 0; 117 if (renderer && renderer->isText()) { 118 RenderText* renderText = toRenderText(renderer); 119 textLength = renderText ? renderText->textLength() : 0; 120 } 121 122 // Get the text length from the elements under the 123 // accessibility object if the value is still zero. 124 if (!textLength && allowsTextRanges()) 125 textLength = textUnderElement().length(); 126 127 return textLength; 128 } 129 105 130 } // namespace WebCore 106 131 -
trunk/WebCore/accessibility/gtk/AccessibilityObjectWrapperAtk.cpp
r67320 r67383 1460 1460 } 1461 1461 1462 static gboolean webkit_accessible_text_remove_selection(AtkText* text, gint selection_num) 1463 { 1464 notImplemented(); 1465 return FALSE; 1466 } 1467 1468 static gboolean webkit_accessible_text_set_selection(AtkText* text, gint selection_num, gint start_offset, gint end_offset) 1469 { 1470 notImplemented(); 1471 return FALSE; 1462 static gboolean webkit_accessible_text_set_selection(AtkText* text, gint selectionNum, gint startOffset, gint endOffset) 1463 { 1464 // WebCore does not support multiple selection, so anything but 0 does not make sense for now. 1465 if (selectionNum) 1466 return FALSE; 1467 1468 // Consider -1 and out-of-bound values and correct them to length 1469 gint textCount = webkit_accessible_text_get_character_count(text); 1470 if (startOffset < 0 || startOffset > textCount) 1471 startOffset = textCount; 1472 if (endOffset < 0 || endOffset > textCount) 1473 endOffset = textCount; 1474 1475 AccessibilityObject* coreObject = core(text); 1476 PlainTextRange textRange(startOffset, endOffset - startOffset); 1477 VisiblePositionRange range = coreObject->visiblePositionRangeForRange(textRange); 1478 coreObject->setSelectedVisiblePositionRange(range); 1479 1480 return TRUE; 1481 } 1482 1483 static gboolean webkit_accessible_text_remove_selection(AtkText* text, gint selectionNum) 1484 { 1485 // WebCore does not support multiple selection, so anything but 0 does not make sense for now. 1486 if (selectionNum) 1487 return FALSE; 1488 1489 // Do nothing if current selection doesn't belong to the object 1490 if (!webkit_accessible_text_get_n_selections(text)) 1491 return FALSE; 1492 1493 // Set a new 0-sized selection to the caret position, in order 1494 // to simulate selection removal (GAIL style) 1495 gint caretOffset = webkit_accessible_text_get_caret_offset(text); 1496 return webkit_accessible_text_set_selection(text, selectionNum, caretOffset, caretOffset); 1472 1497 } 1473 1498 … … 1476 1501 AccessibilityObject* coreObject = core(text); 1477 1502 1478 // FIXME: We need to reimplement visiblePositionRangeForRange here 1479 // because the actual function checks the offset is within the 1480 // boundaries of text().length(), but text() only works for text 1481 // controls... 1482 VisiblePosition startPosition = coreObject->visiblePositionForIndex(offset); 1483 startPosition.setAffinity(DOWNSTREAM); 1484 VisiblePosition endPosition = coreObject->visiblePositionForIndex(offset); 1485 VisiblePositionRange range = VisiblePositionRange(startPosition, endPosition); 1486 1503 PlainTextRange textRange(offset, 0); 1504 VisiblePositionRange range = coreObject->visiblePositionRangeForRange(textRange); 1487 1505 coreObject->setSelectedVisiblePositionRange(range); 1506 1488 1507 return TRUE; 1489 1508 } -
trunk/WebKit/gtk/ChangeLog
r67300 r67383 1 2010-09-13 Mario Sanchez Prada <msanchez@igalia.com> 2 3 Reviewed by Martin Robinson. 4 5 [GTK] Provide unit tests for AtkText's text selection functions 6 https://bugs.webkit.org/show_bug.cgi?id=43919 7 8 New tests to check getting, setting and removing text selections 9 10 * tests/testatk.c: 11 (testWekitAtkTextSelections): New unit tests to check all the text 12 selection related functions altogether through a single test 13 function. 14 (main): 15 16 Make sure that code dependant on getting information from the 17 clipboard gets executed only when there's a GDK window associated 18 to the webview widget, as that's not the case when executing the 19 unit tests (the wedbview is not inside of any toplevel window) and 20 will make the tests crash if not taken into account. 21 22 * WebCoreSupport/EditorClientGtk.cpp: 23 (WebKit::EditorClient::respondToChangedSelection): 24 1 25 2010-09-11 Xan Lopez <xlopez@igalia.com> 2 26 -
trunk/WebKit/gtk/WebCoreSupport/EditorClientGtk.cpp
r65209 r67383 342 342 } 343 343 344 #if PLATFORM(X11) 345 static void setSelectionPrimaryClipboardIfNeeded(WebKitWebView* webView) 346 { 347 if (!gtk_widget_has_screen(GTK_WIDGET(webView))) 348 return; 349 350 GtkClipboard* clipboard = gtk_widget_get_clipboard(GTK_WIDGET(webView), GDK_SELECTION_PRIMARY); 351 DataObjectGtk* dataObject = DataObjectGtk::forClipboard(clipboard); 352 WebCore::Page* corePage = core(webView); 353 Frame* targetFrame = corePage->focusController()->focusedOrMainFrame(); 354 355 if (!targetFrame->selection()->isRange()) 356 return; 357 358 dataObject->clear(); 359 dataObject->setRange(targetFrame->selection()->toNormalizedRange()); 360 361 viewSettingClipboard = webView; 362 GClosure* callback = g_cclosure_new_object(G_CALLBACK(collapseSelection), G_OBJECT(webView)); 363 g_closure_set_marshal(callback, g_cclosure_marshal_VOID__VOID); 364 pasteboardHelperInstance()->writeClipboardContents(clipboard, callback); 365 viewSettingClipboard = 0; 366 } 367 #endif 368 344 369 void EditorClient::respondToChangedSelection() 345 370 { … … 355 380 356 381 #if PLATFORM(X11) 357 GtkClipboard* clipboard = gtk_widget_get_clipboard(GTK_WIDGET(m_webView), GDK_SELECTION_PRIMARY); 358 DataObjectGtk* dataObject = DataObjectGtk::forClipboard(clipboard); 359 360 if (targetFrame->selection()->isRange()) { 361 dataObject->clear(); 362 dataObject->setRange(targetFrame->selection()->toNormalizedRange()); 363 364 viewSettingClipboard = m_webView; 365 GClosure* callback = g_cclosure_new_object(G_CALLBACK(collapseSelection), G_OBJECT(m_webView)); 366 g_closure_set_marshal(callback, g_cclosure_marshal_VOID__VOID); 367 pasteboardHelperInstance()->writeClipboardContents(clipboard, callback); 368 viewSettingClipboard = 0; 369 } 382 setSelectionPrimaryClipboardIfNeeded(m_webView); 370 383 #endif 371 384 -
trunk/WebKit/gtk/tests/testatk.c
r67270 r67383 45 45 static 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>"; 46 46 47 static const char* listsOfItems = "<html><body><ul><li>text only</li><li><a href='foo'>link only</a></li><li>text and a <a href='bar'>link</a></li></ul><ol><li>text only</li><li><a href='foo'>link only</a></li><li>text and a <a href='bar'>link</a></li></ol></body></html>"; 48 49 static const char* textForSelections = "<html><body><p>A paragraph with plain text</p><p>A paragraph with <a href='http://webkit.org'>a link</a> in the middle</p></body></html>"; 50 47 51 static const char* textWithAttributes = "<html><head><style>.st1 {font-family: monospace; color:rgb(120,121,122);} .st2 {text-decoration:underline; background-color:rgb(80,81,82);}</style></head><body><p style=\"font-size:14; text-align:right;\">This is the <i>first</i><b> sentence of this text.</b></p><p class=\"st1\">This sentence should have an style applied <span class=\"st2\">and this part should have another one</span>.</p><p>x<sub>1</sub><sup>2</sup>=x<sub>2</sub><sup>3</sup></p><p style=\"text-align:center;\">This sentence is the <strike>last</strike> one.</p></body></html>"; 48 49 static const char* listsOfItems = "<html><body><ul><li>text only</li><li><a href='foo'>link only</a></li><li>text and a <a href='bar'>link</a></li></ul><ol><li>text only</li><li><a href='foo'>link only</a></li><li>text and a <a href='bar'>link</a></li></ol></body></html>";50 52 51 53 static gboolean bail_out(GMainLoop* loop) … … 741 743 atk_attribute_set_free(set2); 742 744 atk_attribute_set_free(set3); 745 } 746 747 static void testWekitAtkTextSelections(void) 748 { 749 WebKitWebView* webView; 750 AtkObject* obj; 751 GMainLoop* loop; 752 gchar* selectedText; 753 gint startOffset; 754 gint endOffset; 755 gboolean result; 756 757 webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); 758 g_object_ref_sink(webView); 759 GtkAllocation alloc = { 0, 0, 800, 600 }; 760 gtk_widget_size_allocate(GTK_WIDGET(webView), &alloc); 761 webkit_web_view_load_string(webView, textForSelections, NULL, NULL, NULL); 762 loop = g_main_loop_new(NULL, TRUE); 763 764 g_timeout_add(100, (GSourceFunc)bail_out, loop); 765 g_main_loop_run(loop); 766 767 obj = gtk_widget_get_accessible(GTK_WIDGET(webView)); 768 g_assert(obj); 769 770 AtkText* paragraph1 = ATK_TEXT(atk_object_ref_accessible_child(obj, 0)); 771 g_assert(ATK_IS_TEXT(paragraph1)); 772 AtkText* paragraph2 = ATK_TEXT(atk_object_ref_accessible_child(obj, 1)); 773 g_assert(ATK_IS_TEXT(paragraph2)); 774 AtkText* link = ATK_TEXT(atk_object_ref_accessible_child(ATK_OBJECT(paragraph2), 0)); 775 g_assert(ATK_IS_TEXT(link)); 776 777 // First paragraph (simple text) 778 779 // Basic initial checks 780 g_assert_cmpint(atk_text_get_n_selections(paragraph1), ==, 0); 781 selectedText = atk_text_get_selection(paragraph1, 0, &startOffset, &endOffset); 782 g_assert_cmpint(startOffset, ==, 0); 783 g_assert_cmpint(endOffset, ==, 0); 784 g_assert_cmpstr(selectedText, ==, NULL); 785 g_free (selectedText); 786 // Try removing a non existing (yet) selection 787 result = atk_text_remove_selection(paragraph1, 0); 788 g_assert(!result); 789 // Try setting a 0-char selection 790 result = atk_text_set_selection(paragraph1, 0, 5, 5); 791 g_assert(result); 792 793 // Make a selection and test it 794 result = atk_text_set_selection(paragraph1, 0, 5, 25); 795 g_assert(result); 796 g_assert_cmpint(atk_text_get_n_selections(paragraph1), ==, 1); 797 selectedText = atk_text_get_selection(paragraph1, 0, &startOffset, &endOffset); 798 g_assert_cmpint(startOffset, ==, 5); 799 g_assert_cmpint(endOffset, ==, 25); 800 g_assert_cmpstr(selectedText, ==, "agraph with plain te"); 801 g_free (selectedText); 802 // Try removing the selection from other AtkText object (should fail) 803 result = atk_text_remove_selection(paragraph2, 0); 804 g_assert(!result); 805 806 // Remove the selection and test everything again 807 result = atk_text_remove_selection(paragraph1, 0); 808 g_assert(result); 809 g_assert_cmpint(atk_text_get_n_selections(paragraph1), ==, 0); 810 selectedText = atk_text_get_selection(paragraph1, 0, &startOffset, &endOffset); 811 // Now offsets should be the same, set to the last position of the caret 812 g_assert_cmpint(startOffset, ==, endOffset); 813 g_assert_cmpint(startOffset, ==, 25); 814 g_assert_cmpint(endOffset, ==, 25); 815 g_assert_cmpstr(selectedText, ==, NULL); 816 g_free (selectedText); 817 818 // Second paragraph (text + link + text) 819 820 // Set a selection partially covering the link and test it 821 result = atk_text_set_selection(paragraph2, 0, 7, 21); 822 g_assert(result); 823 824 // Test the paragraph first 825 g_assert_cmpint(atk_text_get_n_selections(paragraph2), ==, 1); 826 selectedText = atk_text_get_selection(paragraph2, 0, &startOffset, &endOffset); 827 g_assert_cmpint(startOffset, ==, 7); 828 g_assert_cmpint(endOffset, ==, 21); 829 g_assert_cmpstr(selectedText, ==, "raph with a li"); 830 g_free (selectedText); 831 832 // Now test just the link 833 g_assert_cmpint(atk_text_get_n_selections(link), ==, 1); 834 selectedText = atk_text_get_selection(link, 0, &startOffset, &endOffset); 835 g_assert_cmpint(startOffset, ==, 0); 836 g_assert_cmpint(endOffset, ==, 4); 837 g_assert_cmpstr(selectedText, ==, "a li"); 838 g_free (selectedText); 839 840 // Remove selections and text everything again 841 result = atk_text_remove_selection(paragraph2, 0); 842 g_assert(result); 843 g_assert_cmpint(atk_text_get_n_selections(paragraph2), ==, 0); 844 selectedText = atk_text_get_selection(paragraph2, 0, &startOffset, &endOffset); 845 // Now offsets should be the same (no selection) 846 g_assert_cmpint(startOffset, ==, endOffset); 847 g_assert_cmpstr(selectedText, ==, NULL); 848 g_free (selectedText); 849 850 g_assert_cmpint(atk_text_get_n_selections(link), ==, 0); 851 selectedText = atk_text_get_selection(link, 0, &startOffset, &endOffset); 852 // Now offsets should be the same (no selection) 853 g_assert_cmpint(startOffset, ==, endOffset); 854 g_assert_cmpstr(selectedText, ==, NULL); 855 g_free (selectedText); 856 857 g_object_unref(paragraph1); 858 g_object_unref(paragraph2); 859 g_object_unref(webView); 743 860 } 744 861 … … 937 1054 g_test_add_func("/webkit/atk/getHeadersInTable", testWebkitAtkGetHeadersInTable); 938 1055 g_test_add_func("/webkit/atk/textAttributes", testWebkitAtkTextAttributes); 1056 g_test_add_func("/webkit/atk/textSelections", testWekitAtkTextSelections); 939 1057 g_test_add_func("/webkit/atk/get_extents", test_webkit_atk_get_extents); 940 1058 g_test_add_func("/webkit/atk/listsOfItems", testWebkitAtkListsOfItems);
Note: See TracChangeset
for help on using the changeset viewer.