LCOV - code coverage report
Current view: directory - accessible/src/base - nsAccessiblePivot.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 245 2 0.8 %
Date: 2012-06-02 Functions: 31 2 6.5 %

       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                 : /* ***** BEGIN LICENSE BLOCK *****
       4                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       5                 :  *
       6                 :  * The contents of this file are subject to the Mozilla Public License Version
       7                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       8                 :  * the License. You may obtain a copy of the License at
       9                 :  * http://www.mozilla.org/MPL/
      10                 :  *
      11                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      12                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      13                 :  * for the specific language governing rights and limitations under the
      14                 :  * License.
      15                 :  *
      16                 :  * The Original Code is mozilla.org code.
      17                 :  *
      18                 :  * The Initial Developer of the Original Code is
      19                 :  * Mozilla Foundation.
      20                 :  * Portions created by the Initial Developer are Copyright (C) 2011
      21                 :  * the Initial Developer. All Rights Reserved.
      22                 :  *
      23                 :  * Contributor(s):
      24                 :  *   Eitan Isaacson <eitan@monotonous.org> (original author)
      25                 :  *
      26                 :  * Alternatively, the contents of this file may be used under the terms of
      27                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
      28                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      29                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      30                 :  * of those above. If you wish to allow use of your version of this file only
      31                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      32                 :  * use your version of this file under the terms of the MPL, indicate your
      33                 :  * decision by deleting the provisions above and replace them with the notice
      34                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      35                 :  * the provisions above, a recipient may use your version of this file under
      36                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      37                 :  *
      38                 :  * ***** END LICENSE BLOCK ***** */
      39                 : 
      40                 : #include "nsAccessiblePivot.h"
      41                 : 
      42                 : #include "nsAccessible.h"
      43                 : #include "nsAccUtils.h"
      44                 : #include "nsHyperTextAccessible.h"
      45                 : #include "States.h"
      46                 : 
      47                 : #include "nsArrayUtils.h"
      48                 : #include "nsComponentManagerUtils.h"
      49                 : #include "nsISupportsPrimitives.h"
      50                 : 
      51                 : using namespace mozilla::a11y;
      52                 : 
      53                 : 
      54                 : /**
      55                 :  * An object that stores a given traversal rule during 
      56                 :  */
      57                 : class RuleCache
      58                 : {
      59                 : public:
      60               0 :   RuleCache(nsIAccessibleTraversalRule* aRule) : mRule(aRule),
      61               0 :                                                  mAcceptRoles(nsnull) { }
      62               0 :   ~RuleCache () {
      63               0 :     if (mAcceptRoles)
      64               0 :       nsMemory::Free(mAcceptRoles);
      65               0 :   }
      66                 : 
      67                 :   nsresult ApplyFilter(nsAccessible* aAccessible, PRUint16* aResult);
      68                 : 
      69                 : private:
      70                 :   nsCOMPtr<nsIAccessibleTraversalRule> mRule;
      71                 :   PRUint32* mAcceptRoles;
      72                 :   PRUint32 mAcceptRolesLength;
      73                 :   PRUint32 mPreFilter;
      74                 : };
      75                 : 
      76                 : ////////////////////////////////////////////////////////////////////////////////
      77                 : // nsAccessiblePivot
      78                 : 
      79               0 : nsAccessiblePivot::nsAccessiblePivot(nsAccessible* aRoot) :
      80                 :   mRoot(aRoot), mPosition(nsnull),
      81               0 :   mStartOffset(-1), mEndOffset(-1)
      82                 : {
      83               0 :   NS_ASSERTION(aRoot, "A root accessible is required");
      84               0 : }
      85                 : 
      86                 : ////////////////////////////////////////////////////////////////////////////////
      87                 : // nsISupports
      88                 : 
      89            1464 : NS_IMPL_CYCLE_COLLECTION_CLASS(nsAccessiblePivot)
      90                 : 
      91               0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsAccessiblePivot)
      92               0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mRoot, nsIAccessible)
      93               0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mPosition, nsIAccessible)
      94               0 :   PRUint32 i, length = tmp->mObservers.Length();                               \
      95               0 :   for (i = 0; i < length; ++i) {
      96               0 :     cb.NoteXPCOMChild(tmp->mObservers.ElementAt(i).get());
      97                 :   }
      98               0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
      99                 : 
     100               0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsAccessiblePivot)
     101               0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mRoot)
     102               0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mPosition)
     103               0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSTARRAY(mObservers)
     104               0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
     105                 : 
     106               0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsAccessiblePivot)
     107               0 :   NS_INTERFACE_MAP_ENTRY(nsIAccessiblePivot)
     108               0 :   NS_INTERFACE_MAP_ENTRY(nsAccessiblePivot)
     109               0 :   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIAccessiblePivot)
     110               0 : NS_INTERFACE_MAP_END
     111                 : 
     112               0 : NS_IMPL_CYCLE_COLLECTING_ADDREF(nsAccessiblePivot)
     113               0 : NS_IMPL_CYCLE_COLLECTING_RELEASE(nsAccessiblePivot)
     114                 : 
     115                 : ////////////////////////////////////////////////////////////////////////////////
     116                 : // nsIAccessiblePivot
     117                 : 
     118                 : NS_IMETHODIMP
     119               0 : nsAccessiblePivot::GetRoot(nsIAccessible** aRoot)
     120                 : {
     121               0 :   NS_ENSURE_ARG_POINTER(aRoot);
     122                 : 
     123               0 :   NS_IF_ADDREF(*aRoot = mRoot);
     124                 : 
     125               0 :   return NS_OK;
     126                 : }
     127                 : 
     128                 : NS_IMETHODIMP
     129               0 : nsAccessiblePivot::GetPosition(nsIAccessible** aPosition)
     130                 : {
     131               0 :   NS_ENSURE_ARG_POINTER(aPosition);
     132                 : 
     133               0 :   NS_IF_ADDREF(*aPosition = mPosition);
     134                 : 
     135               0 :   return NS_OK;
     136                 : }
     137                 : 
     138                 : NS_IMETHODIMP
     139               0 : nsAccessiblePivot::SetPosition(nsIAccessible* aPosition)
     140                 : {
     141               0 :   nsRefPtr<nsAccessible> secondPosition;
     142                 : 
     143               0 :   if (aPosition) {
     144               0 :     secondPosition = do_QueryObject(aPosition);
     145               0 :     if (!secondPosition || !IsRootDescendant(secondPosition))
     146               0 :       return NS_ERROR_INVALID_ARG;
     147                 :   }
     148                 : 
     149                 :   // Swap old position with new position, saves us an AddRef/Release.
     150               0 :   mPosition.swap(secondPosition);
     151               0 :   PRInt32 oldStart = mStartOffset, oldEnd = mEndOffset;
     152               0 :   mStartOffset = mEndOffset = -1;
     153               0 :   NotifyPivotChanged(secondPosition, oldStart, oldEnd);
     154                 : 
     155               0 :   return NS_OK;
     156                 : }
     157                 : 
     158                 : NS_IMETHODIMP
     159               0 : nsAccessiblePivot::GetStartOffset(PRInt32* aStartOffset)
     160                 : {
     161               0 :   NS_ENSURE_ARG_POINTER(aStartOffset);
     162                 : 
     163               0 :   *aStartOffset = mStartOffset;
     164                 : 
     165               0 :   return NS_OK;
     166                 : }
     167                 : 
     168                 : NS_IMETHODIMP
     169               0 : nsAccessiblePivot::GetEndOffset(PRInt32* aEndOffset)
     170                 : {
     171               0 :   NS_ENSURE_ARG_POINTER(aEndOffset);
     172                 : 
     173               0 :   *aEndOffset = mEndOffset;
     174                 : 
     175               0 :   return NS_OK;
     176                 : }
     177                 : 
     178                 : NS_IMETHODIMP
     179               0 : nsAccessiblePivot::SetTextRange(nsIAccessibleText* aTextAccessible,
     180                 :                                 PRInt32 aStartOffset, PRInt32 aEndOffset)
     181                 : {
     182               0 :   NS_ENSURE_ARG(aTextAccessible);
     183                 : 
     184                 :   // Check that start offset is smaller than end offset, and that if a value is
     185                 :   // smaller than 0, both should be -1.
     186               0 :   NS_ENSURE_TRUE(aStartOffset <= aEndOffset &&
     187                 :                  (aStartOffset >= 0 || (aStartOffset != -1 && aEndOffset != -1)),
     188                 :                  NS_ERROR_INVALID_ARG);
     189                 : 
     190               0 :   nsRefPtr<nsHyperTextAccessible> newPosition = do_QueryObject(aTextAccessible);
     191               0 :   if (!newPosition || !IsRootDescendant(newPosition))
     192               0 :     return NS_ERROR_INVALID_ARG;
     193                 : 
     194                 :   // Make sure the given offsets don't exceed the character count.
     195               0 :   PRInt32 charCount = newPosition->CharacterCount();
     196                 : 
     197               0 :   if (aEndOffset > charCount)
     198               0 :     return NS_ERROR_FAILURE;
     199                 : 
     200               0 :   PRInt32 oldStart = mStartOffset, oldEnd = mEndOffset;
     201               0 :   mStartOffset = aStartOffset;
     202               0 :   mEndOffset = aEndOffset;
     203                 : 
     204               0 :   nsRefPtr<nsAccessible> oldPosition = mPosition.forget();
     205               0 :   mPosition = newPosition.forget();
     206                 : 
     207               0 :   NotifyPivotChanged(oldPosition, oldStart, oldEnd);
     208                 : 
     209               0 :   return NS_OK;
     210                 : }
     211                 : 
     212                 : // Traversal functions
     213                 : 
     214                 : NS_IMETHODIMP
     215               0 : nsAccessiblePivot::MoveNext(nsIAccessibleTraversalRule* aRule, bool* aResult)
     216                 : {
     217               0 :   NS_ENSURE_ARG(aResult);
     218               0 :   NS_ENSURE_ARG(aRule);
     219                 : 
     220               0 :   nsresult rv = NS_OK;
     221               0 :   nsAccessible* accessible = SearchForward(mPosition, aRule, false, &rv);
     222               0 :   NS_ENSURE_SUCCESS(rv, rv);
     223                 : 
     224               0 :   *aResult = accessible;
     225               0 :   if (*aResult)
     226               0 :     MovePivotInternal(accessible);
     227                 : 
     228               0 :   return NS_OK;
     229                 : }
     230                 : 
     231                 : NS_IMETHODIMP
     232               0 : nsAccessiblePivot::MovePrevious(nsIAccessibleTraversalRule* aRule, bool* aResult)
     233                 : {
     234               0 :   NS_ENSURE_ARG(aResult);
     235               0 :   NS_ENSURE_ARG(aRule);
     236                 : 
     237               0 :   nsresult rv = NS_OK;
     238               0 :   nsAccessible* accessible = SearchBackward(mPosition, aRule, false, &rv);
     239               0 :   NS_ENSURE_SUCCESS(rv, rv);
     240                 : 
     241               0 :   *aResult = accessible;
     242               0 :   if (*aResult)
     243               0 :     MovePivotInternal(accessible);
     244                 : 
     245               0 :   return NS_OK;
     246                 : }
     247                 : 
     248                 : NS_IMETHODIMP
     249               0 : nsAccessiblePivot::MoveFirst(nsIAccessibleTraversalRule* aRule, bool* aResult)
     250                 : {
     251               0 :   NS_ENSURE_ARG(aResult);
     252               0 :   NS_ENSURE_ARG(aRule);
     253               0 :   nsresult rv = NS_OK;
     254               0 :   nsAccessible* accessible = SearchForward(mRoot, aRule, true, &rv);
     255               0 :   NS_ENSURE_SUCCESS(rv, rv);
     256                 : 
     257               0 :   *aResult = accessible;
     258               0 :   if (*aResult)
     259               0 :     MovePivotInternal(accessible);
     260                 : 
     261               0 :   return NS_OK;
     262                 : }
     263                 : 
     264                 : NS_IMETHODIMP
     265               0 : nsAccessiblePivot::MoveLast(nsIAccessibleTraversalRule* aRule, bool* aResult)
     266                 : {
     267               0 :   NS_ENSURE_ARG(aResult);
     268               0 :   NS_ENSURE_ARG(aRule);
     269                 : 
     270               0 :   *aResult = false;
     271               0 :   nsresult rv = NS_OK;
     272               0 :   nsAccessible* lastAccessible = mRoot;
     273               0 :   nsAccessible* accessible = nsnull;
     274                 : 
     275                 :   // First got to the last accessible in pre-order
     276               0 :   while (lastAccessible->HasChildren())
     277               0 :     lastAccessible = lastAccessible->LastChild();
     278                 : 
     279                 :   // Search backwards from last accessible and find the last occurrence in the doc
     280               0 :   accessible = SearchBackward(lastAccessible, aRule, true, &rv);
     281               0 :   NS_ENSURE_SUCCESS(rv, rv);
     282                 : 
     283               0 :   *aResult = accessible;
     284               0 :   if (*aResult)
     285               0 :     MovePivotInternal(accessible);
     286                 : 
     287               0 :   return NS_OK;
     288                 : }
     289                 : 
     290                 : // TODO: Implement
     291                 : NS_IMETHODIMP
     292               0 : nsAccessiblePivot::MoveNextByText(TextBoundaryType aBoundary, bool* aResult)
     293                 : {
     294               0 :   NS_ENSURE_ARG(aResult);
     295                 : 
     296               0 :   *aResult = false;
     297                 : 
     298               0 :   return NS_ERROR_NOT_IMPLEMENTED;
     299                 : }
     300                 : 
     301                 : // TODO: Implement
     302                 : NS_IMETHODIMP
     303               0 : nsAccessiblePivot::MovePreviousByText(TextBoundaryType aBoundary, bool* aResult)
     304                 : {
     305               0 :   NS_ENSURE_ARG(aResult);
     306                 : 
     307               0 :   *aResult = false;
     308                 : 
     309               0 :   return NS_ERROR_NOT_IMPLEMENTED;
     310                 : }
     311                 : 
     312                 : // Observer functions
     313                 : 
     314                 : NS_IMETHODIMP
     315               0 : nsAccessiblePivot::AddObserver(nsIAccessiblePivotObserver* aObserver)
     316                 : {
     317               0 :   NS_ENSURE_ARG(aObserver);
     318                 : 
     319               0 :   mObservers.AppendElement(aObserver);
     320                 : 
     321               0 :   return NS_OK;
     322                 : }
     323                 : 
     324                 : NS_IMETHODIMP
     325               0 : nsAccessiblePivot::RemoveObserver(nsIAccessiblePivotObserver* aObserver)
     326                 : {
     327               0 :   NS_ENSURE_ARG(aObserver);
     328                 : 
     329               0 :   return mObservers.RemoveElement(aObserver) ? NS_OK : NS_ERROR_FAILURE;
     330                 : }
     331                 : 
     332                 : // Private utility methods
     333                 : 
     334                 : bool
     335               0 : nsAccessiblePivot::IsRootDescendant(nsAccessible* aAccessible)
     336                 : {
     337               0 :   nsAccessible* accessible = aAccessible;
     338               0 :   do {
     339               0 :     if (accessible == mRoot)
     340               0 :       return true;
     341                 :   } while ((accessible = accessible->Parent()));
     342                 : 
     343               0 :   return false;
     344                 : }
     345                 : 
     346                 : void
     347               0 : nsAccessiblePivot::MovePivotInternal(nsAccessible* aPosition)
     348                 : {
     349               0 :   nsRefPtr<nsAccessible> oldPosition = mPosition.forget();
     350               0 :   mPosition = aPosition;
     351               0 :   PRInt32 oldStart = mStartOffset, oldEnd = mEndOffset;
     352               0 :   mStartOffset = mEndOffset = -1;
     353                 : 
     354               0 :   NotifyPivotChanged(oldPosition, oldStart, oldEnd);
     355               0 : }
     356                 : 
     357                 : nsAccessible*
     358               0 : nsAccessiblePivot::SearchBackward(nsAccessible* aAccessible,
     359                 :                                   nsIAccessibleTraversalRule* aRule,
     360                 :                                   bool searchCurrent,
     361                 :                                   nsresult* rv)
     362                 : {
     363               0 :   *rv = NS_OK;
     364                 : 
     365                 :   // Initial position could be unset, in that case return null.
     366               0 :   if (!aAccessible)
     367               0 :     return nsnull;
     368                 : 
     369               0 :   RuleCache cache(aRule);
     370               0 :   nsAccessible* accessible = aAccessible;
     371                 : 
     372               0 :   PRUint16 filtered = nsIAccessibleTraversalRule::FILTER_IGNORE;
     373                 : 
     374               0 :   if (searchCurrent) {
     375               0 :     *rv = cache.ApplyFilter(accessible, &filtered);
     376               0 :     NS_ENSURE_SUCCESS(*rv, nsnull);
     377               0 :     if (filtered & nsIAccessibleTraversalRule::FILTER_MATCH)
     378               0 :       return accessible;
     379                 :   }
     380                 : 
     381               0 :   while (accessible != mRoot) {
     382               0 :     nsAccessible* parent = accessible->Parent();
     383               0 :     PRInt32 idxInParent = accessible->IndexInParent();
     384               0 :     while (idxInParent > 0) {
     385               0 :       if (!(accessible = parent->GetChildAt(--idxInParent)))
     386               0 :         continue;
     387                 : 
     388               0 :       *rv = cache.ApplyFilter(accessible, &filtered);
     389               0 :       NS_ENSURE_SUCCESS(*rv, nsnull);
     390                 : 
     391                 :       nsAccessible* lastChild;
     392               0 :       while (!(filtered & nsIAccessibleTraversalRule::FILTER_IGNORE_SUBTREE) &&
     393                 :              (lastChild = accessible->LastChild())) {
     394               0 :         parent = accessible;
     395               0 :         accessible = lastChild;
     396               0 :         *rv = cache.ApplyFilter(accessible, &filtered);
     397               0 :         NS_ENSURE_SUCCESS(*rv, nsnull);
     398                 :       }
     399                 : 
     400               0 :       if (filtered & nsIAccessibleTraversalRule::FILTER_MATCH)
     401               0 :         return accessible;
     402                 :     }
     403                 : 
     404               0 :     if (!(accessible = parent))
     405               0 :       break;
     406                 : 
     407               0 :     *rv = cache.ApplyFilter(accessible, &filtered);
     408               0 :     NS_ENSURE_SUCCESS(*rv, nsnull);
     409                 : 
     410               0 :     if (filtered & nsIAccessibleTraversalRule::FILTER_MATCH)
     411               0 :       return accessible;
     412                 :   }
     413                 : 
     414               0 :   return nsnull;
     415                 : }
     416                 : 
     417                 : nsAccessible*
     418               0 : nsAccessiblePivot::SearchForward(nsAccessible* aAccessible,
     419                 :                                  nsIAccessibleTraversalRule* aRule,
     420                 :                                  bool searchCurrent,
     421                 :                                  nsresult* rv)
     422                 : {
     423               0 :   *rv = NS_OK;
     424                 : 
     425                 :   // Initial position could be not set, in that case begin search from root.
     426               0 :   nsAccessible *accessible = (!aAccessible) ? mRoot.get() : aAccessible;
     427                 : 
     428               0 :   RuleCache cache(aRule);
     429                 : 
     430               0 :   PRUint16 filtered = nsIAccessibleTraversalRule::FILTER_IGNORE;
     431               0 :   *rv = cache.ApplyFilter(accessible, &filtered);
     432               0 :   NS_ENSURE_SUCCESS(*rv, nsnull);
     433               0 :   if (searchCurrent && (filtered & nsIAccessibleTraversalRule::FILTER_MATCH))
     434               0 :     return accessible;
     435                 : 
     436               0 :   while (true) {
     437               0 :     nsAccessible* firstChild = nsnull;
     438               0 :     while (!(filtered & nsIAccessibleTraversalRule::FILTER_IGNORE_SUBTREE) &&
     439                 :            (firstChild = accessible->FirstChild())) {
     440               0 :       accessible = firstChild;
     441               0 :       *rv = cache.ApplyFilter(accessible, &filtered);
     442               0 :       NS_ENSURE_SUCCESS(*rv, nsnull);
     443                 : 
     444               0 :       if (filtered & nsIAccessibleTraversalRule::FILTER_MATCH)
     445               0 :         return accessible;
     446                 :     }
     447                 : 
     448               0 :     nsAccessible* sibling = nsnull;
     449               0 :     nsAccessible* temp = accessible;
     450               0 :     do {
     451               0 :       if (temp == mRoot)
     452               0 :         break;
     453                 : 
     454               0 :       sibling = temp->NextSibling();
     455                 : 
     456               0 :       if (sibling)
     457               0 :         break;
     458                 :     } while ((temp = temp->Parent()));
     459                 : 
     460               0 :     if (!sibling)
     461                 :       break;
     462                 : 
     463               0 :     accessible = sibling;
     464               0 :     *rv = cache.ApplyFilter(accessible, &filtered);
     465               0 :     NS_ENSURE_SUCCESS(*rv, nsnull);
     466                 : 
     467               0 :     if (filtered & nsIAccessibleTraversalRule::FILTER_MATCH)
     468               0 :       return accessible;
     469                 :   }
     470                 : 
     471               0 :   return nsnull;
     472                 : }
     473                 : 
     474                 : void
     475               0 : nsAccessiblePivot::NotifyPivotChanged(nsAccessible* aOldPosition,
     476                 :                                       PRInt32 aOldStart, PRInt32 aOldEnd)
     477                 : {
     478               0 :   nsTObserverArray<nsCOMPtr<nsIAccessiblePivotObserver> >::ForwardIterator iter(mObservers);
     479               0 :   while (iter.HasMore()) {
     480               0 :     nsIAccessiblePivotObserver* obs = iter.GetNext();
     481               0 :     obs->OnPivotChanged(this, aOldPosition, aOldStart, aOldEnd);
     482                 :   }
     483               0 : }
     484                 : 
     485                 : nsresult
     486               0 : RuleCache::ApplyFilter(nsAccessible* aAccessible, PRUint16* aResult)
     487                 : {
     488               0 :   *aResult = nsIAccessibleTraversalRule::FILTER_IGNORE;
     489                 : 
     490               0 :   if (!mAcceptRoles) {
     491               0 :     nsresult rv = mRule->GetMatchRoles(&mAcceptRoles, &mAcceptRolesLength);
     492               0 :     NS_ENSURE_SUCCESS(rv, rv);
     493               0 :     rv = mRule->GetPreFilter(&mPreFilter);
     494               0 :     NS_ENSURE_SUCCESS(rv, rv);
     495                 :   }
     496                 : 
     497               0 :   if (mPreFilter) {
     498               0 :     PRUint64 state = aAccessible->State();
     499                 : 
     500               0 :     if ((nsIAccessibleTraversalRule::PREFILTER_INVISIBLE & mPreFilter) &&
     501                 :         (state & states::INVISIBLE))
     502               0 :       return NS_OK;
     503                 : 
     504               0 :     if ((nsIAccessibleTraversalRule::PREFILTER_OFFSCREEN & mPreFilter) &&
     505                 :         (state & states::OFFSCREEN))
     506               0 :       return NS_OK;
     507                 : 
     508               0 :     if ((nsIAccessibleTraversalRule::PREFILTER_NOT_FOCUSABLE & mPreFilter) &&
     509               0 :         !(state & states::FOCUSABLE))
     510               0 :       return NS_OK;
     511                 :   }
     512                 : 
     513               0 :   if (mAcceptRolesLength > 0) {
     514               0 :     PRUint32 accessibleRole = aAccessible->Role();
     515               0 :     bool matchesRole = false;
     516               0 :     for (PRUint32 idx = 0; idx < mAcceptRolesLength; idx++) {
     517               0 :       matchesRole = mAcceptRoles[idx] == accessibleRole;
     518               0 :       if (matchesRole)
     519               0 :         break;
     520                 :     }
     521               0 :     if (!matchesRole)
     522               0 :       return NS_OK;
     523                 :   }
     524                 : 
     525               0 :   return mRule->Match(aAccessible, aResult);
     526            4392 : }

Generated by: LCOV version 1.7