Bug 1700051: part 36) Reduce accessibility of `SoftText::mBegin` to `private`. r...
[gecko.git] / accessible / atk / nsMaiHyperlink.cpp
blob85108f0fba5e5c7c4c23508f3edf75835c762536
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "nsIURI.h"
8 #include "nsMaiHyperlink.h"
9 #include "mozilla/a11y/RemoteAccessible.h"
11 using namespace mozilla::a11y;
13 /* MaiAtkHyperlink */
15 #define MAI_TYPE_ATK_HYPERLINK (mai_atk_hyperlink_get_type())
16 #define MAI_ATK_HYPERLINK(obj) \
17 (G_TYPE_CHECK_INSTANCE_CAST((obj), MAI_TYPE_ATK_HYPERLINK, MaiAtkHyperlink))
18 #define MAI_ATK_HYPERLINK_CLASS(klass) \
19 (G_TYPE_CHECK_CLASS_CAST((klass), MAI_TYPE_ATK_HYPERLINK, \
20 MaiAtkHyperlinkClass))
21 #define MAI_IS_ATK_HYPERLINK(obj) \
22 (G_TYPE_CHECK_INSTANCE_TYPE((obj), MAI_TYPE_ATK_HYPERLINK))
23 #define MAI_IS_ATK_HYPERLINK_CLASS(klass) \
24 (G_TYPE_CHECK_CLASS_TYPE((klass), MAI_TYPE_ATK_HYPERLINK))
25 #define MAI_ATK_HYPERLINK_GET_CLASS(obj) \
26 (G_TYPE_INSTANCE_GET_CLASS((obj), MAI_TYPE_ATK_HYPERLINK, \
27 MaiAtkHyperlinkClass))
29 /**
30 * This MaiAtkHyperlink is a thin wrapper, in the MAI namespace,
31 * for AtkHyperlink
34 struct MaiAtkHyperlink {
35 AtkHyperlink parent;
38 * The MaiHyperlink whose properties and features are exported via this
39 * hyperlink instance.
41 MaiHyperlink* maiHyperlink;
44 struct MaiAtkHyperlinkClass {
45 AtkHyperlinkClass parent_class;
48 GType mai_atk_hyperlink_get_type(void);
50 G_BEGIN_DECLS
51 /* callbacks for AtkHyperlink */
52 static void classInitCB(AtkHyperlinkClass* aClass);
53 static void finalizeCB(GObject* aObj);
55 /* callbacks for AtkHyperlink virtual functions */
56 static gchar* getUriCB(AtkHyperlink* aLink, gint aLinkIndex);
57 static AtkObject* getObjectCB(AtkHyperlink* aLink, gint aLinkIndex);
58 static gint getEndIndexCB(AtkHyperlink* aLink);
59 static gint getStartIndexCB(AtkHyperlink* aLink);
60 static gboolean isValidCB(AtkHyperlink* aLink);
61 static gint getAnchorCountCB(AtkHyperlink* aLink);
62 G_END_DECLS
64 static gpointer parent_class = nullptr;
66 static MaiHyperlink* GetMaiHyperlink(AtkHyperlink* aHyperlink) {
67 NS_ENSURE_TRUE(MAI_IS_ATK_HYPERLINK(aHyperlink), nullptr);
68 MaiHyperlink* maiHyperlink = MAI_ATK_HYPERLINK(aHyperlink)->maiHyperlink;
69 NS_ENSURE_TRUE(maiHyperlink != nullptr, nullptr);
70 NS_ENSURE_TRUE(maiHyperlink->GetAtkHyperlink() == aHyperlink, nullptr);
71 return maiHyperlink;
74 GType mai_atk_hyperlink_get_type(void) {
75 static GType type = 0;
77 if (!type) {
78 static const GTypeInfo tinfo = {
79 sizeof(MaiAtkHyperlinkClass),
80 (GBaseInitFunc) nullptr,
81 (GBaseFinalizeFunc) nullptr,
82 (GClassInitFunc)classInitCB,
83 (GClassFinalizeFunc) nullptr,
84 nullptr, /* class data */
85 sizeof(MaiAtkHyperlink), /* instance size */
86 0, /* nb preallocs */
87 (GInstanceInitFunc) nullptr,
88 nullptr /* value table */
91 type = g_type_register_static(ATK_TYPE_HYPERLINK, "MaiAtkHyperlink", &tinfo,
92 GTypeFlags(0));
94 return type;
97 MaiHyperlink::MaiHyperlink(AccessibleOrProxy aHyperLink)
98 : mHyperlink(aHyperLink), mMaiAtkHyperlink(nullptr) {
99 mMaiAtkHyperlink = reinterpret_cast<AtkHyperlink*>(
100 g_object_new(mai_atk_hyperlink_get_type(), nullptr));
101 NS_ASSERTION(mMaiAtkHyperlink, "OUT OF MEMORY");
102 if (!mMaiAtkHyperlink) return;
104 MAI_ATK_HYPERLINK(mMaiAtkHyperlink)->maiHyperlink = this;
107 MaiHyperlink::~MaiHyperlink() {
108 if (mMaiAtkHyperlink) {
109 MAI_ATK_HYPERLINK(mMaiAtkHyperlink)->maiHyperlink = nullptr;
110 g_object_unref(mMaiAtkHyperlink);
114 /* static functions for ATK callbacks */
116 void classInitCB(AtkHyperlinkClass* aClass) {
117 GObjectClass* gobject_class = G_OBJECT_CLASS(aClass);
119 parent_class = g_type_class_peek_parent(aClass);
121 aClass->get_uri = getUriCB;
122 aClass->get_object = getObjectCB;
123 aClass->get_end_index = getEndIndexCB;
124 aClass->get_start_index = getStartIndexCB;
125 aClass->is_valid = isValidCB;
126 aClass->get_n_anchors = getAnchorCountCB;
128 gobject_class->finalize = finalizeCB;
131 void finalizeCB(GObject* aObj) {
132 NS_ASSERTION(MAI_IS_ATK_HYPERLINK(aObj), "Invalid MaiAtkHyperlink");
133 if (!MAI_IS_ATK_HYPERLINK(aObj)) return;
135 MaiAtkHyperlink* maiAtkHyperlink = MAI_ATK_HYPERLINK(aObj);
136 maiAtkHyperlink->maiHyperlink = nullptr;
138 /* call parent finalize function */
139 if (G_OBJECT_CLASS(parent_class)->finalize) {
140 G_OBJECT_CLASS(parent_class)->finalize(aObj);
144 gchar* getUriCB(AtkHyperlink* aLink, gint aLinkIndex) {
145 MaiHyperlink* maiLink = GetMaiHyperlink(aLink);
146 if (!maiLink) return nullptr;
148 nsAutoCString cautoStr;
149 if (LocalAccessible* hyperlink = maiLink->GetAccHyperlink()) {
150 nsCOMPtr<nsIURI> uri = hyperlink->AnchorURIAt(aLinkIndex);
151 if (!uri) return nullptr;
153 nsresult rv = uri->GetSpec(cautoStr);
154 NS_ENSURE_SUCCESS(rv, nullptr);
156 return g_strdup(cautoStr.get());
159 bool valid;
160 maiLink->Proxy()->AnchorURIAt(aLinkIndex, cautoStr, &valid);
161 if (!valid) return nullptr;
163 return g_strdup(cautoStr.get());
166 AtkObject* getObjectCB(AtkHyperlink* aLink, gint aLinkIndex) {
167 MaiHyperlink* maiLink = GetMaiHyperlink(aLink);
168 if (!maiLink) {
169 return nullptr;
172 if (LocalAccessible* hyperlink = maiLink->GetAccHyperlink()) {
173 LocalAccessible* anchor = hyperlink->AnchorAt(aLinkIndex);
174 NS_ENSURE_TRUE(anchor, nullptr);
176 return AccessibleWrap::GetAtkObject(anchor);
179 RemoteAccessible* anchor = maiLink->Proxy()->AnchorAt(aLinkIndex);
180 return anchor ? GetWrapperFor(anchor) : nullptr;
183 gint getEndIndexCB(AtkHyperlink* aLink) {
184 MaiHyperlink* maiLink = GetMaiHyperlink(aLink);
185 if (!maiLink) return false;
187 if (LocalAccessible* hyperlink = maiLink->GetAccHyperlink()) {
188 return static_cast<gint>(hyperlink->EndOffset());
191 bool valid = false;
192 uint32_t endIdx = maiLink->Proxy()->EndOffset(&valid);
193 return valid ? static_cast<gint>(endIdx) : -1;
196 gint getStartIndexCB(AtkHyperlink* aLink) {
197 MaiHyperlink* maiLink = GetMaiHyperlink(aLink);
198 if (!maiLink) return -1;
200 if (LocalAccessible* hyperlink = maiLink->GetAccHyperlink()) {
201 return static_cast<gint>(hyperlink->StartOffset());
204 bool valid = false;
205 uint32_t startIdx = maiLink->Proxy()->StartOffset(&valid);
206 return valid ? static_cast<gint>(startIdx) : -1;
209 gboolean isValidCB(AtkHyperlink* aLink) {
210 MaiHyperlink* maiLink = GetMaiHyperlink(aLink);
211 if (!maiLink) return false;
213 if (LocalAccessible* hyperlink = maiLink->GetAccHyperlink()) {
214 return static_cast<gboolean>(hyperlink->IsLinkValid());
217 return static_cast<gboolean>(maiLink->Proxy()->IsLinkValid());
220 gint getAnchorCountCB(AtkHyperlink* aLink) {
221 MaiHyperlink* maiLink = GetMaiHyperlink(aLink);
222 if (!maiLink) return -1;
224 if (LocalAccessible* hyperlink = maiLink->GetAccHyperlink()) {
225 return static_cast<gint>(hyperlink->AnchorCount());
228 bool valid = false;
229 uint32_t anchorCount = maiLink->Proxy()->AnchorCount(&valid);
230 return valid ? static_cast<gint>(anchorCount) : -1;