diff options
Diffstat (limited to 'Ladybird')
-rw-r--r-- | Ladybird/CMakeLists.txt | 1 | ||||
-rw-r--r-- | Ladybird/InspectorWidget.cpp | 76 | ||||
-rw-r--r-- | Ladybird/InspectorWidget.h | 46 | ||||
-rw-r--r-- | Ladybird/WebContentView.cpp | 67 | ||||
-rw-r--r-- | Ladybird/WebContentView.h | 10 |
5 files changed, 176 insertions, 24 deletions
diff --git a/Ladybird/CMakeLists.txt b/Ladybird/CMakeLists.txt index de2d38c971..c216275f4b 100644 --- a/Ladybird/CMakeLists.txt +++ b/Ladybird/CMakeLists.txt @@ -82,6 +82,7 @@ set(SOURCES ${BROWSER_SOURCE_DIR}/History.cpp BrowserWindow.cpp ConsoleWidget.cpp + InspectorWidget.cpp ModelTranslator.cpp Settings.cpp SettingsDialog.cpp diff --git a/Ladybird/InspectorWidget.cpp b/Ladybird/InspectorWidget.cpp new file mode 100644 index 0000000000..5f3b150369 --- /dev/null +++ b/Ladybird/InspectorWidget.cpp @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2022, MacDue <macdue@dueutil.tech> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#define AK_DONT_REPLACE_STD + +#include "InspectorWidget.h" +#include <LibWebView/DOMTreeModel.h> +#include <QCloseEvent> +#include <QTreeView> +#include <QVBoxLayout> + +namespace Ladybird { + +InspectorWidget::InspectorWidget() +{ + setLayout(new QVBoxLayout); + m_tree_view = new QTreeView; + m_tree_view->setHeaderHidden(true); + m_tree_view->expandToDepth(3); + layout()->addWidget(m_tree_view); + m_tree_view->setModel(&m_dom_model); + QObject::connect(m_tree_view->selectionModel(), &QItemSelectionModel::selectionChanged, + [this](QItemSelection const& selected, QItemSelection const&) { + auto indexes = selected.indexes(); + if (indexes.size()) { + auto index = m_dom_model.to_gui(indexes.first()); + set_selection(index); + } + }); +} + +void InspectorWidget::clear_dom_json() +{ + m_dom_model.set_underlying_model(nullptr); +} + +void InspectorWidget::set_dom_json(StringView dom_json) +{ + m_dom_model.set_underlying_model(::WebView::DOMTreeModel::create(dom_json)); +} + +void InspectorWidget::closeEvent(QCloseEvent* event) +{ + event->accept(); + if (on_close) + on_close(); +} + +void InspectorWidget::set_selection(GUI::ModelIndex index) +{ + if (!index.is_valid()) + return; + + auto* json = static_cast<JsonObject const*>(index.internal_data()); + VERIFY(json); + + Selection selection {}; + if (json->has_u32("pseudo-element"sv)) { + selection.dom_node_id = json->get("parent-id"sv).to_i32(); + selection.pseudo_element = static_cast<Web::CSS::Selector::PseudoElement>(json->get("pseudo-element"sv).to_u32()); + } else { + selection.dom_node_id = json->get("id"sv).to_i32(); + } + + if (selection == m_selection) + return; + m_selection = selection; + + VERIFY(on_dom_node_inspected); + on_dom_node_inspected(m_selection.dom_node_id, m_selection.pseudo_element); +} + +} diff --git a/Ladybird/InspectorWidget.h b/Ladybird/InspectorWidget.h new file mode 100644 index 0000000000..ab367784be --- /dev/null +++ b/Ladybird/InspectorWidget.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2022, MacDue <macdue@dueutil.tech> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include "ModelTranslator.h" +#include <AK/Optional.h> +#include <AK/StringView.h> +#include <LibWeb/CSS/Selector.h> +#include <QWidget> + +class QTreeView; + +namespace Ladybird { + +class InspectorWidget final : public QWidget { + Q_OBJECT +public: + InspectorWidget(); + virtual ~InspectorWidget() = default; + + struct Selection { + i32 dom_node_id { 0 }; + Optional<Web::CSS::Selector::PseudoElement> pseudo_element {}; + bool operator==(Selection const& other) const = default; + }; + + void clear_dom_json(); + void set_dom_json(StringView dom_json); + + Function<void(i32, Optional<Web::CSS::Selector::PseudoElement>)> on_dom_node_inspected; + Function<void()> on_close; + +private: + void set_selection(GUI::ModelIndex); + void closeEvent(QCloseEvent*) override; + + QTreeView* m_tree_view { nullptr }; + ModelTranslator m_dom_model {}; + Selection m_selection; +}; + +} diff --git a/Ladybird/WebContentView.cpp b/Ladybird/WebContentView.cpp index 812b352064..8530770a28 100644 --- a/Ladybird/WebContentView.cpp +++ b/Ladybird/WebContentView.cpp @@ -8,7 +8,7 @@ #include "WebContentView.h" #include "ConsoleWidget.h" -#include "ModelTranslator.h" +#include "InspectorWidget.h" #include "Utilities.h" #include <AK/Assertions.h> #include <AK/ByteBuffer.h> @@ -33,10 +33,10 @@ #include <LibGfx/PNGWriter.h> #include <LibGfx/Painter.h> #include <LibGfx/Rect.h> +#include <LibGfx/SystemTheme.h> #include <LibJS/Runtime/ConsoleObject.h> #include <LibMain/Main.h> #include <LibWeb/Loader/ContentFilter.h> -#include <LibWebView/DOMTreeModel.h> #include <LibWebView/WebContentClient.h> #include <QApplication> #include <QCursor> @@ -52,8 +52,6 @@ #include <QTextEdit> #include <QTimer> #include <QToolTip> -#include <QTreeView> -#include <QVBoxLayout> WebContentView::WebContentView(StringView webdriver_content_ipc_path) : m_webdriver_content_ipc_path(webdriver_content_ipc_path) @@ -79,6 +77,7 @@ WebContentView::WebContentView(StringView webdriver_content_ipc_path) WebContentView::~WebContentView() { + clear_inspector_callbacks(); } void WebContentView::load(AK::URL const& url) @@ -504,34 +503,50 @@ void WebContentView::ensure_inspector_widget() { if (m_inspector_widget) return; -#if 0 - m_inspector_widget = new QWidget; + m_inspector_widget = new Ladybird::InspectorWidget; m_inspector_widget->setWindowTitle("Inspector"); - auto* layout = new QVBoxLayout; - m_inspector_widget->setLayout(layout); - auto* tree_view = new QTreeView; - layout->addWidget(tree_view); - - auto dom_tree = m_page_client->page().top_level_browsing_context().active_document()->dump_dom_tree_as_json(); - auto dom_tree_model = ::WebView::DOMTreeModel::create(dom_tree); - auto* model = new Ladybird::ModelTranslator(dom_tree_model); - tree_view->setModel(model); - tree_view->setHeaderHidden(true); - tree_view->expandToDepth(3); - m_inspector_widget->resize(640, 480); + m_inspector_widget->on_close = [this] { + clear_inspected_dom_node(); + }; - QObject::connect(tree_view->selectionModel(), &QItemSelectionModel::currentChanged, [this](QModelIndex const& index, QModelIndex const&) { - auto const* json = (JsonObject const*)index.internalPointer(); - m_page_client->page().top_level_browsing_context().active_document()->set_inspected_node(Web::DOM::Node::from_id(json->get("id"sv).to_i32())); - }); -#endif + m_inspector_widget->on_dom_node_inspected = [&](auto id, auto pseudo_element) { + inspect_dom_node(id, pseudo_element); + }; +} + +void WebContentView::clear_inspector_callbacks() +{ + if (m_inspector_widget) + m_inspector_widget->on_close = nullptr; +} + +bool WebContentView::is_inspector_open() const +{ + return m_inspector_widget && m_inspector_widget->isVisible(); +} + +void WebContentView::inspect_dom_tree() +{ + client().async_inspect_dom_tree(); +} + +void WebContentView::inspect_dom_node(i32 node_id, Optional<Web::CSS::Selector::PseudoElement> pseudo_element) +{ + // TODO: Use and display response + (void)client().inspect_dom_node(node_id, pseudo_element); +} + +void WebContentView::clear_inspected_dom_node() +{ + inspect_dom_node(0, {}); } void WebContentView::show_inspector() { ensure_inspector_widget(); m_inspector_widget->show(); + inspect_dom_tree(); } void WebContentView::set_color_scheme(ColorScheme color_scheme) @@ -806,11 +821,15 @@ void WebContentView::notify_server_did_start_loading(Badge<WebContentClient>, AK { m_url = url; emit load_started(url, is_redirect); + if (m_inspector_widget) + m_inspector_widget->clear_dom_json(); } void WebContentView::notify_server_did_finish_loading(Badge<WebContentClient>, AK::URL const& url) { m_url = url; + if (is_inspector_open()) + inspect_dom_tree(); } void WebContentView::notify_server_did_request_navigate_back(Badge<WebContentClient>) @@ -916,6 +935,8 @@ void WebContentView::notify_server_did_get_dom_tree(DeprecatedString const& dom_ { if (on_get_dom_tree) on_get_dom_tree(dom_tree); + if (m_inspector_widget) + m_inspector_widget->set_dom_json(dom_tree); } void WebContentView::notify_server_did_get_dom_node_properties(i32 node_id, DeprecatedString const& specified_style, DeprecatedString const& computed_style, DeprecatedString const& custom_properties, DeprecatedString const& node_box_sizing) diff --git a/Ladybird/WebContentView.h b/Ladybird/WebContentView.h index 49e011f98f..a48de1d5de 100644 --- a/Ladybird/WebContentView.h +++ b/Ladybird/WebContentView.h @@ -16,6 +16,7 @@ #include <LibGfx/Forward.h> #include <LibGfx/Rect.h> #include <LibGfx/StandardCursor.h> +#include <LibWeb/CSS/Selector.h> #include <LibWebView/ViewImplementation.h> #include <LibWeb/Forward.h> @@ -27,6 +28,7 @@ class QLineEdit; namespace Ladybird { class ConsoleWidget; +class InspectorWidget; } namespace WebView { @@ -185,13 +187,19 @@ private: void ensure_js_console_widget(); void ensure_inspector_widget(); + bool is_inspector_open() const; + void inspect_dom_tree(); + void inspect_dom_node(i32 node_id, Optional<Web::CSS::Selector::PseudoElement> pseudo_element); + void clear_inspected_dom_node(); + void clear_inspector_callbacks(); + qreal m_inverse_pixel_scaling_ratio { 1.0 }; bool m_should_show_line_box_borders { false }; - QPointer<QWidget> m_inspector_widget; QPointer<QDialog> m_dialog; Ladybird::ConsoleWidget* m_console_widget { nullptr }; + Ladybird::InspectorWidget* m_inspector_widget { nullptr }; Gfx::IntRect m_viewport_rect; |