10 #include <wordring/wwwc/selectors/pseudo_class_defs.hpp>
11 #include <wordring/wwwc/css_defs.hpp>
12 #include <wordring/wwwc/selectors/tree_structural_pseudo_classes.hpp>
14 #include <wordring/wwwc/css_syntax/parsing.hpp>
16 #include <wordring/encoding/encoding.hpp>
17 #include <wordring/html/html_defs.hpp>
19 #include <wordring/whatwg/infra/infra.hpp>
25 #include <string_view>
50 using const_iterator = syntax_primitive_stream::const_iterator;
52 using document_type_name = wordring::html::document_type_name;
65 operator bool()
const;
67 bool operator !()
const;
69 const_iterator begin()
const;
71 const_iterator end()
const;
97 using const_iterator = syntax_primitive_stream::const_iterator;
105 combinator(const_iterator first, const_iterator last, char32_t c);
107 char32_t type()
const;
126 using const_iterator = syntax_primitive_stream::const_iterator;
140 ns_prefix(const_iterator first, const_iterator last, std::u32string
const& prefix);
151 std::u32string
const&
string()
const;
154 std::u32string m_ns_prefix;
173 using const_iterator = syntax_primitive_stream::const_iterator;
180 wq_name(const_iterator first, const_iterator last, std::optional<ns_prefix> ns, std::u32string
const&
name);
184 std::optional<ns_prefix>
const&
prefix()
const;
188 std::u32string
const&
name()
const;
191 std::optional<ns_prefix> m_ns_prefix;
192 std::u32string m_name;
213 using const_iterator = syntax_primitive_stream::const_iterator;
215 using document_type_name = wordring::html::document_type_name;
230 id_selector(const_iterator first, const_iterator last, std::u32string
const&
value);
234 std::u32string
const&
value()
const;
253 template <
typename NodePo
inter>
258 assert(!(ctx.
m_type_name == document_type_name::Xml
259 && (ctx.
m_mode_name == document_mode_name::LimitedQuirks || ctx.
m_mode_name == document_mode_name::Quirks)));
261 if (traits::is_element(np))
263 auto it1 = traits::abegin(np);
264 auto it2 = traits::aend(np);
267 std::u32string name = wordring::encoding_cast<std::u32string>(traits::get_qualified_name(*it1));
272 name = std::move(tmp);
277 std::u32string val = wordring::encoding_cast<std::u32string>(traits::value(*it1));
282 val = std::move(tmp);
284 if (val == m_value)
return true;
293 std::u32string m_value;
314 using const_iterator = syntax_primitive_stream::const_iterator;
316 using document_type_name = wordring::html::document_type_name;
324 class_selector(const_iterator first, const_iterator last, std::u32string
const&
name);
328 std::u32string
const&
name()
const;
350 template <
typename NodePo
inter>
355 assert(!(ctx.
m_type_name == document_type_name::Xml
356 && (ctx.
m_mode_name == document_mode_name::LimitedQuirks || ctx.
m_mode_name == document_mode_name::Quirks)));
358 if (traits::is_element(np))
360 auto it1 = traits::abegin(np);
361 auto it2 = traits::aend(np);
364 std::u32string
name = wordring::encoding_cast<std::u32string>(traits::get_qualified_name(*it1));
369 name = std::move(tmp);
371 if (
name != U
"class")
377 std::u32string val = wordring::encoding_cast<std::u32string>(traits::value(*it1));
382 val = std::move(tmp);
385 std::vector<std::u32string> v;
386 wordring::whatwg::split_on_ascii_whitespace(val.begin(), val.end(), std::back_inserter(v));
387 for (std::u32string
const& s : v)
389 bool matched = (ctx.
m_mode_name == document_mode_name::Quirks)
393 if (matched)
return true;
402 std::u32string m_name;
419 using const_iterator = syntax_primitive_stream::const_iterator;
426 attr_matcher(const_iterator first, const_iterator last, char32_t c);
428 char32_t prefix()
const;
431 char32_t m_prefix = U
'\0';
454 using const_iterator = syntax_primitive_stream::const_iterator;
461 attr_modifier(const_iterator first, const_iterator last, char32_t c);
463 char32_t value()
const;
483 using value_type = std::variant<std::monostate, ident_token, function>;
484 using const_iterator = syntax_primitive_stream::const_iterator;
504 pseudo_class_selector(const_iterator first, const_iterator last,
function const& fn, pseudo_class_fn_name name);
508 template <
typename T>
509 T
const& get()
const {
return std::get<T>(
m_value); }
521 template <
typename NodePo
inter>
524 assert(!(ctx.
m_type_name == document_type_name::Xml
525 && (ctx.
m_mode_name == document_mode_name::LimitedQuirks || ctx.
m_mode_name == document_mode_name::Quirks)));
530 case pseudo_class_id_name::Root:
531 return root_pseudo_class::match(np, ctx);
566 using value_type = pseudo_class_selector::value_type;
567 using const_iterator = syntax_primitive_stream::const_iterator;
599 template <
typename NodePo
inter>
602 assert(!(ctx.
m_type_name == document_type_name::Xml
603 && (ctx.
m_mode_name == document_mode_name::LimitedQuirks || ctx.
m_mode_name == document_mode_name::Quirks)));
627 using const_iterator = syntax_primitive_stream::const_iterator;
634 attribute_selector(const_iterator first, const_iterator last,
wq_name name, char32_t matcher, std::u32string
const& value, char32_t modifier);
636 std::optional<ns_prefix>
const& prefix()
const;
637 std::u32string
const& name()
const;
638 char32_t matcher()
const;
639 std::u32string
const& value()
const;
640 char32_t modifier()
const;
691 template <
typename NodePo
inter>
696 using wordring::whatwg::split_on_ascii_whitespace;
697 using wordring::encoding_cast;
700 assert(!(ctx.
m_type_name == document_type_name::Xml
701 && (ctx.
m_mode_name == document_mode_name::LimitedQuirks || ctx.
m_mode_name == document_mode_name::Quirks)));
704 if (!traits::is_element(np))
return false;
707 auto it1 = traits::abegin(np);
708 auto it2 = traits::aend(np);
714 std::u32string
const& prefix1 = m_name.
prefix()->string();
715 std::u32string uri2 = encoding_cast<std::u32string>(traits::get_namespace(*it1));
717 if (prefix1 == U
"*");
718 else if (prefix1 == U
"")
738 if (!traits::get_namespace(*it1).empty())
746 std::u32string
const& n1 = m_name.
name();
747 std::u32string n2 = encoding_cast<std::u32string>(traits::get_local_name(*it1));
755 if (is_ascii_case_insensitive_match(n1.begin(), n1.end(), n2.begin(), n2.end()))
break;
760 if (it1 == it2)
return false;
766 assert(m_value.empty());
770 std::u32string s = encoding_cast<std::u32string>(traits::value(*it1));
771 if (m_modifier == U
'i')
return is_ascii_case_insensitive_match(m_value.begin(), m_value.end(), s.begin(), s.end());
772 else return m_value == s;
776 std::u32string tmp = encoding_cast<std::u32string>(traits::value(*it1));
777 std::vector<std::u32string> v;
778 split_on_ascii_whitespace(tmp.begin(), tmp.end(), std::back_inserter(v));
779 for (std::u32string
const& s : v)
781 if (m_modifier == U
'i' && is_ascii_case_insensitive_match(m_value.begin(), m_value.end(), s.begin(), s.end()))
return true;
782 else if(m_value == s)
return true;
788 std::u32string s = encoding_cast<std::u32string>(traits::value(*it1));
789 if (m_modifier == U
'i')
791 if (m_value.size() < s.size()
792 && is_ascii_case_insensitive_match(m_value.begin(), m_value.end(), s.begin(), s.begin() + m_value.size())
793 && s[m_value.size()] == U
'-')
return true;
797 if (m_value.size() < s.size()
798 && std::equal(m_value.begin(), m_value.end(), s.begin(), s.begin() + m_value.size())
799 && s[m_value.size()] == U
'-')
return true;
805 std::u32string s = encoding_cast<std::u32string>(traits::value(*it1));
806 if (m_modifier == U
'i')
808 if (m_value.size() <= s.size()
809 && is_ascii_case_insensitive_match(m_value.begin(), m_value.end(), s.begin(), s.begin() + m_value.size()))
return true;
813 if (m_value.size() <= s.size()
814 && std::equal(m_value.begin(), m_value.end(), s.begin(), s.begin() + m_value.size()))
return true;
820 std::u32string s = encoding_cast<std::u32string>(traits::value(*it1));
821 if (s.size() < m_value.size())
return false;
822 if (m_modifier == U
'i')
824 if (is_ascii_case_insensitive_match(m_value.rbegin(), m_value.rend(), s.rbegin(), s.rbegin() + m_value.size()))
return true;
828 if (std::equal(m_value.rbegin(), m_value.rend(), s.rbegin(), s.rbegin() + m_value.size()))
return true;
834 std::u32string s1 = encoding_cast<std::u32string>(traits::value(*it1));
835 std::u32string s2 = m_value;
836 if (m_modifier == U
'i')
839 to_ascii_lowercase(s1.begin(), s1.end(), std::back_inserter(tmp));
842 to_ascii_lowercase(s2.begin(), s2.end(), std::back_inserter(tmp));
845 if (s1.find(s2) != std::u32string::npos)
return true;
858 std::u32string m_value;
884 using const_iterator = syntax_primitive_stream::const_iterator;
886 using value_type = std::variant<id_selector, class_selector, attribute_selector, pseudo_class_selector>;
894 value_type
const& value()
const;
900 template <
typename NodePo
inter>
903 assert(!(ctx.
m_type_name == document_type_name::Xml
904 && (ctx.
m_mode_name == document_mode_name::LimitedQuirks || ctx.
m_mode_name == document_mode_name::Quirks)));
906 return std::visit([&](
auto const& x) {
return x.match(np, ctx); }, m_value);
929 using const_iterator = syntax_primitive_stream::const_iterator;
931 using value_type = std::variant<wq_name, std::optional<ns_prefix>>;
938 type_selector(const_iterator first, const_iterator last, value_type value);
940 value_type
const& value()
const;
950 template <
typename NodePo
inter>
955 using wordring::encoding_cast;
957 assert(!(ctx.
m_type_name == document_type_name::Xml
958 && (ctx.
m_mode_name == document_mode_name::LimitedQuirks || ctx.
m_mode_name == document_mode_name::Quirks)));
961 if (!traits::is_element(np))
return false;
964 std::optional<ns_prefix>
const& opt = (m_value.index() == 0)
965 ? std::get_if<wq_name>(&m_value)->prefix()
966 : **std::get_if<std::optional<ns_prefix>>(&m_value);
968 std::u32string uri2 = encoding_cast<std::u32string>(traits::get_namespace(np));
972 std::u32string
const& prefix1 = opt->string();
973 if (prefix1 == U
"*");
974 else if (prefix1 == U
"")
976 if (!uri2.empty())
return false;
990 if (it->second != uri2)
return false;
995 if (m_value.index() == 1)
return true;
997 std::u32string
const& name1 = std::get_if<wq_name>(&m_value)->name();
998 std::u32string name2 = encoding_cast<std::u32string>(traits::get_local_name(np));
1002 if (is_ascii_case_insensitive_match(name1.begin(), name1.end(), name2.begin(), name2.end()))
return true;
1006 if (name1 == name2)
return true;
1032 using const_iterator = syntax_primitive_stream::const_iterator;
1034 using value_type = std::variant<std::monostate, type_selector, subclass_selector>;
1041 simple_selector(const_iterator first, const_iterator last, value_type value);
1043 value_type
const& value()
const;
1049 template <
typename NodePo
inter>
1052 assert(!(ctx.
m_type_name == document_type_name::Xml
1053 && (ctx.
m_mode_name == document_mode_name::LimitedQuirks || ctx.
m_mode_name == document_mode_name::Quirks)));
1055 if (m_value.index() == 1)
return std::get_if<type_selector>(&m_value)->match(np, ctx);
1056 else if (m_value.index() == 2)
return std::get_if<subclass_selector>(&m_value)->match(np, ctx);
1083 using const_iterator = syntax_primitive_stream::const_iterator;
1085 using value_type = std::variant<type_selector, subclass_selector, pseudo_element_selector, pseudo_class_selector>;
1092 compound_selector(const_iterator first, const_iterator last, std::vector<value_type>&& value);
1094 std::vector<value_type>
const& value()
const;
1100 template <
typename NodePo
inter>
1103 assert(!(ctx.
m_type_name == document_type_name::Xml
1104 && (ctx.
m_mode_name == document_mode_name::LimitedQuirks || ctx.
m_mode_name == document_mode_name::Quirks)));
1106 for (value_type
const& val : m_value)
1108 if (!std::visit([&](
auto const& x) {
return x.match(np, ctx); }, val))
return false;
1115 std::vector<value_type> m_value;
1134 using const_iterator = syntax_primitive_stream::const_iterator;
1136 using value_type = std::variant<compound_selector, combinator>;
1137 using reverse_iterator = std::vector<value_type>::const_reverse_iterator;
1154 template <
typename NodePo
inter>
1159 if (!std::get_if<compound_selector>(&*it)->match(np, ctx))
return false;
1161 if (it == m_value.rend())
return true;
1164 if (it->index() == 1)
1166 c = std::get_if<combinator>(&*it)->type();
1173 for (
auto p = traits::parent(np); p != traits::pointer(); p = traits::parent(p))
1175 if (match(it, p, ctx))
return true;
1180 auto p = traits::parent(np);
1181 if (p != traits::pointer() && match(it, p, ctx))
return true;
1186 auto parent = traits::parent(np);
1187 if (parent == traits::pointer())
return false;
1188 auto first = traits::begin(parent);
1189 for(
auto p = np; p != first;)
1191 p = traits::prev(p);
1192 if (traits::is_element(p))
return match(it, p, ctx);
1198 auto parent = traits::parent(np);
1199 if (parent == traits::pointer())
return false;
1200 auto first = traits::begin(parent);
1201 for (
auto p = np; p != first;)
1203 p = traits::prev(p);
1204 if (traits::is_element(p) && match(it, p, ctx))
return true;
1217 complex_selector(const_iterator first, const_iterator last, std::vector<value_type>&& value);
1219 std::vector<value_type>
const& value()
const;
1225 template <
typename NodePo
inter>
1228 assert(!(ctx.
m_type_name == document_type_name::Xml
1229 && (ctx.
m_mode_name == document_mode_name::LimitedQuirks || ctx.
m_mode_name == document_mode_name::Quirks)));
1231 return match(m_value.rbegin(), np, ctx);
1235 std::vector<value_type> m_value;
1258 using const_iterator = syntax_primitive_stream::const_iterator;
1260 using value_type = std::variant<compound_selector, combinator>;
1267 relative_selector(const_iterator first, const_iterator last, std::vector<value_type>&& value);
1269 std::vector<value_type>
const& value()
const;
1277 template <
typename NodePo
inter>
1281 using ns_name = wordring::html::ns_name;
1283 using wordring::encoding_cast;
1285 assert(!(ctx.
m_type_name == document_type_name::Xml
1286 && (ctx.
m_mode_name == document_mode_name::LimitedQuirks || ctx.
m_mode_name == document_mode_name::Quirks)));
1297 template <
typename NodePo
inter>
1310 std::vector<value_type> m_value;
1327 using const_iterator = syntax_primitive_stream::const_iterator;
1334 relative_selector_list(const_iterator first, const_iterator last, std::vector<relative_selector>&& value);
1336 std::vector<relative_selector>
const& value()
const;
1344 template <
typename NodePo
inter>
1347 assert(!(ctx.
m_type_name == document_type_name::Xml
1348 && (ctx.
m_mode_name == document_mode_name::LimitedQuirks || ctx.
m_mode_name == document_mode_name::Quirks)));
1360 template <
typename NodePo
inter>
1367 std::vector<relative_selector> m_value;
1384 using const_iterator = syntax_primitive_stream::const_iterator;
1391 simple_selector_list(const_iterator first, const_iterator last, std::vector<simple_selector>&& value);
1393 std::vector<simple_selector>
const& value()
const;
1399 template <
typename NodePo
inter>
1402 assert(!(ctx.
m_type_name == document_type_name::Xml
1403 && (ctx.
m_mode_name == document_mode_name::LimitedQuirks || ctx.
m_mode_name == document_mode_name::Quirks)));
1407 if (ss.match(np, ctx))
return true;
1414 std::vector<simple_selector> m_value;
1431 using const_iterator = syntax_primitive_stream::const_iterator;
1438 compound_selector_list(const_iterator first, const_iterator last, std::vector<compound_selector>&& value);
1440 std::vector<compound_selector>
const& value()
const;
1446 template <
typename NodePo
inter>
1449 assert(!(ctx.
m_type_name == document_type_name::Xml
1450 && (ctx.
m_mode_name == document_mode_name::LimitedQuirks || ctx.
m_mode_name == document_mode_name::Quirks)));
1454 if (cs.match(np, ctx))
return true;
1461 std::vector<compound_selector> m_value;
1478 using const_iterator = syntax_primitive_stream::const_iterator;
1485 complex_selector_list(const_iterator first, const_iterator last, std::vector<complex_selector>&& value);
1487 std::vector<complex_selector>
const& value()
const;
1493 template <
typename NodePo
inter>
1496 assert(!(ctx.
m_type_name == document_type_name::Xml
1497 && (ctx.
m_mode_name == document_mode_name::LimitedQuirks || ctx.
m_mode_name == document_mode_name::Quirks)));
1501 if (cs.match(np, ctx))
return true;
1508 std::vector<complex_selector> m_value;
1526 using const_iterator = syntax_primitive_stream::const_iterator;
1541 template <
typename NodePo
inter>
1544 assert(!(ctx.
m_type_name == document_type_name::Xml
1545 && (ctx.
m_mode_name == document_mode_name::LimitedQuirks || ctx.
m_mode_name == document_mode_name::Quirks)));
1547 return m_value.
match(np, ctx);