Changeset 68078 in webkit
- Timestamp:
- Sep 22, 2010 1:43:26 PM (14 years ago)
- Location:
- trunk
- Files:
-
- 15 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r68077 r68078 1 2010-09-22 Mario Sanchez Prada <msanchez@igalia.com> 2 3 Reviewed by Martin Robinson. 4 5 [Gtk] object:text-changed events should be emitted for entries and password text 6 https://bugs.webkit.org/show_bug.cgi?id=25898 7 8 Implement proper 'text-changed' signal emission for the GTK port 9 10 Call deleteTextFromNode() when needed while removing text nodes. 11 Do it even when removeNode() is going to be called afterwards, in 12 order to allow accessibility to get properly notified about the 13 text being removed alongside with that node. 14 15 * editing/DeleteSelectionCommand.cpp: 16 (WebCore::DeleteSelectionCommand::handleGeneralDelete): 17 18 New function in AXObjectCache to call when text changes in a node. 19 Added one new function to allow notifying something changed in a 20 text node through the associated RenderObject, making such a 21 function dependant on the platform-specific implementation, 22 provided through a protected function (provided a proper 23 implementation for the GTK port and a dummy one for the others). 24 25 * accessibility/AXObjectCache.cpp: 26 (WebCore::AXObjectCache::nodeTextChangeNotification): New 27 * accessibility/AXObjectCache.h: 28 (WebCore::AXObjectCache::AXTextChange): New enumeration 29 (WebCore::AXObjectCache::nodeTextChangeNotification): New 30 (WebCore::AXObjectCache::nodeTextChangePlatformNotification): New 31 * accessibility/AccessibilityRenderObject.h: 32 (WebCore::toAccessibilityRenderObject): 33 * accessibility/chromium/AXObjectCacheChromium.cpp: 34 (WebCore::AXObjectCache::nodeTextChangePlatformNotification): New 35 * accessibility/gtk/AXObjectCacheAtk.cpp: 36 (WebCore::emitTextChanged): 37 (WebCore::AXObjectCache::nodeTextChangePlatformNotification): New 38 * accessibility/mac/AXObjectCacheMac.mm: 39 (WebCore::AXObjectCache::nodeTextChangePlatformNotification): New 40 * accessibility/win/AXObjectCacheWin.cpp: 41 (WebCore::AXObjectCache::nodeTextChangePlatformNotification): New 42 43 Notify accessibility when something changes in a text node. 44 Call to AXObjectCache::nodeTextChangeNotification() to notify when 45 text was inserted/deleted when applying/unapplying a text edition 46 command, along with the offset in the original text where the 47 change took place and the number of characters that got affected. 48 49 * editing/AppendNodeCommand.cpp: 50 (WebCore::sendAXTextChangedIgnoringLineBreaks): 51 (WebCore::AppendNodeCommand::doApply): 52 (WebCore::AppendNodeCommand::doUnapply): 53 * editing/DeleteFromTextNodeCommand.cpp: 54 (WebCore::DeleteFromTextNodeCommand::doApply): 55 (WebCore::DeleteFromTextNodeCommand::doUnapply): 56 * editing/InsertIntoTextNodeCommand.cpp: 57 (WebCore::InsertIntoTextNodeCommand::doApply): 58 (WebCore::InsertIntoTextNodeCommand::doUnapply): 59 * editing/InsertNodeBeforeCommand.cpp: 60 (WebCore::InsertNodeBeforeCommand::doApply): 61 (WebCore::InsertNodeBeforeCommand::doUnapply): 62 (WebCore::DeleteSelectionCommand::handleGeneralDelete): 63 1 64 2010-09-22 David Hyatt <hyatt@apple.com> 2 65 -
trunk/WebCore/accessibility/AXObjectCache.cpp
r64874 r68078 466 466 postNotification(renderer, AXSelectedChildrenChanged, false); 467 467 } 468 469 void AXObjectCache::nodeTextChangeNotification(RenderObject* renderer, AXTextChange textChange, unsigned offset, unsigned count) 470 { 471 if (!renderer) 472 return; 473 474 // Delegate on the right platform 475 AccessibilityObject* obj = getOrCreate(renderer); 476 nodeTextChangePlatformNotification(obj, textChange, offset, count); 477 } 468 478 #endif 469 479 -
trunk/WebCore/accessibility/AXObjectCache.h
r66305 r68078 126 126 void postNotification(AccessibilityObject*, Document*, AXNotification, bool postToElement, PostType = PostAsynchronously); 127 127 128 enum AXTextChange { 129 AXTextInserted, 130 AXTextDeleted, 131 }; 132 133 void nodeTextChangeNotification(RenderObject*, AXTextChange, unsigned offset, unsigned count); 134 135 bool nodeHasRole(Node*, const AtomicString& role); 136 128 137 protected: 129 138 void postPlatformNotification(AccessibilityObject*, AXNotification); 139 void nodeTextChangePlatformNotification(AccessibilityObject*, AXTextChange, unsigned offset, unsigned count); 130 140 131 141 private: … … 157 167 inline void AXObjectCache::postNotification(AccessibilityObject*, Document*, AXNotification, bool postToElement, PostType) { } 158 168 inline void AXObjectCache::postPlatformNotification(AccessibilityObject*, AXNotification) { } 169 inline void AXObjectCache::nodeTextChangeNotification(RenderObject*, AXTextChange, unsigned, unsigned) { } 170 inline void AXObjectCache::nodeTextChangePlatformNotification(AccessibilityObject*, AXTextChange, unsigned, unsigned) { } 159 171 inline void AXObjectCache::handleFocusedUIElementChanged(RenderObject*, RenderObject*) { } 160 172 inline void AXObjectCache::handleScrolledToAnchor(const Node*) { } -
trunk/WebCore/accessibility/AccessibilityRenderObject.h
r65021 r68078 312 312 mutable AccessibilityRole m_roleForMSAA; 313 313 }; 314 314 315 inline AccessibilityRenderObject* toAccessibilityRenderObject(AccessibilityObject* object) 316 { 317 ASSERT(!object || object->isAccessibilityRenderObject()); 318 return static_cast<AccessibilityRenderObject*>(object); 319 } 320 321 inline const AccessibilityRenderObject* toAccessibilityRenderObject(const AccessibilityObject* object) 322 { 323 ASSERT(!object || object->isAccessibilityRenderObject()); 324 return static_cast<const AccessibilityRenderObject*>(object); 325 } 326 327 // This will catch anyone doing an unnecessary cast. 328 void toAccessibilityRenderObject(const AccessibilityRenderObject*); 329 315 330 } // namespace WebCore 316 331 -
trunk/WebCore/accessibility/chromium/AXObjectCacheChromium.cpp
r68031 r68078 82 82 } 83 83 84 void AXObjectCache::nodeTextChangePlatformNotification(AccessibilityObject*, AXTextChange, unsigned, unsigned) 85 { 86 } 87 84 88 void AXObjectCache::handleFocusedUIElementChanged(RenderObject*, RenderObject*) 85 89 { -
trunk/WebCore/accessibility/gtk/AXObjectCacheAtk.cpp
r50282 r68078 23 23 #include "AccessibilityObject.h" 24 24 #include "AccessibilityObjectWrapperAtk.h" 25 #include "AccessibilityRenderObject.h" 26 #include "GOwnPtr.h" 27 #include "Range.h" 28 #include "TextIterator.h" 25 29 26 30 namespace WebCore { … … 51 55 } 52 56 57 static void emitTextChanged(AccessibilityRenderObject* object, AXObjectCache::AXTextChange textChange, unsigned offset, unsigned count) 58 { 59 // Get the axObject for the parent object 60 AtkObject* wrapper = object->parentObjectUnignored()->wrapper(); 61 if (!wrapper || !ATK_IS_TEXT(wrapper)) 62 return; 63 64 // Select the right signal to be emitted 65 CString detail; 66 switch (textChange) { 67 case AXObjectCache::AXTextInserted: 68 detail = "text-changed::insert"; 69 break; 70 case AXObjectCache::AXTextDeleted: 71 detail = "text-changed::delete"; 72 break; 73 } 74 75 if (!detail.isNull()) 76 g_signal_emit_by_name(wrapper, detail.data(), offset, count); 77 } 78 79 void AXObjectCache::nodeTextChangePlatformNotification(AccessibilityObject* object, AXTextChange textChange, unsigned offset, unsigned count) 80 { 81 // Sanity check 82 if (count < 1 || !object || !object->isAccessibilityRenderObject()) 83 return; 84 85 Node* node = object->node(); 86 RefPtr<Range> range = Range::create(node->document(), Position(node->parentNode(), 0), Position(node, 0)); 87 emitTextChanged(toAccessibilityRenderObject(object), textChange, offset + TextIterator::rangeLength(range.get()), count); 88 } 89 53 90 void AXObjectCache::handleFocusedUIElementChanged(RenderObject* oldFocusedRender, RenderObject* newFocusedRender) 54 91 { -
trunk/WebCore/accessibility/mac/AXObjectCacheMac.mm
r64517 r68078 115 115 } 116 116 117 void AXObjectCache::nodeTextChangePlatformNotification(AccessibilityObject*, AXTextChange, unsigned, unsigned) 118 { 119 } 120 117 121 void AXObjectCache::handleFocusedUIElementChanged(RenderObject*, RenderObject*) 118 122 { -
trunk/WebCore/accessibility/win/AXObjectCacheWin.cpp
r54078 r68078 104 104 } 105 105 106 void AXObjectCache::nodeTextChangePlatformNotification(AccessibilityObject*, AXTextChange, unsigned, unsigned) 107 { 108 } 109 106 110 AXID AXObjectCache::platformGenerateAXID() const 107 111 { -
trunk/WebCore/editing/AppendNodeCommand.cpp
r51645 r68078 27 27 #include "AppendNodeCommand.h" 28 28 29 #include "AXObjectCache.h" 29 30 #include "htmlediting.h" 30 31 … … 43 44 } 44 45 46 static void sendAXTextChangedIgnoringLineBreaks(Node* node, AXObjectCache::AXTextChange textChange) 47 { 48 String nodeValue = node->nodeValue(); 49 unsigned len = nodeValue.length(); 50 // Don't consider linebreaks in this command 51 if (nodeValue == "\n") 52 return; 53 54 node->document()->axObjectCache()->nodeTextChangeNotification(node->renderer(), textChange, 0, len); 55 } 56 45 57 void AppendNodeCommand::doApply() 46 58 { … … 50 62 ExceptionCode ec; 51 63 m_parent->appendChild(m_node.get(), ec); 64 65 if (AXObjectCache::accessibilityEnabled()) 66 sendAXTextChangedIgnoringLineBreaks(m_node.get(), AXObjectCache::AXTextInserted); 52 67 } 53 68 … … 57 72 return; 58 73 74 // Need to notify this before actually deleting the text 75 if (AXObjectCache::accessibilityEnabled()) 76 sendAXTextChangedIgnoringLineBreaks(m_node.get(), AXObjectCache::AXTextDeleted); 77 59 78 ExceptionCode ec; 60 79 m_node->remove(ec); -
trunk/WebCore/editing/DeleteFromTextNodeCommand.cpp
r51645 r68078 27 27 #include "DeleteFromTextNodeCommand.h" 28 28 29 #include "AXObjectCache.h" 29 30 #include "Text.h" 30 31 … … 54 55 return; 55 56 57 // Need to notify this before actually deleting the text 58 if (AXObjectCache::accessibilityEnabled()) 59 document()->axObjectCache()->nodeTextChangeNotification(m_node->renderer(), AXObjectCache::AXTextDeleted, m_offset, m_count); 60 56 61 m_node->deleteData(m_offset, m_count, ec); 57 62 } … … 66 71 ExceptionCode ec; 67 72 m_node->insertData(m_offset, m_text, ec); 73 74 if (AXObjectCache::accessibilityEnabled()) 75 document()->axObjectCache()->nodeTextChangeNotification(m_node->renderer(), AXObjectCache::AXTextInserted, m_offset, m_count); 68 76 } 69 77 -
trunk/WebCore/editing/DeleteSelectionCommand.cpp
r67238 r68078 444 444 445 445 if (startNode == m_downstreamEnd.node()) { 446 // The selection to delete is all in one node. 447 if (!startNode->renderer() || (startOffset == 0 && m_downstreamEnd.atLastEditingPositionForNode())) { 448 // just delete 449 removeNode(startNode); 450 } else if (m_downstreamEnd.deprecatedEditingOffset() - startOffset > 0) { 446 if (m_downstreamEnd.deprecatedEditingOffset() - startOffset > 0) { 451 447 if (startNode->isTextNode()) { 452 448 // in a text node that needs to be trimmed … … 458 454 } 459 455 } 456 457 // The selection to delete is all in one node. 458 if (!startNode->renderer() || (!startOffset && m_downstreamEnd.atLastEditingPositionForNode())) 459 removeNode(startNode); 460 460 } 461 461 else { … … 473 473 node = startNode->childNode(startOffset); 474 474 } 475 } else if (startNode == m_upstreamEnd.node() && startNode->isTextNode()) { 476 Text* text = static_cast<Text*>(m_upstreamEnd.node()); 477 deleteTextFromNode(text, 0, m_upstreamEnd.deprecatedEditingOffset()); 475 478 } 476 479 -
trunk/WebCore/editing/InsertIntoTextNodeCommand.cpp
r51645 r68078 27 27 #include "InsertIntoTextNodeCommand.h" 28 28 29 #include "AXObjectCache.h" 29 30 #include "Text.h" 30 31 … … 49 50 ExceptionCode ec; 50 51 m_node->insertData(m_offset, m_text, ec); 52 53 if (AXObjectCache::accessibilityEnabled()) 54 document()->axObjectCache()->nodeTextChangeNotification(m_node->renderer(), AXObjectCache::AXTextInserted, m_offset, m_text.length()); 51 55 } 52 56 … … 56 60 return; 57 61 62 // Need to notify this before actually deleting the text 63 if (AXObjectCache::accessibilityEnabled()) 64 document()->axObjectCache()->nodeTextChangeNotification(m_node->renderer(), AXObjectCache::AXTextDeleted, m_offset, m_text.length()); 65 58 66 ExceptionCode ec; 59 67 m_node->deleteData(m_offset, m_text.length(), ec); -
trunk/WebCore/editing/InsertNodeBeforeCommand.cpp
r51645 r68078 27 27 #include "InsertNodeBeforeCommand.h" 28 28 29 #include "AXObjectCache.h" 29 30 #include "htmlediting.h" 30 31 … … 52 53 ExceptionCode ec; 53 54 parent->insertBefore(m_insertChild.get(), m_refChild.get(), ec); 55 56 if (AXObjectCache::accessibilityEnabled()) 57 document()->axObjectCache()->nodeTextChangeNotification(m_insertChild->renderer(), AXObjectCache::AXTextInserted, 0, m_insertChild->nodeValue().length()); 54 58 } 55 59 … … 59 63 return; 60 64 65 // Need to notify this before actually deleting the text 66 if (AXObjectCache::accessibilityEnabled()) 67 document()->axObjectCache()->nodeTextChangeNotification(m_insertChild->renderer(), AXObjectCache::AXTextDeleted, 0, m_insertChild->nodeValue().length()); 68 61 69 ExceptionCode ec; 62 70 m_insertChild->remove(ec); -
trunk/WebKit/gtk/ChangeLog
r68043 r68078 1 2010-09-22 Mario Sanchez Prada <msanchez@igalia.com> 2 3 Reviewed by Martin Robinson. 4 5 [Gtk] object:text-changed events should be emitted for entries and password text 6 https://bugs.webkit.org/show_bug.cgi?id=25898 7 8 New unit test to make sure text-changed signals are emitted 9 10 * tests/testatk.c: 11 (textChangedCb): New. Signal handler for the 12 text-changed::insert and text-changed::delete signals. 13 (checkTextChangesAndBailOut): New. Source function to check 14 the global result of the test and quit from the main loop. 15 (testWebkitAtkTextChangedNotifications): New test. 16 (main): 17 1 18 2010-09-22 Martin Robinson <mrobinson@igalia.com> 2 19 -
trunk/WebKit/gtk/tests/testatk.c
r67383 r68078 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* formWithTextInputs = "<html><body><form><input type='text' name='entry' /></form></body></html>"; 48 47 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>"; 48 50 … … 1035 1037 g_object_unref(uList); 1036 1038 g_object_unref(oList); 1039 g_object_unref(webView); 1040 } 1041 1042 static gboolean textInserted = FALSE; 1043 static gboolean textDeleted = FALSE; 1044 1045 static void textChangedCb(AtkText* text, gint pos, gint len, const gchar* detail) 1046 { 1047 g_assert(text && ATK_IS_OBJECT(text)); 1048 1049 if (!g_strcmp0(detail, "insert")) 1050 textInserted = TRUE; 1051 else if (!g_strcmp0(detail, "delete")) 1052 textDeleted = TRUE; 1053 } 1054 1055 static gboolean checkTextChanges(gpointer unused) 1056 { 1057 g_assert_cmpint(textInserted, ==, TRUE); 1058 g_assert_cmpint(textDeleted, ==, TRUE); 1059 return FALSE; 1060 } 1061 1062 static void testWebkitAtkTextChangedNotifications(void) 1063 { 1064 WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); 1065 g_object_ref_sink(webView); 1066 GtkAllocation alloc = { 0, 0, 800, 600 }; 1067 gtk_widget_size_allocate(GTK_WIDGET(webView), &alloc); 1068 webkit_web_view_load_string(webView, formWithTextInputs, 0, 0, 0); 1069 1070 // Manually spin the main context to get the accessible objects 1071 while (g_main_context_pending(0)) 1072 g_main_context_iteration(0, TRUE); 1073 1074 AtkObject* obj = gtk_widget_get_accessible(GTK_WIDGET(webView)); 1075 g_assert(obj); 1076 1077 AtkObject* form = atk_object_ref_accessible_child(obj, 0); 1078 g_assert(ATK_IS_OBJECT(form)); 1079 1080 AtkObject* textEntry = atk_object_ref_accessible_child(form, 0); 1081 g_assert(ATK_IS_EDITABLE_TEXT(textEntry)); 1082 g_assert(atk_object_get_role(ATK_OBJECT(textEntry)) == ATK_ROLE_ENTRY); 1083 1084 g_signal_connect(textEntry, "text-changed::insert", 1085 G_CALLBACK(textChangedCb), 1086 (gpointer)"insert"); 1087 g_signal_connect(textEntry, "text-changed::delete", 1088 G_CALLBACK(textChangedCb), 1089 (gpointer)"delete"); 1090 1091 gint pos = 0; 1092 atk_editable_text_insert_text(ATK_EDITABLE_TEXT(textEntry), "foo bar baz", 11, &pos); 1093 atk_editable_text_delete_text(ATK_EDITABLE_TEXT(textEntry), 4, 7); 1094 textInserted = FALSE; 1095 textDeleted = FALSE; 1096 1097 g_idle_add((GSourceFunc)checkTextChanges, 0); 1098 1099 g_object_unref(form); 1100 g_object_unref(textEntry); 1037 1101 g_object_unref(webView); 1038 1102 } … … 1057 1121 g_test_add_func("/webkit/atk/get_extents", test_webkit_atk_get_extents); 1058 1122 g_test_add_func("/webkit/atk/listsOfItems", testWebkitAtkListsOfItems); 1123 g_test_add_func("/webkit/atk/textChangedNotifications", testWebkitAtkTextChangedNotifications); 1059 1124 return g_test_run (); 1060 1125 }
Note: See TracChangeset
for help on using the changeset viewer.