Back to index

lightning-sunbird  0.9+nobinonly
nsHTMLImageAccessible.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Author: Aaron Leventhal (aaronl@netscape.com)
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either of the GNU General Public License Version 2 or later (the "GPL"),
00027  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 
00039 #include "imgIContainer.h"
00040 #include "imgIRequest.h"
00041 #include "nsHTMLImageAccessible.h"
00042 #include "nsAccessibilityAtoms.h"
00043 #include "nsIAccessibilityService.h"
00044 #include "nsIDOMHTMLCollection.h"
00045 #include "nsIDocument.h"
00046 #include "nsIHTMLDocument.h"
00047 #include "nsIImageLoadingContent.h"
00048 #include "nsIPresShell.h"
00049 #include "nsIServiceManager.h"
00050 
00051 // --- image -----
00052 
00053 nsHTMLImageAccessible::nsHTMLImageAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell):
00054 nsLinkableAccessible(aDOMNode, aShell)
00055 { 
00056   nsCOMPtr<nsIDOMElement> element(do_QueryInterface(aDOMNode));
00057   nsCOMPtr<nsIPresShell> shell(do_QueryReferent(mWeakShell));
00058   if (!shell)
00059     return;
00060 
00061   nsIDocument *doc = shell->GetDocument();
00062   nsAutoString mapElementName;
00063 
00064   if (doc && element) {
00065     nsCOMPtr<nsIHTMLDocument> htmlDoc(do_QueryInterface(doc));
00066     element->GetAttribute(NS_LITERAL_STRING("usemap"),mapElementName);
00067     if (htmlDoc && !mapElementName.IsEmpty()) {
00068       if (mapElementName.CharAt(0) == '#')
00069         mapElementName.Cut(0,1);
00070       mMapElement = htmlDoc->GetImageMap(mapElementName);
00071     }
00072   }
00073 }
00074 
00075 NS_IMETHODIMP nsHTMLImageAccessible::GetState(PRUint32 *_retval)
00076 {
00077   // The state is a bitfield, get our inherited state, then logically OR it with STATE_ANIMATED if this
00078   // is an animated image.
00079 
00080   nsLinkableAccessible::GetState(_retval);
00081 
00082   nsCOMPtr<nsIImageLoadingContent> content(do_QueryInterface(mDOMNode));
00083   nsCOMPtr<imgIRequest> imageRequest;
00084 
00085   if (content) 
00086     content->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST,
00087                         getter_AddRefs(imageRequest));
00088   
00089   nsCOMPtr<imgIContainer> imgContainer;
00090   if (imageRequest) 
00091     imageRequest->GetImage(getter_AddRefs(imgContainer));
00092 
00093   if (imgContainer) {
00094     PRUint32 numFrames;
00095     imgContainer->GetNumFrames(&numFrames);
00096     if (numFrames > 1)
00097       *_retval |= STATE_ANIMATED;
00098   }
00099 
00100   return NS_OK;
00101 }
00102 
00103 
00104 /* wstring getName (); */
00105 NS_IMETHODIMP nsHTMLImageAccessible::GetName(nsAString& aName)
00106 {
00107   nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
00108   if (!content) {
00109     return NS_ERROR_FAILURE;  // Node has been shut down
00110   }
00111 
00112   if (NS_CONTENT_ATTR_HAS_VALUE != content->GetAttr(kNameSpaceID_None,
00113                                                     nsAccessibilityAtoms::alt,
00114                                                     aName)) {
00115     if (mRoleMapEntry) {
00116       // Use HTML label or DHTML accessibility's labelledby attribute for name
00117       // GetHTMLName will also try title attribute as a last resort
00118       return GetHTMLName(aName, PR_FALSE);
00119     }
00120     if (NS_CONTENT_ATTR_HAS_VALUE != content->GetAttr(kNameSpaceID_None,
00121                                                     nsAccessibilityAtoms::title,
00122                                                     aName)) {
00123       aName.SetIsVoid(PR_TRUE); // No alt or title
00124     }
00125   }
00126 
00127   return NS_OK;
00128 }
00129 
00130 /* wstring getRole (); */
00131 NS_IMETHODIMP nsHTMLImageAccessible::GetRole(PRUint32 *_retval)
00132 {
00133   *_retval = ROLE_GRAPHIC;
00134   return NS_OK;
00135 }
00136 
00137 
00138 already_AddRefed<nsIAccessible> nsHTMLImageAccessible::CreateAreaAccessible(PRInt32 areaNum)
00139 {
00140   if (!mMapElement) 
00141     return nsnull;
00142 
00143   nsCOMPtr<nsIDOMHTMLCollection> mapAreas;
00144   mMapElement->GetAreas(getter_AddRefs(mapAreas));
00145   if (!mapAreas) 
00146     return nsnull;
00147 
00148   nsCOMPtr<nsIDOMNode> domNode;
00149   mapAreas->Item(areaNum,getter_AddRefs(domNode));
00150   if (!domNode)
00151     return nsnull;
00152 
00153   nsCOMPtr<nsIAccessibilityService> accService(do_GetService("@mozilla.org/accessibilityService;1"));
00154   if (!accService)
00155     return nsnull;
00156   if (accService) {
00157     nsIAccessible* acc = nsnull;
00158     accService->GetCachedAccessible(domNode, mWeakShell, &acc);
00159     if (!acc) {
00160       accService->CreateHTMLAreaAccessible(mWeakShell, domNode, this, &acc);
00161       nsCOMPtr<nsPIAccessNode> accessNode(do_QueryInterface(acc));
00162       if (accessNode) {
00163         accessNode->Init();
00164       }
00165     }
00166     return acc;
00167   }
00168   return nsnull;
00169 }
00170 
00171 
00172 void nsHTMLImageAccessible::CacheChildren(PRBool aWalkAnonContent)
00173 {
00174   if (!mWeakShell) {
00175     // This node has been shut down
00176     mAccChildCount = -1;
00177     return;
00178   }
00179 
00180   if (mAccChildCount != eChildCountUninitialized) {
00181     return;
00182   }
00183 
00184   mAccChildCount = 0;
00185   nsCOMPtr<nsIDOMHTMLCollection> mapAreas;
00186   if (mMapElement) {
00187     mMapElement->GetAreas(getter_AddRefs(mapAreas));
00188   }
00189   if (!mapAreas) {
00190     return;
00191   }
00192 
00193   PRUint32 numMapAreas;
00194   mapAreas->GetLength(&numMapAreas);
00195 
00196   nsCOMPtr<nsIAccessible> areaAccessible;
00197   nsCOMPtr<nsPIAccessible> privatePrevAccessible;
00198   while (mAccChildCount < numMapAreas && 
00199          (areaAccessible = CreateAreaAccessible(mAccChildCount)) != nsnull) {
00200     if (privatePrevAccessible) {
00201       privatePrevAccessible->SetNextSibling(areaAccessible);
00202     }
00203     else {
00204       SetFirstChild(areaAccessible);
00205     }
00206 
00207     ++mAccChildCount;
00208 
00209     privatePrevAccessible = do_QueryInterface(areaAccessible);
00210     NS_ASSERTION(privatePrevAccessible, "nsIAccessible impl's should always support nsPIAccessible as well");
00211     privatePrevAccessible->SetParent(this);
00212   }
00213 }
00214