summaryrefslogtreecommitdiff
path: root/Userland/Libraries
diff options
context:
space:
mode:
authornetworkException <git@nwex.de>2022-10-03 20:58:36 +0200
committerAndreas Kling <kling@serenityos.org>2022-10-06 16:41:36 +0200
commit992311c0ee8d439a6d4b4f58e56d3d83338627b6 (patch)
treefa0bf6ab4d6abd9c9141ccd5ef41d9a70e1482f6 /Userland/Libraries
parent83554526f0488b063e0fff07f0fd11d86301e765 (diff)
downloadserenity-992311c0ee8d439a6d4b4f58e56d3d83338627b6.zip
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.
Diffstat (limited to 'Userland/Libraries')
-rw-r--r--Userland/Libraries/LibWeb/CMakeLists.txt1
-rw-r--r--Userland/Libraries/LibWeb/HTML/Scripting/Environments.cpp6
-rw-r--r--Userland/Libraries/LibWeb/HTML/Scripting/Environments.h6
-rw-r--r--Userland/Libraries/LibWeb/HTML/Scripting/ModuleMap.cpp50
-rw-r--r--Userland/Libraries/LibWeb/HTML/Scripting/ModuleMap.h81
5 files changed, 143 insertions, 1 deletions
diff --git a/Userland/Libraries/LibWeb/CMakeLists.txt b/Userland/Libraries/LibWeb/CMakeLists.txt
index 53dc40f06f..ae7969b4da 100644
--- a/Userland/Libraries/LibWeb/CMakeLists.txt
+++ b/Userland/Libraries/LibWeb/CMakeLists.txt
@@ -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
diff --git a/Userland/Libraries/LibWeb/HTML/Scripting/Environments.cpp b/Userland/Libraries/LibWeb/HTML/Scripting/Environments.cpp
index 961bc39459..df530f78dd 100644
--- a/Userland/Libraries/LibWeb/HTML/Scripting/Environments.cpp
+++ b/Userland/Libraries/LibWeb/HTML/Scripting/Environments.cpp
@@ -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()
{
diff --git a/Userland/Libraries/LibWeb/HTML/Scripting/Environments.h b/Userland/Libraries/LibWeb/HTML/Scripting/Environments.h
index 6c42681ddd..c5169fb022 100644
--- a/Userland/Libraries/LibWeb/HTML/Scripting/Environments.h
+++ b/Userland/Libraries/LibWeb/HTML/Scripting/Environments.h
@@ -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
diff --git a/Userland/Libraries/LibWeb/HTML/Scripting/ModuleMap.cpp b/Userland/Libraries/LibWeb/HTML/Scripting/ModuleMap.cpp
new file mode 100644
index 0000000000..ab775f0149
--- /dev/null
+++ b/Userland/Libraries/LibWeb/HTML/Scripting/ModuleMap.cpp
@@ -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));
+}
+
+}
diff --git a/Userland/Libraries/LibWeb/HTML/Scripting/ModuleMap.h b/Userland/Libraries/LibWeb/HTML/Scripting/ModuleMap.h
new file mode 100644
index 0000000000..90143af09a
--- /dev/null
+++ b/Userland/Libraries/LibWeb/HTML/Scripting/ModuleMap.h
@@ -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());
+ }
+};
+
+}