mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-21 23:20:20 +00:00
LibWeb: Allow using queuing strategies on globals other than Window
These interfaces are exposed on *, meaning it should work for workers and our newly added shadow realm global object by being stored on the universal global scope mixin.
This commit is contained in:
parent
13f349aea2
commit
d527c5df5d
Notes:
github-actions[bot]
2024-11-21 01:10:37 +00:00
Author: https://github.com/shannonbooth Commit: https://github.com/LadybirdBrowser/ladybird/commit/d527c5df5d3 Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/2416 Reviewed-by: https://github.com/ADKaster ✅
10 changed files with 89 additions and 61 deletions
|
@ -41,6 +41,7 @@ void ShadowRealmGlobalScope::initialize_web_interfaces()
|
||||||
void ShadowRealmGlobalScope::visit_edges(Cell::Visitor& visitor)
|
void ShadowRealmGlobalScope::visit_edges(Cell::Visitor& visitor)
|
||||||
{
|
{
|
||||||
Base::visit_edges(visitor);
|
Base::visit_edges(visitor);
|
||||||
|
UniversalGlobalScopeMixin::visit_edges(visitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include <AK/Utf8View.h>
|
#include <AK/Utf8View.h>
|
||||||
#include <AK/Vector.h>
|
#include <AK/Vector.h>
|
||||||
#include <LibGC/Function.h>
|
#include <LibGC/Function.h>
|
||||||
|
#include <LibJS/Runtime/NativeFunction.h>
|
||||||
#include <LibWeb/HTML/Scripting/ExceptionReporter.h>
|
#include <LibWeb/HTML/Scripting/ExceptionReporter.h>
|
||||||
#include <LibWeb/HTML/StructuredSerialize.h>
|
#include <LibWeb/HTML/StructuredSerialize.h>
|
||||||
#include <LibWeb/HTML/StructuredSerializeOptions.h>
|
#include <LibWeb/HTML/StructuredSerializeOptions.h>
|
||||||
|
@ -27,6 +28,12 @@ namespace Web::HTML {
|
||||||
|
|
||||||
UniversalGlobalScopeMixin::~UniversalGlobalScopeMixin() = default;
|
UniversalGlobalScopeMixin::~UniversalGlobalScopeMixin() = default;
|
||||||
|
|
||||||
|
void UniversalGlobalScopeMixin::visit_edges(GC::Cell::Visitor& visitor)
|
||||||
|
{
|
||||||
|
visitor.visit(m_count_queuing_strategy_size_function);
|
||||||
|
visitor.visit(m_byte_length_queuing_strategy_size_function);
|
||||||
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/webappapis.html#dom-btoa
|
// https://html.spec.whatwg.org/multipage/webappapis.html#dom-btoa
|
||||||
WebIDL::ExceptionOr<String> UniversalGlobalScopeMixin::btoa(String const& data) const
|
WebIDL::ExceptionOr<String> UniversalGlobalScopeMixin::btoa(String const& data) const
|
||||||
{
|
{
|
||||||
|
@ -101,4 +108,50 @@ WebIDL::ExceptionOr<JS::Value> UniversalGlobalScopeMixin::structured_clone(JS::V
|
||||||
return deserialized;
|
return deserialized;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://streams.spec.whatwg.org/#count-queuing-strategy-size-function
|
||||||
|
GC::Ref<WebIDL::CallbackType> UniversalGlobalScopeMixin::count_queuing_strategy_size_function()
|
||||||
|
{
|
||||||
|
auto& realm = HTML::relevant_realm(this_impl());
|
||||||
|
|
||||||
|
if (!m_count_queuing_strategy_size_function) {
|
||||||
|
// 1. Let steps be the following steps:
|
||||||
|
auto steps = [](auto const&) {
|
||||||
|
// 1. Return 1.
|
||||||
|
return 1.0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 2. Let F be ! CreateBuiltinFunction(steps, 0, "size", « », globalObject’s relevant Realm).
|
||||||
|
auto function = JS::NativeFunction::create(realm, move(steps), 0, "size", &realm);
|
||||||
|
|
||||||
|
// 3. Set globalObject’s count queuing strategy size function to a Function that represents a reference to F, with callback context equal to globalObject’s relevant settings object.
|
||||||
|
m_count_queuing_strategy_size_function = realm.create<WebIDL::CallbackType>(*function, relevant_settings_object(this_impl()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return GC::Ref { *m_count_queuing_strategy_size_function };
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://streams.spec.whatwg.org/#byte-length-queuing-strategy-size-function
|
||||||
|
GC::Ref<WebIDL::CallbackType> UniversalGlobalScopeMixin::byte_length_queuing_strategy_size_function()
|
||||||
|
{
|
||||||
|
auto& realm = HTML::relevant_realm(this_impl());
|
||||||
|
|
||||||
|
if (!m_byte_length_queuing_strategy_size_function) {
|
||||||
|
// 1. Let steps be the following steps, given chunk:
|
||||||
|
auto steps = [](JS::VM& vm) {
|
||||||
|
auto chunk = vm.argument(0);
|
||||||
|
|
||||||
|
// 1. Return ? GetV(chunk, "byteLength").
|
||||||
|
return chunk.get(vm, vm.names.byteLength);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 2. Let F be ! CreateBuiltinFunction(steps, 1, "size", « », globalObject’s relevant Realm).
|
||||||
|
auto function = JS::NativeFunction::create(realm, move(steps), 1, "size", &realm);
|
||||||
|
|
||||||
|
// 3. Set globalObject’s byte length queuing strategy size function to a Function that represents a reference to F, with callback context equal to globalObject’s relevant settings object.
|
||||||
|
m_byte_length_queuing_strategy_size_function = realm.create<WebIDL::CallbackType>(*function, relevant_settings_object(this_impl()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return GC::Ref { *m_byte_length_queuing_strategy_size_function };
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,19 @@ public:
|
||||||
WebIDL::ExceptionOr<String> atob(String const& data) const;
|
WebIDL::ExceptionOr<String> atob(String const& data) const;
|
||||||
void queue_microtask(WebIDL::CallbackType&);
|
void queue_microtask(WebIDL::CallbackType&);
|
||||||
WebIDL::ExceptionOr<JS::Value> structured_clone(JS::Value, StructuredSerializeOptions const&) const;
|
WebIDL::ExceptionOr<JS::Value> structured_clone(JS::Value, StructuredSerializeOptions const&) const;
|
||||||
|
|
||||||
|
GC::Ref<WebIDL::CallbackType> count_queuing_strategy_size_function();
|
||||||
|
GC::Ref<WebIDL::CallbackType> byte_length_queuing_strategy_size_function();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void visit_edges(GC::Cell::Visitor&);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// https://streams.spec.whatwg.org/#count-queuing-strategy-size-function
|
||||||
|
GC::Ptr<WebIDL::CallbackType> m_count_queuing_strategy_size_function;
|
||||||
|
|
||||||
|
// https://streams.spec.whatwg.org/#byte-length-queuing-strategy-size-function
|
||||||
|
GC::Ptr<WebIDL::CallbackType> m_byte_length_queuing_strategy_size_function;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,6 +116,7 @@ void Window::visit_edges(JS::Cell::Visitor& visitor)
|
||||||
{
|
{
|
||||||
Base::visit_edges(visitor);
|
Base::visit_edges(visitor);
|
||||||
WindowOrWorkerGlobalScopeMixin::visit_edges(visitor);
|
WindowOrWorkerGlobalScopeMixin::visit_edges(visitor);
|
||||||
|
UniversalGlobalScopeMixin::visit_edges(visitor);
|
||||||
|
|
||||||
visitor.visit(m_associated_document);
|
visitor.visit(m_associated_document);
|
||||||
visitor.visit(m_current_event);
|
visitor.visit(m_current_event);
|
||||||
|
@ -127,8 +128,6 @@ void Window::visit_edges(JS::Cell::Visitor& visitor)
|
||||||
visitor.visit(m_animation_frame_callback_driver);
|
visitor.visit(m_animation_frame_callback_driver);
|
||||||
visitor.visit(m_pdf_viewer_plugin_objects);
|
visitor.visit(m_pdf_viewer_plugin_objects);
|
||||||
visitor.visit(m_pdf_viewer_mime_type_objects);
|
visitor.visit(m_pdf_viewer_mime_type_objects);
|
||||||
visitor.visit(m_count_queuing_strategy_size_function);
|
|
||||||
visitor.visit(m_byte_length_queuing_strategy_size_function);
|
|
||||||
visitor.visit(m_close_watcher_manager);
|
visitor.visit(m_close_watcher_manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -662,52 +661,6 @@ Vector<GC::Ref<MimeType>> Window::pdf_viewer_mime_type_objects()
|
||||||
return m_pdf_viewer_mime_type_objects;
|
return m_pdf_viewer_mime_type_objects;
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://streams.spec.whatwg.org/#count-queuing-strategy-size-function
|
|
||||||
GC::Ref<WebIDL::CallbackType> Window::count_queuing_strategy_size_function()
|
|
||||||
{
|
|
||||||
auto& realm = this->realm();
|
|
||||||
|
|
||||||
if (!m_count_queuing_strategy_size_function) {
|
|
||||||
// 1. Let steps be the following steps:
|
|
||||||
auto steps = [](auto const&) {
|
|
||||||
// 1. Return 1.
|
|
||||||
return 1.0;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 2. Let F be ! CreateBuiltinFunction(steps, 0, "size", « », globalObject’s relevant Realm).
|
|
||||||
auto function = JS::NativeFunction::create(realm, move(steps), 0, "size", &realm);
|
|
||||||
|
|
||||||
// 3. Set globalObject’s count queuing strategy size function to a Function that represents a reference to F, with callback context equal to globalObject’s relevant settings object.
|
|
||||||
m_count_queuing_strategy_size_function = realm.create<WebIDL::CallbackType>(*function, relevant_settings_object(*this));
|
|
||||||
}
|
|
||||||
|
|
||||||
return GC::Ref { *m_count_queuing_strategy_size_function };
|
|
||||||
}
|
|
||||||
|
|
||||||
// https://streams.spec.whatwg.org/#byte-length-queuing-strategy-size-function
|
|
||||||
GC::Ref<WebIDL::CallbackType> Window::byte_length_queuing_strategy_size_function()
|
|
||||||
{
|
|
||||||
auto& realm = this->realm();
|
|
||||||
|
|
||||||
if (!m_byte_length_queuing_strategy_size_function) {
|
|
||||||
// 1. Let steps be the following steps, given chunk:
|
|
||||||
auto steps = [](JS::VM& vm) {
|
|
||||||
auto chunk = vm.argument(0);
|
|
||||||
|
|
||||||
// 1. Return ? GetV(chunk, "byteLength").
|
|
||||||
return chunk.get(vm, vm.names.byteLength);
|
|
||||||
};
|
|
||||||
|
|
||||||
// 2. Let F be ! CreateBuiltinFunction(steps, 1, "size", « », globalObject’s relevant Realm).
|
|
||||||
auto function = JS::NativeFunction::create(realm, move(steps), 1, "size", &realm);
|
|
||||||
|
|
||||||
// 3. Set globalObject’s byte length queuing strategy size function to a Function that represents a reference to F, with callback context equal to globalObject’s relevant settings object.
|
|
||||||
m_byte_length_queuing_strategy_size_function = realm.create<WebIDL::CallbackType>(*function, relevant_settings_object(*this));
|
|
||||||
}
|
|
||||||
|
|
||||||
return GC::Ref { *m_byte_length_queuing_strategy_size_function };
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool s_inspector_object_exposed = false;
|
static bool s_inspector_object_exposed = false;
|
||||||
static bool s_internals_object_exposed = false;
|
static bool s_internals_object_exposed = false;
|
||||||
|
|
||||||
|
|
|
@ -141,9 +141,6 @@ public:
|
||||||
CrossOriginPropertyDescriptorMap const& cross_origin_property_descriptor_map() const { return m_cross_origin_property_descriptor_map; }
|
CrossOriginPropertyDescriptorMap const& cross_origin_property_descriptor_map() const { return m_cross_origin_property_descriptor_map; }
|
||||||
CrossOriginPropertyDescriptorMap& cross_origin_property_descriptor_map() { return m_cross_origin_property_descriptor_map; }
|
CrossOriginPropertyDescriptorMap& cross_origin_property_descriptor_map() { return m_cross_origin_property_descriptor_map; }
|
||||||
|
|
||||||
GC::Ref<WebIDL::CallbackType> count_queuing_strategy_size_function();
|
|
||||||
GC::Ref<WebIDL::CallbackType> byte_length_queuing_strategy_size_function();
|
|
||||||
|
|
||||||
// JS API functions
|
// JS API functions
|
||||||
GC::Ref<WindowProxy> window() const;
|
GC::Ref<WindowProxy> window() const;
|
||||||
GC::Ref<WindowProxy> self() const;
|
GC::Ref<WindowProxy> self() const;
|
||||||
|
@ -313,12 +310,6 @@ private:
|
||||||
// https://html.spec.whatwg.org/multipage/interaction.html#last-history-action-activation-timestamp
|
// https://html.spec.whatwg.org/multipage/interaction.html#last-history-action-activation-timestamp
|
||||||
HighResolutionTime::DOMHighResTimeStamp m_last_history_action_activation_timestamp { AK::Infinity<double> };
|
HighResolutionTime::DOMHighResTimeStamp m_last_history_action_activation_timestamp { AK::Infinity<double> };
|
||||||
|
|
||||||
// https://streams.spec.whatwg.org/#count-queuing-strategy-size-function
|
|
||||||
GC::Ptr<WebIDL::CallbackType> m_count_queuing_strategy_size_function;
|
|
||||||
|
|
||||||
// https://streams.spec.whatwg.org/#byte-length-queuing-strategy-size-function
|
|
||||||
GC::Ptr<WebIDL::CallbackType> m_byte_length_queuing_strategy_size_function;
|
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/nav-history-apis.html#dom-window-status
|
// https://html.spec.whatwg.org/multipage/nav-history-apis.html#dom-window-status
|
||||||
// When the Window object is created, the attribute must be set to the empty string. It does not do anything else.
|
// When the Window object is created, the attribute must be set to the empty string. It does not do anything else.
|
||||||
String m_status;
|
String m_status;
|
||||||
|
|
|
@ -45,6 +45,7 @@ void WorkerGlobalScope::visit_edges(Cell::Visitor& visitor)
|
||||||
{
|
{
|
||||||
Base::visit_edges(visitor);
|
Base::visit_edges(visitor);
|
||||||
WindowOrWorkerGlobalScopeMixin::visit_edges(visitor);
|
WindowOrWorkerGlobalScopeMixin::visit_edges(visitor);
|
||||||
|
UniversalGlobalScopeMixin::visit_edges(visitor);
|
||||||
|
|
||||||
visitor.visit(m_location);
|
visitor.visit(m_location);
|
||||||
visitor.visit(m_navigator);
|
visitor.visit(m_navigator);
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
#include <LibWeb/Bindings/ByteLengthQueuingStrategyPrototype.h>
|
#include <LibWeb/Bindings/ByteLengthQueuingStrategyPrototype.h>
|
||||||
#include <LibWeb/Bindings/Intrinsics.h>
|
#include <LibWeb/Bindings/Intrinsics.h>
|
||||||
#include <LibWeb/HTML/Window.h>
|
#include <LibWeb/HTML/UniversalGlobalScope.h>
|
||||||
#include <LibWeb/Streams/ByteLengthQueuingStrategy.h>
|
#include <LibWeb/Streams/ByteLengthQueuingStrategy.h>
|
||||||
|
|
||||||
namespace Web::Streams {
|
namespace Web::Streams {
|
||||||
|
@ -34,7 +34,9 @@ ByteLengthQueuingStrategy::~ByteLengthQueuingStrategy() = default;
|
||||||
GC::Ref<WebIDL::CallbackType> ByteLengthQueuingStrategy::size()
|
GC::Ref<WebIDL::CallbackType> ByteLengthQueuingStrategy::size()
|
||||||
{
|
{
|
||||||
// 1. Return this's relevant global object's byte length queuing strategy size function.
|
// 1. Return this's relevant global object's byte length queuing strategy size function.
|
||||||
return verify_cast<HTML::Window>(HTML::relevant_global_object(*this)).byte_length_queuing_strategy_size_function();
|
auto* global = dynamic_cast<HTML::UniversalGlobalScopeMixin*>(&HTML::relevant_global_object(*this));
|
||||||
|
VERIFY(global);
|
||||||
|
return global->byte_length_queuing_strategy_size_function();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ByteLengthQueuingStrategy::initialize(JS::Realm& realm)
|
void ByteLengthQueuingStrategy::initialize(JS::Realm& realm)
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
#include <LibWeb/Bindings/CountQueuingStrategyPrototype.h>
|
#include <LibWeb/Bindings/CountQueuingStrategyPrototype.h>
|
||||||
#include <LibWeb/Bindings/Intrinsics.h>
|
#include <LibWeb/Bindings/Intrinsics.h>
|
||||||
#include <LibWeb/HTML/Window.h>
|
#include <LibWeb/HTML/UniversalGlobalScope.h>
|
||||||
#include <LibWeb/Streams/CountQueuingStrategy.h>
|
#include <LibWeb/Streams/CountQueuingStrategy.h>
|
||||||
|
|
||||||
namespace Web::Streams {
|
namespace Web::Streams {
|
||||||
|
@ -34,7 +34,9 @@ CountQueuingStrategy::~CountQueuingStrategy() = default;
|
||||||
GC::Ref<WebIDL::CallbackType> CountQueuingStrategy::size()
|
GC::Ref<WebIDL::CallbackType> CountQueuingStrategy::size()
|
||||||
{
|
{
|
||||||
// 1. Return this's relevant global object's count queuing strategy size function.
|
// 1. Return this's relevant global object's count queuing strategy size function.
|
||||||
return verify_cast<HTML::Window>(HTML::relevant_global_object(*this)).count_queuing_strategy_size_function();
|
auto* global = dynamic_cast<HTML::UniversalGlobalScopeMixin*>(&HTML::relevant_global_object(*this));
|
||||||
|
VERIFY(global);
|
||||||
|
return global->count_queuing_strategy_size_function();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CountQueuingStrategy::initialize(JS::Realm& realm)
|
void CountQueuingStrategy::initialize(JS::Realm& realm)
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
CountQueuingStrategy | size1 === size2 -> true
|
||||||
|
ByteLengthQueuingStrategy | size1 === size2 -> true
|
|
@ -0,0 +1,10 @@
|
||||||
|
<script src="../include.js"></script>
|
||||||
|
<script>
|
||||||
|
test(() => {
|
||||||
|
for (const QueuingStrategy of [CountQueuingStrategy, ByteLengthQueuingStrategy]) {
|
||||||
|
const size1 = (new QueuingStrategy({ highWaterMark: 5 })).size;
|
||||||
|
const size2 = (new QueuingStrategy({ highWaterMark: 10 })).size;
|
||||||
|
println(`${QueuingStrategy.name} | size1 === size2 -> ${size1 === size2}`);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
Loading…
Reference in a new issue