1 /*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * Copyright (C) 2004, 2005, 2006, 2007, 2010 Apple Inc. All rights reserved.
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public License
17 * along with this library; see the file COPYING.LIB. If not, write to
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 */
21
22 #include "third_party/blink/renderer/core/html/html_map_element.h"
23
24 #include "third_party/blink/renderer/core/dom/document.h"
25 #include "third_party/blink/renderer/core/dom/element_traversal.h"
26 #include "third_party/blink/renderer/core/dom/node_lists_node_data.h"
27 #include "third_party/blink/renderer/core/frame/web_feature.h"
28 #include "third_party/blink/renderer/core/html/html_area_element.h"
29 #include "third_party/blink/renderer/core/html/html_collection.h"
30 #include "third_party/blink/renderer/core/html/html_document.h"
31 #include "third_party/blink/renderer/core/html/html_image_element.h"
32 #include "third_party/blink/renderer/core/html_names.h"
33 #include "third_party/blink/renderer/core/layout/hit_test_result.h"
34 #include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
35
36 namespace blink {
37
HTMLMapElement(Document & document)38 HTMLMapElement::HTMLMapElement(Document& document)
39 : HTMLElement(html_names::kMapTag, document) {
40 UseCounter::Count(document, WebFeature::kMapElement);
41 }
42
43 HTMLMapElement::~HTMLMapElement() = default;
44
AreaForPoint(const PhysicalOffset & location,const LayoutObject * container_object)45 HTMLAreaElement* HTMLMapElement::AreaForPoint(
46 const PhysicalOffset& location,
47 const LayoutObject* container_object) {
48 HTMLAreaElement* default_area = nullptr;
49 for (HTMLAreaElement& area :
50 Traversal<HTMLAreaElement>::DescendantsOf(*this)) {
51 if (area.IsDefault() && !default_area)
52 default_area = &area;
53 else if (area.PointInArea(location, container_object))
54 return &area;
55 }
56
57 return default_area;
58 }
59
ImageElement()60 HTMLImageElement* HTMLMapElement::ImageElement() {
61 HTMLCollection* images = GetDocument().images();
62 for (unsigned i = 0; Element* curr = images->item(i); ++i) {
63 // The HTMLImageElement's useMap() value includes the '#' symbol at the
64 // beginning, which has to be stripped off.
65 auto& image_element = To<HTMLImageElement>(*curr);
66 String use_map_name =
67 image_element.FastGetAttribute(html_names::kUsemapAttr)
68 .GetString()
69 .Substring(1);
70 if (use_map_name == name_)
71 return &image_element;
72 }
73
74 return nullptr;
75 }
76
ParseAttribute(const AttributeModificationParams & params)77 void HTMLMapElement::ParseAttribute(const AttributeModificationParams& params) {
78 // FIXME: This logic seems wrong for XML documents.
79 // Either the id or name will be used depending on the order the attributes
80 // are parsed.
81
82 if (params.name == html_names::kIdAttr ||
83 params.name == html_names::kNameAttr) {
84 if (params.name == html_names::kIdAttr) {
85 // Call base class so that hasID bit gets set.
86 HTMLElement::ParseAttribute(params);
87 if (IsA<HTMLDocument>(GetDocument()))
88 return;
89 }
90 if (isConnected())
91 GetTreeScope().RemoveImageMap(*this);
92 String map_name = params.new_value;
93 if (map_name[0] == '#')
94 map_name = map_name.Substring(1);
95 name_ = AtomicString(map_name);
96 if (isConnected())
97 GetTreeScope().AddImageMap(*this);
98
99 return;
100 }
101
102 HTMLElement::ParseAttribute(params);
103 }
104
areas()105 HTMLCollection* HTMLMapElement::areas() {
106 return EnsureCachedCollection<HTMLCollection>(kMapAreas);
107 }
108
InsertedInto(ContainerNode & insertion_point)109 Node::InsertionNotificationRequest HTMLMapElement::InsertedInto(
110 ContainerNode& insertion_point) {
111 if (insertion_point.isConnected())
112 GetTreeScope().AddImageMap(*this);
113 return HTMLElement::InsertedInto(insertion_point);
114 }
115
RemovedFrom(ContainerNode & insertion_point)116 void HTMLMapElement::RemovedFrom(ContainerNode& insertion_point) {
117 if (insertion_point.isConnected())
118 GetTreeScope().RemoveImageMap(*this);
119 HTMLElement::RemovedFrom(insertion_point);
120 }
121
122 } // namespace blink
123