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 : * Aaron Leventhal <aaronl@netscape.com> (original author)
24 : * Alexander Surkov <surkov.alexander@gmail.com>
25 : *
26 : * Alternatively, the contents of this file may be used under the terms of
27 : * either of the GNU General Public License Version 2 or later (the "GPL"),
28 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 : * in which case the provisions of the GPL or the LGPL are applicable instead
30 : * of those above. If you wish to allow use of your version of this file only
31 : * under the terms of either the GPL or the LGPL, and not to allow others to
32 : * use your version of this file under the terms of the MPL, indicate your
33 : * decision by deleting the provisions above and replace them with the notice
34 : * and other provisions required by the GPL or the LGPL. If you do not delete
35 : * the provisions above, a recipient may use your version of this file under
36 : * the terms of any one of the MPL, the GPL or the LGPL.
37 : *
38 : * ***** END LICENSE BLOCK ***** */
39 :
40 : #include "nsHTMLImageMapAccessible.h"
41 :
42 : #include "nsAccUtils.h"
43 : #include "nsDocAccessible.h"
44 : #include "Role.h"
45 :
46 : #include "nsIDOMHTMLCollection.h"
47 : #include "nsIServiceManager.h"
48 : #include "nsIDOMElement.h"
49 : #include "nsIDOMHTMLAreaElement.h"
50 : #include "nsIFrame.h"
51 : #include "nsImageFrame.h"
52 : #include "nsImageMap.h"
53 :
54 : using namespace mozilla::a11y;
55 : ////////////////////////////////////////////////////////////////////////////////
56 : // nsHTMLImageMapAccessible
57 : ////////////////////////////////////////////////////////////////////////////////
58 :
59 0 : nsHTMLImageMapAccessible::
60 : nsHTMLImageMapAccessible(nsIContent* aContent, nsDocAccessible* aDoc,
61 : nsIDOMHTMLMapElement* aMapElm) :
62 0 : nsHTMLImageAccessibleWrap(aContent, aDoc), mMapElement(aMapElm)
63 : {
64 0 : }
65 :
66 : ////////////////////////////////////////////////////////////////////////////////
67 : // nsHTMLImageMapAccessible: nsISupports
68 :
69 0 : NS_IMPL_ISUPPORTS_INHERITED0(nsHTMLImageMapAccessible, nsHTMLImageAccessible)
70 :
71 : ////////////////////////////////////////////////////////////////////////////////
72 : // nsHTMLImageMapAccessible: nsAccessible public
73 :
74 : role
75 0 : nsHTMLImageMapAccessible::NativeRole()
76 : {
77 0 : return roles::IMAGE_MAP;
78 : }
79 :
80 : ////////////////////////////////////////////////////////////////////////////////
81 : // nsHTMLImageMapAccessible: HyperLinkAccessible
82 :
83 : PRUint32
84 0 : nsHTMLImageMapAccessible::AnchorCount()
85 : {
86 0 : return GetChildCount();
87 : }
88 :
89 : nsAccessible*
90 0 : nsHTMLImageMapAccessible::AnchorAt(PRUint32 aAnchorIndex)
91 : {
92 0 : return GetChildAt(aAnchorIndex);
93 : }
94 :
95 : already_AddRefed<nsIURI>
96 0 : nsHTMLImageMapAccessible::AnchorURIAt(PRUint32 aAnchorIndex)
97 : {
98 0 : nsAccessible* area = GetChildAt(aAnchorIndex);
99 0 : if (!area)
100 0 : return nsnull;
101 :
102 0 : nsIContent* linkContent = area->GetContent();
103 0 : return linkContent ? linkContent->GetHrefURI() : nsnull;
104 : }
105 :
106 : ////////////////////////////////////////////////////////////////////////////////
107 : // nsHTMLImageMapAccessible: nsAccessible protected
108 :
109 : void
110 0 : nsHTMLImageMapAccessible::CacheChildren()
111 : {
112 0 : if (!mMapElement)
113 0 : return;
114 :
115 0 : nsCOMPtr<nsIDOMHTMLCollection> mapAreas;
116 0 : mMapElement->GetAreas(getter_AddRefs(mapAreas));
117 0 : if (!mapAreas)
118 : return;
119 :
120 0 : nsDocAccessible* document = Document();
121 :
122 0 : PRUint32 areaCount = 0;
123 0 : mapAreas->GetLength(&areaCount);
124 :
125 0 : for (PRUint32 areaIdx = 0; areaIdx < areaCount; areaIdx++) {
126 0 : nsCOMPtr<nsIDOMNode> areaNode;
127 0 : mapAreas->Item(areaIdx, getter_AddRefs(areaNode));
128 0 : if (!areaNode)
129 : return;
130 :
131 0 : nsCOMPtr<nsIContent> areaContent(do_QueryInterface(areaNode));
132 : nsRefPtr<nsAccessible> area =
133 0 : new nsHTMLAreaAccessible(areaContent, mDoc);
134 :
135 0 : if (!document->BindToDocument(area, nsAccUtils::GetRoleMapEntry(areaContent)) ||
136 0 : !AppendChild(area)) {
137 : return;
138 : }
139 : }
140 : }
141 :
142 :
143 : ////////////////////////////////////////////////////////////////////////////////
144 : // nsHTMLAreaAccessible
145 : ////////////////////////////////////////////////////////////////////////////////
146 :
147 0 : nsHTMLAreaAccessible::
148 : nsHTMLAreaAccessible(nsIContent* aContent, nsDocAccessible* aDoc) :
149 0 : nsHTMLLinkAccessible(aContent, aDoc)
150 : {
151 0 : }
152 :
153 : ////////////////////////////////////////////////////////////////////////////////
154 : // nsHTMLAreaAccessible: nsIAccessible
155 :
156 : nsresult
157 0 : nsHTMLAreaAccessible::GetNameInternal(nsAString & aName)
158 : {
159 0 : nsresult rv = nsAccessible::GetNameInternal(aName);
160 0 : NS_ENSURE_SUCCESS(rv, rv);
161 :
162 0 : if (!aName.IsEmpty())
163 0 : return NS_OK;
164 :
165 0 : if (!mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::alt, aName))
166 0 : return GetValue(aName);
167 :
168 0 : return NS_OK;
169 : }
170 :
171 : void
172 0 : nsHTMLAreaAccessible::Description(nsString& aDescription)
173 : {
174 0 : aDescription.Truncate();
175 :
176 : // Still to do - follow IE's standard here
177 0 : nsCOMPtr<nsIDOMHTMLAreaElement> area(do_QueryInterface(mContent));
178 0 : if (area)
179 0 : area->GetShape(aDescription);
180 0 : }
181 :
182 : NS_IMETHODIMP
183 0 : nsHTMLAreaAccessible::GetBounds(PRInt32 *aX, PRInt32 *aY,
184 : PRInt32 *aWidth, PRInt32 *aHeight)
185 : {
186 0 : NS_ENSURE_ARG_POINTER(aX);
187 0 : *aX = 0;
188 0 : NS_ENSURE_ARG_POINTER(aY);
189 0 : *aY = 0;
190 0 : NS_ENSURE_ARG_POINTER(aWidth);
191 0 : *aWidth = 0;
192 0 : NS_ENSURE_ARG_POINTER(aHeight);
193 0 : *aHeight = 0;
194 :
195 0 : if (IsDefunct())
196 0 : return NS_ERROR_FAILURE;
197 :
198 : // Essentially this uses GetRect on mAreas of nsImageMap from nsImageFrame.
199 0 : nsPresContext *presContext = GetPresContext();
200 0 : NS_ENSURE_TRUE(presContext, NS_ERROR_FAILURE);
201 :
202 0 : nsIFrame *frame = GetFrame();
203 0 : NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
204 0 : nsImageFrame *imageFrame = do_QueryFrame(frame);
205 :
206 0 : nsImageMap* map = imageFrame->GetImageMap();
207 0 : NS_ENSURE_TRUE(map, NS_ERROR_FAILURE);
208 :
209 0 : nsRect rect;
210 0 : nsresult rv = map->GetBoundsForAreaContent(mContent, rect);
211 0 : NS_ENSURE_SUCCESS(rv, rv);
212 :
213 0 : *aX = presContext->AppUnitsToDevPixels(rect.x);
214 0 : *aY = presContext->AppUnitsToDevPixels(rect.y);
215 :
216 : // XXX Areas are screwy; they return their rects as a pair of points, one pair
217 : // stored into the width and height.
218 0 : *aWidth = presContext->AppUnitsToDevPixels(rect.width - rect.x);
219 0 : *aHeight = presContext->AppUnitsToDevPixels(rect.height - rect.y);
220 :
221 : // Put coords in absolute screen coords
222 0 : nsIntRect orgRectPixels = frame->GetScreenRectExternal();
223 0 : *aX += orgRectPixels.x;
224 0 : *aY += orgRectPixels.y;
225 :
226 0 : return NS_OK;
227 : }
228 :
229 : ////////////////////////////////////////////////////////////////////////////////
230 : // nsHTMLAreaAccessible: nsAccessible public
231 :
232 : PRUint64
233 0 : nsHTMLAreaAccessible::NativeState()
234 : {
235 : // Bypass the link states specialization for non links.
236 0 : if (mRoleMapEntry &&
237 : mRoleMapEntry->role != roles::NOTHING &&
238 : mRoleMapEntry->role != roles::LINK) {
239 0 : return nsAccessible::NativeState();
240 : }
241 :
242 0 : return nsHTMLLinkAccessible::NativeState();
243 : }
244 :
245 : nsAccessible*
246 0 : nsHTMLAreaAccessible::ChildAtPoint(PRInt32 aX, PRInt32 aY,
247 : EWhichChildAtPoint aWhichChild)
248 : {
249 : // Don't walk into area accessibles.
250 0 : return this;
251 : }
252 :
253 : ////////////////////////////////////////////////////////////////////////////////
254 : // nsHTMLImageMapAccessible: HyperLinkAccessible
255 :
256 : PRUint32
257 0 : nsHTMLAreaAccessible::StartOffset()
258 : {
259 : // Image map accessible is not hypertext accessible therefore
260 : // StartOffset/EndOffset implementations of nsAccessible doesn't work here.
261 : // We return index in parent because image map contains area links only which
262 : // are embedded objects.
263 : // XXX: image map should be a hypertext accessible.
264 0 : return IndexInParent();
265 : }
266 :
267 : PRUint32
268 0 : nsHTMLAreaAccessible::EndOffset()
269 : {
270 0 : return IndexInParent() + 1;
271 : }
272 :
273 : ////////////////////////////////////////////////////////////////////////////////
274 : // nsHTMLAreaAccessible: nsAccessible protected
275 :
276 : void
277 0 : nsHTMLAreaAccessible::CacheChildren()
278 : {
279 : // No children for aria accessible.
280 0 : }
|