1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/accessible/src/html/HTMLImageMapAccessible.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,259 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include "HTMLImageMapAccessible.h" 1.10 + 1.11 +#include "ARIAMap.h" 1.12 +#include "nsAccUtils.h" 1.13 +#include "DocAccessible-inl.h" 1.14 +#include "Role.h" 1.15 + 1.16 +#include "nsIDOMHTMLCollection.h" 1.17 +#include "nsIServiceManager.h" 1.18 +#include "nsIDOMElement.h" 1.19 +#include "nsIDOMHTMLAreaElement.h" 1.20 +#include "nsIFrame.h" 1.21 +#include "nsImageFrame.h" 1.22 +#include "nsImageMap.h" 1.23 +#include "nsIURI.h" 1.24 + 1.25 +using namespace mozilla::a11y; 1.26 + 1.27 +//////////////////////////////////////////////////////////////////////////////// 1.28 +// HTMLImageMapAccessible 1.29 +//////////////////////////////////////////////////////////////////////////////// 1.30 + 1.31 +HTMLImageMapAccessible:: 1.32 + HTMLImageMapAccessible(nsIContent* aContent, DocAccessible* aDoc) : 1.33 + ImageAccessibleWrap(aContent, aDoc) 1.34 +{ 1.35 + mType = eImageMapType; 1.36 +} 1.37 + 1.38 +//////////////////////////////////////////////////////////////////////////////// 1.39 +// HTMLImageMapAccessible: nsISupports 1.40 + 1.41 +NS_IMPL_ISUPPORTS_INHERITED0(HTMLImageMapAccessible, ImageAccessible) 1.42 + 1.43 +//////////////////////////////////////////////////////////////////////////////// 1.44 +// HTMLImageMapAccessible: Accessible public 1.45 + 1.46 +role 1.47 +HTMLImageMapAccessible::NativeRole() 1.48 +{ 1.49 + return roles::IMAGE_MAP; 1.50 +} 1.51 + 1.52 +//////////////////////////////////////////////////////////////////////////////// 1.53 +// HTMLImageMapAccessible: HyperLinkAccessible 1.54 + 1.55 +uint32_t 1.56 +HTMLImageMapAccessible::AnchorCount() 1.57 +{ 1.58 + return ChildCount(); 1.59 +} 1.60 + 1.61 +Accessible* 1.62 +HTMLImageMapAccessible::AnchorAt(uint32_t aAnchorIndex) 1.63 +{ 1.64 + return GetChildAt(aAnchorIndex); 1.65 +} 1.66 + 1.67 +already_AddRefed<nsIURI> 1.68 +HTMLImageMapAccessible::AnchorURIAt(uint32_t aAnchorIndex) 1.69 +{ 1.70 + Accessible* area = GetChildAt(aAnchorIndex); 1.71 + if (!area) 1.72 + return nullptr; 1.73 + 1.74 + nsIContent* linkContent = area->GetContent(); 1.75 + return linkContent ? linkContent->GetHrefURI() : nullptr; 1.76 +} 1.77 + 1.78 +//////////////////////////////////////////////////////////////////////////////// 1.79 +// HTMLImageMapAccessible: public 1.80 + 1.81 +void 1.82 +HTMLImageMapAccessible::UpdateChildAreas(bool aDoFireEvents) 1.83 +{ 1.84 + nsImageFrame* imageFrame = do_QueryFrame(mContent->GetPrimaryFrame()); 1.85 + 1.86 + // If image map is not initialized yet then we trigger one time more later. 1.87 + nsImageMap* imageMapObj = imageFrame->GetExistingImageMap(); 1.88 + if (!imageMapObj) 1.89 + return; 1.90 + 1.91 + bool doReorderEvent = false; 1.92 + nsRefPtr<AccReorderEvent> reorderEvent = new AccReorderEvent(this); 1.93 + 1.94 + // Remove areas that are not a valid part of the image map anymore. 1.95 + for (int32_t childIdx = mChildren.Length() - 1; childIdx >= 0; childIdx--) { 1.96 + Accessible* area = mChildren.ElementAt(childIdx); 1.97 + if (area->GetContent()->GetPrimaryFrame()) 1.98 + continue; 1.99 + 1.100 + if (aDoFireEvents) { 1.101 + nsRefPtr<AccHideEvent> event = new AccHideEvent(area, area->GetContent()); 1.102 + mDoc->FireDelayedEvent(event); 1.103 + reorderEvent->AddSubMutationEvent(event); 1.104 + doReorderEvent = true; 1.105 + } 1.106 + 1.107 + RemoveChild(area); 1.108 + } 1.109 + 1.110 + // Insert new areas into the tree. 1.111 + uint32_t areaElmCount = imageMapObj->AreaCount(); 1.112 + for (uint32_t idx = 0; idx < areaElmCount; idx++) { 1.113 + nsIContent* areaContent = imageMapObj->GetAreaAt(idx); 1.114 + 1.115 + Accessible* area = mChildren.SafeElementAt(idx); 1.116 + if (!area || area->GetContent() != areaContent) { 1.117 + nsRefPtr<Accessible> area = new HTMLAreaAccessible(areaContent, mDoc); 1.118 + mDoc->BindToDocument(area, aria::GetRoleMap(areaContent)); 1.119 + 1.120 + if (!InsertChildAt(idx, area)) { 1.121 + mDoc->UnbindFromDocument(area); 1.122 + break; 1.123 + } 1.124 + 1.125 + if (aDoFireEvents) { 1.126 + nsRefPtr<AccShowEvent> event = new AccShowEvent(area, areaContent); 1.127 + mDoc->FireDelayedEvent(event); 1.128 + reorderEvent->AddSubMutationEvent(event); 1.129 + doReorderEvent = true; 1.130 + } 1.131 + } 1.132 + } 1.133 + 1.134 + // Fire reorder event if needed. 1.135 + if (doReorderEvent) 1.136 + mDoc->FireDelayedEvent(reorderEvent); 1.137 +} 1.138 + 1.139 +Accessible* 1.140 +HTMLImageMapAccessible::GetChildAccessibleFor(const nsINode* aNode) const 1.141 +{ 1.142 + uint32_t length = mChildren.Length(); 1.143 + for (uint32_t i = 0; i < length; i++) { 1.144 + Accessible* area = mChildren[i]; 1.145 + if (area->GetContent() == aNode) 1.146 + return area; 1.147 + } 1.148 + 1.149 + return nullptr; 1.150 +} 1.151 + 1.152 +//////////////////////////////////////////////////////////////////////////////// 1.153 +// HTMLImageMapAccessible: Accessible protected 1.154 + 1.155 +void 1.156 +HTMLImageMapAccessible::CacheChildren() 1.157 +{ 1.158 + UpdateChildAreas(false); 1.159 +} 1.160 + 1.161 + 1.162 +//////////////////////////////////////////////////////////////////////////////// 1.163 +// HTMLAreaAccessible 1.164 +//////////////////////////////////////////////////////////////////////////////// 1.165 + 1.166 +HTMLAreaAccessible:: 1.167 + HTMLAreaAccessible(nsIContent* aContent, DocAccessible* aDoc) : 1.168 + HTMLLinkAccessible(aContent, aDoc) 1.169 +{ 1.170 + // Make HTML area DOM element not accessible. HTML image map accessible 1.171 + // manages its tree itself. 1.172 + mStateFlags |= eNotNodeMapEntry; 1.173 +} 1.174 + 1.175 +//////////////////////////////////////////////////////////////////////////////// 1.176 +// HTMLAreaAccessible: nsIAccessible 1.177 + 1.178 +ENameValueFlag 1.179 +HTMLAreaAccessible::NativeName(nsString& aName) 1.180 +{ 1.181 + ENameValueFlag nameFlag = Accessible::NativeName(aName); 1.182 + if (!aName.IsEmpty()) 1.183 + return nameFlag; 1.184 + 1.185 + if (!mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::alt, aName)) 1.186 + GetValue(aName); 1.187 + 1.188 + return eNameOK; 1.189 +} 1.190 + 1.191 +void 1.192 +HTMLAreaAccessible::Description(nsString& aDescription) 1.193 +{ 1.194 + aDescription.Truncate(); 1.195 + 1.196 + // Still to do - follow IE's standard here 1.197 + nsCOMPtr<nsIDOMHTMLAreaElement> area(do_QueryInterface(mContent)); 1.198 + if (area) 1.199 + area->GetShape(aDescription); 1.200 +} 1.201 + 1.202 +//////////////////////////////////////////////////////////////////////////////// 1.203 +// HTMLAreaAccessible: Accessible public 1.204 + 1.205 +Accessible* 1.206 +HTMLAreaAccessible::ChildAtPoint(int32_t aX, int32_t aY, 1.207 + EWhichChildAtPoint aWhichChild) 1.208 +{ 1.209 + // Don't walk into area accessibles. 1.210 + return this; 1.211 +} 1.212 + 1.213 +//////////////////////////////////////////////////////////////////////////////// 1.214 +// HTMLImageMapAccessible: HyperLinkAccessible 1.215 + 1.216 +uint32_t 1.217 +HTMLAreaAccessible::StartOffset() 1.218 +{ 1.219 + // Image map accessible is not hypertext accessible therefore 1.220 + // StartOffset/EndOffset implementations of Accessible doesn't work here. 1.221 + // We return index in parent because image map contains area links only which 1.222 + // are embedded objects. 1.223 + // XXX: image map should be a hypertext accessible. 1.224 + return IndexInParent(); 1.225 +} 1.226 + 1.227 +uint32_t 1.228 +HTMLAreaAccessible::EndOffset() 1.229 +{ 1.230 + return IndexInParent() + 1; 1.231 +} 1.232 + 1.233 +//////////////////////////////////////////////////////////////////////////////// 1.234 +// HTMLAreaAccessible: Accessible protected 1.235 + 1.236 +void 1.237 +HTMLAreaAccessible::CacheChildren() 1.238 +{ 1.239 + // No children for aria accessible. 1.240 +} 1.241 + 1.242 +void 1.243 +HTMLAreaAccessible::GetBoundsRect(nsRect& aBounds, nsIFrame** aBoundingFrame) 1.244 +{ 1.245 + nsIFrame* frame = GetFrame(); 1.246 + if (!frame) 1.247 + return; 1.248 + 1.249 + nsImageFrame* imageFrame = do_QueryFrame(frame); 1.250 + nsImageMap* map = imageFrame->GetImageMap(); 1.251 + 1.252 + nsresult rv = map->GetBoundsForAreaContent(mContent, aBounds); 1.253 + if (NS_FAILED(rv)) 1.254 + return; 1.255 + 1.256 + // XXX Areas are screwy; they return their rects as a pair of points, one pair 1.257 + // stored into the width and height. 1.258 + aBounds.width -= aBounds.x; 1.259 + aBounds.height -= aBounds.y; 1.260 + 1.261 + *aBoundingFrame = frame; 1.262 +}