LCOV - code coverage report
Current view: top level - accessible/atk - nsMaiInterfaceText.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 348 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 23 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #include "InterfaceInitFuncs.h"
       8             : #include "mozilla/a11y/PDocAccessible.h"
       9             : #include "Accessible-inl.h"
      10             : #include "HyperTextAccessible-inl.h"
      11             : #include "nsMai.h"
      12             : #include "ProxyAccessible.h"
      13             : 
      14             : #include "nsIAccessibleTypes.h"
      15             : #include "nsIPersistentProperties2.h"
      16             : #include "nsISimpleEnumerator.h"
      17             : 
      18             : #include "mozilla/Likely.h"
      19             : 
      20             : using namespace mozilla;
      21             : using namespace mozilla::a11y;
      22             : 
      23             : static const char* sAtkTextAttrNames[ATK_TEXT_ATTR_LAST_DEFINED];
      24             : 
      25             : void
      26           0 : ConvertTextAttributeToAtkAttribute(const nsACString& aName,
      27             :                                    const nsAString& aValue,
      28             :                                    AtkAttributeSet** aAttributeSet)
      29             : {
      30             :   // Handle attributes where atk has its own name.
      31           0 :   const char* atkName = nullptr;
      32           0 :   nsAutoString atkValue;
      33           0 :   if (aName.EqualsLiteral("color")) {
      34             :     // The format of the atk attribute is r,g,b and the gecko one is
      35             :     // rgb(r, g, b).
      36           0 :     atkValue = Substring(aValue, 4, aValue.Length() - 5);
      37           0 :     atkValue.StripWhitespace();
      38           0 :     atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_FG_COLOR];
      39           0 :   } else if (aName.EqualsLiteral("background-color")) {
      40             :     // The format of the atk attribute is r,g,b and the gecko one is
      41             :     // rgb(r, g, b).
      42           0 :     atkValue = Substring(aValue, 4, aValue.Length() - 5);
      43           0 :     atkValue.StripWhitespace();
      44           0 :     atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_BG_COLOR];
      45           0 :   } else if (aName.EqualsLiteral("font-family")) {
      46           0 :     atkValue = aValue;
      47           0 :     atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_FAMILY_NAME];
      48           0 :   } else if (aName.EqualsLiteral("font-size")) {
      49             :     // ATK wants the number of pixels without px at the end.
      50           0 :     atkValue = StringHead(aValue, aValue.Length() - 2);
      51           0 :     atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_SIZE];
      52           0 :   } else if (aName.EqualsLiteral("font-weight")) {
      53           0 :     atkValue = aValue;
      54           0 :     atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_WEIGHT];
      55           0 :   } else if (aName.EqualsLiteral("invalid")) {
      56           0 :     atkValue = aValue;
      57           0 :     atkName = sAtkTextAttrNames[ATK_TEXT_ATTR_INVALID];
      58             :   }
      59             : 
      60           0 :   if (atkName) {
      61             :     AtkAttribute* objAttr =
      62           0 :       static_cast<AtkAttribute*>(g_malloc(sizeof(AtkAttribute)));
      63           0 :     objAttr->name = g_strdup(atkName);
      64           0 :     objAttr->value = g_strdup(NS_ConvertUTF16toUTF8(atkValue).get());
      65           0 :     *aAttributeSet = g_slist_prepend(*aAttributeSet, objAttr);
      66             :   }
      67           0 : }
      68             : 
      69             : static AtkAttributeSet*
      70           0 : ConvertToAtkTextAttributeSet(nsTArray<Attribute>& aAttributes)
      71             : {
      72           0 :   AtkAttributeSet* objAttributeSet = nullptr;
      73           0 :   for (size_t i = 0; i < aAttributes.Length(); ++i) {
      74           0 :     AtkAttribute* objAttr = (AtkAttribute *)g_malloc(sizeof(AtkAttribute));
      75           0 :     objAttr->name = g_strdup(aAttributes[i].Name().get());
      76           0 :     objAttr->value =
      77           0 :       g_strdup(NS_ConvertUTF16toUTF8(aAttributes[i].Value()).get());
      78           0 :     objAttributeSet = g_slist_prepend(objAttributeSet, objAttr);
      79           0 :     ConvertTextAttributeToAtkAttribute(aAttributes[i].Name(),
      80           0 :                                        aAttributes[i].Value(),
      81           0 :                                        &objAttributeSet);
      82             :   }
      83           0 :   return objAttributeSet;
      84             : }
      85             : 
      86             : static AtkAttributeSet*
      87           0 : ConvertToAtkTextAttributeSet(nsIPersistentProperties* aAttributes)
      88             : {
      89           0 :   if (!aAttributes)
      90           0 :     return nullptr;
      91             : 
      92           0 :   AtkAttributeSet* objAttributeSet = nullptr;
      93           0 :   nsCOMPtr<nsISimpleEnumerator> propEnum;
      94           0 :   nsresult rv = aAttributes->Enumerate(getter_AddRefs(propEnum));
      95           0 :   NS_ENSURE_SUCCESS(rv, nullptr);
      96             : 
      97           0 :   bool hasMore = false;
      98           0 :   while (NS_SUCCEEDED(propEnum->HasMoreElements(&hasMore)) && hasMore) {
      99           0 :     nsCOMPtr<nsISupports> sup;
     100           0 :     rv = propEnum->GetNext(getter_AddRefs(sup));
     101           0 :     NS_ENSURE_SUCCESS(rv, objAttributeSet);
     102             : 
     103           0 :     nsCOMPtr<nsIPropertyElement> propElem(do_QueryInterface(sup));
     104           0 :     NS_ENSURE_TRUE(propElem, objAttributeSet);
     105             : 
     106           0 :     nsAutoCString name;
     107           0 :     rv = propElem->GetKey(name);
     108           0 :     NS_ENSURE_SUCCESS(rv, objAttributeSet);
     109             : 
     110           0 :     nsAutoString value;
     111           0 :     rv = propElem->GetValue(value);
     112           0 :     NS_ENSURE_SUCCESS(rv, objAttributeSet);
     113             : 
     114           0 :     AtkAttribute* objAttr = (AtkAttribute*)g_malloc(sizeof(AtkAttribute));
     115           0 :     objAttr->name = g_strdup(name.get());
     116           0 :     objAttr->value = g_strdup(NS_ConvertUTF16toUTF8(value).get());
     117           0 :     objAttributeSet = g_slist_prepend(objAttributeSet, objAttr);
     118             : 
     119           0 :     ConvertTextAttributeToAtkAttribute(name, value, &objAttributeSet);
     120             :   }
     121             : 
     122             :   // libatk-adaptor will free it
     123           0 :   return objAttributeSet;
     124             : }
     125             : 
     126             : static void
     127           0 : ConvertTexttoAsterisks(AccessibleWrap* accWrap, nsAString& aString)
     128             : {
     129             :   // convert each char to "*" when it's "password text"
     130           0 :   if (accWrap->NativeRole() == roles::PASSWORD_TEXT) {
     131           0 :     for (uint32_t i = 0; i < aString.Length(); i++)
     132           0 :       aString.Replace(i, 1, NS_LITERAL_STRING("*"));
     133             :   }
     134           0 : }
     135             : 
     136             : extern "C" {
     137             : 
     138             : static gchar*
     139           0 : getTextCB(AtkText *aText, gint aStartOffset, gint aEndOffset)
     140             : {
     141           0 :   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
     142           0 :   nsAutoString autoStr;
     143           0 :   if (accWrap) {
     144           0 :     HyperTextAccessible* text = accWrap->AsHyperText();
     145           0 :     if (!text || !text->IsTextRole())
     146           0 :       return nullptr;
     147             : 
     148           0 :     text->TextSubstring(aStartOffset, aEndOffset, autoStr);
     149             : 
     150           0 :     ConvertTexttoAsterisks(accWrap, autoStr);
     151           0 :   } else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
     152           0 :     proxy->TextSubstring(aStartOffset, aEndOffset, autoStr);
     153             :   }
     154             : 
     155           0 :   NS_ConvertUTF16toUTF8 cautoStr(autoStr);
     156             : 
     157             :   //copy and return, libspi will free it.
     158           0 :   return (cautoStr.get()) ? g_strdup(cautoStr.get()) : nullptr;
     159             : }
     160             : 
     161             : static gchar*
     162           0 : getTextAfterOffsetCB(AtkText *aText, gint aOffset,
     163             :                      AtkTextBoundary aBoundaryType,
     164             :                      gint *aStartOffset, gint *aEndOffset)
     165             : {
     166           0 :     nsAutoString autoStr;
     167           0 :   int32_t startOffset = 0, endOffset = 0;
     168           0 :   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
     169           0 :   if (accWrap) {
     170           0 :     HyperTextAccessible* text = accWrap->AsHyperText();
     171           0 :     if (!text || !text->IsTextRole())
     172           0 :       return nullptr;
     173             : 
     174           0 :     text->TextAfterOffset(aOffset, aBoundaryType, &startOffset, &endOffset, autoStr);
     175           0 :     ConvertTexttoAsterisks(accWrap, autoStr);
     176           0 :   } else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
     177           0 :     proxy->GetTextAfterOffset(aOffset, aBoundaryType, autoStr, &startOffset,
     178           0 :                               &endOffset);
     179             :   }
     180             : 
     181           0 :   *aStartOffset = startOffset;
     182           0 :   *aEndOffset = endOffset;
     183             : 
     184           0 :   NS_ConvertUTF16toUTF8 cautoStr(autoStr);
     185           0 :   return (cautoStr.get()) ? g_strdup(cautoStr.get()) : nullptr;
     186             : }
     187             : 
     188             : static gchar*
     189           0 : getTextAtOffsetCB(AtkText *aText, gint aOffset,
     190             :                   AtkTextBoundary aBoundaryType,
     191             :                   gint *aStartOffset, gint *aEndOffset)
     192             : {
     193           0 :   nsAutoString autoStr;
     194           0 :   int32_t startOffset = 0, endOffset = 0;
     195           0 :   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
     196           0 :   if (accWrap) {
     197           0 :     HyperTextAccessible* text = accWrap->AsHyperText();
     198           0 :     if (!text || !text->IsTextRole())
     199           0 :       return nullptr;
     200             : 
     201           0 :     text->TextAtOffset(aOffset, aBoundaryType, &startOffset, &endOffset, autoStr);
     202           0 :     ConvertTexttoAsterisks(accWrap, autoStr);
     203           0 :   } else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
     204           0 :     proxy->GetTextAtOffset(aOffset, aBoundaryType, autoStr, &startOffset,
     205           0 :                            &endOffset);
     206             :   }
     207             : 
     208           0 :   *aStartOffset = startOffset;
     209           0 :   *aEndOffset = endOffset;
     210             : 
     211           0 :   NS_ConvertUTF16toUTF8 cautoStr(autoStr);
     212           0 :   return (cautoStr.get()) ? g_strdup(cautoStr.get()) : nullptr;
     213             : }
     214             : 
     215             : static gunichar
     216           0 : getCharacterAtOffsetCB(AtkText* aText, gint aOffset)
     217             : {
     218           0 :   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
     219           0 :   if (accWrap) {
     220           0 :     HyperTextAccessible* text = accWrap->AsHyperText();
     221           0 :     if (!text || !text->IsTextRole()) {
     222           0 :       return 0;
     223             :     }
     224             : 
     225             :     // char16_t is unsigned short in Mozilla, gnuichar is guint32 in glib.
     226           0 :     return static_cast<gunichar>(text->CharAt(aOffset));
     227             :   }
     228             : 
     229           0 :   if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
     230           0 :     return static_cast<gunichar>(proxy->CharAt(aOffset));
     231             :   }
     232             : 
     233           0 :   return 0;
     234             : }
     235             : 
     236             : static gchar*
     237           0 : getTextBeforeOffsetCB(AtkText *aText, gint aOffset,
     238             :                       AtkTextBoundary aBoundaryType,
     239             :                       gint *aStartOffset, gint *aEndOffset)
     240             : {
     241           0 :   nsAutoString autoStr;
     242           0 :   int32_t startOffset = 0, endOffset = 0;
     243           0 :   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
     244           0 :   if (accWrap) {
     245           0 :     HyperTextAccessible* text = accWrap->AsHyperText();
     246           0 :     if (!text || !text->IsTextRole())
     247           0 :       return nullptr;
     248             : 
     249           0 :     text->TextBeforeOffset(aOffset, aBoundaryType,
     250           0 :                            &startOffset, &endOffset, autoStr);
     251           0 :     ConvertTexttoAsterisks(accWrap, autoStr);
     252           0 :   } else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
     253           0 :     proxy->GetTextBeforeOffset(aOffset, aBoundaryType, autoStr, &startOffset,
     254           0 :                                &endOffset);
     255             :   }
     256             : 
     257           0 :   *aStartOffset = startOffset;
     258           0 :   *aEndOffset = endOffset;
     259             : 
     260           0 :   NS_ConvertUTF16toUTF8 cautoStr(autoStr);
     261           0 :   return (cautoStr.get()) ? g_strdup(cautoStr.get()) : nullptr;
     262             : }
     263             : 
     264             : static gint
     265           0 : getCaretOffsetCB(AtkText *aText)
     266             : {
     267           0 :   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
     268           0 :   if (accWrap) {
     269           0 :     HyperTextAccessible* text = accWrap->AsHyperText();
     270           0 :     if (!text || !text->IsTextRole()) {
     271           0 :       return 0;
     272             :     }
     273             : 
     274           0 :     return static_cast<gint>(text->CaretOffset());
     275             :   }
     276             : 
     277           0 :   if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
     278           0 :     return static_cast<gint>(proxy->CaretOffset());
     279             :   }
     280             : 
     281           0 :   return 0;
     282             : }
     283             : 
     284             : static AtkAttributeSet*
     285           0 : getRunAttributesCB(AtkText *aText, gint aOffset,
     286             :                    gint *aStartOffset,
     287             :                    gint *aEndOffset)
     288             : {
     289           0 :   *aStartOffset = -1;
     290           0 :   *aEndOffset = -1;
     291           0 :   int32_t startOffset = 0, endOffset = 0;
     292             : 
     293           0 :   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
     294           0 :   if (accWrap) {
     295           0 :     HyperTextAccessible* text = accWrap->AsHyperText();
     296           0 :     if (!text || !text->IsTextRole()) {
     297           0 :       return nullptr;
     298             :     }
     299             : 
     300             :     nsCOMPtr<nsIPersistentProperties> attributes =
     301           0 :       text->TextAttributes(false, aOffset, &startOffset, &endOffset);
     302             : 
     303           0 :     *aStartOffset = startOffset;
     304           0 :     *aEndOffset = endOffset;
     305             : 
     306           0 :     return ConvertToAtkTextAttributeSet(attributes);
     307             :   }
     308             : 
     309           0 :   ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText));
     310           0 :   if (!proxy) {
     311           0 :     return nullptr;
     312             :   }
     313             : 
     314           0 :   AutoTArray<Attribute, 10> attrs;
     315           0 :   proxy->TextAttributes(false, aOffset, &attrs, &startOffset, &endOffset);
     316           0 :   *aStartOffset = startOffset;
     317           0 :   *aEndOffset = endOffset;
     318           0 :   return ConvertToAtkTextAttributeSet(attrs);
     319             : }
     320             : 
     321             : static AtkAttributeSet*
     322           0 : getDefaultAttributesCB(AtkText *aText)
     323             : {
     324           0 :   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
     325           0 :   if (accWrap) {
     326           0 :     HyperTextAccessible* text = accWrap->AsHyperText();
     327           0 :     if (!text || !text->IsTextRole()) {
     328           0 :       return nullptr;
     329             :     }
     330             : 
     331           0 :     nsCOMPtr<nsIPersistentProperties> attributes = text->DefaultTextAttributes();
     332           0 :     return ConvertToAtkTextAttributeSet(attributes);
     333             :   }
     334             : 
     335           0 :   ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText));
     336           0 :   if (!proxy) {
     337           0 :     return nullptr;
     338             :   }
     339             : 
     340           0 :   AutoTArray<Attribute, 10> attrs;
     341           0 :   proxy->DefaultTextAttributes(&attrs);
     342           0 :   return ConvertToAtkTextAttributeSet(attrs);
     343             : }
     344             : 
     345             : static void
     346           0 : getCharacterExtentsCB(AtkText *aText, gint aOffset,
     347             :                       gint *aX, gint *aY,
     348             :                       gint *aWidth, gint *aHeight,
     349             :                       AtkCoordType aCoords)
     350             : {
     351           0 :   if(!aX || !aY || !aWidth || !aHeight) {
     352           0 :     return;
     353             :   }
     354             : 
     355           0 :   nsIntRect rect;
     356             :   uint32_t geckoCoordType;
     357           0 :   if (aCoords == ATK_XY_SCREEN) {
     358           0 :     geckoCoordType = nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE;
     359             :   } else {
     360           0 :     geckoCoordType = nsIAccessibleCoordinateType::COORDTYPE_WINDOW_RELATIVE;
     361             :   }
     362             : 
     363           0 :   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
     364           0 :   if (accWrap) {
     365           0 :     HyperTextAccessible* text = accWrap->AsHyperText();
     366           0 :     if (!text || !text->IsTextRole()) {
     367           0 :       return;
     368             :     }
     369             : 
     370           0 :     rect = text->CharBounds(aOffset, geckoCoordType);
     371           0 :   } else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
     372           0 :     rect = proxy->CharBounds(aOffset, geckoCoordType);
     373             :   } else {
     374           0 :     return;
     375             :   }
     376             : 
     377           0 :   *aX = rect.x;
     378           0 :   *aY = rect.y;
     379           0 :   *aWidth = rect.width;
     380           0 :   *aHeight = rect.height;
     381             : }
     382             : 
     383             : static void
     384           0 : getRangeExtentsCB(AtkText *aText, gint aStartOffset, gint aEndOffset,
     385             :                   AtkCoordType aCoords, AtkTextRectangle *aRect)
     386             : {
     387           0 :   if (!aRect) {
     388           0 :     return;
     389             :   }
     390             : 
     391           0 :   nsIntRect rect;
     392             :   uint32_t geckoCoordType;
     393           0 :   if (aCoords == ATK_XY_SCREEN) {
     394           0 :     geckoCoordType = nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE;
     395             :   } else {
     396           0 :     geckoCoordType = nsIAccessibleCoordinateType::COORDTYPE_WINDOW_RELATIVE;
     397             :   }
     398             : 
     399           0 :   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
     400           0 :   if(accWrap) {
     401           0 :     HyperTextAccessible* text = accWrap->AsHyperText();
     402           0 :     if (!text || !text->IsTextRole()) {
     403           0 :       return;
     404             :     }
     405             : 
     406           0 :     rect = text->TextBounds(aStartOffset, aEndOffset, geckoCoordType);
     407           0 :   } else if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
     408           0 :     rect = proxy->TextBounds(aStartOffset, aEndOffset, geckoCoordType);
     409             :   } else {
     410           0 :     return;
     411             :   }
     412             : 
     413           0 :   aRect->x = rect.x;
     414           0 :   aRect->y = rect.y;
     415           0 :   aRect->width = rect.width;
     416           0 :   aRect->height = rect.height;
     417             : }
     418             : 
     419             : static gint
     420           0 : getCharacterCountCB(AtkText *aText)
     421             : {
     422           0 :   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
     423           0 :   if (accWrap) {
     424           0 :     HyperTextAccessible* textAcc = accWrap->AsHyperText();
     425             :     return
     426           0 :       textAcc->IsDefunct() ? 0 : static_cast<gint>(textAcc->CharacterCount());
     427             :   }
     428             : 
     429           0 :   if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
     430           0 :     return proxy->CharacterCount();
     431             :   }
     432             : 
     433           0 :   return 0;
     434             : }
     435             : 
     436             : static gint
     437           0 : getOffsetAtPointCB(AtkText *aText,
     438             :                    gint aX, gint aY,
     439             :                    AtkCoordType aCoords)
     440             : {
     441           0 :   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
     442           0 :   if (accWrap) {
     443           0 :     HyperTextAccessible* text = accWrap->AsHyperText();
     444           0 :     if (!text || !text->IsTextRole()) {
     445           0 :       return -1;
     446             :     }
     447             : 
     448             :     return static_cast<gint>(
     449           0 :       text->OffsetAtPoint(aX, aY,
     450             :                           (aCoords == ATK_XY_SCREEN ?
     451             :                            nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE :
     452           0 :                            nsIAccessibleCoordinateType::COORDTYPE_WINDOW_RELATIVE)));
     453             :   }
     454             : 
     455           0 :   if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
     456             :     return static_cast<gint>(
     457           0 :       proxy->OffsetAtPoint(aX, aY,
     458             :                            (aCoords == ATK_XY_SCREEN ?
     459             :                             nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE :
     460           0 :                             nsIAccessibleCoordinateType::COORDTYPE_WINDOW_RELATIVE)));
     461             :   }
     462             : 
     463           0 :   return -1;
     464             : }
     465             : 
     466             : static gint
     467           0 : getTextSelectionCountCB(AtkText *aText)
     468             : {
     469           0 :   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
     470           0 :   if (accWrap) {
     471           0 :     HyperTextAccessible* text = accWrap->AsHyperText();
     472           0 :     if (!text || !text->IsTextRole()) {
     473           0 :       return 0;
     474             :     }
     475             : 
     476           0 :     return text->SelectionCount();
     477             :   }
     478             : 
     479           0 :   if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
     480           0 :     return proxy->SelectionCount();
     481             :   }
     482             : 
     483           0 :   return 0;
     484             : }
     485             : 
     486             : static gchar*
     487           0 : getTextSelectionCB(AtkText *aText, gint aSelectionNum,
     488             :                    gint *aStartOffset, gint *aEndOffset)
     489             : {
     490           0 :   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
     491           0 :   int32_t startOffset = 0, endOffset = 0;
     492           0 :   if (accWrap) {
     493           0 :     HyperTextAccessible* text = accWrap->AsHyperText();
     494           0 :     if (!text || !text->IsTextRole()) {
     495           0 :       return nullptr;
     496             :     }
     497             : 
     498           0 :     text->SelectionBoundsAt(aSelectionNum, &startOffset, &endOffset);
     499           0 :     *aStartOffset = startOffset;
     500           0 :     *aEndOffset = endOffset;
     501             : 
     502           0 :     return getTextCB(aText, *aStartOffset, *aEndOffset);
     503             :   }
     504           0 :   if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
     505           0 :     nsString data;
     506           0 :     proxy->SelectionBoundsAt(aSelectionNum, data, &startOffset, &endOffset);
     507           0 :     *aStartOffset = startOffset;
     508           0 :     *aEndOffset = endOffset;
     509             : 
     510           0 :     NS_ConvertUTF16toUTF8 dataAsUTF8(data);
     511           0 :     return (dataAsUTF8.get()) ? g_strdup(dataAsUTF8.get()) : nullptr;
     512             :   }
     513           0 :   return nullptr;
     514             : }
     515             : 
     516             : // set methods
     517             : static gboolean
     518           0 : addTextSelectionCB(AtkText *aText,
     519             :                    gint aStartOffset,
     520             :                    gint aEndOffset)
     521             : {
     522           0 :   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
     523           0 :   if (accWrap) {
     524           0 :     HyperTextAccessible* text = accWrap->AsHyperText();
     525           0 :     if (!text || !text->IsTextRole()) {
     526           0 :       return FALSE;
     527             :     }
     528             : 
     529           0 :     return text->AddToSelection(aStartOffset, aEndOffset);
     530             :   }
     531           0 :   if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
     532           0 :     return proxy->AddToSelection(aStartOffset, aEndOffset);
     533             :   }
     534             : 
     535           0 :   return FALSE;
     536             : }
     537             : 
     538             : static gboolean
     539           0 : removeTextSelectionCB(AtkText *aText,
     540             :                       gint aSelectionNum)
     541             : {
     542           0 :   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
     543           0 :   if (accWrap) {
     544           0 :     HyperTextAccessible* text = accWrap->AsHyperText();
     545           0 :     if (!text || !text->IsTextRole()) {
     546           0 :       return FALSE;
     547             :     }
     548             : 
     549           0 :     return text->RemoveFromSelection(aSelectionNum);
     550             :   }
     551           0 :   if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
     552           0 :     return proxy->RemoveFromSelection(aSelectionNum);
     553             :   }
     554             : 
     555           0 :   return FALSE;
     556             : }
     557             : 
     558             : static gboolean
     559           0 : setTextSelectionCB(AtkText *aText, gint aSelectionNum,
     560             :                    gint aStartOffset, gint aEndOffset)
     561             : {
     562           0 :   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
     563           0 :   if (accWrap) {
     564           0 :     HyperTextAccessible* text = accWrap->AsHyperText();
     565           0 :     if (!text || !text->IsTextRole()) {
     566           0 :       return FALSE;
     567             :     }
     568             : 
     569           0 :     return text->SetSelectionBoundsAt(aSelectionNum, aStartOffset, aEndOffset);
     570             :   }
     571           0 :   if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
     572           0 :     return proxy->SetSelectionBoundsAt(aSelectionNum, aStartOffset, aEndOffset);
     573             :   }
     574             : 
     575           0 :   return FALSE;
     576             : }
     577             : 
     578             : static gboolean
     579           0 : setCaretOffsetCB(AtkText *aText, gint aOffset)
     580             : {
     581           0 :   AccessibleWrap* accWrap = GetAccessibleWrap(ATK_OBJECT(aText));
     582           0 :   if (accWrap) {
     583           0 :     HyperTextAccessible* text = accWrap->AsHyperText();
     584           0 :     if (!text || !text->IsTextRole() || !text->IsValidOffset(aOffset)) {
     585           0 :       return FALSE;
     586             :     }
     587             : 
     588           0 :     text->SetCaretOffset(aOffset);
     589           0 :     return TRUE;
     590             :   }
     591             : 
     592           0 :   if (ProxyAccessible* proxy = GetProxy(ATK_OBJECT(aText))) {
     593           0 :     proxy->SetCaretOffset(aOffset);
     594           0 :     return TRUE;
     595             :   }
     596             : 
     597           0 :   return FALSE;
     598             : }
     599             : }
     600             : 
     601             : void
     602           0 : textInterfaceInitCB(AtkTextIface* aIface)
     603             : {
     604           0 :   NS_ASSERTION(aIface, "Invalid aIface");
     605           0 :   if (MOZ_UNLIKELY(!aIface))
     606           0 :     return;
     607             : 
     608           0 :   aIface->get_text = getTextCB;
     609           0 :   aIface->get_text_after_offset = getTextAfterOffsetCB;
     610           0 :   aIface->get_text_at_offset = getTextAtOffsetCB;
     611           0 :   aIface->get_character_at_offset = getCharacterAtOffsetCB;
     612           0 :   aIface->get_text_before_offset = getTextBeforeOffsetCB;
     613           0 :   aIface->get_caret_offset = getCaretOffsetCB;
     614           0 :   aIface->get_run_attributes = getRunAttributesCB;
     615           0 :   aIface->get_default_attributes = getDefaultAttributesCB;
     616           0 :   aIface->get_character_extents = getCharacterExtentsCB;
     617           0 :   aIface->get_range_extents = getRangeExtentsCB;
     618           0 :   aIface->get_character_count = getCharacterCountCB;
     619           0 :   aIface->get_offset_at_point = getOffsetAtPointCB;
     620           0 :   aIface->get_n_selections = getTextSelectionCountCB;
     621           0 :   aIface->get_selection = getTextSelectionCB;
     622             : 
     623             :     // set methods
     624           0 :   aIface->add_selection = addTextSelectionCB;
     625           0 :   aIface->remove_selection = removeTextSelectionCB;
     626           0 :   aIface->set_selection = setTextSelectionCB;
     627           0 :   aIface->set_caret_offset = setCaretOffsetCB;
     628             : 
     629             :   // Cache the string values of the atk text attribute names.
     630           0 :   for (uint32_t i = 0; i < ArrayLength(sAtkTextAttrNames); i++)
     631           0 :     sAtkTextAttrNames[i] =
     632           0 :       atk_text_attribute_get_name(static_cast<AtkTextAttribute>(i));
     633             : }

Generated by: LCOV version 1.13