mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-07-29 20:29:18 +00:00
LibWeb: Wire up UniversalGlobalScopeMixin to ShadowRealmGlobalScope
This commit is contained in:
parent
2ea31fad32
commit
457cdd0cc3
Notes:
github-actions[bot]
2024-11-09 19:37:09 +00:00
Author: https://github.com/shannonbooth
Commit: 457cdd0cc3
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/2220
Reviewed-by: https://github.com/ADKaster ✅
19 changed files with 216 additions and 110 deletions
1
Tests/LibWeb/Text/expected/HTML/shadow-realm-btoa.txt
Normal file
1
Tests/LibWeb/Text/expected/HTML/shadow-realm-btoa.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Shadow realm evaluation returned: SGVsbG8sIHdvcmxkIQ==
|
1
Tests/LibWeb/Text/expected/HTML/shadow-realm-url.txt
Normal file
1
Tests/LibWeb/Text/expected/HTML/shadow-realm-url.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Shadow realm evaluation returned: example.com
|
8
Tests/LibWeb/Text/input/HTML/shadow-realm-btoa.html
Normal file
8
Tests/LibWeb/Text/input/HTML/shadow-realm-btoa.html
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
<script src="../include.js"></script>
|
||||||
|
<script>
|
||||||
|
test(() => {
|
||||||
|
const realm = new ShadowRealm();
|
||||||
|
const result = realm.evaluate(`() => self.btoa('Hello, world!')`)();
|
||||||
|
println(`Shadow realm evaluation returned: ${result}`);
|
||||||
|
});
|
||||||
|
</script>
|
8
Tests/LibWeb/Text/input/HTML/shadow-realm-url.html
Normal file
8
Tests/LibWeb/Text/input/HTML/shadow-realm-url.html
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
<script src="../include.js"></script>
|
||||||
|
<script>
|
||||||
|
test(() => {
|
||||||
|
const realm = new ShadowRealm();
|
||||||
|
const result = realm.evaluate(`() => new URL('https://example.com/path?name=value').hostname`)();
|
||||||
|
println(`Shadow realm evaluation returned: ${result}`);
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -483,6 +483,7 @@ set(SOURCES
|
||||||
HTML/TokenizedFeatures.cpp
|
HTML/TokenizedFeatures.cpp
|
||||||
HTML/TrackEvent.cpp
|
HTML/TrackEvent.cpp
|
||||||
HTML/TraversableNavigable.cpp
|
HTML/TraversableNavigable.cpp
|
||||||
|
HTML/UniversalGlobalScope.cpp
|
||||||
HTML/UserActivation.cpp
|
HTML/UserActivation.cpp
|
||||||
HTML/VideoTrack.cpp
|
HTML/VideoTrack.cpp
|
||||||
HTML/VideoTrackList.cpp
|
HTML/VideoTrackList.cpp
|
||||||
|
|
|
@ -26,14 +26,16 @@ JS::NonnullGCPtr<ShadowRealmGlobalScope> ShadowRealmGlobalScope::create(JS::Real
|
||||||
|
|
||||||
void ShadowRealmGlobalScope::initialize(JS::Realm&)
|
void ShadowRealmGlobalScope::initialize(JS::Realm&)
|
||||||
{
|
{
|
||||||
// FIXME: This does not work as we do not have any intrinsics in the [HostDefined] of a shadow realm. Figure out how this _should_ work.
|
|
||||||
// Base::initialize(realm);
|
|
||||||
// WEB_SET_PROTOTYPE_FOR_INTERFACE(ShadowRealmGlobalScope);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShadowRealmGlobalScope::initialize_web_interfaces()
|
void ShadowRealmGlobalScope::initialize_web_interfaces()
|
||||||
{
|
{
|
||||||
|
auto& realm = this->realm();
|
||||||
|
|
||||||
|
WEB_SET_PROTOTYPE_FOR_INTERFACE(ShadowRealmGlobalScope);
|
||||||
|
|
||||||
add_shadow_realm_exposed_interfaces(*this);
|
add_shadow_realm_exposed_interfaces(*this);
|
||||||
|
Bindings::ShadowRealmGlobalScopeGlobalMixin::initialize(realm, *this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShadowRealmGlobalScope::visit_edges(Cell::Visitor& visitor)
|
void ShadowRealmGlobalScope::visit_edges(Cell::Visitor& visitor)
|
||||||
|
|
|
@ -7,12 +7,17 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <LibWeb/Bindings/Intrinsics.h>
|
#include <LibWeb/Bindings/Intrinsics.h>
|
||||||
|
#include <LibWeb/Bindings/ShadowRealmGlobalScopeGlobalMixin.h>
|
||||||
#include <LibWeb/DOM/EventTarget.h>
|
#include <LibWeb/DOM/EventTarget.h>
|
||||||
|
#include <LibWeb/HTML/UniversalGlobalScope.h>
|
||||||
|
|
||||||
namespace Web::HTML {
|
namespace Web::HTML {
|
||||||
|
|
||||||
// https://whatpr.org/html/9893/webappapis.html#shadowrealmglobalscope
|
// https://whatpr.org/html/9893/webappapis.html#shadowrealmglobalscope
|
||||||
class ShadowRealmGlobalScope : public DOM::EventTarget {
|
class ShadowRealmGlobalScope
|
||||||
|
: public DOM::EventTarget
|
||||||
|
, public UniversalGlobalScopeMixin
|
||||||
|
, public Bindings::ShadowRealmGlobalScopeGlobalMixin {
|
||||||
WEB_PLATFORM_OBJECT(ShadowRealmGlobalScope, DOM::EventTarget);
|
WEB_PLATFORM_OBJECT(ShadowRealmGlobalScope, DOM::EventTarget);
|
||||||
JS_DECLARE_ALLOCATOR(ShadowRealmGlobalScope);
|
JS_DECLARE_ALLOCATOR(ShadowRealmGlobalScope);
|
||||||
|
|
||||||
|
@ -21,6 +26,9 @@ public:
|
||||||
|
|
||||||
static JS::NonnullGCPtr<ShadowRealmGlobalScope> create(JS::Realm&);
|
static JS::NonnullGCPtr<ShadowRealmGlobalScope> create(JS::Realm&);
|
||||||
|
|
||||||
|
virtual Bindings::PlatformObject& this_impl() override { return *this; }
|
||||||
|
virtual Bindings::PlatformObject const& this_impl() const override { return *this; }
|
||||||
|
|
||||||
// https://whatpr.org/html/9893/webappapis.html#dom-shadowrealmglobalscope-self
|
// https://whatpr.org/html/9893/webappapis.html#dom-shadowrealmglobalscope-self
|
||||||
JS::NonnullGCPtr<ShadowRealmGlobalScope> self()
|
JS::NonnullGCPtr<ShadowRealmGlobalScope> self()
|
||||||
{
|
{
|
||||||
|
@ -28,6 +36,11 @@ public:
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using UniversalGlobalScopeMixin::atob;
|
||||||
|
using UniversalGlobalScopeMixin::btoa;
|
||||||
|
using UniversalGlobalScopeMixin::queue_microtask;
|
||||||
|
using UniversalGlobalScopeMixin::structured_clone;
|
||||||
|
|
||||||
void initialize_web_interfaces();
|
void initialize_web_interfaces();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
|
#import <HTML/UniversalGlobalScope.idl>
|
||||||
|
|
||||||
// https://whatpr.org/html/9893/webappapis.html#shadowrealmglobalscope
|
// https://whatpr.org/html/9893/webappapis.html#shadowrealmglobalscope
|
||||||
[Global, Exposed=ShadowRealm]
|
[Global, Exposed=ShadowRealm]
|
||||||
interface ShadowRealmGlobalScope : EventTarget {
|
interface ShadowRealmGlobalScope : EventTarget {
|
||||||
readonly attribute ShadowRealmGlobalScope self;
|
readonly attribute ShadowRealmGlobalScope self;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ShadowRealmGlobalScope includes UniversalGlobalScope;
|
||||||
|
|
104
Userland/Libraries/LibWeb/HTML/UniversalGlobalScope.cpp
Normal file
104
Userland/Libraries/LibWeb/HTML/UniversalGlobalScope.cpp
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022, Andrew Kaster <akaster@serenityos.org>
|
||||||
|
* Copyright (c) 2023, Linus Groh <linusg@serenityos.org>
|
||||||
|
* Copyright (c) 2023, Luke Wilde <lukew@serenityos.org>
|
||||||
|
* Copyright (c) 2024, Shannon Booth <shannon@serenityos.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <AK/Base64.h>
|
||||||
|
#include <AK/String.h>
|
||||||
|
#include <AK/Utf8View.h>
|
||||||
|
#include <AK/Vector.h>
|
||||||
|
#include <LibJS/Heap/HeapFunction.h>
|
||||||
|
#include <LibWeb/HTML/Scripting/ExceptionReporter.h>
|
||||||
|
#include <LibWeb/HTML/StructuredSerialize.h>
|
||||||
|
#include <LibWeb/HTML/StructuredSerializeOptions.h>
|
||||||
|
#include <LibWeb/HTML/UniversalGlobalScope.h>
|
||||||
|
#include <LibWeb/HTML/Window.h>
|
||||||
|
#include <LibWeb/Infra/Strings.h>
|
||||||
|
#include <LibWeb/WebIDL/AbstractOperations.h>
|
||||||
|
#include <LibWeb/WebIDL/DOMException.h>
|
||||||
|
#include <LibWeb/WebIDL/ExceptionOr.h>
|
||||||
|
#include <LibWeb/WebIDL/Types.h>
|
||||||
|
|
||||||
|
namespace Web::HTML {
|
||||||
|
|
||||||
|
UniversalGlobalScopeMixin::~UniversalGlobalScopeMixin() = default;
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/webappapis.html#dom-btoa
|
||||||
|
WebIDL::ExceptionOr<String> UniversalGlobalScopeMixin::btoa(String const& data) const
|
||||||
|
{
|
||||||
|
auto& vm = this_impl().vm();
|
||||||
|
auto& realm = *vm.current_realm();
|
||||||
|
|
||||||
|
// The btoa(data) method must throw an "InvalidCharacterError" DOMException if data contains any character whose code point is greater than U+00FF.
|
||||||
|
Vector<u8> byte_string;
|
||||||
|
byte_string.ensure_capacity(data.bytes().size());
|
||||||
|
for (u32 code_point : Utf8View(data)) {
|
||||||
|
if (code_point > 0xff)
|
||||||
|
return WebIDL::InvalidCharacterError::create(realm, "Data contains characters outside the range U+0000 and U+00FF"_string);
|
||||||
|
byte_string.append(code_point);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, the user agent must convert data to a byte sequence whose nth byte is the eight-bit representation of the nth code point of data,
|
||||||
|
// and then must apply forgiving-base64 encode to that byte sequence and return the result.
|
||||||
|
return TRY_OR_THROW_OOM(vm, encode_base64(byte_string.span()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/webappapis.html#dom-atob
|
||||||
|
WebIDL::ExceptionOr<String> UniversalGlobalScopeMixin::atob(String const& data) const
|
||||||
|
{
|
||||||
|
auto& vm = this_impl().vm();
|
||||||
|
auto& realm = *vm.current_realm();
|
||||||
|
|
||||||
|
// 1. Let decodedData be the result of running forgiving-base64 decode on data.
|
||||||
|
auto decoded_data = decode_base64(data);
|
||||||
|
|
||||||
|
// 2. If decodedData is failure, then throw an "InvalidCharacterError" DOMException.
|
||||||
|
if (decoded_data.is_error())
|
||||||
|
return WebIDL::InvalidCharacterError::create(realm, "Input string is not valid base64 data"_string);
|
||||||
|
|
||||||
|
// 3. Return decodedData.
|
||||||
|
// decode_base64() returns a byte buffer. LibJS uses UTF-8 for strings. Use isomorphic decoding to convert bytes to UTF-8.
|
||||||
|
return Infra::isomorphic_decode(decoded_data.value());
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#dom-queuemicrotask
|
||||||
|
void UniversalGlobalScopeMixin::queue_microtask(WebIDL::CallbackType& callback)
|
||||||
|
{
|
||||||
|
auto& vm = this_impl().vm();
|
||||||
|
auto& realm = *vm.current_realm();
|
||||||
|
|
||||||
|
JS::GCPtr<DOM::Document> document;
|
||||||
|
if (is<Window>(this_impl()))
|
||||||
|
document = &static_cast<Window&>(this_impl()).associated_document();
|
||||||
|
|
||||||
|
// The queueMicrotask(callback) method must queue a microtask to invoke callback, and if callback throws an exception, report the exception.
|
||||||
|
HTML::queue_a_microtask(document, JS::create_heap_function(realm.heap(), [&callback, &realm] {
|
||||||
|
auto result = WebIDL::invoke_callback(callback, {});
|
||||||
|
if (result.is_error())
|
||||||
|
HTML::report_exception(result, realm);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/structured-data.html#dom-structuredclone
|
||||||
|
WebIDL::ExceptionOr<JS::Value> UniversalGlobalScopeMixin::structured_clone(JS::Value value, StructuredSerializeOptions const& options) const
|
||||||
|
{
|
||||||
|
auto& vm = this_impl().vm();
|
||||||
|
(void)options;
|
||||||
|
|
||||||
|
// 1. Let serialized be ? StructuredSerializeWithTransfer(value, options["transfer"]).
|
||||||
|
// FIXME: Use WithTransfer variant of the AO
|
||||||
|
auto serialized = TRY(structured_serialize(vm, value));
|
||||||
|
|
||||||
|
// 2. Let deserializeRecord be ? StructuredDeserializeWithTransfer(serialized, this's relevant realm).
|
||||||
|
// FIXME: Use WithTransfer variant of the AO
|
||||||
|
auto deserialized = TRY(structured_deserialize(vm, serialized, relevant_realm(this_impl()), {}));
|
||||||
|
|
||||||
|
// 3. Return deserializeRecord.[[Deserialized]].
|
||||||
|
return deserialized;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
33
Userland/Libraries/LibWeb/HTML/UniversalGlobalScope.h
Normal file
33
Userland/Libraries/LibWeb/HTML/UniversalGlobalScope.h
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023, Linus Groh <linusg@serenityos.org>
|
||||||
|
* Copyright (c) 2023, Luke Wilde <lukew@serenityos.org>
|
||||||
|
* Copyright (c) 2024, Shannon Booth <shannon@serenityos.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <AK/Forward.h>
|
||||||
|
#include <AK/String.h>
|
||||||
|
#include <LibJS/Runtime/Value.h>
|
||||||
|
#include <LibWeb/Forward.h>
|
||||||
|
#include <LibWeb/WebIDL/ExceptionOr.h>
|
||||||
|
|
||||||
|
namespace Web::HTML {
|
||||||
|
|
||||||
|
// https://whatpr.org/html/9893/webappapis.html#universalglobalscope-mixin
|
||||||
|
class UniversalGlobalScopeMixin {
|
||||||
|
public:
|
||||||
|
virtual ~UniversalGlobalScopeMixin();
|
||||||
|
|
||||||
|
virtual Bindings::PlatformObject& this_impl() = 0;
|
||||||
|
virtual Bindings::PlatformObject const& this_impl() const = 0;
|
||||||
|
|
||||||
|
WebIDL::ExceptionOr<String> btoa(String const& data) const;
|
||||||
|
WebIDL::ExceptionOr<String> atob(String const& data) const;
|
||||||
|
void queue_microtask(WebIDL::CallbackType&);
|
||||||
|
WebIDL::ExceptionOr<JS::Value> structured_clone(JS::Value, StructuredSerializeOptions const&) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
17
Userland/Libraries/LibWeb/HTML/UniversalGlobalScope.idl
Normal file
17
Userland/Libraries/LibWeb/HTML/UniversalGlobalScope.idl
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
#import <HTML/MessagePort.idl>
|
||||||
|
|
||||||
|
// FIXME: Support VoidFunction in the IDL parser
|
||||||
|
callback VoidFunction = undefined ();
|
||||||
|
|
||||||
|
// https://whatpr.org/html/9893/webappapis.html#universalglobalscope-mixin
|
||||||
|
interface mixin UniversalGlobalScope {
|
||||||
|
// base64 utility methods
|
||||||
|
DOMString btoa(DOMString data);
|
||||||
|
ByteString atob(DOMString data);
|
||||||
|
|
||||||
|
// microtask queuing
|
||||||
|
undefined queueMicrotask(VoidFunction callback);
|
||||||
|
|
||||||
|
// structured cloning
|
||||||
|
any structuredClone(any value, optional StructuredSerializeOptions options = {});
|
||||||
|
};
|
|
@ -24,6 +24,7 @@
|
||||||
#include <LibWeb/HTML/Scripting/ImportMap.h>
|
#include <LibWeb/HTML/Scripting/ImportMap.h>
|
||||||
#include <LibWeb/HTML/ScrollOptions.h>
|
#include <LibWeb/HTML/ScrollOptions.h>
|
||||||
#include <LibWeb/HTML/StructuredSerializeOptions.h>
|
#include <LibWeb/HTML/StructuredSerializeOptions.h>
|
||||||
|
#include <LibWeb/HTML/UniversalGlobalScope.h>
|
||||||
#include <LibWeb/HTML/WindowEventHandlers.h>
|
#include <LibWeb/HTML/WindowEventHandlers.h>
|
||||||
#include <LibWeb/HTML/WindowOrWorkerGlobalScope.h>
|
#include <LibWeb/HTML/WindowOrWorkerGlobalScope.h>
|
||||||
#include <LibWeb/RequestIdleCallback/IdleRequest.h>
|
#include <LibWeb/RequestIdleCallback/IdleRequest.h>
|
||||||
|
@ -49,6 +50,7 @@ class Window final
|
||||||
, public GlobalEventHandlers
|
, public GlobalEventHandlers
|
||||||
, public WindowEventHandlers
|
, public WindowEventHandlers
|
||||||
, public WindowOrWorkerGlobalScopeMixin
|
, public WindowOrWorkerGlobalScopeMixin
|
||||||
|
, public UniversalGlobalScopeMixin
|
||||||
, public Bindings::WindowGlobalMixin {
|
, public Bindings::WindowGlobalMixin {
|
||||||
WEB_PLATFORM_OBJECT(Window, DOM::EventTarget);
|
WEB_PLATFORM_OBJECT(Window, DOM::EventTarget);
|
||||||
JS_DECLARE_ALLOCATOR(Window);
|
JS_DECLARE_ALLOCATOR(Window);
|
||||||
|
@ -58,17 +60,17 @@ public:
|
||||||
|
|
||||||
~Window();
|
~Window();
|
||||||
|
|
||||||
using WindowOrWorkerGlobalScopeMixin::atob;
|
using UniversalGlobalScopeMixin::atob;
|
||||||
using WindowOrWorkerGlobalScopeMixin::btoa;
|
using UniversalGlobalScopeMixin::btoa;
|
||||||
|
using UniversalGlobalScopeMixin::queue_microtask;
|
||||||
|
using UniversalGlobalScopeMixin::structured_clone;
|
||||||
using WindowOrWorkerGlobalScopeMixin::clear_interval;
|
using WindowOrWorkerGlobalScopeMixin::clear_interval;
|
||||||
using WindowOrWorkerGlobalScopeMixin::clear_timeout;
|
using WindowOrWorkerGlobalScopeMixin::clear_timeout;
|
||||||
using WindowOrWorkerGlobalScopeMixin::create_image_bitmap;
|
using WindowOrWorkerGlobalScopeMixin::create_image_bitmap;
|
||||||
using WindowOrWorkerGlobalScopeMixin::fetch;
|
using WindowOrWorkerGlobalScopeMixin::fetch;
|
||||||
using WindowOrWorkerGlobalScopeMixin::queue_microtask;
|
|
||||||
using WindowOrWorkerGlobalScopeMixin::report_error;
|
using WindowOrWorkerGlobalScopeMixin::report_error;
|
||||||
using WindowOrWorkerGlobalScopeMixin::set_interval;
|
using WindowOrWorkerGlobalScopeMixin::set_interval;
|
||||||
using WindowOrWorkerGlobalScopeMixin::set_timeout;
|
using WindowOrWorkerGlobalScopeMixin::set_timeout;
|
||||||
using WindowOrWorkerGlobalScopeMixin::structured_clone;
|
|
||||||
|
|
||||||
// ^DOM::EventTarget
|
// ^DOM::EventTarget
|
||||||
virtual bool dispatch_event(DOM::Event&) override;
|
virtual bool dispatch_event(DOM::Event&) override;
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#import <HTML/History.idl>
|
#import <HTML/History.idl>
|
||||||
#import <HTML/Navigation.idl>
|
#import <HTML/Navigation.idl>
|
||||||
#import <HTML/Navigator.idl>
|
#import <HTML/Navigator.idl>
|
||||||
|
#import <HTML/UniversalGlobalScope.idl>
|
||||||
#import <HTML/WindowLocalStorage.idl>
|
#import <HTML/WindowLocalStorage.idl>
|
||||||
#import <HTML/WindowOrWorkerGlobalScope.idl>
|
#import <HTML/WindowOrWorkerGlobalScope.idl>
|
||||||
#import <HTML/WindowSessionStorage.idl>
|
#import <HTML/WindowSessionStorage.idl>
|
||||||
|
@ -115,6 +116,7 @@ interface Window : EventTarget {
|
||||||
};
|
};
|
||||||
Window includes AnimationFrameProvider;
|
Window includes AnimationFrameProvider;
|
||||||
Window includes GlobalEventHandlers;
|
Window includes GlobalEventHandlers;
|
||||||
|
Window includes UniversalGlobalScope;
|
||||||
Window includes WindowEventHandlers;
|
Window includes WindowEventHandlers;
|
||||||
Window includes WindowLocalStorage;
|
Window includes WindowLocalStorage;
|
||||||
Window includes WindowSessionStorage;
|
Window includes WindowSessionStorage;
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <AK/Base64.h>
|
|
||||||
#include <AK/QuickSort.h>
|
#include <AK/QuickSort.h>
|
||||||
#include <AK/String.h>
|
#include <AK/String.h>
|
||||||
#include <AK/Utf8View.h>
|
#include <AK/Utf8View.h>
|
||||||
|
@ -27,8 +26,6 @@
|
||||||
#include <LibWeb/HTML/Scripting/ExceptionReporter.h>
|
#include <LibWeb/HTML/Scripting/ExceptionReporter.h>
|
||||||
#include <LibWeb/HTML/Scripting/Fetching.h>
|
#include <LibWeb/HTML/Scripting/Fetching.h>
|
||||||
#include <LibWeb/HTML/Scripting/TemporaryExecutionContext.h>
|
#include <LibWeb/HTML/Scripting/TemporaryExecutionContext.h>
|
||||||
#include <LibWeb/HTML/StructuredSerialize.h>
|
|
||||||
#include <LibWeb/HTML/StructuredSerializeOptions.h>
|
|
||||||
#include <LibWeb/HTML/Timer.h>
|
#include <LibWeb/HTML/Timer.h>
|
||||||
#include <LibWeb/HTML/Window.h>
|
#include <LibWeb/HTML/Window.h>
|
||||||
#include <LibWeb/HTML/WindowOrWorkerGlobalScope.h>
|
#include <LibWeb/HTML/WindowOrWorkerGlobalScope.h>
|
||||||
|
@ -108,62 +105,6 @@ bool WindowOrWorkerGlobalScopeMixin::cross_origin_isolated() const
|
||||||
return relevant_settings_object(this_impl()).cross_origin_isolated_capability() == CanUseCrossOriginIsolatedAPIs::Yes;
|
return relevant_settings_object(this_impl()).cross_origin_isolated_capability() == CanUseCrossOriginIsolatedAPIs::Yes;
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/webappapis.html#dom-btoa
|
|
||||||
WebIDL::ExceptionOr<String> WindowOrWorkerGlobalScopeMixin::btoa(String const& data) const
|
|
||||||
{
|
|
||||||
auto& vm = this_impl().vm();
|
|
||||||
auto& realm = *vm.current_realm();
|
|
||||||
|
|
||||||
// The btoa(data) method must throw an "InvalidCharacterError" DOMException if data contains any character whose code point is greater than U+00FF.
|
|
||||||
Vector<u8> byte_string;
|
|
||||||
byte_string.ensure_capacity(data.bytes().size());
|
|
||||||
for (u32 code_point : Utf8View(data)) {
|
|
||||||
if (code_point > 0xff)
|
|
||||||
return WebIDL::InvalidCharacterError::create(realm, "Data contains characters outside the range U+0000 and U+00FF"_string);
|
|
||||||
byte_string.append(code_point);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise, the user agent must convert data to a byte sequence whose nth byte is the eight-bit representation of the nth code point of data,
|
|
||||||
// and then must apply forgiving-base64 encode to that byte sequence and return the result.
|
|
||||||
return TRY_OR_THROW_OOM(vm, encode_base64(byte_string.span()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/webappapis.html#dom-atob
|
|
||||||
WebIDL::ExceptionOr<String> WindowOrWorkerGlobalScopeMixin::atob(String const& data) const
|
|
||||||
{
|
|
||||||
auto& vm = this_impl().vm();
|
|
||||||
auto& realm = *vm.current_realm();
|
|
||||||
|
|
||||||
// 1. Let decodedData be the result of running forgiving-base64 decode on data.
|
|
||||||
auto decoded_data = decode_base64(data);
|
|
||||||
|
|
||||||
// 2. If decodedData is failure, then throw an "InvalidCharacterError" DOMException.
|
|
||||||
if (decoded_data.is_error())
|
|
||||||
return WebIDL::InvalidCharacterError::create(realm, "Input string is not valid base64 data"_string);
|
|
||||||
|
|
||||||
// 3. Return decodedData.
|
|
||||||
// decode_base64() returns a byte buffer. LibJS uses UTF-8 for strings. Use isomorphic decoding to convert bytes to UTF-8.
|
|
||||||
return Infra::isomorphic_decode(decoded_data.value());
|
|
||||||
}
|
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#dom-queuemicrotask
|
|
||||||
void WindowOrWorkerGlobalScopeMixin::queue_microtask(WebIDL::CallbackType& callback)
|
|
||||||
{
|
|
||||||
auto& vm = this_impl().vm();
|
|
||||||
auto& realm = *vm.current_realm();
|
|
||||||
|
|
||||||
JS::GCPtr<DOM::Document> document;
|
|
||||||
if (is<Window>(this_impl()))
|
|
||||||
document = &static_cast<Window&>(this_impl()).associated_document();
|
|
||||||
|
|
||||||
// The queueMicrotask(callback) method must queue a microtask to invoke callback, and if callback throws an exception, report the exception.
|
|
||||||
HTML::queue_a_microtask(document, JS::create_heap_function(realm.heap(), [&callback, &realm] {
|
|
||||||
auto result = WebIDL::invoke_callback(callback, {});
|
|
||||||
if (result.is_error())
|
|
||||||
HTML::report_exception(result, realm);
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/imagebitmap-and-animations.html#dom-createimagebitmap
|
// https://html.spec.whatwg.org/multipage/imagebitmap-and-animations.html#dom-createimagebitmap
|
||||||
JS::NonnullGCPtr<WebIDL::Promise> WindowOrWorkerGlobalScopeMixin::create_image_bitmap(ImageBitmapSource image, Optional<ImageBitmapOptions> options) const
|
JS::NonnullGCPtr<WebIDL::Promise> WindowOrWorkerGlobalScopeMixin::create_image_bitmap(ImageBitmapSource image, Optional<ImageBitmapOptions> options) const
|
||||||
{
|
{
|
||||||
|
@ -261,24 +202,6 @@ JS::NonnullGCPtr<WebIDL::Promise> WindowOrWorkerGlobalScopeMixin::create_image_b
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/structured-data.html#dom-structuredclone
|
|
||||||
WebIDL::ExceptionOr<JS::Value> WindowOrWorkerGlobalScopeMixin::structured_clone(JS::Value value, StructuredSerializeOptions const& options) const
|
|
||||||
{
|
|
||||||
auto& vm = this_impl().vm();
|
|
||||||
(void)options;
|
|
||||||
|
|
||||||
// 1. Let serialized be ? StructuredSerializeWithTransfer(value, options["transfer"]).
|
|
||||||
// FIXME: Use WithTransfer variant of the AO
|
|
||||||
auto serialized = TRY(structured_serialize(vm, value));
|
|
||||||
|
|
||||||
// 2. Let deserializeRecord be ? StructuredDeserializeWithTransfer(serialized, this's relevant realm).
|
|
||||||
// FIXME: Use WithTransfer variant of the AO
|
|
||||||
auto deserialized = TRY(structured_deserialize(vm, serialized, relevant_realm(this_impl()), {}));
|
|
||||||
|
|
||||||
// 3. Return deserializeRecord.[[Deserialized]].
|
|
||||||
return deserialized;
|
|
||||||
}
|
|
||||||
|
|
||||||
JS::NonnullGCPtr<WebIDL::Promise> WindowOrWorkerGlobalScopeMixin::fetch(Fetch::RequestInfo const& input, Fetch::RequestInit const& init) const
|
JS::NonnullGCPtr<WebIDL::Promise> WindowOrWorkerGlobalScopeMixin::fetch(Fetch::RequestInfo const& input, Fetch::RequestInit const& init) const
|
||||||
{
|
{
|
||||||
auto& vm = this_impl().vm();
|
auto& vm = this_impl().vm();
|
||||||
|
|
|
@ -36,12 +36,8 @@ public:
|
||||||
WebIDL::ExceptionOr<String> origin() const;
|
WebIDL::ExceptionOr<String> origin() const;
|
||||||
bool is_secure_context() const;
|
bool is_secure_context() const;
|
||||||
bool cross_origin_isolated() const;
|
bool cross_origin_isolated() const;
|
||||||
WebIDL::ExceptionOr<String> btoa(String const& data) const;
|
|
||||||
WebIDL::ExceptionOr<String> atob(String const& data) const;
|
|
||||||
void queue_microtask(WebIDL::CallbackType&);
|
|
||||||
JS::NonnullGCPtr<WebIDL::Promise> create_image_bitmap(ImageBitmapSource image, Optional<ImageBitmapOptions> options = {}) const;
|
JS::NonnullGCPtr<WebIDL::Promise> create_image_bitmap(ImageBitmapSource image, Optional<ImageBitmapOptions> options = {}) const;
|
||||||
JS::NonnullGCPtr<WebIDL::Promise> create_image_bitmap(ImageBitmapSource image, WebIDL::Long sx, WebIDL::Long sy, WebIDL::Long sw, WebIDL::Long sh, Optional<ImageBitmapOptions> options = {}) const;
|
JS::NonnullGCPtr<WebIDL::Promise> create_image_bitmap(ImageBitmapSource image, WebIDL::Long sx, WebIDL::Long sy, WebIDL::Long sw, WebIDL::Long sh, Optional<ImageBitmapOptions> options = {}) const;
|
||||||
WebIDL::ExceptionOr<JS::Value> structured_clone(JS::Value, StructuredSerializeOptions const&) const;
|
|
||||||
JS::NonnullGCPtr<WebIDL::Promise> fetch(Fetch::RequestInfo const&, Fetch::RequestInit const&) const;
|
JS::NonnullGCPtr<WebIDL::Promise> fetch(Fetch::RequestInfo const&, Fetch::RequestInit const&) const;
|
||||||
|
|
||||||
i32 set_timeout(TimerHandler, i32 timeout, JS::MarkedVector<JS::Value> arguments);
|
i32 set_timeout(TimerHandler, i32 timeout, JS::MarkedVector<JS::Value> arguments);
|
||||||
|
|
|
@ -6,9 +6,6 @@
|
||||||
#import <HTML/MessagePort.idl>
|
#import <HTML/MessagePort.idl>
|
||||||
#import <IndexedDB/IDBFactory.idl>
|
#import <IndexedDB/IDBFactory.idl>
|
||||||
|
|
||||||
// FIXME: Support VoidFunction in the IDL parser
|
|
||||||
callback VoidFunction = undefined ();
|
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/#timerhandler
|
// https://html.spec.whatwg.org/#timerhandler
|
||||||
typedef (DOMString or Function) TimerHandler;
|
typedef (DOMString or Function) TimerHandler;
|
||||||
|
|
||||||
|
@ -21,26 +18,16 @@ interface mixin WindowOrWorkerGlobalScope {
|
||||||
// https://html.spec.whatwg.org/multipage/webappapis.html#dom-reporterror
|
// https://html.spec.whatwg.org/multipage/webappapis.html#dom-reporterror
|
||||||
undefined reportError(any e);
|
undefined reportError(any e);
|
||||||
|
|
||||||
// base64 utility methods
|
|
||||||
DOMString btoa(DOMString data);
|
|
||||||
ByteString atob(DOMString data);
|
|
||||||
|
|
||||||
// timers
|
// timers
|
||||||
long setTimeout(TimerHandler handler, optional long timeout = 0, any... arguments);
|
long setTimeout(TimerHandler handler, optional long timeout = 0, any... arguments);
|
||||||
undefined clearTimeout(optional long id = 0);
|
undefined clearTimeout(optional long id = 0);
|
||||||
long setInterval(TimerHandler handler, optional long timeout = 0, any... arguments);
|
long setInterval(TimerHandler handler, optional long timeout = 0, any... arguments);
|
||||||
undefined clearInterval(optional long id = 0);
|
undefined clearInterval(optional long id = 0);
|
||||||
|
|
||||||
// microtask queuing
|
|
||||||
undefined queueMicrotask(VoidFunction callback);
|
|
||||||
|
|
||||||
// ImageBitmap
|
// ImageBitmap
|
||||||
Promise<ImageBitmap> createImageBitmap(ImageBitmapSource image, optional ImageBitmapOptions options = {});
|
Promise<ImageBitmap> createImageBitmap(ImageBitmapSource image, optional ImageBitmapOptions options = {});
|
||||||
Promise<ImageBitmap> createImageBitmap(ImageBitmapSource image, long sx, long sy, long sw, long sh, optional ImageBitmapOptions options = {});
|
Promise<ImageBitmap> createImageBitmap(ImageBitmapSource image, long sx, long sy, long sw, long sh, optional ImageBitmapOptions options = {});
|
||||||
|
|
||||||
// structured cloning
|
|
||||||
any structuredClone(any value, optional StructuredSerializeOptions options = {});
|
|
||||||
|
|
||||||
// https://fetch.spec.whatwg.org/#fetch-method
|
// https://fetch.spec.whatwg.org/#fetch-method
|
||||||
[NewObject] Promise<Response> fetch(RequestInfo input, optional RequestInit init = {});
|
[NewObject] Promise<Response> fetch(RequestInfo input, optional RequestInit init = {});
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include <LibWeb/DOM/EventTarget.h>
|
#include <LibWeb/DOM/EventTarget.h>
|
||||||
#include <LibWeb/Forward.h>
|
#include <LibWeb/Forward.h>
|
||||||
#include <LibWeb/HTML/Scripting/Fetching.h>
|
#include <LibWeb/HTML/Scripting/Fetching.h>
|
||||||
|
#include <LibWeb/HTML/UniversalGlobalScope.h>
|
||||||
#include <LibWeb/HTML/WindowOrWorkerGlobalScope.h>
|
#include <LibWeb/HTML/WindowOrWorkerGlobalScope.h>
|
||||||
#include <LibWeb/HTML/WorkerLocation.h>
|
#include <LibWeb/HTML/WorkerLocation.h>
|
||||||
#include <LibWeb/HTML/WorkerNavigator.h>
|
#include <LibWeb/HTML/WorkerNavigator.h>
|
||||||
|
@ -33,7 +34,8 @@ namespace Web::HTML {
|
||||||
// user agent runs the run a worker algorithm.
|
// user agent runs the run a worker algorithm.
|
||||||
class WorkerGlobalScope
|
class WorkerGlobalScope
|
||||||
: public DOM::EventTarget
|
: public DOM::EventTarget
|
||||||
, public WindowOrWorkerGlobalScopeMixin {
|
, public WindowOrWorkerGlobalScopeMixin
|
||||||
|
, public UniversalGlobalScopeMixin {
|
||||||
WEB_PLATFORM_OBJECT(WorkerGlobalScope, DOM::EventTarget);
|
WEB_PLATFORM_OBJECT(WorkerGlobalScope, DOM::EventTarget);
|
||||||
JS_DECLARE_ALLOCATOR(WorkerGlobalScope);
|
JS_DECLARE_ALLOCATOR(WorkerGlobalScope);
|
||||||
|
|
||||||
|
@ -44,17 +46,17 @@ public:
|
||||||
virtual Bindings::PlatformObject& this_impl() override { return *this; }
|
virtual Bindings::PlatformObject& this_impl() override { return *this; }
|
||||||
virtual Bindings::PlatformObject const& this_impl() const override { return *this; }
|
virtual Bindings::PlatformObject const& this_impl() const override { return *this; }
|
||||||
|
|
||||||
using WindowOrWorkerGlobalScopeMixin::atob;
|
using UniversalGlobalScopeMixin::atob;
|
||||||
using WindowOrWorkerGlobalScopeMixin::btoa;
|
using UniversalGlobalScopeMixin::btoa;
|
||||||
|
using UniversalGlobalScopeMixin::queue_microtask;
|
||||||
|
using UniversalGlobalScopeMixin::structured_clone;
|
||||||
using WindowOrWorkerGlobalScopeMixin::clear_interval;
|
using WindowOrWorkerGlobalScopeMixin::clear_interval;
|
||||||
using WindowOrWorkerGlobalScopeMixin::clear_timeout;
|
using WindowOrWorkerGlobalScopeMixin::clear_timeout;
|
||||||
using WindowOrWorkerGlobalScopeMixin::create_image_bitmap;
|
using WindowOrWorkerGlobalScopeMixin::create_image_bitmap;
|
||||||
using WindowOrWorkerGlobalScopeMixin::fetch;
|
using WindowOrWorkerGlobalScopeMixin::fetch;
|
||||||
using WindowOrWorkerGlobalScopeMixin::performance;
|
using WindowOrWorkerGlobalScopeMixin::performance;
|
||||||
using WindowOrWorkerGlobalScopeMixin::queue_microtask;
|
|
||||||
using WindowOrWorkerGlobalScopeMixin::set_interval;
|
using WindowOrWorkerGlobalScopeMixin::set_interval;
|
||||||
using WindowOrWorkerGlobalScopeMixin::set_timeout;
|
using WindowOrWorkerGlobalScopeMixin::set_timeout;
|
||||||
using WindowOrWorkerGlobalScopeMixin::structured_clone;
|
|
||||||
|
|
||||||
// Following methods are from the WorkerGlobalScope IDL definition
|
// Following methods are from the WorkerGlobalScope IDL definition
|
||||||
// https://html.spec.whatwg.org/multipage/workers.html#the-workerglobalscope-common-interface
|
// https://html.spec.whatwg.org/multipage/workers.html#the-workerglobalscope-common-interface
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
#import <CSS/FontFaceSet.idl>
|
#import <CSS/FontFaceSet.idl>
|
||||||
#import <DOM/EventTarget.idl>
|
#import <DOM/EventTarget.idl>
|
||||||
#import <DOM/EventHandler.idl>
|
#import <DOM/EventHandler.idl>
|
||||||
|
#import <HTML/MessagePort.idl>
|
||||||
|
#import <HTML/UniversalGlobalScope.idl>
|
||||||
#import <HTML/WindowOrWorkerGlobalScope.idl>
|
#import <HTML/WindowOrWorkerGlobalScope.idl>
|
||||||
#import <HTML/WorkerLocation.idl>
|
#import <HTML/WorkerLocation.idl>
|
||||||
#import <HTML/WorkerNavigator.idl>
|
#import <HTML/WorkerNavigator.idl>
|
||||||
#import <HTML/MessagePort.idl>
|
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/workers.html#workerglobalscope
|
// https://html.spec.whatwg.org/multipage/workers.html#workerglobalscope
|
||||||
[Exposed=Worker]
|
[Exposed=Worker]
|
||||||
|
@ -22,5 +23,6 @@ interface WorkerGlobalScope : EventTarget {
|
||||||
attribute EventHandler onunhandledrejection;
|
attribute EventHandler onunhandledrejection;
|
||||||
};
|
};
|
||||||
|
|
||||||
WorkerGlobalScope includes WindowOrWorkerGlobalScope;
|
|
||||||
WorkerGlobalScope includes FontFaceSource;
|
WorkerGlobalScope includes FontFaceSource;
|
||||||
|
WorkerGlobalScope includes UniversalGlobalScope;
|
||||||
|
WorkerGlobalScope includes WindowOrWorkerGlobalScope;
|
||||||
|
|
|
@ -222,7 +222,7 @@ libweb_js_bindings(HTML/RadioNodeList)
|
||||||
libweb_js_bindings(HTML/ServiceWorker)
|
libweb_js_bindings(HTML/ServiceWorker)
|
||||||
libweb_js_bindings(HTML/ServiceWorkerContainer)
|
libweb_js_bindings(HTML/ServiceWorkerContainer)
|
||||||
libweb_js_bindings(HTML/ServiceWorkerRegistration)
|
libweb_js_bindings(HTML/ServiceWorkerRegistration)
|
||||||
libweb_js_bindings(HTML/ShadowRealmGlobalScope)
|
libweb_js_bindings(HTML/ShadowRealmGlobalScope GLOBAL)
|
||||||
libweb_js_bindings(HTML/Storage)
|
libweb_js_bindings(HTML/Storage)
|
||||||
libweb_js_bindings(HTML/SubmitEvent)
|
libweb_js_bindings(HTML/SubmitEvent)
|
||||||
libweb_js_bindings(HTML/TextMetrics)
|
libweb_js_bindings(HTML/TextMetrics)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue