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

mario at webkit.org mario at webkit.org
Wed Dec 22 15:20:11 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit 7f95c62e08580baf44acb985c9cc26f0a1d7cc40
Author: mario at webkit.org <mario at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Mon Nov 1 15:05:36 2010 +0000

    2010-11-01  Mario Sanchez Prada  <msanchez at igalia.com>
    
            Reviewed by Martin Robinson.
    
            [Gtk] AtkHyperlink needs to be implemented
            https://bugs.webkit.org/show_bug.cgi?id=33785
    
            Implemented the AtkHyperlink/AtkHypertext stuff in the GTK port.
    
            Even thought these kind of tasks are usually about implementing an
            interface, in this case it was needed to implement some more
            things due to the fact that AtkHyperlink is neither an interface
            nor an AtkObject, but just an abstract class child of GObject that
            needs to be redefined in a specific subclass of that one. On top
            of that, it was needed to implement the AtkAction interface as
            well for that new class, so exposed hyperlinks can work as
            expected with Assistive Technologies based on ATK.
    
            Furthermore, as there's no mechanism to get an instance of that
            AtkHyperlink other than doing it through an AtkObject implementing
            the AtkHypertext interface, it was needed to also add the code to
            implement that one, so it makes possible to ask for the
            'hyperlinks' under an 'hypertext' accessible object.
    
            Finally, to complete the implementation of all this stuff and make
            it all consistent, it was needed as well to implement the
            AtkHyperlinkImpl interface (providing just one method only) so
            that allows retrieving the AtkHyperlink object associated to an
            AtkObject implementing such an interface.
    
            * GNUmakefile.am: Add the new WebKitAccessibleHyperlink.[h|cpp]
            files to the sources list for the GTK port.
    
            * accessibility/gtk/AccessibilityObjectWrapperAtk.cpp:
            (core): New function to return the core accessibility object
            related to an AtkObject implementing the AtkHypertext interface.
            (webkitAccessibleHypertextGetLink): New, part of the
            implementation of the AtkHypertext interface.
            (webkitAccessibleHypertextGetNLinks): New, likewise.
            (webkitAccessibleHypertextGetLinkIndex): New, likewise.
            (atkHypertextInterfaceInit): New, initialize the AtkHypertext
            interface.
            (webkitAccessibleHyperlinkImplGetHyperlink): New, part of the
            implementation of the AtkHyperlinkImpl interface.
            (atkHyperlinkImplInterfaceInit): New, initialize the
            AtkHyperlinkImpl interface.
            (GetAtkInterfaceTypeFromWAIType): Add ATK_TYPE_HYPERTEXT and
            ATK_TYPE_HYPERLINK_IMPL to the list of recognized types.
            (getInterfaceMaskFromObject): Decide when it's needed to add
            WAI_HYPERTEXT and WAI_HYPERLINK to the interface mask.
    
            * accessibility/gtk/WebKitAccessibleHyperlink.h: Added.
            * accessibility/gtk/WebKitAccessibleHyperlink.cpp: Added.
            (returnString): Return (const char*) from String variables.
            (core): Return the associated AccessibilityObject.
            (webkitAccessibleHyperlinkActionDoAction): Part of the
            implementation of the AtkAction interface.
            (webkitAccessibleHyperlinkActionGetNActions): Likewise.
            (webkitAccessibleHyperlinkActionGetDescription): Likewise.
            (webkitAccessibleHyperlinkActionGetKeybinding): Likewise.
            (webkitAccessibleHyperlinkActionGetName): Likewise.
            (atkActionInterfaceInit): Initialize the AtkAction interface.
            (getRangeLengthForObject): Returns the length for a given Range,
            considering special cases (e.g. List item markers).
            (webkitAccessibleHyperlinkGetURI): Implementation of one of the
            methods in the AtkHyperlink abstract class.
            (webkitAccessibleHyperlinkGetObject): Likewise.
            (webkitAccessibleHyperlinkGetStartIndex): Likewise.
            (webkitAccessibleHyperlinkGetEndIndex): Likewise.
            (webkitAccessibleHyperlinkIsValid): Likewise.
            (webkitAccessibleHyperlinkGetNAnchors): Likewise.
            (webkitAccessibleHyperlinkIsSelectedLink): Likewise.
            (webkitAccessibleHyperlinkGetProperty): Getter method.
            (webkitAccessibleHyperlinkSetProperty): Setter method.
            (webkitAccessibleHyperlinkFinalize): Finalize method.
            (webkitAccessibleHyperlinkClassInit): Initialize the
            WebKitAccessibleHyperlink class.
            (webkitAccessibleHyperlinkInit): Initialize the
            WebKitAccessibleHyperlink instance.
            (webkitAccessibleHyperlinkGetType): Implementation of the
            get_type() function for the WebKitAccessibleHyperlink class.
            (webkitAccessibleHyperlinkNew): Returns an instance of the class
            associated to a given AtkHyperlinkImpl object.
            (webkitAccessibleHyperlinkGetAccessibilityObject): Public function
            returning the AccessibilityObject associated to the instance of
            the WebKitAccessibleHyperlink class.
    
    2010-11-01  Mario Sanchez Prada  <msanchez at igalia.com>
    
            Reviewed by Martin Robinson.
    
            [Gtk] AtkHyperlink needs to be implemented
            https://bugs.webkit.org/show_bug.cgi?id=33785
    
            New test to ensure the AtkHypertext/AtkHyperlink stuff works.
    
            * tests/testatk.c:
            (testWebkitAtkHypertextAndHyperlinks): New test, checking both the
            implementation of the AtkHypertext interface, the subclass of the
            AtkHyperlink abstract class, and the implementation of the
            AtkAction interface in that subclass.
            (main): Added the new unit test.
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@71026 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 6fb4994..d0fae86 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,90 @@
+2010-11-01  Mario Sanchez Prada  <msanchez at igalia.com>
+
+        Reviewed by Martin Robinson.
+
+        [Gtk] AtkHyperlink needs to be implemented
+        https://bugs.webkit.org/show_bug.cgi?id=33785
+
+        Implemented the AtkHyperlink/AtkHypertext stuff in the GTK port.
+
+        Even thought these kind of tasks are usually about implementing an
+        interface, in this case it was needed to implement some more
+        things due to the fact that AtkHyperlink is neither an interface
+        nor an AtkObject, but just an abstract class child of GObject that
+        needs to be redefined in a specific subclass of that one. On top
+        of that, it was needed to implement the AtkAction interface as
+        well for that new class, so exposed hyperlinks can work as
+        expected with Assistive Technologies based on ATK.
+
+        Furthermore, as there's no mechanism to get an instance of that
+        AtkHyperlink other than doing it through an AtkObject implementing
+        the AtkHypertext interface, it was needed to also add the code to
+        implement that one, so it makes possible to ask for the
+        'hyperlinks' under an 'hypertext' accessible object.
+
+        Finally, to complete the implementation of all this stuff and make
+        it all consistent, it was needed as well to implement the
+        AtkHyperlinkImpl interface (providing just one method only) so
+        that allows retrieving the AtkHyperlink object associated to an
+        AtkObject implementing such an interface.
+
+        * GNUmakefile.am: Add the new WebKitAccessibleHyperlink.[h|cpp]
+        files to the sources list for the GTK port.
+
+        * accessibility/gtk/AccessibilityObjectWrapperAtk.cpp:
+        (core): New function to return the core accessibility object
+        related to an AtkObject implementing the AtkHypertext interface.
+        (webkitAccessibleHypertextGetLink): New, part of the
+        implementation of the AtkHypertext interface.
+        (webkitAccessibleHypertextGetNLinks): New, likewise.
+        (webkitAccessibleHypertextGetLinkIndex): New, likewise.
+        (atkHypertextInterfaceInit): New, initialize the AtkHypertext
+        interface.
+        (webkitAccessibleHyperlinkImplGetHyperlink): New, part of the
+        implementation of the AtkHyperlinkImpl interface.
+        (atkHyperlinkImplInterfaceInit): New, initialize the
+        AtkHyperlinkImpl interface.
+        (GetAtkInterfaceTypeFromWAIType): Add ATK_TYPE_HYPERTEXT and
+        ATK_TYPE_HYPERLINK_IMPL to the list of recognized types.
+        (getInterfaceMaskFromObject): Decide when it's needed to add
+        WAI_HYPERTEXT and WAI_HYPERLINK to the interface mask.
+
+        * accessibility/gtk/WebKitAccessibleHyperlink.h: Added.
+        * accessibility/gtk/WebKitAccessibleHyperlink.cpp: Added.
+        (returnString): Return (const char*) from String variables.
+        (core): Return the associated AccessibilityObject.
+        (webkitAccessibleHyperlinkActionDoAction): Part of the
+        implementation of the AtkAction interface.
+        (webkitAccessibleHyperlinkActionGetNActions): Likewise.
+        (webkitAccessibleHyperlinkActionGetDescription): Likewise.
+        (webkitAccessibleHyperlinkActionGetKeybinding): Likewise.
+        (webkitAccessibleHyperlinkActionGetName): Likewise.
+        (atkActionInterfaceInit): Initialize the AtkAction interface.
+        (getRangeLengthForObject): Returns the length for a given Range,
+        considering special cases (e.g. List item markers).
+        (webkitAccessibleHyperlinkGetURI): Implementation of one of the
+        methods in the AtkHyperlink abstract class.
+        (webkitAccessibleHyperlinkGetObject): Likewise.
+        (webkitAccessibleHyperlinkGetStartIndex): Likewise.
+        (webkitAccessibleHyperlinkGetEndIndex): Likewise.
+        (webkitAccessibleHyperlinkIsValid): Likewise.
+        (webkitAccessibleHyperlinkGetNAnchors): Likewise.
+        (webkitAccessibleHyperlinkIsSelectedLink): Likewise.
+        (webkitAccessibleHyperlinkGetProperty): Getter method.
+        (webkitAccessibleHyperlinkSetProperty): Setter method.
+        (webkitAccessibleHyperlinkFinalize): Finalize method.
+        (webkitAccessibleHyperlinkClassInit): Initialize the
+        WebKitAccessibleHyperlink class.
+        (webkitAccessibleHyperlinkInit): Initialize the
+        WebKitAccessibleHyperlink instance.
+        (webkitAccessibleHyperlinkGetType): Implementation of the
+        get_type() function for the WebKitAccessibleHyperlink class.
+        (webkitAccessibleHyperlinkNew): Returns an instance of the class
+        associated to a given AtkHyperlinkImpl object.
+        (webkitAccessibleHyperlinkGetAccessibilityObject): Public function
+        returning the AccessibilityObject associated to the instance of
+        the WebKitAccessibleHyperlink class.
+
 2010-11-01  Pavel Feldman  <pfeldman at chromium.org>
 
         Not reviewed: simplify inspector styles test to make all bots happy.
diff --git a/WebCore/GNUmakefile.am b/WebCore/GNUmakefile.am
index 7fe1dac..becbb81 100644
--- a/WebCore/GNUmakefile.am
+++ b/WebCore/GNUmakefile.am
@@ -3496,6 +3496,8 @@ webcoregtk_sources += \
 	WebCore/accessibility/gtk/AccessibilityObjectWrapperAtk.cpp \
 	WebCore/accessibility/gtk/AccessibilityObjectWrapperAtk.h \
 	WebCore/accessibility/gtk/AXObjectCacheAtk.cpp \
+	WebCore/accessibility/gtk/WebKitAccessibleHyperlink.h \
+	WebCore/accessibility/gtk/WebKitAccessibleHyperlink.cpp \
 	WebCore/bindings/js/ScriptControllerGtk.cpp \
 	WebCore/page/gtk/DragControllerGtk.cpp \
 	WebCore/page/gtk/EventHandlerGtk.cpp \
diff --git a/WebCore/accessibility/gtk/AccessibilityObjectWrapperAtk.cpp b/WebCore/accessibility/gtk/AccessibilityObjectWrapperAtk.cpp
index 283b2de..726cdb1 100644
--- a/WebCore/accessibility/gtk/AccessibilityObjectWrapperAtk.cpp
+++ b/WebCore/accessibility/gtk/AccessibilityObjectWrapperAtk.cpp
@@ -60,14 +60,15 @@
 #include "RenderText.h"
 #include "TextEncoding.h"
 #include "TextIterator.h"
-#include <wtf/text/CString.h>
-#include <wtf/text/AtomicString.h>
+#include "WebKitAccessibleHyperlink.h"
 
 #include <atk/atk.h>
 #include <glib.h>
 #include <glib/gprintf.h>
 #include <libgail-util/gail-util.h>
 #include <pango/pango.h>
+#include <wtf/text/AtomicString.h>
+#include <wtf/text/CString.h>
 
 using namespace WebCore;
 
@@ -143,6 +144,11 @@ static AccessibilityObject* core(AtkTable* table)
     return core(ATK_OBJECT(table));
 }
 
+static AccessibilityObject* core(AtkHypertext* hypertext)
+{
+    return core(ATK_OBJECT(hypertext));
+}
+
 static AccessibilityObject* core(AtkDocument* document)
 {
     return core(ATK_OBJECT(document));
@@ -1954,6 +1960,89 @@ static void atk_table_interface_init(AtkTableIface* iface)
     iface->get_row_description = webkit_accessible_table_get_row_description;
 }
 
+static AtkHyperlink* webkitAccessibleHypertextGetLink(AtkHypertext* hypertext, gint index)
+{
+    AccessibilityObject::AccessibilityChildrenVector children = core(hypertext)->children();
+    if (index < 0 || static_cast<unsigned>(index) >= children.size())
+        return 0;
+
+    gint currentLink = -1;
+    for (unsigned i = 0; i < children.size(); i++) {
+        AccessibilityObject* coreChild = children.at(i).get();
+        if (!coreChild->accessibilityIsIgnored() && coreChild->isLink()) {
+            currentLink++;
+            if (index != currentLink)
+                continue;
+
+            AtkObject* axObject = coreChild->wrapper();
+            if (!axObject || !ATK_IS_HYPERLINK_IMPL(axObject))
+                return 0;
+
+            return atk_hyperlink_impl_get_hyperlink(ATK_HYPERLINK_IMPL(axObject));
+        }
+    }
+
+    return 0;
+}
+
+static gint webkitAccessibleHypertextGetNLinks(AtkHypertext* hypertext)
+{
+    AccessibilityObject::AccessibilityChildrenVector children = core(hypertext)->children();
+    if (!children.size())
+        return 0;
+
+    gint linksFound = 0;
+    for (size_t i = 0; i < children.size(); i++) {
+        AccessibilityObject* coreChild = children.at(i).get();
+        if (!coreChild->accessibilityIsIgnored() && coreChild->isLink())
+            linksFound++;
+    }
+
+    return linksFound;
+}
+
+static gint webkitAccessibleHypertextGetLinkIndex(AtkHypertext* hypertext, gint charIndex)
+{
+    size_t linksCount = webkitAccessibleHypertextGetNLinks(hypertext);
+    if (!linksCount)
+        return -1;
+
+    for (size_t i = 0; i < linksCount; i++) {
+        AtkHyperlink* hyperlink = ATK_HYPERLINK(webkitAccessibleHypertextGetLink(hypertext, i));
+        gint startIndex = atk_hyperlink_get_start_index(hyperlink);
+        gint endIndex = atk_hyperlink_get_end_index(hyperlink);
+
+        // Check if the char index in the link's offset range
+        if (startIndex <= charIndex && charIndex < endIndex)
+            return i;
+    }
+
+    // Not found if reached
+    return -1;
+}
+
+static void atkHypertextInterfaceInit(AtkHypertextIface* iface)
+{
+    iface->get_link = webkitAccessibleHypertextGetLink;
+    iface->get_n_links = webkitAccessibleHypertextGetNLinks;
+    iface->get_link_index = webkitAccessibleHypertextGetLinkIndex;
+}
+
+static AtkHyperlink* webkitAccessibleHyperlinkImplGetHyperlink(AtkHyperlinkImpl* hyperlink)
+{
+    AtkHyperlink* hyperlinkObject = ATK_HYPERLINK(g_object_get_data(G_OBJECT(hyperlink), "hyperlink-object"));
+    if (!hyperlinkObject) {
+        hyperlinkObject = ATK_HYPERLINK(webkitAccessibleHyperlinkNew(hyperlink));
+        g_object_set_data(G_OBJECT(hyperlink), "hyperlink-object", hyperlinkObject);
+    }
+    return hyperlinkObject;
+}
+
+static void atkHyperlinkImplInterfaceInit(AtkHyperlinkImplIface* iface)
+{
+    iface->get_hyperlink = webkitAccessibleHyperlinkImplGetHyperlink;
+}
+
 static const gchar* documentAttributeValue(AtkDocument* document, const gchar* attribute)
 {
     Document* coreDocument = core(document)->document();
@@ -2025,6 +2114,10 @@ static const GInterfaceInfo AtkInterfacesInitFunctions[] = {
      (GInterfaceFinalizeFunc) 0, 0},
     {(GInterfaceInitFunc)atk_table_interface_init,
      (GInterfaceFinalizeFunc) 0, 0},
+    {(GInterfaceInitFunc)atkHypertextInterfaceInit,
+     (GInterfaceFinalizeFunc) 0, 0},
+    {(GInterfaceInitFunc)atkHyperlinkImplInterfaceInit,
+     (GInterfaceFinalizeFunc) 0, 0},
     {(GInterfaceInitFunc)atk_document_interface_init,
      (GInterfaceFinalizeFunc) 0, 0}
 };
@@ -2037,31 +2130,37 @@ enum WAIType {
     WAI_COMPONENT,
     WAI_IMAGE,
     WAI_TABLE,
+    WAI_HYPERTEXT,
+    WAI_HYPERLINK,
     WAI_DOCUMENT
 };
 
 static GType GetAtkInterfaceTypeFromWAIType(WAIType type)
 {
-  switch (type) {
-  case WAI_ACTION:
-      return ATK_TYPE_ACTION;
-  case WAI_SELECTION:
-      return ATK_TYPE_SELECTION;
-  case WAI_EDITABLE_TEXT:
-      return ATK_TYPE_EDITABLE_TEXT;
-  case WAI_TEXT:
-      return ATK_TYPE_TEXT;
-  case WAI_COMPONENT:
-      return ATK_TYPE_COMPONENT;
-  case WAI_IMAGE:
-      return ATK_TYPE_IMAGE;
-  case WAI_TABLE:
-      return ATK_TYPE_TABLE;
-  case WAI_DOCUMENT:
-      return ATK_TYPE_DOCUMENT;
-  }
-
-  return G_TYPE_INVALID;
+    switch (type) {
+    case WAI_ACTION:
+        return ATK_TYPE_ACTION;
+    case WAI_SELECTION:
+        return ATK_TYPE_SELECTION;
+    case WAI_EDITABLE_TEXT:
+        return ATK_TYPE_EDITABLE_TEXT;
+    case WAI_TEXT:
+        return ATK_TYPE_TEXT;
+    case WAI_COMPONENT:
+        return ATK_TYPE_COMPONENT;
+    case WAI_IMAGE:
+        return ATK_TYPE_IMAGE;
+    case WAI_TABLE:
+        return ATK_TYPE_TABLE;
+    case WAI_HYPERTEXT:
+        return ATK_TYPE_HYPERTEXT;
+    case WAI_HYPERLINK:
+        return ATK_TYPE_HYPERLINK_IMPL;
+    case WAI_DOCUMENT:
+        return ATK_TYPE_DOCUMENT;
+    }
+
+    return G_TYPE_INVALID;
 }
 
 static guint16 getInterfaceMaskFromObject(AccessibilityObject* coreObject)
@@ -2071,20 +2170,24 @@ static guint16 getInterfaceMaskFromObject(AccessibilityObject* coreObject)
     // Component interface is always supported
     interfaceMask |= 1 << WAI_COMPONENT;
 
+    AccessibilityRole role = coreObject->roleValue();
+
     // Action
-    if (!coreObject->actionVerb().isEmpty())
+    if (!coreObject->actionVerb().isEmpty()) {
         interfaceMask |= 1 << WAI_ACTION;
 
+        if (!coreObject->accessibilityIsIgnored() && coreObject->isLink())
+            interfaceMask |= 1 << WAI_HYPERLINK;
+    }
+
     // Selection
     if (coreObject->isListBox())
         interfaceMask |= 1 << WAI_SELECTION;
 
     // Text & Editable Text
-    AccessibilityRole role = coreObject->roleValue();
-
     if (role == StaticTextRole)
         interfaceMask |= 1 << WAI_TEXT;
-    else if (coreObject->isAccessibilityRenderObject())
+    else if (coreObject->isAccessibilityRenderObject()) {
         if (coreObject->isTextControl()) {
             interfaceMask |= 1 << WAI_TEXT;
             if (!coreObject->isReadOnly())
@@ -2092,11 +2195,15 @@ static guint16 getInterfaceMaskFromObject(AccessibilityObject* coreObject)
         } else {
             AccessibilityRenderObject* axRenderObject = static_cast<AccessibilityRenderObject*>(coreObject);
             RenderObject* renderer = axRenderObject->renderer();
-            if (role != TableRole && renderer && renderer->childrenInline())
-                interfaceMask |= 1 << WAI_TEXT;
-            else if (role == ListItemRole) {
-                // Add the TEXT interface for list items whose
-                // first accessible child has a text renderer
+            if (role != TableRole) {
+                interfaceMask |= 1 << WAI_HYPERTEXT;
+                if (renderer && renderer->childrenInline())
+                    interfaceMask |= 1 << WAI_TEXT;
+            }
+
+            // Add the TEXT interface for list items whose
+            // first accessible child has a text renderer
+            if (role == ListItemRole) {
                 AccessibilityObject::AccessibilityChildrenVector children = axRenderObject->children();
                 if (children.size()) {
                     AccessibilityObject* axRenderChild = children.at(0).get();
@@ -2104,6 +2211,7 @@ static guint16 getInterfaceMaskFromObject(AccessibilityObject* coreObject)
                 }
             }
         }
+    }
 
     // Image
     if (coreObject->isImage())
diff --git a/WebCore/accessibility/gtk/WebKitAccessibleHyperlink.cpp b/WebCore/accessibility/gtk/WebKitAccessibleHyperlink.cpp
new file mode 100644
index 0000000..5927430
--- /dev/null
+++ b/WebCore/accessibility/gtk/WebKitAccessibleHyperlink.cpp
@@ -0,0 +1,392 @@
+/*
+ * Copyright (C) 2010 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "WebKitAccessibleHyperlink.h"
+
+#if HAVE(ACCESSIBILITY)
+
+#include "AXObjectCache.h"
+#include "AccessibilityObject.h"
+#include "AccessibilityObjectWrapperAtk.h"
+#include "AccessibilityRenderObject.h"
+#include "NotImplemented.h"
+#include "Position.h"
+#include "Range.h"
+#include "RenderListMarker.h"
+#include "RenderObject.h"
+#include "TextIterator.h"
+
+#include <atk/atk.h>
+#include <glib.h>
+
+using namespace WebCore;
+
+struct _WebKitAccessibleHyperlinkPrivate {
+    WebKitAccessible* hyperlinkImpl;
+};
+
+#define WEBKIT_ACCESSIBLE_HYPERLINK_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), WEBKIT_TYPE_ACCESSIBLE_HYPERLINK, WebKitAccessibleHyperlinkPrivate))
+
+enum {
+    PROP_0,
+
+    PROP_HYPERLINK_IMPL
+};
+
+static gpointer webkitAccessibleHyperlinkParentClass = 0;
+
+// Used to provide const char* returns.
+static const char* returnString(const String& str)
+{
+    static CString returnedString;
+    returnedString = str.utf8();
+    return returnedString.data();
+}
+
+static AccessibilityObject* core(WebKitAccessible* accessible)
+{
+    if (!accessible || !WEBKIT_IS_ACCESSIBLE(accessible))
+        return 0;
+
+    return webkit_accessible_get_accessibility_object(accessible);
+}
+
+static AccessibilityObject* core(WebKitAccessibleHyperlink* link)
+{
+    if (!link)
+        return 0;
+
+    return core(link->priv->hyperlinkImpl);
+}
+
+static AccessibilityObject* core(AtkHyperlink* link)
+{
+    if (!WEBKIT_IS_ACCESSIBLE_HYPERLINK(link))
+        return 0;
+
+    return core(WEBKIT_ACCESSIBLE_HYPERLINK(link));
+}
+
+static AccessibilityObject* core(AtkAction* action)
+{
+    return core(WEBKIT_ACCESSIBLE_HYPERLINK(action));
+}
+
+
+static gboolean webkitAccessibleHyperlinkActionDoAction(AtkAction* action, gint index)
+{
+    g_return_val_if_fail(WEBKIT_IS_ACCESSIBLE_HYPERLINK(action), FALSE);
+    g_return_val_if_fail(WEBKIT_ACCESSIBLE_HYPERLINK(action)->priv->hyperlinkImpl, FALSE);
+    g_return_val_if_fail(!index, FALSE);
+
+    if (!ATK_IS_ACTION(WEBKIT_ACCESSIBLE_HYPERLINK(action)->priv->hyperlinkImpl))
+        return FALSE;
+
+    AccessibilityObject* coreObject = core(action);
+    if (!coreObject)
+        return FALSE;
+
+    return coreObject->performDefaultAction();
+}
+
+static gint webkitAccessibleHyperlinkActionGetNActions(AtkAction* action)
+{
+    g_return_val_if_fail(WEBKIT_IS_ACCESSIBLE_HYPERLINK(action), 0);
+    g_return_val_if_fail(WEBKIT_ACCESSIBLE_HYPERLINK(action)->priv->hyperlinkImpl, 0);
+
+    if (!ATK_IS_ACTION(WEBKIT_ACCESSIBLE_HYPERLINK(action)->priv->hyperlinkImpl))
+        return 0;
+
+    return 1;
+}
+
+static const gchar* webkitAccessibleHyperlinkActionGetDescription(AtkAction* action, gint index)
+{
+    g_return_val_if_fail(WEBKIT_IS_ACCESSIBLE_HYPERLINK(action), 0);
+    g_return_val_if_fail(WEBKIT_ACCESSIBLE_HYPERLINK(action)->priv->hyperlinkImpl, 0);
+    g_return_val_if_fail(!index, 0);
+
+    // TODO: Need a way to provide/localize action descriptions.
+    notImplemented();
+    return "";
+}
+
+static const gchar* webkitAccessibleHyperlinkActionGetKeybinding(AtkAction* action, gint index)
+{
+    g_return_val_if_fail(WEBKIT_IS_ACCESSIBLE_HYPERLINK(action), 0);
+    g_return_val_if_fail(WEBKIT_ACCESSIBLE_HYPERLINK(action)->priv->hyperlinkImpl, 0);
+    g_return_val_if_fail(!index, 0);
+
+    if (!ATK_IS_ACTION(WEBKIT_ACCESSIBLE_HYPERLINK(action)->priv->hyperlinkImpl))
+        return 0;
+
+    AccessibilityObject* coreObject = core(action);
+    if (!coreObject)
+        return 0;
+
+    return returnString(coreObject->accessKey().string());
+}
+
+static const gchar* webkitAccessibleHyperlinkActionGetName(AtkAction* action, gint index)
+{
+    g_return_val_if_fail(WEBKIT_IS_ACCESSIBLE_HYPERLINK(action), 0);
+    g_return_val_if_fail(WEBKIT_ACCESSIBLE_HYPERLINK(action)->priv->hyperlinkImpl, 0);
+    g_return_val_if_fail(!index, 0);
+
+    if (!ATK_IS_ACTION(WEBKIT_ACCESSIBLE_HYPERLINK(action)->priv->hyperlinkImpl))
+        return 0;
+
+    AccessibilityObject* coreObject = core(action);
+    if (!coreObject)
+        return 0;
+
+    return returnString(coreObject->actionVerb());
+}
+
+static void atkActionInterfaceInit(AtkActionIface* iface)
+{
+    iface->do_action = webkitAccessibleHyperlinkActionDoAction;
+    iface->get_n_actions = webkitAccessibleHyperlinkActionGetNActions;
+    iface->get_description = webkitAccessibleHyperlinkActionGetDescription;
+    iface->get_keybinding = webkitAccessibleHyperlinkActionGetKeybinding;
+    iface->get_name = webkitAccessibleHyperlinkActionGetName;
+}
+
+static gchar* webkitAccessibleHyperlinkGetURI(AtkHyperlink* link, gint index)
+{
+    g_return_val_if_fail(WEBKIT_IS_ACCESSIBLE_HYPERLINK(link), 0);
+    // FIXME: Do NOT support more than one instance of an AtkObject
+    // implementing AtkHyperlinkImpl in every instance of AtkHyperLink
+    g_return_val_if_fail(!index, 0);
+
+    AccessibilityObject* coreObject = core(link);
+    if (!coreObject || coreObject->url().isNull())
+        return 0;
+
+    return g_strdup(returnString(coreObject->url().string()));
+}
+
+static AtkObject* webkitAccessibleHyperlinkGetObject(AtkHyperlink* link, gint index)
+{
+    g_return_val_if_fail(WEBKIT_IS_ACCESSIBLE_HYPERLINK(link), 0);
+    g_return_val_if_fail(WEBKIT_ACCESSIBLE_HYPERLINK(link)->priv->hyperlinkImpl, 0);
+
+    // FIXME: Do NOT support more than one instance of an AtkObject
+    // implementing AtkHyperlinkImpl in every instance of AtkHyperLink
+    g_return_val_if_fail(!index, 0);
+
+    return ATK_OBJECT(WEBKIT_ACCESSIBLE_HYPERLINK(link)->priv->hyperlinkImpl);
+}
+
+static gint getRangeLengthForObject(AccessibilityObject* obj, Range* range)
+{
+    // This is going to be the actual length in most of the cases
+    int baseLength = TextIterator::rangeLength(range);
+
+    // Check whether the current hyperlink belongs to a list item.
+    // If so, we need to consider the length of the item's marker
+    AccessibilityObject* parent = obj->parentObjectUnignored();
+    if (!parent || !parent->isAccessibilityRenderObject() || !parent->isListItem())
+        return baseLength;
+
+    // Even if we don't expose list markers to Assistive
+    // Technologies, we need to have a way to measure their length
+    // for those cases when it's needed to take it into account
+    // separately (as in getAccessibilityObjectForOffset)
+    AccessibilityObject* markerObj = parent->firstChild();
+    if (!markerObj)
+        return baseLength;
+
+    RenderObject* renderer = static_cast<const AccessibilityRenderObject*>(markerObj)->renderer();
+    if (!renderer || !renderer->isListMarker())
+        return baseLength;
+
+    RenderListMarker* marker = toRenderListMarker(renderer);
+    return baseLength + marker->text().length() + marker->suffix().length();
+}
+
+static gint webkitAccessibleHyperlinkGetStartIndex(AtkHyperlink* link)
+{
+    g_return_val_if_fail(WEBKIT_IS_ACCESSIBLE_HYPERLINK(link), 0);
+
+    AccessibilityObject* coreObject = core(link);
+    if (!coreObject)
+        return 0;
+
+    Node* node = coreObject->node();
+    if (!node)
+        return 0;
+
+    RefPtr<Range> range = Range::create(node->document(), firstPositionInNode(node->parentNode()), firstPositionInNode(node));
+    return getRangeLengthForObject(coreObject, range.get());
+}
+
+static gint webkitAccessibleHyperlinkGetEndIndex(AtkHyperlink* link)
+{
+    g_return_val_if_fail(WEBKIT_IS_ACCESSIBLE_HYPERLINK(link), 0);
+
+    AccessibilityObject* coreObject = core(link);
+    if (!coreObject)
+        return 0;
+
+    Node* node = coreObject->node();
+    if (!node)
+        return 0;
+
+    RefPtr<Range> range = Range::create(node->document(), firstPositionInNode(node->parentNode()), lastPositionInNode(node));
+    return getRangeLengthForObject(coreObject, range.get());
+}
+
+static gboolean webkitAccessibleHyperlinkIsValid(AtkHyperlink* link)
+{
+    g_return_val_if_fail(WEBKIT_IS_ACCESSIBLE_HYPERLINK(link), 0);
+    g_return_val_if_fail(WEBKIT_ACCESSIBLE_HYPERLINK(link)->priv->hyperlinkImpl, FALSE);
+
+    // Link is valid for the whole object's lifetime
+    return TRUE;
+}
+
+static gint webkitAccessibleHyperlinkGetNAnchors(AtkHyperlink* link)
+{
+    // FIXME Do NOT support more than one instance of an AtkObject
+    // implementing AtkHyperlinkImpl in every instance of AtkHyperLink
+    g_return_val_if_fail(WEBKIT_IS_ACCESSIBLE_HYPERLINK(link), 0);
+    g_return_val_if_fail(WEBKIT_ACCESSIBLE_HYPERLINK(link)->priv->hyperlinkImpl, 0);
+    return 1;
+}
+
+static gboolean webkitAccessibleHyperlinkIsSelectedLink(AtkHyperlink* link)
+{
+    // Not implemented: this function is deprecated in ATK now
+    notImplemented();
+    return FALSE;
+}
+
+static void webkitAccessibleHyperlinkGetProperty(GObject* object, guint propId, GValue* value, GParamSpec* pspec)
+{
+    switch (propId) {
+    case PROP_HYPERLINK_IMPL:
+        g_value_set_object(value, WEBKIT_ACCESSIBLE_HYPERLINK(object)->priv->hyperlinkImpl);
+        break;
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, pspec);
+    }
+}
+
+static void webkitAccessibleHyperlinkSetProperty(GObject* object, guint propId, const GValue* value, GParamSpec* pspec)
+{
+    WebKitAccessibleHyperlinkPrivate* priv = WEBKIT_ACCESSIBLE_HYPERLINK(object)->priv;
+
+    switch (propId) {
+    case PROP_HYPERLINK_IMPL:
+        // No need to check and unref previous values of
+        // priv->hyperlinkImpl as this is a CONSTRUCT ONLY property
+        priv->hyperlinkImpl = WEBKIT_ACCESSIBLE(g_value_get_object(value));
+        g_object_weak_ref(G_OBJECT(priv->hyperlinkImpl), (GWeakNotify)g_object_unref, object);
+        break;
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, pspec);
+    }
+}
+
+static void webkitAccessibleHyperlinkFinalize(GObject* object)
+{
+    G_OBJECT_CLASS(webkitAccessibleHyperlinkParentClass)->finalize(object);
+}
+
+static void webkitAccessibleHyperlinkClassInit(AtkHyperlinkClass* klass)
+{
+    GObjectClass* gobjectClass = G_OBJECT_CLASS(klass);
+
+    webkitAccessibleHyperlinkParentClass = g_type_class_peek_parent(klass);
+
+    gobjectClass->finalize = webkitAccessibleHyperlinkFinalize;
+    gobjectClass->set_property = webkitAccessibleHyperlinkSetProperty;
+    gobjectClass->get_property = webkitAccessibleHyperlinkGetProperty;
+
+    klass->get_uri = webkitAccessibleHyperlinkGetURI;
+    klass->get_object = webkitAccessibleHyperlinkGetObject;
+    klass->get_start_index = webkitAccessibleHyperlinkGetStartIndex;
+    klass->get_end_index = webkitAccessibleHyperlinkGetEndIndex;
+    klass->is_valid = webkitAccessibleHyperlinkIsValid;
+    klass->get_n_anchors = webkitAccessibleHyperlinkGetNAnchors;
+    klass->is_selected_link = webkitAccessibleHyperlinkIsSelectedLink;
+
+    g_object_class_install_property(gobjectClass, PROP_HYPERLINK_IMPL,
+                                    g_param_spec_object("hyperlink-impl",
+                                                        "Hyperlink implementation",
+                                                        "The associated WebKitAccessible instance.",
+                                                        WEBKIT_TYPE_ACCESSIBLE,
+                                                        (GParamFlags)(G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)));
+
+    g_type_class_add_private(gobjectClass, sizeof(WebKitAccessibleHyperlinkPrivate));
+}
+
+static void webkitAccessibleHyperlinkInit(AtkHyperlink* link)
+{
+    WEBKIT_ACCESSIBLE_HYPERLINK(link)->priv = WEBKIT_ACCESSIBLE_HYPERLINK_GET_PRIVATE(link);
+    WEBKIT_ACCESSIBLE_HYPERLINK(link)->priv->hyperlinkImpl = 0;
+}
+
+GType webkitAccessibleHyperlinkGetType()
+{
+    static volatile gsize typeVolatile = 0;
+
+    if (g_once_init_enter(&typeVolatile)) {
+        static const GTypeInfo tinfo = {
+            sizeof(WebKitAccessibleHyperlinkClass),
+            (GBaseInitFunc) 0,
+            (GBaseFinalizeFunc) 0,
+            (GClassInitFunc) webkitAccessibleHyperlinkClassInit,
+            (GClassFinalizeFunc) 0,
+            0, /* class data */
+            sizeof(WebKitAccessibleHyperlink), /* instance size */
+            0, /* nb preallocs */
+            (GInstanceInitFunc) webkitAccessibleHyperlinkInit,
+            0 /* value table */
+        };
+
+        static const GInterfaceInfo actionInfo = {
+            (GInterfaceInitFunc)(GInterfaceInitFunc)atkActionInterfaceInit,
+            (GInterfaceFinalizeFunc) 0, 0
+        };
+
+        GType type = g_type_register_static(ATK_TYPE_HYPERLINK, "WebKitAccessibleHyperlink", &tinfo, GTypeFlags(0));
+        g_type_add_interface_static(type, ATK_TYPE_ACTION, &actionInfo);
+
+        g_once_init_leave(&typeVolatile, type);
+    }
+
+    return typeVolatile;
+}
+
+WebKitAccessibleHyperlink* webkitAccessibleHyperlinkNew(AtkHyperlinkImpl* hyperlinkImpl)
+{
+    g_return_val_if_fail(ATK_IS_HYPERLINK_IMPL(hyperlinkImpl), 0);
+    return WEBKIT_ACCESSIBLE_HYPERLINK(g_object_new(WEBKIT_TYPE_ACCESSIBLE_HYPERLINK, "hyperlink-impl", hyperlinkImpl, 0));
+}
+
+WebCore::AccessibilityObject* webkitAccessibleHyperlinkGetAccessibilityObject(WebKitAccessibleHyperlink* link)
+{
+    g_return_val_if_fail(WEBKIT_IS_ACCESSIBLE_HYPERLINK(link), 0);
+    return core(link);
+}
+
+#endif // HAVE(ACCESSIBILITY)
diff --git a/WebCore/accessibility/gtk/WebKitAccessibleHyperlink.h b/WebCore/accessibility/gtk/WebKitAccessibleHyperlink.h
new file mode 100644
index 0000000..9df819d
--- /dev/null
+++ b/WebCore/accessibility/gtk/WebKitAccessibleHyperlink.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2010 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef WebKitAccessibleHyperlink_h
+#define WebKitAccessibleHyperlink_h
+
+#include "AccessibilityObjectWrapperAtk.h"
+
+#include <atk/atk.h>
+
+namespace WebCore {
+class AccessibilityObject;
+}
+
+G_BEGIN_DECLS
+
+#define WEBKIT_TYPE_ACCESSIBLE_HYPERLINK                  (webkitAccessibleHyperlinkGetType ())
+#define WEBKIT_ACCESSIBLE_HYPERLINK(obj)                  (G_TYPE_CHECK_INSTANCE_CAST ((obj), WEBKIT_TYPE_ACCESSIBLE_HYPERLINK, WebKitAccessibleHyperlink))
+#define WEBKIT_ACCESSIBLE_HYPERLINK_CLASS(klass)          (G_TYPE_CHECK_CLASS_CAST ((klass), WEBKIT_TYPE_ACCESSIBLE_HYPERLINK, WebKitAccessibleHyperlinkClass))
+#define WEBKIT_IS_ACCESSIBLE_HYPERLINK(obj)               (G_TYPE_CHECK_INSTANCE_TYPE ((obj), WEBKIT_TYPE_ACCESSIBLE_HYPERLINK))
+#define WEBKIT_IS_ACCESSIBLE_HYPERLINK_CLASS(klass)       (G_TYPE_CHECK_CLASS_TYPE ((klass), WEBKIT_TYPE_ACCESSIBLE_HYPERLINK))
+#define WEBKIT_ACCESSIBLE_HYPERLINK_GET_CLASS(obj)        (G_TYPE_INSTANCE_GET_CLASS ((obj), WEBKIT_TYPE_ACCESSIBLE_HYPERLINK, WebKitAccessibleHyperlinkClass))
+
+typedef struct _WebKitAccessibleHyperlink                WebKitAccessibleHyperlink;
+typedef struct _WebKitAccessibleHyperlinkClass           WebKitAccessibleHyperlinkClass;
+typedef struct _WebKitAccessibleHyperlinkPrivate         WebKitAccessibleHyperlinkPrivate;
+
+struct _WebKitAccessibleHyperlink {
+    AtkHyperlink parent;
+
+    // private
+    WebKitAccessibleHyperlinkPrivate *priv;
+};
+
+struct _WebKitAccessibleHyperlinkClass {
+    AtkObjectClass parentClass;
+};
+
+GType webkitAccessibleHyperlinkGetType(void) G_GNUC_CONST;
+
+WebKitAccessibleHyperlink* webkitAccessibleHyperlinkNew(AtkHyperlinkImpl* hyperlinkImpl);
+
+WebCore::AccessibilityObject* webkitAccessibleHyperlinkGetAccessibilityObject(WebKitAccessibleHyperlink* link);
+
+G_END_DECLS
+
+#endif // WebKitAccessibleHyperlink_h
diff --git a/WebKit/gtk/ChangeLog b/WebKit/gtk/ChangeLog
index e4e009b..03201c1 100644
--- a/WebKit/gtk/ChangeLog
+++ b/WebKit/gtk/ChangeLog
@@ -1,3 +1,19 @@
+2010-11-01  Mario Sanchez Prada  <msanchez at igalia.com>
+
+        Reviewed by Martin Robinson.
+
+        [Gtk] AtkHyperlink needs to be implemented
+        https://bugs.webkit.org/show_bug.cgi?id=33785
+
+        New test to ensure the AtkHypertext/AtkHyperlink stuff works.
+
+        * tests/testatk.c:
+        (testWebkitAtkHypertextAndHyperlinks): New test, checking both the
+        implementation of the AtkHypertext interface, the subclass of the
+        AtkHyperlink abstract class, and the implementation of the
+        AtkAction interface in that subclass.
+        (main): Added the new unit test.
+
 2010-10-30  Xan Lopez  <xlopez at igalia.com>
 
         Reviewed by Martin Robinson.
