| 
									
										
										
										
											2022-07-05 23:18:21 +01:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2022-07-19 12:23:11 +02:00
										 |  |  |  * Copyright (c) 2022, Andreas Kling <kling@serenityos.org> | 
					
						
							| 
									
										
										
										
											2022-07-05 23:18:21 +01:00
										 |  |  |  * Copyright (c) 2022, Matthew Costa <ucosty@gmail.com> | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * SPDX-License-Identifier: BSD-2-Clause | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "Tab.h"
 | 
					
						
							|  |  |  | #include "BrowserWindow.h"
 | 
					
						
							| 
									
										
										
										
											2022-07-06 14:38:50 +01:00
										 |  |  | #include "History.h"
 | 
					
						
							| 
									
										
										
										
											2022-07-14 05:41:13 +02:00
										 |  |  | #include "Settings.h"
 | 
					
						
							| 
									
										
										
										
											2022-07-05 23:18:21 +01:00
										 |  |  | #include <QCoreApplication>
 | 
					
						
							| 
									
										
										
										
											2022-09-09 14:23:36 +02:00
										 |  |  | #include <QFont>
 | 
					
						
							|  |  |  | #include <QFontMetrics>
 | 
					
						
							| 
									
										
										
										
											2022-07-13 04:39:38 +02:00
										 |  |  | #include <QPoint>
 | 
					
						
							| 
									
										
										
										
											2022-09-09 14:23:36 +02:00
										 |  |  | #include <QResizeEvent>
 | 
					
						
							| 
									
										
										
										
											2022-07-05 23:18:21 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | extern String s_serenity_resource_root; | 
					
						
							| 
									
										
										
										
											2022-07-14 05:41:13 +02:00
										 |  |  | extern Browser::Settings* s_settings; | 
					
						
							| 
									
										
										
										
											2022-07-05 23:18:21 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-21 21:17:13 +02:00
										 |  |  | Tab::Tab(BrowserWindow* window) | 
					
						
							| 
									
										
										
										
											2022-07-05 23:18:21 +01:00
										 |  |  |     : m_window(window) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     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); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     m_view = new WebView; | 
					
						
							|  |  |  |     m_toolbar = new QToolBar; | 
					
						
							|  |  |  |     m_location_edit = new QLineEdit; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-09 14:23:36 +02:00
										 |  |  |     m_hover_label = new QLabel(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); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-12 09:12:04 +02:00
										 |  |  |     auto* focus_location_editor_action = new QAction("Edit Location"); | 
					
						
							|  |  |  |     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); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-06 14:38:50 +01:00
										 |  |  |     auto back_icon_path = QString("%1/res/icons/16x16/go-back.png").arg(s_serenity_resource_root.characters()); | 
					
						
							|  |  |  |     auto forward_icon_path = QString("%1/res/icons/16x16/go-forward.png").arg(s_serenity_resource_root.characters()); | 
					
						
							|  |  |  |     auto home_icon_path = QString("%1/res/icons/16x16/go-home.png").arg(s_serenity_resource_root.characters()); | 
					
						
							| 
									
										
										
										
											2022-07-05 23:18:21 +01:00
										 |  |  |     auto reload_icon_path = QString("%1/res/icons/16x16/reload.png").arg(s_serenity_resource_root.characters()); | 
					
						
							| 
									
										
										
										
											2022-07-06 14:38:50 +01:00
										 |  |  |     m_back_action = make<QAction>(QIcon(back_icon_path), "Back"); | 
					
						
							| 
									
										
										
										
											2022-09-18 08:53:33 +02:00
										 |  |  |     m_back_action->setEnabled(false); | 
					
						
							| 
									
										
										
										
											2022-09-17 18:06:08 +02:00
										 |  |  |     m_back_action->setShortcuts(QKeySequence::keyBindings(QKeySequence::StandardKey::Back)); | 
					
						
							| 
									
										
										
										
											2022-07-06 14:38:50 +01:00
										 |  |  |     m_forward_action = make<QAction>(QIcon(forward_icon_path), "Forward"); | 
					
						
							| 
									
										
										
										
											2022-09-18 08:53:33 +02:00
										 |  |  |     m_forward_action->setEnabled(false); | 
					
						
							| 
									
										
										
										
											2022-09-17 18:06:08 +02:00
										 |  |  |     m_forward_action->setShortcuts(QKeySequence::keyBindings(QKeySequence::StandardKey::Forward)); | 
					
						
							| 
									
										
										
										
											2022-07-06 14:38:50 +01:00
										 |  |  |     m_home_action = make<QAction>(QIcon(home_icon_path), "Home"); | 
					
						
							|  |  |  |     m_reload_action = make<QAction>(QIcon(reload_icon_path), "Reload"); | 
					
						
							|  |  |  |     m_reload_action->setShortcut(QKeySequence("Ctrl+R")); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     m_toolbar->addAction(m_back_action); | 
					
						
							|  |  |  |     m_toolbar->addAction(m_forward_action); | 
					
						
							|  |  |  |     m_toolbar->addAction(m_reload_action); | 
					
						
							|  |  |  |     m_toolbar->addAction(m_home_action); | 
					
						
							| 
									
										
										
										
											2022-07-05 23:18:21 +01:00
										 |  |  |     m_toolbar->addWidget(m_location_edit); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-12 09:04:51 +02:00
										 |  |  |     QObject::connect(m_view, &WebView::link_hovered, [this](QString const& title) { | 
					
						
							| 
									
										
										
										
											2022-09-09 14:23:36 +02:00
										 |  |  |         m_hover_label->setText(title); | 
					
						
							|  |  |  |         update_hover_label(); | 
					
						
							|  |  |  |         m_hover_label->show(); | 
					
						
							| 
									
										
										
										
											2022-07-13 04:39:38 +02:00
										 |  |  |     }); | 
					
						
							| 
									
										
										
										
											2022-09-12 09:04:51 +02:00
										 |  |  |     QObject::connect(m_view, &WebView::link_unhovered, [this] { | 
					
						
							| 
									
										
										
										
											2022-09-09 14:23:36 +02:00
										 |  |  |         m_hover_label->hide(); | 
					
						
							| 
									
										
										
										
											2022-07-13 04:39:38 +02:00
										 |  |  |     }); | 
					
						
							| 
									
										
										
										
											2022-07-05 23:18:21 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-12 09:04:51 +02:00
										 |  |  |     QObject::connect(m_view, &WebView::load_started, [this](const URL& url) { | 
					
						
							| 
									
										
										
										
											2022-07-06 14:38:50 +01:00
										 |  |  |         m_location_edit->setText(url.to_string().characters()); | 
					
						
							|  |  |  |         m_history.push(url, m_title.toUtf8().data()); | 
					
						
							| 
									
										
										
										
											2022-09-18 08:53:33 +02:00
										 |  |  |         m_back_action->setEnabled(m_history.can_go_back()); | 
					
						
							|  |  |  |         m_forward_action->setEnabled(m_history.can_go_forward()); | 
					
						
							| 
									
										
										
										
											2022-07-06 14:38:50 +01:00
										 |  |  |     }); | 
					
						
							| 
									
										
										
										
											2022-07-05 23:18:21 +01:00
										 |  |  |     QObject::connect(m_location_edit, &QLineEdit::returnPressed, this, &Tab::location_edit_return_pressed); | 
					
						
							|  |  |  |     QObject::connect(m_view, &WebView::title_changed, this, &Tab::page_title_changed); | 
					
						
							|  |  |  |     QObject::connect(m_view, &WebView::favicon_changed, this, &Tab::page_favicon_changed); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-06 14:38:50 +01:00
										 |  |  |     QObject::connect(m_back_action, &QAction::triggered, this, &Tab::back); | 
					
						
							|  |  |  |     QObject::connect(m_forward_action, &QAction::triggered, this, &Tab::forward); | 
					
						
							|  |  |  |     QObject::connect(m_home_action, &QAction::triggered, this, &Tab::home); | 
					
						
							|  |  |  |     QObject::connect(m_reload_action, &QAction::triggered, this, &Tab::reload); | 
					
						
							| 
									
										
										
										
											2022-09-12 09:12:04 +02:00
										 |  |  |     QObject::connect(focus_location_editor_action, &QAction::triggered, this, &Tab::focus_location_editor); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Tab::focus_location_editor() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_location_edit->setFocus(); | 
					
						
							|  |  |  |     m_location_edit->selectAll(); | 
					
						
							| 
									
										
										
										
											2022-07-06 14:38:50 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-14 18:32:51 +03:00
										 |  |  | void Tab::navigate(QString url) | 
					
						
							| 
									
										
										
										
											2022-07-06 14:38:50 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2022-07-19 20:08:02 +02:00
										 |  |  |     if (!url.startsWith("http://", Qt::CaseInsensitive) && !url.startsWith("https://", Qt::CaseInsensitive) && !url.startsWith("file://", Qt::CaseInsensitive)) | 
					
						
							| 
									
										
										
										
											2022-07-14 18:32:51 +03:00
										 |  |  |         url = "http://" + url; | 
					
						
							| 
									
										
										
										
											2022-07-06 14:38:50 +01:00
										 |  |  |     view().load(url.toUtf8().data()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Tab::back() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (!m_history.can_go_back()) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     m_history.go_back(); | 
					
						
							|  |  |  |     view().load(m_history.current().url.to_string()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Tab::forward() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (!m_history.can_go_forward()) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     m_history.go_forward(); | 
					
						
							|  |  |  |     view().load(m_history.current().url.to_string()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Tab::home() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2022-07-14 05:41:13 +02:00
										 |  |  |     navigate(s_settings->homepage()); | 
					
						
							| 
									
										
										
										
											2022-07-05 23:18:21 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Tab::reload() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     view().reload(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Tab::location_edit_return_pressed() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2022-07-06 14:38:50 +01:00
										 |  |  |     navigate(m_location_edit->text()); | 
					
						
							| 
									
										
										
										
											2022-07-05 23:18:21 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Tab::page_title_changed(QString title) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2022-07-06 14:38:50 +01:00
										 |  |  |     m_title = title; | 
					
						
							| 
									
										
										
										
											2022-07-05 23:18:21 +01:00
										 |  |  |     emit title_changed(tab_index(), std::move(title)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Tab::page_favicon_changed(QIcon icon) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     emit favicon_changed(tab_index(), std::move(icon)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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
										 |  |  | 
 | 
					
						
							|  |  |  | void Tab::debug_request(String const& request, String const& argument) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_view->debug_request(request, argument); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											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() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_hover_label->resize(QFontMetrics(m_hover_label->font()).boundingRect(m_hover_label->text()).adjusted(-4, -2, 4, 2).size()); | 
					
						
							|  |  |  |     m_hover_label->move(6, height() - m_hover_label->height() - 8); | 
					
						
							|  |  |  |     m_hover_label->raise(); | 
					
						
							|  |  |  | } |