ObservableArray.cpp 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  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. GC_DEFINE_ALLOCATOR(ObservableArray);
  10. GC::Ref<ObservableArray> ObservableArray::create(JS::Realm& realm)
  11. {
  12. auto prototype = realm.intrinsics().array_prototype();
  13. return realm.create<ObservableArray>(prototype);
  14. }
  15. ObservableArray::ObservableArray(Object& prototype)
  16. : JS::Array(prototype)
  17. {
  18. }
  19. void ObservableArray::visit_edges(JS::Cell::Visitor& visitor)
  20. {
  21. Base::visit_edges(visitor);
  22. visitor.visit(m_on_set_an_indexed_value);
  23. visitor.visit(m_on_delete_an_indexed_value);
  24. }
  25. void ObservableArray::set_on_set_an_indexed_value_callback(SetAnIndexedValueCallbackFunction&& callback)
  26. {
  27. m_on_set_an_indexed_value = GC::create_function(heap(), move(callback));
  28. }
  29. void ObservableArray::set_on_delete_an_indexed_value_callback(DeleteAnIndexedValueCallbackFunction&& callback)
  30. {
  31. m_on_delete_an_indexed_value = GC::create_function(heap(), move(callback));
  32. }
  33. JS::ThrowCompletionOr<bool> ObservableArray::internal_set(JS::PropertyKey const& property_key, JS::Value value, JS::Value receiver, JS::CacheablePropertyMetadata* metadata)
  34. {
  35. if (property_key.is_number() && m_on_set_an_indexed_value)
  36. TRY(Bindings::throw_dom_exception_if_needed(vm(), [&] { return m_on_set_an_indexed_value->function()(value); }));
  37. return TRY(Base::internal_set(property_key, value, receiver, metadata));
  38. }
  39. JS::ThrowCompletionOr<bool> ObservableArray::internal_delete(JS::PropertyKey const& property_key)
  40. {
  41. if (property_key.is_number() && m_on_delete_an_indexed_value)
  42. TRY(Bindings::throw_dom_exception_if_needed(vm(), [&] { return m_on_delete_an_indexed_value->function()(); }));
  43. return JS::Array::internal_delete(property_key);
  44. }
  45. JS::ThrowCompletionOr<void> ObservableArray::append(JS::Value value)
  46. {
  47. if (m_on_set_an_indexed_value)
  48. TRY(Bindings::throw_dom_exception_if_needed(vm(), [&] { return m_on_set_an_indexed_value->function()(value); }));
  49. indexed_properties().append(value);
  50. return {};
  51. }
  52. void ObservableArray::clear()
  53. {
  54. while (!indexed_properties().is_empty()) {
  55. indexed_properties().storage()->take_first();
  56. }
  57. }
  58. }