LCOV - code coverage report
Current view: directory - accessible/src/base - nsAccessibilityService.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 793 0 0.0 %
Date: 2012-06-02 Functions: 61 0 0.0 %

       1                 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2                 : /* ***** BEGIN LICENSE BLOCK *****
       3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       4                 :  *
       5                 :  * The contents of this file are subject to the Mozilla Public License Version
       6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       7                 :  * the License. You may obtain a copy of the License at
       8                 :  * http://www.mozilla.org/MPL/
       9                 :  *
      10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      12                 :  * for the specific language governing rights and limitations under the
      13                 :  * License.
      14                 :  *
      15                 :  * The Original Code is mozilla.org code.
      16                 :  *
      17                 :  * The Initial Developer of the Original Code is
      18                 :  * Netscape Communications Corporation.
      19                 :  * Portions created by the Initial Developer are Copyright (C) 1998
      20                 :  * the Initial Developer. All Rights Reserved.
      21                 :  *
      22                 :  * Contributor(s):
      23                 :  *   John Gaunt (jgaunt@netscape.com)
      24                 :  *
      25                 :  * Alternatively, the contents of this file may be used under the terms of
      26                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
      27                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      28                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      29                 :  * of those above. If you wish to allow use of your version of this file only
      30                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      31                 :  * use your version of this file under the terms of the MPL, indicate your
      32                 :  * decision by deleting the provisions above and replace them with the notice
      33                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      34                 :  * the provisions above, a recipient may use your version of this file under
      35                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      36                 :  *
      37                 :  * ***** END LICENSE BLOCK ***** */
      38                 : 
      39                 : #include "mozilla/Util.h"
      40                 : 
      41                 : // NOTE: alphabetically ordered
      42                 : #include "nsAccessibilityService.h"
      43                 : #include "nsAccessiblePivot.h"
      44                 : #include "nsCoreUtils.h"
      45                 : #include "nsAccUtils.h"
      46                 : #include "nsApplicationAccessibleWrap.h"
      47                 : #include "nsARIAGridAccessibleWrap.h"
      48                 : #include "nsARIAMap.h"
      49                 : #include "FocusManager.h"
      50                 : 
      51                 : #include "nsIContentViewer.h"
      52                 : #include "nsCURILoader.h"
      53                 : #include "nsDocAccessible.h"
      54                 : #include "nsHTMLCanvasAccessible.h"
      55                 : #include "nsHTMLImageMapAccessible.h"
      56                 : #include "nsHTMLLinkAccessible.h"
      57                 : #include "nsHTMLSelectAccessible.h"
      58                 : #include "nsHTMLTableAccessibleWrap.h"
      59                 : #include "nsHTMLTextAccessible.h"
      60                 : #include "nsHyperTextAccessibleWrap.h"
      61                 : #include "nsIAccessibilityService.h"
      62                 : #include "nsIAccessibleProvider.h"
      63                 : #include "Role.h"
      64                 : #include "States.h"
      65                 : #include "Statistics.h"
      66                 : 
      67                 : #include "nsIDOMDocument.h"
      68                 : #include "nsIDOMHTMLAreaElement.h"
      69                 : #include "nsIDOMHTMLLegendElement.h"
      70                 : #include "nsIDOMHTMLObjectElement.h"
      71                 : #include "nsIDOMHTMLOptGroupElement.h"
      72                 : #include "nsIDOMHTMLOptionElement.h"
      73                 : #include "nsIDOMXULElement.h"
      74                 : #include "nsIHTMLDocument.h"
      75                 : #include "nsImageFrame.h"
      76                 : #include "nsILink.h"
      77                 : #include "nsIObserverService.h"
      78                 : #include "nsLayoutUtils.h"
      79                 : #include "nsNPAPIPluginInstance.h"
      80                 : #include "nsISupportsUtils.h"
      81                 : #include "nsObjectFrame.h"
      82                 : #include "nsOuterDocAccessible.h"
      83                 : #include "nsRootAccessibleWrap.h"
      84                 : #include "nsTextFragment.h"
      85                 : #include "mozilla/Services.h"
      86                 : #include "nsEventStates.h"
      87                 : 
      88                 : #ifdef MOZ_XUL
      89                 : #include "nsXULAlertAccessible.h"
      90                 : #include "nsXULColorPickerAccessible.h"
      91                 : #include "nsXULComboboxAccessible.h"
      92                 : #include "nsXULFormControlAccessible.h"
      93                 : #include "nsXULListboxAccessibleWrap.h"
      94                 : #include "nsXULMenuAccessibleWrap.h"
      95                 : #include "nsXULSliderAccessible.h"
      96                 : #include "nsXULTabAccessible.h"
      97                 : #include "nsXULTextAccessible.h"
      98                 : #include "nsXULTreeGridAccessibleWrap.h"
      99                 : #endif
     100                 : 
     101                 : // For native window support for object/embed/applet tags
     102                 : #ifdef XP_WIN
     103                 : #include "nsHTMLWin32ObjectAccessible.h"
     104                 : #endif
     105                 : 
     106                 : // For embedding plugin accessibles
     107                 : #ifdef MOZ_ACCESSIBILITY_ATK
     108                 : #include "AtkSocketAccessible.h"
     109                 : #endif
     110                 : 
     111                 : #include "nsXFormsFormControlsAccessible.h"
     112                 : #include "nsXFormsWidgetsAccessible.h"
     113                 : 
     114                 : #include "mozilla/FunctionTimer.h"
     115                 : #include "mozilla/dom/Element.h"
     116                 : 
     117                 : using namespace mozilla;
     118                 : using namespace mozilla::a11y;
     119                 : 
     120                 : ////////////////////////////////////////////////////////////////////////////////
     121                 : // nsAccessibilityService
     122                 : ////////////////////////////////////////////////////////////////////////////////
     123                 : 
     124                 : nsAccessibilityService *nsAccessibilityService::gAccessibilityService = nsnull;
     125                 : bool nsAccessibilityService::gIsShutdown = true;
     126                 : 
     127               0 : nsAccessibilityService::nsAccessibilityService() :
     128               0 :   nsAccDocManager(), FocusManager()
     129                 : {
     130                 :   NS_TIME_FUNCTION;
     131               0 : }
     132                 : 
     133               0 : nsAccessibilityService::~nsAccessibilityService()
     134                 : {
     135               0 :   NS_ASSERTION(gIsShutdown, "Accessibility wasn't shutdown!");
     136               0 :   gAccessibilityService = nsnull;
     137               0 : }
     138                 : 
     139                 : ////////////////////////////////////////////////////////////////////////////////
     140                 : // nsISupports
     141                 : 
     142               0 : NS_IMPL_ISUPPORTS_INHERITED3(nsAccessibilityService,
     143                 :                              nsAccDocManager,
     144                 :                              nsIAccessibilityService,
     145                 :                              nsIAccessibleRetrieval,
     146                 :                              nsIObserver)
     147                 : 
     148                 : ////////////////////////////////////////////////////////////////////////////////
     149                 : // nsIObserver
     150                 : 
     151                 : NS_IMETHODIMP
     152               0 : nsAccessibilityService::Observe(nsISupports *aSubject, const char *aTopic,
     153                 :                          const PRUnichar *aData)
     154                 : {
     155               0 :   if (!nsCRT::strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID))
     156               0 :     Shutdown();
     157                 : 
     158               0 :   return NS_OK;
     159                 : }
     160                 : 
     161                 : // nsIAccessibilityService
     162                 : void
     163               0 : nsAccessibilityService::NotifyOfAnchorJumpTo(nsIContent* aTargetNode)
     164                 : {
     165               0 :   nsIDocument* documentNode = aTargetNode->GetCurrentDoc();
     166               0 :   if (documentNode) {
     167               0 :     nsDocAccessible* document = GetDocAccessible(documentNode);
     168               0 :     if (document)
     169               0 :       document->SetAnchorJump(aTargetNode);
     170                 :   }
     171               0 : }
     172                 : 
     173                 : // nsIAccessibilityService
     174                 : void
     175               0 : nsAccessibilityService::FireAccessibleEvent(PRUint32 aEvent,
     176                 :                                             nsAccessible* aTarget)
     177                 : {
     178               0 :   nsEventShell::FireEvent(aEvent, aTarget);
     179               0 : }
     180                 : 
     181                 : ////////////////////////////////////////////////////////////////////////////////
     182                 : // nsIAccessibilityService
     183                 : 
     184                 : nsAccessible*
     185               0 : nsAccessibilityService::GetRootDocumentAccessible(nsIPresShell* aPresShell,
     186                 :                                                   bool aCanCreate)
     187                 : {
     188               0 :   nsIDocument* documentNode = aPresShell->GetDocument();
     189               0 :   if (documentNode) {
     190               0 :     nsCOMPtr<nsISupports> container = documentNode->GetContainer();
     191               0 :     nsCOMPtr<nsIDocShellTreeItem> treeItem(do_QueryInterface(container));
     192               0 :     if (treeItem) {
     193               0 :       nsCOMPtr<nsIDocShellTreeItem> rootTreeItem;
     194               0 :       treeItem->GetRootTreeItem(getter_AddRefs(rootTreeItem));
     195               0 :       if (treeItem != rootTreeItem) {
     196               0 :         nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(rootTreeItem));
     197               0 :         nsCOMPtr<nsIPresShell> presShell;
     198               0 :         docShell->GetPresShell(getter_AddRefs(presShell));
     199               0 :         documentNode = presShell->GetDocument();
     200                 :       }
     201                 : 
     202                 :       return aCanCreate ?
     203               0 :         GetDocAccessible(documentNode) : GetDocAccessibleFromCache(documentNode);
     204                 :     }
     205                 :   }
     206               0 :   return nsnull;
     207                 : }
     208                 :  
     209                 : already_AddRefed<nsAccessible>
     210               0 : nsAccessibilityService::CreateOuterDocAccessible(nsIContent* aContent,
     211                 :                                                  nsIPresShell* aPresShell)
     212                 : {
     213                 :   nsAccessible* accessible = 
     214                 :     new nsOuterDocAccessible(aContent, 
     215               0 :                              nsAccUtils::GetDocAccessibleFor(aPresShell));
     216               0 :   NS_ADDREF(accessible);
     217               0 :   return accessible;
     218                 : }
     219                 : 
     220                 : already_AddRefed<nsAccessible>
     221               0 : nsAccessibilityService::CreateHTMLButtonAccessible(nsIContent* aContent,
     222                 :                                                    nsIPresShell* aPresShell)
     223                 : {
     224                 :   nsAccessible* accessible = 
     225                 :     new nsHTMLButtonAccessible(aContent, 
     226               0 :                                nsAccUtils::GetDocAccessibleFor(aPresShell));
     227               0 :   NS_ADDREF(accessible);
     228               0 :   return accessible;
     229                 : }
     230                 : 
     231                 : already_AddRefed<nsAccessible>
     232               0 : nsAccessibilityService::CreateHTMLLIAccessible(nsIContent* aContent,
     233                 :                                                nsIPresShell* aPresShell)
     234                 : {
     235                 :   nsAccessible* accessible = 
     236                 :     new nsHTMLLIAccessible(aContent, 
     237               0 :                            nsAccUtils::GetDocAccessibleFor(aPresShell));
     238               0 :   NS_ADDREF(accessible);
     239               0 :   return accessible;
     240                 : }
     241                 : 
     242                 : already_AddRefed<nsAccessible>
     243               0 : nsAccessibilityService::CreateHyperTextAccessible(nsIContent* aContent,
     244                 :                                                   nsIPresShell* aPresShell)
     245                 : {
     246                 :   nsAccessible* accessible = 
     247                 :     new nsHyperTextAccessibleWrap(aContent, 
     248               0 :                                   nsAccUtils::GetDocAccessibleFor(aPresShell));
     249               0 :   NS_ADDREF(accessible);
     250               0 :   return accessible;
     251                 : }
     252                 : 
     253                 : already_AddRefed<nsAccessible>
     254               0 : nsAccessibilityService::CreateHTMLCheckboxAccessible(nsIContent* aContent,
     255                 :                                                      nsIPresShell* aPresShell)
     256                 : {
     257                 :   nsAccessible* accessible = 
     258                 :     new nsHTMLCheckboxAccessible(aContent, 
     259               0 :                                  nsAccUtils::GetDocAccessibleFor(aPresShell));
     260               0 :   NS_ADDREF(accessible);
     261               0 :   return accessible;
     262                 : }
     263                 : 
     264                 : already_AddRefed<nsAccessible>
     265               0 : nsAccessibilityService::CreateHTMLComboboxAccessible(nsIContent* aContent,
     266                 :                                                      nsIPresShell* aPresShell)
     267                 : {
     268                 :   nsAccessible* accessible = 
     269                 :     new nsHTMLComboboxAccessible(aContent, 
     270               0 :                                  nsAccUtils::GetDocAccessibleFor(aPresShell));
     271               0 :   NS_ADDREF(accessible);
     272               0 :   return accessible;
     273                 : }
     274                 : 
     275                 : already_AddRefed<nsAccessible>
     276               0 : nsAccessibilityService::CreateHTMLCanvasAccessible(nsIContent* aContent,
     277                 :                                                    nsIPresShell* aPresShell)
     278                 : {
     279                 :   nsAccessible* accessible = 
     280                 :     new nsHTMLCanvasAccessible(aContent, 
     281               0 :                                nsAccUtils::GetDocAccessibleFor(aPresShell));
     282               0 :   NS_ADDREF(accessible);
     283               0 :   return accessible;
     284                 : }
     285                 : 
     286                 : already_AddRefed<nsAccessible>
     287               0 : nsAccessibilityService::CreateHTMLFileInputAccessible(nsIContent* aContent,
     288                 :                                                       nsIPresShell* aPresShell)
     289                 : {
     290                 :   nsAccessible* accessible = 
     291                 :     new nsHTMLFileInputAccessible(aContent, 
     292               0 :                                   nsAccUtils::GetDocAccessibleFor(aPresShell));
     293               0 :   NS_ADDREF(accessible);
     294               0 :   return accessible;
     295                 : }
     296                 : 
     297                 : already_AddRefed<nsAccessible>
     298               0 : nsAccessibilityService::CreateHTMLImageAccessible(nsIContent* aContent,
     299                 :                                                   nsIPresShell* aPresShell)
     300                 : {
     301               0 :   nsAutoString mapElmName;
     302               0 :   aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::usemap, mapElmName);
     303               0 :   nsCOMPtr<nsIDOMHTMLMapElement> mapElm;
     304               0 :   if (nsIDocument* document = aContent->GetCurrentDoc()) {
     305               0 :     mapElm = do_QueryInterface(document->FindImageMap(mapElmName));
     306                 :   }
     307                 : 
     308                 :   nsAccessible* accessible = mapElm ?
     309                 :     new nsHTMLImageMapAccessible(aContent, 
     310                 :                                  nsAccUtils::GetDocAccessibleFor(aPresShell), 
     311               0 :                                  mapElm) :
     312                 :     new nsHTMLImageAccessibleWrap(aContent, 
     313               0 :                                   nsAccUtils::GetDocAccessibleFor(aPresShell));
     314               0 :   NS_ADDREF(accessible);
     315               0 :   return accessible;
     316                 : }
     317                 : 
     318                 : already_AddRefed<nsAccessible>
     319               0 : nsAccessibilityService::CreateHTMLGroupboxAccessible(nsIContent* aContent,
     320                 :                                                      nsIPresShell* aPresShell)
     321                 : {
     322                 :   nsAccessible* accessible = 
     323                 :     new nsHTMLGroupboxAccessible(aContent, 
     324               0 :                                  nsAccUtils::GetDocAccessibleFor(aPresShell));
     325               0 :   NS_ADDREF(accessible);
     326               0 :   return accessible;
     327                 : }
     328                 : 
     329                 : already_AddRefed<nsAccessible>
     330               0 : nsAccessibilityService::CreateHTMLListboxAccessible(nsIContent* aContent,
     331                 :                                                     nsIPresShell* aPresShell)
     332                 : {
     333                 :   nsAccessible* accessible = 
     334                 :     new nsHTMLSelectListAccessible(aContent, 
     335               0 :                                    nsAccUtils::GetDocAccessibleFor(aPresShell));
     336               0 :   NS_ADDREF(accessible);
     337               0 :   return accessible;
     338                 : }
     339                 : 
     340                 : already_AddRefed<nsAccessible>
     341               0 : nsAccessibilityService::CreateHTMLMediaAccessible(nsIContent* aContent,
     342                 :                                                   nsIPresShell* aPresShell)
     343                 : {
     344                 :   nsAccessible* accessible = 
     345                 :     new nsEnumRoleAccessible(aContent, 
     346                 :                              nsAccUtils::GetDocAccessibleFor(aPresShell),
     347               0 :                              roles::GROUPING);
     348               0 :   NS_ADDREF(accessible);
     349               0 :   return accessible;
     350                 : }
     351                 : 
     352                 : already_AddRefed<nsAccessible>
     353               0 : nsAccessibilityService::CreateHTMLObjectFrameAccessible(nsObjectFrame* aFrame,
     354                 :                                                         nsIContent* aContent,
     355                 :                                                         nsIPresShell* aPresShell)
     356                 : {
     357                 :   // We can have several cases here:
     358                 :   // 1) a text or html embedded document where the contentDocument variable in
     359                 :   //    the object element holds the content;
     360                 :   // 2) web content that uses a plugin, which means we will have to go to
     361                 :   //    the plugin to get the accessible content;
     362                 :   // 3) an image or imagemap, where the image frame points back to the object
     363                 :   //    element DOMNode.
     364                 : 
     365               0 :   if (aFrame->GetRect().IsEmpty())
     366               0 :     return nsnull;
     367                 : 
     368                 : 
     369                 :   // 1) for object elements containing either HTML or TXT documents
     370               0 :   nsCOMPtr<nsIDOMHTMLObjectElement> obj(do_QueryInterface(aContent));
     371               0 :   if (obj) {
     372               0 :     nsCOMPtr<nsIDOMDocument> domDoc;
     373               0 :     obj->GetContentDocument(getter_AddRefs(domDoc));
     374               0 :     if (domDoc)
     375               0 :       return CreateOuterDocAccessible(aContent, aPresShell);
     376                 :   }
     377                 : 
     378                 : #if defined(XP_WIN) || defined(MOZ_ACCESSIBILITY_ATK)
     379                 :   // 2) for plugins
     380               0 :   nsRefPtr<nsNPAPIPluginInstance> pluginInstance;
     381               0 :   if (NS_SUCCEEDED(aFrame->GetPluginInstance(getter_AddRefs(pluginInstance))) &&
     382               0 :       pluginInstance) {
     383                 : #ifdef XP_WIN
     384                 :     // Note: pluginPort will be null if windowless.
     385                 :     HWND pluginPort = nsnull;
     386                 :     aFrame->GetPluginPort(&pluginPort);
     387                 : 
     388                 :     nsAccessible* accessible = 
     389                 :       new nsHTMLWin32ObjectOwnerAccessible(aContent,
     390                 :                                            nsAccUtils::GetDocAccessibleFor(aPresShell),
     391                 :                                            pluginPort);
     392                 :     NS_ADDREF(accessible);
     393                 :     return accessible;
     394                 : 
     395                 : #elif MOZ_ACCESSIBILITY_ATK
     396               0 :     if (!AtkSocketAccessible::gCanEmbed)
     397               0 :       return nsnull;
     398                 : 
     399               0 :     nsCString plugId;
     400                 :     nsresult rv = pluginInstance->GetValueFromPlugin(
     401               0 :       NPPVpluginNativeAccessibleAtkPlugId, &plugId);
     402               0 :     if (NS_SUCCEEDED(rv) && !plugId.IsEmpty()) {
     403                 :       AtkSocketAccessible* socketAccessible =
     404                 :         new AtkSocketAccessible(aContent, 
     405                 :                                 nsAccUtils::GetDocAccessibleFor(aPresShell), 
     406               0 :                                 plugId);
     407                 : 
     408               0 :       NS_ADDREF(socketAccessible);
     409               0 :       return socketAccessible;
     410                 :     }
     411                 : #endif
     412                 :   }
     413                 : #endif
     414                 : 
     415                 :   // 3) for images and imagemaps, or anything else with a child frame
     416                 :   // we have the object frame, get the image frame
     417               0 :   nsIFrame* frame = aFrame->GetFirstPrincipalChild();
     418               0 :   return frame ? frame->CreateAccessible() : nsnull;
     419                 : }
     420                 : 
     421                 : already_AddRefed<nsAccessible>
     422               0 : nsAccessibilityService::CreateHTMLRadioButtonAccessible(nsIContent* aContent,
     423                 :                                                         nsIPresShell* aPresShell)
     424                 : {
     425                 :   nsAccessible* accessible = 
     426                 :     new nsHTMLRadioButtonAccessible(aContent, 
     427               0 :                                     nsAccUtils::GetDocAccessibleFor(aPresShell));
     428               0 :   NS_ADDREF(accessible);
     429               0 :   return accessible;
     430                 : }
     431                 : 
     432                 : already_AddRefed<nsAccessible>
     433               0 : nsAccessibilityService::CreateHTMLTableAccessible(nsIContent* aContent,
     434                 :                                                   nsIPresShell* aPresShell)
     435                 : {
     436                 :   nsAccessible* accessible = 
     437                 :     new nsHTMLTableAccessibleWrap(aContent, 
     438               0 :                                   nsAccUtils::GetDocAccessibleFor(aPresShell));
     439               0 :   NS_ADDREF(accessible);
     440               0 :   return accessible;
     441                 : }
     442                 : 
     443                 : already_AddRefed<nsAccessible>
     444               0 : nsAccessibilityService::CreateHTMLTableCellAccessible(nsIContent* aContent,
     445                 :                                                       nsIPresShell* aPresShell)
     446                 : {
     447                 :   nsAccessible* accessible = 
     448                 :     new nsHTMLTableCellAccessibleWrap(aContent,
     449               0 :                                       nsAccUtils::GetDocAccessibleFor(aPresShell));
     450               0 :   NS_ADDREF(accessible);
     451               0 :   return accessible;
     452                 : }
     453                 : 
     454                 : already_AddRefed<nsAccessible>
     455               0 : nsAccessibilityService::CreateHTMLTextAccessible(nsIContent* aContent,
     456                 :                                                  nsIPresShell* aPresShell)
     457                 : {
     458                 :   nsAccessible* accessible = 
     459                 :     new nsHTMLTextAccessible(aContent, 
     460               0 :                              nsAccUtils::GetDocAccessibleFor(aPresShell));
     461               0 :   NS_ADDREF(accessible);
     462               0 :   return accessible;
     463                 : }
     464                 : 
     465                 : already_AddRefed<nsAccessible>
     466               0 : nsAccessibilityService::CreateHTMLTextFieldAccessible(nsIContent* aContent,
     467                 :                                                       nsIPresShell* aPresShell)
     468                 : {
     469                 :   nsAccessible* accessible = 
     470                 :     new nsHTMLTextFieldAccessible(aContent, 
     471               0 :                                   nsAccUtils::GetDocAccessibleFor(aPresShell));
     472               0 :   NS_ADDREF(accessible);
     473               0 :   return accessible;
     474                 : }
     475                 : 
     476                 : already_AddRefed<nsAccessible>
     477               0 : nsAccessibilityService::CreateHTMLLabelAccessible(nsIContent* aContent,
     478                 :                                                   nsIPresShell* aPresShell)
     479                 : {
     480                 :   nsAccessible* accessible = 
     481                 :     new nsHTMLLabelAccessible(aContent, 
     482               0 :                               nsAccUtils::GetDocAccessibleFor(aPresShell));
     483               0 :   NS_ADDREF(accessible);
     484               0 :   return accessible;
     485                 : }
     486                 : 
     487                 : already_AddRefed<nsAccessible>
     488               0 : nsAccessibilityService::CreateHTMLHRAccessible(nsIContent* aContent,
     489                 :                                                nsIPresShell* aPresShell)
     490                 : {
     491                 :   nsAccessible* accessible = 
     492                 :     new nsHTMLHRAccessible(aContent, 
     493               0 :                            nsAccUtils::GetDocAccessibleFor(aPresShell));
     494               0 :   NS_ADDREF(accessible);
     495               0 :   return accessible;
     496                 : }
     497                 : 
     498                 : already_AddRefed<nsAccessible>
     499               0 : nsAccessibilityService::CreateHTMLBRAccessible(nsIContent* aContent,
     500                 :                                                nsIPresShell* aPresShell)
     501                 : {
     502                 :   nsAccessible* accessible = 
     503                 :     new nsHTMLBRAccessible(aContent, 
     504               0 :                            nsAccUtils::GetDocAccessibleFor(aPresShell));
     505               0 :   NS_ADDREF(accessible);
     506               0 :   return accessible;
     507                 : }
     508                 : 
     509                 : already_AddRefed<nsAccessible>
     510               0 : nsAccessibilityService::CreateHTMLCaptionAccessible(nsIContent* aContent,
     511                 :                                                     nsIPresShell* aPresShell)
     512                 : {
     513                 :   nsAccessible* accessible = 
     514                 :     new nsHTMLCaptionAccessible(aContent, 
     515               0 :                                 nsAccUtils::GetDocAccessibleFor(aPresShell));
     516               0 :   NS_ADDREF(accessible);
     517               0 :   return accessible;
     518                 : }
     519                 : 
     520                 : void
     521               0 : nsAccessibilityService::ContentRangeInserted(nsIPresShell* aPresShell,
     522                 :                                              nsIContent* aContainer,
     523                 :                                              nsIContent* aStartChild,
     524                 :                                              nsIContent* aEndChild)
     525                 : {
     526                 : #ifdef DEBUG_CONTENTMUTATION
     527                 :   nsAutoString tag;
     528                 :   aStartChild->Tag()->ToString(tag);
     529                 : 
     530                 :   nsIAtom* atomid = aStartChild->GetID();
     531                 :   nsCAutoString id;
     532                 :   if (atomid)
     533                 :     atomid->ToUTF8String(id);
     534                 : 
     535                 :   nsAutoString ctag;
     536                 :   nsCAutoString cid;
     537                 :   nsIAtom* catomid = nsnull;
     538                 :   if (aContainer) {
     539                 :     aContainer->Tag()->ToString(ctag);
     540                 :     catomid = aContainer->GetID();
     541                 :     if (catomid)
     542                 :       catomid->ToUTF8String(cid);
     543                 :   }
     544                 : 
     545                 :   printf("\ncontent inserted: %s@id='%s', container: %s@id='%s', end node: %p\n\n",
     546                 :          NS_ConvertUTF16toUTF8(tag).get(), id.get(),
     547                 :          NS_ConvertUTF16toUTF8(ctag).get(), cid.get(), aEndChild);
     548                 : #endif
     549                 : 
     550               0 :   nsDocAccessible* docAccessible = GetDocAccessible(aPresShell->GetDocument());
     551               0 :   if (docAccessible)
     552               0 :     docAccessible->ContentInserted(aContainer, aStartChild, aEndChild);
     553               0 : }
     554                 : 
     555                 : void
     556               0 : nsAccessibilityService::ContentRemoved(nsIPresShell* aPresShell,
     557                 :                                        nsIContent* aContainer,
     558                 :                                        nsIContent* aChild)
     559                 : {
     560                 : #ifdef DEBUG_CONTENTMUTATION
     561                 :   nsAutoString tag;
     562                 :   aChild->Tag()->ToString(tag);
     563                 : 
     564                 :   nsIAtom* atomid = aChild->GetID();
     565                 :   nsCAutoString id;
     566                 :   if (atomid)
     567                 :     atomid->ToUTF8String(id);
     568                 : 
     569                 :   nsAutoString ctag;
     570                 :   nsCAutoString cid;
     571                 :   nsIAtom* catomid = nsnull;
     572                 :   if (aContainer) {
     573                 :     aContainer->Tag()->ToString(ctag);
     574                 :     catomid = aContainer->GetID();
     575                 :     if (catomid)
     576                 :       catomid->ToUTF8String(cid);
     577                 :   }
     578                 : 
     579                 :   printf("\ncontent removed: %s@id='%s', container: %s@id='%s'\n\n",
     580                 :            NS_ConvertUTF16toUTF8(tag).get(), id.get(),
     581                 :            NS_ConvertUTF16toUTF8(ctag).get(), cid.get());
     582                 : #endif
     583                 : 
     584               0 :   nsDocAccessible* docAccessible = GetDocAccessible(aPresShell->GetDocument());
     585               0 :   if (docAccessible)
     586               0 :     docAccessible->ContentRemoved(aContainer, aChild);
     587               0 : }
     588                 : 
     589                 : void
     590               0 : nsAccessibilityService::UpdateText(nsIPresShell* aPresShell,
     591                 :                                    nsIContent* aContent)
     592                 : {
     593               0 :   nsDocAccessible* document = GetDocAccessible(aPresShell->GetDocument());
     594               0 :   if (document)
     595               0 :     document->UpdateText(aContent);
     596               0 : }
     597                 : 
     598                 : void
     599               0 : nsAccessibilityService::UpdateListBullet(nsIPresShell* aPresShell,
     600                 :                                          nsIContent* aHTMLListItemContent,
     601                 :                                          bool aHasBullet)
     602                 : {
     603               0 :   nsDocAccessible* document = GetDocAccessible(aPresShell->GetDocument());
     604               0 :   if (document) {
     605               0 :     nsAccessible* accessible = document->GetAccessible(aHTMLListItemContent);
     606               0 :     if (accessible) {
     607               0 :       nsHTMLLIAccessible* listItem = accessible->AsHTMLListItem();
     608               0 :       if (listItem)
     609               0 :         listItem->UpdateBullet(aHasBullet);
     610                 :     }
     611                 :   }
     612               0 : }
     613                 : 
     614                 : void
     615               0 : nsAccessibilityService::PresShellDestroyed(nsIPresShell *aPresShell)
     616                 : {
     617                 :   // Presshell destruction will automatically destroy shells for descendant
     618                 :   // documents, so no need to worry about those. Just shut down the accessible
     619                 :   // for this one document. That keeps us from having bad behavior in case of
     620                 :   // deep bushy subtrees.
     621                 :   // When document subtree containing iframe is hidden then we don't get
     622                 :   // pagehide event for the iframe's underlying document and its presshell is
     623                 :   // destroyed before we're notified styles were changed. Shutdown the document
     624                 :   // accessible early.
     625               0 :   nsIDocument* doc = aPresShell->GetDocument();
     626               0 :   if (!doc)
     627               0 :     return;
     628                 : 
     629                 :   NS_LOG_ACCDOCDESTROY("presshell destroyed", doc)
     630                 : 
     631               0 :   nsDocAccessible* docAccessible = GetDocAccessibleFromCache(doc);
     632               0 :   if (docAccessible)
     633               0 :     docAccessible->Shutdown();
     634                 : }
     635                 : 
     636                 : void
     637               0 : nsAccessibilityService::PresShellActivated(nsIPresShell* aPresShell)
     638                 : {
     639               0 :   nsIDocument* DOMDoc = aPresShell->GetDocument();
     640               0 :   if (DOMDoc) {
     641               0 :     nsDocAccessible* document = GetDocAccessibleFromCache(DOMDoc);
     642               0 :     if (document) {
     643               0 :       nsRootAccessible* rootDocument = document->RootAccessible();
     644               0 :       NS_ASSERTION(rootDocument, "Entirely broken tree: no root document!");
     645               0 :       if (rootDocument)
     646               0 :         rootDocument->DocumentActivated(document);
     647                 :     }
     648                 :   }
     649               0 : }
     650                 : 
     651                 : void
     652               0 : nsAccessibilityService::RecreateAccessible(nsIPresShell* aPresShell,
     653                 :                                            nsIContent* aContent)
     654                 : {
     655               0 :   nsDocAccessible* document = GetDocAccessible(aPresShell->GetDocument());
     656               0 :   if (document) {
     657                 :     document->HandleNotification<nsDocAccessible, nsIContent>
     658               0 :       (document, &nsDocAccessible::RecreateAccessible, aContent);
     659                 :   }
     660               0 : }
     661                 : 
     662                 : ////////////////////////////////////////////////////////////////////////////////
     663                 : // nsIAccessibleRetrieval
     664                 : 
     665                 : NS_IMETHODIMP
     666               0 : nsAccessibilityService::GetApplicationAccessible(nsIAccessible **aAccessibleApplication)
     667                 : {
     668               0 :   NS_ENSURE_ARG_POINTER(aAccessibleApplication);
     669                 : 
     670               0 :   NS_IF_ADDREF(*aAccessibleApplication = nsAccessNode::GetApplicationAccessible());
     671               0 :   return NS_OK;
     672                 : }
     673                 : 
     674                 : NS_IMETHODIMP
     675               0 : nsAccessibilityService::GetAccessibleFor(nsIDOMNode *aNode,
     676                 :                                          nsIAccessible **aAccessible)
     677                 : {
     678               0 :   NS_ENSURE_ARG_POINTER(aAccessible);
     679               0 :   *aAccessible = nsnull;
     680               0 :   if (!aNode)
     681               0 :     return NS_OK;
     682                 : 
     683               0 :   nsCOMPtr<nsINode> node(do_QueryInterface(aNode));
     684               0 :   if (!node)
     685               0 :     return NS_ERROR_INVALID_ARG;
     686                 : 
     687               0 :   NS_IF_ADDREF(*aAccessible = GetAccessible(node, nsnull));
     688               0 :   return NS_OK;
     689                 : }
     690                 : 
     691                 : NS_IMETHODIMP
     692               0 : nsAccessibilityService::GetStringRole(PRUint32 aRole, nsAString& aString)
     693                 : {
     694               0 :   if ( aRole >= ArrayLength(kRoleNames)) {
     695               0 :     aString.AssignLiteral("unknown");
     696               0 :     return NS_OK;
     697                 :   }
     698                 : 
     699               0 :   CopyUTF8toUTF16(kRoleNames[aRole], aString);
     700               0 :   return NS_OK;
     701                 : }
     702                 : 
     703                 : NS_IMETHODIMP
     704               0 : nsAccessibilityService::GetStringStates(PRUint32 aState, PRUint32 aExtraState,
     705                 :                                         nsIDOMDOMStringList **aStringStates)
     706                 : {
     707               0 :   nsAccessibleDOMStringList *stringStates = new nsAccessibleDOMStringList();
     708               0 :   NS_ENSURE_TRUE(stringStates, NS_ERROR_OUT_OF_MEMORY);
     709                 : 
     710               0 :   PRUint64 state = nsAccUtils::To64State(aState, aExtraState);
     711                 : 
     712                 :   // states
     713               0 :   if (state & states::UNAVAILABLE)
     714               0 :     stringStates->Add(NS_LITERAL_STRING("unavailable"));
     715               0 :   if (state & states::SELECTED)
     716               0 :     stringStates->Add(NS_LITERAL_STRING("selected"));
     717               0 :   if (state & states::FOCUSED)
     718               0 :     stringStates->Add(NS_LITERAL_STRING("focused"));
     719               0 :   if (state & states::PRESSED)
     720               0 :     stringStates->Add(NS_LITERAL_STRING("pressed"));
     721               0 :   if (state & states::CHECKED)
     722               0 :     stringStates->Add(NS_LITERAL_STRING("checked"));
     723               0 :   if (state & states::MIXED)
     724               0 :     stringStates->Add(NS_LITERAL_STRING("mixed"));
     725               0 :   if (state & states::READONLY)
     726               0 :     stringStates->Add(NS_LITERAL_STRING("readonly"));
     727               0 :   if (state & states::HOTTRACKED)
     728               0 :     stringStates->Add(NS_LITERAL_STRING("hottracked"));
     729               0 :   if (state & states::DEFAULT)
     730               0 :     stringStates->Add(NS_LITERAL_STRING("default"));
     731               0 :   if (state & states::EXPANDED)
     732               0 :     stringStates->Add(NS_LITERAL_STRING("expanded"));
     733               0 :   if (state & states::COLLAPSED)
     734               0 :     stringStates->Add(NS_LITERAL_STRING("collapsed"));
     735               0 :   if (state & states::BUSY)
     736               0 :     stringStates->Add(NS_LITERAL_STRING("busy"));
     737               0 :   if (state & states::FLOATING)
     738               0 :     stringStates->Add(NS_LITERAL_STRING("floating"));
     739               0 :   if (state & states::ANIMATED)
     740               0 :     stringStates->Add(NS_LITERAL_STRING("animated"));
     741               0 :   if (state & states::INVISIBLE)
     742               0 :     stringStates->Add(NS_LITERAL_STRING("invisible"));
     743               0 :   if (state & states::OFFSCREEN)
     744               0 :     stringStates->Add(NS_LITERAL_STRING("offscreen"));
     745               0 :   if (state & states::SIZEABLE)
     746               0 :     stringStates->Add(NS_LITERAL_STRING("sizeable"));
     747               0 :   if (state & states::MOVEABLE)
     748               0 :     stringStates->Add(NS_LITERAL_STRING("moveable"));
     749               0 :   if (state & states::SELFVOICING)
     750               0 :     stringStates->Add(NS_LITERAL_STRING("selfvoicing"));
     751               0 :   if (state & states::FOCUSABLE)
     752               0 :     stringStates->Add(NS_LITERAL_STRING("focusable"));
     753               0 :   if (state & states::SELECTABLE)
     754               0 :     stringStates->Add(NS_LITERAL_STRING("selectable"));
     755               0 :   if (state & states::LINKED)
     756               0 :     stringStates->Add(NS_LITERAL_STRING("linked"));
     757               0 :   if (state & states::TRAVERSED)
     758               0 :     stringStates->Add(NS_LITERAL_STRING("traversed"));
     759               0 :   if (state & states::MULTISELECTABLE)
     760               0 :     stringStates->Add(NS_LITERAL_STRING("multiselectable"));
     761               0 :   if (state & states::EXTSELECTABLE)
     762               0 :     stringStates->Add(NS_LITERAL_STRING("extselectable"));
     763               0 :   if (state & states::PROTECTED)
     764               0 :     stringStates->Add(NS_LITERAL_STRING("protected"));
     765               0 :   if (state & states::HASPOPUP)
     766               0 :     stringStates->Add(NS_LITERAL_STRING("haspopup"));
     767               0 :   if (state & states::REQUIRED)
     768               0 :     stringStates->Add(NS_LITERAL_STRING("required"));
     769               0 :   if (state & states::ALERT)
     770               0 :     stringStates->Add(NS_LITERAL_STRING("alert"));
     771               0 :   if (state & states::INVALID)
     772               0 :     stringStates->Add(NS_LITERAL_STRING("invalid"));
     773               0 :   if (state & states::CHECKABLE)
     774               0 :     stringStates->Add(NS_LITERAL_STRING("checkable"));
     775                 : 
     776                 :   // extraStates
     777               0 :   if (state & states::SUPPORTS_AUTOCOMPLETION)
     778               0 :     stringStates->Add(NS_LITERAL_STRING("autocompletion"));
     779               0 :   if (state & states::DEFUNCT)
     780               0 :     stringStates->Add(NS_LITERAL_STRING("defunct"));
     781               0 :   if (state & states::SELECTABLE_TEXT)
     782               0 :     stringStates->Add(NS_LITERAL_STRING("selectable text"));
     783               0 :   if (state & states::EDITABLE)
     784               0 :     stringStates->Add(NS_LITERAL_STRING("editable"));
     785               0 :   if (state & states::ACTIVE)
     786               0 :     stringStates->Add(NS_LITERAL_STRING("active"));
     787               0 :   if (state & states::MODAL)
     788               0 :     stringStates->Add(NS_LITERAL_STRING("modal"));
     789               0 :   if (state & states::MULTI_LINE)
     790               0 :     stringStates->Add(NS_LITERAL_STRING("multi line"));
     791               0 :   if (state & states::HORIZONTAL)
     792               0 :     stringStates->Add(NS_LITERAL_STRING("horizontal"));
     793               0 :   if (state & states::OPAQUE1)
     794               0 :     stringStates->Add(NS_LITERAL_STRING("opaque"));
     795               0 :   if (state & states::SINGLE_LINE)
     796               0 :     stringStates->Add(NS_LITERAL_STRING("single line"));
     797               0 :   if (state & states::TRANSIENT)
     798               0 :     stringStates->Add(NS_LITERAL_STRING("transient"));
     799               0 :   if (state & states::VERTICAL)
     800               0 :     stringStates->Add(NS_LITERAL_STRING("vertical"));
     801               0 :   if (state & states::STALE)
     802               0 :     stringStates->Add(NS_LITERAL_STRING("stale"));
     803               0 :   if (state & states::ENABLED)
     804               0 :     stringStates->Add(NS_LITERAL_STRING("enabled"));
     805               0 :   if (state & states::SENSITIVE)
     806               0 :     stringStates->Add(NS_LITERAL_STRING("sensitive"));
     807               0 :   if (state & states::EXPANDABLE)
     808               0 :     stringStates->Add(NS_LITERAL_STRING("expandable"));
     809                 : 
     810                 :   //unknown states
     811               0 :   PRUint32 stringStatesLength = 0;
     812               0 :   stringStates->GetLength(&stringStatesLength);
     813               0 :   if (!stringStatesLength)
     814               0 :     stringStates->Add(NS_LITERAL_STRING("unknown"));
     815                 : 
     816               0 :   NS_ADDREF(*aStringStates = stringStates);
     817               0 :   return NS_OK;
     818                 : }
     819                 : 
     820                 : // nsIAccessibleRetrieval::getStringEventType()
     821                 : NS_IMETHODIMP
     822               0 : nsAccessibilityService::GetStringEventType(PRUint32 aEventType,
     823                 :                                            nsAString& aString)
     824                 : {
     825               0 :   NS_ASSERTION(nsIAccessibleEvent::EVENT_LAST_ENTRY == ArrayLength(kEventTypeNames),
     826                 :                "nsIAccessibleEvent constants are out of sync to kEventTypeNames");
     827                 : 
     828               0 :   if (aEventType >= ArrayLength(kEventTypeNames)) {
     829               0 :     aString.AssignLiteral("unknown");
     830               0 :     return NS_OK;
     831                 :   }
     832                 : 
     833               0 :   CopyUTF8toUTF16(kEventTypeNames[aEventType], aString);
     834               0 :   return NS_OK;
     835                 : }
     836                 : 
     837                 : // nsIAccessibleRetrieval::getStringRelationType()
     838                 : NS_IMETHODIMP
     839               0 : nsAccessibilityService::GetStringRelationType(PRUint32 aRelationType,
     840                 :                                               nsAString& aString)
     841                 : {
     842               0 :   if (aRelationType >= ArrayLength(kRelationTypeNames)) {
     843               0 :     aString.AssignLiteral("unknown");
     844               0 :     return NS_OK;
     845                 :   }
     846                 : 
     847               0 :   CopyUTF8toUTF16(kRelationTypeNames[aRelationType], aString);
     848               0 :   return NS_OK;
     849                 : }
     850                 : 
     851                 : NS_IMETHODIMP
     852               0 : nsAccessibilityService::GetAccessibleFromCache(nsIDOMNode* aNode,
     853                 :                                                nsIAccessible** aAccessible)
     854                 : {
     855               0 :   NS_ENSURE_ARG_POINTER(aAccessible);
     856               0 :   *aAccessible = nsnull;
     857               0 :   if (!aNode)
     858               0 :     return NS_OK;
     859                 : 
     860               0 :   nsCOMPtr<nsINode> node(do_QueryInterface(aNode));
     861               0 :   if (!node)
     862               0 :     return NS_ERROR_INVALID_ARG;
     863                 : 
     864                 :   // Search for an accessible in each of our per document accessible object
     865                 :   // caches. If we don't find it, and the given node is itself a document, check
     866                 :   // our cache of document accessibles (document cache). Note usually shutdown
     867                 :   // document accessibles are not stored in the document cache, however an
     868                 :   // "unofficially" shutdown document (i.e. not from nsAccDocManager) can still
     869                 :   // exist in the document cache.
     870               0 :   nsAccessible* accessible = FindAccessibleInCache(node);
     871               0 :   if (!accessible) {
     872               0 :     nsCOMPtr<nsIDocument> document(do_QueryInterface(node));
     873               0 :     if (document)
     874               0 :       accessible = GetDocAccessibleFromCache(document);
     875                 :   }
     876                 : 
     877               0 :   NS_IF_ADDREF(*aAccessible = accessible);
     878               0 :   return NS_OK;
     879                 : }
     880                 : 
     881                 : NS_IMETHODIMP
     882               0 : nsAccessibilityService::CreateAccessiblePivot(nsIAccessible* aRoot,
     883                 :                                               nsIAccessiblePivot** aPivot)
     884                 : {
     885               0 :   NS_ENSURE_ARG_POINTER(aPivot);
     886               0 :   NS_ENSURE_ARG(aRoot);
     887               0 :   *aPivot = nsnull;
     888                 : 
     889               0 :   nsRefPtr<nsAccessible> accessibleRoot(do_QueryObject(aRoot));
     890               0 :   NS_ENSURE_TRUE(accessibleRoot, NS_ERROR_INVALID_ARG);
     891                 : 
     892               0 :   nsAccessiblePivot* pivot = new nsAccessiblePivot(accessibleRoot);
     893               0 :   NS_ADDREF(*aPivot = pivot);
     894                 : 
     895               0 :   return NS_OK;
     896                 : }
     897                 : 
     898                 : ////////////////////////////////////////////////////////////////////////////////
     899                 : // nsAccessibilityService public
     900                 : 
     901                 : nsAccessible*
     902               0 : nsAccessibilityService::GetAccessible(nsINode* aNode, nsIPresShell* aPresShell)
     903                 : {
     904               0 :   NS_PRECONDITION(aNode, "Getting an accessible for null node! Crash.");
     905                 : 
     906                 :   // XXX handle the presshell
     907               0 :   nsDocAccessible* document = GetDocAccessible(aNode->OwnerDoc());
     908               0 :   return document ? document->GetAccessible(aNode) : nsnull;
     909                 : }
     910                 : 
     911               0 : static bool HasRelatedContent(nsIContent *aContent)
     912                 : {
     913               0 :   nsAutoString id;
     914               0 :   if (!aContent || !nsCoreUtils::GetID(aContent, id) || id.IsEmpty()) {
     915               0 :     return false;
     916                 :   }
     917                 : 
     918                 :   // If the given ID is referred by relation attribute then create an accessible
     919                 :   // for it. Take care of HTML elements only for now.
     920               0 :   return aContent->IsHTML() &&
     921               0 :     nsAccUtils::GetDocAccessibleFor(aContent)->IsDependentID(id);
     922                 : }
     923                 : 
     924                 : nsAccessible*
     925               0 : nsAccessibilityService::GetOrCreateAccessible(nsINode* aNode,
     926                 :                                               nsDocAccessible* aDoc,
     927                 :                                               bool* aIsSubtreeHidden)
     928                 : {
     929               0 :   if (!aDoc || !aNode || gIsShutdown)
     930               0 :     return nsnull;
     931                 : 
     932               0 :   if (aIsSubtreeHidden)
     933               0 :     *aIsSubtreeHidden = false;
     934                 : 
     935                 :   // Check to see if we already have an accessible for this node in the cache.
     936               0 :   nsAccessible* cachedAccessible = aDoc->GetAccessible(aNode);
     937               0 :   if (cachedAccessible)
     938               0 :     return cachedAccessible;
     939                 : 
     940                 :   // No cache entry, so we must create the accessible.
     941                 : 
     942               0 :   if (aNode->IsNodeOfType(nsINode::eDOCUMENT)) {
     943                 :     // If it's document node then ask accessible document loader for
     944                 :     // document accessible, otherwise return null.
     945               0 :     nsCOMPtr<nsIDocument> document(do_QueryInterface(aNode));
     946               0 :     return GetDocAccessible(document);
     947                 :   }
     948                 : 
     949                 :   // We have a content node.
     950               0 :   if (!aNode->IsInDoc()) {
     951               0 :     NS_WARNING("Creating accessible for node with no document");
     952               0 :     return nsnull;
     953                 :   }
     954                 : 
     955               0 :   if (aNode->OwnerDoc() != aDoc->GetDocumentNode()) {
     956               0 :     NS_ERROR("Creating accessible for wrong document");
     957               0 :     return nsnull;
     958                 :   }
     959                 : 
     960               0 :   nsCOMPtr<nsIContent> content(do_QueryInterface(aNode));
     961               0 :   if (!content)
     962               0 :     return nsnull;
     963                 : 
     964                 :   // Frames can be deallocated when we flush layout, or when we call into code
     965                 :   // that can flush layout, either directly, or via DOM manipulation, or some
     966                 :   // CSS styles like :hover. We use the weak frame checks to avoid calling
     967                 :   // methods on a dead frame pointer.
     968               0 :   nsWeakFrame weakFrame = content->GetPrimaryFrame();
     969                 : 
     970                 :   // Check frame and its visibility. Note, hidden frame allows visible
     971                 :   // elements in subtree.
     972               0 :   if (!weakFrame.GetFrame() || !weakFrame->GetStyleVisibility()->IsVisible()) {
     973               0 :     if (aIsSubtreeHidden && !weakFrame.GetFrame())
     974               0 :       *aIsSubtreeHidden = true;
     975                 : 
     976               0 :     return nsnull;
     977                 :   }
     978                 : 
     979               0 :   if (weakFrame.GetFrame()->GetContent() != content) {
     980                 :     // Not the main content for this frame. This happens because <area>
     981                 :     // elements return the image frame as their primary frame. The main content
     982                 :     // for the image frame is the image content. If the frame is not an image
     983                 :     // frame or the node is not an area element then null is returned.
     984                 :     // This setup will change when bug 135040 is fixed. Make sure we don't
     985                 :     // create area accessible here. Hopefully assertion below will handle that.
     986                 : 
     987                 : #ifdef DEBUG
     988               0 :   nsImageFrame* imageFrame = do_QueryFrame(weakFrame.GetFrame());
     989               0 :   NS_ASSERTION(imageFrame && content->IsHTML() && content->Tag() == nsGkAtoms::area,
     990                 :                "Unknown case of not main content for the frame!");
     991                 : #endif
     992               0 :     return nsnull;
     993                 :   }
     994                 : 
     995                 : #ifdef DEBUG
     996               0 :   nsImageFrame* imageFrame = do_QueryFrame(weakFrame.GetFrame());
     997               0 :   NS_ASSERTION(!imageFrame || !content->IsHTML() || content->Tag() != nsGkAtoms::area,
     998                 :                "Image map manages the area accessible creation!");
     999                 : #endif
    1000                 : 
    1001                 :   nsDocAccessible* docAcc =
    1002               0 :     GetAccService()->GetDocAccessible(aNode->OwnerDoc());
    1003               0 :   if (!docAcc) {
    1004               0 :     NS_NOTREACHED("Node has no host document accessible!");
    1005               0 :     return nsnull;
    1006                 :   }
    1007                 : 
    1008                 :   // Attempt to create an accessible based on what we know.
    1009               0 :   nsRefPtr<nsAccessible> newAcc;
    1010                 : 
    1011                 :   // Create accessible for visible text frames.
    1012               0 :   if (content->IsNodeOfType(nsINode::eTEXT)) {
    1013               0 :     nsAutoString text;
    1014               0 :     weakFrame->GetRenderedText(&text, nsnull, nsnull, 0, PR_UINT32_MAX);
    1015               0 :     if (text.IsEmpty()) {
    1016               0 :       if (aIsSubtreeHidden)
    1017               0 :         *aIsSubtreeHidden = true;
    1018                 : 
    1019               0 :       return nsnull;
    1020                 :     }
    1021                 : 
    1022               0 :     newAcc = weakFrame->CreateAccessible();
    1023               0 :     if (docAcc->BindToDocument(newAcc, nsnull)) {
    1024               0 :       newAcc->AsTextLeaf()->SetText(text);
    1025               0 :       return newAcc;
    1026                 :     }
    1027                 : 
    1028               0 :     return nsnull;
    1029                 :   }
    1030                 : 
    1031               0 :   bool isHTML = content->IsHTML();
    1032               0 :   if (isHTML && content->Tag() == nsGkAtoms::map) {
    1033                 :     // Create hyper text accessible for HTML map if it is used to group links
    1034                 :     // (see http://www.w3.org/TR/WCAG10-HTML-TECHS/#group-bypass). If the HTML
    1035                 :     // map rect is empty then it is used for links grouping. Otherwise it should
    1036                 :     // be used in conjunction with HTML image element and in this case we don't
    1037                 :     // create any accessible for it and don't walk into it. The accessibles for
    1038                 :     // HTML area (nsHTMLAreaAccessible) the map contains are attached as
    1039                 :     // children of the appropriate accessible for HTML image
    1040                 :     // (nsHTMLImageAccessible).
    1041               0 :     if (nsLayoutUtils::GetAllInFlowRectsUnion(weakFrame,
    1042               0 :                                               weakFrame->GetParent()).IsEmpty()) {
    1043               0 :       if (aIsSubtreeHidden)
    1044               0 :         *aIsSubtreeHidden = true;
    1045                 : 
    1046               0 :       return nsnull;
    1047                 :     }
    1048                 : 
    1049               0 :     newAcc = new nsHyperTextAccessibleWrap(content, docAcc);
    1050               0 :     if (docAcc->BindToDocument(newAcc, nsAccUtils::GetRoleMapEntry(aNode)))
    1051               0 :       return newAcc;
    1052               0 :     return nsnull;
    1053                 :   }
    1054                 : 
    1055               0 :   nsRoleMapEntry *roleMapEntry = nsAccUtils::GetRoleMapEntry(aNode);
    1056               0 :   if (roleMapEntry && !nsCRT::strcmp(roleMapEntry->roleString, "presentation")) {
    1057                 :     // Ignore presentation role if element is focusable (focus event shouldn't
    1058                 :     // be ever lost and should be sensible).
    1059               0 :     if (content->IsFocusable())
    1060               0 :       roleMapEntry = nsnull;
    1061                 :     else
    1062               0 :       return nsnull;
    1063                 :   }
    1064                 : 
    1065               0 :   if (weakFrame.IsAlive() && !newAcc && isHTML) {  // HTML accessibles
    1066               0 :     bool tryTagNameOrFrame = true;
    1067                 : 
    1068               0 :     nsIAtom *frameType = weakFrame.GetFrame()->GetType();
    1069                 : 
    1070                 :     bool partOfHTMLTable =
    1071                 :       frameType == nsGkAtoms::tableCaptionFrame ||
    1072                 :       frameType == nsGkAtoms::tableCellFrame ||
    1073                 :       frameType == nsGkAtoms::tableRowGroupFrame ||
    1074               0 :       frameType == nsGkAtoms::tableRowFrame;
    1075                 : 
    1076               0 :     if (partOfHTMLTable) {
    1077                 :       // Table-related frames don't get table-related roles
    1078                 :       // unless they are inside a table, but they may still get generic
    1079                 :       // accessibles
    1080               0 :       nsIContent *tableContent = content;
    1081               0 :       while ((tableContent = tableContent->GetParent()) != nsnull) {
    1082               0 :         nsIFrame *tableFrame = tableContent->GetPrimaryFrame();
    1083               0 :         if (!tableFrame)
    1084               0 :           continue;
    1085                 : 
    1086               0 :         if (tableFrame->GetType() == nsGkAtoms::tableOuterFrame) {
    1087               0 :           nsAccessible* tableAccessible = aDoc->GetAccessible(tableContent);
    1088                 : 
    1089               0 :           if (tableAccessible) {
    1090               0 :             if (!roleMapEntry) {
    1091               0 :               roles::Role role = tableAccessible->Role();
    1092                 :               // No ARIA role and not in table: override role. For example,
    1093                 :               // <table role="label"><td>content</td></table>
    1094               0 :               if (role != roles::TABLE && role != roles::TREE_TABLE)
    1095               0 :                 roleMapEntry = &nsARIAMap::gEmptyRoleMap;
    1096                 :             }
    1097                 : 
    1098               0 :             break;
    1099                 :           }
    1100                 : 
    1101                 : #ifdef DEBUG
    1102                 :           nsRoleMapEntry *tableRoleMapEntry =
    1103               0 :             nsAccUtils::GetRoleMapEntry(tableContent);
    1104               0 :           NS_ASSERTION(tableRoleMapEntry &&
    1105                 :                        !nsCRT::strcmp(tableRoleMapEntry->roleString, "presentation"),
    1106                 :                        "No accessible for parent table and it didn't have role of presentation");
    1107                 : #endif
    1108                 : 
    1109               0 :           if (!roleMapEntry && !content->IsFocusable()) {
    1110                 :             // Table-related descendants of presentation table are also
    1111                 :             // presentation if they aren't focusable and have not explicit ARIA
    1112                 :             // role (don't create accessibles for them unless they need to fire
    1113                 :             // focus events).
    1114               0 :             return nsnull;
    1115                 :           }
    1116                 : 
    1117                 :           // otherwise create ARIA based accessible.
    1118               0 :           tryTagNameOrFrame = false;
    1119               0 :           break;
    1120                 :         }
    1121                 : 
    1122               0 :         if (tableContent->Tag() == nsGkAtoms::table) {
    1123                 :           // Stop before we are fooled by any additional table ancestors
    1124                 :           // This table cell frameis part of a separate ancestor table.
    1125               0 :           tryTagNameOrFrame = false;
    1126               0 :           break;
    1127                 :         }
    1128                 :       }
    1129                 : 
    1130               0 :       if (!tableContent)
    1131               0 :         tryTagNameOrFrame = false;
    1132                 :     }
    1133                 : 
    1134               0 :     if (roleMapEntry) {
    1135                 :       // Create ARIA grid/treegrid accessibles if node is not of a child or
    1136                 :       // valid child of HTML table and is not a HTML table.
    1137               0 :       if ((!partOfHTMLTable || !tryTagNameOrFrame) &&
    1138                 :           frameType != nsGkAtoms::tableOuterFrame) {
    1139                 : 
    1140               0 :         if (roleMapEntry->role == roles::TABLE ||
    1141                 :             roleMapEntry->role == roles::TREE_TABLE) {
    1142               0 :           newAcc = new nsARIAGridAccessibleWrap(content, docAcc);
    1143                 : 
    1144               0 :         } else if (roleMapEntry->role == roles::GRID_CELL ||
    1145                 :             roleMapEntry->role == roles::ROWHEADER ||
    1146                 :             roleMapEntry->role == roles::COLUMNHEADER) {
    1147               0 :           newAcc = new nsARIAGridCellAccessibleWrap(content, docAcc);
    1148                 :         }
    1149                 :       }
    1150                 :     }
    1151                 : 
    1152               0 :     if (!newAcc && tryTagNameOrFrame) {
    1153                 :       // Prefer to use markup (mostly tag name, perhaps attributes) to
    1154                 :       // decide if and what kind of accessible to create.
    1155                 :       // The method creates accessibles for table related content too therefore
    1156                 :       // we do not call it if accessibles for table related content are
    1157                 :       // prevented above.
    1158                 :       newAcc = CreateHTMLAccessibleByMarkup(weakFrame.GetFrame(), content,
    1159               0 :                                             docAcc);
    1160                 : 
    1161               0 :       if (!newAcc) {
    1162                 :         // Do not create accessible object subtrees for non-rendered table
    1163                 :         // captions. This could not be done in
    1164                 :         // nsTableCaptionFrame::GetAccessible() because the descendants of
    1165                 :         // the table caption would still be created. By setting
    1166                 :         // *aIsSubtreeHidden = true we ensure that no descendant accessibles
    1167                 :         // are created.
    1168               0 :         nsIFrame* f = weakFrame.GetFrame();
    1169               0 :         if (!f) {
    1170               0 :           f = aDoc->PresShell()->GetRealPrimaryFrameFor(content);
    1171                 :         }
    1172               0 :         if (f->GetType() == nsGkAtoms::tableCaptionFrame &&
    1173               0 :            f->GetRect().IsEmpty()) {
    1174                 :           // XXX This is not the ideal place for this code, but right now there
    1175                 :           // is no better place:
    1176               0 :           if (aIsSubtreeHidden)
    1177               0 :             *aIsSubtreeHidden = true;
    1178                 : 
    1179               0 :           return nsnull;
    1180                 :         }
    1181                 : 
    1182                 :         // Try using frame to do it.
    1183               0 :         newAcc = f->CreateAccessible();
    1184                 :       }
    1185                 :     }
    1186                 :   }
    1187                 : 
    1188               0 :   if (!newAcc) {
    1189                 :     // Elements may implement nsIAccessibleProvider via XBL. This allows them to
    1190                 :     // say what kind of accessible to create.
    1191               0 :     newAcc = CreateAccessibleByType(content, docAcc);
    1192                 :   }
    1193                 : 
    1194               0 :   if (!newAcc) {
    1195                 :     // Create generic accessibles for SVG and MathML nodes.
    1196               0 :     if (content->IsSVG(nsGkAtoms::svg)) {
    1197                 :       newAcc = new nsEnumRoleAccessible(content, docAcc,
    1198               0 :                                         roles::DIAGRAM);
    1199                 :     }
    1200               0 :     else if (content->IsMathML(nsGkAtoms::math)) {
    1201                 :       newAcc = new nsEnumRoleAccessible(content, docAcc,
    1202               0 :                                         roles::EQUATION);
    1203                 :     }
    1204                 :   }
    1205                 : 
    1206               0 :   if (!newAcc) {
    1207                 :     newAcc = CreateAccessibleForDeckChild(weakFrame.GetFrame(), content,
    1208               0 :                                           docAcc);
    1209                 :   }
    1210                 : 
    1211                 :   // If no accessible, see if we need to create a generic accessible because
    1212                 :   // of some property that makes this object interesting
    1213                 :   // We don't do this for <body>, <html>, <window>, <dialog> etc. which 
    1214                 :   // correspond to the doc accessible and will be created in any case
    1215               0 :   if (!newAcc && content->Tag() != nsGkAtoms::body && content->GetParent() && 
    1216               0 :       ((weakFrame.GetFrame() && weakFrame.GetFrame()->IsFocusable()) ||
    1217               0 :        (isHTML && nsCoreUtils::HasClickListener(content)) ||
    1218               0 :        HasUniversalAriaProperty(content) || roleMapEntry ||
    1219               0 :        HasRelatedContent(content) || nsCoreUtils::IsXLink(content))) {
    1220                 :     // This content is focusable or has an interesting dynamic content accessibility property.
    1221                 :     // If it's interesting we need it in the accessibility hierarchy so that events or
    1222                 :     // other accessibles can point to it, or so that it can hold a state, etc.
    1223               0 :     if (isHTML) {
    1224                 :       // Interesting HTML container which may have selectable text and/or embedded objects
    1225               0 :       newAcc = new nsHyperTextAccessibleWrap(content, docAcc);
    1226                 :     }
    1227                 :     else {  // XUL, SVG, MathML etc.
    1228                 :       // Interesting generic non-HTML container
    1229               0 :       newAcc = new nsAccessibleWrap(content, docAcc);
    1230                 :     }
    1231                 :   }
    1232                 : 
    1233               0 :   return docAcc->BindToDocument(newAcc, roleMapEntry) ? newAcc : nsnull;
    1234                 : }
    1235                 : 
    1236                 : ////////////////////////////////////////////////////////////////////////////////
    1237                 : // nsAccessibilityService private
    1238                 : 
    1239                 : bool
    1240               0 : nsAccessibilityService::Init()
    1241                 : {
    1242                 :   // Initialize accessible document manager.
    1243               0 :   if (!nsAccDocManager::Init())
    1244               0 :     return false;
    1245                 : 
    1246                 :   // Add observers.
    1247                 :   nsCOMPtr<nsIObserverService> observerService =
    1248               0 :     mozilla::services::GetObserverService();
    1249               0 :   if (!observerService)
    1250               0 :     return false;
    1251                 : 
    1252               0 :   observerService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false);
    1253                 : 
    1254                 :   // Initialize accessibility.
    1255               0 :   nsAccessNodeWrap::InitAccessibility();
    1256                 : 
    1257               0 :   gIsShutdown = false;
    1258               0 :   return true;
    1259                 : }
    1260                 : 
    1261                 : void
    1262               0 : nsAccessibilityService::Shutdown()
    1263                 : {
    1264                 :   // Remove observers.
    1265                 :   nsCOMPtr<nsIObserverService> observerService =
    1266               0 :       mozilla::services::GetObserverService();
    1267               0 :   if (observerService)
    1268               0 :     observerService->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID);
    1269                 : 
    1270                 :   // Stop accessible document loader.
    1271               0 :   nsAccDocManager::Shutdown();
    1272                 : 
    1273                 :   // Application is going to be closed, shutdown accessibility and mark
    1274                 :   // accessibility service as shutdown to prevent calls of its methods.
    1275                 :   // Don't null accessibility service static member at this point to be safe
    1276                 :   // if someone will try to operate with it.
    1277                 : 
    1278               0 :   NS_ASSERTION(!gIsShutdown, "Accessibility was shutdown already");
    1279                 : 
    1280               0 :   gIsShutdown = true;
    1281                 : 
    1282               0 :   nsAccessNodeWrap::ShutdownAccessibility();
    1283               0 : }
    1284                 : 
    1285                 : bool
    1286               0 : nsAccessibilityService::HasUniversalAriaProperty(nsIContent *aContent)
    1287                 : {
    1288                 :   // ARIA attributes that take token values (NMTOKEN, bool) are special cased
    1289                 :   // because of special value "undefined" (see HasDefinedARIAToken).
    1290               0 :   return nsAccUtils::HasDefinedARIAToken(aContent, nsGkAtoms::aria_atomic) ||
    1291               0 :          nsAccUtils::HasDefinedARIAToken(aContent, nsGkAtoms::aria_busy) ||
    1292               0 :          aContent->HasAttr(kNameSpaceID_None, nsGkAtoms::aria_controls) ||
    1293               0 :          aContent->HasAttr(kNameSpaceID_None, nsGkAtoms::aria_describedby) ||
    1294               0 :          aContent->HasAttr(kNameSpaceID_None, nsGkAtoms::aria_disabled) ||
    1295               0 :          nsAccUtils::HasDefinedARIAToken(aContent, nsGkAtoms::aria_dropeffect) ||
    1296               0 :          aContent->HasAttr(kNameSpaceID_None, nsGkAtoms::aria_flowto) ||
    1297               0 :          nsAccUtils::HasDefinedARIAToken(aContent, nsGkAtoms::aria_grabbed) ||
    1298               0 :          nsAccUtils::HasDefinedARIAToken(aContent, nsGkAtoms::aria_haspopup) ||
    1299               0 :          aContent->HasAttr(kNameSpaceID_None, nsGkAtoms::aria_hidden) ||
    1300               0 :          nsAccUtils::HasDefinedARIAToken(aContent, nsGkAtoms::aria_invalid) ||
    1301               0 :          aContent->HasAttr(kNameSpaceID_None, nsGkAtoms::aria_label) ||
    1302               0 :          aContent->HasAttr(kNameSpaceID_None, nsGkAtoms::aria_labelledby) ||
    1303               0 :          nsAccUtils::HasDefinedARIAToken(aContent, nsGkAtoms::aria_live) ||
    1304               0 :          nsAccUtils::HasDefinedARIAToken(aContent, nsGkAtoms::aria_owns) ||
    1305               0 :          nsAccUtils::HasDefinedARIAToken(aContent, nsGkAtoms::aria_relevant);
    1306                 : }
    1307                 : 
    1308                 : already_AddRefed<nsAccessible>
    1309               0 : nsAccessibilityService::CreateAccessibleByType(nsIContent* aContent,
    1310                 :                                                nsDocAccessible* aDoc)
    1311                 : {
    1312               0 :   nsCOMPtr<nsIAccessibleProvider> accessibleProvider(do_QueryInterface(aContent));
    1313               0 :   if (!accessibleProvider)
    1314               0 :     return nsnull;
    1315                 : 
    1316                 :   PRInt32 type;
    1317               0 :   nsresult rv = accessibleProvider->GetAccessibleType(&type);
    1318               0 :   if (NS_FAILED(rv))
    1319               0 :     return nsnull;
    1320                 : 
    1321               0 :   if (type == nsIAccessibleProvider::OuterDoc) {
    1322               0 :     nsAccessible* accessible = new nsOuterDocAccessible(aContent, aDoc);
    1323               0 :     NS_IF_ADDREF(accessible);
    1324               0 :     return accessible;
    1325                 :   }
    1326                 : 
    1327               0 :   nsAccessible* accessible = nsnull;
    1328               0 :   switch (type)
    1329                 :   {
    1330                 : #ifdef MOZ_XUL
    1331                 :     case nsIAccessibleProvider::NoAccessible:
    1332               0 :       return nsnull;
    1333                 : 
    1334                 :     // XUL controls
    1335                 :     case nsIAccessibleProvider::XULAlert:
    1336               0 :       accessible = new nsXULAlertAccessible(aContent, aDoc);
    1337               0 :       break;
    1338                 : 
    1339                 :     case nsIAccessibleProvider::XULButton:
    1340               0 :       accessible = new nsXULButtonAccessible(aContent, aDoc);
    1341               0 :       break;
    1342                 : 
    1343                 :     case nsIAccessibleProvider::XULCheckbox:
    1344               0 :       accessible = new nsXULCheckboxAccessible(aContent, aDoc);
    1345               0 :       break;
    1346                 : 
    1347                 :     case nsIAccessibleProvider::XULColorPicker:
    1348               0 :       accessible = new nsXULColorPickerAccessible(aContent, aDoc);
    1349               0 :       break;
    1350                 : 
    1351                 :     case nsIAccessibleProvider::XULColorPickerTile:
    1352               0 :       accessible = new nsXULColorPickerTileAccessible(aContent, aDoc);
    1353               0 :       break;
    1354                 : 
    1355                 :     case nsIAccessibleProvider::XULCombobox:
    1356               0 :       accessible = new nsXULComboboxAccessible(aContent, aDoc);
    1357               0 :       break;
    1358                 : 
    1359                 :     case nsIAccessibleProvider::XULDropmarker:
    1360               0 :       accessible = new nsXULDropmarkerAccessible(aContent, aDoc);
    1361               0 :       break;
    1362                 : 
    1363                 :     case nsIAccessibleProvider::XULGroupbox:
    1364               0 :       accessible = new nsXULGroupboxAccessible(aContent, aDoc);
    1365               0 :       break;
    1366                 : 
    1367                 :     case nsIAccessibleProvider::XULImage:
    1368                 :     {
    1369                 :       // Don't include nameless images in accessible tree.
    1370               0 :       if (!aContent->HasAttr(kNameSpaceID_None,
    1371               0 :                              nsGkAtoms::tooltiptext))
    1372               0 :         return nsnull;
    1373                 : 
    1374               0 :       accessible = new nsHTMLImageAccessibleWrap(aContent, aDoc);
    1375               0 :       break;
    1376                 : 
    1377                 :     }
    1378                 :     case nsIAccessibleProvider::XULLink:
    1379               0 :       accessible = new nsXULLinkAccessible(aContent, aDoc);
    1380               0 :       break;
    1381                 : 
    1382                 :     case nsIAccessibleProvider::XULListbox:
    1383               0 :       accessible = new nsXULListboxAccessibleWrap(aContent, aDoc);
    1384               0 :       break;
    1385                 : 
    1386                 :     case nsIAccessibleProvider::XULListCell:
    1387               0 :       accessible = new nsXULListCellAccessibleWrap(aContent, aDoc);
    1388               0 :       break;
    1389                 : 
    1390                 :     case nsIAccessibleProvider::XULListHead:
    1391               0 :       accessible = new nsXULColumnsAccessible(aContent, aDoc);
    1392               0 :       break;
    1393                 : 
    1394                 :     case nsIAccessibleProvider::XULListHeader:
    1395               0 :       accessible = new nsXULColumnItemAccessible(aContent, aDoc);
    1396               0 :       break;
    1397                 : 
    1398                 :     case nsIAccessibleProvider::XULListitem:
    1399               0 :       accessible = new nsXULListitemAccessible(aContent, aDoc);
    1400               0 :       break;
    1401                 : 
    1402                 :     case nsIAccessibleProvider::XULMenubar:
    1403               0 :       accessible = new nsXULMenubarAccessible(aContent, aDoc);
    1404               0 :       break;
    1405                 : 
    1406                 :     case nsIAccessibleProvider::XULMenuitem:
    1407               0 :       accessible = new nsXULMenuitemAccessibleWrap(aContent, aDoc);
    1408               0 :       break;
    1409                 : 
    1410                 :     case nsIAccessibleProvider::XULMenupopup:
    1411                 :     {
    1412                 : #ifdef MOZ_ACCESSIBILITY_ATK
    1413                 :       // ATK considers this node to be redundant when within menubars, and it makes menu
    1414                 :       // navigation with assistive technologies more difficult
    1415                 :       // XXX In the future we will should this for consistency across the nsIAccessible
    1416                 :       // implementations on each platform for a consistent scripting environment, but
    1417                 :       // then strip out redundant accessibles in the nsAccessibleWrap class for each platform.
    1418               0 :       nsIContent *parent = aContent->GetParent();
    1419               0 :       if (parent && parent->NodeInfo()->Equals(nsGkAtoms::menu,
    1420               0 :                                                kNameSpaceID_XUL))
    1421               0 :         return nsnull;
    1422                 : #endif
    1423               0 :       accessible = new nsXULMenupopupAccessible(aContent, aDoc);
    1424               0 :       break;
    1425                 : 
    1426                 :     }
    1427                 :     case nsIAccessibleProvider::XULMenuSeparator:
    1428               0 :       accessible = new nsXULMenuSeparatorAccessible(aContent, aDoc);
    1429               0 :       break;
    1430                 : 
    1431                 :     case nsIAccessibleProvider::XULPane:
    1432                 :       accessible = new nsEnumRoleAccessible(aContent, aDoc,
    1433               0 :                                             roles::PANE);
    1434               0 :       break;
    1435                 : 
    1436                 :     case nsIAccessibleProvider::XULProgressMeter:
    1437               0 :       accessible = new XULProgressMeterAccessible(aContent, aDoc);
    1438               0 :       break;
    1439                 : 
    1440                 :     case nsIAccessibleProvider::XULStatusBar:
    1441               0 :       accessible = new nsXULStatusBarAccessible(aContent, aDoc);
    1442               0 :       break;
    1443                 : 
    1444                 :     case nsIAccessibleProvider::XULScale:
    1445               0 :       accessible = new nsXULSliderAccessible(aContent, aDoc);
    1446               0 :       break;
    1447                 : 
    1448                 :     case nsIAccessibleProvider::XULRadioButton:
    1449               0 :       accessible = new nsXULRadioButtonAccessible(aContent, aDoc);
    1450               0 :       break;
    1451                 : 
    1452                 :     case nsIAccessibleProvider::XULRadioGroup:
    1453               0 :       accessible = new nsXULRadioGroupAccessible(aContent, aDoc);
    1454               0 :       break;
    1455                 : 
    1456                 :     case nsIAccessibleProvider::XULTab:
    1457               0 :       accessible = new nsXULTabAccessible(aContent, aDoc);
    1458               0 :       break;
    1459                 : 
    1460                 :     case nsIAccessibleProvider::XULTabs:
    1461               0 :       accessible = new nsXULTabsAccessible(aContent, aDoc);
    1462               0 :       break;
    1463                 : 
    1464                 :     case nsIAccessibleProvider::XULTabpanels:
    1465               0 :       accessible = new nsXULTabpanelsAccessible(aContent, aDoc);
    1466               0 :       break;
    1467                 : 
    1468                 :     case nsIAccessibleProvider::XULText:
    1469               0 :       accessible = new nsXULTextAccessible(aContent, aDoc);
    1470               0 :       break;
    1471                 : 
    1472                 :     case nsIAccessibleProvider::XULTextBox:
    1473               0 :       accessible = new nsXULTextFieldAccessible(aContent, aDoc);
    1474               0 :       break;
    1475                 : 
    1476                 :     case nsIAccessibleProvider::XULThumb:
    1477               0 :       accessible = new nsXULThumbAccessible(aContent, aDoc);
    1478               0 :       break;
    1479                 : 
    1480                 :     case nsIAccessibleProvider::XULTree:
    1481               0 :       return CreateAccessibleForXULTree(aContent, aDoc);
    1482                 : 
    1483                 :     case nsIAccessibleProvider::XULTreeColumns:
    1484               0 :       accessible = new nsXULTreeColumnsAccessible(aContent, aDoc);
    1485               0 :       break;
    1486                 : 
    1487                 :     case nsIAccessibleProvider::XULTreeColumnItem:
    1488               0 :       accessible = new nsXULColumnItemAccessible(aContent, aDoc);
    1489               0 :       break;
    1490                 : 
    1491                 :     case nsIAccessibleProvider::XULToolbar:
    1492               0 :       accessible = new nsXULToolbarAccessible(aContent, aDoc);
    1493               0 :       break;
    1494                 : 
    1495                 :     case nsIAccessibleProvider::XULToolbarSeparator:
    1496               0 :       accessible = new nsXULToolbarSeparatorAccessible(aContent, aDoc);
    1497               0 :       break;
    1498                 : 
    1499                 :     case nsIAccessibleProvider::XULTooltip:
    1500               0 :       accessible = new nsXULTooltipAccessible(aContent, aDoc);
    1501               0 :       break;
    1502                 : 
    1503                 :     case nsIAccessibleProvider::XULToolbarButton:
    1504               0 :       accessible = new nsXULToolbarButtonAccessible(aContent, aDoc);
    1505               0 :       break;
    1506                 : 
    1507                 : #endif // MOZ_XUL
    1508                 : 
    1509                 :     // XForms elements
    1510                 :     case nsIAccessibleProvider::XFormsContainer:
    1511               0 :       accessible = new nsXFormsContainerAccessible(aContent, aDoc);
    1512               0 :       break;
    1513                 : 
    1514                 :     case nsIAccessibleProvider::XFormsLabel:
    1515               0 :       accessible = new nsXFormsLabelAccessible(aContent, aDoc);
    1516               0 :       break;
    1517                 : 
    1518                 :     case nsIAccessibleProvider::XFormsOutput:
    1519               0 :       accessible = new nsXFormsOutputAccessible(aContent, aDoc);
    1520               0 :       break;
    1521                 : 
    1522                 :     case nsIAccessibleProvider::XFormsTrigger:
    1523               0 :       accessible = new nsXFormsTriggerAccessible(aContent, aDoc);
    1524               0 :       break;
    1525                 : 
    1526                 :     case nsIAccessibleProvider::XFormsInput:
    1527               0 :       accessible = new nsXFormsInputAccessible(aContent, aDoc);
    1528               0 :       break;
    1529                 : 
    1530                 :     case nsIAccessibleProvider::XFormsInputBoolean:
    1531               0 :       accessible = new nsXFormsInputBooleanAccessible(aContent, aDoc);
    1532               0 :       break;
    1533                 : 
    1534                 :     case nsIAccessibleProvider::XFormsInputDate:
    1535               0 :       accessible = new nsXFormsInputDateAccessible(aContent, aDoc);
    1536               0 :       break;
    1537                 : 
    1538                 :     case nsIAccessibleProvider::XFormsSecret:
    1539               0 :       accessible = new nsXFormsSecretAccessible(aContent, aDoc);
    1540               0 :       break;
    1541                 : 
    1542                 :     case nsIAccessibleProvider::XFormsSliderRange:
    1543               0 :       accessible = new nsXFormsRangeAccessible(aContent, aDoc);
    1544               0 :       break;
    1545                 : 
    1546                 :     case nsIAccessibleProvider::XFormsSelect:
    1547               0 :       accessible = new nsXFormsSelectAccessible(aContent, aDoc);
    1548               0 :       break;
    1549                 : 
    1550                 :     case nsIAccessibleProvider::XFormsChoices:
    1551               0 :       accessible = new nsXFormsChoicesAccessible(aContent, aDoc);
    1552               0 :       break;
    1553                 : 
    1554                 :     case nsIAccessibleProvider::XFormsSelectFull:
    1555               0 :       accessible = new nsXFormsSelectFullAccessible(aContent, aDoc);
    1556               0 :       break;
    1557                 : 
    1558                 :     case nsIAccessibleProvider::XFormsItemCheckgroup:
    1559               0 :       accessible = new nsXFormsItemCheckgroupAccessible(aContent, aDoc);
    1560               0 :       break;
    1561                 : 
    1562                 :     case nsIAccessibleProvider::XFormsItemRadiogroup:
    1563               0 :       accessible = new nsXFormsItemRadiogroupAccessible(aContent, aDoc);
    1564               0 :       break;
    1565                 : 
    1566                 :     case nsIAccessibleProvider::XFormsSelectCombobox:
    1567               0 :       accessible = new nsXFormsSelectComboboxAccessible(aContent, aDoc);
    1568               0 :       break;
    1569                 : 
    1570                 :     case nsIAccessibleProvider::XFormsItemCombobox:
    1571               0 :       accessible = new nsXFormsItemComboboxAccessible(aContent, aDoc);
    1572               0 :       break;
    1573                 : 
    1574                 :     case nsIAccessibleProvider::XFormsDropmarkerWidget:
    1575               0 :       accessible = new nsXFormsDropmarkerWidgetAccessible(aContent, aDoc);
    1576               0 :       break;
    1577                 : 
    1578                 :     case nsIAccessibleProvider::XFormsCalendarWidget:
    1579               0 :       accessible = new nsXFormsCalendarWidgetAccessible(aContent, aDoc);
    1580               0 :       break;
    1581                 : 
    1582                 :     case nsIAccessibleProvider::XFormsComboboxPopupWidget:
    1583               0 :       accessible = new nsXFormsComboboxPopupWidgetAccessible(aContent, aDoc);
    1584               0 :       break;
    1585                 : 
    1586                 :     default:
    1587               0 :       return nsnull;
    1588                 :   }
    1589                 : 
    1590               0 :   NS_IF_ADDREF(accessible);
    1591               0 :   return accessible;
    1592                 : }
    1593                 : 
    1594                 : already_AddRefed<nsAccessible>
    1595               0 : nsAccessibilityService::CreateHTMLAccessibleByMarkup(nsIFrame* aFrame,
    1596                 :                                                      nsIContent* aContent,
    1597                 :                                                      nsDocAccessible* aDoc)
    1598                 : {
    1599                 :   // This method assumes we're in an HTML namespace.
    1600               0 :   nsIAtom* tag = aContent->Tag();
    1601               0 :   if (tag == nsGkAtoms::figcaption) {
    1602                 :     nsAccessible* accessible =
    1603               0 :       new nsHTMLFigcaptionAccessible(aContent, aDoc);
    1604               0 :     NS_IF_ADDREF(accessible);
    1605               0 :     return accessible;
    1606                 :   }
    1607                 : 
    1608               0 :   if (tag == nsGkAtoms::figure) {
    1609               0 :     nsAccessible* accessible = new nsHTMLFigureAccessible(aContent, aDoc);
    1610               0 :     NS_IF_ADDREF(accessible);
    1611               0 :     return accessible;
    1612                 :   }
    1613                 : 
    1614               0 :   if (tag == nsGkAtoms::legend) {
    1615               0 :     nsAccessible* accessible = new nsHTMLLegendAccessible(aContent, aDoc);
    1616               0 :     NS_IF_ADDREF(accessible);
    1617               0 :     return accessible;
    1618                 :   }
    1619                 : 
    1620               0 :   if (tag == nsGkAtoms::option) {
    1621               0 :     nsAccessible* accessible = new nsHTMLSelectOptionAccessible(aContent, aDoc);
    1622               0 :     NS_IF_ADDREF(accessible);
    1623               0 :     return accessible;
    1624                 :   }
    1625                 : 
    1626               0 :   if (tag == nsGkAtoms::optgroup) {
    1627                 :     nsAccessible* accessible = new nsHTMLSelectOptGroupAccessible(aContent,
    1628               0 :                                                                   aDoc);
    1629               0 :     NS_IF_ADDREF(accessible);
    1630               0 :     return accessible;
    1631                 :   }
    1632                 : 
    1633               0 :   if (tag == nsGkAtoms::ul || tag == nsGkAtoms::ol ||
    1634                 :       tag == nsGkAtoms::dl) {
    1635               0 :     nsAccessible* accessible = new nsHTMLListAccessible(aContent, aDoc);
    1636               0 :     NS_IF_ADDREF(accessible);
    1637               0 :     return accessible;
    1638                 :   }
    1639                 : 
    1640               0 :   if (tag == nsGkAtoms::a) {
    1641                 :     // Only some roles truly enjoy life as nsHTMLLinkAccessibles, for details
    1642                 :     // see closed bug 494807.
    1643               0 :     nsRoleMapEntry *roleMapEntry = nsAccUtils::GetRoleMapEntry(aContent);
    1644               0 :     if (roleMapEntry && roleMapEntry->role != roles::NOTHING &&
    1645                 :         roleMapEntry->role != roles::LINK) {
    1646               0 :       nsAccessible* accessible = new nsHyperTextAccessibleWrap(aContent, aDoc);
    1647               0 :       NS_IF_ADDREF(accessible);
    1648               0 :       return accessible;
    1649                 :     }
    1650                 : 
    1651               0 :     nsAccessible* accessible = new nsHTMLLinkAccessible(aContent, aDoc);
    1652               0 :     NS_IF_ADDREF(accessible);
    1653               0 :     return accessible;
    1654                 :   }
    1655                 : 
    1656               0 :   if (tag == nsGkAtoms::dt ||
    1657                 :       (tag == nsGkAtoms::li &&
    1658               0 :        aFrame->GetType() != nsGkAtoms::blockFrame)) {
    1659                 :     // Normally for li, it is created by the list item frame (in nsBlockFrame)
    1660                 :     // which knows about the bullet frame; however, in this case the list item
    1661                 :     // must have been styled using display: foo
    1662               0 :     nsAccessible* accessible = new nsHTMLLIAccessible(aContent, aDoc);
    1663               0 :     NS_IF_ADDREF(accessible);
    1664               0 :     return accessible;
    1665                 :   }
    1666                 : 
    1667               0 :   if (tag == nsGkAtoms::abbr ||
    1668                 :       tag == nsGkAtoms::acronym ||
    1669                 :       tag == nsGkAtoms::blockquote ||
    1670                 :       tag == nsGkAtoms::dd ||
    1671                 :       tag == nsGkAtoms::form ||
    1672                 :       tag == nsGkAtoms::h1 ||
    1673                 :       tag == nsGkAtoms::h2 ||
    1674                 :       tag == nsGkAtoms::h3 ||
    1675                 :       tag == nsGkAtoms::h4 ||
    1676                 :       tag == nsGkAtoms::h5 ||
    1677                 :       tag == nsGkAtoms::h6 ||
    1678                 :       tag == nsGkAtoms::q) {
    1679               0 :     nsAccessible* accessible = new nsHyperTextAccessibleWrap(aContent, aDoc);
    1680               0 :     NS_IF_ADDREF(accessible);
    1681               0 :     return accessible;
    1682                 :   }
    1683                 : 
    1684               0 :   if (tag == nsGkAtoms::tr) {
    1685                 :     nsAccessible* accessible = new nsEnumRoleAccessible(aContent, aDoc,
    1686               0 :                                                         roles::ROW);
    1687               0 :     NS_IF_ADDREF(accessible);
    1688               0 :     return accessible;
    1689                 :   }
    1690                 : 
    1691               0 :   if (nsCoreUtils::IsHTMLTableHeader(aContent)) {
    1692                 :     nsAccessible* accessible = new nsHTMLTableHeaderCellAccessibleWrap(aContent,
    1693               0 :                                                                        aDoc);
    1694               0 :     NS_IF_ADDREF(accessible);
    1695               0 :     return accessible;
    1696                 :   }
    1697                 : 
    1698               0 :   if (tag == nsGkAtoms::output) {
    1699               0 :     nsAccessible* accessible = new nsHTMLOutputAccessible(aContent, aDoc);
    1700               0 :     NS_IF_ADDREF(accessible);
    1701               0 :     return accessible;
    1702                 :   }
    1703                 : 
    1704               0 :   if (tag == nsGkAtoms::progress) {
    1705                 :     nsAccessible* accessible =
    1706               0 :       new HTMLProgressMeterAccessible(aContent, aDoc);
    1707               0 :     NS_IF_ADDREF(accessible);
    1708               0 :     return accessible;
    1709                 :   }
    1710                 : 
    1711               0 :   return nsnull;
    1712                 :  }
    1713                 : 
    1714                 : ////////////////////////////////////////////////////////////////////////////////
    1715                 : // nsIAccessibilityService (DON'T put methods here)
    1716                 : 
    1717                 : nsAccessible*
    1718               0 : nsAccessibilityService::AddNativeRootAccessible(void* aAtkAccessible)
    1719                 :  {
    1720                 : #ifdef MOZ_ACCESSIBILITY_ATK
    1721                 :   nsApplicationAccessible* applicationAcc =
    1722               0 :     nsAccessNode::GetApplicationAccessible();
    1723               0 :   if (!applicationAcc)
    1724               0 :     return nsnull;
    1725                 : 
    1726                 :   nsRefPtr<nsNativeRootAccessibleWrap> nativeRootAcc =
    1727               0 :      new nsNativeRootAccessibleWrap((AtkObject*)aAtkAccessible);
    1728               0 :   if (!nativeRootAcc)
    1729               0 :     return nsnull;
    1730                 : 
    1731               0 :   if (applicationAcc->AppendChild(nativeRootAcc))
    1732               0 :     return nativeRootAcc;
    1733                 : #endif
    1734                 : 
    1735               0 :   return nsnull;
    1736                 :  }
    1737                 : 
    1738                 : void
    1739               0 : nsAccessibilityService::RemoveNativeRootAccessible(nsAccessible* aAccessible)
    1740                 : {
    1741                 : #ifdef MOZ_ACCESSIBILITY_ATK
    1742                 :   nsApplicationAccessible* applicationAcc =
    1743               0 :     nsAccessNode::GetApplicationAccessible();
    1744                 : 
    1745               0 :   if (applicationAcc)
    1746               0 :     applicationAcc->RemoveChild(aAccessible);
    1747                 : #endif
    1748               0 : }
    1749                 : 
    1750                 : ////////////////////////////////////////////////////////////////////////////////
    1751                 : // NS_GetAccessibilityService
    1752                 : ////////////////////////////////////////////////////////////////////////////////
    1753                 : 
    1754                 : /**
    1755                 :  * Return accessibility service; creating one if necessary.
    1756                 :  */
    1757                 : nsresult
    1758               0 : NS_GetAccessibilityService(nsIAccessibilityService** aResult)
    1759                 : {
    1760               0 :   NS_ENSURE_TRUE(aResult, NS_ERROR_NULL_POINTER);
    1761               0 :   *aResult = nsnull;
    1762                 :  
    1763               0 :   if (nsAccessibilityService::gAccessibilityService) {
    1764               0 :     NS_ADDREF(*aResult = nsAccessibilityService::gAccessibilityService);
    1765               0 :     return NS_OK;
    1766                 :   }
    1767                 : 
    1768               0 :   nsRefPtr<nsAccessibilityService> service = new nsAccessibilityService();
    1769               0 :   NS_ENSURE_TRUE(service, NS_ERROR_OUT_OF_MEMORY);
    1770                 : 
    1771               0 :   if (!service->Init()) {
    1772               0 :     service->Shutdown();
    1773               0 :     return NS_ERROR_FAILURE;
    1774                 :   }
    1775                 : 
    1776               0 :   statistics::A11yInitialized();
    1777                 : 
    1778               0 :   nsAccessibilityService::gAccessibilityService = service;
    1779               0 :   NS_ADDREF(*aResult = service);
    1780                 : 
    1781               0 :   return NS_OK;
    1782                 : }
    1783                 : 
    1784                 : ////////////////////////////////////////////////////////////////////////////////
    1785                 : // nsAccessibilityService private (DON'T put methods here)
    1786                 : 
    1787                 : already_AddRefed<nsAccessible>
    1788               0 : nsAccessibilityService::CreateAccessibleForDeckChild(nsIFrame* aFrame,
    1789                 :                                                      nsIContent* aContent,
    1790                 :                                                      nsDocAccessible* aDoc)
    1791                 : {
    1792               0 :   if (aFrame->GetType() == nsGkAtoms::boxFrame ||
    1793               0 :       aFrame->GetType() == nsGkAtoms::scrollFrame) {
    1794                 : 
    1795               0 :     nsIFrame* parentFrame = aFrame->GetParent();
    1796               0 :     if (parentFrame && parentFrame->GetType() == nsGkAtoms::deckFrame) {
    1797                 :       // If deck frame is for xul:tabpanels element then the given node has
    1798                 :       // tabpanel accessible.
    1799               0 :       nsCOMPtr<nsIContent> parentContent = parentFrame->GetContent();
    1800                 : #ifdef MOZ_XUL
    1801               0 :       if (parentContent->NodeInfo()->Equals(nsGkAtoms::tabpanels,
    1802               0 :                                             kNameSpaceID_XUL)) {
    1803               0 :         nsAccessible* accessible = new nsXULTabpanelAccessible(aContent, aDoc);
    1804               0 :         NS_IF_ADDREF(accessible);
    1805               0 :         return accessible;
    1806                 :       }
    1807                 : #endif
    1808                 :       nsAccessible* accessible = new nsEnumRoleAccessible(aContent, aDoc,
    1809               0 :                                                           roles::PROPERTYPAGE);
    1810               0 :       NS_IF_ADDREF(accessible);
    1811               0 :       return accessible;
    1812                 :     }
    1813                 :   }
    1814                 : 
    1815               0 :   return nsnull;
    1816                 : }
    1817                 : 
    1818                 : #ifdef MOZ_XUL
    1819                 : already_AddRefed<nsAccessible>
    1820               0 : nsAccessibilityService::CreateAccessibleForXULTree(nsIContent* aContent,
    1821                 :                                                    nsDocAccessible* aDoc)
    1822                 : {
    1823               0 :   nsCOMPtr<nsITreeBoxObject> treeBoxObj = nsCoreUtils::GetTreeBoxObject(aContent);
    1824               0 :   if (!treeBoxObj)
    1825               0 :     return nsnull;
    1826                 : 
    1827               0 :   nsCOMPtr<nsITreeColumns> treeColumns;
    1828               0 :   treeBoxObj->GetColumns(getter_AddRefs(treeColumns));
    1829               0 :   if (!treeColumns)
    1830               0 :     return nsnull;
    1831                 : 
    1832               0 :   PRInt32 count = 0;
    1833               0 :   treeColumns->GetCount(&count);
    1834                 : 
    1835                 :   // Outline of list accessible.
    1836               0 :   if (count == 1) {
    1837               0 :     nsAccessible* accessible = new nsXULTreeAccessible(aContent, aDoc);
    1838               0 :     NS_IF_ADDREF(accessible);
    1839               0 :     return accessible;
    1840                 :   }
    1841                 : 
    1842                 :   // Table or tree table accessible.
    1843               0 :   nsAccessible* accessible = new nsXULTreeGridAccessibleWrap(aContent, aDoc);
    1844               0 :   NS_IF_ADDREF(accessible);
    1845               0 :   return accessible;
    1846                 : }
    1847                 : #endif
    1848                 : 
    1849                 : ////////////////////////////////////////////////////////////////////////////////
    1850                 : // Services
    1851                 : ////////////////////////////////////////////////////////////////////////////////
    1852                 : 
    1853                 : mozilla::a11y::FocusManager*
    1854               0 : mozilla::a11y::FocusMgr()
    1855                 : {
    1856               0 :   return nsAccessibilityService::gAccessibilityService;
    1857                 : }

Generated by: LCOV version 1.7