QualifiedName.cpp 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. /*
  2. * Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <AK/HashTable.h>
  7. #include <LibWeb/DOM/QualifiedName.h>
  8. namespace Web::DOM {
  9. struct ImplTraits : public Traits<QualifiedName::Impl*> {
  10. static unsigned hash(QualifiedName::Impl* impl)
  11. {
  12. return pair_int_hash(impl->local_name.hash(), pair_int_hash(impl->prefix.hash(), impl->namespace_.hash()));
  13. }
  14. static bool equals(QualifiedName::Impl* a, QualifiedName::Impl* b)
  15. {
  16. return a->local_name == b->local_name
  17. && a->prefix == b->prefix
  18. && a->namespace_ == b->namespace_;
  19. }
  20. };
  21. static HashTable<QualifiedName::Impl*, ImplTraits> impls;
  22. static NonnullRefPtr<QualifiedName::Impl> ensure_impl(FlyString const& local_name, FlyString const& prefix, FlyString const& namespace_)
  23. {
  24. auto hash = pair_int_hash(local_name.hash(), pair_int_hash(prefix.hash(), namespace_.hash()));
  25. auto it = impls.find(hash, [&](QualifiedName::Impl* entry) {
  26. return entry->local_name == local_name
  27. && entry->prefix == prefix
  28. && entry->namespace_ == namespace_;
  29. });
  30. if (it != impls.end())
  31. return *(*it);
  32. return adopt_ref(*new QualifiedName::Impl(local_name, prefix, namespace_));
  33. }
  34. QualifiedName::QualifiedName(FlyString const& local_name, FlyString const& prefix, FlyString const& namespace_)
  35. : m_impl(ensure_impl(local_name, prefix, namespace_))
  36. {
  37. }
  38. QualifiedName::Impl::Impl(FlyString const& a_local_name, FlyString const& a_prefix, FlyString const& a_namespace)
  39. : local_name(a_local_name)
  40. , prefix(a_prefix)
  41. , namespace_(a_namespace)
  42. {
  43. impls.set(this);
  44. make_internal_string();
  45. }
  46. QualifiedName::Impl::~Impl()
  47. {
  48. impls.remove(this);
  49. }
  50. // https://dom.spec.whatwg.org/#concept-attribute-qualified-name
  51. // https://dom.spec.whatwg.org/#concept-element-qualified-name
  52. void QualifiedName::Impl::make_internal_string()
  53. {
  54. // This is possible to do according to the spec: "User agents could have this as an internal slot as an optimization."
  55. if (prefix.is_null()) {
  56. as_string = local_name;
  57. return;
  58. }
  59. as_string = String::formatted("{}:{}", prefix, local_name);
  60. }
  61. }