Serenity Operating System
at master 75 lines 3.2 kB view raw
1/* 2 * Copyright (c) 2021-2022, Andreas Kling <kling@serenityos.org> 3 * Copyright (c) 2023, Luke Wilde <lukew@serenityos.org> 4 * 5 * SPDX-License-Identifier: BSD-2-Clause 6 */ 7 8#pragma once 9 10#include <AK/DeprecatedFlyString.h> 11#include <AK/Function.h> 12#include <LibJS/Heap/GCPtr.h> 13#include <LibWeb/Bindings/LegacyPlatformObject.h> 14#include <LibWeb/Forward.h> 15 16namespace Web::DOM { 17 18// NOTE: HTMLCollection is in the DOM namespace because it's part of the DOM specification. 19 20// This class implements a live, filtered view of a DOM subtree. 21// When constructing an HTMLCollection, you provide a root node + a filter. 22// The filter is a simple Function object that answers the question 23// "is this Element part of the collection?" 24 25// FIXME: HTMLCollection currently does no caching. It will re-filter on every access! 26// We should teach it how to cache results. The main challenge is invalidating 27// these caches, since this needs to happen on various kinds of DOM mutation. 28 29class HTMLCollection : public Bindings::LegacyPlatformObject { 30 WEB_PLATFORM_OBJECT(HTMLCollection, Bindings::LegacyPlatformObject); 31 32public: 33 static WebIDL::ExceptionOr<JS::NonnullGCPtr<HTMLCollection>> create(ParentNode& root, Function<bool(Element const&)> filter); 34 35 virtual ~HTMLCollection() override; 36 37 size_t length(); 38 Element* item(size_t index) const; 39 Element* named_item(DeprecatedFlyString const& name) const; 40 41 JS::MarkedVector<Element*> collect_matching_elements() const; 42 43 virtual WebIDL::ExceptionOr<JS::Value> item_value(size_t index) const override; 44 virtual WebIDL::ExceptionOr<JS::Value> named_item_value(DeprecatedFlyString const& name) const override; 45 virtual Vector<DeprecatedString> supported_property_names() const override; 46 virtual bool is_supported_property_index(u32) const override; 47 48protected: 49 HTMLCollection(ParentNode& root, Function<bool(Element const&)> filter); 50 51 virtual JS::ThrowCompletionOr<void> initialize(JS::Realm&) override; 52 53 JS::NonnullGCPtr<ParentNode> root() { return *m_root; } 54 55private: 56 virtual void visit_edges(Cell::Visitor&) override; 57 58 // ^Bindings::LegacyPlatformObject 59 virtual bool supports_indexed_properties() const override { return true; } 60 virtual bool supports_named_properties() const override { return true; } 61 virtual bool has_indexed_property_setter() const override { return false; } 62 virtual bool has_named_property_setter() const override { return false; } 63 virtual bool has_named_property_deleter() const override { return false; } 64 virtual bool has_legacy_override_built_ins_interface_extended_attribute() const override { return false; } 65 virtual bool has_legacy_unenumerable_named_properties_interface_extended_attribute() const override { return true; } 66 virtual bool has_global_interface_extended_attribute() const override { return false; } 67 virtual bool indexed_property_setter_has_identifier() const override { return false; } 68 virtual bool named_property_setter_has_identifier() const override { return false; } 69 virtual bool named_property_deleter_has_identifier() const override { return false; } 70 71 JS::NonnullGCPtr<ParentNode> m_root; 72 Function<bool(Element const&)> m_filter; 73}; 74 75}