LibWeb+LibWebView+WebContent: Add an Inspector IDL object to the Window
This is an internal object that must be explicitly enabled by the chrome before it is added to the Window. The Inspector object will be used by a special WebView that will replace all chrome-specific inspector windows. The IDL defines methods that this WebView will need to inform the chrome of various events, such as the user clicking a DOM node.
This commit is contained in:
parent
30e96749de
commit
ffdc2d8add
Notes:
sideshowbarker
2024-07-16 18:26:46 +09:00
Author: https://github.com/trflynn89 Commit: https://github.com/SerenityOS/serenity/commit/ffdc2d8add Pull-request: https://github.com/SerenityOS/serenity/pull/22038
21 changed files with 156 additions and 1 deletions
|
@ -1,5 +1,8 @@
|
|||
source_set("Internals") {
|
||||
configs += [ "//Userland/Libraries/LibWeb:configs" ]
|
||||
deps = [ "//Userland/Libraries/LibWeb:all_generated" ]
|
||||
sources = [ "Internals.cpp" ]
|
||||
sources = [
|
||||
"Inspector.cpp",
|
||||
"Internals.cpp",
|
||||
]
|
||||
}
|
||||
|
|
|
@ -216,6 +216,7 @@ standard_idl_files = [
|
|||
"//Userland/Libraries/LibWeb/HTML/WorkerLocation.idl",
|
||||
"//Userland/Libraries/LibWeb/HTML/WorkerNavigator.idl",
|
||||
"//Userland/Libraries/LibWeb/HighResolutionTime/Performance.idl",
|
||||
"//Userland/Libraries/LibWeb/Internals/Inspector.idl",
|
||||
"//Userland/Libraries/LibWeb/Internals/Internals.idl",
|
||||
"//Userland/Libraries/LibWeb/IntersectionObserver/IntersectionObserver.idl",
|
||||
"//Userland/Libraries/LibWeb/IntersectionObserver/IntersectionObserverEntry.idl",
|
||||
|
|
|
@ -415,6 +415,7 @@ set(SOURCES
|
|||
Infra/ByteSequences.cpp
|
||||
Infra/JSON.cpp
|
||||
Infra/Strings.cpp
|
||||
Internals/Inspector.cpp
|
||||
Internals/Internals.cpp
|
||||
IntersectionObserver/IntersectionObserver.cpp
|
||||
IntersectionObserver/IntersectionObserverEntry.cpp
|
||||
|
|
|
@ -482,6 +482,7 @@ class Performance;
|
|||
}
|
||||
|
||||
namespace Web::Internals {
|
||||
class Inspector;
|
||||
class Internals;
|
||||
}
|
||||
|
||||
|
|
|
@ -60,6 +60,7 @@
|
|||
#include <LibWeb/HighResolutionTime/TimeOrigin.h>
|
||||
#include <LibWeb/Infra/Base64.h>
|
||||
#include <LibWeb/Infra/CharacterTypes.h>
|
||||
#include <LibWeb/Internals/Inspector.h>
|
||||
#include <LibWeb/Internals/Internals.h>
|
||||
#include <LibWeb/Layout/Viewport.h>
|
||||
#include <LibWeb/Page/Page.h>
|
||||
|
@ -781,8 +782,14 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<WebIDL::CallbackType>> Window::byte_length_
|
|||
return JS::NonnullGCPtr { *m_byte_length_queuing_strategy_size_function };
|
||||
}
|
||||
|
||||
static bool s_inspector_object_exposed = false;
|
||||
static bool s_internals_object_exposed = false;
|
||||
|
||||
void Window::set_inspector_object_exposed(bool exposed)
|
||||
{
|
||||
s_inspector_object_exposed = exposed;
|
||||
}
|
||||
|
||||
void Window::set_internals_object_exposed(bool exposed)
|
||||
{
|
||||
s_internals_object_exposed = exposed;
|
||||
|
@ -798,6 +805,8 @@ WebIDL::ExceptionOr<void> Window::initialize_web_interfaces(Badge<WindowEnvironm
|
|||
Bindings::WindowGlobalMixin::initialize(realm, *this);
|
||||
WindowOrWorkerGlobalScopeMixin::initialize(realm);
|
||||
|
||||
if (s_inspector_object_exposed)
|
||||
define_direct_property("inspector", heap().allocate<Internals::Inspector>(realm, realm), JS::default_attributes);
|
||||
if (s_internals_object_exposed)
|
||||
define_direct_property("internals", heap().allocate<Internals::Internals>(realm, realm), JS::default_attributes);
|
||||
|
||||
|
|
|
@ -196,6 +196,7 @@ public:
|
|||
HighResolutionTime::DOMHighResTimeStamp get_last_activation_timestamp() const { return m_last_activation_timestamp; }
|
||||
void set_last_activation_timestamp(HighResolutionTime::DOMHighResTimeStamp timestamp) { m_last_activation_timestamp = timestamp; }
|
||||
|
||||
static void set_inspector_object_exposed(bool);
|
||||
static void set_internals_object_exposed(bool);
|
||||
|
||||
[[nodiscard]] OrderedHashMap<String, JS::NonnullGCPtr<Navigable>> document_tree_child_navigable_target_name_property_set();
|
||||
|
|
50
Userland/Libraries/LibWeb/Internals/Inspector.cpp
Normal file
50
Userland/Libraries/LibWeb/Internals/Inspector.cpp
Normal file
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright (c) 2023, Tim Flynn <trflynn89@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibJS/Runtime/Realm.h>
|
||||
#include <LibJS/Runtime/VM.h>
|
||||
#include <LibWeb/Bindings/InspectorPrototype.h>
|
||||
#include <LibWeb/Bindings/Intrinsics.h>
|
||||
#include <LibWeb/CSS/Selector.h>
|
||||
#include <LibWeb/HTML/BrowsingContext.h>
|
||||
#include <LibWeb/HTML/Window.h>
|
||||
#include <LibWeb/Internals/Inspector.h>
|
||||
#include <LibWeb/Page/Page.h>
|
||||
|
||||
namespace Web::Internals {
|
||||
|
||||
JS_DEFINE_ALLOCATOR(Inspector);
|
||||
|
||||
Inspector::Inspector(JS::Realm& realm)
|
||||
: Bindings::PlatformObject(realm)
|
||||
{
|
||||
}
|
||||
|
||||
Inspector::~Inspector() = default;
|
||||
|
||||
void Inspector::initialize(JS::Realm& realm)
|
||||
{
|
||||
Base::initialize(realm);
|
||||
Object::set_prototype(&Bindings::ensure_web_prototype<Bindings::InspectorPrototype>(realm, "Inspector"));
|
||||
}
|
||||
|
||||
void Inspector::inspector_loaded()
|
||||
{
|
||||
if (auto* page = global_object().browsing_context()->page())
|
||||
page->client().inspector_did_load();
|
||||
}
|
||||
|
||||
void Inspector::inspect_dom_node(i32 node_id, Optional<i32> const& pseudo_element)
|
||||
{
|
||||
if (auto* page = global_object().browsing_context()->page()) {
|
||||
page->client().inspector_did_select_dom_node(node_id, pseudo_element.map([](auto value) {
|
||||
VERIFY(value < to_underlying(Web::CSS::Selector::PseudoElement::PseudoElementCount));
|
||||
return static_cast<Web::CSS::Selector::PseudoElement>(value);
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
30
Userland/Libraries/LibWeb/Internals/Inspector.h
Normal file
30
Userland/Libraries/LibWeb/Internals/Inspector.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright (c) 2023, Tim Flynn <trflynn89@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibJS/Forward.h>
|
||||
#include <LibWeb/Bindings/PlatformObject.h>
|
||||
|
||||
namespace Web::Internals {
|
||||
|
||||
class Inspector final : public Bindings::PlatformObject {
|
||||
WEB_PLATFORM_OBJECT(Inspector, Bindings::PlatformObject);
|
||||
JS_DECLARE_ALLOCATOR(Inspector);
|
||||
|
||||
public:
|
||||
virtual ~Inspector() override;
|
||||
|
||||
void inspector_loaded();
|
||||
void inspect_dom_node(i32 node_id, Optional<i32> const& pseudo_element);
|
||||
|
||||
private:
|
||||
explicit Inspector(JS::Realm&);
|
||||
|
||||
virtual void initialize(JS::Realm&) override;
|
||||
};
|
||||
|
||||
}
|
6
Userland/Libraries/LibWeb/Internals/Inspector.idl
Normal file
6
Userland/Libraries/LibWeb/Internals/Inspector.idl
Normal file
|
@ -0,0 +1,6 @@
|
|||
[Exposed=Nobody] interface Inspector {
|
||||
|
||||
undefined inspectorLoaded();
|
||||
undefined inspectDOMNode(long nodeID, optional long pseudoElement);
|
||||
|
||||
};
|
|
@ -24,6 +24,7 @@
|
|||
#include <LibIPC/Forward.h>
|
||||
#include <LibJS/Heap/Handle.h>
|
||||
#include <LibWeb/CSS/PreferredColorScheme.h>
|
||||
#include <LibWeb/CSS/Selector.h>
|
||||
#include <LibWeb/Cookie/Cookie.h>
|
||||
#include <LibWeb/Forward.h>
|
||||
#include <LibWeb/HTML/ActivateTab.h>
|
||||
|
@ -260,6 +261,9 @@ public:
|
|||
|
||||
virtual void page_did_insert_clipboard_entry([[maybe_unused]] String data, [[maybe_unused]] String presentation_style, [[maybe_unused]] String mime_type) { }
|
||||
|
||||
virtual void inspector_did_load() { }
|
||||
virtual void inspector_did_select_dom_node([[maybe_unused]] i32 node_id, [[maybe_unused]] Optional<CSS::Selector::PseudoElement> const& pseudo_element) { }
|
||||
|
||||
protected:
|
||||
virtual ~PageClient() = default;
|
||||
};
|
||||
|
|
|
@ -202,6 +202,7 @@ libweb_js_bindings(HTML/WorkerGlobalScope)
|
|||
libweb_js_bindings(HTML/WorkerLocation)
|
||||
libweb_js_bindings(HTML/WorkerNavigator)
|
||||
libweb_js_bindings(HighResolutionTime/Performance)
|
||||
libweb_js_bindings(Internals/Inspector)
|
||||
libweb_js_bindings(Internals/Internals)
|
||||
libweb_js_bindings(IntersectionObserver/IntersectionObserver)
|
||||
libweb_js_bindings(IntersectionObserver/IntersectionObserverEntry)
|
||||
|
|
|
@ -383,4 +383,9 @@ void ViewImplementation::use_native_user_style_sheet()
|
|||
set_user_style_sheet(MUST(String::from_utf8(native_stylesheet_source)));
|
||||
}
|
||||
|
||||
void ViewImplementation::enable_inspector_prototype()
|
||||
{
|
||||
client().async_enable_inspector_prototype();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -106,6 +106,8 @@ public:
|
|||
// native GUI widgets as possible.
|
||||
void use_native_user_style_sheet();
|
||||
|
||||
void enable_inspector_prototype();
|
||||
|
||||
Function<void(Gfx::IntSize)> on_did_layout;
|
||||
Function<void()> on_ready_to_paint;
|
||||
Function<String(Web::HTML::ActivateTab)> on_new_tab;
|
||||
|
@ -161,6 +163,8 @@ public:
|
|||
Function<void()> on_text_test_finish;
|
||||
Function<void(Gfx::Color)> on_theme_color_change;
|
||||
Function<void(String const&, String const&, String const&)> on_insert_clipboard_entry;
|
||||
Function<void()> on_inspector_loaded;
|
||||
Function<void(i32, Optional<Web::CSS::Selector::PseudoElement> const&)> on_inspector_selected_dom_node;
|
||||
|
||||
virtual Gfx::IntRect viewport_rect() const = 0;
|
||||
virtual Gfx::IntPoint to_content_position(Gfx::IntPoint widget_position) const = 0;
|
||||
|
|
|
@ -402,4 +402,16 @@ void WebContentClient::did_insert_clipboard_entry(String const& data, String con
|
|||
m_view.on_insert_clipboard_entry(data, presentation_style, mime_type);
|
||||
}
|
||||
|
||||
void WebContentClient::inspector_did_load()
|
||||
{
|
||||
if (m_view.on_inspector_loaded)
|
||||
m_view.on_inspector_loaded();
|
||||
}
|
||||
|
||||
void WebContentClient::inspector_did_select_dom_node(i32 node_id, Optional<Web::CSS::Selector::PseudoElement> const& pseudo_element)
|
||||
{
|
||||
if (m_view.on_inspector_selected_dom_node)
|
||||
m_view.on_inspector_selected_dom_node(node_id, pseudo_element);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -86,6 +86,8 @@ private:
|
|||
virtual void did_finish_text_test() override;
|
||||
virtual void did_change_theme_color(Gfx::Color color) override;
|
||||
virtual void did_insert_clipboard_entry(String const& data, String const& presentation_style, String const& mime_type) override;
|
||||
virtual void inspector_did_load() override;
|
||||
virtual void inspector_did_select_dom_node(i32 node_id, Optional<Web::CSS::Selector::PseudoElement> const& pseudo_element) override;
|
||||
|
||||
ViewImplementation& m_view;
|
||||
};
|
||||
|
|
|
@ -929,4 +929,9 @@ void ConnectionFromClient::inspect_accessibility_tree()
|
|||
}
|
||||
}
|
||||
|
||||
void ConnectionFromClient::enable_inspector_prototype()
|
||||
{
|
||||
Web::HTML::Window::set_inspector_object_exposed(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -106,6 +106,8 @@ private:
|
|||
|
||||
virtual void set_user_style(String const&) override;
|
||||
|
||||
virtual void enable_inspector_prototype() override;
|
||||
|
||||
virtual Messages::WebContentServer::TakeDocumentScreenshotResponse take_document_screenshot() override;
|
||||
|
||||
virtual Messages::WebContentServer::GetLocalStorageEntriesResponse get_local_storage_entries() override;
|
||||
|
|
|
@ -503,4 +503,14 @@ void PageHost::page_did_insert_clipboard_entry(String data, String presentation_
|
|||
m_client.async_did_insert_clipboard_entry(move(data), move(presentation_style), move(mime_type));
|
||||
}
|
||||
|
||||
void PageHost::inspector_did_load()
|
||||
{
|
||||
m_client.async_inspector_did_load();
|
||||
}
|
||||
|
||||
void PageHost::inspector_did_select_dom_node(i32 node_id, Optional<Web::CSS::Selector::PseudoElement> const& pseudo_element)
|
||||
{
|
||||
m_client.async_inspector_did_select_dom_node(node_id, pseudo_element);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -121,6 +121,8 @@ private:
|
|||
virtual void page_did_finish_text_test() override;
|
||||
virtual void page_did_change_theme_color(Gfx::Color color) override;
|
||||
virtual void page_did_insert_clipboard_entry(String data, String presentation_style, String mime_type) override;
|
||||
virtual void inspector_did_load() override;
|
||||
virtual void inspector_did_select_dom_node(i32 node_id, Optional<Web::CSS::Selector::PseudoElement> const& pseudo_element) override;
|
||||
|
||||
explicit PageHost(ConnectionFromClient&);
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <LibGfx/ShareableBitmap.h>
|
||||
#include <LibWeb/Cookie/Cookie.h>
|
||||
#include <LibWeb/Cookie/ParsedCookie.h>
|
||||
#include <LibWeb/CSS/Selector.h>
|
||||
#include <LibWeb/HTML/ActivateTab.h>
|
||||
#include <LibWeb/Page/Page.h>
|
||||
|
||||
|
@ -69,4 +70,7 @@ endpoint WebContentClient
|
|||
|
||||
did_finish_text_test() =|
|
||||
|
||||
inspector_did_load() =|
|
||||
inspector_did_select_dom_node(i32 node_id, Optional<Web::CSS::Selector::PseudoElement> pseudo_element) =|
|
||||
|
||||
}
|
||||
|
|
|
@ -86,4 +86,6 @@ endpoint WebContentServer
|
|||
toggle_media_controls_state() =|
|
||||
|
||||
set_user_style(String source) =|
|
||||
|
||||
enable_inspector_prototype() =|
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue