1/*
2 * Copyright (C) 2010, 2011, 2012 Igalia S.L.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public License
15 * along with this library; see the file COPYING.LIB.  If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
20#include "config.h"
21#include "WebKitAccessibleInterfaceHypertext.h"
22
23#if HAVE(ACCESSIBILITY)
24
25#include "AccessibilityObject.h"
26#include "WebKitAccessibleWrapperAtk.h"
27
28using namespace WebCore;
29
30static AccessibilityObject* core(AtkHypertext* hypertext)
31{
32    if (!WEBKIT_IS_ACCESSIBLE(hypertext))
33        return 0;
34
35    return webkitAccessibleGetAccessibilityObject(WEBKIT_ACCESSIBLE(hypertext));
36}
37
38static AtkHyperlink* webkitAccessibleHypertextGetLink(AtkHypertext* hypertext, gint index)
39{
40    AccessibilityObject::AccessibilityChildrenVector children = core(hypertext)->children();
41    if (index < 0 || static_cast<unsigned>(index) >= children.size())
42        return 0;
43
44    gint currentLink = -1;
45    for (unsigned i = 0; i < children.size(); i++) {
46        AccessibilityObject* coreChild = children.at(i).get();
47        if (!coreChild->accessibilityIsIgnored()) {
48            AtkObject* axObject = coreChild->wrapper();
49            if (!axObject || !ATK_IS_HYPERLINK_IMPL(axObject))
50                continue;
51
52            currentLink++;
53            if (index != currentLink)
54                continue;
55
56            return atk_hyperlink_impl_get_hyperlink(ATK_HYPERLINK_IMPL(axObject));
57        }
58    }
59
60    return 0;
61}
62
63static gint webkitAccessibleHypertextGetNLinks(AtkHypertext* hypertext)
64{
65    AccessibilityObject::AccessibilityChildrenVector children = core(hypertext)->children();
66    if (!children.size())
67        return 0;
68
69    gint linksFound = 0;
70    for (size_t i = 0; i < children.size(); i++) {
71        AccessibilityObject* coreChild = children.at(i).get();
72        if (!coreChild->accessibilityIsIgnored()) {
73            AtkObject* axObject = coreChild->wrapper();
74            if (axObject && ATK_IS_HYPERLINK_IMPL(axObject))
75                linksFound++;
76        }
77    }
78
79    return linksFound;
80}
81
82static gint webkitAccessibleHypertextGetLinkIndex(AtkHypertext* hypertext, gint charIndex)
83{
84    size_t linksCount = webkitAccessibleHypertextGetNLinks(hypertext);
85    if (!linksCount)
86        return -1;
87
88    for (size_t i = 0; i < linksCount; i++) {
89        AtkHyperlink* hyperlink = ATK_HYPERLINK(webkitAccessibleHypertextGetLink(hypertext, i));
90        gint startIndex = atk_hyperlink_get_start_index(hyperlink);
91        gint endIndex = atk_hyperlink_get_end_index(hyperlink);
92
93        // Check if the char index in the link's offset range
94        if (startIndex <= charIndex && charIndex < endIndex)
95            return i;
96    }
97
98    // Not found if reached
99    return -1;
100}
101
102void webkitAccessibleHypertextInterfaceInit(AtkHypertextIface* iface)
103{
104    iface->get_link = webkitAccessibleHypertextGetLink;
105    iface->get_n_links = webkitAccessibleHypertextGetNLinks;
106    iface->get_link_index = webkitAccessibleHypertextGetLinkIndex;
107}
108
109#endif
110