blob: c3d8f32a69d6c496a8d502e13d36f22cd18b2271 [file] [log] [blame]
// Copyright (c) 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/accessibility/platform/ax_platform_atk_hyperlink.h"
#include "ui/accessibility/ax_text_utils.h"
#include "ui/accessibility/platform/ax_platform_node_auralinux.h"
#include "ui/accessibility/platform/ax_platform_node_delegate.h"
namespace ui {
struct _AXPlatformAtkHyperlinkPrivate {
AXPlatformNodeAuraLinux* platform_node = nullptr;
base::Optional<int> end_index;
base::Optional<int> start_index;
};
static gpointer kAXPlatformAtkHyperlinkParentClass = nullptr;
static AXPlatformNodeAuraLinux* ToAXPlatformNodeAuraLinux(
AXPlatformAtkHyperlink* atk_hyperlink) {
if (!atk_hyperlink)
return nullptr;
return atk_hyperlink->priv->platform_node;
}
static void AXPlatformAtkHyperlinkFinalize(GObject* self) {
AX_PLATFORM_ATK_HYPERLINK(self)->priv->~AXPlatformAtkHyperlinkPrivate();
G_OBJECT_CLASS(kAXPlatformAtkHyperlinkParentClass)->finalize(self);
}
static gchar* AXPlatformAtkHyperlinkGetUri(AtkHyperlink* atk_hyperlink,
gint index) {
AXPlatformNodeAuraLinux* obj =
ToAXPlatformNodeAuraLinux(AX_PLATFORM_ATK_HYPERLINK(atk_hyperlink));
if (!obj)
return nullptr;
if (index != 0)
return nullptr;
return g_strdup(
obj->GetStringAttribute(ax::mojom::StringAttribute::kUrl).c_str());
}
static AtkObject* AXPlatformAtkHyperlinkGetObject(AtkHyperlink* atk_hyperlink,
gint index) {
AXPlatformNodeAuraLinux* obj =
ToAXPlatformNodeAuraLinux(AX_PLATFORM_ATK_HYPERLINK(atk_hyperlink));
if (!obj)
return nullptr;
if (index != 0)
return nullptr;
return ATK_OBJECT(obj->GetNativeViewAccessible());
}
static gint AXPlatformAtkHyperlinkGetNAnchors(AtkHyperlink* atk_hyperlink) {
AXPlatformNodeAuraLinux* obj =
ToAXPlatformNodeAuraLinux(AX_PLATFORM_ATK_HYPERLINK(atk_hyperlink));
return obj ? 1 : 0;
}
static gboolean AXPlatformAtkHyperlinkIsValid(AtkHyperlink* atk_hyperlink) {
AXPlatformNodeAuraLinux* obj =
ToAXPlatformNodeAuraLinux(AX_PLATFORM_ATK_HYPERLINK(atk_hyperlink));
return obj ? TRUE : FALSE;
}
static gboolean AXPlatformAtkHyperlinkIsSelectedLink(
AtkHyperlink* atk_hyperlink) {
AXPlatformNodeAuraLinux* obj =
ToAXPlatformNodeAuraLinux(AX_PLATFORM_ATK_HYPERLINK(atk_hyperlink));
if (!obj)
return false;
return obj->GetDelegate()->GetFocus() == obj->GetNativeViewAccessible();
}
static int AXPlatformAtkHyperlinkGetStartIndex(AtkHyperlink* atk_hyperlink) {
g_return_val_if_fail(IS_AX_PLATFORM_ATK_HYPERLINK(atk_hyperlink), 0);
AXPlatformAtkHyperlink* link = AX_PLATFORM_ATK_HYPERLINK(atk_hyperlink);
return link->priv->start_index ? *link->priv->start_index : 0;
}
static int AXPlatformAtkHyperlinkGetEndIndex(AtkHyperlink* atk_hyperlink) {
g_return_val_if_fail(IS_AX_PLATFORM_ATK_HYPERLINK(atk_hyperlink), 0);
AXPlatformAtkHyperlink* link = AX_PLATFORM_ATK_HYPERLINK(atk_hyperlink);
return link->priv->end_index ? *link->priv->end_index : 0;
}
static void AXPlatformAtkHyperlinkClassInit(AtkHyperlinkClass* klass) {
GObjectClass* gobject_class = G_OBJECT_CLASS(klass);
kAXPlatformAtkHyperlinkParentClass = g_type_class_peek_parent(klass);
g_type_class_add_private(gobject_class,
sizeof(AXPlatformAtkHyperlinkPrivate));
gobject_class->finalize = AXPlatformAtkHyperlinkFinalize;
klass->get_uri = AXPlatformAtkHyperlinkGetUri;
klass->get_object = AXPlatformAtkHyperlinkGetObject;
klass->is_valid = AXPlatformAtkHyperlinkIsValid;
klass->get_n_anchors = AXPlatformAtkHyperlinkGetNAnchors;
klass->is_selected_link = AXPlatformAtkHyperlinkIsSelectedLink;
klass->get_start_index = AXPlatformAtkHyperlinkGetStartIndex;
klass->get_end_index = AXPlatformAtkHyperlinkGetEndIndex;
}
//
// AtkAction interface.
//
static AXPlatformNodeAuraLinux* ToAXPlatformNodeAuraLinuxFromHyperlinkAction(
AtkAction* atk_action) {
if (!IS_AX_PLATFORM_ATK_HYPERLINK(atk_action))
return nullptr;
return ToAXPlatformNodeAuraLinux(AX_PLATFORM_ATK_HYPERLINK(atk_action));
}
static gboolean ax_platform_atk_hyperlink_do_action(AtkAction* action,
gint index) {
g_return_val_if_fail(ATK_IS_ACTION(action), FALSE);
g_return_val_if_fail(!index, FALSE);
AXPlatformNodeAuraLinux* obj =
ToAXPlatformNodeAuraLinuxFromHyperlinkAction(action);
if (!obj)
return FALSE;
obj->DoDefaultAction();
return TRUE;
}
static gint ax_platform_atk_hyperlink_get_n_actions(AtkAction* action) {
g_return_val_if_fail(ATK_IS_ACTION(action), FALSE);
AXPlatformNodeAuraLinux* obj =
ToAXPlatformNodeAuraLinuxFromHyperlinkAction(action);
if (!obj)
return 0;
return 1;
}
static const gchar* ax_platform_atk_hyperlink_get_description(AtkAction* action,
gint index) {
g_return_val_if_fail(ATK_IS_ACTION(action), FALSE);
g_return_val_if_fail(!index, FALSE);
AXPlatformNodeAuraLinux* obj =
ToAXPlatformNodeAuraLinuxFromHyperlinkAction(action);
if (!obj)
return nullptr;
// Not implemented
return nullptr;
}
static const gchar* ax_platform_atk_hyperlink_get_keybinding(AtkAction* action,
gint index) {
g_return_val_if_fail(ATK_IS_ACTION(action), FALSE);
g_return_val_if_fail(!index, FALSE);
AXPlatformNodeAuraLinux* obj =
ToAXPlatformNodeAuraLinuxFromHyperlinkAction(action);
if (!obj)
return nullptr;
return obj->GetStringAttribute(ax::mojom::StringAttribute::kAccessKey)
.c_str();
}
static const gchar* ax_platform_atk_hyperlink_get_name(AtkAction* atk_action,
gint index) {
g_return_val_if_fail(ATK_IS_ACTION(atk_action), FALSE);
g_return_val_if_fail(!index, FALSE);
AXPlatformNodeAuraLinux* obj =
ToAXPlatformNodeAuraLinuxFromHyperlinkAction(atk_action);
if (!obj)
return nullptr;
int action;
if (!obj->GetIntAttribute(ax::mojom::IntAttribute::kDefaultActionVerb,
&action))
return nullptr;
base::string16 action_verb = ui::ActionVerbToUnlocalizedString(
static_cast<ax::mojom::DefaultActionVerb>(action));
ATK_AURALINUX_RETURN_STRING(base::UTF16ToUTF8(action_verb));
}
static const gchar* ax_platform_atk_hyperlink_get_localized_name(
AtkAction* atk_action,
gint index) {
g_return_val_if_fail(ATK_IS_ACTION(atk_action), FALSE);
g_return_val_if_fail(!index, FALSE);
AXPlatformNodeAuraLinux* obj =
ToAXPlatformNodeAuraLinuxFromHyperlinkAction(atk_action);
if (!obj)
return nullptr;
int action;
if (!obj->GetIntAttribute(ax::mojom::IntAttribute::kDefaultActionVerb,
&action))
return nullptr;
base::string16 action_verb = ui::ActionVerbToLocalizedString(
static_cast<ax::mojom::DefaultActionVerb>(action));
ATK_AURALINUX_RETURN_STRING(base::UTF16ToUTF8(action_verb));
}
static void atk_action_interface_init(AtkActionIface* iface) {
iface->do_action = ax_platform_atk_hyperlink_do_action;
iface->get_n_actions = ax_platform_atk_hyperlink_get_n_actions;
iface->get_description = ax_platform_atk_hyperlink_get_description;
iface->get_keybinding = ax_platform_atk_hyperlink_get_keybinding;
iface->get_name = ax_platform_atk_hyperlink_get_name;
iface->get_localized_name = ax_platform_atk_hyperlink_get_localized_name;
}
void ax_platform_atk_hyperlink_set_object(
AXPlatformAtkHyperlink* atk_hyperlink,
AXPlatformNodeAuraLinux* platform_node) {
g_return_if_fail(AX_PLATFORM_ATK_HYPERLINK(atk_hyperlink));
atk_hyperlink->priv->platform_node = platform_node;
}
void ax_platform_atk_hyperlink_set_indices(
AXPlatformAtkHyperlink* atk_hyperlink,
int start_index,
int end_index) {
atk_hyperlink->priv->start_index = start_index;
atk_hyperlink->priv->end_index = end_index;
}
static void AXPlatformAtkHyperlinkInit(AXPlatformAtkHyperlink* self, gpointer) {
AXPlatformAtkHyperlinkPrivate* priv =
G_TYPE_INSTANCE_GET_PRIVATE(self, ax_platform_atk_hyperlink_get_type(),
AXPlatformAtkHyperlinkPrivate);
self->priv = priv;
new (priv) AXPlatformAtkHyperlinkPrivate();
}
GType ax_platform_atk_hyperlink_get_type() {
static volatile gsize type_volatile = 0;
AXPlatformNodeAuraLinux::EnsureGTypeInit();
if (g_once_init_enter(&type_volatile)) {
static const GTypeInfo tinfo = {
sizeof(AXPlatformAtkHyperlinkClass),
(GBaseInitFunc) nullptr,
(GBaseFinalizeFunc) nullptr,
(GClassInitFunc)AXPlatformAtkHyperlinkClassInit,
(GClassFinalizeFunc) nullptr,
nullptr, /* class data */
sizeof(AXPlatformAtkHyperlink), /* instance size */
0, /* nb preallocs */
(GInstanceInitFunc)AXPlatformAtkHyperlinkInit,
nullptr /* value table */
};
static const GInterfaceInfo actionInfo = {
(GInterfaceInitFunc)(GInterfaceInitFunc)atk_action_interface_init,
(GInterfaceFinalizeFunc)0, 0};
GType type = g_type_register_static(
ATK_TYPE_HYPERLINK, "AXPlatformAtkHyperlink", &tinfo, GTypeFlags(0));
g_type_add_interface_static(type, ATK_TYPE_ACTION, &actionInfo);
g_once_init_leave(&type_volatile, type);
}
return type_volatile;
}
} // namespace ui