accessible/src/atk/nsMaiHyperlink.cpp

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* vim: set ts=2 et sw=2 tw=80: */
michael@0 3 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 4 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 6
michael@0 7 #include "nsIURI.h"
michael@0 8 #include "nsMaiHyperlink.h"
michael@0 9
michael@0 10 using namespace mozilla::a11y;
michael@0 11
michael@0 12 /* MaiAtkHyperlink */
michael@0 13
michael@0 14 #define MAI_TYPE_ATK_HYPERLINK (mai_atk_hyperlink_get_type ())
michael@0 15 #define MAI_ATK_HYPERLINK(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj),\
michael@0 16 MAI_TYPE_ATK_HYPERLINK, MaiAtkHyperlink))
michael@0 17 #define MAI_ATK_HYPERLINK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass),\
michael@0 18 MAI_TYPE_ATK_HYPERLINK, MaiAtkHyperlinkClass))
michael@0 19 #define MAI_IS_ATK_HYPERLINK(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj),\
michael@0 20 MAI_TYPE_ATK_HYPERLINK))
michael@0 21 #define MAI_IS_ATK_HYPERLINK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),\
michael@0 22 MAI_TYPE_ATK_HYPERLINK))
michael@0 23 #define MAI_ATK_HYPERLINK_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),\
michael@0 24 MAI_TYPE_ATK_HYPERLINK, MaiAtkHyperlinkClass))
michael@0 25
michael@0 26 /**
michael@0 27 * This MaiAtkHyperlink is a thin wrapper, in the MAI namespace,
michael@0 28 * for AtkHyperlink
michael@0 29 */
michael@0 30
michael@0 31 struct MaiAtkHyperlink
michael@0 32 {
michael@0 33 AtkHyperlink parent;
michael@0 34
michael@0 35 /*
michael@0 36 * The MaiHyperlink whose properties and features are exported via this
michael@0 37 * hyperlink instance.
michael@0 38 */
michael@0 39 MaiHyperlink *maiHyperlink;
michael@0 40 };
michael@0 41
michael@0 42 struct MaiAtkHyperlinkClass
michael@0 43 {
michael@0 44 AtkHyperlinkClass parent_class;
michael@0 45 };
michael@0 46
michael@0 47 GType mai_atk_hyperlink_get_type(void);
michael@0 48
michael@0 49 G_BEGIN_DECLS
michael@0 50 /* callbacks for AtkHyperlink */
michael@0 51 static void classInitCB(AtkHyperlinkClass *aClass);
michael@0 52 static void finalizeCB(GObject *aObj);
michael@0 53
michael@0 54 /* callbacks for AtkHyperlink virtual functions */
michael@0 55 static gchar *getUriCB(AtkHyperlink *aLink, gint aLinkIndex);
michael@0 56 static AtkObject *getObjectCB(AtkHyperlink *aLink, gint aLinkIndex);
michael@0 57 static gint getEndIndexCB(AtkHyperlink *aLink);
michael@0 58 static gint getStartIndexCB(AtkHyperlink *aLink);
michael@0 59 static gboolean isValidCB(AtkHyperlink *aLink);
michael@0 60 static gint getAnchorCountCB(AtkHyperlink *aLink);
michael@0 61 G_END_DECLS
michael@0 62
michael@0 63 static gpointer parent_class = nullptr;
michael@0 64 static Accessible*
michael@0 65 get_accessible_hyperlink(AtkHyperlink *aHyperlink);
michael@0 66
michael@0 67 GType
michael@0 68 mai_atk_hyperlink_get_type(void)
michael@0 69 {
michael@0 70 static GType type = 0;
michael@0 71
michael@0 72 if (!type) {
michael@0 73 static const GTypeInfo tinfo = {
michael@0 74 sizeof(MaiAtkHyperlinkClass),
michael@0 75 (GBaseInitFunc)nullptr,
michael@0 76 (GBaseFinalizeFunc)nullptr,
michael@0 77 (GClassInitFunc)classInitCB,
michael@0 78 (GClassFinalizeFunc)nullptr,
michael@0 79 nullptr, /* class data */
michael@0 80 sizeof(MaiAtkHyperlink), /* instance size */
michael@0 81 0, /* nb preallocs */
michael@0 82 (GInstanceInitFunc)nullptr,
michael@0 83 nullptr /* value table */
michael@0 84 };
michael@0 85
michael@0 86 type = g_type_register_static(ATK_TYPE_HYPERLINK,
michael@0 87 "MaiAtkHyperlink",
michael@0 88 &tinfo, GTypeFlags(0));
michael@0 89 }
michael@0 90 return type;
michael@0 91 }
michael@0 92
michael@0 93 MaiHyperlink::MaiHyperlink(Accessible* aHyperLink) :
michael@0 94 mHyperlink(aHyperLink),
michael@0 95 mMaiAtkHyperlink(nullptr)
michael@0 96 {
michael@0 97 }
michael@0 98
michael@0 99 MaiHyperlink::~MaiHyperlink()
michael@0 100 {
michael@0 101 if (mMaiAtkHyperlink) {
michael@0 102 MAI_ATK_HYPERLINK(mMaiAtkHyperlink)->maiHyperlink = nullptr;
michael@0 103 g_object_unref(mMaiAtkHyperlink);
michael@0 104 }
michael@0 105 }
michael@0 106
michael@0 107 AtkHyperlink*
michael@0 108 MaiHyperlink::GetAtkHyperlink(void)
michael@0 109 {
michael@0 110 NS_ENSURE_TRUE(mHyperlink, nullptr);
michael@0 111
michael@0 112 if (mMaiAtkHyperlink)
michael@0 113 return mMaiAtkHyperlink;
michael@0 114
michael@0 115 if (!mHyperlink->IsLink())
michael@0 116 return nullptr;
michael@0 117
michael@0 118 mMaiAtkHyperlink =
michael@0 119 reinterpret_cast<AtkHyperlink *>
michael@0 120 (g_object_new(mai_atk_hyperlink_get_type(), nullptr));
michael@0 121 NS_ASSERTION(mMaiAtkHyperlink, "OUT OF MEMORY");
michael@0 122 NS_ENSURE_TRUE(mMaiAtkHyperlink, nullptr);
michael@0 123
michael@0 124 /* be sure to initialize it with "this" */
michael@0 125 MaiHyperlink::Initialize(mMaiAtkHyperlink, this);
michael@0 126
michael@0 127 return mMaiAtkHyperlink;
michael@0 128 }
michael@0 129
michael@0 130 /* static */
michael@0 131
michael@0 132 /* remember to call this static function when a MaiAtkHyperlink
michael@0 133 * is created
michael@0 134 */
michael@0 135
michael@0 136 nsresult
michael@0 137 MaiHyperlink::Initialize(AtkHyperlink *aObj, MaiHyperlink *aHyperlink)
michael@0 138 {
michael@0 139 NS_ENSURE_ARG(MAI_IS_ATK_HYPERLINK(aObj));
michael@0 140 NS_ENSURE_ARG(aHyperlink);
michael@0 141
michael@0 142 /* initialize hyperlink */
michael@0 143 MAI_ATK_HYPERLINK(aObj)->maiHyperlink = aHyperlink;
michael@0 144 return NS_OK;
michael@0 145 }
michael@0 146
michael@0 147 /* static functions for ATK callbacks */
michael@0 148
michael@0 149 void
michael@0 150 classInitCB(AtkHyperlinkClass *aClass)
michael@0 151 {
michael@0 152 GObjectClass *gobject_class = G_OBJECT_CLASS(aClass);
michael@0 153
michael@0 154 parent_class = g_type_class_peek_parent(aClass);
michael@0 155
michael@0 156 aClass->get_uri = getUriCB;
michael@0 157 aClass->get_object = getObjectCB;
michael@0 158 aClass->get_end_index = getEndIndexCB;
michael@0 159 aClass->get_start_index = getStartIndexCB;
michael@0 160 aClass->is_valid = isValidCB;
michael@0 161 aClass->get_n_anchors = getAnchorCountCB;
michael@0 162
michael@0 163 gobject_class->finalize = finalizeCB;
michael@0 164 }
michael@0 165
michael@0 166 void
michael@0 167 finalizeCB(GObject *aObj)
michael@0 168 {
michael@0 169 NS_ASSERTION(MAI_IS_ATK_HYPERLINK(aObj), "Invalid MaiAtkHyperlink");
michael@0 170 if (!MAI_IS_ATK_HYPERLINK(aObj))
michael@0 171 return;
michael@0 172
michael@0 173 MaiAtkHyperlink *maiAtkHyperlink = MAI_ATK_HYPERLINK(aObj);
michael@0 174 maiAtkHyperlink->maiHyperlink = nullptr;
michael@0 175
michael@0 176 /* call parent finalize function */
michael@0 177 if (G_OBJECT_CLASS (parent_class)->finalize)
michael@0 178 G_OBJECT_CLASS (parent_class)->finalize(aObj);
michael@0 179 }
michael@0 180
michael@0 181 gchar *
michael@0 182 getUriCB(AtkHyperlink *aLink, gint aLinkIndex)
michael@0 183 {
michael@0 184 Accessible* hyperlink = get_accessible_hyperlink(aLink);
michael@0 185 NS_ENSURE_TRUE(hyperlink, nullptr);
michael@0 186
michael@0 187 nsCOMPtr<nsIURI> uri = hyperlink->AnchorURIAt(aLinkIndex);
michael@0 188 if (!uri)
michael@0 189 return nullptr;
michael@0 190
michael@0 191 nsAutoCString cautoStr;
michael@0 192 nsresult rv = uri->GetSpec(cautoStr);
michael@0 193 NS_ENSURE_SUCCESS(rv, nullptr);
michael@0 194
michael@0 195 return g_strdup(cautoStr.get());
michael@0 196 }
michael@0 197
michael@0 198 AtkObject *
michael@0 199 getObjectCB(AtkHyperlink *aLink, gint aLinkIndex)
michael@0 200 {
michael@0 201 Accessible* hyperlink = get_accessible_hyperlink(aLink);
michael@0 202 NS_ENSURE_TRUE(hyperlink, nullptr);
michael@0 203
michael@0 204 Accessible* anchor = hyperlink->AnchorAt(aLinkIndex);
michael@0 205 NS_ENSURE_TRUE(anchor, nullptr);
michael@0 206
michael@0 207 AtkObject* atkObj = AccessibleWrap::GetAtkObject(anchor);
michael@0 208 //no need to add ref it, because it is "get" not "ref"
michael@0 209 return atkObj;
michael@0 210 }
michael@0 211
michael@0 212 gint
michael@0 213 getEndIndexCB(AtkHyperlink *aLink)
michael@0 214 {
michael@0 215 Accessible* hyperlink = get_accessible_hyperlink(aLink);
michael@0 216 NS_ENSURE_TRUE(hyperlink, -1);
michael@0 217
michael@0 218 return static_cast<gint>(hyperlink->EndOffset());
michael@0 219 }
michael@0 220
michael@0 221 gint
michael@0 222 getStartIndexCB(AtkHyperlink *aLink)
michael@0 223 {
michael@0 224 Accessible* hyperlink = get_accessible_hyperlink(aLink);
michael@0 225 NS_ENSURE_TRUE(hyperlink, -1);
michael@0 226
michael@0 227 return static_cast<gint>(hyperlink->StartOffset());
michael@0 228 }
michael@0 229
michael@0 230 gboolean
michael@0 231 isValidCB(AtkHyperlink *aLink)
michael@0 232 {
michael@0 233 Accessible* hyperlink = get_accessible_hyperlink(aLink);
michael@0 234 NS_ENSURE_TRUE(hyperlink, FALSE);
michael@0 235
michael@0 236 return static_cast<gboolean>(hyperlink->IsLinkValid());
michael@0 237 }
michael@0 238
michael@0 239 gint
michael@0 240 getAnchorCountCB(AtkHyperlink *aLink)
michael@0 241 {
michael@0 242 Accessible* hyperlink = get_accessible_hyperlink(aLink);
michael@0 243 NS_ENSURE_TRUE(hyperlink, -1);
michael@0 244
michael@0 245 return static_cast<gint>(hyperlink->AnchorCount());
michael@0 246 }
michael@0 247
michael@0 248 // Check if aHyperlink is a valid MaiHyperlink, and return the
michael@0 249 // HyperLinkAccessible related.
michael@0 250 Accessible*
michael@0 251 get_accessible_hyperlink(AtkHyperlink *aHyperlink)
michael@0 252 {
michael@0 253 NS_ENSURE_TRUE(MAI_IS_ATK_HYPERLINK(aHyperlink), nullptr);
michael@0 254 MaiHyperlink * maiHyperlink =
michael@0 255 MAI_ATK_HYPERLINK(aHyperlink)->maiHyperlink;
michael@0 256 NS_ENSURE_TRUE(maiHyperlink != nullptr, nullptr);
michael@0 257 NS_ENSURE_TRUE(maiHyperlink->GetAtkHyperlink() == aHyperlink, nullptr);
michael@0 258 return maiHyperlink->GetAccHyperlink();
michael@0 259 }

mercurial