| 
									
										
										
										
											2022-07-05 23:18:21 +01:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2024-10-04 13:19:50 +02:00
										 |  |  |  * Copyright (c) 2022, Andreas Kling <andreas@ladybird.org> | 
					
						
							| 
									
										
										
										
											2022-07-05 23:18:21 +01:00
										 |  |  |  * Copyright (c) 2022, Matthew Costa <ucosty@gmail.com> | 
					
						
							| 
									
										
										
										
											2024-04-28 15:07:23 +01:00
										 |  |  |  * Copyright (c) 2024, Jamie Mansfield <jmansfield@cadixdev.org> | 
					
						
							| 
									
										
										
										
											2022-07-05 23:18:21 +01:00
										 |  |  |  * | 
					
						
							|  |  |  |  * SPDX-License-Identifier: BSD-2-Clause | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-04 16:40:12 -04:00
										 |  |  | #include <AK/TemporaryChange.h>
 | 
					
						
							| 
									
										
										
										
											2023-05-15 13:43:58 -04:00
										 |  |  | #include <LibGfx/ImageFormats/BMPWriter.h>
 | 
					
						
							| 
									
										
										
										
											2025-02-22 21:51:15 +13:00
										 |  |  | #include <LibURL/Parser.h>
 | 
					
						
							| 
									
										
										
										
											2024-02-25 13:09:26 -05:00
										 |  |  | #include <LibWeb/HTML/SelectedFile.h>
 | 
					
						
							| 
									
										
										
										
											2023-10-23 12:49:53 -04:00
										 |  |  | #include <LibWebView/SearchEngine.h>
 | 
					
						
							| 
									
										
										
										
											2023-08-28 16:36:51 -04:00
										 |  |  | #include <LibWebView/SourceHighlighter.h>
 | 
					
						
							| 
									
										
										
										
											2023-10-13 09:52:06 -04:00
										 |  |  | #include <LibWebView/URL.h>
 | 
					
						
							| 
									
										
										
										
											2024-11-09 12:50:33 -05:00
										 |  |  | #include <UI/Qt/BrowserWindow.h>
 | 
					
						
							|  |  |  | #include <UI/Qt/Icon.h>
 | 
					
						
							|  |  |  | #include <UI/Qt/InspectorWidget.h>
 | 
					
						
							|  |  |  | #include <UI/Qt/Settings.h>
 | 
					
						
							|  |  |  | #include <UI/Qt/StringUtils.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-15 12:27:10 -04:00
										 |  |  | #include <QClipboard>
 | 
					
						
							| 
									
										
										
										
											2023-09-04 15:46:20 +02:00
										 |  |  | #include <QColorDialog>
 | 
					
						
							| 
									
										
										
										
											2022-07-05 23:18:21 +01:00
										 |  |  | #include <QCoreApplication>
 | 
					
						
							| 
									
										
										
										
											2023-05-20 21:53:38 -07:00
										 |  |  | #include <QCursor>
 | 
					
						
							| 
									
										
										
										
											2024-01-06 10:00:03 -05:00
										 |  |  | #include <QDesktopServices>
 | 
					
						
							| 
									
										
										
										
											2023-05-25 23:47:12 +02:00
										 |  |  | #include <QFileDialog>
 | 
					
						
							| 
									
										
										
										
											2022-09-09 14:23:36 +02:00
										 |  |  | #include <QFont>
 | 
					
						
							|  |  |  | #include <QFontMetrics>
 | 
					
						
							| 
									
										
										
										
											2023-05-15 12:27:10 -04:00
										 |  |  | #include <QGuiApplication>
 | 
					
						
							| 
									
										
										
										
											2023-05-15 13:43:58 -04:00
										 |  |  | #include <QImage>
 | 
					
						
							| 
									
										
										
										
											2023-05-17 14:23:34 -04:00
										 |  |  | #include <QInputDialog>
 | 
					
						
							| 
									
										
										
										
											2023-05-15 11:49:44 -04:00
										 |  |  | #include <QMenu>
 | 
					
						
							| 
									
										
										
										
											2023-05-16 07:56:12 -04:00
										 |  |  | #include <QMessageBox>
 | 
					
						
							| 
									
										
										
										
											2023-11-10 13:44:12 -05:00
										 |  |  | #include <QMimeData>
 | 
					
						
							| 
									
										
										
										
											2024-03-14 19:19:51 -04:00
										 |  |  | #include <QMimeDatabase>
 | 
					
						
							|  |  |  | #include <QMimeType>
 | 
					
						
							| 
									
										
										
										
											2023-05-05 15:38:46 +02:00
										 |  |  | #include <QPainter>
 | 
					
						
							| 
									
										
										
										
											2022-07-13 04:39:38 +02:00
										 |  |  | #include <QPoint>
 | 
					
						
							| 
									
										
										
										
											2024-01-06 10:00:03 -05:00
										 |  |  | #include <QPushButton>
 | 
					
						
							| 
									
										
										
										
											2022-09-09 14:23:36 +02:00
										 |  |  | #include <QResizeEvent>
 | 
					
						
							| 
									
										
										
										
											2022-07-05 23:18:21 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-02 11:52:59 -06:00
										 |  |  | namespace Ladybird { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-29 06:53:53 -04:00
										 |  |  | static QIcon default_favicon() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2024-07-07 16:30:22 +01:00
										 |  |  |     static QIcon icon = load_icon_from_uri("resource://icons/48x48/app-browser.png"sv); | 
					
						
							| 
									
										
										
										
											2024-03-29 06:53:53 -04:00
										 |  |  |     return icon; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-30 14:01:05 -04:00
										 |  |  | Tab::Tab(BrowserWindow* window, RefPtr<WebView::WebContentClient> parent_client, size_t page_index) | 
					
						
							| 
									
										
										
										
											2022-10-01 12:46:24 -06:00
										 |  |  |     : QWidget(window) | 
					
						
							|  |  |  |     , m_window(window) | 
					
						
							| 
									
										
										
										
											2022-07-05 23:18:21 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     m_layout = new QBoxLayout(QBoxLayout::Direction::TopToBottom, this); | 
					
						
							| 
									
										
										
										
											2022-09-09 14:27:59 +02:00
										 |  |  |     m_layout->setSpacing(0); | 
					
						
							| 
									
										
										
										
											2022-07-05 23:18:21 +01:00
										 |  |  |     m_layout->setContentsMargins(0, 0, 0, 0); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-30 14:01:05 -04:00
										 |  |  |     m_view = new WebContentView(this, parent_client, page_index); | 
					
						
							| 
									
										
										
										
											2024-05-29 20:12:21 +01:00
										 |  |  |     m_find_in_page = new FindInPageWidget(this, m_view); | 
					
						
							|  |  |  |     m_find_in_page->setVisible(false); | 
					
						
							| 
									
										
										
										
											2022-10-01 12:46:24 -06:00
										 |  |  |     m_toolbar = new QToolBar(this); | 
					
						
							| 
									
										
										
										
											2023-01-19 01:12:13 +11:00
										 |  |  |     m_location_edit = new LocationEdit(this); | 
					
						
							| 
									
										
										
										
											2022-07-05 23:18:21 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-24 03:18:57 +03:00
										 |  |  |     m_hover_label = new HyperlinkLabel(this); | 
					
						
							| 
									
										
										
										
											2022-09-09 15:19:18 +02:00
										 |  |  |     m_hover_label->hide(); | 
					
						
							| 
									
										
										
										
											2022-09-09 14:23:36 +02:00
										 |  |  |     m_hover_label->setFrameShape(QFrame::Shape::Box); | 
					
						
							|  |  |  |     m_hover_label->setAutoFillBackground(true); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-24 03:18:57 +03:00
										 |  |  |     QObject::connect(m_hover_label, &HyperlinkLabel::mouse_entered, [this] { | 
					
						
							|  |  |  |         update_hover_label(); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-19 18:07:50 +02:00
										 |  |  |     auto* focus_location_editor_action = new QAction("Edit Location", this); | 
					
						
							| 
									
										
										
										
											2022-09-12 09:12:04 +02:00
										 |  |  |     focus_location_editor_action->setShortcut(QKeySequence("Ctrl+L")); | 
					
						
							|  |  |  |     addAction(focus_location_editor_action); | 
					
						
							| 
									
										
										
										
											2022-07-07 02:56:09 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-05 23:18:21 +01:00
										 |  |  |     m_layout->addWidget(m_toolbar); | 
					
						
							|  |  |  |     m_layout->addWidget(m_view); | 
					
						
							| 
									
										
										
										
											2024-05-29 20:12:21 +01:00
										 |  |  |     m_layout->addWidget(m_find_in_page); | 
					
						
							| 
									
										
										
										
											2022-07-05 23:18:21 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-05 16:11:51 +01:00
										 |  |  |     m_hamburger_button = new QToolButton(m_toolbar); | 
					
						
							|  |  |  |     m_hamburger_button->setText("Show &Menu"); | 
					
						
							|  |  |  |     m_hamburger_button->setToolTip("Show Menu"); | 
					
						
							|  |  |  |     m_hamburger_button->setIcon(create_tvg_icon_with_theme_colors("hamburger", palette())); | 
					
						
							|  |  |  |     m_hamburger_button->setPopupMode(QToolButton::InstantPopup); | 
					
						
							|  |  |  |     m_hamburger_button->setMenu(&m_window->hamburger_menu()); | 
					
						
							| 
									
										
										
										
											2024-05-06 13:49:08 +01:00
										 |  |  |     m_hamburger_button->setStyleSheet(":menu-indicator {image: none}"); | 
					
						
							| 
									
										
										
										
											2024-05-05 16:11:51 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-29 19:46:47 +01:00
										 |  |  |     recreate_toolbar_icons(); | 
					
						
							| 
									
										
										
										
											2023-05-05 15:38:46 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-29 06:53:53 -04:00
										 |  |  |     m_favicon = default_favicon(); | 
					
						
							| 
									
										
										
										
											2024-03-28 11:11:02 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-13 13:07:12 +01:00
										 |  |  |     m_toolbar->addAction(&m_window->go_back_action()); | 
					
						
							|  |  |  |     m_toolbar->addAction(&m_window->go_forward_action()); | 
					
						
							|  |  |  |     m_toolbar->addAction(&m_window->reload_action()); | 
					
						
							| 
									
										
										
										
											2022-07-05 23:18:21 +01:00
										 |  |  |     m_toolbar->addWidget(m_location_edit); | 
					
						
							| 
									
										
										
										
											2024-07-08 23:12:42 +01:00
										 |  |  |     m_toolbar->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); | 
					
						
							| 
									
										
										
										
											2024-05-05 16:11:51 +01:00
										 |  |  |     m_hamburger_button_action = m_toolbar->addWidget(m_hamburger_button); | 
					
						
							| 
									
										
										
										
											2023-07-30 23:25:32 +01:00
										 |  |  |     m_toolbar->setIconSize({ 16, 16 }); | 
					
						
							|  |  |  |     // This is a little awkward, but without this Qt shrinks the button to the size of the icon.
 | 
					
						
							|  |  |  |     // Note: toolButtonStyle="0" -> ToolButtonIconOnly.
 | 
					
						
							|  |  |  |     m_toolbar->setStyleSheet("QToolButton[toolButtonStyle=\"0\"]{width:24px;height:24px}"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-05 16:11:51 +01:00
										 |  |  |     m_hamburger_button_action->setVisible(!Settings::the()->show_menubar()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     QObject::connect(Settings::the(), &Settings::show_menubar_changed, this, [this](bool show_menubar) { | 
					
						
							|  |  |  |         m_hamburger_button_action->setVisible(!show_menubar); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-30 23:25:32 +01:00
										 |  |  |     m_reset_zoom_button = new QToolButton(m_toolbar); | 
					
						
							|  |  |  |     m_reset_zoom_button->setToolButtonStyle(Qt::ToolButtonTextOnly); | 
					
						
							| 
									
										
										
										
											2023-03-31 21:33:42 +01:00
										 |  |  |     m_reset_zoom_button->setToolTip("Reset zoom level"); | 
					
						
							| 
									
										
										
										
											2023-03-29 00:25:42 +01:00
										 |  |  |     m_reset_zoom_button_action = m_toolbar->addWidget(m_reset_zoom_button); | 
					
						
							|  |  |  |     m_reset_zoom_button_action->setVisible(false); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     QObject::connect(m_reset_zoom_button, &QAbstractButton::clicked, [this] { | 
					
						
							|  |  |  |         view().reset_zoom(); | 
					
						
							|  |  |  |         update_reset_zoom_button(); | 
					
						
							| 
									
										
										
										
											2023-08-04 13:37:52 +02:00
										 |  |  |         m_window->update_zoom_menu(); | 
					
						
							| 
									
										
										
										
											2023-03-29 00:25:42 +01:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-17 12:37:31 -04:00
										 |  |  |     view().on_activate_tab = [this] { | 
					
						
							| 
									
										
										
										
											2023-03-20 19:52:00 -04:00
										 |  |  |         m_window->activate_tab(tab_index()); | 
					
						
							| 
									
										
										
										
											2023-05-17 12:37:31 -04:00
										 |  |  |     }; | 
					
						
							| 
									
										
										
										
											2023-03-20 19:52:00 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-17 12:37:31 -04:00
										 |  |  |     view().on_close = [this] { | 
					
						
							| 
									
										
										
										
											2023-03-07 06:13:08 +03:00
										 |  |  |         m_window->close_tab(tab_index()); | 
					
						
							| 
									
										
										
										
											2023-05-17 12:37:31 -04:00
										 |  |  |     }; | 
					
						
							| 
									
										
										
										
											2023-03-07 06:13:08 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-17 12:37:31 -04:00
										 |  |  |     view().on_link_hover = [this](auto const& url) { | 
					
						
							| 
									
										
										
										
											2023-12-16 17:49:34 +03:30
										 |  |  |         m_hover_label->setText(qstring_from_ak_string(url.to_byte_string())); | 
					
						
							| 
									
										
										
										
											2022-09-09 14:23:36 +02:00
										 |  |  |         update_hover_label(); | 
					
						
							|  |  |  |         m_hover_label->show(); | 
					
						
							| 
									
										
										
										
											2023-05-17 12:37:31 -04:00
										 |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     view().on_link_unhover = [this]() { | 
					
						
							| 
									
										
										
										
											2022-09-09 14:23:36 +02:00
										 |  |  |         m_hover_label->hide(); | 
					
						
							| 
									
										
										
										
											2023-05-17 12:37:31 -04:00
										 |  |  |     }; | 
					
						
							| 
									
										
										
										
											2022-07-05 23:18:21 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-14 00:05:47 +02:00
										 |  |  |     view().on_load_start = [this](const URL::URL& url, bool) { | 
					
						
							|  |  |  |         if (m_inspector_widget) | 
					
						
							|  |  |  |             m_inspector_widget->reset(); | 
					
						
							| 
									
										
										
										
											2022-11-24 01:52:16 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-28 11:11:02 -04:00
										 |  |  |         auto url_serialized = qstring_from_ak_string(url.serialize()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         m_title = url_serialized; | 
					
						
							|  |  |  |         emit title_changed(tab_index(), url_serialized); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-29 06:53:53 -04:00
										 |  |  |         m_favicon = default_favicon(); | 
					
						
							|  |  |  |         emit favicon_changed(tab_index(), m_favicon); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-10 10:33:35 +01:00
										 |  |  |         m_location_edit->set_url(url); | 
					
						
							| 
									
										
										
										
											2023-02-01 19:51:56 +01:00
										 |  |  |         m_location_edit->setCursorPosition(0); | 
					
						
							| 
									
										
										
										
											2023-05-17 12:37:31 -04:00
										 |  |  |     }; | 
					
						
							| 
									
										
										
										
											2023-05-17 11:54:36 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     view().on_load_finish = [this](auto&) { | 
					
						
							| 
									
										
										
										
											2023-11-23 20:04:54 -05:00
										 |  |  |         if (m_inspector_widget != nullptr && m_inspector_widget->isVisible()) | 
					
						
							|  |  |  |             m_inspector_widget->inspect(); | 
					
						
							| 
									
										
										
										
											2023-05-17 11:54:36 -04:00
										 |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-14 00:05:47 +02:00
										 |  |  |     view().on_url_change = [this](auto const& url) { | 
					
						
							| 
									
										
										
										
											2024-06-10 10:33:35 +01:00
										 |  |  |         m_location_edit->set_url(url); | 
					
						
							| 
									
										
										
										
											2024-03-29 06:55:09 -04:00
										 |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-05 23:18:21 +01:00
										 |  |  |     QObject::connect(m_location_edit, &QLineEdit::returnPressed, this, &Tab::location_edit_return_pressed); | 
					
						
							| 
									
										
										
										
											2023-05-17 12:37:31 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     view().on_title_change = [this](auto const& title) { | 
					
						
							| 
									
										
										
										
											2023-12-04 09:55:47 -05:00
										 |  |  |         m_title = qstring_from_ak_string(title); | 
					
						
							| 
									
										
										
										
											2023-05-17 12:37:31 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         emit title_changed(tab_index(), m_title); | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     view().on_favicon_change = [this](auto const& bitmap) { | 
					
						
							|  |  |  |         auto qimage = QImage(bitmap.scanline_u8(0), bitmap.width(), bitmap.height(), QImage::Format_ARGB32); | 
					
						
							|  |  |  |         if (qimage.isNull()) | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  |         auto qpixmap = QPixmap::fromImage(qimage); | 
					
						
							|  |  |  |         if (qpixmap.isNull()) | 
					
						
							|  |  |  |             return; | 
					
						
							| 
									
										
										
										
											2024-03-28 11:11:02 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         m_favicon = qpixmap; | 
					
						
							|  |  |  |         emit favicon_changed(tab_index(), m_favicon); | 
					
						
							| 
									
										
										
										
											2023-05-17 12:37:31 -04:00
										 |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-17 14:23:34 -04:00
										 |  |  |     view().on_request_alert = [this](auto const& message) { | 
					
						
							|  |  |  |         m_dialog = new QMessageBox(QMessageBox::Icon::Warning, "Ladybird", qstring_from_ak_string(message), QMessageBox::StandardButton::Ok, &view()); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-25 13:43:53 -04:00
										 |  |  |         QObject::connect(m_dialog, &QDialog::finished, this, [this]() { | 
					
						
							|  |  |  |             view().alert_closed(); | 
					
						
							|  |  |  |             m_dialog = nullptr; | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         m_dialog->open(); | 
					
						
							| 
									
										
										
										
											2023-05-17 14:23:34 -04:00
										 |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     view().on_request_confirm = [this](auto const& message) { | 
					
						
							|  |  |  |         m_dialog = new QMessageBox(QMessageBox::Icon::Question, "Ladybird", qstring_from_ak_string(message), QMessageBox::StandardButton::Ok | QMessageBox::StandardButton::Cancel, &view()); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-25 13:43:53 -04:00
										 |  |  |         QObject::connect(m_dialog, &QDialog::finished, this, [this](auto result) { | 
					
						
							|  |  |  |             view().confirm_closed(result == QMessageBox::StandardButton::Ok || result == QDialog::Accepted); | 
					
						
							|  |  |  |             m_dialog = nullptr; | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         m_dialog->open(); | 
					
						
							| 
									
										
										
										
											2023-05-17 14:23:34 -04:00
										 |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     view().on_request_prompt = [this](auto const& message, auto const& default_) { | 
					
						
							|  |  |  |         m_dialog = new QInputDialog(&view()); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-25 13:43:53 -04:00
										 |  |  |         auto& dialog = static_cast<QInputDialog&>(*m_dialog); | 
					
						
							| 
									
										
										
										
											2023-05-17 14:23:34 -04:00
										 |  |  |         dialog.setWindowTitle("Ladybird"); | 
					
						
							|  |  |  |         dialog.setLabelText(qstring_from_ak_string(message)); | 
					
						
							|  |  |  |         dialog.setTextValue(qstring_from_ak_string(default_)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-25 13:43:53 -04:00
										 |  |  |         QObject::connect(m_dialog, &QDialog::finished, this, [this](auto result) { | 
					
						
							|  |  |  |             if (result == QDialog::Accepted) { | 
					
						
							|  |  |  |                 auto& dialog = static_cast<QInputDialog&>(*m_dialog); | 
					
						
							|  |  |  |                 view().prompt_closed(ak_string_from_qstring(dialog.textValue())); | 
					
						
							|  |  |  |             } else { | 
					
						
							|  |  |  |                 view().prompt_closed({}); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2023-05-17 14:23:34 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-25 13:43:53 -04:00
										 |  |  |             m_dialog = nullptr; | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         m_dialog->open(); | 
					
						
							| 
									
										
										
										
											2023-05-17 14:23:34 -04:00
										 |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     view().on_request_set_prompt_text = [this](auto const& message) { | 
					
						
							|  |  |  |         if (m_dialog && is<QInputDialog>(*m_dialog)) | 
					
						
							|  |  |  |             static_cast<QInputDialog&>(*m_dialog).setTextValue(qstring_from_ak_string(message)); | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     view().on_request_accept_dialog = [this]() { | 
					
						
							|  |  |  |         if (m_dialog) | 
					
						
							|  |  |  |             m_dialog->accept(); | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     view().on_request_dismiss_dialog = [this]() { | 
					
						
							|  |  |  |         if (m_dialog) | 
					
						
							|  |  |  |             m_dialog->reject(); | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-04 15:46:20 +02:00
										 |  |  |     view().on_request_color_picker = [this](Color current_color) { | 
					
						
							|  |  |  |         m_dialog = new QColorDialog(QColor(current_color.red(), current_color.green(), current_color.blue()), &view()); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-25 13:43:53 -04:00
										 |  |  |         auto& dialog = static_cast<QColorDialog&>(*m_dialog); | 
					
						
							| 
									
										
										
										
											2023-09-04 15:46:20 +02:00
										 |  |  |         dialog.setWindowTitle("Ladybird"); | 
					
						
							|  |  |  |         dialog.setOption(QColorDialog::ShowAlphaChannel, false); | 
					
						
							| 
									
										
										
										
											2024-04-24 06:53:44 -04:00
										 |  |  |         QObject::connect(&dialog, &QColorDialog::currentColorChanged, this, [this](QColor const& color) { | 
					
						
							| 
									
										
										
										
											2023-12-11 06:53:10 +01:00
										 |  |  |             view().color_picker_update(Color(color.red(), color.green(), color.blue()), Web::HTML::ColorPickerUpdateState::Update); | 
					
						
							|  |  |  |         }); | 
					
						
							| 
									
										
										
										
											2023-09-04 15:46:20 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-25 13:43:53 -04:00
										 |  |  |         QObject::connect(m_dialog, &QDialog::finished, this, [this](auto result) { | 
					
						
							|  |  |  |             if (result == QDialog::Accepted) { | 
					
						
							|  |  |  |                 auto& dialog = static_cast<QColorDialog&>(*m_dialog); | 
					
						
							|  |  |  |                 view().color_picker_update(Color(dialog.selectedColor().red(), dialog.selectedColor().green(), dialog.selectedColor().blue()), Web::HTML::ColorPickerUpdateState::Closed); | 
					
						
							|  |  |  |             } else { | 
					
						
							|  |  |  |                 view().color_picker_update({}, Web::HTML::ColorPickerUpdateState::Closed); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             m_dialog = nullptr; | 
					
						
							|  |  |  |         }); | 
					
						
							| 
									
										
										
										
											2023-09-04 15:46:20 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-25 13:43:53 -04:00
										 |  |  |         m_dialog->open(); | 
					
						
							| 
									
										
										
										
											2023-09-04 15:46:20 +02:00
										 |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-14 19:19:51 -04:00
										 |  |  |     view().on_request_file_picker = [this](auto const& accepted_file_types, auto allow_multiple_files) { | 
					
						
							| 
									
										
										
										
											2024-02-25 13:09:26 -05:00
										 |  |  |         Vector<Web::HTML::SelectedFile> selected_files; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         auto create_selected_file = [&](auto const& qfile_path) { | 
					
						
							|  |  |  |             auto file_path = ak_byte_string_from_qstring(qfile_path); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (auto file = Web::HTML::SelectedFile::from_file_path(file_path); file.is_error()) | 
					
						
							|  |  |  |                 warnln("Unable to open file {}: {}", file_path, file.error()); | 
					
						
							|  |  |  |             else | 
					
						
							|  |  |  |                 selected_files.append(file.release_value()); | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-14 19:19:51 -04:00
										 |  |  |         QStringList accepted_file_filters; | 
					
						
							|  |  |  |         QMimeDatabase mime_database; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for (auto const& filter : accepted_file_types.filters) { | 
					
						
							|  |  |  |             filter.visit( | 
					
						
							|  |  |  |                 [&](Web::HTML::FileFilter::FileType type) { | 
					
						
							|  |  |  |                     QString title; | 
					
						
							|  |  |  |                     QString filter; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     switch (type) { | 
					
						
							|  |  |  |                     case Web::HTML::FileFilter::FileType::Audio: | 
					
						
							|  |  |  |                         title = "Audio files"; | 
					
						
							|  |  |  |                         filter = "audio/"; | 
					
						
							|  |  |  |                         break; | 
					
						
							|  |  |  |                     case Web::HTML::FileFilter::FileType::Image: | 
					
						
							|  |  |  |                         title = "Image files"; | 
					
						
							|  |  |  |                         filter = "image/"; | 
					
						
							|  |  |  |                         break; | 
					
						
							|  |  |  |                     case Web::HTML::FileFilter::FileType::Video: | 
					
						
							|  |  |  |                         title = "Video files"; | 
					
						
							|  |  |  |                         filter = "video/"; | 
					
						
							|  |  |  |                         break; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     QStringList extensions; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     for (auto const& mime_type : mime_database.allMimeTypes()) { | 
					
						
							|  |  |  |                         if (mime_type.name().startsWith(filter)) | 
					
						
							|  |  |  |                             extensions.append(mime_type.globPatterns()); | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     accepted_file_filters.append(QString("%1 (%2)").arg(title, extensions.join(" "))); | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |                 [&](Web::HTML::FileFilter::MimeType const& filter) { | 
					
						
							|  |  |  |                     if (auto mime_type = mime_database.mimeTypeForName(qstring_from_ak_string(filter.value)); mime_type.isValid()) | 
					
						
							|  |  |  |                         accepted_file_filters.append(mime_type.filterString()); | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |                 [&](Web::HTML::FileFilter::Extension const& filter) { | 
					
						
							|  |  |  |                     auto extension = MUST(String::formatted("*.{}", filter.value)); | 
					
						
							|  |  |  |                     accepted_file_filters.append(qstring_from_ak_string(extension)); | 
					
						
							|  |  |  |                 }); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         accepted_file_filters.size() > 1 ? accepted_file_filters.prepend("All files (*)") : accepted_file_filters.append("All files (*)"); | 
					
						
							|  |  |  |         auto filters = accepted_file_filters.join(";;"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-25 13:09:26 -05:00
										 |  |  |         if (allow_multiple_files == Web::HTML::AllowMultipleFiles::Yes) { | 
					
						
							| 
									
										
										
										
											2024-03-14 19:19:51 -04:00
										 |  |  |             auto paths = QFileDialog::getOpenFileNames(this, "Select files", QDir::homePath(), filters); | 
					
						
							| 
									
										
										
										
											2024-02-25 13:09:26 -05:00
										 |  |  |             selected_files.ensure_capacity(static_cast<size_t>(paths.size())); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             for (auto const& path : paths) | 
					
						
							|  |  |  |                 create_selected_file(path); | 
					
						
							|  |  |  |         } else { | 
					
						
							| 
									
										
										
										
											2024-03-14 19:19:51 -04:00
										 |  |  |             auto path = QFileDialog::getOpenFileName(this, "Select file", QDir::homePath(), filters); | 
					
						
							| 
									
										
										
										
											2024-02-25 13:09:26 -05:00
										 |  |  |             create_selected_file(path); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         view().file_picker_closed(std::move(selected_files)); | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-09 19:25:17 +01:00
										 |  |  |     view().on_find_in_page = [this](auto current_match_index, auto const& total_match_count) { | 
					
						
							|  |  |  |         m_find_in_page->update_result_label(current_match_index, total_match_count); | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-12 09:12:04 +02:00
										 |  |  |     QObject::connect(focus_location_editor_action, &QAction::triggered, this, &Tab::focus_location_editor); | 
					
						
							| 
									
										
										
										
											2022-10-05 15:23:41 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-18 17:20:15 -04:00
										 |  |  |     view().on_received_source = [this](auto const& url, auto const& base_url, auto const& source) { | 
					
						
							|  |  |  |         auto html = WebView::highlight_source(url, base_url, source, Syntax::Language::HTML, WebView::HighlightOutputMode::FullDocument); | 
					
						
							| 
									
										
										
										
											2024-01-30 18:52:59 -07:00
										 |  |  |         m_window->new_tab_from_content(html, Web::HTML::ActivateTab::Yes); | 
					
						
							| 
									
										
										
										
											2023-05-17 12:37:31 -04:00
										 |  |  |     }; | 
					
						
							| 
									
										
										
										
											2022-10-07 13:35:40 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-23 11:18:35 +01:00
										 |  |  |     view().on_inspector_requested_style_sheet_source = [this](auto const& identifier) { | 
					
						
							|  |  |  |         view().request_style_sheet_source(identifier); | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-17 12:37:31 -04:00
										 |  |  |     view().on_restore_window = [this]() { | 
					
						
							| 
									
										
										
										
											2022-11-14 11:24:06 -05:00
										 |  |  |         m_window->showNormal(); | 
					
						
							| 
									
										
										
										
											2023-05-17 12:37:31 -04:00
										 |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     view().on_reposition_window = [this](auto const& position) { | 
					
						
							| 
									
										
										
										
											2022-11-14 11:24:06 -05:00
										 |  |  |         m_window->move(position.x(), position.y()); | 
					
						
							| 
									
										
										
										
											2024-10-28 23:37:11 -04:00
										 |  |  |         view().did_update_window_rect(); | 
					
						
							| 
									
										
										
										
											2023-05-17 12:37:31 -04:00
										 |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     view().on_resize_window = [this](auto const& size) { | 
					
						
							| 
									
										
										
										
											2022-11-14 11:24:06 -05:00
										 |  |  |         m_window->resize(size.width(), size.height()); | 
					
						
							| 
									
										
										
										
											2024-10-28 23:37:11 -04:00
										 |  |  |         view().did_update_window_rect(); | 
					
						
							| 
									
										
										
										
											2023-05-17 12:37:31 -04:00
										 |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     view().on_maximize_window = [this]() { | 
					
						
							| 
									
										
										
										
											2022-11-14 11:24:06 -05:00
										 |  |  |         m_window->showMaximized(); | 
					
						
							| 
									
										
										
										
											2024-10-28 23:45:18 -04:00
										 |  |  |         view().did_update_window_rect(); | 
					
						
							| 
									
										
										
										
											2023-05-17 12:37:31 -04:00
										 |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     view().on_minimize_window = [this]() { | 
					
						
							| 
									
										
										
										
											2022-11-14 11:24:06 -05:00
										 |  |  |         m_window->showMinimized(); | 
					
						
							| 
									
										
										
										
											2023-05-17 12:37:31 -04:00
										 |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     view().on_fullscreen_window = [this]() { | 
					
						
							| 
									
										
										
										
											2022-11-14 11:24:06 -05:00
										 |  |  |         m_window->showFullScreen(); | 
					
						
							| 
									
										
										
										
											2024-10-28 23:45:18 -04:00
										 |  |  |         view().did_update_window_rect(); | 
					
						
							| 
									
										
										
										
											2023-05-17 12:37:31 -04:00
										 |  |  |     }; | 
					
						
							| 
									
										
										
										
											2023-05-15 11:49:44 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-10 13:44:12 -05:00
										 |  |  |     view().on_insert_clipboard_entry = [](auto const& data, auto const&, auto const& mime_type) { | 
					
						
							|  |  |  |         QByteArray qdata { data.bytes_as_string_view().characters_without_null_termination(), static_cast<qsizetype>(data.bytes_as_string_view().length()) }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         auto* mime_data = new QMimeData(); | 
					
						
							|  |  |  |         mime_data->setData(qstring_from_ak_string(mime_type), qdata); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         auto* clipboard = QGuiApplication::clipboard(); | 
					
						
							|  |  |  |         clipboard->setMimeData(mime_data); | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-28 11:16:10 -04:00
										 |  |  |     view().on_audio_play_state_changed = [this](auto play_state) { | 
					
						
							|  |  |  |         emit audio_play_state_changed(tab_index(), play_state); | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-14 00:05:47 +02:00
										 |  |  |     view().on_navigation_buttons_state_changed = [this](auto back_enabled, auto forward_enabled) { | 
					
						
							|  |  |  |         m_can_navigate_back = back_enabled; | 
					
						
							|  |  |  |         m_can_navigate_forward = forward_enabled; | 
					
						
							|  |  |  |         emit navigation_buttons_state_changed(tab_index()); | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-28 15:07:23 +01:00
										 |  |  |     auto* reload_tab_action = new QAction("&Reload Tab", this); | 
					
						
							|  |  |  |     QObject::connect(reload_tab_action, &QAction::triggered, this, [this]() { | 
					
						
							|  |  |  |         reload(); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto* duplicate_tab_action = new QAction("&Duplicate Tab", this); | 
					
						
							|  |  |  |     QObject::connect(duplicate_tab_action, &QAction::triggered, this, [this]() { | 
					
						
							|  |  |  |         m_window->new_tab_from_url(view().url(), Web::HTML::ActivateTab::Yes); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto* move_to_start_action = new QAction("Move to &Start", this); | 
					
						
							|  |  |  |     QObject::connect(move_to_start_action, &QAction::triggered, this, [this]() { | 
					
						
							|  |  |  |         m_window->move_tab(tab_index(), 0); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto* move_to_end_action = new QAction("Move to &End", this); | 
					
						
							|  |  |  |     QObject::connect(move_to_end_action, &QAction::triggered, this, [this]() { | 
					
						
							|  |  |  |         m_window->move_tab(tab_index(), m_window->tab_count() - 1); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto* close_tab_action = new QAction("&Close Tab", this); | 
					
						
							|  |  |  |     QObject::connect(close_tab_action, &QAction::triggered, this, [this]() { | 
					
						
							|  |  |  |         view().on_close(); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto* close_tabs_to_left_action = new QAction("C&lose Tabs to Left", this); | 
					
						
							|  |  |  |     QObject::connect(close_tabs_to_left_action, &QAction::triggered, this, [this]() { | 
					
						
							|  |  |  |         for (auto i = tab_index() - 1; i >= 0; i--) { | 
					
						
							|  |  |  |             m_window->close_tab(i); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto* close_tabs_to_right_action = new QAction("Close Tabs to R&ight", this); | 
					
						
							|  |  |  |     QObject::connect(close_tabs_to_right_action, &QAction::triggered, this, [this]() { | 
					
						
							|  |  |  |         for (auto i = m_window->tab_count() - 1; i > tab_index(); i--) { | 
					
						
							|  |  |  |             m_window->close_tab(i); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto* close_other_tabs_action = new QAction("Cl&ose Other Tabs", this); | 
					
						
							|  |  |  |     QObject::connect(close_other_tabs_action, &QAction::triggered, this, [this]() { | 
					
						
							|  |  |  |         for (auto i = m_window->tab_count() - 1; i >= 0; i--) { | 
					
						
							|  |  |  |             if (i == tab_index()) | 
					
						
							|  |  |  |                 continue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             m_window->close_tab(i); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     m_context_menu = new QMenu("Context menu", this); | 
					
						
							|  |  |  |     m_context_menu->addAction(reload_tab_action); | 
					
						
							|  |  |  |     m_context_menu->addAction(duplicate_tab_action); | 
					
						
							|  |  |  |     m_context_menu->addSeparator(); | 
					
						
							|  |  |  |     auto* move_tab_menu = m_context_menu->addMenu("Mo&ve Tab"); | 
					
						
							|  |  |  |     move_tab_menu->addAction(move_to_start_action); | 
					
						
							|  |  |  |     move_tab_menu->addAction(move_to_end_action); | 
					
						
							|  |  |  |     m_context_menu->addSeparator(); | 
					
						
							|  |  |  |     m_context_menu->addAction(close_tab_action); | 
					
						
							|  |  |  |     auto* close_multiple_tabs_menu = m_context_menu->addMenu("Close &Multiple Tabs"); | 
					
						
							|  |  |  |     close_multiple_tabs_menu->addAction(close_tabs_to_left_action); | 
					
						
							|  |  |  |     close_multiple_tabs_menu->addAction(close_tabs_to_right_action); | 
					
						
							|  |  |  |     close_multiple_tabs_menu->addAction(close_other_tabs_action); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-23 12:49:53 -04:00
										 |  |  |     auto* search_selected_text_action = new QAction("&Search for <query>", this); | 
					
						
							| 
									
										
										
										
											2023-11-05 07:45:43 -05:00
										 |  |  |     search_selected_text_action->setIcon(load_icon_from_uri("resource://icons/16x16/find.png"sv)); | 
					
						
							| 
									
										
										
										
											2023-10-23 12:49:53 -04:00
										 |  |  |     QObject::connect(search_selected_text_action, &QAction::triggered, this, [this]() { | 
					
						
							| 
									
										
										
										
											2025-02-22 21:51:15 +13:00
										 |  |  |         auto url_string = MUST(String::formatted(Settings::the()->search_engine().query_url, URL::percent_encode(*m_page_context_menu_search_text))); | 
					
						
							|  |  |  |         auto url = URL::Parser::basic_parse(url_string); | 
					
						
							|  |  |  |         VERIFY(url.has_value()); | 
					
						
							|  |  |  |         m_window->new_tab_from_url(url.release_value(), Web::HTML::ActivateTab::Yes); | 
					
						
							| 
									
										
										
										
											2023-10-23 12:49:53 -04:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-06 10:00:03 -05:00
										 |  |  |     auto take_screenshot = [this](auto type) { | 
					
						
							|  |  |  |         auto& view = this->view(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         view.take_screenshot(type) | 
					
						
							|  |  |  |             ->when_resolved([this](auto const& path) { | 
					
						
							|  |  |  |                 auto message = MUST(String::formatted("Screenshot saved to: {}", path)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 QMessageBox dialog(this); | 
					
						
							|  |  |  |                 dialog.setWindowTitle("Ladybird"); | 
					
						
							|  |  |  |                 dialog.setIcon(QMessageBox::Information); | 
					
						
							|  |  |  |                 dialog.setText(qstring_from_ak_string(message)); | 
					
						
							|  |  |  |                 dialog.addButton(QMessageBox::Ok); | 
					
						
							|  |  |  |                 dialog.addButton(QMessageBox::Open)->setText("Open folder"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if (dialog.exec() == QMessageBox::Open) { | 
					
						
							|  |  |  |                     auto path_url = QUrl::fromLocalFile(qstring_from_ak_string(path.dirname())); | 
					
						
							|  |  |  |                     QDesktopServices::openUrl(path_url); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             }) | 
					
						
							|  |  |  |             .when_rejected([this](auto const& error) { | 
					
						
							| 
									
										
										
										
											2024-08-28 15:32:30 -04:00
										 |  |  |                 if (error.is_errno() && error.code() == ECANCELED) | 
					
						
							|  |  |  |                     return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-06 10:00:03 -05:00
										 |  |  |                 auto error_message = MUST(String::formatted("{}", error)); | 
					
						
							|  |  |  |                 QMessageBox::warning(this, "Ladybird", qstring_from_ak_string(error_message)); | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-16 07:56:12 -04:00
										 |  |  |     auto* take_visible_screenshot_action = new QAction("Take &Visible Screenshot", this); | 
					
						
							| 
									
										
										
										
											2023-11-05 07:45:43 -05:00
										 |  |  |     take_visible_screenshot_action->setIcon(load_icon_from_uri("resource://icons/16x16/filetype-image.png"sv)); | 
					
						
							| 
									
										
										
										
											2024-01-06 10:00:03 -05:00
										 |  |  |     QObject::connect(take_visible_screenshot_action, &QAction::triggered, this, [take_screenshot]() { | 
					
						
							|  |  |  |         take_screenshot(WebView::ViewImplementation::ScreenshotType::Visible); | 
					
						
							| 
									
										
										
										
											2023-05-16 07:56:12 -04:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto* take_full_screenshot_action = new QAction("Take &Full Screenshot", this); | 
					
						
							| 
									
										
										
										
											2023-11-05 07:45:43 -05:00
										 |  |  |     take_full_screenshot_action->setIcon(load_icon_from_uri("resource://icons/16x16/filetype-image.png"sv)); | 
					
						
							| 
									
										
										
										
											2024-01-06 10:00:03 -05:00
										 |  |  |     QObject::connect(take_full_screenshot_action, &QAction::triggered, this, [take_screenshot]() { | 
					
						
							|  |  |  |         take_screenshot(WebView::ViewImplementation::ScreenshotType::Full); | 
					
						
							| 
									
										
										
										
											2023-05-16 07:56:12 -04:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-04 09:39:22 -05:00
										 |  |  |     m_page_context_menu = new QMenu("Context menu", this); | 
					
						
							| 
									
										
										
										
											2023-05-15 11:49:44 -04:00
										 |  |  |     m_page_context_menu->addAction(&m_window->go_back_action()); | 
					
						
							|  |  |  |     m_page_context_menu->addAction(&m_window->go_forward_action()); | 
					
						
							|  |  |  |     m_page_context_menu->addAction(&m_window->reload_action()); | 
					
						
							|  |  |  |     m_page_context_menu->addSeparator(); | 
					
						
							|  |  |  |     m_page_context_menu->addAction(&m_window->copy_selection_action()); | 
					
						
							| 
									
										
										
										
											2024-03-22 11:56:49 +01:00
										 |  |  |     m_page_context_menu->addAction(&m_window->paste_action()); | 
					
						
							| 
									
										
										
										
											2023-05-15 11:49:44 -04:00
										 |  |  |     m_page_context_menu->addAction(&m_window->select_all_action()); | 
					
						
							|  |  |  |     m_page_context_menu->addSeparator(); | 
					
						
							| 
									
										
										
										
											2023-10-23 12:49:53 -04:00
										 |  |  |     m_page_context_menu->addAction(search_selected_text_action); | 
					
						
							|  |  |  |     m_page_context_menu->addSeparator(); | 
					
						
							| 
									
										
										
										
											2023-05-16 07:56:12 -04:00
										 |  |  |     m_page_context_menu->addAction(take_visible_screenshot_action); | 
					
						
							|  |  |  |     m_page_context_menu->addAction(take_full_screenshot_action); | 
					
						
							|  |  |  |     m_page_context_menu->addSeparator(); | 
					
						
							| 
									
										
										
										
											2023-05-15 11:49:44 -04:00
										 |  |  |     m_page_context_menu->addAction(&m_window->view_source_action()); | 
					
						
							|  |  |  |     m_page_context_menu->addAction(&m_window->inspect_dom_node_action()); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-12 22:33:36 +01:00
										 |  |  |     view().on_context_menu_request = [this, search_selected_text_action](Gfx::IntPoint content_position) { | 
					
						
							| 
									
										
										
										
											2023-10-23 12:49:53 -04:00
										 |  |  |         auto selected_text = Settings::the()->enable_search() | 
					
						
							|  |  |  |             ? view().selected_text_with_whitespace_collapsed() | 
					
						
							|  |  |  |             : OptionalNone {}; | 
					
						
							|  |  |  |         TemporaryChange change_url { m_page_context_menu_search_text, std::move(selected_text) }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (m_page_context_menu_search_text.has_value()) { | 
					
						
							|  |  |  |             auto action_text = WebView::format_search_query_for_display(Settings::the()->search_engine().query_url, *m_page_context_menu_search_text); | 
					
						
							|  |  |  |             search_selected_text_action->setText(qstring_from_ak_string(action_text)); | 
					
						
							|  |  |  |             search_selected_text_action->setVisible(true); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             search_selected_text_action->setVisible(false); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-10 22:15:06 -04:00
										 |  |  |         m_page_context_menu->exec(view().map_point_to_global_position(content_position)); | 
					
						
							| 
									
										
										
										
											2023-05-15 11:49:44 -04:00
										 |  |  |     }; | 
					
						
							| 
									
										
										
										
											2023-05-15 12:27:10 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-23 17:20:51 -05:00
										 |  |  |     auto* open_link_in_new_tab_action = new QAction("Open Link in New &Tab", this); | 
					
						
							| 
									
										
										
										
											2023-11-05 07:45:43 -05:00
										 |  |  |     open_link_in_new_tab_action->setIcon(load_icon_from_uri("resource://icons/16x16/new-tab.png"sv)); | 
					
						
							| 
									
										
										
										
											2023-05-15 12:48:46 -04:00
										 |  |  |     QObject::connect(open_link_in_new_tab_action, &QAction::triggered, this, [this]() { | 
					
						
							|  |  |  |         open_link_in_new_tab(m_link_context_menu_url); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-23 17:20:51 -05:00
										 |  |  |     m_link_context_menu_copy_url_action = new QAction("Copy &Link Address", this); | 
					
						
							| 
									
										
										
										
											2023-12-05 13:04:15 +00:00
										 |  |  |     m_link_context_menu_copy_url_action->setIcon(load_icon_from_uri("resource://icons/16x16/edit-copy.png"sv)); | 
					
						
							|  |  |  |     QObject::connect(m_link_context_menu_copy_url_action, &QAction::triggered, this, [this]() { | 
					
						
							| 
									
										
										
										
											2023-05-15 12:48:46 -04:00
										 |  |  |         copy_link_url(m_link_context_menu_url); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-04 09:39:22 -05:00
										 |  |  |     m_link_context_menu = new QMenu("Link context menu", this); | 
					
						
							| 
									
										
										
										
											2023-05-15 12:48:46 -04:00
										 |  |  |     m_link_context_menu->addAction(open_link_in_new_tab_action); | 
					
						
							| 
									
										
										
										
											2023-12-05 13:04:15 +00:00
										 |  |  |     m_link_context_menu->addAction(m_link_context_menu_copy_url_action); | 
					
						
							| 
									
										
										
										
											2023-05-15 12:48:46 -04:00
										 |  |  |     m_link_context_menu->addSeparator(); | 
					
						
							|  |  |  |     m_link_context_menu->addAction(&m_window->inspect_dom_node_action()); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-12 22:33:36 +01:00
										 |  |  |     view().on_link_context_menu_request = [this](auto const& url, Gfx::IntPoint content_position) { | 
					
						
							| 
									
										
										
										
											2023-05-15 12:48:46 -04:00
										 |  |  |         m_link_context_menu_url = url; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-05 13:04:15 +00:00
										 |  |  |         switch (WebView::url_type(url)) { | 
					
						
							|  |  |  |         case WebView::URLType::Email: | 
					
						
							|  |  |  |             m_link_context_menu_copy_url_action->setText("Copy &Email Address"); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         case WebView::URLType::Telephone: | 
					
						
							|  |  |  |             m_link_context_menu_copy_url_action->setText("Copy &Phone Number"); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         case WebView::URLType::Other: | 
					
						
							| 
									
										
										
										
											2024-09-23 17:20:51 -05:00
										 |  |  |             m_link_context_menu_copy_url_action->setText("Copy &Link Address"); | 
					
						
							| 
									
										
										
										
											2023-12-05 13:04:15 +00:00
										 |  |  |             break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-10 22:15:06 -04:00
										 |  |  |         m_link_context_menu->exec(view().map_point_to_global_position(content_position)); | 
					
						
							| 
									
										
										
										
											2023-05-15 12:48:46 -04:00
										 |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-15 13:43:58 -04:00
										 |  |  |     auto* open_image_action = new QAction("&Open Image", this); | 
					
						
							| 
									
										
										
										
											2023-11-05 07:45:43 -05:00
										 |  |  |     open_image_action->setIcon(load_icon_from_uri("resource://icons/16x16/filetype-image.png"sv)); | 
					
						
							| 
									
										
										
										
											2023-05-15 13:43:58 -04:00
										 |  |  |     QObject::connect(open_image_action, &QAction::triggered, this, [this]() { | 
					
						
							|  |  |  |         open_link(m_image_context_menu_url); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto* open_image_in_new_tab_action = new QAction("&Open Image in New &Tab", this); | 
					
						
							| 
									
										
										
										
											2023-11-05 07:45:43 -05:00
										 |  |  |     open_image_in_new_tab_action->setIcon(load_icon_from_uri("resource://icons/16x16/new-tab.png"sv)); | 
					
						
							| 
									
										
										
										
											2023-05-15 13:43:58 -04:00
										 |  |  |     QObject::connect(open_image_in_new_tab_action, &QAction::triggered, this, [this]() { | 
					
						
							|  |  |  |         open_link_in_new_tab(m_image_context_menu_url); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-10 20:33:27 +11:00
										 |  |  |     m_image_context_menu_copy_image_action = new QAction("&Copy Image", this); | 
					
						
							|  |  |  |     m_image_context_menu_copy_image_action->setIcon(load_icon_from_uri("resource://icons/16x16/edit-copy.png"sv)); | 
					
						
							|  |  |  |     QObject::connect(m_image_context_menu_copy_image_action, &QAction::triggered, this, [this]() { | 
					
						
							|  |  |  |         if (!m_image_context_menu_bitmap.has_value()) | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         auto* bitmap = m_image_context_menu_bitmap.value().bitmap(); | 
					
						
							| 
									
										
										
										
											2023-05-15 13:43:58 -04:00
										 |  |  |         if (bitmap == nullptr) | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         auto data = Gfx::BMPWriter::encode(*bitmap); | 
					
						
							|  |  |  |         if (data.is_error()) | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         auto image = QImage::fromData(data.value().data(), data.value().size(), "BMP"); | 
					
						
							|  |  |  |         if (image.isNull()) | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         auto* clipboard = QGuiApplication::clipboard(); | 
					
						
							|  |  |  |         clipboard->setImage(image); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto* copy_image_url_action = new QAction("Copy Image &URL", this); | 
					
						
							| 
									
										
										
										
											2023-11-05 07:45:43 -05:00
										 |  |  |     copy_image_url_action->setIcon(load_icon_from_uri("resource://icons/16x16/edit-copy.png"sv)); | 
					
						
							| 
									
										
										
										
											2023-05-15 13:43:58 -04:00
										 |  |  |     QObject::connect(copy_image_url_action, &QAction::triggered, this, [this]() { | 
					
						
							|  |  |  |         copy_link_url(m_image_context_menu_url); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-04 09:39:22 -05:00
										 |  |  |     m_image_context_menu = new QMenu("Image context menu", this); | 
					
						
							| 
									
										
										
										
											2023-05-15 13:43:58 -04:00
										 |  |  |     m_image_context_menu->addAction(open_image_action); | 
					
						
							|  |  |  |     m_image_context_menu->addAction(open_image_in_new_tab_action); | 
					
						
							|  |  |  |     m_image_context_menu->addSeparator(); | 
					
						
							| 
									
										
										
										
											2025-01-10 20:33:27 +11:00
										 |  |  |     m_image_context_menu->addAction(m_image_context_menu_copy_image_action); | 
					
						
							| 
									
										
										
										
											2023-05-15 13:43:58 -04:00
										 |  |  |     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()); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-10 20:33:27 +11:00
										 |  |  |     view().on_image_context_menu_request = [this](auto& image_url, Gfx::IntPoint content_position, Optional<Gfx::ShareableBitmap> const& shareable_bitmap) { | 
					
						
							| 
									
										
										
										
											2023-05-15 13:43:58 -04:00
										 |  |  |         m_image_context_menu_url = image_url; | 
					
						
							|  |  |  |         m_image_context_menu_bitmap = shareable_bitmap; | 
					
						
							| 
									
										
										
										
											2025-01-10 20:33:27 +11:00
										 |  |  |         m_image_context_menu_copy_image_action->setEnabled(shareable_bitmap.has_value()); | 
					
						
							| 
									
										
										
										
											2023-05-15 13:43:58 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-10 22:15:06 -04:00
										 |  |  |         m_image_context_menu->exec(view().map_point_to_global_position(content_position)); | 
					
						
							| 
									
										
										
										
											2023-05-15 13:43:58 -04:00
										 |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-05 07:45:43 -05:00
										 |  |  |     m_media_context_menu_play_icon = load_icon_from_uri("resource://icons/16x16/play.png"sv); | 
					
						
							|  |  |  |     m_media_context_menu_pause_icon = load_icon_from_uri("resource://icons/16x16/pause.png"sv); | 
					
						
							|  |  |  |     m_media_context_menu_mute_icon = load_icon_from_uri("resource://icons/16x16/audio-volume-muted.png"sv); | 
					
						
							|  |  |  |     m_media_context_menu_unmute_icon = load_icon_from_uri("resource://icons/16x16/audio-volume-high.png"sv); | 
					
						
							| 
									
										
										
										
											2023-05-15 12:27:10 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-04 09:39:22 -05:00
										 |  |  |     m_media_context_menu_play_pause_action = new QAction("&Play", this); | 
					
						
							| 
									
										
										
										
											2023-11-05 07:45:43 -05:00
										 |  |  |     m_media_context_menu_play_pause_action->setIcon(m_media_context_menu_play_icon); | 
					
						
							| 
									
										
										
										
											2023-06-16 10:51:38 -04:00
										 |  |  |     QObject::connect(m_media_context_menu_play_pause_action, &QAction::triggered, this, [this]() { | 
					
						
							|  |  |  |         view().toggle_media_play_state(); | 
					
						
							| 
									
										
										
										
											2023-05-15 12:27:10 -04:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-04 09:39:22 -05:00
										 |  |  |     m_media_context_menu_mute_unmute_action = new QAction("&Mute", this); | 
					
						
							| 
									
										
										
										
											2023-11-05 07:45:43 -05:00
										 |  |  |     m_media_context_menu_mute_unmute_action->setIcon(m_media_context_menu_mute_icon); | 
					
						
							| 
									
										
										
										
											2023-06-16 11:29:54 -04:00
										 |  |  |     QObject::connect(m_media_context_menu_mute_unmute_action, &QAction::triggered, this, [this]() { | 
					
						
							|  |  |  |         view().toggle_media_mute_state(); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-04 09:39:22 -05:00
										 |  |  |     m_media_context_menu_controls_action = new QAction("Show &Controls", this); | 
					
						
							| 
									
										
										
										
											2023-06-16 10:51:38 -04:00
										 |  |  |     m_media_context_menu_controls_action->setCheckable(true); | 
					
						
							|  |  |  |     QObject::connect(m_media_context_menu_controls_action, &QAction::triggered, this, [this]() { | 
					
						
							|  |  |  |         view().toggle_media_controls_state(); | 
					
						
							| 
									
										
										
										
											2023-05-15 12:27:10 -04:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-04 09:39:22 -05:00
										 |  |  |     m_media_context_menu_loop_action = new QAction("&Loop", this); | 
					
						
							| 
									
										
										
										
											2023-06-16 10:51:38 -04:00
										 |  |  |     m_media_context_menu_loop_action->setCheckable(true); | 
					
						
							|  |  |  |     QObject::connect(m_media_context_menu_loop_action, &QAction::triggered, this, [this]() { | 
					
						
							|  |  |  |         view().toggle_media_loop_state(); | 
					
						
							| 
									
										
										
										
											2023-05-15 12:27:10 -04:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-19 07:15:13 -04:00
										 |  |  |     auto* open_audio_action = new QAction("&Open Audio", this); | 
					
						
							| 
									
										
										
										
											2023-11-05 07:45:43 -05:00
										 |  |  |     open_audio_action->setIcon(load_icon_from_uri("resource://icons/16x16/filetype-sound.png"sv)); | 
					
						
							| 
									
										
										
										
											2023-06-19 07:15:13 -04:00
										 |  |  |     QObject::connect(open_audio_action, &QAction::triggered, this, [this]() { | 
					
						
							|  |  |  |         open_link(m_media_context_menu_url); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto* open_audio_in_new_tab_action = new QAction("Open Audio in New &Tab", this); | 
					
						
							| 
									
										
										
										
											2023-11-05 07:45:43 -05:00
										 |  |  |     open_audio_in_new_tab_action->setIcon(load_icon_from_uri("resource://icons/16x16/new-tab.png"sv)); | 
					
						
							| 
									
										
										
										
											2023-06-19 07:15:13 -04:00
										 |  |  |     QObject::connect(open_audio_in_new_tab_action, &QAction::triggered, this, [this]() { | 
					
						
							|  |  |  |         open_link_in_new_tab(m_media_context_menu_url); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-16 11:05:15 -04:00
										 |  |  |     auto* copy_audio_url_action = new QAction("Copy Audio &URL", this); | 
					
						
							| 
									
										
										
										
											2023-11-05 07:45:43 -05:00
										 |  |  |     copy_audio_url_action->setIcon(load_icon_from_uri("resource://icons/16x16/edit-copy.png"sv)); | 
					
						
							| 
									
										
										
										
											2023-06-16 11:05:15 -04:00
										 |  |  |     QObject::connect(copy_audio_url_action, &QAction::triggered, this, [this]() { | 
					
						
							|  |  |  |         copy_link_url(m_media_context_menu_url); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-04 09:39:22 -05:00
										 |  |  |     m_audio_context_menu = new QMenu("Audio context menu", this); | 
					
						
							| 
									
										
										
										
											2023-06-16 11:05:15 -04:00
										 |  |  |     m_audio_context_menu->addAction(m_media_context_menu_play_pause_action); | 
					
						
							| 
									
										
										
										
											2023-06-16 11:29:54 -04:00
										 |  |  |     m_audio_context_menu->addAction(m_media_context_menu_mute_unmute_action); | 
					
						
							| 
									
										
										
										
											2023-06-16 11:05:15 -04:00
										 |  |  |     m_audio_context_menu->addAction(m_media_context_menu_controls_action); | 
					
						
							|  |  |  |     m_audio_context_menu->addAction(m_media_context_menu_loop_action); | 
					
						
							|  |  |  |     m_audio_context_menu->addSeparator(); | 
					
						
							| 
									
										
										
										
											2023-06-19 07:15:13 -04:00
										 |  |  |     m_audio_context_menu->addAction(open_audio_action); | 
					
						
							|  |  |  |     m_audio_context_menu->addAction(open_audio_in_new_tab_action); | 
					
						
							|  |  |  |     m_audio_context_menu->addSeparator(); | 
					
						
							| 
									
										
										
										
											2023-06-16 11:05:15 -04:00
										 |  |  |     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()); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-15 12:27:10 -04:00
										 |  |  |     auto* open_video_action = new QAction("&Open Video", this); | 
					
						
							| 
									
										
										
										
											2023-11-05 07:45:43 -05:00
										 |  |  |     open_video_action->setIcon(load_icon_from_uri("resource://icons/16x16/filetype-video.png"sv)); | 
					
						
							| 
									
										
										
										
											2023-05-15 12:27:10 -04:00
										 |  |  |     QObject::connect(open_video_action, &QAction::triggered, this, [this]() { | 
					
						
							| 
									
										
										
										
											2023-06-16 10:51:38 -04:00
										 |  |  |         open_link(m_media_context_menu_url); | 
					
						
							| 
									
										
										
										
											2023-05-15 12:27:10 -04:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto* open_video_in_new_tab_action = new QAction("Open Video in New &Tab", this); | 
					
						
							| 
									
										
										
										
											2023-11-05 07:45:43 -05:00
										 |  |  |     open_video_in_new_tab_action->setIcon(load_icon_from_uri("resource://icons/16x16/new-tab.png"sv)); | 
					
						
							| 
									
										
										
										
											2023-05-15 12:27:10 -04:00
										 |  |  |     QObject::connect(open_video_in_new_tab_action, &QAction::triggered, this, [this]() { | 
					
						
							| 
									
										
										
										
											2023-06-16 10:51:38 -04:00
										 |  |  |         open_link_in_new_tab(m_media_context_menu_url); | 
					
						
							| 
									
										
										
										
											2023-05-15 12:27:10 -04:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     auto* copy_video_url_action = new QAction("Copy Video &URL", this); | 
					
						
							| 
									
										
										
										
											2023-11-05 07:45:43 -05:00
										 |  |  |     copy_video_url_action->setIcon(load_icon_from_uri("resource://icons/16x16/edit-copy.png"sv)); | 
					
						
							| 
									
										
										
										
											2023-05-15 12:27:10 -04:00
										 |  |  |     QObject::connect(copy_video_url_action, &QAction::triggered, this, [this]() { | 
					
						
							| 
									
										
										
										
											2023-06-16 10:51:38 -04:00
										 |  |  |         copy_link_url(m_media_context_menu_url); | 
					
						
							| 
									
										
										
										
											2023-05-15 12:27:10 -04:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-04 09:39:22 -05:00
										 |  |  |     m_video_context_menu = new QMenu("Video context menu", this); | 
					
						
							| 
									
										
										
										
											2023-06-16 10:51:38 -04:00
										 |  |  |     m_video_context_menu->addAction(m_media_context_menu_play_pause_action); | 
					
						
							| 
									
										
										
										
											2023-06-16 11:29:54 -04:00
										 |  |  |     m_video_context_menu->addAction(m_media_context_menu_mute_unmute_action); | 
					
						
							| 
									
										
										
										
											2023-06-16 10:51:38 -04:00
										 |  |  |     m_video_context_menu->addAction(m_media_context_menu_controls_action); | 
					
						
							|  |  |  |     m_video_context_menu->addAction(m_media_context_menu_loop_action); | 
					
						
							| 
									
										
										
										
											2023-05-15 12:27:10 -04:00
										 |  |  |     m_video_context_menu->addSeparator(); | 
					
						
							|  |  |  |     m_video_context_menu->addAction(open_video_action); | 
					
						
							|  |  |  |     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()); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-12 22:33:36 +01:00
										 |  |  |     view().on_media_context_menu_request = [this](Gfx::IntPoint content_position, Web::Page::MediaContextMenu const& menu) { | 
					
						
							| 
									
										
										
										
											2023-06-16 10:51:38 -04:00
										 |  |  |         m_media_context_menu_url = menu.media_url; | 
					
						
							| 
									
										
										
										
											2023-05-15 12:27:10 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-16 10:51:38 -04:00
										 |  |  |         if (menu.is_playing) { | 
					
						
							| 
									
										
										
										
											2023-11-05 07:45:43 -05:00
										 |  |  |             m_media_context_menu_play_pause_action->setIcon(m_media_context_menu_pause_icon); | 
					
						
							| 
									
										
										
										
											2023-06-16 10:51:38 -04:00
										 |  |  |             m_media_context_menu_play_pause_action->setText("&Pause"); | 
					
						
							| 
									
										
										
										
											2023-05-15 12:27:10 -04:00
										 |  |  |         } else { | 
					
						
							| 
									
										
										
										
											2023-11-05 07:45:43 -05:00
										 |  |  |             m_media_context_menu_play_pause_action->setIcon(m_media_context_menu_play_icon); | 
					
						
							| 
									
										
										
										
											2023-06-16 10:51:38 -04:00
										 |  |  |             m_media_context_menu_play_pause_action->setText("&Play"); | 
					
						
							| 
									
										
										
										
											2023-05-15 12:27:10 -04:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-16 11:29:54 -04:00
										 |  |  |         if (menu.is_muted) { | 
					
						
							| 
									
										
										
										
											2023-11-05 07:45:43 -05:00
										 |  |  |             m_media_context_menu_mute_unmute_action->setIcon(m_media_context_menu_unmute_icon); | 
					
						
							| 
									
										
										
										
											2023-06-16 11:29:54 -04:00
										 |  |  |             m_media_context_menu_mute_unmute_action->setText("Un&mute"); | 
					
						
							|  |  |  |         } else { | 
					
						
							| 
									
										
										
										
											2023-11-05 07:45:43 -05:00
										 |  |  |             m_media_context_menu_mute_unmute_action->setIcon(m_media_context_menu_mute_icon); | 
					
						
							| 
									
										
										
										
											2023-06-16 11:29:54 -04:00
										 |  |  |             m_media_context_menu_mute_unmute_action->setText("&Mute"); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-16 10:51:38 -04:00
										 |  |  |         m_media_context_menu_controls_action->setChecked(menu.has_user_agent_controls); | 
					
						
							|  |  |  |         m_media_context_menu_loop_action->setChecked(menu.is_looping); | 
					
						
							| 
									
										
										
										
											2023-05-15 12:27:10 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-10 22:15:06 -04:00
										 |  |  |         auto screen_position = view().map_point_to_global_position(content_position); | 
					
						
							| 
									
										
										
										
											2023-06-16 10:51:38 -04:00
										 |  |  |         if (menu.is_video) | 
					
						
							|  |  |  |             m_video_context_menu->exec(screen_position); | 
					
						
							| 
									
										
										
										
											2023-06-16 11:05:15 -04:00
										 |  |  |         else | 
					
						
							|  |  |  |             m_audio_context_menu->exec(screen_position); | 
					
						
							| 
									
										
										
										
											2023-05-15 12:27:10 -04:00
										 |  |  |     }; | 
					
						
							| 
									
										
										
										
											2022-09-12 09:12:04 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-17 11:54:36 -04:00
										 |  |  | Tab::~Tab() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     close_sub_widgets(); | 
					
						
							| 
									
										
										
										
											2023-12-29 09:05:05 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // 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; | 
					
						
							| 
									
										
										
										
											2023-05-17 11:54:36 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-29 00:25:42 +01:00
										 |  |  | void Tab::update_reset_zoom_button() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     auto zoom_level = view().zoom_level(); | 
					
						
							|  |  |  |     if (zoom_level != 1.0f) { | 
					
						
							|  |  |  |         auto zoom_level_text = MUST(String::formatted("{}%", round_to<int>(zoom_level * 100))); | 
					
						
							|  |  |  |         m_reset_zoom_button->setText(qstring_from_ak_string(zoom_level_text)); | 
					
						
							|  |  |  |         m_reset_zoom_button_action->setVisible(true); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         m_reset_zoom_button_action->setVisible(false); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-12 09:12:04 +02:00
										 |  |  | void Tab::focus_location_editor() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_location_edit->setFocus(); | 
					
						
							|  |  |  |     m_location_edit->selectAll(); | 
					
						
							| 
									
										
										
										
											2022-07-06 14:38:50 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-18 16:22:27 +13:00
										 |  |  | void Tab::navigate(URL::URL const& url) | 
					
						
							| 
									
										
										
										
											2022-07-06 14:38:50 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-01-30 19:15:55 -07:00
										 |  |  |     view().load(url); | 
					
						
							| 
									
										
										
										
											2022-07-06 14:38:50 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-17 17:12:17 +02:00
										 |  |  | void Tab::load_html(StringView html) | 
					
						
							| 
									
										
										
										
											2023-08-28 16:14:34 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2023-09-17 17:12:17 +02:00
										 |  |  |     view().load_html(html); | 
					
						
							| 
									
										
										
										
											2023-08-28 16:14:34 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-06 14:38:50 +01:00
										 |  |  | void Tab::back() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2024-04-14 00:05:47 +02:00
										 |  |  |     view().traverse_the_history_by_delta(-1); | 
					
						
							| 
									
										
										
										
											2022-07-06 14:38:50 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Tab::forward() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2024-04-14 00:05:47 +02:00
										 |  |  |     view().traverse_the_history_by_delta(1); | 
					
						
							| 
									
										
										
										
											2022-07-06 14:38:50 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-05 23:18:21 +01:00
										 |  |  | void Tab::reload() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2024-04-13 18:53:41 +02:00
										 |  |  |     view().reload(); | 
					
						
							| 
									
										
										
										
											2022-07-05 23:18:21 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-18 16:22:27 +13:00
										 |  |  | void Tab::open_link(URL::URL const& url) | 
					
						
							| 
									
										
										
										
											2023-05-15 12:27:10 -04:00
										 |  |  | { | 
					
						
							|  |  |  |     view().on_link_click(url, "", 0); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-18 16:22:27 +13:00
										 |  |  | void Tab::open_link_in_new_tab(URL::URL const& url) | 
					
						
							| 
									
										
										
										
											2023-05-15 12:27:10 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-08-12 12:50:56 +01:00
										 |  |  |     view().on_link_click(url, "_blank", Web::UIEvents::Mod_Ctrl); | 
					
						
							| 
									
										
										
										
											2023-05-15 12:27:10 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-18 16:22:27 +13:00
										 |  |  | void Tab::copy_link_url(URL::URL const& url) | 
					
						
							| 
									
										
										
										
											2023-05-15 12:27:10 -04:00
										 |  |  | { | 
					
						
							|  |  |  |     auto* clipboard = QGuiApplication::clipboard(); | 
					
						
							| 
									
										
										
										
											2023-12-05 13:04:15 +00:00
										 |  |  |     clipboard->setText(qstring_from_ak_string(WebView::url_text_to_copy(url))); | 
					
						
							| 
									
										
										
										
											2023-05-15 12:27:10 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-05 23:18:21 +01:00
										 |  |  | void Tab::location_edit_return_pressed() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2024-09-19 12:38:31 +00:00
										 |  |  |     if (m_location_edit->text().isEmpty()) | 
					
						
							|  |  |  |         return; | 
					
						
							| 
									
										
										
										
											2024-06-10 10:33:35 +01:00
										 |  |  |     navigate(m_location_edit->url()); | 
					
						
							| 
									
										
										
										
											2022-07-05 23:18:21 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-25 23:47:12 +02:00
										 |  |  | void Tab::open_file() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2024-01-30 19:29:00 -07:00
										 |  |  |     auto filename = QFileDialog::getOpenFileUrl(this, "Open file", QDir::homePath(), "All Files (*.*)"); | 
					
						
							|  |  |  |     if (filename.isValid()) { | 
					
						
							|  |  |  |         navigate(ak_url_from_qurl(filename)); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-05-25 23:47:12 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-05 23:18:21 +01:00
										 |  |  | int Tab::tab_index() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2022-09-21 21:17:13 +02:00
										 |  |  |     return m_window->tab_index(this); | 
					
						
							| 
									
										
										
										
											2022-07-05 23:18:21 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2022-07-08 14:14:40 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-12-16 17:49:34 +03:30
										 |  |  | void Tab::debug_request(ByteString const& request, ByteString const& argument) | 
					
						
							| 
									
										
										
										
											2022-07-08 14:14:40 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-04-14 00:05:47 +02:00
										 |  |  |     m_view->debug_request(request, argument); | 
					
						
							| 
									
										
										
										
											2022-07-08 14:14:40 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2022-09-09 14:23:36 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | void Tab::resizeEvent(QResizeEvent* event) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QWidget::resizeEvent(event); | 
					
						
							|  |  |  |     if (m_hover_label->isVisible()) | 
					
						
							|  |  |  |         update_hover_label(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Tab::update_hover_label() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2024-08-24 03:18:57 +03:00
										 |  |  |     m_hover_label->setText(QFontMetrics(m_hover_label->font()).elidedText(m_hover_label->text(), Qt::ElideRight, width() / 2 - 10)); | 
					
						
							| 
									
										
										
										
											2022-09-09 14:23:36 +02:00
										 |  |  |     m_hover_label->resize(QFontMetrics(m_hover_label->font()).boundingRect(m_hover_label->text()).adjusted(-4, -2, 4, 2).size()); | 
					
						
							| 
									
										
										
										
											2024-08-24 03:18:57 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     auto hover_label_height = height() - m_hover_label->height(); | 
					
						
							| 
									
										
										
										
											2024-05-29 20:12:21 +01:00
										 |  |  |     if (m_find_in_page->isVisible()) | 
					
						
							| 
									
										
										
										
											2024-08-24 03:18:57 +03:00
										 |  |  |         hover_label_height -= m_find_in_page->height(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (m_hover_label->underMouse() && m_hover_label->x() == 0) | 
					
						
							|  |  |  |         m_hover_label->move(width() / 2 + (width() / 2 - m_hover_label->width()), hover_label_height); | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |         m_hover_label->move(0, hover_label_height); | 
					
						
							| 
									
										
										
										
											2024-05-29 20:12:21 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-09 14:23:36 +02:00
										 |  |  |     m_hover_label->raise(); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2023-05-05 15:38:46 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-14 00:05:47 +02:00
										 |  |  | void Tab::update_navigation_buttons_state() | 
					
						
							| 
									
										
										
										
											2024-03-29 06:55:09 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2024-07-13 12:57:06 +01:00
										 |  |  |     if (m_window->current_tab() != this) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-14 00:05:47 +02:00
										 |  |  |     m_window->go_back_action().setEnabled(m_can_navigate_back); | 
					
						
							|  |  |  |     m_window->go_forward_action().setEnabled(m_can_navigate_forward); | 
					
						
							| 
									
										
										
										
											2024-03-29 06:55:09 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-05 15:38:46 +02:00
										 |  |  | bool Tab::event(QEvent* event) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (event->type() == QEvent::PaletteChange) { | 
					
						
							| 
									
										
										
										
											2023-07-29 19:46:47 +01:00
										 |  |  |         recreate_toolbar_icons(); | 
					
						
							| 
									
										
										
										
											2023-05-05 15:38:46 +02:00
										 |  |  |         return QWidget::event(event); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return QWidget::event(event); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-29 19:46:47 +01:00
										 |  |  | void Tab::recreate_toolbar_icons() | 
					
						
							| 
									
										
										
										
											2023-05-05 15:38:46 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2023-07-29 19:46:47 +01:00
										 |  |  |     m_window->go_back_action().setIcon(create_tvg_icon_with_theme_colors("back", palette())); | 
					
						
							|  |  |  |     m_window->go_forward_action().setIcon(create_tvg_icon_with_theme_colors("forward", palette())); | 
					
						
							|  |  |  |     m_window->reload_action().setIcon(create_tvg_icon_with_theme_colors("reload", palette())); | 
					
						
							| 
									
										
										
										
											2024-04-05 07:21:48 -04:00
										 |  |  |     m_window->new_tab_action().setIcon(create_tvg_icon_with_theme_colors("new_tab", palette())); | 
					
						
							| 
									
										
										
										
											2024-05-05 16:11:51 +01:00
										 |  |  |     m_hamburger_button->setIcon(create_tvg_icon_with_theme_colors("hamburger", palette())); | 
					
						
							| 
									
										
										
										
											2023-05-05 15:38:46 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2023-05-17 11:54:36 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-03 18:32:43 -05:00
										 |  |  | 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; | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-17 11:54:36 -04:00
										 |  |  | void Tab::show_inspector_window(InspectorTarget inspector_target) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2023-11-23 20:04:54 -05:00
										 |  |  |     if (!m_inspector_widget) | 
					
						
							| 
									
										
										
										
											2024-12-03 18:32:43 -05:00
										 |  |  |         recreate_inspector(); | 
					
						
							| 
									
										
										
										
											2023-12-10 10:09:40 -05:00
										 |  |  |     else | 
					
						
							|  |  |  |         m_inspector_widget->inspect(); | 
					
						
							| 
									
										
										
										
											2023-05-17 11:54:36 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     m_inspector_widget->show(); | 
					
						
							| 
									
										
										
										
											2023-11-23 20:04:54 -05:00
										 |  |  |     m_inspector_widget->activateWindow(); | 
					
						
							|  |  |  |     m_inspector_widget->raise(); | 
					
						
							| 
									
										
										
										
											2023-05-17 11:54:36 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-23 20:04:54 -05:00
										 |  |  |     if (inspector_target == InspectorTarget::HoveredElement) | 
					
						
							|  |  |  |         m_inspector_widget->select_hovered_node(); | 
					
						
							|  |  |  |     else | 
					
						
							| 
									
										
										
										
											2023-05-17 11:54:36 -04:00
										 |  |  |         m_inspector_widget->select_default_node(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-29 20:12:21 +01:00
										 |  |  | void Tab::show_find_in_page() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_find_in_page->setVisible(true); | 
					
						
							|  |  |  |     m_find_in_page->setFocus(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-13 21:09:49 +01:00
										 |  |  | void Tab::find_previous() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_find_in_page->find_previous(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Tab::find_next() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_find_in_page->find_next(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-17 11:54:36 -04:00
										 |  |  | void Tab::close_sub_widgets() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     auto close_widget_window = [](auto* widget) { | 
					
						
							|  |  |  |         if (widget) | 
					
						
							|  |  |  |             widget->close(); | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     close_widget_window(m_inspector_widget); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2023-08-02 11:52:59 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-05 20:29:12 +01:00
										 |  |  | void Tab::set_block_popups(bool enabled) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     debug_request("block-pop-ups", enabled ? "on" : "off"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-04 13:28:48 +01:00
										 |  |  | void Tab::set_line_box_borders(bool enabled) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     debug_request("set-line-box-borders", enabled ? "on" : "off"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-05 20:29:12 +01:00
										 |  |  | void Tab::set_same_origin_policy(bool enabled) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     debug_request("same-origin-policy", enabled ? "on" : "off"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Tab::set_scripting(bool enabled) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     debug_request("scripting", enabled ? "on" : "off"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-06 00:07:10 +01:00
										 |  |  | void Tab::set_user_agent_string(ByteString const& user_agent) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     debug_request("spoof-user-agent", user_agent); | 
					
						
							|  |  |  |     // Clear the cache to ensure requests are re-done with the new user agent.
 | 
					
						
							|  |  |  |     debug_request("clear-cache"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-02 19:28:39 +01:00
										 |  |  | void Tab::set_navigator_compatibility_mode(ByteString const& compatibility_mode) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     debug_request("navigator-compatibility-mode", compatibility_mode); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-23 21:11:47 +01:00
										 |  |  | void Tab::set_preferred_languages(Vector<String> const& preferred_languages) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_view->set_preferred_languages(preferred_languages); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-02 20:31:14 +01:00
										 |  |  | void Tab::set_enable_do_not_track(bool enable) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_view->set_enable_do_not_track(enable); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-22 23:12:36 +01:00
										 |  |  | void Tab::set_enable_autoplay(bool enable) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_view->set_enable_autoplay(enable); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-02 11:52:59 -06:00
										 |  |  | } |