accessible/src/html/HTMLImageMapAccessible.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #include "HTMLImageMapAccessible.h"
     8 #include "ARIAMap.h"
     9 #include "nsAccUtils.h"
    10 #include "DocAccessible-inl.h"
    11 #include "Role.h"
    13 #include "nsIDOMHTMLCollection.h"
    14 #include "nsIServiceManager.h"
    15 #include "nsIDOMElement.h"
    16 #include "nsIDOMHTMLAreaElement.h"
    17 #include "nsIFrame.h"
    18 #include "nsImageFrame.h"
    19 #include "nsImageMap.h"
    20 #include "nsIURI.h"
    22 using namespace mozilla::a11y;
    24 ////////////////////////////////////////////////////////////////////////////////
    25 // HTMLImageMapAccessible
    26 ////////////////////////////////////////////////////////////////////////////////
    28 HTMLImageMapAccessible::
    29   HTMLImageMapAccessible(nsIContent* aContent, DocAccessible* aDoc) :
    30   ImageAccessibleWrap(aContent, aDoc)
    31 {
    32   mType = eImageMapType;
    33 }
    35 ////////////////////////////////////////////////////////////////////////////////
    36 // HTMLImageMapAccessible: nsISupports
    38 NS_IMPL_ISUPPORTS_INHERITED0(HTMLImageMapAccessible, ImageAccessible)
    40 ////////////////////////////////////////////////////////////////////////////////
    41 // HTMLImageMapAccessible: Accessible public
    43 role
    44 HTMLImageMapAccessible::NativeRole()
    45 {
    46   return roles::IMAGE_MAP;
    47 }
    49 ////////////////////////////////////////////////////////////////////////////////
    50 // HTMLImageMapAccessible: HyperLinkAccessible
    52 uint32_t
    53 HTMLImageMapAccessible::AnchorCount()
    54 {
    55   return ChildCount();
    56 }
    58 Accessible*
    59 HTMLImageMapAccessible::AnchorAt(uint32_t aAnchorIndex)
    60 {
    61   return GetChildAt(aAnchorIndex);
    62 }
    64 already_AddRefed<nsIURI>
    65 HTMLImageMapAccessible::AnchorURIAt(uint32_t aAnchorIndex)
    66 {
    67   Accessible* area = GetChildAt(aAnchorIndex);
    68   if (!area)
    69     return nullptr;
    71   nsIContent* linkContent = area->GetContent();
    72   return linkContent ? linkContent->GetHrefURI() : nullptr;
    73 }
    75 ////////////////////////////////////////////////////////////////////////////////
    76 // HTMLImageMapAccessible: public
    78 void
    79 HTMLImageMapAccessible::UpdateChildAreas(bool aDoFireEvents)
    80 {
    81   nsImageFrame* imageFrame = do_QueryFrame(mContent->GetPrimaryFrame());
    83   // If image map is not initialized yet then we trigger one time more later.
    84   nsImageMap* imageMapObj = imageFrame->GetExistingImageMap();
    85   if (!imageMapObj)
    86     return;
    88   bool doReorderEvent = false;
    89   nsRefPtr<AccReorderEvent> reorderEvent = new AccReorderEvent(this);
    91   // Remove areas that are not a valid part of the image map anymore.
    92   for (int32_t childIdx = mChildren.Length() - 1; childIdx >= 0; childIdx--) {
    93     Accessible* area = mChildren.ElementAt(childIdx);
    94     if (area->GetContent()->GetPrimaryFrame())
    95       continue;
    97     if (aDoFireEvents) {
    98       nsRefPtr<AccHideEvent> event = new AccHideEvent(area, area->GetContent());
    99       mDoc->FireDelayedEvent(event);
   100       reorderEvent->AddSubMutationEvent(event);
   101       doReorderEvent = true;
   102     }
   104     RemoveChild(area);
   105   }
   107   // Insert new areas into the tree.
   108   uint32_t areaElmCount = imageMapObj->AreaCount();
   109   for (uint32_t idx = 0; idx < areaElmCount; idx++) {
   110     nsIContent* areaContent = imageMapObj->GetAreaAt(idx);
   112     Accessible* area = mChildren.SafeElementAt(idx);
   113     if (!area || area->GetContent() != areaContent) {
   114       nsRefPtr<Accessible> area = new HTMLAreaAccessible(areaContent, mDoc);
   115       mDoc->BindToDocument(area, aria::GetRoleMap(areaContent));
   117       if (!InsertChildAt(idx, area)) {
   118         mDoc->UnbindFromDocument(area);
   119         break;
   120       }
   122       if (aDoFireEvents) {
   123         nsRefPtr<AccShowEvent> event = new AccShowEvent(area, areaContent);
   124         mDoc->FireDelayedEvent(event);
   125         reorderEvent->AddSubMutationEvent(event);
   126         doReorderEvent = true;
   127       }
   128     }
   129   }
   131   // Fire reorder event if needed.
   132   if (doReorderEvent)
   133     mDoc->FireDelayedEvent(reorderEvent);
   134 }
   136 Accessible*
   137 HTMLImageMapAccessible::GetChildAccessibleFor(const nsINode* aNode) const
   138 {
   139   uint32_t length = mChildren.Length();
   140   for (uint32_t i = 0; i < length; i++) {
   141     Accessible* area = mChildren[i];
   142     if (area->GetContent() == aNode)
   143       return area;
   144   }
   146   return nullptr;
   147 }
   149 ////////////////////////////////////////////////////////////////////////////////
   150 // HTMLImageMapAccessible: Accessible protected
   152 void
   153 HTMLImageMapAccessible::CacheChildren()
   154 {
   155   UpdateChildAreas(false);
   156 }
   159 ////////////////////////////////////////////////////////////////////////////////
   160 // HTMLAreaAccessible
   161 ////////////////////////////////////////////////////////////////////////////////
   163 HTMLAreaAccessible::
   164   HTMLAreaAccessible(nsIContent* aContent, DocAccessible* aDoc) :
   165   HTMLLinkAccessible(aContent, aDoc)
   166 {
   167   // Make HTML area DOM element not accessible. HTML image map accessible
   168   // manages its tree itself.
   169   mStateFlags |= eNotNodeMapEntry;
   170 }
   172 ////////////////////////////////////////////////////////////////////////////////
   173 // HTMLAreaAccessible: nsIAccessible
   175 ENameValueFlag
   176 HTMLAreaAccessible::NativeName(nsString& aName)
   177 {
   178   ENameValueFlag nameFlag = Accessible::NativeName(aName);
   179   if (!aName.IsEmpty())
   180     return nameFlag;
   182   if (!mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::alt, aName))
   183     GetValue(aName);
   185   return eNameOK;
   186 }
   188 void
   189 HTMLAreaAccessible::Description(nsString& aDescription)
   190 {
   191   aDescription.Truncate();
   193   // Still to do - follow IE's standard here
   194   nsCOMPtr<nsIDOMHTMLAreaElement> area(do_QueryInterface(mContent));
   195   if (area)
   196     area->GetShape(aDescription);
   197 }
   199 ////////////////////////////////////////////////////////////////////////////////
   200 // HTMLAreaAccessible: Accessible public
   202 Accessible*
   203 HTMLAreaAccessible::ChildAtPoint(int32_t aX, int32_t aY,
   204                                  EWhichChildAtPoint aWhichChild)
   205 {
   206   // Don't walk into area accessibles.
   207   return this;
   208 }
   210 ////////////////////////////////////////////////////////////////////////////////
   211 // HTMLImageMapAccessible: HyperLinkAccessible
   213 uint32_t
   214 HTMLAreaAccessible::StartOffset()
   215 {
   216   // Image map accessible is not hypertext accessible therefore
   217   // StartOffset/EndOffset implementations of Accessible doesn't work here.
   218   // We return index in parent because image map contains area links only which
   219   // are embedded objects.
   220   // XXX: image map should be a hypertext accessible.
   221   return IndexInParent();
   222 }
   224 uint32_t
   225 HTMLAreaAccessible::EndOffset()
   226 {
   227   return IndexInParent() + 1;
   228 }
   230 ////////////////////////////////////////////////////////////////////////////////
   231 // HTMLAreaAccessible: Accessible protected
   233 void
   234 HTMLAreaAccessible::CacheChildren()
   235 {
   236   // No children for aria accessible.
   237 }
   239 void
   240 HTMLAreaAccessible::GetBoundsRect(nsRect& aBounds, nsIFrame** aBoundingFrame)
   241 {
   242   nsIFrame* frame = GetFrame();
   243   if (!frame)
   244     return;
   246   nsImageFrame* imageFrame = do_QueryFrame(frame);
   247   nsImageMap* map = imageFrame->GetImageMap();
   249   nsresult rv = map->GetBoundsForAreaContent(mContent, aBounds);
   250   if (NS_FAILED(rv))
   251     return;
   253   // XXX Areas are screwy; they return their rects as a pair of points, one pair
   254   // stored into the width and height.
   255   aBounds.width -= aBounds.x;
   256   aBounds.height -= aBounds.y;
   258   *aBoundingFrame = frame;
   259 }

mercurial