1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 18:28:12 +00:00

LibWeb: Implement ModuleMap and expose it on EnvironmentSettingsObject

This patch adds the ModuleMap class used to keep track of the type and
url of a module as well as the fetching state associated. Each
environment settings object now also has a module map.
This commit is contained in:
networkException 2022-10-03 20:58:36 +02:00 committed by Andreas Kling
parent 83554526f0
commit 992311c0ee
5 changed files with 143 additions and 1 deletions

View file

@ -258,6 +258,7 @@ set(SOURCES
HTML/Scripting/ClassicScript.cpp
HTML/Scripting/Environments.cpp
HTML/Scripting/ExceptionReporter.cpp
HTML/Scripting/ModuleMap.cpp
HTML/Scripting/Script.cpp
HTML/Scripting/WindowEnvironmentSettingsObject.cpp
HTML/Storage.cpp

View file

@ -11,6 +11,7 @@
#include <LibWeb/HTML/PromiseRejectionEvent.h>
#include <LibWeb/HTML/Scripting/Environments.h>
#include <LibWeb/HTML/Scripting/ExceptionReporter.h>
#include <LibWeb/HTML/Scripting/WindowEnvironmentSettingsObject.h>
#include <LibWeb/HTML/Window.h>
#include <LibWeb/Page/Page.h>
@ -34,6 +35,11 @@ JS::ExecutionContext& EnvironmentSettingsObject::realm_execution_context()
return *m_realm_execution_context;
}
ModuleMap& EnvironmentSettingsObject::module_map()
{
return m_module_map;
}
// https://html.spec.whatwg.org/multipage/webappapis.html#environment-settings-object%27s-realm
JS::Realm& EnvironmentSettingsObject::realm()
{

View file

@ -14,6 +14,7 @@
#include <LibJS/Runtime/Realm.h>
#include <LibWeb/HTML/EventLoop/EventLoop.h>
#include <LibWeb/HTML/Origin.h>
#include <LibWeb/HTML/Scripting/ModuleMap.h>
namespace Web::HTML {
@ -61,7 +62,8 @@ struct EnvironmentSettingsObject
// https://html.spec.whatwg.org/multipage/webappapis.html#concept-environment-target-browsing-context
JS::ExecutionContext& realm_execution_context();
// FIXME: A module map https://html.spec.whatwg.org/multipage/webappapis.html#concept-settings-object-module-map
// https://html.spec.whatwg.org/multipage/webappapis.html#concept-settings-object-module-map
ModuleMap& module_map();
// https://html.spec.whatwg.org/multipage/webappapis.html#responsible-document
virtual JS::GCPtr<DOM::Document> responsible_document() = 0;
@ -113,6 +115,8 @@ protected:
private:
NonnullOwnPtr<JS::ExecutionContext> m_realm_execution_context;
ModuleMap m_module_map;
EventLoop* m_responsible_event_loop { nullptr };
// https://html.spec.whatwg.org/multipage/webappapis.html#outstanding-rejected-promises-weak-set

View file

@ -0,0 +1,50 @@
/*
* Copyright (c) 2022, networkException <networkexception@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibWeb/HTML/Scripting/ModuleMap.h>
namespace Web::HTML {
bool ModuleMap::is_fetching(AK::URL const& url, String const& type) const
{
return is(url, type, EntryType::Fetching);
}
bool ModuleMap::is_failed(AK::URL const& url, String const& type) const
{
return is(url, type, EntryType::Failed);
}
bool ModuleMap::is(AK::URL const& url, String const& type, EntryType entry_type) const
{
auto value = m_values.get({ url, type });
if (!value.has_value())
return false;
return value->type == entry_type;
}
Optional<ModuleMap::Entry> ModuleMap::get(AK::URL const& url, String const& type) const
{
return m_values.get({ url, type });
}
AK::HashSetResult ModuleMap::set(AK::URL const& url, String const& type, Entry entry)
{
auto callbacks = m_callbacks.get({ url, type });
if (callbacks.has_value())
for (auto const& callback : *callbacks)
callback(entry);
return m_values.set({ url, type }, entry);
}
void ModuleMap::wait_for_change(AK::URL const& url, String const& type, Function<void(Entry)> callback)
{
m_callbacks.ensure({ url, type }).append(move(callback));
}
}

View file

@ -0,0 +1,81 @@
/*
* Copyright (c) 2022, networkException <networkexception@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <LibWeb/HTML/Scripting/ModuleScript.h>
namespace Web::HTML {
class ModuleLocationTuple {
public:
ModuleLocationTuple(AK::URL url, String type)
: m_url(move(url))
, m_type(move(type))
{
}
AK::URL const& url() const { return m_url; };
String const& type() const { return m_type; }
bool operator==(ModuleLocationTuple const& other) const
{
return other.url() == m_url && other.type() == m_type;
};
private:
AK::URL m_url;
String m_type;
};
// https://html.spec.whatwg.org/multipage/webappapis.html#module-map
class ModuleMap {
AK_MAKE_NONCOPYABLE(ModuleMap);
public:
ModuleMap() = default;
~ModuleMap() = default;
enum class EntryType {
Fetching,
Failed,
ModuleScript
};
struct Entry {
EntryType type;
JavaScriptModuleScript* module_script;
};
bool is_fetching(AK::URL const& url, String const& type) const;
bool is_failed(AK::URL const& url, String const& type) const;
bool is(AK::URL const& url, String const& type, EntryType) const;
Optional<Entry> get(AK::URL const& url, String const& type) const;
AK::HashSetResult set(AK::URL const& url, String const& type, Entry);
void wait_for_change(AK::URL const& url, String const& type, Function<void(Entry)> callback);
private:
HashMap<ModuleLocationTuple, Entry> m_values;
HashMap<ModuleLocationTuple, Vector<Function<void(Entry)>>> m_callbacks;
};
}
namespace AK {
template<>
struct Traits<Web::HTML::ModuleLocationTuple> : public GenericTraits<Web::HTML::ModuleLocationTuple> {
static unsigned hash(Web::HTML::ModuleLocationTuple const& tuple)
{
return pair_int_hash(tuple.url().to_string().hash(), tuple.type().hash());
}
};
}