LibWeb/Bindings: Define constructor properties in the correct order

This commit is contained in:
Shannon Booth 2025-01-11 13:40:44 +13:00 committed by Tim Ledbetter
parent 3261f873c5
commit 627b7dd936
Notes: github-actions[bot] 2025-01-11 01:44:32 +00:00
8 changed files with 56 additions and 9 deletions

View file

@ -26,8 +26,9 @@ void AudioConstructor::initialize(JS::Realm& realm)
auto& vm = this->vm();
Base::initialize(realm);
define_direct_property(vm.names.prototype, &ensure_web_prototype<Bindings::HTMLAudioElementPrototype>(realm, "HTMLAudioElement"_fly_string), 0);
define_direct_property(vm.names.length, JS::Value(0), JS::Attribute::Configurable);
define_direct_property(vm.names.name, JS::PrimitiveString::create(vm, "Audio"_string), JS::Attribute::Configurable);
define_direct_property(vm.names.prototype, &ensure_web_prototype<Bindings::HTMLAudioElementPrototype>(realm, "HTMLAudioElement"_fly_string), 0);
}
JS::ThrowCompletionOr<JS::Value> AudioConstructor::call()

View file

@ -26,8 +26,9 @@ void ImageConstructor::initialize(JS::Realm& realm)
auto& vm = this->vm();
Base::initialize(realm);
define_direct_property(vm.names.prototype, &ensure_web_prototype<Bindings::HTMLImageElementPrototype>(realm, "HTMLImageElement"_fly_string), 0);
define_direct_property(vm.names.length, JS::Value(0), JS::Attribute::Configurable);
define_direct_property(vm.names.name, JS::PrimitiveString::create(vm, "Image"_string), JS::Attribute::Configurable);
define_direct_property(vm.names.prototype, &ensure_web_prototype<Bindings::HTMLImageElementPrototype>(realm, "HTMLImageElement"_fly_string), 0);
}
JS::ThrowCompletionOr<JS::Value> ImageConstructor::call()

View file

@ -29,8 +29,9 @@ void OptionConstructor::initialize(JS::Realm& realm)
auto& vm = this->vm();
Base::initialize(realm);
define_direct_property(vm.names.prototype, &ensure_web_prototype<Bindings::HTMLOptionElementPrototype>(realm, "HTMLOptionElement"_fly_string), 0);
define_direct_property(vm.names.length, JS::Value(0), JS::Attribute::Configurable);
define_direct_property(vm.names.name, JS::PrimitiveString::create(vm, "Option"_string), JS::Attribute::Configurable);
define_direct_property(vm.names.prototype, &ensure_web_prototype<Bindings::HTMLOptionElementPrototype>(realm, "HTMLOptionElement"_fly_string), 0);
}
JS::ThrowCompletionOr<JS::Value> OptionConstructor::call()

View file

@ -4,7 +4,7 @@
* Copyright (c) 2021-2023, Luke Wilde <lukew@serenityos.org>
* Copyright (c) 2022, Ali Mohammad Pur <mpfard@serenityos.org>
* Copyright (c) 2023-2024, Kenneth Myhra <kennethmyhra@serenityos.org>
* Copyright (c) 2023-2024, Shannon Booth <shannon@serenityos.org>
* Copyright (c) 2023-2025, Shannon Booth <shannon@serenityos.org>
* Copyright (c) 2023-2024, Matthew Olsson <mattco@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
@ -4753,8 +4753,9 @@ void @constructor_class@::initialize(JS::Realm& realm)
}
generator.append(R"~~~(
define_direct_property(vm.names.prototype, &ensure_web_prototype<@prototype_class@>(realm, "@namespaced_name@"_fly_string), 0);
define_direct_property(vm.names.length, JS::Value(@constructor.length@), JS::Attribute::Configurable);
define_direct_property(vm.names.name, JS::PrimitiveString::create(vm, "@namespaced_name@"_string), JS::Attribute::Configurable);
define_direct_property(vm.names.prototype, &ensure_web_prototype<@prototype_class@>(realm, "@namespaced_name@"_fly_string), 0);
)~~~");

View file

@ -152,7 +152,6 @@ void Intrinsics::create_web_prototype_and_constructor<@prototype_class@>(JS::Rea
m_constructors.set("@interface_name@"_fly_string, constructor);
prototype->define_direct_property(vm.names.constructor, constructor.ptr(), JS::Attribute::Writable | JS::Attribute::Configurable);
constructor->define_direct_property(vm.names.name, JS::PrimitiveString::create(vm, "@interface_name@"_string), JS::Attribute::Configurable);
)~~~");
if (legacy_constructor.has_value()) {
@ -160,9 +159,7 @@ void Intrinsics::create_web_prototype_and_constructor<@prototype_class@>(JS::Rea
gen.set("legacy_constructor_class", legacy_constructor->constructor_class);
gen.append(R"~~~(
auto legacy_constructor = realm.create<@legacy_constructor_class@>(realm);
m_constructors.set("@legacy_interface_name@"_fly_string, legacy_constructor);
legacy_constructor->define_direct_property(vm.names.name, JS::PrimitiveString::create(vm, "@legacy_interface_name@"_string), JS::Attribute::Configurable);)~~~");
m_constructors.set("@legacy_interface_name@"_fly_string, legacy_constructor);)~~~");
}
gen.append(R"~~~(

View file

@ -0,0 +1,8 @@
Harness status: OK
Found 3 tests
3 Pass
Pass Constructor property enumeration order of "length", "name", and "prototype"
Pass Method property enumeration order of "length" and "name"
Pass Getter property enumeration order of "length" and "name"

View file

@ -0,0 +1,15 @@
<!doctype html>
<meta charset=utf-8>
<script>
self.GLOBAL = {
isWindow: function() { return true; },
isWorker: function() { return false; },
isShadowRealm: function() { return false; },
};
</script>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<div id=log></div>
<script src="../../webidl/ecmascript-binding/builtin-function-properties.any.js"></script>

View file

@ -0,0 +1,23 @@
"use strict";
test(() => {
const ownPropKeys = Reflect.ownKeys(Blob).slice(0, 3);
assert_array_equals(ownPropKeys, ["length", "name", "prototype"]);
}, 'Constructor property enumeration order of "length", "name", and "prototype"');
test(() => {
assert_own_property(Blob.prototype, "slice");
const ownPropKeys = Reflect.ownKeys(Blob.prototype.slice).slice(0, 2);
assert_array_equals(ownPropKeys, ["length", "name"]);
}, 'Method property enumeration order of "length" and "name"');
test(() => {
assert_own_property(Blob.prototype, "size");
const desc = Reflect.getOwnPropertyDescriptor(Blob.prototype, "size");
assert_equals(typeof desc.get, "function");
const ownPropKeys = Reflect.ownKeys(desc.get).slice(0, 2);
assert_array_equals(ownPropKeys, ["length", "name"]);
}, 'Getter property enumeration order of "length" and "name"');