[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc

commit-queue at webkit.org commit-queue at webkit.org
Wed Dec 22 13:39:51 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit 2aa8d03c17d1d8a5f2cb0e3c481a549ec1f5c13e
Author: commit-queue at webkit.org <commit-queue at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Wed Sep 22 20:43:26 2010 +0000

    2010-09-22 Mario Sanchez Prada <msanchez at igalia.com>
    
            Reviewed by Martin Robinson.
    
            [Gtk] object:text-changed events should be emitted for entries and password text
            https://bugs.webkit.org/show_bug.cgi?id=25898
    
            Implement proper 'text-changed' signal emission for the GTK port
    
            Call deleteTextFromNode() when needed while removing text nodes.
            Do it even when removeNode() is going to be called afterwards, in
            order to allow accessibility to get properly notified about the
            text being removed alongside with that node.
    
            * editing/DeleteSelectionCommand.cpp:
            (WebCore::DeleteSelectionCommand::handleGeneralDelete):
    
            New function in AXObjectCache to call when text changes in a node.
            Added one new function to allow notifying something changed in a
            text node through the associated RenderObject, making such a
            function dependant on the platform-specific implementation,
            provided through a protected function (provided a proper
            implementation for the GTK port and a dummy one for the others).
    
            * accessibility/AXObjectCache.cpp:
            (WebCore::AXObjectCache::nodeTextChangeNotification): New
            * accessibility/AXObjectCache.h:
            (WebCore::AXObjectCache::AXTextChange): New enumeration
            (WebCore::AXObjectCache::nodeTextChangeNotification): New
            (WebCore::AXObjectCache::nodeTextChangePlatformNotification): New
            * accessibility/AccessibilityRenderObject.h:
            (WebCore::toAccessibilityRenderObject):
            * accessibility/chromium/AXObjectCacheChromium.cpp:
            (WebCore::AXObjectCache::nodeTextChangePlatformNotification): New
            * accessibility/gtk/AXObjectCacheAtk.cpp:
            (WebCore::emitTextChanged):
            (WebCore::AXObjectCache::nodeTextChangePlatformNotification): New
            * accessibility/mac/AXObjectCacheMac.mm:
            (WebCore::AXObjectCache::nodeTextChangePlatformNotification): New
            * accessibility/win/AXObjectCacheWin.cpp:
            (WebCore::AXObjectCache::nodeTextChangePlatformNotification): New
    
            Notify accessibility when something changes in a text node.
            Call to AXObjectCache::nodeTextChangeNotification() to notify when
            text was inserted/deleted when applying/unapplying a text edition
            command, along with the offset in the original text where the
            change took place and the number of characters that got affected.
    
            * editing/AppendNodeCommand.cpp:
            (WebCore::sendAXTextChangedIgnoringLineBreaks):
            (WebCore::AppendNodeCommand::doApply):
            (WebCore::AppendNodeCommand::doUnapply):
            * editing/DeleteFromTextNodeCommand.cpp:
            (WebCore::DeleteFromTextNodeCommand::doApply):
            (WebCore::DeleteFromTextNodeCommand::doUnapply):
            * editing/InsertIntoTextNodeCommand.cpp:
            (WebCore::InsertIntoTextNodeCommand::doApply):
            (WebCore::InsertIntoTextNodeCommand::doUnapply):
            * editing/InsertNodeBeforeCommand.cpp:
            (WebCore::InsertNodeBeforeCommand::doApply):
            (WebCore::InsertNodeBeforeCommand::doUnapply):
            (WebCore::DeleteSelectionCommand::handleGeneralDelete):
    2010-09-22  Mario Sanchez Prada  <msanchez at igalia.com>
    
            Reviewed by Martin Robinson.
    
            [Gtk] object:text-changed events should be emitted for entries and password text
            https://bugs.webkit.org/show_bug.cgi?id=25898
    
            New unit test to make sure text-changed signals are emitted
    
            * tests/testatk.c:
            (textChangedCb): New. Signal handler for the
            text-changed::insert and text-changed::delete signals.
            (checkTextChangesAndBailOut): New. Source function to check
            the global result of the test and quit from the main loop.
            (testWebkitAtkTextChangedNotifications): New test.
            (main):
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@68078 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 5421aec..6d33284 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,66 @@
+2010-09-22 Mario Sanchez Prada <msanchez at igalia.com>
+
+        Reviewed by Martin Robinson.
+
+        [Gtk] object:text-changed events should be emitted for entries and password text
+        https://bugs.webkit.org/show_bug.cgi?id=25898
+
+        Implement proper 'text-changed' signal emission for the GTK port
+
+        Call deleteTextFromNode() when needed while removing text nodes.
+        Do it even when removeNode() is going to be called afterwards, in
+        order to allow accessibility to get properly notified about the
+        text being removed alongside with that node.
+
+        * editing/DeleteSelectionCommand.cpp:
+        (WebCore::DeleteSelectionCommand::handleGeneralDelete):
+
+        New function in AXObjectCache to call when text changes in a node.
+        Added one new function to allow notifying something changed in a
+        text node through the associated RenderObject, making such a
+        function dependant on the platform-specific implementation,
+        provided through a protected function (provided a proper
+        implementation for the GTK port and a dummy one for the others).
+
+        * accessibility/AXObjectCache.cpp:
+        (WebCore::AXObjectCache::nodeTextChangeNotification): New
+        * accessibility/AXObjectCache.h:
+        (WebCore::AXObjectCache::AXTextChange): New enumeration
+        (WebCore::AXObjectCache::nodeTextChangeNotification): New
+        (WebCore::AXObjectCache::nodeTextChangePlatformNotification): New
+        * accessibility/AccessibilityRenderObject.h:
+        (WebCore::toAccessibilityRenderObject):
+        * accessibility/chromium/AXObjectCacheChromium.cpp:
+        (WebCore::AXObjectCache::nodeTextChangePlatformNotification): New
+        * accessibility/gtk/AXObjectCacheAtk.cpp:
+        (WebCore::emitTextChanged):
+        (WebCore::AXObjectCache::nodeTextChangePlatformNotification): New
+        * accessibility/mac/AXObjectCacheMac.mm:
+        (WebCore::AXObjectCache::nodeTextChangePlatformNotification): New
+        * accessibility/win/AXObjectCacheWin.cpp:
+        (WebCore::AXObjectCache::nodeTextChangePlatformNotification): New
+
+        Notify accessibility when something changes in a text node.
+        Call to AXObjectCache::nodeTextChangeNotification() to notify when
+        text was inserted/deleted when applying/unapplying a text edition
+        command, along with the offset in the original text where the
+        change took place and the number of characters that got affected.
+
+        * editing/AppendNodeCommand.cpp:
+        (WebCore::sendAXTextChangedIgnoringLineBreaks):
+        (WebCore::AppendNodeCommand::doApply):
+        (WebCore::AppendNodeCommand::doUnapply):
+        * editing/DeleteFromTextNodeCommand.cpp:
+        (WebCore::DeleteFromTextNodeCommand::doApply):
+        (WebCore::DeleteFromTextNodeCommand::doUnapply):
+        * editing/InsertIntoTextNodeCommand.cpp:
+        (WebCore::InsertIntoTextNodeCommand::doApply):
+        (WebCore::InsertIntoTextNodeCommand::doUnapply):
+        * editing/InsertNodeBeforeCommand.cpp:
+        (WebCore::InsertNodeBeforeCommand::doApply):
+        (WebCore::InsertNodeBeforeCommand::doUnapply):
+        (WebCore::DeleteSelectionCommand::handleGeneralDelete):
+
 2010-09-22  David Hyatt  <hyatt at apple.com>
 
         Reviewed by Dan Bernstein.
diff --git a/WebCore/accessibility/AXObjectCache.cpp b/WebCore/accessibility/AXObjectCache.cpp
index 907bb15..a58b324 100644
--- a/WebCore/accessibility/AXObjectCache.cpp
+++ b/WebCore/accessibility/AXObjectCache.cpp
@@ -465,6 +465,16 @@ void AXObjectCache::selectedChildrenChanged(RenderObject* renderer)
     // to find the container which should send out the notification.
     postNotification(renderer, AXSelectedChildrenChanged, false);
 }
+
+void AXObjectCache::nodeTextChangeNotification(RenderObject* renderer, AXTextChange textChange, unsigned offset, unsigned count)
+{
+    if (!renderer)
+        return;
+
+    // Delegate on the right platform
+    AccessibilityObject* obj = getOrCreate(renderer);
+    nodeTextChangePlatformNotification(obj, textChange, offset, count);
+}
 #endif
 
 #if HAVE(ACCESSIBILITY)
diff --git a/WebCore/accessibility/AXObjectCache.h b/WebCore/accessibility/AXObjectCache.h
index 28a5917..7189a35 100644
--- a/WebCore/accessibility/AXObjectCache.h
+++ b/WebCore/accessibility/AXObjectCache.h
@@ -125,8 +125,18 @@ public:
     void postNotification(RenderObject*, AXNotification, bool postToElement, PostType = PostAsynchronously);
     void postNotification(AccessibilityObject*, Document*, AXNotification, bool postToElement, PostType = PostAsynchronously);
 
+    enum AXTextChange {
+        AXTextInserted,
+        AXTextDeleted,
+    };
+
+    void nodeTextChangeNotification(RenderObject*, AXTextChange, unsigned offset, unsigned count);
+
+    bool nodeHasRole(Node*, const AtomicString& role);
+
 protected:
     void postPlatformNotification(AccessibilityObject*, AXNotification);
+    void nodeTextChangePlatformNotification(AccessibilityObject*, AXTextChange, unsigned offset, unsigned count);
 
 private:
     HashMap<AXID, RefPtr<AccessibilityObject> > m_objects;
@@ -156,6 +166,8 @@ inline void AXObjectCache::selectedChildrenChanged(RenderObject*) { }
 inline void AXObjectCache::postNotification(RenderObject*, AXNotification, bool postToElement, PostType) { }
 inline void AXObjectCache::postNotification(AccessibilityObject*, Document*, AXNotification, bool postToElement, PostType) { }
 inline void AXObjectCache::postPlatformNotification(AccessibilityObject*, AXNotification) { }
+inline void AXObjectCache::nodeTextChangeNotification(RenderObject*, AXTextChange, unsigned, unsigned) { }
+inline void AXObjectCache::nodeTextChangePlatformNotification(AccessibilityObject*, AXTextChange, unsigned, unsigned) { }
 inline void AXObjectCache::handleFocusedUIElementChanged(RenderObject*, RenderObject*) { }
 inline void AXObjectCache::handleScrolledToAnchor(const Node*) { }
 inline void AXObjectCache::contentChanged(RenderObject*) { }
diff --git a/WebCore/accessibility/AccessibilityRenderObject.h b/WebCore/accessibility/AccessibilityRenderObject.h
index cefaa94..b7b85fe 100644
--- a/WebCore/accessibility/AccessibilityRenderObject.h
+++ b/WebCore/accessibility/AccessibilityRenderObject.h
@@ -311,7 +311,22 @@ private:
     
     mutable AccessibilityRole m_roleForMSAA;
 };
-    
+
+inline AccessibilityRenderObject* toAccessibilityRenderObject(AccessibilityObject* object)
+{
+    ASSERT(!object || object->isAccessibilityRenderObject());
+    return static_cast<AccessibilityRenderObject*>(object);
+}
+
+inline const AccessibilityRenderObject* toAccessibilityRenderObject(const AccessibilityObject* object)
+{
+    ASSERT(!object || object->isAccessibilityRenderObject());
+    return static_cast<const AccessibilityRenderObject*>(object);
+}
+
+// This will catch anyone doing an unnecessary cast.
+void toAccessibilityRenderObject(const AccessibilityRenderObject*);
+
 } // namespace WebCore
 
 #endif // AccessibilityRenderObject_h
diff --git a/WebCore/accessibility/chromium/AXObjectCacheChromium.cpp b/WebCore/accessibility/chromium/AXObjectCacheChromium.cpp
index 93c748e..18b206a 100644
--- a/WebCore/accessibility/chromium/AXObjectCacheChromium.cpp
+++ b/WebCore/accessibility/chromium/AXObjectCacheChromium.cpp
@@ -81,6 +81,10 @@ void AXObjectCache::postPlatformNotification(AccessibilityObject* obj, AXNotific
     client->postAccessibilityNotification(obj, notification);        
 }
 
+void AXObjectCache::nodeTextChangePlatformNotification(AccessibilityObject*, AXTextChange, unsigned, unsigned)
+{
+}
+
 void AXObjectCache::handleFocusedUIElementChanged(RenderObject*, RenderObject*)
 {
 }
diff --git a/WebCore/accessibility/gtk/AXObjectCacheAtk.cpp b/WebCore/accessibility/gtk/AXObjectCacheAtk.cpp
index c30b006..a4ea87c 100644
--- a/WebCore/accessibility/gtk/AXObjectCacheAtk.cpp
+++ b/WebCore/accessibility/gtk/AXObjectCacheAtk.cpp
@@ -22,6 +22,10 @@
 
 #include "AccessibilityObject.h"
 #include "AccessibilityObjectWrapperAtk.h"
+#include "AccessibilityRenderObject.h"
+#include "GOwnPtr.h"
+#include "Range.h"
+#include "TextIterator.h"
 
 namespace WebCore {
 
@@ -50,6 +54,39 @@ void AXObjectCache::postPlatformNotification(AccessibilityObject* coreObject, AX
     }
 }
 
