mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 12:28:12 +00:00
WebContent+LibWeb+LibJS: Simplify injection of JS console globals
Instead of creating a new global object and proxying everything through it, we now evaluate console inputs inside a `with` environment. This seems to match the behavior of WebKit and Gecko in my basic testing, and removes the ConsoleGlobalObject which has been a source of confusion and invalid downcasts. The globals now live in a class called ConsoleGlobalObjectExtensions (renamed from ConsoleGlobalObject since it's no longer a global object). To make this possible, I had to add a way to override the initial lexical environment when calling JS::Interpreter::run(). This is plumbed via Web::HTML::ClassicScript::run().
This commit is contained in:
parent
23b07b3408
commit
fbf9cb3387
12 changed files with 187 additions and 292 deletions
|
@ -7,78 +7,42 @@
|
|||
*/
|
||||
|
||||
#include "WebContentConsoleClient.h"
|
||||
#include <AK/TemporaryChange.h>
|
||||
#include <LibJS/Interpreter.h>
|
||||
#include <LibJS/MarkupGenerator.h>
|
||||
#include <LibJS/Runtime/AbstractOperations.h>
|
||||
#include <LibJS/Runtime/ObjectEnvironment.h>
|
||||
#include <LibWeb/HTML/PolicyContainers.h>
|
||||
#include <LibWeb/HTML/Scripting/ClassicScript.h>
|
||||
#include <LibWeb/HTML/Scripting/Environments.h>
|
||||
#include <LibWeb/HTML/Window.h>
|
||||
#include <WebContent/ConsoleGlobalObject.h>
|
||||
#include <WebContent/ConsoleGlobalEnvironmentExtensions.h>
|
||||
|
||||
namespace WebContent {
|
||||
|
||||
class ConsoleEnvironmentSettingsObject final : public Web::HTML::EnvironmentSettingsObject {
|
||||
JS_CELL(ConsoleEnvironmentSettingsObject, EnvironmentSettingsObject);
|
||||
|
||||
public:
|
||||
ConsoleEnvironmentSettingsObject(NonnullOwnPtr<JS::ExecutionContext> execution_context)
|
||||
: Web::HTML::EnvironmentSettingsObject(move(execution_context))
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~ConsoleEnvironmentSettingsObject() override = default;
|
||||
|
||||
JS::GCPtr<Web::DOM::Document> responsible_document() override { return nullptr; }
|
||||
DeprecatedString api_url_character_encoding() override { return m_api_url_character_encoding; }
|
||||
AK::URL api_base_url() override { return m_url; }
|
||||
Web::HTML::Origin origin() override { return m_origin; }
|
||||
Web::HTML::PolicyContainer policy_container() override { return m_policy_container; }
|
||||
Web::HTML::CanUseCrossOriginIsolatedAPIs cross_origin_isolated_capability() override { return Web::HTML::CanUseCrossOriginIsolatedAPIs::Yes; }
|
||||
|
||||
private:
|
||||
DeprecatedString m_api_url_character_encoding;
|
||||
AK::URL m_url;
|
||||
Web::HTML::Origin m_origin;
|
||||
Web::HTML::PolicyContainer m_policy_container;
|
||||
};
|
||||
|
||||
WebContentConsoleClient::WebContentConsoleClient(JS::Console& console, JS::Realm& realm, ConnectionFromClient& client)
|
||||
: ConsoleClient(console)
|
||||
, m_client(client)
|
||||
, m_realm(realm)
|
||||
{
|
||||
JS::DeferGC defer_gc(realm.heap());
|
||||
|
||||
auto& vm = realm.vm();
|
||||
auto& window = static_cast<Web::HTML::Window&>(realm.global_object());
|
||||
|
||||
auto console_execution_context = MUST(JS::Realm::initialize_host_defined_realm(
|
||||
vm, [&](JS::Realm& realm) {
|
||||
m_console_global_object = vm.heap().allocate_without_realm<ConsoleGlobalObject>(realm, window);
|
||||
return m_console_global_object;
|
||||
},
|
||||
nullptr));
|
||||
|
||||
auto* console_realm = console_execution_context->realm;
|
||||
m_console_settings = vm.heap().allocate<ConsoleEnvironmentSettingsObject>(*console_realm, move(console_execution_context));
|
||||
auto* intrinsics = vm.heap().allocate<Web::Bindings::Intrinsics>(*console_realm, *console_realm);
|
||||
auto host_defined = make<Web::Bindings::HostDefined>(*m_console_settings, *intrinsics);
|
||||
console_realm->set_host_defined(move(host_defined));
|
||||
auto& window = verify_cast<Web::HTML::Window>(realm.global_object());
|
||||
m_console_global_environment_extensions = realm.heap().allocate<ConsoleGlobalEnvironmentExtensions>(realm, realm, window);
|
||||
}
|
||||
|
||||
void WebContentConsoleClient::handle_input(DeprecatedString const& js_source)
|
||||
{
|
||||
if (!m_realm)
|
||||
if (!m_console_global_environment_extensions)
|
||||
return;
|
||||
|
||||
auto script = Web::HTML::ClassicScript::create("(console)", js_source, *m_console_settings, m_console_settings->api_base_url());
|
||||
auto& settings = Web::HTML::relevant_settings_object(*m_console_global_environment_extensions);
|
||||
auto script = Web::HTML::ClassicScript::create("(console)", js_source, settings, settings.api_base_url());
|
||||
|
||||
JS::Environment* with_scope = JS::new_object_environment(*m_console_global_environment_extensions, true, &settings.realm().global_environment());
|
||||
|
||||
// FIXME: Add parse error printouts back once ClassicScript can report parse errors.
|
||||
|
||||
auto result = script->run();
|
||||
auto result = script->run(Web::HTML::ClassicScript::RethrowErrors::No, with_scope);
|
||||
|
||||
if (result.value().has_value()) {
|
||||
m_console_global_object->set_most_recent_result(result.value().value());
|
||||
m_console_global_environment_extensions->set_most_recent_result(result.value().value());
|
||||
print_html(JS::MarkupGenerator::html_from_value(*result.value()).release_value_but_fixme_should_propagate_errors().to_deprecated_string());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue