diff --git a/accessible/atk/AccessibleWrap.cpp b/accessible/atk/AccessibleWrap.cpp index e98be1ef262..bfd213ce5c3 100644 --- a/accessible/atk/AccessibleWrap.cpp +++ b/accessible/atk/AccessibleWrap.cpp @@ -1019,15 +1019,20 @@ GetWrapperFor(ProxyAccessible* aProxy) } static uint16_t -GetInterfacesForProxy(ProxyAccessible* aProxy) +GetInterfacesForProxy(ProxyAccessible* aProxy, uint32_t aInterfaces) { - return MAI_INTERFACE_COMPONENT; + uint16_t interfaces = 1 << MAI_INTERFACE_COMPONENT; + if (aInterfaces & Interfaces::HYPERTEXT) + interfaces |= (1 << MAI_INTERFACE_HYPERTEXT) | (1 << MAI_INTERFACE_TEXT) + | (1 << MAI_INTERFACE_EDITABLE_TEXT); + + return interfaces; } void -a11y::ProxyCreated(ProxyAccessible* aProxy) +a11y::ProxyCreated(ProxyAccessible* aProxy, uint32_t aInterfaces) { - GType type = GetMaiAtkType(GetInterfacesForProxy(aProxy)); + GType type = GetMaiAtkType(GetInterfacesForProxy(aProxy, aInterfaces)); NS_ASSERTION(type, "why don't we have a type!"); AtkObject* obj = diff --git a/accessible/atk/nsMaiInterfaceText.cpp b/accessible/atk/nsMaiInterfaceText.cpp index a8922d49e70..ee3f995018c 100644 --- a/accessible/atk/nsMaiInterfaceText.cpp +++ b/accessible/atk/nsMaiInterfaceText.cpp @@ -9,6 +9,7 @@ #include "Accessible-inl.h" #include "HyperTextAccessible-inl.h" #include "nsMai.h" +#include "ProxyAccessible.h" #include "nsIAccessibleTypes.h" #include "nsIPersistentProperties2.h" @@ -110,21 +111,23 @@ static gchar* getTextCB(AtkText *aText, gint aStartOffset, gint aEndOffset) { AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText)); - if (!accWrap) - return nullptr; + nsAutoString autoStr; + if (accWrap) { + HyperTextAccessible* text = accWrap->AsHyperText(); + if (!text || !text->IsTextRole()) + return nullptr; - HyperTextAccessible* text = accWrap->AsHyperText(); - if (!text || !text->IsTextRole()) - return nullptr; - - nsAutoString autoStr; text->TextSubstring(aStartOffset, aEndOffset, autoStr); ConvertTexttoAsterisks(accWrap, autoStr); - NS_ConvertUTF16toUTF8 cautoStr(autoStr); + } else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) { + proxy->TextSubstring(aStartOffset, aEndOffset, autoStr); + } - //copy and return, libspi will free it. - return (cautoStr.get()) ? g_strdup(cautoStr.get()) : nullptr; + NS_ConvertUTF16toUTF8 cautoStr(autoStr); + + //copy and return, libspi will free it. + return (cautoStr.get()) ? g_strdup(cautoStr.get()) : nullptr; } static gchar* diff --git a/accessible/base/DocManager.cpp b/accessible/base/DocManager.cpp index 8430d1738d2..ae4f233905e 100644 --- a/accessible/base/DocManager.cpp +++ b/accessible/base/DocManager.cpp @@ -549,5 +549,5 @@ DocManager::RemoteDocAdded(DocAccessibleParent* aDoc) MOZ_ASSERT(!sRemoteDocuments->Contains(aDoc), "How did we already have the doc!"); sRemoteDocuments->AppendElement(aDoc); - ProxyCreated(aDoc); + ProxyCreated(aDoc, 0); } diff --git a/accessible/base/Platform.h b/accessible/base/Platform.h index 544a1a6b9f6..b48064f6475 100644 --- a/accessible/base/Platform.h +++ b/accessible/base/Platform.h @@ -55,7 +55,7 @@ void PlatformShutdown(); * called when a new ProxyAccessible is created, so the platform may setup a * wrapper for it, or take other action. */ -void ProxyCreated(ProxyAccessible*); +void ProxyCreated(ProxyAccessible* aProxy, uint32_t aInterfaces); /** * Called just before a ProxyAccessible is destroyed so its wrapper can be diff --git a/accessible/ipc/DocAccessibleChild.cpp b/accessible/ipc/DocAccessibleChild.cpp index 678e021a892..4a371931f62 100644 --- a/accessible/ipc/DocAccessibleChild.cpp +++ b/accessible/ipc/DocAccessibleChild.cpp @@ -7,6 +7,7 @@ #include "DocAccessibleChild.h" #include "Accessible-inl.h" +#include "ProxyAccessible.h" #include "nsIPersistentProperties2.h" #include "nsISimpleEnumerator.h" @@ -14,12 +15,23 @@ namespace mozilla { namespace a11y { -void +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 @@ -27,7 +39,7 @@ SerializeTree(Accessible* aRoot, nsTArray& aTree) if (childCount == 1 && aRoot->GetChildAt(0)->IsDoc()) childCount = 0; - aTree.AppendElement(AccessibleData(id, role, childCount)); + aTree.AppendElement(AccessibleData(id, role, childCount, interfaces)); for (uint32_t i = 0; i < childCount; i++) SerializeTree(aRoot->GetChildAt(i), aTree); } @@ -117,5 +129,19 @@ DocAccessibleChild::RecvAttributes(const uint64_t& aID, nsTArray* aAt 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; +} } } diff --git a/accessible/ipc/DocAccessibleChild.h b/accessible/ipc/DocAccessibleChild.h index 13ccf4cbcb3..4be0d81fccd 100644 --- a/accessible/ipc/DocAccessibleChild.h +++ b/accessible/ipc/DocAccessibleChild.h @@ -49,6 +49,10 @@ public: virtual bool RecvDescription(const uint64_t& aID, nsString* aDesc) MOZ_OVERRIDE; virtual bool RecvAttributes(const uint64_t& aID, nsTArray *aAttributes) MOZ_OVERRIDE; + virtual bool RecvTextSubstring(const uint64_t& aID, + const int32_t& aStartOffset, + const int32_t& aEndOffset, nsString* aText) + MOZ_OVERRIDE; private: DocAccessible* mDoc; diff --git a/accessible/ipc/DocAccessibleParent.cpp b/accessible/ipc/DocAccessibleParent.cpp index 5fc89289394..7e281af5366 100644 --- a/accessible/ipc/DocAccessibleParent.cpp +++ b/accessible/ipc/DocAccessibleParent.cpp @@ -7,6 +7,7 @@ #include "DocAccessibleParent.h" #include "nsAutoPtr.h" #include "mozilla/a11y/Platform.h" +#include "ProxyAccessible.h" namespace mozilla { namespace a11y { @@ -74,7 +75,7 @@ DocAccessibleParent::AddSubtree(ProxyAccessible* aParent, new ProxyAccessible(newChild.ID(), aParent, this, role); aParent->AddChildAt(aIdxInParent, newProxy); mAccessibles.PutEntry(newChild.ID())->mProxy = newProxy; - ProxyCreated(newProxy); + ProxyCreated(newProxy, newChild.Interfaces()); uint32_t accessibles = 1; uint32_t kids = newChild.ChildrenCount(); @@ -142,7 +143,7 @@ DocAccessibleParent::AddChildDoc(DocAccessibleParent* aChildDoc, outerDoc->SetChildDoc(aChildDoc); mChildDocs.AppendElement(aChildDoc); aChildDoc->mParentDoc = this; - ProxyCreated(aChildDoc); + ProxyCreated(aChildDoc, 0); return true; } diff --git a/accessible/ipc/PDocAccessible.ipdl b/accessible/ipc/PDocAccessible.ipdl index 6581d364abb..a40cdaea5f8 100644 --- a/accessible/ipc/PDocAccessible.ipdl +++ b/accessible/ipc/PDocAccessible.ipdl @@ -14,6 +14,7 @@ struct AccessibleData uint64_t ID; uint32_t Role; uint32_t ChildrenCount; + uint32_t Interfaces; }; struct ShowEventData @@ -49,6 +50,8 @@ child: prio(high) sync Name(uint64_t aID) returns(nsString name); prio(high) sync Description(uint64_t aID) returns(nsString desc); prio(high) sync Attributes(uint64_t aID) returns(Attribute[] attributes); +prio(high) sync TextSubstring(uint64_t aID, int32_t aStartOffset, int32_t + aEndOffset) returns(nsString aText); }; } diff --git a/accessible/ipc/ProxyAccessible.cpp b/accessible/ipc/ProxyAccessible.cpp index c07683e5e3f..52dfb071ae4 100644 --- a/accessible/ipc/ProxyAccessible.cpp +++ b/accessible/ipc/ProxyAccessible.cpp @@ -69,5 +69,12 @@ ProxyAccessible::Attributes(nsTArray *aAttrs) const { unused << mDoc->SendAttributes(mID, aAttrs); } + +void +ProxyAccessible::TextSubstring(int32_t aStartOffset, int32_t aEndOfset, + nsString& aText) const +{ + unused << mDoc->SendTextSubstring(mID, aStartOffset, aEndOfset, &aText); +} } } diff --git a/accessible/ipc/ProxyAccessible.h b/accessible/ipc/ProxyAccessible.h index f66839197bb..e8301d4aaa3 100644 --- a/accessible/ipc/ProxyAccessible.h +++ b/accessible/ipc/ProxyAccessible.h @@ -79,6 +79,12 @@ public: */ void Attributes(nsTArray *aAttrs) const; + /** + * Get the text between the given offsets. + */ + void TextSubstring(int32_t aStartOffset, int32_t aEndOfset, + nsString& aText) const; + /** * Allow the platform to store a pointers worth of data on us. */ @@ -108,6 +114,11 @@ private: bool mOuterDoc : 1; }; +enum Interfaces +{ + HYPERTEXT = 1 +}; + } } diff --git a/accessible/mac/Platform.mm b/accessible/mac/Platform.mm index 02c146571b5..a80b001c9e9 100644 --- a/accessible/mac/Platform.mm +++ b/accessible/mac/Platform.mm @@ -34,7 +34,7 @@ PlatformShutdown() } void -ProxyCreated(ProxyAccessible*) +ProxyCreated(ProxyAccessible*, uint32_t) { } diff --git a/accessible/other/Platform.cpp b/accessible/other/Platform.cpp index fa202d8ff12..526c50e84ef 100644 --- a/accessible/other/Platform.cpp +++ b/accessible/other/Platform.cpp @@ -20,7 +20,7 @@ a11y::PlatformShutdown() } void -a11y::ProxyCreated(ProxyAccessible*) +a11y::ProxyCreated(ProxyAccessible*, uint32_t) { } diff --git a/accessible/windows/msaa/Platform.cpp b/accessible/windows/msaa/Platform.cpp index dad8a08b6ff..039a5c7adfa 100644 --- a/accessible/windows/msaa/Platform.cpp +++ b/accessible/windows/msaa/Platform.cpp @@ -35,7 +35,7 @@ a11y::PlatformShutdown() } void -a11y::ProxyCreated(ProxyAccessible*) +a11y::ProxyCreated(ProxyAccessible*, uint32_t) { }