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.

     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"
    10 using namespace mozilla::a11y;
    12 /* MaiAtkHyperlink */
    14 #define MAI_TYPE_ATK_HYPERLINK      (mai_atk_hyperlink_get_type ())
    15 #define MAI_ATK_HYPERLINK(obj)      (G_TYPE_CHECK_INSTANCE_CAST ((obj),\
    16                                      MAI_TYPE_ATK_HYPERLINK, MaiAtkHyperlink))
    17 #define MAI_ATK_HYPERLINK_CLASS(klass)  (G_TYPE_CHECK_CLASS_CAST ((klass),\
    18                                  MAI_TYPE_ATK_HYPERLINK, MaiAtkHyperlinkClass))
    19 #define MAI_IS_ATK_HYPERLINK(obj)      (G_TYPE_CHECK_INSTANCE_TYPE ((obj),\
    20                                         MAI_TYPE_ATK_HYPERLINK))
    21 #define MAI_IS_ATK_HYPERLINK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),\
    22                                         MAI_TYPE_ATK_HYPERLINK))
    23 #define MAI_ATK_HYPERLINK_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),\
    24                                  MAI_TYPE_ATK_HYPERLINK, MaiAtkHyperlinkClass))
    26 /**
    27  * This MaiAtkHyperlink is a thin wrapper, in the MAI namespace,
    28  * for AtkHyperlink
    29  */
    31 struct MaiAtkHyperlink
    32 {
    33     AtkHyperlink parent;
    35     /*
    36      * The MaiHyperlink whose properties and features are exported via this
    37      * hyperlink instance.
    38      */
    39     MaiHyperlink *maiHyperlink;
    40 };
    42 struct MaiAtkHyperlinkClass
    43 {
    44     AtkHyperlinkClass parent_class;
    45 };
    47 GType mai_atk_hyperlink_get_type(void);
    49 G_BEGIN_DECLS
    50 /* callbacks for AtkHyperlink */
    51 static void classInitCB(AtkHyperlinkClass *aClass);
    52 static void finalizeCB(GObject *aObj);
    54 /* callbacks for AtkHyperlink virtual functions */
    55 static gchar *getUriCB(AtkHyperlink *aLink, gint aLinkIndex);
    56 static AtkObject *getObjectCB(AtkHyperlink *aLink, gint aLinkIndex);
    57 static gint getEndIndexCB(AtkHyperlink *aLink);
    58 static gint getStartIndexCB(AtkHyperlink *aLink);
    59 static gboolean isValidCB(AtkHyperlink *aLink);
    60 static gint getAnchorCountCB(AtkHyperlink *aLink);
    61 G_END_DECLS
    63 static gpointer parent_class = nullptr;
    64 static Accessible*
    65 get_accessible_hyperlink(AtkHyperlink *aHyperlink);
    67 GType
    68 mai_atk_hyperlink_get_type(void)
    69 {
    70     static GType type = 0;
    72     if (!type) {
    73         static const GTypeInfo tinfo = {
    74             sizeof(MaiAtkHyperlinkClass),
    75             (GBaseInitFunc)nullptr,
    76             (GBaseFinalizeFunc)nullptr,
    77             (GClassInitFunc)classInitCB,
    78             (GClassFinalizeFunc)nullptr,
    79             nullptr, /* class data */
    80             sizeof(MaiAtkHyperlink), /* instance size */
    81             0, /* nb preallocs */
    82             (GInstanceInitFunc)nullptr,
    83             nullptr /* value table */
    84         };
    86         type = g_type_register_static(ATK_TYPE_HYPERLINK,
    87                                       "MaiAtkHyperlink",
    88                                       &tinfo, GTypeFlags(0));
    89     }
    90     return type;
    91 }
    93 MaiHyperlink::MaiHyperlink(Accessible* aHyperLink) :
    94     mHyperlink(aHyperLink),
    95     mMaiAtkHyperlink(nullptr)
    96 {
    97 }
    99 MaiHyperlink::~MaiHyperlink()
   100 {
   101     if (mMaiAtkHyperlink) {
   102         MAI_ATK_HYPERLINK(mMaiAtkHyperlink)->maiHyperlink = nullptr;
   103         g_object_unref(mMaiAtkHyperlink);
   104     }
   105 }
   107 AtkHyperlink*
   108 MaiHyperlink::GetAtkHyperlink(void)
   109 {
   110   NS_ENSURE_TRUE(mHyperlink, nullptr);
   112   if (mMaiAtkHyperlink)
   113     return mMaiAtkHyperlink;
   115   if (!mHyperlink->IsLink())
   116     return nullptr;
   118     mMaiAtkHyperlink =
   119         reinterpret_cast<AtkHyperlink *>
   120                         (g_object_new(mai_atk_hyperlink_get_type(), nullptr));
   121     NS_ASSERTION(mMaiAtkHyperlink, "OUT OF MEMORY");
   122     NS_ENSURE_TRUE(mMaiAtkHyperlink, nullptr);
   124     /* be sure to initialize it with "this" */
   125     MaiHyperlink::Initialize(mMaiAtkHyperlink, this);
   127     return mMaiAtkHyperlink;
   128 }
   130 /* static */
   132 /* remember to call this static function when a MaiAtkHyperlink
   133  * is created
   134  */
   136 nsresult
   137 MaiHyperlink::Initialize(AtkHyperlink *aObj, MaiHyperlink *aHyperlink)
   138 {
   139     NS_ENSURE_ARG(MAI_IS_ATK_HYPERLINK(aObj));
   140     NS_ENSURE_ARG(aHyperlink);
   142     /* initialize hyperlink */
   143     MAI_ATK_HYPERLINK(aObj)->maiHyperlink = aHyperlink;
   144     return NS_OK;
   145 }
   147 /* static functions for ATK callbacks */
   149 void
   150 classInitCB(AtkHyperlinkClass *aClass)
   151 {
   152     GObjectClass *gobject_class = G_OBJECT_CLASS(aClass);
   154     parent_class = g_type_class_peek_parent(aClass);
   156     aClass->get_uri = getUriCB;
   157     aClass->get_object = getObjectCB;
   158     aClass->get_end_index = getEndIndexCB;
   159     aClass->get_start_index = getStartIndexCB;
   160     aClass->is_valid = isValidCB;
   161     aClass->get_n_anchors = getAnchorCountCB;
   163     gobject_class->finalize = finalizeCB;
   164 }
   166 void
   167 finalizeCB(GObject *aObj)
   168 {
   169     NS_ASSERTION(MAI_IS_ATK_HYPERLINK(aObj), "Invalid MaiAtkHyperlink");
   170     if (!MAI_IS_ATK_HYPERLINK(aObj))
   171         return;
   173     MaiAtkHyperlink *maiAtkHyperlink = MAI_ATK_HYPERLINK(aObj);
   174     maiAtkHyperlink->maiHyperlink = nullptr;
   176     /* call parent finalize function */
   177     if (G_OBJECT_CLASS (parent_class)->finalize)
   178         G_OBJECT_CLASS (parent_class)->finalize(aObj);
   179 }
   181 gchar *
   182 getUriCB(AtkHyperlink *aLink, gint aLinkIndex)
   183 {
   184     Accessible* hyperlink = get_accessible_hyperlink(aLink);
   185     NS_ENSURE_TRUE(hyperlink, nullptr);
   187     nsCOMPtr<nsIURI> uri = hyperlink->AnchorURIAt(aLinkIndex);
   188     if (!uri)
   189         return nullptr;
   191     nsAutoCString cautoStr;
   192     nsresult rv = uri->GetSpec(cautoStr);
   193     NS_ENSURE_SUCCESS(rv, nullptr);
   195     return g_strdup(cautoStr.get());
   196 }
   198 AtkObject *
   199 getObjectCB(AtkHyperlink *aLink, gint aLinkIndex)
   200 {
   201     Accessible* hyperlink = get_accessible_hyperlink(aLink);
   202     NS_ENSURE_TRUE(hyperlink, nullptr);
   204     Accessible* anchor = hyperlink->AnchorAt(aLinkIndex);
   205     NS_ENSURE_TRUE(anchor, nullptr);
   207     AtkObject* atkObj = AccessibleWrap::GetAtkObject(anchor);
   208     //no need to add ref it, because it is "get" not "ref"
   209     return atkObj;
   210 }
   212 gint
   213 getEndIndexCB(AtkHyperlink *aLink)
   214 {
   215     Accessible* hyperlink = get_accessible_hyperlink(aLink);
   216     NS_ENSURE_TRUE(hyperlink, -1);
   218     return static_cast<gint>(hyperlink->EndOffset());
   219 }
   221 gint
   222 getStartIndexCB(AtkHyperlink *aLink)
   223 {
   224     Accessible* hyperlink = get_accessible_hyperlink(aLink);
   225     NS_ENSURE_TRUE(hyperlink, -1);
   227     return static_cast<gint>(hyperlink->StartOffset());
   228 }
   230 gboolean
   231 isValidCB(AtkHyperlink *aLink)
   232 {
   233     Accessible* hyperlink = get_accessible_hyperlink(aLink);
   234     NS_ENSURE_TRUE(hyperlink, FALSE);
   236     return static_cast<gboolean>(hyperlink->IsLinkValid());
   237 }
   239 gint
   240 getAnchorCountCB(AtkHyperlink *aLink)
   241 {
   242     Accessible* hyperlink = get_accessible_hyperlink(aLink);
   243     NS_ENSURE_TRUE(hyperlink, -1);
   245     return static_cast<gint>(hyperlink->AnchorCount());
   246 }
   248 // Check if aHyperlink is a valid MaiHyperlink, and return the
   249 // HyperLinkAccessible related.
   250 Accessible*
   251 get_accessible_hyperlink(AtkHyperlink *aHyperlink)
   252 {
   253     NS_ENSURE_TRUE(MAI_IS_ATK_HYPERLINK(aHyperlink), nullptr);
   254     MaiHyperlink * maiHyperlink =
   255         MAI_ATK_HYPERLINK(aHyperlink)->maiHyperlink;
   256     NS_ENSURE_TRUE(maiHyperlink != nullptr, nullptr);
   257     NS_ENSURE_TRUE(maiHyperlink->GetAtkHyperlink() == aHyperlink, nullptr);
   258     return maiHyperlink->GetAccHyperlink();
   259 }

mercurial