1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 /* code for HTML client-side image maps */
8 
9 #ifndef nsImageMap_h
10 #define nsImageMap_h
11 
12 #include "mozilla/gfx/2D.h"
13 #include "nsCOMPtr.h"
14 #include "nsCoord.h"
15 #include "nsTArray.h"
16 #include "nsStubMutationObserver.h"
17 #include "nsIDOMEventListener.h"
18 #include "Units.h"
19 
20 class Area;
21 class nsImageFrame;
22 class nsIFrame;
23 class nsIContent;
24 struct nsRect;
25 
26 namespace mozilla {
27 namespace dom {
28 class HTMLAreaElement;
29 }
30 }  // namespace mozilla
31 
32 class nsImageMap final : public nsStubMutationObserver,
33                          public nsIDOMEventListener {
34   typedef mozilla::gfx::DrawTarget DrawTarget;
35   typedef mozilla::gfx::ColorPattern ColorPattern;
36   typedef mozilla::gfx::StrokeOptions StrokeOptions;
37 
38  public:
39   nsImageMap();
40 
41   void Init(nsImageFrame* aImageFrame, nsIContent* aMap);
42 
43   /**
44    * Return the first area element (in content order) for the given point in
45    * CSS pixel coordinate or nullptr if the coordinate is outside all areas.
46    */
47   mozilla::dom::HTMLAreaElement* GetArea(const mozilla::CSSIntPoint& aPt) const;
48 
49   /**
50    * Return area elements count associated with the image map.
51    */
AreaCount()52   uint32_t AreaCount() const { return mAreas.Length(); }
53 
54   /**
55    * Return area element at the given index.
56    */
57   mozilla::dom::HTMLAreaElement* GetAreaAt(uint32_t aIndex) const;
58 
59   void Draw(nsIFrame* aFrame, DrawTarget& aDrawTarget,
60             const ColorPattern& aColor,
61             const StrokeOptions& aStrokeOptions = StrokeOptions());
62 
63   /**
64    * Called just before the nsImageFrame releases us.
65    * Used to break the cycle caused by the DOM listener.
66    */
67   void Destroy();
68 
69   // nsISupports
70   NS_DECL_ISUPPORTS
71 
72   // nsIMutationObserver
73   NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
74   NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
75   NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
76   NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
77   NS_DECL_NSIMUTATIONOBSERVER_PARENTCHAINCHANGED
78 
79   // nsIDOMEventListener
80   NS_DECL_NSIDOMEVENTLISTENER
81 
82   nsresult GetBoundsForAreaContent(nsIContent* aContent, nsRect& aBounds);
83 
84   using AreaList = AutoTArray<mozilla::UniquePtr<Area>, 8>;
85 
86  protected:
87   virtual ~nsImageMap();
88 
89   void FreeAreas();
90 
91   void UpdateAreas();
92 
93   void SearchForAreas(nsIContent* aParent);
94 
95   void AddArea(mozilla::dom::HTMLAreaElement* aArea);
96   void AreaRemoved(mozilla::dom::HTMLAreaElement* aArea);
97 
98   void MaybeUpdateAreas(nsIContent* aContent);
99 
100   nsImageFrame* mImageFrame;  // the frame that owns us
101   nsCOMPtr<nsIContent> mMap;
102 
103   // almost always has some entries
104   AreaList mAreas;
105 
106   // This is set when we search for all area children and tells us whether we
107   // should consider the whole subtree or just direct children when we get
108   // content notifications about changes inside the map subtree.
109   bool mConsiderWholeSubtree;
110 };
111 
112 #endif /* nsImageMap_h */
113