+static void emitTextChanged(AccessibilityRenderObject* object, AXObjectCache::AXTextChange textChange, unsigned offset, unsigned count)
+{
+    // Get the axObject for the parent object
+    AtkObject* wrapper = object->parentObjectUnignored()->wrapper();
+    if (!wrapper || !ATK_IS_TEXT(wrapper))
+        return;
+
+    // Select the right signal to be emitted
+    CString detail;
+    switch (textChange) {
+    case AXObjectCache::AXTextInserted:
+        detail = "text-changed::insert";
+        break;
+    case AXObjectCache::AXTextDeleted:
+        detail = "text-changed::delete";
+        break;
+    }
+
+    if (!detail.isNull())
+        g_signal_emit_by_name(wrapper, detail.data(), offset, count);
+}
+
+void AXObjectCache::nodeTextChangePlatformNotification(AccessibilityObject* object, AXTextChange textChange, unsigned offset, unsigned count)
+{
+    // Sanity check
+    if (count < 1 || !object || !object->isAccessibilityRenderObject())
+        return;
+
+    Node* node = object->node();
+    RefPtr<Range> range = Range::create(node->document(),  Position(node->parentNode(), 0), Position(node, 0));
+    emitTextChanged(toAccessibilityRenderObject(object), textChange, offset + TextIterator::rangeLength(range.get()), count);
+}
+
 void AXObjectCache::handleFocusedUIElementChanged(RenderObject* oldFocusedRender, RenderObject* newFocusedRender)
 {
     RefPtr<AccessibilityObject> oldObject = getOrCreate(oldFocusedRender);
diff --git a/WebCore/accessibility/mac/AXObjectCacheMac.mm b/WebCore/accessibility/mac/AXObjectCacheMac.mm
index a02bc75..e651a75 100644
--- a/WebCore/accessibility/mac/AXObjectCacheMac.mm
+++ b/WebCore/accessibility/mac/AXObjectCacheMac.mm
@@ -114,6 +114,10 @@ void AXObjectCache::postPlatformNotification(AccessibilityObject* obj, AXNotific
     [obj->wrapper() accessibilityPostedNotification:macNotification];
 }
 
+void AXObjectCache::nodeTextChangePlatformNotification(AccessibilityObject*, AXTextChange, unsigned, unsigned)
+{
+}
+
 void AXObjectCache::handleFocusedUIElementChanged(RenderObject*, RenderObject*)
 {
     [[WebCoreViewFactory sharedFactory] accessibilityHandleFocusChanged];
diff --git a/WebCore/accessibility/win/AXObjectCacheWin.cpp b/WebCore/accessibility/win/AXObjectCacheWin.cpp
index 21e61d9..b20b51a 100644
--- a/WebCore/accessibility/win/AXObjectCacheWin.cpp
+++ b/WebCore/accessibility/win/AXObjectCacheWin.cpp
@@ -103,6 +103,10 @@ void AXObjectCache::postPlatformNotification(AccessibilityObject* obj, AXNotific
     NotifyWinEvent(msaaEvent, page->chrome()->platformPageClient(), OBJID_CLIENT, -static_cast<LONG>(obj->axObjectID()));
 }
 
+void AXObjectCache::nodeTextChangePlatformNotification(AccessibilityObject*, AXTextChange, unsigned, unsigned)
+{
+}
+
 AXID AXObjectCache::platformGenerateAXID() const
 {
     static AXID lastUsedID = 0;
diff --git a/WebCore/editing/AppendNodeCommand.cpp b/WebCore/editing/AppendNodeCommand.cpp
index 6178641..eeecdd2 100644
--- a/WebCore/editing/AppendNodeCommand.cpp
+++ b/WebCore/editing/AppendNodeCommand.cpp
@@ -26,6 +26,7 @@
 #include "config.h"
 #include "AppendNodeCommand.h"
 
+#include "AXObjectCache.h"
 #include "htmlediting.h"
 
 namespace WebCore {
@@ -42,6 +43,17 @@ AppendNodeCommand::AppendNodeCommand(PassRefPtr<Element> parent, PassRefPtr<Node
     ASSERT(m_parent->isContentEditable() || !m_parent->attached());
 }
 
+static void sendAXTextChangedIgnoringLineBreaks(Node* node, AXObjectCache::AXTextChange textChange)
+{
+    String nodeValue = node->nodeValue();
+    unsigned len = nodeValue.length();
+    // Don't consider linebreaks in this command
+    if (nodeValue == "\n")
+      return;
+
+    node->document()->axObjectCache()->nodeTextChangeNotification(node->renderer(), textChange, 0, len);
+}
+
 void AppendNodeCommand::doApply()
 {
     if (!m_parent->isContentEditable() && m_parent->attached())
@@ -49,6 +61,9 @@ void AppendNodeCommand::doApply()
         
     ExceptionCode ec;
     m_parent->appendChild(m_node.get(), ec);
+
+    if (AXObjectCache::accessibilityEnabled())
+        sendAXTextChangedIgnoringLineBreaks(m_node.get(), AXObjectCache::AXTextInserted);
 }
 
 void AppendNodeCommand::doUnapply()
@@ -56,6 +71,10 @@ void AppendNodeCommand::doUnapply()
     if (!m_parent->isContentEditable())
         return;
         
+    // Need to notify this before actually deleting the text
+    if (AXObjectCache::accessibilityEnabled())
+        sendAXTextChangedIgnoringLineBreaks(m_node.get(), AXObjectCache::AXTextDeleted);
+
     ExceptionCode ec;
     m_node->remove(ec);
 }
diff --git a/WebCore/editing/DeleteFromTextNodeCommand.cpp b/WebCore/editing/DeleteFromTextNodeCommand.cpp
index f1d79af..fe572e1 100644
--- a/WebCore/editing/DeleteFromTextNodeCommand.cpp
+++ b/WebCore/editing/DeleteFromTextNodeCommand.cpp
@@ -26,6 +26,7 @@
 #include "config.h"
 #include "DeleteFromTextNodeCommand.h"
 
+#include "AXObjectCache.h"
 #include "Text.h"
 
 namespace WebCore {
@@ -53,6 +54,10 @@ void DeleteFromTextNodeCommand::doApply()
     if (ec)
         return;
     
+    // Need to notify this before actually deleting the text
+    if (AXObjectCache::accessibilityEnabled())
+        document()->axObjectCache()->nodeTextChangeNotification(m_node->renderer(), AXObjectCache::AXTextDeleted, m_offset, m_count);
+
     m_node->deleteData(m_offset, m_count, ec);
 }
 
@@ -65,6 +70,9 @@ void DeleteFromTextNodeCommand::doUnapply()
         
     ExceptionCode ec;
     m_node->insertData(m_offset, m_text, ec);
+
+    if (AXObjectCache::accessibilityEnabled())
+        document()->axObjectCache()->nodeTextChangeNotification(m_node->renderer(), AXObjectCache::AXTextInserted, m_offset, m_count);
 }
 
 } // namespace WebCore
diff --git a/WebCore/editing/DeleteSelectionCommand.cpp b/WebCore/editing/DeleteSelectionCommand.cpp
index 4aa5c3c..4aca57e 100644
--- a/WebCore/editing/DeleteSelectionCommand.cpp
+++ b/WebCore/editing/DeleteSelectionCommand.cpp
@@ -443,11 +443,7 @@ void DeleteSelectionCommand::handleGeneralDelete()
         return;
 
     if (startNode == m_downstreamEnd.node()) {
-        // The selection to delete is all in one node.
-        if (!startNode->renderer() || (startOffset == 0 && m_downstreamEnd.atLastEditingPositionForNode())) {
-            // just delete
-            removeNode(startNode);
-        } else if (m_downstreamEnd.deprecatedEditingOffset() - startOffset > 0) {
+        if (m_downstreamEnd.deprecatedEditingOffset() - startOffset > 0) {
             if (startNode->isTextNode()) {
                 // in a text node that needs to be trimmed
                 Text* text = static_cast<Text*>(startNode);
@@ -457,6 +453,10 @@ void DeleteSelectionCommand::handleGeneralDelete()
                 m_endingPosition = m_upstreamStart;
             }
         }
+
+        // The selection to delete is all in one node.
+        if (!startNode->renderer() || (!startOffset && m_downstreamEnd.atLastEditingPositionForNode()))
+            removeNode(startNode);
     }
     else {
         bool startNodeWasDescendantOfEndNode = m_upstreamStart.node()->isDescendantOf(m_downstreamEnd.node());
@@ -472,6 +472,9 @@ void DeleteSelectionCommand::handleGeneralDelete()
             } else {
                 node = startNode->childNode(startOffset);
             }
+        } else if (startNode == m_upstreamEnd.node() && startNode->isTextNode()) {
+            Text* text = static_cast<Text*>(m_upstreamEnd.node());
+            deleteTextFromNode(text, 0, m_upstreamEnd.deprecatedEditingOffset());
         }
         
         // handle deleting all nodes that are completely selected
diff --git a/WebCore/editing/InsertIntoTextNodeCommand.cpp b/WebCore/editing/InsertIntoTextNodeCommand.cpp
index 9c3423a..9b7761c 100644
--- a/WebCore/editing/InsertIntoTextNodeCommand.cpp
+++ b/WebCore/editing/InsertIntoTextNodeCommand.cpp
@@ -26,6 +26,7 @@
 #include "config.h"
 #include "InsertIntoTextNodeCommand.h"
 
+#include "AXObjectCache.h"
 #include "Text.h"
 
 namespace WebCore {
@@ -48,6 +49,9 @@ void InsertIntoTextNodeCommand::doApply()
     
     ExceptionCode ec;
     m_node->insertData(m_offset, m_text, ec);
+
+    if (AXObjectCache::accessibilityEnabled())
+        document()->axObjectCache()->nodeTextChangeNotification(m_node->renderer(), AXObjectCache::AXTextInserted, m_offset, m_text.length());
 }
 
 void InsertIntoTextNodeCommand::doUnapply()
@@ -55,6 +59,10 @@ void InsertIntoTextNodeCommand::doUnapply()
     if (!m_node->isContentEditable())
         return;
         
+    // Need to notify this before actually deleting the text
+    if (AXObjectCache::accessibilityEnabled())
+        document()->axObjectCache()->nodeTextChangeNotification(m_node->renderer(), AXObjectCache::AXTextDeleted, m_offset, m_text.length());
+
     ExceptionCode ec;
     m_node->deleteData(m_offset, m_text.length(), ec);
 }