diff --git a/WebKit/gtk/tests/testatk.c b/WebKit/gtk/tests/testatk.c
index bd6473a..50e4a08 100644
--- a/WebKit/gtk/tests/testatk.c
+++ b/WebKit/gtk/tests/testatk.c
@@ -46,6 +46,8 @@ static const char* contentsInTableWithHeaders = "<html><body><table><tr><th>foo<
 
 static const char* formWithTextInputs = "<html><body><form><input type='text' name='entry' /></form></body></html>";
 
+static const char* hypertextAndHyperlinks = "<html><body><p>A paragraph with no links at all</p><p><a href='http://foo.bar.baz/'>A line</a> with <a href='http://bar.baz.foo/'>a link in the middle</a> as well as at the beginning and <a href='http://baz.foo.bar/'>at the end</a></p></body></html>";
+
 static const char* layoutAndDataTables = "<html><body><table><tr><th>Odd</th><th>Even</th></tr><tr><td>1</td><td>2</td></tr></table><table><tr><td>foo</td><td>bar</td></tr></table></body></html>";
 
 static const char* linksWithInlineImages = "<html><head><style>a.http:before {content: url(no-image.png);}</style><body><p><a class='http' href='foo'>foo</a> bar baz</p><p>foo <a class='http' href='bar'>bar</a> baz</p><p>foo bar <a class='http' href='baz'>baz</a></p></body></html>";
@@ -1070,6 +1072,81 @@ static void testWebkitAtkLinksWithInlineImages(void)
     g_object_unref(webView);
 }
 
+static void testWebkitAtkHypertextAndHyperlinks(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, hypertextAndHyperlinks, 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* paragraph1 = atk_object_ref_accessible_child(obj, 0);
+    g_assert(ATK_OBJECT(paragraph1));
+    g_assert(atk_object_get_role(paragraph1) == ATK_ROLE_PARAGRAPH);
+    g_assert(ATK_IS_HYPERTEXT(paragraph1));
+
+    // No links in the first paragraph
+    gint nLinks = atk_hypertext_get_n_links(ATK_HYPERTEXT(paragraph1));
+    g_assert_cmpint(nLinks, ==, 0);
+
+    AtkObject* paragraph2 = atk_object_ref_accessible_child(obj, 1);
+    g_assert(ATK_OBJECT(paragraph2));
+    g_assert(atk_object_get_role(paragraph2) == ATK_ROLE_PARAGRAPH);
+    g_assert(ATK_IS_HYPERTEXT(paragraph2));
+
+    // Check links in the second paragraph
+    nLinks = atk_hypertext_get_n_links(ATK_HYPERTEXT(paragraph2));
+    g_assert_cmpint(nLinks, ==, 3);
+
+    AtkHyperlink* hLink1 = atk_hypertext_get_link(ATK_HYPERTEXT(paragraph2), 0);
+    g_assert(ATK_HYPERLINK(hLink1));
+    AtkObject* hLinkObject1 = atk_hyperlink_get_object(hLink1, 0);
+    g_assert(ATK_OBJECT(hLinkObject1));
+    g_assert(atk_object_get_role(hLinkObject1) == ATK_ROLE_LINK);
+    g_assert_cmpint(atk_hyperlink_get_start_index(hLink1), ==, 0);
+    g_assert_cmpint(atk_hyperlink_get_end_index(hLink1), ==, 6);
+    g_assert_cmpint(atk_hyperlink_get_n_anchors(hLink1), ==, 1);
+    g_assert_cmpstr(atk_hyperlink_get_uri(hLink1, 0), ==, "http://foo.bar.baz/");
+
+    AtkHyperlink* hLink2 = atk_hypertext_get_link(ATK_HYPERTEXT(paragraph2), 1);
+    g_assert(ATK_HYPERLINK(hLink2));
+    AtkObject* hLinkObject2 = atk_hyperlink_get_object(hLink2, 0);
+    g_assert(ATK_OBJECT(hLinkObject2));
+    g_assert(atk_object_get_role(hLinkObject2) == ATK_ROLE_LINK);
+    g_assert_cmpint(atk_hyperlink_get_start_index(hLink2), ==, 12);
+    g_assert_cmpint(atk_hyperlink_get_end_index(hLink2), ==, 32);
+    g_assert_cmpint(atk_hyperlink_get_n_anchors(hLink2), ==, 1);
+    g_assert_cmpstr(atk_hyperlink_get_uri(hLink2, 0), ==, "http://bar.baz.foo/");
+
+    AtkHyperlink* hLink3 = atk_hypertext_get_link(ATK_HYPERTEXT(paragraph2), 2);
+    g_assert(ATK_HYPERLINK(hLink3));
+    AtkObject* hLinkObject3 = atk_hyperlink_get_object(hLink3, 0);
+    g_assert(ATK_OBJECT(hLinkObject3));
+    g_assert(atk_object_get_role(hLinkObject3) == ATK_ROLE_LINK);
+    g_assert_cmpint(atk_hyperlink_get_start_index(hLink3), ==, 65);
+    g_assert_cmpint(atk_hyperlink_get_end_index(hLink3), ==, 75);
+    g_assert_cmpint(atk_hyperlink_get_n_anchors(hLink3), ==, 1);
+    g_assert_cmpstr(atk_hyperlink_get_uri(hLink3, 0), ==, "http://baz.foo.bar/");
+
+    // Finally check the AtkAction interface for a given AtkHyperlink
+    g_assert(ATK_IS_ACTION(hLink1));
+    g_assert_cmpint(atk_action_get_n_actions(ATK_ACTION(hLink1)), ==, 1);
+    g_assert_cmpstr(atk_action_get_keybinding(ATK_ACTION(hLink1), 0), ==, "");
+    g_assert_cmpstr(atk_action_get_name(ATK_ACTION(hLink1), 0), ==, "jump");
+    g_assert(atk_action_do_action(ATK_ACTION(hLink1), 0));
+
+    g_object_unref(paragraph1);
+    g_object_unref(paragraph2);
+    g_object_unref(webView);
+}
+
 static void testWebkitAtkListsOfItems(void)
 {
     WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
@@ -1222,6 +1299,7 @@ int main(int argc, char** argv)
     g_test_add_func("/webkit/atk/textAttributes", testWebkitAtkTextAttributes);
     g_test_add_func("/webkit/atk/textSelections", testWekitAtkTextSelections);
     g_test_add_func("/webkit/atk/getExtents", testWebkitAtkGetExtents);
+    g_test_add_func("/webkit/atk/hypertextAndHyperlinks", testWebkitAtkHypertextAndHyperlinks);
     g_test_add_func("/webkit/atk/layoutAndDataTables", testWebkitAtkLayoutAndDataTables);
     g_test_add_func("/webkit/atk/linksWithInlineImages", testWebkitAtkLinksWithInlineImages);
     g_test_add_func("/webkit/atk/listsOfItems", testWebkitAtkListsOfItems);

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list