Bug 1140162 - IPC Proxy for TextAttributes and DefaultTextAttributes, r=tbsaunde
authorOlli Pettay <Olli.Pettay@helsinki.fi>
Fri, 06 Mar 2015 22:44:02 +0200
changeset 232420 7fa300ea1b1d88a7bdd1be8f26efa732c1beff25
parent 232419 2d66bec2f5e1f4fc6cde2bb9bc6a6b53f638786e
child 232421 803e783be389469c19faf2b303318ea73111e863
push id56553
push useropettay@mozilla.com
push dateSun, 08 Mar 2015 01:29:33 +0000
treeherdermozilla-inbound@7fa300ea1b1d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstbsaunde
bugs1140162
milestone39.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1140162 - IPC Proxy for TextAttributes and DefaultTextAttributes, r=tbsaunde
accessible/atk/nsMaiInterfaceText.cpp
accessible/ipc/DocAccessibleChild.cpp
accessible/ipc/DocAccessibleChild.h
accessible/ipc/PDocAccessible.ipdl
accessible/ipc/ProxyAccessible.cpp
accessible/ipc/ProxyAccessible.h
--- a/accessible/atk/nsMaiInterfaceText.cpp
+++ b/accessible/atk/nsMaiInterfaceText.cpp
@@ -1,32 +1,91 @@
 /* -*- 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 "InterfaceInitFuncs.h"
-
+#include "mozilla/a11y/PDocAccessible.h"
 #include "Accessible-inl.h"
 #include "HyperTextAccessible-inl.h"
 #include "nsMai.h"
 #include "ProxyAccessible.h"
 
 #include "nsIAccessibleTypes.h"
 #include "nsIPersistentProperties2.h"
 #include "nsISimpleEnumerator.h"
 
 #include "mozilla/Likely.h"
 
 using namespace mozilla;
 using namespace mozilla::a11y;
 
 static const char* sAtkTextAttrNames[ATK_TEXT_ATTR_LAST_DEFINED];
 
+void
+ConvertTextAttributeToAtkAttribute(const nsACString& aName,
+                                   const nsAString& aValue,
+                                   AtkAttributeSet** aAttributeSet)
+{
+  // Handle attributes where atk has its own name.
+  const char* atkName = nullptr;
+  nsAutoString atkValue;
+  if (aName.EqualsLiteral("color")) {
+    // The format of the atk attribute is r,g,b and the gecko one is
+    // rgb(r,g,b).
+    atkValue = Substring(aValue, 5, aValue.Length() - 1);
+    atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_FG_COLOR];
+  } else if (aName.EqualsLiteral("background-color")) {
+    // The format of the atk attribute is r,g,b and the gecko one is
+    // rgb(r,g,b).
+    atkValue = Substring(aValue, 5, aValue.Length() - 1);
+    atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_BG_COLOR];
+  } else if (aName.EqualsLiteral("font-family")) {
+    atkValue = aValue;
+    atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_FAMILY_NAME];
+  } else if (aName.EqualsLiteral("font-size")) {
+    // ATK wants the number of pixels without px at the end.
+    atkValue = StringHead(aValue, aValue.Length() - 2);
+    atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_SIZE];
+  } else if (aName.EqualsLiteral("font-weight")) {
+    atkValue = aValue;
+    atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_WEIGHT];
+  } else if (aName.EqualsLiteral("invalid")) {
+    atkValue = aValue;
+    atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_INVALID];
+  }
+
+  if (atkName) {
+    AtkAttribute* objAttr =
+      static_cast<AtkAttribute*>(g_malloc(sizeof(AtkAttribute)));
+    objAttr->name = g_strdup(atkName);
+    objAttr->value = g_strdup(NS_ConvertUTF16toUTF8(atkValue).get());
+    *aAttributeSet = g_slist_prepend(*aAttributeSet, objAttr);
+  }
+}
+
+static AtkAttributeSet*
+ConvertToAtkTextAttributeSet(nsTArray<Attribute>& aAttributes)
+{
+  AtkAttributeSet* objAttributeSet = nullptr;
+  for (size_t i = 0; i < aAttributes.Length(); ++i) {
+    AtkAttribute* objAttr = (AtkAttribute *)g_malloc(sizeof(AtkAttribute));
+    objAttr->name = g_strdup(aAttributes[i].Name().get());
+    objAttr->value =
+      g_strdup(NS_ConvertUTF16toUTF8(aAttributes[i].Value()).get());
+    objAttributeSet = g_slist_prepend(objAttributeSet, objAttr);
+    ConvertTextAttributeToAtkAttribute(aAttributes[i].Name(),
+                                       aAttributes[i].Value(),
+                                       &objAttributeSet);
+  }
+  return objAttributeSet;
+}
+
 static AtkAttributeSet*
 ConvertToAtkTextAttributeSet(nsIPersistentProperties* aAttributes)
 {
   if (!aAttributes)
     return nullptr;
 
   AtkAttributeSet* objAttributeSet = nullptr;
   nsCOMPtr<nsISimpleEnumerator> propEnum;
@@ -50,50 +109,17 @@ ConvertToAtkTextAttributeSet(nsIPersiste
     rv = propElem->GetValue(value);
     NS_ENSURE_SUCCESS(rv, objAttributeSet);
 
     AtkAttribute* objAttr = (AtkAttribute*)g_malloc(sizeof(AtkAttribute));
     objAttr->name = g_strdup(name.get());
     objAttr->value = g_strdup(NS_ConvertUTF16toUTF8(value).get());
     objAttributeSet = g_slist_prepend(objAttributeSet, objAttr);
 
-    // Handle attributes where atk has its own name.
-    const char* atkName = nullptr;
-    nsAutoString atkValue;
-    if (name.EqualsLiteral("color")) {
-      // The format of the atk attribute is r,g,b and the gecko one is
-      // rgb(r,g,b).
-      atkValue = Substring(value, 5, value.Length() - 1);
-      atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_FG_COLOR];
-    } else if (name.EqualsLiteral("background-color")) {
-      // The format of the atk attribute is r,g,b and the gecko one is
-      // rgb(r,g,b).
-      atkValue = Substring(value, 5, value.Length() - 1);
-      atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_BG_COLOR];
-    } else if (name.EqualsLiteral("font-family")) {
-      atkValue = value;
-      atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_FAMILY_NAME];
-    } else if (name.EqualsLiteral("font-size")) {
-      // ATK wants the number of pixels without px at the end.
-      atkValue = StringHead(value, value.Length() - 2);
-      atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_SIZE];
-    } else if (name.EqualsLiteral("font-weight")) {
-      atkValue = value;
-      atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_WEIGHT];
-    } else if (name.EqualsLiteral("invalid")) {
-      atkValue = value;
-      atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_INVALID];
-    }
-
-    if (atkName) {
-      objAttr = static_cast<AtkAttribute*>(g_malloc(sizeof(AtkAttribute)));
-      objAttr->name = g_strdup(atkName);
-      objAttr->value = g_strdup(NS_ConvertUTF16toUTF8(atkValue).get());
-      objAttributeSet = g_slist_prepend(objAttributeSet, objAttr);
-    }
+    ConvertTextAttributeToAtkAttribute(name, value, &objAttributeSet);
   }
 
   // libatk-adaptor will free it
   return objAttributeSet;
 }
 
 static void
 ConvertTexttoAsterisks(AccessibleWrap* accWrap, nsAString& aString)
@@ -247,48 +273,68 @@ getCaretOffsetCB(AtkText *aText)
 
 static AtkAttributeSet*
 getRunAttributesCB(AtkText *aText, gint aOffset,
                    gint *aStartOffset,
                    gint *aEndOffset)
 {
   *aStartOffset = -1;
   *aEndOffset = -1;
+  int32_t startOffset = 0, endOffset = 0;
 
   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
-  if (!accWrap)
-    return nullptr;
+  if (accWrap) {
+    HyperTextAccessible* text = accWrap->AsHyperText();
+    if (!text || !text->IsTextRole()) {
+      return nullptr;
+    }
+
+    nsCOMPtr<nsIPersistentProperties> attributes =
+      text->TextAttributes(false, aOffset, &startOffset, &endOffset);
 
-  HyperTextAccessible* text = accWrap->AsHyperText();
-  if (!text || !text->IsTextRole())
+    *aStartOffset = startOffset;
+    *aEndOffset = endOffset;
+
+    return ConvertToAtkTextAttributeSet(attributes);
+  }
+
+  ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText));
+  if (!proxy) {
     return nullptr;
+  }
 
-  int32_t startOffset = 0, endOffset = 0;
-  nsCOMPtr<nsIPersistentProperties> attributes =
-    text->TextAttributes(false, aOffset, &startOffset, &endOffset);
-
+  nsAutoTArray<Attribute, 10> attrs;
+  proxy->TextAttributes(false, aOffset, &attrs, &startOffset, &endOffset);
   *aStartOffset = startOffset;
   *aEndOffset = endOffset;
-
-  return ConvertToAtkTextAttributeSet(attributes);
+  return ConvertToAtkTextAttributeSet(attrs);
 }
 
 static AtkAttributeSet*
 getDefaultAttributesCB(AtkText *aText)
 {
   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
-  if (!accWrap)
-    return nullptr;
+  if (accWrap) {
+    HyperTextAccessible* text = accWrap->AsHyperText();
+    if (!text || !text->IsTextRole()) {
+      return nullptr;
+    }
 
-  HyperTextAccessible* text = accWrap->AsHyperText();
-  if (!text || !text->IsTextRole())
+    nsCOMPtr<nsIPersistentProperties> attributes = text->DefaultTextAttributes();
+    return ConvertToAtkTextAttributeSet(attributes);
+  }
+
+  ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText));
+  if (!proxy) {
     return nullptr;
+  }
 
-  nsCOMPtr<nsIPersistentProperties> attributes = text->DefaultTextAttributes();
-  return ConvertToAtkTextAttributeSet(attributes);
+  nsAutoTArray<Attribute, 10> attrs;
+  proxy->DefaultTextAttributes(&attrs);
+  return ConvertToAtkTextAttributeSet(attrs);
 }
 
 static void
 getCharacterExtentsCB(AtkText *aText, gint aOffset,
                       gint *aX, gint *aY,
                       gint *aWidth, gint *aHeight,
                       AtkCoordType aCoords)
 {
--- a/accessible/ipc/DocAccessibleChild.cpp
+++ b/accessible/ipc/DocAccessibleChild.cpp
@@ -122,21 +122,28 @@ DocAccessibleChild::RecvDescription(cons
 bool
 DocAccessibleChild::RecvAttributes(const uint64_t& aID, nsTArray<Attribute>* aAttributes)
 {
   Accessible* acc = IdToAccessible(aID);
   if (!acc)
     return true;
 
   nsCOMPtr<nsIPersistentProperties> props = acc->Attributes();
-  if (!props)
-    return true;
+  return PersistentPropertiesToArray(props, aAttributes);
+}
 
+bool
+DocAccessibleChild::PersistentPropertiesToArray(nsIPersistentProperties* aProps,
+                                                nsTArray<Attribute>* aAttributes)
+{
+  if (!aProps) {
+    return true;
+  }
   nsCOMPtr<nsISimpleEnumerator> propEnum;
-  nsresult rv = props->Enumerate(getter_AddRefs(propEnum));
+  nsresult rv = aProps->Enumerate(getter_AddRefs(propEnum));
   NS_ENSURE_SUCCESS(rv, false);
 
   bool hasMore;
   while (NS_SUCCEEDED(propEnum->HasMoreElements(&hasMore)) && hasMore) {
     nsCOMPtr<nsISupports> sup;
     rv = propEnum->GetNext(getter_AddRefs(sup));
     NS_ENSURE_SUCCESS(rv, false);
 
@@ -320,10 +327,41 @@ DocAccessibleChild::RecvCharAt(const uin
                                uint16_t* aChar)
 {
   HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
   *aChar = acc && acc->IsTextRole() ?
     static_cast<uint16_t>(acc->CharAt(aOffset)) : 0;
   return true;
 }
 
+bool
+DocAccessibleChild::RecvTextAttributes(const uint64_t& aID,
+                                       const bool& aIncludeDefAttrs,
+                                       const int32_t& aOffset,
+                                       nsTArray<Attribute>* aAttributes,
+                                       int32_t* aStartOffset,
+                                       int32_t* aEndOffset)
+{
+  HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
+  if (!acc || !acc->IsTextRole()) {
+    return true;
+  }
+
+  nsCOMPtr<nsIPersistentProperties> props =
+    acc->TextAttributes(aIncludeDefAttrs, aOffset, aStartOffset, aEndOffset);
+  return PersistentPropertiesToArray(props, aAttributes);
+}
+
+bool
+DocAccessibleChild::RecvDefaultTextAttributes(const uint64_t& aID,
+                                              nsTArray<Attribute> *aAttributes)
+{
+  HyperTextAccessible* acc = IdToHyperTextAccessible(aID);
+  if (!acc || !acc->IsTextRole()) {
+    return true;
+  }
+
+  nsCOMPtr<nsIPersistentProperties> props = acc->DefaultTextAttributes();
+  return PersistentPropertiesToArray(props, aAttributes);
+}
+
 }
 }
--- a/accessible/ipc/DocAccessibleChild.h
+++ b/accessible/ipc/DocAccessibleChild.h
@@ -94,16 +94,31 @@ public:
                                        const int32_t& aBoundaryType,
                                        nsString* aText, int32_t* aStartOffset,
                                        int32_t* aEndOffset) MOZ_OVERRIDE;
 
   virtual bool RecvCharAt(const uint64_t& aID,
                           const int32_t& aOffset,
                           uint16_t* aChar) MOZ_OVERRIDE;
 
+  virtual bool RecvTextAttributes(const uint64_t& aID,
+                                  const bool& aIncludeDefAttrs,
+                                  const int32_t& aOffset,
+                                  nsTArray<Attribute>* aAttributes,
+                                  int32_t* aStartOffset,
+                                  int32_t* aEndOffset)
+    MOZ_OVERRIDE;
+
+  virtual bool RecvDefaultTextAttributes(const uint64_t& aID,
+                                         nsTArray<Attribute>* aAttributes)
+    MOZ_OVERRIDE;
+
 private:
+  bool PersistentPropertiesToArray(nsIPersistentProperties* aProps,
+                                   nsTArray<Attribute>* aAttributes);
+
   DocAccessible* mDoc;
 };
 
 }
 }
 
 #endif
--- a/accessible/ipc/PDocAccessible.ipdl
+++ b/accessible/ipc/PDocAccessible.ipdl
@@ -70,15 +70,20 @@ child:
   prio(high) sync CharacterCount(uint64_t aID) returns(int32_t aCount);
   prio(high) sync SelectionCount(uint64_t aID) returns(int32_t aCount);
   prio(high) sync TextSubstring(uint64_t aID, int32_t aStartOffset, int32_t
                                 aEndOffset) returns(nsString aText);
   prio(high) sync GetTextAfterOffset(uint64_t aID, int32_t aOffset, int32_t aBoundaryType)
     returns(nsString aText, int32_t aStartOffset, int32_t aEndOffset);
   prio(high) sync GetTextAtOffset(uint64_t aID, int32_t aOffset, int32_t aBoundaryType)
     returns(nsString aText, int32_t aStartOffset, int32_t aEndOffset);
+
   prio(high) sync GetTextBeforeOffset(uint64_t aID, int32_t aOffset, int32_t aBoundaryType)
     returns(nsString aText, int32_t aStartOffset, int32_t aEndOffset);
   prio(high) sync CharAt(uint64_t aID, int32_t aOffset) returns(uint16_t aChar);
+
+  prio(high) sync TextAttributes(uint64_t aID, bool aIncludeDefAttrs, int32_t aOffset)
+    returns(Attribute[] aAttributes, int32_t aStartOffset, int32_t aEndOffset);
+  prio(high) sync DefaultTextAttributes(uint64_t aID) returns(Attribute[] aAttributes);
 };
 
 }
 }
--- a/accessible/ipc/ProxyAccessible.cpp
+++ b/accessible/ipc/ProxyAccessible.cpp
@@ -221,10 +221,27 @@ ProxyAccessible::GetTextBeforeOffset(int
 char16_t
 ProxyAccessible::CharAt(int32_t aOffset)
 {
   uint16_t retval = 0;
   unused << mDoc->SendCharAt(mID, aOffset, &retval);
   return static_cast<char16_t>(retval);
 }
 
+void
+ProxyAccessible::TextAttributes(bool aIncludeDefAttrs,
+                                int32_t aOffset,
+                                nsTArray<Attribute>* aAttributes,
+                                int32_t* aStartOffset,
+                                int32_t* aEndOffset)
+{
+  unused << mDoc->SendTextAttributes(mID, aIncludeDefAttrs, aOffset,
+                                     aAttributes, aStartOffset, aEndOffset);
+}
+
+void
+ProxyAccessible::DefaultTextAttributes(nsTArray<Attribute>* aAttrs)
+{
+  unused << mDoc->SendDefaultTextAttributes(mID, aAttrs);
+}
+
 }
 }
--- a/accessible/ipc/ProxyAccessible.h
+++ b/accessible/ipc/ProxyAccessible.h
@@ -120,16 +120,23 @@ public:
                        int32_t* aEndOffset);
 
   void GetTextBeforeOffset(int32_t aOffset, AccessibleTextBoundary aBoundaryType,
                            nsString& aText, int32_t* aStartOffset,
                            int32_t* aEndOffset);
 
   char16_t CharAt(int32_t aOffset);
 
+  void TextAttributes(bool aIncludeDefAttrs,
+                      const int32_t aOffset,
+                      nsTArray<Attribute>* aAttributes,
+                      int32_t* aStartOffset,
+                      int32_t* aEndOffset);
+  void DefaultTextAttributes(nsTArray<Attribute>* aAttrs);
+
   /**
    * Allow the platform to store a pointers worth of data on us.
    */
   uintptr_t GetWrapper() const { return mWrapper; }
   void SetWrapper(uintptr_t aWrapper) { mWrapper = aWrapper; }
 
   /*
    * Return the ID of the accessible being proxied.