diff options
| author | Akshay Nair <phenax5@gmail.com> | 2025-03-11 23:02:44 +0530 |
|---|---|---|
| committer | Akshay Nair <phenax5@gmail.com> | 2025-03-12 00:13:47 +0530 |
| commit | 35d8464f8975ab35c1e2f1a076302d9f95bfb22c (patch) | |
| tree | 0b4e26e36fb27dd32c0e174e4ef829f1f77c1daf | |
| parent | 0d5b7cb2a8bea5d91c58dd40f80d60bca384b766 (diff) | |
| download | null-browser-35d8464f8975ab35c1e2f1a076302d9f95bfb22c.tar.gz null-browser-35d8464f8975ab35c1e2f1a076302d9f95bfb22c.zip | |
Refactor browsermanager to webviewstack
| -rw-r--r-- | include/LuaRuntime.hpp | 8 | ||||
| -rw-r--r-- | include/widgets/MainWindow.hpp | 8 | ||||
| -rw-r--r-- | include/widgets/WebViewStack.hpp (renamed from include/widgets/BrowserManager.hpp) | 33 | ||||
| -rw-r--r-- | spec/BrowserManagerSpec.cpp | 271 | ||||
| -rw-r--r-- | spec/WebViewStackSpec.cpp | 273 | ||||
| -rw-r--r-- | src/widgets/MainWindow.cpp | 29 | ||||
| -rw-r--r-- | src/widgets/WebViewStack.cpp (renamed from src/widgets/BrowserManager.cpp) | 57 |
7 files changed, 335 insertions, 344 deletions
diff --git a/include/LuaRuntime.hpp b/include/LuaRuntime.hpp index 83ebf0c..5bfc82c 100644 --- a/include/LuaRuntime.hpp +++ b/include/LuaRuntime.hpp @@ -2,7 +2,7 @@ #include <QtCore> #include <lua.hpp> -#include "widgets/BrowserManager.hpp" +#include "widgets/WebViewStack.hpp" class LuaRuntime : public QObject { Q_OBJECT @@ -15,14 +15,12 @@ public: void evaluate(QString code); -protected: - LuaRuntime(); - ~LuaRuntime(); - signals: void urlOpened(QString url, OpenType openType); protected: + LuaRuntime(); + ~LuaRuntime(); static int lua_onUrlOpen(lua_State *state); static int lua_onUrlTabOpen(lua_State *state); diff --git a/include/widgets/MainWindow.hpp b/include/widgets/MainWindow.hpp index 4731fe4..99a3895 100644 --- a/include/widgets/MainWindow.hpp +++ b/include/widgets/MainWindow.hpp @@ -6,8 +6,8 @@ #include <QWebEngineView> #include "LuaRuntime.hpp" -#include "widgets/BrowserManager.hpp" #include "widgets/InputLine.hpp" +#include "widgets/WebViewStack.hpp" class EvaluationType { public: @@ -20,10 +20,12 @@ class MainWindow : public QMainWindow { public: MainWindow(); -protected: +private: void keyPressEvent(QKeyEvent *event) override; void onInputSubmit(QString input); + void evaluateCommand(QString command); + void hideInputLine(); void showInputLine(); void showURLInput(QString url, OpenType openType); @@ -32,7 +34,7 @@ protected: void setEvaluationType(EvaluationType *); private: - BrowserManager *browserManager; + WebViewStack *webViewStack; InputLine *inputLine; LuaRuntime *luaRuntime; QStackedLayout *layout; diff --git a/include/widgets/BrowserManager.hpp b/include/widgets/WebViewStack.hpp index 8cf265d..1d10715 100644 --- a/include/widgets/BrowserManager.hpp +++ b/include/widgets/WebViewStack.hpp @@ -7,34 +7,37 @@ enum OpenType { OpenUrl, OpenUrlInTab, OpenUrlInBgTab, OpenUrlInWindow }; -class BrowserManager : public QWidget { +class WebViewStack : public QWidget { Q_OBJECT public: inline static const QUrl NewtabURL = QUrl("about:blank"); public: - BrowserManager(QWebEngineProfile *profile = new QWebEngineProfile); + WebViewStack(QWebEngineProfile *profile = new QWebEngineProfile, + QWidget *parent = nullptr); - QUrl currentUrl(); - void setCurrentUrl(QUrl url); - - QWebEngineView *createNewWebView(QUrl url = BrowserManager::NewtabURL, - bool focus = false); - - void openUrl(QUrl url = BrowserManager::NewtabURL, + void openUrl(QUrl url = WebViewStack::NewtabURL, OpenType openType = OpenType::OpenUrl); - std::vector<QUrl> webViewUrls(); + std::vector<QUrl> urls(); u_int32_t currentWebViewIndex(); - u_int32_t webViewCount(); + u_int32_t count(); + QUrl currentUrl(); + void focusWebView(long index); - void nextWebView(); - void previousWebView(); + void next(); + void previous(); + + void close(long index); + void closeCurrent(); - void closeWebView(long index); - void closeCurrentWebView(); +private: + void setCurrentUrl(QUrl url); + QWebEngineView *createNewWebView(QUrl url = WebViewStack::NewtabURL, + bool focus = false); +private slots: void onNewWebViewRequest(QWebEngineNewWindowRequest &request); private: diff --git a/spec/BrowserManagerSpec.cpp b/spec/BrowserManagerSpec.cpp deleted file mode 100644 index efa1ca3..0000000 --- a/spec/BrowserManagerSpec.cpp +++ /dev/null @@ -1,271 +0,0 @@ -#include <QWebEngineNewWindowRequest> -#include <QWebEngineProfile> -#include <vector> - -#include "testUtils.h" -#include "widgets/BrowserManager.hpp" - -class BrowserManagerSpec : public QObject { - Q_OBJECT - - class FakeNewWindowRequest : public QWebEngineNewWindowRequest { - public: - FakeNewWindowRequest(DestinationType t, const QRect &r, const QUrl &u, - bool b) - : QWebEngineNewWindowRequest(t, r, u, b, nullptr) {} - }; - -private slots: - void testInitialState() { - context("when initialized"); - it("opens a single tab") { - BrowserManager browserManager; - - QCOMPARE(browserManager.webViewCount(), 1); - QCOMPARE(browserManager.currentUrl(), BrowserManager::NewtabURL); - browserManager.deleteLater(); - } - } - - void testCreateNewWebView() { - context("when creating a new background webview without a url"); - it("opens new tab url as a background view") { - BrowserManager browserManager; - - browserManager.createNewWebView(); - - QCOMPARE(browserManager.webViewCount(), 2); - std::vector<QUrl> urls = {QUrl(BrowserManager::NewtabURL), - QUrl(BrowserManager::NewtabURL)}; - QCOMPARE(browserManager.webViewUrls(), urls); - QCOMPARE(browserManager.currentWebViewIndex(), 0); - QCOMPARE(browserManager.currentUrl(), BrowserManager::NewtabURL); - } - - context("when creating a new webview with a url and focus is false"); - it("opens the given url in background") { - BrowserManager browserManager; - - browserManager.createNewWebView(QUrl("https://duckduckgo.com"), false); - - QCOMPARE(browserManager.webViewCount(), 2); - std::vector<QUrl> urls = {QUrl(BrowserManager::NewtabURL), - QUrl("https://duckduckgo.com")}; - QCOMPARE(browserManager.webViewUrls(), urls); - QCOMPARE(browserManager.currentWebViewIndex(), 0); - QCOMPARE(browserManager.currentUrl(), BrowserManager::NewtabURL); - } - - context("when creating a new webview with a url and focus is true"); - it("opens the given url as current view") { - BrowserManager browserManager; - - browserManager.createNewWebView(QUrl("https://duckduckgo.com"), true); - - QCOMPARE(browserManager.webViewCount(), 2); - std::vector<QUrl> urls = {QUrl(BrowserManager::NewtabURL), - QUrl("https://duckduckgo.com")}; - QCOMPARE(browserManager.webViewUrls(), urls); - QCOMPARE(browserManager.currentWebViewIndex(), 1); - QCOMPARE(browserManager.currentUrl(), QUrl("https://duckduckgo.com")); - } - } - - void testNextNavigation() { - context("when nextWebView is called"); - context("- and there is only 1 tab"); - it("does nothing") { - BrowserManager browserManager; - - browserManager.nextWebView(); - - QCOMPARE(browserManager.currentWebViewIndex(), 0); - QCOMPARE(browserManager.currentUrl(), BrowserManager::NewtabURL); - } - - context("when nextWebView is called"); - context("- and there are tabs after the current tab"); - it("goes to the next tab") { - BrowserManager browserManager; - browserManager.createNewWebView(QUrl("http://a1.com")); - browserManager.createNewWebView(QUrl("http://a2.com")); - - browserManager.nextWebView(); - - QCOMPARE(browserManager.currentWebViewIndex(), 1); - QCOMPARE(browserManager.currentUrl(), QUrl("http://a1.com")); - } - - context("when nextWebView is called"); - context("- and current tab is the last tab"); - it("jumps to the first tab") { - BrowserManager browserManager; - browserManager.createNewWebView(QUrl("http://a1.com")); - browserManager.createNewWebView(QUrl("http://a2.com"), true); - QCOMPARE(browserManager.currentWebViewIndex(), 2); - - browserManager.nextWebView(); - - QCOMPARE(browserManager.currentWebViewIndex(), 0); - QCOMPARE(browserManager.currentUrl(), BrowserManager::NewtabURL); - } - } - - void testPreviousNavigation() { - context("when previousWebView is called"); - context("- and there is only 1 tab"); - it("does nothing") { - BrowserManager browserManager; - - browserManager.previousWebView(); - - QCOMPARE(browserManager.currentWebViewIndex(), 0); - QCOMPARE(browserManager.currentUrl(), BrowserManager::NewtabURL); - } - - context("when previousWebView is called"); - context("- and there are tabs before the current tab"); - it("goes to the next tab") { - BrowserManager browserManager; - browserManager.createNewWebView(QUrl("http://a1.com")); - browserManager.createNewWebView(QUrl("http://a2.com"), true); - QCOMPARE(browserManager.currentWebViewIndex(), 2); - - browserManager.previousWebView(); - - QCOMPARE(browserManager.currentWebViewIndex(), 1); - QCOMPARE(browserManager.currentUrl(), QUrl("http://a1.com")); - } - - context("when previousWebView is called"); - context("- and current tab is the last tab"); - it("jumps to the last tab") { - BrowserManager browserManager; - browserManager.createNewWebView(QUrl("http://a1.com")); - browserManager.createNewWebView(QUrl("http://a2.com")); - - browserManager.previousWebView(); - - QCOMPARE(browserManager.currentWebViewIndex(), 2); - QCOMPARE(browserManager.currentUrl(), QUrl("http://a2.com")); - } - } - - void testCloseWebView() { - context("when closeWebView is called"); - context("- with out of bounds index"); - it("does nothing") { - BrowserManager browserManager; - browserManager.setCurrentUrl(QUrl("https://a.com")); - - browserManager.closeWebView(1); - - QCOMPARE(browserManager.webViewCount(), 1); - QCOMPARE(browserManager.webViewUrls(), - (std::vector<QUrl>{QUrl("https://a.com")})); - QCOMPARE(browserManager.currentWebViewIndex(), 0); - QCOMPARE(browserManager.currentUrl(), QUrl("https://a.com")); - } - - context("when closeWebView is called"); - context("- and there is only 1 tab"); - it("closes the tab and opens empty tab in its place") { - BrowserManager browserManager; - browserManager.setCurrentUrl(QUrl("https://a.com")); - QCOMPARE(browserManager.webViewCount(), 1); - - browserManager.closeWebView(0); - - QCOMPARE(browserManager.webViewCount(), 1); - QCOMPARE(browserManager.webViewUrls(), - (std::vector<QUrl>{BrowserManager::NewtabURL})); - QCOMPARE(browserManager.currentWebViewIndex(), 0); - QCOMPARE(browserManager.currentUrl(), BrowserManager::NewtabURL); - } - - context("when closeWebView is called"); - context("- with the current tab index"); - context("- and there are some tabs after"); - it("closes the tab and focuses the next tab") { - BrowserManager browserManager; - browserManager.createNewWebView(QUrl("https://a1.com"), true); - browserManager.createNewWebView(QUrl("https://a2.com")); - QCOMPARE(browserManager.webViewCount(), 3); - QCOMPARE(browserManager.currentWebViewIndex(), 1); - - browserManager.closeWebView(1); - - QCOMPARE(browserManager.webViewCount(), 2); - QCOMPARE(browserManager.webViewUrls(), - (std::vector<QUrl>{BrowserManager::NewtabURL, - QUrl("https://a2.com")})); - QCOMPARE(browserManager.currentWebViewIndex(), 1); - QCOMPARE(browserManager.currentUrl(), QUrl("https://a2.com")); - } - - context("when closeWebView is called"); - context("- with the current tab index"); - context("- which is the last tab"); - it("closes the tab and focusses previous tab") { - BrowserManager browserManager; - browserManager.createNewWebView(QUrl("https://a1.com")); - browserManager.createNewWebView(QUrl("https://a2.com"), true); - QCOMPARE(browserManager.webViewCount(), 3); - QCOMPARE(browserManager.currentWebViewIndex(), 2); - - browserManager.closeWebView(2); - - QCOMPARE(browserManager.webViewCount(), 2); - QCOMPARE(browserManager.webViewUrls(), - (std::vector<QUrl>{BrowserManager::NewtabURL, - QUrl("https://a1.com")})); - QCOMPARE(browserManager.currentWebViewIndex(), 1); - QCOMPARE(browserManager.currentUrl(), QUrl("https://a1.com")); - } - } - - void testNewWindowRequestSignal() { - context("when webview emits a newWindowRequested signal"); - context("- of type new tab"); - it("opens a new web view and focusses it") { - BrowserManager browserManager; - browserManager.setCurrentUrl(QUrl("https://a.com")); - auto webview = browserManager.findChild<QWebEngineView *>(); - - FakeNewWindowRequest windowRequest( - FakeNewWindowRequest::DestinationType::InNewTab, QRect(0, 0, 0, 0), - QUrl("https://new.com"), true); - emit webview->page()->newWindowRequested(windowRequest); - - QCOMPARE(browserManager.webViewCount(), 2); - QCOMPARE( - browserManager.webViewUrls(), - (std::vector<QUrl>{QUrl("https://a.com"), QUrl("https://new.com")})); - QCOMPARE(browserManager.currentWebViewIndex(), 1); - QCOMPARE(browserManager.currentUrl(), QUrl("https://new.com")); - } - - context("when webview emits a newWindowRequested signal"); - context("- of type new background tab"); - it("opens a new web view in the background") { - BrowserManager browserManager; - browserManager.setCurrentUrl(QUrl("https://a.com")); - auto webview = browserManager.findChild<QWebEngineView *>(); - - FakeNewWindowRequest windowRequest( - FakeNewWindowRequest::DestinationType::InNewBackgroundTab, - QRect(0, 0, 0, 0), QUrl("https://new.com"), true); - emit webview->page()->newWindowRequested(windowRequest); - - QCOMPARE(browserManager.webViewCount(), 2); - QCOMPARE( - browserManager.webViewUrls(), - (std::vector<QUrl>{QUrl("https://a.com"), QUrl("https://new.com")})); - QCOMPARE(browserManager.currentWebViewIndex(), 0); - QCOMPARE(browserManager.currentUrl(), QUrl("https://a.com")); - } - } -}; - -QTEST_REGISTER(BrowserManagerSpec) -#include "BrowserManagerSpec.moc" diff --git a/spec/WebViewStackSpec.cpp b/spec/WebViewStackSpec.cpp new file mode 100644 index 0000000..5824437 --- /dev/null +++ b/spec/WebViewStackSpec.cpp @@ -0,0 +1,273 @@ +#include <QWebEngineNewWindowRequest> +#include <QWebEngineProfile> +#include <vector> + +#include "testUtils.h" +#include "widgets/WebViewStack.hpp" + +class WebViewStackSpec : public QObject { + Q_OBJECT + + class FakeNewWindowRequest : public QWebEngineNewWindowRequest { + public: + FakeNewWindowRequest(DestinationType t, const QRect &r, const QUrl &u, + bool b) + : QWebEngineNewWindowRequest(t, r, u, b, nullptr) {} + }; + +private slots: + void testInitialState() { + context("when initialized"); + it("opens a single tab") { + WebViewStack webViewStack; + + QCOMPARE(webViewStack.count(), 1); + QCOMPARE(webViewStack.currentUrl(), WebViewStack::NewtabURL); + webViewStack.deleteLater(); + } + } + + void testOpenUrl() { + context("when openUrl is called without an open type"); + it("replaces current tab url with newtab url") { + WebViewStack webViewStack; + webViewStack.openUrl(QUrl("http://a.com"), OpenType::OpenUrl); + + webViewStack.openUrl(); + + QCOMPARE(webViewStack.count(), 1); + std::vector<QUrl> urls = {QUrl(WebViewStack::NewtabURL)}; + QCOMPARE(webViewStack.urls(), urls); + QCOMPARE(webViewStack.currentWebViewIndex(), 0); + QCOMPARE(webViewStack.currentUrl(), WebViewStack::NewtabURL); + } + + context("when creating a new webview with a url and focus is false"); + it("opens the given url in background") { + WebViewStack webViewStack; + + webViewStack.openUrl(QUrl("https://duckduckgo.com"), + OpenType::OpenUrlInBgTab); + + QCOMPARE(webViewStack.count(), 2); + std::vector<QUrl> urls = {QUrl(WebViewStack::NewtabURL), + QUrl("https://duckduckgo.com")}; + QCOMPARE(webViewStack.urls(), urls); + QCOMPARE(webViewStack.currentWebViewIndex(), 0); + QCOMPARE(webViewStack.currentUrl(), WebViewStack::NewtabURL); + } + + context("when creating a new webview with a url and focus is true"); + it("opens the given url as current view") { + WebViewStack webViewStack; + + webViewStack.openUrl(QUrl("https://duckduckgo.com"), + OpenType::OpenUrlInTab); + + QCOMPARE(webViewStack.count(), 2); + std::vector<QUrl> urls = {QUrl(WebViewStack::NewtabURL), + QUrl("https://duckduckgo.com")}; + QCOMPARE(webViewStack.urls(), urls); + QCOMPARE(webViewStack.currentWebViewIndex(), 1); + QCOMPARE(webViewStack.currentUrl(), QUrl("https://duckduckgo.com")); + } + } + + void testNextNavigation() { + context("when nextWebView is called"); + context("- and there is only 1 tab"); + it("does nothing") { + WebViewStack webViewStack; + + webViewStack.next(); + + QCOMPARE(webViewStack.currentWebViewIndex(), 0); + QCOMPARE(webViewStack.currentUrl(), WebViewStack::NewtabURL); + } + + context("when nextWebView is called"); + context("- and there are tabs after the current tab"); + it("goes to the next tab") { + WebViewStack webViewStack; + webViewStack.openUrl(QUrl("http://a1.com"), OpenType::OpenUrlInBgTab); + webViewStack.openUrl(QUrl("http://a2.com"), OpenType::OpenUrlInBgTab); + + webViewStack.next(); + + QCOMPARE(webViewStack.currentWebViewIndex(), 1); + QCOMPARE(webViewStack.currentUrl(), QUrl("http://a1.com")); + } + + context("when nextWebView is called"); + context("- and current tab is the last tab"); + it("jumps to the first tab") { + WebViewStack webViewStack; + webViewStack.openUrl(QUrl("http://a1.com"), OpenType::OpenUrlInBgTab); + webViewStack.openUrl(QUrl("http://a2.com"), OpenType::OpenUrlInTab); + QCOMPARE(webViewStack.currentWebViewIndex(), 2); + + webViewStack.next(); + + QCOMPARE(webViewStack.currentWebViewIndex(), 0); + QCOMPARE(webViewStack.currentUrl(), WebViewStack::NewtabURL); + } + } + + void testPreviousNavigation() { + context("when previousWebView is called"); + context("- and there is only 1 tab"); + it("does nothing") { + WebViewStack webViewStack; + + webViewStack.previous(); + + QCOMPARE(webViewStack.currentWebViewIndex(), 0); + QCOMPARE(webViewStack.currentUrl(), WebViewStack::NewtabURL); + } + + context("when previousWebView is called"); + context("- and there are tabs before the current tab"); + it("goes to the next tab") { + WebViewStack webViewStack; + webViewStack.openUrl(QUrl("http://a1.com"), OpenType::OpenUrlInBgTab); + webViewStack.openUrl(QUrl("http://a2.com"), OpenType::OpenUrlInTab); + QCOMPARE(webViewStack.currentWebViewIndex(), 2); + + webViewStack.previous(); + + QCOMPARE(webViewStack.currentWebViewIndex(), 1); + QCOMPARE(webViewStack.currentUrl(), QUrl("http://a1.com")); + } + + context("when previousWebView is called"); + context("- and current tab is the last tab"); + it("jumps to the last tab") { + WebViewStack webViewStack; + webViewStack.openUrl(QUrl("http://a1.com"), OpenType::OpenUrlInBgTab); + webViewStack.openUrl(QUrl("http://a2.com"), OpenType::OpenUrlInBgTab); + + webViewStack.previous(); + + QCOMPARE(webViewStack.currentWebViewIndex(), 2); + QCOMPARE(webViewStack.currentUrl(), QUrl("http://a2.com")); + } + } + + void testCloseWebView() { + context("when closeWebView is called"); + context("- with out of bounds index"); + it("does nothing") { + WebViewStack webViewStack; + webViewStack.openUrl(QUrl("https://a.com"), OpenType::OpenUrl); + + webViewStack.close(1); + + QCOMPARE(webViewStack.count(), 1); + QCOMPARE(webViewStack.urls(), (std::vector<QUrl>{QUrl("https://a.com")})); + QCOMPARE(webViewStack.currentWebViewIndex(), 0); + QCOMPARE(webViewStack.currentUrl(), QUrl("https://a.com")); + } + + context("when closeWebView is called"); + context("- and there is only 1 tab"); + it("closes the tab and opens empty tab in its place") { + WebViewStack webViewStack; + webViewStack.openUrl(QUrl("https://a.com"), OpenType::OpenUrl); + QCOMPARE(webViewStack.count(), 1); + + webViewStack.close(0); + + QCOMPARE(webViewStack.count(), 1); + QCOMPARE(webViewStack.urls(), + (std::vector<QUrl>{WebViewStack::NewtabURL})); + QCOMPARE(webViewStack.currentWebViewIndex(), 0); + QCOMPARE(webViewStack.currentUrl(), WebViewStack::NewtabURL); + } + + context("when closeWebView is called"); + context("- with the current tab index"); + context("- and there are some tabs after"); + it("closes the tab and focuses the next tab") { + WebViewStack webViewStack; + webViewStack.openUrl(QUrl("https://a1.com"), OpenType::OpenUrlInTab); + webViewStack.openUrl(QUrl("https://a2.com"), OpenType::OpenUrlInBgTab); + QCOMPARE(webViewStack.count(), 3); + QCOMPARE(webViewStack.currentWebViewIndex(), 1); + + webViewStack.close(1); + + QCOMPARE(webViewStack.count(), 2); + QCOMPARE( + webViewStack.urls(), + (std::vector<QUrl>{WebViewStack::NewtabURL, QUrl("https://a2.com")})); + QCOMPARE(webViewStack.currentWebViewIndex(), 1); + QCOMPARE(webViewStack.currentUrl(), QUrl("https://a2.com")); + } + + context("when closeWebView is called"); + context("- with the current tab index"); + context("- which is the last tab"); + it("closes the tab and focusses previous tab") { + WebViewStack webViewStack; + webViewStack.openUrl(QUrl("https://a1.com"), OpenType::OpenUrlInBgTab); + webViewStack.openUrl(QUrl("https://a2.com"), OpenType::OpenUrlInTab); + QCOMPARE(webViewStack.count(), 3); + QCOMPARE(webViewStack.currentWebViewIndex(), 2); + + webViewStack.close(2); + + QCOMPARE(webViewStack.count(), 2); + QCOMPARE( + webViewStack.urls(), + (std::vector<QUrl>{WebViewStack::NewtabURL, QUrl("https://a1.com")})); + QCOMPARE(webViewStack.currentWebViewIndex(), 1); + QCOMPARE(webViewStack.currentUrl(), QUrl("https://a1.com")); + } + } + + void testNewWindowRequestSignal() { + context("when webview emits a newWindowRequested signal"); + context("- of type new tab"); + it("opens a new web view and focusses it") { + WebViewStack webViewStack; + webViewStack.openUrl(QUrl("https://a.com"), OpenType::OpenUrl); + auto webview = webViewStack.findChild<QWebEngineView *>(); + QCOMPARE(webViewStack.count(), 1); + + FakeNewWindowRequest windowRequest( + FakeNewWindowRequest::DestinationType::InNewTab, QRect(0, 0, 0, 0), + QUrl("https://new.com"), true); + emit webview->page()->newWindowRequested(windowRequest); + + QCOMPARE(webViewStack.count(), 2); + QCOMPARE( + webViewStack.urls(), + (std::vector<QUrl>{QUrl("https://a.com"), QUrl("https://new.com")})); + QCOMPARE(webViewStack.currentWebViewIndex(), 1); + QCOMPARE(webViewStack.currentUrl(), QUrl("https://new.com")); + } + + context("when webview emits a newWindowRequested signal"); + context("- of type new background tab"); + it("opens a new web view in the background") { + WebViewStack webViewStack; + webViewStack.openUrl(QUrl("https://a.com"), OpenType::OpenUrl); + auto webview = webViewStack.findChild<QWebEngineView *>(); + + FakeNewWindowRequest windowRequest( + FakeNewWindowRequest::DestinationType::InNewBackgroundTab, + QRect(0, 0, 0, 0), QUrl("https://new.com"), true); + emit webview->page()->newWindowRequested(windowRequest); + + QCOMPARE(webViewStack.count(), 2); + QCOMPARE( + webViewStack.urls(), + (std::vector<QUrl>{QUrl("https://a.com"), QUrl("https://new.com")})); + QCOMPARE(webViewStack.currentWebViewIndex(), 0); + QCOMPARE(webViewStack.currentUrl(), QUrl("https://a.com")); + } + } +}; + +QTEST_REGISTER(WebViewStackSpec) +#include "WebViewStackSpec.moc" diff --git a/src/widgets/MainWindow.cpp b/src/widgets/MainWindow.cpp index f2825e8..2d936aa 100644 --- a/src/widgets/MainWindow.cpp +++ b/src/widgets/MainWindow.cpp @@ -7,9 +7,9 @@ #include "CommandParser.hpp" #include "completion/CommandsAdapter.hpp" #include "completion/UrlAdapter.hpp" -#include "widgets/BrowserManager.hpp" #include "widgets/InputLine.hpp" #include "widgets/MainWindow.hpp" +#include "widgets/WebViewStack.hpp" MainWindow::MainWindow() { setStyleSheet("background-color: #000; color: #fff;"); @@ -23,8 +23,8 @@ MainWindow::MainWindow() { centralWidget()->setLayout(layout); // Web engine - browserManager = new BrowserManager(new QWebEngineProfile("web-browser")); - layout->addWidget(browserManager); + webViewStack = new WebViewStack(new QWebEngineProfile("web-browser")); + layout->addWidget(webViewStack); // Command input inputLine = new InputLine; @@ -38,7 +38,7 @@ MainWindow::MainWindow() { luaRuntime = LuaRuntime::instance(); connect(luaRuntime, &LuaRuntime::urlOpened, this, [this](QString url, OpenType openType) { - browserManager->openUrl(QUrl(url), openType); + webViewStack->openUrl(QUrl(url), openType); }); } @@ -78,7 +78,7 @@ void MainWindow::onInputSubmit(QString input) { if (dynamic_cast<CommandEval *>(currentEvaluationType)) { evaluateCommand(input); } else if (auto urlEval = dynamic_cast<UrlEval *>(currentEvaluationType)) { - browserManager->openUrl(input, urlEval->type()); + webViewStack->openUrl(input, urlEval->type()); } } @@ -94,19 +94,19 @@ void MainWindow::evaluateCommand(QString command) { if (cmd.argsString.trimmed().isEmpty()) showURLInput("", OpenType::OpenUrl); else - browserManager->openUrl(cmd.argsString, OpenType::OpenUrl); + webViewStack->openUrl(cmd.argsString, OpenType::OpenUrl); break; case CommandType::TabOpen: if (cmd.argsString.trimmed().isEmpty()) showURLInput("", OpenType::OpenUrlInTab); else - browserManager->openUrl(cmd.argsString, OpenType::OpenUrlInTab); + webViewStack->openUrl(cmd.argsString, OpenType::OpenUrlInTab); break; case CommandType::TabNext: - browserManager->nextWebView(); + webViewStack->next(); break; case CommandType::TabPrev: - browserManager->previousWebView(); + webViewStack->previous(); break; case CommandType::Noop: break; @@ -117,21 +117,22 @@ void MainWindow::keyPressEvent(QKeyEvent *event) { auto combo = event->keyCombination(); if (combo.key() == Qt::Key_L && combo.keyboardModifiers().testFlag(Qt::ControlModifier)) { - showURLInput(browserManager->currentUrl().toString(), OpenType::OpenUrl); + showURLInput(webViewStack->currentUrl().toString(), OpenType::OpenUrl); } else if (combo.key() == Qt::Key_Semicolon && combo.keyboardModifiers().testFlag(Qt::ControlModifier)) { showCommandInput(""); } else if (combo.key() == Qt::Key_T && combo.keyboardModifiers().testFlag(Qt::ControlModifier)) { - browserManager->createNewWebView(QUrl("https://lite.duckduckgo.com"), true); + webViewStack->openUrl(QUrl("https://lite.duckduckgo.com"), + OpenType::OpenUrlInTab); } else if (combo.key() == Qt::Key_J && combo.keyboardModifiers().testFlag(Qt::ControlModifier)) { - browserManager->nextWebView(); + webViewStack->next(); } else if (combo.key() == Qt::Key_K && combo.keyboardModifiers().testFlag(Qt::ControlModifier)) { - browserManager->previousWebView(); + webViewStack->previous(); } else if (combo.key() == Qt::Key_W && combo.keyboardModifiers().testFlag(Qt::ControlModifier)) { - browserManager->closeCurrentWebView(); + webViewStack->closeCurrent(); } } diff --git a/src/widgets/BrowserManager.cpp b/src/widgets/WebViewStack.cpp index 5ac6479..8102351 100644 --- a/src/widgets/BrowserManager.cpp +++ b/src/widgets/WebViewStack.cpp @@ -2,21 +2,20 @@ #include <QWebEngineNewWindowRequest> #include <QWebEngineView> -#include "widgets/BrowserManager.hpp" +#include "widgets/WebViewStack.hpp" -BrowserManager::BrowserManager(QWebEngineProfile *profile) : QWidget() { +WebViewStack::WebViewStack(QWebEngineProfile *profile, QWidget *parent) + : QWidget(parent), profile(profile) { setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); layout = new QStackedLayout(this); layout->setStackingMode(QStackedLayout::StackAll); layout->setContentsMargins(0, 0, 0, 0); - this->profile = profile; - - createNewWebView(BrowserManager::NewtabURL, true); + createNewWebView(WebViewStack::NewtabURL, true); } -void BrowserManager::openUrl(QUrl url, OpenType openType) { +void WebViewStack::openUrl(QUrl url, OpenType openType) { switch (openType) { case OpenType::OpenUrl: setCurrentUrl(url); @@ -28,29 +27,19 @@ void BrowserManager::openUrl(QUrl url, OpenType openType) { createNewWebView(url, false); break; case OpenType::OpenUrlInWindow: - // TODO: impl + createNewWebView(url, true); break; } } -QWebEngineView *BrowserManager::createNewWebView(QUrl url, bool focus) { +QWebEngineView *WebViewStack::createNewWebView(QUrl url, bool focus) { auto webview = new QWebEngineView(profile); webview->setUrl(url); layout->addWidget(webview); webViewList.append(webview); connect(webview->page(), &QWebEnginePage::newWindowRequested, this, - &BrowserManager::onNewWebViewRequest); - // connect(webview->page(), &QWebEnginePage::windowCloseRequested, this, - // [this, webview]() { - // for (int i = 0; i <= this->webViewList.length(); i++) { - // auto w = this->webViewList.at(0); - // printf("::::: %d\n\n", w == webview); - // if (w == webview) { - // this->closeWebView(i); - // } - // } - // }); + &WebViewStack::onNewWebViewRequest); if (focus) focusWebView(webViewList.length() - 1); @@ -58,7 +47,7 @@ QWebEngineView *BrowserManager::createNewWebView(QUrl url, bool focus) { return webview; } -void BrowserManager::onNewWebViewRequest(QWebEngineNewWindowRequest &request) { +void WebViewStack::onNewWebViewRequest(QWebEngineNewWindowRequest &request) { switch (request.destination()) { case QWebEngineNewWindowRequest::InNewTab: createNewWebView(request.requestedUrl(), true); @@ -77,7 +66,7 @@ void BrowserManager::onNewWebViewRequest(QWebEngineNewWindowRequest &request) { } } -void BrowserManager::nextWebView() { +void WebViewStack::next() { if (webViewList.isEmpty()) return; auto index = currentWebViewIndex() + 1; @@ -86,7 +75,7 @@ void BrowserManager::nextWebView() { focusWebView(index); } -void BrowserManager::previousWebView() { +void WebViewStack::previous() { if (webViewList.isEmpty()) return; auto index = currentWebViewIndex() - 1; @@ -95,11 +84,9 @@ void BrowserManager::previousWebView() { focusWebView(index); } -void BrowserManager::closeCurrentWebView() { - closeWebView(currentWebViewIndex()); -} +void WebViewStack::closeCurrent() { close(currentWebViewIndex()); } -void BrowserManager::closeWebView(long index) { +void WebViewStack::close(long index) { if (index < 0 || index >= webViewList.length()) return; @@ -112,23 +99,21 @@ void BrowserManager::closeWebView(long index) { focusWebView(currentWebViewIndex()); if (webViewList.isEmpty()) { - createNewWebView(BrowserManager::NewtabURL, true); + createNewWebView(WebViewStack::NewtabURL, true); } } -std::vector<QUrl> BrowserManager::webViewUrls() { +std::vector<QUrl> WebViewStack::urls() { std::vector<QUrl> urls; for (auto &view : webViewList) urls.push_back(view->url()); return urls; } -u_int32_t BrowserManager::currentWebViewIndex() { - return layout->currentIndex(); -} -u_int32_t BrowserManager::webViewCount() { return webViewList.length(); } +u_int32_t WebViewStack::currentWebViewIndex() { return layout->currentIndex(); } +u_int32_t WebViewStack::count() { return webViewList.length(); } -void BrowserManager::focusWebView(long index) { +void WebViewStack::focusWebView(long index) { if (webViewList.isEmpty()) return; @@ -136,14 +121,14 @@ void BrowserManager::focusWebView(long index) { layout->setCurrentIndex(index); } -QUrl BrowserManager::currentUrl() { +QUrl WebViewStack::currentUrl() { if (currentWebViewIndex() >= webViewList.length()) - return QUrl("about:newtab"); + return QUrl(""); return webViewList.at(currentWebViewIndex())->url(); } -void BrowserManager::setCurrentUrl(QUrl url) { +void WebViewStack::setCurrentUrl(QUrl url) { if (currentWebViewIndex() >= webViewList.length()) return; |
