michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* vim: set ts=2 et sw=2 tw=80: */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "InterfaceInitFuncs.h" michael@0: michael@0: #include "Accessible-inl.h" michael@0: #include "AccessibleWrap.h" michael@0: #include "DocAccessible.h" michael@0: #include "nsMai.h" michael@0: #include "mozilla/Likely.h" michael@0: michael@0: using namespace mozilla::a11y; michael@0: michael@0: static const char* const kDocTypeName = "W3C-doctype"; michael@0: static const char* const kDocUrlName = "DocURL"; michael@0: static const char* const kMimeTypeName = "MimeType"; michael@0: michael@0: // below functions are vfuncs on an ATK interface so they need to be C call michael@0: extern "C" { michael@0: michael@0: static const gchar* getDocumentLocaleCB(AtkDocument* aDocument); michael@0: static AtkAttributeSet* getDocumentAttributesCB(AtkDocument* aDocument); michael@0: static const gchar* getDocumentAttributeValueCB(AtkDocument* aDocument, michael@0: const gchar* aAttrName); michael@0: michael@0: void michael@0: documentInterfaceInitCB(AtkDocumentIface *aIface) michael@0: { michael@0: NS_ASSERTION(aIface, "Invalid Interface"); michael@0: if(MOZ_UNLIKELY(!aIface)) michael@0: return; michael@0: michael@0: /* michael@0: * We don't support get_document or set_attribute right now. michael@0: * get_document_type is deprecated, we return DocType in michael@0: * get_document_attribute_value and get_document_attributes instead. michael@0: */ michael@0: aIface->get_document_attributes = getDocumentAttributesCB; michael@0: aIface->get_document_attribute_value = getDocumentAttributeValueCB; michael@0: aIface->get_document_locale = getDocumentLocaleCB; michael@0: } michael@0: michael@0: const gchar * michael@0: getDocumentLocaleCB(AtkDocument *aDocument) michael@0: { michael@0: AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aDocument)); michael@0: if (!accWrap) michael@0: return nullptr; michael@0: michael@0: nsAutoString locale; michael@0: accWrap->Language(locale); michael@0: return locale.IsEmpty() ? nullptr : AccessibleWrap::ReturnString(locale); michael@0: } michael@0: michael@0: static inline GSList * michael@0: prependToList(GSList *aList, const char *const aName, const nsAutoString &aValue) michael@0: { michael@0: if (aValue.IsEmpty()) michael@0: return aList; michael@0: michael@0: // libspi will free these michael@0: AtkAttribute *atkAttr = (AtkAttribute *)g_malloc(sizeof(AtkAttribute)); michael@0: atkAttr->name = g_strdup(aName); michael@0: atkAttr->value = g_strdup(NS_ConvertUTF16toUTF8(aValue).get()); michael@0: return g_slist_prepend(aList, atkAttr); michael@0: } michael@0: michael@0: AtkAttributeSet * michael@0: getDocumentAttributesCB(AtkDocument *aDocument) michael@0: { michael@0: AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aDocument)); michael@0: if (!accWrap || !accWrap->IsDoc()) michael@0: return nullptr; michael@0: michael@0: // according to atkobject.h, AtkAttributeSet is a GSList michael@0: GSList* attributes = nullptr; michael@0: DocAccessible* document = accWrap->AsDoc(); michael@0: nsAutoString aURL; michael@0: nsresult rv = document->GetURL(aURL); michael@0: if (NS_SUCCEEDED(rv)) michael@0: attributes = prependToList(attributes, kDocUrlName, aURL); michael@0: michael@0: nsAutoString aW3CDocType; michael@0: rv = document->GetDocType(aW3CDocType); michael@0: if (NS_SUCCEEDED(rv)) michael@0: attributes = prependToList(attributes, kDocTypeName, aW3CDocType); michael@0: michael@0: nsAutoString aMimeType; michael@0: rv = document->GetMimeType(aMimeType); michael@0: if (NS_SUCCEEDED(rv)) michael@0: attributes = prependToList(attributes, kMimeTypeName, aMimeType); michael@0: michael@0: return attributes; michael@0: } michael@0: michael@0: const gchar * michael@0: getDocumentAttributeValueCB(AtkDocument *aDocument, michael@0: const gchar *aAttrName) michael@0: { michael@0: AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aDocument)); michael@0: if (!accWrap || !accWrap->IsDoc()) michael@0: return nullptr; michael@0: michael@0: DocAccessible* document = accWrap->AsDoc(); michael@0: nsresult rv; michael@0: nsAutoString attrValue; michael@0: if (!strcasecmp(aAttrName, kDocTypeName)) michael@0: rv = document->GetDocType(attrValue); michael@0: else if (!strcasecmp(aAttrName, kDocUrlName)) michael@0: rv = document->GetURL(attrValue); michael@0: else if (!strcasecmp(aAttrName, kMimeTypeName)) michael@0: rv = document->GetMimeType(attrValue); michael@0: else michael@0: return nullptr; michael@0: michael@0: NS_ENSURE_SUCCESS(rv, nullptr); michael@0: return attrValue.IsEmpty() ? nullptr : AccessibleWrap::ReturnString(attrValue); michael@0: } michael@0: }