Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/accessible/html/HTMLImageMapAccessible.cpp
Line
Count
Source (jump to first uncovered line)
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/. */
5
6
#include "HTMLImageMapAccessible.h"
7
8
#include "ARIAMap.h"
9
#include "nsAccUtils.h"
10
#include "DocAccessible-inl.h"
11
#include "Role.h"
12
13
#include "nsIServiceManager.h"
14
#include "nsIFrame.h"
15
#include "nsImageFrame.h"
16
#include "nsImageMap.h"
17
#include "nsIURI.h"
18
#include "mozilla/dom/HTMLAreaElement.h"
19
20
using namespace mozilla::a11y;
21
22
////////////////////////////////////////////////////////////////////////////////
23
// HTMLImageMapAccessible
24
////////////////////////////////////////////////////////////////////////////////
25
26
HTMLImageMapAccessible::
27
  HTMLImageMapAccessible(nsIContent* aContent, DocAccessible* aDoc) :
28
  ImageAccessibleWrap(aContent, aDoc)
29
0
{
30
0
  mType = eImageMapType;
31
0
32
0
  UpdateChildAreas(false);
33
0
}
34
35
////////////////////////////////////////////////////////////////////////////////
36
// HTMLImageMapAccessible: Accessible public
37
38
role
39
HTMLImageMapAccessible::NativeRole() const
40
0
{
41
0
  return roles::IMAGE_MAP;
42
0
}
43
44
////////////////////////////////////////////////////////////////////////////////
45
// HTMLImageMapAccessible: HyperLinkAccessible
46
47
uint32_t
48
HTMLImageMapAccessible::AnchorCount()
49
0
{
50
0
  return ChildCount();
51
0
}
52
53
Accessible*
54
HTMLImageMapAccessible::AnchorAt(uint32_t aAnchorIndex)
55
0
{
56
0
  return GetChildAt(aAnchorIndex);
57
0
}
58
59
already_AddRefed<nsIURI>
60
HTMLImageMapAccessible::AnchorURIAt(uint32_t aAnchorIndex) const
61
0
{
62
0
  Accessible* area = GetChildAt(aAnchorIndex);
63
0
  if (!area)
64
0
    return nullptr;
65
0
66
0
  nsIContent* linkContent = area->GetContent();
67
0
  return linkContent ? linkContent->GetHrefURI() : nullptr;
68
0
}
69
70
////////////////////////////////////////////////////////////////////////////////
71
// HTMLImageMapAccessible: public
72
73
void
74
HTMLImageMapAccessible::UpdateChildAreas(bool aDoFireEvents)
75
0
{
76
0
  nsImageFrame* imageFrame = do_QueryFrame(mContent->GetPrimaryFrame());
77
0
78
0
  // If image map is not initialized yet then we trigger one time more later.
79
0
  nsImageMap* imageMapObj = imageFrame->GetExistingImageMap();
80
0
  if (!imageMapObj)
81
0
    return;
82
0
83
0
  TreeMutation mt(this, TreeMutation::kNoEvents & !aDoFireEvents);
84
0
85
0
  // Remove areas that are not a valid part of the image map anymore.
86
0
  for (int32_t childIdx = mChildren.Length() - 1; childIdx >= 0; childIdx--) {
87
0
    Accessible* area = mChildren.ElementAt(childIdx);
88
0
    if (area->GetContent()->GetPrimaryFrame())
89
0
      continue;
90
0
91
0
    mt.BeforeRemoval(area);
92
0
    RemoveChild(area);
93
0
  }
94
0
95
0
  // Insert new areas into the tree.
96
0
  uint32_t areaElmCount = imageMapObj->AreaCount();
97
0
  for (uint32_t idx = 0; idx < areaElmCount; idx++) {
98
0
    nsIContent* areaContent = imageMapObj->GetAreaAt(idx);
99
0
    Accessible* area = mChildren.SafeElementAt(idx);
100
0
    if (!area || area->GetContent() != areaContent) {
101
0
      RefPtr<Accessible> area = new HTMLAreaAccessible(areaContent, mDoc);
102
0
      mDoc->BindToDocument(area, aria::GetRoleMap(areaContent->AsElement()));
103
0
104
0
      if (!InsertChildAt(idx, area)) {
105
0
        mDoc->UnbindFromDocument(area);
106
0
        break;
107
0
      }
108
0
109
0
      mt.AfterInsertion(area);
110
0
    }
111
0
  }
112
0
113
0
  mt.Done();
114
0
}
115
116
Accessible*
117
HTMLImageMapAccessible::GetChildAccessibleFor(const nsINode* aNode) const
118
0
{
119
0
  uint32_t length = mChildren.Length();
120
0
  for (uint32_t i = 0; i < length; i++) {
121
0
    Accessible* area = mChildren[i];
122
0
    if (area->GetContent() == aNode)
123
0
      return area;
124
0
  }
125
0
126
0
  return nullptr;
127
0
}
128
129
////////////////////////////////////////////////////////////////////////////////
130
// HTMLAreaAccessible
131
////////////////////////////////////////////////////////////////////////////////
132
133
HTMLAreaAccessible::
134
  HTMLAreaAccessible(nsIContent* aContent, DocAccessible* aDoc) :
