3 #include <wordring/html/html_atom.hpp>
4 #include <wordring/html/html_defs.hpp>
6 #include <wordring/encoding/encoding.hpp>
8 #include <wordring/whatwg/infra/infra.hpp>
25 template <
typename String>
28 template <
typename String1>
31 template <
typename String1>
34 template <
typename String1>
37 template <
typename String1>
40 template <
typename String1>
43 template <
typename String1>
46 template <
typename String1>
49 template <
typename String1>
52 template <
typename String1>
55 template <
typename String1>
59 using string_type = String;
66 : m_namespace_uri(
static_cast<ns_name
>(0))
68 , m_local_name(
static_cast<attribute_name
>(0))
80 simple_attr(ns_name ns, string_type
const& prefix, attribute_name name, string_type
const& val = string_type())
92 simple_attr(ns_name ns, string_type
const& prefix, string_type
const& name, string_type
const& val = string_type())
100 simple_attr(attribute_name name, string_type
const& val = string_type())
101 : m_namespace_uri(static_cast<ns_name>(0))
108 simple_attr(string_type
const& name, string_type
const& val = string_type())
109 : m_namespace_uri(static_cast<ns_name>(0))
116 simple_attr& operator=(simple_attr
const& rhs) =
default;
117 simple_attr& operator=(simple_attr&& rhs) =
default;
119 string_type namespace_uri()
const {
return static_cast<string_type
>(m_namespace_uri); }
121 void namespace_uri(string_type
const& uri) { m_namespace_uri = uri; }
123 ns_name namespace_uri_name()
const {
return m_namespace_uri; }
125 void namespace_uri_name(ns_name uri) { m_namespace_uri = uri; }
127 string_type
const& prefix()
const {
return m_prefix; }
129 void prefix(string_type
const& s) { m_prefix = s; }
131 string_type local_name()
const {
return static_cast<string_type
>(m_local_name); }
133 void local_name(string_type
const& name) { m_local_name = name; }
135 attribute_name local_name_name()
const {
return m_local_name; }
137 void local_name_name(attribute_name name) { m_local_name = name; }
139 string_type qualified_name()
const
141 string_type s = prefix();
142 if (!s.empty()) wordring::to_string(U
':', std::back_inserter(s));
143 s.append(local_name());
148 string_type
const& value()
const {
return m_value; }
150 void value(string_type
const& s) { m_value = s; }
153 namespace_uri_type m_namespace_uri;
154 string_type m_prefix;
155 local_name_type m_local_name;
160 static_assert(std::is_copy_constructible_v<simple_attr<std::u32string>>);
161 static_assert(std::is_copy_assignable_v<simple_attr<std::u32string>>);
167 template <
typename String1>
170 return lhs.m_namespace_uri == rhs.m_namespace_uri
171 && lhs.m_prefix == rhs.m_prefix
172 && lhs.m_local_name == rhs.m_local_name;
175 template <
typename String1>
176 inline bool operator==(simple_attr<String1>
const& lhs, attribute_name local_name)
178 return lhs == simple_attr<String1>(local_name);
181 template <
typename String1>
182 inline bool operator==(attribute_name local_name, simple_attr<String1>
const& rhs)
184 return simple_attr<String1>(local_name) == rhs;
187 template <
typename String1>
188 inline bool operator==(simple_attr<String1>
const& lhs, String1
const& local_name)
190 return lhs == simple_attr<String1>(local_name);
193 template <
typename String1>
194 inline bool operator==(String1
const& local_name, simple_attr<String1>
const& rhs)
196 return simple_attr<String1>(local_name) == rhs;
199 template <
typename String1>
200 inline bool operator!=(simple_attr<String1>
const& lhs, simple_attr<String1>
const& rhs)
202 return !(lhs == rhs);
205 template <
typename String1>
206 inline bool operator!=(simple_attr<String1>
const& lhs, attribute_name local_name)
208 return !(lhs == local_name);
211 template <
typename String1>
212 inline bool operator!=(attribute_name local_name, simple_attr<String1>
const& rhs)
214 return !(local_name == rhs);
217 template <
typename String1>
218 inline bool operator!=(simple_attr<String1>
const& lhs, String1
const& local_name)
220 return !(lhs == local_name);
223 template <
typename String1>
224 inline bool operator!=(String1
const& local_name, simple_attr<String1>
const& rhs)
226 return !(local_name == rhs);
237 template <
typename String>
240 template <
typename String1>
243 template <
typename String1>
247 using string_type = String;
251 : m_document_type(document_type_name::Html)
252 , m_document_mode(document_mode_name::NoQuirks)
262 document_type_name document_type()
const {
return m_document_type; }
264 void document_type(document_type_name type)
266 m_document_type = type;
273 m_document_mode = mode;
277 document_type_name m_document_type;
284 template <
typename String1>
291 template <
typename String1>
292 inline bool operator!=(simple_document<String1>
const& lhs, simple_document<String1>
const& rhs)
294 return !(lhs == rhs);
305 template <
typename String>
308 template <
typename String1>
311 template <
typename String1>
315 using string_type = String;
318 simple_document_type(string_type
const& name, string_type
const& public_id, string_type
const& system_id)
320 , m_public_id(public_id)
321 , m_system_id(system_id)
325 string_type
const& name()
const {
return m_name; }
327 void name(string_type
const& s) { m_name = s; }
329 string_type
const& public_id()
const {
return m_public_id; }
331 void public_id(string_type
const& s) { m_public_id = s; }
333 string_type
const& system_id()
const {
return m_system_id; }
335 void system_id(string_type
const& s) { m_system_id = s; }
339 string_type m_public_id;
340 string_type m_system_id;
346 template <
typename String1>
353 template <
typename String1>
354 inline bool operator!=(simple_document_type<String1>
const& lhs, simple_document_type<String1>
const& rhs)
356 return !(lhs == rhs);
367 template <
typename String>
370 template <
typename String1>
373 template <
typename String1>
377 using string_type = String;
383 template <
typename String1>
390 template <
typename String1>
391 inline bool operator!=(simple_document_fragment<String1>
const& lhs, simple_document_fragment<String1>
const& rhs)
393 return !(lhs == rhs);
404 template <
typename String>
407 template <
typename String1>
410 template <
typename String1>
414 using string_type = String;
420 using container = std::vector<attribute_type>;
421 using iterator =
typename container::iterator;
422 using const_iterator =
typename container::const_iterator;
426 : m_namespace_uri(
static_cast<ns_name
>(0))
427 , m_namespace_prefix()
428 , m_local_name(
static_cast<tag_name
>(0))
433 simple_element(string_type
const& ns, string_type
const& prefix, string_type
const& name)
434 : m_namespace_uri(ns)
435 , m_namespace_prefix(prefix)
441 simple_element(ns_name ns, string_type
const& prefix, string_type
const& name)
442 : m_namespace_uri(ns)
443 , m_namespace_prefix(prefix)
449 simple_element(ns_name ns, string_type
const& prefix, tag_name name)
450 : m_namespace_uri(ns)
451 , m_namespace_prefix(prefix)
458 : m_namespace_uri(ns_name::HTML)
459 , m_namespace_prefix()
466 : m_namespace_uri(ns_name::HTML)
467 , m_namespace_prefix()
477 string_type
namespace_uri()
const {
return static_cast<string_type
>(m_namespace_uri); }
479 void namespace_uri(string_type
const& uri) { m_namespace_uri = uri; }
481 ns_name namespace_uri_name()
const {
return m_namespace_uri; }
483 void namespace_uri_name(ns_name ns) { m_namespace_uri = ns; }
485 string_type namespace_prefix()
const {
return m_namespace_prefix; }
487 void namespace_prefix(string_type
const& prefix) { m_namespace_prefix = prefix; }
489 string_type local_name()
const {
return static_cast<string_type
>(m_local_name); }
491 void local_name(string_type
const& name) { m_local_name = name; }
493 tag_name local_name_name()
const {
return m_local_name; }
495 void local_name_name(tag_name name) { m_local_name = name; }
497 string_type qualified_name()
const
499 string_type s = namespace_prefix();
500 if (!s.empty()) wordring::to_string(U
':', std::back_inserter(s));
501 s.append(local_name());
507 void push_back(attribute_type
const& attr) { m_attributes.push_back(std::move(attr)); }
509 iterator begin() {
return m_attributes.begin(); }
511 const_iterator begin()
const {
return m_attributes.begin(); }
513 iterator end() {
return m_attributes.end(); }
515 const_iterator end()
const {
return m_attributes.end(); }
521 return std::find(m_attributes.begin(), m_attributes.end(), attr);
526 const_iterator
find(ns_name ns, string_type
const& prefix, string_type
const& name)
const
528 return std::find_if(m_attributes.begin(), m_attributes.end(), [&](
attribute_type const& a)->bool {
529 return a == attribute_type(ns, prefix, name); });
534 const_iterator
find(ns_name ns, string_type
const& prefix, attribute_name name)
const
536 return std::find_if(m_attributes.begin(), m_attributes.end(), [&](
attribute_type const& a)->bool {
537 return a == attribute_type(ns, prefix, name); });
542 const_iterator
find(string_type
const& name)
const
544 return find(
static_cast<ns_name
>(0), string_type(), name);
549 const_iterator
find(attribute_name name)
const
551 return find(
static_cast<ns_name
>(0), string_type(), name);
555 namespace_uri_type m_namespace_uri;
556 string_type m_namespace_prefix;
557 local_name_type m_local_name;
559 container m_attributes;
562 static_assert(std::is_copy_constructible_v<simple_element<std::u32string>>);
563 static_assert(std::is_copy_assignable_v<simple_element<std::u32string>>);
565 template <
typename String1>
566 inline bool operator==(simple_element<String1>
const& lhs, simple_element<String1>
const& rhs)
568 using attribute_type =
typename simple_element<String1>::attribute_type;
570 if (lhs.m_attributes.size() != rhs.m_attributes.size())
return false;
572 for (attribute_type
const& a : lhs.m_attributes)
574 if (std::find(rhs.m_attributes.begin(), rhs.m_attributes.end(), a) == rhs.m_attributes.end())
return false;
580 template <
typename String1>
581 inline bool operator!=(simple_element<String1>
const& lhs, simple_element<String1>
const& rhs)
583 return !(lhs == rhs);
594 template <
typename String>
597 template <
typename String1>
600 template <
typename String1>
604 using string_type = String;
605 using value_type =
typename string_type::value_type;
615 string_type
const& data()
const {
return m_data; }
620 string_type& data() {
return m_data; }
622 void data(string_type
const& s) { m_data = s; }
632 static_assert(std::is_copy_constructible_v<simple_text<std::u32string>>);
633 static_assert(std::is_copy_assignable_v<simple_text<std::u32string>>);
635 template <
typename String1>
636 inline bool operator==(simple_text<String1>
const&, simple_text<String1>
const&)
642 template <
typename String1>
643 inline bool operator!=(simple_text<String1>
const& lhs, simple_text<String1>
const& rhs)
645 return !(lhs == rhs);
656 template <
typename String>
659 template <
typename String1>
662 template <
typename String1>
666 using string_type = String;
669 string_type
const& data()
const {
return m_data; }
671 string_type& data() {
return m_data; }
673 void data(string_type
const& s) { m_data = s; }
675 void data(string_type&& s) { m_data = std::move(s); }
677 string_type
const& target()
const {
return m_target; }
679 string_type& target() {
return m_target; }
681 void target(string_type
const& s) { m_target = s; }
683 void target(string_type&& s) { m_target = std::move(s); }
687 string_type m_target;
693 template <
typename String1>
700 template <
typename String1>
701 inline bool operator!=(simple_processing_instruction<String1>
const& lhs, simple_processing_instruction<String1>
const& rhs)
703 return !(lhs == rhs);
714 template <
typename String>
717 template <
typename String1>
720 template <
typename String1>
724 using string_type = String;
737 : m_data(std::move(s))
741 string_type
const& data()
const {
return m_data; }
743 string_type& data() {
return m_data; }
745 void data(string_type
const& s) { m_data = s; }
747 void data(string_type&& s) { m_data = std::move(s); }
756 template <
typename String1>
763 template <
typename String1>
764 inline bool operator!=(simple_comment<String1>
const& lhs, simple_comment<String1>
const& rhs)
766 return !(lhs == rhs);
774 template <
typename String>
777 template <
typename String1>
780 template <
typename String1>
784 using string_type = std::remove_cv_t<String>;
795 using attribute_iterator =
typename element_type::iterator;
796 using const_attribute_iterator =
typename element_type::const_iterator;
828 ProcessingInstruction = 7,
832 DocumentFragment = 11,
840 simple_node(element_type
const& val) : m_value(val) {}
841 simple_node(element_type && val) : m_value(std::move(val)) {}
843 simple_node(text_type
const& val) : m_value(val) {}
844 simple_node(text_type && val) : m_value(std::move(val)) {}
846 simple_node(processing_instruction_type
const& val) : m_value(val) {}
847 simple_node(processing_instruction_type && val) : m_value(std::move(val)) {}
849 simple_node(comment_type
const& val) : m_value(val) {}
850 simple_node(comment_type && val) : m_value(std::move(val)) {}
852 simple_node(document_type
const& val) : m_value(val) {}
853 simple_node(document_type && val) : m_value(std::move(val)) {}
855 simple_node(document_type_type
const& val) : m_value(val) {}
856 simple_node(document_type_type && val) : m_value(std::move(val)) {}
858 simple_node(document_fragment_type
const& val) : m_value(val) {}
859 simple_node(document_fragment_type && val) : m_value(std::move(val)) {}
861 simple_node& operator=(simple_node
const& rhs) =
default;
862 simple_node& operator=(simple_node&& rhs) =
default;
866 switch (m_value.index())
868 case 0:
return type_name::Element;
869 case 1:
return type_name::Text;
870 case 2:
return type_name::ProcessingInstruction;
871 case 3:
return type_name::Comment;
872 case 4:
return type_name::Document;
873 case 5:
return type_name::DocumentType;
874 case 6:
return type_name::DocumentFragment;
882 bool is_element()
const {
return std::holds_alternative<element_type>(m_value); }
883 bool is_text()
const {
return std::holds_alternative<text_type>(m_value); }
884 bool is_processing_instruction()
const {
return std::holds_alternative<processing_instruction_type>(m_value); }
885 bool is_comment()
const {
return std::holds_alternative<comment_type>(m_value); }
886 bool is_document()
const {
return std::holds_alternative<document_type>(m_value); }
887 bool is_document_type()
const {
return std::holds_alternative<document_type_type>(m_value); }
893 if (is_element())
return std::get_if<element_type>(&m_value)->namespace_uri_name();
895 return static_cast<ns_name
>(0);
902 if (is_element())
return std::get_if<element_type>(&m_value)->namespace_uri();
911 if (is_element())
return std::get_if<element_type>(&m_value)->local_name_name();
913 return static_cast<tag_name
>(0);
920 if (is_element())
return std::get_if<element_type>(&m_value)->local_name();
925 string_type qualified_name()
const
927 if (is_element())
return std::get_if<element_type>(&m_value)->qualified_name();
936 if (is_element())
return std::get_if<element_type>(&m_value)->begin();
938 return attribute_iterator();
943 const_attribute_iterator
begin()
const
945 if (is_element())
return std::get_if<element_type>(&m_value)->begin();
947 return attribute_iterator();
954 if (is_element())
return std::get_if<element_type>(&m_value)->end();
956 return attribute_iterator();
961 const_attribute_iterator
end()
const
963 if (is_element())
return std::get_if<element_type>(&m_value)->end();
965 return attribute_iterator();
980 const_attribute_iterator
find(ns_name ns, string_type
const& prefix, string_type
const& name)
const
996 const_attribute_iterator
find(string_type
const& name)
const
998 return find(
static_cast<ns_name
>(0), string_type(), name);
1011 const_attribute_iterator
find(attribute_name name)
const
1014 return a ==
attribute_type(
static_cast<ns_name
>(0), string_type(), name); });
1017 bool contains(ns_name ns, string_type
const& prefix, string_type
const& name)
1019 const_attribute_iterator it = std::find_if(
begin(),
end(), [&](attribute_type
const& a)->
bool {
1020 return a == attribute_type(ns, prefix, name); });
1029 if (is_element()) std::get_if<element_type>(&m_value)->push_back(std::move(attr));
1033 wordring::html::document_type_name document_type_name()
const
1035 if (is_document())
return std::get_if<document_type>(&m_value)->document_type();
1037 return static_cast<wordring::html::document_type_name
>(0);
1046 if (is_document()) std::get_if<document_type>(&m_value)->document_type(type);
1052 if (is_document())
return std::get_if<document_type>(&m_value)->document_mode();
1063 if (is_document()) std::get_if<document_type>(&m_value)->document_mode(mode);
1073 case type_name::Text:
1074 return std::get_if<text_type>(&m_value)->data();
1075 case type_name::Comment:
1076 return std::get_if<comment_type>(&m_value)->data();
1077 case type_name::ProcessingInstruction:
1078 return std::get_if<processing_instruction_type>(&m_value)->data();
1101 case type_name::Text:
1102 return std::get_if<text_type>(&m_value)->data();
1103 case type_name::Comment:
1104 return std::get_if<comment_type>(&m_value)->data();
1105 case type_name::ProcessingInstruction:
1106 return std::get_if<processing_instruction_type>(&m_value)->data();
1114 string_type
const& target()
const
1116 if (is_processing_instruction())
return std::get_if<processing_instruction_type>(&m_value)->target();
1121 string_type
const& name()
const
1123 if (is_document_type())
return std::get_if<document_type_type>(&m_value)->name();
1130 string_type m_string;
1133 static_assert(std::is_copy_constructible_v<simple_node<std::u32string>>);
1134 static_assert(std::is_copy_assignable_v<simple_node<std::u32string>>);
1136 template <
typename String1>
1137 inline bool operator==(simple_node<String1>
const lhs, simple_node<String1>
const& rhs)
1139 return lhs.m_value == rhs.m_value;
1142 template <
typename String1>
1143 inline bool operator!=(simple_node<String1>
const lhs, simple_node<String1>
const& rhs)
1145 return !(lhs == rhs);