diff --git a/UI/Qt/BrowserWindow.cpp b/UI/Qt/BrowserWindow.cpp index 946216bf64f..cf217641445 100644 --- a/UI/Qt/BrowserWindow.cpp +++ b/UI/Qt/BrowserWindow.cpp @@ -353,18 +353,6 @@ BrowserWindow::BrowserWindow(Vector const& initial_urls, IsPopupWindow } }); - auto* inspector_action = new QAction("Open &Inspector", this); - inspector_action->setIcon(load_icon_from_uri("resource://icons/browser/dom-tree.png"sv)); - inspector_action->setShortcuts({ QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_I), - QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_C), - QKeySequence(Qt::Key_F12) }); - inspect_menu->addAction(inspector_action); - QObject::connect(inspector_action, &QAction::triggered, this, [this] { - if (m_current_tab) { - m_current_tab->show_inspector_window(); - } - }); - auto* task_manager_action = new QAction("Open Task &Manager", this); task_manager_action->setIcon(load_icon_from_uri("resource://icons/16x16/app-system-monitor.png"sv)); task_manager_action->setShortcuts({ QKeySequence("Ctrl+Shift+M") }); @@ -648,11 +636,6 @@ BrowserWindow::BrowserWindow(Vector const& initial_urls, IsPopupWindow QObject::connect(m_tabs_container, &QTabWidget::tabCloseRequested, this, &BrowserWindow::close_tab); QObject::connect(close_current_tab_action, &QAction::triggered, this, &BrowserWindow::close_current_tab); - m_inspect_dom_node_action = new QAction("&Inspect Element", this); - connect(m_inspect_dom_node_action, &QAction::triggered, this, [this] { - if (m_current_tab) - m_current_tab->show_inspector_window(Tab::InspectorTarget::HoveredElement); - }); m_go_back_action = new QAction("Go Back", this); connect(m_go_back_action, &QAction::triggered, this, [this] { if (m_current_tab) diff --git a/UI/Qt/BrowserWindow.h b/UI/Qt/BrowserWindow.h index 18602a76311..ff796049edb 100644 --- a/UI/Qt/BrowserWindow.h +++ b/UI/Qt/BrowserWindow.h @@ -99,11 +99,6 @@ public: return *m_view_source_action; } - QAction& inspect_dom_node_action() - { - return *m_inspect_dom_node_action; - } - Tab* current_tab() const { return m_current_tab; } public slots: @@ -202,7 +197,6 @@ private: QAction* m_select_all_action { nullptr }; QAction* m_find_in_page_action { nullptr }; QAction* m_view_source_action { nullptr }; - QAction* m_inspect_dom_node_action { nullptr }; QAction* m_show_line_box_borders_action { nullptr }; QAction* m_enable_scripting_action { nullptr }; QAction* m_enable_content_filtering_action { nullptr }; diff --git a/UI/Qt/CMakeLists.txt b/UI/Qt/CMakeLists.txt index ec171bee255..8da50577220 100644 --- a/UI/Qt/CMakeLists.txt +++ b/UI/Qt/CMakeLists.txt @@ -5,7 +5,6 @@ target_sources(ladybird PRIVATE BrowserWindow.cpp FindInPageWidget.cpp Icon.cpp - InspectorWidget.cpp LocationEdit.cpp Settings.cpp SettingsDialog.cpp diff --git a/UI/Qt/InspectorWidget.cpp b/UI/Qt/InspectorWidget.cpp deleted file mode 100644 index 445f71565a5..00000000000 --- a/UI/Qt/InspectorWidget.cpp +++ /dev/null @@ -1,244 +0,0 @@ -/* - * Copyright (c) 2022, MacDue - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -namespace Ladybird { - -extern bool is_using_dark_system_theme(QWidget&); - -InspectorWidget::InspectorWidget(QWidget* tab, WebContentView& content_view) - : QWidget(tab, Qt::Window) -{ - m_inspector_view = new WebContentView(this); - m_inspector_view->on_close = [this] { - close(); - }; - - if (is_using_dark_system_theme(*this)) - m_inspector_view->update_palette(WebContentView::PaletteMode::Dark); - - auto* inspector_close_action = new QAction("Close Inspector", this); - inspector_close_action->setShortcuts({ QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_I), QKeySequence(Qt::CTRL | Qt::Key_W), QKeySequence(Qt::Key_F12) }); - addAction(inspector_close_action); - connect(inspector_close_action, &QAction::triggered, [this]() { close(); }); - - auto* copy_action = new QAction("&Copy", this); - copy_action->setShortcuts(QKeySequence::keyBindings(QKeySequence::StandardKey::Copy)); - addAction(copy_action); - connect(copy_action, &QAction::triggered, [this]() { - auto text = m_inspector_view->selected_text(); - QGuiApplication::clipboard()->setText(qstring_from_ak_string(text)); - }); - - auto* paste_action = new QAction("&Paste", this); - paste_action->setShortcuts(QKeySequence::keyBindings(QKeySequence::StandardKey::Paste)); - addAction(paste_action); - connect(paste_action, &QAction::triggered, [this]() { - auto* clipboard = QGuiApplication::clipboard(); - m_inspector_view->paste(ak_string_from_qstring(clipboard->text())); - }); - - auto* select_all_action = new QAction("Select &All", this); - select_all_action->setShortcuts(QKeySequence::keyBindings(QKeySequence::StandardKey::SelectAll)); - addAction(select_all_action); - connect(select_all_action, &QAction::triggered, [this]() { - m_inspector_view->select_all(); - }); - - m_inspector_client = make(content_view, *m_inspector_view); - - m_edit_node_action = new QAction("&Edit node", this); - connect(m_edit_node_action, &QAction::triggered, [this]() { m_inspector_client->context_menu_edit_dom_node(); }); - - m_copy_node_action = new QAction("&Copy HTML", this); - connect(m_copy_node_action, &QAction::triggered, [this]() { m_inspector_client->context_menu_copy_dom_node(); }); - - m_screenshot_node_action = new QAction("Take node &screenshot", this); - connect(m_screenshot_node_action, &QAction::triggered, [this]() { m_inspector_client->context_menu_screenshot_dom_node(); }); - - m_create_child_element_action = new QAction("Create child &element", this); - connect(m_create_child_element_action, &QAction::triggered, [this]() { m_inspector_client->context_menu_create_child_element(); }); - - m_create_child_text_node_action = new QAction("Create child &text node", this); - connect(m_create_child_text_node_action, &QAction::triggered, [this]() { m_inspector_client->context_menu_create_child_text_node(); }); - - m_clone_node_action = new QAction("C&lone node", this); - connect(m_clone_node_action, &QAction::triggered, [this]() { m_inspector_client->context_menu_clone_dom_node(); }); - - m_delete_node_action = new QAction("&Delete node", this); - connect(m_delete_node_action, &QAction::triggered, [this]() { m_inspector_client->context_menu_remove_dom_node(); }); - - m_add_attribute_action = new QAction("&Add attribute", this); - connect(m_add_attribute_action, &QAction::triggered, [this]() { m_inspector_client->context_menu_add_dom_node_attribute(); }); - - m_remove_attribute_action = new QAction("&Remove attribute", this); - connect(m_remove_attribute_action, &QAction::triggered, [this]() { m_inspector_client->context_menu_remove_dom_node_attribute(); }); - - m_copy_attribute_value_action = new QAction("Copy attribute &value", this); - connect(m_copy_attribute_value_action, &QAction::triggered, [this]() { m_inspector_client->context_menu_copy_dom_node_attribute_value(); }); - - m_delete_cookie_action = new QAction("&Delete cookie", this); - connect(m_delete_cookie_action, &QAction::triggered, [this]() { m_inspector_client->context_menu_delete_cookie(); }); - - m_delete_all_cookies_action = new QAction("Delete &all cookies", this); - connect(m_delete_all_cookies_action, &QAction::triggered, [this]() { m_inspector_client->context_menu_delete_all_cookies(); }); - - m_dom_node_text_context_menu = new QMenu("DOM text context menu", this); - m_dom_node_text_context_menu->addAction(m_edit_node_action); - m_dom_node_text_context_menu->addAction(m_copy_node_action); - m_dom_node_text_context_menu->addSeparator(); - m_dom_node_text_context_menu->addAction(m_delete_node_action); - - auto* create_child_menu = new QMenu("Create child", this); - create_child_menu->addAction(m_create_child_element_action); - create_child_menu->addAction(m_create_child_text_node_action); - - m_dom_node_tag_context_menu = new QMenu("DOM tag context menu", this); - m_dom_node_tag_context_menu->addAction(m_edit_node_action); - m_dom_node_tag_context_menu->addSeparator(); - m_dom_node_tag_context_menu->addAction(m_add_attribute_action); - m_dom_node_tag_context_menu->addMenu(create_child_menu); - m_dom_node_tag_context_menu->addAction(m_clone_node_action); - m_dom_node_tag_context_menu->addAction(m_delete_node_action); - m_dom_node_tag_context_menu->addSeparator(); - m_dom_node_tag_context_menu->addAction(m_copy_node_action); - m_dom_node_tag_context_menu->addAction(m_screenshot_node_action); - - m_dom_node_attribute_context_menu = new QMenu("DOM attribute context menu", this); - m_dom_node_attribute_context_menu->addAction(m_edit_node_action); - m_dom_node_attribute_context_menu->addAction(m_copy_attribute_value_action); - m_dom_node_attribute_context_menu->addAction(m_remove_attribute_action); - m_dom_node_attribute_context_menu->addSeparator(); - m_dom_node_attribute_context_menu->addAction(m_add_attribute_action); - m_dom_node_attribute_context_menu->addMenu(create_child_menu); - m_dom_node_attribute_context_menu->addAction(m_clone_node_action); - m_dom_node_attribute_context_menu->addAction(m_delete_node_action); - m_dom_node_attribute_context_menu->addSeparator(); - m_dom_node_attribute_context_menu->addAction(m_copy_node_action); - m_dom_node_attribute_context_menu->addAction(m_screenshot_node_action); - - m_cookie_context_menu = new QMenu("Cookie context menu", this); - m_cookie_context_menu->addAction(m_delete_cookie_action); - m_cookie_context_menu->addAction(m_delete_all_cookies_action); - - m_inspector_client->on_requested_dom_node_text_context_menu = [this](auto position) { - m_edit_node_action->setText("&Edit text"); - m_copy_node_action->setText("&Copy text"); - - m_dom_node_text_context_menu->exec(m_inspector_view->map_point_to_global_position(position)); - }; - - m_inspector_client->on_requested_dom_node_tag_context_menu = [this](auto position, auto const& tag) { - m_edit_node_action->setText(qstring_from_ak_string(MUST(String::formatted("&Edit \"{}\"", tag)))); - m_copy_node_action->setText("&Copy HTML"); - - m_dom_node_tag_context_menu->exec(m_inspector_view->map_point_to_global_position(position)); - }; - - m_inspector_client->on_requested_dom_node_attribute_context_menu = [this](auto position, auto const&, WebView::Attribute const& attribute) { - static constexpr size_t MAX_ATTRIBUTE_VALUE_LENGTH = 32; - - m_copy_node_action->setText("&Copy HTML"); - m_edit_node_action->setText(qstring_from_ak_string(MUST(String::formatted("&Edit attribute \"{}\"", attribute.name)))); - m_remove_attribute_action->setText(qstring_from_ak_string(MUST(String::formatted("&Remove attribute \"{}\"", attribute.name)))); - m_copy_attribute_value_action->setText(qstring_from_ak_string(MUST(String::formatted("Copy attribute &value \"{:.{}}{}\"", - attribute.value, MAX_ATTRIBUTE_VALUE_LENGTH, - attribute.value.bytes_as_string_view().length() > MAX_ATTRIBUTE_VALUE_LENGTH ? "..."sv : ""sv)))); - - m_dom_node_attribute_context_menu->exec(m_inspector_view->map_point_to_global_position(position)); - }; - - m_inspector_client->on_requested_cookie_context_menu = [this](auto position, auto const& cookie) { - m_delete_cookie_action->setText(qstring_from_ak_string(MUST(String::formatted("&Delete \"{}\"", cookie.name)))); - m_cookie_context_menu->exec(m_inspector_view->map_point_to_global_position(position)); - }; - - setLayout(new QVBoxLayout); - layout()->addWidget(m_inspector_view); - - setWindowTitle("Inspector"); - resize(875, 825); - - // Listen for DPI changes - m_device_pixel_ratio = devicePixelRatio(); - m_current_screen = screen(); - if (QT_VERSION < QT_VERSION_CHECK(6, 6, 0) || QGuiApplication::platformName() != "wayland") { - setAttribute(Qt::WA_NativeWindow); - setAttribute(Qt::WA_DontCreateNativeAncestors); - QObject::connect(m_current_screen, &QScreen::logicalDotsPerInchChanged, this, &InspectorWidget::device_pixel_ratio_changed); - QObject::connect(windowHandle(), &QWindow::screenChanged, this, [this](QScreen* screen) { - if (m_device_pixel_ratio != screen->devicePixelRatio()) - device_pixel_ratio_changed(screen->devicePixelRatio()); - - // Listen for logicalDotsPerInchChanged signals on new screen - QObject::disconnect(m_current_screen, &QScreen::logicalDotsPerInchChanged, nullptr, nullptr); - m_current_screen = screen; - QObject::connect(m_current_screen, &QScreen::logicalDotsPerInchChanged, this, &InspectorWidget::device_pixel_ratio_changed); - }); - } -} - -InspectorWidget::~InspectorWidget() = default; - -void InspectorWidget::inspect() -{ - m_inspector_client->inspect(); -} - -void InspectorWidget::reset() -{ - m_inspector_client->reset(); -} - -void InspectorWidget::select_hovered_node() -{ - m_inspector_client->select_hovered_node(); -} - -void InspectorWidget::select_default_node() -{ - m_inspector_client->select_default_node(); -} - -void InspectorWidget::device_pixel_ratio_changed(qreal dpi) -{ - m_device_pixel_ratio = dpi; - m_inspector_view->set_device_pixel_ratio(m_device_pixel_ratio); -} - -bool InspectorWidget::event(QEvent* event) -{ -#if QT_VERSION >= QT_VERSION_CHECK(6, 6, 0) - if (event->type() == QEvent::DevicePixelRatioChange) { - if (m_device_pixel_ratio != devicePixelRatio()) - device_pixel_ratio_changed(devicePixelRatio()); - } -#endif - - return QWidget::event(event); -} - -void InspectorWidget::closeEvent(QCloseEvent* event) -{ - event->accept(); - m_inspector_client->clear_selection(); - emit closed(); -} - -} diff --git a/UI/Qt/InspectorWidget.h b/UI/Qt/InspectorWidget.h deleted file mode 100644 index 0b7623655bb..00000000000 --- a/UI/Qt/InspectorWidget.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2022, MacDue - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include -#include -#include - -#include - -class QAction; -class QMenu; - -namespace Ladybird { - -class WebContentView; - -class InspectorWidget final : public QWidget { - Q_OBJECT - -public: - InspectorWidget(QWidget* tab, WebContentView& content_view); - virtual ~InspectorWidget() override; - - void inspect(); - void reset(); - - void select_hovered_node(); - void select_default_node(); - -public slots: - void device_pixel_ratio_changed(qreal dpi); - -signals: - void closed(); - -private: - virtual bool event(QEvent*) override; - void closeEvent(QCloseEvent*) override; - - QScreen* m_current_screen; - double m_device_pixel_ratio { 0 }; - - WebContentView* m_inspector_view; - OwnPtr m_inspector_client; - - QMenu* m_dom_node_text_context_menu { nullptr }; - QMenu* m_dom_node_tag_context_menu { nullptr }; - QMenu* m_dom_node_attribute_context_menu { nullptr }; - QMenu* m_cookie_context_menu { nullptr }; - - QAction* m_edit_node_action { nullptr }; - QAction* m_copy_node_action { nullptr }; - QAction* m_screenshot_node_action { nullptr }; - QAction* m_create_child_element_action { nullptr }; - QAction* m_create_child_text_node_action { nullptr }; - QAction* m_clone_node_action { nullptr }; - QAction* m_delete_node_action { nullptr }; - QAction* m_add_attribute_action { nullptr }; - QAction* m_remove_attribute_action { nullptr }; - QAction* m_copy_attribute_value_action { nullptr }; - QAction* m_delete_cookie_action { nullptr }; - QAction* m_delete_all_cookies_action { nullptr }; -}; - -} diff --git a/UI/Qt/Tab.cpp b/UI/Qt/Tab.cpp index 75d5ce7aeb5..1851f683a4e 100644 --- a/UI/Qt/Tab.cpp +++ b/UI/Qt/Tab.cpp @@ -15,7 +15,6 @@ #include #include #include -#include #include #include @@ -139,9 +138,6 @@ Tab::Tab(BrowserWindow* window, RefPtr parent_client, }; view().on_load_start = [this](const URL::URL& url, bool) { - if (m_inspector_widget) - m_inspector_widget->reset(); - auto url_serialized = qstring_from_ak_string(url.serialize()); m_title = url_serialized; @@ -154,11 +150,6 @@ Tab::Tab(BrowserWindow* window, RefPtr parent_client, m_location_edit->setCursorPosition(0); }; - view().on_load_finish = [this](auto&) { - if (m_inspector_widget != nullptr && m_inspector_widget->isVisible()) - m_inspector_widget->inspect(); - }; - view().on_url_change = [this](auto const& url) { m_location_edit->set_url(url); }; @@ -349,10 +340,6 @@ Tab::Tab(BrowserWindow* window, RefPtr parent_client, m_window->new_tab_from_content(html, Web::HTML::ActivateTab::Yes); }; - view().on_inspector_requested_style_sheet_source = [this](auto const& identifier) { - view().request_style_sheet_source(identifier); - }; - view().on_restore_window = [this]() { m_window->showNormal(); }; @@ -528,7 +515,6 @@ Tab::Tab(BrowserWindow* window, RefPtr parent_client, m_page_context_menu->addAction(take_full_screenshot_action); m_page_context_menu->addSeparator(); m_page_context_menu->addAction(&m_window->view_source_action()); - m_page_context_menu->addAction(&m_window->inspect_dom_node_action()); view().on_context_menu_request = [this, search_selected_text_action](Gfx::IntPoint content_position) { auto selected_text = Settings::the()->enable_search() @@ -562,8 +548,6 @@ Tab::Tab(BrowserWindow* window, RefPtr parent_client, m_link_context_menu = new QMenu("Link context menu", this); m_link_context_menu->addAction(open_link_in_new_tab_action); m_link_context_menu->addAction(m_link_context_menu_copy_url_action); - m_link_context_menu->addSeparator(); - m_link_context_menu->addAction(&m_window->inspect_dom_node_action()); view().on_link_context_menu_request = [this](auto const& url, Gfx::IntPoint content_position) { m_link_context_menu_url = url; @@ -629,8 +613,6 @@ Tab::Tab(BrowserWindow* window, RefPtr parent_client, m_image_context_menu->addSeparator(); m_image_context_menu->addAction(m_image_context_menu_copy_image_action); m_image_context_menu->addAction(copy_image_url_action); - m_image_context_menu->addSeparator(); - m_image_context_menu->addAction(&m_window->inspect_dom_node_action()); view().on_image_context_menu_request = [this](auto& image_url, Gfx::IntPoint content_position, Optional const& shareable_bitmap) { m_image_context_menu_url = image_url; @@ -697,8 +679,6 @@ Tab::Tab(BrowserWindow* window, RefPtr parent_client, m_audio_context_menu->addAction(open_audio_in_new_tab_action); m_audio_context_menu->addSeparator(); m_audio_context_menu->addAction(copy_audio_url_action); - m_audio_context_menu->addSeparator(); - m_audio_context_menu->addAction(&m_window->inspect_dom_node_action()); auto* open_video_action = new QAction("&Open Video", this); open_video_action->setIcon(load_icon_from_uri("resource://icons/16x16/filetype-video.png"sv)); @@ -728,8 +708,6 @@ Tab::Tab(BrowserWindow* window, RefPtr parent_client, m_video_context_menu->addAction(open_video_in_new_tab_action); m_video_context_menu->addSeparator(); m_video_context_menu->addAction(copy_video_url_action); - m_video_context_menu->addSeparator(); - m_video_context_menu->addAction(&m_window->inspect_dom_node_action()); view().on_media_context_menu_request = [this](Gfx::IntPoint content_position, Web::Page::MediaContextMenu const& menu) { m_media_context_menu_url = menu.media_url; @@ -761,14 +739,7 @@ Tab::Tab(BrowserWindow* window, RefPtr parent_client, }; } -Tab::~Tab() -{ - close_sub_widgets(); - - // Delete the InspectorWidget explicitly to ensure it is deleted before the WebContentView. Otherwise, Qt - // can destroy these objects in any order, which may cause use-after-free in InspectorWidget's destructor. - delete m_inspector_widget; -} +Tab::~Tab() = default; void Tab::update_reset_zoom_button() { @@ -906,36 +877,6 @@ void Tab::recreate_toolbar_icons() m_hamburger_button->setIcon(create_tvg_icon_with_theme_colors("hamburger", palette())); } -void Tab::recreate_inspector() -{ - if (m_inspector_widget) - m_inspector_widget->deleteLater(); - - m_inspector_widget = new InspectorWidget(this, view()); - - QObject::connect(m_inspector_widget, &InspectorWidget::closed, [this] { - m_inspector_widget->deleteLater(); - m_inspector_widget = nullptr; - }); -} - -void Tab::show_inspector_window(InspectorTarget inspector_target) -{ - if (!m_inspector_widget) - recreate_inspector(); - else - m_inspector_widget->inspect(); - - m_inspector_widget->show(); - m_inspector_widget->activateWindow(); - m_inspector_widget->raise(); - - if (inspector_target == InspectorTarget::HoveredElement) - m_inspector_widget->select_hovered_node(); - else - m_inspector_widget->select_default_node(); -} - void Tab::show_find_in_page() { m_find_in_page->setVisible(true); @@ -952,16 +893,6 @@ void Tab::find_next() m_find_in_page->find_next(); } -void Tab::close_sub_widgets() -{ - auto close_widget_window = [](auto* widget) { - if (widget) - widget->close(); - }; - - close_widget_window(m_inspector_widget); -} - void Tab::set_block_popups(bool enabled) { debug_request("block-pop-ups", enabled ? "on" : "off"); diff --git a/UI/Qt/Tab.h b/UI/Qt/Tab.h index 10154156bf6..133213830f8 100644 --- a/UI/Qt/Tab.h +++ b/UI/Qt/Tab.h @@ -24,7 +24,6 @@ namespace Ladybird { class BrowserWindow; -class InspectorWidget; class HyperlinkLabel final : public QLabel { Q_OBJECT @@ -66,12 +65,6 @@ public: void open_file(); void update_reset_zoom_button(); - enum class InspectorTarget { - Document, - HoveredElement - }; - void show_inspector_window(InspectorTarget = InspectorTarget::Document); - void show_find_in_page(); void find_previous(); void find_next(); @@ -124,10 +117,6 @@ private: void open_link_in_new_tab(URL::URL const&); void copy_link_url(URL::URL const&); - void close_sub_widgets(); - - void recreate_inspector(); - QBoxLayout* m_layout { nullptr }; QToolBar* m_toolbar { nullptr }; QToolButton* m_hamburger_button { nullptr }; @@ -172,8 +161,6 @@ private: int tab_index(); - Ladybird::InspectorWidget* m_inspector_widget { nullptr }; - QPointer m_dialog; bool m_can_navigate_back { false };