135
  HTMLLinkAccessible(aContent, aDoc)
136
0
{
137
0
  // Make HTML area DOM element not accessible. HTML image map accessible
138
0
  // manages its tree itself.
139
0
  mStateFlags |= eNotNodeMapEntry;
140
0
}
141
142
////////////////////////////////////////////////////////////////////////////////
143
// HTMLAreaAccessible: Accessible
144
145
ENameValueFlag
146
HTMLAreaAccessible::NativeName(nsString& aName) const
147
0
{
148
0
  ENameValueFlag nameFlag = Accessible::NativeName(aName);
149
0
  if (!aName.IsEmpty())
150
0
    return nameFlag;
151
0
152
0
  if (!mContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::alt, aName))
153
0
    Value(aName);
154
0
155
0
  return eNameOK;
156
0
}
157
158
void
159
HTMLAreaAccessible::Description(nsString& aDescription)
160
0
{
161
0
  aDescription.Truncate();
162
0
163
0
  // Still to do - follow IE's standard here
164
0
  RefPtr<dom::HTMLAreaElement> area =
165
0
    dom::HTMLAreaElement::FromNodeOrNull(mContent);
166
0
  if (area)
167
0
    area->GetShape(aDescription);
168
0
}
169
170
////////////////////////////////////////////////////////////////////////////////
171
// HTMLAreaAccessible: Accessible public
172
173
Accessible*
174
HTMLAreaAccessible::ChildAtPoint(int32_t aX, int32_t aY,
175
                                 EWhichChildAtPoint aWhichChild)
176
0
{
177
0
  // Don't walk into area accessibles.
178
0
  return this;
179
0
}
180
181
////////////////////////////////////////////////////////////////////////////////
182
// HTMLImageMapAccessible: HyperLinkAccessible
183
184
uint32_t
185
HTMLAreaAccessible::StartOffset()
186
0
{
187
0
  // Image map accessible is not hypertext accessible therefore
188
0
  // StartOffset/EndOffset implementations of Accessible doesn't work here.
189
0
  // We return index in parent because image map contains area links only which
190
0
  // are embedded objects.
191
0
  // XXX: image map should be a hypertext accessible.
192
0
  return IndexInParent();
193
0
}
194
195
uint32_t
196
HTMLAreaAccessible::EndOffset()
197
0
{
198
0
  return IndexInParent() + 1;
199
0
}
200
201
nsRect
202
HTMLAreaAccessible::RelativeBounds(nsIFrame** aBoundingFrame) const
203
0
{
204
0
  nsIFrame* frame = GetFrame();
205
0
  if (!frame)
206
0
    return nsRect();
207
0
208
0
  nsImageFrame* imageFrame = do_QueryFrame(frame);
209
0
  nsImageMap* map = imageFrame->GetImageMap();
210
0
211
0
  nsRect bounds;
212
0
  nsresult rv = map->GetBoundsForAreaContent(mContent, bounds);
213
0
  if (NS_FAILED(rv))
214
0
    return nsRect();
215
0
216
0
  // XXX Areas are screwy; they return their rects as a pair of points, one pair
217
0
  // stored into the width and height.
218
0
  *aBoundingFrame = frame;
219
0
  bounds.SizeTo(bounds.Width() - bounds.X(), bounds.Height() - bounds.Y());
220
0
  return bounds;
221
0
}