ObservableArray.cpp 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. /*
  2. * Copyright (c) 2024, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <LibWeb/Bindings/ExceptionOrUtils.h>
  7. #include <LibWeb/WebIDL/ObservableArray.h>
  8. namespace Web::WebIDL {
  9. JS::NonnullGCPtr<ObservableArray> ObservableArray::create(JS::Realm& realm)
  10. {
  11. auto prototype = realm.intrinsics().array_prototype();
  12. return realm.heap().allocate<ObservableArray>(realm, prototype);
  13. }
  14. ObservableArray::ObservableArray(Object& prototype)
  15. : JS::Array(prototype)
  16. {
  17. }
  18. void ObservableArray::visit_edges(JS::Cell::Visitor& visitor)
  19. {
  20. Base::visit_edges(visitor);
  21. visitor.visit(m_on_set_an_indexed_value);
  22. visitor.visit(m_on_delete_an_indexed_value);
  23. }
  24. void ObservableArray::set_on_set_an_indexed_value_callback(SetAnIndexedValueCallbackFunction&& callback)
  25. {
  26. m_on_set_an_indexed_value = create_heap_function(heap(), move(callback));
  27. }
  28. void ObservableArray::set_on_delete_an_indexed_value_callback(DeleteAnIndexedValueCallbackFunction&& callback)
  29. {
  30. m_on_delete_an_indexed_value = create_heap_function(heap(), move(callback));
  31. }
  32. JS::ThrowCompletionOr<bool> ObservableArray::internal_set(JS::PropertyKey const& property_key, JS::Value value, JS::Value receiver, JS::CacheablePropertyMetadata* metadata)
  33. {
  34. if (property_key.is_number() && m_on_set_an_indexed_value)
  35. TRY(Bindings::throw_dom_exception_if_needed(vm(), [&] { return m_on_set_an_indexed_value->function()(value); }));
  36. return TRY(Base::internal_set(property_key, value, receiver, metadata));
  37. }
  38. JS::ThrowCompletionOr<bool> ObservableArray::internal_delete(JS::PropertyKey const& property_key)
  39. {
  40. if (property_key.is_number() && m_on_delete_an_indexed_value)
  41. TRY(Bindings::throw_dom_exception_if_needed(vm(), [&] { return m_on_delete_an_indexed_value->function()(); }));
  42. return JS::Array::internal_delete(property_key);
  43. }
  44. JS::ThrowCompletionOr<void> ObservableArray::append(JS::Value value)
  45. {
  46. if (m_on_set_an_indexed_value)
  47. TRY(Bindings::throw_dom_exception_if_needed(vm(), [&] { return m_on_set_an_indexed_value->function()(value); }));
  48. indexed_properties().append(value);
  49. return {};
  50. }
  51. void ObservableArray::clear()
  52. {
  53. while (!indexed_properties().is_empty()) {
  54. indexed_properties().storage()->take_first();
  55. }
  56. }
  57. }