mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-09-25 02:38:59 +00:00
LibWeb: Implement caching of reflected element array attributes
Some checks are pending
CI / Lagom (arm64, Sanitizer_CI, false, macos-15, macOS, Clang) (push) Waiting to run
CI / Lagom (x86_64, Fuzzers_CI, false, ubuntu-24.04, Linux, Clang) (push) Waiting to run
CI / Lagom (x86_64, Sanitizer_CI, false, ubuntu-24.04, Linux, GNU) (push) Waiting to run
CI / Lagom (x86_64, Sanitizer_CI, true, ubuntu-24.04, Linux, Clang) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (arm64, macos-15, macOS, macOS-universal2) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (x86_64, ubuntu-24.04, Linux, Linux-x86_64) (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Label PRs with merge conflicts / auto-labeler (push) Waiting to run
Push notes / build (push) Waiting to run
Some checks are pending
CI / Lagom (arm64, Sanitizer_CI, false, macos-15, macOS, Clang) (push) Waiting to run
CI / Lagom (x86_64, Fuzzers_CI, false, ubuntu-24.04, Linux, Clang) (push) Waiting to run
CI / Lagom (x86_64, Sanitizer_CI, false, ubuntu-24.04, Linux, GNU) (push) Waiting to run
CI / Lagom (x86_64, Sanitizer_CI, true, ubuntu-24.04, Linux, Clang) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (arm64, macos-15, macOS, macOS-universal2) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (x86_64, ubuntu-24.04, Linux, Linux-x86_64) (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Label PRs with merge conflicts / auto-labeler (push) Waiting to run
Push notes / build (push) Waiting to run
For attributes like Element.ariaControlsElements, which are a reflection of FrozenArray<Element>, we must return the same JS::Array object every time the attribute is invoked - until its contents have changed. This patch implements caching of the reflected array in accordance with the spec.
This commit is contained in:
parent
6f894ccd77
commit
ac1c2a956a
Notes:
github-actions[bot]
2025-04-26 21:30:33 +00:00
Author: https://github.com/trflynn89
Commit: ac1c2a956a
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/4477
7 changed files with 93 additions and 14 deletions
|
@ -1874,7 +1874,7 @@ static void generate_wrap_statement(SourceGenerator& generator, ByteString const
|
|||
// This might need to change if we switch to a RootVector.
|
||||
if (is_platform_object(sequence_generic_type.parameters().first())) {
|
||||
scoped_generator.append(R"~~~(
|
||||
auto* wrapped_element@recursion_depth@ = &(*element@recursion_depth@);
|
||||
auto* wrapped_element@recursion_depth@ = &(*element@recursion_depth@);
|
||||
)~~~");
|
||||
} else {
|
||||
scoped_generator.append("JS::Value wrapped_element@recursion_depth@;\n"sv);
|
||||
|
@ -3748,6 +3748,9 @@ static void generate_prototype_or_global_mixin_definitions(IDL::Interface const&
|
|||
for (auto& attribute : interface.attributes) {
|
||||
if (attribute.extended_attributes.contains("FIXME"))
|
||||
continue;
|
||||
|
||||
bool generated_reflected_element_array = false;
|
||||
|
||||
auto attribute_generator = generator.fork();
|
||||
attribute_generator.set("attribute.name", attribute.name);
|
||||
attribute_generator.set("attribute.getter_callback", attribute.getter_callback_name);
|
||||
|
@ -4054,18 +4057,14 @@ JS_DEFINE_NATIVE_FUNCTION(@class_name@::@attribute.getter_callback@)
|
|||
// inherits from Element, then with attr being the reflected content attribute name:
|
||||
// FIXME: Handle "an interface that inherits from Element".
|
||||
else if (is_nullable_frozen_array_of_single_type(attribute.type, "Element"sv)) {
|
||||
generated_reflected_element_array = true;
|
||||
|
||||
// 1. Let elements be the result of running this's get the attr-associated elements.
|
||||
attribute_generator.append(R"~~~(
|
||||
static auto content_attribute = "@attribute.reflect_name@"_fly_string;
|
||||
|
||||
auto retval = impl->get_the_attribute_associated_elements(content_attribute, TRY(throw_dom_exception_if_needed(vm, [&] { return impl->@attribute.cpp_name@(); })));
|
||||
)~~~");
|
||||
|
||||
// FIXME: 2. If the contents of elements is equal to the contents of this's cached attr-associated elements, then return
|
||||
// this's cached attr-associated elements object.
|
||||
// FIXME: 3. Let elementsAsFrozenArray be elements, converted to a FrozenArray<T>?.
|
||||
// FIXME: 4. Set this's cached attr-associated elements to elements.
|
||||
// FIXME: 5. Set this's cached attr-associated elements object to elementsAsFrozenArray.
|
||||
} else {
|
||||
attribute_generator.append(R"~~~(
|
||||
auto retval = impl->get_attribute_value("@attribute.reflect_name@"_fly_string);
|
||||
|
@ -4083,6 +4082,19 @@ JS_DEFINE_NATIVE_FUNCTION(@class_name@::@attribute.getter_callback@)
|
|||
Bindings::invoke_custom_element_reactions(queue);
|
||||
)~~~");
|
||||
}
|
||||
|
||||
if (generated_reflected_element_array) {
|
||||
// 2. If the contents of elements is equal to the contents of this's cached attr-associated elements,
|
||||
// then return this's cached attr-associated elements object.
|
||||
attribute_generator.append(R"~~~(
|
||||
auto cached_@attribute.cpp_name@ = TRY(throw_dom_exception_if_needed(vm, [&] { return impl->cached_@attribute.cpp_name@(); }));
|
||||
if (WebIDL::lists_contain_same_elements(cached_@attribute.cpp_name@, retval))
|
||||
return cached_@attribute.cpp_name@;
|
||||
|
||||
auto result = TRY([&]() -> JS::ThrowCompletionOr<JS::Value> {
|
||||
)~~~");
|
||||
}
|
||||
|
||||
} else {
|
||||
if (!attribute.extended_attributes.contains("CEReactions")) {
|
||||
attribute_generator.append(R"~~~(
|
||||
|
@ -4127,6 +4139,24 @@ JS_DEFINE_NATIVE_FUNCTION(@class_name@::@attribute.getter_callback@)
|
|||
|
||||
generate_return_statement(generator, *attribute.type, interface);
|
||||
|
||||
if (generated_reflected_element_array) {
|
||||
// 3. Let elementsAsFrozenArray be elements, converted to a FrozenArray<T>?.
|
||||
// 4. Set this's cached attr-associated elements to elements.
|
||||
// 5. Set this's cached attr-associated elements object to elementsAsFrozenArray.
|
||||
attribute_generator.append(R"~~~(
|
||||
}());
|
||||
|
||||
if (result.is_null()) {
|
||||
TRY(throw_dom_exception_if_needed(vm, [&] { impl->set_cached_@attribute.cpp_name@({}); }));
|
||||
} else {
|
||||
auto& array = as<JS::Array>(result.as_object());
|
||||
TRY(throw_dom_exception_if_needed(vm, [&] { impl->set_cached_@attribute.cpp_name@(&array); }));
|
||||
}
|
||||
|
||||
return result;
|
||||
)~~~");
|
||||
}
|
||||
|
||||
attribute_generator.append(R"~~~(
|
||||
}
|
||||
)~~~");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue