123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262 |
- /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
- /* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
- #include "nsIURI.h"
- #include "nsMaiHyperlink.h"
- #include "mozilla/a11y/ProxyAccessible.h"
- using namespace mozilla::a11y;
- /* MaiAtkHyperlink */
- #define MAI_TYPE_ATK_HYPERLINK (mai_atk_hyperlink_get_type ())
- #define MAI_ATK_HYPERLINK(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj),\
- MAI_TYPE_ATK_HYPERLINK, MaiAtkHyperlink))
- #define MAI_ATK_HYPERLINK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass),\
- MAI_TYPE_ATK_HYPERLINK, MaiAtkHyperlinkClass))
- #define MAI_IS_ATK_HYPERLINK(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj),\
- MAI_TYPE_ATK_HYPERLINK))
- #define MAI_IS_ATK_HYPERLINK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),\
- MAI_TYPE_ATK_HYPERLINK))
- #define MAI_ATK_HYPERLINK_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),\
- MAI_TYPE_ATK_HYPERLINK, MaiAtkHyperlinkClass))
- /**
- * This MaiAtkHyperlink is a thin wrapper, in the MAI namespace,
- * for AtkHyperlink
- */
- struct MaiAtkHyperlink
- {
- AtkHyperlink parent;
- /*
- * The MaiHyperlink whose properties and features are exported via this
- * hyperlink instance.
- */
- MaiHyperlink *maiHyperlink;
- };
- struct MaiAtkHyperlinkClass
- {
- AtkHyperlinkClass parent_class;
- };
- GType mai_atk_hyperlink_get_type(void);
- G_BEGIN_DECLS
- /* callbacks for AtkHyperlink */
- static void classInitCB(AtkHyperlinkClass *aClass);
- static void finalizeCB(GObject *aObj);
- /* callbacks for AtkHyperlink virtual functions */
- static gchar *getUriCB(AtkHyperlink *aLink, gint aLinkIndex);
- static AtkObject *getObjectCB(AtkHyperlink *aLink, gint aLinkIndex);
- static gint getEndIndexCB(AtkHyperlink *aLink);
- static gint getStartIndexCB(AtkHyperlink *aLink);
- static gboolean isValidCB(AtkHyperlink *aLink);
- static gint getAnchorCountCB(AtkHyperlink *aLink);
- G_END_DECLS
- static gpointer parent_class = nullptr;
- static MaiHyperlink*
- GetMaiHyperlink(AtkHyperlink *aHyperlink)
- {
- NS_ENSURE_TRUE(MAI_IS_ATK_HYPERLINK(aHyperlink), nullptr);
- MaiHyperlink * maiHyperlink =
- MAI_ATK_HYPERLINK(aHyperlink)->maiHyperlink;
- NS_ENSURE_TRUE(maiHyperlink != nullptr, nullptr);
- NS_ENSURE_TRUE(maiHyperlink->GetAtkHyperlink() == aHyperlink, nullptr);
- return maiHyperlink;
- }
- GType
- mai_atk_hyperlink_get_type(void)
- {
- static GType type = 0;
- if (!type) {
- static const GTypeInfo tinfo = {
- sizeof(MaiAtkHyperlinkClass),
- (GBaseInitFunc)nullptr,
- (GBaseFinalizeFunc)nullptr,
- (GClassInitFunc)classInitCB,
- (GClassFinalizeFunc)nullptr,
- nullptr, /* class data */
- sizeof(MaiAtkHyperlink), /* instance size */
- 0, /* nb preallocs */
- (GInstanceInitFunc)nullptr,
- nullptr /* value table */
- };
- type = g_type_register_static(ATK_TYPE_HYPERLINK,
- "MaiAtkHyperlink",
- &tinfo, GTypeFlags(0));
- }
- return type;
- }
- MaiHyperlink::MaiHyperlink(AccessibleOrProxy aHyperLink) :
- mHyperlink(aHyperLink),
- mMaiAtkHyperlink(nullptr)
- {
- mMaiAtkHyperlink =
- reinterpret_cast<AtkHyperlink *>
- (g_object_new(mai_atk_hyperlink_get_type(), nullptr));
- NS_ASSERTION(mMaiAtkHyperlink, "OUT OF MEMORY");
- if (!mMaiAtkHyperlink)
- return;
- MAI_ATK_HYPERLINK(mMaiAtkHyperlink)->maiHyperlink = this;
- }
- MaiHyperlink::~MaiHyperlink()
- {
- if (mMaiAtkHyperlink) {
- MAI_ATK_HYPERLINK(mMaiAtkHyperlink)->maiHyperlink = nullptr;
- g_object_unref(mMaiAtkHyperlink);
- }
- }
- /* static functions for ATK callbacks */
- void
- classInitCB(AtkHyperlinkClass *aClass)
- {
- GObjectClass *gobject_class = G_OBJECT_CLASS(aClass);
- parent_class = g_type_class_peek_parent(aClass);
- aClass->get_uri = getUriCB;
- aClass->get_object = getObjectCB;
- aClass->get_end_index = getEndIndexCB;
- aClass->get_start_index = getStartIndexCB;
- aClass->is_valid = isValidCB;
- aClass->get_n_anchors = getAnchorCountCB;
- gobject_class->finalize = finalizeCB;
- }
- void
- finalizeCB(GObject *aObj)
- {
- NS_ASSERTION(MAI_IS_ATK_HYPERLINK(aObj), "Invalid MaiAtkHyperlink");
- if (!MAI_IS_ATK_HYPERLINK(aObj))
- return;
- MaiAtkHyperlink *maiAtkHyperlink = MAI_ATK_HYPERLINK(aObj);
- maiAtkHyperlink->maiHyperlink = nullptr;
- /* call parent finalize function */
- if (G_OBJECT_CLASS (parent_class)->finalize)
- G_OBJECT_CLASS (parent_class)->finalize(aObj);
- }
- gchar *
- getUriCB(AtkHyperlink *aLink, gint aLinkIndex)
- {
- MaiHyperlink* maiLink = GetMaiHyperlink(aLink);
- if (!maiLink)
- return nullptr;
- nsAutoCString cautoStr;
- if (Accessible* hyperlink = maiLink->GetAccHyperlink()) {
- nsCOMPtr<nsIURI> uri = hyperlink->AnchorURIAt(aLinkIndex);
- if (!uri)
- return nullptr;
- nsresult rv = uri->GetSpec(cautoStr);
- NS_ENSURE_SUCCESS(rv, nullptr);
- return g_strdup(cautoStr.get());
- }
- bool valid;
- maiLink->Proxy()->AnchorURIAt(aLinkIndex, cautoStr, &valid);
- if (!valid)
- return nullptr;
- return g_strdup(cautoStr.get());
- }
- AtkObject *
- getObjectCB(AtkHyperlink *aLink, gint aLinkIndex)
- {
- MaiHyperlink* maiLink = GetMaiHyperlink(aLink);
- if (!maiLink) {
- return nullptr;
- }
- if (Accessible* hyperlink = maiLink->GetAccHyperlink()) {
- Accessible* anchor = hyperlink->AnchorAt(aLinkIndex);
- NS_ENSURE_TRUE(anchor, nullptr);
- return AccessibleWrap::GetAtkObject(anchor);
- }
- ProxyAccessible* anchor = maiLink->Proxy()->AnchorAt(aLinkIndex);
- return anchor ? GetWrapperFor(anchor) : nullptr;
- }
- gint
- getEndIndexCB(AtkHyperlink *aLink)
- {
- MaiHyperlink* maiLink = GetMaiHyperlink(aLink);
- if (!maiLink)
- return false;
- if (Accessible* hyperlink = maiLink->GetAccHyperlink())
- return static_cast<gint>(hyperlink->EndOffset());
- bool valid = false;
- uint32_t endIdx = maiLink->Proxy()->EndOffset(&valid);
- return valid ? static_cast<gint>(endIdx) : -1;
- }
- gint
- getStartIndexCB(AtkHyperlink *aLink)
- {
- MaiHyperlink* maiLink = GetMaiHyperlink(aLink);
- if (!maiLink)
- return -1;
- if (Accessible* hyperlink = maiLink->GetAccHyperlink())
- return static_cast<gint>(hyperlink->StartOffset());
- bool valid = false;
- uint32_t startIdx = maiLink->Proxy()->StartOffset(&valid);
- return valid ? static_cast<gint>(startIdx) : -1;
- }
- gboolean
- isValidCB(AtkHyperlink *aLink)
- {
- MaiHyperlink* maiLink = GetMaiHyperlink(aLink);
- if (!maiLink)
- return false;
- if (Accessible* hyperlink = maiLink->GetAccHyperlink())
- return static_cast<gboolean>(hyperlink->IsLinkValid());
- return static_cast<gboolean>(maiLink->Proxy()->IsLinkValid());
- }
- gint
- getAnchorCountCB(AtkHyperlink *aLink)
- {
- MaiHyperlink* maiLink = GetMaiHyperlink(aLink);
- if (!maiLink)
- return -1;
- if (Accessible* hyperlink = maiLink->GetAccHyperlink())
- return static_cast<gint>(hyperlink->AnchorCount());
- bool valid = false;
- uint32_t anchorCount = maiLink->Proxy()->AnchorCount(&valid);
- return valid ? static_cast<gint>(anchorCount) : -1;
- }
|