--- a/layout/generic/nsImageMap.cpp
+++ b/layout/generic/nsImageMap.cpp
@@ -5,16 +5,17 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* code for HTML client-side image maps */
#include "nsImageMap.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/Event.h" // for nsIDOMEvent::InternalDOMEvent()
+#include "mozilla/dom/HTMLAreaElement.h"
#include "mozilla/gfx/PathHelpers.h"
#include "mozilla/UniquePtr.h"
#include "nsString.h"
#include "nsReadableUtils.h"
#include "nsPresContext.h"
#include "nsNameSpaceManager.h"
#include "nsGkAtoms.h"
#include "nsImageFrame.h"
@@ -25,43 +26,44 @@
#include "ImageLayers.h"
#ifdef ACCESSIBILITY
#include "nsAccessibilityService.h"
#endif
using namespace mozilla;
using namespace mozilla::gfx;
+using namespace mozilla::dom;
class Area {
public:
- explicit Area(nsIContent* aArea);
+ explicit Area(HTMLAreaElement* aArea);
virtual ~Area();
virtual void ParseCoords(const nsAString& aSpec);
virtual bool IsInside(nscoord x, nscoord y) const = 0;
virtual void Draw(nsIFrame* aFrame, DrawTarget& aDrawTarget,
const ColorPattern& aColor,
const StrokeOptions& aStrokeOptions) = 0;
virtual void GetRect(nsIFrame* aFrame, nsRect& aRect) = 0;
void HasFocus(bool aHasFocus);
- nsCOMPtr<nsIContent> mArea;
+ RefPtr<HTMLAreaElement> mArea;
UniquePtr<nscoord[]> mCoords;
int32_t mNumCoords;
bool mHasFocus;
};
-Area::Area(nsIContent* aArea)
+Area::Area(HTMLAreaElement* aArea)
: mArea(aArea)
{
MOZ_COUNT_CTOR(Area);
- NS_PRECONDITION(mArea, "How did that happen?");
+ MOZ_ASSERT(mArea, "How did that happen?");
mNumCoords = 0;
mHasFocus = false;
}
Area::~Area()
{
MOZ_COUNT_DTOR(Area);
}
@@ -262,26 +264,26 @@ void Area::HasFocus(bool aHasFocus)
{
mHasFocus = aHasFocus;
}
//----------------------------------------------------------------------
class DefaultArea : public Area {
public:
- explicit DefaultArea(nsIContent* aArea);
+ explicit DefaultArea(HTMLAreaElement* aArea);
virtual bool IsInside(nscoord x, nscoord y) const override;
virtual void Draw(nsIFrame* aFrame, DrawTarget& aDrawTarget,
const ColorPattern& aColor,
const StrokeOptions& aStrokeOptions) override;
virtual void GetRect(nsIFrame* aFrame, nsRect& aRect) override;
};
-DefaultArea::DefaultArea(nsIContent* aArea)
+DefaultArea::DefaultArea(HTMLAreaElement* aArea)
: Area(aArea)
{
}
bool DefaultArea::IsInside(nscoord x, nscoord y) const
{
return true;
}
@@ -306,27 +308,27 @@ void DefaultArea::GetRect(nsIFrame* aFra
aRect = aFrame->GetRect();
aRect.MoveTo(0, 0);
}
//----------------------------------------------------------------------
class RectArea : public Area {
public:
- explicit RectArea(nsIContent* aArea);
+ explicit RectArea(HTMLAreaElement* aArea);
virtual void ParseCoords(const nsAString& aSpec) override;
virtual bool IsInside(nscoord x, nscoord y) const override;
virtual void Draw(nsIFrame* aFrame, DrawTarget& aDrawTarget,
const ColorPattern& aColor,
const StrokeOptions& aStrokeOptions) override;
virtual void GetRect(nsIFrame* aFrame, nsRect& aRect) override;
};
-RectArea::RectArea(nsIContent* aArea)
+RectArea::RectArea(HTMLAreaElement* aArea)
: Area(aArea)
{
}
void RectArea::ParseCoords(const nsAString& aSpec)
{
Area::ParseCoords(aSpec);
@@ -412,27 +414,27 @@ void RectArea::GetRect(nsIFrame* aFrame,
aRect.SetRect(x1, y1, x2, y2);
}
}
//----------------------------------------------------------------------
class PolyArea : public Area {
public:
- explicit PolyArea(nsIContent* aArea);
+ explicit PolyArea(HTMLAreaElement* aArea);
virtual void ParseCoords(const nsAString& aSpec) override;
virtual bool IsInside(nscoord x, nscoord y) const override;
virtual void Draw(nsIFrame* aFrame, DrawTarget& aDrawTarget,
const ColorPattern& aColor,
const StrokeOptions& aStrokeOptions) override;
virtual void GetRect(nsIFrame* aFrame, nsRect& aRect) override;
};
-PolyArea::PolyArea(nsIContent* aArea)
+PolyArea::PolyArea(HTMLAreaElement* aArea)
: Area(aArea)
{
}
void PolyArea::ParseCoords(const nsAString& aSpec)
{
Area::ParseCoords(aSpec);
@@ -569,27 +571,27 @@ void PolyArea::GetRect(nsIFrame* aFrame,
aRect.SetRect(x1, y1, x2, y2);
}
}
//----------------------------------------------------------------------
class CircleArea : public Area {
public:
- explicit CircleArea(nsIContent* aArea);
+ explicit CircleArea(HTMLAreaElement* aArea);
virtual void ParseCoords(const nsAString& aSpec) override;
virtual bool IsInside(nscoord x, nscoord y) const override;
virtual void Draw(nsIFrame* aFrame, DrawTarget& aDrawTarget,
const ColorPattern& aColor,
const StrokeOptions& aStrokeOptions) override;
virtual void GetRect(nsIFrame* aFrame, nsRect& aRect) override;
};
-CircleArea::CircleArea(nsIContent* aArea)
+CircleArea::CircleArea(HTMLAreaElement* aArea)
: Area(aArea)
{
}
void CircleArea::ParseCoords(const nsAString& aSpec)
{
Area::ParseCoords(aSpec);
@@ -742,72 +744,57 @@ nsImageMap::Init(nsImageFrame* aImageFra
mMap = aMap;
mMap->AddMutationObserver(this);
// "Compile" the areas in the map into faster access versions
UpdateAreas();
}
void
-nsImageMap::SearchForAreas(nsIContent* aParent, bool& aFoundArea,
- bool& aFoundAnchor)
+nsImageMap::SearchForAreas(nsIContent* aParent)
{
- uint32_t i, n = aParent->GetChildCount();
-
- // Look for <area> or <a> elements. We'll use whichever type we find first.
- for (i = 0; i < n; i++) {
- nsIContent *child = aParent->GetChildAt(i);
-
- // If we haven't determined that the map element contains an
- // <a> element yet, then look for <area>.
- if (!aFoundAnchor && child->IsHTMLElement(nsGkAtoms::area)) {
- aFoundArea = true;
- AddArea(child);
+ // Look for <area> elements.
+ for (nsIContent* child = aParent->GetFirstChild();
+ child;
+ child = child->GetNextSibling()) {
+ if (auto* area = HTMLAreaElement::FromContent(child)) {
+ AddArea(area);
// Continue to next child. This stops mConsiderWholeSubtree from
// getting set. It also makes us ignore children of <area>s which
// is consistent with how we react to dynamic insertion of such
// children.
continue;
}
- // If we haven't determined that the map element contains an
- // <area> element yet, then look for <a>.
- if (!aFoundArea && child->IsHTMLElement(nsGkAtoms::a)) {
- aFoundAnchor = true;
- AddArea(child);
- }
-
if (child->IsElement()) {
mConsiderWholeSubtree = true;
- SearchForAreas(child, aFoundArea, aFoundAnchor);
+ SearchForAreas(child);
}
}
}
void
nsImageMap::UpdateAreas()
{
// Get rid of old area data
FreeAreas();
- bool foundArea = false;
- bool foundAnchor = false;
mConsiderWholeSubtree = false;
+ SearchForAreas(mMap);
- SearchForAreas(mMap, foundArea, foundAnchor);
#ifdef ACCESSIBILITY
if (nsAccessibilityService* accService = GetAccService()) {
accService->UpdateImageMap(mImageFrame);
}
#endif
}
void
-nsImageMap::AddArea(nsIContent* aArea)
+nsImageMap::AddArea(HTMLAreaElement* aArea)
{
static nsIContent::AttrValuesArray strings[] =
{&nsGkAtoms::rect, &nsGkAtoms::rectangle,
&nsGkAtoms::circle, &nsGkAtoms::circ,
&nsGkAtoms::_default,
&nsGkAtoms::poly, &nsGkAtoms::polygon,
nullptr};
--- a/layout/generic/nsImageMap.h
+++ b/layout/generic/nsImageMap.h
@@ -17,16 +17,22 @@
#include "nsIDOMEventListener.h"
class Area;
class nsImageFrame;
class nsIFrame;
class nsIContent;
struct nsRect;
+namespace mozilla {
+namespace dom {
+class HTMLAreaElement;
+}
+}
+
class nsImageMap final : public nsStubMutationObserver,
public nsIDOMEventListener
{
typedef mozilla::gfx::DrawTarget DrawTarget;
typedef mozilla::gfx::ColorPattern ColorPattern;
typedef mozilla::gfx::StrokeOptions StrokeOptions;
public:
@@ -77,21 +83,20 @@ public:
nsRect& aBounds);
protected:
virtual ~nsImageMap();
void FreeAreas();
void UpdateAreas();
- void SearchForAreas(nsIContent* aParent,
- bool& aFoundArea,
- bool& aFoundAnchor);
- void AddArea(nsIContent* aArea);
+ void SearchForAreas(nsIContent* aParent);
+
+ void AddArea(mozilla::dom::HTMLAreaElement* aArea);
void MaybeUpdateAreas(nsIContent *aContent);
nsImageFrame* mImageFrame; // the frame that owns us
nsCOMPtr<nsIContent> mMap;
AutoTArray<Area*, 8> mAreas; // almost always has some entries
// This is set when we search for all area children and tells us whether we