diff --git a/WebCore/editing/InsertNodeBeforeCommand.cpp b/WebCore/editing/InsertNodeBeforeCommand.cpp
index 2ce9846..fb72312 100644
--- a/WebCore/editing/InsertNodeBeforeCommand.cpp
+++ b/WebCore/editing/InsertNodeBeforeCommand.cpp
@@ -26,6 +26,7 @@
 #include "config.h"
 #include "InsertNodeBeforeCommand.h"
 
+#include "AXObjectCache.h"
 #include "htmlediting.h"
 
 namespace WebCore {
@@ -51,6 +52,9 @@ void InsertNodeBeforeCommand::doApply()
 
     ExceptionCode ec;
     parent->insertBefore(m_insertChild.get(), m_refChild.get(), ec);
+
+    if (AXObjectCache::accessibilityEnabled())
+        document()->axObjectCache()->nodeTextChangeNotification(m_insertChild->renderer(), AXObjectCache::AXTextInserted, 0, m_insertChild->nodeValue().length());
 }
 
 void InsertNodeBeforeCommand::doUnapply()
@@ -58,6 +62,10 @@ void InsertNodeBeforeCommand::doUnapply()
     if (!m_insertChild->isContentEditable())
         return;
         
+    // Need to notify this before actually deleting the text
+    if (AXObjectCache::accessibilityEnabled())
+        document()->axObjectCache()->nodeTextChangeNotification(m_insertChild->renderer(), AXObjectCache::AXTextDeleted, 0, m_insertChild->nodeValue().length());
+
     ExceptionCode ec;
     m_insertChild->remove(ec);
 }
diff --git a/WebKit/gtk/ChangeLog b/WebKit/gtk/ChangeLog
index b3a894f..9b66c80 100644
--- a/WebKit/gtk/ChangeLog
+++ b/WebKit/gtk/ChangeLog
@@ -1,3 +1,20 @@
+2010-09-22  Mario Sanchez Prada  <msanchez at igalia.com>
+
+        Reviewed by Martin Robinson.
+
+        [Gtk] object:text-changed events should be emitted for entries and password text
+        https://bugs.webkit.org/show_bug.cgi?id=25898
+
+        New unit test to make sure text-changed signals are emitted
+
+        * tests/testatk.c:
+        (textChangedCb): New. Signal handler for the
+        text-changed::insert and text-changed::delete signals.
+        (checkTextChangesAndBailOut): New. Source function to check
+        the global result of the test and quit from the main loop.
+        (testWebkitAtkTextChangedNotifications): New test.
+        (main):
+
 2010-09-22  Martin Robinson  <mrobinson at igalia.com>
 
         Reviewed by Xan Lopez.
diff --git a/WebKit/gtk/tests/testatk.c b/WebKit/gtk/tests/testatk.c
index 9ca7c05..9e72334 100644
--- a/WebKit/gtk/tests/testatk.c
+++ b/WebKit/gtk/tests/testatk.c
@@ -44,6 +44,8 @@ static const char* contentsInTable = "<html><body><table><tr><td>foo</td><td>bar
 
 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>";
 
+static const char* formWithTextInputs = "<html><body><form><input type='text' name='entry' /></form></body></html>";
+
 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>";
 
 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>";
@@ -1037,6 +1039,68 @@ static void testWebkitAtkListsOfItems(void)
     g_object_unref(webView);
 }
 
+static gboolean textInserted = FALSE;
+static gboolean textDeleted = FALSE;
+
+static void textChangedCb(AtkText* text, gint pos, gint len, const gchar* detail)
+{
+    g_assert(text && ATK_IS_OBJECT(text));
+
+    if (!g_strcmp0(detail, "insert"))
+        textInserted = TRUE;
+    else if (!g_strcmp0(detail, "delete"))
+        textDeleted = TRUE;
+}
+
+static gboolean checkTextChanges(gpointer unused)
+{
+    g_assert_cmpint(textInserted, ==, TRUE);
+    g_assert_cmpint(textDeleted, ==, TRUE);
+    return FALSE;
+}
+
+static void testWebkitAtkTextChangedNotifications(void)
+{
+    WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
+    g_object_ref_sink(webView);
+    GtkAllocation alloc = { 0, 0, 800, 600 };
+    gtk_widget_size_allocate(GTK_WIDGET(webView), &alloc);
+    webkit_web_view_load_string(webView, formWithTextInputs, 0, 0, 0);
+
+    // Manually spin the main context to get the accessible objects
+    while (g_main_context_pending(0))
+        g_main_context_iteration(0, TRUE);
+
+    AtkObject* obj = gtk_widget_get_accessible(GTK_WIDGET(webView));
+    g_assert(obj);
+
+    AtkObject* form = atk_object_ref_accessible_child(obj, 0);
+    g_assert(ATK_IS_OBJECT(form));
+
+    AtkObject* textEntry = atk_object_ref_accessible_child(form, 0);
+    g_assert(ATK_IS_EDITABLE_TEXT(textEntry));
+    g_assert(atk_object_get_role(ATK_OBJECT(textEntry)) == ATK_ROLE_ENTRY);
+
+    g_signal_connect(textEntry, "text-changed::insert",
+                     G_CALLBACK(textChangedCb),
+                     (gpointer)"insert");
+    g_signal_connect(textEntry, "text-changed::delete",
+                     G_CALLBACK(textChangedCb),
+                     (gpointer)"delete");
+
+    gint pos = 0;
+    atk_editable_text_insert_text(ATK_EDITABLE_TEXT(textEntry), "foo bar baz", 11, &pos);
+    atk_editable_text_delete_text(ATK_EDITABLE_TEXT(textEntry), 4, 7);
+    textInserted = FALSE;
+    textDeleted = FALSE;
+
+    g_idle_add((GSourceFunc)checkTextChanges, 0);
+
+    g_object_unref(form);
+    g_object_unref(textEntry);
+    g_object_unref(webView);
+}
+
 int main(int argc, char** argv)
 {
     g_thread_init(NULL);
@@ -1056,6 +1120,7 @@ int main(int argc, char** argv)
     g_test_add_func("/webkit/atk/textSelections", testWekitAtkTextSelections);
     g_test_add_func("/webkit/atk/get_extents", test_webkit_atk_get_extents);
     g_test_add_func("/webkit/atk/listsOfItems", testWebkitAtkListsOfItems);
+    g_test_add_func("/webkit/atk/textChangedNotifications", testWebkitAtkTextChangedNotifications);
     return g_test_run ();
 }
 

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list