Shaka Player Embedded
element.cc
Go to the documentation of this file.
1 // Copyright 2016 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "src/js/dom/element.h"
16 
17 #include "src/js/dom/attr.h"
18 #include "src/js/dom/document.h"
19 #include "src/js/dom/text.h"
20 #include "src/memory/heap_tracer.h"
21 
22 namespace shaka {
23 namespace js {
24 namespace dom {
25 
26 Element::Element(RefPtr<Document> document, const std::string& local_name,
27  optional<std::string> namespace_uri,
28  optional<std::string> namespace_prefix)
29  : ContainerNode(ELEMENT_NODE, document),
30  namespace_uri(namespace_uri),
31  namespace_prefix(namespace_prefix),
32  local_name(local_name) {}
33 
34 // \cond Doxygen_Skip
35 Element::~Element() {}
36 // \endcond Doxygen_Skip
37 
38 void Element::Trace(memory::HeapTracer* tracer) const {
39  ContainerNode::Trace(tracer);
40  tracer->Trace(&attributes_);
41 }
42 
43 std::string Element::tag_name() const {
45  return local_name;
46  return namespace_prefix.value() + ":" + local_name;
47 }
48 
49 std::string Element::node_name() const {
50  return tag_name();
51 }
52 
54  return nullopt;
55 }
56 
58  std::string ret;
59  for (auto& child : child_nodes()) {
60  if (child->node_type() == TEXT_NODE) {
61  ret.append(static_cast<Text*>(child.get())->data());
62  } else if (child->is_element()) {
63  auto temp = child->TextContent();
64  DCHECK(temp.has_value());
65  ret.append(temp.value());
66  }
67  }
68  return ret;
69 }
70 
72  auto it = FindAttribute(name);
73  if (it == attributes_.end())
74  return nullopt;
75  return (*it)->value;
76 }
77 
79  const std::string& name) const {
80  auto it = FindAttributeNS(ns, name);
81  if (it == attributes_.end())
82  return nullopt;
83  return (*it)->value;
84 }
85 
86 bool Element::HasAttribute(const std::string& name) const {
87  return FindAttribute(name) != attributes_.end();
88 }
89 
90 bool Element::HasAttributeNS(const std::string& ns,
91  const std::string& name) const {
92  return FindAttributeNS(ns, name) != attributes_.end();
93 }
94 
95 void Element::SetAttribute(const std::string& key, const std::string& value) {
96  auto it = FindAttribute(key);
97  if (it != attributes_.end()) {
98  (*it)->value = value;
99  } else {
100  attributes_.emplace_back(
101  new Attr(document(), this, key, nullopt, nullopt, value));
102  }
103 }
104 
105 void Element::SetAttributeNS(const std::string& ns, const std::string& key,
106  const std::string& value) {
107  // |key| is a qualified name, e.g. 'foo:bar'. We search by local name, so
108  // split to get just 'bar'.
109  auto split_at = key.find(':');
110  CHECK_NE(split_at, std::string::npos);
111  const std::string local_name = key.substr(split_at + 1);
112  const std::string prefix = key.substr(0, split_at);
113 
114  auto it = FindAttributeNS(ns, local_name);
115  if (it != attributes_.end()) {
116  (*it)->value = value;
117  } else {
118  attributes_.push_back(
119  new Attr(document(), this, local_name, ns, prefix, value));
120  }
121 }
122 
123 void Element::RemoveAttribute(const std::string& attr) {
124  auto it = FindAttribute(attr);
125  if (it != attributes_.end())
126  attributes_.erase(it);
127 }
128 
129 void Element::RemoveAttributeNS(const std::string& ns,
130  const std::string& attr) {
131  auto it = FindAttributeNS(ns, attr);
132  if (it != attributes_.end())
133  attributes_.erase(it);
134 }
135 
136 Element::attr_iter Element::FindAttribute(const std::string& name) {
137  auto it = attributes_.begin();
138  for (; it != attributes_.end(); it++) {
139  if ((*it)->attr_name() == name)
140  return it;
141  }
142  return it;
143 }
144 
145 Element::attr_iter Element::FindAttributeNS(const std::string& ns,
146  const std::string& name) {
147  auto it = attributes_.begin();
148  for (; it != attributes_.end(); it++) {
149  if ((*it)->namespace_uri == ns && (*it)->local_name == name)
150  return it;
151  }
152  return it;
153 }
154 
155 std::vector<RefPtr<Attr>> Element::attributes() const {
156  return std::vector<RefPtr<Attr>>(attributes_.begin(), attributes_.end());
157 }
158 
160  AddReadOnlyProperty("namespaceURI", &Element::namespace_uri);
161  AddReadOnlyProperty("prefix", &Element::namespace_prefix);
162  AddReadOnlyProperty("localName", &Element::local_name);
163  AddReadOnlyProperty("id", &Element::id);
164 
165  AddGenericProperty("tagName", &Element::tag_name);
166 
167  AddMemberFunction("hasAttributes", &Element::has_attributes);
168  AddMemberFunction("getAttribute", &Element::GetAttribute);
169  AddMemberFunction("getAttributeNS", &Element::GetAttributeNS);
170  AddMemberFunction("setAttribute", &Element::SetAttribute);
171  AddMemberFunction("setAttributeNS", &Element::SetAttributeNS);
172  AddMemberFunction("hasAttribute", &Element::HasAttribute);
173  AddMemberFunction("hasAttributeNS", &Element::HasAttributeNS);
174  AddMemberFunction("removeAttribute", &Element::RemoveAttribute);
175  AddMemberFunction("removeAttributeNS", &Element::RemoveAttributeNS);
176 
177  AddGenericProperty("attributes", &Element::attributes);
178 
179  NotImplemented("className");
180  NotImplemented("classList");
181  NotImplemented("slot");
182 
183  NotImplemented("getAttributeNames");
184 
185  NotImplemented("getAttributeNode");
186  NotImplemented("getAttributeNodeNS");
187  NotImplemented("setAttributeNode");
188  NotImplemented("setAttributeNodeNS");
189  NotImplemented("removeAttributeNode");
190 
191  NotImplemented("attachShadow");
192  NotImplemented("shadowRoot");
193 
194  NotImplemented("closest");
195  NotImplemented("matches");
196  NotImplemented("webkitMatchesSelector");
197 
198  NotImplemented("insertAdjacentElement");
199  NotImplemented("insertAdjacentText");
200 }
201 
202 } // namespace dom
203 } // namespace js
204 } // namespace shaka
bool HasAttribute(const std::string &name) const
Definition: element.cc:86
void RemoveAttributeNS(const std::string &ns, const std::string &attr)
Definition: element.cc:129
std::vector< RefPtr< Attr > > attributes() const
Definition: element.cc:155
bool has_attributes() const
Definition: element.h:55
optional< std::string > NodeValue() const override
Definition: element.cc:53
const std::string id
Definition: element.h:47
const nullopt_t nullopt
Definition: optional.cc:22
const optional< std::string > namespace_uri
Definition: element.h:44
bool HasAttributeNS(const std::string &ns, const std::string &name) const
Definition: element.cc:90
const T & value() const &
Definition: optional.h:147
virtual void RemoveAttribute(const std::string &attr)
Definition: element.cc:123
optional< std::string > TextContent() const override
Definition: element.cc:57
Element(RefPtr< Document > document, const std::string &local_name, optional< std::string > namespace_uri, optional< std::string > namespace_prefix)
Definition: element.cc:26
void Trace(memory::HeapTracer *tracer) const override
Definition: element.cc:38
RefPtr< Document > document() const
Definition: node.cc:47
optional< std::string > GetAttribute(const std::string &name) const
Definition: element.cc:71
std::string node_name() const override
Definition: element.cc:49
void Trace(const Traceable *ptr)
Definition: heap_tracer.cc:43
void SetAttributeNS(const std::string &ns, const std::string &key, const std::string &value)
Definition: element.cc:105
void SetAttribute(const std::string &key, const std::string &value)
Definition: element.cc:95
const std::string local_name
Definition: element.h:46
std::vector< RefPtr< Node > > child_nodes() const
Definition: node.cc:55
optional< std::string > GetAttributeNS(const std::string &ns, const std::string &name) const
Definition: element.cc:78
std::string tag_name() const
Definition: element.cc:43
const optional< std::string > namespace_prefix
Definition: element.h:45
bool has_value() const
Definition: optional.h:143
void Trace(memory::HeapTracer *tracer) const override
Definition: node.cc:35
std::string name() const