/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=2 et sw=2 tw=80: */ /* 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 "DocAccessibleChild.h" #include "Accessible-inl.h" #include "ProxyAccessible.h" #include "nsIPersistentProperties2.h" #include "nsISimpleEnumerator.h" namespace mozilla { namespace a11y { static uint32_t InterfacesFor(Accessible* aAcc) { uint32_t interfaces = 0; if (aAcc->IsHyperText() && aAcc->AsHyperText()->IsTextRole()) interfaces |= Interfaces::HYPERTEXT; return interfaces; } static void SerializeTree(Accessible* aRoot, nsTArray& aTree) { uint64_t id = reinterpret_cast(aRoot->UniqueID()); uint32_t role = aRoot->Role(); uint32_t childCount = aRoot->ChildCount(); uint32_t interfaces = InterfacesFor(aRoot); // OuterDocAccessibles are special because we don't want to serialize the // child doc here, we'll call PDocAccessibleConstructor in // NotificationController. if (childCount == 1 && aRoot->GetChildAt(0)->IsDoc()) childCount = 0; aTree.AppendElement(AccessibleData(id, role, childCount, interfaces)); for (uint32_t i = 0; i < childCount; i++) SerializeTree(aRoot->GetChildAt(i), aTree); } void DocAccessibleChild::ShowEvent(AccShowEvent* aShowEvent) { Accessible* parent = aShowEvent->Parent(); uint64_t parentID = parent->IsDoc() ? 0 : reinterpret_cast(parent->UniqueID()); uint32_t idxInParent = aShowEvent->GetAccessible()->IndexInParent(); nsTArray shownTree; ShowEventData data(parentID, idxInParent, shownTree); SerializeTree(aShowEvent->GetAccessible(), data.NewTree()); SendShowEvent(data); } bool DocAccessibleChild::RecvState(const uint64_t& aID, uint64_t* aState) { Accessible* acc = mDoc->GetAccessibleByUniqueID((void*)aID); if (!acc) { *aState = states::DEFUNCT; return true; } *aState = acc->State(); return true; } bool DocAccessibleChild::RecvName(const uint64_t& aID, nsString* aName) { Accessible* acc = mDoc->GetAccessibleByUniqueID((void*)aID); if (!acc) return true; acc->Name(*aName); return true; } bool DocAccessibleChild::RecvDescription(const uint64_t& aID, nsString* aDesc) { Accessible* acc = mDoc->GetAccessibleByUniqueID((void*)aID); if (!acc) return true; acc->Description(*aDesc); return true; } bool DocAccessibleChild::RecvAttributes(const uint64_t& aID, nsTArray* aAttributes) { Accessible* acc = mDoc->GetAccessibleByUniqueID((void*)aID); if (!acc) return true; nsCOMPtr props = acc->Attributes(); if (!props) return true; nsCOMPtr propEnum; nsresult rv = props->Enumerate(getter_AddRefs(propEnum)); NS_ENSURE_SUCCESS(rv, false); bool hasMore; while (NS_SUCCEEDED(propEnum->HasMoreElements(&hasMore)) && hasMore) { nsCOMPtr sup; rv = propEnum->GetNext(getter_AddRefs(sup)); NS_ENSURE_SUCCESS(rv, false); nsCOMPtr propElem(do_QueryInterface(sup)); NS_ENSURE_TRUE(propElem, false); nsAutoCString name; rv = propElem->GetKey(name); NS_ENSURE_SUCCESS(rv, false); nsAutoString value; rv = propElem->GetValue(value); NS_ENSURE_SUCCESS(rv, false); aAttributes->AppendElement(Attribute(name, value)); } return true; } bool DocAccessibleChild::RecvTextSubstring(const uint64_t& aID, const int32_t& aStartOffset, const int32_t& aEndOffset, nsString* aText) { Accessible* acc = mDoc->GetAccessibleByUniqueID((void*)aID); if (!acc || !acc->IsHyperText()) return false; acc->AsHyperText()->TextSubstring(aStartOffset, aEndOffset, *aText); return true; } } }