mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 13:38:11 +00:00
LibWeb: Restore proper functionality of legacy platform objects
With the GC heap conversion, the functionality of legacy platform objects was broken. This is because the generated implementation of one of them was used for all of them, removing functionality such as deletion. This re-adds all functionality, where questions such as "does the object support indexed properties?" is instead answered by virtual functions instead of by the IDL generator checking the presence of certain keywords/attributes.
This commit is contained in:
parent
7e76a51cb0
commit
54f58e2662
23 changed files with 450 additions and 132 deletions
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
|
* Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
|
||||||
|
* Copyright (c) 2023, Luke Wilde <lukew@serenityos.org>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
@ -17,10 +18,9 @@ LegacyPlatformObject::LegacyPlatformObject(JS::Realm& realm)
|
||||||
|
|
||||||
LegacyPlatformObject::~LegacyPlatformObject() = default;
|
LegacyPlatformObject::~LegacyPlatformObject() = default;
|
||||||
|
|
||||||
|
// https://webidl.spec.whatwg.org/#dfn-named-property-visibility
|
||||||
JS::ThrowCompletionOr<bool> LegacyPlatformObject::is_named_property_exposed_on_object(JS::PropertyKey const& property_key) const
|
JS::ThrowCompletionOr<bool> LegacyPlatformObject::is_named_property_exposed_on_object(JS::PropertyKey const& property_key) const
|
||||||
{
|
{
|
||||||
[[maybe_unused]] auto& vm = this->vm();
|
|
||||||
|
|
||||||
// The spec doesn't say anything about the type of the property name here.
|
// The spec doesn't say anything about the type of the property name here.
|
||||||
// Numbers can be converted to a string, which is fine and what other engines do.
|
// Numbers can be converted to a string, which is fine and what other engines do.
|
||||||
// However, since a symbol cannot be converted to a string, it cannot be a supported property name. Return early if it's a symbol.
|
// However, since a symbol cannot be converted to a string, it cannot be a supported property name. Return early if it's a symbol.
|
||||||
|
@ -29,7 +29,6 @@ JS::ThrowCompletionOr<bool> LegacyPlatformObject::is_named_property_exposed_on_o
|
||||||
|
|
||||||
// 1. If P is not a supported property name of O, then return false.
|
// 1. If P is not a supported property name of O, then return false.
|
||||||
// NOTE: This is in it's own variable to enforce the type.
|
// NOTE: This is in it's own variable to enforce the type.
|
||||||
// FIXME: Can this throw?
|
|
||||||
Vector<DeprecatedString> supported_property_names = this->supported_property_names();
|
Vector<DeprecatedString> supported_property_names = this->supported_property_names();
|
||||||
auto property_key_string = property_key.to_string();
|
auto property_key_string = property_key.to_string();
|
||||||
if (!supported_property_names.contains_slow(property_key_string))
|
if (!supported_property_names.contains_slow(property_key_string))
|
||||||
|
@ -42,7 +41,10 @@ JS::ThrowCompletionOr<bool> LegacyPlatformObject::is_named_property_exposed_on_o
|
||||||
if (own_property_named_p.has_value())
|
if (own_property_named_p.has_value())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// NOTE: Step 3 is not here as the interface doesn't have the LegacyOverrideBuiltIns extended attribute.
|
// 3. If O implements an interface that has the [LegacyOverrideBuiltIns] extended attribute, then return true.
|
||||||
|
if (has_legacy_override_built_ins_interface_extended_attribute())
|
||||||
|
return true;
|
||||||
|
|
||||||
// 4. Let prototype be O.[[GetPrototypeOf]]().
|
// 4. Let prototype be O.[[GetPrototypeOf]]().
|
||||||
auto* prototype = TRY(internal_get_prototype_of());
|
auto* prototype = TRY(internal_get_prototype_of());
|
||||||
|
|
||||||
|
@ -62,18 +64,22 @@ JS::ThrowCompletionOr<bool> LegacyPlatformObject::is_named_property_exposed_on_o
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
JS::ThrowCompletionOr<Optional<JS::PropertyDescriptor>> LegacyPlatformObject::legacy_platform_object_get_own_property_for_get_own_property_slot(JS::PropertyKey const& property_name) const
|
// https://webidl.spec.whatwg.org/#LegacyPlatformObjectGetOwnProperty
|
||||||
|
JS::ThrowCompletionOr<Optional<JS::PropertyDescriptor>> LegacyPlatformObject::legacy_platform_object_get_own_property(JS::PropertyKey const& property_name, IgnoreNamedProps ignore_named_props) const
|
||||||
{
|
{
|
||||||
auto& vm = this->vm();
|
auto& vm = this->vm();
|
||||||
|
|
||||||
if (property_name.is_number()) {
|
// 1. If O supports indexed properties and P is an array index, then:
|
||||||
|
if (supports_indexed_properties() && property_name.is_number()) {
|
||||||
// 1. Let index be the result of calling ToUint32(P).
|
// 1. Let index be the result of calling ToUint32(P).
|
||||||
u32 index = property_name.as_number();
|
u32 index = property_name.as_number();
|
||||||
|
|
||||||
// 2. If index is a supported property index, then:
|
// 2. If index is a supported property index, then:
|
||||||
// FIXME: Can this throw?
|
|
||||||
if (is_supported_property_index(index)) {
|
if (is_supported_property_index(index)) {
|
||||||
|
// 1. Let operation be the operation used to declare the indexed property getter.
|
||||||
|
// 2. Let value be an uninitialized variable.
|
||||||
|
// 3. If operation was defined without an identifier, then set value to the result of performing the steps listed in the interface description to determine the value of an indexed property with index as the index.
|
||||||
|
// 4. Otherwise, operation was defined with an identifier. Set value to the result of performing the method steps of operation with O as this and « index » as the argument values.
|
||||||
auto value = TRY(throw_dom_exception_if_needed(vm, [&] { return item_value(index); }));
|
auto value = TRY(throw_dom_exception_if_needed(vm, [&] { return item_value(index); }));
|
||||||
|
|
||||||
// 5. Let desc be a newly created Property Descriptor with no fields.
|
// 5. Let desc be a newly created Property Descriptor with no fields.
|
||||||
|
@ -82,7 +88,8 @@ JS::ThrowCompletionOr<Optional<JS::PropertyDescriptor>> LegacyPlatformObject::le
|
||||||
// 6. Set desc.[[Value]] to the result of converting value to an ECMAScript value.
|
// 6. Set desc.[[Value]] to the result of converting value to an ECMAScript value.
|
||||||
descriptor.value = value;
|
descriptor.value = value;
|
||||||
|
|
||||||
descriptor.writable = false;
|
// 7. If O implements an interface with an indexed property setter, then set desc.[[Writable]] to true, otherwise set it to false.
|
||||||
|
descriptor.writable = has_indexed_property_setter();
|
||||||
|
|
||||||
// 8. Set desc.[[Enumerable]] and desc.[[Configurable]] to true.
|
// 8. Set desc.[[Enumerable]] and desc.[[Configurable]] to true.
|
||||||
descriptor.enumerable = true;
|
descriptor.enumerable = true;
|
||||||
|
@ -93,82 +100,135 @@ JS::ThrowCompletionOr<Optional<JS::PropertyDescriptor>> LegacyPlatformObject::le
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. Set ignoreNamedProps to true.
|
// 3. Set ignoreNamedProps to true.
|
||||||
return TRY(Object::internal_get_own_property(property_name));
|
ignore_named_props = IgnoreNamedProps::Yes;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 1. If the result of running the named property visibility algorithm with property name P and object O is true, then:
|
// 2. If O supports named properties and ignoreNamedProps is false, then:
|
||||||
if (TRY(is_named_property_exposed_on_object(property_name))) {
|
if (supports_named_properties() && ignore_named_props == IgnoreNamedProps::No) {
|
||||||
// FIXME: It's unfortunate that this is done twice, once in is_named_property_exposed_on_object and here.
|
// 1. If the result of running the named property visibility algorithm with property name P and object O is true, then:
|
||||||
auto property_name_string = property_name.to_string();
|
if (TRY(is_named_property_exposed_on_object(property_name))) {
|
||||||
|
// FIXME: It's unfortunate that this is done twice, once in is_named_property_exposed_on_object and here.
|
||||||
|
auto property_name_string = property_name.to_string();
|
||||||
|
|
||||||
auto value = TRY(throw_dom_exception_if_needed(vm, [&] { return named_item_value(property_name_string); }));
|
// 1. Let operation be the operation used to declare the named property getter.
|
||||||
|
// 2. Let value be an uninitialized variable.
|
||||||
|
// 3. If operation was defined without an identifier, then set value to the result of performing the steps listed in the interface description to determine the value of a named property with P as the name.
|
||||||
|
// 4. Otherwise, operation was defined with an identifier. Set value to the result of performing the method steps of operation with O as this and « P » as the argument values.
|
||||||
|
auto value = TRY(throw_dom_exception_if_needed(vm, [&] { return named_item_value(property_name_string); }));
|
||||||
|
|
||||||
// 5. Let desc be a newly created Property Descriptor with no fields.
|
// 5. Let desc be a newly created Property Descriptor with no fields.
|
||||||
JS::PropertyDescriptor descriptor;
|
JS::PropertyDescriptor descriptor;
|
||||||
|
|
||||||
// 6. Set desc.[[Value]] to the result of converting value to an ECMAScript value.
|
// 6. Set desc.[[Value]] to the result of converting value to an ECMAScript value.
|
||||||
descriptor.value = value;
|
descriptor.value = value;
|
||||||
|
|
||||||
descriptor.writable = false;
|
// 7. If O implements an interface with a named property setter, then set desc.[[Writable]] to true, otherwise set it to false.
|
||||||
|
descriptor.writable = has_named_property_setter();
|
||||||
|
|
||||||
descriptor.enumerable = false;
|
// 8. If O implements an interface with the [LegacyUnenumerableNamedProperties] extended attribute, then set desc.[[Enumerable]] to false, otherwise set it to true.
|
||||||
|
descriptor.enumerable = !has_legacy_unenumerable_named_properties_interface_extended_attribute();
|
||||||
|
|
||||||
// 9. Set desc.[[Configurable]] to true.
|
// 9. Set desc.[[Configurable]] to true.
|
||||||
descriptor.configurable = true;
|
descriptor.configurable = true;
|
||||||
|
|
||||||
// 10. Return desc.
|
// 10. Return desc.
|
||||||
return descriptor;
|
return descriptor;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 3. Return OrdinaryGetOwnProperty(O, P).
|
||||||
return TRY(Object::internal_get_own_property(property_name));
|
return TRY(Object::internal_get_own_property(property_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
JS::ThrowCompletionOr<Optional<JS::PropertyDescriptor>> LegacyPlatformObject::legacy_platform_object_get_own_property_for_set_slot(JS::PropertyKey const& property_name) const
|
// https://webidl.spec.whatwg.org/#invoke-indexed-setter
|
||||||
|
WebIDL::ExceptionOr<void> LegacyPlatformObject::invoke_indexed_property_setter(JS::PropertyKey const& property_name, JS::Value value)
|
||||||
{
|
{
|
||||||
if (!property_name.is_number())
|
// 1. Let index be the result of calling ? ToUint32(P).
|
||||||
return TRY(Object::internal_get_own_property(property_name));
|
auto index = property_name.as_number();
|
||||||
|
|
||||||
// 1. Let index be the result of calling ToUint32(P).
|
// 2. Let creating be true if index is not a supported property index, and false otherwise.
|
||||||
u32 index = property_name.as_number();
|
bool creating = !is_supported_property_index(index);
|
||||||
|
|
||||||
// 2. If index is a supported property index, then:
|
// FIXME: We do not have this information at this point, so converting the value is left as an exercise to the inheritor of LegacyPlatformObject.
|
||||||
// FIXME: Can this throw?
|
// 3. Let operation be the operation used to declare the indexed property setter.
|
||||||
if (is_supported_property_index(index)) {
|
// 4. Let T be the type of the second argument of operation.
|
||||||
|
// 5. Let value be the result of converting V to an IDL value of type T.
|
||||||
|
|
||||||
auto value = TRY(throw_dom_exception_if_needed(vm(), [&] { return item_value(index); }));
|
// 6. If operation was defined without an identifier, then:
|
||||||
|
if (!indexed_property_setter_has_identifier()) {
|
||||||
|
// 1. If creating is true, then perform the steps listed in the interface description to set the value of a new indexed property with index as the index and value as the value.
|
||||||
|
if (creating)
|
||||||
|
return set_value_of_new_indexed_property(index, value);
|
||||||
|
|
||||||
// 5. Let desc be a newly created Property Descriptor with no fields.
|
// 2. Otherwise, creating is false. Perform the steps listed in the interface description to set the value of an existing indexed property with index as the index and value as the value.
|
||||||
JS::PropertyDescriptor descriptor;
|
return set_value_of_existing_indexed_property(index, value);
|
||||||
|
|
||||||
// 6. Set desc.[[Value]] to the result of converting value to an ECMAScript value.
|
|
||||||
descriptor.value = value;
|
|
||||||
|
|
||||||
descriptor.writable = false;
|
|
||||||
|
|
||||||
// 8. Set desc.[[Enumerable]] and desc.[[Configurable]] to true.
|
|
||||||
descriptor.enumerable = true;
|
|
||||||
descriptor.configurable = true;
|
|
||||||
|
|
||||||
// 9. Return desc.
|
|
||||||
return descriptor;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. Set ignoreNamedProps to true.
|
// 7. Otherwise, operation was defined with an identifier. Perform the method steps of operation with O as this and « index, value » as the argument values.
|
||||||
return TRY(Object::internal_get_own_property(property_name));
|
return set_value_of_indexed_property(index, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://webidl.spec.whatwg.org/#invoke-named-setter
|
||||||
|
WebIDL::ExceptionOr<void> LegacyPlatformObject::invoke_named_property_setter(DeprecatedString const& property_name, JS::Value value)
|
||||||
|
{
|
||||||
|
// 1. Let creating be true if P is not a supported property name, and false otherwise.
|
||||||
|
Vector<DeprecatedString> supported_property_names = this->supported_property_names();
|
||||||
|
bool creating = !supported_property_names.contains_slow(property_name);
|
||||||
|
|
||||||
|
// FIXME: We do not have this information at this point, so converting the value is left as an exercise to the inheritor of LegacyPlatformObject.
|
||||||
|
// 2. Let operation be the operation used to declare the indexed property setter.
|
||||||
|
// 3. Let T be the type of the second argument of operation.
|
||||||
|
// 4. Let value be the result of converting V to an IDL value of type T.
|
||||||
|
|
||||||
|
// 5. If operation was defined without an identifier, then:
|
||||||
|
if (!named_property_setter_has_identifier()) {
|
||||||
|
// 1. If creating is true, then perform the steps listed in the interface description to set the value of a new named property with P as the name and value as the value.
|
||||||
|
if (creating)
|
||||||
|
return set_value_of_new_named_property(property_name, value);
|
||||||
|
|
||||||
|
// 2. Otherwise, creating is false. Perform the steps listed in the interface description to set the value of an existing named property with P as the name and value as the value.
|
||||||
|
return set_value_of_existing_named_property(property_name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 6. Otherwise, operation was defined with an identifier. Perform the method steps of operation with O as this and « P, value » as the argument values.
|
||||||
|
return set_value_of_named_property(property_name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://webidl.spec.whatwg.org/#legacy-platform-object-getownproperty
|
||||||
JS::ThrowCompletionOr<Optional<JS::PropertyDescriptor>> LegacyPlatformObject::internal_get_own_property(JS::PropertyKey const& property_name) const
|
JS::ThrowCompletionOr<Optional<JS::PropertyDescriptor>> LegacyPlatformObject::internal_get_own_property(JS::PropertyKey const& property_name) const
|
||||||
{
|
{
|
||||||
// 1. Return LegacyPlatformObjectGetOwnProperty(O, P, false).
|
// 1. Return ? LegacyPlatformObjectGetOwnProperty(O, P, false).
|
||||||
return TRY(legacy_platform_object_get_own_property_for_get_own_property_slot(property_name));
|
return TRY(legacy_platform_object_get_own_property(property_name, IgnoreNamedProps::No));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://webidl.spec.whatwg.org/#legacy-platform-object-set
|
||||||
JS::ThrowCompletionOr<bool> LegacyPlatformObject::internal_set(JS::PropertyKey const& property_name, JS::Value value, JS::Value receiver)
|
JS::ThrowCompletionOr<bool> LegacyPlatformObject::internal_set(JS::PropertyKey const& property_name, JS::Value value, JS::Value receiver)
|
||||||
{
|
{
|
||||||
[[maybe_unused]] auto& global_object = this->global_object();
|
auto& vm = this->vm();
|
||||||
|
|
||||||
// 2. Let ownDesc be LegacyPlatformObjectGetOwnProperty(O, P, true).
|
// 1. If O and Receiver are the same object, then:
|
||||||
auto own_descriptor = TRY(legacy_platform_object_get_own_property_for_set_slot(property_name));
|
if (receiver.is_object() && &receiver.as_object() == this) {
|
||||||
|
// 1. If O implements an interface with an indexed property setter and P is an array index, then:
|
||||||
|
if (has_indexed_property_setter() && property_name.is_number()) {
|
||||||
|
// 1. Invoke the indexed property setter on O with P and V.
|
||||||
|
TRY(throw_dom_exception_if_needed(vm, [&] { return invoke_indexed_property_setter(property_name, value); }));
|
||||||
|
|
||||||
|
// 2. Return true.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. If O implements an interface with a named property setter and Type(P) is String, then:
|
||||||
|
if (has_named_property_setter() && property_name.is_string()) {
|
||||||
|
// 1. Invoke the named property setter on O with P and V.
|
||||||
|
TRY(throw_dom_exception_if_needed(vm, [&] { return invoke_named_property_setter(property_name.as_string(), value); }));
|
||||||
|
|
||||||
|
// 2. Return true.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Let ownDesc be ? LegacyPlatformObjectGetOwnProperty(O, P, true).
|
||||||
|
auto own_descriptor = TRY(legacy_platform_object_get_own_property(property_name, IgnoreNamedProps::Yes));
|
||||||
|
|
||||||
// 3. Perform ? OrdinarySetWithOwnDescriptor(O, P, V, Receiver, ownDesc).
|
// 3. Perform ? OrdinarySetWithOwnDescriptor(O, P, V, Receiver, ownDesc).
|
||||||
// NOTE: The spec says "perform" instead of "return", meaning nothing will be returned on this path according to the spec, which isn't possible to do.
|
// NOTE: The spec says "perform" instead of "return", meaning nothing will be returned on this path according to the spec, which isn't possible to do.
|
||||||
|
@ -176,56 +236,83 @@ JS::ThrowCompletionOr<bool> LegacyPlatformObject::internal_set(JS::PropertyKey c
|
||||||
return ordinary_set_with_own_descriptor(property_name, value, receiver, own_descriptor);
|
return ordinary_set_with_own_descriptor(property_name, value, receiver, own_descriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://webidl.spec.whatwg.org/#legacy-platform-object-defineownproperty
|
||||||
JS::ThrowCompletionOr<bool> LegacyPlatformObject::internal_define_own_property(JS::PropertyKey const& property_name, JS::PropertyDescriptor const& property_descriptor)
|
JS::ThrowCompletionOr<bool> LegacyPlatformObject::internal_define_own_property(JS::PropertyKey const& property_name, JS::PropertyDescriptor const& property_descriptor)
|
||||||
{
|
{
|
||||||
[[maybe_unused]] auto& vm = this->vm();
|
auto& vm = this->vm();
|
||||||
[[maybe_unused]] auto& global_object = this->global_object();
|
|
||||||
|
|
||||||
if (property_name.is_number()) {
|
// 1. If O supports indexed properties and P is an array index, then:
|
||||||
|
if (supports_indexed_properties() && property_name.is_number()) {
|
||||||
// 1. If the result of calling IsDataDescriptor(Desc) is false, then return false.
|
// 1. If the result of calling IsDataDescriptor(Desc) is false, then return false.
|
||||||
if (!property_descriptor.is_data_descriptor())
|
if (!property_descriptor.is_data_descriptor())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return false;
|
// 2. If O does not implement an interface with an indexed property setter, then return false.
|
||||||
|
if (!has_indexed_property_setter())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// 3. Invoke the indexed property setter on O with P and Desc.[[Value]].
|
||||||
|
TRY(throw_dom_exception_if_needed(vm, [&] { return invoke_indexed_property_setter(property_name, property_descriptor.value.value()); }));
|
||||||
|
|
||||||
|
// 4. Return true.
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (property_name.is_string()) {
|
// 2. If O supports named properties, O does not implement an interface with the [Global] extended attribute, Type(P) is String, and P is not an unforgeable property name of O, then:
|
||||||
auto& property_name_as_string = property_name.as_string();
|
// FIXME: Check if P is not an unforgeable property name of O
|
||||||
|
if (supports_named_properties() && !has_global_interface_extended_attribute() && property_name.is_string()) {
|
||||||
|
auto const& property_name_as_string = property_name.as_string();
|
||||||
|
|
||||||
// 1. Let creating be true if P is not a supported property name, and false otherwise.
|
// 1. Let creating be true if P is not a supported property name, and false otherwise.
|
||||||
// NOTE: This is in it's own variable to enforce the type.
|
// NOTE: This is in it's own variable to enforce the type.
|
||||||
// FIXME: Can this throw?
|
|
||||||
Vector<DeprecatedString> supported_property_names = this->supported_property_names();
|
Vector<DeprecatedString> supported_property_names = this->supported_property_names();
|
||||||
[[maybe_unused]] bool creating = !supported_property_names.contains_slow(property_name_as_string);
|
bool creating = !supported_property_names.contains_slow(property_name_as_string);
|
||||||
|
|
||||||
// NOTE: This has to be done manually instead of using Object::has_own_property, as that would use the overridden internal_get_own_property.
|
// 2. If O implements an interface with the [LegacyOverrideBuiltIns] extended attribute or O does not have an own property named P, then:
|
||||||
auto own_property_named_p = TRY(Object::internal_get_own_property(property_name));
|
// NOTE: Own property lookup has to be done manually instead of using Object::has_own_property, as that would use the overridden internal_get_own_property.
|
||||||
|
if (has_legacy_override_built_ins_interface_extended_attribute() || !TRY(Object::internal_get_own_property(property_name)).has_value()) {
|
||||||
if (!own_property_named_p.has_value()) {
|
// 1. If creating is false and O does not implement an interface with a named property setter, then return false.
|
||||||
|
if (!creating && !has_named_property_setter())
|
||||||
if (!creating)
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// 2. If O implements an interface with a named property setter, then:
|
||||||
|
if (has_named_property_setter()) {
|
||||||
|
// 1. If the result of calling IsDataDescriptor(Desc) is false, then return false.
|
||||||
|
if (!property_descriptor.is_data_descriptor())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// 2. Invoke the named property setter on O with P and Desc.[[Value]].
|
||||||
|
TRY(throw_dom_exception_if_needed(vm, [&] { return invoke_named_property_setter(property_name_as_string, property_descriptor.value.value()); }));
|
||||||
|
|
||||||
|
// 3. Return true.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// property_descriptor is a const&, thus we need to create a copy here to set [[Configurable]]
|
// 3. If O does not implement an interface with the [Global] extended attribute, then set Desc.[[Configurable]] to true.
|
||||||
JS::PropertyDescriptor descriptor_copy(property_descriptor);
|
// 4. Return ! OrdinaryDefineOwnProperty(O, P, Desc).
|
||||||
descriptor_copy.configurable = true;
|
if (!has_global_interface_extended_attribute()) {
|
||||||
|
// property_descriptor is a const&, thus we need to create a copy here to set [[Configurable]]
|
||||||
|
JS::PropertyDescriptor descriptor_copy(property_descriptor);
|
||||||
|
descriptor_copy.configurable = true;
|
||||||
|
return Object::internal_define_own_property(property_name, descriptor_copy);
|
||||||
|
}
|
||||||
|
|
||||||
// 4. Return OrdinaryDefineOwnProperty(O, P, Desc).
|
return Object::internal_define_own_property(property_name, property_descriptor);
|
||||||
return Object::internal_define_own_property(property_name, descriptor_copy);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://webidl.spec.whatwg.org/#legacy-platform-object-delete
|
||||||
JS::ThrowCompletionOr<bool> LegacyPlatformObject::internal_delete(JS::PropertyKey const& property_name)
|
JS::ThrowCompletionOr<bool> LegacyPlatformObject::internal_delete(JS::PropertyKey const& property_name)
|
||||||
{
|
{
|
||||||
[[maybe_unused]] auto& global_object = this->global_object();
|
auto& vm = this->vm();
|
||||||
|
|
||||||
if (property_name.is_number()) {
|
// 1. If O supports indexed properties and P is an array index, then:
|
||||||
// 1. Let index be the result of calling ToUint32(P).
|
if (supports_indexed_properties() && property_name.is_number()) {
|
||||||
|
// 1. Let index be the result of calling ! ToUint32(P).
|
||||||
u32 index = property_name.as_number();
|
u32 index = property_name.as_number();
|
||||||
|
|
||||||
// 2. If index is not a supported property index, then return true.
|
// 2. If index is not a supported property index, then return true.
|
||||||
// FIXME: Can this throw?
|
|
||||||
if (!is_supported_property_index(index))
|
if (!is_supported_property_index(index))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
@ -233,33 +320,60 @@ JS::ThrowCompletionOr<bool> LegacyPlatformObject::internal_delete(JS::PropertyKe
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TRY(is_named_property_exposed_on_object(property_name))) {
|
// 2. If O supports named properties, O does not implement an interface with the [Global] extended attribute and
|
||||||
|
// the result of calling the named property visibility algorithm with property name P and object O is true, then:
|
||||||
|
if (supports_named_properties() && !has_global_interface_extended_attribute() && TRY(is_named_property_exposed_on_object(property_name))) {
|
||||||
|
// 1. If O does not implement an interface with a named property deleter, then return false.
|
||||||
|
if (!has_named_property_deleter())
|
||||||
|
return false;
|
||||||
|
|
||||||
return false;
|
// FIXME: It's unfortunate that this is done twice, once in is_named_property_exposed_on_object and here.
|
||||||
|
auto property_name_string = property_name.to_string();
|
||||||
|
|
||||||
|
// 2. Let operation be the operation used to declare the named property deleter.
|
||||||
|
// 3. If operation was defined without an identifier, then:
|
||||||
|
// 1. Perform the steps listed in the interface description to delete an existing named property with P as the name.
|
||||||
|
// 2. If the steps indicated that the deletion failed, then return false.
|
||||||
|
// 4. Otherwise, operation was defined with an identifier:
|
||||||
|
// 1. Perform method steps of operation with O as this and « P » as the argument values.
|
||||||
|
// 2. If operation was declared with a return type of boolean and the steps returned false, then return false.
|
||||||
|
auto did_deletion_fail = TRY(throw_dom_exception_if_needed(vm, [&] { return delete_value(property_name_string); }));
|
||||||
|
if (!named_property_deleter_has_identifier())
|
||||||
|
VERIFY(did_deletion_fail != DidDeletionFail::NotRelevant);
|
||||||
|
|
||||||
|
if (did_deletion_fail == DidDeletionFail::Yes)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// 5. Return true.
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. If O has an own property with name P, then:
|
// 3. If O has an own property with name P, then:
|
||||||
|
// NOTE: This has to be done manually instead of using Object::has_own_property, as that would use the overridden internal_get_own_property.
|
||||||
auto own_property_named_p_descriptor = TRY(Object::internal_get_own_property(property_name));
|
auto own_property_named_p_descriptor = TRY(Object::internal_get_own_property(property_name));
|
||||||
|
|
||||||
if (own_property_named_p_descriptor.has_value()) {
|
if (own_property_named_p_descriptor.has_value()) {
|
||||||
// 1. If the property is not configurable, then return false.
|
// 1. If the property is not configurable, then return false.
|
||||||
// 2. Otherwise, remove the property from O.
|
if (!own_property_named_p_descriptor->configurable.value())
|
||||||
if (*own_property_named_p_descriptor->configurable)
|
|
||||||
storage_delete(property_name);
|
|
||||||
else
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// 2. Otherwise, remove the property from O.
|
||||||
|
storage_delete(property_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. Return true.
|
// 4. Return true.
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://webidl.spec.whatwg.org/#legacy-platform-object-preventextensions
|
||||||
JS::ThrowCompletionOr<bool> LegacyPlatformObject::internal_prevent_extensions()
|
JS::ThrowCompletionOr<bool> LegacyPlatformObject::internal_prevent_extensions()
|
||||||
{
|
{
|
||||||
// 1. Return false.
|
// 1. Return false.
|
||||||
|
// Spec Note: Note: this keeps legacy platform objects extensible by making [[PreventExtensions]] fail for them.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://webidl.spec.whatwg.org/#legacy-platform-object-ownpropertykeys
|
||||||
JS::ThrowCompletionOr<JS::MarkedVector<JS::Value>> LegacyPlatformObject::internal_own_property_keys() const
|
JS::ThrowCompletionOr<JS::MarkedVector<JS::Value>> LegacyPlatformObject::internal_own_property_keys() const
|
||||||
{
|
{
|
||||||
auto& vm = this->vm();
|
auto& vm = this->vm();
|
||||||
|
@ -267,16 +381,22 @@ JS::ThrowCompletionOr<JS::MarkedVector<JS::Value>> LegacyPlatformObject::interna
|
||||||
// 1. Let keys be a new empty list of ECMAScript String and Symbol values.
|
// 1. Let keys be a new empty list of ECMAScript String and Symbol values.
|
||||||
JS::MarkedVector<JS::Value> keys { heap() };
|
JS::MarkedVector<JS::Value> keys { heap() };
|
||||||
|
|
||||||
for (u64 index = 0; index <= NumericLimits<u32>::max(); ++index) {
|
// 2. If O supports indexed properties, then for each index of O’s supported property indices, in ascending numerical order, append ! ToString(index) to keys.
|
||||||
if (is_supported_property_index(index))
|
if (supports_indexed_properties()) {
|
||||||
keys.append(JS::PrimitiveString::create(vm, DeprecatedString::number(index)));
|
for (u64 index = 0; index <= NumericLimits<u32>::max(); ++index) {
|
||||||
else
|
if (is_supported_property_index(index))
|
||||||
break;
|
keys.append(JS::PrimitiveString::create(vm, DeprecatedString::number(index)));
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& named_property : supported_property_names()) {
|
// 3. If O supports named properties, then for each P of O’s supported property names that is visible according to the named property visibility algorithm, append P to keys.
|
||||||
if (TRY(is_named_property_exposed_on_object(named_property)))
|
if (supports_named_properties()) {
|
||||||
keys.append(JS::PrimitiveString::create(vm, named_property));
|
for (auto& named_property : supported_property_names()) {
|
||||||
|
if (TRY(is_named_property_exposed_on_object(named_property)))
|
||||||
|
keys.append(JS::PrimitiveString::create(vm, named_property));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. For each P of O’s own property keys that is a String, in ascending chronological order of property creation, append P to keys.
|
// 4. For each P of O’s own property keys that is a String, in ascending chronological order of property creation, append P to keys.
|
||||||
|
@ -297,12 +417,12 @@ JS::ThrowCompletionOr<JS::MarkedVector<JS::Value>> LegacyPlatformObject::interna
|
||||||
return { move(keys) };
|
return { move(keys) };
|
||||||
}
|
}
|
||||||
|
|
||||||
JS::Value LegacyPlatformObject::item_value(size_t) const
|
WebIDL::ExceptionOr<JS::Value> LegacyPlatformObject::item_value(size_t) const
|
||||||
{
|
{
|
||||||
return JS::js_undefined();
|
return JS::js_undefined();
|
||||||
}
|
}
|
||||||
|
|
||||||
JS::Value LegacyPlatformObject::named_item_value(DeprecatedFlyString const&) const
|
WebIDL::ExceptionOr<JS::Value> LegacyPlatformObject::named_item_value(DeprecatedFlyString const&) const
|
||||||
{
|
{
|
||||||
return JS::js_undefined();
|
return JS::js_undefined();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
|
* Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
|
||||||
|
* Copyright (c) 2023, Luke Wilde <lukew@serenityos.org>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
@ -7,6 +8,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <LibWeb/Bindings/PlatformObject.h>
|
#include <LibWeb/Bindings/PlatformObject.h>
|
||||||
|
#include <LibWeb/WebIDL/ExceptionOr.h>
|
||||||
|
|
||||||
namespace Web::Bindings {
|
namespace Web::Bindings {
|
||||||
|
|
||||||
|
@ -25,16 +27,70 @@ public:
|
||||||
virtual JS::ThrowCompletionOr<JS::MarkedVector<JS::Value>> internal_own_property_keys() const override;
|
virtual JS::ThrowCompletionOr<JS::MarkedVector<JS::Value>> internal_own_property_keys() const override;
|
||||||
|
|
||||||
JS::ThrowCompletionOr<bool> is_named_property_exposed_on_object(JS::PropertyKey const&) const;
|
JS::ThrowCompletionOr<bool> is_named_property_exposed_on_object(JS::PropertyKey const&) const;
|
||||||
JS::ThrowCompletionOr<Optional<JS::PropertyDescriptor>> legacy_platform_object_get_own_property_for_get_own_property_slot(JS::PropertyKey const&) const;
|
|
||||||
JS::ThrowCompletionOr<Optional<JS::PropertyDescriptor>> legacy_platform_object_get_own_property_for_set_slot(JS::PropertyKey const&) const;
|
|
||||||
|
|
||||||
virtual JS::Value item_value(size_t index) const;
|
enum class IgnoreNamedProps {
|
||||||
virtual JS::Value named_item_value(DeprecatedFlyString const& name) const;
|
No,
|
||||||
|
Yes,
|
||||||
|
};
|
||||||
|
JS::ThrowCompletionOr<Optional<JS::PropertyDescriptor>> legacy_platform_object_get_own_property(JS::PropertyKey const&, IgnoreNamedProps ignore_named_props) const;
|
||||||
|
|
||||||
|
virtual WebIDL::ExceptionOr<JS::Value> item_value(size_t index) const;
|
||||||
|
virtual WebIDL::ExceptionOr<JS::Value> named_item_value(DeprecatedFlyString const& name) const;
|
||||||
virtual Vector<DeprecatedString> supported_property_names() const;
|
virtual Vector<DeprecatedString> supported_property_names() const;
|
||||||
virtual bool is_supported_property_index(u32) const;
|
virtual bool is_supported_property_index(u32) const;
|
||||||
|
|
||||||
|
// NOTE: These will crash if you make has_named_property_setter return true but do not override these methods.
|
||||||
|
// NOTE: This is only used if named_property_setter_has_identifier returns false, otherwise set_value_of_named_property is used instead.
|
||||||
|
virtual WebIDL::ExceptionOr<void> set_value_of_new_named_property(DeprecatedString const&, JS::Value) { VERIFY_NOT_REACHED(); }
|
||||||
|
virtual WebIDL::ExceptionOr<void> set_value_of_existing_named_property(DeprecatedString const&, JS::Value) { VERIFY_NOT_REACHED(); }
|
||||||
|
|
||||||
|
// NOTE: These will crash if you make has_named_property_setter return true but do not override these methods.
|
||||||
|
// NOTE: This is only used if you make named_property_setter_has_identifier return true, otherwise set_value_of_{new,existing}_named_property is used instead.
|
||||||
|
virtual WebIDL::ExceptionOr<void> set_value_of_named_property(DeprecatedString const&, JS::Value) { VERIFY_NOT_REACHED(); }
|
||||||
|
|
||||||
|
// NOTE: These will crash if you make has_indexed_property_setter return true but do not override these methods.
|
||||||
|
// NOTE: This is only used if indexed_property_setter_has_identifier returns false, otherwise set_value_of_indexed_property is used instead.
|
||||||
|
virtual WebIDL::ExceptionOr<void> set_value_of_new_indexed_property(u32, JS::Value) { VERIFY_NOT_REACHED(); }
|
||||||
|
virtual WebIDL::ExceptionOr<void> set_value_of_existing_indexed_property(u32, JS::Value) { VERIFY_NOT_REACHED(); }
|
||||||
|
|
||||||
|
// NOTE: These will crash if you make has_named_property_setter return true but do not override these methods.
|
||||||
|
// NOTE: This is only used if indexed_property_setter_has_identifier returns true, otherwise set_value_of_{new,existing}_indexed_property is used instead.
|
||||||
|
virtual WebIDL::ExceptionOr<void> set_value_of_indexed_property(u32, JS::Value) { VERIFY_NOT_REACHED(); }
|
||||||
|
|
||||||
|
enum class DidDeletionFail {
|
||||||
|
// If the named property deleter has an identifier, but does not return a boolean.
|
||||||
|
// This is done because we don't know the return type of the deleter outside of the IDL generator.
|
||||||
|
NotRelevant,
|
||||||
|
No,
|
||||||
|
Yes,
|
||||||
|
};
|
||||||
|
|
||||||
|
// NOTE: This will crash if you make has_named_property_deleter return true but do not override this method.
|
||||||
|
virtual WebIDL::ExceptionOr<DidDeletionFail> delete_value(DeprecatedString const&) { VERIFY_NOT_REACHED(); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit LegacyPlatformObject(JS::Realm& realm);
|
explicit LegacyPlatformObject(JS::Realm& realm);
|
||||||
|
|
||||||
|
// NOTE: These two can also be seen as "has x property getter"
|
||||||
|
virtual bool supports_indexed_properties() const = 0;
|
||||||
|
virtual bool supports_named_properties() const = 0;
|
||||||
|
|
||||||
|
virtual bool has_indexed_property_setter() const = 0;
|
||||||
|
virtual bool has_named_property_setter() const = 0;
|
||||||
|
|
||||||
|
virtual bool has_named_property_deleter() const = 0;
|
||||||
|
|
||||||
|
virtual bool has_legacy_override_built_ins_interface_extended_attribute() const = 0;
|
||||||
|
virtual bool has_legacy_unenumerable_named_properties_interface_extended_attribute() const = 0;
|
||||||
|
virtual bool has_global_interface_extended_attribute() const = 0;
|
||||||
|
|
||||||
|
virtual bool indexed_property_setter_has_identifier() const = 0;
|
||||||
|
virtual bool named_property_setter_has_identifier() const = 0;
|
||||||
|
virtual bool named_property_deleter_has_identifier() const = 0;
|
||||||
|
|
||||||
|
private:
|
||||||
|
WebIDL::ExceptionOr<void> invoke_indexed_property_setter(JS::PropertyKey const&, JS::Value);
|
||||||
|
WebIDL::ExceptionOr<void> invoke_named_property_setter(DeprecatedString const&, JS::Value);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -183,7 +183,7 @@ bool CSSRuleList::evaluate_media_queries(HTML::Window const& window)
|
||||||
return any_media_queries_changed_match_state;
|
return any_media_queries_changed_match_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
JS::Value CSSRuleList::item_value(size_t index) const
|
WebIDL::ExceptionOr<JS::Value> CSSRuleList::item_value(size_t index) const
|
||||||
{
|
{
|
||||||
return item(index);
|
return item(index);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2021-2022, Sam Atkins <atkinssj@serenityos.org>
|
* Copyright (c) 2021-2022, Sam Atkins <atkinssj@serenityos.org>
|
||||||
* Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
|
* Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
|
||||||
|
* Copyright (c) 2023, Luke Wilde <lukew@serenityos.org>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
@ -54,7 +55,7 @@ public:
|
||||||
Iterator end() { return m_rules.end(); }
|
Iterator end() { return m_rules.end(); }
|
||||||
|
|
||||||
virtual bool is_supported_property_index(u32 index) const override;
|
virtual bool is_supported_property_index(u32 index) const override;
|
||||||
virtual JS::Value item_value(size_t index) const override;
|
virtual WebIDL::ExceptionOr<JS::Value> item_value(size_t index) const override;
|
||||||
|
|
||||||
WebIDL::ExceptionOr<void> remove_a_css_rule(u32 index);
|
WebIDL::ExceptionOr<void> remove_a_css_rule(u32 index);
|
||||||
WebIDL::ExceptionOr<unsigned> insert_a_css_rule(Variant<StringView, CSSRule*>, u32 index);
|
WebIDL::ExceptionOr<unsigned> insert_a_css_rule(Variant<StringView, CSSRule*>, u32 index);
|
||||||
|
@ -69,6 +70,19 @@ private:
|
||||||
virtual JS::ThrowCompletionOr<void> initialize(JS::Realm&) override;
|
virtual JS::ThrowCompletionOr<void> initialize(JS::Realm&) override;
|
||||||
virtual void visit_edges(Cell::Visitor&) override;
|
virtual void visit_edges(Cell::Visitor&) override;
|
||||||
|
|
||||||
|
// ^Bindings::LegacyPlatformObject
|
||||||
|
virtual bool supports_indexed_properties() const override { return true; }
|
||||||
|
virtual bool supports_named_properties() const override { return false; }
|
||||||
|
virtual bool has_indexed_property_setter() const override { return false; }
|
||||||
|
virtual bool has_named_property_setter() const override { return false; }
|
||||||
|
virtual bool has_named_property_deleter() const override { return false; }
|
||||||
|
virtual bool has_legacy_override_built_ins_interface_extended_attribute() const override { return false; }
|
||||||
|
virtual bool has_legacy_unenumerable_named_properties_interface_extended_attribute() const override { return false; }
|
||||||
|
virtual bool has_global_interface_extended_attribute() const override { return false; }
|
||||||
|
virtual bool indexed_property_setter_has_identifier() const override { return false; }
|
||||||
|
virtual bool named_property_setter_has_identifier() const override { return false; }
|
||||||
|
virtual bool named_property_deleter_has_identifier() const override { return false; }
|
||||||
|
|
||||||
Vector<CSSRule&> m_rules;
|
Vector<CSSRule&> m_rules;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -115,7 +115,7 @@ bool MediaList::matches() const
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
JS::Value MediaList::item_value(size_t index) const
|
WebIDL::ExceptionOr<JS::Value> MediaList::item_value(size_t index) const
|
||||||
{
|
{
|
||||||
if (index >= m_media.size())
|
if (index >= m_media.size())
|
||||||
return JS::js_undefined();
|
return JS::js_undefined();
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2021-2022, Sam Atkins <atkinssj@serenityos.org>
|
* Copyright (c) 2021-2022, Sam Atkins <atkinssj@serenityos.org>
|
||||||
* Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
|
* Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
|
||||||
|
* Copyright (c) 2023, Luke Wilde <lukew@serenityos.org>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
@ -31,7 +32,7 @@ public:
|
||||||
void delete_medium(DeprecatedString);
|
void delete_medium(DeprecatedString);
|
||||||
|
|
||||||
virtual bool is_supported_property_index(u32 index) const override;
|
virtual bool is_supported_property_index(u32 index) const override;
|
||||||
virtual JS::Value item_value(size_t index) const override;
|
virtual WebIDL::ExceptionOr<JS::Value> item_value(size_t index) const override;
|
||||||
|
|
||||||
bool evaluate(HTML::Window const&);
|
bool evaluate(HTML::Window const&);
|
||||||
bool matches() const;
|
bool matches() const;
|
||||||
|
@ -41,6 +42,19 @@ private:
|
||||||
|
|
||||||
virtual JS::ThrowCompletionOr<void> initialize(JS::Realm&) override;
|
virtual JS::ThrowCompletionOr<void> initialize(JS::Realm&) override;
|
||||||
|
|
||||||
|
// ^Bindings::LegacyPlatformObject
|
||||||
|
virtual bool supports_indexed_properties() const override { return true; }
|
||||||
|
virtual bool supports_named_properties() const override { return false; }
|
||||||
|
virtual bool has_indexed_property_setter() const override { return false; }
|
||||||
|
virtual bool has_named_property_setter() const override { return false; }
|
||||||
|
virtual bool has_named_property_deleter() const override { return false; }
|
||||||
|
virtual bool has_legacy_override_built_ins_interface_extended_attribute() const override { return false; }
|
||||||
|
virtual bool has_legacy_unenumerable_named_properties_interface_extended_attribute() const override { return false; }
|
||||||
|
virtual bool has_global_interface_extended_attribute() const override { return false; }
|
||||||
|
virtual bool indexed_property_setter_has_identifier() const override { return false; }
|
||||||
|
virtual bool named_property_setter_has_identifier() const override { return false; }
|
||||||
|
virtual bool named_property_deleter_has_identifier() const override { return false; }
|
||||||
|
|
||||||
NonnullRefPtrVector<MediaQuery> m_media;
|
NonnullRefPtrVector<MediaQuery> m_media;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -84,7 +84,7 @@ bool StyleSheetList::is_supported_property_index(u32 index) const
|
||||||
return index < m_sheets.size();
|
return index < m_sheets.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
JS::Value StyleSheetList::item_value(size_t index) const
|
WebIDL::ExceptionOr<JS::Value> StyleSheetList::item_value(size_t index) const
|
||||||
{
|
{
|
||||||
if (index >= m_sheets.size())
|
if (index >= m_sheets.size())
|
||||||
return JS::js_undefined();
|
return JS::js_undefined();
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2020-2022, Andreas Kling <kling@serenityos.org>
|
* Copyright (c) 2020-2022, Andreas Kling <kling@serenityos.org>
|
||||||
|
* Copyright (c) 2023, Luke Wilde <lukew@serenityos.org>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
@ -33,7 +34,7 @@ public:
|
||||||
size_t length() const { return m_sheets.size(); }
|
size_t length() const { return m_sheets.size(); }
|
||||||
|
|
||||||
virtual bool is_supported_property_index(u32 index) const override;
|
virtual bool is_supported_property_index(u32 index) const override;
|
||||||
virtual JS::Value item_value(size_t index) const override;
|
virtual WebIDL::ExceptionOr<JS::Value> item_value(size_t index) const override;
|
||||||
|
|
||||||
DOM::Document& document() { return m_document; }
|
DOM::Document& document() { return m_document; }
|
||||||
DOM::Document const& document() const { return m_document; }
|
DOM::Document const& document() const { return m_document; }
|
||||||
|
@ -44,6 +45,19 @@ private:
|
||||||
virtual JS::ThrowCompletionOr<void> initialize(JS::Realm&) override;
|
virtual JS::ThrowCompletionOr<void> initialize(JS::Realm&) override;
|
||||||
virtual void visit_edges(Cell::Visitor&) override;
|
virtual void visit_edges(Cell::Visitor&) override;
|
||||||
|
|
||||||
|
// ^Bindings::LegacyPlatformObject
|
||||||
|
virtual bool supports_indexed_properties() const override { return true; }
|
||||||
|
virtual bool supports_named_properties() const override { return false; }
|
||||||
|
virtual bool has_indexed_property_setter() const override { return false; }
|
||||||
|
virtual bool has_named_property_setter() const override { return false; }
|
||||||
|
virtual bool has_named_property_deleter() const override { return false; }
|
||||||
|
virtual bool has_legacy_override_built_ins_interface_extended_attribute() const override { return false; }
|
||||||
|
virtual bool has_legacy_unenumerable_named_properties_interface_extended_attribute() const override { return false; }
|
||||||
|
virtual bool has_global_interface_extended_attribute() const override { return false; }
|
||||||
|
virtual bool indexed_property_setter_has_identifier() const override { return false; }
|
||||||
|
virtual bool named_property_setter_has_identifier() const override { return false; }
|
||||||
|
virtual bool named_property_deleter_has_identifier() const override { return false; }
|
||||||
|
|
||||||
void sort_sheets();
|
void sort_sheets();
|
||||||
|
|
||||||
DOM::Document& m_document;
|
DOM::Document& m_document;
|
||||||
|
|
|
@ -268,7 +268,7 @@ void DOMTokenList::run_update_steps()
|
||||||
MUST(associated_element->set_attribute(m_associated_attribute, value()));
|
MUST(associated_element->set_attribute(m_associated_attribute, value()));
|
||||||
}
|
}
|
||||||
|
|
||||||
JS::Value DOMTokenList::item_value(size_t index) const
|
WebIDL::ExceptionOr<JS::Value> DOMTokenList::item_value(size_t index) const
|
||||||
{
|
{
|
||||||
auto const& string = item(index);
|
auto const& string = item(index);
|
||||||
if (string.is_null())
|
if (string.is_null())
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2021, Tim Flynn <trflynn89@serenityos.org>
|
* Copyright (c) 2021, Tim Flynn <trflynn89@serenityos.org>
|
||||||
* Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
|
* Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
|
||||||
|
* Copyright (c) 2023, Luke Wilde <lukew@serenityos.org>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
@ -29,7 +30,7 @@ public:
|
||||||
void associated_attribute_changed(StringView value);
|
void associated_attribute_changed(StringView value);
|
||||||
|
|
||||||
virtual bool is_supported_property_index(u32 index) const override;
|
virtual bool is_supported_property_index(u32 index) const override;
|
||||||
virtual JS::Value item_value(size_t index) const override;
|
virtual WebIDL::ExceptionOr<JS::Value> item_value(size_t index) const override;
|
||||||
|
|
||||||
size_t length() const { return m_token_set.size(); }
|
size_t length() const { return m_token_set.size(); }
|
||||||
DeprecatedString const& item(size_t index) const;
|
DeprecatedString const& item(size_t index) const;
|
||||||
|
@ -48,6 +49,19 @@ private:
|
||||||
virtual JS::ThrowCompletionOr<void> initialize(JS::Realm&) override;
|
virtual JS::ThrowCompletionOr<void> initialize(JS::Realm&) override;
|
||||||
virtual void visit_edges(Cell::Visitor&) override;
|
virtual void visit_edges(Cell::Visitor&) override;
|
||||||
|
|
||||||
|
// ^Bindings::LegacyPlatformObject
|
||||||
|
virtual bool supports_indexed_properties() const override { return true; }
|
||||||
|
virtual bool supports_named_properties() const override { return false; }
|
||||||
|
virtual bool has_indexed_property_setter() const override { return false; }
|
||||||
|
virtual bool has_named_property_setter() const override { return false; }
|
||||||
|
virtual bool has_named_property_deleter() const override { return false; }
|
||||||
|
virtual bool has_legacy_override_built_ins_interface_extended_attribute() const override { return false; }
|
||||||
|
virtual bool has_legacy_unenumerable_named_properties_interface_extended_attribute() const override { return false; }
|
||||||
|
virtual bool has_global_interface_extended_attribute() const override { return false; }
|
||||||
|
virtual bool indexed_property_setter_has_identifier() const override { return false; }
|
||||||
|
virtual bool named_property_setter_has_identifier() const override { return false; }
|
||||||
|
virtual bool named_property_deleter_has_identifier() const override { return false; }
|
||||||
|
|
||||||
WebIDL::ExceptionOr<void> validate_token(StringView token) const;
|
WebIDL::ExceptionOr<void> validate_token(StringView token) const;
|
||||||
void run_update_steps();
|
void run_update_steps();
|
||||||
|
|
||||||
|
|
|
@ -130,7 +130,7 @@ bool HTMLCollection::is_supported_property_index(u32 index) const
|
||||||
return index < elements.size();
|
return index < elements.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
JS::Value HTMLCollection::item_value(size_t index) const
|
WebIDL::ExceptionOr<JS::Value> HTMLCollection::item_value(size_t index) const
|
||||||
{
|
{
|
||||||
auto* element = item(index);
|
auto* element = item(index);
|
||||||
if (!element)
|
if (!element)
|
||||||
|
@ -138,7 +138,7 @@ JS::Value HTMLCollection::item_value(size_t index) const
|
||||||
return const_cast<Element*>(element);
|
return const_cast<Element*>(element);
|
||||||
}
|
}
|
||||||
|
|
||||||
JS::Value HTMLCollection::named_item_value(DeprecatedFlyString const& index) const
|
WebIDL::ExceptionOr<JS::Value> HTMLCollection::named_item_value(DeprecatedFlyString const& index) const
|
||||||
{
|
{
|
||||||
auto* element = named_item(index);
|
auto* element = named_item(index);
|
||||||
if (!element)
|
if (!element)
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2021-2022, Andreas Kling <kling@serenityos.org>
|
* Copyright (c) 2021-2022, Andreas Kling <kling@serenityos.org>
|
||||||
|
* Copyright (c) 2023, Luke Wilde <lukew@serenityos.org>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
@ -39,8 +40,8 @@ public:
|
||||||
|
|
||||||
JS::MarkedVector<Element*> collect_matching_elements() const;
|
JS::MarkedVector<Element*> collect_matching_elements() const;
|
||||||
|
|
||||||
virtual JS::Value item_value(size_t index) const override;
|
virtual WebIDL::ExceptionOr<JS::Value> item_value(size_t index) const override;
|
||||||
virtual JS::Value named_item_value(DeprecatedFlyString const& name) const override;
|
virtual WebIDL::ExceptionOr<JS::Value> named_item_value(DeprecatedFlyString const& name) const override;
|
||||||
virtual Vector<DeprecatedString> supported_property_names() const override;
|
virtual Vector<DeprecatedString> supported_property_names() const override;
|
||||||
virtual bool is_supported_property_index(u32) const override;
|
virtual bool is_supported_property_index(u32) const override;
|
||||||
|
|
||||||
|
@ -54,6 +55,19 @@ protected:
|
||||||
private:
|
private:
|
||||||
virtual void visit_edges(Cell::Visitor&) override;
|
virtual void visit_edges(Cell::Visitor&) override;
|
||||||
|
|
||||||
|
// ^Bindings::LegacyPlatformObject
|
||||||
|
virtual bool supports_indexed_properties() const override { return true; }
|
||||||
|
virtual bool supports_named_properties() const override { return true; }
|
||||||
|
virtual bool has_indexed_property_setter() const override { return false; }
|
||||||
|
virtual bool has_named_property_setter() const override { return false; }
|
||||||
|
virtual bool has_named_property_deleter() const override { return false; }
|
||||||
|
virtual bool has_legacy_override_built_ins_interface_extended_attribute() const override { return false; }
|
||||||
|
virtual bool has_legacy_unenumerable_named_properties_interface_extended_attribute() const override { return true; }
|
||||||
|
virtual bool has_global_interface_extended_attribute() const override { return false; }
|
||||||
|
virtual bool indexed_property_setter_has_identifier() const override { return false; }
|
||||||
|
virtual bool named_property_setter_has_identifier() const override { return false; }
|
||||||
|
virtual bool named_property_deleter_has_identifier() const override { return false; }
|
||||||
|
|
||||||
JS::NonnullGCPtr<ParentNode> m_root;
|
JS::NonnullGCPtr<ParentNode> m_root;
|
||||||
Function<bool(Element const&)> m_filter;
|
Function<bool(Element const&)> m_filter;
|
||||||
};
|
};
|
||||||
|
|
|
@ -301,7 +301,7 @@ Attr const* NamedNodeMap::remove_attribute_ns(StringView namespace_, StringView
|
||||||
return attribute;
|
return attribute;
|
||||||
}
|
}
|
||||||
|
|
||||||
JS::Value NamedNodeMap::item_value(size_t index) const
|
WebIDL::ExceptionOr<JS::Value> NamedNodeMap::item_value(size_t index) const
|
||||||
{
|
{
|
||||||
auto const* node = item(index);
|
auto const* node = item(index);
|
||||||
if (!node)
|
if (!node)
|
||||||
|
@ -309,7 +309,7 @@ JS::Value NamedNodeMap::item_value(size_t index) const
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
JS::Value NamedNodeMap::named_item_value(DeprecatedFlyString const& name) const
|
WebIDL::ExceptionOr<JS::Value> NamedNodeMap::named_item_value(DeprecatedFlyString const& name) const
|
||||||
{
|
{
|
||||||
auto const* node = get_named_item(name);
|
auto const* node = get_named_item(name);
|
||||||
if (!node)
|
if (!node)
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
* Copyright (c) 2021, Tim Flynn <trflynn89@serenityos.org>
|
* Copyright (c) 2021, Tim Flynn <trflynn89@serenityos.org>
|
||||||
* Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
|
* Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
|
||||||
* Copyright (c) 2022, Alexander Narsudinov <a.narsudinov@gmail.com>
|
* Copyright (c) 2022, Alexander Narsudinov <a.narsudinov@gmail.com>
|
||||||
|
* Copyright (c) 2023, Luke Wilde <lukew@serenityos.org>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
@ -27,8 +28,8 @@ public:
|
||||||
|
|
||||||
virtual bool is_supported_property_index(u32 index) const override;
|
virtual bool is_supported_property_index(u32 index) const override;
|
||||||
virtual Vector<DeprecatedString> supported_property_names() const override;
|
virtual Vector<DeprecatedString> supported_property_names() const override;
|
||||||
virtual JS::Value item_value(size_t index) const override;
|
virtual WebIDL::ExceptionOr<JS::Value> item_value(size_t index) const override;
|
||||||
virtual JS::Value named_item_value(DeprecatedFlyString const& name) const override;
|
virtual WebIDL::ExceptionOr<JS::Value> named_item_value(DeprecatedFlyString const& name) const override;
|
||||||
|
|
||||||
size_t length() const { return m_attributes.size(); }
|
size_t length() const { return m_attributes.size(); }
|
||||||
bool is_empty() const { return m_attributes.is_empty(); }
|
bool is_empty() const { return m_attributes.is_empty(); }
|
||||||
|
@ -59,6 +60,19 @@ private:
|
||||||
virtual JS::ThrowCompletionOr<void> initialize(JS::Realm&) override;
|
virtual JS::ThrowCompletionOr<void> initialize(JS::Realm&) override;
|
||||||
virtual void visit_edges(Cell::Visitor&) override;
|
virtual void visit_edges(Cell::Visitor&) override;
|
||||||
|
|
||||||
|
// ^Bindings::LegacyPlatformObject
|
||||||
|
virtual bool supports_indexed_properties() const override { return true; }
|
||||||
|
virtual bool supports_named_properties() const override { return true; }
|
||||||
|
virtual bool has_indexed_property_setter() const override { return false; }
|
||||||
|
virtual bool has_named_property_setter() const override { return false; }
|
||||||
|
virtual bool has_named_property_deleter() const override { return false; }
|
||||||
|
virtual bool has_legacy_override_built_ins_interface_extended_attribute() const override { return false; }
|
||||||
|
virtual bool has_legacy_unenumerable_named_properties_interface_extended_attribute() const override { return true; }
|
||||||
|
virtual bool has_global_interface_extended_attribute() const override { return false; }
|
||||||
|
virtual bool indexed_property_setter_has_identifier() const override { return false; }
|
||||||
|
virtual bool named_property_setter_has_identifier() const override { return false; }
|
||||||
|
virtual bool named_property_deleter_has_identifier() const override { return false; }
|
||||||
|
|
||||||
Element& associated_element() { return *m_element; }
|
Element& associated_element() { return *m_element; }
|
||||||
Element const& associated_element() const { return *m_element; }
|
Element const& associated_element() const { return *m_element; }
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ JS::ThrowCompletionOr<void> NodeList::initialize(JS::Realm& realm)
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
JS::Value NodeList::item_value(size_t index) const
|
WebIDL::ExceptionOr<JS::Value> NodeList::item_value(size_t index) const
|
||||||
{
|
{
|
||||||
auto* node = item(index);
|
auto* node = item(index);
|
||||||
if (!node)
|
if (!node)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2021, Luke Wilde <lukew@serenityos.org>
|
* Copyright (c) 2021-2023, Luke Wilde <lukew@serenityos.org>
|
||||||
* Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
|
* Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
@ -21,13 +21,26 @@ public:
|
||||||
virtual u32 length() const = 0;
|
virtual u32 length() const = 0;
|
||||||
virtual Node const* item(u32 index) const = 0;
|
virtual Node const* item(u32 index) const = 0;
|
||||||
|
|
||||||
virtual JS::Value item_value(size_t index) const override;
|
virtual WebIDL::ExceptionOr<JS::Value> item_value(size_t index) const override;
|
||||||
virtual bool is_supported_property_index(u32) const override;
|
virtual bool is_supported_property_index(u32) const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit NodeList(JS::Realm&);
|
explicit NodeList(JS::Realm&);
|
||||||
|
|
||||||
virtual JS::ThrowCompletionOr<void> initialize(JS::Realm&) override;
|
virtual JS::ThrowCompletionOr<void> initialize(JS::Realm&) override;
|
||||||
|
|
||||||
|
// ^Bindings::LegacyPlatformObject
|
||||||
|
virtual bool supports_indexed_properties() const final override { return true; }
|
||||||
|
virtual bool supports_named_properties() const final override { return false; }
|
||||||
|
virtual bool has_indexed_property_setter() const final override { return false; }
|
||||||
|
virtual bool has_named_property_setter() const final override { return false; }
|
||||||
|
virtual bool has_named_property_deleter() const final override { return false; }
|
||||||
|
virtual bool has_legacy_override_built_ins_interface_extended_attribute() const final override { return false; }
|
||||||
|
virtual bool has_legacy_unenumerable_named_properties_interface_extended_attribute() const final override { return false; }
|
||||||
|
virtual bool has_global_interface_extended_attribute() const final override { return false; }
|
||||||
|
virtual bool indexed_property_setter_has_identifier() const final override { return false; }
|
||||||
|
virtual bool named_property_setter_has_identifier() const final override { return false; }
|
||||||
|
virtual bool named_property_deleter_has_identifier() const final override { return false; }
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@ bool FileList::is_supported_property_index(u32 index) const
|
||||||
return m_files.size() < index;
|
return m_files.size() < index;
|
||||||
}
|
}
|
||||||
|
|
||||||
JS::Value FileList::item_value(size_t index) const
|
WebIDL::ExceptionOr<JS::Value> FileList::item_value(size_t index) const
|
||||||
{
|
{
|
||||||
if (index >= m_files.size())
|
if (index >= m_files.size())
|
||||||
return JS::js_undefined();
|
return JS::js_undefined();
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2022, Andrew Kaster <akaster@serenityos.org>
|
* Copyright (c) 2022, Andrew Kaster <akaster@serenityos.org>
|
||||||
|
* Copyright (c) 2023, Luke Wilde <lukew@serenityos.org>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
@ -30,7 +31,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool is_supported_property_index(u32 index) const override;
|
virtual bool is_supported_property_index(u32 index) const override;
|
||||||
virtual JS::Value item_value(size_t index) const override;
|
virtual WebIDL::ExceptionOr<JS::Value> item_value(size_t index) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FileList(JS::Realm&, Vector<JS::NonnullGCPtr<File>>&&);
|
FileList(JS::Realm&, Vector<JS::NonnullGCPtr<File>>&&);
|
||||||
|
@ -38,6 +39,19 @@ private:
|
||||||
virtual JS::ThrowCompletionOr<void> initialize(JS::Realm&) override;
|
virtual JS::ThrowCompletionOr<void> initialize(JS::Realm&) override;
|
||||||
virtual void visit_edges(Cell::Visitor&) override;
|
virtual void visit_edges(Cell::Visitor&) override;
|
||||||
|
|
||||||
|
// ^Bindings::LegacyPlatformObject
|
||||||
|
virtual bool supports_indexed_properties() const override { return true; }
|
||||||
|
virtual bool supports_named_properties() const override { return false; }
|
||||||
|
virtual bool has_indexed_property_setter() const override { return false; }
|
||||||
|
virtual bool has_named_property_setter() const override { return false; }
|
||||||
|
virtual bool has_named_property_deleter() const override { return false; }
|
||||||
|
virtual bool has_legacy_override_built_ins_interface_extended_attribute() const override { return false; }
|
||||||
|
virtual bool has_legacy_unenumerable_named_properties_interface_extended_attribute() const override { return false; }
|
||||||
|
virtual bool has_global_interface_extended_attribute() const override { return false; }
|
||||||
|
virtual bool indexed_property_setter_has_identifier() const override { return false; }
|
||||||
|
virtual bool named_property_setter_has_identifier() const override { return false; }
|
||||||
|
virtual bool named_property_deleter_has_identifier() const override { return false; }
|
||||||
|
|
||||||
Vector<JS::NonnullGCPtr<File>> m_files;
|
Vector<JS::NonnullGCPtr<File>> m_files;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,7 @@ bool DOMRectList::is_supported_property_index(u32 index) const
|
||||||
return index < m_rects.size();
|
return index < m_rects.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
JS::Value DOMRectList::item_value(size_t index) const
|
WebIDL::ExceptionOr<JS::Value> DOMRectList::item_value(size_t index) const
|
||||||
{
|
{
|
||||||
if (index >= m_rects.size())
|
if (index >= m_rects.size())
|
||||||
return JS::js_undefined();
|
return JS::js_undefined();
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2022, DerpyCrabs <derpycrabs@gmail.com>
|
* Copyright (c) 2022, DerpyCrabs <derpycrabs@gmail.com>
|
||||||
|
* Copyright (c) 2023, Luke Wilde <lukew@serenityos.org>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
@ -25,13 +26,26 @@ public:
|
||||||
DOMRect const* item(u32 index) const;
|
DOMRect const* item(u32 index) const;
|
||||||
|
|
||||||
virtual bool is_supported_property_index(u32) const override;
|
virtual bool is_supported_property_index(u32) const override;
|
||||||
virtual JS::Value item_value(size_t index) const override;
|
virtual WebIDL::ExceptionOr<JS::Value> item_value(size_t index) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DOMRectList(JS::Realm&, Vector<JS::NonnullGCPtr<DOMRect>>);
|
DOMRectList(JS::Realm&, Vector<JS::NonnullGCPtr<DOMRect>>);
|
||||||
|
|
||||||
virtual JS::ThrowCompletionOr<void> initialize(JS::Realm&) override;
|
virtual JS::ThrowCompletionOr<void> initialize(JS::Realm&) override;
|
||||||
|
|
||||||
|
// ^Bindings::LegacyPlatformObject
|
||||||
|
virtual bool supports_indexed_properties() const override { return true; }
|
||||||
|
virtual bool supports_named_properties() const override { return false; }
|
||||||
|
virtual bool has_indexed_property_setter() const override { return false; }
|
||||||
|
virtual bool has_named_property_setter() const override { return false; }
|
||||||
|
virtual bool has_named_property_deleter() const override { return false; }
|
||||||
|
virtual bool has_legacy_override_built_ins_interface_extended_attribute() const override { return false; }
|
||||||
|
virtual bool has_legacy_unenumerable_named_properties_interface_extended_attribute() const override { return false; }
|
||||||
|
virtual bool has_global_interface_extended_attribute() const override { return false; }
|
||||||
|
virtual bool indexed_property_setter_has_identifier() const override { return false; }
|
||||||
|
virtual bool named_property_setter_has_identifier() const override { return false; }
|
||||||
|
virtual bool named_property_deleter_has_identifier() const override { return false; }
|
||||||
|
|
||||||
Vector<JS::NonnullGCPtr<DOMRect>> m_rects;
|
Vector<JS::NonnullGCPtr<DOMRect>> m_rects;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -119,8 +119,12 @@ DeprecatedString DOMStringMap::determine_value_of_named_property(DeprecatedStrin
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/dom.html#dom-domstringmap-setitem
|
// https://html.spec.whatwg.org/multipage/dom.html#dom-domstringmap-setitem
|
||||||
WebIDL::ExceptionOr<void> DOMStringMap::set_value_of_new_named_property(DeprecatedString const& name, DeprecatedString const& value)
|
WebIDL::ExceptionOr<void> DOMStringMap::set_value_of_new_named_property(DeprecatedString const& name, JS::Value unconverted_value)
|
||||||
{
|
{
|
||||||
|
// NOTE: Since LegacyPlatformObject does not know the type of value, we must convert it ourselves.
|
||||||
|
// The type of `value` is `DOMString`.
|
||||||
|
auto value = TRY(unconverted_value.to_deprecated_string(vm()));
|
||||||
|
|
||||||
AK::StringBuilder builder;
|
AK::StringBuilder builder;
|
||||||
|
|
||||||
// 3. Insert the string data- at the front of name.
|
// 3. Insert the string data- at the front of name.
|
||||||
|
@ -158,13 +162,13 @@ WebIDL::ExceptionOr<void> DOMStringMap::set_value_of_new_named_property(Deprecat
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/dom.html#dom-domstringmap-setitem
|
// https://html.spec.whatwg.org/multipage/dom.html#dom-domstringmap-setitem
|
||||||
WebIDL::ExceptionOr<void> DOMStringMap::set_value_of_existing_named_property(DeprecatedString const& name, DeprecatedString const& value)
|
WebIDL::ExceptionOr<void> DOMStringMap::set_value_of_existing_named_property(DeprecatedString const& name, JS::Value value)
|
||||||
{
|
{
|
||||||
return set_value_of_new_named_property(name, value);
|
return set_value_of_new_named_property(name, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/dom.html#dom-domstringmap-removeitem
|
// https://html.spec.whatwg.org/multipage/dom.html#dom-domstringmap-removeitem
|
||||||
bool DOMStringMap::delete_existing_named_property(DeprecatedString const& name)
|
WebIDL::ExceptionOr<Bindings::LegacyPlatformObject::DidDeletionFail> DOMStringMap::delete_value(DeprecatedString const& name)
|
||||||
{
|
{
|
||||||
AK::StringBuilder builder;
|
AK::StringBuilder builder;
|
||||||
|
|
||||||
|
@ -188,10 +192,10 @@ bool DOMStringMap::delete_existing_named_property(DeprecatedString const& name)
|
||||||
m_associated_element->remove_attribute(data_name);
|
m_associated_element->remove_attribute(data_name);
|
||||||
|
|
||||||
// The spec doesn't have the step. This indicates that the deletion was successful.
|
// The spec doesn't have the step. This indicates that the deletion was successful.
|
||||||
return true;
|
return DidDeletionFail::No;
|
||||||
}
|
}
|
||||||
|
|
||||||
JS::Value DOMStringMap::named_item_value(DeprecatedFlyString const& name) const
|
WebIDL::ExceptionOr<JS::Value> DOMStringMap::named_item_value(DeprecatedFlyString const& name) const
|
||||||
{
|
{
|
||||||
return JS::PrimitiveString::create(vm(), determine_value_of_named_property(name));
|
return JS::PrimitiveString::create(vm(), determine_value_of_named_property(name));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2021, Luke Wilde <lukew@serenityos.org>
|
* Copyright (c) 2021-2023, Luke Wilde <lukew@serenityos.org>
|
||||||
* Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
|
* Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
@ -23,10 +23,10 @@ public:
|
||||||
|
|
||||||
DeprecatedString determine_value_of_named_property(DeprecatedString const&) const;
|
DeprecatedString determine_value_of_named_property(DeprecatedString const&) const;
|
||||||
|
|
||||||
WebIDL::ExceptionOr<void> set_value_of_new_named_property(DeprecatedString const&, DeprecatedString const&);
|
virtual WebIDL::ExceptionOr<void> set_value_of_new_named_property(DeprecatedString const&, JS::Value) override;
|
||||||
WebIDL::ExceptionOr<void> set_value_of_existing_named_property(DeprecatedString const&, DeprecatedString const&);
|
virtual WebIDL::ExceptionOr<void> set_value_of_existing_named_property(DeprecatedString const&, JS::Value) override;
|
||||||
|
|
||||||
bool delete_existing_named_property(DeprecatedString const&);
|
virtual WebIDL::ExceptionOr<DidDeletionFail> delete_value(DeprecatedString const&) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit DOMStringMap(DOM::Element&);
|
explicit DOMStringMap(DOM::Element&);
|
||||||
|
@ -35,9 +35,21 @@ private:
|
||||||
virtual void visit_edges(Cell::Visitor&) override;
|
virtual void visit_edges(Cell::Visitor&) override;
|
||||||
|
|
||||||
// ^LegacyPlatformObject
|
// ^LegacyPlatformObject
|
||||||
virtual JS::Value named_item_value(DeprecatedFlyString const&) const override;
|
virtual WebIDL::ExceptionOr<JS::Value> named_item_value(DeprecatedFlyString const&) const override;
|
||||||
virtual Vector<DeprecatedString> supported_property_names() const override;
|
virtual Vector<DeprecatedString> supported_property_names() const override;
|
||||||
|
|
||||||
|
virtual bool supports_indexed_properties() const override { return false; }
|
||||||
|
virtual bool supports_named_properties() const override { return true; }
|
||||||
|
virtual bool has_indexed_property_setter() const override { return false; }
|
||||||
|
virtual bool has_named_property_setter() const override { return true; }
|
||||||
|
virtual bool has_named_property_deleter() const override { return true; }
|
||||||
|
virtual bool has_legacy_override_built_ins_interface_extended_attribute() const override { return true; }
|
||||||
|
virtual bool has_legacy_unenumerable_named_properties_interface_extended_attribute() const override { return false; }
|
||||||
|
virtual bool has_global_interface_extended_attribute() const override { return false; }
|
||||||
|
virtual bool indexed_property_setter_has_identifier() const override { return false; }
|
||||||
|
virtual bool named_property_setter_has_identifier() const override { return false; }
|
||||||
|
virtual bool named_property_deleter_has_identifier() const override { return false; }
|
||||||
|
|
||||||
struct NameValuePair {
|
struct NameValuePair {
|
||||||
DeprecatedString name;
|
DeprecatedString name;
|
||||||
DeprecatedString value;
|
DeprecatedString value;
|
||||||
|
|
|
@ -113,7 +113,8 @@ JS_DEFINE_NATIVE_FUNCTION(ConsoleGlobalEnvironmentExtensions::$$_function)
|
||||||
|
|
||||||
auto array = TRY(JS::Array::create(*vm.current_realm(), node_list->length()));
|
auto array = TRY(JS::Array::create(*vm.current_realm(), node_list->length()));
|
||||||
for (auto i = 0u; i < node_list->length(); ++i) {
|
for (auto i = 0u; i < node_list->length(); ++i) {
|
||||||
TRY(array->create_data_property_or_throw(i, node_list->item_value(i)));
|
// NOTE: NodeList::item_value cannot fail.
|
||||||
|
TRY(array->create_data_property_or_throw(i, MUST(node_list->item_value(i))));
|
||||||
}
|
}
|
||||||
|
|
||||||
return array;
|
return array;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue