CLOSED TREE: TraceMonkey merge head. (a=blockers)
[mozilla-central.git] / accessible / src / html / nsHTMLImageAccessible.cpp
blob9f4481f6f8ca29d1246023c1bfba4e89fa3fa5a2
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
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/
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.
15 * The Original Code is mozilla.org code.
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.
22 * Contributor(s):
23 * Author: Aaron Leventhal (aaronl@netscape.com)
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.
37 * ***** END LICENSE BLOCK ***** */
39 #include "nsHTMLImageAccessible.h"
41 #include "nsAccessibilityAtoms.h"
42 #include "nsAccUtils.h"
44 #include "imgIContainer.h"
45 #include "imgIRequest.h"
46 #include "nsIDocument.h"
47 #include "nsIImageLoadingContent.h"
48 #include "nsILink.h"
49 #include "nsIPresShell.h"
50 #include "nsIServiceManager.h"
51 #include "nsIDOMHTMLImageElement.h"
52 #include "nsIDOMDocument.h"
53 #include "nsPIDOMWindow.h"
55 ////////////////////////////////////////////////////////////////////////////////
56 // nsHTMLImageAccessible
57 ////////////////////////////////////////////////////////////////////////////////
59 nsHTMLImageAccessible::
60 nsHTMLImageAccessible(nsIContent *aContent, nsIWeakReference *aShell) :
61 nsLinkableAccessible(aContent, aShell)
65 NS_IMPL_ISUPPORTS_INHERITED1(nsHTMLImageAccessible, nsAccessible,
66 nsIAccessibleImage)
68 ////////////////////////////////////////////////////////////////////////////////
69 // nsAccessible public
71 nsresult
72 nsHTMLImageAccessible::GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState)
74 // The state is a bitfield, get our inherited state, then logically OR it with
75 // STATE_ANIMATED if this is an animated image.
77 nsresult rv = nsLinkableAccessible::GetStateInternal(aState, aExtraState);
78 NS_ENSURE_A11Y_SUCCESS(rv, rv);
80 nsCOMPtr<nsIImageLoadingContent> content(do_QueryInterface(mContent));
81 nsCOMPtr<imgIRequest> imageRequest;
83 if (content)
84 content->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST,
85 getter_AddRefs(imageRequest));
87 nsCOMPtr<imgIContainer> imgContainer;
88 if (imageRequest)
89 imageRequest->GetImage(getter_AddRefs(imgContainer));
91 if (imgContainer) {
92 PRBool animated;
93 imgContainer->GetAnimated(&animated);
94 if (animated)
95 *aState |= nsIAccessibleStates::STATE_ANIMATED;
98 return NS_OK;
101 nsresult
102 nsHTMLImageAccessible::GetNameInternal(nsAString& aName)
104 PRBool hasAltAttrib =
105 mContent->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::alt, aName);
106 if (!aName.IsEmpty())
107 return NS_OK;
109 nsresult rv = nsAccessible::GetNameInternal(aName);
110 NS_ENSURE_SUCCESS(rv, rv);
112 if (aName.IsEmpty() && hasAltAttrib) {
113 // No accessible name but empty 'alt' attribute is present. If further name
114 // computation algorithm doesn't provide non empty name then it means
115 // an empty 'alt' attribute was used to indicate a decorative image (see
116 // nsIAccessible::name attribute for details).
117 return NS_OK_EMPTY_NAME;
120 return NS_OK;
123 PRUint32
124 nsHTMLImageAccessible::NativeRole()
126 return nsIAccessibleRole::ROLE_GRAPHIC;
129 ////////////////////////////////////////////////////////////////////////////////
130 // nsIAccessible
132 NS_IMETHODIMP
133 nsHTMLImageAccessible::GetNumActions(PRUint8 *aNumActions)
135 NS_ENSURE_ARG_POINTER(aNumActions);
136 *aNumActions = 0;
138 if (IsDefunct())
139 return NS_ERROR_FAILURE;
141 nsresult rv= nsLinkableAccessible::GetNumActions(aNumActions);
142 NS_ENSURE_SUCCESS(rv, rv);
144 if (HasLongDesc())
145 (*aNumActions)++;
147 return NS_OK;
150 NS_IMETHODIMP
151 nsHTMLImageAccessible::GetActionName(PRUint8 aIndex, nsAString& aName)
153 aName.Truncate();
155 if (IsDefunct())
156 return NS_ERROR_FAILURE;
158 if (IsValidLongDescIndex(aIndex)) {
159 aName.AssignLiteral("showlongdesc");
160 return NS_OK;
162 return nsLinkableAccessible::GetActionName(aIndex, aName);
165 NS_IMETHODIMP
166 nsHTMLImageAccessible::DoAction(PRUint8 aIndex)
168 if (IsDefunct())
169 return NS_ERROR_FAILURE;
171 if (IsValidLongDescIndex(aIndex)) {
172 //get the long description uri and open in a new window
173 nsCOMPtr<nsIDOMHTMLImageElement> element(do_QueryInterface(mContent));
174 NS_ENSURE_TRUE(element, NS_ERROR_FAILURE);
176 nsAutoString longDesc;
177 nsresult rv = element->GetLongDesc(longDesc);
178 NS_ENSURE_SUCCESS(rv, rv);
180 nsIDocument* document = mContent->GetOwnerDoc();
181 nsCOMPtr<nsPIDOMWindow> piWindow = document->GetWindow();
182 nsCOMPtr<nsIDOMWindowInternal> win(do_QueryInterface(piWindow));
183 NS_ENSURE_TRUE(win, NS_ERROR_FAILURE);
184 nsCOMPtr<nsIDOMWindow> tmp;
185 return win->Open(longDesc, EmptyString(), EmptyString(),
186 getter_AddRefs(tmp));
188 return nsLinkableAccessible::DoAction(aIndex);
191 ////////////////////////////////////////////////////////////////////////////////
192 // nsIAccessibleImage
194 NS_IMETHODIMP
195 nsHTMLImageAccessible::GetImagePosition(PRUint32 aCoordType,
196 PRInt32 *aX, PRInt32 *aY)
198 PRInt32 width, height;
199 nsresult rv = GetBounds(aX, aY, &width, &height);
200 if (NS_FAILED(rv))
201 return rv;
203 return nsAccUtils::ConvertScreenCoordsTo(aX, aY, aCoordType, this);
206 NS_IMETHODIMP
207 nsHTMLImageAccessible::GetImageSize(PRInt32 *aWidth, PRInt32 *aHeight)
209 PRInt32 x, y;
210 return GetBounds(&x, &y, aWidth, aHeight);
213 // nsAccessible
214 nsresult
215 nsHTMLImageAccessible::GetAttributesInternal(nsIPersistentProperties *aAttributes)
217 if (IsDefunct())
218 return NS_ERROR_FAILURE;
220 nsresult rv = nsLinkableAccessible::GetAttributesInternal(aAttributes);
221 NS_ENSURE_SUCCESS(rv, rv);
223 nsAutoString src;
224 mContent->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::src, src);
225 if (!src.IsEmpty())
226 nsAccUtils::SetAccAttr(aAttributes, nsAccessibilityAtoms::src, src);
228 return NS_OK;
231 ////////////////////////////////////////////////////////////////////////////////
232 // Private methods
234 PRBool
235 nsHTMLImageAccessible::HasLongDesc()
237 if (IsDefunct())
238 return PR_FALSE;
240 return mContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::longDesc);
243 PRBool
244 nsHTMLImageAccessible::IsValidLongDescIndex(PRUint8 aIndex)
246 if (!HasLongDesc())
247 return PR_FALSE;
249 PRUint8 numActions = 0;
250 nsresult rv = nsLinkableAccessible::GetNumActions(&numActions);
251 NS_ENSURE_SUCCESS(rv, PR_FALSE);
253 return (aIndex == numActions);