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 
19 class Area;
20 class nsImageFrame;
21 class nsIFrame;
22 class nsIContent;
23 struct nsRect;
24 
25 namespace mozilla {
26 namespace dom {
27 class HTMLAreaElement;
28 }
29 }  // namespace mozilla
30 
31 class nsImageMap final : public nsStubMutationObserver,
32                          public nsIDOMEventListener {
33   typedef mozilla::gfx::DrawTarget DrawTarget;
34   typedef mozilla::gfx::ColorPattern ColorPattern;
35   typedef mozilla::gfx::StrokeOptions StrokeOptions;
36 
37  public:
38   nsImageMap();
39 
40   void Init(nsImageFrame* aImageFrame, nsIContent* aMap);
41 
42   /**
43    * Return the first area element (in content order) for the given aX,aY pixel
44    * coordinate or nullptr if the coordinate is outside all areas.
45    */
46   mozilla::dom::HTMLAreaElement* GetArea(nscoord aX, nscoord aY) const;
47 
48   /**
49    * Return area elements count associated with the image map.
50    */
AreaCount()51   uint32_t AreaCount() const { return mAreas.Length(); }
52 
53   /**
54    * Return area element at the given index.
55    */
56   mozilla::dom::HTMLAreaElement* GetAreaAt(uint32_t aIndex) const;
57 
58   void Draw(nsIFrame* aFrame, DrawTarget& aDrawTarget,
59             const ColorPattern& aColor,
60             const StrokeOptions& aStrokeOptions = StrokeOptions());
61 
62   /**
63    * Called just before the nsImageFrame releases us.
64    * Used to break the cycle caused by the DOM listener.
65    */
66   void Destroy();
67 
68   // nsISupports
69   NS_DECL_ISUPPORTS
70 
71   // nsIMutationObserver
72   NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
73   NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
74   NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
75   NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
76   NS_DECL_NSIMUTATIONOBSERVER_PARENTCHAINCHANGED
77 
78   // nsIDOMEventListener
79   NS_DECL_NSIDOMEVENTLISTENER
80 
81   nsresult GetBoundsForAreaContent(nsIContent* aContent, nsRect& aBounds);
82 
83   using AreaList = AutoTArray<mozilla::UniquePtr<Area>, 8>;
84 
85  protected:
86   virtual ~nsImageMap();
87 
88   void FreeAreas();
89 
90   void UpdateAreas();
91 
92   void SearchForAreas(nsIContent* aParent);
93 
94   void AddArea(mozilla::dom::HTMLAreaElement* aArea);
95   void AreaRemoved(mozilla::dom::HTMLAreaElement* aArea);
96 
97   void MaybeUpdateAreas(nsIContent* aContent);
98 
99   nsImageFrame* mImageFrame;  // the frame that owns us
100   nsCOMPtr<nsIContent> mMap;
101 
102   // almost always has some entries
103   AreaList mAreas;
104 
105   // This is set when we search for all area children and tells us whether we
106   // should consider the whole subtree or just direct children when we get
107   // content notifications about changes inside the map subtree.
108   bool mConsiderWholeSubtree;
109 };
110 
111 #endif /* nsImageMap_h */
112